diff --git a/.cirrus.yml b/.cirrus.yml index 78e49d9805..a3604a425e 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_vim b/.github/MAINTAINERS similarity index 86% rename from .github/CODEOWNERS_vim rename to .github/MAINTAINERS index 9bac8b2dd1..7ec5433a2b 100644 --- a/.github/CODEOWNERS_vim +++ b/.github/MAINTAINERS @@ -11,12 +11,14 @@ 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 runtime/autoload/php.vim @david-szabo97 runtime/autoload/rubycomplete.vim @segfault @dkearns runtime/autoload/rust.vim @lilyball +runtime/autoload/typst.vim @gpanders runtime/autoload/xmlformat.vim @chrisbra runtime/autoload/dist/json.vim @habamax runtime/colors/blue.vim @habamax @romainl @neutaaaaan @@ -63,13 +65,14 @@ 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 runtime/compiler/jjs.vim @dkearns runtime/compiler/jshint.vim @dkearns runtime/compiler/jsonlint.vim @dkearns +runtime/compiler/jq.vim @vito-c runtime/compiler/lazbuild.vim @dkearns runtime/compiler/perl.vim @petdance @heptite runtime/compiler/perlcritic.vim @petdance @dkearns @@ -98,29 +101,43 @@ runtime/compiler/tidy.vim @dkearns runtime/compiler/ts-node.vim @dkearns runtime/compiler/tsc.vim @dkearns runtime/compiler/typedoc.vim @dkearns +runtime/compiler/typst.vim @gpanders 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/antlr4.vim @jiangyinzuo +runtime/ftplugin/apache.vim @dubgeiser +runtime/ftplugin/arduino.vim @k-takata +runtime/ftplugin/astro.vim @romainl +runtime/ftplugin/asy.vim @avidseeker runtime/ftplugin/awk.vim @dkearns runtime/ftplugin/basic.vim @dkearns runtime/ftplugin/bst.vim @tpope +runtime/ftplugin/cabal.vim @ribru17 +runtime/ftplugin/cedar.vim @ribru17 runtime/ftplugin/cfg.vim @chrisbra runtime/ftplugin/chatito.vim @ObserverOfTime +runtime/ftplugin/chicken.vim @evhan runtime/ftplugin/clojure.vim @axvr +runtime/ftplugin/cmakecache.vim @ribru17 runtime/ftplugin/cs.vim @nickspoons runtime/ftplugin/csh.vim @dkearns runtime/ftplugin/css.vim @dkearns +runtime/ftplugin/csv.vim @habamax runtime/ftplugin/cucumber.vim @tpope +runtime/ftplugin/cuda.vim @ribru17 +runtime/ftplugin/dart.vim @ribru17 runtime/ftplugin/deb822sources.vim @jamessan runtime/ftplugin/debchangelog.vim @jamessan runtime/ftplugin/debcontrol.vim @jamessan runtime/ftplugin/debsources.vim @jamessan runtime/ftplugin/desktop.vim @e-kwsm runtime/ftplugin/dosbatch.vim @mrdubya +runtime/ftplugin/editorconfig.vim @ribru17 runtime/ftplugin/eiffel.vim @dkearns runtime/ftplugin/elixir.vim @mhanberg runtime/ftplugin/erlang.vim @hcs42 @@ -142,40 +159,56 @@ 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/gomod.vim @yu-yk 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/hlsplaylist.vim @avidseeker 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 runtime/ftplugin/ishd.vim @dkearns runtime/ftplugin/j.vim @glts runtime/ftplugin/java.vim @zzzyxwvut +runtime/ftplugin/javacc.vim @ribru17 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/kivy.vim @ribru17 runtime/ftplugin/kotlin.vim @udalov +runtime/ftplugin/ldapconf.vim @ribru17 runtime/ftplugin/less.vim @genoma +runtime/ftplugin/lex.vim @ribru17 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 runtime/ftplugin/markdown.vim @tpope +runtime/ftplugin/mediawiki.vim @avidseeker runtime/ftplugin/meson.vim @Liambeguin runtime/ftplugin/modula2.vim @dkearns runtime/ftplugin/modula3.vim @dkearns +runtime/ftplugin/mojo.vim @ribru17 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 @@ -188,40 +221,54 @@ 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 runtime/ftplugin/rust.vim @lilyball runtime/ftplugin/sass.vim @tpope runtime/ftplugin/scala.vim @derekwyatt +runtime/ftplugin/scheme.vim @evhan 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/squirrel.vim @ribru17 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 runtime/ftplugin/tap.vim @petdance runtime/ftplugin/tcsh.vim @dkearns +runtime/ftplugin/terraform.vim @JannoTjarks +runtime/ftplugin/tf.vim @ribru17 runtime/ftplugin/tidy.vim @dkearns runtime/ftplugin/tmux.vim @ericpruitt runtime/ftplugin/toml.vim @averms runtime/ftplugin/tt2html.vim @petdance runtime/ftplugin/typescript.vim @dkearns runtime/ftplugin/typescriptreact.vim @dkearns +runtime/ftplugin/typst.vim @gpanders 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 @@ -230,8 +277,11 @@ runtime/ftplugin/wget2.vim @dkearns runtime/ftplugin/xcompose.vim @ObserverOfTime runtime/ftplugin/xml.vim @chrisbra runtime/ftplugin/xs.vim @petdance +runtime/ftplugin/yacc.vim @ribru17 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 runtime/indent/cdl.vim @dkearns @@ -256,10 +306,11 @@ runtime/indent/freebasic.vim @dkearns runtime/indent/gdscript.vim @habamax runtime/indent/gitconfig.vim @tpope runtime/indent/gitolite.vim @sitaramc +runtime/indent/glsl.vim @gpanders 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 @@ -268,6 +319,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 @@ -277,6 +329,7 @@ runtime/indent/lua.vim @marcuscf runtime/indent/make.vim @dkearns runtime/indent/meson.vim @Liambeguin runtime/indent/mma.vim @dkearns +runtime/indent/mojo.vim @ribru17 runtime/indent/nginx.vim @chr4 runtime/indent/nsis.vim @k-takata runtime/indent/occam.vim @dkearns @@ -293,6 +346,7 @@ runtime/indent/readline.vim @dkearns runtime/indent/ruby.vim @AndrewRadev @dkearns runtime/indent/sass.vim @tpope runtime/indent/scala.vim @derekwyatt +runtime/indent/scheme.vim @evhan runtime/indent/scss.vim @tpope runtime/indent/sh.vim @chrisbra runtime/indent/solidity.vim @cothi @@ -301,6 +355,7 @@ runtime/indent/tcl.vim @dkearns runtime/indent/tcsh.vim @dkearns runtime/indent/teraterm.vim @k-takata runtime/indent/typescript.vim @HerringtonDarkholme +runtime/indent/typst.vim @gpanders runtime/indent/vroom.vim @dbarnett runtime/indent/wast.vim @rhysd runtime/indent/xml.vim @chrisbra @@ -314,17 +369,22 @@ runtime/lang/menu_ru_ru.cp1251.vim @RestorerZ runtime/lang/menu_ru_ru.koi8-r.vim @RestorerZ runtime/lang/menu_ru_ru.utf-8.vim @RestorerZ runtime/pack/dist/opt/cfilter/plugin/cfilter.vim @yegappan +runtime/pack/dist/opt/comment/ @habamax runtime/pack/dist/opt/matchit/ @chrisbra +runtime/pack/dist/opt/nohlsearch/ @habamax runtime/plugin/manpager.vim @Konfekt runtime/syntax/shared/hgcommitDiff.vim @vegerot runtime/syntax/abaqus.vim @costerwi runtime/syntax/aidl.vim @dpelle runtime/syntax/ant.vim @dkearns +runtime/syntax/antlr4.vim @jiangyinzuo runtime/syntax/arduino.vim @johshoff runtime/syntax/asciidoc.vim @aerostitch runtime/syntax/asm.vim @dkearns runtime/syntax/asmh8300.vim @dkearns runtime/syntax/asterisk.vim @jaunis +runtime/syntax/astro.vim @wuelnerdotexe +runtime/syntax/asy.vim @avidseeker runtime/syntax/autohotkey.vim @mmikeww runtime/syntax/awk.vim @dkearns runtime/syntax/basic.vim @dkearns @@ -336,9 +396,11 @@ runtime/syntax/cabalconfig.vim @coot runtime/syntax/cabalproject.vim @coot runtime/syntax/cf.vim @ernstvanderlinden runtime/syntax/chatito.vim @ObserverOfTime +runtime/syntax/chicken.vim @evhan runtime/syntax/chuck.vim @gacallea runtime/syntax/clojure.vim @axvr runtime/syntax/cs.vim @nickspoons +runtime/syntax/csv.vim @habamax runtime/syntax/cucumber.vim @tpope runtime/syntax/d.vim @JesseKPhillips runtime/syntax/dart.vim @pr3d4t0r @@ -378,6 +440,7 @@ runtime/syntax/gitconfig.vim @tpope runtime/syntax/gitignore.vim @ObserverOfTime runtime/syntax/gitolite.vim @sitaramc runtime/syntax/gitrebase.vim @tpope +runtime/syntax/glsl.vim @gpanders runtime/syntax/go.vim @bhcleek runtime/syntax/godoc.vim @dbarnett runtime/syntax/gp.vim @KBelabas @@ -385,7 +448,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 @@ -400,10 +464,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 @@ -417,6 +485,7 @@ runtime/syntax/make.vim @rohieb runtime/syntax/mallard.vim @jhradilek runtime/syntax/markdown.vim @tpope runtime/syntax/mason.vim @petdance +runtime/syntax/mediawiki.vim @avidseeker runtime/syntax/meson.vim @Liambeguin runtime/syntax/modula2.vim @dkearns runtime/syntax/modula2/opt/iso.vim @trijezdci @@ -452,6 +521,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 @@ -463,6 +533,7 @@ runtime/syntax/rst.vim @marshallward runtime/syntax/ruby.vim @dkearns runtime/syntax/sass.vim @tpope runtime/syntax/scala.vim @derekwyatt +runtime/syntax/scheme.vim @evhan runtime/syntax/scss.vim @tpope runtime/syntax/sdoc.vim @gpanders runtime/syntax/sed.vim @dkearns @@ -489,9 +560,10 @@ 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/typst.vim @gpanders +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 0000000000..19eb9b6d0c --- /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/coverity.yml b/.github/workflows/coverity.yml index 290f7e4e4b..90a6e9ff0c 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 0720cb1699..99bfcfa2c8 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 57eb8dd402..5e24dbb70b 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 \ @@ -212,6 +214,7 @@ SRC_ALL = \ src/testdir/pyxfile/*.py \ src/testdir/dumps/*.dump \ src/testdir/dumps/*.vim \ + src/testdir/samples/*.html \ src/testdir/samples/*.txt \ src/testdir/samples/*.vim \ src/testdir/samples/test000 \ @@ -219,6 +222,7 @@ SRC_ALL = \ src/testdir/silent.wav \ src/testdir/popupbounce.vim \ src/testdir/crash/* \ + src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo \ src/proto.h \ src/protodef.h \ src/proto/alloc.pro \ @@ -263,6 +267,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 \ @@ -755,6 +760,10 @@ RT_ALL = \ runtime/tutor/tutor.vim \ runtime/vimrc_example.vim \ runtime/pack/dist/opt/cfilter/plugin/cfilter.vim \ + runtime/pack/dist/opt/comment/plugin/comment.vim \ + runtime/pack/dist/opt/comment/doc/comment.txt \ + runtime/pack/dist/opt/comment/doc/tags \ + runtime/pack/dist/opt/comment/autoload/comment.vim \ runtime/pack/dist/opt/dvorak/plugin/dvorak.vim \ runtime/pack/dist/opt/dvorak/dvorak/enable.vim \ runtime/pack/dist/opt/dvorak/dvorak/disable.vim \ @@ -775,6 +784,7 @@ RT_ALL = \ runtime/pack/dist/opt/matchit/doc/matchit.txt \ runtime/pack/dist/opt/matchit/doc/tags \ runtime/pack/dist/opt/matchit/autoload/*.vim \ + runtime/pack/dist/opt/nohlsearch/plugin/nohlsearch.vim \ runtime/pack/dist/opt/shellmenu/plugin/shellmenu.vim \ runtime/pack/dist/opt/swapmouse/plugin/swapmouse.vim \ runtime/pack/dist/opt/termdebug/plugin/termdebug.vim \ @@ -799,7 +809,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 \ @@ -828,8 +837,10 @@ RT_SCRIPTS = \ runtime/syntax/testdir/runtest.vim \ runtime/syntax/testdir/ftplugin/*.* \ runtime/syntax/testdir/input/*.* \ + runtime/syntax/testdir/input/selftestdir/* \ 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/Makefile b/Makefile index f4db80fb82..ad07376366 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ VIM_FOR_INDENTTEST = ../../src/vim indenttest: cd runtime/indent && \ $(MAKE) clean && \ - $(MAKE) test VIM="$(VIM_FOR_INDENTTEST)" + $(MAKE) test VIMPROG="$(VIM_FOR_INDENTTEST)" # Executable used for running the syntax tests. VIM_FOR_SYNTAXTEST = ../../src/vim @@ -249,9 +249,6 @@ VERSION = $(MAJOR)$(MINOR) VDOT = $(MAJOR).$(MINOR) VIMRTDIR = vim$(VERSION) -# Vim used for conversion from "unix" to "dos" -VIM = vim - # How to include Filelist depends on the version of "make" you have. # If the current choice doesn't work, try the other one. diff --git a/README.rux.txt b/README.rux.txt index 5c92b85634..be909280c8 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 bdfefaf8d7..d90ebbc1fa 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/README_vim.md b/README_vim.md index 6e6cf11b89..cfee68e8a2 100644 --- a/README_vim.md +++ b/README_vim.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/READMEdir/README_vimlogo.txt b/READMEdir/README_vimlogo.txt index 9798b108d1..570e876548 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/ci/appveyor.bat b/ci/appveyor.bat index 5498769515..c77cee19d2 100644 --- a/ci/appveyor.bat +++ b/ci/appveyor.bat @@ -1,15 +1,20 @@ @echo off :: Batch file for building/testing Vim on AppVeyor set target=%1 +set "GETTEXT_PATH=c:\gettext64\bin" setlocal ENABLEDELAYEDEXPANSION cd %APPVEYOR_BUILD_FOLDER% :: Python3 -set PYTHON3_VER=311 -set PYTHON3_RELEASE=3.11.1 -set PYTHON3_URL=https://www.python.org/ftp/python/%PYTHON3_RELEASE%/python-%PYTHON3_RELEASE%-amd64.exe -set PYTHON3_DIR=C:\python%PYTHON3_VER%-x64 +set "PYTHON3_VER=311" +set "PYTHON3_RELEASE=3.11.1" +set "PYTHON3_URL=https://www.python.org/ftp/python/%PYTHON3_RELEASE%/python-%PYTHON3_RELEASE%-amd64.exe" +set "PYTHON3_DIR=C:\python%PYTHON3_VER%-x64" + +:: Gettext-tools, iconv and libraries +set "GETTEXT64_URL=https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.21-v1.16/gettext0.21-iconv1.16-shared-64.zip" +set "GETTEXT64_DIR=c:\gettext64" set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" @@ -43,6 +48,18 @@ if not exist %PYTHON3_DIR% ( AssociateFiles=0 Shortcuts=0 Include_doc=0 Include_launcher=0 ^ InstallLauncherAllUsers=0 ) +:: GETTEXT +if not exist %GETTEXT64_DIR% ( + mkdir %GETTEXT64_DIR% + call :downloadfile %GETTEXT64_URL% downloads\gettext64.zip + cmd /c powershell.exe -NoLogo -NoProfile -Command ^ + Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; ^ + [System.IO.Compression.ZipFile]::ExtractToDirectory^('downloads\gettext64.zip', ^ + '%GETTEXT64_DIR%'^) + copy /y %GETTEXT64_DIR%\bin\libintl-8.dll C:\projects\vim\src\ || exit 1 + copy /y %GETTEXT64_DIR%\bin\libiconv-2.dll C:\projects\vim\src\ || exit 1 +) + @echo off goto :eof @@ -92,7 +109,7 @@ goto :eof @echo on cd src/testdir :: Testing with MSVC gvim -path %PYTHON3_DIR%;%PATH% +path %PYTHON3_DIR%;%GETTEXT_PATH%;%PATH% nmake -f Make_mvc.mak VIMPROG=..\gvim nmake -f Make_mvc.mak clean :: Testing with MSVC console version diff --git a/nsis/gvim.nsi b/nsis/gvim.nsi index b8ef079dba..31f6260d95 100644 --- a/nsis/gvim.nsi +++ b/nsis/gvim.nsi @@ -225,7 +225,7 @@ Page custom SetCustom ValidateCustom # Version resources VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "Vim" -VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Vim Developers" +VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "The Vim Project" VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "Vim" VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "Copyright (C) 1996" VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Vi Improved - A Text Editor" diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim index 7096dcf4ac..355f724d0f 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 -# Last Change: 2023 Aug 10 +# Last Change: 2024 Jun 06 # Rewritten in Vim9 script by github user lacygoill # Former Maintainer: Bram Moolenaar @@ -210,7 +210,7 @@ export def Complete(findstart: bool, abase: string): any # {{{1 # Find the variable in the tags file(s) var diclist: list> = taglist('^' .. items[0] .. '$') # Remove members, these can't appear without something in front. - ->filter((_, v: dict): bool => + ->filter((_, v: dict): 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 05f1611b22..be299ef50d 100644 --- a/runtime/autoload/dist/ft.vim +++ b/runtime/autoload/dist/ft.vim @@ -3,12 +3,14 @@ vim9script # Vim functions for file type detection # # Maintainer: The Vim Project -# Last Change: 2024 Feb 18 +# Last Change: 2024 May 23 # Former Maintainer: Bram Moolenaar # These functions are moved here from runtime/filetype.vim to make startup # faster. +var prolog_pattern = '^\s*\(:-\|%\+\(\s\|$\)\|\/\*\)\|\.\s*$' + export def Check_inp() if getline(1) =~ '%%' setf tex @@ -376,15 +378,57 @@ export def FTfs() endif enddef -# Distinguish between HTML, XHTML and Django +# 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(':h', get(g:, 'haredoc_search_depth', 1)) + setf haredoc + endif + endif +enddef + +# Distinguish between HTML, XHTML, Django and Angular export def FThtml() var n = 1 - while n < 10 && n <= line("$") + + # Test if the filename follows the Angular component template convention + # Disabled for the reasons mentioned here: #13594 + # if expand('%:t') =~ '^.*\.component\.html$' + # setf htmlangular + # return + # endif + + while n < 40 && n <= line("$") + # Check for Angular + if getline(n) =~ '@\(if\|for\|defer\|switch\)\|\*\(ngIf\|ngFor\|ngSwitch\|ngTemplateOutlet\)\|ng-template\|ng-content\|{{.*}}' + setf htmlangular + return + endif + + # Check for XHTML if getline(n) =~ '\\|{#\s\+' + # Check for Django + if getline(n) =~ '{%\s*\(autoescape\|block\|comment\|csrf_token\|cycle\|debug\|extends\|filter\|firstof\|for\|if\|ifchanged\|include\|load\|lorem\|now\|query_string\|regroup\|resetcycle\|spaceless\|templatetag\|url\|verbatim\|widthratio\|with\)\>\|{#\s\+' setf htmldjango return endif @@ -406,20 +450,24 @@ 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 # require a blank after the '%' because Perl uses "%list" and "%translate" var lnum = getline(nextnonblank(1)) - if lnum =~ '\' || lnum =~ '^\s*\(%\+\(\s\|$\)\|/\*\)' || lnum =~ ':-' + if lnum =~ '\' || lnum =~ prolog_pattern setf prolog else exe 'setf ' .. default @@ -598,7 +646,7 @@ export def FTpl() # recognize Prolog by specific text in the first non-empty line # require a blank after the '%' because Perl uses "%list" and "%translate" var line = getline(nextnonblank(1)) - if line =~ '\' || line =~ '^\s*\(%\+\(\s\|$\)\|/\*\)' || line =~ ':-' + if line =~ '\' || line =~ prolog_pattern setf prolog else setf perl @@ -1235,6 +1283,56 @@ export def FTtyp() setf typst enddef +# Detect Microsoft Developer Studio Project files (Makefile) or Faust DSP +# files. +export def FTdsp() + if exists("g:filetype_dsp") + exe "setf " .. g:filetype_dsp + return + endif + + # Test the filename + if expand('%:t') =~ '^[mM]akefile.*$' + setf make + return + endif + + # Test the file contents + for line in getline(1, 200) + # Chech for comment style + if line =~ '^#.*' + setf make + return + endif + + # Check for common lines + if line =~ '^.*Microsoft Developer Studio Project File.*$' + setf make + return + endif + + if line =~ '^!MESSAGE This is not a valid makefile\..+$' + setf make + return + endif + + # Check for keywords + if line =~ '^!(IF,ELSEIF,ENDIF).*$' + setf make + return + endif + + # Check for common assignments + if line =~ '^SOURCE=.*$' + setf make + return + endif + endfor + + # Otherwise, assume we have a Faust file + setf faust +enddef + # Set the filetype of a *.v file to Verilog, V or Cog based on the first 200 # lines. export def FTv() @@ -1298,5 +1396,21 @@ export def FTvba() endif enddef +export def Detect_UCI_statements(): bool + # Match a config or package statement at the start of the line. + const config_or_package_statement = '^\s*\(\(c\|config\)\|\(p\|package\)\)\s\+\S' + # Match a line that is either all blank or blank followed by a comment + const comment_or_blank = '^\s*\(#.*\)\?$' + + # Return true iff the file has a config or package statement near the + # top of the file and all preceding lines were comments or blank. + return getline(1) =~# config_or_package_statement + \ || getline(1) =~# comment_or_blank + \ && ( getline(2) =~# config_or_package_statement + \ || getline(2) =~# comment_or_blank + \ && getline(3) =~# config_or_package_statement + \ ) +enddef + # Uncomment this line to check for compilation errors early # defcompile diff --git a/runtime/autoload/dist/man.vim b/runtime/autoload/dist/man.vim index 708e1062b4..d9dbaf47d4 100644 --- a/runtime/autoload/dist/man.vim +++ b/runtime/autoload/dist/man.vim @@ -4,6 +4,7 @@ " Maintainer: SungHyun Nam " Autoload Split: Bram Moolenaar " Last Change: 2024 Jan 17 (make it work on AIX, see #13847) +" 2024 Jul 06 (honor command modifiers, #15117) let s:cpo_save = &cpo set cpo-=C @@ -165,7 +166,9 @@ func dist#man#GetPage(cmdmods, ...) endwhile endif if &filetype != "man" - if exists("g:ft_man_open_mode") + if a:cmdmods =~ '\<\(tab\|vertical\|horizontal\)\>' + let open_cmd = a:cmdmods . ' split' + elseif exists("g:ft_man_open_mode") if g:ft_man_open_mode == 'vert' let open_cmd = 'vsplit' elseif g:ft_man_open_mode == 'tab' @@ -174,7 +177,7 @@ func dist#man#GetPage(cmdmods, ...) let open_cmd = 'split' endif else - let open_cmd = a:cmdmods . ' split' + let open_cmd = 'split' endif endif endif diff --git a/runtime/autoload/dist/script.vim b/runtime/autoload/dist/script.vim index f58899af31..33ed7fd2fc 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 0000000000..c4581fccf9 --- /dev/null +++ b/runtime/autoload/hare.vim @@ -0,0 +1,26 @@ +" Vim autoload file. +" Language: Hare +" Maintainer: Amelia Clarke +" 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 e2152b0dfc..5c2a43a17a 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -9,6 +9,14 @@ " 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) +" 2024 Jun 23 by Vim Project: save ad restore registers when liststyle = WIDELIST (#15077, #15114) +" 2024 Jul 22 by Vim Project: avoid endless recursion (#15318) " Former Maintainer: Charles E Campbell " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim " Copyright: Copyright (C) 2016 Charles E. Campbell {{{1 @@ -283,20 +291,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 +314,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 =~ '\%(\\|\\)\%(\.exe\)\=$' - let g:netrw_cygwin= 1 - else - let g:netrw_cygwin= 0 - endif + if has("win32unix") && &shell =~ '\%(\\|\\)\%(\.exe\)\=$' + let g:netrw_cygwin= 1 else let g:netrw_cygwin= 0 endif @@ -372,10 +371,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 +398,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 +412,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 +434,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 +450,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 +483,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 +542,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 +680,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("")) @@ -701,12 +695,11 @@ fun! netrw#Explore(indx,dosplit,style,...) \ ((isdirectory(s:NetrwFile(a:1))))? 'is a directory' : 'is not a directory', \ '~'.expand("")) if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1)) -" call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("")) - call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g')) -" call Dret("netrw#Explore : returning from retry") - return -" else " Decho -" call Decho("retry not needed",'~'.expand("")) + let a1 = substitute(a:1, '\\\(\s\)', '\1', 'g') + if a1 != a:1 + call netrw#Explore(a:indx, a:dosplit, a:style, a1) + return + endif endif endif @@ -844,7 +837,7 @@ fun! netrw#Explore(indx,dosplit,style,...) " handle .../**/.../filepat " call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("")) 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 +874,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 +1413,7 @@ fun! netrw#Obtain(islocal,fname,...) " call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("")) 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("")) for fname in fnamelist @@ -2301,7 +2294,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 +3214,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("")) " call Decho(" g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("")) if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>' @@ -3336,38 +3329,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 +3951,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 +4105,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 @@ -4536,7 +4497,15 @@ fun! s:NetrwGetWord() call cursor(line("."),filestart+1) NetrwKeepj norm! ma endif - let rega= @a + + let dict={} + " save the unnamed register and register 0-9 and a + let dict.a=[getreg('a'), getregtype('a')] + for i in range(0, 9) + let dict[i] = [getreg(i), getregtype(i)] + endfor + let dict.unnamed = [getreg(''), getregtype('')] + let eofname= filestart + b:netrw_cpf + 1 if eofname <= col("$") call cursor(line("."),filestart+b:netrw_cpf+1) @@ -4544,8 +4513,10 @@ fun! s:NetrwGetWord() else NetrwKeepj norm! "ay$ endif + let dirname = @a - let @a = rega + call s:RestoreRegister(dict) + " call Decho("2: dirname<".dirname.">",'~'.expand("")) let dirname= substitute(dirname,'\s\+$','','e') " call Decho("3: dirname<".dirname.">",'~'.expand("")) @@ -4864,7 +4835,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 +5082,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) endif " call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("")) - 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 +5367,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 +5414,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 +5462,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("")) if executable("start") call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1)) @@ -5613,13 +5584,12 @@ endfun " --------------------------------------------------------------------- " netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2 fun! netrw#BrowseXVis() -" call Dfunc("netrw#BrowseXVis()") - let akeep = @a + let dict={} + let dict.a=[getreg('a'), getregtype('a')] norm! gv"ay let gxfile= @a - let @a = akeep + call s:RestoreRegister(dict) call netrw#BrowseX(gxfile,netrw#CheckIfRemote(gxfile)) -" call Dret("netrw#BrowseXVis") endfun " --------------------------------------------------------------------- @@ -5766,6 +5736,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 +5809,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 +5983,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 +7204,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 +7218,7 @@ fun! s:NetrwMarkFileCopy(islocal,...) " call Decho("args<".args."> is a directory",'~'.expand("")) let copycmd= g:netrw_localcopydircmd " call Decho("using copydircmd<".copycmd.">",'~'.expand("")) - 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 +7836,7 @@ fun! s:NetrwMarkFileMove(islocal) endif let tgt = s:ShellEscape(s:netrwmftgt) " call Decho("tgt<".tgt.">",'~'.expand("")) - 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("")) if g:netrw_localmovecmd =~ '\s' @@ -7880,7 +7857,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("")) @@ -9812,7 +9789,13 @@ fun! s:NetrwWideListing() " fpl: filenames per line " fpc: filenames per column setl ma noro - let keepa= @a + let dict={} + " save the unnamed register and register 0-9 and a + let dict.a=[getreg('a'), getregtype('a')] + for i in range(0, 9) + let dict[i] = [getreg(i), getregtype(i)] + endfor + let dict.unnamed = [getreg(''), getregtype('')] " call Decho("setl ma noro",'~'.expand("")) let b:netrw_cpf= 0 if line("$") >= w:netrw_bannercnt @@ -9820,7 +9803,8 @@ fun! s:NetrwWideListing() exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif' NetrwKeepj call histdel("/",-1) else - let @a= keepa + " restore stored registers + call s:RestoreRegister(dict) " call Dret("NetrwWideListing") return endif @@ -9872,7 +9856,7 @@ fun! s:NetrwWideListing() exe 'nno b :call search(''^.\\|\s\s\zs\S'',''bW'')'."\" " call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("")) exe "setl ".g:netrw_bufsettings - let @a= keepa + call s:RestoreRegister(dict) " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("")) " call Dret("NetrwWideListing") return @@ -9884,7 +9868,6 @@ fun! s:NetrwWideListing() sil! nunmap b endif endif - endfun " --------------------------------------------------------------------- @@ -10205,7 +10188,8 @@ fun! s:SetupNetrwStatusLine(statline) endif " set up User9 highlighting as needed - let keepa= @a + let dict={} + let dict.a=[getreg('a'), getregtype('a')] redir @a try hi User9 @@ -10217,7 +10201,7 @@ fun! s:SetupNetrwStatusLine(statline) endif endtry redir END - let @a= keepa + call s:RestoreRegister(dict) endif " set up status line (may use User9 highlighting) @@ -10349,7 +10333,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 +10841,7 @@ fun! netrw#FileUrlEdit(fname) let fname= substitute(fname,'^file://localhost/','file:///','') " call Decho("fname<".fname.">",'~'.expand("")) 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("")) let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','') @@ -10867,7 +10851,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("")) if plainfname =~ '^/\+\a:' " call Decho('removing leading "/"s','~'.expand("")) @@ -11079,7 +11063,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("")) au ShellCmdPost * call s:LocalBrowseRefresh() else @@ -11121,7 +11105,7 @@ fun! s:LocalListing() let filelist = filelist + s:NetrwGlob(dirname,".*",0) " call Decho("filelist=".string(filelist),'~'.expand("")) - 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("")) elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/' " include ../ in the glob() entry if its missing @@ -11167,7 +11151,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("")) @@ -11501,7 +11485,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 +11498,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 +11628,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 !~ '\%(\\|\\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16")) + if (!g:netrw_cygwin || &shell !~ '\%(\\|\\)\%(\.exe\)\=$') && has("win32") " remove cygdrive prefix, if present let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','') " remove trailing slash (Win95) @@ -11704,11 +11688,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("")) 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("")) if a:base =~ '[/\\]$' let ret= a:base.a:subdir @@ -11820,7 +11804,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 @@ -12027,6 +12011,16 @@ fun! s:RestoreCursorline() " call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn) endfun +" s:RestoreRegister: restores all registers given in the dict {{{2 +fun! s:RestoreRegister(dict) + for [key, val] in items(a:dict) + if key == 'unnamed' + let key = '' + endif + call setreg(key, val[0], val[1]) + endfor +endfun + " --------------------------------------------------------------------- " s:NetrwDelete: Deletes a file. {{{2 " Uses Steve Hall's idea to insure that Windows paths stay @@ -12036,7 +12030,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 +12221,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 +12694,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 5525c0d035..3452602272 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/typst.vim b/runtime/autoload/typst.vim new file mode 100644 index 0000000000..55edd23928 --- /dev/null +++ b/runtime/autoload/typst.vim @@ -0,0 +1,50 @@ +" Language: Typst +" Maintainer: Gregory Anders +" Last Change: 2024-07-14 +" Based on: https://github.com/kaarmu/typst.vim + +function! typst#indentexpr() abort + let l:lnum = v:lnum + let s:sw = shiftwidth() + + let [l:plnum, l:pline] = s:get_prev_nonblank(l:lnum - 1) + if l:plnum == 0 | return 0 | endif + + let l:line = getline(l:lnum) + let l:ind = indent(l:plnum) + + let l:synname = synIDattr(synID(l:lnum, 1, 1), 'name') + + " Use last indent for block comments + if l:synname == 'typstCommentBlock' + return l:ind + endif + + if l:pline =~ '\v[{[(]\s*$' + let l:ind += s:sw + endif + + if l:line =~ '\v^\s*[}\])]' + let l:ind -= s:sw + endif + + return l:ind +endfunction + +" Gets the previous non-blank line that is not a comment. +function! s:get_prev_nonblank(lnum) abort + let l:lnum = prevnonblank(a:lnum) + let l:line = getline(l:lnum) + + while l:lnum > 0 && l:line =~ '^\s*//' + let l:lnum = prevnonblank(l:lnum - 1) + let l:line = getline(l:lnum) + endwhile + + return [l:lnum, s:remove_comments(l:line)] +endfunction + +" Removes comments from the given line. +function! s:remove_comments(line) abort + return substitute(a:line, '\s*//.*', '', '') +endfunction diff --git a/runtime/autoload/zig/fmt.vim b/runtime/autoload/zig/fmt.vim deleted file mode 100644 index b78c1994dd..0000000000 --- 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 c0034f8a7a..d0e706e83a 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 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 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/colors/blue.vim b/runtime/colors/blue.vim index f95cf272aa..8478c6a89c 100644 --- a/runtime/colors/blue.vim +++ b/runtime/colors/blue.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Steven Vertigan " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Mon 08 Jan 2024 09:42:49 AM AEDT +" Last Updated: Wed 10 Jul 2024 17:27:38 " Generated by Colortemplate v2.2.3 @@ -22,9 +22,11 @@ hi Normal guifg=#ffd700 guibg=#000087 gui=NONE cterm=NONE hi CursorLine guifg=NONE guibg=#005faf gui=NONE cterm=NONE hi Pmenu guifg=#ffffff guibg=#008787 gui=NONE cterm=NONE hi PmenuSel guifg=#008787 guibg=#ffffff gui=NONE cterm=NONE +hi PmenuMatch guifg=#ffd700 guibg=#008787 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff7f50 guibg=#ffffff gui=NONE cterm=NONE hi QuickFixLine guifg=#000000 guibg=#d787d7 gui=NONE cterm=NONE hi ColorColumn guifg=NONE guibg=#870087 gui=NONE cterm=NONE -hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE +hi Conceal guifg=#008787 guibg=NONE gui=NONE cterm=NONE hi Cursor guifg=#000000 guibg=#00ff00 gui=NONE cterm=NONE hi CursorColumn guifg=NONE guibg=#005faf gui=NONE cterm=NONE hi CursorIM guifg=#000000 guibg=#ffd700 gui=NONE cterm=NONE @@ -132,9 +134,11 @@ if s:t_Co >= 256 hi CursorLine ctermfg=NONE ctermbg=25 cterm=NONE hi Pmenu ctermfg=231 ctermbg=30 cterm=NONE hi PmenuSel ctermfg=30 ctermbg=231 cterm=NONE + hi PmenuMatch ctermfg=220 ctermbg=30 cterm=NONE + hi PmenuMatchSel ctermfg=209 ctermbg=231 cterm=NONE hi QuickFixLine ctermfg=16 ctermbg=176 cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=90 cterm=NONE - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=30 ctermbg=NONE cterm=NONE hi Cursor ctermfg=16 ctermbg=46 cterm=NONE hi CursorColumn ctermfg=NONE ctermbg=25 cterm=NONE hi CursorIM ctermfg=16 ctermbg=220 cterm=NONE @@ -247,7 +251,7 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=black ctermbg=white cterm=NONE hi QuickFixLine ctermfg=black ctermbg=magenta cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=darkmagenta cterm=NONE - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=darkcyan ctermbg=NONE cterm=NONE hi Cursor ctermfg=black ctermbg=green cterm=NONE hi CursorColumn ctermfg=NONE ctermbg=blue cterm=NONE hi CursorIM ctermfg=black ctermbg=yellow cterm=NONE diff --git a/runtime/colors/darkblue.vim b/runtime/colors/darkblue.vim index b792b90fb2..e12b2e7a9e 100644 --- a/runtime/colors/darkblue.vim +++ b/runtime/colors/darkblue.vim @@ -4,7 +4,7 @@ " Maintainer: Original author Bohdan Vlasyuk " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Mon 08 Jan 2024 09:43:03 AM AEDT +" Last Updated: Wed 10 Jul 2024 17:25:49 " Generated by Colortemplate v2.2.3 @@ -68,7 +68,7 @@ hi! link CurSearch Search hi! link MessageWindow Pmenu hi! link PopupNotification Todo hi Normal guifg=#c0c0c0 guibg=#000040 gui=NONE cterm=NONE -hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE +hi Conceal guifg=#008b8b guibg=NONE gui=NONE cterm=NONE hi ColorColumn guifg=#c0c0c0 guibg=#8b0000 gui=NONE cterm=NONE hi Cursor guifg=#000000 guibg=#ffff60 gui=NONE cterm=NONE hi QuickFixLine guifg=#000000 guibg=#ff80ff gui=NONE cterm=NONE @@ -85,6 +85,8 @@ hi Pmenu guifg=#ffffff guibg=#0030ff gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel guifg=#0030ff guibg=#ffffff gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#ffffff gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff80ff guibg=#0030ff gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff00ff guibg=#ffffff gui=NONE cterm=NONE hi Question guifg=#90f020 guibg=NONE gui=NONE cterm=NONE hi SignColumn guifg=#808080 guibg=NONE gui=NONE cterm=NONE hi SpecialKey guifg=#008b8b guibg=NONE gui=NONE cterm=NONE @@ -176,7 +178,7 @@ if s:t_Co >= 256 hi! link MessageWindow Pmenu hi! link PopupNotification Todo hi Normal ctermfg=252 ctermbg=17 cterm=NONE - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=30 ctermbg=NONE cterm=NONE hi ColorColumn ctermfg=252 ctermbg=88 cterm=NONE hi Cursor ctermfg=16 ctermbg=227 cterm=NONE hi QuickFixLine ctermfg=16 ctermbg=213 cterm=NONE @@ -193,6 +195,8 @@ if s:t_Co >= 256 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=27 ctermbg=231 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=231 cterm=NONE + hi PmenuMatch ctermfg=213 ctermbg=27 cterm=NONE + hi PmenuMatchSel ctermfg=201 ctermbg=231 cterm=NONE hi Question ctermfg=118 ctermbg=NONE cterm=NONE hi SignColumn ctermfg=102 ctermbg=NONE cterm=NONE hi SpecialKey ctermfg=30 ctermbg=NONE cterm=NONE @@ -238,7 +242,7 @@ endif if s:t_Co >= 16 hi Normal ctermfg=grey ctermbg=black cterm=NONE - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=darkcyan ctermbg=NONE cterm=NONE hi ColorColumn ctermfg=grey ctermbg=darkred cterm=NONE hi Cursor ctermfg=black ctermbg=yellow cterm=NONE hi QuickFixLine ctermfg=black ctermbg=magenta cterm=NONE @@ -255,6 +259,8 @@ if s:t_Co >= 16 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=blue ctermbg=white cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=white cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=blue cterm=NONE + hi PmenuMatchSel ctermfg=darkmagenta ctermbg=white cterm=NONE hi Question ctermfg=green ctermbg=NONE cterm=NONE hi SignColumn ctermfg=darkgrey ctermbg=NONE cterm=NONE hi SpecialKey ctermfg=darkcyan ctermbg=NONE cterm=NONE diff --git a/runtime/colors/delek.vim b/runtime/colors/delek.vim index 16de514b57..b9e98db931 100644 --- a/runtime/colors/delek.vim +++ b/runtime/colors/delek.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer David Schweikert " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:34 +" Last Updated: Wed 10 Jul 2024 17:29:36 " Generated by Colortemplate v2.2.3 @@ -38,6 +38,8 @@ hi Pmenu guifg=#000000 guibg=#add8e6 gui=NONE cterm=NONE hi PmenuSel guifg=#ffffff guibg=#00008b gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#ffffff gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#008b8b gui=NONE cterm=NONE +hi PmenuMatch guifg=#cd00cd guibg=#add8e6 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff87ff guibg=#00008b gui=NONE cterm=NONE hi TabLine guifg=#000000 guibg=#e4e4e4 gui=NONE cterm=NONE hi TabLineFill guifg=NONE guibg=#bcbcbc gui=NONE cterm=NONE hi TabLineSel guifg=#000000 guibg=#ffffff gui=bold cterm=bold @@ -45,6 +47,7 @@ hi ToolbarLine guifg=NONE guibg=#e4e4e4 gui=NONE cterm=NONE hi ToolbarButton guifg=#ffffff guibg=#bcbcbc gui=bold cterm=bold hi NonText guifg=#bcbcbc guibg=NONE gui=NONE cterm=NONE hi SpecialKey guifg=#bcbcbc guibg=NONE gui=NONE cterm=NONE +hi Conceal guifg=#bcbcbc guibg=NONE gui=NONE cterm=NONE hi Folded guifg=#00008b guibg=#e4e4e4 gui=NONE cterm=NONE hi Visual guifg=#000000 guibg=#d0d0d0 gui=NONE cterm=NONE hi VisualNOS guifg=NONE guibg=#ee0000 gui=NONE cterm=NONE @@ -82,7 +85,6 @@ hi PreProc guifg=#cd00cd guibg=NONE gui=NONE cterm=NONE hi Type guifg=#0000ff guibg=NONE gui=bold cterm=bold hi Special guifg=#ff1493 guibg=NONE gui=NONE cterm=NONE hi Directory guifg=#008b8b guibg=NONE gui=bold cterm=bold -hi Conceal guifg=#ee0000 guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Title guifg=#cd00cd guibg=NONE gui=bold cterm=bold hi CursorLine guifg=NONE guibg=#e4e4e4 gui=NONE cterm=NONE @@ -112,6 +114,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=231 ctermbg=18 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=231 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=30 cterm=NONE + hi PmenuMatch ctermfg=164 ctermbg=152 cterm=NONE + hi PmenuMatchSel ctermfg=213 ctermbg=18 cterm=NONE hi TabLine ctermfg=16 ctermbg=254 cterm=NONE hi TabLineFill ctermfg=NONE ctermbg=250 cterm=NONE hi TabLineSel ctermfg=16 ctermbg=231 cterm=bold @@ -119,6 +123,7 @@ if s:t_Co >= 256 hi ToolbarButton ctermfg=231 ctermbg=250 cterm=bold hi NonText ctermfg=250 ctermbg=NONE cterm=NONE hi SpecialKey ctermfg=250 ctermbg=NONE cterm=NONE + hi Conceal ctermfg=250 ctermbg=NONE cterm=NONE hi Folded ctermfg=18 ctermbg=254 cterm=NONE hi Visual ctermfg=16 ctermbg=252 cterm=NONE hi VisualNOS ctermfg=NONE ctermbg=196 cterm=NONE @@ -156,7 +161,6 @@ if s:t_Co >= 256 hi Type ctermfg=21 ctermbg=NONE cterm=bold hi Special ctermfg=198 ctermbg=NONE cterm=NONE hi Directory ctermfg=30 ctermbg=NONE cterm=bold - hi Conceal ctermfg=196 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Title ctermfg=164 ctermbg=NONE cterm=bold hi CursorLine ctermfg=NONE ctermbg=254 cterm=NONE @@ -180,6 +184,8 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=white ctermbg=darkblue cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=white cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=darkcyan cterm=NONE + hi PmenuMatch ctermfg=darkmagenta ctermbg=grey cterm=NONE + hi PmenuMatchSel ctermfg=magenta ctermbg=darkblue cterm=NONE hi TabLine ctermfg=black ctermbg=grey cterm=NONE hi TabLineFill ctermfg=NONE ctermbg=darkgrey cterm=NONE hi TabLineSel ctermfg=black ctermbg=white cterm=bold @@ -187,6 +193,7 @@ if s:t_Co >= 16 hi ToolbarButton ctermfg=white ctermbg=darkgrey cterm=bold hi NonText ctermfg=darkgrey ctermbg=NONE cterm=NONE hi SpecialKey ctermfg=darkgrey ctermbg=NONE cterm=NONE + hi Conceal ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Folded ctermfg=darkblue ctermbg=grey cterm=NONE hi Visual ctermfg=black ctermbg=darkgrey cterm=NONE hi VisualNOS ctermfg=NONE ctermbg=darkred cterm=NONE @@ -224,7 +231,6 @@ if s:t_Co >= 16 hi Type ctermfg=blue ctermbg=NONE cterm=bold hi Special ctermfg=magenta ctermbg=NONE cterm=NONE hi Directory ctermfg=darkcyan ctermbg=NONE cterm=bold - hi Conceal ctermfg=darkred ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Title ctermfg=darkmagenta ctermbg=NONE cterm=bold hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline @@ -256,6 +262,7 @@ if s:t_Co >= 8 hi ToolbarButton ctermfg=black ctermbg=gray cterm=bold,reverse hi NonText ctermfg=darkblue ctermbg=NONE cterm=NONE hi SpecialKey ctermfg=darkblue ctermbg=NONE cterm=NONE + hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE hi Folded ctermfg=darkyellow ctermbg=NONE cterm=NONE hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline @@ -291,7 +298,6 @@ if s:t_Co >= 8 hi Type ctermfg=darkblue ctermbg=NONE cterm=NONE hi Special ctermfg=darkmagenta ctermbg=NONE cterm=bold hi Directory ctermfg=darkcyan ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Title ctermfg=darkmagenta ctermbg=NONE cterm=bold hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE @@ -398,6 +404,7 @@ endif " Color: darkmagenta #870087 18 darkmagenta " Color: darkcyan #008787 30 darkcyan " Color: gray #878787 102 gray +" Color: magenta #ff87ff 213 magenta " Term colors: bg0 statement constant preproc identifier type special bg1 " Term colors: comment statement constant preproc identifier type special fg0 " Color: bgDiffA #5F875F 65 darkgreen diff --git a/runtime/colors/desert.vim b/runtime/colors/desert.vim index e639653da2..b822f3d8e0 100644 --- a/runtime/colors/desert.vim +++ b/runtime/colors/desert.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Hans Fugal " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:34 +" Last Updated: Sat 06 Jul 2024 14:19:35 " Generated by Colortemplate v2.2.3 @@ -37,6 +37,8 @@ hi Pmenu guifg=#ffffff guibg=#666666 gui=NONE cterm=NONE hi PmenuSel guifg=#333333 guibg=#f0e68c gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#333333 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#c2bfa5 gui=NONE cterm=NONE +hi PmenuMatch guifg=#ffa0a0 guibg=#666666 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#cd5c5c guibg=#f0e68c gui=NONE cterm=NONE hi TabLine guifg=#333333 guibg=#c2bfa5 gui=NONE cterm=NONE hi TabLineFill guifg=NONE guibg=#c2bfa5 gui=NONE cterm=NONE hi TabLineSel guifg=#333333 guibg=#f0e68c gui=NONE cterm=NONE @@ -111,6 +113,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=236 ctermbg=186 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=236 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=144 cterm=NONE + hi PmenuMatch ctermfg=217 ctermbg=241 cterm=NONE + hi PmenuMatchSel ctermfg=167 ctermbg=186 cterm=NONE hi TabLine ctermfg=236 ctermbg=144 cterm=NONE hi TabLineFill ctermfg=NONE ctermbg=144 cterm=NONE hi TabLineSel ctermfg=236 ctermbg=186 cterm=NONE diff --git a/runtime/colors/elflord.vim b/runtime/colors/elflord.vim index 3a72dfb46c..1ef803af9f 100644 --- a/runtime/colors/elflord.vim +++ b/runtime/colors/elflord.vim @@ -3,7 +3,7 @@ " Maintainer: original maintainer Ron Aaron " Website: https://www.github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:35 +" Last Updated: Sat 06 Jul 2024 14:27:56 " Generated by Colortemplate v2.2.3 @@ -72,6 +72,8 @@ hi Pmenu guifg=#ffffff guibg=#444444 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#bebebe gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#00cdcd gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#ffffff gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff00ff guibg=#444444 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff00ff guibg=#00cdcd gui=NONE cterm=NONE hi Question guifg=#00ff00 guibg=NONE gui=bold cterm=bold hi Search guifg=#000000 guibg=#ffff00 gui=NONE cterm=NONE hi SignColumn guifg=#00ffff guibg=NONE gui=NONE cterm=NONE @@ -140,6 +142,8 @@ if s:t_Co >= 256 hi PmenuSbar ctermfg=NONE ctermbg=250 cterm=NONE hi PmenuSel ctermfg=16 ctermbg=44 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=231 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=238 cterm=NONE + hi PmenuMatchSel ctermfg=201 ctermbg=44 cterm=NONE hi Question ctermfg=46 ctermbg=NONE cterm=bold hi Search ctermfg=16 ctermbg=226 cterm=NONE hi SignColumn ctermfg=51 ctermbg=NONE cterm=NONE @@ -211,6 +215,8 @@ if s:t_Co >= 16 hi PmenuSbar ctermfg=NONE ctermbg=grey cterm=NONE hi PmenuSel ctermfg=black ctermbg=darkcyan cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=white cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=magenta ctermbg=darkcyan cterm=NONE hi Question ctermfg=green ctermbg=NONE cterm=bold hi Search ctermfg=black ctermbg=yellow cterm=NONE hi SignColumn ctermfg=cyan ctermbg=NONE cterm=NONE diff --git a/runtime/colors/evening.vim b/runtime/colors/evening.vim index 2753daa440..f69094aa10 100644 --- a/runtime/colors/evening.vim +++ b/runtime/colors/evening.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Steven Vertigan " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Mon 08 Jan 2024 09:43:27 AM AEDT +" Last Updated: Wed 10 Jul 2024 17:31:17 " Generated by Colortemplate v2.2.3 @@ -79,12 +79,14 @@ hi Pmenu guifg=#ffffff guibg=#4d4d4d gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#bebebe gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#ffffff gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff80ff guibg=#4d4d4d gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#8b008b guibg=#bebebe gui=NONE cterm=NONE hi QuickFixLine guifg=#ffffff guibg=#8b008b gui=NONE cterm=NONE hi Cursor guifg=#000000 guibg=#00ff00 gui=NONE cterm=NONE hi Error guifg=#ff0000 guibg=#ffffff gui=reverse cterm=reverse hi ErrorMsg guifg=#ffffff guibg=#ff0000 gui=NONE cterm=NONE hi LineNr guifg=#ffff00 guibg=NONE gui=NONE cterm=NONE -hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE +hi Conceal guifg=#666666 guibg=NONE gui=NONE cterm=NONE hi FoldColumn guifg=#add8e6 guibg=NONE gui=NONE cterm=NONE hi Folded guifg=#00008b guibg=#d3d3d3 gui=bold cterm=bold hi IncSearch guifg=#00ff00 guibg=NONE gui=reverse cterm=reverse @@ -187,12 +189,14 @@ if s:t_Co >= 256 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=16 ctermbg=250 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=231 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=239 cterm=NONE + hi PmenuMatchSel ctermfg=90 ctermbg=250 cterm=NONE hi QuickFixLine ctermfg=231 ctermbg=90 cterm=NONE hi Cursor ctermfg=16 ctermbg=46 cterm=NONE hi Error ctermfg=196 ctermbg=231 cterm=reverse hi ErrorMsg ctermfg=231 ctermbg=196 cterm=NONE hi LineNr ctermfg=226 ctermbg=NONE cterm=NONE - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=241 ctermbg=NONE cterm=NONE hi FoldColumn ctermfg=153 ctermbg=NONE cterm=NONE hi Folded ctermfg=18 ctermbg=252 cterm=bold hi IncSearch ctermfg=46 ctermbg=NONE cterm=reverse @@ -298,12 +302,14 @@ if s:t_Co >= 16 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=black ctermbg=gray cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=white cterm=NONE + hi PmenuMatch ctermfg=darkmagenta ctermbg=darkgray cterm=NONE + hi PmenuMatchSel ctermfg=darkmagenta ctermbg=gray cterm=NONE hi QuickFixLine ctermfg=white ctermbg=darkmagenta cterm=NONE hi Cursor ctermfg=black ctermbg=green cterm=NONE hi Error ctermfg=red ctermbg=white cterm=reverse hi ErrorMsg ctermfg=white ctermbg=red cterm=NONE hi LineNr ctermfg=darkyellow ctermbg=NONE cterm=NONE - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=darkgray ctermbg=NONE cterm=NONE hi FoldColumn ctermfg=lightblue ctermbg=NONE cterm=NONE hi Folded ctermfg=darkblue ctermbg=gray cterm=bold hi IncSearch ctermfg=green ctermbg=NONE cterm=reverse diff --git a/runtime/colors/habamax.vim b/runtime/colors/habamax.vim index f32a5494ac..417e334a7f 100644 --- a/runtime/colors/habamax.vim +++ b/runtime/colors/habamax.vim @@ -4,7 +4,7 @@ " Maintainer: Maxim Kim " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Mon 08 Jan 2024 09:39:53 AM AEDT +" Last Updated: Mon 08 Jul 2024 17:44:13 " Generated by Colortemplate v2.2.3 @@ -16,7 +16,7 @@ let g:colors_name = 'habamax' let s:t_Co = has('gui_running') ? -1 : (&t_Co ?? 0) if (has('termguicolors') && &termguicolors) || has('gui_running') - let g:terminal_ansi_colors = ['#1c1c1c', '#d75f5f', '#87af87', '#afaf87', '#5f87af', '#af87af', '#5f8787', '#9e9e9e', '#767676', '#d7875f', '#afd7af', '#d7d787', '#87afd7', '#d7afd7', '#87afaf', '#bcbcbc'] + let g:terminal_ansi_colors = ['#1c1c1c', '#af5f5f', '#5faf5f', '#af875f', '#5f87af', '#af87af', '#5f8787', '#9e9e9e', '#767676', '#d75f87', '#87d787', '#d7af87', '#87afd7', '#d787d7', '#87afaf', '#bcbcbc'] endif hi! link Terminal Normal hi! link StatuslineTerm Statusline @@ -39,14 +39,14 @@ hi! link markdownUrl String hi Normal guifg=#bcbcbc guibg=#1c1c1c gui=NONE cterm=NONE hi Statusline guifg=#1c1c1c guibg=#9e9e9e gui=NONE cterm=NONE hi StatuslineNC guifg=#1c1c1c guibg=#767676 gui=NONE cterm=NONE -hi VertSplit guifg=#767676 guibg=#767676 gui=NONE cterm=NONE +hi VertSplit guifg=#767676 guibg=NONE gui=NONE cterm=NONE hi TabLine guifg=#1c1c1c guibg=#767676 gui=NONE cterm=NONE -hi TabLineFill guifg=#1c1c1c guibg=#767676 gui=NONE cterm=NONE -hi TabLineSel guifg=NONE guibg=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold +hi TabLineFill guifg=#1c1c1c guibg=NONE gui=NONE cterm=NONE +hi TabLineSel guifg=#1c1c1c guibg=#9e9e9e gui=bold cterm=bold hi ToolbarLine guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE -hi ToolbarButton guifg=#9e9e9e guibg=#1c1c1c gui=bold,reverse cterm=bold,reverse +hi ToolbarButton guifg=#767676 guibg=#1c1c1c gui=bold,reverse cterm=bold,reverse hi QuickFixLine guifg=#1c1c1c guibg=#5f87af gui=NONE cterm=NONE -hi CursorLineNr guifg=#ffaf5f guibg=NONE gui=bold cterm=bold +hi CursorLineNr guifg=#dadada guibg=NONE gui=bold cterm=bold hi LineNr guifg=#585858 guibg=NONE gui=NONE cterm=NONE hi LineNrAbove guifg=#585858 guibg=NONE gui=NONE cterm=NONE hi LineNrBelow guifg=#585858 guibg=NONE gui=NONE cterm=NONE @@ -59,55 +59,57 @@ hi VisualNOS guifg=#1c1c1c guibg=#5f8787 gui=NONE cterm=NONE hi Pmenu guifg=NONE guibg=#3a3a3a gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#767676 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE -hi PmenuSel guifg=#1c1c1c guibg=#afaf87 gui=NONE cterm=NONE -hi PmenuKind guifg=#d7875f guibg=#3a3a3a gui=NONE cterm=NONE -hi PmenuKindSel guifg=#d75f5f guibg=#afaf87 gui=NONE cterm=NONE +hi PmenuSel guifg=NONE guibg=#585858 gui=NONE cterm=NONE +hi PmenuKind guifg=#5f8787 guibg=#3a3a3a gui=NONE cterm=NONE +hi PmenuKindSel guifg=#5f8787 guibg=#585858 gui=NONE cterm=NONE hi PmenuExtra guifg=#767676 guibg=#3a3a3a gui=NONE cterm=NONE -hi PmenuExtraSel guifg=#1c1c1c guibg=#afaf87 gui=NONE cterm=NONE +hi PmenuExtraSel guifg=#9e9e9e guibg=#585858 gui=NONE cterm=NONE +hi PmenuMatch guifg=#ffaf5f guibg=#3a3a3a gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ffaf5f guibg=#585858 gui=NONE cterm=NONE hi SignColumn guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE -hi Error guifg=#d75f5f guibg=#1c1c1c gui=reverse cterm=reverse -hi ErrorMsg guifg=#d75f5f guibg=#1c1c1c gui=reverse cterm=reverse -hi ModeMsg guifg=#1c1c1c guibg=#d7d787 gui=NONE cterm=NONE -hi MoreMsg guifg=#87af87 guibg=NONE gui=NONE cterm=NONE -hi Question guifg=#afaf87 guibg=NONE gui=NONE cterm=NONE -hi WarningMsg guifg=#d7875f guibg=NONE gui=NONE cterm=NONE -hi Todo guifg=#d7d787 guibg=#1c1c1c gui=reverse cterm=reverse +hi Error guifg=#af5f5f guibg=#1c1c1c gui=reverse cterm=reverse +hi ErrorMsg guifg=#af5f5f guibg=#1c1c1c gui=reverse cterm=reverse +hi ModeMsg guifg=NONE guibg=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold +hi MoreMsg guifg=#5faf5f guibg=NONE gui=NONE cterm=NONE +hi Question guifg=#d7af87 guibg=NONE gui=NONE cterm=NONE +hi WarningMsg guifg=#d75f87 guibg=NONE gui=NONE cterm=NONE +hi Todo guifg=#d7af87 guibg=#1c1c1c gui=reverse cterm=reverse hi MatchParen guifg=#ff00af guibg=NONE gui=bold cterm=bold -hi Search guifg=#1c1c1c guibg=#87af87 gui=NONE cterm=NONE +hi Search guifg=#1c1c1c guibg=#5faf5f gui=NONE cterm=NONE hi IncSearch guifg=#1c1c1c guibg=#ffaf5f gui=NONE cterm=NONE -hi CurSearch guifg=#1c1c1c guibg=#afaf87 gui=NONE cterm=NONE -hi WildMenu guifg=#1c1c1c guibg=#d7d787 gui=NONE cterm=NONE +hi CurSearch guifg=#1c1c1c guibg=#ffaf5f gui=NONE cterm=NONE +hi WildMenu guifg=#1c1c1c guibg=#d7af87 gui=NONE cterm=NONE hi debugPC guifg=#1c1c1c guibg=#5f87af gui=NONE cterm=NONE -hi debugBreakpoint guifg=#1c1c1c guibg=#d7875f gui=NONE cterm=NONE -hi Cursor guifg=#1c1c1c guibg=#ffaf5f gui=NONE cterm=NONE +hi debugBreakpoint guifg=#1c1c1c guibg=#d75f87 gui=NONE cterm=NONE +hi Cursor guifg=#000000 guibg=#dadada gui=NONE cterm=NONE hi lCursor guifg=#1c1c1c guibg=#5fff00 gui=NONE cterm=NONE hi CursorLine guifg=NONE guibg=#303030 gui=NONE cterm=NONE hi CursorColumn guifg=NONE guibg=#303030 gui=NONE cterm=NONE hi Folded guifg=#9e9e9e guibg=#262626 gui=NONE cterm=NONE hi ColorColumn guifg=NONE guibg=#3a3a3a gui=NONE cterm=NONE hi SpellBad guifg=NONE guibg=NONE guisp=#d75f5f gui=undercurl ctermfg=NONE ctermbg=NONE cterm=underline -hi SpellCap guifg=NONE guibg=NONE guisp=#5f87af gui=undercurl ctermfg=NONE ctermbg=NONE cterm=underline -hi SpellLocal guifg=NONE guibg=NONE guisp=#87af87 gui=undercurl ctermfg=NONE ctermbg=NONE cterm=underline -hi SpellRare guifg=NONE guibg=NONE guisp=#d7afd7 gui=undercurl ctermfg=NONE ctermbg=NONE cterm=underline +hi SpellCap guifg=NONE guibg=NONE guisp=#ffaf5f gui=undercurl ctermfg=NONE ctermbg=NONE cterm=underline +hi SpellLocal guifg=NONE guibg=NONE guisp=#5fd75f gui=undercurl ctermfg=NONE ctermbg=NONE cterm=underline +hi SpellRare guifg=NONE guibg=NONE guisp=#d787d7 gui=undercurl ctermfg=NONE ctermbg=NONE cterm=underline hi Comment guifg=#767676 guibg=NONE gui=NONE cterm=NONE -hi Constant guifg=#d7875f guibg=NONE gui=NONE cterm=NONE -hi String guifg=#87af87 guibg=NONE gui=NONE cterm=NONE -hi Character guifg=#afd7af guibg=NONE gui=NONE cterm=NONE +hi Constant guifg=#d75f87 guibg=NONE gui=NONE cterm=NONE +hi String guifg=#5faf5f guibg=NONE gui=NONE cterm=NONE +hi Character guifg=#87d787 guibg=NONE gui=NONE cterm=NONE hi Identifier guifg=#87afaf guibg=NONE gui=NONE cterm=NONE hi Statement guifg=#af87af guibg=NONE gui=NONE cterm=NONE -hi PreProc guifg=#afaf87 guibg=NONE gui=NONE cterm=NONE -hi Type guifg=#87afd7 guibg=NONE gui=NONE cterm=NONE +hi PreProc guifg=#af875f guibg=NONE gui=NONE cterm=NONE +hi Type guifg=#5f87af guibg=NONE gui=NONE cterm=NONE hi Special guifg=#5f8787 guibg=NONE gui=NONE cterm=NONE hi Underlined guifg=NONE guibg=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline -hi Title guifg=#d7d787 guibg=NONE gui=bold cterm=bold +hi Title guifg=NONE guibg=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold hi Directory guifg=#87afaf guibg=NONE gui=bold cterm=bold -hi Conceal guifg=#767676 guibg=NONE gui=NONE cterm=NONE +hi Conceal guifg=#585858 guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Debug guifg=#5f8787 guibg=NONE gui=NONE cterm=NONE hi DiffAdd guifg=#dadada guibg=#5f875f gui=NONE cterm=NONE hi DiffDelete guifg=#af875f guibg=NONE gui=NONE cterm=NONE -hi Added guifg=#87af87 guibg=NONE gui=NONE cterm=NONE -hi Changed guifg=#5f8787 guibg=NONE gui=NONE cterm=NONE +hi Added guifg=#5fd75f guibg=NONE gui=NONE cterm=NONE +hi Changed guifg=#ffaf5f guibg=NONE gui=NONE cterm=NONE hi Removed guifg=#d75f5f guibg=NONE gui=NONE cterm=NONE hi diffSubname guifg=#af87af guibg=NONE gui=NONE cterm=NONE hi DiffText guifg=#dadada guibg=#878787 gui=NONE cterm=NONE @@ -135,14 +137,14 @@ if s:t_Co >= 256 hi Normal ctermfg=250 ctermbg=234 cterm=NONE hi Statusline ctermfg=234 ctermbg=247 cterm=NONE hi StatuslineNC ctermfg=234 ctermbg=243 cterm=NONE - hi VertSplit ctermfg=243 ctermbg=243 cterm=NONE + hi VertSplit ctermfg=243 ctermbg=NONE cterm=NONE hi TabLine ctermfg=234 ctermbg=243 cterm=NONE - hi TabLineFill ctermfg=234 ctermbg=243 cterm=NONE - hi TabLineSel ctermfg=NONE ctermbg=NONE cterm=bold + hi TabLineFill ctermfg=234 ctermbg=NONE cterm=NONE + hi TabLineSel ctermfg=234 ctermbg=247 cterm=bold hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton ctermfg=247 ctermbg=234 cterm=bold,reverse + hi ToolbarButton ctermfg=243 ctermbg=234 cterm=bold,reverse hi QuickFixLine ctermfg=234 ctermbg=67 cterm=NONE - hi CursorLineNr ctermfg=215 ctermbg=NONE cterm=bold + hi CursorLineNr ctermfg=253 ctermbg=NONE cterm=bold hi LineNr ctermfg=240 ctermbg=NONE cterm=NONE hi LineNrAbove ctermfg=240 ctermbg=NONE cterm=NONE hi LineNrBelow ctermfg=240 ctermbg=NONE cterm=NONE @@ -155,53 +157,55 @@ if s:t_Co >= 256 hi Pmenu ctermfg=NONE ctermbg=237 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=243 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE - hi PmenuSel ctermfg=234 ctermbg=144 cterm=NONE - hi PmenuKind ctermfg=173 ctermbg=237 cterm=NONE - hi PmenuKindSel ctermfg=167 ctermbg=144 cterm=NONE + hi PmenuSel ctermfg=NONE ctermbg=240 cterm=NONE + hi PmenuKind ctermfg=66 ctermbg=237 cterm=NONE + hi PmenuKindSel ctermfg=66 ctermbg=240 cterm=NONE hi PmenuExtra ctermfg=243 ctermbg=237 cterm=NONE - hi PmenuExtraSel ctermfg=234 ctermbg=144 cterm=NONE + hi PmenuExtraSel ctermfg=247 ctermbg=240 cterm=NONE + hi PmenuMatch ctermfg=215 ctermbg=237 cterm=NONE + hi PmenuMatchSel ctermfg=215 ctermbg=240 cterm=NONE hi SignColumn ctermfg=NONE ctermbg=NONE cterm=NONE - hi Error ctermfg=167 ctermbg=234 cterm=reverse - hi ErrorMsg ctermfg=167 ctermbg=234 cterm=reverse - hi ModeMsg ctermfg=234 ctermbg=186 cterm=NONE - hi MoreMsg ctermfg=108 ctermbg=NONE cterm=NONE - hi Question ctermfg=144 ctermbg=NONE cterm=NONE - hi WarningMsg ctermfg=173 ctermbg=NONE cterm=NONE - hi Todo ctermfg=186 ctermbg=234 cterm=reverse + hi Error ctermfg=131 ctermbg=234 cterm=reverse + hi ErrorMsg ctermfg=131 ctermbg=234 cterm=reverse + hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold + hi MoreMsg ctermfg=71 ctermbg=NONE cterm=NONE + hi Question ctermfg=180 ctermbg=NONE cterm=NONE + hi WarningMsg ctermfg=168 ctermbg=NONE cterm=NONE + hi Todo ctermfg=180 ctermbg=234 cterm=reverse hi MatchParen ctermfg=199 ctermbg=NONE cterm=bold - hi Search ctermfg=234 ctermbg=108 cterm=NONE + hi Search ctermfg=234 ctermbg=71 cterm=NONE hi IncSearch ctermfg=234 ctermbg=215 cterm=NONE - hi CurSearch ctermfg=234 ctermbg=144 cterm=NONE - hi WildMenu ctermfg=234 ctermbg=186 cterm=NONE + hi CurSearch ctermfg=234 ctermbg=215 cterm=NONE + hi WildMenu ctermfg=234 ctermbg=180 cterm=NONE hi debugPC ctermfg=234 ctermbg=67 cterm=NONE - hi debugBreakpoint ctermfg=234 ctermbg=173 cterm=NONE + hi debugBreakpoint ctermfg=234 ctermbg=168 cterm=NONE hi CursorLine ctermfg=NONE ctermbg=236 cterm=NONE hi CursorColumn ctermfg=NONE ctermbg=236 cterm=NONE hi Folded ctermfg=247 ctermbg=235 cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=237 cterm=NONE hi SpellBad ctermfg=167 ctermbg=NONE cterm=underline - hi SpellCap ctermfg=67 ctermbg=NONE cterm=underline - hi SpellLocal ctermfg=108 ctermbg=NONE cterm=underline - hi SpellRare ctermfg=182 ctermbg=NONE cterm=underline + hi SpellCap ctermfg=215 ctermbg=NONE cterm=underline + hi SpellLocal ctermfg=77 ctermbg=NONE cterm=underline + hi SpellRare ctermfg=176 ctermbg=NONE cterm=underline hi Comment ctermfg=243 ctermbg=NONE cterm=NONE - hi Constant ctermfg=173 ctermbg=NONE cterm=NONE - hi String ctermfg=108 ctermbg=NONE cterm=NONE - hi Character ctermfg=151 ctermbg=NONE cterm=NONE + hi Constant ctermfg=168 ctermbg=NONE cterm=NONE + hi String ctermfg=71 ctermbg=NONE cterm=NONE + hi Character ctermfg=114 ctermbg=NONE cterm=NONE hi Identifier ctermfg=109 ctermbg=NONE cterm=NONE hi Statement ctermfg=139 ctermbg=NONE cterm=NONE - hi PreProc ctermfg=144 ctermbg=NONE cterm=NONE - hi Type ctermfg=110 ctermbg=NONE cterm=NONE + hi PreProc ctermfg=137 ctermbg=NONE cterm=NONE + hi Type ctermfg=67 ctermbg=NONE cterm=NONE hi Special ctermfg=66 ctermbg=NONE cterm=NONE hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline - hi Title ctermfg=186 ctermbg=NONE cterm=bold + hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=109 ctermbg=NONE cterm=bold - hi Conceal ctermfg=243 ctermbg=NONE cterm=NONE + hi Conceal ctermfg=240 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Debug ctermfg=66 ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=253 ctermbg=65 cterm=NONE hi DiffDelete ctermfg=137 ctermbg=NONE cterm=NONE - hi Added ctermfg=108 ctermbg=NONE cterm=NONE - hi Changed ctermfg=66 ctermbg=NONE cterm=NONE + hi Added ctermfg=77 ctermbg=NONE cterm=NONE + hi Changed ctermfg=215 ctermbg=NONE cterm=NONE hi Removed ctermfg=167 ctermbg=NONE cterm=NONE hi diffSubname ctermfg=139 ctermbg=NONE cterm=NONE hi DiffText ctermfg=253 ctermbg=102 cterm=NONE @@ -214,14 +218,14 @@ if s:t_Co >= 16 hi Normal ctermfg=white ctermbg=black cterm=NONE hi Statusline ctermfg=black ctermbg=gray cterm=NONE hi StatuslineNC ctermfg=black ctermbg=darkgray cterm=NONE - hi VertSplit ctermfg=darkgray ctermbg=darkgray cterm=NONE + hi VertSplit ctermfg=darkgray ctermbg=NONE cterm=NONE hi TabLine ctermfg=black ctermbg=darkgray cterm=NONE - hi TabLineFill ctermfg=black ctermbg=darkgray cterm=NONE - hi TabLineSel ctermfg=NONE ctermbg=NONE cterm=bold + hi TabLineFill ctermfg=black ctermbg=NONE cterm=NONE + hi TabLineSel ctermfg=black ctermbg=gray cterm=bold hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton ctermfg=gray ctermbg=black cterm=bold,reverse - hi QuickFixLine ctermfg=black ctermbg=blue cterm=NONE - hi CursorLineNr ctermfg=red ctermbg=NONE cterm=bold + hi ToolbarButton ctermfg=darkgray ctermbg=black cterm=bold,reverse + hi QuickFixLine ctermfg=black ctermbg=darkblue cterm=NONE + hi CursorLineNr ctermfg=white ctermbg=NONE cterm=bold hi LineNr ctermfg=darkgrey ctermbg=NONE cterm=NONE hi LineNrAbove ctermfg=darkgrey ctermbg=NONE cterm=NONE hi LineNrBelow ctermfg=darkgrey ctermbg=NONE cterm=NONE @@ -242,24 +246,24 @@ if s:t_Co >= 16 hi SignColumn ctermfg=NONE ctermbg=NONE cterm=NONE hi Error ctermfg=darkred ctermbg=black cterm=reverse hi ErrorMsg ctermfg=darkred ctermbg=black cterm=reverse - hi ModeMsg ctermfg=black ctermbg=yellow cterm=NONE + hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=darkgreen ctermbg=NONE cterm=NONE - hi Question ctermfg=darkyellow ctermbg=NONE cterm=NONE + hi Question ctermfg=yellow ctermbg=NONE cterm=NONE hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE hi Todo ctermfg=yellow ctermbg=black cterm=reverse hi MatchParen ctermfg=magenta ctermbg=NONE cterm=bold hi Search ctermfg=black ctermbg=darkgreen cterm=NONE hi IncSearch ctermfg=black ctermbg=red cterm=NONE - hi CurSearch ctermfg=black ctermbg=darkyellow cterm=NONE + hi CurSearch ctermfg=black ctermbg=red cterm=NONE hi WildMenu ctermfg=black ctermbg=yellow cterm=NONE - hi debugPC ctermfg=black ctermbg=blue cterm=NONE + hi debugPC ctermfg=black ctermbg=darkblue cterm=NONE hi debugBreakpoint ctermfg=black ctermbg=red cterm=NONE hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline hi CursorColumn ctermfg=black ctermbg=darkyellow cterm=NONE hi Folded ctermfg=black ctermbg=darkyellow cterm=NONE hi ColorColumn ctermfg=black ctermbg=darkyellow cterm=NONE hi SpellBad ctermfg=darkred ctermbg=NONE cterm=underline - hi SpellCap ctermfg=blue ctermbg=NONE cterm=underline + hi SpellCap ctermfg=darkyellow ctermbg=NONE cterm=underline hi SpellLocal ctermfg=darkgreen ctermbg=NONE cterm=underline hi SpellRare ctermfg=magenta ctermbg=NONE cterm=underline hi Comment ctermfg=darkgray ctermbg=NONE cterm=NONE @@ -269,18 +273,18 @@ if s:t_Co >= 16 hi Identifier ctermfg=cyan ctermbg=NONE cterm=NONE hi Statement ctermfg=darkmagenta ctermbg=NONE cterm=NONE hi PreProc ctermfg=darkyellow ctermbg=NONE cterm=NONE - hi Type ctermfg=blue ctermbg=NONE cterm=NONE + hi Type ctermfg=darkblue ctermbg=NONE cterm=NONE hi Special ctermfg=darkcyan ctermbg=NONE cterm=NONE hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline - hi Title ctermfg=yellow ctermbg=NONE cterm=bold + hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=cyan ctermbg=NONE cterm=bold - hi Conceal ctermfg=darkgray ctermbg=NONE cterm=NONE + hi Conceal ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Debug ctermfg=darkcyan ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE hi DiffDelete ctermfg=darkyellow ctermbg=NONE cterm=NONE hi Added ctermfg=darkgreen ctermbg=NONE cterm=NONE - hi Changed ctermfg=darkcyan ctermbg=NONE cterm=NONE + hi Changed ctermfg=darkyellow ctermbg=NONE cterm=NONE hi Removed ctermfg=darkred ctermbg=NONE cterm=NONE hi diffSubname ctermfg=darkmagenta ctermbg=NONE cterm=NONE hi DiffText ctermfg=white ctermbg=lightgrey cterm=NONE @@ -293,13 +297,13 @@ if s:t_Co >= 8 hi Normal ctermfg=gray ctermbg=black cterm=NONE hi Statusline ctermfg=gray ctermbg=black cterm=bold,reverse hi StatuslineNC ctermfg=gray ctermbg=black cterm=reverse - hi VertSplit ctermfg=gray ctermbg=black cterm=reverse + hi VertSplit ctermfg=gray ctermbg=NONE cterm=NONE hi TabLine ctermfg=black ctermbg=gray cterm=NONE - hi TabLineFill ctermfg=black ctermbg=gray cterm=NONE - hi TabLineSel ctermfg=NONE ctermbg=NONE cterm=NONE + hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=NONE + hi TabLineSel ctermfg=black ctermbg=gray cterm=bold hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton ctermfg=gray ctermbg=black cterm=bold,reverse - hi QuickFixLine ctermfg=black ctermbg=blue cterm=NONE + hi ToolbarButton ctermfg=gray ctermbg=black cterm=reverse + hi QuickFixLine ctermfg=black ctermbg=darkblue cterm=NONE hi CursorLineNr ctermfg=darkyellow ctermbg=NONE cterm=bold hi LineNr ctermfg=gray ctermbg=NONE cterm=bold hi LineNrAbove ctermfg=gray ctermbg=NONE cterm=bold @@ -321,7 +325,7 @@ if s:t_Co >= 8 hi SignColumn ctermfg=NONE ctermbg=NONE cterm=NONE hi Error ctermfg=darkred ctermbg=gray cterm=bold,reverse hi ErrorMsg ctermfg=darkred ctermbg=gray cterm=bold,reverse - hi ModeMsg ctermfg=black ctermbg=darkyellow cterm=NONE + hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=darkgreen ctermbg=NONE cterm=NONE hi Question ctermfg=darkyellow ctermbg=NONE cterm=NONE hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE @@ -331,14 +335,14 @@ if s:t_Co >= 8 hi IncSearch ctermfg=black ctermbg=darkyellow cterm=NONE hi CurSearch ctermfg=black ctermbg=darkyellow cterm=NONE hi WildMenu ctermfg=black ctermbg=darkyellow cterm=NONE - hi debugPC ctermfg=black ctermbg=blue cterm=NONE + hi debugPC ctermfg=black ctermbg=darkblue cterm=NONE hi debugBreakpoint ctermfg=black ctermbg=darkcyan cterm=NONE hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline hi CursorColumn ctermfg=black ctermbg=darkyellow cterm=NONE hi Folded ctermfg=black ctermbg=darkyellow cterm=NONE hi ColorColumn ctermfg=black ctermbg=darkyellow cterm=NONE hi SpellBad ctermfg=darkred ctermbg=gray cterm=reverse - hi SpellCap ctermfg=blue ctermbg=gray cterm=reverse + hi SpellCap ctermfg=darkblue ctermbg=gray cterm=reverse hi SpellLocal ctermfg=darkgreen ctermbg=black cterm=reverse hi SpellRare ctermfg=darkmagenta ctermbg=gray cterm=reverse hi Comment ctermfg=gray ctermbg=NONE cterm=bold @@ -348,10 +352,10 @@ if s:t_Co >= 8 hi Identifier ctermfg=gray ctermbg=NONE cterm=NONE hi Statement ctermfg=darkmagenta ctermbg=NONE cterm=NONE hi PreProc ctermfg=darkyellow ctermbg=NONE cterm=NONE - hi Type ctermfg=blue ctermbg=NONE cterm=NONE + hi Type ctermfg=darkblue ctermbg=NONE cterm=NONE hi Special ctermfg=darkcyan ctermbg=NONE cterm=NONE hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline - hi Title ctermfg=darkyellow ctermbg=NONE cterm=bold + hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=darkcyan ctermbg=NONE cterm=bold hi Conceal ctermfg=gray ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE @@ -359,7 +363,7 @@ if s:t_Co >= 8 hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE hi DiffDelete ctermfg=darkyellow ctermbg=NONE cterm=NONE hi Added ctermfg=darkgreen ctermbg=NONE cterm=NONE - hi Changed ctermfg=darkcyan ctermbg=NONE cterm=NONE + hi Changed ctermfg=darkyellow ctermbg=NONE cterm=NONE hi Removed ctermfg=darkred ctermbg=NONE cterm=NONE hi diffSubname ctermfg=darkmagenta ctermbg=NONE cterm=NONE hi DiffText ctermfg=white ctermbg=black cterm=bold,reverse @@ -437,29 +441,29 @@ if s:t_Co >= 0 endif " Background: dark -" Color: color00 #1C1C1C 234 black +" Color: color00 #1c1c1c 234 black " Color: color08 #767676 243 darkgray -" Color: color01 #D75F5F 167 darkred -" Color: color09 #D7875F 173 red -" Color: color02 #87AF87 108 darkgreen -" Color: color10 #AFD7AF 151 green -" Color: color03 #AFAF87 144 darkyellow -" Color: color11 #D7D787 186 yellow -" Color: color04 #5F87AF 67 blue -" Color: color12 #87AFD7 110 blue -" Color: color05 #AF87AF 139 darkmagenta -" Color: color13 #D7AFD7 182 magenta -" Color: color06 #5F8787 66 darkcyan -" Color: color14 #87AFAF 109 cyan -" Color: color07 #9E9E9E 247 gray -" Color: color15 #BCBCBC 250 white +" Color: color01 #af5f5f 131 darkred +" Color: color09 #d75f87 168 red +" Color: color02 #5faf5f 71 darkgreen +" Color: color10 #87d787 114 green +" Color: color03 #af875f 137 darkyellow +" Color: color11 #d7af87 180 yellow +" Color: color04 #5f87af 67 darkblue +" Color: color12 #87afd7 110 blue +" Color: color05 #af87af 139 darkmagenta +" Color: color13 #d787d7 176 magenta +" Color: color06 #5f8787 66 darkcyan +" Color: color14 #87afaf 109 cyan +" Color: color07 #9e9e9e 247 gray +" Color: color15 #bcbcbc 250 white " Color: colorLine #303030 236 darkgrey " Color: colorB #3a3a3a 237 darkgrey " Color: colorF #262626 235 darkgrey " Color: colorNonT #585858 240 darkgrey -" Color: colorC #FFAF5F 215 red -" Color: colorlC #5FFF00 82 green -" Color: colorV #1F3F5F 109 cyan +" Color: colorC #ffaf5f 215 red +" Color: colorlC #5fff00 82 green +" Color: colorV #1f3f5f 109 cyan " Color: colorMP #ff00af 199 magenta " Color: diffAdd #5f875f 65 darkgreen " Color: diffDelete #af875f 137 darkyellow @@ -467,6 +471,9 @@ endif " Color: diffText #878787 102 lightgrey " Color: black #000000 16 black " Color: white #dadada 253 white +" Color: Added #5fd75f 77 darkgreen +" Color: Changed #ffaf5f 215 darkyellow +" Color: Removed #d75f5f 167 darkred " Term colors: color00 color01 color02 color03 color04 color05 color06 color07 " Term colors: color08 color09 color10 color11 color12 color13 color14 color15 " vim: et ts=8 sw=2 sts=2 diff --git a/runtime/colors/industry.vim b/runtime/colors/industry.vim index dd40f34cf4..f267f55dc0 100644 --- a/runtime/colors/industry.vim +++ b/runtime/colors/industry.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Shian Lee. " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:36 +" Last Updated: Sat 06 Jul 2024 14:32:15 " Generated by Colortemplate v2.2.3 @@ -29,6 +29,8 @@ hi Pmenu guifg=#dadada guibg=#444444 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#ffff00 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#000000 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#6c6c6c gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff00ff guibg=#444444 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff00ff guibg=#ffff00 gui=NONE cterm=NONE hi TabLine guifg=#dadada guibg=#444444 gui=NONE cterm=NONE hi TabLineFill guifg=NONE guibg=#6c6c6c gui=NONE cterm=NONE hi TabLineSel guifg=#ffffff guibg=#000000 gui=bold cterm=bold @@ -103,6 +105,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=16 ctermbg=226 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=16 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=242 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=238 cterm=NONE + hi PmenuMatchSel ctermfg=201 ctermbg=226 cterm=NONE hi TabLine ctermfg=253 ctermbg=238 cterm=NONE hi TabLineFill ctermfg=NONE ctermbg=242 cterm=NONE hi TabLineSel ctermfg=231 ctermbg=16 cterm=bold @@ -180,6 +184,8 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=black ctermbg=yellow cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=black cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=grey cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=magenta ctermbg=yellow cterm=NONE hi TabLine ctermfg=white ctermbg=darkgrey cterm=NONE hi TabLineFill ctermfg=NONE ctermbg=grey cterm=NONE hi TabLineSel ctermfg=white ctermbg=black cterm=bold diff --git a/runtime/colors/koehler.vim b/runtime/colors/koehler.vim index 71858f0507..3629c9e6b3 100644 --- a/runtime/colors/koehler.vim +++ b/runtime/colors/koehler.vim @@ -3,7 +3,7 @@ " Maintainer: original maintainer Ron Aaron " Website: https://www.github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:36 +" Last Updated: Wed 10 Jul 2024 17:32:50 " Generated by Colortemplate v2.2.3 @@ -62,7 +62,7 @@ hi CursorLine guifg=NONE guibg=#555555 gui=NONE cterm=NONE hi CursorLineNr guifg=#ffff00 guibg=NONE gui=bold cterm=bold hi Folded guifg=#00cdcd guibg=#666666 gui=NONE cterm=NONE hi QuickFixLine guifg=#000000 guibg=#ffff00 gui=NONE cterm=NONE -hi Conceal guifg=#e5e5e5 guibg=#a9a9a9 gui=NONE cterm=NONE +hi Conceal guifg=#666666 guibg=NONE gui=NONE cterm=NONE hi Cursor guifg=#000000 guibg=#00ff00 gui=NONE cterm=NONE hi Directory guifg=#cc8000 guibg=NONE gui=NONE cterm=NONE hi EndOfBuffer guifg=#cd0000 guibg=NONE gui=bold cterm=bold @@ -77,6 +77,8 @@ hi Pmenu guifg=#ffffff guibg=#444444 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#00cdcd gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#ffffff gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff00ff guibg=#444444 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff0000 guibg=#00cdcd gui=NONE cterm=NONE hi Question guifg=#5c5cff guibg=NONE gui=bold cterm=bold hi Search guifg=#ffffff guibg=#ff0000 gui=NONE cterm=NONE hi SignColumn guifg=#00ffff guibg=NONE gui=NONE cterm=NONE @@ -123,7 +125,7 @@ if s:t_Co >= 256 hi CursorLineNr ctermfg=226 ctermbg=NONE cterm=bold hi Folded ctermfg=44 ctermbg=59 cterm=NONE hi QuickFixLine ctermfg=16 ctermbg=226 cterm=NONE - hi Conceal ctermfg=254 ctermbg=145 cterm=NONE + hi Conceal ctermfg=59 ctermbg=NONE cterm=NONE hi Cursor ctermfg=16 ctermbg=46 cterm=NONE hi Directory ctermfg=172 ctermbg=NONE cterm=NONE hi EndOfBuffer ctermfg=160 ctermbg=NONE cterm=bold @@ -138,6 +140,8 @@ if s:t_Co >= 256 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=16 ctermbg=44 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=231 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=238 cterm=NONE + hi PmenuMatchSel ctermfg=196 ctermbg=44 cterm=NONE hi Question ctermfg=63 ctermbg=NONE cterm=bold hi Search ctermfg=231 ctermbg=196 cterm=NONE hi SignColumn ctermfg=51 ctermbg=NONE cterm=NONE @@ -187,7 +191,7 @@ if s:t_Co >= 16 hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline hi Folded ctermfg=darkblue ctermbg=NONE cterm=NONE hi QuickFixLine ctermfg=black ctermbg=yellow cterm=NONE - hi Conceal ctermfg=grey ctermbg=grey cterm=NONE + hi Conceal ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Cursor ctermfg=black ctermbg=green cterm=NONE hi Directory ctermfg=darkyellow ctermbg=NONE cterm=NONE hi EndOfBuffer ctermfg=darkred ctermbg=NONE cterm=bold @@ -202,6 +206,8 @@ if s:t_Co >= 16 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=black ctermbg=darkcyan cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=white cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=red ctermbg=darkcyan cterm=NONE hi Question ctermfg=blue ctermbg=NONE cterm=bold hi Search ctermfg=white ctermbg=red cterm=NONE hi SignColumn ctermfg=cyan ctermbg=NONE cterm=NONE diff --git a/runtime/colors/lunaperche.vim b/runtime/colors/lunaperche.vim index 3546710a3d..4dca8d6d01 100644 --- a/runtime/colors/lunaperche.vim +++ b/runtime/colors/lunaperche.vim @@ -4,7 +4,7 @@ " Maintainer: Maxim Kim " Website: https://www.github.com/vim/colorschemes " License: Vim License (see `:help license`) -" Last Updated: Mon 08 Jan 2024 09:41:03 AM AEDT +" Last Updated: Wed 10 Jul 2024 17:22:08 " Generated by Colortemplate v2.2.3 @@ -120,6 +120,8 @@ if &background ==# 'dark' hi PmenuKindSel guifg=#ff5f5f guibg=#4e4e4e gui=NONE cterm=NONE hi PmenuExtra guifg=#767676 guibg=#303030 gui=NONE cterm=NONE hi PmenuExtraSel guifg=#767676 guibg=#4e4e4e gui=NONE cterm=NONE + hi PmenuMatch guifg=#d787d7 guibg=#303030 gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#d787d7 guibg=#4e4e4e gui=NONE cterm=NONE hi SignColumn guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Error guifg=#ffffff guibg=#ff5f5f gui=NONE cterm=NONE hi ErrorMsg guifg=#ffffff guibg=#ff5f5f gui=NONE cterm=NONE @@ -158,7 +160,7 @@ if &background ==# 'dark' hi Underlined guifg=NONE guibg=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline hi Title guifg=NONE guibg=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold hi Directory guifg=#5fafff guibg=NONE gui=bold cterm=bold - hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal guifg=#585858 guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd guifg=#c6c6c6 guibg=#875f87 gui=NONE cterm=NONE hi DiffChange guifg=#c6c6c6 guibg=#5f5f5f gui=NONE cterm=NONE @@ -211,6 +213,8 @@ else hi PmenuKindSel guifg=#af0000 guibg=#c6c6c6 gui=NONE cterm=NONE hi PmenuExtra guifg=#767676 guibg=#e4e4e4 gui=NONE cterm=NONE hi PmenuExtraSel guifg=#767676 guibg=#c6c6c6 gui=NONE cterm=NONE + hi PmenuMatch guifg=#af00af guibg=#e4e4e4 gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#af00af guibg=#c6c6c6 gui=NONE cterm=NONE hi SignColumn guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Error guifg=#ffffff guibg=#d70000 gui=NONE cterm=NONE hi ErrorMsg guifg=#ffffff guibg=#d70000 gui=NONE cterm=NONE @@ -249,7 +253,7 @@ else hi Underlined guifg=NONE guibg=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline hi Title guifg=NONE guibg=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold hi Directory guifg=#005fd7 guibg=NONE gui=bold cterm=bold - hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal guifg=#9e9e9e guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd guifg=#000000 guibg=#d7afd7 gui=NONE cterm=NONE hi DiffChange guifg=#000000 guibg=#d0d0d0 gui=NONE cterm=NONE @@ -381,6 +385,8 @@ if s:t_Co >= 256 hi PmenuKindSel ctermfg=203 ctermbg=239 cterm=NONE hi PmenuExtra ctermfg=243 ctermbg=236 cterm=NONE hi PmenuExtraSel ctermfg=243 ctermbg=239 cterm=NONE + hi PmenuMatch ctermfg=176 ctermbg=236 cterm=NONE + hi PmenuMatchSel ctermfg=176 ctermbg=239 cterm=NONE hi SignColumn ctermfg=NONE ctermbg=NONE cterm=NONE hi Error ctermfg=231 ctermbg=203 cterm=NONE hi ErrorMsg ctermfg=231 ctermbg=203 cterm=NONE @@ -417,7 +423,7 @@ if s:t_Co >= 256 hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=75 ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=240 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=251 ctermbg=96 cterm=NONE hi DiffChange ctermfg=251 ctermbg=59 cterm=NONE @@ -467,6 +473,8 @@ if s:t_Co >= 256 hi PmenuKindSel ctermfg=124 ctermbg=251 cterm=NONE hi PmenuExtra ctermfg=243 ctermbg=254 cterm=NONE hi PmenuExtraSel ctermfg=243 ctermbg=251 cterm=NONE + hi PmenuMatch ctermfg=127 ctermbg=254 cterm=NONE + hi PmenuMatchSel ctermfg=127 ctermbg=251 cterm=NONE hi SignColumn ctermfg=NONE ctermbg=NONE cterm=NONE hi Error ctermfg=231 ctermbg=160 cterm=NONE hi ErrorMsg ctermfg=231 ctermbg=160 cterm=NONE @@ -503,7 +511,7 @@ if s:t_Co >= 256 hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=26 ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=247 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=16 ctermbg=182 cterm=NONE hi DiffChange ctermfg=16 ctermbg=252 cterm=NONE @@ -594,7 +602,7 @@ if s:t_Co >= 16 hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=blue ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=grey ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=white ctermbg=darkmagenta cterm=NONE hi DiffChange ctermfg=white ctermbg=darkgreen cterm=NONE @@ -680,7 +688,7 @@ if s:t_Co >= 16 hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=darkblue ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=black ctermbg=darkmagenta cterm=NONE hi DiffChange ctermfg=black ctermbg=lightgray cterm=NONE diff --git a/runtime/colors/morning.vim b/runtime/colors/morning.vim index 1644b04df8..442b859aac 100644 --- a/runtime/colors/morning.vim +++ b/runtime/colors/morning.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Bram Moolenaar " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:37 +" Last Updated: Wed 10 Jul 2024 17:35:47 " Generated by Colortemplate v2.2.3 @@ -42,6 +42,8 @@ hi Pmenu guifg=#000000 guibg=#b2b2b2 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#ffff00 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#e4e4e4 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#000000 gui=NONE cterm=NONE +hi PmenuMatch guifg=#a52a2a guibg=#b2b2b2 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#a52a2a guibg=#ffff00 gui=NONE cterm=NONE hi TabLine guifg=#000000 guibg=#bcbcbc gui=underline cterm=underline hi TabLineFill guifg=NONE guibg=NONE gui=reverse ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel guifg=#000000 guibg=#e4e4e4 gui=bold cterm=bold @@ -82,7 +84,7 @@ hi Type guifg=#2e8b57 guibg=NONE gui=bold cterm=bold hi Special guifg=#6a5acd guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Directory guifg=#008787 guibg=NONE gui=bold cterm=bold -hi Conceal guifg=#0000ff guibg=NONE gui=NONE cterm=NONE +hi Conceal guifg=#878787 guibg=NONE gui=NONE cterm=NONE hi Title guifg=#a52a2a guibg=NONE gui=bold cterm=bold hi DiffAdd guifg=#ffffff guibg=#5f875f gui=NONE cterm=NONE hi DiffChange guifg=#ffffff guibg=#5f87af gui=NONE cterm=NONE @@ -114,6 +116,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=16 ctermbg=226 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=254 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=16 cterm=NONE + hi PmenuMatch ctermfg=124 ctermbg=249 cterm=NONE + hi PmenuMatchSel ctermfg=124 ctermbg=226 cterm=NONE hi TabLine ctermfg=16 ctermbg=250 cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=16 ctermbg=254 cterm=bold @@ -154,7 +158,7 @@ if s:t_Co >= 256 hi Special ctermfg=62 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Directory ctermfg=30 ctermbg=NONE cterm=bold - hi Conceal ctermfg=21 ctermbg=NONE cterm=NONE + hi Conceal ctermfg=102 ctermbg=NONE cterm=NONE hi Title ctermfg=124 ctermbg=NONE cterm=bold hi DiffAdd ctermfg=231 ctermbg=65 cterm=NONE hi DiffChange ctermfg=231 ctermbg=67 cterm=NONE @@ -179,6 +183,8 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=black ctermbg=yellow cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=grey cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=black cterm=NONE + hi PmenuMatch ctermfg=darkred ctermbg=white cterm=NONE + hi PmenuMatchSel ctermfg=darkred ctermbg=yellow cterm=NONE hi TabLine ctermfg=black ctermbg=white cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=black ctermbg=grey cterm=bold @@ -219,7 +225,7 @@ if s:t_Co >= 16 hi Special ctermfg=darkblue ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Directory ctermfg=darkcyan ctermbg=NONE cterm=bold - hi Conceal ctermfg=blue ctermbg=NONE cterm=NONE + hi Conceal ctermfg=gray ctermbg=NONE cterm=NONE hi Title ctermfg=darkred ctermbg=NONE cterm=bold hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE hi DiffChange ctermfg=white ctermbg=blue cterm=NONE diff --git a/runtime/colors/murphy.vim b/runtime/colors/murphy.vim index a6a08ed41a..3026be32e5 100644 --- a/runtime/colors/murphy.vim +++ b/runtime/colors/murphy.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Ron Aaron . " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Mon 08 Jan 2024 09:50:15 AM AEDT +" Last Updated: Tue 09 Jul 2024 16:49:50 " Generated by Colortemplate v2.2.3 @@ -38,6 +38,8 @@ hi Pmenu guifg=#ffffff guibg=#444444 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#ffff00 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#303030 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#bcbcbc gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff00ff guibg=#444444 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff00ff guibg=#ffff00 gui=NONE cterm=NONE hi TabLineFill guifg=NONE guibg=#303030 gui=NONE cterm=NONE hi TabLine guifg=#87ff87 guibg=#444444 gui=NONE cterm=NONE hi TabLineSel guifg=#ffffff guibg=#000000 gui=NONE cterm=NONE @@ -111,6 +113,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=16 ctermbg=226 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=236 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=250 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=238 cterm=NONE + hi PmenuMatchSel ctermfg=201 ctermbg=226 cterm=NONE hi TabLineFill ctermfg=NONE ctermbg=236 cterm=NONE hi TabLine ctermfg=120 ctermbg=238 cterm=NONE hi TabLineSel ctermfg=231 ctermbg=16 cterm=NONE @@ -176,6 +180,8 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=black ctermbg=yellow cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=black cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=grey cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=magenta ctermbg=yellow cterm=NONE hi TabLineFill ctermfg=NONE ctermbg=grey cterm=NONE hi TabLine ctermfg=green ctermbg=darkgrey cterm=NONE hi TabLineSel ctermfg=white ctermbg=black cterm=NONE diff --git a/runtime/colors/pablo.vim b/runtime/colors/pablo.vim index bd5693ec8b..b5046b4a3b 100644 --- a/runtime/colors/pablo.vim +++ b/runtime/colors/pablo.vim @@ -3,7 +3,7 @@ " Maintainer: Original maintainerRon Aaron " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:38 +" Last Updated: Wed 10 Jul 2024 17:37:50 " Generated by Colortemplate v2.2.3 @@ -37,7 +37,7 @@ hi Underlined guifg=#80a0ff guibg=NONE gui=underline cterm=underline hi Ignore guifg=#000000 guibg=#000000 gui=NONE cterm=NONE hi Error guifg=#ffffff guibg=#ff0000 gui=NONE cterm=NONE hi Todo guifg=#000000 guibg=#c0c000 gui=NONE cterm=NONE -hi Conceal guifg=#e5e5e5 guibg=#a9a9a9 gui=NONE cterm=NONE +hi Conceal guifg=#666666 guibg=NONE gui=NONE cterm=NONE hi Cursor guifg=#000000 guibg=#ffffff gui=NONE cterm=NONE hi lCursor guifg=#000000 guibg=#ffffff gui=NONE cterm=NONE hi CursorIM guifg=NONE guibg=fg gui=NONE cterm=NONE @@ -84,6 +84,8 @@ hi Pmenu guifg=fg guibg=#303030 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#e5e5e5 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#ffffff gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff00ff guibg=#303030 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff00ff guibg=#e5e5e5 gui=NONE cterm=NONE hi DiffAdd guifg=#ffffff guibg=#5f875f gui=NONE cterm=NONE hi DiffChange guifg=#ffffff guibg=#5f87af gui=NONE cterm=NONE hi DiffText guifg=#000000 guibg=#c6c6c6 gui=NONE cterm=NONE @@ -110,7 +112,7 @@ if s:t_Co >= 256 hi Ignore ctermfg=16 ctermbg=16 cterm=NONE hi Error ctermfg=231 ctermbg=196 cterm=NONE hi Todo ctermfg=16 ctermbg=142 cterm=NONE - hi Conceal ctermfg=254 ctermbg=248 cterm=NONE + hi Conceal ctermfg=241 ctermbg=NONE cterm=NONE hi Cursor ctermfg=16 ctermbg=231 cterm=NONE hi lCursor ctermfg=16 ctermbg=231 cterm=NONE hi CursorIM ctermfg=NONE ctermbg=fg cterm=NONE @@ -157,6 +159,8 @@ if s:t_Co >= 256 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=16 ctermbg=254 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=231 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=236 cterm=NONE + hi PmenuMatchSel ctermfg=201 ctermbg=254 cterm=NONE hi DiffAdd ctermfg=231 ctermbg=65 cterm=NONE hi DiffChange ctermfg=231 ctermbg=67 cterm=NONE hi DiffText ctermfg=16 ctermbg=251 cterm=NONE @@ -178,7 +182,7 @@ if s:t_Co >= 16 hi Ignore ctermfg=black ctermbg=black cterm=NONE hi Error ctermfg=white ctermbg=red cterm=NONE hi Todo ctermfg=black ctermbg=darkyellow cterm=NONE - hi Conceal ctermfg=grey ctermbg=grey cterm=NONE + hi Conceal ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Cursor ctermfg=black ctermbg=white cterm=NONE hi lCursor ctermfg=black ctermbg=white cterm=NONE hi CursorIM ctermfg=NONE ctermbg=fg cterm=NONE @@ -225,6 +229,8 @@ if s:t_Co >= 16 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=black ctermbg=grey cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=white cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=magenta ctermbg=grey cterm=NONE hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE hi DiffChange ctermfg=white ctermbg=blue cterm=NONE hi DiffText ctermfg=black ctermbg=grey cterm=NONE diff --git a/runtime/colors/peachpuff.vim b/runtime/colors/peachpuff.vim index 392945a375..89614a8b6d 100644 --- a/runtime/colors/peachpuff.vim +++ b/runtime/colors/peachpuff.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer David Ne\v{c}as (Yeti) " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:39 +" Last Updated: Wed 10 Jul 2024 17:38:47 " Generated by Colortemplate v2.2.3 @@ -42,6 +42,8 @@ hi Pmenu guifg=#000000 guibg=#ffaf87 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#f5c195 gui=bold cterm=bold hi PmenuSbar guifg=NONE guibg=#ffdab9 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#737373 gui=NONE cterm=NONE +hi PmenuMatch guifg=#a52a2a guibg=#ffaf87 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#a52a2a guibg=#f5c195 gui=bold cterm=bold hi TabLine guifg=#ffdab9 guibg=#737373 gui=underline cterm=underline hi TabLineFill guifg=NONE guibg=NONE gui=reverse ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel guifg=#000000 guibg=#ffdab9 gui=bold cterm=bold @@ -81,7 +83,7 @@ hi PreProc guifg=#cd00cd guibg=NONE gui=NONE cterm=NONE hi Type guifg=#2e8b57 guibg=NONE gui=bold cterm=bold hi Special guifg=#6a5acd guibg=NONE gui=NONE cterm=NONE hi Directory guifg=#008b8b guibg=NONE gui=bold cterm=bold -hi Conceal guifg=#406090 guibg=NONE gui=NONE cterm=NONE +hi Conceal guifg=#737373 guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Title guifg=#cd00cd guibg=NONE gui=bold cterm=bold hi DiffAdd guifg=#ffffff guibg=#5f875f gui=NONE cterm=NONE @@ -114,6 +116,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=16 ctermbg=180 cterm=bold hi PmenuSbar ctermfg=NONE ctermbg=223 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=243 cterm=NONE + hi PmenuMatch ctermfg=124 ctermbg=216 cterm=NONE + hi PmenuMatchSel ctermfg=124 ctermbg=180 cterm=bold hi TabLine ctermfg=223 ctermbg=243 cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=16 ctermbg=223 cterm=bold @@ -153,7 +157,7 @@ if s:t_Co >= 256 hi Type ctermfg=29 ctermbg=NONE cterm=bold hi Special ctermfg=62 ctermbg=NONE cterm=NONE hi Directory ctermfg=30 ctermbg=NONE cterm=bold - hi Conceal ctermfg=25 ctermbg=NONE cterm=NONE + hi Conceal ctermfg=243 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Title ctermfg=164 ctermbg=NONE cterm=bold hi DiffAdd ctermfg=231 ctermbg=65 cterm=NONE @@ -181,6 +185,8 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=black ctermbg=yellow cterm=bold hi PmenuSbar ctermfg=NONE ctermbg=white cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=darkgrey cterm=NONE + hi PmenuMatch ctermfg=darkred ctermbg=grey cterm=NONE + hi PmenuMatchSel ctermfg=darkred ctermbg=yellow cterm=bold hi TabLine ctermfg=white ctermbg=darkgrey cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=black ctermbg=white cterm=bold diff --git a/runtime/colors/quiet.vim b/runtime/colors/quiet.vim index 1a8603a8a0..b1bf80722c 100644 --- a/runtime/colors/quiet.vim +++ b/runtime/colors/quiet.vim @@ -4,7 +4,7 @@ " Maintainer: Maxence Weynans " Website: https://github.com/vim/colorschemes " License: Vim License (see `:help license`)` -" Last Updated: Fri 15 Dec 2023 20:05:39 +" Last Updated: Mon 24 Jun 2024 01:47:26 AM CEST " Generated by Colortemplate v2.2.3 @@ -13,6 +13,9 @@ let g:colors_name = 'quiet' let s:t_Co = has('gui_running') ? -1 : (&t_Co ?? 0) +hi! link Added Normal +hi! link Changed Normal +hi! link Removed Normal hi! link Terminal Normal hi! link StatusLineTerm StatusLine hi! link StatusLineTermNC StatusLineNC @@ -74,10 +77,12 @@ if &background ==# 'dark' hi MoreMsg guifg=#dadada guibg=NONE gui=NONE cterm=NONE hi NonText guifg=#707070 guibg=NONE gui=NONE cterm=NONE hi Pmenu guifg=#000000 guibg=#a8a8a8 gui=NONE cterm=NONE + hi PmenuMatch guifg=#d7005f guibg=#a8a8a8 gui=NONE cterm=NONE hi PmenuExtra guifg=#000000 guibg=#a8a8a8 gui=NONE cterm=NONE hi PmenuKind guifg=#000000 guibg=#a8a8a8 gui=bold cterm=bold hi PmenuSbar guifg=#707070 guibg=#585858 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#dadada gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#d7005f guibg=#dadada gui=bold cterm=bold hi PmenuExtraSel guifg=#000000 guibg=#dadada gui=NONE cterm=NONE hi PmenuKindSel guifg=#000000 guibg=#dadada gui=bold cterm=bold hi PmenuThumb guifg=#dadada guibg=#dadada gui=NONE cterm=NONE @@ -144,10 +149,12 @@ else hi MoreMsg guifg=#000000 guibg=NONE gui=NONE cterm=NONE hi NonText guifg=#626262 guibg=NONE gui=NONE cterm=NONE hi Pmenu guifg=#000000 guibg=#a8a8a8 gui=NONE cterm=NONE + hi PmenuMatch guifg=#d70000 guibg=#a8a8a8 gui=NONE cterm=NONE hi PmenuExtra guifg=#000000 guibg=#a8a8a8 gui=NONE cterm=NONE hi PmenuKind guifg=#000000 guibg=#a8a8a8 gui=bold cterm=bold hi PmenuSbar guifg=#000000 guibg=#e4e4e4 gui=NONE cterm=NONE hi PmenuSel guifg=#d7d7d7 guibg=#000000 gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#d70000 guibg=#000000 gui=bold cterm=bold hi PmenuExtraSel guifg=#d7d7d7 guibg=#000000 gui=NONE cterm=NONE hi PmenuKindSel guifg=#d7d7d7 guibg=#000000 gui=bold cterm=bold hi PmenuThumb guifg=#000000 guibg=#000000 gui=NONE cterm=NONE @@ -213,10 +220,12 @@ if s:t_Co >= 256 hi MoreMsg ctermfg=253 ctermbg=NONE cterm=NONE hi NonText ctermfg=242 ctermbg=NONE cterm=NONE hi Pmenu ctermfg=16 ctermbg=248 cterm=NONE + hi PmenuMatch ctermfg=161 ctermbg=248 cterm=NONE hi PmenuExtra ctermfg=16 ctermbg=248 cterm=NONE hi PmenuKind ctermfg=16 ctermbg=248 cterm=bold hi PmenuSbar ctermfg=242 ctermbg=240 cterm=NONE hi PmenuSel ctermfg=16 ctermbg=253 cterm=NONE + hi PmenuMatchSel ctermfg=161 ctermbg=253 cterm=bold hi PmenuExtraSel ctermfg=16 ctermbg=253 cterm=NONE hi PmenuKindSel ctermfg=16 ctermbg=253 cterm=bold hi PmenuThumb ctermfg=253 ctermbg=253 cterm=NONE @@ -280,10 +289,12 @@ if s:t_Co >= 256 hi MoreMsg ctermfg=16 ctermbg=NONE cterm=NONE hi NonText ctermfg=241 ctermbg=NONE cterm=NONE hi Pmenu ctermfg=16 ctermbg=248 cterm=NONE + hi PmenuMatch ctermfg=160 ctermbg=248 cterm=NONE hi PmenuExtra ctermfg=16 ctermbg=248 cterm=NONE hi PmenuKind ctermfg=16 ctermbg=248 cterm=bold hi PmenuSbar ctermfg=16 ctermbg=254 cterm=NONE hi PmenuSel ctermfg=188 ctermbg=16 cterm=NONE + hi PmenuMatchSel ctermfg=160 ctermbg=16 cterm=bold hi PmenuExtraSel ctermfg=188 ctermbg=16 cterm=NONE hi PmenuKindSel ctermfg=188 ctermbg=16 cterm=bold hi PmenuThumb ctermfg=16 ctermbg=16 cterm=NONE @@ -359,9 +370,11 @@ if s:t_Co >= 16 hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=NONE ctermbg=NONE cterm=NONE hi Pmenu ctermfg=NONE ctermbg=NONE cterm=reverse + hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse hi PmenuExtra ctermfg=NONE ctermbg=NONE cterm=reverse hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold + hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE @@ -425,9 +438,11 @@ if s:t_Co >= 16 hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=NONE ctermbg=NONE cterm=NONE hi Pmenu ctermfg=NONE ctermbg=NONE cterm=reverse + hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse hi PmenuExtra ctermfg=NONE ctermbg=NONE cterm=reverse hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold + hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE @@ -498,9 +513,11 @@ if s:t_Co >= 8 hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=NONE ctermbg=NONE cterm=NONE hi Pmenu ctermfg=NONE ctermbg=NONE cterm=reverse + hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse hi PmenuExtra ctermfg=NONE ctermbg=NONE cterm=reverse hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold + hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE @@ -564,9 +581,11 @@ if s:t_Co >= 8 hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=NONE ctermbg=NONE cterm=NONE hi Pmenu ctermfg=NONE ctermbg=NONE cterm=reverse + hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse hi PmenuExtra ctermfg=NONE ctermbg=NONE cterm=reverse hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold + hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE diff --git a/runtime/colors/retrobox.vim b/runtime/colors/retrobox.vim index 46d269f983..1cab59f08e 100644 --- a/runtime/colors/retrobox.vim +++ b/runtime/colors/retrobox.vim @@ -4,7 +4,7 @@ " Maintainer: Maxim Kim , ported from gruvbox8 of Lifepillar " Website: https://www.github.com/vim/colorschemes " License: Vim License (see `:help license`) -" Last Updated: Fri 15 Dec 2023 20:05:40 +" Last Updated: Thu 11 Jul 2024 09:50:48 AM AEST " Generated by Colortemplate v2.2.3 @@ -21,14 +21,15 @@ hi! link Tag Special hi! link lCursor Cursor hi! link MessageWindow PMenu hi! link PopupNotification Todo -hi! link CurSearch Search +hi! link CurSearch IncSearch +hi! link Terminal Normal if &background ==# 'dark' if (has('termguicolors') && &termguicolors) || has('gui_running') let g:terminal_ansi_colors = ['#1c1c1c', '#cc241d', '#98971a', '#d79921', '#458588', '#b16286', '#689d6a', '#a89984', '#928374', '#fb4934', '#b8bb26', '#fabd2f', '#83a598', '#d3869b', '#8ec07c', '#ebdbb2'] endif hi Normal guifg=#ebdbb2 guibg=#1c1c1c gui=NONE cterm=NONE - hi CursorLineNr guifg=#fabd2f guibg=#303030 gui=NONE cterm=NONE + hi CursorLineNr guifg=#fabd2f guibg=#1c1c1c gui=bold cterm=bold hi FoldColumn guifg=#928374 guibg=#1c1c1c gui=NONE cterm=NONE hi SignColumn guifg=#928374 guibg=#1c1c1c gui=NONE cterm=NONE hi VertSplit guifg=#303030 guibg=#1c1c1c gui=NONE cterm=NONE @@ -49,6 +50,8 @@ if &background ==# 'dark' hi PmenuKindSel guifg=#fb4934 guibg=#83a598 gui=NONE cterm=NONE hi PmenuExtra guifg=#a89984 guibg=#3c3836 gui=NONE cterm=NONE hi PmenuExtraSel guifg=#303030 guibg=#83a598 gui=NONE cterm=NONE + hi PmenuMatch guifg=#b16286 guibg=#3c3836 gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#b16286 guibg=#83a598 gui=bold cterm=bold hi SpecialKey guifg=#928374 guibg=NONE gui=NONE cterm=NONE hi StatusLine guifg=#504945 guibg=#ebdbb2 gui=bold,reverse cterm=bold,reverse hi StatusLineNC guifg=#3c3836 guibg=#a89984 gui=reverse cterm=reverse @@ -60,7 +63,7 @@ if &background ==# 'dark' hi Visual guifg=#1c1c1c guibg=#83a598 gui=NONE cterm=NONE hi WildMenu guifg=#83a598 guibg=#504945 gui=bold cterm=bold hi EndOfBuffer guifg=#504945 guibg=NONE gui=NONE cterm=NONE - hi Conceal guifg=#83a598 guibg=NONE gui=NONE cterm=NONE + hi Conceal guifg=#504945 guibg=NONE gui=NONE cterm=NONE hi Cursor guifg=#1c1c1c guibg=#fbf1c7 gui=NONE cterm=NONE hi DiffAdd guifg=#b8bb26 guibg=#1c1c1c gui=reverse cterm=reverse hi DiffChange guifg=#8ec07c guibg=#1c1c1c gui=reverse cterm=reverse @@ -119,7 +122,7 @@ else let g:terminal_ansi_colors = ['#3c3836', '#cc241d', '#98971a', '#d79921', '#458588', '#b16286', '#689d6a', '#7c6f64', '#928374', '#9d0006', '#79740e', '#b57614', '#076678', '#8f3f71', '#427b58', '#fbf1c7'] endif hi Normal guifg=#3c3836 guibg=#fbf1c7 gui=NONE cterm=NONE - hi CursorLineNr guifg=#b57614 guibg=#e5d4b1 gui=NONE cterm=NONE + hi CursorLineNr guifg=#b57614 guibg=#fbf1c7 gui=bold cterm=bold hi FoldColumn guifg=#928374 guibg=#fbf1c7 gui=NONE cterm=NONE hi SignColumn guifg=#3c3836 guibg=#fbf1c7 gui=NONE cterm=NONE hi VertSplit guifg=#bdae93 guibg=#fbf1c7 gui=NONE cterm=NONE @@ -140,6 +143,8 @@ else hi PmenuKindSel guifg=#9d0006 guibg=#076678 gui=NONE cterm=NONE hi PmenuExtra guifg=#7c6f64 guibg=#e5d4b1 gui=NONE cterm=NONE hi PmenuExtraSel guifg=#bdae93 guibg=#076678 gui=NONE cterm=NONE + hi PmenuMatch guifg=#8f3f71 guibg=#e5d4b1 gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#d3869b guibg=#076678 gui=bold cterm=bold hi SpecialKey guifg=#928374 guibg=NONE gui=NONE cterm=NONE hi StatusLine guifg=#bdae93 guibg=#3c3836 gui=bold,reverse cterm=bold,reverse hi StatusLineNC guifg=#ebdbb2 guibg=#3c3836 gui=reverse cterm=reverse @@ -151,7 +156,7 @@ else hi Visual guifg=#fbf1c7 guibg=#076678 gui=NONE cterm=NONE hi WildMenu guifg=#076678 guibg=#e5d4b1 gui=bold cterm=bold hi EndOfBuffer guifg=#e5d4b1 guibg=NONE gui=NONE cterm=NONE - hi Conceal guifg=#076678 guibg=NONE gui=NONE cterm=NONE + hi Conceal guifg=#a89984 guibg=NONE gui=NONE cterm=NONE hi Cursor guifg=#fbf1c7 guibg=#282828 gui=NONE cterm=NONE hi DiffAdd guifg=#79740e guibg=#fbf1c7 gui=reverse cterm=reverse hi DiffChange guifg=#427b58 guibg=#fbf1c7 gui=reverse cterm=reverse @@ -209,7 +214,7 @@ endif if s:t_Co >= 256 if &background ==# 'dark' hi Normal ctermfg=187 ctermbg=234 cterm=NONE - hi CursorLineNr ctermfg=214 ctermbg=236 cterm=NONE + hi CursorLineNr ctermfg=214 ctermbg=234 cterm=bold hi FoldColumn ctermfg=102 ctermbg=234 cterm=NONE hi SignColumn ctermfg=102 ctermbg=234 cterm=NONE hi VertSplit ctermfg=236 ctermbg=234 cterm=NONE @@ -230,6 +235,8 @@ if s:t_Co >= 256 hi PmenuKindSel ctermfg=203 ctermbg=109 cterm=NONE hi PmenuExtra ctermfg=102 ctermbg=237 cterm=NONE hi PmenuExtraSel ctermfg=236 ctermbg=109 cterm=NONE + hi PmenuMatch ctermfg=132 ctermbg=237 cterm=NONE + hi PmenuMatchSel ctermfg=132 ctermbg=109 cterm=bold hi SpecialKey ctermfg=102 ctermbg=NONE cterm=NONE hi StatusLine ctermfg=239 ctermbg=187 cterm=bold,reverse hi StatusLineNC ctermfg=237 ctermbg=102 cterm=reverse @@ -241,7 +248,7 @@ if s:t_Co >= 256 hi Visual ctermfg=234 ctermbg=109 cterm=NONE hi WildMenu ctermfg=109 ctermbg=239 cterm=bold hi EndOfBuffer ctermfg=239 ctermbg=NONE cterm=NONE - hi Conceal ctermfg=109 ctermbg=NONE cterm=NONE + hi Conceal ctermfg=239 ctermbg=NONE cterm=NONE hi Cursor ctermfg=234 ctermbg=230 cterm=NONE hi DiffAdd ctermfg=142 ctermbg=234 cterm=reverse hi DiffChange ctermfg=107 ctermbg=234 cterm=reverse @@ -297,7 +304,7 @@ if s:t_Co >= 256 else " Light background hi Normal ctermfg=237 ctermbg=230 cterm=NONE - hi CursorLineNr ctermfg=172 ctermbg=188 cterm=NONE + hi CursorLineNr ctermfg=172 ctermbg=230 cterm=bold hi FoldColumn ctermfg=102 ctermbg=230 cterm=NONE hi SignColumn ctermfg=237 ctermbg=230 cterm=NONE hi VertSplit ctermfg=144 ctermbg=230 cterm=NONE @@ -318,6 +325,8 @@ if s:t_Co >= 256 hi PmenuKindSel ctermfg=124 ctermbg=23 cterm=NONE hi PmenuExtra ctermfg=243 ctermbg=188 cterm=NONE hi PmenuExtraSel ctermfg=144 ctermbg=23 cterm=NONE + hi PmenuMatch ctermfg=126 ctermbg=188 cterm=NONE + hi PmenuMatchSel ctermfg=175 ctermbg=23 cterm=bold hi SpecialKey ctermfg=102 ctermbg=NONE cterm=NONE hi StatusLine ctermfg=144 ctermbg=237 cterm=bold,reverse hi StatusLineNC ctermfg=187 ctermbg=237 cterm=reverse @@ -329,7 +338,7 @@ if s:t_Co >= 256 hi Visual ctermfg=230 ctermbg=23 cterm=NONE hi WildMenu ctermfg=23 ctermbg=188 cterm=bold hi EndOfBuffer ctermfg=188 ctermbg=NONE cterm=NONE - hi Conceal ctermfg=23 ctermbg=NONE cterm=NONE + hi Conceal ctermfg=137 ctermbg=NONE cterm=NONE hi Cursor ctermfg=230 ctermbg=235 cterm=NONE hi DiffAdd ctermfg=64 ctermbg=230 cterm=reverse hi DiffChange ctermfg=29 ctermbg=230 cterm=reverse @@ -422,7 +431,7 @@ if s:t_Co >= 16 hi Visual ctermfg=Black ctermbg=Blue cterm=NONE hi WildMenu ctermfg=White ctermbg=Black cterm=bold hi EndOfBuffer ctermfg=DarkGray ctermbg=NONE cterm=NONE - hi Conceal ctermfg=Blue ctermbg=NONE cterm=NONE + hi Conceal ctermfg=DarkGray ctermbg=NONE cterm=NONE hi Cursor ctermfg=Black ctermbg=White cterm=NONE hi DiffAdd ctermfg=Green ctermbg=Black cterm=reverse hi DiffChange ctermfg=Cyan ctermbg=Black cterm=reverse @@ -510,7 +519,7 @@ if s:t_Co >= 16 hi Visual ctermfg=White ctermbg=Blue cterm=NONE hi WildMenu ctermfg=Black ctermbg=White cterm=bold hi EndOfBuffer ctermfg=Grey ctermbg=NONE cterm=NONE - hi Conceal ctermfg=Blue ctermbg=NONE cterm=NONE + hi Conceal ctermfg=Grey ctermbg=NONE cterm=NONE hi Cursor ctermfg=White ctermbg=DarkGray cterm=NONE hi DiffAdd ctermfg=Green ctermbg=White cterm=reverse hi DiffChange ctermfg=Cyan ctermbg=White cterm=reverse @@ -603,7 +612,7 @@ if s:t_Co >= 8 hi Visual ctermfg=Black ctermbg=Blue cterm=NONE hi WildMenu ctermfg=Blue ctermbg=DarkGray cterm=bold hi EndOfBuffer ctermfg=NONE ctermbg=NONE cterm=NONE - hi Conceal ctermfg=Blue ctermbg=NONE cterm=NONE + hi Conceal ctermfg=DarkGray ctermbg=NONE cterm=NONE hi Cursor ctermfg=Black ctermbg=White cterm=NONE hi DiffAdd ctermfg=Green ctermbg=Black cterm=reverse hi DiffChange ctermfg=Cyan ctermbg=Black cterm=reverse @@ -691,7 +700,7 @@ if s:t_Co >= 8 hi Visual ctermfg=White ctermbg=Blue cterm=NONE hi WildMenu ctermfg=Blue ctermbg=Grey cterm=bold hi EndOfBuffer ctermfg=NONE ctermbg=NONE cterm=NONE - hi Conceal ctermfg=Blue ctermbg=NONE cterm=NONE + hi Conceal ctermfg=Grey ctermbg=NONE cterm=NONE hi Cursor ctermfg=White ctermbg=DarkGray cterm=NONE hi DiffAdd ctermfg=Green ctermbg=White cterm=reverse hi DiffChange ctermfg=Cyan ctermbg=White cterm=reverse @@ -852,7 +861,7 @@ endif " Color: bg1 #ebdbb2 187 Grey " Color: bg2 #e5d4b1 188 Grey " Color: bg3 #bdae93 144 -" Color: bg4 #a89984 137 +" Color: bg4 #a89984 137 Grey " Color: bg5 #ebe1b7 229 Grey " Color: bg6 #ffffd7 231 Grey " Color: fg0 #282828 235 DarkGray @@ -866,6 +875,7 @@ endif " Color: yellow #b57614 172 Yellow " Color: blue #076678 23 Blue " Color: purple #8f3f71 126 Magenta +" Color: lightpurple #d3869b 175 Magenta " Color: aqua #427b58 29 Cyan " Color: orange #ff5f00 202 Magenta " Term colors: fg1 neutralred neutralgreen neutralyellow neutralblue neutralpurple neutralaqua fg4 diff --git a/runtime/colors/ron.vim b/runtime/colors/ron.vim index 684b485067..c3b058f2b8 100644 --- a/runtime/colors/ron.vim +++ b/runtime/colors/ron.vim @@ -3,7 +3,7 @@ " Maintainer: original maintainer Ron Aaron " Website: https://www.github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:41 +" Last Updated: Wed 10 Jul 2024 17:39:56 " Generated by Colortemplate v2.2.3 @@ -58,7 +58,7 @@ hi CursorColumn guifg=NONE guibg=#666666 gui=NONE cterm=NONE hi CursorLine guifg=NONE guibg=#666666 gui=NONE cterm=NONE hi CursorLineNr guifg=#ffff00 guibg=NONE gui=bold cterm=NONE hi QuickFixLine guifg=#000000 guibg=#00cdcd gui=NONE cterm=NONE -hi Conceal guifg=#e5e5e5 guibg=#a9a9a9 gui=NONE cterm=NONE +hi Conceal guifg=#666666 guibg=NONE gui=NONE cterm=NONE hi Cursor guifg=#ffffff guibg=#60a060 gui=NONE cterm=NONE hi Directory guifg=#00ffff guibg=NONE gui=NONE cterm=NONE hi EndOfBuffer guifg=#ffff00 guibg=#303030 gui=NONE cterm=NONE @@ -75,6 +75,8 @@ hi Pmenu guifg=#ffffff guibg=#444444 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#000000 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#00cdcd gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#e5e5e5 gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff00ff guibg=#444444 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff00ff guibg=#00cdcd gui=NONE cterm=NONE hi Question guifg=#00ff00 guibg=#000000 gui=bold cterm=NONE hi Search guifg=#000000 guibg=#a9a9a9 gui=bold cterm=NONE hi SignColumn guifg=#00ffff guibg=NONE gui=NONE cterm=NONE @@ -123,7 +125,7 @@ if s:t_Co >= 256 hi CursorLine ctermfg=NONE ctermbg=59 cterm=NONE hi CursorLineNr ctermfg=226 ctermbg=NONE cterm=NONE hi QuickFixLine ctermfg=16 ctermbg=44 cterm=NONE - hi Conceal ctermfg=254 ctermbg=145 cterm=NONE + hi Conceal ctermfg=59 ctermbg=NONE cterm=NONE hi Cursor ctermfg=231 ctermbg=71 cterm=NONE hi Directory ctermfg=51 ctermbg=NONE cterm=NONE hi EndOfBuffer ctermfg=226 ctermbg=236 cterm=NONE @@ -140,6 +142,8 @@ if s:t_Co >= 256 hi PmenuSbar ctermfg=NONE ctermbg=16 cterm=NONE hi PmenuSel ctermfg=16 ctermbg=44 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=254 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=238 cterm=NONE + hi PmenuMatchSel ctermfg=201 ctermbg=44 cterm=NONE hi Question ctermfg=46 ctermbg=16 cterm=NONE hi Search ctermfg=16 ctermbg=145 cterm=NONE hi SignColumn ctermfg=51 ctermbg=NONE cterm=NONE @@ -191,7 +195,7 @@ if s:t_Co >= 16 hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline hi CursorLineNr ctermfg=yellow ctermbg=NONE cterm=underline hi QuickFixLine ctermfg=black ctermbg=darkcyan cterm=NONE - hi Conceal ctermfg=grey ctermbg=grey cterm=NONE + hi Conceal ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Cursor ctermfg=white ctermbg=green cterm=NONE hi Directory ctermfg=cyan ctermbg=NONE cterm=NONE hi EndOfBuffer ctermfg=yellow ctermbg=darkgrey cterm=NONE @@ -208,6 +212,8 @@ if s:t_Co >= 16 hi PmenuSbar ctermfg=NONE ctermbg=black cterm=NONE hi PmenuSel ctermfg=black ctermbg=darkcyan cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=grey cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=magenta ctermbg=darkcyan cterm=NONE hi Question ctermfg=green ctermbg=black cterm=NONE hi Search ctermfg=black ctermbg=grey cterm=NONE hi SignColumn ctermfg=cyan ctermbg=NONE cterm=NONE diff --git a/runtime/colors/shine.vim b/runtime/colors/shine.vim index ec7da8cb17..491695be3a 100644 --- a/runtime/colors/shine.vim +++ b/runtime/colors/shine.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer is Yasuhiro Matsumoto " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:41 +" Last Updated: Wed 10 Jul 2024 17:41:19 " Generated by Colortemplate v2.2.3 @@ -45,6 +45,8 @@ hi Pmenu guifg=#000000 guibg=#a8a8a8 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#ffff60 gui=NONE cterm=NONE hi PmenuSbar guifg=#ffffff guibg=#ffffff gui=NONE cterm=NONE hi PmenuThumb guifg=#767676 guibg=#767676 gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff0000 guibg=#a8a8a8 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff0000 guibg=#ffff60 gui=NONE cterm=NONE hi TabLine guifg=#000000 guibg=#dadada gui=underline cterm=underline hi TabLineFill guifg=NONE guibg=NONE gui=reverse ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel guifg=#000000 guibg=#ffffff gui=bold cterm=bold @@ -79,7 +81,7 @@ hi Statement guifg=#2e8b57 guibg=NONE gui=bold cterm=bold hi Type guifg=#2e8b57 guibg=NONE gui=bold cterm=bold hi Comment guifg=#a8a8a8 guibg=NONE gui=bold cterm=NONE hi StorageClass guifg=#ff0000 guibg=NONE gui=bold cterm=bold -hi Conceal guifg=#dadada guibg=#767676 gui=NONE cterm=NONE +hi Conceal guifg=#add8e6 guibg=NONE gui=NONE cterm=NONE hi Identifier guifg=#008b8b guibg=NONE gui=NONE cterm=NONE hi Constant guifg=#a07070 guibg=NONE gui=NONE cterm=NONE hi Number guifg=#a07070 guibg=NONE gui=bold cterm=bold @@ -123,6 +125,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=16 ctermbg=228 cterm=NONE hi PmenuSbar ctermfg=231 ctermbg=231 cterm=NONE hi PmenuThumb ctermfg=243 ctermbg=243 cterm=NONE + hi PmenuMatch ctermfg=196 ctermbg=248 cterm=NONE + hi PmenuMatchSel ctermfg=196 ctermbg=228 cterm=NONE hi TabLine ctermfg=16 ctermbg=253 cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=16 ctermbg=231 cterm=bold @@ -157,7 +161,7 @@ if s:t_Co >= 256 hi Type ctermfg=29 ctermbg=NONE cterm=bold hi Comment ctermfg=248 ctermbg=NONE cterm=NONE hi StorageClass ctermfg=196 ctermbg=NONE cterm=bold - hi Conceal ctermfg=253 ctermbg=243 cterm=NONE + hi Conceal ctermfg=153 ctermbg=NONE cterm=NONE hi Identifier ctermfg=30 ctermbg=NONE cterm=NONE hi Constant ctermfg=95 ctermbg=NONE cterm=NONE hi Number ctermfg=95 ctermbg=NONE cterm=bold @@ -192,6 +196,8 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=black ctermbg=yellow cterm=NONE hi PmenuSbar ctermfg=white ctermbg=white cterm=NONE hi PmenuThumb ctermfg=darkgrey ctermbg=darkgrey cterm=NONE + hi PmenuMatch ctermfg=red ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=red ctermbg=yellow cterm=NONE hi TabLine ctermfg=black ctermbg=grey cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=black ctermbg=white cterm=bold @@ -226,7 +232,7 @@ if s:t_Co >= 16 hi Type ctermfg=darkgreen ctermbg=NONE cterm=bold hi Comment ctermfg=darkgrey ctermbg=NONE cterm=NONE hi StorageClass ctermfg=red ctermbg=NONE cterm=bold - hi Conceal ctermfg=grey ctermbg=darkgrey cterm=NONE + hi Conceal ctermfg=blue ctermbg=NONE cterm=NONE hi Identifier ctermfg=darkcyan ctermbg=NONE cterm=NONE hi Constant ctermfg=darkred ctermbg=NONE cterm=NONE hi Number ctermfg=darkred ctermbg=NONE cterm=bold diff --git a/runtime/colors/slate.vim b/runtime/colors/slate.vim index d58d07850d..64d0f06688 100644 --- a/runtime/colors/slate.vim +++ b/runtime/colors/slate.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Ralph Amissah " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:41 +" Last Updated: Tue 09 Jul 2024 17:05:47 " Generated by Colortemplate v2.2.3 @@ -34,9 +34,11 @@ hi StatusLineTerm guifg=#000000 guibg=#afaf87 gui=NONE cterm=NONE hi StatusLineTermNC guifg=#666666 guibg=#afaf87 gui=NONE cterm=NONE hi VertSplit guifg=#666666 guibg=#afaf87 gui=NONE cterm=NONE hi PmenuSel guifg=#262626 guibg=#d7d787 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#d7875f guibg=#d7d787 gui=NONE cterm=NONE hi Pmenu guifg=NONE guibg=#4a4a4a gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#262626 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#ffd700 gui=NONE cterm=NONE +hi PmenuMatch guifg=#d7875f guibg=#4a4a4a gui=NONE cterm=NONE hi TabLineSel guifg=#000000 guibg=#afaf87 gui=NONE cterm=NONE hi TabLine guifg=#666666 guibg=#333333 gui=NONE cterm=NONE hi TabLineFill guifg=#ff8787 guibg=#333333 gui=NONE cterm=NONE @@ -111,9 +113,11 @@ if s:t_Co >= 256 hi StatusLineTermNC ctermfg=241 ctermbg=144 cterm=NONE hi VertSplit ctermfg=241 ctermbg=144 cterm=NONE hi PmenuSel ctermfg=235 ctermbg=186 cterm=NONE + hi PmenuMatchSel ctermfg=173 ctermbg=186 cterm=NONE hi Pmenu ctermfg=NONE ctermbg=239 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=235 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=220 cterm=NONE + hi PmenuMatch ctermfg=173 ctermbg=239 cterm=NONE hi TabLineSel ctermfg=16 ctermbg=144 cterm=NONE hi TabLine ctermfg=241 ctermbg=236 cterm=NONE hi TabLineFill ctermfg=210 ctermbg=236 cterm=NONE @@ -184,6 +188,7 @@ if s:t_Co >= 16 hi Pmenu ctermfg=NONE ctermbg=darkgrey cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=black cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=yellow cterm=NONE + hi PmenuMatch ctermfg=darkmagenta ctermbg=darkgrey cterm=NONE hi TabLineSel ctermfg=black ctermbg=darkyellow cterm=NONE hi TabLine ctermfg=grey ctermbg=darkgrey cterm=NONE hi TabLineFill ctermfg=cyan ctermbg=darkgrey cterm=NONE diff --git a/runtime/colors/sorbet.vim b/runtime/colors/sorbet.vim index a762dfb613..dd06c3639a 100644 --- a/runtime/colors/sorbet.vim +++ b/runtime/colors/sorbet.vim @@ -4,7 +4,7 @@ " Maintainer: Maxence Weynans " Website: https://github.com/vim/colorschemes " License: Vim License (see `:help license`)` -" Last Updated: Fri 15 Dec 2023 20:05:42 +" Last Updated: Wed 19 Jun 2024 05:16:50 PM CEST " Generated by Colortemplate v2.2.3 @@ -51,6 +51,9 @@ if (has('termguicolors') && &termguicolors) || has('gui_running') let g:terminal_ansi_colors = ['#000000', '#d75f5f', '#87d75f', '#d7af5f', '#87afd7', '#af87d7', '#5fafaf', '#dadada', '#707070', '#ff5f5f', '#87ff5f', '#ffd75f', '#87d7ff', '#d787ff', '#5fd7d7', '#ffffff'] endif hi Normal guifg=#dadada guibg=#161821 gui=NONE cterm=NONE +hi Added guifg=#87d75f guibg=NONE gui=NONE cterm=NONE +hi Changed guifg=#87afd7 guibg=NONE gui=NONE cterm=NONE +hi Removed guifg=#d75f5f guibg=NONE gui=NONE cterm=NONE hi ColorColumn guifg=NONE guibg=#262831 gui=NONE cterm=NONE hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi CurSearch guifg=#ff5fff guibg=#000000 gui=reverse cterm=reverse @@ -73,10 +76,12 @@ hi ModeMsg guifg=#dadada guibg=NONE gui=bold cterm=bold hi MoreMsg guifg=#dadada guibg=NONE gui=NONE cterm=NONE hi NonText guifg=#707070 guibg=NONE gui=NONE cterm=NONE hi Pmenu guifg=#000000 guibg=#a6a8b1 gui=NONE cterm=NONE +hi PmenuMatch guifg=#d7005f guibg=#a6a8b1 gui=NONE cterm=NONE hi PmenuExtra guifg=#000000 guibg=#a6a8b1 gui=NONE cterm=NONE hi PmenuKind guifg=#000000 guibg=#a6a8b1 gui=bold cterm=bold hi PmenuSbar guifg=#707070 guibg=#5f5f87 gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#d7d7ff gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#d7005f guibg=#d7d7ff gui=bold cterm=bold hi PmenuExtraSel guifg=#000000 guibg=#d7d7ff gui=NONE cterm=NONE hi PmenuKindSel guifg=#000000 guibg=#d7d7ff gui=bold cterm=bold hi PmenuThumb guifg=#dadada guibg=#d7d7ff gui=NONE cterm=NONE @@ -115,11 +120,13 @@ hi Underlined guifg=#dadada guibg=NONE gui=underline cterm=underline hi CursorIM guifg=#000000 guibg=#afff00 gui=NONE cterm=NONE hi ToolbarLine guifg=NONE guibg=#000000 gui=NONE cterm=NONE hi ToolbarButton guifg=#dadada guibg=#000000 gui=bold cterm=bold -hi DiffRemoved guifg=#d75f5f guibg=NONE gui=NONE cterm=NONE hi debugBreakpoint guifg=#8787af guibg=#000000 gui=bold,reverse cterm=bold,reverse if s:t_Co >= 256 hi Normal ctermfg=253 ctermbg=233 cterm=NONE + hi Added ctermfg=113 ctermbg=NONE cterm=NONE + hi Changed ctermfg=110 ctermbg=NONE cterm=NONE + hi Removed ctermfg=167 ctermbg=NONE cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=235 cterm=NONE hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE hi CurSearch ctermfg=207 ctermbg=16 cterm=reverse @@ -142,10 +149,12 @@ if s:t_Co >= 256 hi MoreMsg ctermfg=253 ctermbg=NONE cterm=NONE hi NonText ctermfg=242 ctermbg=NONE cterm=NONE hi Pmenu ctermfg=16 ctermbg=248 cterm=NONE + hi PmenuMatch ctermfg=161 ctermbg=248 cterm=NONE hi PmenuExtra ctermfg=16 ctermbg=248 cterm=NONE hi PmenuKind ctermfg=16 ctermbg=248 cterm=bold hi PmenuSbar ctermfg=242 ctermbg=60 cterm=NONE hi PmenuSel ctermfg=16 ctermbg=189 cterm=NONE + hi PmenuMatchSel ctermfg=161 ctermbg=189 cterm=bold hi PmenuExtraSel ctermfg=16 ctermbg=189 cterm=NONE hi PmenuKindSel ctermfg=16 ctermbg=189 cterm=bold hi PmenuThumb ctermfg=253 ctermbg=189 cterm=NONE @@ -184,7 +193,6 @@ if s:t_Co >= 256 hi CursorIM ctermfg=16 ctermbg=154 cterm=NONE hi ToolbarLine ctermfg=NONE ctermbg=16 cterm=NONE hi ToolbarButton ctermfg=253 ctermbg=16 cterm=bold - hi DiffRemoved ctermfg=167 ctermbg=NONE cterm=NONE hi debugBreakpoint ctermfg=103 ctermbg=16 cterm=bold,reverse unlet s:t_Co finish @@ -204,6 +212,9 @@ if s:t_Co >= 16 hi TabLine ctermfg=darkgrey ctermbg=NONE cterm=reverse hi VertSplit ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Normal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Added ctermfg=darkgreen ctermbg=NONE cterm=NONE + hi Changed ctermfg=darkblue ctermbg=NONE cterm=NONE + hi Removed ctermfg=darkred ctermbg=NONE cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=NONE cterm=reverse hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE hi Cursor ctermfg=NONE ctermbg=NONE cterm=reverse @@ -220,9 +231,11 @@ if s:t_Co >= 16 hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=NONE ctermbg=NONE cterm=NONE hi Pmenu ctermfg=NONE ctermbg=NONE cterm=reverse + hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse hi PmenuExtra ctermfg=NONE ctermbg=NONE cterm=reverse hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold + hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE @@ -256,7 +269,6 @@ if s:t_Co >= 16 hi CursorIM ctermfg=NONE ctermbg=NONE cterm=NONE hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=reverse hi ToolbarButton ctermfg=NONE ctermbg=NONE cterm=bold,reverse - hi DiffRemoved ctermfg=darkred ctermbg=NONE cterm=NONE hi debugBreakpoint ctermfg=NONE ctermbg=NONE cterm=bold,reverse unlet s:t_Co finish @@ -276,6 +288,9 @@ if s:t_Co >= 8 hi TabLine ctermfg=NONE ctermbg=NONE cterm=bold,underline hi VertSplit ctermfg=NONE ctermbg=NONE cterm=NONE hi Normal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Added ctermfg=darkgreen ctermbg=NONE cterm=NONE + hi Changed ctermfg=darkblue ctermbg=NONE cterm=NONE + hi Removed ctermfg=darkred ctermbg=NONE cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=NONE cterm=reverse hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE hi Cursor ctermfg=NONE ctermbg=NONE cterm=reverse @@ -292,9 +307,11 @@ if s:t_Co >= 8 hi ModeMsg ctermfg=NONE ctermbg=NONE cterm=bold hi MoreMsg ctermfg=NONE ctermbg=NONE cterm=NONE hi Pmenu ctermfg=NONE ctermbg=NONE cterm=reverse + hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse hi PmenuExtra ctermfg=NONE ctermbg=NONE cterm=reverse hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold + hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE @@ -328,7 +345,6 @@ if s:t_Co >= 8 hi CursorIM ctermfg=NONE ctermbg=NONE cterm=NONE hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=reverse hi ToolbarButton ctermfg=NONE ctermbg=NONE cterm=bold,reverse - hi DiffRemoved ctermfg=darkred ctermbg=NONE cterm=NONE hi debugBreakpoint ctermfg=NONE ctermbg=NONE cterm=bold,reverse unlet s:t_Co finish diff --git a/runtime/colors/torte.vim b/runtime/colors/torte.vim index 2ad17b05b0..949015e480 100644 --- a/runtime/colors/torte.vim +++ b/runtime/colors/torte.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Thorsten Maerz " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:42 +" Last Updated: Wed 10 Jul 2024 17:43:03 " Generated by Colortemplate v2.2.3 @@ -48,7 +48,7 @@ hi CursorLineNr guifg=#ffff00 guibg=#666666 gui=NONE cterm=NONE hi SignColumn guifg=#00ffff guibg=NONE gui=NONE cterm=NONE hi FoldColumn guifg=#00ffff guibg=NONE gui=NONE cterm=NONE hi ColorColumn guifg=#cccccc guibg=#8b0000 gui=NONE cterm=NONE -hi Conceal guifg=#e5e5e5 guibg=#a9a9a9 gui=NONE cterm=NONE +hi Conceal guifg=#666666 guibg=NONE gui=NONE cterm=NONE hi Cursor guifg=#000000 guibg=#00ff00 gui=bold cterm=NONE hi lCursor guifg=#000000 guibg=#e5e5e5 gui=NONE cterm=NONE hi CursorIM guifg=NONE guibg=fg gui=NONE cterm=NONE @@ -85,6 +85,8 @@ hi Pmenu guifg=fg guibg=#303030 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#ffff00 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#bebebe gui=NONE cterm=NONE +hi PmenuMatch guifg=#ff00ff guibg=#303030 gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#ff00ff guibg=#ffff00 gui=NONE cterm=NONE hi DiffAdd guifg=#ffffff guibg=#5f875f gui=NONE cterm=NONE hi DiffChange guifg=#ffffff guibg=#5f87af gui=NONE cterm=NONE hi DiffText guifg=#000000 guibg=#c6c6c6 gui=NONE cterm=NONE @@ -121,7 +123,7 @@ if s:t_Co >= 256 hi SignColumn ctermfg=51 ctermbg=NONE cterm=NONE hi FoldColumn ctermfg=51 ctermbg=NONE cterm=NONE hi ColorColumn ctermfg=251 ctermbg=88 cterm=NONE - hi Conceal ctermfg=254 ctermbg=248 cterm=NONE + hi Conceal ctermfg=242 ctermbg=NONE cterm=NONE hi Cursor ctermfg=16 ctermbg=46 cterm=NONE hi lCursor ctermfg=16 ctermbg=254 cterm=NONE hi CursorIM ctermfg=NONE ctermbg=fg cterm=NONE @@ -158,6 +160,8 @@ if s:t_Co >= 256 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=16 ctermbg=226 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=250 cterm=NONE + hi PmenuMatch ctermfg=201 ctermbg=236 cterm=NONE + hi PmenuMatchSel ctermfg=201 ctermbg=226 cterm=NONE hi DiffAdd ctermfg=231 ctermbg=65 cterm=NONE hi DiffChange ctermfg=231 ctermbg=67 cterm=NONE hi DiffText ctermfg=16 ctermbg=251 cterm=NONE @@ -187,7 +191,7 @@ if s:t_Co >= 16 hi SignColumn ctermfg=cyan ctermbg=NONE cterm=NONE hi FoldColumn ctermfg=cyan ctermbg=NONE cterm=NONE hi ColorColumn ctermfg=white ctermbg=darkred cterm=NONE - hi Conceal ctermfg=grey ctermbg=grey cterm=NONE + hi Conceal ctermfg=grey ctermbg=NONE cterm=NONE hi Cursor ctermfg=black ctermbg=green cterm=NONE hi lCursor ctermfg=black ctermbg=grey cterm=NONE hi CursorIM ctermfg=NONE ctermbg=fg cterm=NONE @@ -224,6 +228,8 @@ if s:t_Co >= 16 hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuSel ctermfg=black ctermbg=yellow cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=grey cterm=NONE + hi PmenuMatch ctermfg=magenta ctermbg=darkgrey cterm=NONE + hi PmenuMatchSel ctermfg=magenta ctermbg=yellow cterm=NONE hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE hi DiffChange ctermfg=white ctermbg=blue cterm=NONE hi DiffText ctermfg=black ctermbg=grey cterm=NONE diff --git a/runtime/colors/wildcharm.vim b/runtime/colors/wildcharm.vim index ee1f37625c..9f516cc755 100644 --- a/runtime/colors/wildcharm.vim +++ b/runtime/colors/wildcharm.vim @@ -4,7 +4,7 @@ " Maintainer: Maxim Kim " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Mon 08 Jan 2024 09:40:36 AM AEDT +" Last Updated: Sat 06 Jul 2024 09:42:27 " Generated by Colortemplate v2.2.3 @@ -26,14 +26,14 @@ if &background ==# 'dark' let g:terminal_ansi_colors = ['#000000', '#d7005f', '#00af5f', '#d78700', '#0087d7', '#d787d7', '#00afaf', '#d0d0d0', '#767676', '#ff5f87', '#00d75f', '#ffaf00', '#00afff', '#ff87ff', '#00d7d7', '#ffffff'] endif hi Normal guifg=#d0d0d0 guibg=#000000 gui=NONE cterm=NONE - hi Statusline guifg=#d0d0d0 guibg=#000000 gui=reverse cterm=reverse + hi Statusline guifg=#9e9e9e guibg=#000000 gui=bold,reverse cterm=bold,reverse hi StatuslineNC guifg=#767676 guibg=#000000 gui=reverse cterm=reverse - hi VertSplit guifg=#767676 guibg=#767676 gui=NONE cterm=NONE - hi TabLine guifg=#000000 guibg=#d0d0d0 gui=NONE cterm=NONE - hi TabLineFill guifg=NONE guibg=#767676 gui=NONE cterm=NONE - hi TabLineSel guifg=#ffffff guibg=#000000 gui=NONE cterm=NONE + hi VertSplit guifg=#767676 guibg=NONE gui=NONE cterm=NONE + hi TabLine guifg=#000000 guibg=#767676 gui=NONE cterm=NONE + hi TabLineFill guifg=NONE guibg=#000000 gui=NONE cterm=NONE + hi TabLineSel guifg=#000000 guibg=#9e9e9e gui=bold cterm=bold hi ToolbarLine guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton guifg=#000000 guibg=#ffffff gui=NONE cterm=NONE + hi ToolbarButton guifg=#000000 guibg=#d0d0d0 gui=NONE cterm=NONE hi QuickFixLine guifg=#000000 guibg=#ff87ff gui=NONE cterm=NONE hi CursorLineNr guifg=#ffffff guibg=NONE gui=bold cterm=bold hi LineNr guifg=#585858 guibg=NONE gui=NONE cterm=NONE @@ -43,13 +43,15 @@ if &background ==# 'dark' hi EndOfBuffer guifg=#585858 guibg=NONE gui=NONE cterm=NONE hi EndOfBuffer guifg=#767676 guibg=NONE gui=NONE cterm=NONE hi Pmenu guifg=#d0d0d0 guibg=#303030 gui=NONE cterm=NONE - hi PmenuSel guifg=#000000 guibg=#ffaf00 gui=NONE cterm=NONE + hi PmenuSel guifg=#d0d0d0 guibg=#585858 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#d0d0d0 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuKind guifg=#ff5f87 guibg=#303030 gui=NONE cterm=NONE - hi PmenuKindSel guifg=#d7005f guibg=#ffaf00 gui=NONE cterm=NONE + hi PmenuKindSel guifg=#ff5f87 guibg=#585858 gui=NONE cterm=NONE hi PmenuExtra guifg=#767676 guibg=#303030 gui=NONE cterm=NONE - hi PmenuExtraSel guifg=#000000 guibg=#ffaf00 gui=NONE cterm=NONE + hi PmenuExtraSel guifg=#767676 guibg=#585858 gui=NONE cterm=NONE + hi PmenuMatch guifg=#d787d7 guibg=#303030 gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#d787d7 guibg=#585858 gui=NONE cterm=NONE hi SignColumn guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Error guifg=#d7005f guibg=#ffffff gui=reverse cterm=reverse hi ErrorMsg guifg=#d7005f guibg=#ffffff gui=reverse cterm=reverse @@ -65,7 +67,7 @@ if &background ==# 'dark' hi debugBreakpoint guifg=#00afaf guibg=NONE gui=reverse cterm=reverse hi Cursor guifg=#000000 guibg=#ffffff gui=NONE cterm=NONE hi lCursor guifg=#000000 guibg=#ff5fff gui=NONE cterm=NONE - hi Visual guifg=#0087d7 guibg=#000000 gui=reverse cterm=reverse + hi Visual guifg=#5fd7ff guibg=#000000 gui=reverse cterm=reverse hi VisualNOS guifg=#000000 guibg=#00afff gui=NONE cterm=NONE hi CursorLine guifg=NONE guibg=#262626 gui=NONE cterm=NONE hi CursorColumn guifg=NONE guibg=#262626 gui=NONE cterm=NONE @@ -87,7 +89,7 @@ if &background ==# 'dark' hi Underlined guifg=NONE guibg=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline hi Title guifg=NONE guibg=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold hi Directory guifg=#00afff guibg=NONE gui=bold cterm=bold - hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal guifg=#585858 guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd guifg=#afffaf guibg=#5f875f gui=NONE cterm=NONE hi DiffChange guifg=#d0d0d0 guibg=#5f5f5f gui=NONE cterm=NONE @@ -102,14 +104,14 @@ else let g:terminal_ansi_colors = ['#000000', '#af0000', '#008700', '#af5f00', '#005faf', '#870087', '#008787', '#8a8a8a', '#808080', '#d70000', '#5faf5f', '#d78700', '#0087d7', '#af00af', '#00afaf', '#ffffff'] endif hi Normal guifg=#000000 guibg=#ffffff gui=NONE cterm=NONE - hi Statusline guifg=#ffffff guibg=#5f5f5f gui=NONE cterm=NONE + hi Statusline guifg=#ffffff guibg=#5f5f5f gui=bold cterm=bold hi StatuslineNC guifg=#000000 guibg=#d0d0d0 gui=NONE cterm=NONE - hi VertSplit guifg=#d0d0d0 guibg=#d0d0d0 gui=NONE cterm=NONE + hi VertSplit guifg=#5f5f5f guibg=NONE gui=NONE cterm=NONE hi TabLine guifg=#000000 guibg=#d0d0d0 gui=NONE cterm=NONE - hi TabLineFill guifg=NONE guibg=#808080 gui=NONE cterm=NONE - hi TabLineSel guifg=#ffffff guibg=#000000 gui=reverse cterm=reverse + hi TabLineFill guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE + hi TabLineSel guifg=#5f5f5f guibg=#ffffff gui=bold,reverse cterm=bold,reverse hi ToolbarLine guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton guifg=#ffffff guibg=#000000 gui=NONE cterm=NONE + hi ToolbarButton guifg=#ffffff guibg=#5f5f5f gui=NONE cterm=NONE hi QuickFixLine guifg=#ffffff guibg=#870087 gui=NONE cterm=NONE hi CursorLineNr guifg=#000000 guibg=NONE gui=bold cterm=bold hi LineNr guifg=#b2b2b2 guibg=NONE gui=NONE cterm=NONE @@ -118,13 +120,15 @@ else hi EndOfBuffer guifg=#b2b2b2 guibg=NONE gui=NONE cterm=NONE hi SpecialKey guifg=#b2b2b2 guibg=NONE gui=NONE cterm=NONE hi Pmenu guifg=#000000 guibg=#e4e4e4 gui=NONE cterm=NONE - hi PmenuSel guifg=#ffffff guibg=#d78700 gui=NONE cterm=NONE + hi PmenuSel guifg=#000000 guibg=#b2b2b2 gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#808080 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuKind guifg=#d70000 guibg=#e4e4e4 gui=NONE cterm=NONE - hi PmenuKindSel guifg=#af0000 guibg=#d78700 gui=NONE cterm=NONE + hi PmenuKindSel guifg=#d70000 guibg=#b2b2b2 gui=NONE cterm=NONE hi PmenuExtra guifg=#808080 guibg=#e4e4e4 gui=NONE cterm=NONE - hi PmenuExtraSel guifg=#ffffff guibg=#d78700 gui=NONE cterm=NONE + hi PmenuExtraSel guifg=#808080 guibg=#b2b2b2 gui=NONE cterm=NONE + hi PmenuMatch guifg=#870087 guibg=#e4e4e4 gui=NONE cterm=NONE + hi PmenuMatchSel guifg=#870087 guibg=#b2b2b2 gui=NONE cterm=NONE hi SignColumn guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Error guifg=#d70000 guibg=#ffffff gui=reverse cterm=reverse hi ErrorMsg guifg=#d70000 guibg=#ffffff gui=reverse cterm=reverse @@ -132,7 +136,7 @@ else hi MoreMsg guifg=#008700 guibg=NONE gui=NONE cterm=NONE hi Question guifg=#870087 guibg=NONE gui=NONE cterm=NONE hi WarningMsg guifg=#af5f00 guibg=NONE gui=NONE cterm=NONE - hi Todo guifg=#8700ff guibg=#ffffff gui=reverse cterm=reverse + hi Todo guifg=#5f00d7 guibg=#ffffff gui=reverse cterm=reverse hi Search guifg=#ffffff guibg=#008700 gui=NONE cterm=NONE hi IncSearch guifg=#ffffff guibg=#d78700 gui=NONE cterm=NONE hi WildMenu guifg=#ffffff guibg=#d78700 gui=NONE cterm=NONE @@ -158,11 +162,11 @@ else hi Statement guifg=#005faf guibg=NONE gui=NONE cterm=NONE hi Type guifg=#af5f00 guibg=NONE gui=NONE cterm=NONE hi PreProc guifg=#008787 guibg=NONE gui=NONE cterm=NONE - hi Special guifg=#8700ff guibg=NONE gui=NONE cterm=NONE + hi Special guifg=#5f00d7 guibg=NONE gui=NONE cterm=NONE hi Underlined guifg=NONE guibg=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline hi Title guifg=NONE guibg=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold hi Directory guifg=#005faf guibg=NONE gui=bold cterm=bold - hi Conceal guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal guifg=#b2b2b2 guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd guifg=#005f00 guibg=#afd7af gui=NONE cterm=NONE hi DiffChange guifg=#262626 guibg=#dadada gui=NONE cterm=NONE @@ -184,14 +188,14 @@ if s:t_Co >= 256 hi! link CurSearch IncSearch if &background ==# 'dark' hi Normal ctermfg=252 ctermbg=16 cterm=NONE - hi Statusline ctermfg=252 ctermbg=16 cterm=reverse + hi Statusline ctermfg=247 ctermbg=16 cterm=bold,reverse hi StatuslineNC ctermfg=243 ctermbg=16 cterm=reverse - hi VertSplit ctermfg=243 ctermbg=243 cterm=NONE - hi TabLine ctermfg=16 ctermbg=252 cterm=NONE - hi TabLineFill ctermfg=NONE ctermbg=243 cterm=NONE - hi TabLineSel ctermfg=231 ctermbg=16 cterm=NONE + hi VertSplit ctermfg=243 ctermbg=NONE cterm=NONE + hi TabLine ctermfg=16 ctermbg=243 cterm=NONE + hi TabLineFill ctermfg=NONE ctermbg=16 cterm=NONE + hi TabLineSel ctermfg=16 ctermbg=247 cterm=bold hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton ctermfg=16 ctermbg=231 cterm=NONE + hi ToolbarButton ctermfg=16 ctermbg=252 cterm=NONE hi QuickFixLine ctermfg=16 ctermbg=213 cterm=NONE hi CursorLineNr ctermfg=231 ctermbg=NONE cterm=bold hi LineNr ctermfg=240 ctermbg=NONE cterm=NONE @@ -201,13 +205,15 @@ if s:t_Co >= 256 hi EndOfBuffer ctermfg=240 ctermbg=NONE cterm=NONE hi EndOfBuffer ctermfg=243 ctermbg=NONE cterm=NONE hi Pmenu ctermfg=252 ctermbg=236 cterm=NONE - hi PmenuSel ctermfg=16 ctermbg=214 cterm=NONE + hi PmenuSel ctermfg=252 ctermbg=240 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=252 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuKind ctermfg=204 ctermbg=236 cterm=NONE - hi PmenuKindSel ctermfg=161 ctermbg=214 cterm=NONE + hi PmenuKindSel ctermfg=204 ctermbg=240 cterm=NONE hi PmenuExtra ctermfg=243 ctermbg=236 cterm=NONE - hi PmenuExtraSel ctermfg=16 ctermbg=214 cterm=NONE + hi PmenuExtraSel ctermfg=243 ctermbg=240 cterm=NONE + hi PmenuMatch ctermfg=176 ctermbg=236 cterm=NONE + hi PmenuMatchSel ctermfg=176 ctermbg=240 cterm=NONE hi SignColumn ctermfg=NONE ctermbg=NONE cterm=NONE hi Error ctermfg=161 ctermbg=231 cterm=reverse hi ErrorMsg ctermfg=161 ctermbg=231 cterm=reverse @@ -221,17 +227,17 @@ if s:t_Co >= 256 hi WildMenu ctermfg=16 ctermbg=214 cterm=NONE hi debugPC ctermfg=32 ctermbg=NONE cterm=reverse hi debugBreakpoint ctermfg=37 ctermbg=NONE cterm=reverse - hi Visual ctermfg=32 ctermbg=16 cterm=reverse + hi Visual ctermfg=81 ctermbg=16 cterm=reverse hi VisualNOS ctermfg=16 ctermbg=39 cterm=NONE hi CursorLine ctermfg=NONE ctermbg=235 cterm=NONE hi CursorColumn ctermfg=NONE ctermbg=235 cterm=NONE hi Folded ctermfg=243 ctermbg=236 cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=236 cterm=NONE hi MatchParen ctermfg=199 ctermbg=NONE cterm=bold - hi SpellBad ctermfg=161 ctermbg=231 cterm=reverse - hi SpellCap ctermfg=37 ctermbg=16 cterm=reverse - hi SpellLocal ctermfg=41 ctermbg=16 cterm=reverse - hi SpellRare ctermfg=213 ctermbg=16 cterm=reverse + hi SpellBad ctermfg=161 ctermbg=NONE cterm=underline + hi SpellCap ctermfg=37 ctermbg=NONE cterm=underline + hi SpellLocal ctermfg=41 ctermbg=NONE cterm=underline + hi SpellRare ctermfg=213 ctermbg=NONE cterm=underline hi Comment ctermfg=243 ctermbg=NONE cterm=NONE hi Constant ctermfg=204 ctermbg=NONE cterm=NONE hi String ctermfg=41 ctermbg=NONE cterm=NONE @@ -243,7 +249,7 @@ if s:t_Co >= 256 hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=39 ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=240 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=157 ctermbg=65 cterm=NONE hi DiffChange ctermfg=252 ctermbg=59 cterm=NONE @@ -255,14 +261,14 @@ if s:t_Co >= 256 else " Light background hi Normal ctermfg=16 ctermbg=231 cterm=NONE - hi Statusline ctermfg=231 ctermbg=59 cterm=NONE + hi Statusline ctermfg=231 ctermbg=59 cterm=bold hi StatuslineNC ctermfg=16 ctermbg=252 cterm=NONE - hi VertSplit ctermfg=252 ctermbg=252 cterm=NONE + hi VertSplit ctermfg=59 ctermbg=NONE cterm=NONE hi TabLine ctermfg=16 ctermbg=252 cterm=NONE - hi TabLineFill ctermfg=NONE ctermbg=240 cterm=NONE - hi TabLineSel ctermfg=231 ctermbg=16 cterm=reverse + hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=NONE + hi TabLineSel ctermfg=59 ctermbg=231 cterm=bold,reverse hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton ctermfg=231 ctermbg=16 cterm=NONE + hi ToolbarButton ctermfg=231 ctermbg=59 cterm=NONE hi QuickFixLine ctermfg=231 ctermbg=90 cterm=NONE hi CursorLineNr ctermfg=16 ctermbg=NONE cterm=bold hi LineNr ctermfg=249 ctermbg=NONE cterm=NONE @@ -271,13 +277,15 @@ if s:t_Co >= 256 hi EndOfBuffer ctermfg=249 ctermbg=NONE cterm=NONE hi SpecialKey ctermfg=249 ctermbg=NONE cterm=NONE hi Pmenu ctermfg=16 ctermbg=254 cterm=NONE - hi PmenuSel ctermfg=231 ctermbg=172 cterm=NONE + hi PmenuSel ctermfg=16 ctermbg=249 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=240 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE hi PmenuKind ctermfg=160 ctermbg=254 cterm=NONE - hi PmenuKindSel ctermfg=124 ctermbg=172 cterm=NONE + hi PmenuKindSel ctermfg=160 ctermbg=249 cterm=NONE hi PmenuExtra ctermfg=240 ctermbg=254 cterm=NONE - hi PmenuExtraSel ctermfg=231 ctermbg=172 cterm=NONE + hi PmenuExtraSel ctermfg=240 ctermbg=249 cterm=NONE + hi PmenuMatch ctermfg=90 ctermbg=254 cterm=NONE + hi PmenuMatchSel ctermfg=90 ctermbg=249 cterm=NONE hi SignColumn ctermfg=NONE ctermbg=NONE cterm=NONE hi Error ctermfg=160 ctermbg=231 cterm=reverse hi ErrorMsg ctermfg=160 ctermbg=231 cterm=reverse @@ -285,7 +293,7 @@ if s:t_Co >= 256 hi MoreMsg ctermfg=28 ctermbg=NONE cterm=NONE hi Question ctermfg=90 ctermbg=NONE cterm=NONE hi WarningMsg ctermfg=130 ctermbg=NONE cterm=NONE - hi Todo ctermfg=93 ctermbg=231 cterm=reverse + hi Todo ctermfg=56 ctermbg=231 cterm=reverse hi Search ctermfg=231 ctermbg=28 cterm=NONE hi IncSearch ctermfg=231 ctermbg=172 cterm=NONE hi WildMenu ctermfg=231 ctermbg=172 cterm=NONE @@ -298,10 +306,10 @@ if s:t_Co >= 256 hi Folded ctermfg=240 ctermbg=254 cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=254 cterm=NONE hi MatchParen ctermfg=199 ctermbg=NONE cterm=bold - hi SpellBad ctermfg=160 ctermbg=231 cterm=reverse - hi SpellCap ctermfg=30 ctermbg=231 cterm=reverse - hi SpellLocal ctermfg=28 ctermbg=231 cterm=reverse - hi SpellRare ctermfg=127 ctermbg=231 cterm=reverse + hi SpellBad ctermfg=160 ctermbg=NONE cterm=underline + hi SpellCap ctermfg=30 ctermbg=NONE cterm=underline + hi SpellLocal ctermfg=28 ctermbg=NONE cterm=underline + hi SpellRare ctermfg=127 ctermbg=NONE cterm=underline hi Comment ctermfg=245 ctermbg=NONE cterm=NONE hi Constant ctermfg=124 ctermbg=NONE cterm=NONE hi String ctermfg=28 ctermbg=NONE cterm=NONE @@ -309,11 +317,11 @@ if s:t_Co >= 256 hi Statement ctermfg=25 ctermbg=NONE cterm=NONE hi Type ctermfg=130 ctermbg=NONE cterm=NONE hi PreProc ctermfg=30 ctermbg=NONE cterm=NONE - hi Special ctermfg=93 ctermbg=NONE cterm=NONE + hi Special ctermfg=56 ctermbg=NONE cterm=NONE hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=25 ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=249 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=22 ctermbg=151 cterm=NONE hi DiffChange ctermfg=235 ctermbg=253 cterm=NONE @@ -330,14 +338,14 @@ endif if s:t_Co >= 16 if &background ==# 'dark' hi Normal ctermfg=grey ctermbg=black cterm=NONE - hi Statusline ctermfg=grey ctermbg=black cterm=reverse + hi Statusline ctermfg=grey ctermbg=black cterm=bold,reverse hi StatuslineNC ctermfg=darkgrey ctermbg=black cterm=reverse - hi VertSplit ctermfg=darkgrey ctermbg=darkgrey cterm=NONE - hi TabLine ctermfg=black ctermbg=grey cterm=NONE - hi TabLineFill ctermfg=NONE ctermbg=darkgrey cterm=NONE - hi TabLineSel ctermfg=white ctermbg=black cterm=NONE + hi VertSplit ctermfg=darkgrey ctermbg=NONE cterm=NONE + hi TabLine ctermfg=black ctermbg=darkgrey cterm=NONE + hi TabLineFill ctermfg=NONE ctermbg=black cterm=NONE + hi TabLineSel ctermfg=black ctermbg=grey cterm=bold hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton ctermfg=black ctermbg=white cterm=NONE + hi ToolbarButton ctermfg=black ctermbg=grey cterm=NONE hi QuickFixLine ctermfg=black ctermbg=magenta cterm=NONE hi CursorLineNr ctermfg=white ctermbg=NONE cterm=bold hi LineNr ctermfg=grey ctermbg=NONE cterm=NONE @@ -366,17 +374,17 @@ if s:t_Co >= 16 hi WildMenu ctermfg=black ctermbg=yellow cterm=NONE hi debugPC ctermfg=darkblue ctermbg=NONE cterm=reverse hi debugBreakpoint ctermfg=darkcyan ctermbg=NONE cterm=reverse - hi Visual ctermfg=darkblue ctermbg=black cterm=reverse + hi Visual ctermfg=cyan ctermbg=black cterm=reverse hi VisualNOS ctermfg=black ctermbg=blue cterm=NONE hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline hi CursorColumn ctermfg=black ctermbg=yellow cterm=NONE hi Folded ctermfg=black ctermbg=NONE cterm=bold hi ColorColumn ctermfg=black ctermbg=darkyellow cterm=NONE hi MatchParen ctermfg=NONE ctermbg=NONE cterm=bold,underline - hi SpellBad ctermfg=darkred ctermbg=white cterm=reverse - hi SpellCap ctermfg=darkcyan ctermbg=black cterm=reverse - hi SpellLocal ctermfg=green ctermbg=black cterm=reverse - hi SpellRare ctermfg=magenta ctermbg=black cterm=reverse + hi SpellBad ctermfg=darkred ctermbg=NONE cterm=underline + hi SpellCap ctermfg=darkcyan ctermbg=NONE cterm=underline + hi SpellLocal ctermfg=green ctermbg=NONE cterm=underline + hi SpellRare ctermfg=magenta ctermbg=NONE cterm=underline hi Comment ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Constant ctermfg=red ctermbg=NONE cterm=NONE hi String ctermfg=green ctermbg=NONE cterm=NONE @@ -388,7 +396,7 @@ if s:t_Co >= 16 hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=blue ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=grey ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=black ctermbg=darkgreen cterm=NONE hi DiffChange ctermfg=black ctermbg=lightgray cterm=NONE @@ -400,14 +408,14 @@ if s:t_Co >= 16 else " Light background hi Normal ctermfg=black ctermbg=white cterm=NONE - hi Statusline ctermfg=white ctermbg=darkgrey cterm=NONE + hi Statusline ctermfg=white ctermbg=darkgrey cterm=bold hi StatuslineNC ctermfg=black ctermbg=lightgrey cterm=NONE - hi VertSplit ctermfg=lightgrey ctermbg=lightgrey cterm=NONE + hi VertSplit ctermfg=darkgrey ctermbg=NONE cterm=NONE hi TabLine ctermfg=black ctermbg=lightgrey cterm=NONE - hi TabLineFill ctermfg=NONE ctermbg=darkgrey cterm=NONE - hi TabLineSel ctermfg=white ctermbg=black cterm=reverse + hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=NONE + hi TabLineSel ctermfg=darkgrey ctermbg=white cterm=bold,reverse hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE - hi ToolbarButton ctermfg=white ctermbg=black cterm=NONE + hi ToolbarButton ctermfg=white ctermbg=darkgrey cterm=NONE hi QuickFixLine ctermfg=white ctermbg=darkmagenta cterm=NONE hi CursorLineNr ctermfg=black ctermbg=NONE cterm=bold hi LineNr ctermfg=darkgrey ctermbg=NONE cterm=NONE @@ -430,7 +438,7 @@ if s:t_Co >= 16 hi MoreMsg ctermfg=darkgreen ctermbg=NONE cterm=NONE hi Question ctermfg=darkmagenta ctermbg=NONE cterm=NONE hi WarningMsg ctermfg=darkyellow ctermbg=NONE cterm=NONE - hi Todo ctermfg=darkred ctermbg=white cterm=reverse + hi Todo ctermfg=blue ctermbg=white cterm=reverse hi Search ctermfg=white ctermbg=darkgreen cterm=NONE hi IncSearch ctermfg=white ctermbg=yellow cterm=NONE hi WildMenu ctermfg=white ctermbg=yellow cterm=NONE @@ -443,10 +451,10 @@ if s:t_Co >= 16 hi Folded ctermfg=black ctermbg=NONE cterm=bold hi ColorColumn ctermfg=black ctermbg=darkyellow cterm=NONE hi MatchParen ctermfg=NONE ctermbg=NONE cterm=bold,underline - hi SpellBad ctermfg=red ctermbg=white cterm=reverse - hi SpellCap ctermfg=darkcyan ctermbg=white cterm=reverse - hi SpellLocal ctermfg=darkgreen ctermbg=white cterm=reverse - hi SpellRare ctermfg=magenta ctermbg=white cterm=reverse + hi SpellBad ctermfg=red ctermbg=NONE cterm=underline + hi SpellCap ctermfg=darkcyan ctermbg=NONE cterm=underline + hi SpellLocal ctermfg=darkgreen ctermbg=NONE cterm=underline + hi SpellRare ctermfg=magenta ctermbg=NONE cterm=underline hi Comment ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Constant ctermfg=darkred ctermbg=NONE cterm=NONE hi String ctermfg=darkgreen ctermbg=NONE cterm=NONE @@ -454,11 +462,11 @@ if s:t_Co >= 16 hi Statement ctermfg=darkblue ctermbg=NONE cterm=NONE hi Type ctermfg=darkyellow ctermbg=NONE cterm=NONE hi PreProc ctermfg=darkcyan ctermbg=NONE cterm=NONE - hi Special ctermfg=darkred ctermbg=NONE cterm=NONE + hi Special ctermfg=blue ctermbg=NONE cterm=NONE hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline hi Title ctermfg=NONE ctermbg=NONE cterm=bold hi Directory ctermfg=darkblue ctermbg=NONE cterm=bold - hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE + hi Conceal ctermfg=darkgrey ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi DiffAdd ctermfg=black ctermbg=darkgreen cterm=NONE hi DiffChange ctermfg=black ctermbg=lightgray cterm=NONE @@ -477,10 +485,10 @@ if s:t_Co >= 8 hi Normal ctermfg=grey ctermbg=black cterm=NONE hi Statusline ctermfg=grey ctermbg=black cterm=bold,reverse hi StatuslineNC ctermfg=black ctermbg=grey cterm=NONE - hi VertSplit ctermfg=grey ctermbg=grey cterm=NONE - hi TabLine ctermfg=grey ctermbg=black cterm=reverse - hi TabLineFill ctermfg=NONE ctermbg=grey cterm=NONE - hi TabLineSel ctermfg=grey ctermbg=black cterm=NONE + hi VertSplit ctermfg=grey ctermbg=NONE cterm=NONE + hi TabLine ctermfg=grey ctermbg=black cterm=NONE + hi TabLineFill ctermfg=grey ctermbg=NONE cterm=NONE + hi TabLineSel ctermfg=grey ctermbg=black cterm=bold,reverse hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE hi ToolbarButton ctermfg=grey ctermbg=black cterm=bold,reverse hi QuickFixLine ctermfg=black ctermbg=darkmagenta cterm=NONE @@ -544,10 +552,10 @@ if s:t_Co >= 8 hi Normal ctermfg=black ctermbg=grey cterm=NONE hi Statusline ctermfg=grey ctermbg=black cterm=bold hi StatuslineNC ctermfg=grey ctermbg=darkgrey cterm=NONE - hi VertSplit ctermfg=black ctermbg=black cterm=NONE - hi TabLine ctermfg=black ctermbg=grey cterm=reverse - hi TabLineFill ctermfg=NONE ctermbg=darkgrey cterm=NONE - hi TabLineSel ctermfg=black ctermbg=grey cterm=NONE + hi VertSplit ctermfg=black ctermbg=NONE cterm=NONE + hi TabLine ctermfg=black ctermbg=grey cterm=NONE + hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=NONE + hi TabLineSel ctermfg=grey ctermbg=black cterm=bold hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE hi ToolbarButton ctermfg=grey ctermbg=black cterm=bold hi QuickFixLine ctermfg=black ctermbg=darkmagenta cterm=NONE @@ -572,7 +580,7 @@ if s:t_Co >= 8 hi MoreMsg ctermfg=darkgreen ctermbg=NONE cterm=NONE hi Question ctermfg=darkmagenta ctermbg=NONE cterm=NONE hi WarningMsg ctermfg=darkyellow ctermbg=NONE cterm=NONE - hi Todo ctermfg=darkred ctermbg=black cterm=reverse + hi Todo ctermfg=blue ctermbg=black cterm=reverse hi Search ctermfg=darkgreen ctermbg=black cterm=reverse hi IncSearch ctermfg=darkyellow ctermbg=black cterm=reverse hi WildMenu ctermfg=black ctermbg=darkyellow cterm=NONE @@ -706,6 +714,8 @@ endif " Color: colorlC #ff5fff 207 magenta " Color: colorDim #878787 102 grey " Color: colorMP #ff00af 199 magenta +" Color: colorV #5fd7ff 81 cyan +" Color: colorSt #9e9e9e 247 grey " Color: diffAdd #5f875f 65 darkgreen " Color: diffAddFg #afffaf 157 black " Color: diffDelete #875f5f 95 darkred @@ -733,7 +743,7 @@ endif " Color: color14 #00afaf 37 cyan " Color: color07 #8a8a8a 245 grey " Color: color15 #ffffff 231 white -" Color: color16 #8700ff 93 darkred +" Color: color16 #5f00d7 56 blue " Color: colorCm #8a8a8a 245 darkgrey " Color: colorLine #EEEEEE 255 grey " Color: colorB #E4E4E4 254 grey @@ -741,7 +751,7 @@ endif " Color: colorTab #d0d0d0 252 lightgrey " Color: colorC #000000 16 black " Color: colorlC #FF00FF 201 magenta -" Color: colorV #5F87AF 67 darkblue +" Color: colorV #0087af 31 darkcyan " Color: colorDim #626262 241 darkgrey " Color: colorSt #5f5f5f 59 darkgrey " Color: colorMP #ff00af 199 magenta diff --git a/runtime/colors/zaibatsu.vim b/runtime/colors/zaibatsu.vim index dba860397d..db396d4605 100644 --- a/runtime/colors/zaibatsu.vim +++ b/runtime/colors/zaibatsu.vim @@ -4,7 +4,7 @@ " Maintainer: Romain Lafourcade " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:43 +" Last Updated: Tue 09 Jul 2024 17:11:55 " Generated by Colortemplate v2.2.3 @@ -35,6 +35,8 @@ hi PmenuExtra guifg=#878092 guibg=#ffffff gui=NONE cterm=NONE hi! link PmenuExtraSel PmenuSel hi PmenuKind guifg=#878092 guibg=#ffffff gui=NONE cterm=NONE hi! link PmenuKindSel PmenuSel +hi PmenuMatch guifg=#d700ff guibg=#ffffff gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#d700ff guibg=#afafff gui=NONE cterm=NONE hi ColorColumn guifg=NONE guibg=#510039 gui=NONE cterm=NONE hi CursorLine guifg=NONE guibg=#362b49 gui=NONE cterm=NONE hi CursorColumn guifg=NONE guibg=#362b49 gui=NONE cterm=NONE @@ -138,6 +140,8 @@ if s:t_Co >= 256 hi! link PmenuExtraSel PmenuSel hi PmenuKind ctermfg=103 ctermbg=231 cterm=NONE hi! link PmenuKindSel PmenuSel + hi PmenuMatch ctermfg=165 ctermbg=231 cterm=NONE + hi PmenuMatchSel ctermfg=165 ctermbg=147 cterm=NONE hi ColorColumn ctermfg=NONE ctermbg=52 cterm=NONE hi CursorLine ctermfg=NONE ctermbg=237 cterm=NONE hi CursorColumn ctermfg=NONE ctermbg=237 cterm=NONE @@ -244,6 +248,8 @@ if s:t_Co >= 16 hi! link PmenuExtraSel PmenuSel hi PmenuKind ctermfg=darkgray ctermbg=white cterm=NONE hi! link PmenuKindSel PmenuSel + hi PmenuMatch ctermfg=darkmagenta ctermbg=white cterm=NONE + hi PmenuMatchSel ctermfg=darkmagenta ctermbg=blue cterm=NONE hi ColorColumn ctermfg=white ctermbg=darkred cterm=NONE hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline hi CursorColumn ctermfg=NONE ctermbg=blue cterm=NONE @@ -350,6 +356,8 @@ if s:t_Co >= 8 hi! link PmenuExtraSel PmenuSel hi! link PmenuKind Pmenu hi! link PmenuKindSel PmenuSel + hi! link PmenuMatch Pmenu + hi! link PmenuMatchSel PmenuSel hi ColorColumn ctermfg=white ctermbg=darkred cterm=NONE hi CursorLine ctermfg=NONE ctermbg=NONE cterm=underline hi CursorColumn ctermfg=NONE ctermbg=blue cterm=NONE diff --git a/runtime/colors/zellner.vim b/runtime/colors/zellner.vim index 8a15004d5e..e1e1186307 100644 --- a/runtime/colors/zellner.vim +++ b/runtime/colors/zellner.vim @@ -4,7 +4,7 @@ " Maintainer: Original maintainer Ron Aaron " Website: https://github.com/vim/colorschemes " License: Same as Vim -" Last Updated: Fri 15 Dec 2023 20:05:44 +" Last Updated: Wed 10 Jul 2024 17:44:06 " Generated by Colortemplate v2.2.3 @@ -42,6 +42,8 @@ hi Pmenu guifg=#000000 guibg=#dadada gui=NONE cterm=NONE hi PmenuSel guifg=#000000 guibg=#ffff00 gui=NONE cterm=NONE hi PmenuSbar guifg=NONE guibg=#ffffff gui=NONE cterm=NONE hi PmenuThumb guifg=NONE guibg=#a9a9a9 gui=NONE cterm=NONE +hi PmenuMatch guifg=#a52a2a guibg=#dadada gui=NONE cterm=NONE +hi PmenuMatchSel guifg=#a52a2a guibg=#ffff00 gui=NONE cterm=NONE hi TabLine guifg=#000000 guibg=#a9a9a9 gui=underline cterm=underline hi TabLineFill guifg=NONE guibg=NONE gui=reverse ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel guifg=#000000 guibg=#ffffff gui=bold cterm=bold @@ -82,7 +84,7 @@ hi Type guifg=#0000ff guibg=NONE gui=NONE cterm=NONE hi Special guifg=#ff00ff guibg=NONE gui=NONE cterm=NONE hi Tag guifg=#006400 guibg=NONE gui=NONE cterm=NONE hi Directory guifg=#0000ff guibg=NONE gui=bold cterm=bold -hi Conceal guifg=#ff0000 guibg=NONE gui=NONE cterm=NONE +hi Conceal guifg=#a9a9a9 guibg=NONE gui=NONE cterm=NONE hi Ignore guifg=NONE guibg=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE hi Title guifg=#a020f0 guibg=NONE gui=bold cterm=bold hi DiffAdd guifg=#ffffff guibg=#5f875f gui=NONE cterm=NONE @@ -115,6 +117,8 @@ if s:t_Co >= 256 hi PmenuSel ctermfg=16 ctermbg=226 cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=231 cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=248 cterm=NONE + hi PmenuMatch ctermfg=124 ctermbg=253 cterm=NONE + hi PmenuMatchSel ctermfg=124 ctermbg=226 cterm=NONE hi TabLine ctermfg=16 ctermbg=248 cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=16 ctermbg=231 cterm=bold @@ -155,7 +159,7 @@ if s:t_Co >= 256 hi Special ctermfg=201 ctermbg=NONE cterm=NONE hi Tag ctermfg=22 ctermbg=NONE cterm=NONE hi Directory ctermfg=21 ctermbg=NONE cterm=bold - hi Conceal ctermfg=196 ctermbg=NONE cterm=NONE + hi Conceal ctermfg=248 ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Title ctermfg=129 ctermbg=NONE cterm=bold hi DiffAdd ctermfg=231 ctermbg=65 cterm=NONE @@ -183,6 +187,8 @@ if s:t_Co >= 16 hi PmenuSel ctermfg=black ctermbg=yellow cterm=NONE hi PmenuSbar ctermfg=NONE ctermbg=white cterm=NONE hi PmenuThumb ctermfg=NONE ctermbg=darkgrey cterm=NONE + hi PmenuMatch ctermfg=darkred ctermbg=grey cterm=NONE + hi PmenuMatchSel ctermfg=darkred ctermbg=yellow cterm=NONE hi TabLine ctermfg=black ctermbg=grey cterm=underline hi TabLineFill ctermfg=NONE ctermbg=NONE cterm=reverse hi TabLineSel ctermfg=black ctermbg=white cterm=bold @@ -223,7 +229,7 @@ if s:t_Co >= 16 hi Special ctermfg=magenta ctermbg=NONE cterm=NONE hi Tag ctermfg=darkgreen ctermbg=NONE cterm=NONE hi Directory ctermfg=blue ctermbg=NONE cterm=bold - hi Conceal ctermfg=red ctermbg=NONE cterm=NONE + hi Conceal ctermfg=grey ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Title ctermfg=darkmagenta ctermbg=NONE cterm=bold hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE @@ -288,7 +294,7 @@ if s:t_Co >= 8 hi Type ctermfg=darkblue ctermbg=NONE cterm=bold hi Special ctermfg=darkgreen ctermbg=NONE cterm=NONE hi Directory ctermfg=darkblue ctermbg=NONE cterm=bold - hi Conceal ctermfg=darkred ctermbg=NONE cterm=NONE + hi Conceal ctermfg=NONE ctermbg=NONE cterm=NONE hi Ignore ctermfg=NONE ctermbg=NONE cterm=NONE hi Title ctermfg=darkmagenta ctermbg=NONE cterm=bold hi DiffAdd ctermfg=white ctermbg=darkgreen cterm=NONE diff --git a/runtime/compiler/hare.vim b/runtime/compiler/hare.vim index c98bbb9c63..33edb3a281 100644 --- a/runtime/compiler/hare.vim +++ b/runtime/compiler/hare.vim @@ -1,28 +1,29 @@ -" Vim compiler file -" Compiler: Hare Compiler -" Maintainer: Amelia Clarke -" Last Change: 2022-09-21 -" 2024 Apr 05 by The Vim Project (removed :CompilerSet definition) +" Vim compiler file. +" Compiler: Hare +" Maintainer: Amelia Clarke +" 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 f5fe84124f..9bd4cdf270 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 -" 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/compiler/jq.vim b/runtime/compiler/jq.vim new file mode 100644 index 0000000000..a656223e51 --- /dev/null +++ b/runtime/compiler/jq.vim @@ -0,0 +1,25 @@ +" Vim compiler file +" Compiler: jq +" Maintainer: Vito +" Last Change: 2024 Apr 17 +" Upstream: https://github.com/vito-c/jq.vim + +if exists('b:current_compiler') + finish +endif +let b:current_compiler = 'jq' + +let s:save_cpoptions = &cpoptions +set cpoptions&vim + +if has('unix') + CompilerSet makeprg=jq\ -f\ %:S\ /dev/null +else + CompilerSet makeprg=jq\ -f\ %:S\ nul +endif +CompilerSet errorformat=%E%m\ at\ \\<%o\\>\\,\ line\ %l:, + \%Z, + \%-G%.%# + +let &cpoptions = s:save_cpoptions +unlet s:save_cpoptions diff --git a/runtime/compiler/typst.vim b/runtime/compiler/typst.vim new file mode 100644 index 0000000000..33e55818e9 --- /dev/null +++ b/runtime/compiler/typst.vim @@ -0,0 +1,15 @@ +" Vim compiler file +" Language: Typst +" Maintainer: Gregory Anders +" Last Change: 2024-07-14 +" Based on: https://github.com/kaarmu/typst.vim + +if exists('current_compiler') + finish +endif +let current_compiler = get(g:, 'typst_cmd', 'typst') + +" With `--diagnostic-format` we can use the default errorformat +let s:makeprg = [current_compiler, 'compile', '--diagnostic-format', 'short', '%:S'] + +execute 'CompilerSet makeprg=' . join(s:makeprg, '\ ') diff --git a/runtime/doc/Make_all.mak b/runtime/doc/Make_all.mak index a829497de8..3e148c1fac 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 \ @@ -173,6 +174,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/Make_mvc.mak b/runtime/doc/Make_mvc.mak index f2fbc52ed5..c387ef8c4f 100644 --- a/runtime/doc/Make_mvc.mak +++ b/runtime/doc/Make_mvc.mak @@ -12,7 +12,7 @@ # Correct the following line for the where executeable file vim is installed. # Please do not put the path in quotes. -VIMEXE = D:\Programs\Vim\vim90\vim.exe +VIMPROG = D:\Programs\Vim\vim90\vim.exe # Correct the following line for the directory where iconv installed. # Please do not put the path in quotes. @@ -63,7 +63,7 @@ doctags : doctags.c # Use Vim to generate the tags file. Can only be used when Vim has been # compiled and installed. Supports multiple languages. vimtags : $(DOCS) - @"$(VIMEXE)" --clean -esX -V1 -u doctags.vim + @"$(VIMPROG)" --clean -esX -V1 -u doctags.vim uganda.nsis.txt : uganda.??? @@ -105,7 +105,7 @@ perlhtml : tags $(DOCS) # Check URLs in the help with "curl" or "powershell". test_urls : - "$(VIMEXE)" --clean -S test_urls.vim + "$(VIMPROG)" --clean -S test_urls.vim clean : $(RM) doctags.exe doctags.obj diff --git a/runtime/doc/Makefile b/runtime/doc/Makefile index 30a4f08bd7..38f505367c 100644 --- a/runtime/doc/Makefile +++ b/runtime/doc/Makefile @@ -6,8 +6,7 @@ AWK = awk -# Set to $(VIMTARGET) when executed from src/Makefile. -VIMEXE = vim +VIMPROG = ../../src/vim # include the config.mk from the source directory. It's only needed to set # AWK, used for "make html". Comment this out if the include gives problems. @@ -23,9 +22,9 @@ include Make_all.mak all: tags vim.man evim.man vimdiff.man vimtutor.man xxd.man $(CONVERTED) # Use Vim to generate the tags file. Can only be used when Vim has been -# compiled and installed. Supports multiple languages. +# compiled. Supports multiple languages. vimtags: $(DOCS) - @$(VIMEXE) --clean -esX -V1 -u doctags.vim + @$(VIMPROG) --clean -esX -V1 -u doctags.vim # Use "doctags" to generate the tags file. Only works for English! tags: doctags $(DOCS) @@ -57,7 +56,7 @@ uganda.nsis.txt : uganda.??? $${dpn} | uniq > $${trg%txt}$${dpn##*.}; \ done # This files needs to be in dos fileformat for NSIS. - $(VIMEXE) -e -X -u NONE --cmd "set notitle noicon nocp noml viminfo=" \ + $(VIMPROG) -e -X -u NONE --cmd "set notitle noicon nocp noml viminfo=" \ -c "argdo write ++ff=dos" -c "qa" uganda.nsis.??? # Awk version of .txt to .html conversion. @@ -91,7 +90,7 @@ perlhtml: tags $(DOCS) # Check URLs in the help with "curl". test_urls: - $(VIMEXE) --clean -S test_urls.vim + $(VIMPROG) --clean -S test_urls.vim clean: -rm -f doctags *.html tags.ref diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 16d162a1ff..1ea96bce72 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 Jul 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -54,20 +54,20 @@ Recommended use: without the autocommand being repeated. Example in Vim9 script: > - autocmd_add({replace: true, + autocmd_add([{replace: true, group: 'DemoGroup', event: 'BufEnter', pattern: '*.txt', cmd: 'call DemoBufEnter()' - }) + }]) In legacy script: > - call autocmd_add(#{replace: v:true, + call autocmd_add([#{replace: v:true, \ group: 'DemoGroup', \ event: 'BufEnter', \ pattern: '*.txt', \ cmd: 'call DemoBufEnter()' - \ }) + \ }]) ============================================================================== 2. Defining autocommands *autocmd-define* @@ -381,6 +381,7 @@ Name triggered by ~ |CursorHold| the user doesn't press a key for a while |CursorHoldI| the user doesn't press a key for a while in Insert mode |CursorMoved| the cursor was moved in Normal mode +|CursorMovedC| the cursor was moved in the |Command-line| |CursorMovedI| the cursor was moved in Insert mode |WinNewPre| before creating a new window @@ -430,8 +431,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 @@ -440,6 +441,8 @@ Name triggered by ~ |CompleteDone| after Insert mode completion is done, after clearing info +|KeyInputPre| just before a key is processed + |User| to be used in combination with ":doautocmd" |SigUSR1| after the SIGUSR1 signal has been detected @@ -750,6 +753,13 @@ CursorMoved After the cursor was moved in Normal or Visual Careful: This is triggered very often, don't do anything that the user does not expect or that is slow. + *CursorMovedC* +CursorMovedC After the cursor was moved in the command + line. Be careful not to mess up the command + line, it may cause Vim to lock up. + is set to a single character, + indicating the type of command-line. + |cmdwin-char| *CursorMovedI* CursorMovedI After the cursor was moved in Insert mode. Not triggered when the popup menu is visible. @@ -908,12 +918,12 @@ FilterWritePre Before writing a file for a filter command or *FocusGained* FocusGained When Vim got input focus. Only for the GUI version and a few console versions where this - can be detected. + can be detected. |xterm-focus-event| *FocusLost* FocusLost When Vim lost input focus. Only for the GUI version and a few console versions where this - can be detected. May also happen when a - dialog pops up. + can be detected. |xterm-focus-event| + May also happen when a dialog pops up. *FuncUndefined* FuncUndefined When a user function is used but it isn't defined. Useful for defining a function only @@ -971,6 +981,23 @@ InsertLeavePre Just before leaving Insert mode. Also when *InsertLeave* InsertLeave Just after leaving Insert mode. Also when using CTRL-O |i_CTRL-O|. But not for |i_CTRL-C|. + *KeyInputPre* +KeyInputPre Just before a key is processed after mappings + have been applied. The pattern is matched + against a string that indicates the current + mode, which is the same as what is returned by + `mode(1)`. + The |v:char| variable indicates the key typed + and can be changed during the event to process + a different key. When |v:char| is not a + single character or a special key, the first + character is used. + The following values of |v:event| are set: + typed The key is typed or not. + typedchar The (actual) typed key. + It is not allowed to change the text + |textlock| or the current mode. + {only with the +eval feature} *MenuPopup* MenuPopup Just before showing the popup menu (under the right mouse button). Useful for adjusting the diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index d156579f46..1a957e27bf 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 Jul 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -28,9 +28,9 @@ acos({expr}) Float arc cosine of {expr} add({object}, {item}) List/Blob append {item} to {object} and({expr}, {expr}) Number bitwise AND append({lnum}, {text}) Number append {text} below line {lnum} -appendbufline({expr}, {lnum}, {text}) +appendbufline({buf}, {lnum}, {text}) Number append {text} below line {lnum} - in buffer {expr} + in buffer {buf} argc([{winid}]) Number number of files in the argument list argidx() Number current index in the argument list arglistid([{winnr} [, {tabnr}]]) Number argument list id @@ -67,6 +67,8 @@ autocmd_get([{opts}]) List return a list of autocmds balloon_gettext() String current text in the balloon balloon_show({expr}) none show {expr} inside the balloon balloon_split({msg}) List split {msg} as used for a balloon +bindtextdomain({package}, {path}) + Bool bind text domain to specified path blob2list({blob}) List convert {blob} into a list of numbers browse({save}, {title}, {initdir}, {default}) String put up a file requester @@ -153,8 +155,8 @@ diff_filler({lnum}) Number diff filler lines about {lnum} diff_hlID({lnum}, {col}) Number diff highlighting at {lnum}/{col} digraph_get({chars}) String get the |digraph| of {chars} digraph_getlist([{listall}]) List get all |digraph|s -digraph_set({chars}, {digraph}) Boolean register |digraph| -digraph_setlist({digraphlist}) Boolean register multiple |digraph|s +digraph_set({chars}, {digraph}) Bool register |digraph| +digraph_setlist({digraphlist}) Bool register multiple |digraph|s echoraw({expr}) none output {expr} as-is empty({expr}) Number |TRUE| if {expr} is empty environ() Dict return environment variables @@ -178,6 +180,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 +269,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 @@ -273,7 +279,8 @@ gettabvar({nr}, {varname} [, {def}]) gettabwinvar({tabnr}, {winnr}, {name} [, {def}]) any {name} in {winnr} in tab page {tabnr} gettagstack([{nr}]) Dict get the tag stack of window {nr} -gettext({text}) String lookup translation of {text} +gettext({text} [, {package}]) + String lookup translation of {text} getwininfo([{winid}]) List list of info about each window getwinpos([{timeout}]) List X and Y coord in pixels of Vim window getwinposx() Number X coord in pixels of the Vim window @@ -302,6 +309,7 @@ hlget([{name} [, {resolve}]]) List get highlight group attributes hlset({list}) Number set highlight group attributes hostname() String name of the machine Vim is running on iconv({expr}, {from}, {to}) String convert encoding of {expr} +id({item}) String get unique identity string of item indent({lnum}) Number indent of line {lnum} index({object}, {expr} [, {start} [, {ic}]]) Number index in {object} where {expr} appears @@ -425,6 +433,7 @@ popup_menu({what}, {options}) Number create a popup window used as a menu popup_move({id}, {options}) none set position of popup window {id} popup_notification({what}, {options}) Number create a notification popup window +popup_setbuf({id}, {buf}) Bool set the buffer for the popup window {id} popup_setoptions({id}, {options}) none set options for popup window {id} popup_settext({id}, {text}) none set the text of popup window {id} @@ -521,9 +530,9 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]]) server2client({clientid}, {string}) Number send reply string serverlist() String get a list of available servers -setbufline({expr}, {lnum}, {text}) +setbufline({buf}, {lnum}, {text}) Number set line {lnum} to {text} in buffer - {expr} + {buf} setbufvar({buf}, {varname}, {val}) none set {varname} in buffer {buf} to {val} setcellwidths({list}) none set character cell width overrides @@ -767,6 +776,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 @@ -783,6 +793,8 @@ abs({expr}) *abs()* Can also be used as a |method|: > Compute()->abs() +< + Return type: |Number| or |Float| depending on {expr} acos({expr}) *acos()* @@ -798,6 +810,8 @@ acos({expr}) *acos()* Can also be used as a |method|: > Compute()->acos() +< + Return type: |Float| add({object}, {expr}) *add()* @@ -813,6 +827,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()* @@ -823,6 +840,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()* @@ -844,6 +863,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()* @@ -871,6 +892,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()* @@ -883,10 +906,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 @@ -900,6 +927,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 @@ -920,6 +949,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]. @@ -935,12 +967,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|. @@ -954,6 +986,8 @@ atan({expr}) *atan()* Can also be used as a |method|: > Compute()->atan() +< + Return type: |Float| atan2({expr1}, {expr2}) *atan2()* @@ -970,6 +1004,8 @@ atan2({expr1}, {expr2}) *atan2()* Can also be used as a |method|: > Compute()->atan2(1) +< + Return type: |Float| autocmd_add({acmds}) *autocmd_add()* @@ -1017,6 +1053,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. @@ -1065,6 +1104,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 @@ -1123,11 +1165,17 @@ autocmd_get([{opts}]) *autocmd_get()* Can also be used as a |method|: > Getopts()->autocmd_get() < + Return type: list> + + 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 @@ -1159,6 +1207,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 @@ -1171,6 +1222,19 @@ balloon_split({msg}) *balloon_split()* < {only available when compiled with the |+balloon_eval_term| feature} + Return type: list or list + +bindtextdomain({package}, {path}) *bindtextdomain()* + Bind a specific {package} to a {path} so that the + |gettext()| function can be used to get language-specific + translations for a package. {path} is the directory name + for the translations. See |package-translation|. + + Returns v:true on success and v:false on failure (out of + memory). + + Return type: |vim9-boolean| + blob2list({blob}) *blob2list()* Return a List containing the number value of each byte in Blob {blob}. Examples: > @@ -1182,6 +1246,8 @@ blob2list({blob}) *blob2list()* Can also be used as a |method|: > GetBlob()->blob2list() < + Return type: list or list + *browse()* browse({save}, {title}, {initdir}, {default}) Put up a file requester. This only works when "has("browse")" @@ -1194,8 +1260,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 @@ -1207,6 +1275,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). @@ -1222,6 +1293,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 @@ -1248,8 +1322,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). @@ -1257,6 +1334,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 @@ -1270,6 +1350,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 @@ -1278,6 +1361,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 @@ -1311,11 +1397,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. @@ -1337,10 +1425,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}, @@ -1354,6 +1445,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 @@ -1368,6 +1462,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 @@ -1381,10 +1478,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 @@ -1422,6 +1522,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 @@ -1438,6 +1541,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 @@ -1450,6 +1556,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 @@ -1467,6 +1576,8 @@ ceil({expr}) *ceil()* Can also be used as a |method|: > Compute()->ceil() +< + Return type: |Float| ch_ functions are documented here: |channel-functions-details| @@ -1481,6 +1592,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: > @@ -1502,6 +1616,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}. @@ -1514,6 +1631,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 @@ -1527,6 +1646,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}. @@ -1563,6 +1684,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 @@ -1589,6 +1713,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'. @@ -1599,6 +1726,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 @@ -1609,35 +1739,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. @@ -1650,6 +1782,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. @@ -1684,6 +1818,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 @@ -1696,6 +1833,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. @@ -1705,6 +1845,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 @@ -1767,6 +1909,8 @@ complete_info([{what}]) *complete_info()* < Can also be used as a |method|: > GetItems()->complete_info() < + Return type: dict + *confirm()* confirm({msg} [, {choices} [, {default} [, {type}]]]) confirm() offers the user a dialog, from which a choice can be @@ -1826,8 +1970,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 @@ -1837,6 +1984,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|. @@ -1850,6 +2000,8 @@ cos({expr}) *cos()* Can also be used as a |method|: > Compute()->cos() +< + Return type: |Float| cosh({expr}) *cosh()* @@ -1865,6 +2017,8 @@ cosh({expr}) *cosh()* Can also be used as a |method|: > Compute()->cosh() +< + Return type: |Float| count({comp}, {expr} [, {ic} [, {start}]]) *count()* *E706* @@ -1883,6 +2037,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 @@ -1924,6 +2080,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 @@ -1959,6 +2118,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 @@ -1971,6 +2133,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 @@ -1996,6 +2161,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 @@ -2022,6 +2190,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}. @@ -2040,6 +2211,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 @@ -2052,6 +2225,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 @@ -2118,6 +2294,10 @@ diff({fromlist}, {tolist} [, {options}]) *diff()* Can also be used as a |method|: > GetFromList->diff(to_list) < + Return type: |String| or list> or list + 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 @@ -2129,6 +2309,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 @@ -2144,6 +2327,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 @@ -2168,6 +2353,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. @@ -2194,6 +2381,8 @@ digraph_getlist([{listall}]) *digraph_getlist()* Can also be used as a |method|: > GetNumber()->digraph_getlist() < + Return type: list> + This function works only when compiled with the |+digraphs| feature. If this feature is disabled, this function will display an error message. @@ -2207,7 +2396,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 @@ -2219,6 +2408,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. @@ -2242,6 +2433,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. @@ -2256,6 +2449,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. @@ -2275,6 +2470,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 @@ -2283,6 +2481,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 err_teapot([{expr}]) *err_teapot()* @@ -2292,6 +2492,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 @@ -2304,6 +2506,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. @@ -2314,6 +2518,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 @@ -2321,6 +2528,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 @@ -2349,6 +2559,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 @@ -2382,6 +2595,9 @@ execute({command} [, {silent}]) *execute()* Can also be used as a |method|: > GetCommand()->execute() +< + Return type: |String| + exepath({expr}) *exepath()* If {expr} is an executable and is either an absolute path, a @@ -2395,8 +2611,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 @@ -2500,6 +2719,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 @@ -2515,6 +2736,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 @@ -2529,6 +2752,8 @@ exp({expr}) *exp()* Can also be used as a |method|: > Compute()->exp() +< + Return type: |Float| expand({string} [, {nosuf} [, {list}]]) *expand()* @@ -2546,7 +2771,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 @@ -2629,6 +2854,9 @@ expand({string} [, {nosuf} [, {list}]]) *expand()* Can also be used as a |method|: > Getpattern()->expand() +< + Return type: |String| or list depending on {list} + expandcmd({string} [, {options}]) *expandcmd()* Expand special items in String {string} like what is done for @@ -2654,6 +2882,8 @@ expandcmd({string} [, {options}]) *expandcmd()* Can also be used as a |method|: > GetCommand()->expandcmd() < + Return type: |String| or list depending on {list} + extend({expr1}, {expr2} [, {expr3}]) *extend()* {expr1} and {expr2} must be both |Lists| or both |Dictionaries|. @@ -2692,6 +2922,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()* @@ -2699,6 +2932,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 @@ -2756,6 +2992,24 @@ feedkeys({string} [, {mode}]) *feedkeys()* Can also be used as a |method|: > GetInput()->feedkeys() +< + Return type: |String| or list 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 @@ -2772,7 +3026,10 @@ filereadable({file}) *filereadable()* < Can also be used as a |method|: > GetName()->filereadable() -< *file_readable()* +< + Return type: |Number| + + *file_readable()* Obsolete name: file_readable(). @@ -2784,6 +3041,8 @@ filewritable({file}) *filewritable()* Can also be used as a |method|: > GetName()->filewritable() +< + Return type: |Number| filter({expr1}, {expr2}) *filter()* @@ -2846,6 +3105,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 @@ -2867,6 +3130,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. @@ -2878,6 +3144,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} @@ -2903,9 +3172,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 @@ -2931,6 +3205,8 @@ float2nr({expr}) *float2nr()* Can also be used as a |method|: > Compute()->float2nr() +< + Return type: |Number| floor({expr}) *floor()* @@ -2948,6 +3224,8 @@ floor({expr}) *floor()* Can also be used as a |method|: > Compute()->floor() +< + Return type: |Float| fmod({expr1}, {expr2}) *fmod()* @@ -2968,6 +3246,8 @@ fmod({expr1}, {expr2}) *fmod()* Can also be used as a |method|: > Compute()->fmod(1.22) +< + Return type: |Float| fnameescape({string}) *fnameescape()* @@ -2988,6 +3268,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 @@ -3008,6 +3291,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 @@ -3018,6 +3304,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 @@ -3028,6 +3317,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} @@ -3044,6 +3336,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 @@ -3060,8 +3354,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. @@ -3075,6 +3372,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|. @@ -3115,12 +3415,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} @@ -3145,8 +3450,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. @@ -3161,6 +3468,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}. @@ -3243,6 +3552,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| @@ -3265,19 +3577,28 @@ garbagecollect([{atexit}]) *garbagecollect()* type a character. To force garbage collection immediately use |test_garbagecollect_now()|. -get({list}, {idx} [, {default}]) *get()* + Return type: |String| + + +get({list}, {idx} [, {default}]) *get()* *get()-list* 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) -get({blob}, {idx} [, {default}]) +< + Return type: any, depending on {list} + +get({blob}, {idx} [, {default}]) *get()-blob* 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) -get({dict}, {key} [, {default}]) +< + Return type: |Number| + +get({dict}, {key} [, {default}]) *get()-dict* Get item with key {key} from |Dictionary| {dict}. When this item is not available return {default}. Return zero when {default} is omitted. Useful example: > @@ -3286,17 +3607,36 @@ get({dict}, {key} [, {default}]) 'default' when it does not exist. Preferably used as a |method|: > mydict->get(key) -get({func}, {what}) - Get item {what} from Funcref {func}. Possible values for +< + Return type: any, depending on {dict} + +get({func}, {what}) *get()-func* + Get item {what} from |Funcref| {func}. Possible values for {what} are: - "name" The function name - "func" The function - "dict" The dictionary - "args" The list with arguments + "name" The function name + "func" The function + "dict" The dictionary + "args" The list with arguments + "arity" A dictionary with information about the number of + arguments accepted by the function (minus the + {arglist}) with the following fields: + required the number of positional arguments + optional the number of optional arguments, + in addition to the required ones + varargs |TRUE| if the function accepts a + variable number of arguments |...| + + Note: There is no error, if the {arglist} of + the Funcref contains more arguments than the + Funcref expects, it's not validated. + Returns zero on error. + Preferably used as a |method|: > myfunc->get(what) < + Return type: any, depending on {func} and {what} + *getbufinfo()* getbufinfo([{buf}]) getbufinfo([{dict}]) @@ -3372,6 +3712,8 @@ getbufinfo([{dict}]) Can also be used as a |method|: > GetBufnr()->getbufinfo() < + Return type: list> + *getbufline()* getbufline({buf}, {lnum} [, {end}]) @@ -3402,11 +3744,16 @@ getbufline({buf}, {lnum} [, {end}]) < Can also be used as a |method|: > GetBufnr()->getbufline(lnum) < + Return type: list + *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:" @@ -3431,12 +3778,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 + getchangelist([{buf}]) *getchangelist()* Returns the |changelist| for the buffer {buf}. For the use @@ -3456,6 +3808,9 @@ getchangelist([{buf}]) *getchangelist()* Can also be used as a |method|: > GetBufnr()->getchangelist() +< + Return type: list + getchar([{expr}]) *getchar()* Get a single character from the user or input stream. @@ -3536,6 +3891,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 @@ -3553,8 +3911,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. @@ -3569,6 +3929,9 @@ getcharpos({expr}) < Can also be used as a |method|: > GetMark()->getcharpos() +< + Return type: list + getcharsearch() *getcharsearch()* Return the current character search information as a {dict} @@ -3590,6 +3953,8 @@ getcharsearch() *getcharsearch()* :nnoremap , getcharsearch().forward ? ',' : ';' < Also see |setcharsearch()|. + Return type: dict + getcharstr([{expr}]) *getcharstr()* Get a single character from the user or input stream as a @@ -3603,6 +3968,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 @@ -3612,6 +3980,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 @@ -3623,6 +3994,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. @@ -3632,6 +4006,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. @@ -3642,6 +4019,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: @@ -3657,11 +4037,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 @@ -3681,6 +4067,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()* customlist,{func} custom completion, defined via {func} diff_buffer |:diffget| and |:diffput| completion dir directory names + dir_in_path directory names in |'cdpath'| environment environment variable names event autocommand events expression Vim expression @@ -3736,6 +4123,8 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()* Can also be used as a |method|: > GetPattern()->getcompletion('color') < + Return type: list + *getcurpos()* getcurpos([{winid}]) Get the position of the cursor. This is like getpos('.'), but @@ -3765,8 +4154,10 @@ getcurpos([{winid}]) Can also be used as a |method|: > GetWinid()->getcurpos() < - *getcursorcharpos()* -getcursorcharpos([{winid}]) + Return type: list + + +getcursorcharpos([{winid}]) *getcursorcharpos()* Same as |getcurpos()| but the column number in the returned List is a character index instead of a byte index. @@ -3777,9 +4168,11 @@ getcursorcharpos([{winid}]) < Can also be used as a |method|: > GetWinid()->getcursorcharpos() +< + Return type: list -< *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. @@ -3814,6 +4207,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} @@ -3827,6 +4222,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 @@ -3842,6 +4240,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}. @@ -3860,8 +4261,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}. @@ -3872,6 +4276,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 @@ -3882,6 +4289,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 @@ -3906,12 +4316,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. @@ -3934,8 +4349,10 @@ getjumplist([{winnr} [, {tabnr}]]) *getjumplist()* Can also be used as a |method|: > GetWinnr()->getjumplist() +< + Return type: list -< *getline()* + *getline()* getline({lnum} [, {end}]) Without {end} the result is a String, which is line {lnum} from the current buffer. Example: > @@ -3960,8 +4377,10 @@ getline({lnum} [, {end}]) < Can also be used as a |method|: > ComputeLnum()->getline() +< + Return type: list 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()* @@ -3994,6 +4413,8 @@ getloclist({nr} [, {what}]) *getloclist()* Examples (See also |getqflist-examples|): > :echo getloclist(3, {'all': 0}) :echo getloclist(5, {'filewinid': 0}) +< + Return type: list> or list getmarklist([{buf}]) *getmarklist()* @@ -4017,6 +4438,9 @@ getmarklist([{buf}]) *getmarklist()* Can also be used as a |method|: > GetBufnr()->getmarklist() +< + Return type: list> or list + getmatches([{win}]) *getmatches()* Returns a |List| with all matches previously defined for the @@ -4043,6 +4467,9 @@ getmatches([{win}]) *getmatches()* 'pattern': 'FIXME', 'priority': 10, 'id': 2}] > :unlet m < + Return type: list> or list + + 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 @@ -4073,21 +4500,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 + + 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 @@ -4098,23 +4559,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 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 + getqflist([{what}]) *getqflist()* Returns a |List| with all the current quickfix errors. Each @@ -4219,6 +4688,9 @@ getqflist([{what}]) *getqflist()* :echo getqflist({'nr': 2, 'title': 1}) :echo getqflist({'lines' : ["F1:10:L10"]}) < + Return type: list> or list + + getreg([{regname} [, 1 [, {list}]]]) *getreg()* The result is a String, which is the contents of register {regname}. Example: > @@ -4246,6 +4718,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 @@ -4275,6 +4750,9 @@ getreginfo([{regname}]) *getreginfo()* Can also be used as a |method|: > GetRegname()->getreginfo() +< + Return type: dict + getregion({pos1}, {pos2} [, {opts}]) *getregion()* Returns the list of strings from {pos1} to {pos2} from a @@ -4288,14 +4766,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 - "" 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()|. @@ -4321,14 +4799,55 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()* difference if the buffer is displayed in a window with different 'virtualedit' or 'list' values. - Examples: > - :xnoremap - \ echow getregion( - \ getpos('v'), getpos('.'), #{ type: mode() }) -< + Examples: > + :xnoremap + \ echow getregion( + \ getpos('v'), getpos('.'), #{ type: mode() }) +< + Can also be used as a |method|: > + getpos('.')->getregion(getpos("'a")) +< + Return type: list + +< +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 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('.')->getregion(getpos("'a")) + getpos('.')->getregionpos(getpos("'a")) < + Return type: list>> + + getregtype([{regname}]) *getregtype()* The result is a String, which is type of register {regname}. The value will be one of: @@ -4344,6 +4863,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 @@ -4384,8 +4905,11 @@ getscriptinfo([{opts}]) *getscriptinfo()* Examples: > :echo getscriptinfo({'name': 'myscript'}) - :echo getscriptinfo({'sid': 15}).variables + :echo getscriptinfo({'sid': 15})[0].variables < + Return type: list> + + 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 @@ -4401,6 +4925,9 @@ gettabinfo([{tabnr}]) *gettabinfo()* Can also be used as a |method|: > GetTabnr()->gettabinfo() +< + Return type: list> + gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()* Get the value of a tab-local variable {varname} in tab page @@ -4414,6 +4941,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 @@ -4443,6 +4973,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}. @@ -4474,18 +5007,26 @@ gettagstack([{winnr}]) *gettagstack()* Can also be used as a |method|: > GetWinnr()->gettagstack() +< + Return type: dict -gettext({text}) *gettext()* +gettext({text} [, {package}]) *gettext()* Translate String {text} if possible. - This is mainly for use in the distributed Vim scripts. When - generating message translations the {text} is extracted by - xgettext, the translator can add the translated message in the - .po file and Vim will lookup the translation when gettext() is - called. + This is intended for use in Vim scripts. When generating + message translations the {text} is extracted by `xgettext`, + the translator can add translated messages into the .po file + and Vim will lookup the translation when gettext() is called. For {text} double quoted strings are preferred, because - xgettext does not understand escaping in single quoted - strings. + `xgettext` does not support single quoted escaped text. + + When the {package} is specified, the translation is looked up + for that specific package. This is mainly required for + third-party Vim scripts. You need to specify a path to the + translations with the |bindtextdomain()| function before + using the gettext() function. + + Return type: |String| getwininfo([{winid}]) *getwininfo()* @@ -4527,6 +5068,9 @@ getwininfo([{winid}]) *getwininfo()* Can also be used as a |method|: > GetWinnr()->getwininfo() +< + Return type: list> + getwinpos([{timeout}]) *getwinpos()* The result is a |List| with two numbers, the result of @@ -4551,22 +5095,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 + + +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: > @@ -4576,6 +5129,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. @@ -4614,6 +5170,10 @@ glob({expr} [, {nosuf} [, {list} [, {alllinks}]]]) *glob()* Can also be used as a |method|: > GetExpr()->glob() +< + Return type: |String| or list or list depending + on {list} + glob2regpat({string}) *glob2regpat()* Convert a file pattern, as used by glob(), into a search @@ -4629,7 +5189,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: > @@ -4669,8 +5232,11 @@ globpath({path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]]) second argument: > GetExpr()->globpath(&rtp) < - *has()* -has({feature} [, {check}]) + Return type: |String| or list or list 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 @@ -4696,6 +5262,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} @@ -4707,6 +5275,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: @@ -4744,6 +5315,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 @@ -4778,6 +5352,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 @@ -4803,6 +5380,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| @@ -4838,6 +5418,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 @@ -4856,6 +5439,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}. @@ -4868,6 +5454,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 @@ -4880,6 +5468,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 @@ -4931,6 +5522,9 @@ hlget([{name} [, {resolve}]]) *hlget()* Can also be used as a |method|: > GetName()->hlget() < + Return type: list> + + hlset({list}) *hlset()* Creates or modifies the attributes of a List of highlight groups. Each item in {list} is a dictionary containing the @@ -4982,8 +5576,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 @@ -4995,12 +5591,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}. @@ -5023,8 +5625,39 @@ 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| + + +id({item}) *id()* + The result is a unique String associated with the {item} and + not with the {item}'s contents. It is only valid while the + {item} exists and is referenced. It is valid only in the + instance of vim that produces the result. The whole idea is + that `id({item})` does not change if the contents of {item} + changes. This is useful as a `key` for creating an identity + dictionary, rather than one based on equals. + + This operation does not reference {item} and there is no + function to convert the `id` to the {item}. It may be useful to + have a map of `id` to {item}. The following > + var referenceMap: dict + var id = item->id() + referenceMap[id] = item +< prevents {item} from being garbage collected and provides a + way to get the {item} from the `id`. + + {item} may be a List, Dictionary, Object, Job, Channel or + Blob. If the item is not a permitted type, or it is a null + value, then an empty String is returned. + + Can also be used as a |method|: > + GetItem()->id() +< + 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()|. @@ -5033,6 +5666,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 @@ -5061,6 +5697,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 @@ -5102,6 +5741,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 @@ -5150,6 +5792,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 @@ -5167,6 +5812,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 @@ -5187,6 +5835,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()|. @@ -5194,6 +5845,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 @@ -5202,6 +5856,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: @@ -5215,6 +5872,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 @@ -5236,6 +5896,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} @@ -5248,6 +5911,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 @@ -5261,6 +5926,8 @@ interrupt() *interrupt()* : endif :endfunction :au BufWritePre * call s:check_typoname(expand('')) +< + Return type: void invert({expr}) *invert()* Bitwise invert. The argument is converted to a number. A @@ -5268,6 +5935,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 @@ -5285,6 +5955,8 @@ isabsolutepath({path}) *isabsolutepath()* < Can also be used as a |method|: > GetName()->isabsolutepath() +< + Return type: |Number| isdirectory({directory}) *isdirectory()* @@ -5295,6 +5967,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 @@ -5306,6 +5981,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 @@ -5326,6 +6004,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. > @@ -5334,6 +6015,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 @@ -5351,6 +6035,9 @@ items({dict}) *items()* Can also be used as a |method|: > mydict->items() +< + Return type: list> or list + job_ functions are documented here: |job-functions-details| @@ -5368,6 +6055,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: @@ -5378,6 +6068,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: @@ -5395,6 +6088,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 @@ -5431,6 +6127,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. @@ -5461,6 +6160,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 @@ -5468,6 +6170,9 @@ keys({dict}) *keys()* Can also be used as a |method|: > mydict->keys() +< + Return type: list + keytrans({string}) *keytrans()* Turn the internal byte representation of keys into a form that @@ -5478,9 +6183,12 @@ keytrans({string}) *keytrans()* Can also be used as a |method|: > "\"->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 @@ -5494,8 +6202,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}. @@ -5560,30 +6271,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" @@ -5595,6 +6298,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 @@ -5612,6 +6318,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 @@ -5623,6 +6332,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}. @@ -5636,10 +6348,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: > @@ -5655,6 +6370,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 @@ -5731,6 +6449,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 @@ -5742,6 +6463,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(). @@ -5750,11 +6474,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|. @@ -5769,6 +6498,8 @@ log({expr}) *log()* Can also be used as a |method|: > Compute()->log() +< + Return type: |Float| log10({expr}) *log10()* @@ -5783,6 +6514,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 @@ -5800,8 +6534,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|. @@ -5864,6 +6601,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()* @@ -5940,6 +6680,9 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()* < Can also be used as a |method|: > GetKey()->maparg('n') +< + Return type: |String| or dict depending on {dict} + mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()* Check if there is a mapping that matches with {name} in mode @@ -5976,6 +6719,8 @@ mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()* Can also be used as a |method|: > GetKey()->mapcheck('n') +< + Return type: |String| maplist([{abbr}]) *maplist()* @@ -6010,6 +6755,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> mapnew({expr1}, {expr2}) *mapnew()* @@ -6018,6 +6765,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}) @@ -6056,6 +6806,8 @@ mapset({dict}) for d in save_maps mapset(d) endfor +< + Return type: |Number| match({expr}, {pat} [, {start} [, {count}]]) *match()* @@ -6125,6 +6877,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 @@ -6187,14 +6942,17 @@ 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} instead of a pattern. This command is faster than |matchadd()| - because it does not require to handle regular expressions and - sets buffer line boundaries to redraw screen. It is supposed - to be used when fast match additions and deletions are - required, for example to highlight matching parentheses. + because it does not handle regular expressions and it sets + buffer line boundaries to redraw screen. It is supposed to be + used when fast match additions and deletions are required, for + example to highlight matching parentheses. {pos} is a list of positions. Each position can be one of these: @@ -6223,6 +6981,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|, @@ -6239,6 +7000,8 @@ matcharg({nr}) *matcharg()* Can also be used as a |method|: > GetMatch()->matcharg() < + Return type: list + *matchbufline()* matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}]) Returns the |List| of matches in lines from {lnum} to {end} in @@ -6286,6 +7049,9 @@ matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}]) Can also be used as a |method|: > GetBuffer()->matchbufline('mypat', 1, '$') +< + Return type: list> or list + matchdelete({id} [, {win}) *matchdelete()* *E802* *E803* Deletes a match with ID {id} previously defined by |matchadd()| @@ -6297,6 +7063,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 @@ -6319,6 +7088,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()* @@ -6384,6 +7155,9 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* \ {'matchseq': 1}) < results in ['two one']. + Return type: list or list + + matchfuzzypos({list}, {str} [, {dict}]) *matchfuzzypos()* Same as |matchfuzzy()|, but returns the list of matched strings, the list of character positions where characters @@ -6405,6 +7179,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> + + 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 @@ -6420,6 +7197,8 @@ matchlist({expr}, {pat} [, {start} [, {count}]]) *matchlist()* Can also be used as a |method|: > GetText()->matchlist('word') < + Return type: list or list + *matchstrlist()* matchstrlist({list}, {pat} [, {dict}]) Returns the |List| of matches in {list} where {pat} matches. @@ -6456,6 +7235,9 @@ matchstrlist({list}, {pat} [, {dict}]) Can also be used as a |method|: > GetListOfStrings()->matchstrlist('mypat') +< + Return type: list> or list + matchstr({expr}, {pat} [, {start} [, {count}]]) *matchstr()* Same as |match()|, but return the matched string. Example: > @@ -6472,6 +7254,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 @@ -6494,9 +7279,11 @@ matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()* Can also be used as a |method|: > GetText()->matchstrpos('word') < + Return type: list - *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, @@ -6507,6 +7294,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()* @@ -6581,10 +7370,11 @@ menu_info({name} [, {mode}]) *menu_info()* < Can also be used as a |method|: > GetMenuName()->menu_info('v') +< + Return type: dict - -< *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, @@ -6595,25 +7385,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: > @@ -6649,8 +7438,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. @@ -6706,6 +7498,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 @@ -6728,8 +7523,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: > @@ -6741,6 +7539,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 @@ -6762,6 +7563,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 @@ -6777,6 +7581,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 @@ -6794,6 +7600,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 @@ -6810,8 +7619,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| @@ -6831,6 +7642,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} @@ -6843,6 +7657,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 @@ -7169,6 +7986,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 @@ -7179,8 +7998,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()* @@ -7231,8 +8052,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 @@ -7243,8 +8066,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| @@ -7262,12 +8087,18 @@ pum_getpos() *pum_getpos()* The values are the same as in |v:event| during |CompleteChanged|. + Return type: dict + + 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. @@ -7282,8 +8113,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()* @@ -7299,8 +8132,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 @@ -7309,9 +8144,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* @@ -7329,6 +8166,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()* @@ -7352,6 +8190,8 @@ range({expr} [, {max} [, {stride}]]) *range()* Can also be used as a |method|: > GetExpr()->range() < + Return type: list + readblob({fname} [, {offset} [, {size}]]) *readblob()* Read file {fname} in binary mode and return a |Blob|. @@ -7377,6 +8217,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}. @@ -7434,6 +8276,9 @@ readdir({directory} [, {expr} [, {dict}]]) *readdir()* Can also be used as a |method|: > GetDirName()->readdir() < + Return type: list or list + + readdirex({directory} [, {expr} [, {dict}]]) *readdirex()* Extended version of |readdir()|. Return a list of Dictionaries with file and directory @@ -7493,6 +8338,8 @@ readdirex({directory} [, {expr} [, {dict}]]) *readdirex()* Can also be used as a |method|: > GetDirName()->readdirex() < + Return type: list> or list + *readfile()* readfile({fname} [, {type} [, {max}]]) @@ -7531,6 +8378,8 @@ readfile({fname} [, {type} [, {max}]]) Can also be used as a |method|: > GetFileName()->readfile() +< + Return type: list or list reduce({object}, {func} [, {initial}]) *reduce()* *E998* {func} is called for every item in {object}, which can be a @@ -7551,6 +8400,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()* @@ -7558,13 +8410,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 can be used. @@ -7590,8 +8448,11 @@ reltime({start}, {end}) *reltime()* Can also be used as a |method|: > GetStart()->reltime() < + Return type: list + {only available when compiled with the |+reltime| feature} + reltimefloat({time}) *reltimefloat()* Return a Float that represents the time value of {time}. Example: > @@ -7605,8 +8466,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}. @@ -7627,8 +8491,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}]]) @@ -7665,6 +8531,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. @@ -7680,8 +8549,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} @@ -7701,6 +8572,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 @@ -7716,8 +8590,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}|. @@ -7747,19 +8623,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 @@ -7776,6 +8657,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}) @@ -7789,6 +8673,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. @@ -7797,6 +8683,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 @@ -7807,6 +8696,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 @@ -7820,6 +8712,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), @@ -7839,6 +8735,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 @@ -7851,6 +8750,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 @@ -7868,6 +8771,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 @@ -7883,8 +8789,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 @@ -7894,6 +8802,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 @@ -7907,6 +8818,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 @@ -7917,6 +8831,9 @@ screenchars({row}, {col}) *screenchars()* Can also be used as a |method|: > GetRow()->screenchars(col) +< + Return type: list or list + screencol() *screencol()* The result is a Number, which is the current screen column of @@ -7932,6 +8849,9 @@ screencol() *screencol()* nnoremap GG :echom screencol() nnoremap GG echom screencol() < + 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 @@ -7958,6 +8878,9 @@ screenpos({winid}, {lnum}, {col}) *screenpos()* Can also be used as a |method|: > GetWinid()->screenpos(lnum, col) +< + Return type: dict or dict + screenrow() *screenrow()* The result is a Number, which is the current screen row of the @@ -7967,6 +8890,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. @@ -7978,6 +8904,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 @@ -8084,6 +9012,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 @@ -8210,6 +9141,9 @@ searchcount([{options}]) *searchcount()* Can also be used as a |method|: > GetSearchOpts()->searchcount() < + Return type: dict + + searchdecl({name} [, {global} [, {thisblock}]]) *searchdecl()* Search for the declaration of {name}. @@ -8231,6 +9165,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}]]]]) @@ -8319,6 +9255,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}]]]]) @@ -8332,6 +9270,8 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} < See |match-parens| for a bigger and more useful example. + Return type: list + *searchpos()* searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]]) Same as |search()|, but returns a |List| with the line and @@ -8350,6 +9290,9 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]]) Can also be used as a |method|: > GetPattern()->searchpos() +< + Return type: list + server2client({clientid}, {string}) *server2client()* Send a reply string to {clientid}. The most recent {clientid} @@ -8367,6 +9310,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 @@ -8375,6 +9321,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. @@ -8405,6 +9354,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 @@ -8423,6 +9375,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()* @@ -8459,6 +9413,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 @@ -8473,6 +9429,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}, @@ -8496,6 +9455,9 @@ setcharsearch({dict}) *setcharsearch()* Can also be used as a |method|: > SavedSearch()->setcharsearch() +< + Return type: dict + setcmdline({str} [, {pos}]) *setcmdline()* Set the command line to {str} and set the cursor position to @@ -8506,6 +9468,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 @@ -8524,6 +9489,9 @@ setcmdpos({pos}) *setcmdpos()* Can also be used as a |method|: > GetPos()->setcmdpos() +< + Return type: |Number| + setcursorcharpos({lnum}, {col} [, {off}]) *setcursorcharpos()* setcursorcharpos({list}) @@ -8539,6 +9507,8 @@ setcursorcharpos({list}) Can also be used as a |method|: > GetCursorPos()->setcursorcharpos() +< + Return type: |Number| setenv({name}, {val}) *setenv()* @@ -8551,6 +9521,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}. @@ -8572,11 +9545,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 @@ -8605,6 +9581,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}. @@ -8625,6 +9604,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 @@ -8637,8 +9619,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 @@ -8689,6 +9673,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. @@ -8807,8 +9794,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| @@ -8866,6 +9855,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}. @@ -8880,6 +9872,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 @@ -8902,6 +9897,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}. @@ -8939,6 +9937,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. @@ -8949,6 +9950,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 @@ -8956,8 +9960,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. @@ -8971,11 +9977,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 "" 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 "" (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 @@ -8999,6 +10006,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 @@ -9014,6 +10024,8 @@ shiftwidth([{col}]) *shiftwidth()* Can also be used as a |method|: > GetColumn()->shiftwidth() +< + Return type: |Number| showdefinition({string} [, {options}]) *showdefinition()* Opens a macOS popup window showing the definition of {string} @@ -9059,6 +10071,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|. @@ -9072,6 +10087,8 @@ sin({expr}) *sin()* Can also be used as a |method|: > Compute()->sin() +< + Return type: |Float| sinh({expr}) *sinh()* @@ -9087,6 +10104,8 @@ sinh({expr}) *sinh()* Can also be used as a |method|: > Compute()->sinh() +< + Return type: |Float| slice({expr}, {start} [, {end}]) *slice()* @@ -9101,6 +10120,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* @@ -9180,12 +10201,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()* @@ -9221,8 +10247,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}]) @@ -9233,8 +10261,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()* @@ -9249,8 +10279,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}) @@ -9264,8 +10296,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 @@ -9292,8 +10326,10 @@ spellbadword([{sentence}]) Can also be used as a |method|: > GetText()->spellbadword() < - *spellsuggest()* -spellsuggest({word} [, {max} [, {capital}]]) + Return type: list + + +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. @@ -9316,11 +10352,14 @@ spellsuggest({word} [, {max} [, {capital}]]) Can also be used as a |method|: > GetWord()->spellsuggest() +< + Return type: list or list + split({string} [, {pattern} [, {keepempty}]]) *split()* Make a |List| out of {string}. When {pattern} is omitted or - empty each white-separated sequence of characters becomes an - item. + empty each white space separated sequence of characters + becomes an item. Otherwise the string is split where {pattern} matches, removing the matched characters. 'ignorecase' is not used here, add \c to ignore case. |/\c| @@ -9342,6 +10381,8 @@ split({string} [, {pattern} [, {keepempty}]]) *split()* Can also be used as a |method|: > GetString()->split() +< + Return type: list sqrt({expr}) *sqrt()* Return the non-negative square root of Float {expr} as a @@ -9358,6 +10399,8 @@ sqrt({expr}) *sqrt()* Can also be used as a |method|: > Compute()->sqrt() +< + Return type: |Float| srand([{expr}]) *srand()* @@ -9373,6 +10416,9 @@ srand([{expr}]) *srand()* :let seed = srand() :let seed = srand(userinput) :echo rand(seed) +< + Return type: list + state([{what}]) *state()* Return a string which contains characters indicating the @@ -9410,6 +10456,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, @@ -9431,6 +10480,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 @@ -9447,6 +10499,8 @@ str2list({string} [, {utf8}]) *str2list()* < Can also be used as a |method|: > GetString()->str2list() +< + Return type: list str2nr({string} [, {base} [, {quoted}]]) *str2nr()* @@ -9470,6 +10524,8 @@ str2nr({string} [, {base} [, {quoted}]]) *str2nr()* Can also be used as a |method|: > GetText()->str2nr() +< + Return type: |Number| strcharlen({string}) *strcharlen()* @@ -9484,6 +10540,8 @@ strcharlen({string}) *strcharlen()* Can also be used as a |method|: > GetText()->strcharlen() +< + Return type: |Number| strcharpart({src}, {start} [, {len} [, {skipcc}]]) *strcharpart()* @@ -9503,6 +10561,8 @@ strcharpart({src}, {start} [, {len} [, {skipcc}]]) *strcharpart()* Can also be used as a |method|: > GetText()->strcharpart(5) +< + Return type: |String| strchars({string} [, {skipcc}]) *strchars()* @@ -9535,6 +10595,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 @@ -9552,6 +10615,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 @@ -9574,6 +10640,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 @@ -9586,6 +10655,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 @@ -9609,8 +10681,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 ~ @@ -9639,6 +10714,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 @@ -9651,6 +10728,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 @@ -9679,6 +10759,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 @@ -9709,6 +10792,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 @@ -9730,6 +10816,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 @@ -9743,6 +10832,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 @@ -9766,6 +10858,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 @@ -9777,6 +10872,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 @@ -9808,6 +10906,9 @@ submatch({nr} [, {list}]) *submatch()* *E935* Can also be used as a |method|: > GetNr()->submatch() +< + Return type: |String| or list depending on {list} + substitute({string}, {pat}, {sub}, {flags}) *substitute()* The result is a String, which is a copy of {string}, in which @@ -9854,6 +10955,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. @@ -9865,6 +10969,9 @@ swapfilelist() *swapfilelist()* let &directory = '.' let swapfiles = swapfilelist() let &directory = save_dir +< + Return type: list + swapinfo({fname}) *swapinfo()* The result is a dictionary, which holds information about the @@ -9887,6 +10994,9 @@ swapinfo({fname}) *swapinfo()* Can also be used as a |method|: > GetFilename()->swapinfo() +< + Return type: dict or dict + swapname({buf}) *swapname()* The result is the swap file path of the buffer {expr}. @@ -9897,6 +11007,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 @@ -9923,6 +11036,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 @@ -9966,6 +11081,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()* @@ -9978,6 +11095,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: @@ -10004,6 +11124,12 @@ synconcealed({lnum}, {col}) *synconcealed()* synconcealed(lnum, 5) [1, 'X', 2] synconcealed(lnum, 6) [0, '', 0] + Note: Doesn't consider |matchadd()| highlighting items, + since syntax and matching highlighting are two different + mechanisms |syntax-vs-match|. +< + Return type: list + synstack({lnum}, {col}) *synstack()* Return a |List|, which is the stack of syntax items at the @@ -10024,6 +11150,9 @@ synstack({lnum}, {col}) *synstack()* character in a line and the first column in an empty line are valid positions. + Return type: list or list + + 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|. @@ -10086,6 +11215,8 @@ system({expr} [, {input}]) *system()* *E677* Can also be used as a |method|: > :echo GetCmd()->system() +< + Return type: |String| systemlist({expr} [, {input}]) *systemlist()* @@ -10104,6 +11235,8 @@ systemlist({expr} [, {input}]) *systemlist()* Can also be used as a |method|: > :echo GetCmd()->systemlist() +< + Return type: list tabpagebuflist([{arg}]) *tabpagebuflist()* @@ -10121,6 +11254,9 @@ tabpagebuflist([{arg}]) *tabpagebuflist()* Can also be used as a |method|: > GetTabpage()->tabpagebuflist() +< + Return type: list + tabpagenr([{arg}]) *tabpagenr()* The result is a Number, which is the number of the current @@ -10136,6 +11272,8 @@ tabpagenr([{arg}]) *tabpagenr()* Returns zero on error. + Return type: |Number| + tabpagewinnr({tabarg} [, {arg}]) *tabpagewinnr()* Like |winnr()| but for tab page {tabarg}. @@ -10153,10 +11291,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 or list + taglist({expr} [, {filename}]) *taglist()* Returns a |List| of tags matching the regular expression {expr}. @@ -10203,6 +11346,9 @@ taglist({expr} [, {filename}]) *taglist()* Can also be used as a |method|: > GetTagpattern()->taglist() +< + Return type: list> or list + tan({expr}) *tan()* Return the tangent of {expr}, measured in radians, as a |Float| @@ -10217,6 +11363,8 @@ tan({expr}) *tan()* Can also be used as a |method|: > Compute()->tan() +< + Return type: |Float| tanh({expr}) *tanh()* @@ -10232,6 +11380,8 @@ tanh({expr}) *tanh()* Can also be used as a |method|: > Compute()->tanh() +< + Return type: |Float| tempname() *tempname()* *temp-file-name* @@ -10240,11 +11390,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| @@ -10283,6 +11437,8 @@ terminalprops() *terminalprops()* - |v:termstyleresp| and |v:termblinkresp| for the response to |t_RS| and |t_RC|. + Return type: dict + test_ functions are documented here: |test-functions-details| @@ -10307,8 +11463,11 @@ timer_info([{id}]) Can also be used as a |method|: > GetTimer()->timer_info() +< + Return type: list> or list + + {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 @@ -10325,8 +11484,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}]) @@ -10369,8 +11531,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 @@ -10378,16 +11544,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 @@ -10395,6 +11567,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 @@ -10403,6 +11578,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 @@ -10422,6 +11600,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 @@ -10453,6 +11634,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 @@ -10470,6 +11654,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 @@ -10504,6 +11691,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()* @@ -10512,6 +11701,8 @@ typename({expr}) *typename()* echo typename([1, 2, 3]) < list ~ + Return type: |String| + undofile({name}) *undofile()* Return the name of the undo file that would be used for a file @@ -10528,6 +11719,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 @@ -10573,6 +11767,9 @@ undotree([{buf}]) *undotree()* blocks. Each item may again have an "alt" item. + Return type: dict + + 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 @@ -10586,6 +11783,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 @@ -10616,6 +11816,8 @@ utf16idx({string}, {idx} [, {countcc} [, {charidx}]]) < Can also be used as a |method|: > GetName()->utf16idx(idx) +< + Return type: |Number| values({dict}) *values()* @@ -10625,6 +11827,9 @@ values({dict}) *values()* Can also be used as a |method|: > mydict->values() +< + Return type: list + virtcol({expr} [, {list} [, {winid}]]) *virtcol()* The result is a Number, which is the screen column of the file @@ -10636,7 +11841,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 @@ -10646,18 +11853,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. @@ -10666,6 +11861,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": @@ -10676,13 +11872,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 @@ -10708,6 +11909,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 @@ -10727,6 +11931,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'. @@ -10738,6 +11945,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, @@ -10756,6 +11966,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 @@ -10763,6 +11976,9 @@ win_findbuf({bufnr}) *win_findbuf()* Can also be used as a |method|: > GetBufnr()->win_findbuf() +< + Return type: list or list + win_getid([{win} [, {tab}]]) *win_getid()* Get the |window-ID| for the specified window. @@ -10775,6 +11991,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()* @@ -10800,6 +12018,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. @@ -10807,6 +12028,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 @@ -10815,6 +12039,9 @@ win_id2tabwin({expr}) *win_id2tabwin()* Can also be used as a |method|: > GetWinid()->win_id2tabwin() +< + Return type: list + win_id2win({expr}) *win_id2win()* Return the window number of window with ID {expr}. @@ -10822,6 +12049,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) @@ -10840,6 +12070,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 @@ -10855,6 +12088,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 @@ -10867,6 +12103,9 @@ win_screenpos({nr}) *win_screenpos()* Can also be used as a |method|: > GetWinid()->win_screenpos() < + Return type: list + + win_splitmove({nr}, {target} [, {options}]) *win_splitmove()* Temporarily switch to window {target}, then move window {nr} to a new split adjacent to {target}. @@ -10890,6 +12129,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 @@ -10904,11 +12145,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 @@ -10916,6 +12163,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|. @@ -10929,6 +12178,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. @@ -10962,15 +12214,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 + + +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. @@ -11003,8 +12261,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. @@ -11013,8 +12274,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 @@ -11033,8 +12296,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 @@ -11060,6 +12326,8 @@ winsaveview() Returns a |Dictionary| that contains information to restore skipcol columns skipped Note that no option values are saved. + Return type: dict + winwidth({nr}) *winwidth()* The result is a Number, which is the width of window {nr}. @@ -11077,6 +12345,8 @@ winwidth({nr}) *winwidth()* Can also be used as a |method|: > GetWinid()->winwidth() +< + Return type: |Number| wordcount() *wordcount()* @@ -11100,9 +12370,10 @@ wordcount() *wordcount()* visual_words Number of words visually selected (only in Visual mode) + Return type: dict - *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. @@ -11150,6 +12421,8 @@ writefile({object}, {fname} [, {flags}]) < Can also be used as a |method|: > GetText()->writefile("thefile") +< + Return type: |Number| xor({expr}, {expr}) *xor()* @@ -11162,6 +12435,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 fad389b2ff..a28f07f2a4 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 Jul 14 VIM REFERENCE MANUAL by Bram Moolenaar @@ -95,13 +95,14 @@ For inserting text see |insert.txt|. These commands delete text. You can repeat them with the `.` command (except `:d`) and undo them. Use Visual mode to delete blocks of text. See |registers| for an explanation of registers. - + *d-special* An exception for the d{motion} command: If the motion is not linewise, the start and end of the motion are not in the same line, and there are only blanks before the start and there are no non-blanks after the end of the motion, the delete becomes linewise. This means that the delete also removes the line of blanks that you might expect to remain. Use the |o_v| operator to -force the motion to be characterwise. +force the motion to be characterwise or remove the "z" flag from 'cpoptions' +(see |cpo-z|) to disable this peculiarity. Trying to delete an empty region of text (e.g., "d0" in the first column) is an error when 'cpoptions' includes the 'E' flag. @@ -251,7 +252,7 @@ blank; this is probably a bug, because "dw" deletes all the blanks; use the If you prefer "cw" to include the space after a word, use this mapping: > :map cw dwi -Or use "caw" (see |aw|). +Alternatively use "caw" (see also |aw| and |cpo-z|). *:c* *:ch* *:change* :{range}c[hange][!] Replace lines of text with some different text. @@ -623,7 +624,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 @@ -1271,13 +1273,13 @@ Vim fills these registers with text from yank and delete commands. Numbered register 0 contains the text from the most recent yank command, unless the command specified another register with ["x]. Numbered register 1 contains the text deleted by the most recent delete or -change command, unless the command specified another register or the text is -less than one line (the small delete register is used then). An exception is -made for the delete operator with these movement commands: |%|, |(|, |)|, |`|, -|/|, |?|, |n|, |N|, |{| and |}|. Register "1 is always used then (this is Vi -compatible). The "- register is used as well if the delete is within a line. -Note that these characters may be mapped. E.g. |%| is mapped by the matchit -plugin. +change command (even when the command specified another register), unless the +text is less than one line (the small delete register is used then). An +exception is made for the delete operator with these movement commands: |%|, +|(|, |)|, |`|, |/|, |?|, |n|, |N|, |{| and |}|. +Register "1 is always used then (this is Vi compatible). The "- register is +used as well if the delete is within a line. Note that these characters may be +mapped. E.g. |%| is mapped by the matchit plugin. With each successive deletion or change, Vim shifts the previous contents of register 1 into register 2, 2 into 3, and so forth, losing the previous contents of register 9. @@ -1346,7 +1348,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 characters. If the String ends in a , it is regarded as a linewise @@ -1412,6 +1414,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 d625a01b24..c1fae51466 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 Jul 17 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 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 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 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 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 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 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 or list 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()* @@ -948,8 +981,9 @@ job_start({command} [, {options}]) *job_start()* invoked. {command} can be a String. This works best on MS-Windows. On - Unix it is split up in white-separated parts to be passed to - execvp(). Arguments in double quotes can contain white space. + Unix it is split up in white space separated parts to be + passed to execvp(). Arguments in double quotes can contain + white space. {command} can be a List, where the first item is the executable and further items are the arguments. All items are converted @@ -997,6 +1031,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 +1056,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 +1104,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 13c4d729b7..214571f289 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -1,4 +1,4 @@ -*cmdline.txt* For Vim version 9.1. Last change: 2023 Dec 09 +*cmdline.txt* For Vim version 9.1. Last change: 2024 Apr 27 VIM REFERENCE MANUAL by Bram Moolenaar @@ -650,6 +650,12 @@ followed by another Vim command: :[range]! a user defined command without the "-bar" argument |:command| + and the following |Vim9-script| keywords: + :abstract + :class + :enum + :interface + Note that this is confusing (inherited from Vi): With ":g" the '|' is included in the command, with ":s" it is not. diff --git a/runtime/doc/debug.txt b/runtime/doc/debug.txt index 1d3090af8f..4963fdd030 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 1b1ad85616..678a924611 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/editing.txt b/runtime/doc/editing.txt index ca8f0aee85..4d477cff81 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1,4 +1,4 @@ -*editing.txt* For Vim version 9.1. Last change: 2024 Apr 12 +*editing.txt* For Vim version 9.1. Last change: 2024 Jul 10 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1804,7 +1804,7 @@ There are three different types of searching: stop-directories are appended to the path (for the 'path' option) or to the filename (for the 'tags' option) with a ';'. If you want several stop-directories separate them with ';'. If you want no stop-directory - ("search upward till the root directory) just use ';'. > + ("search upward till the root directory") just use ';'. > /usr/include/sys;/usr < will search in: > /usr/include/sys @@ -1817,7 +1817,7 @@ There are three different types of searching: If Vim's current path is /u/user_x/work/release and you do > :set path=include;/u/user_x -< and then search for a file with |gf| the file is searched in: > +< and then search for a file with |gf| the file is searched in: > /u/user_x/work/release/include /u/user_x/work/include /u/user_x/include @@ -1829,7 +1829,7 @@ There are three different types of searching: 3) Combined up/downward search: If Vim's current path is /u/user_x/work/release and you do > set path=**;/u/user_x -< and then search for a file with |gf| the file is searched in: > +< and then search for a file with |gf| the file is searched in: > /u/user_x/work/release/** /u/user_x/work/** /u/user_x/** @@ -1841,10 +1841,10 @@ There are three different types of searching: In the above example you might want to set path to: > :set path=**,/u/user_x/** -< This searches: - /u/user_x/work/release/** ~ - /u/user_x/** ~ - This searches the same directories, but in a different order. +< This searches: > + /u/user_x/work/release/** + /u/user_x/** +< This searches the same directories, but in a different order. Note that completion for ":find", ":sfind", and ":tabfind" commands do not currently work with 'path' items that contain a URL or use the double star diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 92a116e52e..bf75a02388 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 Jul 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1995,7 +1995,8 @@ v:beval_winid The |window-ID| of the window, over which the mouse pointer *v:char* *char-variable* v:char Argument for evaluating 'formatexpr' and used for the typed character when using in an abbreviation |:map-|. - It is also used by the |InsertCharPre| and |InsertEnter| events. + It is also used by the |InsertCharPre|, |InsertEnter| and + |KeyInputPre| events. *v:charconvert_from* *charconvert_from-variable* v:charconvert_from @@ -2739,7 +2740,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 @@ -3111,7 +3112,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} @@ -3135,9 +3136,10 @@ text... let lconst[0] = 2 " Error! let lconst[1][0] = 'b' " OK < *E995* - |:const| does not allow to for changing a variable: > + It is an error to specify an existing variable with + :const. > :let x = 1 - :const x = 2 " Error! + :const x = 1 " Error! < *E996* Note that environment variables, option values and register values cannot be used here, since they cannot diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index f13cfc60d1..6c706b1775 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 09 +*filetype.txt* For Vim version 9.1. Last change: 2024 Jul 16 VIM REFERENCE MANUAL by Bram Moolenaar @@ -149,6 +149,7 @@ variables can be used to overrule the filetype used for certain extensions: *.csh g:filetype_csh |ft-csh-syntax| *.dat g:filetype_dat *.def g:filetype_def + *.dsp g:filetype_dsp *.f g:filetype_f |ft-forth-syntax| *.frm g:filetype_frm |ft-form-syntax| *.fs g:filetype_fs |ft-forth-syntax| @@ -452,6 +453,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 @@ -610,6 +623,17 @@ any #lang directive overrides, use the following command: > let g:freebasic_lang = "fblite" +GDSCRIPT *ft-gdscript-plugin* + +By default the following options are set, based on Godot official docs: > + + setlocal noexpandtab softtabstop=0 shiftwidth=0 + +To disable this behavior, set the following variable in your vimrc: > + + let g:gdscript_recommended_style = 0 + + GIT COMMIT *ft-gitcommit-plugin* One command, :DiffGitCached, is provided to show a diff of the current commit @@ -617,6 +641,17 @@ in the preview window. It is equivalent to calling "git diff --cached" plus any arguments given to the command. +GO *ft-go-plugin* + +By default the following options are set, based on Golang official docs: > + + setlocal noexpandtab softtabstop=0 shiftwidth=0 + +To disable this behavior, set the following variable in your vimrc: > + + let g:go_recommended_style = 0 + + GPROF *ft-gprof-plugin* The gprof filetype plugin defines a mapping to jump from a function @@ -627,6 +662,43 @@ 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 +is a filename whose extension is either ".jar" or ".zip", e.g.: > + let g:ftplugin_java_source_path = '/path/to/src.jar' + let g:ftplugin_java_source_path = '/path/to/src.zip' +< +and the |zip| plugin has already been sourced, the |gf| command can be used to +open the archive and the |n| command can be used to look for the selected type +and the key can be used to load a listed file. + +Note that the effect of using the "gf" command WITHIN a buffer loaded with the +Zip plugin depends on the version of the Zip plugin. For the Zip plugin +versions that do not support Jar type archives, consider creating symbolic +links with the ".zip" extension for each Jar archive of interest and assigning +any such file to the variable from now on. + +Otherwise, for the defined variable "g:ftplugin_java_source_path", the local +value of the 'path' option will be further modified by prefixing the value of +the variable, e.g.: > + let g:ftplugin_java_source_path = $JDK_SRC_PATH + let &l:path = g:ftplugin_java_source_path . ',' . &l:path +< +and the "gf" command can be used on a fully-qualified type to look for a file +in the "path" and to try to load it. + +Remember to manually trigger the |FileType| event from a buffer with a Java +file loaded in it each time after assigning a new value to the variable: > + doautocmd FileType +< + JSON-FORMAT *ft-json-plugin* JSON filetype can be extended to use 'formatexpr' and "json.FormatExpr()" @@ -836,6 +908,10 @@ You can change the default by defining the variable g:tex_flavor to the format let g:tex_flavor = "latex" Currently no other formats are recognized. +TYPST *ft-typst-plugin* + + *g:typst_conceal* +When |TRUE| the Typst filetype plugin will set the 'conceallevel' option to 2. VIM *ft-vim-plugin* @@ -846,6 +922,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 0000000000..937c5e0961 --- /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 9d320954ec..abeaa835ca 100644 --- a/runtime/doc/gui.txt +++ b/runtime/doc/gui.txt @@ -1,4 +1,4 @@ -*gui.txt* For Vim version 9.1. Last change: 2023 Apr 29 +*gui.txt* For Vim version 9.1. Last change: 2024 Jul 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -71,6 +71,8 @@ When the GUI starts up initializations are carried out, in this order: - For Win32, $HOME is set by Vim if needed, see |$HOME-windows|. - When a "_gvimrc" file is not found, ".gvimrc" is tried too. And vice versa. + - On Unix, if "~/.config/vim/gvimrc" or "$XDG_CONFIG_HOME/vim/gvimrc" + exists, it is sourced. You can check this with ":version". The name of the first file found is stored in $MYGVIMRC, unless it was already set. - If the 'exrc' option is set (which is NOT the default) the file ./.gvimrc @@ -497,14 +499,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 ~ @@ -514,7 +516,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' @@ -973,7 +975,7 @@ name and all existing submenus below it are affected. 5.7 Examples for Menus *menu-examples* -Here is an example on how to add menu items with menu's! You can add a menu +Here is an example on how to add menu items with menus. You can add a menu item for the keyword under the cursor. The register "z" is used. > :nmenu Words.Add\ Var wb"zye:menu! Words.z z @@ -1270,7 +1272,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/gui_x11.txt b/runtime/doc/gui_x11.txt index 2b4e274e4a..2223b888b4 100644 --- a/runtime/doc/gui_x11.txt +++ b/runtime/doc/gui_x11.txt @@ -1,4 +1,4 @@ -*gui_x11.txt* For Vim version 9.1. Last change: 2024 Jan 30 +*gui_x11.txt* For Vim version 9.1. Last change: 2024 Apr 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -645,8 +645,8 @@ that version. For Motif, you need at least Motif version 1.2 and/or X11R5. Motif 2.0 and X11R6 are OK. Motif 1.1 and X11R4 might work, no guarantee (there may be a few problems, but you might make it compile and run with a bit of work, please -send me the patches if you do). The newest releases of LessTif have been -reported to work fine too. +send patches if you do). The newest releases of LessTif have been reported to +work fine too. *gui-x11-athena* *gui-x11-neXtaw* Support for the Athena GUI and neXtaw was removed in patch 8.2.4677. diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt index 343ea76059..179fb513d1 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 3fa8f817f4..bb4c6a18d5 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 8456d08c66..623684152b 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 fe24505ed1..2e57423fb0 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/index.txt b/runtime/doc/index.txt index 9a4eb4269c..019d1a5e60 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1,4 +1,4 @@ -*index.txt* For Vim version 9.1. Last change: 2023 Jan 09 +*index.txt* For Vim version 9.1. Last change: 2023 Jul 14 VIM REFERENCE MANUAL by Bram Moolenaar @@ -213,10 +213,12 @@ tag char note action in Normal mode ~ || 1 go to N newer entry in jump list |CTRL-I| CTRL-I 1 same as || 1 same as "j" +|| 1 same as CTRL-F |CTRL-J| CTRL-J 1 same as "j" CTRL-K not used |CTRL-L| CTRL-L redraw screen || 1 cursor to the first CHAR N lines lower +|| 1 same as CTRL-F |CTRL-M| CTRL-M 1 same as |CTRL-N| CTRL-N 1 same as "j" |CTRL-O| CTRL-O 1 go to N older entry in jump list @@ -287,9 +289,11 @@ tag char note action in Normal mode ~ |star| * 1 search forward for the Nth occurrence of the ident under the cursor |+| + 1 same as +|| 1 same as CTRL-F |,| , 1 repeat latest f, t, F or T in opposite direction N times |-| - 1 cursor to the first CHAR N lines higher +|| 1 same as CTRL-B |.| . 2 repeat last change with count replaced with N |/| /{pattern} 1 search forward for the Nth occurrence of @@ -753,7 +757,7 @@ tag char note action in Normal mode ~ search pattern and Visually select it |gP| ["x]gP 2 put the text [from register x] before the cursor N times, leave the cursor after it -|gQ| gQ switch to "Ex" mode with Vim editing +|gQ| gQ switch to "Ex" mode with Vim editing |gR| gR 2 enter Virtual Replace mode |gT| gT go to the previous tab page |gU| gU{motion} 2 make Nmove text uppercase diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index 6ebd83e3e7..0d59a2edab 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -1,4 +1,4 @@ -*insert.txt* For Vim version 9.1. Last change: 2024 Jan 04 +*insert.txt* For Vim version 9.1. Last change: 2024 Jul 13 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1995,13 +1995,25 @@ These two commands will keep on asking for lines, until you type a line containing only a ".". Watch out for lines starting with a backslash, see |line-continuation|. -When in Ex mode (see |-e|) a backslash at the end of the line can be used to -insert a NUL character. To be able to have a line ending in a backslash use -two backslashes. This means that the number of backslashes is halved, but -only at the end of the line. - -NOTE: These commands cannot be used with |:global| or |:vglobal|. -":append" and ":insert" don't work properly in between ":if" and +Text typed after a "|" command separator is used first. So the following +command in ex mode: > + :a|one + two + . + :visual + + one + two +< +In |Ex-mode|, when these commands are used with |:global| or |:vglobal| then +the lines are obtained from the text following the command. Separate lines +with a NL escaped with a backslash: > + :global/abc/insert\ + one line\ + another line +The final "." is not needed then. + +NOTE: ":append" and ":insert" don't work properly in between ":if" and ":endif", ":for" and ":endfor", ":while" and ":endwhile". *:start* *:startinsert* diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index 12297261c7..432a98671b 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 Jul 11 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 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: > @@ -1631,6 +1631,7 @@ completion can be enabled: -complete=compiler compilers -complete=cscope |:cscope| suboptions -complete=dir directory names + -complete=dir_in_path directory names in |'cdpath'| -complete=environment environment variable names -complete=event autocommand events -complete=expression Vim expression diff --git a/runtime/doc/mbyte.txt b/runtime/doc/mbyte.txt index 91154a7449..f02092b810 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 Jul 17 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 @@ -492,7 +493,7 @@ The GUI fully supports multibyte characters. It is also possible in a terminal, if the terminal supports the same encoding that Vim uses. Thus this is less flexible. -For example, you can run Vim in a xterm with added multibyte support and/or +For example, you can run Vim in an xterm with added multibyte support and/or |XIM|. Examples are kterm (Kanji term) and hanterm (for Korean), Eterm (Enlightened terminal) and rxvt. @@ -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. @@ -1378,7 +1379,7 @@ Motif. Use the ":hi Menu font={fontname}" command for this. |:highlight| TYPING UTF-8 *utf-8-typing* If you are using X-Windows, you should find an input method that supports -UTF-8. +the UTF-8 encoding. If your system does not provide support for typing UTF-8, you can use the 'keymap' feature. This allows writing a keymap file, which defines a UTF-8 diff --git a/runtime/doc/mlang.txt b/runtime/doc/mlang.txt index 82c9772a72..9a15bdfb56 100644 --- a/runtime/doc/mlang.txt +++ b/runtime/doc/mlang.txt @@ -1,4 +1,4 @@ -*mlang.txt* For Vim version 9.1. Last change: 2022 Sep 17 +*mlang.txt* For Vim version 9.1. Last change: 2024 Jul 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -59,7 +59,9 @@ use of "-" and "_". :lan[guage] tim[e] {name} :lan[guage] col[late] {name} Set the current language (aka locale) to {name}. - The locale {name} must be a valid locale on your + The POSIX format of {name} is: > + language[_territory][.encoding] +< The locale {name} must be a valid locale on your system. Some systems accept aliases like "en" or "en_US", but some only accept the full specification like "en_US.ISO_8859-1". On Unix systems you can use diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt index 8c07fbf53e..3e45884be9 100644 --- a/runtime/doc/motion.txt +++ b/runtime/doc/motion.txt @@ -1,4 +1,4 @@ -*motion.txt* For Vim version 9.1. Last change: 2023 Dec 27 +*motion.txt* For Vim version 9.1. Last change: 2024 Jul 14 VIM REFERENCE MANUAL by Bram Moolenaar @@ -351,6 +351,7 @@ gg Goto line [count], default first line, on the first *:[range]* :[range] Set the cursor on the last line number in [range]. + In Ex mode, print the lines in [range]. [range] can also be just one line number, e.g., ":1" or ":'m". In contrast with |G| this command does not modify the @@ -433,7 +434,7 @@ WORD before the fold. Special case: "cw" and "cW" are treated like "ce" and "cE" if the cursor is on a non-blank. This is because "cw" is interpreted as change-word, and a -word does not include the following white space. +word does not include the following white space (see also |cw|). Another special case: When using the "w" motion in combination with an operator and the last word moved over is at the end of a line, the end of diff --git a/runtime/doc/netbeans.txt b/runtime/doc/netbeans.txt index a62123ce64..ee227b4753 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 8e3417e18e..9af1740f4b 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 Jul 16 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1481,7 +1481,7 @@ A jump table for the options with a short description can be found at |Q_op|. applying 'breakindent', even if the resulting text should normally be narrower. This prevents text indented almost to the right window border - occupying lot of vertical space when broken. + occupying lots of vertical space when broken. (default: 20) shift:{n} After applying 'breakindent', the wrapped line's beginning will be shifted by the given number of @@ -1924,13 +1924,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| @@ -2115,7 +2116,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: @@ -2158,6 +2159,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 @@ -2263,8 +2272,9 @@ A jump table for the options with a short description can be found at |Q_op|. Also see 'preserveindent'. *'cpoptions'* *'cpo'* *cpo* -'cpoptions' 'cpo' string (Vim default: "aABceFs", - Vi default: all flags) +'cpoptions' 'cpo' string (Vim default: "aABceFsz", + Vi default: all flags, except "#{|&/\." + |$VIM_POSIX|: all flags) global A sequence of single character flags. When a character is present this indicates Vi-compatible behavior. This is used for things where @@ -2492,6 +2502,9 @@ A jump table for the options with a short description can be found at |Q_op|. *cpo-Z* Z When using "w!" while the 'readonly' option is set, don't reset 'readonly'. + *cpo-z* + z Special casing the "cw" and "d" command (see |cw| and + |d-special|). *cpo-!* ! When redoing a filter command, use the last used external command, whatever it was. Otherwise the last @@ -4360,12 +4373,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 @@ -4384,6 +4399,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 @@ -4424,6 +4440,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") @@ -4807,7 +4825,7 @@ A jump table for the options with a short description can be found at |Q_op|. in Insert mode as specified with the 'indentkeys' option. When this option is not empty, it overrules the 'cindent' and 'smartindent' indenting. When 'lisp' is set, this option is - is only used when 'lispoptions' contains "expr:1". + only used when 'lispoptions' contains "expr:1". When 'paste' is set this option is not used for indenting. The expression is evaluated with |v:lnum| set to the line number for which the indent is to be computed. The cursor is also in this line @@ -5170,7 +5188,7 @@ A jump table for the options with a short description can be found at |Q_op|. part can be in one of two forms: 1. A list of pairs. Each pair is a "from" character immediately followed by the "to" character. Examples: "aA", "aAbBcC". - 2. A list of "from" characters, a semi-colon and a list of "to" + 2. A list of "from" characters, a semicolon and a list of "to" characters. Example: "abc;ABC" Example: "aA,fgh;FGH,cCdDeE" Special characters need to be preceded with a backslash. These are @@ -5252,7 +5270,7 @@ A jump table for the options with a short description can be found at |Q_op|. update use |:redraw|. This may occasionally cause display errors. It is only meant to be set temporarily when performing an operation where redrawing may cause - flickering or cause a slow down. + flickering or cause a slowdown. *'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'* 'linebreak' 'lbr' boolean (default off) @@ -6030,6 +6048,20 @@ A jump table for the options with a short description can be found at |Q_op|. (without "unsigned" it would become "9-2019"). Using CTRL-X on "0" or CTRL-A on "18446744073709551615" (2^64 - 1) has no effect, overflow is prevented. + blank If included, treat numbers as signed or unsigned based on + preceding whitespace. If a number with a leading dash has its + dash immediately preceded by a non-whitespace character (i.e., + not a tab or a " "), the negative sign won't be considered as + part of the number. For example: + Using CTRL-A on "14" in "Carbon-14" results in "Carbon-15" + (without "blank" it would become "Carbon-13"). + Using CTRL-X on "8" in "Carbon -8" results in "Carbon -9" + (because -8 is preceded by whitespace. If "unsigned" was + set, it would result in "Carbon -7"). + If this format is included, overflow is prevented as if + "unsigned" were set. If both this format and "unsigned" are + included, "unsigned" will take precedence. + Numbers which simply begin with a digit in the range 1-9 are always considered decimal. This also happens for numbers that are not recognized as octal or hex. @@ -6277,7 +6309,7 @@ A jump table for the options with a short description can be found at |Q_op|. :set path+= < To use an environment variable, you probably need to replace the separator. Here is an example to append $INCL, in which directory - names are separated with a semi-colon: > + names are separated with a semicolon: > :let &path = &path .. "," .. substitute($INCL, ';', ',', 'g') < Replace the ';' with a ':' or whatever separator is used. Note that this doesn't work when $INCL contains a comma or white space. @@ -6814,7 +6846,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, macOS: "$HOME/.vim, + Unix, macOS: "$HOME/.vim or + $XDG_CONFIG_HOME/vim, $VIM/vimfiles, $VIMRUNTIME, $VIM/vimfiles/after, @@ -6855,7 +6888,7 @@ A jump table for the options with a short description can be found at |Q_op|. import/ files that are found by `:import` indent/ indent scripts |indent-expression| keymap/ key mapping files |mbyte-keymap| - lang/ menu translations |:menutrans| + lang/ message translations |:menutrans| and |multi-lang| menu.vim GUI menus |menu.vim| pack/ packages |:packadd| plugin/ plugin scripts |write-plugin| @@ -6866,6 +6899,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 @@ -7341,7 +7376,7 @@ A jump table for the options with a short description can be found at |Q_op|. POSIX default: "AS") global *E1336* This option helps to avoid all the |hit-enter| prompts caused by file - messages, for example with CTRL-G, and to avoid some other messages. + messages, for example with CTRL-G, and to avoid some other messages. It is a list of flags: flag meaning when present ~ f use "(3 of 5)" instead of "(file 3 of 5)" *shm-f* @@ -7364,8 +7399,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 @@ -7387,7 +7422,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 , but still gives as useful a message as @@ -7794,7 +7833,7 @@ A jump table for the options with a short description can be found at |Q_op|. minus two. timeout:{millisec} Limit the time searching for suggestions to - {millisec} milli seconds. Applies to the following + {millisec} milliseconds. Applies to the following methods. When omitted the limit is 5000. When negative there is no limit. {only works when built with the |+reltime| feature} @@ -8196,6 +8235,19 @@ A jump table for the options with a short description can be found at |Q_op|. 'S' flag in 'cpoptions'. Only normal file name characters can be used, "/\*?[|<>" are illegal. + *'tabclose'* *'tcl'* +'tabclose' 'tcl' string (default "") + global + This option controls the behavior when closing tab pages (e.g., using + |:tabclose|). When empty Vim goes to the next (right) tab page. + + Possible values (comma-separated list): + left If included, go to the previous tab page instead of + the next one. + uselast If included, go to the previously used tab page if + possible. This option takes precedence over the + others. + *'tabline'* *'tal'* 'tabline' 'tal' string (default empty) global @@ -9130,13 +9182,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_dos.txt b/runtime/doc/os_dos.txt index e81ba9a5ab..1b738f43ac 100644 --- a/runtime/doc/os_dos.txt +++ b/runtime/doc/os_dos.txt @@ -1,4 +1,4 @@ -*os_dos.txt* For Vim version 9.1. Last change: 2006 Mar 30 +*os_dos.txt* For Vim version 9.1. Last change: 2024 Apr 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -330,6 +330,11 @@ following values: 'shellpipe' >%s 2>&1 'shellredir' >%s 2>&1 +Note: those options are only set after reading the |.vimrc| file, in +particular setting the 'shell' option via |-c| is too late to take effect for +the other shell related settings. Consider using |--cmd| to override this +option via the command line. + If you find that PowerShell commands are taking a long time to run then try with "-NoProfile" at the beginning of the 'shellcmdflag'. Note this will prevent any PowerShell environment setup by the profile from taking place. diff --git a/runtime/doc/os_vms.txt b/runtime/doc/os_vms.txt index 862f31d07f..4549c00189 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 bbe9940089..54c8e91bd0 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 2d1898de52..4351944df9 100644 --- a/runtime/doc/pattern.txt +++ b/runtime/doc/pattern.txt @@ -1,4 +1,4 @@ -*pattern.txt* For Vim version 9.1. Last change: 2023 Oct 23 +*pattern.txt* For Vim version 9.1. Last change: 2024 Jun 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -151,13 +151,17 @@ CTRL-C Interrupt current (search) command. Use CTRL-Break on executing autocommands |autocmd-searchpat|. Same thing for when invoking a user function. + While typing the search pattern the current match will be shown if the 'incsearch' option is on. Remember that you still have to finish the search command with to actually position the cursor at the displayed match. Or use to abandon the search. + *nohlsearch-auto* All matches for the last used search pattern will be highlighted if you set -the 'hlsearch' option. This can be suspended with the |:nohlsearch| command. +the 'hlsearch' option. This can be suspended with the |:nohlsearch| command +or auto suspended with nohlsearch plugin. See |nohlsearch-install|. + When 'shortmess' does not include the "S" flag, Vim will automatically show an index, on which the cursor is. This can look like this: > @@ -1394,6 +1398,19 @@ Finally, these constructs are unique to Perl: ============================================================================== 10. Highlighting matches *match-highlight* + *syntax-vs-match* + Note that the match highlight mechanism is independent + of |syntax-highlighting|, which is (usually) a buffer-local + highlighting, while matching is window-local, both methods + can be freely mixed. Match highlighting functions give you + a bit more flexibility in when and how to apply, but are + typically only used for temporary highlighting, without strict + rules. Both methods can be used to conceal text. + + Thus the matching functions like |matchadd()| won't consider + syntax rules and functions like |synconcealed()| and the + other way around. + *:mat* *:match* :mat[ch] {group} /{pattern}/ Define a pattern to highlight in the current window. It will @@ -1500,5 +1517,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 2b22105d56..a4dee26fce 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 Jul 13 ------------------------------------------------ NETRW REFERENCE MANUAL by Charles E. Campbell @@ -15,7 +15,7 @@ Copyright: Copyright (C) 2017 Charles E Campbell *netrw-copyright* merchantability. No guarantees of suitability for any purpose. 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. Use at your own risk! + software. Use at your own risk! For bug reports, see |bugs|. *netrw* *dav* *ftp* *netrw-file* *rcp* *scp* @@ -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, 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 -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 > 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 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; it doesn't work! @@ -3891,12 +3859,7 @@ netrw: thereby making it easier to associate which part of the debugging trace is due to which command. - Please send that information to 's maintainer along - with the o/s you're using and the vim version that you're using - (see |:version|) (remove the embedded NOSPAM first) > - - NcampObell@SdrPchip.AorgM-NOSPAM -< + For bug reports, please see |bugs|. ============================================================================== 12. History *netrw-history* {{{1 diff --git a/runtime/doc/pi_tar.txt b/runtime/doc/pi_tar.txt index 0ab111c283..5b317d6087 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 f5cb12fb9d..b9e992b04c 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 16 VIM REFERENCE MANUAL by Bram Moolenaar @@ -186,6 +186,7 @@ Manipulating a popup window: |popup_move()| change the position and size of a popup |popup_setoptions()| override options of a popup |popup_settext()| replace the popup buffer contents + |popup_setbuf()| set the buffer for the popup window Closing popup windows: |popup_close()| close one popup @@ -219,6 +220,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 +240,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 +253,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 +267,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 +299,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 +325,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 +349,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 +361,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 +380,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 +423,8 @@ popup_getoptions({id}) *popup_getoptions()* Can also be used as a |method|: > GetPopup()->popup_getoptions() +< + Return type: dict popup_getpos({id}) *popup_getpos()* @@ -428,6 +454,8 @@ popup_getpos({id}) *popup_getpos()* Can also be used as a |method|: > GetPopup()->popup_getpos() +< + Return type: dict or dict popup_hide({id}) *popup_hide()* @@ -440,11 +468,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 or list + popup_locate({row}, {col}) *popup_locate()* Return the |window-ID| of the popup at screen position {row} @@ -452,6 +484,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 +518,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 +539,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 +571,20 @@ popup_notification({what}, {options}) *popup_notification()* Can also be used as a |method|: > GetText()->popup_notification({}) +< + Return type: |Number| + + +popup_setbuf({id}, {buf}) *popup_setbuf()* + Set buffer {buf} to be displayed in popup win {id}. For the + use of {buf}, see |bufname()| function. + May change window size or position to adjust for the size + of the buffer text. + + Can also be used as a |method|: > + GetPopup()->popup_setbuf(bufnr('foobar')) +< + Return type: |vim9-boolean| popup_setoptions({id}, {options}) *popup_setoptions()* @@ -569,17 +621,20 @@ 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()* - Set the text of the buffer in popup win {id}. {text} is the - same as supplied to |popup_create()|, except that a buffer - number is not allowed. + Set the text of the buffer in popup win {id}. {text} is + a string or a list of strings to be displayed in the popup. Does not change the window size or position, other than caused by the different text. Can also be used as a |method|: > GetPopup()->popup_settext('hello') +< + Return type: |Number| popup_show({id}) *popup_show()* @@ -588,6 +643,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 7b4f403bf6..174143f9eb 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 @@ -504,10 +504,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. @@ -598,7 +599,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. @@ -623,10 +624,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: @@ -634,7 +632,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/ @@ -651,12 +650,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 e659d39508..d759c18a4a 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 Jul 17 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. @@ -1086,8 +1092,8 @@ commands can be combined to create a NewGrep command: > :vim[grep][!] {pattern} {file} ... Like above, but instead of enclosing the pattern in a - non-ID character use a white-separated pattern. The - pattern must start with an ID character. + non-ID character use a white space separated pattern. + The pattern must start with an ID character. Example: > :vimgrep Error *.c < @@ -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* @@ -1400,6 +1414,17 @@ shells and OSes and also does not allow to use other available TeX options, if any. If your TeX doesn't support "-interaction=nonstopmode", please report it with different means to express \nonstopmode from the command line. +TYPST COMPILER *compiler-typst* + +Vim includes a compiler plugin for Typst files. This compiler is enabled +automatically in Typst buffers by the Typst filetype plugin |ft-typst-plugin|. +Run |:make| to compile the current Typst file. + + *g:typst_cmd* +By default Vim will use "typst" as the command to run the Typst compiler. This +can be changed by setting the |g:typst_cmd| variable: > + let g:typst_cmd = "/path/to/other/command" + ============================================================================= 7. The error format *error-file-format* diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index 583df7be99..29a99a1bf8 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -942,6 +942,7 @@ Short explanation of each option: *option-list* 'switchbuf' 'swb' sets behavior when switching to another buffer 'synmaxcol' 'smc' maximum column to find syntax items 'syntax' 'syn' syntax to be loaded for current buffer +'tabclose' 'tcl' which tab page to focus when closing a tab 'tabline' 'tal' custom format for the console tab pages line 'tabpagemax' 'tpm' maximum number of tab pages for |-p| and "tab all" 'tabstop' 'ts' number of spaces that in file uses diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index e95b6a1ae6..f2ba03f90b 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -1,4 +1,4 @@ -*repeat.txt* For Vim version 9.1. Last change: 2023 May 26 +*repeat.txt* For Vim version 9.1. Last change: 2024 Jul 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -735,6 +735,10 @@ Your directory layout would be like this: start/foobar/autoload/foo.vim " loaded when foo command used start/foobar/doc/foo.txt " help for foo.vim start/foobar/doc/tags " help tags + start/foobar/lang//LC_MESSAGES/foobar.mo + " messages for the plugin in the + " language. These files are + " optional. opt/fooextra/plugin/extra.vim " optional plugin, defines commands opt/fooextra/autoload/extra.vim " loaded when extra command used opt/fooextra/doc/extra.txt " help for extra.vim @@ -744,24 +748,345 @@ This allows for the user to do: > mkdir ~/.vim/pack cd ~/.vim/pack git clone https://github.com/you/foobar.git myfoobar - +< Here "myfoobar" is a name that the user can choose, the only condition is that it differs from other packages. In your documentation you explain what the plugins do, and tell the user how to load the optional plugin: > :packadd! fooextra - +< You could add this packadd command in one of your plugins, to be executed when the optional plugin is needed. + *package-doc* *package-documentation* Run the `:helptags` command to generate the doc/tags file. Including this generated file in the package means that the user can drop the package in the pack directory and the help command works right away. Don't forget to re-run the command after changing the plugin help: > :helptags path/start/foobar/doc :helptags path/opt/fooextra/doc - +< + *package-translation* +In order for a plugin to display translated messages, a few steps are +required. +The author of the plugin who likes to translate messages must define the name +of the package and the location of the directory where the translations can be +found using the |bindtextdomain()| function: > + :call bindtextdomain("foobar", + \ fnamemodify(expand(" + +
+ + + + + +strong importance + + + + +
+ + + + + + + + + + + +unarticulated annotation +
    + + + + + + + + +
    + + + + + + + + + + + +strikethrough + + + + + + + + +<plaintext> diff --git a/runtime/syntax/testdir/input/html_html b/runtime/syntax/testdir/input/html_html deleted file mode 100644 index bfeca26db8..0000000000 --- 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 0000000000..c5871c3c8d --- /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_annotations_signature.java b/runtime/syntax/testdir/input/java_annotations_signature.java new file mode 100644 index 0000000000..8236218550 --- /dev/null +++ b/runtime/syntax/testdir/input/java_annotations_signature.java @@ -0,0 +1,78 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'style' +// VIM_TEST_SETUP let g:java_highlight_signature = 1 + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +class Annotations$Tests +{ + @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 = Annotations$Tests.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 = Annotations$Tests.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 0000000000..628e230895 --- /dev/null +++ b/runtime/syntax/testdir/input/java_enfoldment.java @@ -0,0 +1,98 @@ +// VIM_TEST_SETUP setlocal foldenable foldcolumn=2 foldmethod=syntax + + + @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); +} + } +/*\\\*/ { + (new java.util.function.Function<Object, Object>() { + /** + * {@inheritDoc} */ + public Object apply(Object o) { return o; }; + }).apply( + (new java.util.function.Function<Object, Object>() { + /** {@inheritDoc} + */ + public Object apply(Object o) { return o; }; + })); + } + + /** + * 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_generics.java b/runtime/syntax/testdir/input/java_generics.java new file mode 100644 index 0000000000..c9b001a406 --- /dev/null +++ b/runtime/syntax/testdir/input/java_generics.java @@ -0,0 +1,140 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'style' +// VIM_TEST_SETUP let g:java_highlight_generics = 1 +// VIM_TEST_SETUP hi link javaGenericsC1 Todo +// VIM_TEST_SETUP hi link javaGenericsC2 Error + +import java.math.BigInteger; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.LongFunction; +import java.util.function.Predicate; + +class GenericsTests<T extends Number & Comparable<? super T>, U> +{ // JDK 21+. + static final Function<Function<Object, Object>, Object> PARTIAL = + GenericsTests.y0(); + static final Function<BigInteger, BigInteger> FACTORIAL_2000 = + GenericsTests.<BigInteger, BigInteger>y1() + .apply(f -> x -> (x.compareTo(BigInteger.ONE) < 1) + ? BigInteger.ONE + : x.multiply(f.apply(x.subtract(BigInteger.ONE)))); + + static <T1> Y0<T1> y0() + { + return (Function<T1, T1> f) -> f.apply( + GenericsTests.<T1>y0() + .apply(f)); + } + + static <T1, T2> Y1<T1, T2> y1() + { + return (Function<Function<T1, T2>, Function<T1, T2>> f) -> + (T1 x) -> f.apply(GenericsTests.<T1, T2>y1() + .apply(f)) + .apply(x); + } + + static<T> void noOp(T dummy) { } + + interface alpha<T> { } + + interface Y0<T1> extends Function<Function<T1, T1>, T1> { } + + interface Y1<T1, T2> extends Function<Function<Function<T1, T2>, + Function<T1, T2>>, + Function<T1, T2>> { } + + interface Stackable<E> extends Iterable<E> + { + boolean isEmpty(); + E peek(); + E pop(); + Stackable<E> popAll(Stackable<? super E> elements); + Stackable<E> popSome(Stackable<? super E> elements, + Predicate<? super E> filter); + Stackable<E> push(E element); + Stackable<E> pushAll(Iterable<? extends E> elements); + Stackable<E> pushSome(Iterable<? extends E> elements, + Predicate<? super E> filter); + Stackable<E> wind(Consumer<? super Stackable<E>> action); + } + + sealed interface Num<N extends Number> + { + int radix(); + N value(); + } + + record Bin<N extends Number>(N value) implements Num<N> + { + public int radix() { return 2; } + } + + record Dec<N extends Number>(N value) implements Num<N> + { + public int radix() { return 10; } + } + + record Hex<N extends Number>(N value) implements Num<N> + { + public int radix() { return 16; } + } + + record Oct<N extends Number>(N value) implements Num<N> + { + public int radix() { return 8; } + } + + static Num<Long> fromDecimal(long x, int radix) + { + record Pair(LongFunction<Num<Long>> a, + LongFunction<String> b) { } + final Pair p = switch (radix) { + case 2 -> new Pair(Bin::new, Long::toBinaryString); + case 8 -> new Pair(Oct::new, Long::toOctalString); + case 16 -> new Pair(Hex::new, Long::toHexString); + default -> new Pair(Dec::new, + y -> Long.toString(y)); + }; + return p.a().apply(Long.parseLong(p.b().apply(x), radix)); + } + + static long toDecimal(Num<Long> x) + { + return Long.parseLong(switch (x) { + case Bin<?>(Long b) -> Long.toBinaryString(b); + case Oct<?>(Long o) -> Long.toOctalString(o); + case Hex<?>(Long h) -> Long.toHexString(h); + default -> Long.toString(x.value()); + }, x.radix()); + } + + @java.lang.annotation.Target( + java.lang.annotation.ElementType.TYPE_USE) + @interface Taggable + { + String value() default ""; + } + + { + int N = 0, X = 1, Y = 2; + Predicate<T> f = y->N<y.intValue(); + Predicate<T> g = y->X<N&&(Integer)y>N; + boolean[] bb = { + X<N||N>Y, X < Y, X <Y, X <(Y), X<(Y), (X)<Y, + Double.isFinite(X<<Y), + X<=Y, X<(int)(byte)Y, X<~Y, X<-Y, X<+Y, + }; + Class<?> klass = GenericsTests.class; + Class< java.lang.Class<@Taggable("<>")int[][]> [] [] > + [ ] [ ] $ [ ] [ ]; + if (false) { new GenericsTests<>(); } + alpha<?> ao; + alpha<U> au; + alpha<alpha<U>> aau; + alpha<Y0<?>> ay0o; + alpha<Y0<U>> ay0u; + Y0<alpha<?>> y0ao; + Y0<alpha<U>> y0au; + } +} diff --git a/runtime/syntax/testdir/input/java_generics_signature.java b/runtime/syntax/testdir/input/java_generics_signature.java new file mode 100644 index 0000000000..505e70e06d --- /dev/null +++ b/runtime/syntax/testdir/input/java_generics_signature.java @@ -0,0 +1,140 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'style' +// VIM_TEST_SETUP let g:java_highlight_signature = 1 +// VIM_TEST_SETUP let g:java_highlight_generics = 1 +// VIM_TEST_SETUP hi link javaGenericsC1 Todo +// VIM_TEST_SETUP hi link javaGenericsC2 Error +import java.math.BigInteger; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.LongFunction; +import java.util.function.Predicate; + +class Generics$Tests<T extends Number & Comparable<? super T>, U> +{ // JDK 21+. + static final Function<Function<Object, Object>, Object> PARTIAL = + Generics$Tests.y0(); + static final Function<BigInteger, BigInteger> FACTORIAL_2000 = + Generics$Tests.<BigInteger, BigInteger>y1() + .apply(f -> x -> (x.compareTo(BigInteger.ONE) < 1) + ? BigInteger.ONE + : x.multiply(f.apply(x.subtract(BigInteger.ONE)))); + + static <T1> Y0<T1> y0() + { + return (Function<T1, T1> f) -> f.apply( + Generics$Tests.<T1>y0() + .apply(f)); + } + + static <T1, T2> Y1<T1, T2> y1() + { + return (Function<Function<T1, T2>, Function<T1, T2>> f) -> + (T1 x) -> f.apply(Generics$Tests.<T1, T2>y1() + .apply(f)) + .apply(x); + } + + static<T> void noOp(T dummy) { } + + interface alpha<T> { } + + interface Y0<T1> extends Function<Function<T1, T1>, T1> { } + + interface Y1<T1, T2> extends Function<Function<Function<T1, T2>, + Function<T1, T2>>, + Function<T1, T2>> { } + + interface Stackable<E> extends Iterable<E> + { + boolean isEmpty(); + E peek(); + E pop(); + Stackable<E> popAll(Stackable<? super E> elements); + Stackable<E> popSome(Stackable<? super E> elements, + Predicate<? super E> filter); + Stackable<E> push(E element); + Stackable<E> pushAll(Iterable<? extends E> elements); + Stackable<E> pushSome(Iterable<? extends E> elements, + Predicate<? super E> filter); + Stackable<E> wind(Consumer<? super Stackable<E>> action); + } + + sealed interface Num<N extends Number> + { + int radix(); + N value(); + } + + record Bin<N extends Number>(N value) implements Num<N> + { + public int radix() { return 2; } + } + + record Dec<N extends Number>(N value) implements Num<N> + { + public int radix() { return 10; } + } + + record Hex<N extends Number>(N value) implements Num<N> + { + public int radix() { return 16; } + } + + record Oct<N extends Number>(N value) implements Num<N> + { + public int radix() { return 8; } + } + + static Num<Long> fromDecimal(long x, int radix) + { + record Pair(LongFunction<Num<Long>> a, + LongFunction<String> b) { } + final Pair p = switch (radix) { + case 2 -> new Pair(Bin::new, Long::toBinaryString); + case 8 -> new Pair(Oct::new, Long::toOctalString); + case 16 -> new Pair(Hex::new, Long::toHexString); + default -> new Pair(Dec::new, + y -> Long.toString(y)); + }; + return p.a().apply(Long.parseLong(p.b().apply(x), radix)); + } + + static long toDecimal(Num<Long> x) + { + return Long.parseLong(switch (x) { + case Bin<?>(Long b) -> Long.toBinaryString(b); + case Oct<?>(Long o) -> Long.toOctalString(o); + case Hex<?>(Long h) -> Long.toHexString(h); + default -> Long.toString(x.value()); + }, x.radix()); + } + + @java.lang.annotation.Target( + java.lang.annotation.ElementType.TYPE_USE) + @interface Taggable + { + String value() default ""; + } + + { + int N = 0, X = 1, Y = 2; + Predicate<T> f = y->N<y.intValue(); + Predicate<T> g = y->X<N&&(Integer)y>N; + boolean[] bb = { + X<N||N>Y, X < Y, X <Y, X <(Y), X<(Y), (X)<Y, + Double.isFinite(X<<Y), + X<=Y, X<(int)(byte)Y, X<~Y, X<-Y, X<+Y, + }; + Class<?> klass = Generics$Tests.class; + Class< java.lang.Class<@Taggable("<>")int[][]> [] [] > + [ ] [ ] $ [ ] [ ]; + if (false) { new Generics$Tests<>(); } + alpha<?> ao; + alpha<U> au; + alpha<alpha<U>> aau; + alpha<Y0<?>> ay0o; + alpha<Y0<U>> ay0u; + Y0<alpha<?>> y0ao; + Y0<alpha<U>> y0au; + } +} 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 0000000000..75f5af4cc8 --- /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_lambda_expressions_signature.java b/runtime/syntax/testdir/input/java_lambda_expressions_signature.java new file mode 100644 index 0000000000..16cf9905dd --- /dev/null +++ b/runtime/syntax/testdir/input/java_lambda_expressions_signature.java @@ -0,0 +1,154 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'style' +// VIM_TEST_SETUP let g:java_highlight_signature = 1 + +import java.lang.annotation.ElementType; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Predicate; + +class LambdaExpressions$Tests // 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_indent2.java b/runtime/syntax/testdir/input/java_methods_indent2.java new file mode 100644 index 0000000000..3754cc4d5e --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_indent2.java @@ -0,0 +1,104 @@ +// 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", new Thread( + + () -> { + })), D("d", (java.util.function.BooleanSupplier) () -> true), + E("e", new char[] { 'a', 'b', 'c', 'd' }), F("f", new Object() { + transient String name = ""; + @Override public String toString() { return this.name; } + }), //\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\// + G("g"), @Deprecated H("h"); + + final String s; + private E2(String s) { this.s = s; } + private <δ> E2(String s, δ dummy) { this(s); } + + @Override public String toString() { return name().toUpperCase(); } +} diff --git a/runtime/syntax/testdir/input/java_methods_indent2_signature.java b/runtime/syntax/testdir/input/java_methods_indent2_signature.java new file mode 100644 index 0000000000..05e633bf25 --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_indent2_signature.java @@ -0,0 +1,104 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'indent2' +// VIM_TEST_SETUP let g:java_highlight_signature = 1 +// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8 +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +abstract class Indent2$MethodsTests +{ // 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 Indent2$MethodsTests() { } + <T extends Comparable<T>> Indent2$MethodsTests(T t, Void v) { } + private <T extends Comparable<T>> Indent2$MethodsTests(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 + Indent2$MethodsTests.<α, β>μʭʭ$98_(ƒ)[0]; + } + + public static Class<?> classLock() { return Indent2$MethodsTests.class; } + + @Override @SuppressWarnings("cast") + public String toString() { return (String) "Indent2$MethodsTests"; } +} + +enum E2$ +{ + @SuppressWarnings("bespoke") A("a"), + B("b" + /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/), + C("c", new Thread( + + () -> { + })), D("d", (java.util.function.BooleanSupplier) () -> true), + E("e", new char[] { 'a', 'b', 'c', 'd' }), F("f", new Object() { + transient String name = ""; + @Override public String toString() { return this.name; } + }), //\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\// + G("g"), @Deprecated H("h"); + + final String s; + private E2$(String s) { this.s = s; } + private <δ> E2$(String s, δ dummy) { this(s); } + + @Override public String toString() { return name().toUpperCase(); } +} 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 0000000000..8fc05c04be --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_indent4.java @@ -0,0 +1,104 @@ +// 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", new Thread( + + () -> { + })), D("d", (java.util.function.BooleanSupplier) () -> true), + E("e", new char[] { 'a', 'b', 'c', 'd' }), F("f", new Object() { + transient String name = ""; + @Override public String toString() { return this.name; } + }), //\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\// + G("g"), @Deprecated H("h"); + + final String s; + private E4(String s) { this.s = s; } + private <δ> E4(String s, δ dummy) { this(s); } + + @Override public String toString() { return name().toUpperCase(); } +} diff --git a/runtime/syntax/testdir/input/java_methods_indent4_signature.java b/runtime/syntax/testdir/input/java_methods_indent4_signature.java new file mode 100644 index 0000000000..f21d95d0c5 --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_indent4_signature.java @@ -0,0 +1,104 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'indent4' +// VIM_TEST_SETUP let g:java_highlight_signature = 1 +// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8 +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +abstract class Indent4$MethodsTests +{ // 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 Indent4$MethodsTests() { } + <T extends Comparable<T>> Indent4$MethodsTests(T t, Void v) { } + private <T extends Comparable<T>> Indent4$MethodsTests(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 + Indent4$MethodsTests.<α, β>μʭʭ$98_(ƒ)[0]; + } + + public static Class<?> classLock() { return Indent4$MethodsTests.class; } + + @Override @SuppressWarnings("cast") + public String toString() { return (String) "Indent4$MethodsTests"; } +} + +enum E4$ +{ + @SuppressWarnings("bespoke") A("a"), + B("b" + /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/), + C("c", new Thread( + + () -> { + })), D("d", (java.util.function.BooleanSupplier) () -> true), + E("e", new char[] { 'a', 'b', 'c', 'd' }), F("f", new Object() { + transient String name = ""; + @Override public String toString() { return this.name; } + }), //\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\// + G("g"), @Deprecated H("h"); + + final String s; + private E4$(String s) { this.s = s; } + private <δ> E4$(String s, δ dummy) { this(s); } + + @Override public String toString() { return name().toUpperCase(); } +} 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 0000000000..d27830c878 --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_indent8.java @@ -0,0 +1,104 @@ +// 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", new Thread( + + () -> { + })), D("d", (java.util.function.BooleanSupplier) () -> true), + E("e", new char[] { 'a', 'b', 'c', 'd' }), F("f", new Object() { + transient String name = ""; + @Override public String toString() { return this.name; } + }), //\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\// + G("g"), @Deprecated H("h"); + + final String s; + private E8(String s) { this.s = s; } + private <δ> E8(String s, δ dummy) { this(s); } + + @Override public String toString() { return name().toUpperCase(); } +} diff --git a/runtime/syntax/testdir/input/java_methods_indent8_signature.java b/runtime/syntax/testdir/input/java_methods_indent8_signature.java new file mode 100644 index 0000000000..8d8219690b --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_indent8_signature.java @@ -0,0 +1,104 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'indent8' +// VIM_TEST_SETUP let g:java_highlight_signature = 1 +// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8 +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +abstract class Indent8$MethodsTests +{ // 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 Indent8$MethodsTests() { } + <T extends Comparable<T>> Indent8$MethodsTests(T t, Void v) { } + private <T extends Comparable<T>> Indent8$MethodsTests(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 + Indent8$MethodsTests.<α, β>μʭʭ$98_(ƒ)[0]; + } + + public static Class<?> classLock() { return Indent8$MethodsTests.class; } + + @Override @SuppressWarnings("cast") + public String toString() { return (String) "Indent8$MethodsTests"; } +} + +enum E8$ +{ + @SuppressWarnings("bespoke") A("a"), + B("b" + /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/), + C("c", new Thread( + + () -> { + })), D("d", (java.util.function.BooleanSupplier) () -> true), + E("e", new char[] { 'a', 'b', 'c', 'd' }), F("f", new Object() { + transient String name = ""; + @Override public String toString() { return this.name; } + }), //\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\// + G("g"), @Deprecated H("h"); + + final String s; + private E8$(String s) { this.s = s; } + private <δ> E8$(String s, δ dummy) { this(s); } + + @Override public String toString() { return name().toUpperCase(); } +} diff --git a/runtime/syntax/testdir/input/java_methods_style.java b/runtime/syntax/testdir/input/java_methods_style.java new file mode 100644 index 0000000000..e2e7d3877d --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_style.java @@ -0,0 +1,82 @@ +// 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 +{ + // 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 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_( + @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 + 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_methods_style_signature.java b/runtime/syntax/testdir/input/java_methods_style_signature.java new file mode 100644 index 0000000000..8e3b4d64b3 --- /dev/null +++ b/runtime/syntax/testdir/input/java_methods_style_signature.java @@ -0,0 +1,82 @@ +// VIM_TEST_SETUP let g:java_highlight_functions = 'style' +// VIM_TEST_SETUP let g:java_highlight_signature = 1 +// VIM_TEST_SETUP set encoding=utf-8 termencoding=utf-8 +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +abstract class Style$MethodsTests +{ + // 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 Style$MethodsTests() { } + <T extends Comparable<T>> Style$MethodsTests(T t, Void v) { } + private <T extends Comparable<T>> Style$MethodsTests(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 + Style$MethodsTests.<α, β>μʭʭ$98_(ƒ)[0]; + } + + public static Class<?> classLock() { return Style$MethodsTests.class; } + + @Override @SuppressWarnings("cast") + public String toString() { return (String) "Style$MethodsTests"; } +} diff --git a/runtime/syntax/testdir/input/java_unfoldment.java b/runtime/syntax/testdir/input/java_unfoldment.java new file mode 100644 index 0000000000..258ed05c0c --- /dev/null +++ b/runtime/syntax/testdir/input/java_unfoldment.java @@ -0,0 +1,98 @@ +// 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); +} + } +/*\\\*/ { + (new java.util.function.Function<Object, Object>() { + /** + * {@inheritDoc} */ + public Object apply(Object o) { return o; }; + }).apply( + (new java.util.function.Function<Object, Object>() { + /** {@inheritDoc} + */ + public Object apply(Object o) { return o; }; + })); + } + + /** + * 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/selftestdir/README.txt b/runtime/syntax/testdir/input/selftestdir/README.txt new file mode 100644 index 0000000000..035701db07 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/README.txt @@ -0,0 +1,10 @@ +The test files with made-up syntax in this directory serve for additional +linewise checks to be manually performed whenever the algorithm managing +screen dump file generation is modified (../../runtest.vim#RunTest()). + +This is mainly used for debugging and testing the syntax test suite. + +Please test any changes as follows: + cd runtime/syntax/ + VIM_SYNTAX_SELF_TESTING=1 make clean test + diff --git a/runtime/syntax/testdir/input/selftestdir/dots_01 b/runtime/syntax/testdir/input/selftestdir/dots_01 new file mode 100644 index 0000000000..cf78d974cb --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_01 @@ -0,0 +1,60 @@ +..........................................................................1 +..........................................................................2 +..........................................................................3 +..........................................................................4 +..............................winwidth(0): 75.............................5 +.............................winheight(0): 19.............................6 +.................................ruler....................................7 +..........................................................................8 +..........................................................................9 +.........................................................................10 +.........................................................................11 +.........................................................................12 +.........................................................................13 +.........................................................................14 +.........................................................................15 +.........................................................................16 +.........................................................................17 +.........................................................................18 +.........................................................................19 +.........................................................................20 +.........................................................................21 +.........................................................................22 +.........................................................................23 +.........................................................................24 +.........................................................................25 +.........................................................................26 +.........................................................................27 +.........................................................................28 +.........................................................................29 +.........................................................................30 +.........................................................................31 +.........................................................................32 +.........................................................................33 +.........................................................................34 +.........................................................................35 +.........................................................................36 +.........................................................................37 +.........................................................................38 +.........................................................................39 +.........................................................................40 +.........................................................................41 +.........................................................................42 +.........................................................................43 +.........................................................................44 +.........................................................................45 +.........................................................................46 +.........................................................................47 +.........................................................................48 +.........................................................................49 +.........................................................................50 +.........................................................................51 +.........................................................................52 +.........................................................................53 +.........................................................................54 +.........................................................................55 +.........................................................................56 +.........................................................................57 +.........................................................................58 +.........................................................................59 +.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_02 b/runtime/syntax/testdir/input/selftestdir/dots_02 new file mode 100644 index 0000000000..4748fa117f --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_02 @@ -0,0 +1,30 @@ +1..........................................................................2 +3..........................................................................4 +5..........................................................................6 +7..........................................................................8 +9............................winwidth(0): 75...............................10 +11..........................winheight(0): 19...............................12 +13..............................ruler......................................14 +15.........................................................................16 +17.........................................................................18 +19.........................................................................20 +21.........................................................................22 +23.........................................................................24 +25.........................................................................26 +27.........................................................................28 +29.........................................................................30 +31.........................................................................32 +33.........................................................................34 +35.........................................................................36 +37.........................................................................38 +39.........................................................................40 +41.........................................................................42 +43.........................................................................44 +45.........................................................................46 +47.........................................................................48 +49.........................................................................50 +51.........................................................................52 +53.........................................................................54 +55.........................................................................56 +57.........................................................................58 +59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_03 b/runtime/syntax/testdir/input/selftestdir/dots_03 new file mode 100644 index 0000000000..a8a16e98cc --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_03 @@ -0,0 +1,20 @@ +1..........................................................................2..........................................................................3 +4..........................................................................5..........................................................................6 +7..........................................................................8..........................................................................9 +10.........................................................................11.........................................................................12 +13...........................winwidth(0): 75...............................14.........................................................................15 +16..........................winheight(0): 19...............................17.........................................................................18 +19..............................ruler......................................20.........................................................................21 +22.........................................................................23.........................................................................24 +25.........................................................................26.........................................................................27 +28.........................................................................29.........................................................................30 +31.........................................................................32.........................................................................33 +34.........................................................................35.........................................................................36 +37.........................................................................38.........................................................................39 +40.........................................................................41.........................................................................42 +43.........................................................................44.........................................................................45 +46.........................................................................47.........................................................................48 +49.........................................................................50.........................................................................51 +52.........................................................................53.........................................................................54 +55.........................................................................56.........................................................................57 +58.........................................................................59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_04 b/runtime/syntax/testdir/input/selftestdir/dots_04 new file mode 100644 index 0000000000..ac0a26a284 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_04 @@ -0,0 +1,15 @@ +1..........................................................................2..........................................................................3..........................................................................4 +5..........................................................................6..........................................................................7..........................................................................8 +9..........................................................................10.........................................................................11.........................................................................12 +13.........................................................................14.........................................................................15.........................................................................16 +17...........................winwidth(0): 75...............................18.........................................................................19.........................................................................20 +21..........................winheight(0): 19...............................22.........................................................................23.........................................................................24 +25..............................ruler......................................26.........................................................................27.........................................................................28 +29.........................................................................30.........................................................................31.........................................................................32 +33.........................................................................34.........................................................................35.........................................................................36 +37.........................................................................38.........................................................................39.........................................................................40 +41.........................................................................42.........................................................................43.........................................................................44 +45.........................................................................46.........................................................................47.........................................................................48 +49.........................................................................50.........................................................................51.........................................................................52 +53.........................................................................54.........................................................................55.........................................................................56 +57.........................................................................58.........................................................................59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_05 b/runtime/syntax/testdir/input/selftestdir/dots_05 new file mode 100644 index 0000000000..2dfb5be08e --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_05 @@ -0,0 +1,12 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5 +6..........................................................................7..........................................................................8..........................................................................9..........................................................................10 +11.........................................................................12.........................................................................13.........................................................................14.........................................................................15 +16.........................................................................17.........................................................................18.........................................................................19.........................................................................20 +21...........................winwidth(0): 75...............................22.........................................................................23.........................................................................24.........................................................................25 +26..........................winheight(0): 19...............................27.........................................................................28.........................................................................29.........................................................................30 +31..............................ruler......................................32.........................................................................33.........................................................................34.........................................................................35 +36.........................................................................37.........................................................................38.........................................................................39.........................................................................40 +41.........................................................................42.........................................................................43.........................................................................44.........................................................................45 +46.........................................................................47.........................................................................48.........................................................................49.........................................................................50 +51.........................................................................52.........................................................................53.........................................................................54.........................................................................55 +56.........................................................................57.........................................................................58.........................................................................59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_06 b/runtime/syntax/testdir/input/selftestdir/dots_06 new file mode 100644 index 0000000000..87eaf76d0b --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_06 @@ -0,0 +1,10 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6 +7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12 +13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18 +19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24 +25...........................winwidth(0): 75...............................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30 +31..........................winheight(0): 19...............................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36 +37..............................ruler......................................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42 +43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48 +49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54 +55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_07 b/runtime/syntax/testdir/input/selftestdir/dots_07 new file mode 100644 index 0000000000..801c470767 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_07 @@ -0,0 +1,9 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7 +8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14 +15.........................................................................16.........................................................................17.........................................................................18.........................................................................19.........................................................................20.........................................................................21 +22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28 +29...........................winwidth(0): 75...............................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35 +36..........................winheight(0): 19...............................37.........................................................................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42 +43..............................ruler......................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49 +50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56 +57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_08 b/runtime/syntax/testdir/input/selftestdir/dots_08 new file mode 100644 index 0000000000..2b7bdd94aa --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_08 @@ -0,0 +1,8 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8 +9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16 +17.........................................................................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24 +25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32 +33...........................winwidth(0): 75...............................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38.........................................................................39.........................................................................40 +41..........................winheight(0): 19...............................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48 +49..............................ruler......................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56 +57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_09 b/runtime/syntax/testdir/input/selftestdir/dots_09 new file mode 100644 index 0000000000..76b25e6c90 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_09 @@ -0,0 +1,7 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9 +10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18 +19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27 +28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36 +37...........................winwidth(0): 75...............................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45 +46..........................winheight(0): 19...............................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54 +55..............................ruler......................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_10 b/runtime/syntax/testdir/input/selftestdir/dots_10 new file mode 100644 index 0000000000..9d6a15851a --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_10 @@ -0,0 +1,6 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10 +11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18.........................................................................19.........................................................................20 +21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30 +31...........................winwidth(0): 75...............................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38.........................................................................39.........................................................................40 +41..........................wihheight(0): 19...............................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50 +51..............................ruler......................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_11 b/runtime/syntax/testdir/input/selftestdir/dots_11 new file mode 100644 index 0000000000..503b734d21 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_11 @@ -0,0 +1,6 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11 +12.........................................................................13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22 +23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33 +34...........................winwidth(0): 75...............................35.........................................................................36.........................................................................37.........................................................................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44 +45..........................winheight(0): 19...............................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55 +56..............................ruler......................................57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64.........................................................................65.........................................................................66 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_12 b/runtime/syntax/testdir/input/selftestdir/dots_12 new file mode 100644 index 0000000000..347feb223f --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_12 @@ -0,0 +1,5 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12 +13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24 +25...........................winwidth(0): 75...............................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36 +37..........................winheight(0): 19...............................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48 +49..............................ruler......................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_13 b/runtime/syntax/testdir/input/selftestdir/dots_13 new file mode 100644 index 0000000000..b177614a16 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_13 @@ -0,0 +1,5 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13 +14.........................................................................15.........................................................................16.........................................................................17.........................................................................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26 +27...........................winwidth(0): 75...............................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38.........................................................................39 +40..........................winheight(0): 19...............................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52 +53..............................ruler......................................54.........................................................................55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64.........................................................................65 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_14 b/runtime/syntax/testdir/input/selftestdir/dots_14 new file mode 100644 index 0000000000..9a46c3e08f --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_14 @@ -0,0 +1,5 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14 +15.........................................................................16.........................................................................17.........................................................................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28 +29...........................winwidth(0): 75...............................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42 +43..........................winheight(0): 19...............................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56 +57..............................ruler......................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64.........................................................................65.........................................................................66.........................................................................67.........................................................................68.........................................................................69.........................................................................70 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_15 b/runtime/syntax/testdir/input/selftestdir/dots_15 new file mode 100644 index 0000000000..45fbef949f --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_15 @@ -0,0 +1,4 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15 +16...........................winwidth(0): 75...............................17.........................................................................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30 +31..........................winheight(0): 19...............................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45 +46..............................ruler......................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_16 b/runtime/syntax/testdir/input/selftestdir/dots_16 new file mode 100644 index 0000000000..1af3caa605 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_16 @@ -0,0 +1,4 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16 +17...........................winwidth(0): 75...............................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32 +33..........................winheight(0): 19...............................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48 +49..............................ruler......................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_17 b/runtime/syntax/testdir/input/selftestdir/dots_17 new file mode 100644 index 0000000000..6dc5050846 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_17 @@ -0,0 +1,4 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16.........................................................................17 +18...........................winwidth(0): 75...............................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34 +35..........................winheight(0): 19...............................36.........................................................................37.........................................................................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51 +52...............................ruler.....................................53.........................................................................54.........................................................................55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64.........................................................................65.........................................................................66.........................................................................67.........................................................................68 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_18 b/runtime/syntax/testdir/input/selftestdir/dots_18 new file mode 100644 index 0000000000..f84a827a7d --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_18 @@ -0,0 +1,4 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18 +19...........................winwidth(0): 75...............................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36 +37..........................winheight(0): 19...............................38.........................................................................39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54 +55...............................ruler.....................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64.........................................................................65.........................................................................66.........................................................................67.........................................................................68.........................................................................69.........................................................................70.........................................................................71.........................................................................72 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_19 b/runtime/syntax/testdir/input/selftestdir/dots_19 new file mode 100644 index 0000000000..9f0ad00d1a --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_19 @@ -0,0 +1,4 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5..........................................................................6..........................................................................7..........................................................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18.........................................................................19 +20...........................winwidth(0): 75...............................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38 +39..........................winheight(0): 19...............................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56.........................................................................57 +58...............................ruler.....................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64.........................................................................65.........................................................................66.........................................................................67.........................................................................68.........................................................................69.........................................................................70.........................................................................71.........................................................................72.........................................................................73.........................................................................74.........................................................................75.........................................................................76 diff --git a/runtime/syntax/testdir/input/selftestdir/dots_20 b/runtime/syntax/testdir/input/selftestdir/dots_20 new file mode 100644 index 0000000000..ca3a93d252 --- /dev/null +++ b/runtime/syntax/testdir/input/selftestdir/dots_20 @@ -0,0 +1,2 @@ +1..........................................................................2..........................................................................3..........................................................................4..........................................................................5.............................winwidth(0): 75..............................6............................winheight(0): 19..............................7................................ruler.....................................8..........................................................................9..........................................................................10.........................................................................11.........................................................................12.........................................................................13.........................................................................14.........................................................................15.........................................................................16.........................................................................17.........................................................................18.........................................................................19.........................................................................20.........................................................................21.........................................................................22.........................................................................23.........................................................................24.........................................................................25.........................................................................26.........................................................................27.........................................................................28.........................................................................29.........................................................................30.........................................................................31.........................................................................32.........................................................................33.........................................................................34.........................................................................35.........................................................................36.........................................................................37.........................................................................38 +39.........................................................................40.........................................................................41.........................................................................42.........................................................................43.........................................................................44.........................................................................45.........................................................................46.........................................................................47.........................................................................48.........................................................................49.........................................................................50.........................................................................51.........................................................................52.........................................................................53.........................................................................54.........................................................................55.........................................................................56.........................................................................57.........................................................................58.........................................................................59.........................................................................60.........................................................................61.........................................................................62.........................................................................63.........................................................................64.........................................................................65.........................................................................66.........................................................................67.........................................................................68.........................................................................69.........................................................................70.........................................................................71.........................................................................72.........................................................................73.........................................................................74.........................................................................75.........................................................................76 diff --git a/runtime/syntax/testdir/input/vim_ex_comment-vim9.vim b/runtime/syntax/testdir/input/vim9_comment.vim similarity index 69% rename from runtime/syntax/testdir/input/vim_ex_comment-vim9.vim rename to runtime/syntax/testdir/input/vim9_comment.vim index 786d11b43f..fd6a5d2a2a 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_commands.vim b/runtime/syntax/testdir/input/vim9_ex_commands.vim new file mode 100644 index 0000000000..028e688739 --- /dev/null +++ b/runtime/syntax/testdir/input/vim9_ex_commands.vim @@ -0,0 +1,1225 @@ +vim9script + +# Vim9 Ex commands + +# START NOT MATCHED +:@ +:@@ +:Next +:X +# END NOT MATCHED + +:help + :help +: help + : help + +:2match +:3match +:abbreviate +:abclear +:aboveleft +:abstract +:all +:amenu +:anoremenu +:argadd +:argdedupe +:argdelete +:argdo +:argedit +:argglobal +:arglocal +:args +:argument +:ascii +:augroup Foo +:augroup END +:aunmenu +:autocmd +:badd +:ball +:balt +:bdelete +:behave mswin +:behave xterm +:belowright +:bfirst +:blast +:bmodified +:bnext +:bNext +:botright +:bprevious +:break +:breakadd +:breakdel +:breaklist +:brewind +:browse +:bufdo +:buffer +:buffers +:bunload +:bwipeout +:cabbrev +:cabclear +:cabove +:caddbuffer +:caddexpr +:caddfile +:cafter +:call +:catch +:cbefore +:cbelow +:cbottom +:cbuffer +:cc +:cclose +:cd +:cdo +:center +:cexpr +:cfdo +:cfile +:cfirst +:cgetbuffer +:cgetexpr +:cgetfile +:changes +:chdir +:checkpath +:checktime +:chistory +:class +:class +:clast +:clearjumps +:clist +:close +:cmap +:cmapclear +:cmenu +:cnewer +:cnext +:cNext +:cnfile +:cNfile +:cnoreabbrev +:cnoremap +:cnoremenu +:colder +:colorscheme +:comclear +:command +:compiler +:confirm +:const +:continue +:copen +:copy +:cpfile +:cprevious +:cquit +:crewind +:cscope +:cstag +:cunabbrev +:cunmap +:cunmenu +:cwindow +:debug +:debuggreedy +:def +:defcompile +:defcompile +:defer +:delcommand +:delete +:delfunction +:delmarks +:diffget +:diffoff +:diffpatch +:diffput +:diffsplit +:diffthis +:diffupdate +:digraphs +:disassemble +:disassemble +:display +:djump +:dl +:dlist +:doautoall +:doautocmd +:dp +:drop +:dsearch +:dsplit +:earlier +:echo +:echoconsole +:echoerr +:echohl +:echomsg +:echon +:echowindow +:edit +:else +:elseif +:emenu +:endclass +:endclass +:enddef +:endenum +:endfor +:endfunction +:endif +:endinterface +:endtry +:endwhile +:enew +:enum +:eval +:ex +:execute +:exit +:export +:export +:exusage +:file +:files +:filetype +:filter +:final +:finally +:find +:finish +:first +:fixdel +:fold +:foldclose +:folddoclosed +:folddoopen +:foldopen +:for +:function +:global/.../ +:goto +:grep +:grepadd +:gui +:gvim +:hardcopy +:help +:helpclose +:helpfind +:helpgrep +:helptags +:hide +:highlight +:history +:horizontal +:iabbrev +:iabclear +:if +:ijump +:ilist +:imap +:imapclear +:imenu +:import +:inoreabbrev +:inoremap +:inoremenu +:interface +:intro +:isearch +:isplit +:iunabbrev +:iunmap +:iunmenu +:join +:jumps +:k +:keepalt +:keepjumps +:keepmarks +:keeppatterns +:labove +:laddbuffer +:laddexpr +:laddfile +:lafter +:language +:last +:later +:lbefore +:lbelow +:lbottom +:lbuffer +:lcd +:lchdir +:lclose +:lcscope +:ldo +:left +:leftabove +:legacy +:lexpr +:lfdo +:lfile +:lfirst +:lgetbuffer +:lgetexpr +:lgetfile +:lgrep +:lgrepadd +:lhelpgrep +:lhistory +:list +:ll +:llast +:llist +:lmake +:lmap +:lmapclear +:lnewer +:lnext +:lNext +:lnfile +:lNfile +:lnoremap +:loadkeymap +:loadview +:lockmarks +:lockvar +:lolder +:lopen +:lpfile +:lprevious +:lrewind +:ls +:ltag +:lua +:luado +:luafile +:lunmap +:lvimgrep +:lvimgrepadd +:lwindow +:make +:mapclear +:map +:mark +:marks +:match +:menu +:menutranslate +:messages +:mkexrc +:mksession +:mkspell +:mkview +:mkvimrc +:move +:mzfile +:mzscheme +:nbclose +:nbkey +:nbstart +:new +:next +:nmap +:nmapclear +:nmenu +:nnoremap +:nnoremenu +:noautocmd +:nohlsearch +:noreabbrev +:noremap +:noremenu +:normal +:noswapfile +:number +:nunmap +:nunmenu +:oldfiles +:omap +:omapclear +:omenu +:only +:onoremap +:onoremenu +:options +:ounmap +:ounmenu +:ownsyntax +:packadd +:packloadall +:pclose +:pedit +:perl +:perldo +:pop +:popup +:ppop +:preserve +:previous +:print +:profdel +:profile +:promptfind +:promptrepl +:psearch +:ptag +:ptfirst +:ptjump +:ptlast +:ptnext +:ptNext +:ptprevious +:ptrewind +:ptselect +:public +:public +:put +:pwd +:py3 +:py3do +:py3file +:pydo +:pyfile +:python +:python3 +:pythonx +:pyx +:pyxdo +:pyxfile +:qall +:quit +:quitall +:read +:recover +:redir +:redo +:redraw +:redrawstatus +:redrawtabline +:registers +:resize +:retab +:return +:rewind +:right +:rightbelow +:ruby +:rubydo +:rubyfile +:rundo +:runtime +:rviminfo +:sall +:sandbox +:sargument +:saveas +:sball +:sbfirst +:sblast +:sbmodified +:sbnext +:sbNext +:sbprevious +:sbrewind +:sbuffer +:scriptencoding +:scriptnames +:scriptversion +:scscope +:set +:setfiletype +:setglobal +:setlocal +:sfind +:sfirst +:shell +:sign +:silent +:simalt +:slast +:sleep +:sleep! +:smagic +:smap +:smapclear +:smenu +:smile +:snext +:sNext +:snomagic +:snoremap +:snoremenu +:sort +:source +:spelldump +:spellgood +:spellinfo +:spellrare +:spellrepall +:spellundo +:spellwrong +:split +:sprevious +:srewind +:stag +:startgreplace +:startinsert +:startreplace +:static +:static +:stjump +:stop +:stopinsert +:stselect +:substitute +:sunhide +:sunmap +:sunmenu +:suspend +:sview +:swapname +:syncbind +:syntax +:syntime +:tab +:tabclose +:tabdo +:tabedit +:tabfind +:tabfirst +:tablast +:tabmove +:tabnew +:tabnext +:tabNext +:tabonly +:tabprevious +:tabrewind +:tabs +:tag +:tags +:tcd +:tchdir +:tcl +:tcldo +:tclfile +:tearoff +:terminal +:tfirst +:throw +:tjump +:tlast +:tlmenu +:tlnoremenu +:tlunmenu +:tmap +:tmapclear +:tmenu +:tnext +:tNext +:tnoremap +:topleft +:tprevious +:trewind +:try +:tselect +:tunmap +:tunmenu +:type +:unabbreviate +:unabbreviate +:undo +:undojoin +:undolist +:unhide +:unlockvar +:unmap +:unmenu +:unsilent +:update +:var +:verbose +:version +:vertical +:vglobal/.../ +:view +:vim9cmd +# :vim9script +:vimgrep +:vimgrepadd +:visual +:viusage +:vmap +:vmapclear +:vmenu +:vnew +:vnoremap +:vnoremenu +:vsplit +:vunmap +:vunmenu +:wall +:while +:wincmd +:windo +:winpos +:winsize +:wnext +:wNext +:wprevious +:wq +:wqall +:write +:wundo +:wviminfo +:xall +:xmap +:xmapclear +:xmenu +:xnoremap +:xnoremenu +:xrestore +:xunmap +:xunmenu +:yank +:z + +Foo()|help +Foo() | help +Foo() |help +Foo()| help + +Foo() | 2match +Foo() | 3match +Foo() | abbreviate +Foo() | abclear +Foo() | aboveleft +Foo() | abstract +Foo() | all +Foo() | amenu +Foo() | anoremenu +Foo() | argadd +Foo() | argdedupe +Foo() | argdelete +Foo() | argdo +Foo() | argedit +Foo() | argglobal +Foo() | arglocal +Foo() | args +Foo() | argument +Foo() | ascii +Foo() | augroup Foo | augroup END +Foo() | aunmenu +Foo() | autocmd +Foo() | badd +Foo() | ball +Foo() | balt +Foo() | bdelete +Foo() | behave mswin +Foo() | behave xterm +Foo() | belowright +Foo() | bfirst +Foo() | blast +Foo() | bmodified +Foo() | bnext +Foo() | bNext +Foo() | botright +Foo() | bprevious +Foo() | break +Foo() | breakadd +Foo() | breakdel +Foo() | breaklist +Foo() | brewind +Foo() | browse +Foo() | bufdo +Foo() | buffer +Foo() | buffers +Foo() | bunload +Foo() | bwipeout +Foo() | cabbrev +Foo() | cabclear +Foo() | cabove +Foo() | caddbuffer +Foo() | caddexpr +Foo() | caddfile +Foo() | cafter +Foo() | call +Foo() | catch +Foo() | cbefore +Foo() | cbelow +Foo() | cbottom +Foo() | cbuffer +Foo() | cc +Foo() | cclose +Foo() | cd +Foo() | cdo +Foo() | center +Foo() | cexpr +Foo() | cfdo +Foo() | cfile +Foo() | cfirst +Foo() | cgetbuffer +Foo() | cgetexpr +Foo() | cgetfile +Foo() | changes +Foo() | chdir +Foo() | checkpath +Foo() | checktime +Foo() | chistory +Foo() | class +Foo() | class +Foo() | clast +Foo() | clearjumps +Foo() | clist +Foo() | close +Foo() | cmap +Foo() | cmapclear +Foo() | cmenu +Foo() | cnewer +Foo() | cnext +Foo() | cNext +Foo() | cnfile +Foo() | cNfile +Foo() | cnoreabbrev +Foo() | cnoremap +Foo() | cnoremenu +Foo() | colder +Foo() | colorscheme +Foo() | comclear +Foo() | command +Foo() | compiler +Foo() | confirm +Foo() | const +Foo() | continue +Foo() | copen +Foo() | copy +Foo() | cpfile +Foo() | cprevious +Foo() | cquit +Foo() | crewind +Foo() | cscope +Foo() | cstag +Foo() | cunabbrev +Foo() | cunmap +Foo() | cunmenu +Foo() | cwindow +Foo() | debug +Foo() | debuggreedy +Foo() | def +Foo() | defcompile +Foo() | defcompile +Foo() | defer +Foo() | delcommand +Foo() | delete +Foo() | delfunction +Foo() | delmarks +Foo() | diffget +Foo() | diffoff +Foo() | diffpatch +Foo() | diffput +Foo() | diffsplit +Foo() | diffthis +Foo() | diffupdate +Foo() | digraphs +Foo() | disassemble +Foo() | disassemble +Foo() | display +Foo() | djump +Foo() | dl +Foo() | dlist +Foo() | doautoall +Foo() | doautocmd +Foo() | dp +Foo() | drop +Foo() | dsearch +Foo() | dsplit +Foo() | earlier +Foo() | echo +Foo() | echoconsole +Foo() | echoerr +Foo() | echohl +Foo() | echomsg +Foo() | echon +Foo() | echowindow +Foo() | edit +Foo() | else +Foo() | elseif +Foo() | emenu +Foo() | endclass +Foo() | endclass +Foo() | enddef +Foo() | endenum +Foo() | endfor +Foo() | endfunction +Foo() | endif +Foo() | endinterface +Foo() | endtry +Foo() | endwhile +Foo() | enew +Foo() | enum +Foo() | eval +Foo() | ex +Foo() | execute +Foo() | exit +Foo() | export +Foo() | export +Foo() | exusage +Foo() | file +Foo() | files +Foo() | filetype +Foo() | filter +Foo() | final +Foo() | finally +Foo() | find +Foo() | finish +Foo() | first +Foo() | fixdel +Foo() | fold +Foo() | foldclose +Foo() | folddoclosed +Foo() | folddoopen +Foo() | foldopen +Foo() | for +Foo() | function +Foo() | global/.../ +Foo() | goto +Foo() | grep +Foo() | grepadd +Foo() | gui +Foo() | gvim +Foo() | hardcopy +Foo() | help +Foo() | helpclose +Foo() | helpfind +Foo() | helpgrep +Foo() | helptags +Foo() | hide +Foo() | highlight +Foo() | history +Foo() | horizontal +Foo() | iabbrev +Foo() | iabclear +Foo() | if +Foo() | ijump +Foo() | ilist +Foo() | imap +Foo() | imapclear +Foo() | imenu +Foo() | import +Foo() | inoreabbrev +Foo() | inoremap +Foo() | inoremenu +Foo() | interface +Foo() | intro +Foo() | isearch +Foo() | isplit +Foo() | iunabbrev +Foo() | iunmap +Foo() | iunmenu +Foo() | join +Foo() | jumps +Foo() | keepalt +Foo() | keepjumps +Foo() | keepmarks +Foo() | keeppatterns +Foo() | labove +Foo() | laddbuffer +Foo() | laddexpr +Foo() | laddfile +Foo() | lafter +Foo() | language +Foo() | last +Foo() | later +Foo() | lbefore +Foo() | lbelow +Foo() | lbottom +Foo() | lbuffer +Foo() | lcd +Foo() | lchdir +Foo() | lclose +Foo() | lcscope +Foo() | ldo +Foo() | left +Foo() | leftabove +Foo() | legacy +Foo() | lexpr +Foo() | lfdo +Foo() | lfile +Foo() | lfirst +Foo() | lgetbuffer +Foo() | lgetexpr +Foo() | lgetfile +Foo() | lgrep +Foo() | lgrepadd +Foo() | lhelpgrep +Foo() | lhistory +Foo() | list +Foo() | ll +Foo() | llast +Foo() | llist +Foo() | lmake +Foo() | lmap +Foo() | lmapclear +Foo() | lnewer +Foo() | lnext +Foo() | lNext +Foo() | lnfile +Foo() | lNfile +Foo() | lnoremap +Foo() | loadkeymap +Foo() | loadview +Foo() | lockmarks +Foo() | lockvar +Foo() | lolder +Foo() | lopen +Foo() | lpfile +Foo() | lprevious +Foo() | lrewind +Foo() | ls +Foo() | ltag +Foo() | lua +Foo() | luado +Foo() | luafile +Foo() | lunmap +Foo() | lvimgrep +Foo() | lvimgrepadd +Foo() | lwindow +Foo() | make +Foo() | mark +Foo() | move +Foo() | map +Foo() | mapclear +Foo() | marks +Foo() | match +Foo() | menu +Foo() | menutranslate +Foo() | messages +Foo() | mkexrc +Foo() | mksession +Foo() | mkspell +Foo() | mkview +Foo() | mkvimrc +Foo() | mzfile +Foo() | mzscheme +Foo() | nbclose +Foo() | nbkey +Foo() | nbstart +Foo() | new +Foo() | next +Foo() | nmap +Foo() | nmapclear +Foo() | nmenu +Foo() | nnoremap +Foo() | nnoremenu +Foo() | noautocmd +Foo() | nohlsearch +Foo() | noreabbrev +Foo() | noremap +Foo() | noremenu +Foo() | normal +Foo() | noswapfile +Foo() | number +Foo() | nunmap +Foo() | nunmenu +Foo() | oldfiles +Foo() | omap +Foo() | omapclear +Foo() | omenu +Foo() | only +Foo() | onoremap +Foo() | onoremenu +Foo() | options +Foo() | ounmap +Foo() | ounmenu +Foo() | ownsyntax +Foo() | packadd +Foo() | packloadall +Foo() | pclose +Foo() | pedit +Foo() | perl +Foo() | perldo +Foo() | pop +Foo() | popup +Foo() | ppop +Foo() | preserve +Foo() | previous +Foo() | print +Foo() | profdel +Foo() | profile +Foo() | promptfind +Foo() | promptrepl +Foo() | psearch +Foo() | ptag +Foo() | ptfirst +Foo() | ptjump +Foo() | ptlast +Foo() | ptnext +Foo() | ptNext +Foo() | ptprevious +Foo() | ptrewind +Foo() | ptselect +Foo() | public +Foo() | public +Foo() | put +Foo() | pwd +Foo() | py3 +Foo() | py3do +Foo() | py3file +Foo() | pydo +Foo() | pyfile +Foo() | python +Foo() | python3 +Foo() | pythonx +Foo() | pyx +Foo() | pyxdo +Foo() | pyxfile +Foo() | qall +Foo() | quit +Foo() | quitall +Foo() | read +Foo() | recover +Foo() | redir +Foo() | redo +Foo() | redraw +Foo() | redrawstatus +Foo() | redrawtabline +Foo() | registers +Foo() | resize +Foo() | retab +Foo() | return +Foo() | rewind +Foo() | right +Foo() | rightbelow +Foo() | ruby +Foo() | rubydo +Foo() | rubyfile +Foo() | rundo +Foo() | runtime +Foo() | rviminfo +Foo() | sall +Foo() | sandbox +Foo() | sargument +Foo() | saveas +Foo() | sball +Foo() | sbfirst +Foo() | sblast +Foo() | sbmodified +Foo() | sbnext +Foo() | sbNext +Foo() | sbprevious +Foo() | sbrewind +Foo() | sbuffer +Foo() | scriptencoding +Foo() | scriptnames +Foo() | scriptversion +Foo() | scscope +Foo() | set +Foo() | setfiletype +Foo() | setglobal +Foo() | setlocal +Foo() | sfind +Foo() | sfirst +Foo() | shell +Foo() | sign +Foo() | silent +Foo() | simalt +Foo() | slast +Foo() | sleep +Foo() | sleep! +Foo() | smagic +Foo() | smap +Foo() | smapclear +Foo() | smenu +Foo() | smile +Foo() | snext +Foo() | sNext +Foo() | snomagic +Foo() | snoremap +Foo() | snoremenu +Foo() | sort +Foo() | source +Foo() | spelldump +Foo() | spellgood +Foo() | spellinfo +Foo() | spellrare +Foo() | spellrepall +Foo() | spellundo +Foo() | spellwrong +Foo() | split +Foo() | sprevious +Foo() | srewind +Foo() | stag +Foo() | startgreplace +Foo() | startinsert +Foo() | startreplace +Foo() | static +Foo() | static +Foo() | stjump +Foo() | stop +Foo() | stopinsert +Foo() | stselect +Foo() | substitute +Foo() | sunhide +Foo() | sunmap +Foo() | sunmenu +Foo() | suspend +Foo() | sview +Foo() | swapname +Foo() | syncbind +Foo() | syntax +Foo() | syntime +Foo() | tab +Foo() | tabclose +Foo() | tabdo +Foo() | tabedit +Foo() | tabfind +Foo() | tabfirst +Foo() | tablast +Foo() | tabmove +Foo() | tabnew +Foo() | tabnext +Foo() | tabNext +Foo() | tabonly +Foo() | tabprevious +Foo() | tabrewind +Foo() | tabs +Foo() | tag +Foo() | tags +Foo() | tcd +Foo() | tchdir +Foo() | tcl +Foo() | tcldo +Foo() | tclfile +Foo() | tearoff +Foo() | terminal +Foo() | tfirst +Foo() | throw +Foo() | tjump +Foo() | tlast +Foo() | tlmenu +Foo() | tlnoremenu +Foo() | tlunmenu +Foo() | tmap +Foo() | tmapclear +Foo() | tmenu +Foo() | tnext +Foo() | tNext +Foo() | tnoremap +Foo() | topleft +Foo() | tprevious +Foo() | trewind +Foo() | try +Foo() | tselect +Foo() | tunmap +Foo() | tunmenu +Foo() | type +Foo() | unabbreviate +Foo() | unabbreviate +Foo() | undo +Foo() | undojoin +Foo() | undolist +Foo() | unhide +Foo() | unlockvar +Foo() | unmap +Foo() | unmenu +Foo() | unsilent +Foo() | update +Foo() | var +Foo() | verbose +Foo() | version +Foo() | vertical +Foo() | vglobal/.../ +Foo() | vim9cmd +# call Foo() | vim9script +Foo() | vimgrep +Foo() | vimgrepadd +Foo() | visual +Foo() | viusage +Foo() | view +Foo() | vmap +Foo() | vmapclear +Foo() | vmenu +Foo() | vnew +Foo() | vnoremap +Foo() | vnoremenu +Foo() | vsplit +Foo() | vunmap +Foo() | vunmenu +Foo() | windo +Foo() | write +Foo() | wNext +Foo() | wall +Foo() | while +Foo() | winsize +Foo() | wincmd +Foo() | winpos +Foo() | wnext +Foo() | wprevious +Foo() | wq +Foo() | wqall +Foo() | wundo +Foo() | wviminfo +Foo() | xall +Foo() | xmapclear +Foo() | xmap +Foo() | xmenu +Foo() | xrestore +Foo() | xnoremap +Foo() | xnoremenu +Foo() | xunmap +Foo() | xunmenu +Foo() | yank +Foo() | z + + +# Legacy-script only + +:Print +:append + text +. +:change + text +. +:insert + text +. +:k +:let +:mode +:open +:t +:unlet +:xit + +Foo() | append + text +. +Foo() | change + text +. +Foo() | insert + text +. +Foo() | k +Foo() | let +Foo() | mode +Foo() | open +Foo() | t +Foo() | unlet +Foo() | xit + 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 0000000000..fd02c1a60a --- /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_function_def_tail_comment_errors.vim b/runtime/syntax/testdir/input/vim9_ex_function_def_tail_comment_errors.vim new file mode 100644 index 0000000000..b4b9f6de0f --- /dev/null +++ b/runtime/syntax/testdir/input/vim9_ex_function_def_tail_comment_errors.vim @@ -0,0 +1,44 @@ +vim9script + +# Vim9 :function and :def tail comment errors +# VIM_TEST_SETUP unlet! g:vimsyn_folding + +fun Test1() abort # fun + return 1 +endfun # endfun + +def Test2(): number " def + return 2 +enddef " enddef + +fun Test3() abort # fun + fun s:DoTest3() abort # fun + return 3 + endfun # endfun + return s:DoTest3() +endfun # endfun + +def Test4(): number " def + def DoTest4(): number " def + return 4 + enddef " enddef + return DoTest4() +enddef " enddef + +def Test5(): number " def + fun DoTest5() abort # fun + return 5 + endfun # endfun + return DoTest5() +enddef " enddef + +fun Test6() abort # fun + def s:DoTest6(): number " def + return 6 + enddef " enddef + return s:DoTest6() +endfun # endfun + +for d in range(1, 6) + exec $'echo Test{d}()' +endfor diff --git a/runtime/syntax/testdir/input/vim9_ex_function_def_tail_comments.vim b/runtime/syntax/testdir/input/vim9_ex_function_def_tail_comments.vim new file mode 100644 index 0000000000..12f7942cf1 --- /dev/null +++ b/runtime/syntax/testdir/input/vim9_ex_function_def_tail_comments.vim @@ -0,0 +1,44 @@ +vim9script + +# Vim9 :function and :def tail comments +# VIM_TEST_SETUP unlet! g:vimsyn_folding + +fun Test1() abort " fun + return 1 +endfun " endfun + +def Test2(): number # def + return 2 +enddef # enddef + +fun Test3() abort " fun + fun s:DoTest3() abort " fun + return 3 + endfun " endfun + return s:DoTest3() +endfun " endfun + +def Test4(): number # def + def DoTest4(): number # def + return 4 + enddef # enddef + return DoTest4() +enddef # enddef + +def Test5(): number # def + fun DoTest5() abort " fun + return 5 + endfun " endfun + return DoTest5() +enddef # enddef + +fun Test6() abort " fun + def s:DoTest6(): number # def + return 6 + enddef # enddef + return s:DoTest6() +endfun " endfun + +for d in range(1, 6) + exec $'echo Test{d}()' +endfor 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 0000000000..dcea14d28d --- /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_keymap.vim b/runtime/syntax/testdir/input/vim9_keymap.vim index a69b723a73..1c59e56ae0 100644 --- a/runtime/syntax/testdir/input/vim9_keymap.vim +++ b/runtime/syntax/testdir/input/vim9_keymap.vim @@ -4,7 +4,7 @@ vim9script scriptencoding utf-8 -let b:keymap_name = "syntax-test" +b:keymap_name = "syntax-test" loadkeymap diff --git a/runtime/syntax/testdir/input/vim9_shebang.vim b/runtime/syntax/testdir/input/vim9_shebang.vim new file mode 100755 index 0000000000..c012fd9fc9 --- /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 similarity index 69% rename from runtime/syntax/testdir/input/vim_ex_comment.vim rename to runtime/syntax/testdir/input/vim_comment.vim index 54e514eaa3..f382f8df79 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_call.vim b/runtime/syntax/testdir/input/vim_ex_call.vim new file mode 100644 index 0000000000..ae6bdc99e8 --- /dev/null +++ b/runtime/syntax/testdir/input/vim_ex_call.vim @@ -0,0 +1,51 @@ +" Vim :call command + + +" functions for which there are same-named Ex commands + +call browse(save, title, initdir, default) +call call(func, arglist, dict) +call chdir(dir) +call confirm(msg, choices, default, type) +call copy(expr) +call delete(fname, flags) +call eval(string) +call execute(command) +call filter(expr1, expr2) +call function(name, arglist, dict) +call insert(object, item, idx) +call join(list, sep) +call map(expr1, expr2) +call match(expr, pat, start, count) +call mode(expr) +call sort(list, how, dict) +call split(string, pattern, keepempty) +call substitute(str, pat, sub, flags) +call swapname(buf) + +call browse (save, title, initdir, default) +call call (func, arglist, dict) +call chdir (dir) +call confirm (msg, choices, default, type) +call copy (expr) +call delete (fname, flags) +call eval (string) +call execute (command) +call filter (expr1, expr2) +call function (name, arglist, dict) +call insert (object, item, idx) +call join (list, sep) +call map (expr1, expr2) +call match (expr, pat, start, count) +call mode (expr) +call sort (list, how, dict) +call split (string, pattern, keepempty) +call substitute (str, pat, sub, flags) +call swapname (buf) + +call Foo() +call Foo(arg1) +call Foo(arg1, arg2) + +let res = call(func, arglist, dict) +let res = call (func, arglist, dict) 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 0000000000..f0e2a8fdc3 --- /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_commands.vim b/runtime/syntax/testdir/input/vim_ex_commands.vim index aaa351bd33..6ed7b3eac4 100644 --- a/runtime/syntax/testdir/input/vim_ex_commands.vim +++ b/runtime/syntax/testdir/input/vim_ex_commands.vim @@ -98,7 +98,6 @@ :checkpath :checktime :chistory -:class :clast :clearjumps :clist @@ -172,7 +171,6 @@ :else :elseif :emenu -:endclass :enddef :endif :endfor @@ -184,7 +182,6 @@ :ex :execute :exit -:export :exusage :file :files @@ -313,8 +310,7 @@ :move :mark :make -" requires trailing whitespace to distinguish from map() -:map +:map :mapclear :marks :match @@ -553,12 +549,10 @@ :unsilent :update :vglobal/.../ -:var :version :verbose :vertical :vim9cmd -" :vim9script :vimgrep :vimgrepadd :visual @@ -691,7 +685,6 @@ call Foo() | chdir call Foo() | checkpath call Foo() | checktime call Foo() | chistory -call Foo() | class call Foo() | clast call Foo() | clearjumps call Foo() | clist @@ -765,7 +758,6 @@ call Foo() | echowindow call Foo() | else call Foo() | elseif call Foo() | emenu -call Foo() | endclass call Foo() | enddef call Foo() | endif call Foo() | endfor @@ -777,7 +769,6 @@ call Foo() | eval call Foo() | ex call Foo() | execute call Foo() | exit -call Foo() | export call Foo() | exusage call Foo() | file call Foo() | files @@ -907,8 +898,7 @@ call Foo() | lwindow call Foo() | move call Foo() | mark call Foo() | make -" requires trailing whitespace to distinguish from map() -call Foo() | map +call Foo() | map call Foo() | mapclear call Foo() | marks call Foo() | match @@ -1147,12 +1137,10 @@ call Foo() | unmenu call Foo() | unsilent call Foo() | update call Foo() | vglobal/.../ -call Foo() | var call Foo() | version call Foo() | verbose call Foo() | vertical call Foo() | vim9cmd -" call Foo() | vim9script call Foo() | vimgrep call Foo() | vimgrepadd call Foo() | visual @@ -1193,3 +1181,39 @@ call Foo() | xunmap call Foo() | xunmenu call Foo() | yank call Foo() | z + + +" Vim9-script only + +:abstract +:class +:defcompile +:disassemble +:endclass +:endinterface +:endenum +:enum +:export +:final +:interface +:public +:static +:type +:var + +Foo() | abstract +Foo() | class +Foo() | defcompile +Foo() | disassemble +Foo() | endclass +Foo() | endenum +Foo() | endinterface +Foo() | enum +Foo() | export +Foo() | final +Foo() | interface +Foo() | public +Foo() | static +Foo() | type +Foo() | var + 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 0000000000..4214d6b3a0 --- /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_def.vim b/runtime/syntax/testdir/input/vim_ex_def.vim index 2685ba5fd1..a1d538158e 100644 --- a/runtime/syntax/testdir/input/vim_ex_def.vim +++ b/runtime/syntax/testdir/input/vim_ex_def.vim @@ -85,7 +85,7 @@ def Foo() enddef | echo "Foo" def Foo() -enddef " comment +enddef # comment " parameters diff --git a/runtime/syntax/testdir/input/vim_ex_def_fold.vim b/runtime/syntax/testdir/input/vim_ex_def_fold.vim index 3326075a3e..d85f273523 100644 --- a/runtime/syntax/testdir/input/vim_ex_def_fold.vim +++ b/runtime/syntax/testdir/input/vim_ex_def_fold.vim @@ -86,7 +86,7 @@ def Foo() enddef | echo "Foo" def Foo() -enddef " comment +enddef # comment " parameters diff --git a/runtime/syntax/testdir/input/vim_ex_function_def_tail_comment_errors.vim b/runtime/syntax/testdir/input/vim_ex_function_def_tail_comment_errors.vim new file mode 100644 index 0000000000..e5d746439a --- /dev/null +++ b/runtime/syntax/testdir/input/vim_ex_function_def_tail_comment_errors.vim @@ -0,0 +1,43 @@ +" Vim :function and :def tail comment errors +" VIM_TEST_SETUP unlet! g:vimsyn_folding + +fun s:Test1() abort # fun + return 1 +endfun # endfun + +def s:Test2(): number " def + return 2 +enddef " enddef + +fun s:Test3() abort # fun + fun s:DoTest3() abort # fun + return 3 + endfun # endfun + return s:DoTest3() +endfun # endfun + +def s:Test4(): number " def + def DoTest4(): number " def + return 4 + enddef " enddef + return DoTest4() +enddef " enddef + +def s:Test5(): number " def + fun DoTest5() abort # fun + return 5 + endfun # endfun + return DoTest5() +enddef " enddef + +fun s:Test6() abort # fun + def s:DoTest6(): number " def + return 6 + enddef " enddef + return s:DoTest6() +endfun # endfun + +for d in range(1, 6)->reverse() + exec $'echo s:Test{d}()' + exec $'delfunction s:Test{d}' +endfor diff --git a/runtime/syntax/testdir/input/vim_ex_function_def_tail_comments.vim b/runtime/syntax/testdir/input/vim_ex_function_def_tail_comments.vim new file mode 100644 index 0000000000..e46bf752e6 --- /dev/null +++ b/runtime/syntax/testdir/input/vim_ex_function_def_tail_comments.vim @@ -0,0 +1,43 @@ +" Vim :function and :def tail comments +" VIM_TEST_SETUP unlet! g:vimsyn_folding + +fun s:Test1() abort " fun + return 1 +endfun " endfun + +def s:Test2(): number # def + return 2 +enddef # enddef + +fun s:Test3() abort " fun + fun s:DoTest3() abort " fun + return 3 + endfun " endfun + return s:DoTest3() +endfun " endfun + +def s:Test4(): number # def + def DoTest4(): number # def + return 4 + enddef # enddef + return DoTest4() +enddef # enddef + +def s:Test5(): number # def + fun DoTest5() abort " fun + return 5 + endfun " endfun + return DoTest5() +enddef # enddef + +fun s:Test6() abort " fun + def s:DoTest6(): number # def + return 6 + enddef # enddef + return s:DoTest6() +endfun " endfun + +for d in range(1, 6)->reverse() + exec $'echo s:Test{d}()' + exec $'delfunction s:Test{d}' +endfor diff --git a/runtime/syntax/testdir/input/vim_ex_map.vim b/runtime/syntax/testdir/input/vim_ex_map.vim index 95f42922e3..3ddc9e9a8d 100644 --- a/runtime/syntax/testdir/input/vim_ex_map.vim +++ b/runtime/syntax/testdir/input/vim_ex_map.vim @@ -5,9 +5,6 @@ map! lhs rhs map map lhs rhs -call map(list, 'v:val') -call map (list, 'v:val') - mapclear <buffer> mapclear! <buffer> nmapclear <buffer> @@ -69,6 +66,27 @@ map lhs echo "clear" +" Differentiate map() from :map + +map ( :echo "open-paren"<CR> + +call map(list, 'v:val') +call map (list, 'v:val') + +function Foo() + map ( :echo "open-paren"<CR> + call map(list, 'v:val') + call map (list, 'v:val') +endfunction + +def Foo() + map ( :echo "open-paren"<CR> + map(list, 'v:val') + # :map LHS=(list, RHS='v:val') + map (list, 'v:val') +enddef + + " Issue #12672 nnoremap <leader>foo :echo call( diff --git a/runtime/syntax/testdir/input/vim_ex_match.vim b/runtime/syntax/testdir/input/vim_ex_match.vim new file mode 100644 index 0000000000..8d1462820c --- /dev/null +++ b/runtime/syntax/testdir/input/vim_ex_match.vim @@ -0,0 +1,32 @@ +" Vim :match, :2match and :3match commands + +match FooGroup /Foo/ +match +match none + +2match FooGroup /Foo/ +2match +2match none + +3match FooGroup /Foo/ +3match +3match none + + +" Differentiate map() from :map + +call match(haystack, 'needle') +call match (haystack, 'needle') + +function Foo() + match FooGroup /Foo/ + call match(haystack, 'needle') + call match (haystack, 'needle') +endfunction + +def Foo() + match FooGroup /Foo/ + match(haystack, 'needle') + # Error: bad :match command - trailing characters + match (haystack, 'needle') +enddef 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 0000000000..d9b53b3a30 --- /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 0000000000..49fd31e80c --- /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 340d573ac1..021060a0c8 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 0000000000..4adbc88485 --- /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_keymap.vim b/runtime/syntax/testdir/input/vim_keymap.vim index 424d437a67..029bc768ae 100644 --- a/runtime/syntax/testdir/input/vim_keymap.vim +++ b/runtime/syntax/testdir/input/vim_keymap.vim @@ -1,27 +1,24 @@ -" Vim Keymap file for syntax testing - -" Maintainer: Doug Kearns <dougkearns@gmail.com> -" Last Changed: 2023 Nov 21 - -scriptencoding utf-8 - -let b:keymap_name = "syntax-test" - -loadkeymap - -" Line comment - - " Another line comment - -a A Basic mapping -'a á More than one char in first column - -" Special notation -<char-62> B Special notation allowed in LHS - decimal -c <char-0103> Special notation allowed in RHS - octal -<char-0x0064> <char-0x0044> Special notation allowed in LHS and RHS - hexadecimal - -" Vim-script comment characters +" Vim Keymap file for syntax testing + +scriptencoding utf-8 + +let b:keymap_name = "syntax-test" + +loadkeymap + +" Line comment + + " Another line comment + +a A Basic mapping +'a á More than one char in first column + +" Special notation +<char-62> B Special notation allowed in LHS - decimal +c <char-0103> Special notation allowed in RHS - octal +<char-0x0064> <char-0x0044> Special notation allowed in LHS and RHS - hexadecimal + +" Vim-script comment characters # <char-0x00a3> Line should not match as a Vim9-script comment -\" “ Line should not match as a legacy-script comment +\" “ Line should not match as a legacy-script comment : " Line should not match as a legacy-script comment diff --git a/runtime/syntax/testdir/input/vim_shebang.vim b/runtime/syntax/testdir/input/vim_shebang.vim new file mode 100755 index 0000000000..47a550cf5a --- /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/testdir/input/yaml.yaml b/runtime/syntax/testdir/input/yaml.yaml index d87aca2113..72e0a0dd4f 100644 --- a/runtime/syntax/testdir/input/yaml.yaml +++ b/runtime/syntax/testdir/input/yaml.yaml @@ -24,7 +24,7 @@ not a number: [.nan, .NaN, .NAN] plain strings: - a b c - - a * b & c @ d# e : f # comment + - a:b & c @ d# e * f # comment - {{ f(' ') }} #8234 double quoted strings: - "" @@ -91,9 +91,10 @@ flow collection: inside block mapping: foo: {bar: baz} bar: ["foo": {baz: qux}] - flow collection: [foo # comment + flow:collection: [foo # comment , {bar: [{ # comment - baz: ' + baz: + ' qux # not comment ' # comment }]}] diff --git a/runtime/syntax/testdir/runtest.vim b/runtime/syntax/testdir/runtest.vim index e1cfdcfe1c..7c48b3fb17 100644 --- a/runtime/syntax/testdir/runtest.vim +++ b/runtime/syntax/testdir/runtest.vim @@ -85,6 +85,28 @@ func HandleSwapExists() endif endfunc +def IsWinNumOneAtEOF(in_name_and_out_name: string): bool + # Expect defaults from term_util#RunVimInTerminal(). + if winwidth(1) != 75 || winheight(1) != 20 + ch_log(printf('Aborting for %s: (75 x 20) != (%d x %d)', + in_name_and_out_name, + winwidth(1), + winheight(1))) + return true + endif + # A two-fold role: (1) redraw whenever the first test file is of 19 lines or + # less long (not applicable to c.c); (2) redraw in case the terminal buffer + # cannot redraw itself just yet (else expect extra files generated). + redraw + const pos: string = join([ + screenstring(20, 71), + screenstring(20, 72), + screenstring(20, 73), + screenstring(20, 74), + screenstring(20, 75)], '') + return (pos == ' All ' || pos == ' Bot ') +enddef + func RunTest() let ok_count = 0 let failed_tests = [] @@ -94,14 +116,17 @@ func RunTest() let setup = glob('input/setup/*.vim', 1, 1) \ ->reduce({d, f -> extend(d, {fnamemodify(f, ':t:r'): f})}, {}) - for fname in glob('input/*.*', 1, 1) - if fname =~ '\~$' - " backup file, skip - continue - endif + if exists("$VIM_SYNTAX_SELF_TESTING") + let dirpath = 'input/selftestdir/' + let fnames = readdir(dirpath, {fname -> fname !~ '^README.txt$'}) + else + let dirpath = 'input/' + let fnames = readdir(dirpath, {fname -> fname !~ '\~$' && fname =~ '^.\+\..\+$'}) + endif - let linecount = readfile(fname)->len() - let root = fnamemodify(fname, ':t:r') + for fname in fnames + let root = fnamemodify(fname, ':r') + let fname = dirpath .. fname let filetype = substitute(root, '\([^_.]*\)[_.].*', '\1', '') let failed_root = 'failed/' .. root @@ -118,6 +143,10 @@ func RunTest() call delete('done/' .. root) let lines =<< trim END + " Track the cursor progress through a syntax test file so that any + " degenerate input can be reported. Each file will have its own cursor. + let s:cursor = 1 + " extra info for shell variables func ShellInfo() let msg = '' @@ -160,11 +189,111 @@ func RunTest() call cursor(1, 1) " BEGIN [runtime/defaults.vim] " Also, disable italic highlighting to avoid issues on some terminals. - set display=truncate ruler scrolloff=5 t_ZH= t_ZR= + set display=lastline ruler scrolloff=5 t_ZH= t_ZR= syntax on " END [runtime/defaults.vim] redraw! endfunc + + def s:AssertCursorForwardProgress(): bool + const curnum: number = line('.') + if curnum <= cursor + # Use "actions/upload-artifact@v4" of ci.yml for delivery. + writefile([printf('No cursor progress: %d <= %d (%s). Please file an issue.', + curnum, + cursor, + bufname('%'))], + 'failed/00-FIXME', + 'a') + bwipeout! + endif + cursor = curnum + return true + enddef + + def ScrollToSecondPage(estate: number, op_wh: number, op_so: number): bool + if line('.') != 1 || line('w$') >= line('$') + return AssertCursorForwardProgress() + endif + try + set scrolloff=0 + # Advance mark "c"[ursor] along with the cursor. + norm! Lmc + if foldclosed('.') < 0 && + (strdisplaywidth(getline('.')) + &l:fdc * winheight(1)) >= estate + # Make for an exit for a screenful long line. + norm! j^ + return AssertCursorForwardProgress() + else + # Place the cursor on the actually last visible line. + while winline() < op_wh + const lastnum: number = winline() + norm! gjmc + if lastnum > winline() + break + endif + endwhile + norm! zt + endif + finally + # COMPATIBILITY: Scroll up around "scrolloff" lines. + &scrolloff = max([1, op_so]) + endtry + norm! ^ + return AssertCursorForwardProgress() + enddef + + def ScrollToNextPage(estate: number, op_wh: number, op_so: number): bool + if line('.') == 1 || line('w$') >= line('$') + return AssertCursorForwardProgress() + endif + try + set scrolloff=0 + # Advance mark "c"[ursor] along with the cursor. + norm! Lmc + if foldclosed('.') < 0 && + (strdisplaywidth(getline('.')) + &l:fdc * winheight(1)) >= estate + # Make for an exit for a screenful long line. + norm! j^ + return AssertCursorForwardProgress() + else + # Place the cursor on the actually last visible line. + while winline() < op_wh + const lastnum: number = winline() + norm! gjmc + if lastnum > winline() + break + endif + endwhile + endif + finally + # COMPATIBILITY: Scroll up/down around "scrolloff" lines. + &scrolloff = max([1, op_so]) + endtry + norm! zt + const marknum: number = line("'c") + # Eschew &smoothscroll since line("`c") is not supported. + # Remember that "w0" can point to the first line of a _closed_ fold + # whereas the last line of a _closed_ fold can be marked. + if line('w0') > marknum + while line('w0') > marknum + exe "norm! \<C-y>" + endwhile + if line('w0') != marknum + exe "norm! \<C-e>H" + endif + # Handle non-wrapped lines. + elseif line('w0') < marknum + while line('w0') < marknum + exe "norm! \<C-e>" + endwhile + if line('w0') != marknum + exe "norm! \<C-y>H" + endif + endif + norm! ^ + return AssertCursorForwardProgress() + enddef END call writefile(lines, 'Xtestscript') @@ -198,34 +327,39 @@ func RunTest() " Screendump at the start of the file: failed/root_00.dump let root_00 = root .. '_00' - call ch_log('First screendump for ' .. fname .. ': failed/' .. root_00 .. '.dump') + let in_name_and_out_name = fname .. ': failed/' .. root_00 .. '.dump' + call ch_log('First screendump for ' .. in_name_and_out_name) let fail = VerifyScreenDump(buf, root_00, {}) - " clear the shell info if there are not enough lines to cause a scroll - if filetype == 'sh' && linecount <= 19 - call term_sendkeys(buf, ":redraw\<CR>") - endif - " Make a Screendump every 18 lines of the file: failed/root_NN.dump - let topline = 1 let nr = 1 - while linecount - topline > 20 - let topline += 18 - call term_sendkeys(buf, printf("%dGzt", topline)) - let root_next = root .. printf('_%02d', nr) - call ch_log('Next screendump for ' .. fname .. ': failed/' .. root_next .. '.dump') - let fail += VerifyScreenDump(buf, root_next, {}) - let nr += 1 - endwhile - - " Screendump at the end of the file: failed/root_99.dump - call term_sendkeys(buf, 'Gzb') - let root_last = root .. '_99' - call ch_log('Last screendump for ' .. fname .. ': failed/' .. root_last .. '.dump') - let fail += VerifyScreenDump(buf, root_last, {}) - - call StopVimInTerminal(buf) - call delete('Xtestscript') + let root_next = printf('%s_%02d', root, nr) + let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump' + + " Accommodate the next code block to "buf"'s contingency for self + " wipe-out. + try + if !IsWinNumOneAtEOF(in_name_and_out_name) + call term_sendkeys(buf, ":call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR>") + call ch_log('Next screendump for ' .. in_name_and_out_name) + let fail += VerifyScreenDump(buf, root_next, {}) + let nr += 1 + let root_next = printf('%s_%02d', root, nr) + let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump' + + while !IsWinNumOneAtEOF(in_name_and_out_name) + call term_sendkeys(buf, ":call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR>") + call ch_log('Next screendump for ' .. in_name_and_out_name) + let fail += VerifyScreenDump(buf, root_next, {}) + let nr += 1 + let root_next = printf('%s_%02d', root, nr) + let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump' + endwhile + endif + call StopVimInTerminal(buf) + finally + call delete('Xtestscript') + endtry " redraw here to avoid the following messages to get mixed up with screen " output. diff --git a/runtime/syntax/tmux.vim b/runtime/syntax/tmux.vim index 9766ed55d7..80636f2c58 100644 --- a/runtime/syntax/tmux.vim +++ b/runtime/syntax/tmux.vim @@ -1,5 +1,5 @@ " Language: tmux(1) configuration file -" Version: 3.4 (git-608d1134) +" Version: 3.4 (git-171004df) " URL: https://github.com/ericpruitt/tmux.vim/ " Maintainer: Eric Pruitt <eric.pruitt@gmail.com> " License: 2-Clause BSD (http://opensource.org/licenses/BSD-2-Clause) @@ -28,7 +28,7 @@ syn match tmuxKey /\(C-\|M-\|\^\)\+\S\+/ display syn match tmuxNumber /\<\d\+\>/ display syn match tmuxFlags /\s-\a\+/ display syn match tmuxVariableExpansion /\$\({[A-Za-z_]\w*}\|[A-Za-z_]\w*\)/ display -syn match tmuxControl /\(^\|\s\)%\(if\|elif\|else\|endif\)\($\|\s\)/ display +syn match tmuxControl /\(^\|\s\)%\(if\|elif\|else\|endif\|hidden\)\($\|\s\)/ display syn match tmuxEscape /\\\(u\x\{4\}\|U\x\{8\}\|\o\{3\}\|[\\ernt$]\)/ display " Missing closing bracket. @@ -99,11 +99,11 @@ syn keyword tmuxOptions \ after-set-environment after-set-hook after-set-option after-show-environment \ after-show-messages after-show-options after-split-window after-unbind-key \ aggressive-resize alert-activity alert-bell alert-silence allow-passthrough -\ allow-rename alternate-screen assume-paste-time automatic-rename -\ automatic-rename-format backspace base-index bell-action buffer-limit -\ client-active client-attached client-detached client-focus-in +\ allow-rename allow-set-title alternate-screen assume-paste-time +\ automatic-rename automatic-rename-format backspace base-index bell-action +\ buffer-limit client-active client-attached client-detached client-focus-in \ client-focus-out client-resized client-session-changed clock-mode-color -\ clock-mode-colour clock-mode-style command-alias copy-command +\ clock-mode-colour clock-mode-style command-alias command-error copy-command \ copy-mode-current-match-style copy-mode-mark-style copy-mode-match-style \ cursor-color cursor-colour cursor-style default-command default-shell \ default-size default-terminal destroy-unattached detach-on-destroy diff --git a/runtime/syntax/tsv.vim b/runtime/syntax/tsv.vim new file mode 100644 index 0000000000..f0dd9f717d --- /dev/null +++ b/runtime/syntax/tsv.vim @@ -0,0 +1,12 @@ +" Vim filetype plugin file +" Language: Tab separated values (TSV) +" Last Change: 2024 Jul 16 +" This runtime file is looking for a new maintainer. + +if exists('b:current_syntax') + finish +endif + +let b:csv_delimiter = '\t' " enforce tab delimiter +runtime! syntax/csv.vim +let b:current_syntax = 'tsv' diff --git a/runtime/syntax/typescript.vim b/runtime/syntax/typescript.vim index 5389c21497..03520fd56a 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 1c510459f5..061ec4d81e 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/typst.vim b/runtime/syntax/typst.vim new file mode 100644 index 0000000000..82fdadb3d5 --- /dev/null +++ b/runtime/syntax/typst.vim @@ -0,0 +1,472 @@ +" Vim syntax file +" Language: Typst +" Maintainer: Gregory Anders <greg@gpanders.com> +" Last Change: 2024-07-14 +" Based on: https://github.com/kaarmu/typst.vim + +if exists('b:current_syntax') + finish +endif + +syntax sync fromstart +syntax spell toplevel + +" Common {{{1 +syntax cluster typstCommon + \ contains=@typstComment + +" Common > Comment {{{2 +syntax cluster typstComment + \ contains=typstCommentBlock,typstCommentLine +syntax match typstCommentBlock + \ #/\*\%(\_.\{-}\)\*/# + \ contains=typstCommentTodo,@Spell +syntax match typstCommentLine + \ #//.*# + \ contains=typstCommentTodo,@Spell +syntax keyword typstCommentTodo + \ contained + \ TODO FIXME XXX TBD + + +" Code {{{1 +syntax cluster typstCode + \ contains=@typstCommon + \ ,@typstCodeKeywords + \ ,@typstCodeConstants + \ ,@typstCodeIdentifiers + \ ,@typstCodeFunctions + \ ,@typstCodeParens + +" Code > Keywords {{{2 +syntax cluster typstCodeKeywords + \ contains=typstCodeConditional + \ ,typstCodeRepeat + \ ,typstCodeKeyword + \ ,typstCodeStatement +syntax keyword typstCodeConditional + \ contained + \ if else +syntax keyword typstCodeRepeat + \ contained + \ while for +syntax keyword typstCodeKeyword + \ contained + \ not in and or return +syntax region typstCodeStatement + \ contained + \ matchgroup=typstCodeStatementWord start=/\v(let|set|import|include)>/ + \ matchgroup=Noise end=/\v%(;|$)/ + \ contains=@typstCode +syntax region typstCodeStatement + \ contained + \ matchgroup=typstCodeStatementWord start=/show/ + \ matchgroup=Noise end=/\v%(:|$)/ keepend + \ contains=@typstCode + \ skipwhite nextgroup=@typstCode,typstCodeShowRocket +syntax match typstCodeShowRocket + \ contained + \ /.*=>/ + \ contains=@typstCode + \ skipwhite nextgroup=@typstCode + +" Code > Identifiers {{{2 +syntax cluster typstCodeIdentifiers + \ contains=typstCodeIdentifier + \ ,typstCodeFieldAccess +syntax match typstCodeIdentifier + \ contained + \ /\v\w\k*>(<%(let|set|show|import|include))@<![\.\[\(]@!/ +syntax match typstCodeFieldAccess + \ contained + \ /\v\w\k*>(<%(let|set|show|import|include))@<!\.[\[\(]@!/ + \ nextgroup=typstCodeFieldAccess,typstCodeFunction + +" Code > Functions {{{2 +syntax cluster typstCodeFunctions + \ contains=typstCodeFunction +syntax match typstCodeFunction + \ contained + \ /\v\w\k*>(<%(let|set|show|import|include))@<![\(\[]@=/ + \ nextgroup=typstCodeFunctionArgument +syntax match typstCodeFunctionArgument + \ contained + \ /\v%(%(\(.{-}\)|\[.{-}\]|\{.{-}\}))*/ transparent + \ contains=@typstCode + +" Code > Constants {{{2 +syntax cluster typstCodeConstants + \ contains=typstCodeConstant + \ ,typstCodeNumberInteger + \ ,typstCodeNumberFloat + \ ,typstCodeNumberLength + \ ,typstCodeNumberAngle + \ ,typstCodeNumberRatio + \ ,typstCodeNumberFraction + \ ,typstCodeString + \ ,typstCodeLabel +syntax match typstCodeConstant + \ contained + \ /\v<%(none|auto|true|false)-@!>/ +syntax match typstCodeNumberInteger + \ contained + \ /\v<\d+>/ + +syntax match typstCodeNumberFloat + \ contained + \ /\v<\d+\.\d*>/ +syntax match typstCodeNumberLength + \ contained + \ /\v<\d+(\.\d*)?(pt|mm|cm|in|em)>/ +syntax match typstCodeNumberAngle + \ contained + \ /\v<\d+(\.\d*)?(deg|rad)>/ +syntax match typstCodeNumberRatio + \ contained + \ /\v<\d+(\.\d*)?\%/ +syntax match typstCodeNumberFraction + \ contained + \ /\v<\d+(\.\d*)?fr>/ +syntax region typstCodeString + \ contained + \ start=/"/ skip=/\v\\\\|\\"/ end=/"/ + \ contains=@Spell +syntax match typstCodeLabel + \ contained + \ /\v\<\K%(\k*-*)*\>/ + +" Code > Parens {{{2 +syntax cluster typstCodeParens + \ contains=typstCodeParen + \ ,typstCodeBrace + \ ,typstCodeBracket + \ ,typstCodeDollar + \ ,typstMarkupRawInline + \ ,typstMarkupRawBlock +syntax region typstCodeParen + \ contained + \ matchgroup=Noise start=/(/ end=/)/ + \ contains=@typstCode +syntax region typstCodeBrace + \ contained + \ matchgroup=Noise start=/{/ end=/}/ + \ contains=@typstCode +syntax region typstCodeBracket + \ contained + \ matchgroup=Noise start=/\[/ end=/\]/ + \ contains=@typstMarkup +syntax region typstCodeDollar + \ contained + \ matchgroup=Number start=/\\\@<!\$/ end=/\\\@<!\$/ + \ contains=@typstMath + + +" Hashtag {{{1 +syntax cluster typstHashtag + \ contains=@typstHashtagKeywords + \ ,@typstHashtagConstants + \ ,@typstHashtagIdentifiers + \ ,@typstHashtagFunctions + \ ,@typstHashtagParens + +" Hashtag > Keywords {{{2 +syntax cluster typstHashtagKeywords + \ contains=typstHashtagConditional + \ ,typstHashtagRepeat + \ ,typstHashtagKeywords + \ ,typstHashtagStatement + +" syntax match typstHashtagControlFlowError +" \ /\v#%(if|while|for)>-@!.{-}$\_.{-}%(\{|\[|\()/ +syntax match typstHashtagControlFlow + \ /\v#%(if|while|for)>.{-}\ze%(\{|\[|\()/ + \ contains=typstHashtagConditional,typstHashtagRepeat + \ nextgroup=@typstCode +syntax region typstHashtagConditional + \ contained + \ start=/\v#if>/ end=/\v\ze(\{|\[)/ + \ contains=@typstCode +syntax region typstHashtagRepeat + \ contained + \ start=/\v#(while|for)>/ end=/\v\ze(\{|\[)/ + \ contains=@typstCode +syntax match typstHashtagKeyword + \ /\v#(return)>/ + \ skipwhite nextgroup=@typstCode +syntax region typstHashtagStatement + \ matchgroup=typstHashtagStatementWord start=/\v#(let|set|import|include)>/ + \ matchgroup=Noise end=/\v%(;|$)/ + \ contains=@typstCode +syntax region typstHashtagStatement + \ matchgroup=typstHashtagStatementWord start=/#show/ + \ matchgroup=Noise end=/\v%(:|$)/ keepend + \ contains=@typstCode + \ skipwhite nextgroup=@typstCode,typstCodeShowRocket + +" Hashtag > Constants {{{2 +syntax cluster typstHashtagConstants + \ contains=typstHashtagConstant +syntax match typstHashtagConstant + \ /\v#(none|auto|true|false)>/ + +" Hashtag > Identifiers {{{2 +syntax cluster typstHashtagIdentifiers + \ contains=typstHashtagIdentifier + \ ,typstHashtagFieldAccess +syntax match typstHashtagIdentifier + \ /\v#\w\k*>(<%(let|set|show|import|include))@<![\.\[\(]@!/ +syntax match typstHashtagFieldAccess + \ /\v#\w\k*>(<%(let|set|show|import|include))@<!\.[\[\(]@!/ + \ nextgroup=typstCodeFieldAccess,typstCodeFunction + +" Hashtag > Functions {{{2 +syntax cluster typstHashtagFunctions + \ contains=typstHashtagFunction +syntax match typstHashtagFunction + \ /\v#\w\k*>(<%(let|set|show|import|include))@<![\(\[]@=/ + \ nextgroup=typstCodeFunctionArgument + +" Hashtag > Parens {{{2 +syntax cluster typstHashtagParens + \ contains=typstHashtagParen + \ ,typstHashtagBrace + \ ,typstHashtagBracket + \ ,typstHashtagDollar +syntax region typstHashtagParen + \ matchgroup=Noise start=/#(/ end=/)/ + \ contains=@typstCode +syntax region typstHashtagBrace + \ matchgroup=Noise start=/#{/ end=/}/ + \ contains=@typstCode +syntax region typstHashtagBracket + \ matchgroup=Noise start=/#\[/ end=/\]/ + \ contains=@typstMarkup +syntax region typstHashtagDollar + \ matchgroup=Noise start=/#\$/ end=/\\\@<!\$/ + \ contains=@typstMath + + +" Markup {{{1 +syntax cluster typstMarkup + \ contains=@typstCommon + \ ,@Spell + \ ,@typstHashtag + \ ,@typstMarkupText + \ ,@typstMarkupParens + +" Markup > Text {{{2 +syntax cluster typstMarkupText + \ contains=typstMarkupRawInline + \ ,typstMarkupRawBlock + \ ,typstMarkupLabel + \ ,typstMarkupReference + \ ,typstMarkupUrl + \ ,typstMarkupHeading + \ ,typstMarkupBulletList + \ ,typstMarkupEnumList + \ ,typstMarkupTermList + \ ,typstMarkupBold + \ ,typstMarkupItalic + \ ,typstMarkupLinebreak + \ ,typstMarkupNonbreakingSpace + \ ,typstMarkupShy + \ ,typstMarkupDash + \ ,typstMarkupEllipsis + +" Raw Text +syntax match typstMarkupRawInline + \ /`.\{-}`/ +syntax region typstMarkupRawBlock + \ matchgroup=Macro start=/```\w*/ + \ matchgroup=Macro end=/```/ keepend +syntax region typstMarkupCodeBlockTypst + \ matchgroup=Macro start=/```typst/ + \ matchgroup=Macro end=/```/ contains=@typstCode keepend + \ concealends + +for s:name in get(g:, 'typst_embedded_languages', []) + let s:include = ['syntax include' + \ ,'@typstEmbedded_'..s:name + \ ,'syntax/'..s:name..'.vim'] + let s:rule = ['syn region' + \,s:name + \,'matchgroup=Macro' + \,'start=/```'..s:name..'\>/ end=/```/' + \,'contains=@typstEmbedded_'..s:name + \,'keepend' + \,'concealends'] + execute 'silent! ' .. join(s:include, ' ') + unlet! b:current_syntax + execute join(s:rule, ' ') +endfor + +" Label & Reference +syntax match typstMarkupLabel + \ /\v\<\K%(\k*-*)*\>/ +syntax match typstMarkupReference + \ /\v\@\K%(\k*-*)*/ + +" URL +syntax match typstMarkupUrl + \ #\v\w+://\S*# + +" Heading +syntax match typstMarkupHeading + \ /^\s*\zs=\{1,6}\s.*$/ + \ contains=typstMarkupLabel,@Spell + +" Lists +syntax match typstMarkupBulletList + \ /\v^\s*-\s+/ +syntax match typstMarkupEnumList + \ /\v^\s*(\+|\d+\.)\s+/ +syntax region typstMarkupTermList + \ oneline start=/\v^\s*\/\s/ end=/:/ + \ contains=@typstMarkup + +" Bold & Italic +syntax match typstMarkupBold + \ /\v(\w|\\)@1<!\*\S@=.{-}(\n.{-1,})*\S@1<=\\@1<!\*/ + \ contains=typstMarkupBoldRegion +syntax match typstMarkupItalic + \ /\v(\w|\\)@1<!_\S@=.{-}(\n.{-1,})*\S@1<=\\@1<!_/ + \ contains=typstMarkupItalicRegion +syntax match typstMarkupBoldItalic + \ contained + \ /\v(\w|\\)@1<![_\*]\S@=.{-}(\n.{-1,})*\S@1<=\\@1<!\2/ + \ contains=typstMarkupBoldRegion,typstMarkupItalicRegion +syntax region typstMarkupBoldRegion + \ contained + \ transparent matchgroup=typstMarkupBold + \ start=/\(^\|[^0-9a-zA-Z]\)\@<=\*/ end=/\*\($\|[^0-9a-zA-Z]\)\@=/ + \ concealends contains=typstMarkupBoldItalic,typstMarkupLabel,@Spell +syntax region typstMarkupItalicRegion + \ contained + \ transparent matchgroup=typstMarkupItalic + \ start=/\(^\|[^0-9a-zA-Z]\)\@<=_/ end=/_\($\|[^0-9a-zA-Z]\)\@=/ + \ concealends contains=typstMarkupBoldItalic,typstMarkupLabel,@Spell + +" Linebreak & Special Whitespace +syntax match typstMarkupLinebreak + \ /\\\\/ +syntax match typstMarkupNonbreakingSpace + \ /\~/ +syntax match typstMarkupShy + \ /-?/ + +" Special Symbols +syntax match typstMarkupDash + \ /-\{2,3}/ +syntax match typstMarkupEllipsis + \ /\.\.\./ + +" Markup > Parens {{{2 +syntax cluster typstMarkupParens + \ contains=typstMarkupBracket + \ ,typstMarkupDollar +syntax region typstMarkupBracket + \ matchgroup=Noise start=/\[/ end=/\]/ + \ contains=@typstMarkup +syntax region typstMarkupDollar + \ matchgroup=Special start=/\\\@<!\$/ end=/\\\@<!\$/ + \ contains=@typstMath + + +" Math {{{1 +syntax cluster typstMath + \ contains=@typstCommon + \ ,@typstHashtag + \ ,typstMathIdentifier + \ ,typstMathFunction + \ ,typstMathNumber + \ ,typstMathSymbol + \ ,typstMathBold + \ ,typstMathScripts + \ ,typstMathQuote + +syntax match typstMathIdentifier + \ /\a\a\+/ + \ contained +syntax match typstMathFunction + \ /\a\a\+\ze(/ + \ contained +syntax match typstMathNumber + \ /\<\d\+\>/ + \ contained +syntax region typstMathQuote + \ matchgroup=String start=/"/ skip=/\\"/ end=/"/ + \ contained + +" Math > Linked groups {{{2 +highlight default link typstMathIdentifier Identifier +highlight default link typstMathFunction Statement +highlight default link typstMathNumber Number +highlight default link typstMathSymbol Statement + +" Highlighting {{{1 + +" Highlighting > Linked groups {{{2 +highlight default link typstCommentBlock Comment +highlight default link typstCommentLine Comment +highlight default link typstCommentTodo Todo +highlight default link typstCodeConditional Conditional +highlight default link typstCodeRepeat Repeat +highlight default link typstCodeKeyword Keyword +highlight default link typstCodeConstant Constant +highlight default link typstCodeNumberInteger Number +highlight default link typstCodeNumberFloat Number +highlight default link typstCodeNumberLength Number +highlight default link typstCodeNumberAngle Number +highlight default link typstCodeNumberRatio Number +highlight default link typstCodeNumberFraction Number +highlight default link typstCodeString String +highlight default link typstCodeLabel Structure +highlight default link typstCodeStatementWord Statement +highlight default link typstCodeIdentifier Identifier +highlight default link typstCodeFieldAccess Identifier +highlight default link typstCodeFunction Function +highlight default link typstCodeParen Noise +highlight default link typstCodeBrace Noise +highlight default link typstCodeBracket Noise +highlight default link typstCodeDollar Noise +" highlight default link typstHashtagControlFlowError Error +highlight default link typstHashtagConditional Conditional +highlight default link typstHashtagRepeat Repeat +highlight default link typstHashtagKeyword Keyword +highlight default link typstHashtagConstant Constant +highlight default link typstHashtagStatementWord Statement +highlight default link typstHashtagIdentifier Identifier +highlight default link typstHashtagFieldAccess Identifier +highlight default link typstHashtagFunction Function +highlight default link typstHashtagParen Noise +highlight default link typstHashtagBrace Noise +highlight default link typstHashtagBracket Noise +highlight default link typstHashtagDollar Noise +highlight default link typstMarkupRawInline Macro +highlight default link typstMarkupRawBlock Macro +highlight default link typstMarkupLabel Structure +highlight default link typstMarkupReference Structure +highlight default link typstMarkupBulletList Structure +" highlight default link typstMarkupItalicError Error +" highlight default link typstMarkupBoldError Error +highlight default link typstMarkupEnumList Structure +highlight default link typstMarkupLinebreak Structure +highlight default link typstMarkupNonbreakingSpace Structure +highlight default link typstMarkupShy Structure +highlight default link typstMarkupDash Structure +highlight default link typstMarkupEllipsis Structure +highlight default link typstMarkupTermList Structure +highlight default link typstMarkupDollar Noise + +" Highlighting > Custom Styling {{{2 +highlight! Conceal ctermfg=NONE ctermbg=NONE guifg=NONE guibg=NONE + +highlight default typstMarkupHeading term=underline,bold cterm=underline,bold gui=underline,bold +highlight default typstMarkupUrl term=underline cterm=underline gui=underline +highlight default typstMarkupBold term=bold cterm=bold gui=bold +highlight default typstMarkupItalic term=italic cterm=italic gui=italic +highlight default typstMarkupBoldItalic term=bold,italic cterm=bold,italic gui=bold,italic + +let b:current_syntax = 'typst' + +" }}}1 diff --git a/runtime/syntax/uci.vim b/runtime/syntax/uci.vim new file mode 100644 index 0000000000..fdf5bfd9b3 --- /dev/null +++ b/runtime/syntax/uci.vim @@ -0,0 +1,33 @@ +" Vim syntax file +" Language: OpenWrt Unified Configuration Interface +" Maintainer: Colin Caine <complaints@cmcaine.co.uk> +" Upstream: https://github.com/cmcaine/vim-uci +" Last Change: 2021 Sep 19 +" +" For more information on uci, see https://openwrt.org/docs/guide-user/base-system/uci + +if exists("b:current_syntax") + finish +endif + +" Fancy zero-width non-capturing look-behind to see what the last word was. +" Would be really nice if there was some less obscure or more efficient way to +" do this. +syntax match uciOptionName '\%(\%(option\|list\)\s\+\)\@<=\S*' +syntax match uciConfigName '\%(\%(package\|config\)\s\+\)\@<=\S*' +syntax keyword uciConfigDec package config nextgroup=uciConfigName skipwhite +syntax keyword uciOptionType option list nextgroup=uciOptionName skipwhite + +" Standard matches. +syntax match uciComment "#.*$" +syntax region uciString start=+"+ end=+"+ skip=+\\"+ +syntax region uciString start=+'+ end=+'+ skip=+\\'+ + +highlight default link uciConfigName Identifier +highlight default link uciOptionName Constant +highlight default link uciConfigDec Statement +highlight default link uciOptionType Type +highlight default link uciComment Comment +highlight default link uciString Normal + +let b:current_syntax = "uci" diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index 02d6dde673..1be5498950 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 Jul 18 " Former Maintainer: Charles E. Campbell " DO NOT CHANGE DIRECTLY. @@ -28,14 +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 2mat[ch] 3mat[ch] +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] 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] finall[y] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] foldd[oopen] folddoc[losed] foldo[pen] g[lobal] go[to] gr[ep] grepa[dd] gu[i] gv[im] h[elp] helpc[lose] helpf[ind] helpg[rep] helpt[ags] +syn keyword vimCommand contained 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] 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] ma[rk] mak[e] +syn keyword vimCommand contained marks 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] rew[ind] ri[ght] +syn keyword vimCommand contained 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] tabm[ove] tabl[ast] +syn keyword vimCommand contained 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] 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 " Lower priority for _new_ to distinguish constructors from the command. syn match vimCommand contained "\<new\>(\@!" @@ -50,8 +48,8 @@ syn keyword vimOption contained ft filetype fcs fillchars fixeol fixendofline fc syn keyword vimOption contained imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot mis menuitems msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus syn keyword vimOption contained mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions syn keyword vimOption contained report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang -syn keyword vimOption contained spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tal tabline tpm tabpagemax ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir -syn keyword vimOption contained udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth winptydll wiw winwidth wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes +syn keyword vimOption contained spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype +syn keyword vimOption contained udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth winptydll wiw winwidth wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes " vimOptions: These are the turn-off setting variants {{{2 " GEN_SYN_VIM: vimOption turn-off, START_STR='syn keyword vimOption contained', END_STR='' @@ -69,7 +67,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" @@ -90,32 +88,38 @@ syn keyword vimErrSetting contained invakm invaltkeymap invanti invantialias inv " AutoCmd Events {{{2 syn case ignore " GEN_SYN_VIM: vimAutoEvent, START_STR='syn keyword vimAutoEvent contained', END_STR='' -syn keyword vimAutoEvent contained BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineChanged CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme ColorSchemePre CompleteChanged CompleteDone CompleteDonePre CursorHold CursorHoldI CursorMoved CursorMovedI DiffUpdated DirChanged DirChangedPre EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre -syn keyword vimAutoEvent contained FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave InsertLeavePre MenuPopup ModeChanged OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SafeState SafeStateAgain SessionLoadPost SessionWritePost ShellCmdPost ShellFilterPost SigUSR1 SourceCmd SourcePost SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TerminalWinOpen TermResponse TermResponseAll TextChanged TextChangedI TextChangedP TextChangedT TextYankPost User VimEnter VimLeave VimLeavePre VimResized VimResume VimSuspend WinClosed WinEnter WinLeave WinNew WinNewPre WinResized WinScrolled +syn keyword vimAutoEvent contained BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineChanged CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme ColorSchemePre CompleteChanged CompleteDone CompleteDonePre CursorHold CursorHoldI CursorMoved CursorMovedC CursorMovedI DiffUpdated DirChanged DirChangedPre EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost +syn keyword vimAutoEvent contained FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave InsertLeavePre KeyInputPre MenuPopup ModeChanged OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SafeState SafeStateAgain SessionLoadPost SessionWritePost ShellCmdPost ShellFilterPost SigUSR1 SourceCmd SourcePost SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TerminalWinOpen TermResponse TermResponseAll TextChanged TextChangedI TextChangedP TextChangedT TextYankPost User VimEnter VimLeave VimLeavePre VimResized VimResume VimSuspend WinClosed WinEnter WinLeave WinNew WinNewPre WinResized WinScrolled " Highlight commonly used Groupnames {{{2 syn keyword vimGroup contained Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo " 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 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 bindtextdomain 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 +syn keyword vimFuncName contained chdir cindent 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 +syn keyword vimFuncName contained getchar 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 id indent index indexof input inputdialog inputlist inputrestore inputsave inputsecret +syn keyword vimFuncName contained insert 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 +syn keyword vimFuncName contained popup_findecho popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide popup_list popup_locate popup_menu popup_move popup_notification popup_setbuf 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 +syn keyword vimFuncName contained rubyeval screenattr screenchar 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 +syn keyword vimFuncName contained strdisplaywidth strftime 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 +syn keyword vimFuncName contained test_getvalue test_gui_event 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 +syn keyword vimFuncName contained winwidth wordcount writefile xor "--- syntax here and above generated by mkvimvim --- " Special Vim Highlighting (not automatic) {{{1 -" Set up folding commands for this syntax highlighting file {{{2 +" Set up commands for this syntax highlighting file {{{2 + +com! -nargs=* Vim9 execute <q-args> s:vim9script ? "" : "contained" +com! -nargs=* VimL execute <q-args> s:vim9script ? "contained" : "" + if exists("g:vimsyn_folding") && g:vimsyn_folding =~# '[afhHlmpPrt]' if g:vimsyn_folding =~# 'a' com! -nargs=* VimFolda <args> fold @@ -198,6 +202,14 @@ else let s:vimsyn_maxlines= 60 endif +" Nulls {{{2 +" ===== +Vim9 syn keyword vim9Null null null_blob null_channel null_class null_dict null_function null_job null_list null_object null_partial null_string + +" Booleans {{{2 +" ======== +Vim9 syn keyword vim9Boolean true false + " Numbers {{{2 " ======= syn case ignore @@ -211,7 +223,8 @@ 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,vimCall,vimCatch,vimConst,vimDef,@vimEcho,vimEnddef,vimEndfunction,vimExecute,vimIsCommand,vimExtCmd,vimFor,vimFunction,vimGlobal,vimHighlight,vimLet,vimMap,vimMark,vimMatch,vimNotFunc,vimNorm,vimSet,vimSleep,vimSyntax,vimThrow,vimUnlet,vimUnmap,vimUserCmd,vimMenu,vimMenutranslate,@vim9CmdList +syn cluster vim9CmdList contains=vim9Const,vim9Final,vim9For,vim9Var 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#_]*\>" @@ -222,7 +235,8 @@ syn match vimVar "\s\zs&t_k;" syn match vimFBVar contained "\<[bwglstav]:\h[a-zA-Z0-9#_]*\>" syn keyword vimCommand contained in -syn cluster vimExprList contains=vimEnvvar,vimFunc,vimFuncVar,vimNumber,vimOper,vimOperParen,vimLetRegister,vimString,vimVar +syn cluster vimExprList contains=vimEnvvar,vimFunc,vimNumber,vimOper,vimOperParen,vimLetRegister,vimString,vimVar,@vim9ExprList +syn cluster vim9ExprList contains=vim9Boolean,vim9Null " Insertions And Appends: insert append {{{2 " (buftype != nofile test avoids having append, change, insert show up in the command window) @@ -242,6 +256,15 @@ syn match vimBehave "\<be\%[have]\>" nextgroup=vimBehaveBang,vimBehaveModel,vi syn match vimBehaveBang contained "\a\@1<=!" nextgroup=vimBehaveModel skipwhite syn keyword vimBehaveModel contained mswin xterm +" Call {{{2 +" ==== +syn match vimCall "\<call\=\>" skipwhite nextgroup=vimFunc + +" 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 @@ -271,8 +294,8 @@ syn keyword vimAugroupKey contained aug[roup] skipwhite nextgroup=vimAugroupBan " Operators: {{{2 " ========= -syn cluster vimOperGroup contains=vimEnvvar,vimFunc,vimFuncVar,vimOper,vimOperParen,vimNumber,vimString,vimRegister,@vimContinue,vim9Comment,vimVar -syn match vimOper "||\|&&\|[-+*/%.!]" skipwhite nextgroup=vimString,vimSpecFile +syn cluster vimOperGroup contains=vimEnvvar,vimFunc,vimFuncVar,vimOper,vimOperParen,vimNumber,vimString,vimRegister,@vimContinue,vim9Comment,vimVar,vimBoolean,vimNull +syn match vimOper "||\|&&\|[-+*/%.!]" skipwhite nextgroup=vimString,vimSpecFile syn match vimOper "\%#=1\(==\|!=\|>=\|<=\|=\~\|!\~\|>\|<\|=\|!\~#\)[?#]\{0,2}" skipwhite nextgroup=vimString,vimSpecFile syn match vimOper "\(\<is\|\<isnot\)[?#]\{0,2}\>" skipwhite nextgroup=vimString,vimSpecFile syn region vimOperParen matchgroup=vimParenSep start="(" end=")" contains=@vimOperGroup @@ -287,8 +310,8 @@ syn cluster vimFuncList contains=vimFuncBang,vimFunctionError,vimFuncKey,vimFunc syn cluster vimDefList contains=vimFuncBang,vimFunctionError,vimDefKey,vimFuncSID,Tag syn cluster vimFuncBodyCommon contains=@vimCmdList,vimCmplxRepeat,vimContinue,vimCtrlChar,vimDef,vimEnvvar,vimFBVar,vimFunc,vimFunction,vimLetHereDoc,vimNotation,vimNotFunc,vimNumber,vimOper,vimOperParen,vimRegister,vimSearch,vimSpecFile,vimString,vimSubst,vimFuncFold -syn cluster vimFuncBodyList contains=@vimFuncBodyCommon,vimComment,vimLineComment,vimFuncVar,vimInsert -syn cluster vimDefBodyList contains=@vimFuncBodyCommon,vim9Comment,vim9LineComment +syn cluster vimFuncBodyList contains=@vimFuncBodyCommon,vimComment,vimLineComment,vimFuncVar,vimInsert,vimConst,vimLet +syn cluster vimDefBodyList contains=@vimFuncBodyCommon,vim9Comment,vim9LineComment,vim9Const,vim9Final,vim9Var,vim9Null,vim9Boolean,vim9For syn region vimFuncPattern contained matchgroup=vimOper start="/" end="$" contains=@vimSubstList syn match vimFunction "\<fu\%[nction]\>" skipwhite nextgroup=vimCmdSep,vimComment,vimFuncPattern contains=vimFuncKey @@ -308,19 +331,19 @@ syn keyword vimFuncKey contained fu[nction] syn keyword vimDefKey contained def syn keyword vimMethodName contained empty len string -syn region vimFuncParams contained matchgroup=Delimiter start="(" skip=+\n\s*\\\|\n\s*"\\ + end=")" skipwhite skipnl nextgroup=vimFuncBody,vimFuncComment,vimEndfunction,vimFuncMod contains=vimFuncParam,@vimContinue -syn region vimDefParams contained matchgroup=Delimiter start="(" end=")" skipwhite skipnl nextgroup=vimDefBody,vimDefComment,vimEnddef,vimReturnType contains=vimDefParam,vim9Comment +syn region vimFuncParams contained matchgroup=Delimiter start="(" skip=+\n\s*\\\|\n\s*"\\ + end=")" skipwhite skipnl nextgroup=vimFuncBody,vimFuncComment,vimEndfunction,vimFuncMod,vim9CommentError contains=vimFuncParam,@vimContinue +syn region vimDefParams contained matchgroup=Delimiter start="(" end=")" skipwhite skipnl nextgroup=vimDefBody,vimDefComment,vimEnddef,vimReturnType,vimCommentError contains=vimDefParam,vim9Comment,vimFuncParamEquals syn match vimFuncParam contained "\<\h\w*\>\|\.\.\." skipwhite nextgroup=vimFuncParamEquals syn match vimDefParam contained "\<\h\w*\>" skipwhite nextgroup=vimParamType,vimFuncParamEquals syn match vimFuncParamEquals contained "=" skipwhite nextgroup=@vimExprList -syn match vimFuncMod contained "\<\%(abort\|closure\|dict\|range\)\>" skipwhite skipnl nextgroup=vimFuncBody,vimFuncComment,vimEndfunction,vimFuncMod +syn match vimFuncMod contained "\<\%(abort\|closure\|dict\|range\)\>" skipwhite skipnl nextgroup=vimFuncBody,vimFuncComment,vimEndfunction,vimFuncMod,vim9CommentError -syn region vimFuncBody contained start="^" matchgroup=vimCommand end="\<endfu\%[nction]\>" contains=@vimFuncBodyList -syn region vimDefBody contained start="^" matchgroup=vimCommand end="\<enddef\>" contains=@vimDefBodyList +syn region vimFuncBody contained start="^.\=" matchgroup=vimCommand end="\<endfu\%[nction]\>" contains=@vimFuncBodyList skipwhite nextgroup=vimCmdSep,vimComment,vim9CommentError +syn region vimDefBody contained start="^.\=" matchgroup=vimCommand end="\<enddef\>" contains=@vimDefBodyList skipwhite nextgroup=vimCmdSep,vim9Comment,vimCommentError -syn match vimEndfunction "\<endf\%[unction]\>" -syn match vimEnddef "\<enddef\>" +syn match vimEndfunction "\<endf\%[unction]\>" skipwhite nextgroup=vimCmdSep,vimComment,vim9CommentError +syn match vimEnddef "\<enddef\>" skipwhite nextgroup=vimCmdSep,vim9Comment,vimCommentError if exists("g:vimsyn_folding") && g:vimsyn_folding =~# 'f' syn region vimFuncFold start="^\s*:\=\s*fu\%[nction]\>!\=\s*\%(<[sS][iI][dD]>\|[sg]:\)\=\%(\i\|[#.]\|{.\{-1,}}\)\+\s*(" end="^\s*:\=\s*endf\%[unction]\>" contains=vimFunction fold keepend extend transparent @@ -333,9 +356,9 @@ syn match vimFuncBlank contained "\s\+" " Types: {{{2 " ===== -" vimTypes : new for vim9 -syn region vimReturnType contained start=":\s" end="$" matchgroup=vim9Comment end="\ze#" skipwhite skipnl nextgroup=vimDefBody,vimDefComment,vimEnddef contains=vimTypeSep transparent -syn match vimParamType contained ":\s\+\a" skipwhite skipnl nextgroup=vimFuncParamEquals contains=vimTypeSep,@vimType + +syn region vimReturnType contained start=":\s" end="$" matchgroup=vim9Comment end="\ze[#"]" skipwhite skipnl nextgroup=vimDefBody,vimDefComment,vimEnddef,vimCommentError contains=vimTypeSep transparent +syn match vimParamType contained ":\s" skipwhite skipnl nextgroup=@vimType contains=vimTypeSep syn match vimTypeSep contained ":\s\@=" skipwhite nextgroup=@vimType syn keyword vimType contained any blob bool channel float job number string void @@ -395,7 +418,7 @@ endif syn case ignore syn keyword vimUserAttrbKey contained bar ban[g] cou[nt] ra[nge] com[plete] n[args] re[gister] " GEN_SYN_VIM: vimUserAttrbCmplt, START_STR='syn keyword vimUserAttrbCmplt contained', END_STR='' -syn keyword vimUserAttrbCmplt contained arglist augroup behave buffer color command compiler cscope diff_buffer dir environment event expression file file_in_path filetype function help highlight history keymap locale mapclear mapping menu messages syntax syntime option packadd runtime shellcmd sign tag tag_listfiles user var breakpoint scriptnames +syn keyword vimUserAttrbCmplt contained arglist augroup behave buffer color command compiler cscope diff_buffer dir environment event expression file file_in_path filetype function help highlight history keymap locale mapclear mapping menu messages syntax syntime option packadd runtime shellcmd sign tag tag_listfiles user var breakpoint scriptnames dir_in_path syn keyword vimUserAttrbCmplt contained custom customlist nextgroup=vimUserAttrbCmpltFunc,vimUserCmdError syn match vimUserAttrbCmpltFunc contained ",\%([sS]:\|<[sS][iI][dD]>\)\=\%(\h\w*\%([.#]\h\w*\)\+\|\h\w*\)"hs=s+1 nextgroup=vimUserCmdError @@ -406,38 +429,31 @@ 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 - syn match vimComment +\<endif\s\+".*$+lc=5 contains=@vimCommentGroup,vimCommentString contained - syn match vimComment +\<else\s\+".*$+lc=4 contains=@vimCommentGroup,vimCommentString contained - " Vim9 comments - TODO: might be highlighted while they don't work - syn match vim9Comment excludenl +\s#[^{].*$+lc=1 contains=@vimCommentGroup,vimCommentString - syn match vim9Comment +\<endif\s\+#[^{].*$+lc=5 contains=@vimCommentGroup,vimCommentString - syn match vim9Comment +\<else\s\+#[^{].*$+lc=4 contains=@vimCommentGroup,vimCommentString - " Vim9 comment inside expression - " syn match vim9Comment +\s\zs#[^{].*$+ms=s+1 contains=@vimCommentGroup,vimCommentString - " syn match vim9Comment +^\s*#[^{].*$+ contains=@vimCommentGroup,vimCommentString - " syn match vim9Comment +^\s*#$+ contains=@vimCommentGroup,vimCommentString - syn cluster vimComment contains=vim9Comment else - syn match vimComment excludenl +\s"[^\-:.%#=*].*$+lc=1 contains=@vimCommentGroup,vimCommentString - syn match vimComment +\<endif\s\+".*$+lc=5 contains=@vimCommentGroup,vimCommentString - syn match vimComment +\<else\s\+".*$+lc=4 contains=@vimCommentGroup,vimCommentString - " Vim9 comments - TODO: might be highlighted while they don't work - syn match vim9Comment excludenl +\s#[^{].*$+lc=1 contains=@vimCommentGroup,vimCommentString contained - syn match vim9Comment +\<endif\s\+#[^{].*$+lc=5 contains=@vimCommentGroup,vimCommentString contained - syn match vim9Comment +\<else\s\+#[^{].*$+lc=4 contains=@vimCommentGroup,vimCommentString contained - " Vim9 comment inside expression - syn match vim9Comment +\s\zs#[^{].*$+ms=s+1 contains=@vimCommentGroup,vimCommentString contained - syn match vim9Comment +^\s*#[^{].*$+ contains=@vimCommentGroup,vimCommentString contained - syn match vim9Comment +^\s*#$+ contains=@vimCommentGroup,vimCommentString contained - syn cluster vimComment contains=vimComment endif +VimL syn match vimComment excludenl +\s"[^\-:.%#=*].*$+lc=1 contains=@vimCommentGroup,vimCommentString +VimL syn match vimComment +\<endif\s\+".*$+lc=5 contains=@vimCommentGroup,vimCommentString +VimL syn match vimComment +\<else\s\+".*$+lc=4 contains=@vimCommentGroup,vimCommentString +" Vim9 comments - TODO: might be highlighted while they don't work +Vim9 syn match vim9Comment excludenl +\s#[^{].*$+lc=1 contains=@vimCommentGroup,vimCommentString +Vim9 syn match vim9Comment +\<endif\s\+#[^{].*$+lc=5 contains=@vimCommentGroup,vimCommentString +Vim9 syn match vim9Comment +\<else\s\+#[^{].*$+lc=4 contains=@vimCommentGroup,vimCommentString +" Vim9 comment inside expression +Vim9 syn match vim9Comment +\s\zs#[^{].*$+ms=s+1 contains=@vimCommentGroup,vimCommentString contained +Vim9 syn match vim9Comment +^\s*#[^{].*$+ contains=@vimCommentGroup,vimCommentString contained +Vim9 syn match vim9Comment +^\s*#$+ contains=@vimCommentGroup,vimCommentString contained + +syn match vim9CommentError contained "#.*" +syn match vimCommentError contained +".*+ + " Environment Variables: {{{2 " ===================== syn match vimEnvvar "\$\I\i*" @@ -475,12 +491,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 +507,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'" @@ -532,22 +550,32 @@ syn region vimSetString contained start=+="+hs=s+1 skip=+\\\\\|\\"+ end=+"+ co syn match vimSetSep contained "[,:]" syn match vimSetMod contained "&vim\=\|[!&?<]\|all&" -" Let And Var: {{{2 -" =========== -syn keyword vimLet let skipwhite nextgroup=vimVar,vimFuncVar,vimLetHereDoc,vimLetRegister,vimVarList -syn keyword vimConst cons[t] skipwhite nextgroup=vimVar,vimLetHereDoc,vimVarList -syn region vimVarList contained start="\[" end="]" contains=vimVar,vimContinue +" Variable Declarations: {{{2 +" ===================== +VimL syn keyword vimLet let skipwhite nextgroup=vimVar,vimFuncVar,vimLetRegister,vimVarList +VimL syn keyword vimConst cons[t] skipwhite nextgroup=vimVar,vimVarList +syn region vimVarList contained start="\[" end="]" contains=vimVar,@vimContinue -syn keyword vimUnlet unl[et] skipwhite nextgroup=vimUnletBang,vimUnletVars +VimL syn keyword vimUnlet unl[et] skipwhite nextgroup=vimUnletBang,vimUnletVars syn match vimUnletBang contained "!" skipwhite nextgroup=vimUnletVars syn region vimUnletVars contained start="$\I\|\h" skip="\n\s*\\" end="$" end="|" contains=vimVar,vimEnvvar,vimContinue,vimString,vimNumber VimFoldh syn region vimLetHereDoc matchgroup=vimLetHereDocStart start='=<<\s*\%(trim\s\+\%(eval\s\+\)\=\|eval\s\+\%(trim\s\+\)\=\)\=\z(\L\S*\)' matchgroup=vimLetHereDocStop end='^\s*\z1\s*$' extend -syn keyword vimLet var skipwhite nextgroup=vimVar,vimFuncVar,vimLetHereDoc + +Vim9 syn keyword vim9Const const skipwhite nextgroup=vim9Variable,vim9VariableList +Vim9 syn keyword vim9Final final skipwhite nextgroup=vim9Variable,vim9VariableList +Vim9 syn keyword vim9Var var skipwhite nextgroup=vim9Variable,vim9VariableList + +syn match vim9Variable contained "\<\h\w*\>" skipwhite nextgroup=vimTypeSep,vimLetHereDoc +syn region vim9VariableList contained start="\[" end="]" contains=vim9Variable,@vimContinue " For: {{{2 " === -syn keyword vimFor for skipwhite nextgroup=vimVar,vimVarList +if s:vim9script + syn keyword vim9For for skipwhite nextgroup=vim9Variable,vim9VariableList +else + syn keyword vimFor for skipwhite nextgroup=vimVar,vimVarList +endif " Abbreviations: {{{2 " ============= @@ -591,15 +619,17 @@ syn region vimExecute matchgroup=vimCommand start="\<exe\%[cute]\>" skip=+\\|\|\ " Maps: {{{2 " ==== -syn match vimMap "\<map\>\ze\s*(\@!" skipwhite nextgroup=vimMapMod,vimMapLhs -syn match vimMap "\<map!" contains=vimMapBang skipwhite nextgroup=vimMapMod,vimMapLhs -" GEN_SYN_VIM: vimCommand map, START_STR='syn keyword vimMap', END_STR='skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs' -syn keyword vimMap cm[ap] cno[remap] im[ap] ino[remap] lm[ap] ln[oremap] nm[ap] nn[oremap] no[remap] om[ap] ono[remap] smap snor[emap] tma[p] tno[remap] vm[ap] vn[oremap] xm[ap] xn[oremap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs +" GEN_SYN_VIM: vimCommand map, START_STR='syn keyword vimMap', END_STR='skipwhite nextgroup=vimMapMod,vimMapLhs' +syn keyword vimMap cm[ap] cno[remap] im[ap] ino[remap] lm[ap] ln[oremap] nm[ap] nn[oremap] om[ap] ono[remap] smap snor[emap] tma[p] tno[remap] vm[ap] vn[oremap] xm[ap] xn[oremap] skipwhite nextgroup=vimMapMod,vimMapLhs +syn match vimMap "\<map\>" skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs +syn keyword vimMap no[remap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs " GEN_SYN_VIM: vimCommand mapclear, START_STR='syn keyword vimMap', END_STR='skipwhite nextgroup=vimMapMod' syn keyword vimMap cmapc[lear] imapc[lear] lmapc[lear] nmapc[lear] omapc[lear] smapc[lear] tmapc[lear] vmapc[lear] xmapc[lear] skipwhite nextgroup=vimMapMod -syn keyword vimMap mapc[lear] skipwhite nextgroup=vimMapBang,vimMapMod -" GEN_SYN_VIM: vimCommand unmap, START_STR='syn keyword vimUnmap', END_STR='skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs' -syn keyword vimUnmap cu[nmap] iu[nmap] lu[nmap] nun[map] ou[nmap] sunm[ap] tunma[p] unm[ap] vu[nmap] xu[nmap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs +syn keyword vimMap mapc[lear] skipwhite nextgroup=vimMapBang,vimMapMod +" GEN_SYN_VIM: vimCommand unmap, START_STR='syn keyword vimUnmap', END_STR='skipwhite nextgroup=vimMapMod,vimMapLhs' +syn keyword vimUnmap cu[nmap] iu[nmap] lu[nmap] nun[map] ou[nmap] sunm[ap] tunma[p] vu[nmap] xu[nmap] skipwhite nextgroup=vimMapMod,vimMapLhs +syn keyword vimUnmap unm[ap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs + syn match vimMapLhs contained "\%(.\|\S\)\+" contains=vimCtrlChar,vimNotation skipwhite nextgroup=vimMapRhs syn match vimMapLhs contained "\%(.\|\S\)\+\ze\s*$" contains=vimCtrlChar,vimNotation skipwhite skipnl nextgroup=vimMapRhsContinue syn match vimMapBang contained "\a\@1<=!" skipwhite nextgroup=vimMapMod,vimMapLhs @@ -666,6 +696,8 @@ syn match vimFunc "\%(\%([sSgGbBwWtTlL]:\|<[sS][iI][dD]>\)\=\%(\w\ syn match vimUserFunc contained "\%(\%([sSgGbBwWtTlL]:\|<[sS][iI][dD]>\)\=\%(\w\+\.\)*\I[a-zA-Z0-9_.]*\)\|\<\u[a-zA-Z0-9.]*\>\|\<if\>" contains=vimNotation,vimMethodName syn keyword vimFuncEcho contained ec ech echo +syn match vimMap "\<map\%(\s\+(\)\@=" skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs + " User Command Highlighting: {{{2 syn match vimUsrCmd '^\s*\zs\u\%(\w*\)\@>\%([(#[]\|\s\+\%([-+*/%]\=\|\.\.\)=\)\@!' @@ -683,11 +715,26 @@ endif syn match vimNotFunc "\<if\>\|\<el\%[seif]\>\|\<retu\%[rn]\>\|\<while\>" skipwhite nextgroup=vimOper,vimOperParen,vimVar,vimFunc,vimNotation +" Match: {{{2 +" ===== +syn match vimMatch "\<[23]\=mat\%[ch]\>" skipwhite nextgroup=vimMatchGroup,vimMatchNone +syn match vimMatchGroup contained "[[:alnum:]._-]\+" skipwhite nextgroup=vimMatchPattern +syn case ignore +syn keyword vimMatchNone contained none +syn case match +syn region vimMatchPattern contained matchgroup=Delimiter start="\z([!#$%&'()*+,-./:;<=>?@[\]^_`{}~]\)" skip="\\\\\|\\\z1" end="\z1" contains=@vimSubstList oneline + " Norm: {{{2 " ==== 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 @@ -852,17 +899,20 @@ 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 -else - syn match vimLineComment +^[ \t:]*".*$+ contains=@vimCommentGroup,vimCommentString,vimCommentTitle - syn match vim9LineComment +^[ \t:]*#.*$+ contains=@vimCommentGroup,vimCommentString,vim9CommentTitle contained -endif +Vim9 syn region vim9LineComment start=+^[ \t:]*\zs#.*$+ skip=+\n\s*\\\|\n\s*#\\ + end="$" contains=@vimCommentGroup,vimCommentString,vim9CommentTitle +VimL syn region vimLineComment start=+^[ \t:]*\zs".*$+ skip=+\n\s*\\\|\n\s*"\\ + end="$" contains=@vimCommentGroup,vimCommentString,vimCommentTitle + 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 @@ -895,12 +945,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 @@ -1087,13 +1137,13 @@ 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 hi def link vimBufnrWarn vimWarn endif - hi def link vim9Vim9ScriptArg Special hi def link vimAbb vimCommand hi def link vimAddress vimMark hi def link vimAugroupBang vimBang @@ -1107,19 +1157,20 @@ if !exists("skip_vim_syntax_inits") hi def link vimBehaveModel vimBehave hi def link vimBehave vimCommand hi def link vimBracket Delimiter + hi def link vimCall vimCommand + hi def link vimCatch vimCommand hi def link vimCmplxRepeat SpecialChar hi def link vimCommand Statement hi def link vimComment Comment - hi def link vim9Comment Comment + hi def link vimCommentError vimError hi def link vimCommentString vimString hi def link vimCommentTitle PreProc - hi def link vim9CommentTitle PreProc hi def link vimCondHL vimCommand hi def link vimConst vimCommand hi def link vimContinue Special hi def link vimContinueComment vimComment hi def link vimCtrlChar SpecialChar - hi def link vimDefComment vimComment + hi def link vimDefComment vim9Comment hi def link vimDefKey vimCommand hi def link vimDefParam vimVar hi def link vimEcho vimCommand @@ -1180,13 +1231,15 @@ if !exists("skip_vim_syntax_inits") hi def link vimLetHereDocStop Special hi def link vimLetRegister Special hi def link vimLineComment vimComment - hi def link vim9LineComment vimComment hi def link vimMapBang vimBang hi def link vimMapModKey vimFuncSID hi def link vimMapMod vimBracket hi def link vimMap vimCommand hi def link vimMark Number hi def link vimMarkNumber vimNumber + hi def link vimMatch vimCommand + hi def link vimMatchGroup vimGroup + hi def link vimMatchNone vimGroup hi def link vimMenuBang vimBang hi def link vimMenuClear Special hi def link vimMenuMod vimMapMod @@ -1223,7 +1276,10 @@ if !exists("skip_vim_syntax_inits") hi def link vimSetMod vimOption 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 +1320,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 @@ -1279,6 +1336,20 @@ if !exists("skip_vim_syntax_inits") hi def link vimUserFunc Normal hi def link vimVar Identifier hi def link vimWarn WarningMsg + + hi def link vim9Boolean Boolean + hi def link vim9Comment Comment + hi def link vim9CommentError vimError + hi def link vim9CommentTitle PreProc + hi def link vim9Const vimCommand + hi def link vim9Final vimCommand + hi def link vim9For vimCommand + hi def link vim9LineComment vimComment + hi def link vim9Null Constant + hi def link vim9Var vimCommand + hi def link vim9Variable vimVar + hi def link vim9Vim9Script vimCommand + hi def link vim9Vim9ScriptArg Special endif " Current Syntax Variable: {{{2 @@ -1286,6 +1357,8 @@ let b:current_syntax = "vim" " --------------------------------------------------------------------- " Cleanup: {{{1 +delc Vim9 +delc VimL delc VimFolda delc VimFoldf delc VimFoldh diff --git a/runtime/syntax/yaml.vim b/runtime/syntax/yaml.vim index 6ec806a4cb..e992bc02e6 100644 --- a/runtime/syntax/yaml.vim +++ b/runtime/syntax/yaml.vim @@ -129,7 +129,7 @@ syn region yamlFlowCollection matchgroup=yamlFlowIndicator start='\[' end='\]' c execute 'syn match yamlPlainScalar /'.s:ns_plain_out.'/' execute 'syn match yamlPlainScalar contained /'.s:ns_plain_in.'/' -execute 'syn match yamlFlowMappingKey /'.s:ns_plain_in.'\%(\s\+'.s:ns_plain_in.'\)*\ze\s*:/ contained '. +execute 'syn match yamlFlowMappingKey /'.s:ns_plain_in.'\%(\s\+'.s:ns_plain_in.'\)*\ze\s*:\%(\s\|$\)/ contained '. \'nextgroup=yamlFlowMappingDelimiter skipwhite' syn match yamlFlowMappingKeyStart /?/ contained nextgroup=@yamlFlowNode skipwhite syn match yamlFlowMappingMerge /<<\ze\s*:/ contained nextgroup=yamlFlowMappingDelimiter skipwhite diff --git a/runtime/tutor/tutor.es b/runtime/tutor/tutor.es index ed9397c02b..601a14f24b 100644 --- a/runtime/tutor/tutor.es +++ b/runtime/tutor/tutor.es @@ -236,7 +236,7 @@ Ahora contin Muchos comandos que cambian texto estn compuestos por un operador y un movimiento. - El formato para eliminar un comando con el operador de borrado d es el + El formato para comando eliminar con el operador de borrado d es el siguiente: d movimiento diff --git a/runtime/tutor/tutor.es.utf-8 b/runtime/tutor/tutor.es.utf-8 index d6187ff8dd..242df1724a 100644 --- a/runtime/tutor/tutor.es.utf-8 +++ b/runtime/tutor/tutor.es.utf-8 @@ -236,7 +236,7 @@ Ahora continúe con la Lección 2. Muchos comandos que cambian texto están compuestos por un operador y un movimiento. - El formato para eliminar un comando con el operador de borrado d es el + El formato para comando eliminar con el operador de borrado d es el siguiente: d movimiento diff --git a/src/GvimExt/gvimext.cpp b/src/GvimExt/gvimext.cpp index e58b142555..f98423c15f 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/INSTALL b/src/INSTALL index efa03da800..79d75842cd 100644 --- a/src/INSTALL +++ b/src/INSTALL @@ -178,12 +178,6 @@ There used to be a KDE version of Vim, using Qt libraries, but since it didn't work very well and there was no maintainer it was dropped. -Unix: COMPILING ON LINUX - -On Linux, when using -g to compile (which is default for gcc), the executable -will probably be statically linked. If you don't want this, remove the -g -option from CFLAGS. - Unix: PUTTING vimrc IN /etc Some Linux distributions prefer to put the global vimrc file in /etc, and the diff --git a/src/Make_ami.mak b/src/Make_ami.mak index 9e9ebe37be..09cdd3c173 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 7afb6e03ce..20ed903567 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 e05518610b..adcf19a4e1 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -135,7 +135,7 @@ # Version Support: WINVER=[0x0601, 0x0602, 0x0603, 0x0A00] (default is # 0x0601) # Supported versions depends on your target SDK, check SDKDDKVer.h -# See https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt +# See https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt # # Debug version: DEBUG=yes # Mapfile: MAP=[no, yes or lines] (default is yes) @@ -187,7 +187,7 @@ MINOR= 1 !ENDIF !IF ![$(PS) $(PSFLAGS) try{Out-File -FilePath '.\patchlvl.tmp' -InputObject \ - \"PATCHLEVEL=$$(((Get-Content -Path '.\version.c' \ + \"PATCHLEVEL=$$([decimal^]((Get-Content -Path '.\version.c' \ -TotalCount ((Select-String -Pattern 'static int included_patches' \ -Path '.\version.c').LineNumber+3))[-1^]).Trim().TrimEnd(','))\"} \ catch{exit 1}] @@ -384,15 +384,15 @@ TERMINAL = no !if "$(TERMINAL)" == "yes" TERM_OBJ = \ $(OBJDIR)/terminal.obj \ - $(OBJDIR)/vterm_encoding.obj \ - $(OBJDIR)/vterm_keyboard.obj \ - $(OBJDIR)/vterm_mouse.obj \ - $(OBJDIR)/vterm_parser.obj \ - $(OBJDIR)/vterm_pen.obj \ - $(OBJDIR)/vterm_screen.obj \ - $(OBJDIR)/vterm_state.obj \ - $(OBJDIR)/vterm_unicode.obj \ - $(OBJDIR)/vterm_vterm.obj + $(OBJDIR)/libvterm/encoding.obj \ + $(OBJDIR)/libvterm/keyboard.obj \ + $(OBJDIR)/libvterm/mouse.obj \ + $(OBJDIR)/libvterm/parser.obj \ + $(OBJDIR)/libvterm/pen.obj \ + $(OBJDIR)/libvterm/screen.obj \ + $(OBJDIR)/libvterm/state.obj \ + $(OBJDIR)/libvterm/unicode.obj \ + $(OBJDIR)/libvterm/vterm.obj TERM_DEFS = -DFEAT_TERMINAL TERM_DEPS = \ libvterm/include/vterm.h \ @@ -538,9 +538,10 @@ CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib #VIMRUNTIMEDIR = somewhere CFLAGS = -c /W3 /GF /nologo -I. -Iproto -DHAVE_PATHDEF -DWIN32 -DHAVE_STDINT_H \ - $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \ + $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) \ $(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) $(SOD_INC) \ - $(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) \ + $(CHANNEL_DEFS) $(DEFINES) \ + -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) \ /source-charset:utf-8 #>>>>> end of choices @@ -567,13 +568,16 @@ CPUNR = i686 ! message *** WARNING CPUNR=pentium4 is deprecated in favour of sse2. ! message Retargeting to sse2. CPUNR = sse2 -!elseif "$(CPUNR)" != "any" && "$(CPUNR)" != "i686" && "$(CPUNR)" != "sse" && "$(CPUNR)" != "sse2" && "$(CPUNR)" != "avx" && "$(CPUNR)" != "avx2" +!elseif "$(CPUNR)" != "any" && "$(CPUNR)" != "i686" \ + && "$(CPUNR)" != "sse" && "$(CPUNR)" != "sse2" \ + && "$(CPUNR)" != "avx" && "$(CPUNR)" != "avx2" ! error *** ERROR Unknown target architecture "$(CPUNR)". Make aborted. !endif # Convert processor ID to MVC-compatible number # IA32/SSE/SSE2 are only supported on x86 -!if "$(ASSEMBLY_ARCHITECTURE)" == "i386" && ("$(CPUNR)" == "i686" || "$(CPUNR)" == "any") +!if "$(ASSEMBLY_ARCHITECTURE)" == "i386" \ + && ("$(CPUNR)" == "i686" || "$(CPUNR)" == "any") CPUARG = /arch:IA32 !elseif "$(ASSEMBLY_ARCHITECTURE)" == "i386" && "$(CPUNR)" == "sse" CPUARG = /arch:SSE @@ -718,6 +722,7 @@ OBJ = \ $(OUTDIR)\float.obj \ $(OUTDIR)\fold.obj \ $(OUTDIR)\getchar.obj \ + $(OUTDIR)\gc.obj \ $(OUTDIR)\gui_xim.obj \ $(OUTDIR)\hardcopy.obj \ $(OUTDIR)\hashtab.obj \ @@ -1061,7 +1066,7 @@ MZSCHEME_LIB = "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib" ! endif ! else MZSCHEME_LIB = "$(MZSCHEME)\lib\msvc\libmzgc$(MZSCHEME_VER).lib" \ - "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib" + "$(MZSCHEME)\lib\msvc\lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).lib" ! endif ! endif MZSCHEME_OBJ = $(OUTDIR)\if_mzsch.obj @@ -1163,7 +1168,8 @@ RUBY_INSTALL_NAME = x64-$(RUBY_MSVCRT_NAME)-ruby$(RUBY_API_VER) ! message Ruby requested (version $(RUBY_VER)) - root dir is "$(RUBY)" CFLAGS = $(CFLAGS) -DFEAT_RUBY RUBY_OBJ = $(OUTDIR)\if_ruby.obj -RUBY_INC = /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)" /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)\$(RUBY_PLATFORM)" +RUBY_INC = /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)" \ + /I "$(RUBY)\include\ruby-$(RUBY_API_VER_LONG)\$(RUBY_PLATFORM)" RUBY_LIB = "$(RUBY)\lib\$(RUBY_INSTALL_NAME).lib" # Do we want to load Ruby dynamically? ! if "$(DYNAMIC_RUBY)" == "yes" @@ -1219,8 +1225,9 @@ PATHDEF_SRC = $(OUTDIR)\pathdef.c LINKARGS1 = /nologo LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(LIBC) $(OLE_LIB) \ - $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \ - $(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB) + $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) \ + $(PYTHON3_LIB) $(RUBY_LIB) $(TCL_LIB) $(SOUND_LIB) \ + $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB) !ifdef NODEBUG # Add /opt:ref to remove unreferenced functions and data even when /DEBUG is @@ -1280,36 +1287,40 @@ all: $(MAIN_TARGET) \ !if "$(VIMDLL)" == "yes" -$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \ - $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ - $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \ - version.c version.h +$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) \ + $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) $(LUA_OBJ) $(PERL_OBJ) \ + $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ + $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \ + $(XPM_OBJ) version.c version.h $(CC) $(CFLAGS_OUTDIR) version.c $(LINK) @<< -$(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) -$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) -$(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) -$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) +$(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) +$(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) +$(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) +$(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) << $(GVIM).exe: $(OUTDIR) $(EXEOBJG) $(VIMDLLBASE).dll - $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(GVIM).exe $(EXEOBJG) $(VIMDLLBASE).lib $(LIBC) + $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(GVIM).exe \ + $(EXEOBJG) $(VIMDLLBASE).lib $(LIBC) $(VIM).exe: $(OUTDIR) $(EXEOBJC) $(VIMDLLBASE).dll - $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM_CON) -out:$(VIM).exe $(EXEOBJC) $(VIMDLLBASE).lib $(LIBC) + $(LINK) $(LINKARGS1) /subsystem:$(SUBSYSTEM_CON) -out:$(VIM).exe \ + $(EXEOBJC) $(VIMDLLBASE).lib $(LIBC) !else -$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \ - $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ - $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \ - version.c version.h +$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) \ + $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) $(LUA_OBJ) $(PERL_OBJ) \ + $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ + $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \ + $(XPM_OBJ) version.c version.h $(CC) $(CFLAGS_OUTDIR) version.c $(LINK) @<< -$(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) -$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) -$(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) -$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) +$(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) +$(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) +$(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) $(TERM_OBJ) $(SOUND_OBJ) +$(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) << !endif @@ -1319,7 +1330,15 @@ $(VIM): $(VIM).exe $(OUTDIR): if not exist $(OUTDIR)/nul mkdir $(OUTDIR:/=\) -CFLAGS_INST = /nologo /O2 -DNDEBUG -DWIN32 -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) $(CFLAGS_DEPR) +$(OUTDIR)/libvterm: $(OUTDIR) + if not exist $(OUTDIR)/libvterm/nul mkdir $(OUTDIR:/=\)\libvterm + +CFLAGS_INST = /nologo /O2 -DNDEBUG -DWIN32 -DWINVER=$(WINVER) \ + -D_WIN32_WINNT=$(WINVER) $(CFLAGS_DEPR) + +!IFDEF PATCHLEVEL +CFLAGS_INST= $(CFLAGS_INST) -DVIM_VERSION_PATCHLEVEL=$(PATCHLEVEL) +!ENDIF install.exe: dosinst.c dosinst.h version.h $(CC) $(CFLAGS_INST) dosinst.c kernel32.lib shell32.lib \ @@ -1404,7 +1423,8 @@ cmdidxs: ex_cmds.h # - change nv_cmds[] in nv_cmds.h to add the new normal/visual mode command. # - run "make nvcmdidxs" to generate nv_cmdidxs.h nvcmdidxs: nv_cmds.h - $(CC) /nologo -I. -Iproto -DNDEBUG create_nvcmdidxs.c -link -subsystem:$(SUBSYSTEM_TOOLS) + $(CC) /nologo -I. -Iproto -DNDEBUG create_nvcmdidxs.c \ + -link -subsystem:$(SUBSYSTEM_TOOLS) vim --clean -N -X --not-a-term -u create_nvcmdidxs.vim -c quit -del create_nvcmdidxs.exe @@ -1415,7 +1435,7 @@ test: testgvim testgui: cd testdir - $(MAKE) /NOLOGO -f Make_mvc.mak VIMPROG=..\gvim + $(MAKE) /NOLOGO -f Make_mvc.mak "VIMPROG=..\gvim.exe" cd .. testtiny: @@ -1425,7 +1445,7 @@ testtiny: testgvimtiny: cd testdir - $(MAKE) /NOLOGO -f Make_mvc.mak tiny VIMPROG=..\gvim + $(MAKE) /NOLOGO -f Make_mvc.mak "VIMPROG=..\gvim.exe" tiny cd .. testclean: @@ -1466,15 +1486,15 @@ test_vim9: ########################################################################### # Create a default rule for transforming .c files to .obj files in $(OUTDIR) -.c{$(OUTDIR)/}.obj:: +.c{$(OUTDIR)}.obj:: $(CC) $(CFLAGS_OUTDIR) $< # Create a default rule for xdiff. -{xdiff/}.c{$(OUTDIR)/}.obj:: +{xdiff}.c{$(OUTDIR)}.obj:: $(CC) $(CFLAGS_OUTDIR) $< # Create a default rule for transforming .cpp files to .obj files in $(OUTDIR) -.cpp{$(OUTDIR)/}.obj:: +.cpp{$(OUTDIR)}.obj:: $(CC) $(CFLAGS_OUTDIR) $< $(OUTDIR)/alloc.obj: $(OUTDIR) alloc.c $(INCL) @@ -1571,6 +1591,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 @@ -1631,7 +1653,6 @@ $(OUTDIR)/if_tcl.obj: $(OUTDIR) if_tcl.c $(INCL) $(CC) $(CFLAGS_OUTDIR) $(TCL_INC) if_tcl.c $(OUTDIR)/iscygpty.obj: $(OUTDIR) iscygpty.c $(CUI_INCL) - $(CC) $(CFLAGS_OUTDIR) iscygpty.c $(OUTDIR)/job.obj: $(OUTDIR) job.c $(INCL) @@ -1797,7 +1818,8 @@ $(OUTDIR)/vimg.res: $(OUTDIR) vim.rc vim.manifest version.h gui_w32_rc.h \ $(OUTDIR)/vimd.res: $(OUTDIR) vim.rc version.h gui_w32_rc.h \ tools.bmp tearoff.bmp vim.ico vim_error.ico \ vim_alert.ico vim_info.ico vim_quest.ico - $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) -DRCDLL -DVIMDLLBASE=\"$(VIMDLLBASE)\" vim.rc + $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) \ + -DRCDLL -DVIMDLLBASE=\"$(VIMDLLBASE)\" vim.rc !else $(OUTDIR)/vim.res: $(OUTDIR) vim.rc vim.manifest version.h gui_w32_rc.h \ tools.bmp tearoff.bmp vim.ico vim_error.ico \ @@ -1818,32 +1840,27 @@ CCCTERM = $(CC) $(CFLAGS) -Ilibvterm/include -DINLINE="" \ -DGET_SPECIAL_PTY_TYPE_FUNCTION=get_special_pty_type \ -D_CRT_SECURE_NO_WARNINGS -$(OUTDIR)/vterm_encoding.obj: $(OUTDIR) libvterm/src/encoding.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/encoding.c +# Create a default rule for vterm. +{libvterm/src}.c{$(OUTDIR)/libvterm}.obj:: + $(CCCTERM) /Fo$(OUTDIR)/libvterm/ $< + +$(OUTDIR)/libvterm/encoding.obj: $(OUTDIR)/libvterm libvterm/src/encoding.c $(TERM_DEPS) -$(OUTDIR)/vterm_keyboard.obj: $(OUTDIR) libvterm/src/keyboard.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/keyboard.c +$(OUTDIR)/libvterm/keyboard.obj: $(OUTDIR)/libvterm libvterm/src/keyboard.c $(TERM_DEPS) -$(OUTDIR)/vterm_mouse.obj: $(OUTDIR) libvterm/src/mouse.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/mouse.c +$(OUTDIR)/libvterm/mouse.obj: $(OUTDIR)/libvterm libvterm/src/mouse.c $(TERM_DEPS) -$(OUTDIR)/vterm_parser.obj: $(OUTDIR) libvterm/src/parser.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/parser.c +$(OUTDIR)/libvterm/parser.obj: $(OUTDIR)/libvterm libvterm/src/parser.c $(TERM_DEPS) -$(OUTDIR)/vterm_pen.obj: $(OUTDIR) libvterm/src/pen.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/pen.c +$(OUTDIR)/libvterm/pen.obj: $(OUTDIR)/libvterm libvterm/src/pen.c $(TERM_DEPS) -$(OUTDIR)/vterm_screen.obj: $(OUTDIR) libvterm/src/screen.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/screen.c +$(OUTDIR)/libvterm/screen.obj: $(OUTDIR)/libvterm libvterm/src/screen.c $(TERM_DEPS) -$(OUTDIR)/vterm_state.obj: $(OUTDIR) libvterm/src/state.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/state.c +$(OUTDIR)/libvterm/state.obj: $(OUTDIR)/libvterm libvterm/src/state.c $(TERM_DEPS) -$(OUTDIR)/vterm_unicode.obj: $(OUTDIR) libvterm/src/unicode.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/unicode.c +$(OUTDIR)/libvterm/unicode.obj: $(OUTDIR)/libvterm libvterm/src/unicode.c $(TERM_DEPS) -$(OUTDIR)/vterm_vterm.obj: $(OUTDIR) libvterm/src/vterm.c $(TERM_DEPS) - $(CCCTERM) /Fo$@ libvterm/src/vterm.c +$(OUTDIR)/libvterm/vterm.obj: $(OUTDIR)/libvterm libvterm/src/vterm.c $(TERM_DEPS) # $CFLAGS may contain backslashes, quotes and chevrons, escape them all. @@ -1911,6 +1928,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 f050c9db2f..559c2f8e43 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 b95cbc8a2b..80ee3b394e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1539,6 +1539,7 @@ BASIC_SRC = \ float.c \ fold.c \ getchar.c \ + gc.c \ gui_xim.c \ hardcopy.c \ hashtab.c \ @@ -1701,6 +1702,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 \ @@ -1879,6 +1881,7 @@ PRO_AUTO = \ float.pro \ fold.pro \ getchar.pro \ + gc.pro \ gui_xim.pro \ gui_beval.pro \ hardcopy.pro \ @@ -2205,7 +2208,7 @@ test check: unittests $(TERM_TEST) scripttests scripttests: $(MAKE) -f Makefile $(VIMTARGET) if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \ - cd $(PODIR); $(MAKE) -f Makefile check VIM=../$(VIMTARGET); \ + cd $(PODIR); $(MAKE) -f Makefile check VIMPROG=../$(VIMTARGET); \ fi -if test $(VIMTARGET) != vim -a ! -r vim; then \ ln -s $(VIMTARGET) vim; \ @@ -2359,7 +2362,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) @@ -2374,10 +2377,8 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(VIMTARGET) $(DEST_RT) \ ## cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)" -a -f tags; then \ ## mv -f tags tags.dist; fi ## @echo generating help tags -## # We can assume Vim was build, but it may not have been installed, -## # thus use the executable in the current directory. -## -@BUILD_DIR="`pwd`"; cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \ -## $(MAKE) VIMEXE="$$BUILD_DIR/$(VIMTARGET)" vimtags; fi +## -@cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \ +## $(MAKE) vimtags; fi cd $(HELPSOURCE); \ files=`ls *.txt tags`; \ files="$$files `ls *.??x tags-?? 2>/dev/null || true`"; \ @@ -2451,8 +2452,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 @@ -2698,7 +2697,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) $@ @@ -2890,10 +2889,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. @@ -3255,6 +3254,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 @@ -3982,6 +3984,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 os_mac.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 \ os_mac.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 \ @@ -4137,11 +4144,6 @@ objects/os_unix.o: os_unix.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 os_unixx.h -objects/pathdef.o: auto/pathdef.c vim.h protodef.h auto/config.h feature.h \ - os_unix.h os_mac.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/popupmenu.o: popupmenu.c vim.h protodef.h auto/config.h feature.h \ os_unix.h os_mac.h ascii.h keymap.h termdefs.h macros.h option.h \ beval.h proto/gui_beval.pro structs.h regexp.h gui.h \ @@ -4298,15 +4300,15 @@ objects/userfunc.o: userfunc.c vim.h protodef.h auto/config.h feature.h os_unix. libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \ globals.h errors.h objects/version.o: version.c vim.h protodef.h auto/config.h feature.h os_unix.h \ - os_mac.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 version.h + os_mac.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 version.h objects/vim9class.o: vim9class.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 vim9.h + os_unix.h os_mac.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 vim9.h objects/vim9cmds.o: vim9cmds.c vim.h protodef.h auto/config.h feature.h os_unix.h \ os_mac.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 \ @@ -4394,7 +4396,7 @@ objects/MMBackend.o: MacVim/MMBackend.m MacVim/MMBackend.h MacVim/MacVim.h vim.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 + globals.h errors.h proto/gui_macvim.pro objects/MacVim.o: MacVim/MacVim.m MacVim/MacVim.h objects/json_test.o: json_test.c main.c vim.h protodef.h auto/config.h feature.h \ os_unix.h os_mac.h ascii.h keymap.h termdefs.h macros.h option.h \ diff --git a/src/README.md b/src/README.md index f3806d229a..404298863d 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 02a96bf159..332de9682a 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -6650,11 +6650,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' ` if test "x$MACOS_X" = "xyes"; then perllibs=`echo "$perllibs" | sed -e 's/-arch[^-]*//g'` @@ -11703,55 +11705,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` @@ -16237,6 +16190,30 @@ then : fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgettext" >&5 +printf %s "checking for dgettext... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <libintl.h> +int +main (void) +{ +dgettext("Test", "Test"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; printf "%s\n" "#define HAVE_DGETTEXT 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _nl_msg_cat_cntr" >&5 printf %s "checking for _nl_msg_cat_cntr... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/src/autocmd.c b/src/autocmd.c index fa3c565053..3864680d49 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -120,6 +120,7 @@ static keyvalue_T event_tab[] = { KEYVALUE_ENTRY(EVENT_CURSORHOLD, "CursorHold"), KEYVALUE_ENTRY(EVENT_CURSORHOLDI, "CursorHoldI"), KEYVALUE_ENTRY(EVENT_CURSORMOVED, "CursorMoved"), + KEYVALUE_ENTRY(EVENT_CURSORMOVEDC, "CursorMovedC"), KEYVALUE_ENTRY(EVENT_CURSORMOVEDI, "CursorMovedI"), KEYVALUE_ENTRY(EVENT_DIFFUPDATED, "DiffUpdated"), KEYVALUE_ENTRY(EVENT_DIRCHANGED, "DirChanged"), @@ -154,6 +155,7 @@ static keyvalue_T event_tab[] = { KEYVALUE_ENTRY(EVENT_INSERTENTER, "InsertEnter"), KEYVALUE_ENTRY(EVENT_INSERTLEAVE, "InsertLeave"), KEYVALUE_ENTRY(EVENT_INSERTLEAVEPRE, "InsertLeavePre"), + KEYVALUE_ENTRY(EVENT_KEYINPUTPRE, "KeyInputPre"), KEYVALUE_ENTRY(EVENT_MENUPOPUP, "MenuPopup"), KEYVALUE_ENTRY(EVENT_MODECHANGED, "ModeChanged"), KEYVALUE_ENTRY(EVENT_OPTIONSET, "OptionSet"), @@ -2021,6 +2023,15 @@ has_insertcharpre(void) return (first_autopat[(int)EVENT_INSERTCHARPRE] != NULL); } +/* + * Return TRUE when there is an KeyInputPre autocommand defined. + */ + int +has_keyinputpre(void) +{ + return (first_autopat[(int)EVENT_KEYINPUTPRE] != NULL); +} + /* * Return TRUE when there is an CmdUndefined autocommand defined. */ @@ -2251,10 +2262,12 @@ apply_autocmds_group( || event == EVENT_CMDLINECHANGED || event == EVENT_CMDLINEENTER || event == EVENT_CMDLINELEAVE + || event == EVENT_CURSORMOVEDC || event == EVENT_CMDWINENTER || event == EVENT_CMDWINLEAVE || event == EVENT_CMDUNDEFINED || event == EVENT_FUNCUNDEFINED + || event == EVENT_KEYINPUTPRE || event == EVENT_REMOTEREPLY || event == EVENT_SPELLFILEMISSING || event == EVENT_QUICKFIXCMDPRE @@ -3392,6 +3405,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 e064f62218..c29c9250db 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -50,6 +50,7 @@ static void free_buffer(buf_T *); static void free_buffer_stuff(buf_T *buf, int free_options); static int bt_nofileread(buf_T *buf); static void no_write_message_buf(buf_T *buf); +static int do_buffer_ext(int action, int start, int dir, int count, int flags); #ifdef UNIX # define dev_T dev_t @@ -754,10 +755,16 @@ close_buffer( */ if (wipe_buf) { + tabpage_T *tp; + win_T *wp; + // Do not wipe out the buffer if it is used in a window. if (buf->b_nwindows > 0) return FALSE; + FOR_ALL_TAB_WINDOWS(tp, wp) + mark_forget_file(wp, buf->b_fnum); + if (action == DOBUF_WIPE_REUSE) { // we can re-use this buffer number, store it @@ -1104,13 +1111,30 @@ goto_buffer( { bufref_T old_curbuf; int save_sea = swap_exists_action; + int skip_help_buf; + + switch (eap->cmdidx) + { + case CMD_bnext: + case CMD_sbnext: + case CMD_bNext: + case CMD_bprevious: + case CMD_sbNext: + case CMD_sbprevious: + skip_help_buf = TRUE; + break; + default: + skip_help_buf = FALSE; + break; + } set_bufref(&old_curbuf, curbuf); if (swap_exists_action == SEA_NONE) swap_exists_action = SEA_DIALOG; - (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO, - start, dir, count, eap->forceit); + (void)do_buffer_ext(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO, start, dir, count, + (eap->forceit ? DOBUF_FORCEIT : 0) | + (skip_help_buf ? DOBUF_SKIPHELP : 0)); if (swap_exists_action == SEA_QUIT && *eap->cmd == 's') { #if defined(FEAT_EVAL) @@ -1341,8 +1365,11 @@ do_buffer_ext( if (buf == NULL) buf = lastbuf; } - // don't count unlisted buffers - if (unload || buf->b_p_bl) + // Don't count unlisted buffers. + // Avoid non-help buffers if the starting point was a non-help buffer and + // vice-versa. + if (unload || (buf->b_p_bl + && ((flags & DOBUF_SKIPHELP) == 0 || buf->b_help == bp->b_help))) { --count; bp = NULL; // use this buffer as new starting point @@ -2433,6 +2460,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 c76a053114..bef058ce10 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/change.c b/src/change.c index 327a5b4bfa..9f8d6b38f7 100644 --- a/src/change.c +++ b/src/change.c @@ -1355,17 +1355,17 @@ del_bytes( mch_memmove(newp + col, oldp + col + count, (size_t)movelen); if (alloc_newp) ml_replace(lnum, newp, FALSE); -#ifdef FEAT_PROP_POPUP else { +#ifdef FEAT_PROP_POPUP // Also move any following text properties. if (oldlen + 1 < curbuf->b_ml.ml_line_len) mch_memmove(newp + newlen + 1, oldp + oldlen + 1, (size_t)curbuf->b_ml.ml_line_len - oldlen - 1); +#endif curbuf->b_ml.ml_line_len -= count; curbuf->b_ml.ml_line_textlen = 0; } -#endif // mark the buffer as changed and prepare for displaying inserted_bytes(lnum, col, -count); diff --git a/src/charset.c b/src/charset.c index 470698f0e0..19b089526a 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; } @@ -815,20 +827,20 @@ linetabsize_no_outer(win_T *wp, linenr_T lnum) if (cts.cts_text_prop_count) { - int write_idx = 0; - for (int read_idx = 0; read_idx < cts.cts_text_prop_count; read_idx++) - { - textprop_T *tp = &cts.cts_text_props[read_idx]; - if (tp->tp_col != MAXCOL) - { - if (read_idx != write_idx) - cts.cts_text_props[write_idx] = *tp; - write_idx++; - } - } - cts.cts_text_prop_count = write_idx; - if (cts.cts_text_prop_count == 0) - VIM_CLEAR(cts.cts_text_props); + int write_idx = 0; + for (int read_idx = 0; read_idx < cts.cts_text_prop_count; read_idx++) + { + textprop_T *tp = &cts.cts_text_props[read_idx]; + if (tp->tp_col != MAXCOL) + { + if (read_idx != write_idx) + cts.cts_text_props[write_idx] = *tp; + write_idx++; + } + } + cts.cts_text_prop_count = write_idx; + if (cts.cts_text_prop_count == 0) + VIM_CLEAR(cts.cts_text_props); } win_linetabsize_cts(&cts, (colnr_T)MAXCOL); @@ -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 } @@ -1374,17 +1397,17 @@ win_lbr_chartabsize( else if (max_head_vcol > vcol + head_prev + prev_rem) head += (max_head_vcol - (vcol + head_prev + prev_rem) + width2 - 1) / width2 * head_mid; -# ifdef FEAT_PROP_POPUP else if (max_head_vcol < 0) { - int off = 0; + int off = mb_added; +# ifdef FEAT_PROP_POPUP if (*s != NUL && ((State & MODE_NORMAL) || cts->cts_start_incl)) off += cts->cts_cur_text_width; +# endif if (off >= prev_rem) head += (1 + (off - prev_rem) / width) * head_mid; } -# endif } } diff --git a/src/clientserver.c b/src/clientserver.c index 1b31406f27..f854a6406e 100644 --- a/src/clientserver.c +++ b/src/clientserver.c @@ -613,7 +613,7 @@ build_drop_cmd( // Call inputsave() so that a prompt for an encryption key works. ga_concat(&ga, (char_u *) - "<CR>:if exists('*inputsave')|call inputsave()|endif|"); + "<CR><C-\\><C-N>:if exists('*inputsave')|call inputsave()|endif|"); if (tabs) ga_concat(&ga, (char_u *)"tab "); ga_concat(&ga, (char_u *)"drop"); @@ -657,7 +657,13 @@ build_drop_cmd( // endif // endif ga_concat(&ga, (char_u *)":if !exists('+acd')||!&acd|if haslocaldir()|"); +#ifdef MSWIN + // in case :set shellslash is set, need to normalize the directory separators + // '/' is not valid in a filename so replacing '/' by '\\' should be safe + ga_concat(&ga, (char_u *)"cd -|lcd -|elseif getcwd()->tr('/','\\') ==# '"); +#else ga_concat(&ga, (char_u *)"cd -|lcd -|elseif getcwd() ==# '"); +#endif ga_concat(&ga, cdp); ga_concat(&ga, (char_u *)"'|cd -|endif|endif<CR>"); vim_free(cdp); diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 64646fa036..b2cb3afeda 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -46,6 +46,7 @@ cmdline_fuzzy_completion_supported(expand_T *xp) && xp->xp_context != EXPAND_COLORS && xp->xp_context != EXPAND_COMPILER && xp->xp_context != EXPAND_DIRECTORIES + && xp->xp_context != EXPAND_DIRS_IN_CDPATH && xp->xp_context != EXPAND_FILES && xp->xp_context != EXPAND_FILES_IN_PATH && xp->xp_context != EXPAND_FILETYPE @@ -107,7 +108,8 @@ wildescape( || xp->xp_context == EXPAND_FILES_IN_PATH || xp->xp_context == EXPAND_SHELLCMD || xp->xp_context == EXPAND_BUFFERS - || xp->xp_context == EXPAND_DIRECTORIES) + || xp->xp_context == EXPAND_DIRECTORIES + || xp->xp_context == EXPAND_DIRS_IN_CDPATH) { // Insert a backslash into a file name before a space, \, %, # // and wildmatch characters, except '~'. @@ -437,6 +439,28 @@ cmdline_compl_startcol(void) return compl_startcol; } +/* + * 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. @@ -1382,7 +1406,8 @@ addstar( if (context != EXPAND_FILES && context != EXPAND_FILES_IN_PATH && context != EXPAND_SHELLCMD - && context != EXPAND_DIRECTORIES) + && context != EXPAND_DIRECTORIES + && context != EXPAND_DIRS_IN_CDPATH) { // Matching will be done internally (on something other than files). // So we convert the file-matching-type wildcards into our kind for @@ -2116,7 +2141,7 @@ set_context_by_cmdname( case CMD_lcd: case CMD_lchdir: if (xp->xp_context == EXPAND_FILES) - xp->xp_context = EXPAND_DIRECTORIES; + xp->xp_context = EXPAND_DIRS_IN_CDPATH; break; case CMD_help: xp->xp_context = EXPAND_HELP; @@ -2832,6 +2857,8 @@ expand_files_and_dirs( flags |= EW_FILE; else if (xp->xp_context == EXPAND_FILES_IN_PATH) flags |= (EW_FILE | EW_PATH); + else if (xp->xp_context == EXPAND_DIRS_IN_CDPATH) + flags = (flags | EW_DIR | EW_CDPATH) & ~EW_FILE; else flags = (flags | EW_DIR) & ~EW_FILE; if (options & WILD_ICASE) @@ -3088,7 +3115,8 @@ ExpandFromContext( if (xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES - || xp->xp_context == EXPAND_FILES_IN_PATH) + || xp->xp_context == EXPAND_FILES_IN_PATH + || xp->xp_context == EXPAND_DIRS_IN_CDPATH) return expand_files_and_dirs(xp, pat, matches, numMatches, flags, options); diff --git a/src/cmdhist.c b/src/cmdhist.c index 6342f02bdd..684c08e704 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/config.h.in b/src/config.h.in index 8ad9f03136..530c0829f0 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -222,7 +222,6 @@ #undef HAVE_UNSETENV #undef HAVE_USLEEP #undef HAVE_UTIME -#undef HAVE_BIND_TEXTDOMAIN_CODESET #undef HAVE_MBLEN #undef HAVE_TIMER_CREATE #undef HAVE_CLOCK_GETTIME @@ -424,6 +423,12 @@ /* Define if there is a working gettext(). */ #undef HAVE_GETTEXT +/* Define if there is a working bind_textdomain_codeset(). */ +#undef HAVE_BIND_TEXTDOMAIN_CODESET + +/* Define if there is a working dgettext(). */ +#undef HAVE_DGETTEXT + /* Define if _nl_msg_cat_cntr is present. */ #undef HAVE_NL_MSG_CAT_CNTR diff --git a/src/configure.ac b/src/configure.ac index 5f907bab8b..2e0a43fae0 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -1275,13 +1275,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' ` if test "x$MACOS_X" = "xyes"; then dnl Perl on Mac OS X 10.5 and later adds "-arch" flags but these @@ -3536,13 +3540,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 @@ -4746,6 +4743,12 @@ if test "$enable_nls" = "yes"; then AC_SUBST(MAKEMO) dnl this was added in GNU gettext 0.10.36 AC_CHECK_FUNCS(bind_textdomain_codeset) + AC_MSG_CHECKING([for dgettext]) + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [#include <libintl.h>], + [dgettext("Test", "Test");])], + AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_DGETTEXT), + AC_MSG_RESULT([no])) dnl _nl_msg_cat_cntr is required for GNU gettext AC_MSG_CHECKING([for _nl_msg_cat_cntr]) AC_LINK_IFELSE([AC_LANG_PROGRAM( diff --git a/src/dict.c b/src/dict.c index c78995d80e..d3636f3bc9 100644 --- a/src/dict.c +++ b/src/dict.c @@ -1091,6 +1091,33 @@ eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal) return OK; } +/* + * 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. @@ -1195,8 +1222,7 @@ dict_lookup(hashitem_T *hi) dict_equal( dict_T *d1, dict_T *d2, - int ic, // ignore case for strings - int recursive) // TRUE when used recursively + int ic) // ignore case for strings { hashitem_T *hi; dictitem_T *item2; @@ -1220,7 +1246,7 @@ dict_equal( item2 = dict_find(d2, hi->hi_key, -1); if (item2 == NULL) return FALSE; - if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive)) + if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) return FALSE; --todo; } @@ -1248,7 +1274,7 @@ dict_count(dict_T *d, typval_T *needle, int ic) if (!HASHITEM_EMPTY(hi)) { --todo; - if (tv_equal(&HI2DI(hi)->di_tv, needle, ic, FALSE)) + if (tv_equal(&HI2DI(hi)->di_tv, needle, ic)) ++n; } } diff --git a/src/dosinst.c b/src/dosinst.c index 35625a7946..116cc8fa40 100644 --- a/src/dosinst.c +++ b/src/dosinst.c @@ -1663,7 +1663,7 @@ install_registry(void) uninstall_string, icon_string, version_string, - "Bram Moolenaar et al."); + "The Vim Project"); if (ERROR_SUCCESS != lRet) return FAIL; diff --git a/src/drawline.c b/src/drawline.c index e8b019c530..12a86d5b82 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 @@ -4255,7 +4261,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 d12f52cfe0..ba7d40a3d3 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 c0bba186e7..4d1987fc6b 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 @@ -1319,7 +1320,7 @@ edit( c = ins_ctrl_ey(c); break; - default: + default: #ifdef UNIX if (c == intr_char) // special interrupt char goto do_intr; @@ -1851,7 +1852,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/errors.h b/src/errors.h index 21403c184d..5cd1b0681f 100644 --- a/src/errors.h +++ b/src/errors.h @@ -1039,8 +1039,10 @@ EXTERN char e_missing_argument_str[] INIT(= N_("E417: Missing argument: %s")); EXTERN char e_illegal_value_str[] INIT(= N_("E418: Illegal value: %s")); +#ifdef FEAT_EVAL EXTERN char e_im_a_teapot[] INIT(= N_("E418: I'm a teapot")); +#endif EXTERN char e_fg_color_unknown[] INIT(= N_("E419: FG color unknown")); EXTERN char e_bg_color_unknown[] @@ -1274,8 +1276,10 @@ EXTERN char e_is_not_file_or_writable_device[] INIT(= N_("is not a file or writable device")); EXTERN char e_str_is_not_file_or_writable_device[] INIT(= N_("E503: \"%s\" is not a file or writable device")); +#ifdef FEAT_EVAL EXTERN char e_coffee_currently_not_available[] INIT(= N_("E503: Coffee is currently not available")); +#endif // E504 EXTERN char e_is_read_only_cannot_override_W_in_cpoptions[] INIT(= N_("is read-only (cannot override: \"W\" in 'cpoptions')")); @@ -1572,11 +1576,12 @@ EXTERN char e_too_many_signs_defined[] EXTERN char e_unknown_printer_font_str[] INIT(= N_("E613: Unknown printer font: %s")); #endif -EXTERN char e_class_required[] - INIT(= N_("E614: Class required")); +// E614 unused (deleted) // E615 unused +#ifdef FEAT_EVAL EXTERN char e_object_required_for_argument_nr[] INIT(= N_("E616: Object required for argument %d")); +#endif #ifdef FEAT_GUI_GTK EXTERN char e_cannot_be_changed_in_gtk_GUI[] INIT(= N_("E617: Cannot be changed in the GTK GUI")); @@ -3320,8 +3325,10 @@ EXTERN char e_could_not_check_for_pending_sigalrm_str[] #ifdef FEAT_EVAL EXTERN char e_substitute_nesting_too_deep[] INIT(= N_("E1290: substitute nesting too deep")); +# ifdef MSWIN EXTERN char e_invalid_argument_nr[] INIT(= N_("E1291: Invalid argument: %ld")); +# endif #endif EXTERN char e_cmdline_window_already_open[] INIT(= N_("E1292: Command-line window is already open")); @@ -3392,16 +3399,13 @@ EXTERN char e_invalid_object_variable_declaration_str[] INIT(= N_("E1317: Invalid object variable declaration: %s")); EXTERN char e_not_valid_command_in_class_str[] INIT(= N_("E1318: Not a valid command in a class: %s")); -EXTERN char e_using_class_as_number[] - INIT(= N_("E1319: Using a Class as a Number")); +// E1319 unused EXTERN char e_using_object_as_number[] INIT(= N_("E1320: Using an Object as a Number")); -EXTERN char e_using_class_as_float[] - INIT(= N_("E1321: Using a Class as a Float")); +// E1321 unused EXTERN char e_using_object_as_float[] INIT(= N_("E1322: Using an Object as a Float")); -EXTERN char e_using_class_as_string[] - INIT(= N_("E1323: Using a Class as a String")); +// E1323 unused EXTERN char e_using_object_as_string[] INIT(= N_("E1324: Using an Object as a String")); EXTERN char e_method_not_found_on_class_str_str[] @@ -3552,8 +3556,7 @@ EXTERN char e_type_can_only_be_defined_in_vim9_script[] INIT(= N_("E1393: Type can only be defined in Vim9 script")); EXTERN char e_type_name_must_start_with_uppercase_letter_str[] INIT(= N_("E1394: Type name must start with an uppercase letter: %s")); -EXTERN char e_cannot_modify_typealias[] - INIT(= N_("E1395: Type alias \"%s\" cannot be modified")); +// E1395 unused EXTERN char e_typealias_already_exists_for_str[] INIT(= N_("E1396: Type alias \"%s\" already exists")); EXTERN char e_missing_typealias_name[] @@ -3562,20 +3565,16 @@ EXTERN char e_missing_typealias_type[] INIT(= N_("E1398: Missing type alias type")); EXTERN char e_type_can_only_be_used_in_script[] INIT(= N_("E1399: Type can only be used in a script")); -EXTERN char e_using_typealias_as_number[] - INIT(= N_("E1400: Using type alias \"%s\" as a Number")); -EXTERN char e_using_typealias_as_float[] - INIT(= N_("E1401: Using type alias \"%s\" as a Float")); -EXTERN char e_using_typealias_as_string[] - INIT(= N_("E1402: Using type alias \"%s\" as a String")); +// E1400 unused +// E1401 unused +// E1402 unused EXTERN char e_using_typealias_as_value_str[] INIT(= N_("E1403: Type alias \"%s\" cannot be used as a value")); EXTERN char e_abstract_cannot_be_used_in_interface[] INIT(= N_("E1404: Abstract cannot be used in an interface")); EXTERN char e_using_class_as_value_str[] INIT(= N_("E1405: Class \"%s\" cannot be used as a value")); -EXTERN char e_using_class_as_var_val[] - INIT(= N_("E1406: Cannot use a Class as a variable or value")); +// E1406 unused EXTERN char e_using_typealias_as_var_val[] INIT(= N_("E1407: Cannot use a Typealias as a variable or value")); EXTERN char e_final_variable_not_supported_in_interface[] @@ -3630,20 +3629,26 @@ EXTERN char e_fmt_arg_nr_unused_str[] INIT(= N_("E1501: format argument %d unused in $-style format: %s")); EXTERN char e_positional_num_field_spec_reused_str_str[] INIT(= N_("E1502: Positional argument %d used as field width reused as different type: %s/%s")); +#ifdef FEAT_EVAL EXTERN char e_positional_nr_out_of_bounds_str[] INIT(= N_("E1503: Positional argument %d out of bounds: %s")); +#endif EXTERN char e_positional_arg_num_type_inconsistent_str_str[] INIT(= N_("E1504: Positional argument %d type used inconsistently: %s/%s")); EXTERN char e_invalid_format_specifier_str[] INIT(= N_("E1505: Invalid format specifier: %s")); +#ifdef FEAT_XATTR EXTERN char e_xattr_erange[] INIT(= N_("E1506: Buffer too small to copy xattr value or key")); +#endif EXTERN char e_aptypes_is_null_nr_str[] INIT(= "E1507: Internal error: ap_types or ap_types[idx] is NULL: %d: %s"); +#ifdef FEAT_XATTR EXTERN char e_xattr_e2big[] INIT(= N_("E1508: Size of the extended attribute value is larger than the maximum size allowed")); EXTERN char e_xattr_other[] INIT(= N_("E1509: Error occurred when reading or writing extended attribute")); +#endif EXTERN char e_val_too_large[] INIT(= N_("E1510: Value too large: %s")); EXTERN char e_wrong_number_of_characters_for_field_str[] diff --git a/src/eval.c b/src/eval.c index 51ee604319..a001bba6a0 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,11 +1274,15 @@ get_lval_imported( return rc == OK ? p : NULL; } +typedef enum { + GLV_FAIL, + GLV_OK, + GLV_STOP +} glv_status_T; + /* - * 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]", - * "name.key", "name.key[expr]" etc. - * Indexing only works if "name" is an existing List or Dictionary. + * 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 @@ -1256,235 +1293,485 @@ get_lval_imported( * GLV_READ_ONLY: will not change the variable * GLV_NO_AUTOLOAD: do not use script autoloading * - * Returns a pointer to just after the name, including indexes. - * When an evaluation error occurs "lp->ll_name" is NULL; - * Returns NULL for a parsing error. Still need to free items in "lp"! + * 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'. */ - char_u * -get_lval( - char_u *name, - typval_T *rettv, + 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, - int skip, - int flags, // GLV_ values - int fne_flags) // flags for find_name_end() + typval_T *rettv) { - char_u *p; - 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; - int vim9script = in_vim9script(); - class_T *cl_exec = NULL; // class that is executing, or NULL. - -#ifdef LOG_LOCKVAR - if (lval_root == NULL) - ch_log(NULL, "LKVAR: get_lval(): name: %s, lval_root (nil)", name); - else - ch_log(NULL, "LKVAR: get_lval(): name: %s, lr_tv %p lr_is_arg %d", - name, (void*)lval_root->lr_tv, lval_root->lr_is_arg); - char buf[80]; - ch_log(NULL, "LKVAR: ...: GLV flags: %s", - flags_tostring(flags, glv_flag_strings, buf, sizeof(buf))); -#endif + char_u *p = *key_end; - // Clear everything in "lp". - CLEAR_POINTER(lp); + 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; - if (skip || (flags & GLV_COMPILING)) + // a NULL dict is equivalent with an empty dict + if (lp->ll_tv->vval.v_dict == NULL) { - // When skipping or compiling just find the end of the name. - lp->ll_name = name; - lp->ll_name_end = find_name_end(name, NULL, NULL, - FNE_INCL_BR | fne_flags); - return lp->ll_name_end; + 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; - // Cannot use "s:var" at the Vim9 script level. "s: type" is OK. - if (vim9script && at_script_level() - && name[0] == 's' && name[1] == ':' && !VIM_ISWHITE(name[2])) + 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) { - semsg(_(e_cannot_use_s_colon_in_vim9_script_str), name); - return NULL; + 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; } - // Find the end of the name. - p = find_name_end(name, &expr_start, &expr_end, fne_flags); - lp->ll_name_end = p; - if (expr_start != 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) { - // Don't expand the name when we already know there is an error. - if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p) - && *p != '[' && *p != '.') + // 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_trailing_characters_str), p); - return NULL; + semsg(_(e_illegal_variable_name_str), name); + return GLV_FAIL; } - lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); - if (lp->ll_exp_name == NULL) + // Key does not exist in dict: may need to add it. + if (*p == '[' || *p == '.' || unlet) { - // Report an invalid expression in braces, unless the - // expression evaluation has been cancelled due to an - // aborting error, an interrupt, or an exception. - if (!aborting() && !quiet) - { - emsg_severe = TRUE; - semsg(_(e_invalid_argument_str), name); - return NULL; - } + if (!quiet) + semsg(_(e_key_not_present_in_dictionary_str), key); + return GLV_FAIL; } - lp->ll_name = lp->ll_exp_name; + 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; } - else - { - lp->ll_name = name; + // 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; - if (vim9script) - { - // "a: type" is declaring variable "a" with a type, not "a:". - // However, "g:[key]" is indexing a dictionary. - if (p == name + 2 && p[-1] == ':' && *p != '[') - { - --p; - lp->ll_name_end = p; - } - if (*skipwhite(p) == ':') - { - char_u *tp = skipwhite(p + 1); + lp->ll_tv = &lp->ll_di->di_tv; - if (is_scoped_variable(name)) - { - semsg(_(e_cannot_use_type_with_this_variable_str), name); - return NULL; - } - if (VIM_ISWHITE(*p)) - { - semsg(_(e_no_white_space_allowed_before_colon_str), p); - return NULL; - } - if (tp == p + 1 && !quiet) - { - semsg(_(e_white_space_required_after_str_str), ":", p); - return NULL; - } - if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) - { - semsg(_(e_using_type_not_in_script_context_str), p); - return NULL; - } - if (vim9script && (flags & GLV_NO_DECL) && - !(flags & GLV_FOR_LOOP)) - { - // Using a type and not in a "var" declaration. - semsg(_(e_trailing_characters_str), p); - return NULL; - } + 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); - // parse the type after the name - lp->ll_type = parse_type(&tp, - &SCRIPT_ITEM(current_sctx.sc_sid)->sn_type_list, - !quiet); - if (lp->ll_type == NULL && !quiet) - return NULL; - lp->ll_name_end = tp; - } - // TODO: check inside class? + 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; } } - if (lp->ll_name == NULL) - return p; +} - if (*p == '.') +/* + * 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) { - imported_T *import = find_imported(lp->ll_name, p - lp->ll_name, TRUE); - if (import != NULL) + if (lp->ll_tv->vval.v_object == NULL) { - p++; // skip '.' - p = get_lval_imported(lp, rettv, import->imp_sid, p, &v, - fne_flags, vim9script); - if (p == NULL) - return 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; - // Without [idx] or .key we are done. - if (*p != '[' && *p != '.') + 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 (lval_root != NULL) - fill_lval_from_lval_root(lp, lval_root); - return p; + if (get_lval_oc_variable(lp, cl, key, key_end, v_type, cl_exec, flags) + == FAIL) + return FAIL; } - if (vim9script && lval_root != NULL) - cl_exec = lval_root->lr_cl_exec; - if (vim9script && lval_root != NULL && lval_root->lr_tv != NULL) + if (lp->ll_valtype == NULL) { - // using local variable - lp->ll_tv = lval_root->lr_tv; - v = NULL; + member_not_found_msg(cl, v_type, key, key_end - key); + return FAIL; } - else if (lp->ll_tv == NULL) + + 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) { - cc = *p; - *p = NUL; - // When we would write to the variable pass &ht and prevent autoload. - writing = !(flags & GLV_READ_ONLY); - v = find_var(lp->ll_name, writing ? &ht : NULL, - (flags & GLV_NO_AUTOLOAD) || writing); - if (v == NULL && !quiet) - semsg(_(e_undefined_variable_str), lp->ll_name); - *p = cc; - if (v == NULL) - return NULL; - lp->ll_tv = &v->di_tv; + if (!quiet) + semsg(_(e_dot_not_allowed_after_str_str), + vartype_name(v_type), name); + return FALSE; } - if (vim9script && (flags & GLV_NO_DECL) == 0) + 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_variable_already_declared_str), lp->ll_name); - return NULL; + 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 == '.' && 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 (*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; @@ -1493,17 +1780,17 @@ get_lval( 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; + goto done; if (lp->ll_range) { if (!quiet) emsg(_(e_slice_must_come_last)); - return NULL; + goto done; } #ifdef LOG_LOCKVAR ch_log(NULL, "LKVAR: get_lval() loop: p: %s, type: %s", p, - vartype_name(v_type)); + vartype_name(v_type)); #endif if (vim9script && lp->ll_valtype == NULL @@ -1519,7 +1806,7 @@ get_lval( 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)); + vartype_name(lp->ll_valtype->tt_type)); #endif } } @@ -1528,13 +1815,14 @@ get_lval( 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; + goto done; } p = key + len; } @@ -1548,13 +1836,10 @@ get_lval( { empty1 = FALSE; if (eval1(&p, &var1, &EVALARG_EVALUATE) == FAIL) // recursive! - return NULL; + goto done; if (tv_get_string_chk(&var1) == NULL) - { // not a number or string - clear_tv(&var1); - return NULL; - } + goto done; p = skipwhite(p); } @@ -1565,19 +1850,17 @@ get_lval( { if (!quiet) emsg(_(e_cannot_slice_dictionary)); - clear_tv(&var1); - return NULL; + goto done; } if (rettv != NULL && !(rettv->v_type == VAR_LIST - && rettv->vval.v_list != NULL) + && rettv->vval.v_list != NULL) && !(rettv->v_type == VAR_BLOB - && rettv->vval.v_blob != NULL)) + && rettv->vval.v_blob != NULL)) { if (!quiet) emsg(_(e_slice_requires_list_or_blob_value)); - clear_tv(&var1); - return NULL; + goto done; } p = skipwhite(p + 1); if (*p == ']') @@ -1587,17 +1870,10 @@ get_lval( lp->ll_empty2 = FALSE; // recursive! if (eval1(&p, &var2, &EVALARG_EVALUATE) == FAIL) - { - clear_tv(&var1); - return NULL; - } + goto done; if (tv_get_string_chk(&var2) == NULL) - { // not a number or string - clear_tv(&var1); - clear_tv(&var2); - return NULL; - } + goto done; } lp->ll_range = TRUE; } @@ -1608,9 +1884,7 @@ get_lval( { if (!quiet) emsg(_(e_missing_closing_square_brace)); - clear_tv(&var1); - clear_tv(&var2); - return NULL; + goto done; } // Skip to past ']'. @@ -1619,284 +1893,279 @@ get_lval( #ifdef LOG_LOCKVAR if (len == -1) ch_log(NULL, "LKVAR: ... loop: p: %s, '[' key: %s", p, - empty1 ? ":" : (char*)tv_get_string(&var1)); + 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; + glv_status_T glv_status; - // 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; + 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]", + * "name.key", "name.key[expr]" etc. + * Indexing only works if "name" is an existing List or Dictionary. + * "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 + * + * Returns a pointer to just after the name, including indexes. + * When an evaluation error occurs "lp->ll_name" is NULL; + * Returns NULL for a parsing error. Still need to free items in "lp"! + */ + char_u * +get_lval( + char_u *name, + typval_T *rettv, + lval_T *lp, + int unlet, + int skip, + int flags, // GLV_ values + int fne_flags) // flags for find_name_end() +{ + char_u *p; + char_u *expr_start, *expr_end; + int cc; + dictitem_T *v = NULL; + hashtab_T *ht = NULL; + int quiet = flags & GLV_QUIET; + int writing = 0; + int vim9script = in_vim9script(); + class_T *cl_exec = NULL; // class that is executing, or NULL. + +#ifdef LOG_LOCKVAR + if (lval_root == NULL) + ch_log(NULL, "LKVAR: get_lval(): name: %s, lval_root (nil)", name); + else + ch_log(NULL, "LKVAR: get_lval(): name: %s, lr_tv %p lr_is_arg %d", + name, (void*)lval_root->lr_tv, lval_root->lr_is_arg); + char buf[80]; + ch_log(NULL, "LKVAR: ...: GLV flags: %s", + flags_tostring(flags, glv_flag_strings, buf, sizeof(buf))); +#endif + + // Clear everything in "lp". + CLEAR_POINTER(lp); - lp->ll_di = dict_find(lp->ll_dict, key, len); + if (skip || (flags & GLV_COMPILING)) + { + // When skipping or compiling just find the end of the name. + lp->ll_name = name; + lp->ll_name_end = find_name_end(name, NULL, NULL, + FNE_INCL_BR | fne_flags); + return lp->ll_name_end; + } + + // Cannot use "s:var" at the Vim9 script level. "s: type" is OK. + if (vim9script && at_script_level() + && name[0] == 's' && name[1] == ':' && !VIM_ISWHITE(name[2])) + { + semsg(_(e_cannot_use_s_colon_in_vim9_script_str), name); + return NULL; + } + + // Find the end of the name. + p = find_name_end(name, &expr_start, &expr_end, fne_flags); + lp->ll_name_end = p; + if (expr_start != NULL) + { + // Don't expand the name when we already know there is an error. + if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p) + && *p != '[' && *p != '.') + { + semsg(_(e_trailing_characters_str), p); + return NULL; + } - // 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) + lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); + if (lp->ll_exp_name == NULL) + { + // Report an invalid expression in braces, unless the + // expression evaluation has been cancelled due to an + // aborting error, an interrupt, or an exception. + if (!aborting() && !quiet) { - int prevval; + emsg_severe = TRUE; + semsg(_(e_invalid_argument_str), name); + return NULL; + } + } + lp->ll_name = lp->ll_exp_name; + } + else + { + lp->ll_name = name; - if (len != -1) + if (vim9script) + { + // "a: type" is declaring variable "a" with a type, not "a:". + // However, "g:[key]" is indexing a dictionary. + if (p == name + 2 && p[-1] == ':' && *p != '[') + { + --p; + lp->ll_name_end = p; + } + if (*skipwhite(p) == ':') + { + char_u *tp = skipwhite(p + 1); + + if (is_scoped_variable(name)) { - prevval = key[len]; - key[len] = NUL; + semsg(_(e_cannot_use_type_with_this_variable_str), name); + return NULL; } - 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) + if (VIM_ISWHITE(*p)) { - clear_tv(&var1); + semsg(_(e_no_white_space_allowed_before_colon_str), p); 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()) + if (tp == p + 1 && !quiet) { - semsg(_(e_illegal_variable_name_str), name); - clear_tv(&var1); + semsg(_(e_white_space_required_after_str_str), ":", p); return NULL; } - - // Key does not exist in dict: may need to add it. - if (*p == '[' || *p == '.' || unlet) + if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) { - if (!quiet) - semsg(_(e_key_not_present_in_dictionary_str), key); - clear_tv(&var1); + semsg(_(e_using_type_not_in_script_context_str), p); + return NULL; + } + if (vim9script && (flags & GLV_NO_DECL) && + !(flags & GLV_FOR_LOOP)) + { + // Using a type and not in a "var" declaration. + semsg(_(e_trailing_characters_str), p); 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) + // parse the type after the name + lp->ll_type = parse_type(&tp, + &SCRIPT_ITEM(current_sctx.sc_sid)->sn_type_list, + !quiet); + if (lp->ll_type == NULL && !quiet) return NULL; + lp->ll_name_end = tp; } - lp->ll_blob = lp->ll_tv->vval.v_blob; - lp->ll_tv = NULL; - break; + // TODO: check inside class? } - 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); + } + if (lp->ll_name == NULL) + return p; - 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); + if (*p == '.') + { + imported_T *import = find_imported(lp->ll_name, p - lp->ll_name, TRUE); + if (import != NULL) + { + p++; // skip '.' + p = get_lval_imported(lp, import->imp_sid, p, &v, fne_flags); + if (p == NULL) 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; + // Without [idx] or .key we are done. + if (*p != '[' && *p != '.') + { + if (lval_root != NULL) + fill_lval_from_lval_root(lp, lval_root); + return p; + } + + if (vim9script && lval_root != NULL) + cl_exec = lval_root->lr_cl_exec; + if (vim9script && lval_root != NULL && lval_root->lr_tv != NULL) + { + // using local variable + lp->ll_tv = lval_root->lr_tv; + v = NULL; + } + else if (lp->ll_tv == NULL) + { + cc = *p; + *p = NUL; + // When we would write to the variable pass &ht and prevent autoload. + writing = !(flags & GLV_READ_ONLY); + v = find_var(lp->ll_name, writing ? &ht : NULL, + (flags & GLV_NO_AUTOLOAD) || writing); + if (v == NULL && !quiet) + semsg(_(e_undefined_variable_str), lp->ll_name); + *p = cc; + if (v == NULL) + return NULL; + lp->ll_tv = &v->di_tv; + } - // TODO: what if class is NULL? - if (cl != NULL) - { - lp->ll_valtype = NULL; + if (vim9script && (flags & GLV_NO_DECL) == 0) + { + if (!quiet) + semsg(_(e_variable_already_declared_str), lp->ll_name); + return 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 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; - 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 (vim9script && lp->ll_valtype != NULL && rettv != NULL) + { + where_T where = WHERE_INIT; - if (lp->ll_valtype == NULL) - { - member_not_found_msg(cl, v_type, key, p - key); - return NULL; - } - } - } + // 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; } - 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) @@ -3598,6 +3946,40 @@ eval_addlist(typval_T *tv1, typval_T *tv2) return OK; } +/* + * 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 @@ -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; @@ -3660,48 +4042,143 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg) return FAIL; } - /* - * Get the second variable. - */ - if (evaluate && vim9script && !IS_WHITE_OR_NUL(p[2])) + /* + * Get the second variable. + */ + if (evaluate && vim9script && !IS_WHITE_OR_NUL(p[2])) + { + error_white_both(p, 2); + clear_tv(rettv); + return FAIL; + } + *arg = skipwhite_and_linebreak(p + 2, evalarg); + if (eval6(arg, &var2, evalarg) == FAIL) + { + clear_tv(rettv); + return FAIL; + } + + if (evaluate) + { + if (eval_shift_number(rettv, &var2, exprtype) == FAIL) + return FAIL; + } + + clear_tv(&var2); + } + + return OK; +} + +/* + * 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) { - error_white_both(p, 2); - clear_tv(rettv); + // 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; } - *arg = skipwhite_and_linebreak(p + 2, evalarg); - if (eval6(arg, &var2, evalarg) == 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(rettv); + clear_tv(tv1); + clear_tv(tv2); return FAIL; } + if (tv1->v_type == VAR_FLOAT) + f2 = n2; + } + clear_tv(tv1); - 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); - 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); + // 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; @@ -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; @@ -4310,7 +4714,159 @@ handle_predefined(char_u *s, int len, typval_T *rettv) } break; } - return FAIL; + return FAIL; +} + +/* + * 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; } /* @@ -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; } @@ -5152,30 +5600,6 @@ check_can_index(typval_T *rettv, int evaluate, int verbose) return OK; } -/* - * 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]. @@ -5421,768 +5845,387 @@ partial_unref(partial_T *pt) if (pt->pt_loopvars[depth] != NULL && loopvars_check_refcount(pt->pt_loopvars[depth])) break; - } - } -} - -/* - * 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". + * 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 -set_ref_in_callback(callback_T *cb, int copyID) + static char_u * +string_tv2string( + typval_T *tv, + char_u **tofree, + int echo_style, + int composite_val) { - typval_T tv; + char_u *r = NULL; - if (cb->cb_name == NULL || *cb->cb_name == NUL || cb->cb_partial == NULL) - return FALSE; + 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; + } - tv.v_type = VAR_PARTIAL; - tv.vval.v_partial = cb->cb_partial; - return set_ref_in_item(&tv, copyID, NULL, NULL); + return r; } /* - * Mark the dict "dd" with "copyID". - * Also see set_ref_in_item(). + * 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. */ - static int -set_ref_in_item_dict( - dict_T *dd, - int copyID, - ht_stack_T **ht_stack, - list_stack_T **list_stack) + static char_u * +func_tv2string(typval_T *tv, char_u **tofree, int echo_style) { - if (dd == NULL || dd->dv_copyID == copyID) - return FALSE; + char_u *r = NULL; + char_u buf[MAX_FUNC_NAME_LEN]; + + if (echo_style) + { + *tofree = NULL; - // 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); + if (tv->vval.v_string == NULL) + r = (char_u *)"function()"; + else + { + 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; - ht_stack_T *newitem = ALLOC_ONE(ht_stack_T); - if (newitem == NULL) - return TRUE; + if (tv->vval.v_string != NULL) + s = make_ufunc_name_readable(tv->vval.v_string, buf, + MAX_FUNC_NAME_LEN); - newitem->ht = &dd->dv_hashtab; - newitem->prev = *ht_stack; - *ht_stack = newitem; + r = *tofree = string_quote(s, TRUE); + } - return FALSE; + return r; } /* - * Mark the list "ll" with "copyID". - * Also see set_ref_in_item(). + * Return a textual representation of the object method in "tv", a VAR_PARTIAL. + * If the memory is allocated "tofree" is set to it, otherwise NULL. + * When "echo_style" is FALSE, put quotes around the function name as + * "function()", otherwise does not put quotes around function name. + * May return NULL. */ - static int -set_ref_in_item_list( - list_T *ll, - int copyID, - ht_stack_T **ht_stack, - list_stack_T **list_stack) + static char_u * +method_tv2string(typval_T *tv, char_u **tofree, int echo_style) { - 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; + char_u buf[MAX_FUNC_NAME_LEN]; + partial_T *pt = tv->vval.v_partial; - newitem->list = ll; - newitem->prev = *list_stack; - *list_stack = newitem; + size_t len = vim_snprintf((char *)buf, sizeof(buf), "<SNR>%d_%s.%s", + pt->pt_func->uf_script_ctx.sc_sid, + pt->pt_func->uf_class->class_name, + pt->pt_func->uf_name); + if (len >= sizeof(buf)) + { + if (echo_style) + { + *tofree = NULL; + return (char_u *)"function()"; + } + else + return *tofree = string_quote((char_u*)"", TRUE); + } - return FALSE; + return *tofree = echo_style ? vim_strsave(buf) : string_quote(buf, TRUE); } /* - * Mark the partial "pt" with "copyID". - * Also see set_ref_in_item(). + * 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. */ - static int -set_ref_in_item_partial( - partial_T *pt, - int copyID, - ht_stack_T **ht_stack, - list_stack_T **list_stack) + static char_u * +partial_tv2string( + typval_T *tv, + char_u **tofree, + char_u *numbuf, + int copyID) { - if (pt == NULL || pt->pt_copyID == copyID) - return FALSE; - - // Didn't see this partial yet. - pt->pt_copyID = copyID; + char_u *r = NULL; + partial_T *pt; + char_u *fname; + garray_T ga; + int i; + char_u *tf; - int abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID); + pt = tv->vval.v_partial; + fname = string_quote(pt == NULL ? NULL : partial_name(pt), FALSE); - if (pt->pt_dict != NULL) + 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; - 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); + ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID)); + vim_free(tf); } + // terminate with ')' and a NUL + ga_concat_len(&ga, (char_u *)")", 2); - 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() + *tofree = ga.ga_data; + r = *tofree; - 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) + { + // 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) { - dtv.v_type = VAR_CHANNEL; - dtv.vval.v_channel = job->jv_channel; - set_ref_in_item(&dtv, copyID, ht_stack, list_stack); + *tofree = NULL; + r = (char_u *)"[...]"; } - if (job->jv_exit_cb.cb_partial != NULL) + else { - 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); + int old_copyID; + if (restore_copyID) + 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; } - return FALSE; + 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); + int old_copyID; + if (restore_copyID) + 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; } - return FALSE; + return r; } -#endif /* - * Mark the class "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. */ - int -set_ref_in_item_class( - class_T *cl, - 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 (cl == NULL || cl->class_copyID == copyID) - return FALSE; +#ifdef FEAT_JOB_CHANNEL + *tofree = NULL; + + if (tv->v_type == VAR_JOB) + r = job_to_string_buf(tv, numbuf); + else + r = channel_to_string_buf(tv, numbuf); - cl->class_copyID = copyID; - if (cl->class_members_tv != NULL) + if (composite_val) { - // 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); + *tofree = string_quote(r, FALSE); + r = *tofree; } +#endif - 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 class in "tv". + * If the memory is allocated "tofree" is set to it, otherwise NULL. + * 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 * +class_tv2string(typval_T *tv, char_u **tofree) { - 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); + 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; } /* - * 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 an Object in "tv". + * If the memory is allocated "tofree" is set to it, otherwise NULL. + * When "copyID" is not zero replace recursive object with "...". + * When "restore_copyID" is FALSE, repeated items in the object are + * replaced with "...". May return NULL. */ - int -set_ref_in_item( - typval_T *tv, - int copyID, - ht_stack_T **ht_stack, - list_stack_T **list_stack) + static char_u * +object_tv2string( + typval_T *tv, + char_u **tofree, + int copyID, + int restore_copyID, + char_u *numbuf, + int echo_style, + int composite_val) { - int abort = FALSE; + char_u *r = NULL; - switch (tv->v_type) + object_T *obj = tv->vval.v_object; + if (obj == NULL || obj->obj_class == NULL) { - 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); + *tofree = NULL; + r = (char_u *)"object of [unknown]"; + } + else if (copyID != 0 && obj->obj_copyID == copyID + && obj->obj_class->class_obj_member_count != 0) + { + size_t n = 25 + strlen((char *)obj->obj_class->class_name); + r = alloc(n); + if (r != NULL) + (void)vim_snprintf((char *)r, n, "object of %s {...}", + obj->obj_class->class_name); + *tofree = r; + } + else + { + int old_copyID; + if (restore_copyID) + old_copyID = obj->obj_copyID; - 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; + obj->obj_copyID = copyID; + *tofree = object2string(obj, numbuf, copyID, echo_style, + restore_copyID, composite_val); + if (restore_copyID) + obj->obj_copyID = old_copyID; + r = *tofree; } - return 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. @@ -6209,7 +6252,7 @@ echo_string_core( { // Only give this message once for a recursive call to avoid // flooding the user with errors. And stop iterating over lists - // and dicts. + // and dicts and objects. did_echo_string_emsg = TRUE; emsg(_(e_variable_nested_too_deep_for_displaying)); } @@ -6221,155 +6264,31 @@ 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; - } + if (tv->vval.v_partial == NULL + || tv->vval.v_partial->pt_obj == NULL) + r = partial_tv2string(tv, tofree, numbuf, copyID); + else + r = method_tv2string(tv, tofree, echo_style); + break; case VAR_BLOB: 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 +6301,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,25 +6310,12 @@ 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, - echo_style, restore_copyID, - composite_val); + r = object_tv2string(tv, tofree, copyID, restore_copyID, + numbuf, echo_style, composite_val); break; case VAR_FLOAT: @@ -6451,7 +6348,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 ee703b5e13..47187c650d 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -28,6 +28,7 @@ static void f_balloon_show(typval_T *argvars, typval_T *rettv); static void f_balloon_split(typval_T *argvars, typval_T *rettv); # endif #endif +static void f_bindtextdomain(typval_T *argvars, typval_T *rettv); static void f_byte2line(typval_T *argvars, typval_T *rettv); static void f_call(typval_T *argvars, typval_T *rettv); static void f_changenr(typval_T *argvars, typval_T *rettv); @@ -72,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); @@ -79,6 +81,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv); static void f_hlID(typval_T *argvars, typval_T *rettv); static void f_hlexists(typval_T *argvars, typval_T *rettv); static void f_hostname(typval_T *argvars, typval_T *rettv); +static void f_id(typval_T *argvars, typval_T *rettv); static void f_index(typval_T *argvars, typval_T *rettv); static void f_indexof(typval_T *argvars, typval_T *rettv); static void f_input(typval_T *argvars, typval_T *rettv); @@ -1131,6 +1134,7 @@ static argcheck_T arg2_number_bool[] = {arg_number, arg_bool}; static argcheck_T arg2_number_dict_any[] = {arg_number, arg_dict_any}; static argcheck_T arg2_number_list[] = {arg_number, arg_list_any}; static argcheck_T arg2_number_string[] = {arg_number, arg_string}; +static argcheck_T arg2_number_buffer[] = {arg_number, arg_buffer}; static argcheck_T arg2_number_string_or_list[] = {arg_number, arg_string_or_list_any}; static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any}; static argcheck_T arg2_string[] = {arg_string, arg_string}; @@ -1321,7 +1325,6 @@ ret_list_items(int argcount UNUSED, *decl_type = &t_list_any; return &t_list_list_any; } - static type_T * ret_list_string_items(int argcount UNUSED, type2_T *argtypes UNUSED, @@ -1331,6 +1334,14 @@ ret_list_string_items(int argcount UNUSED, return &t_list_list_string; } static type_T * +ret_list_regionpos(int argcount UNUSED, + type2_T *argtypes UNUSED, + type_T **decl_type) +{ + *decl_type = &t_list_any; + return &t_list_list_list_number; +} + static type_T * ret_dict_any(int argcount UNUSED, type2_T *argtypes UNUSED, type_T **decl_type UNUSED) @@ -1821,6 +1832,8 @@ static funcentry_T global_functions[] = NULL #endif }, + {"bindtextdomain", 2, 2, 0, arg2_string, + ret_bool, f_bindtextdomain}, {"blob2list", 1, 1, FEARG_1, arg1_blob, ret_list_number, f_blob2list}, {"browse", 4, 4, 0, arg4_browse, @@ -1961,11 +1974,11 @@ static funcentry_T global_functions[] = ret_number, f_diff_hlID}, {"digraph_get", 1, 1, FEARG_1, arg1_string, ret_string, f_digraph_get}, - {"digraph_getlist",0, 1, FEARG_1, arg1_bool, + {"digraph_getlist", 0, 1, FEARG_1, arg1_bool, ret_list_string_items, f_digraph_getlist}, {"digraph_set", 2, 2, FEARG_1, arg2_string, ret_bool, f_digraph_set}, - {"digraph_setlist",1, 1, FEARG_1, arg1_list_string, + {"digraph_setlist", 1, 1, FEARG_1, arg1_list_string, ret_bool, f_digraph_setlist}, {"echoraw", 1, 1, FEARG_1, arg1_string, ret_void, f_echoraw}, @@ -2005,6 +2018,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, @@ -2135,6 +2150,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_regionpos, f_getregionpos}, {"getregtype", 0, 1, FEARG_1, arg1_string, ret_string, f_getregtype}, {"getscriptinfo", 0, 1, 0, arg1_dict_any, @@ -2147,7 +2164,7 @@ static funcentry_T global_functions[] = ret_any, f_gettabwinvar}, {"gettagstack", 0, 1, FEARG_1, arg1_number, ret_dict_any, f_gettagstack}, - {"gettext", 1, 1, FEARG_1, arg1_string, + {"gettext", 1, 2, FEARG_1, arg2_string, ret_string, f_gettext}, {"getwininfo", 0, 1, FEARG_1, arg1_number, ret_list_dict_any, f_getwininfo}, @@ -2197,6 +2214,8 @@ static funcentry_T global_functions[] = ret_string, f_hostname}, {"iconv", 3, 3, FEARG_1, arg3_string, ret_string, f_iconv}, + {"id", 1, 1, FEARG_1, NULL, + ret_string, f_id}, {"indent", 1, 1, FEARG_1, arg1_lnum, ret_number, f_indent}, {"index", 2, 4, FEARG_1, arg24_index, @@ -2415,6 +2434,8 @@ static funcentry_T global_functions[] = ret_void, PROP_FUNC(f_popup_move)}, {"popup_notification", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict, ret_number, PROP_FUNC(f_popup_notification)}, + {"popup_setbuf", 2, 2, FEARG_1, arg2_number_buffer, + ret_number_bool, PROP_FUNC(f_popup_setbuf)}, {"popup_setoptions", 2, 2, FEARG_1, arg2_number_dict_any, ret_void, PROP_FUNC(f_popup_setoptions)}, {"popup_settext", 2, 2, FEARG_1, arg2_number_string_or_list, @@ -3116,8 +3137,8 @@ internal_func_check_arg_types( // functions, check the arguments are not types. if (!(func_allows_type(idx))) { - for (int i = 0; i < argcount; ++i) - if (check_type_is_value(types[i].type_curr) == FAIL) + for (int i = 0; i < argcount; ++i) + if (check_type_is_value(types[i].type_curr) == FAIL) return FAIL; } @@ -3471,6 +3492,33 @@ get_buf_arg(typval_T *arg) return buf; } +/* + * "bindtextdomain(package, path)" function + */ + static void +f_bindtextdomain(typval_T *argvars, typval_T *rettv) +{ + rettv->v_type = VAR_BOOL; + rettv->vval.v_number = VVAL_TRUE; + + if (check_for_nonempty_string_arg(argvars, 0) == FAIL + || check_for_nonempty_string_arg(argvars, 1) == FAIL) + return; + + if (strcmp((const char *)argvars[0].vval.v_string, VIMPACKAGE) == 0) + semsg(_(e_invalid_argument_str), tv_get_string(&argvars[0])); + else + { + if (bindtextdomain((const char *)argvars[0].vval.v_string, (const char *)argvars[1].vval.v_string) == NULL) + { + do_outofmem_msg((long)0); + rettv->vval.v_number = VVAL_FALSE; + } + } + + return; +} + /* * "byte2line(byte)" function */ @@ -3843,8 +3891,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. @@ -3961,7 +4010,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; @@ -4457,7 +4506,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; @@ -5107,6 +5156,36 @@ f_get(typval_T *argvars, typval_T *rettv) list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]); } } + else if (STRCMP(what, "arity") == 0) + { + int required = 0, optional = 0, varargs = FALSE; + char_u *name = partial_name(pt); + + get_func_arity(name, &required, &optional, &varargs); + + rettv->v_type = VAR_DICT; + if (rettv_dict_alloc(rettv) == OK) + { + dict_T *dict = rettv->vval.v_dict; + + // Take into account the arguments of the partial, if any. + // Note that it is possible to supply more arguments than the function + // accepts. + if (pt->pt_argc >= required + optional) + required = optional = 0; + else if (pt->pt_argc > required) + { + optional -= pt->pt_argc - required; + required = 0; + } + else + required -= pt->pt_argc; + + dict_add_number(dict, "required", required); + dict_add_number(dict, "optional", optional); + dict_add_bool(dict, "varargs", varargs); + } + } else semsg(_(e_invalid_argument_str), what); @@ -5463,7 +5542,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; @@ -5483,40 +5562,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) { @@ -5534,120 +5609,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)); @@ -5678,6 +5775,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; @@ -5828,11 +6106,39 @@ f_gettagstack(typval_T *argvars, typval_T *rettv) static void f_gettext(typval_T *argvars, typval_T *rettv) { - if (check_for_nonempty_string_arg(argvars, 0) == FAIL) +#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) + char *prev = NULL; +#endif + + if (check_for_nonempty_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL) return; rettv->v_type = VAR_STRING; - rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string)); + + if (argvars[1].v_type == VAR_STRING && + argvars[1].vval.v_string != NULL && + *(argvars[1].vval.v_string) != NUL) + { +#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) + prev = bind_textdomain_codeset((const char *)argvars[1].vval.v_string, (char *)p_enc); +#endif + +#if defined(HAVE_DGETTEXT) + rettv->vval.v_string = vim_strsave((char_u *)dgettext((const char *)argvars[1].vval.v_string, (const char *)argvars[0].vval.v_string)); +#else + textdomain((const char *)argvars[1].vval.v_string); + rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string)); + textdomain(VIMPACKAGE); +#endif + +#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) + if (prev != NULL) + bind_textdomain_codeset((const char *)argvars[1].vval.v_string, prev); +#endif + } + else + rettv->vval.v_string = vim_strsave((char_u *)_(argvars[0].vval.v_string)); } // for VIM_VERSION_ defines @@ -7267,6 +7573,46 @@ f_hostname(typval_T *argvars UNUSED, typval_T *rettv) rettv->vval.v_string = vim_strsave(hostname); } +/* + * "id()" function + * Identity. Return address of item as a hex string, %p format. + * Currently only valid for object/container types. + * Return empty string if not an object. + */ + static void +f_id(typval_T *argvars, typval_T *rettv) +{ + char numbuf[NUMBUFLEN]; + char *p = numbuf; + + switch (argvars[0].v_type) + { + case VAR_LIST: + case VAR_DICT: + case VAR_OBJECT: + case VAR_JOB: + case VAR_CHANNEL: + case VAR_BLOB: + // Assume pointer value in typval_T vval union at common location. + if (argvars[0].vval.v_object != NULL) + { + // "v" gets the address as an integer + uintptr_t v = (uintptr_t)(void *)argvars[0].vval.v_object; + // Build a hex string from the item's address; it is in + // reverse order. Ignore trailing zeros. + for (; p < numbuf + sizeof(uintptr_t) * 2 && v != 0; + ++p, v >>= 4) + *p = "0123456789abcdef"[v & 0xf]; + } + default: + break; + } + *p = NUL; + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = vim_strsave((char_u *)numbuf); +} + /* * "index()" function */ @@ -7316,7 +7662,7 @@ f_index(typval_T *argvars, typval_T *rettv) { tv.v_type = VAR_NUMBER; tv.vval.v_number = blob_get(b, idx); - if (tv_equal(&tv, &argvars[1], ic, FALSE)) + if (tv_equal(&tv, &argvars[1], ic)) { rettv->vval.v_number = idx; return; @@ -7349,7 +7695,7 @@ f_index(typval_T *argvars, typval_T *rettv) } for ( ; item != NULL; item = item->li_next, ++idx) - if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE)) + if (tv_equal(&item->li_tv, &argvars[1], ic)) { rettv->vval.v_number = idx; break; @@ -7406,6 +7752,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); @@ -7413,6 +7760,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; @@ -7448,6 +7798,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); @@ -7458,6 +7809,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; @@ -7481,7 +7835,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; @@ -9038,69 +9394,47 @@ f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED) static void init_srand(UINT32_T *x) { -#ifndef MSWIN - static int dev_urandom_state = NOTDONE; // FAIL or OK once tried -#endif + struct { + union { + UINT32_T number; + char_u bytes[sizeof(UINT32_T)]; + } contents; + } buf; if (srand_seed_for_testing_is_used) { *x = srand_seed_for_testing; return; } -#ifndef MSWIN - if (dev_urandom_state != FAIL) - { - int fd = open("/dev/urandom", O_RDONLY); - struct { - union { - UINT32_T number; - char bytes[sizeof(UINT32_T)]; - } contents; - } buf; - // Attempt reading /dev/urandom. - if (fd == -1) - dev_urandom_state = FAIL; - else - { - buf.contents.number = 0; - if (read(fd, buf.contents.bytes, sizeof(UINT32_T)) - != sizeof(UINT32_T)) - dev_urandom_state = FAIL; - else - { - dev_urandom_state = OK; - *x = buf.contents.number; - } - close(fd); - } - } - if (dev_urandom_state != OK) -#endif + if (mch_get_random(buf.contents.bytes, sizeof(buf.contents.bytes)) == OK) { - // Reading /dev/urandom doesn't work, fall back to: - // - randombytes_random() - // - reltime() or time() - // - XOR with process ID + *x = buf.contents.number; + return; + } + + // The system's random number generator doesn't work, fall back to: + // - randombytes_random() + // - reltime() or time() + // - XOR with process ID #if defined(FEAT_SODIUM) - if (crypt_sodium_init() >= 0) - *x = crypt_sodium_randombytes_random(); - else + if (crypt_sodium_init() >= 0) + *x = crypt_sodium_randombytes_random(); + else #endif - { + { #if defined(FEAT_RELTIME) - proftime_T res; - profile_start(&res); + proftime_T res; + profile_start(&res); # if defined(MSWIN) - *x = (UINT32_T)res.LowPart; + *x = (UINT32_T)res.LowPart; # else - *x = (UINT32_T)res.tv_fsec; + *x = (UINT32_T)res.tv_fsec; # endif #else - *x = vim_time(); + *x = vim_time(); #endif - *x ^= mch_get_pid(); - } + *x ^= mch_get_pid(); } } @@ -9578,6 +9912,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; @@ -9652,10 +9987,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. @@ -10068,6 +10405,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; @@ -10087,15 +10431,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; @@ -10112,13 +10465,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 @@ -10753,7 +11107,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 } @@ -10822,7 +11176,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(); @@ -11535,7 +11889,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; @@ -11543,11 +11897,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/evalvars.c b/src/evalvars.c index f102606d12..85d6ac5df7 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -3342,12 +3342,31 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload) } } + // and finally try + return find_var_autoload_prefix(name, 0, htp, NULL); +} + +/* + * Find variable "name" with sn_autoload_prefix. + * Return a pointer to it if found, NULL if not found. + * When "sid" > 0, use it otherwise use "current_sctx.sc_sid". + * When "htp" is not NULL set "htp" to the hashtab_T used. + * When "namep" is not NULL set "namep" to the generated name, and + * then the caller gets ownership and is responsible for freeing the name. + */ + dictitem_T * +find_var_autoload_prefix(char_u *name, int sid, hashtab_T **htp, + char_u **namep) +{ + hashtab_T *ht; + dictitem_T *ret = NULL; // When using "vim9script autoload" script-local items are prefixed but can // be used with s:name. - if (SCRIPT_ID_VALID(current_sctx.sc_sid) + int check_sid = sid > 0 ? sid : current_sctx.sc_sid; + if (SCRIPT_ID_VALID(check_sid) && (in_vim9script() || (name[0] == 's' && name[1] == ':'))) { - scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); + scriptitem_T *si = SCRIPT_ITEM(check_sid); if (si->sn_autoload_prefix != NULL) { @@ -3357,20 +3376,26 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload) if (auto_name != NULL) { + int free_auto_name = TRUE; ht = &globvarht; ret = find_var_in_ht(ht, 'g', auto_name, TRUE); - vim_free(auto_name); if (ret != NULL) { if (htp != NULL) *htp = ht; - return ret; + if (namep != NULL) + { + free_auto_name = FALSE; + *namep = auto_name; + } } + if (free_auto_name) + vim_free(auto_name); } } } - return NULL; + return ret; } /* @@ -3510,7 +3535,11 @@ lookup_scriptitem( hi = hash_find(ht, p); res = HASHITEM_EMPTY(hi) ? FAIL : OK; - // if not script-local, then perhaps imported + // if not script-local, then perhaps autoload-exported + if (res == FAIL && find_var_autoload_prefix(p, 0, NULL, NULL) != NULL) + res = OK; + + // if not script-local or autoload, then perhaps imported if (res == FAIL && find_imported(p, 0, FALSE) != NULL) res = OK; if (p != buffer) @@ -3906,23 +3935,40 @@ set_var_const( if (sid != 0) { + varname = NULL; if (SCRIPT_ID_VALID(sid)) - ht = &SCRIPT_VARS(sid); - varname = name; + { + char_u *auto_name = NULL; + if (find_var_autoload_prefix(name, sid, &ht, &auto_name) != NULL) + { + var_in_autoload = TRUE; + varname = auto_name; + name_tofree = varname; + } + else + ht = &SCRIPT_VARS(sid); + } + if (varname == NULL) + varname = name; } else { - scriptitem_T *si; + scriptitem_T *si; + char_u *auto_name = NULL; - if (in_vim9script() && is_export - && SCRIPT_ID_VALID(current_sctx.sc_sid) - && (si = SCRIPT_ITEM(current_sctx.sc_sid)) - ->sn_autoload_prefix != NULL) + if (in_vim9script() + && SCRIPT_ID_VALID(current_sctx.sc_sid) + && (si = SCRIPT_ITEM(current_sctx.sc_sid)) + ->sn_autoload_prefix != NULL + && (is_export + || find_var_autoload_prefix(name, 0, NULL, &auto_name) + != NULL)) { // In a vim9 autoload script an exported variable is put in the // global namespace with the autoload prefix. var_in_autoload = TRUE; - varname = concat_str(si->sn_autoload_prefix, name); + varname = auto_name != NULL ? auto_name + : concat_str(si->sn_autoload_prefix, name); if (varname == NULL) goto failed; name_tofree = varname; @@ -4191,6 +4237,7 @@ set_var_const( * - Whether the variable is read-only * - Whether the variable value is locked * - Whether the variable is locked + * NOTE: "name" is only used for error messages. */ int var_check_permission(dictitem_T *di, char_u *name) diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 2a5d842fc9..c365937983 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3360,7 +3360,13 @@ ex_append(exarg_T *eap) indent = get_indent_lnum(lnum); } ex_keep_indent = FALSE; - if (eap->ea_getline == NULL) + if (*eap->arg == '|') + { + // Get the text after the trailing bar. + theline = vim_strsave(eap->arg + 1); + *eap->arg = NUL; + } + else if (eap->ea_getline == NULL) { // No getline() function, use the lines that follow. This ends // when there is no more. @@ -3750,6 +3756,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 +3830,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 +3838,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 +3892,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 +3939,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 +4076,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 +5114,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 +5161,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 +5177,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 +5635,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 +5653,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 +5674,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 98d32dd130..aff945838a 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -99,13 +99,14 @@ typedef struct exarg exarg_T; */ #ifdef DO_DECLARE_EXCMD # define EXCMD(a, b, c, d, e) \ - {(char_u *)b, c, (long_u)(d), e} + {(char_u *)b, STRLEN_LITERAL(b), c, (long_u)(d), e} typedef void (*ex_func_T) (exarg_T *eap); static struct cmdname { char_u *cmd_name; // name of the command + size_t cmd_namelen; // length of the command name ex_func_T cmd_func; // function for this command long_u cmd_argt; // flags declared above cmd_addr_T cmd_addr_type; // flag for address type @@ -128,7 +129,7 @@ EXCMD(CMD_aboveleft, "aboveleft", ex_wrongmodifier, EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM, ADDR_NONE), EXCMD(CMD_abstract, "abstract", ex_class, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, + EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_all, "all", ex_all, EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR, @@ -270,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), @@ -288,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), @@ -330,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), @@ -356,7 +357,7 @@ EXCMD(CMD_clast, "clast", ex_cc, EX_RANGE|EX_COUNT|EX_TRLBAR|EX_BANG, ADDR_UNSIGNED), EXCMD(CMD_class, "class", ex_class, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, + EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_close, "close", ex_close, EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, @@ -596,7 +597,7 @@ EXCMD(CMD_enew, "enew", ex_edit, EX_BANG|EX_TRLBAR, ADDR_NONE), EXCMD(CMD_enum, "enum", ex_class, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, + EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_eval, "eval", ex_eval, EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, @@ -758,7 +759,7 @@ EXCMD(CMD_intro, "intro", ex_intro, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_interface, "interface", ex_class, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, + EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_isearch, "isearch", ex_findpat, EX_BANG|EX_RANGE|EX_DFLALL|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK, @@ -819,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), @@ -831,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), @@ -885,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 4927f76c82..c361e12a28 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -19,6 +19,10 @@ static int ex_pressedreturn = FALSE; # define ex_hardcopy ex_ni #endif +#if defined(FEAT_EVAL) || defined(PROTO) +static int cmp_cmdmod_info(const void *a, const void *b); +#endif + #ifdef FEAT_EVAL static char_u *do_one_cmd(char_u **, int, cstack_T *, char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie); #else @@ -82,7 +86,7 @@ static void correct_range(exarg_T *eap); #ifdef FEAT_QUICKFIX static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep); #endif -static char_u *repl_cmdline(exarg_T *eap, char_u *src, int srclen, char_u *repl, char_u **cmdlinep); +static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen, char_u *repl, char_u **cmdlinep); static void ex_highlight(exarg_T *eap); static void ex_colorscheme(exarg_T *eap); static void ex_cquit(exarg_T *eap); @@ -1462,8 +1466,13 @@ handle_did_throw(void) current_exception->throw_name = NULL; discard_current_exception(); // uses IObuff if 'verbose' - suppress_errthrow = TRUE; - force_abort = TRUE; + + // If "silent!" is active the uncaught exception is not fatal. + if (emsg_silent == 0) + { + suppress_errthrow = TRUE; + force_abort = TRUE; + } if (messages != NULL) { @@ -2338,12 +2347,7 @@ do_one_cmd( { for (p = ea.arg; *p; ++p) { - // Remove one backslash before a newline, so that it's possible to - // pass a newline to the shell and also a newline that is preceded - // with a backslash. This makes it impossible to end a shell - // command in a backslash, but that doesn't appear useful. - // Halving the number of backslashes is incompatible with previous - // versions. + // Remove one backslash before a newline if (*p == '\\' && p[1] == '\n') STRMOVE(p, p + 1); else if (*p == '\n' && !(ea.argt & EX_EXPR_ARG)) @@ -2723,6 +2727,12 @@ ex_errmsg(char *msg, char_u *arg) return ex_error_buf; } +/* + * The "+" string used in place of an empty command in Ex mode. + * This string is used in pointer comparison. + */ +static char exmode_plus[] = "+"; + /* * Handle a range without a command. * Returns an error message on failure. @@ -2732,7 +2742,8 @@ ex_range_without_command(exarg_T *eap) { char *errormsg = NULL; - if ((*eap->cmd == '|' || (exmode_active && eap->line1 != eap->line2)) + if ((*eap->cmd == '|' || + (exmode_active && eap->cmd != (char_u *)exmode_plus + 1)) #ifdef FEAT_EVAL && !in_vim9script() #endif @@ -2862,9 +2873,8 @@ parse_command_modifiers( { // The automatically inserted Visual area range is skipped, so that // typing ":cmdmod cmd" in Visual mode works without having to move the - // range to after the modififiers. The command will be - // "'<,'>cmdmod cmd", parse "cmdmod cmd" and then put back "'<,'>" - // before "cmd" below. + // range to after the modifiers. The command will be "'<,'>cmdmod cmd", + // parse "cmdmod cmd" and then put back "'<,'>" before "cmd" below. eap->cmd += 5; cmd_start = eap->cmd; has_visual_range = TRUE; @@ -2951,7 +2961,7 @@ parse_command_modifiers( switch (*p) { - // When adding an entry, also modify cmdmods[]. + // When adding an entry, also modify cmdmod_info_tab[]. case 'a': if (!checkforcmd_noparen(&eap->cmd, "aboveleft", 3)) break; cmod->cmod_split |= WSP_ABOVE; @@ -3215,7 +3225,7 @@ parse_command_modifiers( eap->cmd = orig_cmd; } else if (use_plus_cmd) - eap->cmd = (char_u *)"+"; + eap->cmd = (char_u *)exmode_plus; return OK; } @@ -3961,7 +3971,7 @@ find_ex_command( if (eap->cmdidx == CMD_mode || eap->cmdidx == CMD_Print) eap->cmdidx = CMD_SIZE; else if ((cmdnames[eap->cmdidx].cmd_argt & EX_WHOLE) - && len < (int)STRLEN(cmdnames[eap->cmdidx].cmd_name)) + && len < (int)cmdnames[eap->cmdidx].cmd_namelen) { semsg(_(e_command_cannot_be_shortened_str), eap->cmd); eap->cmdidx = CMD_SIZE; @@ -4010,12 +4020,14 @@ find_ex_command( } #if defined(FEAT_EVAL) || defined(PROTO) -static struct cmdmod +typedef struct { char *name; int minlen; int has_count; // :123verbose :3tab -} cmdmods[] = { +} cmdmod_info_T; + +static cmdmod_info_T cmdmod_info_tab[] = { {"aboveleft", 3, FALSE}, {"belowright", 3, FALSE}, {"botright", 2, FALSE}, @@ -4041,8 +4053,18 @@ static struct cmdmod {"unsilent", 3, FALSE}, {"verbose", 4, TRUE}, {"vertical", 4, FALSE}, - {"vim9cmd", 4, FALSE}, -}; + {"vim9cmd", 4, FALSE} +}; // cmdmod_info_tab + +// compare two cmdmod_info_T structs by case sensitive name with length + static int +cmp_cmdmod_info(const void *a, const void *b) +{ + cmdmod_info_T *cm1 = (cmdmod_info_T *)a; + cmdmod_info_T *cm2 = (cmdmod_info_T *)b; + + return STRNCMP(cm1->name, cm2->name, cm2->minlen); +} /* * Return length of a command modifier (including optional count). @@ -4051,20 +4073,36 @@ static struct cmdmod int modifier_len(char_u *cmd) { - int i, j; char_u *p = cmd; + cmdmod_info_T target; + cmdmod_info_T *entry; if (VIM_ISDIGIT(*cmd)) p = skipwhite(skipdigits(cmd + 1)); - for (i = 0; i < (int)ARRAY_LENGTH(cmdmods); ++i) + + // only lowercase characters can match + if (!ASCII_ISLOWER(*p)) + return 0; + + target.name = (char *)p; + target.minlen = 0; // not used, see cmp_cmdmod_info() + target.has_count = FALSE; + + entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info); + if (entry != NULL) { - for (j = 0; p[j] != NUL; ++j) - if (p[j] != cmdmods[i].name[j]) + int i; + + for (i = entry->minlen; p[i] != NUL; ++i) + { + if (p[i] != entry->name[i]) break; - if (!ASCII_ISALPHA(p[j]) && j >= cmdmods[i].minlen - && (p == cmd || cmdmods[i].has_count)) - return j + (int)(p - cmd); + } + + if (!ASCII_ISALPHA(p[i]) && i >= entry->minlen && (p == cmd || entry->has_count)) + return i + (int)(p - cmd); } + return 0; } @@ -4078,18 +4116,33 @@ cmd_exists(char_u *name) { exarg_T ea; int full = FALSE; - int i; - int j; char_u *p; - // Check command modifiers. - for (i = 0; i < (int)ARRAY_LENGTH(cmdmods); ++i) + // only lowercase characters can match + if (ASCII_ISLOWER(*name)) { - for (j = 0; name[j] != NUL; ++j) - if (name[j] != cmdmods[i].name[j]) - break; - if (name[j] == NUL && j >= cmdmods[i].minlen) - return (cmdmods[i].name[j] == NUL ? 2 : 1); + cmdmod_info_T target; + cmdmod_info_T *entry; + + target.name = (char *)name; + target.minlen = 0; // not used, see cmp_cmdmod_info() + target.has_count = FALSE; + + // Check command modifiers. + entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info); + if (entry != NULL) + { + int i; + + for (i = entry->minlen; name[i] != NUL; ++i) + { + if (name[i] != entry->name[i]) + break; + } + + if (name[i] == NUL && i >= entry->minlen) + return (entry->name[i] == NUL ? 2 : 1); + } } // Check built-in commands and user defined commands. @@ -4526,7 +4579,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; @@ -4580,7 +4633,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 { @@ -4657,6 +4710,7 @@ get_address( if (n == MAXLNUM) { emsg(_(e_line_number_out_of_range)); + cmd = NULL; goto error; } } @@ -4687,6 +4741,7 @@ get_address( if (lnum >= 0 && n >= LONG_MAX - lnum) { emsg(_(e_line_number_out_of_range)); + cmd = NULL; goto error; } lnum += n; @@ -5003,12 +5058,14 @@ replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep) } else { - new_cmdline = alloc(STRLEN(program) + STRLEN(p) + 2); + size_t program_len = STRLEN(program); + + new_cmdline = alloc(program_len + STRLEN(p) + 2); if (new_cmdline == NULL) return NULL; // out of memory STRCPY(new_cmdline, program); - STRCAT(new_cmdline, " "); - STRCAT(new_cmdline, p); + STRCPY(new_cmdline + program_len, " "); + STRCPY(new_cmdline + program_len + 1, p); } msg_make(p); @@ -5034,7 +5091,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; @@ -5229,7 +5286,7 @@ expand_filename( } if (p != NULL) { - (void)repl_cmdline(eap, eap->arg, (int)STRLEN(eap->arg), + (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep); if (n == 2) // p came from ExpandOne() vim_free(p); @@ -5252,23 +5309,26 @@ expand_filename( repl_cmdline( exarg_T *eap, char_u *src, - int srclen, + size_t srclen, char_u *repl, char_u **cmdlinep) { - int len; - int i; + size_t repllen; + size_t taillen; + size_t i; char_u *new_cmdline; + size_t new_cmdlinelen; /* * The new command line is build in new_cmdline[]. * First allocate it. * Careful: a "+cmd" argument may have been NUL terminated. */ - len = (int)STRLEN(repl); - i = (int)(src - *cmdlinep) + (int)STRLEN(src + srclen) + len + 3; + repllen = STRLEN(repl); + taillen = STRLEN(src + srclen); + i = (src - *cmdlinep) + repllen + taillen + 3; if (eap->nextcmd != NULL) - i += (int)STRLEN(eap->nextcmd);// add space for next command + i += STRLEN(eap->nextcmd); // add space for next command if ((new_cmdline = alloc(i)) == NULL) return NULL; // out of memory! @@ -5278,19 +5338,19 @@ repl_cmdline( * Copy what came after the expanded part. * Copy the next commands, if there are any. */ - i = (int)(src - *cmdlinep); // length of part before match - mch_memmove(new_cmdline, *cmdlinep, (size_t)i); + new_cmdlinelen = src - *cmdlinep; // length of part before replacement + mch_memmove(new_cmdline, *cmdlinep, new_cmdlinelen); - mch_memmove(new_cmdline + i, repl, (size_t)len); - i += len; // remember the end of the string - STRCPY(new_cmdline + i, src + srclen); - src = new_cmdline + i; // remember where to continue + mch_memmove(new_cmdline + new_cmdlinelen, repl, repllen); + new_cmdlinelen += repllen; // remember the end of the string + STRCPY(new_cmdline + new_cmdlinelen, src + srclen); + src = new_cmdline + new_cmdlinelen; // remember where to continue if (eap->nextcmd != NULL) // append next command { - i = (int)STRLEN(new_cmdline) + 1; - STRCPY(new_cmdline + i, eap->nextcmd); - eap->nextcmd = new_cmdline + i; + new_cmdlinelen += taillen + 1; + STRCPY(new_cmdline + new_cmdlinelen, eap->nextcmd); + eap->nextcmd = new_cmdline + new_cmdlinelen; } eap->cmd = new_cmdline + (eap->cmd - *cmdlinep); eap->arg = new_cmdline + (eap->arg - *cmdlinep); @@ -5355,7 +5415,11 @@ separate_nextcmd(exarg_T *eap, int keep_backslash) && in_vim9script() && !(eap->argt & EX_NOTRLCOM) && p > eap->cmd && VIM_ISWHITE(p[-1])) - || *p == '|' || *p == '\n') + || (*p == '|' + && eap->cmdidx != CMD_append + && eap->cmdidx != CMD_change + && eap->cmdidx != CMD_insert) + || *p == '\n') { /* * We remove the '\' before the '|', unless EX_CTRLV is used @@ -5461,9 +5525,10 @@ get_bad_name(expand_T *xp UNUSED, int idx) "drop", }; - if (idx < (int)ARRAY_LENGTH(p_bad_values)) - return (char_u*)p_bad_values[idx]; - return NULL; + if (idx < 0 || idx >= (int)ARRAY_LENGTH(p_bad_values)) + return NULL; + + return (char_u*)p_bad_values[idx]; } /* @@ -5577,9 +5642,10 @@ get_argopt_name(expand_T *xp UNUSED, int idx) "edit", }; - if (idx < (int)ARRAY_LENGTH(p_opt_values)) - return (char_u*)p_opt_values[idx]; - return NULL; + if (idx < 0 || idx >= (int)ARRAY_LENGTH(p_opt_values)) + return NULL; + + return (char_u*)p_opt_values[idx]; } /* @@ -7213,7 +7279,7 @@ ex_resize(exarg_T *eap) ex_find(exarg_T *eap) { if (!check_can_set_curbuf_forceit(eap->forceit)) - return; + return; char_u *fname; int count; @@ -7305,7 +7371,7 @@ ex_edit(exarg_T *eap) // All other commands must obey 'winfixbuf' / ! rules && (is_other_file(0, ffname) && !check_can_set_curbuf_forceit(eap->forceit)) ) - return; + return; do_exedit(eap, NULL); } @@ -9298,62 +9364,83 @@ ex_tag_cmd(exarg_T *eap, char_u *name) eap->forceit, TRUE); } +enum { + SPEC_PERC = 0, + SPEC_HASH, + SPEC_CWORD, // cursor word + SPEC_CCWORD, // cursor WORD + SPEC_CEXPR, // expr under cursor + SPEC_CFILE, // cursor path name + SPEC_SFILE, // ":so" file name + SPEC_SLNUM, // ":so" file line number + SPEC_STACK, // call stack + SPEC_SCRIPT, // script file name + SPEC_AFILE, // autocommand file name + SPEC_ABUF, // autocommand buffer number + SPEC_AMATCH, // autocommand match name + SPEC_SFLNUM, // script file line number + SPEC_SID // script ID: <SNR>123_ +#ifdef FEAT_CLIENTSERVER + , SPEC_CLIENT +#endif +}; + /* * Check "str" for starting with a special cmdline variable. * If found return one of the SPEC_ values and set "*usedlen" to the length of * the variable. Otherwise return -1 and "*usedlen" is unchanged. */ int -find_cmdline_var(char_u *src, int *usedlen) -{ - int len; - int i; - static char *(spec_str[]) = { - "%", -#define SPEC_PERC 0 - "#", -#define SPEC_HASH (SPEC_PERC + 1) - "<cword>", // cursor word -#define SPEC_CWORD (SPEC_HASH + 1) - "<cWORD>", // cursor WORD -#define SPEC_CCWORD (SPEC_CWORD + 1) - "<cexpr>", // expr under cursor -#define SPEC_CEXPR (SPEC_CCWORD + 1) - "<cfile>", // cursor path name -#define SPEC_CFILE (SPEC_CEXPR + 1) - "<sfile>", // ":so" file name -#define SPEC_SFILE (SPEC_CFILE + 1) - "<slnum>", // ":so" file line number -#define SPEC_SLNUM (SPEC_SFILE + 1) - "<stack>", // call stack -#define SPEC_STACK (SPEC_SLNUM + 1) - "<script>", // script file name -#define SPEC_SCRIPT (SPEC_STACK + 1) - "<afile>", // autocommand file name -#define SPEC_AFILE (SPEC_SCRIPT + 1) - "<abuf>", // autocommand buffer number -#define SPEC_ABUF (SPEC_AFILE + 1) - "<amatch>", // autocommand match name -#define SPEC_AMATCH (SPEC_ABUF + 1) - "<sflnum>", // script file line number -#define SPEC_SFLNUM (SPEC_AMATCH + 1) - "<SID>", // script ID: <SNR>123_ -#define SPEC_SID (SPEC_SFLNUM + 1) +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[] = { + KEYVALUE_ENTRY(SPEC_SID, "SID>"), // script ID: <SNR>123_ + KEYVALUE_ENTRY(SPEC_ABUF, "abuf>"), // autocommand buffer number + KEYVALUE_ENTRY(SPEC_AFILE, "afile>"), // autocommand file name + KEYVALUE_ENTRY(SPEC_AMATCH, "amatch>"), // autocommand match name + KEYVALUE_ENTRY(SPEC_CCWORD, "cWORD>"), // cursor WORD + KEYVALUE_ENTRY(SPEC_CEXPR, "cexpr>"), // expr under cursor + KEYVALUE_ENTRY(SPEC_CFILE, "cfile>"), // cursor path name #ifdef FEAT_CLIENTSERVER - "<client>" -# define SPEC_CLIENT (SPEC_SID + 1) -#endif + KEYVALUE_ENTRY(SPEC_CLIENT, "client>"), +#endif + KEYVALUE_ENTRY(SPEC_CWORD, "cword>"), // cursor word + KEYVALUE_ENTRY(SPEC_SCRIPT, "script>"), // script file name + KEYVALUE_ENTRY(SPEC_SFILE, "sfile>"), // ":so" file name + KEYVALUE_ENTRY(SPEC_SFLNUM, "sflnum>"), // script file line number + KEYVALUE_ENTRY(SPEC_SLNUM, "slnum>"), // ":so" file line number + KEYVALUE_ENTRY(SPEC_STACK, "stack>") // call stack }; + keyvalue_T target; + keyvalue_T *entry; - for (i = 0; i < (int)ARRAY_LENGTH(spec_str); ++i) + switch (*src) { - len = (int)STRLEN(spec_str[i]); - if (STRNCMP(src, spec_str[i], len) == 0) - { - *usedlen = len; - return i; - } + case '%': + *usedlen = 1; + return SPEC_PERC; + + case '#': + *usedlen = 1; + return SPEC_HASH; + + case '<': + target.key = 0; + target.value = (char *)src + 1; // skip over '<' + target.length = 0; // not used, see cmp_keyvalue_value_n() + + entry = (keyvalue_T *)bsearch(&target, &spec_str_tab, ARRAY_LENGTH(spec_str_tab), sizeof(spec_str_tab[0]), cmp_keyvalue_value_n); + if (entry == NULL) + return -1; + + *usedlen = entry->length + 1; + return entry->key; + + default: + break; } + return -1; } @@ -9385,7 +9472,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 @@ -9455,7 +9542,7 @@ eval_vars( */ else { - int off = 0; + size_t off = 0; switch (spec_idx) { @@ -9716,14 +9803,17 @@ eval_vars( expand_sfile(char_u *arg) { char *errormsg; - int len; char_u *result; + size_t resultlen; char_u *newres; + size_t len; char_u *repl; - int srclen; + size_t repllen; + size_t srclen; char_u *p; - result = vim_strsave(arg); + resultlen = STRLEN(arg); + result = vim_strnsave(arg, resultlen); if (result == NULL) return NULL; @@ -9747,18 +9837,20 @@ expand_sfile(char_u *arg) p += srclen; continue; } - len = (int)STRLEN(result) - srclen + (int)STRLEN(repl) + 1; - newres = alloc(len); + repllen = STRLEN(repl); + resultlen += repllen - srclen; + newres = alloc(resultlen + 1); if (newres == NULL) { vim_free(repl); vim_free(result); return NULL; } - mch_memmove(newres, result, (size_t)(p - result)); - STRCPY(newres + (p - result), repl); - len = (int)STRLEN(newres); - STRCAT(newres, p + srclen); + len = p - result; + mch_memmove(newres, result, len); + STRCPY(newres + len, repl); + len += repllen; + STRCPY(newres + len, p + srclen); vim_free(repl); vim_free(result); result = newres; diff --git a/src/ex_getln.c b/src/ex_getln.c index eb168cda73..49d947df3f 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) @@ -1586,6 +1586,7 @@ getcmdline_int( int res; int save_msg_scroll = msg_scroll; int save_State = State; // remember State when called + int prev_cmdpos = -1; int some_key_typed = FALSE; // one of the keys was typed // mouse drag and release events are ignored, unless they are // preceded with a mouse down event @@ -2482,6 +2483,13 @@ getcmdline_int( * (Sorry for the goto's, I know it is ugly). */ cmdline_not_changed: + // Trigger CursorMovedC autocommands. + if (ccline.cmdpos != prev_cmdpos) + { + trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC); + prev_cmdpos = ccline.cmdpos; + } + #ifdef FEAT_SEARCH_EXTRA if (!is_state.incsearch_postponed) continue; @@ -2493,10 +2501,17 @@ getcmdline_int( if (is_state.winid != curwin->w_id) init_incsearch_state(&is_state); #endif + // Trigger CmdlineChanged autocommands. if (trigger_cmdlinechanged) - // Trigger CmdlineChanged autocommands. trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED); + // Trigger CursorMovedC autocommands. + if (ccline.cmdpos != prev_cmdpos) + { + trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC); + prev_cmdpos = ccline.cmdpos; + } + #ifdef FEAT_SEARCH_EXTRA if (xpc.xp_context == EXPAND_NOTHING && (KeyTyped || vpeekc() == NUL)) may_do_incsearch_highlighting(firstc, count, &is_state); @@ -2548,12 +2563,14 @@ getcmdline_int( 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); } } @@ -3137,31 +3154,15 @@ getexmodeline( windgoto(msg_row, msg_col); pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len; - // We are done when a NL is entered, but not when it comes after an - // odd number of backslashes, that results in a NUL. - if (line_ga.ga_len > 0 && pend[-1] == '\n') + // We are done when a NL is entered, but not when it comes after a + // backslash in prompt mode. + if (line_ga.ga_len > 0 && pend[-1] == '\n' + && (line_ga.ga_len <= 1 || pend[-2] != '\\' || !promptc)) { - int bcount = 0; - - while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\') - ++bcount; - - if (bcount > 0) - { - // Halve the number of backslashes: "\NL" -> "NUL", "\\NL" -> - // "\NL", etc. - line_ga.ga_len -= (bcount + 1) / 2; - pend -= (bcount + 1) / 2; - pend[-1] = '\n'; - } - - if ((bcount & 1) == 0) - { - --line_ga.ga_len; - --pend; - *pend = NUL; - break; - } + --line_ga.ga_len; + --pend; + *pend = NUL; + break; } } @@ -4186,6 +4187,7 @@ get_cmdline_completion(void) { cmdline_info_T *p; char_u *buffer; + int xp_context; if (cmdline_star > 0) return NULL; @@ -4194,15 +4196,21 @@ get_cmdline_completion(void) if (p == NULL || p->xpc == NULL) return NULL; - set_expand_context(p->xpc); - if (p->xpc->xp_context == EXPAND_UNSUCCESSFUL) + xp_context = p->xpc->xp_context; + if (xp_context == EXPAND_NOTHING) + { + set_expand_context(p->xpc); + xp_context = p->xpc->xp_context; + p->xpc->xp_context = EXPAND_NOTHING; + } + if (xp_context == EXPAND_UNSUCCESSFUL) return NULL; - char_u *cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context); + char_u *cmd_compl = cmdcomplete_type_to_str(xp_context); if (cmd_compl == NULL) return NULL; - if (p->xpc->xp_context == EXPAND_USER_LIST || p->xpc->xp_context == EXPAND_USER_DEFINED) + if (xp_context == EXPAND_USER_LIST || xp_context == EXPAND_USER_DEFINED) { buffer = alloc(STRLEN(cmd_compl) + STRLEN(p->xpc->xp_arg) + 2); if (buffer == NULL) @@ -4318,6 +4326,7 @@ set_cmdline_pos( new_cmdpos = 0; else new_cmdpos = pos; + return 0; } diff --git a/src/fileio.c b/src/fileio.c index da5af6db0c..00b99facad 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3771,19 +3771,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; /* @@ -3904,6 +3897,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. @@ -3915,7 +3963,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. @@ -3927,7 +3975,7 @@ vim_rename(char_u *from, char_u *to) #ifdef HAVE_ACL mch_free_acl(acl); #endif - return -1; + return FAIL; } buffer = alloc(WRITEBUFSIZE); @@ -3938,7 +3986,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) @@ -3970,10 +4018,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 866966246d..e1cf10f493 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 @@ modify_fname( 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; @@ -3620,11 +3645,15 @@ dos_expandpath( } else { + stat_T sb; + // no more wildcards, check if there is a match // remove backslashes for the remaining components only if (*path_end != 0) backslash_halve(buf + len + 1); - if (mch_getperm(buf) >= 0) // add existing file + // add existing file + if ((flags & EW_ALLLINKS) ? mch_lstat((char *)buf, &sb) >= 0 + : mch_getperm(buf) >= 0) addfile(gap, buf, flags); } } @@ -3974,6 +4003,8 @@ gen_expand_wildcards( int add_pat; int retval = OK; int did_expand_in_path = FALSE; + char_u *path_option = *curbuf->b_p_path == NUL ? + p_path : curbuf->b_p_path; /* * expand_env() is called to expand things like "~user". If this fails, @@ -4063,7 +4094,7 @@ gen_expand_wildcards( */ if (mch_has_exp_wildcard(p) || (flags & EW_ICASE)) { - if ((flags & EW_PATH) + if ((flags & (EW_PATH | EW_CDPATH)) && !mch_isFullName(p) && !(p[0] == '.' && (vim_ispathsep(p[1]) @@ -4097,8 +4128,8 @@ gen_expand_wildcards( vim_free(t); } - if (did_expand_in_path && ga.ga_len > 0 && (flags & EW_PATH)) - uniquefy_paths(&ga, p); + if (did_expand_in_path && ga.ga_len > 0 && (flags & (EW_PATH | EW_CDPATH))) + uniquefy_paths(&ga, p, path_option); if (p != pat[i]) vim_free(p); } diff --git a/src/findfile.c b/src/findfile.c index 2636609250..4310a508c1 100644 --- a/src/findfile.c +++ b/src/findfile.c @@ -418,6 +418,7 @@ vim_findfile_init( { char_u *helper; void *ptr; + size_t len; helper = walker; ptr = vim_realloc(search_ctx->ffsc_stopdirs_v, @@ -428,18 +429,21 @@ vim_findfile_init( // ignore, keep what we have and continue break; walker = vim_strchr(walker, ';'); - if (walker) + len = walker ? (size_t)(walker - helper) : STRLEN(helper); + // "" means ascent till top of directory tree. + if (*helper != NUL && !vim_isAbsName(helper) + && len + 1 < MAXPATHL) { + // Make the stop dir an absolute path name. + vim_strncpy(ff_expand_buffer, helper, len); search_ctx->ffsc_stopdirs_v[dircount-1] = - vim_strnsave(helper, walker - helper); - walker++; + FullName_save(ff_expand_buffer, FALSE); } else - // this might be "", which means ascent till top - // of directory tree. search_ctx->ffsc_stopdirs_v[dircount-1] = - vim_strsave(helper); - + vim_strnsave(helper, len); + if (walker) + walker++; dircount++; } while (walker != NULL); @@ -1078,11 +1082,13 @@ vim_findfile(void *search_ctx_arg) && search_ctx->ffsc_stopdirs_v != NULL && !got_int) { ff_stack_T *sptr; + // path_end may point to the NUL or the previous path separator + int plen = (path_end - search_ctx->ffsc_start_dir) + + (*path_end != NUL); // is the last starting directory in the stop list? if (ff_path_in_stoplist(search_ctx->ffsc_start_dir, - (int)(path_end - search_ctx->ffsc_start_dir), - search_ctx->ffsc_stopdirs_v) == TRUE) + plen, search_ctx->ffsc_stopdirs_v) == TRUE) break; // cut of last dir @@ -1521,22 +1527,14 @@ ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v) return TRUE; for (i = 0; stopdirs_v[i] != NULL; i++) - { - if ((int)STRLEN(stopdirs_v[i]) > path_len) - { - // match for parent directory. So '/home' also matches - // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else - // '/home/r' would also match '/home/rks' - if (fnamencmp(stopdirs_v[i], path, path_len) == 0 - && vim_ispathsep(stopdirs_v[i][path_len])) - return TRUE; - } - else - { - if (fnamecmp(stopdirs_v[i], path) == 0) - return TRUE; - } - } + // match for parent directory. So '/home' also matches + // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else + // '/home/r' would also match '/home/rks' + if (fnamencmp(stopdirs_v[i], path, path_len) == 0 + && ((int)STRLEN(stopdirs_v[i]) <= path_len + || vim_ispathsep(stopdirs_v[i][path_len]))) + return TRUE; + return FALSE; } @@ -2213,10 +2211,11 @@ is_unique(char_u *maybe_unique, garray_T *gap, int i) * expanding each into their equivalent path(s). */ static void -expand_path_option(char_u *curdir, garray_T *gap) +expand_path_option( + char_u *curdir, + char_u *path_option, // p_path or p_cdpath + garray_T *gap) { - char_u *path_option = *curbuf->b_p_path == NUL - ? p_path : curbuf->b_p_path; char_u *buf; char_u *p; int len; @@ -2331,7 +2330,10 @@ get_path_cutoff(char_u *fname, garray_T *gap) * that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len". */ void -uniquefy_paths(garray_T *gap, char_u *pattern) +uniquefy_paths( + garray_T *gap, + char_u *pattern, + char_u *path_option) // p_path or p_cdpath { int i; int len; @@ -2374,7 +2376,7 @@ uniquefy_paths(garray_T *gap, char_u *pattern) if ((curdir = alloc(MAXPATHL)) == NULL) goto theend; mch_dirname(curdir, MAXPATHL); - expand_path_option(curdir, &path_ga); + expand_path_option(curdir, path_option, &path_ga); in_curdir = ALLOC_CLEAR_MULT(char_u *, gap->ga_len); if (in_curdir == NULL) @@ -2522,13 +2524,17 @@ expand_in_path( garray_T path_ga; char_u *paths = NULL; int glob_flags = 0; + char_u *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; if ((curdir = alloc(MAXPATHL)) == NULL) return 0; mch_dirname(curdir, MAXPATHL); ga_init2(&path_ga, sizeof(char_u *), 1); - expand_path_option(curdir, &path_ga); + if (flags & EW_CDPATH) + expand_path_option(curdir, p_cdpath, &path_ga); + else + expand_path_option(curdir, path_option, &path_ga); vim_free(curdir); if (path_ga.ga_len == 0) return 0; @@ -2542,7 +2548,7 @@ expand_in_path( glob_flags |= WILD_ICASE; if (flags & EW_ADDSLASH) glob_flags |= WILD_ADD_SLASH; - globpath(paths, pattern, gap, glob_flags, FALSE); + globpath(paths, pattern, gap, glob_flags, !!(flags & EW_CDPATH)); vim_free(paths); return gap->ga_len; diff --git a/src/gc.c b/src/gc.c new file mode 100644 index 0000000000..987ca27e76 --- /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/getchar.c b/src/getchar.c index 09abe3281a..15c432ed3d 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -42,6 +42,11 @@ static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; static int typeahead_char = 0; // typeahead char that's not flushed +#ifdef FEAT_EVAL +static char_u typedchars[MAXMAPLEN + 1] = { NUL }; // typed chars before map +static int typedchars_pos = 0; +#endif + /* * When block_redo is TRUE the redo buffer will not be changed. * Used by edit() to repeat insertions. @@ -96,6 +101,9 @@ static void closescript(void); static void updatescript(int c); static int vgetorpeek(int); static int inchar(char_u *buf, int maxlen, long wait_time); +#ifdef FEAT_EVAL +static int do_key_input_pre(int c); +#endif /* * Free and clear a buffer. @@ -1281,6 +1289,74 @@ del_typebuf(int len, int offset) typebuf.tb_change_cnt = 1; } +/* + * State for adding bytes to a recording or 'showcmd'. + */ +typedef struct +{ + char_u buf[MB_MAXBYTES * 3 + 4]; + int prev_c; + size_t buflen; + unsigned pending_special; + unsigned pending_mbyte; +} gotchars_state_T; + +/* + * Add a single byte to a recording or 'showcmd'. + * Return TRUE if a full key has been received, FALSE otherwise. + */ + static int +gotchars_add_byte(gotchars_state_T *state, char_u byte) +{ + int c = state->buf[state->buflen++] = byte; + int retval = FALSE; + int in_special = state->pending_special > 0; + int in_mbyte = state->pending_mbyte > 0; + + if (in_special) + state->pending_special--; + else if (c == K_SPECIAL +#ifdef FEAT_GUI + || c == CSI +#endif + ) + // When receiving a special key sequence, store it until we have all + // the bytes and we can decide what to do with it. + state->pending_special = 2; + + if (state->pending_special > 0) + goto ret_false; + + if (in_mbyte) + state->pending_mbyte--; + else + { + if (in_special) + { + if (state->prev_c == KS_MODIFIER) + // When receiving a modifier, wait for the modified key. + goto ret_false; + c = TO_SPECIAL(state->prev_c, c); + if (c == K_FOCUSGAINED || c == K_FOCUSLOST) + // Drop K_FOCUSGAINED and K_FOCUSLOST, they are not useful + // in a recording. + state->buflen = 0; + } + // When receiving a multibyte character, store it until we have all + // the bytes, so that it won't be split between two buffer blocks, + // and delete_buff_tail() will work properly. + state->pending_mbyte = MB_BYTE2LEN_CHECK(c) - 1; + } + + if (state->pending_mbyte > 0) + goto ret_false; + + retval = TRUE; +ret_false: + state->prev_c = c; + return retval; +} + /* * Write typed characters to script file. * If recording is on put the character in the record buffer. @@ -1290,78 +1366,26 @@ gotchars(char_u *chars, int len) { char_u *s = chars; size_t i; - int c = NUL; - static int prev_c = NUL; - static char_u buf[MB_MAXBYTES * 3 + 4]; - static size_t buflen = 0; - static unsigned pending = 0; - static int in_special = FALSE; - static int in_mbyte = FALSE; int todo = len; + static gotchars_state_T state; - for (; todo--; prev_c = c) + while (todo-- > 0) { - c = buf[buflen++] = *s++; - if (pending > 0) - pending--; - - // When receiving a special key sequence, store it until we have all - // the bytes and we can decide what to do with it. - if ((pending == 0 || in_mbyte) - && (c == K_SPECIAL -#ifdef FEAT_GUI - || c == CSI -#endif - )) - { - pending += 2; - if (!in_mbyte) - in_special = TRUE; - } - - if (pending > 0) + if (!gotchars_add_byte(&state, *s++)) continue; - if (!in_mbyte) - { - if (in_special) - { - in_special = FALSE; - if (prev_c == KS_MODIFIER) - // When receiving a modifier, wait for the modified key. - continue; - c = TO_SPECIAL(prev_c, c); - if (c == K_FOCUSGAINED || c == K_FOCUSLOST) - // Drop K_FOCUSGAINED and K_FOCUSLOST, they are not useful - // in a recording. - buflen = 0; - } - // When receiving a multibyte character, store it until we have all - // the bytes, so that it won't be split between two buffer blocks, - // and delete_buff_tail() will work properly. - pending = MB_BYTE2LEN_CHECK(c) - 1; - if (pending > 0) - { - in_mbyte = TRUE; - continue; - } - } - else - // Stored all bytes of a multibyte character. - in_mbyte = FALSE; - // Handle one byte at a time; no translation to be done. - for (i = 0; i < buflen; ++i) - updatescript(buf[i]); + for (i = 0; i < state.buflen; ++i) + updatescript(state.buf[i]); if (reg_recording != 0) { - buf[buflen] = NUL; - add_buff(&recordbuff, buf, (long)buflen); + state.buf[state.buflen] = NUL; + add_buff(&recordbuff, state.buf, (long)state.buflen); // remember how many chars were last recorded - last_recorded_len += buflen; + last_recorded_len += state.buflen; } - buflen = 0; + state.buflen = 0; } may_sync_undo(); @@ -1690,6 +1714,13 @@ updatescript(int c) ml_sync_all(c == 0, TRUE); count = 0; } +#ifdef FEAT_EVAL + if (typedchars_pos < MAXMAPLEN) + { + typedchars[typedchars_pos] = c; + typedchars_pos++; + } +#endif } /* @@ -1750,6 +1781,67 @@ merge_modifyOtherKeys(int c_arg, int *modifiers) return c; } +/* + * Add a single byte to 'showcmd' for a partially matched mapping. + * Call add_to_showcmd() if a full key has been received. + */ + static void +add_byte_to_showcmd(char_u byte) +{ + static gotchars_state_T state; + char_u *ptr; + int modifiers = 0; + int c = NUL; + + if (!p_sc || msg_silent != 0) + return; + + if (!gotchars_add_byte(&state, byte)) + return; + + state.buf[state.buflen] = NUL; + state.buflen = 0; + + ptr = state.buf; + if (ptr[0] == K_SPECIAL && ptr[1] == KS_MODIFIER && ptr[2] != NUL) + { + modifiers = ptr[2]; + ptr += 3; + } + + if (*ptr != NUL) + { + char_u *mb_ptr = mb_unescape(&ptr); + + c = mb_ptr != NULL ? (*mb_ptr2char)(mb_ptr) : *ptr++; + if (c <= 0x7f) + { + // Merge modifiers into the key to make the result more readable. + int modifiers_after = modifiers; + int mod_c = merge_modifyOtherKeys(c, &modifiers_after); + + if (modifiers_after == 0) + { + modifiers = 0; + c = mod_c; + } + } + } + + // TODO: is there a more readable and yet compact representation of + // modifiers and special keys? + if (modifiers != 0) + { + add_to_showcmd(K_SPECIAL); + add_to_showcmd(KS_MODIFIER); + add_to_showcmd(modifiers); + } + if (c != NUL) + add_to_showcmd(c); + while (*ptr != NUL) + add_to_showcmd(*ptr++); +} + /* * Get the next input character. * Can return a special key or a multi-byte character. @@ -1919,8 +2011,45 @@ vgetc(void) #endif } - // a keypad or special function key was not mapped, use it like - // its ASCII equivalent + // For a multi-byte character get all the bytes and return the + // converted character. + // Note: This will loop until enough bytes are received! + if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1) + { + ++no_mapping; + buf[0] = c; + for (i = 1; i < n; ++i) + { + buf[i] = vgetorpeek(TRUE); + if (buf[i] == K_SPECIAL +#ifdef FEAT_GUI + || (buf[i] == CSI) +#endif + ) + { + // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER + // sequence, which represents a K_SPECIAL (0x80), + // or a CSI - KS_EXTRA - KE_CSI sequence, which + // represents a CSI (0x9B), + // or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI + // too. + c = vgetorpeek(TRUE); + if (vgetorpeek(TRUE) == KE_CSI && c == KS_EXTRA) + buf[i] = CSI; + } + } + --no_mapping; + c = (*mb_ptr2char)(buf); + } + + if (vgetc_char == 0) + { + vgetc_mod_mask = mod_mask; + vgetc_char = c; + } + + // A keypad or special function key was not mapped, use it like + // its ASCII equivalent. switch (c) { case K_KPLUS: c = '+'; break; @@ -1982,43 +2111,6 @@ vgetc(void) case K_XRIGHT: c = K_RIGHT; break; } - // For a multi-byte character get all the bytes and return the - // converted character. - // Note: This will loop until enough bytes are received! - if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1) - { - ++no_mapping; - buf[0] = c; - for (i = 1; i < n; ++i) - { - buf[i] = vgetorpeek(TRUE); - if (buf[i] == K_SPECIAL -#ifdef FEAT_GUI - || (buf[i] == CSI) -#endif - ) - { - // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER - // sequence, which represents a K_SPECIAL (0x80), - // or a CSI - KS_EXTRA - KE_CSI sequence, which - // represents a CSI (0x9B), - // or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI - // too. - c = vgetorpeek(TRUE); - if (vgetorpeek(TRUE) == KE_CSI && c == KS_EXTRA) - buf[i] = CSI; - } - } - --no_mapping; - c = (*mb_ptr2char)(buf); - } - - if (vgetc_char == 0) - { - vgetc_mod_mask = mod_mask; - vgetc_char = c; - } - break; } @@ -2053,6 +2145,13 @@ vgetc(void) } #endif +#ifdef FEAT_EVAL + c = do_key_input_pre(c); + + // Clear the next typedchars_pos + typedchars_pos = 0; +#endif + // Need to process the character before we know it's safe to do something // else. if (c != K_IGNORE) @@ -2061,6 +2160,78 @@ vgetc(void) return c; } +#ifdef FEAT_EVAL +/* + * Handle the InsertCharPre autocommand. + * "c" is the character that was typed. + * Return new input character. + */ + static int +do_key_input_pre(int c) +{ + int res = c; + char_u buf[MB_MAXBYTES + 1]; + char_u curr_mode[MODE_MAX_LENGTH]; + int save_State = State; + save_v_event_T save_v_event; + dict_T *v_event; + + // Return quickly when there is nothing to do. + if (!has_keyinputpre()) + return res; + + if (IS_SPECIAL(c)) + { + buf[0] = K_SPECIAL; + buf[1] = KEY2TERMCAP0(c); + buf[2] = KEY2TERMCAP1(c); + buf[3] = NUL; + } + else + buf[(*mb_char2bytes)(c, buf)] = NUL; + + typedchars[typedchars_pos] = NUL; + vim_unescape_csi(typedchars); + + get_mode(curr_mode); + + // Lock the text to avoid weird things from happening. + ++textlock; + set_vim_var_string(VV_CHAR, buf, -1); // set v:char + + v_event = get_v_event(&save_v_event); + (void)dict_add_bool(v_event, "typed", KeyTyped); + (void)dict_add_string(v_event, "typedchar", typedchars); + + if (apply_autocmds(EVENT_KEYINPUTPRE, curr_mode, curr_mode, FALSE, curbuf) + && STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) + { + // Get the value of v:char. It may be empty or more than one + // character. Only use it when changed, otherwise continue with the + // original character. + char_u *v_char; + + v_char = get_vim_var_str(VV_CHAR); + + // Convert special bytes when it is special string. + if (STRLEN(v_char) >= 3 && v_char[0] == K_SPECIAL) + res = TERMCAP2KEY(v_char[1], v_char[2]); + else if (STRLEN(v_char) > 0) + res = PTR2CHAR(v_char); + } + + restore_v_event(v_event, &save_v_event); + + set_vim_var_string(VV_CHAR, NULL, -1); // clear v:char + --textlock; + + // Restore the State, it may have been changed. + State = save_State; + + return res; +} +#endif + /* * Like vgetc(), but never return a NUL when called recursively, get a key * directly from the user (ignoring typeahead). @@ -3595,7 +3766,7 @@ vgetorpeek(int advance) if (typebuf.tb_len > SHOWCMD_COLS) showcmd_idx = typebuf.tb_len - SHOWCMD_COLS; while (showcmd_idx < typebuf.tb_len) - (void)add_to_showcmd( + add_byte_to_showcmd( typebuf.tb_buf[typebuf.tb_off + showcmd_idx++]); curwin->w_wcol = old_wcol; curwin->w_wrow = old_wrow; diff --git a/src/globals.h b/src/globals.h index a482920abb..71e99ca790 100644 --- a/src/globals.h +++ b/src/globals.h @@ -131,8 +131,8 @@ EXTERN int screen_Columns INIT(= 0); // actual size of ScreenLines[] */ EXTERN int mod_mask INIT(= 0); // current key modifiers -// The value of "mod_mask" and the unomdified character before calling -// merge_modifyOtherKeys(). +// The value of "mod_mask" and the unmodified character in vgetc() after it has +// called vgetorpeek() enough times. EXTERN int vgetc_mod_mask INIT(= 0); EXTERN int vgetc_char INIT(= 0); @@ -519,28 +519,37 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE); #define t_list_list_any (static_types[70]) #define t_const_list_list_any (static_types[71]) -#define t_list_list_string (static_types[72]) -#define t_const_list_list_string (static_types[73]) +#define t_list_list_number (static_types[72]) +#define t_const_list_list_number (static_types[73]) -#define t_dict_bool (static_types[74]) -#define t_const_dict_bool (static_types[75]) +#define t_list_list_string (static_types[74]) +#define t_const_list_list_string (static_types[75]) -#define t_dict_number (static_types[76]) -#define t_const_dict_number (static_types[77]) +#define t_list_list_list_number (static_types[76]) +#define t_const_list_list_list_number (static_types[77]) -#define t_dict_string (static_types[78]) -#define t_const_dict_string (static_types[79]) +#define t_dict_bool (static_types[78]) +#define t_const_dict_bool (static_types[79]) -#define t_super (static_types[80]) -#define t_const_super (static_types[81]) +#define t_dict_number (static_types[80]) +#define t_const_dict_number (static_types[81]) -#define t_object (static_types[82]) -#define t_const_object (static_types[83]) +#define t_dict_string (static_types[82]) +#define t_const_dict_string (static_types[83]) -#define t_class (static_types[84]) -#define t_const_class (static_types[85]) +#define t_super (static_types[84]) +#define t_const_super (static_types[85]) -EXTERN type_T static_types[86] +#define t_object (static_types[86]) +#define t_const_object (static_types[87]) + +#define t_class (static_types[88]) +#define t_const_class (static_types[89]) + +#define t_typealias (static_types[90]) +#define t_const_typealias (static_types[91]) + +EXTERN type_T static_types[92] #ifdef DO_INIT = { // 0: t_unknown @@ -687,33 +696,45 @@ EXTERN type_T static_types[86] {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL, NULL}, - // 72: t_list_list_string + // 74: t_list_list_number + {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_number, NULL, NULL}, + {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_number, NULL, NULL}, + + // 74: t_list_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL, NULL}, - // 74: t_dict_bool + // 76: t_list_list_list_number + {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_list_number, NULL, NULL}, + {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_list_number, NULL, NULL}, + + // 78: t_dict_bool {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL}, - // 76: t_dict_number + // 80: t_dict_number {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL, NULL}, - // 78: t_dict_string + // 82: t_dict_string {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL, NULL}, - // 80: t_super (VAR_CLASS with tt_member set to &t_bool + // 84: t_super (VAR_CLASS with tt_member set to &t_bool {VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL, NULL}, {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL, NULL}, - // 82: t_object + // 86: t_object {VAR_OBJECT, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL}, {VAR_OBJECT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL}, - // 84: t_class + // 88: t_class {VAR_CLASS, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL}, {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL}, + + // 90: t_typealias + {VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC, NULL, NULL, NULL}, + {VAR_TYPEALIAS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL, NULL}, } #endif ; @@ -1933,6 +1954,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 7d529dc47c..5cdaf27ee4 100644 --- a/src/gui.c +++ b/src/gui.c @@ -460,7 +460,7 @@ gui_init_check(void) // and in that case we don't want to overwrite ligatures map that has already // been correctly populated (as that would lead to a cleared ligatures maps). if (*p_guiligatures == NUL) - CLEAR_FIELD(gui.ligatures_map); + CLEAR_FIELD(gui.ligatures_map); #endif #if defined(ALWAYS_USE_GUI) || defined(VIMDLL) @@ -5376,7 +5376,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 { @@ -5384,7 +5384,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 d4a8b93648..6c97d1a196 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -797,8 +797,8 @@ draw_event(GtkWidget *widget UNUSED, # if GTK_CHECK_VERSION(3,10,0) static gboolean scale_factor_event(GtkWidget *widget, - GParamSpec* pspec UNUSED, - gpointer user_data UNUSED) + GParamSpec* pspec UNUSED, + gpointer user_data UNUSED) { if (gui.surface != NULL) cairo_surface_destroy(gui.surface); @@ -2152,6 +2152,9 @@ scroll_event(GtkWidget *widget, FALSE, vim_modifiers); } } + else if (event->direction == GDK_SCROLL_SMOOTH && display_type == DT_X11) + // for X11 we deal with unsmooth events, and so ignore the smooth ones + ; else #undef DT_X11 #undef DT_WAYLAND @@ -2701,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); @@ -2738,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_w32.c b/src/gui_w32.c index f628dd663b..721c4480d5 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -274,13 +274,9 @@ gui_mch_set_rendering_options(char_u *s) // cproto fails on missing include files #ifndef PROTO - -# ifndef __MINGW32__ -# include <shellapi.h> -# endif +# include <shellapi.h> # include <commctrl.h> # include <windowsx.h> - #endif // PROTO #ifdef FEAT_MENU diff --git a/src/gui_x11.c b/src/gui_x11.c index fc63658f8d..edde6b55c5 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 1916c93399..8187fd8f8d 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"), @@ -3349,8 +3351,8 @@ syn_list_header( if (msg_col >= endcol) // output at least one space endcol = msg_col + 1; - if (Columns <= endcol) // avoid hang for tiny window - endcol = Columns - 1; + if (Columns <= (long)endcol) // avoid hang for tiny window + endcol = (int)(Columns - 1); msg_advance(endcol); diff --git a/src/if_cscope.c b/src/if_cscope.c index d9982ef164..7b6fd926ef 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 3e5993bb64..e0fd3eafb0 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/if_python3.c b/src/if_python3.c index c135e7e6fd..96c9497712 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -232,7 +232,11 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll # define PyObject_HasAttrString py3_PyObject_HasAttrString # define PyObject_SetAttrString py3_PyObject_SetAttrString # define PyObject_CallFunctionObjArgs py3_PyObject_CallFunctionObjArgs -# define _PyObject_CallFunction_SizeT py3__PyObject_CallFunction_SizeT +# if PY_VERSION_HEX >= 0x030d0000 +# define PyObject_CallFunction py3_PyObject_CallFunction +# else +# define _PyObject_CallFunction_SizeT py3__PyObject_CallFunction_SizeT +# endif # define PyObject_Call py3_PyObject_Call # define PyEval_GetLocals py3_PyEval_GetLocals # define PyEval_GetGlobals py3_PyEval_GetGlobals @@ -398,7 +402,11 @@ static PyObject* (*py3_PyObject_GetAttrString)(PyObject *, const char *); static int (*py3_PyObject_HasAttrString)(PyObject *, const char *); static int (*py3_PyObject_SetAttrString)(PyObject *, const char *, PyObject *); static PyObject* (*py3_PyObject_CallFunctionObjArgs)(PyObject *, ...); +# if PY_VERSION_HEX >= 0x030d0000 +static PyObject* (*py3_PyObject_CallFunction)(PyObject *, char *, ...); +# else static PyObject* (*py3__PyObject_CallFunction_SizeT)(PyObject *, char *, ...); +# endif static PyObject* (*py3_PyObject_Call)(PyObject *, PyObject *, PyObject *); static PyObject* (*py3_PyEval_GetGlobals)(void); static PyObject* (*py3_PyEval_GetLocals)(void); @@ -601,7 +609,11 @@ static struct {"PyObject_HasAttrString", (PYTHON_PROC*)&py3_PyObject_HasAttrString}, {"PyObject_SetAttrString", (PYTHON_PROC*)&py3_PyObject_SetAttrString}, {"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&py3_PyObject_CallFunctionObjArgs}, +# if PY_VERSION_HEX >= 0x030d0000 + {"PyObject_CallFunction", (PYTHON_PROC*)&py3_PyObject_CallFunction}, +# else {"_PyObject_CallFunction_SizeT", (PYTHON_PROC*)&py3__PyObject_CallFunction_SizeT}, +# endif {"PyObject_Call", (PYTHON_PROC*)&py3_PyObject_Call}, {"PyEval_GetGlobals", (PYTHON_PROC*)&py3_PyEval_GetGlobals}, {"PyEval_GetLocals", (PYTHON_PROC*)&py3_PyEval_GetLocals}, diff --git a/src/indent.c b/src/indent.c index 1dfde7ddda..0d6fadb26d 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 @@ -977,7 +996,7 @@ get_breakindent_win( # else if (wp->w_briopt_vcol == 0) prev_indent = get_indent_str(line, - (int)wp->w_buffer->b_p_ts, no_ts); + (int)wp->w_buffer->b_p_ts, no_ts); # endif prev_tick = CHANGEDTICK(wp->w_buffer); prev_listopt = wp->w_briopt_list; diff --git a/src/insexpand.c b/src/insexpand.c index dd1956a304..2e4dd044a5 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -58,7 +58,7 @@ static char *ctrl_x_msgs[] = N_(" Command-line completion (^V^N^P)"), N_(" User defined completion (^U^N^P)"), N_(" Omni completion (^O^N^P)"), - N_(" Spelling suggestion (s^N^P)"), + N_(" Spelling suggestion (^S^N^P)"), N_(" Keyword Local completion (^N^P)"), NULL, // CTRL_X_EVAL doesn't use msg. N_(" Command-line completion (^V^N^P)"), @@ -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,10 @@ 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 *compl_fuzzy_scores; + static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup); static void ins_compl_longest_match(compl_T *match); static void ins_compl_del_pum(void); @@ -1049,21 +1048,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) -{ - 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; + unsigned int +get_cot_flags(void) +{ + return curbuf->b_cot_flags != 0 ? curbuf->b_cot_flags : cot_flags; } @@ -1110,7 +1100,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 +1134,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); } @@ -1211,6 +1201,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 @@ -1226,6 +1229,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 +1242,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 +1267,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 +1298,37 @@ 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; + } + + if (!shown_match_ok && compl == compl_shown_match && !compl_no_select) + { + cur = i; + 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))) + { + 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 +1337,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 +1345,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 +1365,16 @@ 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); + shown_match_ok = TRUE; + } + if (!shown_match_ok) // no displayed match at all cur = -1; @@ -1369,6 +1431,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; @@ -1385,6 +1448,15 @@ ins_compl_show_pum(void) #define DICT_FIRST (1) // use just first element in "dict" #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 +1780,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 +1820,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); @@ -2408,9 +2482,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()) @@ -2882,6 +2955,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()) @@ -3251,7 +3328,8 @@ typedef struct process_next_cpt_value( ins_compl_next_state_T *st, int *compl_type_arg, - pos_T *start_match_pos) + pos_T *start_match_pos, + int in_fuzzy) { int compl_type = -1; int status = INS_COMPL_CPT_OK; @@ -3267,7 +3345,7 @@ process_next_cpt_value( st->first_match_pos = *start_match_pos; // Move the cursor back one character so that ^N can match the // word immediately after the cursor. - if (ctrl_x_mode_normal() && dec(&st->first_match_pos) < 0) + if (ctrl_x_mode_normal() && (!in_fuzzy && dec(&st->first_match_pos) < 0)) { // Move the cursor to after the last character in the // buffer, so that word at start of buffer is found @@ -3378,7 +3456,7 @@ process_next_cpt_value( 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, @@ -3434,6 +3512,18 @@ get_next_tag_completion(void) p_ic = save_p_ic; } +/* + * Compare function for qsort + */ +static int compare_scores(const void *a, const void *b) +{ + int idx_a = *(const int *)a; + int idx_b = *(const int *)b; + int score_a = compl_fuzzy_scores[idx_a]; + int score_b = compl_fuzzy_scores[idx_b]; + return (score_a > score_b) ? -1 : (score_a < score_b) ? 1 : 0; +} + /* * Get the next set of filename matching "compl_pattern". */ @@ -3442,6 +3532,51 @@ get_next_filename_completion(void) { char_u **matches; int num_matches; + char_u *ptr; + garray_T fuzzy_indices; + int i; + int score; + char_u *leader = ins_compl_leader(); + int leader_len = STRLEN(leader); + int in_fuzzy = ((get_cot_flags() & COT_FUZZY) != 0 && leader_len > 0); + char_u **sorted_matches; + int *fuzzy_indices_data; + char_u *last_sep = NULL; + size_t path_with_wildcard_len; + char_u *path_with_wildcard; + + if (in_fuzzy) + { + last_sep = vim_strrchr(leader, PATHSEP); + if (last_sep == NULL) + { + // No path separator or separator is the last character, + // fuzzy match the whole leader + vim_free(compl_pattern); + compl_pattern = vim_strsave((char_u *)"*"); + compl_patternlen = STRLEN(compl_pattern); + } + else if (*(last_sep + 1) == '\0') + in_fuzzy = FALSE; + else + { + // Split leader into path and file parts + int path_len = last_sep - leader + 1; + path_with_wildcard_len = path_len + 2; + path_with_wildcard = alloc(path_with_wildcard_len); + if (path_with_wildcard != NULL) + { + vim_strncpy(path_with_wildcard, leader, path_len); + vim_strcat(path_with_wildcard, (char_u *)"*", path_with_wildcard_len); + vim_free(compl_pattern); + compl_pattern = path_with_wildcard; + compl_patternlen = STRLEN(compl_pattern); + + // Move leader to the file part + leader = last_sep + 1; + } + } + } if (expand_wildcards(1, &compl_pattern, &num_matches, &matches, EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) != OK) @@ -3452,12 +3587,9 @@ get_next_filename_completion(void) #ifdef BACKSLASH_IN_FILENAME if (curbuf->b_p_csl[0] != NUL) { - int i; - for (i = 0; i < num_matches; ++i) { - char_u *ptr = matches[i]; - + ptr = matches[i]; while (*ptr != NUL) { if (curbuf->b_p_csl[0] == 's' && *ptr == '\\') @@ -3469,6 +3601,46 @@ get_next_filename_completion(void) } } #endif + + if (in_fuzzy) + { + ga_init2(&fuzzy_indices, sizeof(int), 10); + compl_fuzzy_scores = (int *)alloc(sizeof(int) * num_matches); + + for (i = 0; i < num_matches; i++) + { + ptr = matches[i]; + score = fuzzy_match_str(ptr, leader); + if (score > 0) + { + if (ga_grow(&fuzzy_indices, 1) == OK) + { + ((int *)fuzzy_indices.ga_data)[fuzzy_indices.ga_len] = i; + compl_fuzzy_scores[i] = score; + fuzzy_indices.ga_len++; + } + } + } + + // prevent qsort from deref NULL pointer + if (fuzzy_indices.ga_len > 0) + { + fuzzy_indices_data = (int *)fuzzy_indices.ga_data; + qsort(fuzzy_indices_data, fuzzy_indices.ga_len, sizeof(int), compare_scores); + + sorted_matches = (char_u **)alloc(sizeof(char_u *) * fuzzy_indices.ga_len); + for (i = 0; i < fuzzy_indices.ga_len; ++i) + sorted_matches[i] = vim_strsave(matches[fuzzy_indices_data[i]]); + + FreeWild(num_matches, matches); + matches = sorted_matches; + num_matches = fuzzy_indices.ga_len; + } + + vim_free(compl_fuzzy_scores); + ga_clear(&fuzzy_indices); + } + ins_compl_add_matches(num_matches, matches, p_fic || p_wic); } @@ -3482,8 +3654,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); } @@ -3617,8 +3788,10 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) int save_p_scs; int save_p_ws; int looped_around = FALSE; - char_u *ptr; - int len; + char_u *ptr = NULL; + int len = 0; + int in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0 && compl_length > 0; + char_u *leader = ins_compl_leader(); // If 'infercase' is set, don't use 'smartcase' here save_p_scs = p_scs; @@ -3632,7 +3805,7 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) save_p_ws = p_ws; if (st->ins_buf != curbuf) p_ws = FALSE; - else if (*st->e_cpt == '.') + else if (*st->e_cpt == '.' && !in_fuzzy) p_ws = TRUE; looped_around = FALSE; for (;;) @@ -3643,13 +3816,17 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) // ctrl_x_mode_line_or_eval() || word-wise search that // has added a word that was at the beginning of the line - if (ctrl_x_mode_line_or_eval() || (compl_cont_status & CONT_SOL)) + if ((ctrl_x_mode_whole_line() && !in_fuzzy) || ctrl_x_mode_eval() || (compl_cont_status & CONT_SOL)) found_new_match = search_for_exact_line(st->ins_buf, st->cur_match_pos, compl_direction, compl_pattern); + else if (in_fuzzy) + found_new_match = search_for_fuzzy_match(st->ins_buf, + st->cur_match_pos, leader, compl_direction, + start_pos, &len, &ptr, ctrl_x_mode_whole_line()); else found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos, - NULL, compl_direction, compl_pattern, 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) { @@ -3694,8 +3871,9 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos) && start_pos->col == st->cur_match_pos->col) continue; - ptr = ins_compl_get_next_word_or_line(st->ins_buf, st->cur_match_pos, - &len, &cont_s_ipos); + if (!in_fuzzy) + ptr = ins_compl_get_next_word_or_line(st->ins_buf, st->cur_match_pos, + &len, &cont_s_ipos); if (ptr == NULL) continue; @@ -3794,6 +3972,7 @@ ins_compl_get_exp(pos_T *ini) int i; int found_new_match; int type = ctrl_x_mode; + int in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0; if (!compl_started) { @@ -3819,8 +3998,11 @@ ins_compl_get_exp(pos_T *ini) st.ins_buf = curbuf; // In case the buffer was wiped out. compl_old_match = compl_curr_match; // remember the last current match - st.cur_match_pos = (compl_dir_forward()) - ? &st.last_match_pos : &st.first_match_pos; + if (in_fuzzy) + st.cur_match_pos = (compl_dir_forward()) + ? &st.last_match_pos : &st.first_match_pos; + else + st.cur_match_pos = &st.last_match_pos; // For ^N/^P loop over all the flags/windows/buffers in 'complete'. for (;;) @@ -3834,7 +4016,7 @@ ins_compl_get_exp(pos_T *ini) if ((ctrl_x_mode_normal() || ctrl_x_mode_line_or_eval()) && (!compl_started || st.found_all)) { - int status = process_next_cpt_value(&st, &type, ini); + int status = process_next_cpt_value(&st, &type, ini, in_fuzzy); if (status == INS_COMPL_CPT_END) break; @@ -4021,6 +4203,43 @@ ins_compl_show_filename(void) redraw_cmdline = FALSE; // don't overwrite! } +/* + * 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 ((is_forward && compl_selected_item == compl_match_arraysize - 1) + || (is_backward && compl_selected_item == 0)) + return compl_first_match != compl_shown_match ? compl_first_match : + (compl_first_match->cp_prev ? compl_first_match->cp_prev : NULL); + + if (is_forward) + target_idx = compl_selected_item + 1; + 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'. @@ -4043,12 +4262,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))); @@ -4057,7 +4280,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 @@ -4107,7 +4331,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. @@ -4157,13 +4382,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(); @@ -4309,7 +4539,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; @@ -4387,7 +4617,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 @@ -4408,32 +4639,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; } @@ -4469,7 +4713,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"); @@ -4479,13 +4726,17 @@ 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; } @@ -4507,7 +4758,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; } @@ -4537,7 +4793,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; } @@ -4551,9 +4812,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 @@ -4651,8 +4916,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 @@ -4689,8 +4958,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 @@ -4911,6 +5184,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; } @@ -5199,7 +5473,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 e4030de861..6e5c50f74d 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 e9f1ae3206..36ce494df8 100644 --- a/src/list.c +++ b/src/list.c @@ -365,8 +365,7 @@ list_len(list_T *l) list_equal( list_T *l1, list_T *l2, - int ic, // ignore case for strings - int recursive) // TRUE when used recursively + int ic) // ignore case for strings { listitem_T *item1, *item2; @@ -386,7 +385,7 @@ list_equal( for (item1 = l1->lv_first, item2 = l2->lv_first; item1 != NULL && item2 != NULL; item1 = item1->li_next, item2 = item2->li_next) - if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) + if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) return FALSE; return item1 == NULL && item2 == NULL; } @@ -2727,7 +2726,7 @@ list_count(list_T *l, typval_T *needle, long idx, int ic) } for ( ; li != NULL; li = li->li_next) - if (tv_equal(&li->li_tv, needle, ic, FALSE)) + if (tv_equal(&li->li_tv, needle, ic)) ++n; return n; @@ -3194,4 +3193,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/macros.h b/src/macros.h index 190778eca3..38983ac9c5 100644 --- a/src/macros.h +++ b/src/macros.h @@ -194,7 +194,11 @@ #ifdef HAVE_LSTAT # define mch_lstat(n, p) lstat((n), (p)) #else -# define mch_lstat(n, p) mch_stat((n), (p)) +# ifdef MSWIN +# define mch_lstat(n, p) vim_lstat((n), (p)) +# else +# define mch_lstat(n, p) mch_stat((n), (p)) +# endif #endif #ifdef VMS diff --git a/src/mark.c b/src/mark.c index 22e3c62575..9f6a9ccf58 100644 --- a/src/mark.c +++ b/src/mark.c @@ -129,6 +129,38 @@ setmark_pos(int c, pos_T *pos, int fnum) return FAIL; } +/* + * Delete every entry referring to file 'fnum' from both the jumplist and the + * tag stack. + */ + void +mark_forget_file(win_T *wp, int fnum) +{ + int i; + + for (i = wp->w_jumplistlen - 1; i >= 0; --i) + if (wp->w_jumplist[i].fmark.fnum == fnum) + { + vim_free(wp->w_jumplist[i].fname); + if (wp->w_jumplistidx > i) + --wp->w_jumplistidx; + --wp->w_jumplistlen; + mch_memmove(&wp->w_jumplist[i], &wp->w_jumplist[i + 1], + (wp->w_jumplistlen - i) * sizeof(wp->w_jumplist[i])); + } + + for (i = wp->w_tagstacklen - 1; i >= 0; --i) + if (wp->w_tagstack[i].fmark.fnum == fnum) + { + tagstack_clear_entry(&wp->w_tagstack[i]); + if (wp->w_tagstackidx > i) + --wp->w_tagstackidx; + --wp->w_tagstacklen; + mch_memmove(&wp->w_tagstack[i], &wp->w_tagstack[i + 1], + (wp->w_tagstacklen - i) * sizeof(wp->w_tagstack[i])); + } +} + /* * Set the previous context mark to the current position and add it to the * jump list. diff --git a/src/mbyte.c b/src/mbyte.c index 406d1093ff..a68ba7be3d 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -102,7 +102,7 @@ # define WINBYTE BYTE #endif -#if (defined(MSWIN) || defined(WIN32UNIX)) && !defined(__MINGW32__) +#if defined(MSWIN) || defined(WIN32UNIX) # include <winnls.h> #endif @@ -5542,6 +5542,20 @@ string_convert_ext( return retval; } +/* + * Return 1 or 2 when "c" is in the cellwidth table. + * Return 0 if not. + */ + int +get_cellwidth(int c UNUSED) +{ +#ifdef FEAT_EVAL + return cw_value(c); +#else + return 0; +#endif +} + #if defined(FEAT_EVAL) || defined(PROTO) /* diff --git a/src/memline.c b/src/memline.c index 6c63fad121..9e579cdfd9 100644 --- a/src/memline.c +++ b/src/memline.c @@ -2710,7 +2710,7 @@ ml_get_buf_len(buf_T *buf, linenr_T lnum) char_u *line; if (*(line = ml_get_buf(buf, lnum, FALSE)) == NUL) - return 0; + return 0; if (buf->b_ml.ml_line_textlen <= 0) buf->b_ml.ml_line_textlen = (int)STRLEN(line) + 1; diff --git a/src/misc1.c b/src/misc1.c index b188c5f361..dac1cfc481 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 8d836bc78f..380fbff231 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -3049,16 +3049,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 a234fca1d2..f2780e584e 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; @@ -3244,26 +3273,33 @@ pagescroll(int dir, long count, int half) cursor_down_inner(curwin, curscount); else cursor_up_inner(curwin, curscount); - - if (get_scrolloff_value() > 0) - cursor_correct(); -#ifdef FEAT_FOLDING - // Move cursor to first line of closed fold. - foldAdjustCursor(); -#endif - - nochange = nochange - && prev_col == curwin->w_cursor.col - && prev_lnum == curwin->w_cursor.lnum; } else { // 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); + + if (!nochange) + { + // Place cursor at top or bottom of window. + validate_botline(); + curwin->w_cursor.lnum = (dir == FORWARD ? curwin->w_topline + : curwin->w_botline - 1); + } } + if (get_scrolloff_value() > 0) + cursor_correct(); +#ifdef FEAT_FOLDING + // Move cursor to first line of closed fold. + foldAdjustCursor(); +#endif + nochange = nochange + && prev_col == curwin->w_cursor.col + && prev_lnum == curwin->w_cursor.lnum; + // Error if both the viewport and cursor did not change. if (nochange) beep_flush(); diff --git a/src/netbeans.c b/src/netbeans.c index 180ba9cb98..469be4cfee 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -1689,8 +1689,10 @@ nb_do_cmd( if (streq((char *)args, "T") && buf->bufp != curbuf) { exarg_T exarg; + CLEAR_FIELD(exarg); exarg.cmd = (char_u *)"goto"; exarg.forceit = FALSE; + exarg.cmdidx = CMD_USER; dosetvisible = TRUE; goto_buffer(&exarg, DOBUF_FIRST, FORWARD, buf->bufp->b_fnum); do_update = 1; diff --git a/src/normal.c b/src/normal.c index 9fbb40ceee..9ce43d8260 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); @@ -1711,6 +1711,7 @@ add_to_showcmd(int c) int extra_len; int overflow; int i; + char_u mbyte_buf[MB_MAXBYTES]; static int ignore[] = { #ifdef FEAT_GUI @@ -1745,9 +1746,17 @@ add_to_showcmd(int c) if (ignore[i] == c) return FALSE; - p = transchar(c); - if (*p == ' ') - STRCPY(p, "<20>"); + if (c <= 0x7f || !vim_isprintc(c)) + { + p = transchar(c); + if (*p == ' ') + STRCPY(p, "<20>"); + } + else + { + mbyte_buf[(*mb_char2bytes)(c, mbyte_buf)] = NUL; + p = mbyte_buf; + } old_len = (int)STRLEN(showcmd_buf); extra_len = (int)STRLEN(p); overflow = old_len + extra_len - SHOWCMD_COLS; @@ -1816,7 +1825,7 @@ pop_showcmd(void) static void display_showcmd(void) { - int len = (int)STRLEN(showcmd_buf); + int len = vim_strsize(showcmd_buf); showcmd_is_clear = (len == 0); cursor_off(); @@ -2166,6 +2175,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; @@ -2182,8 +2192,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; @@ -2212,7 +2223,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 @@ -2590,7 +2601,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); @@ -3338,7 +3349,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; @@ -3348,6 +3360,7 @@ nv_K_getcmd( { // in the help buffer STRCPY(buf, "he! "); + *buflen = STRLEN_LITERAL("he! "); return n; } @@ -3355,10 +3368,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; } @@ -3383,19 +3395,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; @@ -3414,7 +3423,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' @@ -3469,11 +3479,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) { @@ -3487,12 +3498,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; @@ -3501,30 +3515,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 @@ -3538,7 +3569,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); @@ -3546,7 +3578,8 @@ nv_ident(cmdarg_T *cap) return; } buf = newbuf; - STRCAT(buf, p); + STRCPY(buf + buflen, p); + buflen += plen; vim_free(p); } else @@ -3566,12 +3599,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) @@ -3585,6 +3619,7 @@ nv_ident(cmdarg_T *cap) *p++ = *ptr++; } *p = NUL; + buflen = p - buf; } // Execute the command. @@ -3593,13 +3628,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 { @@ -4123,7 +4161,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); } @@ -4138,7 +4176,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)) { @@ -4146,7 +4184,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; } @@ -4167,6 +4205,7 @@ normal_search( cmdarg_T *cap, int dir, char_u *pat, + size_t patlen, int opt, // extra flags for do_search() int *wrapped) { @@ -4182,7 +4221,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; @@ -4207,6 +4246,7 @@ normal_search( // "/$" will put the cursor after the end of the line, may need to // correct that here check_cursor(); + return i; } @@ -4437,7 +4477,7 @@ nv_brackets(cmdarg_T *cap) SAFE_islower(cap->nchar) ? ACTION_SHOW : ACTION_GOTO, cap->cmdchar == ']' ? curwin->w_cursor.lnum + 1 : (linenr_T)1, (linenr_T)MAXLNUM, - FALSE); + FALSE); vim_free(ptr); curwin->w_set_curswant = TRUE; } @@ -4535,13 +4575,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; @@ -6571,8 +6613,12 @@ nv_wordcmd(cmdarg_T *cap) // "ce" will change until the end of the next word, but "cw" // will change only one character! This is done by setting // flag. - cap->oap->inclusive = TRUE; - word_end = TRUE; + // This can be configured using :set cpo-z + if (vim_strchr(p_cpo, CPO_WORD) != NULL) + { + cap->oap->inclusive = TRUE; + word_end = TRUE; + } flag = TRUE; } } @@ -6669,29 +6715,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 0ab0d005db..eb8f64c1fb 100644 --- a/src/ops.c +++ b/src/ops.c @@ -231,14 +231,17 @@ 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 if (round) // round off indent { - i = count / sw_val; // number of 'shiftwidth' rounded down - j = count % sw_val; // extra spaces + i = trim_to_int(count) / sw_val; // number of 'shiftwidth' rounded down + j = trim_to_int(count) % sw_val; // extra spaces if (j && left) // first remove extra spaces --amount; if (left) @@ -281,14 +284,15 @@ shift_block(oparg_T *oap, int amount) int oldstate = State; int total; 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; colnr_T ws_vcol; int added; - unsigned new_line_len; // the length of the line after the + size_t new_line_len; // the length of the line after the // block shift #ifdef FEAT_RIGHTLEFT int old_p_ri = p_ri; @@ -307,6 +311,7 @@ shift_block(oparg_T *oap, int amount) return; // multiplication overflow oldp = ml_get_curline(); + oldlen = ml_get_curline_len(); if (!left) { @@ -369,15 +374,16 @@ shift_block(oparg_T *oap, int amount) // if we're splitting a TAB, allow for it bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0); - new_line_len = bd.textcol + tabs + spaces + (int)STRLEN(bd.textstart); + new_line_len = bd.textcol + tabs + spaces + (oldlen - (bd.textstart - oldp)); newp = alloc(new_line_len + 1); if (newp == NULL) return; mch_memmove(newp, oldp, (size_t)bd.textcol); - vim_memset(newp + bd.textcol, TAB, (size_t)tabs); - vim_memset(newp + bd.textcol + tabs, ' ', (size_t)spaces); - // Note that STRMOVE() copies the trailing NUL. - STRMOVE(newp + bd.textcol + tabs + spaces, bd.textstart); + newlen = bd.textcol; + vim_memset(newp + newlen, TAB, (size_t)tabs); + newlen += tabs; + vim_memset(newp + newlen, ' ', (size_t)spaces); + STRCPY(newp + newlen + spaces, bd.textstart); } else // left { @@ -387,11 +393,13 @@ shift_block(oparg_T *oap, int amount) // copied verbatim colnr_T verbatim_copy_width;// the (displayed) width of this part // of line - unsigned fill; // nr of spaces that replace a TAB + size_t fill; // nr of spaces that replace a TAB size_t block_space_width; size_t shift_amount; char_u *non_white = bd.textstart; colnr_T non_white_col; + size_t fixedlen; // length of string left of the shift + // position (ie the string not being shifted) chartabsize_T cts; /* @@ -463,21 +471,27 @@ shift_block(oparg_T *oap, int amount) // - the beginning of the original line up to "verbatim_copy_end", // - "fill" number of spaces, // - the rest of the line, pointed to by non_white. - new_line_len = (unsigned)(verbatim_copy_end - oldp) - + fill - + (unsigned)STRLEN(non_white); + fixedlen = verbatim_copy_end - oldp; + new_line_len = fixedlen + fill + (oldlen - (non_white - oldp)); newp = alloc(new_line_len + 1); if (newp == NULL) return; - mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp)); - vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill); - // Note that STRMOVE() copies the trailing NUL. - STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white); + mch_memmove(newp, oldp, fixedlen); + newlen = fixedlen; + vim_memset(newp + newlen, ' ', (size_t)fill); + STRCPY(newp + newlen + fill, non_white); } // replace the line - added = new_line_len - ml_get_curline_len(); ml_replace(curwin->w_cursor.lnum, newp, FALSE); + + // compute the number of bytes added or subtracted. + // note new_line_len and oldlen are unsigned so we have + // to be careful about how we calculate this. + if (new_line_len >= oldlen) + added = (int)(new_line_len - oldlen); + else + added = 0 - (int)(oldlen - new_line_len); inserted_bytes(curwin->w_cursor.lnum, bd.textcol, added); State = oldstate; curwin->w_cursor.col = oldcol; @@ -494,6 +508,7 @@ shift_block(oparg_T *oap, int amount) block_insert( oparg_T *oap, char_u *s, + size_t slen, int b_insert, struct block_def *bdp) { @@ -502,13 +517,11 @@ block_insert( int spaces = 0; // non-zero if cutting a TAB colnr_T offset; // pointer along new line colnr_T startcol; // column where insert starts - unsigned s_len; // STRLEN(s) char_u *newp, *oldp; // new, old lines linenr_T lnum; // loop var int oldstate = State; State = MODE_INSERT; // don't want MODE_REPLACE for State - s_len = (unsigned)STRLEN(s); for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++) { @@ -554,7 +567,7 @@ block_insert( spaces = 0; // Make sure the allocated size matches what is actually copied below. - newp = alloc(ml_get_len(lnum) + spaces + s_len + newp = alloc(ml_get_len(lnum) + spaces + slen + (spaces > 0 && !bdp->is_short ? ts_val - spaces : 0) + count + 1); if (newp == NULL) @@ -569,8 +582,8 @@ block_insert( startcol = offset + spaces; // copy the new text - mch_memmove(newp + startcol, s, (size_t)s_len); - offset += s_len; + mch_memmove(newp + startcol, s, slen); + offset += (int)slen; if (spaces > 0 && !bdp->is_short) { @@ -591,13 +604,13 @@ block_insert( if (spaces > 0) offset += count; - STRMOVE(newp + offset, oldp); + STRCPY(newp + offset, oldp); ml_replace(lnum, newp, FALSE); if (b_insert) // correct any text properties - inserted_bytes(lnum, startcol, s_len); + inserted_bytes(lnum, startcol, (int)slen); if (lnum == oap->end.lnum) { @@ -663,6 +676,7 @@ op_delete(oparg_T *oap) && !oap->block_mode && oap->line_count > 1 && oap->motion_force == NUL + && (vim_strchr(p_cpo, CPO_WORD) != NULL) && oap->op_type == OP_DELETE) { ptr = ml_get(oap->end.lnum) + oap->end.col; @@ -809,8 +823,8 @@ op_delete(oparg_T *oap) vim_memset(newp + bd.textcol, ' ', (size_t)(bd.startspaces + bd.endspaces)); // copy the part after the deleted part - oldp += bd.textcol + bd.textlen; - STRMOVE(newp + bd.textcol + bd.startspaces + bd.endspaces, oldp); + STRCPY(newp + bd.textcol + bd.startspaces + bd.endspaces, + oldp + bd.textcol + bd.textlen); // replace the line ml_replace(lnum, newp, FALSE); @@ -1030,7 +1044,7 @@ op_replace(oparg_T *oap, int c) int n, numc; int num_chars; char_u *newp, *oldp; - size_t oldlen; + size_t newlen, oldlen; struct block_def bd; char_u *after_p = NULL; int had_ctrl_v_cr = FALSE; @@ -1122,9 +1136,10 @@ op_replace(oparg_T *oap, int c) vim_memset(newp, NUL, (size_t)(oldlen + 1 + n)); // copy up to deleted part mch_memmove(newp, oldp, (size_t)bd.textcol); - oldp += bd.textcol + bd.textlen; + newlen = bd.textcol; // insert pre-spaces - vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces); + vim_memset(newp + newlen, ' ', (size_t)bd.startspaces); + newlen += bd.startspaces; // insert replacement chars CHECK FOR ALLOCATED SPACE // REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR // literally. @@ -1132,27 +1147,31 @@ op_replace(oparg_T *oap, int c) { if (has_mbyte) { - n = (int)STRLEN(newp); while (--num_chars >= 0) - n += (*mb_char2bytes)(c, newp + n); + newlen += (*mb_char2bytes)(c, newp + newlen); } else - vim_memset(newp + STRLEN(newp), c, (size_t)numc); + { + vim_memset(newp + newlen, c, (size_t)numc); + newlen += numc; + } if (!bd.is_short) { // insert post-spaces - vim_memset(newp + STRLEN(newp), ' ', (size_t)bd.endspaces); + vim_memset(newp + newlen, ' ', (size_t)bd.endspaces); // copy the part after the changed part - STRMOVE(newp + STRLEN(newp), oldp); + STRCPY(newp + newlen + bd.endspaces, + oldp + bd.textcol + bd.textlen); } } else { // Replacing with \r or \n means splitting the line. - after_p = alloc(oldlen + 1 + n - STRLEN(newp)); + after_p = alloc(oldlen + 1 + n - newlen); if (after_p != NULL) - STRMOVE(after_p, oldp); + STRCPY(after_p, oldp + bd.textcol + bd.textlen); } + // replace the line ml_replace(curwin->w_cursor.lnum, newp, FALSE); if (after_p != NULL) @@ -1243,8 +1262,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; } } @@ -1593,7 +1612,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; @@ -1707,7 +1726,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) @@ -1715,7 +1734,7 @@ op_insert(oparg_T *oap, long count1) // block handled here if (u_save(oap->start.lnum, (linenr_T)(oap->end.lnum + 1)) == OK) - block_insert(oap, ins_text, (oap->op_type == OP_INSERT), + block_insert(oap, ins_text, ins_len, (oap->op_type == OP_INSERT), &bd); curwin->w_cursor.col = oap->start.col; @@ -1736,9 +1755,7 @@ op_change(oparg_T *oap) { colnr_T l; int retval; - long offset; linenr_T linenr; - long ins_len; long pre_textlen = 0; long pre_indent = 0; char_u *firstline; @@ -1798,6 +1815,8 @@ op_change(oparg_T *oap) */ if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int) { + 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. firstline = ml_get(oap->start.lnum); @@ -1809,14 +1828,14 @@ 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 // copy of the inserted text. if ((ins_text = alloc(ins_len + 1)) != NULL) { - vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len); + vim_strncpy(ins_text, firstline + bd.textcol, ins_len); for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum; linenr++) { @@ -1824,6 +1843,7 @@ op_change(oparg_T *oap) if (!bd.is_short || virtual_op) { pos_T vpos; + size_t newlen; // If the block starts in virtual space, count the // initial coladd offset as part of "startspaces" @@ -1835,25 +1855,22 @@ op_change(oparg_T *oap) else vpos.coladd = 0; oldp = ml_get(linenr); - newp = alloc(ml_get_len(linenr) - + vpos.coladd + ins_len + 1); + newp = alloc(ml_get_len(linenr) + vpos.coladd + ins_len + 1); if (newp == NULL) continue; // copy up to block start mch_memmove(newp, oldp, (size_t)bd.textcol); - offset = bd.textcol; - vim_memset(newp + offset, ' ', (size_t)vpos.coladd); - offset += vpos.coladd; - mch_memmove(newp + offset, ins_text, (size_t)ins_len); - offset += ins_len; - oldp += bd.textcol; - STRMOVE(newp + offset, oldp); + newlen = bd.textcol; + vim_memset(newp + newlen, ' ', (size_t)vpos.coladd); + newlen += vpos.coladd; + mch_memmove(newp + newlen, ins_text, ins_len); + STRCPY(newp + newlen + ins_len, oldp + bd.textcol); ml_replace(linenr, newp, FALSE); #ifdef FEAT_PROP_POPUP // 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 } } @@ -2431,13 +2448,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) { @@ -2449,8 +2467,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++; @@ -2470,19 +2488,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; } } @@ -2490,10 +2505,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; } @@ -2511,11 +2527,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) @@ -2658,6 +2674,8 @@ do_addsub( int do_bin; int do_alpha; int do_unsigned; + int do_blank; + int blank_unsigned = FALSE; // blank: treat as unsigned? int firstdigit; int subtract; int negative = FALSE; @@ -2675,6 +2693,7 @@ do_addsub( do_bin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin" do_alpha = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha" do_unsigned = (vim_strchr(curbuf->b_p_nf, 'u') != NULL); // "Unsigned" + do_blank = (vim_strchr(curbuf->b_p_nf, 'k') != NULL); // "blanK" if (virtual_active()) { @@ -2798,8 +2817,13 @@ do_addsub( && (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1)) && !do_unsigned) { - negative = TRUE; - was_positive = FALSE; + if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2])) + blank_unsigned = TRUE; + else + { + negative = TRUE; + was_positive = FALSE; + } } } @@ -2860,10 +2884,16 @@ do_addsub( && !visual && !do_unsigned) { - // negative number - --col; - negative = TRUE; + if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2])) + blank_unsigned = TRUE; + else + { + // negative number + --col; + negative = TRUE; + } } + // get the number value (unsigned) if (visual && VIsual_mode != 'V') maxlen = (curbuf->b_visual.vi_curswant == MAXCOL @@ -2923,7 +2953,7 @@ do_addsub( negative = FALSE; } - if (do_unsigned && negative) + if ((do_unsigned || blank_unsigned) && negative) { if (subtract) // sticking at zero. diff --git a/src/option.c b/src/option.c index dd58863600..90d24fc747 100644 --- a/src/option.c +++ b/src/option.c @@ -384,6 +384,8 @@ set_init_xdg_rtp(void) char_u *xdg_rtp = NULL; char_u *vimrc_xdg = NULL; + // initialize chartab, so we can expand $HOME + (void)init_chartab(); vimrc1 = expand_env_save((char_u *)USR_VIMRC_FILE); vimrc2 = expand_env_save((char_u *)USR_VIMRC_FILE2); @@ -415,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); @@ -6368,6 +6378,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; @@ -6477,6 +6491,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 @@ -6557,6 +6572,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 @@ -7355,6 +7372,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 @@ -8505,10 +8524,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; } @@ -8527,7 +8546,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 1feb026441..ac18ca42e9 100644 --- a/src/option.h +++ b/src/option.h @@ -212,6 +212,7 @@ typedef enum { #define CPO_REPLCNT 'X' // "R" with a count only deletes chars once #define CPO_YANK 'y' #define CPO_KEEPRO 'Z' // don't reset 'readonly' on ":w!" +#define CPO_WORD 'z' // do not special-case word motions cw and dw #define CPO_DOLLAR '$' #define CPO_FILTER '!' #define CPO_MATCH '%' @@ -231,9 +232,9 @@ typedef enum { #define CPO_SCOLON ';' // using "," and ";" will skip over char if // cursor would not move // default values for Vim, Vi and POSIX -#define CPO_VIM "aABceFs" -#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;" -#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;" +#define CPO_VIM "aABceFsz" +#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>;" +#define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\\.;" // characters for p_ww option: #define WW_ALL "bshl<>[]~" @@ -513,6 +514,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 @@ -963,7 +978,6 @@ EXTERN int p_sol; // 'startofline' EXTERN char_u *p_su; // 'suffixes' EXTERN char_u *p_sws; // 'swapsync' EXTERN char_u *p_swb; // 'switchbuf' -EXTERN char_u *p_spk; // 'splitkeep' EXTERN unsigned swb_flags; // Keep in sync with p_swb_values in optionstr.c #define SWB_USEOPEN 0x001 @@ -972,9 +986,14 @@ EXTERN unsigned swb_flags; #define SWB_NEWTAB 0x008 #define SWB_VSPLIT 0x010 #define SWB_USELAST 0x020 +EXTERN char_u *p_spk; // 'splitkeep' #ifdef FEAT_SYN_HL EXTERN char_u *p_syn; // 'syntax' #endif +EXTERN char_u *p_tcl; // 'tabclose' +EXTERN unsigned tcl_flags; // flags from 'tabclose' +#define TCL_LEFT 0x001 +#define TCL_USELAST 0x002 EXTERN long p_ts; // 'tabstop' EXTERN int p_tbs; // 'tagbsearch' EXTERN char_u *p_tc; // 'tagcase' @@ -1153,6 +1172,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 15a1432667..45e06df50b 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)) @@ -303,7 +304,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) @@ -684,7 +685,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} @@ -709,7 +710,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, @@ -2571,6 +2572,9 @@ static struct vimoption options[] = {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, + {"tabclose", "tcl", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, + (char_u *)&p_tcl, PV_NONE, did_set_tabclose, expand_set_tabclose, + {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"tabline", "tal", P_STRING|P_VI_DEF|P_RALL|P_MLE, #ifdef FEAT_STL_OPT (char_u *)&p_tal, PV_NONE, did_set_tabline, NULL, @@ -2968,13 +2972,13 @@ static struct vimoption options[] = {"window", "wi", P_NUM|P_VI_DEF, (char_u *)&p_window, PV_NONE, did_set_window, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, - {"winfixbuf", "wfb", P_BOOL|P_VI_DEF|P_RWIN, + {"winfixbuf", "wfb", P_BOOL|P_VI_DEF, (char_u *)VAR_WIN, PV_WFB, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"winfixheight", "wfh", P_BOOL|P_VI_DEF|P_RSTAT, (char_u *)VAR_WIN, PV_WFH, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, - {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT, + {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT, (char_u *)VAR_WIN, PV_WFW, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"winheight", "wh", P_NUM|P_VI_DEF, @@ -2984,7 +2988,7 @@ static struct vimoption options[] = {"winminheight", "wmh", P_NUM|P_VI_DEF, (char_u *)&p_wmh, PV_NONE, did_set_winminheight, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, - {"winminwidth", "wmw", P_NUM|P_VI_DEF, + {"winminwidth", "wmw", P_NUM|P_VI_DEF, (char_u *)&p_wmw, PV_NONE, did_set_winminwidth, NULL, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"winptydll", NULL, P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, diff --git a/src/optionstr.c b/src/optionstr.c index 1022f72a4e..78e9df902e 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -33,7 +33,7 @@ static char *(p_briopt_values[]) = {"shift:", "min:", "sbr", "list:", "column:", static char *(p_dip_values[]) = {"filler", "context:", "iblank", "icase", "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "algorithm:", NULL}; static char *(p_dip_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL}; #endif -static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL}; +static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", "blank", NULL}; static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL}; #ifdef FEAT_CLIPBOARD // Note: Keep this in sync with did_set_clipboard() @@ -81,6 +81,8 @@ static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize", static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL}; static char *(p_spk_values[]) = {"cursor", "screen", "topline", NULL}; static char *(p_tc_values[]) = {"followic", "ignore", "match", "followscs", "smart", NULL}; +// Keep in sync with TCL_ flags in option.h +static char *(p_tcl_values[]) = {"left", "uselast", NULL}; #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN) static char *(p_toolbar_values[]) = {"text", "icons", "tooltips", "horiz", NULL}; #endif @@ -118,7 +120,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 +146,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); @@ -165,6 +168,7 @@ didset_string_options(void) (void)opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE); #endif (void)opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE); + (void)opt_strings_flags(p_tcl, p_tcl_values, &tcl_flags, TRUE); } #if defined(FEAT_EVAL) || defined(PROTO) @@ -301,6 +305,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); @@ -1607,10 +1612,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; } @@ -3666,6 +3682,26 @@ expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches) matches); } +/* + * The 'tabclose' option is changed. + */ + char * +did_set_tabclose(optset_T *args UNUSED) +{ + return did_set_opt_flags(p_tcl, p_tcl_values, &tcl_flags, TRUE); +} + + int +expand_set_tabclose(optexpand_T *args, int *numMatches, char_u ***matches) +{ + return expand_set_opt_string( + args, + p_tcl_values, + ARRAY_LENGTH(p_tcl_values) - 1, + numMatches, + matches); +} + #if defined(FEAT_STL_OPT) || defined(PROTO) /* * The 'tabline' option is changed. diff --git a/src/os_mswin.c b/src/os_mswin.c index 512fa40896..95e3cbcb91 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -18,20 +18,12 @@ #include <sys/types.h> #include <signal.h> #include <limits.h> + +// cproto fails on missing include files #ifndef PROTO # include <process.h> -#endif - -#undef chdir -#ifdef __GNUC__ -# ifndef __MINGW32__ -# include <dirent.h> -# endif -#else # include <direct.h> -#endif -#ifndef PROTO # if !defined(FEAT_GUI_MSWIN) # include <shellapi.h> # endif @@ -41,37 +33,8 @@ # include <winspool.h> # include <commdlg.h> # endif - #endif // PROTO -#ifdef __MINGW32__ -# ifndef FROM_LEFT_1ST_BUTTON_PRESSED -# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001 -# endif -# ifndef RIGHTMOST_BUTTON_PRESSED -# define RIGHTMOST_BUTTON_PRESSED 0x0002 -# endif -# ifndef FROM_LEFT_2ND_BUTTON_PRESSED -# define FROM_LEFT_2ND_BUTTON_PRESSED 0x0004 -# endif -# ifndef FROM_LEFT_3RD_BUTTON_PRESSED -# define FROM_LEFT_3RD_BUTTON_PRESSED 0x0008 -# endif -# ifndef FROM_LEFT_4TH_BUTTON_PRESSED -# define FROM_LEFT_4TH_BUTTON_PRESSED 0x0010 -# endif - -/* - * EventFlags - */ -# ifndef MOUSE_MOVED -# define MOUSE_MOVED 0x0001 -# endif -# ifndef DOUBLE_CLICK -# define DOUBLE_CLICK 0x0002 -# endif -#endif - /* * When generating prototypes for Win32 on Unix, these lines make the syntax * errors disappear. They do not need to be correct. @@ -144,37 +107,6 @@ static HWND s_hwnd = 0; // console window handle, set by GetConsoleHwnd() int WSInitialized = FALSE; // WinSock is initialized #endif -// Don't generate prototypes here, because some systems do have these -// functions. -#if defined(__GNUC__) && !defined(PROTO) -# ifndef __MINGW32__ -int _stricoll(char *a, char *b) -{ - // the ANSI-ish correct way is to use strxfrm(): - char a_buff[512], b_buff[512]; // file names, so this is enough on Win32 - strxfrm(a_buff, a, 512); - strxfrm(b_buff, b, 512); - return strcoll(a_buff, b_buff); -} - -char * _fullpath(char *buf, char *fname, int len) -{ - LPTSTR toss; - - return (char *)GetFullPathName(fname, len, buf, &toss); -} -# endif - -# if !defined(__MINGW32__) || (__GNUC__ < 4) -int _chdrive(int drive) -{ - char temp [3] = "-:"; - temp[0] = drive + 'A' - 1; - return !SetCurrentDirectory(temp); -} -# endif -#endif - #ifndef PROTO /* @@ -430,16 +362,6 @@ slash_adjust(char_u *p) } } -// Use 64-bit stat functions. -#undef stat -#undef _stat -#undef _wstat -#undef _fstat -#define stat _stat64 -#define _stat _stat64 -#define _wstat _wstat64 -#define _fstat _fstat64 - static int read_reparse_point(const WCHAR *name, char_u *buf, DWORD *buf_len) { @@ -461,58 +383,6 @@ read_reparse_point(const WCHAR *name, char_u *buf, DWORD *buf_len) return ok ? OK : FAIL; } - static int -wstat_symlink_aware(const WCHAR *name, stat_T *stp) -{ -#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__) - // Work around for VC12 or earlier (and MinGW). _wstat() can't handle - // symlinks properly. - // VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves - // status of a symlink itself. - // VC10: _wstat() supports a symlink to a normal file, but it doesn't - // support a symlink to a directory (always returns an error). - // VC11 and VC12: _wstat() doesn't return an error for a symlink to a - // directory, but it doesn't set S_IFDIR flag. - // MinGW: Same as VC9. - int n; - BOOL is_symlink = FALSE; - HANDLE hFind, h; - DWORD attr = 0; - WIN32_FIND_DATAW findDataW; - - hFind = FindFirstFileW(name, &findDataW); - if (hFind != INVALID_HANDLE_VALUE) - { - attr = findDataW.dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) - && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) - is_symlink = TRUE; - FindClose(hFind); - } - if (is_symlink) - { - h = CreateFileW(name, FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, - (attr & FILE_ATTRIBUTE_DIRECTORY) - ? FILE_FLAG_BACKUP_SEMANTICS : 0, - NULL); - if (h != INVALID_HANDLE_VALUE) - { - int fd; - - fd = _open_osfhandle((intptr_t)h, _O_RDONLY); - n = _fstat(fd, (struct _stat *)stp); - if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) - stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR; - _close(fd); - return n; - } - } -#endif - return _wstat(name, (struct _stat *)stp); -} - char_u * resolve_appexeclink(char_u *fname) { @@ -568,11 +438,76 @@ resolve_appexeclink(char_u *fname) return utf16_to_enc(p, NULL); } +// Use 64-bit stat functions. +#undef stat +#undef _stat +#undef _wstat +#undef _fstat +#define stat _stat64 +#define _stat _stat64 +#define _wstat _wstat64 +#define _fstat _fstat64 + +/* + * Implements lstat() and stat() that can handle symlinks properly. + */ + static int +mswin_stat_impl(const WCHAR *name, stat_T *stp, const int resolve) +{ + int n; + int fd; + BOOL is_symlink = FALSE; + HANDLE hFind, h; + DWORD attr = 0; + DWORD flag = 0; + WIN32_FIND_DATAW findDataW; + +#ifdef _UCRT + if (resolve) + // Universal CRT can handle symlinks properly. + return _wstat(name, stp); +#endif + + hFind = FindFirstFileW(name, &findDataW); + if (hFind != INVALID_HANDLE_VALUE) + { + attr = findDataW.dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) + && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) + is_symlink = TRUE; + FindClose(hFind); + } + + // Use the plain old stat() whenever it's possible. + if (!is_symlink) + return _wstat(name, stp); + + if (!resolve && is_symlink) + flag = FILE_FLAG_OPEN_REPARSE_POINT; + if (attr & FILE_ATTRIBUTE_DIRECTORY) + flag |= FILE_FLAG_BACKUP_SEMANTICS; + + h = CreateFileW(name, FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, flag, + NULL); + if (h == INVALID_HANDLE_VALUE) + return -1; + + fd = _open_osfhandle((intptr_t)h, _O_RDONLY); + n = _fstat(fd, (struct _stat *)stp); + if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY)) + stp->st_mode = (stp->st_mode & ~S_IFMT) | S_IFDIR; + _close(fd); + + return n; +} + /* * stat() can't handle a trailing '/' or '\', remove it first. + * When 'resolve' is true behave as lstat() wrt symlinks. */ - int -vim_stat(const char *name, stat_T *stp) + static int +stat_impl(const char *name, stat_T *stp, const int resolve) { // WinNT and later can use _MAX_PATH wide characters for a pathname, which // means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is @@ -607,11 +542,23 @@ vim_stat(const char *name, stat_T *stp) if (wp == NULL) return -1; - n = wstat_symlink_aware(wp, stp); + n = mswin_stat_impl(wp, stp, resolve); vim_free(wp); return n; } + int +vim_lstat(const char *name, stat_T *stp) +{ + return stat_impl(name, stp, FALSE); +} + + int +vim_stat(const char *name, stat_T *stp) +{ + return stat_impl(name, stp, TRUE); +} + #if (defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)) || defined(PROTO) void mch_settmode(tmode_T tmode UNUSED) @@ -883,6 +830,40 @@ mch_icon_load(HANDLE *iconp) 0, mch_icon_load_cb, iconp); } +/* + * Fill the buffer 'buf' with 'len' random bytes. + * Returns FAIL if the OS PRNG is not available or something went wrong. + */ + int +mch_get_random(char_u *buf, int len) +{ + static int initialized = NOTDONE; + static HINSTANCE hInstLib; + static BOOL (WINAPI *pProcessPrng)(PUCHAR, ULONG); + + if (initialized == NOTDONE) + { + hInstLib = vimLoadLib("bcryptprimitives.dll"); + if (hInstLib != NULL) + pProcessPrng = (void *)GetProcAddress(hInstLib, "ProcessPrng"); + if (hInstLib == NULL || pProcessPrng == NULL) + { + FreeLibrary(hInstLib); + initialized = FAIL; + } + else + initialized = OK; + } + + if (initialized == FAIL) + return FAIL; + + // According to the documentation this call cannot fail. + pProcessPrng(buf, len); + + return OK; +} + int mch_libcall( char_u *libname, @@ -2940,7 +2921,7 @@ expand_font_enumproc( // Filter only on ANSI. Otherwise will see a lot of random fonts that we // usually don't want. if (lf->lfCharSet != ANSI_CHARSET) - return 1; + return 1; int (*add_match)(char_u *) = (int (*)(char_u *))lparam; @@ -2974,7 +2955,7 @@ gui_mch_expand_font(optexpand_T *args, void *param UNUSED, int (*add_match)(char // Always fill in with the current font size as first option for // convenience. We simply round to the closest integer for simplicity. - int font_height = (int)round( + int font_height = (int)round( pixels_to_points(-current_font_height, TRUE, (long_i)NULL)); vim_snprintf(buf, ARRAY_LENGTH(buf), "h%d", font_height); add_match((char_u *)buf); diff --git a/src/os_unix.c b/src/os_unix.c index 9c944b0cc3..a60ccc0008 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2701,6 +2701,9 @@ mch_FullName( if ((force || !mch_isFullName(fname)) && ((p = vim_strrchr(fname, '/')) == NULL || p != fname)) { + if (p == NULL && STRCMP(fname, "..") == 0) + // Handle ".." without path separators. + p = fname + 2; /* * If the file name has a path, change to that directory for a moment, * and then get the directory (and get back to where we were). @@ -2709,7 +2712,7 @@ mch_FullName( if (p != NULL) { if (STRCMP(p, "/..") == 0) - // for "/path/dir/.." include the "/.." + // For "/path/dir/.." include the "/..". p += 3; #ifdef HAVE_FCHDIR @@ -7520,9 +7523,9 @@ gpm_open(void) { Gpm_Close(); // We don't want to talk to xterm via gpm - // Gpm_Close fails to properly restore the WINCH and TSTP handlers, - // leading to Vim ignoring resize signals. We have to re-initialize - // these handlers again here. + // Gpm_Close fails to properly restore the WINCH and TSTP handlers, + // leading to Vim ignoring resize signals. We have to re-initialize + // these handlers again here. # ifdef SIGWINCH mch_signal(SIGWINCH, sig_winch); # endif @@ -7744,6 +7747,37 @@ sig_sysmouse SIGDEFARG(sigarg) } #endif // FEAT_SYSMOUSE +/* + * Fill the buffer 'buf' with 'len' random bytes. + * Returns FAIL if the OS PRNG is not available or something went wrong. + */ + int +mch_get_random(char_u *buf, int len) +{ + static int dev_urandom_state = NOTDONE; + + if (dev_urandom_state == FAIL) + return FAIL; + + int fd = open("/dev/urandom", O_RDONLY); + + // Attempt reading /dev/urandom. + if (fd == -1) + dev_urandom_state = FAIL; + else if (read(fd, buf, len) == len) + { + dev_urandom_state = OK; + close(fd); + } + else + { + dev_urandom_state = FAIL; + close(fd); + } + + return dev_urandom_state; +} + #if defined(FEAT_LIBCALL) || defined(PROTO) typedef char_u * (*STRPROCSTR)(char_u *); typedef char_u * (*INTPROCSTR)(int); diff --git a/src/os_unix.h b/src/os_unix.h index 67dad2e689..99184abe6c 100644 --- a/src/os_unix.h +++ b/src/os_unix.h @@ -279,6 +279,12 @@ typedef struct dsc$descriptor DESC; # ifndef USR_GVIMRC_FILE3 # define USR_GVIMRC_FILE3 "sys$login:_gvimrc" # endif +#else +# ifndef USR_GVIMRC_FILE3 +# define USR_GVIMRC_FILE3 (mch_getenv("XDG_CONFIG_HOME") \ + ? "$XDG_CONFIG_HOME/vim/gvimrc" \ + : "~/.config/vim/gvimrc") +# endif #endif #ifndef VIM_DEFAULTS_FILE @@ -341,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/os_win32.c b/src/os_win32.c index 9947150cdf..eeb3b47166 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -34,52 +34,14 @@ #ifndef PROTO # include <process.h> # include <winternl.h> -#endif - -#undef chdir -#ifdef __GNUC__ -# ifndef __MINGW32__ -# include <dirent.h> -# endif -#else # include <direct.h> -#endif -#ifndef PROTO # if !defined(FEAT_GUI_MSWIN) # include <shellapi.h> # endif -#endif - -#ifdef FEAT_JOB_CHANNEL -# include <tlhelp32.h> -#endif - -#ifdef __MINGW32__ -# ifndef FROM_LEFT_1ST_BUTTON_PRESSED -# define FROM_LEFT_1ST_BUTTON_PRESSED 0x0001 -# endif -# ifndef RIGHTMOST_BUTTON_PRESSED -# define RIGHTMOST_BUTTON_PRESSED 0x0002 -# endif -# ifndef FROM_LEFT_2ND_BUTTON_PRESSED -# define FROM_LEFT_2ND_BUTTON_PRESSED 0x0004 -# endif -# ifndef FROM_LEFT_3RD_BUTTON_PRESSED -# define FROM_LEFT_3RD_BUTTON_PRESSED 0x0008 -# endif -# ifndef FROM_LEFT_4TH_BUTTON_PRESSED -# define FROM_LEFT_4TH_BUTTON_PRESSED 0x0010 -# endif -/* - * EventFlags - */ -# ifndef MOUSE_MOVED -# define MOUSE_MOVED 0x0001 -# endif -# ifndef DOUBLE_CLICK -# define DOUBLE_CLICK 0x0002 +# ifdef FEAT_JOB_CHANNEL +# include <tlhelp32.h> # endif #endif @@ -2762,12 +2724,6 @@ mch_inchar( #endif // FEAT_GUI_MSWIN } -#ifndef PROTO -# ifndef __MINGW32__ -# include <shellapi.h> // required for FindExecutable() -# endif -#endif - /* * Return TRUE if "name" is an executable file, FALSE if not or it doesn't exist. * When returning TRUE and "path" is not NULL save the path and set "*path" to @@ -5529,11 +5485,7 @@ mch_call_shell( * CTRL-C, Ctrl-Break or illegal instruction might otherwise kill us. */ mch_signal(SIGINT, SIG_IGN); -#if defined(__GNUC__) && !defined(__MINGW32__) - mch_signal(SIGKILL, SIG_IGN); -#else mch_signal(SIGBREAK, SIG_IGN); -#endif mch_signal(SIGILL, SIG_IGN); mch_signal(SIGFPE, SIG_IGN); mch_signal(SIGSEGV, SIG_IGN); @@ -5768,11 +5720,7 @@ mch_call_shell( resettitle(); mch_signal(SIGINT, SIG_DFL); -#if defined(__GNUC__) && !defined(__MINGW32__) - mch_signal(SIGKILL, SIG_DFL); -#else mch_signal(SIGBREAK, SIG_DFL); -#endif mch_signal(SIGILL, SIG_DFL); mch_signal(SIGFPE, SIG_DFL); mch_signal(SIGSEGV, SIG_DFL); diff --git a/src/po/Make_cyg.mak b/src/po/Make_cyg.mak index 705858da58..c04837eed3 100644 --- a/src/po/Make_cyg.mak +++ b/src/po/Make_cyg.mak @@ -16,7 +16,7 @@ endif include Make_all.mak PACKAGE = vim -VIM = ../vim +VIMPROG = ../vim # Uncomment one of the lines below or modify it to put the path to your # gettext binaries @@ -64,18 +64,18 @@ PO_INPUTLIST = \ vim.desktop.in first_time: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(LANGUAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js $(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(PACKAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) $(MV) $(PACKAGE).po $(PACKAGE).pot - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js # Don't add a dependency here, we only want to update the .po files manually diff --git a/src/po/Make_ming.mak b/src/po/Make_ming.mak index 42dab84449..21d2d2037c 100644 --- a/src/po/Make_ming.mak +++ b/src/po/Make_ming.mak @@ -23,9 +23,9 @@ include Make_all.mak PACKAGE = vim ifeq (sh.exe, $(SHELL)) -VIM = ..\vim +VIMPROG = ..\vim else -VIM = ../vim +VIMPROG = ../vim endif # Uncomment one of the lines below or modify it to put the path to your @@ -77,18 +77,18 @@ PO_INPUTLIST = \ vim.desktop.in first_time: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(LANGUAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js $(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(XGETTEXT) --default-domain=$(PACKAGE) \ --add-comments $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) $(MV) $(PACKAGE).po $(PACKAGE).pot - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) $(RM) *.js # Don't add a dependency here, we only want to update the .po files manually diff --git a/src/po/Make_mvc.mak b/src/po/Make_mvc.mak index a9a69fdcc2..174908ae54 100644 --- a/src/po/Make_mvc.mak +++ b/src/po/Make_mvc.mak @@ -40,7 +40,9 @@ VIMRUNTIME = ..\..\runtime PACKAGE = vim # Correct the following line for the where executeable file vim is # installed. Please do not put the path in quotes. -VIM = ..\vim.exe +!IFNDEF VIMPROG +VIMPROG = ..\vim.exe +!ENDIF # Correct the following line for the directory where gettext et al is # installed. Please do not put the path in quotes. @@ -102,7 +104,7 @@ originals : $(MOFILES) converted: $(MOCONVERTED) .po.ck: - "$(VIM)" -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \ + "$(VIMPROG)" -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \ -c "if error == 0 | q | else | num 2 | cq | endif" $< $(TOUCH_TARGET) @@ -496,27 +498,28 @@ files: $(PO_INPUTLIST) $(LS) $(LSFLAGS) $(PO_INPUTLIST) > .\files first_time: files - "$(VIM)" -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \ + "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \ $(PO_VIM_INPUTLIST) + @ copy /a .\files+.\vim_to_js .\allfiles set OLD_PO_FILE_INPUT=yes set OLD_PO_FILE_OUTPUT=yes $(XGETTEXT) --default-domain=$(LANGUAGE) --add-comments $(XGETTEXT_KEYWORDS) \ - --files-from=.\files $(PO_VIM_JSLIST) - "$(VIM)" -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \ + --files-from=.\allfiles + "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \ $(PO_VIM_INPUTLIST) - $(RM) *.js + $(RM) *.js .\vim_to_js $(PACKAGE).pot: files - "$(VIM)" -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \ + "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \ $(PO_VIM_INPUTLIST) + @ copy /a .\files+.\vim_to_js .\allfiles set OLD_PO_FILE_INPUT=yes set OLD_PO_FILE_OUTPUT=yes - $(XGETTEXT) --default-domain=$(PACKAGE) --add-comments $(XGETTEXT_KEYWORDS) \ - --files-from=.\files $(PO_VIM_JSLIST) - $(MV) $(PACKAGE).po $(PACKAGE).pot - "$(VIM)" -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \ + $(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \ + --add-comments $(XGETTEXT_KEYWORDS) --files-from=.\allfiles + "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \ $(PO_VIM_INPUTLIST) - $(RM) *.js + $(RM) *.js .\vim_to_js # Only original translations with default encoding should be updated. # The files that are converted to a different encoding clearly state "DO NOT EDIT". @@ -541,16 +544,39 @@ install-all: all "$(VIMRUNTIME)\lang\%%l\LC_MESSAGES\$(PACKAGE).mo" cleanup-po: $(LANGUAGE).po - "$(VIM)" -u NONE -e -X -S cleanup.vim -c wq $(LANGUAGE).po + "$(VIMPROG)" -u NONE -e -X -S cleanup.vim -c wq $(LANGUAGE).po cleanup-po-all: $(POFILES) - !"$(VIM)" -u NONE -e -X -S cleanup.vim -c wq $** + !"$(VIMPROG)" -u NONE -e -X -S cleanup.vim -c wq $** + +####### +# For translations of plug-ins +####### + +# Preparing the POT file of the plug-in package +POT_PLUGPACKAGE_PATH = $(MAKEDIR) +$(PLUGPACKAGE).pot : $(PO_PLUG_INPUTLIST) + "$(VIMPROG)" -u NONE --not-a-term -S tojavascript.vim \ + $(PLUGPACKAGE).pot $** + $(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \ + --package-name=$(PLUGPACKAGE) \ + --output-dir="$(POT_PLUGPACKAGE_PATH)" \ + --output=$(PLUGPACKAGE).pot --files-from=.\vim_to_js + "$(VIMPROG)" -u NONE --not-a-term -S fixfilenames.vim \ + "$(POT_PLUGPACKAGE_PATH)\$(PLUGPACKAGE).pot" $** + $(RM) *.js .\vim_to_js + +# Converting the PO file of the plug-in package to the binary format of the MO file +MO_PLUGPACKAGE_PATH = $(MAKEDIR) +$(PLUGPACKAGE).mo : $(PO_PLUGPACKAGE) + $(MSGFMT) -o $(MO_PLUGPACKAGE_PATH)\$@ $? + clean: checkclean $(RM) *.mo $(RM) *.pot $(RM) *.orig - $(RM) files + $(RM) files allfiles $(RM) sjiscorr.obj sjiscorr.exe # $(RM) big5corr.obj big5corr.exe diff --git a/src/po/Makefile b/src/po/Makefile index 24a003b852..2e85b149df 100644 --- a/src/po/Makefile +++ b/src/po/Makefile @@ -11,7 +11,7 @@ include Make_all.mak PACKAGE = vim SHELL = /bin/sh -VIM = ../vim +VIMPROG = ../vim # MacOS sed is locale aware, set $LANG to avoid problems. SED = LANG=C sed @@ -40,8 +40,8 @@ converted: $(MOCONVERTED) $(MSGFMTCMD) -o $@ $< .po.ck: - $(VIM) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" -S check.vim \ - -c "if error == 0 | q | else | num 2 | cq | endif" $< + $(VIMPROG) -u NONE --noplugins -e -s -X --cmd "set enc=utf-8" \ + -S check.vim -c "if error == 0 | q | else | num 2 | cq | endif" $< touch $@ check: $(CHECKFILES) @@ -251,6 +251,7 @@ prefixcheck: clean: checkclean rm -f core core.* *.old.po *.mo *.pot sjiscorr rm -f LINGUAS vim.desktop gvim.desktop tmp_*desktop + rm -f ./allfiles # rm -f big5corr distclean: clean @@ -271,21 +272,25 @@ PO_INPUTLIST = \ $(PACKAGE).pot: $(PO_INPUTLIST) $(PO_VIM_INPUTLIST) # Convert the Vim scripts to (what looks like) Javascript. - $(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \ + $(PO_VIM_INPUTLIST) + @ echo ${PO_INPUTLIST} | tr ' ' '\n' > ./allfiles + @ cat ./vim_to_js >> ./allfiles # Create vim.pot. - $(XGETTEXT) --default-domain=$(PACKAGE) --add-comments \ - $(XGETTEXT_KEYWORDS) $(PO_INPUTLIST) $(PO_VIM_JSLIST) - mv -f $(PACKAGE).po $(PACKAGE).pot + $(XGETTEXT) --default-domain=$(PACKAGE) --output=$(PACKAGE).pot \ + --add-comments $(XGETTEXT_KEYWORDS) --files-from=./allfiles # Fix Vim scripts names, so that "gf" works. - $(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \ + $(PO_VIM_INPUTLIST) # Delete the temporary files. - rm *.js + rm -f *.js ./vim_to_js vim.desktop: vim.desktop.in $(POFILES) echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS $(MSGFMT) --desktop -d . --template vim.desktop.in -o tmp_vim.desktop rm -f LINGUAS - if command -v desktop-file-validate; then desktop-file-validate tmp_vim.desktop; fi + if command -v desktop-file-validate; \ + then desktop-file-validate tmp_vim.desktop; fi mv tmp_vim.desktop vim.desktop # The dependency on vim.desktop is only to avoid the two targets are build at @@ -294,7 +299,8 @@ gvim.desktop: gvim.desktop.in $(POFILES) vim.desktop echo $(LANGUAGES) | tr " " "\n" |$(SED) -e '/\./d' | sort > LINGUAS $(MSGFMT) --desktop -d . --template gvim.desktop.in -o tmp_gvim.desktop rm -f LINGUAS - if command -v desktop-file-validate; then desktop-file-validate tmp_gvim.desktop; fi + if command -v desktop-file-validate; \ + then desktop-file-validate tmp_gvim.desktop; fi mv tmp_gvim.desktop gvim.desktop # Only original translations with default encoding should be updated. @@ -311,3 +317,28 @@ $(LANGUAGES): else \ echo "msgmerge for $@.po failed!"; mv $@.po.old $@.po; \ fi + + +####### +# For translations of plug-ins +####### + +# Preparing the POT file of the plug-in package +POT_PLUGPACKAGE_PATH = $(PWD) +$(PLUGPACKAGE).pot: $(PO_PLUG_INPUTLIST) + $(VIMPROG) -u NONE --not-a-term -S tojavascript.vim \ + $(PLUGPACKAGE).pot $? + $(XGETTEXT) --from-code=UTF-8 --default-domain=$(PLUGPACKAGE) \ + --package-name=$(PLUGPACKAGE) \ + --output-dir=$(POT_PLUGPACKAGE_PATH) \ + --output=$(PLUGPACKAGE).pot --files-from=./vim_to_js + $(VIMPROG) -u NONE --not-a-term -S fixfilenames.vim \ + $(POT_PLUGPACKAGE_PATH)/$(PLUGPACKAGE).pot $? + rm -f *.js ./vim_to_js + +# Converting the PO file of the plug-in package to the binary format of the MO +MO_PLUGPACKAGE_PATH = $(PWD) +$(PLUGPACKAGE).mo: $(PO_PLUGPACKAGE) + $(MSGFMTCMD) -o $(MO_PLUGPACKAGE_PATH)/$@ $< + +# vim: set noet sw=8 ts=8 sts=0 wm=0 tw=0 ft=make: diff --git a/src/po/README.txt b/src/po/README.txt index 50aff6a835..801f5e56a7 100644 --- a/src/po/README.txt +++ b/src/po/README.txt @@ -160,3 +160,20 @@ convert ja.po to EUC-JP (supposed as your system encoding): "Content-Type: text/plain; charset=EUC-JP\n" There are examples in the Makefile for the conversions already supported. + + +TRANSLATION OF VIM THE EDITOR PLUG-INS + +Vim supports displaying plugin messages for various native languages. +Translation is available both for plugins that are supplied as part of the Vim +editor (e.g. "optwin.vim") and for third-party plugin packages. + +To translate the plugins supplied with the Vim editor, you must specify a +gettext() function call for the strings you want to translate. +The translation of these strings will be retrieved by gettext() from the MO +file "vim.mo". + +For third-party plugins, it is necessary to specify a one-time call to the +bindtextdomain() function in scripts containing translation strings and for +all message strings to add a {package} argument to the gettext() function. For +more information, see ":help package-translation". diff --git a/src/po/README_mvc.txt b/src/po/README_mvc.txt index ae9fa2b1ff..e5fd85e2ec 100644 --- a/src/po/README_mvc.txt +++ b/src/po/README_mvc.txt @@ -137,4 +137,22 @@ command: nmake.exe -f Make_mvc.mak clean + +TRANSLATION OF VIM THE EDITOR PLUG-INS + +Vim supports displaying plugin messages for various native languages. +Translation is available both for plugins that are supplied as part of the Vim +editor (e.g. "optwin.vim") and for third-party plugin packages. + +To translate the plugins supplied with the Vim editor, you must specify a +gettext() function call for the strings you want to translate. +The translation of these strings will be retrieved by gettext() from the MO +file "vim.mo". + +For third-party plugins, it is necessary to specify a one-time call to the +bindtextdomain() function in scripts containing translation strings and for +all message strings to add a {package} argument to the gettext() function. For +more information, see ":help package-translation". + + vim:tw=78: diff --git a/src/po/ca.po b/src/po/ca.po index caf02a9421..052caad20e 100644 --- a/src/po/ca.po +++ b/src/po/ca.po @@ -1326,8 +1326,8 @@ msgstr " Compleci msgid " Omni completion (^O^N^P)" msgstr " Omni-compleci (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Suggeriment d'ortografia (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Suggeriment d'ortografia (^S^N^P)" # i C-x C-p msgid " Keyword Local completion (^N^P)" diff --git a/src/po/check.vim b/src/po/check.vim index b0460f10de..2ea4a3824e 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/da.po b/src/po/da.po index 80cc6feea9..4cb212a3bf 100644 --- a/src/po/da.po +++ b/src/po/da.po @@ -412,8 +412,8 @@ msgstr " Fuldførelse af brugerdefineret (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Fuldførelse af omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Staveforslag (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Staveforslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Fuldførelse af nøgleord local (^N^P)" diff --git a/src/po/de.po b/src/po/de.po index f0f00d7921..99a62db281 100644 --- a/src/po/de.po +++ b/src/po/de.po @@ -1376,8 +1376,8 @@ msgstr " Benutzerdefinierte Vervollst msgid " Omni completion (^O^N^P)" msgstr " Omni-Vervollstndigung (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Vorschlag der Rechtschreibprfung (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Vorschlag der Rechtschreibprfung (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokale Stichwort-Vervollstndigung(^N^P)" diff --git a/src/po/eo.po b/src/po/eo.po index a9aaefa821..3f86652cc8 100644 --- a/src/po/eo.po +++ b/src/po/eo.po @@ -2616,8 +2616,8 @@ msgstr " Kompletigo difinita de uzanto (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Kompletigo Omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Sugesto de literumo (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Sugesto de literumo (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Kompletigo loka de ŝlosilvorto (^N/^P)" diff --git a/src/po/es.po b/src/po/es.po index cfd3b6ec96..2f02c95122 100644 --- a/src/po/es.po +++ b/src/po/es.po @@ -1351,8 +1351,8 @@ msgstr " Completar definido por usuario (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Completar con método Omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Sugerencia de ortografía (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Sugerencia de ortografía (^S^N^P)" # Scroll has its own msgs, in its place there is the msg for local # * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo diff --git a/src/po/fi.po b/src/po/fi.po index d2fd336be7..9dc24d33bc 100644 --- a/src/po/fi.po +++ b/src/po/fi.po @@ -1325,8 +1325,8 @@ msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omnitäydennys (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Oikaisulukuehdotus (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Oikaisulukuehdotus (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Avainsanan paikallinen täydennys (^N^P)" diff --git a/src/po/fixfilenames.vim b/src/po/fixfilenames.vim index 04bc0791c0..2344b3bdc4 100644 --- a/src/po/fixfilenames.vim +++ b/src/po/fixfilenames.vim @@ -3,9 +3,11 @@ set shortmess+=A -for name in argv()[1:] - let jsname = fnamemodify(name, ":t:r") .. ".js" - exe "%s+" .. jsname .. "+" .. substitute(name, '\\', '/', 'g') .. "+" +let s:namenum = 0 +for s:name in argv()[1:] + let s:jsname = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js" + exe "%s+" .. s:jsname .. "+" .. substitute(s:name, '\\', '/', 'g') .. "+ge" + let s:namenum +=1 endfor write diff --git a/src/po/fr.po b/src/po/fr.po index 27f11eb742..3a55f8d4e9 100644 --- a/src/po/fr.po +++ b/src/po/fr.po @@ -2738,8 +2738,8 @@ msgstr " Compl msgid " Omni completion (^O^N^P)" msgstr " Compltement selon le type de fichier (Omni) (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Suggestion d'orthographe (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Suggestion d'orthographe (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Compltement local de mot-cl (^N/^P)" diff --git a/src/po/ga.po b/src/po/ga.po index e81ef69d0f..cd1a02970b 100644 --- a/src/po/ga.po +++ b/src/po/ga.po @@ -1401,8 +1401,8 @@ msgstr " Comhl msgid " Omni completion (^O^N^P)" msgstr " Comhln Omni (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Moladh litrithe (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Moladh litrithe (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Comhln lognta lorgfhocal (^N^P)" diff --git a/src/po/hu.po b/src/po/hu.po index 0a11847554..221cf3302d 100644 --- a/src/po/hu.po +++ b/src/po/hu.po @@ -264,8 +264,8 @@ msgstr " Felhasználó által definiált kiegészítés (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni kiegészítés (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Helyesírási javaslat (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Helyesírási javaslat (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Kulcsszó helyi kiegészítés (^N^P)" diff --git a/src/po/it.po b/src/po/it.po index 8bdc5e3459..da83291438 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" @@ -1287,8 +1287,8 @@ msgstr " Completamento definito dall'utente (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Completamento globale (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Suggerimento ortografico (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Suggerimento ortografico (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Completamento Parola Locale (^N^P)" @@ -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/po/ja.euc-jp.po b/src/po/ja.euc-jp.po index 362be9ebcb..cc9c6c3768 100644 --- a/src/po/ja.euc-jp.po +++ b/src/po/ja.euc-jp.po @@ -1337,8 +1337,8 @@ msgstr " msgid " Omni completion (^O^N^P)" msgstr " 䴰 (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ֤꽤 (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ֤꽤 (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ɽꥭ䴰 (^N^P)" diff --git a/src/po/ja.po b/src/po/ja.po index 3b63fcf08a..06201b2c6e 100644 --- a/src/po/ja.po +++ b/src/po/ja.po @@ -1337,8 +1337,8 @@ msgstr " ユーザー定義補完 (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " オムニ補完 (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " 綴り修正候補 (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " 綴り修正候補 (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " 局所キーワード補完 (^N^P)" diff --git a/src/po/ja.sjis.po b/src/po/ja.sjis.po index 589fd5abff..e40627e8d3 100644 --- a/src/po/ja.sjis.po +++ b/src/po/ja.sjis.po @@ -1337,8 +1337,8 @@ msgstr " msgid " Omni completion (^O^N^P)" msgstr " Ij⊮ (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ԂC (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ԂC (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ǏL[[h⊮ (^N^P)" diff --git a/src/po/ko.UTF-8.po b/src/po/ko.UTF-8.po index a9ee0ca748..f7714ae60c 100644 --- a/src/po/ko.UTF-8.po +++ b/src/po/ko.UTF-8.po @@ -411,8 +411,8 @@ msgstr " 사용자 정의 완성 (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni 완성 (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " 단어 제안 (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " 단어 제안 (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " 낱말 로컬 완성 (^N^P)" diff --git a/src/po/ko.po b/src/po/ko.po index 00fb48681f..ab957a5e18 100644 --- a/src/po/ko.po +++ b/src/po/ko.po @@ -411,8 +411,8 @@ msgstr " msgid " Omni completion (^O^N^P)" msgstr " Omni ϼ (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ܾ (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ܾ (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ϼ (^N^P)" diff --git a/src/po/nb.po b/src/po/nb.po index d9f527bce4..957b99d480 100644 --- a/src/po/nb.po +++ b/src/po/nb.po @@ -283,9 +283,8 @@ msgstr " Brukerdefinert fullf msgid " Omni completion (^O^N^P)" msgstr " Omni-fullfring (^O^N^P)" -#, fuzzy -#~ msgid " Spelling suggestion (s^N^P)" -#~ msgstr " Staveforslag (^S^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Staveforslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokal nkkelordfullfring (^N^P)" diff --git a/src/po/nl.po b/src/po/nl.po index 09f281b1bd..6ac59ca330 100644 --- a/src/po/nl.po +++ b/src/po/nl.po @@ -287,8 +287,8 @@ msgstr " gebruikergedefinieerde voltooiing (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " omni-voltooiing (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " spellingsuggestie (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " spellingsuggestie (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " lokaal-trefwoordvoltooiing (^N^P)" diff --git a/src/po/no.po b/src/po/no.po index d9f527bce4..957b99d480 100644 --- a/src/po/no.po +++ b/src/po/no.po @@ -283,9 +283,8 @@ msgstr " Brukerdefinert fullf msgid " Omni completion (^O^N^P)" msgstr " Omni-fullfring (^O^N^P)" -#, fuzzy -#~ msgid " Spelling suggestion (s^N^P)" -#~ msgstr " Staveforslag (^S^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Staveforslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokal nkkelordfullfring (^N^P)" diff --git a/src/po/pl.UTF-8.po b/src/po/pl.UTF-8.po index c9036a35ec..39064f6135 100644 --- a/src/po/pl.UTF-8.po +++ b/src/po/pl.UTF-8.po @@ -298,8 +298,8 @@ msgstr "Dopełnianie zdefiniowane przez użytkownika (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni uzupełnianie (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr "Propozycja pisowni (^L^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr "Propozycja pisowni (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokalne dopełnianie słów kluczowych (^N^P)" diff --git a/src/po/pl.cp1250.po b/src/po/pl.cp1250.po index 9280d2fbb0..b748b4a22f 100644 --- a/src/po/pl.cp1250.po +++ b/src/po/pl.cp1250.po @@ -298,8 +298,8 @@ msgstr "Dope msgid " Omni completion (^O^N^P)" msgstr " Omni uzupenianie (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr "Propozycja pisowni (^L^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr "Propozycja pisowni (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokalne dopenianie sw kluczowych (^N^P)" diff --git a/src/po/pl.po b/src/po/pl.po index f10897d098..aebc33faf8 100644 --- a/src/po/pl.po +++ b/src/po/pl.po @@ -298,8 +298,8 @@ msgstr "Dope msgid " Omni completion (^O^N^P)" msgstr " Omni uzupenianie (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr "Propozycja pisowni (^L^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr "Propozycja pisowni (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokalne dopenianie sw kluczowych (^N^P)" diff --git a/src/po/pt_BR.po b/src/po/pt_BR.po index 3a8844a544..ea5a17fb1a 100644 --- a/src/po/pt_BR.po +++ b/src/po/pt_BR.po @@ -406,8 +406,8 @@ msgstr " Completar definido pelo usuário (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Completação inteligente (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Sugestão de ortografia (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Sugestão de ortografia (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Completar palavra-chave local (^N^P)" diff --git a/src/po/ru.cp1251.po b/src/po/ru.cp1251.po index 05d10e00df..caf584f857 100644 --- a/src/po/ru.cp1251.po +++ b/src/po/ru.cp1251.po @@ -2045,7 +2045,7 @@ msgid " Omni completion (^O^N^P)" msgstr " CTRL+O CTRL+N CTRL+P" # :!~ Restorer -msgid " Spelling suggestion (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" msgstr " CTRL+S CTRL+N CTRL+P" # :!~ Restorer diff --git a/src/po/ru.po b/src/po/ru.po index 13589d0ce5..a679b4f411 100644 --- a/src/po/ru.po +++ b/src/po/ru.po @@ -2039,7 +2039,7 @@ msgid " Omni completion (^O^N^P)" msgstr " Подстановка по контексту CTRL+O и CTRL+N или CTRL+P" # :!~ Restorer -msgid " Spelling suggestion (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" msgstr " Подстановка вариантов написания CTRL+S и CTRL+N или CTRL+P" # :!~ Restorer diff --git a/src/po/sr.po b/src/po/sr.po index 2f5113c6d0..3b76e3c483 100644 --- a/src/po/sr.po +++ b/src/po/sr.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Serbian)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-04 14:05+0400\n" -"PO-Revision-Date: 2024-03-04 14:10+0400\n" +"POT-Creation-Date: 2024-07-19 10:23+0400\n" +"PO-Revision-Date: 2024-07-19 10:39+0400\n" "Last-Translator: Ivan Pešić <ivan.pesic@gmail.com>\n" "Language-Team: Serbian\n" "Language: sr\n" @@ -447,10 +447,6 @@ msgstr "катакана" msgid "Bopomofo" msgstr "бопомофо" -msgid "Not enough memory to set references, garbage collection aborted!" -msgstr "" -"Нема довољно меморије за постављање референци, прекинуто је скупљање отпада" - msgid "" "\n" "\tLast set from " @@ -879,6 +875,10 @@ msgstr[0] "+-%s%3ld линија: " msgstr[1] "+-%s%3ld линије: " msgstr[2] "+-%s%3ld линија: " +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "" +"Нема довољно меморије за постављање референци, прекинуто је скупљање отпада" + msgid "No match at cursor, finding next" msgstr "Нема подударања на месту курсора, тражи се даље" @@ -1262,15 +1262,6 @@ msgstr "linenr је ван опсега" msgid "not allowed in the Vim sandbox" msgstr "није дозвољено унутар Vim sandbox" -#, c-format -msgid "E370: Could not load library %s" -msgstr "E370: Библиотека %s није могла да се учита" - -msgid "Sorry, this command is disabled: the Perl library could not be loaded." -msgstr "" -"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да се " -"учита." - msgid "invalid buffer number" msgstr "неисправан број бафера" @@ -1372,8 +1363,8 @@ msgstr " Кориснички дефинисано довршавање (^U^N^P) msgid " Omni completion (^O^N^P)" msgstr " Omni довршавање (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Правописни предлог (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Правописни предлог (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Довршавање локалне кључне речи (^N^P)" @@ -3622,6 +3613,9 @@ msgstr " 2ги кориснички vimrc фајл: \"" msgid " 3rd user vimrc file: \"" msgstr " 3ћи кориснички vimrc фајл: \"" +msgid " 4th user vimrc file: \"" +msgstr " 4ти кориснички vimrc фајл: \"" + msgid " user exrc file: \"" msgstr " кориснички exrc фајл: \"" @@ -3883,6 +3877,15 @@ msgstr "Уписивање viminfo фајла „%s”" msgid "Already only one window" msgstr "Већ постоји само један прозор" +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: Библиотека %s није могла да се учита" + +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да се " +"учита." + msgid "Edit with Vim using &tabpages" msgstr "Уређуј програмом Vim у новој &картици" @@ -5936,9 +5939,6 @@ msgstr "E612: Дефинисано је превише знакова" msgid "E613: Unknown printer font: %s" msgstr "E613: Непознат фонт штампача: %s" -msgid "E614: Class required" -msgstr "E614: Потребна је класа" - #, c-format msgid "E616: Object required for argument %d" msgstr "E616: За аргумент %d је потребан објекат" @@ -6834,6 +6834,10 @@ msgstr "" "E876: (НКА регуларни израз) Нема довољно простора да се ускладишти комплетан " "НКА" +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %d" +msgstr "E877: (НКА регуларни израз) Неисправна класа карактера: %d" + msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!" msgstr "" "E878: (НКА регуларни израз) Није могла да се алоцира меморија за обилазак " @@ -8414,21 +8418,12 @@ msgstr "E1317: Неисправна декларација променљиве msgid "E1318: Not a valid command in a class: %s" msgstr "E1318: Команда не важи у класи: %s" -msgid "E1319: Using a Class as a Number" -msgstr "E1319: Класа се користи као Број" - msgid "E1320: Using an Object as a Number" msgstr "E1320: Објекат се користи као Број" -msgid "E1321: Using a Class as a Float" -msgstr "E1321: Класа се користи као Покретни" - msgid "E1322: Using an Object as a Float" msgstr "E1322: Објекат се користи као Покретни" -msgid "E1323: Using a Class as a String" -msgstr "E1323: Класа се користи као Стринг" - msgid "E1324: Using an Object as a String" msgstr "E1324: Објекат се користи као Стринг" @@ -8457,14 +8452,14 @@ msgid "E1330: Invalid type for object variable: %s" msgstr "E1330: Неисправан тип променљиве објекта: %s" msgid "" -"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or " +"E1331: public must be followed by \"var\" or \"static\" or \"final\" or " "\"const\"" msgstr "" -"E1331: Након Public мора да следи „var” или „static” или „final” или „const”" +"E1331: Након public мора да следи „var” или „static” или „final” или „const”" #, c-format -msgid "E1332: Public variable name cannot start with underscore: %s" -msgstr "E1332: Име Public променљиве не може почети доњом цртом: %s" +msgid "E1332: public variable name cannot start with underscore: %s" +msgstr "E1332: Име public променљиве не може почети доњом цртом: %s" #, c-format msgid "E1333: Cannot access protected variable \"%s\" in class \"%s\"" @@ -8662,10 +8657,10 @@ msgstr "" "E1386: Методи објекта „%s” може да се приступи само користећи објекат класе " "„%s”" -msgid "E1387: Public variable not supported in an interface" -msgstr "E1387: У интерфејсу се не подржава јавна променљива" +msgid "E1387: public variable not supported in an interface" +msgstr "E1387: У интерфејсу се не подржава public променљива" -msgid "E1388: Public keyword not supported for a method" +msgid "E1388: public keyword not supported for a method" msgstr "E1388: Метода не подржава кључну реч public" msgid "E1389: Missing name after implements" @@ -8695,10 +8690,6 @@ msgstr "E1393: Тип може да се дефинише само у Vim9 ск msgid "E1394: Type name must start with an uppercase letter: %s" msgstr "E1394: Име типа мора да почне великим словом: %s" -#, c-format -msgid "E1395: Type alias \"%s\" cannot be modified" -msgstr "E1395: Алијас типа „%s” не може да се измени" - #, c-format msgid "E1396: Type alias \"%s\" already exists" msgstr "E1396: Алијас типа „%s” већ постоји" @@ -8712,18 +8703,6 @@ msgstr "E1398: Недостаје тип алијаса типа" msgid "E1399: Type can only be used in a script" msgstr "E1399: Тип може да се употреби само у скрипти" -#, c-format -msgid "E1400: Using type alias \"%s\" as a Number" -msgstr "E1400: Алијас типа „%s” се користи као Број" - -#, c-format -msgid "E1401: Using type alias \"%s\" as a Float" -msgstr "E1401: Алијас типа „%s” се користи као Покретни" - -#, c-format -msgid "E1402: Using type alias \"%s\" as a String" -msgstr "E1402: Алијас типа „%s” се користи као Стринг" - #, c-format msgid "E1403: Type alias \"%s\" cannot be used as a value" msgstr "E1403: Алијас типа „%s” не може да се користи као вредност" @@ -8735,9 +8714,6 @@ msgstr "E1404: Abstract не може да се користи у интерфе msgid "E1405: Class \"%s\" cannot be used as a value" msgstr "E1405: Класа „%s” не може да се користи као вредност" -msgid "E1406: Cannot use a Class as a variable or value" -msgstr "E1406: Класа не може да се користи као променљива или вредност" - msgid "E1407: Cannot use a Typealias as a variable or value" msgstr "E1407: Алијас типа не може да се користи као променљива или вредност" @@ -8763,6 +8739,65 @@ msgstr "E1412: Није подржана уграђена метода обје msgid "E1413: Builtin class method not supported" msgstr "E1413: Није подржана уграђена метода класе" +msgid "E1414: Enum can only be defined in Vim9 script" +msgstr "E1414: Набрајање може да се дефинише само у Vim9 скрипти" + +#, c-format +msgid "E1415: Enum name must start with an uppercase letter: %s" +msgstr "E1415: Име набрајања мора да почне великим словом: %s" + +msgid "E1416: Enum cannot extend a class or enum" +msgstr "E1416: Набрајање не може да прошири класу или набрајање" + +msgid "E1417: Abstract cannot be used in an Enum" +msgstr "E1417: Abstract не може да се користи у набрајању" + +#, c-format +msgid "E1418: Invalid enum value declaration: %s" +msgstr "E1418: Неисправна декларација вредности набрајања: %s" + +#, c-format +msgid "E1419: Not a valid command in an Enum: %s" +msgstr "E1419: Команда не важи у набрајању: %s" + +msgid "E1420: Missing :endenum" +msgstr "E1420: Недостаје :endenum" + +#, c-format +msgid "E1421: Enum \"%s\" cannot be used as a value" +msgstr "E1421: Набрајање „%s” не може да се користи као вредност" + +#, c-format +msgid "E1422: Enum value \"%s\" not found in enum \"%s\"" +msgstr "E1422: Вредност набрајања „%s” није пронађена у набрајању „%s”" + +#, c-format +msgid "E1423: Enum value \"%s.%s\" cannot be modified" +msgstr "E1423: Вредност набрајања „%s.%s” не може да се измени" + +#, c-format +msgid "E1424: Using an Enum \"%s\" as a Number" +msgstr "E1424: Набрајање „%s” се користи као Број" + +#, c-format +msgid "E1425: Using an Enum \"%s\" as a String" +msgstr "E1425: Набрајање „%s” се користи као Стринг" + +#, c-format +msgid "E1426: Enum \"%s\" ordinal value cannot be modified" +msgstr "E1426: Редна вредност набрајања „%s” не може да се измени" + +#, c-format +msgid "E1427: Enum \"%s\" name cannot be modified" +msgstr "E1427: Набрајање „%s” не може да се измени" + +#, c-format +msgid "E1428: Duplicate enum value: %s" +msgstr "E1428: Дуплирана вредност набрајања: %s" + +msgid "E1429: Class can only be used in a script" +msgstr "E1429: Class може да се употреби само у скрипти" + #, c-format msgid "E1500: Cannot mix positional and non-positional arguments: %s" msgstr "E1500: Не могу да се мешају позициони и непозициони аргументи: %s" @@ -8817,8 +8852,8 @@ msgstr "E1511: Погрешан број карактера за поље „%s msgid "E1512: Wrong character width for field \"%s\"" msgstr "E1512: Погрешна ширина карактера за поље „%s”" -msgid "E1513: Cannot edit buffer. 'winfixbuf' is enabled" -msgstr "E1513: Не може да се уређује бафер. Укључена је опција 'winfixbuf'" +msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled" +msgstr "E1513: Не може да пређе на други бафер. Укључена је опција 'winfixbuf'" msgid "--No lines in buffer--" msgstr "--У баферу нема линија--" @@ -9635,6 +9670,9 @@ msgstr "вишеструке картице" msgid "0, 1 or 2; when to use a tab pages line" msgstr "0, 1 или 2; када се користи линија са картицама" +msgid "behaviour when closing tab pages: left, uselast or empty" +msgstr "понашање приликом затварања картице: left, uselast или празно" + msgid "maximum number of tab pages to open for -p and \"tab all\"" msgstr "максимални број картица које се отварају за -p и „tab all”" diff --git a/src/po/sv.po b/src/po/sv.po index 629a22c9b0..d5296dba9d 100644 --- a/src/po/sv.po +++ b/src/po/sv.po @@ -261,8 +261,8 @@ msgstr " Anv msgid " Omni completion (^O^N^P)" msgstr " Omnikomplettering (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Stavningsfrslag (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Stavningsfrslag (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Lokal nyckelordskomplettering (^N^P)" diff --git a/src/po/tojavascript.vim b/src/po/tojavascript.vim index 8b0dd736d5..4671a472fa 100644 --- a/src/po/tojavascript.vim +++ b/src/po/tojavascript.vim @@ -5,15 +5,20 @@ set shortmess+=A -for name in argv()[1:] - exe 'edit ' .. fnameescape(name) +let s:namenum = 0 +let s:fls = [] +for s:name in argv()[1:] + exe 'edit ' .. fnameescape(s:name) " Strip comments, also after :set commands. g/^\s*"/s/.*// g/^\s*set .*"/s/.*// " Write as .js file, xgettext recognizes them - exe 'w! ' .. fnamemodify(name, ":t:r") .. ".js" + let s:fl = fnamemodify(s:name, ":t:r") .. s:namenum .. ".js" + exe 'w! ' .. s:fl + call add(s:fls, s:fl) + let s:namenum += 1 endfor - +call writefile(s:fls, "vim_to_js") quit diff --git a/src/po/tr.po b/src/po/tr.po index 4cff7b327d..1150d60268 100644 --- a/src/po/tr.po +++ b/src/po/tr.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim Turkish Localization Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-17 12:57+0300\n" -"PO-Revision-Date: 2023-12-17 17:00+0300\n" +"POT-Creation-Date: 2024-06-18 13:41+0300\n" +"PO-Revision-Date: 2024-06-18 17:00+0300\n" "Last-Translator: Emir SARI <emir_sari@icloud.com>\n" "Language-Team: Turkish <https://github.com/bitigchi/vim>\n" "Language: tr\n" @@ -173,6 +173,9 @@ msgstr " (dosya %d/%d)" msgid " (file (%d) of %d)" msgstr " (dosya (%d)/%d)" +msgid "[Command Line]" +msgstr "[Komut Satırı]" + msgid "[Prompt]" msgstr "[İstem]" @@ -444,9 +447,6 @@ msgstr "Katakana" msgid "Bopomofo" msgstr "Bopomofo" -msgid "Not enough memory to set references, garbage collection aborted!" -msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu" - msgid "" "\n" "\tLast set from " @@ -697,9 +697,6 @@ msgstr "Hata" msgid "Interrupt" msgstr "Yarıda Kesilme" -msgid "[Command Line]" -msgstr "[Komut Satırı]" - msgid "is a directory" msgstr "bir dizin" @@ -868,6 +865,9 @@ msgid_plural "+-%s%3ld lines: " msgstr[0] "+-%s%3ld satır: " msgstr[1] "+-%s%3ld satır: " +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu" + msgid "No match at cursor, finding next" msgstr "İmleç konumunda eşleşme bulunamadı, sonraki bulunuyor" @@ -1348,8 +1348,8 @@ msgstr " Kullanıcı tanımlı tamamlamalar (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Omni tamamlaması (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Yazım önerisi (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Yazım önerisi (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Dahili anahtar sözcük tamamlaması (^N^P)" @@ -1427,6 +1427,9 @@ msgstr "mapnew() argümanı" msgid "filter() argument" msgstr "filter() argümanı" +msgid "foreach() argument" +msgstr "foreach() argümanı" + msgid "extendnew() argument" msgstr "extendnew() argümanı" @@ -2473,6 +2476,9 @@ msgstr "%s, %s üzerinde" msgid "Printing '%s'" msgstr "'%s' yazdırılıyor" +#~ msgid "DefaultFontNameForWindows" +#~ msgstr "" + #, c-format msgid "Opening the X display took %ld msec" msgstr "X ekranını açma %ld milisaniye sürdü" @@ -3414,8 +3420,8 @@ msgid "%s returning %s" msgstr "%s, %s döndürüyor" #, c-format -msgid "Function %s does not need compiling" -msgstr "%s işlevini derlemeye gerek yok " +msgid "Function %s%s%s does not need compiling" +msgstr "%s%s%s işlevini derlemeye gerek yok " #, c-format msgid "%s (%s, compiled %s)" @@ -3574,6 +3580,10 @@ msgstr " kullanıcı 2. vimrc dosyası: \"" msgid " 3rd user vimrc file: \"" msgstr " kullanıcı 3. vimrc dosyası: \"" +msgid " 4th user vimrc file: \"" +msgstr " kullanıcı 4. vimrc dosyası: \"" + + msgid " user exrc file: \"" msgstr " kullanıcı exrc dosyası: \"" @@ -4180,6 +4190,10 @@ msgstr "E104: Kaçan, ikili harflerde kullanılamaz" msgid "E105: Using :loadkeymap not in a sourced file" msgstr "E105: :loadkeymap kaynak alınmayan bir dosyada kullanılıyor" +#, c-format +msgid "E106: Unsupported diff output format: %s" +msgstr "E106: Desteklenmeyen diff çıktısı biçimi: %s" + #, c-format msgid "E107: Missing parentheses: %s" msgstr "E107: Ayraç eksik: %s" @@ -4509,8 +4523,8 @@ msgstr "E196: Bu sürümde ikili harfler bulunmamaktadır" msgid "E197: Cannot set language to \"%s\"" msgstr "E197: \"%s\" diline ayarlanamıyor" -msgid "E199: Active window or buffer deleted" -msgstr "E199: Etkin pencere veya arabellek silinmiş" +msgid "E199: Active window or buffer changed or deleted" +msgstr "E199: Etkin pencere veya arabellek değiştirilmiş veya silinmiş" msgid "E200: *ReadPre autocommands made the file unreadable" msgstr "E200: *ReadPre otokomutları dosyayı okunamaz hale getirdi" @@ -6771,6 +6785,10 @@ msgstr "" msgid "E876: (NFA regexp) Not enough space to store the whole NFA" msgstr "E876: (BSO düzenli ifadesi) Tüm BSO'yu depolamak için yeterli alan yok" +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %d" +msgstr "E877: (BSO düzenli ifadesi) Geçersiz karakter sınıfı: %d" + msgid "E878: (NFA regexp) Could not allocate memory for branch traversal!" msgstr "E878: (BSO düzenli ifadesi) Dal gezinmesi için bellek ayrılamadı!" @@ -8383,13 +8401,14 @@ msgid "E1330: Invalid type for object variable: %s" msgstr "E1330: Nesne değişkeni için geçersiz tür: %s" msgid "" -"E1331: Public must be followed by \"var\" or \"static\" or \"final\" or " +"E1331: public must be followed by \"var\" or \"static\" or \"final\" or " "\"const\"" -msgstr "E1331: Public sonrası \"var\", \"static\", \"final\" veya \"const\" " +msgstr "" +"E1331: public sonrası \"var\", \"static\", \"final\" veya \"const\" " "gelmelidir" #, c-format -msgid "E1332: Public variable name cannot start with underscore: %s" +msgid "E1332: public variable name cannot start with underscore: %s" msgstr "E1332: Genel değişken adı bir alt çizgiyle başlayamaz: %s" #, c-format @@ -8512,8 +8531,8 @@ msgstr "E1367: \"%2$s\" arayüzünün \"%1$s\" değişkeninin erişim düzeyi fa msgid "" "E1368: Static must be followed by \"var\" or \"def\" or \"final\" or " "\"const\"" -msgstr "E1368: Static sonrası \"var\", \"def\", \"final\" veya \"const\" " -"gelmelidir" +msgstr "" +"E1368: Static sonrası \"var\", \"def\", \"final\" veya \"const\" gelmelidir" #, c-format msgid "E1369: Duplicate variable: %s" @@ -8535,18 +8554,21 @@ msgstr "E1373: Soyut yöntem \"%s\" gerçeklenmemiş" #, c-format msgid "E1374: Class variable \"%s\" accessible only inside class \"%s\"" -msgstr "E1374: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfının içinde " +msgstr "" +"E1374: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfının içinde " "erişilebilirdir" #, c-format msgid "E1375: Class variable \"%s\" accessible only using class \"%s\"" -msgstr "E1375: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfı kullanılarak " +msgstr "" +"E1375: Sınıf değişkeni \"%s\", yalnızca \"%s\" sınıfı kullanılarak " "erişilebilirdir" #, c-format msgid "E1376: Object variable \"%s\" accessible only using class \"%s\" object" -msgstr "E1376: Nesne değişkeni \"%s\", yalnızca sınıf \"%s\" nesnesi " -"kullanılarak erişilebilirdir" +msgstr "" +"E1376: Nesne değişkeni \"%s\", yalnızca sınıf \"%s\" nesnesi kullanılarak " +"erişilebilirdir" #, c-format msgid "E1377: Access level of method \"%s\" is different in class \"%s\"" @@ -8576,23 +8598,25 @@ msgstr "" #, c-format msgid "E1384: Class method \"%s\" accessible only inside class \"%s\"" -msgstr "E1384: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfının içinde " -"erişilebilirdir" +msgstr "" +"E1384: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfının içinde erişilebilirdir" #, c-format msgid "E1385: Class method \"%s\" accessible only using class \"%s\"" -msgstr "E1385: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfı kullanılarak " +msgstr "" +"E1385: Sınıf yöntemi \"%s\", yalnızca \"%s\" sınıfı kullanılarak " "erişilebilirdir" #, c-format msgid "E1386: Object method \"%s\" accessible only using class \"%s\" object" -msgstr "E1386: Nesne yöntemi \"%s\", yalnızca sınıf \"%s\" nesnesi " -"kullanılarak erişilebilirdir" +msgstr "" +"E1386: Nesne yöntemi \"%s\", yalnızca sınıf \"%s\" nesnesi kullanılarak " +"erişilebilirdir" -msgid "E1387: Public variable not supported in an interface" +msgid "E1387: public variable not supported in an interface" msgstr "E1387: Bir arayüzde genel değişken desteklenmiyor" -msgid "E1388: Public keyword not supported for a method" +msgid "E1388: public keyword not supported for a method" msgstr "E1388: Bir yöntem için genel anahtar sözcük desteklenmiyor" msgid "E1389: Missing name after implements" @@ -8607,12 +8631,14 @@ msgstr "" #, c-format msgid "E1391: Cannot (un)lock variable \"%s\" in class \"%s\"" -msgstr "E1391: \"%2$s\" sınıfındaki \"%1$s\" değişkeni kilitlenemiyor/açılamıyor" +msgstr "" +"E1391: \"%2$s\" sınıfındaki \"%1$s\" değişkeni kilitlenemiyor/açılamıyor" #, c-format msgid "E1392: Cannot (un)lock class variable \"%s\" in class \"%s\"" -msgstr "E1392: \"%2$s\" sınıfındaki \"%1$s\" sınıf değişkeni " -"kilitlenemiyor/açılamıyor" +msgstr "" +"E1392: \"%2$s\" sınıfındaki \"%1$s\" sınıf değişkeni kilitlenemiyor/" +"açılamıyor" msgid "E1393: Type can only be defined in Vim9 script" msgstr "E1393: Tür, yalnızca Vim9 betiğinde tanımlanabilir" @@ -8672,12 +8698,82 @@ msgstr "E1408: Final değişkeni bir arayüzde desteklenmiyor" #, c-format msgid "E1409: Cannot change read-only variable \"%s\" in class \"%s\"" -msgstr "E1409: \"%2$s\" sınıfındaki \"%1$s\" saltokunur değişken " -"değiştirilemiyor" +msgstr "" +"E1409: \"%2$s\" sınıfındaki \"%1$s\" saltokunur değişken değiştirilemiyor" msgid "E1410: Const variable not supported in an interface" msgstr "E1410: Bir arayüzde bir bir Const değişken desteklenmiyor" +#, c-format +msgid "E1411: Missing dot after object \"%s\"" +msgstr "E1411: \"%s\" nesnesi sonrası nokta eksik" + +#, c-format +msgid "E1412: Builtin object method \"%s\" not supported" +msgstr "E1412: Yerleşik nesne yöntemi \"%s\" desteklenmiyor" + +msgid "E1413: Builtin class method not supported" +msgstr "E1413: Yerleşik sınıf yöntemi desteklenmiyor" + +msgid "E1414: Enum can only be defined in Vim9 script" +msgstr "E1414: Enümerasyon, yalnızca Vim9 betiğinde kullanılabilir" + +#, c-format +msgid "E1415: Enum name must start with an uppercase letter: %s" +msgstr "E1415: Enümerasyon adı bir BÜYÜK harfle başlamalıdır: %s" + +msgid "E1416: Enum cannot extend a class or enum" +msgstr "E1416: Enümerasyon, bir sınıfı veya enümerasyonu genişletemez" + +msgid "E1417: Abstract cannot be used in an Enum" +msgstr "E1417: Abstract yalnızca bir enümerasyonda kullanılabilir" + +#, c-format +msgid "E1418: Invalid enum value declaration: %s" +msgstr "E1418: Geçersiz enümerasyon değeri beyanı: %s" + +#, c-format +msgid "E1419: Not a valid command in an Enum: %s" +msgstr "E1419: Bir enümerasyonda geçerli olmayan bir komut: %s" + +msgid "E1420: Missing :endenum" +msgstr "E1420: :endenum eksik" + +#, c-format +msgid "E1421: Enum \"%s\" cannot be used as a value" +msgstr "E1421: \"%s\" enümerasyonu yalnızca bir değer olarak kullanılabilir" + +#, c-format +msgid "E1422: Enum value \"%s\" not found in enum \"%s\"" +msgstr "E1422: \"%2$s\" enümerasyonunda \"%1$s\" değeri bulunamadı" + +#, c-format +msgid "E1423: Enum value \"%s.%s\" cannot be modified" +msgstr "E1423: Enümerasyon değeri \"%s.%s\" değiştirilemiyor" + +#, c-format +msgid "E1424: Using an Enum \"%s\" as a Number" +msgstr "E1424: Enümerasyon \"%s\", sayı olarak kullanılıyor" + +#, c-format +msgid "E1425: Using an Enum \"%s\" as a String" +msgstr "E1425: Enümerasyon \"%s\", dizi olarak kullanılıyor" + +#, c-format +msgid "E1426: Enum \"%s\" ordinal value cannot be modified" +msgstr "E1426: Enümerasyon sıralı değeri \"%s\" değiştirilemiyor" + +#, c-format +msgid "E1427: Enum \"%s\" name cannot be modified" +msgstr "E1427: Enümerasyon adı \"%s\" değiştirilemiyor" + +#, c-format +msgid "E1428: Duplicate enum value: %s" +msgstr "E1428: Yinelenen enümerasyon değeri: %s" + +msgid "E1429: Class can only be used in a script" +msgstr "E1429: Sınıf yalnızca bir betikte kullanılabilir" + #, c-format msgid "E1500: Cannot mix positional and non-positional arguments: %s" msgstr "E1500: Konumsal ve konumsal olmayan argümanlar karıştırılamıyor: %s" @@ -8724,6 +8820,17 @@ msgstr "E1509: Genişletilmiş öznitelik okunurken veya yazılırken hata oluş msgid "E1510: Value too large: %s" msgstr "E1510: Değer pek büyük: %s" +#, c-format +msgid "E1511: Wrong number of characters for field \"%s\"" +msgstr "E1511: \"%s\" alanı için yanlış karakter sayısı" + +#, c-format +msgid "E1512: Wrong character width for field \"%s\"" +msgstr "E1512: \"%s\" alanı için yanlış karakter genişliği" + +msgid "E1513: Cannot switch buffer. 'winfixbuf' is enabled" +msgstr "E1513: Arabellek değiştirilemiyor. 'winfixbuf' etkinleştirilmiş" + msgid "--No lines in buffer--" msgstr "--Arabellek içinde satır yok--" @@ -9442,6 +9549,9 @@ msgstr "geçerli pencere için kullanılan en az satır sayısı" msgid "minimal number of lines used for any window" msgstr "herhangi bir pencere için kullanılan en az satır sayısı" +msgid "keep window focused on a single buffer" +msgstr "pencereyi tek bir arabelleğe odaklı tut" + msgid "keep the height of the window" msgstr "pencerenin yüksekliğini tut" diff --git a/src/po/uk.cp1251.po b/src/po/uk.cp1251.po index 40d87f5906..1a14b2a3d8 100644 --- a/src/po/uk.cp1251.po +++ b/src/po/uk.cp1251.po @@ -1386,8 +1386,8 @@ msgstr " msgid " Omni completion (^O^N^P)" msgstr " (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " (^N^P)" diff --git a/src/po/uk.po b/src/po/uk.po index 273f833c10..d756d4558c 100644 --- a/src/po/uk.po +++ b/src/po/uk.po @@ -1386,8 +1386,8 @@ msgstr " Користувацьке доповнення (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " Кмітливе доповнення (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " Орфографічна підказка (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " Орфографічна підказка (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " Доповнення місцевих ключових слів (^N^P)" diff --git a/src/po/zh_CN.UTF-8.po b/src/po/zh_CN.UTF-8.po index c034b45b80..a12fefbdc4 100644 --- a/src/po/zh_CN.UTF-8.po +++ b/src/po/zh_CN.UTF-8.po @@ -1291,8 +1291,8 @@ msgstr " 用户自定义补全 (^U^N^P)" msgid " Omni completion (^O^N^P)" msgstr " 全能补全 (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " 拼写建议 (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " 拼写建议 (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " 关键字局部补全 (^N^P)" diff --git a/src/po/zh_CN.cp936.po b/src/po/zh_CN.cp936.po index ef3dfa8b29..1498778102 100644 --- a/src/po/zh_CN.cp936.po +++ b/src/po/zh_CN.cp936.po @@ -1291,8 +1291,8 @@ msgstr " msgid " Omni completion (^O^N^P)" msgstr " ȫܲȫ (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ƴд (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ƴд (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ؼ־ֲȫ (^N^P)" diff --git a/src/po/zh_CN.po b/src/po/zh_CN.po index 4e34616b86..a003c1455f 100644 --- a/src/po/zh_CN.po +++ b/src/po/zh_CN.po @@ -1291,8 +1291,8 @@ msgstr " msgid " Omni completion (^O^N^P)" msgstr " ȫܲȫ (^O^N^P)" -msgid " Spelling suggestion (s^N^P)" -msgstr " ƴд (s^N^P)" +msgid " Spelling suggestion (^S^N^P)" +msgstr " ƴд (^S^N^P)" msgid " Keyword Local completion (^N^P)" msgstr " ؼ־ֲȫ (^N^P)" diff --git a/src/popupmenu.c b/src/popupmenu.c index 741980660f..c116b102af 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 @@ -416,6 +420,119 @@ pum_under_menu(int row, int col, int only_redrawing) && col < pum_col + pum_width + pum_scrollbar; } +/* + * 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". */ @@ -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; @@ -1192,9 +1332,10 @@ pum_set_event_info(dict_T *dict) static void pum_position_at_mouse(int min_width) { - if (Rows - mouse_row > pum_size) + if (Rows - mouse_row > pum_size || Rows - mouse_row > mouse_row) { - // Enough space below the mouse row. + // Enough space below the mouse row, + // or there is more space below the mouse row than above. pum_row = mouse_row + 1; if (pum_height > Rows - pum_row) pum_height = Rows - pum_row; @@ -1211,16 +1352,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 +1603,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; @@ -1472,7 +1634,7 @@ pum_select_mouse_pos(void) { int idx = mouse_row - pum_row; - if (idx < 0 || idx >= pum_size) + if (idx < 0 || idx >= pum_height) pum_selected = -1; else if (*pum_array[idx].pum_text != NUL) pum_selected = idx; @@ -1554,6 +1716,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 +1814,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 25bb15349e..0ff57fb4b1 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; } @@ -699,8 +699,8 @@ popup_highlight_curline(win_T *wp) if (syn_name2id((char_u *)linehl) == 0) linehl = "PmenuSel"; - sign_define_by_name(sign_name, NULL, (char_u *)linehl, - NULL, NULL, NULL, NULL); + sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL, + NULL, SIGN_DEF_PRIO); } sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name, @@ -2651,6 +2651,8 @@ f_popup_filter_yesno(typval_T *argvars, typval_T *rettv) return; c = *key; + if (c == CAR && need_wait_return) + return; if (c == K_SPECIAL && key[1] != NUL) c = TO_SPECIAL(key[1], key[2]); @@ -2844,6 +2846,54 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED) popup_adjust_position(wp); } +/* + * popup_setbuf({id}, {bufnr}) + */ + void +f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED) +{ + int id; + win_T *wp; + buf_T *buf; + + rettv->v_type = VAR_BOOL; + rettv->vval.v_number = VVAL_FALSE; + + if (check_for_number_arg(argvars, 0) == FAIL + || check_for_buffer_arg(argvars, 1) == FAIL) + return; + + id = (int)tv_get_number(&argvars[0]); + wp = find_popup_win(id); + if (wp == NULL) + return; + + buf = tv_get_buf_from_arg(&argvars[1]); + + if (buf == NULL) + return; +#ifdef FEAT_TERMINAL + if (buf->b_term != NULL && popup_terminal_exists()) + { + emsg(_(e_cannot_open_second_popup_with_terminal)); + return; + } +#endif + + if (wp->w_buffer != buf) + { + wp->w_buffer->b_nwindows--; + win_init_popup_win(wp, buf); + set_local_options_default(wp, FALSE); + swap_exists_action = SEA_READONLY; + buffer_ensure_loaded(buf); + swap_exists_action = SEA_NONE; + redraw_win_later(wp, UPD_NOT_VALID); + popup_adjust_position(wp); + } + rettv->vval.v_number = VVAL_TRUE; +} + static void popup_free(win_T *wp) { diff --git a/src/proto.h b/src/proto.h index b5f217d746..07fe07b6ed 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/autocmd.pro b/src/proto/autocmd.pro index 4a502da625..920987a8c7 100644 --- a/src/proto/autocmd.pro +++ b/src/proto/autocmd.pro @@ -26,6 +26,7 @@ int has_textchanged(void); int has_textchangedI(void); int has_textchangedP(void); int has_insertcharpre(void); +int has_keyinputpre(void); int has_cmdundefined(void); int has_textyankpost(void); int has_completechanged(void); diff --git a/src/proto/cmdexpand.pro b/src/proto/cmdexpand.pro index 100c23d66a..dfa6d1b96b 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 9c9e56c075..5bf4b8da44 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 fdccca5737..b1ceeccd4c 100644 --- a/src/proto/dict.pro +++ b/src/proto/dict.pro @@ -37,9 +37,10 @@ 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); +int dict_equal(dict_T *d1, dict_T *d2, int ic); long dict_count(dict_T *d, typval_T *needle, int ic); void dict_extend_func(typval_T *argvars, type_T *type, char *func_name, char_u *arg_errmsg, int is_new, typval_T *rettv); void dict_filter_map(dict_T *d, filtermap_T filtermap, type_T *argtype, char *func_name, char_u *arg_errmsg, typval_T *expr, typval_T *rettv); diff --git a/src/proto/eval.pro b/src/proto/eval.pro index 1c2d05dff7..7247265aa1 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/evalvars.pro b/src/proto/evalvars.pro index ea14fe5cef..a0e0100016 100644 --- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -63,6 +63,7 @@ int eval_variable(char_u *name, int len, scid_T sid, typval_T *rettv, dictitem_T int eval_variable_import(char_u *name, typval_T *rettv); void check_vars(char_u *name, int len); dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload); +dictitem_T *find_var_autoload_prefix(char_u *name, int sid, hashtab_T **htp, char_u **namep); dictitem_T *find_var_also_in_script(char_u *name, hashtab_T **htp, int no_autoload); dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload); hashtab_T *get_script_local_ht(void); diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro index 768d87abe8..2b86b1a7e5 100644 --- a/src/proto/ex_docmd.pro +++ b/src/proto/ex_docmd.pro @@ -67,8 +67,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 3f7b30d448..8d978709fc 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 fd8de80379..46f51cb36f 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/findfile.pro b/src/proto/findfile.pro index 95601011ac..1c28221576 100644 --- a/src/proto/findfile.pro +++ b/src/proto/findfile.pro @@ -12,7 +12,7 @@ char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum); char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum); char_u *find_file_name_in_path(char_u *ptr, int len, int options, long count, char_u *rel_fname); int vim_ispathlistsep(int c); -void uniquefy_paths(garray_T *gap, char_u *pattern); +void uniquefy_paths(garray_T *gap, char_u *pattern, char_u *path_option); int expand_in_path(garray_T *gap, char_u *pattern, int flags); void simplify_filename(char_u *filename); void f_simplify(typval_T *argvars, typval_T *rettv); diff --git a/src/proto/gc.pro b/src/proto/gc.pro new file mode 100644 index 0000000000..e13dbda31c --- /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 bafcefc677..6e56a0e370 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 51f5db0f8f..dbd5ef7efa 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 0b58c692a4..27bea5e878 100644 --- a/src/proto/list.pro +++ b/src/proto/list.pro @@ -16,7 +16,7 @@ listitem_T *listitem_alloc(void); void listitem_free(list_T *l, listitem_T *item); void listitem_remove(list_T *l, listitem_T *item); long list_len(list_T *l); -int list_equal(list_T *l1, list_T *l2, int ic, int recursive); +int list_equal(list_T *l1, list_T *l2, int ic); listitem_T *list_find(list_T *l, long n); long list_find_nr(list_T *l, long idx, int *errorp); char_u *list_find_str(list_T *l, long idx); @@ -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/mark.pro b/src/proto/mark.pro index cc45f0d3c3..d398c3677c 100644 --- a/src/proto/mark.pro +++ b/src/proto/mark.pro @@ -28,4 +28,5 @@ void set_last_cursor(win_T *win); void free_all_marks(void); xfmark_T *get_namedfm(void); void f_getmarklist(typval_T *argvars, typval_T *rettv); +void mark_forget_file(win_T *wp, int fnum); /* vim: set ft=c : */ diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro index 7883b3b4c7..c57c94c8ae 100644 --- a/src/proto/mbyte.pro +++ b/src/proto/mbyte.pro @@ -85,6 +85,7 @@ int convert_input(char_u *ptr, int len, int maxlen); int convert_input_safe(char_u *ptr, int len, int maxlen, char_u **restp, int *restlenp); char_u *string_convert(vimconv_T *vcp, char_u *ptr, int *lenp); char_u *string_convert_ext(vimconv_T *vcp, char_u *ptr, int *lenp, int *unconvlenp); +int get_cellwidth(int c); void f_setcellwidths(typval_T *argvars, typval_T *rettv); void f_getcellwidths(typval_T *argvars, typval_T *rettv); void f_charclass(typval_T *argvars, typval_T *rettv); diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro index e76bf75d0f..d64f961f01 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 6dcbe414fc..36a26ec480 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 e736639c90..6d03886c44 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -69,6 +69,7 @@ char *did_set_showtabline(optset_T *args); char *did_set_smoothscroll(optset_T *args); char *did_set_spell(optset_T *args); char *did_set_swapfile(optset_T *args); +char *did_set_tabclose(optset_T *args); char *did_set_termguicolors(optset_T *args); char *did_set_terse(optset_T *args); char *did_set_textauto(optset_T *args); @@ -149,7 +150,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/optionstr.pro b/src/proto/optionstr.pro index b25e497740..f5f0a745ef 100644 --- a/src/proto/optionstr.pro +++ b/src/proto/optionstr.pro @@ -156,6 +156,7 @@ char *did_set_swapsync(optset_T *args); int expand_set_swapsync(optexpand_T *args, int *numMatches, char_u ***matches); char *did_set_switchbuf(optset_T *args); int expand_set_switchbuf(optexpand_T *args, int *numMatches, char_u ***matches); +int expand_set_tabclose(optexpand_T *args, int *numMatches, char_u ***matches); char *did_set_tabline(optset_T *args); char *did_set_tagcase(optset_T *args); int expand_set_tagcase(optexpand_T *args, int *numMatches, char_u ***matches); diff --git a/src/proto/os_mswin.pro b/src/proto/os_mswin.pro index 47310104b8..cde9ceaeed 100644 --- a/src/proto/os_mswin.pro +++ b/src/proto/os_mswin.pro @@ -11,6 +11,7 @@ int mch_isFullName(char_u *fname); void slash_adjust(char_u *p); char_u *resolve_appexeclink(char_u *fname); int vim_stat(const char *name, stat_T *stp); +int vim_lstat(const char *name, stat_T *stp); void mch_settmode(tmode_T tmode); int mch_get_shellsize(void); void mch_set_shellsize(void); @@ -22,6 +23,7 @@ int mch_has_wildcard(char_u *p); int mch_chdir(char *path); int mch_icon_load(HANDLE *iconp); int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result); +int mch_get_random(char_u *buf, int len); void DumpPutS(const char *psz); int mch_get_winpos(int *x, int *y); void mch_set_winpos(int x, int y); diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro index 6e13de6caa..d9dc8d9d54 100644 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -76,6 +76,7 @@ int mch_rename(const char *src, const char *dest); int gpm_available(void); int gpm_enabled(void); int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result); +int mch_get_random(char_u *buf, int len); void setup_term_clip(void); void start_xterm_trace(int button); void stop_xterm_trace(void); diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro index 1ff995085a..11679c68ee 100644 --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -34,6 +34,7 @@ void f_popup_hide(typval_T *argvars, typval_T *rettv); void popup_show(win_T *wp); void f_popup_show(typval_T *argvars, typval_T *rettv); void f_popup_settext(typval_T *argvars, typval_T *rettv); +void f_popup_setbuf(typval_T *argvars, typval_T *rettv); int error_if_popup_window(int also_with_term); int popup_close(int id, int force); int popup_close_tabpage(tabpage_T *tp, int id, int force); diff --git a/src/proto/search.pro b/src/proto/search.pro index 5b2b889317..866599409c 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,8 @@ 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); +int search_for_fuzzy_match(buf_T *buf, pos_T *pos, char_u *pattern, int dir, pos_T *start_pos, int *len, char_u **ptr, int whole_line); void fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count); int fuzzymatches_to_strmatches(fuzmatch_str_T *fuzmatch, char_u ***matches, int count, int funcsort); /* vim: set ft=c : */ diff --git a/src/proto/sign.pro b/src/proto/sign.pro index a042bad7f1..1cca0a6963 100644 --- a/src/proto/sign.pro +++ b/src/proto/sign.pro @@ -8,7 +8,7 @@ int buf_findsigntype_id(buf_T *buf, linenr_T lnum, int typenr); int buf_signcount(buf_T *buf, linenr_T lnum); void buf_delete_signs(buf_T *buf, char_u *group); void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); -int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl); +int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl, int prio); int sign_exists_by_name(char_u *name); int sign_undefine_by_name(char_u *name, int give_error); int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio); diff --git a/src/proto/spell.pro b/src/proto/spell.pro index 98a1353493..680bf34f4f 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/tag.pro b/src/proto/tag.pro index 6de463e92c..eec7c24ed4 100644 --- a/src/proto/tag.pro +++ b/src/proto/tag.pro @@ -14,4 +14,5 @@ int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file); int get_tags(list_T *list, char_u *pat, char_u *buf_fname); void get_tagstack(win_T *wp, dict_T *retdict); int set_tagstack(win_T *wp, dict_T *d, int action); +void tagstack_clear_entry(taggy_T *item); /* vim: set ft=c : */ diff --git a/src/proto/typval.pro b/src/proto/typval.pro index b6ea1310fd..1edfeb4c18 100644 --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -68,14 +68,13 @@ int typval_compare(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic); int typval_compare_list(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_null(typval_T *tv1, typval_T *tv2); int typval_compare_blob(typval_T *tv1, typval_T *tv2, exprtype_T type, int *res); -int typval_compare_class(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_object(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_dict(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_func(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); int typval_compare_string(typval_T *tv1, typval_T *tv2, exprtype_T type, int ic, int *res); char_u *typval_tostring(typval_T *arg, int quotes); int tv_islocked(typval_T *tv); -int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive); +int tv_equal(typval_T *tv1, typval_T *tv2, int ic); int eval_option(char_u **arg, typval_T *rettv, int evaluate); int eval_number(char_u **arg, typval_T *rettv, int evaluate, int want_string); int eval_string(char_u **arg, typval_T *rettv, int evaluate, int interpolate); diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro index 9bb461663e..ce5d257caf 100644 --- a/src/proto/userfunc.pro +++ b/src/proto/userfunc.pro @@ -95,4 +95,5 @@ int set_ref_in_call_stack(int copyID); int set_ref_in_functions(int copyID); int set_ref_in_func_args(int copyID); int set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID); +int get_func_arity(char_u *name, int *required, int *optional, int *varargs); /* vim: set ft=c : */ diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro index d3d3b99be3..c87fffbc8a 100644 --- a/src/proto/vim9class.pro +++ b/src/proto/vim9class.pro @@ -40,7 +40,8 @@ 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); +int object_equal(object_T *o1, object_T *o2, int ic); +char_u *object2string(object_T *obj, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int composite_val); int class_instance_of(class_T *cl, class_T *other_cl); void f_instanceof(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/quickfix.c b/src/quickfix.c index 2e5b693733..414fe650d7 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 4373ae0cfa..ff201d9ffe 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,31 +1944,33 @@ 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 /* @@ -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 @@ vim_regsub_both( } #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 5d9450d871..5452dda0f6 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 5e4fadd028..4f07a21d5d 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/screen.c b/src/screen.c index 83a740bc13..70010a1e45 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1993,7 +1993,21 @@ screen_char(unsigned off, int row, int col) { char_u buf[MB_MAXBYTES + 1]; - if (utf_ambiguous_width(ScreenLinesUC[off]) + if ( +#ifdef FEAT_GUI + !gui.in_use && +#endif + get_cellwidth(ScreenLinesUC[off]) > 1 + ) + { + // If the width is set to 2 with setcellwidths() + // clear the two screen cells. If the character is actually + // single width it won't change the second cell. + out_str((char_u *)" "); + term_windgoto(row, col); + screen_cur_col = 9999; + } + else if (utf_ambiguous_width(ScreenLinesUC[off]) # ifdef FEAT_GUI_MACVIM /* In the GUI, check if the cell width is actually 1 in order * to display 2-cells emoji correctly. */ diff --git a/src/scriptfile.c b/src/scriptfile.c index cc76260410..711f576c09 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; } @@ -1273,7 +1278,7 @@ cmd_source(char_u *fname, exarg_T *eap) emsg(_(e_argument_required)); else // source ex commands from the current buffer - do_source_ext(NULL, FALSE, FALSE, NULL, eap, clearvars); + do_source_ext(NULL, FALSE, DOSO_NONE, NULL, eap, clearvars); } else if (eap != NULL && eap->forceit) // ":source!": read Normal mode commands @@ -1424,14 +1429,17 @@ do_source_buffer_init(source_cookie_T *sp, exarg_T *eap) char_u *line = NULL; char_u *fname; - CLEAR_FIELD(*sp); - if (curbuf == NULL) return NULL; // Use ":source buffer=<num>" as the script name - vim_snprintf((char *)IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum); - fname = vim_strsave(IObuff); + if (curbuf->b_ffname != NULL) + fname = vim_strsave(curbuf->b_ffname); + else + { + vim_snprintf((char *)IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum); + fname = vim_strsave(IObuff); + } if (fname == NULL) return NULL; @@ -1448,6 +1456,8 @@ do_source_buffer_init(source_cookie_T *sp, exarg_T *eap) } sp->buf_lnum = 0; sp->source_from_buf = TRUE; + // When sourcing a range of lines from a buffer, use buffer line number. + sp->sourcing_lnum = eap->line1 - 1; return fname; @@ -1636,13 +1646,6 @@ do_source_ext( cookie.fileformat = EOL_UNKNOWN; #endif - if (fname == NULL) - // When sourcing a range of lines from a buffer, use the buffer line - // number. - cookie.sourcing_lnum = eap->line1 - 1; - else - cookie.sourcing_lnum = 0; - #ifdef FEAT_EVAL // Check if this script has a breakpoint. cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0); diff --git a/src/search.c b/src/search.c index c4fc87ee1c..a02faaf618 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,28 @@ 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); +static int fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos); #define SEARCH_STAT_DEF_TIMEOUT 40L #define SEARCH_STAT_DEF_MAX_COUNT 99 @@ -69,8 +89,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 +102,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 +112,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 +145,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 +153,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 +162,8 @@ search_regcomp( */ if (pat == NULL || *pat == NUL) { + int i; + if (pat_use == RE_LAST) i = last_idx; else @@ -154,11 +178,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 +194,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 +209,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,7 +233,7 @@ 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; @@ -215,7 +244,11 @@ save_re_pat(int idx, char_u *pat, int magic) #endif 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; @@ -236,19 +269,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; @@ -258,18 +303,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); @@ -280,9 +329,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 @@ -313,7 +368,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; } @@ -333,6 +394,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 @@ -523,7 +585,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 = '/'; @@ -542,7 +609,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 @@ -570,7 +641,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 @@ -604,6 +675,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 @@ -633,8 +705,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) @@ -642,6 +715,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; @@ -788,7 +863,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) { @@ -900,7 +975,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; @@ -1183,12 +1258,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; @@ -1196,10 +1273,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. */ @@ -1277,24 +1357,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; } } @@ -1309,13 +1393,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; } @@ -1354,16 +1442,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(); @@ -1372,24 +1463,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) { @@ -1399,45 +1494,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) + { + msgbuflen = 0; + } + else { - vim_memset(msgbuf, ' ', len); - msgbuf[len - 1] = NUL; + 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 @@ -1458,7 +1561,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) @@ -1476,7 +1579,10 @@ do_search( out_flush(); msg_nowait = TRUE; // don't wait for this message } - } + + if (!shortmess(SHM_SEARCHCOUNT)) + show_search_stats = TRUE; + } // msgbuf != NULL } /* @@ -1517,7 +1623,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))), @@ -1584,14 +1690,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) @@ -1622,6 +1723,7 @@ do_search( goto end_do_search; } ++pat; + --patlen; } if (options & SEARCH_MARK) @@ -2835,7 +2937,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; @@ -2845,9 +2947,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; @@ -2865,7 +2970,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 @@ -2935,8 +3040,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 @@ -2967,7 +3072,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; @@ -3071,6 +3176,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) @@ -3089,34 +3195,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); @@ -3125,10 +3230,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; @@ -3224,7 +3328,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 @@ -3352,7 +3456,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); @@ -3371,8 +3475,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; @@ -3889,7 +3992,7 @@ find_pattern_in_path( && action == ACTION_EXPAND && !compl_status_sol() && *startp != NUL - && *(p = startp + mb_ptr2len(startp)) != NUL) + && *(startp + mb_ptr2len(startp)) != NUL) goto search_line; } line_breakcheck(); @@ -3992,6 +4095,7 @@ show_pat_in_path( long count) { char_u *p; + size_t linelen; if (did_show) msg_putchar('\n'); // cursor below last one @@ -3999,9 +4103,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 @@ -4031,6 +4136,7 @@ show_pat_in_path( { if (vim_fgets(line, LSIZE, fp)) // end of file break; + linelen = STRLEN(line); ++*lnum; } else @@ -4038,6 +4144,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'); } @@ -4165,7 +4272,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 @@ -4998,6 +5108,220 @@ fuzzy_match_str(char_u *str, char_u *pat) return score; } +/* + * 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 +} + +/* + * This function searches for a fuzzy match of the pattern `pat` within the + * line pointed to by `*ptr`. It splits the line into words, performs fuzzy + * matching on each word, and returns the length and position of the first + * matched word. + */ + static int +fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos) +{ + char_u *str = *ptr; + char_u *strBegin = str; + char_u *end = NULL; + char_u *start = NULL; + int found = FALSE; + int result; + char save_end; + + if (str == NULL || pat == NULL) + return found; + + while (*str != NUL) + { + // Skip non-word characters + start = find_word_start(str); + if (*start == NUL) + break; + end = find_word_end(start); + + // Extract the word from start to end + save_end = *end; + *end = NUL; + + // Perform fuzzy match + result = fuzzy_match_str(start, pat); + *end = save_end; + + if (result > 0) + { + *len = (int)(end - start); + current_pos->col += (int)(end - strBegin); + found = TRUE; + *ptr = start; + break; + } + + // Move to the end of the current word for the next iteration + str = end; + // Ensure we continue searching after the current word + while (*str != NUL && !vim_iswordp(str)) + MB_PTR_ADV(str); + } + + return found; +} + +/* + * Search for the next fuzzy match in the specified buffer. + * This function attempts to find the next occurrence of the given pattern + * in the buffer, starting from the current position. It handles line wrapping + * and direction of search. + * + * Return TRUE if a match is found, otherwise FALSE. + */ + int +search_for_fuzzy_match( + buf_T *buf, + pos_T *pos, + char_u *pattern, + int dir, + pos_T *start_pos, + int *len, + char_u **ptr, + int whole_line) +{ + pos_T current_pos = *pos; + pos_T circly_end; + int found_new_match = FAIL; + int looped_around = FALSE; + + if (whole_line) + current_pos.lnum += dir; + + if (buf == curbuf) + circly_end = *start_pos; + else + { + circly_end.lnum = buf->b_ml.ml_line_count; + circly_end.col = 0; + circly_end.coladd = 0; + } + + do { + + // Check if looped around and back to start position + if (looped_around && EQUAL_POS(current_pos, circly_end)) + break; + + // Ensure current_pos is valid + if (current_pos.lnum >= 1 && current_pos.lnum <= buf->b_ml.ml_line_count) + { + // Get the current line buffer + *ptr = ml_get_buf(buf, current_pos.lnum, FALSE); + // If ptr is end of line is reached, move to next line + // or previous line based on direction + if (**ptr != NUL) + { + if (!whole_line) + { + *ptr += current_pos.col; + // Try to find a fuzzy match in the current line starting from current position + found_new_match = fuzzy_match_str_in_line(ptr, pattern, len, &current_pos); + if (found_new_match) + { + *pos = current_pos; + break; + } + else if (looped_around && current_pos.lnum == circly_end.lnum) + break; + } + else + { + if (fuzzy_match_str(*ptr, pattern) > 0) + { + found_new_match = TRUE; + *pos = current_pos; + *len = STRLEN(*ptr); + break; + } + } + } + } + + // Move to the next line or previous line based on direction + if (dir == FORWARD) + { + if (++current_pos.lnum > buf->b_ml.ml_line_count) + { + if (p_ws) + { + current_pos.lnum = 1; + looped_around = TRUE; + } + else + break; + } + } + else + { + if (--current_pos.lnum < 1) + { + if (p_ws) + { + current_pos.lnum = buf->b_ml.ml_line_count; + looped_around = TRUE; + } + else + break; + + } + } + current_pos.col = 0; + } while (TRUE); + + return found_new_match; +} + /* * Free an array of fuzzy string matches "fuzmatch[count]". */ diff --git a/src/sign.c b/src/sign.c index 8aa043bc45..b1f496c388 100644 --- a/src/sign.c +++ b/src/sign.c @@ -34,6 +34,7 @@ struct sign int sn_text_hl; // highlight ID for text int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set int sn_num_hl; // highlight ID for line number + int sn_priority; // default priority of this sign, -1 means SIGN_DEF_PRIO }; static sign_T *first_sign = NULL; @@ -1047,7 +1048,8 @@ sign_define_by_name( char_u *text, char_u *texthl, char_u *culhl, - char_u *numhl) + char_u *numhl, + int prio) { sign_T *sp_prev; sign_T *sp; @@ -1083,6 +1085,8 @@ sign_define_by_name( if (text != NULL && (sign_define_init_text(sp, text) == FAIL)) return FAIL; + sp->sn_priority = prio; + if (linehl != NULL) { if (*linehl == NUL) @@ -1206,6 +1210,10 @@ sign_place( if (*sign_id == 0) *sign_id = sign_group_get_next_signid(buf, sign_group); + // Use the default priority value for this sign. + if (prio == -1) + prio = (sp->sn_priority != -1) ? sp->sn_priority : SIGN_DEF_PRIO; + if (lnum > 0) // ":sign place {id} line={lnum} name={name} file={fname}": // place a sign @@ -1338,6 +1346,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline) char_u *texthl = NULL; char_u *culhl = NULL; char_u *numhl = NULL; + int prio = -1; int failed = FALSE; // set values for a defined sign. @@ -1377,6 +1386,11 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline) arg += 6; numhl = vim_strnsave(arg, p - arg); } + else if (STRNCMP(arg, "priority=", 9) == 0) + { + arg += 9; + prio = atoi((char *)arg); + } else { semsg(_(e_invalid_argument_str), arg); @@ -1386,7 +1400,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline) } if (!failed) - sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl); + sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl, prio); vim_free(icon); vim_free(text); @@ -1721,7 +1735,7 @@ ex_sign(exarg_T *eap) linenr_T lnum = -1; char_u *sign_name = NULL; char_u *group = NULL; - int prio = SIGN_DEF_PRIO; + int prio = -1; // Parse command line arguments if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio, @@ -1750,6 +1764,8 @@ sign_getinfo(sign_T *sp, dict_T *retdict) dict_add_string(retdict, "icon", sp->sn_icon); if (sp->sn_text != NULL) dict_add_string(retdict, "text", sp->sn_text); + if (sp->sn_priority > 0) + dict_add_number(retdict, "priority", sp->sn_priority); if (sp->sn_line_hl > 0) { p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); @@ -1913,6 +1929,7 @@ sign_gui_started(void) sign_list_defined(sign_T *sp) { char_u *p; + char lbuf[MSG_BUF_LEN]; smsg("sign %s", sp->sn_name); if (sp->sn_icon != NULL) @@ -1931,6 +1948,11 @@ sign_list_defined(sign_T *sp) msg_puts(" text="); msg_outtrans(sp->sn_text); } + if (sp->sn_priority > 0) + { + vim_snprintf(lbuf, MSG_BUF_LEN, " priority=%d", sp->sn_priority); + msg_puts(lbuf); + } if (sp->sn_line_hl > 0) { msg_puts(" linehl="); @@ -2088,7 +2110,8 @@ get_sign_name(expand_T *xp UNUSED, int idx) { char *define_arg[] = { - "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", NULL + "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", "priority=", + NULL }; return (char_u *)define_arg[idx]; } @@ -2261,6 +2284,7 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict) char_u *texthl = NULL; char_u *culhl = NULL; char_u *numhl = NULL; + int prio = -1; int retval = -1; if (name_arg == NULL) @@ -2281,9 +2305,10 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict) texthl = dict_get_string(dict, "texthl", TRUE); culhl = dict_get_string(dict, "culhl", TRUE); numhl = dict_get_string(dict, "numhl", TRUE); + prio = dict_get_number_def(dict, "priority", -1); } - if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl) == OK) + if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl, prio) == OK) retval = 0; cleanup: @@ -2511,7 +2536,7 @@ sign_place_from_dict( buf_T *buf = NULL; dictitem_T *di; linenr_T lnum = 0; - int prio = SIGN_DEF_PRIO; + int prio = -1; int notanum = FALSE; int ret_sign_id = -1; diff --git a/src/spell.c b/src/spell.c index 43c521dde6..909d426e20 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/spellfile.c b/src/spellfile.c index 51261abfb5..0b9536dc16 100644 --- a/src/spellfile.c +++ b/src/spellfile.c @@ -6434,7 +6434,13 @@ init_spellfile(void) l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell"); if (filewritable(buf) != 2) - vim_mkdir(buf, 0755); + { + if (vim_mkdir(buf, 0755) != 0) + { + vim_free(buf); + return; + } + } l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, diff --git a/src/spellsuggest.c b/src/spellsuggest.c index c6e61832da..b305bfb83e 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 33de175f29..6b2ff0a011 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 3635f185cd..fe7d3add70 100644 --- a/src/structs.h +++ b/src/structs.h @@ -3225,6 +3225,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' @@ -4487,6 +4489,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; /* @@ -4814,6 +4818,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; @@ -4916,7 +4921,8 @@ typedef enum { WT_MEMBER, WT_METHOD, // object method WT_METHOD_ARG, // object method argument type - WT_METHOD_RETURN // object method return type + WT_METHOD_RETURN, // object method return type + WT_CAST, // type cast } wherekind_T; // Struct used to pass the location of a type check. Used in error messages to diff --git a/src/syntax.c b/src/syntax.c index 48e7152011..02120529f3 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -4084,8 +4084,8 @@ syn_list_cluster(int id) if (msg_col >= endcol) // output at least one space endcol = msg_col + 1; - if (Columns <= endcol) // avoid hang for tiny window - endcol = Columns - 1; + if (Columns <= (long)endcol) // avoid hang for tiny window + endcol = (int)(Columns - 1); msg_advance(endcol); if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL) diff --git a/src/tag.c b/src/tag.c index 9117d0fd27..f94d3eb9d4 100644 --- a/src/tag.c +++ b/src/tag.c @@ -144,7 +144,6 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_ #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) static int add_llist_tags(char_u *tag, int num_matches, char_u **matches); #endif -static void tagstack_clear_entry(taggy_T *item); static char_u *tagmatchname = NULL; // name of last used tag @@ -311,7 +310,7 @@ do_tag( #endif if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit)) - return FALSE; + return FALSE; if (type == DT_HELP) { @@ -3413,6 +3412,11 @@ get_tagfname( // move the filename one char forward and truncate the // filepath with a NUL filename = gettail(buf); + if (r_ptr != NULL) + { + STRMOVE(r_ptr + 1, r_ptr); + ++r_ptr; + } STRMOVE(filename + 1, filename); *filename++ = NUL; @@ -3709,7 +3713,7 @@ jumpto_tag( char_u *lbuf; if (postponed_split == 0 && !check_can_set_curbuf_forceit(forceit)) - return FAIL; + return FAIL; // Make a copy of the line, it can become invalid when an autocommand calls // back here recursively. @@ -3901,6 +3905,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 +3920,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 +3932,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 +3942,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; } @@ -4231,7 +4237,7 @@ find_extra(char_u **pp) /* * Free a single entry in a tag stack */ - static void + void tagstack_clear_entry(taggy_T *item) { VIM_CLEAR(item->tagname); diff --git a/src/terminal.c b/src/terminal.c index 22e5a13fc2..a654995e3c 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 @@ -6169,8 +6176,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 f5baa56457..2f8676a5de 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -20,7 +20,8 @@ SCRIPTS_TINY = \ test24 \ test25 \ test26 \ - test27 + test27 \ + test28 SCRIPTS_TINY_OUT = \ test10.out \ @@ -31,7 +32,8 @@ SCRIPTS_TINY_OUT = \ test24.out \ test25.out \ test26.out \ - test27.out + test27.out \ + test28.out # Tests for Vim9 script. TEST_VIM9 = \ @@ -143,6 +145,7 @@ NEW_TESTS = \ test_file_perm \ test_file_size \ test_filechanged \ + test_filecopy \ test_fileformat \ test_filetype \ test_filter_cmd \ @@ -160,6 +163,10 @@ NEW_TESTS = \ test_function_lists \ test_ga \ test_getcwd \ + test_gettext \ + test_gettext_cp1251 \ + test_gettext_utf8 \ + test_gettext_make \ test_getvar \ test_gf \ test_glob2regpat \ @@ -279,6 +286,7 @@ NEW_TESTS = \ test_spell \ test_spell_utf8 \ test_spellfile \ + test_spellrare \ test_startup \ test_startup_utf8 \ test_stat \ @@ -308,6 +316,7 @@ NEW_TESTS = \ test_textobjects \ test_textprop \ test_timers \ + test_tohtml \ test_true_false \ test_trycatch \ test_undo \ @@ -404,6 +413,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 \ @@ -418,6 +428,10 @@ NEW_TESTS_RES = \ test_functions.res \ test_function_lists.res \ test_getcwd.res \ + test_gettext.res \ + test_gettext_cp1251.res \ + test_gettext_utf8.res \ + test_gettext_make.res \ test_getvar.res \ test_gf.res \ test_gn.res \ @@ -523,6 +537,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 \ @@ -548,6 +563,7 @@ NEW_TESTS_RES = \ test_textobjects.res \ test_textprop.res \ test_timers.res \ + test_tohtml.res \ test_true_false.res \ test_trycatch.res \ test_undo.res \ diff --git a/src/testdir/Make_mvc.mak b/src/testdir/Make_mvc.mak index 318cd4a16c..1bf9eae254 100644 --- a/src/testdir/Make_mvc.mak +++ b/src/testdir/Make_mvc.mak @@ -5,9 +5,9 @@ # Testing may be done with a debug build !IF EXIST(..\\vimd.exe) && !EXIST(..\\vim.exe) -VIMPROG = ..\\vimd +VIMPROG = ..\\vimd.exe !ELSE -VIMPROG = ..\\vim +VIMPROG = ..\\vim.exe !ENDIF @@ -42,7 +42,7 @@ report: else ( echo No failures reported > test_result.log ) $(VIMPROG) -u NONE $(COMMON_ARGS) -S summarize.vim messages -if exist starttime del starttime - @echo. + @echo: @echo Test results: @cmd /c type test_result.log @if exist test.log ( echo TEST FAILURE & exit /b 1 ) \ @@ -56,7 +56,7 @@ $(NEW_TESTS): -if exist test.log del test.log -if exist messages del messages -if exist starttime del starttime - @$(MAKE) -nologo -f Make_mvc.mak $@.res VIMPROG=$(VIMPROG) + @$(MAKE) -nologo -f Make_mvc.mak VIMPROG=$(VIMPROG) $@.res @type messages @if exist test.log exit 1 diff --git a/src/testdir/Makefile b/src/testdir/Makefile index 4e476f9663..7a4c4c484d 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -84,7 +84,7 @@ test_vim9: RM_ON_RUN = test.out X* viminfo RM_ON_START = test.ok benchmark.out -RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in +RUN_VIMPROG = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in # Delete files that may interfere with running tests. This includes some files # that may result from working on the tests, not only from running them. @@ -114,7 +114,7 @@ tinytests: $(SCRIPTS_TINY_OUT) @# 200 msec is sufficient, but only modern sleep supports a fraction of @# a second, fall back to a second if it fails. @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1" - $(RUN_VIM) $*.in $(REDIR_TEST_TO_NULL) + $(RUN_VIMPROG) $*.in $(REDIR_TEST_TO_NULL) @# Check if the test.out file matches test.ok. @/bin/sh -c "if test -f test.out; then \ diff --git a/src/testdir/dumps/Test_balloon_eval_term_03.dump b/src/testdir/dumps/Test_balloon_eval_term_03.dump new file mode 100644 index 0000000000..ccbe9d06a1 --- /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_breakindent_with_double_width_wrap_1.dump b/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump new file mode 100644 index 0000000000..7b761bc1d2 --- /dev/null +++ b/src/testdir/dumps/Test_breakindent_with_double_width_wrap_1.dump @@ -0,0 +1,6 @@ +| +0&#ffffff0@7|a@40|>+0#4040ff13& +| +0#0000000&@7>口*&@2| +&@35 +|~+0#4040ff13&| @48 +|~| @48 +|~| @48 +| +0#0000000&@31|1|,|4|3|-|5|9| @6|A|l@1| diff --git a/src/testdir/dumps/Test_mouse_popup_position_01.dump b/src/testdir/dumps/Test_mouse_popup_position_01.dump new file mode 100644 index 0000000000..54ba886c99 --- /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 0000000000..7dfab529e5 --- /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 0000000000..b38ccd92e6 --- /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_popup_setbuf_01.dump b/src/testdir/dumps/Test_popup_setbuf_01.dump new file mode 100644 index 0000000000..14359bacfe --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_01.dump @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_popup_setbuf_02.dump b/src/testdir/dumps/Test_popup_setbuf_02.dump new file mode 100644 index 0000000000..5feb98299d --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_02.dump @@ -0,0 +1,10 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t|b|u|f|(|p|,| |'|f|o@1|b|a|r|.|t|x|t|'|)| @21|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_popup_setbuf_03.dump b/src/testdir/dumps/Test_popup_setbuf_03.dump new file mode 100644 index 0000000000..2c49576dce --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_03.dump @@ -0,0 +1,10 @@ +|~+0#4040ff13#ffffff0| @73 +|~| @73 +|~| @73 +|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|E+0#ffffff16#e000002|1|2@1|0|:| |S|t|r|i|n|g| |o|r| |N|u|m|b|e|r| |r|e|q|u|i|r|e|d| |f|o|r| |a|r|g|u|m|e|n|t| |2| +0#0000000#ffffff0@27 +|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35 diff --git a/src/testdir/dumps/Test_popup_setbuf_04.dump b/src/testdir/dumps/Test_popup_setbuf_04.dump new file mode 100644 index 0000000000..937fa7c3c2 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_04.dump @@ -0,0 +1,10 @@ +>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255 +|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 diff --git a/src/testdir/dumps/Test_popup_setbuf_05.dump b/src/testdir/dumps/Test_popup_setbuf_05.dump new file mode 100644 index 0000000000..a13dfe35ee --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_05.dump @@ -0,0 +1,10 @@ +>h+0#e000002#ffffff0|e|l|p|.|t|x|t| +0#0000000&@7|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000000&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @12 +@75 +@24|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @30 +@73|k| +@6|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e| +0#0000001#ffd7ff255|s+0#0000000#ffffff0|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @2 +|l| @73 +|h+3&&|e|l|p|.|t|x|t| |[|H|e|l|p|]|[|R|O|]| @37|1|,|1| @11|T|o|p +| +0&&@74 +|[+1&&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_popup_setbuf_06.dump b/src/testdir/dumps/Test_popup_setbuf_06.dump new file mode 100644 index 0000000000..937fa7c3c2 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_06.dump @@ -0,0 +1,10 @@ +>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255 +|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255 +| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255 diff --git a/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump new file mode 100644 index 0000000000..6022a16368 --- /dev/null +++ b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_2.dump @@ -0,0 +1,3 @@ +|a+0&#ffffff0@39|b+0#e000e06&@8|>+0#4040ff13& +>口*0#0000000&|1+&|2|3|4|5| @42 +@32|1|,|4|1|-|5|1| @6|A|l@1| diff --git a/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump new file mode 100644 index 0000000000..c033399ac0 --- /dev/null +++ b/src/testdir/dumps/Test_prop_inserts_text_before_double_width_wrap_3.dump @@ -0,0 +1,3 @@ +|a+0&#ffffff0@39|b+0#e000e06&@8|>+0#4040ff13& +|+@2>口*0#0000000&|1+&|2|3|4|5| @39 +|:|s|e|t| |s|h|o|w|b|r|e|a|k|=|+@2| @13|1|,|4|1|-|5|4| @6|A|l@1| diff --git a/src/testdir/dumps/Test_pum_highlights_03.dump b/src/testdir/dumps/Test_pum_highlights_03.dump new file mode 100644 index 0000000000..77d87d48f9 --- /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 0000000000..486a59e5a5 --- /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 0000000000..a2ce2cf375 --- /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 0000000000..3eb1524769 --- /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 0000000000..5d51f11dd9 --- /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 0000000000..41314abce5 --- /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 0000000000..77d87d48f9 --- /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 0000000000..3eb1524769 --- /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 0000000000..3616c80b62 --- /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_pum_highlights_10.dump b/src/testdir/dumps/Test_pum_highlights_10.dump new file mode 100644 index 0000000000..790b028b9c --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_10.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0|h|e|l@1|o| |h|e|l|i|o| |h|e|r|o| |h|e|l@1|o> @51 +|~+0#4040ff13&| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|r|o| @10| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|l|i|o| @9| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#e0e0e08|h+0#00e0e07&|e+0#0000001&|l@1|o| @9| +0#4040ff13#ffffff0@41 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@27 diff --git a/src/testdir/dumps/Test_pum_highlights_11.dump b/src/testdir/dumps/Test_pum_highlights_11.dump new file mode 100644 index 0000000000..ef75a89ed3 --- /dev/null +++ b/src/testdir/dumps/Test_pum_highlights_11.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0|h|e|l@1|o| |h|e|l|i|o| |h|e|r|o| |h|e|l|i|o> @51 +|~+0#4040ff13&| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|r|o| @10| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#e0e0e08|h+0#00e0e07&|e+0#0000001&|l|i|o| @9| +0#4040ff13#ffffff0@41 +|~| @15| +0#0000001#ffd7ff255|h+0#0000e05&|e+0#0000001&|l@1|o| @9| +0#4040ff13#ffffff0@41 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |3| +0#0000000&@27 diff --git a/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_1.dump b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_1.dump new file mode 100644 index 0000000000..73f4418126 --- /dev/null +++ b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_1.dump @@ -0,0 +1,6 @@ +>➜+0&#ffffff0@49 +@10| @39 +|➜@49 +@10| @39 +|~+0#4040ff13&| @48 +| +0#0000000&@31|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_2.dump b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_2.dump new file mode 100644 index 0000000000..2b575f6b39 --- /dev/null +++ b/src/testdir/dumps/Test_setcellwidths_with_non_ambiwidth_character_dump_2.dump @@ -0,0 +1,6 @@ +>➜+0&#ffffff0| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| +|➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| +|➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| @30 +|➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| |➜| +|@+0#4040ff13&@2| @46 +| +0#0000000&@31|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_smooth_long_6.dump b/src/testdir/dumps/Test_smooth_long_6.dump index 507aa460da..ba48c2825f 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 225207ff6c..222e0019f5 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 0000000000..6c1d2231fc --- /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 0000000000..9162df0c22 --- /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 0000000000..1a1fcaeae0 --- /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 0000000000..4ed62b65bf --- /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 0000000000..6d7e1578d1 --- /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 0000000000..4f5dcea8b9 --- /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 0000000000..c21c0229a0 --- /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 0000000000..efdec1e651 --- /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 0000000000..200df913cc --- /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 0000000000..54b726f304 --- /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 0000000000..1a4cdd2997 --- /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 0000000000..fcc210690b --- /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_11.dump b/src/testdir/dumps/Test_wildmenu_pum_11.dump index 4697c8a562..a0ffc74241 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_11.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_11.dump @@ -1,10 +1,10 @@ | +0&#ffffff0@74 |~+0#4040ff13&| @73 -|~| @73 |~| @10| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@46 +|~| @10| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@46 |~| @10| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@46 |:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=> @55 diff --git a/src/testdir/dumps/Test_wildmenu_pum_12.dump b/src/testdir/dumps/Test_wildmenu_pum_12.dump index d93631de77..12842c4a5b 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_12.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_12.dump @@ -1,10 +1,10 @@ | +0&#ffffff0@74 |~+0#4040ff13&| @73 -|~| @73 |~| @17| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@39 +|~| @17| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@39 |~| @17| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@39 |:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=> @48 diff --git a/src/testdir/dumps/Test_wildmenu_pum_13.dump b/src/testdir/dumps/Test_wildmenu_pum_13.dump index b2b1424f56..94a8ccc6d7 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_13.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_13.dump @@ -1,10 +1,10 @@ | +0&#ffffff0@74 |~+0#4040ff13&| @73 -|~| @73 |~| @24| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@32 +|~| @24| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@32 |~| @24| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@32 |:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=| |c|u|l|h|l|=> @41 diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_1.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_1.dump new file mode 100644 index 0000000000..077268206d --- /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 0000000000..ec781effa8 --- /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 0000000000..afb792a1db --- /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 0000000000..0be8053226 --- /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 0000000000..7453cb9de2 --- /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 0000000000..8345007951 --- /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 0000000000..55db4ca463 --- /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 def474b571..fe55f0c4f5 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,']], @@ -144,6 +144,7 @@ let test_values = { \ 'splitkeep': [['cursor', 'screen', 'topline'], ['xxx']], \ 'swapsync': [['', 'sync', 'fsync'], ['xxx']], \ 'switchbuf': [['', 'useopen', 'split,newtab'], ['xxx']], + \ 'tabclose': [['', 'left', 'left,uselast'], ['xxx']], \ 'tagcase': [['smart', 'match'], ['', 'xxx', 'smart,match']], \ 'term': [[], []], \ 'termguicolors': [[], []], diff --git a/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo b/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo new file mode 100644 index 0000000000..300eba2137 Binary files /dev/null and b/src/testdir/ru_RU/LC_MESSAGES/__PACKAGE__.mo differ diff --git a/src/testdir/samples/Test_tohtml_basic.c.html b/src/testdir/samples/Test_tohtml_basic.c.html new file mode 100644 index 0000000000..d9467b5086 --- /dev/null +++ b/src/testdir/samples/Test_tohtml_basic.c.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<title>/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic.c.html</title> +<meta name="Generator" content="Vim/9.1"> +<meta name="plugin-version" content="vim9.0_v2"> +<meta name="syntax" content="none"> +<meta name="settings" content="use_css,no_foldcolumn,pre_wrap,prevent_copy=,use_input_for_pc=none"> +<meta name="colorscheme" content="none"> +<style> +<!-- +pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #ffffff; } +body { font-family: monospace; color: #000000; background-color: #ffffff; } +* { font-size: 1em; } +--> +</style> +</head> +<body> +<pre id='vimCodeElement'> +#include &lt;stdio.h&gt; +#include &lt;stdlib.h&gt; + +int isprime(int n) +{ + if (n &lt;= 1) + return 0; + + for (int i = 2; i &lt;= n / 2; i++) + if (n % i == 0) + return 0; + + return 1; +} + +int main(int argc, char *argv[]) +{ + int n = 7; + + printf(&quot;%d is %s prime\n&quot;, n, isprime(n) ? &quot;a&quot; : &quot;not a&quot;); + + return 0; +} +</pre> +</body> +</html> +<!-- vim: set foldmethod=manual : --> diff --git a/src/testdir/samples/Test_tohtml_basic_no_css.c.html b/src/testdir/samples/Test_tohtml_basic_no_css.c.html new file mode 100644 index 0000000000..fcbcf5c1fc --- /dev/null +++ b/src/testdir/samples/Test_tohtml_basic_no_css.c.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title>/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic_no_css.c.html</title> +<meta name="Generator" content="Vim/9.1"> +<meta name="plugin-version" content="vim9.0_v2"> +<meta name="syntax" content="none"> +<meta name="settings" content="no_pre,no_foldcolumn,expand_tabs,prevent_copy=,use_input_for_pc=none"> +<meta name="colorscheme" content="none"> +</head> +<body bgcolor="#ffffff" text="#000000"> +<font face="monospace"> +#include &lt;stdio.h&gt;<br> +#include &lt;stdlib.h&gt;<br> +<br> +int isprime(int n)<br> +{<br> +&nbsp;&nbsp;if (n &lt;= 1)<br> +&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br> +<br> +&nbsp;&nbsp;for (int i = 2; i &lt;= n / 2; i++)<br> +&nbsp;&nbsp;&nbsp;&nbsp;if (n % i == 0)<br> +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br> +<br> +&nbsp;&nbsp;return 1;<br> +}<br> +<br> +int main(int argc, char *argv[])<br> +{<br> +&nbsp;&nbsp;int n = 7;<br> +<br> +&nbsp;&nbsp;printf(&quot;%d is %s prime\n&quot;, n, isprime(n) ? &quot;a&quot; : &quot;not a&quot;);<br> +<br> +&nbsp;&nbsp;return 0;<br> +}<br> +</font> +</body> +</html> +<!-- vim: set foldmethod=manual : --> diff --git a/src/testdir/test28.in b/src/testdir/test28.in new file mode 100644 index 0000000000..3d5289d220 --- /dev/null +++ b/src/testdir/test28.in @@ -0,0 +1,13 @@ +Test for using CTRL-A/CTRL-X in tiny mode + +STARTTEST +/12352 +/12354 +:/^STARTHERE/+,$w! test.out +:qa! +ENDTEST + +STARTHERE +12352 + +12354 diff --git a/src/testdir/test28.ok b/src/testdir/test28.ok new file mode 100644 index 0000000000..085c1331ad --- /dev/null +++ b/src/testdir/test28.ok @@ -0,0 +1,3 @@ +12353 + +12353 diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index f3118bfdde..4e21907f35 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -2096,6 +2096,38 @@ func Test_Cmdline() au! CmdlineEnter au! CmdlineLeave let &shellslash = save_shellslash + + au! CursorMovedC : let g:pos += [getcmdpos()] + let g:pos = [] + call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 5, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\<C-B>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\<C-U>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 5, 4, 5], g:pos) + let g:pos = [] + call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3], g:pos) + let g:pos = [] + call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3, 2], g:pos) + au! CursorMovedC + + " setcmdpos() is no-op inside an autocommand + au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1) + let g:pos = [] + call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt') + call assert_equal([2, 3, 4, 5, 6, 5, 4], g:pos) + au! CursorMovedC + + unlet g:entered + unlet g:left + unlet g:pos endfunc " Test for BufWritePre autocommand that deletes or unloads the buffer. @@ -4024,6 +4056,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'})" @@ -4679,4 +4737,98 @@ func Test_SwapExists_set_other_buf_modified() bwipe! endfunc +func Test_BufEnter_botline() + set hidden + call writefile(range(10), 'Xxx1', 'D') + call writefile(range(20), 'Xxx2', 'D') + edit Xxx1 + edit Xxx2 + au BufEnter Xxx1 call assert_true(line('w$') > 1) + edit Xxx1 + + bwipe! Xxx1 + bwipe! Xxx2 + au! BufEnter Xxx1 + set hidden&vim +endfunc + +func Test_KeyInputPre() + " Consume previous keys + call feedkeys('', 'ntx') + + " KeyInputPre can record input keys. + let s:keys = [] + au KeyInputPre n call add(s:keys, v:char) + + call feedkeys('jkjkjjj', 'ntx') + call assert_equal( + \ ['j', 'k', 'j', 'k', 'j', 'j', 'j'], + \ s:keys) + + unlet s:keys + au! KeyInputPre + + " KeyInputPre can handle multibyte. + let s:keys = [] + au KeyInputPre * call add(s:keys, v:char) + edit Xxx1 + + call feedkeys("iあ\<ESC>", 'ntx') + call assert_equal(['i', "あ", "\<ESC>"], s:keys) + + bwipe! Xxx1 + unlet s:keys + au! KeyInputPre + + " KeyInputPre can change input keys. + au KeyInputPre i if v:char ==# 'a' | let v:char = 'b' | endif + edit Xxx1 + + call feedkeys("iaabb\<ESC>", 'ntx') + call assert_equal(getline('.'), 'bbbb') + + bwipe! Xxx1 + au! KeyInputPre + + " KeyInputPre returns multiple characters. + au KeyInputPre i if v:char ==# 'a' | let v:char = 'cccc' | endif + edit Xxx1 + + call feedkeys("iaabb\<ESC>", 'ntx') + call assert_equal(getline('.'), 'ccbb') + + bwipe! Xxx1 + au! KeyInputPre + + " KeyInputPre can use special keys. + au KeyInputPre i if v:char ==# 'a' | let v:char = "\<Ignore>" | endif + edit Xxx1 + + call feedkeys("iaabb\<ESC>", 'ntx') + call assert_equal(getline('.'), 'bb') + + bwipe! Xxx1 + au! KeyInputPre + + " Test for v:event.typed + au KeyInputPre n call assert_true(v:event.typed) + call feedkeys('j', 'ntx') + + au! KeyInputPre + + au KeyInputPre n call assert_false(v:event.typed) + call feedkeys('j', 'nx') + + au! KeyInputPre + + " Test for v:event.typedchar + nnoremap j k + au KeyInputPre n + \ call assert_equal(v:event.typedchar, 'j') + \ | call assert_equal(v:char, 'k') + call feedkeys('j', 'tx') + + au! KeyInputPre +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_autoload.vim b/src/testdir/test_autoload.vim index 835b81e27e..d0f913660e 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 5e84f9e675..80d5831968 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 cccecb7611..f0e8209063 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) @@ -95,6 +102,18 @@ func Test_blob_assign() END call v9.CheckLegacyAndVim9Failure(lines, 'E979:') + 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 @@ -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_breakindent.vim b/src/testdir/test_breakindent.vim index 96d91c949c..b306c02078 100644 --- a/src/testdir/test_breakindent.vim +++ b/src/testdir/test_breakindent.vim @@ -1165,4 +1165,15 @@ func Test_breakindent_min_with_signcol() call s:close_windows() endfunc +func Test_breakindent_with_double_width_wrap() + 50vnew + setlocal tabstop=8 breakindent nolist + call setline(1, "\t" .. repeat('a', winwidth(0) - 9) .. '口口口') + normal! $g0 + call assert_equal(2, winline()) + call assert_equal(9, wincol()) + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim index de088bd8ef..757ba05784 100644 --- a/src/testdir/test_buffer.vim +++ b/src/testdir/test_buffer.vim @@ -126,6 +126,52 @@ func Test_buflist_browse() %bwipe! endfunc +" Test for :bnext and :bprev when called from help and non-help buffers. +func Test_bnext_bprev_help() + %bwipe! + + e XHelp1 | set bt=help + let b1 = bufnr() + e Xbuf1 + let b2 = bufnr() + + " There's only one buffer of each type. + b XHelp1 + bnext | call assert_equal(b1, bufnr()) + bprev | call assert_equal(b1, bufnr()) + b Xbuf1 + bnext | call assert_equal(b2, bufnr()) + bprev | call assert_equal(b2, bufnr()) + + " Add one more buffer of each type. + e XHelp2 | set bt=help + let b3 = bufnr() + e Xbuf2 + let b4 = bufnr() + + " Help buffer jumps to help buffer. + b XHelp1 + bnext | call assert_equal(b3, bufnr()) + bnext | call assert_equal(b1, bufnr()) + bprev | call assert_equal(b3, bufnr()) + bprev | call assert_equal(b1, bufnr()) + + " Regular buffer jumps to regular buffer. + b Xbuf1 + bnext | call assert_equal(b4, bufnr()) + bnext | call assert_equal(b2, bufnr()) + bprev | call assert_equal(b4, bufnr()) + bprev | call assert_equal(b2, bufnr()) + + " :brewind and :blast are not affected by the buffer type. + b Xbuf2 + brewind | call assert_equal(b1, bufnr()) + b XHelp1 + blast | call assert_equal(b4, bufnr()) + + %bwipe! +endfunc + " Test for :bdelete func Test_bdelete_cmd() %bwipe! diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim index 9fb5958fe6..13a3eba370 100644 --- a/src/testdir/test_cd.vim +++ b/src/testdir/test_cd.vim @@ -200,12 +200,20 @@ endfunc func Test_cd_completion() call mkdir('XComplDir1', 'D') call mkdir('XComplDir2', 'D') + call mkdir('sub/XComplDir3', 'pD') call writefile([], 'XComplFile', 'D') for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir'] call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/', @:) endfor + + set cdpath+=sub + for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir'] + call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/ XComplDir3/', @:) + endfor + set cdpath& endfunc func Test_cd_unknown_dir() diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index ed8f89dd59..f83d673346 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -658,7 +658,8 @@ func Test_getcompletion() unlet g:cmdline_compl_params " For others test if the name is recognized. - let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user'] + let names = ['buffer', 'environment', 'file_in_path', 'dir_in_path', 'mapping', 'tag', + \ 'tag_listfiles', 'user'] if has('cmdline_hist') call add(names, 'history') endif @@ -2741,6 +2742,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() @@ -3563,7 +3613,7 @@ func Test_cmdline_complete_bang_cmd_argument() endfunc func Call_cmd_funcs() - return string([getcmdpos(), getcmdscreenpos(), getcmdcompltype()]) + return [getcmdpos(), getcmdscreenpos(), getcmdcompltype()] endfunc func Test_screenpos_and_completion() @@ -3571,13 +3621,24 @@ func Test_screenpos_and_completion() call assert_equal(0, getcmdscreenpos()) call assert_equal('', getcmdcompltype()) - cnoremap <expr> <F2> string([getcmdpos(), getcmdscreenpos(), getcmdcompltype()]) + cnoremap <expr> <F2> string(Call_cmd_funcs()) call feedkeys(":let a\<F2>\<C-B>\"\<CR>", "xt") call assert_equal("\"let a[6, 7, 'var']", @:) call feedkeys(":quit \<F2>\<C-B>\"\<CR>", "xt") call assert_equal("\"quit [6, 7, '']", @:) call feedkeys(":nosuchcommand \<F2>\<C-B>\"\<CR>", "xt") call assert_equal("\"nosuchcommand [15, 16, '']", @:) + + " Check that getcmdcompltype() doesn't interfere with cmdline completion. + let g:results = [] + cnoremap <F2> <Cmd>let g:results += [[getcmdline()] + Call_cmd_funcs()]<CR> + call feedkeys(":sign un\<Tab>\<F2>\<Tab>\<F2>\<Tab>\<F2>\<C-C>", "xt") + call assert_equal([ + \ ['sign undefine', 14, 15, 'sign'], + \ ['sign unplace', 13, 14, 'sign'], + \ ['sign un', 8, 9, 'sign']], g:results) + + unlet g:results cunmap <F2> endfunc diff --git a/src/testdir/test_cmdmods.vim b/src/testdir/test_cmdmods.vim index 323a78e4a0..66ff6a1fa8 100644 --- a/src/testdir/test_cmdmods.vim +++ b/src/testdir/test_cmdmods.vim @@ -8,10 +8,10 @@ def Test_cmdmods_array() # :hide is both a command and a modifier cmds->extend(['hide']) - # Get the entries of cmdmods[] in ex_docmd.c + # Get the entries of cmdmod_info_tab[] in ex_docmd.c edit ../ex_docmd.c - var top = search('^} cmdmods[') + 1 - var bot = search('^};') - 1 + var top = search('^static cmdmod_info_T cmdmod_info_tab[') + 1 + var bot = search('^};.*\/\/ cmdmod_info_tab') - 1 lines = getline(top, bot) var mods = lines->map((_, v) => substitute(v, '.*"\(\k*\)".*', '\1', '')) diff --git a/src/testdir/test_codestyle.vim b/src/testdir/test_codestyle.vim index a455264de7..83f52ef34c 100644 --- a/src/testdir/test_codestyle.vim +++ b/src/testdir/test_codestyle.vim @@ -28,6 +28,13 @@ def Test_source_files() g:ignoreSwapExists = 'e' exe 'edit ' .. fname + # Some files are generated files and may contain space errors. + if fname =~ 'dlldata.c' + || fname =~ 'if_ole.h' + || fname =~ 'iid_ole.c' + continue + endif + PerformCheck(fname, ' \t', 'space before Tab', '') PerformCheck(fname, '\s$', 'trailing white space', '') @@ -68,7 +75,8 @@ def Test_test_files() && fname !~ 'test_listchars.vim' && fname !~ 'test_visual.vim' cursor(1, 1) - var lnum = search(fname =~ "test_regexp_latin" ? '[^á] \t' : ' \t') + var skip = 'getline(".") =~ "codestyle: ignore"' + var lnum = search(fname =~ "test_regexp_latin" ? '[^á] \t' : ' \t', 'W', 0, 0, skip) ReportError('testdir/' .. fname, lnum, 'space before Tab') endif @@ -155,4 +163,4 @@ def Test_help_files() enddef -" vim: shiftwidth=2 sts=2 expandtab +" vim: shiftwidth=2 sts=2 expandtab nofoldenable diff --git a/src/testdir/test_cpoptions.vim b/src/testdir/test_cpoptions.vim index 6ff8301d63..7bfbcd12a1 100644 --- a/src/testdir/test_cpoptions.vim +++ b/src/testdir/test_cpoptions.vim @@ -19,7 +19,7 @@ func Test_cpo_a() set cpo+=a read XfileCpoA call assert_equal('XfileCpoA', @#) - close! + bw! let &cpo = save_cpo endfunc @@ -39,7 +39,7 @@ func Test_cpo_A() set cpo+=A write XcpoAfile2 call assert_equal('XcpoAfile2', @#) - close! + bw! call delete('XcpoAfile2') let &cpo = save_cpo endfunc @@ -81,7 +81,7 @@ func Test_cpo_B() call assert_equal('abd ', getline(1)) call feedkeys(":imap <buffer> x\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"imap <buffer> x\k', @:) - close! + bw! let &cpo = save_cpo endfunc @@ -96,7 +96,7 @@ func Test_cpo_c() set cpo-=c exe "normal gg/abab\<CR>" call assert_equal(5, searchcount().total) - close! + bw! let &cpo = save_cpo endfunc @@ -143,7 +143,7 @@ func Test_cpo_D() exe "norm! 1gg0f\<c-k>!!" call assert_equal(1, col('.')) set cpo-=D - close! + bw! let &cpo = save_cpo endfunc @@ -183,7 +183,7 @@ func Test_cpo_E() call assert_beeps('exe "normal v\<C-A>"') call assert_beeps('exe "normal v\<C-X>"') set cpo-=E - close! + bw! endfunc " Test for the 'f' flag in 'cpo' (read in an empty buffer sets the file name) @@ -213,7 +213,7 @@ func Test_cpo_F() set cpo+=F write XfileCpoF call assert_equal('XfileCpoF', @%) - close! + bw! call delete('XfileCpoF') let &cpo = save_cpo endfunc @@ -229,7 +229,7 @@ func Test_cpo_g() set cpo+=g edit call assert_equal(1, line('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -245,7 +245,7 @@ func Test_cpo_H() call setline(1, ' ') normal! Ia call assert_equal(' a ', getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -264,7 +264,7 @@ func Test_cpo_I() %d exe "normal i one\<CR>\<Up>" call assert_equal('', getline(2)) - close! + bw! let &cpo = save_cpo endfunc @@ -295,7 +295,7 @@ func Test_cpo_J() normal ( call assert_equal(colnr, col('.')) endfor - close! + bw! let &cpo = save_cpo endfunc @@ -317,7 +317,7 @@ func Test_cpo_l() set cpo+=l exe 'normal gg/[\t]' .. "\<CR>" call assert_equal([4, 10], [col('.'), virtcol('.')]) - close! + bw! let &cpo = save_cpo endfunc @@ -338,7 +338,7 @@ func Test_cpo_L() call setline(1, 'abcdefghijklmnopqr') exe "normal 0gR\<Tab>" call assert_equal("\<Tab>ijklmnopqr", getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -376,7 +376,7 @@ func Test_cpo_M() call cursor(2, 1) call assert_beeps('normal %') - close! + bw! let &cpo = save_cpo endfunc @@ -392,7 +392,7 @@ func Test_cpo_n() set cpo+=n redraw! call assert_equal('aaaa', Screenline(2)) - close! + bw! let &cpo = save_cpo endfunc @@ -409,7 +409,7 @@ func Test_cpo_o() exe "normal /one/+2\<CR>" normal n call assert_equal(5, line('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -424,7 +424,7 @@ func Test_cpo_O() set cpo+=O write call assert_equal(['one'], readfile('XfileCpoO')) - close! + bw! let &cpo = save_cpo endfunc @@ -462,7 +462,7 @@ func Test_cpo_q() set cpo+=q normal gg4J call assert_equal(4, col('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -483,7 +483,7 @@ func Test_cpo_r() let @/ = 'three' normal 2G. call assert_equal('abc three four', getline(2)) - close! + bw! let &cpo = save_cpo endfunc @@ -503,7 +503,7 @@ func Test_cpo_R() 3mark r %!sort call assert_equal(0, line("'r")) - close! + bw! let &cpo = save_cpo endfunc @@ -530,8 +530,8 @@ func Test_cpo_S() wincmd p call assert_equal(0, &autoindent) wincmd t - close! - close! + bw! + bw! let &cpo = save_cpo endfunc @@ -550,7 +550,7 @@ func Test_cpo_u() exe "normal iabc\<C-G>udef\<C-G>ughi" normal uu call assert_equal('abcdefghi', getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -574,7 +574,7 @@ func Test_cpo_w() call assert_equal('hereZZZare some words', getline('.')) norm! 1gg2elcWYYY call assert_equal('hereZZZare someYYYwords', getline('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -611,7 +611,7 @@ func Test_cpo_X() normal ggRy normal 4. call assert_equal('yyyyxxxaaaaa', getline(1)) - close! + bw! let &cpo = save_cpo endfunc @@ -630,7 +630,7 @@ func Test_cpo_y() normal ggyy normal 2G. call assert_equal("two\n", @") - close! + bw! let &cpo = save_cpo endfunc @@ -647,7 +647,7 @@ func Test_cpo_Z() setlocal readonly write! call assert_equal(1, &readonly) - close! + bw! let &cpo = save_cpo endfunc @@ -700,7 +700,7 @@ func Test_cpo_percent() call assert_equal(15, col('.')) normal 22|% call assert_equal(27, col('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -716,7 +716,7 @@ func Test_cpo_minus() call assert_beeps('normal 10k') call assert_equal(3, line('.')) call assert_fails(10, 'E16:') - close! + bw! let &cpo = save_cpo endfunc @@ -732,7 +732,7 @@ func Test_cpo_plus() set cpo+=+ write X2 call assert_equal(0, &modified) - close! + bw! call delete('X1') call delete('X2') let &cpo = save_cpo @@ -749,7 +749,7 @@ func Test_cpo_star() set cpo+=* *a call assert_equal(1, x) - close! + bw! let &cpo = save_cpo endfunc @@ -770,7 +770,7 @@ func Test_cpo_gt() normal gg"Rye normal "Rye call assert_equal("\none\none", @r) - close! + bw! let &cpo = save_cpo endfunc @@ -803,7 +803,7 @@ func Test_cpo_semicolon() call assert_equal('bbb y', getline(4)) call assert_equal('ccc', getline(5)) call assert_equal('ddd yee y', getline(6)) - close! + bw! let &cpo = save_cpo endfunc @@ -828,7 +828,7 @@ func Test_cpo_hash() call assert_equal(['', 'one', 'two', 'three'], getline(1, '$')) normal gg2Ozero call assert_equal(['zero', '', 'one', 'two', 'three'], getline(1, '$')) - close! + bw! let &cpo = save_cpo endfunc @@ -858,7 +858,7 @@ func Test_cpo_backslash() set cpo+=\ exe 'normal gg/[ \-]' .. "\<CR>n" call assert_equal(2, col('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -880,7 +880,7 @@ func Test_cpo_brace() call assert_equal(2, line('.')) normal G{ call assert_equal(2, line('.')) - close! + bw! let &cpo = save_cpo endfunc @@ -908,8 +908,53 @@ func Test_cpo_dot() call delete('Xfoo') set cpo& - close! + bw! let &cpo = save_cpo endfunc +" Test for the 'z' flag in 'cpo' (make cw and dw work similar and avoid +" inconsistencies, see :h cpo-z) +func Test_cpo_z() + let save_cpo = &cpo + new + " Test 1: dw behaves differently from cw + call setline(1, ['foo bar baz', 'one two three']) + call cursor(1, 1) + " dw does not delete the whitespace after the word + norm! wcwanother + set cpo-=z + " dw deletes the whitespace after the word + call cursor(2, 1) + norm! wcwfour + call assert_equal(['foo another baz', 'one fourthree'], getline(1, '$')) + " Test 2: d{motion} becomes linewise :h d-special + %d + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + set cpo+=z + " delete operation becomes linewise + call feedkeys("fbd/e\\zs\<cr>", 'tnx') + call assert_equal(['one ', 'zwei'], getline(1, '$')) + %d + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + call feedkeys("fbd2w", 'tnx') + call assert_equal(['one ', 'zwei'], getline(1, '$')) + + " delete operation does not become line wise + set cpo-=z + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + call feedkeys("fbd/e\\zs\<cr>", 'tnx') + call assert_equal(['one ', ' ', 'zwei'], getline(1, '$')) " codestyle: ignore + %d + call setline(1, ['one ', ' bar', ' e ', 'zwei']) + call cursor(2, 1) + call feedkeys("fbd2w", 'tnx') + call assert_equal(['one ', ' ', 'zwei'], getline(1, '$')) + + " clean up + bw! + let &cpo = save_cpo +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim index 56abee5275..93ae03ba0f 100644 --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -1955,6 +1955,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_ex_mode.vim b/src/testdir/test_ex_mode.vim index 59c28f3836..a1ec15d7e2 100644 --- a/src/testdir/test_ex_mode.vim +++ b/src/testdir/test_ex_mode.vim @@ -68,7 +68,7 @@ func Test_Ex_substitute() CheckRunVimInTerminal let buf = RunVimInTerminal('', {'rows': 6}) - call term_sendkeys(buf, ":call setline(1, ['foo foo', 'foo foo', 'foo foo'])\<CR>") + call term_sendkeys(buf, ":call setline(1, repeat(['foo foo'], 4))\<CR>") call term_sendkeys(buf, ":set number\<CR>") call term_sendkeys(buf, "gQ") call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) @@ -90,8 +90,14 @@ func Test_Ex_substitute() " Pressing enter in ex mode should print the current line call term_sendkeys(buf, "\<CR>") - call WaitForAssert({-> assert_match(' 3 foo foo', - \ term_getline(buf, 5))}, 1000) + call WaitForAssert({-> assert_match(' 3 foo foo', term_getline(buf, 5))}, 1000) + call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) + + " The printed line should overwrite the colon + call term_sendkeys(buf, "\<CR>") + call WaitForAssert({-> assert_match(' 3 foo foo', term_getline(buf, 4))}, 1000) + call WaitForAssert({-> assert_match(' 4 foo foo', term_getline(buf, 5))}, 1000) + call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) call term_sendkeys(buf, ":vi\<CR>") call WaitForAssert({-> assert_match('foo bar', term_getline(buf, 1))}, 1000) @@ -165,6 +171,37 @@ func Test_Ex_global() call assert_equal('bax', getline(3)) call assert_equal('bay', getline(5)) bwipe! + + new + call setline(1, ['foo', 'bar']) + call feedkeys("Qg/./i\\\na\\\n.\\\na\\\nb\\\n.", "xt") + call assert_equal(['a', 'b', 'foo', 'a', 'b', 'bar'], getline(1, '$')) + bwipe! +endfunc + +func Test_Ex_shell() + CheckUnix + + new + call feedkeys("Qr !echo foo\\\necho bar\n", 'xt') + call assert_equal(['', 'foo', 'bar'], getline(1, '$')) + bwipe! + + new + call feedkeys("Qr !echo foo\\\\\nbar\n", 'xt') + call assert_equal(['', 'foobar'], getline(1, '$')) + bwipe! + + new + call feedkeys("Qr !echo foo\\ \\\necho bar\n", 'xt') + call assert_equal(['', 'foo ', 'bar'], getline(1, '$')) + bwipe! + + new + call setline(1, ['bar', 'baz']) + call feedkeys("Qg/./!echo \\\ns/b/c/", "xt") + call assert_equal(['car', 'caz'], getline(1, '$')) + bwipe! endfunc " Test for pressing Ctrl-C in :append inside a loop in Ex mode @@ -204,18 +241,11 @@ func Test_Ex_append() call feedkeys("Qappend!\npqr\nxyz\n.\nvisual\n", 'xt') call assert_equal(["\t abc", "\t pqr", "\t xyz"], getline(1, '$')) close! -endfunc -" In Ex-mode, backslashes at the end of a command should be halved. -func Test_Ex_echo_backslash() - " This test works only when the language is English - CheckEnglish - let bsl = '\\\\' - let bsl2 = '\\\' - call assert_fails('call feedkeys("Qecho " .. bsl .. "\nvisual\n", "xt")', - \ 'E15: Invalid expression: "\\"') - call assert_fails('call feedkeys("Qecho " .. bsl2 .. "\nm\nvisual\n", "xt")', - \ "E15: Invalid expression: \"\\\nm\"") + new + call feedkeys("Qappend\na\\\n.", 'xt') + call assert_equal(['a\'], getline(1, '$')) + close! endfunc func Test_ex_mode_errors() @@ -314,5 +344,38 @@ func Test_empty_command_visual_mode() call delete('guidialogfile') endfunc +" Test using backslash in ex-mode +func Test_backslash_multiline() + new + call setline(1, 'enum') + call feedkeys('Qg/enum/i\ \ .', "xt") + call assert_equal(["", "enum"], getline(1, 2)) +endfunc + +" Test using backslash in ex-mode after patch 9.1.0535 +func Test_backslash_multiline2() + new + call feedkeys('Qa X \\ Y .', "xt") + call assert_equal(['X \\', "Y"], getline(1, 2)) +endfunc + +" Testing implicit print command +func Test_implicit_print() + new + call setline(1, ['one', 'two', 'three']) + call feedkeys('Q:let a=execute(":1,2")', 'xt') + call feedkeys('Q:let b=execute(":3")', 'xt') + call assert_equal('one two', a->split('\n')->join(' ')) + call assert_equal('three', b->split('\n')->join(' ')) + bw! +endfunc + +" Test inserting text after the trailing bar +func Test_insert_after_trailing_bar() + new + call feedkeys("Qi|\nfoo\n.\na|bar\nbar\n.\nc|baz\n.", "xt") + call assert_equal(['', 'foo', 'bar', 'baz'], getline(1, '$')) + bwipe! +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim index 221ceb0f0b..3b7e489f38 100644 --- a/src/testdir/test_excmd.vim +++ b/src/testdir/test_excmd.vim @@ -703,6 +703,8 @@ func Test_address_line_overflow() call setline(1, range(100)) call assert_fails('|.44444444444444444444444', 'E1247:') call assert_fails('|.9223372036854775806', 'E1247:') + call assert_fails('.44444444444444444444444d', 'E1247:') + call assert_equal(range(100)->map('string(v:val)'), getline(1, '$')) $ yank 77777777777777777777 diff --git a/src/testdir/test_filecopy.vim b/src/testdir/test_filecopy.vim new file mode 100644 index 0000000000..b526dce7b8 --- /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 e2098667ea..11e74afce6 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -95,6 +95,7 @@ def s:GetFilenameChecks(): dict<list<string>> aml: ['file.aml'], ampl: ['file.run'], ant: ['build.xml'], + antlr4: ['parser.g4'], apache: ['.htaccess', '/etc/httpd/file.conf', '/etc/apache2/sites-2/file.com', '/etc/apache2/some.config', '/etc/apache2/conf.file/conf', '/etc/apache2/mods-some/file', '/etc/apache2/sites-some/file', '/etc/httpd/conf.d/file.config', '/etc/apache2/conf.file/file', '/etc/apache2/file.conf', '/etc/apache2/file.conf-file', '/etc/apache2/mods-file/file', '/etc/apache2/sites-file/file', '/etc/apache2/sites-file/file.com', '/etc/httpd/conf.d/file.conf', '/etc/httpd/conf.d/file.conf-file', 'access.conf', 'access.conf-file', 'any/etc/apache2/conf.file/file', 'any/etc/apache2/file.conf', 'any/etc/apache2/file.conf-file', 'any/etc/apache2/mods-file/file', 'any/etc/apache2/sites-file/file', 'any/etc/apache2/sites-file/file.com', 'any/etc/httpd/conf.d/file.conf', 'any/etc/httpd/conf.d/file.conf-file', 'any/etc/httpd/file.conf', 'apache.conf', 'apache.conf-file', 'apache2.conf', 'apache2.conf-file', 'httpd.conf', 'httpd.conf-file', 'srm.conf', 'srm.conf-file', '/etc/httpd/mods-some/file', '/etc/httpd/sites-some/file', '/etc/httpd/conf.file/conf'], apachestyle: ['/etc/proftpd/file.config,/etc/proftpd/conf.file/file', '/etc/proftpd/conf.file/file', '/etc/proftpd/file.conf', '/etc/proftpd/file.conf-file', 'any/etc/proftpd/conf.file/file', 'any/etc/proftpd/file.conf', 'any/etc/proftpd/file.conf-file', 'proftpd.conf', 'proftpd.conf-file'], applescript: ['file.scpt'], @@ -106,6 +107,7 @@ def s:GetFilenameChecks(): dict<list<string>> asn: ['file.asn', 'file.asn1'], asterisk: ['asterisk/file.conf', 'asterisk/file.conf-file', 'some-asterisk/file.conf', 'some-asterisk/file.conf-file'], astro: ['file.astro'], + asy: ['file.asy'], atlas: ['file.atl', 'file.as'], authzed: ['schema.zed'], autohotkey: ['file.ahk'], @@ -121,7 +123,7 @@ def s:GetFilenameChecks(): dict<list<string>> beancount: ['file.beancount'], bib: ['file.bib'], bicep: ['file.bicep', 'file.bicepparam'], - bindzone: ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file'], + bindzone: ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file', 'foobar.zone'], bitbake: ['file.bb', 'file.bbappend', 'file.bbclass', 'build/conf/local.conf', 'meta/conf/layer.conf', 'build/conf/bbappend.conf', 'meta-layer/conf/distro/foo.conf'], blade: ['file.blade.php'], blank: ['file.bl'], @@ -131,7 +133,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'], @@ -142,6 +144,7 @@ def s:GetFilenameChecks(): dict<list<string>> cdl: ['file.cdl'], cdrdaoconf: ['/etc/cdrdao.conf', '/etc/defaults/cdrdao', '/etc/default/cdrdao', '.cdrdao', 'any/etc/cdrdao.conf', 'any/etc/default/cdrdao', 'any/etc/defaults/cdrdao'], cdrtoc: ['file.toc'], + cedar: ['file.cedar'], cf: ['file.cfm', 'file.cfi', 'file.cfc'], cfengine: ['cfengine.conf'], cfg: ['file.hgrc', 'filehgrc', 'hgrc', 'some-hgrc'], @@ -160,7 +163,7 @@ def s:GetFilenameChecks(): dict<list<string>> cmakecache: ['CMakeCache.txt'], cmod: ['file.cmod'], cmusrc: ['any/.cmus/autosave', 'any/.cmus/rc', 'any/.cmus/command-history', 'any/.cmus/file.theme', 'any/cmus/rc', 'any/cmus/file.theme', '/.cmus/autosave', '/.cmus/command-history', '/.cmus/file.theme', '/.cmus/rc', '/cmus/file.theme', '/cmus/rc'], - cobol: ['file.cbl', 'file.cob', 'file.lib'], + cobol: ['file.cbl', 'file.cob'], coco: ['file.atg'], conaryrecipe: ['file.recipe'], conf: ['auto.master', 'file.conf', 'texdoc.cnf', '.x11vncrc', '.chktexrc', '.ripgreprc', 'ripgreprc', 'file.ctags', '.mbsyncrc'], @@ -222,11 +225,11 @@ def s:GetFilenameChecks(): dict<list<string>> 'psprint.conf', 'sofficerc', 'any/.config/lxqt/globalkeyshortcuts.conf', 'any/.config/screengrab/screengrab.conf', 'any/.local/share/flatpak/repo/config', '.notmuch-config'], dot: ['file.dot', 'file.gv'], - dracula: ['file.drac', 'file.drc', 'filelvs', 'filelpe', 'drac.file', 'lpe', 'lvs', 'some-lpe', 'some-lvs'], + dracula: ['file.drac', 'file.drc', 'file.lvs', 'file.lpe', 'drac.file'], dtd: ['file.dtd'], dtrace: ['/usr/lib/dtrace/io.d'], dts: ['file.dts', 'file.dtsi', 'file.dtso', 'file.its', 'file.keymap'], - dune: ['jbuild', 'dune', 'dune-project', 'dune-workspace'], + dune: ['jbuild', 'dune', 'dune-project', 'dune-workspace', 'dune-file'], dylan: ['file.dylan'], dylanintr: ['file.intr'], dylanlid: ['file.lid'], @@ -256,6 +259,7 @@ def s:GetFilenameChecks(): dict<list<string>> factor: ['file.factor'], falcon: ['file.fal'], fan: ['file.fan', 'file.fwt'], + faust: ['file.dsp', 'file.lib'], fennel: ['file.fnl'], fetchmail: ['.fetchmailrc'], fgl: ['file.4gl', 'file.4gh', 'file.m4gl'], @@ -285,13 +289,13 @@ def s:GetFilenameChecks(): dict<list<string>> gitattributes: ['file.git/info/attributes', '.gitattributes', '/.config/git/attributes', '/etc/gitattributes', '/usr/local/etc/gitattributes', 'some.git/info/attributes'] + WhenConfigHome('$XDG_CONFIG_HOME/git/attributes'), gitcommit: ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG', 'NOTES_EDITMSG', 'EDIT_DESCRIPTION'], gitconfig: ['file.git/config', 'file.git/config.worktree', 'file.git/worktrees/x/config.worktree', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig', '/usr/local/etc/gitconfig', '/etc/gitconfig.d/file', 'any/etc/gitconfig.d/file', '/.gitconfig.d/file', 'any/.config/git/config', 'any/.gitconfig.d/file', 'some.git/config', 'some.git/modules/any/config'] + WhenConfigHome('$XDG_CONFIG_HOME/git/config'), - gitignore: ['file.git/info/exclude', '.gitignore', '/.config/git/ignore', 'some.git/info/exclude'] + WhenConfigHome('$XDG_CONFIG_HOME/git/ignore'), + gitignore: ['file.git/info/exclude', '.gitignore', '/.config/git/ignore', 'some.git/info/exclude'] + WhenConfigHome('$XDG_CONFIG_HOME/git/ignore') + ['.prettierignore'], gitolite: ['gitolite.conf', '/gitolite-admin/conf/file', 'any/gitolite-admin/conf/file'], gitrebase: ['git-rebase-todo'], gitsendemail: ['.gitsendemail.msg.xxxxxx'], gkrellmrc: ['gkrellmrc', 'gkrellmrc_x'], gleam: ['file.gleam'], - glsl: ['file.glsl'], + glsl: ['file.glsl', 'file.vert', 'file.tesc', 'file.tese', 'file.geom', 'file.frag', 'file.comp', 'file.rgen', 'file.rmiss', 'file.rchit', 'file.rahit', 'file.rint', 'file.rcall'], gn: ['file.gn', 'file.gni'], gnash: ['gnashrc', '.gnashrc', 'gnashpluginrc', '.gnashpluginrc'], gnuplot: ['file.gpi', '.gnuplot', 'file.gnuplot', '.gnuplot_history'], @@ -332,10 +336,12 @@ def s:GetFilenameChecks(): dict<list<string>> hoon: ['file.hoon'], hostconf: ['/etc/host.conf', 'any/etc/host.conf'], hostsaccess: ['/etc/hosts.allow', '/etc/hosts.deny', 'any/etc/hosts.allow', 'any/etc/hosts.deny'], + # file.component.html should be HTML, not Angular, see #13594 html: ['file.html', 'file.htm', 'file.cshtml', 'file.component.html'], htmlm4: ['file.html.m4'], httest: ['file.htt', 'file.htb'], 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 +350,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 +365,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'], + json: ['file.json', 'file.jsonp', 'file.json-patch', 'file.geojson', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', 'file.jupyterlab-settings', '.prettierrc', '.firebaserc', '.stylelintrc', '.lintstagedrc', 'file.slnf', 'file.sublime-project', 'file.sublime-settings', 'file.sublime-workspace', 'file.bd', 'file.bda', 'file.xci', 'flake.lock', 'pack.mcmeta'], 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'], @@ -380,6 +388,7 @@ def s:GetFilenameChecks(): dict<list<string>> lace: ['file.ace', 'file.ACE'], latte: ['file.latte', 'file.lte'], ld: ['file.ld', 'any/usr/lib/aarch64-xilinx-linux/ldscripts/aarch64elf32b.x'], + ldapconf: ['ldap.conf', '.ldaprc', 'ldaprc'], ldif: ['file.ldif'], lean: ['file.lean'], ledger: ['file.ldg', 'file.ledger', 'file.journal'], @@ -417,18 +426,19 @@ def s:GetFilenameChecks(): dict<list<string>> mail: ['snd.123', '.letter', '.letter.123', '.followup', '.article', '.article.123', 'pico.123', 'mutt-xx-xxx', 'muttng-xx-xxx', 'ae123.txt', 'file.eml', 'reportbug-file'], mailaliases: ['/etc/mail/aliases', '/etc/aliases', 'any/etc/aliases', 'any/etc/mail/aliases'], mailcap: ['.mailcap', 'mailcap'], - make: ['file.mk', 'file.mak', 'file.dsp', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile'], + make: ['file.mk', 'file.mak', 'makefile', 'Makefile', 'makefile-file', 'Makefile-file', 'some-makefile', 'some-Makefile', 'Kbuild'], mallard: ['file.page'], man: ['file.man'], manconf: ['/etc/man.conf', 'man.config', 'any/etc/man.conf'], map: ['file.map'], maple: ['file.mv', 'file.mpl', 'file.mws'], markdown: ['file.markdown', 'file.mdown', 'file.mkd', 'file.mkdn', 'file.mdwn', 'file.md'], - mason: ['file.mason', 'file.mhtml', 'file.comp'], + mason: ['file.mason', 'file.mhtml'], master: ['file.mas', 'file.master'], matlab: ['file.m'], maxima: ['file.demo', 'file.dmt', 'file.dm1', 'file.dm2', 'file.dm3', 'file.wxm', 'maxima-init.mac'], + mediawiki: ['file.mw', 'file.wiki'], mel: ['file.mel'], mermaid: ['file.mmd', 'file.mmdc', 'file.mermaid'], meson: ['meson.build', 'meson.options', 'meson_options.txt'], @@ -463,7 +473,7 @@ def s:GetFilenameChecks(): dict<list<string>> mgp: ['file.mgp'], mib: ['file.mib', 'file.my'], mix: ['file.mix', 'file.mixal'], - mma: ['file.nb'], + mma: ['file.nb', 'file.wl'], mmp: ['file.mmp'], modconf: ['/etc/modules.conf', '/etc/modules', '/etc/conf.modules', '/etc/modprobe.file', 'any/etc/conf.modules', 'any/etc/modprobe.file', 'any/etc/modules', 'any/etc/modules.conf'], modula3: ['file.m3', 'file.mg', 'file.i3', 'file.ig', 'file.lm3'], @@ -518,7 +528,8 @@ def s:GetFilenameChecks(): dict<list<string>> octave: ['octaverc', '.octaverc', 'octave.conf', 'any/.local/share/octave/history'], odin: ['file.odin'], omnimark: ['file.xom', 'file.xin'], - opam: ['opam', 'file.opam', 'file.opam.template'], + ondir: ['.ondirrc'], + opam: ['opam', 'file.opam', 'file.opam.template', 'opam.locked', 'file.opam.locked'], openroad: ['file.or'], openscad: ['file.scad'], openvpn: ['file.ovpn', '/etc/openvpn/client/client.conf', '/usr/share/openvpn/examples/server.conf'], @@ -573,6 +584,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'], @@ -587,6 +599,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'], @@ -639,7 +652,8 @@ def s:GetFilenameChecks(): dict<list<string>> sh: ['.bashrc', '.bash_profile', '.bash-profile', '.bash_logout', '.bash-logout', '.bash_aliases', '.bash-aliases', '.bash_history', '.bash-history', '/tmp/bash-fc-3Ozjlw', '/tmp/bash-fc.3Ozjlw', 'PKGBUILD', 'APKBUILD', 'file.bash', '/usr/share/doc/bash-completion/filter.sh', '/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf', 'file.bats', '.ash_history', 'any/etc/neofetch/config.conf', '.xprofile', - 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf'], + 'user-dirs.defaults', 'user-dirs.dirs', 'makepkg.conf', '.makepkg.conf', 'file.mdd', 'file.cygport', '.env', '.envrc', 'devscripts.conf', + '.devscripts'], sieve: ['file.siv', 'file.sieve'], sil: ['file.sil'], simula: ['file.sim'], @@ -650,6 +664,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'], @@ -662,6 +677,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'], @@ -685,6 +701,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'], @@ -745,11 +762,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', 'file.pdf_tex'], texinfo: ['file.texinfo', 'file.texi', 'file.txi'], texmf: ['texmf.cnf'], text: ['file.text', 'file.txt', 'README', 'LICENSE', 'COPYING', 'AUTHORS', '/usr/share/doc/bash-completion/AUTHORS', '/etc/apt/apt.conf.d/README', '/etc/Muttrc.d/README'], @@ -984,6 +1002,7 @@ def s:GetScriptChecks(): dict<list<list<string>>> ['#!/path/regina']], janet: [['#!/path/janet']], dart: [['#!/path/dart']], + vim: [['#!/path/vim']], } enddef @@ -1032,7 +1051,8 @@ func Test_emptybuf_ftdetect() call assert_equal('', &filetype) filetype detect call assert_equal('sh', &filetype) - close! + " close the swapfile + bw! endfunc " Test for ':filetype indent on' and ':filetype indent off' commands @@ -1505,6 +1525,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 @@ -1521,6 +1576,41 @@ func Test_hook_file() filetype off endfunc +func Test_html_file() + filetype on + + " HTML Angular + let content = ['@for (item of items; track item.name) {', ' <li> {{ item.name }}</li>', '} @empty {', ' <li> There are no items.</li>', '}'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('htmlangular', &filetype) + bwipe! + + " Django Template + let content = ['{% if foobar %}', + \ ' <ul>', + \ ' {% for question in list %}', + \ ' <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>', + \ ' {% endfor %}', + \ ' </ul>', + \ '{% else %}', + \ ' <p>No polls are available.</p>', + \ '{% endif %}'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('htmldjango', &filetype) + bwipe! + + " regular HTML + let content = ['<!DOCTYPE html>', '<html>', ' <head>Foobar</head>', ' <body>Content', ' </body>', '</html>'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('html', &filetype) + bwipe! + + filetype off +endfunc + func Test_m_file() filetype on @@ -1683,14 +1773,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) @@ -2355,6 +2445,32 @@ func Test_typ_file() filetype off endfunc +func Test_dsp_file() + filetype on + + " Microsoft Developer Studio Project file + + call writefile(['# Microsoft Developer Studio Project File'], 'Xfile.dsp', 'D') + split Xfile.dsp + call assert_equal('make', &filetype) + bwipe! + + let g:filetype_dsp = 'make' + split test.dsp + call assert_equal('make', &filetype) + bwipe! + unlet g:filetype_dsp + + " Faust + + call writefile(['this is a fallback'], 'Xfile.dsp') + split Xfile.dsp + call assert_equal('faust', &filetype) + bwipe! + + filetype off +endfunc + func Test_vba_file() filetype on @@ -2441,4 +2557,91 @@ func Test_def_file() filetype off endfunc +func Test_uci_file() + filetype on + + call mkdir('any/etc/config', 'pR') + call writefile(['config firewall'], 'any/etc/config/firewall', 'D') + split any/etc/config/firewall + call assert_equal('uci', &filetype) + bwipe! + + call writefile(['# config for nginx here'], 'any/etc/config/firewall', 'D') + split any/etc/config/firewall + call assert_notequal('uci', &filetype) + bwipe! + + call writefile(['# Copyright Cool Cats 1997', 'config firewall'], 'any/etc/config/firewall', 'D') + split any/etc/config/firewall + call assert_equal('uci', &filetype) + bwipe! + + filetype off +endfunc + +func Test_pro_file() + filetype on + + "Prolog + call writefile([':-module(test/1,'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['% comment'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['/* multiline comment'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['rule(test, 1.7).'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('prolog', &filetype) + bwipe! + + " IDL + call writefile(['x = findgen(100)/10'], 'Xfile.pro', 'D') + split Xfile.pro + call assert_equal('idlang', &filetype) + + filetype off +endfunc + + +func Test_pl_file() + filetype on + + "Prolog + call writefile([':-module(test/1,'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['% comment'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['/* multiline comment'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + call writefile(['rule(test, 1.7).'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('prolog', &filetype) + bwipe! + + " Perl + call writefile(['%data = (1, 2, 3);'], 'Xfile.pl', 'D') + split Xfile.pl + call assert_equal('perl', &filetype) + + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_findfile.vim b/src/testdir/test_findfile.vim index 20d5096132..a5e18b9570 100644 --- a/src/testdir/test_findfile.vim +++ b/src/testdir/test_findfile.vim @@ -98,14 +98,48 @@ func Test_findfile() " Test upwards search with stop-directory. cd Xdir2 + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3/', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';../', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';..', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -1) call assert_equal(1, len(l)) call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';../../', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + let l = findfile('bar', ';../..', -1) + call assert_equal(1, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1) call assert_equal(2, len(l)) call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) call assert_match('.*/Xfinddir1/bar', l[1]) + let l = findfile('bar', ';' . save_dir . '/Xfinddir1', -1) + call assert_equal(2, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + call assert_match('.*/Xfinddir1/bar', l[1]) + let l = findfile('bar', ';../../../', -1) + call assert_equal(2, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + call assert_match('.*/Xfinddir1/bar', l[1]) + let l = findfile('bar', ';../../..', -1) + call assert_equal(2, len(l)) + call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0]) + call assert_match('.*/Xfinddir1/bar', l[1]) " Test combined downwards and upwards search from Xdir2/. cd ../.. @@ -133,6 +167,7 @@ func Test_finddir() let save_shellslash = &shellslash let save_dir = getcwd() set path=,, + set shellslash call CreateFiles() cd Xfinddir1 diff --git a/src/testdir/test_fnamemodify.vim b/src/testdir/test_fnamemodify.vim index c19f4646b3..4e61343fa4 100644 --- a/src/testdir/test_fnamemodify.vim +++ b/src/testdir/test_fnamemodify.vim @@ -14,6 +14,8 @@ func Test_fnamemodify() call assert_equal($HOME .. "/foo" , fnamemodify('~/foo', ':p')) call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/../', ':p')) call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/..', ':p')) + call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('../', ':p')) + call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('..', ':p')) call assert_equal('test.out', fnamemodify('test.out', ':.')) call assert_equal('a', fnamemodify('../testdir/a', ':.')) call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~')) diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim index 3c78e62c3e..dedc4a2432 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 f0d7385825..8e973f6c9e 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,56 @@ 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 + +func Test_glob_symlinks() + call writefile([], 'Xglob1') + + if has("win32") + silent !mklink XglobBad DoesNotExist + if v:shell_error + throw 'Skipped: cannot create symlinks' + endif + silent !mklink XglobOk Xglob1 + else + silent !ln -s DoesNotExist XglobBad + silent !ln -s Xglob1 XglobOk + endif + + " The broken symlink is excluded when alllinks is false. + call assert_equal(['Xglob1', 'XglobBad', 'XglobOk'], sort(glob('Xglob*', 0, 1, 1))) + call assert_equal(['Xglob1', 'XglobOk'], sort(glob('Xglob*', 0, 1, 0))) + + call delete('Xglob1') + call delete('XglobBad') + call delete('XglobOk') +endfunc + " Test for browse() func Test_browse() CheckFeature browse @@ -3748,11 +3865,6 @@ func Test_default_arg_value() call assert_equal('msg', HasDefault()) endfunc -" Test for gettext() -func Test_gettext() - call assert_fails('call gettext(1)', 'E1174:') -endfunc - func Test_builtin_check() call assert_fails('let g:["trim"] = {x -> " " .. x}', 'E704:') call assert_fails('let g:.trim = {x -> " " .. x}', 'E704:') @@ -4039,6 +4151,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_gettext.vim b/src/testdir/test_gettext.vim new file mode 100644 index 0000000000..a990121a8e --- /dev/null +++ b/src/testdir/test_gettext.vim @@ -0,0 +1,18 @@ +source check.vim + +CheckFeature gettext + +" Test for gettext() +func Test_gettext() + call assert_fails('call bindtextdomain("test")', 'E119:') + call assert_fails('call bindtextdomain("vim", "test")', 'E475:') + + call assert_fails('call gettext(1)', 'E1174:') + call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx")) + + call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx", "vim")) + call assert_equal('xxxTESTxxx', gettext("xxxTESTxxx", "__PACKAGE__")) + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_gettext_cp1251.vim b/src/testdir/test_gettext_cp1251.vim new file mode 100644 index 0000000000..69d2bbf4cd --- /dev/null +++ b/src/testdir/test_gettext_cp1251.vim @@ -0,0 +1,35 @@ +source check.vim +" This fail on CI MacOS 14 because bindtextdomain() is not available there +" (missing library?) +CheckNotMac +CheckFeature gettext + +" Test for gettext() +func Test_gettext() + set encoding=cp1251 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + + try + call assert_true(bindtextdomain("__PACKAGE__", getcwd())) + + try + language messages ru_RU + call assert_equal(': ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to ru (missing?)" + endtry + + try + language messages en_GB.UTF-8 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to en (missing?)" + endtry + + catch /^Vim\%((\a\+)\)\=:E342:/ + throw "Skipped: out of memory executing bindtextdomain()" + endtry + set encoding& +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_gettext_make.vim b/src/testdir/test_gettext_make.vim new file mode 100644 index 0000000000..1242fa43c1 --- /dev/null +++ b/src/testdir/test_gettext_make.vim @@ -0,0 +1,72 @@ +source check.vim +CheckNotMac +CheckFeature gettext + +" Test for package translation Makefile +func Test_gettext_makefile() + cd ../po + if has('win32') + if getenv('GETTEXT_PATH') == v:null + throw 'Skipped: %GETTEXT_PATH% is not set.' + endif + call system('nmake.exe -f Make_mvc.mak "VIMPROG=' .. getenv('VIMPROG') .. + \ '" "GETTEXT_PATH=' .. getenv('GETTEXT_PATH') .. + \ '" PLUGPACKAGE=test_gettext + \ "PO_PLUG_INPUTLIST=..\testdir\test_gettext_makefile_in1.vim + \ ..\testdir\test_gettext_makefile_in2.vim + \ ..\testdir\test_gettext_makefile_in3.vim + \ ..\testdir\test_gettext_makefile_in4.vim" test_gettext.pot') + else +" Will it work on macOS? + call system("make -f Makefile PLUGPACKAGE=test_gettext + \ PO_PLUG_INPUTLIST=\"../testdir/test_gettext_makefile_in1.vim + \ ../testdir/test_gettext_makefile_in2.vim + \ ../testdir/test_gettext_makefile_in3.vim + \ ../testdir/test_gettext_makefile_in4.vim\" test_gettext.pot") + endif + if v:shell_error != 0 + throw 'Fail to create test_gettext.pot. Error code: ' .. v:shell_error + endif + let expected =<< trim END + # SOME DESCRIPTIVE TITLE. + # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER + # This file is distributed under the same license as the test_gettext package. + # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. + # + #, fuzzy + msgid "" + msgstr "" + "Project-Id-Version: test_gettext\n" + "Report-Msgid-Bugs-To: \n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" + "Language-Team: LANGUAGE <LL@li.org>\n" + "Language: \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=CHARSET\n" + "Content-Transfer-Encoding: 8bit\n" + + #: ../testdir/test_gettext_makefile_in1.vim:4 ../testdir/test_gettext_makefile_in1.vim:6 + #: ../testdir/test_gettext_makefile_in2.vim:5 ../testdir/test_gettext_makefile_in4.vim:4 + msgid "This is a test" + msgstr "" + + #: ../testdir/test_gettext_makefile_in1.vim:5 + msgid "This is another test" + msgstr "" + + #: ../testdir/test_gettext_makefile_in2.vim:4 + msgid "This is a test from the second file" + msgstr "" + + #: ../testdir/test_gettext_makefile_in4.vim:5 + msgid "This is a fourth test" + msgstr "" + END + let potfile = filter(readfile("test_gettext.pot"), 'v:val !~ "POT-Creation-Date"') + call assert_equal(expected, potfile) + call delete('test_gettext.pot') + cd - +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_gettext_makefile_in1.vim b/src/testdir/test_gettext_makefile_in1.vim new file mode 100644 index 0000000000..cbe11591f9 --- /dev/null +++ b/src/testdir/test_gettext_makefile_in1.vim @@ -0,0 +1,7 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +echo gettext("This is a test", "test_gettext") +echo gettext("This is another test", "test_gettext") +echo gettext("This is a test", "test_gettext") +" vim: ts=8 diff --git a/src/testdir/test_gettext_makefile_in2.vim b/src/testdir/test_gettext_makefile_in2.vim new file mode 100644 index 0000000000..86d3dd9ed1 --- /dev/null +++ b/src/testdir/test_gettext_makefile_in2.vim @@ -0,0 +1,6 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +echo gettext("This is a test from the second file", "test_gettext") +echo gettext("This is a test", "test_gettext") +" vim: ts=8 diff --git a/src/testdir/test_gettext_makefile_in3.vim b/src/testdir/test_gettext_makefile_in3.vim new file mode 100644 index 0000000000..f4cf93d1a9 --- /dev/null +++ b/src/testdir/test_gettext_makefile_in3.vim @@ -0,0 +1,4 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +" vim: ts=8 diff --git a/src/testdir/test_gettext_makefile_in4.vim b/src/testdir/test_gettext_makefile_in4.vim new file mode 100644 index 0000000000..7f9f3f7dd5 --- /dev/null +++ b/src/testdir/test_gettext_makefile_in4.vim @@ -0,0 +1,6 @@ +" Test file for gettext() package makefile +" Last Change: 2024 Jun 01 + +echo gettext("This is a test", "test_gettext") +echo gettext("This is a fourth test", "test_gettext") +" vim: ts=8 diff --git a/src/testdir/test_gettext_utf8.vim b/src/testdir/test_gettext_utf8.vim new file mode 100644 index 0000000000..b96f8ea8ed --- /dev/null +++ b/src/testdir/test_gettext_utf8.vim @@ -0,0 +1,35 @@ +source check.vim +" This fail on CI MacOS 14 because bindtextdomain() is not available there +" (missing library?) +CheckNotMac +CheckFeature gettext + +" Test for gettext() +func Test_gettext() + set encoding=utf-8 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + + try + call assert_true(bindtextdomain("__PACKAGE__", getcwd())) + + try + language messages ru_RU + call assert_equal('ОШИБКА: ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to ru (missing?)" + endtry + + try + language messages en_GB.UTF-8 + call assert_equal('ERROR: ', gettext("ERROR: ", "__PACKAGE__")) + catch /^Vim\%((\a\+)\)\=:E197:/ + throw "Skipped: not possible to set locale to en (missing?)" + endtry + + catch /^Vim\%((\a\+)\)\=:E342:/ + throw "Skipped: out of memory executing bindtextdomain()" + endtry + set encoding& +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_getvar.vim b/src/testdir/test_getvar.vim index 2065186a5a..6efb192ebc 100644 --- a/src/testdir/test_getvar.vim +++ b/src/testdir/test_getvar.vim @@ -142,20 +142,28 @@ func Test_get_func() let l:F = function('tr') call assert_equal('tr', get(l:F, 'name')) call assert_equal(l:F, get(l:F, 'func')) + call assert_equal({'required': 3, 'optional': 0, 'varargs': v:false}, + \ get(l:F, 'arity')) let Fb_func = function('s:FooBar') call assert_match('<SNR>\d\+_FooBar', get(Fb_func, 'name')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, + \ get(Fb_func, 'arity')) let Fb_ref = funcref('s:FooBar') call assert_match('<SNR>\d\+_FooBar', get(Fb_ref, 'name')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, + \ get(Fb_ref, 'arity')) call assert_equal({'func has': 'no dict'}, get(l:F, 'dict', {'func has': 'no dict'})) call assert_equal(0, get(l:F, 'dict')) call assert_equal([], get(l:F, 'args')) + let NF = test_null_function() call assert_equal('', get(NF, 'name')) call assert_equal(NF, get(NF, 'func')) call assert_equal(0, get(NF, 'dict')) call assert_equal([], get(NF, 'args')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, get(NF, 'arity')) endfunc " get({partial}, {what} [, {default}]) - in test_partial.vim diff --git a/src/testdir/test_global.vim b/src/testdir/test_global.vim index 34857b2555..0f72c3cf80 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_goto.vim b/src/testdir/test_goto.vim index 357a8d27c8..8813bcbacd 100644 --- a/src/testdir/test_goto.vim +++ b/src/testdir/test_goto.vim @@ -296,6 +296,7 @@ func Test_gd_string() return x; } [CODE] + call XTest_goto_decl('gd', lines, 4, 7) endfunc @@ -320,14 +321,14 @@ func Test_set_options_keep_col() let pos = getcurpos() normal j set invhlsearch spell spelllang=en,cjk spelloptions=camel textwidth=80 - set cursorline cursorcolumn cursorlineopt=line colorcolumn=+1 + set cursorline cursorcolumn cursorlineopt=line colorcolumn=+1 winfixbuf set background=dark set background=light normal k call assert_equal(pos, getcurpos()) bwipe! set hlsearch& spell& spelllang& spelloptions& textwidth& - set cursorline& cursorcolumn& cursorlineopt& colorcolumn& + set cursorline& cursorcolumn& cursorlineopt& colorcolumn& winfixbuf& set background& endfunc diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim index 034b9a0e97..fe72497411 100644 --- a/src/testdir/test_gui.vim +++ b/src/testdir/test_gui.vim @@ -955,7 +955,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) @@ -1771,7 +1771,8 @@ func Test_gui_lowlevel_keyevent() new " Test for <Ctrl-A> to <Ctrl-Z> keys - for kc in range(65, 90) + " FIXME: <Ctrl-C> is excluded for now. It makes the test flaky. + for kc in range(65, 66) + range(68, 90) call SendKeys([0x11, kc]) try let ch = getcharstr() diff --git a/src/testdir/test_history.vim b/src/testdir/test_history.vim index 19490f2528..b288abc3f6 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_increment.vim b/src/testdir/test_increment.vim index fdd7c0ce01..3a5f5ee028 100644 --- a/src/testdir/test_increment.vim +++ b/src/testdir/test_increment.vim @@ -840,6 +840,44 @@ func Test_increment_unsigned() set nrformats-=unsigned endfunc +" Try incrementing/decrementing a number when nrformats contains blank +func Test_increment_blank() + set nrformats+=blank + + " Signed + call setline(1, '0') + exec "norm! gg0\<C-X>" + call assert_equal('-1', getline(1)) + + call setline(1, '3') + exec "norm! gg010\<C-X>" + call assert_equal('-7', getline(1)) + + call setline(1, '-0') + exec "norm! gg0\<C-X>" + call assert_equal("-1", getline(1)) + + " Unsigned + " NOTE: 18446744073709551615 == 2^64 - 1 + call setline(1, 'a-18446744073709551615') + exec "norm! gg0\<C-A>" + call assert_equal('a-18446744073709551615', getline(1)) + + call setline(1, 'a-18446744073709551615') + exec "norm! gg0\<C-A>" + call assert_equal('a-18446744073709551615', getline(1)) + + call setline(1, 'a-18446744073709551614') + exec "norm! gg08\<C-A>" + call assert_equal('a-18446744073709551615', getline(1)) + + call setline(1, 'a-1') + exec "norm! gg0\<C-A>" + call assert_equal('a-2', getline(1)) + + set nrformats-=blank +endfunc + func Test_in_decrement_large_number() " NOTE: 18446744073709551616 == 2^64 call setline(1, '18446744073709551616') diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim index eb89a15c53..f3f6eac23f 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,173 @@ 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('.')) + + set completeopt-=noinsert + call setline(1, ['xyz yxz x']) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('xyz yxz xyz', getline('.')) + " can fuzzy get yxz when use Ctrl-N twice + call setline(1, ['xyz yxz x']) + call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!') + call assert_equal('xyz yxz yxz', getline('.')) + + call setline(1, ['你好 你']) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('你好 你好', getline('.')) + call setline(1, ['你的 我的 的']) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('你的 我的 你的', getline('.')) + " can fuzzy get multiple-byte word when use Ctrl-N twice + call setline(1, ['你的 我的 的']) + call feedkeys("A\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!') + call assert_equal('你的 我的 我的', getline('.')) + + " respect wrapscan + set nowrapscan + call setline(1, ["xyz", "yxz", ""]) + call cursor(3, 1) + call feedkeys("Sy\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('y', getline('.')) + set wrapscan + call feedkeys("Sy\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('xyz', getline('.')) + + " fuzzy on file + call writefile([''], 'fobar', 'D') + call writefile([''], 'foobar', 'D') + call setline(1, ['fob']) + call cursor(1, 1) + call feedkeys("A\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_equal('fobar', getline('.')) + call feedkeys("Sfob\<C-X>\<C-f>\<C-N>\<Esc>0", 'tx!') + call assert_equal('foobar', getline('.')) + call feedkeys("S../\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_match('../*', getline('.')) + call feedkeys("S../td\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_match('../testdir', getline('.')) + + " can get completion from other buffer + set completeopt=fuzzy,menu,menuone + vnew + call setline(1, ["completeness,", "compatibility", "Composite", "Omnipotent"]) + wincmd p + call feedkeys("Somp\<C-N>\<Esc>0", 'tx!') + call assert_equal('completeness', getline('.')) + call feedkeys("Somp\<C-N>\<C-N>\<Esc>0", 'tx!') + call assert_equal('compatibility', getline('.')) + call feedkeys("Somp\<C-P>\<Esc>0", 'tx!') + call assert_equal('Omnipotent', getline('.')) + call feedkeys("Somp\<C-P>\<C-P>\<Esc>0", 'tx!') + call assert_equal('Composite', getline('.')) + call feedkeys("S omp\<C-N>\<Esc>0", 'tx!') + call assert_equal(' completeness', getline('.')) + + " fuzzy on whole line completion + call setline(1, ["world is on fire", "no one can save me but you", 'user can execute', '']) + call cursor(4, 1) + call feedkeys("Swio\<C-X>\<C-L>\<Esc>0", 'tx!') + call assert_equal('world is on fire', getline('.')) + call feedkeys("Su\<C-X>\<C-L>\<C-P>\<Esc>0", 'tx!') + call assert_equal('no one can save me but you', getline('.')) + + " clean up + set omnifunc= + bw! + 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_jumplist.vim b/src/testdir/test_jumplist.vim index 8fbf39f55b..4b9fcee780 100644 --- a/src/testdir/test_jumplist.vim +++ b/src/testdir/test_jumplist.vim @@ -59,29 +59,63 @@ func Test_getjumplist() call assert_equal(4, l[1]) endfunc -func Test_jumplist_invalid() +func Test_jumplist_wipe_buf() new clearjumps - " put some randome text - put ='a' - let prev = bufnr('%') + " Put some random text and fill the jump list. + call setline(1, ['foo', 'bar', 'baz']) + normal G + normal gg setl nomodified bufhidden=wipe e XXJumpListBuffer - let bnr = bufnr('%') - " 1) empty jumplist - let expected = [[ - \ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0}], 1] - call assert_equal(expected, getjumplist()) + " The jump list is empty as the buffer was wiped out. + call assert_equal([[], 0], getjumplist()) let jumps = execute(':jumps') call assert_equal('>', jumps[-1:]) - " now jump back - exe ":norm! \<c-o>" - let expected = [[ - \ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0}, - \ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 0] - call assert_equal(expected, getjumplist()) - let jumps = execute(':jumps') - call assert_match('> 0 2 0 -invalid-', jumps) + + " Put some random text and fill the jump list. + call setline(1, ['foo', 'bar', 'baz']) + setl bufhidden=hide + + " References to wiped buffer are deleted with multiple tabpages. + let [w1, t1] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + split XXJumpListBuffer + let [w2, t2] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + tabnew XXJumpListBuffer + let [w3, t3] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + split XXJumpListBuffer + let [w4, t4] = [win_getid(), tabpagenr()] + clearjumps + normal G + normal gg + enew + + for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]] + call assert_equal(2, len(getjumplist(w, t)[0])) + endfor + + bwipe! XXJumpListBuffer + + for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]] + call assert_equal(0, len(getjumplist(w, t)[0])) + endfor + + %bwipe! endfunc " Test for '' mark in an empty buffer diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim index 4c69476362..48217cf33e 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 @@ -1128,6 +1147,19 @@ func Test_listdict_compare() call assert_fails('echo {} =~ {}', 'E736:') endfunc +func Test_recursive_listdict_compare() + let l1 = [0, 1] + let l1[0] = l1 + let l2 = [0, 1] + let l2[0] = l2 + call assert_true(l1 == l2) + let d1 = {0: 0, 1: 1} + let d1[0] = d1 + let d2 = {0: 0, 1: 1} + let d2[0] = d2 + call assert_true(d1 == d2) +endfunc + " compare complex recursively linked list and dict func Test_listdict_compare_complex() let lines =<< trim END @@ -1505,6 +1537,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:') @@ -1536,4 +1570,83 @@ func Test_extendnew_leak() for i in range(100) | silent! call extendnew({}, {}, {}) | endfor endfunc +" Test for comparing deeply nested List/Dict values +func Test_deep_nested_listdict_compare() + let lines =<< trim END + def GetNestedList(sz: number): list<any> + var l: list<any> = [] + var x: list<any> = l + for i in range(sz) + var y: list<any> = [1] + add(x, y) + x = y + endfor + return l + enddef + + VAR l1 = GetNestedList(1000) + VAR l2 = GetNestedList(999) + call assert_false(l1 == l2) + + #" after 1000 nested items, the lists are considered to be equal + VAR l3 = GetNestedList(1001) + VAR l4 = GetNestedList(1002) + call assert_true(l3 == l4) + END + call v9.CheckLegacyAndVim9Success(lines) + + let lines =<< trim END + def GetNestedDict(sz: number): dict<any> + var d: dict<any> = {} + var x: dict<any> = d + for i in range(sz) + var y: dict<any> = {} + x['a'] = y + x = y + endfor + return d + enddef + + VAR d1 = GetNestedDict(1000) + VAR d2 = GetNestedDict(999) + call assert_false(d1 == d2) + + #" after 1000 nested items, the Dicts are considered to be equal + VAR d3 = GetNestedDict(1001) + VAR d4 = GetNestedDict(1002) + call assert_true(d3 == d4) + END + call v9.CheckLegacyAndVim9Success(lines) +endfunc + +" Test for using id() +def Test_id_with_dict() + # demonstate a way that "id(item)" differs from "string(item)" + var d1 = {one: 1} + var d2 = {one: 1} + var d3 = {one: 1} + var idDict: dict<any> + idDict[id(d1)] = d1 + idDict[id(d2)] = d2 + idDict[id(d3)] = d3 + assert_equal(3, idDict->len()) + + var stringDict: dict<any> + stringDict[string(d1)] = d1 + stringDict[string(d2)] = d2 + stringDict[string(d3)] = d3 + assert_equal(1, stringDict->len()) + + assert_equal('', id(3)) + + assert_equal('', id(null)) + assert_equal('', id(null_blob)) + assert_equal('', id(null_dict)) + assert_equal('', id(null_function)) + assert_equal('', id(null_list)) + assert_equal('', id(null_partial)) + assert_equal('', id(null_string)) + assert_equal('', id(null_channel)) + assert_equal('', id(null_job)) +enddef " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_listlbr_utf8.vim b/src/testdir/test_listlbr_utf8.vim index 313ff30cc4..693f2015fc 100644 --- a/src/testdir/test_listlbr_utf8.vim +++ b/src/testdir/test_listlbr_utf8.vim @@ -280,6 +280,9 @@ func Test_chinese_char_on_wrap_column() call s:compare_lines(expect, lines) call assert_equal(len(expect), winline()) call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol()) + norm! g0 + call assert_equal(len(expect), winline()) + call assert_equal(1, wincol()) call s:close_windows() endfunc @@ -315,6 +318,9 @@ func Test_chinese_char_on_wrap_column_sbr() call s:compare_lines(expect, lines) call assert_equal(len(expect), winline()) call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol()) + norm! g0 + call assert_equal(len(expect), winline()) + call assert_equal(4, wincol()) call s:close_windows() endfunc diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim index 71d90468ba..1175310465 100644 --- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -248,21 +248,25 @@ func Test_map_meta_multibyte() endfunc func Test_map_super_quotes() - if has('gui_gtk') || has('gui_gtk3') || has("macos") - imap <D-"> foo - call feedkeys("Go-\<*D-\">-\<Esc>", "xt") - call assert_equal("-foo-", getline('$')) - set nomodified - iunmap <D-"> + if "\<D-j>"[-1:] == '>' + throw 'Skipped: <D- modifier not supported' endif + + imap <D-"> foo + call feedkeys("Go-\<*D-\">-\<Esc>", "xt") + call assert_equal("-foo-", getline('$')) + set nomodified + iunmap <D-"> endfunc func Test_map_super_multibyte() - if has('gui_gtk') || has('gui_gtk3') || has("macos") - imap <D-á> foo - call assert_match('i <D-á>\s*foo', execute('imap')) - iunmap <D-á> + if "\<D-j>"[-1:] == '>' + throw 'Skipped: <D- modifier not supported' endif + + imap <D-á> foo + call assert_match('i <D-á>\s*foo', execute('imap')) + iunmap <D-á> endfunc func Test_abbr_after_line_join() @@ -1807,6 +1811,49 @@ func Test_map_after_timed_out_nop() call StopVimInTerminal(buf) endfunc +" Test 'showcmd' behavior with a partial mapping +func Test_showcmd_part_map() + CheckRunVimInTerminal + + let lines =<< trim END + set notimeout showcmd + nnoremap ,a <Ignore> + nnoremap ;a <Ignore> + nnoremap Àa <Ignore> + nnoremap Ëa <Ignore> + nnoremap βa <Ignore> + nnoremap ωa <Ignore> + nnoremap …a <Ignore> + nnoremap <C-W>a <Ignore> + END + call writefile(lines, 'Xtest_showcmd_part_map', 'D') + let buf = RunVimInTerminal('-S Xtest_showcmd_part_map', #{rows: 6}) + + call term_sendkeys(buf, ":set noruler | echo\<CR>") + call WaitForAssert({-> assert_equal('', term_getline(buf, 6))}) + + for c in [',', ';', 'À', 'Ë', 'β', 'ω', '…'] + call term_sendkeys(buf, c) + call WaitForAssert({-> assert_equal(c, trim(term_getline(buf, 6)))}) + call term_sendkeys(buf, 'a') + call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))}) + endfor + + call term_sendkeys(buf, "\<C-W>") + call WaitForAssert({-> assert_equal('^W', trim(term_getline(buf, 6)))}) + call term_sendkeys(buf, 'a') + call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))}) + + " Use feedkeys() as terminal buffer cannot forward unsimplified Ctrl-W. + " This is like typing Ctrl-W with modifyOtherKeys enabled. + call term_sendkeys(buf, ':call feedkeys("\<*C-W>", "m")' .. " | echo\<CR>") + call WaitForAssert({-> assert_equal('^W', trim(term_getline(buf, 6)))}) + call term_sendkeys(buf, 'a') + call WaitForAssert({-> assert_equal('', trim(term_getline(buf, 6)))}) + + call StopVimInTerminal(buf) +endfunc + func Test_using_past_typeahead() nnoremap :00 0 exe "norm :set \x80\xfb0=0\<CR>" diff --git a/src/testdir/test_menu.vim b/src/testdir/test_menu.vim index 30c2040d57..3bfb92c321 100644 --- a/src/testdir/test_menu.vim +++ b/src/testdir/test_menu.vim @@ -489,13 +489,48 @@ func Test_popup_menu() unmenu PopUp endfunc +func Test_popup_menu_truncated() + CheckNotGui + + set mouse=a mousemodel=popup + aunmenu PopUp + for i in range(2 * &lines) + exe $'menu PopUp.{i} <Cmd>let g:res = {i}<CR>' + endfor + + func LeftClickExpr(row, col) + call test_setmouse(a:row, a:col) + return "\<LeftMouse>" + endfunc + + " Clicking at the bottom should place popup menu above click position. + " <RightRelease> should not select an item immediately. + let g:res = -1 + call test_setmouse(&lines, 1) + nnoremap <expr><F2> LeftClickExpr(4, 1) + call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx') + call assert_equal(3, g:res) + + " Clicking at the top should place popup menu below click position. + let g:res = -1 + call test_setmouse(1, 1) + nnoremap <expr><F2> LeftClickExpr(5, 1) + call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx') + call assert_equal(3, g:res) + + nunmap <F2> + delfunc LeftClickExpr + unlet g:res + aunmenu PopUp + set mouse& mousemodel& +endfunc + " Test for MenuPopup autocommand func Test_autocmd_MenuPopup() CheckNotGui - set mouse=a - set mousemodel=popup - aunmenu * + set mouse=a mousemodel=popup + aunmenu PopUp autocmd MenuPopup * exe printf( \ 'anoremenu PopUp.Foo <Cmd>let g:res = ["%s", "%s"]<CR>', \ expand('<afile>'), expand('<amatch>')) diff --git a/src/testdir/test_method.vim b/src/testdir/test_method.vim index 120fadecbc..f18ac14340 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 7fb6a4bf53..398bf2992f 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('.')) @@ -3813,8 +3813,8 @@ func Test_normal_vert_scroll_longline() call assert_equal(11, line('.')) call assert_equal(1, winline()) exe "normal \<C-B>" - call assert_equal(10, line('.')) - call assert_equal(4, winline()) + call assert_equal(11, line('.')) + call assert_equal(5, winline()) exe "normal \<C-B>\<C-B>" call assert_equal(5, line('.')) call assert_equal(5, winline()) @@ -4247,4 +4247,38 @@ func Test_halfpage_cursor_startend() bwipe! endfunc +" Test for Ctrl-F/B moving the cursor to the window boundaries. +func Test_page_cursor_topbot() + 10new + call setline(1, range(1, 100)) + exe "norm! gg2\<C-F>" + call assert_equal(17, line('.')) + exe "norm! \<C-B>" + call assert_equal(18, line('.')) + exe "norm! \<C-B>\<C-F>" + call assert_equal(9, line('.')) + " Not when already at the start of the buffer. + exe "norm! ggj\<C-B>" + call assert_equal(2, line('.')) + bwipe! +endfunc + +" 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_options.vim b/src/testdir/test_options.vim index 70ad048956..2698ad1f62 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -548,6 +548,9 @@ func Test_set_completion_string_values() call assert_equal('sync', getcompletion('set swapsync=', 'cmdline')[1]) call assert_equal('usetab', getcompletion('set switchbuf=', 'cmdline')[1]) call assert_equal('ignore', getcompletion('set tagcase=', 'cmdline')[1]) + if exists('+tabclose') + call assert_equal('left uselast', join(sort(getcompletion('set tabclose=', 'cmdline'))), ' ') + endif if exists('+termwintype') call assert_equal('conpty', getcompletion('set termwintype=', 'cmdline')[1]) endif @@ -1419,7 +1422,8 @@ func Test_write() set nowrite call assert_fails('write Xwrfile', 'E142:') set write - close! + " close swapfile + bw! endfunc " Test for 'buftype' option @@ -1736,7 +1740,7 @@ func Test_VIM_POSIX() qall [CODE] if RunVim([], after, '') - call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\.;', + call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>#{|&/\.;', \ 'AS'], readfile('X_VIM_POSIX')) endif @@ -1746,7 +1750,7 @@ func Test_VIM_POSIX() qall [CODE] if RunVim([], after, '') - call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;', + call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZz$!%*-+<>;', \ 'S'], readfile('X_VIM_POSIX')) endif diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim index 4b054b5204..acc8b73c81 100644 --- a/src/testdir/test_partial.vim +++ b/src/testdir/test_partial.vim @@ -311,6 +311,11 @@ func Test_auto_partial_rebind() endfunc func Test_get_partial_items() + func s:Qux(x, y, z=3, w=1, ...) + endfunc + func s:Qux1(x, y) + endfunc + let dict = {'name': 'hello'} let args = ["foo", "bar"] let Func = function('MyDictFunc') @@ -331,6 +336,23 @@ func Test_get_partial_items() let dict = {'partial has': 'no dict'} call assert_equal(dict, get(P, 'dict', dict)) call assert_equal(0, get(l:P, 'dict')) + + call assert_equal({'required': 2, 'optional': 2, 'varargs': v:true}, + \ get(funcref('s:Qux', []), 'arity')) + call assert_equal({'required': 1, 'optional': 2, 'varargs': v:true}, + \ get(funcref('s:Qux', [1]), 'arity')) + call assert_equal({'required': 0, 'optional': 2, 'varargs': v:true}, + \ get(funcref('s:Qux', [1, 2]), 'arity')) + call assert_equal({'required': 0, 'optional': 1, 'varargs': v:true}, + \ get(funcref('s:Qux', [1, 2, 3]), 'arity')) + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:true}, + \ get(funcref('s:Qux', [1, 2, 3, 4]), 'arity')) + " More args than expected is not an error + call assert_equal({'required': 0, 'optional': 0, 'varargs': v:false}, + \ get(funcref('s:Qux1', [1, 2, 3, 4]), 'arity')) + + delfunc s:Qux + delfunc s:Qux1 endfunc func Test_compare_partials() @@ -406,4 +428,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_paste.vim b/src/testdir/test_paste.vim index d079f48f92..b35fc8123d 100644 --- a/src/testdir/test_paste.vim +++ b/src/testdir/test_paste.vim @@ -93,7 +93,7 @@ func Test_paste_ex_mode() call assert_equal("foo\rbar", foo) " pasting more than 40 bytes - exe "norm Q\<PasteStart>0000000000000000000000000000000000000000000000000000000000000000000000\<C-C>" + exe "norm Q\<PasteStart>s/.*/0000000000000000000000000000000000000000000000000000000000000000/\<C-C>" endfunc func Test_paste_onechar() diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim index 7da310e167..33af374f2e 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -913,6 +913,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. @@ -935,6 +942,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']) @@ -1180,6 +1218,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& @@ -1344,4 +1384,124 @@ 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', {}) + + " issue #15095 wrong select + call term_sendkeys(buf, "\<ESC>:set completeopt=fuzzy,menu\<CR>") + call TermWait(buf) + call term_sendkeys(buf, "S hello helio hero h\<C-X>\<C-P>") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_highlights_10', {}) + + call term_sendkeys(buf, "\<ESC>S hello helio hero h\<C-X>\<C-P>\<C-P>") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_highlights_11', {}) + + 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_popupwin.vim b/src/testdir/test_popupwin.vim index a397f70752..64aa654cf7 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -2499,6 +2499,88 @@ func Test_popup_settext_null() call popup_close(id) endfunc +func Test_popup_setbuf() + CheckScreendump + + let lines =<< trim END + let opts = #{wrap: 0} + let p = popup_create('test', opts) + let buf = bufnr('%') + END + + call writefile(lines, 'XtestPopupSetBuf', 'D') + let buf = RunVimInTerminal('-S XtestPopupSetBuf', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popup_setbuf_01', {}) + + " Setting to an non-existing buffer doesn't do anything + call term_sendkeys(buf, ":call popup_setbuf(p, 'foobar.txt')\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_02', {}) + + " Error + call term_sendkeys(buf, ":call popup_setbuf(p, ['a','b','c'])\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_03', {}) + + " Set to help window + call term_sendkeys(buf, ":help\<CR>") + call term_sendkeys(buf, ":call popup_setbuf(p, 'help.txt')\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_04', {}) + + " Setting back to original buffer + call term_sendkeys(buf, ":call popup_setbuf(p, buf)\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {}) + + " use method + call term_sendkeys(buf, ":echo p->popup_setbuf('help.txt')\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_06', {}) + + call term_sendkeys(buf, ":echo p->popup_setbuf(buf)\<CR>") + call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {}) + + " clean up + call StopVimInTerminal(buf) +endfunc + +func Test_popup_setbuf_terminal() + CheckFeature terminal + + " Check Terminal Feature + let termbuf = term_start(&shell, #{hidden: 1}) + " Wait for shell to start + call WaitForAssert({-> assert_equal("run", job_status(term_getjob(termbuf)))}) + + let popup = popup_create('test', {}) + call assert_true(popup->popup_setbuf(termbuf)) + call popup_close(popup) + + let popup1 = popup_create(termbuf, #{minwidth: 40, minheight: 10, border: []}) + + let popup = popup_create('test', {}) + try + call assert_fails(call popup_setbuf(popup, termbuf)) + catch + endtry + call popup_close(popup) + call popup_close(popup1) + call assert_equal([], popup_list()) + " Close the terminal + call term_sendkeys(termbuf, "exit\<CR>") + " Wait for shell to exit + call WaitForAssert({-> assert_equal("dead", job_status(term_getjob(termbuf)))}) +endfunc + +func Test_popup_setbuf_null() + let id = popup_create('', {}) + call assert_false(popup_setbuf(id, -1)) + call popup_close(id) + + let id = popup_create('', {}) + call assert_true(popup_setbuf(id, test_null_string())) + call assert_true(popup_setbuf(id, '')) + call popup_close(id) + + call assert_false(popup_setbuf(id, 0)) +endfunc + func Test_popup_hidden() new diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim index 69c2943aaf..94e4f475c0 100644 --- a/src/testdir/test_put.vim +++ b/src/testdir/test_put.vim @@ -168,10 +168,6 @@ func Test_very_large_count() endfunc func Test_very_large_count_64bit() - if v:sizeoflong < 8 - throw 'Skipped: only works with 64 bit long ints' - endif - new let @" = repeat('x', 100) call assert_fails('norm 999999999p', 'E1240:') @@ -188,10 +184,6 @@ func Test_very_large_count_block() endfunc func Test_very_large_count_block_64bit() - if v:sizeoflong < 8 - throw 'Skipped: only works with 64 bit long ints' - endif - new call setline(1, repeat('x', 100)) exe "norm \<C-V>$y" diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index c784a2da59..47b9b4703d 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -893,7 +893,7 @@ func Test_helpgrep() endfunc def Test_helpgrep_vim9_restore_cpo() - assert_equal('aABceFs', &cpo) + assert_equal('aABceFsz', &cpo) var rtp_save = &rtp var dir = 'Xruntime/after' @@ -905,7 +905,7 @@ def Test_helpgrep_vim9_restore_cpo() cwindow silent helpgrep grail - assert_equal('aABceFs', &cpo) + assert_equal('aABceFsz', &cpo) &rtp = rtp_save cclose helpclose @@ -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_registers.vim b/src/testdir/test_registers.vim index 1d377bdd41..b2261d4d6c 100644 --- a/src/testdir/test_registers.vim +++ b/src/testdir/test_registers.vim @@ -261,6 +261,19 @@ func Test_zz_recording_with_select_mode_utf8_gui() call Run_test_recording_with_select_mode_utf8() endfunc +func Test_recording_with_super_mod() + if "\<D-j>"[-1:] == '>' + throw 'Skipped: <D- modifier not supported' + endif + + nnoremap <D-j> <Ignore> + let s = repeat("\<D-j>", 1000) + " This used to crash Vim + call feedkeys($'qr{s}q', 'tx') + call assert_equal(s, @r) + nunmap <D-j> +endfunc + " Test for executing the last used register (@) func Test_last_used_exec_reg() " Test for the @: command diff --git a/src/testdir/test_remote.vim b/src/testdir/test_remote.vim index ae931fd291..fd8b0af240 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 @@ -76,4 +76,49 @@ func Test_remote_servername() close endfunc +func Test_remote_servername_shellslash() + " Note this test does not currently run on Windows + " because: + " 1) we cannot run the gui version of Vim inside a terminal + " 2) Running Windows vim.exe inside a terminal would work, but is + " disabled because of the limited colors inside the default Windows + " console (see CanRunVimInTerminal in term_util.vim) + CheckRunVimInTerminal + CheckMSWindows + + " That is the file we want the server to open, + " despite the wildignore setting + call mkdir(expand('~/remote/'), 'pD') + call writefile(range(1, 20), expand('~/remote/XTEST.txt'), 'D') + " just a dummy file, so that the ':wq' further down is successful + call writefile(range(1, 20), 'Xdummy.log', 'D') + + " Run Vim in a terminal and open a terminal window to run Vim in. + let lines =<< trim END + set shellslash + cd ~/remote + END + call writefile(lines, 'XRemoteEditing1.vim', 'D') + let buf = RunVimInTerminal('--servername XVIMTEST -S XRemoteEditing1.vim Xdummy.log', {'rows': 10}) + call TermWait(buf) + + " wildignore setting should be ignored and the XVIMTEST server should now + " open XTEST.txt, if wildignore setting is not ignored, the server + " will continue with the Xdummy.log file + let buf2 = RunVimInTerminal('--servername XVIMTEST --remote-silent ~/remote/XTEST.txt', {'rows': 5, 'wait_for_ruler': 0}) + " job should be no-longer running, so we can just close it + exe buf2 .. 'bw!' + + call term_sendkeys(buf, ":pwd\<CR>") + call WaitForAssert({-> assert_match('remote/$', term_getline(buf, 10))}, 1000) + call TermWait(buf) + call term_sendkeys(buf, ":q!\<CR>") + call TermWait(buf) + if term_getstatus(buf) == 'running' + call StopVimInTerminal(buf) + endif + bw! + close +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim index cda9bf0d78..1b60019c3c 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_selectmode.vim b/src/testdir/test_selectmode.vim index bf1b52b325..63aa0b9a19 100644 --- a/src/testdir/test_selectmode.vim +++ b/src/testdir/test_selectmode.vim @@ -321,4 +321,20 @@ func Test_ins_ctrl_o_in_insert_mode_resets_selectmode() bwipe! endfunc +" Test that an :lmap mapping for a printable keypad key is applied when typing +" it in Select mode. +func Test_selectmode_keypad_lmap() + new + lnoremap <buffer> <kPoint> ??? + lnoremap <buffer> <kEnter> !!! + setlocal iminsert=1 + call setline(1, 'abcdef') + call feedkeys("gH\<kPoint>\<Esc>", 'tx') + call assert_equal(['???'], getline(1, '$')) + call feedkeys("gH\<kEnter>\<Esc>", 'tx') + call assert_equal(['!!!'], getline(1, '$')) + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_shell.vim b/src/testdir/test_shell.vim index 7d91dff358..2ac559676f 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 59646308e9..0c41692a06 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_signs.vim b/src/testdir/test_signs.vim index 0d76d7a445..7f53d62daf 100644 --- a/src/testdir/test_signs.vim +++ b/src/testdir/test_signs.vim @@ -245,7 +245,7 @@ func Test_sign_completion() call assert_equal('"sign define jump list place undefine unplace', @:) call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_equal('"sign define Sign culhl= icon= linehl= numhl= text= texthl=', @:) + call assert_equal('"sign define Sign culhl= icon= linehl= numhl= priority= text= texthl=', @:) for hl in ['culhl', 'linehl', 'numhl', 'texthl'] call feedkeys(":sign define Sign "..hl.."=Spell\<C-A>\<C-B>\"\<CR>", 'tx') @@ -1231,6 +1231,25 @@ func Test_sign_priority() call sign_define("sign1", attr) call sign_define("sign2", attr) call sign_define("sign3", attr) + let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search', 'priority': 60} + call sign_define("sign4", attr) + + " Test for :sign list + let a = execute('sign list') + call assert_equal("\nsign sign1 text==> linehl=Search texthl=Search\n" . + \ "sign sign2 text==> linehl=Search texthl=Search\n" . + \ "sign sign3 text==> linehl=Search texthl=Search\n" . + \ "sign sign4 text==> priority=60 linehl=Search texthl=Search", a) + + " Test for sign_getdefined() + let s = sign_getdefined() + call assert_equal([ + \ {'name': 'sign1', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'}, + \ {'name': 'sign2', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'}, + \ {'name': 'sign3', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'}, + \ {'name': 'sign4', 'priority': 60, 'texthl': 'Search', 'linehl': 'Search', + \ 'text': '=>'}], + \ s) " Place three signs with different priority in the same line call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') @@ -1585,6 +1604,25 @@ func Test_sign_priority() call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a) + call sign_unplace('*') + + " Test for sign with default priority. + call sign_place(1, 'g1', 'sign4', 'Xsign', {'lnum' : 3}) + sign place 2 line=5 name=sign4 group=g1 file=Xsign + + let s = sign_getplaced('Xsign', {'group' : '*'}) + call assert_equal([ + \ {'id' : 1, 'name' : 'sign4', 'lnum' : 3, 'group' : 'g1', + \ 'priority' : 60}, + \ {'id' : 2, 'name' : 'sign4', 'lnum' : 5, 'group' : 'g1', + \ 'priority' : 60}], + \ s[0].signs) + + let a = execute('sign place group=g1') + call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" . + \ " line=3 id=1 group=g1 name=sign4 priority=60\n" . + \ " line=5 id=2 group=g1 name=sign4 priority=60\n", a) + call sign_unplace('*') call sign_undefine() enew | only diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim index 1ddcd83d51..692e191a3c 100644 --- a/src/testdir/test_spell.vim +++ b/src/testdir/test_spell.vim @@ -5,6 +5,7 @@ source check.vim CheckFeature spell source screendump.vim +source view_util.vim func TearDown() set nospell @@ -300,6 +301,20 @@ func Test_compl_with_CTRL_X_CTRL_K_using_spell() set spell& spelllang& dictionary& ignorecase& endfunc +func Test_compl_with_CTRL_X_s() + new + set spell spelllang=en_us showmode + inoremap <buffer><F2> <Cmd>let g:msg = Screenline(&lines)<CR> + + call feedkeys("STheatre\<C-X>s\<F2>\<C-Y>\<Esc>", 'tx') + call assert_equal(['Theater'], getline(1, '$')) + call assert_match('(^S^N^P)', g:msg) + + bwipe! + set spell& spelllang& showmode& + unlet g:msg +endfunc + func Test_spellrepall() new set spell diff --git a/src/testdir/test_spellrare.vim b/src/testdir/test_spellrare.vim new file mode 100644 index 0000000000..ceb35cbd17 --- /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 7c2bbb4767..afdc104d7c 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_tabpage.vim b/src/testdir/test_tabpage.vim index 3624790e3e..1a40567085 100644 --- a/src/testdir/test_tabpage.vim +++ b/src/testdir/test_tabpage.vim @@ -965,6 +965,64 @@ func Test_tabpage_alloc_failure() call assert_equal(1, tabpagenr('$')) endfunc +func Test_tabpage_tabclose() + " Default behaviour, move to the right. + call s:reconstruct_tabpage_for_test(6) + norm! 4gt + setl tcl= + tabclose + call assert_equal("n3", bufname()) + + " Move to the left. + call s:reconstruct_tabpage_for_test(6) + norm! 4gt + setl tcl=left + tabclose + call assert_equal("n1", bufname()) + + " Move to the last used tab page. + call s:reconstruct_tabpage_for_test(6) + norm! 5gt + norm! 2gt + setl tcl=uselast + tabclose + call assert_equal("n3", bufname()) + + " Same, but the last used tab page is invalid. Move to the right. + call s:reconstruct_tabpage_for_test(6) + norm! 5gt + norm! 3gt + setl tcl=uselast + tabclose 5 + tabclose! + call assert_equal("n2", bufname()) + + " Same, but the last used tab page is invalid. Move to the left. + call s:reconstruct_tabpage_for_test(6) + norm! 5gt + norm! 3gt + setl tcl=uselast,left + tabclose 5 + tabclose! + call assert_equal("n0", bufname()) + + " Move left when moving right is not possible. + call s:reconstruct_tabpage_for_test(6) + setl tcl= + norm! 6gt + tabclose + call assert_equal("n3", bufname()) + + " Move right when moving left is not possible. + call s:reconstruct_tabpage_for_test(6) + setl tcl=left + norm! 1gt + tabclose + call assert_equal("n0", bufname()) + + setl tcl& +endfunc + " this was giving ml_get errors func Test_tabpage_last_line() enew diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim index 2abf1f6595..c2419375a0 100644 --- a/src/testdir/test_tagjump.vim +++ b/src/testdir/test_tagjump.vim @@ -958,8 +958,63 @@ func Test_tag_stack() call settagstack(1, {'items' : []}) call assert_fails('pop', 'E73:') + " References to wiped buffer are deleted. + for i in range(10, 20) + edit Xtest + exe "tag var" .. i + endfor + edit Xtest + + let t = gettagstack() + call assert_equal(11, t.length) + call assert_equal(12, t.curidx) + + bwipe! + + let t = gettagstack() + call assert_equal(0, t.length) + call assert_equal(1, t.curidx) + + " References to wiped buffer are deleted with multiple tabpages. + let w1 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + new + let w2 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + tabnew + let w3 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + new + let w4 = win_getid() + call settagstack(1, {'items' : []}) + for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor + enew + + for w in [w1, w2, w3, w4] + let t = gettagstack(w) + call assert_equal(11, t.length) + call assert_equal(12, t.curidx) + endfor + + bwipe! Xtest + + for w in [w1, w2, w3, w4] + let t = gettagstack(w) + call assert_equal(0, t.length) + call assert_equal(1, t.curidx) + endfor + + %bwipe! set tags& - %bwipe endfunc " Test for browsing multiple matching tags @@ -1560,4 +1615,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_taglist.vim b/src/testdir/test_taglist.vim index 2dd236683b..c5c7df2a9c 100644 --- a/src/testdir/test_taglist.vim +++ b/src/testdir/test_taglist.vim @@ -100,9 +100,9 @@ func Test_tagfiles() help let tf = tagfiles() - " if 'helplang includes another language, then we may find - " 2 tagfiles (e.g.: for EN and RU) - " we may need to adjust this, if further translated help files are included + " If 'helplang' includes another language, then we may find 2 tagfiles + " (e.g.: for EN and RU). + " We may need to adjust this, if further translated help files are included. call assert_inrange(1, 2, len(tf)) call assert_equal(fnamemodify(expand('$VIMRUNTIME/doc/tags'), ':p:gs?\\?/?'), \ fnamemodify(tf[0], ':p:gs?\\?/?')) @@ -127,6 +127,47 @@ func Test_tagsfile_without_trailing_newline() set tags& endfunc +" Check that specifying a stop directory in 'tags' works properly. +func Test_tagfiles_stopdir() + let save_cwd = getcwd() + + call mkdir('Xtagsdir1/Xtagsdir2/Xtagsdir3', 'pR') + call writefile([], 'Xtagsdir1/Xtags', 'D') + + cd Xtagsdir1/ + let &tags = './Xtags;' .. fnamemodify('..', ':p') + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir2/ + let &tags = './Xtags;' .. fnamemodify('..', ':p') + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir3/ + let &tags = './Xtags;' .. fnamemodify('..', ':p') + call assert_equal(0, len(tagfiles())) + + let &tags = './Xtags;../' + call assert_equal(0, len(tagfiles())) + + cd .. + call assert_equal(1, len(tagfiles())) + + cd .. + call assert_equal(1, len(tagfiles())) + + let &tags = './Xtags;..' + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir2/ + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir3/ + call assert_equal(0, len(tagfiles())) + + set tags& + call chdir(save_cwd) +endfunc + " Test for ignoring comments in a tags file func Test_tagfile_ignore_comments() call writefile([ diff --git a/src/testdir/test_termdebug.vim b/src/testdir/test_termdebug.vim index 68bffd4b28..fe5ed89dc2 100644 --- a/src/testdir/test_termdebug.vim +++ b/src/testdir/test_termdebug.vim @@ -123,13 +123,13 @@ func Test_termdebug_basic() " 60 is approx spaceBuffer * 3 if winwidth(0) <= 78 + 60 Var - call assert_equal(winnr(), winnr('$')) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]]) + call assert_equal(winnr('$'), winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout()) let cn += 1 bw! Asm - call assert_equal(winnr(), winnr('$')) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]]) + call assert_equal(winnr('$'), winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout()) let cn += 1 bw! endif @@ -138,16 +138,16 @@ func Test_termdebug_basic() let winw = winwidth(0) Var if winwidth(0) < winw - call assert_equal(winnr(), winnr('$') - 1) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]]) + call assert_equal(winnr('$') - 1, winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout()) let cn += 1 bw! endif let winw = winwidth(0) Asm if winwidth(0) < winw - call assert_equal(winnr(), winnr('$') - 1) - call assert_equal(winlayout(), ['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]]) + call assert_equal(winnr('$') - 1, winnr()) + call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout()) let cn += 1 bw! endif @@ -160,6 +160,18 @@ func Test_termdebug_basic() call WaitForAssert({-> assert_equal(1, winnr('$'))}) call assert_equal([], sign_getplaced('', #{group: 'TermDebug'})[0].signs) + for use_prompt in [v:true, v:false] + let g:termdebug_config = {} + let g:termdebug_config['use_prompt'] = use_prompt + TermdebugCommand ./XTD_basic arg args + call WaitForAssert({-> assert_equal(3, winnr('$'))}) + wincmd t + quit! + redraw! + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + unlet g:termdebug_config + endfor + call s:cleanup_files(bin_name) %bw! endfunc @@ -230,26 +242,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,46 +270,201 @@ 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! + + " -- Test that local-buffer mappings are restored in the correct buffers -- + " local mappings for foo + file foo nnoremap <buffer> K :echom "bK"<cr> nnoremap <buffer> - :echom "b-"<cr> nnoremap <buffer> + :echom "b+"<cr> + + " no mappings for 'bar' + enew + file bar + + " Start termdebug from foo + buffer foo Termdebug call WaitForAssert({-> assert_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>') + + Source + buffer bar + call assert_false(maparg('K', 'n', 0, 1)->empty()) + call assert_false(maparg('-', 'n', 0, 1)->empty()) + call assert_false(maparg('+', 'n', 0, 1)->empty()) + call assert_true(maparg('K', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('-', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('+', 'n', 0, 1).buffer->empty()) wincmd t quit! redraw! call WaitForAssert({-> assert_equal(1, winnr('$'))}) - 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>') + " Termdebug session ended. Buffer 'bar' shall have no mappings + call assert_true(bufname() ==# 'bar') + call assert_false(maparg('K', 'n', 0, 1)->empty()) + call assert_false(maparg('-', 'n', 0, 1)->empty()) + call assert_false(maparg('+', 'n', 0, 1)->empty()) + call assert_true(maparg('K', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('-', 'n', 0, 1).buffer->empty()) + call assert_true(maparg('+', 'n', 0, 1).buffer->empty()) + + " Buffer 'foo' shall have the same mapping as before running the termdebug + " session + buffer foo + call assert_true(bufname() ==# 'foo') + call assert_true(maparg('K', 'n', 0, 1).buffer) + call assert_true(maparg('-', 'n', 0, 1).buffer) + call assert_true(maparg('+', 'n', 0, 1).buffer) + call assert_equal(':echom "bK"<cr>', maparg('K', 'n', 0, 1).rhs) + + nunmap K + nunmap + + nunmap - %bw! endfunc +function Test_termdebug_save_restore_variables() + " saved mousemodel + let &mousemodel='' + + " saved keys + nnoremap K :echo "hello world!"<cr> + let expected_map_K = maparg('K', 'n', 0 , 1) + nnoremap + :echo "hello plus!"<cr> + let expected_map_plus = maparg('+', 'n', 0 , 1) + let expected_map_minus = {} + + " saved &columns + let expected_columns = &columns + + " We want termdebug to overwrite 'K' map but not '+' map. + let g:termdebug_config = {} + let g:termdebug_config['map_K'] = v:true + + Termdebug + call WaitForAssert({-> assert_equal(3, winnr('$'))}) + call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')}) + wincmd t + quit! + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + + call assert_true(empty(&mousemodel)) + + call assert_true(empty(expected_map_minus)) + call assert_equal(expected_map_K.rhs, maparg('K', 'n', 0, 1).rhs) + call assert_equal(expected_map_plus.rhs, maparg('+', 'n', 0, 1).rhs) + + call assert_equal(expected_columns, &columns) + + nunmap K + nunmap + + unlet g:termdebug_config +endfunction + +function Test_termdebug_sanity_check() + " Test if user has filename/folders with wrong names + let g:termdebug_config = {} + let s:dict = {'disasm_window': 'Termdebug-asm-listing', 'use_prompt': 'gdb', 'variables_window': 'Termdebug-variables-listing'} + + for key in keys(s:dict) + let s:filename = s:dict[key] + let g:termdebug_config[key] = v:true + let s:error_message = "You have a file/folder named '" .. s:filename .. "'" + + " Write dummy file with bad name + call writefile(['This', 'is', 'a', 'test'], s:filename) + Termdebug + call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)}) + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + + call delete(s:filename) + call remove(g:termdebug_config, key) + endfor + + unlet g:termdebug_config +endfunction + +function Test_termdebug_double_termdebug_instances() + let s:error_message = 'Terminal debugger already running, cannot run two' + Termdebug + call WaitForAssert({-> assert_equal(3, winnr('$'))}) + Termdebug + call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)}) + wincmd t + quit! + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + :%bw! +endfunction + +function Test_termdebug_config_types() + " TODO Remove the deprecated features after 1 Jan 2025. + let g:termdebug_config = {} + let s:error_message = 'Deprecation Warning:' + call assert_true(maparg('K', 'n', 0, 1)->empty()) + + for key in ['disasm_window', 'variables_window', 'map_K'] + for val in [0, 1, v:true, v:false] + let g:termdebug_config[key] = val + Termdebug + + " Type check: warning is displayed + if typename(val) == 'number' + call WaitForAssert({-> assert_true(execute('messages') =~ s:error_message)}) + endif + + " Test on g:termdebug_config keys + if val && key != 'map_K' + call WaitForAssert({-> assert_equal(4, winnr('$'))}) + call remove(g:termdebug_config, key) + else + call WaitForAssert({-> assert_equal(3, winnr('$'))}) + endif + + " Test on mapping + if key == 'map_K' + if val + call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs) + else + call assert_true(maparg('K', 'n', 0, 1)->empty()) + endif + endif + + " Shutoff termdebug + wincmd t + quit! + call WaitForAssert({-> assert_equal(1, winnr('$'))}) + :%bw! + + endfor + endfor + + unlet g:termdebug_config +endfunction + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim index 223bcc5378..3cca1b05cb 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 a9cffd0e6f..e31ea22053 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 @@ -1312,4 +1312,28 @@ func Test_textwdith_overflow() bw! endfunc +func Test_breakindent_reformat() + " Make sure textformatting uses the full width + " of the textwidth and does not consider the indent + " from breakindent into account when calculating the + " line length. Should break at tw 78 and not at 70 + CheckOption breakindent + new + 80vnew + 39vnew + setl ai breakindent tw=78 + let lorem = [ + \ ' Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam luctus', + \ ' lectus sodales, dictum augue vel, molestie augue. Duis sit amet', + \ ' rhoncus justo. Nullam posuere risus semper magna commodo scelerisque.', + \ ' Duis et venenatis sem. In rhoncus augue sed tempor mattis. Mauris id', + \ ' aliquet odio.'] + call setline(1, lorem) + norm! gqap + call assert_equal(lorem, getline(1, '$')) + bw! + bw! + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_textobjects.vim b/src/testdir/test_textobjects.vim index d5e772db50..2622b06a4a 100644 --- a/src/testdir/test_textobjects.vim +++ b/src/testdir/test_textobjects.vim @@ -201,6 +201,18 @@ func Test_string_html_objects() normal! 2k0vaty call assert_equal("<div><div\nattr=\"attr\"\n></div></div>", @", e) + " tag, that includes a > in some attribute + let t = "<div attr=\"attr >> foo >> bar \">Hello</div>" + $put =t + normal! fHyit + call assert_equal("Hello", @", e) + + " tag, that includes a > in some attribute + let t = "<div attr='attr >> foo >> bar '>Hello 123</div>" + $put =t + normal! fHyit + call assert_equal("Hello 123", @", e) + set quoteescape& " this was going beyond the end of the line diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index 2bf28349d7..57277f79e2 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2901,6 +2901,10 @@ func Test_prop_inserts_text_before_double_width_wrap() call writefile(lines, 'XscriptPropsBeforeDoubleWidthWrap', 'D') let buf = RunVimInTerminal('-S XscriptPropsBeforeDoubleWidthWrap', #{rows: 3, cols: 50}) call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_1', {}) + call term_sendkeys(buf, 'g0') + call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_2', {}) + call term_sendkeys(buf, ":set showbreak=+++\<CR>") + call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_double_width_wrap_3', {}) call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_tohtml.vim b/src/testdir/test_tohtml.vim new file mode 100644 index 0000000000..a1c8572732 --- /dev/null +++ b/src/testdir/test_tohtml.vim @@ -0,0 +1,72 @@ +" Tests for Vim :TOhtml + +source check.vim + +func s:setup_basic(src_name) + let lines =<< trim END + #include <stdio.h> + #include <stdlib.h> + + int isprime(int n) + { + if (n <= 1) + return 0; + + for (int i = 2; i <= n / 2; i++) + if (n % i == 0) + return 0; + + return 1; + } + + int main(int argc, char *argv[]) + { + int n = 7; + + printf("%d is %s prime\n", n, isprime(n) ? "a" : "not a"); + + return 0; + } + END + call writefile(lines, a:src_name) + exe 'edit ' . a:src_name + TOhtml + write +endfunc + +func s:cleanup_basic(src_name) + call delete(a:src_name) + call delete(a:src_name . ".html") +endfunc + +source $VIMRUNTIME/plugin/tohtml.vim + +func Test_tohtml_basic() + let src_name = "Test_tohtml_basic.c" + call s:setup_basic(src_name) + let expected = readfile("samples/" . src_name . ".html") + let actual = readfile(src_name . ".html") + call assert_equal(expected[0:3], actual[0:3]) + " Ignore the title + call assert_equal(expected[5:11], actual[5:11]) + " Ignore pre and body css + call assert_equal(expected[14:], actual[14:]) + call s:cleanup_basic(src_name) +endfunc + +func Test_tohtml_basic_no_css() + let g:html_use_css = 0 + let src_name = "Test_tohtml_basic_no_css.c" + call s:setup_basic(src_name) + let expected = readfile("samples/" . src_name . ".html") + let actual = readfile(src_name . ".html") + call assert_equal(expected[0:3], actual[0:3]) + " Ignore the title + call assert_equal(expected[5:10], actual[5:10]) + " Ignore body's inline css + call assert_equal(expected[12:], actual[12:]) + call s:cleanup_basic(src_name) + unlet g:html_use_css +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim index df0abd354c..0f46240db5 100644 --- a/src/testdir/test_utf8.vim +++ b/src/testdir/test_utf8.vim @@ -300,6 +300,27 @@ func Test_setcellwidths_dump() call StopVimInTerminal(buf) endfunc +" Test setcellwidths() on characters that are not targets of 'ambiwidth'. +func Test_setcellwidths_with_non_ambiwidth_character_dump() + CheckRunVimInTerminal + + let lines =<< trim END + call setline(1, [repeat("\u279c", 60), repeat("\u279c", 60)]) + set ambiwidth=single + END + call writefile(lines, 'XCellwidthsWithNonAmbiwidthCharacter', 'D') + let buf = RunVimInTerminal('-S XCellwidthsWithNonAmbiwidthCharacter', {'rows': 6, 'cols': 50}) + call term_sendkeys(buf, ":call setcellwidths([[0x279c, 0x279c, 1]])\<CR>") + call term_sendkeys(buf, ":echo\<CR>") + call VerifyScreenDump(buf, 'Test_setcellwidths_with_non_ambiwidth_character_dump_1', {}) + + call term_sendkeys(buf, ":call setcellwidths([[0x279c, 0x279c, 2]])\<CR>") + call term_sendkeys(buf, ":echo\<CR>") + call VerifyScreenDump(buf, 'Test_setcellwidths_with_non_ambiwidth_character_dump_2', {}) + + call StopVimInTerminal(buf) +endfunc + " For some reason this test causes Test_customlist_completion() to fail on CI, " so run it as the last test. func Test_zz_ambiwidth_hl_dump() @@ -321,7 +342,6 @@ func Test_zz_ambiwidth_hl_dump() call term_sendkeys(buf, ":echo\<CR>") call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {}) - if 0 " Enable after #14539 is fixed call term_sendkeys(buf, ":call setcellwidths([[0x2103, 0x2103, 2]])\<CR>") call term_sendkeys(buf, ":echo\<CR>") call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_2', {}) @@ -329,7 +349,6 @@ func Test_zz_ambiwidth_hl_dump() call term_sendkeys(buf, ":call setcellwidths([[0x2103, 0x2103, 1]])\<CR>") call term_sendkeys(buf, ":echo\<CR>") call VerifyScreenDump(buf, 'Test_ambiwidth_hl_dump_1', {}) - endif call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_vartabs.vim b/src/testdir/test_vartabs.vim index e15a072f72..bae00dd057 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 4296c37092..bb08943ffa 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 442d375feb..c8baaf687c 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -66,16 +66,16 @@ def Test_abs() assert_equal(0, abs(0)) assert_equal(2, abs(-2)) assert_equal(3, abs(3)) - v9.CheckDefAndScriptFailure(['abs("text")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['abs("text")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal(0, abs(0)) assert_equal(2.0, abs(-2.0)) assert_equal(3.0, abs(3.0)) enddef def Test_add() - v9.CheckDefAndScriptFailure(['add({}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1226: List or Blob required for argument 1']) - v9.CheckDefAndScriptFailure(['add([])'], 'E119:') - v9.CheckDefExecFailure([ + v9.CheckSourceDefAndScriptFailure(['add({}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1226: List or Blob required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['add([])'], 'E119:') + v9.CheckSourceDefExecFailure([ 'var ln: list<number> = [1]', 'add(ln, "a")'], 'E1012: Type mismatch; expected number but got string') @@ -91,7 +91,7 @@ def Test_add() enddef TryChange() END - v9.CheckScriptFailure(lines, 'E741:') + v9.CheckSourceScriptFailure(lines, 'E741:') enddef def Test_add_blob() @@ -107,18 +107,18 @@ def Test_add_blob() var b: blob add(b, "x") END - v9.CheckDefFailure(lines, 'E1012:', 2) + v9.CheckSourceDefFailure(lines, 'E1012:', 2) lines =<< trim END add(test_null_blob(), 123) END - v9.CheckDefExecAndScriptFailure(lines, 'E1131:', 1) + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1131:', 1) lines =<< trim END var b: blob = test_null_blob() add(b, 123) END - v9.CheckDefExecFailure(lines, 'E1131:', 2) + v9.CheckSourceDefExecFailure(lines, 'E1131:', 2) # Getting variable with NULL blob fails lines =<< trim END @@ -126,7 +126,7 @@ def Test_add_blob() var b: blob = test_null_blob() add(b, 123) END - v9.CheckScriptFailure(lines, 'E1131:', 3) + v9.CheckSourceScriptFailure(lines, 'E1131:', 3) enddef def Test_add_list() @@ -138,18 +138,18 @@ def Test_add_list() var l: list<number> add(l, "x") END - v9.CheckDefFailure(lines, 'E1012:', 2) + v9.CheckSourceDefFailure(lines, 'E1012:', 2) lines =<< trim END add(test_null_list(), 123) END - v9.CheckDefExecAndScriptFailure(lines, 'E1130:', 1) + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1130:', 1) lines =<< trim END var l: list<number> = test_null_list() add(l, 123) END - v9.CheckDefExecFailure(lines, 'E1130:', 2) + v9.CheckSourceDefExecFailure(lines, 'E1130:', 2) # Getting an uninitialized variable allocates a new list at script level lines =<< trim END @@ -157,7 +157,7 @@ def Test_add_list() var l: list<number> add(l, 123) END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) # Adding to a variable set to a NULL list fails lines =<< trim END @@ -165,21 +165,21 @@ def Test_add_list() var l: list<number> = test_null_list() add(l, 123) END - v9.CheckScriptFailure(lines, 'E1130:', 3) + v9.CheckSourceScriptFailure(lines, 'E1130:', 3) lines =<< trim END vim9script var l: list<string> = ['a'] l->add(123) END - v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3) + v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3) lines =<< trim END vim9script var l: list<string> l->add(123) END - v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3) + v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 3) enddef def Test_add_const() @@ -187,26 +187,26 @@ def Test_add_const() const l = [1, 2] add(l, 3) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') lines =<< trim END final l = [1, 2] add(l, 3) assert_equal([1, 2, 3], l) END - v9.CheckDefSuccess(lines) + v9.CheckSourceDefSuccess(lines) lines =<< trim END const b = 0z0102 add(b, 0z03) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob') enddef def Test_and() - v9.CheckDefAndScriptFailure(['and("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['and(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['and("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['and(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_append() @@ -224,12 +224,12 @@ def Test_append() assert_equal("{'a': 10}", getline(1)) append(0, function('min')) assert_equal("function('min')", getline(1)) - v9.CheckDefAndScriptFailure(['append([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['append("", "x")'], 'E1209: Invalid value for a line number') - v9.CheckDefExecAndScriptFailure(['append(".a", "x")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['append([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['append("", "x")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecAndScriptFailure(['append(".a", "x")'], 'E1209: Invalid value for a line number') # only get one error assert_fails('append("''aa", "x")', ['E1209: Invalid value for a line number: "''aa"', 'E1209:']) - v9.CheckDefExecAndScriptFailure(['append(-1, "x")'], 'E966: Invalid line number: -1') + v9.CheckSourceDefExecAndScriptFailure(['append(-1, "x")'], 'E966: Invalid line number: -1') bwipe! enddef @@ -245,12 +245,12 @@ def Test_appendbufline() assert_equal(['0', 'one', '1', 'two', '2', ''], getbufline(bnum, 1, '$')) appendbufline(bnum, 0, 'zero') assert_equal(['zero'], getbufline(bnum, 1)) - v9.CheckDefAndScriptFailure(['appendbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['appendbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1') - v9.CheckDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', "$a", "x")'], 'E1030: Using a String as a Number: "$a"') + v9.CheckSourceDefAndScriptFailure(['appendbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['appendbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1') + v9.CheckSourceDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', "$a", "x")'], 'E1030: Using a String as a Number: "$a"') assert_fails('appendbufline(' .. bnum .. ', "$a", "x")', ['E1030: Using a String as a Number: "$a"', 'E1030:']) - v9.CheckDefAndScriptFailure(['appendbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['appendbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3']) bnum->bufwinid()->win_gotoid() appendbufline('', 0, 'numbers') getline(1)->assert_equal('numbers') @@ -258,80 +258,80 @@ def Test_appendbufline() enddef def Test_argc() - v9.CheckDefAndScriptFailure(['argc("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['argc("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_arglistid() - v9.CheckDefAndScriptFailure(['arglistid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['arglistid(1, "y")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['arglistid("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['arglistid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['arglistid(1, "y")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['arglistid("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_argv() - v9.CheckDefAndScriptFailure(['argv("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['argv(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['argv("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['argv("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['argv(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['argv("x", "y")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_assert_beeps() - v9.CheckDefAndScriptFailure(['assert_beeps(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['assert_beeps(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) enddef def Test_assert_equalfile() - v9.CheckDefAndScriptFailure(['assert_equalfile(1, "f2")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['assert_equalfile("f1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['assert_equalfile("f1", "f2", ["a"])'], ['E1013: Argument 3: type mismatch, expected string but got list<string>', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['assert_equalfile(1, "f2")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['assert_equalfile("f1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['assert_equalfile("f1", "f2", ["a"])'], ['E1013: Argument 3: type mismatch, expected string but got list<string>', 'E1174: String required for argument 3']) enddef def Test_assert_exception() - v9.CheckDefAndScriptFailure(['assert_exception({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['assert_exception("E1:", v:null)'], ['E1013: Argument 2: type mismatch, expected string but got special', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['assert_exception({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['assert_exception("E1:", v:null)'], ['E1013: Argument 2: type mismatch, expected string but got special', 'E1174: String required for argument 2']) enddef def Test_assert_fails() - v9.CheckDefAndScriptFailure(['assert_fails([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['assert_fails("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1222: String or List required for argument 2']) - v9.CheckDefAndScriptFailure(['assert_fails("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) - v9.CheckDefAndScriptFailure(['assert_fails("a", "b", "c", 4, 5)'], ['E1013: Argument 5: type mismatch, expected string but got number', 'E1174: String required for argument 5']) + v9.CheckSourceDefAndScriptFailure(['assert_fails([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['assert_fails("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1222: String or List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['assert_fails("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['assert_fails("a", "b", "c", 4, 5)'], ['E1013: Argument 5: type mismatch, expected string but got number', 'E1174: String required for argument 5']) enddef def Test_assert_inrange() - v9.CheckDefAndScriptFailure(['assert_inrange("a", 2, 3)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['assert_inrange(1, "b", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) - v9.CheckDefAndScriptFailure(['assert_inrange(1, 2, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 3']) - v9.CheckDefAndScriptFailure(['assert_inrange(1, 2, 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['assert_inrange("a", 2, 3)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['assert_inrange(1, "b", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['assert_inrange(1, 2, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['assert_inrange(1, 2, 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) enddef def Test_assert_match() - v9.CheckDefAndScriptFailure(['assert_match({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', '']) - v9.CheckDefAndScriptFailure(['assert_match("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', '']) - v9.CheckDefAndScriptFailure(['assert_match("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', '']) + v9.CheckSourceDefAndScriptFailure(['assert_match({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', '']) + v9.CheckSourceDefAndScriptFailure(['assert_match("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', '']) + v9.CheckSourceDefAndScriptFailure(['assert_match("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', '']) enddef def Test_assert_nobeep() - v9.CheckDefAndScriptFailure(['assert_nobeep(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['assert_nobeep(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) enddef def Test_assert_notmatch() - v9.CheckDefAndScriptFailure(['assert_notmatch({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', '']) - v9.CheckDefAndScriptFailure(['assert_notmatch("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', '']) - v9.CheckDefAndScriptFailure(['assert_notmatch("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', '']) + v9.CheckSourceDefAndScriptFailure(['assert_notmatch({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', '']) + v9.CheckSourceDefAndScriptFailure(['assert_notmatch("a", 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', '']) + v9.CheckSourceDefAndScriptFailure(['assert_notmatch("a", "b", null)'], ['E1013: Argument 3: type mismatch, expected string but got special', '']) enddef def Test_assert_report() - v9.CheckDefAndScriptFailure(['assert_report([1, 2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['assert_report([1, 2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) enddef def Test_autocmd_add() - v9.CheckDefAndScriptFailure(['autocmd_add({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['autocmd_add({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) enddef def Test_autocmd_delete() - v9.CheckDefAndScriptFailure(['autocmd_delete({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['autocmd_delete({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) enddef def Test_autocmd_get() - v9.CheckDefAndScriptFailure(['autocmd_get(10)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['autocmd_get(10)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1']) enddef def Test_balloon_show() @@ -341,8 +341,8 @@ def Test_balloon_show() assert_fails('balloon_show(10)', 'E1222:') assert_fails('balloon_show(true)', 'E1222:') - v9.CheckDefAndScriptFailure(['balloon_show(1.2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['balloon_show({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['balloon_show(1.2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['balloon_show({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) enddef def Test_balloon_split() @@ -354,22 +354,22 @@ enddef def Test_blob2list() assert_equal(['x', 'x'], blob2list(0z1234)->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['blob2list(10)'], ['E1013: Argument 1: type mismatch, expected blob but got number', 'E1238: Blob required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['blob2list(10)'], ['E1013: Argument 1: type mismatch, expected blob but got number', 'E1238: Blob required for argument 1']) enddef def Test_browse() CheckFeature browse - v9.CheckDefAndScriptFailure(['browse(2, "title", "dir", "file")'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['browse(true, 2, "dir", "file")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['browse(true, "title", 3, "file")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) - v9.CheckDefAndScriptFailure(['browse(true, "title", "dir", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['browse(2, "title", "dir", "file")'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['browse(true, 2, "dir", "file")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['browse(true, "title", 3, "file")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['browse(true, "title", "dir", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) enddef def Test_browsedir() if has('browse') - v9.CheckDefAndScriptFailure(['browsedir({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['browsedir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['browsedir({}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['browsedir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) endif enddef @@ -425,8 +425,8 @@ def Test_bufnr() buf = bufnr('Xdummy', true) buf->assert_notequal(-1) exe 'bwipe! ' .. buf - v9.CheckDefAndScriptFailure(['bufnr([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['bufnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['bufnr([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['bufnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) enddef def Test_bufwinid() @@ -452,23 +452,23 @@ def Test_bufwinnr() enddef def Test_byte2line() - v9.CheckDefAndScriptFailure(['byte2line("1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['byte2line([])'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['byte2line("1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['byte2line([])'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1']) byte2line(0)->assert_equal(-1) enddef def Test_byteidx() - v9.CheckDefAndScriptFailure(['byteidx(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['byteidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['byteidx("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['byteidx(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['byteidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['byteidx("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) byteidx('', 0)->assert_equal(0) byteidx('', 1)->assert_equal(-1) enddef def Test_byteidxcomp() - v9.CheckDefAndScriptFailure(['byteidxcomp(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['byteidxcomp("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['byteidxcomp("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['byteidxcomp(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['byteidxcomp("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['byteidxcomp("a", 0, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) enddef def Test_call_call() @@ -488,20 +488,20 @@ def Test_call_call() assert_equal('Inner', g:done) unlet g:done END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) delfunc g:Inner - v9.CheckDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1') - v9.CheckDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1') - v9.CheckDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) - v9.CheckDefAndScriptFailure(['call("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1') + v9.CheckSourceDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1') + v9.CheckSourceDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['call("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) enddef def Test_ch_canread() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_canread(10)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_canread(10)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) endif enddef @@ -509,7 +509,7 @@ def Test_ch_close() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_close("c")'], ['E1013: Argument 1: type mismatch, expected channel but got string', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_close("c")'], ['E1013: Argument 1: type mismatch, expected channel but got string', 'E1217: Channel or Job required for argument 1']) endif enddef @@ -517,7 +517,7 @@ def Test_ch_close_in() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_close_in(true)'], ['E1013: Argument 1: type mismatch, expected channel but got bool', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_close_in(true)'], ['E1013: Argument 1: type mismatch, expected channel but got bool', 'E1217: Channel or Job required for argument 1']) endif enddef @@ -525,8 +525,8 @@ def Test_ch_evalexpr() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_evalexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_evalexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['ch_evalexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_evalexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) endif enddef @@ -534,9 +534,9 @@ def Test_ch_evalraw() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_evalraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_evalraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2']) - v9.CheckDefAndScriptFailure(['ch_evalraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['ch_evalraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_evalraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_evalraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) endif enddef @@ -544,8 +544,8 @@ def Test_ch_getbufnr() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_getbufnr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_getbufnr(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_getbufnr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_getbufnr(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) # test empty string argument for ch_getbufnr() var job: job = job_start(&shell) g:WaitForAssert(() => assert_equal('run', job_status(job))) @@ -558,8 +558,8 @@ def Test_ch_getjob() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_getjob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_getjob({"a": 10})'], ['E1013: Argument 1: type mismatch, expected channel but got dict<number>', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_getjob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_getjob({"a": 10})'], ['E1013: Argument 1: type mismatch, expected channel but got dict<number>', 'E1217: Channel or Job required for argument 1']) assert_equal(0, ch_getjob(test_null_channel())) endif enddef @@ -568,7 +568,7 @@ def Test_ch_info() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_info([1])'], ['E1013: Argument 1: type mismatch, expected channel but got list<number>', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_info([1])'], ['E1013: Argument 1: type mismatch, expected channel but got list<number>', 'E1217: Channel or Job required for argument 1']) endif enddef @@ -576,8 +576,8 @@ def Test_ch_log() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_log(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_log("a", 1)'], ['E1013: Argument 2: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_log(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_log("a", 1)'], ['E1013: Argument 2: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 2']) endif enddef @@ -589,8 +589,8 @@ def Test_ch_logfile() assert_fails('ch_logfile("foo", true)', 'E1174:') ch_logfile('', '')->assert_equal(0) - v9.CheckDefAndScriptFailure(['ch_logfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_logfile("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_logfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_logfile("a", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2']) endif enddef @@ -598,9 +598,9 @@ def Test_ch_open() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_open({"a": 10}, "a")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_open("a", [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) - v9.CheckDefExecAndScriptFailure(['ch_open("")'], 'E475: Invalid argument') + v9.CheckSourceDefAndScriptFailure(['ch_open({"a": 10}, "a")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_open("a", [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['ch_open("")'], 'E475: Invalid argument') endif enddef @@ -608,8 +608,8 @@ def Test_ch_read() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_read(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_read(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_read(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_read(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) endif enddef @@ -617,8 +617,8 @@ def Test_ch_readblob() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_readblob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_readblob(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_readblob(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_readblob(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) endif enddef @@ -626,8 +626,8 @@ def Test_ch_readraw() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_readraw(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_readraw(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_readraw(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_readraw(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) endif enddef @@ -635,8 +635,8 @@ def Test_ch_sendexpr() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_sendexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_sendexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['ch_sendexpr(1, "a")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_sendexpr(test_null_channel(), 1, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) endif enddef @@ -644,9 +644,9 @@ def Test_ch_sendraw() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_sendraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_sendraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2']) - v9.CheckDefAndScriptFailure(['ch_sendraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['ch_sendraw(1, "")'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_sendraw(test_null_channel(), 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_sendraw(test_null_channel(), "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) endif enddef @@ -654,8 +654,8 @@ def Test_ch_setoptions() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_setoptions(1, {})'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_setoptions(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_setoptions(1, {})'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_setoptions(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) endif enddef @@ -663,8 +663,8 @@ def Test_ch_status() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['ch_status(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) - v9.CheckDefAndScriptFailure(['ch_status(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['ch_status(1)'], ['E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ch_status(test_null_channel(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) endif enddef @@ -672,8 +672,8 @@ def Test_char2nr() char2nr('あ', true)->assert_equal(12354) assert_fails('char2nr(true)', 'E1174:') - v9.CheckDefAndScriptFailure(['char2nr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['char2nr("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['char2nr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['char2nr("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) assert_equal(97, char2nr('a', 1)) assert_equal(97, char2nr('a', 0)) assert_equal(97, char2nr('a', true)) @@ -687,10 +687,10 @@ def Test_charclass() enddef def Test_charcol() - v9.CheckDefAndScriptFailure(['charcol(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['charcol({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['charcol(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['charcol("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['charcol(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['charcol({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['charcol(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['charcol("")'], 'E1209: Invalid value for a line number') new setline(1, ['abcdefgh']) cursor(1, 4) @@ -701,10 +701,10 @@ def Test_charcol() enddef def Test_charidx() - v9.CheckDefAndScriptFailure(['charidx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['charidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['charidx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) - v9.CheckDefAndScriptFailure(['charidx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['charidx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['charidx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['charidx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['charidx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4']) charidx('', 0)->assert_equal(0) charidx('', 1)->assert_equal(-1) enddef @@ -714,15 +714,15 @@ def Test_chdir() enddef def Test_cindent() - v9.CheckDefAndScriptFailure(['cindent([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['cindent(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['cindent("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['cindent([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['cindent(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['cindent("")'], 'E1209: Invalid value for a line number') assert_equal(-1, cindent(0)) assert_equal(0, cindent('.')) enddef def Test_clearmatches() - v9.CheckDefAndScriptFailure(['clearmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['clearmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_col() @@ -735,26 +735,26 @@ def Test_col() assert_fails('col(true)', 'E1222:') - v9.CheckDefAndScriptFailure(['col(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['col({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['col(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['col(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['col("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['col(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['col({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['col(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['col(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['col("")'], 'E1209: Invalid value for a line number') bw! enddef def Test_complete() - v9.CheckDefAndScriptFailure(['complete("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['complete(1, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['complete("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['complete(1, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2']) enddef def Test_complete_add() - v9.CheckDefAndScriptFailure(['complete_add([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1223: String or Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['complete_add([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1223: String or Dictionary required for argument 1']) enddef def Test_complete_info() - v9.CheckDefAndScriptFailure(['complete_info("")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['complete_info({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['complete_info("")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['complete_info({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1211: List required for argument 1']) assert_equal({'pum_visible': 0, 'mode': '', 'selected': -1, 'items': []}, complete_info()) assert_equal({'mode': '', 'items': []}, complete_info(['mode', 'items'])) enddef @@ -767,10 +767,10 @@ def Test_confirm() assert_fails('confirm(true)', 'E1174:') assert_fails('confirm("yes", true)', 'E1174:') assert_fails('confirm("yes", "maybe", 2, true)', 'E1174:') - v9.CheckDefAndScriptFailure(['confirm(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['confirm("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['confirm("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['confirm("a", "b", 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['confirm(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['confirm("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['confirm("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['confirm("a", "b", 3, 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) enddef def Test_copy_return_type() @@ -798,7 +798,7 @@ def Test_copy_return_type() var nll: list<list<number>> = [[1, 2]] nll->copy()[0]->extend(['x']) END - v9.CheckDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string> in extend()') + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string> in extend()') var nd: dict<number> = {a: 1, b: 2} assert_equal({a: 1, b: 2, c: 'x'}, nd->copy()->extend({c: 'x'})) @@ -806,7 +806,7 @@ def Test_copy_return_type() var ndd: dict<dict<number>> = {a: {x: 1, y: 2}} ndd->copy()['a']->extend({z: 'x'}) END - v9.CheckDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string> in extend()') + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string> in extend()') # after a deepcopy() the item type can also change var nll: list<list<number>> = [[1, 2]] @@ -822,9 +822,9 @@ enddef def Test_count() count('ABC ABC ABC', 'b', true)->assert_equal(3) count('ABC ABC ABC', 'b', false)->assert_equal(0) - v9.CheckDefAndScriptFailure(['count(10, 1)'], 'E1225: String, List or Dictionary required for argument 1') - v9.CheckDefAndScriptFailure(['count("a", [1], 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) - v9.CheckDefAndScriptFailure(['count("a", [1], 0, "b")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['count(10, 1)'], 'E1225: String, List or Dictionary required for argument 1') + v9.CheckSourceDefAndScriptFailure(['count("a", [1], 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['count("a", [1], 0, "b")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) count([1, 2, 2, 3], 2)->assert_equal(2) count([1, 2, 2, 3], 2, false, 2)->assert_equal(1) count({a: 1.1, b: 2.2, c: 1.1}, 1.1)->assert_equal(2) @@ -833,9 +833,9 @@ enddef def Test_cscope_connection() CheckFeature cscope assert_equal(0, cscope_connection()) - v9.CheckDefAndScriptFailure(['cscope_connection("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['cscope_connection(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['cscope_connection(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['cscope_connection("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['cscope_connection(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['cscope_connection(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) enddef def Test_cursor() @@ -851,35 +851,35 @@ def Test_cursor() var lines =<< trim END cursor('2', 1) END - v9.CheckDefExecAndScriptFailure(lines, 'E1209:') - v9.CheckDefAndScriptFailure(['cursor(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['cursor(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['cursor(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefExecAndScriptFailure(['cursor("", 2)'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1209:') + v9.CheckSourceDefAndScriptFailure(['cursor(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['cursor(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['cursor(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['cursor("", 2)'], 'E1209: Invalid value for a line number') enddef def Test_debugbreak() CheckMSWindows - v9.CheckDefAndScriptFailure(['debugbreak("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['debugbreak("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_deepcopy() - v9.CheckDefAndScriptFailure(['deepcopy({}, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['deepcopy({}, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) enddef def Test_delete() var res: bool = delete('doesnotexist') assert_equal(true, res) - v9.CheckDefAndScriptFailure(['delete(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['delete("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefExecAndScriptFailure(['delete("")'], 'E474: Invalid argument') + v9.CheckSourceDefAndScriptFailure(['delete(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['delete("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['delete("")'], 'E474: Invalid argument') enddef def Test_deletebufline() - v9.CheckDefAndScriptFailure(['deletebufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['deletebufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) - v9.CheckDefAndScriptFailure(['deletebufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['deletebufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['deletebufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['deletebufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3']) new setline(1, ['one', 'two']) deletebufline('', 1) @@ -892,58 +892,58 @@ def Test_deletebufline() enddef def Test_diff_filler() - v9.CheckDefAndScriptFailure(['diff_filler([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['diff_filler(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['diff_filler("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['diff_filler([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['diff_filler(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['diff_filler("")'], 'E1209: Invalid value for a line number') assert_equal(0, diff_filler(1)) assert_equal(0, diff_filler('.')) enddef def Test_diff_hlID() - v9.CheckDefAndScriptFailure(['diff_hlID(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['diff_hlID(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['diff_hlID("", 10)'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['diff_hlID(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['diff_hlID(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['diff_hlID("", 10)'], 'E1209: Invalid value for a line number') enddef def Test_digraph_get() - v9.CheckDefAndScriptFailure(['digraph_get(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefExecAndScriptFailure(['digraph_get("")'], 'E1214: Digraph must be just two characters') + v9.CheckSourceDefAndScriptFailure(['digraph_get(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['digraph_get("")'], 'E1214: Digraph must be just two characters') enddef def Test_digraph_getlist() - v9.CheckDefAndScriptFailure(['digraph_getlist(10)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['digraph_getlist("")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['digraph_getlist(10)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['digraph_getlist("")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) enddef def Test_digraph_set() - v9.CheckDefAndScriptFailure(['digraph_set(10, "a")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['digraph_set("ab", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2']) - v9.CheckDefExecAndScriptFailure(['digraph_set("", "a")'], 'E1214: Digraph must be just two characters') + v9.CheckSourceDefAndScriptFailure(['digraph_set(10, "a")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['digraph_set("ab", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['digraph_set("", "a")'], 'E1214: Digraph must be just two characters') enddef def Test_digraph_setlist() - v9.CheckDefAndScriptFailure(['digraph_setlist("a")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1216: digraph_setlist() argument must be a list of lists with two items']) - v9.CheckDefAndScriptFailure(['digraph_setlist({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1216: digraph_setlist() argument must be a list of lists with two items']) + v9.CheckSourceDefAndScriptFailure(['digraph_setlist("a")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1216: digraph_setlist() argument must be a list of lists with two items']) + v9.CheckSourceDefAndScriptFailure(['digraph_setlist({})'], ['E1013: Argument 1: type mismatch, expected list<string> but got dict<any>', 'E1216: digraph_setlist() argument must be a list of lists with two items']) enddef def Test_echoraw() - v9.CheckDefAndScriptFailure(['echoraw(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['echoraw(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['echoraw(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['echoraw(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) enddef def Test_escape() - v9.CheckDefAndScriptFailure(['escape(10, " ")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['escape(true, false)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['escape("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['escape(10, " ")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['escape(true, false)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['escape("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) assert_equal('a\:b', escape("a:b", ":")) escape('abc', '')->assert_equal('abc') escape('', ':')->assert_equal('') enddef def Test_eval() - v9.CheckDefAndScriptFailure(['eval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['eval(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1']) - v9.CheckDefExecAndScriptFailure(['eval("")'], 'E15: Invalid expression') + v9.CheckSourceDefAndScriptFailure(['eval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['eval(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['eval("")'], 'E15: Invalid expression') assert_equal(2, eval('1 + 1')) enddef @@ -951,8 +951,8 @@ def Test_executable() assert_false(executable("")) assert_false(executable(test_null_string())) - v9.CheckDefExecFailure(['echo executable(123)'], 'E1013:') - v9.CheckDefExecFailure(['echo executable(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo executable(123)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo executable(true)'], 'E1013:') enddef def Test_execute() @@ -960,23 +960,25 @@ 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.CheckDefAndScriptFailure(['execute(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) - v9.CheckDefFailure(['execute([123])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>') - v9.CheckDefExecFailure(['echo execute(["xx", 123])'], 'E492') - v9.CheckDefAndScriptFailure(['execute("xx", 123)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + 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>') + v9.CheckSourceDefExecFailure(['echo execute(["xx", 123])'], 'E492') + v9.CheckSourceDefAndScriptFailure(['execute("xx", 123)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) enddef def Test_exepath() - v9.CheckDefExecFailure(['echo exepath(true)'], 'E1013:') - v9.CheckDefExecFailure(['echo exepath(v:null)'], 'E1013:') - v9.CheckDefExecFailure(['echo exepath("")'], 'E1175:') + v9.CheckSourceDefExecFailure(['echo exepath(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo exepath(v:null)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo exepath("")'], 'E1175:') enddef command DoSomeCommand let g:didSomeCommand = 4 def Test_exists() - v9.CheckDefAndScriptFailure(['exists(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['exists(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) call assert_equal(1, exists('&tabstop')) var lines =<< trim END @@ -985,14 +987,14 @@ def Test_exists() endif endif END - v9.CheckDefFailure(lines, 'E113:') - v9.CheckScriptSuccess(lines) + v9.CheckSourceDefFailure(lines, 'E113:') + v9.CheckSourceScriptSuccess(lines) enddef def Test_exists_compiled() call assert_equal(1, exists_compiled('&tabstop')) - v9.CheckDefAndScriptFailure(['exists_compiled(10)'], ['E1232:', 'E1233:']) - v9.CheckDefAndScriptFailure(['exists_compiled(v:progname)'], ['E1232:', 'E1233:']) + v9.CheckSourceDefAndScriptFailure(['exists_compiled(10)'], ['E1232:', 'E1233:']) + v9.CheckSourceDefAndScriptFailure(['exists_compiled(v:progname)'], ['E1232:', 'E1233:']) if exists_compiled('+newoption') if &newoption == 'ok' @@ -1044,9 +1046,9 @@ def Test_expand() split SomeFile expand('%', true, true)->assert_equal(['SomeFile']) close - v9.CheckDefAndScriptFailure(['expand(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['expand("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) - v9.CheckDefAndScriptFailure(['expand("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['expand(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['expand("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['expand("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) expand('')->assert_equal('') var caught = false @@ -1065,8 +1067,8 @@ def Test_expandcmd() assert_equal("yes", expandcmd("`={a: 'yes'}['a']`")) expandcmd('')->assert_equal('') - v9.CheckDefAndScriptFailure(['expandcmd([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['expandcmd("abc", [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['expandcmd([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['expandcmd("abc", [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) enddef def Test_extend_arg_types() @@ -1093,7 +1095,7 @@ def Test_extend_arg_types() dany->extend({b: 'x'}) assert_equal({a: 0, b: 'x'}, dany) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END assert_equal([1, 2, "x"], extend([1, 2], ["x"])) @@ -1101,17 +1103,17 @@ def Test_extend_arg_types() assert_equal({a: 1, b: "x"}, extend({a: 1}, {b: "x"})) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) - v9.CheckDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E712: Argument of extend() must be a List or Dictionary']) - v9.CheckDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E712: Argument of extend() must be a List or Dictionary']) - v9.CheckDefAndScriptFailure(['var ll = [1, 2]', 'extend(ll, ["x"])'], ['E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>']) - v9.CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string') + v9.CheckSourceDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E712: Argument of extend() must be a List or Dictionary']) + v9.CheckSourceDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E712: Argument of extend() must be a List or Dictionary']) + v9.CheckSourceDefAndScriptFailure(['var ll = [1, 2]', 'extend(ll, ["x"])'], ['E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>']) + v9.CheckSourceDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string') - v9.CheckDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, expected dict<any> but got number') - v9.CheckDefFailure(['extend({a: 1}, {b: 2}, 1)'], 'E1013: Argument 3: type mismatch, expected string but got number') + v9.CheckSourceDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, expected dict<any> but got number') + v9.CheckSourceDefFailure(['extend({a: 1}, {b: 2}, 1)'], 'E1013: Argument 3: type mismatch, expected string but got number') - v9.CheckScriptFailure(['vim9script', 'var l = [1]', 'extend(l, ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<any> in extend()') + v9.CheckSourceScriptFailure(['vim9script', 'var l = [1]', 'extend(l, ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<any> in extend()') enddef func g:ExtendDict(d) @@ -1123,26 +1125,26 @@ def Test_extend_dict_item_type() var d: dict<number> = {a: 1} extend(d, {b: 2}) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END var d: dict<number> = {a: 1} extend(d, {b: 'x'}) END - v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string>', 2) + v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string>', 2) lines =<< trim END var d: dict<number> = {a: 1} g:ExtendDict(d) END - v9.CheckDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0) - v9.CheckScriptFailure(['vim9script'] + lines, 'E1012:', 1) + v9.CheckSourceDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0) + v9.CheckSourceScriptFailure(['vim9script'] + lines, 'E1012:', 1) lines =<< trim END var d: dict<bool> extend(d, {b: 0}) END - v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<bool> but got dict<number>', 2) + v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<bool> but got dict<number>', 2) enddef func g:ExtendList(l) @@ -1154,26 +1156,26 @@ def Test_extend_list_item_type() var l: list<number> = [1] extend(l, [2]) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END var l: list<number> = [1] extend(l, ['x']) END - v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 2) + v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>', 2) lines =<< trim END var l: list<number> = [1] g:ExtendList(l) END - v9.CheckDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0) - v9.CheckScriptFailure(['vim9script'] + lines, 'E1012:', 1) + v9.CheckSourceDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string', 0) + v9.CheckSourceScriptFailure(['vim9script'] + lines, 'E1012:', 1) lines =<< trim END var l: list<bool> extend(l, [0]) END - v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<bool> but got list<number>', 2) + v9.CheckSourceDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected list<bool> but got list<number>', 2) enddef def Test_extend_return_type() @@ -1203,7 +1205,7 @@ def Test_extend_with_error_function() Test() END - v9.CheckScriptFailure(lines, 'E1001: Variable not found: m') + v9.CheckSourceScriptFailure(lines, 'E1001: Variable not found: m') enddef def Test_extend_const() @@ -1211,20 +1213,20 @@ def Test_extend_const() const l = [1, 2] extend(l, [3]) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') lines =<< trim END const d = {a: 1, b: 2} extend(d, {c: 3}) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') lines =<< trim END final d = {a: 1, b: 2} extend(d, {c: 3}) assert_equal({a: 1, b: 2, c: 3}, d) END - v9.CheckDefSuccess(lines) + v9.CheckSourceDefSuccess(lines) # item in a for loop is final lines =<< trim END @@ -1233,23 +1235,23 @@ def Test_extend_const() item->extend({x: 2}) endfor END - v9.CheckDefSuccess(lines) + v9.CheckSourceDefSuccess(lines) enddef def Test_extendnew() assert_equal([1, 2, 'a'], extendnew([1, 2], ['a'])) assert_equal({one: 1, two: 'a'}, extendnew({one: 1}, {two: 'a'})) - v9.CheckDefAndScriptFailure(['extendnew({a: 1}, 42)'], ['E1013: Argument 2: type mismatch, expected dict<number> but got number', 'E712: Argument of extendnew() must be a List or Dictionary']) - v9.CheckDefAndScriptFailure(['extendnew({a: 1}, [42])'], ['E1013: Argument 2: type mismatch, expected dict<number> but got list<number>', 'E712: Argument of extendnew() must be a List or Dictionary']) - v9.CheckDefAndScriptFailure(['extendnew([1, 2], "x")'], ['E1013: Argument 2: type mismatch, expected list<number> but got string', 'E712: Argument of extendnew() must be a List or Dictionary']) - v9.CheckDefAndScriptFailure(['extendnew([1, 2], {x: 1})'], ['E1013: Argument 2: type mismatch, expected list<number> but got dict<number>', 'E712: Argument of extendnew() must be a List or Dictionary']) + v9.CheckSourceDefAndScriptFailure(['extendnew({a: 1}, 42)'], ['E1013: Argument 2: type mismatch, expected dict<number> but got number', 'E712: Argument of extendnew() must be a List or Dictionary']) + v9.CheckSourceDefAndScriptFailure(['extendnew({a: 1}, [42])'], ['E1013: Argument 2: type mismatch, expected dict<number> but got list<number>', 'E712: Argument of extendnew() must be a List or Dictionary']) + v9.CheckSourceDefAndScriptFailure(['extendnew([1, 2], "x")'], ['E1013: Argument 2: type mismatch, expected list<number> but got string', 'E712: Argument of extendnew() must be a List or Dictionary']) + v9.CheckSourceDefAndScriptFailure(['extendnew([1, 2], {x: 1})'], ['E1013: Argument 2: type mismatch, expected list<number> but got dict<number>', 'E712: Argument of extendnew() must be a List or Dictionary']) enddef def Test_feedkeys() - v9.CheckDefAndScriptFailure(['feedkeys(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['feedkeys("x", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['feedkeys([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['feedkeys(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['feedkeys("x", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['feedkeys([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) g:TestVar = 1 feedkeys(":g:TestVar = 789\n", 'xt') assert_equal(789, g:TestVar) @@ -1260,16 +1262,16 @@ def Test_filereadable() assert_false(filereadable("")) assert_false(filereadable(test_null_string())) - v9.CheckDefExecFailure(['echo filereadable(123)'], 'E1013:') - v9.CheckDefExecFailure(['echo filereadable(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo filereadable(123)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo filereadable(true)'], 'E1013:') enddef def Test_filewritable() assert_false(filewritable("")) assert_false(filewritable(test_null_string())) - v9.CheckDefExecFailure(['echo filewritable(123)'], 'E1013:') - v9.CheckDefExecFailure(['echo filewritable(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo filewritable(123)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo filewritable(true)'], 'E1013:') enddef def Test_finddir() @@ -1278,20 +1280,20 @@ def Test_finddir() var lines =<< trim END var l: list<string> = finddir('nothing', '*;', -1) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) delete('Xtestdir', 'rf') - v9.CheckDefAndScriptFailure(['finddir(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['finddir(v:null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1']) - v9.CheckDefExecFailure(['echo finddir("")'], 'E1175:') - v9.CheckDefAndScriptFailure(['finddir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['finddir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['finddir(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['finddir(v:null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1']) + v9.CheckSourceDefExecFailure(['echo finddir("")'], 'E1175:') + v9.CheckSourceDefAndScriptFailure(['finddir("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['finddir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) finddir('abc', '')->assert_equal('') - v9.CheckDefFailure(['var s: list<string> = finddir("foo")'], 'E1012: Type mismatch; expected list<string> but got string') - v9.CheckDefFailure(['var s: list<string> = finddir("foo", "path")'], 'E1012: Type mismatch; expected list<string> but got string') + v9.CheckSourceDefFailure(['var s: list<string> = finddir("foo")'], 'E1012: Type mismatch; expected list<string> but got string') + v9.CheckSourceDefFailure(['var s: list<string> = finddir("foo", "path")'], 'E1012: Type mismatch; expected list<string> but got string') # with third argument only runtime type checking - v9.CheckDefCompileSuccess(['var s: list<string> = finddir("foo", "path", 1)']) + v9.CheckSourceDefCompileSuccess(['var s: list<string> = finddir("foo", "path", 1)']) enddef def Test_findfile() @@ -1299,13 +1301,13 @@ def Test_findfile() var lines =<< trim END var l: list<string> = findfile('nothing', '*;', -1) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) - v9.CheckDefExecFailure(['findfile(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool') - v9.CheckDefExecFailure(['findfile(v:null)'], 'E1013: Argument 1: type mismatch, expected string but got special') - v9.CheckDefExecFailure(['findfile("")'], 'E1175:') - v9.CheckDefAndScriptFailure(['findfile("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['findfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefExecFailure(['findfile(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool') + v9.CheckSourceDefExecFailure(['findfile(v:null)'], 'E1013: Argument 1: type mismatch, expected string but got special') + v9.CheckSourceDefExecFailure(['findfile("")'], 'E1175:') + v9.CheckSourceDefAndScriptFailure(['findfile("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['findfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) findfile('abc', '')->assert_equal('') enddef @@ -1313,7 +1315,7 @@ def Test_flatten() var lines =<< trim END echo flatten([1, 2, 3]) END - v9.CheckDefAndScriptFailure(lines, 'E1158:') + v9.CheckSourceDefAndScriptFailure(lines, 'E1158:') enddef def Test_flattennew() @@ -1328,106 +1330,106 @@ def Test_flattennew() var ll: list<list<string>> = [['a', 'b', 'c']] assert_equal(['a', 'b', 'c'], ll->flattennew()) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) - v9.CheckDefAndScriptFailure(['flattennew({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['flattennew([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['flattennew({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['flattennew([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef " Test for float functions argument type def Test_float_funcs_args() # acos() - v9.CheckDefAndScriptFailure(['acos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['acos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('1.570796', string(acos(0.0))) # asin() - v9.CheckDefAndScriptFailure(['asin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['asin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(asin(0.0))) # atan() - v9.CheckDefAndScriptFailure(['atan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['atan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(atan(0.0))) # atan2() - v9.CheckDefAndScriptFailure(['atan2("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['atan2("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('-2.356194', string(atan2(-1, -1))) - v9.CheckDefAndScriptFailure(['atan2(1.2, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) - v9.CheckDefAndScriptFailure(['atan2(1.2)'], ['E119:', 'E119:']) + v9.CheckSourceDefAndScriptFailure(['atan2(1.2, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['atan2(1.2)'], ['E119:', 'E119:']) # ceil() - v9.CheckDefAndScriptFailure(['ceil("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['ceil("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('2.0', string(ceil(2.0))) # cos() - v9.CheckDefAndScriptFailure(['cos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['cos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('1.0', string(cos(0.0))) # cosh() - v9.CheckDefAndScriptFailure(['cosh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['cosh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('1.0', string(cosh(0.0))) # exp() - v9.CheckDefAndScriptFailure(['exp("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['exp("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('1.0', string(exp(0.0))) # float2nr() - v9.CheckDefAndScriptFailure(['float2nr("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['float2nr("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal(1, float2nr(1.234)) # floor() - v9.CheckDefAndScriptFailure(['floor("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['floor("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('2.0', string(floor(2.0))) # fmod() - v9.CheckDefAndScriptFailure(['fmod(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) - v9.CheckDefAndScriptFailure(['fmod("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['fmod(1.1)'], ['E119:', 'E119:']) + v9.CheckSourceDefAndScriptFailure(['fmod(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['fmod("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['fmod(1.1)'], ['E119:', 'E119:']) assert_equal('0.13', string(fmod(12.33, 1.22))) # isinf() - v9.CheckDefAndScriptFailure(['isinf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['isinf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal(1, isinf(1.0 / 0.0)) # isnan() - v9.CheckDefAndScriptFailure(['isnan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['isnan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_true(isnan(0.0 / 0.0)) # log() - v9.CheckDefAndScriptFailure(['log("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['log("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(log(1.0))) # log10() - v9.CheckDefAndScriptFailure(['log10("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['log10("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(log10(1.0))) # pow() - v9.CheckDefAndScriptFailure(['pow("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['pow(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) - v9.CheckDefAndScriptFailure(['pow(1.1)'], ['E119:', 'E119:']) + v9.CheckSourceDefAndScriptFailure(['pow("a", 1.1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['pow(1.1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['pow(1.1)'], ['E119:', 'E119:']) assert_equal('1.0', string(pow(0.0, 0.0))) # round() - v9.CheckDefAndScriptFailure(['round("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['round("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('2.0', string(round(2.1))) # sin() - v9.CheckDefAndScriptFailure(['sin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sin("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(sin(0.0))) # sinh() - v9.CheckDefAndScriptFailure(['sinh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sinh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(sinh(0.0))) # sqrt() - v9.CheckDefAndScriptFailure(['sqrt("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sqrt("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(sqrt(0.0))) # tan() - v9.CheckDefAndScriptFailure(['tan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['tan("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(tan(0.0))) # tanh() - v9.CheckDefAndScriptFailure(['tanh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['tanh("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('0.0', string(tanh(0.0))) # trunc() - v9.CheckDefAndScriptFailure(['trunc("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['trunc("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1219: Float or Number required for argument 1']) assert_equal('2.0', string(trunc(2.1))) enddef def Test_fnameescape() - v9.CheckDefAndScriptFailure(['fnameescape(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['fnameescape(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal('\+a\%b\|', fnameescape('+a%b|')) fnameescape('')->assert_equal('') enddef def Test_fnamemodify() - v9.CheckDefSuccess(['echo fnamemodify(test_null_string(), ":p")']) - v9.CheckDefSuccess(['echo fnamemodify("", ":p")']) - v9.CheckDefSuccess(['echo fnamemodify("file", test_null_string())']) - v9.CheckDefSuccess(['echo fnamemodify("file", "")']) + v9.CheckSourceDefSuccess(['echo fnamemodify(test_null_string(), ":p")']) + v9.CheckSourceDefSuccess(['echo fnamemodify("", ":p")']) + v9.CheckSourceDefSuccess(['echo fnamemodify("file", test_null_string())']) + v9.CheckSourceDefSuccess(['echo fnamemodify("file", "")']) - v9.CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got bool') - v9.CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got special') - v9.CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool') + v9.CheckSourceDefExecFailure(['echo fnamemodify(true, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got bool') + v9.CheckSourceDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got special') + v9.CheckSourceDefExecFailure(['echo fnamemodify("file", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool') enddef def Wrong_dict_key_type(items: list<number>): list<number> @@ -1454,10 +1456,10 @@ def Test_filter() enddef assert_equal(['xxx'], Func()) END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) - v9.CheckDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got float', 'E1251: List, Dictionary, Blob or String required for argument 1']) - v9.CheckDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String']) + v9.CheckSourceDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got float', 'E1251: List, Dictionary, Blob or String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String']) lines =<< trim END def F(i: number, v: any): string @@ -1465,51 +1467,51 @@ def Test_filter() enddef echo filter([1, 2, 3], F) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool but got func(number, any): string', 'E1135: Using a String as a Bool:']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool but got func(number, any): string', 'E1135: Using a String as a Bool:']) # check first function argument type lines =<< trim END var l = [1, 2, 3] filter(l, (i: string, v: number) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number']) lines =<< trim END var d = {a: 1} filter(d, (i: number, v: number) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(number, number): bool', 'E1013: Argument 1: type mismatch, expected number but got string']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(number, number): bool', 'E1013: Argument 1: type mismatch, expected number but got string']) lines =<< trim END var b = 0z1122 filter(b, (i: string, v: number) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number']) lines =<< trim END var s = 'text' filter(s, (i: string, v: string) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(string, string): bool', 'E1013: Argument 1: type mismatch, expected string but got number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(string, string): bool', 'E1013: Argument 1: type mismatch, expected string but got number']) # check second function argument type lines =<< trim END var l = [1, 2, 3] filter(l, (i: number, v: string) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number']) lines =<< trim END var d = {a: 1} filter(d, (i: string, v: string) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(string, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(string, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number']) lines =<< trim END var b = 0z1122 filter(b, (i: number, v: string) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number']) lines =<< trim END var s = 'text' filter(s, (i: number, v: number) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(number, number): bool', 'E1013: Argument 2: type mismatch, expected number but got string']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(number, number): bool', 'E1013: Argument 2: type mismatch, expected number but got string']) enddef def Test_filter_wrong_dict_key_type() @@ -1536,39 +1538,39 @@ def Test_filter_const() const l = [1, 2, 3] filter(l, 'v:val == 2') END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') lines =<< trim END const d = {a: 1, b: 2} filter(d, 'v:val == 2') END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') enddef def Test_foldclosed() - v9.CheckDefAndScriptFailure(['foldclosed(function("min"))'], ['E1013: Argument 1: type mismatch, expected string but got func(...): unknown', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['foldclosed("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['foldclosed(function("min"))'], ['E1013: Argument 1: type mismatch, expected string but got func(...): unknown', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['foldclosed("")'], 'E1209: Invalid value for a line number') assert_equal(-1, foldclosed(1)) assert_equal(-1, foldclosed('$')) enddef def Test_foldclosedend() - v9.CheckDefAndScriptFailure(['foldclosedend(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['foldclosedend("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['foldclosedend(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['foldclosedend("")'], 'E1209: Invalid value for a line number') assert_equal(-1, foldclosedend(1)) assert_equal(-1, foldclosedend('w0')) enddef def Test_foldlevel() - v9.CheckDefAndScriptFailure(['foldlevel(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['foldlevel("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['foldlevel(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['foldlevel("")'], 'E1209: Invalid value for a line number') assert_equal(0, foldlevel(1)) assert_equal(0, foldlevel('.')) enddef def Test_foldtextresult() - v9.CheckDefAndScriptFailure(['foldtextresult(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['foldtextresult("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['foldtextresult(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['foldtextresult("")'], 'E1209: Invalid value for a line number') assert_equal('', foldtextresult(1)) assert_equal('', foldtextresult('.')) enddef @@ -1605,8 +1607,8 @@ def Test_fullcommand() enddef def Test_funcref() - v9.CheckDefAndScriptFailure(['funcref("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) - v9.CheckDefAndScriptFailure(['funcref("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['funcref("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['funcref("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) var lines =<< trim END vim9script @@ -1623,7 +1625,7 @@ def Test_funcref() defcompile GetRefOk() END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) lines =<< trim END vim9script @@ -1635,14 +1637,14 @@ def Test_funcref() enddef GetRefBad() END - v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)') + v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)') enddef def Test_function() - v9.CheckDefExecAndScriptFailure(['function(123)'], 'E1256: String or function required for argument 1') + v9.CheckSourceDefExecAndScriptFailure(['function(123)'], 'E1256: String or function required for argument 1') - v9.CheckDefAndScriptFailure(['function("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) - v9.CheckDefAndScriptFailure(['function("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['function("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['function("reverse", [2], [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) var lines =<< trim END vim9script @@ -1659,7 +1661,7 @@ def Test_function() defcompile GetRefOk() END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) lines =<< trim END vim9script @@ -1671,17 +1673,17 @@ def Test_function() enddef GetRefBad() END - v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)') + v9.CheckSourceScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(bool)') enddef def Test_garbagecollect() garbagecollect(true) - v9.CheckDefAndScriptFailure(['garbagecollect("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['garbagecollect(20)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['garbagecollect("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['garbagecollect(20)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) enddef def Test_get() - v9.CheckDefAndScriptFailure(['get("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E896: Argument of get() must be a List, Dictionary or Blob']) + v9.CheckSourceDefAndScriptFailure(['get("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E896: Argument of get() must be a List, Dictionary or Blob']) [3, 5, 2]->get(1)->assert_equal(5) [3, 5, 2]->get(3)->assert_equal(0) [3, 5, 2]->get(3, 9)->assert_equal(9) @@ -1701,7 +1703,7 @@ def Test_get() enddef assert_equal(0, DoThat()) END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) enddef def Test_getbufinfo() @@ -1714,7 +1716,7 @@ def Test_getbufinfo() getbufinfo({bufloaded: true, buflisted: true, bufmodified: false}) ->len()->assert_equal(3) bwipe Xtestfile1 Xtestfile2 - v9.CheckDefAndScriptFailure(['getbufinfo(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getbufinfo(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) enddef def Test_getbufline() @@ -1738,17 +1740,17 @@ def Test_getbufline() assert_fails('getbufoneline("", "$a")', ['E1030: Using a String as a Number: "$a"', 'E1030: Using a String as a Number: "$a"']) bwipe! - v9.CheckDefAndScriptFailure(['getbufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getbufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) - v9.CheckDefAndScriptFailure(['getbufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['getbufline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getbufline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getbufline("a", 2, 0z10)'], ['E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3']) - v9.CheckDefAndScriptFailure(['getbufoneline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getbufoneline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getbufoneline([], 2)'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getbufoneline("a", [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) enddef def Test_getbufvar() - v9.CheckDefAndScriptFailure(['getbufvar(true, "v")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getbufvar(true, "v")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) enddef def Test_getchangelist() @@ -1764,21 +1766,21 @@ def Test_getchar() endwhile getchar(true)->assert_equal(0) getchar(1)->assert_equal(0) - v9.CheckDefAndScriptFailure(['getchar(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['getchar("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getchar(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getchar("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) enddef def Test_getcharpos() assert_equal(['x', 'x', 'x', 'x'], getcharpos('.')->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['getcharpos(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['getcharpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefExecAndScriptFailure(['getcharpos("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['getcharpos(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcharpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['getcharpos("")'], 'E1209: Invalid value for a line number') enddef def Test_getcharstr() - v9.CheckDefAndScriptFailure(['getcharstr(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['getcharstr("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcharstr(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcharstr("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) enddef def Test_getcompletion() @@ -1786,29 +1788,29 @@ def Test_getcompletion() var l = getcompletion('run', 'file', true) l->assert_equal([]) set wildignore& - v9.CheckDefAndScriptFailure(['getcompletion(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['getcompletion("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['getcompletion("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) - v9.CheckDefExecAndScriptFailure(['getcompletion("a", "")'], 'E475: Invalid argument') + v9.CheckSourceDefAndScriptFailure(['getcompletion(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcompletion("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getcompletion("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['getcompletion("a", "")'], 'E475: Invalid argument') getcompletion('', 'messages')->assert_equal(['clear']) enddef def Test_getcurpos() assert_equal(['x', 'x', 'x', 'x', 'x'], getcurpos()->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['getcurpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcurpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_getcursorcharpos() assert_equal(['x', 'x', 'x', 'x', 'x'], getcursorcharpos()->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['getcursorcharpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcursorcharpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_getcwd() - v9.CheckDefAndScriptFailure(['getcwd("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getcwd("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getcwd(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getcwd("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcwd("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getcwd(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_getenv() @@ -1827,7 +1829,7 @@ def Test_getenv() enddef def Test_getfontname() - v9.CheckDefAndScriptFailure(['getfontname(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getfontname(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) #getfontname('')->assert_equal('') enddef @@ -1835,38 +1837,38 @@ def Test_getfperm() assert_equal('', getfperm("")) assert_equal('', getfperm(test_null_string())) - v9.CheckDefExecFailure(['echo getfperm(true)'], 'E1013:') - v9.CheckDefExecFailure(['echo getfperm(v:null)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getfperm(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getfperm(v:null)'], 'E1013:') enddef def Test_getfsize() assert_equal(-1, getfsize("")) assert_equal(-1, getfsize(test_null_string())) - v9.CheckDefExecFailure(['echo getfsize(true)'], 'E1013:') - v9.CheckDefExecFailure(['echo getfsize(v:null)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getfsize(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getfsize(v:null)'], 'E1013:') enddef def Test_getftime() assert_equal(-1, getftime("")) assert_equal(-1, getftime(test_null_string())) - v9.CheckDefExecFailure(['echo getftime(true)'], 'E1013:') - v9.CheckDefExecFailure(['echo getftime(v:null)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getftime(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getftime(v:null)'], 'E1013:') enddef def Test_getftype() assert_equal('', getftype("")) assert_equal('', getftype(test_null_string())) - v9.CheckDefExecFailure(['echo getftype(true)'], 'E1013:') - v9.CheckDefExecFailure(['echo getftype(v:null)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getftype(true)'], 'E1013:') + v9.CheckSourceDefExecFailure(['echo getftype(v:null)'], 'E1013:') enddef def Test_getjumplist() - v9.CheckDefAndScriptFailure(['getjumplist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getjumplist("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getjumplist(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getjumplist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getjumplist("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getjumplist(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_getline() @@ -1882,20 +1884,20 @@ def Test_getline() assert_equal([3, 3, 3], getline(1, 3)->map((_, _) => 3)) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END echo getline('1') END - v9.CheckDefExecAndScriptFailure(lines, 'E1209:') - v9.CheckDefAndScriptFailure(['getline(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getline(1, true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['getline("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1209:') + v9.CheckSourceDefAndScriptFailure(['getline(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getline(1, true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['getline("")'], 'E1209: Invalid value for a line number') enddef def Test_getloclist() - v9.CheckDefAndScriptFailure(['getloclist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getloclist(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getloclist("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getloclist(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) enddef def Test_getloclist_return_type() @@ -1907,26 +1909,26 @@ def Test_getloclist_return_type() enddef def Test_getmarklist() - v9.CheckDefAndScriptFailure(['getmarklist([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getmarklist([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) assert_equal([], getmarklist(10000)) assert_fails('getmarklist("a%b@#")', 'E94:') enddef def Test_getmatches() - v9.CheckDefAndScriptFailure(['getmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getmatches("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_getpos() assert_equal(['x', 'x', 'x', 'x'], getpos('.')->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['getpos(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getpos(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal([0, 1, 1, 0], getpos('.')) - v9.CheckDefExecFailure(['getpos("a")'], 'E1209:') - v9.CheckDefExecAndScriptFailure(['getpos("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecFailure(['getpos("a")'], 'E1209:') + v9.CheckSourceDefExecAndScriptFailure(['getpos("")'], 'E1209: Invalid value for a line number') enddef def Test_getqflist() - v9.CheckDefAndScriptFailure(['getqflist([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getqflist([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) call assert_equal({}, getqflist({})) enddef @@ -1945,9 +1947,9 @@ def Test_getreg() assert_equal([7, 7, 7], getreg('a', true, true)->map((_, _) => 7)) assert_fails('getreg("ab")', 'E1162:') - v9.CheckDefAndScriptFailure(['getreg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['getreg(".", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) - v9.CheckDefAndScriptFailure(['getreg(".", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['getreg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getreg(".", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getreg(".", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) @" = 'A1B2C3' getreg('')->assert_equal('A1B2C3') enddef @@ -1967,6 +1969,17 @@ def Test_getreginfo() getreginfo('').regcontents->assert_equal(['D1E2F3']) enddef +def Test_getregionpos() + var lines =<< trim END + cursor(1, 1) + var pos = getregionpos(getpos('.'), getpos('$')) + for p in pos + assert_equal(bufnr('%'), p[0][0]) + endfor + END + v9.CheckSourceDefSuccess(lines) +enddef + def Test_getregtype() var lines = ['aaa', 'bbb', 'ccc'] setreg('a', lines) @@ -1977,7 +1990,7 @@ def Test_getregtype() enddef def Test_getscriptinfo() - v9.CheckDefAndScriptFailure(['getscriptinfo("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getscriptinfo("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1']) var lines1 =<< trim END vim9script @@ -2016,78 +2029,78 @@ def Test_getscriptinfo() assert_true(index(l[0].functions, f) != -1) endfor END - v9.CheckDefAndScriptSuccess(lines2) + v9.CheckSourceDefAndScriptSuccess(lines2) enddef def Test_gettabinfo() - v9.CheckDefAndScriptFailure(['gettabinfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['gettabinfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_gettabvar() - v9.CheckDefAndScriptFailure(['gettabvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['gettabvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['gettabvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['gettabvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) enddef def Test_gettabwinvar() - v9.CheckDefAndScriptFailure(['gettabwinvar("a", 2, "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['gettabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['gettabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['gettabwinvar("a", 2, "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['gettabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['gettabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) enddef def Test_gettagstack() - v9.CheckDefAndScriptFailure(['gettagstack("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['gettagstack("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_gettext() - v9.CheckDefAndScriptFailure(['gettext(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefExecAndScriptFailure(['gettext("")'], 'E1175: Non-empty string required for argument 1') + v9.CheckSourceDefAndScriptFailure(['gettext(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['gettext("")'], 'E1175: Non-empty string required for argument 1') assert_equal('abc', gettext("abc")) assert_fails('gettext("")', 'E1175:') enddef def Test_getwininfo() - v9.CheckDefAndScriptFailure(['getwininfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getwininfo("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_getwinpos() assert_equal(['x', 'x'], getwinpos()->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['getwinpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getwinpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_getwinvar() - v9.CheckDefAndScriptFailure(['getwinvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['getwinvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['getwinvar("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['getwinvar(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) enddef def Test_glob() glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) - v9.CheckDefAndScriptFailure(['glob(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['glob("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) - v9.CheckDefAndScriptFailure(['glob("a", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) - v9.CheckDefAndScriptFailure(['glob("a", 1, true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['glob(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['glob("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['glob("a", 1, "b")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['glob("a", 1, true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) glob('')->assert_equal('') enddef def Test_glob2regpat() - v9.CheckDefAndScriptFailure(['glob2regpat(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['glob2regpat(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1174: String required for argument 1']) glob2regpat('')->assert_equal('^$') enddef def Test_globpath() globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) - v9.CheckDefAndScriptFailure(['globpath(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['globpath("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['globpath("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) - v9.CheckDefAndScriptFailure(['globpath("a", "b", true, "d")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4']) - v9.CheckDefAndScriptFailure(['globpath("a", "b", true, false, "e")'], ['E1013: Argument 5: type mismatch, expected bool but got string', 'E1212: Bool required for argument 5']) + v9.CheckSourceDefAndScriptFailure(['globpath(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['globpath("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['globpath("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['globpath("a", "b", true, "d")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['globpath("a", "b", true, false, "e")'], ['E1013: Argument 5: type mismatch, expected bool but got string', 'E1212: Bool required for argument 5']) globpath('', '')->assert_equal('') enddef def Test_has() has('eval', true)->assert_equal(1) - v9.CheckDefAndScriptFailure(['has(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['has("a", "b")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['has(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['has("a", "b")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) has('')->assert_equal(0) enddef @@ -2098,14 +2111,14 @@ def Test_has_key() assert_false(has_key(d, 'x')) assert_false(has_key(d, 99)) - v9.CheckDefAndScriptFailure(['has_key([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['has_key({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['has_key([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['has_key({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 2']) enddef def Test_haslocaldir() - v9.CheckDefAndScriptFailure(['haslocaldir("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['haslocaldir("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['haslocaldir(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['haslocaldir("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['haslocaldir("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['haslocaldir(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_hasmapto() @@ -2113,81 +2126,81 @@ def Test_hasmapto() iabbrev foo foobar hasmapto('foobar', 'i', true)->assert_equal(1) iunabbrev foo - v9.CheckDefAndScriptFailure(['hasmapto(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['hasmapto("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['hasmapto("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['hasmapto(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['hasmapto("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['hasmapto("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) hasmapto('', '')->assert_equal(0) enddef def Test_histadd() - v9.CheckDefAndScriptFailure(['histadd(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['histadd(":", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['histadd(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['histadd(":", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) histadd("search", 'skyblue') assert_equal('skyblue', histget('/', -1)) histadd("search", '')->assert_equal(0) enddef def Test_histdel() - v9.CheckDefAndScriptFailure(['histdel(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['histdel(":", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['histdel(1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['histdel(":", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) histdel('search', '')->assert_equal(0) enddef def Test_histget() - v9.CheckDefAndScriptFailure(['histget(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['histget("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['histget(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['histget("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_histnr() - v9.CheckDefAndScriptFailure(['histnr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['histnr(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal(-1, histnr('abc')) enddef def Test_hlID() - v9.CheckDefAndScriptFailure(['hlID(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['hlID(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal(0, hlID('NonExistingHighlight')) hlID('')->assert_equal(0) enddef def Test_hlexists() - v9.CheckDefAndScriptFailure(['hlexists([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['hlexists([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) assert_equal(0, hlexists('NonExistingHighlight')) hlexists('')->assert_equal(0) enddef def Test_hlget() - v9.CheckDefAndScriptFailure(['hlget([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['hlget([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) hlget('')->assert_equal([]) enddef def Test_hlset() - v9.CheckDefAndScriptFailure(['hlset("id")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['hlset("id")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) hlset([])->assert_equal(0) enddef def Test_iconv() - v9.CheckDefAndScriptFailure(['iconv(1, "from", "to")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['iconv("abc", 10, "to")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['iconv("abc", "from", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['iconv(1, "from", "to")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['iconv("abc", 10, "to")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['iconv("abc", "from", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) assert_equal('abc', iconv('abc', 'fromenc', 'toenc')) iconv('', '', '')->assert_equal('') enddef def Test_indent() - v9.CheckDefAndScriptFailure(['indent([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['indent(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['indent("")'], 'E1209: Invalid value for a line number') - v9.CheckDefExecAndScriptFailure(['indent(-1)'], 'E966: Invalid line number: -1') + v9.CheckSourceDefAndScriptFailure(['indent([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['indent(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['indent("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecAndScriptFailure(['indent(-1)'], 'E966: Invalid line number: -1') assert_equal(0, indent(1)) enddef def Test_index() index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) - v9.CheckDefAndScriptFailure(['index("a", "a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1']) - v9.CheckDefFailure(['index(["1"], 1)'], 'E1013: Argument 2: type mismatch, expected string but got number') - v9.CheckDefAndScriptFailure(['index(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['index([1], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['index(0z1020, 10, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['index("a", "a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1']) + v9.CheckSourceDefFailure(['index(["1"], 1)'], 'E1013: Argument 2: type mismatch, expected string but got number') + v9.CheckSourceDefAndScriptFailure(['index(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['index([1], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['index(0z1020, 10, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) enddef def Test_indexof() @@ -2195,6 +2208,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) @@ -2210,7 +2224,7 @@ def Test_indexof() indexof([{color: "red"}], TestIdx) END - v9.CheckDefAndScriptFailure(lines, ['E176: Invalid number of arguments', 'E118: Too many arguments for function']) + v9.CheckSourceDefAndScriptFailure(lines, ['E176: Invalid number of arguments', 'E118: Too many arguments for function']) lines =<< trim END def TestIdx(k: number, v: dict<any>) @@ -2218,7 +2232,7 @@ def Test_indexof() indexof([{color: "red"}], TestIdx) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1031: Cannot use void value']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1031: Cannot use void value']) lines =<< trim END def TestIdx(k: number, v: dict<any>): string @@ -2227,35 +2241,35 @@ def Test_indexof() indexof([{color: "red"}], TestIdx) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1135: Using a String as a Bool']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool', 'E1135: Using a String as a Bool']) enddef def Test_input() - v9.CheckDefAndScriptFailure(['input(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['input(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['input("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['input("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['input(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['input(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['input("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['input("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) enddef def Test_inputdialog() - v9.CheckDefAndScriptFailure(['inputdialog(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['inputdialog(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['inputdialog("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['inputdialog("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['inputdialog(5)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['inputdialog(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['inputdialog("p", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['inputdialog("p", "q", 20)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) enddef def Test_inputlist() - v9.CheckDefAndScriptFailure(['inputlist(10)'], ['E1013: Argument 1: type mismatch, expected list<string> but got number', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['inputlist("abc")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1']) - v9.CheckDefFailure(['inputlist([1, 2, 3])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>') + v9.CheckSourceDefAndScriptFailure(['inputlist(10)'], ['E1013: Argument 1: type mismatch, expected list<string> but got number', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['inputlist("abc")'], ['E1013: Argument 1: type mismatch, expected list<string> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefFailure(['inputlist([1, 2, 3])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>') feedkeys("2\<CR>", 't') var r: number = inputlist(['a', 'b', 'c']) assert_equal(2, r) enddef def Test_inputsecret() - v9.CheckDefAndScriptFailure(['inputsecret(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['inputsecret("Pass:", 20)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['inputsecret(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['inputsecret("Pass:", 20)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) feedkeys("\<CR>", 't') var ans: string = inputsecret('Pass:', '123') assert_equal('123', ans) @@ -2282,12 +2296,12 @@ def Test_insert() var lines =<< trim END insert(test_null_list(), 123) END - v9.CheckDefExecAndScriptFailure(lines, 'E1130:', 1) + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1130:', 1) lines =<< trim END insert(test_null_blob(), 123) END - v9.CheckDefExecAndScriptFailure(lines, 'E1131:', 1) + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1131:', 1) assert_equal([1, 2, 3], insert([2, 3], 1)) assert_equal([1, 2, 3], insert([2, 3], number_one)) @@ -2296,9 +2310,9 @@ def Test_insert() assert_equal(['a', 'b', 'c'], insert(['b', 'c'], 'a')) assert_equal(0z1234, insert(0z34, 0x12)) - v9.CheckDefAndScriptFailure(['insert("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1']) - v9.CheckDefFailure(['insert([2, 3], "a")'], 'E1013: Argument 2: type mismatch, expected number but got string') - v9.CheckDefAndScriptFailure(['insert([2, 3], 1, "x")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['insert("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1226: List or Blob required for argument 1']) + v9.CheckSourceDefFailure(['insert([2, 3], "a")'], 'E1013: Argument 2: type mismatch, expected number but got string') + v9.CheckSourceDefAndScriptFailure(['insert([2, 3], 1, "x")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) enddef def Test_instanceof() @@ -2308,7 +2322,7 @@ def Test_instanceof() endclass instanceof('hello', Foo) END - v9.CheckScriptFailure(lines, 'E616: Object required for argument 1') + v9.CheckSourceScriptFailure(lines, 'E616: Object required for argument 1') lines =<< trim END vim9script @@ -2316,7 +2330,7 @@ def Test_instanceof() endclass instanceof(Foo.new(), 123) END - v9.CheckScriptFailure(lines, 'E693: Class or class typealias required for argument 2') + v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2') lines =<< trim END vim9script @@ -2327,7 +2341,7 @@ def Test_instanceof() enddef Bar() END - v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected object<Unknown> but got string') + v9.CheckSourceScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected object<Unknown> but got string') lines =<< trim END vim9script @@ -2338,7 +2352,7 @@ def Test_instanceof() enddef Bar() END - v9.CheckScriptFailure(lines, 'E693: Class or class typealias required for argument 2') + v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2') lines =<< trim END vim9script @@ -2346,7 +2360,7 @@ def Test_instanceof() endclass instanceof(Foo.new(), [{}]) END - v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 2') + v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2') lines =<< trim END vim9script @@ -2357,22 +2371,22 @@ def Test_instanceof() enddef Bar() END - v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 2') + v9.CheckSourceScriptFailure(lines, 'E693: Class or class typealias required for argument 2') enddef def Test_invert() - v9.CheckDefAndScriptFailure(['invert("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['invert("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_isdirectory() - v9.CheckDefAndScriptFailure(['isdirectory(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['isdirectory(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1']) assert_false(isdirectory('NonExistingDir')) assert_false(isdirectory('')) enddef def Test_islocked() - v9.CheckDefAndScriptFailure(['islocked(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['var n1: number = 10', 'islocked(n1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['islocked(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['var n1: number = 10', 'islocked(n1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) g:v1 = 10 assert_false(islocked('g:v1')) lockvar g:v1 @@ -2382,7 +2396,7 @@ def Test_islocked() enddef def Test_items() - v9.CheckDefFailure(['123->items()'], 'E1225:') + v9.CheckSourceDefFailure(['123->items()'], 'E1225:') assert_equal([['a', 10], ['b', 20]], {'a': 10, 'b': 20}->items()) assert_equal([], {}->items()) assert_equal(['x', 'x'], {'a': 10, 'b': 20}->items()->map((_, _) => 'x')) @@ -2400,7 +2414,7 @@ def Test_job_getchannel() if !has('job') CheckFeature job else - v9.CheckDefAndScriptFailure(['job_getchannel("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['job_getchannel("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) assert_fails('job_getchannel(test_null_job())', 'E916: Not a valid job') endif enddef @@ -2409,7 +2423,7 @@ def Test_job_info() if !has('job') CheckFeature job else - v9.CheckDefAndScriptFailure(['job_info("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['job_info("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) assert_fails('job_info(test_null_job())', 'E916: Not a valid job') endif enddef @@ -2420,8 +2434,8 @@ def Test_job_setoptions() if !has('job') CheckFeature job else - v9.CheckDefAndScriptFailure(['job_setoptions(test_null_channel(), {})'], ['E1013: Argument 1: type mismatch, expected job but got channel', 'E1218: Job required for argument 1']) - v9.CheckDefAndScriptFailure(['job_setoptions(test_null_job(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['job_setoptions(test_null_channel(), {})'], ['E1013: Argument 1: type mismatch, expected job but got channel', 'E1218: Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['job_setoptions(test_null_job(), [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) assert_equal('fail', job_status(test_null_job())) endif enddef @@ -2430,7 +2444,7 @@ def Test_job_status() if !has('job') CheckFeature job else - v9.CheckDefAndScriptFailure(['job_status("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['job_status("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) assert_equal('fail', job_status(test_null_job())) endif enddef @@ -2439,25 +2453,25 @@ def Test_job_stop() if !has('job') CheckFeature job else - v9.CheckDefAndScriptFailure(['job_stop("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) - v9.CheckDefAndScriptFailure(['job_stop(test_null_job(), true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['job_stop("a")'], ['E1013: Argument 1: type mismatch, expected job but got string', 'E1218: Job required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['job_stop(test_null_job(), true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) endif enddef def Test_join() - v9.CheckDefAndScriptFailure(['join("abc")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['join([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['join("abc")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['join([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) join([''], '')->assert_equal('') enddef def Test_js_decode() - v9.CheckDefAndScriptFailure(['js_decode(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['js_decode(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal([1, 2], js_decode('[1,2]')) js_decode('')->assert_equal(v:none) enddef def Test_json_decode() - v9.CheckDefAndScriptFailure(['json_decode(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['json_decode(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1']) assert_equal(1.0, json_decode('1.0')) json_decode('')->assert_equal(v:none) enddef @@ -2465,7 +2479,7 @@ enddef def Test_keys() assert_equal([7, 7], keys({a: 1, b: 2})->map((_, _) => 7)) - v9.CheckDefAndScriptFailure(['keys([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['keys([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) assert_equal(['a'], {a: 'v'}->keys()) assert_equal([], {}->keys()) enddef @@ -2476,7 +2490,7 @@ def Test_keys_return_type() enddef def Test_len() - v9.CheckDefAndScriptFailure(['len(true)'], ['E1013: Argument 1: type mismatch, expected list<any> but got bool', 'E701: Invalid type for len()']) + v9.CheckSourceDefAndScriptFailure(['len(true)'], ['E1013: Argument 1: type mismatch, expected list<any> but got bool', 'E701: Invalid type for len()']) assert_equal(2, "ab"->len()) assert_equal(3, 456->len()) assert_equal(0, []->len()) @@ -2486,42 +2500,42 @@ enddef def Test_libcall() CheckFeature libcall - v9.CheckDefAndScriptFailure(['libcall(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['libcall("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['libcall("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['libcall(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['libcall("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['libcall("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3']) enddef def Test_libcallnr() CheckFeature libcall - v9.CheckDefAndScriptFailure(['libcallnr(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['libcallnr("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['libcallnr("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['libcallnr(1, "b", 3)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['libcallnr("a", 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['libcallnr("a", "b", 1.1)'], ['E1013: Argument 3: type mismatch, expected string but got float', 'E1220: String or Number required for argument 3']) enddef def Test_line() assert_fails('line(true)', 'E1174:') - v9.CheckDefAndScriptFailure(['line(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['line(".", "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['line("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['line(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['line(".", "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['line("")'], 'E1209: Invalid value for a line number') enddef def Test_line2byte() - v9.CheckDefAndScriptFailure(['line2byte(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['line2byte("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['line2byte(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['line2byte("")'], 'E1209: Invalid value for a line number') assert_equal(-1, line2byte(1)) assert_equal(-1, line2byte(10000)) enddef def Test_lispindent() - v9.CheckDefAndScriptFailure(['lispindent({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['lispindent("")'], 'E1209: Invalid value for a line number') - v9.CheckDefExecAndScriptFailure(['lispindent(-1)'], 'E966: Invalid line number: -1') + v9.CheckSourceDefAndScriptFailure(['lispindent({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['lispindent("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecAndScriptFailure(['lispindent(-1)'], 'E966: Invalid line number: -1') assert_equal(0, lispindent(1)) enddef def Test_list2blob() - v9.CheckDefAndScriptFailure(['list2blob(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1']) - v9.CheckDefFailure(['list2blob([0z10, 0z02])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<blob>') + v9.CheckSourceDefAndScriptFailure(['list2blob(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1']) + v9.CheckSourceDefFailure(['list2blob([0z10, 0z02])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<blob>') enddef def Test_list2str_str2list_utf8() @@ -2532,8 +2546,8 @@ def Test_list2str_str2list_utf8() enddef def Test_list2str() - v9.CheckDefAndScriptFailure(['list2str(".", true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['list2str([1], 0z10)'], ['E1013: Argument 2: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['list2str(".", true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['list2str([1], 0z10)'], ['E1013: Argument 2: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 2']) enddef def s:SID(): number @@ -2543,22 +2557,22 @@ def s:SID(): number enddef def Test_listener_add() - v9.CheckDefAndScriptFailure(['listener_add("1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['listener_add("1", true)'], ['E1013: Argument 2: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 2']) enddef def Test_listener_flush() - v9.CheckDefAndScriptFailure(['listener_flush([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['listener_flush([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) enddef def Test_listener_remove() - v9.CheckDefAndScriptFailure(['listener_remove("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['listener_remove("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_luaeval() if !has('lua') CheckFeature lua endif - v9.CheckDefAndScriptFailure(['luaeval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['luaeval(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) if exists_compiled('*luaeval') luaeval('')->assert_equal(v:null) endif @@ -2566,10 +2580,10 @@ enddef def Test_map() if has('channel') - v9.CheckDefAndScriptFailure(['map(test_null_channel(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got channel', 'E1251: List, Dictionary, Blob or String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['map(test_null_channel(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got channel', 'E1251: List, Dictionary, Blob or String required for argument 1']) endif - v9.CheckDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1']) - v9.CheckDefAndScriptFailure(['map([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String']) + v9.CheckSourceDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['map([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String']) # type of dict remains dict<any> even when type of values changes # same for list @@ -2599,7 +2613,7 @@ def Test_map() assert_equal({a: 'x'}, {a: [1, 2]}->map((_, v) => 'x')) assert_equal({a: 'x'}, {a: {b: 2}}->map((_, v) => 'x')) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) enddef def Test_map_failure() @@ -2627,7 +2641,7 @@ def Test_map_failure() g:gd = d map(g:gd, (k, v) => true) END - v9.CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got bool') + v9.CheckSourceDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got bool') enddef def Test_map_const() @@ -2635,13 +2649,13 @@ def Test_map_const() const l = [1, 2, 3] map(l, 'SomeFunc') END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') lines =<< trim END const d = {a: 1, b: 2} map(d, 'SomeFunc') END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') enddef def Test_map_function_arg() @@ -2653,16 +2667,16 @@ def Test_map_function_arg() map(l, MapOne) assert_equal(['0:a', '1:b', '2:c'], l) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END range(3)->map((a, b, c) => a + b + c) END - v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1190: One argument too few']) + v9.CheckSourceDefAndScriptFailure(lines, ['E176:', 'E1190: One argument too few']) lines =<< trim END range(3)->map((a, b, c, d) => a + b + c + d) END - v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1190: 2 arguments too few']) + v9.CheckSourceDefAndScriptFailure(lines, ['E176:', 'E1190: 2 arguments too few']) # declared list cannot change type lines =<< trim END @@ -2672,7 +2686,7 @@ def Test_map_function_arg() var ll: list<number> = [1, 2, 3] echo map(ll, Map) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): string', 'E1012: Type mismatch; expected number but got string']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): string', 'E1012: Type mismatch; expected number but got string']) # not declared list can change type echo [1, 2, 3]->map((..._) => 'x') @@ -2684,25 +2698,25 @@ def Test_map_item_type() map(l, (k, v) => k .. '/' .. v ) assert_equal(['0/a', '1/b', '2/c'], l) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END var l: list<number> = [0] echo map(l, (_, v) => []) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2) lines =<< trim END var l: list<number> = range(2) echo map(l, (_, v) => []) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2) lines =<< trim END var d: dict<number> = {key: 0} echo map(d, (_, v) => []) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(any, any): list<any>', 'E1012: Type mismatch; expected number but got list<any>'], 2) enddef def Test_maparg() @@ -2725,10 +2739,10 @@ def Test_maparg() abbr: 0, mode_bits: 0x47}) unmap foo - v9.CheckDefAndScriptFailure(['maparg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['maparg("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['maparg("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) - v9.CheckDefAndScriptFailure(['maparg("a", "b", true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['maparg(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['maparg("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['maparg("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['maparg("a", "b", true, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) maparg('')->assert_equal('') # value argument type is checked at compile time @@ -2736,46 +2750,46 @@ def Test_maparg() var l = [123] l->map((i: number, v: string) => 0) END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number') lines =<< trim END var d = {a: 123} d->map((i: string, v: string) => 0) END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(string, string): number') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?number): number but got func(string, string): number') lines =<< trim END var s = 'abc' s->map((i: number, v: number) => 'x') END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(number, number): string') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(number, number): string') lines =<< trim END var s = 0z1122 s->map((i: number, v: string) => 0) END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, string): number') # index argument type is checked at compile time lines =<< trim END ['x']->map((i: string, v: string) => 'y') END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?any): any but got func(string, string): string') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?any): any but got func(string, string): string') lines =<< trim END {a: 1}->map((i: number, v: number) => 0) END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?any): any but got func(number, number): number') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?string, ?any): any but got func(number, number): number') lines =<< trim END 'abc'->map((i: string, v: string) => 'x') END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(string, string): string') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?string): string but got func(string, string): string') lines =<< trim END 0z1122->map((i: string, v: number) => 0) END - v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number') + v9.CheckSourceDefFailure(lines, 'E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number') enddef def Test_maparg_mapset() @@ -2790,31 +2804,31 @@ def Test_mapcheck() iabbrev foo foobar mapcheck('foo', 'i', true)->assert_equal('foobar') iunabbrev foo - v9.CheckDefAndScriptFailure(['mapcheck(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['mapcheck("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['mapcheck("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['mapcheck(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mapcheck("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['mapcheck("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) mapcheck('')->assert_equal('') mapcheck('', '')->assert_equal('') enddef def Test_mapnew() if has('channel') - v9.CheckDefAndScriptFailure(['mapnew(test_null_job(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got job', 'E1251: List, Dictionary, Blob or String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mapnew(test_null_job(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got job', 'E1251: List, Dictionary, Blob or String required for argument 1']) endif - v9.CheckDefAndScriptFailure(['mapnew(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mapnew(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1']) enddef def Test_mapset() - v9.CheckDefAndScriptFailure(['mapset(1, true, {})'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1223: String or Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['mapset("a", 2, {})'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) - v9.CheckDefAndScriptFailure(['mapset("a", false, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['mapset(1, true, {})'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1223: String or Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mapset("a", 2, {})'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['mapset("a", false, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) enddef def Test_match() - v9.CheckDefAndScriptFailure(['match(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['match(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['match("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['match("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['match(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['match(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['match("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['match("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) assert_equal(2, match('ab12cd', '12')) assert_equal(-1, match('ab12cd', '34')) assert_equal(6, match('ab12cd12ef', '12', 4)) @@ -2829,39 +2843,39 @@ def Test_match() enddef def Test_matchadd() - v9.CheckDefAndScriptFailure(['matchadd(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['matchadd("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['matchadd("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['matchadd("a", "b", 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) - v9.CheckDefAndScriptFailure(['matchadd("a", "b", 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5']) + v9.CheckSourceDefAndScriptFailure(['matchadd(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchadd("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchadd("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchadd("a", "b", 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['matchadd("a", "b", 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5']) matchadd('', 'a')->assert_equal(-1) matchadd('Search', '')->assert_equal(-1) enddef def Test_matchaddpos() - v9.CheckDefAndScriptFailure(['matchaddpos(1, [1])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['matchaddpos("a", "b")'], ['E1013: Argument 2: type mismatch, expected list<any> but got string', 'E1211: List required for argument 2']) - v9.CheckDefAndScriptFailure(['matchaddpos("a", [1], "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['matchaddpos("a", [1], 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) - v9.CheckDefAndScriptFailure(['matchaddpos("a", [1], 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5']) + v9.CheckSourceDefAndScriptFailure(['matchaddpos(1, [1])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", "b")'], ['E1013: Argument 2: type mismatch, expected list<any> but got string', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", [1], "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", [1], 1, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['matchaddpos("a", [1], 1, 1, [])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 5']) matchaddpos('', [1])->assert_equal(-1) enddef def Test_matcharg() - v9.CheckDefAndScriptFailure(['matcharg("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matcharg("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_matchdelete() - v9.CheckDefAndScriptFailure(['matchdelete("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['matchdelete("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['matchdelete(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchdelete("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchdelete("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchdelete(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_matchend() - v9.CheckDefAndScriptFailure(['matchend(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['matchend(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['matchend("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['matchend("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['matchend(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchend(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchend("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchend("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) assert_equal(4, matchend('ab12cd', '12')) assert_equal(-1, matchend('ab12cd', '34')) assert_equal(8, matchend('ab12cd12ef', '12', 4)) @@ -2876,9 +2890,9 @@ def Test_matchend() enddef def Test_matchfuzzy() - v9.CheckDefAndScriptFailure(['matchfuzzy({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['matchfuzzy([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['matchfuzzy([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchfuzzy({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchfuzzy([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchfuzzy([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) matchfuzzy(['abc', 'xyz'], '')->assert_equal([]) var lines =<< trim END var items = [{name: 'xyz', id: 1}, {name: 'def', id: 2}, @@ -2888,13 +2902,13 @@ def Test_matchfuzzy() var k: list<string> = matchfuzzy(['one', 'two', 'who'], 'o') assert_equal(['one', 'two', 'who'], k) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) enddef def Test_matchfuzzypos() - v9.CheckDefAndScriptFailure(['matchfuzzypos({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['matchfuzzypos([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['matchfuzzypos([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchfuzzypos({}, "p")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchfuzzypos([], 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchfuzzypos([], "a", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) matchfuzzypos(['abc', 'xyz'], '')->assert_equal([[], [], []]) var lines =<< trim END var items = [{name: 'xyz', id: 1}, {name: 'def', id: 2}, @@ -2904,14 +2918,14 @@ def Test_matchfuzzypos() var k: list<string> = matchfuzzypos(['one', 'two', 'who'], 'o')[0] assert_equal(['one', 'two', 'who'], k) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) enddef def Test_matchlist() - v9.CheckDefAndScriptFailure(['matchlist(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['matchlist(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['matchlist("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['matchlist("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['matchlist(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchlist(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchlist("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchlist("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) var l: list<string> = ['12', '', '', '', '', '', '', '', '', ''] assert_equal(l, matchlist('ab12cd', '12')) assert_equal([], matchlist('ab12cd', '34')) @@ -2929,10 +2943,10 @@ def Test_matchlist() enddef def Test_matchstr() - v9.CheckDefAndScriptFailure(['matchstr(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['matchstr(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['matchstr("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['matchstr("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['matchstr(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchstr(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchstr("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchstr("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) assert_equal('12', matchstr('ab12cd', '12')) assert_equal('', matchstr('ab12cd', '34')) assert_equal('12', matchstr('ab12cd12ef', '12', 4)) @@ -2947,10 +2961,10 @@ def Test_matchstr() enddef def Test_matchstrpos() - v9.CheckDefAndScriptFailure(['matchstrpos(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['matchstrpos(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['matchstrpos("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['matchstrpos("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['matchstrpos(0z12, "p")'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['matchstrpos(["s"], [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['matchstrpos("s", "p", "q")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['matchstrpos("s", "p", 1, "r")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) assert_equal(['12', 2, 4], matchstrpos('ab12cd', '12')) assert_equal(['', -1, -1], matchstrpos('ab12cd', '34')) assert_equal(['12', 6, 8], matchstrpos('ab12cd12ef', '12', 4)) @@ -2978,13 +2992,13 @@ def Test_max() ? [1, max([2, 3])] : [4, 5] assert_equal([4, 5], l2) - v9.CheckDefAndScriptFailure(['max(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['max(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1']) enddef def Test_menu_info() - v9.CheckDefAndScriptFailure(['menu_info(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['menu_info(10, "n")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['menu_info("File", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['menu_info(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['menu_info(10, "n")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['menu_info("File", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) assert_equal({}, menu_info('aMenu')) enddef @@ -3000,49 +3014,49 @@ def Test_min() ? [1, min([2, 3])] : [4, 5] assert_equal([4, 5], l2) - v9.CheckDefAndScriptFailure(['min(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['min(5)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1227: List or Dictionary required for argument 1']) enddef def Test_mkdir() - v9.CheckDefAndScriptFailure(['mkdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['mkdir("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['mkdir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefExecAndScriptFailure(['mkdir("")'], 'E1175: Non-empty string required for argument 1') + v9.CheckSourceDefAndScriptFailure(['mkdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mkdir("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['mkdir("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['mkdir("")'], 'E1175: Non-empty string required for argument 1') delete('a', 'rf') enddef def Test_mode() - v9.CheckDefAndScriptFailure(['mode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['mode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) enddef def Test_mzeval() if !has('mzscheme') CheckFeature mzscheme endif - v9.CheckDefAndScriptFailure(['mzeval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['mzeval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) enddef def Test_nextnonblank() - v9.CheckDefAndScriptFailure(['nextnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['nextnonblank("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['nextnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['nextnonblank("")'], 'E1209: Invalid value for a line number') assert_equal(0, nextnonblank(1)) enddef def Test_nr2char() nr2char(97, true)->assert_equal('a') - v9.CheckDefAndScriptFailure(['nr2char("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['nr2char(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['nr2char("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['nr2char(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) enddef def Test_or() - v9.CheckDefAndScriptFailure(['or("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['or(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['or("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['or(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_pathshorten() - v9.CheckDefAndScriptFailure(['pathshorten(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['pathshorten("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['pathshorten(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['pathshorten("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) pathshorten('')->assert_equal('') enddef @@ -3050,12 +3064,12 @@ def Test_perleval() if !has('perl') CheckFeature perl endif - v9.CheckDefAndScriptFailure(['perleval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['perleval(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) enddef def Test_popup_atcursor() - v9.CheckDefAndScriptFailure(['popup_atcursor({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_atcursor("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_atcursor({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_atcursor("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) # Pass variable of type 'any' to popup_atcursor() var what: any = 'Hello' @@ -3065,17 +3079,17 @@ def Test_popup_atcursor() enddef def Test_popup_beval() - v9.CheckDefAndScriptFailure(['popup_beval({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_beval("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_beval({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_beval("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) enddef def Test_popup_clear() - v9.CheckDefAndScriptFailure(['popup_clear(["a"])'], ['E1013: Argument 1: type mismatch, expected bool but got list<string>', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_clear(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_clear(["a"])'], ['E1013: Argument 1: type mismatch, expected bool but got list<string>', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_clear(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) enddef def Test_popup_close() - v9.CheckDefAndScriptFailure(['popup_close("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_close("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_popup_create() @@ -3087,81 +3101,86 @@ def Test_popup_create() enddef def Test_popup_dialog() - v9.CheckDefAndScriptFailure(['popup_dialog({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_dialog("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_dialog({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_dialog("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) enddef def Test_popup_filter_menu() - v9.CheckDefAndScriptFailure(['popup_filter_menu("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_filter_menu(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_filter_menu("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_filter_menu(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) var id: number = popup_menu(["one", "two", "three"], {}) popup_filter_menu(id, '') popup_close(id) enddef def Test_popup_filter_yesno() - v9.CheckDefAndScriptFailure(['popup_filter_yesno("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_filter_yesno(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_filter_yesno("x", "")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_filter_yesno(1, 1)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) enddef def Test_popup_getoptions() - v9.CheckDefAndScriptFailure(['popup_getoptions("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_getoptions(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_getoptions("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_getoptions(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) enddef def Test_popup_getpos() - v9.CheckDefAndScriptFailure(['popup_getpos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_getpos(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_getpos("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_getpos(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) enddef def Test_popup_hide() - v9.CheckDefAndScriptFailure(['popup_hide("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_hide(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_hide("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_hide(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) enddef def Test_popup_locate() - v9.CheckDefAndScriptFailure(['popup_locate("a", 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_locate(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_locate("a", 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_locate(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_popup_menu() - v9.CheckDefAndScriptFailure(['popup_menu({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_menu("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_menu({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_menu("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) enddef def Test_popup_move() - v9.CheckDefAndScriptFailure(['popup_move("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_move(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_move("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_move(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) enddef def Test_popup_notification() - v9.CheckDefAndScriptFailure(['popup_notification({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_notification("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_notification({"a": 10}, {})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_notification("a", [1, 2])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) enddef def Test_popup_setoptions() - v9.CheckDefAndScriptFailure(['popup_setoptions("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_setoptions(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_setoptions("x", {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_setoptions(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) enddef def Test_popup_settext() - v9.CheckDefAndScriptFailure(['popup_settext("x", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_settext(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['popup_settext("x", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_settext(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2']) +enddef + +def Test_popup_setbuf() + v9.CheckSourceDefAndScriptFailure(['popup_setbuf([], "abc")'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_setbuf(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2']) enddef def Test_popup_show() - v9.CheckDefAndScriptFailure(['popup_show("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['popup_show(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_show("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_show(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) enddef def Test_prevnonblank() - v9.CheckDefAndScriptFailure(['prevnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['prevnonblank("")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['prevnonblank(null)'], ['E1013: Argument 1: type mismatch, expected string but got special', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['prevnonblank("")'], 'E1209: Invalid value for a line number') assert_equal(0, prevnonblank(1)) enddef def Test_printf() - v9.CheckDefAndScriptFailure(['printf([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['printf([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) printf(0x10)->assert_equal('16') assert_equal(" abc", "abc"->printf("%4s")) enddef @@ -3170,7 +3189,7 @@ def Test_prompt_getprompt() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['prompt_getprompt([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prompt_getprompt([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) assert_equal('', prompt_getprompt('NonExistingBuf')) endif enddef @@ -3179,7 +3198,7 @@ def Test_prompt_setcallback() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['prompt_setcallback(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prompt_setcallback(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) endif enddef @@ -3187,7 +3206,7 @@ def Test_prompt_setinterrupt() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['prompt_setinterrupt(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prompt_setinterrupt(true, "1")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) endif enddef @@ -3195,109 +3214,109 @@ def Test_prompt_setprompt() if !has('channel') CheckFeature channel else - v9.CheckDefAndScriptFailure(['prompt_setprompt([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['prompt_setprompt(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prompt_setprompt([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prompt_setprompt(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) endif enddef def Test_prop_add() - v9.CheckDefAndScriptFailure(['prop_add("a", 2, {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_add(1, "b", {})'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['prop_add(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['prop_add("a", 2, {})'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_add(1, "b", {})'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_add(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) enddef def Test_prop_add_list() - v9.CheckDefAndScriptFailure(['prop_add_list([], [])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_add_list({}, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_add_list([], [])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_add_list({}, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2']) enddef def Test_prop_clear() - v9.CheckDefAndScriptFailure(['prop_clear("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_clear(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['prop_clear(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['prop_clear("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_clear(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_clear(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) enddef def Test_prop_find() - v9.CheckDefAndScriptFailure(['prop_find([1, 2])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_find([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_find({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_find([1, 2])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_find([1, 2], "k")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_find({"a": 10}, ["a"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2']) assert_fails("prop_find({}, '')", 'E474:') enddef def Test_prop_list() - v9.CheckDefAndScriptFailure(['prop_list("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_list(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_list("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_list(1, [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) enddef def Test_prop_remove() - v9.CheckDefAndScriptFailure(['prop_remove([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_remove({}, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['prop_remove({}, 1, "b")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['prop_remove([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_remove({}, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_remove({}, 1, "b")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) enddef def Test_prop_type_add() - v9.CheckDefAndScriptFailure(['prop_type_add({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_type_add("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_type_add({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_add("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) assert_fails("prop_type_add('', {highlight: 'Search'})", 'E475:') enddef def Test_prop_type_change() - v9.CheckDefAndScriptFailure(['prop_type_change({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_type_change("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_type_change({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_change("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) assert_fails("prop_type_change('', {highlight: 'Search'})", 'E475:') enddef def Test_prop_type_delete() - v9.CheckDefAndScriptFailure(['prop_type_delete({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_type_delete({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_type_delete("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_type_delete({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_delete({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_delete("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) assert_fails("prop_type_delete('')", 'E475:') enddef def Test_prop_type_get() - v9.CheckDefAndScriptFailure(['prop_type_get({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_type_get({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_type_get("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['prop_type_get({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_get({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_get("a", "b")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) assert_fails("prop_type_get('')", 'E475:') enddef def Test_prop_type_list() - v9.CheckDefAndScriptFailure(['prop_type_list(["a"])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['prop_type_list(2)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_list(["a"])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['prop_type_list(2)'], ['E1013: Argument 1: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 1']) enddef def Test_py3eval() if !has('python3') CheckFeature python3 endif - v9.CheckDefAndScriptFailure(['py3eval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['py3eval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) enddef def Test_pyeval() if !has('python') CheckFeature python endif - v9.CheckDefAndScriptFailure(['pyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['pyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) enddef def Test_pyxeval() if !has('python') && !has('python3') CheckFeature python endif - v9.CheckDefAndScriptFailure(['pyxeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['pyxeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) enddef def Test_rand() - v9.CheckDefAndScriptFailure(['rand(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1']) - v9.CheckDefFailure(['rand(["a"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>') + v9.CheckSourceDefAndScriptFailure(['rand(10)'], ['E1013: Argument 1: type mismatch, expected list<number> but got number', 'E1211: List required for argument 1']) + v9.CheckSourceDefFailure(['rand(["a"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>') assert_true(rand() >= 0) assert_true(rand(srand()) >= 0) enddef def Test_range() - v9.CheckDefAndScriptFailure(['range("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['range(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['range(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['range("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['range(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['range(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) # returns a list<number> but it's not declared as such assert_equal(['x', 'x'], range(2)->map((i, v) => 'x')) @@ -3306,8 +3325,8 @@ enddef def Test_readdir() eval expand('sautest')->readdir((e) => e[0] !=# '.') eval expand('sautest')->readdirex((e) => e.name[0] !=# '.') - v9.CheckDefAndScriptFailure(['readdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['readdir("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['readdir(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['readdir("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) if has('unix') # only fails on Unix-like systems assert_fails('readdir("")', 'E484: Can''t open file') @@ -3315,8 +3334,8 @@ def Test_readdir() enddef def Test_readdirex() - v9.CheckDefAndScriptFailure(['readdirex(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['readdirex("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['readdirex(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['readdirex("a", "1", [3])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) if has('unix') # only fails on Unix-like systems assert_fails('readdirex("")', 'E484: Can''t open file') @@ -3332,8 +3351,8 @@ def Test_readblob() var lines =<< trim END var read: list<string> = readblob('Xreadblob') END - v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<string> but got blob', 1) - v9.CheckDefExecAndScriptFailure(['readblob("")'], 'E484: Can''t open file <empty>') + v9.CheckSourceDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<string> but got blob', 1) + v9.CheckSourceDefExecAndScriptFailure(['readblob("")'], 'E484: Can''t open file <empty>') enddef def Test_readfile() @@ -3346,15 +3365,15 @@ def Test_readfile() var lines =<< trim END var read: dict<string> = readfile('Xreadfile') END - v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<string> but got list<string>', 1) + v9.CheckSourceDefAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<string> but got list<string>', 1) - v9.CheckDefAndScriptFailure(['readfile("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['readfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefExecAndScriptFailure(['readfile("")'], 'E1175: Non-empty string required for argument 1') + v9.CheckSourceDefAndScriptFailure(['readfile("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['readfile("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['readfile("")'], 'E1175: Non-empty string required for argument 1') enddef def Test_reduce() - v9.CheckDefAndScriptFailure(['reduce({a: 10}, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1252: String, List or Blob required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['reduce({a: 10}, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1252: String, List or Blob required for argument 1']) assert_equal(6, [1, 2, 3]->reduce((r, c) => r + c, 0)) assert_equal(11, 0z0506->reduce((r, c) => r + c, 0)) enddef @@ -3362,13 +3381,13 @@ enddef def Test_reltime() CheckFeature reltime - v9.CheckDefExecAndScriptFailure(['[]->reltime()'], 'E474:') - v9.CheckDefExecAndScriptFailure(['[]->reltime([])'], 'E474:') + v9.CheckSourceDefExecAndScriptFailure(['[]->reltime()'], 'E474:') + v9.CheckSourceDefExecAndScriptFailure(['[]->reltime([])'], 'E474:') - v9.CheckDefAndScriptFailure(['reltime("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1']) - v9.CheckDefFailure(['reltime(["x", "y"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>') - v9.CheckDefAndScriptFailure(['reltime([1, 2], 10)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2']) - v9.CheckDefFailure(['reltime([1, 2], ["a", "b"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>') + v9.CheckSourceDefAndScriptFailure(['reltime("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefFailure(['reltime(["x", "y"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>') + v9.CheckSourceDefAndScriptFailure(['reltime([1, 2], 10)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2']) + v9.CheckSourceDefFailure(['reltime([1, 2], ["a", "b"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>') var start: list<any> = reltime() assert_true(type(reltime(start)) == v:t_list) var end: list<any> = reltime() @@ -3378,31 +3397,31 @@ enddef def Test_reltimefloat() CheckFeature reltime - v9.CheckDefExecAndScriptFailure(['[]->reltimefloat()'], 'E474:') + v9.CheckSourceDefExecAndScriptFailure(['[]->reltimefloat()'], 'E474:') - v9.CheckDefAndScriptFailure(['reltimefloat("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1']) - v9.CheckDefFailure(['reltimefloat([1.1])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<float>') + v9.CheckSourceDefAndScriptFailure(['reltimefloat("x")'], ['E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefFailure(['reltimefloat([1.1])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<float>') assert_true(type(reltimefloat(reltime())) == v:t_float) enddef def Test_reltimestr() CheckFeature reltime - v9.CheckDefExecAndScriptFailure(['[]->reltimestr()'], 'E474:') + v9.CheckSourceDefExecAndScriptFailure(['[]->reltimestr()'], 'E474:') - v9.CheckDefAndScriptFailure(['reltimestr(true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got bool', 'E1211: List required for argument 1']) - v9.CheckDefFailure(['reltimestr([true])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<bool>') + v9.CheckSourceDefAndScriptFailure(['reltimestr(true)'], ['E1013: Argument 1: type mismatch, expected list<number> but got bool', 'E1211: List required for argument 1']) + v9.CheckSourceDefFailure(['reltimestr([true])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<bool>') assert_true(type(reltimestr(reltime())) == v:t_string) enddef def Test_remote_expr() CheckFeature clientserver CheckEnv DISPLAY - v9.CheckDefAndScriptFailure(['remote_expr(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['remote_expr("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['remote_expr("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) - v9.CheckDefAndScriptFailure(['remote_expr("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) - v9.CheckDefExecAndScriptFailure(['remote_expr("", "")'], 'E241: Unable to send to ') + v9.CheckSourceDefAndScriptFailure(['remote_expr(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['remote_expr("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['remote_expr("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['remote_expr("a", "b", "c", "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefExecAndScriptFailure(['remote_expr("", "")'], 'E241: Unable to send to ') enddef def Test_remote_foreground() @@ -3411,7 +3430,7 @@ def Test_remote_foreground() CheckNotMSWindows CheckX11 - v9.CheckDefAndScriptFailure(['remote_foreground(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['remote_foreground(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_fails('remote_foreground("NonExistingServer")', 'E241:') assert_fails('remote_foreground("")', 'E241:') enddef @@ -3419,32 +3438,32 @@ enddef def Test_remote_peek() CheckFeature clientserver CheckEnv DISPLAY - v9.CheckDefAndScriptFailure(['remote_peek(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['remote_peek("a5b6c7", [1])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) - v9.CheckDefExecAndScriptFailure(['remote_peek("")'], 'E573: Invalid server id used') + v9.CheckSourceDefAndScriptFailure(['remote_peek(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['remote_peek("a5b6c7", [1])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['remote_peek("")'], 'E573: Invalid server id used') enddef def Test_remote_read() CheckFeature clientserver CheckEnv DISPLAY - v9.CheckDefAndScriptFailure(['remote_read(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['remote_read("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['remote_read("")'], 'E573: Invalid server id used') + v9.CheckSourceDefAndScriptFailure(['remote_read(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['remote_read("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['remote_read("")'], 'E573: Invalid server id used') enddef def Test_remote_send() CheckFeature clientserver CheckEnv DISPLAY - v9.CheckDefAndScriptFailure(['remote_send(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['remote_send("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['remote_send("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['remote_send(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['remote_send("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['remote_send("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) assert_fails('remote_send("", "")', 'E241:') enddef def Test_remote_startserver() CheckFeature clientserver CheckEnv DISPLAY - v9.CheckDefAndScriptFailure(['remote_startserver({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['remote_startserver({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) enddef def Test_remove_literal_list() @@ -3458,28 +3477,28 @@ def Test_remove_const() const l = [1, 2, 3, 4] remove(l, 1) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') lines =<< trim END const d = {a: 1, b: 2} remove(d, 'a') END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict<number>') lines =<< trim END const b = 0z010203 remove(b, 1) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob') enddef def Test_remove() - v9.CheckDefAndScriptFailure(['remove("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1228: List, Dictionary or Blob required for argument 1']) - v9.CheckDefAndScriptFailure(['remove([], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['remove([], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['remove({}, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2']) - v9.CheckDefAndScriptFailure(['remove(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['remove(0z20, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['remove("a", 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1228: List, Dictionary or Blob required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['remove([], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['remove([], 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['remove({}, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['remove(0z10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['remove(0z20, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) var l: any = [1, 2, 3, 4] remove(l, 1) assert_equal([1, 3, 4], l) @@ -3511,14 +3530,14 @@ def Test_remove_return_type() enddef def Test_rename() - v9.CheckDefAndScriptFailure(['rename(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['rename("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['rename(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['rename("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) rename('', '')->assert_equal(0) enddef def Test_repeat() - v9.CheckDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1301: String, Number, List or Blob required for argument 1']) - v9.CheckDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1301: String, Number, List or Blob required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1301: String, Number, List or Blob required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1301: String, Number, List or Blob required for argument 1']) var lines =<< trim END assert_equal('aaa', repeat('a', 3)) assert_equal('111', repeat(1, 3)) @@ -3529,17 +3548,17 @@ def Test_repeat() s ..= repeat(5, 3) assert_equal('-555', s) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) enddef def Test_resolve() - v9.CheckDefAndScriptFailure(['resolve([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['resolve([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) assert_equal('SomeFile', resolve('SomeFile')) resolve('')->assert_equal('') enddef def Test_reverse() - v9.CheckDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1252: String, List or Blob required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['reverse(10)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1252: String, List or Blob required for argument 1']) enddef def Test_reverse_return_type() @@ -3556,49 +3575,49 @@ def Test_reverse_const() const l = [1, 2, 3, 4] reverse(l) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') lines =<< trim END const b = 0z010203 reverse(b) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const blob') enddef def Test_rubyeval() if !has('ruby') CheckFeature ruby endif - v9.CheckDefAndScriptFailure(['rubyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['rubyeval([2])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) enddef def Test_screenattr() - v9.CheckDefAndScriptFailure(['screenattr("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['screenattr(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['screenattr("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['screenattr(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_screenchar() - v9.CheckDefAndScriptFailure(['screenchar("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['screenchar(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['screenchar("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['screenchar(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_screenchars() assert_equal(['x'], screenchars(1, 1)->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['screenchars("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['screenchars(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['screenchars("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['screenchars(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_screenpos() - v9.CheckDefAndScriptFailure(['screenpos("a", 1, 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['screenpos(1, "b", 1)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['screenpos(1, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['screenpos("a", 1, 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['screenpos(1, "b", 1)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['screenpos(1, 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) assert_equal({col: 1, row: 1, endcol: 1, curscol: 1}, screenpos(1, 1, 1)) enddef def Test_screenstring() - v9.CheckDefAndScriptFailure(['screenstring("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['screenstring(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['screenstring("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['screenstring(1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_search() @@ -3630,13 +3649,13 @@ def Test_search() normal 0 assert_equal([0, 0], searchpos('this', '', 0, 0, 'col(".") > col')) bwipe! - v9.CheckDefAndScriptFailure(['search(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['search("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['search("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['search("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['search(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['search("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['search("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['search("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) new setline(1, "match this") - v9.CheckDefAndScriptFailure(['search("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String']) + v9.CheckSourceDefAndScriptFailure(['search("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String']) bwipe! enddef @@ -3652,14 +3671,14 @@ def Test_searchcount() maxcount: 99, incomplete: 0}) bwipe! - v9.CheckDefAndScriptFailure(['searchcount([1])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['searchcount([1])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 1']) enddef def Test_searchdecl() searchdecl('blah', true, true)->assert_equal(1) - v9.CheckDefAndScriptFailure(['searchdecl(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['searchdecl("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) - v9.CheckDefAndScriptFailure(['searchdecl("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['searchdecl(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['searchdecl("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['searchdecl("a", true, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) # search for an empty string declaration var lines: list<string> =<< trim END @@ -3719,7 +3738,7 @@ def Test_searchpair() enddef Fail() END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) assert_equal('yes', g:caught) unlet g:caught bwipe! @@ -3727,64 +3746,64 @@ def Test_searchpair() lines =<< trim END echo searchpair("a", "b", "c", "d", "f", 33) END - v9.CheckDefAndScriptFailure(lines, ['E1001: Variable not found: f', 'E475: Invalid argument: d']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1001: Variable not found: f', 'E475: Invalid argument: d']) var errors = ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1'] - v9.CheckDefAndScriptFailure(['searchpair(1, "b", "c")'], errors) - v9.CheckDefAndScriptFailure(['searchpairpos(1, "b", "c")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpair(1, "b", "c")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpairpos(1, "b", "c")'], errors) errors = ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2'] - v9.CheckDefAndScriptFailure(['searchpair("a", 2, "c")'], errors) - v9.CheckDefAndScriptFailure(['searchpairpos("a", 2, "c")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpair("a", 2, "c")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", 2, "c")'], errors) errors = ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3'] - v9.CheckDefAndScriptFailure(['searchpair("a", "b", 3)'], errors) - v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", 3)'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", 3)'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", 3)'], errors) errors = ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4'] - v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", 4)'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", 4)'], errors) new setline(1, "match this") errors = ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String'] - v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", "r", [0])'], errors) - v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", [0])'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", "r", [0])'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", [0])'], errors) bwipe! errors = ['E1013: Argument 6: type mismatch, expected number but got string', 'E1210: Number required for argument 6'] - v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", "f")'], errors) - v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", "f")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", "f")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", "f")'], errors) errors = ['E1013: Argument 7: type mismatch, expected number but got string', 'E1210: Number required for argument 7'] - v9.CheckDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", 3, "g")'], errors) - v9.CheckDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", 3, "g")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", 3, "g")'], errors) + v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", 3, "g")'], errors) enddef def Test_searchpos() assert_equal(['x', 'x'], searchpos('.')->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['searchpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['searchpos("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['searchpos("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['searchpos("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['searchpos(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['searchpos("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['searchpos("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['searchpos("a", "b", 3, "d")'], ['E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4']) new setline(1, "match this") - v9.CheckDefAndScriptFailure(['searchpos("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String']) + v9.CheckSourceDefAndScriptFailure(['searchpos("a", "", 9, 0, [0])'], ['E1013: Argument 5: type mismatch, expected func(...): any but got list<number>', 'E730: Using a List as a String']) bwipe! enddef def Test_server2client() CheckFeature clientserver CheckEnv DISPLAY - v9.CheckDefAndScriptFailure(['server2client(10, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['server2client("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefExecAndScriptFailure(['server2client("", "a")'], 'E573: Invalid server id used') - v9.CheckDefExecAndScriptFailure(['server2client("", "")'], 'E573: Invalid server id used') + v9.CheckSourceDefAndScriptFailure(['server2client(10, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['server2client("a", 10)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['server2client("", "a")'], 'E573: Invalid server id used') + v9.CheckSourceDefExecAndScriptFailure(['server2client("", "")'], 'E573: Invalid server id used') enddef def Test_shellescape() - v9.CheckDefAndScriptFailure(['shellescape(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['shellescape("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['shellescape(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['shellescape("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) if has('unix') assert_equal("''", shellescape('')) endif @@ -3837,7 +3856,7 @@ def Test_set_get_bufline() exe 'bwipe! ' .. b END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) enddef def Test_setbufvar() @@ -3864,8 +3883,8 @@ def Test_setbufvar() setbufvar('%', 'myvar', 123) getbufvar('%', 'myvar')->assert_equal(123) - v9.CheckDefAndScriptFailure(['setbufvar(true, "v", 3)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['setbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['setbufvar(true, "v", 3)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setbufvar(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) assert_fails('setbufvar("%", "", 10)', 'E461: Illegal variable name') enddef @@ -3878,10 +3897,10 @@ def Test_setbufline() setbufline(bnum, 5, 10) setbufline(bnum, 6, ['two', 11]) assert_equal(['1', '2', '3', 'one', '10', 'two', '11'], getbufline(bnum, 1, '$')) - v9.CheckDefAndScriptFailure(['setbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['setbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['setbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1') - v9.CheckDefAndScriptFailure(['setbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['setbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['setbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1') + v9.CheckSourceDefAndScriptFailure(['setbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict<number>', 'E1224: String, Number or List required for argument 3']) bnum->bufwinid()->win_gotoid() setbufline('', 1, 'nombres') getline(1)->assert_equal('nombres') @@ -3889,53 +3908,53 @@ def Test_setbufline() enddef def Test_setcellwidths() - v9.CheckDefAndScriptFailure(['setcellwidths(1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['setcellwidths({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setcellwidths(1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setcellwidths({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) enddef def Test_setcharpos() - v9.CheckDefAndScriptFailure(['setcharpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefFailure(['setcharpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>') - v9.CheckDefAndScriptFailure(['setcharpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2']) - v9.CheckDefExecAndScriptFailure(['setcharpos("", [0, 1, 1, 1])'], 'E474: Invalid argument') + v9.CheckSourceDefAndScriptFailure(['setcharpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefFailure(['setcharpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>') + v9.CheckSourceDefAndScriptFailure(['setcharpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['setcharpos("", [0, 1, 1, 1])'], 'E474: Invalid argument') enddef def Test_setcharsearch() - v9.CheckDefAndScriptFailure(['setcharsearch("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1']) - v9.CheckDefAndScriptFailure(['setcharsearch([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setcharsearch("x")'], ['E1013: Argument 1: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setcharsearch([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) var d: dict<any> = {char: 'x', forward: 1, until: 1} setcharsearch(d) assert_equal(d, getcharsearch()) enddef def Test_setcmdline() - v9.CheckDefAndScriptSuccess(['setcmdline("ls", 2)']) - v9.CheckDefAndScriptFailure(['setcmdline(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['setcmdline("ls", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptSuccess(['setcmdline("ls", 2)']) + v9.CheckSourceDefAndScriptFailure(['setcmdline(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setcmdline("ls", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_setcmdpos() - v9.CheckDefAndScriptFailure(['setcmdpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setcmdpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_setcursorcharpos() - v9.CheckDefAndScriptFailure(['setcursorcharpos(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1']) - v9.CheckDefAndScriptFailure(['setcursorcharpos(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['setcursorcharpos(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefExecAndScriptFailure(['setcursorcharpos("", 10)'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['setcursorcharpos(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected number but got blob', 'E1224: String, Number or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setcursorcharpos(1, "2")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['setcursorcharpos(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['setcursorcharpos("", 10)'], 'E1209: Invalid value for a line number') enddef def Test_setenv() - v9.CheckDefAndScriptFailure(['setenv(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setenv(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal(0, setenv('', '')) assert_equal(0, setenv('', v:null)) enddef def Test_setfperm() - v9.CheckDefAndScriptFailure(['setfperm(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['setfperm("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2']) - v9.CheckDefExecAndScriptFailure(['setfperm("Xfile", "")'], 'E475: Invalid argument') - v9.CheckDefExecAndScriptFailure(['setfperm("", "")'], 'E475: Invalid argument') + v9.CheckSourceDefAndScriptFailure(['setfperm(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setfperm("a", 0z10)'], ['E1013: Argument 2: type mismatch, expected string but got blob', 'E1174: String required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['setfperm("Xfile", "")'], 'E475: Invalid argument') + v9.CheckSourceDefExecAndScriptFailure(['setfperm("", "")'], 'E475: Invalid argument') assert_equal(0, setfperm('', 'rw-r--r--')) enddef @@ -3949,9 +3968,9 @@ def Test_setline() assert_equal(['one', 'b', 'c', 'd'], getline(1, '$')) setline(1, 10) assert_equal(['10', 'b', 'c', 'd'], getline(1, '$')) - v9.CheckDefAndScriptFailure(['setline([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) - v9.CheckDefExecAndScriptFailure(['setline("", "x")'], 'E1209: Invalid value for a line number') - v9.CheckDefExecAndScriptFailure(['setline(-1, "x")'], 'E966: Invalid line number: -1') + v9.CheckSourceDefAndScriptFailure(['setline([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['setline("", "x")'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecAndScriptFailure(['setline(-1, "x")'], 'E966: Invalid line number: -1') assert_fails('setline(".a", "x")', ['E1209:', 'E1209:']) bw! enddef @@ -3961,28 +3980,28 @@ def Test_setloclist() var what = {items: items} setqflist([], ' ', what) setloclist(0, [], ' ', what) - v9.CheckDefAndScriptFailure(['setloclist("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['setloclist(1, 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) - v9.CheckDefAndScriptFailure(['setloclist(1, [], 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) - v9.CheckDefAndScriptFailure(['setloclist(1, [], "a", [])'], ['E1013: Argument 4: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['setloclist("1", [])'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setloclist(1, 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['setloclist(1, [], 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['setloclist(1, [], "a", [])'], ['E1013: Argument 4: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 4']) enddef def Test_setmatches() - v9.CheckDefAndScriptFailure(['setmatches({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['setmatches([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['setmatches({})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setmatches([], "1")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_setpos() - v9.CheckDefAndScriptFailure(['setpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefFailure(['setpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>') - v9.CheckDefAndScriptFailure(['setpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2']) - v9.CheckDefExecAndScriptFailure(['setpos("", [0, 1, 1, 1])'], 'E474: Invalid argument') + v9.CheckSourceDefAndScriptFailure(['setpos(1, [])'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefFailure(['setpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>') + v9.CheckSourceDefAndScriptFailure(['setpos(".", 1)'], ['E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['setpos("", [0, 1, 1, 1])'], 'E474: Invalid argument') enddef def Test_setqflist() - v9.CheckDefAndScriptFailure(['setqflist(1, "")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['setqflist([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['setqflist([], "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['setqflist(1, "")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setqflist([], 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['setqflist([], "", [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) enddef def Test_setreg() @@ -3991,111 +4010,111 @@ def Test_setreg() setreg('a', reginfo) getreginfo('a')->assert_equal(reginfo) assert_fails('setreg("ab", 0)', 'E1162:') - v9.CheckDefAndScriptFailure(['setreg(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['setreg("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['setreg(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setreg("a", "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) setreg('', '1a2b3c') assert_equal('1a2b3c', @") enddef def Test_settabvar() - v9.CheckDefAndScriptFailure(['settabvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['settabvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['settabvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['settabvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) assert_fails('settabvar(1, "", 10)', 'E461: Illegal variable name') enddef def Test_settabwinvar() - v9.CheckDefAndScriptFailure(['settabwinvar("a", 2, "c", true)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['settabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['settabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['settabwinvar("a", 2, "c", true)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['settabwinvar(1, "b", "c", [])'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['settabwinvar(1, 1, 3, {})'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) assert_fails('settabwinvar(1, 1, "", 10)', 'E461: Illegal variable name') enddef def Test_settagstack() - v9.CheckDefAndScriptFailure(['settagstack(true, {})'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['settagstack(1, [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) - v9.CheckDefAndScriptFailure(['settagstack(1, {}, 2)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['settagstack(true, {})'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['settagstack(1, [1])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['settagstack(1, {}, 2)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) assert_fails('settagstack(1, {}, "")', 'E962: Invalid action') enddef def Test_setwinvar() - v9.CheckDefAndScriptFailure(['setwinvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['setwinvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['setwinvar("a", "b", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['setwinvar(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) assert_fails('setwinvar(1, "", 10)', 'E461: Illegal variable name') assert_fails('setwinvar(0, "&rulerformat", true)', ['E928:', 'E928:']) enddef def Test_sha256() - v9.CheckDefAndScriptFailure(['sha256(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['sha256(0zABCD)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sha256(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sha256(0zABCD)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) assert_equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha256('abc')) assert_equal('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha256('')) enddef def Test_shiftwidth() - v9.CheckDefAndScriptFailure(['shiftwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['shiftwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_sign_define() - v9.CheckDefAndScriptFailure(['sign_define({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_define({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_define("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['sign_define({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_define({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_define("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) enddef def Test_sign_getdefined() - v9.CheckDefAndScriptFailure(['sign_getdefined(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_getdefined(2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_getdefined(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_getdefined(2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) sign_getdefined('')->assert_equal([]) enddef def Test_sign_getplaced() - v9.CheckDefAndScriptFailure(['sign_getplaced(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_getplaced(1, ["a"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) - v9.CheckDefAndScriptFailure(['sign_getplaced("a", 1.1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got float', 'E1206: Dictionary required for argument 2']) - v9.CheckDefExecAndScriptFailure(['sign_getplaced(bufnr(), {lnum: ""})'], 'E1030: Using a String as a Number:') + v9.CheckSourceDefAndScriptFailure(['sign_getplaced(["x"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_getplaced(1, ["a"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['sign_getplaced("a", 1.1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got float', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['sign_getplaced(bufnr(), {lnum: ""})'], 'E1030: Using a String as a Number:') sign_getplaced('')->assert_equal([{signs: [], bufnr: bufnr()}]) enddef def Test_sign_jump() - v9.CheckDefAndScriptFailure(['sign_jump("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_jump(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['sign_jump(1, "b", true)'], ['E1013: Argument 3: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['sign_jump("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_jump(1, 2, 3)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['sign_jump(1, "b", true)'], ['E1013: Argument 3: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 3']) enddef def Test_sign_place() - v9.CheckDefAndScriptFailure(['sign_place("a", "b", "c", "d")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_place(1, 2, "c", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['sign_place(1, "b", 3, "d")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) - v9.CheckDefAndScriptFailure(['sign_place(1, "b", "c", 1.1)'], ['E1013: Argument 4: type mismatch, expected string but got float', 'E1220: String or Number required for argument 4']) - v9.CheckDefAndScriptFailure(['sign_place(1, "b", "c", "d", [1])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 5']) - v9.CheckDefExecAndScriptFailure(['sign_place(0, "", "MySign", bufnr(), {lnum: ""})'], 'E1209: Invalid value for a line number: ""') + v9.CheckSourceDefAndScriptFailure(['sign_place("a", "b", "c", "d")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_place(1, 2, "c", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['sign_place(1, "b", 3, "d")'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['sign_place(1, "b", "c", 1.1)'], ['E1013: Argument 4: type mismatch, expected string but got float', 'E1220: String or Number required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['sign_place(1, "b", "c", "d", [1])'], ['E1013: Argument 5: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 5']) + v9.CheckSourceDefExecAndScriptFailure(['sign_place(0, "", "MySign", bufnr(), {lnum: ""})'], 'E1209: Invalid value for a line number: ""') assert_fails("sign_place(0, '', '', '')", 'E155:') enddef def Test_sign_placelist() - v9.CheckDefAndScriptFailure(['sign_placelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_placelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) - v9.CheckDefExecAndScriptFailure(['sign_placelist([{"name": "MySign", "buffer": bufnr(), "lnum": ""}])'], 'E1209: Invalid value for a line number: ""') + v9.CheckSourceDefAndScriptFailure(['sign_placelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_placelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['sign_placelist([{"name": "MySign", "buffer": bufnr(), "lnum": ""}])'], 'E1209: Invalid value for a line number: ""') assert_fails('sign_placelist([{name: "MySign", buffer: "", lnum: 1}])', 'E155:') enddef def Test_sign_undefine() - v9.CheckDefAndScriptFailure(['sign_undefine({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_undefine([1])'], ['E1013: Argument 1: type mismatch, expected list<string> but got list<number>', 'E155: Unknown sign:']) + v9.CheckSourceDefAndScriptFailure(['sign_undefine({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_undefine([1])'], ['E1013: Argument 1: type mismatch, expected list<string> but got list<number>', 'E155: Unknown sign:']) enddef def Test_sign_unplace() - v9.CheckDefAndScriptFailure(['sign_unplace({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_unplace({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_unplace("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['sign_unplace({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_unplace({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_unplace("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) enddef def Test_sign_unplacelist() - v9.CheckDefAndScriptFailure(['sign_unplacelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['sign_unplacelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_unplacelist("x")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sign_unplacelist({"a": 10})'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) enddef def Test_simplify() - v9.CheckDefAndScriptFailure(['simplify(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['simplify(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) call assert_equal('NonExistingFile', simplify('NonExistingFile')) simplify('')->assert_equal('') enddef @@ -4105,9 +4124,9 @@ def Test_slice() assert_equal(['val'], lds->slice(0, 1)->map((_, v) => 'val')) assert_equal(['val'], lds[ : ]->map((_, v) => 'val')) - v9.CheckDefAndScriptFailure(['slice({"a": 10}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['slice([1, 2, 3], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['slice("abc", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['slice({"a": 10}, 1)'], ['E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['slice([1, 2, 3], "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['slice("abc", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) enddef def Test_spellsuggest() @@ -4116,29 +4135,29 @@ def Test_spellsuggest() else spellsuggest('marrch', 1, true)->assert_equal(['March']) endif - v9.CheckDefAndScriptFailure(['spellsuggest(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['spellsuggest("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['spellsuggest("a", 1, 0z01)'], ['E1013: Argument 3: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['spellsuggest(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['spellsuggest("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['spellsuggest("a", 1, 0z01)'], ['E1013: Argument 3: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 3']) spellsuggest('')->assert_equal([]) enddef def Test_sound_playevent() CheckFeature sound - v9.CheckDefAndScriptFailure(['sound_playevent(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sound_playevent(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) enddef def Test_sound_playfile() CheckFeature sound - v9.CheckDefAndScriptFailure(['sound_playfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sound_playfile(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) enddef def Test_sound_stop() CheckFeature sound - v9.CheckDefAndScriptFailure(['sound_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sound_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_soundfold() - v9.CheckDefAndScriptFailure(['soundfold(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['soundfold(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal('abc', soundfold('abc')) assert_equal('', soundfold('')) enddef @@ -4160,12 +4179,12 @@ def Test_sort_argument() sort(l, Compare) assert_equal([1, 2, 3, 4, 5, 6, 7, 8], l) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END sort([1, 2, 3], (a: any, b: any) => 1) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END vim9script @@ -4176,7 +4195,7 @@ def Test_sort_argument() enddef SortedList()->assert_equal([1, 2, 3]) END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) enddef def Test_sort_const() @@ -4184,12 +4203,12 @@ def Test_sort_const() const l = [1, 2, 3, 4] sort(l) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') enddef def Test_sort_compare_func_fails() - v9.CheckDefAndScriptFailure(['sort("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['sort([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['sort("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sort([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) var lines =<< trim END vim9script @@ -4202,31 +4221,31 @@ def Test_sort_compare_func_fails() var l = [1, 2, 3] sort(l, (a: string, b: number) => 1) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number', 'E1013: Argument 1: type mismatch, expected string but got number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number', 'E1013: Argument 1: type mismatch, expected string but got number']) lines =<< trim END var l = ['a', 'b', 'c'] sort(l, (a: string, b: number) => 1) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?string): number but got func(string, number): number', 'E1013: Argument 2: type mismatch, expected number but got string']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?string): number but got func(string, number): number', 'E1013: Argument 2: type mismatch, expected number but got string']) lines =<< trim END sort([1, 2, 3], (a: number, b: number) => true) END - v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): bool', 'E1138: Using a Bool as a Number']) + v9.CheckSourceDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): bool', 'E1138: Using a Bool as a Number']) enddef def Test_spellbadword() - v9.CheckDefAndScriptFailure(['spellbadword(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['spellbadword(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) spellbadword('good')->assert_equal(['', '']) spellbadword('')->assert_equal(['', '']) enddef def Test_split() split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) - v9.CheckDefAndScriptFailure(['split(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['split("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['split("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['split(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['split("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['split("a", "b", 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) split('')->assert_equal([]) split('', '')->assert_equal([]) enddef @@ -4235,12 +4254,12 @@ def Test_srand() var expected = srand()->len()->range()->map((_, _) => 'x') assert_equal(expected, srand()->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['srand("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['srand("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) type(srand(100))->assert_equal(v:t_list) enddef def Test_state() - v9.CheckDefAndScriptFailure(['state({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['state({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) assert_equal('', state('a')) enddef @@ -4249,14 +4268,14 @@ def Test_str2float() str2float("2e-2")->assert_equal(0.02) str2float('')->assert_equal(0.0) - v9.CheckDefAndScriptFailure(['str2float(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['str2float(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) enddef def Test_str2list() assert_equal(['x', 'x', 'x'], str2list('abc')->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['str2list(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['str2list("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['str2list(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['str2list("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) assert_equal([97], str2list('a')) assert_equal([97], str2list('a', 1)) assert_equal([97], str2list('a', true)) @@ -4267,29 +4286,29 @@ def Test_str2nr() str2nr("1'000'000", 10, true)->assert_equal(1000000) str2nr('')->assert_equal(0) - v9.CheckDefAndScriptFailure(['str2nr(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['str2nr("123", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['str2nr("123", 10, "x")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['str2nr(123)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['str2nr("123", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['str2nr("123", 10, "x")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) enddef def Test_strcharlen() - v9.CheckDefAndScriptFailure(['strcharlen([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strcharlen([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) "abc"->strcharlen()->assert_equal(3) strcharlen(99)->assert_equal(2) enddef def Test_strcharpart() - v9.CheckDefAndScriptFailure(['strcharpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strcharpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['strcharpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['strcharpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['strcharpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strcharpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strcharpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['strcharpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) strcharpart('', 0)->assert_equal('') enddef def Test_strchars() strchars("A\u20dd", true)->assert_equal(1) - v9.CheckDefAndScriptFailure(['strchars(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strchars("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strchars(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strchars("a", 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) assert_equal(3, strchars('abc')) assert_equal(3, strchars('abc', 1)) assert_equal(3, strchars('abc', true)) @@ -4297,46 +4316,46 @@ def Test_strchars() enddef def Test_strdisplaywidth() - v9.CheckDefAndScriptFailure(['strdisplaywidth(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strdisplaywidth("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strdisplaywidth(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strdisplaywidth("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) strdisplaywidth('')->assert_equal(0) enddef def Test_strftime() if exists('*strftime') - v9.CheckDefAndScriptFailure(['strftime(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strftime("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strftime(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strftime("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) strftime('')->assert_equal('') endif enddef def Test_strgetchar() - v9.CheckDefAndScriptFailure(['strgetchar(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strgetchar("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strgetchar(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strgetchar("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) strgetchar('', 0)->assert_equal(-1) strgetchar('', 1)->assert_equal(-1) enddef def Test_stridx() - v9.CheckDefAndScriptFailure(['stridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['stridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['stridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['stridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['stridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['stridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) stridx('', '')->assert_equal(0) stridx('', 'a')->assert_equal(-1) stridx('a', '')->assert_equal(0) enddef def Test_strlen() - v9.CheckDefAndScriptFailure(['strlen([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strlen([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) "abc"->strlen()->assert_equal(3) strlen(99)->assert_equal(2) enddef def Test_strpart() - v9.CheckDefAndScriptFailure(['strpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['strpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) - v9.CheckDefAndScriptFailure(['strpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['strpart(1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strpart("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strpart("a", 1, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['strpart("a", 1, 1, 2)'], ['E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4']) strpart('', 0)->assert_equal('') enddef @@ -4344,8 +4363,8 @@ def Test_strptime() CheckFunction strptime CheckNotBSD if exists_compiled('*strptime') - v9.CheckDefAndScriptFailure(['strptime(10, "2021")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strptime("%Y", 2021)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strptime(10, "2021")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strptime("%Y", 2021)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) assert_notequal(0, strptime('%Y', '2021')) # This fails on BSD 14 and returns # -2209078800 instead of 0 @@ -4354,30 +4373,30 @@ def Test_strptime() enddef def Test_strridx() - v9.CheckDefAndScriptFailure(['strridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['strridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['strridx([1], "b")'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strridx("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strridx("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) strridx('', '')->assert_equal(0) strridx('', 'a')->assert_equal(-1) strridx('a', '')->assert_equal(1) enddef def Test_strtrans() - v9.CheckDefAndScriptFailure(['strtrans(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strtrans(20)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal('abc', strtrans('abc')) strtrans('')->assert_equal('') enddef def Test_strutf16len() - v9.CheckDefAndScriptFailure(['strutf16len([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['strutf16len("a", "")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['strutf16len([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strutf16len("a", "")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) ""->strutf16len()->assert_equal(0) '-ą́-ą́'->strutf16len(true)->assert_equal(8) '-ą́-ą́'->strutf16len(false)->assert_equal(4) enddef def Test_strwidth() - v9.CheckDefAndScriptFailure(['strwidth(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['strwidth(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal(4, strwidth('abcd')) strwidth('')->assert_equal(0) enddef @@ -4388,8 +4407,8 @@ def Test_submatch() var actual = substitute('A123456789', pat, Rep, '') var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" actual->assert_equal(expected) - v9.CheckDefAndScriptFailure(['submatch("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['submatch(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['submatch("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['submatch(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) enddef def Test_substitute() @@ -4400,30 +4419,30 @@ def Test_substitute() assert_fails('"text"->substitute(".*", () => test_null_job(), "")', 'E908: Using an invalid value as a String: job') assert_fails('"text"->substitute(".*", () => test_null_channel(), "")', 'E908: Using an invalid value as a String: channel') endif - v9.CheckDefAndScriptFailure(['substitute(1, "b", "1", "d")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['substitute("a", 2, "1", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['substitute("a", "b", "1", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['substitute(1, "b", "1", "d")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['substitute("a", 2, "1", "d")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['substitute("a", "b", "1", 4)'], ['E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4']) substitute('', '', '', '')->assert_equal('') var lines =<< trim END assert_equal("4", substitute("3", '\d', '\=str2nr(submatch(0)) + 1', 'g')) END - v9.CheckDefAndScriptSuccess(lines) + v9.CheckSourceDefAndScriptSuccess(lines) lines =<< trim END assert_equal("4", substitute("3", '\d', '\="text" x', 'g')) END - v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: x') + v9.CheckSourceDefAndScriptFailure(lines, 'E488: Trailing characters: x') enddef def Test_swapinfo() - v9.CheckDefAndScriptFailure(['swapinfo({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['swapinfo({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1174: String required for argument 1']) call swapinfo('x')->assert_equal({error: 'Cannot open file'}) call swapinfo('')->assert_equal({error: 'Cannot open file'}) enddef def Test_swapname() - v9.CheckDefAndScriptFailure(['swapname([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['swapname([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) assert_fails('swapname("NonExistingBuf")', 'E94:') enddef @@ -4432,46 +4451,46 @@ def Test_synID() setline(1, "text") synID(1, 1, true)->assert_equal(0) bwipe! - v9.CheckDefAndScriptFailure(['synID(0z10, 1, true)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['synID("a", true, false)'], ['E1013: Argument 2: type mismatch, expected number but got bool', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['synID(1, 1, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) - v9.CheckDefExecAndScriptFailure(['synID("", 10, true)'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['synID(0z10, 1, true)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['synID("a", true, false)'], ['E1013: Argument 2: type mismatch, expected number but got bool', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['synID(1, 1, 2)'], ['E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['synID("", 10, true)'], 'E1209: Invalid value for a line number') enddef def Test_synIDattr() - v9.CheckDefAndScriptFailure(['synIDattr("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['synIDattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['synIDattr(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['synIDattr("a", "b")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['synIDattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['synIDattr(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) synIDattr(1, '', '')->assert_equal('') enddef def Test_synIDtrans() - v9.CheckDefAndScriptFailure(['synIDtrans("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['synIDtrans("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_synconcealed() - v9.CheckDefAndScriptFailure(['synconcealed(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['synconcealed(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['synconcealed(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['synconcealed(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) if has('conceal') - v9.CheckDefExecAndScriptFailure(['synconcealed("", 4)'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefExecAndScriptFailure(['synconcealed("", 4)'], 'E1209: Invalid value for a line number') endif enddef def Test_synstack() - v9.CheckDefAndScriptFailure(['synstack(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['synstack(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefExecAndScriptFailure(['synstack("", 4)'], 'E1209: Invalid value for a line number') + v9.CheckSourceDefAndScriptFailure(['synstack(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['synstack(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['synstack("", 4)'], 'E1209: Invalid value for a line number') enddef def Test_system() - v9.CheckDefAndScriptFailure(['system(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['system("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['system(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['system("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2']) assert_equal("123\n", system('echo 123')) enddef def Test_systemlist() - v9.CheckDefAndScriptFailure(['systemlist(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['systemlist("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['systemlist(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['systemlist("a", {})'], ['E1013: Argument 2: type mismatch, expected string but got dict<any>', 'E1224: String, Number or List required for argument 2']) if has('win32') call assert_equal(["123\r"], systemlist('echo 123')) else @@ -4480,106 +4499,107 @@ def Test_systemlist() enddef def Test_tabpagebuflist() - v9.CheckDefAndScriptFailure(['tabpagebuflist("t")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['tabpagebuflist("t")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) assert_equal([bufnr('')], tabpagebuflist()) assert_equal([bufnr('')], tabpagebuflist(1)) assert_equal(['x'], tabpagebuflist()->map((_, _) => 'x')) enddef def Test_tabpagenr() - v9.CheckDefAndScriptFailure(['tabpagenr(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefExecAndScriptFailure(['tabpagenr("")'], 'E15: Invalid expression') + v9.CheckSourceDefAndScriptFailure(['tabpagenr(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['tabpagenr("")'], 'E15: Invalid expression') assert_equal(1, tabpagenr('$')) assert_equal(1, tabpagenr()) enddef def Test_tabpagewinnr() - v9.CheckDefAndScriptFailure(['tabpagewinnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['tabpagewinnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefExecAndScriptFailure(['tabpagewinnr(1, "")'], 'E15: Invalid expression') + v9.CheckSourceDefAndScriptFailure(['tabpagewinnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['tabpagewinnr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['tabpagewinnr(1, "")'], 'E15: Invalid expression') enddef def Test_taglist() - v9.CheckDefAndScriptFailure(['taglist([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['taglist("a", [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['taglist([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['taglist("a", [2])'], ['E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2']) taglist('')->assert_equal(0) taglist('', '')->assert_equal(0) enddef def Test_term_dumpload() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_dumpload({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['term_dumpload({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['term_dumpload("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) - v9.CheckDefExecAndScriptFailure(['term_dumpload("")'], 'E485: Can''t read file') + v9.CheckSourceDefAndScriptFailure(['term_dumpload({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_dumpload({"a": 10}, "b")'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_dumpload("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['term_dumpload("")'], 'E485: Can''t read file') enddef def Test_term_dumpdiff() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_dumpdiff(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['term_dumpdiff("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['term_dumpdiff("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) - v9.CheckDefExecAndScriptFailure(['term_dumpdiff("", "")'], 'E485: Can''t read file') + v9.CheckSourceDefAndScriptFailure(['term_dumpdiff(1, "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_dumpdiff("a", 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_dumpdiff("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['term_dumpdiff("", "")'], 'E485: Can''t read file') enddef def Test_term_dumpwrite() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_dumpwrite(true, "b")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_dumpwrite(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['term_dumpwrite("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['term_dumpwrite(true, "b")'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_dumpwrite(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_dumpwrite("a", "b", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) enddef def Test_term_getaltscreen() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getaltscreen(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getaltscreen(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) enddef def Test_term_getansicolors() CheckRunVimInTerminal CheckFeature termguicolors - v9.CheckDefAndScriptFailure(['term_getansicolors(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getansicolors(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1220: String or Number required for argument 1']) enddef def Test_term_getattr() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getattr("x", "a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_getattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_getattr("x", "a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getattr(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) enddef def Test_term_getcursor() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getcursor({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getcursor({"a": 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1220: String or Number required for argument 1']) enddef def Test_term_getjob() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getjob(0z10)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) + 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() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getline(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_getline(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_getline(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getline(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2']) enddef def Test_term_getscrolled() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getscrolled(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getscrolled(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) enddef def Test_term_getsize() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getsize(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getsize(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) enddef def Test_term_getstatus() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_getstatus(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_getstatus(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) enddef def Test_term_gettitle() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_gettitle(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_gettitle(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) enddef def Test_term_gettty() @@ -4590,28 +4610,28 @@ def Test_term_gettty() term_gettty(buf, true)->assert_notequal('') g:StopShellInTerminal(buf) endif - v9.CheckDefAndScriptFailure(['term_gettty([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_gettty(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_gettty([1])'], ['E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_gettty(1, 2)'], ['E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2']) enddef def Test_term_scrape() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_scrape(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_scrape(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_scrape(1.1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_scrape(1, 1.1)'], ['E1013: Argument 2: type mismatch, expected string but got float', 'E1220: String or Number required for argument 2']) enddef def Test_term_sendkeys() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_sendkeys([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_sendkeys(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_sendkeys([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_sendkeys(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) enddef def Test_term_setansicolors() CheckRunVimInTerminal if has('termguicolors') || has('gui') - v9.CheckDefAndScriptFailure(['term_setansicolors([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_setansicolors(10, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_setansicolors([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_setansicolors(10, {})'], ['E1013: Argument 2: type mismatch, expected list<any> but got dict<any>', 'E1211: List required for argument 2']) else throw 'Skipped: Only works with termguicolors or gui feature' endif @@ -4619,27 +4639,27 @@ enddef def Test_term_setapi() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_setapi([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_setapi(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_setapi([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_setapi(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) enddef def Test_term_setkill() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_setkill([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_setkill(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_setkill([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_setkill(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) enddef def Test_term_setrestore() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_setrestore([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_setrestore(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_setrestore([], "p")'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_setrestore(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1174: String required for argument 2']) enddef def Test_term_setsize() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_setsize(1.1, 2, 3)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_setsize(1, "2", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['term_setsize(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['term_setsize(1.1, 2, 3)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_setsize(1, "2", 3)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_setsize(1, 2, "3")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) enddef def Test_term_start() @@ -4652,76 +4672,76 @@ def Test_term_start() winnr()->assert_equal(winnr) bwipe! endif - v9.CheckDefAndScriptFailure(['term_start({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['term_start([], [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) - v9.CheckDefAndScriptFailure(['term_start("", "")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) - v9.CheckDefExecAndScriptFailure(['term_start("")'], 'E474: Invalid argument') + v9.CheckSourceDefAndScriptFailure(['term_start({})'], ['E1013: Argument 1: type mismatch, expected string but got dict<any>', 'E1222: String or List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_start([], [])'], ['E1013: Argument 2: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_start("", "")'], ['E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefExecAndScriptFailure(['term_start("")'], 'E474: Invalid argument') enddef def Test_term_wait() CheckRunVimInTerminal - v9.CheckDefAndScriptFailure(['term_wait(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) - v9.CheckDefAndScriptFailure(['term_wait(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['term_wait(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['term_wait(1, "a")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_test_alloc_fail() - v9.CheckDefAndScriptFailure(['test_alloc_fail("a", 10, 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['test_alloc_fail(10, "b", 20)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['test_alloc_fail(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['test_alloc_fail("a", 10, 20)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_alloc_fail(10, "b", 20)'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['test_alloc_fail(10, 20, "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) enddef def Test_test_feedinput() - v9.CheckDefAndScriptFailure(['test_feedinput(test_void())'], ['E1013: Argument 1: type mismatch, expected string but got void', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['test_feedinput(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_feedinput(test_void())'], ['E1013: Argument 1: type mismatch, expected string but got void', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_feedinput(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) enddef def Test_test_getvalue() - v9.CheckDefAndScriptFailure(['test_getvalue(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_getvalue(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1']) enddef def Test_test_gui_event() CheckGui - v9.CheckDefAndScriptFailure(['test_gui_event([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['test_gui_event("abc", 1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['test_gui_event([], {})'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_gui_event("abc", 1)'], ['E1013: Argument 2: type mismatch, expected dict<any> but got number', 'E1206: Dictionary required for argument 2']) enddef def Test_test_ignore_error() - v9.CheckDefAndScriptFailure(['test_ignore_error([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_ignore_error([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) test_ignore_error('RESET') enddef def Test_test_option_not_set() - v9.CheckDefAndScriptFailure(['test_option_not_set([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_option_not_set([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) enddef def Test_test_override() - v9.CheckDefAndScriptFailure(['test_override(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['test_override("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['test_override(1, 1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_override("a", "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_test_setmouse() - v9.CheckDefAndScriptFailure(['test_setmouse("a", 10)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['test_setmouse(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['test_setmouse("a", 10)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_setmouse(10, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_test_settime() - v9.CheckDefAndScriptFailure(['test_settime([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_settime([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1']) enddef def Test_test_srand_seed() - v9.CheckDefAndScriptFailure(['test_srand_seed([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['test_srand_seed("10")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_srand_seed([1])'], ['E1013: Argument 1: type mismatch, expected number but got list<number>', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['test_srand_seed("10")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_timer_info() - v9.CheckDefAndScriptFailure(['timer_info("id")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['timer_info("id")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) assert_equal([], timer_info(100)) assert_equal([], timer_info()->filter((_, t) => t.callback->string() !~ 'TestTimeout')) enddef def Test_timer_pause() - v9.CheckDefAndScriptFailure(['timer_pause("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['timer_pause(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['timer_pause("x", 1)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['timer_pause(1, "a")'], ['E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) enddef def Test_timer_paused() @@ -4733,31 +4753,31 @@ def Test_timer_paused() enddef def Test_timer_start() - v9.CheckDefAndScriptFailure(['timer_start("a", "1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['timer_start(1, "1", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) - v9.CheckDefExecAndScriptFailure(['timer_start(100, 0)'], 'E921:') - v9.CheckDefExecAndScriptFailure(['timer_start(100, "")'], 'E921:') + v9.CheckSourceDefAndScriptFailure(['timer_start("a", "1")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['timer_start(1, "1", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefExecAndScriptFailure(['timer_start(100, 0)'], 'E921:') + v9.CheckSourceDefExecAndScriptFailure(['timer_start(100, "")'], 'E921:') enddef def Test_timer_stop() - v9.CheckDefAndScriptFailure(['timer_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['timer_stop("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) assert_equal(0, timer_stop(100)) enddef def Test_tolower() - v9.CheckDefAndScriptFailure(['tolower(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['tolower(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) tolower('')->assert_equal('') enddef def Test_toupper() - v9.CheckDefAndScriptFailure(['toupper(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['toupper(1)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) toupper('')->assert_equal('') enddef def Test_tr() - v9.CheckDefAndScriptFailure(['tr(1, "a", "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['tr("a", 1, "b")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['tr("a", "a", 1)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['tr(1, "a", "b")'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['tr("a", 1, "b")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['tr("a", "a", 1)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) tr('', '', '')->assert_equal('') tr('ab', '', '')->assert_equal('ab') assert_fails("tr('ab', 'ab', '')", 'E475:') @@ -4765,9 +4785,9 @@ def Test_tr() enddef def Test_trim() - v9.CheckDefAndScriptFailure(['trim(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2']) - v9.CheckDefAndScriptFailure(['trim("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['trim(["a"])'], ['E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['trim("a", ["b"])'], ['E1013: Argument 2: type mismatch, expected string but got list<string>', 'E1174: String required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['trim("a", "b", "c")'], ['E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3']) trim('')->assert_equal('') trim('', '')->assert_equal('') enddef @@ -4783,26 +4803,28 @@ def Test_typename() if has('channel') assert_equal('channel', test_null_channel()->typename()) endif + var l: list<func(list<number>): number> = [function('min')] + assert_equal('list<func(list<number>): number>', typename(l)) enddef def Test_undofile() - v9.CheckDefAndScriptFailure(['undofile(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['undofile(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) assert_equal('.abc.un~', fnamemodify(undofile('abc'), ':t')) undofile('')->assert_equal('') enddef def Test_uniq() - v9.CheckDefAndScriptFailure(['uniq("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) - v9.CheckDefAndScriptFailure(['uniq([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['uniq("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['uniq([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3']) - v9.CheckDefFailure(['var l: list<number> = uniq(["a", "b"])'], 'E1012: Type mismatch; expected list<number> but got list<string>') + v9.CheckSourceDefFailure(['var l: list<number> = uniq(["a", "b"])'], 'E1012: Type mismatch; expected list<number> but got list<string>') enddef def Test_utf16idx() - v9.CheckDefAndScriptFailure(['utf16idx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) - v9.CheckDefAndScriptFailure(['utf16idx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['utf16idx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) - v9.CheckDefAndScriptFailure(['utf16idx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4']) + v9.CheckSourceDefAndScriptFailure(['utf16idx(0z10, 1)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['utf16idx("a", "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['utf16idx("a", 1, "")'], ['E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['utf16idx("a", 1, 0, "")'], ['E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4']) utf16idx('', 0)->assert_equal(0) utf16idx('', 1)->assert_equal(-1) enddef @@ -4812,11 +4834,11 @@ def Test_uniq_const() const l = [1, 2, 3, 4] uniq(l) END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') + v9.CheckSourceDefFailure(lines, 'E1307: Argument 1: Trying to modify a const list<number>') enddef def Test_values() - v9.CheckDefAndScriptFailure(['values([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['values([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) assert_equal([], {}->values()) assert_equal(['sun'], {star: 'sun'}->values()) @@ -4843,20 +4865,20 @@ def Test_values() Process(D) END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) enddef def Test_virtcol() - v9.CheckDefAndScriptFailure(['virtcol(1.1)'], [ + v9.CheckSourceDefAndScriptFailure(['virtcol(1.1)'], [ 'E1013: Argument 1: type mismatch, expected string but got float', 'E1222: String or List required for argument 1']) - v9.CheckDefAndScriptFailure(['virtcol(".", "a")'], [ + v9.CheckSourceDefAndScriptFailure(['virtcol(".", "a")'], [ 'E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2']) - v9.CheckDefAndScriptFailure(['virtcol(".", v:true, [])'], [ + v9.CheckSourceDefAndScriptFailure(['virtcol(".", v:true, [])'], [ 'E1013: Argument 3: type mismatch, expected number but got list', 'E1210: Number required for argument 3']) - v9.CheckDefExecAndScriptFailure(['virtcol("")'], + v9.CheckSourceDefExecAndScriptFailure(['virtcol("")'], 'E1209: Invalid value for a line number') new setline(1, ['abcde和平fgh']) @@ -4872,8 +4894,8 @@ def Test_virtcol() enddef def Test_visualmode() - v9.CheckDefAndScriptFailure(['visualmode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) - v9.CheckDefAndScriptFailure(['visualmode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['visualmode("1")'], ['E1013: Argument 1: type mismatch, expected bool but got string', 'E1212: Bool required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['visualmode(2)'], ['E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1']) enddef def Test_win_execute() @@ -4881,29 +4903,29 @@ def Test_win_execute() assert_equal("\n" .. winnr(), 'echo winnr()'->win_execute(win_getid())) assert_equal("\n" .. winnr(), win_execute(win_getid(), 'echo winnr()', 'silent')) assert_equal('', win_execute(342343, 'echo winnr()')) - v9.CheckDefAndScriptFailure(['win_execute("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['win_execute(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2']) - v9.CheckDefAndScriptFailure(['win_execute(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['win_execute("a", "b", "c")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_execute(1, 2, "c")'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['win_execute(1, "b", 3)'], ['E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3']) enddef def Test_win_findbuf() - v9.CheckDefAndScriptFailure(['win_findbuf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_findbuf("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) assert_equal([], win_findbuf(1000)) assert_equal([win_getid()], win_findbuf(bufnr(''))) enddef def Test_win_getid() - v9.CheckDefAndScriptFailure(['win_getid(".")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['win_getid(1, ".")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['win_getid(".")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_getid(1, ".")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) assert_equal(win_getid(), win_getid(1, 1)) enddef def Test_win_gettype() - v9.CheckDefAndScriptFailure(['win_gettype("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_gettype("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_win_gotoid() - v9.CheckDefAndScriptFailure(['win_gotoid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_gotoid("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef func Test_win_gotoid_in_mapping() @@ -4948,43 +4970,43 @@ func Test_win_gotoid_in_mapping() endfunc def Test_win_id2tabwin() - v9.CheckDefAndScriptFailure(['win_id2tabwin("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_id2tabwin("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_win_id2win() - v9.CheckDefAndScriptFailure(['win_id2win("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_id2win("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_win_screenpos() assert_equal(['x', 'x'], win_screenpos(1)->map((_, _) => 'x')) - v9.CheckDefAndScriptFailure(['win_screenpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_screenpos("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_win_splitmove() split win_splitmove(1, 2, {vertical: true, rightbelow: true}) close - v9.CheckDefAndScriptFailure(['win_splitmove("a", 2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['win_splitmove(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) - v9.CheckDefAndScriptFailure(['win_splitmove(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) + v9.CheckSourceDefAndScriptFailure(['win_splitmove("a", 2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['win_splitmove(1, "b")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['win_splitmove(1, 2, [])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 3']) enddef def Test_winbufnr() - v9.CheckDefAndScriptFailure(['winbufnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['winbufnr("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_winheight() - v9.CheckDefAndScriptFailure(['winheight("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['winheight("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_winlayout() - v9.CheckDefAndScriptFailure(['winlayout("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['winlayout("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_winnr() - v9.CheckDefAndScriptFailure(['winnr([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) - v9.CheckDefExecAndScriptFailure(['winnr("")'], 'E15: Invalid expression') + v9.CheckSourceDefAndScriptFailure(['winnr([])'], ['E1013: Argument 1: type mismatch, expected string but got list<any>', 'E1174: String required for argument 1']) + v9.CheckSourceDefExecAndScriptFailure(['winnr("")'], 'E15: Invalid expression') assert_equal(1, winnr()) assert_equal(1, winnr('$')) enddef @@ -4999,7 +5021,7 @@ def Test_winrestcmd() enddef def Test_winrestview() - v9.CheckDefAndScriptFailure(['winrestview([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['winrestview([])'], ['E1013: Argument 1: type mismatch, expected dict<any> but got list<any>', 'E1206: Dictionary required for argument 1']) :%d _ setline(1, 'Hello World') winrestview({lnum: 1, col: 6}) @@ -5012,20 +5034,20 @@ def Test_winsaveview() var lines =<< trim END var view: list<number> = winsaveview() END - v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<number>', 1) + v9.CheckSourceDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<number>', 1) enddef def Test_winwidth() - v9.CheckDefAndScriptFailure(['winwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['winwidth("x")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) enddef def Test_xor() - v9.CheckDefAndScriptFailure(['xor("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) - v9.CheckDefAndScriptFailure(['xor(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) + v9.CheckSourceDefAndScriptFailure(['xor("x", 0x2)'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['xor(0x1, "x")'], ['E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2']) enddef def Test_writefile() - v9.CheckDefExecAndScriptFailure(['writefile(["a"], "")'], 'E482: Can''t create file <empty>') + v9.CheckSourceDefExecAndScriptFailure(['writefile(["a"], "")'], 'E482: Can''t create file <empty>') enddef def Test_passing_type_to_builtin() @@ -5045,7 +5067,7 @@ def Test_passing_type_to_builtin() x = string(T) x = instanceof(C.new(), U, C) END - v9.CheckScriptSuccess(lines) + v9.CheckSourceScriptSuccess(lines) # check argument to add at script level # Note: add() is special cased in compile_call in vim9expr @@ -5055,7 +5077,7 @@ def Test_passing_type_to_builtin() endclass add([], C) END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check argument to add in :def lines =<< trim END @@ -5067,7 +5089,7 @@ def Test_passing_type_to_builtin() enddef F() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check member call argument to add at script level lines =<< trim END @@ -5076,7 +5098,7 @@ def Test_passing_type_to_builtin() endclass []->add(C) END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check member call argument to add in :def lines =<< trim END @@ -5088,7 +5110,7 @@ def Test_passing_type_to_builtin() enddef F() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # Try "empty()" builtin # check argument to empty at script level @@ -5098,7 +5120,7 @@ def Test_passing_type_to_builtin() endclass empty(C) END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check argument to empty in :def lines =<< trim END @@ -5110,7 +5132,7 @@ def Test_passing_type_to_builtin() enddef F() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check member call argument to empty at script level lines =<< trim END @@ -5119,7 +5141,7 @@ def Test_passing_type_to_builtin() endclass C->empty() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check member call argument to empty in :def lines =<< trim END @@ -5131,7 +5153,7 @@ def Test_passing_type_to_builtin() enddef F() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # Try "abs()" builtin # check argument to abs at script level @@ -5141,7 +5163,7 @@ def Test_passing_type_to_builtin() endclass abs(C) END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check argument to abs in :def lines =<< trim END @@ -5153,7 +5175,7 @@ def Test_passing_type_to_builtin() enddef F() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check member call argument to abs at script level lines =<< trim END @@ -5162,7 +5184,7 @@ def Test_passing_type_to_builtin() endclass C->abs() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') # check member call argument to abs in :def lines =<< trim END @@ -5174,15 +5196,31 @@ def Test_passing_type_to_builtin() enddef F() END - v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') + v9.CheckSourceScriptFailure(lines, 'E1405: Class "C" cannot be used as a value') enddef def Test_getregion() assert_equal(['x'], getregion(getpos('.'), getpos('.'))->map((_, _) => 'x')) - - v9.CheckDefAndScriptFailure(['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('.'))) - v9.CheckDefExecFailure(['getregion(getpos("a"), getpos("."))'], 'E1209:') + 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 5957f57ae1..4654598465 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -67,6 +67,54 @@ def Test_class_basic() END v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3) + # Additional command after "class name" + lines =<< trim END + vim9script + class Something | var x = 10 + endclass + END + v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2) + + # Additional command after "object variable" + lines =<< trim END + vim9script + class Something + var l: list<number> = [] | var y = 10 + endclass + END + v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3) + + # Additional command after "class variable" + lines =<< trim END + vim9script + class Something + static var d = {a: 10} | var y = 10 + endclass + END + v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3) + + # Additional command after "object method" + lines =<< trim END + vim9script + class Something + def Foo() | var y = 10 + enddef + endclass + 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 @@ -497,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() @@ -2176,6 +2246,47 @@ def Test_class_object_to_string() assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos)) END v9.CheckSourceSuccess(lines) + + # check string() with object nesting + lines =<< trim END + vim9script + class C + var nest1: C + var nest2: C + def Init(n1: C, n2: C) + this.nest1 = n1 + this.nest2 = n2 + enddef + endclass + + var o1 = C.new() + var o2 = C.new() + o1.Init(o1, o2) + o2.Init(o2, o1) + + # The following previously put's vim into an infinite loop. + + var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}" + assert_equal(expect, string(o1)) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + + class B + endclass + + class C + var b: B + var c: C + endclass + + var o1 = C.new(B.new(), C.new(B.new())) + var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}" + assert_equal(expect, string(o1)) + END + v9.CheckSourceSuccess(lines) enddef def Test_interface_basics() @@ -2237,6 +2348,14 @@ def Test_interface_basics() END v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6) + # Additional commands after "interface name" + lines =<< trim END + vim9script + interface Something | var x = 10 | var y = 20 + endinterface + END + v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2) + lines =<< trim END vim9script export interface EnterExit @@ -3233,6 +3352,14 @@ def Test_abstract_class() END v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1) + # Additional commands after "abstract class" + lines =<< trim END + vim9script + abstract class Something | var x = [] + endclass + END + v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2) + # Abstract class cannot have a "new" function lines =<< trim END vim9script @@ -10339,6 +10466,20 @@ func Test_object_string() call v9.CheckSourceSuccess(lines) endfunc +" Test for using the string() builtin method with an object's method +def Test_method_string() + var lines =<< trim END + vim9script + class A + def F() + enddef + endclass + assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F)) + END + v9.CheckScriptSuccess(lines) +enddef + + " Test for using a class in the class definition def Test_Ref_Class_Within_Same_Class() var lines =<< trim END @@ -10400,6 +10541,156 @@ def Test_Ref_Class_Within_Same_Class() v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3) enddef +" Test for comparing a class referencing itself +def Test_Object_Compare_With_Recursive_Class_Ref() + var lines =<< trim END + vim9script + + class C + public var nest: C + endclass + + var o1 = C.new() + o1.nest = o1 + + var result = o1 == o1 + assert_equal(true, result) + END + v9.CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + + class C + public var nest: C + endclass + var o1 = C.new() + var o2 = C.new(C.new()) + + var result = o1 == o2 + assert_equal(false, result) + END + v9.CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + class C + var nest1: C + var nest2: C + def Init(n1: C, n2: C) + this.nest1 = n1 + this.nest2 = n2 + enddef + endclass + + var o1 = C.new() + var o2 = C.new() + o1.Init(o1, o2) + o2.Init(o2, o1) + + var result = o1 == o2 + assert_equal(true, result) + END + v9.CheckScriptSuccess(lines) +enddef + +" Test for comparing a class with nesting objects +def Test_Object_Compare_With_Nesting_Objects() + # On a compare, after vim equal recurses 1000 times, not finding an unequal, + # return the compare is equal. + # Test that limit + + var lines =<< trim END + vim9script + class C + public var n: number + public var nest: C + + # Create a "C" that chains/nests to indicated depth. + # return {head: firstC, tail: lastC} + static def CreateNested(depth: number): dict<C> + var first = C.new(1, null_object) + var last = first + for i in range(2, depth) + last.nest = C.new(i, null_object) + last = last.nest + endfor + return {head: first, tail: last} + enddef + + # Return pointer to nth item in chain. + def GetLink(depth: number): C + var count = 1 + var p: C = this + while count < depth + p = p.nest + if p == null + throw "too deep" + endif + count += 1 + endwhile + return p + enddef + + # Return the length of the chain + def len(): number + var count = 1 + var p: C = this + while p.nest != null + p = p.nest + count += 1 + endwhile + return count + enddef + endclass + + var chain = C.CreateNested(3) + var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}" + assert_equal(s, string(chain.head)) + assert_equal(3, chain.head->len()) + + var chain1 = C.CreateNested(100) + var chain2 = C.CreateNested(100) + assert_true(chain1.head == chain2.head) + + # modify the tail of chain2, compare not equal + chain2.tail.n = 123456 + assert_true(chain1.head != chain2.head) + + # a tail of a different length compares not equal + chain2 = C.CreateNested(101) + assert_true(chain1.head != chain2.head) + + chain1 = C.CreateNested(1000) + chain2 = C.CreateNested(1000) + assert_true(chain1.head == chain2.head) + + # modify the tail of chain2, compare not equal + chain2.tail.n = 123456 + assert_true(chain1.head != chain2.head) + + # try a chain longer that the limit + chain1 = C.CreateNested(1001) + chain2 = C.CreateNested(1001) + assert_true(chain1.head == chain2.head) + + # modify the tail, but still equal + chain2.tail.n = 123456 + assert_true(chain1.head == chain2.head) + + # remove 2 items from front, shorten the chain by two. + chain1.head = chain1.head.GetLink(3) + chain2.head = chain2.head.GetLink(3) + assert_equal(3, chain1.head.n) + assert_equal(3, chain2.head.n) + assert_equal(999, chain1.head->len()) + assert_equal(999, chain2.head->len()) + # Now less than the limit, compare not equal + assert_true(chain1.head != chain2.head) + END + v9.CheckScriptSuccess(lines) +enddef + " Test for using a compound operator from a lambda function in an object method def Test_compound_op_in_objmethod_lambda() # Test using the "+=" operator @@ -10638,4 +10929,74 @@ 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 + +def Test_class_member_init_typecheck() + # Ensure the class member is assigned its declared type. + var lines =<< trim END + vim9script + class S + static var l: list<string> = [] + endclass + S.l->add(123) + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5) + + # Ensure the initializer value and the declared type match. + lines =<< trim END + vim9script + class S + var l: list<string> = [1, 2, 3] + endclass + var o = S.new() + END + v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>') + + # Ensure the class member is assigned its declared type. + lines =<< trim END + vim9script + class S + var l: list<string> = [] + endclass + var o = S.new() + o.l->add(123) + END + v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6) +enddef + +def Test_class_cast() + var lines =<< trim END + vim9script + class A + endclass + class B extends A + var mylen: number + endclass + def F(o: A): number + return (<B>o).mylen + enddef + + defcompile F + END + v9.CheckScriptSuccess(lines) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 1daef222db..7746b23b41 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -381,6 +381,34 @@ def Test_disassemble_import_autoload() v9.CheckScriptSuccess(lines) enddef +def Test_disassemble_import_autoload_autoload() + mkdir('Xauto_auto/autoload', 'pR') + var lines =<< trim END + vim9script + export const val = 11 + END + writefile(lines, 'Xauto_auto/autoload/Xauto_vars_f1.vim') + + lines =<< trim END + vim9script + + import autoload './Xauto_auto/autoload/Xauto_vars_f1.vim' as f1 + def F() + f1.val = 13 + enddef + var res = execute('disass F') + + assert_match('<SNR>\d*_F.*' .. + 'f1.val = 13\_s*' .. + '\d PUSHNR 13\_s*' .. + '\d SOURCE .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' .. + '\d STOREEXPORT val in .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' .. + '\d RETURN void', + res) + END + v9.CheckScriptSuccess(lines) +enddef + def s:ScriptFuncStore() var localnr = 1 localnr = 2 @@ -1030,7 +1058,7 @@ def Test_disassemble_closure_in_loop() 'endif\_s*' .. 'g:Ref = () => ii\_s*' .. - '\d\+ FUNCREF <lambda>4 vars $3-$3\_s*' .. + '\d\+ FUNCREF <lambda>\d\+ vars $3-$3\_s*' .. '\d\+ STOREG g:Ref\_s*' .. 'continue\_s*' .. @@ -1733,6 +1761,74 @@ def Test_disassemble_typecast() instr) enddef +def Test_disassemble_object_cast() + # Downcasting. + var lines =<< trim END + vim9script + class A + endclass + class B extends A + var mylen: number + endclass + def F(o: A): number + return (<B>o).mylen + enddef + + g:instr = execute('disassemble F') + END + v9.CheckScriptSuccess(lines) + assert_match('\<SNR>\d*_F\_s*' .. + 'return (<B>o).mylen\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 CHECKTYPE object<B> stack\[-1\]\_s*' .. + '2 OBJ_MEMBER 0\_s*' .. + '3 RETURN\_s*', + g:instr) + + # Upcasting. + lines =<< trim END + vim9script + class A + var mylen: number + endclass + class B extends A + endclass + def F(o: B): number + return (<A>o).mylen + enddef + + g:instr = execute('disassemble F') + END + v9.CheckScriptSuccess(lines) + assert_match('\<SNR>\d*_F\_s*' .. + 'return (<A>o).mylen\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 OBJ_MEMBER 0\_s*' .. + '2 RETURN\_s*', + g:instr) + + # Casting, type is not statically known. + lines =<< trim END + vim9script + class A + endclass + class B extends A + endclass + def F(o: any): any + return <A>o + enddef + + g:instr = execute('disassemble F') + END + v9.CheckScriptSuccess(lines) + assert_match('\<SNR>\d*_F\_s*' .. + 'return <A>o\_s*' .. + '0 LOAD arg\[-1\]\_s*' .. + '1 CHECKTYPE object<A> stack\[-1\]\_s*' .. + '2 RETURN\_s*', + g:instr) +enddef + def s:Computing() var nr = 3 var nrres = nr + 7 @@ -3468,4 +3564,26 @@ def Test_disassemble_compound_op_in_closure() unlet g:instr enddef +def Test_disassemble_member_initializer() + var lines =<< trim END + vim9script + class A + var l: list<string> = [] + var d: dict<string> = {} + endclass + g:instr = execute('disassemble A.new') + END + v9.CheckScriptSuccess(lines) + # Ensure SETTYPE is emitted and that matches the declared type. + assert_match('new\_s*' .. + '0 NEW A size \d\+\_s*' .. + '1 NEWLIST size 0\_s*' .. + '2 SETTYPE list<string>\_s*' .. + '3 STORE_THIS 0\_s*' .. + '4 NEWDICT size 0\_s*' .. + '5 SETTYPE dict<string>\_s*' .. + '6 STORE_THIS 1', g:instr) + unlet g:instr +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_enum.vim b/src/testdir/test_vim9_enum.vim index 274b556b77..bc54bee3a9 100644 --- a/src/testdir/test_vim9_enum.vim +++ b/src/testdir/test_vim9_enum.vim @@ -97,7 +97,16 @@ def Test_enum_parse() vim9script enum Something | endenum END - v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 3) + v9.CheckSourceFailure(lines, 'E488: Trailing characters: | endenum', 2) + + # another command follows the enum name + lines =<< trim END + vim9script + enum Something | var x = 10 + Foo + endenum + END + v9.CheckSourceFailure(lines, 'E488: Trailing characters: | var x = 10', 2) # Try to define an enum with the same name as an existing variable lines =<< trim END diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index 7764b3791b..57347318e0 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 27585a9049..d07bbfba70 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -166,6 +166,37 @@ def Test_wrong_function_name() delfunc g:Define enddef +" Check that in a legacy script a :def accesses the correct script variables. +" Github issue: #14615. +def Test_access_var_from_legacy_def() + # Access a script variable by name WITH "s:" prefix. + var lines =<< trim END + let s:foo = 'init' + let s:xxfoo = 'init' + def! AccessVarFromLegacyDef() + s:xxfoo = 'CHANGED' + enddef + call AccessVarFromLegacyDef() + call assert_equal('init', s:foo) + call assert_equal('CHANGED', s:xxfoo) + END + v9.CheckScriptSuccess(lines) + + # Access a script variable by name WITHOUT "s:" prefix; + # previously this accessed "foo" and not "xxfoo" + lines =<< trim END + let s:foo = 'init' + let s:xxfoo = 'init' + def! AccessVarFromLegacyDef() + xxfoo = 'CHANGED' + enddef + call AccessVarFromLegacyDef() + call assert_equal('init', s:foo) + call assert_equal('CHANGED', s:xxfoo) + END + v9.CheckScriptSuccess(lines) +enddef + def Test_listing_function_error() var lines =<< trim END var filler = 123 @@ -4602,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 156b035d48..fb309cb3bc 100644 --- a/src/testdir/test_vim9_import.vim +++ b/src/testdir/test_vim9_import.vim @@ -1140,6 +1140,182 @@ def Test_autoload_import_relative() v9.CheckScriptFailure(lines, 'E484:') enddef +" autoload relative, access from compiled function. +" Github issues: #14565, #14579 +def Test_autoload_import_relative_compiled_buffer() + var lines =<< trim END + vim9script + + export def F1(): string + return 'InFile.vim' + enddef + END + writefile(lines, 'Ximportrelativebuffer.vim', 'D') + lines =<< trim END + vim9script + + import autoload './Ximportrelativebuffer.vim' as xfile + + def F(): string + return xfile.F1() + enddef + assert_equal('InFile.vim', F()) + END + new + setline(1, lines) + :source + # source one more time to detect issues with clearing the script state and + # variables + :source + :bw! +enddef + +" Test for relative import when sourcing a buffer in another directory +def Test_autoload_import_relative_from_buffer_in_dir() + mkdir('Ximportrelative/dir1/dir2', 'pR') + var lines =<< trim END + vim9script + + export def F1(): string + return 'InFile.vim' + enddef + END + writefile(lines, 'Ximportrelative/dir1/dir2/Ximport.vim') + lines =<< trim END + vim9script + + import autoload './Ximport.vim' as xfile + + def F(): string + return xfile.F1() + enddef + assert_equal('InFile.vim', F()) + END + writefile(lines, 'Ximportrelative/dir1/dir2/Xrelative.vim') + + split Ximportrelative/dir1/dir2/Xrelative.vim + :source + # source one more time to detect issues with clearing the script state and + # variables + :source + :bw! +enddef + +" Test modifying exported autoload variable. Github issue: #14591 +def Test_autoload_export_variables() + mkdir('Xautoload_vars/autoload', 'pR') + var lines =<< trim END + vim9script + g:Xautoload_vars_autoload = true + export var val = 11 + val = 42 + END + + # Test that the imported script, above, can modify the exported variable; + # and test that the importing script, below, can modify the variable. + writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f2.vim', 'D') + lines =<< trim END + vim9script + g:Xautoload_vars_autoload = false + + import autoload './Xautoload_vars/autoload/Xauto_vars_f2.vim' as f2 + # Verify that the import statement does not load the file. + assert_equal(false, g:Xautoload_vars_autoload) + + def F(): number + return f2.val + enddef + # Verify compile does not load the file. + defcompile F + assert_equal(false, g:Xautoload_vars_autoload) + + # load the file by accessing the exported variable + assert_equal(42, F()) + assert_equal(true, g:Xautoload_vars_autoload) + unlet g:Xautoload_vars_autoload + + assert_equal(42, f2.val) + f2.val = 17 + assert_equal(17, f2.val) + + def G() + f2.val = 19 + enddef + G() + assert_equal(19, f2.val) + END + v9.CheckScriptSuccess(lines) + + # Test const var is not modifiable. + lines =<< trim END + vim9script + export const val = 11 + val = 42 + END + writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f3.vim', 'D') + lines =<< trim END + vim9script + + import autoload './Xautoload_vars/autoload/Xauto_vars_f3.vim' as f3 + + var x = f3.val + END + v9.CheckScriptFailure(lines, 'E46:') + + # Test const var is not modifiable from importing script. + lines =<< trim END + vim9script + export const val = 11 + END + writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f4.vim', 'D') + lines =<< trim END + vim9script + + import autoload './Xautoload_vars/autoload/Xauto_vars_f4.vim' as f4 + + f4.val = 13 + END + v9.CheckScriptFailure(lines, 'E46:') + + # Test const var is not modifiable from importing script from :def. + # Github issue: #14606 + lines =<< trim END + vim9script + export const val = 11 + END + writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f5.vim', 'D') + lines =<< trim END + vim9script + + import autoload './Xautoload_vars/autoload/Xauto_vars_f5.vim' as f5 + + def F() + f5.val = 13 + enddef + F() + END + v9.CheckScriptFailure(lines, 'E741:') + + # Still part of Github issue: #14606 + lines =<< trim END + vim9script + export var val = 11 + END + writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f6.vim', 'D') + lines =<< trim END + vim9script + + import autoload './Xautoload_vars/autoload/Xauto_vars_f6.vim' as f6 + + def F() + f6.val = 13 + enddef + F() + assert_equal(13, f6.val) + END + v9.CheckScriptSuccess(lines) +enddef + def Test_autoload_import_relative_autoload_dir() mkdir('autoload', 'pR') var lines =<< trim END @@ -2892,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') @@ -3046,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 a3f21bed02..bcb590d107 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() @@ -3983,7 +4007,7 @@ def Test_restoring_cpo() edit XanotherScript so % assert_equal('aABceFsMny>', &cpo) - assert_equal('aABceFs', g:cpoval) + assert_equal('aABceFsz', g:cpoval) :1del setline(1, 'let g:cpoval = &cpo') w @@ -4024,10 +4048,10 @@ def Test_restoring_cpo() exe "silent !" .. cmd assert_equal([ - 'before: aABceFs', - 'after: aABceFsM', - 'later: aABceFsM', - 'vim9: aABceFs'], readfile('Xrporesult')) + 'before: aABceFsz', + 'after: aABceFszM', + 'later: aABceFszM', + 'vim9: aABceFsz'], readfile('Xrporesult')) $HOME = save_HOME delete('Xrporesult') @@ -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,60 @@ 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_dict, 1, '{}', 4, 'dict<any>'], + [null_function, 1, "function('')", 2, 'func(...): unknown'], + [null_list, 1, '[]', 3, 'list<any>'], + [null_object, 1, 'object of [unknown]', 13, 'object<Unknown>'], + [null_partial, 1, "function('')", 2, 'func(...): unknown'], + [null_string, 1, "''", 1, 'string'] + ] + if has('channel') + nullValues->add([null_channel, 1, 'channel fail', 9, 'channel']) + endif + if has('job') + nullValues->add([null_job, 1, 'no process', 8, 'job']) + endif + + for [Val, emptyExp, stringExp, typeExp, typenameExp] in nullValues + assert_equal(emptyExp, empty(Val)) + 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 998079cf6f..2792d45dc9 100644 --- a/src/testdir/test_vim9_typealias.vim +++ b/src/testdir/test_vim9_typealias.vim @@ -172,6 +172,14 @@ def Test_typealias() END v9.CheckSourceSuccess(lines) + # another command follows a type alias + lines =<< trim END + vim9script + type MyType = number | var x = 20 + assert_equal(20, x) + END + v9.CheckSourceSuccess(lines) + # Sourcing a script twice (which will free script local variables) # Uses "lines" from the previous test new @@ -355,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 1f4a72db16..7aab271336 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 0c4aedb3c6..21f894e9a3 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 @@ -7528,6 +7536,31 @@ func Test_deeply_nested_source() call system(cmd) endfunc +func Test_exception_silent() + XpathINIT + let lines =<< trim END + func Throw() + Xpath 'a' + throw "Uncaught" + " This line is not executed. + Xpath 'b' + endfunc + " The exception is suppressed due to the presence of silent!. + silent! call Throw() + try + call DoesNotExist() + catch /E117:/ + Xpath 'c' + endtry + Xpath 'd' + END + let verify =<< trim END + call assert_equal('acd', g:Xpath) + END + + call RunInNewVim(lines, verify) +endfunc + "------------------------------------------------------------------------------- " Modelines {{{1 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_virtualedit.vim b/src/testdir/test_virtualedit.vim index 48d4aa0616..3d3fdd0bec 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 adcc3e9127..3750ebf6b9 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_winfixbuf.vim b/src/testdir/test_winfixbuf.vim index edf71f0e6e..3cec4ed70b 100644 --- a/src/testdir/test_winfixbuf.vim +++ b/src/testdir/test_winfixbuf.vim @@ -200,10 +200,7 @@ func s:reset_all_buffers() set nowinfixbuf call setqflist([]) - - for l:window_info in getwininfo() - call setloclist(l:window_info["winid"], []) - endfor + call setloclist(0, [], 'f') delmarks A-Z0-9 endfunc @@ -642,7 +639,7 @@ func Test_caddexpr() call s:reset_all_buffers() let l:file_path = tempname() - call writefile(["Error - bad-thing-found"], l:file_path) + call writefile(["Error - bad-thing-found"], l:file_path, 'D') execute "edit " . l:file_path let l:file_buffer = bufnr() let l:current = bufnr() @@ -658,8 +655,6 @@ func Test_caddexpr() execute 'caddexpr expand("%") .. ":" .. line(".") .. ":" .. getline(".")' call assert_equal(l:current, bufnr()) - - call delete(l:file_path) endfunc " Fail :cbuffer but :cbuffer! is allowed @@ -668,7 +663,7 @@ func Test_cbuffer() call s:reset_all_buffers() let l:file_path = tempname() - call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path) + call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path, 'D') execute "edit " . l:file_path let l:file_buffer = bufnr() let l:current = bufnr() @@ -687,8 +682,6 @@ func Test_cbuffer() execute "cbuffer! " . l:file_buffer call assert_equal("first.unittest", expand("%:t")) - - call delete(l:file_path) endfunc " Allow :cc but the 'nowinfixbuf' window is selected, instead @@ -1305,7 +1298,7 @@ func Test_find() let l:current = bufnr() let l:file = tempname() - call writefile([], l:file) + call writefile([], l:file, 'D') let l:file = fnamemodify(l:file, ':p') " In case it's Windows 8.3-style. let l:directory = fnamemodify(l:file, ":p:h") let l:name = fnamemodify(l:file, ":p:t") @@ -1322,7 +1315,6 @@ func Test_find() call assert_equal(l:file, expand("%:p")) execute "set path=" . l:original_path - call delete(l:file) endfunc " Fail :first but :first! is allowed @@ -1383,8 +1375,8 @@ func Test_ijump() call writefile([ \ '#include "' . l:include_file . '"' \ ], - \ "main.c") - call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file) + \ "main.c", 'D') + call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D') edit main.c set winfixbuf @@ -1406,8 +1398,6 @@ func Test_ijump() set define& set include& set path& - call delete("main.c") - call delete(l:include_file) endfunc " Fail :lNext but :lNext! is allowed @@ -1472,7 +1462,7 @@ func Test_laddexpr() call s:reset_all_buffers() let l:file_path = tempname() - call writefile(["Error - bad-thing-found"], l:file_path) + call writefile(["Error - bad-thing-found"], l:file_path, 'D') execute "edit " . l:file_path let l:file_buffer = bufnr() let l:current = bufnr() @@ -1488,8 +1478,6 @@ func Test_laddexpr() execute 'laddexpr expand("%") .. ":" .. line(".") .. ":" .. getline(".")' call assert_equal(l:current, bufnr()) - - call delete(l:file_path) endfunc " Fail :last but :last! is allowed @@ -1512,7 +1500,7 @@ func Test_lbuffer() call s:reset_all_buffers() let l:file_path = tempname() - call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path) + call writefile(["first.unittest:1:Error - bad-thing-found"], l:file_path, 'D') execute "edit " . l:file_path let l:file_buffer = bufnr() let l:current = bufnr() @@ -1531,8 +1519,6 @@ func Test_lbuffer() execute "lbuffer! " . l:file_buffer call assert_equal("first.unittest", expand("%:t")) - - call delete(l:file_path) endfunc " Fail :ldo but :ldo! is allowed @@ -1596,7 +1582,7 @@ func Test_lfile() write let l:file = tempname() - call writefile(["first.unittest:1:Error - bad-thing-found was detected"], l:file) + call writefile(["first.unittest:1:Error - bad-thing-found was detected"], l:file, 'D') let l:current = bufnr() @@ -1608,7 +1594,6 @@ func Test_lfile() execute ":lfile! " . l:file call assert_equal(l:first, bufnr()) - call delete(l:file) call delete("first.unittest") call delete("second.unittest") endfunc @@ -1748,9 +1733,9 @@ func Test_ltag() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother execute "normal \<C-]>" @@ -1763,9 +1748,6 @@ func Test_ltag() ltag! one set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail vim.command if we try to change buffers while 'winfixbuf' is set @@ -1971,9 +1953,9 @@ func Test_normal_g_ctrl_square_bracket_right() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -1984,9 +1966,6 @@ func Test_normal_g_ctrl_square_bracket_right() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail to jump to a tag with g<RightMouse> if 'winfixbuf' is enabled @@ -1999,9 +1978,9 @@ func Test_normal_g_rightmouse() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother execute "normal \<C-]>" @@ -2014,9 +1993,6 @@ func Test_normal_g_rightmouse() set tags& set mouse& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail to jump to a tag with g] if 'winfixbuf' is enabled @@ -2028,9 +2004,9 @@ func Test_normal_g_square_bracket_right() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -2041,9 +2017,6 @@ func Test_normal_g_square_bracket_right() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail to jump to a tag with <C-RightMouse> if 'winfixbuf' is enabled @@ -2056,9 +2029,9 @@ func Test_normal_ctrl_rightmouse() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother execute "normal \<C-]>" @@ -2071,9 +2044,6 @@ func Test_normal_ctrl_rightmouse() set tags& set mouse& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail to jump to a tag with <C-t> if 'winfixbuf' is enabled @@ -2085,9 +2055,9 @@ func Test_normal_ctrl_t() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother execute "normal \<C-]>" @@ -2099,9 +2069,6 @@ func Test_normal_ctrl_t() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Disallow <C-^> in 'winfixbuf' windows @@ -2203,9 +2170,9 @@ func Test_normal_ctrl_square_bracket_right() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -2216,9 +2183,6 @@ func Test_normal_ctrl_square_bracket_right() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Allow <C-w><C-]> with 'winfixbuf' enabled because it runs in a new, split window @@ -2230,9 +2194,9 @@ func Test_normal_ctrl_w_ctrl_square_bracket_right() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -2242,9 +2206,6 @@ func Test_normal_ctrl_w_ctrl_square_bracket_right() call assert_equal(l:current_windows + 1, s:get_windows_count()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Allow <C-w>g<C-]> with 'winfixbuf' enabled because it runs in a new, split window @@ -2256,9 +2217,9 @@ func Test_normal_ctrl_w_g_ctrl_square_bracket_right() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -2268,9 +2229,6 @@ func Test_normal_ctrl_w_g_ctrl_square_bracket_right() call assert_equal(l:current_windows + 1, s:get_windows_count()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail to jump to a tag with <C-]> if 'winfixbuf' is enabled @@ -2282,9 +2240,9 @@ func Test_normal_gt() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one", "two", "three"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one", "two", "three"], "Xother", 'D') edit Xother set winfixbuf @@ -2295,9 +2253,6 @@ func Test_normal_gt() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Prevent gF from switching a 'winfixbuf' window's buffer @@ -2306,7 +2261,7 @@ func Test_normal_gF() let l:file = tempname() call append(0, [l:file]) - call writefile([], l:file) + call writefile([], l:file, 'D') " Place the cursor onto the line that has `l:file` normal gg " Prevent Vim from erroring with "No write since last change @ command @@ -2325,7 +2280,7 @@ func Test_normal_gF() normal gF call assert_notequal(l:buffer, bufnr()) - call delete(l:file) + set nohidden endfunc " Prevent gf from switching a 'winfixbuf' window's buffer @@ -2334,7 +2289,7 @@ func Test_normal_gf() let l:file = tempname() call append(0, [l:file]) - call writefile([], l:file) + call writefile([], l:file, 'D') " Place the cursor onto the line that has `l:file` normal gg " Prevent Vim from erroring with "No write since last change @ command @@ -2353,7 +2308,7 @@ func Test_normal_gf() normal gf call assert_notequal(l:buffer, bufnr()) - call delete(l:file) + set nohidden endfunc " Fail "goto file under the cursor" (using [f, which is the same as `:normal gf`) @@ -2362,7 +2317,7 @@ func Test_normal_square_bracket_left_f() let l:file = tempname() call append(0, [l:file]) - call writefile([], l:file) + call writefile([], l:file, 'D') " Place the cursor onto the line that has `l:file` normal gg " Prevent Vim from erroring with "No write since last change @ command @@ -2381,7 +2336,7 @@ func Test_normal_square_bracket_left_f() normal [f call assert_notequal(l:buffer, bufnr()) - call delete(l:file) + set nohidden endfunc " Fail to go to a C macro with [<C-d> if 'winfixbuf' is enabled @@ -2392,8 +2347,8 @@ func Test_normal_square_bracket_left_ctrl_d() call writefile(["min(1, 12);", \ '#include "' . l:include_file . '"' \ ], - \ "main.c") - call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file) + \ "main.c", 'D') + call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D') edit main.c normal ]\<C-d> @@ -2408,9 +2363,6 @@ func Test_normal_square_bracket_left_ctrl_d() execute "normal [\<C-d>" call assert_notequal(l:current, bufnr()) - - call delete("main.c") - call delete(l:include_file) endfunc " Fail to go to a C macro with ]<C-d> if 'winfixbuf' is enabled @@ -2421,8 +2373,8 @@ func Test_normal_square_bracket_right_ctrl_d() call writefile(["min(1, 12);", \ '#include "' . l:include_file . '"' \ ], - \ "main.c") - call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file) + \ "main.c", 'D') + call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D') edit main.c set winfixbuf @@ -2436,9 +2388,6 @@ func Test_normal_square_bracket_right_ctrl_d() execute "normal ]\<C-d>" call assert_notequal(l:current, bufnr()) - - call delete("main.c") - call delete(l:include_file) endfunc " Fail to go to a C macro with [<C-i> if 'winfixbuf' is enabled @@ -2449,8 +2398,8 @@ func Test_normal_square_bracket_left_ctrl_i() call writefile(['#include "' . l:include_file . '"', \ "min(1, 12);", \ ], - \ "main.c") - call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file) + \ "main.c", 'D') + call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D') edit main.c " Move to the line with `min(1, 12);` on it" normal j @@ -2473,8 +2422,6 @@ func Test_normal_square_bracket_left_ctrl_i() set define& set include& set path& - call delete("main.c") - call delete(l:include_file) endfunc " Fail to go to a C macro with ]<C-i> if 'winfixbuf' is enabled @@ -2485,8 +2432,8 @@ func Test_normal_square_bracket_right_ctrl_i() call writefile(["min(1, 12);", \ '#include "' . l:include_file . '"' \ ], - \ "main.c") - call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file) + \ "main.c", 'D') + call writefile(["#define min(X, Y) ((X) < (Y) ? (X) : (Y))"], l:include_file, 'D') edit main.c set winfixbuf @@ -2508,8 +2455,6 @@ func Test_normal_square_bracket_right_ctrl_i() set define& set include& set path& - call delete("main.c") - call delete(l:include_file) endfunc " Fail "goto file under the cursor" (using ]f, which is the same as `:normal gf`) @@ -2518,7 +2463,7 @@ func Test_normal_square_bracket_right_f() let l:file = tempname() call append(0, [l:file]) - call writefile([], l:file) + call writefile([], l:file, 'D') " Place the cursor onto the line that has `l:file` normal gg " Prevent Vim from erroring with "No write since last change @ command @@ -2537,7 +2482,7 @@ func Test_normal_square_bracket_right_f() normal ]f call assert_notequal(l:buffer, bufnr()) - call delete(l:file) + set nohidden endfunc " Fail to jump to a tag with v<C-]> if 'winfixbuf' is enabled @@ -2549,9 +2494,9 @@ func Test_normal_v_ctrl_square_bracket_right() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -2562,9 +2507,6 @@ func Test_normal_v_ctrl_square_bracket_right() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail to jump to a tag with vg<C-]> if 'winfixbuf' is enabled @@ -2576,9 +2518,9 @@ func Test_normal_v_g_ctrl_square_bracket_right() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -2589,9 +2531,6 @@ func Test_normal_v_g_ctrl_square_bracket_right() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Allow :pedit because, unlike :edit, it uses a separate window @@ -2616,9 +2555,9 @@ func Test_pop() \ "thesame\tXfile\t2;\"\td\tfile:", \ "thesame\tXfile\t3;\"\td\tfile:", \ ], - \ "Xtags") - call writefile(["thesame one", "thesame two", "thesame three"], "Xfile") - call writefile(["thesame one"], "Xother") + \ "Xtags", 'D') + call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D') + call writefile(["thesame one"], "Xother", 'D') edit Xother tag thesame @@ -2634,9 +2573,6 @@ func Test_pop() call assert_notequal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail :previous but :previous! is allowed @@ -2704,7 +2640,7 @@ func Test_pythonx_pyxfile() \ "buffer = vim.vars['_previous_buffer']", \ "vim.current.buffer = vim.buffers[buffer]", \ ], - \ "file.py") + \ "file.py", 'D') try pyxfile file.py @@ -2714,7 +2650,6 @@ func Test_pythonx_pyxfile() call assert_equal(1, l:caught) - call delete("file.py") unlet g:_previous_buffer endfunc @@ -2841,11 +2776,11 @@ func Test_short_option() call s:make_buffer_pairs() set winfixbuf - call assert_fails("edit something_else", "E1513") + call assert_fails("edit something_else", "E1513:") set nowinfixbuf set wfb - call assert_fails("edit another_place", "E1513") + call assert_fails("edit another_place", "E1513:") set nowfb edit last_place @@ -2892,9 +2827,9 @@ func Test_tNext() \ "thesame\tXfile\t2;\"\td\tfile:", \ "thesame\tXfile\t3;\"\td\tfile:", \ ], - \ "Xtags") - call writefile(["thesame one", "thesame two", "thesame three"], "Xfile") - call writefile(["thesame one"], "Xother") + \ "Xtags", 'D') + call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D') + call writefile(["thesame one"], "Xother", 'D') edit Xother tag thesame @@ -2911,9 +2846,6 @@ func Test_tNext() tNext! set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Call :tabdo and choose the next available 'nowinfixbuf' window. @@ -2971,9 +2903,9 @@ func Test_tag() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -2987,9 +2919,6 @@ func Test_tag() call assert_notequal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc @@ -3002,9 +2931,10 @@ func Test_tfirst() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') + tag one edit Xother set winfixbuf @@ -3018,9 +2948,6 @@ func Test_tfirst() call assert_notequal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail :tjump but :tjump! is allowed @@ -3032,9 +2959,9 @@ func Test_tjump() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") - call writefile(["one"], "Xother") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') + call writefile(["one"], "Xother", 'D') edit Xother set winfixbuf @@ -3048,9 +2975,6 @@ func Test_tjump() call assert_notequal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail :tlast but :tlast! is allowed @@ -3062,8 +2986,8 @@ func Test_tlast() \ "one\tXfile\t1", \ "three\tXfile\t3", \ "two\tXfile\t2"], - \ "Xtags") - call writefile(["one", "two", "three"], "Xfile") + \ "Xtags", 'D') + call writefile(["one", "two", "three"], "Xfile", 'D') edit Xfile tjump one edit Xfile @@ -3079,8 +3003,6 @@ func Test_tlast() call assert_equal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") endfunc " Fail :tnext but :tnext! is allowed @@ -3093,9 +3015,9 @@ func Test_tnext() \ "thesame\tXfile\t2;\"\td\tfile:", \ "thesame\tXfile\t3;\"\td\tfile:", \ ], - \ "Xtags") - call writefile(["thesame one", "thesame two", "thesame three"], "Xfile") - call writefile(["thesame one"], "Xother") + \ "Xtags", 'D') + call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D') + call writefile(["thesame one"], "Xother", 'D') edit Xother tag thesame @@ -3112,9 +3034,6 @@ func Test_tnext() call assert_notequal(l:current, bufnr()) set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail :tprevious but :tprevious! is allowed @@ -3127,9 +3046,9 @@ func Test_tprevious() \ "thesame\tXfile\t2;\"\td\tfile:", \ "thesame\tXfile\t3;\"\td\tfile:", \ ], - \ "Xtags") - call writefile(["thesame one", "thesame two", "thesame three"], "Xfile") - call writefile(["thesame one"], "Xother") + \ "Xtags", 'D') + call writefile(["thesame one", "thesame two", "thesame three"], "Xfile", 'D') + call writefile(["thesame one"], "Xother", 'D') edit Xother tag thesame @@ -3146,9 +3065,6 @@ func Test_tprevious() tprevious! set tags& - call delete("Xtags") - call delete("Xfile") - call delete("Xother") endfunc " Fail :view but :view! is allowed @@ -3436,7 +3352,7 @@ func Test_exitfree_no_error() END call writefile(lines, 'Xwfb_exitfree', 'D') call assert_notmatch('E1513:', - \ system(GetVimCommandClean() .. ' -X -S Xwfb_exitfree')) + \ system(GetVimCommandClean() .. ' --not-a-term -X -S Xwfb_exitfree')) endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_xdg.vim b/src/testdir/test_xdg.vim index 557864e257..b9ec3c7314 100644 --- a/src/testdir/test_xdg.vim +++ b/src/testdir/test_xdg.vim @@ -1,9 +1,7 @@ " Tests for the XDG feature source check.vim - source shared.vim -source mouse.vim func s:get_rcs() let rcs = { @@ -39,12 +37,12 @@ endfunc func Test_xdg_runtime_files() " This tests, that the initialization file from " ~/.vimrc, ~/.vim/vimrc and ~/.config/vim/vimrc (or - " $XDG_HOMECONFIG/vim/vimrc) are sourced in that order + " $XDG_CONFIG_HOME/vim/vimrc) are sourced in that order CheckUnix call mkdir(expand('~/.vim/'), 'pD') call mkdir(expand('~/.config/vim/'), 'pD') call mkdir(expand('~/xdg/vim/'), 'pD') - + let rc1=expand('~/.vimrc') let rc2=expand('~/.vim/vimrc') let rc3=expand('~/.config/vim/vimrc') @@ -82,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 @@ -96,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 @@ -114,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 @@ -130,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 @@ -147,15 +149,151 @@ func Test_xdg_version() unlet $XDG_CONFIG_HOME let a = execute(':version')->split('\n') let a = filter(a, { _, val -> val =~ '\.config\|XDG_CONFIG_HOME' }) - call assert_equal(1, len(a)) - call assert_match('\~/.config/vim/vimrc', a[0]) + " There should be 1 entry for gvimrc and 1 entry for vimrc, + " but only if Vim was compiled with gui support + call assert_equal(1 + has("gui"), len(a)) + call assert_match('\~/\.config/vim/vimrc', a[0]) + if has("gui") + call assert_match('\~/\.config/vim/gvimrc', a[1]) + endif let $XDG_CONFIG_HOME = expand('~/.xdg') let a = execute(':version')->split('\n') let a = filter(a, { _, val -> val =~ '\.config\|XDG_CONFIG_HOME' }) - call assert_equal(1, len(a)) + call assert_equal(1 + has("gui"), len(a)) call assert_match('XDG_CONFIG_HOME/vim/vimrc', a[0]) + if has("gui") + call assert_match('XDG_CONFIG_HOME/vim/gvimrc', a[1]) + endif + unlet $XDG_CONFIG_HOME +endfunc + +" Test for gvimrc, must be last, since it starts the GUI +" and sources a few extra test files +func Test_zzz_xdg_runtime_files() + CheckCanRunGui + CheckUnix + + " Is setup in Github Runner + unlet $XDG_CONFIG_HOME + source setup_gui.vim + call GUISetUpCommon() + + " This tests, that the GUI initialization file from + " ~/.gvimrc, ~/.vim/gvimrc, ~/.config/vim/gvimrc + " and ~/XDG_CONFIG_HOME/vim/gvimrc is sourced + " when starting GUI mode + call mkdir(expand('~/.vim/'), 'pD') + call mkdir(expand('~/.config/vim/'), 'pD') + call mkdir(expand('~/xdg/vim/'), 'pD') + + let rc1=expand('~/.gvimrc') + let rc2=expand('~/.vim/gvimrc') + let rc3=expand('~/.config/vim/gvimrc') + let rc4=expand('~/xdg/vim/gvimrc') + + " g:rc_one|two|three|four is to verify, that the other + " init files are not sourced + " g:rc is to verify which rc file has been loaded. + let file1 =<< trim CODE + let g:rc_one = 'one' + let g:rc = '.gvimrc' + CODE + let file2 =<< trim CODE + let g:rc_two = 'two' + let g:rc = '.vim/gvimrc' + CODE + let file3 =<< trim CODE + let g:rc_three = 'three' + let g:rc = '.config/vim/gvimrc' + CODE + let file4 =<< trim CODE + let g:rc_four = 'four' + let g:rc = 'xdg/vim/gvimrc' + CODE + call writefile(file1, rc1) + call writefile(file2, rc2) + call writefile(file3, rc3) + call writefile(file4, rc4) + + " Get the Vim command to run without the '-u NONE' argument + let vimcmd = substitute(GetVimCommand(), '-u NONE', '', '') + + " Test for ~/.gvimrc + let lines =<< trim END + " Ignore the "failed to create input context" error. + call test_ignore_error('E285') + gui -f + call assert_match('Xhome/\.gvimrc', $MYGVIMRC) + call filter(g:, {idx, _ -> idx =~ '^rc'}) + call assert_equal(#{rc_one: 'one', rc: '.gvimrc'}, g:) + call writefile(v:errors, 'Xresult') + quit + END + call writefile(lines, 'Xscript', 'D') + call system($'{vimcmd} -S Xscript') + call assert_equal([], readfile('Xresult')) + + call delete(rc1) + + " Test for ~/.vim/gvimrc + let lines =<< trim END + " Ignore the "failed to create input context" error. + call test_ignore_error('E285') + gui -f + call assert_match('Xhome/\.vim/gvimrc', $MYGVIMRC) + call filter(g:, {idx, _ -> idx =~ '^rc'}) + call assert_equal(#{rc_two: 'two', rc: '.vim/gvimrc'}, g:) + call writefile(v:errors, 'Xresult') + quit + END + call writefile(lines, 'Xscript', 'D') + call system($'{vimcmd} -S Xscript') + call assert_equal([], readfile('Xresult')) + + call delete(rc2) + + " Test for ~/.config/vim/gvimrc + let lines =<< trim END + " Ignore the "failed to create input context" error. + call test_ignore_error('E285') + gui -f + let msg = $'HOME="{$HOME}", ~="{expand("~")}"' + call assert_match('Xhome/\.config/vim/gvimrc', $MYGVIMRC, msg) + call filter(g:, {idx, _ -> idx =~ '^rc'}) + call assert_equal(#{rc_three: 'three', rc: '.config/vim/gvimrc'}, g:) + call writefile(v:errors, 'Xresult') + quit + END + call writefile(lines, 'Xscript', 'D') + call system($'{vimcmd} -S Xscript') + call assert_equal([], readfile('Xresult')) + + call delete(rc3) + + " Test for ~/xdg/vim/gvimrc + let $XDG_CONFIG_HOME=expand('~/xdg/') + let lines =<< trim END + " Ignore the "failed to create input context" error. + call test_ignore_error('E285') + gui -f + let msg = $'HOME="{$HOME}", XDG_CONFIG_HOME="{$XDG_CONFIG_HOME}"' + call assert_match('Xhome/xdg/vim/gvimrc', $MYGVIMRC, msg) + call filter(g:, {idx, _ -> idx =~ '^rc'}) + call assert_equal(#{rc_four: 'four', rc: 'xdg/vim/gvimrc'}, g:) + call writefile(v:errors, 'Xresult') + quit + END + call writefile(lines, 'Xscript', 'D') + call system($'{vimcmd} -S Xscript') + call assert_equal([], readfile('Xresult')) + + call delete(rc4) + + " Clean up unlet $XDG_CONFIG_HOME + call GUITearDownCommon() + call delete('Xhome', 'rf') endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim index 7a2771e033..a91a1fcf92 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/testdir/vim9.vim b/src/testdir/vim9.vim index 764b6119db..ff4db7bbc5 100644 --- a/src/testdir/vim9.vim +++ b/src/testdir/vim9.vim @@ -110,46 +110,6 @@ export def CheckScriptSuccess(lines: list<string>) endtry enddef -# :source a list of "lines" and check whether it fails with "error" -export def CheckSourceFailure(lines: list<string>, error: string, lnum = -3) - var cwd = getcwd() - new - setline(1, lines) - try - assert_fails('source', error, lines, lnum) - finally - chdir(cwd) - bw! - endtry -enddef - -# :source a list of "lines" and check whether it fails with the list of -# "errors" -export def CheckSourceFailureList(lines: list<string>, errors: list<string>, lnum = -3) - var cwd = getcwd() - new - setline(1, lines) - try - assert_fails('source', errors, lines, lnum) - finally - chdir(cwd) - bw! - endtry -enddef - -# :source a list of "lines" and check whether it succeeds -export def CheckSourceSuccess(lines: list<string>) - var cwd = getcwd() - new - setline(1, lines) - try - :source - finally - chdir(cwd) - bw! - endtry -enddef - export def CheckDefAndScriptSuccess(lines: list<string>) CheckDefSuccess(lines) CheckScriptSuccess(['vim9script'] + lines) @@ -313,3 +273,177 @@ export def CheckLegacyAndVim9Failure(lines: list<string>, error: any) CheckDefExecFailure(vim9lines, defError) CheckScriptFailure(['vim9script'] + vim9lines, scriptError) enddef + +# :source a list of "lines" and check whether it fails with "error" +export def CheckSourceScriptFailure(lines: list<string>, error: string, lnum = -3) + var cwd = getcwd() + new + setline(1, lines) + var bnr = bufnr() + try + assert_fails('source', error, lines, lnum) + finally + chdir(cwd) + exe $':bw! {bnr}' + endtry +enddef + +# :source a list of "lines" and check whether it fails with the list of +# "errors" +export def CheckSourceScriptFailureList(lines: list<string>, errors: list<string>, lnum = -3) + var cwd = getcwd() + new + var bnr = bufnr() + setline(1, lines) + try + assert_fails('source', errors, lines, lnum) + finally + chdir(cwd) + exe $':bw! {bnr}' + endtry +enddef + +# :source a list of "lines" and check whether it succeeds +export def CheckSourceScriptSuccess(lines: list<string>) + var cwd = getcwd() + new + var bnr = bufnr() + setline(1, lines) + try + :source + finally + chdir(cwd) + exe $':bw! {bnr}' + endtry +enddef + +export def CheckSourceSuccess(lines: list<string>) + CheckSourceScriptSuccess(lines) +enddef + +export def CheckSourceFailure(lines: list<string>, error: string, lnum = -3) + CheckSourceScriptFailure(lines, error, lnum) +enddef + +export def CheckSourceFailureList(lines: list<string>, errors: list<string>, lnum = -3) + CheckSourceScriptFailureList(lines, errors, lnum) +enddef + +# :source a List of "lines" inside a ":def" function and check that no error +# occurs when called. +export func CheckSourceDefSuccess(lines) + let cwd = getcwd() + new + let bnr = bufnr() + call setline(1, ['def Func()'] + a:lines + ['enddef', 'defcompile']) + try + source + call Func() + finally + call chdir(cwd) + delfunc! Func + exe $'bw! {bnr}' + endtry +endfunc + +export def CheckSourceDefAndScriptSuccess(lines: list<string>) + CheckSourceDefSuccess(lines) + CheckSourceScriptSuccess(['vim9script'] + lines) +enddef + +# Check that "lines" inside a ":def" function has no error when compiled. +export func CheckSourceDefCompileSuccess(lines) + let cwd = getcwd() + new + let bnr = bufnr() + call setline(1, ['def Func()', '# comment'] + a:lines + ['#comment', 'enddef', 'defcompile']) + try + source + finally + call chdir(cwd) + delfunc! Func + exe $':bw! {bnr}' + endtry +endfunc + +# Check that "lines" inside ":def" results in an "error" message. +# If "lnum" is given check that the error is reported for this line. +# Add a line before and after to make it less likely that the line number is +# accidentally correct. +export func CheckSourceDefFailure(lines, error, lnum = -3) + let cwd = getcwd() + new + let bnr = bufnr() + call setline(1, ['def Func()', '# comment'] + a:lines + ['#comment', 'enddef', 'defcompile']) + try + call assert_fails('source', a:error, a:lines, a:lnum + 1) + finally + call chdir(cwd) + delfunc! Func + exe $':bw! {bnr}' + endtry +endfunc + +# Check that "lines" inside ":def" results in an "error" message when executed. +# If "lnum" is given check that the error is reported for this line. +# Add a line before and after to make it less likely that the line number is +# accidentally correct. +export func CheckSourceDefExecFailure(lines, error, lnum = -3) + let cwd = getcwd() + new + let bnr = bufnr() + call setline(1, ['def Func()', '# comment'] + a:lines + ['#comment', 'enddef']) + try + source + call assert_fails('call Func()', a:error, a:lines, a:lnum + 1) + finally + call chdir(cwd) + delfunc! Func + exe $':bw! {bnr}' + endtry +endfunc + +# Check that a command fails when used in a :def function and when used in +# Vim9 script. +# When "error" is a string, both with the same error. +# When "error" is a list, the :def function fails with "error[0]" , the script +# fails with "error[1]". +export def CheckSourceDefAndScriptFailure(lines: list<string>, error: any, lnum = -3) + var errorDef: string + var errorScript: string + if type(error) == v:t_string + errorDef = error + errorScript = error + elseif type(error) == v:t_list && len(error) == 2 + errorDef = error[0] + errorScript = error[1] + else + echoerr 'error argument must be a string or a list with two items' + return + endif + CheckSourceDefFailure(lines, errorDef, lnum) + CheckSourceScriptFailure(['vim9script'] + lines, errorScript, lnum + 1) +enddef + +# Check that a command fails when executed in a :def function and when used in +# Vim9 script. +# When "error" is a string, both with the same error. +# When "error" is a list, the :def function fails with "error[0]" , the script +# fails with "error[1]". +export def CheckSourceDefExecAndScriptFailure(lines: list<string>, error: any, lnum = -3) + var errorDef: string + var errorScript: string + if type(error) == v:t_string + errorDef = error + errorScript = error + elseif type(error) == v:t_list && len(error) == 2 + errorDef = error[0] + errorScript = error[1] + else + echoerr 'error argument must be a string or a list with two items' + return + endif + CheckSourceDefExecFailure(lines, errorDef, lnum) + CheckSourceScriptFailure(['vim9script'] + lines, errorScript, lnum + 1) +enddef + diff --git a/src/testing.c b/src/testing.c index 33de3a5cd8..18b8e788eb 100644 --- a/src/testing.c +++ b/src/testing.c @@ -187,7 +187,7 @@ fill_assert_error( { item2 = dict_find(got_d, hi->hi_key, -1); if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv, - &item2->di_tv, FALSE, FALSE)) + &item2->di_tv, FALSE)) { // item of exp_d not present in got_d or values differ. dict_add_tv(exp_tv->vval.v_dict, @@ -262,7 +262,7 @@ assert_equal_common(typval_T *argvars, assert_type_T atype) { garray_T ga; - if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE) + if (tv_equal(&argvars[0], &argvars[1], FALSE) != (atype == ASSERT_EQUAL)) { prepare_assert_error(&ga); @@ -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/textformat.c b/src/textformat.c index 41ec2cfe4b..d380899c8f 100644 --- a/src/textformat.c +++ b/src/textformat.c @@ -59,9 +59,11 @@ internal_format( int safe_tw = trim_to_int(8 * (vimlong_T)textwidth); #ifdef FEAT_LINEBREAK int has_lbr = curwin->w_p_lbr; + int has_bri = curwin->w_p_bri; // make sure win_lbr_chartabsize() counts correctly curwin->w_p_lbr = FALSE; + curwin->w_p_bri = FALSE; #endif // When 'ai' is off we don't want a space under the cursor to be @@ -475,6 +477,7 @@ internal_format( #ifdef FEAT_LINEBREAK curwin->w_p_lbr = has_lbr; + curwin->w_p_bri = has_bri; #endif if (!format_only && haveto_redraw) { diff --git a/src/textobject.c b/src/textobject.c index 1890d7c83f..aa2db07709 100644 --- a/src/textobject.c +++ b/src/textobject.c @@ -1426,15 +1426,22 @@ current_tagblock( if (!do_include) { - // Exclude the start tag. + // Exclude the start tag, + // but skip over '>' if it appears in quotes + int in_quotes = FALSE; curwin->w_cursor = start_pos; while (inc_cursor() >= 0) - if (*ml_get_cursor() == '>') + { + p = ml_get_cursor(); + if (*p == '>' && !in_quotes) { inc_cursor(); start_pos = curwin->w_cursor; break; } + else if (*p == '"' || *p == '\'') + in_quotes = !in_quotes; + } curwin->w_cursor = end_pos; // If we are in Visual mode and now have the same text as before set diff --git a/src/typval.c b/src/typval.c index 6a73719b71..67c819f0a4 100644 --- a/src/typval.c +++ b/src/typval.c @@ -1605,8 +1605,7 @@ typval_compare_list( } else { - val = list_equal(tv1->vval.v_list, tv2->vval.v_list, - ic, FALSE); + val = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); if (type == EXPR_NEQUAL) val = !val; } @@ -1698,24 +1697,6 @@ typval_compare_blob( return OK; } -/* - * Compare "tv1" to "tv2" as classes according to "type". - * Put the result, false or true, in "res". - * Return FAIL and give an error message when the comparison can't be done. - */ - int -typval_compare_class( - typval_T *tv1, - typval_T *tv2, - exprtype_T type UNUSED, - int ic UNUSED, - int *res) -{ - // TODO: use "type" - *res = tv1->vval.v_class == tv2->vval.v_class; - return OK; -} - /* * Compare "tv1" to "tv2" as objects according to "type". * Put the result, false or true, in "res". @@ -1742,14 +1723,6 @@ typval_compare_object( return OK; } - class_T *cl1 = tv1->vval.v_object->obj_class; - class_T *cl2 = tv2->vval.v_object->obj_class; - if (cl1 != cl2 || cl1 == NULL || cl2 == NULL) - { - *res = !res_match; - return OK; - } - object_T *obj1 = tv1->vval.v_object; object_T *obj2 = tv2->vval.v_object; if (type == EXPR_IS || type == EXPR_ISNOT) @@ -1758,14 +1731,7 @@ typval_compare_object( return OK; } - for (int i = 0; i < cl1->class_obj_member_count; ++i) - if (!tv_equal((typval_T *)(obj1 + 1) + i, - (typval_T *)(obj2 + 1) + i, ic, TRUE)) - { - *res = !res_match; - return OK; - } - *res = res_match; + *res = object_equal(obj1, obj2, ic) ? res_match : !res_match; return OK; } @@ -1802,7 +1768,7 @@ typval_compare_dict( } else { - val = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, FALSE); + val = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); if (type == EXPR_NEQUAL) val = !val; } @@ -1841,14 +1807,14 @@ typval_compare_func( if (tv1->v_type == VAR_FUNC && tv2->v_type == VAR_FUNC) // strings are considered the same if their value is // the same - val = tv_equal(tv1, tv2, ic, FALSE); + val = tv_equal(tv1, tv2, ic); else if (tv1->v_type == VAR_PARTIAL && tv2->v_type == VAR_PARTIAL) val = (tv1->vval.v_partial == tv2->vval.v_partial); else val = FALSE; } else - val = tv_equal(tv1, tv2, ic, FALSE); + val = tv_equal(tv1, tv2, ic); if (type == EXPR_NEQUAL || type == EXPR_ISNOT) val = !val; *res = val; @@ -2003,7 +1969,7 @@ func_equal( if (d1 != d2) return FALSE; } - else if (!dict_equal(d1, d2, ic, TRUE)) + else if (!dict_equal(d1, d2, ic)) return FALSE; // empty list and no list considered the same @@ -2013,7 +1979,7 @@ func_equal( return FALSE; for (i = 0; i < a1; ++i) if (!tv_equal(tv1->vval.v_partial->pt_argv + i, - tv2->vval.v_partial->pt_argv + i, ic, TRUE)) + tv2->vval.v_partial->pt_argv + i, ic)) return FALSE; return TRUE; @@ -2028,8 +1994,7 @@ func_equal( tv_equal( typval_T *tv1, typval_T *tv2, - int ic, // ignore case - int recursive) // TRUE when used recursively + int ic) // ignore case { char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; char_u *s1, *s2; @@ -2043,7 +2008,7 @@ tv_equal( // Reduce the limit every time running into it. That should work fine for // deeply linked structures that are not recursively linked and catch // recursiveness quickly. - if (!recursive) + if (recursive_cnt == 0) tv_equal_recurse_limit = 1000; if (recursive_cnt >= tv_equal_recurse_limit) { @@ -2073,13 +2038,13 @@ tv_equal( { case VAR_LIST: ++recursive_cnt; - r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); + r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); --recursive_cnt; return r; case VAR_DICT: ++recursive_cnt; - r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE); + r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); --recursive_cnt; return r; @@ -2114,7 +2079,9 @@ tv_equal( return tv1->vval.v_class == tv2->vval.v_class; case VAR_OBJECT: - (void)typval_compare_object(tv1, tv2, EXPR_EQUAL, ic, &r); + ++recursive_cnt; + r = object_equal(tv1->vval.v_object, tv2->vval.v_object, ic); + --recursive_cnt; return r; case VAR_PARTIAL: diff --git a/src/usercmd.c b/src/usercmd.c index e2c0114ca3..3f0781c4fc 100644 --- a/src/usercmd.c +++ b/src/usercmd.c @@ -102,6 +102,7 @@ static struct {EXPAND_BREAKPOINT, "breakpoint"}, {EXPAND_SCRIPTNAMES, "scriptnames"}, #endif + {EXPAND_DIRS_IN_CDPATH, "dir_in_path"}, {0, NULL} }; diff --git a/src/userfunc.c b/src/userfunc.c index 71b39837c7..e44397d81b 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: @@ -5499,6 +5503,47 @@ ex_function(exarg_T *eap) ga_clear_strings(&lines_to_free); } + int +get_func_arity(char_u *name, int *required, int *optional, int *varargs) +{ + ufunc_T *ufunc = NULL; + int argcount = 0; + int min_argcount = 0; + int idx; + + idx = find_internal_func(name); + if (idx >= 0) + { + internal_func_get_argcount(idx, &argcount, &min_argcount); + *varargs = FALSE; + } + else + { + char_u fname_buf[FLEN_FIXED + 1]; + char_u *tofree = NULL; + funcerror_T error = FCERR_NONE; + char_u *fname; + + // May need to translate <SNR>123_ to K_SNR. + fname = fname_trans_sid(name, fname_buf, &tofree, &error); + if (error == FCERR_NONE) + ufunc = find_func(fname, FALSE); + vim_free(tofree); + + if (ufunc == NULL) + return FAIL; + + argcount = ufunc->uf_args.ga_len; + min_argcount = ufunc->uf_args.ga_len - ufunc->uf_def_args.ga_len; + *varargs = has_varargs(ufunc); + } + + *required = min_argcount; + *optional = argcount - min_argcount; + + return OK; +} + /* * Find a function by name, including "<lambda>123". * Check for "profile" and "debug" arguments and set"compile_type". diff --git a/src/version.c b/src/version.c index f78883e19a..79c38057a2 100644 --- a/src/version.c +++ b/src/version.c @@ -719,6 +719,542 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 610, +/**/ + 609, +/**/ + 608, +/**/ + 607, +/**/ + 606, +/**/ + 605, +/**/ + 604, +/**/ + 603, +/**/ + 602, +/**/ + 601, +/**/ + 600, +/**/ + 599, +/**/ + 598, +/**/ + 597, +/**/ + 596, +/**/ + 595, +/**/ + 594, +/**/ + 593, +/**/ + 592, +/**/ + 591, +/**/ + 590, +/**/ + 589, +/**/ + 588, +/**/ + 587, +/**/ + 586, +/**/ + 585, +/**/ + 584, +/**/ + 583, +/**/ + 582, +/**/ + 581, +/**/ + 580, +/**/ + 579, +/**/ + 578, +/**/ + 577, +/**/ + 576, +/**/ + 575, +/**/ + 574, +/**/ + 573, +/**/ + 572, +/**/ + 571, +/**/ + 570, +/**/ + 569, +/**/ + 568, +/**/ + 567, +/**/ + 566, +/**/ + 565, +/**/ + 564, +/**/ + 563, +/**/ + 562, +/**/ + 561, +/**/ + 560, +/**/ + 559, +/**/ + 558, +/**/ + 557, +/**/ + 556, +/**/ + 555, +/**/ + 554, +/**/ + 553, +/**/ + 552, +/**/ + 551, +/**/ + 550, +/**/ + 549, +/**/ + 548, +/**/ + 547, +/**/ + 546, +/**/ + 545, +/**/ + 544, +/**/ + 543, +/**/ + 542, +/**/ + 541, +/**/ + 540, +/**/ + 539, +/**/ + 538, +/**/ + 537, +/**/ + 536, +/**/ + 535, +/**/ + 534, +/**/ + 533, +/**/ + 532, +/**/ + 531, +/**/ + 530, +/**/ + 529, +/**/ + 528, +/**/ + 527, +/**/ + 526, +/**/ + 525, +/**/ + 524, +/**/ + 523, +/**/ + 522, +/**/ + 521, +/**/ + 520, +/**/ + 519, +/**/ + 518, +/**/ + 517, +/**/ + 516, +/**/ + 515, +/**/ + 514, +/**/ + 513, +/**/ + 512, +/**/ + 511, +/**/ + 510, +/**/ + 509, +/**/ + 508, +/**/ + 507, +/**/ + 506, +/**/ + 505, +/**/ + 504, +/**/ + 503, +/**/ + 502, +/**/ + 501, +/**/ + 500, +/**/ + 499, +/**/ + 498, +/**/ + 497, +/**/ + 496, +/**/ + 495, +/**/ + 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, +/**/ + 375, +/**/ + 374, +/**/ + 373, +/**/ + 372, +/**/ + 371, +/**/ + 370, +/**/ + 369, +/**/ + 368, +/**/ + 367, +/**/ + 366, +/**/ + 365, +/**/ + 364, +/**/ + 363, +/**/ + 362, +/**/ + 361, +/**/ + 360, +/**/ + 359, +/**/ + 358, +/**/ + 357, +/**/ + 356, +/**/ + 355, +/**/ + 354, +/**/ + 353, +/**/ + 352, +/**/ + 351, +/**/ + 350, +/**/ + 349, +/**/ + 348, +/**/ + 347, +/**/ + 346, +/**/ + 345, +/**/ + 344, +/**/ + 343, /**/ 342, /**/ diff --git a/src/version.h b/src/version.h index b9c6d837fe..13f3bac9ff 100644 --- a/src/version.h +++ b/src/version.h @@ -31,7 +31,22 @@ #ifndef VIM_VERSION_PATCHLEVEL # define VIM_VERSION_PATCHLEVEL 0 #endif -#define VIM_VERSION_PATCHLEVEL_STR VIM_TOSTR(VIM_VERSION_PATCHLEVEL) + +// Patchlevel with leading zeros +// For compatibility with the installer from "vim-win32-installer" and WinGet. +// For details see https://github.com/vim/vim-win32-installer/pull/277 +// and https://github.com/vim/vim-win32-installer/pull/285 +#if VIM_VERSION_PATCHLEVEL < 10 +#define LEADZERO(x) 000 ## x +#elif VIM_VERSION_PATCHLEVEL < 100 +#define LEADZERO(x) 00 ## x +#elif VIM_VERSION_PATCHLEVEL < 1000 +#define LEADZERO(x) 0 ## x +#else +#define LEADZERO(x) x +#endif + +#define VIM_VERSION_PATCHLEVEL_STR VIM_TOSTR(LEADZERO(VIM_VERSION_PATCHLEVEL)) // Used by MacOS port; should be one of: development, alpha, beta, final #define VIM_VERSION_RELEASE final diff --git a/src/vim.h b/src/vim.h index 0bd8aad77d..19bd518800 100644 --- a/src/vim.h +++ b/src/vim.h @@ -599,7 +599,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); # ifdef bindtextdomain # undef bindtextdomain # endif -# define bindtextdomain(x, y) // empty +# define bindtextdomain(x, y) "" # ifdef bind_textdomain_codeset # undef bind_textdomain_codeset # endif @@ -657,8 +657,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define VALID_VIRTCOL 0x04 // w_virtcol (file col) is valid #define VALID_CHEIGHT 0x08 // w_cline_height and w_cline_folded valid #define VALID_CROW 0x10 // w_cline_row is valid -#define VALID_BOTLINE 0x20 // w_botine and w_empty_rows are valid -#define VALID_BOTLINE_AP 0x40 // w_botine is approximated +#define VALID_BOTLINE 0x20 // w_botline and w_empty_rows are valid +#define VALID_BOTLINE_AP 0x40 // w_botline is approximated #define VALID_TOPLINE 0x80 // w_topline is valid (for cursor position) // Values for w_popup_flags. @@ -844,7 +844,9 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define EXPAND_ARGOPT 56 #define EXPAND_TERMINALOPT 57 #define EXPAND_KEYMAP 58 -#define EXPAND_MACACTION 59 +#define EXPAND_DIRS_IN_CDPATH 59 +#define EXPAND_MACACTION 60 + // Values for exmode_active (0 is no exmode) #define EXMODE_NORMAL 1 @@ -900,6 +902,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define EW_DODOT 0x4000 // also files starting with a dot #define EW_EMPTYOK 0x8000 // no matches is not an error #define EW_NOTENV 0x10000 // do not expand environment variables +#define EW_CDPATH 0x20000 // search in 'cdpath' too // Flags for find_file_*() functions. #define FINDFILE_FILE 0 // only files @@ -1076,6 +1079,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); // Values for flags argument of do_buffer() #define DOBUF_FORCEIT 1 // :cmd! #define DOBUF_NOPOPUP 2 // skip popup window buffers +#define DOBUF_SKIPHELP 4 // skip or keep help buffers depending on b_help of the + // starting buffer // Values for sub_cmd and which_pat argument for search_regcomp() // Also used for which_pat argument for searchit() @@ -1363,6 +1368,7 @@ enum auto_event EVENT_CURSORHOLD, // cursor in same position for a while EVENT_CURSORHOLDI, // idem, in Insert mode EVENT_CURSORMOVED, // cursor was moved + EVENT_CURSORMOVEDC, // cursor was moved in Command line mode EVENT_CURSORMOVEDI, // cursor was moved in Insert mode EVENT_DIFFUPDATED, // after diffs were updated EVENT_DIRCHANGED, // after user changed directory @@ -1396,6 +1402,7 @@ enum auto_event EVENT_INSERTENTER, // when entering Insert mode EVENT_INSERTLEAVEPRE, // just before leaving Insert mode EVENT_INSERTLEAVE, // just after leaving Insert mode + EVENT_KEYINPUTPRE, // before key input EVENT_MENUPOPUP, // just before popup menu is displayed EVENT_MODECHANGED, // after changing the mode EVENT_OPTIONSET, // option was set @@ -1503,6 +1510,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) @@ -1528,10 +1537,19 @@ 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 */ diff --git a/src/vim9.h b/src/vim9.h index 65de618207..54938fe20c 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -780,6 +780,7 @@ typedef enum { dest_vimvar, dest_class_member, dest_script, + dest_script_v9, dest_reg, dest_expr, } assign_dest_T; diff --git a/src/vim9class.c b/src/vim9class.c index 52c2f764db..70f2405f01 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -136,6 +136,13 @@ parse_member( fill_evalarg_from_eap(&evalarg, eap, FALSE); (void)skip_expr_concatenate(&init_arg, &expr_start, &expr_end, &evalarg); + init_arg = skipwhite(init_arg); + if (*init_arg != NUL && !vim9_comment_start(init_arg)) + { + semsg(_(e_trailing_characters_str), init_arg); + return FAIL; + } + // No type specified for the member. Set it to "any" and the correct // type will be set when the object is instantiated. if (type == NULL) @@ -1273,6 +1280,7 @@ add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap) tv->v_type = m->ocm_type->tt_type; tv->vval.v_string = NULL; } + set_tv_type(tv, m->ocm_type); if (m->ocm_flags & OCMFLAG_CONST) item_lock(tv, DICT_MAXNEST, TRUE, TRUE); } @@ -3093,7 +3101,7 @@ class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) { ret_m = m; ret_idx = i; - break; + break; } } if (idx != NULL) @@ -3176,11 +3184,11 @@ object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx) } } else if (STRCMP(name, m->ocm_name) == 0) - { + { ret_m = m; ret_idx = i; - break; - } + break; + } } if (idx != NULL) *idx = ret_idx; @@ -3676,7 +3684,7 @@ method_not_found_msg(class_T *cl, vartype_T v_type, char_u *name, size_t len) } else semsg(_(e_method_not_found_on_class_str_str), method_name, - cl->class_name); + cl->class_name); vim_free(method_name); } @@ -3835,10 +3843,41 @@ object_len(object_T *obj) } /* - * Return a textual representation of object "obj" + * Return TRUE when two objects have exactly the same values. + */ + int +object_equal( + object_T *o1, + object_T *o2, + int ic) // ignore case for strings +{ + class_T *cl1, *cl2; + + if (o1 == o2) + return TRUE; + if (o1 == NULL || o2 == NULL) + return FALSE; + + cl1 = o1->obj_class; + cl2 = o2->obj_class; + + if (cl1 != cl2 || cl1 == NULL || cl2 == NULL) + return FALSE; + + for (int i = 0; i < cl1->class_obj_member_count; ++i) + if (!tv_equal((typval_T *)(o1 + 1) + i, (typval_T *)(o2 + 1) + i, ic)) + return FALSE; + + return TRUE; +} + +/* + * Return a textual representation of object "obj". + * "obj" must not be NULL. + * May return NULL. */ char_u * -object_string( +object2string( object_T *obj, char_u *numbuf, int copyID, @@ -3852,47 +3891,58 @@ object_string( == OK && rettv.vval.v_string != NULL) return rettv.vval.v_string; + + int ok = OK; + class_T *cl = obj->obj_class; + garray_T ga; + ga_init2(&ga, 1, 50); + + if (cl != NULL && IS_ENUM(cl)) + { + ga_concat(&ga, (char_u *)"enum "); + ga_concat(&ga, cl->class_name); + char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string; + ga_concat(&ga, (char_u *)"."); + ga_concat(&ga, enum_name); + } else { - garray_T ga; - ga_init2(&ga, 1, 50); - - class_T *cl = obj == NULL ? NULL : obj->obj_class; - if (cl != NULL && IS_ENUM(cl)) - { - ga_concat(&ga, (char_u *)"enum "); - ga_concat(&ga, cl->class_name); - char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string; - ga_concat(&ga, (char_u *)"."); - ga_concat(&ga, enum_name); - } - else - { - ga_concat(&ga, (char_u *)"object of "); - ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]" - : cl->class_name); - } - if (cl != NULL) - { - ga_concat(&ga, (char_u *)" {"); - for (int i = 0; i < cl->class_obj_member_count; ++i) + ga_concat(&ga, (char_u *)"object of "); + ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]" + : cl->class_name); + } + if (cl != NULL) + { + ga_concat(&ga, (char_u *)" {"); + for (int i = 0; i < cl->class_obj_member_count; ++i) + { + if (i > 0) + ga_concat(&ga, (char_u *)", "); + ocmember_T *m = &cl->class_obj_members[i]; + ga_concat(&ga, m->ocm_name); + ga_concat(&ga, (char_u *)": "); + char_u *tf = NULL; + char_u *s = echo_string_core((typval_T *)(obj + 1) + i, + &tf, numbuf, copyID, echo_style, + restore_copyID, composite_val); + if (s != NULL) + ga_concat(&ga, s); + vim_free(tf); + if (s == NULL || did_echo_string_emsg) { - if (i > 0) - ga_concat(&ga, (char_u *)", "); - ocmember_T *m = &cl->class_obj_members[i]; - ga_concat(&ga, m->ocm_name); - ga_concat(&ga, (char_u *)": "); - char_u *tf = NULL; - ga_concat(&ga, echo_string_core( - (typval_T *)(obj + 1) + i, - &tf, numbuf, copyID, echo_style, - restore_copyID, composite_val)); - vim_free(tf); + ok = FAIL; + break; } - ga_concat(&ga, (char_u *)"}"); + line_breakcheck(); } - return ga.ga_data; + ga_concat(&ga, (char_u *)"}"); + } + if (ok == FAIL) + { + vim_free(ga.ga_data); + return NULL; } + return (char_u *)ga.ga_data; } /* diff --git a/src/vim9compile.c b/src/vim9compile.c index 0e05f820c5..ea305b7b34 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -522,6 +522,8 @@ use_typecheck(type_T *actual, type_T *expected) (actual->tt_member == &t_void) == (expected->tt_member == &t_void)))) return TRUE; + if (actual->tt_type == VAR_OBJECT && expected->tt_type == VAR_OBJECT) + return TRUE; if ((actual->tt_type == VAR_LIST || actual->tt_type == VAR_DICT) && actual->tt_type == expected->tt_type) // This takes care of a nested list or dict. @@ -1367,6 +1369,7 @@ generate_loadvar(cctx_T *cctx, lhs_T *lhs) generate_LOAD(cctx, ISN_LOADT, 0, name + 2, type); break; case dest_script: + case dest_script_v9: res = compile_load_scriptvar(cctx, name + (name[1] == ':' ? 2 : 0), NULL, NULL); break; @@ -1838,7 +1841,8 @@ compile_lhs( return FAIL; } - lhs->lhs_dest = dest_script; + lhs->lhs_dest = current_script_is_vim9() + ? dest_script_v9 : dest_script; // existing script-local variables should have a type lhs->lhs_scriptvar_sid = current_sctx.sc_sid; @@ -3026,8 +3030,9 @@ compile_assignment( else { if (is_decl && cmdidx == CMD_const && (lhs.lhs_dest == dest_script - || lhs.lhs_dest == dest_global - || lhs.lhs_dest == dest_local)) + || lhs.lhs_dest == dest_script_v9 + || lhs.lhs_dest == dest_global + || lhs.lhs_dest == dest_local)) // ":const var": lock the value, but not referenced variables generate_LOCKCONST(cctx); @@ -3271,261 +3276,194 @@ add_def_function(ufunc_T *ufunc) } /* - * After ex_function() has collected all the function lines: parse and compile - * the lines into instructions. - * Adds the function to "def_functions". - * When "check_return_type" is set then set ufunc->uf_ret_type to the type of - * the return statement (used for lambda). When uf_ret_type is already set - * then check that it matches. - * When "profiling" is true add ISN_PROF_START instructions. - * "outer_cctx" is set for a nested function. - * This can be used recursively through compile_lambda(), which may reallocate - * "def_functions". - * Returns OK or FAIL. + * For an object constructor, generate instruction to setup "this" (the first + * local variable) and to initialize the object variables. */ - int -compile_def_function( - ufunc_T *ufunc, - int check_return_type, - compiletype_T compile_type, - cctx_T *outer_cctx) + static int +obj_constructor_prologue(ufunc_T *ufunc, cctx_T *cctx) { - char_u *line = NULL; - garray_T lines_to_free; - char_u *p; - char *errormsg = NULL; // error message - cctx_T cctx; - garray_T *instr; - int did_emsg_before = did_emsg; - int did_emsg_silent_before = did_emsg_silent; - int ret = FAIL; - sctx_T save_current_sctx = current_sctx; - int save_estack_compiling = estack_compiling; - int save_cmod_flags = cmdmod.cmod_flags; - int do_estack_push; - int new_def_function = FALSE; -#ifdef FEAT_PROFILE - int prof_lnum = -1; -#endif - int debug_lnum = -1; + generate_CONSTRUCT(cctx, ufunc->uf_class); - // allocated lines are freed at the end - ga_init2(&lines_to_free, sizeof(char_u *), 50); - - // When using a function that was compiled before: Free old instructions. - // The index is reused. Otherwise add a new entry in "def_functions". - if (ufunc->uf_dfunc_idx > 0) + for (int i = 0; i < ufunc->uf_class->class_obj_member_count; ++i) { - dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) - + ufunc->uf_dfunc_idx; - isn_T *instr_dest = NULL; + ocmember_T *m = &ufunc->uf_class->class_obj_members[i]; - switch (compile_type) + if (i < 2 && IS_ENUM(ufunc->uf_class)) + // The first two object variables in an enum are the name + // and the ordinal. These are set by the ISN_CONSTRUCT + // instruction. So don't generate instructions to set + // these variables. + continue; + + if (m->ocm_init != NULL) { - case CT_PROFILE: -#ifdef FEAT_PROFILE - instr_dest = dfunc->df_instr_prof; break; -#endif - case CT_NONE: instr_dest = dfunc->df_instr; break; - case CT_DEBUG: instr_dest = dfunc->df_instr_debug; break; - } - if (instr_dest != NULL) - // Was compiled in this mode before: Free old instructions. - delete_def_function_contents(dfunc, FALSE); - ga_clear_strings(&dfunc->df_var_names); - dfunc->df_defer_var_idx = 0; - } - else - { - if (add_def_function(ufunc) == FAIL) - return FAIL; - new_def_function = TRUE; - } + char_u *expr = m->ocm_init; - if ((ufunc->uf_flags & FC_CLOSURE) && outer_cctx == NULL) - { - semsg(_(e_compiling_closure_without_context_str), - printable_func_name(ufunc)); - return FAIL; - } + if (compile_expr0(&expr, cctx) == FAIL) + return FAIL; - ufunc->uf_def_status = UF_COMPILING; + if (!ends_excmd2(m->ocm_init, expr)) + { + semsg(_(e_trailing_characters_str), expr); + return FAIL; + } - CLEAR_FIELD(cctx); + type_T *type = get_type_on_stack(cctx, 0); + if (m->ocm_type->tt_type == VAR_ANY + && !(m->ocm_flags & OCMFLAG_HAS_TYPE) + && type->tt_type != VAR_SPECIAL) + { + // If the member variable type is not yet set, then use + // the initialization expression type. + m->ocm_type = type; + } + else + { + // The type of the member initialization expression is + // determined at run time. Add a runtime type check. + where_T where = WHERE_INIT; + where.wt_kind = WT_MEMBER; + where.wt_func_name = (char *)m->ocm_name; + if (need_type_where(type, m->ocm_type, FALSE, -1, + where, cctx, FALSE, FALSE) == FAIL) + return FAIL; + } + } + else + push_default_value(cctx, m->ocm_type->tt_type, FALSE, NULL); + + if ((m->ocm_type->tt_type == VAR_DICT + || m->ocm_type->tt_type == VAR_LIST) + && m->ocm_type->tt_member != NULL + && m->ocm_type->tt_member != &t_any + && m->ocm_type->tt_member != &t_unknown) + // Set the type in the list or dict, so that it can be checked, + // also in legacy script. + generate_SETTYPE(cctx, m->ocm_type); + + generate_STORE_THIS(cctx, i); + } - cctx.ctx_compile_type = compile_type; - cctx.ctx_ufunc = ufunc; - cctx.ctx_lnum = -1; - cctx.ctx_outer = outer_cctx; - ga_init2(&cctx.ctx_locals, sizeof(lvar_T), 10); - // Each entry on the type stack consists of two type pointers. - ga_init2(&cctx.ctx_type_stack, sizeof(type2_T), 50); - cctx.ctx_type_list = &ufunc->uf_type_list; - ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50); - instr = &cctx.ctx_instr; + return OK; +} - // Set the context to the function, it may be compiled when called from - // another script. Set the script version to the most modern one. - // The line number will be set in next_line_from_context(). - current_sctx = ufunc->uf_script_ctx; - current_sctx.sc_version = SCRIPT_VERSION_VIM9; +/* + * For an object method and an constructor, generate instruction to setup + * "this" (the first local variable). For a constructor, generate instructions + * to initialize the object variables. + */ + static int +obj_method_prologue(ufunc_T *ufunc, cctx_T *cctx) +{ + dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; - // Don't use the flag from ":legacy" here. - cmdmod.cmod_flags &= ~CMOD_LEGACY; + if (GA_GROW_FAILS(&dfunc->df_var_names, 1)) + return FAIL; - // Make sure error messages are OK. - do_estack_push = !estack_top_is_ufunc(ufunc, 1); - if (do_estack_push) - estack_push_ufunc(ufunc, 1); - estack_compiling = TRUE; + ((char_u **)dfunc->df_var_names.ga_data)[0] = + vim_strsave((char_u *)"this"); + ++dfunc->df_var_names.ga_len; - if (check_args_shadowing(ufunc, &cctx) == FAIL) - goto erret; + // In the constructor allocate memory for the object and initialize the + // object members. + if (IS_CONSTRUCTOR_METHOD(ufunc)) + return obj_constructor_prologue(ufunc, cctx); - // For an object method and constructor "this" is the first local variable. - if (ufunc->uf_flags & (FC_OBJECT|FC_NEW)) - { - dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) - + ufunc->uf_dfunc_idx; - if (GA_GROW_FAILS(&dfunc->df_var_names, 1)) - goto erret; - ((char_u **)dfunc->df_var_names.ga_data)[0] = - vim_strsave((char_u *)"this"); - ++dfunc->df_var_names.ga_len; + return OK; +} - // In the constructor allocate memory for the object and initialize the - // object members. - if (IS_CONSTRUCTOR_METHOD(ufunc)) - { - generate_CONSTRUCT(&cctx, ufunc->uf_class); +/* + * Produce instructions for the default values of optional arguments. + */ + static int +compile_def_function_default_args( + ufunc_T *ufunc, + cctx_T *cctx, + garray_T *instr) +{ + int count = ufunc->uf_def_args.ga_len; + int first_def_arg = ufunc->uf_args.ga_len - count; + int i; + int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0); + int did_set_arg_type = FALSE; + + // Produce instructions for the default values of optional arguments. + SOURCING_LNUM = 0; // line number unknown + for (i = 0; i < count; ++i) + { + char_u *arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i]; + if (STRCMP(arg, "v:none") == 0) + // "arg = v:none" means the argument is optional without + // setting a value when the argument is missing. + continue; - for (int i = 0; i < ufunc->uf_class->class_obj_member_count; ++i) - { - ocmember_T *m = &ufunc->uf_class->class_obj_members[i]; + type_T *val_type; + int arg_idx = first_def_arg + i; + where_T where = WHERE_INIT; + int jump_instr_idx = instr->ga_len; + isn_T *isn; - if (i < 2 && IS_ENUM(ufunc->uf_class)) - // The first two object variables in an enum are the name - // and the ordinal. These are set by the ISN_CONSTRUCT - // instruction. So don't generate instructions to set - // these variables. - continue; + // Use a JUMP_IF_ARG_SET instruction to skip if the value was given. + if (generate_JUMP_IF_ARG(cctx, ISN_JUMP_IF_ARG_SET, + i - count - off) == FAIL) + return FAIL; - if (m->ocm_init != NULL) - { - char_u *expr = m->ocm_init; - if (compile_expr0(&expr, &cctx) == FAIL) - goto erret; - if (!ends_excmd2(m->ocm_init, expr)) - { - semsg(_(e_trailing_characters_str), expr); - goto erret; - } + // Make sure later arguments are not found. + ufunc->uf_args_visible = arg_idx; - type_T *type = get_type_on_stack(&cctx, 0); - if (m->ocm_type->tt_type == VAR_ANY - && !(m->ocm_flags & OCMFLAG_HAS_TYPE) - && type->tt_type != VAR_SPECIAL) - { - // If the member variable type is not yet set, then use - // the initialization expression type. - m->ocm_type = type; - } - else if (m->ocm_type->tt_type != type->tt_type) - { - // The type of the member initialization expression is - // determined at run time. Add a runtime type check. - where_T where = WHERE_INIT; - where.wt_kind = WT_MEMBER; - where.wt_func_name = (char *)m->ocm_name; - if (need_type_where(type, m->ocm_type, FALSE, -1, - where, &cctx, FALSE, FALSE) == FAIL) - goto erret; - } - } - else - push_default_value(&cctx, m->ocm_type->tt_type, - FALSE, NULL); - generate_STORE_THIS(&cctx, i); - } - } - } + int r = compile_expr0(&arg, cctx); + if (r == FAIL) + return FAIL; - if (ufunc->uf_def_args.ga_len > 0) - { - int count = ufunc->uf_def_args.ga_len; - int first_def_arg = ufunc->uf_args.ga_len - count; - int i; - int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0); - int did_set_arg_type = FALSE; - - // Produce instructions for the default values of optional arguments. - SOURCING_LNUM = 0; // line number unknown - for (i = 0; i < count; ++i) + // If no type specified use the type of the default value. + // Otherwise check that the default value type matches the + // specified type. + val_type = get_type_on_stack(cctx, 0); + where.wt_index = arg_idx + 1; + where.wt_kind = WT_ARGUMENT; + if (ufunc->uf_arg_types[arg_idx] == &t_unknown) { - char_u *arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i]; - if (STRCMP(arg, "v:none") == 0) - // "arg = v:none" means the argument is optional without - // setting a value when the argument is missing. - continue; + did_set_arg_type = TRUE; + ufunc->uf_arg_types[arg_idx] = val_type; + } + else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx], + FALSE, -1, where, cctx, FALSE, FALSE) == FAIL) + return FAIL; - type_T *val_type; - int arg_idx = first_def_arg + i; - where_T where = WHERE_INIT; - int jump_instr_idx = instr->ga_len; - isn_T *isn; - - // Use a JUMP_IF_ARG_SET instruction to skip if the value was given. - if (generate_JUMP_IF_ARG(&cctx, ISN_JUMP_IF_ARG_SET, - i - count - off) == FAIL) - goto erret; - - // Make sure later arguments are not found. - ufunc->uf_args_visible = arg_idx; - - int r = compile_expr0(&arg, &cctx); - if (r == FAIL) - goto erret; - - // If no type specified use the type of the default value. - // Otherwise check that the default value type matches the - // specified type. - val_type = get_type_on_stack(&cctx, 0); - where.wt_index = arg_idx + 1; - where.wt_kind = WT_ARGUMENT; - if (ufunc->uf_arg_types[arg_idx] == &t_unknown) - { - did_set_arg_type = TRUE; - ufunc->uf_arg_types[arg_idx] = val_type; - } - else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx], - FALSE, -1, where, &cctx, FALSE, FALSE) == FAIL) - goto erret; + if (generate_STORE(cctx, ISN_STORE, i - count - off, NULL) == FAIL) + return FAIL; - if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL) - goto erret; + // set instruction index in JUMP_IF_ARG_SET to here + isn = ((isn_T *)instr->ga_data) + jump_instr_idx; + isn->isn_arg.jumparg.jump_where = instr->ga_len; + } - // set instruction index in JUMP_IF_ARG_SET to here - isn = ((isn_T *)instr->ga_data) + jump_instr_idx; - isn->isn_arg.jumparg.jump_where = instr->ga_len; - } + if (did_set_arg_type) + set_function_type(ufunc); - if (did_set_arg_type) - set_function_type(ufunc); - } - ufunc->uf_args_visible = ufunc->uf_args.ga_len; + return OK; +} - // Compiling a function in an interface is done to get the function type. - // No code is actually compiled. - if (ufunc->uf_class != NULL && IS_INTERFACE(ufunc->uf_class)) - { - ufunc->uf_def_status = UF_NOT_COMPILED; - ret = OK; - goto erret; - } +/* + * Compile def function body. Loop over all the lines in the function and + * generate instructions. + */ + static int +compile_def_function_body( + cctx_T *cctx, + int last_func_lnum, + int check_return_type, + garray_T *lines_to_free, + char **errormsg) +{ + char_u *line = NULL; + char_u *p; + int did_emsg_before = did_emsg; +#ifdef FEAT_PROFILE + int prof_lnum = -1; +#endif + int debug_lnum = -1; - /* - * Loop over all the lines of the function and generate instructions. - */ for (;;) { exarg_T ea; @@ -3536,29 +3474,29 @@ compile_def_function( // Bail out on the first error to avoid a flood of errors and report // the right line number when inside try/catch. if (did_emsg_before != did_emsg) - goto erret; + return FAIL; if (line != NULL && *line == '|') // the line continues after a '|' ++line; else if (line != NULL && *skipwhite(line) != NUL - && !(*line == '#' && (line == cctx.ctx_line_start + && !(*line == '#' && (line == cctx->ctx_line_start || VIM_ISWHITE(line[-1])))) { semsg(_(e_trailing_characters_str), line); - goto erret; + return FAIL; } else if (line != NULL && vim9_bad_comment(skipwhite(line))) - goto erret; + return FAIL; else { - line = next_line_from_context(&cctx, FALSE); - if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len) + line = next_line_from_context(cctx, FALSE); + if (cctx->ctx_lnum >= last_func_lnum) { // beyond the last line #ifdef FEAT_PROFILE - if (cctx.ctx_skip != SKIP_YES) - may_generate_prof_end(&cctx, prof_lnum); + if (cctx->ctx_skip != SKIP_YES) + may_generate_prof_end(cctx, prof_lnum); #endif break; } @@ -3567,42 +3505,42 @@ compile_def_function( if (line != NULL) { line = vim_strsave(line); - if (ga_add_string(&lines_to_free, line) == FAIL) - goto erret; + if (ga_add_string(lines_to_free, line) == FAIL) + return FAIL; } } CLEAR_FIELD(ea); ea.cmdlinep = &line; ea.cmd = skipwhite(line); - ea.skip = cctx.ctx_skip == SKIP_YES; + ea.skip = cctx->ctx_skip == SKIP_YES; if (*ea.cmd == '#') { // "#" starts a comment, but "#{" is an error if (vim9_bad_comment(ea.cmd)) - goto erret; + return FAIL; line = (char_u *)""; continue; } #ifdef FEAT_PROFILE - if (cctx.ctx_compile_type == CT_PROFILE && cctx.ctx_lnum != prof_lnum - && cctx.ctx_skip != SKIP_YES) + if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_lnum != prof_lnum + && cctx->ctx_skip != SKIP_YES) { - may_generate_prof_end(&cctx, prof_lnum); + may_generate_prof_end(cctx, prof_lnum); - prof_lnum = cctx.ctx_lnum; - generate_instr(&cctx, ISN_PROF_START); + prof_lnum = cctx->ctx_lnum; + generate_instr(cctx, ISN_PROF_START); } #endif - if (cctx.ctx_compile_type == CT_DEBUG && cctx.ctx_lnum != debug_lnum - && cctx.ctx_skip != SKIP_YES) + if (cctx->ctx_compile_type == CT_DEBUG && cctx->ctx_lnum != debug_lnum + && cctx->ctx_skip != SKIP_YES) { - debug_lnum = cctx.ctx_lnum; - generate_instr_debug(&cctx); + debug_lnum = cctx->ctx_lnum; + generate_instr_debug(cctx); } - cctx.ctx_prev_lnum = cctx.ctx_lnum + 1; + cctx->ctx_prev_lnum = cctx->ctx_lnum + 1; // Some things can be recognized by the first character. switch (*ea.cmd) @@ -3610,18 +3548,18 @@ compile_def_function( case '}': { // "}" ends a block scope - scopetype_T stype = cctx.ctx_scope == NULL - ? NO_SCOPE : cctx.ctx_scope->se_type; + scopetype_T stype = cctx->ctx_scope == NULL + ? NO_SCOPE : cctx->ctx_scope->se_type; if (stype == BLOCK_SCOPE) { - compile_endblock(&cctx); + compile_endblock(cctx); line = ea.cmd; } else { emsg(_(e_using_rcurly_outside_if_block_scope)); - goto erret; + return FAIL; } if (line != NULL) line = skipwhite(ea.cmd + 1); @@ -3633,7 +3571,7 @@ compile_def_function( // "{'a': 1}->func() is something else if (ends_excmd(*skipwhite(ea.cmd + 1))) { - line = compile_block(ea.cmd, &cctx); + line = compile_block(ea.cmd, cctx); continue; } break; @@ -3642,11 +3580,11 @@ compile_def_function( /* * COMMAND MODIFIERS */ - cctx.ctx_has_cmdmod = FALSE; - if (parse_command_modifiers(&ea, &errormsg, &local_cmdmod, FALSE) + cctx->ctx_has_cmdmod = FALSE; + if (parse_command_modifiers(&ea, errormsg, &local_cmdmod, FALSE) == FAIL) - goto erret; - generate_cmdmods(&cctx, &local_cmdmod); + return FAIL; + generate_cmdmods(cctx, &local_cmdmod); undo_cmdmod(&local_cmdmod); // Check if there was a colon after the last command modifier or before @@ -3677,11 +3615,11 @@ compile_def_function( int assign; // Check for assignment after command modifiers. - assign = may_compile_assignment(&ea, &line, &cctx); + assign = may_compile_assignment(&ea, &line, cctx); if (assign == OK) goto nextline; if (assign == FAIL) - goto erret; + return FAIL; } } @@ -3709,13 +3647,13 @@ compile_def_function( && !(local_cmdmod.cmod_flags & CMOD_LEGACY)) { semsg(_(e_colon_required_before_range_str), cmd); - goto erret; + return FAIL; } ea.addr_count = 1; if (ends_excmd2(line, ea.cmd)) { // A range without a command: jump to the line. - generate_EXEC(&cctx, ISN_EXECRANGE, + generate_EXEC(cctx, ISN_EXECRANGE, vim_strnsave(cmd, ea.cmd - cmd)); line = ea.cmd; goto nextline; @@ -3724,13 +3662,13 @@ compile_def_function( } p = find_ex_command(&ea, NULL, starts_with_colon || (local_cmdmod.cmod_flags & CMOD_LEGACY) - ? NULL : item_exists, &cctx); + ? NULL : item_exists, cctx); if (p == NULL) { - if (cctx.ctx_skip != SKIP_YES) + if (cctx->ctx_skip != SKIP_YES) semsg(_(e_ambiguous_use_of_user_defined_command_str), ea.cmd); - goto erret; + return FAIL; } // When using ":legacy cmd" always use compile_exec(). @@ -3755,7 +3693,7 @@ compile_def_function( case CMD_finally: case CMD_endtry: semsg(_(e_cannot_use_legacy_with_command_str), ea.cmd); - goto erret; + return FAIL; default: break; } @@ -3772,7 +3710,7 @@ compile_def_function( // "p" is equal to "ea.cmd" for a valid command. if (ea.cmdidx == CMD_eval || ea.cmdidx == CMD_var) ; - else if (cctx.ctx_skip == SKIP_YES) + else if (cctx->ctx_skip == SKIP_YES) { line += STRLEN(line); goto nextline; @@ -3780,11 +3718,11 @@ compile_def_function( else { semsg(_(e_command_not_recognized_str), ea.cmd); - goto erret; + return FAIL; } } - if ((cctx.ctx_had_return || cctx.ctx_had_throw) + if ((cctx->ctx_had_return || cctx->ctx_had_throw) && ea.cmdidx != CMD_elseif && ea.cmdidx != CMD_else && ea.cmdidx != CMD_endif @@ -3796,10 +3734,10 @@ compile_def_function( && !ignore_unreachable_code_for_testing) { semsg(_(e_unreachable_code_after_str), - cctx.ctx_had_return ? "return" : "throw"); - goto erret; + cctx->ctx_had_return ? "return" : "throw"); + return FAIL; } - cctx.ctx_had_throw = FALSE; + cctx->ctx_had_throw = FALSE; p = skipwhite(p); if (ea.cmdidx != CMD_SIZE @@ -3815,7 +3753,7 @@ compile_def_function( if ((ea.argt & EX_RANGE) == 0 && ea.addr_count > 0) { emsg(_(e_no_range_allowed)); - goto erret; + return FAIL; } } @@ -3824,13 +3762,13 @@ compile_def_function( case CMD_def: case CMD_function: ea.arg = p; - line = compile_nested_function(&ea, &cctx, &lines_to_free); + line = compile_nested_function(&ea, cctx, lines_to_free); break; case CMD_return: line = compile_return(p, check_return_type, - local_cmdmod.cmod_flags & CMOD_LEGACY, &cctx); - cctx.ctx_had_return = TRUE; + local_cmdmod.cmod_flags & CMOD_LEGACY, cctx); + cctx->ctx_had_return = TRUE; break; case CMD_let: @@ -3841,7 +3779,7 @@ compile_def_function( case CMD_const: case CMD_increment: case CMD_decrement: - line = compile_assignment(p, &ea, ea.cmdidx, &cctx); + line = compile_assignment(p, &ea, ea.cmdidx, cctx); if (line == p) { emsg(_(e_invalid_assignment)); @@ -3852,7 +3790,7 @@ compile_def_function( case CMD_unlet: case CMD_unlockvar: case CMD_lockvar: - line = compile_unletlock(p, &ea, &cctx); + line = compile_unletlock(p, &ea, cctx); break; case CMD_import: @@ -3861,67 +3799,67 @@ compile_def_function( break; case CMD_if: - line = compile_if(p, &cctx); + line = compile_if(p, cctx); break; case CMD_elseif: - line = compile_elseif(p, &cctx); - cctx.ctx_had_return = FALSE; + line = compile_elseif(p, cctx); + cctx->ctx_had_return = FALSE; break; case CMD_else: - line = compile_else(p, &cctx); - cctx.ctx_had_return = FALSE; + line = compile_else(p, cctx); + cctx->ctx_had_return = FALSE; break; case CMD_endif: - line = compile_endif(p, &cctx); + line = compile_endif(p, cctx); break; case CMD_while: - line = compile_while(p, &cctx); + line = compile_while(p, cctx); break; case CMD_endwhile: - line = compile_endwhile(p, &cctx); - cctx.ctx_had_return = FALSE; + line = compile_endwhile(p, cctx); + cctx->ctx_had_return = FALSE; break; case CMD_for: - line = compile_for(p, &cctx); + line = compile_for(p, cctx); break; case CMD_endfor: - line = compile_endfor(p, &cctx); - cctx.ctx_had_return = FALSE; + line = compile_endfor(p, cctx); + cctx->ctx_had_return = FALSE; break; case CMD_continue: - line = compile_continue(p, &cctx); + line = compile_continue(p, cctx); break; case CMD_break: - line = compile_break(p, &cctx); + line = compile_break(p, cctx); break; case CMD_try: - line = compile_try(p, &cctx); + line = compile_try(p, cctx); break; case CMD_catch: - line = compile_catch(p, &cctx); - cctx.ctx_had_return = FALSE; + line = compile_catch(p, cctx); + cctx->ctx_had_return = FALSE; break; case CMD_finally: - line = compile_finally(p, &cctx); - cctx.ctx_had_return = FALSE; + line = compile_finally(p, cctx); + cctx->ctx_had_return = FALSE; break; case CMD_endtry: - line = compile_endtry(p, &cctx); + line = compile_endtry(p, cctx); break; case CMD_throw: - line = compile_throw(p, &cctx); - cctx.ctx_had_throw = TRUE; + line = compile_throw(p, cctx); + cctx->ctx_had_throw = TRUE; break; case CMD_eval: - line = compile_eval(p, &cctx); + line = compile_eval(p, cctx); break; case CMD_defer: - line = compile_defer(p, &cctx); + line = compile_defer(p, cctx); break; #ifdef HAS_MESSAGE_WINDOW @@ -3932,7 +3870,7 @@ compile_def_function( line = NULL; else line = compile_mult_expr(p, ea.cmdidx, - cmd_count, &cctx); + cmd_count, cctx); } break; #endif @@ -3942,29 +3880,29 @@ compile_def_function( case CMD_echoerr: case CMD_echomsg: case CMD_execute: - line = compile_mult_expr(p, ea.cmdidx, 0, &cctx); + line = compile_mult_expr(p, ea.cmdidx, 0, cctx); break; case CMD_put: ea.cmd = cmd; - line = compile_put(p, &ea, &cctx); + line = compile_put(p, &ea, cctx); break; case CMD_substitute: if (check_global_and_subst(ea.cmd, p) == FAIL) - goto erret; - if (cctx.ctx_skip == SKIP_YES) + return FAIL; + if (cctx->ctx_skip == SKIP_YES) line = (char_u *)""; else { ea.arg = p; - line = compile_substitute(line, &ea, &cctx); + line = compile_substitute(line, &ea, cctx); } break; case CMD_redir: ea.arg = p; - line = compile_redir(line, &ea, &cctx); + line = compile_redir(line, &ea, cctx); break; case CMD_cexpr: @@ -3975,7 +3913,7 @@ compile_def_function( case CMD_lgetexpr: #ifdef FEAT_QUICKFIX ea.arg = p; - line = compile_cexpr(line, &ea, &cctx); + line = compile_cexpr(line, &ea, cctx); #else ex_ni(&ea); line = NULL; @@ -3989,13 +3927,13 @@ compile_def_function( case CMD_t: case CMD_xit: not_in_vim9(&ea); - goto erret; + return FAIL; case CMD_SIZE: - if (cctx.ctx_skip != SKIP_YES) + if (cctx->ctx_skip != SKIP_YES) { semsg(_(e_invalid_command_str), ea.cmd); - goto erret; + return FAIL; } // We don't check for a next command here. line = (char_u *)""; @@ -4012,55 +3950,189 @@ compile_def_function( case CMD_tcl: ea.arg = p; if (vim_strchr(line, '\n') == NULL) - line = compile_exec(line, &ea, &cctx); + line = compile_exec(line, &ea, cctx); else // heredoc lines have been concatenated with NL // characters in get_function_body() - line = compile_script(line, &cctx); + line = compile_script(line, cctx); break; case CMD_vim9script: - if (cctx.ctx_skip != SKIP_YES) + if (cctx->ctx_skip != SKIP_YES) { emsg(_(e_vim9script_can_only_be_used_in_script)); - goto erret; + return FAIL; } line = (char_u *)""; break; case CMD_class: emsg(_(e_class_can_only_be_used_in_script)); - goto erret; + return FAIL; case CMD_type: emsg(_(e_type_can_only_be_used_in_script)); - goto erret; + return FAIL; case CMD_global: if (check_global_and_subst(ea.cmd, p) == FAIL) - goto erret; + return FAIL; // FALLTHROUGH default: // Not recognized, execute with do_cmdline_cmd(). ea.arg = p; - line = compile_exec(line, &ea, &cctx); + line = compile_exec(line, &ea, cctx); break; } nextline: if (line == NULL) - goto erret; + return FAIL; line = skipwhite(line); // Undo any command modifiers. - generate_undo_cmdmods(&cctx); + generate_undo_cmdmods(cctx); - if (cctx.ctx_type_stack.ga_len < 0) + if (cctx->ctx_type_stack.ga_len < 0) { iemsg("Type stack underflow"); - goto erret; + return FAIL; } } // END of the loop over all the function body lines. + return OK; +} + +/* + * After ex_function() has collected all the function lines: parse and compile + * the lines into instructions. + * Adds the function to "def_functions". + * When "check_return_type" is set then set ufunc->uf_ret_type to the type of + * the return statement (used for lambda). When uf_ret_type is already set + * then check that it matches. + * When "profiling" is true add ISN_PROF_START instructions. + * "outer_cctx" is set for a nested function. + * This can be used recursively through compile_lambda(), which may reallocate + * "def_functions". + * Returns OK or FAIL. + */ + int +compile_def_function( + ufunc_T *ufunc, + int check_return_type, + compiletype_T compile_type, + cctx_T *outer_cctx) +{ + garray_T lines_to_free; + char *errormsg = NULL; // error message + cctx_T cctx; + garray_T *instr; + int did_emsg_before = did_emsg; + int did_emsg_silent_before = did_emsg_silent; + int ret = FAIL; + sctx_T save_current_sctx = current_sctx; + int save_estack_compiling = estack_compiling; + int save_cmod_flags = cmdmod.cmod_flags; + int do_estack_push; + int new_def_function = FALSE; + + // allocated lines are freed at the end + ga_init2(&lines_to_free, sizeof(char_u *), 50); + + // When using a function that was compiled before: Free old instructions. + // The index is reused. Otherwise add a new entry in "def_functions". + if (ufunc->uf_dfunc_idx > 0) + { + dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + + ufunc->uf_dfunc_idx; + isn_T *instr_dest = NULL; + + switch (compile_type) + { + case CT_PROFILE: +#ifdef FEAT_PROFILE + instr_dest = dfunc->df_instr_prof; break; +#endif + case CT_NONE: instr_dest = dfunc->df_instr; break; + case CT_DEBUG: instr_dest = dfunc->df_instr_debug; break; + } + if (instr_dest != NULL) + // Was compiled in this mode before: Free old instructions. + delete_def_function_contents(dfunc, FALSE); + ga_clear_strings(&dfunc->df_var_names); + dfunc->df_defer_var_idx = 0; + } + else + { + if (add_def_function(ufunc) == FAIL) + return FAIL; + new_def_function = TRUE; + } + + if ((ufunc->uf_flags & FC_CLOSURE) && outer_cctx == NULL) + { + semsg(_(e_compiling_closure_without_context_str), + printable_func_name(ufunc)); + return FAIL; + } + + ufunc->uf_def_status = UF_COMPILING; + + CLEAR_FIELD(cctx); + + cctx.ctx_compile_type = compile_type; + cctx.ctx_ufunc = ufunc; + cctx.ctx_lnum = -1; + cctx.ctx_outer = outer_cctx; + ga_init2(&cctx.ctx_locals, sizeof(lvar_T), 10); + // Each entry on the type stack consists of two type pointers. + ga_init2(&cctx.ctx_type_stack, sizeof(type2_T), 50); + cctx.ctx_type_list = &ufunc->uf_type_list; + ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50); + instr = &cctx.ctx_instr; + + // Set the context to the function, it may be compiled when called from + // another script. Set the script version to the most modern one. + // The line number will be set in next_line_from_context(). + current_sctx = ufunc->uf_script_ctx; + current_sctx.sc_version = SCRIPT_VERSION_VIM9; + + // Don't use the flag from ":legacy" here. + cmdmod.cmod_flags &= ~CMOD_LEGACY; + + // Make sure error messages are OK. + do_estack_push = !estack_top_is_ufunc(ufunc, 1); + if (do_estack_push) + estack_push_ufunc(ufunc, 1); + estack_compiling = TRUE; + + if (check_args_shadowing(ufunc, &cctx) == FAIL) + goto erret; + + // For an object method and a constructor generate instructions to + // initialize "this" and the object variables. + if (ufunc->uf_flags & (FC_OBJECT|FC_NEW)) + if (obj_method_prologue(ufunc, &cctx) == FAIL) + goto erret; + + if (ufunc->uf_def_args.ga_len > 0) + if (compile_def_function_default_args(ufunc, &cctx, instr) == FAIL) + goto erret; + ufunc->uf_args_visible = ufunc->uf_args.ga_len; + + // Compiling a function in an interface is done to get the function type. + // No code is actually compiled. + if (ufunc->uf_class != NULL && IS_INTERFACE(ufunc->uf_class)) + { + ufunc->uf_def_status = UF_NOT_COMPILED; + ret = OK; + goto erret; + } + + // compile the function body + if (compile_def_function_body(&cctx, ufunc->uf_lines.ga_len, + check_return_type, &lines_to_free, &errormsg) == FAIL) + goto erret; + if (cctx.ctx_scope != NULL) { if (cctx.ctx_scope->se_type == IF_SCOPE) diff --git a/src/vim9execute.c b/src/vim9execute.c index 5af3af68ba..3a3960a8d1 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -3842,11 +3842,19 @@ exec_instructions(ectx_T *ectx) case ISN_STOREEXPORT: { int sid = iptr->isn_arg.loadstore.ls_sid; - hashtab_T *ht = &SCRIPT_VARS(sid); char_u *name = iptr->isn_arg.loadstore.ls_name; - dictitem_T *di = find_var_in_ht(ht, 0, - iptr->isn_type == ISN_STORES + dictitem_T *di = NULL; + // First check for a variable from an exported autoload + // with an autoload_prefix; it would be in globals. + if (iptr->isn_type == ISN_STOREEXPORT) + di = find_var_autoload_prefix(name, sid, NULL, NULL); + // Then look for a variable in the script's variables. + if (di == NULL) + { + hashtab_T *ht = &SCRIPT_VARS(sid); + di = find_var_in_ht(ht, 0, STRNCMP("s:", name, 2) == 0 ? name + 2 : name, TRUE); + } --ectx->ec_stack.ga_len; SOURCING_LNUM = iptr->isn_lnum; diff --git a/src/vim9expr.c b/src/vim9expr.c index 8c412b876d..c2428f4bbe 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -425,7 +425,7 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type) if (type->tt_type == VAR_OBJECT) { - ocmember_T *m = object_member_lookup(cl, name, len, &m_idx); + ocmember_T *m = object_member_lookup(cl, name, len, &m_idx); if (m_idx >= 0) { if (*name == '_' && !inside_class(cctx, cl)) @@ -2836,12 +2836,13 @@ compile_expr8(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) type_T *actual; where_T where = WHERE_INIT; + where.wt_kind = WT_CAST; generate_ppconst(cctx, ppconst); actual = get_type_on_stack(cctx, 0); if (check_type_maybe(want_type, actual, FALSE, where) != OK) { - if (need_type(actual, want_type, FALSE, - -1, 0, cctx, FALSE, FALSE) == FAIL) + if (need_type_where(actual, want_type, FALSE, -1, where, cctx, FALSE, FALSE) + == FAIL) return FAIL; } } diff --git a/src/vim9instr.c b/src/vim9instr.c index 4df63fd09a..ad8beb1a30 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -2394,6 +2394,7 @@ generate_store_var( case dest_vimvar: return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL); case dest_script: + case dest_script_v9: { int scriptvar_idx = lhs->lhs_scriptvar_idx; int scriptvar_sid = lhs->lhs_scriptvar_sid; @@ -2401,10 +2402,14 @@ generate_store_var( { isntype_T isn_type = ISN_STORES; + // If "sn_import_autoload", generate ISN_STOREEXPORT (not + // ISN_STORES) if destination is in a vim9script or if + // there is no "sn_autoload_prefix". if (SCRIPT_ID_VALID(scriptvar_sid) && SCRIPT_ITEM(scriptvar_sid)->sn_import_autoload - && SCRIPT_ITEM(scriptvar_sid)->sn_autoload_prefix - == NULL) + && ((SCRIPT_ITEM(scriptvar_sid) + ->sn_autoload_prefix == NULL) + || lhs->lhs_dest == dest_script_v9)) { // "import autoload './dir/script.vim'" - load script // first diff --git a/src/vim9script.c b/src/vim9script.c index a64ce72126..3035889649 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -456,15 +456,24 @@ handle_import( scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); char_u *tail = gettail(si->sn_name); char_u *from_name; + int sourced_from_nofile_buf = FALSE; - // Relative to current script: "./name.vim", "../../name.vim". - len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2; - from_name = alloc((int)len); - if (from_name == NULL) - goto erret; - vim_strncpy(from_name, si->sn_name, tail - si->sn_name); - add_pathsep(from_name); - STRCAT(from_name, tv.vval.v_string); + if (STRNCMP(si->sn_name, ":source buffer=", 15) == 0) + sourced_from_nofile_buf = TRUE; + + if (!sourced_from_nofile_buf) + { + // Relative to current script: "./name.vim", "../../name.vim". + len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2; + from_name = alloc((int)len); + if (from_name == NULL) + goto erret; + vim_strncpy(from_name, si->sn_name, tail - si->sn_name); + add_pathsep(from_name); + STRCAT(from_name, tv.vval.v_string); + } + else + from_name = vim_strsave(tv.vval.v_string); simplify_filename(from_name); res = handle_import_fname(from_name, is_autoload, &sid); diff --git a/src/vim9type.c b/src/vim9type.c index 691c26bf8e..a1571218f6 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -208,6 +208,59 @@ set_tv_type_recurse(type_T *type) && type->tt_member->tt_member != &t_unknown; } +/* + * Set the type of Dict "d" to "type" + */ + static void +set_tv_type_dict(dict_T *d, type_T *type) +{ + if (d->dv_type == type) + return; + + free_type(d->dv_type); + d->dv_type = alloc_type(type); + + // Need to recursively set the type of dict items? + if (!set_tv_type_recurse(type)) + return; + + int todo = (int)d->dv_hashtab.ht_used; + hashitem_T *hi; + dictitem_T *di; + + FOR_ALL_HASHTAB_ITEMS(&d->dv_hashtab, hi, todo) + { + if (!HASHITEM_EMPTY(hi)) + { + --todo; + di = HI2DI(hi); + set_tv_type(&di->di_tv, type->tt_member); + } + } +} + +/* + * Set the type of List "l" to "type" + */ + static void +set_tv_type_list(list_T *l, type_T *type) +{ + if (l->lv_type == type) + return; + + free_type(l->lv_type); + l->lv_type = alloc_type(type); + + // Need to recursively set the type of list items? + if (l->lv_first == &range_list_item || !set_tv_type_recurse(type)) + return; + + listitem_T *li; + + FOR_ALL_LIST_ITEMS(l, li) + set_tv_type(&li->li_tv, type->tt_member); +} + /* * Set the type of "tv" to "type" if it is a list or dict. */ @@ -218,49 +271,11 @@ set_tv_type(typval_T *tv, type_T *type) // If the variable type is "any", then keep the value type. // e.g. var x: any = [1, 2] or var y: any = {v: 1} return; - if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) - { - dict_T *d = tv->vval.v_dict; - if (d->dv_type != type) - { - free_type(d->dv_type); - d->dv_type = alloc_type(type); - if (set_tv_type_recurse(type)) - { - int todo = (int)d->dv_hashtab.ht_used; - hashitem_T *hi; - dictitem_T *di; - - FOR_ALL_HASHTAB_ITEMS(&d->dv_hashtab, hi, todo) - { - if (!HASHITEM_EMPTY(hi)) - { - --todo; - di = HI2DI(hi); - set_tv_type(&di->di_tv, type->tt_member); - } - } - } - } - } + if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) + set_tv_type_dict(tv->vval.v_dict, type); else if (tv->v_type == VAR_LIST && tv->vval.v_list != NULL) - { - list_T *l = tv->vval.v_list; - - if (l->lv_type != type) - { - free_type(l->lv_type); - l->lv_type = alloc_type(type); - if (l->lv_first != &range_list_item && set_tv_type_recurse(type)) - { - listitem_T *li; - - FOR_ALL_LIST_ITEMS(l, li) - set_tv_type(&li->li_tv, type->tt_member); - } - } - } + set_tv_type_list(tv->vval.v_list, type); } type_T * @@ -414,11 +429,131 @@ func_type_add_arg_types( type_any_or_unknown(type_T *type) { return type == NULL || type->tt_type == VAR_ANY - || type->tt_type == VAR_UNKNOWN; + || type->tt_type == VAR_UNKNOWN; +} + +/* + * Get a type_T for a "special" typval in "tv". + */ + static type_T * +special_typval2type(typval_T *tv) +{ + switch (tv->vval.v_number) + { + case VVAL_NULL: + return &t_null; + + case VVAL_NONE: + return &t_none; + + case VVAL_TRUE: + case VVAL_FALSE: + return &t_bool; + + default: + return &t_unknown; + } +} + +/* + * Get a type_T for a List typval in "tv". + * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use + * "any". + * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it + * is "any". + */ + static type_T * +list_typval2type(typval_T *tv, int copyID, garray_T *type_gap, int flags) +{ + list_T *l = tv->vval.v_list; + listitem_T *li; + type_T *member_type = NULL; + + // An empty list has type list<unknown>, unless the type was specified + // and is not list<any>. This matters when assigning to a variable + // with a specific list type. + if (l == NULL || (l->lv_first == NULL + && (l->lv_type == NULL || l->lv_type->tt_member == &t_any))) + return &t_list_empty; + + if ((flags & TVTT_DO_MEMBER) == 0) + return &t_list_any; + + // If the type is list<any> go through the members, it may end up a + // more specific type. + if (l->lv_type != NULL && (l->lv_first == NULL + || (flags & TVTT_MORE_SPECIFIC) == 0 + || l->lv_type->tt_member != &t_any)) + // make a copy, lv_type may be freed if the list is freed + return copy_type_deep(l->lv_type, type_gap); + + if (l->lv_first == &range_list_item) + return &t_list_number; + + if (l->lv_copyID == copyID) + // avoid recursion + return &t_list_any; + + l->lv_copyID = copyID; + + // Use the common type of all members. + member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap, + TVTT_DO_MEMBER); + for (li = l->lv_first->li_next; li != NULL; li = li->li_next) + common_type(typval2type(&li->li_tv, copyID, type_gap, TVTT_DO_MEMBER), + member_type, &member_type, type_gap); + + return get_list_type(member_type, type_gap); } /* - * Get a type_T for a partial typval in "tv". + * Get a type_T for a Dict typval in "tv". + * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use + * "any". + * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it + * is "any". + */ + static type_T * +dict_typval2type(typval_T *tv, int copyID, garray_T *type_gap, int flags) +{ + dict_iterator_T iter; + typval_T *value; + dict_T *d = tv->vval.v_dict; + type_T *member_type = NULL; + + if (d == NULL || (d->dv_hashtab.ht_used == 0 && d->dv_type == NULL)) + return &t_dict_empty; + + if ((flags & TVTT_DO_MEMBER) == 0) + return &t_dict_any; + + // If the type is dict<any> go through the members, it may end up a + // more specific type. + if (d->dv_type != NULL && (d->dv_hashtab.ht_used == 0 + || (flags & TVTT_MORE_SPECIFIC) == 0 + || d->dv_type->tt_member != &t_any)) + return d->dv_type; + + if (d->dv_copyID == copyID) + // avoid recursion + return &t_dict_any; + + d->dv_copyID = copyID; + + // Use the common type of all values. + dict_iterate_start(tv, &iter); + dict_iterate_next(&iter, &value); + member_type = typval2type(value, copyID, type_gap, TVTT_DO_MEMBER); + + while (dict_iterate_next(&iter, &value) != NULL) + common_type(typval2type(value, copyID, type_gap, TVTT_DO_MEMBER), + member_type, &member_type, type_gap); + + return get_dict_type(member_type, type_gap); +} + +/* + * Get a type_T for a "partial" typval in "tv". */ static type_T * partial_typval2type(typval_T *tv, ufunc_T *ufunc, garray_T *type_gap) @@ -448,169 +583,84 @@ partial_typval2type(typval_T *tv, ufunc_T *ufunc, garray_T *type_gap) } /* - * Get a type_T for a typval_T. - * "type_gap" is used to temporarily create types in. - * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use - * "any". - * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it - * is "any". + * Get a type_T for a "class" or an "object" typval in "tv". */ static type_T * -typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags) +oc_typval2type(typval_T *tv) { - type_T *type; - type_T *member_type = NULL; - class_T *class_type = NULL; - int argcount = 0; - int min_argcount = 0; - - if (tv->v_type == VAR_NUMBER) - return &t_number; - if (tv->v_type == VAR_BOOL) - return &t_bool; - if (tv->v_type == VAR_SPECIAL) - { - if (tv->vval.v_number == VVAL_NULL) - return &t_null; - if (tv->vval.v_number == VVAL_NONE) - return &t_none; - if (tv->vval.v_number == VVAL_TRUE - || tv->vval.v_number == VVAL_FALSE) - return &t_bool; - return &t_unknown; - } - if (tv->v_type == VAR_STRING) - return &t_string; - if (tv->v_type == VAR_BLOB) + if (tv->v_type == VAR_CLASS) { - if (tv->vval.v_blob == NULL) - return &t_blob_null; - return &t_blob; - } + if (tv->vval.v_class == NULL) + return &t_class; - if (tv->v_type == VAR_LIST) - { - list_T *l = tv->vval.v_list; - listitem_T *li; - - // An empty list has type list<unknown>, unless the type was specified - // and is not list<any>. This matters when assigning to a variable - // with a specific list type. - if (l == NULL || (l->lv_first == NULL - && (l->lv_type == NULL || l->lv_type->tt_member == &t_any))) - return &t_list_empty; - if ((flags & TVTT_DO_MEMBER) == 0) - return &t_list_any; - // If the type is list<any> go through the members, it may end up a - // more specific type. - if (l->lv_type != NULL && (l->lv_first == NULL - || (flags & TVTT_MORE_SPECIFIC) == 0 - || l->lv_type->tt_member != &t_any)) - // make a copy, lv_type may be freed if the list is freed - return copy_type_deep(l->lv_type, type_gap); - if (l->lv_first == &range_list_item) - return &t_list_number; - if (l->lv_copyID == copyID) - // avoid recursion - return &t_list_any; - l->lv_copyID = copyID; - - // Use the common type of all members. - member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap, - TVTT_DO_MEMBER); - for (li = l->lv_first->li_next; li != NULL; li = li->li_next) - common_type(typval2type(&li->li_tv, copyID, type_gap, - TVTT_DO_MEMBER), - member_type, &member_type, type_gap); - return get_list_type(member_type, type_gap); + return &tv->vval.v_class->class_type; } - if (tv->v_type == VAR_DICT) + if (tv->vval.v_object != NULL) + return &tv->vval.v_object->obj_class->class_object_type; + + return &t_object; +} + +/* + * Get a type_T for a "function" or a "partial" + */ + static type_T * +fp_typval2type(typval_T *tv, garray_T *type_gap) +{ + char_u *name = NULL; + ufunc_T *ufunc = NULL; + type_T *type; + type_T *member_type = NULL; + int argcount = 0; + int min_argcount = 0; + + if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL) { - dict_iterator_T iter; - typval_T *value; - dict_T *d = tv->vval.v_dict; - - if (d == NULL || (d->dv_hashtab.ht_used == 0 && d->dv_type == NULL)) - return &t_dict_empty; - if ((flags & TVTT_DO_MEMBER) == 0) - return &t_dict_any; - // If the type is dict<any> go through the members, it may end up a - // more specific type. - if (d->dv_type != NULL && (d->dv_hashtab.ht_used == 0 - || (flags & TVTT_MORE_SPECIFIC) == 0 - || d->dv_type->tt_member != &t_any)) - return d->dv_type; - if (d->dv_copyID == copyID) - // avoid recursion - return &t_dict_any; - d->dv_copyID = copyID; - - // Use the common type of all values. - dict_iterate_start(tv, &iter); - dict_iterate_next(&iter, &value); - member_type = typval2type(value, copyID, type_gap, TVTT_DO_MEMBER); - while (dict_iterate_next(&iter, &value) != NULL) - common_type(typval2type(value, copyID, type_gap, TVTT_DO_MEMBER), - member_type, &member_type, type_gap); - return get_dict_type(member_type, type_gap); + if (tv->vval.v_partial->pt_func != NULL) + ufunc = tv->vval.v_partial->pt_func; + else + name = tv->vval.v_partial->pt_name; } + else + name = tv->vval.v_string; - if (tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) + if (name == NULL && ufunc == NULL) + return &t_func_unknown; + + if (name != NULL) { - char_u *name = NULL; - ufunc_T *ufunc = NULL; + int idx = find_internal_func(name); - if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL) - { - if (tv->vval.v_partial->pt_func != NULL) - ufunc = tv->vval.v_partial->pt_func; - else - name = tv->vval.v_partial->pt_name; - } - else - name = tv->vval.v_string; - if (name == NULL && ufunc == NULL) - return &t_func_unknown; - if (name != NULL) + if (idx >= 0) { - int idx = find_internal_func(name); - - if (idx >= 0) - { - type_T *decl_type; // unused + type_T *decl_type; // unused - internal_func_get_argcount(idx, &argcount, &min_argcount); - member_type = internal_func_ret_type(idx, 0, NULL, &decl_type, - type_gap); - } - else - ufunc = find_func(name, FALSE); + internal_func_get_argcount(idx, &argcount, &min_argcount); + member_type = internal_func_ret_type(idx, 0, NULL, &decl_type, + type_gap); } - if (ufunc != NULL) + else + ufunc = find_func(name, FALSE); + } + if (ufunc != NULL) + { + // May need to get the argument types from default values by + // compiling the function. + if (ufunc->uf_def_status == UF_TO_BE_COMPILED + && compile_def_function(ufunc, TRUE, CT_NONE, NULL) + == FAIL) + return NULL; + if (ufunc->uf_func_type == NULL) + set_function_type(ufunc); + if (ufunc->uf_func_type != NULL) { - // May need to get the argument types from default values by - // compiling the function. - if (ufunc->uf_def_status == UF_TO_BE_COMPILED - && compile_def_function(ufunc, TRUE, CT_NONE, NULL) - == FAIL) - return NULL; - if (ufunc->uf_func_type == NULL) - set_function_type(ufunc); - if (ufunc->uf_func_type != NULL) - { - if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL) - return partial_typval2type(tv, ufunc, type_gap); - return ufunc->uf_func_type; - } + if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL) + return partial_typval2type(tv, ufunc, type_gap); + return ufunc->uf_func_type; } } - if (tv->v_type == VAR_CLASS) - class_type = tv->vval.v_class; - else if (tv->v_type == VAR_OBJECT && tv->vval.v_object != NULL) - class_type = tv->vval.v_object->obj_class; - type = get_type_ptr(type_gap); if (type == NULL) return NULL; @@ -618,17 +668,89 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags) type->tt_argcount = argcount; type->tt_min_argcount = min_argcount; if (tv->v_type == VAR_PARTIAL && tv->vval.v_partial != NULL - && tv->vval.v_partial->pt_argc > 0) + && tv->vval.v_partial->pt_argc > 0) { type->tt_argcount -= tv->vval.v_partial->pt_argc; type->tt_min_argcount -= tv->vval.v_partial->pt_argc; } type->tt_member = member_type; - type->tt_class = class_type; return type; } +/* + * Get a type_T for a typval_T. + * "type_gap" is used to temporarily create types in. + * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use + * "any". + * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it + * is "any". + */ + static type_T * +typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags) +{ + switch (tv->v_type) + { + case VAR_UNKNOWN: + return &t_unknown; + + case VAR_ANY: + return &t_any; + + case VAR_VOID: + return &t_void; + + case VAR_BOOL: + return &t_bool; + + case VAR_SPECIAL: + return special_typval2type(tv); + + case VAR_NUMBER: + return &t_number; + + case VAR_FLOAT: + return &t_float; + + case VAR_STRING: + return &t_string; + + case VAR_BLOB: + if (tv->vval.v_blob == NULL) + return &t_blob_null; + return &t_blob; + + case VAR_LIST: + return list_typval2type(tv, copyID, type_gap, flags); + + case VAR_DICT: + return dict_typval2type(tv, copyID, type_gap, flags); + + case VAR_JOB: + return &t_job; + + case VAR_CHANNEL: + return &t_channel; + + case VAR_CLASS: + case VAR_OBJECT: + return oc_typval2type(tv); + + case VAR_TYPEALIAS: + return &t_typealias; + + case VAR_FUNC: + case VAR_PARTIAL: + return fp_typval2type(tv, type_gap); + + case VAR_INSTR: + default: + break; + } + + return NULL; +} + /* * Return TRUE if "tv" is not a bool but should be converted to bool. */ @@ -812,6 +934,7 @@ type_mismatch_where(type_T *expected, type_T *actual, where_T where) semsg(_(e_argument_nr_type_mismatch_expected_str_but_got_str_in_str), where.wt_index, typename1, typename2, where.wt_func_name); break; + case WT_CAST: case WT_UNKNOWN: if (where.wt_func_name == NULL) semsg(_(e_type_mismatch_expected_str_but_got_str), @@ -968,7 +1091,15 @@ check_type_maybe( ret = FAIL; } else if (!class_instance_of(actual->tt_class, expected->tt_class)) - ret = FAIL; + { + // Check if this is an up-cast, if so we'll have to check the type at + // runtime. + if (where.wt_kind == WT_CAST && + class_instance_of(expected->tt_class, actual->tt_class)) + ret = MAYBE; + else + ret = FAIL; + } } if (ret == FAIL && give_msg) @@ -1161,6 +1292,201 @@ parse_type_member( return get_dict_type(member_type, type_gap); } +/* + * Parse a "func" type at "*arg" and advance over it. + * When "give_error" is TRUE give error messages, otherwise be quiet. + * Return NULL for failure. + */ + static type_T * +parse_type_func(char_u **arg, size_t len, garray_T *type_gap, int give_error) +{ + char_u *p; + type_T *type; + type_T *ret_type = &t_unknown; + int argcount = -1; + int flags = 0; + int first_optional = -1; + type_T *arg_type[MAX_FUNC_ARGS + 1]; + + // func({type}, ...{type}): {type} + *arg += len; + if (**arg == '(') + { + // "func" may or may not return a value, "func()" does + // not return a value. + ret_type = &t_void; + + p = ++*arg; + argcount = 0; + while (*p != NUL && *p != ')') + { + if (*p == '?') + { + if (first_optional == -1) + first_optional = argcount; + ++p; + } + else if (STRNCMP(p, "...", 3) == 0) + { + flags |= TTFLAG_VARARGS; + p += 3; + } + else if (first_optional != -1) + { + if (give_error) + emsg(_(e_mandatory_argument_after_optional_argument)); + return NULL; + } + + type = parse_type(&p, type_gap, give_error); + if (type == NULL) + return NULL; + if ((flags & TTFLAG_VARARGS) != 0 && type->tt_type != VAR_LIST) + { + char *tofree; + semsg(_(e_variable_arguments_type_must_be_list_str), + type_name(type, &tofree)); + vim_free(tofree); + return NULL; + } + arg_type[argcount++] = type; + + // Nothing comes after "...{type}". + if (flags & TTFLAG_VARARGS) + break; + + if (*p != ',' && *skipwhite(p) == ',') + { + if (give_error) + semsg(_(e_no_white_space_allowed_before_str_str), + ",", p); + return NULL; + } + if (*p == ',') + { + ++p; + if (!VIM_ISWHITE(*p)) + { + if (give_error) + semsg(_(e_white_space_required_after_str_str), + ",", p - 1); + return NULL; + } + } + p = skipwhite(p); + if (argcount == MAX_FUNC_ARGS) + { + if (give_error) + emsg(_(e_too_many_argument_types)); + return NULL; + } + } + + p = skipwhite(p); + if (*p != ')') + { + if (give_error) + emsg(_(e_missing_closing_paren)); + return NULL; + } + *arg = p + 1; + } + if (**arg == ':') + { + // parse return type + ++*arg; + if (!VIM_ISWHITE(**arg) && give_error) + semsg(_(e_white_space_required_after_str_str), ":", *arg - 1); + *arg = skipwhite(*arg); + ret_type = parse_type(arg, type_gap, give_error); + if (ret_type == NULL) + return NULL; + } + if (flags == 0 && first_optional == -1 && argcount <= 0) + type = get_func_type(ret_type, argcount, type_gap); + else + { + type = alloc_func_type(ret_type, argcount, type_gap); + type->tt_flags = flags; + if (argcount > 0) + { + type->tt_argcount = argcount; + type->tt_min_argcount = first_optional == -1 + ? argcount : first_optional; + if (func_type_add_arg_types(type, argcount, type_gap) == FAIL) + return NULL; + mch_memmove(type->tt_args, arg_type, sizeof(type_T *) * argcount); + } + } + + return type; +} + +/* + * Parse a user defined type at "*arg" and advance over it. + * It can be a class or an interface or a typealias name, possibly imported. + * Return NULL if a type is not found. + */ + static type_T * +parse_type_user_defined( + char_u **arg, + size_t len, + garray_T *type_gap, + int give_error) +{ + int did_emsg_before = did_emsg; + typval_T tv; + + tv.v_type = VAR_UNKNOWN; + if (eval_variable_import(*arg, &tv) == OK) + { + if (tv.v_type == VAR_CLASS && tv.vval.v_class != NULL) + { + type_T *type = get_type_ptr(type_gap); + if (type != NULL) + { + // Although the name is that of a class or interface, the type + // uses will be an object. + type->tt_type = VAR_OBJECT; + type->tt_class = tv.vval.v_class; + clear_tv(&tv); + + *arg += len; + // Skip over ".ClassName". + while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.') + ++*arg; + + return type; + } + } + else if (tv.v_type == VAR_TYPEALIAS) + { + // user defined type + type_T *type = copy_type(tv.vval.v_typealias->ta_type, type_gap); + *arg += len; + clear_tv(&tv); + // Skip over ".TypeName". + while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.') + ++*arg; + return type; + } + + clear_tv(&tv); + } + + 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; +} + /* * Parse a type at "arg" and advance over it. * When "give_error" is TRUE give error messages, otherwise be quiet. @@ -1220,130 +1546,7 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error) return &t_float; } if (len == 4 && STRNCMP(*arg, "func", len) == 0) - { - type_T *type; - type_T *ret_type = &t_unknown; - int argcount = -1; - int flags = 0; - int first_optional = -1; - type_T *arg_type[MAX_FUNC_ARGS + 1]; - - // func({type}, ...{type}): {type} - *arg += len; - if (**arg == '(') - { - // "func" may or may not return a value, "func()" does - // not return a value. - ret_type = &t_void; - - p = ++*arg; - argcount = 0; - while (*p != NUL && *p != ')') - { - if (*p == '?') - { - if (first_optional == -1) - first_optional = argcount; - ++p; - } - else if (STRNCMP(p, "...", 3) == 0) - { - flags |= TTFLAG_VARARGS; - p += 3; - } - else if (first_optional != -1) - { - if (give_error) - emsg(_(e_mandatory_argument_after_optional_argument)); - return NULL; - } - - type = parse_type(&p, type_gap, give_error); - if (type == NULL) - return NULL; - if ((flags & TTFLAG_VARARGS) != 0 - && type->tt_type != VAR_LIST) - { - char *tofree; - semsg(_(e_variable_arguments_type_must_be_list_str), - type_name(type, &tofree)); - vim_free(tofree); - return NULL; - } - arg_type[argcount++] = type; - - // Nothing comes after "...{type}". - if (flags & TTFLAG_VARARGS) - break; - - if (*p != ',' && *skipwhite(p) == ',') - { - if (give_error) - semsg(_(e_no_white_space_allowed_before_str_str), - ",", p); - return NULL; - } - if (*p == ',') - { - ++p; - if (!VIM_ISWHITE(*p)) - { - if (give_error) - semsg(_(e_white_space_required_after_str_str), - ",", p - 1); - return NULL; - } - } - p = skipwhite(p); - if (argcount == MAX_FUNC_ARGS) - { - if (give_error) - emsg(_(e_too_many_argument_types)); - return NULL; - } - } - - p = skipwhite(p); - if (*p != ')') - { - if (give_error) - emsg(_(e_missing_closing_paren)); - return NULL; - } - *arg = p + 1; - } - if (**arg == ':') - { - // parse return type - ++*arg; - if (!VIM_ISWHITE(**arg) && give_error) - semsg(_(e_white_space_required_after_str_str), - ":", *arg - 1); - *arg = skipwhite(*arg); - ret_type = parse_type(arg, type_gap, give_error); - if (ret_type == NULL) - return NULL; - } - if (flags == 0 && first_optional == -1 && argcount <= 0) - type = get_func_type(ret_type, argcount, type_gap); - else - { - type = alloc_func_type(ret_type, argcount, type_gap); - type->tt_flags = flags; - if (argcount > 0) - { - type->tt_argcount = argcount; - type->tt_min_argcount = first_optional == -1 - ? argcount : first_optional; - if (func_type_add_arg_types(type, argcount, - type_gap) == FAIL) - return NULL; - mch_memmove(type->tt_args, arg_type, - sizeof(type_T *) * argcount); - } - } - return type; - } + return parse_type_func(arg, len, type_gap, give_error); break; case 'j': if (len == 3 && STRNCMP(*arg, "job", len) == 0) @@ -1383,50 +1586,8 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error) break; } - // It can be a class or interface name, possibly imported. - int did_emsg_before = did_emsg; - typval_T tv; - - tv.v_type = VAR_UNKNOWN; - if (eval_variable_import(*arg, &tv) == OK) - { - if (tv.v_type == VAR_CLASS && tv.vval.v_class != NULL) - { - type_T *type = get_type_ptr(type_gap); - if (type != NULL) - { - // Although the name is that of a class or interface, the type - // uses will be an object. - type->tt_type = VAR_OBJECT; - type->tt_class = tv.vval.v_class; - clear_tv(&tv); - - *arg += len; - // Skip over ".ClassName". - while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.') - ++*arg; - - return type; - } - } - else if (tv.v_type == VAR_TYPEALIAS) - { - // user defined type - type_T *type = copy_type(tv.vval.v_typealias->ta_type, type_gap); - *arg += len; - clear_tv(&tv); - // Skip over ".TypeName". - while (ASCII_ISALNUM(**arg) || **arg == '_' || **arg == '.') - ++*arg; - return type; - } - - clear_tv(&tv); - } - - if (give_error && (did_emsg == did_emsg_before)) - semsg(_(e_type_not_recognized_str), *arg); - return NULL; + // User defined type + return parse_type_user_defined(arg, len, type_gap, give_error); } /* @@ -1482,6 +1643,60 @@ equal_type(type_T *type1, type_T *type2, int flags) return TRUE; } +/* + * Find the common type of "type1" (VAR_FUNC) and "type2" (VAR_FUNC) and put it + * in "dest". "type2" and "dest" may be the same. + */ + static void +common_type_var_func( + type_T *type1, + type_T *type2, + type_T **dest, + garray_T *type_gap) +{ + type_T *common; + + // When one of the types is t_func_unknown return the other one. + // Useful if a list or dict item is null_func. + if (type1 == &t_func_unknown) + { + *dest = type2; + return; + } + if (type2 == &t_func_unknown) + { + *dest = type1; + return; + } + + common_type(type1->tt_member, type2->tt_member, &common, type_gap); + if (type1->tt_argcount == type2->tt_argcount + && type1->tt_argcount >= 0) + { + int argcount = type1->tt_argcount; + int i; + + *dest = alloc_func_type(common, argcount, type_gap); + if (type1->tt_args != NULL && type2->tt_args != NULL) + { + if (func_type_add_arg_types(*dest, argcount, + type_gap) == OK) + for (i = 0; i < argcount; ++i) + common_type(type1->tt_args[i], type2->tt_args[i], + &(*dest)->tt_args[i], type_gap); + } + } + else + // Use -1 for "tt_argcount" to indicate an unknown number of + // arguments. + *dest = alloc_func_type(common, -1, type_gap); + + // Use the minimum of min_argcount. + (*dest)->tt_min_argcount = + type1->tt_min_argcount < type2->tt_min_argcount + ? type1->tt_min_argcount : type2->tt_min_argcount; +} + /* * Find the common type of "type1" and "type2" and put it in "dest". * "type2" and "dest" may be the same. @@ -1521,49 +1736,10 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap) *dest = get_dict_type(common, type_gap); return; } + if (type1->tt_type == VAR_FUNC) { - type_T *common; - - // When one of the types is t_func_unknown return the other one. - // Useful if a list or dict item is null_func. - if (type1 == &t_func_unknown) - { - *dest = type2; - return; - } - if (type2 == &t_func_unknown) - { - *dest = type1; - return; - } - - common_type(type1->tt_member, type2->tt_member, &common, type_gap); - if (type1->tt_argcount == type2->tt_argcount - && type1->tt_argcount >= 0) - { - int argcount = type1->tt_argcount; - int i; - - *dest = alloc_func_type(common, argcount, type_gap); - if (type1->tt_args != NULL && type2->tt_args != NULL) - { - if (func_type_add_arg_types(*dest, argcount, - type_gap) == OK) - for (i = 0; i < argcount; ++i) - common_type(type1->tt_args[i], type2->tt_args[i], - &(*dest)->tt_args[i], type_gap); - } - } - else - // Use -1 for "tt_argcount" to indicate an unknown number of - // arguments. - *dest = alloc_func_type(common, -1, type_gap); - - // Use the minimum of min_argcount. - (*dest)->tt_min_argcount = - type1->tt_min_argcount < type2->tt_min_argcount - ? type1->tt_min_argcount : type2->tt_min_argcount; + common_type_var_func(type1, type2, dest, type_gap); return; } } @@ -1718,120 +1894,156 @@ vartype_name(vartype_T type) } /* - * Return the name of a type. + * Return the type name of a List (list<type>) or Dict (dict<type>). * The result may be in allocated memory, in which case "tofree" is set. */ - char * -type_name(type_T *type, char **tofree) + static char * +type_name_list_or_dict(char *name, type_T *type, char **tofree) { - char *name; - char *arg_free = NULL; + char *member_free; + char *member_name; - *tofree = NULL; - if (type == NULL) - return "[unknown]"; - name = vartype_name(type->tt_type); + if (type->tt_member->tt_type == VAR_UNKNOWN) + member_name = type_name(&t_any, &member_free); + else + member_name = type_name(type->tt_member, &member_free); + + size_t len = STRLEN(name) + STRLEN(member_name) + 3; + *tofree = alloc(len); + if (*tofree == NULL) + return name; + + vim_snprintf(*tofree, len, "%s<%s>", name, member_name); + vim_free(member_free); + return *tofree; +} - if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT) +/* + * Return the type name of a Class (class<name>) or Object (object<name>). + * The result may be in allocated memory, in which case "tofree" is set. + */ + static char * +type_name_class_or_obj(char *name, type_T *type, char **tofree) +{ + char_u *class_name; + + if (type->tt_class != NULL) { - char *member_free; - char *member_name; - if (type->tt_member->tt_type == VAR_UNKNOWN) - member_name = type_name(&t_any, &member_free); - else - member_name = type_name(type->tt_member, &member_free); - size_t len = STRLEN(name) + STRLEN(member_name) + 3; - *tofree = alloc(len); - if (*tofree != NULL) - { - vim_snprintf(*tofree, len, "%s<%s>", name, member_name); - vim_free(member_free); - return *tofree; - } + class_name = type->tt_class->class_name; + if (IS_ENUM(type->tt_class)) + name = "enum"; } + else + class_name = (char_u *)"Unknown"; + + size_t len = STRLEN(name) + STRLEN(class_name) + 3; + *tofree = alloc(len); + if (*tofree == NULL) + return name; + + vim_snprintf(*tofree, len, "%s<%s>", name, class_name); + return *tofree; +} + +/* + * Return the type name of a function. + * The result may be in allocated memory, in which case "tofree" is set. + */ + static char * +type_name_func(type_T *type, char **tofree) +{ + garray_T ga; + int i; + int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0; + char *arg_free = NULL; + + ga_init2(&ga, 1, 100); + if (ga_grow(&ga, 20) == FAIL) + goto failed; + STRCPY(ga.ga_data, "func("); + ga.ga_len += 5; - if (type->tt_type == VAR_OBJECT || type->tt_type == VAR_CLASS) + for (i = 0; i < type->tt_argcount; ++i) { - char_u *class_name; - if (type->tt_class != NULL) - { - class_name = type->tt_class->class_name; - if (IS_ENUM(type->tt_class)) - name = "enum"; - } + char *arg_type; + int len; + + if (type->tt_args == NULL) + arg_type = "[unknown]"; else - class_name = (char_u *)"Unknown"; - size_t len = STRLEN(name) + STRLEN(class_name) + 3; - *tofree = alloc(len); - if (*tofree != NULL) + arg_type = type_name(type->tt_args[i], &arg_free); + if (i > 0) { - vim_snprintf(*tofree, len, "%s<%s>", name, class_name); - return *tofree; + STRCPY((char *)ga.ga_data + ga.ga_len, ", "); + ga.ga_len += 2; } + len = (int)STRLEN(arg_type); + if (ga_grow(&ga, len + 8) == FAIL) + goto failed; + if (varargs && i == type->tt_argcount - 1) + ga_concat(&ga, (char_u *)"..."); + else if (i >= type->tt_min_argcount) + *((char *)ga.ga_data + ga.ga_len++) = '?'; + ga_concat(&ga, (char_u *)arg_type); + VIM_CLEAR(arg_free); } + if (type->tt_argcount < 0) + // any number of arguments + ga_concat(&ga, (char_u *)"..."); - if (type->tt_type == VAR_FUNC) + if (type->tt_member == &t_void) + STRCPY((char *)ga.ga_data + ga.ga_len, ")"); + else { - garray_T ga; - int i; - int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0; + char *ret_free; + char *ret_name = type_name(type->tt_member, &ret_free); + int len; - ga_init2(&ga, 1, 100); - if (ga_grow(&ga, 20) == FAIL) + len = (int)STRLEN(ret_name) + 4; + if (ga_grow(&ga, len) == FAIL) goto failed; - STRCPY(ga.ga_data, "func("); - ga.ga_len += 5; - - for (i = 0; i < type->tt_argcount; ++i) - { - char *arg_type; - int len; + STRCPY((char *)ga.ga_data + ga.ga_len, "): "); + STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name); + vim_free(ret_free); + } + *tofree = ga.ga_data; + return ga.ga_data; - if (type->tt_args == NULL) - arg_type = "[unknown]"; - else - arg_type = type_name(type->tt_args[i], &arg_free); - if (i > 0) - { - STRCPY((char *)ga.ga_data + ga.ga_len, ", "); - ga.ga_len += 2; - } - len = (int)STRLEN(arg_type); - if (ga_grow(&ga, len + 8) == FAIL) - goto failed; - if (varargs && i == type->tt_argcount - 1) - ga_concat(&ga, (char_u *)"..."); - else if (i >= type->tt_min_argcount) - *((char *)ga.ga_data + ga.ga_len++) = '?'; - ga_concat(&ga, (char_u *)arg_type); - VIM_CLEAR(arg_free); - } - if (type->tt_argcount < 0) - // any number of arguments - ga_concat(&ga, (char_u *)"..."); +failed: + vim_free(arg_free); + ga_clear(&ga); + return "[unknown]"; +} - if (type->tt_member == &t_void) - STRCPY((char *)ga.ga_data + ga.ga_len, ")"); - else - { - char *ret_free; - char *ret_name = type_name(type->tt_member, &ret_free); - int len; - - len = (int)STRLEN(ret_name) + 4; - if (ga_grow(&ga, len) == FAIL) - goto failed; - STRCPY((char *)ga.ga_data + ga.ga_len, "): "); - STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name); - vim_free(ret_free); - } - *tofree = ga.ga_data; - return ga.ga_data; +/* + * Return the name of a type. + * The result may be in allocated memory, in which case "tofree" is set. + */ + char * +type_name(type_T *type, char **tofree) +{ + char *name; -failed: - vim_free(arg_free); - ga_clear(&ga); + *tofree = NULL; + if (type == NULL) return "[unknown]"; + name = vartype_name(type->tt_type); + + switch (type->tt_type) + { + case VAR_LIST: + case VAR_DICT: + return type_name_list_or_dict(name, type, tofree); + + case VAR_CLASS: + case VAR_OBJECT: + return type_name_class_or_obj(name, type, tofree); + + case VAR_FUNC: + return type_name_func(type, tofree); + + default: + break; } return name; @@ -1895,10 +2107,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/window.c b/src/window.c index 7d78b5f29a..db0bb1b628 100644 --- a/src/window.c +++ b/src/window.c @@ -2475,6 +2475,7 @@ win_init_empty(win_T *wp) wp->w_topfill = 0; #endif wp->w_botline = 2; + wp->w_valid = 0; #if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) wp->w_s = &wp->w_buffer->b_s; #endif @@ -3781,15 +3782,24 @@ win_altframe( static tabpage_T * alt_tabpage(void) { - tabpage_T *tp; + tabpage_T *tp = NULL; + int forward; - // Use the next tab page if possible. - if (curtab->tp_next != NULL) - return curtab->tp_next; + // Use the last accessed tab page, if possible. + if ((tcl_flags & TCL_USELAST) && valid_tabpage(lastused_tabpage)) + return lastused_tabpage; + + // Use the next tab page, if possible. + forward = curtab->tp_next != NULL && + ((tcl_flags & TCL_LEFT) == 0 || curtab == first_tabpage); + + if (forward) + tp = curtab->tp_next; + else + // Use the previous tab page. + for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) + ; - // Find the last but one tab page. - for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) - ; return tp; } diff --git a/src/xxd/Make_mvc.mak b/src/xxd/Make_mvc.mak index 0133d73115..2361ab3d54 100644 --- a/src/xxd/Make_mvc.mak +++ b/src/xxd/Make_mvc.mak @@ -9,7 +9,7 @@ SUBSYSTEM = $(SUBSYSTEM),$(SUBSYSTEM_VER) xxd: xxd.exe xxd.exe: xxd.c - cl /nologo -DWIN32 xxd.c -link -subsystem:$(SUBSYSTEM) + cl /nologo /source-charset:utf-8 -DWIN32 xxd.c -link -subsystem:$(SUBSYSTEM) # This was for an older compiler # cl /nologo -DWIN32 xxd.c /link setargv.obj diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c index cf8b4ea6a0..7a3d36a7fe 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;