summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-20 03:56:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-20 03:56:58 +0000
commit0f75b2ad2e23107f8112b6dcd4785eeef6cc34aa (patch)
tree25185226a8d172d94b0ff72f5a611659252c76d6
parentReleasing progress-linux version 2:9.1.0377-1~progress7.99u1. (diff)
downloadvim-0f75b2ad2e23107f8112b6dcd4785eeef6cc34aa.tar.xz
vim-0f75b2ad2e23107f8112b6dcd4785eeef6cc34aa.zip
Merging upstream version 2:9.1.0496.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--.cirrus.yml4
-rw-r--r--.github/MAINTAINERS (renamed from .github/CODEOWNERS)41
-rw-r--r--.github/actions/screendump/action.yml26
-rw-r--r--.github/workflows/ci.yml19
-rw-r--r--.github/workflows/coverity.yml3
-rw-r--r--CONTRIBUTING.md21
-rw-r--r--Filelist7
-rw-r--r--README.md4
-rw-r--r--README.rux.txt2
-rw-r--r--README.txt2
-rw-r--r--READMEdir/README_vimlogo.txt4
-rw-r--r--runtime/autoload/ccomplete.vim4
-rw-r--r--runtime/autoload/dist/ft.vim36
-rw-r--r--runtime/autoload/dist/script.vim4
-rw-r--r--runtime/autoload/hare.vim26
-rw-r--r--runtime/autoload/netrw.vim165
-rw-r--r--runtime/autoload/netrwSettings.vim3
-rw-r--r--runtime/autoload/zig/fmt.vim100
-rw-r--r--runtime/autoload/zip.vim37
-rw-r--r--runtime/compiler/hare.vim23
-rw-r--r--runtime/compiler/javac.vim9
-rw-r--r--runtime/doc/Make_all.mak2
-rw-r--r--runtime/doc/autocmd.txt6
-rw-r--r--runtime/doc/builtin.txt1562
-rw-r--r--runtime/doc/change.txt9
-rw-r--r--runtime/doc/channel.txt61
-rw-r--r--runtime/doc/cmdline.txt2
-rw-r--r--runtime/doc/debug.txt4
-rw-r--r--runtime/doc/develop.txt4
-rw-r--r--runtime/doc/eval.txt6
-rw-r--r--runtime/doc/filetype.txt45
-rw-r--r--runtime/doc/ft_hare.txt77
-rw-r--r--runtime/doc/gui.txt15
-rw-r--r--runtime/doc/help.txt5
-rw-r--r--runtime/doc/if_cscop.txt4
-rw-r--r--runtime/doc/if_pyth.txt11
-rw-r--r--runtime/doc/indent.txt2
-rw-r--r--runtime/doc/map.txt10
-rw-r--r--runtime/doc/mbyte.txt19
-rw-r--r--runtime/doc/netbeans.txt14
-rw-r--r--runtime/doc/options.txt45
-rw-r--r--runtime/doc/os_vms.txt3
-rw-r--r--runtime/doc/os_win32.txt5
-rw-r--r--runtime/doc/pattern.txt4
-rw-r--r--runtime/doc/pi_netrw.txt122
-rw-r--r--runtime/doc/pi_tar.txt5
-rw-r--r--runtime/doc/popup.txt47
-rw-r--r--runtime/doc/print.txt21
-rw-r--r--runtime/doc/quickfix.txt30
-rw-r--r--runtime/doc/sign.txt33
-rw-r--r--runtime/doc/spell.txt15
-rw-r--r--runtime/doc/starting.txt21
-rw-r--r--runtime/doc/syntax.txt115
-rw-r--r--runtime/doc/tabpage.txt7
-rw-r--r--runtime/doc/tags40
-rw-r--r--runtime/doc/tagsrch.txt3
-rw-r--r--runtime/doc/term.txt6
-rw-r--r--runtime/doc/terminal.txt67
-rw-r--r--runtime/doc/test_urls.vim6
-rw-r--r--runtime/doc/testing.txt106
-rw-r--r--runtime/doc/textprop.txt38
-rw-r--r--runtime/doc/todo.txt37
-rw-r--r--runtime/doc/usr_01.txt4
-rw-r--r--runtime/doc/usr_05.txt5
-rw-r--r--runtime/doc/usr_21.txt19
-rw-r--r--runtime/doc/usr_30.txt4
-rw-r--r--runtime/doc/usr_41.txt20
-rw-r--r--runtime/doc/usr_52.txt47
-rw-r--r--runtime/doc/various.txt15
-rw-r--r--runtime/doc/version9.txt74
-rw-r--r--runtime/doc/vi_diff.txt4
-rw-r--r--runtime/doc/vim-it.1175
-rw-r--r--runtime/doc/vim-it.UTF-8.1175
-rw-r--r--runtime/doc/vim.188
-rw-r--r--runtime/doc/vim.man134
-rw-r--r--runtime/doc/vim9.txt3
-rw-r--r--runtime/doc/xxd-it.15
-rw-r--r--runtime/doc/xxd-it.UTF-8.15
-rw-r--r--runtime/doc/xxd.17
-rw-r--r--runtime/doc/xxd.man54
-rw-r--r--runtime/filetype.vim52
-rw-r--r--runtime/ftplugin/abaqus.vim3
-rw-r--r--runtime/ftplugin/arduino.vim67
-rw-r--r--runtime/ftplugin/asm.vim3
-rw-r--r--runtime/ftplugin/astro.vim7
-rw-r--r--runtime/ftplugin/bitbake.vim3
-rw-r--r--runtime/ftplugin/c.vim3
-rw-r--r--runtime/ftplugin/calendar.vim3
-rw-r--r--runtime/ftplugin/cgdbrc.vim3
-rw-r--r--runtime/ftplugin/cpp.vim6
-rw-r--r--runtime/ftplugin/csh.vim3
-rw-r--r--runtime/ftplugin/css.vim3
-rw-r--r--runtime/ftplugin/dart.vim15
-rw-r--r--runtime/ftplugin/deb822sources.vim4
-rw-r--r--runtime/ftplugin/debcontrol.vim7
-rw-r--r--runtime/ftplugin/debsources.vim4
-rw-r--r--runtime/ftplugin/desktop.vim3
-rw-r--r--runtime/ftplugin/dtd.vim3
-rw-r--r--runtime/ftplugin/dtrace.vim5
-rw-r--r--runtime/ftplugin/dts.vim3
-rw-r--r--runtime/ftplugin/erlang.vim5
-rw-r--r--runtime/ftplugin/eruby.vim3
-rw-r--r--runtime/ftplugin/fennel.vim3
-rw-r--r--runtime/ftplugin/fish.vim3
-rw-r--r--runtime/ftplugin/fortran.vim3
-rw-r--r--runtime/ftplugin/fstab.vim3
-rw-r--r--runtime/ftplugin/gdb.vim3
-rw-r--r--runtime/ftplugin/graphql.vim13
-rw-r--r--runtime/ftplugin/groovy.vim3
-rw-r--r--runtime/ftplugin/hamster.vim3
-rw-r--r--runtime/ftplugin/hare.vim56
-rw-r--r--runtime/ftplugin/haredoc.vim44
-rw-r--r--runtime/ftplugin/html.vim3
-rw-r--r--runtime/ftplugin/hyprlang.vim13
-rw-r--r--runtime/ftplugin/indent.vim3
-rw-r--r--runtime/ftplugin/initex.vim3
-rw-r--r--runtime/ftplugin/java.vim3
-rw-r--r--runtime/ftplugin/javascript.vim3
-rw-r--r--runtime/ftplugin/jj.vim19
-rw-r--r--runtime/ftplugin/jq.vim11
-rw-r--r--runtime/ftplugin/jsonc.vim3
-rw-r--r--runtime/ftplugin/kdl.vim17
-rw-r--r--runtime/ftplugin/lc.vim13
-rw-r--r--runtime/ftplugin/ld.vim5
-rw-r--r--runtime/ftplugin/liquid.vim3
-rw-r--r--runtime/ftplugin/lisp.vim3
-rw-r--r--runtime/ftplugin/man.vim8
-rw-r--r--runtime/ftplugin/markdown.vim3
-rw-r--r--runtime/ftplugin/mma.vim5
-rw-r--r--runtime/ftplugin/modula2.vim3
-rw-r--r--runtime/ftplugin/modula3.vim3
-rw-r--r--runtime/ftplugin/nim.vim13
-rw-r--r--runtime/ftplugin/nroff.vim6
-rw-r--r--runtime/ftplugin/obse.vim7
-rw-r--r--runtime/ftplugin/ocaml.vim4
-rw-r--r--runtime/ftplugin/odin.vim11
-rw-r--r--runtime/ftplugin/openvpn.vim3
-rw-r--r--runtime/ftplugin/pascal.vim3
-rw-r--r--runtime/ftplugin/pdf.vim3
-rw-r--r--runtime/ftplugin/perl.vim3
-rw-r--r--runtime/ftplugin/php.vim3
-rw-r--r--runtime/ftplugin/prisma.vim13
-rw-r--r--runtime/ftplugin/ps1.vim3
-rw-r--r--runtime/ftplugin/ps1xml.vim3
-rw-r--r--runtime/ftplugin/purescript.vim14
-rw-r--r--runtime/ftplugin/python.vim23
-rw-r--r--runtime/ftplugin/qml.vim3
-rw-r--r--runtime/ftplugin/racket.vim5
-rw-r--r--runtime/ftplugin/raku.vim13
-rw-r--r--runtime/ftplugin/rasi.vim25
-rw-r--r--runtime/ftplugin/rescript.vim13
-rw-r--r--runtime/ftplugin/rust.vim11
-rw-r--r--runtime/ftplugin/scdoc.vim9
-rw-r--r--runtime/ftplugin/scheme.vim15
-rw-r--r--runtime/ftplugin/sh.vim6
-rw-r--r--runtime/ftplugin/slint.vim15
-rw-r--r--runtime/ftplugin/snakemake.vim13
-rw-r--r--runtime/ftplugin/sql.vim5
-rw-r--r--runtime/ftplugin/sshdconfig.vim10
-rw-r--r--runtime/ftplugin/stylus.vim54
-rw-r--r--runtime/ftplugin/svelte.vim13
-rw-r--r--runtime/ftplugin/tcl.vim3
-rw-r--r--runtime/ftplugin/typescript.vim3
-rw-r--r--runtime/ftplugin/typst.vim14
-rw-r--r--runtime/ftplugin/v.vim15
-rw-r--r--runtime/ftplugin/verilog.vim4
-rw-r--r--runtime/ftplugin/vim.vim3
-rw-r--r--runtime/ftplugin/wat.vim3
-rw-r--r--runtime/ftplugin/xdefaults.vim9
-rw-r--r--runtime/ftplugin/xml.vim3
-rw-r--r--runtime/ftplugin/zig.vim60
-rw-r--r--runtime/ftplugin/zsh.vim4
-rw-r--r--runtime/indent/arduino.vim16
-rw-r--r--runtime/indent/asm.vim29
-rw-r--r--runtime/indent/hare.vim31
-rw-r--r--runtime/indent/kdl.vim30
-rw-r--r--runtime/indent/stylus.vim121
-rw-r--r--runtime/indent/testdir/vb.in52
-rw-r--r--runtime/indent/testdir/vb.ok58
-rw-r--r--runtime/indent/vb.vim252
-rw-r--r--runtime/keymap/georgian-qwerty.vim51
-rw-r--r--runtime/lang/menu_af_af.latin1.vim124
-rw-r--r--runtime/lang/menu_ca_es.latin1.vim15
-rw-r--r--runtime/lang/menu_cs_cz.utf-8.vim20
-rw-r--r--runtime/lang/menu_de_de.latin1.vim12
-rw-r--r--runtime/lang/menu_es_es.latin1.vim22
-rw-r--r--runtime/lang/menu_is_is.latin1.vim3
-rw-r--r--runtime/lang/menu_ko_kr.utf-8.vim23
-rw-r--r--runtime/lang/menu_nl_nl.latin1.vim48
-rw-r--r--runtime/lang/menu_pt_br.vim291
-rw-r--r--runtime/lang/menu_pt_pt.vim43
-rw-r--r--runtime/lang/menu_sl_si.utf-8.vim17
-rw-r--r--runtime/lang/menu_slovak_slovak_republic.1250.vim39
-rw-r--r--runtime/lang/menu_sr_rs.utf-8.vim10
-rw-r--r--runtime/optwin.vim4
-rw-r--r--runtime/pack/dist/opt/comment/doc/comment.txt23
-rw-r--r--runtime/pack/dist/opt/comment/doc/tags8
-rw-r--r--runtime/pack/dist/opt/matchit/autoload/matchit.vim12
-rw-r--r--runtime/pack/dist/opt/matchit/doc/matchit.txt6
-rw-r--r--runtime/pack/dist/opt/matchit/doc/tags3
-rw-r--r--runtime/pack/dist/opt/matchit/plugin/matchit.vim4
-rw-r--r--runtime/pack/dist/opt/termdebug/plugin/termdebug.vim2607
-rw-r--r--runtime/plugin/matchparen.vim4
-rw-r--r--runtime/plugin/netrwPlugin.vim4
-rw-r--r--runtime/syntax/cpp.vim9
-rw-r--r--runtime/syntax/deb822sources.vim2
-rw-r--r--runtime/syntax/generator/gen_syntax_vim.vim60
-rw-r--r--runtime/syntax/generator/vim.vim.base70
-rw-r--r--runtime/syntax/hare.vim188
-rw-r--r--runtime/syntax/haredoc.vim32
-rw-r--r--runtime/syntax/html.vim2
-rw-r--r--runtime/syntax/i3config.vim20
-rw-r--r--runtime/syntax/java.vim253
-rw-r--r--runtime/syntax/jj.vim20
-rw-r--r--runtime/syntax/kdl.vim48
-rw-r--r--runtime/syntax/lc.vim2
-rw-r--r--runtime/syntax/mma.vim2
-rw-r--r--runtime/syntax/rasi.vim298
-rw-r--r--runtime/syntax/shared/debversions.vim9
-rw-r--r--runtime/syntax/shared/typescriptcommon.vim192
-rw-r--r--runtime/syntax/spec.vim2
-rw-r--r--runtime/syntax/ssa.vim16
-rw-r--r--runtime/syntax/stylus.vim51
-rw-r--r--runtime/syntax/swayconfig.vim26
-rw-r--r--runtime/syntax/testdir/dumps/html_00.dump26
-rw-r--r--runtime/syntax/testdir/dumps/html_01.dump34
-rw-r--r--runtime/syntax/testdir/dumps/html_02.dump38
-rw-r--r--runtime/syntax/testdir/dumps/html_03.dump36
-rw-r--r--runtime/syntax/testdir/dumps/html_04.dump38
-rw-r--r--runtime/syntax/testdir/dumps/html_05.dump38
-rw-r--r--runtime/syntax/testdir/dumps/html_06.dump38
-rw-r--r--runtime/syntax/testdir/dumps/html_07.dump38
-rw-r--r--runtime/syntax/testdir/dumps/html_08.dump20
-rw-r--r--runtime/syntax/testdir/dumps/html_99.dump30
-rw-r--r--runtime/syntax/testdir/dumps/java_annotations_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_annotations_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_annotations_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_annotations_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_annotations_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_annotations_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_enfoldment_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_enfoldment_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_enfoldment_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_enfoldment_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_enfoldment_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_enfoldment_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_05.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_06.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_07.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_08.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_lambda_expressions_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_00.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_01.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_02.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_03.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_04.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent2_99.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_00.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_01.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_02.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_03.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_04.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent4_99.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_00.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_01.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_02.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_03.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_04.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent8_99.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_indent_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_00.dump24
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_00.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_01.dump26
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_01.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_02.dump30
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_02.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_03.dump36
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_03.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_04.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_99.dump24
-rw-r--r--runtime/syntax/testdir/dumps/java_methods_style_99.vim2
-rw-r--r--runtime/syntax/testdir/dumps/java_unfoldment_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_unfoldment_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_unfoldment_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_unfoldment_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_unfoldment_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/java_unfoldment_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_comment_00.dump (renamed from runtime/syntax/testdir/dumps/vim_ex_comment-vim9_00.dump)6
-rw-r--r--runtime/syntax/testdir/dumps/vim9_comment_01.dump (renamed from runtime/syntax/testdir/dumps/vim_ex_comment-vim9_01.dump)10
-rw-r--r--runtime/syntax/testdir/dumps/vim9_comment_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_comment_03.dump (renamed from runtime/syntax/testdir/dumps/vim_ex_comment-vim9_02.dump)16
-rw-r--r--runtime/syntax/testdir/dumps/vim9_comment_99.dump (renamed from runtime/syntax/testdir/dumps/vim_ex_comment-vim9_99.dump)14
-rw-r--r--runtime/syntax/testdir/dumps/vim9_ex_comment_strings_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_ex_comment_strings_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_ex_comment_strings_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_keymap_01.vim2
-rw-r--r--runtime/syntax/testdir/dumps/vim9_keymap_99.vim2
-rw-r--r--runtime/syntax/testdir/dumps/vim9_legacy_header_00.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim9_legacy_header_99.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim9_legacy_header_fold_00.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim9_legacy_header_fold_99.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim9_shebang_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim9_shebang_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_comment_00.dump (renamed from runtime/syntax/testdir/dumps/vim_ex_comment_00.dump)2
-rw-r--r--runtime/syntax/testdir/dumps/vim_comment_01.dump (renamed from runtime/syntax/testdir/dumps/vim_ex_comment_01.dump)10
-rw-r--r--runtime/syntax/testdir/dumps/vim_comment_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_comment_03.dump (renamed from runtime/syntax/testdir/dumps/vim_00.dump)22
-rw-r--r--runtime/syntax/testdir/dumps/vim_comment_99.dump (renamed from runtime/syntax/testdir/dumps/vim_ex_comment_99.dump)4
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_catch_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_catch_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_comment_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_comment_strings_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_comment_strings_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_def_06.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_func_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_func_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_function_07.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_function_09.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_function_99.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_sleep_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_sleep_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump2
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump24
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_05.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_06.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_07.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump16
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump6
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_syntax_99.dump6
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_throw_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_ex_throw_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_keymap_99.vim2
-rw-r--r--runtime/syntax/testdir/dumps/vim_line_continuation_02.dump6
-rw-r--r--runtime/syntax/testdir/dumps/vim_line_continuation_99.dump6
-rw-r--r--runtime/syntax/testdir/dumps/vim_shebang_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_shebang_99.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_00.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_01.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_02.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_03.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_04.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_05.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_06.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_07.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_08.dump20
-rw-r--r--runtime/syntax/testdir/dumps/vim_syntax_99.dump20
-rw-r--r--runtime/syntax/testdir/input/html.html153
-rw-r--r--runtime/syntax/testdir/input/html_html146
-rw-r--r--runtime/syntax/testdir/input/java_annotations.java78
-rw-r--r--runtime/syntax/testdir/input/java_enfoldment.java86
-rw-r--r--runtime/syntax/testdir/input/java_lambda_expressions.java154
-rw-r--r--runtime/syntax/testdir/input/java_methods_indent.java70
-rw-r--r--runtime/syntax/testdir/input/java_methods_indent2.java92
-rw-r--r--runtime/syntax/testdir/input/java_methods_indent4.java92
-rw-r--r--runtime/syntax/testdir/input/java_methods_indent8.java92
-rw-r--r--runtime/syntax/testdir/input/java_methods_style.java38
-rw-r--r--runtime/syntax/testdir/input/java_unfoldment.java86
-rw-r--r--runtime/syntax/testdir/input/vim9_comment.vim (renamed from runtime/syntax/testdir/input/vim_ex_comment-vim9.vim)23
-rw-r--r--runtime/syntax/testdir/input/vim9_ex_comment_strings.vim22
-rw-r--r--runtime/syntax/testdir/input/vim9_ex_no_comment_strings.vim22
-rwxr-xr-xruntime/syntax/testdir/input/vim9_shebang.vim7
-rw-r--r--runtime/syntax/testdir/input/vim_comment.vim (renamed from runtime/syntax/testdir/input/vim_ex_comment.vim)23
-rw-r--r--runtime/syntax/testdir/input/vim_ex_catch.vim17
-rw-r--r--runtime/syntax/testdir/input/vim_ex_comment_strings.vim20
-rw-r--r--runtime/syntax/testdir/input/vim_ex_no_comment_strings.vim20
-rw-r--r--runtime/syntax/testdir/input/vim_ex_sleep.vim11
-rw-r--r--runtime/syntax/testdir/input/vim_ex_substitute.vim58
-rw-r--r--runtime/syntax/testdir/input/vim_ex_throw.vim5
-rwxr-xr-xruntime/syntax/testdir/input/vim_shebang.vim5
-rw-r--r--runtime/syntax/typescript.vim2
-rw-r--r--runtime/syntax/typescriptreact.vim7
-rw-r--r--runtime/syntax/vim.vim89
-rw-r--r--src/GvimExt/gvimext.cpp19
-rw-r--r--src/Make_ami.mak1
-rw-r--r--src/Make_cyg_ming.mak1
-rw-r--r--src/Make_mvc.mak4
-rw-r--r--src/Make_vms.mms6
-rw-r--r--src/Makefile21
-rw-r--r--src/README.md1
-rwxr-xr-xsrc/auto/configure57
-rw-r--r--src/autocmd.c3
-rw-r--r--src/buffer.c1
-rw-r--r--src/bufwrite.c2
-rw-r--r--src/charset.c31
-rw-r--r--src/cmdexpand.c22
-rw-r--r--src/cmdhist.c12
-rw-r--r--src/configure.ac13
-rw-r--r--src/dict.c27
-rw-r--r--src/drawline.c62
-rw-r--r--src/drawscreen.c2
-rw-r--r--src/edit.c11
-rw-r--r--src/eval.c3569
-rw-r--r--src/evalfunc.c470
-rw-r--r--src/ex_cmds.c32
-rw-r--r--src/ex_cmds.h12
-rw-r--r--src/ex_docmd.c16
-rw-r--r--src/ex_getln.c10
-rw-r--r--src/fileio.c75
-rw-r--r--src/filepath.c35
-rw-r--r--src/gc.c780
-rw-r--r--src/globals.h1
-rw-r--r--src/gui.c4
-rw-r--r--src/gui_gtk_x11.c20
-rw-r--r--src/gui_x11.c11
-rw-r--r--src/highlight.c2
-rw-r--r--src/if_cscope.c2
-rw-r--r--src/if_py_both.h7
-rw-r--r--src/indent.c47
-rw-r--r--src/insexpand.c251
-rwxr-xr-xsrc/link.sh2
-rw-r--r--src/list.c24
-rw-r--r--src/misc1.c13
-rw-r--r--src/mouse.c22
-rw-r--r--src/move.c67
-rw-r--r--src/normal.c152
-rw-r--r--src/ops.c54
-rw-r--r--src/option.c23
-rw-r--r--src/option.h15
-rw-r--r--src/optiondefs.h7
-rw-r--r--src/optionstr.c19
-rw-r--r--src/os_unix.h2
-rw-r--r--src/po/check.vim4
-rw-r--r--src/po/it.po83
-rw-r--r--src/popupmenu.c276
-rw-r--r--src/popupwin.c4
-rw-r--r--src/proto.h1
-rw-r--r--src/proto/cmdexpand.pro2
-rw-r--r--src/proto/cmdhist.pro2
-rw-r--r--src/proto/dict.pro1
-rw-r--r--src/proto/eval.pro10
-rw-r--r--src/proto/ex_docmd.pro4
-rw-r--r--src/proto/fileio.pro1
-rw-r--r--src/proto/filepath.pro3
-rw-r--r--src/proto/gc.pro12
-rw-r--r--src/proto/indent.pro6
-rw-r--r--src/proto/insexpand.pro3
-rw-r--r--src/proto/list.pro1
-rw-r--r--src/proto/misc1.pro2
-rw-r--r--src/proto/normal.pro1
-rw-r--r--src/proto/option.pro2
-rw-r--r--src/proto/search.pro9
-rw-r--r--src/proto/spell.pro2
-rw-r--r--src/proto/vim9class.pro2
-rw-r--r--src/quickfix.c9
-rw-r--r--src/regexp.c413
-rw-r--r--src/regexp_bt.c39
-rw-r--r--src/regexp_nfa.c5
-rw-r--r--src/scriptfile.c7
-rw-r--r--src/search.c345
-rw-r--r--src/spell.c11
-rw-r--r--src/spellsuggest.c2
-rw-r--r--src/strings.c7
-rw-r--r--src/structs.h5
-rw-r--r--src/tag.c14
-rw-r--r--src/terminal.c19
-rw-r--r--src/testdir/Make_all.mak4
-rw-r--r--src/testdir/dumps/Test_balloon_eval_term_03.dump10
-rw-r--r--src/testdir/dumps/Test_mouse_popup_position_01.dump20
-rw-r--r--src/testdir/dumps/Test_mouse_popup_position_02.dump20
-rw-r--r--src/testdir/dumps/Test_popup_command_rl.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_03.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_04.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_05.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_06.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_06a.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_06b.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_07.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_08.dump20
-rw-r--r--src/testdir/dumps/Test_pum_highlights_09.dump20
-rw-r--r--src/testdir/dumps/Test_smooth_long_6.dump2
-rw-r--r--src/testdir/dumps/Test_smooth_long_7.dump2
-rw-r--r--src/testdir/dumps/Test_smooth_long_scrolloff_1.dump8
-rw-r--r--src/testdir/dumps/Test_smooth_long_scrolloff_2.dump8
-rw-r--r--src/testdir/dumps/Test_smooth_long_scrolloff_3.dump8
-rw-r--r--src/testdir/dumps/Test_smooth_long_scrolloff_4.dump8
-rw-r--r--src/testdir/dumps/Test_smooth_long_scrolloff_5.dump8
-rw-r--r--src/testdir/dumps/Test_smooth_long_scrolloff_6.dump8
-rw-r--r--src/testdir/dumps/Test_smooth_long_scrolloff_7.dump8
-rw-r--r--src/testdir/dumps/Test_smoothscroll_in_qf_window_1.dump20
-rw-r--r--src/testdir/dumps/Test_smoothscroll_in_qf_window_2.dump20
-rw-r--r--src/testdir/dumps/Test_smoothscroll_in_qf_window_3.dump20
-rw-r--r--src/testdir/dumps/Test_smoothscroll_in_qf_window_4.dump20
-rw-r--r--src/testdir/dumps/Test_smoothscroll_in_qf_window_5.dump20
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_hl_match_1.dump10
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_hl_match_2.dump10
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_hl_match_3.dump10
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_hl_match_4.dump10
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_hl_match_5.dump10
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_hl_match_6.dump10
-rw-r--r--src/testdir/dumps/Test_wildmenu_pum_rl.dump10
-rw-r--r--src/testdir/gen_opt_test.vim2
-rw-r--r--src/testdir/test_autocmd.vim26
-rw-r--r--src/testdir/test_autoload.vim1
-rw-r--r--src/testdir/test_balloon.vim25
-rw-r--r--src/testdir/test_blob.vim32
-rw-r--r--src/testdir/test_cmdline.vim49
-rw-r--r--src/testdir/test_edit.vim5
-rw-r--r--src/testdir/test_filecopy.vim72
-rw-r--r--src/testdir/test_filetype.vim59
-rw-r--r--src/testdir/test_fold.vim127
-rw-r--r--src/testdir/test_functions.vim96
-rw-r--r--src/testdir/test_global.vim11
-rw-r--r--src/testdir/test_gui.vim2
-rw-r--r--src/testdir/test_history.vim54
-rw-r--r--src/testdir/test_ins_complete.vim184
-rw-r--r--src/testdir/test_listdict.vim21
-rw-r--r--src/testdir/test_method.vim7
-rw-r--r--src/testdir/test_normal.vim130
-rw-r--r--src/testdir/test_partial.vim14
-rw-r--r--src/testdir/test_popup.vim149
-rw-r--r--src/testdir/test_quickfix.vim70
-rw-r--r--src/testdir/test_remote.vim2
-rw-r--r--src/testdir/test_scroll_opt.vim80
-rw-r--r--src/testdir/test_shell.vim4
-rw-r--r--src/testdir/test_shortpathname.vim22
-rw-r--r--src/testdir/test_spellrare.vim61
-rw-r--r--src/testdir/test_substitute.vim24
-rw-r--r--src/testdir/test_tagjump.vim18
-rw-r--r--src/testdir/test_termdebug.vim118
-rw-r--r--src/testdir/test_terminal3.vim25
-rw-r--r--src/testdir/test_textformat.vim2
-rw-r--r--src/testdir/test_vartabs.vim59
-rw-r--r--src/testdir/test_vim9_assign.vim14
-rw-r--r--src/testdir/test_vim9_builtin.vim28
-rw-r--r--src/testdir/test_vim9_class.vim54
-rw-r--r--src/testdir/test_vim9_expr.vim16
-rw-r--r--src/testdir/test_vim9_func.vim13
-rw-r--r--src/testdir/test_vim9_import.vim110
-rw-r--r--src/testdir/test_vim9_script.vim88
-rw-r--r--src/testdir/test_vim9_typealias.vim2
-rw-r--r--src/testdir/test_viminfo.vim30
-rw-r--r--src/testdir/test_vimscript.vim8
-rw-r--r--src/testdir/test_virtualedit.vim22
-rw-r--r--src/testdir/test_visual.vim781
-rw-r--r--src/testdir/test_xdg.vim4
-rw-r--r--src/testdir/test_xxd.vim16
-rw-r--r--src/testing.c2
-rw-r--r--src/userfunc.c4
-rw-r--r--src/version.c238
-rw-r--r--src/vim.h13
-rw-r--r--src/vim9class.c4
-rw-r--r--src/vim9type.c15
-rw-r--r--src/xxd/xxd.c34
579 files changed, 17867 insertions, 7172 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 78e49d9..a3604a4 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -5,9 +5,9 @@ env:
freebsd_task:
name: FreeBSD
matrix:
- - name: FreeBSD 14.0
+ - name: FreeBSD 14.1
freebsd_instance:
- image_family: freebsd-14-0
+ image_family: freebsd-14-1
timeout_in: 20m
install_script:
- pkg install -y gettext
diff --git a/.github/CODEOWNERS b/.github/MAINTAINERS
index ac41ed5..1254782 100644
--- a/.github/CODEOWNERS
+++ b/.github/MAINTAINERS
@@ -11,6 +11,7 @@
nsis/lang/russian.nsi @RestorerZ
runtime/autoload/freebasic.vim @dkearns
+runtime/autoload/hare.vim @selenebun
runtime/autoload/haskell.vim @alx741
runtime/autoload/javascript.vim @jsit
runtime/autoload/modula2.vim @dkearns
@@ -63,7 +64,7 @@ runtime/compiler/gjs.vim @dkearns
runtime/compiler/gm2.vim @dkearns
runtime/compiler/go.vim @dbarnett
runtime/compiler/haml.vim @tpope
-runtime/compiler/hare.vim @rsaihe
+runtime/compiler/hare.vim @selenebun
runtime/compiler/icon.vim @dkearns
runtime/compiler/javac.vim @dkearns
runtime/compiler/jest.vim @dkearns
@@ -103,9 +104,11 @@ runtime/compiler/xmllint.vim @dkearns
runtime/compiler/xo.vim @dkearns
runtime/compiler/yamllint.vim @romainl
runtime/compiler/zsh.vim @dkearns
+runtime/doc/ft_hare.txt @selenebun
runtime/doc/ps1.txt @heaths
runtime/ftplugin/abaqus.vim @costerwi
runtime/ftplugin/apache.vim @dubgeiser
+runtime/ftplugin/arduino.vim @k-takata
runtime/ftplugin/astro.vim @romainl
runtime/ftplugin/awk.vim @dkearns
runtime/ftplugin/basic.vim @dkearns
@@ -117,6 +120,7 @@ runtime/ftplugin/cs.vim @nickspoons
runtime/ftplugin/csh.vim @dkearns
runtime/ftplugin/css.vim @dkearns
runtime/ftplugin/cucumber.vim @tpope
+runtime/ftplugin/dart.vim @ribru17
runtime/ftplugin/deb822sources.vim @jamessan
runtime/ftplugin/debchangelog.vim @jamessan
runtime/ftplugin/debcontrol.vim @jamessan
@@ -144,15 +148,18 @@ runtime/ftplugin/gitconfig.vim @tpope
runtime/ftplugin/gitignore.vim @ObserverOfTime
runtime/ftplugin/gitrebase.vim @tpope
runtime/ftplugin/gitsendemail.vim @tpope
+runtime/ftplugin/graphql.vim @ribru17
runtime/ftplugin/gyp.vim @ObserverOfTime
runtime/ftplugin/go.vim @dbarnett
runtime/ftplugin/gprof.vim @dpelle
runtime/ftplugin/haml.vim @tpope
-runtime/ftplugin/hare.vim @rsaihe
+runtime/ftplugin/hare.vim @selenebun
+runtime/ftplugin/haredoc.vim @selenebun
runtime/ftplugin/heex.vim @cvincent
runtime/ftplugin/hgcommit.vim @k-takata
runtime/ftplugin/hog.vim @wtfbbqhax
runtime/ftplugin/html.vim @dkearns
+runtime/ftplugin/hyprlang.vim @ribru17
runtime/ftplugin/i3config.vim @hiqua
runtime/ftplugin/icon.vim @dkearns
runtime/ftplugin/indent.vim @dkearns
@@ -161,16 +168,19 @@ runtime/ftplugin/j.vim @glts
runtime/ftplugin/java.vim @zzzyxwvut
runtime/ftplugin/javascript.vim @dkearns
runtime/ftplugin/javascriptreact.vim @dkearns
+runtime/ftplugin/jj.vim @gpanders
runtime/ftplugin/json.vim @dbarnett
runtime/ftplugin/json5.vim @dkearns
runtime/ftplugin/jsonc.vim @izhakjakov
runtime/ftplugin/julia.vim @carlobaldassi
runtime/ftplugin/jq.vim @vito-c
runtime/ftplugin/kconfig.vim @chrisbra
+runtime/ftplugin/kdl.vim @imsnif @jiangyinzuo
runtime/ftplugin/kotlin.vim @udalov
runtime/ftplugin/less.vim @genoma
runtime/ftplugin/liquid.vim @tpope
runtime/ftplugin/lua.vim @dkearns
+runtime/ftplugin/lc.vim @ribru17
runtime/ftplugin/lynx.vim @dkearns
runtime/ftplugin/m3build.vim @dkearns
runtime/ftplugin/m3quake.vim @dkearns
@@ -179,6 +189,7 @@ runtime/ftplugin/meson.vim @Liambeguin
runtime/ftplugin/modula2.vim @dkearns
runtime/ftplugin/modula3.vim @dkearns
runtime/ftplugin/nginx.vim @chr4
+runtime/ftplugin/nim.vim @ribru17
runtime/ftplugin/nroff.vim @a-vrma
runtime/ftplugin/nsis.vim @k-takata
runtime/ftplugin/octave.vim @dkearns
@@ -191,14 +202,18 @@ runtime/ftplugin/php.vim @dkearns
runtime/ftplugin/pod.vim @petdance @dkearns
runtime/ftplugin/poefilter.vim @ObserverOfTime
runtime/ftplugin/postscr.vim @mrdubya
+runtime/ftplugin/prisma.vim @ribru17
runtime/ftplugin/ps1.vim @heaths
runtime/ftplugin/ps1xml.vim @heaths
+runtime/ftplugin/purescript.vim @ribru17
runtime/ftplugin/pymanifest.vim @ObserverOfTime
runtime/ftplugin/python.vim @tpict
runtime/ftplugin/qb64.vim @dkearns
runtime/ftplugin/qml.vim @ChaseKnowlden
runtime/ftplugin/racket.vim @benknoble
+runtime/ftplugin/rasi.vim @fymyte
runtime/ftplugin/readline.vim @dkearns
+runtime/ftplugin/rescript.vim @ribru17
runtime/ftplugin/routeros.vim @zainin
runtime/ftplugin/rst.vim @marshallward
runtime/ftplugin/ruby.vim @tpope @dkearns
@@ -209,10 +224,14 @@ runtime/ftplugin/scss.vim @tpope
runtime/ftplugin/sdoc.vim @gpanders
runtime/ftplugin/sed.vim @dkearns
runtime/ftplugin/sh.vim @dkearns
+runtime/ftplugin/slint.vim @ribru17
+runtime/ftplugin/snakemake.vim @ribru17
runtime/ftplugin/solidity.vim @cothi
runtime/ftplugin/solution.vim @dkearns
runtime/ftplugin/spec.vim @ignatenkobrain
runtime/ftplugin/ssa.vim @ObserverOfTime
+runtime/ftplugin/sshdconfig.vim @jiangyinzuo
+runtime/ftplugin/svelte.vim @igorlfs
runtime/ftplugin/swayconfig.vim @jamespeapen
runtime/ftplugin/systemverilog.vim @Kocha
runtime/ftplugin/swig.vim @jmarrec
@@ -224,7 +243,9 @@ runtime/ftplugin/toml.vim @averms
runtime/ftplugin/tt2html.vim @petdance
runtime/ftplugin/typescript.vim @dkearns
runtime/ftplugin/typescriptreact.vim @dkearns
+runtime/ftplugin/typst.vim @ribru17
runtime/ftplugin/unison.vim @chuwy
+runtime/ftplugin/v.vim @ribru17
runtime/ftplugin/vdf.vim @ObserverOfTime
runtime/ftplugin/vim.vim @dkearns
runtime/ftplugin/wast.vim @rhysd
@@ -235,6 +256,7 @@ runtime/ftplugin/xml.vim @chrisbra
runtime/ftplugin/xs.vim @petdance
runtime/ftplugin/zsh.vim @chrisbra
runtime/import/dist/vimhighlight.vim @lacygoill
+runtime/indent/arduino.vim @k-takata
runtime/indent/astro.vim @wuelnerdotexe
runtime/indent/basic.vim @dkearns
runtime/indent/bst.vim @tpope
@@ -263,7 +285,7 @@ runtime/indent/gitolite.vim @sitaramc
runtime/indent/go.vim @dbarnett
runtime/indent/gyp.vim @ObserverOfTime
runtime/indent/haml.vim @tpope
-runtime/indent/hare.vim @rsaihe
+runtime/indent/hare.vim @selenebun
runtime/indent/hog.vim @wtfbbqhax
runtime/indent/idlang.vim @dkearns
runtime/indent/j.vim @glts
@@ -272,6 +294,7 @@ runtime/indent/javascript.vim @bounceme
runtime/indent/json.vim @elzr
runtime/indent/jsonc.vim @izhakjakov
runtime/indent/julia.vim @carlobaldassi
+runtime/indent/kdl.vim @imsnif @jiangyinzuo
runtime/indent/kotlin.vim @udalov
runtime/indent/krl.vim @KnoP-01
runtime/indent/ld.vim @dkearns
@@ -391,7 +414,8 @@ runtime/syntax/gprof.vim @dpelle
runtime/syntax/groff.vim @jmarshall
runtime/syntax/gyp.vim @ObserverOfTime
runtime/syntax/haml.vim @tpope
-runtime/syntax/hare.vim @rsaihe
+runtime/syntax/hare.vim @selenebun
+runtime/syntax/haredoc.vim @selenebun
runtime/syntax/haskell.vim @coot
runtime/syntax/help_ru.vim @RestorerZ
runtime/syntax/hgcommit.vim @k-takata
@@ -406,12 +430,14 @@ runtime/syntax/j.vim @glts
runtime/syntax/jargon.vim @h3xx
runtime/syntax/java.vim @zzzyxwvut
runtime/syntax/javascript.vim @fleiner
+runtime/syntax/jj.vim @gpanders
runtime/syntax/json.vim @vito-c
runtime/syntax/jsonc.vim @izhakjakov
runtime/syntax/julia.vim @carlobaldassi
runtime/syntax/jq.vim @vito-c
runtime/syntax/kconfig.vim @chrisbra
runtime/syntax/kotlin.vim @udalov
+runtime/syntax/kdl.vim @imsnif @jiangyinzuo
runtime/syntax/krl.vim @KnoP-01
runtime/syntax/less.vim @genoma
runtime/syntax/liquid.vim @tpope
@@ -460,6 +486,7 @@ runtime/syntax/racket.vim @benknoble
runtime/syntax/raml.vim @in3d
runtime/syntax/rapid.vim @KnoP-01
runtime/syntax/ratpoison.vim @trapd00r
+runtime/syntax/rasi.vim @fymyte
runtime/syntax/rc.vim @chrisbra
runtime/syntax/rcs.vim @hdima
runtime/syntax/rebol.vim @mrdubya
@@ -497,9 +524,9 @@ runtime/syntax/toml.vim @averms
runtime/syntax/tt2.vim @petdance
runtime/syntax/tt2html.vim @petdance
runtime/syntax/tt2js.vim @petdance
-runtime/syntax/typescript.vim @HerringtonDarkholme
-runtime/syntax/typescriptcommon.vim @HerringtonDarkholme
-runtime/syntax/typescriptreact.vim @HerringtonDarkholme
+runtime/syntax/typescript.vim @HerringtonDarkholme @rhysd
+runtime/syntax/typescriptreact.vim @HerringtonDarkholme @rhysd
+runtime/syntax/shared/typescriptcommon.vim @HerringtonDarkholme @rhysd
runtime/syntax/unison.vim @chuwy
runtime/syntax/vdf.vim @ObserverOfTime
runtime/syntax/vroom.vim @dbarnett
diff --git a/.github/actions/screendump/action.yml b/.github/actions/screendump/action.yml
new file mode 100644
index 0000000..19eb9b6
--- /dev/null
+++ b/.github/actions/screendump/action.yml
@@ -0,0 +1,26 @@
+name: 'screendump'
+description: "Upload failed syntax tests"
+runs:
+ using: "composite"
+ steps:
+ - name: Upload failed syntax tests
+ uses: actions/upload-artifact@v4
+ with:
+ # Name of the artifact to upload.
+ name: ${{ github.workflow }}-${{ github.job }}-${{ join(matrix.*, '-') }}-failed-syntax-tests
+
+ # A file, directory or wildcard pattern that describes what
+ # to upload.
+ path: |
+ ${{ github.workspace }}/runtime/syntax/testdir/failed/*
+ ${{ github.workspace }}/src/testdir/failed/*
+ # The desired behavior if no files are found using the
+ # provided path.
+ if-no-files-found: ignore
+
+ # Duration after which artifact will expire in days. 0 means
+ # using repository settings.
+ retention-days: 0
+
+ # If true, an artifact with a matching name will be deleted
+ overwrite: true
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0307b45..1110665 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -270,6 +270,9 @@ jobs:
do_test() { sg audio "sg $(id -gn) '$*'"; }
do_test make ${SHADOWOPT} ${TEST}
+ - if: ${{ !cancelled() }}
+ uses: ./.github/actions/screendump
+
- name: Vim tags
if: contains(matrix.extra, 'vimtags')
run: |
@@ -330,8 +333,16 @@ jobs:
brew install lua libtool
echo "LUA_PREFIX=$(brew --prefix)" >> $GITHUB_ENV
+ - name: Install blackhole-2ch for macos-12
+ if: matrix.features == 'huge' && matrix.runner == 'macos-12'
+ run: |
+ # Install audio device for playing sound since some of macos-12 machines have no audio device installed.
+ if system_profiler -json SPAudioDataType | jq -er '.SPAudioDataType[]._items == []'; then
+ brew install blackhole-2ch
+ fi
+
- name: Grant microphone access for macos-14
- if: matrix.runner == 'macos-14'
+ if: matrix.features == 'huge' && matrix.runner == 'macos-14'
run: |
# Temporary fix to fix microphone permission issues for macos-14 when playing sound.
sqlite3 $HOME/Library/Application\ Support/com.apple.TCC/TCC.db "INSERT OR IGNORE INTO access VALUES ('kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159,NULL,NULL,'UNUSED',1687786159);"
@@ -388,6 +399,9 @@ jobs:
run: |
make ${TEST}
+ - if: ${{ !cancelled() }}
+ uses: ./.github/actions/screendump
+
windows:
runs-on: windows-2022
@@ -683,6 +697,9 @@ jobs:
nmake -nologo -f Make_mvc.mak tiny VIMPROG=..\vim || exit 1
)
+ - if: ${{ !cancelled() }}
+ uses: ./.github/actions/screendump
+
- name: Generate gcov files
if: matrix.coverage
shell: msys2 {0}
diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml
index 290f7e4..90a6e9f 100644
--- a/.github/workflows/coverity.yml
+++ b/.github/workflows/coverity.yml
@@ -63,6 +63,9 @@ jobs:
# Append various warning flags to CFLAGS.
sed -i -f ci/config.mk.sed src/auto/config.mk
sed -i -f ci/config.mk.${CC}.sed src/auto/config.mk
+ # -O2 gives false warning and turns it into an error:
+ # warning: function may return address of local variable [-Wreturn-local-addr]
+ sed -i 's/-O2 \?//' src/auto/config.mk
- name: Build/scan vim
if: env.TOKEN
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0720cb1..99bfcfa 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -46,17 +46,30 @@ Or open [the todo file][todo list] on GitHub to see the latest version.
# Syntax, indent and other runtime files
The latest version of these files can be obtained from the repository.
-They are usually not updated with numbered patches.
+They are usually not updated with numbered patches. However, they may
+or may not work with older Vim releases (since they may contain new features).
If you find a problem with one of these files or have a suggestion for
improvement, please first try to contact the maintainer directly.
-Look in the header of the file for the name and email address.
+Look in the header of the file for the name, email address, github handle and/or
+upstream repository. You may also check the [MAINTAINERS][11] file.
The maintainer will take care of issues and send updates to the Vim project for
distribution with Vim.
If the maintainer does not respond, contact the [vim-dev][0] mailing list.
+## Contributing new runtime files
+
+If you want to contribute new runtime files for Vim or Neovim, please create a
+PR with your changes against this repository here. For new filetypes, do not forget:
+* to add a new [filetype test][12] (keep it similar to the other filetype tests).
+* all configuration switches should be documented
+ (check [filetype.txt][13] and/or [syntax.txt][14] for filetype and syntax plugins)
+* add yourself as Maintainer to the top of file (again, keep the header similar to
+ other runtime files)
+* add yourself to the [MAINTAINERS][11] file.
+
# Translations
Translating messages and runtime files is very much appreciated! These things
@@ -96,3 +109,7 @@ mailing list. For other questions please use the [Vi Stack Exchange][8] website,
[8]: https://vi.stackexchange.com
[9]: http://www.vim.org/maillist.php#vim-use
[10]: https://github.com/vim/vim/discussions
+[11]: https://github.com/vim/vim/blob/master/.github/MAINTAINERS
+[12]: https://github.com/vim/vim/blob/master/src/testdir/test_filetype.vim
+[13]: https://github.com/vim/vim/blob/master/runtime/doc/filetype.txt
+[14]: https://github.com/vim/vim/blob/master/runtime/doc/syntax.txt
diff --git a/Filelist b/Filelist
index ff474bc..20c19f7 100644
--- a/Filelist
+++ b/Filelist
@@ -5,11 +5,12 @@
SRC_ALL = \
.cirrus.yml \
.gitattributes \
- .github/CODEOWNERS \
+ .github/MAINTAINERS \
.github/ISSUE_TEMPLATE/bug_report.yml \
.github/ISSUE_TEMPLATE/feature_request.md \
.github/workflows/ci.yml \
.github/workflows/codeql-analysis.yml \
+ .github/actions/screendump/action.yml \
.github/workflows/coverity.yml \
.github/dependabot.yml \
.gitignore \
@@ -72,6 +73,7 @@ SRC_ALL = \
src/float.c \
src/fold.c \
src/getchar.c \
+ src/gc.c \
src/globals.h \
src/gui.c \
src/gui.h \
@@ -263,6 +265,7 @@ SRC_ALL = \
src/proto/float.pro \
src/proto/fold.pro \
src/proto/getchar.pro \
+ src/proto/gc.pro \
src/proto/gui.pro \
src/proto/gui_beval.pro \
src/proto/hardcopy.pro \
@@ -803,7 +806,6 @@ RT_SCRIPTS = \
runtime/autoload/dist/*.vim \
runtime/autoload/rust/*.vim \
runtime/autoload/xml/*.vim \
- runtime/autoload/zig/*.vim \
runtime/colors/*.vim \
runtime/colors/README.txt \
runtime/colors/lists/*.vim \
@@ -834,6 +836,7 @@ RT_SCRIPTS = \
runtime/syntax/testdir/input/*.* \
runtime/syntax/testdir/input/setup/*.* \
runtime/syntax/testdir/dumps/*.dump \
+ runtime/syntax/testdir/dumps/*.vim \
runtime/syntax/generator/Makefile \
runtime/syntax/generator/README.md \
runtime/syntax/generator/gen_syntax_vim.vim \
diff --git a/README.md b/README.md
index 6e6cf11..cfee68e 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ or one of the [Maillists](https://www.vim.org/community.php).
## What is Vim?
Vim is a greatly improved version of the good old UNIX editor
-[Vi](https://en.wikipedia.org/wiki/Vi). Many new
+[Vi](https://en.wikipedia.org/wiki/Vi_(text_editor)). Many new
features have been added: multi-level undo, syntax highlighting, command line
history, on-line help, spell checking, filename completion, block operations,
script language, etc. There is also a Graphical User Interface (GUI)
@@ -55,7 +55,7 @@ an overview of currently available distributions.
Some popular places to get the latest Vim:
* Check out the git repository from [GitHub](https://github.com/vim/vim).
-* Get the source code as an [archive](https://github.com/vim/vim/releases).
+* Get the source code as an [archive](https://github.com/vim/vim/tags).
* Get a Windows executable from the
[vim-win32-installer](https://github.com/vim/vim-win32-installer/releases) repository.
diff --git a/README.rux.txt b/README.rux.txt
index 5c92b85..be90928 100644
--- a/README.rux.txt
+++ b/README.rux.txt
@@ -48,7 +48,7 @@ MS Windows 95/98/Me/NT/2000/XP/Vista, AmigaDOS, Atari MiNT, BeOS и RISC OS.
Несколько полезных мест, где можно получить последнюю версию редактора Vim:
* Посмотрите в git-хранилище на GitHub: https://github.com/vim/vim.
-* Получить исходный код в виде архива: https://github.com/vim/vim/releases.
+* Получить исходный код в виде архива: https://github.com/vim/vim/tags.
* Получить исполняемый файл для ОС Windows из хранилища vim-win32-installer:
https://github.com/vim/vim-win32-installer/releases.
diff --git a/README.txt b/README.txt
index bdfefaf..d90ebbc 100644
--- a/README.txt
+++ b/README.txt
@@ -37,7 +37,7 @@ an overview of currently available distributions.
Some popular places to get the latest Vim:
* Check out the git repository from github: https://github.com/vim/vim.
-* Get the source code as an archive: https://github.com/vim/vim/releases.
+* Get the source code as an archive: https://github.com/vim/vim/tags.
* Get a Windows executable from the vim-win32-installer repository:
https://github.com/vim/vim-win32-installer/releases.
diff --git a/READMEdir/README_vimlogo.txt b/READMEdir/README_vimlogo.txt
index 9798b10..570e876 100644
--- a/READMEdir/README_vimlogo.txt
+++ b/READMEdir/README_vimlogo.txt
@@ -1,8 +1,8 @@
The Python project that creates `vimlogo.svg` can be found at
`https://github.com/ShayHill/vimlogo`. The Vim license applies.
-`vimlogo.svg` is an effort to remove errors and inadvertant inconsistencies
-from the original vim logo while maintaing the original design. `vimlogo.svg`
+`vimlogo.svg` is an effort to remove errors and inadvertent inconsistencies
+from the original vim logo while maintaining the original design. `vimlogo.svg`
is based on the `vimlogo.svg` file (previously?) found at
`https://www.vim.org/logos.php`
diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim
index 7096dcf..355f724 100644
--- a/runtime/autoload/ccomplete.vim
+++ b/runtime/autoload/ccomplete.vim
@@ -3,7 +3,7 @@ vim9script noclear
# Vim completion script
# Language: C
# Maintainer: The Vim Project <https://github.com/vim/vim>
-# Last Change: 2023 Aug 10
+# Last Change: 2024 Jun 06
# Rewritten in Vim9 script by github user lacygoill
# Former Maintainer: Bram Moolenaar <Bram@vim.org>
@@ -210,7 +210,7 @@ export def Complete(findstart: bool, abase: string): any # {{{1
# Find the variable in the tags file(s)
var diclist: list<dict<any>> = taglist('^' .. items[0] .. '$')
# Remove members, these can't appear without something in front.
- ->filter((_, v: dict<string>): bool =>
+ ->filter((_, v: dict<any>): bool =>
v->has_key('kind') ? v.kind != 'm' : true)
res = []
diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim
index 4e7d517..bf9e32e 100644
--- a/runtime/autoload/dist/ft.vim
+++ b/runtime/autoload/dist/ft.vim
@@ -3,7 +3,7 @@ vim9script
# Vim functions for file type detection
#
# Maintainer: The Vim Project <https://github.com/vim/vim>
-# Last Change: 2024 Feb 18
+# Last Change: 2024 May 23
# Former Maintainer: Bram Moolenaar <Bram@vim.org>
# These functions are moved here from runtime/filetype.vim to make startup
@@ -376,6 +376,32 @@ export def FTfs()
endif
enddef
+# Recursively search for Hare source files in a directory and any
+# subdirectories, up to a given depth.
+def IsHareModule(dir: string, depth: number): bool
+ if depth <= 0
+ return !empty(glob(dir .. '/*.ha'))
+ endif
+
+ return reduce(sort(glob(dir .. '/*', true, true),
+ (a, b) => isdirectory(a) - isdirectory(b)),
+ (acc, n) => acc
+ || n =~ '\.ha$'
+ || isdirectory(n)
+ && IsHareModule(n, depth - 1),
+ false)
+enddef
+
+# Determine if a README file exists within a Hare module and should be given the
+# Haredoc filetype.
+export def FTharedoc()
+ if exists('g:filetype_haredoc')
+ if IsHareModule('<afile>:h', get(g:, 'haredoc_search_depth', 1))
+ setf haredoc
+ endif
+ endif
+enddef
+
# Distinguish between HTML, XHTML and Django
export def FThtml()
var n = 1
@@ -406,14 +432,18 @@ export def FTidl()
setf idl
enddef
-# Distinguish between "default", Prolog and Cproto prototype file.
+# Distinguish between "default", Prolog, zsh module's C and Cproto prototype file.
export def ProtoCheck(default: string)
+ # zsh modules use '#include "*.pro"'
+ # https://github.com/zsh-users/zsh/blob/63f086d167960a27ecdbcb762179e2c2bf8a29f5/Src/Modules/example.c#L31
+ if getline(1) =~ '/* Generated automatically */'
+ setf c
# Cproto files have a comment in the first line and a function prototype in
# the second line, it always ends in ";". Indent files may also have
# comments, thus we can't match comments to see the difference.
# IDL files can have a single ';' in the second line, require at least one
# chacter before the ';'.
- if getline(2) =~ '.;$'
+ elseif getline(2) =~ '.;$'
setf cpp
else
# recognize Prolog by specific text in the first non-empty line
diff --git a/runtime/autoload/dist/script.vim b/runtime/autoload/dist/script.vim
index f58899a..33ed7fd 100644
--- a/runtime/autoload/dist/script.vim
+++ b/runtime/autoload/dist/script.vim
@@ -229,6 +229,10 @@ export def Exe2filetype(name: string, line1: string): string
elseif name =~ '^execlineb\>'
return 'execline'
+ # Vim
+ elseif name =~ '^vim\>'
+ return 'vim'
+
endif
return ''
diff --git a/runtime/autoload/hare.vim b/runtime/autoload/hare.vim
new file mode 100644
index 0000000..c4581fc
--- /dev/null
+++ b/runtime/autoload/hare.vim
@@ -0,0 +1,26 @@
+" Vim autoload file.
+" Language: Hare
+" Maintainer: Amelia Clarke <selene@perilune.dev>
+" Last Updated: 2024-05-10
+" Upstream: https://git.sr.ht/~sircmpwn/hare.vim
+
+" Attempt to find the directory for a given Hare module.
+function hare#FindModule(str)
+ let path = substitute(trim(a:str, ':', 2), '::', '/', 'g')
+ let dir = finddir(path)
+ while !empty(path) && empty(dir)
+ let path = substitute(path, '/\?\h\w*$', '', '')
+ let dir = finddir(path)
+ endwhile
+ return dir
+endfunction
+
+" Return the value of HAREPATH if it exists. Otherwise use a reasonable default.
+function hare#GetPath()
+ if empty($HAREPATH)
+ return '/usr/src/hare/stdlib,/usr/src/hare/third-party'
+ endif
+ return substitute($HAREPATH, ':', ',', 'g')
+endfunction
+
+" vim: et sts=2 sw=2 ts=8
diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim
index e2152b0..d8de432 100644
--- a/runtime/autoload/netrw.vim
+++ b/runtime/autoload/netrw.vim
@@ -9,6 +9,12 @@
" 2024 Feb 19 by Vim Project: (announce adoption)
" 2024 Feb 29 by Vim Project: handle symlinks in tree mode correctly
" 2024 Apr 03 by Vim Project: detect filetypes for remote edited files
+" 2024 May 08 by Vim Project: cleanup legacy Win9X checks
+" 2024 May 09 by Vim Project: remove hard-coded private.ppk
+" 2024 May 10 by Vim Project: recursively delete directories by default
+" 2024 May 13 by Vim Project: prefer scp over pscp
+" 2024 Jun 04 by Vim Project: set bufhidden if buffer changed, nohidden is set and buffer shall be switched (#14915)
+" 2024 Jun 13 by Vim Project: glob() on Windows fails when a directory name contains [] (#14952)
" Former Maintainer: Charles E Campbell
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
" Copyright: Copyright (C) 2016 Charles E. Campbell {{{1
@@ -283,20 +289,15 @@ if !exists("g:netrw_scp_cmd")
if executable("scp")
call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
elseif executable("pscp")
- if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable('c:\private.ppk')
- call s:NetrwInit("g:netrw_scp_cmd", 'pscp -i c:\private.ppk')
- else
- call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
- endif
+ call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
else
call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
endif
endif
-
call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
call s:NetrwInit("g:netrw_ssh_cmd" , "ssh")
-if (has("win32") || has("win95") || has("win64") || has("win16"))
+if has("win32")
\ && exists("g:netrw_use_nt_rcp")
\ && g:netrw_use_nt_rcp
\ && executable( $SystemRoot .'/system32/rcp.exe')
@@ -311,12 +312,8 @@ endif
" Default values for netrw's global variables {{{2
" Cygwin Detection ------- {{{3
if !exists("g:netrw_cygwin")
- if has("win32") || has("win95") || has("win64") || has("win16")
- if has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
- let g:netrw_cygwin= 1
- else
- let g:netrw_cygwin= 0
- endif
+ if has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
+ let g:netrw_cygwin= 1
else
let g:netrw_cygwin= 0
endif
@@ -372,10 +369,6 @@ endif
call s:NetrwInit("g:netrw_keepdir",1)
if !exists("g:netrw_list_cmd")
if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
- if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
- " provide a pscp-based listing command
- let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
- endif
if exists("g:netrw_list_cmd_options")
let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
else
@@ -403,7 +396,7 @@ if !exists("g:netrw_localcmdshell")
let g:netrw_localcmdshell= ""
endif
if !exists("g:netrw_localcopycmd")
- if has("win32") || has("win95") || has("win64") || has("win16")
+ if has("win32")
if g:netrw_cygwin
let g:netrw_localcopycmd= "cp"
else
@@ -417,7 +410,7 @@ if !exists("g:netrw_localcopycmd")
endif
endif
if !exists("g:netrw_localcopydircmd")
- if has("win32") || has("win95") || has("win64") || has("win16")
+ if has("win32")
if g:netrw_cygwin
let g:netrw_localcopydircmd = "cp"
let g:netrw_localcopydircmdopt= " -R"
@@ -439,7 +432,7 @@ if exists("g:netrw_local_mkdir")
let g:netrw_localmkdir= g:netrw_local_mkdir
call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
endif
-if has("win32") || has("win95") || has("win64") || has("win16")
+if has("win32")
if g:netrw_cygwin
call s:NetrwInit("g:netrw_localmkdir","mkdir")
else
@@ -455,7 +448,7 @@ if exists("g:netrw_local_movecmd")
call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
endif
if !exists("g:netrw_localmovecmd")
- if has("win32") || has("win95") || has("win64") || has("win16")
+ if has("win32")
if g:netrw_cygwin
let g:netrw_localmovecmd= "mv"
else
@@ -488,7 +481,7 @@ call s:NetrwInit("g:netrw_mousemaps" , (exists("+mouse") && &mouse =~# '[anh
call s:NetrwInit("g:netrw_retmap" , 0)
if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
call s:NetrwInit("g:netrw_chgperm" , "chmod PERM FILENAME")
-elseif has("win32") || has("win95") || has("win64") || has("win16")
+elseif has("win32")
call s:NetrwInit("g:netrw_chgperm" , "cacls FILENAME /e /p PERM")
else
call s:NetrwInit("g:netrw_chgperm" , "chmod PERM FILENAME")
@@ -547,14 +540,13 @@ if !exists("g:netrw_xstrlen")
endif
endif
call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
-call s:NetrwInit("g:netrw_win95ftp",1)
call s:NetrwInit("g:netrw_winsize",50)
call s:NetrwInit("g:netrw_wiw",1)
if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
" ---------------------------------------------------------------------
" Default values for netrw's script variables: {{{2
call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
-if has("win32") || has("win95") || has("win64") || has("win16")
+if has("win32")
call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
else
call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
@@ -686,7 +678,7 @@ fun! netrw#Explore(indx,dosplit,style,...)
" record current directory
let curdir = simplify(b:netrw_curdir)
let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
- if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if !exists("g:netrw_cygwin") && has("win32")
let curdir= substitute(curdir,'\','/','g')
endif
" call Decho("curdir<".curdir."> curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
@@ -844,7 +836,7 @@ fun! netrw#Explore(indx,dosplit,style,...)
" handle .../**/.../filepat
" call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
- if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
+ if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && has("win32"))
let b:netrw_curdir = prefixdir
else
let b:netrw_curdir= getcwd().'/'.prefixdir
@@ -881,7 +873,7 @@ fun! netrw#Explore(indx,dosplit,style,...)
else
if dirname == ""
let dirname= getcwd()
- elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
+ elseif has("win32") && !g:netrw_cygwin
" Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
" depending on whether backslashes have been converted to forward slashes by earlier code).
if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
@@ -1420,7 +1412,7 @@ fun! netrw#Obtain(islocal,fname,...)
" call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
let topath= s:ComposePath(tgtdir,"")
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
" transfer files one at time
" call Decho("transfer files one at a time",'~'.expand("<slnum>"))
for fname in fnamelist
@@ -2301,7 +2293,7 @@ fun! netrw#NetRead(mode,...)
endif
" 'C' in 'C:\path\to\file' is handled as hostname on windows.
" This is workaround to avoid mis-handle windows local-path:
- if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if g:netrw_scp_cmd =~ '^scp' && has("win32")
let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
else
let tmpfile_get = tmpfile
@@ -3221,7 +3213,7 @@ fun! s:NetrwMethod(choice)
if exists("s:netrw_hup[host]")
call NetUserPass("ftp:".host)
- elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:'
+ elseif has("win32") && s:netrw_ftp_cmd =~# '-[sS]:'
" call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
" call Decho(" g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
@@ -3336,38 +3328,6 @@ fun! s:NetrwMethod(choice)
" call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
endfun
-" ------------------------------------------------------------------------
-" NetReadFixup: this sort of function is typically written by the user {{{2
-" to handle extra junk that their system's ftp dumps
-" into the transfer. This function is provided as an
-" example and as a fix for a Windows 95 problem: in my
-" experience, win95's ftp always dumped four blank lines
-" at the end of the transfer.
-if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
- fun! NetReadFixup(method, line1, line2)
-" call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
-
- " sanity checks -- attempt to convert inputs to integers
- let method = a:method + 0
- let line1 = a:line1 + 0
- let line2 = a:line2 + 0
- if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
-" call Dret("NetReadFixup")
- return
- endif
-
- if method == 3 " ftp (no <.netrc>)
- let fourblanklines= line2 - 3
- if fourblanklines >= line1
- exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
- call histdel("/",-1)
- endif
- endif
-
-" call Dret("NetReadFixup")
- endfun
-endif
-
" ---------------------------------------------------------------------
" NetUserPass: set username and password for subsequent ftp transfer {{{2
" Usage: :call NetUserPass() -- will prompt for userid and password
@@ -3990,7 +3950,7 @@ fun! s:NetrwBrowse(islocal,dirname)
if b:netrw_curdir =~ '[/\\]$'
let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
endif
- if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if b:netrw_curdir =~ '\a:$' && has("win32")
let b:netrw_curdir= b:netrw_curdir."/"
endif
if b:netrw_curdir == ''
@@ -4144,7 +4104,7 @@ fun! s:NetrwFile(fname)
let b:netrw_curdir= getcwd()
endif
- if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if !exists("g:netrw_cygwin") && has("win32")
if fname =~ '^\' || fname =~ '^\a:\'
" windows, but full path given
let ret= fname
@@ -4864,7 +4824,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...)
call s:SavePosn(s:netrw_posn)
NetrwKeepj call s:NetrwOptionsSave("s:")
NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
let dirname = substitute(b:netrw_curdir,'\\','/','ge')
else
let dirname = b:netrw_curdir
@@ -5111,7 +5071,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...)
endif
" call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
- elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
+ elseif !g:netrw_cygwin && has("win32")
" windows
if a:islocal
let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
@@ -5396,7 +5356,7 @@ fun! netrw#BrowseX(fname,remote)
" set up the filename
" (lower case the extension, make a local copy of a remote file)
let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
- if has("win32") || has("win95") || has("win64") || has("win16")
+ if has("win32")
let exten= substitute(exten,'^.*$','\L&\E','')
endif
if exten =~ "[\\/]"
@@ -5443,12 +5403,12 @@ fun! netrw#BrowseX(fname,remote)
" by default, g:netrw_suppress_gx_mesg is true
if g:netrw_suppress_gx_mesg
if &srr =~ "%s"
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
let redir= substitute(&srr,"%s","nul","")
else
let redir= substitute(&srr,"%s","/dev/null","")
endif
- elseif (has("win32") || has("win95") || has("win64") || has("win16"))
+ elseif has("win32")
let redir= &srr . "nul"
else
let redir= &srr . "/dev/null"
@@ -5491,7 +5451,7 @@ fun! netrw#BrowseX(fname,remote)
call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
let ret= v:shell_error
- elseif has("win32") || has("win64")
+ elseif has("win32")
" call Decho("(netrw#BrowseX) win".(has("win32")? "32" : "64"),'~'.expand("<slnum>"))
if executable("start")
call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
@@ -5766,6 +5726,9 @@ fun! s:NetrwEditFile(cmd,opt,fname)
exe "NetrwKeepj keepalt ".a:opt." ".a:cmd." ".fnameescape(a:fname)
else
" call Decho("exe NetrwKeepj ".a:opt." ".a:cmd." ".fnameescape(a:fname))
+ if a:cmd =~# 'e\%[new]!' && !&hidden && getbufvar(bufname('%'), '&modified', 0)
+ call setbufvar(bufname('%'), '&bufhidden', 'hide')
+ endif
exe "NetrwKeepj ".a:opt." ".a:cmd." ".fnameescape(a:fname)
endif
" call Dret("s:NetrwEditFile")
@@ -5836,16 +5799,20 @@ fun! s:NetrwGlob(direntry,expr,pare)
let filelist= w:netrw_treedict[a:direntry]
endif
let w:netrw_liststyle= keep_liststyle
- elseif v:version > 704 || (v:version == 704 && has("patch656"))
- let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1)
- if a:pare
- let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
- endif
else
- let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1)
- if a:pare
- let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
- endif
+ let path= s:ComposePath(fnameescape(a:direntry),a:expr)
+ if has("win32")
+ " escape [ so it is not detected as wildcard character, see :h wildcard
+ let path= substitute(path, '[', '[[]', 'g')
+ endif
+ if v:version > 704 || (v:version == 704 && has("patch656"))
+ let filelist= glob(path,0,1,1)
+ else
+ let filelist= glob(path,0,1)
+ endif
+ if a:pare
+ let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
+ endif
endif
" call Dret("s:NetrwGlob ".string(filelist))
return filelist
@@ -6006,7 +5973,7 @@ fun! s:NetrwHome()
" just pick the first directory
let home= substitute(&rtp,',.*$','','')
endif
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
let home= substitute(home,'/','\\','g')
endif
endif
@@ -7227,7 +7194,7 @@ fun! s:NetrwMarkFileCopy(islocal,...)
let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
let tgt = s:ShellEscape(s:netrwmftgt)
endif
- if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if !g:netrw_cygwin && has("win32")
let args= substitute(args,'/','\\','g')
let tgt = substitute(tgt, '/','\\','g')
endif
@@ -7241,7 +7208,7 @@ fun! s:NetrwMarkFileCopy(islocal,...)
" call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
let copycmd= g:netrw_localcopydircmd
" call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
- if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if !g:netrw_cygwin && has("win32")
" window's xcopy doesn't copy a directory to a target properly. Instead, it copies a directory's
" contents to a target. One must append the source directory name to the target to get xcopy to
" do the right thing.
@@ -7859,7 +7826,7 @@ fun! s:NetrwMarkFileMove(islocal)
endif
let tgt = s:ShellEscape(s:netrwmftgt)
" call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
- if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if !g:netrw_cygwin && has("win32")
let tgt= substitute(tgt, '/','\\','g')
" call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
if g:netrw_localmovecmd =~ '\s'
@@ -7880,7 +7847,7 @@ fun! s:NetrwMarkFileMove(islocal)
" Jul 19, 2022: fixing file move when g:netrw_keepdir is 1
let fname= b:netrw_curdir."/".fname
endif
- if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if !g:netrw_cygwin && has("win32")
let fname= substitute(fname,'/','\\','g')
endif
" call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
@@ -10349,7 +10316,7 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd)
endif
" cleanup for Windows " {{{3
- if has("win32") || has("win95") || has("win64") || has("win16")
+ if has("win32")
sil! NetrwKeepj %s/\r$//e
NetrwKeepj call histdel("/",-1)
endif
@@ -10857,7 +10824,7 @@ fun! netrw#FileUrlEdit(fname)
let fname= substitute(fname,'^file://localhost/','file:///','')
" call Decho("fname<".fname.">",'~'.expand("<slnum>"))
endif
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
if fname =~ '^file:///\=\a[|:]/'
" call Decho('converting file:///\a|/ -to- file://\a:/','~'.expand("<slnum>"))
let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
@@ -10867,7 +10834,7 @@ fun! netrw#FileUrlEdit(fname)
let fname2396 = netrw#RFC2396(fname)
let fname2396e= fnameescape(fname2396)
let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
" call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
if plainfname =~ '^/\+\a:'
" call Decho('removing leading "/"s','~'.expand("<slnum>"))
@@ -11079,7 +11046,7 @@ fun! s:LocalFastBrowser()
let s:netrw_events= 1
augroup AuNetrwEvent
au!
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
" call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
au ShellCmdPost * call s:LocalBrowseRefresh()
else
@@ -11121,7 +11088,7 @@ fun! s:LocalListing()
let filelist = filelist + s:NetrwGlob(dirname,".*",0)
" call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
- if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if g:netrw_cygwin == 0 && has("win32")
" call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
" include ../ in the glob() entry if its missing
@@ -11167,7 +11134,7 @@ fun! s:LocalListing()
let pfile= filename."/"
elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
- if (has("win32") || has("win95") || has("win64") || has("win16"))
+ if has("win32")
if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
" indicate an executable
" call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
@@ -11501,7 +11468,7 @@ fun! s:NetrwLocalRmFile(path,fname,all)
if !all
echohl Statement
call inputsave()
- let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
+ let ok= input("Confirm *recursive* deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
call inputrestore()
let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
if ok == ""
@@ -11514,7 +11481,7 @@ fun! s:NetrwLocalRmFile(path,fname,all)
let rmfile= substitute(rmfile,'[\/]$','','e')
if all || ok =~# 'y\%[es]' || ok == ""
- if delete(rmfile,"d")
+ if delete(rmfile,"rf")
call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
endif
endif
@@ -11644,7 +11611,7 @@ endfun
" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
fun! netrw#WinPath(path)
" call Dfunc("netrw#WinPath(path<".a:path.">)")
- if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && has("win32")
" remove cygdrive prefix, if present
let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
" remove trailing slash (Win95)
@@ -11704,11 +11671,11 @@ fun! s:ComposePath(base,subdir)
endif
" COMBAK: test on windows with changing to root directory: :e C:/
- elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
+ elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && has("win32")
" call Decho("windows",'~'.expand("<slnum>"))
let ret= a:subdir
- elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
+ elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && has("win32")
" call Decho("windows",'~'.expand("<slnum>"))
if a:base =~ '[/\\]$'
let ret= a:base.a:subdir
@@ -11820,7 +11787,7 @@ fun! s:GetTempfile(fname)
" o/s dependencies
if g:netrw_cygwin != 0
let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
- elseif has("win32") || has("win95") || has("win64") || has("win16")
+ elseif has("win32")
if !exists("+shellslash") || !&ssl
let tmpfile = substitute(tmpfile,'/','\','g')
endif
@@ -12036,7 +12003,7 @@ fun! s:NetrwDelete(path)
" call Dfunc("s:NetrwDelete(path<".a:path.">)")
let path = netrw#WinPath(a:path)
- if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
+ if !g:netrw_cygwin && has("win32")
if exists("+shellslash")
let sskeep= &shellslash
setl noshellslash
@@ -12227,7 +12194,7 @@ fun! s:NetrwLcd(newdir)
" 'root' (ie. '\'). The share name may start with either backslashes ('\\Foo') or
" forward slashes ('//Foo'), depending on whether backslashes have been converted to
" forward slashes by earlier code; so check for both.
- if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
+ if has("win32") && !g:netrw_cygwin
if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
let dirname = '\'
exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
@@ -12700,7 +12667,7 @@ endfun
" ---------------------------------------------------------------------
" s:ShellEscape: shellescape(), or special windows handling {{{2
fun! s:ShellEscape(s, ...)
- if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
+ if has('win32') && $SHELL == '' && &shellslash
return printf('"%s"', substitute(a:s, '"', '""', 'g'))
endif
let f = a:0 > 0 ? a:1 : 0
diff --git a/runtime/autoload/netrwSettings.vim b/runtime/autoload/netrwSettings.vim
index 5525c0d..3452602 100644
--- a/runtime/autoload/netrwSettings.vim
+++ b/runtime/autoload/netrwSettings.vim
@@ -3,6 +3,8 @@
" Maintainer: This runtime file is looking for a new maintainer.
" Former Maintainer: Charles E Campbell
" Version: 18
+" Last Change:
+" 2024 May 08 by Vim Project: cleanup legacy Win9X checks
" Copyright: Copyright (C) 1999-2007 Charles E. Campbell {{{1
" Permission is hereby granted to use and distribute this code,
" with or without modifications, provided that this copyright
@@ -91,7 +93,6 @@ fun! netrwSettings#NetrwSettings()
put = 'let g:netrw_sshport = '.g:netrw_sshport
put = 'let g:netrw_silent = '.g:netrw_silent
put = 'let g:netrw_use_nt_rcp = '.g:netrw_use_nt_rcp
- put = 'let g:netrw_win95ftp = '.g:netrw_win95ftp
let s:netrw_xfer_stop= line(".")
put =''
put ='+ Netrw Messages'
diff --git a/runtime/autoload/zig/fmt.vim b/runtime/autoload/zig/fmt.vim
deleted file mode 100644
index b78c199..0000000
--- a/runtime/autoload/zig/fmt.vim
+++ /dev/null
@@ -1,100 +0,0 @@
-" Adapted from fatih/vim-go: autoload/go/fmt.vim
-"
-" Copyright 2011 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" Upstream: https://github.com/ziglang/zig.vim
-
-function! zig#fmt#Format() abort
- " Save cursor position and many other things.
- let view = winsaveview()
-
- if !executable('zig')
- echohl Error | echomsg "no zig binary found in PATH" | echohl None
- return
- endif
-
- let cmdline = 'zig fmt --stdin --ast-check'
- let current_buf = bufnr('')
-
- " The formatted code is output on stdout, the errors go on stderr.
- if exists('*systemlist')
- silent let out = systemlist(cmdline, current_buf)
- else
- silent let out = split(system(cmdline, current_buf))
- endif
- if len(out) == 1
- if out[0] == "error: unrecognized parameter: '--ast-check'"
- let cmdline = 'zig fmt --stdin'
- if exists('*systemlist')
- silent let out = systemlist(cmdline, current_buf)
- else
- silent let out = split(system(cmdline, current_buf))
- endif
- endif
- endif
- let err = v:shell_error
-
-
- if err == 0
- " remove undo point caused via BufWritePre.
- try | silent undojoin | catch | endtry
-
- " Replace the file content with the formatted version.
- if exists('*deletebufline')
- call deletebufline(current_buf, len(out), line('$'))
- else
- silent execute ':' . len(out) . ',' . line('$') . ' delete _'
- endif
- call setline(1, out)
-
- " No errors detected, close the loclist.
- call setloclist(0, [], 'r')
- lclose
- elseif get(g:, 'zig_fmt_parse_errors', 1)
- let errors = s:parse_errors(expand('%'), out)
-
- call setloclist(0, [], 'r', {
- \ 'title': 'Errors',
- \ 'items': errors,
- \ })
-
- let max_win_height = get(g:, 'zig_fmt_max_window_height', 5)
- " Prevent the loclist from becoming too long.
- let win_height = min([max_win_height, len(errors)])
- " Open the loclist, but only if there's at least one error to show.
- execute 'silent! lwindow ' . win_height
- endif
-
- call winrestview(view)
-
- if err != 0
- echohl Error | echomsg "zig fmt returned error" | echohl None
- return
- endif
-
- " Run the syntax highlighter on the updated content and recompute the folds if
- " needed.
- syntax sync fromstart
-endfunction
-
-" parse_errors parses the given errors and returns a list of parsed errors
-function! s:parse_errors(filename, lines) abort
- " list of errors to be put into location list
- let errors = []
- for line in a:lines
- let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
- if !empty(tokens)
- call add(errors,{
- \"filename": a:filename,
- \"lnum": tokens[2],
- \"col": tokens[3],
- \"text": tokens[4],
- \ })
- endif
- endfor
-
- return errors
-endfunction
-" vim: sw=2 ts=2 et
diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim
index c0034f8..d0e706e 100644
--- a/runtime/autoload/zip.vim
+++ b/runtime/autoload/zip.vim
@@ -4,17 +4,18 @@
" Version: 33
" Maintainer: This runtime file is looking for a new maintainer.
" Former Maintainer: Charles E Campbell
+" Last Change:
+" 2024 Jun 16 by Vim Project: handle whitespace on Windows properly (#14998)
" License: Vim License (see vim's :help license)
-" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
-" Permission is hereby granted to use and distribute this code,
-" with or without modifications, provided that this copyright
-" notice is copied with it. Like anything else that's free,
-" zip.vim and zipPlugin.vim are provided *as is* and comes with
-" no warranty of any kind, either expressed or implied. By using
-" this plugin, you agree that in no event will the copyright
-" holder be liable for any damages resulting from the use
-" of this software.
-"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
+" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
+" Permission is hereby granted to use and distribute this code,
+" with or without modifications, provided that this copyright
+" notice is copied with it. Like anything else that's free,
+" zip.vim and zipPlugin.vim are provided *as is* and comes with
+" no warranty of any kind, either expressed or implied. By using
+" this plugin, you agree that in no event will the copyright
+" holder be liable for any damages resulting from the use
+" of this software.
" ---------------------------------------------------------------------
" Load Once: {{{1
@@ -214,7 +215,6 @@ endfun
" ---------------------------------------------------------------------
" zip#Read: {{{2
fun! zip#Read(fname,mode)
-" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
let repkeep= &report
set report=10
@@ -226,15 +226,12 @@ fun! zip#Read(fname,mode)
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
let fname = substitute(fname, '[', '[[]', 'g')
endif
-" call Decho("zipfile<".zipfile.">")
-" call Decho("fname <".fname.">")
" sanity check
if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
redraw!
echohl Error | echo "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
" call inputsave()|call input("Press <cr> to continue")|call inputrestore()
let &report= repkeep
-" call Dret("zip#Write")
return
endif
@@ -242,10 +239,8 @@ fun! zip#Read(fname,mode)
" exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1)
" but allows zipfile://... entries in quickfix lists
let temp = tempname()
-" call Decho("using temp file<".temp.">")
let fn = expand('%:p')
- exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp
-" call Decho("exe sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp)
+ exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1).' > '.temp
sil exe 'keepalt file '.temp
sil keepj e!
sil exe 'keepalt file '.fnameescape(fn)
@@ -254,11 +249,9 @@ fun! zip#Read(fname,mode)
filetype detect
" cleanup
- " keepj 0d " used to be needed for the ...r! ... method
set nomod
let &report= repkeep
-" call Dret("zip#Read")
endfun
" ---------------------------------------------------------------------
@@ -422,7 +415,6 @@ endfun
" ---------------------------------------------------------------------
" s:Escape: {{{2
fun! s:Escape(fname,isfilt)
-" call Dfunc("QuoteFileDir(fname<".a:fname."> isfilt=".a:isfilt.")")
if exists("*shellescape")
if a:isfilt
let qnameq= shellescape(a:fname,1)
@@ -432,7 +424,10 @@ fun! s:Escape(fname,isfilt)
else
let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
endif
-" call Dret("QuoteFileDir <".qnameq.">")
+ if exists("+shellslash") && &shellslash && &shell =~ "cmd.exe"
+ " renormalize directory separator on Windows
+ let qnameq=substitute(qnameq, '/', '\\', 'g')
+ endif
return qnameq
endfun
diff --git a/runtime/compiler/hare.vim b/runtime/compiler/hare.vim
index c98bbb9..33edb3a 100644
--- a/runtime/compiler/hare.vim
+++ b/runtime/compiler/hare.vim
@@ -1,28 +1,29 @@
-" Vim compiler file
-" Compiler: Hare Compiler
-" Maintainer: Amelia Clarke <me@rsaihe.dev>
-" Last Change: 2022-09-21
-" 2024 Apr 05 by The Vim Project (removed :CompilerSet definition)
+" Vim compiler file.
+" Compiler: Hare
+" Maintainer: Amelia Clarke <selene@perilune.dev>
+" Last Change: 2024-05-23
+" Upstream: https://git.sr.ht/~sircmpwn/hare.vim
-if exists("g:current_compiler")
+if exists('current_compiler')
finish
endif
-let g:current_compiler = "hare"
+let current_compiler = 'hare'
let s:cpo_save = &cpo
set cpo&vim
-if filereadable("Makefile") || filereadable("makefile")
+if filereadable('Makefile') || filereadable('makefile')
CompilerSet makeprg=make
else
CompilerSet makeprg=hare\ build
endif
CompilerSet errorformat=
- \Error\ %f:%l:%c:\ %m,
- \Syntax\ error:\ %.%#\ at\ %f:%l:%c\\,\ %m,
+ \%f:%l:%c:\ syntax\ error:\ %m,
+ \%f:%l:%c:\ error:\ %m,
\%-G%.%#
let &cpo = s:cpo_save
unlet s:cpo_save
-" vim: tabstop=2 shiftwidth=2 expandtab
+
+" vim: et sts=2 sw=2 ts=8
diff --git a/runtime/compiler/javac.vim b/runtime/compiler/javac.vim
index f5fe841..9bd4cdf 100644
--- a/runtime/compiler/javac.vim
+++ b/runtime/compiler/javac.vim
@@ -1,7 +1,7 @@
" Vim compiler file
" Compiler: Java Development Kit Compiler
" Maintainer: Doug Kearns <dougkearns@gmail.com>
-" Last Change: 2024 Apr 03
+" Last Change: 2024 Jun 14
if exists("current_compiler")
finish
@@ -11,7 +11,12 @@ let current_compiler = "javac"
let s:cpo_save = &cpo
set cpo&vim
-CompilerSet makeprg=javac
+if exists("g:javac_makeprg_params")
+ execute $'CompilerSet makeprg=javac\ {escape(g:javac_makeprg_params, ' \|"')}'
+else
+ CompilerSet makeprg=javac
+endif
+
CompilerSet errorformat=%E%f:%l:\ error:\ %m,
\%W%f:%l:\ warning:\ %m,
\%-Z%p^,
diff --git a/runtime/doc/Make_all.mak b/runtime/doc/Make_all.mak
index ed41d7d..f36ad7e 100644
--- a/runtime/doc/Make_all.mak
+++ b/runtime/doc/Make_all.mak
@@ -19,6 +19,7 @@ DOCS = \
fold.txt \
ft_ada.txt \
ft_context.txt \
+ ft_hare.txt \
ft_mp.txt \
ft_ps1.txt \
ft_raku.txt \
@@ -172,6 +173,7 @@ HTMLS = \
fold.html \
ft_ada.html \
ft_context.html \
+ ft_hare.html \
ft_mp.html \
ft_ps1.html \
ft_raku.html \
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 32094b3..037f89c 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -1,4 +1,4 @@
-*autocmd.txt* For Vim version 9.1. Last change: 2024 Mar 26
+*autocmd.txt* For Vim version 9.1. Last change: 2024 May 05
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -428,8 +428,8 @@ Name triggered by ~
|SessionLoadPost| after loading a session file
-|SessionWritePost| After writing the session file using
- the |:mksession| command.
+|SessionWritePost| after writing the session file using
+ the |:mksession| command
|MenuPopup| just before showing the popup menu
|CompleteChanged| after Insert mode completion menu changed
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 79f3cd7..a824531 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt* For Vim version 9.1. Last change: 2024 Apr 07
+*builtin.txt* For Vim version 9.1. Last change: 2024 Jun 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -178,6 +178,8 @@ extendnew({expr1}, {expr2} [, {expr3}])
List/Dict like |extend()| but creates a new
List or Dictionary
feedkeys({string} [, {mode}]) Number add key sequence to typeahead buffer
+filecopy({from}, {to}) Number |TRUE| if copying file {from} to {to}
+ worked
filereadable({file}) Number |TRUE| if {file} is a readable file
filewritable({file}) Number |TRUE| if {file} is a writable file
filter({expr1}, {expr2}) List/Dict/Blob/String
@@ -265,6 +267,8 @@ getreg([{regname} [, 1 [, {list}]]])
getreginfo([{regname}]) Dict information about a register
getregion({pos1}, {pos2} [, {opts}])
List get the text from {pos1} to {pos2}
+getregionpos({pos1}, {pos2} [, {opts}])
+ List get a list of positions for a region
getregtype([{regname}]) String type of a register
getscriptinfo([{opts}]) List list of sourced scripts
gettabinfo([{expr}]) List list of tab pages
@@ -765,6 +769,7 @@ xor({expr}, {expr}) Number bitwise XOR
Not all functions are here, some have been moved to a help file covering the
specific functionality.
+Return type specifies the type for |Vim9-script|, see |vim9-types|
abs({expr}) *abs()*
Return the absolute value of {expr}. When {expr} evaluates to
@@ -781,6 +786,8 @@ abs({expr}) *abs()*
Can also be used as a |method|: >
Compute()->abs()
+<
+ Return type: |Number| or |Float| depending on {expr}
acos({expr}) *acos()*
@@ -796,6 +803,8 @@ acos({expr}) *acos()*
Can also be used as a |method|: >
Compute()->acos()
+<
+ Return type: |Float|
add({object}, {expr}) *add()*
@@ -811,6 +820,9 @@ add({object}, {expr}) *add()*
Can also be used as a |method|: >
mylist->add(val1)->add(val2)
+<
+ Return type: list<{type}> (depending on the given |List|) or
+ |Blob|
and({expr}, {expr}) *and()*
@@ -821,6 +833,8 @@ and({expr}, {expr}) *and()*
:let flag = and(bits, 0x80)
< Can also be used as a |method|: >
:let flag = bits->and(0x80)
+<
+ Return type: |Number|
append({lnum}, {text}) *append()*
@@ -842,6 +856,8 @@ append({lnum}, {text}) *append()*
< Can also be used as a |method| after a List, the base is
passed as the second argument: >
mylist->append(lnum)
+<
+ Return type: |Number|
appendbufline({buf}, {lnum}, {text}) *appendbufline()*
@@ -869,6 +885,8 @@ appendbufline({buf}, {lnum}, {text}) *appendbufline()*
Can also be used as a |method| after a List, the base is
passed as the second argument: >
mylist->appendbufline(buf, lnum)
+<
+ Return type: |Number|
argc([{winid}]) *argc()*
@@ -881,10 +899,14 @@ argc([{winid}]) *argc()*
list is used: either the window number or the window ID.
Returns -1 if the {winid} argument is invalid.
+ Return type: |Number|
+
*argidx()*
argidx() The result is the current index in the argument list. 0 is
the first file. argc() - 1 is the last one. See |arglist|.
+ Return type: |Number|
+
*arglistid()*
arglistid([{winnr} [, {tabnr}]])
Return the argument list ID. This is a number which
@@ -898,6 +920,8 @@ arglistid([{winnr} [, {tabnr}]])
page.
{winnr} can be the window number or the |window-ID|.
+ Return type: |Number|
+
*argv()*
argv([{nr} [, {winid}]])
The result is the {nr}th file in the argument list. See
@@ -918,6 +942,9 @@ argv([{nr} [, {winid}]])
the argument list. Returns an empty List if the {winid}
argument is invalid.
+ Return type: |String|
+
+
asin({expr}) *asin()*
Return the arc sine of {expr} measured in radians, as a |Float|
in the range of [-pi/2, pi/2].
@@ -933,12 +960,12 @@ asin({expr}) *asin()*
Can also be used as a |method|: >
Compute()->asin()
-
+<
+ Return type: |Float|
assert_ functions are documented here: |assert-functions-details|
-
atan({expr}) *atan()*
Return the principal value of the arc tangent of {expr}, in
the range [-pi/2, +pi/2] radians, as a |Float|.
@@ -952,6 +979,8 @@ atan({expr}) *atan()*
Can also be used as a |method|: >
Compute()->atan()
+<
+ Return type: |Float|
atan2({expr1}, {expr2}) *atan2()*
@@ -968,6 +997,8 @@ atan2({expr1}, {expr2}) *atan2()*
Can also be used as a |method|: >
Compute()->atan2(1)
+<
+ Return type: |Float|
autocmd_add({acmds}) *autocmd_add()*
@@ -1015,6 +1046,9 @@ autocmd_add({acmds}) *autocmd_add()*
Can also be used as a |method|: >
GetAutocmdList()->autocmd_add()
<
+ Return type: |vim9-boolean|
+
+
autocmd_delete({acmds}) *autocmd_delete()*
Deletes a List of autocmds and autocmd groups.
@@ -1063,6 +1097,9 @@ autocmd_delete({acmds}) *autocmd_delete()*
<
Can also be used as a |method|: >
GetAutocmdList()->autocmd_delete()
+<
+ Return type: |vim9-boolean|
+
autocmd_get([{opts}]) *autocmd_get()*
Returns a |List| of autocmds. If {opts} is not supplied, then
@@ -1121,11 +1158,17 @@ autocmd_get([{opts}]) *autocmd_get()*
Can also be used as a |method|: >
Getopts()->autocmd_get()
<
+ Return type: list<dict<any>>
+
+
balloon_gettext() *balloon_gettext()*
Return the current text in the balloon. Only for the string,
not used for the List. Returns an empty string if balloon
is not present.
+ Return type: |String|
+
+
balloon_show({expr}) *balloon_show()*
Show {expr} inside the balloon. For the GUI {expr} is used as
a string. For a terminal {expr} can be a list, which contains
@@ -1157,6 +1200,9 @@ balloon_show({expr}) *balloon_show()*
{only available when compiled with the |+balloon_eval| or
|+balloon_eval_term| feature}
+ Return type: |Number|
+
+
balloon_split({msg}) *balloon_split()*
Split String {msg} into lines to be displayed in a balloon.
The splits are made for the current window size and optimize
@@ -1169,6 +1215,9 @@ balloon_split({msg}) *balloon_split()*
< {only available when compiled with the |+balloon_eval_term|
feature}
+ Return type: list<any> or list<string>
+
+
blob2list({blob}) *blob2list()*
Return a List containing the number value of each byte in Blob
{blob}. Examples: >
@@ -1180,6 +1229,8 @@ blob2list({blob}) *blob2list()*
Can also be used as a |method|: >
GetBlob()->blob2list()
<
+ Return type: list<any> or list<number>
+
*browse()*
browse({save}, {title}, {initdir}, {default})
Put up a file requester. This only works when "has("browse")"
@@ -1192,8 +1243,10 @@ browse({save}, {title}, {initdir}, {default})
An empty string is returned when the "Cancel" button is hit,
something went wrong, or browsing is not possible.
- *browsedir()*
-browsedir({title}, {initdir})
+ Return type: |String|
+
+
+browsedir({title}, {initdir}) *browsedir()*
Put up a directory requester. This only works when
"has("browse")" returns |TRUE| (only in some GUI versions).
On systems where a directory browser is not supported a file
@@ -1205,6 +1258,9 @@ browsedir({title}, {initdir})
When the "Cancel" button is hit, something went wrong, or
browsing is not possible, an empty string is returned.
+ Return type: |String|
+
+
bufadd({name}) *bufadd()*
Add a buffer to the buffer list with name {name} (must be a
String).
@@ -1220,6 +1276,9 @@ bufadd({name}) *bufadd()*
< Returns 0 on error.
Can also be used as a |method|: >
let bufnr = 'somename'->bufadd()
+<
+ Return type: |Number|
+
bufexists({buf}) *bufexists()*
The result is a Number, which is |TRUE| if a buffer called
@@ -1246,8 +1305,11 @@ bufexists({buf}) *bufexists()*
Can also be used as a |method|: >
let exists = 'somename'->bufexists()
<
+ Return type: |Number|
+
Obsolete name: buffer_exists(). *buffer_exists()*
+
buflisted({buf}) *buflisted()*
The result is a Number, which is |TRUE| if a buffer called
{buf} exists and is listed (has the 'buflisted' option set).
@@ -1255,6 +1317,9 @@ buflisted({buf}) *buflisted()*
Can also be used as a |method|: >
let listed = 'somename'->buflisted()
+<
+ Return type: |Number|
+
bufload({buf}) *bufload()*
Ensure the buffer {buf} is loaded. When the buffer name
@@ -1268,6 +1333,9 @@ bufload({buf}) *bufload()*
Can also be used as a |method|: >
eval 'somename'->bufload()
+<
+ Return type: |Number|
+
bufloaded({buf}) *bufloaded()*
The result is a Number, which is |TRUE| if a buffer called
@@ -1276,6 +1344,9 @@ bufloaded({buf}) *bufloaded()*
Can also be used as a |method|: >
let loaded = 'somename'->bufloaded()
+<
+ Return type: |Number|
+
bufname([{buf}]) *bufname()*
The result is the name of a buffer. Mostly as it is displayed
@@ -1309,11 +1380,13 @@ bufname([{buf}]) *bufname()*
bufname(3) name of buffer 3
bufname("%") name of current buffer
bufname("file2") name of buffer where "file2" matches.
-< *buffer_name()*
+<
+ Return type: |String|
+ *buffer_name()*
Obsolete name: buffer_name().
- *bufnr()*
-bufnr([{buf} [, {create}]])
+
+bufnr([{buf} [, {create}]]) *bufnr()*
The result is the number of a buffer, as it is displayed by
the `:ls` command. For the use of {buf}, see |bufname()|
above.
@@ -1335,10 +1408,13 @@ bufnr([{buf} [, {create}]])
Can also be used as a |method|: >
echo bufref->bufnr()
<
+ Return type: |Number|
+
Obsolete name: buffer_number(). *buffer_number()*
*last_buffer_nr()*
Obsolete name for bufnr("$"): last_buffer_nr().
+
bufwinid({buf}) *bufwinid()*
The result is a Number, which is the |window-ID| of the first
window associated with buffer {buf}. For the use of {buf},
@@ -1352,6 +1428,9 @@ bufwinid({buf}) *bufwinid()*
Can also be used as a |method|: >
FindBuffer()->bufwinid()
+<
+ Return type: |Number|
+
bufwinnr({buf}) *bufwinnr()*
Like |bufwinid()| but return the window number instead of the
@@ -1366,6 +1445,9 @@ bufwinnr({buf}) *bufwinnr()*
Can also be used as a |method|: >
FindBuffer()->bufwinnr()
+<
+ Return type: |Number|
+
byte2line({byte}) *byte2line()*
Return the line number that contains the character at byte
@@ -1379,10 +1461,13 @@ byte2line({byte}) *byte2line()*
Can also be used as a |method|: >
GetOffset()->byte2line()
+<
+ Return type: |Number|
-< {not available when compiled without the |+byte_offset|
+ {not available when compiled without the |+byte_offset|
feature}
+
byteidx({expr}, {nr} [, {utf16}]) *byteidx()*
Return byte index of the {nr}'th character in the String
{expr}. Use zero for the first character, it then returns
@@ -1420,6 +1505,9 @@ byteidx({expr}, {nr} [, {utf16}]) *byteidx()*
<
Can also be used as a |method|: >
GetName()->byteidx(idx)
+<
+ Return type: |Number|
+
byteidxcomp({expr}, {nr} [, {utf16}]) *byteidxcomp()*
Like byteidx(), except that a composing character is counted
@@ -1436,6 +1524,9 @@ byteidxcomp({expr}, {nr} [, {utf16}]) *byteidxcomp()*
Can also be used as a |method|: >
GetName()->byteidxcomp(idx)
+<
+ Return type: |Number|
+
call({func}, {arglist} [, {dict}]) *call()* *E699*
Call function {func} with the items in |List| {arglist} as
@@ -1448,6 +1539,9 @@ call({func}, {arglist} [, {dict}]) *call()* *E699*
Can also be used as a |method|: >
GetFunc()->call([arg, arg], dict)
+<
+ Return type: any, depending on {func}
+
ceil({expr}) *ceil()*
Return the smallest integral value greater than or equal to
@@ -1465,6 +1559,8 @@ ceil({expr}) *ceil()*
Can also be used as a |method|: >
Compute()->ceil()
+<
+ Return type: |Float|
ch_ functions are documented here: |channel-functions-details|
@@ -1479,6 +1575,9 @@ changenr() *changenr()*
one less than the number of the undone change.
Returns 0 if the undo list is empty.
+ Return type: |Number|
+
+
char2nr({string} [, {utf8}]) *char2nr()*
Return Number value of the first char in {string}.
Examples: >
@@ -1500,6 +1599,9 @@ char2nr({string} [, {utf8}]) *char2nr()*
Can also be used as a |method|: >
GetChar()->char2nr()
+<
+ Return type: |Number|
+
charclass({string}) *charclass()*
Return the character class of the first character in {string}.
@@ -1512,6 +1614,8 @@ charclass({string}) *charclass()*
The class is used in patterns and word motions.
Returns 0 if {string} is not a |String|.
+ Return type: |Number|
+
charcol({expr} [, {winid}]) *charcol()*
Same as |col()| but returns the character index of the column
@@ -1525,6 +1629,8 @@ charcol({expr} [, {winid}]) *charcol()*
< Can also be used as a |method|: >
GetPos()->col()
<
+ Return type: |Number|
+
*charidx()*
charidx({string}, {idx} [, {countcc} [, {utf16}]])
Return the character index of the byte at {idx} in {string}.
@@ -1561,6 +1667,9 @@ charidx({string}, {idx} [, {countcc} [, {utf16}]])
<
Can also be used as a |method|: >
GetName()->charidx(idx)
+<
+ Return type: |Number|
+
chdir({dir}) *chdir()*
Change the current working directory to {dir}. The scope of
@@ -1587,6 +1696,9 @@ chdir({dir}) *chdir()*
< Can also be used as a |method|: >
GetDir()->chdir()
<
+ Return type: |String|
+
+
cindent({lnum}) *cindent()*
Get the amount of indent for line {lnum} according the C
indenting rules, as with 'cindent'.
@@ -1597,6 +1709,9 @@ cindent({lnum}) *cindent()*
Can also be used as a |method|: >
GetLnum()->cindent()
+<
+ Return type: |Number|
+
clearmatches([{win}]) *clearmatches()*
Clears all matches previously defined for the current window
@@ -1607,35 +1722,37 @@ clearmatches([{win}]) *clearmatches()*
Can also be used as a |method|: >
GetWin()->clearmatches()
<
+ Return type: |Number|
+
+
col({expr} [, {winid}]) *col()*
The result is a Number, which is the byte index of the column
- position given with {expr}. The accepted positions are:
- . the cursor position
- $ the end of the cursor line (the result is the
- number of bytes in the cursor line plus one)
- 'x position of mark x (if the mark is not set, 0 is
- returned)
- v In Visual mode: the start of the Visual area (the
- cursor is the end). When not in Visual mode
- returns the cursor position. Differs from |'<| in
- that it's updated right away.
+ position given with {expr}.
+ For accepted positions see |getpos()|.
+ When {expr} is "$", it means the end of the cursor line, so
+ the result is the number of bytes in the cursor line plus one.
Additionally {expr} can be [lnum, col]: a |List| with the line
and column number. Most useful when the column is "$", to get
the last column of a specific line. When "lnum" or "col" is
out of range then col() returns zero.
+
With the optional {winid} argument the values are obtained for
that window instead of the current window.
+
To get the line number use |line()|. To get both use
|getpos()|.
For the screen column position use |virtcol()|. For the
character position use |charcol()|.
+
Note that only marks in the current file can be used.
+
Examples: >
col(".") column of cursor
col("$") length of cursor line plus one
col("'t") column of mark t
col("'" .. markname) column of mark markname
-< The first column is 1. Returns 0 if {expr} is invalid or when
+<
+ The first column is 1. Returns 0 if {expr} is invalid or when
the window with ID {winid} is not found.
For an uppercase mark the column may actually be in another
buffer.
@@ -1648,6 +1765,8 @@ col({expr} [, {winid}]) *col()*
< Can also be used as a |method|: >
GetPos()->col()
<
+ Return type: |Number|
+
complete({startcol}, {matches}) *complete()* *E785*
Set the matches for Insert mode completion.
@@ -1682,6 +1801,9 @@ complete({startcol}, {matches}) *complete()* *E785*
Can also be used as a |method|, the base is passed as the
second argument: >
GetMatches()->complete(col('.'))
+<
+ Return type: |Number|
+
complete_add({expr}) *complete_add()*
Add {expr} to the list of matches. Only to be used by the
@@ -1694,6 +1816,9 @@ complete_add({expr}) *complete_add()*
Can also be used as a |method|: >
GetMoreMatches()->complete_add()
+<
+ Return type: |Number|
+
complete_check() *complete_check()*
Check for a key typed while looking for completion matches.
@@ -1703,6 +1828,8 @@ complete_check() *complete_check()*
Only to be used by the function specified with the
'completefunc' option.
+ Return type: |Number|
+
complete_info([{what}]) *complete_info()*
Returns a |Dictionary| with information about Insert mode
@@ -1765,6 +1892,8 @@ complete_info([{what}]) *complete_info()*
< Can also be used as a |method|: >
GetItems()->complete_info()
<
+ Return type: dict<any>
+
*confirm()*
confirm({msg} [, {choices} [, {default} [, {type}]]])
confirm() offers the user a dialog, from which a choice can be
@@ -1824,8 +1953,11 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
Can also be used as a |method|in: >
BuildMessage()->confirm("&Yes\n&No")
<
- *copy()*
-copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't
+ Return type: |Number|
+
+
+copy({expr}) *copy()*
+ Make a copy of {expr}. For Numbers and Strings this isn't
different from using {expr} directly.
When {expr} is a |List| a shallow copy is created. This means
that the original |List| can be changed without changing the
@@ -1835,6 +1967,9 @@ copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't
Also see |deepcopy()|.
Can also be used as a |method|: >
mylist->copy()
+<
+ Return type: any, depending on {expr}
+
cos({expr}) *cos()*
Return the cosine of {expr}, measured in radians, as a |Float|.
@@ -1848,6 +1983,8 @@ cos({expr}) *cos()*
Can also be used as a |method|: >
Compute()->cos()
+<
+ Return type: |Float|
cosh({expr}) *cosh()*
@@ -1863,6 +2000,8 @@ cosh({expr}) *cosh()*
Can also be used as a |method|: >
Compute()->cosh()
+<
+ Return type: |Float|
count({comp}, {expr} [, {ic} [, {start}]]) *count()* *E706*
@@ -1881,6 +2020,8 @@ count({comp}, {expr} [, {ic} [, {start}]]) *count()* *E706*
Can also be used as a |method|: >
mylist->count(val)
<
+ Return type: |Number|
+
*cscope_connection()*
cscope_connection([{num} , {dbpath} [, {prepend}]])
Checks for the existence of a |cscope| connection. If no
@@ -1922,6 +2063,9 @@ cscope_connection([{num} , {dbpath} [, {prepend}]])
cscope_connection(4, "out", "local") 0
cscope_connection(4, "cscope.out", "/usr/local") 1
<
+ Return type: |Number|
+
+
cursor({lnum}, {col} [, {off}]) *cursor()*
cursor({list})
Positions the cursor at the column (byte count) {col} in the
@@ -1957,6 +2101,9 @@ cursor({list})
Can also be used as a |method|: >
GetCursorPos()->cursor()
+<
+ Return type: |Number|
+
debugbreak({pid}) *debugbreak()*
Specifically used to interrupt a program being debugged. It
@@ -1969,6 +2116,9 @@ debugbreak({pid}) *debugbreak()*
Can also be used as a |method|: >
GetPid()->debugbreak()
+<
+ Return type: |Number|
+
deepcopy({expr} [, {noref}]) *deepcopy()* *E698*
Make a copy of {expr}. For Numbers and Strings this isn't
@@ -1994,6 +2144,9 @@ deepcopy({expr} [, {noref}]) *deepcopy()* *E698*
Can also be used as a |method|: >
GetObject()->deepcopy()
+<
+ Return type: any, depending on {expr}
+
delete({fname} [, {flags}]) *delete()*
Without {flags} or with {flags} empty: Deletes the file by the
@@ -2020,6 +2173,9 @@ delete({fname} [, {flags}]) *delete()*
Can also be used as a |method|: >
GetName()->delete()
+<
+ Return type: |Number|
+
deletebufline({buf}, {first} [, {last}]) *deletebufline()*
Delete lines {first} to {last} (inclusive) from buffer {buf}.
@@ -2038,6 +2194,8 @@ deletebufline({buf}, {first} [, {last}]) *deletebufline()*
Can also be used as a |method|: >
GetBuffer()->deletebufline(1)
<
+ Return type: |Number|
+
*did_filetype()*
did_filetype() Returns |TRUE| when autocommands are being executed and the
FileType event has been triggered at least once. Can be used
@@ -2050,6 +2208,9 @@ did_filetype() Returns |TRUE| when autocommands are being executed and the
editing another buffer to set 'filetype' and load a syntax
file.
+ Return type: |Number|
+
+
diff({fromlist}, {tolist} [, {options}]) *diff()*
Returns a String or a List containing the diff between the
strings in {fromlist} and {tolist}. Uses the Vim internal
@@ -2116,6 +2277,10 @@ diff({fromlist}, {tolist} [, {options}]) *diff()*
Can also be used as a |method|: >
GetFromList->diff(to_list)
<
+ Return type: |String| or list<dict<number>> or list<any>
+ depending on {options}
+
+
diff_filler({lnum}) *diff_filler()*
Returns the number of filler lines above line {lnum}.
These are the lines that were inserted at this point in
@@ -2127,6 +2292,9 @@ diff_filler({lnum}) *diff_filler()*
Can also be used as a |method|: >
GetLnum()->diff_filler()
+<
+ Return type: |Number|
+
diff_hlID({lnum}, {col}) *diff_hlID()*
Returns the highlight ID for diff mode at line {lnum} column
@@ -2142,6 +2310,8 @@ diff_hlID({lnum}, {col}) *diff_hlID()*
Can also be used as a |method|: >
GetLnum()->diff_hlID(col)
<
+ Return type: |Number|
+
digraph_get({chars}) *digraph_get()* *E1214*
Return the digraph of {chars}. This should be a string with
@@ -2166,6 +2336,8 @@ digraph_get({chars}) *digraph_get()* *E1214*
Can also be used as a |method|: >
GetChars()->digraph_get()
<
+ Return type: |String|
+
This function works only when compiled with the |+digraphs|
feature. If this feature is disabled, this function will
display an error message.
@@ -2192,6 +2364,8 @@ digraph_getlist([{listall}]) *digraph_getlist()*
Can also be used as a |method|: >
GetNumber()->digraph_getlist()
<
+ Return type: list<list<string>>
+
This function works only when compiled with the |+digraphs|
feature. If this feature is disabled, this function will
display an error message.
@@ -2205,7 +2379,7 @@ digraph_set({chars}, {digraph}) *digraph_set()*
function is similar to |:digraphs| command, but useful to add
digraphs start with a white space.
- The function result is v:true if |digraph| is registered. If
+ The function returns v:true if |digraph| is registered. If
this fails an error message is given and v:false is returned.
If you want to define multiple digraphs at once, you can use
@@ -2217,6 +2391,8 @@ digraph_set({chars}, {digraph}) *digraph_set()*
Can be used as a |method|: >
GetString()->digraph_set('あ')
<
+ Return type: |vim9-boolean|
+
This function works only when compiled with the |+digraphs|
feature. If this feature is disabled, this function will
display an error message.
@@ -2240,6 +2416,8 @@ digraph_setlist({digraphlist}) *digraph_setlist()*
Can be used as a |method|: >
GetList()->digraph_setlist()
<
+ Return type: |vim9-boolean|
+
This function works only when compiled with the |+digraphs|
feature. If this feature is disabled, this function will
display an error message.
@@ -2254,6 +2432,8 @@ echoraw({string}) *echoraw()*
call echoraw(&t_TI)
< Use with care, you can mess up the terminal this way.
+ Return type: |Number|
+
empty({expr}) *empty()*
Return the Number 1 if {expr} is empty, zero otherwise.
@@ -2273,6 +2453,9 @@ empty({expr}) *empty()*
Can also be used as a |method|: >
mylist->empty()
+<
+ Return type: |Number|
+
environ() *environ()*
Return all of environment variables as dictionary. You can
@@ -2281,6 +2464,8 @@ environ() *environ()*
< Note that the variable name may be CamelCase; to ignore case
use this: >
:echo index(keys(environ()), 'HOME', 0, 1) != -1
+<
+ Return type: dict<string>
err_teapot([{expr}]) *err_teapot()*
@@ -2290,6 +2475,8 @@ err_teapot([{expr}]) *err_teapot()*
indicating that coffee is temporarily not available.
If {expr} is present it must be a String.
+ Return type: |Number|
+
escape({string}, {chars}) *escape()*
Escape the characters in {chars} that occur in {string} with a
@@ -2302,6 +2489,8 @@ escape({string}, {chars}) *escape()*
Can also be used as a |method|: >
GetText()->escape(' \')
<
+ Return type: |String|
+
*eval()*
eval({string}) Evaluate {string} and return the result. Especially useful to
turn the result of |string()| back into the original value.
@@ -2312,6 +2501,9 @@ eval({string}) Evaluate {string} and return the result. Especially useful to
Can also be used as a |method|: >
argv->join()->eval()
+<
+ Return type: any, depending on {string}
+
eventhandler() *eventhandler()*
Returns 1 when inside an event handler. That is that Vim got
@@ -2319,6 +2511,9 @@ eventhandler() *eventhandler()*
e.g., when dropping a file on Vim. This means interactive
commands cannot be used. Otherwise zero is returned.
+ Return type: |Number|
+
+
executable({expr}) *executable()*
This function checks if an executable with the name {expr}
exists. {expr} must be the name of the program without any
@@ -2347,6 +2542,9 @@ executable({expr}) *executable()*
Can also be used as a |method|: >
GetCommand()->executable()
+<
+ Return type: |Number|
+
execute({command} [, {silent}]) *execute()*
Execute an Ex command or commands and return the output as a
@@ -2380,6 +2578,9 @@ execute({command} [, {silent}]) *execute()*
Can also be used as a |method|: >
GetCommand()->execute()
+<
+ Return type: |Number|
+
exepath({expr}) *exepath()*
If {expr} is an executable and is either an absolute path, a
@@ -2393,8 +2594,11 @@ exepath({expr}) *exepath()*
Can also be used as a |method|: >
GetCommand()->exepath()
<
- *exists()*
-exists({expr}) The result is a Number, which is |TRUE| if {expr} is defined,
+ Return type: |String|
+
+
+exists({expr}) *exists()*
+ The result is a Number, which is |TRUE| if {expr} is defined,
zero otherwise.
Note: In a compiled |:def| function the evaluation is done at
@@ -2498,6 +2702,8 @@ exists({expr}) The result is a Number, which is |TRUE| if {expr} is defined,
Can also be used as a |method|: >
Varname()->exists()
<
+ Return type: |String|
+
exists_compiled({expr}) *exists_compiled()*
Like `exists()` but evaluated at compile time. This is useful
@@ -2513,6 +2719,8 @@ exists_compiled({expr}) *exists_compiled()*
Can only be used in a |:def| function. *E1233*
This does not work to check for arguments or local variables.
+ Return type: |String|
+
exp({expr}) *exp()*
Return the exponential of {expr} as a |Float| in the range
@@ -2527,6 +2735,8 @@ exp({expr}) *exp()*
Can also be used as a |method|: >
Compute()->exp()
+<
+ Return type: |Float|
expand({string} [, {nosuf} [, {list}]]) *expand()*
@@ -2544,7 +2754,7 @@ expand({string} [, {nosuf} [, {list}]]) *expand()*
not start with '%', '#' or '<', see below.
For a |:terminal| window '%' expands to a '!' followed by
- the command or shell that is run |terminal-bufname|
+ the command or shell that is run. |terminal-bufname|
When {string} starts with '%', '#' or '<', the expansion is
done like for the |cmdline-special| variables with their
@@ -2627,6 +2837,9 @@ expand({string} [, {nosuf} [, {list}]]) *expand()*
Can also be used as a |method|: >
Getpattern()->expand()
+<
+ Return type: |String| or list<string> depending on {list}
+
expandcmd({string} [, {options}]) *expandcmd()*
Expand special items in String {string} like what is done for
@@ -2652,6 +2865,8 @@ expandcmd({string} [, {options}]) *expandcmd()*
Can also be used as a |method|: >
GetCommand()->expandcmd()
<
+ Return type: |String| or list<string> depending on {list}
+
extend({expr1}, {expr2} [, {expr3}]) *extend()*
{expr1} and {expr2} must be both |Lists| or both
|Dictionaries|.
@@ -2690,6 +2905,9 @@ extend({expr1}, {expr2} [, {expr3}]) *extend()*
Can also be used as a |method|: >
mylist->extend(otherlist)
+<
+ Return type: list<{type}> or dict<{type}> depending on {expr1}
+ and {expr2}, in case of error: |Number|
extendnew({expr1}, {expr2} [, {expr3}]) *extendnew()*
@@ -2697,6 +2915,9 @@ extendnew({expr1}, {expr2} [, {expr3}]) *extendnew()*
List or Dictionary is created and returned. {expr1} remains
unchanged.
+ Return type: list<{type}> or dict<{type}> depending on {expr1}
+ and {expr2}, in case of error: |Number|
+
feedkeys({string} [, {mode}]) *feedkeys()*
Characters in {string} are queued for processing as if they
@@ -2754,6 +2975,24 @@ feedkeys({string} [, {mode}]) *feedkeys()*
Can also be used as a |method|: >
GetInput()->feedkeys()
+<
+ Return type: |String| or list<string> depending on {list}
+
+
+filecopy({from}, {to}) *filecopy()*
+ Copy the file pointed to by the name {from} to {to}. The
+ result is a Number, which is |TRUE| if the file was copied
+ successfully, and |FALSE| when it failed.
+ If a file with name {to} already exists, it will fail.
+ Note that it does not handle directories (yet).
+
+ This function is not available in the |sandbox|.
+
+ Can also be used as a |method|: >
+ GetOldName()->filecopy(newname)
+<
+ Return type: |Number|
+
filereadable({file}) *filereadable()*
The result is a Number, which is |TRUE| when a file with the
@@ -2770,7 +3009,10 @@ filereadable({file}) *filereadable()*
< Can also be used as a |method|: >
GetName()->filereadable()
-< *file_readable()*
+<
+ Return type: |Number|
+
+ *file_readable()*
Obsolete name: file_readable().
@@ -2782,6 +3024,8 @@ filewritable({file}) *filewritable()*
Can also be used as a |method|: >
GetName()->filewritable()
+<
+ Return type: |Number|
filter({expr1}, {expr2}) *filter()*
@@ -2844,6 +3088,10 @@ filter({expr1}, {expr2}) *filter()*
Can also be used as a |method|: >
mylist->filter(expr2)
+<
+ Return type: |String|, |Blob|, list<{type}> or dict<{type}>
+ depending on {expr1}
+
finddir({name} [, {path} [, {count}]]) *finddir()*
Find directory {name} in {path}. Supports both downwards and
@@ -2865,6 +3113,9 @@ finddir({name} [, {path} [, {count}]]) *finddir()*
Can also be used as a |method|: >
GetName()->finddir()
+<
+ Return type: |String|
+
findfile({name} [, {path} [, {count}]]) *findfile()*
Just like |finddir()|, but find a file instead of a directory.
@@ -2876,6 +3127,9 @@ findfile({name} [, {path} [, {count}]]) *findfile()*
Can also be used as a |method|: >
GetName()->findfile()
+<
+ Return type: |String|
+
flatten({list} [, {maxdepth}]) *flatten()*
Flatten {list} up to {maxdepth} levels. Without {maxdepth}
@@ -2901,9 +3155,14 @@ flatten({list} [, {maxdepth}]) *flatten()*
Can also be used as a |method|: >
mylist->flatten()
<
+ Return type: list<{type}>
+
+
flattennew({list} [, {maxdepth}]) *flattennew()*
Like |flatten()| but first make a copy of {list}.
+ Return type: list<{type}>
+
float2nr({expr}) *float2nr()*
Convert {expr} to a Number by omitting the part after the
@@ -2929,6 +3188,8 @@ float2nr({expr}) *float2nr()*
Can also be used as a |method|: >
Compute()->float2nr()
+<
+ Return type: |Number|
floor({expr}) *floor()*
@@ -2946,6 +3207,8 @@ floor({expr}) *floor()*
Can also be used as a |method|: >
Compute()->floor()
+<
+ Return type: |Float|
fmod({expr1}, {expr2}) *fmod()*
@@ -2966,6 +3229,8 @@ fmod({expr1}, {expr2}) *fmod()*
Can also be used as a |method|: >
Compute()->fmod(1.22)
+<
+ Return type: |Float|
fnameescape({string}) *fnameescape()*
@@ -2986,6 +3251,9 @@ fnameescape({string}) *fnameescape()*
<
Can also be used as a |method|: >
GetName()->fnameescape()
+<
+ Return type: |String|
+
fnamemodify({fname}, {mods}) *fnamemodify()*
Modify file name {fname} according to {mods}. {mods} is a
@@ -3006,6 +3274,9 @@ fnamemodify({fname}, {mods}) *fnamemodify()*
Can also be used as a |method|: >
GetName()->fnamemodify(':p:h')
+<
+ Return type: |String|
+
foldclosed({lnum}) *foldclosed()*
The result is a Number. If the line {lnum} is in a closed
@@ -3016,6 +3287,9 @@ foldclosed({lnum}) *foldclosed()*
Can also be used as a |method|: >
GetLnum()->foldclosed()
+<
+ Return type: |Number|
+
foldclosedend({lnum}) *foldclosedend()*
The result is a Number. If the line {lnum} is in a closed
@@ -3026,6 +3300,9 @@ foldclosedend({lnum}) *foldclosedend()*
Can also be used as a |method|: >
GetLnum()->foldclosedend()
+<
+ Return type: |Number|
+
foldlevel({lnum}) *foldlevel()*
The result is a Number, which is the foldlevel of line {lnum}
@@ -3042,6 +3319,8 @@ foldlevel({lnum}) *foldlevel()*
Can also be used as a |method|: >
GetLnum()->foldlevel()
<
+ Return type: |Number|
+
*foldtext()*
foldtext() Returns a String, to be displayed for a closed fold. This is
the default function used for the 'foldtext' option and should
@@ -3058,8 +3337,11 @@ foldtext() Returns a String, to be displayed for a closed fold. This is
will be filled with the fold char from the 'fillchars'
setting.
Returns an empty string when there is no fold.
+
+ Return type: |String|
{not available when compiled without the |+folding| feature}
+
foldtextresult({lnum}) *foldtextresult()*
Returns the text that is displayed for the closed fold at line
{lnum}. Evaluates 'foldtext' in the appropriate context.
@@ -3073,6 +3355,9 @@ foldtextresult({lnum}) *foldtextresult()*
Can also be used as a |method|: >
GetLnum()->foldtextresult()
+<
+ Return type: |String|
+
foreach({expr1}, {expr2}) *foreach()*
{expr1} must be a |List|, |String|, |Blob| or |Dictionary|.
@@ -3113,12 +3398,17 @@ foreach({expr1}, {expr2}) *foreach()*
Can also be used as a |method|: >
mylist->foreach(expr2)
<
+ Return type: |String|, |Blob| list<{type}> or dict<{type}>
+ depending on {expr1}
+
*foreground()*
foreground() Move the Vim window to the foreground. Useful when sent from
a client to a Vim server. |remote_send()|
On Win32 systems this might not work, the OS does not always
allow a window to bring itself to the foreground. Use
|remote_foreground()| instead.
+
+ Return type: |Number|
{only in the Win32, Motif and GTK GUI versions and the
Win32 console version}
@@ -3143,8 +3433,10 @@ fullcommand({name} [, {vim9}]) *fullcommand()*
Can also be used as a |method|: >
GetName()->fullcommand()
<
- *funcref()*
-funcref({name} [, {arglist}] [, {dict}])
+ Return type: |String|
+
+
+funcref({name} [, {arglist}] [, {dict}]) *funcref()*
Just like |function()|, but the returned Funcref will lookup
the function by reference, not by name. This matters when the
function {name} is redefined later.
@@ -3159,6 +3451,8 @@ funcref({name} [, {arglist}] [, {dict}])
Can also be used as a |method|: >
GetFuncname()->funcref([arg])
<
+ Return type: func(...): any or |Number| on error
+
*function()* *partial* *E700* *E923*
function({name} [, {arglist}] [, {dict}])
Return a |Funcref| variable that refers to function {name}.
@@ -3241,6 +3535,9 @@ function({name} [, {arglist}] [, {dict}])
Can also be used as a |method|: >
GetFuncname()->function([arg])
+<
+ Return type: func(...): any or |Number| on error
+
garbagecollect([{atexit}]) *garbagecollect()*
Cleanup unused |Lists|, |Dictionaries|, |Channels| and |Jobs|
@@ -3263,18 +3560,27 @@ garbagecollect([{atexit}]) *garbagecollect()*
type a character. To force garbage collection immediately use
|test_garbagecollect_now()|.
+ Return type: |String|
+
+
get({list}, {idx} [, {default}]) *get()*
Get item {idx} from |List| {list}. When this item is not
available return {default}. Return zero when {default} is
omitted.
Preferably used as a |method|: >
mylist->get(idx)
+<
+ Return type: any, depending on {list}
+
get({blob}, {idx} [, {default}])
Get byte {idx} from |Blob| {blob}. When this byte is not
available return {default}. Return -1 when {default} is
omitted.
Preferably used as a |method|: >
myblob->get(idx)
+<
+ Return type: |Number|
+
get({dict}, {key} [, {default}])
Get item with key {key} from |Dictionary| {dict}. When this
item is not available return {default}. Return zero when
@@ -3284,6 +3590,9 @@ get({dict}, {key} [, {default}])
'default' when it does not exist.
Preferably used as a |method|: >
mydict->get(key)
+<
+ Return type: any, depending on {dict}
+
get({func}, {what})
Get item {what} from Funcref {func}. Possible values for
{what} are:
@@ -3295,6 +3604,8 @@ get({func}, {what})
Preferably used as a |method|: >
myfunc->get(what)
<
+ Return type: any, depending on {func}
+
*getbufinfo()*
getbufinfo([{buf}])
getbufinfo([{dict}])
@@ -3370,6 +3681,8 @@ getbufinfo([{dict}])
Can also be used as a |method|: >
GetBufnr()->getbufinfo()
<
+ Return type: list<dict<any>>
+
*getbufline()*
getbufline({buf}, {lnum} [, {end}])
@@ -3400,11 +3713,16 @@ getbufline({buf}, {lnum} [, {end}])
< Can also be used as a |method|: >
GetBufnr()->getbufline(lnum)
<
+ Return type: list<string>
+
*getbufoneline()*
getbufoneline({buf}, {lnum})
Just like `getbufline()` but only get one line and return it
as a string.
+ Return type: |String|
+
+
getbufvar({buf}, {varname} [, {def}]) *getbufvar()*
The result is the value of option or local buffer variable
{varname} in buffer {buf}. Note that the name without "b:"
@@ -3429,12 +3747,17 @@ getbufvar({buf}, {varname} [, {def}]) *getbufvar()*
< Can also be used as a |method|: >
GetBufnr()->getbufvar(varname)
<
+ Return type: any, depending on {varname}
+
+
getcellwidths() *getcellwidths()*
Returns a |List| of cell widths of character ranges overridden
by |setcellwidths()|. The format is equal to the argument of
|setcellwidths()|. If no character ranges have their cell
widths overridden, an empty List is returned.
+ Return type: list<any>
+
getchangelist([{buf}]) *getchangelist()*
Returns the |changelist| for the buffer {buf}. For the use
@@ -3454,6 +3777,9 @@ getchangelist([{buf}]) *getchangelist()*
Can also be used as a |method|: >
GetBufnr()->getchangelist()
+<
+ Return type: list<any>
+
getchar([{expr}]) *getchar()*
Get a single character from the user or input stream.
@@ -3534,6 +3860,9 @@ getchar([{expr}]) *getchar()*
: endwhile
: return c
:endfunction
+<
+ Return type: |Number| or |String|
+
getcharmod() *getcharmod()*
The result is a Number which is the state of the modifiers for
@@ -3551,8 +3880,10 @@ getcharmod() *getcharmod()*
character itself are obtained. Thus Shift-a results in "A"
without a modifier. Returns 0 if no modifiers are used.
- *getcharpos()*
-getcharpos({expr})
+ Return type: |Number|
+
+
+getcharpos({expr}) *getcharpos()*
Get the position for String {expr}. Same as |getpos()| but the
column number in the returned List is a character index
instead of a byte index.
@@ -3567,6 +3898,9 @@ getcharpos({expr})
<
Can also be used as a |method|: >
GetMark()->getcharpos()
+<
+ Return type: list<number>
+
getcharsearch() *getcharsearch()*
Return the current character search information as a {dict}
@@ -3588,6 +3922,8 @@ getcharsearch() *getcharsearch()*
:nnoremap <expr> , getcharsearch().forward ? ',' : ';'
< Also see |setcharsearch()|.
+ Return type: dict<any>
+
getcharstr([{expr}]) *getcharstr()*
Get a single character from the user or input stream as a
@@ -3601,6 +3937,9 @@ getcharstr([{expr}]) *getcharstr()*
Otherwise this works like |getchar()|, except that a number
result is converted to a string.
+ Return type: |String|
+
+
getcmdcompltype() *getcmdcompltype()*
Return the type of the current command-line completion.
Only works when the command line is being edited, thus
@@ -3610,6 +3949,9 @@ getcmdcompltype() *getcmdcompltype()*
|setcmdline()|.
Returns an empty string when completion is not defined.
+ Return type: |String|
+
+
getcmdline() *getcmdline()*
Return the current command-line. Only works when the command
line is being edited, thus requires use of |c_CTRL-\_e| or
@@ -3621,6 +3963,9 @@ getcmdline() *getcmdline()*
Returns an empty string when entering a password or using
|inputsecret()|.
+ Return type: |String|
+
+
getcmdpos() *getcmdpos()*
Return the position of the cursor in the command line as a
byte count. The first column is 1.
@@ -3630,6 +3975,9 @@ getcmdpos() *getcmdpos()*
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()| and
|setcmdline()|.
+ Return type: |Number|
+
+
getcmdscreenpos() *getcmdscreenpos()*
Return the screen position of the cursor in the command line
as a byte count. The first column is 1.
@@ -3640,6 +3988,9 @@ getcmdscreenpos() *getcmdscreenpos()*
Also see |getcmdpos()|, |setcmdpos()|, |getcmdline()| and
|setcmdline()|.
+ Return type: |Number|
+
+
getcmdtype() *getcmdtype()*
Return the current command-line type. Possible return values
are:
@@ -3655,11 +4006,17 @@ getcmdtype() *getcmdtype()*
Returns an empty string otherwise.
Also see |getcmdpos()|, |setcmdpos()| and |getcmdline()|.
+ Return type: |String|
+
+
getcmdwintype() *getcmdwintype()*
Return the current |command-line-window| type. Possible return
values are the same as |getcmdtype()|. Returns an empty string
when not in the command-line window.
+ Return type: |String|
+
+
getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
Return a list of command-line completion matches. The String
{type} argument specifies what for. The following completion
@@ -3734,6 +4091,8 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
Can also be used as a |method|: >
GetPattern()->getcompletion('color')
<
+ Return type: list<string>
+
*getcurpos()*
getcurpos([{winid}])
Get the position of the cursor. This is like getpos('.'), but
@@ -3763,8 +4122,10 @@ getcurpos([{winid}])
Can also be used as a |method|: >
GetWinid()->getcurpos()
<
- *getcursorcharpos()*
-getcursorcharpos([{winid}])
+ Return type: list<number>
+
+
+getcursorcharpos([{winid}]) *getcursorcharpos()*
Same as |getcurpos()| but the column number in the returned
List is a character index instead of a byte index.
@@ -3775,9 +4136,11 @@ getcursorcharpos([{winid}])
<
Can also be used as a |method|: >
GetWinid()->getcursorcharpos()
+<
+ Return type: list<number>
+
-< *getcwd()*
-getcwd([{winnr} [, {tabnr}]])
+getcwd([{winnr} [, {tabnr}]]) *getcwd()*
The result is a String, which is the name of the current
working directory. 'autochdir' is ignored.
@@ -3812,6 +4175,8 @@ getcwd([{winnr} [, {tabnr}]])
< Can also be used as a |method|: >
GetWinnr()->getcwd()
+<
+ Return type: |String|
getenv({name}) *getenv()*
Return the value of environment variable {name}. The {name}
@@ -3825,6 +4190,9 @@ getenv({name}) *getenv()*
Can also be used as a |method|: >
GetVarname()->getenv()
+<
+ Return type: |String| or |Number|
+
getfontname([{name}]) *getfontname()*
Without an argument returns the name of the normal font being
@@ -3840,6 +4208,9 @@ getfontname([{name}]) *getfontname()*
Note that the GTK GUI accepts any font name, thus checking for
a valid name does not work.
+ Return type: |String|
+
+
getfperm({fname}) *getfperm()*
The result is a String, which is the read, write, and execute
permissions of the given file {fname}.
@@ -3858,8 +4229,11 @@ getfperm({fname}) *getfperm()*
Can also be used as a |method|: >
GetFilename()->getfperm()
<
+ Return type: |String|
+
For setting permissions use |setfperm()|.
+
getfsize({fname}) *getfsize()*
The result is a Number, which is the size in bytes of the
given file {fname}.
@@ -3870,6 +4244,9 @@ getfsize({fname}) *getfsize()*
Can also be used as a |method|: >
GetFilename()->getfsize()
+<
+ Return type: |Number|
+
getftime({fname}) *getftime()*
The result is a Number, which is the last modification time of
@@ -3880,6 +4257,9 @@ getftime({fname}) *getftime()*
Can also be used as a |method|: >
GetFilename()->getftime()
+<
+ Return type: |Number|
+
getftype({fname}) *getftype()*
The result is a String, which is a description of the kind of
@@ -3904,12 +4284,17 @@ getftype({fname}) *getftype()*
Can also be used as a |method|: >
GetFilename()->getftype()
+<
+ Return type: |String|
getimstatus() *getimstatus()*
The result is a Number, which is |TRUE| when the IME status is
active and |FALSE| otherwise.
See 'imstatusfunc'.
+ Return type: |Number|
+
+
getjumplist([{winnr} [, {tabnr}]]) *getjumplist()*
Returns the |jumplist| for the specified window.
@@ -3932,8 +4317,10 @@ getjumplist([{winnr} [, {tabnr}]]) *getjumplist()*
Can also be used as a |method|: >
GetWinnr()->getjumplist()
+<
+ Return type: list<any>
-< *getline()*
+ *getline()*
getline({lnum} [, {end}])
Without {end} the result is a String, which is line {lnum}
from the current buffer. Example: >
@@ -3958,8 +4345,10 @@ getline({lnum} [, {end}])
< Can also be used as a |method|: >
ComputeLnum()->getline()
+<
+ Return type: list<string> or |String| depending on {end}
-< To get lines from another buffer see |getbufline()| and
+ To get lines from another buffer see |getbufline()| and
|getbufoneline()|
getloclist({nr} [, {what}]) *getloclist()*
@@ -3992,6 +4381,8 @@ getloclist({nr} [, {what}]) *getloclist()*
Examples (See also |getqflist-examples|): >
:echo getloclist(3, {'all': 0})
:echo getloclist(5, {'filewinid': 0})
+<
+ Return type: list<dict<any>> or list<any>
getmarklist([{buf}]) *getmarklist()*
@@ -4015,6 +4406,9 @@ getmarklist([{buf}]) *getmarklist()*
Can also be used as a |method|: >
GetBufnr()->getmarklist()
+<
+ Return type: list<dict<any>> or list<any>
+
getmatches([{win}]) *getmatches()*
Returns a |List| with all matches previously defined for the
@@ -4041,6 +4435,9 @@ getmatches([{win}]) *getmatches()*
'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
:unlet m
<
+ Return type: list<dict<any>> or list<any>
+
+
getmousepos() *getmousepos()*
Returns a |Dictionary| with the last known position of the
mouse. This can be used in a mapping for a mouse click or in
@@ -4071,21 +4468,55 @@ getmousepos() *getmousepos()*
When using |getchar()| the Vim variables |v:mouse_lnum|,
|v:mouse_col| and |v:mouse_winid| also provide these values.
+ Return type: dict<number>
+
+
getmouseshape() *getmouseshape()*
Returns the name of the currently showing mouse pointer.
When the |+mouseshape| feature is not supported or the shape
is unknown an empty string is returned.
This function is mainly intended for testing.
- *getpid()*
-getpid() Return a Number which is the process ID of the Vim process.
+ Return type: |String|
+
+
+getpid() *getpid()*
+ Return a Number which is the process ID of the Vim process.
On Unix and MS-Windows this is a unique number, until Vim
exits.
- *getpos()*
-getpos({expr}) Get the position for String {expr}. For possible values of
- {expr} see |line()|. For getting the cursor position see
- |getcurpos()|.
+ Return type: |Number|
+
+
+getpos({expr}) *getpos()*
+ Get the position for String {expr}.
+ The accepted values for {expr} are: *E1209*
+ . The cursor position.
+ $ The last line in the current buffer.
+ 'x Position of mark x (if the mark is not set, 0 is
+ returned for all values).
+ w0 First line visible in current window (one if the
+ display isn't updated, e.g. in silent Ex mode).
+ w$ Last line visible in current window (this is one
+ less than "w0" if no lines are visible).
+ v When not in Visual mode, returns the cursor
+ position. In Visual mode, returns the other end
+ of the Visual area. A good way to think about
+ this is that in Visual mode "v" and "." complement
+ each other. While "." refers to the cursor
+ position, "v" refers to where |v_o| would move the
+ cursor. As a result, you can use "v" and "."
+ together to work on all of a selection in
+ characterwise Visual mode. If the cursor is at
+ the end of a characterwise Visual area, "v" refers
+ to the start of the same Visual area. And if the
+ cursor is at the start of a characterwise Visual
+ area, "v" refers to the end of the same Visual
+ area. "v" differs from |'<| and |'>| in that it's
+ updated right away.
+ Note that a mark in another file can be used. The line number
+ then applies to another buffer.
+
The result is a |List| with four numbers:
[bufnum, lnum, col, off]
"bufnum" is zero, unless a mark like '0 or 'A is used, then it
@@ -4096,23 +4527,31 @@ getpos({expr}) Get the position for String {expr}. For possible values of
it is the offset in screen columns from the start of the
character. E.g., a position within a <Tab> or after the last
character.
- Note that for '< and '> Visual mode matters: when it is "V"
- (visual line mode) the column of '< is zero and the column of
- '> is a large number equal to |v:maxcol|.
+
+ For getting the cursor position see |getcurpos()|.
The column number in the returned List is the byte position
within the line. To get the character position in the line,
use |getcharpos()|.
+
+ Note that for '< and '> Visual mode matters: when it is "V"
+ (visual line mode) the column of '< is zero and the column of
+ '> is a large number equal to |v:maxcol|.
A very large column number equal to |v:maxcol| can be returned,
in which case it means "after the end of the line".
If {expr} is invalid, returns a list with all zeros.
+
This can be used to save and restore the position of a mark: >
let save_a_mark = getpos("'a")
...
call setpos("'a", save_a_mark)
-< Also see |getcharpos()|, |getcurpos()| and |setpos()|.
+<
+ Also see |getcharpos()|, |getcurpos()| and |setpos()|.
Can also be used as a |method|: >
GetMark()->getpos()
+<
+ Return type: list<number>
+
getqflist([{what}]) *getqflist()*
Returns a |List| with all the current quickfix errors. Each
@@ -4217,6 +4656,9 @@ getqflist([{what}]) *getqflist()*
:echo getqflist({'nr': 2, 'title': 1})
:echo getqflist({'lines' : ["F1:10:L10"]})
<
+ Return type: list<dict<any>> or list<any>
+
+
getreg([{regname} [, 1 [, {list}]]]) *getreg()*
The result is a String, which is the contents of register
{regname}. Example: >
@@ -4244,6 +4686,9 @@ getreg([{regname} [, 1 [, {list}]]]) *getreg()*
Can also be used as a |method|: >
GetRegname()->getreg()
+<
+ Return type: |String|
+
getreginfo([{regname}]) *getreginfo()*
Returns detailed information about register {regname} as a
@@ -4273,6 +4718,9 @@ getreginfo([{regname}]) *getreginfo()*
Can also be used as a |method|: >
GetRegname()->getreginfo()
+<
+ Return type: dict<any>
+
getregion({pos1}, {pos2} [, {opts}]) *getregion()*
Returns the list of strings from {pos1} to {pos2} from a
@@ -4286,14 +4734,14 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
The optional argument {opts} is a Dict and supports the
following items:
- type Specify the region's selection type
- (default: "v"):
- "v" for |characterwise| mode
- "V" for |linewise| mode
- "<CTRL-V>" for |blockwise-visual| mode
+ type Specify the region's selection type.
+ See |getregtype()| for possible values,
+ except that the width can be omitted
+ and an empty string cannot be used.
+ (default: "v")
exclusive If |TRUE|, use exclusive selection
- for the end position
+ for the end position.
(default: follow 'selection')
You can get the last selection type by |visualmode()|.
@@ -4326,7 +4774,46 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
<
Can also be used as a |method|: >
getpos('.')->getregion(getpos("'a"))
+
+<
+getregionpos({pos1}, {pos2} [, {opts}]) *getregionpos()*
+ Same as |getregion()|, but returns a list of positions
+ describing the buffer text segments bound by {pos1} and
+ {pos2}.
+ The segments are a pair of positions for every line: >
+ [[{start_pos}, {end_pos}], ...]
+<
+ The position is a |List| with four numbers:
+ [bufnum, lnum, col, off]
+ "bufnum" is the buffer number.
+ "lnum" and "col" are the position in the buffer. The first
+ column is 1.
+ If the "off" number of a starting position is non-zero, it is
+ the offset in screen columns from the start of the character.
+ E.g., a position within a <Tab> or after the last character.
+ If the "off" number of an ending position is non-zero, it is
+ the offset of the character's first cell not included in the
+ selection, otherwise all its cells are included.
+
+ Apart from the options supported by |getregion()|, {opts} also
+ supports the following:
+
+ eol If |TRUE|, indicate positions beyond
+ the end of a line with "col" values
+ one more than the length of the line.
+ If |FALSE|, positions are limited
+ within their lines, and if a line is
+ empty or the selection is entirely
+ beyond the end of a line, a "col"
+ value of 0 is used for both positions.
+ (default: |FALSE|)
+
+ Can also be used as a |method|: >
+ getpos('.')->getregionpos(getpos("'a"))
<
+ Return type: list<string>
+
+
getregtype([{regname}]) *getregtype()*
The result is a String, which is type of register {regname}.
The value will be one of:
@@ -4342,6 +4829,8 @@ getregtype([{regname}]) *getregtype()*
Can also be used as a |method|: >
GetRegname()->getregtype()
+<
+ Return type: |String|
getscriptinfo([{opts}]) *getscriptinfo()*
Returns a |List| with information about all the sourced Vim
@@ -4382,8 +4871,11 @@ getscriptinfo([{opts}]) *getscriptinfo()*
Examples: >
:echo getscriptinfo({'name': 'myscript'})
- :echo getscriptinfo({'sid': 15}).variables
+ :echo getscriptinfo({'sid': 15})[0].variables
<
+ Return type: list<dict<any>>
+
+
gettabinfo([{tabnr}]) *gettabinfo()*
If {tabnr} is not specified, then information about all the
tab pages is returned as a |List|. Each List item is a
@@ -4399,6 +4891,9 @@ gettabinfo([{tabnr}]) *gettabinfo()*
Can also be used as a |method|: >
GetTabnr()->gettabinfo()
+<
+ Return type: list<dict<any>>
+
gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
Get the value of a tab-local variable {varname} in tab page
@@ -4412,6 +4907,9 @@ gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
Can also be used as a |method|: >
GetTabnr()->gettabvar(varname)
+<
+ Return type: any, depending on {varname}
+
gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
Get the value of window-local variable {varname} in window
@@ -4441,6 +4939,9 @@ gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
< Can also be used as a |method|: >
GetTabnr()->gettabwinvar(winnr, varname)
+<
+ Return type: any, depending on {varname}
+
gettagstack([{winnr}]) *gettagstack()*
The result is a Dict, which is the tag stack of window {winnr}.
@@ -4472,6 +4973,8 @@ gettagstack([{winnr}]) *gettagstack()*
Can also be used as a |method|: >
GetWinnr()->gettagstack()
+<
+ Return type: dict<any>
gettext({text}) *gettext()*
@@ -4485,6 +4988,8 @@ gettext({text}) *gettext()*
xgettext does not understand escaping in single quoted
strings.
+ Return type: |String|
+
getwininfo([{winid}]) *getwininfo()*
Returns information about windows as a |List| with Dictionaries.
@@ -4525,6 +5030,9 @@ getwininfo([{winid}]) *getwininfo()*
Can also be used as a |method|: >
GetWinnr()->getwininfo()
+<
+ Return type: list<dict<any>>
+
getwinpos([{timeout}]) *getwinpos()*
The result is a |List| with two numbers, the result of
@@ -4549,22 +5057,31 @@ getwinpos([{timeout}]) *getwinpos()*
Can also be used as a |method|: >
GetTimeout()->getwinpos()
<
- *getwinposx()*
-getwinposx() The result is a Number, which is the X coordinate in pixels of
+ Return type: list<number>
+
+
+getwinposx() *getwinposx()*
+ The result is a Number, which is the X coordinate in pixels of
the left hand side of the GUI Vim window. Also works for an
xterm (uses a timeout of 100 msec).
The result will be -1 if the information is not available
(e.g. on the Wayland backend).
The value can be used with `:winpos`.
- *getwinposy()*
-getwinposy() The result is a Number, which is the Y coordinate in pixels of
+ Return type: |Number|
+
+
+getwinposy() *getwinposy()*
+ The result is a Number, which is the Y coordinate in pixels of
the top of the GUI Vim window. Also works for an xterm (uses
a timeout of 100 msec).
The result will be -1 if the information is not available
(e.g. on the Wayland backend).
The value can be used with `:winpos`.
+ Return type: |Number|
+
+
getwinvar({winnr}, {varname} [, {def}]) *getwinvar()*
Like |gettabwinvar()| for the current tabpage.
Examples: >
@@ -4574,6 +5091,9 @@ getwinvar({winnr}, {varname} [, {def}]) *getwinvar()*
< Can also be used as a |method|: >
GetWinnr()->getwinvar(varname)
<
+ Return type: any, depending on {varname}
+
+
glob({expr} [, {nosuf} [, {list} [, {alllinks}]]]) *glob()*
Expand the file wildcards in {expr}. See |wildcards| for the
use of special characters.
@@ -4612,6 +5132,10 @@ glob({expr} [, {nosuf} [, {list} [, {alllinks}]]]) *glob()*
Can also be used as a |method|: >
GetExpr()->glob()
+<
+ Return type: |String| or list<string> or list<any> depending
+ on {list}
+
glob2regpat({string}) *glob2regpat()*
Convert a file pattern, as used by glob(), into a search
@@ -4627,7 +5151,10 @@ glob2regpat({string}) *glob2regpat()*
Can also be used as a |method|: >
GetExpr()->glob2regpat()
-< *globpath()*
+<
+ Return type: |String|
+
+ *globpath()*
globpath({path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
Perform glob() for String {expr} on all directories in {path}
and concatenate the results. Example: >
@@ -4667,8 +5194,11 @@ globpath({path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
second argument: >
GetExpr()->globpath(&rtp)
<
- *has()*
-has({feature} [, {check}])
+ Return type: |String| or list<string> or list<any> depending
+ on {list}
+
+
+has({feature} [, {check}]) *has()*
When {check} is omitted or is zero: The result is a Number,
which is 1 if the feature {feature} is supported, zero
otherwise. The {feature} argument is a string, case is
@@ -4694,6 +5224,8 @@ has({feature} [, {check}])
< If the `endif` would be moved to the second line as "| endif" it
would not be found.
+ Return type: |Number|
+
has_key({dict}, {key}) *has_key()*
The result is a Number, which is TRUE if |Dictionary| {dict}
@@ -4705,6 +5237,9 @@ has_key({dict}, {key}) *has_key()*
Can also be used as a |method|: >
mydict->has_key(key)
+<
+ Return type: |Number|
+
haslocaldir([{winnr} [, {tabnr}]]) *haslocaldir()*
The result is a Number:
@@ -4742,6 +5277,9 @@ haslocaldir([{winnr} [, {tabnr}]]) *haslocaldir()*
<
Can also be used as a |method|: >
GetWinnr()->haslocaldir()
+<
+ Return type: |Number|
+
hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
The result is a Number, which is TRUE if there is a mapping
@@ -4776,6 +5314,9 @@ hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
Can also be used as a |method|: >
GetRHS()->hasmapto()
+<
+ Return type: |Number|
+
histadd({history}, {item}) *histadd()*
Add the String {item} to the history {history} which can be
@@ -4801,6 +5342,9 @@ histadd({history}, {item}) *histadd()*
Can also be used as a |method|, the base is passed as the
second argument: >
GetHistory()->histadd('search')
+<
+ Return type: |Number|
+
histdel({history} [, {item}]) *histdel()*
Clear {history}, i.e. delete all its entries. See |hist-names|
@@ -4836,6 +5380,9 @@ histdel({history} [, {item}]) *histdel()*
<
Can also be used as a |method|: >
GetHistory()->histdel()
+<
+ Return type: |Number|
+
histget({history} [, {index}]) *histget()*
The result is a String, the entry with Number {index} from
@@ -4854,6 +5401,9 @@ histget({history} [, {index}]) *histget()*
<
Can also be used as a |method|: >
GetHistory()->histget()
+<
+ Return type: |String|
+
histnr({history}) *histnr()*
The result is the Number of the current entry in {history}.
@@ -4866,6 +5416,8 @@ histnr({history}) *histnr()*
< Can also be used as a |method|: >
GetHistory()->histnr()
<
+ Return type: |Number|
+
hlexists({name}) *hlexists()*
The result is a Number, which is TRUE if a highlight group
called {name} exists. This is when the group has been
@@ -4878,6 +5430,9 @@ hlexists({name}) *hlexists()*
Can also be used as a |method|: >
GetName()->hlexists()
<
+ Return type: |Number|
+
+
hlget([{name} [, {resolve}]]) *hlget()*
Returns a List of all the highlight group attributes. If the
optional {name} is specified, then returns a List with only
@@ -4929,6 +5484,9 @@ hlget([{name} [, {resolve}]]) *hlget()*
Can also be used as a |method|: >
GetName()->hlget()
<
+ Return type: list<dict<any>>
+
+
hlset({list}) *hlset()*
Creates or modifies the attributes of a List of highlight
groups. Each item in {list} is a dictionary containing the
@@ -4980,8 +5538,10 @@ hlset({list}) *hlset()*
Can also be used as a |method|: >
GetAttrList()->hlset()
<
- *hlID()*
-hlID({name}) The result is a Number, which is the ID of the highlight group
+ Return type: |Number|
+
+hlID({name}) *hlID()*
+ The result is a Number, which is the ID of the highlight group
with name {name}. When the highlight group doesn't exist,
zero is returned.
This can be used to retrieve information about the highlight
@@ -4993,12 +5553,18 @@ hlID({name}) The result is a Number, which is the ID of the highlight group
Can also be used as a |method|: >
GetName()->hlID()
+<
+ Return type: |Number|
+
hostname() *hostname()*
The result is a String, which is the name of the machine on
which Vim is currently running. Machine names greater than
256 characters long are truncated.
+ Return type: |String|
+
+
iconv({string}, {from}, {to}) *iconv()*
The result is a String, which is the text {string} converted
from encoding {from} to encoding {to}.
@@ -5021,8 +5587,11 @@ iconv({string}, {from}, {to}) *iconv()*
Can also be used as a |method|: >
GetText()->iconv('latin1', 'utf-8')
<
- *indent()*
-indent({lnum}) The result is a Number, which is indent of line {lnum} in the
+ Return type: |String|
+
+
+indent({lnum}) *indent()*
+ The result is a Number, which is indent of line {lnum} in the
current buffer. The indent is counted in spaces, the value
of 'tabstop' is relevant. {lnum} is used just like in
|getline()|.
@@ -5031,6 +5600,9 @@ indent({lnum}) The result is a Number, which is indent of line {lnum} in the
Can also be used as a |method|: >
GetLnum()->indent()
+<
+ Return type: |Number|
+
index({object}, {expr} [, {start} [, {ic}]]) *index()*
Find {expr} in {object} and return its index. See
@@ -5059,6 +5631,9 @@ index({object}, {expr} [, {start} [, {ic}]]) *index()*
< Can also be used as a |method|: >
GetObject()->index(what)
+<
+ Return type: |Number|
+
indexof({object}, {expr} [, {opts}]) *indexof()*
Returns the index of an item in {object} where {expr} is
@@ -5100,6 +5675,9 @@ indexof({object}, {expr} [, {opts}]) *indexof()*
< Can also be used as a |method|: >
mylist->indexof(expr)
+<
+ Return type: |Number|
+
input({prompt} [, {text} [, {completion}]]) *input()*
The result is a String, which is whatever the user typed on
@@ -5148,6 +5726,9 @@ input({prompt} [, {text} [, {completion}]]) *input()*
< Can also be used as a |method|: >
GetPrompt()->input()
+<
+ Return type: |String|
+
inputdialog({prompt} [, {text} [, {cancelreturn}]]) *inputdialog()*
Like |input()|, but when the GUI is running and text dialogs
@@ -5165,6 +5746,9 @@ inputdialog({prompt} [, {text} [, {cancelreturn}]]) *inputdialog()*
Can also be used as a |method|: >
GetPrompt()->inputdialog()
+<
+ Return type: |String|
+
inputlist({textlist}) *inputlist()*
{textlist} must be a |List| of strings. This |List| is
@@ -5185,6 +5769,9 @@ inputlist({textlist}) *inputlist()*
< Can also be used as a |method|: >
GetChoices()->inputlist()
+<
+ Return type: |Number|
+
inputrestore() *inputrestore()*
Restore typeahead that was saved with a previous |inputsave()|.
@@ -5192,6 +5779,9 @@ inputrestore() *inputrestore()*
called. Calling it more often is harmless though.
Returns TRUE when there is nothing to restore, FALSE otherwise.
+ Return type: |Number|
+
+
inputsave() *inputsave()*
Preserve typeahead (also from mappings) and clear it, so that
a following prompt gets input from the user. Should be
@@ -5200,6 +5790,9 @@ inputsave() *inputsave()*
many inputrestore() calls.
Returns TRUE when out of memory, FALSE otherwise.
+ Return type: |Number|
+
+
inputsecret({prompt} [, {text}]) *inputsecret()*
This function acts much like the |input()| function with but
two exceptions:
@@ -5213,6 +5806,9 @@ inputsecret({prompt} [, {text}]) *inputsecret()*
Can also be used as a |method|: >
GetPrompt()->inputsecret()
+<
+ Return type: |String|
+
insert({object}, {item} [, {idx}]) *insert()*
When {object} is a |List| or a |Blob| insert {item} at the start
@@ -5234,6 +5830,9 @@ insert({object}, {item} [, {idx}]) *insert()*
Can also be used as a |method|: >
mylist->insert(item)
<
+ Return type: |Number|
+
+
*instanceof()* *E614* *E616* *E693*
instanceof({object}, {class})
The result is a Number, which is |TRUE| when the {object}
@@ -5246,6 +5845,8 @@ instanceof({object}, {class})
< Can also be used as a |method|: >
myobj->instanceof(mytype)
+<
+ Return type: |Number|
interrupt() *interrupt()*
Interrupt script execution. It works more or less like the
@@ -5259,6 +5860,8 @@ interrupt() *interrupt()*
: endif
:endfunction
:au BufWritePre * call s:check_typoname(expand('<amatch>'))
+<
+ Return type: void
invert({expr}) *invert()*
Bitwise invert. The argument is converted to a number. A
@@ -5266,6 +5869,9 @@ invert({expr}) *invert()*
:let bits = invert(bits)
< Can also be used as a |method|: >
:let bits = bits->invert()
+<
+ Return type: |Number|
+
isabsolutepath({path}) *isabsolutepath()*
The result is a Number, which is |TRUE| when {path} is an
@@ -5283,6 +5889,8 @@ isabsolutepath({path}) *isabsolutepath()*
<
Can also be used as a |method|: >
GetName()->isabsolutepath()
+<
+ Return type: |Number|
isdirectory({directory}) *isdirectory()*
@@ -5293,6 +5901,9 @@ isdirectory({directory}) *isdirectory()*
Can also be used as a |method|: >
GetName()->isdirectory()
+<
+ Return type: |Number|
+
isinf({expr}) *isinf()*
Return 1 if {expr} is a positive infinity, or -1 a negative
@@ -5304,6 +5915,9 @@ isinf({expr}) *isinf()*
Can also be used as a |method|: >
Compute()->isinf()
+<
+ Return type: |Number|
+
islocked({expr}) *islocked()* *E786*
The result is a Number, which is |TRUE| when {expr} is the
@@ -5324,6 +5938,9 @@ islocked({expr}) *islocked()* *E786*
Can also be used as a |method|: >
GetName()->islocked()
+<
+ Return type: |Number|
+
isnan({expr}) *isnan()*
Return |TRUE| if {expr} is a float with value NaN. >
@@ -5332,6 +5949,9 @@ isnan({expr}) *isnan()*
Can also be used as a |method|: >
Compute()->isnan()
+<
+ Return type: |Number|
+
items({dict}) *items()*
Return a |List| with all the key-value pairs of {dict}. Each
@@ -5349,6 +5969,9 @@ items({dict}) *items()*
Can also be used as a |method|: >
mydict->items()
+<
+ Return type: list<list<any>> or list<any>
+
job_ functions are documented here: |job-functions-details|
@@ -5366,6 +5989,9 @@ join({list} [, {sep}]) *join()*
Can also be used as a |method|: >
mylist->join()
+<
+ Return type: |String|
+
js_decode({string}) *js_decode()*
This is similar to |json_decode()| with these differences:
@@ -5376,6 +6002,9 @@ js_decode({string}) *js_decode()*
Can also be used as a |method|: >
ReadObject()->js_decode()
+<
+ Return type: any, depending on {varname}
+
js_encode({expr}) *js_encode()*
This is similar to |json_encode()| with these differences:
@@ -5393,6 +6022,9 @@ js_encode({expr}) *js_encode()*
Can also be used as a |method|: >
GetObject()->js_encode()
+<
+ Return type: |String|
+
json_decode({string}) *json_decode()* *E491*
This parses a JSON formatted string and returns the equivalent
@@ -5429,6 +6061,9 @@ json_decode({string}) *json_decode()* *E491*
Can also be used as a |method|: >
ReadObject()->json_decode()
+<
+ Return type: any, depending on {varname}
+
json_encode({expr}) *json_encode()*
Encode {expr} as JSON and return this as a string.
@@ -5459,6 +6094,9 @@ json_encode({expr}) *json_encode()*
Can also be used as a |method|: >
GetObject()->json_encode()
+<
+ Return type: |String|
+
keys({dict}) *keys()*
Return a |List| with all the keys of {dict}. The |List| is in
@@ -5466,6 +6104,9 @@ keys({dict}) *keys()*
Can also be used as a |method|: >
mydict->keys()
+<
+ Return type: list<string>
+
keytrans({string}) *keytrans()*
Turn the internal byte representation of keys into a form that
@@ -5476,9 +6117,12 @@ keytrans({string}) *keytrans()*
Can also be used as a |method|: >
"\<C-Home>"->keytrans()
+<
+ Return type: |String|
+
-< *len()* *E701*
-len({expr}) The result is a Number, which is the length of the argument.
+len({expr}) *len()* *E701*
+ The result is a Number, which is the length of the argument.
When {expr} is a String or a Number the length in bytes is
used, as with |strlen()|.
When {expr} is a |List| the number of items in the |List| is
@@ -5492,8 +6136,11 @@ len({expr}) The result is a Number, which is the length of the argument.
Can also be used as a |method|: >
mylist->len()
+<
+ Return type: |Number|
+
-< *libcall()* *E364* *E368*
+ *libcall()* *E364* *E368*
libcall({libname}, {funcname}, {argument})
Call function {funcname} in the run-time library {libname}
with single argument {argument}.
@@ -5558,30 +6205,22 @@ libcallnr({libname}, {funcname}, {argument})
third argument: >
GetValue()->libcallnr("libc.so", "printf")
<
+ Return type: |String|
+
line({expr} [, {winid}]) *line()*
The result is a Number, which is the line number of the file
position given with {expr}. The {expr} argument is a string.
- The accepted positions are: *E1209*
- . the cursor position
- $ the last line in the current buffer
- 'x position of mark x (if the mark is not set, 0 is
- returned)
- w0 first line visible in current window (one if the
- display isn't updated, e.g. in silent Ex mode)
- w$ last line visible in current window (this is one
- less than "w0" if no lines are visible)
- v In Visual mode: the start of the Visual area (the
- cursor is the end). When not in Visual mode
- returns the cursor position. Differs from |'<| in
- that it's updated right away.
- Note that a mark in another file can be used. The line number
- then applies to another buffer.
+ See |getpos()| for accepted positions.
+
To get the column number use |col()|. To get both use
|getpos()|.
+
With the optional {winid} argument the values are obtained for
that window instead of the current window.
+
Returns 0 for invalid values of {expr} and {winid}.
+
Examples: >
line(".") line number of the cursor
line(".", winid) idem, in window "winid"
@@ -5593,6 +6232,9 @@ line({expr} [, {winid}]) *line()*
Can also be used as a |method|: >
GetValue()->line()
+<
+ Return type: |Number|
+
line2byte({lnum}) *line2byte()*
Return the byte count from the start of the buffer for line
@@ -5610,6 +6252,9 @@ line2byte({lnum}) *line2byte()*
Can also be used as a |method|: >
GetLnum()->line2byte()
+<
+ Return type: |Number|
+
lispindent({lnum}) *lispindent()*
Get the amount of indent for line {lnum} according the lisp
@@ -5621,6 +6266,9 @@ lispindent({lnum}) *lispindent()*
Can also be used as a |method|: >
GetLnum()->lispindent()
+<
+ Return type: |Number|
+
list2blob({list}) *list2blob()*
Return a Blob concatenating all the number values in {list}.
@@ -5634,10 +6282,13 @@ list2blob({list}) *list2blob()*
Can also be used as a |method|: >
GetList()->list2blob()
+<
+ Return type: |Blob|
+
list2str({list} [, {utf8}]) *list2str()*
- Convert each number in {list} to a character string can
- concatenate them all. Examples: >
+ Convert each number in {list} to a character string and
+ concatenates them all. Examples: >
list2str([32]) returns " "
list2str([65, 66, 67]) returns "ABC"
< The same can be done (slowly) with: >
@@ -5653,6 +6304,9 @@ list2str({list} [, {utf8}]) *list2str()*
Can also be used as a |method|: >
GetList()->list2str()
+<
+ Return type: |String|
+
listener_add({callback} [, {buf}]) *listener_add()*
Add a callback function that will be invoked when changes have
@@ -5729,6 +6383,9 @@ listener_add({callback} [, {buf}]) *listener_add()*
Can also be used as a |method|, the base is passed as the
second argument: >
GetBuffer()->listener_add(callback)
+<
+ Return type: |Number|
+
listener_flush([{buf}]) *listener_flush()*
Invoke listener callbacks for buffer {buf}. If there are no
@@ -5740,6 +6397,9 @@ listener_flush([{buf}]) *listener_flush()*
Can also be used as a |method|: >
GetBuffer()->listener_flush()
+<
+ Return type: |Number|
+
listener_remove({id}) *listener_remove()*
Remove a listener previously added with listener_add().
@@ -5748,11 +6408,16 @@ listener_remove({id}) *listener_remove()*
Can also be used as a |method|: >
GetListenerId()->listener_remove()
+<
+ Return type: |Number|
+
localtime() *localtime()*
Return the current time, measured as seconds since 1st Jan
1970. See also |strftime()|, |strptime()| and |getftime()|.
+ Return type: |Number|
+
log({expr}) *log()*
Return the natural logarithm (base e) of {expr} as a |Float|.
@@ -5767,6 +6432,8 @@ log({expr}) *log()*
Can also be used as a |method|: >
Compute()->log()
+<
+ Return type: |Float|
log10({expr}) *log10()*
@@ -5781,6 +6448,9 @@ log10({expr}) *log10()*
Can also be used as a |method|: >
Compute()->log10()
+<
+ Return type: |Float|
+
luaeval({expr} [, {expr}]) *luaeval()*
Evaluate Lua expression {expr} and return its result converted
@@ -5798,8 +6468,11 @@ luaeval({expr} [, {expr}]) *luaeval()*
Can also be used as a |method|: >
GetExpr()->luaeval()
+<
+ Return type: any, depending on {expr}
+
+ {only available when compiled with the |+lua| feature}
-< {only available when compiled with the |+lua| feature}
map({expr1}, {expr2}) *map()*
{expr1} must be a |List|, |String|, |Blob| or |Dictionary|.
@@ -5862,6 +6535,9 @@ map({expr1}, {expr2}) *map()*
Can also be used as a |method|: >
mylist->map(expr2)
+<
+ Return type: |String|, |Blob|, list<{type}> or dict<{type}>
+ depending on {expr1}
maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()*
@@ -5938,6 +6614,9 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()*
< Can also be used as a |method|: >
GetKey()->maparg('n')
+<
+ Return type: |String| or dict<any> depending on {dict}
+
mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()*
Check if there is a mapping that matches with {name} in mode
@@ -5974,6 +6653,8 @@ mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()*
Can also be used as a |method|: >
GetKey()->mapcheck('n')
+<
+ Return type: |String|
maplist([{abbr}]) *maplist()*
@@ -6008,6 +6689,8 @@ maplist([{abbr}]) *maplist()*
(_, m) => m.lhs == 'xyzzy')[0].mode_bits
ounmap xyzzy
echo printf("Operator-pending mode bit: 0x%x", op_bit)
+<
+ Return type: list<dict<any>>
mapnew({expr1}, {expr2}) *mapnew()*
@@ -6016,6 +6699,9 @@ mapnew({expr1}, {expr2}) *mapnew()*
unchanged. Items can still be changed by {expr2}, if you
don't want that use |deepcopy()| first.
+ Return type: |String|, |Blob|, list<{type}> or dict<{type}>
+ depending on {expr1}
+
mapset({mode}, {abbr}, {dict}) *mapset()*
mapset({dict})
@@ -6054,6 +6740,8 @@ mapset({dict})
for d in save_maps
mapset(d)
endfor
+<
+ Return type: |Number|
match({expr}, {pat} [, {start} [, {count}]]) *match()*
@@ -6123,6 +6811,9 @@ match({expr}, {pat} [, {start} [, {count}]]) *match()*
GetText()->match('word')
GetList()->match('word')
<
+ Return type: |Number|
+
+
*matchadd()* *E290* *E798* *E799* *E801* *E957*
matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
Defines a pattern to be highlighted in the current window (a
@@ -6185,6 +6876,9 @@ matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
Can also be used as a |method|: >
GetGroup()->matchadd('TODO')
<
+ Return type: |Number|
+
+
*matchaddpos()*
matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
Same as |matchadd()|, but requires a list of positions {pos}
@@ -6221,6 +6915,9 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
Can also be used as a |method|: >
GetGroup()->matchaddpos([23, 11])
+<
+ Return type: |Number|
+
matcharg({nr}) *matcharg()*
Selects the {nr} match item, as set with a |:match|,
@@ -6237,6 +6934,8 @@ matcharg({nr}) *matcharg()*
Can also be used as a |method|: >
GetMatch()->matcharg()
<
+ Return type: list<string>
+
*matchbufline()*
matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}])
Returns the |List| of matches in lines from {lnum} to {end} in
@@ -6284,6 +6983,9 @@ matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}])
Can also be used as a |method|: >
GetBuffer()->matchbufline('mypat', 1, '$')
+<
+ Return type: list<dict<any>> or list<any>
+
matchdelete({id} [, {win}) *matchdelete()* *E802* *E803*
Deletes a match with ID {id} previously defined by |matchadd()|
@@ -6295,6 +6997,9 @@ matchdelete({id} [, {win}) *matchdelete()* *E802* *E803*
Can also be used as a |method|: >
GetMatch()->matchdelete()
+<
+ Return type: |Number|
+
matchend({expr}, {pat} [, {start} [, {count}]]) *matchend()*
Same as |match()|, but return the index of first character
@@ -6317,6 +7022,8 @@ matchend({expr}, {pat} [, {start} [, {count}]]) *matchend()*
Can also be used as a |method|: >
GetText()->matchend('word')
+<
+ Return type: |Number|
matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()*
@@ -6382,6 +7089,9 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()*
\ {'matchseq': 1})
< results in ['two one'].
+ Return type: list<string> or list<any>
+
+
matchfuzzypos({list}, {str} [, {dict}]) *matchfuzzypos()*
Same as |matchfuzzy()|, but returns the list of matched
strings, the list of character positions where characters
@@ -6403,6 +7113,9 @@ matchfuzzypos({list}, {str} [, {dict}]) *matchfuzzypos()*
:echo [{'text': 'hello', 'id' : 10}]->matchfuzzypos('ll', {'key' : 'text'})
< results in [[{'id': 10, 'text': 'hello'}], [[2, 3]], [127]]
+ Return type: list<list<any>>
+
+
matchlist({expr}, {pat} [, {start} [, {count}]]) *matchlist()*
Same as |match()|, but return a |List|. The first item in the
list is the matched string, same as what matchstr() would
@@ -6418,6 +7131,8 @@ matchlist({expr}, {pat} [, {start} [, {count}]]) *matchlist()*
Can also be used as a |method|: >
GetText()->matchlist('word')
<
+ Return type: list<string> or list<any>
+
*matchstrlist()*
matchstrlist({list}, {pat} [, {dict}])
Returns the |List| of matches in {list} where {pat} matches.
@@ -6454,6 +7169,9 @@ matchstrlist({list}, {pat} [, {dict}])
Can also be used as a |method|: >
GetListOfStrings()->matchstrlist('mypat')
+<
+ Return type: list<dict<any>> or list<any>
+
matchstr({expr}, {pat} [, {start} [, {count}]]) *matchstr()*
Same as |match()|, but return the matched string. Example: >
@@ -6470,6 +7188,9 @@ matchstr({expr}, {pat} [, {start} [, {count}]]) *matchstr()*
Can also be used as a |method|: >
GetText()->matchstr('word')
+<
+ Return type: |String|
+
matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()*
Same as |matchstr()|, but return the matched string, the start
@@ -6492,9 +7213,11 @@ matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()*
Can also be used as a |method|: >
GetText()->matchstrpos('word')
<
+ Return type: list<any>
- *max()*
-max({expr}) Return the maximum value of all items in {expr}. Example: >
+
+max({expr}) *max()*
+ Return the maximum value of all items in {expr}. Example: >
echo max([apples, pears, oranges])
< {expr} can be a |List| or a |Dictionary|. For a Dictionary,
@@ -6505,6 +7228,8 @@ max({expr}) Return the maximum value of all items in {expr}. Example: >
Can also be used as a |method|: >
mylist->max()
+<
+ Return type: |Number|
menu_info({name} [, {mode}]) *menu_info()*
@@ -6579,10 +7304,11 @@ menu_info({name} [, {mode}]) *menu_info()*
<
Can also be used as a |method|: >
GetMenuName()->menu_info('v')
+<
+ Return type: dict<any>
-
-< *min()*
-min({expr}) Return the minimum value of all items in {expr}. Example: >
+min({expr}) *min()*
+ Return the minimum value of all items in {expr}. Example: >
echo min([apples, pears, oranges])
< {expr} can be a |List| or a |Dictionary|. For a Dictionary,
@@ -6593,25 +7319,24 @@ min({expr}) Return the minimum value of all items in {expr}. Example: >
Can also be used as a |method|: >
mylist->min()
+<
+ Return type: |Number|
-< *mkdir()* *E739*
-mkdir({name} [, {flags} [, {prot}]])
+
+mkdir({name} [, {flags} [, {prot}]]) *mkdir()* *E739*
Create directory {name}.
When {flags} is present it must be a string. An empty string
has no effect.
- If {flags} contains "p" then intermediate directories are
- created as necessary.
+ {flags} can contain these character flags:
+ "p" intermediate directories will be created as necessary
+ "D" {name} will be deleted at the end of the current
+ function, but not recursively |:defer|
+ "R" {name} will be deleted recursively at the end of the
+ current function |:defer|
- If {flags} contains "D" then {name} is deleted at the end of
- the current function, as with: >
- defer delete({name}, 'd')
-<
- If {flags} contains "R" then {name} is deleted recursively at
- the end of the current function, as with: >
- defer delete({name}, 'rf')
-< Note that when {name} has more than one part and "p" is used
+ Note that when {name} has more than one part and "p" is used
some directories may already exist. Only the first one that
is created and what it contains is scheduled to be deleted.
E.g. when using: >
@@ -6647,8 +7372,11 @@ mkdir({name} [, {flags} [, {prot}]])
< Can also be used as a |method|: >
GetName()->mkdir()
<
- *mode()*
-mode([{expr}]) Return a string that indicates the current mode.
+ Return type: |Number|
+
+
+mode([{expr}]) *mode()*
+ Return a string that indicates the current mode.
If {expr} is supplied and it evaluates to a non-zero Number or
a non-empty String (|non-zero-arg|), then the full mode is
returned, otherwise only the first letter is returned.
@@ -6704,6 +7432,9 @@ mode([{expr}]) Return a string that indicates the current mode.
Can also be used as a |method|: >
DoFull()->mode()
+<
+ Return type: |String|
+
mzeval({expr}) *mzeval()*
Evaluate MzScheme expression {expr} and return its result
@@ -6726,8 +7457,11 @@ mzeval({expr}) *mzeval()*
Can also be used as a |method|: >
GetExpr()->mzeval()
<
+ Return type: any, depending on {expr}
+
{only available when compiled with the |+mzscheme| feature}
+
nextnonblank({lnum}) *nextnonblank()*
Return the line number of the first line at or below {lnum}
that is not blank. Example: >
@@ -6739,6 +7473,9 @@ nextnonblank({lnum}) *nextnonblank()*
Can also be used as a |method|: >
GetLnum()->nextnonblank()
+<
+ Return type: |Number|
+
nr2char({expr} [, {utf8}]) *nr2char()*
Return a string with a single character, which has the number
@@ -6760,6 +7497,9 @@ nr2char({expr} [, {utf8}]) *nr2char()*
Can also be used as a |method|: >
GetNumber()->nr2char()
+<
+ Return type: |String|
+
or({expr}, {expr}) *or()*
Bitwise OR on the two arguments. The arguments are converted
@@ -6775,6 +7515,8 @@ or({expr}, {expr}) *or()*
to separate commands. In many places it would not be clear if
"|" is an operator or a command separator.
+ Return type: |Number|
+
pathshorten({path} [, {len}]) *pathshorten()*
Shorten directory names in the path {path} and return the
@@ -6792,6 +7534,9 @@ pathshorten({path} [, {len}]) *pathshorten()*
Can also be used as a |method|: >
GetDirectories()->pathshorten()
+<
+ Return type: |String|
+
perleval({expr}) *perleval()*
Evaluate Perl expression {expr} in scalar context and return
@@ -6808,8 +7553,10 @@ perleval({expr}) *perleval()*
Can also be used as a |method|: >
GetExpr()->perleval()
+<
+ Return type: any, depending on {expr}
-< {only available when compiled with the |+perl| feature}
+ {only available when compiled with the |+perl| feature}
popup_ functions are documented here: |popup-functions|
@@ -6829,6 +7576,9 @@ pow({x}, {y}) *pow()*
Can also be used as a |method|: >
Compute()->pow(3)
+<
+ Return type: |Number|
+
prevnonblank({lnum}) *prevnonblank()*
Return the line number of the first line at or above {lnum}
@@ -6841,6 +7591,9 @@ prevnonblank({lnum}) *prevnonblank()*
Can also be used as a |method|: >
GetLnum()->prevnonblank()
+<
+ Return type: |Number|
+
printf({fmt}, {expr1} ...) *printf()*
Return a String with {fmt}, where "%" items are replaced by
@@ -7167,6 +7920,8 @@ printf({fmt}, {expr1} ...) *printf()*
into this, copying the exact format string and parameters that
were used.
+ Return type: |String|
+
prompt_getprompt({buf}) *prompt_getprompt()*
Returns the effective prompt text for buffer {buf}. {buf} can
@@ -7177,8 +7932,10 @@ prompt_getprompt({buf}) *prompt_getprompt()*
Can also be used as a |method|: >
GetBuffer()->prompt_getprompt()
+<
+ Return type: |String|
-< {only available when compiled with the |+channel| feature}
+ {only available when compiled with the |+channel| feature}
prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
@@ -7229,8 +7986,10 @@ prompt_setinterrupt({buf}, {expr}) *prompt_setinterrupt()*
Can also be used as a |method|: >
GetBuffer()->prompt_setinterrupt(callback)
+<
+ Return type: |Number|
-< {only available when compiled with the |+channel| feature}
+ {only available when compiled with the |+channel| feature}
prompt_setprompt({buf}, {text}) *prompt_setprompt()*
Set prompt for buffer {buf} to {text}. You most likely want
@@ -7241,8 +8000,10 @@ prompt_setprompt({buf}, {text}) *prompt_setprompt()*
<
Can also be used as a |method|: >
GetBuffer()->prompt_setprompt('command: ')
+<
+ Return type: |Number|
-< {only available when compiled with the |+channel| feature}
+ {only available when compiled with the |+channel| feature}
prop_ functions are documented here: |text-prop-functions|
@@ -7260,12 +8021,18 @@ pum_getpos() *pum_getpos()*
The values are the same as in |v:event| during
|CompleteChanged|.
+ Return type: dict<any>
+
+
pumvisible() *pumvisible()*
Returns non-zero when the popup menu is visible, zero
otherwise. See |ins-completion-menu|.
This can be used to avoid some things that would remove the
popup menu.
+ Return type: |Number|
+
+
py3eval({expr}) *py3eval()*
Evaluate Python expression {expr} and return its result
converted to Vim data structures.
@@ -7280,8 +8047,10 @@ py3eval({expr}) *py3eval()*
Can also be used as a |method|: >
GetExpr()->py3eval()
+<
+ Return type: any, depending on {expr}
-< {only available when compiled with the |+python3| feature}
+ {only available when compiled with the |+python3| feature}
*E858* *E859*
pyeval({expr}) *pyeval()*
@@ -7297,8 +8066,10 @@ pyeval({expr}) *pyeval()*
Can also be used as a |method|: >
GetExpr()->pyeval()
+<
+ Return type: any, depending on {expr}
-< {only available when compiled with the |+python| feature}
+ {only available when compiled with the |+python| feature}
pyxeval({expr}) *pyxeval()*
Evaluate Python expression {expr} and return its result
@@ -7307,9 +8078,11 @@ pyxeval({expr}) *pyxeval()*
See also: |pyeval()|, |py3eval()|
Can also be used as a |method|: >
- GetExpr()->pyxeval()
+ < GetExpr()->pyxeval()
+<
+ Return type: any, depending on {expr}
-< {only available when compiled with the |+python| or the
+ {only available when compiled with the |+python| or the
|+python3| feature}
rand([{expr}]) *rand()* *random*
@@ -7327,6 +8100,7 @@ rand([{expr}]) *rand()* *random*
:echo rand(seed)
:echo rand(seed) % 16 " random number 0 - 15
<
+ Return type: |Number|
*E726* *E727*
range({expr} [, {max} [, {stride}]]) *range()*
@@ -7350,6 +8124,8 @@ range({expr} [, {max} [, {stride}]]) *range()*
Can also be used as a |method|: >
GetExpr()->range()
<
+ Return type: list<number>
+
readblob({fname} [, {offset} [, {size}]]) *readblob()*
Read file {fname} in binary mode and return a |Blob|.
@@ -7375,6 +8151,8 @@ readblob({fname} [, {offset} [, {size}]]) *readblob()*
is truncated.
Also see |readfile()| and |writefile()|.
+ Return type: |Blob|
+
readdir({directory} [, {expr} [, {dict}]]) *readdir()*
Return a list with file and directory names in {directory}.
@@ -7432,6 +8210,9 @@ readdir({directory} [, {expr} [, {dict}]]) *readdir()*
Can also be used as a |method|: >
GetDirName()->readdir()
<
+ Return type: list<string> or list<any>
+
+
readdirex({directory} [, {expr} [, {dict}]]) *readdirex()*
Extended version of |readdir()|.
Return a list of Dictionaries with file and directory
@@ -7491,6 +8272,8 @@ readdirex({directory} [, {expr} [, {dict}]]) *readdirex()*
Can also be used as a |method|: >
GetDirName()->readdirex()
<
+ Return type: list<dict<any>> or list<any>
+
*readfile()*
readfile({fname} [, {type} [, {max}]])
@@ -7529,6 +8312,8 @@ readfile({fname} [, {type} [, {max}]])
Can also be used as a |method|: >
GetFileName()->readfile()
+<
+ Return type: list<string> or list<any>
reduce({object}, {func} [, {initial}]) *reduce()* *E998*
{func} is called for every item in {object}, which can be a
@@ -7549,6 +8334,9 @@ reduce({object}, {func} [, {initial}]) *reduce()* *E998*
<
Can also be used as a |method|: >
echo mylist->reduce({ acc, val -> acc + val }, 0)
+<
+ Return type: |String|, |Blob|, list<{type}> or dict<{type}>
+ depending on {object} and {func}
reg_executing() *reg_executing()*
@@ -7556,13 +8344,19 @@ reg_executing() *reg_executing()*
Returns an empty string when no register is being executed.
See |@|.
+ Return type: |String|
+
+
reg_recording() *reg_recording()*
Returns the single letter name of the register being recorded.
Returns an empty string when not recording. See |q|.
-reltime()
+ Return type: |String|
+
+
+reltime() *reltime()*
reltime({start})
-reltime({start}, {end}) *reltime()*
+reltime({start}, {end})
Return an item that represents a time value. The item is a
list with items that depend on the system. In Vim 9 script
the type list<any> can be used.
@@ -7588,8 +8382,11 @@ reltime({start}, {end}) *reltime()*
Can also be used as a |method|: >
GetStart()->reltime()
<
+ Return type: list<number>
+
{only available when compiled with the |+reltime| feature}
+
reltimefloat({time}) *reltimefloat()*
Return a Float that represents the time value of {time}.
Example: >
@@ -7603,8 +8400,11 @@ reltimefloat({time}) *reltimefloat()*
Can also be used as a |method|: >
reltime(start)->reltimefloat()
+<
+ Return type: |Float|
+
+ {only available when compiled with the |+reltime| feature}
-< {only available when compiled with the |+reltime| feature}
reltimestr({time}) *reltimestr()*
Return a String that represents the time value of {time}.
@@ -7625,8 +8425,10 @@ reltimestr({time}) *reltimestr()*
Can also be used as a |method|: >
reltime(start)->reltimestr()
+<
+ Return type: |String|
-< {only available when compiled with the |+reltime| feature}
+ {only available when compiled with the |+reltime| feature}
*remote_expr()* *E449*
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
@@ -7663,6 +8465,9 @@ remote_expr({server}, {string} [, {idvar} [, {timeout}]])
<
Can also be used as a |method|: >
ServerName()->remote_expr(expr)
+<
+ Return type: |String| or list<{type}>
+
remote_foreground({server}) *remote_foreground()*
Move the Vim server with the name {server} to the foreground.
@@ -7678,8 +8483,10 @@ remote_foreground({server}) *remote_foreground()*
Can also be used as a |method|: >
ServerName()->remote_foreground()
+<
+ Return type: |Number|
-< {only in the Win32, Motif and GTK GUI versions and the
+ {only in the Win32, Motif and GTK GUI versions and the
Win32 console version}
@@ -7699,6 +8506,9 @@ remote_peek({serverid} [, {retvar}]) *remote_peek()*
< Can also be used as a |method|: >
ServerId()->remote_peek()
+<
+ Return type: |Number|
+
remote_read({serverid}, [{timeout}]) *remote_read()*
Return the oldest available reply from {serverid} and consume
@@ -7714,8 +8524,10 @@ remote_read({serverid}, [{timeout}]) *remote_read()*
< Can also be used as a |method|: >
ServerId()->remote_read()
<
- *remote_send()* *E241*
-remote_send({server}, {string} [, {idvar}])
+ Return type: |String|
+
+
+remote_send({server}, {string} [, {idvar}]) *remote_send()* *E241*
Send the {string} to {server}. The {server} argument is a
string, also see |{server}|.
@@ -7745,19 +8557,24 @@ remote_send({server}, {string} [, {idvar}])
Can also be used as a |method|: >
ServerName()->remote_send(keys)
<
- *remote_startserver()* *E941* *E942*
-remote_startserver({name})
+ Return type: |String|
+
+
+remote_startserver({name}) *remote_startserver()* *E941* *E942*
Become the server {name}. {name} must be a non-empty string.
This fails if already running as a server, when |v:servername|
is not empty.
Can also be used as a |method|: >
ServerName()->remote_startserver()
+<
+ Return type: |Number|
+
+ {only available when compiled with the |+clientserver| feature}
-< {only available when compiled with the |+clientserver| feature}
-remove({list}, {idx})
-remove({list}, {idx}, {end}) *remove()*
+remove({list}, {idx}) *remove()*
+remove({list}, {idx}, {end})
Without {end}: Remove the item at {idx} from |List| {list} and
return the item.
With {end}: Remove items from {idx} to {end} (inclusive) and
@@ -7774,6 +8591,9 @@ remove({list}, {idx}, {end}) *remove()*
Can also be used as a |method|: >
mylist->remove(idx)
+<
+ Return type: any, depending on {list}
+
remove({blob}, {idx})
remove({blob}, {idx}, {end})
@@ -7787,6 +8607,8 @@ remove({blob}, {idx}, {end})
Example: >
:echo "last byte: " .. remove(myblob, -1)
:call remove(mylist, 0, 9)
+<
+ Return type: |Number|
remove({dict}, {key})
Remove the entry from {dict} with key {key} and return it.
@@ -7795,6 +8617,9 @@ remove({dict}, {key})
< If there is no {key} in {dict} this is an error.
Returns zero on error.
+ Return type: any, depending on {dict}
+
+
rename({from}, {to}) *rename()*
Rename the file by the name {from} to the name {to}. This
should also work to move files across file systems. The
@@ -7805,6 +8630,9 @@ rename({from}, {to}) *rename()*
Can also be used as a |method|: >
GetOldName()->rename(newname)
+<
+ Return type: |Number|
+
repeat({expr}, {count}) *repeat()*
Repeat {expr} {count} times and return the concatenated
@@ -7818,6 +8646,10 @@ repeat({expr}, {count}) *repeat()*
Can also be used as a |method|: >
mylist->repeat(count)
+<
+ Return type: |String|, |Blob| or list<{type}> depending on
+ {expr}
+
resolve({filename}) *resolve()* *E655*
On MS-Windows, when {filename} is a shortcut (a .lnk file),
@@ -7837,6 +8669,9 @@ resolve({filename}) *resolve()* *E655*
Can also be used as a |method|: >
GetName()->resolve()
+<
+ Return type: |String|
+
reverse({object}) *reverse()*
Reverse the order of items in {object}. {object} can be a
@@ -7849,6 +8684,10 @@ reverse({object}) *reverse()*
:let revlist = reverse(copy(mylist))
< Can also be used as a |method|: >
mylist->reverse()
+<
+ Return type: |String|, |Blob| or list<{type}> depending on
+ {object}
+
round({expr}) *round()*
Round off {expr} to the nearest integral value and return it
@@ -7866,6 +8705,9 @@ round({expr}) *round()*
Can also be used as a |method|: >
Compute()->round()
+<
+ Return type: |Float|
+
rubyeval({expr}) *rubyeval()*
Evaluate Ruby expression {expr} and return its result
@@ -7881,8 +8723,10 @@ rubyeval({expr}) *rubyeval()*
Can also be used as a |method|: >
GetRubyExpr()->rubyeval()
+<
+ Return type: any, depending on {expr}
-< {only available when compiled with the |+ruby| feature}
+ {only available when compiled with the |+ruby| feature}
screenattr({row}, {col}) *screenattr()*
Like |screenchar()|, but return the attribute. This is a rather
@@ -7892,6 +8736,9 @@ screenattr({row}, {col}) *screenattr()*
Can also be used as a |method|: >
GetRow()->screenattr(col)
+<
+ Return type: |Number|
+
screenchar({row}, {col}) *screenchar()*
The result is a Number, which is the character at position
@@ -7905,6 +8752,9 @@ screenchar({row}, {col}) *screenchar()*
Can also be used as a |method|: >
GetRow()->screenchar(col)
+<
+ Return type: |Number|
+
screenchars({row}, {col}) *screenchars()*
The result is a |List| of Numbers. The first number is the same
@@ -7915,6 +8765,9 @@ screenchars({row}, {col}) *screenchars()*
Can also be used as a |method|: >
GetRow()->screenchars(col)
+<
+ Return type: list<number> or list<any>
+
screencol() *screencol()*
The result is a Number, which is the current screen column of
@@ -7930,6 +8783,9 @@ screencol() *screencol()*
nnoremap <silent> GG :echom screencol()<CR>
nnoremap GG <Cmd>echom screencol()<CR>
<
+ Return type: |Number|
+
+
screenpos({winid}, {lnum}, {col}) *screenpos()*
The result is a Dict with the screen position of the text
character in window {winid} at buffer line {lnum} and column
@@ -7956,6 +8812,9 @@ screenpos({winid}, {lnum}, {col}) *screenpos()*
Can also be used as a |method|: >
GetWinid()->screenpos(lnum, col)
+<
+ Return type: dict<number> or dict<any>
+
screenrow() *screenrow()*
The result is a Number, which is the current screen row of the
@@ -7965,6 +8824,9 @@ screenrow() *screenrow()*
Note: Same restrictions as with |screencol()|.
+ Return type: |Number|
+
+
screenstring({row}, {col}) *screenstring()*
The result is a String that contains the base character and
any composing characters at position [row, col] on the screen.
@@ -7976,6 +8838,8 @@ screenstring({row}, {col}) *screenstring()*
Can also be used as a |method|: >
GetRow()->screenstring(col)
<
+ Return type: |String|
+
*search()*
search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Search for regexp pattern {pattern}. The search starts at the
@@ -8082,6 +8946,9 @@ search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Can also be used as a |method|: >
GetPattern()->search()
+<
+ Return type: |Number|
+
searchcount([{options}]) *searchcount()*
Get or update the last search count, like what is displayed
@@ -8208,6 +9075,9 @@ searchcount([{options}]) *searchcount()*
Can also be used as a |method|: >
GetSearchOpts()->searchcount()
<
+ Return type: dict<number>
+
+
searchdecl({name} [, {global} [, {thisblock}]]) *searchdecl()*
Search for the declaration of {name}.
@@ -8229,6 +9099,8 @@ searchdecl({name} [, {global} [, {thisblock}]]) *searchdecl()*
Can also be used as a |method|: >
GetName()->searchdecl()
<
+ Return type: |Number|
+
*searchpair()*
searchpair({start}, {middle}, {end} [, {flags} [, {skip}
[, {stopline} [, {timeout}]]]])
@@ -8317,6 +9189,8 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip}
:echo searchpair('{', '', '}', 'bW',
\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"')
<
+ Return type: |Number|
+
*searchpairpos()*
searchpairpos({start}, {middle}, {end} [, {flags} [, {skip}
[, {stopline} [, {timeout}]]]])
@@ -8330,6 +9204,8 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip}
<
See |match-parens| for a bigger and more useful example.
+ Return type: list<number>
+
*searchpos()*
searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Same as |search()|, but returns a |List| with the line and
@@ -8348,6 +9224,9 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
Can also be used as a |method|: >
GetPattern()->searchpos()
+<
+ Return type: list<number>
+
server2client({clientid}, {string}) *server2client()*
Send a reply string to {clientid}. The most recent {clientid}
@@ -8365,6 +9244,9 @@ server2client({clientid}, {string}) *server2client()*
< Can also be used as a |method|: >
GetClientId()->server2client(string)
<
+ Return type: |Number|
+
+
serverlist() *serverlist()*
Return a list of available server names, one per line.
When there are no servers or the information is not available
@@ -8373,6 +9255,9 @@ serverlist() *serverlist()*
Example: >
:echo serverlist()
<
+ Return type: |String|
+
+
setbufline({buf}, {lnum}, {text}) *setbufline()*
Set line {lnum} to {text} in buffer {buf}. This works like
|setline()| for the specified buffer.
@@ -8403,6 +9288,9 @@ setbufline({buf}, {lnum}, {text}) *setbufline()*
Can also be used as a |method|, the base is passed as the
third argument: >
GetText()->setbufline(buf, lnum)
+<
+ Return type: |Number|
+
setbufvar({buf}, {varname}, {val}) *setbufvar()*
Set option or local variable {varname} in buffer {buf} to
@@ -8421,6 +9309,8 @@ setbufvar({buf}, {varname}, {val}) *setbufvar()*
Can also be used as a |method|, the base is passed as the
third argument: >
GetValue()->setbufvar(buf, varname)
+<
+ Return type: |Number|
setcellwidths({list}) *setcellwidths()*
@@ -8457,6 +9347,8 @@ setcellwidths({list}) *setcellwidths()*
match with what Vim knows about each emoji. If it doesn't
look right you need to adjust the {list} argument.
+ Return type: |Number|
+
setcharpos({expr}, {list}) *setcharpos()*
Same as |setpos()| but uses the specified column number as the
@@ -8471,6 +9363,9 @@ setcharpos({expr}, {list}) *setcharpos()*
Can also be used as a |method|: >
GetPosition()->setcharpos('.')
+<
+ Return type: |Number|
+
setcharsearch({dict}) *setcharsearch()*
Set the current character search information to {dict},
@@ -8494,6 +9389,9 @@ setcharsearch({dict}) *setcharsearch()*
Can also be used as a |method|: >
SavedSearch()->setcharsearch()
+<
+ Return type: dict<any>
+
setcmdline({str} [, {pos}]) *setcmdline()*
Set the command line to {str} and set the cursor position to
@@ -8504,6 +9402,9 @@ setcmdline({str} [, {pos}]) *setcmdline()*
Can also be used as a |method|: >
GetText()->setcmdline()
+<
+ Return type: |Number|
+
setcmdpos({pos}) *setcmdpos()*
Set the cursor position in the command line to byte position
@@ -8522,6 +9423,9 @@ setcmdpos({pos}) *setcmdpos()*
Can also be used as a |method|: >
GetPos()->setcmdpos()
+<
+ Return type: |Number|
+
setcursorcharpos({lnum}, {col} [, {off}]) *setcursorcharpos()*
setcursorcharpos({list})
@@ -8537,6 +9441,8 @@ setcursorcharpos({list})
Can also be used as a |method|: >
GetCursorPos()->setcursorcharpos()
+<
+ Return type: |Number|
setenv({name}, {val}) *setenv()*
@@ -8549,6 +9455,9 @@ setenv({name}, {val}) *setenv()*
Can also be used as a |method|, the base is passed as the
second argument: >
GetPath()->setenv('PATH')
+<
+ Return type: |Number|
+
setfperm({fname}, {mode}) *setfperm()* *chmod*
Set the file permissions for {fname} to {mode}.
@@ -8570,11 +9479,14 @@ setfperm({fname}, {mode}) *setfperm()* *chmod*
<
To read permissions see |getfperm()|.
+ Return type: |Number|
+
setline({lnum}, {text}) *setline()*
Set line {lnum} of the current buffer to {text}. To insert
lines use |append()|. To set lines in another buffer use
- |setbufline()|. Any text properties in {lnum} are cleared.
+ |setbufline()|.
+ Any text properties in {lnum} are cleared |text-prop-cleared|.
{lnum} is used like with |getline()|.
When {lnum} is just below the last line the {text} will be
@@ -8603,6 +9515,9 @@ setline({lnum}, {text}) *setline()*
Can also be used as a |method|, the base is passed as the
second argument: >
GetText()->setline(lnum)
+<
+ Return type: |Number|
+
setloclist({nr}, {list} [, {action} [, {what}]]) *setloclist()*
Create or replace or add to the location list for window {nr}.
@@ -8623,6 +9538,9 @@ setloclist({nr}, {list} [, {action} [, {what}]]) *setloclist()*
Can also be used as a |method|, the base is passed as the
second argument: >
GetLoclist()->setloclist(winnr)
+<
+ Return type: |Number|
+
setmatches({list} [, {win}]) *setmatches()*
Restores a list of matches saved by |getmatches()| for the
@@ -8635,8 +9553,10 @@ setmatches({list} [, {win}]) *setmatches()*
Can also be used as a |method|: >
GetMatches()->setmatches()
<
- *setpos()*
-setpos({expr}, {list})
+ Return type: |Number|
+
+
+setpos({expr}, {list}) *setpos()*
Set the position for String {expr}. Possible values:
. the cursor
'x mark x
@@ -8687,6 +9607,9 @@ setpos({expr}, {list})
Can also be used as a |method|: >
GetPosition()->setpos('.')
+<
+ Return type: |Number|
+
setqflist({list} [, {action} [, {what}]]) *setqflist()*
Create or replace or add to the quickfix list.
@@ -8805,8 +9728,10 @@ setqflist({list} [, {action} [, {what}]]) *setqflist()*
second argument: >
GetErrorlist()->setqflist()
<
- *setreg()*
-setreg({regname}, {value} [, {options}])
+ Return type: |Number|
+
+
+setreg({regname}, {value} [, {options}]) *setreg()*
Set the register {regname} to {value}.
If {regname} is "" or "@", the unnamed register '"' is used.
The {regname} argument is a string. In |Vim9-script|
@@ -8864,6 +9789,9 @@ setreg({regname}, {value} [, {options}])
< Can also be used as a |method|, the base is passed as the
second argument: >
GetText()->setreg('a')
+<
+ Return type: |Number|
+
settabvar({tabnr}, {varname}, {val}) *settabvar()*
Set tab-local variable {varname} to {val} in tab page {tabnr}.
@@ -8878,6 +9806,9 @@ settabvar({tabnr}, {varname}, {val}) *settabvar()*
Can also be used as a |method|, the base is passed as the
third argument: >
GetValue()->settabvar(tab, name)
+<
+ Return type: |Number|
+
settabwinvar({tabnr}, {winnr}, {varname}, {val}) *settabwinvar()*
Set option or local variable {varname} in window {winnr} to
@@ -8900,6 +9831,9 @@ settabwinvar({tabnr}, {winnr}, {varname}, {val}) *settabwinvar()*
Can also be used as a |method|, the base is passed as the
fourth argument: >
GetValue()->settabwinvar(tab, winnr, name)
+<
+ Return type: |Number|
+
settagstack({nr}, {dict} [, {action}]) *settagstack()*
Modify the tag stack of the window {nr} using {dict}.
@@ -8937,6 +9871,9 @@ settagstack({nr}, {dict} [, {action}]) *settagstack()*
Can also be used as a |method|, the base is passed as the
second argument: >
GetStack()->settagstack(winnr)
+<
+ Return type: |Number|
+
setwinvar({winnr}, {varname}, {val}) *setwinvar()*
Like |settabwinvar()| for the current tab page.
@@ -8947,6 +9884,9 @@ setwinvar({winnr}, {varname}, {val}) *setwinvar()*
< Can also be used as a |method|, the base is passed as the
third argument: >
GetValue()->setwinvar(winnr, name)
+<
+ Return type: |Number|
+
sha256({string}) *sha256()*
Returns a String with 64 hex characters, which is the SHA256
@@ -8954,8 +9894,10 @@ sha256({string}) *sha256()*
Can also be used as a |method|: >
GetText()->sha256()
+<
+ Return type: |String|
-< {only available when compiled with the |+cryptv| feature}
+ {only available when compiled with the |+cryptv| feature}
shellescape({string} [, {special}]) *shellescape()*
Escape {string} for use as a shell command argument.
@@ -8969,11 +9911,12 @@ shellescape({string} [, {special}]) *shellescape()*
Otherwise it will enclose {string} in single quotes and
replace all "'" with "'\''".
- When the {special} argument is present and it's a non-zero
- Number or a non-empty String (|non-zero-arg|), then special
- items such as "!", "%", "#" and "<cword>" will be preceded by
- a backslash. This backslash will be removed again by the |:!|
- command.
+ The {special} argument adds additional escaping of keywords
+ used in Vim commands. When it is not omitted and a non-zero
+ number or a non-empty String (|non-zero-arg|), then special
+ items such as "!", "%", "#" and "<cword>" (as listed in
+ |expand()|) will be preceded by a backslash.
+ This backslash will be removed again by the |:!| command.
The "!" character will be escaped (again with a |non-zero-arg|
{special}) when 'shell' contains "csh" in the tail. That is
@@ -8997,6 +9940,9 @@ shellescape({string} [, {special}]) *shellescape()*
Can also be used as a |method|: >
GetCommand()->shellescape()
+<
+ Return type: |String|
+
shiftwidth([{col}]) *shiftwidth()*
Returns the effective value of 'shiftwidth'. This is the
@@ -9012,6 +9958,8 @@ shiftwidth([{col}]) *shiftwidth()*
Can also be used as a |method|: >
GetColumn()->shiftwidth()
+<
+ Return type: |Number|
sign_ functions are documented here: |sign-functions-details|
@@ -9035,6 +9983,9 @@ simplify({filename}) *simplify()*
Can also be used as a |method|: >
GetName()->simplify()
+<
+ Return type: |String|
+
sin({expr}) *sin()*
Return the sine of {expr}, measured in radians, as a |Float|.
@@ -9048,6 +9999,8 @@ sin({expr}) *sin()*
Can also be used as a |method|: >
Compute()->sin()
+<
+ Return type: |Float|
sinh({expr}) *sinh()*
@@ -9063,6 +10016,8 @@ sinh({expr}) *sinh()*
Can also be used as a |method|: >
Compute()->sinh()
+<
+ Return type: |Float|
slice({expr}, {start} [, {end}]) *slice()*
@@ -9077,6 +10032,8 @@ slice({expr}, {start} [, {end}]) *slice()*
Can also be used as a |method|: >
GetList()->slice(offset)
+<
+ Return type: list<{type}>
sort({list} [, {how} [, {dict}]]) *sort()* *E702*
@@ -9156,12 +10113,17 @@ sort({list} [, {how} [, {dict}]]) *sort()* *E702*
< For a simple expression you can use a lambda: >
eval mylist->sort({i1, i2 -> i1 - i2})
<
+ Return type: list<{type}>
+
+
sound_clear() *sound_clear()*
Stop playing all sounds.
On some Linux systems you may need the libcanberra-pulse
package, otherwise sound may not stop.
+ Return type: |Number|
+
{only available when compiled with the |+sound| feature}
*sound_playevent()*
@@ -9197,8 +10159,10 @@ sound_playevent({name} [, {callback}])
Can also be used as a |method|: >
GetSoundName()->sound_playevent()
+<
+ Return type: |Number|
-< {only available when compiled with the |+sound| feature}
+ {only available when compiled with the |+sound| feature}
*sound_playfile()*
sound_playfile({path} [, {callback}])
@@ -9209,8 +10173,10 @@ sound_playfile({path} [, {callback}])
< Can also be used as a |method|: >
GetSoundPath()->sound_playfile()
+<
+ Return type: |Number|
-< {only available when compiled with the |+sound| feature}
+ {only available when compiled with the |+sound| feature}
sound_stop({id}) *sound_stop()*
@@ -9225,8 +10191,10 @@ sound_stop({id}) *sound_stop()*
Can also be used as a |method|: >
soundid->sound_stop()
+<
+ Return type: |Number|
-< {only available when compiled with the |+sound| feature}
+ {only available when compiled with the |+sound| feature}
*soundfold()*
soundfold({word})
@@ -9240,8 +10208,10 @@ soundfold({word})
Can also be used as a |method|: >
GetWord()->soundfold()
<
- *spellbadword()*
-spellbadword([{sentence}])
+ Return type: |String|
+
+
+spellbadword([{sentence}]) *spellbadword()*
Without argument: The result is the badly spelled word under
or after the cursor. The cursor is moved to the start of the
bad word. When no bad word is found in the cursor line the
@@ -9268,8 +10238,10 @@ spellbadword([{sentence}])
Can also be used as a |method|: >
GetText()->spellbadword()
<
- *spellsuggest()*
-spellsuggest({word} [, {max} [, {capital}]])
+ Return type: list<string>
+
+
+spellsuggest({word} [, {max} [, {capital}]]) *spellsuggest()*
Return a |List| with spelling suggestions to replace {word}.
When {max} is given up to this number of suggestions are
returned. Otherwise up to 25 suggestions are returned.
@@ -9292,6 +10264,9 @@ spellsuggest({word} [, {max} [, {capital}]])
Can also be used as a |method|: >
GetWord()->spellsuggest()
+<
+ Return type: list<string> or list<any>
+
split({string} [, {pattern} [, {keepempty}]]) *split()*
Make a |List| out of {string}. When {pattern} is omitted or
@@ -9318,6 +10293,8 @@ split({string} [, {pattern} [, {keepempty}]]) *split()*
Can also be used as a |method|: >
GetString()->split()
+<
+ Return type: list<string>
sqrt({expr}) *sqrt()*
Return the non-negative square root of Float {expr} as a
@@ -9334,6 +10311,8 @@ sqrt({expr}) *sqrt()*
Can also be used as a |method|: >
Compute()->sqrt()
+<
+ Return type: |Float|
srand([{expr}]) *srand()*
@@ -9349,6 +10328,9 @@ srand([{expr}]) *srand()*
:let seed = srand()
:let seed = srand(userinput)
:echo rand(seed)
+<
+ Return type: list<number>
+
state([{what}]) *state()*
Return a string which contains characters indicating the
@@ -9386,6 +10368,9 @@ state([{what}]) *state()*
recursiveness up to "ccc")
s screen has scrolled for messages
+ Return type: |String|
+
+
str2float({string} [, {quoted}]) *str2float()*
Convert String {string} to a Float. This mostly works the
same as when using a floating point number in an expression,
@@ -9407,6 +10392,9 @@ str2float({string} [, {quoted}]) *str2float()*
Can also be used as a |method|: >
let f = text->substitute(',', '', 'g')->str2float()
+<
+ Return type: |Float|
+
str2list({string} [, {utf8}]) *str2list()*
Return a list containing the number values which represent
@@ -9423,6 +10411,8 @@ str2list({string} [, {utf8}]) *str2list()*
< Can also be used as a |method|: >
GetString()->str2list()
+<
+ Return type: list<number>
str2nr({string} [, {base} [, {quoted}]]) *str2nr()*
@@ -9446,6 +10436,8 @@ str2nr({string} [, {base} [, {quoted}]]) *str2nr()*
Can also be used as a |method|: >
GetText()->str2nr()
+<
+ Return type: |Number|
strcharlen({string}) *strcharlen()*
@@ -9460,6 +10452,8 @@ strcharlen({string}) *strcharlen()*
Can also be used as a |method|: >
GetText()->strcharlen()
+<
+ Return type: |Number|
strcharpart({src}, {start} [, {len} [, {skipcc}]]) *strcharpart()*
@@ -9479,6 +10473,8 @@ strcharpart({src}, {start} [, {len} [, {skipcc}]]) *strcharpart()*
Can also be used as a |method|: >
GetText()->strcharpart(5)
+<
+ Return type: |String|
strchars({string} [, {skipcc}]) *strchars()*
@@ -9511,6 +10507,9 @@ strchars({string} [, {skipcc}]) *strchars()*
<
Can also be used as a |method|: >
GetText()->strchars()
+<
+ Return type: |Number|
+
strdisplaywidth({string} [, {col}]) *strdisplaywidth()*
The result is a Number, which is the number of display cells
@@ -9528,6 +10527,9 @@ strdisplaywidth({string} [, {col}]) *strdisplaywidth()*
Can also be used as a |method|: >
GetText()->strdisplaywidth()
+<
+ Return type: |Number|
+
strftime({format} [, {time}]) *strftime()*
The result is a String, which is a formatted date and time, as
@@ -9550,6 +10552,9 @@ strftime({format} [, {time}]) *strftime()*
< Can also be used as a |method|: >
GetFormat()->strftime()
+<
+ Return type: |String|
+
strgetchar({str}, {index}) *strgetchar()*
Get a Number corresponding to the character at {index} in
@@ -9562,6 +10567,9 @@ strgetchar({str}, {index}) *strgetchar()*
Can also be used as a |method|: >
GetText()->strgetchar(5)
+<
+ Return type: |Number|
+
stridx({haystack}, {needle} [, {start}]) *stridx()*
The result is a Number, which gives the byte index in
@@ -9585,8 +10593,11 @@ stridx({haystack}, {needle} [, {start}]) *stridx()*
Can also be used as a |method|: >
GetHaystack()->stridx(needle)
<
- *string()*
-string({expr}) Return {expr} converted to a String. If {expr} is a Number,
+ Return type: |Number|
+
+
+string({expr}) *string()*
+ Return {expr} converted to a String. If {expr} is a Number,
Float, String, Blob or a composition of them, then the result
can be parsed back with |eval()|.
{expr} type result ~
@@ -9615,6 +10626,8 @@ string({expr}) Return {expr} converted to a String. If {expr} is a Number,
< Also see |strtrans()|.
+ Return type: |String|
+
strlen({string}) *strlen()*
The result is a Number, which is the length of the String
@@ -9627,6 +10640,9 @@ strlen({string}) *strlen()*
Can also be used as a |method|: >
GetString()->strlen()
+<
+ Return type: |Number|
+
strpart({src}, {start} [, {len} [, {chars}]]) *strpart()*
The result is a String, which is part of {src}, starting from
@@ -9655,6 +10671,9 @@ strpart({src}, {start} [, {len} [, {chars}]]) *strpart()*
Can also be used as a |method|: >
GetText()->strpart(5)
+<
+ Return type: |String|
+
strptime({format}, {timestring}) *strptime()*
The result is a Number, which is a unix timestamp representing
@@ -9685,6 +10704,9 @@ strptime({format}, {timestring}) *strptime()*
<
Not available on all systems. To check use: >
:if exists("*strptime")
+<
+ Return type: |Number|
+
strridx({haystack}, {needle} [, {start}]) *strridx()*
The result is a Number, which gives the byte index in
@@ -9706,6 +10728,9 @@ strridx({haystack}, {needle} [, {start}]) *strridx()*
Can also be used as a |method|: >
GetHaystack()->strridx(needle)
+<
+ Return type: |Number|
+
strtrans({string}) *strtrans()*
The result is a String, which is {string} with all unprintable
@@ -9719,6 +10744,9 @@ strtrans({string}) *strtrans()*
Can also be used as a |method|: >
GetString()->strtrans()
+<
+ Return type: |String|
+
strutf16len({string} [, {countcc}]) *strutf16len()*
The result is a Number, which is the number of UTF-16 code
@@ -9742,6 +10770,9 @@ strutf16len({string} [, {countcc}]) *strutf16len()*
Can also be used as a |method|: >
GetText()->strutf16len()
<
+ Return type: |Number|
+
+
strwidth({string}) *strwidth()*
The result is a Number, which is the number of display cells
String {string} occupies. A Tab character is counted as one
@@ -9753,6 +10784,9 @@ strwidth({string}) *strwidth()*
Can also be used as a |method|: >
GetString()->strwidth()
+<
+ Return type: |Number|
+
submatch({nr} [, {list}]) *submatch()* *E935*
Only for an expression in a |:substitute| command or
@@ -9784,6 +10818,9 @@ submatch({nr} [, {list}]) *submatch()* *E935*
Can also be used as a |method|: >
GetNr()->submatch()
+<
+ Return type: |String| or list<string> depending on {list}
+
substitute({string}, {pat}, {sub}, {flags}) *substitute()*
The result is a String, which is a copy of {string}, in which
@@ -9830,6 +10867,9 @@ substitute({string}, {pat}, {sub}, {flags}) *substitute()*
Can also be used as a |method|: >
GetString()->substitute(pat, sub, flags)
+<
+ Return type: |String|
+
swapfilelist() *swapfilelist()*
Returns a list of swap file names, like what "vim -r" shows.
@@ -9841,6 +10881,9 @@ swapfilelist() *swapfilelist()*
let &directory = '.'
let swapfiles = swapfilelist()
let &directory = save_dir
+<
+ Return type: list<string>
+
swapinfo({fname}) *swapinfo()*
The result is a dictionary, which holds information about the
@@ -9863,6 +10906,9 @@ swapinfo({fname}) *swapinfo()*
Can also be used as a |method|: >
GetFilename()->swapinfo()
+<
+ Return type: dict<any> or dict<string>
+
swapname({buf}) *swapname()*
The result is the swap file path of the buffer {expr}.
@@ -9873,6 +10919,9 @@ swapname({buf}) *swapname()*
Can also be used as a |method|: >
GetBufname()->swapname()
+<
+ Return type: |String|
+
synID({lnum}, {col}, {trans}) *synID()*
The result is a Number, which is the syntax ID at the position
@@ -9899,6 +10948,8 @@ synID({lnum}, {col}, {trans}) *synID()*
Example (echoes the name of the syntax item under the cursor): >
:echo synIDattr(synID(line("."), col("."), 1), "name")
<
+ Return type: |Number|
+
synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
The result is a String, which is the {what} attribute of
@@ -9942,6 +10993,8 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
<
Can also be used as a |method|: >
:echo synID(line("."), col("."), 1)->synIDtrans()->synIDattr("fg")
+<
+ Return type: |String|
synIDtrans({synID}) *synIDtrans()*
@@ -9954,6 +11007,9 @@ synIDtrans({synID}) *synIDtrans()*
Can also be used as a |method|: >
:echo synID(line("."), col("."), 1)->synIDtrans()->synIDattr("fg")
+<
+ Return type: |Number|
+
synconcealed({lnum}, {col}) *synconcealed()*
The result is a |List| with currently three items:
@@ -9983,6 +11039,8 @@ synconcealed({lnum}, {col}) *synconcealed()*
Note: Doesn't consider |matchadd()| highlighting items,
since syntax and matching highlighting are two different
mechanisms |syntax-vs-match|.
+<
+ Return type: list<any>
synstack({lnum}, {col}) *synstack()*
@@ -10004,6 +11062,9 @@ synstack({lnum}, {col}) *synstack()*
character in a line and the first column in an empty line are
valid positions.
+ Return type: list<number> or list<any>
+
+
system({expr} [, {input}]) *system()* *E677*
Get the output of the shell command {expr} as a |String|. See
|systemlist()| to get the output as a |List|.
@@ -10066,6 +11127,8 @@ system({expr} [, {input}]) *system()* *E677*
Can also be used as a |method|: >
:echo GetCmd()->system()
+<
+ Return type: |String|
systemlist({expr} [, {input}]) *systemlist()*
@@ -10084,6 +11147,8 @@ systemlist({expr} [, {input}]) *systemlist()*
Can also be used as a |method|: >
:echo GetCmd()->systemlist()
+<
+ Return type: list<string>
tabpagebuflist([{arg}]) *tabpagebuflist()*
@@ -10101,6 +11166,9 @@ tabpagebuflist([{arg}]) *tabpagebuflist()*
Can also be used as a |method|: >
GetTabpage()->tabpagebuflist()
+<
+ Return type: list<number>
+
tabpagenr([{arg}]) *tabpagenr()*
The result is a Number, which is the number of the current
@@ -10116,6 +11184,8 @@ tabpagenr([{arg}]) *tabpagenr()*
Returns zero on error.
+ Return type: |Number|
+
tabpagewinnr({tabarg} [, {arg}]) *tabpagewinnr()*
Like |winnr()| but for tab page {tabarg}.
@@ -10133,10 +11203,15 @@ tabpagewinnr({tabarg} [, {arg}]) *tabpagewinnr()*
Can also be used as a |method|: >
GetTabpage()->tabpagewinnr()
<
- *tagfiles()*
-tagfiles() Returns a |List| with the file names used to search for tags
+ Return type: |Number|
+
+
+tagfiles() *tagfiles()*
+ Returns a |List| with the file names used to search for tags
for the current buffer. This is the 'tags' option expanded.
+ Return type: list<string> or list<any>
+
taglist({expr} [, {filename}]) *taglist()*
Returns a |List| of tags matching the regular expression {expr}.
@@ -10183,6 +11258,9 @@ taglist({expr} [, {filename}]) *taglist()*
Can also be used as a |method|: >
GetTagpattern()->taglist()
+<
+ Return type: list<dict<any>> or list<any>
+
tan({expr}) *tan()*
Return the tangent of {expr}, measured in radians, as a |Float|
@@ -10197,6 +11275,8 @@ tan({expr}) *tan()*
Can also be used as a |method|: >
Compute()->tan()
+<
+ Return type: |Float|
tanh({expr}) *tanh()*
@@ -10212,6 +11292,8 @@ tanh({expr}) *tanh()*
Can also be used as a |method|: >
Compute()->tanh()
+<
+ Return type: |Float|
tempname() *tempname()* *temp-file-name*
@@ -10220,11 +11302,15 @@ tempname() *tempname()* *temp-file-name*
is different for at least 26 consecutive calls. Example: >
:let tmpfile = tempname()
:exe "redir > " .. tmpfile
-< For Unix, the file will be in a private directory |tempfile|.
+< For Unix, the file will be in a private directory |tempfile|
+ that is recursively deleted when Vim exits, on other systems
+ temporary files are not cleaned up automatically on exit.
For MS-Windows forward slashes are used when the 'shellslash'
option is set, or when 'shellcmdflag' starts with '-' and
'shell' does not contain powershell or pwsh.
+ Return type: |String|
+
term_ functions are documented here: |terminal-function-details|
@@ -10263,6 +11349,8 @@ terminalprops() *terminalprops()*
- |v:termstyleresp| and |v:termblinkresp| for the response to
|t_RS| and |t_RC|.
+ Return type: dict<string>
+
test_ functions are documented here: |test-functions-details|
@@ -10287,8 +11375,11 @@ timer_info([{id}])
Can also be used as a |method|: >
GetTimer()->timer_info()
+<
+ Return type: list<dict<any>> or list<any>
+
+ {only available when compiled with the |+timers| feature}
-< {only available when compiled with the |+timers| feature}
timer_pause({timer}, {paused}) *timer_pause()*
Pause or unpause a timer. A paused timer does not invoke its
@@ -10305,8 +11396,11 @@ timer_pause({timer}, {paused}) *timer_pause()*
Can also be used as a |method|: >
GetTimer()->timer_pause(1)
+<
+ Return type: |Number|
+
+ {only available when compiled with the |+timers| feature}
-< {only available when compiled with the |+timers| feature}
*timer_start()* *timer* *timers*
timer_start({time}, {callback} [, {options}])
@@ -10349,8 +11443,12 @@ timer_start({time}, {callback} [, {options}])
GetMsec()->timer_start(callback)
< Not available in the |sandbox|.
+
+ Return type: |Number|
+
{only available when compiled with the |+timers| feature}
+
timer_stop({timer}) *timer_stop()*
Stop a timer. The timer callback will no longer be invoked.
{timer} is an ID returned by timer_start(), thus it must be a
@@ -10358,16 +11456,22 @@ timer_stop({timer}) *timer_stop()*
Can also be used as a |method|: >
GetTimer()->timer_stop()
+<
+ Return type: |Number|
+
+ {only available when compiled with the |+timers| feature}
-< {only available when compiled with the |+timers| feature}
timer_stopall() *timer_stopall()*
Stop all timers. The timer callbacks will no longer be
invoked. Useful if a timer is misbehaving. If there are no
timers there is no error.
+ Return type: |Number|
+
{only available when compiled with the |+timers| feature}
+
tolower({expr}) *tolower()*
The result is a copy of the String given, with all uppercase
characters turned into lowercase (just like applying |gu| to
@@ -10375,6 +11479,9 @@ tolower({expr}) *tolower()*
Can also be used as a |method|: >
GetText()->tolower()
+<
+ Return type: |String|
+
toupper({expr}) *toupper()*
The result is a copy of the String given, with all lowercase
@@ -10383,6 +11490,9 @@ toupper({expr}) *toupper()*
Can also be used as a |method|: >
GetText()->toupper()
+<
+ Return type: |String|
+
tr({src}, {fromstr}, {tostr}) *tr()*
The result is a copy of the {src} string with all characters
@@ -10402,6 +11512,9 @@ tr({src}, {fromstr}, {tostr}) *tr()*
Can also be used as a |method|: >
GetText()->tr(from, to)
+<
+ Return type: |String|
+
trim({text} [, {mask} [, {dir}]]) *trim()*
Return {text} as a String where any character in {mask} is
@@ -10433,6 +11546,9 @@ trim({text} [, {mask} [, {dir}]]) *trim()*
Can also be used as a |method|: >
GetText()->trim()
+<
+ Return type: |String|
+
trunc({expr}) *trunc()*
Return the largest integral value with magnitude less than or
@@ -10450,6 +11566,9 @@ trunc({expr}) *trunc()*
Can also be used as a |method|: >
Compute()->trunc()
<
+ Return type: |Float|
+
+
*type()*
type({expr}) The result is a Number representing the type of {expr}.
Instead of using the number directly, it is better to use the
@@ -10484,6 +11603,8 @@ type({expr}) The result is a Number representing the type of {expr}.
< Can also be used as a |method|: >
mylist->type()
+<
+ Return type: |Number|
typename({expr}) *typename()*
@@ -10492,6 +11613,8 @@ typename({expr}) *typename()*
echo typename([1, 2, 3])
< list<number> ~
+ Return type: |String|
+
undofile({name}) *undofile()*
Return the name of the undo file that would be used for a file
@@ -10508,6 +11631,9 @@ undofile({name}) *undofile()*
Can also be used as a |method|: >
GetFilename()->undofile()
+<
+ Return type: |String|
+
undotree([{buf}]) *undotree()*
Return the current state of the undo tree for the current
@@ -10553,6 +11679,9 @@ undotree([{buf}]) *undotree()*
blocks. Each item may again have an "alt"
item.
+ Return type: dict<any>
+
+
uniq({list} [, {func} [, {dict}]]) *uniq()* *E882*
Remove second and succeeding copies of repeated adjacent
{list} items in-place. Returns {list}. If you want a list
@@ -10566,6 +11695,9 @@ uniq({list} [, {func} [, {dict}]]) *uniq()* *E882*
Can also be used as a |method|: >
mylist->uniq()
<
+ Return type: list<{type}>
+
+
*utf16idx()*
utf16idx({string}, {idx} [, {countcc} [, {charidx}]])
Same as |charidx()| but returns the UTF-16 code unit index of
@@ -10596,6 +11728,8 @@ utf16idx({string}, {idx} [, {countcc} [, {charidx}]])
<
Can also be used as a |method|: >
GetName()->utf16idx(idx)
+<
+ Return type: |Number|
values({dict}) *values()*
@@ -10605,6 +11739,9 @@ values({dict}) *values()*
Can also be used as a |method|: >
mydict->values()
+<
+ Return type: list<any>
+
virtcol({expr} [, {list} [, {winid}]]) *virtcol()*
The result is a Number, which is the screen column of the file
@@ -10616,7 +11753,9 @@ virtcol({expr} [, {list} [, {winid}]]) *virtcol()*
set to 8, it returns 8. |conceal| is ignored.
For the byte position use |col()|.
- For the use of {expr} see |col()|.
+ For the use of {expr} see |getpos()| and |col()|.
+ When {expr} is "$", it means the end of the cursor line, so
+ the result is the number of cells in the cursor line plus one.
When 'virtualedit' is used {expr} can be [lnum, col, off],
where "off" is the offset in screen columns from the start of
@@ -10626,18 +11765,6 @@ virtcol({expr} [, {list} [, {winid}]]) *virtcol()*
beyond the end of the line can be returned. Also see
|'virtualedit'|
- The accepted positions are:
- . the cursor position
- $ the end of the cursor line (the result is the
- number of displayed characters in the cursor line
- plus one)
- 'x position of mark x (if the mark is not set, 0 is
- returned)
- v In Visual mode: the start of the Visual area (the
- cursor is the end). When not in Visual mode
- returns the cursor position. Differs from |'<| in
- that it's updated right away.
-
If {list} is present and non-zero then virtcol() returns a
List with the first and last screen position occupied by the
character.
@@ -10646,6 +11773,7 @@ virtcol({expr} [, {list} [, {winid}]]) *virtcol()*
that window instead of the current window.
Note that only marks in the current file can be used.
+
Examples: >
" With text "foo^Lbar" and cursor on the "^L":
@@ -10656,13 +11784,18 @@ virtcol({expr} [, {list} [, {winid}]]) *virtcol()*
" With text " there", with 't at 'h':
virtcol("'t") " returns 6
-< The first column is 1. 0 or [0, 0] is returned for an error.
+<
+ The first column is 1. 0 or [0, 0] is returned for an error.
+
A more advanced example that echoes the maximum length of
all lines: >
echo max(map(range(1, line('$')), "virtcol([v:val, '$'])"))
< Can also be used as a |method|: >
GetPos()->virtcol()
+<
+ Return type: |Number|
+
virtcol2col({winid}, {lnum}, {col}) *virtcol2col()*
The result is a Number, which is the byte index of the
@@ -10688,6 +11821,9 @@ virtcol2col({winid}, {lnum}, {col}) *virtcol2col()*
Can also be used as a |method|: >
GetWinid()->virtcol2col(lnum, col)
+<
+ Return type: |Number|
+
visualmode([{expr}]) *visualmode()*
The result is a String, which describes the last Visual mode
@@ -10707,6 +11843,9 @@ visualmode([{expr}]) *visualmode()*
a non-empty String, then the Visual mode will be cleared and
the old value is returned. See |non-zero-arg|.
+ Return type: |String|
+
+
wildmenumode() *wildmenumode()*
Returns |TRUE| when the wildmenu is active and |FALSE|
otherwise. See 'wildmenu' and 'wildmode'.
@@ -10718,6 +11857,9 @@ wildmenumode() *wildmenumode()*
<
(Note, this needs the 'wildcharm' option set appropriately).
+ Return type: |Number|
+
+
win_execute({id}, {command} [, {silent}]) *win_execute()*
Like `execute()` but in the context of window {id}.
The window will temporarily be made the current window,
@@ -10736,6 +11878,9 @@ win_execute({id}, {command} [, {silent}]) *win_execute()*
Can also be used as a |method|, the base is passed as the
second argument: >
GetCommand()->win_execute(winid)
+<
+ Return type: |String|
+
win_findbuf({bufnr}) *win_findbuf()*
Returns a |List| with |window-ID|s for windows that contain
@@ -10743,6 +11888,9 @@ win_findbuf({bufnr}) *win_findbuf()*
Can also be used as a |method|: >
GetBufnr()->win_findbuf()
+<
+ Return type: list<number> or list<any>
+
win_getid([{win} [, {tab}]]) *win_getid()*
Get the |window-ID| for the specified window.
@@ -10755,6 +11903,8 @@ win_getid([{win} [, {tab}]]) *win_getid()*
Can also be used as a |method|: >
GetWinnr()->win_getid()
+<
+ Return type: |Number|
win_gettype([{nr}]) *win_gettype()*
@@ -10780,6 +11930,9 @@ win_gettype([{nr}]) *win_gettype()*
Can also be used as a |method|: >
GetWinid()->win_gettype()
<
+ Return type: |String|
+
+
win_gotoid({expr}) *win_gotoid()*
Go to window with ID {expr}. This may also change the current
tabpage.
@@ -10787,6 +11940,9 @@ win_gotoid({expr}) *win_gotoid()*
Can also be used as a |method|: >
GetWinid()->win_gotoid()
+<
+ Return type: |Number|
+
win_id2tabwin({expr}) *win_id2tabwin()*
Return a list with the tab number and window number of window
@@ -10795,6 +11951,9 @@ win_id2tabwin({expr}) *win_id2tabwin()*
Can also be used as a |method|: >
GetWinid()->win_id2tabwin()
+<
+ Return type: list<number>
+
win_id2win({expr}) *win_id2win()*
Return the window number of window with ID {expr}.
@@ -10802,6 +11961,9 @@ win_id2win({expr}) *win_id2win()*
Can also be used as a |method|: >
GetWinid()->win_id2win()
+<
+ Return type: |Number|
+
win_move_separator({nr}, {offset}) *win_move_separator()*
Move window {nr}'s vertical separator (i.e., the right border)
@@ -10820,6 +11982,9 @@ win_move_separator({nr}, {offset}) *win_move_separator()*
Can also be used as a |method|: >
GetWinnr()->win_move_separator(offset)
+<
+ Return type: |Number|
+
win_move_statusline({nr}, {offset}) *win_move_statusline()*
Move window {nr}'s status line (i.e., the bottom border) by
@@ -10835,6 +12000,9 @@ win_move_statusline({nr}, {offset}) *win_move_statusline()*
Can also be used as a |method|: >
GetWinnr()->win_move_statusline(offset)
+<
+ Return type: |Number|
+
win_screenpos({nr}) *win_screenpos()*
Return the screen position of window {nr} as a list with two
@@ -10847,6 +12015,9 @@ win_screenpos({nr}) *win_screenpos()*
Can also be used as a |method|: >
GetWinid()->win_screenpos()
<
+ Return type: list<number>
+
+
win_splitmove({nr}, {target} [, {options}]) *win_splitmove()*
Temporarily switch to window {target}, then move window {nr}
to a new split adjacent to {target}.
@@ -10870,6 +12041,8 @@ win_splitmove({nr}, {target} [, {options}]) *win_splitmove()*
Can also be used as a |method|: >
GetWinid()->win_splitmove(target)
<
+ Return type: |Number|
+
*winbufnr()*
winbufnr({nr}) The result is a Number, which is the number of the buffer
@@ -10884,11 +12057,17 @@ winbufnr({nr}) The result is a Number, which is the number of the buffer
Can also be used as a |method|: >
FindWindow()->winbufnr()->bufname()
<
+ Return type: |Number|
+
+
*wincol()*
wincol() The result is a Number, which is the virtual column of the
cursor in the window. This is counting screen cells from the
left side of the window. The leftmost column is one.
+ Return type: |Number|
+
+
*windowsversion()*
windowsversion()
The result is a String. For MS-Windows it indicates the OS
@@ -10896,6 +12075,8 @@ windowsversion()
Windows XP is "5.1". For non-MS-Windows systems the result is
an empty string.
+ Return type: |String|
+
winheight({nr}) *winheight()*
The result is a Number, which is the height of window {nr}.
{nr} can be the window number or the |window-ID|.
@@ -10909,6 +12090,9 @@ winheight({nr}) *winheight()*
< Can also be used as a |method|: >
GetWinid()->winheight()
<
+ Return type: |Number|
+
+
winlayout([{tabnr}]) *winlayout()*
The result is a nested List containing the layout of windows
in a tabpage.
@@ -10942,15 +12126,21 @@ winlayout([{tabnr}]) *winlayout()*
Can also be used as a |method|: >
GetTabnr()->winlayout()
<
- *winline()*
-winline() The result is a Number, which is the screen line of the cursor
+ Return type: list<any>
+
+
+winline() *winline()*
+ The result is a Number, which is the screen line of the cursor
in the window. This is counting screen lines from the top of
the window. The first line is one.
If the cursor was moved the view on the file will be updated
first, this may cause a scroll.
- *winnr()*
-winnr([{arg}]) The result is a Number, which is the number of the current
+ Return type: |Number|
+
+
+winnr([{arg}]) *winnr()*
+ The result is a Number, which is the number of the current
window. The top window has number 1.
Returns zero for a popup window.
@@ -10983,8 +12173,11 @@ winnr([{arg}]) The result is a Number, which is the number of the current
< Can also be used as a |method|: >
GetWinval()->winnr()
<
- *winrestcmd()*
-winrestcmd() Returns a sequence of |:resize| commands that should restore
+ Return type: |Number|
+
+
+winrestcmd() *winrestcmd()*
+ Returns a sequence of |:resize| commands that should restore
the current window sizes. Only works properly when no windows
are opened or closed and the current window and tab page is
unchanged.
@@ -10993,8 +12186,10 @@ winrestcmd() Returns a sequence of |:resize| commands that should restore
:call MessWithWindowSizes()
:exe cmd
<
- *winrestview()*
-winrestview({dict})
+ Return type: |String|
+
+
+winrestview({dict}) *winrestview()*
Uses the |Dictionary| returned by |winsaveview()| to restore
the view of the current window.
Note: The {dict} does not have to contain all values, that are
@@ -11013,8 +12208,11 @@ winrestview({dict})
Can also be used as a |method|: >
GetView()->winrestview()
<
- *winsaveview()*
-winsaveview() Returns a |Dictionary| that contains information to restore
+ Return type: |Number|
+
+
+winsaveview() *winsaveview()*
+ Returns a |Dictionary| that contains information to restore
the view of the current window. Use |winrestview()| to
restore the view.
This is useful if you have a mapping that jumps around in the
@@ -11040,6 +12238,8 @@ winsaveview() Returns a |Dictionary| that contains information to restore
skipcol columns skipped
Note that no option values are saved.
+ Return type: dict<number>
+
winwidth({nr}) *winwidth()*
The result is a Number, which is the width of window {nr}.
@@ -11057,6 +12257,8 @@ winwidth({nr}) *winwidth()*
Can also be used as a |method|: >
GetWinid()->winwidth()
+<
+ Return type: |Number|
wordcount() *wordcount()*
@@ -11080,9 +12282,10 @@ wordcount() *wordcount()*
visual_words Number of words visually selected
(only in Visual mode)
+ Return type: dict<number>
- *writefile()*
-writefile({object}, {fname} [, {flags}])
+
+writefile({object}, {fname} [, {flags}]) *writefile()*
When {object} is a |List| write it to file {fname}. Each list
item is separated with a NL. Each list item must be a String
or Number.
@@ -11130,6 +12333,8 @@ writefile({object}, {fname} [, {flags}])
< Can also be used as a |method|: >
GetText()->writefile("thefile")
+<
+ Return type: |Number|
xor({expr}, {expr}) *xor()*
@@ -11142,6 +12347,7 @@ xor({expr}, {expr}) *xor()*
Can also be used as a |method|: >
:let bits = bits->xor(0x80)
<
+ Return type: |Number|
==============================================================================
3. Feature list *feature-list*
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index cd3d6ad..50ff4ec 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1,4 +1,4 @@
-*change.txt* For Vim version 9.1. Last change: 2024 Apr 14
+*change.txt* For Vim version 9.1. Last change: 2024 May 18
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -623,7 +623,8 @@ Vim uses temporary files for filtering, generating diffs and also for
tempname(). For Unix, the file will be in a private directory (only
accessible by the current user) to avoid security problems (e.g., a symlink
attack or other people reading your file). When Vim exits the directory and
-all files in it are deleted. When Vim has the setuid bit set this may cause
+all files in it are deleted (only on Unix, on other systems you will have to
+clean up yourself). When Vim has the setuid bit set this may cause
problems, the temp file is owned by the setuid user but the filter command
probably runs as the original user.
Directory for temporary files is created in the first of these directories
@@ -1346,7 +1347,7 @@ The expression must evaluate to a String. A Number is always automatically
converted to a String. For the "p" and ":put" command, if the result is a
Float it's converted into a String. If the result is a List each element is
turned into a String and used as a line. A Dictionary is converted into a
-String. A FuncRef results in an error message (use string() to convert).
+String. A Funcref results in an error message (use string() to convert).
If the "= register is used for the "p" command, the String is split up at <NL>
characters. If the String ends in a <NL>, it is regarded as a linewise
@@ -1412,6 +1413,8 @@ The next three commands always work on whole lines.
:[range]m[ove] {address} *:m* *:mo* *:move* *E134*
Move the lines given by [range] to below the line
given by {address}.
+ Any text properties in [range] are cleared
+ |text-prop-cleared|.
==============================================================================
6. Formatting text *formatting*
diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt
index d625a01..f294679 100644
--- a/runtime/doc/channel.txt
+++ b/runtime/doc/channel.txt
@@ -1,4 +1,4 @@
-*channel.txt* For Vim version 9.1. Last change: 2023 Aug 15
+*channel.txt* For Vim version 9.1. Last change: 2024 Jun 13
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -502,6 +502,8 @@ ch_canread({handle}) *ch_canread()*
Can also be used as a |method|: >
GetChannel()->ch_canread()
+<
+ Return type: |Number|
ch_close({handle}) *ch_close()*
Close {handle}. See |channel-close|.
@@ -510,6 +512,8 @@ ch_close({handle}) *ch_close()*
Can also be used as a |method|: >
GetChannel()->ch_close()
+<
+ Return type: |Number|
ch_close_in({handle}) *ch_close_in()*
Close the "in" part of {handle}. See |channel-close-in|.
@@ -518,6 +522,8 @@ ch_close_in({handle}) *ch_close_in()*
Can also be used as a |method|: >
GetChannel()->ch_close_in()
+<
+ Return type: |Number|
ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
@@ -541,6 +547,8 @@ ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
Can also be used as a |method|: >
GetChannel()->ch_evalexpr(expr)
+<
+ Return type: dict<any> or |String|
ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
@@ -559,6 +567,8 @@ ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
Can also be used as a |method|: >
GetChannel()->ch_evalraw(rawstring)
+<
+ Return type: dict<any> or |String|
ch_getbufnr({handle}, {what}) *ch_getbufnr()*
Get the buffer number that {handle} is using for String {what}.
@@ -569,6 +579,8 @@ ch_getbufnr({handle}, {what}) *ch_getbufnr()*
Can also be used as a |method|: >
GetChannel()->ch_getbufnr(what)
+<
+ Return type: |Number|
ch_getjob({channel}) *ch_getjob()*
Get the Job associated with {channel}.
@@ -577,7 +589,8 @@ ch_getjob({channel}) *ch_getjob()*
Can also be used as a |method|: >
GetChannel()->ch_getjob()
-
+<
+ Return type: |job| or |String|
ch_info({handle}) *ch_info()*
Returns a Dictionary with information about {handle}. The
@@ -613,7 +626,8 @@ ch_info({handle}) *ch_info()*
Can also be used as a |method|: >
GetChannel()->ch_info()
-
+<
+ Return type: dict<any>
ch_log({msg} [, {handle}]) *ch_log()*
Write String {msg} in the channel log file, if it was opened
@@ -628,7 +642,8 @@ ch_log({msg} [, {handle}]) *ch_log()*
Can also be used as a |method|: >
'did something'->ch_log()
-
+<
+ Return type: dict<any>
ch_logfile({fname} [, {mode}]) *ch_logfile()*
Start logging channel activity to {fname}.
@@ -655,7 +670,8 @@ ch_logfile({fname} [, {mode}]) *ch_logfile()*
Can also be used as a |method|: >
'logfile'->ch_logfile('w')
-
+<
+ Return type: |Number|
ch_open({address} [, {options}]) *ch_open()*
Open a channel to {address}. See |channel|.
@@ -669,7 +685,8 @@ ch_open({address} [, {options}]) *ch_open()*
Can also be used as a |method|: >
GetAddress()->ch_open()
-
+<
+ Return type: |channel|
ch_read({handle} [, {options}]) *ch_read()*
Read from {handle} and return the received message.
@@ -680,7 +697,8 @@ ch_read({handle} [, {options}]) *ch_read()*
Can also be used as a |method|: >
GetChannel()->ch_read()
-
+<
+ Return type: |String|
ch_readblob({handle} [, {options}]) *ch_readblob()*
Like ch_read() but reads binary data and returns a |Blob|.
@@ -688,7 +706,8 @@ ch_readblob({handle} [, {options}]) *ch_readblob()*
Can also be used as a |method|: >
GetChannel()->ch_readblob()
-
+<
+ Return type: |Blob|
ch_readraw({handle} [, {options}]) *ch_readraw()*
Like ch_read() but for a JS and JSON channel does not decode
@@ -698,7 +717,8 @@ ch_readraw({handle} [, {options}]) *ch_readraw()*
Can also be used as a |method|: >
GetChannel()->ch_readraw()
-
+<
+ Return type: |String|
ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
Send {expr} over {handle}. The {expr} is encoded
@@ -720,6 +740,8 @@ ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
Can also be used as a |method|: >
GetChannel()->ch_sendexpr(expr)
+<
+ Return type: dict<any> or |String|
ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()*
@@ -733,7 +755,8 @@ ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()*
Can also be used as a |method|: >
GetChannel()->ch_sendraw(rawexpr)
-
+<
+ Return type: dict<any> or |String|
ch_setoptions({handle}, {options}) *ch_setoptions()*
Set options on {handle}:
@@ -751,7 +774,8 @@ ch_setoptions({handle}, {options}) *ch_setoptions()*
Can also be used as a |method|: >
GetChannel()->ch_setoptions(options)
-
+<
+ Return type: |Number|
ch_status({handle} [, {options}]) *ch_status()*
Return the status of {handle}:
@@ -770,6 +794,8 @@ ch_status({handle} [, {options}]) *ch_status()*
<
Can also be used as a |method|: >
GetChannel()->ch_status()
+<
+ Return type: |String|
==============================================================================
9. Starting a job with a channel *job-start* *job*
@@ -900,6 +926,8 @@ job_getchannel({job}) *job_getchannel()*
<
Can also be used as a |method|: >
GetJob()->job_getchannel()
+<
+ Return type: |channel|
job_info([{job}]) *job_info()*
Returns a Dictionary with information about {job}:
@@ -927,6 +955,9 @@ job_info([{job}]) *job_info()*
Can also be used as a |method|: >
GetJob()->job_info()
+<
+ Return type: dict<any> or list<job> depending on whether {job}
+ was given
job_setoptions({job}, {options}) *job_setoptions()*
@@ -936,6 +967,8 @@ job_setoptions({job}, {options}) *job_setoptions()*
Can also be used as a |method|: >
GetJob()->job_setoptions(options)
+<
+ Return type: |Number|
job_start({command} [, {options}]) *job_start()*
@@ -997,6 +1030,8 @@ job_start({command} [, {options}]) *job_start()*
Can also be used as a |method|: >
BuildCommand()->job_start()
+<
+ Return type: |job|
job_status({job}) *job_status()* *E916*
@@ -1020,6 +1055,8 @@ job_status({job}) *job_status()* *E916*
Can also be used as a |method|: >
GetJob()->job_status()
+<
+ Return type: |String|
job_stop({job} [, {how}]) *job_stop()*
@@ -1066,6 +1103,8 @@ job_stop({job} [, {how}]) *job_stop()*
Can also be used as a |method|: >
GetJob()->job_stop()
+<
+ Return type: |Number|
==============================================================================
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index 6a7515a..214571f 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -650,7 +650,7 @@ followed by another Vim command:
:[range]!
a user defined command without the "-bar" argument |:command|
- and the following |Vim9-script| keywords:
+ and the following |Vim9-script| keywords:
:abstract
:class
:enum
diff --git a/runtime/doc/debug.txt b/runtime/doc/debug.txt
index 1d3090a..4963fdd 100644
--- a/runtime/doc/debug.txt
+++ b/runtime/doc/debug.txt
@@ -1,4 +1,4 @@
-*debug.txt* For Vim version 9.1. Last change: 2019 May 07
+*debug.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -160,7 +160,7 @@ In WinDbg: choose Open Crash Dump on the File menu. Follow the instructions in
3.5 Obtaining Microsoft Debugging Tools ~
The Debugging Tools for Windows (including WinDbg) can be downloaded from
- http://www.microsoft.com/whdc/devtools/debugging/default.mspx
+ https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools
This includes the WinDbg debugger.
Visual C++ 2005 Express Edition can be downloaded for free from:
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index 1b1ad85..678a924 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -1,4 +1,4 @@
-*develop.txt* For Vim version 9.1. Last change: 2022 Sep 20
+*develop.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -152,7 +152,7 @@ VIM IS... NOT *design-not*
everything but the kitchen sink, but some people say that you can clean one
with it. ;-)"
To use Vim with gdb see |terminal-debugger|. Other (older) tools can be
- found at http://www.agide.org and http://clewn.sf.net.
+ found at http://www.agide.org (link seems dead) and http://clewn.sf.net.
- Vim is not a fancy GUI editor that tries to look nice at the cost of
being less consistent over all platforms. But functional GUI features are
welcomed.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index fd37d97..18cd2c1 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 9.1. Last change: 2024 Mar 28
+*eval.txt* For Vim version 9.1. Last change: 2024 Jun 01
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2727,7 +2727,7 @@ v:vim_did_enter Zero until most of startup is done. It is set to one just
v:warningmsg Last given warning message. It's allowed to set this variable.
*v:windowid* *windowid-variable*
-v:windowid When any X11 based GUI is running or when running in a
+v:windowid When any X11/Wayland based GUI is running or when running in a
terminal and Vim connects to the X server (|-X|) this will be
set to the window ID.
When an MS-Windows GUI is running this will be set to the
@@ -3099,7 +3099,7 @@ text...
:cons[t] {var-name} = {expr1}
:cons[t] [{name1}, {name2}, ...] = {expr1}
:cons[t] [{name}, ..., ; {lastname}] = {expr1}
-:cons[t] {var-name} =<< [trim] {marker}
+:cons[t] {var-name} =<< [trim] [eval] {marker}
text...
text...
{marker}
diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt
index f8a8ebe..927b75c 100644
--- a/runtime/doc/filetype.txt
+++ b/runtime/doc/filetype.txt
@@ -1,4 +1,4 @@
-*filetype.txt* For Vim version 9.1. Last change: 2024 Apr 18
+*filetype.txt* For Vim version 9.1. Last change: 2024 May 23
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -452,6 +452,18 @@ To disable folding everything under the title use this: >
let asciidoc_fold_under_title = 0
+ARDUINO *ft-arduino-plugin*
+
+By default the following options are set, in accordance with the default
+settings of Arduino IDE: >
+
+ setlocal expandtab tabstop=2 softtabstop=2 shiftwidth=2
+
+To disable this behavior, set the following variable in your vimrc: >
+
+ let g:arduino_recommended_style = 0
+
+
AWK *ft-awk-plugin*
Support for features specific to GNU Awk, like @include, can be enabled by
@@ -627,6 +639,12 @@ The mapping can be disabled with: >
let g:no_gprof_maps = 1
+HARE *ft-hare*
+
+Since the text for this plugin is rather long it has been put in a separate
+file: |ft_hare.txt|.
+
+
JAVA *ft-java-plugin*
Whenever the variable "g:ftplugin_java_source_path" is defined and its value
@@ -877,6 +895,31 @@ The mappings can be disabled with: >
let g:no_vim_maps = 1
+ZIG *ft-zig-plugin*
+
+ *g:zig_recommended_style*
+By default the following indentation options are set, in accordance with Zig's
+recommended style (https://ziglang.org/documentation/master/): >
+
+ setlocal expandtab shiftwidth=4 softtabstop=4 tabstop=8
+<
+To disable this behavior, set |g:zig_recommended_style| to 0: >
+
+ let g:zig_recommended_style = 0
+<
+ *g:zig_std_dir*
+The path to the Zig standard library. The Zig |ftplugin| reads |g:zig_std_dir|
+and appends it to the 'path' for Zig files. Where the Zig standard library
+is located is system and installation method dependent.
+
+One can automatically set |g:zig_std_dir| using `zig env`: >
+
+ let g:zig_std_dir = json_decode(system('zig env'))['std_dir']
+<
+This can, for example, be put in a FileType |:autocmd| or user |ftplugin| to
+only load when a Zig file is opened.
+
+
ZIMBU *ft-zimbu-plugin*
The Zimbu filetype plugin defines mappings to move to the start and end of
diff --git a/runtime/doc/ft_hare.txt b/runtime/doc/ft_hare.txt
new file mode 100644
index 0000000..937c5e0
--- /dev/null
+++ b/runtime/doc/ft_hare.txt
@@ -0,0 +1,77 @@
+*ft_hare.txt* Support for the Hare programming language
+
+==============================================================================
+CONTENTS *hare*
+
+1. Introduction |hare-intro|
+2. Filetype plugin |hare-plugin|
+3. Settings |hare-settings|
+
+==============================================================================
+INTRODUCTION *hare-intro*
+
+This plugin provides syntax highlighting, indentation, and other functionality
+for the Hare programming language. Support is also provided for README files
+inside Hare modules, but this must be enabled by setting |g:filetype_haredoc|.
+
+==============================================================================
+FILETYPE PLUGIN *hare-plugin*
+
+This plugin automatically sets the value of 'path' to include the contents of
+the HAREPATH environment variable, allowing commands such as |gf| to directly
+open standard library or third-party modules. If HAREPATH is not set, it
+defaults to the recommended paths for most Unix-like filesystems, namely
+/usr/src/hare/stdlib and /usr/src/hare/third-party.
+
+==============================================================================
+SETTINGS *hare-settings*
+
+This plugin provides a small number of variables that you can define in your
+vimrc to configure its behavior.
+
+ *g:filetype_haredoc*
+This plugin is able to automatically detect Hare modules and set the "haredoc"
+filetype for any README files. As the recursive directory search used as a
+heuristic has a minor performance impact, this feature is disabled by default
+and must be specifically opted into: >
+ let g:filetype_haredoc = 1
+<
+See |g:haredoc_search_depth| for ways to tweak the searching behavior.
+
+ *g:hare_recommended_style*
+The following options are set by default, in accordance with the official Hare
+style guide: >
+ setlocal noexpandtab
+ setlocal shiftwidth=0
+ setlocal softtabstop=0
+ setlocal tabstop=8
+ setlocal textwidth=80
+<
+To disable this behavior: >
+ let g:hare_recommended_style = 0
+<
+ *g:hare_space_error*
+By default, trailing whitespace and tabs preceded by space characters are
+highlighted as errors. This is automatically turned off when in insert mode.
+To disable this highlighting completely: >
+ let g:hare_space_error = 0
+<
+ *g:haredoc_search_depth*
+By default, when |g:filetype_haredoc| is enabled, only the current directory
+and its immediate subdirectories are searched for Hare files. The maximum
+search depth may be adjusted with: >
+ let g:haredoc_search_depth = 2
+<
+ Value Effect~
+ 0 Only search the current directory.
+ 1 Search the current directory and immediate
+ subdirectories.
+ 2 Search the current directory and two levels of
+ subdirectories.
+
+The maximum search depth can be set to any integer, but using values higher
+than 2 is not recommended, and will likely provide no tangible benefit in most
+situations.
+
+==============================================================================
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt
index 3fda6e1..3b55919 100644
--- a/runtime/doc/gui.txt
+++ b/runtime/doc/gui.txt
@@ -1,4 +1,4 @@
-*gui.txt* For Vim version 9.1. Last change: 2024 Apr 17
+*gui.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -498,14 +498,14 @@ Starting off with the default set is a good idea. You can add more items, or,
if you don't like the defaults at all, start with removing all menus
|:unmenu-all|. You can also avoid the default menus being loaded by adding
this line to your .vimrc file (NOT your .gvimrc file!): >
- :let did_install_default_menus = 1
+ :let g:did_install_default_menus = 1
If you also want to avoid the Syntax menu: >
- :let did_install_syntax_menu = 1
+ :let g:did_install_syntax_menu = 1
The first item in the Syntax menu can be used to show all available filetypes
in the menu (which can take a bit of time to load). If you want to have all
filetypes already present at startup, add: >
- :let do_syntax_sel_menu = 1
-
+ :let g:do_syntax_sel_menu = 1
+< *menu-lazyload* *g:do_no_lazyload_menus*
The following menuitems show all available color schemes, keymaps and compiler
settings:
Edit > Color Scheme ~
@@ -515,7 +515,7 @@ However, they can also take a bit of time to load, because they search all
related files from the directories in 'runtimepath'. Therefore they are
loaded lazily (by the |CursorHold| event), or you can also load them manually.
If you want to have all these items already present at startup, add: >
- :let do_no_lazyload_menus = 1
+ :let g:do_no_lazyload_menus = 1
Note that the menu.vim is sourced when `:syntax on` or `:filetype on` is
executed or after your .vimrc file is sourced. This means that the 'encoding'
@@ -1238,7 +1238,8 @@ This section describes other features which are related to the GUI.
endif
A recommended Japanese font is MS Mincho. You can find info here:
-http://www.lexikan.com/mincho.htm
+https://learn.microsoft.com/en-us/typography/font-list/ms-mincho
+It should be distributed with Windows.
==============================================================================
8. Shell Commands *gui-shell*
diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt
index 7109bae..faa5f32 100644
--- a/runtime/doc/help.txt
+++ b/runtime/doc/help.txt
@@ -1,4 +1,4 @@
-*help.txt* For Vim version 9.1. Last change: 2022 Dec 03
+*help.txt* For Vim version 9.1. Last change: 2024 May 27
VIM - main help file
k
@@ -162,7 +162,8 @@ Programming language support ~
|filetype.txt| settings done specifically for a type of file
|quickfix.txt| commands for a quick edit-compile-fix cycle
|ft_ada.txt| Ada (the programming language) support
-|ft_context.txt| Filetype plugin for ConTeXt
+|ft_context.txt| Filetype plugin for ConTeXt
+|ft_hare.txt| Filetype plugin for Hare
|ft_mp.txt| Filetype plugin for METAFONT and MetaPost
|ft_ps1.txt| Filetype plugin for Windows PowerShell
|ft_raku.txt| Filetype plugin for Raku
diff --git a/runtime/doc/if_cscop.txt b/runtime/doc/if_cscop.txt
index 3fa8f81..bb4c6a1 100644
--- a/runtime/doc/if_cscop.txt
+++ b/runtime/doc/if_cscop.txt
@@ -1,4 +1,4 @@
-*if_cscop.txt* For Vim version 9.1. Last change: 2022 Jan 08
+*if_cscop.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL by Andy Kahn
@@ -358,7 +358,7 @@ system calls: fork(), pipe(), execl(), waitpid(). This means it is mostly
limited to Unix systems.
Additionally Cscope support works for Win32. For more information and a
-cscope version for Win32 see:
+cscope version for Win32 see (link seems dead):
http://iamphet.nm.ru/cscope/index.html
diff --git a/runtime/doc/if_pyth.txt b/runtime/doc/if_pyth.txt
index 8456d08..6236841 100644
--- a/runtime/doc/if_pyth.txt
+++ b/runtime/doc/if_pyth.txt
@@ -1,4 +1,4 @@
-*if_pyth.txt* For Vim version 9.1. Last change: 2023 Oct 25
+*if_pyth.txt* For Vim version 9.1. Last change: 2024 May 16
VIM REFERENCE MANUAL by Paul Moore
@@ -343,7 +343,8 @@ In python vim.VIM_SPECIAL_PATH special directory is used as a replacement for
the list of paths found in 'runtimepath': with this directory in sys.path and
vim.path_hooks in sys.path_hooks python will try to load module from
{rtp}/python2 (or python3) and {rtp}/pythonx (for both python versions) for
-each {rtp} found in 'runtimepath'.
+each {rtp} found in 'runtimepath' (Note: find_module() has been removed from
+imp module around Python 3.12.0a7).
Implementation is similar to the following, but written in C: >
@@ -404,10 +405,12 @@ vim.VIM_SPECIAL_PATH *python-VIM_SPECIAL_PATH*
vim.find_module(...) *python-find_module*
vim.path_hook(path) *python-path_hook*
+vim.find_spec(...) *python-find_spec*
Methods or objects used to implement path loading as described above.
You should not be using any of these directly except for vim.path_hook
- in case you need to do something with sys.meta_path. It is not
- guaranteed that any of the objects will exist in the future vim
+ in case you need to do something with sys.meta_path, vim.find_spec()
+ is available starting with Python 3.7.
+ It is not guaranteed that any of the objects will exist in future vim
versions.
vim._get_paths *python-_get_paths*
diff --git a/runtime/doc/indent.txt b/runtime/doc/indent.txt
index fe24505..2e57423 100644
--- a/runtime/doc/indent.txt
+++ b/runtime/doc/indent.txt
@@ -1261,5 +1261,5 @@ By default, the yaml indent script does not try to detect multiline scalars.
If you want to enable this, set the following variable: >
let g:yaml_indent_multiline_scalar = 1
-
+<
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 1229726..365f49a 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1,4 +1,4 @@
-*map.txt* For Vim version 9.1. Last change: 2024 Jan 25
+*map.txt* For Vim version 9.1. Last change: 2024 May 05
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -986,11 +986,11 @@ For the Meta modifier the "T" character is used. For example, to map Meta-b
in Insert mode: >
:imap <T-b> terrible
-1.12 MAPPING SUPER-KEYS or COMMAND-KEYS *:map-super-keys* *:map-cmd-key*
+1.12 MAPPING SUPER-KEYS or COMMAND-KEYS *:map-super-keys* *:map-cmd-key*
-The Super modifier is available in GUI mode (when |gui_running| is 1) for
-GVim on Linux and MacVim on Mac OS. If you're on a Mac, this represents the
-Command key, on Linux with the GTK GUI it represents the Super key.
+The Super modifier is available in GUI mode (when |gui_running| is 1) for gVim
+on Linux and MacVim on Mac OS. If you're on a Mac, this represents the Command
+key, on Linux with the GTK GUI it represents the Super key.
The character "D" is used for the Super / Command modifier.
For example, to map Command-b in Insert mode: >
diff --git a/runtime/doc/mbyte.txt b/runtime/doc/mbyte.txt
index 91154a7..3bb2bfb 100644
--- a/runtime/doc/mbyte.txt
+++ b/runtime/doc/mbyte.txt
@@ -1,4 +1,4 @@
-*mbyte.txt* For Vim version 9.1. Last change: 2022 Apr 03
+*mbyte.txt* For Vim version 9.1. Last change: 2024 Jun 09
VIM REFERENCE MANUAL by Bram Moolenaar et al.
@@ -451,18 +451,19 @@ Useful utilities for converting the charset:
Chinese: hc
Hc is "Hanzi Converter". Hc convert a GB file to a Big5 file, or Big5
file to GB file. Hc can be found at:
+ https://www.freshports.org/chinese/hc
ftp://ftp.cuhk.hk/pub/chinese/ifcss/software/unix/convert/hc-30.tar.gz
Korean: hmconv
Hmconv is Korean code conversion utility especially for E-mail. It can
convert between EUC-KR and ISO-2022-KR. Hmconv can be found at:
- ftp://ftp.kaist.ac.kr/pub/hangul/code/hmconv/
+ https://www.freshports.org/korean/hmconv/
Multilingual: lv
Lv is a Powerful Multilingual File Viewer. And it can be worked as
|charset| converter. Supported |charset|: ISO-2022-CN, ISO-2022-JP,
ISO-2022-KR, EUC-CN, EUC-JP, EUC-KR, EUC-TW, UTF-7, UTF-8, ISO-8859
- series, Shift_JIS, Big5 and HZ. Lv can be found at:
+ series, Shift_JIS, Big5 and HZ. Lv can be found at (link seems dead):
http://www.ff.iij4u.or.jp/~nrt/lv/index.html
@@ -777,13 +778,13 @@ is suitable for complex input, such as CJK.
For example, there are xwnmo and kinput2 Japanese |IM-server|, both are
FrontEnd system. Xwnmo is distributed with Wnn (see below), kinput2 can be
- found at: ftp://ftp.sra.co.jp/pub/x11/kinput2/
+ found at (link seems dead): ftp://ftp.sra.co.jp/pub/x11/kinput2/
For Chinese, there's a great XIM server named "xcin", you can input both
Traditional and Simplified Chinese characters. And it can accept other
- locale if you make a correct input table. Xcin can be found at:
- http://cle.linux.org.tw/xcin/
- Others are scim: http://scim.freedesktop.org/ and fcitx:
+ locale if you make a correct input table. Xcin can be found at (link seems
+ dead): http://cle.linux.org.tw/xcin/
+ Others are scim: https://www.freedesktop.org/wiki/Software/scim/ and fcitx:
http://www.fcitx.org/
- Conversion Server
@@ -801,7 +802,7 @@ is suitable for complex input, such as CJK.
pronounced in Hira-gana, second, we convert Hira-gana to Kanji or Kata-Kana,
if needed. There are some Kana-Kanji conversion server: jserver
(distributed with Wnn, see below) and canna. Canna can be found at:
- http://canna.sourceforge.jp/
+ https://osdn.net/projects/canna/
There is a good input system: Wnn4.2. Wnn 4.2 contains,
xwnmo (|IM-server|)
@@ -1355,7 +1356,7 @@ You might also want to select the font used for the menus. Unfortunately this
doesn't always work. See the system specific remarks below, and 'langmenu'.
-USING UTF-8 IN X-Windows *utf-8-in-xwindows*
+USING UTF-8 IN X-WINDOWS *utf-8-in-xwindows*
Note: This section does not apply to the GTK+ 2 GUI.
diff --git a/runtime/doc/netbeans.txt b/runtime/doc/netbeans.txt
index a62123c..ee227b4 100644
--- a/runtime/doc/netbeans.txt
+++ b/runtime/doc/netbeans.txt
@@ -1,4 +1,4 @@
-*netbeans.txt* For Vim version 9.1. Last change: 2023 Nov 26
+*netbeans.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL by Gordon Prieur et al.
@@ -77,8 +77,8 @@ Initially just a Java IDE, NetBeans has had C, C++, and Fortran support added
in recent releases.
For more information visit the main NetBeans web site http://www.netbeans.org.
-The External Editor is now, unfortunately, declared obsolete. See
- http://externaleditor.netbeans.org.
+The External Editor is now, unfortunately, declared obsolete. See (link seems
+dead): http://externaleditor.netbeans.org.
Sun Microsystems, Inc. also ships NetBeans under the name Sun ONE Studio.
Visit http://www.sun.com for more information regarding the Sun ONE Studio
@@ -147,8 +147,9 @@ On MS-Windows:
The Win32 support is now in beta stage.
To use XPM signs on Win32 (e.g. when using with NetBeans) you can compile
-XPM by yourself or use precompiled libraries from http://iamphet.nm.ru/misc/
-(for MS Visual C++) or http://gnuwin32.sourceforge.net (for MinGW).
+XPM by yourself or use precompiled libraries from (link seems dead):
+http://iamphet.nm.ru/misc/ (for MS Visual C++) or
+http://gnuwin32.sourceforge.net (for MinGW).
Enable debugging:
-----------------
@@ -946,7 +947,8 @@ for details on downloading this module if your NetBeans release does not have
it.
For C, C++, and Fortran support you will also need the cpp module. See
-http://cpp.netbeans.org for information regarding this module.
+http://cpp.netbeans.org (link seems dead) for information regarding this
+module.
You can also download Sun ONE Studio from Sun Microsystems, Inc for a 30 day
free trial. See http://www.sun.com for further details.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 806f5f0..6ec4031 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.1. Last change: 2024 Mar 29
+*options.txt* For Vim version 9.1. Last change: 2024 Jun 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1909,13 +1909,14 @@ A jump table for the options with a short description can be found at |Q_op|.
insert a space.
*'commentstring'* *'cms'* *E537*
-'commentstring' 'cms' string (default "/*%s*/")
+'commentstring' 'cms' string (default "/* %s */")
local to buffer
{not available when compiled without the |+folding|
feature}
A template for a comment. The "%s" in the value is replaced with the
- comment text. Currently only used to add markers for folding, see
- |fold-marker|.
+ comment text, and should be padded with a space when possible.
+ Currently used to add markers for folding, see |fold-marker|. Also
+ commonly used by commenting plugins (e.g. |comment-install|).
*'compatible'* *'cp'* *'nocompatible'* *'nocp'*
'compatible' 'cp' boolean (default on, off when a |vimrc| or |gvimrc|
@@ -2100,7 +2101,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'completeopt'* *'cot'*
'completeopt' 'cot' string (default: "menu,preview")
- global
+ global or local to buffer |global-local|
A comma-separated list of options for Insert mode completion
|ins-completion|. The supported values are:
@@ -2143,6 +2144,14 @@ A jump table for the options with a short description can be found at |Q_op|.
select one from the menu. Only works in combination with
"menu" or "menuone".
+ fuzzy Enable |fuzzy-matching| for completion candidates. This
+ allows for more flexible and intuitive matching, where
+ characters can be skipped and matches can be found even
+ if the exact sequence is not typed. Only makes a
+ difference how completion candidates are reduced from the
+ list of alternatives, but not how the candidates are
+ collected (using different completion types).
+
*'completepopup'* *'cpp'*
'completepopup' 'cpp' string (default empty)
global
@@ -4266,12 +4275,14 @@ A jump table for the options with a short description can be found at |Q_op|.
T:DiffText,>:SignColumn,-:Conceal,
B:SpellBad,P:SpellCap,R:SpellRare,
L:SpellLocal,+:Pmenu,=:PmenuSel,
+ k:PmenuMatch,<:PmenuMatchSel,
[:PmenuKind,]:PmenuKindSel,
{:PmenuExtra,}:PmenuExtraSel,
x:PmenuSbar,X:PmenuThumb,*:TabLine,
#:TabLineSel,_:TabLineFill,!:CursorColumn,
.:CursorLine,o:ColorColumn,q:QuickFixLine,
- z:StatusLineTerm,Z:StatusLineTermNC")
+ z:StatusLineTerm,Z:StatusLineTermNC,
+ g:MsgArea")
global
This option can be used to set highlighting mode for various
occasions. It is a comma-separated list of character pairs. The
@@ -4290,6 +4301,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|hl-Search| l last search pattern highlighting (see 'hlsearch')
|hl-MoreMsg| m |more-prompt|
|hl-ModeMsg| M Mode (e.g., "-- INSERT --")
+ |hl-MsgArea| g |Command-line| and message area
|hl-LineNr| n line number for ":number" and ":#" commands, and
when 'number' or 'relativenumber' option is set.
|hl-LineNrAbove| a line number above the cursor for when the
@@ -4330,6 +4342,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|hl-PmenuExtraSel| } popup menu "extra" selected line
|hl-PmenuSbar| x popup menu scrollbar
|hl-PmenuThumb| X popup menu scrollbar thumb
+ |hl-PmenuMatch| k popup menu matched text
+ |hl-PmenuMatchSel| < popup menu matched text in selected line
The display modes are:
r reverse (termcap entry "mr" and "me")
@@ -6683,7 +6697,8 @@ A jump table for the options with a short description can be found at |Q_op|.
<
*'runtimepath'* *'rtp'* *vimfiles*
'runtimepath' 'rtp' string (default:
- Unix: "$HOME/.vim,
+ Unix: "$HOME/.vim or
+ $XDG_CONFIG_HOME/vim,
$VIM/vimfiles,
$VIMRUNTIME,
$VIM/vimfiles/after,
@@ -6735,6 +6750,8 @@ A jump table for the options with a short description can be found at |Q_op|.
And any other file searched for with the |:runtime| command.
+ For $XDG_CONFIG_HOME see |xdg-base-dir|.
+
The defaults for most systems are setup to search five locations:
1. In your home directory, for your personal preferences.
2. In a system-wide Vim directory, for preferences from the system
@@ -7233,8 +7250,8 @@ A jump table for the options with a short description can be found at |Q_op|.
message; also for quickfix message (e.g., ":cn")
s don't give "search hit BOTTOM, continuing at TOP" or *shm-s*
"search hit TOP, continuing at BOTTOM" messages; when using
- the search count do not show "W" after the count message (see
- S below)
+ the search count do not show "W" before the count message
+ (see |shm-S| below)
t truncate file message at the start if it is too long *shm-t*
to fit on the command-line, "<" will appear in the left most
column; ignored in Ex mode
@@ -7256,7 +7273,11 @@ A jump table for the options with a short description can be found at |Q_op|.
`:silent` was used for the command; note that this also
affects messages from autocommands and 'autoread' reloading
S do not show search count message when searching, e.g. *shm-S*
- "[1/5]"
+ "[1/5]". When the "S" flag is not present (e.g. search count
+ is shown), the "search hit BOTTOM, continuing at TOP" and
+ "search hit TOP, continuing at BOTTOM" messages are only
+ indicated by a "W" (Mnemonic: Wrapped) letter before the
+ search count statistics.
This gives you the opportunity to avoid that a change between buffers
requires you to hit <Enter>, but still gives as useful a message as
@@ -8986,13 +9007,15 @@ A jump table for the options with a short description can be found at |Q_op|.
*'viewdir'* *'vdir'*
'viewdir' 'vdir' string (default for Amiga: "home:vimfiles/view",
for Win32: "$HOME/vimfiles/view",
- for Unix: "$HOME/.vim/view",
+ for Unix: "$HOME/.vim/view" or
+ "$XDG_CONFIG_HOME/vim/view"
for macOS: "$VIM/vimfiles/view",
for VMS: "sys$login:vimfiles/view")
global
{not available when compiled without the |+mksession|
feature}
Name of the directory where to store files for |:mkview|.
+ For $XDG_CONFIG_HOME see |xdg-base-dir|.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
diff --git a/runtime/doc/os_vms.txt b/runtime/doc/os_vms.txt
index 862f31d..4549c00 100644
--- a/runtime/doc/os_vms.txt
+++ b/runtime/doc/os_vms.txt
@@ -1,4 +1,4 @@
-*os_vms.txt* For Vim version 9.1. Last change: 2023 Dec 14
+*os_vms.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL
@@ -40,7 +40,6 @@ Or use one of the mirrors:
You can download precompiled executables from:
http://www.polarhome.com/vim/
- ftp://ftp.polarhome.com/pub/vim/
To use the precompiled binary version, you need one of these archives:
diff --git a/runtime/doc/os_win32.txt b/runtime/doc/os_win32.txt
index bbe9940..54c8e91 100644
--- a/runtime/doc/os_win32.txt
+++ b/runtime/doc/os_win32.txt
@@ -1,4 +1,4 @@
-*os_win32.txt* For Vim version 9.1. Last change: 2023 Dec 04
+*os_win32.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL by George Reilly
@@ -250,8 +250,7 @@ A. Basically what you need is to put a tee program that will copy its input
copy of tee (and a number of other GNU tools) at
http://gnuwin32.sourceforge.net or http://unxutils.sourceforge.net
Alternatively, try the more recent Cygnus version of the GNU tools at
- http://www.cygwin.com Other Unix-style tools for Win32 are listed at
- http://directory.google.com/Top/Computers/Software/Operating_Systems/Unix/Win32/
+ http://www.cygwin.com
When you do get a copy of tee, you'll need to add >
:set shellpipe=\|\ tee
< to your _vimrc.
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
index f16e7d2..183806a 100644
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -1,4 +1,4 @@
-*pattern.txt* For Vim version 9.1. Last change: 2024 Apr 26
+*pattern.txt* For Vim version 9.1. Last change: 2024 Jun 03
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1513,5 +1513,7 @@ the matching positions and the fuzzy match scores.
The "f" flag of `:vimgrep` enables fuzzy matching.
+To enable fuzzy matching for |ins-completion|, add the "fuzzy" value to the
+'completeopt' option.
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/pi_netrw.txt b/runtime/doc/pi_netrw.txt
index 2b22105..aeaca0b 100644
--- a/runtime/doc/pi_netrw.txt
+++ b/runtime/doc/pi_netrw.txt
@@ -1,4 +1,4 @@
-*pi_netrw.txt* For Vim version 9.1. Last change: 2023 Jun 19
+*pi_netrw.txt* For Vim version 9.1. Last change: 2024 May 11
------------------------------------------------
NETRW REFERENCE MANUAL by Charles E. Campbell
@@ -449,10 +449,6 @@ settings are described below, in |netrw-browser-options|, and in
messages don't always seem to show up this
way, but one doesn't have to quit the window.
- *g:netrw_win95ftp* =1 if using Win95, will remove four trailing blank
- lines that o/s's ftp "provides" on transfers
- =0 force normal ftp behavior (no trailing line removal)
-
*g:netrw_cygwin* =1 assume scp under windows is from cygwin. Also
permits network browsing to use ls with time and
size sorting (default if windows)
@@ -828,8 +824,6 @@ set in the user's <.vimrc> file: (see also |netrw-settings| |netrw-protocol|)
g:netrw_uid Holds current user-id for ftp.
g:netrw_use_nt_rcp =0 don't use WinNT/2K/XP's rcp (default)
=1 use WinNT/2K/XP's rcp, binary mode
- g:netrw_win95ftp =0 use unix-style ftp even if win95/98/ME/etc
- =1 use default method to do ftp >
-----------------------------------------------------------------------
<
*netrw-internal-variables*
@@ -958,21 +952,8 @@ messages) you may write a NetReadFixup() function:
endfunction
>
The NetReadFixup() function will be called if it exists and thus allows you to
-customize your reading process. As a further example, <netrw.vim> contains
-just such a function to handle Windows 95 ftp. For whatever reason, Windows
-95's ftp dumps four blank lines at the end of a transfer, and so it is
-desirable to automate their removal. Here's some code taken from <netrw.vim>
-itself:
->
- if has("win95") && g:netrw_win95ftp
- fun! NetReadFixup(method, line1, line2)
- if method == 3 " ftp (no <.netrc>)
- let fourblanklines= line2 - 3
- silent fourblanklines .. "," .. line2 .. "g/^\s*/d"
- endif
- endfunction
- endif
->
+customize your reading process.
+
(Related topics: |ftp| |netrw-userpass| |netrw-start|)
==============================================================================
@@ -2052,11 +2033,7 @@ passwords:
better way to do that: I can use a regular ssh account which uses a
password to access the material without the need to key-in the password
each time. It's good for security and convenience. I tried ssh public key
- authorization + ssh-agent, implementing this, and it works! Here are two
- links with instructions:
-
- http://www.ibm.com/developerworks/library/l-keyc2/
- http://sial.org/howto/openssh/publickey-auth/
+ authorization + ssh-agent, implementing this, and it works!
Ssh hints:
@@ -3412,16 +3389,7 @@ Example: Clear netrw's marked file list via a mapping on gu >
(This section is likely to grow as I get feedback)
(also see |netrw-debug|)
*netrw-p1*
- P1. I use windows 95, and my ftp dumps four blank lines at the {{{2
- end of every read.
-
- See |netrw-fixup|, and put the following into your
- <.vimrc> file:
-
- let g:netrw_win95ftp= 1
-
- *netrw-p2*
- P2. I use Windows, and my network browsing with ftp doesn't sort by {{{2
+ P1. I use Windows, and my network browsing with ftp doesn't sort by {{{2
time or size! -or- The remote system is a Windows server; why
don't I get sorts by time or size?
@@ -3447,8 +3415,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
modify its listing behavior.
- *netrw-p3*
- P3. I tried rcp://user@host/ (or protocol other than ftp) and netrw {{{2
+ *netrw-p2*
+ P2. I tried rcp://user@host/ (or protocol other than ftp) and netrw {{{2
used ssh! That wasn't what I asked for...
Netrw has two methods for browsing remote directories: ssh
@@ -3456,8 +3424,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
When it comes time to do download a file (not just a directory
listing), netrw will use the given protocol to do so.
- *netrw-p4*
- P4. I would like long listings to be the default. {{{2
+ *netrw-p3*
+ P3. I would like long listings to be the default. {{{2
Put the following statement into your |.vimrc|: >
@@ -3466,8 +3434,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
Check out |netrw-browser-var| for more customizations that
you can set.
- *netrw-p5*
- P5. My times come up oddly in local browsing {{{2
+ *netrw-p4*
+ P4. My times come up oddly in local browsing {{{2
Does your system's strftime() accept the "%c" to yield dates
such as "Sun Apr 27 11:49:23 1997"? If not, do a
@@ -3476,16 +3444,16 @@ Example: Clear netrw's marked file list via a mapping on gu >
let g:netrw_timefmt= "%X" (where X is the option)
<
- *netrw-p6*
- P6. I want my current directory to track my browsing. {{{2
+ *netrw-p5*
+ P5. I want my current directory to track my browsing. {{{2
How do I do that?
Put the following line in your |.vimrc|:
>
let g:netrw_keepdir= 0
<
- *netrw-p7*
- P7. I use Chinese (or other non-ascii) characters in my filenames, {{{2
+ *netrw-p6*
+ P6. I use Chinese (or other non-ascii) characters in my filenames, {{{2
and netrw (Explore, Sexplore, Hexplore, etc) doesn't display them!
(taken from an answer provided by Wu Yongwei on the vim
@@ -3499,8 +3467,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
(...it is one more reason to recommend that people use utf-8!)
- *netrw-p8*
- P8. I'm getting "ssh is not executable on your system" -- what do I {{{2
+ *netrw-p7*
+ P7. I'm getting "ssh is not executable on your system" -- what do I {{{2
do?
(Dudley Fox) Most people I know use putty for windows ssh. It
@@ -3582,8 +3550,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
of the others will use the string in g:netrw_ssh_cmd by
default.
- *netrw-p9* *netrw-ml_get*
- P9. I'm browsing, changing directory, and bang! ml_get errors {{{2
+ *netrw-p8* *netrw-ml_get*
+ P8. I'm browsing, changing directory, and bang! ml_get errors {{{2
appear and I have to kill vim. Any way around this?
Normally netrw attempts to avoid writing swapfiles for
@@ -3593,8 +3561,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
in your <.vimrc>: >
let g:netrw_use_noswf= 0
<
- *netrw-p10*
- P10. I'm being pestered with "[something] is a directory" and {{{2
+ *netrw-p9*
+ P9. I'm being pestered with "[something] is a directory" and {{{2
"Press ENTER or type command to continue" prompts...
The "[something] is a directory" prompt is issued by Vim,
@@ -3604,8 +3572,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
I also suggest that you set your |'cmdheight'| to 2 (or more) in
your <.vimrc> file.
- *netrw-p11*
- P11. I want to have two windows; a thin one on the left and my {{{2
+ *netrw-p10*
+ P10. I want to have two windows; a thin one on the left and my {{{2
editing window on the right. How may I accomplish this?
You probably want netrw running as in a side window. If so, you
@@ -3630,8 +3598,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
<middlemouse> to select the file.
- *netrw-p12*
- P12. My directory isn't sorting correctly, or unwanted letters are {{{2
+ *netrw-p11*
+ P11. My directory isn't sorting correctly, or unwanted letters are {{{2
appearing in the listed filenames, or things aren't lining
up properly in the wide listing, ...
@@ -3640,8 +3608,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
Multibyte encodings use two (or more) bytes per character.
You may need to change |g:netrw_sepchr| and/or |g:netrw_xstrlen|.
- *netrw-p13*
- P13. I'm a Windows + putty + ssh user, and when I attempt to {{{2
+ *netrw-p12*
+ P12. I'm a Windows + putty + ssh user, and when I attempt to {{{2
browse, the directories are missing trailing "/"s so netrw treats
them as file transfers instead of as attempts to browse
subdirectories. How may I fix this?
@@ -3661,8 +3629,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
"let g:netrw_sftp_cmd = "d:\\dev\\putty\\PSFTP.exe"
"let g:netrw_scp_cmd = "d:\\dev\\putty\\PSCP.exe"
<
- *netrw-p14*
- P14. I would like to speed up writes using Nwrite and scp/ssh {{{2
+ *netrw-p13*
+ P13. I would like to speed up writes using Nwrite and scp/ssh {{{2
style connections. How? (Thomer M. Gil)
Try using ssh's ControlMaster and ControlPath (see the ssh_config
@@ -3688,8 +3656,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
vim scp://host.domain.com//home/user/.bashrc
<
- *netrw-p15*
- P15. How may I use a double-click instead of netrw's usual single {{{2
+ *netrw-p14*
+ P14. How may I use a double-click instead of netrw's usual single {{{2
click to open a file or directory? (Ben Fritz)
First, disable netrw's mapping with >
@@ -3701,8 +3669,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
all netrw's mouse mappings, not just the <leftmouse> one.
(see |g:netrw_mousemaps|)
- *netrw-p16*
- P16. When editing remote files (ex. :e ftp://hostname/path/file), {{{2
+ *netrw-p15*
+ P15. When editing remote files (ex. :e ftp://hostname/path/file), {{{2
under Windows I get an |E303| message complaining that its unable
to open a swap file.
@@ -3710,8 +3678,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
directory. Start netrw from your $HOME or other writable
directory.
- *netrw-p17*
- P17. Netrw is closing buffers on its own. {{{2
+ *netrw-p16*
+ P16. Netrw is closing buffers on its own. {{{2
What steps will reproduce the problem?
1. :Explore, navigate directories, open a file
2. :Explore, open another file
@@ -3724,15 +3692,15 @@ Example: Clear netrw's marked file list via a mapping on gu >
It appears that the buffers are not exactly closed;
a ":ls!" will show them (although ":ls" does not).
- *netrw-P18*
- P18. How to locally edit a file that's only available via {{{2
+ *netrw-P17*
+ P17. How to locally edit a file that's only available via {{{2
another server accessible via ssh?
See http://stackoverflow.com/questions/12469645/
"Using Vim to Remotely Edit A File on ServerB Only
Accessible From ServerA"
- *netrw-P19*
- P19. How do I get numbering on in directory listings? {{{2
+ *netrw-P18*
+ P18. How do I get numbering on in directory listings? {{{2
With |g:netrw_bufsettings|, you can control netrw's buffer
settings; try putting >
let g:netrw_bufsettings="noma nomod nu nobl nowrap ro nornu"
@@ -3740,8 +3708,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
instead, try >
let g:netrw_bufsettings="noma nomod nonu nobl nowrap ro rnu"
<
- *netrw-P20*
- P20. How may I have gvim start up showing a directory listing? {{{2
+ *netrw-P19*
+ P19. How may I have gvim start up showing a directory listing? {{{2
Try putting the following code snippet into your .vimrc: >
augroup VimStartup
au!
@@ -3753,8 +3721,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
This snippet assumes that you have client-server enabled
(ie. a "huge" vim version).
- *netrw-P21*
- P21. I've made a directory (or file) with an accented character, {{{2
+ *netrw-P20*
+ P20. I've made a directory (or file) with an accented character, {{{2
but netrw isn't letting me enter that directory/read that file:
Its likely that the shell or o/s is using a different encoding
@@ -3764,8 +3732,8 @@ Example: Clear netrw's marked file list via a mapping on gu >
au FileType netrw set enc=latin1
<
- *netrw-P22*
- P22. I get an error message when I try to copy or move a file: {{{2
+ *netrw-P21*
+ P21. I get an error message when I try to copy or move a file: {{{2
**error** (netrw) tried using g:netrw_localcopycmd<cp>; it doesn't work!
diff --git a/runtime/doc/pi_tar.txt b/runtime/doc/pi_tar.txt
index 0ab111c..5b317d6 100644
--- a/runtime/doc/pi_tar.txt
+++ b/runtime/doc/pi_tar.txt
@@ -1,4 +1,4 @@
-*pi_tar.txt* For Vim version 9.1. Last change: 2022 Oct 17
+*pi_tar.txt* For Vim version 9.1. Last change: 2024 May 11
+====================+
| Tar File Interface |
@@ -164,7 +164,8 @@ Copyright 2005-2017: *tar-copyright*
v2 * converted to use Vim7's new autoload feature
by Bram Moolenaar
v1 (original) * Michael Toren
- (see http://michael.toren.net/code/)
+ (see http://michael.toren.net/code/
+ link seems dead)
==============================================================================
vim:tw=78:ts=8:noet:ft=help
diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt
index f5cb12f..1ad4fb9 100644
--- a/runtime/doc/popup.txt
+++ b/runtime/doc/popup.txt
@@ -1,4 +1,4 @@
-*popup.txt* For Vim version 9.1. Last change: 2022 Oct 07
+*popup.txt* For Vim version 9.1. Last change: 2024 Jun 08
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -219,6 +219,8 @@ popup_atcursor({what}, {options}) *popup_atcursor()*
Can also be used as a |method|: >
GetText()->popup_atcursor({})
+<
+ Return type: |Number|
popup_beval({what}, {options}) *popup_beval()*
@@ -237,6 +239,8 @@ popup_beval({what}, {options}) *popup_beval()*
Can also be used as a |method|: >
GetText()->popup_beval({})
<
+ Return type: |Number|
+
*popup_clear()*
popup_clear([{force}])
Emergency solution to a misbehaving plugin: close all popup
@@ -248,6 +252,8 @@ popup_clear([{force}])
when it is the current window. If a terminal is running in a
popup it is killed.
+ Return type: |Number|
+
popup_close({id} [, {result}]) *popup_close()*
Close popup {id}. The window and the associated buffer will
@@ -260,6 +266,8 @@ popup_close({id} [, {result}]) *popup_close()*
Can also be used as a |method|: >
GetPopup()->popup_close()
+<
+ Return type: |Number|
popup_create({what}, {options}) *popup_create()*
@@ -290,6 +298,8 @@ popup_create({what}, {options}) *popup_create()*
Can also be used as a |method|: >
GetText()->popup_create({})
+<
+ Return type: |Number|
popup_dialog({what}, {options}) *popup_dialog()*
@@ -314,6 +324,8 @@ popup_dialog({what}, {options}) *popup_dialog()*
Can also be used as a |method|: >
GetText()->popup_dialog({})
+<
+ Return type: |Number|
popup_filter_menu({id}, {key}) *popup_filter_menu()*
@@ -336,6 +348,8 @@ popup_filter_menu({id}, {key}) *popup_filter_menu()*
To add shortcut keys, see the example here:
|popup_menu-shortcut-example|
+ Return type: |Number|
+
popup_filter_yesno({id}, {key}) *popup_filter_yesno()*
Filter that can be used for a popup. It handles only the keys
@@ -346,12 +360,16 @@ popup_filter_yesno({id}, {key}) *popup_filter_yesno()*
keys are ignored.
See the example here: |popup_dialog-example|
+ Return type: |Number|
+
popup_findecho() *popup_findecho()*
Get the |window-ID| for the popup that shows messages for the
`:echowindow` command. Return zero if there is none.
Mainly useful to hide the popup.
+ Return type: |Number|
+
popup_findinfo() *popup_findinfo()*
Get the |window-ID| for the popup info window, as it used by
@@ -361,11 +379,16 @@ popup_findinfo() *popup_findinfo()*
the item in the popup menu.
Returns zero if there is none.
+ Return type: |Number|
+
popup_findpreview() *popup_findpreview()*
Get the |window-ID| for the popup preview window.
Return zero if there is none.
+ Return type: |Number|
+
+
popup_getoptions({id}) *popup_getoptions()*
Return the {options} for popup {id} in a Dict.
A zero value means the option was not set. For "zindex" the
@@ -399,6 +422,8 @@ popup_getoptions({id}) *popup_getoptions()*
Can also be used as a |method|: >
GetPopup()->popup_getoptions()
+<
+ Return type: dict<any>
popup_getpos({id}) *popup_getpos()*
@@ -428,6 +453,8 @@ popup_getpos({id}) *popup_getpos()*
Can also be used as a |method|: >
GetPopup()->popup_getpos()
+<
+ Return type: dict<number> or dict<any>
popup_hide({id}) *popup_hide()*
@@ -440,11 +467,15 @@ popup_hide({id}) *popup_hide()*
Can also be used as a |method|: >
GetPopup()->popup_hide()
+<
+ Return type: |Number|
popup_list() *popup_list()*
Return a List with the |window-ID| of all existing popups.
+ Return type: list<number> or list<any>
+
popup_locate({row}, {col}) *popup_locate()*
Return the |window-ID| of the popup at screen position {row}
@@ -452,6 +483,8 @@ popup_locate({row}, {col}) *popup_locate()*
highest zindex is returned. If there are no popups at this
position then zero is returned.
+ Return type: |Number|
+
popup_menu({what}, {options}) *popup_menu()*
Show the {what} near the cursor, handle selecting one of the
@@ -484,6 +517,8 @@ popup_menu({what}, {options}) *popup_menu()*
< Can also be used as a |method|: >
GetChoices()->popup_menu({})
+<
+ Return type: |Number|
popup_move({id}, {options}) *popup_move()*
@@ -503,6 +538,8 @@ popup_move({id}, {options}) *popup_move()*
Can also be used as a |method|: >
GetPopup()->popup_move(options)
+<
+ Return type: |Number|
popup_notification({what}, {options}) *popup_notification()*
@@ -533,6 +570,8 @@ popup_notification({what}, {options}) *popup_notification()*
Can also be used as a |method|: >
GetText()->popup_notification({})
+<
+ Return type: |Number|
popup_setoptions({id}, {options}) *popup_setoptions()*
@@ -569,6 +608,8 @@ popup_setoptions({id}, {options}) *popup_setoptions()*
Can also be used as a |method|: >
GetPopup()->popup_setoptions(options)
+<
+ Return type: |Number|
popup_settext({id}, {text}) *popup_settext()*
@@ -580,6 +621,8 @@ popup_settext({id}, {text}) *popup_settext()*
Can also be used as a |method|: >
GetPopup()->popup_settext('hello')
+<
+ Return type: |Number|
popup_show({id}) *popup_show()*
@@ -588,6 +631,8 @@ popup_show({id}) *popup_show()*
If {id} is the info popup it will be positioned next to the
current popup menu item.
+ Return type: |Number|
+
==============================================================================
3. Usage *popup-usage*
diff --git a/runtime/doc/print.txt b/runtime/doc/print.txt
index 84fca44..55a9c37 100644
--- a/runtime/doc/print.txt
+++ b/runtime/doc/print.txt
@@ -1,4 +1,4 @@
-*print.txt* For Vim version 9.1. Last change: 2022 Oct 01
+*print.txt* For Vim version 9.1. Last change: 2024 May 11
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -497,10 +497,11 @@ No CJK fonts are supplied with Vim. There are some free Korean, Japanese, and
Traditional Chinese fonts available at:
http://examples.oreilly.com/cjkvinfo/adobe/samples/
+ https://resources.oreilly.com/examples/9781565922242/
You can find descriptions of the various fonts in the read me file at
- http://examples.oreilly.de/english_examples/cjkvinfo/adobe/00README
+ https://resources.oreilly.com/examples/9781565922242/-/blob/master/00README
Please read your printer documentation on how to install new fonts.
@@ -591,7 +592,7 @@ There are three available versions:
- GNU Ghostscript which is available under the GNU General Public License. It
can be obtained from:
- ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/gnu/
+ https://www.gnu.org/software/ghostscript
- A commercial version for inclusion in commercial products.
@@ -616,10 +617,7 @@ X11
- Ghostview. Obtainable from:
http://www.cs.wisc.edu/~ghost/gv/
-
-- gv. Derived from Ghostview. Obtainable from:
-
- http://wwwthep.physik.uni-mainz.de/~plass/gv/
+ https://www.gnu.org/software/gv/
Copies (possibly not the most recent) can be found at:
@@ -627,7 +625,8 @@ X11
OpenVMS
-- Is apparently supported in the main code now (untested). See:
+- Is apparently supported in the main code now (untested).
+ See (link seems dead):
http://wwwthep.physik.uni-mainz.de/~plass/gv/
@@ -644,12 +643,6 @@ Linux
http://www.cs.wisc.edu/~ghost/gsview/
-- BMV. Different from Ghostview and gv in that it doesn't use X but svgalib.
- Obtainable from:
-
- ftp://sunsite.unc.edu/pub/Linux/apps/graphics/viewers/svga/bmv-1.2.tgz
-
-
7.3 PSUtils
PSUtils is a collection of utility programs for manipulating PostScript
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index e659d39..e2aef24 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -1,4 +1,4 @@
-*quickfix.txt* For Vim version 9.1. Last change: 2023 Apr 15
+*quickfix.txt* For Vim version 9.1. Last change: 2024 Jun 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -287,7 +287,8 @@ processing a quickfix or location list command, it will be aborted.
current window is used instead of the quickfix list.
*:cb* *:cbuffer* *E681*
-:cb[uffer][!] [bufnr] Read the error list from the current buffer.
+:[range]cb[uffer][!] [bufnr]
+ Read the error list from the current buffer.
When [bufnr] is given it must be the number of a
loaded buffer. That buffer will then be used instead
of the current buffer.
@@ -296,26 +297,31 @@ processing a quickfix or location list command, it will be aborted.
See |:cc| for [!].
*:lb* *:lbuffer*
-:lb[uffer][!] [bufnr] Same as ":cbuffer", except the location list for the
+:[range]lb[uffer][!] [bufnr]
+ Same as ":cbuffer", except the location list for the
current window is used instead of the quickfix list.
*:cgetb* *:cgetbuffer*
-:cgetb[uffer] [bufnr] Read the error list from the current buffer. Just
+:[range]cgetb[uffer] [bufnr]
+ Read the error list from the current buffer. Just
like ":cbuffer" but don't jump to the first error.
*:lgetb* *:lgetbuffer*
-:lgetb[uffer] [bufnr] Same as ":cgetbuffer", except the location list for
+:[range]lgetb[uffer] [bufnr]
+ Same as ":cgetbuffer", except the location list for
the current window is used instead of the quickfix
list.
*:cad* *:cadd* *:caddbuffer*
-:cad[dbuffer] [bufnr] Read the error list from the current buffer and add
+:[range]cad[dbuffer] [bufnr]
+ Read the error list from the current buffer and add
the errors to the current quickfix list. If a
quickfix list is not present, then a new list is
created. Otherwise, same as ":cbuffer".
*:laddb* *:laddbuffer*
-:laddb[uffer] [bufnr] Same as ":caddbuffer", except the location list for
+:[range]laddb[uffer] [bufnr]
+ Same as ":caddbuffer", except the location list for
the current window is used instead of the quickfix
list.
@@ -1297,6 +1303,14 @@ g:compiler_gcc_ignore_unmatched_lines
positives.
+JAVAC *compiler-javac*
+
+Commonly used compiler options can be added to 'makeprg' by setting the
+g:javac_makeprg_params variable. For example: >
+
+ let g:javac_makeprg_params = "-Xlint:all -encoding utf-8"
+<
+
MANX AZTEC C *quickfix-manx* *compiler-manx*
To use Vim with Manx's Aztec C compiler on the Amiga you should do the
@@ -1329,7 +1343,7 @@ passed to make, say :make html or :make pdf.
Additional arguments can be passed to pandoc:
- either by appending them to make, say `:make html --self-contained` .
-- or setting them in `b:pandoc_compiler_args` or `g:pandoc_compiler_args`
+- or setting them in `b:pandoc_compiler_args` or `g:pandoc_compiler_args`.
PERL *quickfix-perl* *compiler-perl*
diff --git a/runtime/doc/sign.txt b/runtime/doc/sign.txt
index 02240f0..dac3a57 100644
--- a/runtime/doc/sign.txt
+++ b/runtime/doc/sign.txt
@@ -1,4 +1,4 @@
-*sign.txt* For Vim version 9.1. Last change: 2023 Feb 21
+*sign.txt* For Vim version 9.1. Last change: 2024 Jun 08
VIM REFERENCE MANUAL by Gordon Prieur
@@ -435,6 +435,9 @@ sign_define({list})
<
Can also be used as a |method|: >
GetSignList()->sign_define()
+<
+ Return type: |Number|
+
sign_getdefined([{name}]) *sign_getdefined()*
Get a list of defined signs and their attributes.
@@ -473,6 +476,9 @@ sign_getdefined([{name}]) *sign_getdefined()*
<
Can also be used as a |method|: >
GetSignList()->sign_getdefined()
+<
+ Return type: list<dict<string>> or list<any>
+
sign_getplaced([{buf} [, {dict}]]) *sign_getplaced()*
Return a list of signs placed in a buffer or all the buffers.
@@ -537,8 +543,10 @@ sign_getplaced([{buf} [, {dict}]]) *sign_getplaced()*
Can also be used as a |method|: >
GetBufname()->sign_getplaced()
<
- *sign_jump()*
-sign_jump({id}, {group}, {buf})
+ Return type: list<dict<any>>
+
+
+sign_jump({id}, {group}, {buf}) *sign_jump()*
Open the buffer {buf} or jump to the window that contains
{buf} and position the cursor at sign {id} in group {group}.
This is similar to the |:sign-jump| command.
@@ -556,6 +564,9 @@ sign_jump({id}, {group}, {buf})
Can also be used as a |method|: >
GetSignid()->sign_jump()
<
+ Return type: |Number|
+
+
*sign_place()*
sign_place({id}, {group}, {name}, {buf} [, {dict}])
Place the sign defined as {name} at line {lnum} in file or
@@ -608,8 +619,10 @@ sign_place({id}, {group}, {name}, {buf} [, {dict}])
Can also be used as a |method|: >
GetSignid()->sign_place(group, name, expr)
<
- *sign_placelist()*
-sign_placelist({list})
+ Return type: |Number|
+
+
+sign_placelist({list}) *sign_placelist()*
Place one or more signs. This is similar to the
|sign_place()| function. The {list} argument specifies the
List of signs to place. Each list item is a dict with the
@@ -669,6 +682,9 @@ sign_placelist({list})
<
Can also be used as a |method|: >
GetSignlist()->sign_placelist()
+<
+ Return type: |Number|
+
sign_undefine([{name}]) *sign_undefine()*
sign_undefine({list})
@@ -695,6 +711,9 @@ sign_undefine({list})
<
Can also be used as a |method|: >
GetSignlist()->sign_undefine()
+<
+ Return type: |Number|
+
sign_unplace({group} [, {dict}]) *sign_unplace()*
Remove a previously placed sign in one or more buffers. This
@@ -741,6 +760,9 @@ sign_unplace({group} [, {dict}]) *sign_unplace()*
< Can also be used as a |method|: >
GetSigngroup()->sign_unplace()
<
+ Return type: |Number|
+
+
sign_unplacelist({list}) *sign_unplacelist()*
Remove previously placed signs from one or more buffers. This
is similar to the |sign_unplace()| function.
@@ -772,5 +794,6 @@ sign_unplacelist({list}) *sign_unplacelist()*
Can also be used as a |method|: >
GetSignlist()->sign_unplacelist()
<
+ Return type: list<number> or list<any>
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt
index dea3adb..809e3a8 100644
--- a/runtime/doc/spell.txt
+++ b/runtime/doc/spell.txt
@@ -1,4 +1,4 @@
-*spell.txt* For Vim version 9.1. Last change: 2023 May 25
+*spell.txt* For Vim version 9.1. Last change: 2024 May 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -62,6 +62,17 @@ To search for the next misspelled word:
*[S*
[S Like "]S" but search backwards.
+ *]r*
+]r Move to next "rare" word after the cursor.
+ A count before the command can be used to repeat.
+ 'wrapscan' applies.
+
+ *[r*
+[r Like "]r" but search backwards, find the "rare"
+ word before the cursor. Doesn't recognize words
+ split over two lines, thus may stop at words that are
+ not highlighted as rare.
+
To add words to your own word list:
@@ -903,7 +914,7 @@ right encoding.
*spell-AUTHOR* *spell-EMAIL* *spell-COPYRIGHT*
NAME Name of the language
VERSION 1.0.1 with fixes
- HOME http://www.myhome.eu
+ HOME <URL>
AUTHOR John Doe
EMAIL john AT Doe DOT net
COPYRIGHT LGPL
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index b83a61e..30e85ed 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1,4 +1,4 @@
-*starting.txt* For Vim version 9.1. Last change: 2024 Apr 21
+*starting.txt* For Vim version 9.1. Last change: 2024 Jun 04
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -104,9 +104,9 @@ rvim vim -Z Like "vim", but in restricted mode (see |-Z|) *rvim*
rview vim -RZ Like "view", but in restricted mode. *rview*
rgvim vim -gZ Like "gvim", but in restricted mode. *rgvim*
rgview vim -RgZ Like "gview", but in restricted mode. *rgview*
-evim vim -y Easy Vim: set 'insertmode' (see |-y|) *evim*
-eview vim -yR Like "evim" in read-only mode *eview*
-vimdiff vim -d Start in diff mode |diff-mode|
+evim vim -y Easy Vim: set 'insertmode' (see |-y|) *evim*
+eview vim -yR Like "evim" in read-only mode *eview*
+vimdiff vim -d Start in diff mode |diff-mode|
gvimdiff vim -gd Start in diff mode |diff-mode|
Additional characters may follow, they are ignored. For example, you can have
@@ -428,8 +428,8 @@ a slash. Thus "-R" means recovery and "-/R" readonly.
--not-a-term Tells Vim that the user knows that the input and/or output is
not connected to a terminal. This will avoid the warning and
the two second delay that would happen.
- Also avoids the "Reading from stdin..." message.
- Also avoids the "N files to edit" message.
+ Also avoids the "Reading from stdin..." as well as the
+ "N files to edit" message.
--gui-dialog-file {name} *--gui-dialog-file*
When using the GUI, instead of showing a dialog, write the
@@ -812,7 +812,7 @@ accordingly. Vim proceeds in this order:
Places for your personal initializations:
Unix $HOME/.vimrc, $HOME/.vim/vimrc
- or $XDG_CONFIG_HOME/vim/vimrc
+ or $XDG_CONFIG_HOME/vim/vimrc
MS-Windows $HOME/_vimrc, $HOME/vimfiles/vimrc
or $VIM/_vimrc
Amiga s:.vimrc, home:.vimrc, home:vimfiles:vimrc
@@ -1119,8 +1119,8 @@ feature backward compatible). However, if you want to migrate to use
and `~/.vim/vimrc` file.
*xdg-runtime*
-When the |xdg-vimrc| is used the |'runtimepath'| will be modified accordingly
-to respect the |xdg-base-dir|: >
+When the |xdg-vimrc| is used the 'runtimepath' and 'packpath' options will be
+modified accordingly to respect the |xdg-base-dir|: >
"$XDG_CONFIG_HOME/vim,$VIMRUNTIME,/after,$XDG_CONFIG_HOME/vim/after"
<
@@ -1712,7 +1712,8 @@ most of the information will be restored).
|viminfo-file-name| above).
If [!] is given, then any information that is
already set (registers, marks, |v:oldfiles|, etc.)
- will be overwritten.
+ will be overwritten. "E195" may be given, when
+ 'viminfofile' has been set to "NONE".
*:wv* *:wviminfo* *E137* *E138* *E574* *E886* *E929*
:wv[iminfo][!] [file] Write to viminfo file [file] (default: see
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index bfc4645..c07c3a4 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1,4 +1,4 @@
-*syntax.txt* For Vim version 9.1. Last change: 2024 Apr 26
+*syntax.txt* For Vim version 9.1. Last change: 2024 Jun 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -935,18 +935,19 @@ ASTRO *astro.vim* *ft-astro-syntax*
Configuration
The following variables control certain syntax highlighting features.
-You can add them to your .vimrc: >
+You can add them to your .vimrc.
+
+To enable TypeScript and TSX for ".astro" files (default "disable"): >
let g:astro_typescript = "enable"
<
-Enables TypeScript and TSX for ".astro" files. Default Value: "disable" >
+To enable Stylus for ".astro" files (default "disable"): >
let g:astro_stylus = "enable"
<
-Enables Stylus for ".astro" files. Default Value: "disable"
-
NOTE: You need to install an external plugin to support stylus in astro files.
-ASPPERL and ASPVBS *ft-aspperl-syntax* *ft-aspvbs-syntax*
+ASPPERL *ft-aspperl-syntax*
+ASPVBS *ft-aspvbs-syntax*
*.asp and *.asa files could be either Perl or Visual Basic script. Since it's
hard to detect this you can set two global variables to tell Vim what you are
@@ -1482,9 +1483,9 @@ Two syntax highlighting files exist for Euphoria. One for Euphoria
version 3.1.1, which is the default syntax highlighting file, and one for
Euphoria version 4.0.5 or later.
-Euphoria version 3.1.1 (http://www.rapideuphoria.com/) is still necessary
-for developing applications for the DOS platform, which Euphoria version 4
-(http://www.openeuphoria.org/) does not support.
+Euphoria version 3.1.1 (http://www.rapideuphoria.com/ link seems dead) is
+still necessary for developing applications for the DOS platform, which
+Euphoria version 4 (http://www.openeuphoria.org/) does not support.
The following file extensions are auto-detected as Euphoria file type:
@@ -1541,7 +1542,8 @@ Elixir.
FLEXWIKI *flexwiki.vim* *ft-flexwiki-syntax*
-FlexWiki is an ASP.NET-based wiki package available at http://www.flexwiki.com
+FlexWiki is an ASP.NET-based wiki package which used to be available at
+http://www.flexwiki.com
NOTE: This site currently doesn't work, on Wikipedia is mentioned that
development stopped in 2009.
@@ -1907,7 +1909,7 @@ Note: Syntax folding might slow down syntax highlighting significantly,
especially for large files.
-HTML/OS (by Aestiva) *htmlos.vim* *ft-htmlos-syntax*
+HTML/OS (BY AESTIVA) *htmlos.vim* *ft-htmlos-syntax*
The coloring scheme for HTML/OS works as follows:
@@ -2014,15 +2016,25 @@ Function names are not highlighted, as the way to find functions depends on
how you write Java code. The syntax file knows two possible ways to highlight
functions:
-If you write function declarations that are always indented by either
-a tab, 8 spaces or 2 spaces you may want to set >
+If you write function declarations that are consistently indented by either
+a tab, or a space . . . or eight space character(s), you may want to set >
:let java_highlight_functions="indent"
+ :let java_highlight_functions="indent1"
+ :let java_highlight_functions="indent2"
+ :let java_highlight_functions="indent3"
+ :let java_highlight_functions="indent4"
+ :let java_highlight_functions="indent5"
+ :let java_highlight_functions="indent6"
+ :let java_highlight_functions="indent7"
+ :let java_highlight_functions="indent8"
+Note that in terms of 'shiftwidth', this is the leftmost step of indentation.
However, if you follow the Java guidelines about how functions and classes are
-supposed to be named (with respect to upper and lowercase), use >
+supposed to be named (with respect to upper- and lowercase) and there is any
+amount of indentation, you may want to set >
:let java_highlight_functions="style"
-If both options do not work for you, but you would still want function
-declarations to be highlighted create your own definitions by changing the
-definitions in java.vim or by creating your own java.vim which includes the
+If neither setting does work for you, but you would still want function
+declarations to be highlighted, create your own definitions by changing the
+definitions in java.vim or by creating your own java.vim that includes the
original one and then adds the code to highlight functions.
In Java 1.1 the functions System.out.println() and System.err.println() should
@@ -3036,6 +3048,13 @@ To highlight R code in knitr chunk headers, add to your |vimrc|: >
let rrst_syn_hl_chunk = 1
+RASI *rasi.vim* *ft-rasi-syntax*
+
+Rasi stands for Rofi Advanced Style Information. It is used by the program
+rofi to style the rendering of the search window. The language is heavily
+inspired by CSS stylesheet. Files with the following extensions are recognized
+as rasi files: .rasi.
+
READLINE *readline.vim* *ft-readline-syntax*
The readline library is primarily used by the BASH shell, which adds quite a
@@ -3752,6 +3771,19 @@ set "tf_minlines" to the value you desire. Example: >
:let tf_minlines = your choice
<
+TYPESCRIPT *typescript.vim* *ft-typescript-syntax*
+ *typescriptreact.vim* *ft-typescriptreact-syntax*
+
+There is one option to control the TypeScript syntax highlighting.
+
+ *g:typescript_host_keyword*
+When this variable is set to 1, host-specific APIs such as `addEventListener`
+are highlighted. To disable set it to zero in your .vimrc: >
+
+ let g:typescript_host_keyword = 0
+<
+The default value is 1.
+
VIM *vim.vim* *ft-vim-syntax*
*g:vimsyn_minlines* *g:vimsyn_maxlines*
There is a trade-off between more accurate syntax highlighting versus screen
@@ -3770,35 +3802,42 @@ The g:vimsyn_embed option allows users to select what, if any, types of
embedded script highlighting they wish to have. >
g:vimsyn_embed == 0 : don't support any embedded scripts
- g:vimsyn_embed =~ 'l' : support embedded lua
- g:vimsyn_embed =~ 'm' : support embedded mzscheme
- g:vimsyn_embed =~ 'p' : support embedded perl
- g:vimsyn_embed =~ 'P' : support embedded python
- g:vimsyn_embed =~ 'r' : support embedded ruby
- g:vimsyn_embed =~ 't' : support embedded tcl
+ g:vimsyn_embed =~ 'l' : support embedded Lua
+ g:vimsyn_embed =~ 'm' : support embedded MzScheme
+ g:vimsyn_embed =~ 'p' : support embedded Perl
+ g:vimsyn_embed =~ 'P' : support embedded Python
+ g:vimsyn_embed =~ 'r' : support embedded Ruby
+ g:vimsyn_embed =~ 't' : support embedded Tcl
<
By default, g:vimsyn_embed is a string supporting interpreters that your vim
-itself supports. Concatenate multiple characters to support multiple types
-of embedded interpreters; ie. g:vimsyn_embed= "mp" supports embedded mzscheme
-and embedded perl.
+itself supports. Concatenate the indicated characters to support multiple
+types of embedded interpreters (e.g., g:vimsyn_embed = "mp" supports embedded
+mzscheme and embedded perl).
*g:vimsyn_folding*
-
-Some folding is now supported with syntax/vim.vim: >
+Some folding is now supported with when 'foldmethod' is set to "syntax": >
g:vimsyn_folding == 0 or doesn't exist: no syntax-based folding
g:vimsyn_folding =~ 'a' : augroups
g:vimsyn_folding =~ 'f' : fold functions
g:vimsyn_folding =~ 'h' : fold heredocs
g:vimsyn_folding =~ 'H' : fold Vim9-script legacy headers
- g:vimsyn_folding =~ 'l' : fold lua script
- g:vimsyn_folding =~ 'm' : fold mzscheme script
- g:vimsyn_folding =~ 'p' : fold perl script
- g:vimsyn_folding =~ 'P' : fold python script
- g:vimsyn_folding =~ 'r' : fold ruby script
- g:vimsyn_folding =~ 't' : fold tcl script
-let g:vimsyn_folding = 'acfhlmpPrt'
+ g:vimsyn_folding =~ 'l' : fold Lua script
+ g:vimsyn_folding =~ 'm' : fold MzScheme script
+ g:vimsyn_folding =~ 'p' : fold Perl script
+ g:vimsyn_folding =~ 'P' : fold Python script
+ g:vimsyn_folding =~ 'r' : fold Ruby script
+ g:vimsyn_folding =~ 't' : fold Tcl script
<
- *g:vimsyn_noerror*
+
+By default, g:vimsyn_folding is unset. Concatenate the indicated characters
+to support folding of multiple syntax constructs (e.g.,
+g:vimsyn_folding = "fh" will enable folding of both functions and heredocs).
+
+ *g:vimsyn_comment_strings*
+By default, strings are highlighted inside comments. This may be disabled by
+setting g:vimsyn_comment_strings to false.
+
+ *g:vimsyn_noerror*
Not all error highlighting that syntax/vim.vim does may be correct; Vim script
is a difficult language to highlight correctly. A way to suppress error
highlighting is to put the following line in your |vimrc|: >
@@ -5645,6 +5684,10 @@ PmenuExtraSel Popup menu: Selected item "extra text".
PmenuSbar Popup menu: Scrollbar.
*hl-PmenuThumb*
PmenuThumb Popup menu: Thumb of the scrollbar.
+ *hl-PmenuMatch*
+PmenuMatch Popup menu: Matched text in normal item.
+ *hl-PmenuMatchSel*
+PmenuMatchSel Popup menu: Matched text in selected item.
*hl-PopupNotification*
PopupNotification
Popup window created with |popup_notification()|. If not
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt
index a922604..abbc778 100644
--- a/runtime/doc/tabpage.txt
+++ b/runtime/doc/tabpage.txt
@@ -1,4 +1,4 @@
-*tabpage.txt* For Vim version 9.1. Last change: 2024 Mar 25
+*tabpage.txt* For Vim version 9.1. Last change: 2024 May 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -225,8 +225,9 @@ gT Go to the previous tab page. Wraps around from the first one
*:tabl* *:tablast*
:tabl[ast] Go to the last tab page.
- *g<Tab>* *CTRL-W_g<Tab>* *<C-Tab>*
-g<Tab> Go to the last accessed tab page.
+<C-Tab> *g<Tab>* *CTRL-W_g<Tab>* *<C-Tab>*
+g<Tab>
+CTRL-W g<Tab> Go to the last accessed tab page.
Other commands:
*:tabs*
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 8096f5d..794fa0c 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -2015,6 +2015,7 @@ $quote eval.txt /*$quote*
52.3 usr_52.txt /*52.3*
52.4 usr_52.txt /*52.4*
52.5 usr_52.txt /*52.5*
+52.6 usr_52.txt /*52.6*
8g8 various.txt /*8g8*
90.1 usr_90.txt /*90.1*
90.2 usr_90.txt /*90.2*
@@ -5876,6 +5877,7 @@ ZZ editing.txt /*ZZ*
[p change.txt /*[p*
[pattern] pattern.txt /*[pattern]*
[quotex] intro.txt /*[quotex]*
+[r spell.txt /*[r*
[range] cmdline.txt /*[range]*
[s spell.txt /*[s*
[star motion.txt /*[star*
@@ -5904,6 +5906,7 @@ ZZ editing.txt /*ZZ*
]i tagsrch.txt /*]i*
]m motion.txt /*]m*
]p change.txt /*]p*
+]r spell.txt /*]r*
]s spell.txt /*]s*
]star motion.txt /*]star*
]z fold.txt /*]z*
@@ -6529,6 +6532,7 @@ compiler-dotnet quickfix.txt /*compiler-dotnet*
compiler-gcc quickfix.txt /*compiler-gcc*
compiler-gnat ft_ada.txt /*compiler-gnat*
compiler-hpada ft_ada.txt /*compiler-hpada*
+compiler-javac quickfix.txt /*compiler-javac*
compiler-manx quickfix.txt /*compiler-manx*
compiler-pandoc quickfix.txt /*compiler-pandoc*
compiler-perl quickfix.txt /*compiler-perl*
@@ -7088,6 +7092,7 @@ file-searching editing.txt /*file-searching*
file-type filetype.txt /*file-type*
file-types filetype.txt /*file-types*
file_readable() builtin.txt /*file_readable()*
+filecopy() builtin.txt /*filecopy()*
fileencoding-changed version6.txt /*fileencoding-changed*
filename-backslash cmdline.txt /*filename-backslash*
filename-modifiers cmdline.txt /*filename-modifiers*
@@ -7226,6 +7231,7 @@ ft-ada-syntax ft_ada.txt /*ft-ada-syntax*
ft-ada-variables ft_ada.txt /*ft-ada-variables*
ft-ant-syntax syntax.txt /*ft-ant-syntax*
ft-apache-syntax syntax.txt /*ft-apache-syntax*
+ft-arduino-plugin filetype.txt /*ft-arduino-plugin*
ft-asciidoc-plugin filetype.txt /*ft-asciidoc-plugin*
ft-asm-syntax syntax.txt /*ft-asm-syntax*
ft-asm68k-syntax syntax.txt /*ft-asm68k-syntax*
@@ -7282,6 +7288,7 @@ ft-gitcommit-plugin filetype.txt /*ft-gitcommit-plugin*
ft-gprof-plugin filetype.txt /*ft-gprof-plugin*
ft-groff-syntax syntax.txt /*ft-groff-syntax*
ft-gsp-syntax syntax.txt /*ft-gsp-syntax*
+ft-hare filetype.txt /*ft-hare*
ft-haskell-syntax syntax.txt /*ft-haskell-syntax*
ft-html-indent indent.txt /*ft-html-indent*
ft-html-omni insert.txt /*ft-html-omni*
@@ -7355,6 +7362,7 @@ ft-qf-plugin filetype.txt /*ft-qf-plugin*
ft-quake-syntax syntax.txt /*ft-quake-syntax*
ft-r-indent indent.txt /*ft-r-indent*
ft-r-syntax syntax.txt /*ft-r-syntax*
+ft-rasi-syntax syntax.txt /*ft-rasi-syntax*
ft-readline-syntax syntax.txt /*ft-readline-syntax*
ft-rego-syntax syntax.txt /*ft-rego-syntax*
ft-rexx-syntax syntax.txt /*ft-rexx-syntax*
@@ -7388,6 +7396,8 @@ ft-termcap-syntax syntax.txt /*ft-termcap-syntax*
ft-tex-plugin filetype.txt /*ft-tex-plugin*
ft-tex-syntax syntax.txt /*ft-tex-syntax*
ft-tf-syntax syntax.txt /*ft-tf-syntax*
+ft-typescript-syntax syntax.txt /*ft-typescript-syntax*
+ft-typescriptreact-syntax syntax.txt /*ft-typescriptreact-syntax*
ft-vb-syntax syntax.txt /*ft-vb-syntax*
ft-verilog-indent indent.txt /*ft-verilog-indent*
ft-vhdl-indent indent.txt /*ft-vhdl-indent*
@@ -7401,10 +7411,12 @@ ft-xml-syntax syntax.txt /*ft-xml-syntax*
ft-xpm-syntax syntax.txt /*ft-xpm-syntax*
ft-yaml-indent indent.txt /*ft-yaml-indent*
ft-yaml-syntax syntax.txt /*ft-yaml-syntax*
+ft-zig-plugin filetype.txt /*ft-zig-plugin*
ft-zimbu-plugin filetype.txt /*ft-zimbu-plugin*
ft-zsh-syntax syntax.txt /*ft-zsh-syntax*
ft_ada.txt ft_ada.txt /*ft_ada.txt*
ft_context.txt ft_context.txt /*ft_context.txt*
+ft_hare.txt ft_hare.txt /*ft_hare.txt*
ft_mp.txt ft_mp.txt /*ft_mp.txt*
ft_ps1.txt ft_ps1.txt /*ft_ps1.txt*
ft_raku.txt ft_raku.txt /*ft_raku.txt*
@@ -7490,7 +7502,9 @@ g:decada.Error_Format ft_ada.txt /*g:decada.Error_Format*
g:decada.Make() ft_ada.txt /*g:decada.Make()*
g:decada.Make_Command ft_ada.txt /*g:decada.Make_Command*
g:decada.Unit_Name() ft_ada.txt /*g:decada.Unit_Name()*
+g:do_no_lazyload_menus gui.txt /*g:do_no_lazyload_menus*
g:filetype_csh syntax.txt /*g:filetype_csh*
+g:filetype_haredoc ft_hare.txt /*g:filetype_haredoc*
g:filetype_r syntax.txt /*g:filetype_r*
g:ftplugin_rust_source_path ft_rust.txt /*g:ftplugin_rust_source_path*
g:gnat ft_ada.txt /*g:gnat*
@@ -7506,6 +7520,9 @@ g:gnat.Set_Project_File() ft_ada.txt /*g:gnat.Set_Project_File()*
g:gnat.Tags() ft_ada.txt /*g:gnat.Tags()*
g:gnat.Tags_Command ft_ada.txt /*g:gnat.Tags_Command*
g:gzip_exec pi_gzip.txt /*g:gzip_exec*
+g:hare_recommended_style ft_hare.txt /*g:hare_recommended_style*
+g:hare_space_error ft_hare.txt /*g:hare_space_error*
+g:haredoc_search_depth ft_hare.txt /*g:haredoc_search_depth*
g:html_charset_override syntax.txt /*g:html_charset_override*
g:html_diff_one_file syntax.txt /*g:html_diff_one_file*
g:html_dynamic_folds syntax.txt /*g:html_dynamic_folds*
@@ -7630,7 +7647,6 @@ g:netrw_use_errorwindow pi_netrw.txt /*g:netrw_use_errorwindow*
g:netrw_use_noswf pi_netrw.txt /*g:netrw_use_noswf*
g:netrw_use_nt_rcp pi_netrw.txt /*g:netrw_use_nt_rcp*
g:netrw_usetab pi_netrw.txt /*g:netrw_usetab*
-g:netrw_win95ftp pi_netrw.txt /*g:netrw_win95ftp*
g:netrw_winsize pi_netrw.txt /*g:netrw_winsize*
g:netrw_wiw pi_netrw.txt /*g:netrw_wiw*
g:netrw_xstrlen pi_netrw.txt /*g:netrw_xstrlen*
@@ -7688,17 +7704,21 @@ g:tex_stylish syntax.txt /*g:tex_stylish*
g:tex_subscripts syntax.txt /*g:tex_subscripts*
g:tex_superscripts syntax.txt /*g:tex_superscripts*
g:tex_verbspell syntax.txt /*g:tex_verbspell*
+g:typescript_host_keyword syntax.txt /*g:typescript_host_keyword*
g:var eval.txt /*g:var*
g:vim_indent indent.txt /*g:vim_indent*
g:vim_indent_cont indent.txt /*g:vim_indent_cont*
g:vimball_home pi_vimball.txt /*g:vimball_home*
g:vimball_mkdir pi_vimball.txt /*g:vimball_mkdir*
+g:vimsyn_comment_strings syntax.txt /*g:vimsyn_comment_strings*
g:vimsyn_embed syntax.txt /*g:vimsyn_embed*
g:vimsyn_folding syntax.txt /*g:vimsyn_folding*
g:vimsyn_maxlines syntax.txt /*g:vimsyn_maxlines*
g:vimsyn_minlines syntax.txt /*g:vimsyn_minlines*
g:vimsyn_noerror syntax.txt /*g:vimsyn_noerror*
g:yaml_schema syntax.txt /*g:yaml_schema*
+g:zig_recommended_style filetype.txt /*g:zig_recommended_style*
+g:zig_std_dir filetype.txt /*g:zig_std_dir*
g:zipPlugin_ext pi_zip.txt /*g:zipPlugin_ext*
g:zip_exec pi_zip.txt /*g:zip_exec*
g:zip_extractcmd pi_zip.txt /*g:zip_extractcmd*
@@ -7798,6 +7818,7 @@ getreg() builtin.txt /*getreg()*
getreginfo() builtin.txt /*getreginfo()*
getregion() builtin.txt /*getregion()*
getregion-notes builtin.txt /*getregion-notes*
+getregionpos() builtin.txt /*getregionpos()*
getregtype() builtin.txt /*getregtype()*
getscript pi_getscript.txt /*getscript*
getscript-autoinstall pi_getscript.txt /*getscript-autoinstall*
@@ -7968,6 +7989,10 @@ haiku-user-settings-dir os_haiku.txt /*haiku-user-settings-dir*
haiku-vimdir os_haiku.txt /*haiku-vimdir*
hangul hangulin.txt /*hangul*
hangulin.txt hangulin.txt /*hangulin.txt*
+hare ft_hare.txt /*hare*
+hare-intro ft_hare.txt /*hare-intro*
+hare-plugin ft_hare.txt /*hare-plugin*
+hare-settings ft_hare.txt /*hare-settings*
has() builtin.txt /*has()*
has-patch builtin.txt /*has-patch*
has-python if_pyth.txt /*has-python*
@@ -8067,6 +8092,8 @@ hl-PmenuExtra syntax.txt /*hl-PmenuExtra*
hl-PmenuExtraSel syntax.txt /*hl-PmenuExtraSel*
hl-PmenuKind syntax.txt /*hl-PmenuKind*
hl-PmenuKindSel syntax.txt /*hl-PmenuKindSel*
+hl-PmenuMatch syntax.txt /*hl-PmenuMatch*
+hl-PmenuMatchSel syntax.txt /*hl-PmenuMatchSel*
hl-PmenuSbar syntax.txt /*hl-PmenuSbar*
hl-PmenuSel syntax.txt /*hl-PmenuSel*
hl-PmenuThumb syntax.txt /*hl-PmenuThumb*
@@ -8692,6 +8719,7 @@ mbyte-utf8 mbyte.txt /*mbyte-utf8*
mbyte.txt mbyte.txt /*mbyte.txt*
menu-changes-5.4 version5.txt /*menu-changes-5.4*
menu-examples gui.txt /*menu-examples*
+menu-lazyload gui.txt /*menu-lazyload*
menu-priority gui.txt /*menu-priority*
menu-separator gui.txt /*menu-separator*
menu-shortcut gui.txt /*menu-shortcut*
@@ -8836,11 +8864,11 @@ netrw-D pi_netrw.txt /*netrw-D*
netrw-I pi_netrw.txt /*netrw-I*
netrw-O pi_netrw.txt /*netrw-O*
netrw-P pi_netrw.txt /*netrw-P*
+netrw-P17 pi_netrw.txt /*netrw-P17*
netrw-P18 pi_netrw.txt /*netrw-P18*
netrw-P19 pi_netrw.txt /*netrw-P19*
netrw-P20 pi_netrw.txt /*netrw-P20*
netrw-P21 pi_netrw.txt /*netrw-P21*
-netrw-P22 pi_netrw.txt /*netrw-P22*
netrw-R pi_netrw.txt /*netrw-R*
netrw-S pi_netrw.txt /*netrw-S*
netrw-Tb pi_netrw.txt /*netrw-Tb*
@@ -8970,7 +8998,6 @@ netrw-p13 pi_netrw.txt /*netrw-p13*
netrw-p14 pi_netrw.txt /*netrw-p14*
netrw-p15 pi_netrw.txt /*netrw-p15*
netrw-p16 pi_netrw.txt /*netrw-p16*
-netrw-p17 pi_netrw.txt /*netrw-p17*
netrw-p2 pi_netrw.txt /*netrw-p2*
netrw-p3 pi_netrw.txt /*netrw-p3*
netrw-p4 pi_netrw.txt /*netrw-p4*
@@ -9517,6 +9544,7 @@ python-eval if_pyth.txt /*python-eval*
python-examples if_pyth.txt /*python-examples*
python-fchdir if_pyth.txt /*python-fchdir*
python-find_module if_pyth.txt /*python-find_module*
+python-find_spec if_pyth.txt /*python-find_spec*
python-foreach_rtp if_pyth.txt /*python-foreach_rtp*
python-input if_pyth.txt /*python-input*
python-options if_pyth.txt /*python-options*
@@ -9622,6 +9650,7 @@ raku-unicode ft_raku.txt /*raku-unicode*
rand() builtin.txt /*rand()*
random builtin.txt /*random*
range() builtin.txt /*range()*
+rasi.vim syntax.txt /*rasi.vim*
raw-terminal-mode term.txt /*raw-terminal-mode*
rcp pi_netrw.txt /*rcp*
read-in-close-cb channel.txt /*read-in-close-cb*
@@ -10669,7 +10698,9 @@ text-functions usr_41.txt /*text-functions*
text-objects motion.txt /*text-objects*
text-objects-changed version5.txt /*text-objects-changed*
text-prop-changes textprop.txt /*text-prop-changes*
+text-prop-cleared textprop.txt /*text-prop-cleared*
text-prop-functions textprop.txt /*text-prop-functions*
+text-prop-functions-details textprop.txt /*text-prop-functions-details*
text-prop-intro textprop.txt /*text-prop-intro*
text-properties textprop.txt /*text-properties*
text-property-functions usr_41.txt /*text-property-functions*
@@ -10727,6 +10758,8 @@ type-inference vim9.txt /*type-inference*
type-mistakes tips.txt /*type-mistakes*
typealias vim9class.txt /*typealias*
typename() builtin.txt /*typename()*
+typescript.vim syntax.txt /*typescript.vim*
+typescriptreact.vim syntax.txt /*typescriptreact.vim*
u undo.txt /*u*
uganda uganda.txt /*uganda*
uganda.txt uganda.txt /*uganda.txt*
@@ -11130,6 +11163,7 @@ vim-raku ft_raku.txt /*vim-raku*
vim-script-intro usr_41.txt /*vim-script-intro*
vim-script-library eval.txt /*vim-script-library*
vim-security intro.txt /*vim-security*
+vim-shebang various.txt /*vim-shebang*
vim-use intro.txt /*vim-use*
vim-variable eval.txt /*vim-variable*
vim.b if_lua.txt /*vim.b*
diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt
index d3d549a..7091f83 100644
--- a/runtime/doc/tagsrch.txt
+++ b/runtime/doc/tagsrch.txt
@@ -546,7 +546,8 @@ JTags For Java, in Java. It can be found at
http://www.fleiner.com/jtags/.
ptags.py For Python, in Python. Found in your Python source
directory at Tools/scripts/ptags.py.
-ptags For Perl, in Perl. It can be found at
+ptags For Perl, in Perl. It can be found at (link seems
+ dead):
http://www.eleves.ens.fr:8080/home/nthiery/Tags/.
gnatxref For Ada. See http://www.gnuada.org/. gnatxref is
part of the gnat package.
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt
index 1256d75..da6156c 100644
--- a/runtime/doc/term.txt
+++ b/runtime/doc/term.txt
@@ -1,4 +1,4 @@
-*term.txt* For Vim version 9.1. Last change: 2024 Apr 14
+*term.txt* For Vim version 9.1. Last change: 2024 May 05
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -382,8 +382,8 @@ The options are listed below. The associated termcap code is always equal to
the last two characters of the option name. Only one termcap code is
required: Cursor motion, 't_cm'.
-The options 't_da', 't_db', 't_ms', 't_xs', 't_xn', 't_xo' represent flags in the
-termcap. When the termcap flag is present, the option will be set to "y".
+The options 't_da', 't_db', 't_ms', 't_xs', 't_xn', 't_xo' represent flags in
+the termcap. When the termcap flag is present, the option will be set to "y".
But any non-empty string means that the flag is set. An empty string means
that the flag is not set. 't_CS' works like this too, but it isn't a termcap
flag.
diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt
index c99b882..e918394 100644
--- a/runtime/doc/terminal.txt
+++ b/runtime/doc/terminal.txt
@@ -1,4 +1,4 @@
-*terminal.txt* For Vim version 9.1. Last change: 2024 Mar 17
+*terminal.txt* For Vim version 9.1. Last change: 2024 Jun 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -536,8 +536,10 @@ term_dumpdiff({filename}, {filename} [, {options}])
Can also be used as a |method|: >
GetFilename()->term_dumpdiff(otherfile)
<
- *term_dumpload()*
-term_dumpload({filename} [, {options}])
+ Return type: |Number|
+
+
+term_dumpload({filename} [, {options}]) *term_dumpload()*
Open a new window displaying the contents of {filename}
The file must have been created with |term_dumpwrite()|.
Returns the buffer number or zero when it fails.
@@ -548,8 +550,10 @@ term_dumpload({filename} [, {options}])
Can also be used as a |method|: >
GetFilename()->term_dumpload()
<
- *term_dumpwrite()*
-term_dumpwrite({buf}, {filename} [, {options}])
+ Return type: |Number|
+
+
+term_dumpwrite({buf}, {filename} [, {options}]) *term_dumpwrite()*
Dump the contents of the terminal screen of {buf} in the file
{filename}. This uses a format that can be used with
|term_dumpload()| and |term_dumpdiff()|.
@@ -565,6 +569,9 @@ term_dumpwrite({buf}, {filename} [, {options}])
Can also be used as a |method|, the base is used for the file
name: >
GetFilename()->term_dumpwrite(bufnr)
+<
+ Return type: |Number|
+
term_getaltscreen({buf}) *term_getaltscreen()*
Returns 1 if the terminal of {buf} is using the alternate
@@ -573,6 +580,8 @@ term_getaltscreen({buf}) *term_getaltscreen()*
Can also be used as a |method|: >
GetBufnr()->term_getaltscreen()
+<
+ Return type: |Number|
term_getansicolors({buf}) *term_getansicolors()*
@@ -587,8 +596,10 @@ term_getansicolors({buf}) *term_getansicolors()*
Can also be used as a |method|: >
GetBufnr()->term_getansicolors()
+<
+ Return type: list<string> or list<any>
-< {only available when compiled with GUI enabled and/or the
+ {only available when compiled with GUI enabled and/or the
|+termguicolors| feature}
term_getattr({attr}, {what}) *term_getattr()*
@@ -602,6 +613,8 @@ term_getattr({attr}, {what}) *term_getattr()*
Can also be used as a |method|: >
GetAttr()->term_getattr()
+<
+ Return type: |Number|
term_getcursor({buf}) *term_getcursor()*
@@ -627,14 +640,20 @@ term_getcursor({buf}) *term_getcursor()*
Can also be used as a |method|: >
GetBufnr()->term_getcursor()
+<
+ Return type: list<any>
+
term_getjob({buf}) *term_getjob()*
Get the Job associated with terminal window {buf}.
{buf} is used as with |term_getsize()|.
- Returns |v:null| when there is no job.
+ Returns |v:null| when there is no job. In Vim9 script, return
+ |null_job| when there is no job.
Can also be used as a |method|: >
GetBufnr()->term_getjob()
+<
+ Return type: |job|
term_getline({buf}, {row}) *term_getline()*
@@ -649,6 +668,8 @@ term_getline({buf}, {row}) *term_getline()*
Can also be used as a |method|: >
GetBufnr()->term_getline(row)
+<
+ Return type: |String|
term_getscrolled({buf}) *term_getscrolled()*
@@ -664,6 +685,8 @@ term_getscrolled({buf}) *term_getscrolled()*
Can also be used as a |method|: >
GetBufnr()->term_getscrolled()
+<
+ Return type: |Number|
term_getsize({buf}) *term_getsize()*
@@ -677,6 +700,8 @@ term_getsize({buf}) *term_getsize()*
Can also be used as a |method|: >
GetBufnr()->term_getsize()
+<
+ Return type: list<number> or list<any>
term_getstatus({buf}) *term_getstatus()*
@@ -693,6 +718,8 @@ term_getstatus({buf}) *term_getstatus()*
Can also be used as a |method|: >
GetBufnr()->term_getstatus()
+<
+ Return type: |String|
term_gettitle({buf}) *term_gettitle()*
@@ -705,6 +732,8 @@ term_gettitle({buf}) *term_gettitle()*
Can also be used as a |method|: >
GetBufnr()->term_gettitle()
+<
+ Return type: |String|
term_gettty({buf} [, {input}]) *term_gettty()*
@@ -717,12 +746,16 @@ term_gettty({buf} [, {input}]) *term_gettty()*
Can also be used as a |method|: >
GetBufnr()->term_gettty()
+<
+ Return type: |String|
term_list() *term_list()*
Return a list with the buffer numbers of all buffers for
terminal windows.
+ Return type: list<number> or list<any>
+
term_scrape({buf}, {row}) *term_scrape()*
Get the contents of {row} of terminal screen of {buf}.
@@ -744,6 +777,8 @@ term_scrape({buf}, {row}) *term_scrape()*
Can also be used as a |method|: >
GetBufnr()->term_scrape(row)
+<
+ Return type: list<dict<any>> or list<any>
term_sendkeys({buf}, {keys}) *term_sendkeys()*
@@ -755,6 +790,8 @@ term_sendkeys({buf}, {keys}) *term_sendkeys()*
Can also be used as a |method|: >
GetBufnr()->term_sendkeys(keys)
+<
+ Return type: |Number|
term_setansicolors({buf}, {colors}) *term_setansicolors()*
@@ -788,8 +825,10 @@ term_setansicolors({buf}, {colors}) *term_setansicolors()*
Can also be used as a |method|: >
GetBufnr()->term_setansicolors(colors)
+<
+ Return type: |Number|
-< {only available with GUI enabled and/or the |+termguicolors|
+ {only available with GUI enabled and/or the |+termguicolors|
feature}
@@ -804,6 +843,8 @@ term_setapi({buf}, {expr}) *term_setapi()*
When used as a method the base is used for {buf}: >
GetBufnr()->term_setapi({expr})
+<
+ Return type: |Number|
term_setkill({buf}, {how}) *term_setkill()*
@@ -820,6 +861,8 @@ term_setkill({buf}, {how}) *term_setkill()*
Can also be used as a |method|: >
GetBufnr()->term_setkill(how)
+<
+ Return type: |Number|
term_setrestore({buf}, {command}) *term_setrestore()*
@@ -833,6 +876,8 @@ term_setrestore({buf}, {command}) *term_setrestore()*
Can also be used as a |method|: >
GetBufnr()->term_setrestore(command)
+<
+ Return type: |Number|
term_setsize({buf}, {rows}, {cols}) *term_setsize()* *E955*
@@ -847,6 +892,8 @@ term_setsize({buf}, {rows}, {cols}) *term_setsize()* *E955*
Can also be used as a |method|: >
GetBufnr()->term_setsize(rows, cols)
+<
+ Return type: |Number|
term_start({cmd} [, {options}]) *term_start()*
@@ -922,6 +969,8 @@ term_start({cmd} [, {options}]) *term_start()*
Can also be used as a |method|: >
GetCommand()->term_start()
+<
+ Return type: |Number|
term_wait({buf} [, {time}]) *term_wait()*
@@ -932,6 +981,8 @@ term_wait({buf} [, {time}]) *term_wait()*
Can also be used as a |method|: >
GetBufnr()->term_wait()
+<
+ Return type: |Number|
==============================================================================
3. Terminal communication *terminal-communication*
diff --git a/runtime/doc/test_urls.vim b/runtime/doc/test_urls.vim
index e23f879..b75dc29 100644
--- a/runtime/doc/test_urls.vim
+++ b/runtime/doc/test_urls.vim
@@ -12,11 +12,11 @@ func Test_check_URLs()
else
let s:outdev = '/dev/null'
endif
-" Restorer: For Windows users. If "curl" or "weget" is installed on the system
-" but not in %PATH%, add the full routes for them to this environment variable.
+" Restorer: For Windows users. If "curl" or "wget" is installed on the system
+" but not in %PATH%, add the full path to them to %PATH% environment variable.
if executable('curl')
" Note: does not follow redirects!
- let s:command1 = 'curl --silent --fail --output ' ..s:outdev.. ' --head '
+ let s:command1 = 'curl --silent --max-time 5 --fail --output ' ..s:outdev.. ' --head '
let s:command2 = ""
elseif executable('wget')
" Note: only allow a couple of redirects
diff --git a/runtime/doc/testing.txt b/runtime/doc/testing.txt
index 9b9f60b..ebf562b 100644
--- a/runtime/doc/testing.txt
+++ b/runtime/doc/testing.txt
@@ -1,4 +1,4 @@
-*testing.txt* For Vim version 9.1. Last change: 2024 Apr 07
+*testing.txt* For Vim version 9.1. Last change: 2024 Jun 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -45,12 +45,16 @@ test_alloc_fail({id}, {countdown}, {repeat}) *test_alloc_fail()*
Can also be used as a |method|: >
GetAllocId()->test_alloc_fail()
+<
+ Return type: |Number|
test_autochdir() *test_autochdir()*
Set a flag to enable the effect of 'autochdir' before Vim
startup has finished.
+ Return type: |Number|
+
test_feedinput({string}) *test_feedinput()*
Characters in {string} are queued for processing as if they
@@ -59,6 +63,8 @@ test_feedinput({string}) *test_feedinput()*
Can also be used as a |method|: >
GetText()->test_feedinput()
+<
+ Return type: |Number|
test_garbagecollect_now() *test_garbagecollect_now()*
@@ -69,11 +75,13 @@ test_garbagecollect_now() *test_garbagecollect_now()*
This will not work when called from a :def function, because
variables on the stack will be freed.
+ Return type: |Number|
test_garbagecollect_soon() *test_garbagecollect_soon()*
Set the flag to call the garbagecollector as if in the main
loop. Only to be used in tests.
+ Return type: |Number|
test_getvalue({name}) *test_getvalue()*
Get the value of an internal variable. These values for
@@ -83,6 +91,8 @@ test_getvalue({name}) *test_getvalue()*
Can also be used as a |method|: >
GetName()->test_getvalue()
<
+ Return type: |Number|
+
*test_gui_event()*
test_gui_event({event}, {args})
Generate a GUI {event} with arguments {args} for testing Vim
@@ -212,6 +222,8 @@ test_gui_event({event}, {args})
Can also be used as a |method|: >
GetEvent()->test_gui_event({args})
<
+ Return type: |vim9-boolean|
+
test_ignore_error({expr}) *test_ignore_error()*
Ignore any error containing {expr}. A normal message is given
instead.
@@ -224,7 +236,8 @@ test_ignore_error({expr}) *test_ignore_error()*
Can also be used as a |method|: >
GetErrorText()->test_ignore_error()
-
+<
+ Return type: |Number|
test_mswin_event({event}, {args}) *test_mswin_event()*
Generate a low-level MS-Windows {event} with arguments {args}
@@ -307,40 +320,49 @@ test_mswin_event({event}, {args}) *test_mswin_event()*
Can also be used as a |method|: >
GetEvent()->test_mswin_event({args})
<
+ Return type: |vim9-boolean|
test_null_blob() *test_null_blob()*
Return a |Blob| that is null. Only useful for testing.
+ Return type: |Blob|
test_null_channel() *test_null_channel()*
Return a |Channel| that is null. Only useful for testing.
{only available when compiled with the +channel feature}
+ Return type: |Channel|
test_null_dict() *test_null_dict()*
Return a |Dict| that is null. Only useful for testing.
+ Return type: dict<any>
test_null_function() *test_null_function()*
Return a |Funcref| that is null. Only useful for testing.
+ Return type: func(...): unknown
test_null_job() *test_null_job()*
Return a |Job| that is null. Only useful for testing.
{only available when compiled with the +job feature}
+ Return type: |job|
test_null_list() *test_null_list()*
Return a |List| that is null. Only useful for testing.
+ Return type: list<any>
test_null_partial() *test_null_partial()*
Return a |Partial| that is null. Only useful for testing.
+ Return type: func(...): unknown
test_null_string() *test_null_string()*
Return a |String| that is null. Only useful for testing.
+ Return type: |String|
test_option_not_set({name}) *test_option_not_set()*
Reset the flag that indicates option {name} was set. Thus it
@@ -353,7 +375,8 @@ test_option_not_set({name}) *test_option_not_set()*
Can also be used as a |method|: >
GetOptionName()->test_option_not_set()
-
+<
+ Return type: |Number|
test_override({name}, {val}) *test_override()*
Overrides certain parts of Vim's internal processing to be able
@@ -365,29 +388,32 @@ test_override({name}, {val}) *test_override()*
{name} effect when {val} is non-zero ~
alloc_lines make a copy of every buffer line into allocated
memory, so that memory access errors can be found
- by valgrind
+ by valgrind.
autoload `import autoload` will load the script right
- away, not postponed until an item is used
- char_avail disable the char_avail() function
+ away, not postponed until an item is used.
+ char_avail disable the char_avail() function.
+ defcompile all the |:def| functions in a sourced script are
+ compiled when defined. This is similar to using
+ the |:defcompile| command in a script.
nfa_fail makes the NFA regexp engine fail to force a
- fallback to the old engine
+ fallback to the old engine.
no_query_mouse do not query the mouse position for "dec"
- terminals
+ terminals.
no_wait_return set the "no_wait_return" flag. Not restored
with "ALL".
- redraw disable the redrawing() function
- redraw_flag ignore the RedrawingDisabled flag
- starting reset the "starting" variable, see below
+ redraw disable the redrawing() function.
+ redraw_flag ignore the RedrawingDisabled flag.
+ starting reset the "starting" variable, see below.
term_props reset all terminal properties when the version
- string is detected
+ string is detected.
ui_delay time in msec to use in ui_delay(); overrules a
- wait time of up to 3 seconds for messages
- unreachable no error for code after `:throw` and `:return`
- uptime overrules sysinfo.uptime
+ wait time of up to 3 seconds for messages.
+ unreachable no error for code after `:throw` and `:return`.
+ uptime overrules sysinfo.uptime.
vterm_title setting the window title by a job running in a
- terminal window
+ terminal window.
ALL clear all overrides, except alloc_lines ({val} is
- not used)
+ not used).
"starting" is to be used when a test should behave like
startup was done. Since the tests are run by sourcing a
@@ -406,7 +432,8 @@ test_override({name}, {val}) *test_override()*
< Can also be used as a |method|: >
GetOverrideVal()-> test_override('starting')
-
+<
+ Return type: |Number|
test_refcount({expr}) *test_refcount()*
Return the reference count of {expr}. When {expr} is of a
@@ -415,7 +442,8 @@ test_refcount({expr}) *test_refcount()*
Can also be used as a |method|: >
GetVarname()->test_refcount()
-
+<
+ Return type: |Number|
test_setmouse({row}, {col}) *test_setmouse()*
Set the mouse position to be used for the next mouse action.
@@ -423,6 +451,8 @@ test_setmouse({row}, {col}) *test_setmouse()*
For example: >
call test_setmouse(4, 20)
call feedkeys("\<LeftMouse>", "xt")
+<
+ Return type: |Number|
test_settime({expr}) *test_settime()*
@@ -436,20 +466,25 @@ test_settime({expr}) *test_settime()*
Can also be used as a |method|: >
GetTime()->test_settime()
-
+<
+ Return type: |Number|
test_srand_seed([{seed}]) *test_srand_seed()*
When {seed} is given this sets the seed value used by
`srand()`. When omitted the test seed is removed.
+ Return type: |Number|
test_unknown() *test_unknown()*
Return a value with unknown type. Only useful for testing.
+ Return type: unknown
test_void() *test_void()*
Return a value with void type. Only useful for testing.
+ Return type: void
+
==============================================================================
3. Assert functions *assert-functions-details*
@@ -463,6 +498,8 @@ assert_beeps({cmd}) *assert_beeps()*
Can also be used as a |method|: >
GetCmd()->assert_beeps()
<
+ Return type: |Number|
+
*assert_equal()*
assert_equal({expected}, {actual} [, {msg}])
When {expected} and {actual} are not equal an error message is
@@ -483,8 +520,10 @@ assert_equal({expected}, {actual} [, {msg}])
Can also be used as a |method|, the base is passed as the
second argument: >
mylist->assert_equal([1, 2, 3])
+<
+ Return type: |Number|
-< *assert_equalfile()*
+ *assert_equalfile()*
assert_equalfile({fname-one}, {fname-two} [, {msg}])
When the files {fname-one} and {fname-two} do not contain
exactly the same text an error message is added to |v:errors|.
@@ -495,6 +534,8 @@ assert_equalfile({fname-one}, {fname-two} [, {msg}])
Can also be used as a |method|: >
GetLog()->assert_equalfile('expected.log')
+<
+ Return type: |Number|
assert_exception({error} [, {msg}]) *assert_exception()*
When v:exception does not contain the string {error} an error
@@ -509,6 +550,8 @@ assert_exception({error} [, {msg}]) *assert_exception()*
call assert_exception('E492:')
endtry
<
+ Return type: |Number|
+
*assert_fails()*
assert_fails({cmd} [, {error} [, {msg} [, {lnum} [, {context}]]]])
Run {cmd} and add an error message to |v:errors| if it does
@@ -549,6 +592,8 @@ assert_fails({cmd} [, {error} [, {msg} [, {lnum} [, {context}]]]])
Can also be used as a |method|: >
GetCmd()->assert_fails('E99:')
+<
+ Return type: |Number|
assert_false({actual} [, {msg}]) *assert_false()*
When {actual} is not false an error message is added to
@@ -562,6 +607,8 @@ assert_false({actual} [, {msg}]) *assert_false()*
Can also be used as a |method|: >
GetResult()->assert_false()
+<
+ Return type: |Number|
assert_inrange({lower}, {upper}, {actual} [, {msg}]) *assert_inrange()*
This asserts number and |Float| values. When {actual} is lower
@@ -571,6 +618,8 @@ assert_inrange({lower}, {upper}, {actual} [, {msg}]) *assert_inrange()*
but got {actual}". When {msg} is present it is prefixed to
that.
+ Return type: |Number|
+
*assert_match()*
assert_match({pattern}, {actual} [, {msg}])
When {pattern} does not match {actual} an error message is
@@ -594,6 +643,8 @@ assert_match({pattern}, {actual} [, {msg}])
Can also be used as a |method|: >
getFile()->assert_match('foo.*')
<
+ Return type: |Number|
+
assert_nobeep({cmd}) *assert_nobeep()*
Run {cmd} and add an error message to |v:errors| if it
produces a beep or visual bell.
@@ -602,6 +653,8 @@ assert_nobeep({cmd}) *assert_nobeep()*
Can also be used as a |method|: >
GetCmd()->assert_nobeep()
<
+ Return type: |Number|
+
*assert_notequal()*
assert_notequal({expected}, {actual} [, {msg}])
The opposite of `assert_equal()`: add an error message to
@@ -610,8 +663,10 @@ assert_notequal({expected}, {actual} [, {msg}])
Can also be used as a |method|: >
mylist->assert_notequal([1, 2, 3])
+<
+ Return type: |Number|
-< *assert_notmatch()*
+ *assert_notmatch()*
assert_notmatch({pattern}, {actual} [, {msg}])
The opposite of `assert_match()`: add an error message to
|v:errors| when {pattern} matches {actual}.
@@ -619,7 +674,8 @@ assert_notmatch({pattern}, {actual} [, {msg}])
Can also be used as a |method|: >
getFile()->assert_notmatch('bar.*')
-
+<
+ Return type: |Number|
assert_report({msg}) *assert_report()*
Report a test failure directly, using String {msg}.
@@ -627,6 +683,8 @@ assert_report({msg}) *assert_report()*
Can also be used as a |method|: >
GetMessage()->assert_report()
+<
+ Return type: |Number|
assert_true({actual} [, {msg}]) *assert_true()*
@@ -640,5 +698,7 @@ assert_true({actual} [, {msg}]) *assert_true()*
Can also be used as a |method|: >
GetResult()->assert_true()
<
+ Return type: |Number|
+
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/textprop.txt b/runtime/doc/textprop.txt
index bf7fd16..6b46e06 100644
--- a/runtime/doc/textprop.txt
+++ b/runtime/doc/textprop.txt
@@ -1,4 +1,4 @@
-*textprop.txt* For Vim version 9.1. Last change: 2023 Apr 23
+*textprop.txt* For Vim version 9.1. Last change: 2024 Jun 08
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -118,6 +118,8 @@ prop_list({lnum} [, {props}]) text properties in {lnum}
prop_remove({props} [, {lnum} [, {lnum-end}]])
remove a text property
+ *text-prop-functions-details*
+
*prop_add()* *E965*
prop_add({lnum}, {col}, {props})
Attach a text property at position {lnum}, {col}. {col} is
@@ -234,8 +236,10 @@ prop_add({lnum}, {col}, {props})
Can also be used as a |method|: >
GetLnum()->prop_add(col, props)
<
- *prop_add_list()*
-prop_add_list({props}, [{item}, ...])
+ Return type: |Number|
+
+
+prop_add_list({props}, [{item}, ...]) *prop_add_list()*
Similar to prop_add(), but attaches a text property at
multiple positions in a buffer.
@@ -284,8 +288,10 @@ prop_clear({lnum} [, {lnum-end} [, {props}]]) *prop_clear()*
Can also be used as a |method|: >
GetLnum()->prop_clear()
<
- *prop_find()*
-prop_find({props} [, {direction}])
+ Return type: |Number|
+
+
+prop_find({props} [, {direction}]) *prop_find()*
Search for a text property as specified with {props}:
id property with this ID
type property with this type name
@@ -310,6 +316,8 @@ prop_find({props} [, {direction}])
as with prop_list(), and additionally an "lnum" entry.
If no match is found then an empty Dict is returned.
+ Return type: dict<any>
+
prop_list({lnum} [, {props}]) *prop_list()*
Returns a List with all the text properties in line {lnum}.
@@ -380,6 +388,8 @@ prop_list({lnum} [, {props}]) *prop_list()*
Can also be used as a |method|: >
GetLnum()->prop_list()
<
+ Return type: list<dict<any>> or list<any>
+
*prop_remove()* *E968* *E860*
prop_remove({props} [, {lnum} [, {lnum-end}]])
Remove a matching text property from line {lnum}. When
@@ -409,6 +419,8 @@ prop_remove({props} [, {lnum} [, {lnum-end}]])
Can also be used as a |method|: >
GetProps()->prop_remove()
+<
+ Return type: |Number|
prop_type_add({name}, {props}) *prop_type_add()* *E969* *E970*
@@ -436,6 +448,9 @@ prop_type_add({name}, {props}) *prop_type_add()* *E969* *E970*
Can also be used as a |method|: >
GetPropName()->prop_type_add(props)
+<
+ Return type: |Number|
+
prop_type_change({name}, {props}) *prop_type_change()*
Change properties of an existing text property type. If a
@@ -444,6 +459,9 @@ prop_type_change({name}, {props}) *prop_type_change()*
Can also be used as a |method|: >
GetPropName()->prop_type_change(props)
+<
+ Return type: |Number|
+
prop_type_delete({name} [, {props}]) *prop_type_delete()*
Remove the text property type {name}. When text properties
@@ -458,6 +476,9 @@ prop_type_delete({name} [, {props}]) *prop_type_delete()*
Can also be used as a |method|: >
GetPropName()->prop_type_delete()
+<
+ Return type: |Number|
+
prop_type_get({name} [, {props}]) *prop_type_get()*
Returns the properties of property type {name}. This is a
@@ -471,6 +492,9 @@ prop_type_get({name} [, {props}]) *prop_type_get()*
Can also be used as a |method|: >
GetPropName()->prop_type_get()
+<
+ Return type: dict<any>
+
prop_type_list([{props}]) *prop_type_list()*
Returns a list with all property type names.
@@ -478,6 +502,8 @@ prop_type_list([{props}]) *prop_type_list()*
{props} can contain a "bufnr" item. When it is given, use
this buffer instead of the global property types.
+ Return type: list<string> or list<any>
+
==============================================================================
3. When text changes *text-prop-changes*
@@ -504,7 +530,7 @@ callback update spelling mistakes in the changed text. Vim will move the
properties below the changed text, so that they still highlight the same text,
thus you don't need to update these.
-
+ *text-prop-cleared*
Text property columns are not updated or copied: ~
- When setting the line with |setline()| or through an interface, such as Lua,
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 8712008..c37a1d4 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt* For Vim version 9.1. Last change: 2024 Mar 28
+*todo.txt* For Vim version 9.1. Last change: 2024 Jun 03
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -82,8 +82,6 @@ With 'smoothscroll' set and "lastline" in 'display', moving the cursor to a
wrapping line that makes the display scroll up may scroll much more than
needed, thus jump-scrolling. (part of issue 12411)
-Add filecopy() ? #12346
-
Implement foreach() PR #12166
Errors when running tests with valgrind:
@@ -1710,7 +1708,8 @@ Also Vundle: https://github.com/gmarik/vundle
Or minpac: https://github.com/k-takata/minpac, since it leverages the builtin
package feature.
Long message about this from ZyX, 2014 Mar 23. And following replies.
-Also see http://vim-wiki.mawercer.de/wiki/topic/vim%20plugin%20managment.html
+Also see (link seems dead):
+http://vim-wiki.mawercer.de/wiki/topic/vim%20plugin%20managment.html
User view:
- Support multiple sources, basically any http:// URL. Or a central place that
will work for everybody (github? redirects from vim.org?).
@@ -2441,7 +2440,7 @@ Problem with 'ts' set to 9 and 'showbreak' to ">>>". (Matthew Winn, 2007 Oct
Would be more consistent when an existing tab is re-used. (Tony Mechelynck)
Using Aap to build Vim: add remarks about how to set personal preferences.
-Example on http://www.calmar.ws/tmp/aap.html
+Example on http://www.calmar.ws/tmp/aap.html (link seems dead)
When 'diffopt' has "context:0" a single deleted line causes two folds to merge
and mess up syncing. (Austin Jennings, 2008 Jan 31)
@@ -2472,7 +2471,7 @@ Asked about latest version: 0.77.1 is on www.vim.org.
More AmigaOS4 patches. (Peter Bengtsson, Nov 9)
Amiga patches with vbcc. (Adrien Destugues, 2010 Aug 30)
-http://pulkomandy.ath.cx/drop/vim73_vbcc_amiga.diff
+(link seems dead): http://pulkomandy.ath.cx/drop/vim73_vbcc_amiga.diff
Problem with compound words? (Bert, 2008 May 6)
No warning for when flags are defined after they are used in an affix.
@@ -2542,8 +2541,9 @@ Win32: Patch for cscope external command. (Mike Williams, 2007 Aug 7)
Win32: XPM support only works with path without spaces. Patch by Mathias
Michaelis, 2006 Jun 9. Another patch for more path names, 2006 May 31.
-New version: http://members.tcnet.ch/michaelis/vim/patches.zip (also for other
-patches by Mathias, see mail Feb 22)
+New version (link seems dead):
+http://members.tcnet.ch/michaelis/vim/patches.zip
+(also for other patches by Mathias, see mail Feb 22)
Win32: compiling with normal features and OLE fails. Patch by Mathias
Michaelis, 2006 Jun 4.
@@ -3068,7 +3068,7 @@ Win32 GUI known bugs:
the screen.
8 The -P argument doesn't work very well with many MDI applications.
The last argument of CreateWindowEx() should be used, see MSDN docs.
- Tutorial: http://win32assembly.online.fr/tut32.html
+ Tutorial (link seems dead): http://win32assembly.online.fr/tut32.html
6 Win32 GUI: With "-u NONE -U NONE" and doing "CTRL-W v" "CTRL-W o", the ":"
of ":only" is highlighted like the cursor. (Lipelis)
8 When 'encoding' is "utf-8", should use 'guifont' for both normal and wide
@@ -3470,7 +3470,7 @@ Macintosh:
way to avoid using the builtin termcap.
8 Xterm sends ^[[H for <Home> and ^[[F for <End> in some mode. Also
recognize these keys? Mostly useful for xterm simulators, like gnometerm.
- See http://dickey.his.com/xterm/xterm.faq.html#xterm_pc_style.
+ See https://invisible-island.net/xterm/xterm.faq.html#xterm_pc_style
8 '[ and '] should be set to start/end of line when using a linewise operator
(e.g., ":w").
8 CTRL-A can't handle big "long" numbers, they become negative. Check for
@@ -3759,8 +3759,8 @@ Spell checking:
What does MAXNGRAMSUGS do?
Is COMPLEXPREFIXES necessary when we have flags for affixes?
- There is no Finnish spell checking file. For openoffice Voikko is now
- used, which is based on Malaga: http://home.arcor.de/bjoern-beutel/malaga/
- (Teemu Likonen)
+ used, which is based on Malaga (link seems dead):
+ http://home.arcor.de/bjoern-beutel/malaga/ (Teemu Likonen)
8 ":mkspell" still takes much too long in Hungarian dictionary from
hunspell. Only solution appears to be to postpone secondary suffixes.
8 Handle postponed prefix with COMPOUNDPERMITFLAG or COMPOUNDFORBIDFLAG.
@@ -3816,7 +3816,7 @@ Spell checking:
syntax items (to add @Spell).
Add ":syntax contains {pattern} add=@Spell" command? A bit like ":syn
cluster" but change the contains list directly for matching syntax items.
-- References: MySpell library (in OpenOffice.org).
+- References: MySpell library (in OpenOffice.org), (links seem dead):
http://spellchecker.mozdev.org/source.html
http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
author: Kevin Hendricks <kevin.hendricks@sympatico.ca>
@@ -3974,8 +3974,9 @@ Multi-byte characters:
could be entered. E.g., for "f" command. But not in Normal mode. Sort
of opposite of 'langmap'. Use ":amap" command?
- When breaking a line, take properties of multibyte characters into
- account. The "linebreak" program from Bruno Haible can do it:
- ftp://ftp.ilog.fr/pub/Users/haible/gnu/linebreak-0.1.tar.gz
+ account. The "linebreak" program from Bruno Haible can do it, this
+ is now part of gnulib module unilbrk:
+ https://www.gnu.org/software/gnulib/MODULES.html
But it's very complicated...
- Problem with 'langmap' being used on the rhs of a mapping. (Nikolai
Weibull, 2008 May 14).
@@ -4239,7 +4240,6 @@ Vim script language:
base64enc() base 64 encoding
base64dec() base 64 decoding
attributes() return file protection flags "drwxrwxrwx"
- filecopy(from, to) Copy a file
shorten(fname) shorten a file name, like home_replace()
perl(cmd) call Perl and return string
inputrl() like input() but right-to-left
@@ -4399,7 +4399,6 @@ Code size:
left out.
8 When compiled with a GUI-only version, the termcap entries for terminals
can be removed.
-8 Can the check for libelf in configure.ac be removed?
Messages:
@@ -4773,10 +4772,10 @@ Omni completion:
ctags -f $allTagsFile --fields=+aiKmnsSz --language-force=C++ --C++-kinds=+cefgmnpsut-dlux -u $files
www.vim.org script 1213 (Java Development Environment) (Fuchuan Wang)
IComplete: http://www.vim.org/scripts/script.php?script_id=1265
- and http://stud4.tuwien.ac.at/~e0125672/icomplete/
http://cedet.sourceforge.net/intellisense.shtml (for Emacs)
Ivan Villanueva has something for Java.
- Emacs: http://www.xref-tech.com/xrefactory/more_c_completion.html
+ Emacs (link seems dead):
+ http://www.xref-tech.com/xrefactory/more_c_completion.html
Completion in .NET framework SharpDevelop: http://www.icsharpcode.net
- Pre-expand abbreviations, show which abbrevs would match?
diff --git a/runtime/doc/usr_01.txt b/runtime/doc/usr_01.txt
index fafb242..fdf1b53 100644
--- a/runtime/doc/usr_01.txt
+++ b/runtime/doc/usr_01.txt
@@ -1,4 +1,4 @@
-*usr_01.txt* For Vim version 9.1. Last change: 2023 May 12
+*usr_01.txt* For Vim version 9.1. Last change: 2024 May 11
VIM USER MANUAL - by Bram Moolenaar
@@ -165,7 +165,7 @@ The Vim user manual and reference manual are Copyright (c) 1988 by Bram
Moolenaar. This material may be distributed only subject to the terms and
conditions set forth in the Open Publication License, v1.0 or later. The
latest version is presently available at:
- http://www.opencontent.org/openpub/
+ https://opencontent.org/openpub/
People who contribute to the manuals must agree with the above copyright
notice.
diff --git a/runtime/doc/usr_05.txt b/runtime/doc/usr_05.txt
index 063af9b..a9e8fb9 100644
--- a/runtime/doc/usr_05.txt
+++ b/runtime/doc/usr_05.txt
@@ -1,4 +1,4 @@
-*usr_05.txt* For Vim version 9.1. Last change: 2024 Apr 26
+*usr_05.txt* For Vim version 9.1. Last change: 2024 May 17
VIM USER MANUAL - by Bram Moolenaar
@@ -445,7 +445,8 @@ Load the plugin with this command: >
This way you can use the plugin with the default key bindings `gc` and similar
for commenting (which is a well-established mapping in the Vim community).
-After restarting your Vim, the plugin is active and you can read about it at: >
+If you add this line to your vimrc file, then you need to restart Vim to have
+the package loaded. Once the package is loaded, read about it at: >
:h comment.txt
More information about packages can be found here: |packages|.
diff --git a/runtime/doc/usr_21.txt b/runtime/doc/usr_21.txt
index 95ded58..fe3ee31 100644
--- a/runtime/doc/usr_21.txt
+++ b/runtime/doc/usr_21.txt
@@ -1,4 +1,4 @@
-*usr_21.txt* For Vim version 9.1. Last change: 2019 Apr 25
+*usr_21.txt* For Vim version 9.1. Last change: 2024 May 17
VIM USER MANUAL - by Bram Moolenaar
@@ -207,6 +207,23 @@ You get the same list of files as with |:oldfiles|. If you want to edit
Type "2" and press <Enter> to edit the second file.
+If you know that the filename contains a pattern, you can also |:filter| the
+list of files: >
+
+ :filter /resume/ :browse oldfiles
+<
+Since there is only one single matching filename, Vim will directly edit that
+file without prompting. If the filter matches several files, you'll get
+prompted for the list of matching files instead: >
+
+ :filter! /resume/ browse oldfiles
+< 1: ~/.viminfo ~
+ 3: /tmp/draft ~
+ Type number and <Enter> (q or empty cancels): ~
+
+Note: this time we filtered out all files NOT matching resume.
+
+
More info at |:oldfiles|, |v:oldfiles| and |c_#<|.
diff --git a/runtime/doc/usr_30.txt b/runtime/doc/usr_30.txt
index 19a1259..c3bbcba 100644
--- a/runtime/doc/usr_30.txt
+++ b/runtime/doc/usr_30.txt
@@ -1,4 +1,4 @@
-*usr_30.txt* For Vim version 9.1. Last change: 2007 Nov 10
+*usr_30.txt* For Vim version 9.1. Last change: 2024 Apr 29
VIM USER MANUAL - by Bram Moolenaar
@@ -246,7 +246,7 @@ code block the cursor is in: >
=a{
-I you have really badly indented code, you can re-indent the whole file with:
+If you have really badly indented code, you can re-indent the whole file with:
>
gg=G
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 6137cfd..60d0d1e 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1,4 +1,4 @@
-*usr_41.txt* For Vim version 9.1. Last change: 2024 Apr 26
+*usr_41.txt* For Vim version 9.1. Last change: 2024 Jun 09
VIM USER MANUAL - by Bram Moolenaar
@@ -29,6 +29,22 @@ Table of contents: |usr_toc.txt|
==============================================================================
*41.1* Introduction *vim-script-intro* *script*
+Let's start with some nomenclature. A Vim script is any file that Vim can
+interpret and execute. This includes files written in Vim's scripting language
+like for example .vim files or configuration files like .vimrc and .gvimrc.
+These scripts may define functions, commands and settings that Vim uses to
+customize and extend its behavior.
+
+With a slight abuse of nomenclature, we will use "Vim script" to refer to the
+Vim scripting language throughout this documentation. This shorthand helps to
+streamline explanations and discussions about scripting with Vim.
+
+A Vim plugin is a collection of one or more Vim scripts, along with additional
+files like help documentation, configuration files, and other resources,
+designed to add specific features or functionalities to Vim. A plugin can
+provide new commands, enhance existing capabilities, and integrate external
+tools or services into the Vim environment.
+
Your first experience with Vim scripts is the vimrc file. Vim reads it when
it starts up and executes the commands. You can set options to the values you
prefer, define mappings, select plugins and much more. You can use any colon
@@ -930,6 +946,7 @@ Cursor and mark position: *cursor-functions* *mark-functions*
Working with text in the current buffer: *text-functions*
getline() get a line or list of lines from the buffer
getregion() get a region of text from the buffer
+ getregionpos() get a list of positions for a region
setline() replace a line in the buffer
append() append line or list of lines in the buffer
indent() indent of a specific line
@@ -992,6 +1009,7 @@ System functions and manipulation of files:
readdir() get a List of file names in a directory
readdirex() get a List of file information in a directory
writefile() write a List of lines or Blob into a file
+ filecopy() copy a file {from} to {to}
Date and Time: *date-functions* *time-functions*
getftime() get last modification time of a file
diff --git a/runtime/doc/usr_52.txt b/runtime/doc/usr_52.txt
index 222b899..d5062e2 100644
--- a/runtime/doc/usr_52.txt
+++ b/runtime/doc/usr_52.txt
@@ -1,4 +1,4 @@
-*usr_52.txt* For Vim version 9.1. Last change: 2022 Jun 04
+*usr_52.txt* For Vim version 9.1. Last change: 2024 Jun 09
VIM USER MANUAL - by Bram Moolenaar
@@ -13,6 +13,7 @@ smaller parts.
|52.3| Autoloading without import/export
|52.4| Other mechanisms to use
|52.5| Using a Vim9 script from legacy script
+|52.6| Vim9 script examples: comment package, highlight-yank plugin
Next chapter: |usr_90.txt| Installing Vim
Previous chapter: |usr_51.txt| Create a plugin
@@ -45,7 +46,7 @@ private function: >
def GetReply(nr: number): string
if nr == 42
return 'yes'
- elseif nr = 22
+ elseif nr == 22
return 'maybe'
else
return 'no'
@@ -155,7 +156,7 @@ AUTOLOAD DIRECTORY
Another form is to use autoload with a script name that is not an absolute or
relative path: >
- import autload "monthlib.vim"
+ import autoload "monthlib.vim"
This will search for the script "monthlib.vim" in the autoload directories of
'runtimepath'. With Unix one of the directories often is "~/.vim/autoload".
@@ -336,6 +337,46 @@ will have to make sure to use a unique name for these global items. Example: >
call g:NicePluginTest()
==============================================================================
+*52.6* Vim9 script examples: comment package, highlight-yank plugin
+
+COMMENT PACKAGE
+
+Vim comes with a comment plugin, written in Vim9 script. |comment-install|
+Have a look at the package located at $VIMRUNTIME/pack/dist/opt/comment/
+
+HIGHLIGHT YANK PLUGIN
+
+Here is an example for highlighting the yanked region. It makes use of the
+|getregionpos()| function, available since Vim 9.1.0446.
+
+Copy the following example into a new file and place it into your plugin directory
+and it will be active next time you start Vim. |add-plugin|: >
+
+ vim9script
+
+ def HighlightedYank(hlgroup = 'IncSearch', duration = 300, in_visual = true)
+ if v:event.operator ==? 'y'
+ if !in_visual && visualmode() != null_string
+ visualmode(1)
+ return
+ endif
+ var [beg, end] = [getpos("'["), getpos("']")]
+ var type = v:event.regtype ?? 'v'
+ var pos = getregionpos(beg, end, {type: type})
+ var end_offset = (type == 'V' || v:event.inclusive) ? 1 : 0
+ var m = matchaddpos(hlgroup, pos->mapnew((_, v) => {
+ var col_beg = v[0][2] + v[0][3]
+ var col_end = v[1][2] + v[1][3] + end_offset
+ return [v[0][1], col_beg, col_end - col_beg]
+ }))
+ var winid = win_getid()
+ timer_start(duration, (_) => m->matchdelete(winid))
+ endif
+ enddef
+
+ autocmd TextYankPost * HighlightedYank()
+<
+==============================================================================
Next chapter: |usr_90.txt| Installing Vim
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index 0aa5c74..1ce8927 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -1,4 +1,4 @@
-*various.txt* For Vim version 9.1. Last change: 2023 Sep 27
+*various.txt* For Vim version 9.1. Last change: 2024 Jun 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -138,12 +138,18 @@ g8 Print the hex values of the bytes used in the
:[range]# [count] [flags]
synonym for :number.
- *:#!*
+ *:#!* *vim-shebang*
:#!{anything} Ignored, so that you can start a Vim script with: >
#!vim -S
- echo "this is a Vim script"
- quit
+ let mylogbook='$HOME/logbook.md'
+ exe $':e {mylogbook}'
+ $
+ put ='## ' .. strftime('%d. %b %Y')
+ norm! o
<
+ Make that script executable and run it to create a
+ new diary entry.
+
*:z* *E144*
:[range]z[+-^.=][count] Display several lines of text surrounding the line
specified with [range], or around the current line
@@ -608,6 +614,7 @@ N *+X11* Unix only: can restore window title |X11|
|:command| - filter by command name
|:files| - filter by file name
|:highlight| - filter by highlight group
+ |:history| - filter by history commands
|:jumps| - filter by file name
|:let| - filter by variable name
|:list| - filter whole line
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 03050ee..5b5bded 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.1. Last change: 2024 Apr 26
+*version9.txt* For Vim version 9.1. Last change: 2024 Jun 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -31694,7 +31694,7 @@ The release 9.1 is dedicated to Vim's Benevolent dictator for life
This release has hundreds of bug fixes, there are a few new features and there
are many minor improvements.
-Vim9 classes
+Vim9 classes ~
------------
Support for classes and objects in a Vim9 script are added. This is described
in |vim9-class|. The following features are supported:
@@ -31711,12 +31711,12 @@ in |vim9-class|. The following features are supported:
Support for creating a type alias for an existing type is added.
-Virtual text
+Virtual text ~
------------
Support for adding |virtual-text| to a buffer is added. This is useful for
language server features (e.g. inlay hints)
-Smooth Scroll
+Smooth Scroll ~
-------------
Support for scrolling text using screen lines instead of file lines is added.
Refer to the 'smoothscroll' option.
@@ -31726,7 +31726,8 @@ The EditorConfig (|editorconfig-install|) and the JSON formatting
OpenVMS x86_64 platform port: http://www.polarhome.com/vim/
-Other improvements *new-other-9.1*
+ *new-other-9.1*
+Other improvements ~
------------------
- Support for undercurl (|t_Ce|), double underline (|t_Us|), dotted underline
(|t_ds|) and dashed underline (|t_Ds|) termcap entries and
@@ -31783,7 +31784,8 @@ Other improvements *new-other-9.1*
- xxd: reversing a bit dump (xxd -r).
- xxd: customize the variable name used in the C include output (xxd -n).
-Changed *changed-9.1*
+ *changed-9.1*
+Changed ~
-------
- The features |++builtin_terms|, |+cmdline_info|, |+cmdwin|, |+file_in_path|,
|+float|, |+path_extra|, |+textobjects|, |+wildignore| and |+wildmenu| are
@@ -31815,7 +31817,8 @@ Changed *changed-9.1*
- Migrate to autoconf 2.71.
- Start using C99 feature (declare variable in for loops).
-Added *added-9.1*
+ *added-9.1*
+Added ~
-----
Various syntax, indent and other plugins were added.
@@ -32090,7 +32093,7 @@ Solution: Store the text column when drawing text.
Patch 9.0.0049
Problem: Csv and tsv files are not recognized.
-Solution: Add patterns fo csv and tsv files. (Leandro Lourenci,
+Solution: Add patterns for csv and tsv files. (Leandro Lourenci,
closes #10680)
Patch 9.0.0050
@@ -40641,7 +40644,7 @@ Solution: Use the class-related grow array for storing the
Patch 9.0.1989
Problem: Vim9: double error message given
-Solution: Only give second error message, if ther
+Solution: Only give second error message, if there
wasn't one given before
Patch 9.0.1990
@@ -40687,7 +40690,7 @@ Solution: Mention the defining class for variable access error message
Patch 9.0.2000
Problem: Vim9: use-after-free in deep call stack
-Solution: Get the objct pointer from execution stack
+Solution: Get the object pointer from execution stack
Patch 9.0.2001
Problem: Vim9: segfault with islocked()
@@ -41541,39 +41544,48 @@ VERSION 9.2 *version-9.2* *version9.2* *vim-9.2*
This section is about improvements made between version 9.1 and 9.2
and is a work in progress.
-Support for Wayland UI.
-
-Support for the XDG Desktop Specification |xdg-base-dir|
-
-Vim9 script
+Vim9 script ~
-----------
Add support for internal builtin functions with vim9 objects, see
|builtin-object-methods|
Enum support for Vim9 script |:enum|
-Other improvements *new-other-9.2*
+ *new-other-9.2*
+Other new features ~
------------------
The comment plugin |comment-install| is included.
-Changed *changed-9.2*
--------
+Support for Wayland UI.
+
+Support for the XDG Desktop Specification |xdg-base-dir|
+Support highlighting the matched text for insert-mode completion and
+command-line completion in |ins-completion-menu|.
+
+ *changed-9.2*
+Changed~
+-------
- use 'smoothscroll' logic for CTRL-F and CTRL-B for pagewise scrolling
- use 'smoothscroll' logic for CTRL-D and CTRL-U for half-pagewise scrolling
+- the default for 'commentstring' contains whitespace padding to have
+ automatic comments look nicer |comment-install|
+- 'completeopt' is now a |global-local| option.
-Added *added-9.2*
+ *added-9.2*
+Added ~
-----
-
Various syntax, indent and other plugins were added.
Functions: ~
|diff()| diff two Lists of strings
+|filecopy()| copy a file {from} to {to}
|foreach()| apply function to List items
+|getregion()| get a region of text from a buffer
+|getregionpos()| get a list of positions for a region
|matchbufline()| all the matches of a pattern in a buffer
|matchstrlist()| all the matches of a pattern in a List of strings
-|getregion()| get a region of text from a buffer
Autocommands: ~
@@ -41586,39 +41598,45 @@ Autocommands: ~
Highlighting: ~
-|hl-MsgArea| highlighting of the Command-line and messages area.
+|hl-MsgArea| highlighting of the Command-line and messages area
+|hl-PmenuMatch| Popup menu: highlighting of matched text
+|hl-PmenuMatchSel| Popup menu: highlighting of matched text in selected
+ line
Commands: ~
+|[r| and |]r| to move the cursor to previous/next rare word
+
Options: ~
'winfixbuf' Keep buffer focused in a window
-'t_xo' Terminal uses XON/XOFF handshaking (e.g. vt420).
+'t_xo' Terminal uses XON/XOFF handshaking (e.g. vt420)
+'t_CF' Support for alternate font highlighting terminal code
==============================================================================
-INCOMPATIBLE CHANGES *incompatible-9.2*
+INCOMPATIBLE CHANGES *incompatible-9.2*
Improved/Different MS-Windows mapping support
|w32-experimental-keycode-trans-strategy|
==============================================================================
-IMPROVEMENTS *improvements-9.2*
+IMPROVEMENTS *improvements-9.2*
Support for command-line completion of 'keymap' option values.
Support for compiling all the methods in a Vim9 class using |:defcompile|.
-Support for alternate font highlighting using |t_CF| terminal code.
-
Support for Super key mappings in GTK using <D-Key>.
Improved visual highlighting.
Python3 support in OpenVMS.
+Support |fuzzy-matching| during |ins-completion| with "fuzzy" item for 'completeopt'
+
==============================================================================
-COMPILE TIME CHANGES *compile-changes-9.2*
+COMPILE TIME CHANGES *compile-changes-9.2*
Support for building with Ruby 3.3.
diff --git a/runtime/doc/vi_diff.txt b/runtime/doc/vi_diff.txt
index 1714833..3bcee47 100644
--- a/runtime/doc/vi_diff.txt
+++ b/runtime/doc/vi_diff.txt
@@ -1,4 +1,4 @@
-*vi_diff.txt* For Vim version 9.1. Last change: 2022 Apr 03
+*vi_diff.txt* For Vim version 9.1. Last change: 2024 May 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -49,7 +49,7 @@ printed.
autoprint (ap) boolean (default on) *'autoprint'* *'ap'*
beautify (bf) boolean (default off) *'beautify'* *'bf'*
-flash (fl) boolean (default ??) *'flash'* *'fl'*
+flash (fl) boolean (default on) *'flash'* *'fl'*
graphic (gr) boolean (default off) *'graphic'* *'gr'*
hardtabs (ht) number (default 8) *'hardtabs'* *'ht'*
number of spaces that a <Tab> moves on the display
diff --git a/runtime/doc/vim-it.1 b/runtime/doc/vim-it.1
index 8337ad9..7ecd9f4 100644
--- a/runtime/doc/vim-it.1
+++ b/runtime/doc/vim-it.1
@@ -1,4 +1,4 @@
-.TH VIM 1 "13 giugno 2022"
+.TH VIM 1 "4 giugno 2024"
.SH NOME
vim \- VI Migliorato, un editor di testi per programmatori
.SH SINTASSI
@@ -42,9 +42,9 @@ Vedere ":help vi_diff.txt" per un sommario delle differenze fra
.B Vim
e Vi.
.PP
-Mentre usate
+Mentre si usa
.B Vim
-potete ricevere molto aiuto dal sistema di help online, col comando
+si pu ricevere molto aiuto dal sistema di help online, col comando
":help".
Vedere qui sotto la sezione AIUTO ONLINE.
.PP
@@ -68,18 +68,18 @@ nome_file ..
Una lista di nomi di file.
Il primo di questi sar il file corrente, e verr letto nel buffer.
Il cursore sar posizionato sulla prima linea del buffer.
-Potete arrivare agli altri file col comando ":next".
+Si pu arrivare agli altri file col comando ":next".
Per editare un file il cui nome inizia per "\-" premettete "\-\-" alla lista_file.
.TP
\-
-Il file da editare letto dallo "stdin"-
-I comandi sono letti da "stderr", che dovrebbe essere un terminale [tty].
+Il file da editare letto dallo stdin.
+I comandi sono letti da stderr, che dovrebbe essere un terminale [tty].
.TP
\-t {tag}
Il file da editare e la posizione iniziale del cursore dipendono da "tag",
una specie di "etichetta" a cui saltare.
{tag} viene cercata nel file "tags", e il file a essa associato diventa
-quello corrente, ed il comando ad essa associato viene eseguito.
+quello corrente, e il comando a essa associato viene eseguito.
Di solito si usa per programmi C, nel qual caso {tag} potrebbe essere un
nome di funzione.
L'effetto che il file contenente quella funzione diventa il file corrente
@@ -97,10 +97,10 @@ Vedere ":help quickfix".
.PP
.B Vim
si comporta in modo diverso se invocato con nomi differenti (il programma
-eseguibile "sottostante" pu essere sempre lo stesso).
+eseguibile "soggiacente" pu essere sempre lo stesso).
.TP 10
vim
-Modo Normal, comportamento normale.
+Modo Normal, comportamento predefinito.
.TP
ex
Inizia in Modo "Ex".
@@ -108,7 +108,7 @@ Si pu passare in Modo Normal col comando ":vi".
Si pu invocare il Modo "Ex" anche con l'argomento "\-e".
.TP
view
-Inizia in Modo Read-only (Sola Lettura). Non potete modificare i file.
+Inizia in Modo Read-only (Sola Lettura). Non si possono modificare i file.
Si pu invocare il Modo Read-only anche con l'argomento "\-R".
.TP
gvim gview
@@ -131,11 +131,11 @@ Le opzioni possono essere in un ordine qualsiasi, prima o dopo i nomi di file.
Opzioni che non hanno un argomento si possono specificare dietro a un solo "\-".
.TP 12
+[numero]
-Per il primo file il cursore sar posizionato sulla linea "numero".
+Nel primo file il cursore sar posizionato sulla linea "numero".
Se "numero" manca, il cursore sar posizionato sull'ultima linea del file.
.TP
+/{espressione}
-Per il primo file il cursore sar posizionato alla
+Nel primo file il cursore sar posizionato alla
prima occorrenza di {espressione}.
Vedere ":help search\-pattern" per come specificare l'espressione.
.TP
@@ -166,7 +166,7 @@ Si possono usare fino a 10 di questi comandi, indipendentemente dai comandi "\-c
Se
.B Vim
stato compilato con supporto ARABIC per editare file con orientamento
-destra-sinistra e tastiera con mappatura araba, questa opzione inizia
+destra-sinistra e tastiera con mappatura araba, quest'opzione inizia
.B Vim
in Modo Arabic, cio impostando 'arabic'.
Altrimenti viene dato un messaggio di errore e
@@ -176,7 +176,7 @@ termina in modo anormale.
\-b
Modo Binary (binario).
Vengono impostate alcune opzioni che permettono di modificare un file
-binario o un programma eseguibile.
+binario o un file che contiene un programma eseguibile.
.TP
\-C
Compatibile. Imposta l'opzione 'compatible'.
@@ -186,12 +186,12 @@ ha quasi lo stesso comportamento di Vi, anche in presenza di un file .vimrc.
.TP
\-d
Inizia in Modo Diff [differenze].
-Dovrebbero esserci come argomenti due o tre o quattro nomi di file.
+Dovrebbero esserci come argomenti da due o otto nomi di file.
.B Vim
aprir tutti i file evidenziando le differenze fra gli stessi.
Funziona come vimdiff(1).
.TP
-\-d {dispositivo}
+\-d {dispositivo}, \-dev {dispositivo}
Apre {dispositivo} per usarlo come terminale.
Solo per l'Amiga.
Esempio:
@@ -221,7 +221,7 @@ non fatto ripartire per aprire una nuova finestra.
Opzione da usare quando
.B Vim
eseguito da un programma che attende la fine della
-sessione di edit (ad es. mail).
+sessione di edit (p.es., mail).
Sull'Amiga i comandi ":sh" e ":!" non sono disponibili.
.TP
\-\-nofork
@@ -233,7 +233,7 @@ non crea [fork] una nuova finestra, indipendente dalla shell di invocazione.
Se
.B Vim
stato compilato con supporto FKMAP per editare file con orientamento
-destra-sinistra e tastiera con mappatura Farsi, questa opzione inizia
+destra-sinistra e tastiera con mappatura Farsi, quest'opzione inizia
.B Vim
in Modo Farsi, cio impostando 'fkmap' e 'rightleft'.
Altrimenti viene dato un messaggio di errore e
@@ -243,12 +243,19 @@ termina in modo anormale.
\-g
Se
.B Vim
- stato compilato con supporto GUI, questa opzione chiede di usarla.
+ stato compilato con supporto GUI, quest'opzione chiede di usarla.
Se Vim stato compilato senza supporto GUI viene dato un messaggio di errore e
.B Vim
termina in modo anormale.
.TP
-\-h
+\-\-gui-dialog-file {nome}
+Quando si usa la GUI, invece di visualizzare un dialogo, il titolo e il
+messaggio del dialogo sono scritti sul file {nome}. Il file viene creato o,
+se gi esistente, viene esteso. Quest'opzione serve solo in fase di test,
+per evitare di restare bloccati da un dialogo che non si riesce a visualizzare.
+Se si sta lavorando senza la GUI l'argomento viene ignorato.
+.TP
+\-\-help, \-h, \-?
Un po' di aiuto su opzioni e argomenti che si possono dare invocando Vim.
Subito dopo
.B Vim
@@ -258,7 +265,7 @@ esce.
Se
.B Vim
stato compilato col supporto RIGHTLEFT per editare file con orientamento
-destra-sinistra e tastiera con mappatura Ebraica, questa opzione inizia
+destra-sinistra e tastiera con mappatura Ebraica, quest'opzione inizia
.B Vim
in Modo Ebraico, cio impostando 'hkmap' e 'rightleft'.
Altrimenti viene dato un messaggio di errore e
@@ -266,7 +273,7 @@ Altrimenti viene dato un messaggio di errore e
termina in modo anormale.
.TP
\-i {viminfo}
-Se abilitato l'uso di un file viminfo, questa opzione indica il nome
+Se abilitato l'uso di un file viminfo, quest'opzione indica il nome
del file da usare invece di quello predefinito "~/.viminfo".
Si pu anche evitare l'uso di un file .viminfo, dando come nome
"NONE".
@@ -292,13 +299,13 @@ opzioni possono essere abilitate in seguito, permettendo cos modifiche.
Modo "Non-compatibile". Annulla l'opzione 'compatible'.
Cos
.B Vim
-va un po' meglio, ma meno compatibile con Vi, anche in assenza di un
+si comporta un po' meglio, ma meno compatibile con Vi, anche in assenza di un
file .vimrc.
.TP
\-n
Inibisce l'uso di un file di swap.
Il recupero dopo una caduta di macchina diventa impossibile.
-Utile per editare un file su un supporto molto lento (ad es. floppy).
+Utile per editare un file su un supporto molto lento (p.es., floppy).
Il comando ":set uc=0" ha lo stesso effetto.
Per abilitare il recupero usare ":set uc=200".
.TP
@@ -306,16 +313,23 @@ Per abilitare il recupero usare ":set uc=200".
Diviene un Editor server per NetBeans. Vedere la documentazione per dettagli.
.TP
\-o[N]
-Apri N finestre in orizzontale.
-Se N manca, apri una finestra per ciascun file.
+Apre N finestre in orizzontale.
+Se N manca, apre una finestra per ciascun file.
.TP
\-O[N]
-Apri N finestre, in verticale.
-Se N manca, apri una finestra per ciascun file.
+Apre N finestre, in verticale.
+Se N manca, apre una finestra per ciascun file.
.TP
\-p[N]
-Apri N pagine di linguette.
-Quando N omesso, apri una pagine di linguette per ciascun file.
+Apre N pagine di linguette.
+Quando N omesso, apre una pagine di linguette per ciascun file.
+.TP
+\-P {titolo-padre}
+Solo per GUI Win32: Specifica il titolo dell'applicazione-padre. Se possibile,
+Vim viene eseguito in una finestra MDI (Multiple-Document Interface).
+{titolo-padre} deve apparire nel titolo della applicazione-padre. Accertatevi
+che sia sufficientemente esplicativo. Notare che l'implementazione ancora
+rudimentale. Non funziona per tutte le applicazioni, e il men non funziona.
.TP
\-R
Modo Read-only (Sola Lettura).
@@ -324,7 +338,7 @@ Si pu ancora modificare il buffer, ma il file protetto da una riscrittura
involontaria.
Se si vuole davvero riscrivere il file, occorre aggiungere un punto esclamativo
al comando Ex, come in ":w!".
-L'opzione \-R implica anche l'opzione \-n (vedere sotto).
+L'opzione \-R implica anche l'opzione \-n (vedere sopra).
L'opzione 'readonly' pu essere annullata con ":set noro".
Vedere ":help 'readonly'".
.TP
@@ -342,10 +356,10 @@ Vedere ":help recovery".
Modo silenzioso. Solo quando invocato come "Ex" o quando l'opzione
"\-e" stata data prima dell'opzione "\-s".
.TP
-\-s {scriptin}
-Lo script file {scriptin} letto.
+\-s {script_in_input}
+Lo script file {script_in_input} letto.
I caratteri nel file sono interpretati come se immessi da terminale.
-Lo stesso risultato si pu ottenere col comando ":source! {scriptin}".
+Lo stesso risultato si pu ottenere col comando ":source! {script_in_input}".
Se la fine del file di input viene raggiunta prima che Vim termini,
l'ulteriore input verr preso dalla tastiera.
.TP
@@ -356,12 +370,22 @@ quale tipo di terminale state usando.
Utile solo se il terminale non viene riconosciuto correttamente da Vim.
Dovrebbe essere un terminale noto a
.B Vim
-(internamente) o definito nei file termcap o terminfo.
+(predefinito) o definito nei file termcap o terminfo.
+.TP
+\-\-not-a-term
+Da usare per specifica a
+.B Vim
+che l'utente consapevole che l'input e l'output non avvengono con un terminale
+vero e proprio. Ci serve per evitare il messaggio di avvertimento e il ritardo
+di due secondi che avverrebbero in assenza di questo argomento.
+.TP
+\-\-ttyfail
+Quando stdin o stdout non sono un terminale (tty) esci subito da Vim.
.TP
\-u {vimrc}
Usa i comandi nel file {vimrc} per inizializzazioni.
Tutte le altre inizializzazioni non sono eseguite.
-Usate questa opzione per editare qualche file di tipo speciale.
+Usare quest'opzione per editare qualche file di tipo speciale.
Si possono anche omettere tutte le inizializzazioni dando come nome "NONE".
Vedere ":help initialization" da vim per ulteriori dettagli.
.TP
@@ -376,21 +400,37 @@ Verboso. Vim manda messaggi relativi ai file di script che esegue
e quando legge o scrive un file viminfo. Il numero opzionale N il valore
dell'opzione 'verbose'. Il valore predefinito 10.
.TP
+\-V[N]{nome_file}
+Comw \-V imposta 'verbosefile' a {nome_file}. Il risultato che i messaggi
+non sono visualizzati, ma scritti sul file {nome_file}. Il {nome_file} non
+deve iniziare con un numero.
+.TP
+\-\-log {nome_file}
+Se
+.B Vim
+ stato compilato con le funzionalit eval e channel, inizia a registrare
+e scrive le registrazioni a {nome_file}. Ci equivale a chiamare
+.I ch_logfile({nome_file}, 'ao')
+in una fase molto iniziale dell'avvio del programma.
+.TP
\-v
Inizia
.B Vim
in Modo Vi, come se il programma eseguibile fosse "vi". Questo ha
effetto solo quando Vim viene invocato con il nome "ex".
.TP
-\-w {scriptout}
-Ogni carattere immesso viene registrato nel file {scriptout},
+\-w{numero}
+Imposta l'opzione 'window' a {numero}.
+.TP
+\-w {script_file}
+Ogni carattere immesso viene registrato nel file {script_file},
finch non si esce da
.B Vim.
Utile se si vuole creare uno script file da usare con "vim \-s" o
":source!".
-Se il file {scriptout} esiste, quel che immettete viene aggiunto in fondo.
+Se il file {script_file} esiste, il testo immesso viene aggiunto in fondo.
.TP
-\-W {scriptout}
+\-W {script_file}
Come \-w, ma uno script file esistente viene sovrascritto.
.TP
\-x
@@ -421,10 +461,7 @@ Richiede di non usare alcun file di personalizzazione (vimrc, plugin, etc.).
Utile per verificare se un problema persiste invocando Vim "originale".
.TP
\-\-echo\-wid
-Solo per GUI GTK: Visualizza Window ID su "stdout".
-.TP
-\-\-help
-Vim d un messaggio ed esce, come con l'argomento "\-h".
+Solo per GUI GTK: Visualizza ID di Window su stdout.
.TP
\-\-literal
Considera i nomi passati come argomenti letterali, senza espandere metacaratteri.
@@ -439,7 +476,7 @@ argomenti. Se non si trova un server viene dato un messaggio e i file sono
editati nel Vim corrente.
.TP
\-\-remote\-expr {expr}
-Connettersi a un server Vim, valutare {expr} e stampare il risultato su "stdout".
+Connettersi a un server Vim, valutare {expr} e stampare il risultato su stdout.
.TP
\-\-remote\-send {chiavi}
Connettersi a un server Vim e spedirgli {chiavi}.
@@ -467,7 +504,11 @@ Solo per GUI GTK: Usa meccanismo GtkPlug per eseguire gvim in un'altra finestra.
Durante la fase iniziale, scrive messaggi di log al file {nome_file}.
.TP
\-\-version
-Stampa la versione di Vim ed esci.
+Stampa la versione di Vim ed esce.
+.TP
+\-\-windowid {id}
+Solo per GUI Win32: Chiede a gvim di provare a user l'ID di window {id}
+come padre, in modo da venir eseguito all'interno della finestra specificata.
.SH AIUTO ONLINE
Battere ":help" in
.B Vim
@@ -481,53 +522,57 @@ Tutti i file di documentazione possono essere navigati cos. Ad es.:
":help syntax.txt".
.SH FILE
.TP 15
-/usr/local/lib/vim/doc/*.txt
+/usr/local/share/vim/vim??/doc/*.txt
I file di documentazione di
.B Vim
.
Usare ":help doc\-file\-list" per avere la lista completa.
+.br
+.I vim??
+ il numero di versione corto, p.es., vim91 per indicare
+.B Vim 9.1
.TP
-/usr/local/lib/vim/doc/tags
+/usr/local/share/vim/vim??/doc/tags
Il file di tags usato per trovare informazioni nei file di documentazione.
.TP
-/usr/local/lib/vim/syntax/syntax.vim
+/usr/local/share/vim/vim??/syntax/syntax.vim
Inizializzazioni sintattiche a livello di sistema.
.TP
-/usr/local/lib/vim/syntax/*.vim
+/usr/local/share/vim/vim??/syntax/*.vim
File di colorazione sintattica per vari linguaggi.
.TP
-/usr/local/lib/vim/vimrc
+/usr/local/share/vim/vimrc
Inizializzazioni
.B Vim
a livello di sistema.
.TP
-~/.vimrc
+~/.vimrc, ~/.vim/vimrc, $XDG_CONFIG_HOME/vim/vimrc
Inizializzazioni personali di
.B Vim
-.
+(viene utilizzata la prima trovata).
.TP
-/usr/local/lib/vim/gvimrc
+/usr/local/share/vim/gvimrc
Inizializzazioni gvim a livello di sistema.
.TP
-~/.gvimrc
-Inizializzazioni personali di
+~/.gvimrc, ~/.vim/gvimrc, $XDG_CONFIG_HOME/vim/gvimrc
+Inizializzazioni personali di gvim (viene utilizzata la prima trovata).
.TP
-/usr/local/lib/vim/optwin.vim
-Script Vim usato dal comando ":options", da usare per visualizzare e impostare opzioni.
+/usr/local/share/vim/optwin.vim
+Script Vim usato dal comando ":options", maniera elegante per visualizzare e impostare opzioni.
.TP
-/usr/local/lib/vim/menu.vim
+/usr/local/share/vim/vim??/menu.vim
Inizializzazioni del men gvim a livello di sistema.
.TP
-/usr/local/lib/vim/bugreport.vim
+/usr/local/share/vim/vim??/bugreport.vim
Script Vim per generare una segnalazione di errore. Vedere ":help bugs".
.TP
-/usr/local/lib/vim/filetype.vim
+/usr/local/share/vim/vim??/filetype.vim
Script Vim per determinare il tipo di un file dal suo nome. Vedere ":help 'filetype'".
.TP
-/usr/local/lib/vim/scripts.vim
+/usr/local/share/vim/vim??/scripts.vim
Script Vim per determinare il tipo di un file dal suo contenuto. Vedere ":help 'filetype'".
.TP
-/usr/local/lib/vim/print/*.ps
+/usr/local/share/vim/vim??/print/*.ps
File usati per stampa PostScript.
.PP
Per informazioni aggiornate [in inglese \- NdT] vedere la home page di Vim:
@@ -546,8 +591,8 @@ Vedere ":help credits" in
basato su Stevie, scritto da: Tim Thompson,
Tony Andrews e G.R. (Fred) Walter.
In verit, poco o nulla rimasto del loro codice originale.
-.SH BACHI
-Probabili.
+.SH BUG
+Probabilmente.
Vedere ":help todo" per una lista di problemi noti.
.PP
Si noti che un certo numero di comportamenti che possono essere considerati errori
diff --git a/runtime/doc/vim-it.UTF-8.1 b/runtime/doc/vim-it.UTF-8.1
index 5931d4b..c9b5835 100644
--- a/runtime/doc/vim-it.UTF-8.1
+++ b/runtime/doc/vim-it.UTF-8.1
@@ -1,4 +1,4 @@
-.TH VIM 1 "13 giugno 2022"
+.TH VIM 1 "4 giugno 2024"
.SH NOME
vim \- VI Migliorato, un editor di testi per programmatori
.SH SINTASSI
@@ -42,9 +42,9 @@ Vedere ":help vi_diff.txt" per un sommario delle differenze fra
.B Vim
e Vi.
.PP
-Mentre usate
+Mentre si usa
.B Vim
-potete ricevere molto aiuto dal sistema di help online, col comando
+si può ricevere molto aiuto dal sistema di help online, col comando
":help".
Vedere qui sotto la sezione AIUTO ONLINE.
.PP
@@ -68,18 +68,18 @@ nome_file ..
Una lista di nomi di file.
Il primo di questi sarà il file corrente, e verrà letto nel buffer.
Il cursore sarà posizionato sulla prima linea del buffer.
-Potete arrivare agli altri file col comando ":next".
+Si può arrivare agli altri file col comando ":next".
Per editare un file il cui nome inizia per "\-" premettete "\-\-" alla lista_file.
.TP
\-
-Il file da editare è letto dallo "stdin"-
-I comandi sono letti da "stderr", che dovrebbe essere un terminale [tty].
+Il file da editare è letto dallo stdin.
+I comandi sono letti da stderr, che dovrebbe essere un terminale [tty].
.TP
\-t {tag}
Il file da editare e la posizione iniziale del cursore dipendono da "tag",
una specie di "etichetta" a cui saltare.
{tag} viene cercata nel file "tags", e il file a essa associato diventa
-quello corrente, ed il comando ad essa associato viene eseguito.
+quello corrente, e il comando a essa associato viene eseguito.
Di solito si usa per programmi C, nel qual caso {tag} potrebbe essere un
nome di funzione.
L'effetto è che il file contenente quella funzione diventa il file corrente
@@ -97,10 +97,10 @@ Vedere ":help quickfix".
.PP
.B Vim
si comporta in modo diverso se invocato con nomi differenti (il programma
-eseguibile "sottostante" può essere sempre lo stesso).
+eseguibile "soggiacente" può essere sempre lo stesso).
.TP 10
vim
-Modo Normal, comportamento normale.
+Modo Normal, comportamento predefinito.
.TP
ex
Inizia in Modo "Ex".
@@ -108,7 +108,7 @@ Si può passare in Modo Normal col comando ":vi".
Si può invocare il Modo "Ex" anche con l'argomento "\-e".
.TP
view
-Inizia in Modo Read-only (Sola Lettura). Non potete modificare i file.
+Inizia in Modo Read-only (Sola Lettura). Non si possono modificare i file.
Si può invocare il Modo Read-only anche con l'argomento "\-R".
.TP
gvim gview
@@ -131,11 +131,11 @@ Le opzioni possono essere in un ordine qualsiasi, prima o dopo i nomi di file.
Opzioni che non hanno un argomento si possono specificare dietro a un solo "\-".
.TP 12
+[numero]
-Per il primo file il cursore sarà posizionato sulla linea "numero".
+Nel primo file il cursore sarà posizionato sulla linea "numero".
Se "numero" manca, il cursore sarà posizionato sull'ultima linea del file.
.TP
+/{espressione}
-Per il primo file il cursore sarà posizionato alla
+Nel primo file il cursore sarà posizionato alla
prima occorrenza di {espressione}.
Vedere ":help search\-pattern" per come specificare l'espressione.
.TP
@@ -166,7 +166,7 @@ Si possono usare fino a 10 di questi comandi, indipendentemente dai comandi "\-c
Se
.B Vim
è stato compilato con supporto ARABIC per editare file con orientamento
-destra-sinistra e tastiera con mappatura araba, questa opzione inizia
+destra-sinistra e tastiera con mappatura araba, quest'opzione inizia
.B Vim
in Modo Arabic, cioè impostando 'arabic'.
Altrimenti viene dato un messaggio di errore e
@@ -176,7 +176,7 @@ termina in modo anormale.
\-b
Modo Binary (binario).
Vengono impostate alcune opzioni che permettono di modificare un file
-binario o un programma eseguibile.
+binario o un file che contiene un programma eseguibile.
.TP
\-C
Compatibile. Imposta l'opzione 'compatible'.
@@ -186,12 +186,12 @@ ha quasi lo stesso comportamento di Vi, anche in presenza di un file .vimrc.
.TP
\-d
Inizia in Modo Diff [differenze].
-Dovrebbero esserci come argomenti due o tre o quattro nomi di file.
+Dovrebbero esserci come argomenti da due o otto nomi di file.
.B Vim
aprirà tutti i file evidenziando le differenze fra gli stessi.
Funziona come vimdiff(1).
.TP
-\-d {dispositivo}
+\-d {dispositivo}, \-dev {dispositivo}
Apre {dispositivo} per usarlo come terminale.
Solo per l'Amiga.
Esempio:
@@ -221,7 +221,7 @@ non è fatto ripartire per aprire una nuova finestra.
Opzione da usare quando
.B Vim
è eseguito da un programma che attende la fine della
-sessione di edit (ad es. mail).
+sessione di edit (p.es., mail).
Sull'Amiga i comandi ":sh" e ":!" non sono disponibili.
.TP
\-\-nofork
@@ -233,7 +233,7 @@ non crea [fork] una nuova finestra, indipendente dalla shell di invocazione.
Se
.B Vim
è stato compilato con supporto FKMAP per editare file con orientamento
-destra-sinistra e tastiera con mappatura Farsi, questa opzione inizia
+destra-sinistra e tastiera con mappatura Farsi, quest'opzione inizia
.B Vim
in Modo Farsi, cioè impostando 'fkmap' e 'rightleft'.
Altrimenti viene dato un messaggio di errore e
@@ -243,12 +243,19 @@ termina in modo anormale.
\-g
Se
.B Vim
-è stato compilato con supporto GUI, questa opzione chiede di usarla.
+è stato compilato con supporto GUI, quest'opzione chiede di usarla.
Se Vim è stato compilato senza supporto GUI viene dato un messaggio di errore e
.B Vim
termina in modo anormale.
.TP
-\-h
+\-\-gui-dialog-file {nome}
+Quando si usa la GUI, invece di visualizzare un dialogo, il titolo e il
+messaggio del dialogo sono scritti sul file {nome}. Il file viene creato o,
+se già esistente, viene esteso. Quest'opzione serve solo in fase di test,
+per evitare di restare bloccati da un dialogo che non si riesce a visualizzare.
+Se si sta lavorando senza la GUI l'argomento viene ignorato.
+.TP
+\-\-help, \-h, \-?
Un po' di aiuto su opzioni e argomenti che si possono dare invocando Vim.
Subito dopo
.B Vim
@@ -258,7 +265,7 @@ esce.
Se
.B Vim
è stato compilato col supporto RIGHTLEFT per editare file con orientamento
-destra-sinistra e tastiera con mappatura Ebraica, questa opzione inizia
+destra-sinistra e tastiera con mappatura Ebraica, quest'opzione inizia
.B Vim
in Modo Ebraico, cioè impostando 'hkmap' e 'rightleft'.
Altrimenti viene dato un messaggio di errore e
@@ -266,7 +273,7 @@ Altrimenti viene dato un messaggio di errore e
termina in modo anormale.
.TP
\-i {viminfo}
-Se è abilitato l'uso di un file viminfo, questa opzione indica il nome
+Se è abilitato l'uso di un file viminfo, quest'opzione indica il nome
del file da usare invece di quello predefinito "~/.viminfo".
Si può anche evitare l'uso di un file .viminfo, dando come nome
"NONE".
@@ -292,13 +299,13 @@ opzioni possono essere abilitate in seguito, permettendo così modifiche.
Modo "Non-compatibile". Annulla l'opzione 'compatible'.
Così
.B Vim
-va un po' meglio, ma è meno compatibile con Vi, anche in assenza di un
+si comporta un po' meglio, ma è meno compatibile con Vi, anche in assenza di un
file .vimrc.
.TP
\-n
Inibisce l'uso di un file di swap.
Il recupero dopo una caduta di macchina diventa impossibile.
-Utile per editare un file su un supporto molto lento (ad es. floppy).
+Utile per editare un file su un supporto molto lento (p.es., floppy).
Il comando ":set uc=0" ha lo stesso effetto.
Per abilitare il recupero usare ":set uc=200".
.TP
@@ -306,16 +313,23 @@ Per abilitare il recupero usare ":set uc=200".
Diviene un Editor server per NetBeans. Vedere la documentazione per dettagli.
.TP
\-o[N]
-Apri N finestre in orizzontale.
-Se N manca, apri una finestra per ciascun file.
+Apre N finestre in orizzontale.
+Se N manca, apre una finestra per ciascun file.
.TP
\-O[N]
-Apri N finestre, in verticale.
-Se N manca, apri una finestra per ciascun file.
+Apre N finestre, in verticale.
+Se N manca, apre una finestra per ciascun file.
.TP
\-p[N]
-Apri N pagine di linguette.
-Quando N è omesso, apri una pagine di linguette per ciascun file.
+Apre N pagine di linguette.
+Quando N è omesso, apre una pagine di linguette per ciascun file.
+.TP
+\-P {titolo-padre}
+Solo per GUI Win32: Specifica il titolo dell'applicazione-padre. Se possibile,
+Vim viene eseguito in una finestra MDI (Multiple-Document Interface).
+{titolo-padre} deve apparire nel titolo della applicazione-padre. Accertatevi
+che sia sufficientemente esplicativo. Notare che l'implementazione è ancora
+rudimentale. Non funziona per tutte le applicazioni, e il menù non funziona.
.TP
\-R
Modo Read-only (Sola Lettura).
@@ -324,7 +338,7 @@ Si può ancora modificare il buffer, ma il file è protetto da una riscrittura
involontaria.
Se si vuole davvero riscrivere il file, occorre aggiungere un punto esclamativo
al comando Ex, come in ":w!".
-L'opzione \-R implica anche l'opzione \-n (vedere sotto).
+L'opzione \-R implica anche l'opzione \-n (vedere sopra).
L'opzione 'readonly' può essere annullata con ":set noro".
Vedere ":help 'readonly'".
.TP
@@ -342,10 +356,10 @@ Vedere ":help recovery".
Modo silenzioso. Solo quando invocato come "Ex" o quando l'opzione
"\-e" è stata data prima dell'opzione "\-s".
.TP
-\-s {scriptin}
-Lo script file {scriptin} è letto.
+\-s {script_in_input}
+Lo script file {script_in_input} è letto.
I caratteri nel file sono interpretati come se immessi da terminale.
-Lo stesso risultato si può ottenere col comando ":source! {scriptin}".
+Lo stesso risultato si può ottenere col comando ":source! {script_in_input}".
Se la fine del file di input viene raggiunta prima che Vim termini,
l'ulteriore input verrà preso dalla tastiera.
.TP
@@ -356,12 +370,22 @@ quale tipo di terminale state usando.
Utile solo se il terminale non viene riconosciuto correttamente da Vim.
Dovrebbe essere un terminale noto a
.B Vim
-(internamente) o definito nei file termcap o terminfo.
+(predefinito) o definito nei file termcap o terminfo.
+.TP
+\-\-not-a-term
+Da usare per specifica a
+.B Vim
+che l'utente è consapevole che l'input e l'output non avvengono con un terminale
+vero e proprio. Ciò serve per evitare il messaggio di avvertimento e il ritardo
+di due secondi che avverrebbero in assenza di questo argomento.
+.TP
+\-\-ttyfail
+Quando stdin o stdout non sono un terminale (tty) esci subito da Vim.
.TP
\-u {vimrc}
Usa i comandi nel file {vimrc} per inizializzazioni.
Tutte le altre inizializzazioni non sono eseguite.
-Usate questa opzione per editare qualche file di tipo speciale.
+Usare quest'opzione per editare qualche file di tipo speciale.
Si possono anche omettere tutte le inizializzazioni dando come nome "NONE".
Vedere ":help initialization" da vim per ulteriori dettagli.
.TP
@@ -376,21 +400,37 @@ Verboso. Vim manda messaggi relativi ai file di script che esegue
e quando legge o scrive un file viminfo. Il numero opzionale N è il valore
dell'opzione 'verbose'. Il valore predefinito è 10.
.TP
+\-V[N]{nome_file}
+Comw \-V imposta 'verbosefile' a {nome_file}. Il risultato è che i messaggi
+non sono visualizzati, ma scritti sul file {nome_file}. Il {nome_file} non
+deve iniziare con un numero.
+.TP
+\-\-log {nome_file}
+Se
+.B Vim
+è stato compilato con le funzionalità eval e channel, inizia a registrare
+e scrive le registrazioni a {nome_file}. Ciò equivale a chiamare
+.I ch_logfile({nome_file}, 'ao')
+in una fase molto iniziale dell'avvio del programma.
+.TP
\-v
Inizia
.B Vim
in Modo Vi, come se il programma eseguibile fosse "vi". Questo ha
effetto solo quando Vim viene invocato con il nome "ex".
.TP
-\-w {scriptout}
-Ogni carattere immesso viene registrato nel file {scriptout},
+\-w{numero}
+Imposta l'opzione 'window' a {numero}.
+.TP
+\-w {script_file}
+Ogni carattere immesso viene registrato nel file {script_file},
finché non si esce da
.B Vim.
Utile se si vuole creare uno script file da usare con "vim \-s" o
":source!".
-Se il file {scriptout} esiste, quel che immettete viene aggiunto in fondo.
+Se il file {script_file} esiste, il testo immesso viene aggiunto in fondo.
.TP
-\-W {scriptout}
+\-W {script_file}
Come \-w, ma uno script file esistente viene sovrascritto.
.TP
\-x
@@ -421,10 +461,7 @@ Richiede di non usare alcun file di personalizzazione (vimrc, plugin, etc.).
Utile per verificare se un problema persiste invocando Vim "originale".
.TP
\-\-echo\-wid
-Solo per GUI GTK: Visualizza Window ID su "stdout".
-.TP
-\-\-help
-Vim dà un messaggio ed esce, come con l'argomento "\-h".
+Solo per GUI GTK: Visualizza ID di Window su stdout.
.TP
\-\-literal
Considera i nomi passati come argomenti letterali, senza espandere metacaratteri.
@@ -439,7 +476,7 @@ argomenti. Se non si trova un server viene dato un messaggio e i file sono
editati nel Vim corrente.
.TP
\-\-remote\-expr {expr}
-Connettersi a un server Vim, valutare {expr} e stampare il risultato su "stdout".
+Connettersi a un server Vim, valutare {expr} e stampare il risultato su stdout.
.TP
\-\-remote\-send {chiavi}
Connettersi a un server Vim e spedirgli {chiavi}.
@@ -467,7 +504,11 @@ Solo per GUI GTK: Usa meccanismo GtkPlug per eseguire gvim in un'altra finestra.
Durante la fase iniziale, scrive messaggi di log al file {nome_file}.
.TP
\-\-version
-Stampa la versione di Vim ed esci.
+Stampa la versione di Vim ed esce.
+.TP
+\-\-windowid {id}
+Solo per GUI Win32: Chiede a gvim di provare a user l'ID di window {id}
+come padre, in modo da venir eseguito all'interno della finestra specificata.
.SH AIUTO ONLINE
Battere ":help" in
.B Vim
@@ -481,53 +522,57 @@ Tutti i file di documentazione possono essere navigati così. Ad es.:
":help syntax.txt".
.SH FILE
.TP 15
-/usr/local/lib/vim/doc/*.txt
+/usr/local/share/vim/vim??/doc/*.txt
I file di documentazione di
.B Vim
.
Usare ":help doc\-file\-list" per avere la lista completa.
+.br
+.I vim??
+è il numero di versione corto, p.es., vim91 per indicare
+.B Vim 9.1
.TP
-/usr/local/lib/vim/doc/tags
+/usr/local/share/vim/vim??/doc/tags
Il file di tags usato per trovare informazioni nei file di documentazione.
.TP
-/usr/local/lib/vim/syntax/syntax.vim
+/usr/local/share/vim/vim??/syntax/syntax.vim
Inizializzazioni sintattiche a livello di sistema.
.TP
-/usr/local/lib/vim/syntax/*.vim
+/usr/local/share/vim/vim??/syntax/*.vim
File di colorazione sintattica per vari linguaggi.
.TP
-/usr/local/lib/vim/vimrc
+/usr/local/share/vim/vimrc
Inizializzazioni
.B Vim
a livello di sistema.
.TP
-~/.vimrc
+~/.vimrc, ~/.vim/vimrc, $XDG_CONFIG_HOME/vim/vimrc
Inizializzazioni personali di
.B Vim
-.
+(viene utilizzata la prima trovata).
.TP
-/usr/local/lib/vim/gvimrc
+/usr/local/share/vim/gvimrc
Inizializzazioni gvim a livello di sistema.
.TP
-~/.gvimrc
-Inizializzazioni personali di
+~/.gvimrc, ~/.vim/gvimrc, $XDG_CONFIG_HOME/vim/gvimrc
+Inizializzazioni personali di gvim (viene utilizzata la prima trovata).
.TP
-/usr/local/lib/vim/optwin.vim
-Script Vim usato dal comando ":options", da usare per visualizzare e impostare opzioni.
+/usr/local/share/vim/optwin.vim
+Script Vim usato dal comando ":options", maniera elegante per visualizzare e impostare opzioni.
.TP
-/usr/local/lib/vim/menu.vim
+/usr/local/share/vim/vim??/menu.vim
Inizializzazioni del menù gvim a livello di sistema.
.TP
-/usr/local/lib/vim/bugreport.vim
+/usr/local/share/vim/vim??/bugreport.vim
Script Vim per generare una segnalazione di errore. Vedere ":help bugs".
.TP
-/usr/local/lib/vim/filetype.vim
+/usr/local/share/vim/vim??/filetype.vim
Script Vim per determinare il tipo di un file dal suo nome. Vedere ":help 'filetype'".
.TP
-/usr/local/lib/vim/scripts.vim
+/usr/local/share/vim/vim??/scripts.vim
Script Vim per determinare il tipo di un file dal suo contenuto. Vedere ":help 'filetype'".
.TP
-/usr/local/lib/vim/print/*.ps
+/usr/local/share/vim/vim??/print/*.ps
File usati per stampa PostScript.
.PP
Per informazioni aggiornate [in inglese \- NdT] vedere la home page di Vim:
@@ -546,8 +591,8 @@ Vedere ":help credits" in
è basato su Stevie, scritto da: Tim Thompson,
Tony Andrews e G.R. (Fred) Walter.
In verità, poco o nulla è rimasto del loro codice originale.
-.SH BACHI
-Probabili.
+.SH BUG
+Probabilmente.
Vedere ":help todo" per una lista di problemi noti.
.PP
Si noti che un certo numero di comportamenti che possono essere considerati errori
diff --git a/runtime/doc/vim.1 b/runtime/doc/vim.1
index 5613dd4..a180a62 100644
--- a/runtime/doc/vim.1
+++ b/runtime/doc/vim.1
@@ -1,4 +1,4 @@
-.TH VIM 1 "2021 Jun 13"
+.TH VIM 1 "2024 Jun 04"
.SH NAME
vim \- Vi IMproved, a programmer's text editor
.SH SYNOPSIS
@@ -191,7 +191,7 @@ There should between two to eight file name arguments.
will open all the files and show differences between them.
Works like vimdiff(1).
.TP
-\-d {device}
+\-d {device}, \-dev {device}
Open {device} for use as a terminal.
Only on the Amiga.
Example:
@@ -248,7 +248,13 @@ If no GUI support was compiled in, an error message is given and
.B Vim
aborts.
.TP
-\-h
+\-\-gui-dialog-file {name}
+When using the GUI, instead of showing a dialog, write the title and message of
+the dialog to file {name}. The file is created or appended to. Only useful
+for testing, to avoid that the test gets stuck on a dialog that can't be seen.
+Without the GUI the argument is ignored.
+.TP
+\-\-help, \-h, \-?
Give a bit of help about the command line arguments and options.
After this
.B Vim
@@ -317,6 +323,13 @@ When N is omitted, open one window for each file.
Open N tab pages.
When N is omitted, open one tab page for each file.
.TP
+\-P {parent-title}
+Win32 GUI only: Specify the title of the parent application. When possible, Vim
+will run in an MDI window inside the application. {parent-title} must appear in
+the window title of the parent application. Make sure that it is specific
+enough. Note that the implementation is still primitive. It won't work with
+all applications and the menu doesn't work.
+.TP
\-R
Read-only mode.
The 'readonly' option will be set.
@@ -358,6 +371,16 @@ Should be a terminal known to
.B Vim
(builtin) or defined in the termcap or terminfo file.
.TP
+\-\-not-a-term
+Tells
+.B Vim
+that the user knows that the input and/or output is not connected to a
+terminal. This will avoid the warning and the two second delay that would
+happen.
+.TP
+\-\-ttyfail
+When stdin or stdout is not a a terminal (tty) then exit right away.
+.TP
\-u {vimrc}
Use the commands in the file {vimrc} for initializations.
All the other initializations are skipped.
@@ -376,12 +399,28 @@ Verbose. Give messages about which files are sourced and for reading and
writing a viminfo file. The optional number N is the value for 'verbose'.
Default is 10.
.TP
+\-V[N]{filename}
+Like \-V and set 'verbosefile' to {filename}. The result is that messages are
+not displayed but written to the file {filename}. {filename} must not start
+with a digit.
+.TP
+\-\-log {filename}
+If
+.B Vim
+has been compiled with eval and channel feature, start logging and write
+entries to {filename}. This works like calling
+.I ch_logfile({filename}, 'ao')
+very early during startup.
+.TP
\-v
Start
.B Vim
in Vi mode, just like the executable was called "vi". This only has effect
when the executable is called "ex".
.TP
+\-w{number}
+Set the 'window' option to {number}.
+.TP
\-w {scriptout}
All the characters that you type are recorded in the file
{scriptout}, until you exit
@@ -423,9 +462,6 @@ a problem reproduces with a clean Vim setup.
\-\-echo\-wid
GTK GUI only: Echo the Window ID on stdout.
.TP
-\-\-help
-Give a help message and exit, just like "\-h".
-.TP
\-\-literal
Take file name arguments literally, do not expand wildcards. This has no
effect on Unix where the shell expands wildcards.
@@ -468,6 +504,10 @@ During startup write timing messages to the file {fname}.
.TP
\-\-version
Print version information and exit.
+.TP
+\-\-windowid {id}
+Win32 GUI only: Make gvim try to use the window {id} as a parent, so that it
+runs inside that window.
.SH ON-LINE HELP
Type ":help" in
.B Vim
@@ -481,53 +521,57 @@ All documentation files can be viewed in this way, for example
":help syntax.txt".
.SH FILES
.TP 15
-/usr/local/lib/vim/doc/*.txt
+/usr/local/share/vim/vim??/doc/*.txt
The
.B Vim
documentation files.
Use ":help doc\-file\-list" to get the complete list.
+.br
+.I vim??
+is short version number, like vim91 for
+.B Vim 9.1
.TP
-/usr/local/lib/vim/doc/tags
+/usr/local/share/vim/vim??/doc/tags
The tags file used for finding information in the documentation files.
.TP
-/usr/local/lib/vim/syntax/syntax.vim
+/usr/local/share/vim/vim??/syntax/syntax.vim
System wide syntax initializations.
.TP
-/usr/local/lib/vim/syntax/*.vim
+/usr/local/share/vim/vim??/syntax/*.vim
Syntax files for various languages.
.TP
-/usr/local/lib/vim/vimrc
+/usr/local/share/vim/vimrc
System wide
.B Vim
initializations.
.TP
-~/.vimrc
+~/.vimrc, ~/.vim/vimrc, $XDG_CONFIG_HOME/vim/vimrc
Your personal
.B Vim
-initializations.
+initializations (first one found is used).
.TP
-/usr/local/lib/vim/gvimrc
+/usr/local/share/vim/gvimrc
System wide gvim initializations.
.TP
-~/.gvimrc
-Your personal gvim initializations.
+~/.gvimrc, ~/.vim/gvimrc, $XDG_CONFIG_HOME/vim/gvimrc
+Your personal gvim initializations (first one found is used).
.TP
-/usr/local/lib/vim/optwin.vim
+/usr/local/share/vim/vim??/optwin.vim
Script used for the ":options" command, a nice way to view and set options.
.TP
-/usr/local/lib/vim/menu.vim
+/usr/local/share/vim/vim??/menu.vim
System wide menu initializations for gvim.
.TP
-/usr/local/lib/vim/bugreport.vim
+/usr/local/share/vim/vim??/bugreport.vim
Script to generate a bug report. See ":help bugs".
.TP
-/usr/local/lib/vim/filetype.vim
+/usr/local/share/vim/vim??/filetype.vim
Script to detect the type of a file by its name. See ":help 'filetype'".
.TP
-/usr/local/lib/vim/scripts.vim
+/usr/local/share/vim/vim??/scripts.vim
Script to detect the type of a file by its contents. See ":help 'filetype'".
.TP
-/usr/local/lib/vim/print/*.ps
+/usr/local/share/vim/vim??/print/*.ps
Files used for PostScript printing.
.PP
For recent info read the VIM home page:
diff --git a/runtime/doc/vim.man b/runtime/doc/vim.man
index cc6a9bc..4ce444e 100644
--- a/runtime/doc/vim.man
+++ b/runtime/doc/vim.man
@@ -139,7 +139,8 @@ OPTIONS
name arguments. Vim will open all the files and show dif‐
ferences between them. Works like vimdiff(1).
- -d {device} Open {device} for use as a terminal. Only on the Amiga.
+ -d {device}, -dev {device}
+ Open {device} for use as a terminal. Only on the Amiga.
Example: "-d con:20/30/600/150".
-D Debugging. Go to debugging mode when executing the first
@@ -171,7 +172,15 @@ OPTIONS
ables the GUI. If no GUI support was compiled in, an error
message is given and Vim aborts.
- -h Give a bit of help about the command line arguments and op‐
+ --gui-dialog-file {name}
+ When using the GUI, instead of showing a dialog, write the
+ title and message of the dialog to file {name}. The file
+ is created or appended to. Only useful for testing, to
+ avoid that the test gets stuck on a dialog that can't be
+ seen. Without the GUI the argument is ignored.
+
+ --help, -h, -?
+ Give a bit of help about the command line arguments and op‐
tions. After this Vim exits.
-H If Vim has been compiled with RIGHTLEFT support for editing
@@ -220,6 +229,15 @@ OPTIONS
-p[N] Open N tab pages. When N is omitted, open one tab page for
each file.
+ -P {parent-title}
+ Win32 GUI only: Specify the title of the parent applica‐
+ tion. When possible, Vim will run in an MDI window inside
+ the application. {parent-title} must appear in the window
+ title of the parent application. Make sure that it is spe‐
+ cific enough. Note that the implementation is still primi‐
+ tive. It won't work with all applications and the menu
+ doesn't work.
+
-R Read-only mode. The 'readonly' option will be set. You
can still edit the buffer, but will be prevented from acci‐
dentally overwriting a file. If you do want to overwrite a
@@ -252,26 +270,47 @@ OPTIONS
terminal known to Vim (builtin) or defined in the termcap
or terminfo file.
- -u {vimrc} Use the commands in the file {vimrc} for initializations.
- All the other initializations are skipped. Use this to
- edit a special kind of files. It can also be used to skip
- all initializations by giving the name "NONE". See ":help
+ --not-a-term
+ Tells Vim that the user knows that the input and/or output
+ is not connected to a terminal. This will avoid the warn‐
+ ing and the two second delay that would happen.
+
+ --ttyfail When stdin or stdout is not a a terminal (tty) then exit
+ right away.
+
+ -u {vimrc} Use the commands in the file {vimrc} for initializations.
+ All the other initializations are skipped. Use this to
+ edit a special kind of files. It can also be used to skip
+ all initializations by giving the name "NONE". See ":help
initialization" within vim for more details.
- -U {gvimrc} Use the commands in the file {gvimrc} for GUI initializa‐
- tions. All the other GUI initializations are skipped. It
- can also be used to skip all GUI initializations by giving
- the name "NONE". See ":help gui-init" within vim for more
+ -U {gvimrc} Use the commands in the file {gvimrc} for GUI initializa‐
+ tions. All the other GUI initializations are skipped. It
+ can also be used to skip all GUI initializations by giving
+ the name "NONE". See ":help gui-init" within vim for more
details.
- -V[N] Verbose. Give messages about which files are sourced and
- for reading and writing a viminfo file. The optional num‐
+ -V[N] Verbose. Give messages about which files are sourced and
+ for reading and writing a viminfo file. The optional num‐
ber N is the value for 'verbose'. Default is 10.
+ -V[N]{filename}
+ Like -V and set 'verbosefile' to {filename}. The result is
+ that messages are not displayed but written to the file
+ {filename}. {filename} must not start with a digit.
+
+ --log {filename}
+ If Vim has been compiled with eval and channel feature,
+ start logging and write entries to {filename}. This works
+ like calling ch_logfile({filename}, 'ao') very early during
+ startup.
+
-v Start Vim in Vi mode, just like the executable was called
"vi". This only has effect when the executable is called
"ex".
+ -w{number} Set the 'window' option to {number}.
+
-w {scriptout}
All the characters that you type are recorded in the file
{scriptout}, until you exit Vim. This is useful if you
@@ -306,8 +345,6 @@ OPTIONS
--echo-wid GTK GUI only: Echo the Window ID on stdout.
- --help Give a help message and exit, just like "-h".
-
--literal Take file name arguments literally, do not expand wild‐
cards. This has no effect on Unix where the shell expands
wildcards.
@@ -354,58 +391,67 @@ OPTIONS
--version Print version information and exit.
+ --windowid {id}
+ Win32 GUI only: Make gvim try to use the window {id} as a
+ parent, so that it runs inside that window.
+
ON-LINE HELP
- Type ":help" in Vim to get started. Type ":help subject" to get help
- on a specific subject. For example: ":help ZZ" to get help for the
- "ZZ" command. Use <Tab> and CTRL-D to complete subjects (":help cmd‐
- line-completion"). Tags are present to jump from one place to another
+ Type ":help" in Vim to get started. Type ":help subject" to get help
+ on a specific subject. For example: ":help ZZ" to get help for the
+ "ZZ" command. Use <Tab> and CTRL-D to complete subjects (":help cmd‐
+ line-completion"). Tags are present to jump from one place to another
(sort of hypertext links, see ":help"). All documentation files can be
viewed in this way, for example ":help syntax.txt".
FILES
- /usr/local/lib/vim/doc/*.txt
- The Vim documentation files. Use ":help doc-file-list"
+ /usr/local/share/vim/vim??/doc/*.txt
+ The Vim documentation files. Use ":help doc-file-list"
to get the complete list.
+ vim?? is short version number, like vim91 for Vim 9.1
- /usr/local/lib/vim/doc/tags
- The tags file used for finding information in the docu‐
+ /usr/local/share/vim/vim??/doc/tags
+ The tags file used for finding information in the docu‐
mentation files.
- /usr/local/lib/vim/syntax/syntax.vim
+ /usr/local/share/vim/vim??/syntax/syntax.vim
System wide syntax initializations.
- /usr/local/lib/vim/syntax/*.vim
+ /usr/local/share/vim/vim??/syntax/*.vim
Syntax files for various languages.
- /usr/local/lib/vim/vimrc
+ /usr/local/share/vim/vimrc
System wide Vim initializations.
- ~/.vimrc Your personal Vim initializations.
+ ~/.vimrc, ~/.vim/vimrc, $XDG_CONFIG_HOME/vim/vimrc
+ Your personal Vim initializations (first one found is
+ used).
- /usr/local/lib/vim/gvimrc
+ /usr/local/share/vim/gvimrc
System wide gvim initializations.
- ~/.gvimrc Your personal gvim initializations.
+ ~/.gvimrc, ~/.vim/gvimrc, $XDG_CONFIG_HOME/vim/gvimrc
+ Your personal gvim initializations (first one found is
+ used).
- /usr/local/lib/vim/optwin.vim
- Script used for the ":options" command, a nice way to
+ /usr/local/share/vim/vim??/optwin.vim
+ Script used for the ":options" command, a nice way to
view and set options.
- /usr/local/lib/vim/menu.vim
+ /usr/local/share/vim/vim??/menu.vim
System wide menu initializations for gvim.
- /usr/local/lib/vim/bugreport.vim
+ /usr/local/share/vim/vim??/bugreport.vim
Script to generate a bug report. See ":help bugs".
- /usr/local/lib/vim/filetype.vim
- Script to detect the type of a file by its name. See
+ /usr/local/share/vim/vim??/filetype.vim
+ Script to detect the type of a file by its name. See
":help 'filetype'".
- /usr/local/lib/vim/scripts.vim
- Script to detect the type of a file by its contents.
+ /usr/local/share/vim/vim??/scripts.vim
+ Script to detect the type of a file by its contents.
See ":help 'filetype'".
- /usr/local/lib/vim/print/*.ps
+ /usr/local/share/vim/vim??/print/*.ps
Files used for PostScript printing.
For recent info read the VIM home page:
@@ -417,19 +463,19 @@ SEE ALSO
AUTHOR
Most of Vim was made by Bram Moolenaar, with a lot of help from others.
See ":help credits" in Vim.
- Vim is based on Stevie, worked on by: Tim Thompson, Tony Andrews and
+ Vim is based on Stevie, worked on by: Tim Thompson, Tony Andrews and
G.R. (Fred) Walter. Although hardly any of the original code remains.
BUGS
Probably. See ":help todo" for a list of known problems.
- Note that a number of things that may be regarded as bugs by some, are
- in fact caused by a too-faithful reproduction of Vi's behaviour. And
- if you think other things are bugs "because Vi does it differently",
- you should take a closer look at the vi_diff.txt file (or type :help
- vi_diff.txt when in Vim). Also have a look at the 'compatible' and
+ Note that a number of things that may be regarded as bugs by some, are
+ in fact caused by a too-faithful reproduction of Vi's behaviour. And
+ if you think other things are bugs "because Vi does it differently",
+ you should take a closer look at the vi_diff.txt file (or type :help
+ vi_diff.txt when in Vim). Also have a look at the 'compatible' and
'cpoptions' options.
- 2021 Jun 13 VIM(1)
+ 2024 Jun 04 VIM(1)
diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt
index 7a49aa0..68e5d99 100644
--- a/runtime/doc/vim9.txt
+++ b/runtime/doc/vim9.txt
@@ -1,4 +1,4 @@
-*vim9.txt* For Vim version 9.1. Last change: 2024 Apr 13
+*vim9.txt* For Vim version 9.1. Last change: 2024 May 31
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -67,6 +67,7 @@ rewrite old scripts, they keep working as before. You may want to use a few
Note that {cmd} cannot use local variables, since it is parsed
with legacy expression syntax.
+See some examples of Vim9 script at |52.6|.
==============================================================================
2. Differences from legacy Vim script *vim9-differences*
diff --git a/runtime/doc/xxd-it.1 b/runtime/doc/xxd-it.1
index 9311ed5..a4c1fe4 100644
--- a/runtime/doc/xxd-it.1
+++ b/runtime/doc/xxd-it.1
@@ -75,6 +75,9 @@ Non c' un valore massimo per \-ps; se si specifica 0 viene scritta un'unica lun
.IR \-C " | " \-capitalize
Mette in maiuscolo i nomi di variabili nello stile delle `include' C, se si usa \-i.
.TP
+.I \-d
+Mostra spostamenti usando numeri decimali invece che esadecimali.
+.TP
.IR \-E " | " \-EBCDIC
Cambia la codifica della colonna di destra da ASCII a EBCDIC.
Questo non modifica la rappresentazione esadecimale. Non ha senso
@@ -143,7 +146,7 @@ lo stesso colore, a seconda del valore esadecimale. Utile soprattutto a
distinguere i caratteri stampabili da quelli non stampabili.
.I quando
pu assumere i valori
-.BR never ", " always ", o " auto .
+.BR never ", " always ", o " auto " (default: auto).
Quando la variabile d'ambiente
.BR $NO_COLOR
impostata, la colorazione viene disabilitata.
diff --git a/runtime/doc/xxd-it.UTF-8.1 b/runtime/doc/xxd-it.UTF-8.1
index 66df3ff..58b9789 100644
--- a/runtime/doc/xxd-it.UTF-8.1
+++ b/runtime/doc/xxd-it.UTF-8.1
@@ -75,6 +75,9 @@ Non c'è un valore massimo per \-ps; se si specifica 0 viene scritta un'unica lu
.IR \-C " | " \-capitalize
Mette in maiuscolo i nomi di variabili nello stile delle `include' C, se si usa \-i.
.TP
+.I \-d
+Mostra spostamenti usando numeri decimali invece che esadecimali.
+.TP
.IR \-E " | " \-EBCDIC
Cambia la codifica della colonna di destra da ASCII a EBCDIC.
Questo non modifica la rappresentazione esadecimale. Non ha senso
@@ -143,7 +146,7 @@ lo stesso colore, a seconda del valore esadecimale. Utile soprattutto a
distinguere i caratteri stampabili da quelli non stampabili.
.I quando
può assumere i valori
-.BR never ", " always ", o " auto .
+.BR never ", " always ", o " auto " (default: auto).
Quando la variabile d'ambiente
.BR $NO_COLOR
è impostata, la colorazione viene disabilitata.
diff --git a/runtime/doc/xxd.1 b/runtime/doc/xxd.1
index f5a7c65..c76f89b 100644
--- a/runtime/doc/xxd.1
+++ b/runtime/doc/xxd.1
@@ -75,6 +75,9 @@ No maximum for \-ps. With \-ps, 0 results in one long line of output.
.IR \-C " | " \-capitalize
Capitalize variable names in C include file style, when using \-i.
.TP
+.I \-d
+show offset in decimal instead of hex.
+.TP
.IR \-E " | " \-EBCDIC
Change the character encoding in the righthand column from ASCII to EBCDIC.
This does not change the hexadecimal representation. The option is
@@ -138,12 +141,12 @@ anywhere. Use the combination
to read a bits dump instead of a hex dump.
.TP
.IR \-R " " when
-In output the hex-value and the value are both colored with the same color
+In the output the hex-value and the value are both colored with the same color
depending on the hex-value. Mostly helping to differentiate printable and
non-printable characters.
.I \fIwhen\fP
is
-.BR never ", " always ", or " auto .
+.BR never ", " always ", or " auto " (default: auto).
When the
.BR $NO_COLOR
environment variable is set, colorization will be disabled.
diff --git a/runtime/doc/xxd.man b/runtime/doc/xxd.man
index 56b69b4..b06971b 100644
--- a/runtime/doc/xxd.man
+++ b/runtime/doc/xxd.man
@@ -49,6 +49,8 @@ OPTIONS
Capitalize variable names in C include file style, when using
-i.
+ -d show offset in decimal instead of hex.
+
-E | -EBCDIC
Change the character encoding in the righthand column from ASCII
to EBCDIC. This does not change the hexadecimal representation.
@@ -97,15 +99,15 @@ OPTIONS
truncating it. Use the combination -r -p to read plain hexadeci‐
mal dumps without line number information and without a particu‐
lar column layout. Additional whitespace and line breaks are al‐
- lowed anywhere. Use the combination -r -b to read a bits dump
+ lowed anywhere. Use the combination -r -b to read a bits dump
instead of a hex dump.
-R when
- In output the hex-value and the value are both colored with the
- same color depending on the hex-value. Mostly helping to differ‐
- entiate printable and non-printable characters. when is never,
- always, or auto. When the $NO_COLOR environment variable is
- set, colorization will be disabled.
+ In the output the hex-value and the value are both colored with
+ the same color depending on the hex-value. Mostly helping to
+ differentiate printable and non-printable characters. when is
+ never, always, or auto (default: auto). When the $NO_COLOR en‐
+ vironment variable is set, colorization will be disabled.
-seek offset
When used after -r: revert with <offset> added to file positions
@@ -113,9 +115,9 @@ OPTIONS
-s [+][-]seek
Start at <seek> bytes abs. (or rel.) infile offset. + indicates
- that the seek is relative to the current stdin file position
+ that the seek is relative to the current stdin file position
(meaningless when not reading from stdin). - indicates that the
- seek should be that many characters from the end of the input
+ seek should be that many characters from the end of the input
(or if combined with +: before the current stdin file position).
Without -s option, xxd starts at the current file position.
@@ -125,20 +127,20 @@ OPTIONS
Show version string.
CAVEATS
- xxd -r has some built-in magic while evaluating line number informa‐
- tion. If the output file is seekable, then the line numbers at the
- start of each hex dump line may be out of order, lines may be missing,
- or overlapping. In these cases xxd will lseek(2) to the next position.
- If the output file is not seekable, only gaps are allowed, which will
+ xxd -r has some built-in magic while evaluating line number informa‐
+ tion. If the output file is seekable, then the line numbers at the
+ start of each hex dump line may be out of order, lines may be missing,
+ or overlapping. In these cases xxd will lseek(2) to the next position.
+ If the output file is not seekable, only gaps are allowed, which will
be filled by null-bytes.
xxd -r never generates parse errors. Garbage is silently skipped.
When editing hex dumps, please note that xxd -r skips everything on the
input line after reading enough columns of hexadecimal data (see option
- -c). This also means that changes to the printable ASCII (or EBCDIC)
+ -c). This also means that changes to the printable ASCII (or EBCDIC)
columns are always ignored. Reverting a plain (or PostScript) style hex
- dump with xxd -r -p does not depend on the correct number of columns.
+ dump with xxd -r -p does not depend on the correct number of columns.
Here, anything that looks like a pair of hex digits is interpreted.
Note the difference between
@@ -146,28 +148,28 @@ CAVEATS
and
% xxd -i < file
- xxd -s +seek may be different from xxd -s seek, as lseek(2) is used to
+ xxd -s +seek may be different from xxd -s seek, as lseek(2) is used to
"rewind" input. A '+' makes a difference if the input source is stdin,
- and if stdin's file position is not at the start of the file by the
- time xxd is started and given its input. The following examples may
+ and if stdin's file position is not at the start of the file by the
+ time xxd is started and given its input. The following examples may
help to clarify (or further confuse!):
- Rewind stdin before reading; needed because the `cat' has already read
+ Rewind stdin before reading; needed because the `cat' has already read
to the end of stdin.
% sh -c "cat > plain_copy; xxd -s 0 > hex_copy" < file
- Hex dump from file position 0x480 (=1024+128) onwards. The `+' sign
+ Hex dump from file position 0x480 (=1024+128) onwards. The `+' sign
means "relative to the current position", thus the `128' adds to the 1k
where dd left off.
- % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +128 > hex_snippet"
+ % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +128 > hex_snippet"
< file
Hex dump from file position 0x100 (=1024-768) onwards.
% sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +-768 > hex_snippet"
< file
- However, this is a rare situation and the use of `+' is rarely needed.
- The author prefers to monitor the effect of xxd with strace(1) or
+ However, this is a rare situation and the use of `+' is rarely needed.
+ The author prefers to monitor the effect of xxd with strace(1) or
truss(1), whenever -s is used.
EXAMPLES
@@ -211,7 +213,7 @@ EXAMPLES
% xxd -s 0x36 -l 13 -c 13 xxd.1
0000036: 3235 7468 204d 6179 2031 3939 36 25th May 1996
- Create a 65537 byte file with all bytes 0x00, except for the last one
+ Create a 65537 byte file with all bytes 0x00, except for the last one
which is 'A' (hex 0x41).
% echo "010000: 41" | xxd -r > file
@@ -222,11 +224,11 @@ EXAMPLES
000fffc: 0000 0000 40 ....A
Create a 1 byte file containing a single 'A' character. The number af‐
- ter '-r -s' adds to the line numbers found in the file; in effect, the
+ ter '-r -s' adds to the line numbers found in the file; in effect, the
leading bytes are suppressed.
% echo "010000: 41" | xxd -r -s -0x10000 > file
- Use xxd as a filter within an editor such as vim(1) to hex dump a re‐
+ Use xxd as a filter within an editor such as vim(1) to hex dump a re‐
gion marked between `a' and `z'.
:'a,'z!xxd
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index 9d6b4bd..a2daf14 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1,7 +1,7 @@
" Vim support file to detect file types
"
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2023 Dec 06
+" Last Change: 2024 May 31
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" Listen very carefully, I will say this only once
@@ -972,6 +972,7 @@ au BufNewFile,BufRead *.hbs setf handlebars
" Hare
au BufNewFile,BufRead *.ha setf hare
+au BufNewFile,BufRead README call dist#ft#FTharedoc()
" Haskell
au BufNewFile,BufRead *.hs,*.hsc,*.hs-boot,*.hsig setf haskell
@@ -1044,6 +1045,9 @@ au BufRead,BufNewFile *.hurl setf hurl
" Hyper Builder
au BufNewFile,BufRead *.hb setf hb
+" Hyprlang
+au BufNewFile,BufRead hypr\(land\|paper\|idle\|lock\).conf setf hyprlang
+
" Httest
au BufNewFile,BufRead *.htt,*.htb setf httest
@@ -1072,7 +1076,7 @@ au BufNewFile,BufRead */.icewm/menu setf icemenu
au BufNewFile,BufRead .indent.pro setf indent
au BufNewFile,BufRead indent.pro call dist#ft#ProtoCheck('indent')
-" IDL (Interactive Data Language)
+" IDL (Interactive Data Language), Prolog, Cproto or zsh module C
au BufNewFile,BufRead *.pro call dist#ft#ProtoCheck('idlang')
" Indent RC
@@ -1103,6 +1107,9 @@ au BufNewFile,BufRead *.ini,*.INI setf dosini
" SysV Inittab
au BufNewFile,BufRead inittab setf inittab
+" Inko
+au BufNewFile,BufRead *.inko setf inko
+
" Inno Setup
au BufNewFile,BufRead *.iss setf iss
@@ -1145,6 +1152,9 @@ au BufNewFile,BufRead *.clp setf jess
" Jgraph
au BufNewFile,BufRead *.jgr setf jgraph
+" Jujutsu
+au BufNewFile,BufRead *.jjdescription setf jj
+
" Jovial
au BufNewFile,BufRead *.jov,*.j73,*.jovial setf jovial
@@ -1167,7 +1177,7 @@ au BufNewFile,BufRead *.ipynb,*.jupyterlab-settings setf json
au BufNewFile,BufRead *.sublime-project,*.sublime-settings,*.sublime-workspace setf json
" Other files that look like json
-au BufNewFile,BufRead .prettierrc,.firebaserc,.stylelintrc,flake.lock setf json
+au BufNewFile,BufRead .prettierrc,.firebaserc,.stylelintrc,.lintstagedrc,flake.lock setf json
" JSONC (JSON with comments)
au BufNewFile,BufRead *.jsonc,.babelrc,.eslintrc,.jsfmtrc setf jsonc
@@ -1356,6 +1366,7 @@ au BufNewFile,BufRead .mailcap,mailcap setf mailcap
" Makefile
au BufNewFile,BufRead *[mM]akefile,*.mk,*.mak,*.dsp setf make
+au BufNewFile,BufRead Kbuild setf make
" MakeIndex
au BufNewFile,BufRead *.ist,*.mst setf ist
@@ -1856,6 +1867,9 @@ au BufNewFile,BufRead *.pk setf poke
" Protocols
au BufNewFile,BufRead */etc/protocols setf protocols
+" Purescript
+au BufNewFile,BufRead *.purs setf purescript
+
" PyPA manifest files
au BufNewFile,BufRead MANIFEST.in setf pymanifest
@@ -2050,6 +2064,9 @@ au BufNewFile,BufRead *.scala setf scala
" SBT - Scala Build Tool
au BufNewFile,BufRead *.sbt setf sbt
+" Slint
+au BufNewFile,BufRead *.slint setf slint
+
" SuperCollider
au BufNewFile,BufRead *.sc call dist#ft#FTsc()
@@ -2133,7 +2150,7 @@ au BufNewFile,BufRead catalog setf catalog
" Gentoo ebuilds, Arch Linux PKGBUILDs and Alpine Linux APKBUILDs are actually
" bash scripts.
" NOTE: Patterns ending in a star are further down, these have lower priority.
-au BufNewFile,BufRead .bashrc,bashrc,bash.bashrc,.bash[_-]profile,.bash[_-]logout,.bash[_-]aliases,.bash[_-]history,bash-fc[-.],*.ebuild,*.bash,*.eclass,PKGBUILD,APKBUILD,*.bats call dist#ft#SetFileTypeSH("bash")
+au BufNewFile,BufRead .bashrc,bashrc,bash.bashrc,.bash[_-]profile,.bash[_-]logout,.bash[_-]aliases,.bash[_-]history,bash-fc[-.],*.ebuild,*.bash,*.eclass,PKGBUILD,APKBUILD,*.bats,*.cygport call dist#ft#SetFileTypeSH("bash")
au BufNewFile,BufRead .kshrc,*.ksh call dist#ft#SetFileTypeSH("ksh")
au BufNewFile,BufRead */etc/profile,.profile,*.sh,*.env call dist#ft#SetFileTypeSH(getline(1))
@@ -2226,6 +2243,9 @@ au BufNewFile,BufRead *.smt,*.smith setf smith
" Smithy
au BufNewFile,BufRead *.smithy setf smithy
+" Snakemake
+au BufNewFile,BufRead Snakefile,*.smk setf snakemake
+
" Snobol4 and spitbol
au BufNewFile,BufRead *.sno,*.spt setf snobol4
@@ -2382,6 +2402,9 @@ au BufNewFile,BufRead *.tcl,*.tm,*.tk,*.itcl,*.itk,*.jacl,.tclshrc,.wishrc,.tcls
" Xilinx's xsct and xsdb use tcl
au BufNewFile,BufRead .xsctcmdhistory,.xsdbcmdhistory setf tcl
+" templ
+au BufNewFile,BufRead *.templ setf templ
+
" Teal
au BufRead,BufNewFile *.tl setf teal
@@ -2413,7 +2436,7 @@ au BufNewFile,BufRead texdoc.cnf setf conf
" LaTeX packages will generate some medium LaTeX files during compiling
" They should be ignored by .gitignore https://github.com/github/gitignore/blob/main/TeX.gitignore
" Sometime we need to view its content for debugging
-au BufNewFile,BufRead *.{pgf,nlo,nls,out,thm,eps_tex,pygtex,pygstyle,clo,aux,brf,ind,lof,loe,nav,vrb,ins,tikz,bbx,cbx,beamer} setf tex
+au BufNewFile,BufRead *.{pgf,nlo,nls,thm,eps_tex,pygtex,pygstyle,clo,aux,brf,ind,lof,loe,nav,vrb,ins,tikz,bbx,cbx,beamer} setf tex
" ConTeXt
au BufNewFile,BufRead *.mkii,*.mkiv,*.mkvi,*.mkxl,*.mklx setf context
@@ -2839,6 +2862,10 @@ au StdinReadPost * if !did_filetype() | runtime! scripts.vim | endif
" But before patterns matching everything in a directory.
au BufNewFile,BufRead *.text,README,LICENSE,COPYING,AUTHORS setf text
+" What should *.out files be? Text?
+" Disabled until it is clear, to what this should be set
+"au BufNewFile,BufRead *.out setf text
+
" Extra checks for when no filetype has been detected now. Mostly used for
" patterns that end in "*". E.g., "zsh*" matches "zsh.vim", but that's a Vim
@@ -3010,6 +3037,9 @@ au BufNewFile,BufRead .reminders* call s:StarSetf('remind')
" SGML catalog file
au BufNewFile,BufRead sgml.catalog* call s:StarSetf('catalog')
+" Stylus
+au BufNewFile,BufReadPost *.styl,*.stylus setf stylus
+
" avoid doc files being recognized a shell files
au BufNewFile,BufRead */doc/{,.}bash[_-]completion{,.d,.sh}{,/*} setf text
@@ -3076,6 +3106,15 @@ au BufNewFile,BufRead */etc/yum.repos.d/* call s:StarSetf('dosini')
au BufNewFile,BufRead .zsh*,.zlog*,.zcompdump* call s:StarSetf('zsh')
au BufNewFile,BufRead zsh*,zlog* call s:StarSetf('zsh')
+" Zsh module
+" mdd: https://github.com/zsh-users/zsh/blob/57248b88830ce56adc243a40c7773fb3825cab34/Etc/zsh-development-guide#L285-L288
+" mdh, pro: https://github.com/zsh-users/zsh/blob/57248b88830ce56adc243a40c7773fb3825cab34/Etc/zsh-development-guide#L268-L271
+" *.mdd will generate *.mdh, *.pro and *.epro.
+" module's *.c will #include *.mdh containing module dependency information and
+" *.pro containing all static declarations of *.c
+" *.epro contains all external declarations of *.c
+au BufNewFile,BufRead *.mdh,*.epro setf c
+au BufNewFile,BufRead *.mdd setf sh
" Help files match *.txt but should have a last line that is a modeline.
au BufNewFile,BufRead *.txt
@@ -3114,6 +3153,9 @@ au BufNewFile,BufRead yarn.lock setf yaml
" Zathurarc
au BufNewFile,BufRead zathurarc setf zathurarc
+" Rofi stylesheet
+au BufNewFile,BufRead *.rasi setf rasi
+
" If the GUI is already running, may still need to install the Syntax menu.
" Don't do it when the 'M' flag is included in 'guioptions'.
if has("menu") && has("gui_running")
diff --git a/runtime/ftplugin/abaqus.vim b/runtime/ftplugin/abaqus.vim
index c16e7b0..d4bb6fe 100644
--- a/runtime/ftplugin/abaqus.vim
+++ b/runtime/ftplugin/abaqus.vim
@@ -3,6 +3,7 @@
" Maintainer: Carl Osterwisch <costerwi@gmail.com>
" Last Change: 2022 Oct 08
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin") | finish | endif
@@ -27,7 +28,7 @@ setlocal isfname-=,
" Define format of comment lines (see 'formatoptions' for uses)
setlocal comments=:**
-setlocal commentstring=**%s
+setlocal commentstring=**\ %s
" Definitions start with a * and assign a NAME, NSET, or ELSET
" Used in [d ^wd and other commands
diff --git a/runtime/ftplugin/arduino.vim b/runtime/ftplugin/arduino.vim
new file mode 100644
index 0000000..60b11da
--- /dev/null
+++ b/runtime/ftplugin/arduino.vim
@@ -0,0 +1,67 @@
+" Vim filetype plugin file
+" Language: Arduino
+" Maintainer: The Vim Project <https://github.com/vim/vim>
+" Ken Takata <https://github.com/k-takata>
+" Last Change: 2024 Apr 12
+" 2024 Jun 02 by Riley Bruins <ribru17@gmail.com> ('commentstring')
+"
+" Most of the part was copied from c.vim.
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+ finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Using line continuation here.
+let s:cpo_save = &cpo
+set cpo-=C
+
+let b:undo_ftplugin = "setl fo< com< ofu< cms< def< inc<"
+
+if !exists("g:arduino_recommended_style") || g:arduino_recommended_style != 0
+ " Use the default setting of Arduino IDE.
+ setlocal expandtab tabstop=2 softtabstop=2 shiftwidth=2
+ let b:undo_ftplugin ..= " et< ts< sts< sw<"
+endif
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+setlocal fo-=t fo+=croql
+
+" These options have the right value as default, but the user may have
+" overruled that.
+setlocal commentstring=/*\ %s\ */ define& include&
+
+" Set completion with CTRL-X CTRL-O to autoloaded function.
+if exists('&ofu')
+ setlocal ofu=ccomplete#Complete
+endif
+
+" Set 'comments' to format dashed lists in comments.
+" Also include ///, used for Doxygen.
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,://
+
+" When the matchit plugin is loaded, this makes the % command skip parens and
+" braces in comments properly.
+if !exists("b:match_words")
+ let b:match_words = '^\s*#\s*if\(\|def\|ndef\)\>:^\s*#\s*elif\>:^\s*#\s*else\>:^\s*#\s*endif\>'
+ let b:match_skip = 's:comment\|string\|character\|special'
+ let b:undo_ftplugin ..= " | unlet! b:match_skip b:match_words"
+endif
+
+" Win32 and GTK can filter files in the browse dialog
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+ let b:browsefilter = "Arduino Source Files (*.ino, *.pde)\t*.ino;*.pde\n"
+ if has("win32")
+ let b:browsefilter ..= "All Files (*.*)\t*\n"
+ else
+ let b:browsefilter ..= "All Files (*)\t*\n"
+ endif
+ let b:undo_ftplugin ..= " | unlet! b:browsefilter"
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/runtime/ftplugin/asm.vim b/runtime/ftplugin/asm.vim
index 0ae1610..4482b90 100644
--- a/runtime/ftplugin/asm.vim
+++ b/runtime/ftplugin/asm.vim
@@ -4,13 +4,14 @@
" Last Change: 2020 May 23
" 2023 Aug 28 by Vim Project (undo_ftplugin)
" 2024 Apr 09 by Vim Project (add Matchit support)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
setl include=^\\s*%\\s*include
setl comments=:;,s1:/*,mb:*,ex:*/,://
-setl commentstring=;%s
+setl commentstring=;\ %s
let b:undo_ftplugin = "setl commentstring< comments< include<"
diff --git a/runtime/ftplugin/astro.vim b/runtime/ftplugin/astro.vim
index 0b0e034..5d35ba9 100644
--- a/runtime/ftplugin/astro.vim
+++ b/runtime/ftplugin/astro.vim
@@ -2,6 +2,7 @@
" Language: Astro
" Maintainer: Romain Lafourcade <romainlafourcade@gmail.com>
" Last Change: 2024 Apr 21
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -25,17 +26,17 @@ function! s:AstroComments() abort
\ || s:IdentifyScope('^\s*<script', '^\s*<\/script>')
" ECMAScript comments
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
- setlocal commentstring=//%s
+ setlocal commentstring=//\ %s
elseif s:IdentifyScope('^\s*<style', '^\s*<\/style>')
" CSS comments
setlocal comments=s1:/*,mb:*,ex:*/
- setlocal commentstring=/*%s*/
+ setlocal commentstring=/*\ %s\ */
else
" HTML comments
setlocal comments=s:<!--,m:\ \ \ \ ,e:-->
- setlocal commentstring=<!--%s-->
+ setlocal commentstring=<!--\ %s\ -->
endif
endfunction
diff --git a/runtime/ftplugin/bitbake.vim b/runtime/ftplugin/bitbake.vim
index 99fe334..4d50a7f 100644
--- a/runtime/ftplugin/bitbake.vim
+++ b/runtime/ftplugin/bitbake.vim
@@ -3,13 +3,14 @@
" Maintainer: Gregory Anders <greg@gpanders.com>
" Repository: https://github.com/openembedded/bitbake
" Latest Revision: 2022-07-23
+" 2024-05-23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal comments=:#
setlocal suffixesadd=.bb,.bbclass
diff --git a/runtime/ftplugin/c.vim b/runtime/ftplugin/c.vim
index e2eebc5..378d580 100644
--- a/runtime/ftplugin/c.vim
+++ b/runtime/ftplugin/c.vim
@@ -2,6 +2,7 @@
" Language: C
" Maintainer: The Vim Project <https://github.com/vim/vim>
" Last Change: 2023 Aug 22
+" 2024 Jun 02 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" Only do this when not done yet for this buffer
@@ -24,7 +25,7 @@ setlocal fo-=t fo+=croql
" These options have the right value as default, but the user may have
" overruled that.
-setlocal commentstring& define& include&
+setlocal commentstring=/*\ %s\ */ define& include&
" Set completion with CTRL-X CTRL-O to autoloaded function.
if exists('&ofu')
diff --git a/runtime/ftplugin/calendar.vim b/runtime/ftplugin/calendar.vim
index f454ba1..c4e683a 100644
--- a/runtime/ftplugin/calendar.vim
+++ b/runtime/ftplugin/calendar.vim
@@ -2,6 +2,7 @@
" Language: calendar(1) input file
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
" Latest Revision: 2008-07-09
+" 2024-06-02 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -13,7 +14,7 @@ set cpo&vim
let b:undo_ftplugin = "setl com< cms< inc< fo<"
-setlocal comments=s1:/*,mb:*,ex:*/ commentstring& include&
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */ include&
setlocal formatoptions-=t formatoptions+=croql
let &cpo = s:cpo_save
diff --git a/runtime/ftplugin/cgdbrc.vim b/runtime/ftplugin/cgdbrc.vim
index 46cf135..99f9702 100644
--- a/runtime/ftplugin/cgdbrc.vim
+++ b/runtime/ftplugin/cgdbrc.vim
@@ -3,6 +3,7 @@
" Maintainer: Wu, Zhenyu <wuzhenyu@ustc.edu>
" Documentation: https://cgdb.github.io/docs/Configuring-CGDB.html
" Latest Revision: 2024-04-09
+" 2024-05-23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists('b:did_ftplugin')
finish
@@ -14,7 +15,7 @@ set cpoptions&vim
let b:undo_ftplugin = 'setl com< cms<'
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal comments=:#
let &cpoptions = s:save_cpoptions
diff --git a/runtime/ftplugin/cpp.vim b/runtime/ftplugin/cpp.vim
index fc92935..fac3edd 100644
--- a/runtime/ftplugin/cpp.vim
+++ b/runtime/ftplugin/cpp.vim
@@ -1,7 +1,7 @@
" Vim filetype plugin file
" Language: C++
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2023 Aug 10
+" Last Change: 2024 Jun 06
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" Only do this when not done yet for this buffer
@@ -12,6 +12,10 @@ endif
" Behaves mostly just like C
runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
+" Change 'commentstring' to "C++ style"/"mono-line" comments
+setlocal commentstring=//\ %s
+let b:undo_ftplugin ..= ' | setl commentstring<'
+
" C++ uses templates with <things>
" Disabled, because it gives an error for typing an unmatched ">".
" set matchpairs+=<:>
diff --git a/runtime/ftplugin/csh.vim b/runtime/ftplugin/csh.vim
index a22bee3..74666b9 100644
--- a/runtime/ftplugin/csh.vim
+++ b/runtime/ftplugin/csh.vim
@@ -4,6 +4,7 @@
" Previous Maintainer: Dan Sharp
" Contributor: Johannes Zellner <johannes@zellner.org>
" Last Change: 2024 Jan 14
+" 2024 May 23 by Riley Bruins ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -14,7 +15,7 @@ let s:save_cpo = &cpo
set cpo-=C
setlocal comments=:#
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal formatoptions-=t
setlocal formatoptions+=crql
diff --git a/runtime/ftplugin/css.vim b/runtime/ftplugin/css.vim
index ece2def..778a9e1 100644
--- a/runtime/ftplugin/css.vim
+++ b/runtime/ftplugin/css.vim
@@ -3,6 +3,7 @@
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
" Last Change: 2020 Dec 21
+" 2024 Jun 02 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -14,7 +15,7 @@ set cpo&vim
let b:undo_ftplugin = "setl com< cms< inc< fo< ofu< isk<"
-setlocal comments=s1:/*,mb:*,ex:*/ commentstring&
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */
setlocal formatoptions-=t formatoptions+=croql
setlocal omnifunc=csscomplete#CompleteCSS
setlocal iskeyword+=-
diff --git a/runtime/ftplugin/dart.vim b/runtime/ftplugin/dart.vim
new file mode 100644
index 0000000..42c90c2
--- /dev/null
+++ b/runtime/ftplugin/dart.vim
@@ -0,0 +1,15 @@
+" Vim filetype plugin
+" Language: dart
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 18
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+" Set 'comments' to format dashed lists in comments.
+" Also include ///, used for Doxygen.
+setl comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,:// commentstring=//\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/deb822sources.vim b/runtime/ftplugin/deb822sources.vim
index 4936f42..31c81b1 100644
--- a/runtime/ftplugin/deb822sources.vim
+++ b/runtime/ftplugin/deb822sources.vim
@@ -1,6 +1,6 @@
" Language: Debian sources.list
" Maintainer: Debian Vim Maintainers <team+vim@tracker.debian.org>
-" Last Change: 2024 Mar 20
+" Last Change: 2024 May 25
" License: Vim License
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/ftplugin/deb822sources.vim
@@ -10,7 +10,7 @@ endif
let b:did_ftplugin=1
setlocal comments=:#
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal formatoptions-=t
let b:undo_ftplugin = 'setlocal comments< commentstring< formatoptions<'
diff --git a/runtime/ftplugin/debcontrol.vim b/runtime/ftplugin/debcontrol.vim
index bb710e5..5b8292b 100644
--- a/runtime/ftplugin/debcontrol.vim
+++ b/runtime/ftplugin/debcontrol.vim
@@ -2,7 +2,7 @@
" Language: Debian control files
" Maintainer: Debian Vim Maintainers
" Former Maintainer: Pierre Habouzit <madcoder@debian.org>
-" Last Change: 2023 Jan 16
+" Last Change: 2024 May 25
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/ftplugin/debcontrol.vim
" Do these settings once per buffer
@@ -19,8 +19,11 @@ if exists('g:debcontrol_fold_enable')
endif
setlocal textwidth=0
+setlocal comments=:#
+setlocal commentstring=#\ %s
+
" Clean unloading
-let b:undo_ftplugin = 'setlocal tw< foldmethod< foldexpr< foldtext<'
+let b:undo_ftplugin = 'setlocal tw< foldmethod< foldexpr< foldtext< comments< commentstring<'
" }}}1
diff --git a/runtime/ftplugin/debsources.vim b/runtime/ftplugin/debsources.vim
index cbb4faf..2c5ea35 100644
--- a/runtime/ftplugin/debsources.vim
+++ b/runtime/ftplugin/debsources.vim
@@ -1,6 +1,6 @@
" Language: Debian sources.list
" Maintainer: Debian Vim Maintainers <team+vim@tracker.debian.org>
-" Last Change: 2023 Aug 30
+" Last Change: 2024 May 25
" License: Vim License
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/ftplugin/debsources.vim
@@ -10,7 +10,7 @@ endif
let b:did_ftplugin=1
setlocal comments=:#
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal formatoptions-=t
let b:undo_ftplugin = 'setlocal comments< commentstring< formatoptions<'
diff --git a/runtime/ftplugin/desktop.vim b/runtime/ftplugin/desktop.vim
index bd6fd70..d15afd2 100644
--- a/runtime/ftplugin/desktop.vim
+++ b/runtime/ftplugin/desktop.vim
@@ -2,6 +2,7 @@
" Language: XDG desktop entry
" Maintainer: Eisuke Kawashima ( e.kawaschima+vim AT gmail.com )
" Last Change: 2022-07-26
+" 2024-05-24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists('b:did_ftplugin')
finish
@@ -9,5 +10,5 @@ endif
let b:did_ftplugin = v:true
setl comments=:#
-setl commentstring=#%s
+setl commentstring=#\ %s
let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/dtd.vim b/runtime/ftplugin/dtd.vim
index bea8c5c..f970148 100644
--- a/runtime/ftplugin/dtd.vim
+++ b/runtime/ftplugin/dtd.vim
@@ -6,6 +6,7 @@
" Former maintainer: Dan Sharp
" Last Change: 2009 Jan 20
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
@@ -15,7 +16,7 @@ let b:did_ftplugin = 1
let s:save_cpo = &cpo
set cpo-=C
-setlocal commentstring=<!--%s-->
+setlocal commentstring=<!--\ %s\ -->
setlocal comments=s:<!--,m:\ \ \ \ \ ,e:-->
setlocal formatoptions-=t
diff --git a/runtime/ftplugin/dtrace.vim b/runtime/ftplugin/dtrace.vim
index 9288097..a276b31 100644
--- a/runtime/ftplugin/dtrace.vim
+++ b/runtime/ftplugin/dtrace.vim
@@ -1,6 +1,7 @@
" Language: D script as described in "Solaris Dynamic Tracing Guide",
" http://docs.sun.com/app/docs/doc/817-6223
" Last Change: 2008/03/20
+" 2024/05/23 by Riley Bruins <ribru17@gmail.com ('commentstring')
" Version: 1.2
" Maintainer: Nicolas Weber <nicolasweber@gmx.de>
@@ -26,8 +27,8 @@ setlocal fo-=t fo+=croql
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/
" dtrace uses /* */ comments. Set this explicitly, just in case the user
-" changed this (/*%s*/ is the default)
-setlocal commentstring=/*%s*/
+" changed this (/*\ %s\ */ is the default)
+setlocal commentstring=/*\ %s\ */
setlocal iskeyword+=@,$
diff --git a/runtime/ftplugin/dts.vim b/runtime/ftplugin/dts.vim
index 42e3833..346ff94 100644
--- a/runtime/ftplugin/dts.vim
+++ b/runtime/ftplugin/dts.vim
@@ -2,6 +2,7 @@
" Language: dts/dtsi (device tree files)
" Maintainer: Wu, Zhenyu <wuzhenyu@ustc.edu>
" Latest Revision: 2024 Apr 12
+" 2024 Jun 02 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists('b:did_ftplugin')
finish
@@ -12,5 +13,5 @@ let b:undo_ftplugin = 'setl inc< cms< com<'
setlocal include=^\\%(#include\\\|/include/\\)
" same as C
-setlocal commentstring&
+setlocal commentstring=/*\ %s\ */
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,://
diff --git a/runtime/ftplugin/erlang.vim b/runtime/ftplugin/erlang.vim
index 1cb57f4..5a3ab71 100644
--- a/runtime/ftplugin/erlang.vim
+++ b/runtime/ftplugin/erlang.vim
@@ -6,7 +6,8 @@
" Eduardo Lopez (http://github.com/tapichu)
" Arvid Bjurklint (http://github.com/slarwise)
" Paweł Zacharek (http://github.com/subc2)
-" Last Update: 2023-Dec-20
+" Riley Bruins (http://github.com/ribru17) ('commentstring')
+" Last Update: 2024 May 23
" License: Vim license
" URL: https://github.com/vim-erlang/vim-erlang-runtime
@@ -27,7 +28,7 @@ if get(g:, 'erlang_folding', 0)
endif
setlocal comments=:%%%,:%%,:%
-setlocal commentstring=%%s
+setlocal commentstring=%\ %s
setlocal formatoptions+=ro
diff --git a/runtime/ftplugin/eruby.vim b/runtime/ftplugin/eruby.vim
index b5c4665..b3e074a 100644
--- a/runtime/ftplugin/eruby.vim
+++ b/runtime/ftplugin/eruby.vim
@@ -5,6 +5,7 @@
" Release Coordinator: Doug Kearns <dougkearns@gmail.com>
" Last Change: 2022 May 15
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -125,7 +126,7 @@ if exists("loaded_matchit")
endif
" TODO: comments=
-setlocal commentstring=<%#%s%>
+setlocal commentstring=<%#\ %s\ %>
let b:undo_ftplugin = "setl cms< " .
\ " | unlet! b:browsefilter b:match_words | " . b:undo_ftplugin
diff --git a/runtime/ftplugin/fennel.vim b/runtime/ftplugin/fennel.vim
index 93cf366..2a9623f 100644
--- a/runtime/ftplugin/fennel.vim
+++ b/runtime/ftplugin/fennel.vim
@@ -2,13 +2,14 @@
" Language: Fennel
" Maintainer: Gregory Anders <greg[NOSPAM]@gpanders.com>
" Last Update: 2023 Jun 9
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists('b:did_ftplugin')
finish
endif
let b:did_ftplugin = 1
-setlocal commentstring=;%s
+setlocal commentstring=;\ %s
setlocal comments=:;;,:;
setlocal formatoptions-=t
setlocal suffixesadd=.fnl
diff --git a/runtime/ftplugin/fish.vim b/runtime/ftplugin/fish.vim
index f06ad3a..55d7ea8 100644
--- a/runtime/ftplugin/fish.vim
+++ b/runtime/ftplugin/fish.vim
@@ -4,6 +4,7 @@
" Repository: https://github.com/nickeb96/fish.vim
" Last Change: February 1, 2023
" 2023 Aug 28 by Vim Project (undo_ftplugin)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -12,7 +13,7 @@ let b:did_ftplugin = 1
setlocal iskeyword=@,48-57,_,192-255,-,.
setlocal comments=:#
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal formatoptions+=crjq
let b:undo_ftplugin = "setl cms< com< fo< isk<"
diff --git a/runtime/ftplugin/fortran.vim b/runtime/ftplugin/fortran.vim
index 3c32581..19a4c1e 100644
--- a/runtime/ftplugin/fortran.vim
+++ b/runtime/ftplugin/fortran.vim
@@ -11,6 +11,7 @@
" Doug Kearns, and Fritz Reese.
" Last Change: 2023 Dec 22
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do these settings when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -89,7 +90,7 @@ else
endif
" Set commentstring for foldmethod=marker
-setlocal cms=!%s
+setlocal cms=!\ %s
" Tabs are not a good idea in Fortran so the default is to expand tabs
if !exists("fortran_have_tabs")
diff --git a/runtime/ftplugin/fstab.vim b/runtime/ftplugin/fstab.vim
index 9980532..0e7ffda 100644
--- a/runtime/ftplugin/fstab.vim
+++ b/runtime/ftplugin/fstab.vim
@@ -3,6 +3,7 @@
" Maintainer: Radu Dineiu <radu.dineiu@gmail.com>
" URL: https://raw.github.com/rid9/vim-fstab/master/ftplugin/fstab.vim
" Last Change: 2021 Jan 02
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Version: 1.0
"
" Credits:
@@ -13,7 +14,7 @@ if exists("b:did_ftplugin")
endif
let b:did_ftplugin = 1
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
let b:undo_ftplugin = "setlocal commentstring<"
" vim: ts=8 ft=vim
diff --git a/runtime/ftplugin/gdb.vim b/runtime/ftplugin/gdb.vim
index 7c10633..af88a04 100644
--- a/runtime/ftplugin/gdb.vim
+++ b/runtime/ftplugin/gdb.vim
@@ -3,11 +3,12 @@
" Maintainer: Michaël Peeters <NOSPAMm.vim@noekeon.org>
" Last Changed: 2017-10-26
" 2024-04-10: - add Matchit support (by Vim Project)
+" 2024-04-23: - add space to commentstring (by Riley Bruins) ('commentstring')
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal include=^\\s*source
" Undo the stuff we changed.
diff --git a/runtime/ftplugin/graphql.vim b/runtime/ftplugin/graphql.vim
new file mode 100644
index 0000000..56f6e36
--- /dev/null
+++ b/runtime/ftplugin/graphql.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: graphql
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 18
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=:# commentstring=#\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/groovy.vim b/runtime/ftplugin/groovy.vim
index cc7d6e3..a2e2b2f 100644
--- a/runtime/ftplugin/groovy.vim
+++ b/runtime/ftplugin/groovy.vim
@@ -2,6 +2,7 @@
" Language: groovy
" Maintainer: Justin M. Keyes <justinkz@gmail.com>
" Last Change: 2016 May 22
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists('b:did_ftplugin')
finish
@@ -13,7 +14,7 @@ set cpo-=C
let b:undo_ftplugin = 'setlocal commentstring<'
-setlocal commentstring=//%s
+setlocal commentstring=//\ %s
let &cpo = s:cpo_save
unlet s:cpo_save
diff --git a/runtime/ftplugin/hamster.vim b/runtime/ftplugin/hamster.vim
index 5446e72..904f267 100644
--- a/runtime/ftplugin/hamster.vim
+++ b/runtime/ftplugin/hamster.vim
@@ -3,6 +3,7 @@
" Version: 2.0.6.0
" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
" Last Change: 2021 Jan 19
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -31,7 +32,7 @@ if &tw == 0
endif
" Comments start with a double quote
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
" Move around functions.
noremap <silent><buffer> [[ :call search('^\s*sub\>', "bW")<CR>
diff --git a/runtime/ftplugin/hare.vim b/runtime/ftplugin/hare.vim
index 0200ba5..422bb7b 100644
--- a/runtime/ftplugin/hare.vim
+++ b/runtime/ftplugin/hare.vim
@@ -1,35 +1,59 @@
-" Vim filetype plugin
-" Language: Hare
-" Maintainer: Amelia Clarke <me@rsaihe.dev>
-" Previous Maintainer: Drew DeVault <sir@cmpwn.com>
-" Last Updated: 2022-09-28
-" 2023 Aug 28 by Vim Project (undo_ftplugin)
+" Vim filetype plugin.
+" Language: Hare
+" Maintainer: Amelia Clarke <selene@perilune.dev>
+" Last Updated: 2024-05-10
+" Upstream: https://git.sr.ht/~sircmpwn/hare.vim
if exists('b:did_ftplugin')
finish
endif
let b:did_ftplugin = 1
-" Formatting settings.
-setlocal formatoptions-=t formatoptions+=croql/
+let s:cpo_save = &cpo
+set cpo&vim
+
+" Set the default compiler.
+compiler hare
-" Miscellaneous.
+" Formatting settings.
setlocal comments=://
setlocal commentstring=//\ %s
+setlocal formatlistpat=^\ \\?-\
+setlocal formatoptions+=croqnlj/ formatoptions-=t
+
+" Search for Hare modules.
+setlocal include=^\\s*use\\>
+setlocal includeexpr=hare#FindModule(v:fname)
+setlocal isfname+=:
setlocal suffixesadd=.ha
-let b:undo_ftplugin = "setl cms< com< fo< sua<"
+" Add HAREPATH to the default search paths.
+setlocal path-=/usr/include,,
+let &l:path .= ',' .. hare#GetPath() .. ',,'
-" Hare recommended style.
-if get(g:, "hare_recommended_style", 1)
+let b:undo_ftplugin = 'setl cms< com< flp< fo< inc< inex< isf< pa< sua< mp<'
+
+" Follow the Hare style guide by default.
+if get(g:, 'hare_recommended_style', 1)
setlocal noexpandtab
- setlocal shiftwidth=8
+ setlocal shiftwidth=0
setlocal softtabstop=0
setlocal tabstop=8
setlocal textwidth=80
- let b:undo_ftplugin ..= " | setl et< sts< sw< ts< tw<"
+ let b:undo_ftplugin .= ' et< sts< sw< ts< tw<'
endif
-compiler hare
+augroup hare.vim
+ autocmd!
+
+ " Highlight whitespace errors by default.
+ if get(g:, 'hare_space_error', 1)
+ autocmd InsertEnter * hi link hareSpaceError NONE
+ autocmd InsertLeave * hi link hareSpaceError Error
+ endif
+augroup END
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
-" vim: et sw=2 sts=2 ts=8
+" vim: et sts=2 sw=2 ts=8
diff --git a/runtime/ftplugin/haredoc.vim b/runtime/ftplugin/haredoc.vim
new file mode 100644
index 0000000..69030b4
--- /dev/null
+++ b/runtime/ftplugin/haredoc.vim
@@ -0,0 +1,44 @@
+" Vim filetype plugin.
+" Language: Haredoc (Hare documentation format)
+" Maintainer: Amelia Clarke <selene@perilune.dev>
+" Last Updated: 2024-05-02
+" Upstream: https://git.sr.ht/~selene/hare.vim
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" Formatting settings.
+setlocal comments=:\
+setlocal formatlistpat=^\ \\?-\
+setlocal formatoptions+=tnlj formatoptions-=c formatoptions-=q
+
+" Search for Hare modules.
+setlocal includeexpr=hare#FindModule(v:fname)
+setlocal isfname+=:
+setlocal suffixesadd=.ha
+
+" Add HAREPATH to the default search paths.
+setlocal path-=/usr/include,,
+let &l:path .= ',' .. hare#GetPath() .. ',,'
+
+let b:undo_ftplugin = 'setl com< flp< fo< inex< isf< pa< sua<'
+
+" Follow the Hare style guide by default.
+if get(g:, 'hare_recommended_style', 1)
+ setlocal noexpandtab
+ setlocal shiftwidth=0
+ setlocal softtabstop=0
+ setlocal tabstop=8
+ setlocal textwidth=80
+ let b:undo_ftplugin .= ' et< sts< sw< ts< tw<'
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: et sts=2 sw=2 ts=8
diff --git a/runtime/ftplugin/html.vim b/runtime/ftplugin/html.vim
index 3aa60a8..5495f85 100644
--- a/runtime/ftplugin/html.vim
+++ b/runtime/ftplugin/html.vim
@@ -3,6 +3,7 @@
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Previous Maintainer: Dan Sharp
" Last Change: 2024 Jan 14
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -13,7 +14,7 @@ let s:save_cpo = &cpo
set cpo-=C
setlocal matchpairs+=<:>
-setlocal commentstring=<!--%s-->
+setlocal commentstring=<!--\ %s\ -->
setlocal comments=s:<!--,m:\ \ \ \ ,e:-->
let b:undo_ftplugin = "setlocal comments< commentstring< matchpairs<"
diff --git a/runtime/ftplugin/hyprlang.vim b/runtime/ftplugin/hyprlang.vim
new file mode 100644
index 0000000..5c186c3
--- /dev/null
+++ b/runtime/ftplugin/hyprlang.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: hyprlang
+" Maintainer: ribru17 <ribru17@gmail.com>
+" Last Change: 2024 May 18
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=:# commentstring=#\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/indent.vim b/runtime/ftplugin/indent.vim
index 64a650a..32208d3 100644
--- a/runtime/ftplugin/indent.vim
+++ b/runtime/ftplugin/indent.vim
@@ -3,6 +3,7 @@
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
" Latest Revision: 2008-07-09
+" 2024-06-02 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -14,7 +15,7 @@ set cpo&vim
let b:undo_ftplugin = "setl com< cms< fo<"
-setlocal comments=s1:/*,mb:*,ex:*/ commentstring&
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */
setlocal formatoptions-=t formatoptions+=croql
let &cpo = s:cpo_save
diff --git a/runtime/ftplugin/initex.vim b/runtime/ftplugin/initex.vim
index 0ee3e8d..71049df 100644
--- a/runtime/ftplugin/initex.vim
+++ b/runtime/ftplugin/initex.vim
@@ -3,6 +3,7 @@
" Maintainer: Benji Fisher, Ph.D. <benji@member.AMS.org>
" Version: 1.0
" Last Change: Wed 19 Apr 2006
+" Last Change: Thu 23 May 2024 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer.
if exists("b:did_ftplugin")
@@ -23,7 +24,7 @@ setlocal com=sO:%\ -,mO:%\ \ ,eO:%%,:%
" Set 'commentstring' to recognize the % comment character:
" (Thanks to Ajit Thakkar.)
-setlocal cms=%%s
+setlocal cms=%\ %s
" Allow "[d" to be used to find a macro definition:
let &l:define='\\\([egx]\|char\|mathchar\|count\|dimen\|muskip\|skip\|toks\)\='
diff --git a/runtime/ftplugin/java.vim b/runtime/ftplugin/java.vim
index fa2b610..eee7ef0 100644
--- a/runtime/ftplugin/java.vim
+++ b/runtime/ftplugin/java.vim
@@ -5,6 +5,7 @@
" Repository: https://github.com/zzzyxwvut/java-vim.git
" Last Change: 2024 Apr 18
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
@@ -61,7 +62,7 @@ setlocal formatoptions-=t formatoptions+=croql
" Set 'comments' to format dashed lists in comments. Behaves just like C.
setlocal comments& comments^=sO:*\ -,mO:*\ \ ,exO:*/
-setlocal commentstring=//%s
+setlocal commentstring=//\ %s
" Change the :browse e filter to primarily show Java-related files.
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
diff --git a/runtime/ftplugin/javascript.vim b/runtime/ftplugin/javascript.vim
index 2633954..455b794 100644
--- a/runtime/ftplugin/javascript.vim
+++ b/runtime/ftplugin/javascript.vim
@@ -3,6 +3,7 @@
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Contributor: Romain Lafourcade <romainlafourcade@gmail.com>
" Last Change: 2024 Jan 14
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -24,7 +25,7 @@ endif
" Set 'comments' to format dashed lists in comments.
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
-setlocal commentstring=//%s
+setlocal commentstring=//\ %s
" Change the :browse e filter to primarily show JavaScript-related files.
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
diff --git a/runtime/ftplugin/jj.vim b/runtime/ftplugin/jj.vim
new file mode 100644
index 0000000..cc5d700
--- /dev/null
+++ b/runtime/ftplugin/jj.vim
@@ -0,0 +1,19 @@
+" Vim filetype plugin
+" Language: jj description
+" Maintainer: Gregory Anders <greg@gpanders.com>
+" Last Change: 2024 May 8
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+" Use the same formatoptions and textwidth as the gitcommit ftplugin
+setlocal nomodeline formatoptions+=tl textwidth=72
+setlocal formatoptions-=c formatoptions-=r formatoptions-=o formatoptions-=q formatoptions+=n
+setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}]\\s\\+\\\|^\\s*[-*+]\\s\\+
+
+setlocal comments=b:JJ:
+setlocal commentstring=JJ:\ %s
+
+let b:undo_ftplugin = 'setl modeline< formatoptions< textwidth< formatlistpat< comments< commentstring<'
diff --git a/runtime/ftplugin/jq.vim b/runtime/ftplugin/jq.vim
index 15cd400..d258836 100644
--- a/runtime/ftplugin/jq.vim
+++ b/runtime/ftplugin/jq.vim
@@ -1,7 +1,8 @@
" Vim compiler file
" Language: jq
" Maintainer: Vito <vito.blog@gmail.com>
-" Last Change: 2024 Apr 17
+" Last Change: 2024 Apr 29
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Upstream: https://github.com/vito-c/jq.vim
if exists('b:did_ftplugin')
@@ -9,10 +10,8 @@ if exists('b:did_ftplugin')
endif
let b:did_ftplugin = 1
-let b:undo_ftplugin = 'setl commentstring<'
-
-setlocal commentstring=#%s
+setlocal include=^\\s*\\%(import\\\|include\\)
+setlocal commentstring=#\ %s
compiler jq
-let &cpoptions = s:save_cpoptions
-unlet s:save_cpoptions
+let b:undo_ftplugin = 'setl commentstring< include<'
diff --git a/runtime/ftplugin/jsonc.vim b/runtime/ftplugin/jsonc.vim
index e47a75f..ec32684 100644
--- a/runtime/ftplugin/jsonc.vim
+++ b/runtime/ftplugin/jsonc.vim
@@ -5,6 +5,7 @@
" https://github.com/kevinoid/vim-jsonc
" License: MIT
" Last Change: 2021 Nov 22
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
runtime! ftplugin/json.vim
@@ -15,7 +16,7 @@ else
endif
" Set comment (formatting) related options. {{{1
-setlocal commentstring=//%s comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+setlocal commentstring=//\ %s comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
" Let Vim know how to disable the plug-in.
let b:undo_ftplugin = 'setlocal commentstring< comments<'
diff --git a/runtime/ftplugin/kdl.vim b/runtime/ftplugin/kdl.vim
new file mode 100644
index 0000000..c9a1d8b
--- /dev/null
+++ b/runtime/ftplugin/kdl.vim
@@ -0,0 +1,17 @@
+" Vim filetype plugin
+" Language: KDL
+" Author: Aram Drevekenin <aram@poor.dev>
+" Maintainer: Yinzuo Jiang <jiangyinzuo@foxmail.com>
+" Last Change: 2024-06-10
+
+if exists("b:did_ftplugin")
+ finish
+endif
+
+let b:did_ftplugin = 1
+
+setlocal comments=://
+setlocal commentstring=//\ %s
+setlocal formatoptions-=t
+
+let b:undo_ftplugin = 'setlocal comments< commentstring< formatoptions<'
diff --git a/runtime/ftplugin/lc.vim b/runtime/ftplugin/lc.vim
new file mode 100644
index 0000000..e818f1a
--- /dev/null
+++ b/runtime/ftplugin/lc.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: Elsa
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 25
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=:-- commentstring=--\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/ld.vim b/runtime/ftplugin/ld.vim
index 1ab80d5..9cc70bd 100644
--- a/runtime/ftplugin/ld.vim
+++ b/runtime/ftplugin/ld.vim
@@ -1,7 +1,8 @@
" Vim filetype plugin file
" Language: ld(1) script
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2008-07-09
+" Latest Revision: 2008 Jul 09
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -13,7 +14,7 @@ set cpo&vim
let b:undo_ftplugin = "setl com< cms< inc< fo<"
-setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*%s*/ include=^\\s*INCLUDE
+setlocal comments=s1:/*,mb:*,ex:*/ commentstring=/*\ %s\ */ include=^\\s*INCLUDE
setlocal formatoptions-=t formatoptions+=croql
let &cpo = s:cpo_save
diff --git a/runtime/ftplugin/liquid.vim b/runtime/ftplugin/liquid.vim
index f24ec4c..dbd8abe 100644
--- a/runtime/ftplugin/liquid.vim
+++ b/runtime/ftplugin/liquid.vim
@@ -2,6 +2,7 @@
" Language: Liquid
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
" Last Change: 2022 Mar 15
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists('b:did_ftplugin')
finish
@@ -56,6 +57,6 @@ if exists('loaded_matchit')
let b:match_words .= '\<\%(if\w*\|unless\|case\)\>:\<\%(elsif\|else\|when\)\>:\<end\%(if\w*\|unless\|case\)\>,\<\%(for\|tablerow\)\>:\%({%\s*\)\@<=empty\>:\<end\%(for\|tablerow\)\>,\<\(capture\|comment\|highlight\)\>:\<end\1\>'
endif
-setlocal commentstring={%\ comment\ %}%s{%\ endcomment\ %}
+setlocal commentstring={%\ comment\ %}\ %s\ {%\ endcomment\ %}
let b:undo_ftplugin .= 'setl cms< | unlet! b:browsefilter b:match_words'
diff --git a/runtime/ftplugin/lisp.vim b/runtime/ftplugin/lisp.vim
index db3ac96..fe3c6fe 100644
--- a/runtime/ftplugin/lisp.vim
+++ b/runtime/ftplugin/lisp.vim
@@ -5,6 +5,7 @@
" Original author: Dorai Sitaram <ds26@gte.com>
" Original URL: http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html
" Last Change: Mar 10, 2021
+" May 23, 2024 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -19,6 +20,6 @@ setl define=^\\s*(def\\k*
setl formatoptions-=t
setl iskeyword+=+,-,*,/,%,<,=,>,:,$,?,!,@-@,94
setl lisp
-setl commentstring=;%s
+setl commentstring=;\ %s
let b:undo_ftplugin = "setlocal comments< define< formatoptions< iskeyword< lisp< commentstring<"
diff --git a/runtime/ftplugin/man.vim b/runtime/ftplugin/man.vim
index a2c33bc..91e8a8b 100644
--- a/runtime/ftplugin/man.vim
+++ b/runtime/ftplugin/man.vim
@@ -3,7 +3,7 @@
" Maintainer: Jason Franklin <vim@justemail.net>
" Maintainer: SungHyun Nam <goweol@gmail.com>
" Autoload Split: Bram Moolenaar
-" Last Change: 2023 Mar 21
+" Last Change: 2024 Jun 06 (disabled the q mapping, #8210)
" To make the ":Man" command available before editing a manual page, source
" this script from your startup vimrc file.
@@ -39,14 +39,16 @@ if &filetype == "man"
nnoremap <buffer> <silent> <c-]> :call dist#man#PreGetPage(v:count)<CR>
nnoremap <buffer> <silent> <c-t> :call dist#man#PopPage()<CR>
- nnoremap <buffer> <silent> q :q<CR>
+ " Disabled, since this hides the ability to record a macro or use the
+ " command line window
+ " nnoremap <buffer> <silent> q :q<CR>
" Add undo commands for the maps
let b:undo_ftplugin = b:undo_ftplugin
\ . '|silent! nunmap <buffer> <Plug>ManBS'
\ . '|silent! nunmap <buffer> <c-]>'
\ . '|silent! nunmap <buffer> <c-t>'
- \ . '|silent! nunmap <buffer> q'
+ "\ . '|silent! nunmap <buffer> q'
endif
if exists('g:ft_man_folding_enable') && (g:ft_man_folding_enable == 1)
diff --git a/runtime/ftplugin/markdown.vim b/runtime/ftplugin/markdown.vim
index 022dd0d..d4ee5ac 100644
--- a/runtime/ftplugin/markdown.vim
+++ b/runtime/ftplugin/markdown.vim
@@ -2,6 +2,7 @@
" Language: Markdown
" Maintainer: Tim Pope <https://github.com/tpope/vim-markdown>
" Last Change: 2023 Dec 28
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -12,7 +13,7 @@ runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
let s:keepcpo= &cpo
set cpo&vim
-setlocal comments=fb:*,fb:-,fb:+,n:> commentstring=<!--%s-->
+setlocal comments=fb:*,fb:-,fb:+,n:> commentstring=<!--\ %s\ -->
setlocal formatoptions+=tcqln formatoptions-=r formatoptions-=o
setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\|^\\s*[-*+]\\s\\+\\\|^\\[^\\ze[^\\]]\\+\\]:\\&^.\\{4\\}
diff --git a/runtime/ftplugin/mma.vim b/runtime/ftplugin/mma.vim
index ce4cee1..91a8111 100644
--- a/runtime/ftplugin/mma.vim
+++ b/runtime/ftplugin/mma.vim
@@ -1,7 +1,8 @@
" Vim filetype plugin file
" Language: Mathematica
" Maintainer: Ian Ford <ianf@wolfram.com>
-" Last Change: 22 January 2019
+" Last Change: 2019 Jan 22
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -13,4 +14,4 @@ let b:did_ftplugin = 1
let b:undo_ftplugin = "setlocal commentstring<"
-setlocal commentstring=\(*%s*\)
+setlocal commentstring=\(*\ %s\ *\)
diff --git a/runtime/ftplugin/modula2.vim b/runtime/ftplugin/modula2.vim
index 9c1acc2..306688d 100644
--- a/runtime/ftplugin/modula2.vim
+++ b/runtime/ftplugin/modula2.vim
@@ -2,6 +2,7 @@
" Language: Modula-2
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Last Change: 2024 Jan 14
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -17,7 +18,7 @@ if s:dialect ==# "r10"
setlocal comments=s:(*,m:\ ,e:*),:!
setlocal commentstring=!\ %s
else
- setlocal commentstring=(*%s*)
+ setlocal commentstring=(*\ %s\ *)
setlocal comments=s:(*,m:\ ,e:*)
endif
setlocal formatoptions-=t formatoptions+=croql
diff --git a/runtime/ftplugin/modula3.vim b/runtime/ftplugin/modula3.vim
index 45dd7ca..f899d1d 100644
--- a/runtime/ftplugin/modula3.vim
+++ b/runtime/ftplugin/modula3.vim
@@ -2,6 +2,7 @@
" Language: Modula-3
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Last Change: 2024 Jan 14
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -12,7 +13,7 @@ let s:cpo_save = &cpo
set cpo&vim
setlocal comments=s0:(*,mb:\ ,ex:*)
-setlocal commentstring=(*%s*)
+setlocal commentstring=(*\ %s\ *)
setlocal formatoptions-=t formatoptions+=croql
setlocal suffixesadd+=.m3
setlocal formatprg=m3pp
diff --git a/runtime/ftplugin/nim.vim b/runtime/ftplugin/nim.vim
new file mode 100644
index 0000000..4ab8b7b
--- /dev/null
+++ b/runtime/ftplugin/nim.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: nim
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 19
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=exO:]#,fs1:#[,mb:*,ex:]#,:# commentstring=#\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/nroff.vim b/runtime/ftplugin/nroff.vim
index cf62d02..ed0b32f 100644
--- a/runtime/ftplugin/nroff.vim
+++ b/runtime/ftplugin/nroff.vim
@@ -2,15 +2,15 @@
" Language: roff(7)
" Maintainer: Aman Verma
" Homepage: https://github.com/a-vrma/vim-nroff-ftplugin
-" Previous Maintainer: Chris Spiegel <cspiegel@gmail.com>
-" Last Change: 2020 Nov 21
+" Previous Maintainer: Chris Spiegel <cspiegel@gmail.com>
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
-setlocal commentstring=.\\\"%s
+setlocal commentstring=.\\\"\ %s
setlocal comments=:.\\\"
setlocal sections+=Sh
diff --git a/runtime/ftplugin/obse.vim b/runtime/ftplugin/obse.vim
index 6d865f0..bf5076f 100644
--- a/runtime/ftplugin/obse.vim
+++ b/runtime/ftplugin/obse.vim
@@ -2,8 +2,9 @@
" Language: Oblivion Language (obl)
" Original Creator: Kat <katisntgood@gmail.com>
" Maintainer: Kat <katisntgood@gmail.com>
-" Created: August 08, 2021
-" Last Change: 13 November 2022
+" Created: 2021 Aug 08
+" Last Change: 2022 Nov 13
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -20,7 +21,7 @@ noremap <script> <buffer> <silent> ]] <nop>
noremap <script> <buffer> <silent> [] <nop>
noremap <script> <buffer> <silent> ][ <nop>
-setlocal commentstring=;%s
+setlocal commentstring=;\ %s
setlocal comments=:;
function s:NextSection(type, backwards, visual)
diff --git a/runtime/ftplugin/ocaml.vim b/runtime/ftplugin/ocaml.vim
index 20172c9..8b88d8d 100644
--- a/runtime/ftplugin/ocaml.vim
+++ b/runtime/ftplugin/ocaml.vim
@@ -5,12 +5,14 @@
" Pierre Vittet <pierre-vittet@pvittet.com>
" Stefano Zacchiroli <zack@bononia.it>
" Vincent Aravantinos <firstname.name@imag.fr>
+" Riley Bruins <ribru17@gmail.com> ('commentstring')
" URL: https://github.com/ocaml/vim-ocaml
" Last Change:
" 2013 Oct 27 - Added commentstring (MM)
" 2013 Jul 26 - load default compiler settings (MM)
" 2013 Jul 24 - removed superfluous efm-setting (MM)
" 2013 Jul 22 - applied fixes supplied by Hirotaka Hamada (MM)
+" 2024 May 23 - added space in commentstring (RB)
if exists("b:did_ftplugin")
finish
@@ -40,7 +42,7 @@ set cpo&vim
" Comment string
setlocal comments=sr:(*\ ,mb:\ ,ex:*)
setlocal comments^=sr:(**,mb:\ \ ,ex:*)
-setlocal commentstring=(*%s*)
+setlocal commentstring=(*\ %s\ *)
" Add mappings, unless the user didn't want this.
if !exists("no_plugin_maps") && !exists("no_ocaml_maps")
diff --git a/runtime/ftplugin/odin.vim b/runtime/ftplugin/odin.vim
index 9d94a57..c0ad262 100644
--- a/runtime/ftplugin/odin.vim
+++ b/runtime/ftplugin/odin.vim
@@ -1,10 +1,11 @@
vim9script
# Vim filetype plugin file
-# Language: Odin
-# Maintainer: Maxim Kim <habamax@gmail.com>
-# Website: https://github.com/habamax/vim-odin
-# Last Change: 2024-01-15
+# Language: Odin
+# Maintainer: Maxim Kim <habamax@gmail.com>
+# Website: https://github.com/habamax/vim-odin
+# Last Change: 2024 Jan 15
+# 2024-May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -16,5 +17,5 @@ b:undo_ftplugin = 'setlocal commentstring<'
\ .. '| setlocal suffixesadd<'
setlocal suffixesadd=.odin
-setlocal commentstring=//%s
+setlocal commentstring=//\ %s
setlocal comments=s1:/*,mb:*,ex:*/,://
diff --git a/runtime/ftplugin/openvpn.vim b/runtime/ftplugin/openvpn.vim
index 56c0f25..9cd7b7a 100644
--- a/runtime/ftplugin/openvpn.vim
+++ b/runtime/ftplugin/openvpn.vim
@@ -2,6 +2,7 @@
" Language: OpenVPN
" Maintainer: ObserverOfTime <chronobserver@disroot.org>
" Last Change: 2022 Oct 16
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists('b:did_ftplugin')
finish
@@ -9,6 +10,6 @@ endif
let b:did_ftplugin = 1
setlocal iskeyword+=-,.,/
-setlocal comments=:#,:; commentstring=#%s
+setlocal comments=:#,:; commentstring=#\ %s
let b:undo_ftplugin = 'setl isk< com< cms<'
diff --git a/runtime/ftplugin/pascal.vim b/runtime/ftplugin/pascal.vim
index 9abd7dd..7c800c4 100644
--- a/runtime/ftplugin/pascal.vim
+++ b/runtime/ftplugin/pascal.vim
@@ -3,6 +3,7 @@
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Previous Maintainer: Dan Sharp
" Last Change: 2024 Jan 14
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
@@ -11,7 +12,7 @@ let s:cpo_save = &cpo
set cpo&vim
set comments=s:(*,m:\ ,e:*),s:{,m:\ ,e:}
-set commentstring={%s}
+set commentstring={\ %s\ }
if exists("pascal_delphi")
set comments+=:///
diff --git a/runtime/ftplugin/pdf.vim b/runtime/ftplugin/pdf.vim
index 1ed9911..96c77c8 100644
--- a/runtime/ftplugin/pdf.vim
+++ b/runtime/ftplugin/pdf.vim
@@ -2,13 +2,14 @@
" Language: PDF
" Maintainer: Tim Pope <vimNOSPAM@tpope.info>
" Last Change: 2007 Dec 16
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
-setlocal commentstring=%%s
+setlocal commentstring=%\ %s
setlocal comments=:%
let b:undo_ftplugin = "setlocal cms< com< | unlet! b:match_words"
diff --git a/runtime/ftplugin/perl.vim b/runtime/ftplugin/perl.vim
index 8c6a80e..03368a7 100644
--- a/runtime/ftplugin/perl.vim
+++ b/runtime/ftplugin/perl.vim
@@ -8,6 +8,7 @@
" 2023 Sep 07 by Vim Project (safety check: don't execute perl
" from current directory)
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
@@ -22,7 +23,7 @@ setlocal formatoptions+=crqol
setlocal keywordprg=perldoc\ -f
setlocal comments=:#
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
" Provided by Ned Konz <ned at bike-nomad dot com>
"---------------------------------------------
diff --git a/runtime/ftplugin/php.vim b/runtime/ftplugin/php.vim
index f03f145..e124961 100644
--- a/runtime/ftplugin/php.vim
+++ b/runtime/ftplugin/php.vim
@@ -3,6 +3,7 @@
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Previous Maintainer: Dan Sharp
" Last Change: 2024 Jan 14
+" Last Change: 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -44,7 +45,7 @@ if exists("b:match_skip")
endif
setlocal comments=s1:/*,mb:*,ex:*/,://,:#
-setlocal commentstring=/*%s*/
+setlocal commentstring=/*\ %s\ */
setlocal formatoptions+=l formatoptions-=t
if get(g:, "php_autocomment", 1)
diff --git a/runtime/ftplugin/prisma.vim b/runtime/ftplugin/prisma.vim
new file mode 100644
index 0000000..8b733da
--- /dev/null
+++ b/runtime/ftplugin/prisma.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: prisma
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 19
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=:///,:// commentstring=//\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/ps1.vim b/runtime/ftplugin/ps1.vim
index d6ab010..9d698f2 100644
--- a/runtime/ftplugin/ps1.vim
+++ b/runtime/ftplugin/ps1.vim
@@ -3,6 +3,7 @@
" URL: https://github.com/PProvost/vim-ps1
" Last Change: 2021 Apr 02
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin") | finish | endif
@@ -14,7 +15,7 @@ let s:cpo_save = &cpo
set cpo&vim
setlocal tw=0
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal formatoptions=tcqro
" Enable autocompletion of hyphenated PowerShell commands,
" e.g. Get-Content or Get-ADUser
diff --git a/runtime/ftplugin/ps1xml.vim b/runtime/ftplugin/ps1xml.vim
index 17bb181..0052de1 100644
--- a/runtime/ftplugin/ps1xml.vim
+++ b/runtime/ftplugin/ps1xml.vim
@@ -3,6 +3,7 @@
" URL: https://github.com/PProvost/vim-ps1
" Last Change: 2021 Apr 02
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin") | finish | endif
@@ -14,7 +15,7 @@ let s:cpo_save = &cpo
set cpo&vim
setlocal tw=0
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal formatoptions=tcqro
" Change the browse dialog on Win32 and GTK to show mainly PowerShell-related files
diff --git a/runtime/ftplugin/purescript.vim b/runtime/ftplugin/purescript.vim
new file mode 100644
index 0000000..b3300bb
--- /dev/null
+++ b/runtime/ftplugin/purescript.vim
@@ -0,0 +1,14 @@
+" Vim filetype plugin
+" Language: purescript
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 19
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=s1f:{-,mb:\ ,ex:-},:--\ \|,:--
+setl commentstring=--\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/python.vim b/runtime/ftplugin/python.vim
index 79acaa6..c000296 100644
--- a/runtime/ftplugin/python.vim
+++ b/runtime/ftplugin/python.vim
@@ -1,10 +1,9 @@
" Vim filetype plugin file
" Language: python
-" Maintainer: Tom Picton <tom@tompicton.co.uk>
+" Maintainer: Tom Picton <tom@tompicton.com>
" Previous Maintainer: James Sully <sullyj3@gmail.com>
" Previous Maintainer: Johannes Zellner <johannes@zellner.org>
-" Last Change: Mon, 5 October 2020
-" 2024 Jan 14 by Vim Project (browsefilter)
+" Last Change: 2024/05/13
" https://github.com/tpict/vim-ftplugin-python
if exists("b:did_ftplugin") | finish | endif
@@ -15,7 +14,7 @@ set cpo&vim
setlocal cinkeys-=0#
setlocal indentkeys-=0#
setlocal include=^\\s*\\(from\\\|import\\)
-setlocal define=^\\s*\\(def\\\|class\\)
+setlocal define=^\\s*\\(\\(async\\s\\+\\)\\?def\\\|class\\)
" For imports with leading .., append / and replace additional .s with ../
let b:grandparent_match = '^\(.\.\)\(\.*\)'
@@ -57,14 +56,14 @@ let b:next_end='\v\S\n*(%$\|^(\s*\n*)*(class\|def\|async def)\|^\S)'
let b:prev_end='\v\S\n*(^(\s*\n*)*(class\|def\|async def)\|^\S)'
if !exists('g:no_plugin_maps') && !exists('g:no_python_maps')
- execute "nnoremap <silent> <buffer> ]] :call <SID>Python_jump('n', '". b:next_toplevel."', 'W', v:count1)<cr>"
- execute "nnoremap <silent> <buffer> [[ :call <SID>Python_jump('n', '". b:prev_toplevel."', 'Wb', v:count1)<cr>"
- execute "nnoremap <silent> <buffer> ][ :call <SID>Python_jump('n', '". b:next_endtoplevel."', 'W', v:count1, 0)<cr>"
- execute "nnoremap <silent> <buffer> [] :call <SID>Python_jump('n', '". b:prev_endtoplevel."', 'Wb', v:count1, 0)<cr>"
- execute "nnoremap <silent> <buffer> ]m :call <SID>Python_jump('n', '". b:next."', 'W', v:count1)<cr>"
- execute "nnoremap <silent> <buffer> [m :call <SID>Python_jump('n', '". b:prev."', 'Wb', v:count1)<cr>"
- execute "nnoremap <silent> <buffer> ]M :call <SID>Python_jump('n', '". b:next_end."', 'W', v:count1, 0)<cr>"
- execute "nnoremap <silent> <buffer> [M :call <SID>Python_jump('n', '". b:prev_end."', 'Wb', v:count1, 0)<cr>"
+ execute "nnoremap <silent> <buffer> ]] :<C-U>call <SID>Python_jump('n', '". b:next_toplevel."', 'W', v:count1)<cr>"
+ execute "nnoremap <silent> <buffer> [[ :<C-U>call <SID>Python_jump('n', '". b:prev_toplevel."', 'Wb', v:count1)<cr>"
+ execute "nnoremap <silent> <buffer> ][ :<C-U>call <SID>Python_jump('n', '". b:next_endtoplevel."', 'W', v:count1, 0)<cr>"
+ execute "nnoremap <silent> <buffer> [] :<C-U>call <SID>Python_jump('n', '". b:prev_endtoplevel."', 'Wb', v:count1, 0)<cr>"
+ execute "nnoremap <silent> <buffer> ]m :<C-U>call <SID>Python_jump('n', '". b:next."', 'W', v:count1)<cr>"
+ execute "nnoremap <silent> <buffer> [m :<C-U>call <SID>Python_jump('n', '". b:prev."', 'Wb', v:count1)<cr>"
+ execute "nnoremap <silent> <buffer> ]M :<C-U>call <SID>Python_jump('n', '". b:next_end."', 'W', v:count1, 0)<cr>"
+ execute "nnoremap <silent> <buffer> [M :<C-U>call <SID>Python_jump('n', '". b:prev_end."', 'Wb', v:count1, 0)<cr>"
execute "onoremap <silent> <buffer> ]] :call <SID>Python_jump('o', '". b:next_toplevel."', 'W', v:count1)<cr>"
execute "onoremap <silent> <buffer> [[ :call <SID>Python_jump('o', '". b:prev_toplevel."', 'Wb', v:count1)<cr>"
diff --git a/runtime/ftplugin/qml.vim b/runtime/ftplugin/qml.vim
index aa05c11..53df11c 100644
--- a/runtime/ftplugin/qml.vim
+++ b/runtime/ftplugin/qml.vim
@@ -3,6 +3,7 @@
" Maintainer: Chase Knowlden <haroldknowlden@gmail.com>
" Last Change: 2023 Aug 16
" 2023 Aug 23 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists( 'b:did_ftplugin' )
finish
@@ -28,7 +29,7 @@ endif
" Set 'comments' to format dashed lists in comments.
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
-setlocal commentstring=//%s
+setlocal commentstring=//\ %s
setlocal formatoptions-=t
setlocal formatoptions+=croql
diff --git a/runtime/ftplugin/racket.vim b/runtime/ftplugin/racket.vim
index 84f5422..7bfd87d 100644
--- a/runtime/ftplugin/racket.vim
+++ b/runtime/ftplugin/racket.vim
@@ -3,8 +3,7 @@
" Maintainer: D. Ben Knoble <ben.knoble+github@gmail.com>
" Previous Maintainer: Will Langstroth <will@langstroth.com>
" URL: https://github.com/benknoble/vim-racket
-" Last Change: 2022 Aug 29
-" 2024 Jan 14 by Vim Project (browsefilter)
+" Last Change: 2024 May 28
if exists("b:did_ftplugin")
finish
@@ -21,7 +20,7 @@ setlocal iskeyword=@,!,#-',*-:,<-Z,a-z,~,_,94
setlocal comments=:;;;;,:;;;,:;;,:;
setlocal formatoptions+=r
-"setlocal commentstring=;;%s
+"setlocal commentstring=;;\ %s
setlocal commentstring=#\|\ %s\ \|#
setlocal formatprg=raco\ fmt
diff --git a/runtime/ftplugin/raku.vim b/runtime/ftplugin/raku.vim
index 941222b..f57427e 100644
--- a/runtime/ftplugin/raku.vim
+++ b/runtime/ftplugin/raku.vim
@@ -1,10 +1,11 @@
" Vim filetype plugin file
-" Language: Raku
-" Maintainer: vim-perl <vim-perl@googlegroups.com>
-" Homepage: https://github.com/Raku/vim-raku
+" Language: Raku
+" Maintainer: vim-perl <vim-perl@googlegroups.com>
+" Homepage: https://github.com/Raku/vim-raku
" Bugs/requests: https://github.com/Raku/vim-raku/issues
-" Last Change: 2021-04-16
-" Contributors: Hinrik Örn Sigurðsson <hinrik.sig@gmail.com>
+" Last Change: 2021 Apr 16
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
+" Contributors: Hinrik Örn Sigurðsson <hinrik.sig@gmail.com>
"
" Based on ftplugin/perl.vim by Dan Sharp <dwsharp at hotmail dot com>
@@ -21,7 +22,7 @@ setlocal formatoptions+=crqol
setlocal keywordprg=p6doc
setlocal comments=:#\|,:#=,:#
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
" Provided by Ned Konz <ned at bike-nomad dot com>
"---------------------------------------------
diff --git a/runtime/ftplugin/rasi.vim b/runtime/ftplugin/rasi.vim
new file mode 100644
index 0000000..5f8ce86
--- /dev/null
+++ b/runtime/ftplugin/rasi.vim
@@ -0,0 +1,25 @@
+" Vim filetype plugin file
+" Language: RASI
+" Maintainer: Pierrick Guillaume <pierguill@gmail.com>
+" Last Change: 2024 May 21
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+let b:undo_ftplugin = "setl com< cms< isk< inc<"
+
+setlocal comments=s1:/*,mb:*,ex:*/
+setlocal commentstring=//\ %s
+setlocal iskeyword+=-
+
+let &l:include = '^\s*@import\s\+\%(url(\)\='
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: ts=8
diff --git a/runtime/ftplugin/rescript.vim b/runtime/ftplugin/rescript.vim
new file mode 100644
index 0000000..dd94c68
--- /dev/null
+++ b/runtime/ftplugin/rescript.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: rescript
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 21
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// commentstring=//\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/rust.vim b/runtime/ftplugin/rust.vim
index fb15b44..c2bcdd3 100644
--- a/runtime/ftplugin/rust.vim
+++ b/runtime/ftplugin/rust.vim
@@ -1,7 +1,8 @@
-" Language: Rust
-" Description: Vim ftplugin for Rust
-" Maintainer: Chris Morgan <me@chrismorgan.info>
-" Last Change: 2024-03-17
+" Language: Rust
+" Description: Vim ftplugin for Rust
+" Maintainer: Chris Morgan <me@chrismorgan.info>
+" Last Change: 2024 Mar 17
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com ('commentstring')
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if exists("b:did_ftplugin")
@@ -36,7 +37,7 @@ if get(g:, 'rust_bang_comment_leader', 0)
else
setlocal comments=s0:/*!,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
endif
-setlocal commentstring=//%s
+setlocal commentstring=//\ %s
setlocal formatoptions-=t formatoptions+=croqnl
" j was only added in 7.3.541, so stop complaints about its nonexistence
silent! setlocal formatoptions+=j
diff --git a/runtime/ftplugin/scdoc.vim b/runtime/ftplugin/scdoc.vim
index 552c865..8225e43 100644
--- a/runtime/ftplugin/scdoc.vim
+++ b/runtime/ftplugin/scdoc.vim
@@ -1,7 +1,8 @@
" scdoc filetype plugin
-" Maintainer: Gregory Anders <contact@gpanders.com>
-" Last Updated: 2022-05-09
-" Upstream: https://github.com/gpanders/vim-scdoc
+" Maintainer: Gregory Anders <contact@gpanders.com>
+" Last Updated: 2022 May 09
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
+" Upstream: https://github.com/gpanders/vim-scdoc
" Only do this when not done yet for this buffer
if exists('b:did_ftplugin')
@@ -12,7 +13,7 @@ endif
let b:did_ftplugin = 1
setlocal comments=b:;
-setlocal commentstring=;%s
+setlocal commentstring=;\ %s
setlocal formatoptions+=t
setlocal noexpandtab
setlocal shiftwidth=0
diff --git a/runtime/ftplugin/scheme.vim b/runtime/ftplugin/scheme.vim
index 04655bc..03f625b 100644
--- a/runtime/ftplugin/scheme.vim
+++ b/runtime/ftplugin/scheme.vim
@@ -1,11 +1,12 @@
" Vim filetype plugin file
-" Language: Scheme (R7RS)
-" Last Change: 2019-11-19
-" Author: Evan Hanson <evhan@foldling.org>
-" Maintainer: Evan Hanson <evhan@foldling.org>
+" Language: Scheme (R7RS)
+" Last Change: 2019 Nov 19
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
+" Author: Evan Hanson <evhan@foldling.org>
+" Maintainer: Evan Hanson <evhan@foldling.org>
" Previous Maintainer: Sergey Khorev <sergey.khorev@gmail.com>
-" Repository: https://git.foldling.org/vim-scheme.git
-" URL: https://foldling.org/vim/ftplugin/scheme.vim
+" Repository: https://git.foldling.org/vim-scheme.git
+" URL: https://foldling.org/vim/ftplugin/scheme.vim
if exists('b:did_ftplugin')
finish
@@ -16,7 +17,7 @@ set cpo&vim
setl lisp
setl comments=:;;;;,:;;;,:;;,:;,sr:#\|,mb:\|,ex:\|#
-setl commentstring=;%s
+setl commentstring=;\ %s
setl define=^\\s*(def\\k*
setl iskeyword=33,35-39,42-43,45-58,60-90,94,95,97-122,126
diff --git a/runtime/ftplugin/sh.vim b/runtime/ftplugin/sh.vim
index 6d2093b..c47aa52 100644
--- a/runtime/ftplugin/sh.vim
+++ b/runtime/ftplugin/sh.vim
@@ -4,7 +4,7 @@
" Previous Maintainer: Dan Sharp
" Contributor: Enno Nagel <ennonagel+vim@gmail.com>
" Eisuke Kawashima
-" Last Change: 2024 Feb 27
+" Last Change: 2024 May 06 by Vim Project (MANPAGER=)
if exists("b:did_ftplugin")
finish
@@ -46,11 +46,11 @@ endif
if get(b:, "is_bash", 0)
if !has("gui_running") && executable("less")
- command! -buffer -nargs=1 ShKeywordPrg silent exe '!bash -c "{ help "<args>" 2>/dev/null || man "<args>"; } | LESS= less"' | redraw!
+ command! -buffer -nargs=1 ShKeywordPrg silent exe '!bash -c "{ help "<args>" 2>/dev/null || MANPAGER= man "<args>"; } | LESS= less"' | redraw!
elseif has("terminal")
command! -buffer -nargs=1 ShKeywordPrg silent exe ':term bash -c "help "<args>" 2>/dev/null || man "<args>""'
else
- command! -buffer -nargs=1 ShKeywordPrg echo system('bash -c "help <args>" 2>/dev/null || man "<args>"')
+ command! -buffer -nargs=1 ShKeywordPrg echo system('bash -c "help <args>" 2>/dev/null || MANPAGER= man "<args>"')
endif
setlocal keywordprg=:ShKeywordPrg
let b:undo_ftplugin ..= " | setl kp< | sil! delc -buffer ShKeywordPrg"
diff --git a/runtime/ftplugin/slint.vim b/runtime/ftplugin/slint.vim
new file mode 100644
index 0000000..ac8057f
--- /dev/null
+++ b/runtime/ftplugin/slint.vim
@@ -0,0 +1,15 @@
+" Vim filetype plugin
+" Language: slint
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 19
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+" Set 'comments' to format dashed lists in comments.
+" Also include ///, used for Doxygen.
+setl comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,:// commentstring=//\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/snakemake.vim b/runtime/ftplugin/snakemake.vim
new file mode 100644
index 0000000..ab90ca1
--- /dev/null
+++ b/runtime/ftplugin/snakemake.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: snakemake
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 Jun 13
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl comments=:# commentstring=#\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/sql.vim b/runtime/ftplugin/sql.vim
index c85232f..61b7e67 100644
--- a/runtime/ftplugin/sql.vim
+++ b/runtime/ftplugin/sql.vim
@@ -4,6 +4,7 @@
" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
" Last Change: 2017 Mar 07
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 18 by Vim Project (set comment options)
" Download: http://vim.sourceforge.net/script.php?script_id=454
" For more details please use:
@@ -105,6 +106,8 @@ set cpo&vim
setlocal formatoptions-=t
setlocal formatoptions+=c
+setlocal comments=:-- commentstring=--\ %s
+
" Functions/Commands to allow the user to change SQL syntax dialects
" through the use of :SQLSetType <tab> for completion.
" This works with both Vim 6 and 7.
@@ -266,7 +269,7 @@ if exists("b:did_ftplugin") && exists("b:current_ftplugin") && b:current_ftplugi
finish
endif
-let b:undo_ftplugin = "setl comments< formatoptions< define< omnifunc<" .
+let b:undo_ftplugin = "setl comments< commentstring< formatoptions< define< omnifunc<" .
\ " | unlet! b:browsefilter b:match_words"
" Don't load another plugin for this buffer
diff --git a/runtime/ftplugin/sshdconfig.vim b/runtime/ftplugin/sshdconfig.vim
new file mode 100644
index 0000000..3d39454
--- /dev/null
+++ b/runtime/ftplugin/sshdconfig.vim
@@ -0,0 +1,10 @@
+" Vim filetype plugin file
+" Language: OpenSSH server configuration file
+" Maintainer: Yinzuo Jiang <jiangyinzuo@foxmail.com>
+" Latest Revision: 2024-05-17
+
+if exists("b:did_ftplugin")
+ finish
+endif
+
+runtime! ftplugin/conf.vim
diff --git a/runtime/ftplugin/stylus.vim b/runtime/ftplugin/stylus.vim
new file mode 100644
index 0000000..1c5f14e
--- /dev/null
+++ b/runtime/ftplugin/stylus.vim
@@ -0,0 +1,54 @@
+" Vim filetype plugin
+" Language: Stylus
+" Maintainer: Marc Harter
+" Credits: Tim Pope
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+ finish
+endif
+
+let s:save_cpo = &cpo
+set cpo-=C
+
+" Define some defaults in case the included ftplugins don't set them.
+let s:undo_ftplugin = ""
+let s:browsefilter = "All Files (*.*)\t*.*\n"
+
+runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim
+unlet! b:did_ftplugin
+
+" Override our defaults if these were set by an included ftplugin.
+if exists("b:undo_ftplugin")
+ let s:undo_ftplugin = b:undo_ftplugin
+ unlet b:undo_ftplugin
+endif
+if exists("b:browsefilter")
+ let s:browsefilter = b:browsefilter
+ unlet b:browsefilter
+endif
+
+" Change the browse dialog on Win32 to show mainly Styl-related files
+if has("gui_win32")
+ let b:browsefilter="Stylus Files (*.styl)\t*.styl\n" . s:browsefilter
+endif
+
+setlocal comments= commentstring=//\ %s
+setlocal suffixesadd=.styl
+setlocal formatoptions+=r
+
+" Add '-' and '#' to the what makes up a keyword.
+" This means that 'e' and 'w' work properly now, for properties
+" and valid variable names.
+setl iskeyword+=#,-
+
+" Add a Stylus command (to see if it's valid)
+command -buffer Stylus !clear; cat % |stylus
+
+
+let b:undo_ftplugin = "setl sua< isk< cms< com< fo< "
+ \ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin
+
+let &cpo = s:save_cpo
+
+" vim:set sw=2:
diff --git a/runtime/ftplugin/svelte.vim b/runtime/ftplugin/svelte.vim
new file mode 100644
index 0000000..e0ec4e0
--- /dev/null
+++ b/runtime/ftplugin/svelte.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin
+" Language: svelte
+" Maintainer: Igor Lacerda <igorlafarsi@gmail.com>
+" Last Change: 2024 Jun 09
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setl commentstring=<!--\ %s\ -->
+
+let b:undo_ftplugin = 'setl cms<'
diff --git a/runtime/ftplugin/tcl.vim b/runtime/ftplugin/tcl.vim
index fa90009..214d9c2 100644
--- a/runtime/ftplugin/tcl.vim
+++ b/runtime/ftplugin/tcl.vim
@@ -3,6 +3,7 @@
" Maintainer: Robert L Hicks <sigzero@gmail.com>
" Latest Revision: 2009-05-01
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -15,7 +16,7 @@ let s:cpo_save = &cpo
set cpo-=C
setlocal comments=:#
-setlocal commentstring=#%s
+setlocal commentstring=#\ %s
setlocal formatoptions+=croql
" Change the browse dialog on Windows to show mainly Tcl-related files
diff --git a/runtime/ftplugin/typescript.vim b/runtime/ftplugin/typescript.vim
index 680521d..fb5f4e1 100644
--- a/runtime/ftplugin/typescript.vim
+++ b/runtime/ftplugin/typescript.vim
@@ -2,6 +2,7 @@
" Language: TypeScript
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Last Change: 2024 Jan 14
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -18,7 +19,7 @@ setlocal formatoptions-=t formatoptions+=croql
" Set 'comments' to format dashed lists in comments.
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
-setlocal commentstring=//%s
+setlocal commentstring=//\ %s
setlocal suffixesadd+=.ts,.d.ts,.tsx,.js,.jsx,.cjs,.mjs
diff --git a/runtime/ftplugin/typst.vim b/runtime/ftplugin/typst.vim
new file mode 100644
index 0000000..c2d7811
--- /dev/null
+++ b/runtime/ftplugin/typst.vim
@@ -0,0 +1,14 @@
+" Vim filetype plugin
+" Language: typst
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 19
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+setlocal commentstring=//\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/v.vim b/runtime/ftplugin/v.vim
new file mode 100644
index 0000000..4d4f60d
--- /dev/null
+++ b/runtime/ftplugin/v.vim
@@ -0,0 +1,15 @@
+" Vim filetype plugin
+" Language: v
+" Maintainer: Riley Bruins <ribru17@gmail.com>
+" Last Change: 2024 May 19
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+" Set 'comments' to format dashed lists in comments.
+" Also include ///, used for Doxygen.
+setl comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,:// commentstring=//\ %s
+
+let b:undo_ftplugin = 'setl com< cms<'
diff --git a/runtime/ftplugin/verilog.vim b/runtime/ftplugin/verilog.vim
index 83c3754..c20be25 100644
--- a/runtime/ftplugin/verilog.vim
+++ b/runtime/ftplugin/verilog.vim
@@ -3,6 +3,7 @@
" Maintainer: Chih-Tsun Huang <cthuang@cs.nthu.edu.tw>
" Last Change: 2017 Aug 25 by Chih-Tsun Huang
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 20 by Riley Bruins <ribru17@gmail.com> (commentstring)
" URL: http://www.cs.nthu.edu.tw/~cthuang/vim/ftplugin/verilog.vim
"
" Credits:
@@ -22,7 +23,7 @@ let s:cpo_save = &cpo
set cpo&vim
" Undo the plugin effect
-let b:undo_ftplugin = "setlocal fo< com< tw<"
+let b:undo_ftplugin = "setlocal fo< com< tw< cms<"
\ . "| unlet! b:browsefilter b:match_ignorecase b:match_words"
" Set 'formatoptions' to break comment lines but not other lines,
@@ -31,6 +32,7 @@ setlocal fo-=t fo+=croqlm1
" Set 'comments' to format dashed lists in comments.
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+setlocal commentstring=//\ %s
" Format comments to be up to 78 characters long
if &textwidth == 0
diff --git a/runtime/ftplugin/vim.vim b/runtime/ftplugin/vim.vim
index 67f360b..11c05d1 100644
--- a/runtime/ftplugin/vim.vim
+++ b/runtime/ftplugin/vim.vim
@@ -2,6 +2,7 @@
" Language: Vim
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Last Change: 2024 Apr 13
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" Only do this when not done yet for this buffer
@@ -51,7 +52,7 @@ setlocal keywordprg=:help
" Comments starts with # in Vim9 script. We have to guess which one to use.
if "\n" .. getline(1, 32)->join("\n") =~# '\n\s*vim9\%[script]\>'
- setlocal commentstring=#%s
+ setlocal commentstring=#\ %s
else
setlocal commentstring=\"%s
endif
diff --git a/runtime/ftplugin/wat.vim b/runtime/ftplugin/wat.vim
index 35d2d6a..ad1140b 100644
--- a/runtime/ftplugin/wat.vim
+++ b/runtime/ftplugin/wat.vim
@@ -2,6 +2,7 @@
" Language: WebAssembly
" Maintainer: rhysd <lin90162@yahoo.co.jp>
" Last Change: Nov 14, 2023
+" May 24, 2024 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" For bugs, patches and license go to https://github.com/rhysd/vim-wasm
if exists("b:did_ftplugin")
@@ -10,7 +11,7 @@ endif
let b:did_ftplugin = 1
setlocal comments=s:(;,e:;),:;;
-setlocal commentstring=(;%s;)
+setlocal commentstring=(;\ %s\ ;)
setlocal formatoptions-=t
setlocal iskeyword+=$,.,/
diff --git a/runtime/ftplugin/xdefaults.vim b/runtime/ftplugin/xdefaults.vim
index c1aff70..26c7516 100644
--- a/runtime/ftplugin/xdefaults.vim
+++ b/runtime/ftplugin/xdefaults.vim
@@ -1,7 +1,8 @@
" Vim filetype plugin file
-" Language: X resources files like ~/.Xdefaults (xrdb)
-" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2008-07-09
+" Language: X resources files like ~/.Xdefaults (xrdb)
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Latest Revision: 2008 Jul 09
+" 2024 Jun 03 by Riley Bruins <ribru17@gmail.com> ('commentstring')
if exists("b:did_ftplugin")
finish
@@ -13,7 +14,7 @@ set cpo&vim
let b:undo_ftplugin = "setl com< cms< inc< fo<"
-setlocal comments=s1:/*,mb:*,ex:*/,:! commentstring& inc&
+setlocal comments=s1:/*,mb:*,ex:*/,:! commentstring=!\ %s inc&
setlocal formatoptions-=t formatoptions+=croql
let &cpo = s:cpo_save
diff --git a/runtime/ftplugin/xml.vim b/runtime/ftplugin/xml.vim
index b81c398..83c528e 100644
--- a/runtime/ftplugin/xml.vim
+++ b/runtime/ftplugin/xml.vim
@@ -3,6 +3,7 @@
" Maintainer: Christian Brabandt <cb@256bit.org>
" Last Changed: Dec 07th, 2018
" 2024 Jan 14 by Vim Project (browsefilter)
+" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
" Repository: https://github.com/chrisbra/vim-xml-ftplugin
" Previous Maintainer: Dan Sharp
" URL: http://dwsharp.users.sourceforge.net/vim/ftplugin
@@ -15,7 +16,7 @@ let b:did_ftplugin = 1
let s:save_cpo = &cpo
set cpo&vim
-setlocal commentstring=<!--%s-->
+setlocal commentstring=<!--\ %s\ -->
" Remove the middlepart from the comments section, as this causes problems:
" https://groups.google.com/d/msg/vim_dev/x4GT-nqa0Kg/jvtRnEbtAnMJ
setlocal comments=s:<!--,e:-->
diff --git a/runtime/ftplugin/zig.vim b/runtime/ftplugin/zig.vim
index 28b8cd5..ea229b6 100644
--- a/runtime/ftplugin/zig.vim
+++ b/runtime/ftplugin/zig.vim
@@ -1,68 +1,52 @@
" Vim filetype plugin file
-" Language: Zig
-" Upstream: https://github.com/ziglang/zig.vim
+" Language: Zig
+" Maintainer: Mathias Lindgren <math.lindgren@gmail.com>
+" Last Change: 2024 May 21
+" Based on: https://github.com/ziglang/zig.vim
-" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
-let s:cpo_orig = &cpo
+let s:cpo_save = &cpo
set cpo&vim
compiler zig_build
" Match Zig builtin fns
setlocal iskeyword+=@-@
-
-" Recommended code style, no tabs and 4-space indentation
-setlocal expandtab
-setlocal tabstop=8
-setlocal softtabstop=4
-setlocal shiftwidth=4
-
setlocal formatoptions-=t formatoptions+=croql
-
-setlocal suffixesadd=.zig,.zir
+setlocal suffixesadd=.zig,.zir,.zon
+let &l:define='\v(<fn>|<const>|<var>|^\s*\#\s*define)'
+let b:undo_ftplugin = 'setl isk< fo< sua< mp< def<'
+
+if get(g:, 'zig_recommended_style', 1)
+ setlocal expandtab
+ setlocal tabstop=8
+ setlocal softtabstop=4
+ setlocal shiftwidth=4
+ let b:undo_ftplugin .= ' | setl et< ts< sts< sw<'
+endif
if has('comments')
setlocal comments=:///,://!,://
setlocal commentstring=//\ %s
+ let b:undo_ftplugin .= ' | setl com< cms<'
endif
if has('find_in_path')
let &l:includeexpr='substitute(v:fname, "^([^.])$", "\1.zig", "")'
let &l:include='\v(\@import>|\@cInclude>|^\s*\#\s*include)'
-endif
-
-let &l:define='\v(<fn>|<const>|<var>|^\s*\#\s*define)'
-
-" Safety check: don't execute zig from current directory
-if !exists('g:zig_std_dir') && exists('*json_decode') &&
- \ executable('zig') && dist#vim#IsSafeExecutable('zig', 'zig')
- silent let s:env = system('zig env')
- if v:shell_error == 0
- let g:zig_std_dir = json_decode(s:env)['std_dir']
- endif
- unlet! s:env
+ let b:undo_ftplugin .= ' | setl inex< inc<'
endif
if exists('g:zig_std_dir')
- let &l:path = g:zig_std_dir . ',' . &l:path
+ let &l:path .= ',' . g:zig_std_dir
+ let b:undo_ftplugin .= ' | setl pa<'
endif
-let b:undo_ftplugin =
- \ 'setl isk< et< ts< sts< sw< fo< sua< mp< com< cms< inex< inc< pa<'
-
-augroup vim-zig
- autocmd! * <buffer>
- autocmd BufWritePre <buffer> if get(g:, 'zig_fmt_autosave', 1) | call zig#fmt#Format() | endif
-augroup END
-
-let b:undo_ftplugin .= '|au! vim-zig * <buffer>'
-
-let &cpo = s:cpo_orig
-unlet s:cpo_orig
+let &cpo = s:cpo_save
+unlet s:cpo_save
" vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab
diff --git a/runtime/ftplugin/zsh.vim b/runtime/ftplugin/zsh.vim
index 40986fc..aee8900 100644
--- a/runtime/ftplugin/zsh.vim
+++ b/runtime/ftplugin/zsh.vim
@@ -2,7 +2,7 @@
" Language: Zsh shell script
" Maintainer: Christian Brabandt <cb@256bit.org>
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2023-10-07
+" Latest Revision: 2024 May 06 by Vim Project (MANPAGER=)
" License: Vim (see :h license)
" Repository: https://github.com/chrisbra/vim-zsh
@@ -24,7 +24,7 @@ if executable('zsh') && &shell !~# '/\%(nologin\|false\)$'
elseif has('terminal')
command! -buffer -nargs=1 ZshKeywordPrg silent exe ':term zsh -c "autoload -Uz run-help; run-help <args>"'
else
- command! -buffer -nargs=1 ZshKeywordPrg echo system('zsh -c "autoload -Uz run-help; run-help <args> 2>/dev/null"')
+ command! -buffer -nargs=1 ZshKeywordPrg echo system('MANPAGER= zsh -c "autoload -Uz run-help; run-help <args> 2>/dev/null"')
endif
if !exists('current_compiler')
compiler zsh
diff --git a/runtime/indent/arduino.vim b/runtime/indent/arduino.vim
new file mode 100644
index 0000000..88717ac
--- /dev/null
+++ b/runtime/indent/arduino.vim
@@ -0,0 +1,16 @@
+" Vim indent file
+" Language: Arduino
+" Maintainer: The Vim Project <https://github.com/vim/vim>
+" Ken Takata <https://github.com/k-takata>
+" Last Change: 2024 Apr 03
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+" Use C indenting.
+setlocal cindent
+
+let b:undo_indent = "setl cin<"
diff --git a/runtime/indent/asm.vim b/runtime/indent/asm.vim
deleted file mode 100644
index 4efa766..0000000
--- a/runtime/indent/asm.vim
+++ /dev/null
@@ -1,29 +0,0 @@
-" Vim indent file
-" Language: asm
-" Maintainer: Philip Jones <philj56@gmail.com>
-" Upstream: https://github.com/philj56/vim-asm-indent
-" Last Change: 2017-Jul-01
-" 2024 Apr 25 by Vim Project (undo_indent)
-
-if exists("b:did_indent")
- finish
-endif
-let b:did_indent = 1
-
-setlocal indentexpr=s:getAsmIndent()
-setlocal indentkeys=<:>,!^F,o,O
-
-let b:undo_indent = "indentexpr< indentkeys<"
-
-function! s:getAsmIndent()
- let line = getline(v:lnum)
- let ind = shiftwidth()
-
- " If the line is a label (starts with ':' terminated keyword),
- " then don't indent
- if line =~ '^\s*\k\+:'
- let ind = 0
- endif
-
- return ind
-endfunction
diff --git a/runtime/indent/hare.vim b/runtime/indent/hare.vim
index 0a9d8da..1b51d1e 100644
--- a/runtime/indent/hare.vim
+++ b/runtime/indent/hare.vim
@@ -1,19 +1,16 @@
" Vim indent file
-" Language: Hare
-" Maintainer: Amelia Clarke <me@rsaihe.dev>
-" Last Change: 2022 Sep 22
-" 2023 Aug 28 by Vim Project (undo_indent)
+" Language: Hare
+" Maintainer: Amelia Clarke <selene@perilune.dev>
+" Last Change: 2024-04-14
+" Upstream: https://git.sr.ht/~sircmpwn/hare.vim
-if exists("b:did_indent")
+if exists('b:did_indent')
finish
endif
let b:did_indent = 1
-if !has("cindent") || !has("eval")
- finish
-endif
-
-setlocal cindent
+let s:cpo_save = &cpo
+set cpo&vim
" L0 -> don't deindent labels
" (s -> use one indent after a trailing (
@@ -41,7 +38,11 @@ setlocal cinwords=if,else,for,switch,match
setlocal indentexpr=GetHareIndent()
-let b:undo_indent = "setl cin< cino< cinw< inde< indk<"
+let b:undo_indent = 'setl cino< cinw< inde< indk<'
+
+if exists('*GetHareIndent()')
+ finish
+endif
function! FloorCindent(lnum)
return cindent(a:lnum) / shiftwidth() * shiftwidth()
@@ -122,7 +123,8 @@ function! GetHareIndent()
" Indent the body of a case.
" If the previous line ended in a semicolon and the line before that was a
" case, don't do any special indenting.
- if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\>\s*(//.*)?$' && line !~# '\v^\s*}'
+ if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\>\s*(//.*)?$'
+ \ && line !~# '\v^\s*}'
return indent(prevlnum)
endif
@@ -138,4 +140,7 @@ function! GetHareIndent()
return l:indent
endfunction
-" vim: tabstop=2 shiftwidth=2 expandtab
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: et sw=2 sts=2 ts=8
diff --git a/runtime/indent/kdl.vim b/runtime/indent/kdl.vim
new file mode 100644
index 0000000..b0a6bd9
--- /dev/null
+++ b/runtime/indent/kdl.vim
@@ -0,0 +1,30 @@
+" Vim indent file
+" Language: KDL
+" Author: Aram Drevekenin <aram@poor.dev>
+" Maintainer: Yinzuo Jiang <jiangyinzuo@foxmail.com>
+" Last Change: 2024-06-16
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=KdlIndent()
+let b:undo_indent = "setlocal indentexpr<"
+
+function! KdlIndent(...)
+ let line = substitute(getline(v:lnum), '//.*$', '', '')
+ let previousNum = prevnonblank(v:lnum - 1)
+ let previous = substitute(getline(previousNum), '//.*$', '', '')
+
+ let l:indent = indent(previousNum)
+ if previous =~ "{" && previous !~ "}"
+ let l:indent += shiftwidth()
+ endif
+ if line =~ "}" && line !~ "{"
+ let l:indent -= shiftwidth()
+ endif
+ return l:indent
+endfunction
+" vim: sw=2 sts=2 et
diff --git a/runtime/indent/stylus.vim b/runtime/indent/stylus.vim
new file mode 100644
index 0000000..89634f0
--- /dev/null
+++ b/runtime/indent/stylus.vim
@@ -0,0 +1,121 @@
+" Vim indent file
+" Language: Stylus
+" Maintainer: Marc Harter
+" Last Change: 2010 May 21
+" Based On: sass.vim from Tim Pope
+"
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=GetStylusIndent()
+setlocal indentkeys=o,O,*<Return>,},],0),!^F
+let b:undo_indent = "setl indentexpr< indentkeys<"
+
+if exists("*GetStylusIndent") " only define once
+ finish
+endif
+
+function s:prevnonblanknoncomment(lnum)
+ let lnum = a:lnum
+ while lnum > 1
+ let lnum = prevnonblank(lnum)
+ let line = getline(lnum)
+ if line =~ '\*/'
+ while lnum > 1 && line !~ '/\*'
+ let lnum -= 1
+ endwhile
+ if line =~ '^\s*/\*'
+ let lnum -= 1
+ else
+ break
+ endif
+ else
+ break
+ endif
+ endwhile
+ return lnum
+endfunction
+
+function s:count_braces(lnum, count_open)
+ let n_open = 0
+ let n_close = 0
+ let line = getline(a:lnum)
+ let pattern = '[{}]'
+ let i = match(line, pattern)
+ while i != -1
+ if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'css\%(Comment\|StringQ\{1,2}\)'
+ if line[i] == '{'
+ let n_open += 1
+ elseif line[i] == '}'
+ if n_open > 0
+ let n_open -= 1
+ else
+ let n_close += 1
+ endif
+ endif
+ endif
+ let i = match(line, pattern, i + 1)
+ endwhile
+ return a:count_open ? n_open : n_close
+endfunction
+
+" function CheckCSSIndent()
+" let line = getline(v:lnum)
+" if line =~ '^\s*\*'
+" return cindent(v:lnum)
+" endif
+"
+" let pnum = s:prevnonblanknoncomment(v:lnum - 1)
+" if pnum == 0
+" return 0
+" endif
+
+function! GetStylusIndent()
+ let line = getline(v:lnum)
+ if line =~ '^\s*\*'
+ return cindent(v:lnum)
+ endif
+
+ let pnum = s:prevnonblanknoncomment(v:lnum - 1)
+ if pnum == 0
+ return 0
+ endif
+
+ let lnum = prevnonblank(v:lnum-1)
+ if lnum == 0
+ return 0
+ endif
+
+ let pline = getline(pnum)
+
+ if pline =~ '[}{]'
+ return indent(pnum) + s:count_braces(pnum, 1) * &sw - s:count_braces(v:lnum, 0) * &sw
+ endif
+
+ let line = substitute(getline(lnum),'[\s()]\+$','','') " get last line strip ending whitespace
+ let cline = substitute(substitute(getline(v:lnum),'\s\+$','',''),'^\s\+','','') " get current line, trimmed
+ let lastcol = strlen(line) " get last col in prev line
+ let line = substitute(line,'^\s\+','','') " then remove preceeding whitespace
+ let indent = indent(lnum) " get indent on prev line
+ let cindent = indent(v:lnum) " get indent on current line
+ let increase = indent + &sw " increase indent by the shift width
+ if indent == indent(lnum)
+ let indent = cindent <= indent ? indent : increase
+ endif
+
+ let group = synIDattr(synID(lnum,lastcol,1),'name')
+
+ " if group !~? 'css.*' && line =~? ')\s*$' " match user functions
+ " return increase
+ if group =~? '\v^%(cssTagName|cssClassName|cssIdentifier|cssSelectorOp|cssSelectorOp2|cssBraces|cssAttributeSelector|cssPseudo|stylusId|stylusClass)$'
+ return increase
+ elseif (group == 'stylusUserFunction') && (indent(lnum) == '0') " mixin definition
+ return increase
+ else
+ return indent
+ endif
+endfunction
+
+" vim:set sw=2;
diff --git a/runtime/indent/testdir/vb.in b/runtime/indent/testdir/vb.in
index 1653ae6..cb964f7 100644
--- a/runtime/indent/testdir/vb.in
+++ b/runtime/indent/testdir/vb.in
@@ -1,6 +1,16 @@
' vim: filetype=vb shiftwidth=4 expandtab
'
' START_INDENT
+#Const Debug = False
+
+#If Win64 Then
+' Win64=true, Win32=true, Win16=false
+#ElseIf Win32 Then
+' Win32=true, Win16=false
+#Else
+' Win16=true
+#End If
+
Public Type GEmployeeRecord ' Create user-defined type.
ID As Integer ' Define elements of data type.
Name As String * 20
@@ -95,6 +105,9 @@ Public Sub TestMultiline (cellAddr As String, rowNbr As Long)
Dim rng As Range
Set rng = Range(cellAddr)
+
+' Line continuation is implemented as a two-character sequence-
+' whitespace followed by underscore.
With rng
.Cells(1,1).Value = _
"Line 1 of multiline string; " & _
@@ -102,14 +115,25 @@ With rng
"Line 3 of multiline string"
End With
-' The following lines have whitespace after the underscore character
-' and therefore do not form a valid multiline statement. The indent
-' script correctly treats them as four single line statements contrary
-' to the author's obvious indent.
-rng..Cells(1,1).Value = _
+' This code block omits the leading whitespace character and so
+' the trailing underscore will not be treated as line continuation.
+With rng
+.Cells(1,1).Value =_
+"Line 1 of multiline string; " &_
+"Line 2 of multiline string; " &_
+"Line 3 of multiline string"
+End With
+
+' The following lines have whitespace after the underscore character.
+' This is contrary to Microsoft documentation but it is reported that
+' some Microsoft editors allow it and will still treat the statement
+' as line-continued.
+With rng
+rng.Cells(1,1).Value = _
"Line 1 of multiline string; " & _
"Line 2 of multiline string; " & _
"Line 3 of multiline string"
+End With
End Sub
@@ -121,6 +145,18 @@ stmtLabel:
End Sub
+Public Static Function TestStatic(addend As Integer)
+Dim Integer accumulator
+accumulator = accumulator + addend
+TestStatic = accumulator
+End Function
+
+Friend Function TestFriend(addend As Integer)
+Static Integer accumulator
+accumulator = accumulator + addend
+TestFriend = accumulator
+End Function
+
Sub TestTypeKeyword()
Type EmployeeRecord ' Create user-defined type.
ID As Integer ' Define elements of data type.
@@ -131,4 +167,10 @@ HireDate As Date
End Type
Dim varType As EmployeeRecord
End Sub
+
+Sub TestDateLiteralAfterLineContinuation
+Dim birthday as Date
+birthday = _
+#January 1, 1901#
+End Sub
' END_INDENT
diff --git a/runtime/indent/testdir/vb.ok b/runtime/indent/testdir/vb.ok
index 143c688..01a1a4c 100644
--- a/runtime/indent/testdir/vb.ok
+++ b/runtime/indent/testdir/vb.ok
@@ -1,6 +1,16 @@
' vim: filetype=vb shiftwidth=4 expandtab
'
' START_INDENT
+#Const Debug = False
+
+#If Win64 Then
+' Win64=true, Win32=true, Win16=false
+#ElseIf Win32 Then
+' Win32=true, Win16=false
+#Else
+' Win16=true
+#End If
+
Public Type GEmployeeRecord ' Create user-defined type.
ID As Integer ' Define elements of data type.
Name As String * 20
@@ -95,6 +105,9 @@ Public Sub TestMultiline (cellAddr As String, rowNbr As Long)
Dim rng As Range
Set rng = Range(cellAddr)
+
+ ' Line continuation is implemented as a two-character sequence-
+ ' whitespace followed by underscore.
With rng
.Cells(1,1).Value = _
"Line 1 of multiline string; " & _
@@ -102,14 +115,25 @@ Public Sub TestMultiline (cellAddr As String, rowNbr As Long)
"Line 3 of multiline string"
End With
- ' The following lines have whitespace after the underscore character
- ' and therefore do not form a valid multiline statement. The indent
- ' script correctly treats them as four single line statements contrary
- ' to the author's obvious indent.
- rng..Cells(1,1).Value = _
- "Line 1 of multiline string; " & _
- "Line 2 of multiline string; " & _
- "Line 3 of multiline string"
+ ' This code block omits the leading whitespace character and so
+ ' the trailing underscore will not be treated as line continuation.
+ With rng
+ .Cells(1,1).Value =_
+ "Line 1 of multiline string; " &_
+ "Line 2 of multiline string; " &_
+ "Line 3 of multiline string"
+ End With
+
+ ' The following lines have whitespace after the underscore character.
+ ' This is contrary to Microsoft documentation but it is reported that
+ ' some Microsoft editors allow it and will still treat the statement
+ ' as line-continued.
+ With rng
+ rng.Cells(1,1).Value = _
+ "Line 1 of multiline string; " & _
+ "Line 2 of multiline string; " & _
+ "Line 3 of multiline string"
+ End With
End Sub
@@ -121,6 +145,18 @@ stmtLabel:
End Sub
+Public Static Function TestStatic(addend As Integer)
+ Dim Integer accumulator
+ accumulator = accumulator + addend
+ TestStatic = accumulator
+End Function
+
+Friend Function TestFriend(addend As Integer)
+ Static Integer accumulator
+ accumulator = accumulator + addend
+ TestFriend = accumulator
+End Function
+
Sub TestTypeKeyword()
Type EmployeeRecord ' Create user-defined type.
ID As Integer ' Define elements of data type.
@@ -131,4 +167,10 @@ Sub TestTypeKeyword()
End Type
Dim varType As EmployeeRecord
End Sub
+
+Sub TestDateLiteralAfterLineContinuation
+ Dim birthday as Date
+ birthday = _
+ #January 1, 1901#
+End Sub
' END_INDENT
diff --git a/runtime/indent/vb.vim b/runtime/indent/vb.vim
index bc7142f..a2a8185 100644
--- a/runtime/indent/vb.vim
+++ b/runtime/indent/vb.vim
@@ -1,155 +1,193 @@
-" Vim indent file
-" Language: VisualBasic (ft=vb) / Basic (ft=basic) / SaxBasic (ft=vb)
-" Author: Johannes Zellner <johannes@zellner.org>
-" Maintainer: Michael Soyka (mssr953@gmail.com)
-" Last Change: Fri, 18 Jun 2004 07:22:42 CEST
-" Small update 2010 Jul 28 by Maxim Kim
-" 2022/12/15: add support for multiline statements.
-" 2022/12/21: move VbGetIndent from global to script-local scope
-" 2022/12/26: recognize "Type" keyword
+vim9script
+
+# Vim indent file
+# Language: VisualBasic (ft=vb) / Basic (ft=basic) / SaxBasic (ft=vb)
+# Author: Johannes Zellner <johannes@zellner.org>
+# Maintainer: Michael Soyka (mssr953@gmail.com)
+# Contributors: Doug Kearns (dougkearns@gmail.com)
+# Last Change: Fri, 18 Jun 2004 07:22:42 CEST
+# Small update 2010 Jul 28 by Maxim Kim
+# 2022/12/15: add support for multiline statements.
+# 2022/12/21: move VbGetIndent from global to script-local scope
+# 2022/12/26: recognize "Type" keyword
+# 2023/07/13: correct/extend line continuation pattern (Doug Kearns)
+# 2023/07/14: add more keywords; various optimizations (Doug Kearns)
+# 2023/07/20: convert to Vim9 script
+# 2023/07/23: improve detection of preproc directives (Doug Kearns)
if exists("b:did_indent")
finish
endif
-let b:did_indent = 1
+b:did_indent = v:true
setlocal autoindent
-setlocal indentexpr=s:VbGetIndent(v:lnum)
+setlocal indentexpr=VbGetIndent()
setlocal indentkeys&
setlocal indentkeys+==~else,=~elseif,=~end,=~wend,=~case,=~next,=~select,=~loop
-let b:undo_indent = "set ai< indentexpr< indentkeys<"
+b:undo_indent = "setlocal autoindent< indentexpr< indentkeys<"
-" Only define the function once.
-if exists("*s:VbGetIndent")
+# Only define the function once.
+if exists("*VbGetIndent")
finish
endif
-function s:VbGetIndent(lnum)
- let this_lnum = a:lnum
- let this_line = getline(this_lnum)
+# These regular expressions identify statement labels and preprocessor
+# directives.
+#
+const RE_LABEL: string = '^\s*\k\+:\s*$'
+const RE_PREPROC: string =
+ '^\s*#\%(const\|if\|elseif\|else\|end\|region\|enable\|disable\)\>'
+
+# Microsoft documentation states that line continuation is indicated by a
+# two-character sequence at end-of-line: a space character followed by an
+# underscore. Nonetheless, it has been reported that additional
+# whitespace after the underscore is also allowed. We will support both.
+# However, VB 16.0 also permits a comment after the underscore which,
+# for simplicity, we do not support.
+#
+const RE_LINE_CONTINUATION: string = '\s_\s*$'
+
+# The following regular expressions are used to increase the indent
+# after statements that open a new scope.
+#
+const RE_INCR_INDENT_1: string =
+ '^\s*\%(begin\|select\|case\|default\|if\|else\|elseif\|do\|for\|while\|with\)\>'
+const RE_INCR_INDENT_2: string =
+ '^\s*\%(\%(private\|public\|friend\)\s\+\)\=\%(static\s\+\)\=\%(function\|sub\|property\)\>'
+const RE_INCR_INDENT_3: string =
+ '^\s*\%(\%(private\|public\)\s\+\)\=\%(enum\|type\)\>'
- " labels and preprocessor get zero indent immediately
- let LABELS_OR_PREPROC = '^\s*\(\<\k\+\>:\s*$\|#.*\)'
- if this_line =~? LABELS_OR_PREPROC
- return 0
+def VbGetIndent(): number
+ var this_lnum: number = v:lnum
+ var this_line: string = getline(this_lnum)
+ var this_indent: number = 0
+
+ # labels and preprocessor statements get zero indent immediately
+ if (this_line =~? RE_LABEL) || (this_line =~? RE_PREPROC)
+ return this_indent
endif
-
- " Get the current value of "shiftwidth"
- let bShiftwidth = shiftwidth()
- " Find a non-blank line above the current line.
- " Skip over labels and preprocessor directives.
- let lnum = this_lnum
+ # Get the current value of 'shiftwidth'
+ const SHIFTWIDTH: number = shiftwidth()
+
+ # Find a non-blank line above the current line.
+ # Skip over labels and preprocessor directives.
+ var lnum: number = this_lnum
+ var previous_line: string
while lnum > 0
- let lnum = prevnonblank(lnum - 1)
- let previous_line = getline(lnum)
- if previous_line !~? LABELS_OR_PREPROC
+ lnum = prevnonblank(lnum - 1)
+ previous_line = getline(lnum)
+ if (previous_line !~? RE_LABEL) || (previous_line !~? RE_PREPROC)
break
endif
endwhile
- " Hit the start of the file, use zero indent.
+ # Hit the start of the file, use zero indent.
if lnum == 0
- return 0
+ return this_indent
endif
- " Variable "previous_line" now contains the text in buffer line "lnum".
-
- " Multi-line statements have the underscore character at end-of-line:
- "
- " object.method(arguments, _
- " arguments, _
- " arguments)
- "
- " and require extra logic to determine the correct indentation.
- "
- " Case 1: Line "lnum" is the first line of a multiline statement.
- " Line "lnum" will have a trailing underscore character
- " but the preceding non-blank line does not.
- " Line "this_lnum" will be indented relative to "lnum".
- "
- " Case 2: Line "lnum" is the last line of a multiline statement.
- " Line "lnum" will not have a trailing underscore character
- " but the preceding non-blank line will.
- " Line "this_lnum" will have the same indentation as the starting
- " line of the multiline statement.
- "
- " Case 3: Line "lnum" is neither the first nor last line.
- " Lines "lnum" and "lnum-1" will have a trailing underscore
- " character.
- " Line "this_lnum" will have the same indentation as the preceding
- " line.
- "
- " No matter which case it is, the starting line of the statement must be
- " found. It will be assumed that multiline statements cannot have
- " intermingled comments, statement labels, preprocessor directives or
- " blank lines.
- "
- let lnum_is_continued = (previous_line =~ '_$')
+ # Variable "previous_line" now contains the text in buffer line "lnum".
+
+ # Multi-line statements have the underscore character at end-of-line:
+ #
+ # object.method(arguments, _
+ # arguments, _
+ # arguments)
+ #
+ # and require extra logic to determine the correct indentation.
+ #
+ # Case 1: Line "lnum" is the first line of a multiline statement.
+ # Line "lnum" will have a trailing underscore character
+ # but the preceding non-blank line does not.
+ # Line "this_lnum" will be indented relative to "lnum".
+ #
+ # Case 2: Line "lnum" is the last line of a multiline statement.
+ # Line "lnum" will not have a trailing underscore character
+ # but the preceding non-blank line will.
+ # Line "this_lnum" will have the same indentation as the starting
+ # line of the multiline statement.
+ #
+ # Case 3: Line "lnum" is neither the first nor last line.
+ # Lines "lnum" and "lnum-1" will have a trailing underscore
+ # character.
+ # Line "this_lnum" will have the same indentation as the preceding
+ # line.
+ #
+ # No matter which case it is, the starting line of the statement must be
+ # found. It will be assumed that multiline statements cannot have
+ # intermingled comments, statement labels, preprocessor directives or
+ # blank lines.
+ #
+ var lnum_is_continued: bool = (previous_line =~? RE_LINE_CONTINUATION)
+ var before_lnum: number
+ var before_previous_line: string
if lnum > 1
- let before_lnum = prevnonblank(lnum-1)
- let before_previous_line = getline(before_lnum)
+ before_lnum = prevnonblank(lnum - 1)
+ before_previous_line = getline(before_lnum)
else
- let before_lnum = 0
- let before_previous_line = ""
+ before_lnum = 0
+ before_previous_line = ""
endif
- if before_previous_line !~ '_$'
- " Variable "previous_line" contains the start of a statement.
- "
- let ind = indent(lnum)
+ if before_previous_line !~? RE_LINE_CONTINUATION
+ # Variable "previous_line" contains the start of a statement.
+ #
+ this_indent = indent(lnum)
if lnum_is_continued
- let ind += bShiftwidth
+ this_indent += SHIFTWIDTH
endif
elseif ! lnum_is_continued
- " Line "lnum" contains the last line of a multiline statement.
- " Need to find where this multiline statement begins
- "
+ # Line "lnum" contains the last line of a multiline statement.
+ # Need to find where this multiline statement begins
+ #
while before_lnum > 0
- let before_lnum -= 1
- if getline(before_lnum) !~ '_$'
- let before_lnum += 1
+ before_lnum -= 1
+ if getline(before_lnum) !~? RE_LINE_CONTINUATION
+ before_lnum += 1
break
endif
endwhile
if before_lnum == 0
- let before_lnum = 1
+ before_lnum = 1
endif
- let previous_line = getline(before_lnum)
- let ind = indent(before_lnum)
+ previous_line = getline(before_lnum)
+ this_indent = indent(before_lnum)
else
- " Line "lnum" is not the first or last line of a multiline statement.
- "
- let ind = indent(lnum)
+ # Line "lnum" is not the first or last line of a multiline statement.
+ #
+ this_indent = indent(lnum)
endif
- " Add
- if previous_line =~? '^\s*\<\(begin\|\%(\%(private\|public\|friend\)\s\+\)\=\%(function\|sub\|property\|enum\|type\)\|select\|case\|default\|if\|else\|elseif\|do\|for\|while\|with\)\>'
- let ind = ind + bShiftwidth
+ # Increment indent
+ if (previous_line =~? RE_INCR_INDENT_1) ||
+ (previous_line =~? RE_INCR_INDENT_2) ||
+ (previous_line =~? RE_INCR_INDENT_3)
+ this_indent += SHIFTWIDTH
endif
- " Subtract
- if this_line =~? '^\s*\<end\>\s\+\<select\>'
- if previous_line !~? '^\s*\<select\>'
- let ind = ind - 2 * bShiftwidth
+ # Decrement indent
+ if this_line =~? '^\s*end\s\+select\>'
+ if previous_line !~? '^\s*select\>'
+ this_indent -= 2 * SHIFTWIDTH
else
- " this case is for an empty 'select' -- 'end select'
- " (w/o any case statements) like:
- "
- " select case readwrite
- " end select
- let ind = ind - bShiftwidth
+ # this case is for an empty 'select' -- 'end select'
+ # (w/o any case statements) like:
+ #
+ # select case readwrite
+ # end select
+ this_indent -= SHIFTWIDTH
endif
- elseif this_line =~? '^\s*\<\(end\|else\|elseif\|until\|loop\|next\|wend\)\>'
- let ind = ind - bShiftwidth
- elseif this_line =~? '^\s*\<\(case\|default\)\>'
- if previous_line !~? '^\s*\<select\>'
- let ind = ind - bShiftwidth
+ elseif this_line =~? '^\s*\%(end\|else\|elseif\|until\|loop\|next\|wend\)\>'
+ this_indent -= SHIFTWIDTH
+ elseif this_line =~? '^\s*\%(case\|default\)\>'
+ if previous_line !~? '^\s*select\>'
+ this_indent -= SHIFTWIDTH
endif
endif
- return ind
-endfunction
+ return this_indent
+enddef
-" vim:sw=4
+# vim:sw=4
diff --git a/runtime/keymap/georgian-qwerty.vim b/runtime/keymap/georgian-qwerty.vim
new file mode 100644
index 0000000..df18729
--- /dev/null
+++ b/runtime/keymap/georgian-qwerty.vim
@@ -0,0 +1,51 @@
+" Vim keymap file for Georgian (Mkhedruli) layout
+" Maintainer: Mishiko Okropiridze <misho.okropiridze@gmail.com>
+" Last changed: 2024-06-14
+
+
+let b:keymap_name = "ge"
+
+loadkeymap
+a ა
+A ა
+b ბ
+c ც
+C ჩ
+d დ
+e ე
+E ე
+f ფ
+F ფ
+g გ
+G გ
+h ჰ
+H ჵ
+i ი
+I ი
+j ჯ
+J ჟ
+k კ
+l ლ
+m მ
+n ნ
+o ო
+p პ
+q ქ
+Q ქ
+r რ
+R ღ
+s ს
+S შ
+t ტ
+T თ
+u უ
+v ვ
+V ვ
+w წ
+W ჭ
+x ხ
+X ხ
+y ყ
+Y ყ
+z ზ
+Z ძ
diff --git a/runtime/lang/menu_af_af.latin1.vim b/runtime/lang/menu_af_af.latin1.vim
index 649c4e1..4f44a7c 100644
--- a/runtime/lang/menu_af_af.latin1.vim
+++ b/runtime/lang/menu_af_af.latin1.vim
@@ -1,6 +1,6 @@
" Menu Translations: Afrikaas
" Maintainer: Danie Roux <droux@tuks.co.za>
-" Last Change: 2012 May 01
+" Last Change: 2024 May 2
" Original translations
" Quit when menu translations have already been done.
@@ -31,12 +31,13 @@ menutrans &About &Inleiding\ skerm
" File menu
menutrans &File &Ler
-menutrans &Open\.\.\.<Tab>:e &Open\.\.\.<Tab>:e
+menutrans &Open\.\.\.<Tab>:e Maak\ oop\.\.\.<Tab>:e
menutrans Sp&lit-Open\.\.\.<Tab>:sp Maak\ oop\ in\ nuwe\ &venster\.\.\.<Tab>:sp
+menutrans Open\ &Tab\.\.\.<Tab>:tabnew Maak\ oortjie\ oop\.\.\.<Tab>:tabnew
menutrans &New<Tab>:enew &Nuut<Tab>:enew
menutrans &Close<Tab>:close Maak\ &Toe<Tab>:close
menutrans &Save<Tab>:w &Skryf<Tab>:w
-menutrans Save\ &As\.\.\.<Tab>:w Skryf\ &as\.\.\.<Tab>:w
+menutrans Save\ &As\.\.\.<Tab>:sav Skryf\ &as\.\.\.<Tab>:sav
menutrans &Print &Druk
menutrans Sa&ve-Exit<Tab>:wqa Skryf\ en\ verlaat<Tab>:wqa
menutrans E&xit<Tab>:qa &Verlaat<Tab>:qa
@@ -68,16 +69,18 @@ menutrans &Next\ Error<Tab>:cn Volgende\ Fout<Tab>:cn
menutrans &Previous\ Error<Tab>:cp Vorige\ Fout<Tab>:cp
menutrans &Older\ List<Tab>:cold &Ouer\ Lys<Tab>:cold
menutrans N&ewer\ List<Tab>:cnew &Nuwer\ Lys<Tab>:cnew
-menutrans Error\ &Window<Tab>:cwin Foute\ Venster<Tab>:cwin
-menutrans Convert\ to\ HEX<Tab>:%!xxd Verwissel\ na\ HEX<Tab>:%!xxd
-menutrans Convert\ back<Tab>:%!xxd\ -r Verwissel\ terug<Tab>:%!xxd\ -r
+menutrans Error\ &Window Foute\ Venster<Tab>:cwin
+menutrans &Convert\ to\ HEX<Tab>:%!xxd Verwissel\ na\ HEX<Tab>:%!xxd
+menutrans Conve&rt\ back<Tab>:%!xxd\ -r Verwissel\ terug<Tab>:%!xxd\ -r
" Names for buffer menu.
menutrans &Buffers &Buffers
-menutrans Refresh Verfris
+menutrans &Refresh\ menu Verfris
menutrans Delete Verwyder
menutrans Alternate Vorige
-menutrans [No\ File] [Geen\ Ler]
+menutrans [No\ Name] [Geen\ Ler]
+menutrans &Next Volgende
+menutrans &Previous Vorige
" Window menu
menutrans &Window &Venster
@@ -92,8 +95,8 @@ menutrans P&revious<Tab>^WW &Vorige<Tab>^WW
menutrans &Equal\ Size<Tab>^W= &Gelyke\ hoogte<Tab>^W=
menutrans &Max\ Height<Tab>^W_ &Maksimale\ hoogte<Tab>^W_
menutrans M&in\ Height<Tab>^W1_ Mi&nimale\ hoogte<Tab>^W1_
-menutrans Max\ Width<Tab>^W\| Maksimale\ breedte<Tab>^W\|
-menutrans Min\ Width<Tab>^W1\| Minimale\ breedte<Tab>^W1\|
+menutrans Max\ &Width<Tab>^W\| Maksimale\ breedte<Tab>^W\|
+menutrans Min\ Widt&h<Tab>^W1\| Minimale\ breedte<Tab>^W1\|
menutrans Rotate\ &Up<Tab>^WR Roteer\ na\ &bo<Tab>^WR
menutrans Rotate\ &Down<Tab>^Wr Roteer\ na\ &onder<Tab>^Wr
menutrans Select\ Fo&nt\.\.\. Kies\ font\.\.\.
@@ -153,6 +156,107 @@ menutrans o&ff\ (this\ file) &Af\ (die\ ler)
menutrans Co&lor\ test Toets\ die\ &kleure
menutrans &Highlight\ test Toets\ die\ verligting
menutrans &Convert\ to\ HTML Verwissel\ na\ HTML
+menutrans Split\ &Diff\ with\.\.\. Verdeel\ ewenaar\ met\.\.\.
+menutrans Split\ Patched\ &By\.\.\. Verdeel\ gelap\ deur\.\.\.
+menutrans Settings\ &Window Instellings\ venster\.\.\.
+menutrans Startup\ &Settings Opstart\ instellings
+menutrans &Global\ Settings Globale\ instellings
+menutrans F&ile\ Settings Ler\ instellings
+menutrans C&olor\ Scheme Kleurskema
+menutrans &Keymap Sleutelkaart
+">>>----------------- Edit/Global settings
+menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Wissel\ patroon\ hoogtepunt<Tab>:set\ hls!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Wissel\ geval\ ignoreer<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Wissel\ wat\ ooreenstemmende\ pare\ wys<Tab>:set\ sm!
+menutrans &Context\ lines Kontekslyne
+menutrans &Virtual\ Edit Virtuele\ wysiging
+menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Wissel\ invoegmodus<Tab>:set\ im!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Wissel\ Vi\ verenigbaarheid<Tab>:set\ cp!
+menutrans Search\ &Path\.\.\. Soek\ pad\.\.\.
+menutrans Ta&g\ Files\.\.\. Merk\ lers\.\.\.
+"
+menutrans Toggle\ &Toolbar Wissel\ nutsbalk
+menutrans Toggle\ &Bottom\ Scrollbar Wissel\ onderste\ skuifbalk
+menutrans Toggle\ &Left\ Scrollbar Wissel\ linker\ skuifbalk
+menutrans Toggle\ &Right\ Scrollbar Wissel\ regs\ skuifbalk
+">>>->>>------------- Edit/Global settings/Virtual edit
+menutrans Never Nooit\ nie
+menutrans Block\ Selection Blokkeuse
+menutrans Insert\ mode Invoegmodus
+menutrans Block\ and\ Insert Blokkeer\ en\ plaas
+menutrans Always Altyd
+">>>----------------- Edit/File settings
+menutrans Toggle\ Line\ &Numbering<Tab>:set\ nu! Wissel\ lynnommering<Tab>:set\ nu!
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! Wissel\ relatiewe\ lynnommering<Tab>:set\ nru!
+menutrans Toggle\ &List\ Mode<Tab>:set\ list! Wissel\ lys\ modus<Tab>:set\ list!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! Wissel\ lyn\ wikkel<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! Wissel\ omvou\ by\ woord<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! Wissel\ oortjie\ wat\ uitbrei<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! Wissel\ outomatiese\ inkeping<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Wissel\ C-styl\ inkeping<Tab>:set\ cin!
+">>>---
+menutrans &Shiftwidth Skuifwydte
+menutrans Soft\ &Tabstop Sagte\ tabstop
+menutrans Te&xt\ Width\.\.\. Teks\ breedte\.\.\.
+menutrans &File\ Format\.\.\. Lerformaat\.\.\.
+">>>---------------- Tools/Spelling
+menutrans &Spell\ Check\ On Speltoets\ aan
+menutrans Spell\ Check\ &Off Spelmerk\ af
+menutrans To\ &Next\ error<Tab>]s Na\ die\ volgende\ fout<Tab>]s
+menutrans To\ &Previous\ error<Tab>[s Om\ vorige\ fout<Tab>[s
+menutrans Suggest\ &Corrections<Tab>z= Stel\ regstellings\ voor<Tab>z=
+menutrans &Repeat\ correction<Tab>:spellrepall Herhaal\ regstelling<Tab>:spellrepall
+"-------------------
+menutrans Set\ language\ to\ "en" Stel\ taal\ op\ "en"
+menutrans Set\ language\ to\ "en_au" Stel\ taal\ op\ "en_au"
+menutrans Set\ language\ to\ "en_ca" Stel\ taal\ op\ "en_ca"
+menutrans Set\ language\ to\ "en_gb" Stel\ taal\ op\ "en_gb"
+menutrans Set\ language\ to\ "en_nz" Stel\ taal\ op\ "en_nz"
+menutrans Set\ language\ to\ "en_us" Stel\ taal\ op\ "en_us"
+menutrans &Find\ More\ Languages Vind\ meer\ tale
+let g:menutrans_set_lang_to = 'Stel taal op'
+">>>---------------- Folds
+menutrans &Enable/Disable\ folds<Tab>zi Aktiveer/deaktiveer\ voue<Tab>zi
+menutrans &View\ Cursor\ Line<Tab>zv Bekyk\ wyserlyn<Tab>zv
+menutrans Vie&w\ Cursor\ Line\ only<Tab>zMzx Bekyk\ slegs\ wyserlyn<Tab>z\ Shift+M\ zx
+menutrans C&lose\ more\ folds<Tab>zm Maak\ nog\ voue\ toe<Tab>zm
+menutrans &Close\ all\ folds<Tab>zM Maak\ alle\ voue\ toe<Tab>z\ Shift+M
+menutrans &Open\ all\ folds<Tab>zR Maak\ alle\ voue\ oop<Tab>z\ Shift+R
+menutrans O&pen\ more\ folds<Tab>zr Maak\ meer\ voue\ oop<Tab>zr
+menutrans Fold\ Met&hod Vou\ metode
+menutrans Create\ &Fold<Tab>zf Skep\ vou<Tab>zf
+menutrans &Delete\ Fold<Tab>zd Vee\ vou\ uit<Tab>zd
+menutrans Delete\ &All\ Folds<Tab>zD Vee\ alle\ voue\ uit<Tab>z\ Shift+D
+menutrans Fold\ col&umn\ width Vou\ kolomwydte
+">>>->>>----------- Tools/Folds/Fold Method
+menutrans M&anual Handleiding
+menutrans I&ndent Inkeep
+menutrans E&xpression Uitdrukking
+menutrans S&yntax Sintaksis
+menutrans &Diff Verskil
+menutrans Ma&rker Merker
+">>>--------------- Sub of Tools/Diff
+menutrans &Update Opdateer
+menutrans &Get\ Block Kry\ blok
+menutrans &Put\ Block Sit\ blok
+">>>--------------- Tools/Error window
+menutrans &Update<Tab>:cwin Opdateer<Tab>:cwin
+menutrans &Close<Tab>:cclose Naby<Tab>:cclose
+menutrans &Open<Tab>:copen Maak\ oop<Tab>:copen
+menutrans Se&T\ Compiler Stel\ samesteller
+menutrans &Show\ File\ Types\ in\ menu Wys\ lertipes\ in\ kieslys
+menutrans on/off\ for\ &This\ file Aan/af\ vir\ hierdie\ ler
+menutrans Split\ File\ E&xplorer Verdeel\ lerverkenner
+menutrans Move\ &To Skuif\ na
+">>>----------------- Submenu of Window/Move To
+menutrans &Top<Tab>^WK Top<Tab>Ctrl+W\ Shift+K
+menutrans &Bottom<Tab>^WJ Onderkant<Tab>Ctrl+W\ Shift+J
+menutrans &Left\ side<Tab>^WH Linkerkant<Tab>Ctrl+W\ Shift+H
+menutrans &Right\ side<Tab>^WL Regter\ kant<Tab>Ctrl+W\ Shift+L
+menutrans &User\ Manual Gebruikers\ gids
+menutrans &Sponsor/Register Borg/registreer
+menutrans &Folding Vou
+menutrans &Spelling &Spelling
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_ca_es.latin1.vim b/runtime/lang/menu_ca_es.latin1.vim
index 8fed314..47dc3be 100644
--- a/runtime/lang/menu_ca_es.latin1.vim
+++ b/runtime/lang/menu_ca_es.latin1.vim
@@ -1,7 +1,7 @@
" Menu translations for Catalan
"
" Maintainer: Ernest Adrogu <eadrogue@gmx.net>
-" Last Change: 26 Jul 2017
+" Last Change: 2024 May 2
" Original translations
" Quit when menu translations have already been done.
@@ -71,8 +71,8 @@ menutrans Startup\ &Settings Opcions\ i&nicials
menutrans &Global\ Settings Opcions\ &globals
" submen Edita/Opcions Globals
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Ressaltat\ de\ &patrons<Tab>:set\ hls!
- menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Sensibilitat\ a\ les\ ma&jscules<Tab>:set\ ic!
- menutrans Toggle\ &Showmatch<Tab>:set\ sm! &Ressaltat\ de\ coincidncies<Tab>:set\ sm!
+ menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Sensibilitat\ a\ les\ ma&jscules<Tab>:set\ ic!
+ menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! &Ressaltat\ de\ coincidncies<Tab>:set\ sm!
menutrans &Context\ lines Lnies\ de\ co&ntext
menutrans &Virtual\ Edit Edici\ &virtual
" submen Edita/Opcions Globals/Edici virtual
@@ -82,7 +82,7 @@ menutrans &Global\ Settings Opcions\ &globals
menutrans Block\ and\ Insert &Blocs\ i\ inserci
menutrans Always S&empre
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Mode\ d'&inserci<Tab>:set\ im!
- menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Co&mpatible\ amb\ Vi<Tab>:set\ cp!
+ menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Co&mpatible\ amb\ Vi<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. &Ubicacions\.\.\.
menutrans Ta&g\ Files\.\.\. Fitxers\ d'&etiquetes\.\.\.
menutrans Toggle\ &Toolbar &Barra\ d'eines
@@ -312,5 +312,12 @@ menutrans Config Configuraci
menutrans Set\ '&syntax'\ only Noms\ el\ ressaltat\ de\ sintaxi
menutrans Set\ '&filetype'\ too Carrega\ tamb\ els\ plugins
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! Commuta\ numeraci\ relativa\ de\ lnies<Tab>:set\ nru!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! Commuta\ embolcall\ de\ lnia<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! Commuta\ embolicant\ la\ paraula<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! Commuta\ pestanya\ en\ expansi<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! Commuta\ sagnat\ automtic<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Commuta\ Sagnat\ d'estil\ C<Tab>:set\ cin!
+
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_cs_cz.utf-8.vim b/runtime/lang/menu_cs_cz.utf-8.vim
index 4673bc5..e86391a 100644
--- a/runtime/lang/menu_cs_cz.utf-8.vim
+++ b/runtime/lang/menu_cs_cz.utf-8.vim
@@ -2,6 +2,7 @@
" Maintainer: Jiri Sedlak <jiri_sedlak@users.sourceforge.net>
" Previous maintainer: Jiri Brezina
" Based on: menu.vim (2012-10-21)
+" Last Change: 2024 May 2
" Original translations
" Quit when menu translations have already been done.
@@ -63,8 +64,8 @@ menutrans Settings\ &Window Nastav&ení\ okna
menutrans Startup\ &Settings Počáteční\ &nastavení
menutrans &Global\ Settings &Globální\ nastavení
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! &Přepnout\ zvýraznění\ vzoru<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Přepnout\ ignorování\ &VERZÁLEK<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Přepnout\ &Showmatch\ \{\(\[\])\}<Tab>:set\ sm!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Přepnout\ ignorování\ &VERZÁLEK<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Přepnout\ &Showmatch\ \{\(\[\])\}<Tab>:set\ sm!
menutrans &Context\ lines Zobrazit\ konte&xt\ kurzoru
menutrans &Virtual\ Edit Virtuální\ p&ozice\ kurzoru
menutrans Never Nikdy
@@ -73,7 +74,7 @@ menutrans Insert\ mode Insert\ mód
menutrans Block\ and\ Insert Blok\ a\ Insert
menutrans Always Vždycky
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Přepnout\ Insert\ mó&d<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Přepnout\ kompatibilní\ režim\ s\ 'vi'<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Přepnout\ kompatibilní\ režim\ s\ 'vi'<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Nastavit\ &cestu\ k\ prohledávání\.\.\.
menutrans Ta&g\ Files\.\.\. Ta&g\ soubory\.\.\.
menutrans Toggle\ &Toolbar Přepnout\ &Toolbar
@@ -85,11 +86,11 @@ menutrans F&ile\ Settings Nastavení\ so&uboru
menutrans Toggle\ Line\ &Numbering<Tab>:set\ nu! Přepnout\ číslování\ řá&dků<Tab>:set\ nu!
menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! Přepnout\ relativní\ číslování\ řá&dků<Tab>:set\ rnu!
menutrans Toggle\ &List\ Mode<Tab>:set\ list! Přepnout\ &List\ mód<Tab>:set\ list!
-menutrans Toggle\ Line\ &Wrap<Tab>:set\ wrap! Přepnout\ zala&mování\ řádků<Tab>:set\ wrap!
-menutrans Toggle\ W&rap\ at\ word<Tab>:set\ lbr! Přepnout\ zl&om\ ve\ slově<Tab>:set\ lbr!
-menutrans Toggle\ &expand-tab<Tab>:set\ et! Přepnout\ &expand-tab<Tab>:set\ et!
-menutrans Toggle\ &auto-indent<Tab>:set\ ai! Přepnout\ &auto-indent<Tab>:set\ ai!
-menutrans Toggle\ &C-indenting<Tab>:set\ cin! Přepnout\ &C-indenting<Tab>:set\ cin!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! Přepnout\ zala&mování\ řádků<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! Přepnout\ zl&om\ ve\ slově<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! Přepnout\ &expand-tab<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! Přepnout\ &auto-indent<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Přepnout\ &C-indenting<Tab>:set\ cin!
menutrans &Shiftwidth Nastav&it\ šířku\ od&sazení
menutrans Soft\ &Tabstop Nastavit\ Soft\ &Tabstop
menutrans Te&xt\ Width\.\.\. Šířka\ te&xtu\.\.\.
@@ -154,7 +155,7 @@ if has("diff")
menutrans &Put\ Block &Vložit\ Blok
endif
-menutrans &Make<Tab>:make &Make<Tab>:make
+menutrans &Make<Tab>:make udělat<Tab>:make
menutrans &List\ Errors<Tab>:cl Výpis\ &chyb<Tab>:cl
menutrans L&ist\ Messages<Tab>:cl! Výp&is\ zpráv<Tab>:cl!
menutrans &Next\ Error<Tab>:cn Další\ ch&yba<Tab>:cn
@@ -300,6 +301,7 @@ let g:menutrans_tags_dialog = "Zadejte jména souborů s tagy. Jména oddělte
let g:menutrans_textwidth_dialog = "Zadejte délku řádku (0 pro zakázání formátování):"
let g:menutrans_fileformat_dialog = "Vyberte typ konce řádků"
" }}}"
+menutrans &Show\ File\ Types\ in\ menu Zobrazit\ typy\ souborů\ v\ nabídce
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_de_de.latin1.vim b/runtime/lang/menu_de_de.latin1.vim
index 208d4d5..f915828 100644
--- a/runtime/lang/menu_de_de.latin1.vim
+++ b/runtime/lang/menu_de_de.latin1.vim
@@ -1,9 +1,9 @@
" Menu Translations: German / Deutsch
" Maintainer: Jn Arnar Briem <jonbriem@gmail.com>
-" Originally By: Georg Dahn <gorgyd@yahoo.co.uk>
-" Marcin Dalecki <dalecki@cs.net.pl>
-" Johannes Zellner <johannes@zellner.org>
-" Last Change: Mon, 1 April 2019
+" Originally By: Georg Dahn <gorgyd@yahoo.co.uk>
+" Marcin Dalecki <dalecki@cs.net.pl>
+" Johannes Zellner <johannes@zellner.org>
+" Last Change: 2024 May 2
" vim:set foldmethod=marker tabstop=8:
" Original translations
@@ -74,7 +74,7 @@ menutrans Insert\ mode Einfge-Modus
menutrans Block\ and\ Insert Block-Auswahl\ und\ Einfge-Modus
menutrans Always Immer
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Einfge-&Modus\ ein-\ und\ ausschalten<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Vi-Kompatibilitt\ ein-\ und\ ausschalten<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Vi-Kompatibilitt\ ein-\ und\ ausschalten<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Such-&Pfad\.\.\.
menutrans Ta&g\ Files\.\.\. Ta&g-Dateien\.\.\.
@@ -183,7 +183,7 @@ menutrans Conve&rt\ back<Tab>:%!xxd\ -r Zurck\ konvertieren<Tab>:%!xxd\ -r
" {{{ SYNTAX / SYNTAX
menutrans &Syntax &Syntax
-menutrans &Show\ filetypes\ in\ menu Dateitypen\ an&zeigen
+menutrans &Show\ File\ Types\ in\ menu Dateitypen\ an&zeigen
menutrans Set\ '&syntax'\ only Nur\ '&syntax'\ setzen
menutrans Set\ '&filetype'\ too Auch\ '&filetype'\ setzen
menutrans &Off &Aus
diff --git a/runtime/lang/menu_es_es.latin1.vim b/runtime/lang/menu_es_es.latin1.vim
index 4920d59..cd96517 100644
--- a/runtime/lang/menu_es_es.latin1.vim
+++ b/runtime/lang/menu_es_es.latin1.vim
@@ -1,8 +1,8 @@
" Menu Translations: Espaol
" Previous translator: Alejandro Lpez-Valencia <dradul@users.sourceforge.net>
" Last translator: Omar Campagne Polaino <ocampagne@gmail.com>
-" Version: 7.2.245
-" Last Change: 2012 May 01
+" Version: 9.1.385
+" Last Change: 2024 May 1
" Original translations
" Quit when menu translations have already been done.
@@ -75,8 +75,8 @@ menutrans Startup\ &Settings Opciones\ de\ arranque
menutrans &Global\ Settings Opciones\ &globales
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Activar/Desactivar\ &resaltado\ de\ sintaxis<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Activar/Desactivar\ &ignorar\ maysculas\ y\ minsculas<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Activar/Desactivar\ &mostrar\ coincidencias<Tab>:set\ sm!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Activar/Desactivar\ &ignorar\ maysculas\ y\ minsculas<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Activar/Desactivar\ &mostrar\ coincidencias<Tab>:set\ sm!
menutrans &Context\ lines Lneas\ de\ &contexto
@@ -88,7 +88,7 @@ menutrans Block\ and\ Insert Bloque\ e\ insercin
menutrans Always Siempre
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Activar/Desactivar\ modo\ de\ in&sercin<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Activar/Desactivar\ compatiblidad\ con\ Vi<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Activar/Desactivar\ compatiblidad\ con\ Vi<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Ruta\ de\ &bsqueda\.\.\.
@@ -170,7 +170,7 @@ menutrans &Previous\ Error<Tab>:cp Error\ p&revio<Tab>:cp
menutrans &Older\ List<Tab>:cold Lista\ de\ &viejos\ a\ nuevos<Tab>:cold
menutrans N&ewer\ List<Tab>:cnew Lista\ de\ &nuevos\ a\ viejos<Tab>:cnew
menutrans Error\ &Window Ven&tana\ de\ errores
-menutrans &Set\ Compiler Esco&ger\ el\ compilador\ a\ usar
+menutrans Se&T\ Compiler Esco&ger\ el\ compilador\ a\ usar
menutrans &Convert\ to\ HEX<Tab>:%!xxd Convertir\ a\ formato\ &hexadecimal<Tab>:%!xxd
menutrans Conve&rt\ back<Tab>:%!xxd\ -r &Convertir\ al\ formato\ original<Tab>:%!xxd\ -r
@@ -319,5 +319,15 @@ menutrans &Convert\ to\ HTML &Convertir\ a\ HTML
" Find Help dialog text
let g:menutrans_help_dialog = "Introduzca un nombre de comando o palabra para obtener ayuda;\n\nAnteponga i_ para comandos de entrada (e.g.: i_CTRL-X)\nAnteponga c_ para comandos de la lnea de comandos (e.g.: c_<Del>)\nAnteponga ` para un nombre de opcin (e.g.: `shiftwidth`)"
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! Activar/Desactivar\ numeracin\ de\ lneas\ relativa<Tab>:set\ nru!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! Activar/Desactivar\ ajuste\ de\ lnea<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! Activar/Desactivar\ envolviendo\ la\ palabra<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! Activar/Desactivar\ pestaa\ expandindose<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! Activar/Desactivar\ sangra\ automtica<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Activar/Desactivar\ Sangra\ estilo\ C<Tab>:set\ cin!
+menutrans &Show\ File\ Types\ in\ menu Mostrar\ tipos\ de\ archivos\ en\ el\ men
+menutrans Ma&rker Marcador
+menutrans I&ndent Sangrar
+menutrans E&xpression Expresin
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_is_is.latin1.vim b/runtime/lang/menu_is_is.latin1.vim
index 102dede..1572da6 100644
--- a/runtime/lang/menu_is_is.latin1.vim
+++ b/runtime/lang/menu_is_is.latin1.vim
@@ -1,7 +1,7 @@
" Menu Translations: Icelandic / slenska
" Maintainer: Jn Arnar Briem <jonbriem@gmail.com>
" Originally By: Jn Arnar Briem <jonbriem@gmail.com>
-" Last Change: Sun, 24 Mar 2019 22:40:00 CEST
+" Last Change: 2024 May 2
" Original translations
" vim:set foldmethod=marker tabstop=8:
@@ -301,6 +301,7 @@ let g:menutrans_tags_dialog = "Sli inn nafn Merkjaskra.
let g:menutrans_textwidth_dialog = "Sli inn nja textabreidd (0 til a virkja snimtun): "
let g:menutrans_fileformat_dialog = "Velji Skrarsni"
" }}}
+menutrans &Show\ File\ Types\ in\ menu Sna\ skrargerir\ \ valmyndinni
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_ko_kr.utf-8.vim b/runtime/lang/menu_ko_kr.utf-8.vim
index f8d018b..6674a00 100644
--- a/runtime/lang/menu_ko_kr.utf-8.vim
+++ b/runtime/lang/menu_ko_kr.utf-8.vim
@@ -1,6 +1,6 @@
" Menu Translations: Korean
" Maintainer: SungHyun Nam <goweol@gmail.com>
-" Last Change: 2012 May 01
+" Last Change: 2024 May 2
" Original translations
" Quit when menu translations have already been done.
@@ -36,8 +36,8 @@ menutrans &New<Tab>:enew 새로운(&N)<Tab>:enew
menutrans &Close<Tab>:close 닫기(&C)<Tab>:close
menutrans &Save<Tab>:w 저장(&S)<Tab>:w
menutrans Save\ &As\.\.\.<Tab>:sav 다른\ 이름으로\ 저장(&A)\.\.\.<Tab>:sav
-"menutrans Split\ &Diff\ with\.\.\. Split\ &Diff\ with\.\.\.
-"menutrans Split\ Patched\ &By\.\.\. Split\ Patched\ &By\.\.\.
+menutrans Split\ &Diff\ with\.\.\. 분할\ 차이점\.\.\.
+menutrans Split\ Patched\ &By\.\.\. 분할\ 패치\ 기준\.\.\.
menutrans &Print 인쇄(&P)
menutrans Sa&ve-Exit<Tab>:wqa 저장하고\ 끝내기(&v)<Tab>:wqa
menutrans E&xit<Tab>:qa 끝내기(&x)<Tab>:qa
@@ -62,8 +62,8 @@ menutrans Startup\ &Settings 시작\ 설정(&S)
" Edit/Global Settings
menutrans &Global\ Settings 전역\ 설정(&G)
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! 패턴\ 하이라이트\ 토글(&H)<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! 대소문자\ 구분\ 토글(&I)<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Showmatch\ 토글(&S)<Tab>:set\ sm!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! 대소문자\ 구분\ 토글(&I)<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Showmatch\ 토글(&S)<Tab>:set\ sm!
menutrans &Context\ lines 콘텍스트\ 줄(&C)
menutrans &Virtual\ Edit 가상\ 편집(&V)
menutrans Never 사용\ 안\ 함
@@ -72,7 +72,7 @@ menutrans Insert\ mode 삽입\ 모드
menutrans Block\ and\ Insert 블럭과\ 삽입
menutrans Always 항상\ 사용
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! 삽입\ 모드\ 토글(&M)<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Vi\ 호환\ 토글(&o)<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Vi\ 호환\ 토글(&o)<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. 찾기\ 경로(&P)\.\.\.
menutrans Ta&g\ Files\.\.\. 꼬리표\ 파일(&g)\.\.\.
@@ -141,14 +141,14 @@ menutrans M&anual 수동(&a)
menutrans I&ndent 들여쓰기(&n)
menutrans E&xpression 표현식(&x)
menutrans S&yntax 신택스(&y)
-"menutrans &Diff &Diff
+menutrans &Diff 차이점
menutrans Ma&rker 꼬리표(&r)
" create and delete folds
menutrans Create\ &Fold<Tab>zf 접기\ 생성(&F)<Tab>zf
menutrans &Delete\ Fold<Tab>zd 접기\ 삭제(&D)<Tab>zd
menutrans Delete\ &All\ Folds<Tab>zD 모든\ 접기\ 삭제(&A)<Tab>zD
" moving around in folds
-menutrans Fold\ column\ &width 접기\ 컬럼\ 너비(&w)
+menutrans Fold\ col&umn\ width 접기\ 컬럼\ 너비(&w)
"menutrans &Diff &Diff
menutrans &Update 갱신(&U)
@@ -261,6 +261,13 @@ menutrans on/off\ for\ &This\ file 이\ 파일만\ 켜기/끄기(&T)
menutrans Co&lor\ test 색\ 시험(&l)
menutrans &Highlight\ test Highlight\ 시험(&H)
menutrans &Convert\ to\ HTML HTML로\ 변환(&C)
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! Toggle\ 상대\ 줄\ 번호\ 매기기<Tab>:set\ nru!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! 줄\ 바꿈\ 전환<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! Toggle\ Word에서\ 줄\ 바꿈<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! 탭\ 확장\ 전환<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! 자동\ 들여쓰기\ 전환<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! C\ 스타일\ 들여쓰기\ 전환<Tab>:set\ cin!
+menutrans &Show\ File\ Types\ in\ menu 메뉴에\ 파일\ 형식\ 표시
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_nl_nl.latin1.vim b/runtime/lang/menu_nl_nl.latin1.vim
index 908d58d..eadfc7b 100644
--- a/runtime/lang/menu_nl_nl.latin1.vim
+++ b/runtime/lang/menu_nl_nl.latin1.vim
@@ -1,6 +1,6 @@
" Menu Translations: Nederlands
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2023 Aug 13
+" Last Change: 2024 May 2
" Original translations
" Quit when menu translations have already been done.
@@ -24,8 +24,8 @@ menutrans &User\ Manual Gebruikershandleiding
menutrans &How-to\ links &Hoe-doe-ik\ lijst
"menutrans &GUI &GUI
menutrans &Credits &Met\ dank\ aan
-menutrans Co&pying &Copyright
-menutrans &Sponsor/Register &Sponsor/Registreer
+menutrans Co&pying Auteursrechten
+menutrans &Sponsor/Register Sponsoren/inschrijven
menutrans O&rphans &Weeskinderen
menutrans &Version &Versie
menutrans &About &Introductiescherm
@@ -69,8 +69,8 @@ menutrans &Keymap Toetsenbordindeling
" Edit.Global Settings
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Flip\ Patroonkleuring<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Flip\ Negeren\ hoofd/kleine\ letters<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Flip\ Showmatch<Tab>:set\ sm!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Flip\ Negeren\ hoofd/kleine\ letters<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Flip\ Showmatch<Tab>:set\ sm!
menutrans &Context\ lines Contextregels
menutrans &Virtual\ Edit Virtueel\ positioneren
menutrans Never Nooit
@@ -79,7 +79,7 @@ menutrans Insert\ mode In\ Invoegmode
menutrans Block\ and\ Insert Bij\ Blokselectie\ en\ Invoegmode
menutrans Always Altijd
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Flip\ Invoegmode<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Flip\ Vi\ Compatibiliteit<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Flip\ Vi\ Compatibiliteit<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Zoekpad\.\.\.
menutrans Ta&g\ Files\.\.\. Tag\ Bestanden\.\.\.
menutrans Toggle\ &Toolbar Toon/verberg\ Knoppenbalk
@@ -117,7 +117,7 @@ menutrans &Open<Tab>:copen &Openen<Tab>:copen
menutrans &Close<Tab>:cclose &Sluiten<Tab>:cclose
menutrans &Convert\ to\ HEX<Tab>:%!xxd Converteer\ naar\ HEX<Tab>:%!xxd
menutrans Conve&rt\ back<Tab>:%!xxd\ -r Converteer\ terug<Tab>:%!xxd\ -r
-menutrans &Set\ Compiler Kies\ Compiler
+menutrans Se&T\ Compiler Kies\ Compiler
" Tools.Folding
menutrans &Enable/Disable\ folds<Tab>zi Flip\ tonen\ folds<Tab>zi
@@ -131,13 +131,13 @@ menutrans Fold\ Met&hod Foldwijze
menutrans M&anual Handmatig
menutrans I&ndent Inspringing
menutrans E&xpression Expressie
-menutrans S&yntax Syntax
+menutrans S&yntax Syntaxis
menutrans &Diff Verschillen
menutrans Ma&rker Markeringen
menutrans Create\ &Fold<Tab>zf maak\ Fold<Tab>zf
menutrans &Delete\ Fold<Tab>zd verwijder\ Fold<Tab>zd
menutrans Delete\ &All\ Folds<Tab>zD verwijder\ alle\ Folds<Tab>zD
-menutrans Fold\ column\ &width Fold\ kolom\ breedte
+menutrans Fold\ col&umn\ width Fold\ kolom\ breedte
" Tools.Diff
menutrans &Update Verversen
@@ -221,7 +221,7 @@ if has("toolbar")
endif
" Syntax menu
-menutrans &Syntax &Syntax
+menutrans &Syntax &Syntaxis
menutrans &Show\ filetypes\ in\ menu Toon\ filetypes\ in\ menu
menutrans Set\ '&syntax'\ only Alleen\ 'syntax'\ wijzigen
menutrans Set\ '&filetype'\ too Ook\ 'filetype'\ wijzigen
@@ -241,6 +241,34 @@ let g:menutrans_path_dialog = "Typ het zoekpad voor bestanden.\nGebruik commas t
let g:menutrans_tags_dialog = "Typ namen van tag bestanden.\nGebruik commas tussen de namen."
let g:menutrans_textwidth_dialog = "Typ de nieuwe tekst breedte (0 om formatteren uit the schakelen): "
let g:menutrans_fileformat_dialog = "Selecteer formaat voor het schrijven van het bestand"
+menutrans Open\ &Tab\.\.\.<Tab>:tabnew Tabblad\ openen\.\.\.<Tab>:tabnew
+menutrans Startup\ &Settings Opstartinstellingen
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! Schakel\ Relatieve\ lijnnummering\ in\ of\ uit<Tab>:set\ nru!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! Schakel\ Regelterugloop\ in\ of\ uit<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! Schakel\ terugloop\ bij\ Word\ in\ of\ uit<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! Schakel\ het\ uitbreiden\ van\ tabbladen\ in\ of\ uit<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! Schakel\ Automatisch\ inspringen\ in<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Schakel\ Inspringen\ in\ C-stijl\ in\ of\ uit<Tab>:set\ cin!
+menutrans &Shiftwidth Verschuivingsbreedte
+menutrans Soft\ &Tabstop Zachte\ tabstop
+menutrans &Spelling Spelling
+menutrans &Spell\ Check\ On Spellingcontrole\ ingeschakeld
+menutrans Spell\ Check\ &Off Spellingcontrole\ uitgeschakeld
+menutrans To\ &Next\ error<Tab>]s Naar\ volgende\ fout<Tab>]s
+menutrans To\ &Previous\ error<Tab>[s Naar\ vorige\ fout<Tab>[s
+menutrans Suggest\ &Corrections<Tab>z= Correcties\ voorstellen<Tab>z=
+menutrans &Repeat\ correction<Tab>:spellrepall Herhaal\ correctie<Tab>:spellrepall
+"-------------------
+menutrans Set\ language\ to\ "en" Taal\ instellen\ op\ "en"
+menutrans Set\ language\ to\ "en_au" Taal\ instellen\ op\ "en_au"
+menutrans Set\ language\ to\ "en_ca" Taal\ instellen\ op\ "en_ca"
+menutrans Set\ language\ to\ "en_gb" Taal\ instellen\ op\ "en_gb"
+menutrans Set\ language\ to\ "en_nz" Taal\ instellen\ op\ "en_nz"
+menutrans Set\ language\ to\ "en_us" Taal\ instellen\ op\ "en_us"
+menutrans &Find\ More\ Languages Vind\ meer\ talen
+let g:menutrans_set_lang_to = 'Taal instellen op'
+menutrans &Folding Vouwen
+menutrans &Show\ File\ Types\ in\ menu Bestandstypen\ weergeven\ in\ het\ menu
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_pt_br.vim b/runtime/lang/menu_pt_br.vim
index 0c6ff93..06dea92 100644
--- a/runtime/lang/menu_pt_br.vim
+++ b/runtime/lang/menu_pt_br.vim
@@ -1,290 +1 @@
-" Menu Translations: Portugus do Brasil
-" Maintainer: Jos de Paula <jose@infoviaweb.com>
-" Last Change: 2020 Apr 23
-" Original translations
-
-" Quit when menu translations have already been done.
-if exists("did_menu_trans")
- finish
-endif
-let did_menu_trans = 1
-let s:keepcpo= &cpo
-set cpo&vim
-
-" Translations in latin1 (ISO-8859-1), and should work in
-" latin9 (ISO-8859-15)
-
-if &enc != "cp1252" && &enc != "iso-8859-15"
- scriptencoding latin1
-endif
-
-" Help menu
-menutrans &Help A&juda
-menutrans &Overview<Tab><F1> &Contedo
-menutrans &User\ Manual &Manual\ do\ Usurio
-menutrans &How-to\ links &Como\ fazer?
-menutrans &Find\.\.\. &Procurar\.\.\.
-menutrans &Credits &Crditos
-menutrans O&rphans &rfos
-menutrans Co&pying &Licena
-menutrans &Sponsor/Register &Doar/Registrar
-menutrans &Version &Verso
-menutrans &About &Sobre
-
-" File menu
-menutrans &File &Arquivo
-menutrans &Open\.\.\.<Tab>:e A&brir\.\.\.<Tab>:e
-menutrans Sp&lit-Open\.\.\.<Tab>:sp Ab&rir\ em\ outra\ janela\.\.\.<Tab>:sp
-menutrans &New<Tab>:enew &Novo<Tab>:enew
-menutrans &Close<Tab>:close &Fechar<Tab>:close
-menutrans &Save<Tab>:w &Salvar<Tab>:w
-menutrans Save\ &As\.\.\.<Tab>:sav Sa&lvar\ como\.\.\.<Tab>:sav
-menutrans Split\ &Diff\ with\.\.\. &Exibir\ diferenas\ com\.\.\.
-menutrans Split\ Patched\ &By\.\.\. Ex&ibir\ patcheado\ por\.\.\.
-menutrans &Print I&mprimir
-menutrans Sa&ve-Exit<Tab>:wqa Sal&var\ e\ sair<Tab>:wqa
-menutrans E&xit<Tab>:qa Sai&r<Tab>:qa
-
-" Edit menu
-menutrans &Edit &Editar
-menutrans &Undo<Tab>u &Desfazer<Tab>u
-menutrans &Redo<Tab>^R &Refazer<Tab>u
-menutrans Rep&eat<Tab>\. Repe&tir<Tab>\.
-menutrans Cu&t<Tab>"+x Re&cortar<Tab>"+x
-menutrans &Copy<Tab>"+y Cop&iar<Tab>"+y
-menutrans &Paste<Tab>"+gP C&olar<Tab>"+gP
-menutrans Put\ &Before<Tab>[p Colocar\ &antes<Tab>[p
-menutrans Put\ &After<Tab>]p Colocar\ &depois<Tab>]p
-menutrans &Select\ all<Tab>ggVG &Selecionar\ tudo<Tab>ggVG
-menutrans &Find\.\.\. &Procurar\.\.\.
-menutrans Find\ and\ Rep&lace\.\.\. Procurar\ e\ substit&uir\.\.\.
-menutrans Find\ and\ Rep&lace<Tab>:%s Procurar\ e\ substit&uir<Tab>:%s
-menutrans Find\ and\ Rep&lace Procurar\ e\ substit&uir
-menutrans Find\ and\ Rep&lace<Tab>:s Procurar\ e\ substituir<Tab>:s
-menutrans Settings\ &Window &Opes
-menutrans Startup\ &Settings &Inicializao
-
-" Edit/Global Settings
-menutrans &Global\ Settings Opes\ &Globais
-
-menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Ativar/Desativar\ &Realce\ de\ Padres<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Ativar/Desativar\ &Ignorar\ maisculas<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Ativar/Desativar\ &coincidncias<Tab>:set\ sm!
-
-menutrans &Context\ lines Linhas\ de\ C&ontexto
-
-menutrans &Virtual\ Edit Edio\ &Virtual
-menutrans Never Nunca
-menutrans Block\ Selection Seleo\ de\ Bloco
-menutrans Insert\ mode Modo\ de\ insero
-menutrans Block\ and\ Insert Bloco\ e\ insero
-menutrans Always Sempre
-
-menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Ativar/Desativar\ Modo\ de\ In&sero<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Ativar/Desativar\ Co&mpatibilidade\ com\ Vi<Tab>:set\ cp!
-menutrans Search\ &Path\.\.\. Camin&ho\ de\ Busca\.\.\.
-menutrans Ta&g\ Files\.\.\. Arquivos\ de\ Tags\.\.\.
-
-" GUI options
-menutrans Toggle\ &Toolbar Ocultar/Exibir\ Barra\ de\ &Ferramentas
-menutrans Toggle\ &Bottom\ Scrollbar Ocultar/Exibir\ Barra\ de\ &Rolagem\ Inferior
-menutrans Toggle\ &Left\ Scrollbar Ocultar/Exibir\ Barra\ de\ R&olagem\ Esquerda
-menutrans Toggle\ &Right\ Scrollbar Ocultar/Exibir\ Barra\ de\ Ro&lagem\ Direita
-let g:menutrans_path_dialog = "Indique um caminho de procura para os arquivos.\nSepare os nomes dos diretrios com uma vrgula."
-let g:menutrans_tags_dialog = "Indique os nomes dos arquivos de tags.\nSepare os nomes com uma vrgula."
-
-" Edit/File Settings
-menutrans F&ile\ Settings Opes\ do\ &Arquivo
-
-" Boolean options
-menutrans Toggle\ Line\ &Numbering<Tab>:set\ nu! Ativar/Desativar\ &numerao\ de\ linhas<Tab>:set\ nu!
-menutrans Toggle\ &List\ Mode<Tab>:set\ list! Ativar/Desativar\ modo\ &list<Tab>:set\ list!
-menutrans Toggle\ Line\ &Wrap<Tab>:set\ wrap! Ativar/Desativar\ &quebra\ de\ linhas<Tab>:set\ wrap!
-menutrans Toggle\ W&rap\ at\ word<Tab>:set\ lbr! Ativar/Desativar\ quebra\ na\ &palavra<Tab>:set\ lbr!
-menutrans Toggle\ &expand-tab<Tab>:set\ et! Ativar/Desativar\ expanso\ de\ tabs<Tab>:set\ et!
-menutrans Toggle\ &auto-indent<Tab>:set\ ai! Ativar/Desativar\ &auto-indentao<Tab>:set\ ai!
-menutrans Toggle\ &C-indenting<Tab>:set\ cin! Ativar/Desativar\ indentao\ estilo\ &C<Tab>:set\ cin!
-
-" other options
-menutrans &Shiftwidth Largura\ da\ &indentao
-
-menutrans Soft\ &Tabstop &Tabulao\ com\ espaos
-
-menutrans Te&xt\ Width\.\.\. Largura\ do\ te&xto\.\.\.
-let g:menutrans_textwidth_dialog = "Digite a nova largura do texto (0 para desativar a formatao): "
-
-menutrans &File\ Format\.\.\. &Formato\ do\ arquivo\.\.\.
-let g:menutrans_fileformat_dialog = "Selecione o formato para gravar o arquivo"
-
-menutrans C&olor\ Scheme Esquema\ de\ c&ores
-menutrans default padro
-
-menutrans Select\ Fo&nt\.\.\. Selecionar\ fo&nte\.\.\.
-
-menutrans &Keymap &Mapa\ de\ teclado
-menutrans None Nenhum
-
-" Programming menu
-menutrans &Tools &Ferramentas
-menutrans &Jump\ to\ this\ tag<Tab>g^] &Pular\ para\ este\ tag<Tab>g^]
-menutrans Jump\ &back<Tab>^T &Voltar<Tab>^T
-menutrans Build\ &Tags\ File &Construir\ Arquivo\ de\ tags
-menutrans &Spelling &Ortografia
-menutrans &Folding &Dobra
-menutrans &Make<Tab>:make &Make<Tab>:make
-menutrans &List\ Errors<Tab>:cl &Lista\ de\ erros<Tab>:cl
-menutrans L&ist\ Messages<Tab>:cl! Li&sta\ de\ mensagens<Tab>:cl!
-menutrans &Next\ Error<Tab>:cn P&rximo\ erro<Tab>:cn
-menutrans &Previous\ Error<Tab>:cp &Erro\ anterior<Tab>:cp
-menutrans &Older\ List<Tab>:cold Listar\ erros\ &antigos<Tab>:cold
-menutrans N&ewer\ List<Tab>:cnew Listar\ erros\ &novos<Tab>:cnew
-menutrans Error\ &Window &Janela\ de\ erros
-menutrans Se&T\ Compiler Def&inir\ Compilador
-menutrans &Convert\ to\ HEX<Tab>:%!xxd Converter\ para\ hexadecimal<Tab>:%!xxd
-menutrans Conve&rt\ back<Tab>:%!xxd\ -r Conver&ter\ de\ volta<Tab>:%!xxd\ -r
-
-" Tools.Spelling menu
-menutrans &Spell\ Check\ On &Ativar\ Correo\ Ortogrfica
-menutrans &Spell\ Check\ Off &Desativar\ Correo\ Ortogrfica
-menutrans To\ &Next\ error<Tab>]s &Prximo\ Erro<Tab>]s
-menutrans To\ &Previous\ Error<Tab>[s Erro\ A&nterior<Tab>[s
-menutrans Suggest\ &Corrections<Tab>z= &Sugerir\ Correes<Tab>z=
-menutrans &Repeat\ correction<Tab>:spellrepall &Repetir\ Correo<Tab>:spellrepall
-
-menutrans Set\ language\ to\ "en" Ingls
-menutrans Set\ language\ to\ "en_au" Ingls\ (en_au)
-menutrans Set\ language\ to\ "en_ca" Ingls\ (en_ca)
-menutrans Set\ language\ to\ "en_gb" Ingls\ (en_gb)
-menutrans Set\ language\ to\ "en_nz" Ingls\ (en_nz)
-menutrans Set\ language\ to\ "en_us" Ingls\ (en_us)
-
-menutrans &Find\ More\ Languages &Buscar\ mais\ idiomas
-
-" Tools.Fold Menu
-menutrans &Enable/Disable\ folds<Tab>zi &Ativar/Desativar\ dobras<Tab>zi
-menutrans &View\ Cursor\ Line<Tab>zv &Ver\ linha\ do\ cursor<Tab>zv
-menutrans Vie&w\ Cursor\ Line\ only<Tab>zMzx Ve&r\ somente\ linha\ do\ cursor<Tab>zMzx
-menutrans C&lose\ more\ folds<Tab>zm &Fechar\ mais\ dobras<Tab>zm
-menutrans &Close\ all\ folds<Tab>zM F&echar\ todas\ as\ dobras<Tab>zM
-menutrans O&pen\ more\ folds<Tab>zr A&brir\ mais\ dobras<Tab>zr
-menutrans &Open\ all\ folds<Tab>zR Abr&ir\ todas\ as\ dobras<Tab>zR
-" fold method
-menutrans Fold\ Met&hod &Modo\ de\ dobras
-menutrans Create\ &Fold<Tab>zf Criar\ &dobras<Tab>zf
-menutrans &Delete\ Fold<Tab>zd Remover\ d&obras<Tab>zd
-menutrans Delete\ &All\ Folds<Tab>zD Remover\ &todas\ as\ dobras<Tab>zD
-" moving around in folds
-menutrans Fold\ col&umn\ width &Largura\ da\ coluna\ da\ dobra
-
-" Tools.Diff Menu
-menutrans &Update &Atualizar
-menutrans &Get\ Block &Obter\ Bloco
-menutrans &Put\ Block &Pr\ Bloco
-
-" Tools.Error Menu
-menutrans &Update<Tab>:cwin &Atualizar<Tab>:cwin
-menutrans &Open<Tab>:copen A&brir<Tab>:copen
-menutrans &Close<Tab>:cclose &Fechar<Tab>:cclose
-
-" Names for buffer menu.
-menutrans &Buffers &Buffers
-menutrans &Refresh\ menu A&tualizar\ menu
-menutrans &Delete &Apagar
-menutrans &Alternate A&lternar
-menutrans &Next P&rximo
-menutrans &Previous A&nterior
-let g:menutrans_no_file = "[Sem arquivos]"
-
-" Window menu
-menutrans &Window &Janela
-menutrans &New<Tab>^Wn N&ova<Tab>^Wn
-menutrans S&plit<Tab>^Ws &Dividir<Tab>^Ws
-menutrans Sp&lit\ To\ #<Tab>^W^^ D&ividir\ para\ #<Tab>^W^^
-menutrans Split\ &Vertically<Tab>^Wv Dividir\ &verticalmente<Tab>^Wv
-menutrans Split\ File\ E&xplorer &Abrir\ Gerenciador\ de\ arquivos
-menutrans &Close<Tab>^Wc &Fechar<Tab>^Wc
-menutrans Close\ &Other(s)<Tab>^Wo Fechar\ &outra(s)<Tab>^Wo
-menutrans Move\ &To Mover\ &para
-menutrans &Top<Tab>^WK A&cima<Tab>^WK
-menutrans &Bottom<Tab>^WJ A&baixo<Tab>^WJ
-menutrans &Left\ side<Tab>^WH Lado\ &esquerdo<Tab>^WH
-menutrans &Right\ side<Tab>^WL Lado\ di&reito<Tab>^WL
-menutrans Rotate\ &Up<Tab>^WR &Girar\ para\ cima<Tab>^WR
-menutrans Rotate\ &Down<Tab>^Wr Girar\ para\ bai&xo<Tab>^Wr
-menutrans &Equal\ Size<Tab>^W= Mesmo\ &Tamanho<Tab>^W=
-menutrans &Max\ Height<Tab>^W_ Altura\ &Mxima<Tab>^W_
-menutrans M&in\ Height<Tab>^W1_ A&ltura\ Mnima<Tab>^W1_
-menutrans Max\ &Width<Tab>^W\| Larg&ura\ Mxima<Tab>^W\|
-menutrans Min\ Widt&h<Tab>^W1\| Largura\ M&nima<Tab>^W1\|
-
-" The popup menu
-menutrans &Undo &Desfazer
-menutrans Cu&t Recor&tar
-menutrans &Copy &Copiar
-menutrans &Paste Co&lar
-menutrans &Delete &Apagar
-menutrans Select\ Blockwise Seleo\ de\ bloco
-menutrans Select\ &Word Selecionar\ &Palavra
-menutrans Select\ &Line Selecionar\ L&inha
-menutrans Select\ &All Selecionar\ T&udo
-
-" The GUI toolbar
-if has("toolbar")
- if exists("*Do_toolbar_tmenu")
- delfun Do_toolbar_tmenu
- endif
- fun Do_toolbar_tmenu()
- tmenu ToolBar.Open Abrir Arquivo
- tmenu ToolBar.Save Salvar Arquivo
- tmenu ToolBar.SaveAll Salvar Todos os arquivos
- tmenu ToolBar.Print Imprimir
- tmenu ToolBar.Undo Desfazer
- tmenu ToolBar.Redo Refazer
- tmenu ToolBar.Cut Recortar
- tmenu ToolBar.Copy Copiar
- tmenu ToolBar.Paste Colar
- tmenu ToolBar.Find Procurar...
- tmenu ToolBar.FindNext Procurar Prximo
- tmenu ToolBar.FindPrev Procurar Anterior
- tmenu ToolBar.Replace Procurar e Substituir
- if 0 " disable; these are in the Windoze menu
- tmenu ToolBar.New Nova Janela
- tmenu ToolBar.WinSplit Dividir Janela
- tmenu ToolBar.WinMax Janela Mxima
- tmenu ToolBar.WinMin Janela Mnima
- tmenu ToolBar.WinVSplit Dividir Verticalmente
- tmenu ToolBar.WinMaxWidth Largura Mxima
- tmenu ToolBar.WinMinWidth Largura Mnima
- tmenu ToolBar.WinClose Fechar Janela
- endif
- tmenu ToolBar.LoadSesn Carregar Sesso
- tmenu ToolBar.SaveSesn Salvar Sesso
- tmenu ToolBar.RunScript Executar script
- tmenu ToolBar.Make Make
- tmenu ToolBar.Shell Abrir um shell
- tmenu ToolBar.RunCtags Gerar um arquivo de tags
- tmenu ToolBar.TagJump Saltar para um tag
- tmenu ToolBar.Help Ajuda
- tmenu ToolBar.FindHelp Procurar na Ajuda
- endfun
-endif
-
-" Syntax menu
-menutrans &Syntax &Sintaxe
-"menutrans &Show\ individual\ choices E&xibir\ escolhas\ individuais
-menutrans &Show\ filetypes\ in\ menu E&xibir\ tipos\ de\ arquivos\ no\ menu
-menutrans Set\ '&syntax'\ only Ativar\ somente\ s&intaxe
-menutrans Set\ '&filetype'\ too Ativar\ tambm\ &tipo\ de\ arquivo
-menutrans &Off &Desativar
-menutrans &Manual &Manual
-menutrans A&utomatic A&utomtica
-menutrans on/off\ for\ &This\ file Ativar/Desativar\ neste\ &arquivo
-menutrans Co&lor\ test T&este\ de\ cores
-menutrans &Highlight\ test Teste\ de\ &realce
-menutrans &Convert\ to\ HTML &Converter\ para\ HTML
-
-" Find Help dialog text
-let g:menutrans_help_dialog = "Digite um comando ou palavra para obter ajuda;\n\nAnteponha i_ para comandos de entrada (ex.: i_CTRL-X)\nAnteponha c_ para comandos da linha de comandos (ex.: c_<Del>)\nAnteponha ` para um nome de opo (ex.: `shiftwidth`)"
-
-let &cpo = s:keepcpo
-unlet s:keepcpo
+source <sfile>:p:h/menu_pt_pt.vim
diff --git a/runtime/lang/menu_pt_pt.vim b/runtime/lang/menu_pt_pt.vim
index 423d918..ddc35b8 100644
--- a/runtime/lang/menu_pt_pt.vim
+++ b/runtime/lang/menu_pt_pt.vim
@@ -1,6 +1,7 @@
" Menu Translations: Portugus
" adaptado de pt_br.
" Maintainer: Duarte Henriques <duarte_henriques@myrealbox.com>
+" Last Change: 2024 May 2
" Original translations
" Quit when menu translations have already been done.
@@ -66,8 +67,8 @@ menutrans Settings\ &Window Op&es
menutrans &Global\ Settings Opes\ &Globais
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Activar/Desactivar\ &Realce\ de\ Padres<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Activar/Desactivar\ &Ignorar\ maisculas<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Activar/Desactivar\ &coincidncias<Tab>:set\ sm!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Activar/Desactivar\ &Ignorar\ maisculas<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Activar/Desactivar\ &coincidncias<Tab>:set\ sm!
menutrans &Context\ lines Linhas\ de\ C&ontexto
@@ -79,7 +80,7 @@ menutrans Block\ and\ Insert Bloco\ e\ insero
menutrans Always Sempre
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Activar/Desactivar\ Modo\ de\ In&sero<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Activar/Desactivar\ Co&mpatibilidade\ com\ Vi<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Activar/Desactivar\ Co&mpatibilidade\ com\ Vi<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Camin&ho\ de\ Busca\.\.\.
menutrans Ta&g\ Files\.\.\. Arquivos\ de\ Tags\.\.\.
@@ -128,7 +129,7 @@ menutrans &Jump\ to\ this\ tag<Tab>g^] Saltar\ para\ esta\ &tag<Tab>g^]
menutrans Jump\ &back<Tab>^T &Voltar<Tab>^T
menutrans Build\ &Tags\ File &Construir\ Arquivo\ de\ tags
menutrans &Folding &Dobra
-menutrans &Make<Tab>:make &Make<Tab>:make
+menutrans &Make<Tab>:make Fazer<Tab>:make
menutrans &List\ Errors<Tab>:cl &Lista\ de\ erros<Tab>:cl
menutrans L&ist\ Messages<Tab>:cl! Li&sta\ de\ mensagens<Tab>:cl!
menutrans &Next\ Error<Tab>:cn P&rximo\ erro<Tab>:cn
@@ -136,7 +137,7 @@ menutrans &Previous\ Error<Tab>:cp &Erro\ anterior<Tab>:cp
menutrans &Older\ List<Tab>:cold Listar\ erros\ &antigos<Tab>:cold
menutrans N&ewer\ List<Tab>:cnew Listar\ erros\ &novos<Tab>:cnew
menutrans Error\ &Window &Janela\ de\ erros
-menutrans &Set\ Compiler Def&inir\ Compilador
+menutrans Se&T\ Compiler Def&inir\ Compilador
menutrans &Convert\ to\ HEX<Tab>:%!xxd Converter\ para\ hexadecimal<Tab>:%!xxd
menutrans Conve&rt\ back<Tab>:%!xxd\ -r Conver&ter\ de\ volta<Tab>:%!xxd\ -r
@@ -265,6 +266,38 @@ menutrans &Convert\ to\ HTML &Converter\ para\ HTML
" Find Help dialog text
let g:menutrans_help_dialog = "Digite um comando ou palavra para obter ajuda;\n\nAnteponha i_ para comandos de entrada (ex.: i_CTRL-X)\nAnteponha c_ para comandos da linha de comandos (ex.: c_<Del>)\nAnteponha ` para um nome de opo (ex.: `shiftwidth`)"
+menutrans Open\ &Tab\.\.\.<Tab>:tabnew Aba\ aberta\.\.\.<Tab>:tabnew
+menutrans Startup\ &Settings Configuraes\ de\ inicializao
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! Numerao\ relativa\ de\ linha<Tab>:set\ nru!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! Quebra\ de\ linha<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! Envolvendo\ a\ palavra<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! Gastos\ de\ tabulao<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! Recuo\ automtico<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Recuo\ estilo\ C<Tab>:set\ cin!
+menutrans &Spelling Ortografia
+menutrans &Spell\ Check\ On Correo\ ortogrfica\ ativada
+menutrans Spell\ Check\ &Off Correo\ ortogrfica\ desativada
+menutrans To\ &Next\ error<Tab>]s Prximo\ erro<Tab>]s
+menutrans To\ &Previous\ error<Tab>[s erro\ anterior<Tab>[s
+menutrans Suggest\ &Corrections<Tab>z= Sugerir\ correes<Tab>z=
+menutrans &Repeat\ correction<Tab>:spellrepall repetir\ correo<Tab>:spellrepall
+"-------------------
+menutrans Set\ language\ to\ "en" Definir\ idioma\ para\ "en"
+menutrans Set\ language\ to\ "en_au" Definir\ idioma\ para\ "en_au"
+menutrans Set\ language\ to\ "en_ca" Definir\ idioma\ para\ "en_ca"
+menutrans Set\ language\ to\ "en_gb" Definir\ idioma\ para\ "en_gb"
+menutrans Set\ language\ to\ "en_nz" Definir\ idioma\ para\ "en_nz"
+menutrans Set\ language\ to\ "en_us" Definir\ idioma\ para\ "en_us"
+menutrans &Find\ More\ Languages Encontre\ mais\ idiomas
+let g:menutrans_set_lang_to = 'Definir idioma para'
+menutrans M&anual Manual
+menutrans I&ndent Recuar
+menutrans E&xpression Expresso
+menutrans S&yntax Sintaxe
+menutrans &Diff Diferena
+menutrans Ma&rker Marcador
+menutrans &Show\ File\ Types\ in\ menu Mostrar\ tipos\ de\ arquivo\ no\ menu
+menutrans &Sponsor/Register Patrocinador/Registro
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_sl_si.utf-8.vim b/runtime/lang/menu_sl_si.utf-8.vim
index 10e2541..c866f14 100644
--- a/runtime/lang/menu_sl_si.utf-8.vim
+++ b/runtime/lang/menu_sl_si.utf-8.vim
@@ -1,7 +1,7 @@
" Menu Translations: Slovenian / Slovensko
" Maintainer: Mojca Miklavec <mojca.miklavec.lists@gmail.com>
" Originally By: Mojca Miklavec <mojca.miklavec.lists@gmail.com>
-" Last Change: 2020 Apr 23
+" Last Change: 2024 May 2
" vim:set foldmethod=marker tabstop=8:
" Original translations
@@ -57,8 +57,8 @@ menutrans Startup\ &Settings Začetne\ nastavitve
menutrans &Global\ Settings &Globalne\ nastavitve
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Vključi/izključi\ poudarjanje\ iskanega\ niza<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Vključi/izključi\ ločevanje\ velikih\ in\ malih\ črk<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Vključi/izključi\ kratek\ skok\ na\ pripadajoči\ oklepaj<Tab>:set\ sm!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Vključi/izključi\ ločevanje\ velikih\ in\ malih\ črk<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Vključi/izključi\ kratek\ skok\ na\ pripadajoči\ oklepaj<Tab>:set\ sm!
menutrans &Context\ lines Št\.\ vidnih\ vrstic\ pred/za\ kurzorjem
@@ -69,7 +69,7 @@ menutrans Insert\ mode Le\ v\ načinu\ za\ pisanje
menutrans Block\ and\ Insert Pri\ obojem
menutrans Always Vedno
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Vključi/izključi\ način\ za\ pisanje<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Vključi/izključi\ združljivost\ z\ Vi-jem<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Vključi/izključi\ združljivost\ z\ Vi-jem<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Pot\ za\ iskanje\ \.\.\.
menutrans Ta&g\ Files\.\.\. Ta&g-datoteke\.\.\.
@@ -149,7 +149,7 @@ if has("folding")
menutrans &Delete\ Fold<Tab>zd Izbriši\ zavihek<Tab>zd
menutrans Delete\ &All\ Folds<Tab>zD Izbriši\ vse\ zavihke<Tab>zD
" moving around in folds
- menutrans Fold\ column\ &width Širina\ stolpca\ z\ zavihkom
+ menutrans Fold\ col&umn\ width Širina\ stolpca\ z\ zavihkom
endif " has folding
if has("diff")
@@ -295,6 +295,13 @@ let g:menutrans_textwidth_dialog = "Vnesite novo širino besedila (ali 0 za izkl
let g:menutrans_fileformat_dialog = "Izberite format datoteke"
let g:menutrans_fileformat_choices = "&Unix\n&Dos\n&Mac\n&Prekliči"
" }}}
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! relativno\ številčenje\ vrstic<Tab>:set\ nru!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! ovijanje\ vrstic<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! zavijanje\ v\ besedo<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! razpredelnica\ se\ širi<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! Samodejno\ zamikanje<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Zamik\ v\ slogu\ C<Tab>:set\ cin!
+menutrans &Show\ File\ Types\ in\ menu Prikaži\ vrste\ datotek\ v\ meniju
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_slovak_slovak_republic.1250.vim b/runtime/lang/menu_slovak_slovak_republic.1250.vim
index 965cc91..d367ea8 100644
--- a/runtime/lang/menu_slovak_slovak_republic.1250.vim
+++ b/runtime/lang/menu_slovak_slovak_republic.1250.vim
@@ -1,6 +1,6 @@
" Menu Translations: Slovak
" Translated By: Martin Lacko <lacko@host.sk>
-" Last Change: 2020 Apr 23
+" Last Change: 2024 May 2
" Original translations
" Quit when menu translations have already been done.
@@ -56,8 +56,8 @@ menutrans Find\ and\ Rep&lace\.\.\. N&ahradi\.\.\.
menutrans Settings\ &Window Mo&nosti
menutrans &Global\ Settings &Globlne\ monosti
menutrans Toggle\ Pattern\ &Highlight<Tab>:set\ hls! Prepn\ paletu\ zvrazovania<Tab>:set\ hls!
-menutrans Toggle\ &Ignore-case<Tab>:set\ ic! Prepn\ &ignorovanie\ vekosti<Tab>:set\ ic!
-menutrans Toggle\ &Showmatch<Tab>:set\ sm! Prepn\ &ukza\ zhodu<Tab>:set\ sm!
+menutrans Toggle\ &Ignoring\ Case<Tab>:set\ ic! Prepn\ &ignorovanie\ vekosti<Tab>:set\ ic!
+menutrans Toggle\ &Showing\ Matched\ Pairs<Tab>:set\ sm! Prepn\ &ukza\ zhodu<Tab>:set\ sm!
menutrans &Context\ lines &Kontextov\ riadky
menutrans &Virtual\ Edit &Virtulne\ pravy
menutrans Never Nikdy
@@ -66,7 +66,7 @@ menutrans Insert\ mode Reim\ vkladania
menutrans Block\ and\ Insert Blok\ a\ vkladanie
menutrans Always Vdy
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Prepn\ rei&m\ vkladania<Tab>:set\ im!
-menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Prepn\ vi\ kompatibilitu<Tab>:set\ cp!
+menutrans Toggle\ Vi\ C&ompatibility<Tab>:set\ cp! Prepn\ vi\ kompatibilitu<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Cesta\ &hadania\.\.\.
menutrans Ta&g\ Files\.\.\. Ta&gov\ sbory\.\.\.
menutrans Toggle\ &Toolbar Prepn\ &panel
@@ -121,7 +121,7 @@ menutrans &Open<Tab>:copen &Otvori<Tab>:copen
menutrans &Close<Tab>:cclose &Zatvori<Tab>:cclose
menutrans &Convert\ to\ HEX<Tab>:%!xxd &Konvertova\ do\ HEX<Tab>:%!xxd
menutrans Conve&rt\ back<Tab>:%!xxd\ -r Konve&rtova\ sp<Tab>:%!xxd\ -r
-menutrans &Make<Tab>:make &Make<Tab>:make
+menutrans &Make<Tab>:make urobi<Tab>:make
menutrans &List\ Errors<Tab>:cl Vpis\ &chb<Tab>:cl
menutrans L&ist\ Messages<Tab>:cl! Vp&is\ sprv<Tab>:cl!
menutrans &Next\ Error<Tab>:cn a&lia\ chyba<Tab>:cn
@@ -129,7 +129,7 @@ menutrans &Previous\ Error<Tab>:cp &Predchdzajca\ chyba<Tab>:cp
menutrans &Older\ List<Tab>:cold Sta&r\ zoznam<Tab>:cold
menutrans N&ewer\ List<Tab>:cnew Nov\ &zoznam<Tab>:cnew
menutrans Error\ &Window<Tab>:cwin Chybov\ o&kno<Tab>:cwin
-menutrans &Set\ Compiler Vyberte\ k&ompiltor
+menutrans Se&T\ Compiler Vyberte\ k&ompiltor
menutrans Convert\ to\ HEX<Tab>:%!xxd Prvies\ do\ es&tnstkovho\ formtu<Tab>:%!xxd
menutrans Convert\ back<Tab>:%!xxd\ -r Pr&evies\ sp<Tab>:%!xxd\ -r
@@ -233,6 +233,33 @@ menutrans on/off\ for\ &This\ file Zapn/vypn\ pre\ &tento\ sbor
menutrans Co&lor\ test Test\ &farieb
menutrans &Highlight\ test &Test\ zvrazovania
menutrans &Convert\ to\ HTML &Previes\ do\ HTML
+menutrans Open\ &Tab\.\.\.<Tab>:tabnew otvori\ kartu\.\.\.<Tab>:tabnew
+menutrans Startup\ &Settings nastavenia\ spustenia
+menutrans Toggle\ relati&ve\ Line\ Numbering<Tab>:set\ rnu! relatvne\ slovanie\ riadkov<Tab>:set\ nru!
+menutrans Toggle\ Line\ &Wrapping<Tab>:set\ wrap! zalomenie\ iary<Tab>:set\ wrap!
+menutrans Toggle\ W&rapping\ at\ word<Tab>:set\ lbr! zalomenie\ pri\ slove<Tab>:set\ lbr!
+menutrans Toggle\ Tab\ &Expanding<Tab>:set\ et! rozrenie\ tabuky<Tab>:set\ et!
+menutrans Toggle\ &Auto\ Indenting<Tab>:set\ ai! automatick\ odsadenie<Tab>:set\ ai!
+menutrans Toggle\ &C-Style\ Indenting<Tab>:set\ cin! Odsadenie\ v\ tle\ C<Tab>:set\ cin!
+menutrans &Keymap mapa\ klvesov
+menutrans &Spelling Pravopis
+menutrans &Spell\ Check\ On Kontrola\ pravopisu\ na
+menutrans Spell\ Check\ &Off Kontrola\ pravopisu\ vypnut
+menutrans To\ &Next\ error<Tab>]s alia\ chyba<Tab>]s
+menutrans To\ &Previous\ error<Tab>[s predchdzajca\ chyba<Tab>[s
+menutrans Suggest\ &Corrections<Tab>z= navrhn\ opravy<Tab>z=
+menutrans &Repeat\ correction<Tab>:spellrepall opakova\ opravu<Tab>:spellrepall
+"-------------------
+menutrans Set\ language\ to\ "en" nastavi\ jazyk\ na\ "en"
+menutrans Set\ language\ to\ "en_au" nastavi\ jazyk\ na\ "en_au"
+menutrans Set\ language\ to\ "en_ca" nastavi\ jazyk\ na\ "en_ca"
+menutrans Set\ language\ to\ "en_gb" nastavi\ jazyk\ na\ "en_gb"
+menutrans Set\ language\ to\ "en_nz" nastavi\ jazyk\ na\ "en_nz"
+menutrans Set\ language\ to\ "en_us" nastavi\ jazyk\ na\ "en_us"
+menutrans &Find\ More\ Languages njs\ viac\ jazykov
+let g:menutrans_set_lang_to = 'nastavi jazyk na'
+menutrans &Show\ File\ Types\ in\ menu Zobrazi\ typy\ sborov\ v\ ponuke
+menutrans &Sponsor/Register Sponzor/registrcia
let &cpo = s:keepcpo
unlet s:keepcpo
diff --git a/runtime/lang/menu_sr_rs.utf-8.vim b/runtime/lang/menu_sr_rs.utf-8.vim
index c1c0dcb..c96e46a 100644
--- a/runtime/lang/menu_sr_rs.utf-8.vim
+++ b/runtime/lang/menu_sr_rs.utf-8.vim
@@ -1,6 +1,6 @@
" Menu Translations: Serbian
" Maintainer: Aleksandar Jelenak <ajelenak AT yahoo.com>
-" Last Change: Fri, 30 May 2003 10:17:39 Eastern Daylight Time
+" Last Change: 2024 May 2
" Adapted for VIM 8 by: Иван Пешић on 2017-12-28 12:05+0400
" Original translations
@@ -117,8 +117,8 @@ menutrans Create\ &Fold<Tab>zf С&твори\ свијутак<Tab>zf
menutrans &Delete\ Fold<Tab>zd О&бриши\ свијутак<Tab>zd
menutrans Delete\ &All\ Folds<Tab>zD Обриши\ све\ св&ијутке<Tab>zD
menutrans Fold\ column\ &width Ширина\ &реда\ цвијутка
-"menutrans &Diff &Упоређивање
-menutrans &Make<Tab>:make 'mak&е'<Tab>:make
+menutrans &Diff Упоређивање
+menutrans &Make<Tab>:make Направити<Tab>:make
menutrans &List\ Errors<Tab>:cl Списак\ &грешака<Tab>:cl
menutrans L&ist\ Messages<Tab>:cl! Сп&исак\ порука<Tab>:cl!
menutrans &Next\ Error<Tab>:cn С&ледећа\ грешка<Tab>:cn
@@ -254,7 +254,7 @@ if has("toolbar")
tmenu ToolBar.LoadSesn Учитај сеансу
tmenu ToolBar.SaveSesn Сачувај сеансу
tmenu ToolBar.RunScript Изврши спис
- tmenu ToolBar.Make 'make'
+ tmenu ToolBar.Make Направити
tmenu ToolBar.Shell Оперативно окружење
tmenu ToolBar.RunCtags Направи ознаке
tmenu ToolBar.TagJump Иди на ознаку
@@ -294,4 +294,4 @@ let menutrans_no_file = "[Нема фајла]"
let &cpo = s:keepcpo
unlet s:keepcpo
-" vim: tw=0 keymap=serbian
+" vim: tw=0
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index d3e1605..f218ffb 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -1,7 +1,7 @@
" These commands create the option window.
"
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2023 Aug 31
+" Last Change: 2024 Jun 05
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" If there already is an option window, jump to that one.
@@ -846,7 +846,7 @@ if has("insert_expand")
call append("$", "\t" .. s:local_to_buffer)
call <SID>OptionL("cpt")
call <SID>AddOption("completeopt", gettext("whether to use a popup menu for Insert mode completion"))
- call <SID>OptionG("cot", &cot)
+ call <SID>OptionL("cot")
if exists("+completepopup")
call <SID>AddOption("completepopup", gettext("options for the Insert mode completion info popup"))
call <SID>OptionG("cpp", &cpp)
diff --git a/runtime/pack/dist/opt/comment/doc/comment.txt b/runtime/pack/dist/opt/comment/doc/comment.txt
index e2bf755..25bd067 100644
--- a/runtime/pack/dist/opt/comment/doc/comment.txt
+++ b/runtime/pack/dist/opt/comment/doc/comment.txt
@@ -1,4 +1,4 @@
-*comment.txt* For Vim version 9.1. Last change: 2024 Apr 26
+*comment.txt* For Vim version 9.1. Last change: 2024 Jun 04
VIM REFERENCE MANUAL
@@ -7,6 +7,8 @@ Commenting and un-commenting text.
==============================================================================
+See |comment-install| on how to activate this package.
+
The comment.vim package, allows to toggle comments for a single line, a range
of lines or a selected text object. It defines the following mappings:
@@ -21,20 +23,25 @@ gcG to comment/uncomment from current line till the end of a buffer
*v_gc*
{Visual}gc to comment/uncomment the highlighted lines.
-The plugin uses the buffer-local 'commentstring' option value to add or remove
+This plugin uses the buffer-local 'commentstring' option value to add or remove
comment markers to the selected lines. Whether it will comment or un-comment
depends on the first line of the range of lines to act upon. When it matches
a comment marker, the line will be un-commented, if it doesn't, the line will
-be commented out. Blank and empty lines are not touched.
-
-If the mapping does not seem to work, chances are high, that this particular
-filetype is either not detected by Vim or the filetype plugin does not set the
-'commentstring' option.
+be commented out. Blank and empty lines are ignored.
+
+The comment marker will always be padded with blanks whether or not the
+'commentstring' value contains whitespace around "%s".
+
+If the mapping does not seem to work (or uses wrong comment markers), it might
+be because of several reasons:
+- the filetype is not detected by Vim, see |new-filetype|,
+- filetype plugins are not enabled, see |:filetype-plugin-on| or
+- the filetype plugin does not set the (correct) 'commentstring' option.
You can simply configure this using the following autocommand (e.g. for legacy
Vim script): >
- autocmd Filetype vim :setlocal commentstring="\ %s
+ autocmd Filetype vim :setlocal commentstring="%s
This example sets the " as start of a comment for legacy Vim Script. For Vim9
script, you would instead use the "#" char: >
diff --git a/runtime/pack/dist/opt/comment/doc/tags b/runtime/pack/dist/opt/comment/doc/tags
new file mode 100644
index 0000000..ec3569e
--- /dev/null
+++ b/runtime/pack/dist/opt/comment/doc/tags
@@ -0,0 +1,8 @@
+b:comment_first_col comment.txt /*b:comment_first_col*
+comment.txt comment.txt /*comment.txt*
+g:comment_first_col comment.txt /*g:comment_first_col*
+gcG comment.txt /*gcG*
+gcc comment.txt /*gcc*
+gcip comment.txt /*gcip*
+o_gc comment.txt /*o_gc*
+v_gc comment.txt /*v_gc*
diff --git a/runtime/pack/dist/opt/matchit/autoload/matchit.vim b/runtime/pack/dist/opt/matchit/autoload/matchit.vim
index dc2aba6..aa97748 100644
--- a/runtime/pack/dist/opt/matchit/autoload/matchit.vim
+++ b/runtime/pack/dist/opt/matchit/autoload/matchit.vim
@@ -1,6 +1,6 @@
" matchit.vim: (global plugin) Extended "%" matching
" autload script of matchit plugin, see ../plugin/matchit.vim
-" Last Change: Jan 24, 2022
+" Last Change: May 20, 2024
" Neovim does not support scriptversion
if has("vimscript-4")
@@ -87,9 +87,9 @@ function matchit#Match_wrapper(word, forward, mode) range
let s:last_mps = &mps
" quote the special chars in 'matchpairs', replace [,:] with \| and then
" append the builtin pairs (/*, */, #if, #ifdef, #ifndef, #else, #elif,
- " #endif)
+ " #elifdef, #elifndef, #endif)
let default = escape(&mps, '[$^.*~\\/?]') .. (strlen(&mps) ? "," : "") ..
- \ '\/\*:\*\/,#\s*if\%(n\=def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
+ \ '\/\*:\*\/,#\s*if\%(n\=def\)\=:#\s*else\>:#\s*elif\%(n\=def\)\=\>:#\s*endif\>'
" s:all = pattern with all the keywords
let match_words = match_words .. (strlen(match_words) ? "," : "") .. default
let s:last_words = match_words
@@ -101,6 +101,8 @@ function matchit#Match_wrapper(word, forward, mode) range
let s:pat = s:ParseWords(match_words)
endif
let s:all = substitute(s:pat, s:notslash .. '\zs[,:]\+', '\\|', 'g')
+ " un-escape \, to ,
+ let s:all = substitute(s:all, '\\,', ',', 'g')
" Just in case there are too many '\(...)' groups inside the pattern, make
" sure to use \%(...) groups, so that error E872 can be avoided
let s:all = substitute(s:all, '\\(', '\\%(', 'g')
@@ -112,6 +114,8 @@ function matchit#Match_wrapper(word, forward, mode) range
let s:patBR = substitute(match_words .. ',',
\ s:notslash .. '\zs[,:]*,[,:]*', ',', 'g')
let s:patBR = substitute(s:patBR, s:notslash .. '\zs:\{2,}', ':', 'g')
+ " un-escape \, to ,
+ let s:patBR = substitute(s:patBR, '\\,', ',', 'g')
endif
" Second step: set the following local variables:
@@ -534,6 +538,8 @@ fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
else
let currpat = substitute(current, s:notslash .. a:branch, '\\|', 'g')
endif
+ " un-escape \, to ,
+ let currpat = substitute(currpat, '\\,', ',', 'g')
while a:string !~ a:prefix .. currpat .. a:suffix
let tail = strpart(tail, i)
let i = matchend(tail, s:notslash .. a:comma)
diff --git a/runtime/pack/dist/opt/matchit/doc/matchit.txt b/runtime/pack/dist/opt/matchit/doc/matchit.txt
index d072d59..ba74854 100644
--- a/runtime/pack/dist/opt/matchit/doc/matchit.txt
+++ b/runtime/pack/dist/opt/matchit/doc/matchit.txt
@@ -4,7 +4,7 @@ For instructions on installing this file, type
`:help matchit-install`
inside Vim.
-For Vim version 9.0. Last change: 2023 June 28
+For Vim version 9.1. Last change: 2024 May 20
VIM REFERENCE MANUAL by Benji Fisher et al
@@ -174,8 +174,8 @@ defined automatically.
2.1 Temporarily disable the matchit plugin *matchit-disable* *:MatchDisable*
-To temporarily reset the plugins, that are setup you can run the following
-command: >
+To temporarily disable the matchit plugin, after it hat been loaded,
+execute this command: >
:MatchDisable
This will delete all the defined key mappings to the Vim default.
diff --git a/runtime/pack/dist/opt/matchit/doc/tags b/runtime/pack/dist/opt/matchit/doc/tags
index 4ccdc87..e684fb1 100644
--- a/runtime/pack/dist/opt/matchit/doc/tags
+++ b/runtime/pack/dist/opt/matchit/doc/tags
@@ -1,4 +1,6 @@
:MatchDebug matchit.txt /*:MatchDebug*
+:MatchDisable matchit.txt /*:MatchDisable*
+:MatchEnable matchit.txt /*:MatchEnable*
MatchError matchit.txt /*MatchError*
[% matchit.txt /*[%*
]% matchit.txt /*]%*
@@ -26,6 +28,7 @@ matchit-choose matchit.txt /*matchit-choose*
matchit-configure matchit.txt /*matchit-configure*
matchit-debug matchit.txt /*matchit-debug*
matchit-details matchit.txt /*matchit-details*
+matchit-disable matchit.txt /*matchit-disable*
matchit-highlight matchit.txt /*matchit-highlight*
matchit-hl matchit.txt /*matchit-hl*
matchit-intro matchit.txt /*matchit-intro*
diff --git a/runtime/pack/dist/opt/matchit/plugin/matchit.vim b/runtime/pack/dist/opt/matchit/plugin/matchit.vim
index d6c735d..08fee09 100644
--- a/runtime/pack/dist/opt/matchit/plugin/matchit.vim
+++ b/runtime/pack/dist/opt/matchit/plugin/matchit.vim
@@ -1,7 +1,7 @@
" matchit.vim: (global plugin) Extended "%" matching
" Maintainer: Christian Brabandt
-" Version: 1.19
-" Last Change: 2023, June 28th
+" Version: 1.20
+" Last Change: 2024 May 20
" Repository: https://github.com/chrisbra/matchit
" Previous URL:http://www.vim.org/script.php?script_id=39
" Previous Maintainer: Benji Fisher PhD <benji@member.AMS.org>
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index 50833f0..d24ae57 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -1,518 +1,647 @@
-" Debugger plugin using gdb.
-"
-" Author: Bram Moolenaar
-" Copyright: Vim license applies, see ":help license"
-" Last Change: 2023 Nov 02
-"
-" WORK IN PROGRESS - The basics works stable, more to come
-" Note: In general you need at least GDB 7.12 because this provides the
-" frame= response in MI thread-selected events we need to sync stack to file.
-" The one included with "old" MingW is too old (7.6.1), you may upgrade it or
-" use a newer version from http://www.equation.com/servlet/equation.cmd?fa=gdb
-"
-" There are two ways to run gdb:
-" - In a terminal window; used if possible, does not work on MS-Windows
-" Not used when g:termdebug_use_prompt is set to 1.
-" - Using a "prompt" buffer; may use a terminal window for the program
-"
-" For both the current window is used to view source code and shows the
-" current statement from gdb.
-"
-" USING A TERMINAL WINDOW
-"
-" Opens two visible terminal windows:
-" 1. runs a pty for the debugged program, as with ":term NONE"
-" 2. runs gdb, passing the pty of the debugged program
-" A third terminal window is hidden, it is used for communication with gdb.
-"
-" USING A PROMPT BUFFER
-"
-" Opens a window with a prompt buffer to communicate with gdb.
-" Gdb is run as a job with callbacks for I/O.
-" On Unix another terminal window is opened to run the debugged program
-" On MS-Windows a separate console is opened to run the debugged program
-"
-" The communication with gdb uses GDB/MI. See:
-" https://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI.html
-
-" In case this gets sourced twice.
-if exists(':Termdebug')
- finish
-endif
+vim9script
-" Need either the +terminal feature or +channel and the prompt buffer.
-" The terminal feature does not work with gdb on win32.
-if has('terminal') && !has('win32')
- let s:way = 'terminal'
-elseif has('channel') && exists('*prompt_setprompt')
- let s:way = 'prompt'
-else
- if has('terminal')
- let s:err = 'Cannot debug, missing prompt buffer support'
- else
- let s:err = 'Cannot debug, +channel feature is not supported'
- endif
- command -nargs=* -complete=file -bang Termdebug echoerr s:err
- command -nargs=+ -complete=file -bang TermdebugCommand echoerr s:err
- finish
+# Debugger plugin using gdb.
+
+# Author: Bram Moolenaar
+# Copyright: Vim license applies, see ":help license"
+# Last Change: 2024 Jun 16
+# Converted to Vim9: Ubaldo Tiberi <ubaldo.tiberi@gmail.com>
+
+# WORK IN PROGRESS - The basics works stable, more to come
+# Note: In general you need at least GDB 7.12 because this provides the
+# frame= response in MI thread-selected events we need to sync stack to file.
+# The one included with "old" MingW is too old (7.6.1), you may upgrade it or
+# use a newer version from http://www.equation.com/servlet/equation.cmd?fa=gdb
+
+# There are two ways to run gdb:
+# - In a terminal window; used if possible, does not work on MS-Windows
+# Not used when g:termdebug_use_prompt is set to 1.
+# - Using a "prompt" buffer; may use a terminal window for the program
+
+# For both the current window is used to view source code and shows the
+# current statement from gdb.
+
+# USING A TERMINAL WINDOW
+
+# Opens two visible terminal windows:
+# 1. runs a pty for the debugged program, as with ":term NONE"
+# 2. runs gdb, passing the pty of the debugged program
+# A third terminal window is hidden, it is used for communication with gdb.
+
+# USING A PROMPT BUFFER
+
+# Opens a window with a prompt buffer to communicate with gdb.
+# Gdb is run as a job with callbacks for I/O.
+# On Unix another terminal window is opened to run the debugged program
+# On MS-Windows a separate console is opened to run the debugged program
+
+# The communication with gdb uses GDB/MI. See:
+# https://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI.html
+
+def Echoerr(msg: string)
+ echohl ErrorMsg | echom $'[termdebug] {msg}' | echohl None
+enddef
+
+
+# Variables to keep their status among multiple instances of Termdebug
+# Avoid to source the script twice.
+if exists('g:termdebug_loaded')
+ Echoerr('Termdebug already loaded.')
+ finish
endif
+g:termdebug_loaded = true
+
+# Script variables declaration. These variables are re-initialized at every
+# Termdebug instance
+var way: string
+var err: string
+
+var pc_id: number
+var asm_id: number
+var break_id: number
+var stopped: bool
+var running: bool
+
+var parsing_disasm_msg: number
+var asm_lines: list<string>
+var asm_addr: string
+
+# These shall be constants but cannot be initialized here
+# They indicate the buffer numbers of the main buffers used
+var gdbbufnr: number
+var gdbbufname: string
+var varbufnr: number
+var varbufname: string
+var asmbufnr: number
+var asmbufname: string
+var promptbuf: number
+# This is for the "debugged program" thing
+var ptybufnr: number
+var commbufnr: number
+
+var gdbjob: job
+var gdb_channel: channel
+# These changes because they relate to windows
+var pid: number
+var gdbwin: number
+var varwin: number
+var asmwin: number
+var ptywin: number
+var sourcewin: number
+
+# Contains breakpoints that have been placed, key is a string with the GDB
+# breakpoint number.
+# Each entry is a dict, containing the sub-breakpoints. Key is the subid.
+# For a breakpoint that is just a number the subid is zero.
+# For a breakpoint "123.4" the id is "123" and subid is "4".
+# Example, when breakpoint "44", "123", "123.1" and "123.2" exist:
+# {'44': {'0': entry}, '123': {'0': entry, '1': entry, '2': entry}}
+var breakpoints: dict<any>
+
+# Contains breakpoints by file/lnum. The key is "fname:lnum".
+# Each entry is a list of breakpoint IDs at that position.
+var breakpoint_locations: dict<any>
+var BreakpointSigns: list<string>
+
+var evalFromBalloonExpr: bool
+var evalFromBalloonExprResult: string
+var ignoreEvalError: bool
+var evalexpr: string
+# Remember the old value of 'signcolumn' for each buffer that it's set in, so
+# that we can restore the value for all buffers.
+var signcolumn_buflist: list<number>
+var save_columns: number
+
+var allleft: bool
+# This was s:vertical but I cannot use vertical as variable name
+var vvertical: bool
+
+var winbar_winids: list<number>
+
+var saved_mousemodel: string
+
+var k_map_saved: dict<any>
+var plus_map_saved: dict<any>
+var minus_map_saved: dict<any>
+
+
+def InitScriptVariables()
+ if exists('g:termdebug_config') && has_key(g:termdebug_config, 'use_prompt')
+ way = g:termdebug_config['use_prompt'] ? 'prompt' : 'terminal'
+ elseif exists('g:termdebug_use_prompt')
+ way = g:termdebug_use_prompt
+ elseif has('terminal') && !has('win32')
+ way = 'terminal'
+ else
+ way = 'prompt'
+ endif
+ err = ''
+
+ pc_id = 12
+ asm_id = 13
+ break_id = 14 # breakpoint number is added to this
+ stopped = true
+ running = false
+
+ parsing_disasm_msg = 0
+ asm_lines = []
+ asm_addr = ''
+
+ # They indicate the buffer numbers of the main buffers used
+ gdbbufnr = 0
+ gdbbufname = 'gdb'
+ varbufnr = 0
+ varbufname = 'Termdebug-variables-listing'
+ asmbufnr = 0
+ asmbufname = 'Termdebug-asm-listing'
+ promptbuf = 0
+ # This is for the "debugged program" thing
+ ptybufnr = 0
+ commbufnr = 0
+
+ gdbjob = null_job
+ gdb_channel = null_channel
+ # These changes because they relate to windows
+ pid = 0
+ gdbwin = 0
+ varwin = 0
+ asmwin = 0
+ ptywin = 0
+ sourcewin = 0
+
+ # Contains breakpoints that have been placed, key is a string with the GDB
+ # breakpoint number.
+ # Each entry is a dict, containing the sub-breakpoints. Key is the subid.
+ # For a breakpoint that is just a number the subid is zero.
+ # For a breakpoint "123.4" the id is "123" and subid is "4".
+ # Example, when breakpoint "44", "123", "123.1" and "123.2" exist:
+ # {'44': {'0': entry}, '123': {'0': entry, '1': entry, '2': entry}}
+ breakpoints = {}
+
+ # Contains breakpoints by file/lnum. The key is "fname:lnum".
+ # Each entry is a list of breakpoint IDs at that position.
+ breakpoint_locations = {}
+ BreakpointSigns = []
+
+ evalFromBalloonExpr = false
+ evalFromBalloonExprResult = ''
+ ignoreEvalError = false
+ evalexpr = ''
+ # Remember the old value of 'signcolumn' for each buffer that it's set in, so
+ # that we can restore the value for all buffers.
+ signcolumn_buflist = [bufnr()]
+ save_columns = 0
+
+ winbar_winids = []
+
+ k_map_saved = null_dict
+ plus_map_saved = null_dict
+ minus_map_saved = null_dict
-let s:keepcpo = &cpo
-set cpo&vim
-
-" The command that starts debugging, e.g. ":Termdebug vim".
-" To end type "quit" in the gdb window.
-command -nargs=* -complete=file -bang Termdebug call s:StartDebug(<bang>0, <f-args>)
-command -nargs=+ -complete=file -bang TermdebugCommand call s:StartDebugCommand(<bang>0, <f-args>)
-
-let s:pc_id = 12
-let s:asm_id = 13
-let s:break_id = 14 " breakpoint number is added to this
-let s:stopped = 1
-let s:running = 0
-
-let s:parsing_disasm_msg = 0
-let s:asm_lines = []
-let s:asm_addr = ''
-
-" Take a breakpoint number as used by GDB and turn it into an integer.
-" The breakpoint may contain a dot: 123.4 -> 123004
-" The main breakpoint has a zero subid.
-func s:Breakpoint2SignNumber(id, subid)
- return s:break_id + a:id * 1000 + a:subid
-endfunction
-
-" Define or adjust the default highlighting, using background "new".
-" When the 'background' option is set then "old" has the old value.
-func s:Highlight(init, old, new)
- let default = a:init ? 'default ' : ''
- if a:new ==# 'light' && a:old !=# 'light'
- exe "hi " . default . "debugPC term=reverse ctermbg=lightblue guibg=lightblue"
- elseif a:new ==# 'dark' && a:old !=# 'dark'
- exe "hi " . default . "debugPC term=reverse ctermbg=darkblue guibg=darkblue"
- endif
-endfunc
-
-" Define the default highlighting, using the current 'background' value.
-func s:InitHighlight()
- call s:Highlight(1, '', &background)
+ if has('menu')
+ saved_mousemodel = null_string
+ endif
+enddef
+# The command that starts debugging, e.g. ":Termdebug vim".
+# To end type "quit" in the gdb window.
+command -nargs=* -complete=file -bang Termdebug StartDebug(<bang>0, <f-args>)
+command -nargs=+ -complete=file -bang TermdebugCommand StartDebugCommand(<bang>0, <f-args>)
+
+
+# Take a breakpoint number as used by GDB and turn it into an integer.
+# The breakpoint may contain a dot: 123.4 -> 123004
+# The main breakpoint has a zero subid.
+def Breakpoint2SignNumber(id: number, subid: number): number
+ return break_id + id * 1000 + subid
+enddef
+
+# Define or adjust the default highlighting, using background "new".
+# When the 'background' option is set then "old" has the old value.
+def Highlight(init: bool, old: string, new: string)
+ var default = init ? 'default ' : ''
+ if new ==# 'light' && old !=# 'light'
+ exe $"hi {default}debugPC term=reverse ctermbg=lightblue guibg=lightblue"
+ elseif new ==# 'dark' && old !=# 'dark'
+ exe $"hi {default}debugPC term=reverse ctermbg=darkblue guibg=darkblue"
+ endif
+enddef
+
+# Define the default highlighting, using the current 'background' value.
+def InitHighlight()
+ Highlight(1, '', &background)
hi default debugBreakpoint term=reverse ctermbg=red guibg=red
hi default debugBreakpointDisabled term=reverse ctermbg=gray guibg=gray
-endfunc
+enddef
-" Setup an autocommand to redefine the default highlight when the colorscheme
-" is changed.
-func s:InitAutocmd()
+# Setup an autocommand to redefine the default highlight when the colorscheme
+# is changed.
+def InitAutocmd()
augroup TermDebug
autocmd!
- autocmd ColorScheme * call s:InitHighlight()
+ autocmd ColorScheme * InitHighlight()
augroup END
-endfunc
+enddef
-" Get the command to execute the debugger as a list, defaults to ["gdb"].
-func s:GetCommand()
+# Get the command to execute the debugger as a list, defaults to ["gdb"].
+def GetCommand(): list<string>
+ var cmd = 'gdb'
if exists('g:termdebug_config')
- let cmd = get(g:termdebug_config, 'command', 'gdb')
+ cmd = get(g:termdebug_config, 'command', 'gdb')
elseif exists('g:termdebugger')
- let cmd = g:termdebugger
- else
- let cmd = 'gdb'
+ cmd = g:termdebugger
endif
return type(cmd) == v:t_list ? copy(cmd) : [cmd]
-endfunc
+enddef
-func s:Echoerr(msg)
- echohl ErrorMsg | echom '[termdebug] ' .. a:msg | echohl None
-endfunc
+def StartDebug(bang: bool, ...gdb_args: list<string>)
+ InitScriptVariables()
+ # First argument is the command to debug, second core file or process ID.
+ StartDebug_internal({gdb_args: gdb_args, bang: bang})
+enddef
-func s:StartDebug(bang, ...)
- " First argument is the command to debug, second core file or process ID.
- call s:StartDebug_internal({'gdb_args': a:000, 'bang': a:bang})
-endfunc
+def StartDebugCommand(bang: bool, ...args: list<string>)
+ # First argument is the command to debug, rest are run arguments.
+ StartDebug_internal({gdb_args: [args[0]], proc_args: args[1 : ], bang: bang})
+enddef
-func s:StartDebugCommand(bang, ...)
- " First argument is the command to debug, rest are run arguments.
- call s:StartDebug_internal({'gdb_args': [a:1], 'proc_args': a:000[1:], 'bang': a:bang})
-endfunc
-func s:StartDebug_internal(dict)
- if exists('s:gdbwin')
- call s:Echoerr('Terminal debugger already running, cannot run two')
+def StartDebug_internal(dict: dict<any>)
+ if gdbwin > 0
+ Echoerr('Terminal debugger already running, cannot run two')
return
endif
- let gdbcmd = s:GetCommand()
+ var gdbcmd = GetCommand()
if !executable(gdbcmd[0])
- call s:Echoerr('Cannot execute debugger program "' .. gdbcmd[0] .. '"')
+ Echoerr($'Cannot execute debugger program "{gdbcmd[0]}"')
return
endif
- let s:ptywin = 0
- let s:pid = 0
- let s:asmwin = 0
- let s:asmbuf = 0
- let s:varwin = 0
- let s:varbuf = 0
-
if exists('#User#TermdebugStartPre')
doauto <nomodeline> User TermdebugStartPre
endif
- " Uncomment this line to write logging in "debuglog".
- " call ch_logfile('debuglog', 'w')
-
- let s:sourcewin = win_getid()
+ # Assume current window is the source code window
+ sourcewin = win_getid()
+ var wide = 0
- " Remember the old value of 'signcolumn' for each buffer that it's set in, so
- " that we can restore the value for all buffers.
- let b:save_signcolumn = &signcolumn
- let s:signcolumn_buflist = [bufnr()]
-
- let s:save_columns = 0
- let s:allleft = 0
- let wide = 0
if exists('g:termdebug_config')
- let wide = get(g:termdebug_config, 'wide', 0)
+ wide = get(g:termdebug_config, 'wide', 0)
elseif exists('g:termdebug_wide')
- let wide = g:termdebug_wide
+ wide = g:termdebug_wide
endif
if wide > 0
if &columns < wide
- let s:save_columns = &columns
- let &columns = wide
- " If we make the Vim window wider, use the whole left half for the debug
- " windows.
- let s:allleft = 1
+ save_columns = &columns
+ &columns = wide
+ # If we make the Vim window wider, use the whole left half for the debug
+ # windows.
+ allleft = true
endif
- let s:vertical = 1
- else
- let s:vertical = 0
- endif
-
- " Override using a terminal window by setting g:termdebug_use_prompt to 1.
- let use_prompt = 0
- if exists('g:termdebug_config')
- let use_prompt = get(g:termdebug_config, 'use_prompt', 0)
- elseif exists('g:termdebug_use_prompt')
- let use_prompt = g:termdebug_use_prompt
- endif
- if has('terminal') && !has('win32') && !use_prompt
- let s:way = 'terminal'
+ vvertical = true
else
- let s:way = 'prompt'
+ vvertical = false
endif
- if s:way == 'prompt'
- call s:StartDebug_prompt(a:dict)
+ if way == 'prompt'
+ StartDebug_prompt(dict)
else
- call s:StartDebug_term(a:dict)
+ StartDebug_term(dict)
endif
- if s:GetDisasmWindow()
- let curwinid = win_getid()
- call s:GotoAsmwinOrCreateIt()
- call win_gotoid(curwinid)
+ if GetDisasmWindow()
+ var curwinid = win_getid()
+ GotoAsmwinOrCreateIt()
+ win_gotoid(curwinid)
endif
- if s:GetVariablesWindow()
- let curwinid = win_getid()
- call s:GotoVariableswinOrCreateIt()
- call win_gotoid(curwinid)
+ if GetVariablesWindow()
+ var curwinid = win_getid()
+ GotoVariableswinOrCreateIt()
+ win_gotoid(curwinid)
endif
if exists('#User#TermdebugStartPost')
doauto <nomodeline> User TermdebugStartPost
endif
-endfunc
+enddef
-" Use when debugger didn't start or ended.
-func s:CloseBuffers()
- exe 'bwipe! ' . s:ptybuf
- exe 'bwipe! ' . s:commbuf
- if s:asmbuf > 0 && bufexists(s:asmbuf)
- exe 'bwipe! ' . s:asmbuf
- endif
- if s:varbuf > 0 && bufexists(s:varbuf)
- exe 'bwipe! ' . s:varbuf
- endif
- let s:running = 0
- unlet! s:gdbwin
-endfunc
+# Use when debugger didn't start or ended.
+def CloseBuffers()
+ var bufnames = ['debugged\ program', 'gdb\ communication', asmbufname, varbufname]
+ for bufname in bufnames
+ var buf_nr = bufnr(bufname)
+ if buf_nr > 0 && bufexists(buf_nr)
+ exe $'bwipe! {bufname}'
+ endif
+ endfor
-func s:CheckGdbRunning()
- let gdbproc = term_getjob(s:gdbbuf)
- if gdbproc == v:null || job_status(gdbproc) !=# 'run'
- call s:Echoerr(string(s:GetCommand()[0]) . ' exited unexpectedly')
- call s:CloseBuffers()
- return ''
- endif
- return 'ok'
-endfunc
-
-" Open a terminal window without a job, to run the debugged program in.
-func s:StartDebug_term(dict)
- let s:ptybuf = term_start('NONE', {
- \ 'term_name': 'debugged program',
- \ 'vertical': s:vertical,
- \ })
- if s:ptybuf == 0
- call s:Echoerr('Failed to open the program terminal window')
+ running = 0
+ gdbwin = 0
+enddef
+
+# IsGdbRunning(): bool may be a better name?
+def IsGdbStarted(): bool
+ var gdbproc_status = job_status(term_getjob(gdbbufnr))
+ if gdbproc_status !=# 'run'
+ var cmd_name = string(GetCommand()[0])
+ Echoerr($'{cmd_name} exited unexpectedly')
+ CloseBuffers()
+ return false
+ endif
+ return true
+enddef
+
+# Open a terminal window without a job, to run the debugged program in.
+def StartDebug_term(dict: dict<any>)
+ ptybufnr = term_start('NONE', {
+ term_name: 'debugged program',
+ vertical: vvertical})
+ if ptybufnr == 0
+ Echoerr('Failed to open the program terminal window')
return
endif
- let pty = job_info(term_getjob(s:ptybuf))['tty_out']
- let s:ptywin = win_getid()
- if s:vertical
- " Assuming the source code window will get a signcolumn, use two more
- " columns for that, thus one less for the terminal window.
- exe (&columns / 2 - 1) . "wincmd |"
- if s:allleft
- " use the whole left column
+ var pty = job_info(term_getjob(ptybufnr))['tty_out']
+ ptywin = win_getid()
+
+ if vvertical
+ # Assuming the source code window will get a signcolumn, use two more
+ # columns for that, thus one less for the terminal window.
+ exe $":{(&columns / 2 - 1)}wincmd |"
+ if allleft
+ # use the whole left column
wincmd H
endif
endif
- " Create a hidden terminal window to communicate with gdb
- let s:commbuf = term_start('NONE', {
- \ 'term_name': 'gdb communication',
- \ 'out_cb': function('s:CommOutput'),
- \ 'hidden': 1,
- \ })
- if s:commbuf == 0
- call s:Echoerr('Failed to open the communication terminal window')
- exe 'bwipe! ' . s:ptybuf
+ # Create a hidden terminal window to communicate with gdb
+ commbufnr = term_start('NONE', {
+ term_name: 'gdb communication',
+ out_cb: function('CommOutput'),
+ hidden: 1
+ })
+ if commbufnr == 0
+ Echoerr('Failed to open the communication terminal window')
+ exe $'bwipe! {ptybufnr}'
return
endif
- let commpty = job_info(term_getjob(s:commbuf))['tty_out']
+ var commpty = job_info(term_getjob(commbufnr))['tty_out']
- let gdb_args = get(a:dict, 'gdb_args', [])
- let proc_args = get(a:dict, 'proc_args', [])
+ # Start the gdb buffer
+ var gdb_args = get(dict, 'gdb_args', [])
+ var proc_args = get(dict, 'proc_args', [])
- let gdb_cmd = s:GetCommand()
+ var gdb_cmd = GetCommand()
+
+ gdbbufname = gdb_cmd[0]
if exists('g:termdebug_config') && has_key(g:termdebug_config, 'command_add_args')
- let gdb_cmd = g:termdebug_config.command_add_args(gdb_cmd, pty)
+ gdb_cmd = g:termdebug_config.command_add_args(gdb_cmd, pty)
else
- " Add -quiet to avoid the intro message causing a hit-enter prompt.
- let gdb_cmd += ['-quiet']
- " Disable pagination, it causes everything to stop at the gdb
- let gdb_cmd += ['-iex', 'set pagination off']
- " Interpret commands while the target is running. This should usually only
- " be exec-interrupt, since many commands don't work properly while the
- " target is running (so execute during startup).
- let gdb_cmd += ['-iex', 'set mi-async on']
- " Open a terminal window to run the debugger.
- let gdb_cmd += ['-tty', pty]
- " Command executed _after_ startup is done, provides us with the necessary
- " feedback
- let gdb_cmd += ['-ex', 'echo startupdone\n']
+ # Add -quiet to avoid the intro message causing a hit-enter prompt.
+ gdb_cmd += ['-quiet']
+ # Disable pagination, it causes everything to stop at the gdb
+ gdb_cmd += ['-iex', 'set pagination off']
+ # Interpret commands while the target is running. This should usually only
+ # be exec-interrupt, since many commands don't work properly while the
+ # target is running (so execute during startup).
+ gdb_cmd += ['-iex', 'set mi-async on']
+ # Open a terminal window to run the debugger.
+ gdb_cmd += ['-tty', pty]
+ # Command executed _after_ startup is done, provides us with the necessary
+ # feedback
+ gdb_cmd += ['-ex', 'echo startupdone\n']
endif
if exists('g:termdebug_config') && has_key(g:termdebug_config, 'command_filter')
- let gdb_cmd = g:termdebug_config.command_filter(gdb_cmd)
+ gdb_cmd = g:termdebug_config.command_filter(gdb_cmd)
endif
- " Adding arguments requested by the user
- let gdb_cmd += gdb_args
+ # Adding arguments requested by the user
+ gdb_cmd += gdb_args
- call ch_log('executing "' . join(gdb_cmd) . '"')
- let s:gdbbuf = term_start(gdb_cmd, {
- \ 'term_finish': 'close',
- \ })
- if s:gdbbuf == 0
- call s:Echoerr('Failed to open the gdb terminal window')
- call s:CloseBuffers()
+ ch_log($'executing "{join(gdb_cmd)}"')
+ gdbbufnr = term_start(gdb_cmd, {
+ term_name: gdbbufname,
+ term_finish: 'close',
+ })
+ if gdbbufnr == 0
+ Echoerr('Failed to open the gdb terminal window')
+ CloseBuffers()
return
endif
- let s:gdbwin = win_getid()
+ gdbwin = win_getid()
- " Wait for the "startupdone" message before sending any commands.
- let try_count = 0
- while 1
- if s:CheckGdbRunning() != 'ok'
+ # Wait for the "startupdone" message before sending any commands.
+ var counter = 0
+ var counter_max = 300
+ var success = false
+ while !success && counter < counter_max
+ if !IsGdbStarted()
+ CloseBuffers()
return
endif
for lnum in range(1, 200)
- if term_getline(s:gdbbuf, lnum) =~ 'startupdone'
- let try_count = 9999
- break
+ if term_getline(gdbbufnr, lnum) =~ 'startupdone'
+ success = true
endif
endfor
- let try_count += 1
- if try_count > 300
- " done or give up after five seconds
- break
- endif
+
+ # Each count is 10ms
+ counter += 1
sleep 10m
endwhile
- " Set arguments to be run.
+ if !success
+ Echoerr('Failed to startup the gdb program.')
+ CloseBuffers()
+ return
+ endif
+
+ # ---- gdb started. Next, let's set the MI interface. ---
+ # Set arguments to be run.
if len(proc_args)
- call term_sendkeys(s:gdbbuf, 'server set args ' . join(proc_args) . "\r")
+ term_sendkeys(gdbbufnr, $"server set args {join(proc_args)}\r")
endif
- " Connect gdb to the communication pty, using the GDB/MI interface.
- " Prefix "server" to avoid adding this to the history.
- call term_sendkeys(s:gdbbuf, 'server new-ui mi ' . commpty . "\r")
+ # Connect gdb to the communication pty, using the GDB/MI interface.
+ # Prefix "server" to avoid adding this to the history.
+ term_sendkeys(gdbbufnr, $"server new-ui mi {commpty}\r")
- " Wait for the response to show up, users may not notice the error and wonder
- " why the debugger doesn't work.
- let try_count = 0
- while 1
- if s:CheckGdbRunning() != 'ok'
+ # Wait for the response to show up, users may not notice the error and wonder
+ # why the debugger doesn't work.
+ counter = 0
+ counter_max = 300
+ success = false
+ while !success && counter < counter_max
+ if !IsGdbStarted()
return
endif
- let response = ''
+ var response = ''
for lnum in range(1, 200)
- let line1 = term_getline(s:gdbbuf, lnum)
- let line2 = term_getline(s:gdbbuf, lnum + 1)
+ var line1 = term_getline(gdbbufnr, lnum)
+ var line2 = term_getline(gdbbufnr, lnum + 1)
if line1 =~ 'new-ui mi '
- " response can be in the same line or the next line
- let response = line1 . line2
+ # response can be in the same line or the next line
+ response = $"{line1}{line2}"
if response =~ 'Undefined command'
- call s:Echoerr('Sorry, your gdb is too old, gdb 7.12 is required')
- " CHECKME: possibly send a "server show version" here
- call s:CloseBuffers()
+ Echoerr('Sorry, your gdb is too old, gdb 7.12 is required')
+ # CHECKME: possibly send a "server show version" here
+ CloseBuffers()
return
endif
if response =~ 'New UI allocated'
- " Success!
- break
+ # Success!
+ success = true
endif
elseif line1 =~ 'Reading symbols from' && line2 !~ 'new-ui mi '
- " Reading symbols might take a while, try more times
- let try_count -= 1
+ # Reading symbols might take a while, try more times
+ counter -= 1
endif
endfor
if response =~ 'New UI allocated'
break
endif
- let try_count += 1
- if try_count > 100
- call s:Echoerr('Cannot check if your gdb works, continuing anyway')
- break
- endif
+ counter += 1
sleep 10m
endwhile
- call job_setoptions(term_getjob(s:gdbbuf), {'exit_cb': function('s:EndTermDebug')})
+ if !success
+ Echoerr('Cannot check if your gdb works, continuing anyway')
+ return
+ endif
+
+ job_setoptions(term_getjob(gdbbufnr), {exit_cb: function('EndTermDebug')})
- " Set the filetype, this can be used to add mappings.
+ # Set the filetype, this can be used to add mappings.
set filetype=termdebug
- call s:StartDebugCommon(a:dict)
-endfunc
+ StartDebugCommon(dict)
+enddef
-" Open a window with a prompt buffer to run gdb in.
-func s:StartDebug_prompt(dict)
- if s:vertical
+# Open a window with a prompt buffer to run gdb in.
+def StartDebug_prompt(dict: dict<any>)
+ if vvertical
vertical new
else
new
endif
- let s:gdbwin = win_getid()
- let s:promptbuf = bufnr('')
- call prompt_setprompt(s:promptbuf, 'gdb> ')
+ gdbwin = win_getid()
+ promptbuf = bufnr('')
+ prompt_setprompt(promptbuf, 'gdb> ')
set buftype=prompt
- file gdb
- call prompt_setcallback(s:promptbuf, function('s:PromptCallback'))
- call prompt_setinterrupt(s:promptbuf, function('s:PromptInterrupt'))
-
- if s:vertical
- " Assuming the source code window will get a signcolumn, use two more
- " columns for that, thus one less for the terminal window.
- exe (&columns / 2 - 1) . "wincmd |"
- endif
-
- let gdb_args = get(a:dict, 'gdb_args', [])
- let proc_args = get(a:dict, 'proc_args', [])
-
- let gdb_cmd = s:GetCommand()
- " Add -quiet to avoid the intro message causing a hit-enter prompt.
- let gdb_cmd += ['-quiet']
- " Disable pagination, it causes everything to stop at the gdb, needs to be run early
- let gdb_cmd += ['-iex', 'set pagination off']
- " Interpret commands while the target is running. This should usually only
- " be exec-interrupt, since many commands don't work properly while the
- " target is running (so execute during startup).
- let gdb_cmd += ['-iex', 'set mi-async on']
- " directly communicate via mi2
- let gdb_cmd += ['--interpreter=mi2']
-
- " Adding arguments requested by the user
- let gdb_cmd += gdb_args
-
- call ch_log('executing "' . join(gdb_cmd) . '"')
- let s:gdbjob = job_start(gdb_cmd, {
- \ 'exit_cb': function('s:EndPromptDebug'),
- \ 'out_cb': function('s:GdbOutCallback'),
- \ })
- if job_status(s:gdbjob) != "run"
- call s:Echoerr('Failed to start gdb')
- exe 'bwipe! ' . s:promptbuf
+
+ if empty(glob('gdb'))
+ file gdb
+ elseif empty(glob('Termdebug-gdb-console'))
+ file Termdebug-gdb-console
+ else
+ Echoerr("You have a file/folder named 'gdb' " ..
+ "or 'Termdebug-gdb-console'. " ..
+ "Please exit and rename them because Termdebug may not work " ..
+ "as expected.")
+ endif
+
+ prompt_setcallback(promptbuf, function('PromptCallback'))
+ prompt_setinterrupt(promptbuf, function('PromptInterrupt'))
+
+ if vvertical
+ # Assuming the source code window will get a signcolumn, use two more
+ # columns for that, thus one less for the terminal window.
+ exe $":{(&columns / 2 - 1)}wincmd |"
+ endif
+
+ var gdb_args = get(dict, 'gdb_args', [])
+ var proc_args = get(dict, 'proc_args', [])
+
+ var gdb_cmd = GetCommand()
+ # Add -quiet to avoid the intro message causing a hit-enter prompt.
+ gdb_cmd += ['-quiet']
+ # Disable pagination, it causes everything to stop at the gdb, needs to be run early
+ gdb_cmd += ['-iex', 'set pagination off']
+ # Interpret commands while the target is running. This should usually only
+ # be exec-interrupt, since many commands don't work properly while the
+ # target is running (so execute during startup).
+ gdb_cmd += ['-iex', 'set mi-async on']
+ # directly communicate via mi2
+ gdb_cmd += ['--interpreter=mi2']
+
+ # Adding arguments requested by the user
+ gdb_cmd += gdb_args
+
+ ch_log($'executing "{join(gdb_cmd)}"')
+ gdbjob = job_start(gdb_cmd, {
+ exit_cb: function('EndPromptDebug'),
+ out_cb: function('GdbOutCallback'),
+ })
+ if job_status(gdbjob) != "run"
+ Echoerr('Failed to start gdb')
+ exe $'bwipe! {promptbuf}'
return
endif
- exe $'au BufUnload <buffer={s:promptbuf}> ++once ' ..
- \ 'call job_stop(s:gdbjob, ''kill'')'
- " Mark the buffer modified so that it's not easy to close.
+ exe $'au BufUnload <buffer={promptbuf}> ++once ' ..
+ 'call job_stop(gdbjob, ''kill'')'
+ # Mark the buffer modified so that it's not easy to close.
set modified
- let s:gdb_channel = job_getchannel(s:gdbjob)
+ gdb_channel = job_getchannel(gdbjob)
- let s:ptybuf = 0
+ ptybufnr = 0
if has('win32')
- " MS-Windows: run in a new console window for maximum compatibility
- call s:SendCommand('set new-console on')
+ # MS-Windows: run in a new console window for maximum compatibility
+ SendCommand('set new-console on')
elseif has('terminal')
- " Unix: Run the debugged program in a terminal window. Open it below the
- " gdb window.
- belowright let s:ptybuf = term_start('NONE', {
- \ 'term_name': 'debugged program',
- \ })
- if s:ptybuf == 0
- call s:Echoerr('Failed to open the program terminal window')
- call job_stop(s:gdbjob)
+ # Unix: Run the debugged program in a terminal window. Open it below the
+ # gdb window.
+ belowright ptybufnr = term_start('NONE', {
+ term_name: 'debugged program',
+ vertical: vvertical
+ })
+ if ptybufnr == 0
+ Echoerr('Failed to open the program terminal window')
+ job_stop(gdbjob)
return
endif
- let s:ptywin = win_getid()
- let pty = job_info(term_getjob(s:ptybuf))['tty_out']
- call s:SendCommand('tty ' . pty)
-
- " Since GDB runs in a prompt window, the environment has not been set to
- " match a terminal window, need to do that now.
- call s:SendCommand('set env TERM = xterm-color')
- call s:SendCommand('set env ROWS = ' . winheight(s:ptywin))
- call s:SendCommand('set env LINES = ' . winheight(s:ptywin))
- call s:SendCommand('set env COLUMNS = ' . winwidth(s:ptywin))
- call s:SendCommand('set env COLORS = ' . &t_Co)
- call s:SendCommand('set env VIM_TERMINAL = ' . v:version)
+ ptywin = win_getid()
+ var pty = job_info(term_getjob(ptybufnr))['tty_out']
+ SendCommand($'tty {pty}')
+
+ # Since GDB runs in a prompt window, the environment has not been set to
+ # match a terminal window, need to do that now.
+ SendCommand('set env TERM = xterm-color')
+ SendCommand($'set env ROWS = {winheight(ptywin)}')
+ SendCommand($'set env LINES = {winheight(ptywin)}')
+ SendCommand($'set env COLUMNS = {winwidth(ptywin)}')
+ SendCommand($'set env COLORS = {&t_Co}')
+ SendCommand($'set env VIM_TERMINAL = {v:version}')
else
- " TODO: open a new terminal, get the tty name, pass on to gdb
- call s:SendCommand('show inferior-tty')
+ # TODO: open a new terminal, get the tty name, pass on to gdb
+ SendCommand('show inferior-tty')
endif
- call s:SendCommand('set print pretty on')
- call s:SendCommand('set breakpoint pending on')
+ SendCommand('set print pretty on')
+ SendCommand('set breakpoint pending on')
- " Set arguments to be run
+ # Set arguments to be run
if len(proc_args)
- call s:SendCommand('set args ' . join(proc_args))
+ SendCommand($'set args {join(proc_args)}')
endif
- call s:StartDebugCommon(a:dict)
+ StartDebugCommon(dict)
startinsert
-endfunc
+enddef
-func s:StartDebugCommon(dict)
- " Sign used to highlight the line where the program has stopped.
- " There can be only one.
- call sign_define('debugPC', #{linehl: 'debugPC'})
+def StartDebugCommon(dict: dict<any>)
+ # Sign used to highlight the line where the program has stopped.
+ # There can be only one.
+ sign_define('debugPC', {linehl: 'debugPC'})
- " Install debugger commands in the text window.
- call win_gotoid(s:sourcewin)
- call s:InstallCommands()
- call win_gotoid(s:gdbwin)
+ # Install debugger commands in the text window.
+ win_gotoid(sourcewin)
+ InstallCommands()
+ win_gotoid(gdbwin)
- " Enable showing a balloon with eval info
+ # Enable showing a balloon with eval info
if has("balloon_eval") || has("balloon_eval_term")
set balloonexpr=TermDebugBalloonExpr()
if has("balloon_eval")
@@ -523,243 +652,260 @@ func s:StartDebugCommon(dict)
endif
endif
- " Contains breakpoints that have been placed, key is a string with the GDB
- " breakpoint number.
- " Each entry is a dict, containing the sub-breakpoints. Key is the subid.
- " For a breakpoint that is just a number the subid is zero.
- " For a breakpoint "123.4" the id is "123" and subid is "4".
- " Example, when breakpoint "44", "123", "123.1" and "123.2" exist:
- " {'44': {'0': entry}, '123': {'0': entry, '1': entry, '2': entry}}
- let s:breakpoints = {}
-
- " Contains breakpoints by file/lnum. The key is "fname:lnum".
- " Each entry is a list of breakpoint IDs at that position.
- let s:breakpoint_locations = {}
-
augroup TermDebug
- au BufRead * call s:BufRead()
- au BufUnload * call s:BufUnloaded()
- au OptionSet background call s:Highlight(0, v:option_old, v:option_new)
+ au BufRead * BufRead()
+ au BufUnload * BufUnloaded()
+ au OptionSet background Highlight(0, v:option_old, v:option_new)
augroup END
- " Run the command if the bang attribute was given and got to the debug
- " window.
- if get(a:dict, 'bang', 0)
- call s:SendResumingCommand('-exec-run')
- call win_gotoid(s:ptywin)
+ # Run the command if the bang attribute was given and got to the debug
+ # window.
+ if get(dict, 'bang', 0)
+ SendResumingCommand('-exec-run')
+ win_gotoid(ptywin)
endif
-endfunc
+enddef
-" Send a command to gdb. "cmd" is the string without line terminator.
-func s:SendCommand(cmd)
- call ch_log('sending to gdb: ' . a:cmd)
- if s:way == 'prompt'
- call ch_sendraw(s:gdb_channel, a:cmd . "\n")
+# Send a command to gdb. "cmd" is the string without line terminator.
+def SendCommand(cmd: string)
+ ch_log($'sending to gdb: {cmd}')
+ if way == 'prompt'
+ ch_sendraw(gdb_channel, $"{cmd}\n")
else
- call term_sendkeys(s:commbuf, a:cmd . "\r")
+ term_sendkeys(commbufnr, $"{cmd}\r")
endif
-endfunc
+enddef
-" This is global so that a user can create their mappings with this.
-func TermDebugSendCommand(cmd)
- if s:way == 'prompt'
- call ch_sendraw(s:gdb_channel, a:cmd . "\n")
+# Interrupt or stop the program
+def StopCommand()
+ if way == 'prompt'
+ PromptInterrupt()
else
- let do_continue = 0
- if !s:stopped
- let do_continue = 1
- Stop
+ SendCommand('-exec-interrupt')
+ endif
+enddef
+
+# Continue the program
+def ContinueCommand()
+ if way == 'prompt'
+ SendCommand('continue')
+ else
+ # using -exec-continue results in CTRL-C in the gdb window not working,
+ # communicating via commbuf (= use of SendCommand) has the same result
+ SendCommand('-exec-continue')
+ # command Continue term_sendkeys(gdbbuf, "continue\r")
+ endif
+enddef
+
+# This is global so that a user can create their mappings with this.
+def g:TermDebugSendCommand(cmd: string)
+ if way == 'prompt'
+ ch_sendraw(gdb_channel, $"{cmd}\n")
+ else
+ var do_continue = 0
+ if !stopped
+ do_continue = 1
+ StopCommand()
sleep 10m
endif
- " TODO: should we prepend CTRL-U to clear the command?
- call term_sendkeys(s:gdbbuf, a:cmd . "\r")
+ # TODO: should we prepend CTRL-U to clear the command?
+ term_sendkeys(gdbbufnr, $"{cmd}\r")
if do_continue
- Continue
+ ContinueCommand()
endif
endif
-endfunc
-
-" Send a command that resumes the program. If the program isn't stopped the
-" command is not sent (to avoid a repeated command to cause trouble).
-" If the command is sent then reset s:stopped.
-func s:SendResumingCommand(cmd)
- if s:stopped
- " reset s:stopped here, it may take a bit of time before we get a response
- let s:stopped = 0
- call ch_log('assume that program is running after this command')
- call s:SendCommand(a:cmd)
+enddef
+
+# Send a command that resumes the program. If the program isn't stopped the
+# command is not sent (to avoid a repeated command to cause trouble).
+# If the command is sent then reset stopped.
+def SendResumingCommand(cmd: string)
+ if stopped
+ # reset stopped here, it may take a bit of time before we get a response
+ stopped = false
+ ch_log('assume that program is running after this command')
+ SendCommand(cmd)
else
- call ch_log('dropping command, program is running: ' . a:cmd)
+ ch_log($'dropping command, program is running: {cmd}')
endif
-endfunc
+enddef
-" Function called when entering a line in the prompt buffer.
-func s:PromptCallback(text)
- call s:SendCommand(a:text)
-endfunc
+# Function called when entering a line in the prompt buffer.
+def PromptCallback(text: string)
+ SendCommand(text)
+enddef
-" Function called when pressing CTRL-C in the prompt buffer and when placing a
-" breakpoint.
-func s:PromptInterrupt()
- call ch_log('Interrupting gdb')
+# Function called when pressing CTRL-C in the prompt buffer and when placing a
+# breakpoint.
+def PromptInterrupt()
+ ch_log('Interrupting gdb')
if has('win32')
- " Using job_stop() does not work on MS-Windows, need to send SIGTRAP to
- " the debugger program so that gdb responds again.
- if s:pid == 0
- call s:Echoerr('Cannot interrupt gdb, did not find a process ID')
+ # Using job_stop() does not work on MS-Windows, need to send SIGTRAP to
+ # the debugger program so that gdb responds again.
+ if pid == 0
+ Echoerr('Cannot interrupt gdb, did not find a process ID')
else
- call debugbreak(s:pid)
+ debugbreak(pid)
endif
else
- call job_stop(s:gdbjob, 'int')
+ job_stop(gdbjob, 'int')
endif
-endfunc
+enddef
-" Function called when gdb outputs text.
-func s:GdbOutCallback(channel, text)
- call ch_log('received from gdb: ' . a:text)
+# Function called when gdb outputs text.
+def GdbOutCallback(channel: channel, text: string)
+ ch_log($'received from gdb: {text}')
- " Disassembly messages need to be forwarded as-is.
- if s:parsing_disasm_msg
- call s:CommOutput(a:channel, a:text)
+ # Disassembly messages need to be forwarded as-is.
+ if parsing_disasm_msg > 0
+ CommOutput(channel, text)
return
- end
+ endif
- " Drop the gdb prompt, we have our own.
- " Drop status and echo'd commands.
- if a:text == '(gdb) ' || a:text == '^done' ||
- \ (a:text[0] == '&' && a:text !~ '^&"disassemble')
+ # Drop the gdb prompt, we have our own.
+ # Drop status and echo'd commands.
+ if text == '(gdb) ' || text == '^done' ||
+ (text[0] == '&' && text !~ '^&"disassemble')
return
endif
- if a:text =~ '^\^error,msg='
- let text = s:DecodeMessage(a:text[11:], v:false)
- if exists('s:evalexpr') && text =~ 'A syntax error in expression, near\|No symbol .* in current context'
- " Silently drop evaluation errors.
- unlet s:evalexpr
+
+ var decoded_text = ''
+ if text =~ '^\^error,msg='
+ decoded_text = DecodeMessage(text[11 : ], false)
+ if !empty(evalexpr) && decoded_text =~ 'A syntax error in expression, near\|No symbol .* in current context'
+ # Silently drop evaluation errors.
+ evalexpr = ''
return
endif
- elseif a:text[0] == '~'
- let text = s:DecodeMessage(a:text[1:], v:false)
+ elseif text[0] == '~'
+ decoded_text = DecodeMessage(text[1 : ], false)
else
- call s:CommOutput(a:channel, a:text)
+ CommOutput(channel, text)
return
endif
- let curwinid = win_getid()
- call win_gotoid(s:gdbwin)
+ var curwinid = win_getid()
+ win_gotoid(gdbwin)
- " Add the output above the current prompt.
- call append(line('$') - 1, text)
+ # Add the output above the current prompt.
+ append(line('$') - 1, decoded_text)
set modified
- call win_gotoid(curwinid)
-endfunc
-
-" Decode a message from gdb. "quotedText" starts with a ", return the text up
-" to the next unescaped ", unescaping characters:
-" - remove line breaks (unless "literal" is v:true)
-" - change \" to "
-" - change \\t to \t (unless "literal" is v:true)
-" - change \0xhh to \xhh (disabled for now)
-" - change \ooo to octal
-" - change \\ to \
-func s:DecodeMessage(quotedText, literal)
- if a:quotedText[0] != '"'
- call s:Echoerr('DecodeMessage(): missing quote in ' . a:quotedText)
- return
+ win_gotoid(curwinid)
+enddef
+
+# Decode a message from gdb. "quotedText" starts with a ", return the text up
+# to the next unescaped ", unescaping characters:
+# - remove line breaks (unless "literal" is true)
+# - change \" to "
+# - change \\t to \t (unless "literal" is true)
+# - change \0xhh to \xhh (disabled for now)
+# - change \ooo to octal
+# - change \\ to \
+def DecodeMessage(quotedText: string, literal: bool): string
+ if quotedText[0] != '"'
+ Echoerr($'DecodeMessage(): missing quote in {quotedText}')
+ return ''
endif
- let msg = a:quotedText
- \ ->substitute('^"\|[^\\]\zs".*', '', 'g')
- \ ->substitute('\\"', '"', 'g')
- "\ multi-byte characters arrive in octal form
- "\ NULL-values must be kept encoded as those break the string otherwise
- \ ->substitute('\\000', s:NullRepl, 'g')
- \ ->substitute('\\\o\o\o', {-> eval('"' .. submatch(0) .. '"')}, 'g')
- "\ Note: GDB docs also mention hex encodings - the translations below work
- "\ but we keep them out for performance-reasons until we actually see
- "\ those in mi-returns
- "\ \ ->substitute('\\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. '"')}, 'g')
- "\ \ ->substitute('\\0x00', s:NullRepl, 'g')
- \ ->substitute('\\\\', '\', 'g')
- \ ->substitute(s:NullRepl, '\\000', 'g')
- if !a:literal
+ var msg = quotedText
+ ->substitute('^"\|[^\\]\zs".*', '', 'g')
+ ->substitute('\\"', '"', 'g')
+ #\ multi-byte characters arrive in octal form
+ #\ NULL-values must be kept encoded as those break the string otherwise
+ ->substitute('\\000', NullRepl, 'g')
+ ->substitute('\\\(\o\o\o\)', (m) => nr2char(str2nr(m[1], 8)), 'g')
+ # You could also use ->substitute('\\\\\(\o\o\o\)', '\=nr2char(str2nr(submatch(1), 8))', "g")
+ #\ Note: GDB docs also mention hex encodings - the translations below work
+ #\ but we keep them out for performance-reasons until we actually see
+ #\ those in mi-returns
+ #\ \ ->substitute('\\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. '"')}, 'g')
+ #\ \ ->substitute('\\0x00', NullRepl, 'g')
+ ->substitute('\\\\', '\', 'g')
+ ->substitute(NullRepl, '\\000', 'g')
+ if !literal
return msg
- \ ->substitute('\\t', "\t", 'g')
- \ ->substitute('\\n', '', 'g')
+ ->substitute('\\t', "\t", 'g')
+ ->substitute('\\n', '', 'g')
else
return msg
endif
-endfunc
-const s:NullRepl = 'XXXNULLXXX'
+enddef
+const NullRepl = 'XXXNULLXXX'
-" Extract the "name" value from a gdb message with fullname="name".
-func s:GetFullname(msg)
- if a:msg !~ 'fullname'
+# Extract the "name" value from a gdb message with fullname="name".
+def GetFullname(msg: string): string
+ if msg !~ 'fullname'
return ''
endif
- let name = s:DecodeMessage(substitute(a:msg, '.*fullname=', '', ''), v:true)
+
+ var name = DecodeMessage(substitute(msg, '.*fullname=', '', ''), true)
if has('win32') && name =~ ':\\\\'
- " sometimes the name arrives double-escaped
- let name = substitute(name, '\\\\', '\\', 'g')
+ # sometimes the name arrives double-escaped
+ name = substitute(name, '\\\\', '\\', 'g')
endif
+
return name
-endfunc
+enddef
-" Extract the "addr" value from a gdb message with addr="0x0001234".
-func s:GetAsmAddr(msg)
- if a:msg !~ 'addr='
+# Extract the "addr" value from a gdb message with addr="0x0001234".
+def GetAsmAddr(msg: string): string
+ if msg !~ 'addr='
return ''
endif
- let addr = s:DecodeMessage(substitute(a:msg, '.*addr=', '', ''), v:false)
+
+ var addr = DecodeMessage(substitute(msg, '.*addr=', '', ''), false)
return addr
-endfunc
+enddef
-func s:EndTermDebug(job, status)
+
+def EndTermDebug(job: any, status: any)
if exists('#User#TermdebugStopPre')
doauto <nomodeline> User TermdebugStopPre
endif
- exe 'bwipe! ' . s:commbuf
- unlet s:gdbwin
- call s:EndDebugCommon()
-endfunc
+ if commbufnr > 0 && bufexists(commbufnr)
+ exe $'bwipe! {commbufnr}'
+ endif
+ gdbwin = 0
+ EndDebugCommon()
+enddef
-func s:EndDebugCommon()
- let curwinid = win_getid()
+def EndDebugCommon()
+ var curwinid = win_getid()
- if exists('s:ptybuf') && s:ptybuf
- exe 'bwipe! ' . s:ptybuf
+ if ptybufnr > 0 && bufexists(ptybufnr)
+ exe $'bwipe! {ptybufnr}'
endif
- if s:asmbuf > 0 && bufexists(s:asmbuf)
- exe 'bwipe! ' . s:asmbuf
+ if asmbufnr > 0 && bufexists(asmbufnr)
+ exe $'bwipe! {asmbufnr}'
endif
- if s:varbuf > 0 && bufexists(s:varbuf)
- exe 'bwipe! ' . s:varbuf
+ if varbufnr > 0 && bufexists(varbufnr)
+ exe $'bwipe! {varbufnr}'
endif
- let s:running = 0
+ running = false
- " Restore 'signcolumn' in all buffers for which it was set.
- call win_gotoid(s:sourcewin)
- let was_buf = bufnr()
- for bufnr in s:signcolumn_buflist
+ # Restore 'signcolumn' in all buffers for which it was set.
+ win_gotoid(sourcewin)
+ var was_buf = bufnr()
+ for bufnr in signcolumn_buflist
if bufexists(bufnr)
- exe bufnr .. "buf"
+ exe $":{bufnr}buf"
if exists('b:save_signcolumn')
- let &signcolumn = b:save_signcolumn
+ &signcolumn = b:save_signcolumn
unlet b:save_signcolumn
endif
endif
endfor
if bufexists(was_buf)
- exe was_buf .. "buf"
+ exe $":{was_buf}buf"
endif
- call s:DeleteCommands()
+ DeleteCommands()
- call win_gotoid(curwinid)
+ win_gotoid(curwinid)
- if s:save_columns > 0
- let &columns = s:save_columns
+ if save_columns > 0
+ &columns = save_columns
endif
if has("balloon_eval") || has("balloon_eval_term")
@@ -777,262 +923,262 @@ func s:EndDebugCommon()
endif
au! TermDebug
-endfunc
+enddef
-func s:EndPromptDebug(job, status)
+def EndPromptDebug(job: any, status: any)
if exists('#User#TermdebugStopPre')
doauto <nomodeline> User TermdebugStopPre
endif
- if bufexists(s:promptbuf)
- exe 'bwipe! ' . s:promptbuf
- endif
-
- call s:EndDebugCommon()
- unlet s:gdbwin
- call ch_log("Returning from EndPromptDebug()")
-endfunc
-
-" Disassembly window - added by Michael Sartain
-"
-" - CommOutput: &"disassemble $pc\n"
-" - CommOutput: ~"Dump of assembler code for function main(int, char**):\n"
-" - CommOutput: ~" 0x0000555556466f69 <+0>:\tpush rbp\n"
-" ...
-" - CommOutput: ~" 0x0000555556467cd0:\tpop rbp\n"
-" - CommOutput: ~" 0x0000555556467cd1:\tret \n"
-" - CommOutput: ~"End of assembler dump.\n"
-" - CommOutput: ^done
-
-" - CommOutput: &"disassemble $pc\n"
-" - CommOutput: &"No function contains specified address.\n"
-" - CommOutput: ^error,msg="No function contains specified address."
-func s:HandleDisasmMsg(msg)
- if a:msg =~ '^\^done'
- let curwinid = win_getid()
- if win_gotoid(s:asmwin)
- silent! %delete _
- call setline(1, s:asm_lines)
+ if bufexists(promptbuf)
+ exe $'bwipe! {promptbuf}'
+ endif
+
+ EndDebugCommon()
+ gdbwin = 0
+ ch_log("Returning from EndPromptDebug()")
+enddef
+
+
+# Disassembly window - added by Michael Sartain
+#
+# - CommOutput: &"disassemble $pc\n"
+# - CommOutput: ~"Dump of assembler code for function main(int, char**):\n"
+# - CommOutput: ~" 0x0000555556466f69 <+0>:\tpush rbp\n"
+# ...
+# - CommOutput: ~" 0x0000555556467cd0:\tpop rbp\n"
+# - CommOutput: ~" 0x0000555556467cd1:\tret \n"
+# - CommOutput: ~"End of assembler dump.\n"
+# - CommOutput: ^done
+
+# - CommOutput: &"disassemble $pc\n"
+# - CommOutput: &"No function contains specified address.\n"
+# - CommOutput: ^error,msg="No function contains specified address."
+def HandleDisasmMsg(msg: string)
+ if msg =~ '^\^done'
+ var curwinid = win_getid()
+ if win_gotoid(asmwin)
+ silent! :%delete _
+ setline(1, asm_lines)
set nomodified
set filetype=asm
- let lnum = search('^' . s:asm_addr)
+ var lnum = search($'^{asm_addr}')
if lnum != 0
- call sign_unplace('TermDebug', #{id: s:asm_id})
- call sign_place(s:asm_id, 'TermDebug', 'debugPC', '%', #{lnum: lnum})
+ sign_unplace('TermDebug', {id: asm_id})
+ sign_place(asm_id, 'TermDebug', 'debugPC', '%', {lnum: lnum})
endif
- call win_gotoid(curwinid)
+ win_gotoid(curwinid)
endif
- let s:parsing_disasm_msg = 0
- let s:asm_lines = []
- elseif a:msg =~ '^\^error,msg='
- if s:parsing_disasm_msg == 1
- " Disassemble call ran into an error. This can happen when gdb can't
- " find the function frame address, so let's try to disassemble starting
- " at current PC
- call s:SendCommand('disassemble $pc,+100')
+ parsing_disasm_msg = 0
+ asm_lines = []
+
+ elseif msg =~ '^\^error,msg='
+ if parsing_disasm_msg == 1
+ # Disassemble call ran into an error. This can happen when gdb can't
+ # find the function frame address, so let's try to disassemble starting
+ # at current PC
+ SendCommand('disassemble $pc,+100')
endif
- let s:parsing_disasm_msg = 0
- elseif a:msg =~ '^&"disassemble \$pc'
- if a:msg =~ '+100'
- " This is our second disasm attempt
- let s:parsing_disasm_msg = 2
+ parsing_disasm_msg = 0
+ elseif msg =~ '^&"disassemble \$pc'
+ if msg =~ '+100'
+ # This is our second disasm attempt
+ parsing_disasm_msg = 2
endif
- elseif a:msg !~ '^&"disassemble'
- let value = substitute(a:msg, '^\~\"[ ]*', '', '')
- let value = substitute(value, '^=>[ ]*', '', '')
- let value = substitute(value, '\\n\"\r$', '', '')
- let value = substitute(value, '\\n\"$', '', '')
- let value = substitute(value, '\r', '', '')
- let value = substitute(value, '\\t', ' ', 'g')
-
- if value != '' || !empty(s:asm_lines)
- call add(s:asm_lines, value)
+ elseif msg !~ '^&"disassemble'
+ var value = substitute(msg, '^\~\"[ ]*', '', '')
+ ->substitute('^=>[ ]*', '', '')
+ ->substitute('\\n\"\r$', '', '')
+ ->substitute('\\n\"$', '', '')
+ ->substitute('\r', '', '')
+ ->substitute('\\t', ' ', 'g')
+
+ if value != '' || !empty(asm_lines)
+ add(asm_lines, value)
endif
endif
-endfunc
-
-func s:ParseVarinfo(varinfo)
- let dict = {}
- let nameIdx = matchstrpos(a:varinfo, '{name="\([^"]*\)"')
- let dict['name'] = a:varinfo[nameIdx[1] + 7 : nameIdx[2] - 2]
- let typeIdx = matchstrpos(a:varinfo, ',type="\([^"]*\)"')
- " 'type' maybe is a url-like string,
- " try to shorten it and show only the /tail
- let dict['type'] = (a:varinfo[typeIdx[1] + 7 : typeIdx[2] - 2])->fnamemodify(':t')
- let valueIdx = matchstrpos(a:varinfo, ',value="\(.*\)"}')
+enddef
+
+
+def ParseVarinfo(varinfo: string): dict<any>
+ var dict = {}
+ var nameIdx = matchstrpos(varinfo, '{name="\([^"]*\)"')
+ dict['name'] = varinfo[nameIdx[1] + 7 : nameIdx[2] - 2]
+ var typeIdx = matchstrpos(varinfo, ',type="\([^"]*\)"')
+ # 'type' maybe is a url-like string,
+ # try to shorten it and show only the /tail
+ dict['type'] = (varinfo[typeIdx[1] + 7 : typeIdx[2] - 2])->fnamemodify(':t')
+ var valueIdx = matchstrpos(varinfo, ',value="\(.*\)"}')
if valueIdx[1] == -1
- let dict['value'] = 'Complex value'
+ dict['value'] = 'Complex value'
else
- let dict['value'] = a:varinfo[valueIdx[1] + 8 : valueIdx[2] - 3]
+ dict['value'] = varinfo[valueIdx[1] + 8 : valueIdx[2] - 3]
endif
return dict
-endfunc
-
-func s:HandleVariablesMsg(msg)
- let curwinid = win_getid()
- if win_gotoid(s:varwin)
-
- silent! %delete _
- let spaceBuffer = 20
- call setline(1, 'Type' .
- \ repeat(' ', 16) .
- \ 'Name' .
- \ repeat(' ', 16) .
- \ 'Value')
- let cnt = 1
- let capture = '{name=".\{-}",\%(arg=".\{-}",\)\{0,1\}type=".\{-}"\%(,value=".\{-}"\)\{0,1\}}'
- let varinfo = matchstr(a:msg, capture, 0, cnt)
+enddef
+
+def HandleVariablesMsg(msg: string)
+ var curwinid = win_getid()
+ if win_gotoid(varwin)
+ silent! :%delete _
+ var spaceBuffer = 20
+ var spaces = repeat(' ', 16)
+ setline(1, $'Type{spaces}Name{spaces}Value')
+ var cnt = 1
+ var capture = '{name=".\{-}",\%(arg=".\{-}",\)\{0,1\}type=".\{-}"\%(,value=".\{-}"\)\{0,1\}}'
+ var varinfo = matchstr(msg, capture, 0, cnt)
+
while varinfo != ''
- let vardict = s:ParseVarinfo(varinfo)
- call setline(cnt + 1, vardict['type'] .
- \ repeat(' ', max([20 - len(vardict['type']), 1])) .
- \ vardict['name'] .
- \ repeat(' ', max([20 - len(vardict['name']), 1])) .
- \ vardict['value'])
- let cnt += 1
- let varinfo = matchstr(a:msg, capture, 0, cnt)
+ var vardict = ParseVarinfo(varinfo)
+ setline(cnt + 1, vardict['type'] ..
+ repeat(' ', max([20 - len(vardict['type']), 1])) ..
+ vardict['name'] ..
+ repeat(' ', max([20 - len(vardict['name']), 1])) ..
+ vardict['value'])
+ cnt += 1
+ varinfo = matchstr(msg, capture, 0, cnt)
endwhile
endif
- call win_gotoid(curwinid)
-endfunc
+ win_gotoid(curwinid)
+enddef
+
-" Handle a message received from gdb on the GDB/MI interface.
-func s:CommOutput(chan, msg)
- let msgs = split(a:msg, "\r")
+# Handle a message received from gdb on the GDB/MI interface.
+def CommOutput(chan: channel, message: string)
+ # We may use the standard MI message formats? See #10300 on github that mentions
+ # the following links:
+ # https://sourceware.org/gdb/current/onlinedocs/gdb.html/GDB_002fMI-Input-Syntax.html#GDB_002fMI-Input-Syntax
+ # https://sourceware.org/gdb/current/onlinedocs/gdb.html/GDB_002fMI-Output-Syntax.html#GDB_002fMI-Output-Syntax
- for msg in msgs
- " remove prefixed NL
- if msg[0] == "\n"
- let msg = msg[1:]
+ var msgs = split(message, "\r")
+
+ var msg = ''
+ for received_msg in msgs
+ # remove prefixed NL
+ if received_msg[0] == "\n"
+ msg = received_msg[1 : ]
+ else
+ msg = received_msg
endif
- if s:parsing_disasm_msg
- call s:HandleDisasmMsg(msg)
+ if parsing_disasm_msg > 0
+ HandleDisasmMsg(msg)
elseif msg != ''
if msg =~ '^\(\*stopped\|\*running\|=thread-selected\)'
- call s:HandleCursor(msg)
+ HandleCursor(msg)
elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,'
- call s:HandleNewBreakpoint(msg, 0)
+ HandleNewBreakpoint(msg, 0)
elseif msg =~ '^=breakpoint-modified,'
- call s:HandleNewBreakpoint(msg, 1)
+ HandleNewBreakpoint(msg, 1)
elseif msg =~ '^=breakpoint-deleted,'
- call s:HandleBreakpointDelete(msg)
+ HandleBreakpointDelete(msg)
elseif msg =~ '^=thread-group-started'
- call s:HandleProgramRun(msg)
+ HandleProgramRun(msg)
elseif msg =~ '^\^done,value='
- call s:HandleEvaluate(msg)
+ HandleEvaluate(msg)
elseif msg =~ '^\^error,msg='
- call s:HandleError(msg)
+ HandleError(msg)
elseif msg =~ '^&"disassemble'
- let s:parsing_disasm_msg = 1
- let s:asm_lines = []
- call s:HandleDisasmMsg(msg)
+ parsing_disasm_msg = 1
+ asm_lines = []
+ HandleDisasmMsg(msg)
elseif msg =~ '^\^done,variables='
- call s:HandleVariablesMsg(msg)
+ HandleVariablesMsg(msg)
endif
endif
endfor
-endfunc
+enddef
-func s:GotoProgram()
+def GotoProgram()
if has('win32')
if executable('powershell')
- call system(printf('powershell -Command "add-type -AssemblyName microsoft.VisualBasic;[Microsoft.VisualBasic.Interaction]::AppActivate(%d);"', s:pid))
+ system(printf('powershell -Command "add-type -AssemblyName microsoft.VisualBasic;[Microsoft.VisualBasic.Interaction]::AppActivate(%d);"', pid))
endif
else
- call win_gotoid(s:ptywin)
- endif
-endfunc
-
-" Install commands in the current window to control the debugger.
-func s:InstallCommands()
- let save_cpo = &cpo
- set cpo&vim
-
- command -nargs=? Break call s:SetBreakpoint(<q-args>)
- command -nargs=? Tbreak call s:SetBreakpoint(<q-args>, v:true)
- command Clear call s:ClearBreakpoint()
- command Step call s:SendResumingCommand('-exec-step')
- command Over call s:SendResumingCommand('-exec-next')
- command -nargs=? Until call s:Until(<q-args>)
- command Finish call s:SendResumingCommand('-exec-finish')
- command -nargs=* Run call s:Run(<q-args>)
- command -nargs=* Arguments call s:SendResumingCommand('-exec-arguments ' . <q-args>)
-
- if s:way == 'prompt'
- command Stop call s:PromptInterrupt()
- command Continue call s:SendCommand('continue')
- else
- command Stop call s:SendCommand('-exec-interrupt')
- " using -exec-continue results in CTRL-C in the gdb window not working,
- " communicating via commbuf (= use of SendCommand) has the same result
- "command Continue call s:SendCommand('-exec-continue')
- command Continue call term_sendkeys(s:gdbbuf, "continue\r")
- endif
-
- command -nargs=* Frame call s:Frame(<q-args>)
- command -count=1 Up call s:Up(<count>)
- command -count=1 Down call s:Down(<count>)
-
- command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>)
- command Gdb call win_gotoid(s:gdbwin)
- command Program call s:GotoProgram()
- command Source call s:GotoSourcewinOrCreateIt()
- command Asm call s:GotoAsmwinOrCreateIt()
- command Var call s:GotoVariableswinOrCreateIt()
- command Winbar call s:InstallWinbar(1)
-
- let map = 1
+ win_gotoid(ptywin)
+ endif
+enddef
+
+# Install commands in the current window to control the debugger.
+def InstallCommands()
+
+ command -nargs=? Break SetBreakpoint(<q-args>)
+ command -nargs=? Tbreak SetBreakpoint(<q-args>, true)
+ command Clear ClearBreakpoint()
+ command Step SendResumingCommand('-exec-step')
+ command Over SendResumingCommand('-exec-next')
+ command -nargs=? Until Until(<q-args>)
+ command Finish SendResumingCommand('-exec-finish')
+ command -nargs=* Run Run(<q-args>)
+ command -nargs=* Arguments SendResumingCommand('-exec-arguments ' .. <q-args>)
+ command Stop StopCommand()
+ command Continue ContinueCommand()
+
+ command -nargs=* Frame Frame(<q-args>)
+ command -count=1 Up Up(<count>)
+ command -count=1 Down Down(<count>)
+
+ command -range -nargs=* Evaluate Evaluate(<range>, <q-args>)
+ command Gdb win_gotoid(gdbwin)
+ command Program GotoProgram()
+ command Source GotoSourcewinOrCreateIt()
+ command Asm GotoAsmwinOrCreateIt()
+ command Var GotoVariableswinOrCreateIt()
+ command Winbar InstallWinbar(1)
+
+ var map = 1
if exists('g:termdebug_config')
- let map = get(g:termdebug_config, 'map_K', 1)
+ map = get(g:termdebug_config, 'map_K', 1)
elseif exists('g:termdebug_map_K')
- let map = g:termdebug_map_K
+ map = g:termdebug_map_K
endif
+
if map
- let s:k_map_saved = maparg('K', 'n', 0, 1)
- if !empty(s:k_map_saved) && !s:k_map_saved.buffer || empty(s:k_map_saved)
+ k_map_saved = maparg('K', 'n', 0, 1)
+ if !empty(k_map_saved) && !k_map_saved.buffer || empty(k_map_saved)
nnoremap K :Evaluate<CR>
endif
endif
- let map = 1
+ map = 1
if exists('g:termdebug_config')
- let map = get(g:termdebug_config, 'map_plus', 1)
+ map = get(g:termdebug_config, 'map_plus', 1)
endif
if map
- let s:plus_map_saved = maparg('+', 'n', 0, 1)
- if !empty(s:plus_map_saved) && !s:plus_map_saved.buffer || empty(s:plus_map_saved)
+ plus_map_saved = maparg('+', 'n', 0, 1)
+ if !empty(plus_map_saved) && !plus_map_saved.buffer || empty(plus_map_saved)
nnoremap <expr> + $'<Cmd>{v:count1}Up<CR>'
endif
endif
- let map = 1
+ map = 1
if exists('g:termdebug_config')
- let map = get(g:termdebug_config, 'map_minus', 1)
+ map = get(g:termdebug_config, 'map_minus', 1)
endif
if map
- let s:minus_map_saved = maparg('-', 'n', 0, 1)
- if !empty(s:minus_map_saved) && !s:minus_map_saved.buffer || empty(s:minus_map_saved)
+ minus_map_saved = maparg('-', 'n', 0, 1)
+ if !empty(minus_map_saved) && !minus_map_saved.buffer || empty(minus_map_saved)
nnoremap <expr> - $'<Cmd>{v:count1}Down<CR>'
endif
endif
if has('menu') && &mouse != ''
- call s:InstallWinbar(0)
+ InstallWinbar(0)
- let popup = 1
+ var pup = 1
if exists('g:termdebug_config')
- let popup = get(g:termdebug_config, 'popup', 1)
+ pup = get(g:termdebug_config, 'popup', 1)
elseif exists('g:termdebug_popup')
- let popup = g:termdebug_popup
+ pup = g:termdebug_popup
endif
- if popup
- let s:saved_mousemodel = &mousemodel
- let &mousemodel = 'popup_setpos'
+
+ if pup
+ saved_mousemodel = &mousemodel
+ &mousemodel = 'popup_setpos'
an 1.200 PopUp.-SEP3- <Nop>
an 1.210 PopUp.Set\ breakpoint :Break<CR>
an 1.220 PopUp.Clear\ breakpoint :Clear<CR>
@@ -1041,32 +1187,29 @@ func s:InstallCommands()
endif
endif
- let &cpo = save_cpo
-endfunc
+enddef
-let s:winbar_winids = []
-
-" Install the window toolbar in the current window.
-func s:InstallWinbar(force)
- " install the window toolbar by default, can be disabled in the config
- let winbar = 1
+# Install the window toolbar in the current window.
+def InstallWinbar(force: number)
+ # install the window toolbar by default, can be disabled in the config
+ var winbar = 1
if exists('g:termdebug_config')
- let winbar = get(g:termdebug_config, 'winbar', 1)
+ winbar = get(g:termdebug_config, 'winbar', 1)
endif
- if has('menu') && &mouse != '' && (winbar || a:force)
+ if has('menu') && &mouse != '' && (winbar || force)
nnoremenu WinBar.Step :Step<CR>
nnoremenu WinBar.Next :Over<CR>
nnoremenu WinBar.Finish :Finish<CR>
nnoremenu WinBar.Cont :Continue<CR>
nnoremenu WinBar.Stop :Stop<CR>
nnoremenu WinBar.Eval :Evaluate<CR>
- call add(s:winbar_winids, win_getid())
+ add(winbar_winids, win_getid())
endif
-endfunc
+enddef
-" Delete installed debugger commands in the current window.
-func s:DeleteCommands()
+# Delete installed debugger commands in the current window.
+def DeleteCommands()
delcommand Break
delcommand Tbreak
delcommand Clear
@@ -1089,334 +1232,347 @@ func s:DeleteCommands()
delcommand Var
delcommand Winbar
- if exists('s:k_map_saved')
- if !empty(s:k_map_saved) && !s:k_map_saved.buffer
- nunmap K
- call mapset(s:k_map_saved)
- elseif empty(s:k_map_saved)
+ if k_map_saved isnot null_dict
+ if !empty(k_map_saved) && k_map_saved.buffer
+ # pass
+ elseif !empty(k_map_saved) && !k_map_saved.buffer
nunmap K
+ mapset(k_map_saved)
+ elseif empty(k_map_saved)
+ silent! nunmap K
endif
- unlet s:k_map_saved
+ k_map_saved = null_dict
endif
- if exists('s:plus_map_saved')
- if !empty(s:plus_map_saved) && !s:plus_map_saved.buffer
- nunmap +
- call mapset(s:plus_map_saved)
- elseif empty(s:plus_map_saved)
+ if plus_map_saved isnot null_dict
+ if !empty(plus_map_saved) && plus_map_saved.buffer
+ # pass
+ elseif !empty(plus_map_saved) && !plus_map_saved.buffer
nunmap +
+ mapset(plus_map_saved)
+ elseif empty(plus_map_saved)
+ silent! nunmap +
endif
- unlet s:plus_map_saved
+ plus_map_saved = null_dict
endif
- if exists('s:minus_map_saved')
- if !empty(s:minus_map_saved) && !s:minus_map_saved.buffer
- nunmap -
- call mapset(s:minus_map_saved)
- elseif empty(s:minus_map_saved)
+ if minus_map_saved isnot null_dict
+ if !empty(minus_map_saved) && minus_map_saved.buffer
+ # pass
+ elseif !empty(minus_map_saved) && !minus_map_saved.buffer
nunmap -
+ mapset(minus_map_saved)
+ elseif empty(minus_map_saved)
+ silent! nunmap -
endif
- unlet s:minus_map_saved
+ minus_map_saved = null_dict
endif
if has('menu')
- " Remove the WinBar entries from all windows where it was added.
- let curwinid = win_getid()
- for winid in s:winbar_winids
+ # Remove the WinBar entries from all windows where it was added.
+ var curwinid = win_getid()
+ for winid in winbar_winids
if win_gotoid(winid)
- aunmenu WinBar.Step
- aunmenu WinBar.Next
- aunmenu WinBar.Finish
- aunmenu WinBar.Cont
- aunmenu WinBar.Stop
- aunmenu WinBar.Eval
+ aunmenu WinBar.Step
+ aunmenu WinBar.Next
+ aunmenu WinBar.Finish
+ aunmenu WinBar.Cont
+ aunmenu WinBar.Stop
+ aunmenu WinBar.Eval
endif
endfor
- call win_gotoid(curwinid)
- let s:winbar_winids = []
-
- if exists('s:saved_mousemodel')
- let &mousemodel = s:saved_mousemodel
- unlet s:saved_mousemodel
- aunmenu PopUp.-SEP3-
- aunmenu PopUp.Set\ breakpoint
- aunmenu PopUp.Clear\ breakpoint
- aunmenu PopUp.Run\ until
- aunmenu PopUp.Evaluate
+ win_gotoid(curwinid)
+ winbar_winids = []
+
+ if saved_mousemodel isnot null_string
+ &mousemodel = saved_mousemodel
+ saved_mousemodel = null_string
+ try
+ aunmenu PopUp.-SEP3-
+ aunmenu PopUp.Set\ breakpoint
+ aunmenu PopUp.Clear\ breakpoint
+ aunmenu PopUp.Run\ until
+ aunmenu PopUp.Evaluate
+ catch
+ # ignore any errors in removing the PopUp menu
+ endtry
endif
endif
- call sign_unplace('TermDebug')
- unlet s:breakpoints
- unlet s:breakpoint_locations
-
- call sign_undefine('debugPC')
- call sign_undefine(s:BreakpointSigns->map("'debugBreakpoint' .. v:val"))
- let s:BreakpointSigns = []
-endfunc
-
-" :Until - Execute until past a specified position or current line
-func s:Until(at)
- if s:stopped
- " reset s:stopped here, it may take a bit of time before we get a response
- let s:stopped = 0
- call ch_log('assume that program is running after this command')
- " Use the fname:lnum format
- let at = empty(a:at) ?
- \ fnameescape(expand('%:p')) . ':' . line('.') : a:at
- call s:SendCommand('-exec-until ' . at)
+ sign_unplace('TermDebug')
+ breakpoints = {}
+ breakpoint_locations = {}
+
+ sign_undefine('debugPC')
+ sign_undefine(BreakpointSigns->map("'debugBreakpoint' .. v:val"))
+ BreakpointSigns = []
+enddef
+
+
+# :Until - Execute until past a specified position or current line
+def Until(at: string)
+
+ if stopped
+ # reset stopped here, it may take a bit of time before we get a response
+ stopped = false
+ ch_log('assume that program is running after this command')
+
+ # Use the fname:lnum format
+ var AT = empty(at) ? $"{fnameescape(expand('%:p'))}:{line('.')}" : at
+ SendCommand($'-exec-until {AT}')
else
- call ch_log('dropping command, program is running: exec-until')
- endif
-endfunc
-
-" :Break - Set a breakpoint at the cursor position.
-func s:SetBreakpoint(at, tbreak=v:false)
- " Setting a breakpoint may not work while the program is running.
- " Interrupt to make it work.
- let do_continue = 0
- if !s:stopped
- let do_continue = 1
- Stop
+ ch_log('dropping command, program is running: exec-until')
+ endif
+enddef
+
+# :Break - Set a breakpoint at the cursor position.
+def SetBreakpoint(at: string, tbreak=false)
+ # Setting a breakpoint may not work while the program is running.
+ # Interrupt to make it work.
+ var do_continue = 0
+ if !stopped
+ do_continue = 1
+ StopCommand()
sleep 10m
endif
- " Use the fname:lnum format, older gdb can't handle --source.
- let at = empty(a:at) ?
- \ fnameescape(expand('%:p')) . ':' . line('.') : a:at
- if a:tbreak
- let cmd = '-break-insert -t ' . at
+ # Use the fname:lnum format, older gdb can't handle --source.
+ var AT = empty(at) ? $"{fnameescape(expand('%:p'))}:{line('.')}" : at
+ var cmd = ''
+ if tbreak
+ cmd = $'-break-insert -t {AT}'
else
- let cmd = '-break-insert ' . at
+ cmd = $'-break-insert {AT}'
endif
- call s:SendCommand(cmd)
+ # OK
+ # echom $"cmsd: {cmd}"
+ SendCommand(cmd)
if do_continue
- Continue
- endif
-endfunc
-
-" :Clear - Delete a breakpoint at the cursor position.
-func s:ClearBreakpoint()
- let fname = fnameescape(expand('%:p'))
- let lnum = line('.')
- let bploc = printf('%s:%d', fname, lnum)
- if has_key(s:breakpoint_locations, bploc)
- let idx = 0
- let nr = 0
- for id in s:breakpoint_locations[bploc]
- if has_key(s:breakpoints, id)
- " Assume this always works, the reply is simply "^done".
- call s:SendCommand('-break-delete ' . id)
- for subid in keys(s:breakpoints[id])
- call sign_unplace('TermDebug',
- \ #{id: s:Breakpoint2SignNumber(id, subid)})
+ ContinueCommand()
+ endif
+enddef
+
+def ClearBreakpoint()
+ var fname = fnameescape(expand('%:p'))
+ var lnum = line('.')
+ var bploc = printf('%s:%d', fname, lnum)
+ var nr = 0
+ if has_key(breakpoint_locations, bploc)
+ var idx = 0
+ for id in breakpoint_locations[bploc]
+ if has_key(breakpoints, id)
+ # Assume this always works, the reply is simply "^done".
+ SendCommand($'-break-delete {id}')
+ for subid in keys(breakpoints[id])
+ sign_unplace('TermDebug',
+ {id: Breakpoint2SignNumber(id, str2nr(subid))})
endfor
- unlet s:breakpoints[id]
- unlet s:breakpoint_locations[bploc][idx]
- let nr = id
+ remove(breakpoints, id)
+ remove(breakpoint_locations[bploc], idx)
+ nr = id
break
else
- let idx += 1
+ idx += 1
endif
endfor
+
if nr != 0
- if empty(s:breakpoint_locations[bploc])
- unlet s:breakpoint_locations[bploc]
+ if empty(breakpoint_locations[bploc])
+ remove(breakpoint_locations, bploc)
endif
- echomsg 'Breakpoint ' . id . ' cleared from line ' . lnum . '.'
+ echomsg $'Breakpoint {nr} cleared from line {lnum}.'
else
- call s:Echoerr('Internal error trying to remove breakpoint at line ' . lnum . '!')
+ Echoerr($'Internal error trying to remove breakpoint at line {lnum}!')
endif
else
- echomsg 'No breakpoint to remove at line ' . lnum . '.'
- endif
-endfunc
-
-func s:Run(args)
- if a:args != ''
- call s:SendResumingCommand('-exec-arguments ' . a:args)
- endif
- call s:SendResumingCommand('-exec-run')
-endfunc
-
-" :Frame - go to a specific frame in the stack
-func s:Frame(arg)
- " Note: we explicit do not use mi's command
- " call s:SendCommand('-stack-select-frame "' . a:arg .'"')
- " as we only get a "done" mi response and would have to open the file
- " 'manually' - using cli command "frame" provides us with the mi response
- " already parsed and allows for more formats
- if a:arg =~ '^\d\+$' || a:arg == ''
- " specify frame by number
- call s:SendCommand('-interpreter-exec mi "frame ' . a:arg .'"')
- elseif a:arg =~ '^0x[0-9a-fA-F]\+$'
- " specify frame by stack address
- call s:SendCommand('-interpreter-exec mi "frame address ' . a:arg .'"')
- else
- " specify frame by function name
- call s:SendCommand('-interpreter-exec mi "frame function ' . a:arg .'"')
- endif
-endfunc
-
-" :Up - go a:count frames in the stack "higher"
-func s:Up(count)
- " the 'correct' one would be -stack-select-frame N, but we don't know N
- call s:SendCommand($'-interpreter-exec console "up {a:count}"')
-endfunc
-
-" :Down - go a:count frames in the stack "below"
-func s:Down(count)
- " the 'correct' one would be -stack-select-frame N, but we don't know N
- call s:SendCommand($'-interpreter-exec console "down {a:count}"')
-endfunc
-
-func s:SendEval(expr)
- " check for "likely" boolean expressions, in which case we take it as lhs
- if a:expr =~ "[=!<>]="
- let exprLHS = a:expr
+ echomsg $'No breakpoint to remove at line {lnum}.'
+ endif
+enddef
+
+def Run(args: string)
+ if args != ''
+ SendResumingCommand($'-exec-arguments {args}')
+ endif
+ SendResumingCommand('-exec-run')
+enddef
+
+# :Frame - go to a specific frame in the stack
+def Frame(arg: string)
+ # Note: we explicit do not use mi's command
+ # call SendCommand('-stack-select-frame "' . arg .'"')
+ # as we only get a "done" mi response and would have to open the file
+ # 'manually' - using cli command "frame" provides us with the mi response
+ # already parsed and allows for more formats
+ if arg =~ '^\d\+$' || arg == ''
+ # specify frame by number
+ SendCommand($'-interpreter-exec mi "frame {arg}"')
+ elseif arg =~ '^0x[0-9a-fA-F]\+$'
+ # specify frame by stack address
+ SendCommand($'-interpreter-exec mi "frame address {arg}"')
else
- " remove text that is likely an assignment
- let exprLHS = substitute(a:expr, ' *=.*', '', '')
- endif
-
- " encoding expression to prevent bad errors
- let expr = a:expr
- let expr = substitute(expr, '\\', '\\\\', 'g')
- let expr = substitute(expr, '"', '\\"', 'g')
- call s:SendCommand('-data-evaluate-expression "' . expr . '"')
- let s:evalexpr = exprLHS
-endfunc
-
-" :Evaluate - evaluate what is specified / under the cursor
-func s:Evaluate(range, arg)
- let expr = s:GetEvaluationExpression(a:range, a:arg)
- let s:ignoreEvalError = 0
- call s:SendEval(expr)
-endfunc
-
-" get what is specified / under the cursor
-func s:GetEvaluationExpression(range, arg)
- if a:arg != ''
- " user supplied evaluation
- let expr = s:CleanupExpr(a:arg)
- " DSW: replace "likely copy + paste" assignment
- let expr = substitute(expr, '"\([^"]*\)": *', '\1=', 'g')
- elseif a:range == 2
- " no evaluation but provided but range set
- let pos = getcurpos()
- let reg = getreg('v', 1, 1)
- let regt = getregtype('v')
+ # specify frame by function name
+ SendCommand($'-interpreter-exec mi "frame function {arg}"')
+ endif
+enddef
+
+# :Up - go count frames in the stack "higher"
+def Up(count: number)
+ # the 'correct' one would be -stack-select-frame N, but we don't know N
+ SendCommand($'-interpreter-exec console "up {count}"')
+enddef
+
+# :Down - go count frames in the stack "below"
+def Down(count: number)
+ # the 'correct' one would be -stack-select-frame N, but we don't know N
+ SendCommand($'-interpreter-exec console "down {count}"')
+enddef
+
+def SendEval(expr: string)
+ # check for "likely" boolean expressions, in which case we take it as lhs
+ var exprLHS = substitute(expr, ' *=.*', '', '')
+ if expr =~ "[=!<>]="
+ exprLHS = expr
+ endif
+
+ # encoding expression to prevent bad errors
+ var expr_escaped = expr
+ ->substitute('\\', '\\\\', 'g')
+ ->substitute('"', '\\"', 'g')
+ SendCommand($'-data-evaluate-expression "{expr_escaped}"')
+ evalexpr = exprLHS
+enddef
+
+# :Evaluate - evaluate what is specified / under the cursor
+def Evaluate(range: number, arg: string)
+ var expr = GetEvaluationExpression(range, arg)
+ echom $"expr: {expr}"
+ ignoreEvalError = false
+ SendEval(expr)
+enddef
+
+
+# get what is specified / under the cursor
+def GetEvaluationExpression(range: number, arg: string): string
+ var expr = ''
+ if arg != ''
+ # user supplied evaluation
+ expr = CleanupExpr(arg)
+ # DSW: replace "likely copy + paste" assignment
+ expr = substitute(expr, '"\([^"]*\)": *', '\1=', 'g')
+ elseif range == 2
+ # no evaluation but provided but range set
+ var pos = getcurpos()
+ var regst = getreg('v', 1, 1)
+ var regt = getregtype('v')
normal! gv"vy
- let expr = s:CleanupExpr(@v)
- call setpos('.', pos)
- call setreg('v', reg, regt)
+ expr = CleanupExpr(@v)
+ setpos('.', pos)
+ setreg('v', regst, regt)
else
- " no evaluation provided: get from C-expression under cursor
- " TODO: allow filetype specific lookup #9057
- let expr = expand('<cexpr>')
+ # no evaluation provided: get from C-expression under cursor
+ # TODO: allow filetype specific lookup #9057
+ expr = expand('<cexpr>')
endif
return expr
-endfunc
+enddef
-" clean up expression that may get in because of range
-" (newlines and surrounding whitespace)
-" As it can also be specified via ex-command for assignments this function
-" may not change the "content" parts (like replacing contained spaces)
-func s:CleanupExpr(expr)
- " replace all embedded newlines/tabs/...
- let expr = substitute(a:expr, '\_s', ' ', 'g')
+# clean up expression that may get in because of range
+# (newlines and surrounding whitespace)
+# As it can also be specified via ex-command for assignments this function
+# may not change the "content" parts (like replacing contained spaces)
+def CleanupExpr(passed_expr: string): string
+ # replace all embedded newlines/tabs/...
+ var expr = substitute(passed_expr, '\_s', ' ', 'g')
if &filetype ==# 'cobol'
- " extra cleanup for COBOL:
- " - a semicolon nmay be used instead of a space
- " - a trailing comma or period is ignored as it commonly separates/ends
- " multiple expr
- let expr = substitute(expr, ';', ' ', 'g')
- let expr = substitute(expr, '[,.]\+ *$', '', '')
+ # extra cleanup for COBOL:
+ # - a semicolon nmay be used instead of a space
+ # - a trailing comma or period is ignored as it commonly separates/ends
+ # multiple expr
+ expr = substitute(expr, ';', ' ', 'g')
+ expr = substitute(expr, '[,.]\+ *$', '', '')
endif
- " get rid of leading and trailing spaces
- let expr = substitute(expr, '^ *', '', '')
- let expr = substitute(expr, ' *$', '', '')
+ # get rid of leading and trailing spaces
+ expr = substitute(expr, '^ *', '', '')
+ expr = substitute(expr, ' *$', '', '')
return expr
-endfunc
-
-let s:ignoreEvalError = 0
-let s:evalFromBalloonExpr = 0
-
-" Handle the result of data-evaluate-expression
-func s:HandleEvaluate(msg)
- let value = a:msg
- \ ->substitute('.*value="\(.*\)"', '\1', '')
- \ ->substitute('\\"', '"', 'g')
- \ ->substitute('\\\\', '\\', 'g')
- "\ multi-byte characters arrive in octal form, replace everything but NULL values
- \ ->substitute('\\000', s:NullRepl, 'g')
- \ ->substitute('\\\o\o\o', {-> eval('"' .. submatch(0) .. '"')}, 'g')
- "\ Note: GDB docs also mention hex encodings - the translations below work
- "\ but we keep them out for performance-reasons until we actually see
- "\ those in mi-returns
- "\ ->substitute('\\0x00', s:NullRep, 'g')
- "\ ->substitute('\\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. '"')}, 'g')
- \ ->substitute(s:NullRepl, '\\000', 'g')
- if s:evalFromBalloonExpr
- if s:evalFromBalloonExprResult == ''
- let s:evalFromBalloonExprResult = s:evalexpr . ': ' . value
+enddef
+
+def HandleEvaluate(msg: string)
+ var value = msg
+ ->substitute('.*value="\(.*\)"', '\1', '')
+ ->substitute('\\"', '"', 'g')
+ ->substitute('\\\\', '\\', 'g')
+ #\ multi-byte characters arrive in octal form, replace everything but NULL values
+ ->substitute('\\000', NullRepl, 'g')
+ ->substitute('\\\(\o\o\o\)', (m) => nr2char(str2nr(m[1], 8)), 'g')
+ #\ Note: GDB docs also mention hex encodings - the translations below work
+ #\ but we keep them out for performance-reasons until we actually see
+ #\ those in mi-returns
+ #\ ->substitute('\\0x00', NullRep, 'g')
+ #\ ->substitute('\\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. '"')}, 'g')
+ ->substitute(NullRepl, '\\000', 'g')
+ if evalFromBalloonExpr
+ if empty(evalFromBalloonExprResult)
+ evalFromBalloonExprResult = $'{evalexpr}: {value}'
else
- let s:evalFromBalloonExprResult .= ' = ' . value
+ evalFromBalloonExprResult ..= $' = {value}'
endif
- call balloon_show(s:evalFromBalloonExprResult)
+ balloon_show(evalFromBalloonExprResult)
else
- echomsg '"' . s:evalexpr . '": ' . value
+ echomsg $'"{evalexpr}": {value}'
endif
- if s:evalexpr[0] != '*' && value =~ '^0x' && value != '0x0' && value !~ '"$'
- " Looks like a pointer, also display what it points to.
- let s:ignoreEvalError = 1
- call s:SendEval('*' . s:evalexpr)
+ if evalexpr[0] != '*' && value =~ '^0x' && value != '0x0' && value !~ '"$'
+ # Looks like a pointer, also display what it points to.
+ ignoreEvalError = true
+ SendEval($'*{evalexpr}')
else
- let s:evalFromBalloonExpr = 0
+ evalFromBalloonExpr = false
endif
-endfunc
+enddef
-" Show a balloon with information of the variable under the mouse pointer,
-" if there is any.
-func TermDebugBalloonExpr()
- if v:beval_winid != s:sourcewin
+
+# Show a balloon with information of the variable under the mouse pointer,
+# if there is any.
+def TermDebugBalloonExpr(): string
+ if v:beval_winid != sourcewin
return ''
endif
- if !s:stopped
- " Only evaluate when stopped, otherwise setting a breakpoint using the
- " mouse triggers a balloon.
+ if !stopped
+ # Only evaluate when stopped, otherwise setting a breakpoint using the
+ # mouse triggers a balloon.
return ''
endif
- let s:evalFromBalloonExpr = 1
- let s:evalFromBalloonExprResult = ''
- let s:ignoreEvalError = 1
- let expr = s:CleanupExpr(v:beval_text)
- call s:SendEval(expr)
+ evalFromBalloonExpr = true
+ evalFromBalloonExprResult = ''
+ ignoreEvalError = true
+ var expr = CleanupExpr(v:beval_text)
+ SendEval(expr)
return ''
-endfunc
-
-" Handle an error.
-func s:HandleError(msg)
- if s:ignoreEvalError
- " Result of s:SendEval() failed, ignore.
- let s:ignoreEvalError = 0
- let s:evalFromBalloonExpr = 0
+enddef
+
+# Handle an error.
+def HandleError(msg: string)
+ if ignoreEvalError
+ # Result of SendEval() failed, ignore.
+ ignoreEvalError = false
+ evalFromBalloonExpr = true
return
endif
- let msgVal = substitute(a:msg, '.*msg="\(.*\)"', '\1', '')
- call s:Echoerr(substitute(msgVal, '\\"', '"', 'g'))
-endfunc
+ var msgVal = substitute(msg, '.*msg="\(.*\)"', '\1', '')
+ Echoerr(substitute(msgVal, '\\"', '"', 'g'))
+enddef
-func s:GotoSourcewinOrCreateIt()
- if !win_gotoid(s:sourcewin)
+def GotoSourcewinOrCreateIt()
+ if !win_gotoid(sourcewin)
new
- let s:sourcewin = win_getid()
- call s:InstallWinbar(0)
+ sourcewin = win_getid()
+ InstallWinbar(0)
endif
-endfunc
+enddef
+
-func s:GetDisasmWindow()
+def GetDisasmWindow(): number
if exists('g:termdebug_config')
return get(g:termdebug_config, 'disasm_window', 0)
endif
@@ -1424,9 +1580,9 @@ func s:GetDisasmWindow()
return g:termdebug_disasm_window
endif
return 0
-endfunc
+enddef
-func s:GetDisasmWindowHeight()
+def GetDisasmWindowHeight(): number
if exists('g:termdebug_config')
return get(g:termdebug_config, 'disasm_window_height', 0)
endif
@@ -1434,16 +1590,16 @@ func s:GetDisasmWindowHeight()
return g:termdebug_disasm_window
endif
return 0
-endfunc
+enddef
-func s:GotoAsmwinOrCreateIt()
- if !win_gotoid(s:asmwin)
- let mdf = ''
- if win_gotoid(s:sourcewin)
- " 60 is approx spaceBuffer * 3
+def GotoAsmwinOrCreateIt()
+ var mdf = ''
+ if !win_gotoid(asmwin)
+ if win_gotoid(sourcewin)
+ # 60 is approx spaceBuffer * 3
if winwidth(0) > (78 + 60)
- let mdf = 'vert'
- exe mdf .. ' ' .. 60 .. 'new'
+ mdf = 'vert'
+ exe $'{mdf} :60new'
else
exe 'rightbelow new'
endif
@@ -1451,7 +1607,7 @@ func s:GotoAsmwinOrCreateIt()
exe 'new'
endif
- let s:asmwin = win_getid()
+ asmwin = win_getid()
setlocal nowrap
setlocal number
@@ -1461,32 +1617,36 @@ func s:GotoAsmwinOrCreateIt()
setlocal signcolumn=no
setlocal modifiable
- if s:asmbuf > 0 && bufexists(s:asmbuf)
- exe 'buffer' . s:asmbuf
- else
+ if asmbufnr > 0 && bufexists(asmbufnr)
+ exe $'buffer {asmbufnr}'
+ elseif empty(glob('Termdebug-asm-listing'))
silent file Termdebug-asm-listing
- let s:asmbuf = bufnr('Termdebug-asm-listing')
+ asmbufnr = bufnr('Termdebug-asm-listing')
+ else
+ Echoerr("You have a file/folder named 'Termdebug-asm-listing'. " ..
+ "Please exit and rename it because Termdebug may not work " ..
+ "as expected.")
endif
- if mdf != 'vert' && s:GetDisasmWindowHeight() > 0
- exe 'resize ' .. s:GetDisasmWindowHeight()
+ if mdf != 'vert' && GetDisasmWindowHeight() > 0
+ exe $'resize {GetDisasmWindowHeight()}'
endif
endif
- if s:asm_addr != ''
- let lnum = search('^' . s:asm_addr)
+ if asm_addr != ''
+ var lnum = search($'^{asm_addr}')
if lnum == 0
- if s:stopped
- call s:SendCommand('disassemble $pc')
+ if stopped
+ SendCommand('disassemble $pc')
endif
else
- call sign_unplace('TermDebug', #{id: s:asm_id})
- call sign_place(s:asm_id, 'TermDebug', 'debugPC', '%', #{lnum: lnum})
+ sign_unplace('TermDebug', {id: asm_id})
+ sign_place(asm_id, 'TermDebug', 'debugPC', '%', {lnum: lnum})
endif
endif
-endfunc
+enddef
-func s:GetVariablesWindow()
+def GetVariablesWindow(): number
if exists('g:termdebug_config')
return get(g:termdebug_config, 'variables_window', 0)
endif
@@ -1494,9 +1654,9 @@ func s:GetVariablesWindow()
return g:termdebug_variables_window
endif
return 0
-endfunc
+enddef
-func s:GetVariablesWindowHeight()
+def GetVariablesWindowHeight(): number
if exists('g:termdebug_config')
return get(g:termdebug_config, 'variables_window_height', 0)
endif
@@ -1504,16 +1664,17 @@ func s:GetVariablesWindowHeight()
return g:termdebug_variables_window
endif
return 0
-endfunc
+enddef
+
-func s:GotoVariableswinOrCreateIt()
- if !win_gotoid(s:varwin)
- let mdf = ''
- if win_gotoid(s:sourcewin)
- " 60 is approx spaceBuffer * 3
+def GotoVariableswinOrCreateIt()
+ var mdf = ''
+ if !win_gotoid(varwin)
+ if win_gotoid(sourcewin)
+ # 60 is approx spaceBuffer * 3
if winwidth(0) > (78 + 60)
- let mdf = 'vert'
- exe mdf .. ' ' .. 60 .. 'new'
+ mdf = 'vert'
+ exe $'{mdf} :60new'
else
exe 'rightbelow new'
endif
@@ -1521,7 +1682,7 @@ func s:GotoVariableswinOrCreateIt()
exe 'new'
endif
- let s:varwin = win_getid()
+ varwin = win_getid()
setlocal nowrap
setlocal noswapfile
@@ -1530,281 +1691,289 @@ func s:GotoVariableswinOrCreateIt()
setlocal signcolumn=no
setlocal modifiable
- if s:varbuf > 0 && bufexists(s:varbuf)
- exe 'buffer' . s:varbuf
- else
+ if varbufnr > 0 && bufexists(varbufnr)
+ exe $'buffer {varbufnr}'
+ elseif empty(glob('Termdebug-variables-listing'))
silent file Termdebug-variables-listing
- let s:varbuf = bufnr('Termdebug-variables-listing')
+ varbufnr = bufnr('Termdebug-variables-listing')
+ else
+ Echoerr("You have a file/folder named 'Termdebug-variables-listing'. " ..
+ "Please exit and rename it because Termdebug may not work " ..
+ "as expected.")
endif
- if mdf != 'vert' && s:GetVariablesWindowHeight() > 0
- exe 'resize ' .. s:GetVariablesWindowHeight()
+ if mdf != 'vert' && GetVariablesWindowHeight() > 0
+ exe $'resize {GetVariablesWindowHeight()}'
endif
endif
- if s:running
- call s:SendCommand('-stack-list-variables 2')
+ if running
+ SendCommand('-stack-list-variables 2')
endif
-endfunc
+enddef
-" Handle stopping and running message from gdb.
-" Will update the sign that shows the current position.
-func s:HandleCursor(msg)
- let wid = win_getid()
+# Handle stopping and running message from gdb.
+# Will update the sign that shows the current position.
+def HandleCursor(msg: string)
+ var wid = win_getid()
- if a:msg =~ '^\*stopped'
- call ch_log('program stopped')
- let s:stopped = 1
- if a:msg =~ '^\*stopped,reason="exited-normally"'
- let s:running = 0
+ if msg =~ '^\*stopped'
+ ch_log('program stopped')
+ stopped = 1
+ if msg =~ '^\*stopped,reason="exited-normally"'
+ running = false
endif
- elseif a:msg =~ '^\*running'
- call ch_log('program running')
- let s:stopped = 0
- let s:running = 1
+ elseif msg =~ '^\*running'
+ ch_log('program running')
+ stopped = false
+ running = true
endif
- if a:msg =~ 'fullname='
- let fname = s:GetFullname(a:msg)
- else
- let fname = ''
+ var fname = ''
+ if msg =~ 'fullname='
+ fname = GetFullname(msg)
endif
- if a:msg =~ 'addr='
- let asm_addr = s:GetAsmAddr(a:msg)
- if asm_addr != ''
- let s:asm_addr = asm_addr
+ if msg =~ 'addr='
+ var asm_addr_local = GetAsmAddr(msg)
+ if asm_addr_local != ''
+ asm_addr = asm_addr_local
- let curwinid = win_getid()
- if win_gotoid(s:asmwin)
- let lnum = search('^' . s:asm_addr)
+ var curwinid = win_getid()
+ var lnum = 0
+ if win_gotoid(asmwin)
+ lnum = search($'^{asm_addr}')
if lnum == 0
- call s:SendCommand('disassemble $pc')
+ SendCommand('disassemble $pc')
else
- call sign_unplace('TermDebug', #{id: s:asm_id})
- call sign_place(s:asm_id, 'TermDebug', 'debugPC', '%', #{lnum: lnum})
+ sign_unplace('TermDebug', {id: asm_id})
+ sign_place(asm_id, 'TermDebug', 'debugPC', '%', {lnum: lnum})
endif
- call win_gotoid(curwinid)
+ win_gotoid(curwinid)
endif
endif
endif
- if s:running && s:stopped && bufwinnr('Termdebug-variables-listing') != -1
- call s:SendCommand('-stack-list-variables 2')
+ if running && stopped && bufwinnr(varbufname) != -1
+ SendCommand('-stack-list-variables 2')
endif
- if a:msg =~ '^\(\*stopped\|=thread-selected\)' && filereadable(fname)
- let lnum = substitute(a:msg, '.*line="\([^"]*\)".*', '\1', '')
+ if msg =~ '^\(\*stopped\|=thread-selected\)' && filereadable(fname)
+ var lnum = substitute(msg, '.*line="\([^"]*\)".*', '\1', '')
if lnum =~ '^[0-9]*$'
- call s:GotoSourcewinOrCreateIt()
+ GotoSourcewinOrCreateIt()
if expand('%:p') != fnamemodify(fname, ':p')
- echomsg 'different fname: "' .. expand('%:p') .. '" vs "' .. fnamemodify(fname, ':p') .. '"'
+ echomsg $"different fname: '{expand('%:p')}' vs '{fnamemodify(fname, ':p')}'"
augroup Termdebug
- " Always open a file read-only instead of showing the ATTENTION
- " prompt, since it is unlikely we want to edit the file.
- " The file may be changed but not saved, warn for that.
+ # Always open a file read-only instead of showing the ATTENTION
+ # prompt, since it is unlikely we want to edit the file.
+ # The file may be changed but not saved, warn for that.
au SwapExists * echohl WarningMsg
- \ | echo 'Warning: file is being edited elsewhere'
- \ | echohl None
- \ | let v:swapchoice = 'o'
+ | echo 'Warning: file is being edited elsewhere'
+ | echohl None
+ | v:swapchoice = 'o'
augroup END
if &modified
- " TODO: find existing window
- exe 'split ' . fnameescape(fname)
- let s:sourcewin = win_getid()
- call s:InstallWinbar(0)
+ # TODO: find existing window
+ exe $'split {fnameescape(fname)}'
+ sourcewin = win_getid()
+ InstallWinbar(0)
else
- exe 'edit ' . fnameescape(fname)
+ exe $'edit {fnameescape(fname)}'
endif
augroup Termdebug
au! SwapExists
augroup END
endif
- exe lnum
+ exe $":{lnum}"
normal! zv
- call sign_unplace('TermDebug', #{id: s:pc_id})
- call sign_place(s:pc_id, 'TermDebug', 'debugPC', fname,
- \ #{lnum: lnum, priority: 110})
+ sign_unplace('TermDebug', {id: pc_id})
+ sign_place(pc_id, 'TermDebug', 'debugPC', fname,
+ {lnum: str2nr(lnum), priority: 110})
if !exists('b:save_signcolumn')
- let b:save_signcolumn = &signcolumn
- call add(s:signcolumn_buflist, bufnr())
+ b:save_signcolumn = &signcolumn
+ add(signcolumn_buflist, bufnr())
endif
setlocal signcolumn=yes
endif
- elseif !s:stopped || fname != ''
- call sign_unplace('TermDebug', #{id: s:pc_id})
+ elseif !stopped || fname != ''
+ sign_unplace('TermDebug', {id: pc_id})
endif
- call win_gotoid(wid)
-endfunc
-
-let s:BreakpointSigns = []
+ win_gotoid(wid)
+enddef
-func s:CreateBreakpoint(id, subid, enabled)
- let nr = printf('%d.%d', a:id, a:subid)
- if index(s:BreakpointSigns, nr) == -1
- call add(s:BreakpointSigns, nr)
- if a:enabled == "n"
- let hiName = "debugBreakpointDisabled"
+# Create breakpoint sign
+def CreateBreakpoint(id: number, subid: number, enabled: string)
+ var nr = printf('%d.%d', id, subid)
+ if index(BreakpointSigns, nr) == -1
+ add(BreakpointSigns, nr)
+ var hiName = ''
+ if enabled == "n"
+ hiName = "debugBreakpointDisabled"
else
- let hiName = "debugBreakpoint"
+ hiName = "debugBreakpoint"
endif
- let label = ''
- if exists('g:termdebug_config')
- let label = get(g:termdebug_config, 'sign', '')
- endif
- if label == ''
- let label = printf('%02X', a:id)
- if a:id > 255
- let label = 'F+'
+ var label = ''
+ if exists('g:termdebug_config') && has_key(g:termdebug_config, 'sign')
+ label = g:termdebug_config['sign']
+ else
+ label = printf('%02X', id)
+ if id > 255
+ label = 'F+'
endif
endif
- call sign_define('debugBreakpoint' .. nr,
- \ #{text: slice(label, 0, 2),
- \ texthl: hiName})
- endif
-endfunc
-
-func! s:SplitMsg(s)
- return split(a:s, '{.\{-}}\zs')
-endfunction
-
-" Handle setting a breakpoint
-" Will update the sign that shows the breakpoint
-func s:HandleNewBreakpoint(msg, modifiedFlag)
- if a:msg !~ 'fullname='
- " a watch or a pending breakpoint does not have a file name
- if a:msg =~ 'pending='
- let nr = substitute(a:msg, '.*number=\"\([0-9.]*\)\".*', '\1', '')
- let target = substitute(a:msg, '.*pending=\"\([^"]*\)\".*', '\1', '')
- echomsg 'Breakpoint ' . nr . ' (' . target . ') pending.'
+ sign_define($'debugBreakpoint{nr}',
+ {text: slice(label, 0, 2),
+ texthl: hiName})
+ endif
+enddef
+
+def SplitMsg(str: string): list<string>
+ return split(str, '{.\{-}}\zs')
+enddef
+
+
+# Handle setting a breakpoint
+# Will update the sign that shows the breakpoint
+def HandleNewBreakpoint(msg: string, modifiedFlag: any)
+ var nr = ''
+
+ if msg !~ 'fullname='
+ # a watch or a pending breakpoint does not have a file name
+ if msg =~ 'pending='
+ nr = substitute(msg, '.*number=\"\([0-9.]*\)\".*', '\1', '')
+ var target = substitute(msg, '.*pending=\"\([^"]*\)\".*', '\1', '')
+ echomsg $'Breakpoint {nr} ({target}) pending.'
endif
return
endif
- for msg in s:SplitMsg(a:msg)
- let fname = s:GetFullname(msg)
+
+ for mm in SplitMsg(msg)
+ var fname = GetFullname(mm)
if empty(fname)
continue
endif
- let nr = substitute(msg, '.*number="\([0-9.]*\)\".*', '\1', '')
+ nr = substitute(mm, '.*number="\([0-9.]*\)\".*', '\1', '')
if empty(nr)
return
endif
- " If "nr" is 123 it becomes "123.0" and subid is "0".
- " If "nr" is 123.4 it becomes "123.4.0" and subid is "4"; "0" is discarded.
- let [id, subid; _] = map(split(nr . '.0', '\.'), 'v:val + 0')
- let enabled = substitute(msg, '.*enabled="\([yn]\)".*', '\1', '')
- call s:CreateBreakpoint(id, subid, enabled)
-
- if has_key(s:breakpoints, id)
- let entries = s:breakpoints[id]
+ # If "nr" is 123 it becomes "123.0" and subid is "0".
+ # If "nr" is 123.4 it becomes "123.4.0" and subid is "4"; "0" is discarded.
+ var [id, subid; _] = map(split(nr .. '.0', '\.'), 'str2nr(v:val) + 0')
+ # var [id, subid; _] = map(split(nr .. '.0', '\.'), 'v:val + 0')
+ var enabled = substitute(mm, '.*enabled="\([yn]\)".*', '\1', '')
+ CreateBreakpoint(id, subid, enabled)
+
+ var entries = {}
+ var entry = {}
+ if has_key(breakpoints, id)
+ entries = breakpoints[id]
else
- let entries = {}
- let s:breakpoints[id] = entries
+ breakpoints[id] = entries
endif
if has_key(entries, subid)
- let entry = entries[subid]
+ entry = entries[subid]
else
- let entry = {}
- let entries[subid] = entry
+ entries[subid] = entry
endif
- let lnum = substitute(msg, '.*line="\([^"]*\)".*', '\1', '')
- let entry['fname'] = fname
- let entry['lnum'] = lnum
+ var lnum = str2nr(substitute(mm, '.*line="\([^"]*\)".*', '\1', ''))
+ entry['fname'] = fname
+ entry['lnum'] = lnum
- let bploc = printf('%s:%d', fname, lnum)
- if !has_key(s:breakpoint_locations, bploc)
- let s:breakpoint_locations[bploc] = []
+ var bploc = printf('%s:%d', fname, lnum)
+ if !has_key(breakpoint_locations, bploc)
+ breakpoint_locations[bploc] = []
endif
- let s:breakpoint_locations[bploc] += [id]
+ breakpoint_locations[bploc] += [id]
+ var posMsg = ''
if bufloaded(fname)
- call s:PlaceSign(id, subid, entry)
- let posMsg = ' at line ' . lnum . '.'
+ PlaceSign(id, subid, entry)
+ posMsg = $' at line {lnum}.'
else
- let posMsg = ' in ' . fname . ' at line ' . lnum . '.'
+ posMsg = $' in {fname} at line {lnum}.'
endif
- if !a:modifiedFlag
- let actionTaken = 'created'
+ var actionTaken = ''
+ if !modifiedFlag
+ actionTaken = 'created'
elseif enabled == 'n'
- let actionTaken = 'disabled'
+ actionTaken = 'disabled'
else
- let actionTaken = 'enabled'
+ actionTaken = 'enabled'
endif
- echomsg 'Breakpoint ' . nr . ' ' . actionTaken . posMsg
+ echom $'Breakpoint {nr} {actionTaken}{posMsg}'
endfor
-endfunc
-
-func s:PlaceSign(id, subid, entry)
- let nr = printf('%d.%d', a:id, a:subid)
- call sign_place(s:Breakpoint2SignNumber(a:id, a:subid), 'TermDebug',
- \ 'debugBreakpoint' .. nr, a:entry['fname'],
- \ #{lnum: a:entry['lnum'], priority: 110})
- let a:entry['placed'] = 1
-endfunc
-
-" Handle deleting a breakpoint
-" Will remove the sign that shows the breakpoint
-func s:HandleBreakpointDelete(msg)
- let id = substitute(a:msg, '.*id="\([0-9]*\)\".*', '\1', '') + 0
+enddef
+
+
+def PlaceSign(id: number, subid: number, entry: dict<any>)
+ var nr = printf('%d.%d', id, subid)
+ sign_place(Breakpoint2SignNumber(id, subid), 'TermDebug',
+ $'debugBreakpoint{nr}', entry['fname'],
+ {lnum: entry['lnum'], priority: 110})
+ entry['placed'] = 1
+enddef
+
+# Handle deleting a breakpoint
+# Will remove the sign that shows the breakpoint
+def HandleBreakpointDelete(msg: string)
+ var id = substitute(msg, '.*id="\([0-9]*\)\".*', '\1', '')
if empty(id)
return
endif
- if has_key(s:breakpoints, id)
- for [subid, entry] in items(s:breakpoints[id])
+ if has_key(breakpoints, id)
+ for [subid, entry] in items(breakpoints[id])
if has_key(entry, 'placed')
- call sign_unplace('TermDebug',
- \ #{id: s:Breakpoint2SignNumber(id, subid)})
- unlet entry['placed']
+ sign_unplace('TermDebug',
+ {id: Breakpoint2SignNumber(str2nr(id), str2nr(subid))})
+ remove(entry, 'placed')
endif
endfor
- unlet s:breakpoints[id]
- echomsg 'Breakpoint ' . id . ' cleared.'
+ remove(breakpoints, id)
+ echomsg $'Breakpoint {id} cleared.'
endif
-endfunc
+enddef
-" Handle the debugged program starting to run.
-" Will store the process ID in s:pid
-func s:HandleProgramRun(msg)
- let nr = substitute(a:msg, '.*pid="\([0-9]*\)\".*', '\1', '') + 0
+# Handle the debugged program starting to run.
+# Will store the process ID in pid
+def HandleProgramRun(msg: string)
+ var nr = str2nr(substitute(msg, '.*pid="\([0-9]*\)\".*', '\1', ''))
if nr == 0
return
endif
- let s:pid = nr
- call ch_log('Detected process ID: ' . s:pid)
-endfunc
+ pid = nr
+ ch_log($'Detected process ID: {pid}')
+enddef
-" Handle a BufRead autocommand event: place any signs.
-func s:BufRead()
- let fname = expand('<afile>:p')
- for [id, entries] in items(s:breakpoints)
+# Handle a BufRead autocommand event: place any signs.
+def BufRead()
+ var fname = expand('<afile>:p')
+ for [id, entries] in items(breakpoints)
for [subid, entry] in items(entries)
if entry['fname'] == fname
- call s:PlaceSign(id, subid, entry)
+ PlaceSign(str2nr(id), str2nr(subid), entry)
endif
endfor
endfor
-endfunc
+enddef
-" Handle a BufUnloaded autocommand event: unplace any signs.
-func s:BufUnloaded()
- let fname = expand('<afile>:p')
- for [id, entries] in items(s:breakpoints)
+# Handle a BufUnloaded autocommand event: unplace any signs.
+def BufUnloaded()
+ var fname = expand('<afile>:p')
+ for [id, entries] in items(breakpoints)
for [subid, entry] in items(entries)
if entry['fname'] == fname
- let entry['placed'] = 0
+ entry['placed'] = 0
endif
endfor
endfor
-endfunc
-
-call s:InitHighlight()
-call s:InitAutocmd()
+enddef
-let &cpo = s:keepcpo
-unlet s:keepcpo
+InitHighlight()
+InitAutocmd()
-" vim: sw=2 sts=2 et
+# vim: sw=2 sts=2 et
diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim
index 96c54ee..6c061c9 100644
--- a/runtime/plugin/matchparen.vim
+++ b/runtime/plugin/matchparen.vim
@@ -1,6 +1,6 @@
" Vim plugin for showing matching parens
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2023 Oct 20
+" Last Change: 2024 May 18
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" Exit quickly when:
@@ -218,7 +218,7 @@ command NoMatchParen call s:NoMatchParen()
func s:NoMatchParen()
let w = winnr()
- noau windo silent! call matchdelete(3)
+ noau windo call s:Remove_Matches()
unlet! g:loaded_matchparen
exe "noau ". w . "wincmd w"
au! matchparen
diff --git a/runtime/plugin/netrwPlugin.vim b/runtime/plugin/netrwPlugin.vim
index ed6f7dc..c70e651 100644
--- a/runtime/plugin/netrwPlugin.vim
+++ b/runtime/plugin/netrwPlugin.vim
@@ -2,6 +2,8 @@
" PLUGIN SECTION
" Maintainer: This runtime file is looking for a new maintainer.
" Date: Feb 09, 2021
+" Last Change:
+" 2024 May 08 by Vim Project: cleanup legacy Win9X checks
" Former Maintainer: Charles E Campbell
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
" Copyright: Copyright (C) 1999-2021 Charles E. Campbell {{{1
@@ -35,7 +37,7 @@ augroup FileExplorer
au BufLeave * if &ft != "netrw"|let w:netrw_prvfile= expand("%:p")|endif
au BufEnter * sil call s:LocalBrowse(expand("<amatch>"))
au VimEnter * sil call s:VimEnter(expand("<amatch>"))
- if has("win32") || has("win95") || has("win64") || has("win16")
+ if has("win32")
au BufEnter .* sil call s:LocalBrowse(expand("<amatch>"))
endif
augroup END
diff --git a/runtime/syntax/cpp.vim b/runtime/syntax/cpp.vim
index 8daf90a..ff1226b 100644
--- a/runtime/syntax/cpp.vim
+++ b/runtime/syntax/cpp.vim
@@ -2,7 +2,8 @@
" Language: C++
" Current Maintainer: vim-jp (https://github.com/vim-jp/vim-cpp)
" Previous Maintainer: Ken Shan <ccshan@post.harvard.edu>
-" Last Change: 2023 Dec 08
+" Last Change: 2024 May 04
+" 2024 May 04 by Vim Project (fix digit separator in octals and floats)
" quit when a syntax file was already loaded
if exists("b:current_syntax")
@@ -55,11 +56,11 @@ if !exists("cpp_no_cpp14")
syn match cppNumbers display transparent "\<\d\|\.\d" contains=cppNumber,cppFloat
syn match cppNumber display contained "\<0\([Uu]\=\([Ll]\|LL\|ll\)\|\([Ll]\|LL\|ll\)\=[Uu]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
syn match cppNumber display contained "\<[1-9]\('\=\d\+\)*\([Uu]\=\([Ll]\|LL\|ll\)\|\([Ll]\|LL\|ll\)\=[Uu]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
- syn match cppNumber display contained "\<0\o\+\([Uu]\=\([Ll]\|LL\|ll\)\|\([Ll]\|LL\|ll\)\=[Uu]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
+ syn match cppNumber display contained "\<0\('\=\o\+\)\+\([Uu]\=\([Ll]\|LL\|ll\)\|\([Ll]\|LL\|ll\)\=[Uu]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
syn match cppNumber display contained "\<0b[01]\('\=[01]\+\)*\([Uu]\=\([Ll]\|LL\|ll\)\|\([Ll]\|LL\|ll\)\=[Uu]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
syn match cppNumber display contained "\<0x\x\('\=\x\+\)*\([Uu]\=\([Ll]\|LL\|ll\)\|\([Ll]\|LL\|ll\)\=[Uu]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
- syn match cppFloat display contained "\<\d\+\.\d*\(e[-+]\=\d\+\)\=\([FfLl]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
- syn match cppFloat display contained "\<\.\d\+\(e[-+]\=\d\+\)\=\([FfLl]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
+ syn match cppFloat display contained "\<\d\('\=\d\+\)*\.\(\d\('\=\d\+\)*\)\=\(e[-+]\=\d\+\)\=\([FfLl]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
+ syn match cppFloat display contained "\.\d\('\=\d\+\)*\(e[-+]\=\d\+\)\=\([FfLl]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
syn match cppFloat display contained "\<\d\+e[-+]\=\d\+\([FfLl]\|i[fl]\=\|h\|min\|s\|ms\|us\|ns\|_\i*\)\=\>"
syn region cppString start=+\(L\|u\|u8\|U\)\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"\(sv\|s\|_\i*\)\=+ end='$' contains=cSpecial,cFormat,@Spell
endif
diff --git a/runtime/syntax/deb822sources.vim b/runtime/syntax/deb822sources.vim
index f7d337f..ec45605 100644
--- a/runtime/syntax/deb822sources.vim
+++ b/runtime/syntax/deb822sources.vim
@@ -40,7 +40,7 @@ syn match deb822sourcesUri '\(https\?://\|ftp://\|[rs]sh://\|debtorre
syn region deb822sourcesStrictField matchgroup=deb822sourcesEntryField start="^\%(Types\|URIs\|Suites\|Components\): *" end="$" contains=deb822sourcesType,deb822sourcesUri,deb822sourcesSupportedSuites,deb822sourcesUnsupportedSuites,deb822sourcesFreeComponent,deb822sourcesNonFreeComponent oneline
syn region deb822sourcesField matchgroup=deb822sourcesOptionField start="^\%(Signed-By\|Check-Valid-Until\|Valid-Until-Min\|Valid-Until-Max\|Date-Max-Future\|InRelease-Path\): *" end="$" oneline
syn region deb822sourcesField matchgroup=deb822sourcesMultiValueOptionField start="^\%(Architectures\|Languages\|Targets\)\%(-Add\|-Remove\)\?: *" end="$" oneline
-syn region deb822sourcesStrictField matchgroup=deb822sourcesBooleanOptionField start="^\%(PDiffs\|Allow-Insecure\|Allow-Weak\|Allow-Downgrade-To-Insecure\|Trusted\|Check-Date\): *" end="$" contains=deb822sourcesYesNo oneline
+syn region deb822sourcesStrictField matchgroup=deb822sourcesBooleanOptionField start="^\%(PDiffs\|Allow-Insecure\|Allow-Weak\|Allow-Downgrade-To-Insecure\|Trusted\|Check-Date\|Enabled\): *" end="$" contains=deb822sourcesYesNo oneline
syn region deb822sourcesStrictField matchgroup=deb822sourcesForceBooleanOptionField start="^\%(By-Hash\): *" end="$" contains=deb822sourcesForce,deb822sourcesYesNo oneline
hi def link deb822sourcesField Default
diff --git a/runtime/syntax/generator/gen_syntax_vim.vim b/runtime/syntax/generator/gen_syntax_vim.vim
index d320bdb..8b76775 100644
--- a/runtime/syntax/generator/gen_syntax_vim.vim
+++ b/runtime/syntax/generator/gen_syntax_vim.vim
@@ -274,20 +274,48 @@ function! s:get_vim_command_type(cmd_name)
let ab_prefix = '^[ci]\?'
let menu_prefix = '^\%([acinostvx]\?\|tl\)'
let map_prefix = '^[acilnostvx]\?'
- let exclude_list = [
- \ 'map', 'mapclear',
- \ 'substitute', 'smagic', 'snomagic',
- \ 'setlocal', 'setglobal', 'set', 'var',
- \ 'autocmd', 'augroup', 'doautocmd', 'doautoall',
- \ 'echo', 'echoconsole', 'echoerr', 'echohl', 'echomsg', 'echon', 'echowindow',
- \ 'execute',
- \ 'function', 'endfunction', 'def', 'enddef',
- \ 'behave', 'augroup', 'normal', 'syntax',
- \ 'append', 'insert',
- \ 'Next', 'Print', 'X',
- \ 'new', 'popup',
- \ 'vim9script',
- \ ]
+ let exclude_list =<< trim EOL
+ Next
+ Print
+ X
+ append
+ augroup
+ augroup
+ autocmd
+ behave
+ catch
+ def
+ doautoall
+ doautocmd
+ echo
+ echoconsole
+ echoerr
+ echohl
+ echomsg
+ echon
+ echowindow
+ enddef
+ endfunction
+ execute
+ function
+ insert
+ map
+ mapclear
+ new
+ normal
+ popup
+ set
+ setglobal
+ setlocal
+ sleep
+ smagic
+ snomagic
+ substitute
+ syntax
+ throw
+ var
+ vim9script
+ EOL
" Required for original behavior
" \ 'global', 'vglobal'
@@ -464,6 +492,10 @@ function! s:parse_vim_hlgroup(li)
let item.type = 'both'
call add(a:li, copy(item))
+ " "Conceal" is an option and cannot be used as keyword, so remove it.
+ " (Separately specified as 'syn match' in vim.vim.base).
+ call filter(a:li, {idx, val -> val.name !=# 'Conceal'})
+
quit!
if empty(a:li)
diff --git a/runtime/syntax/generator/vim.vim.base b/runtime/syntax/generator/vim.vim.base
index 90e1ee5..adfd68e 100644
--- a/runtime/syntax/generator/vim.vim.base
+++ b/runtime/syntax/generator/vim.vim.base
@@ -3,7 +3,7 @@
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
" Doug Kearns <dougkearns@gmail.com>
" URL: https://github.com/vim-jp/syntax-vim-ex
-" Last Change: 2024 Apr 13
+" Last Change: 2024 Jun 17
" Former Maintainer: Charles E. Campbell
" DO NOT CHANGE DIRECTLY.
@@ -70,6 +70,7 @@ syn keyword vimGroup contained Comment Constant String Character Number Boolean
" Default highlighting groups {{{2
" GEN_SYN_VIM: vimHLGroup, START_STR='syn keyword vimHLGroup contained', END_STR=''
+syn match vimHLGroup contained "\<Conceal\>"
syn case match
" Function Names {{{2
@@ -174,7 +175,7 @@ syn match vimNumber '\%(^\|\A\)\zs#\x\{6}' skipwhite nextgroup=vimGlobal,vimSub
syn case match
" All vimCommands are contained by vimIsCommand. {{{2
-syn cluster vimCmdList contains=vimAbb,vimAddress,vimAutoCmd,vimAugroup,vimBehave,vimDef,@vimEcho,vimEnddef,vimEndfunction,vimExecute,vimIsCommand,vimExtCmd,vimFor,vimFunction,vimGlobal,vimHighlight,vimLet,vimMap,vimMark,vimNotFunc,vimNorm,vimSet,vimSyntax,vimUnlet,vimUnmap,vimUserCmd,vimMenu,vimMenutranslate
+syn cluster vimCmdList contains=vimAbb,vimAddress,vimAutoCmd,vimAugroup,vimBehave,vimCatch,vimDef,@vimEcho,vimEnddef,vimEndfunction,vimExecute,vimIsCommand,vimExtCmd,vimFor,vimFunction,vimGlobal,vimHighlight,vimLet,vimMap,vimMark,vimNotFunc,vimNorm,vimSet,vimSleep,vimSyntax,vimThrow,vimUnlet,vimUnmap,vimUserCmd,vimMenu,vimMenutranslate
syn match vimCmdSep "[:|]\+" skipwhite nextgroup=@vimCmdList,vimSubst1
syn match vimIsCommand "\<\%(\h\w*\|[23]mat\%[ch]\)\>" contains=vimCommand
syn match vimVar contained "\<\h[a-zA-Z0-9#_]*\>"
@@ -205,6 +206,11 @@ syn match vimBehave "\<be\%[have]\>" nextgroup=vimBehaveBang,vimBehaveModel,vi
syn match vimBehaveBang contained "\a\@1<=!" nextgroup=vimBehaveModel skipwhite
syn keyword vimBehaveModel contained mswin xterm
+" Exception Handling {{{2
+syn keyword vimThrow th[row] skipwhite nextgroup=@vimExprList
+syn keyword vimCatch cat[ch] skipwhite nextgroup=vimCatchPattern
+syn region vimCatchPattern contained matchgroup=Delimiter start="\z([!#$%&'()*+,-./:;<=>?@[\]^_`{}~]\)" skip="\\\\\|\\\z1" end="\z1" contains=@vimSubstList oneline
+
" Filetypes {{{2
" =========
syn match vimFiletype "\<filet\%[ype]\(\s\+\I\i*\)*" skipwhite contains=vimFTCmd,vimFTOption,vimFTError
@@ -368,7 +374,9 @@ syn region vimUserCmdBlock contained matchgroup=vimSep start="{" end="}" contain
" Lower Priority Comments: after some vim commands... {{{2
" =======================
-syn region vimCommentString contained oneline start='\S\s\+"'ms=e end='"'
+if get(g:, "vimsyn_comment_strings", 1)
+ syn region vimCommentString contained oneline start='\S\s\+"'ms=e end='"'
+endif
if s:vim9script
syn match vimComment excludenl +\s"[^\-:.%#=*].*$+lc=1 contains=@vimCommentGroup,vimCommentString contained
@@ -437,12 +445,10 @@ syn match vimStringInterpolationBrace contained "}}"
syn cluster vimSubstList contains=vimPatSep,vimPatRegion,vimPatSepErr,vimSubstTwoBS,vimSubstRange,vimNotation
syn cluster vimSubstRepList contains=vimSubstSubstr,vimSubstTwoBS,vimNotation
syn cluster vimSubstList add=vimCollection
-syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>[\"#|]\@!" nextgroup=vimSubstPat
-syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)_\@=" nextgroup=vimSubstPat
-syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#" nextgroup=vimSubstPat
-syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>[\"#|]\@!" nextgroup=vimSubstPat
-syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)_\@=" nextgroup=vimSubstPat
-syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#" nextgroup=vimSubstPat
+syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>" skipwhite nextgroup=vimSubstPat
+syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)[_#]\@=" skipwhite nextgroup=vimSubstPat
+syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>" skipwhite nextgroup=vimSubstPat
+syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)[_#]\@=" skipwhite nextgroup=vimSubstPat
" TODO: Vim9 illegal separators for abbreviated :s form are [-.:], :su\%[...] required
" : # is allowed but "not recommended" (see :h pattern-delimiter)
syn region vimSubstPat contained matchgroup=vimSubstDelim start="\z([!#$%&'()*+,-./:;<=>?@[\]^_`{}~]\)"rs=s+1 skip="\\\\\|\\\z1" end="\z1"re=e-1,me=e-1 contains=@vimSubstList nextgroup=vimSubstRep4 oneline
@@ -455,6 +461,10 @@ syn match vimSubstTwoBS contained "\\\\"
syn match vimSubstFlagErr contained "[^< \t\r|]\+" contains=vimSubstFlags
syn match vimSubstFlags contained "[&cegiIlnpr#]\+"
+" Vi compatibility
+syn match vimSubstDelim contained "\\"
+syn match vimSubstPat contained "\\\ze[/?&]" contains=vimSubstDelim nextgroup=vimSubstRep4
+
" 'String': {{{2
syn match vimString "[^(,]'[^']\{-}\zs'"
@@ -644,6 +654,12 @@ syn match vimNotFunc "\<if\>\|\<el\%[seif]\>\|\<retu\%[rn]\>\|\<while\>" skipwhi
syn match vimNorm "\<norm\%[al]!\=" skipwhite nextgroup=vimNormCmds
syn match vimNormCmds contained ".*$"
+" Sleep: {{{2
+" =====
+syn keyword vimSleep sl[eep] skipwhite nextgroup=vimSleepBang,vimSleepArg
+syn match vimSleepBang contained "\a\@1<=!" skipwhite nextgroup=vimSleepArg
+syn match vimSleepArg contained "\<\%(\d\+\)\=m\=\>"
+
" Syntax: {{{2
"=======
syn match vimGroupList contained "[^[:space:],]\+\%(\s*,\s*[^[:space:],]\+\)*" contains=vimGroupSpecial
@@ -809,16 +825,23 @@ syn match vimCtrlChar "[- -]"
" Beginners - Patterns that involve ^ {{{2
" =========
if s:vim9script
- syn match vimLineComment +^[ \t:]*".*$+ contains=@vimCommentGroup,vimCommentString,vimCommentTitle contained
- syn match vim9LineComment +^[ \t:]*#.*$+ contains=@vimCommentGroup,vimCommentString,vim9CommentTitle
+ syn region vim9LineComment start=+^[ \t:]*\zs#.*$+ skip=+\n\s*\\\|\n\s*#\\ + end="$" contains=@vimCommentGroup,vimCommentString,vim9CommentTitle
+ syn region vimLineComment start=+^[ \t:]*\zs".*$+ skip=+\n\s*\\\|\n\s*"\\ + end="$" contains=@vimCommentGroup,vimCommentString,vimCommentTitle contained
else
- syn match vimLineComment +^[ \t:]*".*$+ contains=@vimCommentGroup,vimCommentString,vimCommentTitle
- syn match vim9LineComment +^[ \t:]*#.*$+ contains=@vimCommentGroup,vimCommentString,vim9CommentTitle contained
+ syn region vimLineComment start=+^[ \t:]*\zs".*$+ skip=+\n\s*\\\|\n\s*"\\ + end="$" contains=@vimCommentGroup,vimCommentString,vimCommentTitle
+ syn region vim9LineComment start=+^[ \t:]*\zs#.*$+ skip=+\n\s*\\\|\n\s*#\\ + end="$" contains=@vimCommentGroup,vimCommentString,vim9CommentTitle contained
endif
syn match vimCommentTitle '"\s*\%([sS]:\|\h\w*#\)\=\u\w*\(\s\+\u\w*\)*:'hs=s+1 contained contains=vimCommentTitleLeader,vimTodo,@vimCommentGroup
syn match vim9CommentTitle '#\s*\%([sS]:\|\h\w*#\)\=\u\w*\(\s\+\u\w*\)*:'hs=s+1 contained contains=vim9CommentTitleLeader,vimTodo,@vimCommentGroup
+
+" allowed anywhere in the file
+if !s:vim9script
+ syn match vimShebangError "^\s*\zs#!.*" display
+endif
+syn match vimShebang "\%^#!.*" display
+
syn match vimContinue "^\s*\zs\\"
-syn match vimContinueComment '^\s*\zs["#]\\ .*' contained
+syn match vimContinueComment '^\s*\zs["#]\\ .*'
syn cluster vimContinue contains=vimContinue,vimContinueComment
syn region vimString start="^\s*\\\z(['"]\)" skip='\\\\\|\\\z1' end="\z1" oneline keepend contains=@vimStringGroup,vimContinue
syn match vimCommentTitleLeader '"\s\+'ms=s+1 contained
@@ -851,12 +874,12 @@ endif
" Allows users to specify the type of embedded script highlighting
" they want: (perl/python/ruby/tcl support)
" g:vimsyn_embed == 0 : don't embed any scripts
-" g:vimsyn_embed =~# 'l' : embed lua (but only if vim supports it)
-" g:vimsyn_embed =~# 'm' : embed mzscheme (but only if vim supports it)
-" g:vimsyn_embed =~# 'p' : embed perl (but only if vim supports it)
-" g:vimsyn_embed =~# 'P' : embed python (but only if vim supports it)
-" g:vimsyn_embed =~# 'r' : embed ruby (but only if vim supports it)
-" g:vimsyn_embed =~# 't' : embed tcl (but only if vim supports it)
+" g:vimsyn_embed =~# 'l' : embed Lua (but only if vim supports it)
+" g:vimsyn_embed =~# 'm' : embed MzScheme (but only if vim supports it)
+" g:vimsyn_embed =~# 'p' : embed Perl (but only if vim supports it)
+" g:vimsyn_embed =~# 'P' : embed Python (but only if vim supports it)
+" g:vimsyn_embed =~# 'r' : embed Ruby (but only if vim supports it)
+" g:vimsyn_embed =~# 't' : embed Tcl (but only if vim supports it)
if !exists("g:vimsyn_embed")
let g:vimsyn_embed= "lmpPr"
endif
@@ -1043,6 +1066,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimHiCtermError vimError
hi def link vimHiKeyError vimError
hi def link vimMapModErr vimError
+ hi def link vimShebangError vimError
hi def link vimSubstFlagErr vimError
hi def link vimSynCaseError vimError
hi def link vimSynFoldMethodError vimError
@@ -1063,6 +1087,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimBehaveModel vimBehave
hi def link vimBehave vimCommand
hi def link vimBracket Delimiter
+ hi def link vimCatch vimCommand
hi def link vimCmplxRepeat SpecialChar
hi def link vimCommand Statement
hi def link vimComment Comment
@@ -1180,6 +1205,10 @@ if !exists("skip_vim_syntax_inits")
hi def link vimSetSep Statement
hi def link vimSetString vimString
hi def link vim9Vim9Script vimCommand
+ hi def link vimShebang PreProc
+ hi def link vimSleep vimCommand
+ hi def link vimSleepArg Constant
+ hi def link vimSleepBang vimBang
hi def link vimSpecFile Identifier
hi def link vimSpecFileMod vimSpecFile
hi def link vimSpecial Type
@@ -1220,6 +1249,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimSynReg Type
hi def link vimSyntax vimCommand
hi def link vimSynType vimSpecial
+ hi def link vimThrow vimCommand
hi def link vimTodo Todo
hi def link vimType Type
hi def link vimUnlet vimCommand
diff --git a/runtime/syntax/hare.vim b/runtime/syntax/hare.vim
index 07cf33f..4c7ae92 100644
--- a/runtime/syntax/hare.vim
+++ b/runtime/syntax/hare.vim
@@ -1,119 +1,142 @@
-" PRELUDE {{{1
-" Vim syntax file
-" Language: Hare
-" Maintainer: Amelia Clarke <me@rsaihe.dev>
-" Last Change: 2022-09-21
+" Vim syntax file.
+" Language: Hare
+" Maintainer: Amelia Clarke <selene@perilune.dev>
+" Last Change: 2024-05-10
+" Upstream: https://git.sr.ht/~sircmpwn/hare.vim
-if exists("b:current_syntax")
+if exists('b:current_syntax')
finish
endif
-let b:current_syntax = "hare"
+syn include @haredoc syntax/haredoc.vim
+let b:current_syntax = 'hare'
-" SYNTAX {{{1
+" Syntax {{{1
syn case match
+syn iskeyword @,48-57,@-@,_
-" KEYWORDS {{{2
-syn keyword hareConditional if else match switch
+" Keywords {{{2
+syn keyword hareConditional else if match switch
+syn keyword hareDefine def
+syn keyword hareInclude use
syn keyword hareKeyword break continue return yield
+syn keyword hareKeyword case
+syn keyword hareKeyword const let
syn keyword hareKeyword defer
+syn keyword hareKeyword export static
syn keyword hareKeyword fn
-syn keyword hareKeyword let
-syn keyword hareLabel case
syn keyword hareOperator as is
syn keyword hareRepeat for
-syn keyword hareStorageClass const def export nullable static
-syn keyword hareStructure enum struct union
syn keyword hareTypedef type
-" C ABI.
-syn keyword hareKeyword vastart vaarg vaend
-
-" BUILTINS {{{2
-syn keyword hareBuiltin abort
+" Attributes.
+syn keyword hareAttribute @fini @init @test
+syn keyword hareAttribute @offset @packed
+syn keyword hareAttribute @symbol
+syn keyword hareAttribute @threadlocal
+
+" Builtins.
+syn keyword hareBuiltin abort assert
+syn keyword hareBuiltin align len offset
syn keyword hareBuiltin alloc free
syn keyword hareBuiltin append delete insert
-syn keyword hareBuiltin assert
-syn keyword hareBuiltin len offset
+syn keyword hareBuiltin vaarg vaend vastart
-" TYPES {{{2
+" Types {{{2
syn keyword hareType bool
-syn keyword hareType char str
+syn keyword hareType done
syn keyword hareType f32 f64
-syn keyword hareType u8 u16 u32 u64 i8 i16 i32 i64
-syn keyword hareType uint int
-syn keyword hareType rune
+syn keyword hareType i8 i16 i32 i64 int
+syn keyword hareType never
+syn keyword hareType opaque
+syn keyword hareType rune str
+syn keyword hareType u8 u16 u32 u64 uint
syn keyword hareType uintptr
+syn keyword hareType valist
syn keyword hareType void
-" C ABI.
-syn keyword hareType valist
+" Other types.
+syn keyword hareStorageClass nullable
+syn keyword hareStructure enum struct union
-" LITERALS {{{2
-syn keyword hareBoolean true false
-syn keyword hareNull null
-
-" Number literals.
-syn match hareNumber "\v(\.@1<!|\.\.)\zs<\d+([Ee][+-]?\d+)?(z|[iu](8|16|32|64)?)?>" display
-syn match hareNumber "\v(\.@1<!|\.\.)\zs<0b[01]+(z|[iu](8|16|32|64)?)?>" display
-syn match hareNumber "\v(\.@1<!|\.\.)\zs<0o\o+(z|[iu](8|16|32|64)?)?>" display
-syn match hareNumber "\v(\.@1<!|\.\.)\zs<0x\x+(z|[iu](8|16|32|64)?)?>" display
-
-" Floating-point number literals.
-syn match hareFloat "\v<\d+\.\d+([Ee][+-]?\d+)?(f32|f64)?>" display
-syn match hareFloat "\v<\d+([Ee][+-]?\d+)?(f32|f64)>" display
-
-" String and rune literals.
-syn match hareEscape "\\[\\'"0abfnrtv]" contained display
-syn match hareEscape "\v\\(x\x{2}|u\x{4}|U\x{8})" contained display
-syn match hareFormat "\v\{\d*(\%\d*|(:[ 0+-]?\d*(\.\d+)?[Xbox]?))?}" contained display
-syn match hareFormat "\({{\|}}\)" contained display
-syn region hareRune start="'" end="'\|$" skip="\\'" contains=hareEscape display extend
-syn region hareString start=+"+ end=+"\|$+ skip=+\\"+ contains=hareEscape,hareFormat display extend
-syn region hareString start="`" end="`\|$" contains=hareFormat display
-
-" MISCELLANEOUS {{{2
-syn keyword hareTodo FIXME TODO XXX contained
+" Literals {{{2
+syn keyword hareBoolean false true
+syn keyword hareConstant null
-" Attributes.
-syn match hareAttribute "@[a-z]*"
+" Integer literals.
+syn match hareNumber '\v<%(0|[1-9]%(_?\d)*)%([Ee]\+?\d+)?%([iu]%(8|16|32|64)?|z)?>' display
+syn match hareNumber '\v<0b[01]%(_?[01])*%([iu]%(8|16|32|64)?|z)?>' display
+syn match hareNumber '\v<0o\o%(_?\o)*%([iu]%(8|16|32|64)?|z)?>' display
+syn match hareNumber '\v<0x\x%(_?\x)*%([iu]%(8|16|32|64)?|z)?>' display
-" Blocks.
-syn region hareBlock start="{" end="}" fold transparent
+" Floating-point literals.
+syn match hareFloat '\v<%(0|[1-9]%(_?\d)*)\.\d%(_?\d)*%([Ee][+-]?\d+)?%(f32|f64)?>' display
+syn match hareFloat '\v<%(0|[1-9]%(_?\d)*)%([Ee][+-]?\d+)?%(f32|f64)>' display
+syn match hareFloat '\v<0x\x%(_?\x)*%(\.\x%(_?\x)*)?[Pp][+-]?\d+%(f32|f64)?>' display
+
+" Rune and string literals.
+syn region hareRune start="'" skip="\\'" end="'" contains=hareEscape
+syn region hareString start='"' skip='\\"' end='"' contains=hareEscape,hareFormat
+syn region hareString start='`' end='`' contains=hareFormat
+
+" Escape sequences.
+syn match hareEscape '\\[0abfnrtv\\'"]' contained
+syn match hareEscape '\v\\%(x\x{2}|u\x{4}|U\x{8})' contained display
+
+" Format sequences.
+syn match hareFormat '\v\{\d*%(:%(\.?\d+|[ +\-=Xbefgox]|F[.2ESUs]|_%(.|\\%([0abfnrtv\\'"]|x\x{2}|u\x{4}|U\x{8})))*)?}' contained contains=hareEscape display
+syn match hareFormat '{\d*%\d*}' contained display
+syn match hareFormat '{{\|}}' contained display
+
+" Miscellaneous {{{2
" Comments.
-syn region hareComment start="//" end="$" contains=hareCommentDoc,hareTodo,@Spell display keepend
-syn region hareCommentDoc start="\[\[" end="]]\|\ze\_s" contained display
+syn region hareComment start='//' end='$' contains=hareTodo,@haredoc,@Spell display
+syn keyword hareTodo FIXME TODO XXX contained
+
+" Identifiers.
+syn match hareDelimiter '::' display
+syn match hareName '\<\h\w*\>' nextgroup=@harePostfix skipempty skipwhite transparent
-" The size keyword can be either a builtin or a type.
-syn match hareBuiltin "\v<size>\ze(\_s*//.*\_$)*\_s*\(" contains=hareComment
-syn match hareType "\v<size>((\_s*//.*\_$)*\_s*\()@!" contains=hareComment
+" Labels.
+syn match hareLabel ':\h\w*\>' display
-" Trailing whitespace.
-syn match hareSpaceError "\v\s+$" display excludenl
-syn match hareSpaceError "\v\zs +\ze\t" display
+" Match `size` as a type unless it is followed by an open paren.
+syn match hareType '\<size\>' display
+syn match hareBuiltin '\<size\ze(' display
-" Use statement.
-syn region hareUse start="\v^\s*\zsuse>" end=";" contains=hareComment display
+" Postfix expressions.
+syn cluster harePostfix contains=hareErrorTest,hareField,hareIndex,hareParens
+syn match hareErrorTest '!=\@!' contained nextgroup=@harePostfix skipempty skipwhite
+syn match hareErrorTest '?' nextgroup=@harePostfix skipempty skipwhite
+syn match hareField '\.\w*\>'hs=s+1 contained contains=hareNumber nextgroup=@harePostfix skipempty skipwhite
+syn region hareIndex start='\[' end=']' contained nextgroup=@harePostfix skipempty skipwhite transparent
+syn region hareParens start='(' end=')' nextgroup=@harePostfix skipempty skipwhite transparent
-syn match hareErrorAssertion "\v(^([^/]|//@!)*\)\_s*)@<=!\=@!"
-syn match hareQuestionMark "?"
+" Whitespace errors.
+syn match hareSpaceError '^ \+\ze\t' display
+syn match hareSpaceError excludenl '\s\+$' containedin=ALL display
-" DEFAULT HIGHLIGHTING {{{1
-hi def link hareAttribute Keyword
+" Folding {{{3
+syn region hareBlock start='{' end='}' fold transparent
+
+" Default highlighting {{{1
+hi def link hareAttribute PreProc
hi def link hareBoolean Boolean
-hi def link hareBuiltin Function
+hi def link hareBuiltin Operator
hi def link hareComment Comment
-hi def link hareCommentDoc SpecialComment
hi def link hareConditional Conditional
+hi def link hareConstant Constant
+hi def link hareDefine Define
+hi def link hareDelimiter Delimiter
+hi def link hareErrorTest Special
hi def link hareEscape SpecialChar
hi def link hareFloat Float
hi def link hareFormat SpecialChar
+hi def link hareInclude Include
hi def link hareKeyword Keyword
-hi def link hareLabel Label
-hi def link hareNull Constant
+hi def link hareLabel Special
hi def link hareNumber Number
hi def link hareOperator Operator
-hi def link hareQuestionMark Special
hi def link hareRepeat Repeat
hi def link hareRune Character
hi def link hareStorageClass StorageClass
@@ -122,12 +145,13 @@ hi def link hareStructure Structure
hi def link hareTodo Todo
hi def link hareType Type
hi def link hareTypedef Typedef
-hi def link hareUse PreProc
-hi def link hareSpaceError Error
-autocmd InsertEnter * hi link hareSpaceError NONE
-autocmd InsertLeave * hi link hareSpaceError Error
+" Highlight embedded haredoc references.
+hi! def link haredocRefValid SpecialComment
-hi def hareErrorAssertion ctermfg=red cterm=bold guifg=red gui=bold
+" Highlight whitespace errors by default.
+if get(g:, 'hare_space_error', 1)
+ hi def link hareSpaceError Error
+endif
-" vim: tabstop=8 shiftwidth=2 expandtab
+" vim: et sts=2 sw=2 ts=8
diff --git a/runtime/syntax/haredoc.vim b/runtime/syntax/haredoc.vim
new file mode 100644
index 0000000..09c99c1
--- /dev/null
+++ b/runtime/syntax/haredoc.vim
@@ -0,0 +1,32 @@
+" Vim syntax file.
+" Language: Haredoc (Hare documentation format)
+" Maintainer: Amelia Clarke <selene@perilune.dev>
+" Last Change: 2024-05-10
+" Upstream: https://git.sr.ht/~selene/hare.vim
+
+if exists('b:current_syntax')
+ finish
+endif
+let b:current_syntax = 'haredoc'
+
+" Syntax {{{1
+syn case match
+syn iskeyword @,48-57,_
+
+" Code samples.
+syn region haredocCodeSample excludenl start='\t\zs' end='$' contains=@NoSpell display
+
+" References to other declarations and modules.
+syn region haredocRef start='\[\[' end=']]' contains=haredocRefValid,@NoSpell display keepend oneline
+syn match haredocRefValid '\v\[\[\h\w*%(::\h\w*)*%(::)?]]' contained contains=@NoSpell display
+
+" Miscellaneous.
+syn keyword haredocTodo FIXME TODO XXX
+
+" Default highlighting {{{1
+hi def link haredocCodeSample Comment
+hi def link haredocRef Error
+hi def link haredocRefValid Special
+hi def link haredocTodo Todo
+
+" vim: et sts=2 sw=2 ts=8
diff --git a/runtime/syntax/html.vim b/runtime/syntax/html.vim
index c975ae8..d067dde 100644
--- a/runtime/syntax/html.vim
+++ b/runtime/syntax/html.vim
@@ -191,7 +191,7 @@ syn keyword htmlArg contained step title translate typemustmatch
syn match htmlArg contained "\<data-\h\%(\w\|[-.]\)*\%(\_s*=\)\@="
" special characters
-syn match htmlSpecialChar "&#\=[0-9A-Za-z]\{1,8};"
+syn match htmlSpecialChar "&#\=[0-9A-Za-z]\{1,32};"
" Comments (the real ones or the old netscape ones)
if exists("html_wrong_comments")
diff --git a/runtime/syntax/i3config.vim b/runtime/syntax/i3config.vim
index 7441f90..c95cb87 100644
--- a/runtime/syntax/i3config.vim
+++ b/runtime/syntax/i3config.vim
@@ -2,8 +2,8 @@
" Language: i3 config file
" Original Author: Josef Litos (JosefLitos/i3config.vim)
" Maintainer: Quentin Hibon (github user hiqua)
-" Version: 1.2.1
-" Last Change: 2024-04-14
+" Version: 1.2.4
+" Last Change: 2024-05-24
" References:
" http://i3wm.org/docs/userguide.html#configuring
@@ -46,7 +46,7 @@ syn match i3ConfigIncludeCommand /`[^`]*`/ contained contains=@i3ConfigSh
syn region i3ConfigParamLine matchgroup=i3ConfigKeyword start=/include / end=/$/ contained contains=@i3ConfigStrVar,i3ConfigIncludeCommand,i3ConfigShOper keepend
" 4.2 Comments
-syn match i3ConfigComment /^\s*#.*$/ contained contains=i3ConfigTodo
+syn match i3ConfigComment /#.*$/ contained contains=i3ConfigTodo
" 4.3 Fonts
syn match i3ConfigFontSize / \d\+\(px\)\?$/ contained
@@ -64,10 +64,10 @@ syn region i3ConfigBind start=/\zs/ skip=/\\$/ end=/$/ contained contains=@i3Con
syn keyword i3ConfigBindKeyword bindsym bindcode contained skipwhite nextgroup=i3ConfigBindArgument,i3ConfigBindCombo
" 4.6 Binding modes
-syn region i3ConfigModeBlock matchgroup=i3ConfigKeyword start=/^mode\ze\( --pango_markup\)\? \([^'" {]\+\|'[^']\+'\|".\+"\)\s\+{$/ end=/^}\zs$/ contained contains=i3ConfigShParam,@i3ConfigStrVar,i3ConfigBindKeyword,i3ConfigComment,i3ConfigParen fold keepend extend
+syn region i3ConfigModeBlock matchgroup=i3ConfigKeyword start=/mode\ze\( --pango_markup\)\? \([^'" {]\+\|'[^']\+'\|".\+"\)\s\+{$/ end=/^}\zs$/ contained contains=i3ConfigShParam,@i3ConfigStrVar,i3ConfigBindKeyword,i3ConfigComment,i3ConfigParen fold keepend extend
" 4.7 Floating modifier
-syn keyword i3ConfigKeyword floating_modifier contained skipwhite nextgroup=i3ConfigVariable,i3ConfigBindModkey
+syn match i3ConfigKeyword /floating_modifier [$A-Z][0-9A-Za-z]*$/ contained contains=i3ConfigVariable,i3ConfigBindModkey
" 4.8 Floating window size
syn keyword i3ConfigSizeSpecial x contained
@@ -122,8 +122,8 @@ syn match i3ConfigShDelim /[[\]{}();`]\+/ contained
syn match i3ConfigShOper /[<>&|+=~^*!.?]\+/ contained
syn match i3ConfigShParam /\<-[A-Za-z-][0-9A-Za-z_-]*\>/ contained
syn cluster i3ConfigSh contains=@i3ConfigIdent,i3ConfigShOper,i3ConfigShDelim,i3ConfigShParam,i3ConfigShCommand
-syn region i3ConfigExec start=/ [^{]/ skip=/\\$/ end=/$/ contained contains=i3ConfigExecAction,@i3ConfigSh keepend
-syn match i3ConfigKeyword /^\(exec_always\|exec\)/ contained nextgroup=i3ConfigExec
+syn region i3ConfigExec start=/ \ze[^{]/ skip=/\\$/ end=/$/ contained contains=i3ConfigExecAction,@i3ConfigSh keepend
+syn keyword i3ConfigKeyword exec_always exec contained nextgroup=i3ConfigExec
" 4.21 Workspaces per output
syn match i3ConfigOutputIdent /[^'",; ]\+/ contained contains=@i3ConfigIdent,i3ConfigColonOperator skipwhite nextgroup=i3ConfigOutputIdent
@@ -189,7 +189,7 @@ syn keyword i3ConfigBarOpts modifier contained skipwhite nextgroup=i3ConfigBindC
syn keyword i3ConfigBarOpts i3bar_command status_command workspace_command contained skipwhite nextgroup=@i3ConfigSh
syn keyword i3ConfigBarOpts mode hidden_state id position output tray_output tray_padding separator_symbol workspace_buttons workspace_min_width strip_workspace_numbers strip_workspace_name binding_mode_indicator padding contained skipwhite nextgroup=i3ConfigBarOptVals,@i3ConfigValue,i3ConfigShOper
syn keyword i3ConfigBarOptVals dock hide invisible show none top bottom primary nonprimary contained
-syn region i3ConfigBarBlock matchgroup=i3ConfigKeyword start=/^bar\ze {$/ end=/^}\zs$/ contained contains=i3ConfigBarOpts,i3ConfigComment,i3ConfigParen,i3ConfigBindKeyword,i3ConfigColorsBlock fold keepend extend
+syn region i3ConfigBarBlock matchgroup=i3ConfigKeyword start=/bar\ze {$/ end=/^\s*}\zs$/ contained contains=i3ConfigBarOpts,i3ConfigComment,i3ConfigParen,i3ConfigBindKeyword,i3ConfigColorsBlock fold keepend extend
" 5.16 Color block
syn match i3ConfigColorSeq /#[0-9A-Fa-f]\{3,8}\|\$[0-9A-Za-z_:|[\]-]\+/ contained contains=@i3ConfigColVar skipwhite nextgroup=i3ConfigColorSeq
@@ -221,7 +221,7 @@ syn keyword i3ConfigFocusOpts left right up down parent child next prev sibling
syn keyword i3ConfigOutputDir left right down up current primary nonprimary next prev contained skipwhite
syn keyword i3ConfigFocusOutput output contained skipwhite nextgroup=i3ConfigOutputIdent,i3ConfigOutputDir
syn keyword i3ConfigActionKeyword focus contained skipwhite nextgroup=i3ConfigFocusOpts,i3ConfigFocusOutput
-syn match i3ConfigKeyword /^focus / contained nextgroup=i3ConfigFocusOutput
+syn keyword i3ConfigKeyword focus skipwhite contained nextgroup=i3ConfigFocusOutput
" 6.8 Focusing workspaces (4.21)
syn keyword i3ConfigWorkspaceDir prev next back_and_forth contained
@@ -260,7 +260,7 @@ syn match i3ConfigMarkOpt /--\(add\|replace\)\( --toggle\)\?/ contained contains
syn keyword i3ConfigActionKeyword mark contained skipwhite nextgroup=i3ConfigMarkOpt,i3ConfigOutputIdent
" Commands usable for direct config calls - for enforcing start of line for Commands
-syn match i3ConfigTopLevelDirective /^/ skipwhite nextgroup=i3ConfigComment,i3ConfigKeyword,i3ConfigCommand,i3ConfigBindKeyword,i3ConfigParamLine,i3ConfigModeBlock,i3ConfigBarBlock,i3ConfigError
+syn match i3ConfigTopLevelDirective /^\s*/ nextgroup=i3ConfigComment,i3ConfigKeyword,i3ConfigCommand,i3ConfigBindKeyword,i3ConfigParamLine,i3ConfigModeBlock,i3ConfigBarBlock,i3ConfigError
" Commands useable in keybinds
syn keyword i3ConfigActionKeyword mode append_layout kill open fullscreen sticky split floating swap unmark title_window_icon title_format border restart reload exit scratchpad nop bar contained skipwhite nextgroup=i3ConfigOption,@i3ConfigValue
diff --git a/runtime/syntax/java.vim b/runtime/syntax/java.vim
index 8ffe9e0..6f64bdc 100644
--- a/runtime/syntax/java.vim
+++ b/runtime/syntax/java.vim
@@ -3,7 +3,7 @@
" Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com>
" Former Maintainer: Claudio Fleiner <claudio@fleiner.com>
" Repository: https://github.com/zzzyxwvut/java-vim.git
-" Last Change: 2024 Apr 22
+" Last Change: 2024 Jun 15
" Please check :help java.vim for comments on some of the options available.
@@ -14,14 +14,50 @@ if !exists("main_syntax")
endif
" we define it here so that included files can test for it
let main_syntax='java'
- syn region javaFold start="{" end="}" transparent fold
endif
let s:cpo_save = &cpo
set cpo&vim
+"""" STRIVE TO REMAIN COMPATIBLE FOR AT LEAST VIM 7.0.
+let s:ff = {}
+
+function! s:ff.LeftConstant(x, y) abort
+ return a:x
+endfunction
+
+function! s:ff.RightConstant(x, y) abort
+ return a:y
+endfunction
+
+if !exists("*s:ReportOnce")
+ function s:ReportOnce(message) abort
+ echomsg 'syntax/java.vim: ' . a:message
+ endfunction
+else
+ function! s:ReportOnce(dummy)
+ endfunction
+endif
+
+function! JavaSyntaxFoldTextExpr() abort
+ return getline(v:foldstart) !~ '/\*\+\s*$'
+ \ ? foldtext()
+ \ : printf('+-%s%3d lines: ',
+ \ v:folddashes,
+ \ (v:foldend - v:foldstart + 1)) .
+ \ getline(v:foldstart + 1)
+endfunction
+
+" E120 for "fdt=s:JavaSyntaxFoldTextExpr()" before v8.2.3900.
+setlocal foldtext=JavaSyntaxFoldTextExpr()
+
" Admit the ASCII dollar sign to keyword characters (JLS-17, §3.8):
-execute printf('syntax iskeyword %s,$', &l:iskeyword)
+try
+ exec 'syntax iskeyword ' . &l:iskeyword . ',$'
+catch /\<E410:/
+ call s:ReportOnce(v:exception)
+ setlocal iskeyword+=$
+endtry
" some characters that cannot be in a java program (outside a string)
syn match javaError "[\\@`]"
@@ -42,6 +78,7 @@ syn keyword javaConstant null
syn keyword javaTypedef this super
syn keyword javaOperator new instanceof
syn match javaOperator "\<var\>\%(\s*(\)\@!"
+
" Since the yield statement, which could take a parenthesised operand,
" and _qualified_ yield methods get along within the switch block
" (JLS-17, §3.8), it seems futile to make a region definition for this
@@ -49,7 +86,15 @@ syn match javaOperator "\<var\>\%(\s*(\)\@!"
" backtrack (arbitrarily) 80 bytes, at most, on the matched line and,
" if necessary, on the line before that (h: \@<=), trying to match
" neither a method reference nor a qualified method invocation.
-syn match javaOperator "\%(\%(::\|\.\)[[:space:]\n]*\)\@80<!\<yield\>"
+try
+ syn match javaOperator "\%(\%(::\|\.\)[[:space:]\n]*\)\@80<!\<yield\>"
+ let s:ff.Peek = s:ff.LeftConstant
+catch /\<E59:/
+ call s:ReportOnce(v:exception)
+ syn match javaOperator "\%(\%(::\|\.\)[[:space:]\n]*\)\@<!\<yield\>"
+ let s:ff.Peek = s:ff.RightConstant
+endtry
+
syn keyword javaType boolean char byte short int long float double
syn keyword javaType void
syn keyword javaStatement return
@@ -65,6 +110,7 @@ syn match javaClassDecl "\<record\>\%(\s*(\)\@!"
syn match javaClassDecl "^class\>"
syn match javaClassDecl "[^.]\s*\<class\>"ms=s+1
syn match javaAnnotation "@\%(\K\k*\.\)*\K\k*\>"
+syn region javaAnnotation transparent matchgroup=javaAnnotationStart start=/@\%(\K\k*\.\)*\K\k*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=javaAnnotation,javaParenT,javaBlock,javaString,javaBoolean,javaNumber,javaTypedef,javaComment,javaLineComment
syn match javaClassDecl "@interface\>"
syn keyword javaBranch break continue nextgroup=javaUserLabelRef skipwhite
syn match javaUserLabelRef "\k\+" contained
@@ -82,15 +128,22 @@ syn match javaConceptKind "\<default\>\%(\s*\%(:\|->\)\)\@!"
" ".java\=" extension used for a production version and an arbitrary
" extension used for a testing version.
let s:module_info_cur_buf = fnamemodify(bufname("%"), ":t") =~ '^module-info\%(\.class\>\)\@!'
-let s:selectable_regexp_engine = !(v:version < 704)
-lockvar s:selectable_regexp_engine s:module_info_cur_buf
+lockvar s:module_info_cur_buf
+
+if !(v:version < 704)
+ " Request the new regexp engine for [:upper:] and [:lower:].
+ let [s:ff.Engine, s:ff.UpperCase, s:ff.LowerCase] = repeat([s:ff.LeftConstant], 3)
+else
+ " XXX: \C\<[^a-z0-9]\k*\> rejects "type", but matches "τύπος".
+ " XXX: \C\<[^A-Z0-9]\k*\> rejects "Method", but matches "Μέθοδος".
+ let [s:ff.Engine, s:ff.UpperCase, s:ff.LowerCase] = repeat([s:ff.RightConstant], 3)
+endif
" Java modules (since Java 9, for "module-info.java" file).
if s:module_info_cur_buf
syn keyword javaModuleStorageClass module transitive
syn keyword javaModuleStmt open requires exports opens uses provides
syn keyword javaModuleExternal to with
- syn cluster javaTop add=javaModuleStorageClass,javaModuleStmt,javaModuleExternal
endif
if exists("java_highlight_java_lang_ids")
@@ -107,36 +160,32 @@ if exists("java_highlight_all") || exists("java_highlight_java") || exists("ja
" the current keyword placement. The below _match_es follow suit.
syn keyword javaR_JavaLang ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException ClassCastException IllegalArgumentException IllegalMonitorStateException IllegalThreadStateException IndexOutOfBoundsException NegativeArraySizeException NullPointerException NumberFormatException RuntimeException SecurityException StringIndexOutOfBoundsException IllegalStateException UnsupportedOperationException EnumConstantNotPresentException TypeNotPresentException IllegalCallerException LayerInstantiationException WrongThreadException MatchException
- syn cluster javaTop add=javaR_JavaLang
syn cluster javaClasses add=javaR_JavaLang
hi def link javaR_JavaLang javaR_Java
" Member enumerations:
- syn match javaC_JavaLang "\%(\<Thread\.\)\@<=\<State\>"
- syn match javaC_JavaLang "\%(\<Character\.\)\@<=\<UnicodeScript\>"
- syn match javaC_JavaLang "\%(\<ProcessBuilder\.Redirect\.\)\@<=\<Type\>"
- syn match javaC_JavaLang "\%(\<StackWalker\.\)\@<=\<Option\>"
- syn match javaC_JavaLang "\%(\<System\.Logger\.\)\@<=\<Level\>"
+ exec 'syn match javaC_JavaLang "\%(\<Thread\.\)\@' . s:ff.Peek('7', '') . '<=\<State\>"'
+ exec 'syn match javaC_JavaLang "\%(\<Character\.\)\@' . s:ff.Peek('10', '') . '<=\<UnicodeScript\>"'
+ exec 'syn match javaC_JavaLang "\%(\<ProcessBuilder\.Redirect\.\)\@' . s:ff.Peek('24', '') . '<=\<Type\>"'
+ exec 'syn match javaC_JavaLang "\%(\<StackWalker\.\)\@' . s:ff.Peek('12', '') . '<=\<Option\>"'
+ exec 'syn match javaC_JavaLang "\%(\<System\.Logger\.\)\@' . s:ff.Peek('14', '') . '<=\<Level\>"'
" Member classes:
- syn match javaC_JavaLang "\%(\<Character\.\)\@<=\<Subset\>"
- syn match javaC_JavaLang "\%(\<Character\.\)\@<=\<UnicodeBlock\>"
- syn match javaC_JavaLang "\%(\<ProcessBuilder\.\)\@<=\<Redirect\>"
- syn match javaC_JavaLang "\%(\<ModuleLayer\.\)\@<=\<Controller\>"
- syn match javaC_JavaLang "\%(\<Runtime\.\)\@<=\<Version\>"
- syn match javaC_JavaLang "\%(\<System\.\)\@<=\<LoggerFinder\>"
- syn match javaC_JavaLang "\%(\<Enum\.\)\@<=\<EnumDesc\>"
+ exec 'syn match javaC_JavaLang "\%(\<Character\.\)\@' . s:ff.Peek('10', '') . '<=\<Subset\>"'
+ exec 'syn match javaC_JavaLang "\%(\<Character\.\)\@' . s:ff.Peek('10', '') . '<=\<UnicodeBlock\>"'
+ exec 'syn match javaC_JavaLang "\%(\<ProcessBuilder\.\)\@' . s:ff.Peek('15', '') . '<=\<Redirect\>"'
+ exec 'syn match javaC_JavaLang "\%(\<ModuleLayer\.\)\@' . s:ff.Peek('12', '') . '<=\<Controller\>"'
+ exec 'syn match javaC_JavaLang "\%(\<Runtime\.\)\@' . s:ff.Peek('8', '') . '<=\<Version\>"'
+ exec 'syn match javaC_JavaLang "\%(\<System\.\)\@' . s:ff.Peek('7', '') . '<=\<LoggerFinder\>"'
+ exec 'syn match javaC_JavaLang "\%(\<Enum\.\)\@' . s:ff.Peek('5', '') . '<=\<EnumDesc\>"'
syn keyword javaC_JavaLang Boolean Character Class ClassLoader Compiler Double Float Integer Long Math Number Object Process Runtime SecurityManager String StringBuffer Thread ThreadGroup Byte Short Void InheritableThreadLocal Package RuntimePermission ThreadLocal StrictMath StackTraceElement Enum ProcessBuilder StringBuilder ClassValue Module ModuleLayer StackWalker Record
syn match javaC_JavaLang "\<System\>" " See javaDebug.
" As of JDK 21, java.lang.Compiler is no more (deprecated in JDK 9).
syn keyword javaLangDeprecated Compiler
- syn cluster javaTop add=javaC_JavaLang
syn cluster javaClasses add=javaC_JavaLang
hi def link javaC_JavaLang javaC_Java
syn keyword javaE_JavaLang AbstractMethodError ClassCircularityError ClassFormatError Error IllegalAccessError IncompatibleClassChangeError InstantiationError InternalError LinkageError NoClassDefFoundError NoSuchFieldError NoSuchMethodError OutOfMemoryError StackOverflowError ThreadDeath UnknownError UnsatisfiedLinkError VerifyError VirtualMachineError ExceptionInInitializerError UnsupportedClassVersionError AssertionError BootstrapMethodError
- syn cluster javaTop add=javaE_JavaLang
syn cluster javaClasses add=javaE_JavaLang
hi def link javaE_JavaLang javaE_Java
syn keyword javaX_JavaLang ClassNotFoundException CloneNotSupportedException Exception IllegalAccessException InstantiationException InterruptedException NoSuchMethodException Throwable NoSuchFieldException ReflectiveOperationException
- syn cluster javaTop add=javaX_JavaLang
syn cluster javaClasses add=javaX_JavaLang
hi def link javaX_JavaLang javaX_Java
@@ -152,10 +201,9 @@ if exists("java_highlight_all") || exists("java_highlight_java") || exists("ja
syn keyword javaLangObject clone equals finalize getClass hashCode
syn keyword javaLangObject notify notifyAll toString wait
hi def link javaLangObject javaConstant
- syn cluster javaTop add=javaLangObject
endif
-if filereadable(expand("<sfile>:p:h")."/javaid.vim")
+if filereadable(expand("<sfile>:p:h") . "/javaid.vim")
source <sfile>:p:h/javaid.vim
endif
@@ -168,7 +216,7 @@ if exists("java_space_errors")
endif
endif
-syn match javaUserLabel "^\s*\<\K\k*\>\%(\<default\>\)\@<!\s*:"he=e-1
+exec 'syn match javaUserLabel "^\s*\<\K\k*\>\%(\<default\>\)\@' . s:ff.Peek('7', '') . '<!\s*:"he=e-1'
syn region javaLabelRegion transparent matchgroup=javaLabel start="\<case\>" matchgroup=NONE end=":\|->" contains=javaLabelCastType,javaLabelNumber,javaCharacter,javaString,javaConstant,@javaClasses,javaLabelDefault,javaLabelVarType,javaLabelWhenClause
syn region javaLabelRegion transparent matchgroup=javaLabel start="\<default\>\%(\s*\%(:\|->\)\)\@=" matchgroup=NONE end=":\|->" oneline
" Consider grouped _default_ _case_ labels, i.e.
@@ -179,7 +227,7 @@ syn keyword javaLabelVarType contained var
syn keyword javaLabelCastType contained char byte short int
" Allow for the contingency of the enclosing region not being able to
" _keep_ its _end_, e.g. case ':':.
-syn region javaLabelWhenClause contained transparent matchgroup=javaLabel start="\<when\>" matchgroup=NONE end=":"me=e-1 end="->"me=e-2 contains=TOP,javaExternal
+syn region javaLabelWhenClause contained transparent matchgroup=javaLabel start="\<when\>" matchgroup=NONE end=":"me=e-1 end="->"me=e-2 contains=TOP,javaExternal,javaLambdaDef
syn match javaLabelNumber contained "\<0\>[lL]\@!"
syn match javaLabelNumber contained "\<\%(0\%([xX]\x\%(_*\x\)*\|_*\o\%(_*\o\)*\|[bB][01]\%(_*[01]\)*\)\|[1-9]\%(_*\d\)*\)\>[lL]\@!"
hi def link javaLabelDefault javaLabel
@@ -187,13 +235,6 @@ hi def link javaLabelVarType javaOperator
hi def link javaLabelNumber javaNumber
hi def link javaLabelCastType javaType
-" highlighting C++ keywords as errors removed, too many people find it
-" annoying. Was: if !exists("java_allow_cpp_keywords")
-
-" The following cluster contains all java groups except the contained ones
-syn cluster javaTop add=javaExternal,javaError,javaBranch,javaLabelRegion,javaConditional,javaRepeat,javaBoolean,javaConstant,javaTypedef,javaOperator,javaType,javaStatement,javaStorageClass,javaAssert,javaExceptions,javaMethodDecl,javaClassDecl,javaScopeDecl,javaConceptKind,javaError2,javaUserLabel,javaLangObject,javaAnnotation,javaVarArg
-
-
" Comments
syn keyword javaTodo contained TODO FIXME XXX
@@ -208,13 +249,13 @@ if exists("java_comment_strings")
syn cluster javaCommentSpecial2 add=javaComment2String,javaCommentCharacter,javaNumber,javaStrTempl
endif
-syn region javaComment matchgroup=javaCommentStart start="/\*" end="\*/" contains=@javaCommentSpecial,javaTodo,javaCommentError,javaSpaceError,@Spell
+syn region javaComment matchgroup=javaCommentStart start="/\*" end="\*/" contains=@javaCommentSpecial,javaTodo,javaCommentError,javaSpaceError,@Spell fold
syn match javaCommentStar contained "^\s*\*[^/]"me=e-1
syn match javaCommentStar contained "^\s*\*$"
syn match javaLineComment "//.*" contains=@javaCommentSpecial2,javaTodo,javaCommentMarkupTag,javaSpaceError,@Spell
syn match javaCommentMarkupTag contained "@\%(end\|highlight\|link\|replace\|start\)\>" nextgroup=javaCommentMarkupTagAttr,javaSpaceError skipwhite
syn match javaCommentMarkupTagAttr contained "\<region\>" nextgroup=javaCommentMarkupTagAttr,javaSpaceError skipwhite
-syn region javaCommentMarkupTagAttr contained transparent matchgroup=htmlArg start=/\<\%(re\%(gex\|gion\|placement\)\|substring\|t\%(arget\|ype\)\)\%(\s*=\)\@=/ matchgroup=htmlString end=/\%(=\s*\)\@<=\%("[^"]\+"\|'[^']\+'\|\%([.-]\|\k\)\+\)/ nextgroup=javaCommentMarkupTagAttr,javaSpaceError skipwhite oneline
+exec 'syn region javaCommentMarkupTagAttr contained transparent matchgroup=htmlArg start=/\<\%(re\%(gex\|gion\|placement\)\|substring\|t\%(arget\|ype\)\)\%(\s*=\)\@=/ matchgroup=htmlString end=/\%(=\s*\)\@' . s:ff.Peek('80', '') . '<=\%("[^"]\+"\|' . "\x27[^\x27]\\+\x27" . '\|\%([.-]\|\k\)\+\)/ nextgroup=javaCommentMarkupTagAttr,javaSpaceError skipwhite oneline'
hi def link javaCommentMarkupTagAttr htmlArg
hi def link javaCommentString javaString
hi def link javaComment2String javaString
@@ -223,20 +264,24 @@ syn match javaCommentError contained "/\*"me=e-1 display
hi def link javaCommentError javaError
hi def link javaCommentStart javaComment
-syn cluster javaTop add=javaComment,javaLineComment
-
if !exists("java_ignore_javadoc") && main_syntax != 'jsp'
syntax case ignore
- " syntax coloring for javadoc comments (HTML)
+
+ " Include HTML syntax coloring for Javadoc comments.
syntax include @javaHtml syntax/html.vim
unlet b:current_syntax
- " HTML enables spell checking for all text that is not in a syntax item. This
- " is wrong for Java (all identifiers would be spell-checked), so it's undone
- " here.
- syntax spell default
- syn region javaDocComment start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag,javaTodo,javaCommentError,javaSpaceError,@Spell
- syn region javaCommentTitle contained matchgroup=javaDocComment start="/\*\*" matchgroup=javaCommentTitle end="\.$" end="\.[ \t\r]\@=" end="\%(^\s*\**\s*\)\@<=@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@javaHtml,javaCommentStar,javaTodo,javaCommentError,javaSpaceError,@Spell,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag
+ " HTML enables spell checking for all text that is not in a syntax
+ " item (:syntax spell toplevel); instead, limit spell checking to
+ " items matchable with syntax groups containing the @Spell cluster.
+ try
+ syntax spell default
+ catch /\<E390:/
+ call s:ReportOnce(v:exception)
+ endtry
+
+ syn region javaDocComment start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag,javaTodo,javaCommentError,javaSpaceError,@Spell fold
+ exec 'syn region javaCommentTitle contained matchgroup=javaDocComment start="/\*\*" matchgroup=javaCommentTitle end="\.$" end="\.[ \t\r]\@=" end="\%(^\s*\**\s*\)\@' . s:ff.Peek('80', '') . '<=@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@javaHtml,javaCommentStar,javaTodo,javaCommentError,javaSpaceError,@Spell,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag'
syn region javaCommentTitle contained matchgroup=javaDocComment start="/\*\*\s*\r\=\n\=\s*\**\s*\%({@return\>\)\@=" matchgroup=javaCommentTitle end="}\%(\s*\.*\)*" contains=@javaHtml,javaCommentStar,javaTodo,javaCommentError,javaSpaceError,@Spell,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag
syn region javaDocTags contained start="{@\%(li\%(teral\|nk\%(plain\)\=\)\|inherit[Dd]oc\|doc[rR]oot\|value\)\>" end="}"
syn match javaDocTags contained "@\%(param\|exception\|throws\|since\)\s\+\S\+" contains=javaDocParam
@@ -246,9 +291,10 @@ if !exists("java_ignore_javadoc") && main_syntax != 'jsp'
syn match javaDocSeeTagParam contained @"\_[^"]\+"\|<a\s\+\_.\{-}</a>\|\%(\k\|\.\)*\%(#\k\+\%((\_[^)]*)\)\=\)\=@ contains=@javaHtml extend
syn region javaCodeSkipBlock contained transparent start="{\%(@code\>\)\@!" end="}" contains=javaCodeSkipBlock,javaDocCodeTag
syn region javaDocCodeTag contained start="{@code\>" end="}" contains=javaDocCodeTag,javaCodeSkipBlock
- syn region javaDocSnippetTagAttr contained transparent matchgroup=htmlArg start=/\<\%(class\|file\|id\|lang\|region\)\%(\s*=\)\@=/ matchgroup=htmlString end=/:$/ end=/\%(=\s*\)\@<=\%("[^"]\+"\|'[^']\+'\|\%([.\\/-]\|\k\)\+\)/ nextgroup=javaDocSnippetTagAttr skipwhite skipnl
+ exec 'syn region javaDocSnippetTagAttr contained transparent matchgroup=htmlArg start=/\<\%(class\|file\|id\|lang\|region\)\%(\s*=\)\@=/ matchgroup=htmlString end=/:$/ end=/\%(=\s*\)\@' . s:ff.Peek('80', '') . '<=\%("[^"]\+"\|' . "\x27[^\x27]\\+\x27" . '\|\%([.\\/-]\|\k\)\+\)/ nextgroup=javaDocSnippetTagAttr skipwhite skipnl'
syn region javaSnippetSkipBlock contained transparent start="{\%(@snippet\>\)\@!" end="}" contains=javaSnippetSkipBlock,javaDocSnippetTag,javaCommentMarkupTag
syn region javaDocSnippetTag contained start="{@snippet\>" end="}" contains=javaDocSnippetTag,javaSnippetSkipBlock,javaDocSnippetTagAttr,javaCommentMarkupTag
+
syntax case match
endif
@@ -264,10 +310,8 @@ syn region javaString start=+"+ end=+"+ end=+$+ contains=javaSpecialChar,javaS
syn region javaString start=+"""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaSpecialChar,javaSpecialError,javaTextBlockError,@Spell
syn match javaTextBlockError +"""\s*"""+
syn region javaStrTemplEmbExp contained matchgroup=javaStrTempl start="\\{" end="}" contains=TOP
-syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@<="+ end=+"+ contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,@Spell
-syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,javaTextBlockError,@Spell
-" The next line is commented out, it can cause a crash for a long line
-"syn match javaStringError +"\%([^"\\]\|\\.\)*$+
+exec 'syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="+ end=+"+ contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,@Spell'
+exec 'syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,javaTextBlockError,@Spell'
syn match javaCharacter "'[^']*'" contains=javaSpecialChar,javaSpecialCharError
syn match javaCharacter "'\\''" contains=javaSpecialChar
syn match javaCharacter "'[^\\]'"
@@ -286,36 +330,35 @@ syn match javaNumber "\<0[xX]\%(\x\%(_*\x\)*\.\=\|\%(\x\%(_*\x\)*\)\=\.\x\%(
" Unicode characters
syn match javaSpecial "\\u\x\x\x\x"
-syn cluster javaTop add=javaString,javaStrTempl,javaCharacter,javaNumber,javaSpecial,javaStringError,javaTextBlockError
-
" Method declarations (JLS-17, §8.4.3, §8.4.4, §9.4).
if exists("java_highlight_functions")
syn cluster javaFuncParams contains=javaAnnotation,@javaClasses,javaType,javaVarArg,javaComment,javaLineComment
- if java_highlight_functions == "indent"
+ if java_highlight_functions =~# '^indent[1-8]\=$'
+ let s:last = java_highlight_functions[-1 :]
+ let s:indent = s:last != 't' ? repeat("\x20", s:last) : "\t"
syn cluster javaFuncParams add=javaScopeDecl,javaConceptKind,javaStorageClass,javaExternal
- syn match javaFuncDef "^\%(\t\| \%( \{6\}\)\=\)\K\%(\k\|[ .,<>\[\]]\)*([^-+*/]*)" contains=@javaFuncParams
- syn region javaFuncDef start=+^\%(\t\| \%( \{6\}\)\=\)\K\%(\k\|[ .,<>\[\]]\)*([^-+*/]*,\s*+ end=+)+ contains=@javaFuncParams
+ " Try to not match other type members, initialiser blocks, enum
+ " constants (JLS-17, §8.9.1), and constructors (JLS-17, §8.1.7):
+ " at any _conventional_ indentation, skip over all fields with
+ " "[^=]*", all records with "\<record\s", and let the "*Skip*"
+ " definitions take care of constructor declarations and enum
+ " constants (with no support for @Foo(value = "bar")).
+ exec 'syn region javaFuncDef start=+^' . s:indent . '\%(<[^>]\+>\+\s\+\|\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)\+\)\=\%(\<\K\k*\>\.\)*\K\k*\>[^=]*\%(\<record\)\@' . s:ff.Peek('6', '') . '<!\s\K\k*\s*(+ end=+)+ contains=@javaFuncParams'
+ " As long as package-private constructors cannot be matched with
+ " javaFuncDef, do not look with javaConstructorSkipDeclarator for
+ " them.
+ exec 'syn match javaConstructorSkipDeclarator transparent +^' . s:indent . '\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)*p\%(ublic\|rotected\|rivate\)\s\+\%(<[^>]\+>\+\s\+\)\=\K\k*\s*\ze(+ contains=javaAnnotation,javaScopeDecl'
+ exec 'syn match javaEnumSkipArgumentativeConstant transparent +^' . s:indent . '\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)*\K\k*\s*\ze(+ contains=javaAnnotation'
+ unlet s:indent s:last
else
" This is the "style" variant (:help ft-java-syntax).
syn cluster javaFuncParams add=javaScopeDecl,javaConceptKind,javaStorageClass,javaExternal
" Match arbitrarily indented camelCasedName method declarations.
" Match: [@ɐ] [abstract] [<α, β>] Τʬ[<γ>][[][]] μʭʭ(/* ... */);
-
- if s:selectable_regexp_engine
- " Request the new regexp engine for [:upper:] and [:lower:].
- syn region javaFuncDef start=/\%#=2^\s\+\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)*\%(p\%(ublic\|rotected\|rivate\)\s\+\)\=\%(\%(abstract\|default\)\s\+\|\%(\%(final\|\%(native\|strictfp\)\|s\%(tatic\|ynchronized\)\)\s\+\)*\)\=\%(<.*[[:space:]-]\@1<!>\s\+\)\=\%(void\|\%(b\%(oolean\|yte\)\|char\|short\|int\|long\|float\|double\|\%(\<\K\k*\>\.\)*\<[$_[:upper:]]\k*\>\%(<[^(){}]*[[:space:]-]\@1<!>\)\=\)\%(\[\]\)*\)\s\+\<[$_[:lower:]]\k*\>\s*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=@javaFuncParams
- else
- " XXX: \C\<[^a-z0-9]\k*\> rejects "type", but matches "τύπος".
- " XXX: \C\<[^A-Z0-9]\k*\> rejects "Method", but matches "Μέθοδος".
- syn region javaFuncDef start=/^\s\+\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)*\%(p\%(ublic\|rotected\|rivate\)\s\+\)\=\%(\%(abstract\|default\)\s\+\|\%(\%(final\|\%(native\|strictfp\)\|s\%(tatic\|ynchronized\)\)\s\+\)*\)\=\%(<.*[[:space:]-]\@1<!>\s\+\)\=\%(void\|\%(b\%(oolean\|yte\)\|char\|short\|int\|long\|float\|double\|\%(\<\K\k*\>\.\)*\<[^a-z0-9]\k*\>\%(<[^(){}]*[[:space:]-]\@1<!>\)\=\)\%(\[\]\)*\)\s\+\<[^A-Z0-9]\k*\>\s*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=@javaFuncParams
- endif
+ exec 'syn region javaFuncDef start=/' . s:ff.Engine('\%#=2', '') . '^\s\+\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)*\%(p\%(ublic\|rotected\|rivate\)\s\+\)\=\%(\%(abstract\|default\)\s\+\|\%(\%(final\|\%(native\|strictfp\)\|s\%(tatic\|ynchronized\)\)\s\+\)*\)\=\%(<.*[[:space:]-]\@' . s:ff.Peek('1', '') . '<!>\s\+\)\=\%(void\|\%(b\%(oolean\|yte\)\|char\|short\|int\|long\|float\|double\|\%(\<\K\k*\>\.\)*\<' . s:ff.UpperCase('[$_[:upper:]]', '[^a-z0-9]') . '\k*\>\%(<[^(){}]*[[:space:]-]\@' . s:ff.Peek('1', '') . '<!>\)\=\)\%(\[\]\)*\)\s\+\<' . s:ff.LowerCase('[$_[:lower:]]', '[^A-Z0-9]') . '\k*\>\s*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=@javaFuncParams'
endif
-
- syn match javaLambdaDef "\<\K\k*\>\%(\<default\>\)\@<!\s*->"
- syn match javaBraces "[{}]"
- syn cluster javaTop add=javaFuncDef,javaBraces,javaLambdaDef
endif
if exists("java_highlight_debug")
@@ -326,10 +369,8 @@ if exists("java_highlight_debug")
" The highlight groups of java{StrTempl,Debug{,Paren,StrTempl}}\,
" share one colour by default. Do not conflate unrelated parens.
syn region javaDebugStrTemplEmbExp contained matchgroup=javaDebugStrTempl start="\\{" end="}" contains=javaComment,javaLineComment,javaDebug\%(Paren\)\@!.*
- syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@<="+ end=+"+ contains=javaDebugStrTemplEmbExp,javaDebugSpecial
- syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaDebugStrTemplEmbExp,javaDebugSpecial,javaDebugTextBlockError
- " The next line is commented out, it can cause a crash for a long line
-" syn match javaDebugStringError contained +"\%([^"\\]\|\\.\)*$+
+ exec 'syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="+ end=+"+ contains=javaDebugStrTemplEmbExp,javaDebugSpecial'
+ exec 'syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaDebugStrTemplEmbExp,javaDebugSpecial,javaDebugTextBlockError'
syn match javaDebugTextBlockError contained +"""\s*"""+
syn match javaDebugCharacter contained "'[^\\]'"
syn match javaDebugSpecialCharacter contained "'\\.'"
@@ -353,13 +394,10 @@ if exists("java_highlight_debug")
" FIXME: What API do "trace*" belong to?
" syn match javaDebug "\<trace[SL]\=\s*("me=e-1 contains=javaDebug.* nextgroup=javaDebugParen
- syn cluster javaTop add=javaDebug
-
hi def link javaDebug Debug
hi def link javaDebugString DebugString
hi def link javaDebugStrTempl Macro
- hi def link javaDebugStringError javaError
- hi def link javaDebugTextBlockError javaDebugStringError
+ hi def link javaDebugTextBlockError Error
hi def link javaDebugType DebugType
hi def link javaDebugBoolean DebugBoolean
hi def link javaDebugNumber Debug
@@ -375,15 +413,18 @@ if exists("java_highlight_debug")
endif
if exists("java_mark_braces_in_parens_as_errors")
- syn match javaInParen contained "[{}]"
- hi def link javaInParen javaError
- syn cluster javaTop add=javaInParen
+ syn match javaInParen contained "[{}]"
+ hi def link javaInParen javaError
endif
+" Try not to fold top-level-type bodies under assumption that there is
+" but one such body.
+exec 'syn region javaBlock transparent start="\%(^\|^\S[^:]\+\)\@' . s:ff.Peek('120', '') . '<!{" end="}" fold'
+
" catch errors caused by wrong parenthesis
-syn region javaParenT transparent matchgroup=javaParen start="(" end=")" contains=@javaTop,javaParenT1
-syn region javaParenT1 transparent matchgroup=javaParen1 start="(" end=")" contains=@javaTop,javaParenT2 contained
-syn region javaParenT2 transparent matchgroup=javaParen2 start="(" end=")" contains=@javaTop,javaParenT contained
+syn region javaParenT transparent matchgroup=javaParen start="(" end=")" contains=@javaTop,javaInParen,javaParenT1
+syn region javaParenT1 transparent matchgroup=javaParen1 start="(" end=")" contains=@javaTop,javaInParen,javaParenT2 contained
+syn region javaParenT2 transparent matchgroup=javaParen2 start="(" end=")" contains=@javaTop,javaInParen,javaParenT contained
syn match javaParenError ")"
" catch errors caused by wrong square parenthesis
syn region javaParenT transparent matchgroup=javaParen start="\[" end="\]" contains=@javaTop,javaParenT1
@@ -393,11 +434,32 @@ syn match javaParenError "\]"
hi def link javaParenError javaError
+" Lambda expressions (JLS-17, §15.27).
if exists("java_highlight_functions")
" Make ()-matching definitions after the parenthesis error catcher.
- syn match javaLambdaDef "\k\@4<!(\%(\k\|[[:space:]<>?\[\]@,.]\)*)\s*->"
+ "
+ " Match: ([@A [@B ...] final] var a[, var b, ...]) ->
+ " | ([@A [@B ...] final] T[<α>][[][]] a[, T b, ...]) ->
+ " There is no recognition of expressions interspersed with comments
+ " or of expressions whose parameterised parameter types are written
+ " across multiple lines.
+ exec 'syn match javaLambdaDef "\k\@' . s:ff.Peek('4', '') . '<!([[:space:]\n]*\%(\%(@\%(\K\k*\.\)*\K\k*\>\%((\_.\{-1,})\)\{-,1}[[:space:]\n]\+\)*\%(final[[:space:]\n]\+\)\=\%(\<\K\k*\>\.\)*\<\K\k*\>\%(<[^(){}]*[[:space:]-]\@' . s:ff.Peek('1', '') . '<!>\)\=\%(\%(\%(\[\]\)\+\|\.\.\.\)\)\=[[:space:]\n]\+\<\K\k*\>\%(\[\]\)*\%(,[[:space:]\n]*\)\=\)\+)[[:space:]\n]*->" contains=javaAnnotation,javaParamModifier,javaLambdaVarType,javaType,@javaClasses,javaVarArg'
+ " Match: () ->
+ " | (a[, b, ...]) ->
+ exec 'syn match javaLambdaDef "\k\@' . s:ff.Peek('4', '') . '<!([[:space:]\n]*\%(\<\K\k*\>\%(,[[:space:]\n]*\)\=\)*)[[:space:]\n]*->"'
+ " Match: a ->
+ exec 'syn match javaLambdaDef "\<\K\k*\>\%(\<default\>\)\@' . s:ff.Peek('7', '') . '<![[:space:]\n]*->"'
+
+ syn keyword javaParamModifier contained final
+ hi def link javaParamModifier javaConceptKind
+ syn keyword javaLambdaVarType contained var
+ hi def link javaLambdaVarType javaOperator
endif
+" The @javaTop cluster comprises non-contained Java syntax groups.
+" Note that the syntax file "aidl.vim" relies on its availability.
+syn cluster javaTop contains=TOP,javaDocComment,javaBlock,javaParenError,javaParenT
+
if !exists("java_minlines")
let java_minlines = 10
endif
@@ -414,7 +476,6 @@ exec "syn sync ccomment javaComment minlines=" . java_minlines
hi def link javaLambdaDef Function
hi def link javaFuncDef Function
hi def link javaVarArg Function
-hi def link javaBraces Function
hi def link javaBranch Conditional
hi def link javaUserLabelRef javaUserLabel
hi def link javaLabel Label
@@ -439,8 +500,7 @@ hi def link javaCharacter Character
hi def link javaSpecialChar SpecialChar
hi def link javaNumber Number
hi def link javaError Error
-hi def link javaStringError Error
-hi def link javaTextBlockError javaStringError
+hi def link javaTextBlockError Error
hi def link javaStatement Statement
hi def link javaOperator Operator
hi def link javaComment Comment
@@ -450,6 +510,7 @@ hi def link javaConstant Constant
hi def link javaTypedef Typedef
hi def link javaTodo Todo
hi def link javaAnnotation PreProc
+hi def link javaAnnotationStart javaAnnotation
hi def link javaCommentTitle SpecialComment
hi def link javaDocTags Special
@@ -482,6 +543,22 @@ endif
let b:spell_options = "contained"
let &cpo = s:cpo_save
-unlet s:selectable_regexp_engine s:module_info_cur_buf s:cpo_save
+unlet s:module_info_cur_buf s:ff s:cpo_save
+
+" See ":help vim9-mix".
+if !has("vim9script")
+ finish
+endif
-" vim: ts=8
+def! s:JavaSyntaxFoldTextExpr(): string
+ return getline(v:foldstart) !~ '/\*\+\s*$'
+ ? foldtext()
+ : printf('+-%s%3d lines: ',
+ v:folddashes,
+ (v:foldend - v:foldstart + 1)) ..
+ getline(v:foldstart + 1)
+enddef
+
+setlocal foldtext=s:JavaSyntaxFoldTextExpr()
+delfunction! g:JavaSyntaxFoldTextExpr
+" vim: sw=2 ts=8 noet sta
diff --git a/runtime/syntax/jj.vim b/runtime/syntax/jj.vim
new file mode 100644
index 0000000..a2911a0
--- /dev/null
+++ b/runtime/syntax/jj.vim
@@ -0,0 +1,20 @@
+" Vim syntax file
+" Language: jj description
+" Maintainer: Gregory Anders <greg@gpanders.com>
+" Last Change: 2024 May 8
+
+if exists('b:current_syntax')
+ finish
+endif
+let b:current_syntax = 'jj'
+
+syn match jjAdded "A .*" contained
+syn match jjRemoved "D .*" contained
+syn match jjChanged "M .*" contained
+
+syn region jjComment start="^JJ: " end="$" contains=jjAdded,jjRemoved,jjChanged
+
+hi def link jjComment Comment
+hi def link jjAdded Added
+hi def link jjRemoved Removed
+hi def link jjChanged Changed
diff --git a/runtime/syntax/kdl.vim b/runtime/syntax/kdl.vim
new file mode 100644
index 0000000..97e8f93
--- /dev/null
+++ b/runtime/syntax/kdl.vim
@@ -0,0 +1,48 @@
+" Vim syntax file
+" Language: KDL
+" Maintainer: Aram Drevekenin <aram@poor.dev>
+" Maintainer: Yinzuo Jiang <jiangyinzuo@foxmail.com>
+" Latest Revision: 2024-06-16
+
+" quit when a syntax file was already loaded
+if exists("b:current_syntax")
+ finish
+endif
+
+syn match kdlNode '\v(\w|-|\=)' display
+syn match kdlBool '\v(true|false)' display
+
+syn keyword kdlTodo contained TODO FIXME XXX NOTE
+syn region kdlComment start="//" end="$" contains=kdlTodo,@Spell
+syn region kdlComment start="/\*" end="\*/" contains=kdlTodo,@Spell
+
+" Regular int like number with - + or nothing in front
+syn match kdlNumber '\d\+'
+syn match kdlNumber '[-+]\d\+'
+
+" Floating point number with decimal no E or e (+,-)
+syn match kdlNumber '\d\+\.\d*' contained display
+syn match kdlNumber '[-+]\d\+\.\d*' contained display
+
+" Floating point like number with E and no decimal point (+,-)
+syn match kdlNumber '[-+]\=\d[[:digit:]]*[eE][\-+]\=\d\+' contained display
+syn match kdlNumber '\d[[:digit:]]*[eE][\-+]\=\d\+' contained display
+
+" Floating point like number with E and decimal point (+,-)
+syn match kdlNumber '[-+]\=\d[[:digit:]]*\.\d*[eE][\-+]\=\d\+' contained display
+syn match kdlNumber '\d[[:digit:]]*\.\d*[eE][\-+]\=\d\+' contained display
+
+syn region kdlString start='"' end='"' skip='\\\\\|\\"' display
+
+syn region kdlChildren start="{" end="}" contains=kdlString,kdlNumber,kdlNode,kdlBool,kdlComment
+
+hi def link kdlTodo Todo
+hi def link kdlComment Comment
+hi def link kdlNode Statement
+hi def link kdlBool Boolean
+hi def link kdlString String
+hi def link kdlNumber Number
+
+let b:current_syntax = "kdl"
+
+" vim: sw=2 sts=2 et
diff --git a/runtime/syntax/lc.vim b/runtime/syntax/lc.vim
index a334529..1991c1b 100644
--- a/runtime/syntax/lc.vim
+++ b/runtime/syntax/lc.vim
@@ -2,6 +2,7 @@
" Language: Elsa
" Maintainer: Miles Glapa-Grossklag <miles@glapa-grossklag.com>
" Last Change: 2023-01-29
+" 2024 May 25 by Riley Bruins <ribru17@gmail.com> (move 'commentstring' to ftplugin)
if exists('b:current_syntax')
finish
@@ -13,7 +14,6 @@ syntax match elsaKeyword "\v:"
highlight link elsaKeyword Keyword
" Comments
-setlocal commentstring=--%s
syntax match elsaComment "\v--.*$"
highlight link elsaComment Comment
diff --git a/runtime/syntax/mma.vim b/runtime/syntax/mma.vim
index d2f22e9..802cbe5 100644
--- a/runtime/syntax/mma.vim
+++ b/runtime/syntax/mma.vim
@@ -2,6 +2,7 @@
" Language: Mathematica
" Maintainer: steve layland <layland@wolfram.com>
" Last Change: 2012 Feb 03 by Thilo Six
+" 2024 May 24 by Riley Bruins <ribru17@gmail.com> (remove 'commentstring')
" Source: http://members.wri.com/layland/vim/syntax/mma.vim
" http://vim.sourceforge.net/scripts/script.php?script_id=1273
" Id: $Id: mma.vim,v 1.4 2006/04/14 20:40:38 vimboss Exp $
@@ -248,7 +249,6 @@ syntax match mmaBoring "[(){}]" contained
"syntax region mmaRegion start="(\*\+[^<]*<!--[^>]*\*\+)" end="--> \*)" containedin=ALLBUT,@mmaStrings transparent fold keepend
" show fold text
-set commentstring='(*%s*)'
"set foldtext=MmaFoldText()
"function MmaFoldText()
diff --git a/runtime/syntax/rasi.vim b/runtime/syntax/rasi.vim
new file mode 100644
index 0000000..40c3393
--- /dev/null
+++ b/runtime/syntax/rasi.vim
@@ -0,0 +1,298 @@
+" Vim syntax file
+" Language: rasi (Rofi Advanced Style Information)
+" Maintainer: Pierrick Guillaume <pierguill@gmail.com>
+" Last Change: 2024 May 21
+"
+" Syntax support for rasi config file
+
+" This file is based on syntax defined in rofi-theme man page
+" https://man.archlinux.org/man/community/rofi/rofi-theme.5.en
+
+if exists('b:current_syntax')
+ finish
+endif
+let b:current_syntax = 'rasi'
+
+" String {{{
+syn region rasiString start=+"+ skip=+\\"+ end=+"+ oneline contained
+syn match rasiCharacter +L\='[^\\]'+ contained
+
+syn cluster rasiPropertyVals add=rasiString,rasiCharacter
+" }}}
+
+" Integer/Real {{{
+syn match rasiNumber display contained '[+-]\?\d\+\(\.\d\+\)\?'
+
+syn cluster rasiPropertyVals add=rasiNumber
+" }}}
+
+" Boolean {{{
+syn keyword rasiBool contained true false
+
+syn cluster rasiPropertyVals add=rasiBool
+" }}}
+
+" Image {{{
+syn match rasiInvImage display contained 'url([^)]*)'
+syn keyword rasiImageK contained url linear-gradient
+
+syn match rasiImage display contained transparent 'url(\s*"\([^"]\|\\"\)\+"\(\s*,\s*\(none\|both\|width\|height\)\)\?\s*)' contains=rasiImageScale,rasiString,rasiImageK
+syn keyword rasiImageScale contained none both width height
+
+syn match rasiImage display contained transparent 'linear-gradient(\s*\(\(top\|left\|right\|bottom\)\s*,\s*\)\?[^,)]\+\s*\(,\s*[^,)]\+\s*\)\+)' contains=rasiImageDirection,@rasiColors,rasiImageK
+syn keyword rasiImageDirection contained top left right bottom
+
+syn match rasiImage display contained transparent 'linear-gradient(\s*\d\+\(rad\|grad\|deg\)\s*,\s*[^,)]\+\s*\(,\s*[^,)]\+\s*\)\+)' contains=rasiImageUnit,@rasiColor,@rasiInvColor,rasiNumber,rasiImageK
+syn match rasiImageUnit display contained '\(rad\|grad\|deg\)\>'
+
+syn cluster rasiPropertyVals add=rasiInvImage,rasiImage
+" }}}
+
+" Reference {{{
+syn match rasiReference display contained '@[a-zA-Z0-9-]\+'
+
+syn keyword rasiVarReferenceK contained var
+
+syn match rasiInvVarReference display contained 'var([^)]*)'
+syn match rasiVarReference display contained transparent 'var(\s*[a-zA-Z0-9-]\+\s*,\s*\(\a\+\s*([^)]*)\)\?[^),]*)' contains=rasiVarReferenceK,rasiPropertyIdRef,@rasiPropertyVals
+syn match rasiPropertyIdRef display contained '\a[a-zA-Z0-9-]*'
+
+syn cluster rasiPropertyVals add=rasiReference,rasiInvVarReference,rasiVarReference
+" }}}
+
+" Env variable {{{
+syn match rasiInvEnv display contained '${[^}]*}'
+syn match rasiEnv display contained '${\w\+}'hs=s+2,he=e-1
+
+syn keyword rasiEnvVarK contained env
+
+syn match rasiInvEnvVar display contained 'env([^)]*)'
+syn match rasiEnvVar display contained transparent 'env(\s*\w\+\s*,\s*\(\a\+([^)]*)\)\?[^),]*)' contains=rasiEnvVarK,rasiEnvRef,@rasiPropertyVals
+syn match rasiEnvRef display contained '\a\w*'
+
+syn cluster rasiPropertyVals add=rasiEnv,rasiInvEnv,rasiInvEnvVar,rasiEnvVar
+" }}}
+
+" Color {{{
+syn keyword rasiColorK contained rgb[a] hsl[a] hwb[a] cmyk
+
+syn match rasiHexColor display contained '#\x\{3,4}'
+syn match rasiHexColor display contained '#\x\{6}'
+syn match rasiHexColor display contained '#\x\{8}'
+syn match rasiInvHexColor display contained '#\x\{5}\X'he=e-1,me=e-1
+syn match rasiInvHexColor display contained '#\x\{7}\X'he=e-1,me=e-1
+
+syn match rasiInvRGBColor display contained 'rgb\(a\)\?([^)]*)'
+syn match rasiRGBColor display contained transparent 'rgb\(a\)\?(\s*\d\+\s*\(%\)\?\s*,\(\s*\d\+\s*\(%\)\?\s*\){2}\(,\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\)\?)' contains=rasiColorK,rasiNumber,rasiDistance
+
+syn match rasiInvHSLColor display contained 'h\(sl\|wb\)\(a\)\?([^)]*)'
+syn match rasiHSLColor display contained transparent 'h\(sl\|wb\)\(a\)\?(\s*\d\+\(\.\d*\)\?\(deg\|rad\|grad\|turn\)\?\s*\(,\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\)\{2,3})' contains=rasiColorK,rasiNumber,rasiDistance
+
+
+"this matches doesn't works properly (too long ?)
+syn match rasiInvCMYKColor display contained 'cmyk([^)]*)'
+syn match rasiCMYKColor display contained transparent 'cmyk(\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\(,\s*\(\d\(\.\d*\)\?\|\d\{,3}%\)\s*\)\{3,4})' contains=rasiColorK,rasiNumber,rasiDistance
+
+syn case ignore
+syn keyword rasiNamedColor contained
+ \ AliceBlue AntiqueWhite Aqua Aquamarine Azure Beige Bisque Black BlanchedAlmond Blue
+ \ BlueViolet Brown BurlyWood CadetBlue Chartreuse Chocolate Coral CornflowerBlue Cornsilk
+ \ Crimson Cyan DarkBlue DarkCyan DarkGoldenRod DarkGray DarkGrey DarkGreen DarkKhaki DarkMagenta
+ \ DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen Dark SlateBlue
+ \ DarkSlateGray DarkSlateGrey DarkTurquoise DarkViolet DeepPink DeepSkyBlue DimGray DimGrey
+ \ DodgerBlue FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite Gold GoldenRod
+ \ Gray Grey Green GreenYellow HoneyDew HotPink IndianRed Indigo Ivory Khaki Lavender
+ \ LavenderBlush LawnGreen LemonChiffon LightBlue LightCoral LightCyan LightGoldenRodYellow
+ \ LightGray LightGrey LightGreen LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray
+ \ LightSlateGrey LightSteelBlue LightYellow Lime LimeGreen Linen Magenta Maroon MediumAquaMarine
+ \ MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen
+ \ MediumTurquoise MediumVioletRed MidnightBlue MintCream MistyRose Moccasin NavajoWhite Navy
+ \ OldLace Olive OliveDrab Orange OrangeRed Orchid PaleGoldenRod PaleGreen PaleTurquoise
+ \ PaleVioletRed PapayaWhip PeachPuff Peru Pink Plum PowderBlue Purple RebeccaPurple Red
+ \ RosyBrown RoyalBlue SaddleBrown Salmon SandyBrown SeaGreen SeaShell Sienna Silver SkyBlue
+ \ SlateBlue SlateGray SlateGrey Snow SpringGreen SteelBlue Tan Teal Thistle Tomato Turquoise
+ \ Violet Wheat White WhiteSmoke Yellow YellowGreen transparent[] "uses `[]` to escape keyword
+
+syn cluster rasiColors add=rasiHexColor,rasiRGBColor,rasiHSLColor,rasiCMYKColor,rasiNamedColor
+syn cluster rasiColors add=rasiInvHexColor,rasiInvRGBColor,rasiInvHSLColor,rasiInvCMYKColor
+
+syn cluster rasiPropertyVals add=@rasiColors
+" }}}
+
+" Text-Style {{{
+syn keyword rasiTextStyle contained bold italic underline strikethrough none
+
+syn cluster rasiPropertyVals add=rasiTextStyle
+" }}}
+
+" Line-Style {{{
+syn keyword rasiLineStyle contained dash solid
+
+syn cluster rasiPropertyVals add=rasiLineStyle
+" }}}
+
+" Distance {{{
+syn match rasiDistanceUnit display contained '\(px\|em\|ch\|%\|mm\)'
+
+syn match rasiInvDistance display contained '[+-]\?\d\+\.\d\+\(px\|mm\)'
+syn match rasiDistance display contained transparent '[-+]\?\d\+\(px\|mm\)' contains=rasiDistanceUnit,rasiNumber
+syn match rasiDistance display contained transparent '[+-]\?\d\+\(\.\d\+\)\?\(em\|ch\|%\)' contains=rasiDistanceUnit,rasiNumber
+
+syn keyword rasiDistanceCalc contained calc nextgroup=rasiDistanceCalcBody
+syn region rasiDistanceCalcBody display contained start=+(+ end=+)+ contains=rasiDistanceCalcOp,rasiDistance,rasiInvDistance
+syn match rasiDistanceCalcOp display contained '\(+\|-\|/\|\*\|%\|min\|max\)'
+
+syn cluster rasiPropertyVals add=rasiInvDistance,rasiDistance,rasiDistanceCalc
+" }}}
+
+" Position {{{
+syn keyword rasiPosition contained center east north west south
+
+syn cluster rasiPropertyVals add=rasiPosition
+" }}}
+
+" Orientation {{{
+syn keyword rasiOrientation contained horizontal vertical
+
+syn cluster rasiPropertyVals add=rasiOrientation
+" }}}
+
+" Cursor {{{
+syn keyword rasiCursor contained default pointer text
+
+syn cluster rasiPropertyVals add=rasiCursor
+" }}}
+
+" Keyword List {{{
+syn region rasiKeywordList contained start=+\[+ end=+\]+ contains=rasiPropertyIdRef
+
+syn cluster rasiPropertyVals add=rasiKeywordList
+" }}}
+
+" Inherit {{{
+syn keyword rasiInherit contained inherit children
+
+syn cluster rasiPropertyVals add=rasiInherit
+" }}}
+
+syn match rasiGlobalImport display '^\s*@\(import\|theme\)' nextgroup=rasiString skipwhite
+
+" Section {{{
+" syn region rasiSection transparent start='^[^{]\+{'me=e-1 end='}' contains=rasiSectionOpenning,rasiSectionContent
+syn match rasiSectionOpenning transparent '^[^{]\+{'me=e-1 contains=rasiGlobalSection,rasiWidgetName,rasiGlobalMedia nextgroup=rasiThemeSectionContent
+" syn match rasiThemeInnerSectionOpenning transparent '^[^:${]\+{'me=e-1 contains=rasiWidgetName nextgroup=rasiThemeInnerSectionContent contained
+
+syn match rasiGlobalMedia display contained '^\s*@media' nextgroup=rasiInvMediaBody,rasiMediaBody skipwhite
+syn match rasiInvMediaBody display contained '([^)]*)'
+syn match rasiMediaBody display contained '(\s*[a-z-]\+\s*:\s*\d\+\(px\|mm\)\?\s*)' contains=rasiMediaK,rasiNumber,rasiDistance
+syn keyword rasiMediaK contained min-width max-width min-height max-height min-aspect-ratio max-aspect-ratio monitor-id
+
+syn match rasiGlobalSection display contained '^*'
+syn match rasiWidgetName display contained '[a-zA-Z0-9-]\+' nextgroup=rasiVisibleMod skipwhite
+
+syn keyword rasiVisibleMod contained normal selected alternate nextgroup=rasiVisibleMod,rasiStateWrapper skipwhite
+syn match rasiStateWrapper display contained transparent '\.\(normal\|active\|urgent\)' contains=rasiState
+syn keyword rasiState contained normal active urgent
+
+
+syn region rasiThemeSectionContent transparent start="{" end="}" contains=rasiProperty,rasiComment,rasiCommentL,rasiSectionOpenning contained
+" syn region rasiThemeInnerSectionContent transparent start="{" end="}" contains=rasiProperty,rasiComment,rasiCommentL,rasiThemeInnerSectionOpenning contained
+
+syn match rasiProperty transparent '^\s*\S\+\s*:.*;\s*$' keepend contained contains=rasiPropertyId,rasiInvPropertyId,rasiPropertyVal,rasiComment,rasiCommentL
+syn match rasiInvPropertyId '^\([^:]\&[^/]\{2}\)*:'me=e-1 contained
+syn match rasiPropertyId '^\s*[0-9a-zA-Z-]\+\s*:'me=e-1 contained
+syn match rasiInvPropertyVal ':[^;];\s*\S\+\s*$'ms=s+1,hs=s+1
+syn match rasiPropertyVal ':\s*[^;]\+;\s*$'ms=s+1,hs=s+1 contained contains=@rasiPropertyVals
+" }}}
+
+" Comment {{{
+syn cluster rasiCommentGroup contains=rasiTodo,rasiBadContinuation
+
+syn region rasiCommentL start="//" skip="\\$" end="$" keepend contains=@rasiCommentGroup,@Spell
+syn region rasiComment start="/\*" end="\*/" contains=@rasiCommentGroup,rasiCommentStartError,@Spell fold extend
+
+syn match rasiCommentError display '\*/'
+
+syn keyword rasiTodo contained TODO FIXME XXX NOTE
+
+if exists("rasi_minlines")
+ let b:rasi_minlines = rasi_minlines
+else
+ let b:rasi_minlines = 50
+endif
+exec "syn sync ccomment rasiComment minlines=" . b:rasi_minlines
+" }}}
+
+
+
+" Highlighting: {{{
+hi def link rasiError Error
+
+hi def link rasiTodo Todo
+hi def link rasiComment Comment
+hi def link rasiCommentStart rasiComment
+hi def link rasiCommentL rasiComment
+hi def link rasiCommentError rasiError
+
+hi def link rasiString String
+hi def link rasiNumber Number
+hi def link rasiBool Boolean
+
+hi def link rasiImageK Function
+hi def link rasiImageScale Keyword
+hi def link rasiImageDirection Keyword
+hi def link rasiImageUnit Type
+hi def link rasiInvImage rasiError
+
+hi def link rasiHexColor Number
+hi def link rasiColorK Function
+hi def link rasiNamedColor Number
+hi def link rasiInvColor rasiError
+hi def link rasiInvHexColor rasiInvColor
+hi def link rasiInvRGBColor rasiInvColor
+hi def link rasiInvHSLColor rasiInvColor
+hi def link rasiInvCMYKColor rasiInvColor
+
+hi def link rasiTextStyle Keyword
+hi def link rasiLineStyle Keyword
+
+hi def link rasiDistanceUnit Type
+hi def link rasiDistanceCalc Function
+hi def link rasiDistanceCalcOp Operator
+hi def link rasiInvDistance rasiError
+
+hi def link rasiPosition Keyword
+hi def link rasiOrientation Keyword
+hi def link rasiCursor Keyword
+
+hi def link rasiReference Identifier
+hi def link rasiPropertyIdRef Identifier
+hi def link rasiVarReferenceK Function
+hi def link rasiInvVarReference rasiError
+
+hi def link rasiEnv Identifier
+hi def link rasiEnvRef Identifier
+hi def link rasiEnvVarK Function
+hi def link rasiInvEnv rasiError
+hi def link rasiInvEnvVar rasiError
+
+hi def link rasiWidgetName StorageClass
+hi def link rasiGlobalSection StorageClass
+hi def link rasiVisibleMod Type
+hi def link rasiState Tag
+
+hi def link rasiInherit Identifier
+
+hi def link rasiGlobalImport Include
+
+hi def link rasiGlobalMedia Preproc
+hi def link rasiMediaK Keyword
+hi def link rasiInvMediaBody rasiError
+
+hi def link rasiPropertyId Identifier
+hi def link rasiInvProperty rasiError
+hi def link rasiInvPropertyId rasiError
+hi def link rasiInvPropertyVal rasiError
+" }}}
+
+" vim:ts=8
diff --git a/runtime/syntax/shared/debversions.vim b/runtime/syntax/shared/debversions.vim
index e18eca9..56f18b9 100644
--- a/runtime/syntax/shared/debversions.vim
+++ b/runtime/syntax/shared/debversions.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: Debian version information
" Maintainer: Debian Vim Maintainers
-" Last Change: 2024 Apr 27
+" Last Change: 2024 May 25
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/syntax/shared/debversions.vim
let s:cpo = &cpo
@@ -11,7 +11,7 @@ let g:debSharedSupportedVersions = [
\ 'oldstable', 'stable', 'testing', 'unstable', 'experimental', 'sid', 'rc-buggy',
\ 'bullseye', 'bookworm', 'trixie', 'forky',
\
- \ 'trusty', 'xenial', 'bionic', 'focal', 'jammy', 'mantic', 'noble', 'oracular',
+ \ 'focal', 'jammy', 'mantic', 'noble', 'oracular',
\ 'devel'
\ ]
let g:debSharedUnsupportedVersions = [
@@ -22,8 +22,9 @@ let g:debSharedUnsupportedVersions = [
\ 'warty', 'hoary', 'breezy', 'dapper', 'edgy', 'feisty',
\ 'gutsy', 'hardy', 'intrepid', 'jaunty', 'karmic', 'lucid',
\ 'maverick', 'natty', 'oneiric', 'precise', 'quantal', 'raring', 'saucy',
- \ 'utopic', 'vivid', 'wily', 'yakkety', 'zesty', 'artful', 'cosmic',
- \ 'disco', 'eoan', 'hirsute', 'impish', 'kinetic', 'lunar', 'groovy'
+ \ 'trusty', 'utopic', 'vivid', 'wily', 'xenial', 'yakkety', 'zesty',
+ \ 'artful', 'bionic', 'cosmic', 'disco', 'eoan', 'hirsute',
+ \ 'impish', 'kinetic', 'lunar', 'groovy'
\ ]
let &cpo=s:cpo
diff --git a/runtime/syntax/shared/typescriptcommon.vim b/runtime/syntax/shared/typescriptcommon.vim
index d065251..3af79a3 100644
--- a/runtime/syntax/shared/typescriptcommon.vim
+++ b/runtime/syntax/shared/typescriptcommon.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: TypeScript and TypeScriptReact
" Maintainer: Herrington Darkholme
-" Last Change: 2023 Aug 24
+" Last Change: 2024 May 24
" Based On: Herrington Darkholme's yats.vim
" Changes: See https://github.com/HerringtonDarkholme/yats.vim
" Credits: See yats.vim on github
@@ -49,13 +49,13 @@ syntax match typescriptProp contained /\K\k*!\?/
\ nextgroup=@afterIdentifier
\ skipwhite skipempty
-syntax region typescriptIndexExpr contained matchgroup=typescriptProperty start=/\[/rs=s+1 end=/]/he=e-1 contains=@typescriptValue nextgroup=@typescriptSymbols,typescriptDotNotation,typescriptFuncCallArg skipwhite skipempty
+syntax region typescriptIndexExpr contained matchgroup=typescriptProperty start=/\[/ end=/]/ contains=@typescriptValue,typescriptCastKeyword nextgroup=@typescriptSymbols,typescriptDotNotation,typescriptFuncCallArg skipwhite skipempty
syntax match typescriptDotNotation /\.\|?\.\|!\./ nextgroup=typescriptProp skipnl
syntax match typescriptDotStyleNotation /\.style\./ nextgroup=typescriptDOMStyle transparent
" syntax match typescriptFuncCall contained /[a-zA-Z]\k*\ze(/ nextgroup=typescriptFuncCallArg
syntax region typescriptParenExp matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptComments,@typescriptValue,typescriptCastKeyword nextgroup=@typescriptSymbols skipwhite skipempty
-syntax region typescriptFuncCallArg contained matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptValue,@typescriptComments nextgroup=@typescriptSymbols,typescriptDotNotation skipwhite skipempty skipnl
+syntax region typescriptFuncCallArg contained matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptValue,@typescriptComments,typescriptCastKeyword nextgroup=@typescriptSymbols,typescriptDotNotation skipwhite skipempty skipnl
syntax region typescriptEventFuncCallArg contained matchgroup=typescriptParens start=/(/ end=/)/ contains=@typescriptEventExpression
syntax region typescriptEventString contained start=/\z(["']\)/ skip=/\\\\\|\\\z1\|\\\n/ end=/\z1\|$/ contains=typescriptASCII,@events
@@ -116,20 +116,33 @@ syntax match typescriptASCII contained /\\\d\d\d/
syntax region typescriptTemplateSubstitution matchgroup=typescriptTemplateSB
\ start=/\${/ end=/}/
- \ contains=@typescriptValue
+ \ contains=@typescriptValue,typescriptCastKeyword
\ contained
-syntax region typescriptString
+syntax region typescriptString
\ start=+\z(["']\)+ skip=+\\\%(\z1\|$\)+ end=+\z1+ end=+$+
\ contains=typescriptSpecial,@Spell
+ \ nextgroup=@typescriptSymbols
+ \ skipwhite skipempty
\ extend
syntax match typescriptSpecial contained "\v\\%(x\x\x|u%(\x{4}|\{\x{1,6}})|c\u|.)"
-" From vim runtime
-" <https://github.com/vim/vim/blob/master/runtime/syntax/javascript.vim#L48>
-syntax region typescriptRegexpString start=+/[^/*]+me=e-1 skip=+\\\\\|\\/+ end=+/[gimuy]\{0,5\}\s*$+ end=+/[gimuy]\{0,5\}\s*[;.,)\]}:]+me=e-1 nextgroup=typescriptDotNotation oneline
+" From pangloss/vim-javascript
+" <https://github.com/pangloss/vim-javascript/blob/d6e137563c47fb59f26ed25d044c0c7532304f18/syntax/javascript.vim#L64-L72>
+syntax region typescriptRegexpCharClass contained start=+\[+ skip=+\\.+ end=+\]+ contains=typescriptSpecial extend
+syntax match typescriptRegexpBoundary contained "\v\c[$^]|\\b"
+syntax match typescriptRegexpBackRef contained "\v\\[1-9]\d*"
+syntax match typescriptRegexpQuantifier contained "\v[^\\]%([?*+]|\{\d+%(,\d*)?})\??"lc=1
+syntax match typescriptRegexpOr contained "|"
+syntax match typescriptRegexpMod contained "\v\(\?[:=!>]"lc=1
+syntax region typescriptRegexpGroup contained start="[^\\]("lc=1 skip="\\.\|\[\(\\.\|[^]]\+\)\]" end=")" contains=typescriptRegexpCharClass,@typescriptRegexpSpecial keepend
+syntax region typescriptRegexpString
+ \ start=+\%(\%(\<return\|\<typeof\|\_[^)\]'"[:blank:][:alnum:]_$]\)\s*\)\@<=/\ze[^*/]+ skip=+\\.\|\[[^]]\{1,}\]+ end=+/[gimyus]\{,6}+
+ \ contains=typescriptRegexpCharClass,typescriptRegexpGroup,@typescriptRegexpSpecial
+ \ oneline keepend extend
+syntax cluster typescriptRegexpSpecial contains=typescriptSpecial,typescriptRegexpBoundary,typescriptRegexpBackRef,typescriptRegexpQuantifier,typescriptRegexpOr,typescriptRegexpMod
syntax region typescriptTemplate
\ start=/`/ skip=/\\\\\|\\`\|\n/ end=/`\|$/
@@ -140,7 +153,7 @@ syntax region typescriptTemplate
"Array
syntax region typescriptArray matchgroup=typescriptBraces
\ start=/\[/ end=/]/
- \ contains=@typescriptValue,@typescriptComments
+ \ contains=@typescriptValue,@typescriptComments,typescriptCastKeyword
\ nextgroup=@typescriptSymbols,typescriptDotNotation
\ skipwhite skipempty fold
@@ -153,7 +166,7 @@ syntax match typescriptNumber /\<\%(\d[0-9_]*\%(\.\d[0-9_]*\)\=\|\.\d[0-9_]*\)\%
syntax region typescriptObjectLiteral matchgroup=typescriptBraces
\ start=/{/ end=/}/
- \ contains=@typescriptComments,typescriptObjectLabel,typescriptStringProperty,typescriptComputedPropertyName,typescriptObjectAsyncKeyword
+ \ contains=@typescriptComments,typescriptObjectLabel,typescriptStringProperty,typescriptComputedPropertyName,typescriptObjectAsyncKeyword,typescriptTernary,typescriptCastKeyword
\ fold contained
syntax keyword typescriptObjectAsyncKeyword async contained
@@ -223,11 +236,11 @@ syntax match typescriptBinaryOp contained /\*\*=\?/ nextgroup=@typescriptValue
syntax cluster typescriptSymbols contains=typescriptBinaryOp,typescriptKeywordOp,typescriptTernary,typescriptAssign,typescriptCastKeyword
-" runtime syntax/basic/reserved.vim
+" runtime syntax/ts-common/reserved.vim
"Import
syntax keyword typescriptImport from as
syntax keyword typescriptImport import
- \ nextgroup=typescriptImportType
+ \ nextgroup=typescriptImportType,typescriptTypeBlock,typescriptDefaultImportName
\ skipwhite
syntax keyword typescriptImportType type
\ contained
@@ -238,20 +251,11 @@ syntax match typescriptExportType /\<type\s*{\@=/
\ contained skipwhite skipempty skipnl
syntax keyword typescriptModule namespace module
-"this
-
-"JavaScript Prototype
-syntax keyword typescriptPrototype prototype
- \ nextgroup=@afterIdentifier
-syntax keyword typescriptCastKeyword as
+syntax keyword typescriptCastKeyword as satisfies
\ nextgroup=@typescriptType
\ skipwhite
-"Program Keywords
-syntax keyword typescriptIdentifier arguments this super
- \ nextgroup=@afterIdentifier
-
syntax keyword typescriptVariable let var
\ nextgroup=@typescriptVariableDeclarations
\ skipwhite skipempty
@@ -260,6 +264,10 @@ syntax keyword typescriptVariable const
\ nextgroup=typescriptEnum,@typescriptVariableDeclarations
\ skipwhite skipempty
+syntax keyword typescriptUsing using
+ \ nextgroup=@typescriptVariableDeclarations
+ \ skipwhite skipempty
+
syntax region typescriptEnum matchgroup=typescriptEnumKeyword start=/enum / end=/\ze{/
\ nextgroup=typescriptBlock
\ skipwhite
@@ -272,7 +280,6 @@ syntax keyword typescriptOperator delete new typeof void
syntax keyword typescriptForOperator contained in of
syntax keyword typescriptBoolean true false nextgroup=@typescriptSymbols skipwhite skipempty
-syntax keyword typescriptNull null undefined nextgroup=@typescriptSymbols skipwhite skipempty
syntax keyword typescriptMessage alert confirm prompt status
\ nextgroup=typescriptDotNotation,typescriptFuncCallArg
syntax keyword typescriptGlobal self top parent
@@ -290,10 +297,10 @@ syntax keyword typescriptCase case nextgroup=@typescriptPrimiti
syntax keyword typescriptDefault default containedin=typescriptBlock nextgroup=@typescriptValue,typescriptClassKeyword,typescriptInterfaceKeyword skipwhite oneline
syntax keyword typescriptStatementKeyword with
syntax keyword typescriptStatementKeyword yield skipwhite nextgroup=@typescriptValue containedin=typescriptBlock
-syntax keyword typescriptStatementKeyword return skipwhite contained nextgroup=@typescriptValue containedin=typescriptBlock
syntax keyword typescriptTry try
-syntax keyword typescriptExceptions catch throw finally
+syntax keyword typescriptExceptions throw finally
+syntax keyword typescriptExceptions catch nextgroup=typescriptCall skipwhite skipempty oneline
syntax keyword typescriptDebugger debugger
syntax keyword typescriptAsyncFor await nextgroup=typescriptLoopParen skipwhite skipempty contained
@@ -321,6 +328,24 @@ syntax cluster typescriptAmbients contains=
\ typescriptEnumKeyword,typescriptEnum,
\ typescriptModule
+syntax keyword typescriptIdentifier arguments nextgroup=@afterIdentifier
+syntax match typescriptDefaultImportName /\v\h\k*( |,)/
+ \ contained
+ \ nextgroup=typescriptTypeBlock
+ \ skipwhite skipempty
+
+syntax region typescriptTypeBlock
+ \ matchgroup=typescriptBraces
+ \ start=/{/ end=/}/
+ \ contained
+ \ contains=typescriptIdentifierName,typescriptImportType
+ \ fold
+
+"Program Keywords
+syntax keyword typescriptNull null undefined nextgroup=@typescriptSymbols skipwhite skipempty
+syntax keyword typescriptIdentifier this super prototype nextgroup=@afterIdentifier
+syntax keyword typescriptStatementKeyword return skipwhite contained nextgroup=@typescriptValue containedin=typescriptBlock
+
"Syntax coloring for Node.js shebang line
syntax match shellbang "^#!.*node\>"
syntax match shellbang "^#!.*iojs\>"
@@ -536,7 +561,7 @@ syntax region typescriptGenericFunc matchgroup=typescriptTypeBrackets
\ contained skipwhite skipnl
syntax region typescriptFuncType matchgroup=typescriptParens
- \ start=/(/ end=/)\s*=>/me=e-2
+ \ start=/(\(\k\+:\|)\)\@=/ end=/)\s*=>/me=e-2
\ contains=@typescriptParameterList
\ nextgroup=typescriptFuncTypeArrow
\ contained skipwhite skipnl oneline
@@ -546,7 +571,6 @@ syntax match typescriptFuncTypeArrow /=>/
\ containedin=typescriptFuncType
\ contained skipwhite skipnl
-
syntax keyword typescriptConstructorType new
\ nextgroup=@typescriptFunctionType
\ contained skipwhite skipnl
@@ -623,25 +647,24 @@ syntax keyword typescriptReadonlyArrayKeyword readonly
" extension
-if get(g:, 'yats_host_keyword', 1)
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Function Boolean
- " use of nextgroup Suggested by Doug Kearns
+if get(g:, 'typescript_host_keyword', 1)
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Function Boolean nextgroup=typescriptFuncCallArg
syntax keyword typescriptGlobal containedin=typescriptIdentifierName Error EvalError nextgroup=typescriptFuncCallArg
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName InternalError
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName RangeError ReferenceError
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName StopIteration
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName SyntaxError TypeError
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName URIError Date
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float32Array
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float64Array
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int16Array Int32Array
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int8Array Uint16Array
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint32Array Uint8Array
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint8ClampedArray
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName ParallelArray
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName ArrayBuffer DataView
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Iterator Generator
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName Reflect Proxy
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName InternalError nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName RangeError ReferenceError nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName StopIteration nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName SyntaxError TypeError nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName URIError Date nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float32Array nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Float64Array nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int16Array Int32Array nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Int8Array Uint16Array nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint32Array Uint8Array nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Uint8ClampedArray nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName ParallelArray nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName ArrayBuffer DataView nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Iterator Generator nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName Reflect Proxy nextgroup=typescriptFuncCallArg
syntax keyword typescriptGlobal containedin=typescriptIdentifierName arguments
hi def link typescriptGlobal Structure
syntax keyword typescriptGlobalMethod containedin=typescriptIdentifierName eval uneval nextgroup=typescriptFuncCallArg
@@ -675,12 +698,12 @@ if get(g:, 'yats_host_keyword', 1)
hi def link typescriptStringStaticMethod Keyword
syntax keyword typescriptStringMethod contained anchor charAt charCodeAt codePointAt nextgroup=typescriptFuncCallArg
syntax keyword typescriptStringMethod contained concat endsWith includes indexOf lastIndexOf nextgroup=typescriptFuncCallArg
- syntax keyword typescriptStringMethod contained link localeCompare match normalize nextgroup=typescriptFuncCallArg
- syntax keyword typescriptStringMethod contained padStart padEnd repeat replace search nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptStringMethod contained link localeCompare match matchAll normalize nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptStringMethod contained padStart padEnd repeat replace replaceAll search nextgroup=typescriptFuncCallArg
syntax keyword typescriptStringMethod contained slice split startsWith substr substring nextgroup=typescriptFuncCallArg
syntax keyword typescriptStringMethod contained toLocaleLowerCase toLocaleUpperCase nextgroup=typescriptFuncCallArg
syntax keyword typescriptStringMethod contained toLowerCase toString toUpperCase trim nextgroup=typescriptFuncCallArg
- syntax keyword typescriptStringMethod contained valueOf nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptStringMethod contained trimEnd trimStart valueOf nextgroup=typescriptFuncCallArg
syntax cluster props add=typescriptStringMethod
hi def link typescriptStringMethod Keyword
@@ -689,18 +712,18 @@ if get(g:, 'yats_host_keyword', 1)
syntax keyword typescriptArrayStaticMethod contained from isArray of nextgroup=typescriptFuncCallArg
hi def link typescriptArrayStaticMethod Keyword
syntax keyword typescriptArrayMethod contained concat copyWithin entries every fill nextgroup=typescriptFuncCallArg
- syntax keyword typescriptArrayMethod contained filter find findIndex forEach indexOf nextgroup=typescriptFuncCallArg
- syntax keyword typescriptArrayMethod contained includes join keys lastIndexOf map nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptArrayMethod contained filter find findIndex flat flatMap forEach nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptArrayMethod contained includes indexOf join keys lastIndexOf map nextgroup=typescriptFuncCallArg
syntax keyword typescriptArrayMethod contained pop push reduce reduceRight reverse nextgroup=typescriptFuncCallArg
syntax keyword typescriptArrayMethod contained shift slice some sort splice toLocaleString nextgroup=typescriptFuncCallArg
- syntax keyword typescriptArrayMethod contained toSource toString unshift nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptArrayMethod contained toSource toString unshift values nextgroup=typescriptFuncCallArg
syntax cluster props add=typescriptArrayMethod
hi def link typescriptArrayMethod Keyword
syntax keyword typescriptGlobal containedin=typescriptIdentifierName Object nextgroup=typescriptGlobalObjectDot,typescriptFuncCallArg
syntax match typescriptGlobalObjectDot /\./ contained nextgroup=typescriptObjectStaticMethod,typescriptProp
syntax keyword typescriptObjectStaticMethod contained create defineProperties defineProperty nextgroup=typescriptFuncCallArg
- syntax keyword typescriptObjectStaticMethod contained entries freeze getOwnPropertyDescriptors nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptObjectStaticMethod contained entries freeze fromEntries getOwnPropertyDescriptors nextgroup=typescriptFuncCallArg
syntax keyword typescriptObjectStaticMethod contained getOwnPropertyDescriptor getOwnPropertyNames nextgroup=typescriptFuncCallArg
syntax keyword typescriptObjectStaticMethod contained getOwnPropertySymbols getPrototypeOf nextgroup=typescriptFuncCallArg
syntax keyword typescriptObjectStaticMethod contained is isExtensible isFrozen isSealed nextgroup=typescriptFuncCallArg
@@ -715,7 +738,7 @@ if get(g:, 'yats_host_keyword', 1)
syntax keyword typescriptGlobal containedin=typescriptIdentifierName Symbol nextgroup=typescriptGlobalSymbolDot,typescriptFuncCallArg
syntax match typescriptGlobalSymbolDot /\./ contained nextgroup=typescriptSymbolStaticProp,typescriptSymbolStaticMethod,typescriptProp
- syntax keyword typescriptSymbolStaticProp contained length iterator match replace
+ syntax keyword typescriptSymbolStaticProp contained description length iterator match matchAll replace
syntax keyword typescriptSymbolStaticProp contained search split hasInstance isConcatSpreadable
syntax keyword typescriptSymbolStaticProp contained unscopables species toPrimitive
syntax keyword typescriptSymbolStaticProp contained toStringTag
@@ -771,7 +794,7 @@ if get(g:, 'yats_host_keyword', 1)
syntax match typescriptGlobalRegExpDot /\./ contained nextgroup=typescriptRegExpStaticProp,typescriptProp
syntax keyword typescriptRegExpStaticProp contained lastIndex
hi def link typescriptRegExpStaticProp Keyword
- syntax keyword typescriptRegExpProp contained global ignoreCase multiline source sticky
+ syntax keyword typescriptRegExpProp contained dotAll global ignoreCase multiline source sticky
syntax cluster props add=typescriptRegExpProp
hi def link typescriptRegExpProp Keyword
syntax keyword typescriptRegExpMethod contained exec test nextgroup=typescriptFuncCallArg
@@ -805,7 +828,7 @@ if get(g:, 'yats_host_keyword', 1)
syntax keyword typescriptGlobal containedin=typescriptIdentifierName Promise nextgroup=typescriptGlobalPromiseDot,typescriptFuncCallArg
syntax match typescriptGlobalPromiseDot /\./ contained nextgroup=typescriptPromiseStaticMethod,typescriptProp
- syntax keyword typescriptPromiseStaticMethod contained resolve reject all race nextgroup=typescriptFuncCallArg
+ syntax keyword typescriptPromiseStaticMethod contained all allSettled any race reject resolve nextgroup=typescriptFuncCallArg
hi def link typescriptPromiseStaticMethod Keyword
syntax keyword typescriptPromiseMethod contained then catch finally nextgroup=typescriptFuncCallArg
syntax cluster props add=typescriptPromiseMethod
@@ -1232,7 +1255,8 @@ if get(g:, 'yats_host_keyword', 1)
syntax cluster props add=typescriptBOMHistoryMethod
hi def link typescriptBOMHistoryMethod Keyword
- syntax keyword typescriptGlobal containedin=typescriptIdentifierName console
+ syntax keyword typescriptGlobal containedin=typescriptIdentifierName console nextgroup=typescriptGlobalConsoleDot
+ syntax match typescriptGlobalConsoleDot /\./ contained nextgroup=typescriptConsoleMethod,typescriptProp
syntax keyword typescriptConsoleMethod contained count dir error group groupCollapsed nextgroup=typescriptFuncCallArg
syntax keyword typescriptConsoleMethod contained groupEnd info log time timeEnd trace nextgroup=typescriptFuncCallArg
syntax keyword typescriptConsoleMethod contained warn nextgroup=typescriptFuncCallArg
@@ -1735,8 +1759,6 @@ if get(g:, 'yats_host_keyword', 1)
syntax keyword typescriptServiceWorkerEvent contained install activate fetch
syntax cluster events add=typescriptServiceWorkerEvent
hi def link typescriptServiceWorkerEvent Title
-
-
endif
" patch
@@ -1764,6 +1786,7 @@ syntax cluster typescriptPropertyMemberDeclaration contains=
\ typescriptClassStatic,
\ typescriptAccessibilityModifier,
\ typescriptReadonlyModifier,
+ \ typescriptAutoAccessor,
\ typescriptMethodAccessor,
\ @typescriptMembers
" \ typescriptMemberVariableDeclaration
@@ -1780,7 +1803,9 @@ syntax keyword typescriptClassStatic static
syntax keyword typescriptAccessibilityModifier public private protected contained
-syntax keyword typescriptReadonlyModifier readonly contained
+syntax keyword typescriptReadonlyModifier readonly override contained
+
+syntax keyword typescriptAutoAccessor accessor contained
syntax region typescriptStringMember contained
\ start=/\z(["']\)/ skip=/\\\\\|\\\z1\|\\\n/ end=/\z1/
@@ -1789,7 +1814,7 @@ syntax region typescriptStringMember contained
syntax region typescriptComputedMember contained matchgroup=typescriptProperty
\ start=/\[/rs=s+1 end=/]/
- \ contains=@typescriptValue,typescriptMember,typescriptMappedIn
+ \ contains=@typescriptValue,typescriptMember,typescriptMappedIn,typescriptCastKeyword
\ nextgroup=@memberNextGroup
\ skipwhite skipempty
@@ -1861,7 +1886,7 @@ syntax match typescriptInterfaceComma /,/ contained nextgroup=typescriptInterfac
"Block VariableStatement EmptyStatement ExpressionStatement IfStatement IterationStatement ContinueStatement BreakStatement ReturnStatement WithStatement LabelledStatement SwitchStatement ThrowStatement TryStatement DebuggerStatement
syntax cluster typescriptStatement
- \ contains=typescriptBlock,typescriptVariable,
+ \ contains=typescriptBlock,typescriptVariable,typescriptUsing,
\ @typescriptTopExpression,typescriptAssign,
\ typescriptConditional,typescriptRepeat,typescriptBranch,
\ typescriptLabel,typescriptStatementKeyword,
@@ -1899,16 +1924,14 @@ syntax cluster typescriptValue
syntax cluster typescriptEventExpression contains=typescriptArrowFuncDef,typescriptParenExp,@typescriptValue,typescriptRegexpString,@typescriptEventTypes,typescriptOperator,typescriptGlobal,jsxRegion
syntax keyword typescriptAsyncFuncKeyword async
- \ nextgroup=typescriptFuncKeyword,typescriptArrowFuncDef
+ \ nextgroup=typescriptFuncKeyword,typescriptArrowFuncDef,typescriptArrowFuncTypeParameter
\ skipwhite
syntax keyword typescriptAsyncFuncKeyword await
- \ nextgroup=@typescriptValue
+ \ nextgroup=@typescriptValue,typescriptUsing
\ skipwhite
-syntax keyword typescriptFuncKeyword function
- \ nextgroup=typescriptAsyncFunc,typescriptFuncName,@typescriptCallSignature
- \ skipwhite skipempty
+syntax keyword typescriptFuncKeyword function nextgroup=typescriptAsyncFunc,typescriptFuncName,@typescriptCallSignature skipwhite skipempty
syntax match typescriptAsyncFunc contained /*/
\ nextgroup=typescriptFuncName,@typescriptCallSignature
@@ -1918,39 +1941,33 @@ syntax match typescriptFuncName contained /\K\k*/
\ nextgroup=@typescriptCallSignature
\ skipwhite
-" destructuring ({ a: ee }) =>
-syntax match typescriptArrowFuncDef contained /(\(\s*\({\_[^}]*}\|\k\+\)\(:\_[^)]\)\?,\?\)\+)\s*=>/
- \ contains=typescriptArrowFuncArg,typescriptArrowFunc
- \ nextgroup=@typescriptExpression,typescriptBlock
- \ skipwhite skipempty
-
-" matches `(a) =>` or `([a]) =>` or
-" `(
-" a) =>`
-syntax match typescriptArrowFuncDef contained /(\(\_s*[a-zA-Z\$_\[.]\_[^)]*\)*)\s*=>/
+syntax match typescriptArrowFuncDef contained /\K\k*\s*=>/
\ contains=typescriptArrowFuncArg,typescriptArrowFunc
\ nextgroup=@typescriptExpression,typescriptBlock
\ skipwhite skipempty
-syntax match typescriptArrowFuncDef contained /\K\k*\s*=>/
- \ contains=typescriptArrowFuncArg,typescriptArrowFunc
+syntax match typescriptArrowFuncDef contained /(\%(\_[^()]\+\|(\_[^()]*)\)*)\_s*=>/
+ \ contains=typescriptArrowFuncArg,typescriptArrowFunc,@typescriptCallSignature
\ nextgroup=@typescriptExpression,typescriptBlock
\ skipwhite skipempty
-" TODO: optimize this pattern
-syntax region typescriptArrowFuncDef contained start=/(\_[^(^)]*):/ end=/=>/
- \ contains=typescriptArrowFuncArg,typescriptArrowFunc,typescriptTypeAnnotation
+syntax region typescriptArrowFuncDef contained start=/(\%(\_[^()]\+\|(\_[^()]*)\)*):/ matchgroup=typescriptArrowFunc end=/=>/
+ \ contains=typescriptArrowFuncArg,typescriptTypeAnnotation,@typescriptCallSignature
\ nextgroup=@typescriptExpression,typescriptBlock
\ skipwhite skipempty keepend
+syntax region typescriptArrowFuncTypeParameter start=/</ end=/>/
+ \ contains=@typescriptTypeParameterCluster
+ \ nextgroup=typescriptArrowFuncDef
+ \ contained skipwhite skipnl
+
syntax match typescriptArrowFunc /=>/
syntax match typescriptArrowFuncArg contained /\K\k*/
-syntax region typescriptArrowFuncArg contained start=/<\|(/ end=/\ze=>/ contains=@typescriptCallSignature
syntax region typescriptReturnAnnotation contained start=/:/ end=/{/me=e-1 contains=@typescriptType nextgroup=typescriptBlock
-syntax region typescriptFuncImpl contained start=/function\>/ end=/{/me=e-1
+syntax region typescriptFuncImpl contained start=/function\>/ end=/{\|;\|\n/me=e-1
\ contains=typescriptFuncKeyword
\ nextgroup=typescriptBlock
@@ -1970,7 +1987,7 @@ syntax match typescriptDecorator /@\([_$a-zA-Z][_$a-zA-Z0-9]*\.\)*[_$a-zA-Z][_$a
\ nextgroup=typescriptFuncCallArg,typescriptTypeArguments
\ contains=@_semantic,typescriptDotNotation
-" Define the default highlighting.
+
hi def link typescriptReserved Error
hi def link typescriptEndColons Exception
@@ -2013,6 +2030,7 @@ hi def link typescriptDefault typescriptCase
hi def link typescriptBranch Conditional
hi def link typescriptIdentifier Structure
hi def link typescriptVariable Identifier
+hi def link typescriptUsing Identifier
hi def link typescriptDestructureVariable PreProc
hi def link typescriptEnumKeyword Identifier
hi def link typescriptRepeat Repeat
@@ -2050,16 +2068,13 @@ hi def link typescriptFuncKeyword Keyword
hi def link typescriptAsyncFunc Keyword
hi def link typescriptArrowFunc Type
hi def link typescriptFuncName Function
-hi def link typescriptFuncArg PreProc
+hi def link typescriptFuncCallArg PreProc
hi def link typescriptArrowFuncArg PreProc
hi def link typescriptFuncComma Operator
hi def link typescriptClassKeyword Keyword
hi def link typescriptClassExtends Keyword
-" hi def link typescriptClassName Function
hi def link typescriptAbstract Special
-" hi def link typescriptClassHeritage Function
-" hi def link typescriptInterfaceHeritage Function
hi def link typescriptClassStatic StorageClass
hi def link typescriptReadonlyModifier Keyword
hi def link typescriptInterfaceKeyword Keyword
@@ -2077,6 +2092,7 @@ hi def link typescriptFuncTypeArrow Function
hi def link typescriptConstructorType Function
hi def link typescriptTypeQuery Keyword
hi def link typescriptAccessibilityModifier Keyword
+hi def link typescriptAutoAccessor Keyword
hi def link typescriptOptionalMark PreProc
hi def link typescriptFuncType Special
hi def link typescriptMappedIn Special
diff --git a/runtime/syntax/spec.vim b/runtime/syntax/spec.vim
index 12ce8d5..4cb3a34 100644
--- a/runtime/syntax/spec.vim
+++ b/runtime/syntax/spec.vim
@@ -111,7 +111,7 @@ syn region specDescriptionArea matchgroup=specSection start='^%description' end=
syn region specPackageArea matchgroup=specSection start='^%package' end='^%'me=e-1 contains=specPackageOpts,specPreAmble,specComment
"%% Scripts Section %%
-syn region specScriptArea matchgroup=specSection start='^%\(prep\|build\|install\|clean\|check\|pre\|postun\|preun\|post\|posttrans\)\>' skip='^%{\|^%\(define\|patch\d*\|configure\|GNUconfigure\|setup\|autosetup\|autopatch\|find_lang\|make_build\|makeinstall\|make_install\)\>' end='^%'me=e-1 contains=specSpecialVariables,specVariables,@specCommands,specVariables,shDo,shFor,shCaseEsac,specNoNumberHilite,specCommandOpts,shComment,shIf,specSpecialChar,specMacroIdentifier,specSectionMacroArea,specSectionMacroBracketArea,shOperator,shQuote1,shQuote2
+syn region specScriptArea matchgroup=specSection start='^%\(prep\|generate_buildrequires\|conf\|build\|install\|clean\|check\|pre\|postun\|preun\|post\|posttrans\)\>' skip='^%{\|^%\(define\|patch\d*\|configure\|GNUconfigure\|setup\|autosetup\|autopatch\|find_lang\|make_build\|makeinstall\|make_install\)\>' end='^%'me=e-1 contains=specSpecialVariables,specVariables,@specCommands,specVariables,shDo,shFor,shCaseEsac,specNoNumberHilite,specCommandOpts,shComment,shIf,specSpecialChar,specMacroIdentifier,specSectionMacroArea,specSectionMacroBracketArea,shOperator,shQuote1,shQuote2
"%% Changelog Section %%
syn region specChangelogArea matchgroup=specSection start='^%changelog' end='^%'me=e-1 contains=specEmail,specURL,specWeekday,specMonth,specNumber,specComment,specLicense
diff --git a/runtime/syntax/ssa.vim b/runtime/syntax/ssa.vim
index a5dbf37..3cfae81 100644
--- a/runtime/syntax/ssa.vim
+++ b/runtime/syntax/ssa.vim
@@ -2,7 +2,7 @@
" Language: SubStation Alpha
" Maintainer: ObserverOfTime <chronobserver@disroot.org>
" Filenames: *.ass,*.ssa
-" Last Change: 2022 Oct 10
+" Last Change: 2024 Apr 28
if exists('b:current_syntax')
finish
@@ -20,16 +20,20 @@ syn match ssaSection /^\[[a-zA-Z0-9+ ]\+\]$/
syn match ssaHeader /^[^;!:]\+:/ skipwhite nextgroup=ssaField
" Fields
-syn match ssaField /[^,]*/ contained skipwhite nextgroup=ssaDelimiter
+syn match ssaField /[^,]*\(,\|$\)/ contained skipwhite contains=ssaDelimiter,ssaTime nextgroup=ssaField
" Time
-syn match ssaTime /\d:\d\d:\d\d\.\d\d/ contained skipwhite nextgroup=ssaDelimiter
+syn match ssaTime /\d:\d\d:\d\d\.\d\d/ contained
" Delimiter
-syn match ssaDelimiter /,/ contained skipwhite nextgroup=ssaField,ssaTime,ssaText
+syn match ssaDelimiter /,/ contained
+
+" Dialogue
+syn match ssaDialogue /^Dialogue:/ transparent skipwhite nextgroup=ssaDialogueFields
+syn match ssaDialogueFields /\([^,]*,\)\{9\}/ contained transparent skipwhite contains=ssaField,ssaDelimiter nextgroup=ssaText
" Text
-syn match ssaText /\(^Dialogue:\(.*,\)\{9}\)\@<=.*$/ contained contains=@ssaTags,@Spell
+syn match ssaText /.*$/ contained contains=@ssaTags,@Spell
syn cluster ssaTags contains=ssaOverrideTag,ssaEscapeChar,ssaTextComment,ssaItalics,ssaBold,ssaUnderline,ssaStrikeout
" Override tags
@@ -60,4 +64,4 @@ hi ssaItalics cterm=italic gui=italic
hi ssaStrikeout cterm=strikethrough gui=strikethrough
hi ssaUnderline cterm=underline gui=underline
-let b:current_syntax = 'srt'
+let b:current_syntax = 'ssa'
diff --git a/runtime/syntax/stylus.vim b/runtime/syntax/stylus.vim
new file mode 100644
index 0000000..d8bf641
--- /dev/null
+++ b/runtime/syntax/stylus.vim
@@ -0,0 +1,51 @@
+" Vim syntax file
+" Language: Stylus
+" Maintainer: Hsiaoming Yang <lepture@me.com>, Marc Harter
+" Filenames: *.styl, *.stylus
+" Based On: Tim Pope (sass.vim)
+" Created: Dec 14, 2011
+" Modified: May 28, 2024
+
+syn case ignore
+
+syn cluster stylusCssSelectors contains=cssTagName,cssSelector,cssPseudo
+syn cluster stylusCssValues contains=cssValueLength,cssValueInteger,cssValueNumber,cssValueAngle,cssValueTime,cssValueFrequency,cssColorVal,cssCommonVal,cssFontVal,cssListVal,cssTextVal,cssVisualVal,cssBorderVal,cssBackgroundVal,cssFuncVal,cssAdvancedVal
+syn cluster stylusCssProperties contains=cssProp,cssBackgroundProp,cssTableProp,cssBorderProp,cssFontProp,cssColorProp,cssBoxProp,cssTextProp,cssListProp,cssVisualProp,cssAdvancedProp,cssCommonProp,cssSpecialProp
+
+syn match stylusVariable "$\?[[:alnum:]_-]\+"
+syn match stylusVariableAssignment "\%([[:alnum:]_-]\+\s*\)\@<==" nextgroup=stylusCssAttribute,stylusVariable skipwhite
+
+syn match stylusProperty "\%([{};]\s*\|^\)\@<=\%([[:alnum:]-]\|#{[^{}]*}\)\+:" contains=@stylusCssProperties,@stylusCssSelectors skipwhite nextgroup=stylusCssAttribute contained containedin=cssDefineBlock
+syn match stylusProperty "^\s*\zs\s\%(\%([[:alnum:]-]\|#{[^{}]*}\)\+[ :]\|:[[:alnum:]-]\+\)"hs=s+1 contains=@stylusCssProperties,@stylusCssSelectors skipwhite nextgroup=stylusCssAttribute
+syn match stylusProperty "^\s*\zs\s\%(:\=[[:alnum:]-]\+\s*=\)"hs=s+1 contains=@stylusCssProperties,@stylusCssSelectors skipwhite nextgroup=stylusCssAttribute
+
+syn match stylusCssAttribute +\%("\%([^"]\|\\"\)*"\|'\%([^']\|\\'\)*'\|#{[^{}]*}\|[^{};]\)*+ contained contains=@stylusCssValues,cssImportant,stylusFunction,stylusVariable,stylusControl,stylusUserFunction,stylusInterpolation,cssString,stylusComment,cssComment
+
+syn match stylusInterpolation %{[[:alnum:]_-]\+}%
+
+syn match stylusFunction "\<\%(red\|green\|blue\|alpha\|dark\|light\)\>(\@=" contained
+syn match stylusFunction "\<\%(hue\|saturation\|lightness\|push\|unshift\|typeof\|unit\|match\)\>(\@=" contained
+syn match stylusFunction "\<\%(hsla\|hsl\|rgba\|rgb\|lighten\|darken\)\>(\@=" contained
+syn match stylusFunction "\<\%(abs\|ceil\|floor\|round\|min\|max\|even\|odd\|sum\|avg\|sin\|cos\|join\)\>(\@=" contained
+syn match stylusFunction "\<\%(desaturate\|saturate\|invert\|unquote\|quote\|s\)\>(\@=" contained
+syn match stylusFunction "\<\%(operate\|length\|warn\|error\|last\|p\|\)\>(\@=" contained
+syn match stylusFunction "\<\%(opposite-position\|image-size\|add-property\)\>(\@=" contained
+
+syn keyword stylusVariable null true false arguments
+syn keyword stylusControl if else unless for in return
+
+syn match stylusImport "@\%(import\|require\)" nextgroup=stylusImportList
+syn match stylusImportList "[^;]\+" contained contains=cssString.*,cssMediaType,cssURL
+
+syn match stylusAmpersand "&"
+syn match stylusClass "[[:alnum:]_-]\+" contained
+syn match stylusClassChar "\.[[:alnum:]_-]\@=" nextgroup=stylusClass
+syn match stylusEscape "^\s*\zs\\"
+syn match stylusId "[[:alnum:]_-]\+" contained
+syn match stylusIdChar "#[[:alnum:]_-]\@=" nextgroup=stylusId
+
+syn region stylusComment start="//" end="$" contains=cssTodo,@Spell fold
+
+let b:current_syntax = "stylus"
+
+" vim:set sw=2:
diff --git a/runtime/syntax/swayconfig.vim b/runtime/syntax/swayconfig.vim
index 55c5279..d09d476 100644
--- a/runtime/syntax/swayconfig.vim
+++ b/runtime/syntax/swayconfig.vim
@@ -2,8 +2,8 @@
" Language: sway config file
" Original Author: Josef Litos (JosefLitos/i3config.vim)
" Maintainer: James Eapen <james.eapen@vai.org>
-" Version: 1.2.1
-" Last Change: 2024-04-14
+" Version: 1.2.4
+" Last Change: 2024-05-24
" References:
" http://i3wm.org/docs/userguide.html#configuring
@@ -16,10 +16,12 @@ if exists("b:current_syntax")
finish
endif
+" before i3 load to give i3ConfigKeyword lower priority
+syn cluster i3ConfigCommand contains=i3ConfigCommand,i3ConfigAction,i3ConfigActionKeyword,@i3ConfigValue,i3ConfigColor,i3ConfigKeyword
+
runtime! syntax/i3config.vim
" Sway extensions to i3
-syn cluster i3ConfigCommand contains=i3ConfigCommand,i3ConfigAction,i3ConfigActionKeyword,@i3ConfigValue,i3ConfigColor,i3ConfigKeyword
syn keyword i3ConfigActionKeyword opacity urgent shortcuts_inhibitor splitv splith splitt contained contained skipwhite nextgroup=i3ConfigOption
syn keyword i3ConfigOption set plus minus allow deny csd v h t contained contained skipwhite nextgroup=i3ConfigOption,@i3ConfigValue
@@ -32,12 +34,12 @@ syn region i3ConfigBindArgument start=/--input-device=['"]/ end=/\s/ contained c
syn region i3ConfigBindCombo matchgroup=i3ConfigParen start=/{$/ end=/^\s*}$/ contained contains=i3ConfigBindArgument,i3ConfigBindCombo,i3ConfigComment fold keepend extend
" hack for blocks with start outside parsing range
-syn region swayConfigBlockOrphan start=/^\s\+\(--[a-z-]\+ \)*[$a-zA-Z0-9_+]\+ [a-z[]/ skip=/\\$\|$\n^\s*}$/ end=/$/ contains=i3ConfigBindArgument,i3ConfigBindCombo,i3ConfigParen keepend extend
+syn region swayConfigBlockOrphan start=/^\s\+\(--[a-z-]\+ \)*\([$A-Z][$0-9A-Za-z_+]\+\|[a-z]\) [a-z[]/ skip=/\\$\|$\n^\s*}$/ end=/$/ contains=i3ConfigBindArgument,i3ConfigBindCombo,i3ConfigParen keepend extend
-syn region i3ConfigExec start=/ {$/ end=/^}$/ contained contains=i3ConfigExecAction,@i3ConfigSh,i3ConfigComment fold keepend extend
+syn region i3ConfigExec start=/ {$/ end=/^\s*}$/ contained contains=i3ConfigExecAction,@i3ConfigSh,i3ConfigComment fold keepend extend
-syn keyword swayConfigFloatingModifierOpts normal inverse contained
-syn match i3ConfigKeyword /^floating_modifier [$a-zA-Z0-9+]\+ \(normal\|inverse\)$/ contains=i3ConfigVariable,i3ConfigBindModkey,swayConfigFloatingModifierOpts
+syn keyword swayConfigFloatingModifierOpts normal inverse none contained
+syn match i3ConfigKeyword /floating_modifier \(none\|[$A-Z][0-9A-Za-z]\+ \(normal\|inverse\)\)$/ contained contains=i3ConfigVariable,i3ConfigBindModkey,swayConfigFloatingModifierOpts
syn match swayConfigI3Param /--i3/ contains=i3ConfigShParam skipwhite nextgroup=i3ConfigEdgeOpts
syn keyword i3ConfigKeyword hide_edge_borders contained skipwhite nextgroup=swayConfigI3Param,i3ConfigEdgeOpts
@@ -69,7 +71,7 @@ syn keyword i3ConfigBindKeyword bindswitch contained skipwhite nextgroup=swayCon
syn region swayConfigBlockOrphan start=/^\s\+\(lid\|tablet\):/ skip=/\\$\|$\n^\s*}$/ end=/$/ contains=swayConfigBindswitchArgument,swayConfigBindswitchType,i3ConfigParen keepend extend
" Bindgesture
-syn match swayConfigBindgestureArgument /--\(exact\|input-device=[:0-9a-zA-Z_/-]\+\|no-warn\) / contained nextgroup=swayConfigBindgestureArgument,swayConfigBindgestureCombo
+syn match swayConfigBindgestureArgument /--\(exact\|input-device=[:0-9A-Za-z_/-]\+\|no-warn\) / contained nextgroup=swayConfigBindgestureArgument,swayConfigBindgestureCombo
syn keyword swayConfigBindgestureType hold swipe pinch contained
syn keyword swayConfigBindgestureDir up down left right inward outward clockwise counterclockwise contained
syn match swayConfigBindgestureCombo /\(hold\(:[1-5]\)\?\|swipe\(:[3-5]\)\?\(:up\|:down\|:left\|:right\)\?\|pinch\(:[2-5]\)\?:\(+\?\(inward\|outward\|clockwise\|counterclockwise\|up\|down\|left\|right\)\)\+\) / contained contains=i3ConfigNumber,swayConfigBindgestureType,i3ConfigColonOperator,swayConfigBindgestureDir,i3ConfigBindModifier nextgroup=swayConfigBindgestureCombo,i3ConfigBind
@@ -81,7 +83,7 @@ syn region swayConfigBlockOrphan start=/^\s\+\(--[a-z-]\+ \)*\(hold\|swipe\|pinc
" Tiling drag threshold
" Titlebar commands
syn keyword i3ConfigKeyword tiling_drag_threshold titlebar_border_thickness contained skipwhite nextgroup=@i3ConfigNumVar
-syn match i3ConfigKeyword /^titlebar_padding \(\d\+\|\$\S\+\)\( \d\+\)\?$/ contains=@i3ConfigNumVar
+syn match i3ConfigKeyword /titlebar_padding \(\d\+\|\$\S\+\)\( \d\+\)\?$/ contained contains=@i3ConfigNumVar
syn match swayConfigDeviceOper /[*:;!]/ contained
@@ -96,7 +98,7 @@ syn match swayConfigXkbOptsPair /[a-z]\+:/ contained contains=i3ConfigColonOpera
syn keyword swayConfigInputOpts xkb_options contained skipwhite nextgroup=swayConfigXkbOptsPair
syn region swayConfigInput start=/\s/ skip=/\\$/ end=/\ze[,;]\|$/ contained contains=swayConfigInputOpts,@i3ConfigValue keepend
-syn region swayConfigInput matchgroup=i3ConfigParen start=/ {$/ end=/^}$/ contained contains=swayConfigInputOpts,@i3ConfigValue,i3ConfigComment keepend extend
+syn region swayConfigInput matchgroup=i3ConfigParen start=/ {$/ end=/^\s*}$/ contained contains=swayConfigInputOpts,@i3ConfigValue,i3ConfigComment keepend extend
syn keyword swayConfigInputType touchpad pointer keyboard touch tablet_tool tablet_pad switch contained nextgroup=swayConfigInput
syn match swayConfigInputIdent /type:!\?/ contained contains=swayConfigDeviceOper nextgroup=swayConfigInputType
syn match swayConfigInputIdent /[^t '"]\S*/ contained contains=i3ConfigOutputIdent nextgroup=swayConfigInput
@@ -111,7 +113,7 @@ syn keyword swayConfigSeatOpts attach contained skipwhite nextgroup=swayConfigSe
syn match swayConfigSeatOptVals /when-typing/ contained skipwhite nextgroup=swayConfigSeatOptVals
syn keyword swayConfigSeatOptVals move set press release none smart activate deactivate toggle escape enable disable contained skipwhite nextgroup=swayConfigSeatOpts
syn region swayConfigSeat start=/\s/ skip=/\\$/ end=/\ze[,;]\|$/ contained contains=swayConfigSeatOpts,@i3ConfigValue keepend
-syn region swayConfigSeat matchgroup=i3ConfigParen start=/ {$/ end=/^}$/ contained contains=swayConfigSeatOpts,@i3ConfigValue,i3ConfigComment keepend extend
+syn region swayConfigSeat matchgroup=i3ConfigParen start=/ {$/ end=/^\s*}$/ contained contains=swayConfigSeatOpts,@i3ConfigValue,i3ConfigComment keepend extend
syn match swayConfigSeatIdent /[^ ]\+/ contained contains=i3ConfigOutputIdent skipwhite nextgroup=swayConfigSeat
syn keyword i3ConfigKeyword seat contained skipwhite nextgroup=swayConfigSeatIdent
@@ -127,7 +129,7 @@ syn match swayConfigOutputFPS /@[0-9.]\+Hz/ contained skipwhite nextgroup=swayCo
syn match swayConfigOutputMode /\(--custom \)\?[0-9]\+x[0-9]\+/ contained contains=i3ConfigShParam skipwhite nextgroup=swayConfigOutputFPS,swayConfigOutputOpts
syn match swayConfigOutputOptVals /\(flipped-\)\?\(90\|180\|270\)\|flipped\|normal/ contained contains=i3ConfigNumber skipwhite nextgroup=swayConfigOutputOptsVals
syn region swayConfigOutput start=/\s/ skip=/\\$/ end=/\ze[,;]\|$/ contained contains=swayConfigOutputOpts,@i3ConfigValue keepend
-syn region swayConfigOutput matchgroup=i3ConfigParen start=/ {$/ end=/^}$/ contained contains=swayConfigOutputOpts,@i3ConfigValue,i3ConfigComment keepend extend
+syn region swayConfigOutput matchgroup=i3ConfigParen start=/ {$/ end=/^\s*}$/ contained contains=swayConfigOutputOpts,@i3ConfigValue,i3ConfigComment keepend extend
syn match swayConfigOutputIdent /[^ ]\+/ contained contains=i3ConfigOutputIdent skipwhite nextgroup=swayConfigOutput
syn keyword i3ConfigKeyword output contained skipwhite nextgroup=swayConfigOutputIdent
diff --git a/runtime/syntax/testdir/dumps/html_00.dump b/runtime/syntax/testdir/dumps/html_00.dump
index d1b2b91..7905a3a 100644
--- a/runtime/syntax/testdir/dumps/html_00.dump
+++ b/runtime/syntax/testdir/dumps/html_00.dump
@@ -1,20 +1,20 @@
><+0#0000e05#ffffff0|!|-@1| +0#0000000&@70
| +0#0000e05&@1|H|T|M|L| |S|y|n|t|a|x| |T|e|s|t| |F|i|l|e| +0#0000000&@51
| +0#0000e05&@1|M|a|i|n|t|a|i|n|e|r|:| |D|o|u|g| |K|e|a|r|n|s| |<|d|o|u|g|k|e|a|r|n|s|@|g|m|a|i|l|.|c|o|m|>| +0#0000000&@26
-| +0#0000e05&@1|L|a|s|t| |C|h|a|n|g|e|:| |2|0|2|3| |N|o|v| |2|8| +0#0000000&@48
+| +0#0000e05&@1|L|a|s|t| |C|h|a|n|g|e|:| |2|0|2|4| |J|u|n| |1|3| +0#0000000&@48
+| +0#0000e05&@1|V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|h|t|m|l|_|n|o|_|r|e|n|d|e|r|i|n|g| |=| |1| +0#0000000&@30
+@75
+| +0#0000e05&@1|T|O|D|O|:| |I|n|v|e|s|t|i|g|a|t|e| |m|a|c|O|S| |t|e|s|t| |f|a|i|l|u|r|e|s| |w|h|e|n| |c|o|m|p|a|r|i|n|g| |i|t|a|l|i|c|i|z|e|d| |t|e|x|t| |w|i|t|h
+|,| +0#0000000&@73
+| +0#0000e05&@3|f|o|r| |e|x|a|m|p|l|e|,| |<|e|m|>| |a|n|d| |<|i|>| |e|l|e|m|e|n|t|s|.| @1|F|r|e@1|B|S|D| |f|a|i|l|s| |w|i|t|h| |a|n| |e|m|p|t|y| |<|s|t|r|i|k
+|e|>| +0#0000000&@72
+| +0#0000e05&@3|e|l|e|m|e|n|t|.| |S|e@1| |#|1|3|5|9|1| |a|n|d| |#|1|4|2|1|5|.| +0#0000000&@39
|-+0#0000e05&@1|>| +0#0000000&@71
@75
|<+0#0000e05&|!|-@1| |H|T|M|L| |E|l|e|m|e|n|t|s| |-@1|>| +0#0000000&@52
-|<+0#00e0e07&|a+0#af5f00255&|>+0#00e0e07&| +0#0000000&@71
-|<+0#00e0e07&|a+0#af5f00255&|b@1|r|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|a+0#af5f00255&|d@1|r|e|s@1|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|a+0#af5f00255&|>+0#00e0e07&|<|/|a+0#af5f00255&|>+0#00e0e07&| +0#0000000&@67
+|<+0#00e0e07&|a+0#af5f00255&|b@1|r|>+0#00e0e07&|<|/|a+0#af5f00255&|b@1|r|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|a+0#af5f00255&|d@1|r|e|s@1|>+0#00e0e07&|<|/|a+0#af5f00255&|d@1|r|e|s@1|>+0#00e0e07&| +0#0000000&@55
|<+0#00e0e07&|a+0#af5f00255&|r|e|a|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|a+0#af5f00255&|r|t|i|c|l|e|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|a+0#af5f00255&|s|i|d|e|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|a+0#af5f00255&|u|d|i|o|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|b+0#af5f00255&|>+0#00e0e07&|.+2#0000000&@2|<+0#00e0e07&|/|b+0#af5f00255&|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|b+0#af5f00255&|a|s|e|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|b+0#af5f00255&|d|i|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|b+0#af5f00255&|d|o|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|b+0#af5f00255&|l|o|c|k|q|u|o|t|e|>+0#00e0e07&| +0#0000000&@62
-|"|i|n|p|u|t|/|h|t|m|l|.|h|t|m|l|"| |1|4|6|L|,| |1|4|1|7|B| @27|1|,|1| @10|T|o|p|
+|<+0#00e0e07&|a+0#af5f00255&|r|t|i|c|l|e|>+0#00e0e07&|<|/|a+0#af5f00255&|r|t|i|c|l|e|>+0#00e0e07&| +0#0000000&@55
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/html_01.dump b/runtime/syntax/testdir/dumps/html_01.dump
index c855f7b..48b11e6 100644
--- a/runtime/syntax/testdir/dumps/html_01.dump
+++ b/runtime/syntax/testdir/dumps/html_01.dump
@@ -1,20 +1,20 @@
-|<+0#00e0e07#ffffff0|a+0#af5f00255&|u|d|i|o|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|b+0#af5f00255&|>+0#00e0e07&|.+2#0000000&@2|<+0#00e0e07&|/|b+0#af5f00255&|>+0#00e0e07&| +0#0000000&@64
+|<+0#00e0e07#ffffff0|a+0#af5f00255&|b@1|r|>+0#00e0e07&|<|/|a+0#af5f00255&|b@1|r|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|a+0#af5f00255&|d@1|r|e|s@1|>+0#00e0e07&|<|/|a+0#af5f00255&|d@1|r|e|s@1|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|a+0#af5f00255&|r|e|a|>+0#00e0e07&| +0#0000000&@68
+|<+0#00e0e07&|a+0#af5f00255&|r|t|i|c|l|e|>+0#00e0e07&|<|/|a+0#af5f00255&|r|t|i|c|l|e|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|a+0#af5f00255&|s|i|d|e|>+0#00e0e07&|<|/|a+0#af5f00255&|s|i|d|e|>+0#00e0e07&| +0#0000000&@59
+><+0#00e0e07&|a+0#af5f00255&|u|d|i|o|>+0#00e0e07&|<|/|a+0#af5f00255&|u|d|i|o|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|b+0#af5f00255&|>+0#00e0e07&|b+0#0000000&|r|i|n|g| |a|t@1|e|n|t|i|o|n| |t|o|<+0#00e0e07&|/|b+0#af5f00255&|>+0#00e0e07&| +0#0000000&@49
|<+0#00e0e07&|b+0#af5f00255&|a|s|e|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|b+0#af5f00255&|d|i|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|b+0#af5f00255&|d|o|>+0#00e0e07&| +0#0000000&@69
-><+0#00e0e07&|b+0#af5f00255&|l|o|c|k|q|u|o|t|e|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|b+0#af5f00255&|o|d|y|>+0#00e0e07&| +0#0000000&@68
+|<+0#00e0e07&|b+0#af5f00255&|d|i|>+0#00e0e07&|<|/|b+0#af5f00255&|d|i|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|b+0#af5f00255&|d|o|>+0#00e0e07&|<|/|b+0#af5f00255&|d|o|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|b+0#af5f00255&|l|o|c|k|q|u|o|t|e|>+0#00e0e07&|<|/|b+0#af5f00255&|l|o|c|k|q|u|o|t|e|>+0#00e0e07&| +0#0000000&@49
+|<+0#00e0e07&|b+0#af5f00255&|o|d|y|>+0#00e0e07&|<|/|b+0#af5f00255&|o|d|y|>+0#00e0e07&| +0#0000000&@61
|<+0#00e0e07&|b+0#af5f00255&|r|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|b+0#af5f00255&|u|t@1|o|n|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|c+0#af5f00255&|a|n|v|a|s|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|c+0#af5f00255&|a|p|t|i|o|n|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|c+0#af5f00255&|i|t|e|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|c+0#af5f00255&|o|d|e|>+0#00e0e07&| +0#0000000&@68
+|<+0#00e0e07&|b+0#af5f00255&|u|t@1|o|n|>+0#00e0e07&|<|/|b+0#af5f00255&|u|t@1|o|n|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|c+0#af5f00255&|a|n|v|a|s|>+0#00e0e07&|<|/|c+0#af5f00255&|a|n|v|a|s|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|c+0#af5f00255&|a|p|t|i|o|n|>+0#00e0e07&|<|/|c+0#af5f00255&|a|p|t|i|o|n|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|c+0#af5f00255&|i|t|e|>+0#00e0e07&|<|/|c+0#af5f00255&|i|t|e|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|c+0#af5f00255&|o|d|e|>+0#00e0e07&|<|/|c+0#af5f00255&|o|d|e|>+0#00e0e07&| +0#0000000&@61
|<+0#00e0e07&|c+0#af5f00255&|o|l|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|c+0#af5f00255&|o|l|g|r|o|u|p|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|d+0#af5f00255&|a|t|a|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|d+0#af5f00255&|a|t|a|l|i|s|t|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|d+0#af5f00255&@1|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|d+0#af5f00255&|e|l|>+0#00e0e07&|.+1024#0000000&@2|<+0#00e0e07&|/|d+0#af5f00255&|e|l|>+0#00e0e07&| +0#0000000&@60
-@57|1|9|,|1| @9|1|0|%|
+@57|1|9|,|1| @10|9|%|
diff --git a/runtime/syntax/testdir/dumps/html_02.dump b/runtime/syntax/testdir/dumps/html_02.dump
index 9499f2e..bc55823 100644
--- a/runtime/syntax/testdir/dumps/html_02.dump
+++ b/runtime/syntax/testdir/dumps/html_02.dump
@@ -1,20 +1,20 @@
-|<+0#00e0e07#ffffff0|d+0#af5f00255&|e|l|>+0#00e0e07&|.+1024#0000000&@2|<+0#00e0e07&|/|d+0#af5f00255&|e|l|>+0#00e0e07&| +0#0000000&@60
-|<+0#00e0e07&|d+0#af5f00255&|e|t|a|i|l|s|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|d+0#af5f00255&|f|n|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|d+0#af5f00255&|i|a|l|o|g|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|d+0#af5f00255&|i|v|>+0#00e0e07&| +0#0000000&@69
-><+0#00e0e07&|d+0#af5f00255&|l|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|d+0#af5f00255&|t|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|e+0#af5f00255&|m|>+0#00e0e07&|.+4#0000000&@2|<+0#00e0e07&|/|e+0#af5f00255&|m|>+0#00e0e07&| +0#0000000&@62
+|<+0#00e0e07#ffffff0|c+0#af5f00255&|o|l|>+0#00e0e07&| +0#0000000&@69
+|<+0#00e0e07&|c+0#af5f00255&|o|l|g|r|o|u|p|>+0#00e0e07&|<|/|c+0#af5f00255&|o|l|g|r|o|u|p|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|d+0#af5f00255&|a|t|a|>+0#00e0e07&|<|/|d+0#af5f00255&|a|t|a|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|d+0#af5f00255&|a|t|a|l|i|s|t|>+0#00e0e07&|<|/|d+0#af5f00255&|a|t|a|l|i|s|t|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|d+0#af5f00255&@1|>+0#00e0e07&|<|/|d+0#af5f00255&@1|>+0#00e0e07&| +0#0000000&@65
+><+0#00e0e07&|d+0#af5f00255&|e|l|>+0#00e0e07&|d+0#0000000&|e|l|e|t|e|d| |t|e|x|t|<+0#00e0e07&|/|d+0#af5f00255&|e|l|>+0#00e0e07&| +0#0000000&@51
+|<+0#00e0e07&|d+0#af5f00255&|e|t|a|i|l|s|>+0#00e0e07&|<|/|d+0#af5f00255&|e|t|a|i|l|s|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|d+0#af5f00255&|f|n|>+0#00e0e07&|<|/|d+0#af5f00255&|f|n|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|d+0#af5f00255&|i|a|l|o|g|>+0#00e0e07&|<|/|d+0#af5f00255&|i|a|l|o|g|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|d+0#af5f00255&|i|v|>+0#00e0e07&|<|/|d+0#af5f00255&|i|v|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|d+0#af5f00255&|l|>+0#00e0e07&|<|/|d+0#af5f00255&|l|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|d+0#af5f00255&|t|>+0#00e0e07&|<|/|d+0#af5f00255&|t|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|e+0#af5f00255&|m|>+0#00e0e07&|e+0#0000000&|m|p|h|a|s|i|s|<+0#00e0e07&|/|e+0#af5f00255&|m|>+0#00e0e07&| +0#0000000&@57
|<+0#00e0e07&|e+0#af5f00255&|m|b|e|d|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|f+0#af5f00255&|i|e|l|d|s|e|t|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|f+0#af5f00255&|i|g|c|a|p|t|i|o|n|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|f+0#af5f00255&|i|g|u|r|e|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|f+0#af5f00255&|o@1|t|e|r|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|f+0#af5f00255&|o|r|m|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|h+0#af5f00255&|1|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|1|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|h+0#af5f00255&|2|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|2|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|h+0#af5f00255&|3|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|3|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|h+0#af5f00255&|4|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|4|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|h+0#af5f00255&|5|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|5|>+0#00e0e07&| +0#0000000&@62
-@57|3|7|,|1| @9|2|4|%|
+|<+0#00e0e07&|f+0#af5f00255&|i|e|l|d|s|e|t|>+0#00e0e07&|<|/|f+0#af5f00255&|i|e|l|d|s|e|t|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|f+0#af5f00255&|i|g|c|a|p|t|i|o|n|>+0#00e0e07&|<|/|f+0#af5f00255&|i|g|c|a|p|t|i|o|n|>+0#00e0e07&| +0#0000000&@49
+|<+0#00e0e07&|f+0#af5f00255&|i|g|u|r|e|>+0#00e0e07&|<|/|f+0#af5f00255&|i|g|u|r|e|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|f+0#af5f00255&|o@1|t|e|r|>+0#00e0e07&|<|/|f+0#af5f00255&|o@1|t|e|r|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|f+0#af5f00255&|o|r|m|>+0#00e0e07&|<|/|f+0#af5f00255&|o|r|m|>+0#00e0e07&| +0#0000000&@61
+@57|3|7|,|1| @9|2|3|%|
diff --git a/runtime/syntax/testdir/dumps/html_03.dump b/runtime/syntax/testdir/dumps/html_03.dump
index 088da73..4953d71 100644
--- a/runtime/syntax/testdir/dumps/html_03.dump
+++ b/runtime/syntax/testdir/dumps/html_03.dump
@@ -1,20 +1,20 @@
-|<+0#00e0e07#ffffff0|h+0#af5f00255&|5|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|5|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|h+0#af5f00255&|6|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|6|>+0#00e0e07&| +0#0000000&@62
-|<+0#00e0e07&|h+0#af5f00255&|e|a|d|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|h+0#af5f00255&|e|a|d|>+0#00e0e07&| +0#0000000&@58
-|<+0#00e0e07&|h+0#af5f00255&|e|a|d|e|r|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|h+0#af5f00255&|g|r|o|u|p|>+0#00e0e07&| +0#0000000&@66
-><+0#00e0e07&|h+0#af5f00255&|r|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|h+0#af5f00255&|t|m|l|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|i+0#af5f00255&|>+0#00e0e07&|.+4#0000000&@2|<+0#00e0e07&|/|i+0#af5f00255&|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|i+0#af5f00255&|f|r|a|m|e|>+0#00e0e07&| +0#0000000&@66
+|<+0#00e0e07#ffffff0|f+0#af5f00255&|o|r|m|>+0#00e0e07&|<|/|f+0#af5f00255&|o|r|m|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|h+0#af5f00255&|1|>+0#00e0e07&|H+0#0000000&|e|a|d|i|n|g| |L|e|v|e|l| |1|<+0#00e0e07&|/|h+0#af5f00255&|1|>+0#00e0e07&| +0#0000000&@50
+|<+0#00e0e07&|h+0#af5f00255&|2|>+0#00e0e07&|H+0#0000000&|e|a|d|i|n|g| |L|e|v|e|l| |3|<+0#00e0e07&|/|h+0#af5f00255&|2|>+0#00e0e07&| +0#0000000&@50
+|<+0#00e0e07&|h+0#af5f00255&|3|>+0#00e0e07&|H+0#0000000&|e|a|d|i|n|g| |L|e|v|e|l| |4|<+0#00e0e07&|/|h+0#af5f00255&|3|>+0#00e0e07&| +0#0000000&@50
+|<+0#00e0e07&|h+0#af5f00255&|4|>+0#00e0e07&|H+0#0000000&|e|a|d|i|n|g| |L|e|v|e|l| |4|<+0#00e0e07&|/|h+0#af5f00255&|4|>+0#00e0e07&| +0#0000000&@50
+><+0#00e0e07&|h+0#af5f00255&|5|>+0#00e0e07&|H+0#0000000&|e|a|d|i|n|g| |L|e|v|e|l| |5|<+0#00e0e07&|/|h+0#af5f00255&|5|>+0#00e0e07&| +0#0000000&@50
+|<+0#00e0e07&|h+0#af5f00255&|6|>+0#00e0e07&|H+0#0000000&|e|a|d|i|n|g| |L|e|v|e|l| |6|<+0#00e0e07&|/|h+0#af5f00255&|6|>+0#00e0e07&| +0#0000000&@50
+|<+0#00e0e07&|h+0#af5f00255&|e|a|d|>+0#00e0e07&|<|/|h+0#af5f00255&|e|a|d|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|h+0#af5f00255&|e|a|d|e|r|>+0#00e0e07&|<|/|h+0#af5f00255&|e|a|d|e|r|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|h+0#af5f00255&|g|r|o|u|p|>+0#00e0e07&|<|/|h+0#af5f00255&|g|r|o|u|p|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|h+0#af5f00255&|r|>+0#00e0e07&| +0#0000000&@70
+|<+0#00e0e07&|h+0#af5f00255&|t|m|l|>+0#00e0e07&|<|/|h+0#af5f00255&|t|m|l|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|i+0#af5f00255&|>+0#00e0e07&|i+0#0000000&|d|i|o|m|a|t|i|c| |t|e|x|t|<+0#00e0e07&|/|i+0#af5f00255&|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|i+0#af5f00255&|f|r|a|m|e|>+0#00e0e07&|<|/|i+0#af5f00255&|f|r|a|m|e|>+0#00e0e07&| +0#0000000&@57
|<+0#00e0e07&|i+0#af5f00255&|m|g|>+0#00e0e07&| +0#0000000&@69
|<+0#00e0e07&|i+0#af5f00255&|n|p|u|t|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|i+0#af5f00255&|n|s|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|k+0#af5f00255&|b|d|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|l+0#af5f00255&|a|b|e|l|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|l+0#af5f00255&|e|g|e|n|d|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|l+0#af5f00255&|i|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|l+0#af5f00255&|i|n|k|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|m+0#af5f00255&|a|i|n|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|m+0#af5f00255&|a|p|>+0#00e0e07&| +0#0000000&@69
-@57|5@1|,|1| @9|3|8|%|
+|<+0#00e0e07&|i+0#af5f00255&|n|s|>+0#00e0e07&|<|/|i+0#af5f00255&|n|s|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|k+0#af5f00255&|b|d|>+0#00e0e07&|<|/|k+0#af5f00255&|b|d|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|l+0#af5f00255&|a|b|e|l|>+0#00e0e07&|<|/|l+0#af5f00255&|a|b|e|l|>+0#00e0e07&| +0#0000000&@59
+@57|5@1|,|1| @9|3|6|%|
diff --git a/runtime/syntax/testdir/dumps/html_04.dump b/runtime/syntax/testdir/dumps/html_04.dump
index ef3acf7..b2416e8 100644
--- a/runtime/syntax/testdir/dumps/html_04.dump
+++ b/runtime/syntax/testdir/dumps/html_04.dump
@@ -1,20 +1,20 @@
-|<+0#00e0e07#ffffff0|m+0#af5f00255&|a|p|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|m+0#af5f00255&|a|r|k|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|m+0#af5f00255&|e|n|u|>+0#00e0e07&| +0#0000000&@68
+|<+0#00e0e07#ffffff0|l+0#af5f00255&|a|b|e|l|>+0#00e0e07&|<|/|l+0#af5f00255&|a|b|e|l|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|l+0#af5f00255&|e|g|e|n|d|>+0#00e0e07&|<|/|l+0#af5f00255&|e|g|e|n|d|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|l+0#af5f00255&|i|>+0#00e0e07&|<|/|l+0#af5f00255&|i|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|l+0#af5f00255&|i|n|k|>+0#00e0e07&| +0#0000000&@68
+|<+0#00e0e07&|m+0#af5f00255&|a|i|n|>+0#00e0e07&|<|/|m+0#af5f00255&|a|i|n|>+0#00e0e07&| +0#0000000&@61
+><+0#00e0e07&|m+0#af5f00255&|a|p|>+0#00e0e07&|<|/|m+0#af5f00255&|a|p|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|m+0#af5f00255&|a|r|k|>+0#00e0e07&|<|/|m+0#af5f00255&|a|r|k|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|m+0#af5f00255&|e|n|u|>+0#00e0e07&|<|/|m+0#af5f00255&|e|n|u|>+0#00e0e07&| +0#0000000&@61
|<+0#00e0e07&|m+0#af5f00255&|e|t|a|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|m+0#af5f00255&|e|t|e|r|>+0#00e0e07&| +0#0000000&@67
-><+0#00e0e07&|n+0#af5f00255&|a|v|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|n+0#af5f00255&|o|s|c|r|i|p|t|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|o+0#af5f00255&|b|j|e|c|t|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|o+0#af5f00255&|l|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|o+0#af5f00255&|p|t|g|r|o|u|p|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|o+0#af5f00255&|p|t|i|o|n|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|o+0#af5f00255&|u|t|p|u|t|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|p+0#af5f00255&|>+0#00e0e07&| +0#0000000&@71
-|<+0#00e0e07&|p+0#af5f00255&|i|c|t|u|r|e|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|p+0#af5f00255&|r|e|>+0#00e0e07&|.+0#0000000&@2|<+0#00e0e07&|/|p+0#af5f00255&|r|e|>+0#00e0e07&| +0#0000000&@60
-|<+0#00e0e07&|p+0#af5f00255&|r|o|g|r|e|s@1|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|q+0#af5f00255&|>+0#00e0e07&| +0#0000000&@71
-|<+0#00e0e07&|r+0#af5f00255&|p|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|r+0#af5f00255&|t|>+0#00e0e07&| +0#0000000&@70
-@57|7|3|,|1| @9|5|2|%|
+|<+0#00e0e07&|m+0#af5f00255&|e|t|e|r|>+0#00e0e07&|<|/|m+0#af5f00255&|e|t|e|r|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|n+0#af5f00255&|a|v|>+0#00e0e07&|<|/|n+0#af5f00255&|a|v|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|n+0#af5f00255&|o|s|c|r|i|p|t|>+0#00e0e07&|<|/|n+0#af5f00255&|o|s|c|r|i|p|t|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|o+0#af5f00255&|b|j|e|c|t|>+0#00e0e07&|<|/|o+0#af5f00255&|b|j|e|c|t|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|o+0#af5f00255&|l|>+0#00e0e07&|<|/|o+0#af5f00255&|l|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|o+0#af5f00255&|p|t|g|r|o|u|p|>+0#00e0e07&|<|/|o+0#af5f00255&|p|t|g|r|o|u|p|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|o+0#af5f00255&|p|t|i|o|n|>+0#00e0e07&|<|/|o+0#af5f00255&|p|t|i|o|n|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|o+0#af5f00255&|u|t|p|u|t|>+0#00e0e07&|<|/|o+0#af5f00255&|u|t|p|u|t|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|p+0#af5f00255&|>+0#00e0e07&|<|/|p+0#af5f00255&|>+0#00e0e07&| +0#0000000&@67
+|<+0#00e0e07&|p+0#af5f00255&|i|c|t|u|r|e|>+0#00e0e07&|<|/|p+0#af5f00255&|i|c|t|u|r|e|>+0#00e0e07&| +0#0000000&@55
+@57|7|3|,|1| @9|5|0|%|
diff --git a/runtime/syntax/testdir/dumps/html_05.dump b/runtime/syntax/testdir/dumps/html_05.dump
index 411a4f5..20df53e 100644
--- a/runtime/syntax/testdir/dumps/html_05.dump
+++ b/runtime/syntax/testdir/dumps/html_05.dump
@@ -1,20 +1,20 @@
-|<+0#00e0e07#ffffff0|r+0#af5f00255&|t|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|r+0#af5f00255&|u|b|y|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|s+0#af5f00255&|>+0#00e0e07&|.+1024#0000000&@2|<+0#00e0e07&|/|s+0#af5f00255&|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|s+0#af5f00255&|a|m|p|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|s+0#af5f00255&|c|r|i|p|t|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|s+0#af5f00255&|c|r|i|p|t|>+0#00e0e07&| +0#0000000&@54
-><+0#00e0e07&|s+0#af5f00255&|e|a|r|c|h|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|s+0#af5f00255&|e|c|t|i|o|n|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|s+0#af5f00255&|e|l|e|c|t|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|s+0#af5f00255&|l|o|t|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|s+0#af5f00255&|m|a|l@1|>+0#00e0e07&| +0#0000000&@67
+|<+0#00e0e07#ffffff0|p+0#af5f00255&|i|c|t|u|r|e|>+0#00e0e07&|<|/|p+0#af5f00255&|i|c|t|u|r|e|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|p+0#af5f00255&|r|e|>+0#00e0e07&|p+0#0000000&|r|e|f|o|r|m|a|t@1|e|d| |t|e|x|t|<+0#00e0e07&|/|p+0#af5f00255&|r|e|>+0#00e0e07&| +0#0000000&@46
+|<+0#00e0e07&|p+0#af5f00255&|r|o|g|r|e|s@1|>+0#00e0e07&|<|/|p+0#af5f00255&|r|o|g|r|e|s@1|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|q+0#af5f00255&|>+0#00e0e07&|<|/|q+0#af5f00255&|>+0#00e0e07&| +0#0000000&@67
+|<+0#00e0e07&|r+0#af5f00255&|p|>+0#00e0e07&|<|/|r+0#af5f00255&|p|>+0#00e0e07&| +0#0000000&@65
+><+0#00e0e07&|r+0#af5f00255&|t|>+0#00e0e07&|<|/|r+0#af5f00255&|t|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|r+0#af5f00255&|u|b|y|>+0#00e0e07&|<|/|r+0#af5f00255&|u|b|y|>+0#00e0e07&| +0#0000000&@61
+|<+0#0000e05&|!|-@1| |F|r|e@1|B|S|D| |f|a|i|l|u|r|e| +0#0000000&@54
+|<+0#0000e05&|s|>|s|t|r|i|k|e|t|h|r|o|u|g|h|<|/|s|>| +0#0000000&@54
+|-+0#0000e05&@1|>| +0#0000000&@71
+|<+0#00e0e07&|s+0#af5f00255&|a|m|p|>+0#00e0e07&|<|/|s+0#af5f00255&|a|m|p|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|s+0#af5f00255&|c|r|i|p|t|>+0#00e0e07&|<|/|s+0#af5f00255&|c|r|i|p|t|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|s+0#af5f00255&|e|a|r|c|h|>+0#00e0e07&|<|/|s+0#af5f00255&|e|a|r|c|h|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|s+0#af5f00255&|e|c|t|i|o|n|>+0#00e0e07&|<|/|s+0#af5f00255&|e|c|t|i|o|n|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|s+0#af5f00255&|e|l|e|c|t|>+0#00e0e07&|<|/|s+0#af5f00255&|e|l|e|c|t|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|s+0#af5f00255&|l|o|t|>+0#00e0e07&|<|/|s+0#af5f00255&|l|o|t|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|s+0#af5f00255&|m|a|l@1|>+0#00e0e07&|<|/|s+0#af5f00255&|m|a|l@1|>+0#00e0e07&| +0#0000000&@59
|<+0#00e0e07&|s+0#af5f00255&|o|u|r|c|e|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|s+0#af5f00255&|p|a|n|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|s+0#af5f00255&|t|r|o|n|g|>+0#00e0e07&|.+2#0000000&@2|<+0#00e0e07&|/|s+0#af5f00255&|t|r|o|n|g|>+0#00e0e07&| +0#0000000&@54
-|<+0#00e0e07&|s+0#af5f00255&|t|y|l|e|>+0#00e0e07&|.+0#0000000&@2|<+0#00e0e07&|/|s+0#af5f00255&|t|y|l|e|>+0#00e0e07&| +0#0000000&@56
-|<+0#00e0e07&|s+0#af5f00255&|u|b|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|s+0#af5f00255&|u|m@1|a|r|y|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|s+0#af5f00255&|u|p|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|t+0#af5f00255&|a|b|l|e|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|t+0#af5f00255&|b|o|d|y|>+0#00e0e07&| +0#0000000&@67
-@57|9|1|,|1| @9|6@1|%|
+|<+0#00e0e07&|s+0#af5f00255&|p|a|n|>+0#00e0e07&|<|/|s+0#af5f00255&|p|a|n|>+0#00e0e07&| +0#0000000&@61
+@57|9|1|,|1| @9|6|3|%|
diff --git a/runtime/syntax/testdir/dumps/html_06.dump b/runtime/syntax/testdir/dumps/html_06.dump
index 7482dce..d24392f 100644
--- a/runtime/syntax/testdir/dumps/html_06.dump
+++ b/runtime/syntax/testdir/dumps/html_06.dump
@@ -1,20 +1,20 @@
-|<+0#00e0e07#ffffff0|t+0#af5f00255&|b|o|d|y|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|t+0#af5f00255&|d|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|t+0#af5f00255&|e|m|p|l|a|t|e|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|t+0#af5f00255&|e|x|t|a|r|e|a|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|t+0#af5f00255&|f|o@1|t|>+0#00e0e07&| +0#0000000&@67
-><+0#00e0e07&|t+0#af5f00255&|h|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|t+0#af5f00255&|h|e|a|d|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|t+0#af5f00255&|i|m|e|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|t+0#af5f00255&|i|t|l|e|>+0#00e0e07&|.+0#e000e06&@2|<+0#00e0e07&|/|t+0#af5f00255&|i|t|l|e|>+0#00e0e07&| +0#0000000&@56
-|<+0#00e0e07&|t+0#af5f00255&|r|>+0#00e0e07&| +0#0000000&@70
+|<+0#00e0e07#ffffff0|s+0#af5f00255&|p|a|n|>+0#00e0e07&|<|/|s+0#af5f00255&|p|a|n|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|s+0#af5f00255&|t|r|o|n|g|>+0#00e0e07&|s+0#0000000&|t|r|o|n|g| |i|m|p|o|r|t|a|n|c|e|<+0#00e0e07&|/|s+0#af5f00255&|t|r|o|n|g|>+0#00e0e07&| +0#0000000&@40
+|<+0#00e0e07&|s+0#af5f00255&|t|y|l|e|>+0#00e0e07&|<|/|s+0#af5f00255&|t|y|l|e|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|s+0#af5f00255&|u|b|>+0#00e0e07&|<|/|s+0#af5f00255&|u|b|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|s+0#af5f00255&|u|m@1|a|r|y|>+0#00e0e07&|<|/|s+0#af5f00255&|u|m@1|a|r|y|>+0#00e0e07&| +0#0000000&@55
+><+0#00e0e07&|s+0#af5f00255&|u|p|>+0#00e0e07&|<|/|s+0#af5f00255&|u|p|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|t+0#af5f00255&|a|b|l|e|>+0#00e0e07&|<|/|t+0#af5f00255&|a|b|l|e|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|t+0#af5f00255&|b|o|d|y|>+0#00e0e07&|<|/|t+0#af5f00255&|b|o|d|y|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|t+0#af5f00255&|d|>+0#00e0e07&|<|/|t+0#af5f00255&|d|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|t+0#af5f00255&|e|m|p|l|a|t|e|>+0#00e0e07&|<|/|t+0#af5f00255&|e|m|p|l|a|t|e|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|t+0#af5f00255&|e|x|t|a|r|e|a|>+0#00e0e07&|<|/|t+0#af5f00255&|e|x|t|a|r|e|a|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|t+0#af5f00255&|f|o@1|t|>+0#00e0e07&|<|/|t+0#af5f00255&|f|o@1|t|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|t+0#af5f00255&|h|>+0#00e0e07&|<|/|t+0#af5f00255&|h|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|t+0#af5f00255&|h|e|a|d|>+0#00e0e07&|<|/|t+0#af5f00255&|h|e|a|d|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|t+0#af5f00255&|i|m|e|>+0#00e0e07&|<|/|t+0#af5f00255&|i|m|e|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|t+0#af5f00255&|i|t|l|e|>+0#00e0e07&|<|/|t+0#af5f00255&|i|t|l|e|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|t+0#af5f00255&|r|>+0#00e0e07&|<|/|t+0#af5f00255&|r|>+0#00e0e07&| +0#0000000&@65
|<+0#00e0e07&|t+0#af5f00255&|r|a|c|k|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|u+0#af5f00255&|>+0#00e0e07&|.+8#0000000&@2|<+0#00e0e07&|/|u+0#af5f00255&|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|u+0#af5f00255&|l|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|v+0#af5f00255&|a|r|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|v+0#af5f00255&|i|d|e|o|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|w+0#af5f00255&|b|r|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|x+0#af5f00255&|m|p|>+0#00e0e07&| +0#0000000&@69
-@75
-|<+0#0000e05&|!|-@1| |D|e|p|r|e|c|a|t|e|d| |E|l|e|m|e|n|t|s| |-@1|>| +0#0000000&@46
-@57|1|0|9|,|1| @8|8|1|%|
+|<+0#00e0e07&|u+0#af5f00255&|>+0#00e0e07&|u+0#0000000&|n|a|r|t|i|c|u|l|a|t|e|d| |a|n@1|o|t|a|t|i|o|n|<+0#00e0e07&|/|u+0#af5f00255&|>+0#00e0e07&| +0#0000000&@43
+@57|1|0|9|,|1| @8|7|6|%|
diff --git a/runtime/syntax/testdir/dumps/html_07.dump b/runtime/syntax/testdir/dumps/html_07.dump
index 9c5deaa..8a56d4d 100644
--- a/runtime/syntax/testdir/dumps/html_07.dump
+++ b/runtime/syntax/testdir/dumps/html_07.dump
@@ -1,20 +1,20 @@
-|<+0#0000e05#ffffff0|!|-@1| |D|e|p|r|e|c|a|t|e|d| |E|l|e|m|e|n|t|s| |-@1|>| +0#0000000&@46
-|<+0#00e0e07&|a+0#af5f00255&|c|r|o|n|y|m|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|b+0#af5f00255&|i|g|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|c+0#af5f00255&|e|n|t|e|r|>+0#00e0e07&| +0#0000000&@66
-|<+0#00e0e07&|d+0#af5f00255&|i|r|>+0#00e0e07&| +0#0000000&@69
-><+0#00e0e07&|f+0#af5f00255&|o|n|t|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|f+0#af5f00255&|r|a|m|e|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|f+0#af5f00255&|r|a|m|e|s|e|t|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|m+0#af5f00255&|a|r|q|u|e@1|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|m+0#af5f00255&|e|n|u|i|t|e|m|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|n+0#af5f00255&|o|b|r|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|p+0#af5f00255&|a|r|a|m|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|r+0#af5f00255&|b|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|r+0#af5f00255&|t|c|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&|.+1024#0000000&@2|<+0#00e0e07&|/|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&| +0#0000000&@54
-|<+0#00e0e07&|t+0#af5f00255&@1|>+0#00e0e07&| +0#0000000&@70
+|<+0#00e0e07#ffffff0|u+0#af5f00255&|>+0#00e0e07&|u+0#0000000&|n|a|r|t|i|c|u|l|a|t|e|d| |a|n@1|o|t|a|t|i|o|n|<+0#00e0e07&|/|u+0#af5f00255&|>+0#00e0e07&| +0#0000000&@43
+|<+0#00e0e07&|u+0#af5f00255&|l|>+0#00e0e07&|<|/|u+0#af5f00255&|l|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|v+0#af5f00255&|a|r|>+0#00e0e07&|<|/|v+0#af5f00255&|a|r|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|v+0#af5f00255&|i|d|e|o|>+0#00e0e07&|<|/|v+0#af5f00255&|i|d|e|o|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|w+0#af5f00255&|b|r|>+0#00e0e07&| +0#0000000&@69
+><+0#00e0e07&|x+0#af5f00255&|m|p|>+0#00e0e07&|<|/|x+0#af5f00255&|m|p|>+0#00e0e07&| +0#0000000&@63
@75
-|<+0#0000e05&|!|-@1| |N|o|t|e|:| |t|h|e|s|e| |d|e|p|r|e|c|a|t|e|d| |e|l|e|m|e|n|t|s| |h|a|v|e| |n|e|v|e|r| |b|e@1|n| |m|a|t|c|h|e|d| |-@1|>| +0#0000000&@10
-@57|1|2|7|,|1| @8|9|5|%|
+|<+0#0000e05&|!|-@1| |D|e|p|r|e|c|a|t|e|d| |E|l|e|m|e|n|t|s| |-@1|>| +0#0000000&@46
+|<+0#00e0e07&|a+0#af5f00255&|c|r|o|n|y|m|>+0#00e0e07&|<|/|a+0#af5f00255&|c|r|o|n|y|m|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|b+0#af5f00255&|i|g|>+0#00e0e07&|<|/|b+0#af5f00255&|i|g|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|c+0#af5f00255&|e|n|t|e|r|>+0#00e0e07&|<|/|c+0#af5f00255&|e|n|t|e|r|>+0#00e0e07&| +0#0000000&@57
+|<+0#00e0e07&|d+0#af5f00255&|i|r|>+0#00e0e07&|<|/|d+0#af5f00255&|i|r|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|f+0#af5f00255&|o|n|t|>+0#00e0e07&|<|/|f+0#af5f00255&|o|n|t|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|f+0#af5f00255&|r|a|m|e|>+0#00e0e07&|<|/|f+0#af5f00255&|r|a|m|e|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|f+0#af5f00255&|r|a|m|e|s|e|t|>+0#00e0e07&|<|/|f+0#af5f00255&|r|a|m|e|s|e|t|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|m+0#af5f00255&|a|r|q|u|e@1|>+0#00e0e07&|<|/|m+0#af5f00255&|a|r|q|u|e@1|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|m+0#af5f00255&|e|n|u|i|t|e|m|>+0#00e0e07&|<|/|m+0#af5f00255&|e|n|u|i|t|e|m|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|n+0#af5f00255&|o|b|r|>+0#00e0e07&|<|/|n+0#af5f00255&|o|b|r|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&|<|/|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&| +0#0000000&@53
+@57|1|2|7|,|1| @8|9|0|%|
diff --git a/runtime/syntax/testdir/dumps/html_08.dump b/runtime/syntax/testdir/dumps/html_08.dump
new file mode 100644
index 0000000..02a68e7
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/html_08.dump
@@ -0,0 +1,20 @@
+|<+0#00e0e07#ffffff0|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&|<|/|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|p+0#af5f00255&|a|r|a|m|>+0#00e0e07&| +0#0000000&@67
+|<+0#00e0e07&|r+0#af5f00255&|b|>+0#00e0e07&|<|/|r+0#af5f00255&|b|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|r+0#af5f00255&|t|c|>+0#00e0e07&|<|/|r+0#af5f00255&|t|c|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&|s+0#0000000&|t|r|i|k|e|t|h|r|o|u|g|h|<+0#00e0e07&|/|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&| +0#0000000&@44
+><+0#00e0e07&|t+0#af5f00255&@1|>+0#00e0e07&|<|/|t+0#af5f00255&@1|>+0#00e0e07&| +0#0000000&@65
+@75
+|<+0#0000e05&|!|-@1| |E|x|p|e|r|i|m|e|n|t|a|l| |-| |n|o|t| |h|i|g|h|l|i|g|h|t|e|d| |-@1|>| +0#0000000&@35
+|<+0#00e0e07&|p+0#0000000&|o|r|t|a|l|>+0#00e0e07&|<|/|p+0#0000000&|o|r|t|a|l|>+0#00e0e07&| +0#0000000&@57
+@75
+|<+0#0000e05&|!|-@1| |N|o|t|e|:| |t|h|e|s|e| |d|e|p|r|e|c|a|t|e|d| |e|l|e|m|e|n|t|s| |h|a|v|e| |n|e|v|e|r| |b|e@1|n| |m|a|t|c|h|e|d| |-@1|>| +0#0000000&@10
+|<+0#00e0e07&|i+0#0000000&|m|a|g|e|>+0#00e0e07&| +0#0000000&@67
+|<+0#00e0e07&|n+0#0000000&|o|e|m|b|e|d|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|p+0#0000000&|l|a|i|n|t|e|x|t|>+0#00e0e07&| +0#0000000&@63
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|4|5|,|1| @8|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/html_99.dump b/runtime/syntax/testdir/dumps/html_99.dump
index 080a0c6..14866b6 100644
--- a/runtime/syntax/testdir/dumps/html_99.dump
+++ b/runtime/syntax/testdir/dumps/html_99.dump
@@ -1,20 +1,20 @@
-|<+0#00e0e07#ffffff0|f+0#af5f00255&|r|a|m|e|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|f+0#af5f00255&|r|a|m|e|s|e|t|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|m+0#af5f00255&|a|r|q|u|e@1|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|m+0#af5f00255&|e|n|u|i|t|e|m|>+0#00e0e07&| +0#0000000&@64
-|<+0#00e0e07&|n+0#af5f00255&|o|b|r|>+0#00e0e07&| +0#0000000&@68
-|<+0#00e0e07&|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&| +0#0000000&@64
+|<+0#00e0e07#ffffff0|f+0#af5f00255&|r|a|m|e|>+0#00e0e07&|<|/|f+0#af5f00255&|r|a|m|e|>+0#00e0e07&| +0#0000000&@59
+|<+0#00e0e07&|f+0#af5f00255&|r|a|m|e|s|e|t|>+0#00e0e07&|<|/|f+0#af5f00255&|r|a|m|e|s|e|t|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|m+0#af5f00255&|a|r|q|u|e@1|>+0#00e0e07&|<|/|m+0#af5f00255&|a|r|q|u|e@1|>+0#00e0e07&| +0#0000000&@55
+|<+0#00e0e07&|m+0#af5f00255&|e|n|u|i|t|e|m|>+0#00e0e07&|<|/|m+0#af5f00255&|e|n|u|i|t|e|m|>+0#00e0e07&| +0#0000000&@53
+|<+0#00e0e07&|n+0#af5f00255&|o|b|r|>+0#00e0e07&|<|/|n+0#af5f00255&|o|b|r|>+0#00e0e07&| +0#0000000&@61
+|<+0#00e0e07&|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&|<|/|n+0#af5f00255&|o|f|r|a|m|e|s|>+0#00e0e07&| +0#0000000&@53
|<+0#00e0e07&|p+0#af5f00255&|a|r|a|m|>+0#00e0e07&| +0#0000000&@67
-|<+0#00e0e07&|r+0#af5f00255&|b|>+0#00e0e07&| +0#0000000&@70
-|<+0#00e0e07&|r+0#af5f00255&|t|c|>+0#00e0e07&| +0#0000000&@69
-|<+0#00e0e07&|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&|.+1024#0000000&@2|<+0#00e0e07&|/|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&| +0#0000000&@54
-|<+0#00e0e07&|t+0#af5f00255&@1|>+0#00e0e07&| +0#0000000&@70
+|<+0#00e0e07&|r+0#af5f00255&|b|>+0#00e0e07&|<|/|r+0#af5f00255&|b|>+0#00e0e07&| +0#0000000&@65
+|<+0#00e0e07&|r+0#af5f00255&|t|c|>+0#00e0e07&|<|/|r+0#af5f00255&|t|c|>+0#00e0e07&| +0#0000000&@63
+|<+0#00e0e07&|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&|s+0#0000000&|t|r|i|k|e|t|h|r|o|u|g|h|<+0#00e0e07&|/|s+0#af5f00255&|t|r|i|k|e|>+0#00e0e07&| +0#0000000&@44
+|<+0#00e0e07&|t+0#af5f00255&@1|>+0#00e0e07&|<|/|t+0#af5f00255&@1|>+0#00e0e07&| +0#0000000&@65
+@75
+|<+0#0000e05&|!|-@1| |E|x|p|e|r|i|m|e|n|t|a|l| |-| |n|o|t| |h|i|g|h|l|i|g|h|t|e|d| |-@1|>| +0#0000000&@35
+|<+0#00e0e07&|p+0#0000000&|o|r|t|a|l|>+0#00e0e07&|<|/|p+0#0000000&|o|r|t|a|l|>+0#00e0e07&| +0#0000000&@57
@75
|<+0#0000e05&|!|-@1| |N|o|t|e|:| |t|h|e|s|e| |d|e|p|r|e|c|a|t|e|d| |e|l|e|m|e|n|t|s| |h|a|v|e| |n|e|v|e|r| |b|e@1|n| |m|a|t|c|h|e|d| |-@1|>| +0#0000000&@10
|<+0#00e0e07&|i+0#0000000&|m|a|g|e|>+0#00e0e07&| +0#0000000&@67
|<+0#00e0e07&|n+0#0000000&|o|e|m|b|e|d|>+0#00e0e07&| +0#0000000&@65
-|<+0#00e0e07&|p+0#0000000&|l|a|i|n|t|e|x|t|>+0#00e0e07&| +0#0000000&@63
-@75
-|<+0#0000e05&|!|-@1| |E|x|p|e|r|i|m|e|n|t|a|l| |-@1|>| +0#0000000&@53
-><+0#00e0e07&|p+0#0000000&|o|r|t|a|l|>+0#00e0e07&| +0#0000000&@66
-@57|1|4|6|,|1| @8|B|o|t|
+><+0#00e0e07&|p+0#0000000&|l|a|i|n|t|e|x|t|>+0#00e0e07&| +0#0000000&@63
+@57|1|5|3|,|1| @8|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_annotations_00.dump b/runtime/syntax/testdir/dumps/java_annotations_00.dump
new file mode 100644
index 0000000..cb77259
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_annotations_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|h|i|g|h|l|i|g|h|t|_|f|u|n|c|t|i|o|n|s| |=| |'|s|t|y|l|e|'| +0#0000000&@16
+@75
+@75
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|;| @34
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|;| @39
+@75
+|c+0#00e0003&|l|a|s@1| +0#0000000&|A|n@1|o|t|a|t|i|o|n|s|T|e|s|t|s| @52
+|{| @73
+@4|@+0#e000e06&|T|a|r|g|e|t|(|E+0#0000000&|l|e|m|e|n|t|T|y|p|e|.|T|Y|P|E|_|U|S|E|)+0#e000e06&| +0#0000000&@41
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|a|g| @56
+@4|{| @69
+| +0#00e0e07&@7|S|t|r|i|n|g| |v|a|l|u|e|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @40
+| +0#00e0e07&@7|S|t|r|i|n|g| |k|i|n|d|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @41
+@4|}| @69
+@75
+@4|@+0#e000e06&|T|a|r|g|e|t|(|E+0#0000000&|l|e|m|e|n|t|T|y|p|e|.|T|Y|P|E|_|U|S|E|)+0#e000e06&| +0#0000000&@41
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|e|x|t| @55
+@4|{| @69
+| +0#00e0e07&@7|S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|{|"+0#e000002&@1|}+0#0000000&|;| @36
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_annotations_01.dump b/runtime/syntax/testdir/dumps/java_annotations_01.dump
new file mode 100644
index 0000000..a9810e8
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_annotations_01.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|}| @69
+@75
+@4|@+0#e000e06&|T|a|r|g|e|t|(|E+0#0000000&|l|e|m|e|n|t|T|y|p|e|.|T|Y|P|E|_|U|S|E|)+0#e000e06&| +0#0000000&@41
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|e|x|t| @55
+@4|{| @69
+| +0#00e0e07&@7>S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|{|"+0#e000002&@1|}+0#0000000&|;| @36
+@4|}| @69
+@75
+@4|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&| @61
+@8|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| @47
+@8|E|l|e|m|e|n|t|T|y|p|e|.|P|A|R|A|M|E|T|E|R|,| @44
+@8|E|l|e|m|e|n|t|T|y|p|e|.|T|Y|P|E|,| @49
+@4|}|)+0#e000e06&| +0#0000000&@68
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|L|a|b|e|l|s| @53
+@4|{| @69
+| +0#00e0e07&@7|L|a|b|e|l|[|]| |v|a|l|u|e|(|)|;+0#0000000&| @50
+@4|}| @69
+@75
+@4|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|(|{+0#0000000&| @40
+@57|1|9|,|3|-|9| @7|2@1|%|
diff --git a/runtime/syntax/testdir/dumps/java_annotations_02.dump b/runtime/syntax/testdir/dumps/java_annotations_02.dump
new file mode 100644
index 0000000..e6eebf1
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_annotations_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|(|{+0#0000000&| @40
+@8|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| @26
+@8|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|.|P|A|R|A|M|E|T|E|R|,| @23
+@8|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|.|T|Y|P|E|,| @28
+@4|}|)+0#e000e06&| +0#0000000&@68
+@4>@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(|L+0#0000000&|a|b|e|l|s|.|c+0#00e0003&|l|a|s@1|)+0#e000e06&| +0#0000000&@24
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|L|a|b|e|l| @54
+@4|{| @69
+| +0#00e0e07&@7|S|t|r|i|n|g| |v|a|l|u|e|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @40
+| +0#00e0e07&@7|C|l|a|s@1|<|?|>| |t|y|p|e|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|L|a|b|e|l|.|c+0#00e0003&|l|a|s@1|;+0#0000000&| @30
+| +0#00e0e07&@7|b+0#00e0003&|o@1|l|e|a|n| +0#00e0e07&|r|e|d|u|n|d|a|n|t|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|t+0#e000002&|r|u|e|;+0#0000000&| @33
+| +0#00e0e07&@7|T|e|x|t| |t|e|x|t|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|@+0#e000e06&|T|e|x|t|;+0#0000000&| @40
+| +0#00e0e07&@7|T|a|g| |h|e|a|d|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|@+0#e000e06&|T|a|g|(|)|;+0#0000000&| @40
+| +0#00e0e07&@7|T|a|g| |t|a|i|l|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|@+0#e000e06&|T|a|g|(|v+0#0000000&|a|l|u|e| |=| |"+0#e000002&@1|,+0#0000000&| |k|i|n|d| |=| |"+0#e000002&@1|)+0#e000e06&|;+0#0000000&| @19
+@4|}| @69
+@75
+@4|/+0#0000e05&|*| |U|s|e| |i|d|e|n|t|i|t|y| |c|a|s|t| |e|x|p|r|e|s@1|i|o|n|s| |t|o| |n|e|s|t| |T|Y|P|E|_|U|S|E| |a|n@1|o|t|a|t|i|o|n|s|.| |*|/| +0#0000000&@5
+@32|@+0#e000e06&|L|a|b|e|l|(| +0#0000000&@35
+@28|(|@+0#e000e06&|T|e|x|t|(|{+0#0000000&| @38
+@57|3|7|,|2|-|5| @7|5|2|%|
diff --git a/runtime/syntax/testdir/dumps/java_annotations_03.dump b/runtime/syntax/testdir/dumps/java_annotations_03.dump
new file mode 100644
index 0000000..0e7a0b8
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_annotations_03.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@27|(|@+0#e000e06&|T|e|x|t|(|{+0#0000000&| @38
+@8|(|@+0#e000e06&|T|e|x|t|(|{+0#0000000&| |"+0#e000002&|a|"|,+0#0000000&| |"+0#e000002&|a@1|"|,+0#0000000&| |"+0#e000002&|a@2|"|,+0#0000000&| |"+0#e000002&|a@3|"|,+0#0000000&| |}|)+0#e000e06&| +0#0000000&|S|t|r|i|n|g|)| |"+0#e000002&|a|s|"|,+0#0000000&| @15
+@8|(|@+0#e000e06&|T|e|x|t|(|{+0#0000000&| |"+0#e000002&|b|"|,+0#0000000&| |"+0#e000002&|b@1|"|,+0#0000000&| |"+0#e000002&|b@2|"|,+0#0000000&| |"+0#e000002&|b@3|"|,+0#0000000&| |}|)+0#e000e06&| +0#0000000&|S|t|r|i|n|g|)| |"+0#e000002&|b|s|"|,+0#0000000&| @15
+@8|(|@+0#e000e06&|T|e|x|t|(|{+0#0000000&| |"+0#e000002&|c|"|,+0#0000000&| |"+0#e000002&|c@1|"|,+0#0000000&| |"+0#e000002&|c@2|"|,+0#0000000&| |"+0#e000002&|c@3|"|,+0#0000000&| |}|)+0#e000e06&| +0#0000000&|S|t|r|i|n|g|)| |"+0#e000002&|c|s|"|,+0#0000000&| @15
+@8|(|@+0#e000e06&|T|e|x|t|(|{+0#0000000&| |"+0#e000002&|d|"|,+0#0000000&| |"+0#e000002&|d@1|"|,+0#0000000&| |"+0#e000002&|d@2|"|,+0#0000000&| |"+0#e000002&|d@3|"|,+0#0000000&| |}|)+0#e000e06&| +0#0000000&|S|t|r|i|n|g|)| |"+0#e000002&|d|s|"|,+0#0000000&| @15
+@28>}|)+0#e000e06&| +0#0000000&|S|t|r|i|n|g|)| |"+0#e000002&|a|b|c|d|"|)+0#e000e06&| +0#0000000&@28
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|P|r|i|m|e|r| |{| |}| @50
+@75
+@4|@+0#e000e06&|L|a|b|e|l| +0#0000000&|@+0#e000e06&|L|a|b|e|l|(|)| +0#0000000&|@+0#e000e06&|L|a|b|e|l|(|"+0#0000000&@2| @44
+| +0#e000002&@3|n|\| +0#0000000&@68
+| +0#e000002&@3|o|\| +0#0000000&@68
+| +0#e000002&@3|O|\| +0#0000000&@68
+| +0#e000002&@3|p|"+0#0000000&@2|)+0#e000e06&| +0#0000000&@65
+@4|@+0#e000e06&|L|a|b|e|l|(|h+0#0000000&|e|a|d| |=| |@+0#e000e06&|T|a|g|(|v+0#0000000&|a|l|u|e| |=| |"+0#e000002&|@|L|a|b|e|l|"|/+0#0000e05&|*|,| |k|i|n|d| |=| |"|n|a|m|e|"|*|/|)+0#e000e06&@1| +0#0000000&@14
+@4|@+0#e000e06&|L|a|b|e|l|(|/+0#0000e05&@1| |v|a|l|u|e| |=| |"|M|e|t|h|o|d|"|,| +0#0000000&@43
+@8|t|y|p|e| |=| |A|n@1|o|t|a|t|i|o|n|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|,+0#0000000&| @36
+@8|r|e|d|u|n|d|a|n|t| |=| |!@2|(|1+0#e000002&| +0#0000000&|!|=| |1+0#e000002&|)+0#0000000&|,| @42
+@8|h|e|a|d| |=| |@+0#e000e06&|T|a|g|(|v+0#0000000&|a|l|u|e| |=| |"+0#e000002&|@|L|a|b|e|l|"|)+0#e000e06&|,+0#0000000&| @36
+@8|t|e|x|t| |=| |@+0#e000e06&|T|e|x|t|(|{+0#0000000&| |"+0#e000002&|}|)|"|,+0#0000000&| |"+0#e000002&|(|{|"| +0#0000000&|}|)+0#e000e06&@1| +0#0000000&@37
+@57|5@1|,|8|-|2|9| @6|8|3|%|
diff --git a/runtime/syntax/testdir/dumps/java_annotations_04.dump b/runtime/syntax/testdir/dumps/java_annotations_04.dump
new file mode 100644
index 0000000..edd008b
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_annotations_04.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@7|t|e|x|t| |=| |@+0#e000e06&|T|e|x|t|(|{+0#0000000&| |"+0#e000002&|}|)|"|,+0#0000000&| |"+0#e000002&|(|{|"| +0#0000000&|}|)+0#e000e06&@1| +0#0000000&@37
+| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|n|o|O|p|(|@+0#e000e06&|L|a|b|e|l| +0#00e0e07&|@+0#e000e06&|L|a|b|e|l|(|)| +0#00e0e07&|@+0#e000e06&|L|a|b|e|l|(|"+0#e000002&|d|u|m@1|y|"|)+0#e000e06&| +0#0000000&@22
+| +0#00e0e07&@7|@+0#e000e06&|L|a|b|e|l|(|h+0#00e0e07&|e|a|d| |=| |@+0#e000e06&|T|a|g|(|/+0#0000e05&|*|v|a|l|u|e| |=| |"|@|L|a|b|e|l|"|,|*|/| +0#00e0e07&|k|i|n|d| |=| |"+0#e000002&|n|a|m|e|"|)+0#e000e06&@1| +0#0000000&@10
+| +0#00e0e07&@7|@+0#e000e06&|L|a|b|e|l|(|/+0#0000e05&@1| |v|a|l|u|e| |=| |"|P|a|r|a|m|e|t|e|r|"|,| +0#0000000&@36
+| +0#00e0e07&@11|t|y|p|e| |=| |A|n@1|o|t|a|t|i|o|n|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|,+0#00e0e07&| +0#0000000&@32
+| +0#00e0e07&@11>h|e|a|d| |=| |@+0#e000e06&|T|a|g|(|v+0#00e0e07&|a|l|u|e| |=| |"+0#e000002&|@|L|a|b|e|l|"|)+0#e000e06&|,+0#00e0e07&| +0#0000000&@32
+| +0#00e0e07&@11|t|e|x|t| |=| |@+0#e000e06&|T|e|x|t|(|{+0#00e0e07&| |"+0#e000002&|)|{|"|,+0#00e0e07&| |"+0#e000002&|}|(|"| +0#00e0e07&|}|)+0#e000e06&@1| +0#0000000&@33
+| +0#00e0e07&@7|O|b|j|e|c|t| |d|u|m@1|y|)| +0#0000000&@53
+@4|{| @69
+@4|}| @69
+|}| @73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|7|3|,|4|-|1|3| @6|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_annotations_99.dump b/runtime/syntax/testdir/dumps/java_annotations_99.dump
new file mode 100644
index 0000000..7d158f2
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_annotations_99.dump
@@ -0,0 +1,20 @@
+| +0#e000002#ffffff0@3|o|\| +0#0000000&@68
+| +0#e000002&@3|O|\| +0#0000000&@68
+| +0#e000002&@3|p|"+0#0000000&@2|)+0#e000e06&| +0#0000000&@65
+@4|@+0#e000e06&|L|a|b|e|l|(|h+0#0000000&|e|a|d| |=| |@+0#e000e06&|T|a|g|(|v+0#0000000&|a|l|u|e| |=| |"+0#e000002&|@|L|a|b|e|l|"|/+0#0000e05&|*|,| |k|i|n|d| |=| |"|n|a|m|e|"|*|/|)+0#e000e06&@1| +0#0000000&@14
+@4|@+0#e000e06&|L|a|b|e|l|(|/+0#0000e05&@1| |v|a|l|u|e| |=| |"|M|e|t|h|o|d|"|,| +0#0000000&@43
+@8|t|y|p|e| |=| |A|n@1|o|t|a|t|i|o|n|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|,+0#0000000&| @36
+@8|r|e|d|u|n|d|a|n|t| |=| |!@2|(|1+0#e000002&| +0#0000000&|!|=| |1+0#e000002&|)+0#0000000&|,| @42
+@8|h|e|a|d| |=| |@+0#e000e06&|T|a|g|(|v+0#0000000&|a|l|u|e| |=| |"+0#e000002&|@|L|a|b|e|l|"|)+0#e000e06&|,+0#0000000&| @36
+@8|t|e|x|t| |=| |@+0#e000e06&|T|e|x|t|(|{+0#0000000&| |"+0#e000002&|}|)|"|,+0#0000000&| |"+0#e000002&|(|{|"| +0#0000000&|}|)+0#e000e06&@1| +0#0000000&@37
+| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|n|o|O|p|(|@+0#e000e06&|L|a|b|e|l| +0#00e0e07&|@+0#e000e06&|L|a|b|e|l|(|)| +0#00e0e07&|@+0#e000e06&|L|a|b|e|l|(|"+0#e000002&|d|u|m@1|y|"|)+0#e000e06&| +0#0000000&@22
+| +0#00e0e07&@7|@+0#e000e06&|L|a|b|e|l|(|h+0#00e0e07&|e|a|d| |=| |@+0#e000e06&|T|a|g|(|/+0#0000e05&|*|v|a|l|u|e| |=| |"|@|L|a|b|e|l|"|,|*|/| +0#00e0e07&|k|i|n|d| |=| |"+0#e000002&|n|a|m|e|"|)+0#e000e06&@1| +0#0000000&@10
+| +0#00e0e07&@7|@+0#e000e06&|L|a|b|e|l|(|/+0#0000e05&@1| |v|a|l|u|e| |=| |"|P|a|r|a|m|e|t|e|r|"|,| +0#0000000&@36
+| +0#00e0e07&@11|t|y|p|e| |=| |A|n@1|o|t|a|t|i|o|n|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|,+0#00e0e07&| +0#0000000&@32
+| +0#00e0e07&@11|h|e|a|d| |=| |@+0#e000e06&|T|a|g|(|v+0#00e0e07&|a|l|u|e| |=| |"+0#e000002&|@|L|a|b|e|l|"|)+0#e000e06&|,+0#00e0e07&| +0#0000000&@32
+| +0#00e0e07&@11|t|e|x|t| |=| |@+0#e000e06&|T|e|x|t|(|{+0#00e0e07&| |"+0#e000002&|)|{|"|,+0#00e0e07&| |"+0#e000002&|}|(|"| +0#00e0e07&|}|)+0#e000e06&@1| +0#0000000&@33
+| +0#00e0e07&@7|O|b|j|e|c|t| |d|u|m@1|y|)| +0#0000000&@53
+@4|{| @69
+@4|}| @69
+>}| @73
+@57|7|8|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_enfoldment_00.dump b/runtime/syntax/testdir/dumps/java_enfoldment_00.dump
new file mode 100644
index 0000000..9596869
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_enfoldment_00.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1>/+0&#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t|l|o|c|a|l| |f|o|l|d|e|n|a|b|l|e| |f|o|l|d|c|o|l|u|m|n|=|2| |f|o|l|d|m|e|t|h|o|d|=|s|y|n|t|a|x| +0#0000000&@4
+| +0#0000e05#a8a8a8255@1|/+0&#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|m|a|r|k|_|b|r|a|c|e|s|_|i|n|_|p|a|r|e|n|s|_|a|s|_|e|r@1|o|r|s| |=| |1| +0#0000000&@8
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| |1|6| |l|i|n|e|s|:| |@|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|{|-@39
+| @1|c+0#00e0003#ffffff0|l|a|s@1| +0#0000000&|F|o|l|d|i|n|g|T|e|s|t|s| |{| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|F|o|l|d|e|n|a|b|l|e| @48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| |1|9| |l|i|n|e|s|:| |s|t|a|t|i|c| |{|-@50
+| @1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| |O|b|j|e|c|t| |b@1| |=| |(@1|O|b|j|e|c|t|)| |n+0#af5f00255&|e|w| +0#0000000&|b+0#00e0003&|y|t|e|[+0#0000000&|]|{+0#ffffff16#ff404010|}|)+0#0000000#ffffff0|;| |}| @28
+|++0#0000e05#a8a8a8255| |+|-@1| @1|8| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| @1|3| |l|i|n|e|s|:| @2|*| |N|o| |o|p|e|r|a|t|i|o|n|.|-@41
+| @1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|1|(|)| |{| |}| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|2|(|)| @56
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_enfoldment_01.dump b/runtime/syntax/testdir/dumps/java_enfoldment_01.dump
new file mode 100644
index 0000000..f6feccc
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_enfoldment_01.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1|/+0&#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t|l|o|c|a|l| |f|o|l|d|e|n|a|b|l|e| |f|o|l|d|c|o|l|u|m|n|=|2| |f|o|l|d|m|e|t|h|o|d|=|s|y|n|t|a|x| +0#0000000&@4
+| +0#0000e05#a8a8a8255@1|/+0&#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|m|a|r|k|_|b|r|a|c|e|s|_|i|n|_|p|a|r|e|n|s|_|a|s|_|e|r@1|o|r|s| |=| |1| +0#0000000&@8
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| >+|-@1| |1|6| |l|i|n|e|s|:| |@|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|{|-@39
+| @1|c+0#00e0003#ffffff0|l|a|s@1| +0#0000000&|F|o|l|d|i|n|g|T|e|s|t|s| |{| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|F|o|l|d|e|n|a|b|l|e| @48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| |1|9| |l|i|n|e|s|:| |s|t|a|t|i|c| |{|-@50
+| @1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| |O|b|j|e|c|t| |b@1| |=| |(@1|O|b|j|e|c|t|)| |n+0#af5f00255&|e|w| +0#0000000&|b+0#00e0003&|y|t|e|[+0#0000000&|]|{+0#ffffff16#ff404010|}|)+0#0000000#ffffff0|;| |}| @28
+|++0#0000e05#a8a8a8255| |+|-@1| @1|8| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| @1|3| |l|i|n|e|s|:| @2|*| |N|o| |o|p|e|r|a|t|i|o|n|.|-@41
+| @1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|1|(|)| |{| |}| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|2|(|)| @56
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+@57|1|9|,|1| @9|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_enfoldment_02.dump b/runtime/syntax/testdir/dumps/java_enfoldment_02.dump
new file mode 100644
index 0000000..bff7ffc
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_enfoldment_02.dump
@@ -0,0 +1,20 @@
+|++0#0000e05#a8a8a8255| |+|-@1| |1|6| |l|i|n|e|s|:| |@|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|{|-@39
+| @1|c+0#00e0003#ffffff0|l|a|s@1| +0#0000000&|F|o|l|d|i|n|g|T|e|s|t|s| |{| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|F|o|l|d|e|n|a|b|l|e| @48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| >+|-@1| |1|9| |l|i|n|e|s|:| |s|t|a|t|i|c| |{|-@50
+| @1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| |O|b|j|e|c|t| |b@1| |=| |(@1|O|b|j|e|c|t|)| |n+0#af5f00255&|e|w| +0#0000000&|b+0#00e0003&|y|t|e|[+0#0000000&|]|{+0#ffffff16#ff404010|}|)+0#0000000#ffffff0|;| |}| @28
+|++0#0000e05#a8a8a8255| |+|-@1| @1|8| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| @1|3| |l|i|n|e|s|:| @2|*| |N|o| |o|p|e|r|a|t|i|o|n|.|-@41
+| @1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|1|(|)| |{| |}| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|2|(|)| @56
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|3|(|)| |{|-@44
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|4|(|)| |{|-@44
+| +0#0000000#ffffff0@56|3|7|,|4|-|1| @7|1|4|%|
diff --git a/runtime/syntax/testdir/dumps/java_enfoldment_03.dump b/runtime/syntax/testdir/dumps/java_enfoldment_03.dump
new file mode 100644
index 0000000..6e96876
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_enfoldment_03.dump
@@ -0,0 +1,20 @@
+|++0#0000e05#a8a8a8255| |+|-@1| |1|9| |l|i|n|e|s|:| |s|t|a|t|i|c| |{|-@50
+| @1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| |O|b|j|e|c|t| |b@1| |=| |(@1|O|b|j|e|c|t|)| |n+0#af5f00255&|e|w| +0#0000000&|b+0#00e0003&|y|t|e|[+0#0000000&|]|{+0#ffffff16#ff404010|}|)+0#0000000#ffffff0|;| |}| @28
+|++0#0000e05#a8a8a8255| |+|-@1| @1|8| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| >+|-@1| @1|3| |l|i|n|e|s|:| @2|*| |N|o| |o|p|e|r|a|t|i|o|n|.|-@41
+| @1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|1|(|)| |{| |}| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|2|(|)| @56
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|3|(|)| |{|-@44
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|4|(|)| |{|-@44
+| @1|}+0#0000000#ffffff0| @71
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| @1|5| |l|i|n|e|s|:| @1|*| |S|o|m|e| |n|o|t|e|.|-@45
+|+| |+|-@1| @1|5| |l|i|n|e|s|:| @1|*| |A| |s|u|m@1|a|r|y|.|-@45
+| @1|/+0&#ffffff0@1| +0#0000000&@70
+@57|5@1|,|2|-|1| @7|8|2|%|
diff --git a/runtime/syntax/testdir/dumps/java_enfoldment_04.dump b/runtime/syntax/testdir/dumps/java_enfoldment_04.dump
new file mode 100644
index 0000000..563a92f
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_enfoldment_04.dump
@@ -0,0 +1,20 @@
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|3|(|)| |{|-@44
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|4|(|)| |{|-@44
+| @1|}+0#0000000#ffffff0| @71
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| >+|-@1| @1|5| |l|i|n|e|s|:| @1|*| |S|o|m|e| |n|o|t|e|.|-@45
+|+| |+|-@1| @1|5| |l|i|n|e|s|:| @1|*| |A| |s|u|m@1|a|r|y|.|-@45
+| @1|/+0&#ffffff0@1| +0#0000000&@70
+| +0#0000e05#a8a8a8255@1|/+0&#ffffff0@1| |{| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|/+0&#ffffff0@1| |}| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |1|2@1|||.@54
+|~+0#4040ff13#ffffff0| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|7|3|,|2|-|1| @7|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_enfoldment_99.dump b/runtime/syntax/testdir/dumps/java_enfoldment_99.dump
new file mode 100644
index 0000000..771ae98
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_enfoldment_99.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| @1|3| |l|i|n|e|s|:| @2|*| |N|o| |o|p|e|r|a|t|i|o|n|.|-@41
+| @1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|1|(|)| |{| |}| @52
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|2|(|)| @56
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |{|-@57
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|3|(|)| |{|-@44
+| @1| +0#0000000#ffffff0@3|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@48
+|++0#0000e05#a8a8a8255| |+|-@1| @1|2| |l|i|n|e|s|:| |v|o|i|d| |n|o|O|p|4|(|)| |{|-@44
+| @1|}+0#0000000#ffffff0| @71
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| |+|-@1| @1|5| |l|i|n|e|s|:| @1|*| |S|o|m|e| |n|o|t|e|.|-@45
+|+| |+|-@1| @1|5| |l|i|n|e|s|:| @1|*| |A| |s|u|m@1|a|r|y|.|-@45
+| @1|/+0&#ffffff0@1| +0#0000000&@70
+| +0#0000e05#a8a8a8255@1|/+0&#ffffff0@1| |{| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|/+0&#ffffff0@1| |}| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|++0#0000e05#a8a8a8255| >+|-@1| @1|2| |l|i|n|e|s|:| |1|2@1|||.@54
+| +0#0000000#ffffff0@56|8|6|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_00.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_00.dump
new file mode 100644
index 0000000..cbcdd8a
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|h|i|g|h|l|i|g|h|t|_|f|u|n|c|t|i|o|n|s| |=| |'|s|t|y|l|e|'| +0#0000000&@16
+@75
+@75
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|;| @34
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|B|i|n|a|r|y|O|p|e|r|a|t|o|r|;| @33
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|;| @39
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|P|r|e|d|i|c|a|t|e|;| @38
+@75
+|c+0#00e0003&|l|a|s@1| +0#0000000&|L|a|m|b|d|a|E|x|p|r|e|s@1|i|o|n|s|T|e|s|t|s| @3|/+0#0000e05&@1| |J|D|K| |2|1|+|.| +0#0000000&@31
+|{| @73
+| +0#00e0e07&@3|<|I|1|,| |C|1|,| |C|2|,| |T|1|,| |T|2|,| |T|3|,| |Z|1|,| |Z|2|,| |Z|3|,| |S|1|,| |S|2|,| |S|3|>| |v+0#00e0003&|o|i|d| +0#00e0e07&|t|e|s|t|(|)| +0#0000000&@10
+@4|{| @2|/+0#0000e05&@1| |S|c|h|ö|n|f|i|n|k|e|l|'|s| |f|u|n|c|t|i|o|n|s|.| +0#0000000&@39
+@8|I|<|I|1|>| |i| |=| |x+0#00e0e07&| |-|>| +0#0000000&|x|;| @49
+@8|C|<|C|1|,| |C|2|>| |c| |=| |x+0#00e0e07&| |-|>| +0#0000000&|y+0#00e0e07&| |-|>| +0#0000000&|x|;| @40
+@8|T|<|T|1|,| |T|2|,| |T|3|>| |t| |=| |f+0#00e0e07&| |-|>| +0#0000000&|y+0#00e0e07&| |-|>| +0#0000000&|x+0#00e0e07&| |-|>| +0#0000000&|f|.|a|p@1|l|y|(|x|)|.|a|p@1|l|y|(|y|)|;| @13
+@8|Z|<|Z|1|,| |Z|2|,| |Z|3|>| |z| |=| |f+0#00e0e07&| |-|>| +0#0000000&|g+0#00e0e07&| |-|>| +0#0000000&|x+0#00e0e07&| |-|>| +0#0000000&|f|.|a|p@1|l|y|(|g|.|a|p@1|l|y|(|x|)@1|;| @13
+@8|S|<|S|1|,| |S|2|,| |S|3|>| |s| |=| |f+0#00e0e07&| |-|>| +0#0000000&|g+0#00e0e07&| |-|>| +0#0000000&|x+0#00e0e07&| |-|>| +0#0000000&|f|.|a|p@1|l|y|(|x|)| @23
+@24|.|a|p@1|l|y|(|g|.|a|p@1|l|y|(|x|)@1|;| @31
+@75
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_01.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_01.dump
new file mode 100644
index 0000000..4753266
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_01.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@7|C|<|C|1|,| |C|2|>| |c| |=| |x+0#00e0e07&| |-|>| +0#0000000&|y+0#00e0e07&| |-|>| +0#0000000&|x|;| @40
+@8|T|<|T|1|,| |T|2|,| |T|3|>| |t| |=| |f+0#00e0e07&| |-|>| +0#0000000&|y+0#00e0e07&| |-|>| +0#0000000&|x+0#00e0e07&| |-|>| +0#0000000&|f|.|a|p@1|l|y|(|x|)|.|a|p@1|l|y|(|y|)|;| @13
+@8|Z|<|Z|1|,| |Z|2|,| |Z|3|>| |z| |=| |f+0#00e0e07&| |-|>| +0#0000000&|g+0#00e0e07&| |-|>| +0#0000000&|x+0#00e0e07&| |-|>| +0#0000000&|f|.|a|p@1|l|y|(|g|.|a|p@1|l|y|(|x|)@1|;| @13
+@8|S|<|S|1|,| |S|2|,| |S|3|>| |s| |=| |f+0#00e0e07&| |-|>| +0#0000000&|g+0#00e0e07&| |-|>| +0#0000000&|x+0#00e0e07&| |-|>| +0#0000000&|f|.|a|p@1|l|y|(|x|)| @23
+@24|.|a|p@1|l|y|(|g|.|a|p@1|l|y|(|x|)@1|;| @31
+> @74
+@8|I|<|I|1|>| |i|0|1| |=| |(+0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)| |-|>| +0#0000000&|x|;| @41
+@8|I|<|I|1|>| |i|0|2| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)| |-|>| +0#0000000&|x|;| @31
+@8|I|<|I|1|>| |i|0|3| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)| |-|>| +0#0000000&|x|;| @21
+@8|I|<|I|1|>| |i|0|4| |=| |(+0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)| |-|>| +0#0000000&|x|;| @35
+@8|I|<|I|1|>| |i|0|5| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)| |-|>| +0#0000000&|x|;| @25
+@8|I|<|I|1|>| |i|0|6| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)| |-|>| +0#0000000&|x|;| @15
+@8|I|<|I|1|>| |i|0|7| |=| |(+0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| @42
+@8|I|<|I|1|>| |i|0|8| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| @32
+@8|I|<|I|1|>| |i|0|9| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| @22
+@8|I|<|I|1|>| |i|1|0| |=| |(+0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| @36
+@8|I|<|I|1|>| |i|1@1| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| @26
+@8|I|<|I|1|>| |i|1|2| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| @16
+@75
+@57|1|9|,|0|-|1| @8|9|%|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_02.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_02.dump
new file mode 100644
index 0000000..258e3c0
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+@8|I|<|I|1|[|]|>| |i@1|0|1| |=| |(+0#00e0e07&|I|1|.@2| |x|)| |-|>| +0#0000000&|x|;| @36
+@8|I|<|I|1|[|]|>| |i@1|0|2| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1|.@2| |x|)| |-|>| +0#0000000&|x|;| @26
+@8|I|<|I|1|[|]|>| |i@1|0|3| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1|.@2| |x|)| |-|>| +0#0000000&|x|;| @16
+@8|I|<|I|1|[|]|>| |i@1|0|4| |=| |(+0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1|.@2| |x|)| |-|>| +0#0000000&|x|;| @30
+@8>I|<|I|1|[|]|>| |i@1|0|5| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1|.@2| |x|)| |-|>| +0#0000000&|x|;| @20
+@8|I|<|I|1|[|]|>| |i@1|0|6| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1|.@2| |x|)| |-|>| +0#0000000&|x|;| @10
+@75
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|1| |=| |(+0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|,| |v+0#af5f00255&|a|r| +0#00e0e07&|y|)| |-|>| +0#0000000&|x|;| @13
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|2| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|,| +0#0000000&@16
+| +0#00e0e07&@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|y|)| |-|>| +0#0000000&|x|;| @32
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|3| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#0000000&@9
+| +0#00e0e07&@19|x|,| |@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|y|)| |-|>| +0#0000000&|x|;| @19
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|4| |=| |(+0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|,| +0#0000000&@20
+| +0#00e0e07&@19|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|y|)| |-|>| +0#0000000&|x|;| @36
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|5| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#0000000&@17
+| +0#00e0e07&@19|v+0#af5f00255&|a|r| +0#00e0e07&|x|,| |@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|y|)| |-|>| +0#0000000&|x|;| @19
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|6| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#0000000&@23
+| +0#00e0e07&@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|,| +0#0000000&@32
+@57|3|7|,|3|-|9| @7|2@1|%|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_03.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_03.dump
new file mode 100644
index 0000000..094bdd6
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_03.dump
@@ -0,0 +1,20 @@
+| +0#00e0e07#ffffff0@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|,| +0#0000000&@32
+| +0#00e0e07&@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#0000000&@45
+| +0#00e0e07&@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|y|)| |-|>| +0#0000000&|x|;| @26
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|7| |=| |(+0#00e0e07&|I|1| |x|,| |I|1| |y|)| |-|>| +0#0000000&|x|;| @15
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|8| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1| |x|,| +0#0000000&@17
+| +0#00e0e07&@19>@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1| |y|)| |-|>| +0#0000000&|x|;| @33
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|0|9| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1| +0#0000000&@10
+| +0#00e0e07&@19|x|,| |@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1| |y|)| |-|>| +0#0000000&|x|;| @20
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|1|0| |=| |(+0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |x|,| +0#0000000&@21
+| +0#00e0e07&@19|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |y|)| |-|>| +0#0000000&|x|;| @37
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|1@1| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#0000000&@17
+| +0#00e0e07&@19|I|1| |x|,| |@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |y|)| |-|>| +0#0000000&|x|;| @21
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t|1|2| |=| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#0000000&@23
+| +0#00e0e07&@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |x|,| +0#0000000&@33
+| +0#00e0e07&@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#0000000&@45
+| +0#00e0e07&@19|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|I|1| |y|)| |-|>| +0#0000000&|x|;| @27
+@75
+@8|R|u|n@1|a|b|l|e| |n|o|O|p| |=| |(+0#00e0e07&|)| |-|>| +0#0000000&|{|}|;| @41
+@8|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t| |=| |(+0#00e0e07&|x|,| |y|)| |-|>| +0#0000000&|x|;| @23
+@57|5@1|,|6|-|2|1| @6|3|6|%|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_04.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_04.dump
new file mode 100644
index 0000000..4f0e5a3
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_04.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@7|B|i|n|a|r|y|O|p|e|r|a|t|o|r|<|I|1|>| |l|e|f|t|C|o|n|s|t| |=| |(+0#00e0e07&|x|,| |y|)| |-|>| +0#0000000&|x|;| @23
+@8|I|<|I|1|>| |i|d|1| |=| |(+0#00e0e07&|x|)| |-|>| +0#0000000&|(|x|)|;| @43
+@8|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|u|n|c|h|e|c|k|e|d|"|)+0#e000e06&| +0#0000000&|I|<|I|1|>| |i|d|2| |=| @24
+@16|(@1|I|<|I|<|I|1|>@1|)| |(|I|<|?|>|)| |(|F|u|n|c|t|i|o|n|<|I|1|,| @26
+@20|I|1|>| |x|)| |-|>| |x|)|.|a|p@1|l|y|(|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|0+0#e000002&|)+0#0000000&| |{| @23
+@16>c+0#af5f00255&|a|s|e| +0#0000000&|(@1|i+0#00e0003&|n|t|)+0#0000000&| |(|b+0#00e0003&|y|t|e|)+0#0000000&| |1+0#e000002&|)+0#0000000&| |-|>| |(+0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| @21
+@16|d+0#af5f00255&|e|f|a|u|l|t| +0#0000000&|-|>| |(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|I|1| |x|)| |-|>| +0#0000000&|x|;| |}|)|;| @21
+@8|C|<|C|1|,| |C|2|>| |c|o|n|s|t|1| |=| |(+0#00e0e07&|x|)| |-|>| +0#0000000&|(+0#00e0e07&|y|)| |-|>| +0#0000000&|(|x|)|;| @29
+@8|C|<|C|1|,| |C|2|>| |c|o|n|s|t|2| |=| |s+0#af5f00255&|w|i|t|c|h|(+0#0000000&|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|"+0#e000002&@1|)+0#0000000&| |{| @27
+@24|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#e000002&|-|>|"|-+0#0000000&|>|"+0#e000002&|(|s|)|-|>|(|s|)|"|;+0#0000000&| @28
+@24|d+0#af5f00255&|e|f|a|u|l|t|-+0#0000000&|>|"+0#e000002&|d|e|f|a|u|l|t|"|;+0#0000000&| |}|)| |{| @26
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|(|"+0#e000002&|-|>|"|)+0#0000000&|-|>|(+0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)|-|>|(|v+0#af5f00255&|a|r| +0#00e0e07&|y|)|-|>|(+0#0000000&|x|)|;| @27
+@12|d+0#af5f00255&|e|f|a|u|l|t|-+0#0000000&|>|(+0#00e0e07&|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|x|)|-|>|(|@+0#e000e06&|T|a|g@1|a|b|l|e| +0#00e0e07&|v+0#af5f00255&|a|r| +0#00e0e07&|y|)| +0#0000000&@17
+| +0#00e0e07&@15|-|>|(+0#0000000&|x|)|;| @52
+@8|}|;| @64
+@4|}| @69
+@75
+@4|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|(|E+0#0000000&|l|e|m|e|n|t|T|y|p|e|.|P|A|R|A|M|E|T|E|R|)+0#e000e06&| +0#0000000&@19
+@4|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(|T+0#0000000&|a|g@1|a|b|l|e|s|.|c+0#00e0003&|l|a|s@1|)+0#e000e06&| +0#0000000&@21
+@57|7|3|,|5|-|1|7| @6|4|9|%|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_05.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_05.dump
new file mode 100644
index 0000000..98ab331
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_05.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(|T+0#0000000&|a|g@1|a|b|l|e|s|.|c+0#00e0003&|l|a|s@1|)+0#e000e06&| +0#0000000&@21
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|a|g@1|a|b|l|e| |{| |S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| |d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| |}| @18
+@75
+@4|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|(|E+0#0000000&|l|e|m|e|n|t|T|y|p|e|.|P|A|R|A|M|E|T|E|R|)+0#e000e06&| +0#0000000&@19
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|a|g@1|a|b|l|e|s| |{| |T|a|g@1|a|b|l|e|[|]| |v|a|l|u|e|(|)|;| |}| @26
+> @74
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|I|<|A|1|>| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|F|u|n|c|t|i|o|n|<|A|1|,| |A|1|>| |{| |}| @26
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|C|<|A|1|,| |A|2|>| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|F|u|n|c|t|i|o|n|<|A|1|,| |F|u|n|c|t|i|o|n|<|A|2|,| |A|1|>@1| |{| |}| @8
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|T|<|A|1|,| |A|2|,| |A|3|>| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&@39
+@16|F|u|n|c|t|i|o|n|<|F|u|n|c|t|i|o|n|<|A|1|,| |F|u|n|c|t|i|o|n|<|A|2|,| |A|3|>@1|,| @18
+@20|F|u|n|c|t|i|o|n|<|A|2|,| @42
+@20|F|u|n|c|t|i|o|n|<|A|1|,| |A|3|>@2| |{| |}| @32
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|Z|<|A|1|,| |A|2|,| |A|3|>| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|F|u|n|c|t|i|o|n|<|F|u|n|c|t|i|o|n|<|A|2|,| |A|3|>|,| @12
+@20|F|u|n|c|t|i|o|n|<|F|u|n|c|t|i|o|n|<|A|1|,| |A|2|>|,| @28
+@20|F|u|n|c|t|i|o|n|<|A|1|,| |A|3|>@2| |{| |}| @32
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|S|<|A|1|,| |A|2|,| |A|3|>| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&@39
+@16|F|u|n|c|t|i|o|n|<|F|u|n|c|t|i|o|n|<|A|1|,| |F|u|n|c|t|i|o|n|<|A|2|,| |A|3|>@1|,| @18
+@20|F|u|n|c|t|i|o|n|<|F|u|n|c|t|i|o|n|<|A|1|,| |A|2|>|,| @28
+@20|F|u|n|c|t|i|o|n|<|A|1|,| |A|3|>@2| |{| |}| @32
+@57|9|1|,|0|-|1| @7|6|2|%|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_06.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_06.dump
new file mode 100644
index 0000000..2887b48
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_06.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@19|F|u|n|c|t|i|o|n|<|A|1|,| |A|3|>@2| |{| |}| @32
+@75
+| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|e|c|h|o|(|O|b|j|e|c|t| |o|)| +0#0000000&|{| |S|y|s|t|e|m|.|o|u|t|.|p|r|i|n|t|l|n|(|o|)|;| |}| @17
+@75
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|{| @62
+@8>e+0#00e0003&|n|u|m| +0#0000000&|L|e|t@1|e|r|s| |{| |O|T|H|E|R|,| |A|L|P|H|A|,| |B|E|T|A| |}| @31
+@75
+@8|L|e|t@1|e|r|s| |o|t|h|e|r| |=| |L|e|t@1|e|r|s|.|O|T|H|E|R|;| @36
+@75
+@8|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|o|t|h|e|r|)| |{| @50
+@8|c+0#af5f00255&|a|s|e| +0#0000000&|L|e|t@1|e|r|s| |a|l|p|h|a| |w+0#af5f00255&|h|e|n| +0#0000000&|L|e|t@1|e|r|s|.|A|L|P|H|A| |=@1| |a|l|p|h|a|:| @19
+@24|{| |e|c|h|o|(|a|l|p|h|a|)|;| |b+0#af5f00255&|r|e|a|k|;+0#0000000&| |}| @27
+@8|c+0#af5f00255&|a|s|e| +0#0000000&|L|e|t@1|e|r|s| |b|e|t|a| |w+0#af5f00255&|h|e|n| +0#0000000&|L|e|t@1|e|r|s|.|B|E|T|A| |=@1| |b|e|t|a|:| @22
+@24|{| |e|c|h|o|(|b|e|t|a|)|;| |b+0#af5f00255&|r|e|a|k|;+0#0000000&| |}| @28
+@8|d+0#af5f00255&|e|f|a|u|l|t|:+0#0000000&| @11|{| |e|c|h|o|(|o|t|h|e|r|)|;| |}| @30
+@8|}| @65
+@75
+@8|e|c|h|o|(|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|o|t|h|e|r|)| |{| @45
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|L|e|t@1|e|r|s| |a|l|p|h|a| |w+0#af5f00255&|h|e|n| +0#0000000&|L|e|t@1|e|r|s|.|A|L|P|H|A| |=@1| |a|l|p|h|a| @16
+@57|1|0|9|,|3|-|9| @6|7|6|%|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_07.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_07.dump
new file mode 100644
index 0000000..7749ef2
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_07.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@11|c+0#af5f00255&|a|s|e| +0#0000000&|L|e|t@1|e|r|s| |a|l|p|h|a| |w+0#af5f00255&|h|e|n| +0#0000000&|L|e|t@1|e|r|s|.|A|L|P|H|A| |=@1| |a|l|p|h|a| @16
+@24|-|>| |a|l|p|h|a|;| @41
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|L|e|t@1|e|r|s| |b|e|t|a| |w+0#af5f00255&|h|e|n| +0#0000000&|L|e|t@1|e|r|s|.|B|E|T|A| |=@1| |b|e|t|a| @19
+@24|-|>| |b|e|t|a|;| @42
+@12|d+0#af5f00255&|e|f|a|u|l|t| +0#0000000&@8|-|>| |o|t|h|e|r|;| @37
+@8>}|)|;| @63
+@75
+@8|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|n+0#e000002&|u|l@1|)+0#0000000&| |{| @51
+@8|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r| |w+0#af5f00255&|h|e|n| +0#0000000&|!|"+0#e000002&|<|e|m|p|t|y|>|"|.+0#0000000&|e|q|u|a|l|s|(|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|s|t|r|)| |{| @13
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r|_| |w+0#af5f00255&|h|e|n| +0#0000000&@41
+@20|P|r|e|d|i|c|a|t|e|.|<|S|t|r|i|n|g|>|n|o|t|(|t+0#00e0e07&|e|x|t| |-|>| +0#0000000&@25
+@28|!|t|e|x|t|.|i|s|E|m|p|t|y|(|)@1| @30
+@24|.|t|e|s|t|(|s|t|r|_|)| @39
+@28|-|>| |"+0#e000002&|<|e|m|p|t|y|>|"|;+0#0000000&| @33
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r|_| @7|-|>| |s|t|r|_|;| @30
+@12|}|)|:| @8|{| |e|c|h|o|(|s|t|r|)|;| |b+0#af5f00255&|r|e|a|k|;+0#0000000&| |}| @29
+@8|c+0#af5f00255&|a|s|e| +0#0000000&|n+0#e000002&|u|l@1|:+0#0000000&| |d+0#af5f00255&|e|f|a|u|l|t|:+0#0000000&| @4|{| |e|c|h|o|(|"+0#e000002&|O|t|h|e|r|"|)+0#0000000&|;| |}| @24
+@8|}|;| @64
+@75
+@57|1|2|7|,|3|-|9| @6|8|9|%|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_08.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_08.dump
new file mode 100644
index 0000000..4267ebe
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_08.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+@8|e|c|h|o|(|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|n+0#e000002&|u|l@1|)+0#0000000&| |{| @46
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r| |w+0#af5f00255&|h|e|n| +0#0000000&|!|"+0#e000002&|<|e|m|p|t|y|>|"|.+0#0000000&|e|q|u|a|l|s|(| @23
+@28|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|s|t|r|)| |{| @32
+@16|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r|_| |w+0#af5f00255&|h|e|n| +0#0000000&@37
+@20>P|r|e|d|i|c|a|t|e|.|<|S|t|r|i|n|g|>|n|o|t|(|t+0#00e0e07&|e|x|t| |-|>| +0#0000000&@25
+@28|!|t|e|x|t|.|i|s|E|m|p|t|y|(|)@1| @30
+@24|.|t|e|s|t|(|s|t|r|_|)| @39
+@28|-|>| |"+0#e000002&|<|e|m|p|t|y|>|"|;+0#0000000&| @33
+@16|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r|_| @3|-|>| |s|t|r|_|;| @30
+@16|}|)| @5|-|>| |s|t|r|;| @43
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|n+0#e000002&|u|l@1|,+0#0000000&| |d+0#af5f00255&|e|f|a|u|l|t| +0#0000000&@1|-|>| |"+0#e000002&|O|t|h|e|r|"|;+0#0000000&| @31
+@8|}|)|;| @63
+@4|}| @69
+|}| @73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|4|5|,|6|-|2|1| @5|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_lambda_expressions_99.dump b/runtime/syntax/testdir/dumps/java_lambda_expressions_99.dump
new file mode 100644
index 0000000..2a1fe2a
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_lambda_expressions_99.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@11|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r|_| @7|-|>| |s|t|r|_|;| @30
+@12|}|)|:| @8|{| |e|c|h|o|(|s|t|r|)|;| |b+0#af5f00255&|r|e|a|k|;+0#0000000&| |}| @29
+@8|c+0#af5f00255&|a|s|e| +0#0000000&|n+0#e000002&|u|l@1|:+0#0000000&| |d+0#af5f00255&|e|f|a|u|l|t|:+0#0000000&| @4|{| |e|c|h|o|(|"+0#e000002&|O|t|h|e|r|"|)+0#0000000&|;| |}| @24
+@8|}|;| @64
+@75
+@8|e|c|h|o|(|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|n+0#e000002&|u|l@1|)+0#0000000&| |{| @46
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r| |w+0#af5f00255&|h|e|n| +0#0000000&|!|"+0#e000002&|<|e|m|p|t|y|>|"|.+0#0000000&|e|q|u|a|l|s|(| @23
+@28|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|s|t|r|)| |{| @32
+@16|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r|_| |w+0#af5f00255&|h|e|n| +0#0000000&@37
+@20|P|r|e|d|i|c|a|t|e|.|<|S|t|r|i|n|g|>|n|o|t|(|t+0#00e0e07&|e|x|t| |-|>| +0#0000000&@25
+@28|!|t|e|x|t|.|i|s|E|m|p|t|y|(|)@1| @30
+@24|.|t|e|s|t|(|s|t|r|_|)| @39
+@28|-|>| |"+0#e000002&|<|e|m|p|t|y|>|"|;+0#0000000&| @33
+@16|c+0#af5f00255&|a|s|e| +0#0000000&|S|t|r|i|n|g| |s|t|r|_| @3|-|>| |s|t|r|_|;| @30
+@16|}|)| @5|-|>| |s|t|r|;| @43
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|n+0#e000002&|u|l@1|,+0#0000000&| |d+0#af5f00255&|e|f|a|u|l|t| +0#0000000&@1|-|>| |"+0#e000002&|O|t|h|e|r|"|;+0#0000000&| @31
+@8|}|)|;| @63
+@4|}| @69
+>}| @73
+@57|1|5|4|,|1| @8|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_00.dump b/runtime/syntax/testdir/dumps/java_methods_indent2_00.dump
new file mode 100644
index 0000000..6b7595f
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|h|i|g|h|l|i|g|h|t|_|f|u|n|c|t|i|o|n|s| |=| |'|i|n|d|e|n|t|2|'| +0#0000000&@14
+|/+0#0000e05&@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t| |e|n|c|o|d|i|n|g|=|u|t|f|-|8| |t|e|r|m|e|n|c|o|d|i|n|g|=|u|t|f|-|8| +0#0000000&@19
+@75
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|;| @34
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|;| @39
+@75
+|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s| @40
+|{| |/+0#0000e05&@1| |D|O| |N|O|T| |r|e|t|a|b|!| |T|H|I|S| |F|I|L|E|;| |R|E|M|E|M|B|E|R| |A|B|O|U|T| |t|e|s|t|d|i|r|/|f|t|p|l|u|g|i|n|.| +0#0000000&@12
+@2|/+0#0000e05&@1| |T|Y|P|E|S|.| +0#0000000&@63
+@2|r+0#00e0003&|e|c|o|r|d| +0#0000000&|Τ|ʬ|<|α|>|(|α| |a|)| |{| |}| @51
+@75
+@2|e+0#00e0003&|n|u|m| +0#0000000&|E| @66
+@2|{| @71
+@4|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @39
+@4|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @39
+@4|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @55
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @35
+@2|}| @71
+@75
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_00.vim b/runtime/syntax/testdir/dumps/java_methods_indent2_00.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_00.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_01.dump b/runtime/syntax/testdir/dumps/java_methods_indent2_01.dump
new file mode 100644
index 0000000..950d878
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_01.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @39
+@4|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @39
+@4|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @55
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @35
+@2|}| @71
+> @74
+@2|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@18
+@2|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(|T+0#0000000&|ɐ|g@1|a|b|l|ɘ|s|.|c+0#00e0003&|l|a|s@1|)+0#e000e06&| +0#0000000&@23
+@2|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ| @53
+@2|{| @71
+@4|S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| |d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @42
+@2|}| @71
+@75
+@2|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@18
+@2|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ|s| @52
+@2|{| @71
+@4|T|ɐ|g@1|a|b|l|ɘ|[|]| |v|a|l|u|e|(|)|;| @51
+@2|}| @71
+@75
+@57|1|9|,|0|-|1| @7|1|7|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_01.vim b/runtime/syntax/testdir/dumps/java_methods_indent2_01.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_01.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_02.dump b/runtime/syntax/testdir/dumps/java_methods_indent2_02.dump
new file mode 100644
index 0000000..48d31d1
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+@2|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|S|t|y|l|a|b|l|e|<|Α|>| @51
+@2|{| @71
+@4|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|v+0#00e0003&|o|i|d| +0#0000000&|a|s|c|i@1|$|0|_|(|)| |{| |}| @43
+@4|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|Α| |μ|ʭ@1|$|0|_|(|)| |{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|n+0#e000002&|u|l@1|;+0#0000000&| |}| @35
+@2>}| @71
+@75
+@2|/+0#0000e05&@1| |F|I|E|L|D|S|.| +0#0000000&@62
+@2|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|C|l|a|s@1|<|?|>| |C|L|A|S@1|_|L|O|C|K| |=| |c|l|a|s@1|L|o|c|k|(|)|;| @17
+@75
+@2|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|O|b|j|e|c|t| |i|n|s|t|a|n|c|e|L|o|c|k| |=| |n+0#af5f00255&|e|w| +0#0000000&|O|b|j|e|c|t|(|)|;| @23
+@75
+@2|/+0#0000e05&@1| |C|O|N|S|T|R|U|C|T|O|R|S|.| +0#0000000&@56
+@2|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#0000000&|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|(|)| |{| |}| @17
+@2|<|T| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|C|o|m|p|a|r|a|b|l|e|<|T|>@1| |I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|,| |V|o|i|d| |v|)| |{| |}| @10
+@2|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|<|T| |e|x|t|e|n|d|s| |C|o|m|p|a|r|a|b|l|e|<|T|>@1| |I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|)| |{| |}| @10
+@75
+@2|/+0#0000e05&@1| |M|E|T|H|O|D|S|.| +0#0000000&@61
+| +0#00e0e07&@1|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@13
+@57|3|7|,|3| @9|4|2|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_02.vim b/runtime/syntax/testdir/dumps/java_methods_indent2_02.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_02.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_03.dump b/runtime/syntax/testdir/dumps/java_methods_indent2_03.dump
new file mode 100644
index 0000000..f388cd9
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_03.dump
@@ -0,0 +1,20 @@
+| +0#00e0e07#ffffff0@1|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@13
+| +0#00e0e07&@63|)|;+0#0000000&| @8
+| +0#00e0e07&@1|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>| |μ|ʭ@1|$|0|_|(| +0#0000000&@23
+| +0#00e0e07&@31|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#00e0e07&|β| |b|)|;+0#0000000&| @8
+@75
+| +0#00e0e07&@1>@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|1|_|(|/+0#0000e05&|*|/@10|/+0#ffffff16#ff404010|*+0#0000e05#ffffff0|/|)+0#00e0e07&|;+0#0000000&| @15
+| +0#00e0e07&@1|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|1|_|(| +0#0000000&@25
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|>| |ƒ|)|;+0#0000000&| @7
+@75
+| +0#00e0e07&@1|v+0#00e0003&|o|i|d| +0#00e0e07&|A|s|c|i@1|$|2|_|(|)| +0#0000000&|{| |}| @53
+| +0#00e0e07&@1|<|T|,| |U| |e|x|t|e|n|d|s| |S|t|y|l|a|b|l|e|<|T|>@1| |v+0#00e0003&|o|i|d| +0#00e0e07&|Μ|ʭ@1|$|2|_|(|U| |u|)| +0#0000000&|{| |}| @25
+@75
+| +0#00e0e07&@1|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @22
+| +0#00e0e07&@1|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| +0#0000000&@14
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @5
+@75
+@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@43
+| +0#00e0e07&@1|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@11
+@2|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @56
+@57|5@1|,|3| @9|6|7|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_03.vim b/runtime/syntax/testdir/dumps/java_methods_indent2_03.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_03.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_04.dump b/runtime/syntax/testdir/dumps/java_methods_indent2_04.dump
new file mode 100644
index 0000000..0d9fa98
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_04.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@1|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @56
+@75
+@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@43
+| +0#00e0e07&@1|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_|(| +0#0000000&@4
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| +0#0000000&@6
+@2>{| @71
+@4|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@64
+@2|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @32
+@2|}| @71
+@75
+| +0#00e0e07&@1|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|;+0#0000000&| |}|
+@75
+@2|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@37
+| +0#00e0e07&@1|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}| @5
+|}| @73
+@75
+|e+0#00e0003&|n|u|m| +0#0000000&|E|2| @67
+|{| @73
+@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#0000000&|A|(|"+0#e000002&|a|"|)+0#0000000&|,| @36
+@57|7|3|,|3| @9|9|1|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_04.vim b/runtime/syntax/testdir/dumps/java_methods_indent2_04.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_04.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_99.dump b/runtime/syntax/testdir/dumps/java_methods_indent2_99.dump
new file mode 100644
index 0000000..204e85a
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_99.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@64
+@2|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @32
+@2|}| @71
+@75
+| +0#00e0e07&@1|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|;+0#0000000&| |}|
+@75
+@2|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@37
+| +0#00e0e07&@1|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|I|n|d|e|n|t|2|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}| @5
+|}| @73
+@75
+|e+0#00e0003&|n|u|m| +0#0000000&|E|2| @67
+|{| @73
+@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#0000000&|A|(|"+0#e000002&|a|"|)+0#0000000&|,| @36
+@2|B|(|"+0#e000002&|b|"|)+0#0000000&|,| @65
+@2|C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @57
+@2|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @41
+@2|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @57
+@2|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|2|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @36
+>}| @73
+@57|9|2|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent2_99.vim b/runtime/syntax/testdir/dumps/java_methods_indent2_99.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent2_99.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_00.dump b/runtime/syntax/testdir/dumps/java_methods_indent4_00.dump
new file mode 100644
index 0000000..d6ad7af
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|h|i|g|h|l|i|g|h|t|_|f|u|n|c|t|i|o|n|s| |=| |'|i|n|d|e|n|t|4|'| +0#0000000&@14
+|/+0#0000e05&@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t| |e|n|c|o|d|i|n|g|=|u|t|f|-|8| |t|e|r|m|e|n|c|o|d|i|n|g|=|u|t|f|-|8| +0#0000000&@19
+@75
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|;| @34
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|;| @39
+@75
+|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s| @40
+|{| |/+0#0000e05&@1| |D|O| |N|O|T| |r|e|t|a|b|!| |T|H|I|S| |F|I|L|E|;| |R|E|M|E|M|B|E|R| |A|B|O|U|T| |t|e|s|t|d|i|r|/|f|t|p|l|u|g|i|n|.| +0#0000000&@12
+@4|/+0#0000e05&@1| |T|Y|P|E|S|.| +0#0000000&@61
+@4|r+0#00e0003&|e|c|o|r|d| +0#0000000&|Τ|ʬ|<|α|>|(|α| |a|)| |{| |}| @49
+@75
+@4|e+0#00e0003&|n|u|m| +0#0000000&|E| @64
+@4|{| @69
+@8|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @35
+@8|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @35
+@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @51
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @31
+@4|}| @69
+@75
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_00.vim b/runtime/syntax/testdir/dumps/java_methods_indent4_00.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_00.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_01.dump b/runtime/syntax/testdir/dumps/java_methods_indent4_01.dump
new file mode 100644
index 0000000..0f154c5
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_01.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@7|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @35
+@8|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @35
+@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @51
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @31
+@4|}| @69
+> @74
+@4|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@16
+@4|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(|T+0#0000000&|ɐ|g@1|a|b|l|ɘ|s|.|c+0#00e0003&|l|a|s@1|)+0#e000e06&| +0#0000000&@21
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ| @51
+@4|{| @69
+@8|S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| |d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @38
+@4|}| @69
+@75
+@4|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@16
+@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ|s| @50
+@4|{| @69
+@8|T|ɐ|g@1|a|b|l|ɘ|[|]| |v|a|l|u|e|(|)|;| @47
+@4|}| @69
+@75
+@57|1|9|,|0|-|1| @7|1|7|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_01.vim b/runtime/syntax/testdir/dumps/java_methods_indent4_01.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_01.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_02.dump b/runtime/syntax/testdir/dumps/java_methods_indent4_02.dump
new file mode 100644
index 0000000..ed7c8fb
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|S|t|y|l|a|b|l|e|<|Α|>| @49
+@4|{| @69
+@8|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|v+0#00e0003&|o|i|d| +0#0000000&|a|s|c|i@1|$|0|_|(|)| |{| |}| @39
+@8|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|Α| |μ|ʭ@1|$|0|_|(|)| |{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|n+0#e000002&|u|l@1|;+0#0000000&| |}| @31
+@4>}| @69
+@75
+@4|/+0#0000e05&@1| |F|I|E|L|D|S|.| +0#0000000&@60
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|C|l|a|s@1|<|?|>| |C|L|A|S@1|_|L|O|C|K| |=| |c|l|a|s@1|L|o|c|k|(|)|;| @15
+@75
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|O|b|j|e|c|t| |i|n|s|t|a|n|c|e|L|o|c|k| |=| |n+0#af5f00255&|e|w| +0#0000000&|O|b|j|e|c|t|(|)|;| @21
+@75
+@4|/+0#0000e05&@1| |C|O|N|S|T|R|U|C|T|O|R|S|.| +0#0000000&@54
+@4|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#0000000&|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|(|)| |{| |}| @15
+@4|<|T| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|C|o|m|p|a|r|a|b|l|e|<|T|>@1| |I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|,| |V|o|i|d| |v|)| |{| |}| @8
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|<|T| |e|x|t|e|n|d|s| |C|o|m|p|a|r|a|b|l|e|<|T|>@1| |I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|)| |{| |}| @8
+@75
+@4|/+0#0000e05&@1| |M|E|T|H|O|D|S|.| +0#0000000&@59
+| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@11
+@57|3|7|,|5| @9|4|2|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_02.vim b/runtime/syntax/testdir/dumps/java_methods_indent4_02.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_02.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_03.dump b/runtime/syntax/testdir/dumps/java_methods_indent4_03.dump
new file mode 100644
index 0000000..bed45d9
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_03.dump
@@ -0,0 +1,20 @@
+| +0#00e0e07#ffffff0@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@11
+| +0#00e0e07&@63|)|;+0#0000000&| @8
+| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>| |μ|ʭ@1|$|0|_|(| +0#0000000&@21
+| +0#00e0e07&@31|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#00e0e07&|β| |b|)|;+0#0000000&| @8
+@75
+| +0#00e0e07&@3>@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|1|_|(|/+0#0000e05&|*|/@10|/+0#ffffff16#ff404010|*+0#0000e05#ffffff0|/|)+0#00e0e07&|;+0#0000000&| @13
+| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|1|_|(| +0#0000000&@23
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|>| |ƒ|)|;+0#0000000&| @7
+@75
+| +0#00e0e07&@3|v+0#00e0003&|o|i|d| +0#00e0e07&|A|s|c|i@1|$|2|_|(|)| +0#0000000&|{| |}| @51
+| +0#00e0e07&@3|<|T|,| |U| |e|x|t|e|n|d|s| |S|t|y|l|a|b|l|e|<|T|>@1| |v+0#00e0003&|o|i|d| +0#00e0e07&|Μ|ʭ@1|$|2|_|(|U| |u|)| +0#0000000&|{| |}| @23
+@75
+| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @20
+| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| +0#0000000&@12
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @5
+@75
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@41
+| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@9
+@4|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @54
+@57|5@1|,|5| @9|6|7|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_03.vim b/runtime/syntax/testdir/dumps/java_methods_indent4_03.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_03.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_04.dump b/runtime/syntax/testdir/dumps/java_methods_indent4_04.dump
new file mode 100644
index 0000000..9eabb63
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_04.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @54
+@75
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@41
+| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_|(| +0#0000000&@2
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| +0#0000000&@6
+@4>{| @69
+@8|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@60
+@4|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @30
+@4|}| @69
+@75
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|;+0#0000000&|
+|}| @73
+@75
+@4|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@35
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}| @3
+|}| @73
+@75
+|e+0#00e0003&|n|u|m| +0#0000000&|E|4| @67
+|{| @73
+@57|7|3|,|5| @9|9|0|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_04.vim b/runtime/syntax/testdir/dumps/java_methods_indent4_04.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_04.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_99.dump b/runtime/syntax/testdir/dumps/java_methods_indent4_99.dump
new file mode 100644
index 0000000..28fa0bc
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_99.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @30
+@4|}| @69
+@75
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|;+0#0000000&|
+|}| @73
+@75
+@4|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@35
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|I|n|d|e|n|t|4|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}| @3
+|}| @73
+@75
+|e+0#00e0003&|n|u|m| +0#0000000&|E|4| @67
+|{| @73
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#0000000&|A|(|"+0#e000002&|a|"|)+0#0000000&|,| @34
+@4|B|(|"+0#e000002&|b|"|)+0#0000000&|,| @63
+@4|C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @55
+@4|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @39
+@4|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @55
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|4|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @34
+>}| @73
+@57|9|2|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent4_99.vim b/runtime/syntax/testdir/dumps/java_methods_indent4_99.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent4_99.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_00.dump b/runtime/syntax/testdir/dumps/java_methods_indent8_00.dump
new file mode 100644
index 0000000..8be15fe
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|h|i|g|h|l|i|g|h|t|_|f|u|n|c|t|i|o|n|s| |=| |'|i|n|d|e|n|t|8|'| +0#0000000&@14
+|/+0#0000e05&@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t| |e|n|c|o|d|i|n|g|=|u|t|f|-|8| |t|e|r|m|e|n|c|o|d|i|n|g|=|u|t|f|-|8| +0#0000000&@19
+@75
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|;| @34
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|;| @39
+@75
+|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s| @40
+|{| |/+0#0000e05&@1| |D|O| |N|O|T| |r|e|t|a|b|!| |T|H|I|S| |F|I|L|E|;| |R|E|M|E|M|B|E|R| |A|B|O|U|T| |t|e|s|t|d|i|r|/|f|t|p|l|u|g|i|n|.| +0#0000000&@12
+@8|/+0#0000e05&@1| |T|Y|P|E|S|.| +0#0000000&@57
+@8|r+0#00e0003&|e|c|o|r|d| +0#0000000&|Τ|ʬ|<|α|>|(|α| |a|)| |{| |}| @45
+@75
+@8|e+0#00e0003&|n|u|m| +0#0000000&|E| @60
+@8|{| @65
+@16|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @27
+@16|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @27
+@16|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @43
+@16|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @23
+@8|}| @65
+@75
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_00.vim b/runtime/syntax/testdir/dumps/java_methods_indent8_00.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_00.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_01.dump b/runtime/syntax/testdir/dumps/java_methods_indent8_01.dump
new file mode 100644
index 0000000..269034b
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_01.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@15|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @27
+@16|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @27
+@16|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @43
+@16|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @23
+@8|}| @65
+> @74
+@8|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@12
+@8|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(|T+0#0000000&|ɐ|g@1|a|b|l|ɘ|s|.|c+0#00e0003&|l|a|s@1|)+0#e000e06&| +0#0000000&@17
+@8|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ| @47
+@8|{| @65
+@16|S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| |d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @30
+@8|}| @65
+@75
+@8|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@12
+@8|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ|s| @46
+@8|{| @65
+@16|T|ɐ|g@1|a|b|l|ɘ|[|]| |v|a|l|u|e|(|)|;| @39
+@8|}| @65
+@75
+@57|1|9|,|0|-|1| @7|1|7|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_01.vim b/runtime/syntax/testdir/dumps/java_methods_indent8_01.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_01.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_02.dump b/runtime/syntax/testdir/dumps/java_methods_indent8_02.dump
new file mode 100644
index 0000000..e5c7acc
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+@8|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|S|t|y|l|a|b|l|e|<|Α|>| @45
+@8|{| @65
+@16|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|v+0#00e0003&|o|i|d| +0#0000000&|a|s|c|i@1|$|0|_|(|)| |{| |}| @31
+@16|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|Α| |μ|ʭ@1|$|0|_|(|)| |{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|n+0#e000002&|u|l@1|;+0#0000000&| |}| @23
+@8>}| @65
+@75
+@8|/+0#0000e05&@1| |F|I|E|L|D|S|.| +0#0000000&@56
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|C|l|a|s@1|<|?|>| |C|L|A|S@1|_|L|O|C|K| |=| |c|l|a|s@1|L|o|c|k|(|)|;| @11
+@75
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|O|b|j|e|c|t| |i|n|s|t|a|n|c|e|L|o|c|k| |=| |n+0#af5f00255&|e|w| +0#0000000&|O|b|j|e|c|t|(|)|;| @17
+@75
+@8|/+0#0000e05&@1| |C|O|N|S|T|R|U|C|T|O|R|S|.| +0#0000000&@50
+@8|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#0000000&|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|(|)| |{| |}| @11
+@8|<|T| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|C|o|m|p|a|r|a|b|l|e|<|T|>@1| |I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|,| |V|o|i|d| |v|)| |{| |}| @4
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|<|T| |e|x|t|e|n|d|s| |C|o|m|p|a|r|a|b|l|e|<|T|>@1| |I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|)| |{| |}| @4
+@75
+@8|/+0#0000e05&@1| |M|E|T|H|O|D|S|.| +0#0000000&@55
+| +0#00e0e07&@7|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@7
+@57|3|7|,|9| @9|4|2|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_02.vim b/runtime/syntax/testdir/dumps/java_methods_indent8_02.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_02.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_03.dump b/runtime/syntax/testdir/dumps/java_methods_indent8_03.dump
new file mode 100644
index 0000000..e80c44d
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_03.dump
@@ -0,0 +1,20 @@
+| +0#00e0e07#ffffff0@7|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@7
+| +0#00e0e07&@63|)|;+0#0000000&| @8
+| +0#00e0e07&@7|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>| |μ|ʭ@1|$|0|_|(| +0#0000000&@17
+| +0#00e0e07&@31|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#00e0e07&|β| |b|)|;+0#0000000&| @8
+@75
+| +0#00e0e07&@7>@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|1|_|(|/+0#0000e05&|*|/@10|/+0#ffffff16#ff404010|*+0#0000e05#ffffff0|/|)+0#00e0e07&|;+0#0000000&| @9
+| +0#00e0e07&@7|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|1|_|(| +0#0000000&@19
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|>| |ƒ|)|;+0#0000000&| @7
+@75
+| +0#00e0e07&@7|v+0#00e0003&|o|i|d| +0#00e0e07&|A|s|c|i@1|$|2|_|(|)| +0#0000000&|{| |}| @47
+| +0#00e0e07&@7|<|T|,| |U| |e|x|t|e|n|d|s| |S|t|y|l|a|b|l|e|<|T|>@1| |v+0#00e0003&|o|i|d| +0#00e0e07&|Μ|ʭ@1|$|2|_|(|U| |u|)| +0#0000000&|{| |}| @19
+@75
+| +0#00e0e07&@7|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @16
+| +0#00e0e07&@7|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| +0#0000000&@8
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @5
+@75
+@8|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@37
+| +0#00e0e07&@7|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@5
+@8|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @50
+@57|5@1|,|9| @9|6|7|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_03.vim b/runtime/syntax/testdir/dumps/java_methods_indent8_03.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_03.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_04.dump b/runtime/syntax/testdir/dumps/java_methods_indent8_04.dump
new file mode 100644
index 0000000..8ec6396
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_04.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+@8|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@37
+| +0#00e0e07&@7|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_
+|(| +0#0000000&@73
+| +0#00e0e07&@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| +0#0000000&@6
+@8>{| @65
+@16|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@52
+@8|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @26
+@8|}| @65
+@75
+| +0#00e0e07&@7|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a
+|s@1|;+0#0000000&| |}| @69
+@75
+@8|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@31
+| +0#00e0e07&@7|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}
+@1| @73
+@75
+|e+0#00e0003&|n|u|m| +0#0000000&|E|8| @67
+|{| @73
+@57|7|3|,|9| @9|9|0|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_04.vim b/runtime/syntax/testdir/dumps/java_methods_indent8_04.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_04.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_99.dump b/runtime/syntax/testdir/dumps/java_methods_indent8_99.dump
new file mode 100644
index 0000000..d20fbe1
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_99.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@7|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @26
+@8|}| @65
+@75
+| +0#00e0e07&@7|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a
+|s@1|;+0#0000000&| |}| @69
+@75
+@8|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@31
+| +0#00e0e07&@7|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|I|n|d|e|n|t|8|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}
+@1| @73
+@75
+|e+0#00e0003&|n|u|m| +0#0000000&|E|8| @67
+|{| @73
+@8|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#0000000&|A|(|"+0#e000002&|a|"|)+0#0000000&|,| @30
+@8|B|(|"+0#e000002&|b|"|)+0#0000000&|,| @59
+@8|C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @51
+@8|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @35
+@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @51
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|8|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @30
+>}| @73
+@57|9|2|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent8_99.vim b/runtime/syntax/testdir/dumps/java_methods_indent8_99.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_indent8_99.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent_00.dump b/runtime/syntax/testdir/dumps/java_methods_indent_00.dump
deleted file mode 100644
index 8f90e91..0000000
--- a/runtime/syntax/testdir/dumps/java_methods_indent_00.dump
+++ /dev/null
@@ -1,20 +0,0 @@
->/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|h|i|g|h|l|i|g|h|t|_|f|u|n|c|t|i|o|n|s| |=| |'|i|n|d|e|n|t|'| +0#0000000&@15
-@75
-@75
-|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|;| @39
-@75
-|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|I|n|d|e|n|t|M|e|t|h|o|d|s|T|e|s|t|s| @41
-|{+0#00e0e07&| +0#0000000&|/+0#0000e05&@1| |D|O| |N|O|T| |r|e|t|a|b|!| |T|H|I|S| |F|I|L|E|;| |R|E|M|E|M|B|E|R| |A|B|O|U|T| |t|e|s|t|d|i|r|/|f|t|p|l|u|g|i|n|.| +0#0000000&@12
-| +0#00e0e07&@1|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|I|n|d|e|n|t|M|e|t|h|o|d|s|T|e|s|t|s|(|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|}+0#00e0e07&| +0#0000000&@38
-@75
-| +0#00e0e07&@1|r|e|c|o|r|d| |Τ|ʬ|<|α|>|(|α| |a|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|}+0#00e0e07&| +0#0000000&@51
-@75
-@2|e+0#00e0003&|n|u|m| +0#0000000&|𝓔| @66
-@2|{+0#00e0e07&| +0#0000000&@71
-| +0#00e0e07&@7|A|(|"|𝕬|"|)|,| |B|(|"|𝕭|"|)|,| |C|(|"|𝕮|"|)|,| |D|(|"|𝕯|"|)|,| +0#0000000&@35
-| +0#00e0e07&@7|E|(|"|𝕰|"|)|,+0#0000000&| |F|(|"+0#e000002&|𝕱|"|)+0#0000000&|,| |G|(|"+0#e000002&|𝕲|"|)+0#0000000&|,| |H|(|"+0#e000002&|𝕳|"|)+0#0000000&|;| @35
-@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |𝐬|;| @51
-@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|𝓔|(|S|t|r|i|n|g| |𝐬|)| |{+0#00e0e07&| +0#0000000&|t+0#00e0003&|h|i|s|.+0#0000000&|𝐬| |=| |𝐬|;| |}+0#00e0e07&| +0#0000000&@31
-@2|}+0#00e0e07&| +0#0000000&@71
-@75
-@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent_01.dump b/runtime/syntax/testdir/dumps/java_methods_indent_01.dump
deleted file mode 100644
index 44066c3..0000000
--- a/runtime/syntax/testdir/dumps/java_methods_indent_01.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0#00e0e07#ffffff0@7|A|(|"|𝕬|"|)|,| |B|(|"|𝕭|"|)|,| |C|(|"|𝕮|"|)|,| |D|(|"|𝕯|"|)|,| +0#0000000&@35
-| +0#00e0e07&@7|E|(|"|𝕰|"|)|,+0#0000000&| |F|(|"+0#e000002&|𝕱|"|)+0#0000000&|,| |G|(|"+0#e000002&|𝕲|"|)+0#0000000&|,| |H|(|"+0#e000002&|𝕳|"|)+0#0000000&|;| @35
-@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |𝐬|;| @51
-@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|𝓔|(|S|t|r|i|n|g| |𝐬|)| |{+0#00e0e07&| +0#0000000&|t+0#00e0003&|h|i|s|.+0#0000000&|𝐬| |=| |𝐬|;| |}+0#00e0e07&| +0#0000000&@31
-@2|}+0#00e0e07&| +0#0000000&@71
-> @74
-@2|@+0#e000e06&|T|a|r|g|e|t|(+0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|)| @24
-@2|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(+0#0000000&|T|ɐ|g@1|a|b|l|ɘ|s|.|c+0#00e0003&|l|a|s@1|)+0#0000000&| @23
-@2|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ| @53
-@2|{+0#00e0e07&| +0#0000000&@71
-| +0#00e0e07&@7|S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @38
-@2|}+0#00e0e07&| +0#0000000&@71
-@75
-@2|@+0#e000e06&|T|a|r|g|e|t|(+0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|)| @24
-@2|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ|s| @52
-@2|{+0#00e0e07&| +0#0000000&@71
-| +0#00e0e07&@7|T|ɐ|g@1|a|b|l|ɘ|[|]| |v|a|l|u|e|(|)|;+0#0000000&| @47
-@2|}+0#00e0e07&| +0#0000000&@71
-@75
-@57|1|9|,|0|-|1| @7|2|5|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent_02.dump b/runtime/syntax/testdir/dumps/java_methods_indent_02.dump
deleted file mode 100644
index 2ab6583..0000000
--- a/runtime/syntax/testdir/dumps/java_methods_indent_02.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@74
-@2|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|S|t|y|l|a|b|l|e|<|Α|>| @51
-@2|{+0#00e0e07&| +0#0000000&@71
-| +0#00e0e07&@7|d+0#4040ff13&|e|f|a|u|l|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|}+0#00e0e07&| +0#0000000&@39
-| +0#00e0e07&@7|d+0#4040ff13&|e|f|a|u|l|t| +0#00e0e07&|Α| |μ|ʭ@1|$|0|_|(|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|n+0#e000002&|u|l@1|;+0#0000000&| |}+0#00e0e07&| +0#0000000&@31
-@2>}+0#00e0e07&| +0#0000000&@71
-@75
-@2|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&@53
-| +0#00e0e07&@1|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|)|;+0#0000000&| @47
-@75
-@2|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&@53
-| +0#00e0e07&@1|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>| |μ|ʭ@1|$|0|_|(|β| |𝛽|)|;+0#0000000&| @38
-@75
-@2|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&@63
-| +0#00e0e07&@1|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|1|_|(|)|;+0#0000000&| @41
-@75
-@2|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&@63
-@2|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|n+0#e000e06&|a|t|i|v|e| +0#0000000&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|1|_|(| @35
-@24|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|>| |ƒ|)|;| @7
-@57|3|7|,|3| @9|6|0|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent_03.dump b/runtime/syntax/testdir/dumps/java_methods_indent_03.dump
deleted file mode 100644
index 2ce2bba..0000000
--- a/runtime/syntax/testdir/dumps/java_methods_indent_03.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@23|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|>| |ƒ|)|;| @7
-@75
-| +0#00e0e07&@1|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @22
-@2|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|n+0#e000e06&|a|t|i|v|e| +0#0000000&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#0000000&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| @14
-@24|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;| @5
-> @74
-@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @43
-| +0#00e0e07&@1|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@11
-@2|{+0#00e0e07&| +0#0000000&|a|s|c|i@1|$|9|8|_|(|)|;| |}+0#00e0e07&| +0#0000000&@56
-@75
-@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @43
-@2|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#0000000&|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#0000000&|s+0#00e0003&|t|r|i|c|t|f|p| +0#0000000&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_|(| @4
-@24|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| @6
-@2|{+0#00e0e07&| +0#0000000&@71
-@4|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@64
-| +0#00e0e07&@7|I|n|d|e|n|t|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[+0#0000000&|0+0#e000002&|]+0#0000000&|;| @27
-@2|}+0#00e0e07&| +0#0000000&@71
-@75
-@2|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|c|a|s|t|"|)+0#0000000&| @37
-@57|5@1|,|0|-|1| @7|9|6|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_indent_99.dump b/runtime/syntax/testdir/dumps/java_methods_indent_99.dump
deleted file mode 100644
index 36ee838..0000000
--- a/runtime/syntax/testdir/dumps/java_methods_indent_99.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0#00e0e07#ffffff0@1|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @22
-@2|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|n+0#e000e06&|a|t|i|v|e| +0#0000000&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#0000000&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| @14
-@24|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;| @5
-@75
-@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @43
-| +0#00e0e07&@1|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@11
-@2|{+0#00e0e07&| +0#0000000&|a|s|c|i@1|$|9|8|_|(|)|;| |}+0#00e0e07&| +0#0000000&@56
-@75
-@2|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @43
-@2|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#0000000&|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#0000000&|s+0#00e0003&|t|r|i|c|t|f|p| +0#0000000&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_|(| @4
-@24|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| @6
-@2|{+0#00e0e07&| +0#0000000&@71
-@4|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@64
-| +0#00e0e07&@7|I|n|d|e|n|t|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[+0#0000000&|0+0#e000002&|]+0#0000000&|;| @27
-@2|}+0#00e0e07&| +0#0000000&@71
-@75
-@2|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|c|a|s|t|"|)+0#0000000&| @37
-| +0#00e0e07&@1|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| |{| |r|e|t|u|r|n| |(|S|t|r|i|n|g|)| +0#0000000&|"+0#e000002&|I|n|d|e|n|t|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}+0#00e0e07&| +0#0000000&@6
->}+0#00e0e07&| +0#0000000&@73
-@57|7|0|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_00.dump b/runtime/syntax/testdir/dumps/java_methods_style_00.dump
index 01d483c..64c435b 100644
--- a/runtime/syntax/testdir/dumps/java_methods_style_00.dump
+++ b/runtime/syntax/testdir/dumps/java_methods_style_00.dump
@@ -1,20 +1,20 @@
>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|h|i|g|h|l|i|g|h|t|_|f|u|n|c|t|i|o|n|s| |=| |'|s|t|y|l|e|'| +0#0000000&@16
+|/+0#0000e05&@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t| |e|n|c|o|d|i|n|g|=|u|t|f|-|8| |t|e|r|m|e|n|c|o|d|i|n|g|=|u|t|f|-|8| +0#0000000&@19
@75
-@75
+|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|;| @34
|i+0#e000e06&|m|p|o|r|t| +0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|T|a|r|g|e|t|;| @39
@75
|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s| @42
-|{+0#00e0e07&| +0#0000000&@73
-@4|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#0000000&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|(|)| |{+0#00e0e07&| +0#0000000&|}+0#00e0e07&| +0#0000000&@37
-@75
-@4|r+0#00e0003&|e|c|o|r|d| +0#0000000&|Τ|ʬ|<|α|>|(|α| |a|)| |{+0#00e0e07&| +0#0000000&|}+0#00e0e07&| +0#0000000&@49
+|{| @73
+@4|/+0#0000e05&@1| |T|Y|P|E|S|.| +0#0000000&@61
+@4|r+0#00e0003&|e|c|o|r|d| +0#0000000&|Τ|ʬ|<|α|>|(|α| |a|)| |{| |}| @49
@75
-@4|e+0#00e0003&|n|u|m| +0#0000000&|𝓔| @64
-@4|{+0#00e0e07&| +0#0000000&@69
-@8|A|(|"+0#e000002&|𝕬|"|)+0#0000000&|,| |B|(|"+0#e000002&|𝕭|"|)+0#0000000&|,| |C|(|"+0#e000002&|𝕮|"|)+0#0000000&|,| |D|(|"+0#e000002&|𝕯|"|)+0#0000000&|,| @35
-@8|E|(|"+0#e000002&|𝕰|"|)+0#0000000&|,| |F|(|"+0#e000002&|𝕱|"|)+0#0000000&|,| |G|(|"+0#e000002&|𝕲|"|)+0#0000000&|,| |H|(|"+0#e000002&|𝕳|"|)+0#0000000&|;| @35
-@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |𝐬|;| @51
-@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|𝓔|(|S|t|r|i|n|g| |𝐬|)| |{+0#00e0e07&| +0#0000000&|t+0#00e0003&|h|i|s|.+0#0000000&|𝐬| |=| |𝐬|;| |}+0#00e0e07&| +0#0000000&@31
-@4|}+0#00e0e07&| +0#0000000&@69
+@4|e+0#00e0003&|n|u|m| +0#0000000&|E| @64
+@4|{| @69
+@8|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @35
+@8|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @35
+@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @51
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @31
+@4|}| @69
@75
@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_00.vim b/runtime/syntax/testdir/dumps/java_methods_style_00.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_style_00.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_01.dump b/runtime/syntax/testdir/dumps/java_methods_style_01.dump
index c944208..70056a7 100644
--- a/runtime/syntax/testdir/dumps/java_methods_style_01.dump
+++ b/runtime/syntax/testdir/dumps/java_methods_style_01.dump
@@ -1,20 +1,20 @@
-| +0&#ffffff0@7|A|(|"+0#e000002&|𝕬|"|)+0#0000000&|,| |B|(|"+0#e000002&|𝕭|"|)+0#0000000&|,| |C|(|"+0#e000002&|𝕮|"|)+0#0000000&|,| |D|(|"+0#e000002&|𝕯|"|)+0#0000000&|,| @35
-@8|E|(|"+0#e000002&|𝕰|"|)+0#0000000&|,| |F|(|"+0#e000002&|𝕱|"|)+0#0000000&|,| |G|(|"+0#e000002&|𝕲|"|)+0#0000000&|,| |H|(|"+0#e000002&|𝕳|"|)+0#0000000&|;| @35
-@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |𝐬|;| @51
-@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|𝓔|(|S|t|r|i|n|g| |𝐬|)| |{+0#00e0e07&| +0#0000000&|t+0#00e0003&|h|i|s|.+0#0000000&|𝐬| |=| |𝐬|;| |}+0#00e0e07&| +0#0000000&@31
-@4|}+0#00e0e07&| +0#0000000&@69
+| +0&#ffffff0@7|A|(|"+0#e000002&|a|"|)+0#0000000&|,| |B|(|"+0#e000002&|b|"|)+0#0000000&|,| |C|(|"+0#e000002&|c|"|)+0#0000000&|,| |D|(|"+0#e000002&|d|"|)+0#0000000&|,| @35
+@8|E|(|"+0#e000002&|e|"|)+0#0000000&|,| |F|(|"+0#e000002&|f|"|)+0#0000000&|,| |G|(|"+0#e000002&|g|"|)+0#0000000&|,| |H|(|"+0#e000002&|h|"|)+0#0000000&|;| @35
+@8|f+0#4040ff13&|i|n|a|l| +0#0000000&|S|t|r|i|n|g| |s|;| @51
+@8|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|E|(|S|t|r|i|n|g| |s|)| |{| |t+0#00e0003&|h|i|s|.+0#0000000&|s| |=| |s|;| |}| @31
+@4|}| @69
> @74
-@4|@+0#e000e06&|T|a|r|g|e|t|(+0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|)| @22
-@4|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(+0#0000000&|T|ɐ|g@1|a|b|l|ɘ|s|.|c+0#00e0003&|l|a|s@1|)+0#0000000&| @21
+@4|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@16
+@4|@+0#e000e06&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|R|e|p|e|a|t|a|b|l|e|(|T+0#0000000&|ɐ|g@1|a|b|l|ɘ|s|.|c+0#00e0003&|l|a|s@1|)+0#e000e06&| +0#0000000&@21
@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ| @51
-@4|{+0#00e0e07&| +0#0000000&@69
+@4|{| @69
| +0#00e0e07&@7|S|t|r|i|n|g|[|]| |v|a|l|u|e|(|)| +0#0000000&|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|"+0#e000002&@1|;+0#0000000&| @38
-@4|}+0#00e0e07&| +0#0000000&@69
+@4|}| @69
@75
-@4|@+0#e000e06&|T|a|r|g|e|t|(+0#0000000&|j|a|v|a|.|l|a|n|g|.|a|n@1|o|t|a|t|i|o|n|.|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|)| @22
+@4|@+0#e000e06&|T|a|r|g|e|t|(|{+0#0000000&|E|l|e|m|e|n|t|T|y|p|e|.|M|E|T|H|O|D|,| |E|l|e|m|e|n|t|T|y|p|e|.|C|O|N|S|T|R|U|C|T|O|R|}|)+0#e000e06&| +0#0000000&@16
@4|@+0#00e0003&|i|n|t|e|r|f|a|c|e| +0#0000000&|T|ɐ|g@1|a|b|l|ɘ|s| @50
-@4|{+0#00e0e07&| +0#0000000&@69
+@4|{| @69
| +0#00e0e07&@7|T|ɐ|g@1|a|b|l|ɘ|[|]| |v|a|l|u|e|(|)|;+0#0000000&| @47
-@4|}+0#00e0e07&| +0#0000000&@69
+@4|}| @69
@75
-@57|1|9|,|0|-|1| @7|2|7|%|
+@57|1|9|,|0|-|1| @7|2|0|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_01.vim b/runtime/syntax/testdir/dumps/java_methods_style_01.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_style_01.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_02.dump b/runtime/syntax/testdir/dumps/java_methods_style_02.dump
index bbdc9bb..616e1f5 100644
--- a/runtime/syntax/testdir/dumps/java_methods_style_02.dump
+++ b/runtime/syntax/testdir/dumps/java_methods_style_02.dump
@@ -1,20 +1,20 @@
| +0&#ffffff0@74
@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|S|t|y|l|a|b|l|e|<|Α|>| @49
-@4|{+0#00e0e07&| +0#0000000&@69
-| +0#00e0e07&@7|d+0#4040ff13&|e|f|a|u|l|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|}+0#00e0e07&| +0#0000000&@39
-| +0#00e0e07&@7|d+0#4040ff13&|e|f|a|u|l|t| +0#00e0e07&|Α| |μ|ʭ@1|$|0|_|(|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|n+0#e000002&|u|l@1|;+0#0000000&| |}+0#00e0e07&| +0#0000000&@31
-@4>}+0#00e0e07&| +0#0000000&@69
+@4|{| @69
+| +0#00e0e07&@7|d+0#4040ff13&|e|f|a|u|l|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|)| +0#0000000&|{| |}| @39
+| +0#00e0e07&@7|d+0#4040ff13&|e|f|a|u|l|t| +0#00e0e07&|Α| |μ|ʭ@1|$|0|_|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|n+0#e000002&|u|l@1|;+0#0000000&| |}| @31
+@4>}| @69
@75
-| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@11
-| +0#00e0e07&@31|)|;+0#0000000&| @40
-| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>| |μ|ʭ@1|$|0|_|(| +0#0000000&@21
-| +0#00e0e07&@11|/+0#0000e05&|*| |T+0#0000001#ffff4012|O|D|O|:+0#0000e05#ffffff0| |@|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"|b|e|s|p|o|k|e|"|)|*|/| +0#00e0e07&|β| |𝛽|)|;+0#0000000&| @17
+@4|/+0#0000e05&@1| |F|I|E|L|D|S|.| +0#0000000&@60
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|s+0#00e0003&|t|a|t|i|c| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|C|l|a|s@1|<|?|>| |C|L|A|S@1|_|L|O|C|K| |=| |c|l|a|s@1|L|o|c|k|(|)|;| @15
+@75
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|f+0#4040ff13&|i|n|a|l| +0#0000000&|O|b|j|e|c|t| |i|n|s|t|a|n|c|e|L|o|c|k| |=| |n+0#af5f00255&|e|w| +0#0000000&|O|b|j|e|c|t|(|)|;| @21
@75
-| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|1|_|(|/+0#0000e05&|*|/@10|/+0#ffffff16#ff404010|*+0#0000e05#ffffff0|/|)+0#00e0e07&|;+0#0000000&| @13
-| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|1|_|(| +0#0000000&@23
-| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|>| |ƒ|)|;+0#0000000&| @19
+@4|/+0#0000e05&@1| |C|O|N|S|T|R|U|C|T|O|R|S|.| +0#0000000&@54
+@4|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#0000000&|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#0000000&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|(|)| |{| |}| @17
+@4|<|T| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|C|o|m|p|a|r|a|b|l|e|<|T|>@1| |S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|,| |V|o|i|d| |v|)| |{| |}| @10
+@4|p+0#00e0003&|r|i|v|a|t|e| +0#0000000&|<|T| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|C|o|m|p|a|r|a|b|l|e|<|T|>@1| |S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|(|T| |t|)| |{| |}| @10
@75
-| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @20
-| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| +0#0000000&@12
-| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @17
-@57|3|7|,|2|-|5| @7|6|5|%|
+@4|/+0#0000e05&@1| |M|E|T|H|O|D|S|.| +0#0000000&@59
+| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@11
+@57|3|7|,|2|-|5| @7|4|9|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_02.vim b/runtime/syntax/testdir/dumps/java_methods_style_02.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_style_02.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_03.dump b/runtime/syntax/testdir/dumps/java_methods_style_03.dump
index e8ce44b..0656184 100644
--- a/runtime/syntax/testdir/dumps/java_methods_style_03.dump
+++ b/runtime/syntax/testdir/dumps/java_methods_style_03.dump
@@ -1,20 +1,20 @@
-| +0#00e0e07#ffffff0@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @17
+| +0#00e0e07#ffffff0@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|0|_|(|/+0#0000e05&@15| +0#0000000&@11
+| +0#00e0e07&@31|)|;+0#0000000&| @40
+| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|a+0#4040ff13&|b|s|t|r|a|c|t| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>| |μ|ʭ@1|$|0|_|(| +0#0000000&@21
+| +0#00e0e07&@15|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|b|e|s|p|o|k|e|"|)+0#e000e06&| +0#00e0e07&|β| |b|)|;+0#0000000&| @24
@75
-@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @41
-| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@9
-@4|{+0#00e0e07&| +0#0000000&|a|s|c|i@1|$|9|8|_|(|)|;| |}+0#00e0e07&| +0#0000000&@54
-> @74
-@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @41
-| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_|(| +0#0000000&@2
-| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| +0#0000000&@18
-@4|{+0#00e0e07&| +0#0000000&@69
-@8|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@60
-@4|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @32
-@4|}+0#00e0e07&| +0#0000000&@69
+| +0#00e0e07&@3>@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|1|_|(|/+0#0000e05&|*|/@10|/+0#ffffff16#ff404010|*+0#0000e05#ffffff0|/|)+0#00e0e07&|;+0#0000000&| @13
+| +0#00e0e07&@3|@+0#e000e06&|T|ɐ|g@1|a|b|l|ɘ| +0#00e0e07&|p+0#00e0003&|r|i|v|a|t|e| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|1|_|(| +0#0000000&@23
+| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|>| |ƒ|)|;+0#0000000&| @19
+@75
+@4|v+0#00e0003&|o|i|d| +0#0000000&|A|s|c|i@1|$|2|_|(|)| |{| |}| @51
+@4|<|T|,| |U| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|S|t|y|l|a|b|l|e|<|T|>@1| |v+0#00e0003&|o|i|d| +0#0000000&|Μ|ʭ@1|$|2|_|(|U| |u|)| |{| |}| @23
@75
-@4|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|c|a|s|t|"|)+0#0000000&| @35
-| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}+0#00e0e07&| +0#0000000&@5
-|}+0#00e0e07&| +0#0000000&@73
-|~+0#4040ff13&| @73
-|~| @73
-| +0#0000000&@56|5@1|,|0|-|1| @7|B|o|t|
+| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @20
+| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| +0#0000000&@12
+| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @17
+@75
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@41
+| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@9
+@4|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @54
+@57|5@1|,|2|-|5| @7|7@1|%|
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_03.vim b/runtime/syntax/testdir/dumps/java_methods_style_03.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_style_03.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_04.dump b/runtime/syntax/testdir/dumps/java_methods_style_04.dump
new file mode 100644
index 0000000..e593fe1
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_style_04.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @54
+@75
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@41
+| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_|(| +0#0000000&@2
+| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| +0#0000000&@18
+@4>{| @69
+@8|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@60
+@4|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @32
+@4|}| @69
+@75
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|;+0#0000000&| |}|
+@75
+@4|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@35
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}| @5
+|}| @73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|7|3|,|2|-|5| @7|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_04.vim b/runtime/syntax/testdir/dumps/java_methods_style_04.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_style_04.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_99.dump b/runtime/syntax/testdir/dumps/java_methods_style_99.dump
index a2e3228..e8962ce 100644
--- a/runtime/syntax/testdir/dumps/java_methods_style_99.dump
+++ b/runtime/syntax/testdir/dumps/java_methods_style_99.dump
@@ -1,20 +1,20 @@
-| +0#00e0e07#ffffff0@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9|8|_|(|)|;+0#0000000&| @20
-| +0#00e0e07&@3|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|n+0#e000e06&|a|t|i|v|e| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]|[|]| |μ|ʭ@1|$|9|8|_|(| +0#0000000&@12
-| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @17
+| +0#00e0e07#ffffff0@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)|;+0#0000000&| @17
@75
-@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @41
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@41
| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|v+0#00e0003&|o|i|d| +0#00e0e07&|a|s|c|i@1|$|9@1|_|(|)| +0#0000000&@9
-@4|{+0#00e0e07&| +0#0000000&|a|s|c|i@1|$|9|8|_|(|)|;| |}+0#00e0e07&| +0#0000000&@54
+@4|{| |a|s|c|i@1|$|9|8|_|(|)|;| |}| @54
@75
-@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#0000000&| @41
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|s|t|r|i|c|t|f|p|"|)+0#e000e06&| +0#0000000&@41
| +0#00e0e07&@3|p+0#00e0003&|r|o|t|e|c|t|e|d| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|f+0#4040ff13&|i|n|a|l| +0#00e0e07&|s+0#00e0003&|y|n|c|h|r|o|n|i|z|e|d| +0#00e0e07&|s+0#00e0003&|t|r|i|c|t|f|p| +0#00e0e07&|<|α|,| |β|>| |Τ|ʬ|<|α|>|[|]| |μ|ʭ@1|$|9@1|_|(| +0#0000000&@2
| +0#00e0e07&@11|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|β|,| |Τ|ʬ|<|α|>|[|]|[|]|>| |ƒ|)| +0#0000000&@18
-@4|{+0#00e0e07&| +0#0000000&@69
+@4|{| @69
@8|r+0#af5f00255&|e|t|u|r|n| +0#0000000&@60
@4|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|.|<|α|,| |β|>|μ|ʭ@1|$|9|8|_|(|ƒ|)|[|0+0#e000002&|]+0#0000000&|;| @32
-@4|}+0#00e0e07&| +0#0000000&@69
+@4|}| @69
@75
-@4|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(+0#0000000&|"+0#e000002&|c|a|s|t|"|)+0#0000000&| @35
-| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{+0#00e0e07&| +0#0000000&|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}+0#00e0e07&| +0#0000000&@5
->}+0#00e0e07&| +0#0000000&@73
-@57|6@1|,|1| @9|B|o|t|
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|s+0#00e0003&|t|a|t|i|c| +0#00e0e07&|C|l|a|s@1|<|?|>| |c|l|a|s@1|L|o|c|k|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|.|c+0#00e0003&|l|a|s@1|;+0#0000000&| |}|
+@75
+@4|@+0#e000e06&|O|v|e|r@1|i|d|e| +0#0000000&|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|"+0#e000002&|c|a|s|t|"|)+0#e000e06&| +0#0000000&@35
+| +0#00e0e07&@3|p+0#00e0003&|u|b|l|i|c| +0#00e0e07&|S|t|r|i|n|g| |t|o|S|t|r|i|n|g|(|)| +0#0000000&|{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|S|t|r|i|n|g|)| |"+0#e000002&|S|t|y|l|e|M|e|t|h|o|d|s|T|e|s|t|s|"|;+0#0000000&| |}| @5
+>}| @73
+@57|8|2|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/java_methods_style_99.vim b/runtime/syntax/testdir/dumps/java_methods_style_99.vim
new file mode 100644
index 0000000..1509558
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_methods_style_99.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[ƒɐɘʬʭΑ-Ωα-ω�]+?+Ige
diff --git a/runtime/syntax/testdir/dumps/java_unfoldment_00.dump b/runtime/syntax/testdir/dumps/java_unfoldment_00.dump
new file mode 100644
index 0000000..476a795
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_unfoldment_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t|l|o|c|a|l| |n|o|f|o|l|d|e|n|a|b|l|e| +0#0000000&@35
+|/+0#0000e05&@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|m|a|r|k|_|b|r|a|c|e|s|_|i|n|_|p|a|r|e|n|s|_|a|s|_|e|r@1|o|r|s| |=| |1| +0#0000000&@10
+@75
+@4|@+0#e000e06&|S|u|p@1|r|e|s@1|W|a|r|n|i|n|g|s|(|{+0#0000000&| @51
+@4|"@2| @67
+| +0#e000002&@3|b|e|s|p|o|k|e| +0#0000000&@63
+| +0#e000002&@3|/|*| +0#0000000&@68
+| +0#e000002&@4|*| +0#0000000&@68
+| +0#e000002&@4|*|/| +0#0000000&@67
+| +0#e000002&@3|/|*@1| +0#0000000&@67
+| +0#e000002&@4|*| +0#0000000&@68
+| +0#e000002&@4|*|/| +0#0000000&@67
+| +0#e000002&@3|/@1| +0#0000000&@68
+| +0#e000002&@3|/@1| +0#0000000&@68
+| +0#e000002&@3|/@1| +0#0000000&@68
+| +0#e000002&@3|{| +0#0000000&@69
+| +0#e000002&@3|}| +0#0000000&@69
+|"@2| @71
+|}|)+0#e000e06&| +0#0000000&@72
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/java_unfoldment_01.dump b/runtime/syntax/testdir/dumps/java_unfoldment_01.dump
new file mode 100644
index 0000000..cb57834
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_unfoldment_01.dump
@@ -0,0 +1,20 @@
+| +0#e000002#ffffff0@3|/@1| +0#0000000&@68
+| +0#e000002&@3|/@1| +0#0000000&@68
+| +0#e000002&@3|{| +0#0000000&@69
+| +0#e000002&@3|}| +0#0000000&@69
+|"@2| @71
+>}|)+0#e000e06&| +0#0000000&@72
+|c+0#00e0003&|l|a|s@1| +0#0000000&|U|n|f|o|l|d|i|n|g|T|e|s|t|s| |{| @52
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|U|n|f|o|l|d|e|n|a|b|l|e| @48
+@4|{| @69
+@4|}| @69
+@75
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|{| @62
+@8|n+0#af5f00255&|e|w| +0#0000000&|O|b|j|e|c|t|(|)| |{| @52
+@12|{| @61
+@16|{| @57
+@20|n+0#af5f00255&|e|w| +0#0000000&|O|b|j|e|c|t|(|)| |{@2| @38
+@24|n+0#af5f00255&|e|w| +0#0000000&|O|b|j|e|c|t|(|)| |{@2|}@2|;| @30
+@20|}@2|;| @50
+@16|}| @57
+@57|1|9|,|1| @9|1|9|%|
diff --git a/runtime/syntax/testdir/dumps/java_unfoldment_02.dump b/runtime/syntax/testdir/dumps/java_unfoldment_02.dump
new file mode 100644
index 0000000..f557d66
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_unfoldment_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@15|}| @57
+@12|}| @61
+@8|}|;| @64
+@75
+@8|s+0#af5f00255&|w|i|t|c|h| +0#0000000&|(|0+0#e000002&|)+0#0000000&| |{| @54
+@12>c+0#af5f00255&|a|s|e| +0#0000000&|0+0#e000002&|:+0#0000000&| @55
+@12|c+0#af5f00255&|a|s|e| +0#0000000&|1+0#e000002&|:+0#0000000&| |{| @53
+@16|b+0#af5f00255&|r|e|a|k|;+0#0000000&| @52
+@12|}| @61
+@12|d+0#af5f00255&|e|f|a|u|l|t|:+0#0000000&| |;| @52
+@8|}|;| @64
+@4|}| @69
+@75
+@4|{| |O|b|j|e|c|t| |b@1| |=| |(@1|O|b|j|e|c|t|)| |n+0#af5f00255&|e|w| +0#0000000&|b+0#00e0003&|y|t|e|[+0#0000000&|]|{+0#ffffff16#ff404010|}|)+0#0000000#ffffff0|;| |}| @30
+@4|{| @69
+|o+0#af5f00255&|u|t|:+0#0000000&| |{| @68
+@8|d+0#af5f00255&|o| +0#0000000&|{| @62
+@12|i+0#af5f00255&|f| +0#0000000&|(|t+0#e000002&|r|u|e|)+0#0000000&| @53
+@16|b+0#af5f00255&|r|e|a|k| +0#0000000&|o+0#af5f00255&|u|t|;+0#0000000&| @48
+@57|3|7|,|4|-|1|3| @6|4|6|%|
diff --git a/runtime/syntax/testdir/dumps/java_unfoldment_03.dump b/runtime/syntax/testdir/dumps/java_unfoldment_03.dump
new file mode 100644
index 0000000..e2735a7
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_unfoldment_03.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@15|b+0#af5f00255&|r|e|a|k| +0#0000000&|o+0#af5f00255&|u|t|;+0#0000000&| @48
+@8|}| |w+0#af5f00255&|h|i|l|e| +0#0000000&|(|f+0#e000002&|a|l|s|e|)+0#0000000&|;| @50
+|}| @73
+@4|}| @69
+@75
+@4>/+0#0000e05&|*@1| +0#0000000&@67
+| +0#0000e05&@4|*| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000000&@54
+| +0#0000e05&@4|*|/| +0#0000000&@67
+@4|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|1|(|)| |{| |}| @54
+@4|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@50
+@4|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|2|(|)| @58
+@4|{| @69
+@4|}| @69
+@4|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@50
+@4|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|3|(|)| |{| @56
+@4|}| @69
+@4|/+0#0000e05&|*@1| +0#e000e06&|N|o| |o|p|e|r|a|t|i|o|n|.| +0#0000e05&|*|/| +0#0000000&@50
+@4|v+0#00e0003&|o|i|d| +0#0000000&|n|o|O|p|4|(|)| |{| @56
+@4|/+0#0000e05&|*|/|\|/|\|/|\|*|/| +0#0000000&|;| |}| @56
+@57|5@1|,|2|-|5| @7|7|3|%|
diff --git a/runtime/syntax/testdir/dumps/java_unfoldment_04.dump b/runtime/syntax/testdir/dumps/java_unfoldment_04.dump
new file mode 100644
index 0000000..aa0ed17
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_unfoldment_04.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|/+0#0000e05&|*|/|\|/|\|/|\|*|/| +0#0000000&|;| |}| @56
+|}| @73
+@75
+|/+0#0000e05&|*| +0#0000000&@72
+| +0#0000e05&|*| |S|o|m|e| |n|o|t|e|.| +0#0000000&@61
+| +0#0000e05&>*| |{| +0#0000000&@70
+| +0#0000e05&|*| |}| +0#0000000&@70
+| +0#0000e05&|*|/| +0#0000000&@71
+|/+0#0000e05&|*@1| +0#0000000&@71
+| +0#0000e05&|*| +0#e000e06&|A| |s|u|m@1|a|r|y|.| +0#0000000&@61
+| +0#0000e05&|*| |{| +0#0000000&@70
+| +0#0000e05&|*| |}| +0#0000000&@70
+| +0#0000e05&|*|/| +0#0000000&@71
+|/+0#0000e05&@1| +0#0000000&@72
+|/+0#0000e05&@1| |{| +0#0000000&@70
+|/+0#0000e05&@1| |}| +0#0000000&@70
+@75
+|/+0#0000e05&|*| |1|2@1|||.@67
+@20|*|/| +0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|U|n|f|o|l|d|e|n|a|b|l|e| |{| @27
+@57|7|3|,|2| @9|9|8|%|
diff --git a/runtime/syntax/testdir/dumps/java_unfoldment_99.dump b/runtime/syntax/testdir/dumps/java_unfoldment_99.dump
new file mode 100644
index 0000000..9e10ac4
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_unfoldment_99.dump
@@ -0,0 +1,20 @@
+|}+0&#ffffff0| @73
+@75
+|/+0#0000e05&|*| +0#0000000&@72
+| +0#0000e05&|*| |S|o|m|e| |n|o|t|e|.| +0#0000000&@61
+| +0#0000e05&|*| |{| +0#0000000&@70
+| +0#0000e05&|*| |}| +0#0000000&@70
+| +0#0000e05&|*|/| +0#0000000&@71
+|/+0#0000e05&|*@1| +0#0000000&@71
+| +0#0000e05&|*| +0#e000e06&|A| |s|u|m@1|a|r|y|.| +0#0000000&@61
+| +0#0000e05&|*| |{| +0#0000000&@70
+| +0#0000e05&|*| |}| +0#0000000&@70
+| +0#0000e05&|*|/| +0#0000000&@71
+|/+0#0000e05&@1| +0#0000000&@72
+|/+0#0000e05&@1| |{| +0#0000000&@70
+|/+0#0000e05&@1| |}| +0#0000000&@70
+@75
+|/+0#0000e05&|*| |1|2@1|||.@67
+@20|*|/| +0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|U|n|f|o|l|d|e|n|a|b|l|e| |{| @27
+>}| @73
+@57|8|6|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_00.dump b/runtime/syntax/testdir/dumps/vim9_comment_00.dump
index 57b0216..46d283f 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_00.dump
+++ b/runtime/syntax/testdir/dumps/vim9_comment_00.dump
@@ -4,16 +4,16 @@
@75
|#+0#0000e05&| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@53
@75
-| +0#0000e05&|#| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
+@1|#+0#0000e05&| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
@1|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&@57
@75
|f+0#af5f00255&|u|n|c|t|i|o|n|!| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@59
-| +0#0000e05&@1|"| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
+@2|"+0#0000e05&| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
@2|#| |4+0#e000002&|2| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@58
|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
@75
|d+0#af5f00255&|e|f|!| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@64
-| +0#0000e05&@1|#| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
+@2|#+0#0000e05&| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
@2|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@46
|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
@75
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_01.dump b/runtime/syntax/testdir/dumps/vim9_comment_01.dump
index 1b0d7c9..d596208 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_01.dump
+++ b/runtime/syntax/testdir/dumps/vim9_comment_01.dump
@@ -1,20 +1,20 @@
| +0&#ffffff0@74
|d+0#af5f00255&|e|f|!| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@64
-| +0#0000e05&@1|#| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
+@2|#+0#0000e05&| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
@2|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@46
|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
> @74
|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|-+0#af5f00255&|c+0#e000e06&|o|u|n|t| +0#0000000&|F|o@1|C|o|m@1|a|n|d| |{+0#e000e06&| +0#0000000&@47
-| +0#0000e05&@1|#| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
+@2|#+0#0000e05&| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
@2|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@46
|}+0#e000e06&| +0#0000000&@73
@75
|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
-| +0#0000e05&@1|#| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
+@2|#+0#0000e05&| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
@2|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@46
|}+0#e000e06&| +0#0000000&@73
@75
@75
-|#+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1|3|0|4|7| +0#0000000&@59
+|#+0#0000e05&| |M|u|l|t|i|l|i|n|e| |c|o|m@1|e|n|t|s| +0#0000000&@54
@75
-@57|1|9|,|0|-|1| @7|5|9|%|
+@57|1|9|,|0|-|1| @7|2|8|%|
diff --git a/runtime/syntax/testdir/dumps/vim9_comment_02.dump b/runtime/syntax/testdir/dumps/vim9_comment_02.dump
new file mode 100644
index 0000000..e6a4de5
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_comment_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@65
+| +0#0000e05&@1|\| |c|o|n|t|i|n|u|i|n|g| |c|o|m@1|e|n|t| +0#0000000&@52
+| +0#0000e05&@1|\| |c|o|n|t|i|n|u|i|n|g| |c|o|m@1|e|n|t| +0#0000000&@52
+@75
+>#+0#0000e05&| |:|F|o@1| +0#0000000&@68
+| +0#0000e05&@5|\| |a|r|g|1| +0#0000000&@62
+| +0#0000e05&@5|#|\| |c|o|m@1|e|n|t| +0#0000000&@58
+| +0#0000e05&@5|\| |a|r|g|2| +0#0000000&@62
+@75
+|e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|T|O|P|"| +0#0000000&@64
+@75
+@75
+|#+0#0000e05&| |L|i|n|e|-|c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t|s| +0#0000000&@46
+@75
+|:|F|o@1| @70
+@6|#+0#0000e05&|\| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t| +0#0000000&@40
+@6|\+0#e000e06&| +0#0000000&|a|r|g|1| @62
+@6|#+0#0000e05&|\| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t| +0#0000000&@40
+@57|3|7|,|1| @9|6|8|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_02.dump b/runtime/syntax/testdir/dumps/vim9_comment_03.dump
index 7de6ffb..0e424ab 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_02.dump
+++ b/runtime/syntax/testdir/dumps/vim9_comment_03.dump
@@ -1,9 +1,14 @@
-| +0&#ffffff0@74
+| +0&#ffffff0@5|#+0#0000e05&|\| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t| +0#0000000&@40
+@6|\+0#e000e06&| +0#0000000&|a|r|g|2| @62
+@75
+@75
+|#+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1|3|0|4|7| +0#0000000&@59
+> @74
|i+0#af5f00255&|f| +0#0000000&|!+0#af5f00255&|e+0#00e0e07&|x|i|s|t|s|(+0#e000e06&|"+0#e000002&|:|D|i|f@1|O|r|i|g|"|)+0#e000e06&| +0#0000000&@51
@2|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|D|i|f@1|O|r|i|g| |v+0#af5f00255&|e|r|t| +0#0000000&|n+0#af5f00255&|e|w| +0#0000000&||| |s+0#af5f00255&|e|t| +0#0000000&|b+0#e000e06&|t|=+0#0000000&|n|o|f|i|l|e| ||+0#af5f00255&| +0#0000000&|r+0#af5f00255&| +0#0000000&|++0#af5f00255&@1|e|d|i|t| +0#0000000&|%+0#af5f00255&@1| +0#0000000&||| |0+0#e000002&|d+0#0000000&|_| ||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&
@18|\+0#e000e06&| +0#0000000&||| |w+0#af5f00255&|i|n|c|m|d| +0#0000000&|p+0#af5f00255&| +0#0000000&||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@33
|e+0#af5f00255&|n|d|i|f| +0#0000000&@69
-> @74
+@75
@75
|#+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1@1|3|0|7| |a|n|d| |#|1@1|5|6|0| +0#0000000&@48
@75
@@ -12,9 +17,4 @@
|~| @73
|~| @73
|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-| +0#0000000&@56|3|7|,|0|-|1| @7|B|o|t|
+| +0#0000000&@56|5@1|,|0|-|1| @7|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_99.dump b/runtime/syntax/testdir/dumps/vim9_comment_99.dump
index f8759da..bed55bc 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_comment-vim9_99.dump
+++ b/runtime/syntax/testdir/dumps/vim9_comment_99.dump
@@ -1,9 +1,9 @@
-|}+0#e000e06#ffffff0| +0#0000000&@73
-@75
-|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
-| +0#0000e05&@1|#| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
-@2|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@46
-|}+0#e000e06&| +0#0000000&@73
+| +0&#ffffff0@74
+|:|F|o@1| @70
+@6|#+0#0000e05&|\| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t| +0#0000000&@40
+@6|\+0#e000e06&| +0#0000000&|a|r|g|1| @62
+@6|#+0#0000e05&|\| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t| +0#0000000&@40
+@6|\+0#e000e06&| +0#0000000&|a|r|g|2| @62
@75
@75
|#+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1|3|0|4|7| +0#0000000&@59
@@ -17,4 +17,4 @@
|#+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1@1|3|0|7| |a|n|d| |#|1@1|5|6|0| +0#0000000&@48
@75
>#+0#0000e05&| |T|h|i|s| |i|s| |w|h|a|t| |w|e| |c|a|l@1| |"| |b|l|a|h| +0#0000000&@45
-@57|4|1|,|1| @9|B|o|t|
+@57|6|4|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_00.dump b/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_00.dump
new file mode 100644
index 0000000..ef9f580
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_00.dump
@@ -0,0 +1,20 @@
+>v+0#af5f00255#ffffff0|i|m|9|s|c|r|i|p|t| +0#0000000&@64
+@75
+|#+0#0000e05&| |V|i|m| |c|o|m@1|e|n|t| |s|t|r|i|n|g|s| +0#0000000&@53
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|t|r|u|e| +0#0000000&@20
+@75
+|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+@2|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+@2|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_01.dump b/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_01.dump
new file mode 100644
index 0000000..72a7dfb
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_01.dump
@@ -0,0 +1,20 @@
+|e+0#af5f00255#ffffff0|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+@2|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+> @74
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+@2|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|9|,|0|-|1| @7|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_99.dump b/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_99.dump
new file mode 100644
index 0000000..efaf53b
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_ex_comment_strings_99.dump
@@ -0,0 +1,20 @@
+|#+0#0000e05#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|t|r|u|e| +0#0000000&@20
+@75
+|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+@2|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+@2|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+@2|#+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+>}+0#e000e06&| +0#0000000&@73
+@57|2@1|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_00.dump b/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_00.dump
new file mode 100644
index 0000000..191b9f2
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_00.dump
@@ -0,0 +1,20 @@
+>v+0#af5f00255#ffffff0|i|m|9|s|c|r|i|p|t| +0#0000000&@64
+@75
+|#+0#0000e05&| |V|i|m| |c|o|m@1|e|n|t| |s|t|r|i|n|g|s| +0#0000000&@53
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|f|a|l|s|e| +0#0000000&@19
+@75
+|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+@2|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+@2|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_01.dump b/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_01.dump
new file mode 100644
index 0000000..ef54148
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_01.dump
@@ -0,0 +1,20 @@
+|e+0#af5f00255#ffffff0|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+@2|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+> @74
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+@2|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|9|,|0|-|1| @7|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_99.dump b/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_99.dump
new file mode 100644
index 0000000..c384e74
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_ex_no_comment_strings_99.dump
@@ -0,0 +1,20 @@
+|#+0#0000e05#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|f|a|l|s|e| +0#0000000&@19
+@75
+|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+@2|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+@2|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+@2|#+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+>}+0#e000e06&| +0#0000000&@73
+@57|2@1|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim9_keymap_01.vim b/runtime/syntax/testdir/dumps/vim9_keymap_01.vim
new file mode 100644
index 0000000..546837c
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_keymap_01.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[“�]+?+ge
diff --git a/runtime/syntax/testdir/dumps/vim9_keymap_99.vim b/runtime/syntax/testdir/dumps/vim9_keymap_99.vim
new file mode 100644
index 0000000..546837c
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_keymap_99.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[“�]+?+ge
diff --git a/runtime/syntax/testdir/dumps/vim9_legacy_header_00.dump b/runtime/syntax/testdir/dumps/vim9_legacy_header_00.dump
index 2f682d9..a5f1802 100644
--- a/runtime/syntax/testdir/dumps/vim9_legacy_header_00.dump
+++ b/runtime/syntax/testdir/dumps/vim9_legacy_header_00.dump
@@ -12,7 +12,7 @@
@75
|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@65
@75
-| +0#0000e05&|#| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
+@1|#+0#0000e05&| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
@1|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&@57
|~+0#4040ff13&| @73
|~| @73
diff --git a/runtime/syntax/testdir/dumps/vim9_legacy_header_99.dump b/runtime/syntax/testdir/dumps/vim9_legacy_header_99.dump
index d400e31..27ff90e 100644
--- a/runtime/syntax/testdir/dumps/vim9_legacy_header_99.dump
+++ b/runtime/syntax/testdir/dumps/vim9_legacy_header_99.dump
@@ -12,7 +12,7 @@
@75
|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@65
@75
-| +0#0000e05&|#| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
+@1|#+0#0000e05&| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
@1>"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&@57
|~+0#4040ff13&| @73
|~| @73
diff --git a/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_00.dump b/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_00.dump
index b324c46..fe8e737 100644
--- a/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_00.dump
+++ b/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_00.dump
@@ -3,7 +3,7 @@
@75
|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@65
@75
-| +0#0000e05&|#| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
+@1|#+0#0000e05&| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
@1|"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&@57
|~+0#4040ff13&| @73
|~| @73
diff --git a/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_99.dump b/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_99.dump
index b3fa847..fe339c4 100644
--- a/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_99.dump
+++ b/runtime/syntax/testdir/dumps/vim9_legacy_header_fold_99.dump
@@ -3,7 +3,7 @@
@75
|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@65
@75
-| +0#0000e05&|#| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
+@1|#+0#0000e05&| |s|t|r|i|n|g| |o|n|l|y| |r|e|c|o|g|n|i|s|e|d| |w|i|t|h| |l|e|a|d|i|n|g| |c|h|a|r| +0#0000000&@31
@1>"+0#e000002&|u|s|e|l|e|s@1| |s|t|r|i|n|g|"| +0#0000000&@57
|~+0#4040ff13&| @73
|~| @73
diff --git a/runtime/syntax/testdir/dumps/vim9_shebang_00.dump b/runtime/syntax/testdir/dumps/vim9_shebang_00.dump
new file mode 100644
index 0000000..3f2818c
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_shebang_00.dump
@@ -0,0 +1,20 @@
+>#+0#e000e06#ffffff0|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000&@53
+|v+0#af5f00255&|i|m|9|s|c|r|i|p|t| +0#0000000&@64
+@75
+|#+0#0000e05&| |V|i|m| |s|h|e|b|a|n|g| |l|i|n|e| +0#0000000&@56
+@75
+|#+0#0000e05&| |j|u|s|t| |a| |l|i|n|e| |c|o|m@1|e|n|t| +0#0000000&@53
+|#+0#0000e05&|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000&@53
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim9_shebang_99.dump b/runtime/syntax/testdir/dumps/vim9_shebang_99.dump
new file mode 100644
index 0000000..71f543e
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim9_shebang_99.dump
@@ -0,0 +1,20 @@
+|#+0#e000e06#ffffff0|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000&@53
+|v+0#af5f00255&|i|m|9|s|c|r|i|p|t| +0#0000000&@64
+@75
+|#+0#0000e05&| |V|i|m| |s|h|e|b|a|n|g| |l|i|n|e| +0#0000000&@56
+@75
+|#+0#0000e05&| |j|u|s|t| |a| |l|i|n|e| |c|o|m@1|e|n|t| +0#0000000&@53
+>#+0#0000e05&|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000&@53
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|7|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_99.dump b/runtime/syntax/testdir/dumps/vim_99.dump
deleted file mode 100644
index 8e9320c..0000000
--- a/runtime/syntax/testdir/dumps/vim_99.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-|"+0#0000e05#ffffff0| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1|3|0|4|7| +0#0000000&@59
-@75
-|i+0#af5f00255&|f| +0#0000000&|!+0#af5f00255&|e+0#00e0e07&|x|i|s|t|s|(+0#e000e06&|"+0#e000002&|:|D|i|f@1|O|r|i|g|"|)+0#e000e06&| +0#0000000&@51
-@2|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|D|i|f@1|O|r|i|g| |v+0#af5f00255&|e|r|t| +0#0000000&|n+0#af5f00255&|e|w| +0#0000000&||| |s+0#af5f00255&|e|t| +0#0000000&|b+0#e000e06&|t|=+0#0000000&|n|o|f|i|l|e| ||+0#af5f00255&| +0#0000000&|r+0#af5f00255&| +0#0000000&|++0#af5f00255&@1|e|d|i|t| +0#0000000&|#| ||| |0+0#e000002&|d+0#0000000&|_| ||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@1
-| +0#e000e06&@17|\| +0#0000000&||| |w+0#af5f00255&|i|n|c|m|d| +0#0000000&|p+0#af5f00255&| +0#0000000&||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@33
-|e+0#af5f00255&|n|d|i|f| +0#0000000&@69
-@75
-@75
-|"+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1@1|3|0|7| |a|n|d| |#|1@1|5|6|0| +0#0000000&@48
-@75
->"+0#0000e05&| |T|h|i|s| |i|s| |w|h|a|t| |w|e| |c|a|l@1| |"| |b|l|a|h| +0#0000000&@45
-|~+0#4040ff13&| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|"+0#0000000&|i|n|p|u|t|/|v|i|m|.|v|i|m|"| |1@1|L|,| |2|0|9|B| @31|1@1|,|1| @9|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment_00.dump b/runtime/syntax/testdir/dumps/vim_comment_00.dump
index a1c1880..335fc3f 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_comment_00.dump
+++ b/runtime/syntax/testdir/dumps/vim_comment_00.dump
@@ -5,7 +5,7 @@
|#| |4+0#e000002&|2| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@60
@75
|f+0#af5f00255&|u|n|c|t|i|o|n|!| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@59
-| +0#0000e05&@1|"| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
+@2|"+0#0000e05&| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
@2|#| |4+0#e000002&|2| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@58
|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
@75
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment_01.dump b/runtime/syntax/testdir/dumps/vim_comment_01.dump
index 513f64c..ebf0c42 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_comment_01.dump
+++ b/runtime/syntax/testdir/dumps/vim_comment_01.dump
@@ -12,9 +12,9 @@
|}+0#e000e06&| +0#0000000&@73
@75
@75
-|"+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1|3|0|4|7| +0#0000000&@59
+|"+0#0000e05&| |M|u|l|t|i|l|i|n|e| |c|o|m@1|e|n|t|s| +0#0000000&@54
@75
-|i+0#af5f00255&|f| +0#0000000&|!+0#af5f00255&|e+0#00e0e07&|x|i|s|t|s|(+0#e000e06&|"+0#e000002&|:|D|i|f@1|O|r|i|g|"|)+0#e000e06&| +0#0000000&@51
-@2|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|D|i|f@1|O|r|i|g| |v+0#af5f00255&|e|r|t| +0#0000000&|n+0#af5f00255&|e|w| +0#0000000&||| |s+0#af5f00255&|e|t| +0#0000000&|b+0#e000e06&|t|=+0#0000000&|n|o|f|i|l|e| ||+0#af5f00255&| +0#0000000&|r+0#af5f00255&| +0#0000000&|++0#af5f00255&@1|e|d|i|t| +0#0000000&|#| ||| |0+0#e000002&|d+0#0000000&|_| ||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@1
-@18|\+0#e000e06&| +0#0000000&||| |w+0#af5f00255&|i|n|c|m|d| +0#0000000&|p+0#af5f00255&| +0#0000000&||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@33
-@57|1|9|,|3| @9|5|0|%|
+|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@65
+| +0#0000e05&@1|\| |c|o|n|t|i|n|u|i|n|g| |c|o|m@1|e|n|t| +0#0000000&@52
+| +0#0000e05&@1|\| |c|o|n|t|i|n|u|i|n|g| |c|o|m@1|e|n|t| +0#0000000&@52
+@57|1|9|,|3| @9|2|6|%|
diff --git a/runtime/syntax/testdir/dumps/vim_comment_02.dump b/runtime/syntax/testdir/dumps/vim_comment_02.dump
new file mode 100644
index 0000000..8e31fb6
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_comment_02.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#ffffff0@1|\| |c|o|n|t|i|n|u|i|n|g| |c|o|m@1|e|n|t| +0#0000000&@52
+@75
+|"+0#0000e05&| |:|F|o@1| +0#0000000&@68
+| +0#0000e05&@5|\| |a|r|g|1| +0#0000000&@62
+| +0#0000e05&@5|"|\| |c|o|m@1|e|n|t| +0#0000000&@58
+| +0#0000e05&@5>\| |a|r|g|2| +0#0000000&@62
+@75
+|e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|T|O|P|"| +0#0000000&@64
+@75
+@75
+|"+0#0000e05&| |L|i|n|e|-|c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t|s| +0#0000000&@46
+@75
+|:|F|o@1| @70
+@6|"+0#0000e05&|\| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t| +0#0000000&@40
+@6|\+0#e000e06&| +0#0000000&|a|r|g|1| @62
+@6|"+0#0000e05&|\| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |c|o|m@1|e|n|t| +0#0000000&@40
+@6|\+0#e000e06&| +0#0000000&|a|r|g|2| @62
+@75
+@75
+@57|3|7|,|7| @9|6|3|%|
diff --git a/runtime/syntax/testdir/dumps/vim_00.dump b/runtime/syntax/testdir/dumps/vim_comment_03.dump
index 852148f..2d40f6c 100644
--- a/runtime/syntax/testdir/dumps/vim_00.dump
+++ b/runtime/syntax/testdir/dumps/vim_comment_03.dump
@@ -1,20 +1,20 @@
->"+0#0000e05#ffffff0| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1|3|0|4|7| +0#0000000&@59
+| +0&#ffffff0@74
+|"+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1|3|0|4|7| +0#0000000&@59
@75
|i+0#af5f00255&|f| +0#0000000&|!+0#af5f00255&|e+0#00e0e07&|x|i|s|t|s|(+0#e000e06&|"+0#e000002&|:|D|i|f@1|O|r|i|g|"|)+0#e000e06&| +0#0000000&@51
@2|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|D|i|f@1|O|r|i|g| |v+0#af5f00255&|e|r|t| +0#0000000&|n+0#af5f00255&|e|w| +0#0000000&||| |s+0#af5f00255&|e|t| +0#0000000&|b+0#e000e06&|t|=+0#0000000&|n|o|f|i|l|e| ||+0#af5f00255&| +0#0000000&|r+0#af5f00255&| +0#0000000&|++0#af5f00255&@1|e|d|i|t| +0#0000000&|#| ||| |0+0#e000002&|d+0#0000000&|_| ||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@1
-| +0#e000e06&@17|\| +0#0000000&||| |w+0#af5f00255&|i|n|c|m|d| +0#0000000&|p+0#af5f00255&| +0#0000000&||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@33
+@18>\+0#e000e06&| +0#0000000&||| |w+0#af5f00255&|i|n|c|m|d| +0#0000000&|p+0#af5f00255&| +0#0000000&||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@33
|e+0#af5f00255&|n|d|i|f| +0#0000000&@69
@75
@75
|"+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1@1|3|0|7| |a|n|d| |#|1@1|5|6|0| +0#0000000&@48
@75
|"+0#0000e05&| |T|h|i|s| |i|s| |w|h|a|t| |w|e| |c|a|l@1| |"| |b|l|a|h| +0#0000000&@45
-|~+0#4040ff13&| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|"+0#0000000&|i|n|p|u|t|/|v|i|m|.|v|i|m|"| |1@1|L|,| |2|0|9|B| @31|1|,|1| @10|A|l@1|
+@75
+@75
+|"+0#0000e05&| |I|s@1|u|e| |#| |#|9|5|8|7| +0#0000000&@59
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|C|o|m@1|e|n|t|T|i|t|l|e|(+0#e000e06&|)| +0#0000000&@56
+| +0#0000e05&@1|#| |T|i|t|l|e|:| |.@2| +0#0000000&@60
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@57|5@1|,|5|-|1|9| @6|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment_99.dump b/runtime/syntax/testdir/dumps/vim_comment_99.dump
index e9bcabe..bb1fbb0 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_comment_99.dump
+++ b/runtime/syntax/testdir/dumps/vim_comment_99.dump
@@ -15,6 +15,6 @@
|"+0#0000e05&| |I|s@1|u|e| |#| |#|9|5|8|7| +0#0000000&@59
@75
|d+0#af5f00255&|e|f| +0#0000000&|C|o|m@1|e|n|t|T|i|t|l|e|(+0#e000e06&|)| +0#0000000&@56
-| +0#0000e05&@1|#| +0#0000000&|T+0#e000e06&|i|t|l|e|:| +0#0000e05&|.@2| +0#0000000&@60
+| +0#0000e05&@1|#| |T|i|t|l|e|:| |.@2| +0#0000000&@60
>e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
-@57|4|5|,|1| @9|B|o|t|
+@57|6|8|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_catch_00.dump b/runtime/syntax/testdir/dumps/vim_ex_catch_00.dump
new file mode 100644
index 0000000..748c48b
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_catch_00.dump
@@ -0,0 +1,20 @@
+>"+0#0000e05#ffffff0| |V|i|m| |:|c|a|t|c|h| |c|o|m@1|a|n|d| +0#0000000&@54
+@75
+|"+0#0000e05&| |:|h|e|l|p| |:|c|a|t|c|h| +0#0000000&@60
+@75
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|:|I|n|t|e|r@1|u|p|t|$|/+0#e000e06&| +0#0000000&@8|"+0#0000e05&| |c|a|t|c|h| |i|n|t|e|r@1|u|p|t|s| |(|C|T|R|L|-|C|)| +0#0000000&@15
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|\+0#e000e06&|%|(|(+0#0000000&|\|a|\|+|)|\+0#e000e06&|)|\+0#0000000&|=|:|E|/+0#e000e06&| +0#0000000&@4|"+0#0000e05&| |c|a|t|c|h| |a|l@1| |V|i|m| |e|r@1|o|r|s| +0#0000000&@20
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|\+0#e000e06&|%|(|(+0#0000000&|\|a|\|+|)|\+0#e000e06&|)|\+0#0000000&|=|:|/+0#e000e06&| +0#0000000&@5|"+0#0000e05&| |c|a|t|c|h| |e|r@1|o|r|s| |a|n|d| |i|n|t|e|r@1|u|p|t|s| +0#0000000&@13
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|(|w|r|i|t|e|)|:|/+0#e000e06&| +0#0000000&@11|"+0#0000e05&| |c|a|t|c|h| |a|l@1| |e|r@1|o|r|s| |i|n| |:|w|r|i|t|e| +0#0000000&@14
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|\+0#e000e06&|%|(|(+0#0000000&|\|a|\|+|)|\+0#e000e06&|)|\+0#0000000&|=|:|E|1|2|3|:|/+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|a|t|c|h| |e|r@1|o|r| |E|1|2|3| +0#0000000&@24
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|m+0#0000000&|y|-|e|x|c|e|p|t|i|o|n|/+0#e000e06&| +0#0000000&@11|"+0#0000e05&| |c|a|t|c|h| |u|s|e|r| |e|x|c|e|p|t|i|o|n| +0#0000000&@20
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|.+0#0000000&|*|/+0#e000e06&| +0#0000000&@21|"+0#0000e05&| |c|a|t|c|h| |e|v|e|r|y|t|h|i|n|g| +0#0000000&@24
+|c+0#af5f00255&|a|t|c|h| +0#0000000&@26|"+0#0000e05&| |s|a|m|e| |a|s| |/|.|*|/| +0#0000000&@28
+@75
+|"+0#0000e05&| |:|h|e|l|p| |:|t|r|y| +0#0000000&@62
+@75
+|t+0#af5f00255&|r|y| +0#0000000&||| |s+0#af5f00255&|l|e@1|p| +0#0000000&|1+0#e000002&|0@1| +0#0000000&||| |c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|:|I|n|t|e|r@1|u|p|t|$|/+0#e000e06&| +0#0000000&||| |e+0#af5f00255&|n|d|t|r|y| +0#0000000&@24
+|t+0#af5f00255&|r|y| +0#0000000&||| |e+0#af5f00255&|d|i|t| +0#0000000&||| |c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|(|e|d|i|t|)|:|E|\|d|\|+|/+0#e000e06&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|e|r@1|o|r|"| +0#0000000&||| |e+0#af5f00255&|n|d|t|r|y| +0#0000000&@13
+|~+0#4040ff13&| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_catch_99.dump b/runtime/syntax/testdir/dumps/vim_ex_catch_99.dump
new file mode 100644
index 0000000..39e47c1
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_catch_99.dump
@@ -0,0 +1,20 @@
+|"+0#0000e05#ffffff0| |V|i|m| |:|c|a|t|c|h| |c|o|m@1|a|n|d| +0#0000000&@54
+@75
+|"+0#0000e05&| |:|h|e|l|p| |:|c|a|t|c|h| +0#0000000&@60
+@75
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|:|I|n|t|e|r@1|u|p|t|$|/+0#e000e06&| +0#0000000&@8|"+0#0000e05&| |c|a|t|c|h| |i|n|t|e|r@1|u|p|t|s| |(|C|T|R|L|-|C|)| +0#0000000&@15
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|\+0#e000e06&|%|(|(+0#0000000&|\|a|\|+|)|\+0#e000e06&|)|\+0#0000000&|=|:|E|/+0#e000e06&| +0#0000000&@4|"+0#0000e05&| |c|a|t|c|h| |a|l@1| |V|i|m| |e|r@1|o|r|s| +0#0000000&@20
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|\+0#e000e06&|%|(|(+0#0000000&|\|a|\|+|)|\+0#e000e06&|)|\+0#0000000&|=|:|/+0#e000e06&| +0#0000000&@5|"+0#0000e05&| |c|a|t|c|h| |e|r@1|o|r|s| |a|n|d| |i|n|t|e|r@1|u|p|t|s| +0#0000000&@13
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|(|w|r|i|t|e|)|:|/+0#e000e06&| +0#0000000&@11|"+0#0000e05&| |c|a|t|c|h| |a|l@1| |e|r@1|o|r|s| |i|n| |:|w|r|i|t|e| +0#0000000&@14
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|\+0#e000e06&|%|(|(+0#0000000&|\|a|\|+|)|\+0#e000e06&|)|\+0#0000000&|=|:|E|1|2|3|:|/+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|a|t|c|h| |e|r@1|o|r| |E|1|2|3| +0#0000000&@24
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|m+0#0000000&|y|-|e|x|c|e|p|t|i|o|n|/+0#e000e06&| +0#0000000&@11|"+0#0000e05&| |c|a|t|c|h| |u|s|e|r| |e|x|c|e|p|t|i|o|n| +0#0000000&@20
+|c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|.+0#0000000&|*|/+0#e000e06&| +0#0000000&@21|"+0#0000e05&| |c|a|t|c|h| |e|v|e|r|y|t|h|i|n|g| +0#0000000&@24
+|c+0#af5f00255&|a|t|c|h| +0#0000000&@26|"+0#0000e05&| |s|a|m|e| |a|s| |/|.|*|/| +0#0000000&@28
+@75
+|"+0#0000e05&| |:|h|e|l|p| |:|t|r|y| +0#0000000&@62
+@75
+|t+0#af5f00255&|r|y| +0#0000000&||| |s+0#af5f00255&|l|e@1|p| +0#0000000&|1+0#e000002&|0@1| +0#0000000&||| |c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|:|I|n|t|e|r@1|u|p|t|$|/+0#e000e06&| +0#0000000&||| |e+0#af5f00255&|n|d|t|r|y| +0#0000000&@24
+>t+0#af5f00255&|r|y| +0#0000000&||| |e+0#af5f00255&|d|i|t| +0#0000000&||| |c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|V|i|m|(|e|d|i|t|)|:|E|\|d|\|+|/+0#e000e06&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|e|r@1|o|r|"| +0#0000000&||| |e+0#af5f00255&|n|d|t|r|y| +0#0000000&@13
+|~+0#4040ff13&| @73
+|~| @73
+| +0#0000000&@56|1|7|,|1| @9|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment_02.dump b/runtime/syntax/testdir/dumps/vim_ex_comment_02.dump
deleted file mode 100644
index e2b6092..0000000
--- a/runtime/syntax/testdir/dumps/vim_ex_comment_02.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@17|\+0#e000e06&| +0#0000000&||| |w+0#af5f00255&|i|n|c|m|d| +0#0000000&|p+0#af5f00255&| +0#0000000&||| |d+0#af5f00255&|i|f@1|t|h|i|s| +0#0000000&@33
-|e+0#af5f00255&|n|d|i|f| +0#0000000&@69
-@75
-@75
-|"+0#0000e05&| +0#0000000&|I+0#e000e06&|s@1|u|e|:| +0#0000e05&|#|1@1|3|0|7| |a|n|d| |#|1@1|5|6|0| +0#0000000&@48
-> @74
-|"+0#0000e05&| |T|h|i|s| |i|s| |w|h|a|t| |w|e| |c|a|l@1| |"| |b|l|a|h| +0#0000000&@45
-@75
-@75
-|"+0#0000e05&| |I|s@1|u|e| |#| |#|9|5|8|7| +0#0000000&@59
-@75
-|d+0#af5f00255&|e|f| +0#0000000&|C|o|m@1|e|n|t|T|i|t|l|e|(+0#e000e06&|)| +0#0000000&@56
-| +0#0000e05&@1|#| +0#0000000&|T+0#e000e06&|i|t|l|e|:| +0#0000e05&|.@2| +0#0000000&@60
-|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
-|~+0#4040ff13&| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-| +0#0000000&@56|3|7|,|0|-|1| @7|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment_strings_00.dump b/runtime/syntax/testdir/dumps/vim_ex_comment_strings_00.dump
new file mode 100644
index 0000000..9500d07
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_comment_strings_00.dump
@@ -0,0 +1,20 @@
+>"+0#0000e05#ffffff0| |V|i|m| |c|o|m@1|e|n|t| |s|t|r|i|n|g|s| +0#0000000&@53
+|"+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|t|r|u|e| +0#0000000&@20
+@75
+|"+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+| +0#0000e05&@1|#| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+| +0#0000e05&@1|#| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+| +0#0000e05&@1|#| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_comment_strings_99.dump b/runtime/syntax/testdir/dumps/vim_ex_comment_strings_99.dump
new file mode 100644
index 0000000..90edc97
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_comment_strings_99.dump
@@ -0,0 +1,20 @@
+|"+0#0000e05#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|t|r|u|e| +0#0000000&@20
+@75
+|"+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+| +0#0000e05&@1|#| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+| +0#0000e05&@1|#| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+| +0#0000e05&@1|#| |p|r|e| |"+0#e000002&|s|t|r|i|n|g|"| +0#0000e05&|p|o|s|t| +0#0000000&@53
+>}+0#e000e06&| +0#0000000&@73
+@57|2|0|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_06.dump b/runtime/syntax/testdir/dumps/vim_ex_def_06.dump
deleted file mode 100644
index f073026..0000000
--- a/runtime/syntax/testdir/dumps/vim_ex_def_06.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-|e+0#af5f00255#ffffff0|n|d@1|e|f| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@58
-@75
-@75
-|"+0#0000e05&| |p|a|r|a|m|e|t|e|r|s| +0#0000000&@62
-@75
->d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&|x+0#00e0e07&|:+0#0000000&| |b+0#00e0003&|o@1|l|,+0#0000000&| |y+0#00e0e07&| +0#0000000&|=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|,+0#0000000&| |z+0#00e0e07&|:+0#0000000&| |s+0#00e0003&|t|r|i|n|g| +0#0000000&|=+0#af5f00255&| +0#0000000&|"+0#e000002&|z|e|d|"|)+0#e000e06&| +0#0000000&@31
-|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
-@75
-|d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&| +0#0000000&@66
-@4|x+0#00e0e07&|:+0#0000000&| |b+0#00e0003&|o@1|l|,+0#0000000&| @62
-@4|y+0#00e0e07&| +0#0000000&|=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|,+0#0000000&| @63
-@4|z+0#00e0e07&|:+0#0000000&| |s+0#00e0003&|t|r|i|n|g| +0#0000000&|=+0#af5f00255&| +0#0000000&|"+0#e000002&|z|e|d|"|)+0#e000e06&| +0#0000000&@52
-|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
-@75
-@75
-|"+0#0000e05&| |c|o|m@1|e|n|t|s| +0#0000000&@64
-@75
-|d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@65
-| +0#0000e05&@1|#| |V|i|m|9|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@51
-@57|1|0|9|,|1| @8|9|7|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_func_00.dump b/runtime/syntax/testdir/dumps/vim_ex_func_00.dump
deleted file mode 100644
index d89f64e..0000000
--- a/runtime/syntax/testdir/dumps/vim_ex_func_00.dump
+++ /dev/null
@@ -1,20 +0,0 @@
->"+0#0000e05#ffffff0| |Y|N|T|A|X|_|E|X|E| |l|e|t| |g|:|v|i|m|s|y|n|_|n|o|e|r@1|o|r| |=| |1| +0#0000000&@38
-@75
-|f+0#af5f00255&|u|n|c| +0#0000000&|d+0#ffffff16#ff404010|o|i|t|(+0#e000e06#ffffff0|)| +0#0000000&@63
-@75
-|e+0#af5f00255&|n|d|f|u|n|c| +0#0000000&@67
-|~+0#4040ff13&| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-| +0#0000000&@74
diff --git a/runtime/syntax/testdir/dumps/vim_ex_func_99.dump b/runtime/syntax/testdir/dumps/vim_ex_func_99.dump
deleted file mode 100644
index f4ec08f..0000000
--- a/runtime/syntax/testdir/dumps/vim_ex_func_99.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-|"+0#0000e05#ffffff0| |Y|N|T|A|X|_|E|X|E| |l|e|t| |g|:|v|i|m|s|y|n|_|n|o|e|r@1|o|r| |=| |1| +0#0000000&@38
-@75
-|f+0#af5f00255&|u|n|c| +0#0000000&|d+0#ffffff16#ff404010|o|i|t|(+0#e000e06#ffffff0|)| +0#0000000&@63
-@75
->e+0#af5f00255&|n|d|f|u|n|c| +0#0000000&@67
-|~+0#4040ff13&| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-| +0#0000000&@74
diff --git a/runtime/syntax/testdir/dumps/vim_ex_function_07.dump b/runtime/syntax/testdir/dumps/vim_ex_function_07.dump
index 40b00b0..8438849 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_function_07.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_function_07.dump
@@ -5,7 +5,7 @@
@75
>f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
@2|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|4+0#e000002&|2| +0#0000000&@63
-| +0#0000e05&@1|"| |t|r|a|i|l|i|n|g| |w|h|i|t|e|s|p|a|c|e| +0#0000000&@51
+@2|"+0#0000e05&| |t|r|a|i|l|i|n|g| |w|h|i|t|e|s|p|a|c|e| +0#0000000&@51
|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
@75
|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
diff --git a/runtime/syntax/testdir/dumps/vim_ex_function_09.dump b/runtime/syntax/testdir/dumps/vim_ex_function_09.dump
index 94f80da..4c2a626 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_function_09.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_function_09.dump
@@ -10,7 +10,7 @@
|"+0#0000e05&| |c|o|m@1|e|n|t|s| +0#0000000&@64
@75
|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
-| +0#0000e05&@1|"| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
+@2|"+0#0000e05&| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
@2|#| |4+0#e000002&|2| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@58
@2|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|4+0#e000002&|2| +0#0000000&@63
|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
diff --git a/runtime/syntax/testdir/dumps/vim_ex_function_99.dump b/runtime/syntax/testdir/dumps/vim_ex_function_99.dump
index 7eed707..b00e2ac 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_function_99.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_function_99.dump
@@ -4,7 +4,7 @@
|"+0#0000e05&| |c|o|m@1|e|n|t|s| +0#0000000&@64
@75
|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
-| +0#0000e05&@1|"| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
+@2|"+0#0000e05&| |L|e|g|a|c|y|-|s|c|r|i|p|t| |c|o|m@1|e|n|t| +0#0000000&@49
@2|#| |4+0#e000002&|2| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@58
@2|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|4+0#e000002&|2| +0#0000000&@63
|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
diff --git a/runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_00.dump b/runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_00.dump
new file mode 100644
index 0000000..245eab6
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_00.dump
@@ -0,0 +1,20 @@
+>"+0#0000e05#ffffff0| |V|i|m| |c|o|m@1|e|n|t| |s|t|r|i|n|g|s| +0#0000000&@53
+|"+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|f|a|l|s|e| +0#0000000&@19
+@75
+|"+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+| +0#0000e05&@1|#| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+| +0#0000e05&@1|#| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+| +0#0000e05&@1|#| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_99.dump b/runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_99.dump
new file mode 100644
index 0000000..8559c6c
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_no_comment_strings_99.dump
@@ -0,0 +1,20 @@
+|"+0#0000e05#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|c|o|m@1|e|n|t|_|s|t|r|i|n|g|s| |=| |v|:|f|a|l|s|e| +0#0000000&@19
+@75
+|"+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@55
+@75
+|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
+@2|"+0#0000e05&| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|B|a|r|(+0#e000e06&|)| +0#0000000&@65
+| +0#0000e05&@1|#| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
+@75
+|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|F|o@1| |{+0#e000e06&| +0#0000000&@61
+| +0#0000e05&@1|#| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+|}+0#e000e06&| +0#0000000&@73
+@75
+|a+0#af5f00255&|u|t|o|c|m|d| +0#0000000&|B+0#00e0003&|u|f|N|e|w|F|i|l|e| +0#0000000&|*| |{+0#e000e06&| +0#0000000&@52
+| +0#0000e05&@1|#| |p|r|e| |"|s|t|r|i|n|g|"| |p|o|s|t| +0#0000000&@53
+>}+0#e000e06&| +0#0000000&@73
+@57|2|0|,|1| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_sleep_00.dump b/runtime/syntax/testdir/dumps/vim_ex_sleep_00.dump
new file mode 100644
index 0000000..002b9ff
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_sleep_00.dump
@@ -0,0 +1,20 @@
+>"+0#0000e05#ffffff0| |V|i|m| |:|s|l|e@1|p| |c|o|m@1|a|n|d| +0#0000000&@54
+@75
+|s+0#af5f00255&|l|e@1|p| +0#0000000&@7|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |o|n|e| |s|e|c|o|n|d| +0#0000000&@39
+|5+0#e000002&| +0#0000000&|s+0#af5f00255&|l|e@1|p| +0#0000000&@5|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |f|i|v|e| |s|e|c|o|n|d|s| +0#0000000&@37
+|s+0#af5f00255&|l|e@1|p| +0#0000000&|1+0#e000002&|0@1|m| +0#0000000&@2|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+|1+0#e000002&|0@1| +0#0000000&|s+0#af5f00255&|l|e@1|p| +0#0000000&|m+0#e000002&| +0#0000000&@1|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+@75
+|s+0#af5f00255&|l|e@1|p|!| +0#0000000&@6|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |o|n|e| |s|e|c|o|n|d| +0#0000000&@39
+|5+0#e000002&| +0#0000000&|s+0#af5f00255&|l|e@1|p|!| +0#0000000&@4|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |f|i|v|e| |s|e|c|o|n|d|s| +0#0000000&@37
+|s+0#af5f00255&|l|e@1|p|!| +0#0000000&|1+0#e000002&|0@1|m| +0#0000000&@1|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+|1+0#e000002&|0@1| +0#0000000&|s+0#af5f00255&|l|e@1|p|!| +0#0000000&|m+0#e000002&| +0#0000000&|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_sleep_99.dump b/runtime/syntax/testdir/dumps/vim_ex_sleep_99.dump
new file mode 100644
index 0000000..4fc3d5e
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_sleep_99.dump
@@ -0,0 +1,20 @@
+|"+0#0000e05#ffffff0| |V|i|m| |:|s|l|e@1|p| |c|o|m@1|a|n|d| +0#0000000&@54
+@75
+|s+0#af5f00255&|l|e@1|p| +0#0000000&@7|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |o|n|e| |s|e|c|o|n|d| +0#0000000&@39
+|5+0#e000002&| +0#0000000&|s+0#af5f00255&|l|e@1|p| +0#0000000&@5|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |f|i|v|e| |s|e|c|o|n|d|s| +0#0000000&@37
+|s+0#af5f00255&|l|e@1|p| +0#0000000&|1+0#e000002&|0@1|m| +0#0000000&@2|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+|1+0#e000002&|0@1| +0#0000000&|s+0#af5f00255&|l|e@1|p| +0#0000000&|m+0#e000002&| +0#0000000&@1|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+@75
+|s+0#af5f00255&|l|e@1|p|!| +0#0000000&@6|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |o|n|e| |s|e|c|o|n|d| +0#0000000&@39
+|5+0#e000002&| +0#0000000&|s+0#af5f00255&|l|e@1|p|!| +0#0000000&@4|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |f|i|v|e| |s|e|c|o|n|d|s| +0#0000000&@37
+|s+0#af5f00255&|l|e@1|p|!| +0#0000000&|1+0#e000002&|0@1|m| +0#0000000&@1|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+>1+0#e000002&|0@1| +0#0000000&|s+0#af5f00255&|l|e@1|p|!| +0#0000000&|m+0#e000002&| +0#0000000&|"+0#0000e05&| |s|l|e@1|p| |f|o|r| |1|0@1| |m|i|l@1|i|s|e|c|o|n|d|s| +0#0000000&@33
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1@1|,|1| @9|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump
index 806101c..a9624de 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump
@@ -17,4 +17,4 @@
|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
| +0#af5f00255&@1|s|u|b|s|t|i|t|u|t|e|/+0#e000e06&|f+0#0000000&|o@1|/+0#e000e06&|b+0#0000000&|a|r|/+0#e000e06&| +0#0000000&@53
@2|l+0#af5f00255&|e|t| +0#0000000&|b+0#00e0e07&|a|r| +0#0000000&|=+0#af5f00255&| +0#0000000&|s|t|r|-+0#af5f00255&|>|s+0#00e0e07&|u|b|s|t|i|t|u|t|e|(+0#e000e06&|s+0#00e0e07&|t|r|,+0#0000000&| |p+0#00e0e07&|a|t|,+0#0000000&| |s+0#00e0e07&|u|b|,+0#0000000&| |f+0#00e0e07&|l|a|g|s|)+0#e000e06&| +0#0000000&@25
-@57|1|9|,|1| @9|1|9|%|
+@57|1|9|,|1| @9|1|0|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump
index b0e722d..fed54f9 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump
@@ -17,4 +17,4 @@
|s+0#af5f00255&|'+0#e000e06&|/+0#0000000&|'+0#e000e06&|/+0#0000000&@1|'+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
|"+0#0000e05&| |F+0#0000001#ffff4012|I|X|M|E| +0#0000e05#ffffff0|-| |m|a|t|c|h|e|s| |v|i|m|U|s|e|r|F|u|n|c| +0#0000000&@45
|"+0#0000e05&| |s|(|/|(|/@1|(| |"| |c|o|m@1|e|n|t| +0#0000000&@55
-@57|3|7|,|3| @9|4|6|%|
+@57|3|7|,|3| @9|2|4|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump
index cb12bb3..68aac6b 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump
@@ -17,4 +17,4 @@
|"+0#0000e05&| |s|\|/|\|/@1|\| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@42
|s+0#af5f00255&|]+0#e000e06&|/+0#0000000&|]+0#e000e06&|/+0#0000000&@1|]+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
|s+0#af5f00255&|^+0#e000e06&|/+0#0000000&|^+0#e000e06&|/+0#0000000&@1|^+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-@57|5@1|,|1| @9|7|3|%|
+@57|5@1|,|1| @9|3|9|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump
index b378260..8d95e9b 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump
@@ -6,15 +6,15 @@
>s+0#af5f00255&|}+0#e000e06&|/+0#0000000&|}+0#e000e06&|/+0#0000000&@1|}+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
|s+0#af5f00255&|~+0#e000e06&|/+0#0000000&|~+0#e000e06&|/+0#0000000&@1|~+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
@75
-@75
-|"+0#0000e05&| |I|s@1|u|e| |#|1|3|8@1|3| +0#0000000&@60
-@75
-|s|t|r|[|s|]| @68
-|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@68
-@75
-|d+0#af5f00255&|e|f| +0#0000000&|T|e|s|t|(+0#e000e06&|)| +0#0000000&@64
-@2|s|t|r|[|s|]| @66
-@2|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@66
-|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
-@75
-@57|7|3|,|1| @9|B|o|t|
+|s+0#af5f00255&| +0#0000000&|!+0#e000e06&|/+0#0000000&|!+0#e000e06&|/+0#0000000&@1|!+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |s| |"+0#e000002&|/|"|/+0#0000e05&@1|"| |"| |c|o|m@1|e|n|t| |(|w|o|r|k|s| |b|u|t| |d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@31
+|s+0#af5f00255&| +0#0000000&|#+0#e000e06&|/+0#0000000&|#+0#e000e06&|/+0#0000000&@1|#+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|$+0#e000e06&|/+0#0000000&|$+0#e000e06&|/+0#0000000&@1|$+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|%+0#e000e06&|/+0#0000000&|%+0#e000e06&|/+0#0000000&@1|%+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|&+0#e000e06&|/+0#0000000&|&+0#e000e06&|/+0#0000000&@1|&+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|'+0#e000e06&|/+0#0000000&|'+0#e000e06&|/+0#0000000&@1|'+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |F+0#0000001#ffff4012|I|X|M|E| +0#0000e05#ffffff0|-| |m|a|t|c|h|e|s| |v|i|m|U|s|e|r|F|u|n|c| +0#0000000&@45
+|"+0#0000e05&| |s| |(|/|(|/@1|(| |"| |c|o|m@1|e|n|t| +0#0000000&@54
+|s+0#af5f00255&| +0#0000000&|)+0#e000e06&|/+0#0000000&|)+0#e000e06&|/+0#0000000&@1|)+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|*+0#e000e06&|/+0#0000000&|*+0#e000e06&|/+0#0000000&@1|*+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+@57|7|3|,|1| @9|5|3|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_05.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_05.dump
new file mode 100644
index 0000000..58cc3c8
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_05.dump
@@ -0,0 +1,20 @@
+|s+0#af5f00255#ffffff0| +0#0000000&|*+0#e000e06&|/+0#0000000&|*+0#e000e06&|/+0#0000000&@1|*+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|++0#e000e06&|/+0#0000000&|++0#e000e06&|/+0#0000000&@1|++0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|,+0#e000e06&|/+0#0000000&|,+0#e000e06&|/+0#0000000&@1|,+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|-+0#e000e06&|/+0#0000000&|-+0#e000e06&|/+0#0000000&@1|-+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|.+0#e000e06&|/+0#0000000&|.+0#e000e06&|/+0#0000000&@1|.+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+>s+0#af5f00255&| +0#0000000&|/+0#e000e06&|X+0#0000000&|/+0#e000e06&|X+0#0000000&@1|/+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|:+0#e000e06&|/+0#0000000&|:+0#e000e06&|/+0#0000000&@1|:+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|;+0#e000e06&|/+0#0000000&|;+0#e000e06&|/+0#0000000&@1|;+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|<+0#e000e06&|/+0#0000000&|<+0#e000e06&|/+0#0000000&@1|<+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|=+0#e000e06&|/+0#0000000&|=+0#e000e06&|/+0#0000000&@1|=+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|>+0#e000e06&|/+0#0000000&|>+0#e000e06&|/+0#0000000&@1|>+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|?+0#e000e06&|/+0#0000000&|?+0#e000e06&|/+0#0000000&@1|?+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|@+0#e000e06&|/+0#0000000&|@+0#e000e06&|/+0#0000000&@1|@+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|[+0#e000e06&|/+0#0000000&|[+0#e000e06&|/+0#0000000&@1|[+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |s| |\|/|\|/@1|\| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@41
+|s+0#af5f00255&| +0#0000000&|]+0#e000e06&|/+0#0000000&|]+0#e000e06&|/+0#0000000&@1|]+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|^+0#e000e06&|/+0#0000000&|^+0#e000e06&|/+0#0000000&@1|^+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|_+0#e000e06&|/+0#0000000&|_+0#e000e06&|/+0#0000000&@1|_+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|`+0#e000e06&|/+0#0000000&|`+0#e000e06&|/+0#0000000&@1|`+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+@57|9|1|,|1| @9|6|8|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_06.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_06.dump
new file mode 100644
index 0000000..e4f5474
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_06.dump
@@ -0,0 +1,20 @@
+|s+0#af5f00255#ffffff0| +0#0000000&|`+0#e000e06&|/+0#0000000&|`+0#e000e06&|/+0#0000000&@1|`+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|{+0#e000e06&|/+0#0000000&|{+0#e000e06&|/+0#0000000&@1|{+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |s| |||/|||/@1||| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@41
+|s+0#af5f00255&| +0#0000000&|}+0#e000e06&|/+0#0000000&|}+0#e000e06&|/+0#0000000&@1|}+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|~+0#e000e06&|/+0#0000000&|~+0#e000e06&|/+0#0000000&@1|~+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+> @74
+|s+0#af5f00255&|/+0#e000e06&@1|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@62
+|s+0#af5f00255&| +0#0000000&|/+0#e000e06&@1|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@61
+@75
+@75
+|"+0#0000e05&| |V|i| |c|o|m|p|a|t|i|b|i|l|i|t|y| +0#0000000&@56
+@75
+|s+0#af5f00255&|\+0#e000e06&|/|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@62
+|s+0#af5f00255&|\+0#e000e06&|?|{+0#0000000&|s|t|r|i|n|g|}|?+0#e000e06&| +0#0000000&@62
+|s+0#af5f00255&|\+0#e000e06&|&|{+0#0000000&|s|t|r|i|n|g|}|&+0#e000e06&| +0#0000000&@62
+@75
+|s+0#af5f00255&| +0#0000000&|\+0#e000e06&|/|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@61
+|s+0#af5f00255&| +0#0000000&|\+0#e000e06&|?|{+0#0000000&|s|t|r|i|n|g|}|?+0#e000e06&| +0#0000000&@61
+|s+0#af5f00255&| +0#0000000&|\+0#e000e06&|&|{+0#0000000&|s|t|r|i|n|g|}|&+0#e000e06&| +0#0000000&@61
+@57|1|0|9|,|0|-|1| @6|8|2|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_07.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_07.dump
new file mode 100644
index 0000000..29caf89
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_07.dump
@@ -0,0 +1,20 @@
+|s+0#af5f00255#ffffff0| +0#0000000&|\+0#e000e06&|&|{+0#0000000&|s|t|r|i|n|g|}|&+0#e000e06&| +0#0000000&@61
+@75
+@75
+|"+0#0000e05&| |T|r|a|i|l|i|n|g| |c|o|m@1|e|n|t| |a|n|d| |b|a|r| +0#0000000&@48
+@75
+>"+0#0000e05&| +0#0000000&|F+0#0000001#ffff4012|I|X|M|E|:+0#e000e06#ffffff0| +0#0000e05&|t|r|a|i|l|i|n|g| |c|o|m@1|e|n|t|,| |n|o| |w|h|i|t|e|s|p|a|c|e| +0#0000000&@34
+|s+0#af5f00255&|"+0#0000000&| |c|o|m@1|e|n|t| @64
+|s+0#af5f00255&||+0#0000000&| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@61
+@75
+|s+0#af5f00255&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@63
+|s+0#af5f00255&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@60
+@75
+@75
+|"+0#0000e05&| |I|s@1|u|e| |#|1|3|8@1|3| +0#0000000&@60
+@75
+|s|t|r|[|s|]| @68
+|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@68
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|T|e|s|t|(+0#e000e06&|)| +0#0000000&@64
+@57|1|2|7|,|1| @8|9|6|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump b/runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump
index 88cb7dc..6864a4a 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump
@@ -1,10 +1,10 @@
-|s+0#af5f00255#ffffff0|^+0#e000e06&|/+0#0000000&|^+0#e000e06&|/+0#0000000&@1|^+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|_+0#e000e06&|/+0#0000000&|_+0#e000e06&|/+0#0000000&@1|_+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|`+0#e000e06&|/+0#0000000&|`+0#e000e06&|/+0#0000000&@1|`+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|{+0#e000e06&|/+0#0000000&|{+0#e000e06&|/+0#0000000&@1|{+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|"+0#0000e05&| |s|||/|||/@1||| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@42
-|s+0#af5f00255&|}+0#e000e06&|/+0#0000000&|}+0#e000e06&|/+0#0000000&@1|}+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|~+0#e000e06&|/+0#0000000&|~+0#e000e06&|/+0#0000000&@1|~+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
+| +0&#ffffff0@74
+|"+0#0000e05&| +0#0000000&|F+0#0000001#ffff4012|I|X|M|E|:+0#e000e06#ffffff0| +0#0000e05&|t|r|a|i|l|i|n|g| |c|o|m@1|e|n|t|,| |n|o| |w|h|i|t|e|s|p|a|c|e| +0#0000000&@34
+|s+0#af5f00255&|"+0#0000000&| |c|o|m@1|e|n|t| @64
+|s+0#af5f00255&||+0#0000000&| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@61
+@75
+|s+0#af5f00255&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@63
+|s+0#af5f00255&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@60
@75
@75
|"+0#0000e05&| |I|s@1|u|e| |#|1|3|8@1|3| +0#0000000&@60
@@ -17,4 +17,4 @@
@2|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@66
|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
> @74
-@57|8|6|,|0|-|1| @7|B|o|t|
+@57|1|4@1|,|0|-|1| @6|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump
index ade5bd5..5240e4e 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump
@@ -12,9 +12,9 @@
|"+0#0000e05&| @2|"+0#e000002&|c|l|u|s|t|e|r|"| +0#0000e05&|s|h|o|u|l|d| |n|o|t| |b|e| |h|i|g|h|l|i|g|h|t|e|d| |o|u|t|s|i|d|e| |o|f| |:|s|y|n|t|a|x| |c|o|m@1|a|n|d|s| +0#0000000&@7
@75
|f+0#af5f00255&|u|n|c|t|i|o|n|!| +0#0000000&|s+0#e000e06&|:|C+0#0000000&|o|n|t|a|i|n|e|d|G|r|o|u|p|(+0#e000e06&|)| +0#0000000&@46
-| +0#0000e05&@1|"| |.@2| +0#0000000&@67
+@2|"+0#0000e05&| |.@2| +0#0000000&@67
@2|f+0#af5f00255&|o|r| +0#0000000&|c+0#00e0e07&|l|u|s|t|e|r| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|[|'+0#e000002&|m|a|r|k|d|o|w|n|H|i|g|h|l|i|g|h|t|_|z|s|h|'|,+0#0000000&| |'+0#e000002&|z|s|h|'|]+0#0000000&| @25
-| +0#0000e05&@3|"| |.@2| +0#0000000&@65
+@4|"+0#0000e05&| |.@2| +0#0000000&@65
@2|e+0#af5f00255&|n|d|f|o|r| +0#0000000&@66
-| +0#0000e05&@1|"| |.@2| +0#0000000&@67
+@2|"+0#0000e05&| |.@2| +0#0000000&@67
@57|1|6|3|,|7| @8|9@1|%|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_99.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_99.dump
index c1942c8..c06ac66 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_syntax_99.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_99.dump
@@ -11,10 +11,10 @@
|"+0#0000e05&| @2|"+0#e000002&|c|l|u|s|t|e|r|"| +0#0000e05&|s|h|o|u|l|d| |n|o|t| |b|e| |h|i|g|h|l|i|g|h|t|e|d| |o|u|t|s|i|d|e| |o|f| |:|s|y|n|t|a|x| |c|o|m@1|a|n|d|s| +0#0000000&@7
@75
|f+0#af5f00255&|u|n|c|t|i|o|n|!| +0#0000000&|s+0#e000e06&|:|C+0#0000000&|o|n|t|a|i|n|e|d|G|r|o|u|p|(+0#e000e06&|)| +0#0000000&@46
-| +0#0000e05&@1|"| |.@2| +0#0000000&@67
+@2|"+0#0000e05&| |.@2| +0#0000000&@67
@2|f+0#af5f00255&|o|r| +0#0000000&|c+0#00e0e07&|l|u|s|t|e|r| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|[|'+0#e000002&|m|a|r|k|d|o|w|n|H|i|g|h|l|i|g|h|t|_|z|s|h|'|,+0#0000000&| |'+0#e000002&|z|s|h|'|]+0#0000000&| @25
-| +0#0000e05&@3|"| |.@2| +0#0000000&@65
+@4|"+0#0000e05&| |.@2| +0#0000000&@65
@2|e+0#af5f00255&|n|d|f|o|r| +0#0000000&@66
-| +0#0000e05&@1|"| |.@2| +0#0000000&@67
+@2|"+0#0000e05&| |.@2| +0#0000000&@67
>e+0#af5f00255&|n|d|f|u|n|c|t|i|o|n| +0#0000000&@63
@57|1|7@1|,|1| @8|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_throw_00.dump b/runtime/syntax/testdir/dumps/vim_ex_throw_00.dump
new file mode 100644
index 0000000..c4089e8
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_throw_00.dump
@@ -0,0 +1,20 @@
+>"+0#0000e05#ffffff0| |V|i|m| |:|t|h|r|o|w| |c|o|m@1|a|n|d| +0#0000000&@54
+@75
+|"+0#0000e05&| |:|h|e|l|p| |:|t|h|r|o|w| +0#0000000&@60
+@75
+|t+0#af5f00255&|r|y| +0#0000000&||| |t+0#af5f00255&|h|r|o|w| +0#0000000&|"+0#e000002&|o@1|p|s|"| +0#0000000&||| |c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|o@1|/+0#e000e06&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|c|a|u|g|h|t|"| +0#0000000&||| |e+0#af5f00255&|n|d|t|r|y| +0#0000000&@17
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_ex_throw_99.dump b/runtime/syntax/testdir/dumps/vim_ex_throw_99.dump
new file mode 100644
index 0000000..b53fff4
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_throw_99.dump
@@ -0,0 +1,20 @@
+|"+0#0000e05#ffffff0| |V|i|m| |:|t|h|r|o|w| |c|o|m@1|a|n|d| +0#0000000&@54
+@75
+|"+0#0000e05&| |:|h|e|l|p| |:|t|h|r|o|w| +0#0000000&@60
+@75
+>t+0#af5f00255&|r|y| +0#0000000&||| |t+0#af5f00255&|h|r|o|w| +0#0000000&|"+0#e000002&|o@1|p|s|"| +0#0000000&||| |c+0#af5f00255&|a|t|c|h| +0#0000000&|/+0#e000e06&|^+0#0000000&|o@1|/+0#e000e06&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|c|a|u|g|h|t|"| +0#0000000&||| |e+0#af5f00255&|n|d|t|r|y| +0#0000000&@17
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|5|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_keymap_99.vim b/runtime/syntax/testdir/dumps/vim_keymap_99.vim
new file mode 100644
index 0000000..546837c
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_keymap_99.vim
@@ -0,0 +1,2 @@
+" Replace known non-Latin-1 characters.
+%s+[“�]+?+ge
diff --git a/runtime/syntax/testdir/dumps/vim_line_continuation_02.dump b/runtime/syntax/testdir/dumps/vim_line_continuation_02.dump
index c4ceded..e18a56d 100644
--- a/runtime/syntax/testdir/dumps/vim_line_continuation_02.dump
+++ b/runtime/syntax/testdir/dumps/vim_line_continuation_02.dump
@@ -9,11 +9,11 @@
@6|\+0#e000e06&|}| +0#0000000&@66
@75
|l+0#af5f00255&|e|t| +0#0000000&|a+0#00e0e07&|r@1|a|y| +0#0000000&|=+0#af5f00255&| +0#0000000&|[| @61
-| +0#0000e05&@5|"|\| |e|l|e|m|e|n|t| |1| +0#0000000&@56
+@6|"+0#0000e05&|\| |e|l|e|m|e|n|t| |1| +0#0000000&@56
@6|\+0#e000e06&| +0#0000000&|1+0#e000002&|,+0#0000000&| @64
-| +0#0000e05&@5|"|\| |e|l|e|m|e|n|t| |2| +0#0000000&@56
+@6|"+0#0000e05&|\| |e|l|e|m|e|n|t| |2| +0#0000000&@56
@6|\+0#e000e06&| +0#0000000&|2+0#e000002&|,+0#0000000&| @64
-| +0#0000e05&@5|"|\| |e|l|e|m|e|n|t| |3| +0#0000000&@56
+@6|"+0#0000e05&|\| |e|l|e|m|e|n|t| |3| +0#0000000&@56
@6|\+0#e000e06&| +0#0000000&|3+0#e000002&| +0#0000000&@65
@6|\+0#e000e06&|]+0#0000000&| @66
|~+0#4040ff13&| @73
diff --git a/runtime/syntax/testdir/dumps/vim_line_continuation_99.dump b/runtime/syntax/testdir/dumps/vim_line_continuation_99.dump
index 05ea464..3e2c83d 100644
--- a/runtime/syntax/testdir/dumps/vim_line_continuation_99.dump
+++ b/runtime/syntax/testdir/dumps/vim_line_continuation_99.dump
@@ -10,11 +10,11 @@
@6|\+0#e000e06&|}| +0#0000000&@66
@75
|l+0#af5f00255&|e|t| +0#0000000&|a+0#00e0e07&|r@1|a|y| +0#0000000&|=+0#af5f00255&| +0#0000000&|[| @61
-| +0#0000e05&@5|"|\| |e|l|e|m|e|n|t| |1| +0#0000000&@56
+@6|"+0#0000e05&|\| |e|l|e|m|e|n|t| |1| +0#0000000&@56
@6|\+0#e000e06&| +0#0000000&|1+0#e000002&|,+0#0000000&| @64
-| +0#0000e05&@5|"|\| |e|l|e|m|e|n|t| |2| +0#0000000&@56
+@6|"+0#0000e05&|\| |e|l|e|m|e|n|t| |2| +0#0000000&@56
@6|\+0#e000e06&| +0#0000000&|2+0#e000002&|,+0#0000000&| @64
-| +0#0000e05&@5|"|\| |e|l|e|m|e|n|t| |3| +0#0000000&@56
+@6|"+0#0000e05&|\| |e|l|e|m|e|n|t| |3| +0#0000000&@56
@6|\+0#e000e06&| +0#0000000&|3+0#e000002&| +0#0000000&@65
@6>\+0#e000e06&|]+0#0000000&| @66
@57|4|9|,|7| @9|B|o|t|
diff --git a/runtime/syntax/testdir/dumps/vim_shebang_00.dump b/runtime/syntax/testdir/dumps/vim_shebang_00.dump
new file mode 100644
index 0000000..c79da44
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_shebang_00.dump
@@ -0,0 +1,20 @@
+>#+0#e000e06#ffffff0|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000&@53
+@75
+|"+0#0000e05&| |V|i|m| |s|h|e|b|a|n|g| |l|i|n|e| +0#0000000&@56
+@75
+|#+0#ffffff16#ff404010|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000#ffffff0@53
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_shebang_99.dump b/runtime/syntax/testdir/dumps/vim_shebang_99.dump
new file mode 100644
index 0000000..0102412
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_shebang_99.dump
@@ -0,0 +1,20 @@
+|#+0#e000e06#ffffff0|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000&@53
+@75
+|"+0#0000e05&| |V|i|m| |s|h|e|b|a|n|g| |l|i|n|e| +0#0000000&@56
+@75
+>#+0#ffffff16#ff404010|!|/|u|s|r|/|b|i|n|/|e|n|v| |v|i|m| |-|S| +0#0000000#ffffff0@53
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|5|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_00.dump b/runtime/syntax/testdir/dumps/vim_syntax_00.dump
deleted file mode 100644
index 916f96d..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_00.dump
+++ /dev/null
@@ -1,20 +0,0 @@
->"+0#0000e05#ffffff0| |V|i|m| |:|s|y|n|t|a|x| |c|o|m@1|a|n|d| +0#0000000&@53
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|m+0#00e0003&|a|t|c|h| +0#0000000&|t+0#00e0003&|e|s|t|M|a|t|c|h| +0#0000000&|"+0#e000002&|p|a|t@1|e|r|n|"| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&|"+0#0000e05&| |t|a|i|l| |c|o|m@1|e|n|t| +0#0000000&@20
-|"+0#0000e05&| +0#0000000&|N+0#e000e06&|O|T|E|:| +0#0000e05&|c|o|m@1|e|n|t|s| |n|o|t| |c|u|r@1|e|n|t|l|y| |s|u|p@1|o|r|t|e|d| +0#0000000&@34
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|K|e|y|w|o|r|d| +0#0000000&|k|e|y|w|o|r|d| |c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&|"| |t|a|i|l| |c|o|m@1|e|n|t| @18
-|s+0#af5f00255&|y|n| +0#0000000&|r+0#00e0003&|e|g|i|o|n| +0#0000000&|t+0#00e0003&|e|s|t|R|e|g|i|o|n| +0#0000000&|s+0#00e0003&|t|a|r|t|=|"+0#e000002&|s|t|a|r|t|-|p|a|t@1|e|r|n|"| +0#0000000&|s+0#00e0003&|k|i|p|=|"+0#e000002&|s|k|i|p|-|p|a|t@1|e|r|n|"| +0#0000000&|e+0#00e0003&|n|d|=|"+0#e000002&|e|n|d|-|p|a
-|t@1|e|r|n|"| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&|"| |t|a|i|l| |c|o|m@1|e|n|t| @43
-@75
-|"+0#0000e05&| |M|u|l|t|i|l|i|n|e| |c|o|m@1|a|n|d|s| +0#0000000&@54
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|K|e|y|w|o|r|d| +0#0000000&@51
-@6|"+0#0000e05&|\| |O|P|T|I|O|N|S| +0#0000000&@58
-@6|"+0#0000e05&|\| |c|o|n|c|e|a|l| |o|p|t|i|o|n| +0#0000000&@51
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|c|e|a|l| +0#0000000&@59
-@6|"+0#0000e05&|\| |c@1|h|a|r| |o|p|t|i|o|n| +0#0000000&@53
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&@1|h|a|r|=|&+0#e000002&| +0#0000000&@59
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&@57
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d|i|n| |o|p|t|i|o|n| +0#0000000&@47
-@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_01.dump b/runtime/syntax/testdir/dumps/vim_syntax_01.dump
deleted file mode 100644
index 800e4a7..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_01.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@5|"+0#0000e05&|\| |c@1|h|a|r| |o|p|t|i|o|n| +0#0000000&@53
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&@1|h|a|r|=|&+0#e000002&| +0#0000000&@59
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&@57
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d|i|n| |o|p|t|i|o|n| +0#0000000&@47
-@6>\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d|i|n|=|t+0#0000000&|e|s|t|C|o|n|t|a|i|n|e|r| @41
-@6|"+0#0000e05&|\| |n|e|x|t|g|r|o|u|p| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|n+0#e000e06&|e|x|t|g|r|o|u|p|=|t+0#0000000&|e|s|t|N|e|x|t|0|,|@|t|e|s|t|C|l|u|s|t|e|r| @34
-@6|"+0#0000e05&|\| |t|r|a|n|s|p|a|r|e|n|t| |o|p|t|i|o|n| +0#0000000&@47
-@6|\+0#e000e06&| +0#0000000&|t+0#e000e06&|r|a|n|s|p|a|r|e|n|t| +0#0000000&@55
-@6|"+0#0000e05&|\| |s|k|i|p|w|h|i|t|e| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|w|h|i|t|e| +0#0000000&@57
-@6|"+0#0000e05&|\| |s|k|i|p|e|m|p|t|y| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|e|m|p|t|y| +0#0000000&@57
-@6|"+0#0000e05&|\| |s|k|i|p|n|l| |o|p|t|i|o|n| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|n|l| +0#0000000&@60
-@6|"+0#0000e05&|\| |K|E|Y|W|O|R|D|S| |L|I|S|T| +0#0000000&@52
-@6|"+0#0000e05&|\| |k|e|y|w|o|r|d| |1| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|1| @58
-@57|1|9|,|7| @10|8|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_02.dump b/runtime/syntax/testdir/dumps/vim_syntax_02.dump
deleted file mode 100644
index 1caffc1..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_02.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@5|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|1| @58
-@6|"+0#0000e05&|\| |k|e|y|w|o|r|d| |2| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|2| @58
-@6|"+0#0000e05&|\| |k|e|y|w|o|r|d| |3| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|3| @58
-> @74
-|s+0#af5f00255&|y|n| +0#0000000&|m+0#00e0003&|a|t|c|h| +0#0000000&|t+0#00e0003&|e|s|t|M|a|t|c|h| +0#0000000&@55
-@6|"+0#0000e05&|\| |M|A|T|C|H| |P|A|T@1|E|R|N| +0#0000000&@52
-@6|"+0#0000e05&|\| |p|a|t@1|e|r|n| |s|t|a|r|t| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|/+0#e000002&| +0#0000000&@65
-| +0#e000002&@5|"+0#0000e05&|\| |p|a|r|t| |1| |d|e|s|c|r|i|p|t|i|o|n| +0#0000000&@47
-| +0#e000002&@5|\+0#e000e06&|p+0#e000002&|a|t|1|a| |.|*| |p|a|t|1|b| +0#0000000&@53
-| +0#e000002&@5|"+0#0000e05&|\| |p|a|r|t| |2| |d|e|s|c|r|i|p|t|i|o|n| +0#0000000&@47
-| +0#e000002&@5|\+0#e000e06&|p+0#e000002&|a|t|2|a| |.|*| |p|a|t|2|b| +0#0000000&@53
-| +0#e000002&@5|"+0#0000e05&|\| |p|a|r|t| |3| |d|e|s|c|r|i|p|t|i|o|n| +0#0000000&@47
-| +0#e000002&@5|\+0#e000e06&|p+0#e000002&|a|t|3|a| |.|*| |p|a|t|3|b| +0#0000000&@53
-| +0#e000002&@5|"+0#0000e05&|\| |p|a|t@1|e|r|n| |e|n|d| +0#0000000&@54
-| +0#e000002&@5|\+0#e000e06&|/+0#e000002&| +0#0000000&@66
-@6|"+0#0000e05&|\| |O|P|T|I|O|N|S| +0#0000000&@58
-@57|3|7|,|0|-|1| @7|2|1|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_03.dump b/runtime/syntax/testdir/dumps/vim_syntax_03.dump
deleted file mode 100644
index 31ab527..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_03.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@5|"+0#0000e05&|\| |O|P|T|I|O|N|S| +0#0000000&@58
-@6|"+0#0000e05&|\| |c|o|n|c|e|a|l| |o|p|t|i|o|n| +0#0000000&@51
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|c|e|a|l| +0#0000000&@59
-@6|"+0#0000e05&|\| |c@1|h|a|r| |o|p|t|i|o|n| +0#0000000&@53
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&@1|h|a|r|=|&+0#e000002&| +0#0000000&@59
-@6>"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&@57
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d|i|n| |o|p|t|i|o|n| +0#0000000&@47
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d|i|n|=|t+0#0000000&|e|s|t|C|o|n|t|a|i|n|e|r| @41
-@6|"+0#0000e05&|\| |n|e|x|t|g|r|o|u|p| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|n+0#e000e06&|e|x|t|g|r|o|u|p|=|t+0#0000000&|e|s|t|N|e|x|t|0|,|@|t|e|s|t|C|l|u|s|t|e|r| @34
-@6|"+0#0000e05&|\| |t|r|a|n|s|p|a|r|e|n|t| |o|p|t|i|o|n| +0#0000000&@47
-@6|\+0#e000e06&| +0#0000000&|t+0#e000e06&|r|a|n|s|p|a|r|e|n|t| +0#0000000&@55
-@6|"+0#0000e05&|\| |s|k|i|p|w|h|i|t|e| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|w|h|i|t|e| +0#0000000&@57
-@6|"+0#0000e05&|\| |s|k|i|p|e|m|p|t|y| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|e|m|p|t|y| +0#0000000&@57
-@6|"+0#0000e05&|\| |s|k|i|p|n|l| |o|p|t|i|o|n| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|n|l| +0#0000000&@60
-@57|5@1|,|7| @9|3@1|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_04.dump b/runtime/syntax/testdir/dumps/vim_syntax_04.dump
deleted file mode 100644
index d5d9f40..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_04.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@5|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|n|l| +0#0000000&@60
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|s| |o|p|t|i|o|n| +0#0000000&@50
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|s|=|t+0#0000000&|e|s|t|C|o|n|t|a|i|n|e|d|1|,|t|e|s|t|C|o|n|t|a|i|n|e|d|2| @28
-@6|"+0#0000e05&|\| |f|o|l|d| |o|p|t|i|o|n| +0#0000000&@54
-@6|\+0#e000e06&| +0#0000000&|f+0#e000e06&|o|l|d| +0#0000000&@62
-@6>"+0#0000e05&|\| |d|i|s|p|l|a|y| |o|p|t|i|o|n| +0#0000000&@51
-@6|\+0#e000e06&| +0#0000000&|d+0#e000e06&|i|s|p|l|a|y| +0#0000000&@59
-@6|"+0#0000e05&|\| |e|x|t|e|n|d| |o|p|t|i|o|n| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|e+0#e000e06&|x|t|e|n|d| +0#0000000&@60
-@6|"+0#0000e05&|\| |e|x|c|l|u|d|e|n|l| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|e+0#e000e06&|x|c|l|u|d|e|n|l| +0#0000000&@57
-@6|"+0#0000e05&|\| |k|e@1|p|e|n|d| |o|p|t|i|o|n| +0#0000000&@51
-@6|\+0#e000e06&| +0#0000000&|k+0#e000e06&|e@1|p|e|n|d| +0#0000000&@59
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|r+0#00e0003&|e|g|i|o|n| +0#0000000&|t+0#00e0003&|e|s|t|R|e|g|i|o|n| +0#0000000&@53
-@6|"+0#0000e05&|\| |O|P|T|I|O|N|S| +0#0000000&@58
-@6|"+0#0000e05&|\| |s|t|a|r|t| |o|p|t|i|o|n| +0#0000000&@53
-@6|\+0#e000e06&| +0#0000000&|s+0#00e0003&|t|a|r|t|=|"+0#e000002&|s|t|a|r|t|-|p|a|t@1|e|r|n|"| +0#0000000&@45
-@6|"+0#0000e05&|\| |s|k|i|p| |o|p|t|i|o|n| +0#0000000&@54
-@57|7|3|,|7| @9|4|6|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_05.dump b/runtime/syntax/testdir/dumps/vim_syntax_05.dump
deleted file mode 100644
index 47d60c2..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_05.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@5|"+0#0000e05&|\| |s|k|i|p| |o|p|t|i|o|n| +0#0000000&@54
-@6|\+0#e000e06&| +0#0000000&|s+0#00e0003&|k|i|p|=|"+0#e000002&|s|k|i|p|-|p|a|t@1|e|r|n|"| +0#0000000&@47
-@6|"+0#0000e05&|\| |e|n|d| |o|p|t|i|o|n| +0#0000000&@55
-@6|\+0#e000e06&| +0#0000000&|e+0#00e0003&|n|d|=|"+0#e000002&|e|n|d|-|p|a|t@1|e|r|n|"| +0#0000000&@49
-@6|"+0#0000e05&|\| |c|o|n|c|e|a|l| |o|p|t|i|o|n| +0#0000000&@51
-@6>\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|c|e|a|l| +0#0000000&@59
-@6|"+0#0000e05&|\| |c@1|h|a|r| |o|p|t|i|o|n| +0#0000000&@53
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&@1|h|a|r|=|&+0#e000002&| +0#0000000&@59
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&@57
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d|i|n| |o|p|t|i|o|n| +0#0000000&@47
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d|i|n|=|t+0#0000000&|e|s|t|C|o|n|t|a|i|n|e|r| @41
-@6|"+0#0000e05&|\| |n|e|x|t|g|r|o|u|p| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|n+0#e000e06&|e|x|t|g|r|o|u|p|=|t+0#0000000&|e|s|t|N|e|x|t|0|,|@|t|e|s|t|C|l|u|s|t|e|r| @34
-@6|"+0#0000e05&|\| |t|r|a|n|s|p|a|r|e|n|t| |o|p|t|i|o|n| +0#0000000&@47
-@6|\+0#e000e06&| +0#0000000&|t+0#e000e06&|r|a|n|s|p|a|r|e|n|t| +0#0000000&@55
-@6|"+0#0000e05&|\| |s|k|i|p|w|h|i|t|e| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|w|h|i|t|e| +0#0000000&@57
-@6|"+0#0000e05&|\| |s|k|i|p|e|m|p|t|y| |o|p|t|i|o|n| +0#0000000&@49
-@57|9|1|,|7| @9|5|8|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_06.dump b/runtime/syntax/testdir/dumps/vim_syntax_06.dump
deleted file mode 100644
index db1872c..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_06.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@5|"+0#0000e05&|\| |s|k|i|p|e|m|p|t|y| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|e|m|p|t|y| +0#0000000&@57
-@6|"+0#0000e05&|\| |s|k|i|p|n|l| |o|p|t|i|o|n| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|n|l| +0#0000000&@60
-@6|"+0#0000e05&|\| |c|o|n|t|a|i|n|s| |o|p|t|i|o|n| +0#0000000&@50
-@6>\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|s|=|t+0#0000000&|e|s|t|C|o|n|t|a|i|n|e|d|1|,|t|e|s|t|C|o|n|t|a|i|n|e|d|2| @28
-@6|"+0#0000e05&|\| |o|n|e|l|i|n|e| |o|p|t|i|o|n| +0#0000000&@51
-@6|\+0#e000e06&| +0#0000000&|o+0#e000e06&|n|e|l|i|n|e| +0#0000000&@59
-@6|"+0#0000e05&|\| |f|o|l|d| |o|p|t|i|o|n| +0#0000000&@54
-@6|\+0#e000e06&| +0#0000000&|f+0#e000e06&|o|l|d| +0#0000000&@62
-@6|"+0#0000e05&|\| |d|i|s|p|l|a|y| |o|p|t|i|o|n| +0#0000000&@51
-@6|\+0#e000e06&| +0#0000000&|d+0#e000e06&|i|s|p|l|a|y| +0#0000000&@59
-@6|"+0#0000e05&|\| |e|x|t|e|n|d| |o|p|t|i|o|n| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|e+0#e000e06&|x|t|e|n|d| +0#0000000&@60
-@6|"+0#0000e05&|\| |c|o|n|c|e|a|l|e|n|d|s| |o|p|t|i|o|n| +0#0000000&@47
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|c|e|a|l|e|n|d|s| +0#0000000&@55
-@6|"+0#0000e05&|\| |e|x|c|l|u|d|e|n|l| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|e+0#e000e06&|x|c|l|u|d|e|n|l| +0#0000000&@57
-@6|"+0#0000e05&|\| |k|e@1|p|e|n|d| |o|p|t|i|o|n| +0#0000000&@51
-@57|1|0|9|,|7| @8|7|1|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_07.dump b/runtime/syntax/testdir/dumps/vim_syntax_07.dump
deleted file mode 100644
index eb36317..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_07.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-| +0&#ffffff0@5|"+0#0000e05&|\| |k|e@1|p|e|n|d| |o|p|t|i|o|n| +0#0000000&@51
-@6|\+0#e000e06&| +0#0000000&|k+0#e000e06&|e@1|p|e|n|d| +0#0000000&@59
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|c+0#00e0003&|l|u|s|t|e|r| +0#0000000&|t+0#00e0003&|e|s|t|C|l|u|s|t|e|r| +0#0000000&@51
-@6|"+0#0000e05&|\| |O|P|T|I|O|N|S| +0#0000000&@58
-@6>"+0#0000e05&|\| |c|o|n|t|a|i|n|s| |o|p|t|i|o|n| +0#0000000&@50
-@6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|s|=|t+0#0000000&|e|s|t|C|o|n|t|a|i|n|e|d|1|,|t|e|s|t|C|o|n|t|a|i|n|e|d|2|,|t|e|s|t|C|o|n|t|a|i|n|e|d|3| @13
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|c+0#00e0003&|l|u|s|t|e|r| +0#0000000&|t+0#00e0003&|e|s|t|C|l|u|s|t|e|r| +0#0000000&@51
-@6|"+0#0000e05&|\| |O|P|T|I|O|N|S| +0#0000000&@58
-@6|"+0#0000e05&|\| |a|d@1| |o|p|t|i|o|n| +0#0000000&@55
-@6|\+0#e000e06&| +0#0000000&|a+0#e000e06&|d@1|=|t+0#0000000&|e|s|t|A|d@1| @55
-@6|"+0#0000e05&|\| |r|e|m|o|v|e| |o|p|t|i|o|n| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|r+0#e000e06&|e|m|o|v|e|=|t+0#0000000&|e|s|t|R|e|m|o|v|e| @49
-@75
-@75
-|"+0#0000e05&| |m|u|l|t|i|l|i|n|e| |g|r|o|u|p| |l|i|s|t| +0#0000000&@52
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|0| +0#0000000&|k|e|y|w|o|r|d| @45
-@57|1|2|7|,|7| @8|8|3|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_08.dump b/runtime/syntax/testdir/dumps/vim_syntax_08.dump
deleted file mode 100644
index 3906e55..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_08.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-|s+0#af5f00255#ffffff0|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|0| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|1| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|2| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|3| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|4| +0#0000000&|k|e|y|w|o|r|d| @45
->s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|5| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|6| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|7| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|8| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|9| +0#0000000&|k|e|y|w|o|r|d| @45
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|K|e|y|w|o|r|d| +0#0000000&@51
-@6|"+0#0000e05&|\| |n|e|x|t|g|r|o|u|p| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|n+0#e000e06&|e|x|t|g|r|o|u|p|=| +0#0000000&@56
-@6|"+0#0000e05&|\| |a| |c|o|m@1|e|n|t| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|t|e|s|t|N|e|x|t|0| |,| |t|e|s|t|N|e|x|t|1| |,| @43
-@6|"+0#0000e05&|\| |a| |c|o|m@1|e|n|t| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|t|e|s|t|N|e|x|t|[|2|-|8|]|.|*| |,| @49
-@6|"+0#0000e05&|\| |a| |c|o|m@1|e|n|t| +0#0000000&@56
-@57|1|4|5|,|1| @8|9|5|%|
diff --git a/runtime/syntax/testdir/dumps/vim_syntax_99.dump b/runtime/syntax/testdir/dumps/vim_syntax_99.dump
deleted file mode 100644
index 4ca16c6..0000000
--- a/runtime/syntax/testdir/dumps/vim_syntax_99.dump
+++ /dev/null
@@ -1,20 +0,0 @@
-|s+0#af5f00255#ffffff0|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|6| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|7| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|8| +0#0000000&|k|e|y|w|o|r|d| @45
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|N|e|x|t|9| +0#0000000&|k|e|y|w|o|r|d| @45
-@75
-|s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t+0#00e0003&|e|s|t|K|e|y|w|o|r|d| +0#0000000&@51
-@6|"+0#0000e05&|\| |n|e|x|t|g|r|o|u|p| |o|p|t|i|o|n| +0#0000000&@49
-@6|\+0#e000e06&| +0#0000000&|n+0#e000e06&|e|x|t|g|r|o|u|p|=| +0#0000000&@56
-@6|"+0#0000e05&|\| |a| |c|o|m@1|e|n|t| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|t|e|s|t|N|e|x|t|0| |,| |t|e|s|t|N|e|x|t|1| |,| @43
-@6|"+0#0000e05&|\| |a| |c|o|m@1|e|n|t| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|t|e|s|t|N|e|x|t|[|2|-|8|]|.|*| |,| @49
-@6|"+0#0000e05&|\| |a| |c|o|m@1|e|n|t| +0#0000000&@56
-@6|\+0#e000e06&| +0#0000000&|t|e|s|t|N|e|x|t|9| |,| |@|t|e|s|t|C|l|u|s|t|e|r| |s+0#e000e06&|k|i|p|w|h|i|t|e| +0#0000000&@32
-@6|"+0#0000e05&|\| |K|E|Y|W|O|R|D|S| |L|I|S|T| +0#0000000&@52
-@6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|4| @58
-@6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|5| @58
-@6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|6| @58
-> @74
-@57|1|6|4|,|0|-|1| @6|B|o|t|
diff --git a/runtime/syntax/testdir/input/html.html b/runtime/syntax/testdir/input/html.html
new file mode 100644
index 0000000..a4d0eb5
--- /dev/null
+++ b/runtime/syntax/testdir/input/html.html
@@ -0,0 +1,153 @@
+<!--
+ HTML Syntax Test File
+ Maintainer: Doug Kearns <dougkearns@gmail.com>
+ Last Change: 2024 Jun 13
+ VIM_TEST_SETUP let g:html_no_rendering = 1
+
+ TODO: Investigate macOS test failures when comparing italicized text with,
+ for example, <em> and <i> elements. FreeBSD fails with an empty <strike>
+ element. See #13591 and #14215.
+-->
+
+<!-- HTML Elements -->
+<a></a>
+<abbr></abbr>
+<address></address>
+<area>
+<article></article>
+<aside></aside>
+<audio></audio>
+<b>bring attention to</b>
+<base>
+<bdi></bdi>
+<bdo></bdo>
+<blockquote></blockquote>
+<body></body>
+<br>
+<button></button>
+<canvas></canvas>
+<caption></caption>
+<cite></cite>
+<code></code>
+<col>
+<colgroup></colgroup>
+<data></data>
+<datalist></datalist>
+<dd></dd>
+<del>deleted text</del>
+<details></details>
+<dfn></dfn>
+<dialog></dialog>
+<div></div>
+<dl></dl>
+<dt></dt>
+<em>emphasis</em>
+<embed>
+<fieldset></fieldset>
+<figcaption></figcaption>
+<figure></figure>
+<footer></footer>
+<form></form>
+<h1>Heading Level 1</h1>
+<h2>Heading Level 3</h2>
+<h3>Heading Level 4</h3>
+<h4>Heading Level 4</h4>
+<h5>Heading Level 5</h5>
+<h6>Heading Level 6</h6>
+<head></head>
+<header></header>
+<hgroup></hgroup>
+<hr>
+<html></html>
+<i>idiomatic text</i>
+<iframe></iframe>
+<img>
+<input>
+<ins></ins>
+<kbd></kbd>
+<label></label>
+<legend></legend>
+<li></li>
+<link>
+<main></main>
+<map></map>
+<mark></mark>
+<menu></menu>
+<meta>
+<meter></meter>
+<nav></nav>
+<noscript></noscript>
+<object></object>
+<ol></ol>
+<optgroup></optgroup>
+<option></option>
+<output></output>
+<p></p>
+<picture></picture>
+<pre>preformatted text</pre>
+<progress></progress>
+<q></q>
+<rp></rp>
+<rt></rt>
+<ruby></ruby>
+<!-- FreeBSD failure
+<s>strikethrough</s>
+-->
+<samp></samp>
+<script></script>
+<search></search>
+<section></section>
+<select></select>
+<slot></slot>
+<small></small>
+<source>
+<span></span>
+<strong>strong importance</strong>
+<style></style>
+<sub></sub>
+<summary></summary>
+<sup></sup>
+<table></table>
+<tbody></tbody>
+<td></td>
+<template></template>
+<textarea></textarea>
+<tfoot></tfoot>
+<th></th>
+<thead></thead>
+<time></time>
+<title></title>
+<tr></tr>
+<track>
+<u>unarticulated annotation</u>
+<ul></ul>
+<var></var>
+<video></video>
+<wbr>
+<xmp></xmp>
+
+<!-- Deprecated Elements -->
+<acronym></acronym>
+<big></big>
+<center></center>
+<dir></dir>
+<font></font>
+<frame></frame>
+<frameset></frameset>
+<marquee></marquee>
+<menuitem></menuitem>
+<nobr></nobr>
+<noframes></noframes>
+<param>
+<rb></rb>
+<rtc></rtc>
+<strike>strikethrough</strike>
+<tt></tt>
+
+<!-- Experimental - not highlighted -->
+<portal></portal>
+
+<!-- Note: these deprecated elements have never been matched -->
+<image>
+<noembed>
+<plaintext>
diff --git a/runtime/syntax/testdir/input/html_html b/runtime/syntax/testdir/input/html_html
deleted file mode 100644
index bfeca26..0000000
--- a/runtime/syntax/testdir/input/html_html
+++ /dev/null
@@ -1,146 +0,0 @@
-<!--
- HTML Syntax Test File
- Maintainer: Doug Kearns <dougkearns@gmail.com>
- Last Change: 2023 Nov 28
--->
-
-<!-- HTML Elements -->
-<a>
-<abbr>
-<address>
-<area>
-<article>
-<aside>
-<audio>
-<b>...</b>
-<base>
-<bdi>
-<bdo>
-<blockquote>
-<body>
-<br>
-<button>
-<canvas>
-<caption>
-<cite>
-<code>
-<col>
-<colgroup>
-<data>
-<datalist>
-<dd>
-<del>...</del>
-<details>
-<dfn>
-<dialog>
-<div>
-<dl>
-<dt>
-<em>...</em>
-<embed>
-<fieldset>
-<figcaption>
-<figure>
-<footer>
-<form>
-<h1>...</h1>
-<h2>...</h2>
-<h3>...</h3>
-<h4>...</h4>
-<h5>...</h5>
-<h6>...</h6>
-<head>...</head>
-<header>
-<hgroup>
-<hr>
-<html>
-<i>...</i>
-<iframe>
-<img>
-<input>
-<ins>
-<kbd>
-<label>
-<legend>
-<li>
-<link>
-<main>
-<map>
-<mark>
-<menu>
-<meta>
-<meter>
-<nav>
-<noscript>
-<object>
-<ol>
-<optgroup>
-<option>
-<output>
-<p>
-<picture>
-<pre>...</pre>
-<progress>
-<q>
-<rp>
-<rt>
-<ruby>
-<s>...</s>
-<samp>
-<script>...</script>
-<search>
-<section>
-<select>
-<slot>
-<small>
-<source>
-<span>
-<strong>...</strong>
-<style>...</style>
-<sub>
-<summary>
-<sup>
-<table>
-<tbody>
-<td>
-<template>
-<textarea>
-<tfoot>
-<th>
-<thead>
-<time>
-<title>...</title>
-<tr>
-<track>
-<u>...</u>
-<ul>
-<var>
-<video>
-<wbr>
-<xmp>
-
-<!-- Deprecated Elements -->
-<acronym>
-<big>
-<center>
-<dir>
-<font>
-<frame>
-<frameset>
-<marquee>
-<menuitem>
-<nobr>
-<noframes>
-<param>
-<rb>
-<rtc>
-<strike>...</strike>
-<tt>
-
-<!-- Note: these deprecated elements have never been matched -->
-<image>
-<noembed>
-<plaintext>
-
-<!-- Experimental -->
-<portal>
diff --git a/runtime/syntax/testdir/input/java_annotations.java b/runtime/syntax/testdir/input/java_annotations.java
new file mode 100644
index 0000000..c5871c3
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_annotations.java
@@ -0,0 +1,78 @@
+// VIM_TEST_SETUP let g:java_highlight_functions = 'style'
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+class AnnotationsTests
+{
+ @Target(ElementType.TYPE_USE)
+ @interface Tag
+ {
+ String value() default "";
+ String kind() default "";
+ }
+
+ @Target(ElementType.TYPE_USE)
+ @interface Text
+ {
+ String[] value() default {""};
+ }
+
+ @Target({
+ ElementType.METHOD,
+ ElementType.PARAMETER,
+ ElementType.TYPE,
+ })
+ @interface Labels
+ {
+ Label[] value();
+ }
+
+ @java.lang.annotation.Target({
+ java.lang.annotation.ElementType.METHOD,
+ java.lang.annotation.ElementType.PARAMETER,
+ java.lang.annotation.ElementType.TYPE,
+ })
+ @java.lang.annotation.Repeatable(Labels.class)
+ @interface Label
+ {
+ String value() default "";
+ Class<?> type() default Label.class;
+ boolean redundant() default true;
+ Text text() default @Text;
+ Tag head() default @Tag();
+ Tag tail() default @Tag(value = "", kind = "");
+ }
+
+ /* Use identity cast expressions to nest TYPE_USE annotations. */
+ @Label(
+ (@Text({
+ (@Text({ "a", "aa", "aaa", "aaaa", }) String) "as",
+ (@Text({ "b", "bb", "bbb", "bbbb", }) String) "bs",
+ (@Text({ "c", "cc", "ccc", "cccc", }) String) "cs",
+ (@Text({ "d", "dd", "ddd", "dddd", }) String) "ds",
+ }) String) "abcd")
+ interface Primer { }
+
+ @Label @Label() @Label("""
+ n\
+ o\
+ O\
+ p""")
+ @Label(head = @Tag(value = "@Label"/*, kind = "name"*/))
+ @Label(// value = "Method",
+ type = AnnotationsTests.class,
+ redundant = !!!(1 != 1),
+ head = @Tag(value = "@Label"),
+ text = @Text({ "})", "({" }))
+ static void noOp(@Label @Label() @Label("dummy")
+ @Label(head = @Tag(/*value = "@Label",*/ kind = "name"))
+ @Label(// value = "Parameter",
+ type = AnnotationsTests.class,
+ head = @Tag(value = "@Label"),
+ text = @Text({ "){", "}(" }))
+ Object dummy)
+ {
+ }
+}
diff --git a/runtime/syntax/testdir/input/java_enfoldment.java b/runtime/syntax/testdir/input/java_enfoldment.java
new file mode 100644
index 0000000..b534122
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_enfoldment.java
@@ -0,0 +1,86 @@
+// VIM_TEST_SETUP setlocal foldenable foldcolumn=2 foldmethod=syntax
+// VIM_TEST_SETUP let g:java_mark_braces_in_parens_as_errors = 1
+
+ @SuppressWarnings({
+ """
+ bespoke
+ /*
+ *
+ */
+ /**
+ *
+ */
+ //
+ //
+ //
+ {
+ }
+"""
+})
+class FoldingTests {
+ interface Foldenable
+ {
+ }
+
+ static {
+ new Object() {
+ {
+ {
+ new Object() {{{
+ new Object() {{{}}};
+ }}};
+ }
+ }
+ };
+
+ switch (0) {
+ case 0:
+ case 1: {
+ break;
+ }
+ default: ;
+ };
+ }
+
+ { Object bb = ((Object) new byte[]{}); }
+ {
+out: {
+ do {
+ if (true)
+ break out;
+ } while (false);
+}
+ }
+
+ /**
+ * No operation.
+ */
+ void noOp1() { }
+ /** No operation. */
+ void noOp2()
+ {
+ }
+ /** No operation. */
+ void noOp3() {
+ }
+ /** No operation. */
+ void noOp4() {
+ /*/\/\/\*/ ; }
+}
+
+/*
+ * Some note.
+ * {
+ * }
+ */
+/**
+ * A summary.
+ * {
+ * }
+ */
+//
+// {
+// }
+
+/* 122|..........................................................................................*/ interface Foldenable {
+}
diff --git a/runtime/syntax/testdir/input/java_lambda_expressions.java b/runtime/syntax/testdir/input/java_lambda_expressions.java
new file mode 100644
index 0000000..75f5af4
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_lambda_expressions.java
@@ -0,0 +1,154 @@
+// VIM_TEST_SETUP let g:java_highlight_functions = 'style'
+
+
+import java.lang.annotation.ElementType;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+class LambdaExpressionsTests // JDK 21+.
+{
+ <I1, C1, C2, T1, T2, T3, Z1, Z2, Z3, S1, S2, S3> void test()
+ { // Schönfinkel's functions.
+ I<I1> i = x -> x;
+ C<C1, C2> c = x -> y -> x;
+ T<T1, T2, T3> t = f -> y -> x -> f.apply(x).apply(y);
+ Z<Z1, Z2, Z3> z = f -> g -> x -> f.apply(g.apply(x));
+ S<S1, S2, S3> s = f -> g -> x -> f.apply(x)
+ .apply(g.apply(x));
+
+ I<I1> i01 = (var x) -> x;
+ I<I1> i02 = (@Taggable var x) -> x;
+ I<I1> i03 = (@Taggable @Taggable var x) -> x;
+ I<I1> i04 = (final var x) -> x;
+ I<I1> i05 = (@Taggable final var x) -> x;
+ I<I1> i06 = (@Taggable @Taggable final var x) -> x;
+ I<I1> i07 = (I1 x) -> x;
+ I<I1> i08 = (@Taggable I1 x) -> x;
+ I<I1> i09 = (@Taggable @Taggable I1 x) -> x;
+ I<I1> i10 = (final I1 x) -> x;
+ I<I1> i11 = (@Taggable final I1 x) -> x;
+ I<I1> i12 = (@Taggable @Taggable final I1 x) -> x;
+
+ I<I1[]> ii01 = (I1... x) -> x;
+ I<I1[]> ii02 = (@Taggable I1... x) -> x;
+ I<I1[]> ii03 = (@Taggable @Taggable I1... x) -> x;
+ I<I1[]> ii04 = (final I1... x) -> x;
+ I<I1[]> ii05 = (@Taggable final I1... x) -> x;
+ I<I1[]> ii06 = (@Taggable @Taggable final I1... x) -> x;
+
+ BinaryOperator<I1> leftConst01 = (var x, var y) -> x;
+ BinaryOperator<I1> leftConst02 = (@Taggable var x,
+ @Taggable var y) -> x;
+ BinaryOperator<I1> leftConst03 = (@Taggable @Taggable var
+ x, @Taggable @Taggable var y) -> x;
+ BinaryOperator<I1> leftConst04 = (final var x,
+ final var y) -> x;
+ BinaryOperator<I1> leftConst05 = (@Taggable final
+ var x, @Taggable final var y) -> x;
+ BinaryOperator<I1> leftConst06 = (@Taggable
+ @Taggable final var x,
+ @Taggable
+ @Taggable final var y) -> x;
+ BinaryOperator<I1> leftConst07 = (I1 x, I1 y) -> x;
+ BinaryOperator<I1> leftConst08 = (@Taggable I1 x,
+ @Taggable I1 y) -> x;
+ BinaryOperator<I1> leftConst09 = (@Taggable @Taggable I1
+ x, @Taggable @Taggable I1 y) -> x;
+ BinaryOperator<I1> leftConst10 = (final I1 x,
+ final I1 y) -> x;
+ BinaryOperator<I1> leftConst11 = (@Taggable final
+ I1 x, @Taggable final I1 y) -> x;
+ BinaryOperator<I1> leftConst12 = (@Taggable
+ @Taggable final I1 x,
+ @Taggable
+ @Taggable final I1 y) -> x;
+
+ Runnable noOp = () -> {};
+ BinaryOperator<I1> leftConst = (x, y) -> x;
+ I<I1> id1 = (x) -> (x);
+ @SuppressWarnings("unchecked") I<I1> id2 =
+ ((I<I<I1>>) (I<?>) (Function<I1,
+ I1> x) -> x).apply(switch (0) {
+ case ((int) (byte) 1) -> (I1 x) -> x;
+ default -> (@Taggable I1 x) -> x; });
+ C<C1, C2> const1 = (x) -> (y) -> (x);
+ C<C1, C2> const2 = switch(switch ("") {
+ case "->"->"(s)->(s)";
+ default->"default"; }) {
+ case ("->")->(var x)->(var y)->(x);
+ default->(@Taggable var x)->(@Taggable var y)
+ ->(x);
+ };
+ }
+
+ @java.lang.annotation.Target(ElementType.PARAMETER)
+ @java.lang.annotation.Repeatable(Taggables.class)
+ @interface Taggable { String[] value() default ""; }
+
+ @java.lang.annotation.Target(ElementType.PARAMETER)
+ @interface Taggables { Taggable[] value(); }
+
+ interface I<A1> extends Function<A1, A1> { }
+ interface C<A1, A2> extends Function<A1, Function<A2, A1>> { }
+ interface T<A1, A2, A3> extends
+ Function<Function<A1, Function<A2, A3>>,
+ Function<A2,
+ Function<A1, A3>>> { }
+ interface Z<A1, A2, A3> extends Function<Function<A2, A3>,
+ Function<Function<A1, A2>,
+ Function<A1, A3>>> { }
+ interface S<A1, A2, A3> extends
+ Function<Function<A1, Function<A2, A3>>,
+ Function<Function<A1, A2>,
+ Function<A1, A3>>> { }
+
+ static void echo(Object o) { System.out.println(o); }
+
+ static {
+ enum Letters { OTHER, ALPHA, BETA }
+
+ Letters other = Letters.OTHER;
+
+ switch (other) {
+ case Letters alpha when Letters.ALPHA == alpha:
+ { echo(alpha); break; }
+ case Letters beta when Letters.BETA == beta:
+ { echo(beta); break; }
+ default: { echo(other); }
+ }
+
+ echo(switch (other) {
+ case Letters alpha when Letters.ALPHA == alpha
+ -> alpha;
+ case Letters beta when Letters.BETA == beta
+ -> beta;
+ default -> other;
+ });
+
+ switch (null) {
+ case String str when !"<empty>".equals(switch (str) {
+ case String str_ when
+ Predicate.<String>not(text ->
+ !text.isEmpty())
+ .test(str_)
+ -> "<empty>";
+ case String str_ -> str_;
+ }): { echo(str); break; }
+ case null: default: { echo("Other"); }
+ };
+
+ echo(switch (null) {
+ case String str when !"<empty>".equals(
+ switch (str) {
+ case String str_ when
+ Predicate.<String>not(text ->
+ !text.isEmpty())
+ .test(str_)
+ -> "<empty>";
+ case String str_ -> str_;
+ }) -> str;
+ case null, default -> "Other";
+ });
+ }
+}
diff --git a/runtime/syntax/testdir/input/java_methods_indent.java b/runtime/syntax/testdir/input/java_methods_indent.java
deleted file mode 100644
index 627eb8b..0000000
--- a/runtime/syntax/testdir/input/java_methods_indent.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// VIM_TEST_SETUP let g:java_highlight_functions = 'indent'
-
-
-import java.lang.annotation.Target;
-
-abstract class IndentMethodsTests
-{ // DO NOT retab! THIS FILE; REMEMBER ABOUT testdir/ftplugin.
- protected IndentMethodsTests() { }
-
- record Τʬ<α>(α a) { }
-
- enum 𝓔
- {
- A("𝕬"), B("𝕭"), C("𝕮"), D("𝕯"),
- E("𝕰"), F("𝕱"), G("𝕲"), H("𝕳");
- final String 𝐬;
- private 𝓔(String 𝐬) { this.𝐬 = 𝐬; }
- }
-
- @Target(java.lang.annotation.ElementType.METHOD)
- @java.lang.annotation.Repeatable(Tɐggablɘs.class)
- @interface Tɐggablɘ
- {
- String[] value() default "";
- }
-
- @Target(java.lang.annotation.ElementType.METHOD)
- @interface Tɐggablɘs
- {
- Tɐggablɘ[] value();
- }
-
- interface Stylable<Α>
- {
- default void ascii$0_() { }
- default Α μʭʭ$0_() { return null; }
- }
-
- @Tɐggablɘ @Tɐggablɘ
- abstract void ascii$0_();
-
- @Tɐggablɘ @Tɐggablɘ
- abstract <α, β> Τʬ<α> μʭʭ$0_(β 𝛽);
-
- @Tɐggablɘ
- private native void ascii$1_();
-
- @Tɐggablɘ
- private native <α, β> Τʬ<α>[] μʭʭ$1_(
- java.util.function.Function<β, Τʬ<α>[]> ƒ);
-
- static final native synchronized void ascii$98_();
- static final native synchronized <α, β> Τʬ<α>[][] μʭʭ$98_(
- java.util.function.Function<β, Τʬ<α>[][]> ƒ);
-
- @SuppressWarnings("strictfp")
- protected static final synchronized strictfp void ascii$99_()
- { ascii$98_(); }
-
- @SuppressWarnings("strictfp")
- protected static final synchronized strictfp <α, β> Τʬ<α>[] μʭʭ$99_(
- java.util.function.Function<β, Τʬ<α>[][]> ƒ)
- {
- return
- IndentMethodsTests.<α, β>μʭʭ$98_(ƒ)[0];
- }
-
- @Override @SuppressWarnings("cast")
- public String toString() { return (String) "IndentMethodsTests"; }
-}
diff --git a/runtime/syntax/testdir/input/java_methods_indent2.java b/runtime/syntax/testdir/input/java_methods_indent2.java
new file mode 100644
index 0000000..58a6900
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_methods_indent2.java
@@ -0,0 +1,92 @@
+// VIM_TEST_SETUP let g:java_highlight_functions = 'indent2'
+// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+abstract class Indent2MethodsTests
+{ // DO NOT retab! THIS FILE; REMEMBER ABOUT testdir/ftplugin.
+ // TYPES.
+ record Τʬ<α>(α a) { }
+
+ enum E
+ {
+ A("a"), B("b"), C("c"), D("d"),
+ E("e"), F("f"), G("g"), H("h");
+ final String s;
+ private E(String s) { this.s = s; }
+ }
+
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ @java.lang.annotation.Repeatable(Tɐggablɘs.class)
+ @interface Tɐggablɘ
+ {
+ String[] value() default "";
+ }
+
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ @interface Tɐggablɘs
+ {
+ Tɐggablɘ[] value();
+ }
+
+ interface Stylable<Α>
+ {
+ default void ascii$0_() { }
+ default Α μʭʭ$0_() { return null; }
+ }
+
+ // FIELDS.
+ private static final Class<?> CLASS_LOCK = classLock();
+
+ private final Object instanceLock = new Object();
+
+ // CONSTRUCTORS.
+ @Tɐggablɘ @Tɐggablɘ protected Indent2MethodsTests() { }
+ <T extends Comparable<T>> Indent2MethodsTests(T t, Void v) { }
+ private <T extends Comparable<T>> Indent2MethodsTests(T t) { }
+
+ // METHODS.
+ @Tɐggablɘ @Tɐggablɘ abstract void ascii$0_(////////////////
+ );
+ @Tɐggablɘ @Tɐggablɘ abstract <α, β> Τʬ<α> μʭʭ$0_(
+ @SuppressWarnings("bespoke") β b);
+
+ @Tɐggablɘ private native void ascii$1_(/*////////////*/);
+ @Tɐggablɘ private native <α, β> Τʬ<α>[] μʭʭ$1_(
+ java.util.function.Function<β, Τʬ<α>[]> ƒ);
+
+ void Ascii$2_() { }
+ <T, U extends Stylable<T>> void Μʭʭ$2_(U u) { }
+
+ static final native synchronized void ascii$98_();
+ static final native synchronized <α, β> Τʬ<α>[][] μʭʭ$98_(
+ java.util.function.Function<β, Τʬ<α>[][]> ƒ);
+
+ @SuppressWarnings("strictfp")
+ protected static final synchronized strictfp void ascii$99_()
+ { ascii$98_(); }
+
+ @SuppressWarnings("strictfp")
+ protected static final synchronized strictfp <α, β> Τʬ<α>[] μʭʭ$99_(
+ java.util.function.Function<β, Τʬ<α>[][]> ƒ)
+ {
+ return
+ Indent2MethodsTests.<α, β>μʭʭ$98_(ƒ)[0];
+ }
+
+ public static Class<?> classLock() { return Indent2MethodsTests.class; }
+
+ @Override @SuppressWarnings("cast")
+ public String toString() { return (String) "Indent2MethodsTests"; }
+}
+
+enum E2
+{
+ @SuppressWarnings("bespoke") A("a"),
+ B("b"),
+ C("c"), D("d"),
+ E("e"), F("f"), G("g"), H("h");
+ final String s;
+ private E2(String s) { this.s = s; }
+}
diff --git a/runtime/syntax/testdir/input/java_methods_indent4.java b/runtime/syntax/testdir/input/java_methods_indent4.java
new file mode 100644
index 0000000..972cdf3
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_methods_indent4.java
@@ -0,0 +1,92 @@
+// VIM_TEST_SETUP let g:java_highlight_functions = 'indent4'
+// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+abstract class Indent4MethodsTests
+{ // DO NOT retab! THIS FILE; REMEMBER ABOUT testdir/ftplugin.
+ // TYPES.
+ record Τʬ<α>(α a) { }
+
+ enum E
+ {
+ A("a"), B("b"), C("c"), D("d"),
+ E("e"), F("f"), G("g"), H("h");
+ final String s;
+ private E(String s) { this.s = s; }
+ }
+
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ @java.lang.annotation.Repeatable(Tɐggablɘs.class)
+ @interface Tɐggablɘ
+ {
+ String[] value() default "";
+ }
+
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ @interface Tɐggablɘs
+ {
+ Tɐggablɘ[] value();
+ }
+
+ interface Stylable<Α>
+ {
+ default void ascii$0_() { }
+ default Α μʭʭ$0_() { return null; }
+ }
+
+ // FIELDS.
+ private static final Class<?> CLASS_LOCK = classLock();
+
+ private final Object instanceLock = new Object();
+
+ // CONSTRUCTORS.
+ @Tɐggablɘ @Tɐggablɘ protected Indent4MethodsTests() { }
+ <T extends Comparable<T>> Indent4MethodsTests(T t, Void v) { }
+ private <T extends Comparable<T>> Indent4MethodsTests(T t) { }
+
+ // METHODS.
+ @Tɐggablɘ @Tɐggablɘ abstract void ascii$0_(////////////////
+ );
+ @Tɐggablɘ @Tɐggablɘ abstract <α, β> Τʬ<α> μʭʭ$0_(
+ @SuppressWarnings("bespoke") β b);
+
+ @Tɐggablɘ private native void ascii$1_(/*////////////*/);
+ @Tɐggablɘ private native <α, β> Τʬ<α>[] μʭʭ$1_(
+ java.util.function.Function<β, Τʬ<α>[]> ƒ);
+
+ void Ascii$2_() { }
+ <T, U extends Stylable<T>> void Μʭʭ$2_(U u) { }
+
+ static final native synchronized void ascii$98_();
+ static final native synchronized <α, β> Τʬ<α>[][] μʭʭ$98_(
+ java.util.function.Function<β, Τʬ<α>[][]> ƒ);
+
+ @SuppressWarnings("strictfp")
+ protected static final synchronized strictfp void ascii$99_()
+ { ascii$98_(); }
+
+ @SuppressWarnings("strictfp")
+ protected static final synchronized strictfp <α, β> Τʬ<α>[] μʭʭ$99_(
+ java.util.function.Function<β, Τʬ<α>[][]> ƒ)
+ {
+ return
+ Indent4MethodsTests.<α, β>μʭʭ$98_(ƒ)[0];
+ }
+
+ public static Class<?> classLock() { return Indent4MethodsTests.class; }
+
+ @Override @SuppressWarnings("cast")
+ public String toString() { return (String) "Indent4MethodsTests"; }
+}
+
+enum E4
+{
+ @SuppressWarnings("bespoke") A("a"),
+ B("b"),
+ C("c"), D("d"),
+ E("e"), F("f"), G("g"), H("h");
+ final String s;
+ private E4(String s) { this.s = s; }
+}
diff --git a/runtime/syntax/testdir/input/java_methods_indent8.java b/runtime/syntax/testdir/input/java_methods_indent8.java
new file mode 100644
index 0000000..40fd26b
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_methods_indent8.java
@@ -0,0 +1,92 @@
+// VIM_TEST_SETUP let g:java_highlight_functions = 'indent8'
+// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+abstract class Indent8MethodsTests
+{ // DO NOT retab! THIS FILE; REMEMBER ABOUT testdir/ftplugin.
+ // TYPES.
+ record Τʬ<α>(α a) { }
+
+ enum E
+ {
+ A("a"), B("b"), C("c"), D("d"),
+ E("e"), F("f"), G("g"), H("h");
+ final String s;
+ private E(String s) { this.s = s; }
+ }
+
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ @java.lang.annotation.Repeatable(Tɐggablɘs.class)
+ @interface Tɐggablɘ
+ {
+ String[] value() default "";
+ }
+
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+ @interface Tɐggablɘs
+ {
+ Tɐggablɘ[] value();
+ }
+
+ interface Stylable<Α>
+ {
+ default void ascii$0_() { }
+ default Α μʭʭ$0_() { return null; }
+ }
+
+ // FIELDS.
+ private static final Class<?> CLASS_LOCK = classLock();
+
+ private final Object instanceLock = new Object();
+
+ // CONSTRUCTORS.
+ @Tɐggablɘ @Tɐggablɘ protected Indent8MethodsTests() { }
+ <T extends Comparable<T>> Indent8MethodsTests(T t, Void v) { }
+ private <T extends Comparable<T>> Indent8MethodsTests(T t) { }
+
+ // METHODS.
+ @Tɐggablɘ @Tɐggablɘ abstract void ascii$0_(////////////////
+ );
+ @Tɐggablɘ @Tɐggablɘ abstract <α, β> Τʬ<α> μʭʭ$0_(
+ @SuppressWarnings("bespoke") β b);
+
+ @Tɐggablɘ private native void ascii$1_(/*////////////*/);
+ @Tɐggablɘ private native <α, β> Τʬ<α>[] μʭʭ$1_(
+ java.util.function.Function<β, Τʬ<α>[]> ƒ);
+
+ void Ascii$2_() { }
+ <T, U extends Stylable<T>> void Μʭʭ$2_(U u) { }
+
+ static final native synchronized void ascii$98_();
+ static final native synchronized <α, β> Τʬ<α>[][] μʭʭ$98_(
+ java.util.function.Function<β, Τʬ<α>[][]> ƒ);
+
+ @SuppressWarnings("strictfp")
+ protected static final synchronized strictfp void ascii$99_()
+ { ascii$98_(); }
+
+ @SuppressWarnings("strictfp")
+ protected static final synchronized strictfp <α, β> Τʬ<α>[] μʭʭ$99_(
+ java.util.function.Function<β, Τʬ<α>[][]> ƒ)
+ {
+ return
+ Indent8MethodsTests.<α, β>μʭʭ$98_(ƒ)[0];
+ }
+
+ public static Class<?> classLock() { return Indent8MethodsTests.class; }
+
+ @Override @SuppressWarnings("cast")
+ public String toString() { return (String) "Indent8MethodsTests"; }
+}
+
+enum E8
+{
+ @SuppressWarnings("bespoke") A("a"),
+ B("b"),
+ C("c"), D("d"),
+ E("e"), F("f"), G("g"), H("h");
+ final String s;
+ private E8(String s) { this.s = s; }
+}
diff --git a/runtime/syntax/testdir/input/java_methods_style.java b/runtime/syntax/testdir/input/java_methods_style.java
index b3e36fb..e2e7d38 100644
--- a/runtime/syntax/testdir/input/java_methods_style.java
+++ b/runtime/syntax/testdir/input/java_methods_style.java
@@ -1,30 +1,30 @@
// VIM_TEST_SETUP let g:java_highlight_functions = 'style'
+// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8
-
+import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
abstract class StyleMethodsTests
{
- protected StyleMethodsTests() { }
-
+ // TYPES.
record Τʬ<α>(α a) { }
- enum 𝓔
+ enum E
{
- A("𝕬"), B("𝕭"), C("𝕮"), D("𝕯"),
- E("𝕰"), F("𝕱"), G("𝕲"), H("𝕳");
- final String 𝐬;
- private 𝓔(String 𝐬) { this.𝐬 = 𝐬; }
+ A("a"), B("b"), C("c"), D("d"),
+ E("e"), F("f"), G("g"), H("h");
+ final String s;
+ private E(String s) { this.s = s; }
}
- @Target(java.lang.annotation.ElementType.METHOD)
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@java.lang.annotation.Repeatable(Tɐggablɘs.class)
@interface Tɐggablɘ
{
String[] value() default "";
}
- @Target(java.lang.annotation.ElementType.METHOD)
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@interface Tɐggablɘs
{
Tɐggablɘ[] value();
@@ -36,15 +36,29 @@ abstract class StyleMethodsTests
default Α μʭʭ$0_() { return null; }
}
+ // FIELDS.
+ private static final Class<?> CLASS_LOCK = classLock();
+
+ private final Object instanceLock = new Object();
+
+ // CONSTRUCTORS.
+ @Tɐggablɘ @Tɐggablɘ protected StyleMethodsTests() { }
+ <T extends Comparable<T>> StyleMethodsTests(T t, Void v) { }
+ private <T extends Comparable<T>> StyleMethodsTests(T t) { }
+
+ // METHODS.
@Tɐggablɘ @Tɐggablɘ abstract void ascii$0_(////////////////
);
@Tɐggablɘ @Tɐggablɘ abstract <α, β> Τʬ<α> μʭʭ$0_(
- /* TODO: @SuppressWarnings("bespoke")*/ β 𝛽);
+ @SuppressWarnings("bespoke") β b);
@Tɐggablɘ private native void ascii$1_(/*////////////*/);
@Tɐggablɘ private native <α, β> Τʬ<α>[] μʭʭ$1_(
java.util.function.Function<β, Τʬ<α>[]> ƒ);
+ void Ascii$2_() { }
+ <T, U extends Stylable<T>> void Μʭʭ$2_(U u) { }
+
static final native synchronized void ascii$98_();
static final native synchronized <α, β> Τʬ<α>[][] μʭʭ$98_(
java.util.function.Function<β, Τʬ<α>[][]> ƒ);
@@ -61,6 +75,8 @@ abstract class StyleMethodsTests
StyleMethodsTests.<α, β>μʭʭ$98_(ƒ)[0];
}
+ public static Class<?> classLock() { return StyleMethodsTests.class; }
+
@Override @SuppressWarnings("cast")
public String toString() { return (String) "StyleMethodsTests"; }
}
diff --git a/runtime/syntax/testdir/input/java_unfoldment.java b/runtime/syntax/testdir/input/java_unfoldment.java
new file mode 100644
index 0000000..78dd234
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_unfoldment.java
@@ -0,0 +1,86 @@
+// VIM_TEST_SETUP setlocal nofoldenable
+// VIM_TEST_SETUP let g:java_mark_braces_in_parens_as_errors = 1
+
+ @SuppressWarnings({
+ """
+ bespoke
+ /*
+ *
+ */
+ /**
+ *
+ */
+ //
+ //
+ //
+ {
+ }
+"""
+})
+class UnfoldingTests {
+ interface Unfoldenable
+ {
+ }
+
+ static {
+ new Object() {
+ {
+ {
+ new Object() {{{
+ new Object() {{{}}};
+ }}};
+ }
+ }
+ };
+
+ switch (0) {
+ case 0:
+ case 1: {
+ break;
+ }
+ default: ;
+ };
+ }
+
+ { Object bb = ((Object) new byte[]{}); }
+ {
+out: {
+ do {
+ if (true)
+ break out;
+ } while (false);
+}
+ }
+
+ /**
+ * No operation.
+ */
+ void noOp1() { }
+ /** No operation. */
+ void noOp2()
+ {
+ }
+ /** No operation. */
+ void noOp3() {
+ }
+ /** No operation. */
+ void noOp4() {
+ /*/\/\/\*/ ; }
+}
+
+/*
+ * Some note.
+ * {
+ * }
+ */
+/**
+ * A summary.
+ * {
+ * }
+ */
+//
+// {
+// }
+
+/* 122|........................................................................................*/ interface Unfoldenable {
+}
diff --git a/runtime/syntax/testdir/input/vim_ex_comment-vim9.vim b/runtime/syntax/testdir/input/vim9_comment.vim
index 786d11b..fd6a5d2 100644
--- a/runtime/syntax/testdir/input/vim_ex_comment-vim9.vim
+++ b/runtime/syntax/testdir/input/vim9_comment.vim
@@ -28,6 +28,29 @@ autocmd BufNewFile * {
}
+# Multiline comments
+
+# comment
+ \ continuing comment
+ \ continuing comment
+
+# :Foo
+ \ arg1
+ #\ comment
+ \ arg2
+
+echo "TOP"
+
+
+# Line-continuation comments
+
+:Foo
+ #\ line continuation comment
+ \ arg1
+ #\ line continuation comment
+ \ arg2
+
+
# Issue: #13047
if !exists(":DiffOrig")
diff --git a/runtime/syntax/testdir/input/vim9_ex_comment_strings.vim b/runtime/syntax/testdir/input/vim9_ex_comment_strings.vim
new file mode 100644
index 0000000..fd02c1a
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim9_ex_comment_strings.vim
@@ -0,0 +1,22 @@
+vim9script
+
+# Vim comment strings
+# VIM_TEST_SETUP let g:vimsyn_comment_strings = v:true
+
+# pre "string" post
+
+function Foo()
+ " pre "string" post
+endfunction
+
+def Bar()
+ # pre "string" post
+enddef
+
+command Foo {
+ # pre "string" post
+}
+
+autocmd BufNewFile * {
+ # pre "string" post
+}
diff --git a/runtime/syntax/testdir/input/vim9_ex_no_comment_strings.vim b/runtime/syntax/testdir/input/vim9_ex_no_comment_strings.vim
new file mode 100644
index 0000000..dcea14d
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim9_ex_no_comment_strings.vim
@@ -0,0 +1,22 @@
+vim9script
+
+# Vim comment strings
+# VIM_TEST_SETUP let g:vimsyn_comment_strings = v:false
+
+# pre "string" post
+
+function Foo()
+ " pre "string" post
+endfunction
+
+def Bar()
+ # pre "string" post
+enddef
+
+command Foo {
+ # pre "string" post
+}
+
+autocmd BufNewFile * {
+ # pre "string" post
+}
diff --git a/runtime/syntax/testdir/input/vim9_shebang.vim b/runtime/syntax/testdir/input/vim9_shebang.vim
new file mode 100755
index 0000000..c012fd9
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim9_shebang.vim
@@ -0,0 +1,7 @@
+#!/usr/bin/env vim -S
+vim9script
+
+# Vim shebang line
+
+# just a line comment
+#!/usr/bin/env vim -S
diff --git a/runtime/syntax/testdir/input/vim_ex_comment.vim b/runtime/syntax/testdir/input/vim_comment.vim
index 54e514e..f382f8d 100644
--- a/runtime/syntax/testdir/input/vim_ex_comment.vim
+++ b/runtime/syntax/testdir/input/vim_comment.vim
@@ -25,6 +25,29 @@ autocmd BufNewFile * {
}
+" Multiline comments
+
+" comment
+ \ continuing comment
+ \ continuing comment
+
+" :Foo
+ \ arg1
+ "\ comment
+ \ arg2
+
+echo "TOP"
+
+
+" Line-continuation comments
+
+:Foo
+ "\ line continuation comment
+ \ arg1
+ "\ line continuation comment
+ \ arg2
+
+
" Issue: #13047
if !exists(":DiffOrig")
diff --git a/runtime/syntax/testdir/input/vim_ex_catch.vim b/runtime/syntax/testdir/input/vim_ex_catch.vim
new file mode 100644
index 0000000..f0e2a8f
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim_ex_catch.vim
@@ -0,0 +1,17 @@
+" Vim :catch command
+
+" :help :catch
+
+catch /^Vim:Interrupt$/ " catch interrupts (CTRL-C)
+catch /^Vim\%((\a\+)\)\=:E/ " catch all Vim errors
+catch /^Vim\%((\a\+)\)\=:/ " catch errors and interrupts
+catch /^Vim(write):/ " catch all errors in :write
+catch /^Vim\%((\a\+)\)\=:E123:/ " catch error E123
+catch /my-exception/ " catch user exception
+catch /.*/ " catch everything
+catch " same as /.*/
+
+" :help :try
+
+try | sleep 100 | catch /^Vim:Interrupt$/ | endtry
+try | edit | catch /^Vim(edit):E\d\+/ | echo "error" | endtry
diff --git a/runtime/syntax/testdir/input/vim_ex_comment_strings.vim b/runtime/syntax/testdir/input/vim_ex_comment_strings.vim
new file mode 100644
index 0000000..4214d6b
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim_ex_comment_strings.vim
@@ -0,0 +1,20 @@
+" Vim comment strings
+" VIM_TEST_SETUP let g:vimsyn_comment_strings = v:true
+
+" pre "string" post
+
+function Foo()
+ " pre "string" post
+endfunction
+
+def Bar()
+ # pre "string" post
+enddef
+
+command Foo {
+ # pre "string" post
+}
+
+autocmd BufNewFile * {
+ # pre "string" post
+}
diff --git a/runtime/syntax/testdir/input/vim_ex_no_comment_strings.vim b/runtime/syntax/testdir/input/vim_ex_no_comment_strings.vim
new file mode 100644
index 0000000..d9b53b3
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim_ex_no_comment_strings.vim
@@ -0,0 +1,20 @@
+" Vim comment strings
+" VIM_TEST_SETUP let g:vimsyn_comment_strings = v:false
+
+" pre "string" post
+
+function Foo()
+ " pre "string" post
+endfunction
+
+def Bar()
+ # pre "string" post
+enddef
+
+command Foo {
+ # pre "string" post
+}
+
+autocmd BufNewFile * {
+ # pre "string" post
+}
diff --git a/runtime/syntax/testdir/input/vim_ex_sleep.vim b/runtime/syntax/testdir/input/vim_ex_sleep.vim
new file mode 100644
index 0000000..49fd31e
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim_ex_sleep.vim
@@ -0,0 +1,11 @@
+" Vim :sleep command
+
+sleep " sleep for one second
+5 sleep " sleep for five seconds
+sleep 100m " sleep for 100 milliseconds
+100 sleep m " sleep for 100 milliseconds
+
+sleep! " sleep for one second
+5 sleep! " sleep for five seconds
+sleep! 100m " sleep for 100 milliseconds
+100 sleep! m " sleep for 100 milliseconds
diff --git a/runtime/syntax/testdir/input/vim_ex_substitute.vim b/runtime/syntax/testdir/input/vim_ex_substitute.vim
index 340d573..021060a 100644
--- a/runtime/syntax/testdir/input/vim_ex_substitute.vim
+++ b/runtime/syntax/testdir/input/vim_ex_substitute.vim
@@ -73,6 +73,64 @@ s{/{//{ " comment
s}/}//} " comment
s~/~//~ " comment
+s !/!//! " comment
+" s "/"//" " comment (works but disallowed)
+s #/#//# " comment
+s $/$//$ " comment
+s %/%//% " comment
+s &/&//& " comment
+s '/'//' " comment
+" FIXME - matches vimUserFunc
+" s (/(//( " comment
+s )/)//) " comment
+s */*//* " comment
+s +/+//+ " comment
+s ,/,//, " comment
+s -/-//- " comment
+s ././/. " comment
+s /X/XX/ " comment
+s :/://: " comment
+s ;/;//; " comment
+s </<//< " comment
+s =/=//= " comment
+s >/>//> " comment
+s ?/?//? " comment
+s @/@//@ " comment
+s [/[//[ " comment
+" s \/\//\ " comment (disallowed)
+s ]/]//] " comment
+s ^/^//^ " comment
+s _/_//_ " comment
+s `/`//` " comment
+s {/{//{ " comment
+" s |/|//| " comment (disallowed)
+s }/}//} " comment
+s ~/~//~ " comment
+
+s//{string}/
+s //{string}/
+
+
+" Vi compatibility
+
+s\/{string}/
+s\?{string}?
+s\&{string}&
+
+s \/{string}/
+s \?{string}?
+s \&{string}&
+
+
+" Trailing comment and bar
+
+" FIXME: trailing comment, no whitespace
+s" comment
+s| echo "Foo"
+
+s " comment
+s | echo "Foo"
+
" Issue #13883
diff --git a/runtime/syntax/testdir/input/vim_ex_throw.vim b/runtime/syntax/testdir/input/vim_ex_throw.vim
new file mode 100644
index 0000000..4adbc88
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim_ex_throw.vim
@@ -0,0 +1,5 @@
+" Vim :throw command
+
+" :help :throw
+
+try | throw "oops" | catch /^oo/ | echo "caught" | endtry
diff --git a/runtime/syntax/testdir/input/vim_shebang.vim b/runtime/syntax/testdir/input/vim_shebang.vim
new file mode 100755
index 0000000..47a550c
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim_shebang.vim
@@ -0,0 +1,5 @@
+#!/usr/bin/env vim -S
+
+" Vim shebang line
+
+#!/usr/bin/env vim -S
diff --git a/runtime/syntax/typescript.vim b/runtime/syntax/typescript.vim
index 5389c21..03520fd 100644
--- a/runtime/syntax/typescript.vim
+++ b/runtime/syntax/typescript.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: TypeScript
" Maintainer: Herrington Darkholme
-" Last Change: 2023 Aug 13
+" Last Change: 2024 May 24
" Based On: Herrington Darkholme's yats.vim
" Changes: Go to https://github.com/HerringtonDarkholme/yats.vim for recent changes.
" Origin: https://github.com/othree/yajs
diff --git a/runtime/syntax/typescriptreact.vim b/runtime/syntax/typescriptreact.vim
index 1c51045..061ec4d 100644
--- a/runtime/syntax/typescriptreact.vim
+++ b/runtime/syntax/typescriptreact.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: TypeScript with React (JSX)
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2023 Aug 13
+" Last Change: 2024 May 26
" Based On: Herrington Darkholme's yats.vim
" Changes: See https://github.com/HerringtonDarkholme/yats.vim
" Credits: See yats.vim on github
@@ -118,13 +118,14 @@ syntax match tsxEqual +=+ display contained
" <tag id="sample">
" s~~~~~~e
-syntax region tsxString contained start=+"+ end=+"+ contains=tsxEntity,@Spell display
+syntax region tsxString contained start=+"+ skip=+\\"+ end=+"+ contains=tsxEntity,@Spell display
+syntax region tsxString contained start=+'+ skip=+\\'+ end=+'+ contains=tsxEntity,@Spell display
" <tag key={this.props.key}>
" s~~~~~~~~~~~~~~e
syntax region tsxEscJs
\ contained
- \ contains=@typescriptValue,@tsxComment
+ \ contains=@typescriptValue,@tsxComment,typescriptObjectSpread
\ matchgroup=typescriptBraces
\ start=+{+
\ end=+}+
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index 02d6dde..033251f 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -3,7 +3,7 @@
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
" Doug Kearns <dougkearns@gmail.com>
" URL: https://github.com/vim-jp/syntax-vim-ex
-" Last Change: 2024 Apr 13
+" Last Change: 2024 Jun 15
" Former Maintainer: Charles E. Campbell
" DO NOT CHANGE DIRECTLY.
@@ -28,12 +28,12 @@ syn cluster vimCommentGroup contains=vimTodo,@Spell
" regular vim commands {{{2
" GEN_SYN_VIM: vimCommand normal, START_STR='syn keyword vimCommand contained', END_STR=''
-syn keyword vimCommand contained abo[veleft] abs[tract] al[l] ar[gs] arga[dd] argd[elete] argdo argded[upe] arge[dit] argg[lobal] argl[ocal] argu[ment] as[cii] b[uffer] bN[ext] ba[ll] bad[d] balt bd[elete] bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bo[tright] bp[revious] br[ewind] brea[k] breaka[dd] breakd[el] breakl[ist] bro[wse] buffers bufd[o] bun[load] bw[ipeout] c[hange] cN[ext] cNf[ile] cabo[ve] cad[dbuffer] cadde[xpr] caddf[ile] caf[ter] cal[l] cat[ch] cb[uffer] cbe[fore] cbel[ow] cbo[ttom] cc ccl[ose] cd cdo ce[nter] cex[pr] cf[ile] cfd[o] cfir[st] cg[etfile] cgetb[uffer] cgete[xpr] chd[ir] changes che[ckpath] checkt[ime] chi[story] cl[ist] cla[st] class clo[se] cle[arjumps] cn[ext] cnew[er] cnf[ile] co[py] col[der] colo[rscheme] com[mand] comc[lear]
-syn keyword vimCommand contained comp[iler] con[tinue] conf[irm] cons[t] cope[n] cp[revious] cpf[ile] cq[uit] cr[ewind] cs[cope] cst[ag] cw[indow] d[elete] delm[arks] deb[ug] debugg[reedy] defc[ompile] defe[r] delc[ommand] delf[unction] di[splay] dif[fupdate] diffg[et] diffo[ff] diffp[atch] diffpu[t] diffs[plit] difft[his] dig[raphs] disa[ssemble] dj[ump] dli[st] dr[op] ds[earch] dsp[lit] e[dit] ea[rlier] el[se] elsei[f] em[enu] en[dif] endin[terface] endc[lass] ende[num] endfo[r] endt[ry] endw[hile] ene[w] enu[m] ev[al] ex exi[t] exp[ort] exu[sage] f[ile] files filet[ype] filt[er] fin[d] fina[l] finall[y] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] foldd[oopen] folddoc[losed] foldo[pen] for g[lobal] go[to] gr[ep] grepa[dd] gu[i] gv[im] h[elp] helpc[lose] helpf[ind]
-syn keyword vimCommand contained helpg[rep] helpt[ags] ha[rdcopy] hi[ghlight] hid[e] his[tory] ho[rizontal] if ij[ump] il[ist] imp[ort] int[ro] inte[rface] is[earch] isp[lit] j[oin] ju[mps] k kee[pmarks] keepj[umps] keepp[atterns] keepa[lt] l[ist] lN[ext] lNf[ile] la[st] lab[ove] lan[guage] lad[dexpr] laddb[uffer] laddf[ile] laf[ter] lat[er] lb[uffer] lbe[fore] lbel[ow] lbo[ttom] lc[d] lch[dir] lcl[ose] lcs[cope] ld[o] le[ft] lefta[bove] let lex[pr] leg[acy] lf[ile] lfd[o] lfir[st] lg[etfile] lgetb[uffer] lgete[xpr] lgr[ep] lgrepa[dd] lh[elpgrep] lhi[story] ll lla[st] lli[st] lmak[e] lne[xt] lnew[er] lnf[ile] lo[adview] loadk[eymap] loc[kmarks] lockv[ar] lol[der] lop[en] lp[revious] lpf[ile] lr[ewind] lt[ag] lua luad[o] luaf[ile] lv[imgrep] lvimgrepa[dd] lw[indow]
-syn keyword vimCommand contained ls m[ove] ma[rk] mak[e] marks mat[ch] menut[ranslate] mes[sages] mk[exrc] mks[ession] mksp[ell] mkv[imrc] mkvie[w] mod[e] mz[scheme] mzf[ile] n[ext] nb[key] nbc[lose] nbs[tart] noa[utocmd] noh[lsearch] nos[wapfile] nu[mber] o[pen] ol[dfiles] on[ly] opt[ions] ow[nsyntax] p[rint] pa[ckadd] packl[oadall] pc[lose] pe[rl] perld[o] ped[it] po[p] pp[op] pre[serve] prev[ious] pro[mptfind] promptr[epl] prof[ile] profd[el] ps[earch] pt[ag] ptN[ext] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pub[lic] pw[d] py[thon] pyd[o] pyf[ile] py3 py3d[o] python3 py3f[ile] pyx pyxd[o] pythonx pyxf[ile] q[uit] quita[ll] qa[ll] r[ead] rec[over] red[o] redi[r] redr[aw] redraws[tatus] redrawt[abline] reg[isters] res[ize]
-syn keyword vimCommand contained ret[ab] retu[rn] rew[ind] ri[ght] rightb[elow] ru[ntime] rub[y] rubyd[o] rubyf[ile] rund[o] rv[iminfo] sN[ext] sa[rgument] sal[l] san[dbox] sav[eas] sb[uffer] sbN[ext] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbp[revious] sbr[ewind] sc[riptnames] scripte[ncoding] scriptv[ersion] scs[cope] setf[iletype] sf[ind] sfir[st] sh[ell] si[malt] sig[n] sil[ent] sl[eep] sla[st] sn[ext] so[urce] sor[t] sp[lit] spe[llgood] spelld[ump] spelli[nfo] spellr[epall] spellra[re] spellu[ndo] spellw[rong] spr[evious] sr[ewind] st[op] sta[g] star[tinsert] startg[replace] startr[eplace] stat[ic] stopi[nsert] stj[ump] sts[elect] sun[hide] sus[pend] sv[iew] sw[apname] synti[me] sync[bind] smi[le] t tN[ext] ta[g] tags tab tabc[lose] tabd[o] tabe[dit]
-syn keyword vimCommand contained tabf[ind] tabfir[st] tabm[ove] tabl[ast] tabn[ext] tabnew tabo[nly] tabp[revious] tabN[ext] tabr[ewind] tabs tc[d] tch[dir] tcl tcld[o] tclf[ile] te[aroff] ter[minal] tf[irst] th[row] thi[s] tj[ump] tl[ast] tn[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] ty[pe] u[ndo] undoj[oin] undol[ist] unh[ide] unl[et] unlo[ckvar] uns[ilent] up[date] v[global] ve[rsion] verb[ose] vert[ical] vi[sual] vie[w] vim[grep] vimgrepa[dd] vim9[cmd] viu[sage] vne[w] vs[plit] w[rite] wN[ext] wa[ll] wh[ile] wi[nsize] winc[md] wind[o] winp[os] wn[ext] wp[revious] wq wqa[ll] wu[ndo] wv[iminfo] x[it] xa[ll] xr[estore] y[ank] z dl dell delel deletl deletel dp dep delp delep deletp deletep a i
+syn keyword vimCommand contained abo[veleft] abs[tract] al[l] ar[gs] arga[dd] argd[elete] argdo argded[upe] arge[dit] argg[lobal] argl[ocal] argu[ment] as[cii] b[uffer] bN[ext] ba[ll] bad[d] balt bd[elete] bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bo[tright] bp[revious] br[ewind] brea[k] breaka[dd] breakd[el] breakl[ist] bro[wse] buffers bufd[o] bun[load] bw[ipeout] c[hange] cN[ext] cNf[ile] cabo[ve] cad[dbuffer] cadde[xpr] caddf[ile] caf[ter] cal[l] cb[uffer] cbe[fore] cbel[ow] cbo[ttom] cc ccl[ose] cd cdo ce[nter] cex[pr] cf[ile] cfd[o] cfir[st] cg[etfile] cgetb[uffer] cgete[xpr] chd[ir] changes che[ckpath] checkt[ime] chi[story] cl[ist] cla[st] class clo[se] cle[arjumps] cn[ext] cnew[er] cnf[ile] co[py] col[der] colo[rscheme] com[mand] comc[lear] comp[iler]
+syn keyword vimCommand contained con[tinue] conf[irm] cons[t] cope[n] cp[revious] cpf[ile] cq[uit] cr[ewind] cs[cope] cst[ag] cw[indow] d[elete] delm[arks] deb[ug] debugg[reedy] defc[ompile] defe[r] delc[ommand] delf[unction] di[splay] dif[fupdate] diffg[et] diffo[ff] diffp[atch] diffpu[t] diffs[plit] difft[his] dig[raphs] disa[ssemble] dj[ump] dli[st] dr[op] ds[earch] dsp[lit] e[dit] ea[rlier] el[se] elsei[f] em[enu] en[dif] endin[terface] endc[lass] ende[num] endfo[r] endt[ry] endw[hile] ene[w] enu[m] ev[al] ex exi[t] exp[ort] exu[sage] f[ile] files filet[ype] filt[er] fin[d] fina[l] finall[y] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] foldd[oopen] folddoc[losed] foldo[pen] for g[lobal] go[to] gr[ep] grepa[dd] gu[i] gv[im] h[elp] helpc[lose] helpf[ind] helpg[rep]
+syn keyword vimCommand contained helpt[ags] ha[rdcopy] hi[ghlight] hid[e] his[tory] ho[rizontal] if ij[ump] il[ist] imp[ort] int[ro] inte[rface] is[earch] isp[lit] j[oin] ju[mps] k kee[pmarks] keepj[umps] keepp[atterns] keepa[lt] l[ist] lN[ext] lNf[ile] la[st] lab[ove] lan[guage] lad[dexpr] laddb[uffer] laddf[ile] laf[ter] lat[er] lb[uffer] lbe[fore] lbel[ow] lbo[ttom] lc[d] lch[dir] lcl[ose] lcs[cope] ld[o] le[ft] lefta[bove] let lex[pr] leg[acy] lf[ile] lfd[o] lfir[st] lg[etfile] lgetb[uffer] lgete[xpr] lgr[ep] lgrepa[dd] lh[elpgrep] lhi[story] ll lla[st] lli[st] lmak[e] lne[xt] lnew[er] lnf[ile] lo[adview] loadk[eymap] loc[kmarks] lockv[ar] lol[der] lop[en] lp[revious] lpf[ile] lr[ewind] lt[ag] lua luad[o] luaf[ile] lv[imgrep] lvimgrepa[dd] lw[indow] ls m[ove]
+syn keyword vimCommand contained ma[rk] mak[e] marks mat[ch] menut[ranslate] mes[sages] mk[exrc] mks[ession] mksp[ell] mkv[imrc] mkvie[w] mod[e] mz[scheme] mzf[ile] n[ext] nb[key] nbc[lose] nbs[tart] noa[utocmd] noh[lsearch] nos[wapfile] nu[mber] o[pen] ol[dfiles] on[ly] opt[ions] ow[nsyntax] p[rint] pa[ckadd] packl[oadall] pc[lose] pe[rl] perld[o] ped[it] po[p] pp[op] pre[serve] prev[ious] pro[mptfind] promptr[epl] prof[ile] profd[el] ps[earch] pt[ag] ptN[ext] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pub[lic] pw[d] py[thon] pyd[o] pyf[ile] py3 py3d[o] python3 py3f[ile] pyx pyxd[o] pythonx pyxf[ile] q[uit] quita[ll] qa[ll] r[ead] rec[over] red[o] redi[r] redr[aw] redraws[tatus] redrawt[abline] reg[isters] res[ize] ret[ab] retu[rn]
+syn keyword vimCommand contained rew[ind] ri[ght] rightb[elow] ru[ntime] rub[y] rubyd[o] rubyf[ile] rund[o] rv[iminfo] sN[ext] sa[rgument] sal[l] san[dbox] sav[eas] sb[uffer] sbN[ext] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbp[revious] sbr[ewind] sc[riptnames] scripte[ncoding] scriptv[ersion] scs[cope] setf[iletype] sf[ind] sfir[st] sh[ell] si[malt] sig[n] sil[ent] sla[st] sn[ext] so[urce] sor[t] sp[lit] spe[llgood] spelld[ump] spelli[nfo] spellr[epall] spellra[re] spellu[ndo] spellw[rong] spr[evious] sr[ewind] st[op] sta[g] star[tinsert] startg[replace] startr[eplace] stat[ic] stopi[nsert] stj[ump] sts[elect] sun[hide] sus[pend] sv[iew] sw[apname] synti[me] sync[bind] smi[le] t tN[ext] ta[g] tags tab tabc[lose] tabd[o] tabe[dit] tabf[ind] tabfir[st]
+syn keyword vimCommand contained tabm[ove] tabl[ast] tabn[ext] tabnew tabo[nly] tabp[revious] tabN[ext] tabr[ewind] tabs tc[d] tch[dir] tcl tcld[o] tclf[ile] te[aroff] ter[minal] tf[irst] thi[s] tj[ump] tl[ast] tn[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] ty[pe] u[ndo] undoj[oin] undol[ist] unh[ide] unl[et] unlo[ckvar] uns[ilent] up[date] v[global] ve[rsion] verb[ose] vert[ical] vi[sual] vie[w] vim[grep] vimgrepa[dd] vim9[cmd] viu[sage] vne[w] vs[plit] w[rite] wN[ext] wa[ll] wh[ile] wi[nsize] winc[md] wind[o] winp[os] wn[ext] wp[revious] wq wqa[ll] wu[ndo] wv[iminfo] x[it] xa[ll] xr[estore] y[ank] z dl dell delel deletl deletel dp dep delp delep deletp deletep a i
syn keyword vimCommand contained 2mat[ch] 3mat[ch]
@@ -69,7 +69,7 @@ syn keyword vimOption contained invtf invttyfast invudf invundofile invvb invvis
" termcap codes (which can also be set) {{{2
" GEN_SYN_VIM: vimOption term output code, START_STR='syn keyword vimOption contained', END_STR=''
-syn keyword vimOption contained t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce t_CF t_cl t_cm t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC t_EI t_fs t_fd t_fe t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RF t_RB t_RC t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_Si t_so t_SR t_sr t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us t_ut t_vb t_ve t_vi t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u
+syn keyword vimOption contained t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce t_CF t_cl t_cm t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC t_EI t_fs t_fd t_fe t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd t_op t_RF t_RB t_RC t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI t_Si t_so t_SR t_sr t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us t_ut t_vb t_ve t_vi t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u t_xo
" term key codes
syn keyword vimOption contained t_F1 t_F2 t_F3 t_F4 t_F5 t_F6 t_F7 t_F8 t_F9 t_k1 t_K1 t_k2 t_k3 t_K3 t_k4 t_K4 t_k5 t_K5 t_k6 t_K6 t_k7 t_K7 t_k8 t_K8 t_k9 t_K9 t_KA t_kb t_kB t_KB t_KC t_kd t_kD t_KD t_KE t_KF t_KG t_kh t_KH t_kI t_KI t_KJ t_KK t_kl t_KL t_kN t_kP t_kr t_ku
syn match vimOption contained "t_%1"
@@ -98,19 +98,21 @@ syn keyword vimGroup contained Comment Constant String Character Number Boolean
" Default highlighting groups {{{2
" GEN_SYN_VIM: vimHLGroup, START_STR='syn keyword vimHLGroup contained', END_STR=''
-syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit VisualNOS DiffText PmenuSbar TabLineSel TabLineFill Cursor lCursor QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuExtra PmenuExtraSel Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn Conceal MatchParen StatusLineTerm StatusLineTermNC ToolbarLine ToolbarButton Menu Tooltip Scrollbar CursorIM LineNrAbove LineNrBelow
+syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit VisualNOS DiffText PmenuSbar TabLineSel TabLineFill Cursor lCursor QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuMatch PmenuMatchSel PmenuExtra PmenuExtraSel Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn MatchParen StatusLineTerm StatusLineTermNC ToolbarLine ToolbarButton Menu Tooltip Scrollbar CursorIM LineNrAbove LineNrBelow
+syn match vimHLGroup contained "\<Conceal\>"
syn case match
" Function Names {{{2
" GEN_SYN_VIM: vimFuncName, START_STR='syn keyword vimFuncName contained', END_STR=''
syn keyword vimFuncName contained abs acos add and append appendbufline argc argidx arglistid argv asin assert_beeps assert_equal assert_equalfile assert_exception assert_fails assert_false assert_inrange assert_match assert_nobeep assert_notequal assert_notmatch assert_report assert_true atan atan2 autocmd_add autocmd_delete autocmd_get balloon_gettext balloon_show balloon_split blob2list browse browsedir bufadd bufexists buflisted bufload bufloaded bufname bufnr bufwinid bufwinnr byte2line byteidx byteidxcomp call ceil ch_canread ch_close ch_close_in ch_evalexpr ch_evalraw ch_getbufnr ch_getjob ch_info ch_log ch_logfile ch_open ch_read ch_readblob ch_readraw ch_sendexpr ch_sendraw ch_setoptions ch_status changenr char2nr charclass charcol charidx chdir cindent
-syn keyword vimFuncName contained clearmatches col complete complete_add complete_check complete_info confirm copy cos cosh count cscope_connection cursor debugbreak deepcopy delete deletebufline did_filetype diff diff_filler diff_hlID digraph_get digraph_getlist digraph_set digraph_setlist echoraw empty environ err_teapot escape eval eventhandler executable execute exepath exists exists_compiled exp expand expandcmd extend extendnew feedkeys filereadable filewritable filter finddir findfile flatten flattennew float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreach foreground fullcommand funcref function garbagecollect get getbufinfo getbufline getbufoneline getbufvar getcellwidths getchangelist getchar getcharmod
-syn keyword vimFuncName contained getcharpos getcharsearch getcharstr getcmdcompltype getcmdline getcmdpos getcmdscreenpos getcmdtype getcmdwintype getcompletion getcurpos getcursorcharpos getcwd getenv getfontname getfperm getfsize getftime getftype getimstatus getjumplist getline getloclist getmarklist getmatches getmousepos getmouseshape getpid getpos getqflist getreg getreginfo getregion getregtype getscriptinfo gettabinfo gettabvar gettabwinvar gettagstack gettext getwininfo getwinpos getwinposx getwinposy getwinvar glob glob2regpat globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlID hlexists hlget hlset hostname iconv indent index indexof input inputdialog inputlist inputrestore inputsave inputsecret insert instanceof interrupt
-syn keyword vimFuncName contained invert isabsolutepath isdirectory isinf islocked isnan items job_getchannel job_info job_setoptions job_start job_status job_stop join js_decode js_encode json_decode json_encode keys keytrans len libcall libcallnr line line2byte lispindent list2blob list2str listener_add listener_flush listener_remove localtime log log10 luaeval map maparg mapcheck maplist mapnew mapset match matchadd matchaddpos matcharg matchbufline matchdelete matchend matchfuzzy matchfuzzypos matchlist matchstr matchstrlist matchstrpos max menu_info min mkdir mode mzeval nextnonblank nr2char or pathshorten perleval popup_atcursor popup_beval popup_clear popup_close popup_create popup_dialog popup_filter_menu popup_filter_yesno popup_findecho popup_findinfo
-syn keyword vimFuncName contained popup_findpreview popup_getoptions popup_getpos popup_hide popup_list popup_locate popup_menu popup_move popup_notification popup_setoptions popup_settext popup_show pow prevnonblank printf prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex readfile reduce reg_executing reg_recording reltime reltimefloat reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remote_startserver remove rename repeat resolve reverse round rubyeval screenattr screenchar screenchars
-syn keyword vimFuncName contained screencol screenpos screenrow screenstring search searchcount searchdecl searchpair searchpairpos searchpos server2client serverlist setbufline setbufvar setcellwidths setcharpos setcharsearch setcmdline setcmdpos setcursorcharpos setenv setfperm setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar settagstack setwinvar sha256 shellescape shiftwidth sign_define sign_getdefined sign_getplaced sign_jump sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist simplify sin sinh slice sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2float str2list str2nr strcharlen strcharpart strchars strdisplaywidth strftime strgetchar stridx
-syn keyword vimFuncName contained string strlen strpart strptime strridx strtrans strutf16len strwidth submatch substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob term_getline term_getscrolled term_getsize term_getstatus term_gettitle term_gettty term_list term_scrape term_sendkeys term_setansicolors term_setapi term_setkill term_setrestore term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir test_feedinput test_garbagecollect_now test_garbagecollect_soon test_getvalue test_gui_event test_ignore_error
-syn keyword vimFuncName contained test_mswin_event test_null_blob test_null_channel test_null_dict test_null_function test_null_job test_null_list test_null_partial test_null_string test_option_not_set test_override test_refcount test_setmouse test_settime test_srand_seed test_unknown test_void timer_info timer_pause timer_start timer_stop timer_stopall tolower toupper tr trim trunc type typename undofile undotree uniq utf16idx values virtcol virtcol2col visualmode wildmenumode win_execute win_findbuf win_getid win_gettype win_gotoid win_id2tabwin win_id2win win_move_separator win_move_statusline win_screenpos win_splitmove winbufnr wincol windowsversion winheight winlayout winline winnr winrestcmd winrestview winsaveview winwidth wordcount writefile xor
+syn keyword vimFuncName contained clearmatches col complete complete_add complete_check complete_info confirm copy cos cosh count cscope_connection cursor debugbreak deepcopy delete deletebufline did_filetype diff diff_filler diff_hlID digraph_get digraph_getlist digraph_set digraph_setlist echoraw empty environ err_teapot escape eval eventhandler executable execute exepath exists exists_compiled exp expand expandcmd extend extendnew feedkeys filecopy filereadable filewritable filter finddir findfile flatten flattennew float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreach foreground fullcommand funcref function garbagecollect get getbufinfo getbufline getbufoneline getbufvar getcellwidths getchangelist getchar
+syn keyword vimFuncName contained getcharmod getcharpos getcharsearch getcharstr getcmdcompltype getcmdline getcmdpos getcmdscreenpos getcmdtype getcmdwintype getcompletion getcurpos getcursorcharpos getcwd getenv getfontname getfperm getfsize getftime getftype getimstatus getjumplist getline getloclist getmarklist getmatches getmousepos getmouseshape getpid getpos getqflist getreg getreginfo getregion getregionpos getregtype getscriptinfo gettabinfo gettabvar gettabwinvar gettagstack gettext getwininfo getwinpos getwinposx getwinposy getwinvar glob glob2regpat globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlID hlexists hlget hlset hostname iconv indent index indexof input inputdialog inputlist inputrestore inputsave inputsecret insert
+syn keyword vimFuncName contained instanceof interrupt invert isabsolutepath isdirectory isinf islocked isnan items job_getchannel job_info job_setoptions job_start job_status job_stop join js_decode js_encode json_decode json_encode keys keytrans len libcall libcallnr line line2byte lispindent list2blob list2str listener_add listener_flush listener_remove localtime log log10 luaeval map maparg mapcheck maplist mapnew mapset match matchadd matchaddpos matcharg matchbufline matchdelete matchend matchfuzzy matchfuzzypos matchlist matchstr matchstrlist matchstrpos max menu_info min mkdir mode mzeval nextnonblank nr2char or pathshorten perleval popup_atcursor popup_beval popup_clear popup_close popup_create popup_dialog popup_filter_menu popup_filter_yesno popup_findecho
+syn keyword vimFuncName contained popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide popup_list popup_locate popup_menu popup_move popup_notification popup_setoptions popup_settext popup_show pow prevnonblank printf prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex readfile reduce reg_executing reg_recording reltime reltimefloat reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remote_startserver remove rename repeat resolve reverse round rubyeval screenattr screenchar
+syn keyword vimFuncName contained screenchars screencol screenpos screenrow screenstring search searchcount searchdecl searchpair searchpairpos searchpos server2client serverlist setbufline setbufvar setcellwidths setcharpos setcharsearch setcmdline setcmdpos setcursorcharpos setenv setfperm setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar settagstack setwinvar sha256 shellescape shiftwidth sign_define sign_getdefined sign_getplaced sign_jump sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist simplify sin sinh slice sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2float str2list str2nr strcharlen strcharpart strchars strdisplaywidth strftime
+syn keyword vimFuncName contained strgetchar stridx string strlen strpart strptime strridx strtrans strutf16len strwidth submatch substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob term_getline term_getscrolled term_getsize term_getstatus term_gettitle term_gettty term_list term_scrape term_sendkeys term_setansicolors term_setapi term_setkill term_setrestore term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir test_feedinput test_garbagecollect_now test_garbagecollect_soon test_getvalue test_gui_event
+syn keyword vimFuncName contained test_ignore_error test_mswin_event test_null_blob test_null_channel test_null_dict test_null_function test_null_job test_null_list test_null_partial test_null_string test_option_not_set test_override test_refcount test_setmouse test_settime test_srand_seed test_unknown test_void timer_info timer_pause timer_start timer_stop timer_stopall tolower toupper tr trim trunc type typename undofile undotree uniq utf16idx values virtcol virtcol2col visualmode wildmenumode win_execute win_findbuf win_getid win_gettype win_gotoid win_id2tabwin win_id2win win_move_separator win_move_statusline win_screenpos win_splitmove winbufnr wincol windowsversion winheight winlayout winline winnr winrestcmd winrestview winsaveview winwidth wordcount writefile
+syn keyword vimFuncName contained xor
"--- syntax here and above generated by mkvimvim ---
" Special Vim Highlighting (not automatic) {{{1
@@ -211,7 +213,7 @@ syn match vimNumber '\%(^\|\A\)\zs#\x\{6}' skipwhite nextgroup=vimGlobal,vimSub
syn case match
" All vimCommands are contained by vimIsCommand. {{{2
-syn cluster vimCmdList contains=vimAbb,vimAddress,vimAutoCmd,vimAugroup,vimBehave,vimDef,@vimEcho,vimEnddef,vimEndfunction,vimExecute,vimIsCommand,vimExtCmd,vimFor,vimFunction,vimGlobal,vimHighlight,vimLet,vimMap,vimMark,vimNotFunc,vimNorm,vimSet,vimSyntax,vimUnlet,vimUnmap,vimUserCmd,vimMenu,vimMenutranslate
+syn cluster vimCmdList contains=vimAbb,vimAddress,vimAutoCmd,vimAugroup,vimBehave,vimCatch,vimDef,@vimEcho,vimEnddef,vimEndfunction,vimExecute,vimIsCommand,vimExtCmd,vimFor,vimFunction,vimGlobal,vimHighlight,vimLet,vimMap,vimMark,vimNotFunc,vimNorm,vimSet,vimSleep,vimSyntax,vimThrow,vimUnlet,vimUnmap,vimUserCmd,vimMenu,vimMenutranslate
syn match vimCmdSep "[:|]\+" skipwhite nextgroup=@vimCmdList,vimSubst1
syn match vimIsCommand "\<\%(\h\w*\|[23]mat\%[ch]\)\>" contains=vimCommand
syn match vimVar contained "\<\h[a-zA-Z0-9#_]*\>"
@@ -242,6 +244,11 @@ syn match vimBehave "\<be\%[have]\>" nextgroup=vimBehaveBang,vimBehaveModel,vi
syn match vimBehaveBang contained "\a\@1<=!" nextgroup=vimBehaveModel skipwhite
syn keyword vimBehaveModel contained mswin xterm
+" Exception Handling {{{2
+syn keyword vimThrow th[row] skipwhite nextgroup=@vimExprList
+syn keyword vimCatch cat[ch] skipwhite nextgroup=vimCatchPattern
+syn region vimCatchPattern contained matchgroup=Delimiter start="\z([!#$%&'()*+,-./:;<=>?@[\]^_`{}~]\)" skip="\\\\\|\\\z1" end="\z1" contains=@vimSubstList oneline
+
" Filetypes {{{2
" =========
syn match vimFiletype "\<filet\%[ype]\(\s\+\I\i*\)*" skipwhite contains=vimFTCmd,vimFTOption,vimFTError
@@ -406,7 +413,9 @@ syn region vimUserCmdBlock contained matchgroup=vimSep start="{" end="}" contain
" Lower Priority Comments: after some vim commands... {{{2
" =======================
-syn region vimCommentString contained oneline start='\S\s\+"'ms=e end='"'
+if get(g:, "vimsyn_comment_strings", 1)
+ syn region vimCommentString contained oneline start='\S\s\+"'ms=e end='"'
+endif
if s:vim9script
syn match vimComment excludenl +\s"[^\-:.%#=*].*$+lc=1 contains=@vimCommentGroup,vimCommentString contained
@@ -475,12 +484,10 @@ syn match vimStringInterpolationBrace contained "}}"
syn cluster vimSubstList contains=vimPatSep,vimPatRegion,vimPatSepErr,vimSubstTwoBS,vimSubstRange,vimNotation
syn cluster vimSubstRepList contains=vimSubstSubstr,vimSubstTwoBS,vimNotation
syn cluster vimSubstList add=vimCollection
-syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>[\"#|]\@!" nextgroup=vimSubstPat
-syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)_\@=" nextgroup=vimSubstPat
-syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#" nextgroup=vimSubstPat
-syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>[\"#|]\@!" nextgroup=vimSubstPat
-syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)_\@=" nextgroup=vimSubstPat
-syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#" nextgroup=vimSubstPat
+syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>" skipwhite nextgroup=vimSubstPat
+syn match vimSubst "^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)[_#]\@=" skipwhite nextgroup=vimSubstPat
+syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>" skipwhite nextgroup=vimSubstPat
+syn match vimSubst1 contained "\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)[_#]\@=" skipwhite nextgroup=vimSubstPat
" TODO: Vim9 illegal separators for abbreviated :s form are [-.:], :su\%[...] required
" : # is allowed but "not recommended" (see :h pattern-delimiter)
syn region vimSubstPat contained matchgroup=vimSubstDelim start="\z([!#$%&'()*+,-./:;<=>?@[\]^_`{}~]\)"rs=s+1 skip="\\\\\|\\\z1" end="\z1"re=e-1,me=e-1 contains=@vimSubstList nextgroup=vimSubstRep4 oneline
@@ -493,6 +500,10 @@ syn match vimSubstTwoBS contained "\\\\"
syn match vimSubstFlagErr contained "[^< \t\r|]\+" contains=vimSubstFlags
syn match vimSubstFlags contained "[&cegiIlnpr#]\+"
+" Vi compatibility
+syn match vimSubstDelim contained "\\"
+syn match vimSubstPat contained "\\\ze[/?&]" contains=vimSubstDelim nextgroup=vimSubstRep4
+
" 'String': {{{2
syn match vimString "[^(,]'[^']\{-}\zs'"
@@ -688,6 +699,12 @@ syn match vimNotFunc "\<if\>\|\<el\%[seif]\>\|\<retu\%[rn]\>\|\<while\>" skipwhi
syn match vimNorm "\<norm\%[al]!\=" skipwhite nextgroup=vimNormCmds
syn match vimNormCmds contained ".*$"
+" Sleep: {{{2
+" =====
+syn keyword vimSleep sl[eep] skipwhite nextgroup=vimSleepBang,vimSleepArg
+syn match vimSleepBang contained "\a\@1<=!" skipwhite nextgroup=vimSleepArg
+syn match vimSleepArg contained "\<\%(\d\+\)\=m\=\>"
+
" Syntax: {{{2
"=======
syn match vimGroupList contained "[^[:space:],]\+\%(\s*,\s*[^[:space:],]\+\)*" contains=vimGroupSpecial
@@ -853,16 +870,23 @@ syn match vimCtrlChar "[- -]"
" Beginners - Patterns that involve ^ {{{2
" =========
if s:vim9script
- syn match vimLineComment +^[ \t:]*".*$+ contains=@vimCommentGroup,vimCommentString,vimCommentTitle contained
- syn match vim9LineComment +^[ \t:]*#.*$+ contains=@vimCommentGroup,vimCommentString,vim9CommentTitle
+ syn region vim9LineComment start=+^[ \t:]*\zs#.*$+ skip=+\n\s*\\\|\n\s*#\\ + end="$" contains=@vimCommentGroup,vimCommentString,vim9CommentTitle
+ syn region vimLineComment start=+^[ \t:]*\zs".*$+ skip=+\n\s*\\\|\n\s*"\\ + end="$" contains=@vimCommentGroup,vimCommentString,vimCommentTitle contained
else
- syn match vimLineComment +^[ \t:]*".*$+ contains=@vimCommentGroup,vimCommentString,vimCommentTitle
- syn match vim9LineComment +^[ \t:]*#.*$+ contains=@vimCommentGroup,vimCommentString,vim9CommentTitle contained
+ syn region vimLineComment start=+^[ \t:]*\zs".*$+ skip=+\n\s*\\\|\n\s*"\\ + end="$" contains=@vimCommentGroup,vimCommentString,vimCommentTitle
+ syn region vim9LineComment start=+^[ \t:]*\zs#.*$+ skip=+\n\s*\\\|\n\s*#\\ + end="$" contains=@vimCommentGroup,vimCommentString,vim9CommentTitle contained
endif
syn match vimCommentTitle '"\s*\%([sS]:\|\h\w*#\)\=\u\w*\(\s\+\u\w*\)*:'hs=s+1 contained contains=vimCommentTitleLeader,vimTodo,@vimCommentGroup
syn match vim9CommentTitle '#\s*\%([sS]:\|\h\w*#\)\=\u\w*\(\s\+\u\w*\)*:'hs=s+1 contained contains=vim9CommentTitleLeader,vimTodo,@vimCommentGroup
+
+" allowed anywhere in the file
+if !s:vim9script
+ syn match vimShebangError "^\s*\zs#!.*" display
+endif
+syn match vimShebang "\%^#!.*" display
+
syn match vimContinue "^\s*\zs\\"
-syn match vimContinueComment '^\s*\zs["#]\\ .*' contained
+syn match vimContinueComment '^\s*\zs["#]\\ .*'
syn cluster vimContinue contains=vimContinue,vimContinueComment
syn region vimString start="^\s*\\\z(['"]\)" skip='\\\\\|\\\z1' end="\z1" oneline keepend contains=@vimStringGroup,vimContinue
syn match vimCommentTitleLeader '"\s\+'ms=s+1 contained
@@ -1087,6 +1111,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimHiCtermError vimError
hi def link vimHiKeyError vimError
hi def link vimMapModErr vimError
+ hi def link vimShebangError vimError
hi def link vimSubstFlagErr vimError
hi def link vimSynCaseError vimError
hi def link vimSynFoldMethodError vimError
@@ -1107,6 +1132,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimBehaveModel vimBehave
hi def link vimBehave vimCommand
hi def link vimBracket Delimiter
+ hi def link vimCatch vimCommand
hi def link vimCmplxRepeat SpecialChar
hi def link vimCommand Statement
hi def link vimComment Comment
@@ -1224,6 +1250,10 @@ if !exists("skip_vim_syntax_inits")
hi def link vimSetSep Statement
hi def link vimSetString vimString
hi def link vim9Vim9Script vimCommand
+ hi def link vimShebang PreProc
+ hi def link vimSleep vimCommand
+ hi def link vimSleepArg Constant
+ hi def link vimSleepBang vimBang
hi def link vimSpecFile Identifier
hi def link vimSpecFileMod vimSpecFile
hi def link vimSpecial Type
@@ -1264,6 +1294,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimSynReg Type
hi def link vimSyntax vimCommand
hi def link vimSynType vimSpecial
+ hi def link vimThrow vimCommand
hi def link vimTodo Todo
hi def link vimType Type
hi def link vimUnlet vimCommand
diff --git a/src/GvimExt/gvimext.cpp b/src/GvimExt/gvimext.cpp
index e58b142..f98423c 100644
--- a/src/GvimExt/gvimext.cpp
+++ b/src/GvimExt/gvimext.cpp
@@ -55,9 +55,11 @@ getGvimName(char *name, int runtime)
HKEY keyhandle;
DWORD hlen;
- // Get the location of gvim from the registry.
+ // Get the location of gvim from the registry. Try
+ // HKEY_CURRENT_USER first, then fall back to HKEY_LOCAL_MACHINE if
+ // not found.
name[0] = 0;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
+ if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Vim\\Gvim", 0,
KEY_READ, &keyhandle) == ERROR_SUCCESS)
{
hlen = BUFSIZE;
@@ -69,6 +71,19 @@ getGvimName(char *name, int runtime)
RegCloseKey(keyhandle);
}
+ if ((name[0] == 0) &&
+ (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
+ KEY_READ, &keyhandle) == ERROR_SUCCESS))
+ {
+ hlen = BUFSIZE;
+ if (RegQueryValueEx(keyhandle, "path", 0, NULL, (BYTE *)name, &hlen)
+ != ERROR_SUCCESS)
+ name[0] = 0;
+ else
+ name[hlen] = 0;
+ RegCloseKey(keyhandle);
+ }
+
// Registry didn't work, use the search path.
if (name[0] == 0)
strcpy(name, searchpath((char *)"gvim.exe"));
diff --git a/src/Make_ami.mak b/src/Make_ami.mak
index 9e9ebe3..09cdd3c 100644
--- a/src/Make_ami.mak
+++ b/src/Make_ami.mak
@@ -114,6 +114,7 @@ SRC += \
float.c \
fold.c \
getchar.c \
+ gc.c \
hardcopy.c \
hashtab.c \
help.c \
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index 7afb6e0..20ed903 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -797,6 +797,7 @@ OBJ = \
$(OUTDIR)/float.o \
$(OUTDIR)/fold.o \
$(OUTDIR)/getchar.o \
+ $(OUTDIR)/gc.o \
$(OUTDIR)/gui_xim.o \
$(OUTDIR)/hardcopy.o \
$(OUTDIR)/hashtab.o \
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index 4d03a72..e58814b 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -718,6 +718,7 @@ OBJ = \
$(OUTDIR)\float.obj \
$(OUTDIR)\fold.obj \
$(OUTDIR)\getchar.obj \
+ $(OUTDIR)\gc.obj \
$(OUTDIR)\gui_xim.obj \
$(OUTDIR)\hardcopy.obj \
$(OUTDIR)\hashtab.obj \
@@ -1575,6 +1576,8 @@ $(OUTDIR)/fold.obj: $(OUTDIR) fold.c $(INCL)
$(OUTDIR)/getchar.obj: $(OUTDIR) getchar.c $(INCL)
+$(OUTDIR)/gc.obj: $(OUTDIR) gc.c $(INCL)
+
$(OUTDIR)/gui_xim.obj: $(OUTDIR) gui_xim.c $(INCL)
$(OUTDIR)/hardcopy.obj: $(OUTDIR) hardcopy.c $(INCL) version.h
@@ -1915,6 +1918,7 @@ proto.h: \
proto/findfile.pro \
proto/float.pro \
proto/getchar.pro \
+ proto/gc.pro \
proto/gui_xim.pro \
proto/hardcopy.pro \
proto/hashtab.pro \
diff --git a/src/Make_vms.mms b/src/Make_vms.mms
index f050c9d..559c2f8 100644
--- a/src/Make_vms.mms
+++ b/src/Make_vms.mms
@@ -369,6 +369,7 @@ SRC = \
float.c \
fold.c \
getchar.c \
+ gc.c \
gui_xim.c \
hardcopy.c \
hashtab.c \
@@ -500,6 +501,7 @@ OBJ = \
float.obj \
fold.obj \
getchar.obj \
+ gc.obj \
gui_xim.obj \
hardcopy.obj \
hashtab.obj \
@@ -942,6 +944,10 @@ getchar.obj : getchar.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \
gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
errors.h globals.h
+gc.obj : gc.c vim.h [.auto]config.h feature.h os_unix.h \
+ ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \
+ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
+ errors.h globals.h
gui_xim.obj : gui_xim.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \
gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
diff --git a/src/Makefile b/src/Makefile
index 29f63dc..71578eb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1520,6 +1520,7 @@ BASIC_SRC = \
float.c \
fold.c \
getchar.c \
+ gc.c \
gui_xim.c \
hardcopy.c \
hashtab.c \
@@ -1682,6 +1683,7 @@ OBJ_COMMON = \
objects/float.o \
objects/fold.o \
objects/getchar.o \
+ objects/gc.o \
objects/gui_xim.o \
objects/hardcopy.o \
objects/hashtab.o \
@@ -1860,6 +1862,7 @@ PRO_AUTO = \
float.pro \
fold.pro \
getchar.pro \
+ gc.pro \
gui_xim.pro \
gui_beval.pro \
hardcopy.pro \
@@ -2340,7 +2343,7 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(VIMTARGET) $(DEST_RT) \
$(DEST_HELP) $(DEST_PRINT) $(DEST_COL) \
$(DEST_SYN) $(DEST_SYN)/modula2 $(DEST_SYN)/modula2/opt $(DEST_SYN)/shared \
$(DEST_IND) $(DEST_FTP) \
- $(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/zig \
+ $(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml \
$(DEST_AUTO)/rust $(DEST_AUTO)/cargo \
$(DEST_IMPORT) $(DEST_IMPORT)/dist \
$(DEST_PLUG) $(DEST_TUTOR) $(DEST_SPELL) $(DEST_COMP)
@@ -2427,8 +2430,6 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(VIMTARGET) $(DEST_RT) \
cd $(DEST_AUTO)/dist; chmod $(HELPMOD) *.vim
cd $(AUTOSOURCE)/xml; $(INSTALL_DATA) *.vim $(DEST_AUTO)/xml
cd $(DEST_AUTO)/xml; chmod $(HELPMOD) *.vim
- cd $(AUTOSOURCE)/zig; $(INSTALL_DATA) *.vim $(DEST_AUTO)/zig
- cd $(DEST_AUTO)/zig; chmod $(HELPMOD) *.vim
cd $(AUTOSOURCE)/cargo; $(INSTALL_DATA) *.vim $(DEST_AUTO)/cargo
cd $(DEST_AUTO)/cargo; chmod $(HELPMOD) *.vim
cd $(AUTOSOURCE)/rust; $(INSTALL_DATA) *.vim $(DEST_AUTO)/rust
@@ -2673,7 +2674,7 @@ $(DESTDIR)$(exec_prefix) $(DEST_BIN) \
$(DEST_IND) $(DEST_FTP) \
$(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) $(DEST_MACRO) \
$(DEST_PACK) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \
- $(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/zig \
+ $(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml \
$(DEST_AUTO)/cargo $(DEST_AUTO)/rust \
$(DEST_IMPORT) $(DEST_IMPORT)/dist $(DEST_PLUG):
$(MKDIR_P) $@
@@ -2865,10 +2866,10 @@ uninstall_runtime:
-rmdir $(DEST_SYN) $(DEST_IND)
-rm -rf $(DEST_FTP)/*.vim $(DEST_FTP)/README.txt $(DEST_FTP)/logtalk.dict
-rm -f $(DEST_AUTO)/*.vim $(DEST_AUTO)/README.txt
- -rm -f $(DEST_AUTO)/dist/*.vim $(DEST_AUTO)/xml/*.vim $(DEST_AUTO)/zig/*.vim $(DEST_AUTO)/cargo/*.vim $(DEST_AUTO)/rust/*.vim
+ -rm -f $(DEST_AUTO)/dist/*.vim $(DEST_AUTO)/xml/*.vim $(DEST_AUTO)/cargo/*.vim $(DEST_AUTO)/rust/*.vim
-rm -f $(DEST_IMPORT)/dist/*.vim
-rm -f $(DEST_PLUG)/*.vim $(DEST_PLUG)/README.txt
- -rmdir $(DEST_FTP) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/zig $(DEST_AUTO)/cargo $(DEST_AUTO)/rust $(DEST_AUTO)
+ -rmdir $(DEST_FTP) $(DEST_AUTO)/dist $(DEST_AUTO)/xml $(DEST_AUTO)/cargo $(DEST_AUTO)/rust $(DEST_AUTO)
-rmdir $(DEST_IMPORT)/dist $(DEST_IMPORT)
-rmdir $(DEST_PLUG) $(DEST_RT)
# This will fail when other Vim versions are installed, no worries.
@@ -3224,6 +3225,9 @@ objects/fold.o: fold.c
objects/getchar.o: getchar.c
$(CCC) -o $@ getchar.c
+objects/gc.o: gc.c
+ $(CCC) -o $@ gc.c
+
objects/hardcopy.o: hardcopy.c
$(CCC) -o $@ hardcopy.c
@@ -3875,6 +3879,11 @@ objects/getchar.o: getchar.c vim.h protodef.h auto/config.h feature.h os_unix.h
proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \
libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \
globals.h errors.h
+objects/gc.o: gc.c vim.h protodef.h auto/config.h feature.h os_unix.h \
+ auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
+ proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \
+ libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \
+ globals.h errors.h
objects/gui_xim.o: gui_xim.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \
diff --git a/src/README.md b/src/README.md
index f3806d2..4042988 100644
--- a/src/README.md
+++ b/src/README.md
@@ -49,6 +49,7 @@ filepath.c | dealing with file names and paths
findfile.c | search for files in 'path'
fold.c | folding
getchar.c | getting characters and key mapping
+gc.c | garbage collection
help.c | vim help related functions
highlight.c | syntax highlighting
indent.c | text indentation
diff --git a/src/auto/configure b/src/auto/configure
index 0e0cf8e..98b9580 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -6502,11 +6502,13 @@ printf "%s\n" "$vi_cv_perl_xsubpp" >&6; }
-e 's/-flto\(=auto\)\? //' \
-e 's/-W[^ ]*//g' \
-e 's/-D_FORTIFY_SOURCE=.//g'`
- perllibs=`cd $srcdir; $vi_cv_path_perl -MExtUtils::Embed -e 'ldopts' | \
+ perllibs=`cd $srcdir; $vi_cv_path_perl -MExtUtils::Embed -e 'ldopts' | \
sed -e '/Warning/d' -e '/Note (probably harmless)/d' \
+ -e 's/-specs=[^ ]*//g' \
-e 's/-bE:perl.exp//' -e 's/-lc //'`
- perlldflags=`cd $srcdir; $vi_cv_path_perl -MExtUtils::Embed \
- -e 'ccdlflags' | sed -e 's/-bE:perl.exp//'`
+ perlldflags=`cd $srcdir; $vi_cv_path_perl -MExtUtils::Embed \
+ -e 'ccdlflags' | sed -e 's/-bE:perl.exp//' \
+ -e 's/-specs=[^ ]*//g' `
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compile and link flags for Perl are sane" >&5
printf %s "checking if compile and link flags for Perl are sane... " >&6; }
@@ -11405,55 +11407,6 @@ printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
-ac_fn_c_check_header_compile "$LINENO" "elf.h" "ac_cv_header_elf_h" "$ac_includes_default"
-if test "x$ac_cv_header_elf_h" = xyes
-then :
- HAS_ELF=1
-fi
-
-if test "$HAS_ELF" = 1; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lelf" >&5
-printf %s "checking for main in -lelf... " >&6; }
-if test ${ac_cv_lib_elf_main+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lelf $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-int
-main (void)
-{
-return main ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_lib_elf_main=yes
-else $as_nop
- ac_cv_lib_elf_main=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_elf_main" >&5
-printf "%s\n" "$ac_cv_lib_elf_main" >&6; }
-if test "x$ac_cv_lib_elf_main" = xyes
-then :
- printf "%s\n" "#define HAVE_LIBELF 1" >>confdefs.h
-
- LIBS="-lelf $LIBS"
-
-fi
-
-fi
-
ac_header_dirent=no
for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
as_ac_Header=`printf "%s\n" "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
diff --git a/src/autocmd.c b/src/autocmd.c
index bce57cb..8380f8a 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -3391,6 +3391,9 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv)
{
char_u *group_name;
+ if (ap->pat == NULL) // pattern has been removed
+ continue;
+
if (group != AUGROUP_ALL && group != ap->group)
continue;
diff --git a/src/buffer.c b/src/buffer.c
index 58e9718..cbec9b9 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2429,6 +2429,7 @@ free_buf_options(
clear_string_option(&buf->b_p_lop);
clear_string_option(&buf->b_p_cinsd);
clear_string_option(&buf->b_p_cinw);
+ clear_string_option(&buf->b_p_cot);
clear_string_option(&buf->b_p_cpt);
#ifdef FEAT_COMPL_FUNC
clear_string_option(&buf->b_p_cfu);
diff --git a/src/bufwrite.c b/src/bufwrite.c
index bf79ad5..c9d9875 100644
--- a/src/bufwrite.c
+++ b/src/bufwrite.c
@@ -690,7 +690,7 @@ buf_write(
int write_undo_file = FALSE;
context_sha256_T sha_ctx;
#endif
- unsigned int bkc = get_bkc_value(buf);
+ unsigned int bkc = get_bkc_flags(buf);
pos_T orig_start = buf->b_op_start;
pos_T orig_end = buf->b_op_end;
diff --git a/src/charset.c b/src/charset.c
index 470698f..9aa402a 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -765,10 +765,22 @@ linetabsize_str(char_u *s)
linetabsize_col(int startcol, char_u *s)
{
chartabsize_T cts;
+ vimlong_T vcol;
init_chartabsize_arg(&cts, curwin, 0, startcol, s, s);
+ vcol = cts.cts_vcol;
+
while (*cts.cts_ptr != NUL)
- cts.cts_vcol += lbr_chartabsize_adv(&cts);
+ {
+ vcol += lbr_chartabsize_adv(&cts);
+ if (vcol > MAXCOL)
+ {
+ cts.cts_vcol = MAXCOL;
+ break;
+ }
+ else
+ cts.cts_vcol = (int)vcol;
+ }
clear_chartabsize_arg(&cts);
return (int)cts.cts_vcol;
}
@@ -840,22 +852,33 @@ linetabsize_no_outer(win_T *wp, linenr_T lnum)
void
win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
{
+ vimlong_T vcol = cts->cts_vcol;
#ifdef FEAT_PROP_POPUP
cts->cts_with_trailing = len == MAXCOL;
#endif
for ( ; *cts->cts_ptr != NUL && (len == MAXCOL || cts->cts_ptr < cts->cts_line + len);
MB_PTR_ADV(cts->cts_ptr))
- cts->cts_vcol += win_lbr_chartabsize(cts, NULL);
+ {
+ vcol += win_lbr_chartabsize(cts, NULL);
+ if (vcol > MAXCOL)
+ {
+ cts->cts_vcol = MAXCOL;
+ break;
+ }
+ else
+ cts->cts_vcol = (int)vcol;
+ }
#ifdef FEAT_PROP_POPUP
// check for a virtual text at the end of a line or on an empty line
if (len == MAXCOL && cts->cts_has_prop_with_text && *cts->cts_ptr == NUL)
{
(void)win_lbr_chartabsize(cts, NULL);
- cts->cts_vcol += cts->cts_cur_text_width;
+ vcol += cts->cts_cur_text_width;
// when properties are above or below the empty line must also be
// counted
if (cts->cts_ptr == cts->cts_line && cts->cts_prop_lines > 0)
- ++cts->cts_vcol;
+ ++vcol;
+ cts->cts_vcol = vcol > MAXCOL ? MAXCOL : (int)vcol;
}
#endif
}
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 1008bf9..8d8bf06 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -438,6 +438,28 @@ cmdline_compl_startcol(void)
}
/*
+ * Returns the current cmdline completion pattern.
+ */
+ char_u *
+cmdline_compl_pattern(void)
+{
+ expand_T *xp = get_cmdline_info()->xpc;
+
+ return xp == NULL ? NULL : xp->xp_orig;
+}
+
+/*
+ * Returns TRUE if fuzzy cmdline completion is active, FALSE otherwise.
+ */
+ int
+cmdline_compl_is_fuzzy(void)
+{
+ expand_T *xp = get_cmdline_info()->xpc;
+
+ return xp != NULL && cmdline_fuzzy_completion_supported(xp);
+}
+
+/*
* Return the number of characters that should be skipped in a status match.
* These are backslashes used for escaping. Do show backslashes in help tags.
*/
diff --git a/src/cmdhist.c b/src/cmdhist.c
index 6342f02..684c08e 100644
--- a/src/cmdhist.c
+++ b/src/cmdhist.c
@@ -297,11 +297,11 @@ static int last_maptick = -1; // last seen maptick
add_to_history(
int histype,
char_u *new_entry,
+ size_t new_entrylen,
int in_map, // consider maptick when inside a mapping
int sep) // separator character used (search hist)
{
histentry_T *hisptr;
- int len;
if (hislen == 0) // no history
return;
@@ -336,10 +336,9 @@ add_to_history(
vim_free(hisptr->hisstr);
// Store the separator after the NUL of the string.
- len = (int)STRLEN(new_entry);
- hisptr->hisstr = vim_strnsave(new_entry, len + 2);
+ hisptr->hisstr = vim_strnsave(new_entry, new_entrylen + 2);
if (hisptr->hisstr != NULL)
- hisptr->hisstr[len + 1] = sep;
+ hisptr->hisstr[new_entrylen + 1] = sep;
hisptr->hisnum = ++hisnum[histype];
hisptr->viminfo = FALSE;
@@ -566,7 +565,7 @@ f_histadd(typval_T *argvars UNUSED, typval_T *rettv)
return;
init_history();
- add_to_history(histype, str, FALSE, NUL);
+ add_to_history(histype, str, STRLEN(str), FALSE, NUL);
rettv->vval.v_number = TRUE;
}
@@ -768,7 +767,8 @@ ex_history(exarg_T *eap)
if (i == hislen)
i = 0;
if (hist[i].hisstr != NULL
- && hist[i].hisnum >= j && hist[i].hisnum <= k)
+ && hist[i].hisnum >= j && hist[i].hisnum <= k
+ && !message_filtered(hist[i].hisstr))
{
msg_putchar('\n');
sprintf((char *)IObuff, "%c%6d ", i == idx ? '>' : ' ',
diff --git a/src/configure.ac b/src/configure.ac
index f6e54b3..946fe52 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1173,13 +1173,17 @@ if test "$enable_perlinterp" = "yes" -o "$enable_perlinterp" = "dynamic"; then
-e 's/-W[[^ ]]*//g' \
-e 's/-D_FORTIFY_SOURCE=.//g'`
dnl Remove "-lc", it breaks on FreeBSD when using "-pthread".
+ dnl Remove -specs=<file-path>, the hardened flags cause relocation errors
perllibs=`cd $srcdir; $vi_cv_path_perl -MExtUtils::Embed -e 'ldopts' | \
sed -e '/Warning/d' -e '/Note (probably harmless)/d' \
+ -e 's/-specs=[[^ ]*]//g' \
-e 's/-bE:perl.exp//' -e 's/-lc //'`
dnl Don't add perl lib to $LIBS: if it's not in LD_LIBRARY_PATH
dnl a test in configure may fail because of that.
+ dnl Remove -specs=<file-path>, the hardened flags cause relocation errors
perlldflags=`cd $srcdir; $vi_cv_path_perl -MExtUtils::Embed \
- -e 'ccdlflags' | sed -e 's/-bE:perl.exp//'`
+ -e 'ccdlflags' | sed -e 's/-bE:perl.exp//' \
+ -e 's/-specs=[[^ ]*]//g' `
dnl check that compiling a simple program still works with the flags
dnl added for Perl.
@@ -3303,13 +3307,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [int x __attribute__((u
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_ATTRIBUTE_UNUSED),
AC_MSG_RESULT(no))
-dnl Checks for header files.
-AC_CHECK_HEADER(elf.h, HAS_ELF=1)
-dnl AC_CHECK_HEADER(dwarf.h, SVR4=1)
-if test "$HAS_ELF" = 1; then
- AC_CHECK_LIB(elf, main)
-fi
-
AC_HEADER_DIRENT
dnl If sys/wait.h is not found it might still exist but not be POSIX
diff --git a/src/dict.c b/src/dict.c
index c78995d..bf45b0b 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -1092,6 +1092,33 @@ failret:
}
/*
+ * Evaluate a literal dictionary: #{key: val, key: val}
+ * "*arg" points to the "#".
+ * On return, "*arg" points to the character after the Dict.
+ * Return OK or FAIL. Returns NOTDONE for {expr}.
+ */
+ int
+eval_lit_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
+{
+ int vim9script = in_vim9script();
+ int ret = OK;
+
+ if (vim9script)
+ {
+ ret = vim9_bad_comment(*arg) ? FAIL : NOTDONE;
+ }
+ else if ((*arg)[1] == '{')
+ {
+ ++*arg;
+ ret = eval_dict(arg, rettv, evalarg, TRUE);
+ }
+ else
+ ret = NOTDONE;
+
+ return ret;
+}
+
+/*
* Go over all entries in "d2" and add them to "d1".
* When "action" is "error" then a duplicate key is an error.
* When "action" is "force" then a duplicate key is overwritten.
diff --git a/src/drawline.c b/src/drawline.c
index 81577be..e388bdb 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -296,10 +296,9 @@ get_sign_display_info(
if (nrcol)
{
wlv->c_extra = NUL;
- sprintf((char *)wlv->extra, "%-*c ",
- number_width(wp), SIGN_BYTE);
+ wlv->n_extra = vim_snprintf((char *)wlv->extra, sizeof(wlv->extra),
+ "%-*c ", number_width(wp), SIGN_BYTE);
wlv->p_extra = wlv->extra;
- wlv->n_extra = (int)STRLEN(wlv->p_extra);
}
else
wlv->c_extra = SIGN_BYTE;
@@ -310,10 +309,9 @@ get_sign_display_info(
if (nrcol)
{
wlv->c_extra = NUL;
- sprintf((char *)wlv->extra, "%-*c ", number_width(wp),
- MULTISIGN_BYTE);
+ wlv->n_extra = vim_snprintf((char *)wlv->extra, sizeof(wlv->extra),
+ "%-*c ", number_width(wp), MULTISIGN_BYTE);
wlv->p_extra = wlv->extra;
- wlv->n_extra = (int)STRLEN(wlv->p_extra);
}
else
wlv->c_extra = MULTISIGN_BYTE;
@@ -332,17 +330,18 @@ get_sign_display_info(
if (nrcol)
{
int width = number_width(wp) - 2;
- int n;
- for (n = 0; n < width; n++)
- wlv->extra[n] = ' ';
- vim_snprintf((char *)wlv->extra + n,
- sizeof(wlv->extra) - n, "%s ", wlv->p_extra);
+ vim_memset(wlv->extra, ' ', width);
+ wlv->n_extra = width;
+ wlv->n_extra += vim_snprintf((char *)wlv->extra + width,
+ sizeof(wlv->extra) - width, "%s ", wlv->p_extra);
wlv->p_extra = wlv->extra;
}
+ else
+ wlv->n_extra = (int)STRLEN(wlv->p_extra);
+
wlv->c_extra = NUL;
wlv->c_final = NUL;
- wlv->n_extra = (int)STRLEN(wlv->p_extra);
}
if (use_cursor_line_highlight(wp, wlv->lnum)
@@ -417,7 +416,7 @@ handle_lnum_col(
}
}
- sprintf((char *)wlv->extra, fmt, number_width(wp), num);
+ vim_snprintf((char *)wlv->extra, sizeof(wlv->extra), fmt, number_width(wp), num);
if (wp->w_skipcol > 0 && wlv->startrow == 0)
for (wlv->p_extra = wlv->extra; *wlv->p_extra == ' ';
++wlv->p_extra)
@@ -621,25 +620,26 @@ textprop_size_after_trunc(
{
int space = (flags & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_ABOVE))
? wp->w_width - win_col_off(wp) : added;
- int len = (int)STRLEN(text);
int strsize = 0;
- int n_used;
+ char_u *p;
- // if the remaining size is to small and 'wrap' is set we wrap anyway and
+ // if the remaining size is too small and 'wrap' is set we wrap anyway and
// use the next line
if (space < PROP_TEXT_MIN_CELLS && wp->w_p_wrap)
space += wp->w_width;
if (flags & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_ABOVE))
space -= padding;
- for (n_used = 0; n_used < len; n_used += (*mb_ptr2len)(text + n_used))
+
+ for (p = text; *p != NUL; p += (*mb_ptr2len)(p))
{
- int clen = ptr2cells(text + n_used);
+ int clen = ptr2cells(p);
if (strsize + clen > space)
break;
strsize += clen;
}
- *n_used_ptr = n_used;
+ *n_used_ptr = (int)(p - text);
+
return strsize;
}
@@ -1801,13 +1801,13 @@ win_line(
pos = wp->w_cursor;
wp->w_cursor.lnum = lnum;
wp->w_cursor.col = linecol;
- len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf);
+ len = spell_move_to(wp, FORWARD, SMT_ALL, TRUE, &spell_hlf);
// spell_move_to() may call ml_get() and make "line" invalid
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
ptr = line + linecol;
- if (len == 0 || (int)wp->w_cursor.col > ptr - line)
+ if (len == 0 || (int)wp->w_cursor.col > linecol)
{
// no bad word found at line start, don't check until end of a
// word
@@ -2821,15 +2821,16 @@ win_line(
// head byte at end of line
mb_l = 1;
transchar_nonprint(wp->w_buffer, wlv.extra, c);
+ wlv.n_extra = (int)STRLEN(wlv.extra) - 1;
}
else
{
// illegal tail byte
mb_l = 2;
STRCPY(wlv.extra, "XX");
+ wlv.n_extra = 1;
}
wlv.p_extra = wlv.extra;
- wlv.n_extra = (int)STRLEN(wlv.extra) - 1;
wlv.c_extra = NUL;
wlv.c_final = NUL;
c = *wlv.p_extra++;
@@ -3388,11 +3389,16 @@ win_line(
c = *wlv.p_extra;
p = alloc(wlv.n_extra + 1);
- vim_memset(p, ' ', wlv.n_extra);
- STRNCPY(p, wlv.p_extra + 1, STRLEN(wlv.p_extra) - 1);
- p[wlv.n_extra] = NUL;
- vim_free(wlv.p_extra_free);
- wlv.p_extra_free = wlv.p_extra = p;
+ if (p == NULL)
+ wlv.n_extra = 0;
+ else
+ {
+ vim_memset(p, ' ', wlv.n_extra);
+ STRNCPY(p, wlv.p_extra + 1, STRLEN(wlv.p_extra) - 1);
+ p[wlv.n_extra] = NUL;
+ vim_free(wlv.p_extra_free);
+ wlv.p_extra_free = wlv.p_extra = p;
+ }
}
else
#endif
@@ -4251,7 +4257,7 @@ win_line(
if (!wp->w_p_wrap && text_prop_follows && !text_prop_above)
{
// do not output more of the line, only the "below" prop
- ptr += STRLEN(ptr);
+ ptr = line + (size_t)ml_get_buf_len(wp->w_buffer, lnum);
# ifdef FEAT_LINEBREAK
wlv.dont_use_showbreak = TRUE;
# endif
diff --git a/src/drawscreen.c b/src/drawscreen.c
index f8818ff..9096c28 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -1781,7 +1781,7 @@ win_update(win_T *wp)
if (j < wp->w_height - 2) // not too far off
{
i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1,
- TRUE);
+ wp->w_height);
#ifdef FEAT_DIFF
// insert extra lines for previously invisible filler lines
if (wp->w_lines[0].wl_lnum != wp->w_topline)
diff --git a/src/edit.c b/src/edit.c
index 075b39b..e75a1cf 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -519,9 +519,10 @@ edit(
if (
#ifdef FEAT_VARTABS
- curwin->w_wcol < mincol - tabstop_at(
- get_nolist_virtcol(), curbuf->b_p_ts,
- curbuf->b_p_vts_array)
+ curwin->w_wcol < mincol - tabstop_at(get_nolist_virtcol(),
+ curbuf->b_p_ts,
+ curbuf->b_p_vts_array,
+ FALSE)
#else
(int)curwin->w_wcol < mincol - curbuf->b_p_ts
#endif
@@ -1310,7 +1311,7 @@ docomplete:
c = ins_ctrl_ey(c);
break;
- default:
+ default:
#ifdef UNIX
if (c == intr_char) // special interrupt char
goto do_intr;
@@ -1842,7 +1843,7 @@ backspace_until_column(int col)
* Only matters when there are composing characters.
* Return TRUE when something was deleted.
*/
- static int
+ static int
del_char_after_col(int limit_col UNUSED)
{
if (enc_utf8 && limit_col >= 0)
diff --git a/src/eval.c b/src/eval.c
index 51ee604..7848fea 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -22,13 +22,6 @@
#define NAMESPACE_CHAR (char_u *)"abglstvw"
-/*
- * When recursively copying lists and dicts we need to remember which ones we
- * have done to avoid endless recursiveness. This unique ID is used for that.
- * The last bit is used for previous_funccal, ignored when comparing.
- */
-static int current_copyID = 0;
-
static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
@@ -39,7 +32,6 @@ static int eval8(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_str
static int eval9(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
static int eval9_leader(typval_T *rettv, int numeric_only, char_u *start_leader, char_u **end_leaderp);
-static int free_unref_items(int copyID);
static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
/*
@@ -250,93 +242,146 @@ eval_expr_get_funccal(typval_T *expr, typval_T *rettv)
}
/*
- * Evaluate an expression, which can be a function, partial or string.
+ * Evaluate a partial.
* Pass arguments "argv[argc]".
- * If "want_func" is TRUE treat a string as a function name, not an expression.
* "fc_arg" is from eval_expr_get_funccal() or NULL;
* Return the result in "rettv" and OK or FAIL.
*/
- int
-eval_expr_typval(
- typval_T *expr,
- int want_func,
- typval_T *argv,
- int argc,
- funccall_T *fc_arg,
- typval_T *rettv)
+ static int
+eval_expr_partial(
+ typval_T *expr,
+ typval_T *argv,
+ int argc,
+ funccall_T *fc_arg,
+ typval_T *rettv)
{
- char_u *s;
- char_u buf[NUMBUFLEN];
- funcexe_T funcexe;
+ partial_T *partial = expr->vval.v_partial;
- if (expr->v_type == VAR_PARTIAL)
+ if (partial == NULL)
+ return FAIL;
+
+ if (partial->pt_func != NULL
+ && partial->pt_func->uf_def_status != UF_NOT_COMPILED)
{
- partial_T *partial = expr->vval.v_partial;
+ funccall_T *fc = fc_arg != NULL ? fc_arg
+ : create_funccal(partial->pt_func, rettv);
+ int r;
- if (partial == NULL)
+ if (fc == NULL)
return FAIL;
- if (partial->pt_func != NULL
- && partial->pt_func->uf_def_status != UF_NOT_COMPILED)
- {
- funccall_T *fc = fc_arg != NULL ? fc_arg
- : create_funccal(partial->pt_func, rettv);
- int r;
-
- if (fc == NULL)
- return FAIL;
-
- // Shortcut to call a compiled function with minimal overhead.
- r = call_def_function(partial->pt_func, argc, argv,
- DEF_USE_PT_ARGV, partial, NULL, fc, rettv);
- if (fc_arg == NULL)
- remove_funccal();
- if (r == FAIL)
- return FAIL;
- }
- else
- {
- s = partial_name(partial);
- if (s == NULL || *s == NUL)
- return FAIL;
- CLEAR_FIELD(funcexe);
- funcexe.fe_evaluate = TRUE;
- funcexe.fe_partial = partial;
- if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL)
- return FAIL;
- }
- }
- else if (expr->v_type == VAR_INSTR)
- {
- return exe_typval_instr(expr, rettv);
+ // Shortcut to call a compiled function with minimal overhead.
+ r = call_def_function(partial->pt_func, argc, argv, DEF_USE_PT_ARGV,
+ partial, NULL, fc, rettv);
+ if (fc_arg == NULL)
+ remove_funccal();
+ if (r == FAIL)
+ return FAIL;
}
- else if (expr->v_type == VAR_FUNC || want_func)
+ else
{
- s = expr->v_type == VAR_FUNC
- ? expr->vval.v_string
- : tv_get_string_buf_chk_strict(expr, buf, in_vim9script());
+ char_u *s = partial_name(partial);
+ funcexe_T funcexe;
+
if (s == NULL || *s == NUL)
return FAIL;
+
CLEAR_FIELD(funcexe);
funcexe.fe_evaluate = TRUE;
+ funcexe.fe_partial = partial;
if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL)
return FAIL;
}
+
+ return OK;
+}
+
+/*
+ * Evaluate an expression which is a function.
+ * Pass arguments "argv[argc]".
+ * Return the result in "rettv" and OK or FAIL.
+ */
+ static int
+eval_expr_func(
+ typval_T *expr,
+ typval_T *argv,
+ int argc,
+ typval_T *rettv)
+{
+ funcexe_T funcexe;
+ char_u buf[NUMBUFLEN];
+ char_u *s;
+
+ if (expr->v_type == VAR_FUNC)
+ s = expr->vval.v_string;
else
- {
s = tv_get_string_buf_chk_strict(expr, buf, in_vim9script());
- if (s == NULL)
- return FAIL;
- s = skipwhite(s);
- if (eval1_emsg(&s, rettv, NULL) == FAIL)
- return FAIL;
- if (*skipwhite(s) != NUL) // check for trailing chars after expr
- {
- clear_tv(rettv);
- semsg(_(e_invalid_expression_str), s);
- return FAIL;
- }
+ if (s == NULL || *s == NUL)
+ return FAIL;
+
+ CLEAR_FIELD(funcexe);
+ funcexe.fe_evaluate = TRUE;
+ if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL)
+ return FAIL;
+
+ return OK;
+}
+
+/*
+ * Evaluate an expression, which is a string.
+ * Return the result in "rettv" and OK or FAIL.
+ */
+ static int
+eval_expr_string(
+ typval_T *expr,
+ typval_T *rettv)
+{
+ char_u *s;
+ char_u buf[NUMBUFLEN];
+
+ s = tv_get_string_buf_chk_strict(expr, buf, in_vim9script());
+ if (s == NULL)
+ return FAIL;
+
+ s = skipwhite(s);
+ if (eval1_emsg(&s, rettv, NULL) == FAIL)
+ return FAIL;
+
+ if (*skipwhite(s) != NUL) // check for trailing chars after expr
+ {
+ clear_tv(rettv);
+ semsg(_(e_invalid_expression_str), s);
+ return FAIL;
}
+
+ return OK;
+}
+
+/*
+ * Evaluate an expression, which can be a function, partial or string.
+ * Pass arguments "argv[argc]".
+ * If "want_func" is TRUE treat a string as a function name, not an expression.
+ * "fc_arg" is from eval_expr_get_funccal() or NULL;
+ * Return the result in "rettv" and OK or FAIL.
+ */
+ int
+eval_expr_typval(
+ typval_T *expr,
+ int want_func,
+ typval_T *argv,
+ int argc,
+ funccall_T *fc_arg,
+ typval_T *rettv)
+{
+ if (expr->v_type == VAR_PARTIAL)
+ return eval_expr_partial(expr, argv, argc, fc_arg, rettv);
+ else if (expr->v_type == VAR_INSTR)
+ return exe_typval_instr(expr, rettv);
+ else if (expr->v_type == VAR_FUNC || want_func)
+ return eval_expr_func(expr, argv, argc, rettv);
+ else
+ return eval_expr_string(expr, rettv);
+
return OK;
}
@@ -1117,41 +1162,40 @@ get_lval_check_access(
ch_log(NULL, "LKVAR: get_lval_check_access(), cl_exec %p, cl %p, %c",
(void*)cl_exec, (void*)cl, *p);
#endif
- if (cl_exec == NULL || cl_exec != cl)
+ if (cl_exec != NULL && cl_exec == cl)
+ return OK;
+
+ char *msg = NULL;
+ switch (om->ocm_access)
{
- char *msg = NULL;
- switch (om->ocm_access)
- {
- case VIM_ACCESS_PRIVATE:
- msg = e_cannot_access_protected_variable_str;
+ case VIM_ACCESS_PRIVATE:
+ msg = e_cannot_access_protected_variable_str;
+ break;
+ case VIM_ACCESS_READ:
+ // If [idx] or .key following, read only OK.
+ if (*p == '[' || *p == '.')
break;
- case VIM_ACCESS_READ:
- // If [idx] or .key following, read only OK.
- if (*p == '[' || *p == '.')
- break;
- if ((flags & GLV_READ_ONLY) == 0)
+ if ((flags & GLV_READ_ONLY) == 0)
+ {
+ if (IS_ENUM(cl))
{
- if (IS_ENUM(cl))
- {
- if (om->ocm_type->tt_type == VAR_OBJECT)
- semsg(_(e_enumvalue_str_cannot_be_modified),
- cl->class_name, om->ocm_name);
- else
- msg = e_variable_is_not_writable_str;
- }
+ if (om->ocm_type->tt_type == VAR_OBJECT)
+ semsg(_(e_enumvalue_str_cannot_be_modified),
+ cl->class_name, om->ocm_name);
else
msg = e_variable_is_not_writable_str;
}
- break;
- case VIM_ACCESS_ALL:
- break;
- }
- if (msg != NULL)
- {
- emsg_var_cl_define(msg, om->ocm_name, 0, cl);
- return FAIL;
- }
-
+ else
+ msg = e_variable_is_not_writable_str;
+ }
+ break;
+ case VIM_ACCESS_ALL:
+ break;
+ }
+ if (msg != NULL)
+ {
+ emsg_var_cl_define(msg, om->ocm_name, 0, cl);
+ return FAIL;
}
return OK;
}
@@ -1170,12 +1214,10 @@ get_lval_check_access(
static char_u *
get_lval_imported(
lval_T *lp,
- typval_T *rettv,
scid_T imp_sid,
char_u *p,
dictitem_T **dip,
- int fne_flags,
- int vim9script)
+ int fne_flags)
{
ufunc_T *ufunc;
type_T *type = NULL;
@@ -1197,16 +1239,6 @@ get_lval_imported(
TRUE) == -1)
goto failed;
- if (vim9script && type != NULL)
- {
- where_T where = WHERE_INIT;
-
- // In a vim9 script, do type check and make sure the variable is
- // writable.
- if (check_typval_type(type, rettv, where) == FAIL)
- goto failed;
- }
-
// Get the typval for the exported item
hashtab_T *ht = &SCRIPT_VARS(imp_sid);
if (ht == NULL)
@@ -1232,6 +1264,7 @@ get_lval_imported(
goto failed;
lp->ll_tv = &di->di_tv;
+ lp->ll_valtype = type;
success:
rc = OK;
@@ -1241,6 +1274,674 @@ failed:
return rc == OK ? p : NULL;
}
+typedef enum {
+ GLV_FAIL,
+ GLV_OK,
+ GLV_STOP
+} glv_status_T;
+
+/*
+ * Get an Dict lval variable that can be assigned a value to: "name",
+ * "name[expr]", "name[expr][expr]", "name.key", "name.key[expr]" etc.
+ * "name" points to the start of the name.
+ * If "rettv" is not NULL it points to the value to be assigned.
+ * "unlet" is TRUE for ":unlet": slightly different behavior when something is
+ * wrong; must end in space or cmd separator.
+ *
+ * flags:
+ * GLV_QUIET: do not give error messages
+ * GLV_READ_ONLY: will not change the variable
+ * GLV_NO_AUTOLOAD: do not use script autoloading
+ *
+ * The Dict is returned in 'lp'. Returns GLV_OK on success and GLV_FAIL on
+ * failure. Returns GLV_STOP to stop processing the characters following
+ * 'key_end'.
+ */
+ static int
+get_lval_dict_item(
+ lval_T *lp,
+ char_u *name,
+ char_u *key,
+ int len,
+ char_u **key_end,
+ typval_T *var1,
+ int flags,
+ int unlet,
+ typval_T *rettv)
+{
+ int quiet = flags & GLV_QUIET;
+ char_u *p = *key_end;
+
+ if (len == -1)
+ {
+ // "[key]": get key from "var1"
+ key = tv_get_string_chk(var1); // is number or string
+ if (key == NULL)
+ return GLV_FAIL;
+ }
+ lp->ll_list = NULL;
+ lp->ll_object = NULL;
+ lp->ll_class = NULL;
+
+ // a NULL dict is equivalent with an empty dict
+ if (lp->ll_tv->vval.v_dict == NULL)
+ {
+ lp->ll_tv->vval.v_dict = dict_alloc();
+ if (lp->ll_tv->vval.v_dict == NULL)
+ return GLV_FAIL;
+ ++lp->ll_tv->vval.v_dict->dv_refcount;
+ }
+ lp->ll_dict = lp->ll_tv->vval.v_dict;
+
+ lp->ll_di = dict_find(lp->ll_dict, key, len);
+
+ // When assigning to a scope dictionary check that a function and
+ // variable name is valid (only variable name unless it is l: or
+ // g: dictionary). Disallow overwriting a builtin function.
+ if (rettv != NULL && lp->ll_dict->dv_scope != 0)
+ {
+ int prevval;
+
+ if (len != -1)
+ {
+ prevval = key[len];
+ key[len] = NUL;
+ }
+ else
+ prevval = 0; // avoid compiler warning
+ int wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
+ && (rettv->v_type == VAR_FUNC
+ || rettv->v_type == VAR_PARTIAL)
+ && var_wrong_func_name(key, lp->ll_di == NULL))
+ || !valid_varname(key, -1, TRUE);
+ if (len != -1)
+ key[len] = prevval;
+ if (wrong)
+ return GLV_FAIL;
+ }
+
+ if (lp->ll_valtype != NULL)
+ // use the type of the member
+ lp->ll_valtype = lp->ll_valtype->tt_member;
+
+ if (lp->ll_di == NULL)
+ {
+ // Can't add "v:" or "a:" variable.
+ if (lp->ll_dict == get_vimvar_dict()
+ || &lp->ll_dict->dv_hashtab == get_funccal_args_ht())
+ {
+ semsg(_(e_illegal_variable_name_str), name);
+ return GLV_FAIL;
+ }
+
+ // Key does not exist in dict: may need to add it.
+ if (*p == '[' || *p == '.' || unlet)
+ {
+ if (!quiet)
+ semsg(_(e_key_not_present_in_dictionary_str), key);
+ return GLV_FAIL;
+ }
+ if (len == -1)
+ lp->ll_newkey = vim_strsave(key);
+ else
+ lp->ll_newkey = vim_strnsave(key, len);
+ if (lp->ll_newkey == NULL)
+ p = NULL;
+
+ *key_end = p;
+ return GLV_STOP;
+ }
+ // existing variable, need to check if it can be changed
+ else if ((flags & GLV_READ_ONLY) == 0
+ && (var_check_ro(lp->ll_di->di_flags, name, FALSE)
+ || var_check_lock(lp->ll_di->di_flags, name, FALSE)))
+ return GLV_FAIL;
+
+ lp->ll_tv = &lp->ll_di->di_tv;
+
+ return GLV_OK;
+}
+
+/*
+ * Get an blob lval variable that can be assigned a value to: "name",
+ * "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", etc.
+ *
+ * 'var1' specifies the starting blob index and 'var2' specifies the ending
+ * blob index. If the first index is not specified in a range, then 'empty1'
+ * is TRUE. If 'quiet' is TRUE, then error messages are not displayed for
+ * invalid indexes.
+ *
+ * The blob is returned in 'lp'. Returns OK on success and FAIL on failure.
+ */
+ static int
+get_lval_blob(
+ lval_T *lp,
+ typval_T *var1,
+ typval_T *var2,
+ int empty1,
+ int quiet)
+{
+ long bloblen = blob_len(lp->ll_tv->vval.v_blob);
+
+ // Get the number and item for the only or first index of the List.
+ if (empty1)
+ lp->ll_n1 = 0;
+ else
+ // is number or string
+ lp->ll_n1 = (long)tv_get_number(var1);
+
+ if (check_blob_index(bloblen, lp->ll_n1, quiet) == FAIL)
+ return FAIL;
+ if (lp->ll_range && !lp->ll_empty2)
+ {
+ lp->ll_n2 = (long)tv_get_number(var2);
+ if (check_blob_range(bloblen, lp->ll_n1, lp->ll_n2, quiet) == FAIL)
+ return FAIL;
+ }
+
+ if (!lp->ll_range)
+ // Indexing a single byte in a blob. So the rhs type is a
+ // number.
+ lp->ll_valtype = &t_number;
+
+ lp->ll_blob = lp->ll_tv->vval.v_blob;
+ lp->ll_tv = NULL;
+
+ return OK;
+}
+
+/*
+ * Get a List lval variable that can be assigned a value to: "name",
+ * "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", etc.
+ *
+ * 'var1' specifies the starting List index and 'var2' specifies the ending
+ * List index. If the first index is not specified in a range, then 'empty1'
+ * is TRUE. If 'quiet' is TRUE, then error messages are not displayed for
+ * invalid indexes.
+ *
+ * The List is returned in 'lp'. Returns OK on success and FAIL on failure.
+ */
+ static int
+get_lval_list(
+ lval_T *lp,
+ typval_T *var1,
+ typval_T *var2,
+ int empty1,
+ int flags,
+ int quiet)
+{
+ /*
+ * Get the number and item for the only or first index of the List.
+ */
+ if (empty1)
+ lp->ll_n1 = 0;
+ else
+ // is number or string
+ lp->ll_n1 = (long)tv_get_number(var1);
+
+ lp->ll_dict = NULL;
+ lp->ll_object = NULL;
+ lp->ll_class = NULL;
+ lp->ll_list = lp->ll_tv->vval.v_list;
+ lp->ll_li = check_range_index_one(lp->ll_list, &lp->ll_n1,
+ (flags & GLV_ASSIGN_WITH_OP) == 0, quiet);
+ if (lp->ll_li == NULL)
+ return FAIL;
+
+ if (lp->ll_valtype != NULL && !lp->ll_range)
+ // use the type of the member
+ lp->ll_valtype = lp->ll_valtype->tt_member;
+
+ /*
+ * May need to find the item or absolute index for the second
+ * index of a range.
+ * When no index given: "lp->ll_empty2" is TRUE.
+ * Otherwise "lp->ll_n2" is set to the second index.
+ */
+ if (lp->ll_range && !lp->ll_empty2)
+ {
+ lp->ll_n2 = (long)tv_get_number(var2);
+ // is number or string
+ if (check_range_index_two(lp->ll_list,
+ &lp->ll_n1, lp->ll_li, &lp->ll_n2, quiet) == FAIL)
+ return FAIL;
+ }
+
+ lp->ll_tv = &lp->ll_li->li_tv;
+
+ return OK;
+}
+
+/*
+ * Get a class or object lval method in class "cl". The 'key' argument points
+ * to the method name and 'key_end' points to the character after 'key'.
+ * 'v_type' is VAR_CLASS or VAR_OBJECT.
+ *
+ * The method index, method function pointer and method type are returned in
+ * "lp".
+ */
+ static void
+get_lval_oc_method(
+ lval_T *lp,
+ class_T *cl,
+ char_u *key,
+ char_u *key_end,
+ vartype_T v_type)
+{
+ // Look for a method with this name.
+ // round 1: class functions (skipped for an object)
+ // round 2: object methods
+ for (int round = v_type == VAR_OBJECT ? 2 : 1; round <= 2; ++round)
+ {
+ int m_idx;
+ ufunc_T *fp;
+
+ fp = method_lookup(cl, round == 1 ? VAR_CLASS : VAR_OBJECT,
+ key, key_end - key, &m_idx);
+ lp->ll_oi = m_idx;
+ if (fp != NULL)
+ {
+ lp->ll_ufunc = fp;
+ lp->ll_valtype = fp->uf_func_type;
+ break;
+ }
+ }
+}
+
+/*
+ * Get a class or object lval variable in class "cl". The "key" argument
+ * points to the variable name and "key_end" points to the character after
+ * "key". "v_type" is VAR_CLASS or VAR_OBJECT. "cl_exec" is the class that is
+ * executing, or NULL.
+ *
+ * The variable index, typval and type are returned in "lp". Returns FAIL if
+ * the variable is not writable. Otherwise returns OK.
+ */
+ static int
+get_lval_oc_variable(
+ lval_T *lp,
+ class_T *cl,
+ char_u *key,
+ char_u *key_end,
+ vartype_T v_type,
+ class_T *cl_exec,
+ int flags)
+{
+ int m_idx;
+ ocmember_T *om;
+
+ om = member_lookup(cl, v_type, key, key_end - key, &m_idx);
+ lp->ll_oi = m_idx;
+ if (om == NULL)
+ return OK;
+
+ // Check variable is accessible
+ if (get_lval_check_access(cl_exec, cl, om, key_end, flags) == FAIL)
+ return FAIL;
+
+ // When lhs is used to modify the variable, check it is not a read-only
+ // variable.
+ if ((flags & GLV_READ_ONLY) == 0 && (*key_end != '.' && *key_end != '[')
+ && oc_var_check_ro(cl, om))
+ return FAIL;
+
+ 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];
+
+ return OK;
+}
+
+/*
+ * Get a Class or Object lval variable or method that can be assigned a value
+ * to: "name", "name.key", "name.key[expr]" etc.
+ *
+ * The 'key' argument points to the member name and 'key_end' points to the
+ * character after 'key'. 'v_type' is VAR_CLASS or VAR_OBJECT. 'cl_exec' is
+ * the class that is executing, or NULL. If 'quiet' is TRUE, then error
+ * messages are not displayed for invalid indexes.
+ *
+ * The Class or Object is returned in 'lp'. Returns OK on success and FAIL on
+ * failure.
+ */
+ static int
+get_lval_class_or_obj(
+ lval_T *lp,
+ char_u *key,
+ char_u *key_end,
+ vartype_T v_type,
+ class_T *cl_exec,
+ int flags,
+ int quiet)
+{
+ lp->ll_dict = NULL;
+ lp->ll_list = NULL;
+
+ class_T *cl;
+ if (v_type == VAR_OBJECT)
+ {
+ if (lp->ll_tv->vval.v_object == NULL)
+ {
+ if (!quiet)
+ emsg(_(e_using_null_object));
+ return FAIL;
+ }
+ cl = lp->ll_tv->vval.v_object->obj_class;
+ lp->ll_object = lp->ll_tv->vval.v_object;
+ }
+ else
+ {
+ cl = lp->ll_tv->vval.v_class;
+ lp->ll_object = NULL;
+ }
+ lp->ll_class = cl;
+
+ if (cl == NULL)
+ // TODO: what if class is NULL?
+ return OK;
+
+ lp->ll_valtype = NULL;
+
+ if (flags & GLV_PREFER_FUNC)
+ get_lval_oc_method(lp, cl, key, key_end, v_type);
+
+ // Look for object/class member variable
+ if (lp->ll_valtype == NULL)
+ {
+ if (get_lval_oc_variable(lp, cl, key, key_end, v_type, cl_exec, flags)
+ == FAIL)
+ return FAIL;
+ }
+
+ if (lp->ll_valtype == NULL)
+ {
+ member_not_found_msg(cl, v_type, key, key_end - key);
+ return FAIL;
+ }
+
+ return OK;
+}
+
+/*
+ * Check whether dot (".") is allowed after the variable "name" with type
+ * "v_type". Only Dict, Class and Object types support a dot after the name.
+ * Returns TRUE if dot is allowed after the name.
+ */
+ static int
+dot_allowed_after_type(char_u *name, vartype_T v_type, int quiet)
+{
+ if (v_type != VAR_DICT && v_type != VAR_OBJECT && v_type != VAR_CLASS)
+ {
+ if (!quiet)
+ semsg(_(e_dot_not_allowed_after_str_str),
+ vartype_name(v_type), name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Check whether left bracket ("[") is allowed after the variable "name" with
+ * type "v_type". Only Dict, List and Blob types support a bracket after the
+ * variable name. Returns TRUE if bracket is allowed after the name.
+ */
+ static int
+bracket_allowed_after_type(char_u *name, vartype_T v_type, int quiet)
+{
+ if (v_type == VAR_CLASS || v_type == VAR_OBJECT)
+ {
+ if (!quiet)
+ semsg(_(e_index_not_allowed_after_str_str),
+ vartype_name(v_type), name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Check whether the variable "name" with type "v_type" can be followed by an
+ * index. Only Dict, List, Blob, Object and Class types support indexing.
+ * Returns TRUE if indexing is allowed after the name.
+ */
+ static int
+index_allowed_after_type(char_u *name, vartype_T v_type, int quiet)
+{
+ if (v_type != VAR_LIST && v_type != VAR_DICT && v_type != VAR_BLOB &&
+ v_type != VAR_OBJECT && v_type != VAR_CLASS)
+ {
+ if (!quiet)
+ semsg(_(e_index_not_allowed_after_str_str),
+ vartype_name(v_type), name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Get the lval of a list/dict/blob/object/class subitem starting at "p". Loop
+ * until no more [idx] or .key is following.
+ *
+ * If "rettv" is not NULL it points to the value to be assigned.
+ * "unlet" is TRUE for ":unlet".
+ *
+ * Returns a pointer to the character after the subscript on success or NULL on
+ * failure.
+ */
+ static char_u *
+get_lval_subscript(
+ lval_T *lp,
+ char_u *p,
+ char_u *name,
+ typval_T *rettv,
+ hashtab_T *ht,
+ dictitem_T *v,
+ int unlet,
+ int flags, // GLV_ values
+ class_T *cl_exec)
+{
+ int vim9script = in_vim9script();
+ int quiet = flags & GLV_QUIET;
+ char_u *key = NULL;
+ int len;
+ typval_T var1;
+ typval_T var2;
+ int empty1 = FALSE;
+ int rc = FAIL;
+
+ /*
+ * Loop until no more [idx] or .key is following.
+ */
+ var1.v_type = VAR_UNKNOWN;
+ var2.v_type = VAR_UNKNOWN;
+
+ while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.'))
+ {
+ vartype_T v_type = lp->ll_tv->v_type;
+
+ if (*p == '.' && !dot_allowed_after_type(name, v_type, quiet))
+ goto done;
+
+ if (*p == '[' && !bracket_allowed_after_type(name, v_type, quiet))
+ goto done;
+
+ if (!index_allowed_after_type(name, v_type, quiet))
+ goto done;
+
+ // A NULL list/blob works like an empty list/blob, allocate one now.
+ int r = OK;
+ if (v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL)
+ r = rettv_list_alloc(lp->ll_tv);
+ else if (v_type == VAR_BLOB && lp->ll_tv->vval.v_blob == NULL)
+ r = rettv_blob_alloc(lp->ll_tv);
+ if (r == FAIL)
+ goto done;
+
+ if (lp->ll_range)
+ {
+ if (!quiet)
+ emsg(_(e_slice_must_come_last));
+ goto done;
+ }
+#ifdef LOG_LOCKVAR
+ ch_log(NULL, "LKVAR: get_lval() loop: p: %s, type: %s", p,
+ vartype_name(v_type));
+#endif
+
+ if (vim9script && lp->ll_valtype == NULL
+ && v != NULL
+ && lp->ll_tv == &v->di_tv
+ && ht != NULL && ht == get_script_local_ht())
+ {
+ svar_T *sv = find_typval_in_script(lp->ll_tv, 0, TRUE);
+
+ // Vim9 script local variable: get the type
+ if (sv != NULL)
+ {
+ lp->ll_valtype = sv->sv_type;
+#ifdef LOG_LOCKVAR
+ ch_log(NULL, "LKVAR: ... loop: vim9 assign type: %s",
+ vartype_name(lp->ll_valtype->tt_type));
+#endif
+ }
+ }
+
+ len = -1;
+ if (*p == '.')
+ {
+ key = p + 1;
+
+ for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
+ ;
+ if (len == 0)
+ {
+ if (!quiet)
+ emsg(_(e_cannot_use_empty_key_for_dictionary));
+ goto done;
+ }
+ p = key + len;
+ }
+ else
+ {
+ // Get the index [expr] or the first index [expr: ].
+ p = skipwhite(p + 1);
+ if (*p == ':')
+ empty1 = TRUE;
+ else
+ {
+ empty1 = FALSE;
+ if (eval1(&p, &var1, &EVALARG_EVALUATE) == FAIL) // recursive!
+ goto done;
+ if (tv_get_string_chk(&var1) == NULL)
+ // not a number or string
+ goto done;
+ p = skipwhite(p);
+ }
+
+ // Optionally get the second index [ :expr].
+ if (*p == ':')
+ {
+ if (v_type == VAR_DICT)
+ {
+ if (!quiet)
+ emsg(_(e_cannot_slice_dictionary));
+ goto done;
+ }
+ if (rettv != NULL
+ && !(rettv->v_type == VAR_LIST
+ && rettv->vval.v_list != NULL)
+ && !(rettv->v_type == VAR_BLOB
+ && rettv->vval.v_blob != NULL))
+ {
+ if (!quiet)
+ emsg(_(e_slice_requires_list_or_blob_value));
+ goto done;
+ }
+ p = skipwhite(p + 1);
+ if (*p == ']')
+ lp->ll_empty2 = TRUE;
+ else
+ {
+ lp->ll_empty2 = FALSE;
+ // recursive!
+ if (eval1(&p, &var2, &EVALARG_EVALUATE) == FAIL)
+ goto done;
+ if (tv_get_string_chk(&var2) == NULL)
+ // not a number or string
+ goto done;
+ }
+ lp->ll_range = TRUE;
+ }
+ else
+ lp->ll_range = FALSE;
+
+ if (*p != ']')
+ {
+ if (!quiet)
+ emsg(_(e_missing_closing_square_brace));
+ goto done;
+ }
+
+ // Skip to past ']'.
+ ++p;
+ }
+#ifdef LOG_LOCKVAR
+ if (len == -1)
+ ch_log(NULL, "LKVAR: ... loop: p: %s, '[' key: %s", p,
+ empty1 ? ":" : (char*)tv_get_string(&var1));
+ else
+ ch_log(NULL, "LKVAR: ... loop: p: %s, '.' key: %s", p, key);
+#endif
+
+ if (v_type == VAR_DICT)
+ {
+ glv_status_T glv_status;
+
+ glv_status = get_lval_dict_item(lp, name, key, len, &p, &var1,
+ flags, unlet, rettv);
+ if (glv_status == GLV_FAIL)
+ goto done;
+ if (glv_status == GLV_STOP)
+ break;
+ }
+ else if (v_type == VAR_BLOB)
+ {
+ if (get_lval_blob(lp, &var1, &var2, empty1, quiet) == FAIL)
+ goto done;
+
+ break;
+ }
+ else if (v_type == VAR_LIST)
+ {
+ if (get_lval_list(lp, &var1, &var2, empty1, flags, quiet) == FAIL)
+ goto done;
+ }
+ else // v_type == VAR_CLASS || v_type == VAR_OBJECT
+ {
+ if (get_lval_class_or_obj(lp, key, p, v_type, cl_exec, flags,
+ quiet) == FAIL)
+ goto done;
+ }
+
+ clear_tv(&var1);
+ clear_tv(&var2);
+ var1.v_type = VAR_UNKNOWN;
+ var2.v_type = VAR_UNKNOWN;
+ }
+
+ rc = OK;
+
+done:
+ clear_tv(&var1);
+ clear_tv(&var2);
+ return rc == OK ? p : NULL;
+}
+
/*
* Get an lval: variable, Dict item or List item that can be assigned a value
* to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
@@ -1274,11 +1975,6 @@ get_lval(
char_u *expr_start, *expr_end;
int cc;
dictitem_T *v = NULL;
- typval_T var1;
- typval_T var2;
- int empty1 = FALSE;
- char_u *key = NULL;
- int len;
hashtab_T *ht = NULL;
int quiet = flags & GLV_QUIET;
int writing = 0;
@@ -1410,8 +2106,7 @@ get_lval(
if (import != NULL)
{
p++; // skip '.'
- p = get_lval_imported(lp, rettv, import->imp_sid, p, &v,
- fne_flags, vim9script);
+ p = get_lval_imported(lp, import->imp_sid, p, &v, fne_flags);
if (p == NULL)
return NULL;
}
@@ -1456,447 +2151,21 @@ get_lval(
return NULL;
}
- /*
- * Loop until no more [idx] or .key is following.
- */
- var1.v_type = VAR_UNKNOWN;
- var2.v_type = VAR_UNKNOWN;
- while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.'))
- {
- vartype_T v_type = lp->ll_tv->v_type;
-
- if (*p == '.' && v_type != VAR_DICT
- && v_type != VAR_OBJECT
- && v_type != VAR_CLASS)
- {
- if (!quiet)
- semsg(_(e_dot_not_allowed_after_str_str),
- vartype_name(v_type), name);
- return NULL;
- }
- if (v_type != VAR_LIST
- && v_type != VAR_DICT
- && v_type != VAR_BLOB
- && v_type != VAR_OBJECT
- && v_type != VAR_CLASS)
- {
- if (!quiet)
- semsg(_(e_index_not_allowed_after_str_str),
- vartype_name(v_type), name);
- return NULL;
- }
+ // If the next character is a "." or a "[", then process the subitem.
+ p = get_lval_subscript(lp, p, name, rettv, ht, v, unlet, flags, cl_exec);
+ if (p == NULL)
+ return NULL;
- // A NULL list/blob works like an empty list/blob, allocate one now.
- int r = OK;
- if (v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL)
- r = rettv_list_alloc(lp->ll_tv);
- else if (v_type == VAR_BLOB && lp->ll_tv->vval.v_blob == NULL)
- r = rettv_blob_alloc(lp->ll_tv);
- if (r == FAIL)
- return NULL;
+ if (vim9script && lp->ll_valtype != NULL && rettv != NULL)
+ {
+ where_T where = WHERE_INIT;
- if (lp->ll_range)
- {
- if (!quiet)
- emsg(_(e_slice_must_come_last));
+ // In a vim9 script, do type check and make sure the variable is
+ // writable.
+ if (check_typval_type(lp->ll_valtype, rettv, where) == FAIL)
return NULL;
- }
-#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: get_lval() loop: p: %s, type: %s", p,
- vartype_name(v_type));
-#endif
-
- if (vim9script && lp->ll_valtype == NULL
- && v != NULL
- && lp->ll_tv == &v->di_tv
- && ht != NULL && ht == get_script_local_ht())
- {
- svar_T *sv = find_typval_in_script(lp->ll_tv, 0, TRUE);
-
- // Vim9 script local variable: get the type
- if (sv != NULL)
- {
- lp->ll_valtype = sv->sv_type;
-#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: ... loop: vim9 assign type: %s",
- vartype_name(lp->ll_valtype->tt_type));
-#endif
- }
- }
-
- len = -1;
- if (*p == '.')
- {
- key = p + 1;
- for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
- ;
- if (len == 0)
- {
- if (!quiet)
- emsg(_(e_cannot_use_empty_key_for_dictionary));
- return NULL;
- }
- p = key + len;
- }
- else
- {
- // Get the index [expr] or the first index [expr: ].
- p = skipwhite(p + 1);
- if (*p == ':')
- empty1 = TRUE;
- else
- {
- empty1 = FALSE;
- if (eval1(&p, &var1, &EVALARG_EVALUATE) == FAIL) // recursive!
- return NULL;
- if (tv_get_string_chk(&var1) == NULL)
- {
- // not a number or string
- clear_tv(&var1);
- return NULL;
- }
- p = skipwhite(p);
- }
-
- // Optionally get the second index [ :expr].
- if (*p == ':')
- {
- if (v_type == VAR_DICT)
- {
- if (!quiet)
- emsg(_(e_cannot_slice_dictionary));
- clear_tv(&var1);
- return NULL;
- }
- if (rettv != NULL
- && !(rettv->v_type == VAR_LIST
- && rettv->vval.v_list != NULL)
- && !(rettv->v_type == VAR_BLOB
- && rettv->vval.v_blob != NULL))
- {
- if (!quiet)
- emsg(_(e_slice_requires_list_or_blob_value));
- clear_tv(&var1);
- return NULL;
- }
- p = skipwhite(p + 1);
- if (*p == ']')
- lp->ll_empty2 = TRUE;
- else
- {
- lp->ll_empty2 = FALSE;
- // recursive!
- if (eval1(&p, &var2, &EVALARG_EVALUATE) == FAIL)
- {
- clear_tv(&var1);
- return NULL;
- }
- if (tv_get_string_chk(&var2) == NULL)
- {
- // not a number or string
- clear_tv(&var1);
- clear_tv(&var2);
- return NULL;
- }
- }
- lp->ll_range = TRUE;
- }
- else
- lp->ll_range = FALSE;
-
- if (*p != ']')
- {
- if (!quiet)
- emsg(_(e_missing_closing_square_brace));
- clear_tv(&var1);
- clear_tv(&var2);
- return NULL;
- }
-
- // Skip to past ']'.
- ++p;
- }
-#ifdef LOG_LOCKVAR
- if (len == -1)
- ch_log(NULL, "LKVAR: ... loop: p: %s, '[' key: %s", p,
- empty1 ? ":" : (char*)tv_get_string(&var1));
- else
- ch_log(NULL, "LKVAR: ... loop: p: %s, '.' key: %s", p, key);
-#endif
-
- if (v_type == VAR_DICT)
- {
- if (len == -1)
- {
- // "[key]": get key from "var1"
- key = tv_get_string_chk(&var1); // is number or string
- if (key == NULL)
- {
- clear_tv(&var1);
- return NULL;
- }
- }
- lp->ll_list = NULL;
- lp->ll_object = NULL;
- lp->ll_class = NULL;
-
- // a NULL dict is equivalent with an empty dict
- if (lp->ll_tv->vval.v_dict == NULL)
- {
- lp->ll_tv->vval.v_dict = dict_alloc();
- if (lp->ll_tv->vval.v_dict == NULL)
- {
- clear_tv(&var1);
- return NULL;
- }
- ++lp->ll_tv->vval.v_dict->dv_refcount;
- }
- lp->ll_dict = lp->ll_tv->vval.v_dict;
-
- lp->ll_di = dict_find(lp->ll_dict, key, len);
-
- // When assigning to a scope dictionary check that a function and
- // variable name is valid (only variable name unless it is l: or
- // g: dictionary). Disallow overwriting a builtin function.
- if (rettv != NULL && lp->ll_dict->dv_scope != 0)
- {
- int prevval;
-
- if (len != -1)
- {
- prevval = key[len];
- key[len] = NUL;
- }
- else
- prevval = 0; // avoid compiler warning
- int wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
- && (rettv->v_type == VAR_FUNC
- || rettv->v_type == VAR_PARTIAL)
- && var_wrong_func_name(key, lp->ll_di == NULL))
- || !valid_varname(key, -1, TRUE);
- if (len != -1)
- key[len] = prevval;
- if (wrong)
- {
- clear_tv(&var1);
- return NULL;
- }
- }
-
- if (lp->ll_valtype != NULL)
- // use the type of the member
- lp->ll_valtype = lp->ll_valtype->tt_member;
-
- if (lp->ll_di == NULL)
- {
- // Can't add "v:" or "a:" variable.
- if (lp->ll_dict == get_vimvar_dict()
- || &lp->ll_dict->dv_hashtab == get_funccal_args_ht())
- {
- semsg(_(e_illegal_variable_name_str), name);
- clear_tv(&var1);
- return NULL;
- }
-
- // Key does not exist in dict: may need to add it.
- if (*p == '[' || *p == '.' || unlet)
- {
- if (!quiet)
- semsg(_(e_key_not_present_in_dictionary_str), key);
- clear_tv(&var1);
- return NULL;
- }
- if (len == -1)
- lp->ll_newkey = vim_strsave(key);
- else
- lp->ll_newkey = vim_strnsave(key, len);
- clear_tv(&var1);
- if (lp->ll_newkey == NULL)
- p = NULL;
- break;
- }
- // existing variable, need to check if it can be changed
- else if ((flags & GLV_READ_ONLY) == 0
- && (var_check_ro(lp->ll_di->di_flags, name, FALSE)
- || var_check_lock(lp->ll_di->di_flags, name, FALSE)))
- {
- clear_tv(&var1);
- return NULL;
- }
-
- clear_tv(&var1);
- lp->ll_tv = &lp->ll_di->di_tv;
- }
- else if (v_type == VAR_BLOB)
- {
- long bloblen = blob_len(lp->ll_tv->vval.v_blob);
-
- /*
- * Get the number and item for the only or first index of the List.
- */
- if (empty1)
- lp->ll_n1 = 0;
- else
- // is number or string
- lp->ll_n1 = (long)tv_get_number(&var1);
- clear_tv(&var1);
-
- if (check_blob_index(bloblen, lp->ll_n1, quiet) == FAIL)
- {
- clear_tv(&var2);
- return NULL;
- }
- if (lp->ll_range && !lp->ll_empty2)
- {
- lp->ll_n2 = (long)tv_get_number(&var2);
- clear_tv(&var2);
- if (check_blob_range(bloblen, lp->ll_n1, lp->ll_n2, quiet)
- == FAIL)
- return NULL;
- }
- lp->ll_blob = lp->ll_tv->vval.v_blob;
- lp->ll_tv = NULL;
- break;
- }
- else if (v_type == VAR_LIST)
- {
- /*
- * Get the number and item for the only or first index of the List.
- */
- if (empty1)
- lp->ll_n1 = 0;
- else
- // is number or string
- lp->ll_n1 = (long)tv_get_number(&var1);
- clear_tv(&var1);
-
- lp->ll_dict = NULL;
- lp->ll_object = NULL;
- lp->ll_class = NULL;
- lp->ll_list = lp->ll_tv->vval.v_list;
- lp->ll_li = check_range_index_one(lp->ll_list, &lp->ll_n1,
- (flags & GLV_ASSIGN_WITH_OP) == 0, quiet);
- if (lp->ll_li == NULL)
- {
- clear_tv(&var2);
- return NULL;
- }
-
- if (lp->ll_valtype != NULL)
- // use the type of the member
- lp->ll_valtype = lp->ll_valtype->tt_member;
-
- /*
- * May need to find the item or absolute index for the second
- * index of a range.
- * When no index given: "lp->ll_empty2" is TRUE.
- * Otherwise "lp->ll_n2" is set to the second index.
- */
- if (lp->ll_range && !lp->ll_empty2)
- {
- lp->ll_n2 = (long)tv_get_number(&var2);
- // is number or string
- clear_tv(&var2);
- if (check_range_index_two(lp->ll_list,
- &lp->ll_n1, lp->ll_li,
- &lp->ll_n2, quiet) == FAIL)
- return NULL;
- }
-
- lp->ll_tv = &lp->ll_li->li_tv;
- }
- else // v_type == VAR_CLASS || v_type == VAR_OBJECT
- {
- lp->ll_dict = NULL;
- lp->ll_list = NULL;
-
- class_T *cl;
- if (v_type == VAR_OBJECT)
- {
- if (lp->ll_tv->vval.v_object == NULL)
- {
- if (!quiet)
- emsg(_(e_using_null_object));
- return NULL;
- }
- cl = lp->ll_tv->vval.v_object->obj_class;
- lp->ll_object = lp->ll_tv->vval.v_object;
- }
- else
- {
- cl = lp->ll_tv->vval.v_class;
- lp->ll_object = NULL;
- }
- lp->ll_class = cl;
-
- // TODO: what if class is NULL?
- if (cl != NULL)
- {
- lp->ll_valtype = NULL;
-
- if (flags & GLV_PREFER_FUNC)
- {
- // First look for a function with this name.
- // round 1: class functions (skipped for an object)
- // round 2: object methods
- for (int round = v_type == VAR_OBJECT ? 2 : 1;
- round <= 2; ++round)
- {
- int m_idx;
- ufunc_T *fp;
-
- fp = method_lookup(cl,
- round == 1 ? VAR_CLASS : VAR_OBJECT,
- key, p - key, &m_idx);
- lp->ll_oi = m_idx;
- if (fp != NULL)
- {
- lp->ll_ufunc = fp;
- lp->ll_valtype = fp->uf_func_type;
- break;
- }
- }
- }
-
- if (lp->ll_valtype == NULL)
- {
- int m_idx;
- ocmember_T *om
- = member_lookup(cl, v_type, key, p - key, &m_idx);
- lp->ll_oi = m_idx;
- if (om != NULL)
- {
- if (get_lval_check_access(cl_exec, cl, om,
- p, flags) == FAIL)
- return NULL;
-
- // When lhs is used to modify the variable, check it is
- // not a read-only variable.
- if ((flags & GLV_READ_ONLY) == 0
- && (*p != '.' && *p != '[')
- && oc_var_check_ro(cl, om))
- return NULL;
-
- 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];
- }
- }
-
- if (lp->ll_valtype == NULL)
- {
- member_not_found_msg(cl, v_type, key, p - key);
- return NULL;
- }
- }
- }
}
- clear_tv(&var1);
lp->ll_name_end = p;
return p;
}
@@ -2085,159 +2354,238 @@ set_var_lval(
}
/*
- * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2"
- * and "tv1 .= tv2"
+ * Handle "blob1 += blob2".
* Returns OK or FAIL.
*/
- int
-tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
+ static int
+tv_op_blob(typval_T *tv1, typval_T *tv2, char_u *op)
+{
+ if (*op != '+' || tv2->v_type != VAR_BLOB)
+ return FAIL;
+
+ // Blob += Blob
+ if (tv2->vval.v_blob == NULL)
+ return OK;
+
+ if (tv1->vval.v_blob == NULL)
+ {
+ tv1->vval.v_blob = tv2->vval.v_blob;
+ ++tv1->vval.v_blob->bv_refcount;
+ return OK;
+ }
+
+ blob_T *b1 = tv1->vval.v_blob;
+ blob_T *b2 = tv2->vval.v_blob;
+ int len = blob_len(b2);
+
+ for (int i = 0; i < len; i++)
+ ga_append(&b1->bv_ga, blob_get(b2, i));
+
+ return OK;
+}
+
+/*
+ * Handle "list1 += list2".
+ * Returns OK or FAIL.
+ */
+ static int
+tv_op_list(typval_T *tv1, typval_T *tv2, char_u *op)
+{
+ if (*op != '+' || tv2->v_type != VAR_LIST)
+ return FAIL;
+
+ // List += List
+ if (tv2->vval.v_list == NULL)
+ return OK;
+
+ if (tv1->vval.v_list == NULL)
+ {
+ tv1->vval.v_list = tv2->vval.v_list;
+ ++tv1->vval.v_list->lv_refcount;
+ }
+ else
+ list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+
+ return OK;
+}
+
+/*
+ * Handle number operations:
+ * nr += nr , nr -= nr , nr *=nr , nr /= nr , nr %= nr
+ *
+ * Returns OK or FAIL.
+ */
+ static int
+tv_op_number(typval_T *tv1, typval_T *tv2, char_u *op)
{
varnumber_T n;
+ int failed = FALSE;
+
+ n = tv_get_number(tv1);
+ if (tv2->v_type == VAR_FLOAT)
+ {
+ float_T f = n;
+
+ if (*op == '%')
+ return FAIL;
+ switch (*op)
+ {
+ case '+': f += tv2->vval.v_float; break;
+ case '-': f -= tv2->vval.v_float; break;
+ case '*': f *= tv2->vval.v_float; break;
+ case '/': f /= tv2->vval.v_float; break;
+ }
+ clear_tv(tv1);
+ tv1->v_type = VAR_FLOAT;
+ tv1->vval.v_float = f;
+ }
+ else
+ {
+ switch (*op)
+ {
+ case '+': n += tv_get_number(tv2); break;
+ case '-': n -= tv_get_number(tv2); break;
+ case '*': n *= tv_get_number(tv2); break;
+ case '/': n = num_divide(n, tv_get_number(tv2), &failed); break;
+ case '%': n = num_modulus(n, tv_get_number(tv2), &failed); break;
+ }
+ clear_tv(tv1);
+ tv1->v_type = VAR_NUMBER;
+ tv1->vval.v_number = n;
+ }
+
+ return failed ? FAIL : OK;
+}
+
+/*
+ * Handle "str1 .= str2"
+ * Returns OK or FAIL.
+ */
+ static int
+tv_op_string(typval_T *tv1, typval_T *tv2, char_u *op UNUSED)
+{
char_u numbuf[NUMBUFLEN];
char_u *s;
- int failed = FALSE;
- // Can't do anything with a Funcref or Dict or Type on the right.
+ if (tv2->v_type == VAR_FLOAT)
+ return FAIL;
+
+ // str .= str
+ s = tv_get_string(tv1);
+ s = concat_str(s, tv_get_string_buf(tv2, numbuf));
+ clear_tv(tv1);
+ tv1->v_type = VAR_STRING;
+ tv1->vval.v_string = s;
+
+ return OK;
+}
+
+/*
+ * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2"
+ * and "tv1 .= tv2"
+ * Returns OK or FAIL.
+ */
+ static int
+tv_op_nr_or_string(typval_T *tv1, typval_T *tv2, char_u *op)
+{
+ if (tv2->v_type == VAR_LIST)
+ return FAIL;
+
+ if (vim_strchr((char_u *)"+-*/%", *op) != NULL)
+ return tv_op_number(tv1, tv2, op);
+
+ return tv_op_string(tv1, tv2, op);
+}
+
+/*
+ * Handle "f1 += f2", "f1 -= f2", "f1 *= f2", "f1 /= f2".
+ * Returns OK or FAIL.
+ */
+ static int
+tv_op_float(typval_T *tv1, typval_T *tv2, char_u *op)
+{
+ float_T f;
+
+ if (*op == '%' || *op == '.'
+ || (tv2->v_type != VAR_FLOAT
+ && tv2->v_type != VAR_NUMBER
+ && tv2->v_type != VAR_STRING))
+ return FAIL;
+
+ if (tv2->v_type == VAR_FLOAT)
+ f = tv2->vval.v_float;
+ else
+ f = tv_get_number(tv2);
+ switch (*op)
+ {
+ case '+': tv1->vval.v_float += f; break;
+ case '-': tv1->vval.v_float -= f; break;
+ case '*': tv1->vval.v_float *= f; break;
+ case '/': tv1->vval.v_float /= f; break;
+ }
+
+ return OK;
+}
+
+/*
+ * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2"
+ * and "tv1 .= tv2"
+ * Returns OK or FAIL.
+ */
+ int
+tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
+{
+ // Can't do anything with a Funcref or Dict on the right.
// v:true and friends only work with "..=".
- if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
- && tv2->v_type != VAR_CLASS && tv2->v_type != VAR_TYPEALIAS
- && ((tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL)
- || *op == '.'))
- {
- switch (tv1->v_type)
- {
- case VAR_UNKNOWN:
- case VAR_ANY:
- case VAR_VOID:
- case VAR_DICT:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_JOB:
- case VAR_CHANNEL:
- case VAR_INSTR:
- case VAR_OBJECT:
- break;
- case VAR_CLASS:
- case VAR_TYPEALIAS:
- check_typval_is_value(tv1);
- return FAIL;
+ if (tv2->v_type == VAR_FUNC || tv2->v_type == VAR_DICT
+ || ((tv2->v_type == VAR_BOOL || tv2->v_type == VAR_SPECIAL)
+ && *op != '.'))
+ {
+ semsg(_(e_wrong_variable_type_for_str_equal), op);
+ return FAIL;
+ }
- case VAR_BLOB:
- if (*op != '+' || tv2->v_type != VAR_BLOB)
- break;
- // BLOB += BLOB
- if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL)
- {
- blob_T *b1 = tv1->vval.v_blob;
- blob_T *b2 = tv2->vval.v_blob;
- int i, len = blob_len(b2);
- for (i = 0; i < len; i++)
- ga_append(&b1->bv_ga, blob_get(b2, i));
- }
- return OK;
+ int retval = FAIL;
+ switch (tv1->v_type)
+ {
+ case VAR_UNKNOWN:
+ case VAR_ANY:
+ case VAR_VOID:
+ case VAR_DICT:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_JOB:
+ case VAR_CHANNEL:
+ case VAR_INSTR:
+ case VAR_OBJECT:
+ case VAR_CLASS:
+ case VAR_TYPEALIAS:
+ break;
- case VAR_LIST:
- if (*op != '+' || tv2->v_type != VAR_LIST)
- break;
- // List += List
- if (tv2->vval.v_list != NULL)
- {
- if (tv1->vval.v_list == NULL)
- {
- tv1->vval.v_list = tv2->vval.v_list;
- ++tv1->vval.v_list->lv_refcount;
- }
- else
- list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
- }
- return OK;
+ case VAR_BLOB:
+ retval = tv_op_blob(tv1, tv2, op);
+ break;
- case VAR_NUMBER:
- case VAR_STRING:
- if (tv2->v_type == VAR_LIST)
- break;
- if (vim_strchr((char_u *)"+-*/%", *op) != NULL)
- {
- // nr += nr , nr -= nr , nr *=nr , nr /= nr , nr %= nr
- n = tv_get_number(tv1);
- if (tv2->v_type == VAR_FLOAT)
- {
- float_T f = n;
-
- if (*op == '%')
- break;
- switch (*op)
- {
- case '+': f += tv2->vval.v_float; break;
- case '-': f -= tv2->vval.v_float; break;
- case '*': f *= tv2->vval.v_float; break;
- case '/': f /= tv2->vval.v_float; break;
- }
- clear_tv(tv1);
- tv1->v_type = VAR_FLOAT;
- tv1->vval.v_float = f;
- }
- else
- {
- switch (*op)
- {
- case '+': n += tv_get_number(tv2); break;
- case '-': n -= tv_get_number(tv2); break;
- case '*': n *= tv_get_number(tv2); break;
- case '/': n = num_divide(n, tv_get_number(tv2),
- &failed); break;
- case '%': n = num_modulus(n, tv_get_number(tv2),
- &failed); break;
- }
- clear_tv(tv1);
- tv1->v_type = VAR_NUMBER;
- tv1->vval.v_number = n;
- }
- }
- else
- {
- if (tv2->v_type == VAR_FLOAT)
- break;
-
- // str .= str
- s = tv_get_string(tv1);
- s = concat_str(s, tv_get_string_buf(tv2, numbuf));
- clear_tv(tv1);
- tv1->v_type = VAR_STRING;
- tv1->vval.v_string = s;
- }
- return failed ? FAIL : OK;
+ case VAR_LIST:
+ retval = tv_op_list(tv1, tv2, op);
+ break;
- case VAR_FLOAT:
- {
- float_T f;
-
- if (*op == '%' || *op == '.'
- || (tv2->v_type != VAR_FLOAT
- && tv2->v_type != VAR_NUMBER
- && tv2->v_type != VAR_STRING))
- break;
- if (tv2->v_type == VAR_FLOAT)
- f = tv2->vval.v_float;
- else
- f = tv_get_number(tv2);
- switch (*op)
- {
- case '+': tv1->vval.v_float += f; break;
- case '-': tv1->vval.v_float -= f; break;
- case '*': tv1->vval.v_float *= f; break;
- case '/': tv1->vval.v_float /= f; break;
- }
- }
- return OK;
- }
+ case VAR_NUMBER:
+ case VAR_STRING:
+ retval = tv_op_nr_or_string(tv1, tv2, op);
+ break;
+
+ case VAR_FLOAT:
+ retval = tv_op_float(tv1, tv2, op);
+ break;
}
- if (check_typval_is_value(tv2) == OK)
+ if (retval != OK)
semsg(_(e_wrong_variable_type_for_str_equal), op);
- return FAIL;
+
+ return retval;
}
/*
@@ -2714,7 +3062,7 @@ newline_skip_comments(char_u *arg)
char_u *nl = vim_strchr(p, NL);
if (nl == NULL)
- break;
+ break;
p = nl;
}
if (*p != NL)
@@ -3599,6 +3947,40 @@ eval_addlist(typval_T *tv1, typval_T *tv2)
}
/*
+ * Left or right shift the number "tv1" by the number "tv2" and store the
+ * result in "tv1".
+ *
+ * Return OK or FAIL.
+ */
+ static int
+eval_shift_number(typval_T *tv1, typval_T *tv2, int shift_type)
+{
+ if (tv2->v_type != VAR_NUMBER || tv2->vval.v_number < 0)
+ {
+ // right operand should be a positive number
+ if (tv2->v_type != VAR_NUMBER)
+ emsg(_(e_bitshift_ops_must_be_number));
+ else
+ emsg(_(e_bitshift_ops_must_be_positive));
+ clear_tv(tv1);
+ clear_tv(tv2);
+ return FAIL;
+ }
+
+ if (tv2->vval.v_number > MAX_LSHIFT_BITS)
+ // shifting more bits than we have always results in zero
+ tv1->vval.v_number = 0;
+ else if (shift_type == EXPR_LSHIFT)
+ tv1->vval.v_number =
+ (uvarnumber_T)tv1->vval.v_number << tv2->vval.v_number;
+ else
+ tv1->vval.v_number =
+ (uvarnumber_T)tv1->vval.v_number >> tv2->vval.v_number;
+
+ return OK;
+}
+
+/*
* Handle the bitwise left/right shift operator expression:
* var1 << var2
* var1 >> var2
@@ -3624,16 +4006,16 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
{
char_u *p;
int getnext;
- exprtype_T type;
+ exprtype_T exprtype;
int evaluate;
typval_T var2;
int vim9script;
p = eval_next_non_blank(*arg, evalarg, &getnext);
if (p[0] == '<' && p[1] == '<')
- type = EXPR_LSHIFT;
+ exprtype = EXPR_LSHIFT;
else if (p[0] == '>' && p[1] == '>')
- type = EXPR_RSHIFT;
+ exprtype = EXPR_RSHIFT;
else
return OK;
@@ -3678,27 +4060,8 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
if (evaluate)
{
- if (var2.v_type != VAR_NUMBER || var2.vval.v_number < 0)
- {
- // right operand should be a positive number
- if (var2.v_type != VAR_NUMBER)
- emsg(_(e_bitshift_ops_must_be_number));
- else
- emsg(_(e_bitshift_ops_must_be_positive));
- clear_tv(rettv);
- clear_tv(&var2);
+ if (eval_shift_number(rettv, &var2, exprtype) == FAIL)
return FAIL;
- }
-
- if (var2.vval.v_number > MAX_LSHIFT_BITS)
- // shifting more bits than we have always results in zero
- rettv->vval.v_number = 0;
- else if (type == EXPR_LSHIFT)
- rettv->vval.v_number =
- (uvarnumber_T)rettv->vval.v_number << var2.vval.v_number;
- else
- rettv->vval.v_number =
- (uvarnumber_T)rettv->vval.v_number >> var2.vval.v_number;
}
clear_tv(&var2);
@@ -3708,6 +4071,120 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
}
/*
+ * Concatenate strings "tv1" and "tv2" and store the result in "tv1".
+ */
+ static int
+eval_concat_str(typval_T *tv1, typval_T *tv2)
+{
+ char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
+ char_u *s1 = tv_get_string_buf(tv1, buf1);
+ char_u *s2 = NULL;
+ char_u *p;
+ int vim9script = in_vim9script();
+
+ if (vim9script && (tv2->v_type == VAR_VOID
+ || tv2->v_type == VAR_CHANNEL
+ || tv2->v_type == VAR_JOB))
+ semsg(_(e_using_invalid_value_as_string_str),
+ vartype_name(tv2->v_type));
+ else if (vim9script && tv2->v_type == VAR_FLOAT)
+ {
+ vim_snprintf((char *)buf2, NUMBUFLEN, "%g",
+ tv2->vval.v_float);
+ s2 = buf2;
+ }
+ else
+ s2 = tv_get_string_buf_chk(tv2, buf2);
+ if (s2 == NULL) // type error ?
+ {
+ clear_tv(tv1);
+ clear_tv(tv2);
+ return FAIL;
+ }
+
+ p = concat_str(s1, s2);
+ clear_tv(tv1);
+ tv1->v_type = VAR_STRING;
+ tv1->vval.v_string = p;
+
+ return OK;
+}
+
+/*
+ * Add or subtract numbers "tv1" and "tv2" and store the result in "tv1".
+ * The numbers can be whole numbers or floats.
+ */
+ static int
+eval_addsub_number(typval_T *tv1, typval_T *tv2, int op)
+{
+ int error = FALSE;
+ varnumber_T n1, n2;
+ float_T f1 = 0, f2 = 0;
+
+ if (tv1->v_type == VAR_FLOAT)
+ {
+ f1 = tv1->vval.v_float;
+ n1 = 0;
+ }
+ else
+ {
+ n1 = tv_get_number_chk(tv1, &error);
+ if (error)
+ {
+ // This can only happen for "list + non-list" or
+ // "blob + non-blob". For "non-list + ..." or
+ // "something - ...", we returned before evaluating the
+ // 2nd operand.
+ clear_tv(tv1);
+ clear_tv(tv2);
+ return FAIL;
+ }
+ if (tv2->v_type == VAR_FLOAT)
+ f1 = n1;
+ }
+ if (tv2->v_type == VAR_FLOAT)
+ {
+ f2 = tv2->vval.v_float;
+ n2 = 0;
+ }
+ else
+ {
+ n2 = tv_get_number_chk(tv2, &error);
+ if (error)
+ {
+ clear_tv(tv1);
+ clear_tv(tv2);
+ return FAIL;
+ }
+ if (tv1->v_type == VAR_FLOAT)
+ f2 = n2;
+ }
+ clear_tv(tv1);
+
+ // If there is a float on either side the result is a float.
+ if (tv1->v_type == VAR_FLOAT || tv2->v_type == VAR_FLOAT)
+ {
+ if (op == '+')
+ f1 = f1 + f2;
+ else
+ f1 = f1 - f2;
+ tv1->v_type = VAR_FLOAT;
+ tv1->vval.v_float = f1;
+ }
+ else
+ {
+ if (op == '+')
+ n1 = n1 + n2;
+ else
+ n1 = n1 - n2;
+ tv1->v_type = VAR_NUMBER;
+ tv1->vval.v_number = n1;
+ }
+
+ return OK;
+}
+
+/*
* Handle fifth level expression:
* + number addition, concatenation of list or blob
* - number subtraction
@@ -3814,33 +4291,8 @@ eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
*/
if (op == '.')
{
- char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
- char_u *s1 = tv_get_string_buf(rettv, buf1);
- char_u *s2 = NULL;
-
- if (vim9script && (var2.v_type == VAR_VOID
- || var2.v_type == VAR_CHANNEL
- || var2.v_type == VAR_JOB))
- semsg(_(e_using_invalid_value_as_string_str),
- vartype_name(var2.v_type));
- else if (vim9script && var2.v_type == VAR_FLOAT)
- {
- vim_snprintf((char *)buf2, NUMBUFLEN, "%g",
- var2.vval.v_float);
- s2 = buf2;
- }
- else
- s2 = tv_get_string_buf_chk(&var2, buf2);
- if (s2 == NULL) // type error ?
- {
- clear_tv(rettv);
- clear_tv(&var2);
+ if (eval_concat_str(rettv, &var2) == FAIL)
return FAIL;
- }
- p = concat_str(s1, s2);
- clear_tv(rettv);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = p;
}
else if (op == '+' && rettv->v_type == VAR_BLOB
&& var2.v_type == VAR_BLOB)
@@ -3853,73 +4305,119 @@ eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
}
else
{
- int error = FALSE;
- varnumber_T n1, n2;
- float_T f1 = 0, f2 = 0;
+ if (eval_addsub_number(rettv, &var2, op) == FAIL)
+ return FAIL;
+ }
+ clear_tv(&var2);
+ }
+ }
+ return OK;
+}
- if (rettv->v_type == VAR_FLOAT)
- {
- f1 = rettv->vval.v_float;
- n1 = 0;
- }
- else
- {
- n1 = tv_get_number_chk(rettv, &error);
- if (error)
- {
- // This can only happen for "list + non-list" or
- // "blob + non-blob". For "non-list + ..." or
- // "something - ...", we returned before evaluating the
- // 2nd operand.
- clear_tv(rettv);
- clear_tv(&var2);
- return FAIL;
- }
- if (var2.v_type == VAR_FLOAT)
- f1 = n1;
- }
- if (var2.v_type == VAR_FLOAT)
- {
- f2 = var2.vval.v_float;
- n2 = 0;
- }
- else
- {
- n2 = tv_get_number_chk(&var2, &error);
- if (error)
- {
- clear_tv(rettv);
- clear_tv(&var2);
- return FAIL;
- }
- if (rettv->v_type == VAR_FLOAT)
- f2 = n2;
- }
- clear_tv(rettv);
+/*
+ * Multiply or divide or compute the modulo of numbers "tv1" and "tv2" and
+ * store the result in "tv1". The numbers can be whole numbers or floats.
+ */
+ static int
+eval_multdiv_number(typval_T *tv1, typval_T *tv2, int op)
+{
+ varnumber_T n1, n2;
+ float_T f1, f2;
+ int error;
+ int use_float = FALSE;
- // If there is a float on either side the result is a float.
- if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
- {
- if (op == '+')
- f1 = f1 + f2;
- else
- f1 = f1 - f2;
- rettv->v_type = VAR_FLOAT;
- rettv->vval.v_float = f1;
- }
+ f1 = 0;
+ f2 = 0;
+ error = FALSE;
+ if (tv1->v_type == VAR_FLOAT)
+ {
+ f1 = tv1->vval.v_float;
+ use_float = TRUE;
+ n1 = 0;
+ }
+ else
+ n1 = tv_get_number_chk(tv1, &error);
+ clear_tv(tv1);
+ if (error)
+ {
+ clear_tv(tv2);
+ return FAIL;
+ }
+
+ if (tv2->v_type == VAR_FLOAT)
+ {
+ if (!use_float)
+ {
+ f1 = n1;
+ use_float = TRUE;
+ }
+ f2 = tv2->vval.v_float;
+ n2 = 0;
+ }
+ else
+ {
+ n2 = tv_get_number_chk(tv2, &error);
+ clear_tv(tv2);
+ if (error)
+ return FAIL;
+ if (use_float)
+ f2 = n2;
+ }
+
+ /*
+ * Compute the result.
+ * When either side is a float the result is a float.
+ */
+ if (use_float)
+ {
+ if (op == '*')
+ f1 = f1 * f2;
+ else if (op == '/')
+ {
+#ifdef VMS
+ // VMS crashes on divide by zero, work around it
+ if (f2 == 0.0)
+ {
+ if (f1 == 0)
+ f1 = -1 * __F_FLT_MAX - 1L; // similar to NaN
+ else if (f1 < 0)
+ f1 = -1 * __F_FLT_MAX;
else
- {
- if (op == '+')
- n1 = n1 + n2;
- else
- n1 = n1 - n2;
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = n1;
- }
+ f1 = __F_FLT_MAX;
}
- clear_tv(&var2);
+ else
+ f1 = f1 / f2;
+#else
+ // We rely on the floating point library to handle divide
+ // by zero to result in "inf" and not a crash.
+ f1 = f1 / f2;
+#endif
}
+ else
+ {
+ emsg(_(e_cannot_use_percent_with_float));
+ return FAIL;
+ }
+ tv1->v_type = VAR_FLOAT;
+ tv1->vval.v_float = f1;
+ }
+ else
+ {
+ int failed = FALSE;
+
+ if (op == '*')
+ n1 = n1 * n2;
+ else if (op == '/')
+ n1 = num_divide(n1, n2, &failed);
+ else
+ n1 = num_modulus(n1, n2, &failed);
+ if (failed)
+ return FAIL;
+
+ tv1->v_type = VAR_NUMBER;
+ tv1->vval.v_number = n1;
}
+
return OK;
}
@@ -3941,8 +4439,6 @@ eval7(
evalarg_T *evalarg,
int want_string) // after "." operator
{
- int use_float = FALSE;
-
/*
* Get the first expression.
*/
@@ -3959,9 +4455,6 @@ eval7(
typval_T var2;
char_u *p;
int op;
- varnumber_T n1, n2;
- float_T f1, f2;
- int error;
// "*=", "/=" and "%=" are assignments
p = eval_next_non_blank(*arg, evalarg, &getnext);
@@ -3983,26 +4476,6 @@ eval7(
*arg = p;
}
- f1 = 0;
- f2 = 0;
- error = FALSE;
- if (evaluate)
- {
- if (rettv->v_type == VAR_FLOAT)
- {
- f1 = rettv->vval.v_float;
- use_float = TRUE;
- n1 = 0;
- }
- else
- n1 = tv_get_number_chk(rettv, &error);
- clear_tv(rettv);
- if (error)
- return FAIL;
- }
- else
- n1 = 0;
-
/*
* Get the second variable.
*/
@@ -4017,81 +4490,9 @@ eval7(
return FAIL;
if (evaluate)
- {
- if (var2.v_type == VAR_FLOAT)
- {
- if (!use_float)
- {
- f1 = n1;
- use_float = TRUE;
- }
- f2 = var2.vval.v_float;
- n2 = 0;
- }
- else
- {
- n2 = tv_get_number_chk(&var2, &error);
- clear_tv(&var2);
- if (error)
- return FAIL;
- if (use_float)
- f2 = n2;
- }
-
- /*
- * Compute the result.
- * When either side is a float the result is a float.
- */
- if (use_float)
- {
- if (op == '*')
- f1 = f1 * f2;
- else if (op == '/')
- {
-#ifdef VMS
- // VMS crashes on divide by zero, work around it
- if (f2 == 0.0)
- {
- if (f1 == 0)
- f1 = -1 * __F_FLT_MAX - 1L; // similar to NaN
- else if (f1 < 0)
- f1 = -1 * __F_FLT_MAX;
- else
- f1 = __F_FLT_MAX;
- }
- else
- f1 = f1 / f2;
-#else
- // We rely on the floating point library to handle divide
- // by zero to result in "inf" and not a crash.
- f1 = f1 / f2;
-#endif
- }
- else
- {
- emsg(_(e_cannot_use_percent_with_float));
- return FAIL;
- }
- rettv->v_type = VAR_FLOAT;
- rettv->vval.v_float = f1;
- }
- else
- {
- int failed = FALSE;
-
- if (op == '*')
- n1 = n1 * n2;
- else if (op == '/')
- n1 = num_divide(n1, n2, &failed);
- else
- n1 = num_modulus(n1, n2, &failed);
- if (failed)
- return FAIL;
-
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = n1;
- }
- }
+ // Compute the result.
+ if (eval_multdiv_number(rettv, &var2, op) == FAIL)
+ return FAIL;
}
return OK;
@@ -4244,18 +4645,21 @@ handle_predefined(char_u *s, int len, typval_T *rettv)
case 9:
if (STRNCMP(s, "null_", 5) != 0)
break;
+ // null_list
if (STRNCMP(s + 5, "list", 4) == 0)
{
rettv->v_type = VAR_LIST;
rettv->vval.v_list = NULL;
return OK;
}
+ // null_dict
if (STRNCMP(s + 5, "dict", 4) == 0)
{
rettv->v_type = VAR_DICT;
rettv->vval.v_dict = NULL;
return OK;
}
+ // null_blob
if (STRNCMP(s + 5, "blob", 4) == 0)
{
rettv->v_type = VAR_BLOB;
@@ -4314,6 +4718,158 @@ handle_predefined(char_u *s, int len, typval_T *rettv)
}
/*
+ * Handle register contents: @r.
+ */
+ static void
+eval9_reg_contents(
+ char_u **arg,
+ typval_T *rettv,
+ int evaluate)
+{
+ int vim9script = in_vim9script();
+
+ ++*arg; // skip '@'
+ if (evaluate)
+ {
+ if (vim9script && IS_WHITE_OR_NUL(**arg))
+ semsg(_(e_syntax_error_at_str), *arg);
+ else if (vim9script && !valid_yank_reg(**arg, FALSE))
+ emsg_invreg(**arg);
+ else
+ {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = get_reg_contents(**arg,
+ GREG_EXPR_SRC);
+ }
+ }
+ if (**arg != NUL)
+ ++*arg;
+}
+
+/*
+ * Handle a nested expression: (expression) or lambda: (arg) => expr
+ */
+ static int
+eval9_nested_expr(
+ char_u **arg,
+ typval_T *rettv,
+ evalarg_T *evalarg,
+ int evaluate)
+{
+ int ret = NOTDONE;
+ int vim9script = in_vim9script();
+
+ if (vim9script)
+ {
+ ret = get_lambda_tv(arg, rettv, TRUE, evalarg);
+ if (ret == OK && evaluate)
+ {
+ ufunc_T *ufunc = rettv->vval.v_partial->pt_func;
+
+ // Compile it here to get the return type. The return
+ // type is optional, when it's missing use t_unknown.
+ // This is recognized in compile_return().
+ if (ufunc->uf_ret_type->tt_type == VAR_VOID)
+ ufunc->uf_ret_type = &t_unknown;
+ if (compile_def_function(ufunc, FALSE,
+ get_compile_type(ufunc), NULL) == FAIL)
+ {
+ clear_tv(rettv);
+ ret = FAIL;
+ }
+ }
+ }
+ if (ret == NOTDONE)
+ {
+ *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
+ ret = eval1(arg, rettv, evalarg); // recursive!
+
+ *arg = skipwhite_and_linebreak(*arg, evalarg);
+ if (**arg == ')')
+ ++*arg;
+ else if (ret == OK)
+ {
+ emsg(_(e_missing_closing_paren));
+ clear_tv(rettv);
+ ret = FAIL;
+ }
+ }
+
+ return ret;
+}
+
+/*
+* Handle be a variable or function name.
+* Can also be a curly-braces kind of name: {expr}.
+*/
+ static int
+eval9_var_func_name(
+ char_u **arg,
+ typval_T *rettv,
+ evalarg_T *evalarg,
+ int evaluate,
+ char_u **name_start)
+{
+ char_u *s;
+ int len;
+ char_u *alias;
+ int ret = OK;
+ int vim9script = in_vim9script();
+
+ s = *arg;
+ len = get_name_len(arg, &alias, evaluate, TRUE);
+ if (alias != NULL)
+ s = alias;
+
+ if (len <= 0)
+ ret = FAIL;
+ else
+ {
+ int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
+
+ if (evaluate && vim9script && len == 1 && *s == '_')
+ {
+ emsg(_(e_cannot_use_underscore_here));
+ ret = FAIL;
+ }
+ else if (evaluate && vim9script && len > 2
+ && s[0] == 's' && s[1] == ':')
+ {
+ semsg(_(e_cannot_use_s_colon_in_vim9_script_str), s);
+ ret = FAIL;
+ }
+ else if ((vim9script ? **arg : *skipwhite(*arg)) == '(')
+ {
+ // "name(..." recursive!
+ *arg = skipwhite(*arg);
+ ret = eval_func(arg, evalarg, s, len, rettv, flags, NULL);
+ }
+ else if (evaluate)
+ {
+ // get the value of "true", "false", etc. or a variable
+ ret = FAIL;
+ if (vim9script)
+ ret = handle_predefined(s, len, rettv);
+ if (ret == FAIL)
+ {
+ *name_start = s;
+ ret = eval_variable(s, len, 0, rettv, NULL,
+ EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT);
+ }
+ }
+ else
+ {
+ // skip the name
+ check_vars(s, len);
+ ret = OK;
+ }
+ }
+ vim_free(alias);
+
+ return ret;
+}
+
+/*
* Handle sixth level expression:
* number number constant
* 0zFFFFFFFF Blob constant
@@ -4352,12 +4908,9 @@ eval9(
{
int evaluate = evalarg != NULL
&& (evalarg->eval_flags & EVAL_EVALUATE);
- int len;
- char_u *s;
char_u *name_start = NULL;
char_u *start_leader, *end_leader;
int ret = OK;
- char_u *alias;
static int recurse = 0;
int vim9script = in_vim9script();
@@ -4440,19 +4993,9 @@ eval9(
break;
/*
- * Dictionary: #{key: val, key: val}
+ * Literal Dictionary: #{key: val, key: val}
*/
- case '#': if (vim9script)
- {
- ret = vim9_bad_comment(*arg) ? FAIL : NOTDONE;
- }
- else if ((*arg)[1] == '{')
- {
- ++*arg;
- ret = eval_dict(arg, rettv, evalarg, TRUE);
- }
- else
- ret = NOTDONE;
+ case '#': ret = eval_lit_dict(arg, rettv, evalarg);
break;
/*
@@ -4486,64 +5029,14 @@ eval9(
/*
* Register contents: @r.
*/
- case '@': ++*arg;
- if (evaluate)
- {
- if (vim9script && IS_WHITE_OR_NUL(**arg))
- semsg(_(e_syntax_error_at_str), *arg);
- else if (vim9script && !valid_yank_reg(**arg, FALSE))
- emsg_invreg(**arg);
- else
- {
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = get_reg_contents(**arg,
- GREG_EXPR_SRC);
- }
- }
- if (**arg != NUL)
- ++*arg;
+ case '@': eval9_reg_contents(arg, rettv, evaluate);
break;
/*
* nested expression: (expression).
* or lambda: (arg) => expr
*/
- case '(': ret = NOTDONE;
- if (vim9script)
- {
- ret = get_lambda_tv(arg, rettv, TRUE, evalarg);
- if (ret == OK && evaluate)
- {
- ufunc_T *ufunc = rettv->vval.v_partial->pt_func;
-
- // Compile it here to get the return type. The return
- // type is optional, when it's missing use t_unknown.
- // This is recognized in compile_return().
- if (ufunc->uf_ret_type->tt_type == VAR_VOID)
- ufunc->uf_ret_type = &t_unknown;
- if (compile_def_function(ufunc, FALSE,
- get_compile_type(ufunc), NULL) == FAIL)
- {
- clear_tv(rettv);
- ret = FAIL;
- }
- }
- }
- if (ret == NOTDONE)
- {
- *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
- ret = eval1(arg, rettv, evalarg); // recursive!
-
- *arg = skipwhite_and_linebreak(*arg, evalarg);
- if (**arg == ')')
- ++*arg;
- else if (ret == OK)
- {
- emsg(_(e_missing_closing_paren));
- clear_tv(rettv);
- ret = FAIL;
- }
- }
+ case '(': ret = eval9_nested_expr(arg, rettv, evalarg, evaluate);
break;
default: ret = NOTDONE;
@@ -4556,55 +5049,7 @@ eval9(
* Must be a variable or function name.
* Can also be a curly-braces kind of name: {expr}.
*/
- s = *arg;
- len = get_name_len(arg, &alias, evaluate, TRUE);
- if (alias != NULL)
- s = alias;
-
- if (len <= 0)
- ret = FAIL;
- else
- {
- int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
-
- if (evaluate && vim9script && len == 1 && *s == '_')
- {
- emsg(_(e_cannot_use_underscore_here));
- ret = FAIL;
- }
- else if (evaluate && vim9script && len > 2
- && s[0] == 's' && s[1] == ':')
- {
- semsg(_(e_cannot_use_s_colon_in_vim9_script_str), s);
- ret = FAIL;
- }
- else if ((vim9script ? **arg : *skipwhite(*arg)) == '(')
- {
- // "name(..." recursive!
- *arg = skipwhite(*arg);
- ret = eval_func(arg, evalarg, s, len, rettv, flags, NULL);
- }
- else if (evaluate)
- {
- // get the value of "true", "false", etc. or a variable
- ret = FAIL;
- if (vim9script)
- ret = handle_predefined(s, len, rettv);
- if (ret == FAIL)
- {
- name_start = s;
- ret = eval_variable(s, len, 0, rettv, NULL,
- EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT);
- }
- }
- else
- {
- // skip the name
- check_vars(s, len);
- ret = OK;
- }
- }
- vim_free(alias);
+ ret = eval9_var_func_name(arg, rettv, evalarg, evaluate, &name_start);
}
// Handle following '[', '(' and '.' for expr[expr], expr.name,
@@ -4895,7 +5340,7 @@ eval_method(
{
*arg = name;
- // Truncate the name a the "(". Avoid trying to get another line
+ // Truncate the name at the "(". Avoid trying to get another line
// by making "getline" NULL.
*paren = NUL;
char_u *(*getline)(int, void *, int, getline_opt_T) = NULL;
@@ -4950,6 +5395,9 @@ eval_method(
clear_tv(&base);
vim_free(tofree);
+ if (alias != NULL)
+ vim_free(alias);
+
return ret;
}
@@ -5153,30 +5601,6 @@ check_can_index(typval_T *rettv, int evaluate, int verbose)
}
/*
- * slice() function
- */
- void
-f_slice(typval_T *argvars, typval_T *rettv)
-{
- if (in_vim9script()
- && ((argvars[0].v_type != VAR_STRING
- && argvars[0].v_type != VAR_LIST
- && argvars[0].v_type != VAR_BLOB
- && check_for_list_arg(argvars, 0) == FAIL)
- || check_for_number_arg(argvars, 1) == FAIL
- || check_for_opt_number_arg(argvars, 2) == FAIL))
- return;
-
- if (check_can_index(argvars, TRUE, FALSE) != OK)
- return;
-
- copy_tv(argvars, rettv);
- eval_index_inner(rettv, TRUE, argvars + 1,
- argvars[2].v_type == VAR_UNKNOWN ? NULL : argvars + 2,
- TRUE, NULL, 0, FALSE);
-}
-
-/*
* Apply index or range to "rettv".
* "var1" is the first index, NULL for [:expr].
* "var2" is the second index, NULL for [expr] and [expr: ]
@@ -5426,763 +5850,299 @@ partial_unref(partial_T *pt)
}
/*
- * Return the next (unique) copy ID.
- * Used for serializing nested structures.
- */
- int
-get_copyID(void)
-{
- current_copyID += COPYID_INC;
- return current_copyID;
-}
-
-/*
- * Garbage collection for lists and dictionaries.
- *
- * We use reference counts to be able to free most items right away when they
- * are no longer used. But for composite items it's possible that it becomes
- * unused while the reference count is > 0: When there is a recursive
- * reference. Example:
- * :let l = [1, 2, 3]
- * :let d = {9: l}
- * :let l[1] = d
- *
- * Since this is quite unusual we handle this with garbage collection: every
- * once in a while find out which lists and dicts are not referenced from any
- * variable.
- *
- * Here is a good reference text about garbage collection (refers to Python
- * but it applies to all reference-counting mechanisms):
- * http://python.ca/nas/python/gc/
- */
-
-/*
- * Do garbage collection for lists and dicts.
- * When "testing" is TRUE this is called from test_garbagecollect_now().
- * Return TRUE if some memory was freed.
+ * Return a textual representation of a string in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * When both "echo_style" and "composite_val" are FALSE, put quotes around
+ * strings as "string()", otherwise does not put quotes around strings.
+ * May return NULL.
*/
- int
-garbage_collect(int testing)
+ static char_u *
+string_tv2string(
+ typval_T *tv,
+ char_u **tofree,
+ int echo_style,
+ int composite_val)
{
- int copyID;
- int abort = FALSE;
- buf_T *buf;
- win_T *wp;
- int did_free = FALSE;
- tabpage_T *tp;
-
- if (!testing)
- {
- // Only do this once.
- want_garbage_collect = FALSE;
- may_garbage_collect = FALSE;
- garbage_collect_at_exit = FALSE;
- }
-
- // The execution stack can grow big, limit the size.
- if (exestack.ga_maxlen - exestack.ga_len > 500)
- {
- size_t new_len;
- char_u *pp;
- int n;
-
- // Keep 150% of the current size, with a minimum of the growth size.
- n = exestack.ga_len / 2;
- if (n < exestack.ga_growsize)
- n = exestack.ga_growsize;
-
- // Don't make it bigger though.
- if (exestack.ga_len + n < exestack.ga_maxlen)
- {
- new_len = (size_t)exestack.ga_itemsize * (exestack.ga_len + n);
- pp = vim_realloc(exestack.ga_data, new_len);
- if (pp == NULL)
- return FAIL;
- exestack.ga_maxlen = exestack.ga_len + n;
- exestack.ga_data = pp;
- }
- }
-
- // We advance by two because we add one for items referenced through
- // previous_funccal.
- copyID = get_copyID();
-
- /*
- * 1. Go through all accessible variables and mark all lists and dicts
- * with copyID.
- */
-
- // Don't free variables in the previous_funccal list unless they are only
- // referenced through previous_funccal. This must be first, because if
- // the item is referenced elsewhere the funccal must not be freed.
- abort = abort || set_ref_in_previous_funccal(copyID);
-
- // script-local variables
- abort = abort || garbage_collect_scriptvars(copyID);
-
- // buffer-local variables
- FOR_ALL_BUFFERS(buf)
- abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
- NULL, NULL);
-
- // window-local variables
- FOR_ALL_TAB_WINDOWS(tp, wp)
- abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
- NULL, NULL);
- // window-local variables in autocmd windows
- for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
- if (aucmd_win[i].auc_win != NULL)
- abort = abort || set_ref_in_item(
- &aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL);
-#ifdef FEAT_PROP_POPUP
- FOR_ALL_POPUPWINS(wp)
- abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
- NULL, NULL);
- FOR_ALL_TABPAGES(tp)
- FOR_ALL_POPUPWINS_IN_TAB(tp, wp)
- abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
- NULL, NULL);
-#endif
-
- // tabpage-local variables
- FOR_ALL_TABPAGES(tp)
- abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
- NULL, NULL);
- // global variables
- abort = abort || garbage_collect_globvars(copyID);
-
- // function-local variables
- abort = abort || set_ref_in_call_stack(copyID);
-
- // named functions (matters for closures)
- abort = abort || set_ref_in_functions(copyID);
-
- // function call arguments, if v:testing is set.
- abort = abort || set_ref_in_func_args(copyID);
-
- // funcstacks keep variables for closures
- abort = abort || set_ref_in_funcstacks(copyID);
-
- // loopvars keep variables for loop blocks
- abort = abort || set_ref_in_loopvars(copyID);
-
- // v: vars
- abort = abort || garbage_collect_vimvars(copyID);
-
- // callbacks in buffers
- abort = abort || set_ref_in_buffers(copyID);
-
- // 'completefunc', 'omnifunc' and 'thesaurusfunc' callbacks
- abort = abort || set_ref_in_insexpand_funcs(copyID);
-
- // 'operatorfunc' callback
- abort = abort || set_ref_in_opfunc(copyID);
-
- // 'tagfunc' callback
- abort = abort || set_ref_in_tagfunc(copyID);
-
- // 'imactivatefunc' and 'imstatusfunc' callbacks
- abort = abort || set_ref_in_im_funcs(copyID);
-
-#ifdef FEAT_LUA
- abort = abort || set_ref_in_lua(copyID);
-#endif
-
-#ifdef FEAT_PYTHON
- abort = abort || set_ref_in_python(copyID);
-#endif
-
-#ifdef FEAT_PYTHON3
- abort = abort || set_ref_in_python3(copyID);
-#endif
-
-#ifdef FEAT_JOB_CHANNEL
- abort = abort || set_ref_in_channel(copyID);
- abort = abort || set_ref_in_job(copyID);
-#endif
-#ifdef FEAT_NETBEANS_INTG
- abort = abort || set_ref_in_nb_channel(copyID);
-#endif
-
-#ifdef FEAT_TIMERS
- abort = abort || set_ref_in_timer(copyID);
-#endif
-
-#ifdef FEAT_QUICKFIX
- abort = abort || set_ref_in_quickfix(copyID);
-#endif
-
-#ifdef FEAT_TERMINAL
- abort = abort || set_ref_in_term(copyID);
-#endif
-
-#ifdef FEAT_PROP_POPUP
- abort = abort || set_ref_in_popups(copyID);
-#endif
-
- abort = abort || set_ref_in_classes(copyID);
+ char_u *r = NULL;
- if (!abort)
+ if (echo_style && !composite_val)
{
- /*
- * 2. Free lists and dictionaries that are not referenced.
- */
- did_free = free_unref_items(copyID);
-
- /*
- * 3. Check if any funccal can be freed now.
- * This may call us back recursively.
- */
- free_unref_funccal(copyID, testing);
+ *tofree = NULL;
+ r = tv->vval.v_string;
+ if (r == NULL)
+ r = (char_u *)"";
}
- else if (p_verbose > 0)
+ else
{
- verb_msg(_("Not enough memory to set references, garbage collection aborted!"));
+ *tofree = string_quote(tv->vval.v_string, FALSE);
+ r = *tofree;
}
- return did_free;
-}
-
-/*
- * Free lists, dictionaries, channels and jobs that are no longer referenced.
- */
- static int
-free_unref_items(int copyID)
-{
- int did_free = FALSE;
-
- // Let all "free" functions know that we are here. This means no
- // dictionaries, lists, channels or jobs are to be freed, because we will
- // do that here.
- in_free_unref_items = TRUE;
-
- /*
- * PASS 1: free the contents of the items. We don't free the items
- * themselves yet, so that it is possible to decrement refcount counters
- */
-
- // Go through the list of dicts and free items without this copyID.
- did_free |= dict_free_nonref(copyID);
-
- // Go through the list of lists and free items without this copyID.
- did_free |= list_free_nonref(copyID);
-
- // Go through the list of objects and free items without this copyID.
- did_free |= object_free_nonref(copyID);
-
- // Go through the list of classes and free items without this copyID.
- did_free |= class_free_nonref(copyID);
-
-#ifdef FEAT_JOB_CHANNEL
- // Go through the list of jobs and free items without the copyID. This
- // must happen before doing channels, because jobs refer to channels, but
- // the reference from the channel to the job isn't tracked.
- did_free |= free_unused_jobs_contents(copyID, COPYID_MASK);
-
- // Go through the list of channels and free items without the copyID.
- did_free |= free_unused_channels_contents(copyID, COPYID_MASK);
-#endif
-
- /*
- * PASS 2: free the items themselves.
- */
- object_free_items(copyID);
- dict_free_items(copyID);
- list_free_items(copyID);
-
-#ifdef FEAT_JOB_CHANNEL
- // Go through the list of jobs and free items without the copyID. This
- // must happen before doing channels, because jobs refer to channels, but
- // the reference from the channel to the job isn't tracked.
- free_unused_jobs(copyID, COPYID_MASK);
-
- // Go through the list of channels and free items without the copyID.
- free_unused_channels(copyID, COPYID_MASK);
-#endif
-
- in_free_unref_items = FALSE;
-
- return did_free;
+ return r;
}
/*
- * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
- * "list_stack" is used to add lists to be marked. Can be NULL.
- *
- * Returns TRUE if setting references failed somehow.
+ * Return a textual representation of a function in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * When "echo_style" is FALSE, put quotes around the function name as
+ * "function()", otherwise does not put quotes around function name.
+ * May return NULL.
*/
- int
-set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
+ static char_u *
+func_tv2string(typval_T *tv, char_u **tofree, int echo_style)
{
- int todo;
- int abort = FALSE;
- hashitem_T *hi;
- hashtab_T *cur_ht;
- ht_stack_T *ht_stack = NULL;
- ht_stack_T *tempitem;
+ char_u *r = NULL;
+ char_u buf[MAX_FUNC_NAME_LEN];
- cur_ht = ht;
- for (;;)
+ if (echo_style)
{
- if (!abort)
+ *tofree = NULL;
+
+ if (tv->vval.v_string == NULL)
+ r = (char_u *)"function()";
+ else
{
- // Mark each item in the hashtab. If the item contains a hashtab
- // it is added to ht_stack, if it contains a list it is added to
- // list_stack.
- todo = (int)cur_ht->ht_used;
- FOR_ALL_HASHTAB_ITEMS(cur_ht, hi, todo)
- if (!HASHITEM_EMPTY(hi))
- {
- --todo;
- abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID,
- &ht_stack, list_stack);
- }
+ r = make_ufunc_name_readable(tv->vval.v_string, buf,
+ MAX_FUNC_NAME_LEN);
+ if (r == buf)
+ r = *tofree = vim_strsave(buf);
}
+ }
+ else
+ {
+ char_u *s = NULL;
- if (ht_stack == NULL)
- break;
+ if (tv->vval.v_string != NULL)
+ s = make_ufunc_name_readable(tv->vval.v_string, buf,
+ MAX_FUNC_NAME_LEN);
- // take an item from the stack
- cur_ht = ht_stack->ht;
- tempitem = ht_stack;
- ht_stack = ht_stack->prev;
- free(tempitem);
+ r = *tofree = string_quote(s, TRUE);
}
- return abort;
+ return r;
}
-#if defined(FEAT_LUA) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
- || defined(PROTO)
/*
- * Mark a dict and its items with "copyID".
- * Returns TRUE if setting references failed somehow.
+ * Return a textual representation of a partial in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * "numbuf" is used for a number. May return NULL.
*/
- int
-set_ref_in_dict(dict_T *d, int copyID)
+ static char_u *
+partial_tv2string(
+ typval_T *tv,
+ char_u **tofree,
+ char_u *numbuf,
+ int copyID)
{
- if (d != NULL && d->dv_copyID != copyID)
- {
- d->dv_copyID = copyID;
- return set_ref_in_ht(&d->dv_hashtab, copyID, NULL);
- }
- return FALSE;
-}
-#endif
+ char_u *r = NULL;
+ partial_T *pt;
+ char_u *fname;
+ garray_T ga;
+ int i;
+ char_u *tf;
-/*
- * Mark a list and its items with "copyID".
- * Returns TRUE if setting references failed somehow.
- */
- int
-set_ref_in_list(list_T *ll, int copyID)
-{
- if (ll != NULL && ll->lv_copyID != copyID)
+ pt = tv->vval.v_partial;
+ fname = string_quote(pt == NULL ? NULL : partial_name(pt), FALSE);
+
+ ga_init2(&ga, 1, 100);
+ ga_concat(&ga, (char_u *)"function(");
+ if (fname != NULL)
{
- ll->lv_copyID = copyID;
- return set_ref_in_list_items(ll, copyID, NULL);
+ // When using uf_name prepend "g:" for a global function.
+ if (pt != NULL && pt->pt_name == NULL && fname[0] == '\''
+ && vim_isupper(fname[1]))
+ {
+ ga_concat(&ga, (char_u *)"'g:");
+ ga_concat(&ga, fname + 1);
+ }
+ else
+ ga_concat(&ga, fname);
+ vim_free(fname);
}
- return FALSE;
-}
-
-/*
- * Mark all lists and dicts referenced through list "l" with "copyID".
- * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
- *
- * Returns TRUE if setting references failed somehow.
- */
- int
-set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack)
-{
- listitem_T *li;
- int abort = FALSE;
- list_T *cur_l;
- list_stack_T *list_stack = NULL;
- list_stack_T *tempitem;
-
- cur_l = l;
- for (;;)
+ if (pt != NULL && pt->pt_argc > 0)
{
- if (!abort && cur_l->lv_first != &range_list_item)
- // Mark each item in the list. If the item contains a hashtab
- // it is added to ht_stack, if it contains a list it is added to
- // list_stack.
- for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next)
- abort = abort || set_ref_in_item(&li->li_tv, copyID,
- ht_stack, &list_stack);
- if (list_stack == NULL)
- break;
-
- // take an item from the stack
- cur_l = list_stack->list;
- tempitem = list_stack;
- list_stack = list_stack->prev;
- free(tempitem);
+ ga_concat(&ga, (char_u *)", [");
+ for (i = 0; i < pt->pt_argc; ++i)
+ {
+ if (i > 0)
+ ga_concat(&ga, (char_u *)", ");
+ ga_concat(&ga, tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
+ vim_free(tf);
+ }
+ ga_concat(&ga, (char_u *)"]");
}
-
- return abort;
-}
-
-/*
- * Mark the partial in callback 'cb' with "copyID".
- */
- int
-set_ref_in_callback(callback_T *cb, int copyID)
-{
- typval_T tv;
-
- if (cb->cb_name == NULL || *cb->cb_name == NUL || cb->cb_partial == NULL)
- return FALSE;
-
- tv.v_type = VAR_PARTIAL;
- tv.vval.v_partial = cb->cb_partial;
- return set_ref_in_item(&tv, copyID, NULL, NULL);
-}
-
-/*
- * Mark the dict "dd" with "copyID".
- * Also see set_ref_in_item().
- */
- static int
-set_ref_in_item_dict(
- dict_T *dd,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
-{
- if (dd == NULL || dd->dv_copyID == copyID)
- return FALSE;
-
- // Didn't see this dict yet.
- dd->dv_copyID = copyID;
- if (ht_stack == NULL)
- return set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
-
- ht_stack_T *newitem = ALLOC_ONE(ht_stack_T);
- if (newitem == NULL)
- return TRUE;
-
- newitem->ht = &dd->dv_hashtab;
- newitem->prev = *ht_stack;
- *ht_stack = newitem;
-
- return FALSE;
-}
-
-/*
- * Mark the list "ll" with "copyID".
- * Also see set_ref_in_item().
- */
- static int
-set_ref_in_item_list(
- list_T *ll,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
-{
- if (ll == NULL || ll->lv_copyID == copyID)
- return FALSE;
-
- // Didn't see this list yet.
- ll->lv_copyID = copyID;
- if (list_stack == NULL)
- return set_ref_in_list_items(ll, copyID, ht_stack);
-
- list_stack_T *newitem = ALLOC_ONE(list_stack_T);
- if (newitem == NULL)
- return TRUE;
-
- newitem->list = ll;
- newitem->prev = *list_stack;
- *list_stack = newitem;
-
- return FALSE;
-}
-
-/*
- * Mark the partial "pt" with "copyID".
- * Also see set_ref_in_item().
- */
- static int
-set_ref_in_item_partial(
- partial_T *pt,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
-{
- if (pt == NULL || pt->pt_copyID == copyID)
- return FALSE;
-
- // Didn't see this partial yet.
- pt->pt_copyID = copyID;
-
- int abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
-
- if (pt->pt_dict != NULL)
+ if (pt != NULL && pt->pt_dict != NULL)
{
typval_T dtv;
+ ga_concat(&ga, (char_u *)", ");
dtv.v_type = VAR_DICT;
dtv.vval.v_dict = pt->pt_dict;
- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
+ vim_free(tf);
}
+ // terminate with ')' and a NUL
+ ga_concat_len(&ga, (char_u *)")", 2);
- if (pt->pt_obj != NULL)
- {
- typval_T objtv;
-
- objtv.v_type = VAR_OBJECT;
- objtv.vval.v_object = pt->pt_obj;
- set_ref_in_item(&objtv, copyID, ht_stack, list_stack);
- }
+ *tofree = ga.ga_data;
+ r = *tofree;
- for (int i = 0; i < pt->pt_argc; ++i)
- abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
- ht_stack, list_stack);
- // pt_funcstack is handled in set_ref_in_funcstacks()
- // pt_loopvars is handled in set_ref_in_loopvars()
-
- return abort;
+ return r;
}
-#ifdef FEAT_JOB_CHANNEL
/*
- * Mark the job "pt" with "copyID".
- * Also see set_ref_in_item().
+ * Return a textual representation of a List in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * When "copyID" is not zero replace recursive lists with "...". When
+ * "restore_copyID" is FALSE, repeated items in lists are replaced with "...".
+ * May return NULL.
*/
- static int
-set_ref_in_item_job(
- job_T *job,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
+ static char_u *
+list_tv2string(
+ typval_T *tv,
+ char_u **tofree,
+ int copyID,
+ int restore_copyID)
{
- typval_T dtv;
-
- if (job == NULL || job->jv_copyID == copyID)
- return FALSE;
+ char_u *r = NULL;
- job->jv_copyID = copyID;
- if (job->jv_channel != NULL)
+ if (tv->vval.v_list == NULL)
{
- dtv.v_type = VAR_CHANNEL;
- dtv.vval.v_channel = job->jv_channel;
- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ // NULL list is equivalent to empty list.
+ *tofree = NULL;
+ r = (char_u *)"[]";
}
- if (job->jv_exit_cb.cb_partial != NULL)
+ else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID
+ && tv->vval.v_list->lv_len > 0)
{
- dtv.v_type = VAR_PARTIAL;
- dtv.vval.v_partial = job->jv_exit_cb.cb_partial;
- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ *tofree = NULL;
+ r = (char_u *)"[...]";
}
+ else
+ {
+ int old_copyID;
+ if (restore_copyID)
+ old_copyID = tv->vval.v_list->lv_copyID;
- return FALSE;
+ tv->vval.v_list->lv_copyID = copyID;
+ *tofree = list2string(tv, copyID, restore_copyID);
+ if (restore_copyID)
+ tv->vval.v_list->lv_copyID = old_copyID;
+ r = *tofree;
+ }
+
+ return r;
}
/*
- * Mark the channel "ch" with "copyID".
- * Also see set_ref_in_item().
+ * Return a textual representation of a Dict in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * When "copyID" is not zero replace recursive dicts with "...".
+ * When "restore_copyID" is FALSE, repeated items in the dictionary are
+ * replaced with "...". May return NULL.
*/
- static int
-set_ref_in_item_channel(
- channel_T *ch,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
+ static char_u *
+dict_tv2string(
+ typval_T *tv,
+ char_u **tofree,
+ int copyID,
+ int restore_copyID)
{
- typval_T dtv;
-
- if (ch == NULL || ch->ch_copyID == copyID)
- return FALSE;
+ char_u *r = NULL;
- ch->ch_copyID = copyID;
- for (ch_part_T part = PART_SOCK; part < PART_COUNT; ++part)
+ if (tv->vval.v_dict == NULL)
{
- for (jsonq_T *jq = ch->ch_part[part].ch_json_head.jq_next;
- jq != NULL; jq = jq->jq_next)
- set_ref_in_item(jq->jq_value, copyID, ht_stack, list_stack);
- for (cbq_T *cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL;
- cq = cq->cq_next)
- if (cq->cq_callback.cb_partial != NULL)
- {
- dtv.v_type = VAR_PARTIAL;
- dtv.vval.v_partial = cq->cq_callback.cb_partial;
- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
- }
- if (ch->ch_part[part].ch_callback.cb_partial != NULL)
- {
- dtv.v_type = VAR_PARTIAL;
- dtv.vval.v_partial = ch->ch_part[part].ch_callback.cb_partial;
- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
- }
+ // NULL dict is equivalent to empty dict.
+ *tofree = NULL;
+ r = (char_u *)"{}";
}
- if (ch->ch_callback.cb_partial != NULL)
+ else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID
+ && tv->vval.v_dict->dv_hashtab.ht_used != 0)
{
- dtv.v_type = VAR_PARTIAL;
- dtv.vval.v_partial = ch->ch_callback.cb_partial;
- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ *tofree = NULL;
+ r = (char_u *)"{...}";
}
- if (ch->ch_close_cb.cb_partial != NULL)
+ else
{
- dtv.v_type = VAR_PARTIAL;
- dtv.vval.v_partial = ch->ch_close_cb.cb_partial;
- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
- }
-
- return FALSE;
-}
-#endif
+ int old_copyID;
+ if (restore_copyID)
+ old_copyID = tv->vval.v_dict->dv_copyID;
-/*
- * Mark the class "cl" with "copyID".
- * Also see set_ref_in_item().
- */
- int
-set_ref_in_item_class(
- class_T *cl,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
-{
- int abort = FALSE;
-
- if (cl == NULL || cl->class_copyID == copyID)
- return FALSE;
-
- cl->class_copyID = copyID;
- if (cl->class_members_tv != NULL)
- {
- // The "class_members_tv" table is allocated only for regular classes
- // and not for interfaces.
- for (int i = 0; !abort && i < cl->class_class_member_count; ++i)
- abort = abort || set_ref_in_item(
- &cl->class_members_tv[i],
- copyID, ht_stack, list_stack);
+ tv->vval.v_dict->dv_copyID = copyID;
+ *tofree = dict2string(tv, copyID, restore_copyID);
+ if (restore_copyID)
+ tv->vval.v_dict->dv_copyID = old_copyID;
+ r = *tofree;
}
- for (int i = 0; !abort && i < cl->class_class_function_count; ++i)
- abort = abort || set_ref_in_func(NULL,
- cl->class_class_functions[i], copyID);
-
- for (int i = 0; !abort && i < cl->class_obj_method_count; ++i)
- abort = abort || set_ref_in_func(NULL,
- cl->class_obj_methods[i], copyID);
-
- return abort;
+ return r;
}
/*
- * Mark the object "cl" with "copyID".
- * Also see set_ref_in_item().
+ * Return a textual representation of a job or a channel in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * "numbuf" is used for a number.
+ * When "composite_val" is FALSE, put quotes around strings as "string()",
+ * otherwise does not put quotes around strings.
+ * May return NULL.
*/
- static int
-set_ref_in_item_object(
- object_T *obj,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
+ static char_u *
+jobchan_tv2string(
+ typval_T *tv,
+ char_u **tofree,
+ char_u *numbuf,
+ int composite_val)
{
- int abort = FALSE;
+ char_u *r = NULL;
- if (obj == NULL || obj->obj_copyID == copyID)
- return FALSE;
+#ifdef FEAT_JOB_CHANNEL
+ *tofree = NULL;
- obj->obj_copyID = copyID;
+ if (tv->v_type == VAR_JOB)
+ r = job_to_string_buf(tv, numbuf);
+ else
+ r = channel_to_string_buf(tv, numbuf);
- // The typval_T array is right after the object_T.
- typval_T *mtv = (typval_T *)(obj + 1);
- for (int i = 0; !abort
- && i < obj->obj_class->class_obj_member_count; ++i)
- abort = abort || set_ref_in_item(mtv + i, copyID,
- ht_stack, list_stack);
+ if (composite_val)
+ {
+ *tofree = string_quote(r, FALSE);
+ r = *tofree;
+ }
+#endif
- return abort;
+ return r;
}
/*
- * Mark all lists, dicts and other container types referenced through typval
- * "tv" with "copyID".
- * "list_stack" is used to add lists to be marked. Can be NULL.
- * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
- *
- * Returns TRUE if setting references failed somehow.
+ * Return a textual representation of a class in "tv".
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * May return NULL.
*/
- int
-set_ref_in_item(
- typval_T *tv,
- int copyID,
- ht_stack_T **ht_stack,
- list_stack_T **list_stack)
+ static char_u *
+class_tv2string(typval_T *tv, char_u **tofree)
{
- int abort = FALSE;
-
- switch (tv->v_type)
- {
- case VAR_DICT:
- return set_ref_in_item_dict(tv->vval.v_dict, copyID,
- ht_stack, list_stack);
-
- case VAR_LIST:
- return set_ref_in_item_list(tv->vval.v_list, copyID,
- ht_stack, list_stack);
-
- case VAR_FUNC:
- {
- abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
- break;
- }
-
- case VAR_PARTIAL:
- return set_ref_in_item_partial(tv->vval.v_partial, copyID,
- ht_stack, list_stack);
-
- case VAR_JOB:
-#ifdef FEAT_JOB_CHANNEL
- return set_ref_in_item_job(tv->vval.v_job, copyID,
- ht_stack, list_stack);
-#else
- break;
-#endif
-
- case VAR_CHANNEL:
-#ifdef FEAT_JOB_CHANNEL
- return set_ref_in_item_channel(tv->vval.v_channel, copyID,
- ht_stack, list_stack);
-#else
- break;
-#endif
-
- case VAR_CLASS:
- return set_ref_in_item_class(tv->vval.v_class, copyID,
- ht_stack, list_stack);
-
- case VAR_OBJECT:
- return set_ref_in_item_object(tv->vval.v_object, copyID,
- ht_stack, list_stack);
-
- case VAR_UNKNOWN:
- case VAR_ANY:
- case VAR_VOID:
- case VAR_BOOL:
- case VAR_SPECIAL:
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_STRING:
- case VAR_BLOB:
- case VAR_TYPEALIAS:
- case VAR_INSTR:
- // Types that do not contain any other item
- break;
- }
+ char_u *r = NULL;
+ class_T *cl = tv->vval.v_class;
+ char *s = "class";
+
+ if (cl != NULL && IS_INTERFACE(cl))
+ s = "interface";
+ else if (cl != NULL && IS_ENUM(cl))
+ s = "enum";
+ size_t len = STRLEN(s) + 1 +
+ (cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
+ r = *tofree = alloc(len);
+ vim_snprintf((char *)r, len, "%s %s", s,
+ cl == NULL ? "[unknown]" : (char *)cl->class_name);
- return abort;
+ return r;
}
/*
* Return a string with the string representation of a variable.
* If the memory is allocated "tofree" is set to it, otherwise NULL.
* "numbuf" is used for a number.
- * When "copyID" is not NULL replace recursive lists and dicts with "...".
+ * When "copyID" is not zero replace recursive lists and dicts with "...".
* When both "echo_style" and "composite_val" are FALSE, put quotes around
* strings as "string()", otherwise does not put quotes around strings, as
* ":echo" displays values.
@@ -6221,155 +6181,27 @@ echo_string_core(
switch (tv->v_type)
{
case VAR_STRING:
- if (echo_style && !composite_val)
- {
- *tofree = NULL;
- r = tv->vval.v_string;
- if (r == NULL)
- r = (char_u *)"";
- }
- else
- {
- *tofree = string_quote(tv->vval.v_string, FALSE);
- r = *tofree;
- }
+ r = string_tv2string(tv, tofree, echo_style, composite_val);
break;
case VAR_FUNC:
- {
- char_u buf[MAX_FUNC_NAME_LEN];
-
- if (echo_style)
- {
- r = tv->vval.v_string == NULL ? (char_u *)"function()"
- : make_ufunc_name_readable(tv->vval.v_string,
- buf, MAX_FUNC_NAME_LEN);
- if (r == buf)
- {
- r = vim_strsave(buf);
- *tofree = r;
- }
- else
- *tofree = NULL;
- }
- else
- {
- *tofree = string_quote(tv->vval.v_string == NULL ? NULL
- : make_ufunc_name_readable(
- tv->vval.v_string, buf, MAX_FUNC_NAME_LEN),
- TRUE);
- r = *tofree;
- }
- }
+ r = func_tv2string(tv, tofree, echo_style);
break;
case VAR_PARTIAL:
- {
- partial_T *pt = tv->vval.v_partial;
- char_u *fname = string_quote(pt == NULL ? NULL
- : partial_name(pt), FALSE);
- garray_T ga;
- int i;
- char_u *tf;
-
- ga_init2(&ga, 1, 100);
- ga_concat(&ga, (char_u *)"function(");
- if (fname != NULL)
- {
- // When using uf_name prepend "g:" for a global function.
- if (pt != NULL && pt->pt_name == NULL && fname[0] == '\''
- && vim_isupper(fname[1]))
- {
- ga_concat(&ga, (char_u *)"'g:");
- ga_concat(&ga, fname + 1);
- }
- else
- ga_concat(&ga, fname);
- vim_free(fname);
- }
- if (pt != NULL && pt->pt_argc > 0)
- {
- ga_concat(&ga, (char_u *)", [");
- for (i = 0; i < pt->pt_argc; ++i)
- {
- if (i > 0)
- ga_concat(&ga, (char_u *)", ");
- ga_concat(&ga,
- tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
- vim_free(tf);
- }
- ga_concat(&ga, (char_u *)"]");
- }
- if (pt != NULL && pt->pt_dict != NULL)
- {
- typval_T dtv;
-
- ga_concat(&ga, (char_u *)", ");
- dtv.v_type = VAR_DICT;
- dtv.vval.v_dict = pt->pt_dict;
- ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
- vim_free(tf);
- }
- // terminate with ')' and a NUL
- ga_concat_len(&ga, (char_u *)")", 2);
-
- *tofree = ga.ga_data;
- r = *tofree;
- break;
- }
+ r = partial_tv2string(tv, tofree, numbuf, copyID);
+ break;
case VAR_BLOB:
r = blob2string(tv->vval.v_blob, tofree, numbuf);
break;
case VAR_LIST:
- if (tv->vval.v_list == NULL)
- {
- // NULL list is equivalent to empty list.
- *tofree = NULL;
- r = (char_u *)"[]";
- }
- else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID
- && tv->vval.v_list->lv_len > 0)
- {
- *tofree = NULL;
- r = (char_u *)"[...]";
- }
- else
- {
- int old_copyID = tv->vval.v_list->lv_copyID;
-
- tv->vval.v_list->lv_copyID = copyID;
- *tofree = list2string(tv, copyID, restore_copyID);
- if (restore_copyID)
- tv->vval.v_list->lv_copyID = old_copyID;
- r = *tofree;
- }
+ r = list_tv2string(tv, tofree, copyID, restore_copyID);
break;
case VAR_DICT:
- if (tv->vval.v_dict == NULL)
- {
- // NULL dict is equivalent to empty dict.
- *tofree = NULL;
- r = (char_u *)"{}";
- }
- else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID
- && tv->vval.v_dict->dv_hashtab.ht_used != 0)
- {
- *tofree = NULL;
- r = (char_u *)"{...}";
- }
- else
- {
- int old_copyID = tv->vval.v_dict->dv_copyID;
-
- tv->vval.v_dict->dv_copyID = copyID;
- *tofree = dict2string(tv, copyID, restore_copyID);
- if (restore_copyID)
- tv->vval.v_dict->dv_copyID = old_copyID;
- r = *tofree;
- }
+ r = dict_tv2string(tv, tofree, copyID, restore_copyID);
break;
case VAR_NUMBER:
@@ -6382,16 +6214,7 @@ echo_string_core(
case VAR_JOB:
case VAR_CHANNEL:
-#ifdef FEAT_JOB_CHANNEL
- *tofree = NULL;
- r = tv->v_type == VAR_JOB ? job_to_string_buf(tv, numbuf)
- : channel_to_string_buf(tv, numbuf);
- if (composite_val)
- {
- *tofree = string_quote(r, FALSE);
- r = *tofree;
- }
-#endif
+ r = jobchan_tv2string(tv, tofree, numbuf, composite_val);
break;
case VAR_INSTR:
@@ -6400,23 +6223,11 @@ echo_string_core(
break;
case VAR_CLASS:
- {
- class_T *cl = tv->vval.v_class;
- char *s = "class";
- if (IS_INTERFACE(cl))
- s = "interface";
- else if (IS_ENUM(cl))
- s = "enum";
- size_t len = STRLEN(s) + 1 +
- (cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
- r = *tofree = alloc(len);
- vim_snprintf((char *)r, len, "%s %s", s,
- cl == NULL ? "[unknown]" : (char *)cl->class_name);
- }
+ r = class_tv2string(tv, tofree);
break;
case VAR_OBJECT:
- *tofree = r = object_string(tv->vval.v_object, numbuf, copyID,
+ *tofree = r = object2string(tv->vval.v_object, numbuf, copyID,
echo_style, restore_copyID,
composite_val);
break;
@@ -6451,7 +6262,7 @@ echo_string_core(
* If the memory is allocated "tofree" is set to it, otherwise NULL.
* "numbuf" is used for a number.
* Does not put quotes around strings, as ":echo" displays values.
- * When "copyID" is not NULL replace recursive lists and dicts with "...".
+ * When "copyID" is not zero replace recursive lists and dicts with "...".
* May return NULL.
*/
char_u *
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 2064982..9720691 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -73,6 +73,7 @@ static void f_getpos(typval_T *argvars, typval_T *rettv);
static void f_getreg(typval_T *argvars, typval_T *rettv);
static void f_getreginfo(typval_T *argvars, typval_T *rettv);
static void f_getregion(typval_T *argvars, typval_T *rettv);
+static void f_getregionpos(typval_T *argvars, typval_T *rettv);
static void f_getregtype(typval_T *argvars, typval_T *rettv);
static void f_gettagstack(typval_T *argvars, typval_T *rettv);
static void f_gettext(typval_T *argvars, typval_T *rettv);
@@ -2006,6 +2007,8 @@ static funcentry_T global_functions[] =
ret_void, f_feedkeys},
{"file_readable", 1, 1, FEARG_1, arg1_string, // obsolete
ret_number_bool, f_filereadable},
+ {"filecopy", 2, 2, FEARG_1, arg2_string,
+ ret_number_bool, f_filecopy},
{"filereadable", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_filereadable},
{"filewritable", 1, 1, FEARG_1, arg1_string,
@@ -2136,6 +2139,8 @@ static funcentry_T global_functions[] =
ret_dict_any, f_getreginfo},
{"getregion", 2, 3, FEARG_1, arg3_list_list_dict,
ret_list_string, f_getregion},
+ {"getregionpos", 2, 3, FEARG_1, arg3_list_list_dict,
+ ret_list_string, f_getregionpos},
{"getregtype", 0, 1, FEARG_1, arg1_string,
ret_string, f_getregtype},
{"getscriptinfo", 0, 1, 0, arg1_dict_any,
@@ -3840,8 +3845,9 @@ set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol)
return; // type error; errmsg already given
if (lnum > 0)
curwin->w_cursor.lnum = lnum;
- if (col > 0)
- curwin->w_cursor.col = col - 1;
+ if (col != MAXCOL && --col < 0)
+ col = 0;
+ curwin->w_cursor.col = col;
curwin->w_cursor.coladd = coladd;
// Make sure the cursor is in a valid position.
@@ -3958,7 +3964,7 @@ f_empty(typval_T *argvars, typval_T *rettv)
|| *argvars[0].vval.v_string == NUL;
break;
case VAR_PARTIAL:
- n = FALSE;
+ n = argvars[0].vval.v_partial == NULL;
break;
case VAR_NUMBER:
n = argvars[0].vval.v_number == 0;
@@ -4454,7 +4460,7 @@ f_exists_compiled(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
f_expand(typval_T *argvars, typval_T *rettv)
{
char_u *s;
- int len;
+ size_t len;
int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
expand_T xpc;
int error = FALSE;
@@ -5460,7 +5466,7 @@ f_getpos(typval_T *argvars, typval_T *rettv)
/*
* Convert from block_def to string
*/
- static char_u *
+ static char_u *
block_def2str(struct block_def *bd)
{
char_u *p, *ret;
@@ -5480,40 +5486,36 @@ block_def2str(struct block_def *bd)
return ret;
}
-/*
- * "getregion()" function
- */
- static void
-f_getregion(typval_T *argvars, typval_T *rettv)
-{
- linenr_T lnum;
- oparg_T oa;
- struct block_def bd;
- char_u *akt = NULL;
- int inclusive = TRUE;
- int fnum1 = -1, fnum2 = -1;
- pos_T p1, p2;
- char_u *type;
- buf_T *save_curbuf;
- buf_T *findbuf;
- char_u default_type[] = "v";
- int save_virtual;
- int l;
- int region_type = -1;
- int is_select_exclusive;
+ static int
+getregionpos(
+ typval_T *argvars,
+ typval_T *rettv,
+ pos_T *p1,
+ pos_T *p2,
+ int *inclusive,
+ int *region_type,
+ oparg_T *oap)
+{
+ int fnum1 = -1, fnum2 = -1;
+ char_u *type;
+ buf_T *findbuf;
+ char_u default_type[] = "v";
+ int block_width = 0;
+ int is_select_exclusive;
+ int l;
if (rettv_list_alloc(rettv) == FAIL)
- return;
+ return FAIL;
if (check_for_list_arg(argvars, 0) == FAIL
|| check_for_list_arg(argvars, 1) == FAIL
|| check_for_opt_dict_arg(argvars, 2) == FAIL)
- return;
+ return FAIL;
- if (list2fpos(&argvars[0], &p1, &fnum1, NULL, FALSE) != OK
- || list2fpos(&argvars[1], &p2, &fnum2, NULL, FALSE) != OK
+ if (list2fpos(&argvars[0], p1, &fnum1, NULL, FALSE) != OK
+ || list2fpos(&argvars[1], p2, &fnum2, NULL, FALSE) != OK
|| fnum1 != fnum2)
- return;
+ return FAIL;
if (argvars[2].v_type == VAR_DICT)
{
@@ -5531,120 +5533,142 @@ f_getregion(typval_T *argvars, typval_T *rettv)
}
if (type[0] == 'v' && type[1] == NUL)
- region_type = MCHAR;
+ *region_type = MCHAR;
else if (type[0] == 'V' && type[1] == NUL)
- region_type = MLINE;
- else if (type[0] == Ctrl_V && type[1] == NUL)
- region_type = MBLOCK;
+ *region_type = MLINE;
+ else if (type[0] == Ctrl_V)
+ {
+ char_u *p = type + 1;
+
+ if (*p != NUL && ((block_width = getdigits(&p)) <= 0 || *p != NUL))
+ {
+ semsg(_(e_invalid_value_for_argument_str_str), "type", type);
+ return FAIL;
+ }
+ *region_type = MBLOCK;
+ }
else
{
semsg(_(e_invalid_value_for_argument_str_str), "type", type);
- return;
+ return FAIL;
}
findbuf = fnum1 != 0 ? buflist_findnr(fnum1) : curbuf;
if (findbuf == NULL || findbuf->b_ml.ml_mfp == NULL)
{
emsg(_(e_buffer_is_not_loaded));
- return;
+ return FAIL;
}
- if (p1.lnum < 1 || p1.lnum > findbuf->b_ml.ml_line_count)
+ if (p1->lnum < 1 || p1->lnum > findbuf->b_ml.ml_line_count)
{
- semsg(_(e_invalid_line_number_nr), p1.lnum);
- return;
+ semsg(_(e_invalid_line_number_nr), p1->lnum);
+ return FAIL;
}
- if (p1.col < 1 || p1.col > ml_get_buf_len(findbuf, p1.lnum) + 1)
+ if (p1->col == MAXCOL)
+ p1->col = ml_get_buf_len(findbuf, p1->lnum) + 1;
+ else if (p1->col < 1 || p1->col > ml_get_buf_len(findbuf, p1->lnum) + 1)
{
- semsg(_(e_invalid_column_number_nr), p1.col);
- return;
+ semsg(_(e_invalid_column_number_nr), p1->col);
+ return FAIL;
}
- if (p2.lnum < 1 || p2.lnum > findbuf->b_ml.ml_line_count)
+
+ if (p2->lnum < 1 || p2->lnum > findbuf->b_ml.ml_line_count)
{
- semsg(_(e_invalid_line_number_nr), p2.lnum);
- return;
+ semsg(_(e_invalid_line_number_nr), p2->lnum);
+ return FAIL;
}
- if (p2.col < 1 || p2.col > ml_get_buf_len(findbuf, p2.lnum) + 1)
+ if (p2->col == MAXCOL)
+ p2->col = ml_get_buf_len(findbuf, p2->lnum) + 1;
+ else if (p2->col < 1 || p2->col > ml_get_buf_len(findbuf, p2->lnum) + 1)
{
- semsg(_(e_invalid_column_number_nr), p2.col);
- return;
+ semsg(_(e_invalid_column_number_nr), p2->col);
+ return FAIL;
}
- save_curbuf = curbuf;
curbuf = findbuf;
curwin->w_buffer = curbuf;
- save_virtual = virtual_op;
virtual_op = virtual_active();
- // NOTE: Adjust is needed.
- p1.col--;
- p2.col--;
+ // NOTE: Adjustment is needed.
+ p1->col--;
+ p2->col--;
- if (!LT_POS(p1, p2))
+ if (!LT_POS(*p1, *p2))
{
// swap position
pos_T p;
- p = p1;
- p1 = p2;
- p2 = p;
+ p = *p1;
+ *p1 = *p2;
+ *p2 = p;
}
- if (region_type == MCHAR)
+ if (*region_type == MCHAR)
{
- // handle 'selection' == "exclusive"
- if (is_select_exclusive && !EQUAL_POS(p1, p2))
- {
- if (p2.coladd > 0)
- p2.coladd--;
- else if (p2.col > 0)
- {
- p2.col--;
-
- mb_adjustpos(curbuf, &p2);
- }
- else if (p2.lnum > 1)
- {
- p2.lnum--;
- p2.col = ml_get_len(p2.lnum);
- if (p2.col > 0)
- {
- p2.col--;
-
- mb_adjustpos(curbuf, &p2);
- }
- }
- }
- // if fp2 is on NUL (empty line) inclusive becomes false
- if (*ml_get_pos(&p2) == NUL && !virtual_op)
- inclusive = FALSE;
+ // Handle 'selection' == "exclusive".
+ if (is_select_exclusive && !EQUAL_POS(*p1, *p2))
+ // When backing up to previous line, inclusive becomes false.
+ *inclusive = !unadjust_for_sel_inner(p2);
+ // If p2 is on NUL (end of line), inclusive becomes false.
+ if (*inclusive && !virtual_op && *ml_get_pos(p2) == NUL)
+ *inclusive = FALSE;
}
- else if (region_type == MBLOCK)
+ else if (*region_type == MBLOCK)
{
colnr_T sc1, ec1, sc2, ec2;
- getvvcol(curwin, &p1, &sc1, NULL, &ec1);
- getvvcol(curwin, &p2, &sc2, NULL, &ec2);
- oa.motion_type = MBLOCK;
- oa.inclusive = TRUE;
- oa.op_type = OP_NOP;
- oa.start = p1;
- oa.end = p2;
- oa.start_vcol = MIN(sc1, sc2);
- if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1)
- oa.end_vcol = sc2 - 1;
+ getvvcol(curwin, p1, &sc1, NULL, &ec1);
+ getvvcol(curwin, p2, &sc2, NULL, &ec2);
+ oap->motion_type = MBLOCK;
+ oap->inclusive = TRUE;
+ oap->op_type = OP_NOP;
+ oap->start = *p1;
+ oap->end = *p2;
+ oap->start_vcol = MIN(sc1, sc2);
+ if (block_width > 0)
+ oap->end_vcol = oap->start_vcol + block_width - 1;
+ else if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1)
+ oap->end_vcol = sc2 - 1;
else
- oa.end_vcol = MAX(ec1, ec2);
+ oap->end_vcol = MAX(ec1, ec2);
}
// Include the trailing byte of a multi-byte char.
- l = utfc_ptr2len((char_u *)ml_get_pos(&p2));
+ l = mb_ptr2len((char_u *)ml_get_pos(p2));
if (l > 1)
- p2.col += l - 1;
+ p2->col += l - 1;
+
+ return OK;
+}
+
+/*
+ * "getregion()" function
+ */
+ static void
+f_getregion(typval_T *argvars, typval_T *rettv)
+{
+ pos_T p1, p2;
+ int inclusive = TRUE;
+ int region_type = -1;
+ oparg_T oa;
+
+ buf_T *save_curbuf;
+ int save_virtual;
+ char_u *akt = NULL;
+ linenr_T lnum;
+
+ save_curbuf = curbuf;
+ save_virtual = virtual_op;
+
+ if (getregionpos(argvars, rettv,
+ &p1, &p2, &inclusive, &region_type, &oa) == FAIL)
+ return;
for (lnum = p1.lnum; lnum <= p2.lnum; lnum++)
{
int ret = 0;
+ struct block_def bd;
if (region_type == MLINE)
akt = vim_strsave(ml_get(lnum));
@@ -5675,6 +5699,187 @@ f_getregion(typval_T *argvars, typval_T *rettv)
}
}
+ // getregionpos() may change curbuf and virtual_op
+ curbuf = save_curbuf;
+ curwin->w_buffer = curbuf;
+ virtual_op = save_virtual;
+}
+
+ static void
+add_regionpos_range(typval_T *rettv, pos_T p1, pos_T p2)
+{
+ list_T *l1, *l2, *l3;
+
+ l1 = list_alloc();
+ if (l1 == NULL)
+ return;
+
+ if (list_append_list(rettv->vval.v_list, l1) == FAIL)
+ {
+ vim_free(l1);
+ return;
+ }
+
+ l2 = list_alloc();
+ if (l2 == NULL)
+ {
+ vim_free(l1);
+ return;
+ }
+
+ if (list_append_list(l1, l2) == FAIL)
+ {
+ vim_free(l1);
+ vim_free(l2);
+ return;
+ }
+
+ l3 = list_alloc();
+ if (l3 == NULL)
+ {
+ vim_free(l1);
+ vim_free(l2);
+ return;
+ }
+
+ if (list_append_list(l1, l3) == FAIL)
+ {
+ vim_free(l1);
+ vim_free(l2);
+ vim_free(l3);
+ return;
+ }
+
+ list_append_number(l2, curbuf->b_fnum);
+ list_append_number(l2, p1.lnum);
+ list_append_number(l2, p1.col);
+ list_append_number(l2, p1.coladd);
+
+ list_append_number(l3, curbuf->b_fnum);
+ list_append_number(l3, p2.lnum);
+ list_append_number(l3, p2.col);
+ list_append_number(l3, p2.coladd);
+}
+
+/*
+ * "getregionpos()" function
+ */
+ static void
+f_getregionpos(typval_T *argvars, typval_T *rettv)
+{
+ pos_T p1, p2;
+ int inclusive = TRUE;
+ int region_type = -1;
+ int allow_eol = FALSE;
+ oparg_T oa;
+ int lnum;
+
+ buf_T *save_curbuf;
+ int save_virtual;
+
+ save_curbuf = curbuf;
+ save_virtual = virtual_op;
+
+ if (getregionpos(argvars, rettv,
+ &p1, &p2, &inclusive, &region_type, &oa) == FAIL)
+ return;
+
+ if (argvars[2].v_type == VAR_DICT)
+ allow_eol = dict_get_bool(argvars[2].vval.v_dict, "eol", FALSE);
+
+ for (lnum = p1.lnum; lnum <= p2.lnum; lnum++)
+ {
+ pos_T ret_p1, ret_p2;
+ char_u *line = ml_get(lnum);
+ colnr_T line_len = ml_get_len(lnum);
+
+ if (region_type == MLINE)
+ {
+ ret_p1.col = 1;
+ ret_p1.coladd = 0;
+ ret_p2.col = MAXCOL;
+ ret_p2.coladd = 0;
+ }
+ else
+ {
+ struct block_def bd;
+
+ if (region_type == MBLOCK)
+ block_prep(&oa, &bd, lnum, FALSE);
+ else
+ charwise_block_prep(p1, p2, &bd, lnum, inclusive);
+
+ if (bd.is_oneChar) // selection entirely inside one char
+ {
+ if (region_type == MBLOCK)
+ {
+ ret_p1.col = mb_prevptr(line, bd.textstart) - line + 1;
+ ret_p1.coladd = bd.start_char_vcols
+ - (bd.start_vcol - oa.start_vcol);
+ }
+ else
+ {
+ ret_p1.col = p1.col + 1;
+ ret_p1.coladd = p1.coladd;
+ }
+ }
+ else if (region_type == MBLOCK && oa.start_vcol > bd.start_vcol)
+ {
+ // blockwise selection entirely beyond end of line
+ ret_p1.col = MAXCOL;
+ ret_p1.coladd = oa.start_vcol - bd.start_vcol;
+ bd.is_oneChar = TRUE;
+ }
+ else if (bd.startspaces > 0)
+ {
+ ret_p1.col = mb_prevptr(line, bd.textstart) - line + 1;
+ ret_p1.coladd = bd.start_char_vcols - bd.startspaces;
+ }
+ else
+ {
+ ret_p1.col = bd.textcol + 1;
+ ret_p1.coladd = 0;
+ }
+
+ if (bd.is_oneChar) // selection entirely inside one char
+ {
+ ret_p2.col = ret_p1.col;
+ ret_p2.coladd = ret_p1.coladd + bd.startspaces + bd.endspaces;
+ }
+ else if (bd.endspaces > 0)
+ {
+ ret_p2.col = bd.textcol + bd.textlen + 1;
+ ret_p2.coladd = bd.endspaces;
+ }
+ else
+ {
+ ret_p2.col = bd.textcol + bd.textlen;
+ ret_p2.coladd = 0;
+ }
+ }
+
+ if (!allow_eol && ret_p1.col > line_len)
+ {
+ ret_p1.col = 0;
+ ret_p1.coladd = 0;
+ }
+ else if (ret_p1.col > line_len + 1)
+ ret_p1.col = line_len + 1;
+
+ if (!allow_eol && ret_p2.col > line_len)
+ {
+ ret_p2.col = ret_p1.col == 0 ? 0 : line_len;
+ ret_p2.coladd = 0;
+ }
+ else if (ret_p2.col > line_len + 1)
+ ret_p2.col = line_len + 1;
+
+ ret_p1.lnum = lnum;
+ ret_p2.lnum = lnum;
+ add_regionpos_range(rettv, ret_p1, ret_p2);
+ }
+
+ // getregionpos() may change curbuf and virtual_op
curbuf = save_curbuf;
curwin->w_buffer = curbuf;
virtual_op = save_virtual;
@@ -7368,6 +7573,7 @@ indexof_blob(blob_T *b, long startidx, typval_T *expr)
set_vim_var_type(VV_KEY, VAR_NUMBER);
set_vim_var_type(VV_VAL, VAR_NUMBER);
+ int called_emsg_start = called_emsg;
for (idx = startidx; idx < blob_len(b); ++idx)
{
set_vim_var_nr(VV_KEY, idx);
@@ -7375,6 +7581,9 @@ indexof_blob(blob_T *b, long startidx, typval_T *expr)
if (indexof_eval_expr(expr))
return idx;
+
+ if (called_emsg != called_emsg_start)
+ return -1;
}
return -1;
@@ -7410,6 +7619,7 @@ indexof_list(list_T *l, long startidx, typval_T *expr)
set_vim_var_type(VV_KEY, VAR_NUMBER);
+ int called_emsg_start = called_emsg;
for ( ; item != NULL; item = item->li_next, ++idx)
{
set_vim_var_nr(VV_KEY, idx);
@@ -7420,6 +7630,9 @@ indexof_list(list_T *l, long startidx, typval_T *expr)
if (found)
return idx;
+
+ if (called_emsg != called_emsg_start)
+ return -1;
}
return -1;
@@ -7443,7 +7656,9 @@ f_indexof(typval_T *argvars, typval_T *rettv)
|| check_for_opt_dict_arg(argvars, 2) == FAIL)
return;
- if ((argvars[1].v_type == VAR_STRING && argvars[1].vval.v_string == NULL)
+ if ((argvars[1].v_type == VAR_STRING &&
+ (argvars[1].vval.v_string == NULL
+ || *argvars[1].vval.v_string == NUL))
|| (argvars[1].v_type == VAR_FUNC
&& argvars[1].vval.v_partial == NULL))
return;
@@ -9540,6 +9755,7 @@ search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
{
int flags;
char_u *pat;
+ size_t patlen;
pos_T pos;
pos_T save_cursor;
int save_p_ws = p_ws;
@@ -9614,10 +9830,12 @@ search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
sia.sa_tm = time_limit;
#endif
+ patlen = STRLEN(pat);
+
// Repeat until {skip} returns FALSE.
for (;;)
{
- subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L,
+ subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, pat, patlen, 1L,
options, RE_SEARCH, &sia);
// finding the first match again means there is no match where {skip}
// evaluates to zero.
@@ -10030,6 +10248,13 @@ do_searchpair(
{
char_u *save_cpo;
char_u *pat, *pat2 = NULL, *pat3 = NULL;
+ size_t patlen;
+ size_t spatlen;
+ size_t epatlen;
+ size_t pat2size;
+ size_t pat2len;
+ size_t pat3size;
+ size_t pat3len;
long retval = 0;
pos_T pos;
pos_T firstpos;
@@ -10049,15 +10274,24 @@ do_searchpair(
// Make two search patterns: start/end (pat2, for in nested pairs) and
// start/middle/end (pat3, for the top pair).
- pat2 = alloc(STRLEN(spat) + STRLEN(epat) + 17);
- pat3 = alloc(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 25);
- if (pat2 == NULL || pat3 == NULL)
+ spatlen = STRLEN(spat);
+ epatlen = STRLEN(epat);
+ pat2size = spatlen + epatlen + 17;
+ pat2 = alloc(pat2size);
+ if (pat2 == NULL)
+ goto theend;
+ pat3size = spatlen + STRLEN(mpat) + epatlen + 25;
+ pat3 = alloc(pat3size);
+ if (pat3 == NULL)
goto theend;
- sprintf((char *)pat2, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
+ pat2len = vim_snprintf((char *)pat2, pat2size, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
if (*mpat == NUL)
+ {
STRCPY(pat3, pat2);
+ pat3len = pat2len;
+ }
else
- sprintf((char *)pat3, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
+ pat3len = vim_snprintf((char *)pat3, pat3size, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
spat, epat, mpat);
if (flags & SP_START)
options |= SEARCH_START;
@@ -10074,13 +10308,14 @@ do_searchpair(
CLEAR_POS(&firstpos);
CLEAR_POS(&foundpos);
pat = pat3;
+ patlen = pat3len;
for (;;)
{
searchit_arg_T sia;
CLEAR_FIELD(sia);
sia.sa_stop_lnum = lnum_stop;
- n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L,
+ n = searchit(curwin, curbuf, &pos, NULL, dir, pat, patlen, 1L,
options, RE_SEARCH, &sia);
if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos)))
// didn't find it or found the first match again: FAIL
@@ -10715,7 +10950,7 @@ f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv)
if (col < 0)
return; // type error; errmsg already given
#ifdef FEAT_VARTABS
- rettv->vval.v_number = get_sw_value_col(curbuf, col);
+ rettv->vval.v_number = get_sw_value_col(curbuf, col, FALSE);
return;
#endif
}
@@ -10784,7 +11019,7 @@ f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv)
if (argvars[0].v_type == VAR_UNKNOWN)
{
// Find the start and length of the badly spelled word.
- len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
+ len = spell_move_to(curwin, FORWARD, SMT_ALL, TRUE, &attr);
if (len != 0)
{
word = ml_get_cursor();
@@ -11497,7 +11732,7 @@ f_type(typval_T *argvars, typval_T *rettv)
case VAR_CLASS:
{
class_T *cl = argvars[0].vval.v_class;
- if (IS_ENUM(cl))
+ if (cl != NULL && IS_ENUM(cl))
n = VAR_TYPE_ENUM;
else
n = VAR_TYPE_CLASS;
@@ -11505,11 +11740,18 @@ f_type(typval_T *argvars, typval_T *rettv)
}
case VAR_OBJECT:
{
- class_T *cl = argvars[0].vval.v_object->obj_class;
- if (IS_ENUM(cl))
- n = VAR_TYPE_ENUMVALUE;
- else
+ object_T *obj = argvars[0].vval.v_object;
+
+ if (obj == NULL)
n = VAR_TYPE_OBJECT;
+ else
+ {
+ class_T *cl = argvars[0].vval.v_object->obj_class;
+ if (IS_ENUM(cl))
+ n = VAR_TYPE_ENUMVALUE;
+ else
+ n = VAR_TYPE_OBJECT;
+ }
break;
}
case VAR_UNKNOWN:
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 2a5d842..8143c24 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -3750,6 +3750,7 @@ ex_substitute(exarg_T *eap)
int save_do_all; // remember user specified 'g' flag
int save_do_ask; // remember user specified 'c' flag
char_u *pat = NULL, *sub = NULL; // init for GCC
+ size_t patlen = 0;
int delimiter;
int sublen;
int got_quit = FALSE;
@@ -3823,6 +3824,7 @@ ex_substitute(exarg_T *eap)
if (*cmd != '&')
which_pat = RE_SEARCH; // use last '/' pattern
pat = (char_u *)""; // empty search pattern
+ patlen = 0;
delimiter = *cmd++; // remember delimiter character
}
else // find the end of the regexp
@@ -3830,6 +3832,7 @@ ex_substitute(exarg_T *eap)
which_pat = RE_LAST; // use last used regexp
delimiter = *cmd++; // remember delimiter character
pat = cmd; // remember start of search pat
+ patlen = STRLEN(pat);
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(),
&eap->arg, NULL, NULL);
if (cmd[0] == delimiter) // end delimiter found
@@ -3883,6 +3886,7 @@ ex_substitute(exarg_T *eap)
return;
}
pat = NULL; // search_regcomp() will use previous pattern
+ patlen = 0;
sub = vim_strsave(old_sub);
// Vi compatibility quirk: repeating with ":s" keeps the cursor in the
@@ -3929,9 +3933,9 @@ ex_substitute(exarg_T *eap)
}
if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0)
- save_re_pat(RE_SUBST, pat, magic_isset());
+ save_re_pat(RE_SUBST, pat, patlen, magic_isset());
// put pattern in history
- add_to_history(HIST_SEARCH, pat, TRUE, NUL);
+ add_to_history(HIST_SEARCH, pat, patlen, TRUE, NUL);
vim_free(sub);
return;
@@ -4066,7 +4070,7 @@ ex_substitute(exarg_T *eap)
return;
}
- if (search_regcomp(pat, NULL, RE_SUBST, which_pat, SEARCH_HIS, &regmatch) == FAIL)
+ if (search_regcomp(pat, patlen, NULL, RE_SUBST, which_pat, SEARCH_HIS, &regmatch) == FAIL)
{
if (subflags.do_error)
emsg(_(e_invalid_command));
@@ -5104,6 +5108,7 @@ ex_global(exarg_T *eap)
char_u delim; // delimiter, normally '/'
char_u *pat;
+ size_t patlen;
char_u *used_pat;
regmmatch_T regmatch;
int match;
@@ -5150,6 +5155,7 @@ ex_global(exarg_T *eap)
which_pat = RE_SEARCH; // use previous search pattern
++cmd;
pat = (char_u *)"";
+ patlen = 0;
}
else if (*cmd == NUL)
{
@@ -5165,12 +5171,13 @@ ex_global(exarg_T *eap)
delim = *cmd; // get the delimiter
++cmd; // skip delimiter if there is one
pat = cmd; // remember start of pattern
+ patlen = STRLEN(pat);
cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
if (cmd[0] == delim) // end delimiter found
*cmd++ = NUL; // replace it with a NUL
}
- if (search_regcomp(pat, &used_pat, RE_BOTH, which_pat, SEARCH_HIS,
+ if (search_regcomp(pat, patlen, &used_pat, RE_BOTH, which_pat, SEARCH_HIS,
&regmatch) == FAIL)
{
emsg(_(e_invalid_command));
@@ -5622,6 +5629,9 @@ ex_oldfiles(exarg_T *eap UNUSED)
listitem_T *li;
int nr = 0;
char_u *fname;
+ // for a single filtered match, remember the number
+ // so we can jump directly to it without prompting
+ int matches = -1;
if (l == NULL)
{
@@ -5637,6 +5647,10 @@ ex_oldfiles(exarg_T *eap UNUSED)
fname = tv_get_string(&li->li_tv);
if (!message_filtered(fname))
{
+ if (matches < 0)
+ matches = nr;
+ else
+ matches = 0;
msg_outnum((long)nr);
msg_puts(": ");
msg_outtrans(fname);
@@ -5654,7 +5668,15 @@ ex_oldfiles(exarg_T *eap UNUSED)
if (cmdmod.cmod_flags & CMOD_BROWSE)
{
quit_more = FALSE;
- nr = prompt_for_number(FALSE);
+ // we only need to prompt if there is more than 1 match
+ if (matches > 0)
+ {
+ nr = matches;
+ // msg_putchar above sets needs_wait_return
+ need_wait_return = FALSE;
+ }
+ else
+ nr = prompt_for_number(FALSE);
msg_starthere();
if (nr > 0)
{
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 40dec4c..25f6914 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -271,7 +271,7 @@ EXCMD(CMD_cabove, "cabove", ex_cbelow,
ADDR_UNSIGNED),
EXCMD(CMD_caddbuffer, "caddbuffer", ex_cbuffer,
EX_RANGE|EX_WORD1|EX_TRLBAR,
- ADDR_OTHER),
+ ADDR_LINES),
EXCMD(CMD_caddexpr, "caddexpr", ex_cexpr,
EX_NEEDARG|EX_WORD1|EX_NOTRLCOM|EX_EXPR_ARG,
ADDR_NONE),
@@ -289,7 +289,7 @@ EXCMD(CMD_catch, "catch", ex_catch,
ADDR_NONE),
EXCMD(CMD_cbuffer, "cbuffer", ex_cbuffer,
EX_BANG|EX_RANGE|EX_WORD1|EX_TRLBAR,
- ADDR_OTHER),
+ ADDR_LINES),
EXCMD(CMD_cbefore, "cbefore", ex_cbelow,
EX_RANGE|EX_COUNT|EX_TRLBAR,
ADDR_UNSIGNED),
@@ -331,7 +331,7 @@ EXCMD(CMD_cgetfile, "cgetfile", ex_cfile,
ADDR_NONE),
EXCMD(CMD_cgetbuffer, "cgetbuffer", ex_cbuffer,
EX_RANGE|EX_WORD1|EX_TRLBAR,
- ADDR_OTHER),
+ ADDR_LINES),
EXCMD(CMD_cgetexpr, "cgetexpr", ex_cexpr,
EX_NEEDARG|EX_WORD1|EX_NOTRLCOM|EX_EXPR_ARG,
ADDR_NONE),
@@ -820,7 +820,7 @@ EXCMD(CMD_laddexpr, "laddexpr", ex_cexpr,
ADDR_NONE),
EXCMD(CMD_laddbuffer, "laddbuffer", ex_cbuffer,
EX_RANGE|EX_WORD1|EX_TRLBAR,
- ADDR_OTHER),
+ ADDR_LINES),
EXCMD(CMD_laddfile, "laddfile", ex_cfile,
EX_TRLBAR|EX_FILE1,
ADDR_NONE),
@@ -832,7 +832,7 @@ EXCMD(CMD_later, "later", ex_later,
ADDR_NONE),
EXCMD(CMD_lbuffer, "lbuffer", ex_cbuffer,
EX_BANG|EX_RANGE|EX_WORD1|EX_TRLBAR,
- ADDR_OTHER),
+ ADDR_LINES),
EXCMD(CMD_lbefore, "lbefore", ex_cbelow,
EX_RANGE|EX_COUNT|EX_TRLBAR,
ADDR_UNSIGNED),
@@ -886,7 +886,7 @@ EXCMD(CMD_lgetfile, "lgetfile", ex_cfile,
ADDR_NONE),
EXCMD(CMD_lgetbuffer, "lgetbuffer", ex_cbuffer,
EX_RANGE|EX_WORD1|EX_TRLBAR,
- ADDR_OTHER),
+ ADDR_LINES),
EXCMD(CMD_lgetexpr, "lgetexpr", ex_cexpr,
EX_NEEDARG|EX_WORD1|EX_NOTRLCOM|EX_EXPR_ARG,
ADDR_NONE),
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index a588f26..71bfa93 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -4567,7 +4567,7 @@ get_address(
curwin->w_cursor.col = 0;
searchcmdlen = 0;
flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG;
- if (!do_search(NULL, c, c, cmd, 1L, flags, NULL))
+ if (!do_search(NULL, c, c, cmd, STRLEN(cmd), 1L, flags, NULL))
{
curwin->w_cursor = pos;
cmd = NULL;
@@ -4621,7 +4621,7 @@ get_address(
pos.coladd = 0;
if (searchit(curwin, curbuf, &pos, NULL,
*cmd == '?' ? BACKWARD : FORWARD,
- (char_u *)"", 1L, SEARCH_MSG, i, NULL) != FAIL)
+ (char_u *)"", 0, 1L, SEARCH_MSG, i, NULL) != FAIL)
lnum = pos.lnum;
else
{
@@ -5077,7 +5077,7 @@ expand_filename(
{
int has_wildcards; // need to expand wildcards
char_u *repl;
- int srclen;
+ size_t srclen;
char_u *p;
int n;
int escaped;
@@ -5201,7 +5201,7 @@ expand_filename(
}
}
- p = repl_cmdline(eap, p, (size_t)srclen, repl, cmdlinep);
+ p = repl_cmdline(eap, p, srclen, repl, cmdlinep);
vim_free(repl);
if (p == NULL)
return FAIL;
@@ -9363,7 +9363,7 @@ enum {
* the variable. Otherwise return -1 and "*usedlen" is unchanged.
*/
int
-find_cmdline_var(char_u *src, int *usedlen)
+find_cmdline_var(char_u *src, size_t *usedlen)
{
// must be sorted by the 'value' field because it is used by bsearch()!
static keyvalue_T spec_str_tab[] = {
@@ -9444,7 +9444,7 @@ find_cmdline_var(char_u *src, int *usedlen)
eval_vars(
char_u *src, // pointer into commandline
char_u *srcstart, // beginning of valid memory for src
- int *usedlen, // characters after src that are used
+ size_t *usedlen, // characters after src that are used
linenr_T *lnump, // line number for :e command, or NULL
char **errormsg, // pointer to error message
int *escaped, // return value has escaped white space (can
@@ -9514,7 +9514,7 @@ eval_vars(
*/
else
{
- int off = 0;
+ size_t off = 0;
switch (spec_idx)
{
@@ -9781,7 +9781,7 @@ expand_sfile(char_u *arg)
size_t len;
char_u *repl;
size_t repllen;
- int srclen;
+ size_t srclen;
char_u *p;
resultlen = STRLEN(arg);
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 1731d29..3ae4958 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -493,7 +493,7 @@ may_do_incsearch_highlighting(
sia.sa_tm = 500;
#endif
found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
- ccline.cmdbuff + skiplen, count, search_flags,
+ ccline.cmdbuff + skiplen, patlen, count, search_flags,
#ifdef FEAT_RELTIME
&sia
#else
@@ -654,7 +654,7 @@ may_adjust_incsearch_highlighting(
pat[patlen] = NUL;
i = searchit(curwin, curbuf, &t, NULL,
c == Ctrl_G ? FORWARD : BACKWARD,
- pat, count, search_flags, RE_SEARCH, NULL);
+ pat, patlen, count, search_flags, RE_SEARCH, NULL);
--emsg_off;
pat[patlen] = save;
if (i)
@@ -2539,12 +2539,14 @@ returncmd:
if (ccline.cmdlen && firstc != NUL
&& (some_key_typed || histype == HIST_SEARCH))
{
- add_to_history(histype, ccline.cmdbuff, TRUE,
+ size_t cmdbufflen = STRLEN(ccline.cmdbuff);
+
+ add_to_history(histype, ccline.cmdbuff, cmdbufflen, TRUE,
histype == HIST_SEARCH ? firstc : NUL);
if (firstc == ':')
{
vim_free(new_last_cmdline);
- new_last_cmdline = vim_strsave(ccline.cmdbuff);
+ new_last_cmdline = vim_strnsave(ccline.cmdbuff, cmdbufflen);
}
}
diff --git a/src/fileio.c b/src/fileio.c
index 07e05fc..e7f3332 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3770,19 +3770,12 @@ vim_fgets(char_u *buf, int size, FILE *fp)
int
vim_rename(char_u *from, char_u *to)
{
- int fd_in;
- int fd_out;
int n;
- char *errmsg = NULL;
- char *buffer;
+ int ret;
#ifdef AMIGA
BPTR flock;
#endif
stat_T st;
- long perm;
-#ifdef HAVE_ACL
- vim_acl_T acl; // ACL from original file
-#endif
int use_tmp_file = FALSE;
/*
@@ -3903,6 +3896,61 @@ vim_rename(char_u *from, char_u *to)
/*
* Rename() failed, try copying the file.
*/
+ ret = vim_copyfile(from, to);
+ if (ret != OK)
+ return -1;
+
+ /*
+ * Remove copied original file
+ */
+ if (mch_stat((char *)from, &st) >= 0)
+ mch_remove(from);
+
+ return 0;
+}
+
+
+/*
+ * Create the new file with same permissions as the original.
+ * Return -1 for failure, 0 for success.
+ */
+ int
+vim_copyfile(char_u *from, char_u *to)
+{
+ int fd_in;
+ int fd_out;
+ int n;
+ char *errmsg = NULL;
+ char *buffer;
+ long perm;
+#ifdef HAVE_ACL
+ vim_acl_T acl; // ACL from original file
+#endif
+
+#ifdef HAVE_READLINK
+ int ret;
+ int len;
+ stat_T st;
+ char linkbuf[MAXPATHL + 1];
+
+ ret = mch_lstat((char *)from, &st);
+ if (ret >= 0 && S_ISLNK(st.st_mode))
+ {
+ ret = FAIL;
+
+ len = readlink((char *)from, linkbuf, MAXPATHL);
+ if (len > 0)
+ {
+ linkbuf[len] = NUL;
+
+ // Create link
+ ret = symlink(linkbuf, (char *)to);
+ }
+
+ return ret == 0 ? OK : FAIL;
+ }
+#endif
+
perm = mch_getperm(from);
#ifdef HAVE_ACL
// For systems that support ACL: get the ACL from the original file.
@@ -3914,7 +3962,7 @@ vim_rename(char_u *from, char_u *to)
#ifdef HAVE_ACL
mch_free_acl(acl);
#endif
- return -1;
+ return FAIL;
}
// Create the new file with same permissions as the original.
@@ -3926,7 +3974,7 @@ vim_rename(char_u *from, char_u *to)
#ifdef HAVE_ACL
mch_free_acl(acl);
#endif
- return -1;
+ return FAIL;
}
buffer = alloc(WRITEBUFSIZE);
@@ -3937,7 +3985,7 @@ vim_rename(char_u *from, char_u *to)
#ifdef HAVE_ACL
mch_free_acl(acl);
#endif
- return -1;
+ return FAIL;
}
while ((n = read_eintr(fd_in, buffer, WRITEBUFSIZE)) > 0)
@@ -3969,10 +4017,9 @@ vim_rename(char_u *from, char_u *to)
if (errmsg != NULL)
{
semsg(errmsg, to);
- return -1;
+ return FAIL;
}
- mch_remove(from);
- return 0;
+ return OK;
}
static int already_warned = FALSE;
diff --git a/src/filepath.c b/src/filepath.c
index 3bf8a2d..9f68d7c 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -292,7 +292,7 @@ shortpath_for_partial(
modify_fname(
char_u *src, // string with modifiers
int tilde_file, // "~" is a file name, not $HOME
- int *usedlen, // characters after src that are used
+ size_t *usedlen, // characters after src that are used
char_u **fnamep, // file name so far
char_u **bufp, // buffer for allocated file name or NULL
int *fnamelen) // length of fnamep
@@ -668,7 +668,7 @@ repeat:
str = vim_strnsave(*fnamep, *fnamelen);
if (sub != NULL && str != NULL)
{
- *usedlen = (int)(p + 1 - src);
+ *usedlen = p + 1 - src;
s = do_string_sub(str, pat, sub, NULL, flags);
if (s != NULL)
{
@@ -1038,7 +1038,7 @@ f_fnamemodify(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
char_u *mods;
- int usedlen = 0;
+ size_t usedlen = 0;
int len = 0;
char_u *fbuf = NULL;
char_u buf[NUMBUFLEN];
@@ -2649,6 +2649,31 @@ f_browsedir(typval_T *argvars UNUSED, typval_T *rettv)
rettv->v_type = VAR_STRING;
}
+/*
+ * "filecopy()" function
+ */
+ void
+f_filecopy(typval_T *argvars, typval_T *rettv)
+{
+ char_u *from;
+ stat_T st;
+
+ rettv->vval.v_number = FALSE;
+
+ if (check_restricted() || check_secure()
+ || check_for_string_arg(argvars, 0) == FAIL
+ || check_for_string_arg(argvars, 1) == FAIL)
+ return;
+
+ from = tv_get_string(&argvars[0]);
+
+ if (mch_lstat((char *)from, &st) >= 0
+ && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
+ rettv->vval.v_number = vim_copyfile(
+ tv_get_string(&argvars[0]),
+ tv_get_string(&argvars[1])) == OK ? TRUE : FALSE;
+}
+
#endif // FEAT_EVAL
/*
@@ -2707,7 +2732,7 @@ home_replace(
if (homedir_env != NULL && *homedir_env == '~')
{
- int usedlen = 0;
+ size_t usedlen = 0;
int flen;
char_u *fbuf = NULL;
@@ -3170,7 +3195,7 @@ expand_wildcards_eval(
char_u *eval_pat = NULL;
char_u *exp_pat = *pat;
char *ignored_msg;
- int usedlen;
+ size_t usedlen;
int is_cur_alt_file = *exp_pat == '%' || *exp_pat == '#';
int star_follows = FALSE;
diff --git a/src/gc.c b/src/gc.c
new file mode 100644
index 0000000..987ca27
--- /dev/null
+++ b/src/gc.c
@@ -0,0 +1,780 @@
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * gc.c: Garbage Collection
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+/*
+ * When recursively copying lists and dicts we need to remember which ones we
+ * have done to avoid endless recursiveness. This unique ID is used for that.
+ * The last bit is used for previous_funccal, ignored when comparing.
+ */
+static int current_copyID = 0;
+
+static int free_unref_items(int copyID);
+
+/*
+ * Return the next (unique) copy ID.
+ * Used for serializing nested structures.
+ */
+ int
+get_copyID(void)
+{
+ current_copyID += COPYID_INC;
+ return current_copyID;
+}
+
+/*
+ * Garbage collection for lists and dictionaries.
+ *
+ * We use reference counts to be able to free most items right away when they
+ * are no longer used. But for composite items it's possible that it becomes
+ * unused while the reference count is > 0: When there is a recursive
+ * reference. Example:
+ * :let l = [1, 2, 3]
+ * :let d = {9: l}
+ * :let l[1] = d
+ *
+ * Since this is quite unusual we handle this with garbage collection: every
+ * once in a while find out which lists and dicts are not referenced from any
+ * variable.
+ *
+ * Here is a good reference text about garbage collection (refers to Python
+ * but it applies to all reference-counting mechanisms):
+ * http://python.ca/nas/python/gc/
+ */
+
+/*
+ * Do garbage collection for lists and dicts.
+ * When "testing" is TRUE this is called from test_garbagecollect_now().
+ * Return TRUE if some memory was freed.
+ */
+ int
+garbage_collect(int testing)
+{
+ int copyID;
+ int abort = FALSE;
+ buf_T *buf;
+ win_T *wp;
+ int did_free = FALSE;
+ tabpage_T *tp;
+
+ if (!testing)
+ {
+ // Only do this once.
+ want_garbage_collect = FALSE;
+ may_garbage_collect = FALSE;
+ garbage_collect_at_exit = FALSE;
+ }
+
+ // The execution stack can grow big, limit the size.
+ if (exestack.ga_maxlen - exestack.ga_len > 500)
+ {
+ size_t new_len;
+ char_u *pp;
+ int n;
+
+ // Keep 150% of the current size, with a minimum of the growth size.
+ n = exestack.ga_len / 2;
+ if (n < exestack.ga_growsize)
+ n = exestack.ga_growsize;
+
+ // Don't make it bigger though.
+ if (exestack.ga_len + n < exestack.ga_maxlen)
+ {
+ new_len = (size_t)exestack.ga_itemsize * (exestack.ga_len + n);
+ pp = vim_realloc(exestack.ga_data, new_len);
+ if (pp == NULL)
+ return FAIL;
+ exestack.ga_maxlen = exestack.ga_len + n;
+ exestack.ga_data = pp;
+ }
+ }
+
+ // We advance by two because we add one for items referenced through
+ // previous_funccal.
+ copyID = get_copyID();
+
+ /*
+ * 1. Go through all accessible variables and mark all lists and dicts
+ * with copyID.
+ */
+
+ // Don't free variables in the previous_funccal list unless they are only
+ // referenced through previous_funccal. This must be first, because if
+ // the item is referenced elsewhere the funccal must not be freed.
+ abort = abort || set_ref_in_previous_funccal(copyID);
+
+ // script-local variables
+ abort = abort || garbage_collect_scriptvars(copyID);
+
+ // buffer-local variables
+ FOR_ALL_BUFFERS(buf)
+ abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
+ NULL, NULL);
+
+ // window-local variables
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
+ NULL, NULL);
+ // window-local variables in autocmd windows
+ for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
+ if (aucmd_win[i].auc_win != NULL)
+ abort = abort || set_ref_in_item(
+ &aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL);
+#ifdef FEAT_PROP_POPUP
+ FOR_ALL_POPUPWINS(wp)
+ abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
+ NULL, NULL);
+ FOR_ALL_TABPAGES(tp)
+ FOR_ALL_POPUPWINS_IN_TAB(tp, wp)
+ abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
+ NULL, NULL);
+#endif
+
+ // tabpage-local variables
+ FOR_ALL_TABPAGES(tp)
+ abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
+ NULL, NULL);
+ // global variables
+ abort = abort || garbage_collect_globvars(copyID);
+
+ // function-local variables
+ abort = abort || set_ref_in_call_stack(copyID);
+
+ // named functions (matters for closures)
+ abort = abort || set_ref_in_functions(copyID);
+
+ // function call arguments, if v:testing is set.
+ abort = abort || set_ref_in_func_args(copyID);
+
+ // funcstacks keep variables for closures
+ abort = abort || set_ref_in_funcstacks(copyID);
+
+ // loopvars keep variables for loop blocks
+ abort = abort || set_ref_in_loopvars(copyID);
+
+ // v: vars
+ abort = abort || garbage_collect_vimvars(copyID);
+
+ // callbacks in buffers
+ abort = abort || set_ref_in_buffers(copyID);
+
+ // 'completefunc', 'omnifunc' and 'thesaurusfunc' callbacks
+ abort = abort || set_ref_in_insexpand_funcs(copyID);
+
+ // 'operatorfunc' callback
+ abort = abort || set_ref_in_opfunc(copyID);
+
+ // 'tagfunc' callback
+ abort = abort || set_ref_in_tagfunc(copyID);
+
+ // 'imactivatefunc' and 'imstatusfunc' callbacks
+ abort = abort || set_ref_in_im_funcs(copyID);
+
+#ifdef FEAT_LUA
+ abort = abort || set_ref_in_lua(copyID);
+#endif
+
+#ifdef FEAT_PYTHON
+ abort = abort || set_ref_in_python(copyID);
+#endif
+
+#ifdef FEAT_PYTHON3
+ abort = abort || set_ref_in_python3(copyID);
+#endif
+
+#ifdef FEAT_JOB_CHANNEL
+ abort = abort || set_ref_in_channel(copyID);
+ abort = abort || set_ref_in_job(copyID);
+#endif
+#ifdef FEAT_NETBEANS_INTG
+ abort = abort || set_ref_in_nb_channel(copyID);
+#endif
+
+#ifdef FEAT_TIMERS
+ abort = abort || set_ref_in_timer(copyID);
+#endif
+
+#ifdef FEAT_QUICKFIX
+ abort = abort || set_ref_in_quickfix(copyID);
+#endif
+
+#ifdef FEAT_TERMINAL
+ abort = abort || set_ref_in_term(copyID);
+#endif
+
+#ifdef FEAT_PROP_POPUP
+ abort = abort || set_ref_in_popups(copyID);
+#endif
+
+ abort = abort || set_ref_in_classes(copyID);
+
+ if (!abort)
+ {
+ /*
+ * 2. Free lists and dictionaries that are not referenced.
+ */
+ did_free = free_unref_items(copyID);
+
+ /*
+ * 3. Check if any funccal can be freed now.
+ * This may call us back recursively.
+ */
+ free_unref_funccal(copyID, testing);
+ }
+ else if (p_verbose > 0)
+ {
+ verb_msg(_("Not enough memory to set references, garbage collection aborted!"));
+ }
+
+ return did_free;
+}
+
+/*
+ * Free lists, dictionaries, channels and jobs that are no longer referenced.
+ */
+ static int
+free_unref_items(int copyID)
+{
+ int did_free = FALSE;
+
+ // Let all "free" functions know that we are here. This means no
+ // dictionaries, lists, channels or jobs are to be freed, because we will
+ // do that here.
+ in_free_unref_items = TRUE;
+
+ /*
+ * PASS 1: free the contents of the items. We don't free the items
+ * themselves yet, so that it is possible to decrement refcount counters
+ */
+
+ // Go through the list of dicts and free items without this copyID.
+ did_free |= dict_free_nonref(copyID);
+
+ // Go through the list of lists and free items without this copyID.
+ did_free |= list_free_nonref(copyID);
+
+ // Go through the list of objects and free items without this copyID.
+ did_free |= object_free_nonref(copyID);
+
+ // Go through the list of classes and free items without this copyID.
+ did_free |= class_free_nonref(copyID);
+
+#ifdef FEAT_JOB_CHANNEL
+ // Go through the list of jobs and free items without the copyID. This
+ // must happen before doing channels, because jobs refer to channels, but
+ // the reference from the channel to the job isn't tracked.
+ did_free |= free_unused_jobs_contents(copyID, COPYID_MASK);
+
+ // Go through the list of channels and free items without the copyID.
+ did_free |= free_unused_channels_contents(copyID, COPYID_MASK);
+#endif
+
+ /*
+ * PASS 2: free the items themselves.
+ */
+ object_free_items(copyID);
+ dict_free_items(copyID);
+ list_free_items(copyID);
+
+#ifdef FEAT_JOB_CHANNEL
+ // Go through the list of jobs and free items without the copyID. This
+ // must happen before doing channels, because jobs refer to channels, but
+ // the reference from the channel to the job isn't tracked.
+ free_unused_jobs(copyID, COPYID_MASK);
+
+ // Go through the list of channels and free items without the copyID.
+ free_unused_channels(copyID, COPYID_MASK);
+#endif
+
+ in_free_unref_items = FALSE;
+
+ return did_free;
+}
+
+/*
+ * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
+ * "list_stack" is used to add lists to be marked. Can be NULL.
+ *
+ * Returns TRUE if setting references failed somehow.
+ */
+ int
+set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
+{
+ int todo;
+ int abort = FALSE;
+ hashitem_T *hi;
+ hashtab_T *cur_ht;
+ ht_stack_T *ht_stack = NULL;
+ ht_stack_T *tempitem;
+
+ cur_ht = ht;
+ for (;;)
+ {
+ if (!abort)
+ {
+ // Mark each item in the hashtab. If the item contains a hashtab
+ // it is added to ht_stack, if it contains a list it is added to
+ // list_stack.
+ todo = (int)cur_ht->ht_used;
+ FOR_ALL_HASHTAB_ITEMS(cur_ht, hi, todo)
+ if (!HASHITEM_EMPTY(hi))
+ {
+ --todo;
+ abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID,
+ &ht_stack, list_stack);
+ }
+ }
+
+ if (ht_stack == NULL)
+ break;
+
+ // take an item from the stack
+ cur_ht = ht_stack->ht;
+ tempitem = ht_stack;
+ ht_stack = ht_stack->prev;
+ free(tempitem);
+ }
+
+ return abort;
+}
+
+#if defined(FEAT_LUA) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
+ || defined(PROTO)
+/*
+ * Mark a dict and its items with "copyID".
+ * Returns TRUE if setting references failed somehow.
+ */
+ int
+set_ref_in_dict(dict_T *d, int copyID)
+{
+ if (d != NULL && d->dv_copyID != copyID)
+ {
+ d->dv_copyID = copyID;
+ return set_ref_in_ht(&d->dv_hashtab, copyID, NULL);
+ }
+ return FALSE;
+}
+#endif
+
+/*
+ * Mark a list and its items with "copyID".
+ * Returns TRUE if setting references failed somehow.
+ */
+ int
+set_ref_in_list(list_T *ll, int copyID)
+{
+ if (ll != NULL && ll->lv_copyID != copyID)
+ {
+ ll->lv_copyID = copyID;
+ return set_ref_in_list_items(ll, copyID, NULL);
+ }
+ return FALSE;
+}
+
+/*
+ * Mark all lists and dicts referenced through list "l" with "copyID".
+ * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
+ *
+ * Returns TRUE if setting references failed somehow.
+ */
+ int
+set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack)
+{
+ listitem_T *li;
+ int abort = FALSE;
+ list_T *cur_l;
+ list_stack_T *list_stack = NULL;
+ list_stack_T *tempitem;
+
+ cur_l = l;
+ for (;;)
+ {
+ if (!abort && cur_l->lv_first != &range_list_item)
+ // Mark each item in the list. If the item contains a hashtab
+ // it is added to ht_stack, if it contains a list it is added to
+ // list_stack.
+ for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next)
+ abort = abort || set_ref_in_item(&li->li_tv, copyID,
+ ht_stack, &list_stack);
+ if (list_stack == NULL)
+ break;
+
+ // take an item from the stack
+ cur_l = list_stack->list;
+ tempitem = list_stack;
+ list_stack = list_stack->prev;
+ free(tempitem);
+ }
+
+ return abort;
+}
+
+/*
+ * Mark the partial in callback 'cb' with "copyID".
+ */
+ int
+set_ref_in_callback(callback_T *cb, int copyID)
+{
+ typval_T tv;
+
+ if (cb->cb_name == NULL || *cb->cb_name == NUL || cb->cb_partial == NULL)
+ return FALSE;
+
+ tv.v_type = VAR_PARTIAL;
+ tv.vval.v_partial = cb->cb_partial;
+ return set_ref_in_item(&tv, copyID, NULL, NULL);
+}
+
+/*
+ * Mark the dict "dd" with "copyID".
+ * Also see set_ref_in_item().
+ */
+ static int
+set_ref_in_item_dict(
+ dict_T *dd,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ if (dd == NULL || dd->dv_copyID == copyID)
+ return FALSE;
+
+ // Didn't see this dict yet.
+ dd->dv_copyID = copyID;
+ if (ht_stack == NULL)
+ return set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
+
+ ht_stack_T *newitem = ALLOC_ONE(ht_stack_T);
+ if (newitem == NULL)
+ return TRUE;
+
+ newitem->ht = &dd->dv_hashtab;
+ newitem->prev = *ht_stack;
+ *ht_stack = newitem;
+
+ return FALSE;
+}
+
+/*
+ * Mark the list "ll" with "copyID".
+ * Also see set_ref_in_item().
+ */
+ static int
+set_ref_in_item_list(
+ list_T *ll,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ if (ll == NULL || ll->lv_copyID == copyID)
+ return FALSE;
+
+ // Didn't see this list yet.
+ ll->lv_copyID = copyID;
+ if (list_stack == NULL)
+ return set_ref_in_list_items(ll, copyID, ht_stack);
+
+ list_stack_T *newitem = ALLOC_ONE(list_stack_T);
+ if (newitem == NULL)
+ return TRUE;
+
+ newitem->list = ll;
+ newitem->prev = *list_stack;
+ *list_stack = newitem;
+
+ return FALSE;
+}
+
+/*
+ * Mark the partial "pt" with "copyID".
+ * Also see set_ref_in_item().
+ */
+ static int
+set_ref_in_item_partial(
+ partial_T *pt,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ if (pt == NULL || pt->pt_copyID == copyID)
+ return FALSE;
+
+ // Didn't see this partial yet.
+ pt->pt_copyID = copyID;
+
+ int abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
+
+ if (pt->pt_dict != NULL)
+ {
+ typval_T dtv;
+
+ dtv.v_type = VAR_DICT;
+ dtv.vval.v_dict = pt->pt_dict;
+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+
+ if (pt->pt_obj != NULL)
+ {
+ typval_T objtv;
+
+ objtv.v_type = VAR_OBJECT;
+ objtv.vval.v_object = pt->pt_obj;
+ set_ref_in_item(&objtv, copyID, ht_stack, list_stack);
+ }
+
+ for (int i = 0; i < pt->pt_argc; ++i)
+ abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
+ ht_stack, list_stack);
+ // pt_funcstack is handled in set_ref_in_funcstacks()
+ // pt_loopvars is handled in set_ref_in_loopvars()
+
+ return abort;
+}
+
+#ifdef FEAT_JOB_CHANNEL
+/*
+ * Mark the job "pt" with "copyID".
+ * Also see set_ref_in_item().
+ */
+ static int
+set_ref_in_item_job(
+ job_T *job,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ typval_T dtv;
+
+ if (job == NULL || job->jv_copyID == copyID)
+ return FALSE;
+
+ job->jv_copyID = copyID;
+ if (job->jv_channel != NULL)
+ {
+ dtv.v_type = VAR_CHANNEL;
+ dtv.vval.v_channel = job->jv_channel;
+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+ if (job->jv_exit_cb.cb_partial != NULL)
+ {
+ dtv.v_type = VAR_PARTIAL;
+ dtv.vval.v_partial = job->jv_exit_cb.cb_partial;
+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+
+ return FALSE;
+}
+
+/*
+ * Mark the channel "ch" with "copyID".
+ * Also see set_ref_in_item().
+ */
+ static int
+set_ref_in_item_channel(
+ channel_T *ch,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ typval_T dtv;
+
+ if (ch == NULL || ch->ch_copyID == copyID)
+ return FALSE;
+
+ ch->ch_copyID = copyID;
+ for (ch_part_T part = PART_SOCK; part < PART_COUNT; ++part)
+ {
+ for (jsonq_T *jq = ch->ch_part[part].ch_json_head.jq_next;
+ jq != NULL; jq = jq->jq_next)
+ set_ref_in_item(jq->jq_value, copyID, ht_stack, list_stack);
+ for (cbq_T *cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL;
+ cq = cq->cq_next)
+ if (cq->cq_callback.cb_partial != NULL)
+ {
+ dtv.v_type = VAR_PARTIAL;
+ dtv.vval.v_partial = cq->cq_callback.cb_partial;
+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+ if (ch->ch_part[part].ch_callback.cb_partial != NULL)
+ {
+ dtv.v_type = VAR_PARTIAL;
+ dtv.vval.v_partial = ch->ch_part[part].ch_callback.cb_partial;
+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+ }
+ if (ch->ch_callback.cb_partial != NULL)
+ {
+ dtv.v_type = VAR_PARTIAL;
+ dtv.vval.v_partial = ch->ch_callback.cb_partial;
+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+ if (ch->ch_close_cb.cb_partial != NULL)
+ {
+ dtv.v_type = VAR_PARTIAL;
+ dtv.vval.v_partial = ch->ch_close_cb.cb_partial;
+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+
+ return FALSE;
+}
+#endif
+
+/*
+ * Mark the class "cl" with "copyID".
+ * Also see set_ref_in_item().
+ */
+ int
+set_ref_in_item_class(
+ class_T *cl,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ int abort = FALSE;
+
+ if (cl == NULL || cl->class_copyID == copyID)
+ return FALSE;
+
+ cl->class_copyID = copyID;
+ if (cl->class_members_tv != NULL)
+ {
+ // The "class_members_tv" table is allocated only for regular classes
+ // and not for interfaces.
+ for (int i = 0; !abort && i < cl->class_class_member_count; ++i)
+ abort = abort || set_ref_in_item(
+ &cl->class_members_tv[i],
+ copyID, ht_stack, list_stack);
+ }
+
+ for (int i = 0; !abort && i < cl->class_class_function_count; ++i)
+ abort = abort || set_ref_in_func(NULL,
+ cl->class_class_functions[i], copyID);
+
+ for (int i = 0; !abort && i < cl->class_obj_method_count; ++i)
+ abort = abort || set_ref_in_func(NULL,
+ cl->class_obj_methods[i], copyID);
+
+ return abort;
+}
+
+/*
+ * Mark the object "cl" with "copyID".
+ * Also see set_ref_in_item().
+ */
+ static int
+set_ref_in_item_object(
+ object_T *obj,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ int abort = FALSE;
+
+ if (obj == NULL || obj->obj_copyID == copyID)
+ return FALSE;
+
+ obj->obj_copyID = copyID;
+
+ // The typval_T array is right after the object_T.
+ typval_T *mtv = (typval_T *)(obj + 1);
+ for (int i = 0; !abort
+ && i < obj->obj_class->class_obj_member_count; ++i)
+ abort = abort || set_ref_in_item(mtv + i, copyID,
+ ht_stack, list_stack);
+
+ return abort;
+}
+
+/*
+ * Mark all lists, dicts and other container types referenced through typval
+ * "tv" with "copyID".
+ * "list_stack" is used to add lists to be marked. Can be NULL.
+ * "ht_stack" is used to add hashtabs to be marked. Can be NULL.
+ *
+ * Returns TRUE if setting references failed somehow.
+ */
+ int
+set_ref_in_item(
+ typval_T *tv,
+ int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ int abort = FALSE;
+
+ switch (tv->v_type)
+ {
+ case VAR_DICT:
+ return set_ref_in_item_dict(tv->vval.v_dict, copyID,
+ ht_stack, list_stack);
+
+ case VAR_LIST:
+ return set_ref_in_item_list(tv->vval.v_list, copyID,
+ ht_stack, list_stack);
+
+ case VAR_FUNC:
+ {
+ abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
+ break;
+ }
+
+ case VAR_PARTIAL:
+ return set_ref_in_item_partial(tv->vval.v_partial, copyID,
+ ht_stack, list_stack);
+
+ case VAR_JOB:
+#ifdef FEAT_JOB_CHANNEL
+ return set_ref_in_item_job(tv->vval.v_job, copyID,
+ ht_stack, list_stack);
+#else
+ break;
+#endif
+
+ case VAR_CHANNEL:
+#ifdef FEAT_JOB_CHANNEL
+ return set_ref_in_item_channel(tv->vval.v_channel, copyID,
+ ht_stack, list_stack);
+#else
+ break;
+#endif
+
+ case VAR_CLASS:
+ return set_ref_in_item_class(tv->vval.v_class, copyID,
+ ht_stack, list_stack);
+
+ case VAR_OBJECT:
+ return set_ref_in_item_object(tv->vval.v_object, copyID,
+ ht_stack, list_stack);
+
+ case VAR_UNKNOWN:
+ case VAR_ANY:
+ case VAR_VOID:
+ case VAR_BOOL:
+ case VAR_SPECIAL:
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_STRING:
+ case VAR_BLOB:
+ case VAR_TYPEALIAS:
+ case VAR_INSTR:
+ // Types that do not contain any other item
+ break;
+ }
+
+ return abort;
+}
+
+#endif
diff --git a/src/globals.h b/src/globals.h
index 2c00e5f..fb5c7b3 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1936,6 +1936,7 @@ EXTERN int reset_term_props_on_termresponse INIT(= FALSE);
EXTERN int disable_vterm_title_for_testing INIT(= FALSE);
EXTERN long override_sysinfo_uptime INIT(= -1);
EXTERN int override_autoload INIT(= FALSE);
+EXTERN int override_defcompile INIT(= FALSE);
EXTERN int ml_get_alloc_lines INIT(= FALSE);
EXTERN int ignore_unreachable_code_for_testing INIT(= FALSE);
diff --git a/src/gui.c b/src/gui.c
index 1953691..25662ef 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -5312,7 +5312,7 @@ gui_do_findrepl(
i = msg_scroll;
if (down)
{
- (void)do_search(NULL, '/', '/', ga.ga_data, 1L, searchflags, NULL);
+ (void)do_search(NULL, '/', '/', ga.ga_data, STRLEN(ga.ga_data), 1L, searchflags, NULL);
}
else
{
@@ -5320,7 +5320,7 @@ gui_do_findrepl(
// direction
p = vim_strsave_escaped(ga.ga_data, (char_u *)"?");
if (p != NULL)
- (void)do_search(NULL, '?', '?', p, 1L, searchflags, NULL);
+ (void)do_search(NULL, '?', '?', p, STRLEN(p), 1L, searchflags, NULL);
vim_free(p);
}
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 4d201fc..67ee531 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -2704,23 +2704,9 @@ global_event_filter(GdkXEvent *xev,
static void
mainwin_realize(GtkWidget *widget UNUSED, gpointer data UNUSED)
{
-// If you get an error message here, you still need to unpack the runtime
-// archive!
-#ifdef magick
-# undef magick
-#endif
- // A bit hackish, but avoids casting later and allows optimization
-# define static static const
-#define magick vim32x32
#include "../runtime/vim32x32.xpm"
-#undef magick
-#define magick vim16x16
#include "../runtime/vim16x16.xpm"
-#undef magick
-#define magick vim48x48
#include "../runtime/vim48x48.xpm"
-#undef magick
-# undef static
GdkWindow * const mainwin_win = gtk_widget_get_window(gui.mainwin);
@@ -2741,9 +2727,9 @@ mainwin_realize(GtkWidget *widget UNUSED, gpointer data UNUSED)
*/
GList *icons = NULL;
- icons = g_list_prepend(icons, gdk_pixbuf_new_from_xpm_data(vim16x16));
- icons = g_list_prepend(icons, gdk_pixbuf_new_from_xpm_data(vim32x32));
- icons = g_list_prepend(icons, gdk_pixbuf_new_from_xpm_data(vim48x48));
+ icons = g_list_prepend(icons, gdk_pixbuf_new_from_xpm_data((const char **)vim16x16));
+ icons = g_list_prepend(icons, gdk_pixbuf_new_from_xpm_data((const char **)vim32x32));
+ icons = g_list_prepend(icons, gdk_pixbuf_new_from_xpm_data((const char **)vim48x48));
gtk_window_set_icon_list(GTK_WINDOW(gui.mainwin), icons);
diff --git a/src/gui_x11.c b/src/gui_x11.c
index fc63658..edde6b5 100644
--- a/src/gui_x11.c
+++ b/src/gui_x11.c
@@ -1363,20 +1363,9 @@ gui_mch_init(void)
#else
// Use Pixmaps, looking much nicer.
-// If you get an error message here, you still need to unpack the runtime
-// archive!
-# ifdef magick
-# undef magick
-# endif
-# define magick vim32x32
# include "../runtime/vim32x32.xpm"
-# undef magick
-# define magick vim16x16
# include "../runtime/vim16x16.xpm"
-# undef magick
-# define magick vim48x48
# include "../runtime/vim48x48.xpm"
-# undef magick
static Pixmap icon = 0;
static Pixmap icon_mask = 0;
diff --git a/src/highlight.c b/src/highlight.c
index 9aa149f..a71a100 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -258,6 +258,8 @@ static char *(highlight_init_both[]) = {
"default link CurSearch Search",
"default link PmenuKind Pmenu",
"default link PmenuKindSel PmenuSel",
+ "default link PmenuMatch Pmenu",
+ "default link PmenuMatchSel PmenuSel",
"default link PmenuExtra Pmenu",
"default link PmenuExtraSel PmenuSel",
CENT("Normal cterm=NONE", "Normal gui=NONE"),
diff --git a/src/if_cscope.c b/src/if_cscope.c
index d9982ef..7b6fd92 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -541,7 +541,7 @@ cs_add_common(
char *ppath = NULL;
int i;
int len;
- int usedlen = 0;
+ size_t usedlen = 0;
char_u *fbuf = NULL;
// get the filename (arg1), expand it, and try to stat it
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 3e5993b..e0fd3ea 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -7325,12 +7325,11 @@ populate_module(PyObject *m)
return -1;
}
+# if PY_VERSION_HEX < 0x30c00a7
+ // find_module has been removed as of Python 3.12.0a7
if ((py_find_module = PyObject_GetAttrString(cls, "find_module")))
- {
- // find_module() is deprecated, this may stop working in some later
- // version.
ADD_OBJECT(m, "_find_module", py_find_module);
- }
+# endif
Py_DECREF(imp);
diff --git a/src/indent.c b/src/indent.c
index 1dfde7d..777db24 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -123,14 +123,22 @@ tabstop_padding(colnr_T col, int ts_arg, int *vts)
/*
* Find the size of the tab that covers a particular column.
+ *
+ * If this is being called as part of a shift operation, col is not the cursor
+ * column but is the column number to the left of the first non-whitespace
+ * character in the line. If the shift is to the left (left = TRUE), then
+ * return the size of the tab interval to the left of the column.
*/
int
-tabstop_at(colnr_T col, int ts, int *vts)
+tabstop_at(colnr_T col, int ts, int *vts, int left)
{
- int tabcount;
- colnr_T tabcol = 0;
- int t;
- int tab_size = 0;
+ int tabcount; // Number of tab stops in the list of variable
+ // tab stops.
+ colnr_T tabcol = 0; // Column of the tab stop under consideration.
+ int t; // Tabstop index in the list of variable tab
+ // stops.
+ int tab_size = 0; // Size of the tab stop interval to the right
+ // or left of the col.
if (vts == 0 || vts[0] == 0)
return ts;
@@ -141,11 +149,22 @@ tabstop_at(colnr_T col, int ts, int *vts)
tabcol += vts[t];
if (tabcol > col)
{
- tab_size = vts[t];
+ // If shifting left (left != 0), and if the column to the left of
+ // the first first non-blank character (col) in the line is
+ // already to the left of the first tabstop, set the shift amount
+ // (tab_size) to just enough to shift the line to the left margin.
+ // The value doesn't seem to matter as long as it is at least that
+ // distance.
+ if (left && (t == 1))
+ tab_size = col;
+ else
+ tab_size = vts[t - (left ? 1 : 0)];
break;
}
}
- if (t > tabcount)
+ if (t > tabcount) // If the value of the index t is beyond the
+ // end of the list, use the tab stop value at
+ // the end of the list.
tab_size = vts[tabcount];
return tab_size;
@@ -327,20 +346,20 @@ tabstop_first(int *ts)
long
get_sw_value(buf_T *buf)
{
- return get_sw_value_col(buf, 0);
+ return get_sw_value_col(buf, 0, FALSE);
}
/*
* Idem, using "pos".
*/
static long
-get_sw_value_pos(buf_T *buf, pos_T *pos)
+get_sw_value_pos(buf_T *buf, pos_T *pos, int left)
{
pos_T save_cursor = curwin->w_cursor;
long sw_value;
curwin->w_cursor = *pos;
- sw_value = get_sw_value_col(buf, get_nolist_virtcol());
+ sw_value = get_sw_value_col(buf, get_nolist_virtcol(), left);
curwin->w_cursor = save_cursor;
return sw_value;
}
@@ -349,23 +368,23 @@ get_sw_value_pos(buf_T *buf, pos_T *pos)
* Idem, using the first non-black in the current line.
*/
long
-get_sw_value_indent(buf_T *buf)
+get_sw_value_indent(buf_T *buf, int left)
{
pos_T pos = curwin->w_cursor;
pos.col = getwhitecols_curline();
- return get_sw_value_pos(buf, &pos);
+ return get_sw_value_pos(buf, &pos, left);
}
/*
* Idem, using virtual column "col".
*/
long
-get_sw_value_col(buf_T *buf, colnr_T col UNUSED)
+get_sw_value_col(buf_T *buf, colnr_T col UNUSED, int left UNUSED)
{
return buf->b_p_sw ? buf->b_p_sw :
#ifdef FEAT_VARTABS
- tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array);
+ tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array, left);
#else
buf->b_p_ts;
#endif
diff --git a/src/insexpand.c b/src/insexpand.c
index 93a56a8..c673df9 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -113,6 +113,7 @@ struct compl_S
// cp_flags has CP_FREE_FNAME
int cp_flags; // CP_ values
int cp_number; // sequence number
+ int cp_score; // fuzzy match score
};
// values for cp_flags
@@ -147,13 +148,6 @@ static char_u *compl_leader = NULL;
static int compl_get_longest = FALSE; // put longest common string
// in compl_leader
-static int compl_no_insert = FALSE; // FALSE: select & insert
- // TRUE: noinsert
-static int compl_no_select = FALSE; // FALSE: select & insert
- // TRUE: noselect
-static int compl_longest = FALSE; // FALSE: insert full match
- // TRUE: insert longest prefix
-
// Selected one of the matches. When FALSE the match was edited or using the
// longest common string.
static int compl_used_match;
@@ -176,6 +170,7 @@ static int ctrl_x_mode = CTRL_X_NORMAL;
static int compl_matches = 0; // number of completion matches
static char_u *compl_pattern = NULL;
+static size_t compl_patternlen = 0;
static int compl_direction = FORWARD;
static int compl_shows_dir = FORWARD;
static int compl_pending = 0; // > 1 for postponed CTRL-N
@@ -206,6 +201,8 @@ static int compl_cont_status = 0;
static int compl_opt_refresh_always = FALSE;
static int compl_opt_suppress_empty = FALSE;
+static int compl_selected_item = -1;
+
static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup);
static void ins_compl_longest_match(compl_T *match);
static void ins_compl_del_pum(void);
@@ -1049,21 +1046,12 @@ ins_compl_long_shown_match(void)
}
/*
- * Set variables that store noselect and noinsert behavior from the
- * 'completeopt' value.
+ * Get the local or global value of 'completeopt' flags.
*/
- void
-completeopt_was_set(void)
+ unsigned int
+get_cot_flags(void)
{
- compl_no_insert = FALSE;
- compl_no_select = FALSE;
- compl_longest = FALSE;
- if (strstr((char *)p_cot, "noselect") != NULL)
- compl_no_select = TRUE;
- if (strstr((char *)p_cot, "noinsert") != NULL)
- compl_no_insert = TRUE;
- if (strstr((char *)p_cot, "longest") != NULL)
- compl_longest = TRUE;
+ return curbuf->b_cot_flags != 0 ? curbuf->b_cot_flags : cot_flags;
}
@@ -1110,7 +1098,7 @@ ins_compl_del_pum(void)
pum_wanted(void)
{
// 'completeopt' must contain "menu" or "menuone"
- if (vim_strchr(p_cot, 'm') == NULL)
+ if ((get_cot_flags() & COT_ANY_MENU) == 0)
return FALSE;
// The display looks bad on a B&W display.
@@ -1144,7 +1132,7 @@ pum_enough_matches(void)
compl = compl->cp_next;
} while (!is_first_match(compl));
- if (strstr((char *)p_cot, "menuone") != NULL)
+ if (get_cot_flags() & COT_MENUONE)
return (i >= 1);
return (i >= 2);
}
@@ -1212,6 +1200,19 @@ trigger_complete_changed_event(int cur)
#endif
/*
+ * pumitem qsort compare func
+ */
+ static int
+ins_compl_fuzzy_cmp(const void *a, const void *b)
+{
+ const int sa = (*(pumitem_T *)a).pum_score;
+ const int sb = (*(pumitem_T *)b).pum_score;
+ const int ia = (*(pumitem_T *)a).pum_idx;
+ const int ib = (*(pumitem_T *)b).pum_idx;
+ return sa == sb ? (ia == ib ? 0 : (ia < ib ? -1 : 1)) : (sa < sb ? 1 : -1);
+}
+
+/*
* Build a popup menu to show the completion matches.
* Returns the popup menu entry that should be selected. Returns -1 if nothing
* should be selected.
@@ -1226,6 +1227,10 @@ ins_compl_build_pum(void)
int i;
int cur = -1;
int lead_len = 0;
+ int max_fuzzy_score = 0;
+ unsigned int cur_cot_flags = get_cot_flags();
+ int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0;
+ int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
// Need to build the popup menu list.
compl_match_arraysize = 0;
@@ -1235,9 +1240,15 @@ ins_compl_build_pum(void)
do
{
+ // When 'completeopt' contains "fuzzy" and leader is not NULL or empty,
+ // set the cp_score for later comparisons.
+ if (compl_fuzzy_match && compl_leader != NULL && lead_len > 0)
+ compl->cp_score = fuzzy_match_str(compl->cp_str, compl_leader);
+
if (!match_at_original_text(compl)
&& (compl_leader == NULL
- || ins_compl_equal(compl, compl_leader, lead_len)))
+ || ins_compl_equal(compl, compl_leader, lead_len)
+ || (compl_fuzzy_match && compl->cp_score > 0)))
++compl_match_arraysize;
compl = compl->cp_next;
} while (compl != NULL && !is_first_match(compl));
@@ -1254,15 +1265,22 @@ ins_compl_build_pum(void)
if (match_at_original_text(compl_shown_match))
shown_match_ok = TRUE;
+ if (compl_leader != NULL
+ && STRCMP(compl_leader, compl_orig_text) == 0
+ && shown_match_ok == FALSE)
+ compl_shown_match = compl_no_select ? compl_first_match
+ : compl_first_match->cp_next;
+
i = 0;
compl = compl_first_match;
do
{
if (!match_at_original_text(compl)
&& (compl_leader == NULL
- || ins_compl_equal(compl, compl_leader, lead_len)))
+ || ins_compl_equal(compl, compl_leader, lead_len)
+ || (compl_fuzzy_match && compl->cp_score > 0)))
{
- if (!shown_match_ok)
+ if (!shown_match_ok && !compl_fuzzy_match)
{
if (compl == compl_shown_match || did_find_shown_match)
{
@@ -1278,6 +1296,34 @@ ins_compl_build_pum(void)
shown_compl = compl;
cur = i;
}
+ else if (compl_fuzzy_match)
+ {
+ if (i == 0)
+ shown_compl = compl;
+ // Update the maximum fuzzy score and the shown match
+ // if the current item's score is higher
+ if (compl->cp_score > max_fuzzy_score)
+ {
+ did_find_shown_match = TRUE;
+ max_fuzzy_score = compl->cp_score;
+ compl_shown_match = compl;
+ shown_match_ok = TRUE;
+ }
+
+ // If there is no "no select" condition and the max fuzzy
+ // score is positive, or there is no completion leader or the
+ // leader length is zero, mark the shown match as valid and
+ // reset the current index.
+ if (!compl_no_select
+ && (max_fuzzy_score > 0
+ || (compl_leader == NULL || lead_len == 0)))
+ {
+ shown_match_ok = TRUE;
+ cur = 0;
+ if (match_at_original_text(compl_shown_match))
+ compl_shown_match = shown_compl;
+ }
+ }
if (compl->cp_text[CPT_ABBR] != NULL)
compl_match_array[i].pum_text =
@@ -1286,6 +1332,7 @@ ins_compl_build_pum(void)
compl_match_array[i].pum_text = compl->cp_str;
compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
+ compl_match_array[i].pum_score = compl->cp_score;
if (compl->cp_text[CPT_MENU] != NULL)
compl_match_array[i++].pum_extra =
compl->cp_text[CPT_MENU];
@@ -1293,7 +1340,7 @@ ins_compl_build_pum(void)
compl_match_array[i++].pum_extra = compl->cp_fname;
}
- if (compl == compl_shown_match)
+ if (compl == compl_shown_match && !compl_fuzzy_match)
{
did_find_shown_match = TRUE;
@@ -1313,6 +1360,15 @@ ins_compl_build_pum(void)
compl = compl->cp_next;
} while (compl != NULL && !is_first_match(compl));
+ if (compl_fuzzy_match && compl_leader != NULL && lead_len > 0)
+ {
+ for (i = 0; i < compl_match_arraysize; i++)
+ compl_match_array[i].pum_idx = i;
+ // sort by the largest score of fuzzy match
+ qsort(compl_match_array, (size_t)compl_match_arraysize,
+ sizeof(pumitem_T), ins_compl_fuzzy_cmp);
+ }
+
if (!shown_match_ok) // no displayed match at all
cur = -1;
@@ -1369,6 +1425,7 @@ ins_compl_show_pum(void)
// Use the cursor to get all wrapping and other settings right.
col = curwin->w_cursor.col;
curwin->w_cursor.col = compl_col;
+ compl_selected_item = cur;
pum_display(compl_match_array, compl_match_arraysize, cur);
curwin->w_cursor.col = col;
@@ -1386,6 +1443,15 @@ ins_compl_show_pum(void)
#define DICT_EXACT (2) // "dict" is the exact name of a file
/*
+ * Get current completion leader
+ */
+ char_u *
+ins_compl_leader(void)
+{
+ return compl_leader != NULL ? compl_leader : compl_orig_text;
+}
+
+/*
* Add any identifiers that match the given pattern "pat" in the list of
* dictionary files "dict_start" to the list of completions.
*/
@@ -1708,6 +1774,7 @@ ins_compl_free(void)
int i;
VIM_CLEAR(compl_pattern);
+ compl_patternlen = 0;
VIM_CLEAR(compl_leader);
if (compl_first_match == NULL)
@@ -1747,6 +1814,7 @@ ins_compl_clear(void)
compl_started = FALSE;
compl_matches = 0;
VIM_CLEAR(compl_pattern);
+ compl_patternlen = 0;
VIM_CLEAR(compl_leader);
edit_submode_extra = NULL;
VIM_CLEAR(compl_orig_text);
@@ -2404,9 +2472,8 @@ ins_compl_prep(int c)
if (ctrl_x_mode_not_defined_yet()
|| (ctrl_x_mode_normal() && !compl_started))
{
- compl_get_longest = compl_longest;
+ compl_get_longest = (get_cot_flags() & COT_LONGEST) != 0;
compl_used_match = TRUE;
-
}
if (ctrl_x_mode_not_defined_yet())
@@ -2878,6 +2945,10 @@ set_completion(colnr_T startcol, list_T *list)
int save_w_wrow = curwin->w_wrow;
int save_w_leftcol = curwin->w_leftcol;
int flags = CP_ORIGINAL_TEXT;
+ unsigned int cur_cot_flags = get_cot_flags();
+ int compl_longest = (cur_cot_flags & COT_LONGEST) != 0;
+ int compl_no_insert = (cur_cot_flags & COT_NOINSERT) != 0;
+ int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0;
// If already doing completions stop it.
if (ctrl_x_mode_not_default())
@@ -3374,7 +3445,7 @@ done:
get_next_include_file_completion(int compl_type)
{
find_pattern_in_path(compl_pattern, compl_direction,
- (int)STRLEN(compl_pattern), FALSE, FALSE,
+ (int)compl_patternlen, FALSE, FALSE,
(compl_type == CTRL_X_PATH_DEFINES
&& !(compl_cont_status & CONT_SOL))
? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND,
@@ -3478,8 +3549,7 @@ get_next_cmdline_completion(void)
int num_matches;
if (expand_cmdline(&compl_xp, compl_pattern,
- (int)STRLEN(compl_pattern),
- &num_matches, &matches) == EXPAND_OK)
+ (int)compl_patternlen, &num_matches, &matches) == EXPAND_OK)
ins_compl_add_matches(num_matches, matches, FALSE);
}
@@ -3644,8 +3714,8 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
st->cur_match_pos, compl_direction, compl_pattern);
else
found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos,
- NULL, compl_direction, compl_pattern, 1L,
- SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
+ NULL, compl_direction, compl_pattern, compl_patternlen,
+ 1L, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
--msg_silent;
if (!compl_started || st->set_match_pos)
{
@@ -4018,6 +4088,43 @@ ins_compl_show_filename(void)
}
/*
+ * Find a completion item when 'completeopt' contains "fuzzy".
+ */
+ static compl_T *
+find_comp_when_fuzzy(void)
+{
+ int score;
+ char_u* str;
+ int target_idx = -1;
+ int is_forward = compl_shows_dir_forward();
+ int is_backward = compl_shows_dir_backward();
+ compl_T *comp = NULL;
+
+ if (compl_match_array == NULL ||
+ (is_forward && compl_selected_item == compl_match_arraysize - 1)
+ || (is_backward && compl_selected_item == 0))
+ return compl_first_match;
+
+ if (is_forward)
+ target_idx = compl_selected_item + 1;
+ else if (is_backward)
+ target_idx = compl_selected_item == -1 ? compl_match_arraysize - 1
+ : compl_selected_item - 1;
+
+ score = compl_match_array[target_idx].pum_score;
+ str = compl_match_array[target_idx].pum_text;
+
+ comp = compl_first_match;
+ do {
+ if (comp->cp_score == score && (str == comp->cp_str || str == comp->cp_text[CPT_ABBR]))
+ return comp;
+ comp = comp->cp_next;
+ } while (comp != NULL && !is_first_match(comp));
+
+ return NULL;
+}
+
+/*
* Find the next set of matches for completion. Repeat the completion "todo"
* times. The number of matches found is returned in 'num_matches'.
*
@@ -4039,12 +4146,16 @@ find_next_completion_match(
{
int found_end = FALSE;
compl_T *found_compl = NULL;
+ unsigned int cur_cot_flags = get_cot_flags();
+ int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0;
+ int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
while (--todo >= 0)
{
if (compl_shows_dir_forward() && compl_shown_match->cp_next != NULL)
{
- compl_shown_match = compl_shown_match->cp_next;
+ compl_shown_match = compl_fuzzy_match && compl_match_array != NULL
+ ? find_comp_when_fuzzy() : compl_shown_match->cp_next;
found_end = (compl_first_match != NULL
&& (is_first_match(compl_shown_match->cp_next)
|| is_first_match(compl_shown_match)));
@@ -4053,7 +4164,8 @@ find_next_completion_match(
&& compl_shown_match->cp_prev != NULL)
{
found_end = is_first_match(compl_shown_match);
- compl_shown_match = compl_shown_match->cp_prev;
+ compl_shown_match = compl_fuzzy_match && compl_match_array != NULL
+ ? find_comp_when_fuzzy() : compl_shown_match->cp_prev;
found_end |= is_first_match(compl_shown_match);
}
else
@@ -4103,7 +4215,8 @@ find_next_completion_match(
if (!match_at_original_text(compl_shown_match)
&& compl_leader != NULL
&& !ins_compl_equal(compl_shown_match,
- compl_leader, (int)STRLEN(compl_leader)))
+ compl_leader, (int)STRLEN(compl_leader))
+ && !(compl_fuzzy_match && compl_shown_match->cp_score > 0))
++todo;
else
// Remember a matching item.
@@ -4153,13 +4266,18 @@ ins_compl_next(
int advance;
int started = compl_started;
buf_T *orig_curbuf = curbuf;
+ unsigned int cur_cot_flags = get_cot_flags();
+ int compl_no_insert = (cur_cot_flags & COT_NOINSERT) != 0;
+ int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
// When user complete function return -1 for findstart which is next
// time of 'always', compl_shown_match become NULL.
if (compl_shown_match == NULL)
return -1;
- if (compl_leader != NULL && !match_at_original_text(compl_shown_match))
+ if (compl_leader != NULL
+ && !match_at_original_text(compl_shown_match)
+ && !compl_fuzzy_match)
// Update "compl_shown_match" to the actually shown match
ins_compl_update_shown_match();
@@ -4305,7 +4423,7 @@ ins_compl_check_keys(int frequency, int in_compl_func)
}
}
}
- if (compl_pending != 0 && !got_int && !compl_no_insert)
+ if (compl_pending != 0 && !got_int && !(cot_flags & COT_NOINSERT))
{
int todo = compl_pending > 0 ? compl_pending : -compl_pending;
@@ -4383,7 +4501,8 @@ ins_compl_use_match(int c)
/*
* Get the pattern, column and length for normal completion (CTRL-N CTRL-P
* completion)
- * Sets the global variables: compl_col, compl_length and compl_pattern.
+ * Sets the global variables: compl_col, compl_length, compl_pattern and
+ * compl_patternlen.
* Uses the global variables: compl_cont_status and ctrl_x_mode
*/
static int
@@ -4404,32 +4523,45 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
else
compl_pattern = vim_strnsave(line + compl_col, compl_length);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
}
else if (compl_status_adding())
{
char_u *prefix = (char_u *)"\\<";
+ size_t prefixlen = STRLEN_LITERAL("\\<");
// we need up to 2 extra chars for the prefix
compl_pattern = alloc(quote_meta(NULL, line + compl_col,
- compl_length) + 2);
+ compl_length) + prefixlen);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
if (!vim_iswordp(line + compl_col)
|| (compl_col > 0
&& (vim_iswordp(mb_prevptr(line, line + compl_col)))))
+ {
prefix = (char_u *)"";
+ prefixlen = 0;
+ }
STRCPY((char *)compl_pattern, prefix);
- (void)quote_meta(compl_pattern + STRLEN(prefix),
+ (void)quote_meta(compl_pattern + prefixlen,
line + compl_col, compl_length);
}
else if (--startcol < 0
|| !vim_iswordp(mb_prevptr(line, line + startcol + 1)))
{
// Match any word of at least two chars
- compl_pattern = vim_strsave((char_u *)"\\<\\k\\k");
+ compl_pattern = vim_strnsave((char_u *)"\\<\\k\\k", STRLEN_LITERAL("\\<\\k\\k"));
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
compl_col += curs_col;
compl_length = 0;
}
@@ -4465,7 +4597,10 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
// alloc(7) is enough -- Acevedo
compl_pattern = alloc(7);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
STRCPY((char *)compl_pattern, "\\<");
(void)quote_meta(compl_pattern + 2, line + compl_col, 1);
STRCAT((char *)compl_pattern, "\\k");
@@ -4475,13 +4610,18 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
compl_pattern = alloc(quote_meta(NULL, line + compl_col,
compl_length) + 2);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
STRCPY((char *)compl_pattern, "\\<");
(void)quote_meta(compl_pattern + 2, line + compl_col,
compl_length);
}
}
+ compl_patternlen = STRLEN(compl_pattern);
+
return OK;
}
@@ -4503,7 +4643,12 @@ get_wholeline_compl_info(char_u *line, colnr_T curs_col)
else
compl_pattern = vim_strnsave(line + compl_col, compl_length);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
+
+ compl_patternlen = STRLEN(compl_pattern);
return OK;
}
@@ -4533,7 +4678,12 @@ get_filename_compl_info(char_u *line, int startcol, colnr_T curs_col)
compl_length = (int)curs_col - startcol;
compl_pattern = addstar(line + compl_col, compl_length, EXPAND_FILES);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
+
+ compl_patternlen = STRLEN(compl_pattern);
return OK;
}
@@ -4547,9 +4697,13 @@ get_cmdline_compl_info(char_u *line, colnr_T curs_col)
{
compl_pattern = vim_strnsave(line, curs_col);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
+ compl_patternlen = curs_col;
set_cmd_context(&compl_xp, compl_pattern,
- (int)STRLEN(compl_pattern), curs_col, FALSE);
+ (int)compl_patternlen, curs_col, FALSE);
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
|| compl_xp.xp_context == EXPAND_NOTHING)
// No completion possible, use an empty pattern to get a
@@ -4647,8 +4801,12 @@ get_userdefined_compl_info(colnr_T curs_col UNUSED)
compl_length = curs_col - compl_col;
compl_pattern = vim_strnsave(line + compl_col, compl_length);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
+ compl_patternlen = compl_length;
ret = OK;
#endif
@@ -4685,8 +4843,12 @@ get_spell_compl_info(int startcol UNUSED, colnr_T curs_col UNUSED)
line = ml_get(curwin->w_cursor.lnum);
compl_pattern = vim_strnsave(line + compl_col, compl_length);
if (compl_pattern == NULL)
+ {
+ compl_patternlen = 0;
return FAIL;
+ }
+ compl_patternlen = compl_length;
ret = OK;
#endif
@@ -4907,6 +5069,7 @@ ins_compl_start(void)
-1, NULL, NULL, NULL, 0, flags, FALSE) != OK)
{
VIM_CLEAR(compl_pattern);
+ compl_patternlen = 0;
VIM_CLEAR(compl_orig_text);
return FAIL;
}
@@ -5195,7 +5358,7 @@ spell_back_to_badword(void)
{
pos_T tpos = curwin->w_cursor;
- spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL);
+ spell_bad_len = spell_move_to(curwin, BACKWARD, SMT_ALL, TRUE, NULL);
if (curwin->w_cursor.col != tpos.col)
start_arrow(&tpos);
}
diff --git a/src/link.sh b/src/link.sh
index e4030de..6e5c50f 100755
--- a/src/link.sh
+++ b/src/link.sh
@@ -53,7 +53,7 @@ else
if sh link_$PROG.cmd; then
touch auto/link.sed
cp link_$PROG.cmd linkit_$PROG.sh
- for libname in SM ICE nsl dnet dnet_stub inet socket dir elf iconv Xt Xmu Xp Xpm X11 Xdmcp x w perl dl pthread thread readline m crypt attr; do
+ for libname in SM ICE nsl dnet dnet_stub inet socket dir iconv Xt Xmu Xp Xpm X11 Xdmcp x w perl dl pthread thread readline m crypt attr; do
cont=yes
while test -n "$cont"; do
if grep "l$libname " linkit_$PROG.sh >/dev/null; then
diff --git a/src/list.c b/src/list.c
index e9f1ae3..9479b4b 100644
--- a/src/list.c
+++ b/src/list.c
@@ -3194,4 +3194,28 @@ f_reduce(typval_T *argvars, typval_T *rettv)
blob_reduce(argvars, &argvars[1], rettv);
}
+/*
+ * slice() function
+ */
+ void
+f_slice(typval_T *argvars, typval_T *rettv)
+{
+ if (in_vim9script()
+ && ((argvars[0].v_type != VAR_STRING
+ && argvars[0].v_type != VAR_LIST
+ && argvars[0].v_type != VAR_BLOB
+ && check_for_list_arg(argvars, 0) == FAIL)
+ || check_for_number_arg(argvars, 1) == FAIL
+ || check_for_opt_number_arg(argvars, 2) == FAIL))
+ return;
+
+ if (check_can_index(&argvars[0], TRUE, FALSE) != OK)
+ return;
+
+ copy_tv(argvars, rettv);
+ eval_index_inner(rettv, TRUE, argvars + 1,
+ argvars[2].v_type == VAR_UNKNOWN ? NULL : argvars + 2,
+ TRUE, NULL, 0, FALSE);
+}
+
#endif // defined(FEAT_EVAL)
diff --git a/src/misc1.c b/src/misc1.c
index c5a0c38..8348488 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -497,12 +497,17 @@ plines_win_col(win_T *wp, linenr_T lnum, long column)
return lines;
}
+/*
+ * Return number of window lines the physical line range from "first" until
+ * "last" will occupy in window "wp". Takes into account folding, 'wrap',
+ * topfill and filler lines beyond the end of the buffer. Limit to "max" lines.
+ */
int
-plines_m_win(win_T *wp, linenr_T first, linenr_T last, int limit_winheight)
+plines_m_win(win_T *wp, linenr_T first, linenr_T last, int max)
{
int count = 0;
- while (first <= last && (!limit_winheight || count < wp->w_height))
+ while (first <= last && count < max)
{
#ifdef FEAT_FOLDING
int x;
@@ -531,9 +536,7 @@ plines_m_win(win_T *wp, linenr_T first, linenr_T last, int limit_winheight)
if (first == wp->w_buffer->b_ml.ml_line_count + 1)
count += diff_check_fill(wp, first);
#endif
- if (limit_winheight && count > wp->w_height)
- return wp->w_height;
- return (count);
+ return MIN(max, count);
}
int
diff --git a/src/mouse.c b/src/mouse.c
index 247c6df..4e10e72 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -3029,16 +3029,22 @@ mouse_comp_pos(
if (win->w_skipcol > 0 && lnum == win->w_topline)
{
- // Adjust for 'smoothscroll' clipping the top screen lines.
- // A similar formula is used in curs_columns().
int width1 = win->w_width - win_col_off(win);
- int skip_lines = 0;
- if (win->w_skipcol > width1)
- skip_lines = (win->w_skipcol - width1)
+
+ if (width1 > 0)
+ {
+ int skip_lines = 0;
+
+ // Adjust for 'smoothscroll' clipping the top screen lines.
+ // A similar formula is used in curs_columns().
+ if (win->w_skipcol > width1)
+ skip_lines = (win->w_skipcol - width1)
/ (width1 + win_col_off2(win)) + 1;
- else if (win->w_skipcol > 0)
- skip_lines = 1;
- count -= skip_lines;
+ else if (win->w_skipcol > 0)
+ skip_lines = 1;
+
+ count -= skip_lines;
+ }
}
if (count > row)
diff --git a/src/move.c b/src/move.c
index 1b6e003..71654dd 100644
--- a/src/move.c
+++ b/src/move.c
@@ -319,6 +319,7 @@ update_topline(void)
redraw_later(UPD_NOT_VALID);
curwin->w_topline = 1;
curwin->w_botline = 2;
+ curwin->w_skipcol = 0;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
curwin->w_scbind_pos = 1;
}
@@ -1455,7 +1456,7 @@ textpos2screenpos(
is_folded = hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
#endif
- row = plines_m_win(wp, wp->w_topline, lnum - 1, FALSE);
+ row = plines_m_win(wp, wp->w_topline, lnum - 1, INT_MAX);
// "row" should be the screen line where line "lnum" begins, which can
// be negative if "lnum" is "w_topline" and "w_skipcol" is non-zero.
row -= adjust_plines_for_skipcol(wp);
@@ -1629,6 +1630,7 @@ static void cursor_correct_sms(void)
int width2 = width1 + curwin_col_off2();
int so_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
int space_cols = (curwin->w_height - 1) * width2;
+ int overlap, top, bot;
int size = so == 0 ? 0 : win_linetabsize(curwin, curwin->w_topline,
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
@@ -1638,16 +1640,16 @@ static void cursor_correct_sms(void)
so_cols = space_cols / 2; // Not enough room: put cursor in the middle.
// Not enough screen lines in topline: ignore 'scrolloff'.
- while (so_cols > size && so_cols - width2 >= width1)
+ while (so_cols > size && so_cols - width2 >= width1 && width1 > 0)
so_cols -= width2;
if (so_cols >= width1 && so_cols > size)
so_cols -= width1;
// If there is no marker or we have non-zero scrolloff, just ignore it.
- int overlap = (curwin->w_skipcol == 0 || so_cols != 0) ? 0
+ overlap = (curwin->w_skipcol == 0 || so_cols != 0) ? 0
: sms_marker_overlap(curwin, -1);
- int top = curwin->w_skipcol + overlap + so_cols;
- int bot = curwin->w_skipcol + width1 + (curwin->w_height - 1) * width2
+ top = curwin->w_skipcol + overlap + so_cols;
+ bot = curwin->w_skipcol + width1 + (curwin->w_height - 1) * width2
- so_cols;
validate_virtcol();
colnr_T col = curwin->w_virtcol;
@@ -2025,6 +2027,8 @@ adjust_skipcol(void)
long so = get_scrolloff_value();
int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2;
int scrolled = FALSE;
+ int row = 0;
+ int overlap, col;
validate_cheight();
if (curwin->w_cline_height == curwin->w_height
@@ -2039,7 +2043,7 @@ adjust_skipcol(void)
}
validate_virtcol();
- int overlap = sms_marker_overlap(curwin, -1);
+ overlap = sms_marker_overlap(curwin, -1);
while (curwin->w_skipcol > 0
&& curwin->w_virtcol < curwin->w_skipcol + overlap + scrolloff_cols)
{
@@ -2057,8 +2061,19 @@ adjust_skipcol(void)
return; // don't scroll in the other direction now
}
- int col = curwin->w_virtcol - curwin->w_skipcol + scrolloff_cols;
- int row = 0;
+ col = curwin->w_virtcol + scrolloff_cols;
+
+ // Avoid adjusting for 'scrolloff' beyond the text line height.
+ if (scrolloff_cols > 0)
+ {
+ int size = win_linetabsize(curwin, curwin->w_topline,
+ ml_get(curwin->w_topline), (colnr_T)MAXCOL);
+ size = width1 + width2 * ((size - width1 + width2 - 1) / width2);
+ while (col > size)
+ col -= width2;
+ }
+ col -= curwin->w_skipcol;
+
if (col >= width1)
{
col -= width1;
@@ -2616,12 +2631,14 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
plines_win
#endif
(curwin, curwin->w_topline, FALSE);
- int skip_lines = 0;
int width1 = curwin->w_width - curwin_col_off();
+
if (width1 > 0)
{
int width2 = width1 + curwin_col_off2();
- // similar formula is used in curs_columns()
+ int skip_lines = 0;
+
+ // A similar formula is used in curs_columns().
if (curwin->w_skipcol > width1)
skip_lines += (curwin->w_skipcol - width1) / width2 + 1;
else if (curwin->w_skipcol > 0)
@@ -2781,7 +2798,9 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
}
curwin->w_valid |= VALID_TOPLINE;
- cursor_correct_sms();
+ // Make sure cursor is still visible after adjusting skipcol for "zb".
+ if (set_topbot)
+ cursor_correct_sms();
}
/*
@@ -3155,9 +3174,10 @@ static int get_scroll_overlap(int dir)
/*
* Scroll "count" lines with 'smoothscroll' in direction "dir". Return TRUE
- * when scrolling happened.
+ * when scrolling happened. Adjust "curscount" for scrolling different amount of
+ * lines when 'smoothscroll' is disabled.
*/
-static int scroll_with_sms(int dir, long count)
+static int scroll_with_sms(int dir, long count, long *curscount)
{
int prev_sms = curwin->w_p_sms;
colnr_T prev_skipcol = curwin->w_skipcol;
@@ -3180,7 +3200,10 @@ static int scroll_with_sms(int dir, long count)
fixdir = dir * -1;
while (curwin->w_skipcol > 0
&& curwin->w_topline < curbuf->b_ml.ml_line_count)
+ {
scroll_redraw(fixdir == FORWARD, 1);
+ *curscount += (fixdir == dir ? 1 : -1);
+ }
}
curwin->w_p_sms = prev_sms;
@@ -3217,21 +3240,27 @@ pagescroll(int dir, long count, int half)
curwin->w_p_scr = MIN(curwin->w_height, count);
count = MIN(curwin->w_height, curwin->w_p_scr);
- int curscount = count;
+ long curscount = count;
// Adjust count so as to not reveal end of buffer lines.
- if (dir == FORWARD)
+ if (dir == FORWARD
+ && (curwin->w_topline + curwin->w_height + count > buflen
+#ifdef FEAT_FOLDING
+ || hasAnyFolding(curwin)
+#endif
+ ))
{
int n = plines_correct_topline(curwin, curwin->w_topline, FALSE);
if (n - count < curwin->w_height && curwin->w_topline < buflen)
- n += plines_m_win(curwin, curwin->w_topline + 1, buflen, FALSE);
- if (n - count < curwin->w_height)
+ n += plines_m_win(curwin, curwin->w_topline + 1, buflen,
+ curwin->w_height + count);
+ if (n < curwin->w_height + count)
count = n - curwin->w_height;
}
// (Try to) scroll the window unless already at the end of the buffer.
if (count > 0)
{
- nochange = scroll_with_sms(dir, count);
+ nochange = scroll_with_sms(dir, count, &curscount);
curwin->w_cursor.lnum = prev_lnum;
curwin->w_cursor.col = prev_col;
curwin->w_curswant = prev_curswant;
@@ -3250,7 +3279,7 @@ pagescroll(int dir, long count, int half)
// Scroll [count] times 'window' or current window height lines.
count *= ((ONE_WINDOW && p_window > 0 && p_window < Rows - 1) ?
MAX(1, p_window - 2) : get_scroll_overlap(dir));
- nochange = scroll_with_sms(dir, count);
+ nochange = scroll_with_sms(dir, count, &count);
// Place cursor at top or bottom of window.
validate_botline();
diff --git a/src/normal.c b/src/normal.c
index fef2826..b55d941 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -61,7 +61,7 @@ static void nv_end(cmdarg_T *cap);
static void nv_dollar(cmdarg_T *cap);
static void nv_search(cmdarg_T *cap);
static void nv_next(cmdarg_T *cap);
-static int normal_search(cmdarg_T *cap, int dir, char_u *pat, int opt, int *wrapped);
+static int normal_search(cmdarg_T *cap, int dir, char_u *pat, size_t patlen, int opt, int *wrapped);
static void nv_csearch(cmdarg_T *cap);
static void nv_brackets(cmdarg_T *cap);
static void nv_percent(cmdarg_T *cap);
@@ -2169,6 +2169,7 @@ find_decl(
int flags_arg) // flags passed to searchit()
{
char_u *pat;
+ size_t patlen;
pos_T old_pos;
pos_T par_pos;
pos_T found_pos;
@@ -2185,8 +2186,9 @@ find_decl(
// Put "\V" before the pattern to avoid that the special meaning of "."
// and "~" causes trouble.
- sprintf((char *)pat, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s",
- len, ptr);
+ patlen = vim_snprintf((char *)pat, len + 7,
+ vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s", len, ptr);
+
old_pos = curwin->w_cursor;
save_p_ws = p_ws;
save_p_scs = p_scs;
@@ -2215,7 +2217,7 @@ find_decl(
for (;;)
{
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
- pat, 1L, searchflags, RE_LAST, NULL);
+ pat, patlen, 1L, searchflags, RE_LAST, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum)
t = FAIL; // match after start is failure too
@@ -2593,7 +2595,7 @@ nv_zg_zw(cmdarg_T *cap, int nchar)
// off this fails and find_ident_under_cursor() is
// used below.
emsg_off++;
- len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL);
+ len = spell_move_to(curwin, FORWARD, SMT_ALL, TRUE, NULL);
emsg_off--;
if (len != 0 && curwin->w_cursor.col <= pos.col)
ptr = ml_get_pos(&curwin->w_cursor);
@@ -3332,7 +3334,8 @@ nv_K_getcmd(
char_u **ptr_arg,
int n,
char_u *buf,
- unsigned buflen)
+ size_t bufsize,
+ size_t *buflen)
{
char_u *ptr = *ptr_arg;
int isman;
@@ -3342,6 +3345,7 @@ nv_K_getcmd(
{
// in the help buffer
STRCPY(buf, "he! ");
+ *buflen = STRLEN_LITERAL("he! ");
return n;
}
@@ -3349,10 +3353,9 @@ nv_K_getcmd(
{
// 'keywordprog' is an ex command
if (cap->count0 != 0)
- vim_snprintf((char *)buf, buflen, "%s %ld", kp, cap->count0);
+ *buflen = vim_snprintf((char *)buf, bufsize, "%s %ld ", kp, cap->count0);
else
- STRCPY(buf, kp);
- STRCAT(buf, " ");
+ *buflen = vim_snprintf((char *)buf, bufsize, "%s ", kp);
return n;
}
@@ -3377,19 +3380,16 @@ nv_K_getcmd(
isman = (STRCMP(kp, "man") == 0);
isman_s = (STRCMP(kp, "man -s") == 0);
if (cap->count0 != 0 && !(isman || isman_s))
- sprintf((char *)buf, ".,.+%ld", cap->count0 - 1);
+ *buflen = vim_snprintf((char *)buf, bufsize, ".,.+%ld! ", cap->count0 - 1);
+ else
+ *buflen = vim_snprintf((char *)buf, bufsize, "! ");
- STRCAT(buf, "! ");
if (cap->count0 == 0 && isman_s)
- STRCAT(buf, "man");
+ *buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "man ");
else
- STRCAT(buf, kp);
- STRCAT(buf, " ");
+ *buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "%s ", kp);
if (cap->count0 != 0 && (isman || isman_s))
- {
- sprintf((char *)buf + STRLEN(buf), "%ld", cap->count0);
- STRCAT(buf, " ");
- }
+ *buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "%ld ", cap->count0);
*ptr_arg = ptr;
return n;
@@ -3408,7 +3408,8 @@ nv_ident(cmdarg_T *cap)
{
char_u *ptr = NULL;
char_u *buf;
- unsigned buflen;
+ size_t bufsize;
+ size_t buflen;
char_u *newbuf;
char_u *p;
char_u *kp; // value of 'keywordprg'
@@ -3463,11 +3464,12 @@ nv_ident(cmdarg_T *cap)
return;
}
kp_ex = (*kp == ':');
- buflen = (unsigned)(n * 2 + 30 + STRLEN(kp));
- buf = alloc(buflen);
+ bufsize = (size_t)(n * 2 + 30 + STRLEN(kp));
+ buf = alloc(bufsize);
if (buf == NULL)
return;
buf[0] = NUL;
+ buflen = 0;
switch (cmdchar)
{
@@ -3481,12 +3483,15 @@ nv_ident(cmdarg_T *cap)
curwin->w_cursor.col = (colnr_T) (ptr - ml_get_curline());
if (!g_cmd && vim_iswordp(ptr))
+ {
STRCPY(buf, "\\<");
+ buflen = STRLEN_LITERAL("\\<");
+ }
no_smartcase = TRUE; // don't use 'smartcase' now
break;
case 'K':
- n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, buflen);
+ n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, bufsize, &buflen);
if (n == 0)
return;
break;
@@ -3495,30 +3500,47 @@ nv_ident(cmdarg_T *cap)
tag_cmd = TRUE;
#ifdef FEAT_CSCOPE
if (p_cst)
+ {
STRCPY(buf, "cstag ");
+ buflen = STRLEN_LITERAL("cstag ");
+ }
else
#endif
+ {
STRCPY(buf, "ts ");
+ buflen = STRLEN_LITERAL("ts ");
+ }
break;
default:
tag_cmd = TRUE;
if (curbuf->b_help)
+ {
STRCPY(buf, "he! ");
+ buflen = STRLEN_LITERAL("he! ");
+ }
else
{
if (g_cmd)
+ {
STRCPY(buf, "tj ");
+ buflen = STRLEN_LITERAL("tj ");
+ }
else if (cap->count0 == 0)
+ {
STRCPY(buf, "ta ");
+ buflen = STRLEN_LITERAL("ta ");
+ }
else
- sprintf((char *)buf, ":%ldta ", cap->count0);
+ buflen = vim_snprintf((char *)buf, bufsize, ":%ldta ", cap->count0);
}
}
// Now grab the chars in the identifier
if (cmdchar == 'K' && !kp_help)
{
+ size_t plen;
+
ptr = vim_strnsave(ptr, n);
if (kp_ex)
// Escape the argument properly for an Ex command
@@ -3532,7 +3554,8 @@ nv_ident(cmdarg_T *cap)
vim_free(buf);
return;
}
- newbuf = vim_realloc(buf, STRLEN(buf) + STRLEN(p) + 1);
+ plen = STRLEN(p);
+ newbuf = vim_realloc(buf, buflen + plen + 1);
if (newbuf == NULL)
{
vim_free(buf);
@@ -3540,7 +3563,8 @@ nv_ident(cmdarg_T *cap)
return;
}
buf = newbuf;
- STRCAT(buf, p);
+ STRCPY(buf + buflen, p);
+ buflen += plen;
vim_free(p);
}
else
@@ -3560,12 +3584,13 @@ nv_ident(cmdarg_T *cap)
else
aux_ptr = (char_u *)"\\|\"\n*?[";
- p = buf + STRLEN(buf);
+ p = buf + buflen;
while (n-- > 0)
{
// put a backslash before \ and some others
if (vim_strchr(aux_ptr, *ptr) != NULL)
*p++ = '\\';
+
// When current byte is a part of multibyte character, copy all
// bytes of that character.
if (has_mbyte)
@@ -3579,6 +3604,7 @@ nv_ident(cmdarg_T *cap)
*p++ = *ptr++;
}
*p = NUL;
+ buflen = p - buf;
}
// Execute the command.
@@ -3587,13 +3613,16 @@ nv_ident(cmdarg_T *cap)
if (!g_cmd && (has_mbyte
? vim_iswordp(mb_prevptr(ml_get_curline(), ptr))
: vim_iswordc(ptr[-1])))
- STRCAT(buf, "\\>");
+ {
+ STRCPY(buf + buflen, "\\>");
+ buflen += STRLEN_LITERAL("\\>");
+ }
// put pattern in search history
init_history();
- add_to_history(HIST_SEARCH, buf, TRUE, NUL);
+ add_to_history(HIST_SEARCH, buf, buflen, TRUE, NUL);
- (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0, NULL);
+ (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, buflen, 0, NULL);
}
else
{
@@ -4117,7 +4146,7 @@ nv_search(cmdarg_T *cap)
return;
}
- (void)normal_search(cap, cap->cmdchar, cap->searchbuf,
+ (void)normal_search(cap, cap->cmdchar, cap->searchbuf, STRLEN(cap->searchbuf),
(cap->arg || !EQUAL_POS(save_cursor, curwin->w_cursor))
? 0 : SEARCH_MARK, NULL);
}
@@ -4132,7 +4161,7 @@ nv_next(cmdarg_T *cap)
{
pos_T old = curwin->w_cursor;
int wrapped = FALSE;
- int i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, &wrapped);
+ int i = normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, &wrapped);
if (i == 1 && !wrapped && EQUAL_POS(old, curwin->w_cursor))
{
@@ -4140,7 +4169,7 @@ nv_next(cmdarg_T *cap)
// happen when an offset is given and the cursor is on the last char
// in the buffer: Repeat with count + 1.
cap->count1 += 1;
- (void)normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, NULL);
+ (void)normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, NULL);
cap->count1 -= 1;
}
@@ -4161,6 +4190,7 @@ normal_search(
cmdarg_T *cap,
int dir,
char_u *pat,
+ size_t patlen,
int opt, // extra flags for do_search()
int *wrapped)
{
@@ -4176,7 +4206,7 @@ normal_search(
curwin->w_set_curswant = TRUE;
CLEAR_FIELD(sia);
- i = do_search(cap->oap, dir, dir, pat, cap->count1,
+ i = do_search(cap->oap, dir, dir, pat, patlen, cap->count1,
opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia);
if (wrapped != NULL)
*wrapped = sia.sa_wrapped;
@@ -4201,6 +4231,7 @@ normal_search(
// "/$" will put the cursor after the end of the line, may need to
// correct that here
check_cursor();
+
return i;
}
@@ -4529,13 +4560,15 @@ nv_brackets(cmdarg_T *cap)
#endif
#ifdef FEAT_SPELL
- // "[s", "[S", "]s" and "]S": move to next spell error.
- else if (cap->nchar == 's' || cap->nchar == 'S')
+ // "[r", "[s", "[S", "]r", "]s" and "]S": move to next spell error.
+ else if (cap->nchar == 'r' || cap->nchar == 's' || cap->nchar == 'S')
{
setpcmark();
for (n = 0; n < cap->count1; ++n)
if (spell_move_to(curwin, cap->cmdchar == ']' ? FORWARD : BACKWARD,
- cap->nchar == 's' ? TRUE : FALSE, FALSE, NULL) == 0)
+ cap->nchar == 's' ? SMT_ALL :
+ cap->nchar == 'r' ? SMT_RARE :
+ SMT_BAD, FALSE, NULL) == 0)
{
clearopbeep(cap->oap);
break;
@@ -6663,29 +6696,40 @@ adjust_for_sel(cmdarg_T *cap)
int
unadjust_for_sel(void)
{
- pos_T *pp;
-
if (*p_sel == 'e' && !EQUAL_POS(VIsual, curwin->w_cursor))
+ return unadjust_for_sel_inner(LT_POS(VIsual, curwin->w_cursor)
+ ? &curwin->w_cursor : &VIsual);
+ return FALSE;
+}
+
+/*
+ * Move position "*pp" back one character for 'selection' == "exclusive".
+ * Returns TRUE when backed up to the previous line.
+ */
+ int
+unadjust_for_sel_inner(pos_T *pp)
+{
+ colnr_T cs, ce;
+
+ if (pp->coladd > 0)
+ --pp->coladd;
+ else if (pp->col > 0)
{
- if (LT_POS(VIsual, curwin->w_cursor))
- pp = &curwin->w_cursor;
- else
- pp = &VIsual;
- if (pp->coladd > 0)
- --pp->coladd;
- else
- if (pp->col > 0)
- {
- --pp->col;
- mb_adjustpos(curbuf, pp);
- }
- else if (pp->lnum > 1)
+ --pp->col;
+ mb_adjustpos(curbuf, pp);
+ if (virtual_active())
{
- --pp->lnum;
- pp->col = ml_get_len(pp->lnum);
- return TRUE;
+ getvcol(curwin, pp, &cs, NULL, &ce);
+ pp->coladd = ce - cs;
}
}
+ else if (pp->lnum > 1)
+ {
+ --pp->lnum;
+ pp->col = ml_get_len(pp->lnum);
+ return TRUE;
+ }
+
return FALSE;
}
diff --git a/src/ops.c b/src/ops.c
index e3e7827..eb75c34 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -231,7 +231,10 @@ shift_line(
{
vimlong_T count;
int i, j;
- int sw_val = trim_to_int(get_sw_value_indent(curbuf));
+ int sw_val = trim_to_int(get_sw_value_indent(curbuf, left));
+
+ if (sw_val == 0)
+ sw_val = 1; // shouldn't happen, just in case
count = get_indent(); // get current indent
@@ -283,7 +286,7 @@ shift_block(oparg_T *oap, int amount)
char_u *newp, *oldp;
size_t newlen, oldlen;
int oldcol = curwin->w_cursor.col;
- int sw_val = (int)get_sw_value_indent(curbuf);
+ int sw_val = (int)get_sw_value_indent(curbuf, left);
int ts_val = (int)curbuf->b_p_ts;
struct block_def bd;
int incr;
@@ -580,7 +583,7 @@ block_insert(
// copy the new text
mch_memmove(newp + startcol, s, slen);
- offset += slen;
+ offset += (int)slen;
if (spaces > 0 && !bdp->is_short)
{
@@ -607,7 +610,7 @@ block_insert(
if (b_insert)
// correct any text properties
- inserted_bytes(lnum, startcol, slen);
+ inserted_bytes(lnum, startcol, (int)slen);
if (lnum == oap->end.lnum)
{
@@ -1258,8 +1261,8 @@ op_replace(oparg_T *oap, int c)
replace_character(c);
else
PBYTE(curwin->w_cursor, c);
- if (inc(&curwin->w_cursor) == -1)
- break;
+ if (inc(&curwin->w_cursor) == -1)
+ break;
}
}
@@ -1608,7 +1611,7 @@ op_insert(oparg_T *oap, long count1)
if (oap->block_mode)
{
- size_t ins_len;
+ int ins_len;
char_u *firstline, *ins_text;
struct block_def bd2;
int did_indent = FALSE;
@@ -1722,7 +1725,7 @@ op_insert(oparg_T *oap, long count1)
add = len; // short line, point to the NUL
firstline += add;
len -= add;
- if (pre_textlen >= 0 && (ins_len = len - pre_textlen - offset) > 0)
+ if (pre_textlen >= 0 && (ins_len = (int)len - pre_textlen - offset) > 0)
{
ins_text = vim_strnsave(firstline, ins_len);
if (ins_text != NULL)
@@ -1811,7 +1814,7 @@ op_change(oparg_T *oap)
*/
if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int)
{
- size_t ins_len;
+ int ins_len;
// Auto-indenting may have changed the indent. If the cursor was past
// the indent, exclude that indent change from the inserted text.
@@ -1824,7 +1827,7 @@ op_change(oparg_T *oap)
bd.textcol += new_indent - pre_indent;
}
- ins_len = ml_get_len(oap->start.lnum) - pre_textlen;
+ ins_len = (int)ml_get_len(oap->start.lnum) - pre_textlen;
if (ins_len > 0)
{
// Subsequent calls to ml_get() flush the firstline data - take a
@@ -1866,7 +1869,7 @@ op_change(oparg_T *oap)
// Shift the properties for linenr as edit() would do.
if (curbuf->b_has_textprop)
adjust_prop_columns(linenr, bd.textcol,
- vpos.coladd + ins_len, 0);
+ vpos.coladd + (int)ins_len, 0);
#endif
}
}
@@ -2444,13 +2447,14 @@ charwise_block_prep(
int inclusive)
{
colnr_T startcol = 0, endcol = MAXCOL;
- int is_oneChar = FALSE;
colnr_T cs, ce;
char_u *p;
p = ml_get(lnum);
bdp->startspaces = 0;
bdp->endspaces = 0;
+ bdp->is_oneChar = FALSE;
+ bdp->start_char_vcols = 0;
if (lnum == start.lnum)
{
@@ -2462,8 +2466,8 @@ charwise_block_prep(
{
// Part of a tab selected -- but don't
// double-count it.
- bdp->startspaces = (ce - cs + 1)
- - start.coladd;
+ bdp->start_char_vcols = ce - cs + 1;
+ bdp->startspaces = bdp->start_char_vcols - start.coladd;
if (bdp->startspaces < 0)
bdp->startspaces = 0;
startcol++;
@@ -2483,19 +2487,16 @@ charwise_block_prep(
// of multi-byte char.
&& (*mb_head_off)(p, p + endcol) == 0))
{
- if (start.lnum == end.lnum
- && start.col == end.col)
+ if (start.lnum == end.lnum && start.col == end.col)
{
// Special case: inside a single char
- is_oneChar = TRUE;
- bdp->startspaces = end.coladd
- - start.coladd + inclusive;
+ bdp->is_oneChar = TRUE;
+ bdp->startspaces = end.coladd - start.coladd + inclusive;
endcol = startcol;
}
else
{
- bdp->endspaces = end.coladd
- + inclusive;
+ bdp->endspaces = end.coladd + inclusive;
endcol -= inclusive;
}
}
@@ -2503,10 +2504,11 @@ charwise_block_prep(
}
if (endcol == MAXCOL)
endcol = ml_get_len(lnum);
- if (startcol > endcol || is_oneChar)
+ if (startcol > endcol || bdp->is_oneChar)
bdp->textlen = 0;
else
bdp->textlen = endcol - startcol + inclusive;
+ bdp->textcol = startcol;
bdp->textstart = p + startcol;
}
@@ -2524,11 +2526,11 @@ op_addsub(
int change_cnt = 0;
linenr_T amount = Prenum1;
- // do_addsub() might trigger re-evaluation of 'foldexpr' halfway, when the
- // buffer is not completely updated yet. Postpone updating folds until before
- // the call to changed_lines().
+ // do_addsub() might trigger re-evaluation of 'foldexpr' halfway, when the
+ // buffer is not completely updated yet. Postpone updating folds until before
+ // the call to changed_lines().
#ifdef FEAT_FOLDING
- disable_fold_update++;
+ disable_fold_update++;
#endif
if (!VIsual_active)
diff --git a/src/option.c b/src/option.c
index 0cd2823..b26c606 100644
--- a/src/option.c
+++ b/src/option.c
@@ -417,6 +417,14 @@ set_init_xdg_rtp(void)
options[opt_idx].def_val[VI_DEFAULT] = xdg_rtp;
p_pp = xdg_rtp;
+#if defined(XDG_VDIR) && defined(FEAT_SESSION)
+ if ((opt_idx = findoption((char_u *)"viewdir")) < 0)
+ goto theend;
+
+ options[opt_idx].def_val[VI_DEFAULT] = (char_u *)XDG_VDIR;
+ p_vdir = (char_u *)XDG_VDIR;
+#endif
+
theend:
vim_free(vimrc1);
vim_free(vimrc2);
@@ -6216,6 +6224,10 @@ unset_global_local_option(char_u *name, void *from)
clear_string_option(&buf->b_p_inc);
break;
# endif
+ case PV_COT:
+ clear_string_option(&buf->b_p_cot);
+ buf->b_cot_flags = 0;
+ break;
case PV_DICT:
clear_string_option(&buf->b_p_dict);
break;
@@ -6325,6 +6337,7 @@ get_varp_scope(struct vimoption *p, int scope)
case PV_DEF: return (char_u *)&(curbuf->b_p_def);
case PV_INC: return (char_u *)&(curbuf->b_p_inc);
#endif
+ case PV_COT: return (char_u *)&(curbuf->b_p_cot);
case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
#ifdef FEAT_COMPL_FUNC
@@ -6405,6 +6418,8 @@ get_varp(struct vimoption *p)
case PV_INC: return *curbuf->b_p_inc != NUL
? (char_u *)&(curbuf->b_p_inc) : p->var;
#endif
+ case PV_COT: return *curbuf->b_p_cot != NUL
+ ? (char_u *)&(curbuf->b_p_cot) : p->var;
case PV_DICT: return *curbuf->b_p_dict != NUL
? (char_u *)&(curbuf->b_p_dict) : p->var;
case PV_TSR: return *curbuf->b_p_tsr != NUL
@@ -7197,6 +7212,8 @@ buf_copy_options(buf_T *buf, int flags)
COPY_OPT_SCTX(buf, BV_INEX);
# endif
#endif
+ buf->b_p_cot = empty_option;
+ buf->b_cot_flags = 0;
buf->b_p_dict = empty_option;
buf->b_p_tsr = empty_option;
#ifdef FEAT_COMPL_FUNC
@@ -8347,10 +8364,10 @@ get_sidescrolloff_value(void)
}
/*
- * Get the local or global value of 'backupcopy'.
+ * Get the local or global value of 'backupcopy' flags.
*/
unsigned int
-get_bkc_value(buf_T *buf)
+get_bkc_flags(buf_T *buf)
{
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
}
@@ -8369,7 +8386,7 @@ get_flp_value(buf_T *buf)
#endif
/*
- * Get the local or global value of the 'virtualedit' flags.
+ * Get the local or global value of 'virtualedit' flags.
*/
unsigned int
get_ve_flags(void)
diff --git a/src/option.h b/src/option.h
index bf889e4..91d8d95 100644
--- a/src/option.h
+++ b/src/option.h
@@ -513,6 +513,20 @@ EXTERN int p_confirm; // 'confirm'
#endif
EXTERN int p_cp; // 'compatible'
EXTERN char_u *p_cot; // 'completeopt'
+EXTERN unsigned cot_flags; // flags from 'completeopt'
+// Keep in sync with p_cot_values in optionstr.c
+#define COT_MENU 0x001
+#define COT_MENUONE 0x002
+#define COT_ANY_MENU 0x003 // combination of menu flags
+#define COT_LONGEST 0x004 // FALSE: insert full match,
+ // TRUE: insert longest prefix
+#define COT_PREVIEW 0x008
+#define COT_POPUP 0x010
+#define COT_POPUPHIDDEN 0x020
+#define COT_ANY_PREVIEW 0x038 // combination of preview flags
+#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert
+#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect
+#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled
#ifdef BACKSLASH_IN_FILENAME
EXTERN char_u *p_csl; // 'completeslash'
#endif
@@ -1127,6 +1141,7 @@ enum
, BV_CMS
#endif
, BV_COM
+ , BV_COT
, BV_CPT
, BV_DICT
, BV_TSR
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 33e3165..617f3ce 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -50,6 +50,7 @@
# define PV_CMS OPT_BUF(BV_CMS)
#endif
#define PV_COM OPT_BUF(BV_COM)
+#define PV_COT OPT_BOTH(OPT_BUF(BV_COT))
#define PV_CPT OPT_BUF(BV_CPT)
#define PV_DICT OPT_BOTH(OPT_BUF(BV_DICT))
#define PV_TSR OPT_BOTH(OPT_BUF(BV_TSR))
@@ -300,7 +301,7 @@ struct vimoption
# define ISP_LATIN1 (char_u *)"@,161-255"
#endif
-# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea"
+# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,k:PmenuMatch,<:PmenuMatchSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea"
// Default python version for pyx* commands
#if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
@@ -629,7 +630,7 @@ static struct vimoption options[] =
{"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT,
#ifdef FEAT_FOLDING
(char_u *)&p_cms, PV_CMS, did_set_commentstring, NULL,
- {(char_u *)"/*%s*/", (char_u *)0L}
+ {(char_u *)"/* %s */", (char_u *)0L}
#else
(char_u *)NULL, PV_NONE, NULL, NULL,
{(char_u *)0L, (char_u *)0L}
@@ -654,7 +655,7 @@ static struct vimoption options[] =
#endif
SCTX_INIT},
{"completeopt", "cot", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
- (char_u *)&p_cot, PV_NONE, did_set_completeopt, expand_set_completeopt,
+ (char_u *)&p_cot, PV_COT, did_set_completeopt, expand_set_completeopt,
{(char_u *)"menu,preview", (char_u *)0L}
SCTX_INIT},
{"completepopup", "cpp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON,
diff --git a/src/optionstr.c b/src/optionstr.c
index 45f126f..d722981 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -118,7 +118,7 @@ static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
NULL};
static char *(p_fcl_values[]) = {"all", NULL};
#endif
-static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "popup", "popuphidden", "noinsert", "noselect", NULL};
+static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "popup", "popuphidden", "noinsert", "noselect", "fuzzy", NULL};
#ifdef BACKSLASH_IN_FILENAME
static char *(p_csl_values[]) = {"slash", "backslash", NULL};
#endif
@@ -144,6 +144,7 @@ didset_string_options(void)
(void)opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
(void)opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE);
(void)opt_strings_flags(p_bo, p_bo_values, &bo_flags, TRUE);
+ (void)opt_strings_flags(p_cot, p_cot_values, &cot_flags, TRUE);
#ifdef FEAT_SESSION
(void)opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE);
(void)opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE);
@@ -301,6 +302,7 @@ check_buf_options(buf_T *buf)
check_string_option(&buf->b_p_lop);
check_string_option(&buf->b_p_ft);
check_string_option(&buf->b_p_cinw);
+ check_string_option(&buf->b_p_cot);
check_string_option(&buf->b_p_cpt);
#ifdef FEAT_COMPL_FUNC
check_string_option(&buf->b_p_cfu);
@@ -1601,10 +1603,21 @@ expand_set_complete(optexpand_T *args, int *numMatches, char_u ***matches)
char *
did_set_completeopt(optset_T *args UNUSED)
{
- if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
+ char_u *cot = p_cot;
+ unsigned *flags = &cot_flags;
+
+ if (args->os_flags & OPT_LOCAL)
+ {
+ cot = curbuf->b_p_cot;
+ flags = &curbuf->b_cot_flags;
+ }
+
+ if (check_opt_strings(cot, p_cot_values, TRUE) != OK)
+ return e_invalid_argument;
+
+ if (opt_strings_flags(cot, p_cot_values, flags, TRUE) != OK)
return e_invalid_argument;
- completeopt_was_set();
return NULL;
}
diff --git a/src/os_unix.h b/src/os_unix.h
index 6efd8ce..99184ab 100644
--- a/src/os_unix.h
+++ b/src/os_unix.h
@@ -347,6 +347,8 @@ typedef struct dsc$descriptor DESC;
# define DFLT_VDIR "sys$login:vimfiles/view"
# else
# define DFLT_VDIR "$HOME/.vim/view" // default for 'viewdir'
+# define XDG_VDIR (mch_getenv("XDG_CONFIG_HOME") ? \
+ "$XDG_CONFIG_HOME/vim/view" : "~/.config/vim/view")
# endif
#endif
diff --git a/src/po/check.vim b/src/po/check.vim
index b0460f1..2ea4a38 100644
--- a/src/po/check.vim
+++ b/src/po/check.vim
@@ -226,8 +226,8 @@ elseif ctu
" endif
endif
-" Check that all lines are no longer than 80 chars
-let overlong = search('\%>80v', 'n')
+" Check that no lines are longer than 80 chars (except comments)
+let overlong = search('^[^#]\%>80v', 'n')
if overlong > 0
echomsg "Lines should be wrapped at 80 columns"
" TODO: make this an error
diff --git a/src/po/it.po b/src/po/it.po
index 8bdc5e3..fde1c23 100644
--- a/src/po/it.po
+++ b/src/po/it.po
@@ -14,7 +14,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-03-06 09:13+0100\n"
+"POT-Creation-Date: 2024-05-28 09:50+0200\n"
"PO-Revision-Date: 2024-03-06 15:00+0100\n"
"Last-Translator: Antonio Colombo <azc100@gmail.com>\n"
"Language-Team: Italian\n"
@@ -421,9 +421,6 @@ msgstr "Katakana"
msgid "Bopomofo"
msgstr "Bopomofo"
-msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr "Memoria insufficiente per impostarlo, recupero memoria fallito!"
-
msgid ""
"\n"
"\tLast set from "
@@ -810,6 +807,9 @@ msgid_plural "+-%s%3ld lines: "
msgstr[0] "+-%s%3ld riga: "
msgstr[1] "+-%s%3ld righe: "
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr "Memoria insufficiente per impostarlo, recupero memoria fallito!"
+
msgid "No match at cursor, finding next"
msgstr "Nessuna corrispondenza al cursore, cerco la prossima"
@@ -3419,6 +3419,9 @@ msgstr " II file vimrc utente: \""
msgid " 3rd user vimrc file: \""
msgstr " III file vimrc utente: \""
+msgid " 4th user vimrc file: \""
+msgstr " IV file vimrc utente: \""
+
msgid " user exrc file: \""
msgstr " file exrc utente: \""
@@ -6351,6 +6354,9 @@ msgstr ""
"E876: (Espressione regolare NFA) Non c'è spazio sufficiente a immagazzinare "
"l'intero NFA"
+msgid "E877: (NFA regexp) Invalid character class: %d"
+msgstr "E877: (Espressione regolare NFA) Classe di caratteri non valida: %d"
+
msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!"
msgstr ""
"E878: (Espressione regolare NFA) Non posso allocare memoria per lo zigzag di "
@@ -7780,13 +7786,15 @@ msgid "E1330: Invalid type for object variable: %s"
msgstr "E1330: Tipo non valido per variabile Object: %s"
msgid ""
-"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or "
+"E1331: public must be followed by \"var\" or \"static\" or \"final\" or "
+"\"const\""
+msgstr ""
+"E1331: public dev'essere seguito da \"var\" o \"static\" o \"final\" o "
"\"const\""
-msgstr "E1331: Public dev'essere seguito da \"var\" o \"static\" o \"const\""
-msgid "E1332: Public variable name cannot start with underscore: %s"
+msgid "E1332: public variable name cannot start with underscore: %s"
msgstr ""
-"E1332: Il nome di un elemento Pubblico non può iniziare con un trattino "
+"E1332: Il nome di un elemento public non può iniziare con il trattino "
"basso: %s"
msgid "E1333: Cannot access protected variable \"%s\" in class \"%s\""
@@ -7967,10 +7975,10 @@ msgid "E1386: Object method \"%s\" accessible only using class \"%s\" object"
msgstr ""
"E1386: Metodo Object \"%s\" accessibile solo usando la Classe \"%s\" object"
-msgid "E1387: Public variable not supported in an interface"
-msgstr "E1387: Variabile pubblica non supportata in un'Interfaccia"
+msgid "E1387: public variable not supported in an interface"
+msgstr "E1387: Variabile public non supportata in un'Interfaccia"
-msgid "E1388: Public keyword not supported for a method"
+msgid "E1388: public keyword not supported for a method"
msgstr "E1388: Attributo public non supportato per un Metodo"
msgid "E1389: Missing name after implements"
@@ -8054,6 +8062,54 @@ msgstr "E1412: Metodo Object predefinito \"%s\" non supportato"
msgid "E1413: Builtin class method not supported"
msgstr "E1413: Metodo Classe predefinito non supportato"
+msgid "E1414: Enum can only be defined in Vim9 script"
+msgstr "E1414: Enum può essere usato solo negli script Vim9"
+
+msgid "E1415: Enum name must start with an uppercase letter: %s"
+msgstr "E1415: Il nome di Enum deve iniziare con una lettera maiuscola: %s"
+
+msgid "E1416: Enum cannot extend a class or enum"
+msgstr "E1416: Enum non può estendere una Classe o un Enum"
+
+msgid "E1417: Abstract cannot be used in an Enum"
+msgstr "E1417: Impossibile usare Abstract in un Enum"
+
+msgid "E1418: Invalid enum value declaration: %s"
+msgstr "E1418: Dichiarazione di variabile Enum non valida: %s"
+
+msgid "E1419: Not a valid command in an Enum: %s"
+msgstr "E1419: Comando non valido in un Enum: %s"
+
+msgid "E1420: Missing :endenum"
+msgstr "E1420: Manca :endenum"
+
+msgid "E1421: Enum \"%s\" cannot be used as a value"
+msgstr "E1421: Impossibile usare come valore Enum \"%s\""
+
+msgid "E1422: Enum value \"%s\" not found in enum \"%s\""
+msgstr "E1422: Valore Enum \"%s\" non trovato in Enum \"%s\""
+
+msgid "E1423: Enum value \"%s.%s\" cannot be modified"
+msgstr "E1423: Valore Enum \"%s.%s\" non può essere modificato"
+
+msgid "E1424: Using an Enum \"%s\" as a Number"
+msgstr "E1424: Uso dell'Enum \"%s\" come un Numero"
+
+msgid "E1425: Using an Enum \"%s\" as a String"
+msgstr "E1425: Uso di un Enum \"%s\" come una Stringa"
+
+msgid "E1426: Enum \"%s\" ordinal value cannot be modified"
+msgstr "E1426: Il valore ordinale di Enum \"%s\" non può essere modificato"
+
+msgid "E1427: Enum \"%s\" name cannot be modified"
+msgstr "E1427: Il nome di Enum \"%s\" non può essere modificato"
+
+msgid "E1428: Duplicate enum value: %s"
+msgstr "E1428: Valore di Enum duplicato: %s"
+
+msgid "E1429: Class can only be used in a script"
+msgstr "E1429: Class si può usare solo in uno script"
+
msgid "E1500: Cannot mix positional and non-positional arguments: %s"
msgstr ""
"E1500: Non si possono mischiare argomenti posizionali e non posizionali: %s"
@@ -8101,8 +8157,9 @@ msgstr "E1511: Numero caratteri errato per campo \"%s\""
msgid "E1512: Wrong character width for field \"%s\""
msgstr "E1512: Larghezza carattere errata per campo \"%s\""
-msgid "E1513: Cannot edit buffer. 'winfixbuf' is enabled"
-msgstr "E1513: Non riesco a modificare il buffer. Opzione 'winfixbuf' attiva"
+msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled"
+msgstr "E1513: Non riesco a passare a un altro buffer. Opzione "
+"'winfixbuf' attiva"
#. type of cmdline window or 0
#. result of cmdline window or 0
diff --git a/src/popupmenu.c b/src/popupmenu.c
index 7419806..6e9d826 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -26,6 +26,9 @@ static int pum_base_width; // width of pum items base
static int pum_kind_width; // width of pum items kind column
static int pum_extra_width; // width of extra stuff
static int pum_scrollbar; // TRUE when scrollbar present
+#ifdef FEAT_RIGHTLEFT
+static int pum_rl; // TRUE when pum is drawn 'rightleft'
+#endif
static int pum_row; // top row of pum
static int pum_col; // left column of pum
@@ -101,8 +104,9 @@ pum_display(
#if defined(FEAT_QUICKFIX)
win_T *pvwin;
#endif
+
#ifdef FEAT_RIGHTLEFT
- int right_left = State == MODE_CMDLINE ? FALSE : curwin->w_p_rl;
+ pum_rl = State != MODE_CMDLINE && curwin->w_p_rl;
#endif
do
@@ -243,7 +247,7 @@ pum_display(
// w_wcol includes virtual text "above"
int wcol = curwin->w_wcol % curwin->w_width;
#ifdef FEAT_RIGHTLEFT
- if (right_left)
+ if (pum_rl)
cursor_col = curwin->w_wincol + curwin->w_width - wcol - 1;
else
#endif
@@ -264,8 +268,8 @@ pum_display(
if (((cursor_col < Columns - p_pw || cursor_col < Columns - max_width)
#ifdef FEAT_RIGHTLEFT
- && !right_left)
- || (right_left && (cursor_col > p_pw || cursor_col > max_width)
+ && !pum_rl)
+ || (pum_rl && (cursor_col > p_pw || cursor_col > max_width)
#endif
))
{
@@ -274,7 +278,7 @@ pum_display(
// start with the maximum space available
#ifdef FEAT_RIGHTLEFT
- if (right_left)
+ if (pum_rl)
pum_width = pum_col - pum_scrollbar + 1;
else
#endif
@@ -291,22 +295,22 @@ pum_display(
}
else if (((cursor_col > p_pw || cursor_col > max_width)
#ifdef FEAT_RIGHTLEFT
- && !right_left)
- || (right_left && (cursor_col < Columns - p_pw
+ && !pum_rl)
+ || (pum_rl && (cursor_col < Columns - p_pw
|| cursor_col < Columns - max_width)
#endif
))
{
// align pum edge with "cursor_col"
#ifdef FEAT_RIGHTLEFT
- if (right_left
+ if (pum_rl
&& W_ENDCOL(curwin) < max_width + pum_scrollbar + 1)
{
pum_col = cursor_col + max_width + pum_scrollbar + 1;
if (pum_col >= Columns)
pum_col = Columns - 1;
}
- else if (!right_left)
+ else if (!pum_rl)
#endif
{
if (curwin->w_wincol > Columns - max_width - pum_scrollbar
@@ -320,7 +324,7 @@ pum_display(
}
#ifdef FEAT_RIGHTLEFT
- if (right_left)
+ if (pum_rl)
pum_width = pum_col - pum_scrollbar + 1;
else
#endif
@@ -330,7 +334,7 @@ pum_display(
{
pum_width = p_pw;
#ifdef FEAT_RIGHTLEFT
- if (right_left)
+ if (pum_rl)
{
if (pum_width > pum_col)
pum_width = pum_col;
@@ -358,7 +362,7 @@ pum_display(
{
// not enough room, will use what we have
#ifdef FEAT_RIGHTLEFT
- if (right_left)
+ if (pum_rl)
pum_col = Columns - 1;
else
#endif
@@ -370,7 +374,7 @@ pum_display(
if (max_width > p_pw)
max_width = p_pw; // truncate
#ifdef FEAT_RIGHTLEFT
- if (right_left)
+ if (pum_rl)
pum_col = max_width - 1;
else
#endif
@@ -417,6 +421,119 @@ pum_under_menu(int row, int col, int only_redrawing)
}
/*
+ * Computes attributes of text on the popup menu.
+ * Returns attributes for every cell, or NULL if all attributes are the same.
+ */
+ static int *
+pum_compute_text_attrs(char_u *text, hlf_T hlf)
+{
+ int i;
+ size_t leader_len;
+ int char_cells;
+ int new_attr;
+ char_u *ptr = text;
+ int cell_idx = 0;
+ garray_T *ga = NULL;
+ int *attrs = NULL;
+ char_u *leader = NULL;
+ int in_fuzzy;
+ int matched_start = FALSE;
+ int_u char_pos = 0;
+
+ if ((hlf != HLF_PSI && hlf != HLF_PNI)
+ || (highlight_attr[HLF_PMSI] == highlight_attr[HLF_PSI]
+ && highlight_attr[HLF_PMNI] == highlight_attr[HLF_PNI]))
+ return NULL;
+
+ leader = State == MODE_CMDLINE ? cmdline_compl_pattern()
+ : ins_compl_leader();
+ if (leader == NULL || *leader == NUL)
+ return NULL;
+
+ attrs = ALLOC_MULT(int, vim_strsize(text));
+ if (attrs == NULL)
+ return NULL;
+
+ in_fuzzy = State == MODE_CMDLINE ? cmdline_compl_is_fuzzy()
+ : (get_cot_flags() & COT_FUZZY) != 0;
+ leader_len = STRLEN(leader);
+
+ if (in_fuzzy)
+ ga = fuzzy_match_str_with_pos(text, leader);
+ else
+ matched_start = MB_STRNICMP(text, leader, leader_len) == 0;
+
+ while (*ptr != NUL)
+ {
+ new_attr = highlight_attr[hlf];
+
+ if (ga != NULL)
+ {
+ // Handle fuzzy matching
+ for (i = 0; i < ga->ga_len; i++)
+ {
+ if (char_pos == ((int_u *)ga->ga_data)[i])
+ {
+ new_attr = highlight_attr[hlf == HLF_PSI
+ ? HLF_PMSI : HLF_PMNI];
+ break;
+ }
+ }
+ }
+ else if (matched_start && ptr < text + leader_len)
+ new_attr = highlight_attr[hlf == HLF_PSI ? HLF_PMSI : HLF_PMNI];
+
+ char_cells = mb_ptr2cells(ptr);
+ for (i = 0; i < char_cells; i++)
+ attrs[cell_idx + i] = new_attr;
+ cell_idx += char_cells;
+
+ MB_PTR_ADV(ptr);
+ char_pos++;
+ }
+
+ if (ga != NULL)
+ {
+ ga_clear(ga);
+ vim_free(ga);
+ }
+ return attrs;
+}
+
+/*
+ * Displays text on the popup menu with specific attributes.
+ */
+ static void
+pum_screen_puts_with_attrs(
+ int row,
+ int col,
+ int cells UNUSED,
+ char_u *text,
+ int textlen,
+ int *attrs)
+{
+ int col_start = col;
+ char_u *ptr = text;
+ int char_len;
+ int attr;
+
+ // Render text with proper attributes
+ while (*ptr != NUL && ptr < text + textlen)
+ {
+ char_len = mb_ptr2len(ptr);
+#ifdef FEAT_RIGHTLEFT
+ if (pum_rl)
+ attr = attrs[col_start + cells - col - 1];
+ else
+#endif
+ attr = attrs[col - col_start];
+ screen_puts_len(ptr, char_len, row, col, attr);
+ col += mb_ptr2cells(ptr);
+ ptr += char_len;
+ }
+}
+
+/*
* Redraw the popup menu, using "pum_first" and "pum_selected".
*/
void
@@ -426,8 +543,9 @@ pum_redraw(void)
int col;
int attr_scroll = highlight_attr[HLF_PSB];
int attr_thumb = highlight_attr[HLF_PST];
+ hlf_T *hlfs; // array used for highlights
+ hlf_T hlf;
int attr;
- int *attrs; // array used for highlights
int i;
int idx;
char_u *s;
@@ -438,17 +556,17 @@ pum_redraw(void)
int round;
int n;
- int attrsNorm[3];
- int attrsSel[3];
+ hlf_T hlfsNorm[3];
+ hlf_T hlfsSel[3];
// "word"
- attrsNorm[0] = highlight_attr[HLF_PNI];
- attrsSel[0] = highlight_attr[HLF_PSI];
+ hlfsNorm[0] = HLF_PNI;
+ hlfsSel[0] = HLF_PSI;
// "kind"
- attrsNorm[1] = highlight_attr[HLF_PNK];
- attrsSel[1] = highlight_attr[HLF_PSK];
+ hlfsNorm[1] = HLF_PNK;
+ hlfsSel[1] = HLF_PSK;
// "extra text"
- attrsNorm[2] = highlight_attr[HLF_PNX];
- attrsSel[2] = highlight_attr[HLF_PSX];
+ hlfsNorm[2] = HLF_PNX;
+ hlfsSel[2] = HLF_PSX;
if (call_update_screen)
{
@@ -483,12 +601,13 @@ pum_redraw(void)
for (i = 0; i < pum_height; ++i)
{
idx = i + pum_first;
- attrs = (idx == pum_selected) ? attrsSel : attrsNorm;
- attr = attrs[0]; // start with "word" highlight
+ hlfs = (idx == pum_selected) ? hlfsSel : hlfsNorm;
+ hlf = hlfs[0]; // start with "word" highlight
+ attr = highlight_attr[hlf];
// prepend a space if there is room
#ifdef FEAT_RIGHTLEFT
- if (curwin->w_p_rl)
+ if (pum_rl)
{
if (pum_col < curwin->w_wincol + curwin->w_width - 1)
screen_putchar(' ', row, pum_col + 1, attr);
@@ -507,7 +626,8 @@ pum_redraw(void)
totwidth = 0;
for (round = 0; round < 3; ++round)
{
- attr = attrs[round];
+ hlf = hlfs[round];
+ attr = highlight_attr[hlf];
width = 0;
s = NULL;
switch (round)
@@ -527,6 +647,7 @@ pum_redraw(void)
// Display the text that fits or comes before a Tab.
// First convert it to printable characters.
char_u *st;
+ int *attrs;
int saved = *p;
if (saved != NUL)
@@ -534,8 +655,11 @@ pum_redraw(void)
st = transstr(s);
if (saved != NUL)
*p = saved;
+
+ attrs = pum_compute_text_attrs(st, hlf);
+
#ifdef FEAT_RIGHTLEFT
- if (curwin->w_p_rl)
+ if (pum_rl)
{
if (st != NULL)
{
@@ -544,19 +668,19 @@ pum_redraw(void)
if (rt != NULL)
{
char_u *rt_start = rt;
- int size;
+ int cells;
- size = vim_strsize(rt);
- if (size > pum_width)
+ cells = vim_strsize(rt);
+ if (cells > pum_width)
{
do
{
- size -= has_mbyte
- ? (*mb_ptr2cells)(rt) : 1;
+ cells -= has_mbyte
+ ? (*mb_ptr2cells)(rt) : 1;
MB_PTR_ADV(rt);
- } while (size > pum_width);
+ } while (cells > pum_width);
- if (size < pum_width)
+ if (cells < pum_width)
{
// Most left character requires
// 2-cells but only 1 cell is
@@ -564,11 +688,18 @@ pum_redraw(void)
// '<' on the left of the pum
// item
*(--rt) = '<';
- size++;
+ cells++;
}
}
- screen_puts_len(rt, (int)STRLEN(rt),
- row, col - size + 1, attr);
+
+ if (attrs == NULL)
+ screen_puts_len(rt, (int)STRLEN(rt),
+ row, col - cells + 1, attr);
+ else
+ pum_screen_puts_with_attrs(row,
+ col - cells + 1, cells, rt,
+ (int)STRLEN(rt), attrs);
+
vim_free(rt_start);
}
vim_free(st);
@@ -596,18 +727,26 @@ pum_redraw(void)
else
--cells;
}
- screen_puts_len(st, size, row, col, attr);
+
+ if (attrs == NULL)
+ screen_puts_len(st, size, row, col, attr);
+ else
+ pum_screen_puts_with_attrs(row, col, cells,
+ st, size, attrs);
+
vim_free(st);
}
col += width;
}
+ vim_free(attrs);
+
if (*p != TAB)
break;
// Display two spaces for a Tab.
#ifdef FEAT_RIGHTLEFT
- if (curwin->w_p_rl)
+ if (pum_rl)
{
screen_puts_len((char_u *)" ", 2, row, col - 1,
attr);
@@ -640,11 +779,11 @@ pum_redraw(void)
|| pum_base_width + n >= pum_width)
break;
#ifdef FEAT_RIGHTLEFT
- if (curwin->w_p_rl)
+ if (pum_rl)
{
screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
col + 1, ' ', ' ', attr);
- col = pum_col - pum_base_width - n + 1;
+ col = pum_col - pum_base_width - n;
}
else
#endif
@@ -657,7 +796,7 @@ pum_redraw(void)
}
#ifdef FEAT_RIGHTLEFT
- if (curwin->w_p_rl)
+ if (pum_rl)
screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ',
' ', attr);
else
@@ -667,7 +806,7 @@ pum_redraw(void)
if (pum_scrollbar > 0)
{
#ifdef FEAT_RIGHTLEFT
- if (curwin->w_p_rl)
+ if (pum_rl)
screen_putchar(' ', row, pum_col - pum_width,
i >= thumb_pos && i < thumb_pos + thumb_height
? attr_thumb : attr_scroll);
@@ -760,6 +899,7 @@ pum_set_selected(int n, int repeat UNUSED)
int context = pum_height / 2;
#ifdef FEAT_QUICKFIX
int prev_selected = pum_selected;
+ unsigned cur_cot_flags = get_cot_flags();
#endif
#if defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX)
int has_info = FALSE;
@@ -831,7 +971,7 @@ pum_set_selected(int n, int repeat UNUSED)
if (pum_array[pum_selected].pum_info != NULL
&& Rows > 10
&& repeat <= 1
- && vim_strchr(p_cot, 'p') != NULL)
+ && (cur_cot_flags & COT_ANY_PREVIEW))
{
win_T *curwin_save = curwin;
tabpage_T *curtab_save = curtab;
@@ -842,9 +982,9 @@ pum_set_selected(int n, int repeat UNUSED)
# endif
# ifdef FEAT_PROP_POPUP
has_info = TRUE;
- if (strstr((char *)p_cot, "popuphidden") != NULL)
+ if (cur_cot_flags & COT_POPUPHIDDEN)
use_popup = USEPOPUP_HIDDEN;
- else if (strstr((char *)p_cot, "popup") != NULL)
+ else if (cur_cot_flags & COT_POPUP)
use_popup = USEPOPUP_NORMAL;
else
use_popup = USEPOPUP_NONE;
@@ -1211,16 +1351,34 @@ pum_position_at_mouse(int min_width)
pum_row = 0;
}
}
- if (Columns - mouse_col >= pum_base_width
- || Columns - mouse_col > min_width)
- // Enough space to show at mouse column.
- pum_col = mouse_col;
+
+# ifdef FEAT_RIGHTLEFT
+ if (pum_rl)
+ {
+ if (mouse_col + 1 >= pum_base_width
+ || mouse_col + 1 > min_width)
+ // Enough space to show at mouse column.
+ pum_col = mouse_col;
+ else
+ // Not enough space, left align with window.
+ pum_col = (pum_base_width > min_width
+ ? min_width : pum_base_width) - 1;
+ pum_width = pum_col + 1;
+ }
else
- // Not enough space, right align with window.
- pum_col = Columns - (pum_base_width > min_width
+# endif
+ {
+ if (Columns - mouse_col >= pum_base_width
+ || Columns - mouse_col > min_width)
+ // Enough space to show at mouse column.
+ pum_col = mouse_col;
+ else
+ // Not enough space, right align with window.
+ pum_col = Columns - (pum_base_width > min_width
? min_width : pum_base_width);
+ pum_width = Columns - pum_col;
+ }
- pum_width = Columns - pum_col;
if (pum_width > pum_base_width + 1)
pum_width = pum_base_width + 1;
@@ -1444,6 +1602,9 @@ ui_post_balloon(char_u *mesg, list_T *list)
pum_compute_size();
pum_scrollbar = 0;
pum_height = balloon_arraysize;
+# ifdef FEAT_RIGHTLEFT
+ pum_rl = curwin->w_p_rl;
+# endif
pum_position_at_mouse(BALLOON_MIN_WIDTH);
pum_selected = -1;
@@ -1554,6 +1715,9 @@ pum_show_popupmenu(vimmenu_T *menu)
pum_compute_size();
pum_scrollbar = 0;
pum_height = pum_size;
+# ifdef FEAT_RIGHTLEFT
+ pum_rl = curwin->w_p_rl;
+# endif
pum_position_at_mouse(20);
pum_selected = -1;
@@ -1649,7 +1813,11 @@ pum_make_popup(char_u *path_name, int use_mouse_pos)
// Hack: set mouse position at the cursor so that the menu pops up
// around there.
mouse_row = W_WINROW(curwin) + curwin->w_wrow;
- mouse_col = curwin->w_wincol + curwin->w_wcol;
+ mouse_col =
+# ifdef FEAT_RIGHTLEFT
+ curwin->w_p_rl ? W_ENDCOL(curwin) - curwin->w_wcol - 1 :
+# endif
+ curwin->w_wincol + curwin->w_wcol;
}
menu = gui_find_menu(path_name);
diff --git a/src/popupwin.c b/src/popupwin.c
index 25bb153..38c1c9e 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -654,8 +654,8 @@ popup_show_curline(win_T *wp)
wp->w_topline = wp->w_buffer->b_ml.ml_line_count;
while (wp->w_topline < wp->w_cursor.lnum
&& wp->w_topline < wp->w_buffer->b_ml.ml_line_count
- && plines_m_win(wp, wp->w_topline, wp->w_cursor.lnum, FALSE)
- > wp->w_height)
+ && plines_m_win(wp, wp->w_topline, wp->w_cursor.lnum,
+ wp->w_height + 1) > wp->w_height)
++wp->w_topline;
}
diff --git a/src/proto.h b/src/proto.h
index 50802ce..94e34b0 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -94,6 +94,7 @@ extern int _stricoll(char *a, char *b);
# include "float.pro"
# include "fold.pro"
# include "getchar.pro"
+# include "gc.pro"
# include "gui_xim.pro"
# include "hardcopy.pro"
# include "hashtab.pro"
diff --git a/src/proto/cmdexpand.pro b/src/proto/cmdexpand.pro
index 100c23d..dfa6d1b 100644
--- a/src/proto/cmdexpand.pro
+++ b/src/proto/cmdexpand.pro
@@ -6,6 +6,8 @@ int cmdline_pum_active(void);
void cmdline_pum_remove(void);
void cmdline_pum_cleanup(cmdline_info_T *cclp);
int cmdline_compl_startcol(void);
+char_u *cmdline_compl_pattern(void);
+int cmdline_compl_is_fuzzy(void);
char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode);
void ExpandInit(expand_T *xp);
void ExpandCleanup(expand_T *xp);
diff --git a/src/proto/cmdhist.pro b/src/proto/cmdhist.pro
index 9c9e56c..5bf4b8d 100644
--- a/src/proto/cmdhist.pro
+++ b/src/proto/cmdhist.pro
@@ -9,7 +9,7 @@ char_u *get_history_arg(expand_T *xp, int idx);
void init_history(void);
void clear_hist_entry(histentry_T *hisptr);
int in_history(int type, char_u *str, int move_to_front, int sep, int writing);
-void add_to_history(int histype, char_u *new_entry, int in_map, int sep);
+void add_to_history(int histype, char_u *new_entry, size_t new_entrylen, int in_map, int sep);
void f_histadd(typval_T *argvars, typval_T *rettv);
void f_histdel(typval_T *argvars, typval_T *rettv);
void f_histget(typval_T *argvars, typval_T *rettv);
diff --git a/src/proto/dict.pro b/src/proto/dict.pro
index fdccca5..346e1d5 100644
--- a/src/proto/dict.pro
+++ b/src/proto/dict.pro
@@ -37,6 +37,7 @@ varnumber_T dict_get_bool(dict_T *d, char *key, int def);
char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
char_u *get_literal_key(char_u **arg);
int eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal);
+int eval_lit_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
void dict_extend(dict_T *d1, dict_T *d2, char_u *action, char *func_name);
dictitem_T *dict_lookup(hashitem_T *hi);
int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 1c2d05d..7247265 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -48,19 +48,9 @@ int eval_addlist(typval_T *tv1, typval_T *tv2);
int eval_leader(char_u **arg, int vim9);
int handle_predefined(char_u *s, int len, typval_T *rettv);
int check_can_index(typval_T *rettv, int evaluate, int verbose);
-void f_slice(typval_T *argvars, typval_T *rettv);
int eval_index_inner(typval_T *rettv, int is_range, typval_T *var1, typval_T *var2, int exclusive, char_u *key, int keylen, int verbose);
char_u *partial_name(partial_T *pt);
void partial_unref(partial_T *pt);
-int get_copyID(void);
-int garbage_collect(int testing);
-int set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack);
-int set_ref_in_dict(dict_T *d, int copyID);
-int set_ref_in_list(list_T *ll, int copyID);
-int set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack);
-int set_ref_in_callback(callback_T *cb, int copyID);
-int set_ref_in_item_class(class_T *cl, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack);
-int set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack);
char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int composite_val);
char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
int buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx);
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 3fd20b2..3bd7705 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -66,8 +66,8 @@ void restore_current_state(save_state_T *sst);
void ex_normal(exarg_T *eap);
void exec_normal_cmd(char_u *cmd, int remap, int silent);
void exec_normal(int was_typed, int use_vpeekc, int may_use_terminal_loop);
-int find_cmdline_var(char_u *src, int *usedlen);
-char_u *eval_vars(char_u *src, char_u *srcstart, int *usedlen, linenr_T *lnump, char **errormsg, int *escaped, int empty_is_error);
+int find_cmdline_var(char_u *src, size_t *usedlen);
+char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnump, char **errormsg, int *escaped, int empty_is_error);
char_u *expand_sfile(char_u *arg);
void dialog_msg(char_u *buff, char *format, char_u *fname);
void set_no_hlsearch(int flag);
diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro
index 3f7b30d..8d97870 100644
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -26,6 +26,7 @@ char_u *modname(char_u *fname, char_u *ext, int prepend_dot);
char_u *buf_modname(int shortname, char_u *fname, char_u *ext, int prepend_dot);
int vim_fgets(char_u *buf, int size, FILE *fp);
int vim_rename(char_u *from, char_u *to);
+int vim_copyfile(char_u *from, char_u *to);
int check_timestamps(int focus);
int buf_check_timestamp(buf_T *buf, int focus);
void buf_reload(buf_T *buf, int orig_mode, int reload_options);
diff --git a/src/proto/filepath.pro b/src/proto/filepath.pro
index fd8de80..46f51cb 100644
--- a/src/proto/filepath.pro
+++ b/src/proto/filepath.pro
@@ -1,11 +1,12 @@
/* filepath.c */
-int modify_fname(char_u *src, int tilde_file, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen);
+int modify_fname(char_u *src, int tilde_file, size_t *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen);
void shorten_dir(char_u *str);
int file_is_readable(char_u *fname);
void f_chdir(typval_T *argvars, typval_T *rettv);
void f_delete(typval_T *argvars, typval_T *rettv);
void f_executable(typval_T *argvars, typval_T *rettv);
void f_exepath(typval_T *argvars, typval_T *rettv);
+void f_filecopy(typval_T *argvars, typval_T *rettv);
void f_filereadable(typval_T *argvars, typval_T *rettv);
void f_filewritable(typval_T *argvars, typval_T *rettv);
void f_finddir(typval_T *argvars, typval_T *rettv);
diff --git a/src/proto/gc.pro b/src/proto/gc.pro
new file mode 100644
index 0000000..e13dbda
--- /dev/null
+++ b/src/proto/gc.pro
@@ -0,0 +1,12 @@
+/* gc.c */
+int get_copyID(void);
+int garbage_collect(int testing);
+int set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack);
+int set_ref_in_dict(dict_T *d, int copyID);
+int set_ref_in_list(list_T *ll, int copyID);
+int set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack);
+int set_ref_in_callback(callback_T *cb, int copyID);
+int set_ref_in_item_class(class_T *cl, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack);
+int set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack);
+/* vim: set ft=c : */
+
diff --git a/src/proto/indent.pro b/src/proto/indent.pro
index bafcefc..6e56a0e 100644
--- a/src/proto/indent.pro
+++ b/src/proto/indent.pro
@@ -1,15 +1,15 @@
/* indent.c */
int tabstop_set(char_u *var, int **array);
int tabstop_padding(colnr_T col, int ts_arg, int *vts);
-int tabstop_at(colnr_T col, int ts, int *vts);
+int tabstop_at(colnr_T col, int ts, int *vts, int left);
colnr_T tabstop_start(colnr_T col, int ts, int *vts);
void tabstop_fromto(colnr_T start_col, colnr_T end_col, int ts_arg, int *vts, int *ntabs, int *nspcs);
int *tabstop_copy(int *oldts);
int tabstop_count(int *ts);
int tabstop_first(int *ts);
long get_sw_value(buf_T *buf);
-long get_sw_value_indent(buf_T *buf);
-long get_sw_value_col(buf_T *buf, colnr_T col);
+long get_sw_value_indent(buf_T *buf, int left);
+long get_sw_value_col(buf_T *buf, colnr_T col, int left);
long get_sts_value(void);
int get_indent(void);
int get_indent_lnum(linenr_T lnum);
diff --git a/src/proto/insexpand.pro b/src/proto/insexpand.pro
index 51f5db0..dbd5ef7 100644
--- a/src/proto/insexpand.pro
+++ b/src/proto/insexpand.pro
@@ -27,9 +27,10 @@ int ins_compl_accept_char(int c);
int ins_compl_add_infercase(char_u *str_arg, int len, int icase, char_u *fname, int dir, int cont_s_ipos);
int ins_compl_has_shown_match(void);
int ins_compl_long_shown_match(void);
-void completeopt_was_set(void);
+unsigned int get_cot_flags(void);
int pum_wanted(void);
void ins_compl_show_pum(void);
+char_u *ins_compl_leader(void);
char_u *find_word_start(char_u *ptr);
char_u *find_word_end(char_u *ptr);
void ins_compl_clear(void);
diff --git a/src/proto/list.pro b/src/proto/list.pro
index 0b58c69..1659b8f 100644
--- a/src/proto/list.pro
+++ b/src/proto/list.pro
@@ -65,4 +65,5 @@ void f_insert(typval_T *argvars, typval_T *rettv);
void f_remove(typval_T *argvars, typval_T *rettv);
void f_reverse(typval_T *argvars, typval_T *rettv);
void f_reduce(typval_T *argvars, typval_T *rettv);
+void f_slice(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro
index e76bf75..d64f961 100644
--- a/src/proto/misc1.pro
+++ b/src/proto/misc1.pro
@@ -7,7 +7,7 @@ int plines_nofill(linenr_T lnum);
int plines_win_nofill(win_T *wp, linenr_T lnum, int limit_winheight);
int plines_win_nofold(win_T *wp, linenr_T lnum);
int plines_win_col(win_T *wp, linenr_T lnum, long column);
-int plines_m_win(win_T *wp, linenr_T first, linenr_T last, int limit_winheight);
+int plines_m_win(win_T *wp, linenr_T first, linenr_T last, int max);
int gchar_pos(pos_T *pos);
int gchar_cursor(void);
void pchar_cursor(int c);
diff --git a/src/proto/normal.pro b/src/proto/normal.pro
index 6dcbe41..36a26ec 100644
--- a/src/proto/normal.pro
+++ b/src/proto/normal.pro
@@ -31,5 +31,6 @@ int get_visual_text(cmdarg_T *cap, char_u **pp, int *lenp);
void start_selection(void);
void may_start_select(int c);
int unadjust_for_sel(void);
+int unadjust_for_sel_inner(pos_T *pp);
void set_cursor_for_append_to_line(void);
/* vim: set ft=c : */
diff --git a/src/proto/option.pro b/src/proto/option.pro
index be7ee95..69463d4 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -139,7 +139,7 @@ int reset_option_was_set(char_u *name);
int can_bs(int what);
long get_scrolloff_value(void);
long get_sidescrolloff_value(void);
-unsigned int get_bkc_value(buf_T *buf);
+unsigned int get_bkc_flags(buf_T *buf);
char_u *get_flp_value(buf_T *buf);
unsigned int get_ve_flags(void);
char_u *get_showbreak_value(win_T *win);
diff --git a/src/proto/search.pro b/src/proto/search.pro
index 5b2b889..08526c8 100644
--- a/src/proto/search.pro
+++ b/src/proto/search.pro
@@ -1,7 +1,7 @@
/* search.c */
-int search_regcomp(char_u *pat, char_u **used_pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch);
+int search_regcomp(char_u *pat, size_t patlen, char_u **used_pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch);
char_u *get_search_pat(void);
-void save_re_pat(int idx, char_u *pat, int magic);
+void save_re_pat(int idx, char_u *pat, size_t patlen, int magic);
void save_search_patterns(void);
void restore_search_patterns(void);
void free_search_patterns(void);
@@ -21,9 +21,9 @@ char_u *last_search_pat(void);
void reset_search_dir(void);
void set_last_search_pat(char_u *s, int idx, int magic, int setlast);
void last_pat_prog(regmmatch_T *regmatch);
-int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, int dir, char_u *pat, long count, int options, int pat_use, searchit_arg_T *extra_arg);
+int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, int dir, char_u *pat, size_t patlen, long count, int options, int pat_use, searchit_arg_T *extra_arg);
void set_search_direction(int cdir);
-int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, int options, searchit_arg_T *sia);
+int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, size_t patlen, long count, int options, searchit_arg_T *sia);
int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat);
int searchc(cmdarg_T *cap, int t_cmd);
pos_T *findmatch(oparg_T *oap, int initc);
@@ -40,6 +40,7 @@ int fuzzy_match(char_u *str, char_u *pat_arg, int matchseq, int *outScore, int_u
void f_matchfuzzy(typval_T *argvars, typval_T *rettv);
void f_matchfuzzypos(typval_T *argvars, typval_T *rettv);
int fuzzy_match_str(char_u *str, char_u *pat);
+garray_T *fuzzy_match_str_with_pos(char_u *str, char_u *pat);
void fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count);
int fuzzymatches_to_strmatches(fuzmatch_str_T *fuzmatch, char_u ***matches, int count, int funcsort);
/* vim: set ft=c : */
diff --git a/src/proto/spell.pro b/src/proto/spell.pro
index 98a1353..680bf34 100644
--- a/src/proto/spell.pro
+++ b/src/proto/spell.pro
@@ -6,7 +6,7 @@ int match_compoundrule(slang_T *slang, char_u *compflags);
int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req);
int spell_valid_case(int wordflags, int treeflags);
int spell_check_window(win_T *wp);
-int spell_move_to(win_T *wp, int dir, int allwords, int curline, hlf_T *attrp);
+int spell_move_to(win_T *wp, int dir, smt_T behaviour, int curline, hlf_T *attrp);
void spell_cat_line(char_u *buf, char_u *line, int maxlen);
char_u *spell_enc(void);
slang_T *slang_alloc(char_u *lang);
diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro
index d3d3b99..1b5800c 100644
--- a/src/proto/vim9class.pro
+++ b/src/proto/vim9class.pro
@@ -40,7 +40,7 @@ int is_class_name(char_u *name, typval_T *rettv);
void protected_method_access_errmsg(char_u *method_name);
int object_empty(object_T *obj);
int object_len(object_T *obj);
-char_u *object_string(object_T *obj, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int composite_val);
+char_u *object2string(object_T *obj, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int composite_val);
int class_instance_of(class_T *cl, class_T *other_cl);
void f_instanceof(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
index 2e5b693..414fe65 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -3388,7 +3388,7 @@ qf_jump_goto_line(
// Move the cursor to the first line in the buffer
save_cursor = curwin->w_cursor;
curwin->w_cursor.lnum = 0;
- if (!do_search(NULL, '/', '/', qf_pattern, (long)1, SEARCH_KEEP, NULL))
+ if (!do_search(NULL, '/', '/', qf_pattern, STRLEN(qf_pattern), (long)1, SEARCH_KEEP, NULL))
curwin->w_cursor = save_cursor;
}
}
@@ -4867,6 +4867,9 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
if (old_last == NULL)
{
+ win_T *wp;
+ tabpage_T *tp;
+
if (buf != curbuf)
{
internal_error("qf_fill_buffer()");
@@ -4883,6 +4886,10 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0)
(void)ml_delete((linenr_T)1);
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ if (wp->w_buffer == curbuf)
+ wp->w_skipcol = 0;
+
// Remove all undo information
u_clearallandblockfree(curbuf);
}
diff --git a/src/regexp.c b/src/regexp.c
index 4373ae0..ff201d9 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -161,6 +161,7 @@ re_multi_type(int c)
}
static char_u *reg_prev_sub = NULL;
+static size_t reg_prev_sublen = 0;
/*
* REGEXP_INRANGE contains all characters which are always special in a []
@@ -197,6 +198,30 @@ backslash_trans(int c)
return c;
}
+enum
+{
+ CLASS_ALNUM = 0,
+ CLASS_ALPHA,
+ CLASS_BLANK,
+ CLASS_CNTRL,
+ CLASS_DIGIT,
+ CLASS_GRAPH,
+ CLASS_LOWER,
+ CLASS_PRINT,
+ CLASS_PUNCT,
+ CLASS_SPACE,
+ CLASS_UPPER,
+ CLASS_XDIGIT,
+ CLASS_TAB,
+ CLASS_RETURN,
+ CLASS_BACKSPACE,
+ CLASS_ESCAPE,
+ CLASS_IDENT,
+ CLASS_KEYWORD,
+ CLASS_FNAME,
+ CLASS_NONE = 99
+};
+
/*
* Check for a character class name "[:name:]". "pp" points to the '['.
* Returns one of the CLASS_ items. CLASS_NONE means that no item was
@@ -205,58 +230,56 @@ backslash_trans(int c)
static int
get_char_class(char_u **pp)
{
- static const char *(class_names[]) =
+ // must be sorted by the 'value' field because it is used by bsearch()!
+ static keyvalue_T char_class_tab[] =
{
- "alnum:]",
-#define CLASS_ALNUM 0
- "alpha:]",
-#define CLASS_ALPHA 1
- "blank:]",
-#define CLASS_BLANK 2
- "cntrl:]",
-#define CLASS_CNTRL 3
- "digit:]",
-#define CLASS_DIGIT 4
- "graph:]",
-#define CLASS_GRAPH 5
- "lower:]",
-#define CLASS_LOWER 6
- "print:]",
-#define CLASS_PRINT 7
- "punct:]",
-#define CLASS_PUNCT 8
- "space:]",
-#define CLASS_SPACE 9
- "upper:]",
-#define CLASS_UPPER 10
- "xdigit:]",
-#define CLASS_XDIGIT 11
- "tab:]",
-#define CLASS_TAB 12
- "return:]",
-#define CLASS_RETURN 13
- "backspace:]",
-#define CLASS_BACKSPACE 14
- "escape:]",
-#define CLASS_ESCAPE 15
- "ident:]",
-#define CLASS_IDENT 16
- "keyword:]",
-#define CLASS_KEYWORD 17
- "fname:]",
-#define CLASS_FNAME 18
+ KEYVALUE_ENTRY(CLASS_ALNUM, "alnum:]"),
+ KEYVALUE_ENTRY(CLASS_ALPHA, "alpha:]"),
+ KEYVALUE_ENTRY(CLASS_BACKSPACE, "backspace:]"),
+ KEYVALUE_ENTRY(CLASS_BLANK, "blank:]"),
+ KEYVALUE_ENTRY(CLASS_CNTRL, "cntrl:]"),
+ KEYVALUE_ENTRY(CLASS_DIGIT, "digit:]"),
+ KEYVALUE_ENTRY(CLASS_ESCAPE, "escape:]"),
+ KEYVALUE_ENTRY(CLASS_FNAME, "fname:]"),
+ KEYVALUE_ENTRY(CLASS_GRAPH, "graph:]"),
+ KEYVALUE_ENTRY(CLASS_IDENT, "ident:]"),
+ KEYVALUE_ENTRY(CLASS_KEYWORD, "keyword:]"),
+ KEYVALUE_ENTRY(CLASS_LOWER, "lower:]"),
+ KEYVALUE_ENTRY(CLASS_PRINT, "print:]"),
+ KEYVALUE_ENTRY(CLASS_PUNCT, "punct:]"),
+ KEYVALUE_ENTRY(CLASS_RETURN, "return:]"),
+ KEYVALUE_ENTRY(CLASS_SPACE, "space:]"),
+ KEYVALUE_ENTRY(CLASS_TAB, "tab:]"),
+ KEYVALUE_ENTRY(CLASS_UPPER, "upper:]"),
+ KEYVALUE_ENTRY(CLASS_XDIGIT, "xdigit:]")
};
-#define CLASS_NONE 99
- int i;
- if ((*pp)[1] == ':')
+ // check that the value of "pp" has a chance of matching
+ if ((*pp)[1] == ':' && ASCII_ISLOWER((*pp)[2])
+ && ASCII_ISLOWER((*pp)[3]) && ASCII_ISLOWER((*pp)[4]))
{
- for (i = 0; i < (int)ARRAY_LENGTH(class_names); ++i)
- if (STRNCMP(*pp + 2, class_names[i], STRLEN(class_names[i])) == 0)
- {
- *pp += STRLEN(class_names[i]) + 2;
- return i;
- }
+ keyvalue_T target;
+ keyvalue_T *entry;
+ // this function can be called repeatedly with the same value for "pp"
+ // so we cache the last found entry.
+ static keyvalue_T *last_entry = NULL;
+
+ target.key = 0;
+ target.value = (char *)*pp + 2;
+ target.length = 0; // not used, see cmp_keyvalue_value_n()
+
+ if (last_entry != NULL && cmp_keyvalue_value_n(&target, last_entry) == 0)
+ entry = last_entry;
+ else
+ entry = (keyvalue_T *)bsearch(&target, &char_class_tab,
+ ARRAY_LENGTH(char_class_tab),
+ sizeof(char_class_tab[0]), cmp_keyvalue_value_n);
+ if (entry != NULL)
+ {
+ last_entry = entry;
+ *pp += entry->length + 2;
+ return entry->key;
+ }
}
return CLASS_NONE;
}
@@ -597,6 +620,7 @@ skip_regexp_ex(
{
magic_T mymagic;
char_u *p = startp;
+ size_t startplen = 0;
if (magic)
mymagic = MAGIC_ON;
@@ -620,16 +644,21 @@ skip_regexp_ex(
if (dirc == '?' && newp != NULL && p[1] == '?')
{
// change "\?" to "?", make a copy first.
+ if (startplen == 0)
+ startplen = STRLEN(startp);
if (*newp == NULL)
{
- *newp = vim_strsave(startp);
+ *newp = vim_strnsave(startp, startplen);
if (*newp != NULL)
+ {
p = *newp + (p - startp);
+ startp = *newp;
+ }
}
if (dropped != NULL)
++*dropped;
if (*newp != NULL)
- STRMOVE(p, p + 1);
+ mch_memmove(p, p + 1, startplen - ((p + 1) - startp) + 1);
else
++p;
}
@@ -1189,20 +1218,114 @@ reg_iswordc(int c)
return vim_iswordc_buf(c, rex.reg_buf);
}
+#ifdef FEAT_EVAL
+static int can_f_submatch = FALSE; // TRUE when submatch() can be used
+
+// This struct is used for reg_submatch(). Needed for when the
+// substitution string is an expression that contains a call to substitute()
+// and submatch().
+typedef struct {
+ regmatch_T *sm_match;
+ regmmatch_T *sm_mmatch;
+ linenr_T sm_firstlnum;
+ linenr_T sm_maxline;
+ int sm_line_lbr;
+} regsubmatch_T;
+
+static regsubmatch_T rsm; // can only be used when can_f_submatch is TRUE
+#endif
+
+typedef enum
+{
+ RGLF_LINE = 0x01,
+ RGLF_LENGTH = 0x02
+#ifdef FEAT_EVAL
+ ,
+ RGLF_SUBMATCH = 0x04
+#endif
+} reg_getline_flags_T;
+
+//
+// common code for reg_getline(), reg_getline_len(), reg_getline_submatch() and
+// reg_getline_submatch_len().
+// the flags argument (which is a bitmask) controls what info is to be returned and whether
+// or not submatch is in effect.
+// note:
+// submatch is available only if FEAT_EVAL is defined.
+ static void
+reg_getline_common(linenr_T lnum, reg_getline_flags_T flags, char_u **line, colnr_T *length)
+{
+ int get_line = flags & RGLF_LINE;
+ int get_length = flags & RGLF_LENGTH;
+ linenr_T firstlnum;
+ linenr_T maxline;
+
+#ifdef FEAT_EVAL
+ if (flags & RGLF_SUBMATCH)
+ {
+ firstlnum = rsm.sm_firstlnum + lnum;
+ maxline = rsm.sm_maxline;
+ }
+ else
+#endif
+ {
+ firstlnum = rex.reg_firstlnum + lnum;
+ maxline = rex.reg_maxline;
+ }
+
+ // when looking behind for a match/no-match lnum is negative. but we
+ // can't go before line 1.
+ if (firstlnum < 1)
+ {
+ if (get_line)
+ *line = NULL;
+ if (get_length)
+ *length = 0;
+
+ return;
+ }
+
+ if (lnum > maxline)
+ {
+ // must have matched the "\n" in the last line.
+ if (get_line)
+ *line = (char_u *)"";
+ if (get_length)
+ *length = 0;
+
+ return;
+ }
+
+ if (get_line)
+ *line = ml_get_buf(rex.reg_buf, firstlnum, FALSE);
+ if (get_length)
+ *length = ml_get_buf_len(rex.reg_buf, firstlnum);
+}
+
/*
* Get pointer to the line "lnum", which is relative to "reg_firstlnum".
*/
static char_u *
reg_getline(linenr_T lnum)
{
- // when looking behind for a match/no-match lnum is negative. But we
- // can't go before line 1
- if (rex.reg_firstlnum + lnum < 1)
- return NULL;
- if (lnum > rex.reg_maxline)
- // Must have matched the "\n" in the last line.
- return (char_u *)"";
- return ml_get_buf(rex.reg_buf, rex.reg_firstlnum + lnum, FALSE);
+ char_u *line;
+
+ reg_getline_common(lnum, RGLF_LINE, &line, NULL);
+
+ return line;
+}
+
+/*
+ * Get length of line "lnum", which is relative to "reg_firstlnum".
+ */
+ static colnr_T
+reg_getline_len(linenr_T lnum)
+{
+ colnr_T length;
+
+ reg_getline_common(lnum, RGLF_LENGTH, NULL, &length);
+
+ return length;
}
#ifdef FEAT_SYN_HL
@@ -1484,7 +1607,7 @@ match_with_backref(
if (clnum == end_lnum)
len = end_col - ccol;
else
- len = (int)STRLEN(p + ccol);
+ len = (int)reg_getline_len(clnum) - ccol;
if (cstrncmp(p + ccol, rex.input, &len) != 0)
return RA_NOMATCH; // doesn't match
@@ -1745,49 +1868,71 @@ regtilde(char_u *source, int magic)
{
char_u *newsub = source;
char_u *p;
+ size_t newsublen = 0;
+ char_u tilde[3] = {'~', NUL, NUL};
+ size_t tildelen = 1;
+ int error = FALSE;
+
+ if (!magic)
+ {
+ tilde[0] = '\\';
+ tilde[1] = '~';
+ tilde[2] = NUL;
+ tildelen = 2;
+ }
for (p = newsub; *p; ++p)
{
- if ((*p == '~' && magic) || (*p == '\\' && *(p + 1) == '~' && !magic))
+ if (STRNCMP(p, tilde, tildelen) == 0)
{
- if (reg_prev_sub != NULL)
+ size_t prefixlen = p - newsub; // not including the tilde
+ char_u *postfix = p + tildelen;
+ size_t postfixlen;
+ size_t tmpsublen;
+
+ if (newsublen == 0)
+ newsublen = STRLEN(newsub);
+ newsublen -= tildelen;
+ postfixlen = newsublen - prefixlen;
+ tmpsublen = prefixlen + reg_prev_sublen + postfixlen;
+
+ if (tmpsublen > 0 && reg_prev_sub != NULL)
{
- // length = len(newsub) - 1 + len(prev_sub) + 1
+ char_u *tmpsub;
+
// Avoid making the text longer than MAXCOL, it will cause
// trouble at some point.
- size_t prevsublen = STRLEN(reg_prev_sub);
- size_t newsublen = STRLEN(newsub);
- if (prevsublen > MAXCOL || newsublen > MAXCOL
- || newsublen + prevsublen > MAXCOL)
+ if (tmpsublen > MAXCOL)
{
emsg(_(e_resulting_text_too_long));
+ error = TRUE;
break;
}
- char_u *tmpsub = alloc(newsublen + prevsublen);
- if (tmpsub != NULL)
+ tmpsub = alloc(tmpsublen + 1);
+ if (tmpsub == NULL)
{
- // copy prefix
- size_t prefixlen = p - newsub; // not including ~
- mch_memmove(tmpsub, newsub, prefixlen);
- // interpret tilde
- mch_memmove(tmpsub + prefixlen, reg_prev_sub,
- prevsublen);
- // copy postfix
- if (!magic)
- ++p; // back off backslash
- STRCPY(tmpsub + prefixlen + prevsublen, p + 1);
-
- if (newsub != source) // allocated newsub before
- vim_free(newsub);
- newsub = tmpsub;
- p = newsub + prefixlen + prevsublen;
+ emsg(_(e_out_of_memory));
+ error = TRUE;
+ break;
}
+
+ // copy prefix
+ mch_memmove(tmpsub, newsub, prefixlen);
+ // interpret tilde
+ mch_memmove(tmpsub + prefixlen, reg_prev_sub, reg_prev_sublen);
+ // copy postfix
+ STRCPY(tmpsub + prefixlen + reg_prev_sublen, postfix);
+
+ if (newsub != source) // allocated newsub before
+ vim_free(newsub);
+ newsub = tmpsub;
+ newsublen = tmpsublen;
+ p = newsub + prefixlen + reg_prev_sublen;
}
- else if (magic)
- STRMOVE(p, p + 1); // remove '~'
else
- STRMOVE(p, p + 2); // remove '\~'
+ mch_memmove(p, postfix, postfixlen + 1); // remove the tilde (+1 for the NUL)
+
--p;
}
else
@@ -1799,32 +1944,34 @@ regtilde(char_u *source, int magic)
}
}
+ if (error)
+ {
+ if (newsub != source)
+ vim_free(newsub);
+ return source;
+ }
+
// Store a copy of newsub in reg_prev_sub. It is always allocated,
// because recursive calls may make the returned string invalid.
- vim_free(reg_prev_sub);
- reg_prev_sub = vim_strsave(newsub);
+ // Only store it if there something to store.
+ newsublen = p - newsub;
+ if (newsublen == 0)
+ VIM_CLEAR(reg_prev_sub);
+ else
+ {
+ vim_free(reg_prev_sub);
+ reg_prev_sub = vim_strnsave(newsub, newsublen);
+ }
+
+ if (reg_prev_sub == NULL)
+ reg_prev_sublen = 0;
+ else
+ reg_prev_sublen = newsublen;
return newsub;
}
#ifdef FEAT_EVAL
-static int can_f_submatch = FALSE; // TRUE when submatch() can be used
-
-// These pointers are used for reg_submatch(). Needed for when the
-// substitution string is an expression that contains a call to substitute()
-// and submatch().
-typedef struct {
- regmatch_T *sm_match;
- regmmatch_T *sm_mmatch;
- linenr_T sm_firstlnum;
- linenr_T sm_maxline;
- int sm_line_lbr;
-} regsubmatch_T;
-
-static regsubmatch_T rsm; // can only be used when can_f_submatch is TRUE
-#endif
-
-#ifdef FEAT_EVAL
/*
* Put the submatches in "argv[argskip]" which is a list passed into
@@ -2028,12 +2175,16 @@ vim_regsub_both(
// "flags & REGSUB_COPY" != 0.
if (copy)
{
- if (eval_result[nested] != NULL &&
- (int)STRLEN(eval_result[nested]) < destlen)
+ if (eval_result[nested] != NULL)
{
- STRCPY(dest, eval_result[nested]);
- dst += STRLEN(eval_result[nested]);
- VIM_CLEAR(eval_result[nested]);
+ int eval_len = (int)STRLEN(eval_result[nested]);
+
+ if (eval_len < destlen)
+ {
+ STRCPY(dest, eval_result[nested]);
+ dst += eval_len;
+ VIM_CLEAR(eval_result[nested]);
+ }
}
}
else
@@ -2325,7 +2476,7 @@ vim_regsub_both(
len = rex.reg_mmatch->endpos[no].col
- rex.reg_mmatch->startpos[no].col;
else
- len = (int)STRLEN(s);
+ len = (int)reg_getline_len(clnum) - rex.reg_mmatch->startpos[no].col;
}
}
else
@@ -2360,7 +2511,7 @@ vim_regsub_both(
if (rex.reg_mmatch->endpos[no].lnum == clnum)
len = rex.reg_mmatch->endpos[no].col;
else
- len = (int)STRLEN(s);
+ len = (int)reg_getline_len(clnum);
}
else
break;
@@ -2465,26 +2616,25 @@ exit:
}
#ifdef FEAT_EVAL
-/*
- * Call reg_getline() with the line numbers from the submatch. If a
- * substitute() was used the reg_maxline and other values have been
- * overwritten.
- */
+
static char_u *
reg_getline_submatch(linenr_T lnum)
{
- char_u *s;
- linenr_T save_first = rex.reg_firstlnum;
- linenr_T save_max = rex.reg_maxline;
+ char_u *line;
+
+ reg_getline_common(lnum, RGLF_LINE | RGLF_SUBMATCH, &line, NULL);
+
+ return line;
+}
- rex.reg_firstlnum = rsm.sm_firstlnum;
- rex.reg_maxline = rsm.sm_maxline;
+ static colnr_T
+reg_getline_submatch_len(linenr_T lnum)
+{
+ colnr_T length;
- s = reg_getline(lnum);
+ reg_getline_common(lnum, RGLF_LENGTH | RGLF_SUBMATCH, NULL, &length);
- rex.reg_firstlnum = save_first;
- rex.reg_maxline = save_max;
- return s;
+ return length;
}
/*
@@ -2533,7 +2683,7 @@ reg_submatch(int no)
{
// Multiple lines: take start line from start col, middle
// lines completely and end line up to end col.
- len = (int)STRLEN(s);
+ len = (int)reg_getline_submatch_len(lnum) - rsm.sm_mmatch->startpos[no].col;
if (round == 2)
{
STRCPY(retval, s);
@@ -2543,13 +2693,14 @@ reg_submatch(int no)
++lnum;
while (lnum < rsm.sm_mmatch->endpos[no].lnum)
{
- s = reg_getline_submatch(lnum++);
+ s = reg_getline_submatch(lnum);
if (round == 2)
STRCPY(retval + len, s);
- len += (int)STRLEN(s);
+ len += (int)reg_getline_submatch_len(lnum);
if (round == 2)
retval[len] = '\n';
++len;
+ ++lnum;
}
if (round == 2)
STRNCPY(retval + len, reg_getline_submatch(lnum),
@@ -2624,9 +2775,11 @@ reg_submatch_list(int no)
}
else
{
+ int max_lnum = elnum - slnum;
+
if (list_append_string(list, s, -1) == FAIL)
error = TRUE;
- for (i = 1; i < elnum - slnum; i++)
+ for (i = 1; i < max_lnum; i++)
{
s = reg_getline_submatch(slnum + i);
if (list_append_string(list, s, -1) == FAIL)
diff --git a/src/regexp_bt.c b/src/regexp_bt.c
index 5d9450d..5452dda 100644
--- a/src/regexp_bt.c
+++ b/src/regexp_bt.c
@@ -2564,14 +2564,22 @@ bt_regcomp(char_u *expr, int re_flags)
if ((flags & SPSTART || OP(scan) == BOW || OP(scan) == EOW)
&& !(flags & HASNL))
{
+ size_t scanlen;
+
longest = NULL;
len = 0;
for (; scan != NULL; scan = regnext(scan))
- if (OP(scan) == EXACTLY && STRLEN(OPERAND(scan)) >= (size_t)len)
+ {
+ if (OP(scan) == EXACTLY)
{
- longest = OPERAND(scan);
- len = (int)STRLEN(OPERAND(scan));
+ scanlen = STRLEN(OPERAND(scan));
+ if (scanlen >= (size_t)len)
+ {
+ longest = OPERAND(scan);
+ len = (int)scanlen;
+ }
}
+ }
r->regmust = longest;
r->regmlen = len;
}
@@ -3406,8 +3414,7 @@ regmatch(
{
colnr_T pos_col = pos->lnum == rex.lnum + rex.reg_firstlnum
&& pos->col == MAXCOL
- ? (colnr_T)STRLEN(reg_getline(
- pos->lnum - rex.reg_firstlnum))
+ ? reg_getline_len(pos->lnum - rex.reg_firstlnum)
: pos->col;
if ((pos->lnum == rex.lnum + rex.reg_firstlnum
@@ -4695,7 +4702,7 @@ regmatch(
// right.
if (rex.line == NULL)
break;
- rex.input = rex.line + STRLEN(rex.line);
+ rex.input = rex.line + reg_getline_len(rex.lnum);
fast_breakcheck();
}
else
@@ -5249,8 +5256,10 @@ regprop(char_u *op)
{
char *p;
static char buf[50];
+ static size_t buflen = 0;
STRCPY(buf, ":");
+ buflen = 1;
switch ((int) OP(op))
{
@@ -5491,7 +5500,7 @@ regprop(char_u *op)
case MOPEN + 7:
case MOPEN + 8:
case MOPEN + 9:
- sprintf(buf + STRLEN(buf), "MOPEN%d", OP(op) - MOPEN);
+ buflen += sprintf(buf + buflen, "MOPEN%d", OP(op) - MOPEN);
p = NULL;
break;
case MCLOSE + 0:
@@ -5506,7 +5515,7 @@ regprop(char_u *op)
case MCLOSE + 7:
case MCLOSE + 8:
case MCLOSE + 9:
- sprintf(buf + STRLEN(buf), "MCLOSE%d", OP(op) - MCLOSE);
+ buflen += sprintf(buf + buflen, "MCLOSE%d", OP(op) - MCLOSE);
p = NULL;
break;
case BACKREF + 1:
@@ -5518,7 +5527,7 @@ regprop(char_u *op)
case BACKREF + 7:
case BACKREF + 8:
case BACKREF + 9:
- sprintf(buf + STRLEN(buf), "BACKREF%d", OP(op) - BACKREF);
+ buflen += sprintf(buf + buflen, "BACKREF%d", OP(op) - BACKREF);
p = NULL;
break;
case NOPEN:
@@ -5537,7 +5546,7 @@ regprop(char_u *op)
case ZOPEN + 7:
case ZOPEN + 8:
case ZOPEN + 9:
- sprintf(buf + STRLEN(buf), "ZOPEN%d", OP(op) - ZOPEN);
+ buflen += sprintf(buf + buflen, "ZOPEN%d", OP(op) - ZOPEN);
p = NULL;
break;
case ZCLOSE + 1:
@@ -5549,7 +5558,7 @@ regprop(char_u *op)
case ZCLOSE + 7:
case ZCLOSE + 8:
case ZCLOSE + 9:
- sprintf(buf + STRLEN(buf), "ZCLOSE%d", OP(op) - ZCLOSE);
+ buflen += sprintf(buf + buflen, "ZCLOSE%d", OP(op) - ZCLOSE);
p = NULL;
break;
case ZREF + 1:
@@ -5561,7 +5570,7 @@ regprop(char_u *op)
case ZREF + 7:
case ZREF + 8:
case ZREF + 9:
- sprintf(buf + STRLEN(buf), "ZREF%d", OP(op) - ZREF);
+ buflen += sprintf(buf + buflen, "ZREF%d", OP(op) - ZREF);
p = NULL;
break;
#endif
@@ -5602,7 +5611,7 @@ regprop(char_u *op)
case BRACE_COMPLEX + 7:
case BRACE_COMPLEX + 8:
case BRACE_COMPLEX + 9:
- sprintf(buf + STRLEN(buf), "BRACE_COMPLEX%d", OP(op) - BRACE_COMPLEX);
+ buflen += sprintf(buf + buflen, "BRACE_COMPLEX%d", OP(op) - BRACE_COMPLEX);
p = NULL;
break;
case MULTIBYTECODE:
@@ -5612,12 +5621,12 @@ regprop(char_u *op)
p = "NEWL";
break;
default:
- sprintf(buf + STRLEN(buf), "corrupt %d", OP(op));
+ buflen += sprintf(buf + buflen, "corrupt %d", OP(op));
p = NULL;
break;
}
if (p != NULL)
- STRCAT(buf, p);
+ STRCPY(buf + buflen, p);
return (char_u *)buf;
}
#endif // DEBUG
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
index 5e4fadd..4f07a21 100644
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -5387,7 +5387,7 @@ recursive_regmatch(
rex.input = rex.line;
}
else
- rex.input = rex.line + STRLEN(rex.line);
+ rex.input = rex.line + reg_getline_len(rex.lnum);
}
if ((int)(rex.input - rex.line) >= state->val)
{
@@ -6937,8 +6937,7 @@ nfa_regmatch(
{
colnr_T pos_col = pos->lnum == rex.lnum + rex.reg_firstlnum
&& pos->col == MAXCOL
- ? (colnr_T)STRLEN(reg_getline(
- pos->lnum - rex.reg_firstlnum))
+ ? reg_getline_len(pos->lnum - rex.reg_firstlnum)
: pos->col;
result = (pos->lnum == rex.lnum + rex.reg_firstlnum
diff --git a/src/scriptfile.c b/src/scriptfile.c
index d5ec7cf..711f576 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -435,8 +435,13 @@ check_script_symlink(int sid)
si = SCRIPT_ITEM(sid);
si->sn_sourced_sid = real_sid;
if (new_sid)
+ {
SCRIPT_ITEM(real_sid)->sn_import_autoload
= si->sn_import_autoload;
+ if (si->sn_autoload_prefix != NULL)
+ SCRIPT_ITEM(real_sid)->sn_autoload_prefix =
+ vim_strsave(si->sn_autoload_prefix);
+ }
}
}
vim_free(real_fname);
@@ -682,7 +687,7 @@ find_script_in_rtp(char_u *name)
{
int sid = -1;
- (void)do_in_path_and_pp(p_rtp, name, DIP_NOAFTER,
+ (void)do_in_path_and_pp(p_rtp, name, DIP_START | DIP_NOAFTER,
find_script_callback, &sid);
return sid;
}
diff --git a/src/search.c b/src/search.c
index 166ef4a..0b39d90 100644
--- a/src/search.c
+++ b/src/search.c
@@ -17,8 +17,8 @@ static void set_vv_searchforward(void);
static int first_submatch(regmmatch_T *rp);
#endif
#ifdef FEAT_FIND_ID
-static void show_pat_in_path(char_u *, int,
- int, int, FILE *, linenr_T *, long);
+static char_u *get_line_and_copy(linenr_T lnum, char_u *buf);
+static void show_pat_in_path(char_u *, int, int, int, FILE *, linenr_T *, long);
#endif
typedef struct searchstat
@@ -32,8 +32,27 @@ typedef struct searchstat
int last_maxcount; // the max count of the last search
} searchstat_T;
-static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, int show_top_bot_msg, char_u *msgbuf, int recompute, int maxcount, long timeout);
+#ifdef FEAT_SEARCH_EXTRA
+static void save_incsearch_state(void);
+static void restore_incsearch_state(void);
+#endif
+static int check_prevcol(char_u *linep, int col, int ch, int *prevcol);
+static int find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos);
+static void find_mps_values(int *initc, int *findc, int *backwards, int switchit);
+static int is_zero_width(char_u *pattern, size_t patternlen, int move, pos_T *cur, int direction);
+static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, int show_top_bot_msg, char_u *msgbuf, size_t msgbuflen, int recompute, int maxcount, long timeout);
static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat, int recompute, int maxcount, long timeout);
+static int fuzzy_match_compute_score(char_u *str, int strSz, int_u *matches, int numMatches);
+static int fuzzy_match_recursive(char_u *fuzpat, char_u *str, int_u strIdx, int *outScore, char_u *strBegin, int strLen, int_u *srcMatches, int_u *matches, int maxMatches, int nextMatch, int *recursionCount);
+#if defined(FEAT_EVAL) || defined(FEAT_PROTO)
+static int fuzzy_match_item_compare(const void *s1, const void *s2);
+static void fuzzy_match_in_list(list_T *l, char_u *str, int matchseq, char_u *key, callback_T *item_cb, int retmatchpos, list_T *fmatchlist, long max_matches);
+static void do_fuzzymatch(typval_T *argvars, typval_T *rettv, int retmatchpos);
+#endif
+static int fuzzy_match_str_compare(const void *s1, const void *s2);
+static void fuzzy_match_str_sort(fuzmatch_str_T *fm, int sz);
+static int fuzzy_match_func_compare(const void *s1, const void *s2);
+static void fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz);
#define SEARCH_STAT_DEF_TIMEOUT 40L
#define SEARCH_STAT_DEF_MAX_COUNT 99
@@ -69,8 +88,8 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
*/
static spat_T spats[2] =
{
- {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, // last used search pat
- {NULL, TRUE, FALSE, {'/', 0, 0, 0L}} // last used substitute pat
+ {NULL, 0, TRUE, FALSE, {'/', 0, 0, 0L}}, // last used search pat
+ {NULL, 0, TRUE, FALSE, {'/', 0, 0, 0L}} // last used substitute pat
};
static int last_idx = 0; // index in spats[] for RE_LAST
@@ -82,8 +101,9 @@ static char_u lastc_bytes[MB_MAXBYTES + 1];
static int lastc_bytelen = 1; // >1 for multi-byte char
// copy of spats[], for keeping the search patterns while executing autocmds
-static spat_T saved_spats[2];
+static spat_T saved_spats[ARRAY_LENGTH(spats)];
static char_u *saved_mr_pattern = NULL;
+static size_t saved_mr_patternlen = 0;
# ifdef FEAT_SEARCH_EXTRA
static int saved_spats_last_idx = 0;
static int saved_spats_no_hlsearch = 0;
@@ -91,6 +111,7 @@ static int saved_spats_no_hlsearch = 0;
// allocated copy of pattern used by search_regcomp()
static char_u *mr_pattern = NULL;
+static size_t mr_patternlen = 0;
#ifdef FEAT_FIND_ID
/*
@@ -123,6 +144,7 @@ typedef struct SearchedFile
int
search_regcomp(
char_u *pat,
+ size_t patlen,
char_u **used_pat,
int pat_save,
int pat_use,
@@ -130,7 +152,6 @@ search_regcomp(
regmmatch_T *regmatch) // return: pattern and ignore-case flag
{
int magic;
- int i;
rc_did_emsg = FALSE;
magic = magic_isset();
@@ -140,6 +161,8 @@ search_regcomp(
*/
if (pat == NULL || *pat == NUL)
{
+ int i;
+
if (pat_use == RE_LAST)
i = last_idx;
else
@@ -154,11 +177,12 @@ search_regcomp(
return FAIL;
}
pat = spats[i].pat;
+ patlen = spats[i].patlen;
magic = spats[i].magic;
no_smartcase = spats[i].no_scs;
}
else if (options & SEARCH_HIS) // put new pattern in history
- add_to_history(HIST_SEARCH, pat, TRUE, NUL);
+ add_to_history(HIST_SEARCH, pat, patlen, TRUE, NUL);
if (used_pat)
*used_pat = pat;
@@ -169,7 +193,11 @@ search_regcomp(
mr_pattern = reverse_text(pat);
else
#endif
- mr_pattern = vim_strsave(pat);
+ mr_pattern = vim_strnsave(pat, patlen);
+ if (mr_pattern == NULL)
+ mr_patternlen = 0;
+ else
+ mr_patternlen = patlen;
/*
* Save the currently used pattern in the appropriate place,
@@ -180,10 +208,10 @@ search_regcomp(
{
// search or global command
if (pat_save == RE_SEARCH || pat_save == RE_BOTH)
- save_re_pat(RE_SEARCH, pat, magic);
+ save_re_pat(RE_SEARCH, pat, patlen, magic);
// substitute or global command
if (pat_save == RE_SUBST || pat_save == RE_BOTH)
- save_re_pat(RE_SUBST, pat, magic);
+ save_re_pat(RE_SUBST, pat, patlen, magic);
}
regmatch->rmm_ic = ignorecase(pat);
@@ -204,13 +232,17 @@ get_search_pat(void)
}
void
-save_re_pat(int idx, char_u *pat, int magic)
+save_re_pat(int idx, char_u *pat, size_t patlen, int magic)
{
if (spats[idx].pat == pat)
return;
vim_free(spats[idx].pat);
- spats[idx].pat = vim_strsave(pat);
+ spats[idx].pat = vim_strnsave(pat, patlen);
+ if (spats[idx].pat == NULL)
+ spats[idx].patlen = 0;
+ else
+ spats[idx].patlen = patlen;
spats[idx].magic = magic;
spats[idx].no_scs = no_smartcase;
last_idx = idx;
@@ -231,19 +263,31 @@ static int save_level = 0;
void
save_search_patterns(void)
{
+ int i;
+
if (save_level++ != 0)
return;
- saved_spats[0] = spats[0];
- if (spats[0].pat != NULL)
- saved_spats[0].pat = vim_strsave(spats[0].pat);
- saved_spats[1] = spats[1];
- if (spats[1].pat != NULL)
- saved_spats[1].pat = vim_strsave(spats[1].pat);
+ for (i = 0; i < (int)ARRAY_LENGTH(spats); ++i)
+ {
+ saved_spats[i] = spats[i];
+ if (spats[i].pat != NULL)
+ {
+ saved_spats[i].pat = vim_strnsave(spats[i].pat, spats[i].patlen);
+ if (saved_spats[i].pat == NULL)
+ saved_spats[i].patlen = 0;
+ else
+ saved_spats[i].patlen = spats[i].patlen;
+ }
+ }
if (mr_pattern == NULL)
saved_mr_pattern = NULL;
else
- saved_mr_pattern = vim_strsave(mr_pattern);
+ saved_mr_pattern = vim_strnsave(mr_pattern, mr_patternlen);
+ if (saved_mr_pattern == NULL)
+ saved_mr_patternlen = 0;
+ else
+ saved_mr_patternlen = mr_patternlen;
#ifdef FEAT_SEARCH_EXTRA
saved_spats_last_idx = last_idx;
saved_spats_no_hlsearch = no_hlsearch;
@@ -253,18 +297,22 @@ save_search_patterns(void)
void
restore_search_patterns(void)
{
+ int i;
+
if (--save_level != 0)
return;
- vim_free(spats[0].pat);
- spats[0] = saved_spats[0];
+ for (i = 0; i < (int)ARRAY_LENGTH(spats); ++i)
+ {
+ vim_free(spats[i].pat);
+ spats[i] = saved_spats[i];
+ }
#if defined(FEAT_EVAL)
set_vv_searchforward();
#endif
- vim_free(spats[1].pat);
- spats[1] = saved_spats[1];
vim_free(mr_pattern);
mr_pattern = saved_mr_pattern;
+ mr_patternlen = saved_mr_patternlen;
#ifdef FEAT_SEARCH_EXTRA
last_idx = saved_spats_last_idx;
set_no_hlsearch(saved_spats_no_hlsearch);
@@ -275,9 +323,15 @@ restore_search_patterns(void)
void
free_search_patterns(void)
{
- vim_free(spats[0].pat);
- vim_free(spats[1].pat);
+ int i;
+
+ for (i = 0; i < (int)ARRAY_LENGTH(spats); ++i)
+ {
+ VIM_CLEAR(spats[i].pat);
+ spats[i].patlen = 0;
+ }
VIM_CLEAR(mr_pattern);
+ mr_patternlen = 0;
}
#endif
@@ -308,7 +362,13 @@ save_last_search_pattern(void)
saved_last_search_spat = spats[RE_SEARCH];
if (spats[RE_SEARCH].pat != NULL)
- saved_last_search_spat.pat = vim_strsave(spats[RE_SEARCH].pat);
+ {
+ saved_last_search_spat.pat = vim_strnsave(spats[RE_SEARCH].pat, spats[RE_SEARCH].patlen);
+ if (saved_last_search_spat.pat == NULL)
+ saved_last_search_spat.patlen = 0;
+ else
+ saved_last_search_spat.patlen = spats[RE_SEARCH].patlen;
+ }
saved_last_idx = last_idx;
saved_no_hlsearch = no_hlsearch;
}
@@ -328,6 +388,7 @@ restore_last_search_pattern(void)
vim_free(spats[RE_SEARCH].pat);
spats[RE_SEARCH] = saved_last_search_spat;
saved_last_search_spat.pat = NULL;
+ saved_last_search_spat.patlen = 0;
# if defined(FEAT_EVAL)
set_vv_searchforward();
# endif
@@ -513,7 +574,12 @@ set_last_search_pat(
if (*s == NUL)
spats[idx].pat = NULL;
else
- spats[idx].pat = vim_strsave(s);
+ {
+ spats[idx].patlen = STRLEN(s);
+ spats[idx].pat = vim_strnsave(s, spats[idx].patlen);
+ }
+ if (spats[idx].pat == NULL)
+ spats[idx].patlen = 0;
spats[idx].magic = magic;
spats[idx].no_scs = FALSE;
spats[idx].off.dir = '/';
@@ -532,7 +598,11 @@ set_last_search_pat(
if (spats[idx].pat == NULL)
saved_spats[idx].pat = NULL;
else
- saved_spats[idx].pat = vim_strsave(spats[idx].pat);
+ saved_spats[idx].pat = vim_strnsave(spats[idx].pat, spats[idx].patlen);
+ if (saved_spats[idx].pat == NULL)
+ saved_spats[idx].patlen = 0;
+ else
+ saved_spats[idx].patlen = spats[idx].patlen;
# ifdef FEAT_SEARCH_EXTRA
saved_spats_last_idx = last_idx;
# endif
@@ -560,7 +630,7 @@ last_pat_prog(regmmatch_T *regmatch)
return;
}
++emsg_off; // So it doesn't beep if bad expr
- (void)search_regcomp((char_u *)"", NULL, 0, last_idx, SEARCH_KEEP, regmatch);
+ (void)search_regcomp((char_u *)"", 0, NULL, 0, last_idx, SEARCH_KEEP, regmatch);
--emsg_off;
}
#endif
@@ -594,6 +664,7 @@ searchit(
pos_T *end_pos, // set to end of the match, unless NULL
int dir,
char_u *pat,
+ size_t patlen,
long count,
int options,
int pat_use, // which pattern to use when "pat" is empty
@@ -623,8 +694,9 @@ searchit(
linenr_T stop_lnum = 0; // stop after this line number when != 0
int unused_timeout_flag = FALSE;
int *timed_out = &unused_timeout_flag; // set when timed out.
+ int search_from_match_end; // vi-compatible search?
- if (search_regcomp(pat, NULL, RE_SEARCH, pat_use,
+ if (search_regcomp(pat, patlen, NULL, RE_SEARCH, pat_use,
(options & (SEARCH_HIS + SEARCH_KEEP)), &regmatch) == FAIL)
{
if ((options & SEARCH_MSG) && !rc_did_emsg)
@@ -632,6 +704,8 @@ searchit(
return FAIL;
}
+ search_from_match_end = vim_strchr(p_cpo, CPO_SEARCH) != NULL;
+
if (extra_arg != NULL)
{
stop_lnum = extra_arg->sa_stop_lnum;
@@ -778,7 +852,7 @@ searchit(
* of the match, otherwise continue one position
* forward.
*/
- if (vim_strchr(p_cpo, CPO_SEARCH) != NULL)
+ if (search_from_match_end)
{
if (nmatched > 1)
{
@@ -890,7 +964,7 @@ searchit(
* of the match, otherwise continue one position
* forward.
*/
- if (vim_strchr(p_cpo, CPO_SEARCH) != NULL)
+ if (search_from_match_end)
{
if (nmatched > 1)
break;
@@ -1173,12 +1247,14 @@ do_search(
int search_delim, // the delimiter for the search, e.g. '%' in
// s%regex%replacement%
char_u *pat,
+ size_t patlen,
long count,
int options,
searchit_arg_T *sia) // optional arguments or NULL
{
pos_T pos; // position of the last match
char_u *searchstr;
+ size_t searchstrlen;
soffset_T old_off;
int retval; // Return value
char_u *p;
@@ -1186,10 +1262,13 @@ do_search(
char_u *dircp;
char_u *strcopy = NULL;
char_u *ps;
+ int show_search_stats;
char_u *msgbuf = NULL;
- size_t len;
+ size_t msgbuflen = 0;
int has_offset = FALSE;
+ searchcmdlen = 0;
+
/*
* A line offset is not remembered, this is vi compatible.
*/
@@ -1267,24 +1346,28 @@ do_search(
int show_top_bot_msg = FALSE;
searchstr = pat;
+ searchstrlen = patlen;
+
dircp = NULL;
// use previous pattern
if (pat == NULL || *pat == NUL || *pat == search_delim)
{
if (spats[RE_SEARCH].pat == NULL) // no previous pattern
{
- searchstr = spats[RE_SUBST].pat;
- if (searchstr == NULL)
+ if (spats[RE_SUBST].pat == NULL)
{
emsg(_(e_no_previous_regular_expression));
retval = 0;
goto end_do_search;
}
+ searchstr = spats[RE_SUBST].pat;
+ searchstrlen = spats[RE_SUBST].patlen;
}
else
{
// make search_regcomp() use spats[RE_SEARCH].pat
searchstr = (char_u *)"";
+ searchstrlen = 0;
}
}
@@ -1299,13 +1382,17 @@ do_search(
&strcopy, NULL, NULL);
if (strcopy != ps)
{
+ size_t len = STRLEN(strcopy);
// made a copy of "pat" to change "\?" to "?"
- searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy));
+ searchcmdlen += (int)(patlen - len);
pat = strcopy;
+ patlen = len;
searchstr = strcopy;
+ searchstrlen = len;
}
if (*p == search_delim)
{
+ searchstrlen = p - pat;
dircp = p; // remember where we put the NUL
*p++ = NUL;
}
@@ -1344,16 +1431,19 @@ do_search(
// compute length of search command for get_address()
searchcmdlen += (int)(p - pat);
+ patlen -= p - pat;
pat = p; // put pat after search command
}
+ show_search_stats = FALSE;
if ((options & SEARCH_ECHO) && messaging()
&& !msg_silent
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT)))
{
- char_u *trunc;
char_u off_buf[40];
size_t off_len = 0;
+ size_t plen;
+ size_t msgbufsize;
// Compute msg_row early.
msg_start();
@@ -1362,24 +1452,28 @@ do_search(
if (!cmd_silent &&
(spats[0].off.line || spats[0].off.end || spats[0].off.off))
{
- p = off_buf;
- *p++ = dirc;
+ off_buf[off_len++] = dirc;
if (spats[0].off.end)
- *p++ = 'e';
+ off_buf[off_len++] = 'e';
else if (!spats[0].off.line)
- *p++ = 's';
+ off_buf[off_len++] = 's';
if (spats[0].off.off > 0 || spats[0].off.line)
- *p++ = '+';
- *p = NUL;
+ off_buf[off_len++] = '+';
+ off_buf[off_len] = NUL;
if (spats[0].off.off != 0 || spats[0].off.line)
- sprintf((char *)p, "%ld", spats[0].off.off);
- off_len = STRLEN(off_buf);
+ off_len += vim_snprintf((char *)off_buf + off_len, sizeof(off_buf) - off_len, "%ld", spats[0].off.off);
}
if (*searchstr == NUL)
+ {
p = spats[0].pat;
+ plen = spats[0].patlen;
+ }
else
+ {
p = searchstr;
+ plen = searchstrlen;
+ }
if (!shortmess(SHM_SEARCHCOUNT) || cmd_silent)
{
@@ -1389,45 +1483,53 @@ do_search(
// msg_strtrunc() will shorten in the middle.
if (msg_scrolled != 0 && !cmd_silent)
// Use all the columns.
- len = (int)(Rows - msg_row) * Columns - 1;
+ msgbufsize = (int)(Rows - msg_row) * Columns - 1;
else
// Use up to 'showcmd' column.
- len = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
- if (len < STRLEN(p) + off_len + SEARCH_STAT_BUF_LEN + 3)
- len = STRLEN(p) + off_len + SEARCH_STAT_BUF_LEN + 3;
+ msgbufsize = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
+ if (msgbufsize < plen + off_len + SEARCH_STAT_BUF_LEN + 3)
+ msgbufsize = plen + off_len + SEARCH_STAT_BUF_LEN + 3;
}
else
// Reserve enough space for the search pattern + offset.
- len = STRLEN(p) + off_len + 3;
+ msgbufsize = plen + off_len + 3;
vim_free(msgbuf);
- msgbuf = alloc(len);
- if (msgbuf != NULL)
+ msgbuf = alloc(msgbufsize);
+ if (msgbuf == NULL)
{
- vim_memset(msgbuf, ' ', len);
- msgbuf[len - 1] = NUL;
+ msgbuflen = 0;
+ }
+ else
+ {
+ vim_memset(msgbuf, ' ', msgbufsize);
+ msgbuflen = msgbufsize - 1;
+ msgbuf[msgbuflen] = NUL;
// do not fill the msgbuf buffer, if cmd_silent is set, leave it
// empty for the search_stat feature.
if (!cmd_silent)
{
+ char_u *trunc;
+
msgbuf[0] = dirc;
if (enc_utf8 && utf_iscomposing(utf_ptr2char(p)))
{
// Use a space to draw the composing char on.
msgbuf[1] = ' ';
- mch_memmove(msgbuf + 2, p, STRLEN(p));
+ mch_memmove(msgbuf + 2, p, plen);
}
else
- mch_memmove(msgbuf + 1, p, STRLEN(p));
+ mch_memmove(msgbuf + 1, p, plen);
if (off_len > 0)
- mch_memmove(msgbuf + STRLEN(p) + 1, off_buf, off_len);
+ mch_memmove(msgbuf + plen + 1, off_buf, off_len);
trunc = msg_strtrunc(msgbuf, TRUE);
if (trunc != NULL)
{
vim_free(msgbuf);
msgbuf = trunc;
+ msgbuflen = STRLEN(msgbuf);
}
#ifdef FEAT_RIGHTLEFT
@@ -1448,7 +1550,7 @@ do_search(
// move reversed text to beginning of buffer
while (*r != NUL && *r == ' ')
r++;
- pat_len = msgbuf + STRLEN(msgbuf) - r;
+ pat_len = msgbuf + msgbuflen - r;
mch_memmove(msgbuf, r, pat_len);
// overwrite old text
if ((size_t)(r - msgbuf) >= pat_len)
@@ -1466,7 +1568,10 @@ do_search(
out_flush();
msg_nowait = TRUE; // don't wait for this message
}
- }
+
+ if (!shortmess(SHM_SEARCHCOUNT))
+ show_search_stats = TRUE;
+ } // msgbuf != NULL
}
/*
@@ -1507,7 +1612,7 @@ do_search(
*/
c = searchit(curwin, curbuf, &pos, NULL,
dirc == '/' ? FORWARD : BACKWARD,
- searchstr, count, spats[0].off.end + (options &
+ searchstr, searchstrlen, count, spats[0].off.end + (options &
(SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
+ SEARCH_MSG + SEARCH_START
+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
@@ -1574,14 +1679,9 @@ do_search(
}
// Show [1/15] if 'S' is not in 'shortmess'.
- if ((options & SEARCH_ECHO)
- && messaging()
- && !msg_silent
- && c != FAIL
- && !shortmess(SHM_SEARCHCOUNT)
- && msgbuf != NULL)
+ if (show_search_stats)
cmdline_search_stat(dirc, &pos, &curwin->w_cursor,
- show_top_bot_msg, msgbuf,
+ show_top_bot_msg, msgbuf, msgbuflen,
(count != 1 || has_offset
#ifdef FEAT_FOLDING
|| (!(fdo_flags & FDO_SEARCH)
@@ -1612,6 +1712,7 @@ do_search(
goto end_do_search;
}
++pat;
+ --patlen;
}
if (options & SEARCH_MARK)
@@ -2825,7 +2926,7 @@ showmatch(
* Returns TRUE, FALSE or -1 for failure.
*/
static int
-is_zero_width(char_u *pattern, int move, pos_T *cur, int direction)
+is_zero_width(char_u *pattern, size_t patternlen, int move, pos_T *cur, int direction)
{
regmmatch_T regmatch;
int nmatched = 0;
@@ -2835,9 +2936,12 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, int direction)
int flag = 0;
if (pattern == NULL)
+ {
pattern = spats[last_idx].pat;
+ patternlen = spats[last_idx].patlen;
+ }
- if (search_regcomp(pattern, NULL, RE_SEARCH, RE_SEARCH,
+ if (search_regcomp(pattern, patternlen, NULL, RE_SEARCH, RE_SEARCH,
SEARCH_KEEP, &regmatch) == FAIL)
return -1;
@@ -2855,7 +2959,7 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, int direction)
flag = SEARCH_START;
}
- if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1,
+ if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, patternlen, 1,
SEARCH_KEEP + flag, RE_SEARCH, NULL) != FAIL)
{
// Zero-width pattern should match somewhere, then we can check if
@@ -2925,8 +3029,8 @@ current_search(
}
// Is the pattern is zero-width?, this time, don't care about the direction
- zero_width = is_zero_width(spats[last_idx].pat, TRUE, &curwin->w_cursor,
- FORWARD);
+ zero_width = is_zero_width(spats[last_idx].pat, spats[last_idx].patlen,
+ TRUE, &curwin->w_cursor, FORWARD);
if (zero_width == -1)
return FAIL; // pattern not found
@@ -2957,7 +3061,7 @@ current_search(
result = searchit(curwin, curbuf, &pos, &end_pos,
(dir ? FORWARD : BACKWARD),
- spats[last_idx].pat, (long) (i ? count : 1),
+ spats[last_idx].pat, spats[last_idx].patlen, (long) (i ? count : 1),
SEARCH_KEEP | flags, RE_SEARCH, NULL);
p_ws = old_p_ws;
@@ -3061,6 +3165,7 @@ cmdline_search_stat(
pos_T *cursor_pos,
int show_top_bot_msg,
char_u *msgbuf,
+ size_t msgbuflen,
int recompute,
int maxcount,
long timeout)
@@ -3079,34 +3184,33 @@ cmdline_search_stat(
if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
{
if (stat.incomplete == 1)
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
else if (stat.cnt > maxcount && stat.cur > maxcount)
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
maxcount, maxcount);
else if (stat.cnt > maxcount)
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
maxcount, stat.cur);
else
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
stat.cnt, stat.cur);
}
else
#endif
{
if (stat.incomplete == 1)
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
else if (stat.cnt > maxcount && stat.cur > maxcount)
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
maxcount, maxcount);
else if (stat.cnt > maxcount)
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
stat.cur, maxcount);
else
- vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
+ len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
stat.cur, stat.cnt);
}
- len = STRLEN(t);
if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN)
{
mch_memmove(t + 2, t, len);
@@ -3115,10 +3219,9 @@ cmdline_search_stat(
len += 2;
}
- size_t msgbuf_len = STRLEN(msgbuf);
- if (len > msgbuf_len)
- len = msgbuf_len;
- mch_memmove(msgbuf + msgbuf_len - len, t, len);
+ if (len > msgbuflen)
+ len = msgbuflen;
+ mch_memmove(msgbuf + msgbuflen - len, t, len);
if (dirc == '?' && stat.cur == maxcount + 1)
stat.cur = -1;
@@ -3214,7 +3317,7 @@ update_search_stat(
profile_setlimit(timeout, &start);
#endif
while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
- FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST, NULL) != FAIL)
+ FORWARD, NULL, 0, 1, SEARCH_KEEP, RE_LAST, NULL) != FAIL)
{
done_search = TRUE;
#ifdef FEAT_RELTIME
@@ -3342,7 +3445,7 @@ find_pattern_in_path(
pat = alloc(len + 5);
if (pat == NULL)
goto fpip_end;
- sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr);
+ vim_snprintf((char *)pat, len + 5, whole ? "\\<%.*s\\>" : "%.*s", len, ptr);
// ignore case according to p_ic, p_scs and pat
regmatch.rm_ic = ignorecase(pat);
regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0);
@@ -3361,8 +3464,7 @@ find_pattern_in_path(
}
if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL))
{
- def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL
- ? p_def : curbuf->b_p_def,
+ def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL ? p_def : curbuf->b_p_def,
magic_isset() ? RE_MAGIC : 0);
if (def_regmatch.regprog == NULL)
goto fpip_end;
@@ -3879,7 +3981,7 @@ exit_matched:
&& action == ACTION_EXPAND
&& !compl_status_sol()
&& *startp != NUL
- && *(p = startp + mb_ptr2len(startp)) != NUL)
+ && *(startp + mb_ptr2len(startp)) != NUL)
goto search_line;
}
line_breakcheck();
@@ -3976,6 +4078,7 @@ show_pat_in_path(
long count)
{
char_u *p;
+ size_t linelen;
if (did_show)
msg_putchar('\n'); // cursor below last one
@@ -3983,9 +4086,10 @@ show_pat_in_path(
gotocmdline(TRUE); // cursor at status line
if (got_int) // 'q' typed at "--more--" message
return;
+ linelen = STRLEN(line);
for (;;)
{
- p = line + STRLEN(line) - 1;
+ p = line + linelen - 1;
if (fp != NULL)
{
// We used fgets(), so get rid of newline at end
@@ -4015,6 +4119,7 @@ show_pat_in_path(
{
if (vim_fgets(line, LSIZE, fp)) // end of file
break;
+ linelen = STRLEN(line);
++*lnum;
}
else
@@ -4022,6 +4127,7 @@ show_pat_in_path(
if (++*lnum > curbuf->b_ml.ml_line_count)
break;
line = ml_get(*lnum);
+ linelen = ml_get_len(*lnum);
}
msg_putchar('\n');
}
@@ -4149,7 +4255,10 @@ f_searchcount(typval_T *argvars, typval_T *rettv)
if (*pattern == NUL)
goto the_end;
vim_free(spats[last_idx].pat);
- spats[last_idx].pat = vim_strsave(pattern);
+ spats[last_idx].patlen = STRLEN(pattern);
+ spats[last_idx].pat = vim_strnsave(pattern, spats[last_idx].patlen);
+ if (spats[last_idx].pat == NULL)
+ spats[last_idx].patlen = 0;
}
if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL)
goto the_end; // the previous pattern was never defined
@@ -4983,6 +5092,54 @@ fuzzy_match_str(char_u *str, char_u *pat)
}
/*
+ * Fuzzy match the position of string 'pat' in string 'str'.
+ * Returns a dynamic array of matching positions. If there is no match,
+ * returns NULL.
+ */
+ garray_T *
+fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED)
+{
+#ifdef FEAT_SEARCH_EXTRA
+ int score = 0;
+ garray_T *match_positions = NULL;
+ int_u matches[MAX_FUZZY_MATCHES];
+ int j = 0;
+
+ if (str == NULL || pat == NULL)
+ return NULL;
+
+ match_positions = ALLOC_ONE(garray_T);
+ if (match_positions == NULL)
+ return NULL;
+ ga_init2(match_positions, sizeof(int_u), 10);
+
+ if (!fuzzy_match(str, pat, FALSE, &score, matches, MAX_FUZZY_MATCHES)
+ || score == 0)
+ {
+ ga_clear(match_positions);
+ vim_free(match_positions);
+ return NULL;
+ }
+
+ for (char_u *p = pat; *p != NUL; MB_PTR_ADV(p))
+ {
+ if (!VIM_ISWHITE(PTR2CHAR(p)))
+ {
+ ga_grow(match_positions, 1);
+ ((int_u *)match_positions->ga_data)[match_positions->ga_len] =
+ matches[j];
+ match_positions->ga_len++;
+ j++;
+ }
+ }
+
+ return match_positions;
+#else
+ return NULL;
+#endif
+}
+
+/*
* Free an array of fuzzy string matches "fuzmatch[count]".
*/
void
diff --git a/src/spell.c b/src/spell.c
index 43c521d..909d426 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -1336,7 +1336,7 @@ no_spell_checking(win_T *wp)
spell_move_to(
win_T *wp,
int dir, // FORWARD or BACKWARD
- int allwords, // TRUE for "[s"/"]s", FALSE for "[S"/"]S"
+ smt_T behaviour, // Behaviour of the function
int curline,
hlf_T *attrp) // return: attributes of bad word or NULL
// (only when "dir" is FORWARD)
@@ -1441,7 +1441,9 @@ spell_move_to(
if (attr != HLF_COUNT)
{
// We found a bad word. Check the attribute.
- if (allwords || attr == HLF_SPB)
+ if (behaviour == SMT_ALL
+ || (behaviour == SMT_BAD && attr == HLF_SPB)
+ || (behaviour == SMT_RARE && attr == HLF_SPR))
{
// When searching forward only accept a bad word after
// the cursor.
@@ -2953,6 +2955,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
{
pos_T pos = curwin->w_cursor;
char_u *frompat;
+ size_t frompatlen;
char_u *line;
char_u *p;
int save_ws = p_ws;
@@ -2970,7 +2973,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
frompat = alloc(repl_from_len + 7);
if (frompat == NULL)
return;
- sprintf((char *)frompat, "\\V\\<%s\\>", repl_from);
+ frompatlen = vim_snprintf((char *)frompat, repl_from_len + 7, "\\V\\<%s\\>", repl_from);
p_ws = FALSE;
sub_nsubs = 0;
@@ -2978,7 +2981,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
curwin->w_cursor.lnum = 0;
while (!got_int)
{
- if (do_search(NULL, '/', '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
+ if (do_search(NULL, '/', '/', frompat, frompatlen, 1L, SEARCH_KEEP, NULL) == 0
|| u_save_cursor() == FAIL)
break;
diff --git a/src/spellsuggest.c b/src/spellsuggest.c
index c6e6183..b305bfb 100644
--- a/src/spellsuggest.c
+++ b/src/spellsuggest.c
@@ -512,7 +512,7 @@ spell_suggest(int count)
badlen = ml_get_curline_len() - (int)curwin->w_cursor.col;
}
// Find the start of the badly spelled word.
- else if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0
+ else if (spell_move_to(curwin, FORWARD, SMT_ALL, TRUE, NULL) == 0
|| curwin->w_cursor.col > prev_cursor.col)
{
// No bad word or it starts after the cursor: use the word under the
diff --git a/src/strings.c b/src/strings.c
index 33de175..6b2ff0a 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -151,7 +151,7 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
char_u *p;
char_u *d;
char_u *escaped_string;
- int l;
+ size_t l;
int csh_like;
int fish_like;
char_u *shname;
@@ -272,8 +272,9 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
if (do_special && find_cmdline_var(p, &l) >= 0)
{
*d++ = '\\'; // insert backslash
- while (--l >= 0) // copy the var
- *d++ = *p++;
+ memcpy(d, p, l); // copy the var
+ d += l;
+ p += l;
continue;
}
if (*p == '\\' && fish_like)
diff --git a/src/structs.h b/src/structs.h
index 36339c4..7e21f0f 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3222,6 +3222,8 @@ struct file_buffer
#ifdef FEAT_FOLDING
char_u *b_p_cms; // 'commentstring'
#endif
+ char_u *b_p_cot; // 'completeopt' local value
+ unsigned b_cot_flags; // flags for 'completeopt'
char_u *b_p_cpt; // 'complete'
#ifdef BACKSLASH_IN_FILENAME
char_u *b_p_csl; // 'completeslash'
@@ -4468,6 +4470,8 @@ typedef struct
char_u *pum_kind; // extra kind text (may be truncated)
char_u *pum_extra; // extra menu text (may be truncated)
char_u *pum_info; // extra info
+ int pum_score; // fuzzy match score
+ int pum_idx; // index of item before sorting by score
} pumitem_T;
/*
@@ -4795,6 +4799,7 @@ typedef struct soffset
typedef struct spat
{
char_u *pat; // the pattern (in allocated memory) or NULL
+ size_t patlen; // the length of the pattern (0 if pat is NULL)
int magic; // magicness of the pattern
int no_scs; // no smartcase for this pattern
soffset_T off;
diff --git a/src/tag.c b/src/tag.c
index 9117d0f..d406fde 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -3901,6 +3901,8 @@ jumpto_tag(
str = skip_regexp(pbuf + 1, pbuf[0], FALSE) + 1;
if (str > pbuf_end - 1) // search command with nothing following
{
+ size_t pbuflen = pbuf_end - pbuf;
+
save_p_ws = p_ws;
save_p_ic = p_ic;
save_p_scs = p_scs;
@@ -3914,7 +3916,7 @@ jumpto_tag(
else
// start search before first line
curwin->w_cursor.lnum = 0;
- if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
+ if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, (long)1,
search_options, NULL))
retval = OK;
else
@@ -3926,7 +3928,7 @@ jumpto_tag(
* try again, ignore case now
*/
p_ic = TRUE;
- if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
+ if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, (long)1,
search_options, NULL))
{
/*
@@ -3936,14 +3938,14 @@ jumpto_tag(
(void)test_for_static(&tagp);
cc = *tagp.tagname_end;
*tagp.tagname_end = NUL;
- sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
- if (!do_search(NULL, '/', '/', pbuf, (long)1,
+ pbuflen = vim_snprintf((char *)pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname);
+ if (!do_search(NULL, '/', '/', pbuf, pbuflen, (long)1,
search_options, NULL))
{
// Guess again: "^char * \<func ("
- sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
+ pbuflen = vim_snprintf((char *)pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
tagp.tagname);
- if (!do_search(NULL, '/', '/', pbuf, (long)1,
+ if (!do_search(NULL, '/', '/', pbuf, pbuflen, (long)1,
search_options, NULL))
found = 0;
}
diff --git a/src/terminal.c b/src/terminal.c
index 25a6a5d..648fc78 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -538,9 +538,16 @@ term_start(
split_ea.addr_count = 1;
}
+ int cmod_split_modified = FALSE;
if (vertical)
+ {
+ if (!(cmdmod.cmod_split & WSP_VERT))
+ cmod_split_modified = TRUE;
cmdmod.cmod_split |= WSP_VERT;
+ }
ex_splitview(&split_ea);
+ if (cmod_split_modified)
+ cmdmod.cmod_split &= ~WSP_VERT;
if (curwin == old_curwin)
{
// split failed
@@ -6164,8 +6171,16 @@ f_term_getjob(typval_T *argvars, typval_T *rettv)
buf = term_get_buf(argvars, "term_getjob()");
if (buf == NULL)
{
- rettv->v_type = VAR_SPECIAL;
- rettv->vval.v_number = VVAL_NULL;
+ if (in_vim9script())
+ {
+ rettv->v_type = VAR_JOB;
+ rettv->vval.v_job = NULL;
+ }
+ else
+ {
+ rettv->v_type = VAR_SPECIAL;
+ rettv->vval.v_number = VVAL_NULL;
+ }
return;
}
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index b41f5f4..e31d2b5 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -143,6 +143,7 @@ NEW_TESTS = \
test_file_perm \
test_file_size \
test_filechanged \
+ test_filecopy \
test_fileformat \
test_filetype \
test_filter_cmd \
@@ -278,6 +279,7 @@ NEW_TESTS = \
test_spell \
test_spell_utf8 \
test_spellfile \
+ test_spellrare \
test_startup \
test_startup_utf8 \
test_stat \
@@ -403,6 +405,7 @@ NEW_TESTS_RES = \
test_expr.res \
test_file_size.res \
test_filechanged.res \
+ test_filecopy.res \
test_fileformat.res \
test_filetype.res \
test_filter_cmd.res \
@@ -521,6 +524,7 @@ NEW_TESTS_RES = \
test_spell.res \
test_spell_utf8.res \
test_spellfile.res \
+ test_spellrare.res \
test_startup.res \
test_stat.res \
test_statusline.res \
diff --git a/src/testdir/dumps/Test_balloon_eval_term_03.dump b/src/testdir/dumps/Test_balloon_eval_term_03.dump
new file mode 100644
index 0000000..ccbe9d0
--- /dev/null
+++ b/src/testdir/dumps/Test_balloon_eval_term_03.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@38|e|n|o| |e|n|o| |e|n>o
+| @38|o|w|t| |o|X|t| |o|w|t
+| @27| +0#0000001#ffd7ff255@17|e+0#0000000#ffffff0|r|h|t
+| +0#4040ff13&@27| +0#0000001#ffd7ff255|:|6| |n|m|u|l|o|c| |2| |e|n|i|l| | +0#4040ff13#ffffff0@2|~
+| @27| +0#0000001#ffd7ff255@12|<|o|X|t| | +0#4040ff13#ffffff0@2|~
+| @27| +0#0000001#ffd7ff255@17| +0#4040ff13#ffffff0@2|~
+| @48|~
+| @48|~
+| @48|~
+|:+0#0000000&|c|a|l@1| |T|r|i|g@1|e|r|(|)| @16|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_mouse_popup_position_01.dump b/src/testdir/dumps/Test_mouse_popup_position_01.dump
new file mode 100644
index 0000000..54ba886
--- /dev/null
+++ b/src/testdir/dumps/Test_mouse_popup_position_01.dump
@@ -0,0 +1,20 @@
+|0+0&#ffffff0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| >1|8| |1|9|
+|~+0#4040ff13&| @31| +0#0000001#ffd7ff255|U|n|d|o| @11
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255@16
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255|P|a|s|t|e| @10
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255@16
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255|S|e|l|e|c|t| |W|o|r|d| @4
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255|S|e|l|e|c|t| |S|e|n|t|e|n|c|e|
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255|S|e|l|e|c|t| |P|a|r|a|g|r|a|p|h
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255|S|e|l|e|c|t| |L|i|n|e| @4
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255|S|e|l|e|c|t| |B|l|o|c|k| @3
+|~+0#4040ff13#ffffff0| @31| +0#0000001#ffd7ff255|S|e|l|e|c|t| |A|l@1| @5
+|~+0#4040ff13#ffffff0| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|:+0#0000000&|c|a|l@1| |T|r|i|g@1|e|r|(|4|5|)| @14|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_mouse_popup_position_02.dump b/src/testdir/dumps/Test_mouse_popup_position_02.dump
new file mode 100644
index 0000000..7dfab52
--- /dev/null
+++ b/src/testdir/dumps/Test_mouse_popup_position_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0|9|1| |8>1| |7|1| |6|1| |5|1| |4|1| |3|1| |2|1| |1@1| |0|1| |9| |8| |7| |6| |5| |4| |3| |2| |1| |0
+| +0#0000001#ffd7ff255@11|o|d|n|U| | +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255@16| +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255@10|e|t|s|a|P| | +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255@16| +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255@4|d|r|o|W| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255|e|c|n|e|t|n|e|S| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@31|~
+|h+0#0000001#ffd7ff255|p|a|r|g|a|r|a|P| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255@4|e|n|i|L| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255@3|k|c|o|l|B| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@31|~
+| +0#0000001#ffd7ff255@5|l@1|A| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@31|~
+| @48|~
+| @48|~
+| @48|~
+| @48|~
+| @48|~
+| @48|~
+| @48|~
+| @48|~
+|:+0#0000000&|c|a|l@1| |T|r|i|g@1|e|r|(|5|0| |+| |1| |-| |4|5|)| @5|1|,|4|5| @9|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_command_rl.dump b/src/testdir/dumps/Test_popup_command_rl.dump
new file mode 100644
index 0000000..b38ccd9
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_command_rl.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@51|e|v|i|f| |r|u|o|f| |e@1|r|h|t| |o|w|t| |e|n|o
+| @46|e|v|i|f| |r|u|o|f| |e@1|r|h|t>X| |o|w|t| |e|n|o| |d|n|a
+| @45| +0#0000001#ffd7ff255@12|o|d|n|U| |w+0#0000000#ffffff0|t| |e|r|o|m| |e|n|o
+| +0#4040ff13&@45| +0#0000001#ffd7ff255@17| +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255@11|e|t|s|a|P| | +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255@17| +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255@5|d|r|o|W| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255@1|e|c|n|e|t|n|e|S| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255|h|p|a|r|g|a|r|a|P| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255@5|e|n|i|L| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255@4|k|c|o|l|B| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@9|~
+| @45| +0#0000001#ffd7ff255@6|l@1|A| |t|c|e|l|e|S| | +0#4040ff13#ffffff0@9|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+|:+0#0000000&|p|o|p|u|p| |P|o|p|U|p| @62
diff --git a/src/testdir/dumps/Test_pum_highlights_03.dump b/src/testdir/dumps/Test_pum_highlights_03.dump
new file mode 100644
index 0000000..77d87d4
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_03.dump
@@ -0,0 +1,20 @@
+|f+0&#ffffff0|o> @72
+|f+0#00e0e07#e0e0e08|o|o+0#0000001&| @4|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|f|o@1| @1|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|r| @1|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|B|a|z| @1|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|l|a| |f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_04.dump b/src/testdir/dumps/Test_pum_highlights_04.dump
new file mode 100644
index 0000000..486a59e
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_04.dump
@@ -0,0 +1,20 @@
+|你*0&#ffffff0> +&@72
+|你*0#00e0e07#e0e0e08|好*0#0000001&| +&@10| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|好*0#0000001&|吗| +&@8| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|不*0#0000001&|好|吗| +&@6| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|可*0#0000001&|好|吗| +&@6| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_05.dump b/src/testdir/dumps/Test_pum_highlights_05.dump
new file mode 100644
index 0000000..a2ce2cf
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_05.dump
@@ -0,0 +1,20 @@
+|你*0&#ffffff0|吗> +&@70
+|你*0#00e0e07#e0e0e08|好*0#0000001&|吗*0#00e0e07&| +0#0000001&@8| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|不*0#0000001&|好|吗*0#0000e05&| +0#0000001&@6| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|可*0#0000001&|好|吗*0#0000e05&| +0#0000001&@6| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_06.dump b/src/testdir/dumps/Test_pum_highlights_06.dump
new file mode 100644
index 0000000..3eb1524
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_06.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@71> |o|f
+| +0#4040ff13&@58| +0#0000001#e0e0e08|d|n|i|k|o@1|f| @4|o|o+0#00e0e07&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| @1|o@1|f|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| @1|r|a|b|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| @1|z|a|B|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| |a|l|a|b|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_06a.dump b/src/testdir/dumps/Test_pum_highlights_06a.dump
new file mode 100644
index 0000000..5d51f11
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_06a.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@71> |你*&
+| +0#4040ff13&@59| +0#0000001#e0e0e08@10|好*&|你*0#00e0e07&
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@8|吗*&|好|你*0#0000e05&
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@6|吗*&|好|不|你*0#0000e05&
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@6|吗*&|好|可|你*0#0000e05&
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_06b.dump b/src/testdir/dumps/Test_pum_highlights_06b.dump
new file mode 100644
index 0000000..41314ab
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_06b.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@69> |吗*&|你
+| +0#4040ff13&@59| +0#0000001#e0e0e08@8|吗*0#00e0e07&|好*0#0000001&|你*0#00e0e07&
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@6|吗*0#0000e05&|好*0#0000001&|不|你*0#0000e05&
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@6|吗*0#0000e05&|好*0#0000001&|可|你*0#0000e05&
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_07.dump b/src/testdir/dumps/Test_pum_highlights_07.dump
new file mode 100644
index 0000000..77d87d4
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_07.dump
@@ -0,0 +1,20 @@
+|f+0&#ffffff0|o> @72
+|f+0#00e0e07#e0e0e08|o|o+0#0000001&| @4|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|f|o@1| @1|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|r| @1|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|B|a|z| @1|f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|l|a| |f|o@1|k|i|n|d| | +0#4040ff13#ffffff0@58
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_08.dump b/src/testdir/dumps/Test_pum_highlights_08.dump
new file mode 100644
index 0000000..3eb1524
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_08.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@71> |o|f
+| +0#4040ff13&@58| +0#0000001#e0e0e08|d|n|i|k|o@1|f| @4|o|o+0#00e0e07&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| @1|o@1|f|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| @1|r|a|b|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| @1|z|a|B|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@58| +0#0000001#ffd7ff255|d|n|i|k|o@1|f| |a|l|a|b|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |9| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_09.dump b/src/testdir/dumps/Test_pum_highlights_09.dump
new file mode 100644
index 0000000..3616c80
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_09.dump
@@ -0,0 +1,20 @@
+|f+0&#ffffff0> @73
+|f+0#00e0e07#e0e0e08|o+0#0000001&@1| @11| +0#4040ff13#ffffff0@59
+|F+0#0000e05#ffd7ff255|o+0#0000001&@1|b|a|r| @8| +0#4040ff13#ffffff0@59
+|f+0#0000e05#ffd7ff255|o+0#0000001&@1|B|a|z| @8| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@62
diff --git a/src/testdir/dumps/Test_smooth_long_6.dump b/src/testdir/dumps/Test_smooth_long_6.dump
index 507aa46..ba48c28 100644
--- a/src/testdir/dumps/Test_smooth_long_6.dump
+++ b/src/testdir/dumps/Test_smooth_long_6.dump
@@ -3,4 +3,4 @@
|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o
|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e
|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w
-|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|9|0| @9|6@1|%|
+| @21|3|,|9|0| @9|6@1|%|
diff --git a/src/testdir/dumps/Test_smooth_long_7.dump b/src/testdir/dumps/Test_smooth_long_7.dump
index 225207f..222e001 100644
--- a/src/testdir/dumps/Test_smooth_long_7.dump
+++ b/src/testdir/dumps/Test_smooth_long_7.dump
@@ -3,4 +3,4 @@
|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o
|f| |t|e|x|t| |w|i>t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e
|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w
-|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|1|7|0| @8|6@1|%|
+| @21|3|,|1|7|0| @8|6@1|%|
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_1.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_1.dump
new file mode 100644
index 0000000..6c1d223
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_1.dump
@@ -0,0 +1,8 @@
+| +0&#ffffff0@39
+@40
+@40
+> @39
+@40
+@40
+@40
+@40
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_2.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_2.dump
new file mode 100644
index 0000000..9162df0
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_2.dump
@@ -0,0 +1,8 @@
+|<+0#4040ff13#ffffff0@2|t+0#0000000&|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t
+|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l
+|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g|
+|t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o|
+>l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
+| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
+| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
+| @39
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_3.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_3.dump
new file mode 100644
index 0000000..1a1fcae
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_3.dump
@@ -0,0 +1,8 @@
+|<+0#4040ff13#ffffff0@2|l+0#0000000&|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l
+|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g|
+|t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o|
+|l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
+> |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
+| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
+|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
+@40
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_4.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_4.dump
new file mode 100644
index 0000000..4ed62b6
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_4.dump
@@ -0,0 +1,8 @@
+|<+0#4040ff13#ffffff0@2|l+0#0000000&|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l
+|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g|
+|t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o|
+|l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
+| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
+> |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
+|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
+@40
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_5.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_5.dump
new file mode 100644
index 0000000..6d7e157
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_5.dump
@@ -0,0 +1,8 @@
+|<+0#4040ff13#ffffff0@2|l+0#0000000&|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l
+|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g|
+|t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o|
+|l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
+| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
+| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
+>g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
+@40
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_6.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_6.dump
new file mode 100644
index 0000000..4f5dcea
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_6.dump
@@ -0,0 +1,8 @@
+|<+0#4040ff13#ffffff0@2| +0#0000000&|l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o|
+|l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
+| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
+| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
+|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
+>t|h|r|e@1| @34
+|f|o|u|r| @35
+@40
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_7.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_7.dump
new file mode 100644
index 0000000..c21c022
--- /dev/null
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_7.dump
@@ -0,0 +1,8 @@
+| +0&#ffffff0@39
+@40
+@40
+@40
+@40
+@40
+> @39
+@40
diff --git a/src/testdir/dumps/Test_smoothscroll_in_qf_window_1.dump b/src/testdir/dumps/Test_smoothscroll_in_qf_window_1.dump
new file mode 100644
index 0000000..efdec1e
--- /dev/null
+++ b/src/testdir/dumps/Test_smoothscroll_in_qf_window_1.dump
@@ -0,0 +1,20 @@
+> +0&#ffffff0@59
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|[+3#0000000&|N|o| |N|a|m|e|]| @50
+|<+0#4040ff13&@2| +0#af5f00255&|2+0#0000000&|1| |2@1| |2|3| |2|4| |2|5| |2|6| |2|7| |2|8| |2|9| @29
+| +0#af5f00255&|1|0| ||+0#0000000&@1| |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0|
+| +0#af5f00255&@3|2+0#0000000&|1| |2@1| |2|3| |2|4| |2|5| |2|6| |2|7| |2|8| |2|9| @29
+| +0#af5f00255&|1@1| ||+0#0000000&@1| |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0|
+| +0#af5f00255&@3|2+0#0000000&|1| |2@1| |2|3| |2|4| |2|5| |2|6| |2|7| |2|8| |2|9| @29
+|[+1&&|Q|u|i|c|k|f|i|x| |L|i|s|t|]| @44
+| +0&&@59
diff --git a/src/testdir/dumps/Test_smoothscroll_in_qf_window_2.dump b/src/testdir/dumps/Test_smoothscroll_in_qf_window_2.dump
new file mode 100644
index 0000000..200df91
--- /dev/null
+++ b/src/testdir/dumps/Test_smoothscroll_in_qf_window_2.dump
@@ -0,0 +1,20 @@
+> +0&#ffffff0@59
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|[+3#0000000&|N|o| |N|a|m|e|]| @50
+| +0#af5f00255&@1|1| | +0#0000000&@55
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|[+1#0000000&|Q|u|i|c|k|f|i|x| |L|i|s|t|]| @44
+|:+0&&|c|a|l@1| |s|e|t|q|f|l|i|s|t|(|[|]|,| |'|r|'|)| @35
diff --git a/src/testdir/dumps/Test_smoothscroll_in_qf_window_3.dump b/src/testdir/dumps/Test_smoothscroll_in_qf_window_3.dump
new file mode 100644
index 0000000..54b726f
--- /dev/null
+++ b/src/testdir/dumps/Test_smoothscroll_in_qf_window_3.dump
@@ -0,0 +1,20 @@
+> +0&#ffffff0@59
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|[+3#0000000&|N|o| |N|a|m|e|]| @50
+| +0#af5f00255&@1|1| ||+0#0000000#ffff4012@1| |f|o@1| @49
+| +0#af5f00255#ffffff0@1|2| ||+0#0000000&@1| |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0|
+| +0#af5f00255&@3|2+0#0000000&|1| |2@1| |2|3| |2|4| |2|5| |2|6| |2|7| |2|8| |2|9| @29
+| +0#af5f00255&@1|3| ||+0#0000000&@1| |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0|
+| +0#af5f00255&@3|2+0#0000000&|1| |2@1| |2|3| |2|4| |2|5| |2|6| |2|7| |2|8| |2|9| @29
+|[+1&&|Q|u|i|c|k|f|i|x| |L|i|s|t|]| @44
+|:+0&&|c|a|l@1| |s|e|t|q|f|l|i|s|t|(|g|:|l|,| |'|r|'|)| @34
diff --git a/src/testdir/dumps/Test_smoothscroll_in_qf_window_4.dump b/src/testdir/dumps/Test_smoothscroll_in_qf_window_4.dump
new file mode 100644
index 0000000..1a4cdd2
--- /dev/null
+++ b/src/testdir/dumps/Test_smoothscroll_in_qf_window_4.dump
@@ -0,0 +1,20 @@
+> +0&#ffffff0@59
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|[+3#0000000&|N|o| |N|a|m|e|]| @50
+| +0#af5f00255&@1|1| ||+0#0000000#ffff4012@1| |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0|
+| +0#af5f00255#ffffff0@3|2+0#0000000#ffff4012|1| |2@1| |2|3| |2|4| |2|5| |2|6| |2|7| |2|8| |2|9| |3|0| |3|1| |3|2| |3@1| |3|4| |3|5| |3|6| |3|7| |3|8| |3|9
+| +0#af5f00255#ffffff0@3| +0#0000000#ffff4012|4|0| |4|1| |4|2| |4|3| |4@1| |4|5| |4|6| |4|7| |4|8| |4|9| |5|0| |5|1| |5|2| |5|3| |5|4| |5@1| |5|6| |5|7| |5
+| +0#af5f00255#ffffff0@3|8+0#0000000#ffff4012| |5|9| |6|0| |6|1| |6|2| |6|3| |6|4| |6|5| |6@1| |6|7| |6|8| |6|9| |7|0| |7|1| |7|2| |7|3| |7|4| |7|5| |7|6|
+| +0#af5f00255#ffffff0@3|7+0#0000000#ffff4012@1| |7|8| |7|9| |8|0| |8|1| |8|2| |8|3| |8|4| |8|5| |8|6| |8|7| |8@1| |8|9| |9|0| |9|1| |9|2| |9|3| |9|4| |9|5
+|[+1&#ffffff0|Q|u|i|c|k|f|i|x| |L|i|s|t|]| @44
+|:+0&&|c|a|l@1| |s|e|t|q|f|l|i|s|t|(|g|:|l|1|,| |'|r|'|)| @33
diff --git a/src/testdir/dumps/Test_smoothscroll_in_qf_window_5.dump b/src/testdir/dumps/Test_smoothscroll_in_qf_window_5.dump
new file mode 100644
index 0000000..fcc2106
--- /dev/null
+++ b/src/testdir/dumps/Test_smoothscroll_in_qf_window_5.dump
@@ -0,0 +1,20 @@
+> +0&#ffffff0@59
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|[+3#0000000&|N|o| |N|a|m|e|]| @50
+|<+0#4040ff13&@2| +0#af5f00255&| +0#0000000#ffff4012|9|3|7| |9|3|8| |9|3|9| |9|4|0| |9|4|1| |9|4|2| |9|4|3| |9|4@1| |9|4|5| |9|4|6| |9|4|7| |9|4|8| |9|4|9| |9|5|0
+| +0#af5f00255#ffffff0@3| +0#0000000#ffff4012|9|5|1| |9|5|2| |9|5|3| |9|5|4| |9|5@1| |9|5|6| |9|5|7| |9|5|8| |9|5|9| |9|6|0| |9|6|1| |9|6|2| |9|6|3| |9|6|4
+| +0#af5f00255#ffffff0@3| +0#0000000#ffff4012|9|6|5| |9|6@1| |9|6|7| |9|6|8| |9|6|9| |9|7|0| |9|7|1| |9|7|2| |9|7|3| |9|7|4| |9|7|5| |9|7|6| |9|7@1| |9|7|8
+| +0#af5f00255#ffffff0@3| +0#0000000#ffff4012|9|7|9| |9|8|0| |9|8|1| |9|8|2| |9|8|3| |9|8|4| |9|8|5| |9|8|6| |9|8|7| |9|8@1| |9|8|9| |9@1|0| |9@1|1| |9@1|2
+| +0#af5f00255#ffffff0@3| +0#0000000#ffff4012|9@1|3| |9@1|4| |9@1|5| |9@1|6| |9@1|7| |9@1|8| |9@2| @27
+|[+1&#ffffff0|Q|u|i|c|k|f|i|x| |L|i|s|t|]| @44
+|:+0&&|c|a|l@1| |s|e|t|q|f|l|i|s|t|(|g|:|l|1|,| |'|r|'|)| @33
diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_1.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_1.dump
new file mode 100644
index 0000000..0772682
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_hl_match_1.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@49
+|~+0#4040ff13&| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @3| +0#0000001#e0e0e08|p+0#00e0e07&|l|a+0#0000001&|c+0#00e0e07&|e+0#0000001&| @9| +0#4040ff13#ffffff0@28
+|~| @3| +0#0000001#ffd7ff255|u|n|p+0#0000e05&|l|a+0#0000001&|c+0#0000e05&|e+0#0000001&| @7| +0#4040ff13#ffffff0@28
+|:+0#0000000&|s|i|g|n| |p|l|a|c|e> @38
diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_2.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_2.dump
new file mode 100644
index 0000000..ec781ef
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_hl_match_2.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@49
+|~+0#4040ff13&| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @3| +0#0000001#ffd7ff255|p+0#0000e05&|l|a+0#0000001&|c+0#0000e05&|e+0#0000001&| @9| +0#4040ff13#ffffff0@28
+|~| @3| +0#0000001#e0e0e08|u|n|p+0#00e0e07&|l|a+0#0000001&|c+0#00e0e07&|e+0#0000001&| @7| +0#4040ff13#ffffff0@28
+|:+0#0000000&|s|i|g|n| |u|n|p|l|a|c|e> @36
diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_3.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_3.dump
new file mode 100644
index 0000000..afb792a
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_hl_match_3.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@49
+|~+0#4040ff13&| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @3| +0#0000001#ffd7ff255|p+0#0000e05&|l|a+0#0000001&|c+0#0000e05&|e+0#0000001&| @9| +0#4040ff13#ffffff0@28
+|~| @3| +0#0000001#ffd7ff255|u|n|p+0#0000e05&|l|a+0#0000001&|c+0#0000e05&|e+0#0000001&| @7| +0#4040ff13#ffffff0@28
+|:+0#0000000&|s|i|g|n| |p|l|c> @40
diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_4.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_4.dump
new file mode 100644
index 0000000..0be8053
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_hl_match_4.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@49
+|~+0#4040ff13&| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @3| +0#0000001#e0e0e08|u+0#00e0e07&|n|d+0#0000001&|e|f|i|n|e| @6| +0#4040ff13#ffffff0@28
+|~| @3| +0#0000001#ffd7ff255|u+0#0000e05&|n|p+0#0000001&|l|a|c|e| @7| +0#4040ff13#ffffff0@28
+|:+0#0000000&|s|i|g|n| |u|n|d|e|f|i|n|e> @35
diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_5.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_5.dump
new file mode 100644
index 0000000..7453cb9
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_hl_match_5.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@49
+|~+0#4040ff13&| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @3| +0#0000001#ffd7ff255|u+0#0000e05&|n|d+0#0000001&|e|f|i|n|e| @6| +0#4040ff13#ffffff0@28
+|~| @3| +0#0000001#e0e0e08|u+0#00e0e07&|n|p+0#0000001&|l|a|c|e| @7| +0#4040ff13#ffffff0@28
+|:+0#0000000&|s|i|g|n| |u|n|p|l|a|c|e> @36
diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_6.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_6.dump
new file mode 100644
index 0000000..8345007
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_hl_match_6.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@49
+|~+0#4040ff13&| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @48
+|~| @3| +0#0000001#ffd7ff255|u+0#0000e05&|n|d+0#0000001&|e|f|i|n|e| @6| +0#4040ff13#ffffff0@28
+|~| @3| +0#0000001#ffd7ff255|u+0#0000e05&|n|p+0#0000001&|l|a|c|e| @7| +0#4040ff13#ffffff0@28
+|:+0#0000000&|s|i|g|n| |u|n> @41
diff --git a/src/testdir/dumps/Test_wildmenu_pum_rl.dump b/src/testdir/dumps/Test_wildmenu_pum_rl.dump
new file mode 100644
index 0000000..55db4ca
--- /dev/null
+++ b/src/testdir/dumps/Test_wildmenu_pum_rl.dump
@@ -0,0 +1,10 @@
+| +0&#ffffff0@49
+| +0#4040ff13&@48|~
+| @48|~
+| @4| +0#0000001#e0e0e08|d|e|f|i|n|e| @8| +0#4040ff13#ffffff0@27|~
+| @4| +0#0000001#ffd7ff255|j|u|m|p| @10| +0#4040ff13#ffffff0@27|~
+| @4| +0#0000001#ffd7ff255|l|i|s|t| @10| +0#4040ff13#ffffff0@27|~
+| @4| +0#0000001#ffd7ff255|p|l|a|c|e| @9| +0#4040ff13#ffffff0@27|~
+| @4| +0#0000001#ffd7ff255|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@27|~
+| @4| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@27|~
+|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e> @37
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index a195bca..8cca2b9 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -76,7 +76,7 @@ let test_values = {
\ 'clipboard': [['', 'unnamed', 'autoselect,unnamed', 'html', 'exclude:vimdisplay'], ['xxx', '\ze*', 'exclude:\\%(']],
\ 'colorcolumn': [['', '8', '+2'], ['xxx']],
\ 'comments': [['', 'b:#'], ['xxx']],
- \ 'commentstring': [['', '/*%s*/'], ['xxx']],
+ \ 'commentstring': [['', '/*\ %s\ */'], ['xxx']],
\ 'complete': [['', 'w,b'], ['xxx']],
\ 'concealcursor': [['', 'n', 'nvic'], ['xxx']],
\ 'completeopt': [['', 'menu', 'menu,longest'], ['xxx', 'menu,,,longest,']],
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 24e1daf..c9f257a 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -4024,6 +4024,32 @@ func Test_autocmd_get()
\ event: 'BufAdd', pattern: '*.abc'}))
call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns',
\ event: 'BufWipeout'}))
+
+ " Test for getting autocmds after removing one inside an autocmd
+ func CheckAutocmdGet()
+ augroup TestAutoCmdFns
+ autocmd! BufAdd *.vim
+ augroup END
+
+ let expected = [
+ \ #{cmd: 'echo "bufadd-py"', group: 'TestAutoCmdFns',
+ \ pattern: '*.py', nested: v:false, once: v:false,
+ \ event: 'BufAdd'},
+ \ #{cmd: 'echo "bufhidden"', group: 'TestAutoCmdFns',
+ \ pattern: '*.vim', nested: v:false,
+ \ once: v:false, event: 'BufHidden'}]
+
+ call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'}))
+ call assert_equal([expected[0]],
+ \ autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.py'}))
+ call assert_equal([expected[1]],
+ \ autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.vim'}))
+ endfunc
+
+ autocmd User Xauget call CheckAutocmdGet()
+ doautocmd User Xauget
+ autocmd! User Xauget
+
call assert_fails("call autocmd_get(#{group: 'abc', event: 'BufAdd'})",
\ 'E367:')
let cmd = "echo autocmd_get(#{group: 'TestAutoCmdFns', event: 'abc'})"
diff --git a/src/testdir/test_autoload.vim b/src/testdir/test_autoload.vim
index 835b81e..d0f9136 100644
--- a/src/testdir/test_autoload.vim
+++ b/src/testdir/test_autoload.vim
@@ -26,5 +26,4 @@ func Test_autoload_vim9script()
call assert_equal(49, auto9#Add42(7))
endfunc
-
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_balloon.vim b/src/testdir/test_balloon.vim
index 5e84f9e..80d5831 100644
--- a/src/testdir/test_balloon.vim
+++ b/src/testdir/test_balloon.vim
@@ -64,4 +64,29 @@ func Test_balloon_eval_term_visual()
call StopVimInTerminal(buf)
endfunc
+func Test_balloon_eval_term_rightleft()
+ CheckFeature rightleft
+
+ " Use <Ignore> after <MouseMove> to return from vgetc() without removing
+ " the balloon.
+ let xtra_lines =<< trim [CODE]
+ set rightleft
+ func Trigger()
+ call test_setmouse(2, 50 + 1 - 6)
+ call feedkeys("\<MouseMove>\<Ignore>", "xt")
+ endfunc
+ [CODE]
+ call writefile(s:common_script + xtra_lines, 'XTest_beval_rl', 'D')
+
+ " Check that the balloon shows up after a mouse move
+ let buf = RunVimInTerminal('-S XTest_beval_rl', {'rows': 10, 'cols': 50})
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, 'll')
+ call term_sendkeys(buf, ":call Trigger()\<CR>")
+ call VerifyScreenDump(buf, 'Test_balloon_eval_term_03', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_blob.vim b/src/testdir/test_blob.vim
index cccecb7..f0e8209 100644
--- a/src/testdir/test_blob.vim
+++ b/src/testdir/test_blob.vim
@@ -74,6 +74,13 @@ func Test_blob_assign()
VAR l = [0z12]
VAR m = deepcopy(l)
LET m[0] = 0z34 #" E742 or E741 should not occur.
+
+ VAR blob1 = 0z10
+ LET blob1 += test_null_blob()
+ call assert_equal(0z10, blob1)
+ LET blob1 = test_null_blob()
+ LET blob1 += 0z20
+ call assert_equal(0z20, blob1)
END
call v9.CheckLegacyAndVim9Success(lines)
@@ -97,6 +104,18 @@ func Test_blob_assign()
let lines =<< trim END
VAR b = 0zDEADBEEF
+ LET b[0 : 1] = 0x1122
+ END
+ call v9.CheckLegacyAndVim9Failure(lines, ['E709:', 'E1012:', 'E709:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b[0] = 0z11
+ END
+ call v9.CheckLegacyAndVim9Failure(lines, ['E974:', 'E974:', 'E1012:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
LET b ..= 0z33
END
call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1019:', 'E734:'])
@@ -331,6 +350,17 @@ func Test_blob_for_loop()
call assert_equal(5, i)
END
call v9.CheckLegacyAndVim9Success(lines)
+
+ " Test for skipping the loop var assignment in a for loop
+ let lines =<< trim END
+ VAR blob = 0z998877
+ VAR c = 0
+ for _ in blob
+ LET c += 1
+ endfor
+ call assert_equal(3, c)
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
endfunc
func Test_blob_concatenate()
@@ -819,6 +849,7 @@ func Test_indexof()
call assert_equal(-1, indexof(test_null_blob(), "v:val == 0xde"))
call assert_equal(-1, indexof(b, test_null_string()))
call assert_equal(-1, indexof(b, test_null_function()))
+ call assert_equal(-1, indexof(b, ""))
let b = 0z01020102
call assert_equal(1, indexof(b, "v:val == 0x02", #{startidx: 0}))
@@ -830,6 +861,7 @@ func Test_indexof()
" failure cases
call assert_fails('let i = indexof(b, "val == 0xde")', 'E121:')
call assert_fails('let i = indexof(b, {})', 'E1256:')
+ call assert_fails('let i = indexof(b, " ")', 'E15:')
endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index ed8f89d..8b7489e 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -2741,6 +2741,55 @@ func Test_wildmenu_pum_odd_wildchar()
call StopVimInTerminal(buf)
endfunc
+" Test that 'rightleft' should not affect cmdline completion popup menu.
+func Test_wildmenu_pum_rightleft()
+ CheckFeature rightleft
+ CheckScreendump
+
+ let lines =<< trim END
+ set wildoptions=pum
+ set rightleft
+ END
+ call writefile(lines, 'Xwildmenu_pum_rl', 'D')
+ let buf = RunVimInTerminal('-S Xwildmenu_pum_rl', #{rows: 10, cols: 50})
+
+ call term_sendkeys(buf, ":sign \<Tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_rl', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
+" Test highlighting matched text in cmdline completion popup menu.
+func Test_wildmenu_pum_hl_match()
+ CheckScreendump
+
+ let lines =<< trim END
+ set wildoptions=pum,fuzzy
+ hi PmenuMatchSel ctermfg=6 ctermbg=7
+ hi PmenuMatch ctermfg=4 ctermbg=225
+ END
+ call writefile(lines, 'Xwildmenu_pum_hl', 'D')
+ let buf = RunVimInTerminal('-S Xwildmenu_pum_hl', #{rows: 10, cols: 50})
+
+ call term_sendkeys(buf, ":sign plc\<Tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_1', {})
+ call term_sendkeys(buf, "\<Tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_2', {})
+ call term_sendkeys(buf, "\<Tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_3', {})
+ call term_sendkeys(buf, "\<Esc>:set wildoptions-=fuzzy\<CR>")
+ call TermWait(buf)
+ call term_sendkeys(buf, ":sign un\<Tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_4', {})
+ call term_sendkeys(buf, "\<Tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_5', {})
+ call term_sendkeys(buf, "\<Tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_6', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call StopVimInTerminal(buf)
+endfunc
+
" Test for completion after a :substitute command followed by a pipe (|)
" character
func Test_cmdline_complete_substitute()
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
index 789e44c..1665330 100644
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -1952,6 +1952,11 @@ func Test_edit_insert_reg()
let @r = 'sample'
call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
call assert_equal('"', g:Line)
+
+ " Test for inserting an null and an empty list
+ call feedkeys("a\<C-R>=test_null_list()\<CR>", "xt")
+ call feedkeys("a\<C-R>=[]\<CR>", "xt")
+ call assert_equal(['r'], getbufline('', 1, '$'))
call test_override('ALL', 0)
close!
endfunc
diff --git a/src/testdir/test_filecopy.vim b/src/testdir/test_filecopy.vim
new file mode 100644
index 0000000..b526dce
--- /dev/null
+++ b/src/testdir/test_filecopy.vim
@@ -0,0 +1,72 @@
+" Test filecopy()
+
+source check.vim
+source shared.vim
+
+func Test_copy_file_to_file()
+ call writefile(['foo'], 'Xcopy1')
+
+ call assert_true(filecopy('Xcopy1', 'Xcopy2'))
+
+ call assert_equal(['foo'], readfile('Xcopy2'))
+
+ " When the destination file already exists, it should not be overwritten.
+ call writefile(['foo'], 'Xcopy1')
+ call writefile(['bar'], 'Xcopy2', 'D')
+ call assert_false(filecopy('Xcopy1', 'Xcopy2'))
+ call assert_equal(['bar'], readfile('Xcopy2'))
+
+ call delete('Xcopy2')
+ call delete('Xcopy1')
+endfunc
+
+func Test_copy_symbolic_link()
+ CheckUnix
+
+ call writefile(['text'], 'Xtestfile', 'D')
+ silent !ln -s -f Xtestfile Xtestlink
+
+ call assert_true(filecopy('Xtestlink', 'Xtestlink2'))
+ call assert_equal('link', getftype('Xtestlink2'))
+ call assert_equal(['text'], readfile('Xtestlink2'))
+
+ " When the destination file already exists, it should not be overwritten.
+ call assert_false(filecopy('Xtestlink', 'Xtestlink2'))
+
+ call delete('Xtestlink2')
+ call delete('Xtestlink')
+ call delete('Xtestfile')
+endfunc
+
+func Test_copy_dir_to_dir()
+ call mkdir('Xcopydir1')
+ call writefile(['foo'], 'Xcopydir1/Xfilecopy')
+ call mkdir('Xcopydir2')
+
+ " Directory copy is not supported
+ call assert_false(filecopy('Xcopydir1', 'Xcopydir2'))
+
+ call delete('Xcopydir2', 'rf')
+ call delete('Xcopydir1', 'rf')
+endfunc
+
+func Test_copy_fails()
+ CheckUnix
+
+ call writefile(['foo'], 'Xfilecopy', 'D')
+
+ " Can't copy into a non-existing directory.
+ call assert_false(filecopy('Xfilecopy', 'Xdoesnotexist/Xfilecopy'))
+
+ " Can't copy a non-existing file.
+ call assert_false(filecopy('Xdoesnotexist', 'Xfilecopy2'))
+ call assert_equal('', glob('Xfilecopy2'))
+
+ " Can't copy to en empty file name.
+ call assert_false(filecopy('Xfilecopy', ''))
+
+ call assert_fails('call filecopy("Xfilecopy", [])', 'E1174:')
+ call assert_fails('call filecopy(0z, "Xfilecopy")', 'E1174:')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim
index f8fe9ec..d0a078f 100644
--- a/src/testdir/test_filetype.vim
+++ b/src/testdir/test_filetype.vim
@@ -131,7 +131,7 @@ def s:GetFilenameChecks(): dict<list<string>>
bst: ['file.bst'],
bzl: ['file.bazel', 'file.bzl', 'WORKSPACE', 'WORKSPACE.bzlmod'],
bzr: ['bzr_log.any', 'bzr_log.file'],
- c: ['enlightenment/file.cfg', 'file.qc', 'file.c', 'some-enlightenment/file.cfg'],
+ c: ['enlightenment/file.cfg', 'file.qc', 'file.c', 'some-enlightenment/file.cfg', 'file.mdh', 'file.epro'],
cabal: ['file.cabal'],
cabalconfig: ['cabal.config', expand("$HOME/.config/cabal/config")] + WhenConfigHome('$XDG_CONFIG_HOME/cabal/config'),
cabalproject: ['cabal.project', 'cabal.project.local'],
@@ -336,6 +336,7 @@ def s:GetFilenameChecks(): dict<list<string>>
htmlm4: ['file.html.m4'],
httest: ['file.htt', 'file.htb'],
hurl: ['file.hurl'],
+ hyprlang: ['hyprlock.conf', 'hyprland.conf', 'hypridle.conf', 'hyprpaper.conf'],
i3config: ['/home/user/.i3/config', '/home/user/.config/i3/config', '/etc/i3/config', '/etc/xdg/i3/config'],
ibasic: ['file.iba', 'file.ibi'],
icemenu: ['/.icewm/menu', 'any/.icewm/menu'],
@@ -344,6 +345,7 @@ def s:GetFilenameChecks(): dict<list<string>>
inform: ['file.inf', 'file.INF'],
initng: ['/etc/initng/any/file.i', 'file.ii', 'any/etc/initng/any/file.i'],
inittab: ['inittab'],
+ inko: ['file.inko'],
ipfilter: ['ipf.conf', 'ipf6.conf', 'ipf.rules'],
iss: ['file.iss'],
ist: ['file.ist', 'file.mst'],
@@ -358,10 +360,11 @@ def s:GetFilenameChecks(): dict<list<string>>
javascriptreact: ['file.jsx'],
jess: ['file.clp'],
jgraph: ['file.jgr'],
+ jj: ['file.jjdescription'],
jq: ['file.jq'],
jovial: ['file.jov', 'file.j73', 'file.jovial'],
jproperties: ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file', 'org.eclipse.xyz.prefs'],
- json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings', '.prettierrc', '.firebaserc', '.stylelintrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', 'file.bd', 'file.bda', 'file.xci', 'flake.lock'],
+ json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings', '.prettierrc', '.firebaserc', '.stylelintrc', '.lintstagedrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', 'file.bd', 'file.bda', 'file.xci', 'flake.lock'],
json5: ['file.json5'],
jsonc: ['file.jsonc', '.babelrc', '.eslintrc', '.jsfmtrc', '.jshintrc', '.jscsrc', '.vsconfig', '.hintrc', '.swrc', 'jsconfig.json', 'tsconfig.json', 'tsconfig.test.json', 'tsconfig-test.json', '.luaurc'],
jsonl: ['file.jsonl'],
@@ -417,7 +420,7 @@ def s:GetFilenameChecks(): dict<list<string>>
mail: ['snd.123', '.letter', '.letter.123', '.followup', '.article', '.article.123', 'pico.123', 'mutt-xx-xxx', 'muttng-xx-xxx', 'ae123.txt', 'file.eml', 'reportbug-file'],
mailaliases: ['/etc/mail/aliases', '/etc/aliases', 'any/etc/aliases', 'any/etc/mail/aliases'],
mailcap: ['.mailcap', 'mailcap'],
- make: ['file.mk', 'file.mak', 'file.dsp', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile'],
+ make: ['file.mk', 'file.mak', 'file.dsp', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile', 'Kbuild'],
mallard: ['file.page'],
man: ['file.man'],
manconf: ['/etc/man.conf', 'man.config', 'any/etc/man.conf'],
@@ -574,6 +577,7 @@ def s:GetFilenameChecks(): dict<list<string>>
psl: ['file.psl'],
pug: ['file.pug'],
puppet: ['file.pp'],
+ purescript: ['file.purs'],
pymanifest: ['MANIFEST.in'],
pyret: ['file.arr'],
pyrex: ['file.pyx', 'file.pxd'],
@@ -588,6 +592,7 @@ def s:GetFilenameChecks(): dict<list<string>>
radiance: ['file.rad', 'file.mat'],
raku: ['file.pm6', 'file.p6', 'file.t6', 'file.pod6', 'file.raku', 'file.rakumod', 'file.rakudoc', 'file.rakutest'],
raml: ['file.raml'],
+ rasi: ['file.rasi'],
ratpoison: ['.ratpoisonrc', 'ratpoisonrc'],
rbs: ['file.rbs'],
rc: ['file.rc', 'file.rch'],
@@ -640,7 +645,7 @@ def s:GetFilenameChecks(): dict<list<string>>
sh: ['.bashrc', '.bash_profile', '.bash-profile', '.bash_logout', '.bash-logout', '.bash_aliases', '.bash-aliases', '.bash_history', '.bash-history',
'/tmp/bash-fc-3Ozjlw', '/tmp/bash-fc.3Ozjlw', 'PKGBUILD', 'APKBUILD', 'file.bash', '/usr/share/doc/bash-completion/filter.sh',
'/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf', 'file.bats', '.ash_history', 'any/etc/neofetch/config.conf', '.xprofile',
- 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf'],
+ 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf', 'file.mdd', 'file.cygport'],
sieve: ['file.siv', 'file.sieve'],
sil: ['file.sil'],
simula: ['file.sim'],
@@ -651,6 +656,7 @@ def s:GetFilenameChecks(): dict<list<string>>
slang: ['file.sl'],
sage: ['file.sage'],
slice: ['file.ice'],
+ slint: ['file.slint'],
slpconf: ['/etc/slp.conf', 'any/etc/slp.conf'],
slpreg: ['/etc/slp.reg', 'any/etc/slp.reg'],
slpspi: ['/etc/slp.spi', 'any/etc/slp.spi'],
@@ -663,6 +669,7 @@ def s:GetFilenameChecks(): dict<list<string>>
smith: ['file.smt', 'file.smith'],
smithy: ['file.smithy'],
sml: ['file.sml'],
+ snakemake: ['file.smk', 'Snakefile'],
snobol4: ['file.sno', 'file.spt'],
solidity: ['file.sol'],
solution: ['file.sln'],
@@ -686,6 +693,7 @@ def s:GetFilenameChecks(): dict<list<string>>
starlark: ['file.ipd', 'file.star', 'file.starlark'],
stata: ['file.ado', 'file.do', 'file.imata', 'file.mata'],
stp: ['file.stp'],
+ stylus: ['a.styl', 'file.stylus'],
sudoers: ['any/etc/sudoers', 'sudoers.tmp', '/etc/sudoers', 'any/etc/sudoers.d/file'],
supercollider: ['file.quark'],
surface: ['file.sface'],
@@ -746,11 +754,12 @@ def s:GetFilenameChecks(): dict<list<string>>
tcl: ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc', '.tclsh-history', '.xsctcmdhistory', '.xsdbcmdhistory'],
tablegen: ['file.td'],
teal: ['file.tl'],
+ templ: ['file.templ'],
template: ['file.tmpl'],
teraterm: ['file.ttl'],
terminfo: ['file.ti'],
'terraform-vars': ['file.tfvars'],
- tex: ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl', 'any/.texlive/texmf-config/tex/latex/file/file.cfg', 'file.pgf', 'file.nlo', 'file.nls', 'file.out', 'file.thm', 'file.eps_tex', 'file.pygtex', 'file.pygstyle', 'file.clo', 'file.aux', 'file.brf', 'file.ind', 'file.lof', 'file.loe', 'file.nav', 'file.vrb', 'file.ins', 'file.tikz', 'file.bbx', 'file.cbx', 'file.beamer'],
+ tex: ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl', 'any/.texlive/texmf-config/tex/latex/file/file.cfg', 'file.pgf', 'file.nlo', 'file.nls', 'file.thm', 'file.eps_tex', 'file.pygtex', 'file.pygstyle', 'file.clo', 'file.aux', 'file.brf', 'file.ind', 'file.lof', 'file.loe', 'file.nav', 'file.vrb', 'file.ins', 'file.tikz', 'file.bbx', 'file.cbx', 'file.beamer'],
texinfo: ['file.texinfo', 'file.texi', 'file.txi'],
texmf: ['texmf.cnf'],
text: ['file.text', 'file.txt', 'README', 'LICENSE', 'COPYING', 'AUTHORS', '/usr/share/doc/bash-completion/AUTHORS', '/etc/apt/apt.conf.d/README', '/etc/Muttrc.d/README'],
@@ -985,6 +994,7 @@ def s:GetScriptChecks(): dict<list<list<string>>>
['#!/path/regina']],
janet: [['#!/path/janet']],
dart: [['#!/path/dart']],
+ vim: [['#!/path/vim']],
}
enddef
@@ -1506,6 +1516,41 @@ func Test_git_file()
filetype off
endfunc
+func Test_haredoc_file()
+ filetype on
+ call assert_true(mkdir('foo/bar', 'pR'))
+
+ call writefile([], 'README', 'D')
+ split README
+ call assert_notequal('haredoc', &filetype)
+ bwipe!
+
+ let g:filetype_haredoc = 1
+ split README
+ call assert_notequal('haredoc', &filetype)
+ bwipe!
+
+ call writefile([], 'foo/quux.ha')
+ split README
+ call assert_equal('haredoc', &filetype)
+ bwipe!
+ call delete('foo/quux.ha')
+
+ call writefile([], 'foo/bar/baz.ha', 'D')
+ split README
+ call assert_notequal('haredoc', &filetype)
+ bwipe!
+
+ let g:haredoc_search_depth = 2
+ split README
+ call assert_equal('haredoc', &filetype)
+ bwipe!
+ unlet g:filetype_haredoc
+ unlet g:haredoc_search_depth
+
+ filetype off
+endfunc
+
func Test_hook_file()
filetype on
@@ -1684,14 +1729,14 @@ func Test_mod_file()
call assert_equal('pim', b:modula2.dialect)
bwipe!
- " Modula-2 program MODULE with priorty (and uppercase extension)
+ " Modula-2 program MODULE with priority (and uppercase extension)
call writefile(['MODULE Module2Mod [42];'], 'Xfile.MOD')
split Xfile.MOD
call assert_equal('modula2', &filetype)
call assert_equal('pim', b:modula2.dialect)
bwipe!
- " Modula-2 implementation MODULE with priorty (and uppercase extension)
+ " Modula-2 implementation MODULE with priority (and uppercase extension)
call writefile(['IMPLEMENTATION MODULE Module2Mod [42];'], 'Xfile.MOD')
split Xfile.MOD
call assert_equal('modula2', &filetype)
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
index 3c78e62..dedc4a2 100644
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -8,7 +8,73 @@ func PrepIndent(arg)
return [a:arg] + repeat(["\t".a:arg], 5)
endfu
-func Test_address_fold()
+func Test_address_fold_new_default_commentstring()
+ " Test with the new commentstring defaults, that includes padding after v9.1.464
+ new
+ call setline(1, ['int FuncName() {/* {{{ */', 1, 2, 3, 4, 5, '}/* }}} */',
+ \ 'after fold 1', 'after fold 2', 'after fold 3'])
+ setl fen fdm=marker
+ " The next commands should all copy the same part of the buffer,
+ " regardless of the addressing type, since the part to be copied
+ " is folded away
+ :1y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+ :.y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+ :.+y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+ :.,.y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+ :sil .1,.y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .+,.y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+ :,y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+ :,+y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */','after fold 1'], getreg(0,1,1))
+ " using .+3 as second address should c opy the whole folded line + the next 3
+ " lines
+ :.,+3y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */',
+ \ 'after fold 1', 'after fold 2' , 'after fold 3'], getreg(0,1,1))
+ :sil .,-2y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3', '4', '5', '}/* }}} */'], getreg(0,1,1))
+
+ " now test again with folding disabled
+ set nofoldenable
+ :1y
+ call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
+ :.y
+ call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
+ :.+y
+ call assert_equal(['1'], getreg(0,1,1) )
+ :.,.y
+ call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .1,.y
+ call assert_equal(['int FuncName() {/* {{{ */', '1'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .+,.y
+ call assert_equal(['int FuncName() {/* {{{ */', '1'], getreg(0,1,1))
+ :,y
+ call assert_equal(['int FuncName() {/* {{{ */'], getreg(0,1,1))
+ :,+y
+ call assert_equal(['int FuncName() {/* {{{ */', '1'], getreg(0,1,1))
+ " using .+3 as second address should c opy the whole folded line + the next 3
+ " lines
+ :.,+3y
+ call assert_equal(['int FuncName() {/* {{{ */', '1', '2', '3'], getreg(0,1,1))
+ :7
+ :sil .,-2y
+ call assert_equal(['4', '5', '}/* }}} */'], getreg(0,1,1))
+
+ quit!
+endfunc
+
+func Test_address_fold_old_default_commentstring()
+ " Test with the old commentstring defaults, before v9.1.464
new
call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
\ 'after fold 1', 'after fold 2', 'after fold 3'])
@@ -719,7 +785,7 @@ func Test_fold_create_marker_in_C()
call append(0, content)
call cursor(c + 1, 1)
norm! zfG
- call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1))
+ call assert_equal(content[c] . (c < 4 ? '{{{' : '/* {{{ */'), getline(c + 1))
endfor
set fdm& fdl&
@@ -1601,6 +1667,63 @@ func Test_foldtext_scriptlocal_func()
delfunc s:FoldText
endfunc
+" Test for setting 'foldtext' from the modeline and executing the expression
+" in a sandbox
+func Test_foldtext_in_modeline()
+ func ModelineFoldText()
+ call feedkeys('aFoo', 'xt')
+ return "folded text"
+ endfunc
+ let lines =<< trim END
+ func T()
+ let i = 1
+ endfunc
+ " vim: foldenable foldtext=ModelineFoldText()
+ END
+ call writefile(lines, 'Xmodelinefoldtext', 'D')
+
+ set modeline modelineexpr
+ split Xmodelinefoldtext
+
+ call cursor(1, 1)
+ normal! zf3j
+ call assert_equal('folded text', foldtextresult(1))
+ call assert_equal(lines, getbufline('', 1, '$'))
+
+ bw!
+ set modeline& modelineexpr&
+ delfunc ModelineFoldText
+endfunc
+
+" Test for setting 'foldexpr' from the modeline and executing the expression
+" in a sandbox
+func Test_foldexpr_in_modeline()
+ func ModelineFoldExpr()
+ call feedkeys('aFoo', 'xt')
+ return strlen(matchstr(getline(v:lnum),'^\s*'))
+ endfunc
+ let lines =<< trim END
+ aaa
+ bbb
+ ccc
+ ccc
+ bbb
+ aaa
+ " vim: foldenable foldmethod=expr foldexpr=ModelineFoldExpr()
+ END
+ call writefile(lines, 'Xmodelinefoldexpr', 'D')
+
+ set modeline modelineexpr
+ split Xmodelinefoldexpr
+
+ call assert_equal(2, foldlevel(3))
+ call assert_equal(lines, getbufline('', 1, '$'))
+
+ bw!
+ set modeline& modelineexpr&
+ delfunc ModelineFoldExpr
+endfunc
+
" Make sure a fold containing a nested fold is split correctly when using
" foldmethod=indent
func Test_fold_split()
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index f0d7385..acdb954 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -3697,6 +3697,73 @@ func Test_getmousepos()
\ column: 8,
\ coladd: 21,
\ }, getmousepos())
+
+ 30vnew
+ setlocal smoothscroll number
+ call setline(1, join(range(100)))
+ exe "normal! \<C-E>"
+ call test_setmouse(1, 5)
+ call assert_equal(#{
+ \ screenrow: 1,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 1,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 27,
+ \ coladd: 0,
+ \ }, getmousepos())
+ call test_setmouse(2, 5)
+ call assert_equal(#{
+ \ screenrow: 2,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 2,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 53,
+ \ coladd: 0,
+ \ }, getmousepos())
+
+ exe "normal! \<C-E>"
+ call test_setmouse(1, 5)
+ call assert_equal(#{
+ \ screenrow: 1,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 1,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 53,
+ \ coladd: 0,
+ \ }, getmousepos())
+ call test_setmouse(2, 5)
+ call assert_equal(#{
+ \ screenrow: 2,
+ \ screencol: 5,
+ \ winid: win_getid(),
+ \ winrow: 2,
+ \ wincol: 5,
+ \ line: 1,
+ \ column: 79,
+ \ coladd: 0,
+ \ }, getmousepos())
+
+ vert resize 4
+ call test_setmouse(2, 2)
+ " This used to crash Vim
+ call assert_equal(#{
+ \ screenrow: 2,
+ \ screencol: 2,
+ \ winid: win_getid(),
+ \ winrow: 2,
+ \ wincol: 2,
+ \ line: 1,
+ \ column: 53,
+ \ coladd: 0,
+ \ }, getmousepos())
+
+ bwipe!
bwipe!
endfunc
@@ -3728,6 +3795,33 @@ func Test_glob()
call assert_fails("call glob('*', 0, {})", 'E728:')
endfunc
+func Test_glob2()
+ call mkdir('[XglobDir]', 'R')
+ call mkdir('abc[glob]def', 'R')
+
+ call writefile(['glob'], '[XglobDir]/Xglob')
+ call writefile(['glob'], 'abc[glob]def/Xglob')
+ if has("unix")
+ call assert_equal([], (glob('[XglobDir]/*', 0, 1)))
+ call assert_equal([], (glob('abc[glob]def/*', 0, 1)))
+ call assert_equal(['[XglobDir]/Xglob'], (glob('\[XglobDir]/*', 0, 1)))
+ call assert_equal(['abc[glob]def/Xglob'], (glob('abc\[glob]def/*', 0, 1)))
+ elseif has("win32")
+ let _sl=&shellslash
+ call assert_equal([], (glob('[XglobDir]\*', 0, 1)))
+ call assert_equal([], (glob('abc[glob]def\*', 0, 1)))
+ call assert_equal([], (glob('\[XglobDir]\*', 0, 1)))
+ call assert_equal([], (glob('abc\[glob]def\*', 0, 1)))
+ set noshellslash
+ call assert_equal(['[XglobDir]\Xglob'], (glob('[[]XglobDir]/*', 0, 1)))
+ call assert_equal(['abc[glob]def\Xglob'], (glob('abc[[]glob]def/*', 0, 1)))
+ set shellslash
+ call assert_equal(['[XglobDir]/Xglob'], (glob('[[]XglobDir]/*', 0, 1)))
+ call assert_equal(['abc[glob]def/Xglob'], (glob('abc[[]glob]def/*', 0, 1)))
+ let &shellslash=_sl
+ endif
+endfunc
+
" Test for browse()
func Test_browse()
CheckFeature browse
@@ -4039,6 +4133,8 @@ func Test_slice()
call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -6))
END
call v9.CheckLegacyAndVim9Success(lines)
+
+ call assert_equal(0, slice(v:true, 1))
endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_global.vim b/src/testdir/test_global.vim
index 34857b2..0f72c3c 100644
--- a/src/testdir/test_global.vim
+++ b/src/testdir/test_global.vim
@@ -116,7 +116,16 @@ func Test_global_newline()
close!
endfunc
-func Test_wrong_delimiter()
+" Test :g with ? as delimiter.
+func Test_global_question_delimiter()
+ new
+ call setline(1, ['aaaaa', 'b?bbb', 'ccccc', 'ddd?d', 'eeeee'])
+ g?\??delete
+ call assert_equal(['aaaaa', 'ccccc', 'eeeee'], getline(1, '$'))
+ bwipe!
+endfunc
+
+func Test_global_wrong_delimiter()
call assert_fails('g x^bxd', 'E146:')
endfunc
diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim
index 2ff8d34..d53750f 100644
--- a/src/testdir/test_gui.vim
+++ b/src/testdir/test_gui.vim
@@ -899,7 +899,7 @@ func Test_set_term()
endfunc
func Test_windowid_variable()
- if (g:x11_based_gui && empty($WAYLAND_DISPLAY)) || has('win32')
+ if g:x11_based_gui || has('win32')
call assert_true(v:windowid > 0)
else
call assert_equal(0, v:windowid)
diff --git a/src/testdir/test_history.vim b/src/testdir/test_history.vim
index 19490f2..b288abc 100644
--- a/src/testdir/test_history.vim
+++ b/src/testdir/test_history.vim
@@ -96,6 +96,60 @@ function Test_History()
call assert_fails('history xyz', 'E488:')
call assert_fails('history ,abc', 'E488:')
call assert_fails('call histdel(":", "\\%(")', 'E53:')
+
+ " Test for filtering the history list
+ let hist_filter = execute(':filter /_\d/ :history all')->split('\n')
+ call assert_equal(20, len(hist_filter))
+ let expected = [' # cmd history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # search history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # expr history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # input history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4',
+ \ ' # debug history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4']
+ call assert_equal(expected, hist_filter)
+
+ let cmds = {'c': 'cmd', 's': 'search', 'e': 'expr', 'i': 'input', 'd': 'debug'}
+ for h in sort(keys(cmds))
+ " find some items
+ let hist_filter = execute(':filter /_\d/ :history ' .. h)->split('\n')
+ call assert_equal(4, len(hist_filter))
+
+ let expected = [' # ' .. cmds[h] .. ' history',
+ \ ' 2 text_2',
+ \ ' 3 text_3',
+ \ '> 4 text_4']
+ call assert_equal(expected, hist_filter)
+
+ " Search for an item that is not there
+ let hist_filter = execute(':filter /XXXX/ :history ' .. h)->split('\n')
+ call assert_equal(1, len(hist_filter))
+
+ let expected = [' # ' .. cmds[h] .. ' history']
+ call assert_equal(expected, hist_filter)
+
+ " Invert the filter condition, find non-matches
+ let hist_filter = execute(':filter! /_3$/ :history ' .. h)->split('\n')
+ call assert_equal(3, len(hist_filter))
+
+ let expected = [' # ' .. cmds[h] .. ' history',
+ \ ' 2 text_2',
+ \ '> 4 text_4']
+ call assert_equal(expected, hist_filter)
+ endfor
endfunction
function Test_history_truncates_long_entry()
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index eb89a15..48589ce 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -630,14 +630,14 @@ func Test_pum_with_preview_win()
CheckScreendump
let lines =<< trim END
- funct Omni_test(findstart, base)
- if a:findstart
- return col(".") - 1
- endif
- return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}]
- endfunc
- set omnifunc=Omni_test
- set completeopt+=longest
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".") - 1
+ endif
+ return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}]
+ endfunc
+ set omnifunc=Omni_test
+ set completeopt+=longest
END
call writefile(lines, 'Xpreviewscript', 'D')
@@ -809,6 +809,74 @@ func Test_complete_with_longest()
bwipe!
endfunc
+" Test for buffer-local value of 'completeopt'
+func Test_completeopt_buffer_local()
+ set completeopt=menu
+ new
+ call setline(1, ['foofoo', 'foobar', 'foobaz', ''])
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+
+ setlocal bufhidden=hide
+ enew
+ call setline(1, ['foofoo', 'foobar', 'foobaz', ''])
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+
+ setlocal completeopt+=fuzzy,noinsert
+ call assert_equal('menu,fuzzy,noinsert', &l:completeopt)
+ call assert_equal('menu,fuzzy,noinsert', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>bz\<C-Y>", 'tnix')
+ call assert_equal('foobaz', getline('.'))
+
+ setlocal completeopt=
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-Y>", 'tnix')
+ call assert_equal('foofoo', getline('.'))
+
+ setlocal completeopt+=longest
+ call assert_equal('menu,longest', &l:completeopt)
+ call assert_equal('menu,longest', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-X>\<C-Z>", 'tnix')
+ call assert_equal('foo', getline('.'))
+
+ setlocal bufhidden=hide
+ buffer #
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-Y>", 'tnix')
+ call assert_equal('foofoo', getline('.'))
+
+ setlocal completeopt+=fuzzy,noinsert
+ call assert_equal('menu,fuzzy,noinsert', &l:completeopt)
+ call assert_equal('menu,fuzzy,noinsert', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>bz\<C-Y>", 'tnix')
+ call assert_equal('foobaz', getline('.'))
+
+ buffer #
+ call assert_equal('menu,longest', &l:completeopt)
+ call assert_equal('menu,longest', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-X>\<C-Z>", 'tnix')
+ call assert_equal('foo', getline('.'))
+
+ setlocal bufhidden=wipe
+ buffer! #
+ bwipe!
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+
+ set completeopt&
+endfunc
" Test for completing words following a completed word in a line
func Test_complete_wrapscan()
@@ -2451,4 +2519,104 @@ func Test_completefunc_first_call_complete_add()
bwipe!
endfunc
+func Test_complete_fuzzy_match()
+ func OnPumChange()
+ let g:item = get(v:event, 'completed_item', {})
+ let g:word = get(g:item, 'word', v:null)
+ endfunction
+
+ augroup AAAAA_Group
+ au!
+ autocmd CompleteChanged * :call OnPumChange()
+ augroup END
+
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".")
+ endif
+ return [#{word: "foo"}, #{word: "foobar"}, #{word: "fooBaz"}, #{word: "foobala"}]
+ endfunc
+
+ new
+ set omnifunc=Omni_test
+ set completeopt+=noinsert,fuzzy
+ call feedkeys("Gi\<C-x>\<C-o>", 'tx')
+ call assert_equal('foo', g:word)
+ call feedkeys("S\<C-x>\<C-o>fb", 'tx')
+ call assert_equal('fooBaz', g:word)
+ call feedkeys("S\<C-x>\<C-o>fa", 'tx')
+ call assert_equal('foobar', g:word)
+ " select next
+ call feedkeys("S\<C-x>\<C-o>fb\<C-n>", 'tx')
+ call assert_equal('foobar', g:word)
+ " can cyclically select next
+ call feedkeys("S\<C-x>\<C-o>fb\<C-n>\<C-n>\<C-n>", 'tx')
+ call assert_equal(v:null, g:word)
+ " select prev
+ call feedkeys("S\<C-x>\<C-o>fb\<C-p>", 'tx')
+ call assert_equal(v:null, g:word)
+ " can cyclically select prev
+ call feedkeys("S\<C-x>\<C-o>fb\<C-p>\<C-p>\<C-p>\<C-p>", 'tx')
+ call assert_equal('fooBaz', g:word)
+
+ func Comp()
+ call complete(col('.'), ["fooBaz", "foobar", "foobala"])
+ return ''
+ endfunc
+ call feedkeys("i\<C-R>=Comp()\<CR>", 'tx')
+ call assert_equal('fooBaz', g:word)
+
+ " respect noselect
+ set completeopt+=noselect
+ call feedkeys("S\<C-x>\<C-o>fb", 'tx')
+ call assert_equal(v:null, g:word)
+ call feedkeys("S\<C-x>\<C-o>fb\<C-n>", 'tx')
+ call assert_equal('fooBaz', g:word)
+
+ " avoid breaking default completion behavior
+ set completeopt=fuzzy,menu
+ call setline(1, ['hello help hero h'])
+ " Use "!" flag of feedkeys() so that ex_normal_busy is not set and
+ " ins_compl_check_keys() is not skipped.
+ " Add a "0" after the <Esc> to avoid waiting for an escape sequence.
+ call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('hello help hero hello', getline('.'))
+ set completeopt+=noinsert
+ call setline(1, ['hello help hero h'])
+ call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('hello help hero h', getline('.'))
+
+ " clean up
+ set omnifunc=
+ bw!
+ set complete& completeopt&
+ autocmd! AAAAA_Group
+ augroup! AAAAA_Group
+ delfunc OnPumChange
+ delfunc Omni_test
+ delfunc Comp
+ unlet g:item
+ unlet g:word
+endfunc
+
+" Check that tie breaking is stable for completeopt+=fuzzy (which should
+" behave the same on different platforms).
+func Test_complete_fuzzy_match_tie()
+ new
+ set completeopt+=fuzzy,noselect
+ call setline(1, ['aaabbccc', 'aaabbCCC', 'aaabbcccc', 'aaabbCCCC', ''])
+
+ call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-Y>", 'tx')
+ call assert_equal('aaabbccc', getline('.'))
+ call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-N>\<C-Y>", 'tx')
+ call assert_equal('aaabbCCC', getline('.'))
+ call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-N>\<C-N>\<C-Y>", 'tx')
+ call assert_equal('aaabbcccc', getline('.'))
+ call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-N>\<C-N>\<C-N>\<C-Y>", 'tx')
+ call assert_equal('aaabbCCCC', getline('.'))
+
+ bwipe!
+ set completeopt&
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim
index 4c69476..12a6dd4 100644
--- a/src/testdir/test_listdict.vim
+++ b/src/testdir/test_listdict.vim
@@ -60,6 +60,9 @@ func Test_list_slice()
assert_equal([1, 2], l[-3 : -1])
END
call v9.CheckDefAndScriptSuccess(lines)
+
+ call assert_fails('let l[[]] = 1', 'E730: Using a List as a String')
+ call assert_fails('let l[1 : []] = [1]', 'E730: Using a List as a String')
endfunc
" List identity
@@ -178,6 +181,19 @@ func Test_list_assign()
END
call v9.CheckScriptFailure(['vim9script'] + lines, 'E688:')
call v9.CheckDefExecFailure(lines, 'E1093: Expected 2 items but got 1')
+
+ let lines =<< trim END
+ VAR l = [2]
+ LET l += test_null_list()
+ call assert_equal([2], l)
+ LET l = test_null_list()
+ LET l += [1]
+ call assert_equal([1], l)
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
+
+ let d = {'abc': [1, 2, 3]}
+ call assert_fails('let d.abc[0:0z10] = [10, 20]', 'E976: Using a Blob as a String')
endfunc
" test for range assign
@@ -447,6 +463,9 @@ func Test_dict_assign()
n.key = 3
END
call v9.CheckDefFailure(lines, 'E1141:')
+
+ let d = {'abc': {}}
+ call assert_fails("let d.abc[0z10] = 10", 'E976: Using a Blob as a String')
endfunc
" Function in script-local List or Dict
@@ -1505,6 +1524,8 @@ func Test_indexof()
call assert_equal(-1, indexof(test_null_list(), {i, v -> v == 'a'}))
call assert_equal(-1, indexof(l, test_null_string()))
call assert_equal(-1, indexof(l, test_null_function()))
+ call assert_equal(-1, indexof(l, ""))
+ call assert_fails('let i = indexof(l, " ")', 'E15:')
" failure cases
call assert_fails('let i = indexof(l, "v:val == ''cyan''")', 'E735:')
diff --git a/src/testdir/test_method.vim b/src/testdir/test_method.vim
index 120fade..f18ac14 100644
--- a/src/testdir/test_method.vim
+++ b/src/testdir/test_method.vim
@@ -136,6 +136,13 @@ func Test_method_syntax()
call assert_fails('eval [1, 2, 3] ->sort ()', 'E274:')
call assert_fails('eval [1, 2, 3]-> sort ()', 'E274:')
call assert_fails('eval [1, 2, 3]-> sort()', 'E274:')
+
+ " Test for using a method name containing a curly brace name
+ let s = 'len'
+ call assert_equal(4, "xxxx"->str{s}())
+
+ " Test for using a method in an interpolated string
+ call assert_equal('4', $'{"xxxx"->strlen()}')
endfunc
func Test_method_lambda()
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index 4b7e5e6..83594d2 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -402,17 +402,17 @@ func Test_normal08_fold()
" First fold
norm! V4jzf
" check that folds have been created
- call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
+ call assert_equal(['50/* {{{ */', '51', '52', '53', '54/* }}} */'], getline(50,54))
" Second fold
46
norm! V10jzf
" check that folds have been created
- call assert_equal('46/*{{{*/', getline(46))
- call assert_equal('60/*}}}*/', getline(60))
+ call assert_equal('46/* {{{ */', getline(46))
+ call assert_equal('60/* }}} */', getline(60))
norm! k
call assert_equal('45', getline('.'))
norm! j
- call assert_equal('46/*{{{*/', getline('.'))
+ call assert_equal('46/* {{{ */', getline('.'))
norm! j
call assert_equal('61', getline('.'))
norm! k
@@ -421,12 +421,12 @@ func Test_normal08_fold()
norm! k
call assert_equal('45', getline('.'))
norm! j
- call assert_equal('46/*{{{*/', getline('.'))
+ call assert_equal('46/* {{{ */', getline('.'))
norm! j
call assert_equal('47', getline('.'))
norm! k
norm! zcVzO
- call assert_equal('46/*{{{*/', getline('.'))
+ call assert_equal('46/* {{{ */', getline('.'))
norm! j
call assert_equal('47', getline('.'))
norm! j
@@ -434,7 +434,7 @@ func Test_normal08_fold()
norm! j
call assert_equal('49', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
call assert_equal('51', getline('.'))
" delete folds
@@ -1383,14 +1383,14 @@ func Test_normal18_z_fold()
" First fold
norm! 4zF
" check that folds have been created
- call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
+ call assert_equal(['50/* {{{ */', '51', '52', '53/* }}} */'], getline(50,53))
" Test for zd
51
norm! 2zF
call assert_equal(2, foldlevel('.'))
norm! kzd
- call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
+ call assert_equal(['50', '51/* {{{ */', '52/* }}} */', '53'], getline(50,53))
norm! j
call assert_equal(1, foldlevel('.'))
@@ -1409,7 +1409,7 @@ func Test_normal18_z_fold()
norm! 2zF
90
norm! 4zF
- call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
+ call assert_equal(['85/* {{{ */', '86/* {{{ */', '87/* }}} */', '88/* }}} */', '89', '90/* {{{ */', '91', '92', '93/* }}} */'], getline(85,93))
norm! zE
call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
@@ -1421,9 +1421,9 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('49', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
call assert_equal(0, &foldenable)
@@ -1433,7 +1433,7 @@ func Test_normal18_z_fold()
norm! zN
call assert_equal('49', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
call assert_equal(1, &foldenable)
@@ -1454,9 +1454,9 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('49', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
50
@@ -1464,7 +1464,7 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('49', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
@@ -1473,14 +1473,14 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
49
norm! za
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
set nofoldenable
@@ -1494,11 +1494,11 @@ func Test_normal18_z_fold()
norm! 2k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
@@ -1510,11 +1510,11 @@ func Test_normal18_z_fold()
norm! 2k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
@@ -1526,7 +1526,7 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1546,7 +1546,7 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
set nofoldenable
@@ -1555,7 +1555,7 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1565,7 +1565,7 @@ func Test_normal18_z_fold()
norm! zCk
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1576,7 +1576,7 @@ func Test_normal18_z_fold()
norm! zx
call assert_equal(1, &foldenable)
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1588,17 +1588,17 @@ func Test_normal18_z_fold()
norm! 3k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
norm! j
call assert_equal('53', getline('.'))
norm! j
- call assert_equal('54/*}}}*/', getline('.'))
+ call assert_equal('54/* }}} */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1610,15 +1610,15 @@ func Test_normal18_z_fold()
call assert_equal(1, &foldenable)
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
norm! j
call assert_equal('53', getline('.'))
norm! j
- call assert_equal('54/*}}}*/', getline('.'))
+ call assert_equal('54/* }}} */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1631,7 +1631,7 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1648,7 +1648,7 @@ func Test_normal18_z_fold()
norm! k
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1667,7 +1667,7 @@ func Test_normal18_z_fold()
call assert_equal(0, &foldlevel)
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
call assert_equal('55', getline('.'))
@@ -1685,11 +1685,11 @@ func Test_normal18_z_fold()
call assert_equal(2, &foldlevel)
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
@@ -1705,24 +1705,24 @@ func Test_normal18_z_fold()
call assert_equal(2, &foldlevel)
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
- call append(50, ['a /*{{{*/', 'b /*}}}*/'])
+ call append(50, ['a /* {{{ */', 'b /* }}} */'])
48
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('a /*{{{*/', getline('.'))
+ call assert_equal('a /* {{{ */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
48
@@ -1731,15 +1731,15 @@ func Test_normal18_z_fold()
call assert_equal(3, &foldlevel)
call assert_equal('48', getline('.'))
norm! j
- call assert_equal('49/*{{{*/', getline('.'))
+ call assert_equal('49/* {{{ */', getline('.'))
norm! j
- call assert_equal('50/*{{{*/', getline('.'))
+ call assert_equal('50/* {{{ */', getline('.'))
norm! j
- call assert_equal('a /*{{{*/', getline('.'))
+ call assert_equal('a /* {{{ */', getline('.'))
norm! j
- call assert_equal('b /*}}}*/', getline('.'))
+ call assert_equal('b /* }}} */', getline('.'))
norm! j
- call assert_equal('51/*}}}*/', getline('.'))
+ call assert_equal('51/* }}} */', getline('.'))
norm! j
call assert_equal('52', getline('.'))
@@ -4260,4 +4260,22 @@ func Test_page_cursor_topbot()
bwipe!
endfunc
+" Test for Ctrl-D with long line
+func Test_halfpage_longline()
+ 10new
+ call setline(1, ['long'->repeat(1000), 'short'])
+ exe "norm! \<C-D>"
+ call assert_equal(2, line('.'))
+ bwipe!
+endfunc
+
+" Test for Ctrl-E with long line and very narrow window,
+" used to cause an inifite loop
+func Test_scroll_longline_no_loop()
+ 4vnew
+ setl smoothscroll number showbreak=> scrolloff=2
+ call setline(1, repeat(['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'], 3))
+ exe "normal! \<C-E>"
+ bwipe!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim
index 4b054b5..b5a58f6 100644
--- a/src/testdir/test_partial.vim
+++ b/src/testdir/test_partial.vim
@@ -406,4 +406,18 @@ func Test_compare_partials()
call assert_false(F1 is N1)
endfunc
+func Test_partial_method()
+ func Foo(x, y, z)
+ return x + y + z
+ endfunc
+ let d = {"Fn": function('Foo', [10, 20])}
+ call assert_fails('echo 30->d.Fn()', 'E1265: Cannot use a partial here')
+ delfunc Foo
+endfunc
+
+func Test_non_callable_type_as_method()
+ let d = {"Fn": 10}
+ call assert_fails('echo 30->d.Fn()', 'E1085: Not a callable type: d.Fn')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index f5cb8b2..dd01a57 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -908,6 +908,13 @@ func Test_popup_command_dump()
call term_sendkeys(buf, "\<Esc>")
+ if has('rightleft')
+ call term_sendkeys(buf, ":set rightleft\<CR>")
+ call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_command_rl', {})
+ call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>")
+ endif
+
" Set a timer to change a menu entry while it's displayed. The text should
" not change but the command does. Making the screendump also verifies that
" "changed" shows up, which means the timer triggered.
@@ -930,6 +937,37 @@ func Test_popup_command_dump()
call StopVimInTerminal(buf)
endfunc
+" Test position of right-click menu when clicking near window edge.
+func Test_mouse_popup_position()
+ CheckFeature menu
+ CheckScreendump
+
+ let script =<< trim END
+ set mousemodel=popup_setpos
+ source $VIMRUNTIME/menu.vim
+ call setline(1, join(range(20)))
+ func Trigger(col)
+ call test_setmouse(1, a:col)
+ call feedkeys("\<RightMouse>", 't')
+ endfunc
+ END
+ call writefile(script, 'XmousePopupPosition', 'D')
+ let buf = RunVimInTerminal('-S XmousePopupPosition', #{rows: 20, cols: 50})
+
+ call term_sendkeys(buf, ":call Trigger(45)\<CR>")
+ call VerifyScreenDump(buf, 'Test_mouse_popup_position_01', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ if has('rightleft')
+ call term_sendkeys(buf, ":set rightleft\<CR>")
+ call term_sendkeys(buf, ":call Trigger(50 + 1 - 45)\<CR>")
+ call VerifyScreenDump(buf, 'Test_mouse_popup_position_02', {})
+ call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>")
+ endif
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_popup_complete_backwards()
new
call setline(1, ['Post', 'Port', 'Po'])
@@ -1175,6 +1213,8 @@ func Test_CompleteChanged()
set completeopt=menu,menuone
call feedkeys("i\<C-X>\<C-O>\<BS>\<BS>\<BS>f", 'tx')
call assert_equal('five', g:word)
+ call feedkeys("i\<C-X>\<C-O>\<BS>\<BS>\<BS>f\<BS>", 'tx')
+ call assert_equal('one', g:word)
autocmd! AAAAA_Group
set complete& completeopt&
@@ -1339,4 +1379,113 @@ func Test_pum_highlights_custom()
call StopVimInTerminal(buf)
endfunc
+" Test match relate highlight group in pmenu
+func Test_pum_highlights_match()
+ CheckScreendump
+ let lines =<< trim END
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".")
+ endif
+ return {
+ \ 'words': [
+ \ { 'word': 'foo', 'kind': 'fookind' },
+ \ { 'word': 'foofoo', 'kind': 'fookind' },
+ \ { 'word': 'foobar', 'kind': 'fookind' },
+ \ { 'word': 'fooBaz', 'kind': 'fookind' },
+ \ { 'word': 'foobala', 'kind': 'fookind' },
+ \ { 'word': '你好' },
+ \ { 'word': '你好吗' },
+ \ { 'word': '你不好吗' },
+ \ { 'word': '你可好吗' },
+ \]}
+ endfunc
+
+ func Comp()
+ let col = col('.')
+ if getline('.') == 'f'
+ let col -= 1
+ endif
+ call complete(col, [
+ \ #{word: "foo", icase: 1},
+ \ #{word: "Foobar", icase: 1},
+ \ #{word: "fooBaz", icase: 1},
+ \])
+ return ''
+ endfunc
+
+ set omnifunc=Omni_test
+ set completeopt=menu,noinsert,fuzzy
+ hi PmenuMatchSel ctermfg=6 ctermbg=7
+ hi PmenuMatch ctermfg=4 ctermbg=225
+ END
+ call writefile(lines, 'Xscript', 'D')
+ let buf = RunVimInTerminal('-S Xscript', {})
+ call TermWait(buf)
+ call term_sendkeys(buf, "i\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "fo")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_03', {})
+ call term_sendkeys(buf, "\<Esc>S\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "你")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_04', {})
+ call term_sendkeys(buf, "吗")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_05', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+ if has('rightleft')
+ call term_sendkeys(buf, ":set rightleft\<CR>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "S\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "fo")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_06', {})
+ call term_sendkeys(buf, "\<Esc>S\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "你")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_06a', {})
+ call term_sendkeys(buf, "吗")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_06b', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+ call term_sendkeys(buf, ":set norightleft\<CR>")
+ call TermWait(buf)
+ endif
+
+ call term_sendkeys(buf, ":set completeopt-=fuzzy\<CR>")
+ call TermWait(buf)
+ call term_sendkeys(buf, "S\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "fo")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_07', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+ if has('rightleft')
+ call term_sendkeys(buf, ":set rightleft\<CR>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "S\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "fo")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_highlights_08', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+ call term_sendkeys(buf, ":set norightleft\<CR>")
+ endif
+
+ call term_sendkeys(buf, "S\<C-R>=Comp()\<CR>f")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_09', {})
+ call term_sendkeys(buf, "o\<BS>\<C-R>=Comp()\<CR>")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_09', {})
+
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+ call TermWait(buf)
+
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index c784a2d..0b61815 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -6496,4 +6496,74 @@ func Test_efm_format_b()
call setqflist([], 'f')
endfunc
+func XbufferTests_range(cchar)
+ call s:setup_commands(a:cchar)
+
+ enew!
+ let lines =<< trim END
+ Xtestfile7:700:10:Line 700
+ Xtestfile8:800:15:Line 800
+ END
+ silent! call setline(1, lines)
+ norm! Vy
+ " Note: We cannot use :Xbuffer here,
+ " it doesn't properly fail, so we need to
+ " test using the raw c/l commands.
+ " (also further down)
+ if (a:cchar == 'c')
+ exe "'<,'>cbuffer!"
+ else
+ exe "'<,'>lbuffer!"
+ endif
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 1 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700')
+
+ enew!
+ let lines =<< trim END
+ Xtestfile9:900:55:Line 900
+ Xtestfile10:950:66:Line 950
+ END
+ silent! call setline(1, lines)
+ if (a:cchar == 'c')
+ 1cgetbuffer
+ else
+ 1lgetbuffer
+ endif
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 1 &&
+ \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900')
+
+ enew!
+ let lines =<< trim END
+ Xtestfile11:700:20:Line 700
+ Xtestfile12:750:25:Line 750
+ END
+ silent! call setline(1, lines)
+ if (a:cchar == 'c')
+ 1,1caddbuffer
+ else
+ 1,1laddbuffer
+ endif
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
+ \ l[1].lnum == 700 && l[1].col == 20 && l[1].text ==# 'Line 700')
+ enew!
+
+ " Check for invalid range
+ " Using Xbuffer will not run the range check in the cbuffer/lbuffer
+ " commands. So directly call the commands.
+ if (a:cchar == 'c')
+ call assert_fails('900,999caddbuffer', 'E16:')
+ else
+ call assert_fails('900,999laddbuffer', 'E16:')
+ endif
+endfunc
+
+func Test_cbuffer_range()
+ call XbufferTests_range('c')
+ call XbufferTests_range('l')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_remote.vim b/src/testdir/test_remote.vim
index 1475052..fd8b0af 100644
--- a/src/testdir/test_remote.vim
+++ b/src/testdir/test_remote.vim
@@ -12,7 +12,7 @@ source term_util.vim
let s:remote_works = 0
let s:skip = 'Skipped: --remote feature is not possible'
-" nees to be run as first test to verify, that vim --servername works
+" needs to be run as first test to verify, that vim --servername works
func Verify_remote_feature_works()
CheckRunVimInTerminal
enew
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index cda9bf0..1b60019 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -961,6 +961,51 @@ func Test_smoothscroll_insert_bottom()
call StopVimInTerminal(buf)
endfunc
+func Test_smoothscroll_in_qf_window()
+ CheckFeature quickfix
+ CheckScreendump
+
+ let lines =<< trim END
+ set nocompatible display=lastline
+ copen 5
+ setlocal number smoothscroll
+ let g:l = [{'text': 'foo'}] + repeat([{'text': join(range(30))}], 10)
+ call setqflist(g:l, 'r')
+ normal! G
+ wincmd t
+ let g:l1 = [{'text': join(range(1000))}]
+ END
+ call writefile(lines, 'XSmoothScrollInQfWindow', 'D')
+ let buf = RunVimInTerminal('-u NONE -S XSmoothScrollInQfWindow', #{rows: 20, cols: 60})
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_1', {})
+
+ call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
+
+ call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
+
+ call term_sendkeys(buf, ":call setqflist([], 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_2', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l1, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_4', {})
+
+ call term_sendkeys(buf, "\<C-W>b$\<C-W>t")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_5', {})
+
+ call term_sendkeys(buf, ":call setqflist(g:l, 'r')\<CR>")
+ call VerifyScreenDump(buf, 'Test_smoothscroll_in_qf_window_3', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_smoothscroll_in_zero_width_window()
set cpo+=n number smoothscroll
set winwidth=99999 winminwidth=0
@@ -1108,4 +1153,39 @@ func Test_smoothscroll_long_line_zb()
bwipe!
endfunc
+func Test_smooth_long_scrolloff()
+ CheckScreendump
+
+ let lines =<< trim END
+ set smoothscroll scrolloff=3
+ call setline(1, ['one', 'two long '->repeat(100), 'three', 'four', 'five', 'six'])
+ END
+ call writefile(lines, 'XSmoothLongScrolloff', 'D')
+ let buf = RunVimInTerminal('-u NONE -S XSmoothLongScrolloff', #{rows: 8, cols: 40})
+ "FIXME: empty screen due to reset_skipcol()/curs_columns() shenanigans
+ call term_sendkeys(buf, ":norm j721|\<CR>")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_1', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_2', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_3', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_4', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_5', {})
+
+ call term_sendkeys(buf, "gj")
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_6', {})
+
+ call term_sendkeys(buf, "gk")
+ "FIXME: empty screen due to reset_skipcol()/curs_columns() shenanigans
+ call VerifyScreenDump(buf, 'Test_smooth_long_scrolloff_7', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_shell.vim b/src/testdir/test_shell.vim
index 7d91dff..2ac5596 100644
--- a/src/testdir/test_shell.vim
+++ b/src/testdir/test_shell.vim
@@ -158,6 +158,10 @@ func Test_shellescape()
call assert_equal("'te\\#xt'", shellescape("te#xt", 1))
call assert_equal("'te!xt'", shellescape("te!xt"))
call assert_equal("'te\\!xt'", shellescape("te!xt", 1))
+ call assert_equal("'te<cword>xt'", shellescape("te<cword>xt"))
+ call assert_equal("'te\\<cword>xt'", shellescape("te<cword>xt", 1))
+ call assert_equal("'te<cword>%xt'", shellescape("te<cword>%xt"))
+ call assert_equal("'te\\<cword>\\%xt'", shellescape("te<cword>%xt", 1))
call assert_equal("'te\nxt'", shellescape("te\nxt"))
call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1))
diff --git a/src/testdir/test_shortpathname.vim b/src/testdir/test_shortpathname.vim
index 5964630..0c41692 100644
--- a/src/testdir/test_shortpathname.vim
+++ b/src/testdir/test_shortpathname.vim
@@ -16,18 +16,14 @@ func TestIt(file, bits, expected)
endif
endfunc
-func Test_ColonEight()
- let save_dir = getcwd()
-
- " This could change for CygWin to //cygdrive/c .
- let dir1 = 'c:/x.x.y'
+func s:SetupDir(dir)
let trycount = 5
while 1
- if !filereadable(dir1) && !isdirectory(dir1)
+ if !filereadable(a:dir) && !isdirectory(a:dir)
break
endif
if trycount == 1
- call assert_report("Fatal: '" . dir1 . "' exists, cannot run this test")
+ call assert_report("Fatal: '" . a:dir . "' exists, cannot run this test")
return
endif
" When tests run in parallel the directory may exist, wait a bit until it
@@ -35,6 +31,15 @@ func Test_ColonEight()
sleep 5
let trycount -= 1
endwhile
+endfunc
+
+
+func Test_ColonEight()
+ let save_dir = getcwd()
+
+ " This could change for CygWin to //cygdrive/c .
+ let dir1 = 'c:/x.x.y'
+ call s:SetupDir(dir1)
let file1 = dir1 . '/zz.y.txt'
let nofile1 = dir1 . '/z.y.txt'
@@ -78,7 +83,8 @@ func Test_ColonEight()
endfunc
func Test_ColonEight_MultiByte()
- let dir = 'Xtest'
+ let dir = 'c:/Xtest_C8MB'
+ call s:SetupDir(dir)
let file = dir . '/日本語のファイル.txt'
diff --git a/src/testdir/test_spellrare.vim b/src/testdir/test_spellrare.vim
new file mode 100644
index 0000000..ceb35cb
--- /dev/null
+++ b/src/testdir/test_spellrare.vim
@@ -0,0 +1,61 @@
+" Test spell checking
+
+source check.vim
+CheckFeature spell
+
+" Test spellbadword() with argument, specifically to move to "rare" words
+" in normal mode.
+func Test_spellrareword()
+ set spell
+
+ " Create a small word list to test that spellbadword('...')
+ " can return ['...', 'rare'].
+ let lines =<< trim END
+ foo
+ foobar/?
+ foobara/?
+ END
+ call writefile(lines, 'Xwords', 'D')
+
+ mkspell! Xwords.spl Xwords
+ set spelllang=Xwords.spl
+ call assert_equal(['foobar', 'rare'], spellbadword('foo foobar'))
+
+ new
+ call setline(1, ['foo', '', 'foo bar foo bar foobara foo foo foo foobar', '', 'End'])
+ set spell wrapscan
+ normal ]s
+ call assert_equal('foo', expand('<cword>'))
+ normal ]s
+ call assert_equal('bar', expand('<cword>'))
+
+ normal ]r
+ call assert_equal('foobara', expand('<cword>'))
+ normal ]r
+ call assert_equal('foobar', expand('<cword>'))
+ normal ]r
+ call assert_equal('foobara', expand('<cword>'))
+ normal 2]r
+ call assert_equal('foobara', expand('<cword>'))
+
+ normal [r
+ call assert_equal('foobar', expand('<cword>'))
+ normal [r
+ call assert_equal('foobara', expand('<cword>'))
+ normal [r
+ call assert_equal('foobar', expand('<cword>'))
+ normal 2[r
+ call assert_equal('foobar', expand('<cword>'))
+
+ bwipe!
+ set nospell
+
+ call delete('Xwords.spl')
+ set spelllang&
+ set spell&
+
+ " set 'encoding' to clear the word list
+ set encoding=utf-8
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
index 7c2bbb4..afdc104 100644
--- a/src/testdir/test_substitute.vim
+++ b/src/testdir/test_substitute.vim
@@ -173,6 +173,16 @@ func Test_substitute_repeat()
call feedkeys("Qsc\<CR>y", 'tx')
bwipe!
endfunc
+
+" Test :s with ? as delimiter.
+func Test_substitute_question_delimiter()
+ new
+ call setline(1, '??:??')
+ %s?\?\??!!?g
+ call assert_equal('!!:!!', getline(1))
+ bwipe!
+endfunc
+
" Test %s/\n// which is implemented as a special case to use a
" more efficient join rather than doing a regular substitution.
func Test_substitute_join()
@@ -1498,4 +1508,18 @@ func Test_substitute_expr_recursive()
exe bufnr .. "bw!"
endfunc
+" Test for changing 'cpo' in a substitute expression
+func Test_substitute_expr_cpo()
+ func XSubExpr()
+ set cpo=
+ return 'x'
+ endfunc
+
+ let save_cpo = &cpo
+ call assert_equal('xxx', substitute('abc', '.', '\=XSubExpr()', 'g'))
+ call assert_equal(save_cpo, &cpo)
+
+ delfunc XSubExpr
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index 2abf1f6..432906e 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -1560,4 +1560,22 @@ func Test_tagbsearch()
set tags& tagbsearch&
endfunc
+" Test tag guessing with very short names
+func Test_tag_guess_short()
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "y\tXf\t/^y()/"],
+ \ 'Xt', 'D')
+ set tags=Xt cpoptions+=t
+ call writefile(['', 'int * y () {}', ''], 'Xf', 'D')
+
+ let v:statusmsg = ''
+ let @/ = ''
+ ta y
+ call assert_match('E435:', v:statusmsg)
+ call assert_equal(2, line('.'))
+ call assert_match('<y', @/)
+
+ set tags& cpoptions-=t
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_termdebug.vim b/src/testdir/test_termdebug.vim
index 68bffd4..a9762df 100644
--- a/src/testdir/test_termdebug.vim
+++ b/src/testdir/test_termdebug.vim
@@ -230,26 +230,26 @@ endfunc
func Test_termdebug_mapping()
%bw!
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 1)
+ call assert_true(maparg('K', 'n', 0, 1)->empty())
+ call assert_true(maparg('-', 'n', 0, 1)->empty())
+ call assert_true(maparg('+', 'n', 0, 1)->empty())
Termdebug
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':Evaluate<CR>')
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_false(maparg('K', 'n', 0, 1).buffer)
+ call assert_false(maparg('-', 'n', 0, 1).buffer)
+ call assert_false(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs)
wincmd t
quit!
redraw!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 1)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 1)
+ call assert_true(maparg('K', 'n', 0, 1)->empty())
+ call assert_true(maparg('-', 'n', 0, 1)->empty())
+ call assert_true(maparg('+', 'n', 0, 1)->empty())
%bw!
nnoremap K :echom "K"<cr>
@@ -258,24 +258,24 @@ func Test_termdebug_mapping()
Termdebug
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':Evaluate<CR>')
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_false(maparg('K', 'n', 0, 1).buffer)
+ call assert_false(maparg('-', 'n', 0, 1).buffer)
+ call assert_false(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs)
wincmd t
quit!
redraw!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- call assert_equal(maparg('K', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('-', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('+', 'n', 0, 1)->empty(), 0)
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 0)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "K"<cr>')
+ call assert_false(maparg('K', 'n', 0, 1)->empty())
+ call assert_false(maparg('-', 'n', 0, 1)->empty())
+ call assert_false(maparg('+', 'n', 0, 1)->empty())
+ call assert_false(maparg('K', 'n', 0, 1).buffer)
+ call assert_false(maparg('-', 'n', 0, 1).buffer)
+ call assert_false(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':echom "K"<cr>', maparg('K', 'n', 0, 1).rhs)
%bw!
nnoremap <buffer> K :echom "bK"<cr>
@@ -284,20 +284,70 @@ func Test_termdebug_mapping()
Termdebug
call WaitForAssert({-> assert_equal(3, winnr('$'))})
wincmd b
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 1)
+ call assert_true(maparg('K', 'n', 0, 1).buffer)
+ call assert_true(maparg('-', 'n', 0, 1).buffer)
+ call assert_true(maparg('+', 'n', 0, 1).buffer)
call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "bK"<cr>')
wincmd t
quit!
redraw!
call WaitForAssert({-> assert_equal(1, winnr('$'))})
- call assert_equal(maparg('K', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('-', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('+', 'n', 0, 1).buffer, 1)
- call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "bK"<cr>')
+ call assert_true(maparg('K', 'n', 0, 1).buffer)
+ call assert_true(maparg('-', 'n', 0, 1).buffer)
+ call assert_true(maparg('+', 'n', 0, 1).buffer)
+ call assert_equal(':echom "bK"<cr>', maparg('K', 'n', 0, 1).rhs)
%bw!
endfunc
+func Test_termdebug_bufnames()
+ " Test if user has filename/folders named gdb, Termdebug-gdb-console,
+ " etc. in the current directory
+ let g:termdebug_config = {}
+ let g:termdebug_config['use_prompt'] = 1
+ let filename = 'gdb'
+ let replacement_filename = 'Termdebug-gdb-console'
+
+ call writefile(['This', 'is', 'a', 'test'], filename, 'D')
+ " Throw away the file once the test has done.
+ Termdebug
+ " Once termdebug has completed the startup you should have 3 windows on screen
+ call WaitForAssert({-> assert_equal(3, winnr('$'))})
+ " A file named filename already exists in the working directory,
+ " hence you must call the newly created buffer differently
+ call WaitForAssert({-> assert_false(bufexists(filename))})
+ call WaitForAssert({-> assert_true(bufexists(replacement_filename))})
+ quit!
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+
+ " Check if error message is in :message
+ let g:termdebug_config['disasm_window'] = 1
+ let filename = 'Termdebug-asm-listing'
+ call writefile(['This', 'is', 'a', 'test'], filename, 'D')
+ " Check only the head of the error message
+ let error_message = "You have a file/folder named '" .. filename .. "'"
+ Termdebug
+ " Once termdebug has completed the startup you should have 4 windows on screen
+ call WaitForAssert({-> assert_equal(4, winnr('$'))})
+ call WaitForAssert({-> assert_notequal(-1, stridx(execute('messages'), error_message))})
+ quit!
+ wincmd b
+ wincmd q
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+
+ unlet g:termdebug_config
+endfunc
+
+function Test_termdebug_save_restore_variables()
+ let &mousemodel=''
+ Termdebug
+ call WaitForAssert({-> assert_equal(3, winnr('$'))})
+ call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')})
+ wincmd t
+ quit!
+ call WaitForAssert({-> assert_equal(1, winnr('$'))})
+ call WaitForAssert({-> assert_true(empty(&mousemodel))})
+endfunction
+
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim
index 223bcc5..3cca1b0 100644
--- a/src/testdir/test_terminal3.vim
+++ b/src/testdir/test_terminal3.vim
@@ -10,6 +10,8 @@ source screendump.vim
source mouse.vim
source term_util.vim
+import './vim9.vim' as v9
+
let $PROMPT_COMMAND=''
func Test_terminal_altscreen()
@@ -935,7 +937,14 @@ func Test_terminal_vt420()
CheckRunVimInTerminal
" For Termcap
CheckUnix
- let rows=15
+ CheckExecutable infocmp
+ let a = system('infocmp vt420')
+ if v:shell_error
+ " reset v:shell_error
+ let a = system('true')
+ throw 'Skipped: vt420 terminfo not available'
+ endif
+ let rows = 15
call writefile([':set term=vt420'], 'Xterm420', 'D')
let buf = RunVimInTerminal('-S Xterm420', #{rows: rows})
@@ -952,4 +961,18 @@ func Test_terminal_vt420()
call StopVimInTerminal(buf)
endfunc
+" Test for using 'vertical' with term_start(). If a following term_start(),
+" doesn't have the 'vertical' attribute, then it should be split horizontally.
+func Test_terminal_vertical()
+ let lines =<< trim END
+ call term_start("NONE", {'vertical': 1})
+ call term_start("NONE")
+ VAR layout = winlayout()
+ call assert_equal('row', layout[0], string(layout))
+ call assert_equal('col', layout[1][0][0], string(layout))
+ :%bw!
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_textformat.vim b/src/testdir/test_textformat.vim
index 5d58486..e31ea22 100644
--- a/src/testdir/test_textformat.vim
+++ b/src/testdir/test_textformat.vim
@@ -1304,7 +1304,7 @@ func Test_correct_cursor_position()
endfunc
" This was crashing Vim
-func Test_textwdith_overflow()
+func Test_textwidth_overflow()
new
setl tw=999999999
normal 10ig
diff --git a/src/testdir/test_vartabs.vim b/src/testdir/test_vartabs.vim
index e15a072..bae00dd 100644
--- a/src/testdir/test_vartabs.vim
+++ b/src/testdir/test_vartabs.vim
@@ -454,5 +454,64 @@ func Test_vartabstop_latin1()
set nocompatible linebreak& list& revins& smarttab& vartabstop&
endfunc
+" Verify that right-shifting and left-shifting adjust lines to the proper
+" tabstops.
+func Test_vartabstop_shift_right_left()
+ new
+ set expandtab
+ set shiftwidth=0
+ set vartabstop=17,11,7
+ exe "norm! aword"
+ let expect = "word"
+ call assert_equal(expect, getline(1))
+
+ " Shift to first tabstop.
+ norm! >>
+ let expect = " word"
+ call assert_equal(expect, getline(1))
+
+ " Shift to second tabstop.
+ norm! >>
+ let expect = " word"
+ call assert_equal(expect, getline(1))
+
+ " Shift to third tabstop.
+ norm! >>
+ let expect = " word"
+ call assert_equal(expect, getline(1))
+
+ " Shift to fourth tabstop, repeating the third shift width.
+ norm! >>
+ let expect = " word"
+ call assert_equal(expect, getline(1))
+
+ " Shift back to the third tabstop.
+ norm! <<
+ let expect = " word"
+ call assert_equal(expect, getline(1))
+
+ " Shift back to the second tabstop.
+ norm! <<
+ let expect = " word"
+ call assert_equal(expect, getline(1))
+
+ " Shift back to the first tabstop.
+ norm! <<
+ let expect = " word"
+ call assert_equal(expect, getline(1))
+
+ " Shift back to the left margin.
+ norm! <<
+ let expect = "word"
+ call assert_equal(expect, getline(1))
+
+ " Shift again back to the left margin.
+ norm! <<
+ let expect = "word"
+ call assert_equal(expect, getline(1))
+
+ bwipeout!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 4296c37..bb08943 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -650,7 +650,7 @@ def Test_assign_index()
var bl = 0z11
bl[1] = g:val
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1030: Using a String as a Number: "22"')
+ v9.CheckDefExecAndScriptFailure(lines, ['E1030: Using a String as a Number: "22"', 'E1012: Type mismatch; expected number but got string'])
# should not read the next line when generating "a.b"
var a = {}
@@ -3687,4 +3687,16 @@ def Test_final_var_with_blob_value()
v9.CheckScriptSuccess(lines)
enddef
+" Test for overwriting a script-local function using the s: dictionary
+def Test_override_script_local_func()
+ var lines =<< trim END
+ vim9script
+ def MyFunc()
+ enddef
+ var d: dict<any> = s:
+ d.MyFunc = function('min')
+ END
+ v9.CheckScriptFailure(lines, 'E705: Variable name conflicts with existing function: MyFunc', 5)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 42d09fe..6b1a50d 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -960,6 +960,8 @@ def Test_execute()
assert_equal("\nhello", res)
res = execute(["echo 'here'", "echo 'there'"])
assert_equal("\nhere\nthere", res)
+ res = execute("echo 'hi'\n# foo")
+ assert_equal("\nhi", res)
v9.CheckSourceDefAndScriptFailure(['execute(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
v9.CheckSourceDefFailure(['execute([123])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>')
@@ -2195,6 +2197,7 @@ def Test_indexof()
indexof(l, (i, v) => v.color == 'blue')->assert_equal(1)
indexof(l, (i, v) => v.color == 'blue', {startidx: 1})->assert_equal(1)
indexof(l, (i, v) => v.color == 'blue', {startidx: 2})->assert_equal(3)
+ indexof(l, "")->assert_equal(-1)
var b = 0zdeadbeef
indexof(b, "v:val == 0xef")->assert_equal(3)
@@ -4554,6 +4557,7 @@ enddef
def Test_term_getjob()
CheckRunVimInTerminal
v9.CheckSourceDefAndScriptFailure(['term_getjob(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1'])
+ v9.CheckSourceDefAndScriptSuccess(['assert_true(term_getjob(0) == null_job)'])
enddef
def Test_term_getline()
@@ -4783,8 +4787,6 @@ def Test_typename()
if has('channel')
assert_equal('channel', test_null_channel()->typename())
endif
- assert_equal('class<Unknown>', typename(null_class))
- assert_equal('object<Unknown>', typename(null_object))
var l: list<func(list<number>): number> = [function('min')]
assert_equal('list<func(list<number>): number>', typename(l))
enddef
@@ -5183,10 +5185,26 @@ enddef
def Test_getregion()
assert_equal(['x'], getregion(getpos('.'), getpos('.'))->map((_, _) => 'x'))
-
- v9.CheckSourceDefAndScriptFailure(['getregion(10, getpos("."))'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
- assert_equal([''], getregion(getpos('.'), getpos('.')))
+ assert_equal(['x'], getregionpos(getpos('.'), getpos('.'))->map((_, _) => 'x'))
+
+ v9.CheckSourceDefAndScriptFailure(
+ ['getregion(10, getpos("."))'],
+ ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']
+ )
+ v9.CheckSourceDefAndScriptFailure(
+ ['getregionpos(10, getpos("."))'],
+ ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']
+ )
+ assert_equal(
+ [''],
+ getregion(getpos('.'), getpos('.'))
+ )
+ assert_equal(
+ [[[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]]],
+ getregionpos(getpos('.'), getpos('.'))
+ )
v9.CheckSourceDefExecFailure(['getregion(getpos("a"), getpos("."))'], 'E1209:')
+ v9.CheckSourceDefExecFailure(['getregionpos(getpos("a"), getpos("."))'], 'E1209:')
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index bd06c6e..e92fcc5 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -103,6 +103,18 @@ def Test_class_basic()
END
v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
+ # Comments are allowed after an inline block
+ lines =<< trim END
+ vim9script
+ class Foo
+ static const bar = { # {{{
+ baz: 'qux'
+ } # }}}
+ endclass
+ assert_equal({baz: 'qux'}, Foo.bar)
+ END
+ v9.CheckSourceSuccess(lines)
+
# Try to define a class with the same name as an existing variable
lines =<< trim END
vim9script
@@ -533,6 +545,28 @@ def Test_using_null_class()
@_ = null_class.member
END
v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
+
+ # Test for using a null class as a value
+ lines =<< trim END
+ vim9script
+ echo empty(null_class)
+ END
+ v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
+
+ # Test for using a null class with string()
+ lines =<< trim END
+ vim9script
+ assert_equal('class [unknown]', string(null_class))
+ END
+ v9.CheckSourceSuccess(lines)
+
+ # Test for using a null class with type() and typename()
+ lines =<< trim END
+ vim9script
+ assert_equal(12, type(null_class))
+ assert_equal('class<Unknown>', typename(null_class))
+ END
+ v9.CheckSourceSuccess(lines)
enddef
def Test_class_interface_wrong_end()
@@ -10690,4 +10724,24 @@ def Test_class_definition_in_a_function()
v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
enddef
+" Test for using [] with a class and an object
+def Test_class_object_index()
+ var lines =<< trim END
+ vim9script
+ class A
+ endclass
+ A[10] = 1
+ END
+ v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
+
+ lines =<< trim END
+ vim9script
+ class A
+ endclass
+ var a = A.new()
+ a[10] = 1
+ END
+ v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index 7764b37..5734731 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -309,6 +309,9 @@ def Test_expr2()
g:vals = [1]
endif
assert_equal([1], g:vals)
+
+ # string interpolation with ||
+ assert_equal('true', $"{0 || 1}")
END
v9.CheckDefAndScriptSuccess(lines)
@@ -415,6 +418,7 @@ def Test_expr2_fails()
v9.CheckDefExecAndScriptFailure(['var x = 3', 'if x', 'endif'], 'E1023:', 2)
v9.CheckDefAndScriptFailure(["var x = [] || false"], ['E1012: Type mismatch; expected bool but got list<any>', 'E745:'], 1)
+ v9.CheckDefAndScriptFailure(["var x = $'{false || []}'"], ['E1012: Type mismatch; expected bool but got list<any>', 'E745:'], 1)
var lines =<< trim END
vim9script
@@ -475,6 +479,9 @@ def Test_expr3()
failed = true
endif
assert_false(failed)
+
+ # string interpolation with &&
+ assert_equal('false', $"{1 && 0}")
END
v9.CheckDefAndScriptSuccess(lines)
enddef
@@ -574,6 +581,8 @@ def Test_expr3_fails()
echo true && s
END
v9.CheckDefAndScriptFailure(lines, ['E1012: Type mismatch; expected bool but got string', 'E1135: Using a String as a Bool: "asdf"'])
+
+ v9.CheckDefAndScriptFailure(["var x = $'{true && []}'"], ['E1012: Type mismatch; expected bool but got list<any>', 'E745:'], 1)
enddef
" global variables to use for tests with the "any" type
@@ -2109,6 +2118,12 @@ def Test_expr9_number()
Test()
END
v9.CheckDefAndScriptSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+ eval("10\n")
+ END
+ v9.CheckSourceScriptFailure(lines, "E488: Trailing characters: \n")
enddef
def Test_expr9_float()
@@ -2152,6 +2167,7 @@ def Test_expr9_blob()
v9.CheckDefAndScriptSuccess(lines)
v9.CheckDefAndScriptFailure(["var x = 0z123"], 'E973:', 1)
+ v9.CheckDefAndScriptFailure(["var x = null_blox"], ['E1001:', 'E121:'], 1)
enddef
def Test_expr9_string()
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index b008929..d07bbfb 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -4633,6 +4633,19 @@ def Run_Test_keytyped_in_nested_function()
g:StopVimInTerminal(buf)
enddef
+" Test for test_override('defcompile')
+def Test_test_override_defcompile()
+ var lines =<< trim END
+ vim9script
+ def Foo()
+ xxx
+ enddef
+ END
+ test_override('defcompile', 1)
+ v9.CheckScriptFailure(lines, 'E476: Invalid command: xxx')
+ test_override('defcompile', 0)
+enddef
+
" The following messes up syntax highlight, keep near the end.
if has('python3')
def Test_python3_command()
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index 581925d..fb309cb 100644
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -3068,7 +3068,10 @@ def Test_vim9_import_symlink()
var lines =<< trim END
vim9script
import autoload 'bar.vim'
- g:resultFunc = bar.Func()
+ def FooFunc(): string
+ return bar.Func()
+ enddef
+ g:resultFunc = FooFunc()
g:resultValue = bar.value
END
writefile(lines, 'Xto/plugin/foo.vim')
@@ -3222,4 +3225,109 @@ def Test_autoload_import_dict_func()
&rtp = save_rtp
enddef
+" Test for changing the value of an imported Dict item
+def Test_set_imported_dict_item()
+ var lines =<< trim END
+ vim9script
+ export var dict1: dict<bool> = {bflag: false}
+ export var dict2: dict<dict<bool>> = {x: {bflag: false}}
+ END
+ writefile(lines, 'XimportedDict.vim', 'D')
+
+ lines =<< trim END
+ vim9script
+ import './XimportedDict.vim'
+ assert_equal(XimportedDict.dict1.bflag, false)
+ XimportedDict.dict1.bflag = true
+ assert_equal(XimportedDict.dict1.bflag, true)
+ XimportedDict.dict2.x.bflag = true
+ assert_equal(XimportedDict.dict2.x.bflag, true)
+ assert_equal('bool', typename(XimportedDict.dict1.bflag))
+ assert_equal('bool', typename(XimportedDict.dict2.x.bflag))
+ assert_equal('bool', typename(XimportedDict.dict2['x'].bflag))
+ assert_equal('bool', typename(XimportedDict.dict2.x['bflag']))
+
+ assert_equal(XimportedDict.dict1['bflag'], true)
+ XimportedDict.dict1['bflag'] = false
+ assert_equal(XimportedDict.dict1.bflag, false)
+ XimportedDict.dict2['x']['bflag'] = false
+ assert_equal(XimportedDict.dict2['x'].bflag, false)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+ import './XimportedDict.vim'
+ XimportedDict.dict2.x.bflag = []
+ END
+ v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected bool but got list<any>', 3)
+enddef
+
+" Test for changing the value of an imported class member
+def Test_set_imported_class_member()
+ var lines =<< trim END
+ vim9script
+ export class Config
+ public static var option = false
+ endclass
+ END
+ writefile(lines, 'XimportedClass.vim', 'D')
+
+ lines =<< trim END
+ vim9script
+ import './XimportedClass.vim' as foo
+ type FooConfig = foo.Config
+ assert_equal(false, FooConfig.option)
+ assert_equal(false, foo.Config.option)
+ foo.Config.option = true
+ assert_equal(true, foo.Config.option)
+ assert_equal(true, FooConfig.option)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
+" Test for using an imported function from the vimrc file.  The function is
+" defined in the 'start' directory of a package.
+def Test_import_from_vimrc()
+ mkdir('Ximport/pack/foobar/start/foo/autoload', 'pR')
+ var lines =<< trim END
+ vim9script
+ export def Foo()
+ writefile(['Foo called'], 'Xoutput.log')
+ enddef
+ END
+ writefile(lines, 'Ximport/pack/foobar/start/foo/autoload/foo.vim')
+ lines =<< trim END
+ vim9script
+ set packpath+=./Ximport
+ try
+ import autoload 'foo.vim'
+ foo.Foo()
+ catch
+ writefile(['Failed to import foo.vim'], 'Xoutput.log')
+ endtry
+ qall!
+ END
+ writefile(lines, 'Xvimrc', 'D')
+ g:RunVim([], [], '-u Xvimrc')
+ assert_equal(['Foo called'], readfile('Xoutput.log'))
+ delete('Xoutput.log')
+enddef
+
+" Test for changing a locked imported variable
+def Test_import_locked_var()
+ var lines =<< trim END
+ vim9script
+ export var Foo: number = 10
+ lockvar Foo
+ END
+ writefile(lines, 'Ximportlockedvar.vim', 'D')
+ lines =<< trim END
+ vim9script
+ import './Ximportlockedvar.vim' as Bar
+ Bar.Foo = 20
+ END
+ v9.CheckScriptFailure(lines, 'E741: Value is locked: Foo', 3)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index a3f21be..0b17150 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2159,6 +2159,18 @@ def Test_echo_cmd()
assert_match('^two$', g:Screenline(&lines))
v9.CheckDefFailure(['echo "xxx"# comment'], 'E488:')
+
+ # Test for echoing a script local function name
+ var lines =<< trim END
+ vim9script
+ def ScriptLocalEcho()
+ enddef
+ echo ScriptLocalEcho
+ END
+ new
+ setline(1, lines)
+ assert_match('<SNR>\d\+_ScriptLocalEcho', execute('source')->split("\n")[0])
+ bw!
enddef
def Test_echomsg_cmd()
@@ -2510,8 +2522,20 @@ def Test_for_loop()
reslist->add('x')
endfor
assert_equal(['x', 'x', 'x'], reslist)
+
+ # Test for trying to use the loop variable "_" inside the loop
+ for _ in "a"
+ assert_fails('echo _', 'E1181: Cannot use an underscore here')
+ endfor
END
v9.CheckDefAndScriptSuccess(lines)
+
+ lines =<< trim END
+ for i : number : [1, 2]
+ echo i
+ endfor
+ END
+ v9.CheckSourceDefAndScriptFailure(lines, 'E1059: No white space allowed before colon: : [1, 2]', 1)
enddef
def Test_for_loop_list_of_lists()
@@ -4551,11 +4575,11 @@ def Run_Test_debug_with_lambda()
Func()
END
writefile(lines, 'XdebugFunc', 'D')
- var buf = g:RunVimInTerminal('-S XdebugFunc', {rows: 6, wait_for_ruler: 0})
- g:WaitForAssert(() => assert_match('^>', term_getline(buf, 6)))
+ var buf = g:RunVimInTerminal('-S XdebugFunc', {rows: 10, wait_for_ruler: 0})
+ g:WaitForAssert(() => assert_match('^>', term_getline(buf, 10)))
term_sendkeys(buf, "cont\<CR>")
- g:WaitForAssert(() => assert_match('\[0\]', term_getline(buf, 5)))
+ g:WaitForAssert(() => assert_match('\[0\]', term_getline(buf, 9)))
g:StopVimInTerminal(buf)
enddef
@@ -4586,12 +4610,12 @@ def Run_Test_debug_running_out_of_lines()
Crash()
END
writefile(lines, 'XdebugFunc', 'D')
- var buf = g:RunVimInTerminal('-S XdebugFunc', {rows: 6, wait_for_ruler: 0})
- g:WaitForAssert(() => assert_match('^>', term_getline(buf, 6)))
+ var buf = g:RunVimInTerminal('-S XdebugFunc', {rows: 10, wait_for_ruler: 0})
+ g:WaitForAssert(() => assert_match('^>', term_getline(buf, 10)))
term_sendkeys(buf, "next\<CR>")
g:TermWait(buf)
- g:WaitForAssert(() => assert_match('^>', term_getline(buf, 6)))
+ g:WaitForAssert(() => assert_match('^>', term_getline(buf, 10)))
term_sendkeys(buf, "cont\<CR>")
g:TermWait(buf)
@@ -5002,7 +5026,7 @@ def Test_invalid_type_in_for()
enddef
defcompile
END
- v9.CheckSourceFailure(lines, 'E1010: Type not recognized: x in range(10)', 1)
+ v9.CheckSourceFailure(lines, 'E1010: Type not recognized: x', 1)
enddef
" Test for using a line break between the variable name and the type in a for
@@ -5055,6 +5079,56 @@ def Test_eval_lambda_block()
v9.CheckSourceSuccess(lines)
enddef
+" Test for using various null values
+def Test_null_values()
+ var lines =<< trim END
+ var nullValues = [
+ [null, 1, 'null', 7, 'special'],
+ [null_blob, 1, '0z', 10, 'blob'],
+ [null_channel, 1, 'channel fail', 9, 'channel'],
+ [null_dict, 1, '{}', 4, 'dict<any>'],
+ [null_function, 1, "function('')", 2, 'func(...): unknown'],
+ [null_job, 1, 'no process', 8, 'job'],
+ [null_list, 1, '[]', 3, 'list<any>'],
+ [null_object, 1, 'object of [unknown]', 13, 'object<Unknown>'],
+ [null_partial, 1, "function('')", 2, 'func(...): unknown'],
+ [null_string, 1, "''", 1, 'string']
+ ]
+
+ for [Val, emptyExp, stringExp, typeExp, typenameExp] in nullValues
+ assert_equal(emptyExp, empty(Val))
+ assert_equal(stringExp, string(Val))
+ assert_equal(typeExp, type(Val))
+ assert_equal(typenameExp, typename(Val))
+ assert_equal(Val, copy(Val))
+ assert_equal(-1, test_refcount(Val))
+ endfor
+ END
+ v9.CheckSourceDefAndScriptSuccess(lines)
+enddef
+
+" Test for using an unknown type in a typecast
+def Test_unknown_type_in_typecast()
+ var lines =<< trim END
+ vim9script
+ var a = <MyType>b
+ END
+ v9.CheckSourceFailure(lines, 'E1010: Type not recognized: MyType', 2)
+
+ lines =<< trim END
+ vim9script
+ var Fn = <funcx(number, number): number>b
+ END
+ v9.CheckSourceFailure(lines, 'E1010: Type not recognized: funcx(number, number): number', 2)
+
+ # Wrong type in a type cast
+ lines =<< trim END
+ vim9script
+ var i: number = <number>true
+ END
+ v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got bool', 2)
+enddef
+
" Keep this last, it messes up highlighting.
def Test_substitute_cmd()
new
diff --git a/src/testdir/test_vim9_typealias.vim b/src/testdir/test_vim9_typealias.vim
index cf540c2..2792d45 100644
--- a/src/testdir/test_vim9_typealias.vim
+++ b/src/testdir/test_vim9_typealias.vim
@@ -363,7 +363,7 @@ def Test_typealias_import()
var myNum: A.SomeType = 10
END
- v9.CheckScriptFailure(lines, 'E1010: Type not recognized: A.SomeType = 10', 4)
+ v9.CheckScriptFailure(lines, 'E1010: Type not recognized: A.SomeType', 4)
# Use a type alias that is not exported
lines =<< trim END
diff --git a/src/testdir/test_viminfo.vim b/src/testdir/test_viminfo.vim
index 1f4a72d..7aab271 100644
--- a/src/testdir/test_viminfo.vim
+++ b/src/testdir/test_viminfo.vim
@@ -1299,4 +1299,34 @@ func Test_viminfo_merge_old_jumplist()
bw!
endfunc
+func Test_viminfo_oldfiles_filter()
+ let v:oldfiles = []
+ let _viminfofile = &viminfofile
+ let &viminfofile=''
+ let lines = [
+ \ '# comment line',
+ \ '*encoding=utf-8',
+ \ "> /tmp/vimrc_one.vim",
+ \ "\t\"\t11\t0",
+ \ "",
+ \ "> /tmp/foobar.txt",
+ \ "\t\"\t11\t0",
+ \ "",
+ \ ]
+ call writefile(lines, 'Xviminfo1', 'D')
+ rviminfo! Xviminfo1
+ new
+ " filter returns a single item
+ let a = execute('filter /vim/ oldfiles')->split('\n')
+ call assert_equal(1, len(a))
+ " filter returns more than a single match
+ let a = execute('filter #tmp# oldfiles')->split('\n')
+ call assert_equal(2, len(a))
+ " don't get prompted for the file, but directly open it
+ filter /vim/ browse oldfiles
+ call assert_equal("/tmp/vimrc_one.vim", expand("%"))
+ bw
+ let &viminfofile = _viminfofile
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim
index 0c4aedb..8976779 100644
--- a/src/testdir/test_vimscript.vim
+++ b/src/testdir/test_vimscript.vim
@@ -7509,6 +7509,14 @@ func Test_for_over_string()
let res ..= c .. '-'
endfor
call assert_equal('', res)
+
+ " Test for using "_" as the loop variable
+ let i = 0
+ let s = 'abc'
+ for _ in s
+ call assert_equal(s[i], _)
+ let i += 1
+ endfor
endfunc
" Test for deeply nested :source command {{{1
diff --git a/src/testdir/test_virtualedit.vim b/src/testdir/test_virtualedit.vim
index 48d4aa0..3d3fdd0 100644
--- a/src/testdir/test_virtualedit.vim
+++ b/src/testdir/test_virtualedit.vim
@@ -709,5 +709,27 @@ func Test_virtualedit_replace_after_tab()
bwipe!
endfunc
+" Test that setpos('.') and cursor() behave the same for v:maxcol
+func Test_virtualedit_set_cursor_pos_maxcol()
+ new
+ set virtualedit=all
+
+ call setline(1, 'foobar')
+ exe "normal! V\<Esc>"
+ call assert_equal([0, 1, 1, 0], getpos("'<"))
+ call assert_equal([0, 1, v:maxcol, 0], getpos("'>"))
+ let pos = getpos("'>")
+
+ call cursor(1, 1)
+ call setpos('.', pos)
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+
+ call cursor(1, 1)
+ call cursor(pos[1:])
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+
+ set virtualedit&
+ bwipe!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index adcc3e9..3750ebf 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1631,6 +1631,22 @@ func Test_visual_substitute_visual()
bwipe!
endfunc
+func Test_virtualedit_exclusive_selection()
+ new
+ set virtualedit=all selection=exclusive
+
+ call setline(1, "a\tb")
+ normal! 0v8ly
+ call assert_equal("a\t", getreg('"'))
+ normal! 0v6ly
+ call assert_equal('a ', getreg('"'))
+ normal! 06lv2ly
+ call assert_equal(' ', getreg('"'))
+
+ set virtualedit& selection&
+ bwipe!
+endfunc
+
func Test_visual_getregion()
let lines =<< trim END
new
@@ -1640,18 +1656,52 @@ func Test_visual_getregion()
#" Visual mode
call cursor(1, 1)
call feedkeys("\<ESC>vjl", 'tx')
+
call assert_equal(['one', 'tw'],
\ 'v'->getpos()->getregion(getpos('.')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
+ \ ],
+ \ 'v'->getpos()->getregionpos(getpos('.')))
+
call assert_equal(['one', 'tw'],
\ '.'->getpos()->getregion(getpos('v')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
+ \ ],
+ \ '.'->getpos()->getregionpos(getpos('v')))
+
call assert_equal(['o'],
\ 'v'->getpos()->getregion(getpos('v')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ ],
+ \ 'v'->getpos()->getregionpos(getpos('v')))
+
call assert_equal(['w'],
\ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 0]],
+ \ ],
+ \ '.'->getpos()->getregionpos(getpos('.'), {'type': 'v' }))
+
call assert_equal(['one', 'two'],
\ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getpos('.')->getregionpos(getpos('v'), {'type': 'V' }))
+
call assert_equal(['on', 'tw'],
\ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]],
+ \ ],
+ \ getpos('.')->getregionpos(getpos('v'), {'type': "\<C-v>" }))
#" Line visual mode
call cursor(1, 1)
@@ -1698,6 +1748,9 @@ func Test_visual_getregion()
\ "'a"->getpos()->getregion(getpos("'a"), {'type': 'V' }))
call assert_equal(['one', 'two'],
\ "."->getpos()->getregion(getpos("'a"), {'type': "\<c-v>" }))
+ call feedkeys("\<ESC>jVj\<ESC>", 'tx')
+ call assert_equal(['two', 'three'], getregion(getpos("'<"), getpos("'>")))
+ call assert_equal(['two', 'three'], getregion(getpos("'>"), getpos("'<")))
#" Using List
call cursor(1, 1)
@@ -1717,24 +1770,185 @@ func Test_visual_getregion()
call feedkeys("\<ESC>Vjj", 'tx')
call assert_equal(['one', 'two', 'three'],
\ getregion(getpos('v'), getpos('.'), {'type': 'V' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'V' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'V', 'eol': v:true }))
#" Multiline with block visual mode
call cursor(1, 1)
call feedkeys("\<ESC>\<C-v>jj", 'tx')
call assert_equal(['o', 't', 't'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 1, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
call cursor(1, 1)
call feedkeys("\<ESC>\<C-v>jj$", 'tx')
call assert_equal(['one', 'two', 'three'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
#" 'virtualedit'
set virtualedit=all
+
call cursor(1, 1)
call feedkeys("\<ESC>\<C-v>10ljj$", 'tx')
call assert_equal(['one ', 'two ', 'three '],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 3]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 3]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 1]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>\<C-v>hkk", 'tx')
+ call assert_equal([' ', ' ', 'ee'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
+ \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
+ \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 2]],
+ \ [[bufnr('%'), 2, 4, 0], [bufnr('%'), 2, 4, 2]],
+ \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>\<C-v>kk", 'tx')
+ call assert_equal([' ', ' ', 'e'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
+ \ [[bufnr('%'), 2, 0, 0], [bufnr('%'), 2, 0, 0]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 1], [bufnr('%'), 1, 4, 2]],
+ \ [[bufnr('%'), 2, 4, 1], [bufnr('%'), 2, 4, 2]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", 'eol': v:true }))
+
+ call cursor(1, 3)
+ call feedkeys("\<ESC>vjj4l", 'tx')
+ call assert_equal(['e', 'two', 'three '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(1, 3)
+ call feedkeys("\<ESC>lvjj3l", 'tx')
+ call assert_equal(['', 'two', 'three '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 6, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>v3l", 'tx')
+ call assert_equal(['e '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 6, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>lv3l", 'tx')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 6, 0], [bufnr('%'), 3, 6, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
+ call cursor(3, 5)
+ call feedkeys("\<ESC>3lv3l", 'tx')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 3, 6, 2], [bufnr('%'), 3, 6, 6]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', 'eol': v:true }))
+
set virtualedit&
#" using wrong types for positions
@@ -1743,9 +1957,21 @@ func Test_visual_getregion()
call assert_fails("call getregion(1, 2)", 'E1211:')
call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:')
+ call assert_fails("call getregionpos(1, 2)", 'E1211:')
+ call assert_fails("call getregionpos(getpos('.'), {})", 'E1211:')
+ call assert_fails(':echo "."->getpos()->getregionpos("$", [])', 'E1211:')
#" using invalid value for "type"
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
+ call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
+ call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
+ call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'v0' })", 'E475:')
+ call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
+ call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': 'V0' })", 'E475:')
+ call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
+ call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>0' })", 'E475:')
+ call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
+ call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '\<C-v>1:' })", 'E475:')
#" using a mark from another buffer to current buffer
new
@@ -1756,13 +1982,20 @@ func Test_visual_getregion()
call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
call assert_equal([], getregion(getpos("'A"), getpos('.'), {'type': 'v' }))
+ call assert_equal([], getregionpos(getpos('.'), getpos("'A"), {'type': 'v' }))
+ call assert_equal([], getregionpos(getpos("'A"), getpos('.'), {'type': 'v' }))
#" using two marks from another buffer
wincmd p
normal! GmB
wincmd p
call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
- call assert_equal(['9'], getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
+ call assert_equal(['9'],
+ \ getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
+ call assert_equal([
+ \ [[g:buf, 10, 1, 0], [g:buf, 10, 1, 0]],
+ \ ],
+ \ getregionpos(getpos("'B"), getpos("'A"), {'type': 'v' }))
#" using two positions from another buffer
for type in ['v', 'V', "\<C-V>"]
@@ -1773,6 +2006,12 @@ func Test_visual_getregion()
call assert_equal(range(10)->mapnew('string(v:val)'),
\ getregion([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
\ {'type': type, 'exclusive': exclusive }))
+ call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
+ \ getregionpos([g:buf, 1, 1, 0], [g:buf, 10, 2, 0],
+ \ {'type': type, 'exclusive': exclusive }))
+ call assert_equal(range(1, 10)->mapnew('repeat([[g:buf, v:val, 1, 0]], 2)'),
+ \ getregionpos([g:buf, 10, 2, 0], [g:buf, 1, 1, 0],
+ \ {'type': type, 'exclusive': exclusive }))
endfor
endfor
@@ -1785,17 +2024,18 @@ func Test_visual_getregion()
call assert_fails('call getregion([g:buf, 10, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 3, 0])', 'E964:')
call assert_fails('call getregion([g:buf, 10, 3, 0], [g:buf, 1, 1, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 1, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 1, 0, 0])', 'E964:')
#" using invalid buffer
call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
exe $':{g:buf}bwipe!'
unlet g:buf
+ bwipe!
END
call v9.CheckLegacyAndVim9Success(lines)
- bwipe!
-
let lines =<< trim END
#" Selection in starts or ends in the middle of a multibyte character
new
@@ -1804,35 +2044,119 @@ func Test_visual_getregion()
\ "\U0001f1e6\u00ab\U0001f1e7\u00ab\U0001f1e8\u00ab\U0001f1e9",
\ "1234567890"
\ ])
+
call cursor(1, 3)
call feedkeys("\<Esc>\<C-v>ljj", 'xt')
call assert_equal(['cd', "\u00ab ", '34'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 5, 0], [bufnr('%'), 2, 7, 1]],
+ \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
call cursor(1, 4)
call feedkeys("\<Esc>\<C-v>ljj", 'xt')
call assert_equal(['de', "\U0001f1e7", '45'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 4, 0], [bufnr('%'), 1, 5, 0]],
+ \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 10, 0]],
+ \ [[bufnr('%'), 3, 4, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
call cursor(1, 5)
call feedkeys("\<Esc>\<C-v>jj", 'xt')
call assert_equal(['e', ' ', '5'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 5, 0]],
+ \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 7, 2]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal(['efghijk«', '🇦«🇧«🇨«🇩', '12345'],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 22, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 5)
+ call feedkeys("\<Esc>\<C-v>5l2j", 'xt')
+ call assert_equal(['efghij', ' «🇨« ', '567890'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 10, 0]],
+ \ [[bufnr('%'), 2, 7, 1], [bufnr('%'), 2, 19, 1]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 4)
+ call feedkeys("\<Esc>\<C-v>02j", 'xt')
+ call assert_equal(['abcd', '🇦« ', '1234'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 7, 1]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ #" characterwise selection with multibyte chars
call cursor(1, 1)
call feedkeys("\<Esc>vj", 'xt')
call assert_equal(['abcdefghijk«', "\U0001f1e6"],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ set selection=exclusive
+ call feedkeys('l', 'xt')
+ call assert_equal(['abcdefghijk«', "\U0001f1e6"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 4, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
#" marks on multibyte chars
- :set selection=exclusive
call setpos("'a", [0, 1, 11, 0])
call setpos("'b", [0, 2, 16, 0])
call setpos("'c", [0, 2, 0, 0])
call cursor(1, 1)
+
call assert_equal(['ghijk', '🇨«🇩'],
- \ getregion(getpos("'a"), getpos("'b"), {'type': "\<c-v>" }))
+ \ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 7, 0], [bufnr('%'), 1, 11, 0]],
+ \ [[bufnr('%'), 2, 13, 0], [bufnr('%'), 2, 22, 0]],
+ \ ],
+ \ getregionpos(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
+
call assert_equal(['k«', '🇦«🇧«🇨'],
\ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 16, 0]],
+ \ ],
+ \ getregionpos(getpos("'a"), getpos("'b"), {'type': 'v' }))
+
call assert_equal(['k«'],
\ getregion(getpos("'a"), getpos("'c"), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 11, 0], [bufnr('%'), 1, 13, 0]],
+ \ ],
+ \ getregionpos(getpos("'a"), getpos("'c"), {'type': 'v' }))
#" use inclusive selection, although 'selection' is exclusive
call setpos("'a", [0, 1, 11, 0])
@@ -1855,12 +2179,12 @@ func Test_visual_getregion()
call assert_equal(['abcdefghijk«'],
\ getregion(getpos("'a"), getpos("'b"),
\ {'type': 'V', 'exclusive': 1 }))
- :set selection&
+
+ set selection&
+ bwipe!
END
call v9.CheckLegacyAndVim9Success(lines)
- bwipe!
-
let lines =<< trim END
#" Exclusive selection
new
@@ -1891,51 +2215,346 @@ func Test_visual_getregion()
call assert_equal(["c", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
set selection&
+ bwipe!
#" Exclusive selection 2
new
call setline(1, ["a\tc", "x\tz", '', ''])
+
call cursor(1, 1)
call feedkeys("\<Esc>v2l", 'xt')
call assert_equal(["a\t"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>v$G", 'xt')
call assert_equal(["a\tc", "x\tz", ''],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>v$j", 'xt')
call assert_equal(["a\tc", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>\<C-v>$j", 'xt')
call assert_equal(["a\tc", "x\tz"],
\ getregion(getpos('v'), getpos('.'),
\ {'exclusive': v:true, 'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'exclusive': v:true, 'type': "\<C-v>" }))
+
call cursor(1, 1)
call feedkeys("\<Esc>\<C-v>$G", 'xt')
call assert_equal(["a", "x", '', ''],
\ getregion(getpos('v'), getpos('.'),
\ {'exclusive': v:true, 'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ [[bufnr('%'), 4, 0, 0], [bufnr('%'), 4, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'exclusive': v:true, 'type': "\<C-v>" }))
+
call cursor(1, 1)
call feedkeys("\<Esc>wv2j", 'xt')
call assert_equal(["c", "x\tz"],
\ getregion(getpos('v'), getpos('.'), {'exclusive': v:true }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'exclusive': v:true }))
- #" virtualedit
+ #" 'virtualedit' with exclusive selection
set selection=exclusive
set virtualedit=all
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>vj", 'xt')
+ call assert_equal(["a\tc"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
call cursor(1, 1)
- call feedkeys("\<Esc>2lv2lj", 'xt')
+ call feedkeys("\<Esc>v8l", 'xt')
+ call assert_equal(["a\t"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v6l", 'xt')
+ call assert_equal(['a '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 5]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call feedkeys('j', 'xt')
call assert_equal([' c', 'x '],
\ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
+ call assert_equal([' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 2, 7]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 7]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 2]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 2]],
+ \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
call cursor(1, 1)
call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
call assert_equal([' ', ' ', ' '],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
- set virtualedit&
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ #" 'virtualedit' with inclusive selection
set selection&
+ call cursor(1, 1)
+ call feedkeys("\<Esc>vj", 'xt')
+ call assert_equal(["a\tc", 'x'],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 1, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v8l", 'xt')
+ call assert_equal(["a\tc"],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>v6l", 'xt')
+ call assert_equal(['a '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 6]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6lv2l", 'xt')
+ call assert_equal([' c'],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2lv2l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call feedkeys('j', 'xt')
+ call assert_equal([' c', 'x '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>6l\<C-v>2lj", 'xt')
+ call assert_equal([' c', ' z'],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 5], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 2, 3]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 3]],
+ \ [[bufnr('%'), 3, 1, 1], [bufnr('%'), 3, 1, 4]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ call cursor(1, 1)
+ call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
+ \ [[bufnr('%'), 3, 0, 0], [bufnr('%'), 3, 0, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 2, 1], [bufnr('%'), 1, 2, 4]],
+ \ [[bufnr('%'), 2, 2, 1], [bufnr('%'), 2, 2, 4]],
+ \ [[bufnr('%'), 3, 1, 2], [bufnr('%'), 3, 1, 5]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ set virtualedit&
+ bwipe!
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ #" 'virtualedit' with TABs at end of line
+ new
+ set virtualedit=all
+ call setline(1, ["\t", "a\t", "aa\t"])
+
+ call feedkeys("gg06l\<C-v>3l2j", 'xt')
+ call assert_equal([' ', ' ', ' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 2, 0]],
+ \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 3, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
+ \ [[bufnr('%'), 2, 2, 5], [bufnr('%'), 2, 3, 2]],
+ \ [[bufnr('%'), 3, 3, 4], [bufnr('%'), 3, 4, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': "\<C-v>", "eol": v:true }))
+
+ call feedkeys("gg06lv3l", 'xt')
+ call assert_equal([' '],
+ \ getregion(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 1, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 6], [bufnr('%'), 1, 2, 2]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'),
+ \ {'type': 'v', "eol": v:true }))
+
+ set virtualedit&
bwipe!
END
call v9.CheckLegacyAndVim9Success(lines)
@@ -1955,4 +2574,144 @@ func Test_getregion_invalid_buf()
bwipe!
endfunc
+func Test_getregion_after_yank()
+ func! Check_Results(type)
+ call assert_equal(g:expected_region,
+ \ getregion(getpos("'["), getpos("']"), #{ type: a:type }))
+ call assert_equal(g:expected_regionpos,
+ \ getregionpos(getpos("'["), getpos("']"), #{ type: a:type }))
+ call assert_equal(g:expected_region,
+ \ getregion(getpos("']"), getpos("'["), #{ type: a:type }))
+ call assert_equal(g:expected_regionpos,
+ \ getregionpos(getpos("']"), getpos("'["), #{ type: a:type }))
+ let g:checked = 1
+ endfunc
+
+ autocmd TextYankPost *
+ \ : if v:event.operator ==? 'y'
+ \ | call Check_Results(v:event.regtype)
+ \ | endif
+
+ new
+ call setline(1, ['abcd', 'efghijk', 'lmn'])
+
+ let g:expected_region = ['abcd']
+ let g:expected_regionpos = [
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ ]
+ let g:checked = 0
+ normal yy
+ call assert_equal(1, g:checked)
+ call Check_Results(getregtype('"'))
+
+ let g:expected_region = ['cd', 'ghijk', 'n']
+ let g:expected_regionpos = [
+ \ [[bufnr('%'), 1, 3, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 3, 0], [bufnr('%'), 2, 7, 0]],
+ \ [[bufnr('%'), 3, 3, 0], [bufnr('%'), 3, 3, 0]],
+ \ ]
+ let g:checked = 0
+ call feedkeys("gg0ll\<C-V>jj$y", 'tx')
+ call assert_equal(1, g:checked)
+ call Check_Results(getregtype('"'))
+ call assert_equal(g:expected_region, getreg('"', v:true, v:true))
+
+ let g:expected_region = ['bc', 'fg', 'mn']
+ let g:expected_regionpos = [
+ \ [[bufnr('%'), 1, 2, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 3, 0]],
+ \ [[bufnr('%'), 3, 2, 0], [bufnr('%'), 3, 3, 0]],
+ \ ]
+ let g:checked = 0
+ call feedkeys("gg0l\<C-V>jjly", 'tx')
+ call assert_equal(1, g:checked)
+ call Check_Results(getregtype('"'))
+ call assert_equal(g:expected_region, getreg('"', v:true, v:true))
+
+ bwipe!
+
+ new
+ let lines = ['asdfghjkl', '«口=口»', 'qwertyuiop', '口口=口口', 'zxcvbnm']
+ call setline(1, lines)
+
+ let g:expected_region = lines
+ let g:expected_regionpos = [
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 9, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 11, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
+ \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 13, 0]],
+ \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 7, 0]],
+ \ ]
+ let g:checked = 0
+ call feedkeys('ggyG', 'tx')
+ call assert_equal(1, g:checked)
+ call Check_Results(getregtype('"'))
+ call assert_equal(g:expected_region, getreg('"', v:true, v:true))
+
+ let g:expected_region = ['=口»', 'qwertyuiop', '口口=口']
+ let g:expected_regionpos = [
+ \ [[bufnr('%'), 2, 6, 0], [bufnr('%'), 2, 11, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 10, 0]],
+ \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 10, 0]],
+ \ ]
+ let g:checked = 0
+ call feedkeys('2gg02lv2j2ly', 'tx')
+ call assert_equal(1, g:checked)
+ call Check_Results(getregtype('"'))
+ call assert_equal(g:expected_region, getreg('"', v:true, v:true))
+
+ let g:expected_region = ['asdf', '«口=', 'qwer', '口口', 'zxcv']
+ let g:expected_regionpos = [
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 6, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 4, 0]],
+ \ [[bufnr('%'), 4, 1, 0], [bufnr('%'), 4, 6, 0]],
+ \ [[bufnr('%'), 5, 1, 0], [bufnr('%'), 5, 4, 0]],
+ \ ]
+ let g:checked = 0
+ call feedkeys("G0\<C-V>3l4ky", 'tx')
+ call assert_equal(1, g:checked)
+ call Check_Results(getregtype('"'))
+ call assert_equal(g:expected_region, getreg('"', v:true, v:true))
+
+ let g:expected_region = ['ghjkl', '口»', 'tyuiop', '=口口', 'bnm']
+ let g:expected_regionpos = [
+ \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 9, 0]],
+ \ [[bufnr('%'), 2, 7, 0], [bufnr('%'), 2, 11, 0]],
+ \ [[bufnr('%'), 3, 5, 0], [bufnr('%'), 3, 10, 0]],
+ \ [[bufnr('%'), 4, 7, 0], [bufnr('%'), 4, 13, 0]],
+ \ [[bufnr('%'), 5, 5, 0], [bufnr('%'), 5, 7, 0]],
+ \ ]
+ let g:checked = 0
+ call feedkeys("G04l\<C-V>$4ky", 'tx')
+ call assert_equal(1, g:checked)
+ call Check_Results(getregtype('"'))
+ call assert_equal(g:expected_region, getreg('"', v:true, v:true))
+
+ bwipe!
+
+ unlet g:expected_region
+ unlet g:expected_regionpos
+ unlet g:checked
+ autocmd! TextYankPost
+ delfunc Check_Results
+endfunc
+
+func Test_visual_block_cursor_delete()
+ new
+ call setline(1, 'ab')
+ exe ":norm! $\<c-v>hI\<Del>\<ESC>"
+ call assert_equal(['b'], getline(1, 1))
+ bwipe!
+endfunc
+
+func Test_visual_block_cursor_insert_enter()
+ new
+ call setline(1, ['asdf asdf', 'asdf asdf', 'asdf asdf', 'asdf asdf'])
+ call cursor(1, 5)
+ exe ":norm! \<c-v>3jcw\<cr>"
+ call assert_equal(['asdfw', 'asdf', 'asdfasdf', 'asdfasdf', 'asdfasdf'], getline(1, '$'))
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_xdg.vim b/src/testdir/test_xdg.vim
index 6f35b72..b9ec3c7 100644
--- a/src/testdir/test_xdg.vim
+++ b/src/testdir/test_xdg.vim
@@ -80,6 +80,7 @@ func Test_xdg_runtime_files()
call assert_match('XfakeHOME/\.vimrc', $MYVIMRC)
call filter(g:, {idx, _ -> idx =~ '^rc'})
call assert_equal(#{rc_one: 'one', rc: '.vimrc'}, g:)
+ call assert_match('XfakeHOME/\.vim/view', &viewdir)
call writefile(v:errors, 'Xresult')
quit
END
@@ -94,6 +95,7 @@ func Test_xdg_runtime_files()
call assert_match('XfakeHOME/\.vim/vimrc', $MYVIMRC)
call filter(g:, {idx, _ -> idx =~ '^rc'})
call assert_equal(#{rc_two: 'two', rc: '.vim/vimrc'}, g:)
+ call assert_match('XfakeHOME/\.vim/view', &viewdir)
call writefile(v:errors, 'Xresult')
quit
END
@@ -112,6 +114,7 @@ func Test_xdg_runtime_files()
call assert_match('XfakeHOME/\.config/vim/vimrc', $MYVIMRC, msg)
call filter(g:, {idx, _ -> idx =~ '^rc'})
call assert_equal(#{rc_three: 'three', rc: '.config/vim/vimrc'}, g:)
+ call assert_match('XfakeHOME/\.config/vim/view', &viewdir)
call writefile(v:errors, 'Xresult')
quit
END
@@ -128,6 +131,7 @@ func Test_xdg_runtime_files()
call assert_match('XfakeHOME/xdg/vim/vimrc', $MYVIMRC, msg)
call filter(g:, {idx, _ -> idx =~ '^rc'})
call assert_equal(#{rc_four: 'four', rc: 'xdg/vim/vimrc'}, g:)
+ call assert_match('XfakeHOME/xdg/vim/view, &viewdir)
call writefile(v:errors, 'Xresult')
quit
END
diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim
index 7a2771e..a91a1fc 100644
--- a/src/testdir/test_xxd.vim
+++ b/src/testdir/test_xxd.vim
@@ -411,6 +411,22 @@ func Test_xxd_max_cols()
endfor
endfunc
+
+" This used to trigger a buffer overflow (#14738)
+func Test_xxd_buffer_overflow()
+ CheckUnix
+ if system('file ' .. s:xxd_cmd) =~ '32-bit'
+ throw 'Skipped: test only works on 64-bit architecture'
+ endif
+ new
+ let input = repeat('A', 256)
+ call writefile(['-9223372036854775808: ' . repeat("\e[1;32m41\e[0m ", 256) . ' ' . repeat("\e[1;32mA\e[0m", 256)], 'Xxdexpected', 'D')
+ exe 'r! printf ' . input . '| ' . s:xxd_cmd . ' -Ralways -g1 -c256 -d -o 9223372036854775808 > Xxdout'
+ call assert_equalfile('Xxdexpected', 'Xxdout')
+ call delete('Xxdout')
+ bwipe!
+endfunc
+
" -c0 selects the format specific default column value, as if no -c was given
" except for -ps, where it disables extra newlines
func Test_xxd_c0_is_def_cols()
diff --git a/src/testing.c b/src/testing.c
index 33de3a5..3e9e077 100644
--- a/src/testing.c
+++ b/src/testing.c
@@ -1051,6 +1051,8 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
ml_get_alloc_lines = val;
else if (STRCMP(name, (char_u *)"autoload") == 0)
override_autoload = val;
+ else if (STRCMP(name, (char_u *)"defcompile") == 0)
+ override_defcompile = val;
else if (STRCMP(name, (char_u *)"ALL") == 0)
{
disable_char_avail_for_testing = FALSE;
diff --git a/src/userfunc.c b/src/userfunc.c
index 71b3983..7536234 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -5452,6 +5452,10 @@ define_function(
// :func does not use Vim9 script syntax, even in a Vim9 script file
fp->uf_script_ctx.sc_version = SCRIPT_VERSION_MAX;
+ // If test_override('defcompile' 1) is used, then compile the function now
+ if (eap->cmdidx == CMD_def && override_defcompile)
+ defcompile_function(fp, NULL);
+
goto ret_free;
erret:
diff --git a/src/version.c b/src/version.c
index 71e56a2..14a5922 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,244 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 496,
+/**/
+ 495,
+/**/
+ 494,
+/**/
+ 493,
+/**/
+ 492,
+/**/
+ 491,
+/**/
+ 490,
+/**/
+ 489,
+/**/
+ 488,
+/**/
+ 487,
+/**/
+ 486,
+/**/
+ 485,
+/**/
+ 484,
+/**/
+ 483,
+/**/
+ 482,
+/**/
+ 481,
+/**/
+ 480,
+/**/
+ 479,
+/**/
+ 478,
+/**/
+ 477,
+/**/
+ 476,
+/**/
+ 475,
+/**/
+ 474,
+/**/
+ 473,
+/**/
+ 472,
+/**/
+ 471,
+/**/
+ 470,
+/**/
+ 469,
+/**/
+ 468,
+/**/
+ 467,
+/**/
+ 466,
+/**/
+ 465,
+/**/
+ 464,
+/**/
+ 463,
+/**/
+ 462,
+/**/
+ 461,
+/**/
+ 460,
+/**/
+ 459,
+/**/
+ 458,
+/**/
+ 457,
+/**/
+ 456,
+/**/
+ 455,
+/**/
+ 454,
+/**/
+ 453,
+/**/
+ 452,
+/**/
+ 451,
+/**/
+ 450,
+/**/
+ 449,
+/**/
+ 448,
+/**/
+ 447,
+/**/
+ 446,
+/**/
+ 445,
+/**/
+ 444,
+/**/
+ 443,
+/**/
+ 442,
+/**/
+ 441,
+/**/
+ 440,
+/**/
+ 439,
+/**/
+ 438,
+/**/
+ 437,
+/**/
+ 436,
+/**/
+ 435,
+/**/
+ 434,
+/**/
+ 433,
+/**/
+ 432,
+/**/
+ 431,
+/**/
+ 430,
+/**/
+ 429,
+/**/
+ 428,
+/**/
+ 427,
+/**/
+ 426,
+/**/
+ 425,
+/**/
+ 424,
+/**/
+ 423,
+/**/
+ 422,
+/**/
+ 421,
+/**/
+ 420,
+/**/
+ 419,
+/**/
+ 418,
+/**/
+ 417,
+/**/
+ 416,
+/**/
+ 415,
+/**/
+ 414,
+/**/
+ 413,
+/**/
+ 412,
+/**/
+ 411,
+/**/
+ 410,
+/**/
+ 409,
+/**/
+ 408,
+/**/
+ 407,
+/**/
+ 406,
+/**/
+ 405,
+/**/
+ 404,
+/**/
+ 403,
+/**/
+ 402,
+/**/
+ 401,
+/**/
+ 400,
+/**/
+ 399,
+/**/
+ 398,
+/**/
+ 397,
+/**/
+ 396,
+/**/
+ 395,
+/**/
+ 394,
+/**/
+ 393,
+/**/
+ 392,
+/**/
+ 391,
+/**/
+ 390,
+/**/
+ 389,
+/**/
+ 388,
+/**/
+ 387,
+/**/
+ 386,
+/**/
+ 385,
+/**/
+ 384,
+/**/
+ 383,
+/**/
+ 382,
+/**/
+ 381,
+/**/
+ 380,
+/**/
+ 379,
+/**/
+ 378,
+/**/
377,
/**/
376,
diff --git a/src/vim.h b/src/vim.h
index f359245..e703239 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1500,6 +1500,8 @@ typedef enum
, HLF_SPL // SpellLocal
, HLF_PNI // popup menu normal item
, HLF_PSI // popup menu selected item
+ , HLF_PMNI // popup menu matched text in normal item
+ , HLF_PMSI // popup menu matched text in selected item
, HLF_PNK // popup menu normal item "kind"
, HLF_PSK // popup menu selected item "kind"
, HLF_PNX // popup menu normal item "menu" (extra text)
@@ -1525,11 +1527,20 @@ typedef enum
'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', 't', 'v', 'V', \
'w', 'W', 'f', 'F', 'A', 'C', 'D', 'T', '-', '>', \
'B', 'P', 'R', 'L', \
- '+', '=', '[', ']', '{', '}', 'x', 'X', \
+ '+', '=', 'k', '<','[', ']', '{', '}', 'x', 'X', \
'*', '#', '_', '!', '.', 'o', 'q', \
'z', 'Z', 'g'}
/*
+ * Values for behaviour in spell_move_to
+ */
+typedef enum
+{
+ SMT_ALL = 0 // Move to "all" words
+ , SMT_BAD // Move to "bad" words only
+ , SMT_RARE // Move to "rare" words only
+} smt_T;
+/*
* Boolean constants
*/
#ifndef TRUE
diff --git a/src/vim9class.c b/src/vim9class.c
index 4314b52..f66aa68 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -137,7 +137,7 @@ parse_member(
(void)skip_expr_concatenate(&init_arg, &expr_start, &expr_end, &evalarg);
init_arg = skipwhite(init_arg);
- if (*init_arg != NUL)
+ if (*init_arg != NUL && !vim9_comment_start(init_arg))
{
semsg(_(e_trailing_characters_str), init_arg);
return FAIL;
@@ -3845,7 +3845,7 @@ object_len(object_T *obj)
* Return a textual representation of object "obj"
*/
char_u *
-object_string(
+object2string(
object_T *obj,
char_u *numbuf,
int copyID,
diff --git a/src/vim9type.c b/src/vim9type.c
index 775291e..ffdf7fa 100644
--- a/src/vim9type.c
+++ b/src/vim9type.c
@@ -1466,7 +1466,14 @@ parse_type_user_defined(
}
if (give_error && (did_emsg == did_emsg_before))
+ {
+ char_u *p = skip_type(*arg, FALSE);
+ char cc = *p;
+
+ *p = NUL;
semsg(_(e_type_not_recognized_str), *arg);
+ *p = cc;
+ }
return NULL;
}
@@ -2091,10 +2098,12 @@ check_typval_is_value(typval_T *tv)
case VAR_CLASS:
{
class_T *cl = tv->vval.v_class;
- if (IS_ENUM(cl))
- semsg(_(e_using_enum_as_value_str), cl->class_name);
+ char_u *class_name = (cl == NULL) ? (char_u *)""
+ : cl->class_name;
+ if (cl != NULL && IS_ENUM(cl))
+ semsg(_(e_using_enum_as_value_str), class_name);
else
- semsg(_(e_using_class_as_value_str), cl->class_name);
+ semsg(_(e_using_class_as_value_str), class_name);
}
return FAIL;
diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c
index cf8b4ea..7a3d36a 100644
--- a/src/xxd/xxd.c
+++ b/src/xxd/xxd.c
@@ -62,6 +62,7 @@
* 17.01.2024 use size_t instead of usigned int for code-generation (-i), #13876
* 25.01.2024 revert the previous patch (size_t instead of unsigned int)
* 10.02.2024 fix buffer-overflow when writing color output to buffer, #14003
+ * 10.05.2024 fix another buffer-overflow when writing colored output to buffer, #14738
*
* (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com)
*
@@ -142,7 +143,7 @@ extern void perror __P((char *));
# endif
#endif
-char version[] = "xxd 2024-02-10 by Juergen Weigert et al.";
+char version[] = "xxd 2024-05-10 by Juergen Weigert et al.";
#ifdef WIN32
char osver[] = " (Win32)";
#else
@@ -205,29 +206,16 @@ char osver[] = "";
/*
* LLEN is the maximum length of a line; other than the visible characters
* we need to consider also the escape color sequence prologue/epilogue ,
- * (11 bytes for each character). The most larger format is the default one:
- * addr + 1 word for each col/2 + 1 char for each col
- *
- * addr 1st group 2nd group
- * +-------+ +-----------------+ +------+
- * 01234567: 1234 5678 9abc def0 12345678
- *
- * - addr: typically 012345678: -> from 10 up to 18 bytes (including trailing
- * space)
- * - 1st group: 1234 5678 9abc ... -> each byte may be colored, so add 11
- * for each byte
- * - space -> 1 byte
- * - 2nd group: 12345678 -> each char may be colore so add 11
- * for each byte
- * - new line -> 1 byte
- * - zero (end line) -> 1 byte
+ * (11 bytes for each character).
*/
-#define LLEN (2*(int)sizeof(unsigned long) + 2 + /* addr + ": " */ \
- (11 * 2 + 4 + 1) * (COLS / 2) + /* 1st group */ \
- 1 + /* space */ \
- (1 + 11) * COLS + /* 2nd group */ \
- 1 + /* new line */ \
- 1) /* zero */
+#define LLEN \
+ (39 /* addr: ⌈log10(ULONG_MAX)⌉ if "-d" flag given. We assume ULONG_MAX = 2**128 */ \
+ + 2 /* ": " */ \
+ + 13 * COLS /* hex dump with colors */ \
+ + (COLS - 1) /* whitespace between groups if "-g1" option given and "-c" maxed out */ \
+ + 2 /* whitespace */ \
+ + 12 * COLS /* ASCII dump with colors */ \
+ + 2) /* "\n\0" */
char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;