diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 35da109210..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,52 +0,0 @@ -version: "{build}" - -image: Visual Studio 2015 - -skip_tags: true - -environment: - matrix: - - FEATURE: HUGE - - # Alternate environments, not used right now. 2022 is a lot slower. - # - # - job_name: VS-2015 - # appveyor_build_worker_image: Visual Studio 2015 - # FEATURE: HUGE - - # - job_name: VS-2017 - # appveyor_build_worker_image: Visual Studio 2017 - # FEATURE: HUGE - - # - job_name: VS-2019 - # appveyor_build_worker_image: Visual Studio 2019 - # FEATURE: HUGE - - # - job_name: VS-2022 - # appveyor_build_worker_image: Visual Studio 2022 - # FEATURE: HUGE - -# disabled -# - FEATURE: TINY -# - FEATURE: NORMAL - -matrix: - fast_finish: true - -before_build: - - call ver - - ci\appveyor.bat install - -build_script: - - ci\appveyor.bat build - -test_script: - - ci\appveyor.bat test - -artifacts: - - path: src/vim.exe - name: vim - - path: src/gvim.exe - name: gvim - -# vim: sw=2 sts=2 et ts=8 sr diff --git a/.github/MAINTAINERS b/.github/MAINTAINERS index 17458f2d26..fb7ebddf0c 100644 --- a/.github/MAINTAINERS +++ b/.github/MAINTAINERS @@ -18,6 +18,7 @@ runtime/autoload/javascriptcomplete.vim @jsit runtime/autoload/modula2.vim @dkearns runtime/autoload/rubycomplete.vim @segfault @dkearns runtime/autoload/rust.vim @lilyball +runtime/autoload/tohtml.vim @fritzophrenic runtime/autoload/typeset.vim @lifepillar runtime/autoload/xmlformat.vim @chrisbra runtime/autoload/dist/json.vim @habamax @@ -133,6 +134,7 @@ runtime/doc/xxd-ru.1 @RestorerZ runtime/doc/xxd-ru.UTF-8.1 @RestorerZ runtime/ftplugin/abaqus.vim @costerwi runtime/ftplugin/abnf.vim @A4-Tacks +runtime/ftplugin/algol68.vim @dkearns runtime/ftplugin/antlr4.vim @jiangyinzuo runtime/ftplugin/apache.vim @dubgeiser runtime/ftplugin/arduino.vim @k-takata @@ -338,6 +340,7 @@ runtime/ftplugin/thrift.vim @jiangyinzuo runtime/ftplugin/tiasm.vim @Freed-Wu runtime/ftplugin/tidy.vim @dkearns runtime/ftplugin/tmux.vim @ericpruitt +runtime/ftplugin/tolk.vim @redavy runtime/ftplugin/toml.vim @averms runtime/ftplugin/tt2html.vim @petdance runtime/ftplugin/twig.vim @ribru17 @@ -402,6 +405,7 @@ runtime/indent/json.vim @elzr runtime/indent/jsonc.vim @izhakjakov runtime/indent/julia.vim @carlobaldassi runtime/indent/just.vim @pbnj +runtime/indent/karel.vim @KnoP-01 runtime/indent/kdl.vim @imsnif @jiangyinzuo runtime/indent/kotlin.vim @udalov runtime/indent/krl.vim @KnoP-01 @@ -468,10 +472,12 @@ runtime/pack/dist/opt/helptoc/ @kennypete runtime/pack/dist/opt/matchit/ @chrisbra runtime/pack/dist/opt/nohlsearch/ @habamax runtime/plugin/manpager.vim @Konfekt -runtime/syntax/shared/hgcommitDiff.vim @vegerot +runtime/plugin/tohtml.vim @fritzophrenic +runtime/syntax/2html.vim @fritzophrenic runtime/syntax/abaqus.vim @costerwi runtime/syntax/abnf.vim @A4-Tacks runtime/syntax/aidl.vim @dpelle +runtime/syntax/algol68.vim @dkearns runtime/syntax/amiga.vim @sodero runtime/syntax/ant.vim @dkearns runtime/syntax/antlr4.vim @jiangyinzuo @@ -578,17 +584,17 @@ runtime/syntax/java.vim @zzzyxwvut runtime/syntax/javascript.vim @fleiner runtime/syntax/jinja.vim @gpanders runtime/syntax/jjdescription.vim @gpanders +runtime/syntax/jq.vim @vito-c runtime/syntax/json.vim @vito-c runtime/syntax/jsonc.vim @izhakjakov runtime/syntax/julia.vim @carlobaldassi runtime/syntax/just.vim @pbnj -runtime/syntax/jq.vim @vito-c runtime/syntax/karel.vim @kirillmorozov runtime/syntax/kconfig.vim @chrisbra +runtime/syntax/kdl.vim @imsnif @jiangyinzuo runtime/syntax/kitty.vim @OXY2DEV runtime/syntax/kivy.vim @prophittcorey runtime/syntax/kotlin.vim @udalov -runtime/syntax/kdl.vim @imsnif @jiangyinzuo runtime/syntax/krl.vim @KnoP-01 runtime/syntax/leex.vim @jparise runtime/syntax/less.vim @genoma @@ -605,8 +611,8 @@ runtime/syntax/m3quake.vim @dkearns runtime/syntax/mailcap.vim @dkearns runtime/syntax/mallard.vim @jhradilek runtime/syntax/markdown.vim @tpope -runtime/syntax/mbsync.vim @fymyte runtime/syntax/mason.vim @petdance +runtime/syntax/mbsync.vim @fymyte runtime/syntax/mediawiki.vim @avidseeker runtime/syntax/meson.vim @Liambeguin runtime/syntax/mf.vim @lifepillar @@ -655,8 +661,8 @@ runtime/syntax/qml.vim @ChaseKnowlden 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/ratpoison.vim @trapd00r runtime/syntax/rc.vim @chrisbra runtime/syntax/rcs.vim @hdima runtime/syntax/rebol.vim @mrdubya @@ -672,8 +678,10 @@ runtime/syntax/scala.vim @derekwyatt runtime/syntax/scheme.vim @evhan runtime/syntax/scss.vim @tpope runtime/syntax/sed.vim @dkearns -runtime/syntax/shared/debversions.vim @jamessan +runtime/syntax/sgf.vim @lykahb runtime/syntax/shaderslang.vim @mTvare6 +runtime/syntax/shared/debversions.vim @jamessan +runtime/syntax/shared/hgcommitDiff.vim @vegerot runtime/syntax/skhd.vim @kiyoon runtime/syntax/solidity.vim @coti-z runtime/syntax/spajson.vim @dseomn @@ -698,6 +706,7 @@ runtime/syntax/thrift.vim @jiangyinzuo runtime/syntax/tiasm.vim @Freed-Wu runtime/syntax/tidy.vim @dkearns runtime/syntax/tmux.vim @ericpruitt +runtime/syntax/tolk.vim @redavy runtime/syntax/toml.vim @averms runtime/syntax/tt2.vim @petdance runtime/syntax/tt2html.vim @petdance diff --git a/.github/actions/build_vim_on_linux/action.yml b/.github/actions/build_vim_on_linux/action.yml new file mode 100644 index 0000000000..c6486cd34f --- /dev/null +++ b/.github/actions/build_vim_on_linux/action.yml @@ -0,0 +1,325 @@ +name: Build Vim on Linux +description: Build Vim on Linux + +inputs: + features: + description: Vim features + required: true + compiler: + description: Compiler + required: true + architecture: + description: Architecture + required: false + extra: + description: Extra flags + required: true + shadow: + description: Shadow directory + required: false + interface: + description: Interface of language interpreter + required: false + lua_ver: + description: Lua version + required: false + python3: + description: Python3 ABI type + required: false + coverage: + description: Enable coverage + required: false + +runs: + using: "composite" + steps: + - name: Check Filelist (for packaging) + shell: bash + run: | + echo '::group::Check Filelist (for packaging)' + # If any files in the repository are not listed in Filelist this will + # exit with an error code and list the missing entries. + make -f ci/unlisted.make + echo '::endgroup::' + + - name: Check hlgroups (are any new hlgroups added, but not handled in highlight.c) + shell: bash + run: | + echo '::group::Check hlgroups (are any new hlgroups added, but not handled in highlight.c)' + # If any highlight groups have been documented, but not handled in + # highlight.c, nor listed as 'intentionally left out' in hlgroups.ignore, + # exit with an error code and list the missing entries. + make -C ci -f hlgroups.make + echo '::endgroup::' + + - name: Report executable syntax tests + if: contains(fromJSON(inputs.extra), 'syn_test_execs') + shell: bash + run: | + echo '::group::Report executable syntax tests' + # Search and list all found executable syntax tests, and exit with + # an error code. + make -C runtime/syntax executables + echo '::endgroup::' + + - name: Add i386 packages to dpkg + if: inputs.architecture == 'i386' + shell: bash + run: | + echo '::group::Add i386 packages to dpkg' + sudo dpkg --add-architecture i386 + echo '::endgroup::' + + - name: Uninstall snap + shell: bash + run: | + echo '::group::Uninstall snap' + sudo bash ci/remove_snap.sh + echo '::endgroup::' + + - name: Enable debug packages + shell: bash + run: | + echo '::group::Enable debug packages' + # Some of the ASAN suppressions are in libraries linked with dlopen + # and symbolization of them requires these debug packages. + sudo apt install ubuntu-dbgsym-keyring + sudo cp ci/ddebs.list /etc/apt/sources.list.d/ddebs.list + sudo cp ci/pinned-pkgs /etc/apt/preferences.d/pinned-pkgs + echo '::endgroup::' + + # TODO: switch to GTK4 GUI + - name: Install packages + shell: bash + run: | + echo '::group::Install packages' + # This is added by default, and it is often broken, but we don't need anything from it + sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list + PKGS=( \ + gettext \ + x11-utils \ + labwc \ + wl-clipboard \ + wayland-utils \ + libgtk-3-dev:${{ inputs.architecture }} \ + libgtk-3-bin:${{ inputs.architecture }} \ + desktop-file-utils \ + libc6-dbgsym:${{ inputs.architecture }} \ + libtool-bin \ + libncurses-dev:${{ inputs.architecture }} \ + libxt-dev:${{ inputs.architecture }} \ + libegl-mesa0:${{ inputs.architecture }} \ + libegl1:${{ inputs.architecture }} \ + libegl1-mesa-dev:${{ inputs.architecture }} \ + libepoxy-dev:${{ inputs.architecture }} \ + libwayland-egl1:${{ inputs.architecture }} \ + libwayland-client0:${{ inputs.architecture }} \ + libwayland-cursor0:${{ inputs.architecture }} \ + locales-all \ + software-properties-common \ + ) + if ${{ contains(fromJSON(inputs.extra), 'asan') }} && ${{ contains(inputs.architecture, 'native') }}; then + PKGS+=( \ + libepoxy0-dbgsym:${{ inputs.architecture }} \ + libxdamage1-dbgsym:${{ inputs.architecture }} \ + libxcb1-dbgsym:${{ inputs.architecture }} \ + libgtk-3-bin-dbgsym:${{ inputs.architecture }} \ + libgtk-3-0t64-dbgsym:${{ inputs.architecture }} \ + libglib2.0-0t64-dbgsym:${{ inputs.architecture }} \ + libglib2.0-bin-dbgsym:${{ inputs.architecture }} \ + libglib2.0-dev-bin-dbgsym:${{ inputs.architecture }} \ + ) + fi + if ${{ inputs.features == 'huge' }}; then + LUA_VER=${{ inputs.lua_ver || '5.4' }} + PKGS+=( \ + autoconf \ + gdb \ + lcov \ + libcanberra-dev \ + libperl-dev \ + python3-dev \ + liblua${LUA_VER}-dev \ + lua${LUA_VER} \ + ruby-dev \ + tcl-dev \ + cscope \ + libsodium-dev \ + attr \ + libattr1-dev + ) + fi + if ${{ contains(fromJSON(inputs.extra), 'proto') }}; then + PKGS+=( python3-clang ) + fi + sudo apt-get update && sudo apt-get upgrade -y --allow-downgrades && sudo apt-get install -y --allow-downgrades "${PKGS[@]}" + + - name: Install gcc-${{ env.GCC_VER }} + if: inputs.compiler == 'gcc' + shell: bash + run: | + echo '::group::Install gcc-${{ env.GCC_VER }}' + # ubuntu-toolchain-r/test PPA for gcc-13 compiler + # disabled because the installation failed, causing test failures + # sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + sudo apt-get update -y + sudo apt-get install -y gcc-${{ env.GCC_VER }}:${{ inputs.architecture }} + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ env.GCC_VER }} 100 + sudo update-alternatives --set gcc /usr/bin/gcc-${{ env.GCC_VER }} + echo '::endgroup::' + + - name: Install clang-${{ env.CLANG_VER }} + if: inputs.compiler == 'clang' + shell: bash + run: | + echo '::group::Install clang-${{ env.CLANG_VER }}' + . /etc/lsb-release + curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/llvm-archive-keyring.gpg > /dev/null + echo "Types: deb + URIs: https://apt.llvm.org/${DISTRIB_CODENAME}/ + Suites: llvm-toolchain-${DISTRIB_CODENAME}-${{ env.CLANG_VER }} + Components: main + Signed-By: /usr/share/keyrings/llvm-archive-keyring.gpg" | sudo tee /etc/apt/sources.list.d/llvm-toolchain.sources > /dev/null + sudo apt-get update -y + sudo apt-get install -y clang-${{ env.CLANG_VER }} llvm-${{ env.CLANG_VER }} + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${{ env.CLANG_VER }} 100 + sudo update-alternatives --set clang /usr/bin/clang-${{ env.CLANG_VER }} + sudo update-alternatives --install /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-${{ env.CLANG_VER }} 100 + sudo update-alternatives --install /usr/bin/asan_symbolize asan_symbolize /usr/bin/asan_symbolize-${{ env.CLANG_VER }} 100 + echo '::endgroup::' + + - name: Set up environment + shell: bash + run: | + echo '::group::Set up environment' + mkdir -p "${LOG_DIR}" + mkdir -p "${HOME}/bin" + echo "${HOME}/bin" >> $GITHUB_PATH + ( + echo "LINUX_VERSION=$(uname -r)" + echo "NPROC=$(getconf _NPROCESSORS_ONLN)" + echo "TMPDIR=$(mktemp -d -p /tmp)" + + case "${{ inputs.features }}" in + tiny) + echo "TEST=testtiny" + if ${{ contains(fromJSON(inputs.extra), 'nogui') }}; then + CONFOPT="--disable-gui" + fi + ;; + normal) + ;; + huge) + echo "TEST=scripttests test_libvterm indenttest syntaxtest" + INTERFACE=${{ inputs.interface || 'yes' }} + if ${{ inputs.python3 == 'stable-abi' }}; then + PYTHON3_CONFOPT="--with-python3-stable-abi=3.8" + fi + # The ubuntu-24.04 CI runner does not provide a python2 package. + CONFOPT="--enable-perlinterp=${INTERFACE} --enable-pythoninterp=no --enable-python3interp=${INTERFACE} --enable-rubyinterp=${INTERFACE} --enable-luainterp=${INTERFACE} --enable-tclinterp=${INTERFACE} ${PYTHON3_CONFOPT}" + ;; + esac + + if ${{ contains(fromJSON(inputs.extra), 'no_x11_wl') }}; then + CONFOPT="${CONFOPT} --without-x --disable-gui --without-wayland --enable-socketserver" + fi + if ${{ inputs.coverage == true }}; then + CFLAGS="${CFLAGS} --coverage -DUSE_GCOV_FLUSH" + echo "LDFLAGS=--coverage" + fi + if ${{ contains(fromJSON(inputs.extra), 'uchar') }}; then + CFLAGS="${CFLAGS} -funsigned-char" + fi + if ${{ contains(fromJSON(inputs.extra), 'testgui') }}; then + echo "TEST=-C src testgui" + fi + if ${{ contains(fromJSON(inputs.extra), 'unittests') }}; then + echo "TEST=unittests" + fi + if ${{ contains(fromJSON(inputs.extra), 'asan') }}; then + echo "SANITIZER_CFLAGS=-g -O0 -DABORT_ON_INTERNAL_ERROR -DEXITFREE -fsanitize-recover=all -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" + echo "ASAN_OPTIONS=print_stacktrace=1:log_path=${LOG_DIR}/asan" + echo "UBSAN_OPTIONS=print_stacktrace=1:log_path=${LOG_DIR}/ubsan" + echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/src/testdir/lsan-suppress.txt" + fi + if ${{ contains(fromJSON(inputs.extra), 'vimtags') }}; then + echo "TEST=-C runtime/doc vimtags VIMEXE=../../${SRCDIR}/vim" + fi + if ${{ contains(fromJSON(inputs.extra), 'proto') }}; then + echo "TEST=-C src protoclean proto" + fi + echo "CFLAGS=${CFLAGS}" + echo "CONFOPT=${CONFOPT}" + # Disables GTK attempt to integrate with the accessibility service that does run in CI. + echo "NO_AT_BRIDGE=1" + ) >> $GITHUB_ENV + echo '::endgroup::' + + - name: Set up system + shell: bash + run: | + echo '::group::Set up system' + if [[ ${CC} = clang ]]; then + # Use llvm-cov instead of gcov when compiler is clang. + ln -fs /usr/bin/llvm-cov ${HOME}/bin/gcov + fi + sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0 + sudo usermod -a -G audio "${USER}" + sudo bash ci/setup-xvfb.sh + echo '::endgroup::' + + - name: Check autoconf + if: contains(fromJSON(inputs.extra), 'unittests') + shell: bash + run: | + echo '::group::Check autoconf' + make -C src autoconf + echo '::endgroup::' + + - name: Set up shadow dir + if: inputs.shadow + shell: bash + run: | + echo '::group::Set up shadow dir' + make -C src shadow + echo "SRCDIR=${{ inputs.shadow }}" >> $GITHUB_ENV + echo "SHADOWOPT=-C ${{ inputs.shadow }}" >> $GITHUB_ENV + echo '::endgroup::' + + - name: Configure + shell: bash + run: | + echo '::group::Configure' + ./configure --with-features=${{ inputs.features }} ${CONFOPT} --enable-fail-if-missing + # Append various warning flags to CFLAGS. + sed -i -f ci/config.mk.sed ${SRCDIR}/auto/config.mk + sed -i -f ci/config.mk.${CC}.sed ${SRCDIR}/auto/config.mk + if [[ ${CC} = clang ]]; then + # Suppress some warnings produced by clang 12 and later. + sed -i -f ci/config.mk.clang-12.sed ${SRCDIR}/auto/config.mk + fi + echo '::endgroup::' + + - name: Build + if: (!contains(fromJSON(inputs.extra), 'unittests')) + shell: bash + run: | + echo '::group::Build' + make ${SHADOWOPT} -j${NPROC} + echo '::endgroup::' + + - name: Check version + if: (!contains(fromJSON(inputs.extra), 'unittests')) + shell: bash + run: | + echo '::group::Check version' + "${SRCDIR}"/vim --version + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit + if ${{ inputs.features == 'huge' }}; then + # Also check that optional and dynamic features are configured and working + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 \ + -c "let g:required=['gettext', 'sodium', 'sound', 'perl', 'python3', 'lua', 'ruby', 'tcl']" \ + -S ci/if_feat_check.vim -c quit + fi + echo '::endgroup::' diff --git a/.github/actions/test_artifacts/action.yml b/.github/actions/test_artifacts/action.yml index 0de95609c2..17065f7532 100644 --- a/.github/actions/test_artifacts/action.yml +++ b/.github/actions/test_artifacts/action.yml @@ -1,4 +1,4 @@ -name: 'test_artifacts' +name: "test_artifacts" description: "Upload failed test artifacts" inputs: artifact-name: @@ -14,7 +14,7 @@ runs: # it from the matrix automatically like in Vim # upstream. # - name: Collect matrix properties for naming -# uses: actions/github-script@v8 +# uses: actions/github-script@v9 # id: matrix-props # env: # MATRIX_PROPS: ${{ toJSON(inputs) }} @@ -50,9 +50,10 @@ runs: # A file, directory or wildcard pattern that describes what # to upload. path: | - ${{ github.workspace }}/runtime/indent/testdir/*.fail - ${{ github.workspace }}/runtime/syntax/testdir/failed/* - ${{ github.workspace }}/src/testdir/failed/* + ${{ github.workspace }}/logs/**/*.symbolized + ${{ github.workspace }}/runtime/indent/testdir/*.fail + ${{ 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 diff --git a/.github/labeler.yml b/.github/labeler.yml index 720765d383..157f791e70 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -8,7 +8,6 @@ CI: - '.github/dependabot.yml' - '.github/labeler.yml' - '.github/workflows/*' - - '.appveyor.yml' - '.codecov.yml' documentation: diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml new file mode 100644 index 0000000000..987fcecc8b --- /dev/null +++ b/.github/workflows/ci-linux.yml @@ -0,0 +1,176 @@ +name: CI for Linux + +on: + workflow_call: + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for + # pull requests or the commit hash for any other events. + group: ${{ github.workflow }}-linux-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + linux: + runs-on: ${{ matrix.architecture == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} + + env: + CC: ${{ matrix.compiler }} + GCC_VER: 14 + CLANG_VER: 22 + TEST: test + SRCDIR: ./src + LEAK_CFLAGS: -DEXITFREE + LOG_DIR: ${{ github.workspace }}/logs + TERM: xterm + DISPLAY: ":99" + DEBIAN_FRONTEND: noninteractive + + strategy: + fail-fast: false + matrix: + features: [tiny, normal, huge] + compiler: [clang, gcc] + extra: [[]] + # Only use non-native architecture when features != huge. + # features=huge tries to install python3-dev, which fails to install + # for the non-native architecture. + architecture: [native] + include: + - features: tiny + compiler: clang + extra: [nogui] + - features: tiny + compiler: gcc + extra: [nogui, syn_test_execs] + - features: tiny + compiler: gcc + extra: [nogui] + architecture: arm64 + - features: normal + shadow: ./src/shadow + compiler: gcc + architecture: i386 + - features: huge + coverage: true + - features: huge + compiler: clang + interface: dynamic + python3: stable-abi + - features: huge + compiler: gcc + coverage: true + interface: dynamic + extra: [uchar, testgui] + - features: huge + compiler: gcc + coverage: true + extra: [unittests] + - features: huge + compiler: gcc + coverage: true + extra: [unittests] + architecture: arm64 + - features: normal + compiler: gcc + extra: [vimtags, proto, preproc_indent, encoding, codestyle] + - features: huge + compiler: gcc + extra: [no_x11_wl] + + steps: + - name: Checkout repository from GitHub + uses: actions/checkout@v6 + + - name: Build + timeout-minutes: 15 + uses: ./.github/actions/build_vim_on_linux + with: + features: ${{ matrix.features }} + compiler: ${{ matrix.compiler }} + architecture: ${{ matrix.architecture }} + extra: ${{ toJSON(matrix.extra) }} + shadow: ${{ matrix.shadow }} + interface: ${{ matrix.interface }} + lua_ver: ${{ matrix.lua_ver }} + python3: ${{ matrix.python3 }} + coverage: ${{ matrix.coverage }} + + - name: Test + timeout-minutes: 20 + run: make ${SHADOWOPT} ${TEST} + + # Enable to debug failing tests live and ssh into the CI runners + # - name: Setup tmate session + # if: ${{ failure() }} + # uses: mxschmitt/action-tmate@v3 + # with: + # limit-access-to-actor: true + + - name: Upload failed test artifacts + if: ${{ !cancelled() }} + uses: ./.github/actions/test_artifacts + + - name: Vim tags + if: contains(matrix.extra, 'vimtags') + run: | + # This will exit with an error code if the generated vim tags differs from source. + ( + cd runtime/doc + git diff --exit-code -- tags + make html; rm *.html tags.ref; + test -f errors.log && exit 3; + true + ) + + - name: Generate Proto files + if: contains(matrix.extra, 'proto') + run: | + # This will exit with an error code if the generated proto files differ from source + ( + git diff --exit-code -- src/proto/ + true + ) + + - name: Check Source Code style + if: contains(matrix.extra, 'codestyle') + run: | + make -C src/testdir codestyle + + - name: Check preprocessor indent + if: contains(matrix.extra, 'preproc_indent') + run: | + # This will exit with an error code if the files differ from source + ( + "${SRCDIR}"/vim -u NONE --not-a-term -esNX +"cd runtime/tools" -S preproc_indent.vim + git diff --exit-code -- src/*.[ch] src/xxd/xxd.c + true + ) + + - name: Check encoding of utf-8 runtime files + if: contains(matrix.extra, 'encoding') + run: | + # This will exit with an error code if utf-8 runtime files are not in utf-8 encoding + ( + find . -type f -name "*utf-8*.vim" -exec sh -c \ + 'iconv -f utf-8 -t utf-8 "$1" >/dev/null 2>&1 || echo "non utf-8 encoding detected in $1"' \ + find-sh {} \; |grep "non utf-8 encoding" && exit 3 + true + ) + + - name: Generate gcov files + if: matrix.coverage + run: | + cd "${SRCDIR}" + find . -type f -name '*.gcno' -exec gcov -pb {} + || true + + - name: Codecov + timeout-minutes: 20 + if: matrix.coverage + uses: codecov/codecov-action@v6 + with: + flags: linux,${{ matrix.features }}-${{ matrix.compiler }}-${{ join(matrix.extra, '-') }} + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/ci-linux_asan.yml b/.github/workflows/ci-linux_asan.yml new file mode 100644 index 0000000000..daa1e25937 --- /dev/null +++ b/.github/workflows/ci-linux_asan.yml @@ -0,0 +1,82 @@ +name: CI for Linux ASan + +on: + workflow_call: + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for + # pull requests or the commit hash for any other events. + group: ${{ github.workflow }}-linux_asan-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + linux-asan: + runs-on: ubuntu-24.04 + + env: + CC: clang + CLANG_VER: 21 + SRCDIR: ./src + LEAK_CFLAGS: -DEXITFREE + LOG_DIR: ${{ github.workspace }}/logs + TERM: xterm + DISPLAY: ":99" + DEBIAN_FRONTEND: noninteractive + + strategy: + fail-fast: false + matrix: + testset: + - tinytests + - newtests.1 + - newtests.2 + + steps: + - name: Checkout repository from GitHub + uses: actions/checkout@v6 + + - name: Build + timeout-minutes: 15 + uses: ./.github/actions/build_vim_on_linux + with: + features: huge + compiler: clang + extra: '["asan"]' + # Lua5.1 is the most widely used version (since it's what LuaJIT is + # compatible with), so ensure it works + lua_ver: "5.1" + + - name: Test (tinytests) + if: matrix.testset == 'tinytests' + timeout-minutes: 20 + run: make ${TEST} NEW_TESTS_RES= + + - name: Test (newtests) + if: startsWith(matrix.testset, 'newtests') + timeout-minutes: 20 + env: + JOB_INDEX: ${{ strategy.job-index }} + JOB_TOTAL: ${{ strategy.job-total }} + run: | + set -x + make -C src/testdir SCRIPTS_TINY_OUT= \ + NEW_TESTS_RES="$(python3 ci/gen_testset.py $((JOB_TOTAL-1)) | jq -r --argjson i $((JOB_INDEX-1)) '.[$i]|join(" ")')" + + - name: ASan logs + if: ${{ !cancelled() }} + run: | + for f in $(grep -lR '#[[:digit:]]* *0x[[:xdigit:]]*' "${LOG_DIR}"); do + ( + echo "$f" + asan_symbolize -l "$f" + ) | tee "$f".symbolized + false # in order to fail a job + done + + - name: Upload failed test artifacts + if: ${{ !cancelled() }} + uses: ./.github/actions/test_artifacts diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml new file mode 100644 index 0000000000..390f27effa --- /dev/null +++ b/.github/workflows/ci-macos.yml @@ -0,0 +1,103 @@ +name: CI for macOS + +on: + workflow_call: + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for + # pull requests or the commit hash for any other events. + group: ${{ github.workflow }}-macos-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + macos: + runs-on: ${{ matrix.runner }} + + env: + CC: clang + TEST: test + SRCDIR: ./src + LEAK_CFLAGS: -DEXITFREE + TERM: xterm + + strategy: + fail-fast: false + matrix: + features: [tiny, normal, huge] + runner: [macos-15-intel, macos-26] + + steps: + - name: Checkout repository from GitHub + uses: actions/checkout@v6 + + - name: Install packages + if: matrix.features == 'huge' + run: | + brew install lua libtool + echo "LUA_PREFIX=$(brew --prefix)" >> $GITHUB_ENV + + - name: Set up environment + run: | + ( + echo "NPROC=$(getconf _NPROCESSORS_ONLN)" + case "${{ matrix.features }}" in + tiny) + echo "TEST=testtiny" + echo "CONFOPT=--disable-gui" + ;; + normal) + ;; + huge) + echo "CONFOPT=--enable-perlinterp --enable-python3interp --enable-rubyinterp --enable-luainterp --enable-tclinterp" + ;; + esac + ) >> $GITHUB_ENV + + - name: Configure + run: | + ./configure --with-features=${{ matrix.features }} ${CONFOPT} --enable-fail-if-missing + # Append various warning flags to CFLAGS. + # BSD sed needs backup extension specified. + sed -i.bak -f ci/config.mk.sed ${SRCDIR}/auto/config.mk + # On macOS, the entity of gcc is clang. + sed -i.bak -f ci/config.mk.clang.sed ${SRCDIR}/auto/config.mk + # Suppress some warnings produced by clang 12 and later. + if clang --version | grep -qs 'Apple clang version \(1[3-9]\|[2-9]\)\.'; then + sed -i.bak -f ci/config.mk.clang-12.sed ${SRCDIR}/auto/config.mk + fi + + - name: Build + env: + LC_ALL: C + run: | + make -j${NPROC} + + - name: Check version + run: | + "${SRCDIR}"/vim --version + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit + if ${{ matrix.features == 'huge' }}; then + # Also check that optional and dynamic features are configured and working + "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 \ + -c "let g:required=['sound', 'perl', 'python3', 'lua', 'ruby', 'tcl']" \ + -S ci/if_feat_check.vim -c quit + fi + + - name: Install packages for testing + run: | + # Apple diff is broken. Use GNU diff instead. See #14032. + brew install diffutils + + - name: Test + timeout-minutes: 25 + run: | + make ${TEST} + + - name: Upload failed test artifacts + if: ${{ !cancelled() }} + uses: ./.github/actions/test_artifacts diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml new file mode 100644 index 0000000000..1f676b2ca9 --- /dev/null +++ b/.github/workflows/ci-windows.yml @@ -0,0 +1,362 @@ +name: CI for Windows + +on: + workflow_call: + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for + # pull requests or the commit hash for any other events. + group: ${{ github.workflow }}-windows-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + windows: + runs-on: windows-2022 + + env: + # Interfaces + # Lua + LUA_VER: 54 + LUA_VER_DOT: "5.4" + LUA_RELEASE: 5.4.2 + LUA32_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win32_dllw6_lib.zip + LUA64_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win64_dllw6_lib.zip + LUA_DIR: D:\Lua + # do not want \L to end up in pathdef.c and compiler complaining about unknown escape sequences \l + LUA_DIR_SLASH: D:/Lua + # Python 2 + PYTHON_VER: 27 + PYTHON_VER_DOT: "2.7" + PYTHON_DIR: 'C:\Python27' + # Python 3 + PYTHON3_VER: 313 + PYTHON3_VER_DOT: "3.13" + # Other dependencies + # winpty + WINPTY_URL: https://github.com/rprichard/winpty/releases/download/0.4.3/winpty-0.4.3-msvc2015.zip + # libsodium + SODIUM_VER: "1.0.20" + # SODIUM_MSVC_URL: https://download.libsodium.org/libsodium/releases/libsodium-%SODIUM_VER%-stable-msvc.zip + SODIUM_MSVC_URL: https://github.com/jedisct1/libsodium/releases/download/%SODIUM_VER%-RELEASE/libsodium-%SODIUM_VER%-msvc.zip + SODIUM_MSVC_VER: v143 + # SODIUM_MINGW_URL: https://download.libsodium.org/libsodium/releases/libsodium-%SODIUM_VER%-stable-mingw.tar.gz + SODIUM_MINGW_URL: https://github.com/jedisct1/libsodium/releases/download/%SODIUM_VER%-RELEASE/libsodium-%SODIUM_VER%-mingw.tar.gz + SODIUM_MINGW_VER: 26 + # Gettext-tools, iconv and libraries + GETTEXT32_URL: https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.21-v1.16/gettext0.21-iconv1.16-shared-32.zip + GETTEXT64_URL: https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.21-v1.16/gettext0.21-iconv1.16-shared-64.zip + # Escape sequences + COL_RED: "\x1b[31m" + COL_GREEN: "\x1b[32m" + COL_YELLOW: "\x1b[33m" + COL_RESET: "\x1b[m" + + strategy: + fail-fast: false + matrix: + include: + - { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: no, arch: x64, python3: stable } + - { features: HUGE, toolchain: mingw, VIMDLL: yes, GUI: yes, arch: x86, python3: stable, coverage: yes } + - { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: yes, arch: x86 } + - { features: HUGE, toolchain: mingw, VIMDLL: yes, GUI: no, arch: x64, coverage: yes } + - { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: no, arch: x64, ttytype: conpty } + - { features: NORMAL, toolchain: msvc, VIMDLL: yes, GUI: no, arch: x86 } + - { features: NORMAL, toolchain: mingw, VIMDLL: no, GUI: yes, arch: x64 } + - { features: TINY, toolchain: msvc, VIMDLL: yes, GUI: yes, arch: x64 } + - { features: TINY, toolchain: mingw, VIMDLL: no, GUI: no, arch: x86 } + + steps: + - name: Initialize + id: init + shell: bash + run: | + # Show Windows version + cmd /c ver + + if ${{ matrix.arch == 'x64' }}; then + cygreg=registry + pyreg= + echo "VCARCH=amd64" >> $GITHUB_ENV + echo "WARCH=x64" >> $GITHUB_ENV + echo "BITS=64" >> $GITHUB_ENV + echo "MSYSTEM=MINGW64" >> $GITHUB_ENV + else + cygreg=registry32 + pyreg=-32 + echo "VCARCH=x86" >> $GITHUB_ENV + echo "WARCH=ia32" >> $GITHUB_ENV + echo "BITS=32" >> $GITHUB_ENV + echo "MSYSTEM=MINGW32" >> $GITHUB_ENV + fi + + echo "VCVARSALL=$(vswhere -products \* -latest -property installationPath)\\VC\\Auxiliary\\Build\\vcvarsall.bat" >> $GITHUB_ENV + if ${{ matrix.features != 'TINY' }}; then + if ${{ matrix.arch == 'x86' }}; then + choco install python2 --no-progress --forcex86 + else + choco install python2 --no-progress + fi + fi + python3_dir=$(cat "/proc/$cygreg/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON3_VER_DOT}$pyreg/InstallPath/@") + echo "PYTHON3_DIR=$python3_dir" >> $GITHUB_ENV + + if ${{ matrix.toolchain == 'msvc' }}; then + SODIUM_DIR=D:\\libsodium + echo "SODIUM_LIB=${SODIUM_DIR}\\${{ matrix.arch == 'x64' && 'x64' || 'Win32' }}\\Release\\${SODIUM_MSVC_VER}\\dynamic" >> $GITHUB_ENV + else + SODIUM_DIR=D:\\libsodium-win${{ matrix.arch == 'x64' && '64' || '32' }} + # do not want \L to end up in pathdef.c and compiler complaining about unknown escape sequences \l + SODIUM_DIR_SLASH=D:/libsodium-win${{ matrix.arch == 'x64' && '64' || '32' }} + echo "SODIUM_LIB=${SODIUM_DIR}\\bin" >> $GITHUB_ENV + echo "SODIUM_DIR_SLASH=${SODIUM_DIR_SLASH}" >> $GITHUB_ENV + fi + echo "SODIUM_DIR=${SODIUM_DIR}" >> $GITHUB_ENV + echo "GETTEXT_PATH=D:\gettext${{ matrix.arch == 'x64' && '64' || '32' }}" >> $GITHUB_ENV + + - uses: msys2/setup-msys2@v2.31.1 + if: matrix.toolchain == 'mingw' + with: + update: true + install: tar + pacboy: >- + make:p gcc:p + msystem: ${{ env.MSYSTEM }} + release: false + + - name: Checkout repository from GitHub + uses: actions/checkout@v6 + + - name: Create a list of download URLs + shell: cmd + run: | + type NUL > urls.txt + echo %LUA_RELEASE%>> urls.txt + echo %WINPTY_URL%>> urls.txt + echo %SODIUM_VER%>> urls.txt + echo %GETTEXT32_URL%>> urls.txt + echo %GETTEXT64_URL%>> urls.txt + + - name: Cache downloaded files + uses: actions/cache@v5.0.5 + with: + path: downloads + key: ${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('urls.txt') }} + + - name: Download dependencies + shell: cmd + run: | + path C:\Program Files\7-Zip;%path% + if not exist downloads mkdir downloads + + echo %COL_GREEN%Download Lua%COL_RESET% + call :downloadfile %LUA${{ env.BITS }}_URL% downloads\lua.zip + 7z x downloads\lua.zip -o%LUA_DIR% > nul || exit 1 + + if not "${{ matrix.ttytype }}" == "conpty" ( + echo %COL_GREEN%Download winpty%COL_RESET% + call :downloadfile %WINPTY_URL% downloads\winpty.zip + 7z x -y downloads\winpty.zip -oD:\winpty > nul || exit 1 + copy /Y D:\winpty\%WARCH%\bin\winpty.dll src\winpty%BITS%.dll + copy /Y D:\winpty\%WARCH%\bin\winpty-agent.exe src\ + ) + + echo %COL_GREEN%Download libsodium%COL_RESET% + if "${{ matrix.toolchain }}"=="msvc" ( + call :downloadfile %SODIUM_MSVC_URL% downloads\libsodium.zip + 7z x -y downloads\libsodium.zip -oD:\ > nul || exit 1 + ) else ( + call :downloadfile %SODIUM_MINGW_URL% downloads\libsodium.tar.gz + 7z x -y downloads\libsodium.tar.gz -so | 7z x -si -ttar -oD:\ > nul || exit 1 + mklink %SODIUM_LIB%\libsodium.dll %SODIUM_LIB%\libsodium-%SODIUM_MINGW_VER%.dll + ) + + echo %COL_GREEN%Download Gettext%COL_RESET% + call :downloadfile %GETTEXT${{ env.BITS }}_URL% downloads\gettext${{ env.BITS }}.zip + 7z e -y downloads\gettext${{ env.BITS }}.zip -oD:\gettext${{ env.BITS }} > nul || exit 1 + copy /y D:\gettext${{ env.BITS }}\libintl-8.dll src\ || exit 1 + copy /y D:\gettext${{ env.BITS }}\libiconv-2.dll src\ || exit 1 + + goto :eof + + :downloadfile + :: call :downloadfile + if not exist %2 ( + curl -f -L %1 -o %2 + ) + if ERRORLEVEL 1 ( + rem Retry once. + curl -f -L %1 -o %2 || exit 1 + ) + goto :eof + + - name: Build (MSVC) + if: matrix.toolchain == 'msvc' + shell: cmd + run: | + call "%VCVARSALL%" %VCARCH% + cd src + if "${{ matrix.VIMDLL }}"=="yes" ( + set GUI=yes + ) else ( + set GUI=${{ matrix.GUI }} + ) + if "${{ matrix.python3 }}"=="stable" ( + set PYTHON3_STABLE=yes + ) else ( + set PYTHON3_STABLE=no + ) + if "${{ matrix.features }}"=="HUGE" ( + nmake -nologo -f Make_mvc.mak ^ + FEATURES=${{ matrix.features }} ^ + GUI=%GUI% IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} ^ + DYNAMIC_LUA=yes LUA=%LUA_DIR% ^ + DYNAMIC_PYTHON=yes PYTHON=%PYTHON_DIR% ^ + DYNAMIC_PYTHON3=yes PYTHON3=%PYTHON3_DIR% ^ + DYNAMIC_PYTHON3_STABLE_ABI=%PYTHON3_STABLE% ^ + DYNAMIC_SODIUM=yes SODIUM=%SODIUM_DIR% ^ + CI_FLAGS=/we4267 + ) else ( + nmake -nologo -f Make_mvc.mak ^ + FEATURES=${{ matrix.features }} ^ + GUI=%GUI% IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} ^ + CI_FLAGS=/we4267 + ) + + - name: Build (MinGW) + if: matrix.toolchain == 'mingw' + shell: msys2 {0} + run: | + cd src + if [ "${{ matrix.VIMDLL }}" = "yes" ]; then + GUI=yes + else + GUI=${{ matrix.GUI }} + fi + if [ "${{ matrix.python3 }}" = "stable" ]; then + PYTHON3_STABLE=yes + else + PYTHON3_STABLE=no + fi + if [ "${{ matrix.features }}" = "HUGE" ]; then + mingw32-make -f Make_ming.mak -j2 \ + FEATURES=${{ matrix.features }} \ + GUI=$GUI IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} \ + DYNAMIC_LUA=yes LUA=${LUA_DIR_SLASH} \ + DYNAMIC_PYTHON=yes PYTHON=${PYTHON_DIR} \ + DYNAMIC_PYTHON3=yes PYTHON3=${PYTHON3_DIR} \ + DYNAMIC_PYTHON3_STABLE_ABI=${PYTHON3_STABLE} \ + DYNAMIC_SODIUM=yes SODIUM=${SODIUM_DIR_SLASH} \ + STATIC_STDCPLUS=yes COVERAGE=${{ matrix.coverage }} + else + mingw32-make -f Make_ming.mak -j2 \ + FEATURES=${{ matrix.features }} \ + GUI=$GUI IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} \ + STATIC_STDCPLUS=yes + fi + + - name: Check version + shell: cmd + run: | + PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PYTHON3_DIR%;%PATH% + if "${{ matrix.GUI }}"=="yes" ( + start /wait src\gvim -u NONE -i NONE -c "redir > version.txt | ver | q" || exit 1 + type version.txt + echo. + start /wait src\gvim -u NONE -i NONE -c "redir! > version.txt | so ci\if_ver-1.vim | q" + start /wait src\gvim -u NONE -i NONE -c "redir >> version.txt | so ci\if_ver-2.vim | q" + type version.txt + del version.txt + ) else ( + src\vim --version || exit 1 + src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit + src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit + if "${{ matrix.features }}"=="HUGE" ( + src\vim -u NONE -i NONE --not-a-term -esNX -V1 ^ + -c "let g:required=['gettext', 'sodium', 'sound', 'python3', 'lua']" ^ + -S ci/if_feat_check.vim -c quit + ) + ) + + #- name: Prepare Artifact + # shell: cmd + # run: | + # mkdir artifacts + # copy src\*vim.exe artifacts + # copy src\vim*.dll artifacts + # + #- name: Upload Artifact + # uses: actions/upload-artifact@v7 + # with: + # name: vim${{ matrix.bits }}-${{ matrix.toolchain }} + # path: ./artifacts + + # disabled because of https://github.com/tunisiano187/Chocolatey-packages/issues/3916 + #- name: Install packages for testing + # shell: bash + # run: | + # if ${{ matrix.features != 'TINY' }}; then + # if ${{ matrix.arch == 'x64' }}; then + # choco install netbeans --no-progress + # else + # exit 0 + # fi + # fi + + - name: Test and show the result of testing gVim + if: matrix.GUI == 'yes' || matrix.VIMDLL == 'yes' + shell: cmd + timeout-minutes: 15 + run: | + PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PYTHON3_DIR%;%PATH%;%SODIUM_LIB% + call "%VCVARSALL%" %VCARCH% + + echo %COL_GREEN%Test gVim:%COL_RESET% + cd src\testdir + if "${{ matrix.GUI }}"=="yes" ( + nmake -nologo -f Make_mvc.mak VIMPROG=..\gvim || exit 1 + ) else ( + @rem Run only tiny tests. + nmake -nologo -f Make_mvc.mak tiny VIMPROG=..\gvim || exit 1 + ) + + - name: Test and show the result of testing Vim + if: matrix.GUI == 'no' || matrix.VIMDLL == 'yes' + shell: cmd + timeout-minutes: 15 + run: | + PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PYTHON3_DIR%;%PATH%;%SODIUM_LIB% + call "%VCVARSALL%" %VCARCH% + + echo %COL_GREEN%Test Vim:%COL_RESET% + cd src\testdir + nmake -nologo -f Make_mvc.mak clean + if "${{ matrix.GUI }}"=="no" ( + nmake -nologo -f Make_mvc.mak VIMPROG=..\vim || exit 1 + ) else ( + @rem Run only tiny tests. + nmake -nologo -f Make_mvc.mak tiny VIMPROG=..\vim || exit 1 + ) + + - name: Upload failed test artifacts + if: ${{ !cancelled() }} + uses: ./.github/actions/test_artifacts + + - name: Generate gcov files + if: matrix.coverage + shell: msys2 {0} + run: | + cd src + find . -type f -name '*.gcno' -exec gcov -pb {} + || true + + - name: Codecov + timeout-minutes: 20 + if: matrix.coverage + uses: codecov/codecov-action@v6 + with: + directory: src + flags: windows,${{ matrix.toolchain }}-${{ matrix.arch }}-${{ matrix.features }} + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3364adf340..24ef96eaf0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@v4.36.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v4 + uses: github/codeql-action/autobuild@v4.36.0 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@v4.36.0 diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index e413603bd4..4172d28e0d 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -17,6 +17,6 @@ jobs: pull-requests: write steps: - - uses: actions/labeler@v6 + - uses: actions/labeler@v6.1.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..291c07900b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,325 @@ +# AGENTS.md + +Guidance for AI coding agents working in the Vim repository. + +## Project + +Vim is a text editor written in C. The canonical repository is +https://github.com/vim/vim. The code is old and has grown organically over +the past 30+ years. Some files are vendored from upstream projects +(`src/xdiff`, `src/libvterm`); parts of the runtime are occasionally shared +with forks like Neovim. + +Vim strives to be portable across several different operating systems and +aims to be a stable, robust editor gradually developing new features while +remaining backwards compatible as much as possible. + +At the same time, Vim can be compiled with different feature sets, from the +POSIX compatible minimal vi to a full-fledged GUI editor which includes +additional scripting interfaces. + +See `runtime/doc/develop.txt` for the high level design goals. + +## Build and test + + # Full build on Unix/Linux (from src/): + make + + # Run the full test suite: + make test + + # Generate proto files + make proto + + # Run a single test file: + cd src/testdir && make test_name.res + +Output is in testdir/messages and testdir/test.log + +Builds on Windows depend on the Environment, see `src/INSTALLpc.txt` +for Cygwin/MSYS and MSVC ways to build Vim + +Before submitting any patch, at minimum: +1. The build succeeds without new warnings. +2. Relevant tests pass. +3. The code matches the style of the file being edited. + +## Layout + +- `src/` - the C source. Subsystem names are usually obvious from filenames + (`buffer.c`, `window.c`, `search.c`, `vim9compile.c`, etc.). +- `src/proto/` - function prototypes, one `.pro` file per source file. + Regenerated; do not hand-edit unless you know what you're doing. +- `src/po` - Translations +- `src/xxd` - for the xxd subproject +- `src/xdiff` - for the xdiff library (imported from git) +- `src/libvterm` - for the libvterm library +- `src/testdir/` - tests. Vim-script files named `test_*.vim`. + Screendump expected output lives in `src/testdir/dumps/`. +- `runtime/doc/` - user-facing documentation in Vim help format, when updating, + also update the Last Change header +- `runtime/syntax/generator` - Syntax script for Vim Script, automatically generated + from Vims source +- `runtime/` - runtime files shipped with Vim, when updating, also update the + Last Change header and a short description if this file has no maintainer + If the file has a maintainer, changes should go via them (so make a merge + request against the upstream repo instead) +- `src/version.c` - contains the `included_patches[]` list. Every + patch touching anything below `src/` (with the exception of `src/po`) needs a + new entry at the top, will be updated only when merging into + the master tree. + +## Commit format + +Vim uses a strict commit message format. The subject line is a +one-sentence **problem statement**, not a description of the fix: + + patch 9.2.NNNN: short description of the problem + + Problem: Restatement of the problem as a full sentence, possibly + with a reporter attribution in parentheses. + Solution: Short description of the fix, ending with the author's + name in parentheses. + + optional longer description of the problem and solution goes here in prose. + Do not use bullet points. + + fixes: #NNNN + related: #NNNN + closes: #NNNN + + Co-authored-by: Name + Signed-off-by: Author Name + +Rules: + +- **Subject line states the problem**, not the solution. "fix typo" is + wrong; "typo in foo() causes OOB read" is right. +- **Problem line is a full sentence with a trailing period.** It mirrors + the subject. +- **Solution line ends with `(Author Name)`** — parentheses, period + after them. +- **Longer prose**, if any, goes after the Problem/Solution header +- **`fixes:` references the issue** the patch fixes. + **`closes:` references the PR** that introduces the fix. + **`related:` references related issues**, including issues that caused this + one. + All can appear. Colon, aligned, no trailing period. +- **`Signed-off-by:` is required** — DCO. +- **`Co-Authored-By:` is allowed** and is the accepted way to + acknowledge AI assistance transparently. Human + coauthors should usually also have their own Signed-off-by. + +## C code conventions + +- **Indentation is 4 spaces per level.** Existing files use tabs with + `ts=8 sts=4 sw=4 noet` (set by the modeline in the file), + so tabs of width 8 appear where two levels of indent collapse. `sign.c`, + `sound.c`, and any new file must use spaces only and follow the style from + the .editorconfig file. +- **Opening braces go on their own line (Allman style)** — for function + definitions and for control-flow constructs (`if`/`else`/`for`/`while`/ + `do`) alike. +- **Function definitions**: return type on its own indented line, with + the function name beginning on the next line. +- Initialize locals where a reader cannot trivially see the first + assignment (common for pointers and return-value accumulators). + Don't add `= 0` initializers for values that are always assigned + before use — they can hide real uninitialized-read bugs from + the compiler. +- `for (int i = 0; ...)` loop declarations are fine in files that + use them; older files may declare the counter at the top of the + block. +- **Function-scope declarations at the top of a block** is the historical + style, but mid-block declarations are acceptable in files that have + adopted them. Match the surrounding code. +- **Custom types end in `_T`** (e.g., `buf_T`, `linenr_T`, `pos_T`). + Never use `_t` — it collides with POSIX typedefs. +- **C language is C95 plus specific C99 features**: `//` comments, + mixed declarations and statements, `__func__`, `bool`/`_Bool`, + variadic macros, compound literals, `static inline`, trailing enum + commas. Do not reach for later C standards — Vim still must build + with Compaq C on OpenVMS. See `*assumptions-C-compiler*` in + `develop.txt` for the full list. +- **`bool` / `true` / `false` are acceptable.** Vim is transitioning + from `int` with `TRUE`/`FALSE` to C99 `bool`. Do not "fix" `bool` + back to `int`. Within a single patch, be consistent — don't mix + `true` and `TRUE` in new code. +- **Do not mass-convert** `TRUE`/`FALSE` to `true`/`false` across files + unless that is the patch's explicit purpose. Opportunistic + conversions create noise in diffs. +- **`STRLEN_LITERAL("...")`** should be used when the length of a + string literal is needed. Avoid `STRLEN()` on literals. +- **`vim_snprintf_safelen()`** returns the written length; prefer it + over `vim_snprintf()` when the length is then needed. +- **Prefer `dict_add_string_len()`** when the string length is already + known, over `dict_add_string()` which calls `STRLEN()`. +- **String/buffer parameters go `(char_u *buf, size_t buflen)`** — + length alongside pointer, in bytes. Use `size_t` for byte counts, + `int` only where required by legacy APIs. +- **Guards before divisions.** Check for divisor zero explicitly, even + when a composite earlier guard would prevent it. Relying on + transitive guards is fragile. +- When introducing new allocations, verify the cleanup paths handle all exit + conditions (early return, error branches, etc). + +**Use Vim wrappers instead of libc where one exists:** + +| libc | Vim | Why | +|---------------|------------------------|-----------------------------| +| `free()` | `vim_free()` | Tolerates NULL | +| `malloc()` | `alloc()` / `lalloc()` | Checks for OOM | +| `strcpy()` | `STRCPY()` | Cast for `char_u *` | +| `strchr()` | `vim_strchr()` | Handles special characters | +| `strrchr()` | `vim_strrchr()` | Handles special characters | +| `memcpy()` | `mch_memmove()` | Handles overlapping copies | +| `bcopy()` | `mch_memmove()` | Handles overlapping copies | +| `memset()` | `vim_memset()` | Uniform across systems | +| `isspace()` | `vim_isspace()` | Handles bytes > 127 | +| `iswhite()` | `vim_iswhite()` | TRUE only for tab and space | + +Further rules, not spelled out here, live in `runtime/doc/develop.txt`: + +- `*style-names*` — reserved name patterns (`is*`, `to*`, `str*`, `mem*`, + `wcs*`, `.*_t`, `__.*`), forbidden identifiers (`delete`, `this`, `new`, + `time`, `index`), and the 31-character function-name limit. +- `*style-spaces*`, `*style-examples*` — spacing and one-statement-per-line. +- `*style-various*` — `FEAT_` feature prefix, uppercase `#define`, + `#ifdef HAVE_X` rather than `#if HAVE_X`, no `'\"'`. +- `*assumptions-makefiles*` — POSIX.1-2001 `make` only in the main + Makefiles (no `%` rules, `:=`, `.ONESHELL`, GNU conditionals). +- Vim uses `char_u` instead of `char` type +- Vim uses the macros `STRLEN`, `STRCPY`, `STRCMP`, `STRCAT` that work + with the `char_u` type. +- `*style-clang-format*` — `sign.c` and `sound.c` are formatted with + `clang-format`; re-run it after editing those files. + +## Vim9 script conventions (in tests and runtime files) + +- Write modern Vim style (new files can use Vim9 script, but compatibility + with Neovim and other forks is a concern, so in doubt please ask!) +- **Drop `l:` prefix from local variables** in Vim-script tests. +- **Don't add `CheckFeature` inside individual tests** if it's already + at the top of the file. +- If a test file doesn't gate features at the top, add CheckFeature to + individual tests that depend on specific build features. + +## Test conventions + +- Tests are in `src/testdir/test_*.vim`. +- Reproducible tests beat "it doesn't crash" tests. If a patch fixes + a rendering bug, add a screendump test. If it fixes incorrect output, + assert the output. +- Add comprehensive tests for newly added features and include them + in existing tests if possible +- **Screendump tests** use `CheckScreendump`, `RunVimInTerminal`, + `VerifyScreenDump`, and live dumps in `src/testdir/dumps/`. +- `v9.CheckScriptSuccess(lines)` / `v9.CheckScriptFailure(lines, error, lnum)` + are the standard way to test Vim9 script behavior at script-load time. +- When fixing a bug reported as an issue, include a test that + reproduces the original report, not just a minimal synthetic case. +- Tests for Syntax runtime are in `runtime/syntax/testdir` +- Tests for Indent runtime are in `runtime/indent/testdir` + +## Common gotchas + +- **Distinguish what code enforces from what docs claim.** If a patch + changes documented behavior, say so in the Problem/Solution. +- **Generated files** (`src/auto/configure`, generated Wayland protocol + C, etc.) should only be regenerated when their source changes. + Mixing unrelated regeneration into a functional patch creates noise. + +## Documentation + +- User-facing option or feature changes require a `runtime/doc/*.txt` + update in the same patch. +- When editing an existing help file, bump the `Last change:` header + at the top. + +### Help file style + +See `runtime/doc/helphelp.txt` (`*help-writing*`) for the authoritative +reference. Key conventions: + +- **File header**: first line is `*filename.txt*` then a tab then a + short description. That description appears under `LOCAL ADDITIONS` + in `help.txt`. The version and `Last change:` date go on the second + line, right aligned. +- **Modeline**: every help file ends with a Vim modeline — typically + `vim:tw=78:ts=8:noet:ft=help:norl:`. +- **Layout**: `'textwidth'` 78, `'tabstop'` 8, indent and align with + tab characters. Two spaces between sentences. Run `:retab` + (not `:retab!`, and review the diff) after editing. +- **Tags** are defined as `*tag-name*`, usually right-aligned on the + line where the thing they name is introduced. Tag names must be + unique across all of `runtime/doc/`; for plugin help, prefix with + the plugin name. +- **Cross-references inside help text**: + - `|tag-name|` — hot-link to an existing tag. + - `` `:cmd` `` — Ex command, highlighted as a code block. + - `'option'` — option name, in single quotes. + - `` or `CTRL-X` — special keys. + - `{placeholder}` — user-supplied argument. +- **Sections** are separated by a line of `=` starting in column 1. + Column or subsection headings end with `~` to trigger heading + highlighting. +- **Code blocks** start with `>` at the end of the introducing line + and end with `<` as the first non-blank on a later line (any line + starting in column 1 also implicitly closes the block). Use `>vim` + (or another language name) to request syntax highlighting inside + the block. +- **Notation** — `Note`, `Todo`, `Error` and a few similar words are + auto-highlighted; do not try to fake the highlighting by other means. +- **Language**: gender-neutral language is preferred for new or updated + text; existing wording does not need to be rewritten for this alone. + +## Release policy + +Vim alternates between development cycles and stability periods — see +`runtime/doc/develop.txt` `*design-policy*`. + +- **During a stability period** only clear bug fixes, security fixes, + documentation updates, translations, and runtime file updates are + accepted. No new features, no backwards-incompatible changes. +- **Once released in a minor version**, C-core features must stay + backwards-compatible. Runtime files have a bit more flexibility so + their maintainers can correct old behavior. +- **Deprecated features** stay reachable via config (do not hard-error), + are documented as deprecated, can be disabled at compile time, and + may be removed in a later cycle. + +## Security + +Before reporting a suspected security issue or submitting a patch +that touches security-sensitive code, read `SECURITY.md`. Follow +the disclosure process described there. + +## Before submitting + +1. Commit message follows the format above. +2. All modified code compiles without new warnings. +3. Tests pass, and new functionality has regression tests. +4. Documentation is updated for user-visible changes. +5. Signed-off-by is present. +6. Diff contains only changes relevant to the stated problem — + no stray whitespace fixes, no unrelated refactors, no unrelated + regeneration of `auto/configure`. +7. For multi-patch series: each commit compiles and passes its own + tests. A known-broken intermediate state that a later patch fixes + is not acceptable — squash instead. + +## When in doubt + +- Make the smallest possible change to achieve the goal. Do not rewrite + entire files or functions when a targeted edit suffices. +- Read surrounding code and match its style rather than imposing an + "improvement." +- Err toward smaller, more focused patches. A patch that does three + things is three patches. +- If a patch fixes a symptom of a deeper bug, say so in the Problem + and acknowledge the scope limitation in the Solution. +- Before claiming a bug exists, reproduce it. Before claiming code does X, read + the code. Do not rely on training-data memory of file contents. +- Before running shell commands that modify files outside the working tree, + install packages, push branches, or invoke network operations, confirm with + the user. diff --git a/Filelist b/Filelist index 6a21157647..53113b456a 100644 --- a/Filelist +++ b/Filelist @@ -9,20 +9,24 @@ SRC_ALL = \ .github/MAINTAINERS \ .github/ISSUE_TEMPLATE/bug_report.yml \ .github/ISSUE_TEMPLATE/feature_request.md \ + .github/workflows/ci-linux.yml \ + .github/workflows/ci-linux_asan.yml \ + .github/workflows/ci-macos.yml \ + .github/workflows/ci-windows.yml \ .github/workflows/ci.yml \ .github/workflows/codeql-analysis.yml \ .github/workflows/coverity.yml \ .github/workflows/link-check.yml \ + .github/actions/build_vim_on_linux/action.yml \ .github/actions/test_artifacts/action.yml \ .github/dependabot.yml \ .gitignore \ .hgignore \ - .appveyor.yml \ .clang-format \ .codecov.yml \ .editorconfig \ - ci/appveyor.bat \ ci/config.mk*.sed \ + ci/gen_testset.py \ ci/if_ver*.vim \ ci/if_feat_check.vim \ ci/lychee.toml \ @@ -145,12 +149,14 @@ SRC_ALL = \ src/session.c \ src/sha256.c \ src/sign.c \ + src/socketserver.c \ src/sound.c \ src/spell.c \ src/spell.h \ src/spellfile.c \ src/spellsuggest.c \ src/strings.c \ + src/strptime.c \ src/structs.h \ src/syntax.c \ src/tabpanel.c \ @@ -343,6 +349,7 @@ SRC_ALL = \ src/proto/session.pro \ src/proto/sha256.pro \ src/proto/sign.pro \ + src/proto/socketserver.pro \ src/proto/sound.pro \ src/proto/spell.pro \ src/proto/spellfile.pro \ @@ -440,6 +447,7 @@ SRC_ALL = \ src/libvterm/t/66screen_extent.test \ src/libvterm/t/67screen_dbl_wh.test \ src/libvterm/t/68screen_termprops.test \ + src/libvterm/t/69screen_pushline.test \ src/libvterm/t/69screen_reflow.test \ src/libvterm/t/90vttest_01-movement-1.test \ src/libvterm/t/90vttest_01-movement-2.test \ @@ -496,6 +504,9 @@ SRC_UNIX = \ src/gui_gtk_f.c \ src/gui_gtk_f.h \ src/gui_gtk_x11.c \ + src/gui_gtk4.c \ + src/gui_gtk4_f.c \ + src/gui_gtk4_f.h \ src/gui_gtk_res.xml \ src/gui_motif.c \ src/gui_xmdlg.c \ @@ -525,6 +536,7 @@ SRC_UNIX = \ src/proto/gui_gtk.pro \ src/proto/gui_gtk_x11.pro \ src/proto/gui_gtk_gresources.pro \ + src/proto/gui_gtk4.pro \ src/proto/gui_motif.pro \ src/proto/gui_xmdlg.pro \ src/proto/gui_x11.pro \ @@ -1191,10 +1203,10 @@ LANG_DOS = \ # be excluded from distribution tarballs and the like. # This excludes them from the CI check for unlisted files. IGNORE = \ - .appveyor.yml \ .github/FUNDING.yml \ .github/labeler.yml \ .github/workflows/label.yml \ + AGENTS.md \ SECURITY.md \ ci/unlisted.make \ ci/hlgroups.make \ diff --git a/README_vim.md b/README_vim.md index 949fcd7b4f..3e57f0e8c6 100644 --- a/README_vim.md +++ b/README_vim.md @@ -1,7 +1,6 @@ # [![Vim The editor](https://github.com/vim/vim/raw/master/runtime/vimlogo.gif)](https://www.vim.org) [![Github Build status](https://github.com/vim/vim/workflows/GitHub%20CI/badge.svg)](https://github.com/vim/vim/actions?query=workflow%3A%22GitHub+CI%22) -[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/o2qht2kjm02sgghk?svg=true)](https://ci.appveyor.com/project/chrisbra/vim) [![Cirrus Build Status](https://api.cirrus-ci.com/github/vim/vim.svg)](https://cirrus-ci.com/github/vim/vim) [![Coverage Status](https://codecov.io/gh/vim/vim/coverage.svg?branch=master)](https://codecov.io/gh/vim/vim?branch=master) [![Coverity Scan](https://scan.coverity.com/projects/241/badge.svg)](https://scan.coverity.com/projects/vim) diff --git a/ci/appveyor.bat b/ci/appveyor.bat deleted file mode 100644 index 17d95ff691..0000000000 --- a/ci/appveyor.bat +++ /dev/null @@ -1,131 +0,0 @@ -@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" - -:: 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" - -if exist "%VSWHERE%" ( - for /f "usebackq delims=" %%i in ( - `"%VSWHERE%" -products * -latest -property installationPath` - ) do ( - set "VCVARSALL=%%i\VC\Auxiliary\Build\vcvarsall.bat" - ) -) - -if not exist "%VCVARSALL%" ( - set "VCVARSALL=%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" -) -call "%VCVARSALL%" x64 - -goto %target% -echo Unknown build target. -exit 1 - -:: ---------------------------------------------------------------------------- -:install -@echo on -if not exist downloads mkdir downloads - -:: Python 3 -if not exist %PYTHON3_DIR% ( - call :downloadfile %PYTHON3_URL% downloads\python3.exe - cmd /c start /wait downloads\python3.exe /quiet TargetDir=%PYTHON3_DIR% ^ - Include_pip=0 Include_tcltk=0 Include_test=0 Include_tools=0 ^ - 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 - -:: ---------------------------------------------------------------------------- -:build - -cd src - -echo "Building MSVC 64bit console Version" -nmake -f Make_mvc.mak CPU=AMD64 ^ - OLE=no GUI=no IME=yes ICONV=yes DEBUG=no ^ - FEATURES=%FEATURE% CI_CFLAGS=/we4267 -if not exist vim.exe ( - echo Build failure. - exit 1 -) - -:: build MSVC huge version with python and channel support -:: GUI needs to be last, so that testing works -echo "Building MSVC 64bit GUI Version" -if "%FEATURE%" == "HUGE" ( - nmake -f Make_mvc.mak CPU=AMD64 ^ - OLE=no GUI=yes IME=yes ICONV=yes DEBUG=no POSTSCRIPT=yes ^ - PYTHON_VER=27 DYNAMIC_PYTHON=yes PYTHON=C:\Python27-x64 ^ - PYTHON3_VER=%PYTHON3_VER% DYNAMIC_PYTHON3=yes PYTHON3=%PYTHON3_DIR% ^ - FEATURES=%FEATURE% CI_CFLAGS=/we4267 -) ELSE ( - nmake -f Make_mvc.mak CPU=AMD64 ^ - OLE=no GUI=yes IME=yes ICONV=yes DEBUG=no ^ - FEATURES=%FEATURE% CI_CFLAGS=/we4267 -) -if not exist gvim.exe ( - echo Build failure. - exit 1 -) -.\gvim -u NONE -c "redir @a | ver |0put a | wq" ver_msvc.txt || exit 1 - -echo "version output MSVC console" -.\vim --version || exit 1 -echo "version output MSVC GUI" -type ver_msvc.txt || exit 1 - -goto :eof - -:: ---------------------------------------------------------------------------- -:test -@echo on -cd src/testdir -:: Testing with MSVC gvim -path %PYTHON3_DIR%;%GETTEXT_PATH%;%PATH% -nmake -f Make_mvc.mak VIMPROG=..\gvim -nmake -f Make_mvc.mak clean -:: Testing with MSVC console version -nmake -f Make_mvc.mak VIMPROG=..\vim - -@echo off -goto :eof - -:: ---------------------------------------------------------------------------- -:downloadfile -:: call :downloadfile -if not exist %2 ( - curl -f -L %1 -o %2 -) -if ERRORLEVEL 1 ( - rem Retry once. - curl -f -L %1 -o %2 || exit 1 -) -@goto :eof diff --git a/ci/gen_testset.py b/ci/gen_testset.py new file mode 100644 index 0000000000..91eeca111e --- /dev/null +++ b/ci/gen_testset.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +import argparse +import itertools +import json +import re +import subprocess + + +def generate_testset(n): + cp = subprocess.run(["make", "-C", "src/testdir", "-npq"], capture_output=True) + + tests = set() + for line in cp.stdout.decode().split("\n"): + if re.match(r"^(NEW_TESTS_RES|TEST_VIM9_RES) = ", line): + tests.update(re.findall(r"\btest\w+\.res\b", line)) + + tests = sorted(list(tests)) + # move test_alot*.res to the end + tests = ( + [t for t in tests if not t.startswith("test_alot")] + + [t for t in tests if t.startswith("test_alot_")] + + ["test_alot.res"] + ) + targets = tests + + if n > 1: + targets = [ts for ts in itertools.batched(tests, n)] + targets = [[t for t in ts if t] for ts in itertools.zip_longest(*targets)] + + return targets + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("n", type=int, nargs="?", default=1) + args = parser.parse_args() + + print(json.dumps(generate_testset(args.n))) + + +if __name__ == "__main__": + main() diff --git a/ci/lychee.toml b/ci/lychee.toml index 941a2d7f6f..8b9f0099f2 100644 --- a/ci/lychee.toml +++ b/ci/lychee.toml @@ -13,7 +13,7 @@ extensions = ["c", "h", "md", "html", "txt"] accept = ["100..=103", "200..=299", "429"] # Retry each request a few times on transient network errors -retries = 2 +max_retries = 2 retry_wait_time = 2 # Timeout per request in seconds diff --git a/lang/README.ru.txt b/lang/README.ru.txt index 774cfbbd5b..c794e4db46 100644 --- a/lang/README.ru.txt +++ b/lang/README.ru.txt @@ -137,7 +137,7 @@ README_vms.txt VMS ДОПОЛНИĐĸЕЛĐŦĐĐĐ¯ ИНФОРМАĐĻĐ˜Đ¯ -ДĐģŅ ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ macOS Đ˛Ņ‹ ĐŧĐžĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ MacVim: https://macvim.org +ДĐģŅ ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ macOS Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ MacVim: https://macvim.org ĐŸĐžŅĐģĐĩĐ´ĐŊиĐĩ ĐŊĐžĐ˛ĐžŅŅ‚Đ¸ Đž Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ Vim ĐŧĐžĐļĐŊĐž ĐŊĐ°ĐšŅ‚Đ¸ ĐŊа ĐĩĐŗĐž Đ´ĐžĐŧĐ°ŅˆĐŊĐĩĐš ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Đĩ: https://www.vim.org/ diff --git a/nsis/gvim.nsi b/nsis/gvim.nsi index 9843ff080d..02751ce90a 100644 --- a/nsis/gvim.nsi +++ b/nsis/gvim.nsi @@ -90,7 +90,7 @@ Unicode true ; !include defaults to UTF-8 after Unicode True since 3.0 Alpha 2 # ----------- No configurable settings below this line ----------- ########################################################## -# Installer Attributes, Including headers, Plugins and etc. +# Installer Attributes, Including headers, Plugins and etc. CRCCheck force @@ -638,21 +638,23 @@ SectionGroupEnd !undef LIBRARY_X64 ${EndIf} - # Install DLLs for 32-bit gvimext.dll into the GvimExt32 directory. - SetOutPath $0\GvimExt32 - ClearErrors - !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED \ - "${GETTEXT}\gettext32\libintl-8.dll" \ - "$0\GvimExt32\libintl-8.dll" "$0\GvimExt32" - !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED \ - "${GETTEXT}\gettext32\libiconv-2.dll" \ - "$0\GvimExt32\libiconv-2.dll" "$0\GvimExt32" - # Install libgcc_s_sjlj-1.dll only if it is needed. - !if ${INCLUDE_LIBGCC} - !if /FileExists "${GETTEXT}\gettext32\libgcc_s_sjlj-1.dll" - !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED \ - "${GETTEXT}\gettext32\libgcc_s_sjlj-1.dll" \ - "$0\GvimExt32\libgcc_s_sjlj-1.dll" "$0\GvimExt32" + !if ! ${ARM64} + # Install DLLs for 32-bit gvimext.dll into the GvimExt32 directory. + SetOutPath $0\GvimExt32 + ClearErrors + !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED \ + "${GETTEXT}\gettext32\libintl-8.dll" \ + "$0\GvimExt32\libintl-8.dll" "$0\GvimExt32" + !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED \ + "${GETTEXT}\gettext32\libiconv-2.dll" \ + "$0\GvimExt32\libiconv-2.dll" "$0\GvimExt32" + # Install libgcc_s_sjlj-1.dll only if it is needed. + !if ${INCLUDE_LIBGCC} + !if /FileExists "${GETTEXT}\gettext32\libgcc_s_sjlj-1.dll" + !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED \ + "${GETTEXT}\gettext32\libgcc_s_sjlj-1.dll" \ + "$0\GvimExt32\libgcc_s_sjlj-1.dll" "$0\GvimExt32" + !endif !endif !endif ${EndIf} diff --git a/runtime/autoload/README.txt b/runtime/autoload/README.txt index 3b18d3dde5..2180a744bf 100644 --- a/runtime/autoload/README.txt +++ b/runtime/autoload/README.txt @@ -14,9 +14,10 @@ Omni completion files: ccomplete.vim C csscomplete.vim HTML / CSS htmlcomplete.vim HTML -javascriptcomplete.vim Javascript +javascriptcomplete.vim Javascript phpcomplete.vim PHP pythoncomplete.vim Python +python3complete.vim Python rubycomplete.vim Ruby syntaxcomplete.vim from syntax highlighting xmlcomplete.vim XML (uses files in the xml directory) diff --git a/runtime/autoload/context.vim b/runtime/autoload/context.vim index 6b013f2a7b..8b65bb9a62 100644 --- a/runtime/autoload/context.vim +++ b/runtime/autoload/context.vim @@ -3,9 +3,7 @@ vim9script # Language: ConTeXt typesetting engine # Maintainer: Nicola Vitacolonna # Former Maintainers: Nikolai Weibull -# Latest Revision: 2026 Feb 03 -# Last Change: -# 2026 Mar 30 by Vim project: Use fnameescape for the Log command +# Latest Revision: 2026 May 20 # Typesetting {{{ import autoload './typeset.vim' @@ -35,7 +33,7 @@ export def Log(bufname: string) var logpath = typeset.LogPath(bufname) if filereadable(logpath) - execute 'edit' .. fnameescape(typeset.LogPath(bufname)) + execute 'edit' fnameescape(typeset.LogPath(bufname)) return endif diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim index b1c209400e..f59d95af49 100644 --- a/runtime/autoload/dist/ft.vim +++ b/runtime/autoload/dist/ft.vim @@ -3,7 +3,7 @@ vim9script # Vim functions for file type detection # # Maintainer: The Vim Project -# Last Change: 2026 Apr 03 +# Last Change: 2026 May 29 # Former Maintainer: Bram Moolenaar # These functions are moved here from runtime/filetype.vim to make startup @@ -63,6 +63,21 @@ export def FTapp() endfor enddef +# This function checks for Kawasaki robots AS file or atlas file type. +export def FTas() + if exists("g:filetype_as") + exe "setf " .. g:filetype_as + return + endif + for lnum in range(1, min([line("$"), 30])) + if getline(lnum) =~ '^\.NETCONF' + setf kawasaki_as + return + endif + endfor + setf atlas +enddef + # This function checks for the kind of assembly that is wanted by the user, or # can be detected from the beginning of the file. export def FTasm() @@ -547,7 +562,7 @@ export def FThtml() while n < 40 && n <= line("$") # Check for Angular - if getline(n) =~ '@\(if\|for\|defer\|switch\)\|\*\(ngIf\|ngFor\|ngSwitch\|ngTemplateOutlet\)\|ng-template\|ng-content' + if getline(n) =~ '@\(if\|for\|defer\|switch\)\|\*\(ngIf\|ngFor\|ngSwitch\|ngTemplateOutlet\)\|\\|@import\>\|/\*\)' + if getline(n) =~ '^\s*\(//\|#\s*\(include\|import\)\>\|@import\>\|/\*\)' setf objcpp return endif @@ -915,7 +935,7 @@ export def FTinc() elseif line =~ '^\s*\%({\|(\*\)' || line =~? ft_pascal_keywords setf pascal return - elseif line =~# '\<\%(require\|inherit\)\>' || line =~# '[A-Z][A-Za-z0-9_:${}/]*\s\+\%(??\|[?:+.]\)\?=.\? ' + elseif line =~# '^\s*\<\%(require\|inherit\)\>' || line =~# '^\s*[A-Z][A-Za-z0-9_:${}/]*\%(\[[A-Za-z0-9_:/]\+\]\)*\s\+\%(??=\|[?:+.]=\|=[+.]\?\)\s\+' setf bitbake return endif @@ -1726,6 +1746,8 @@ const ft_from_ext = { "tdf": "ahdl", # AIDL "aidl": "aidl", + # Algol 68 + "a68": "algol68", # AMPL "run": "ampl", # ANTLR / PCCTS @@ -1764,7 +1786,6 @@ const ft_from_ext = { "astro": "astro", # Atlas "atl": "atlas", - "as": "atlas", # Atom is based on XML "atom": "xml", # Authzed @@ -1798,6 +1819,7 @@ const ft_from_ext = { # BDF font "bdf": "bdf", # Beancount + "bean": "beancount", "beancount": "beancount", # BibTeX bibliography database file "bib": "bib", @@ -2292,6 +2314,8 @@ const ft_from_ext = { # KAREL "kl": "karel", "KL": "karel", + # Kawasaki AS + "pg": "kawasaki_as", # KDL "kdl": "kdl", # KerML @@ -2312,6 +2336,8 @@ const ft_from_ext = { "kts": "kotlin", # KDE script "ks": "kscript", + # Kaitai struct + "ksy": "yaml", # Kyaml "kyaml": "yaml", "kyml": "yaml", @@ -2613,6 +2639,8 @@ const ft_from_ext = { "qmd": "quarto", # QuickBms "bms": "quickbms", + # Popcap Reanimation files + "reanim": "xml", # Racket (formerly detected as "scheme") "rkt": "racket", "rktd": "racket", @@ -2707,6 +2735,8 @@ const ft_from_ext = { "mill": "scala", # SBT - Scala Build Tool "sbt": "sbt", + # SGF, Smart Game Format + "sgf": "sgf", # Slang Shading Language "slang": "shaderslang", # Slint @@ -2735,6 +2765,8 @@ const ft_from_ext = { "sieve": "sieve", # TriG "trig": "trig", + # Tolk + "tolk": "tolk", # Zig and Zig Object Notation (ZON) "zig": "zig", "zon": "zig", @@ -3113,7 +3145,9 @@ const ft_from_ext = { "bp": "bp", # Tiltfile "Tiltfile": "tiltfile", - "tiltfile": "tiltfile" + "tiltfile": "tiltfile", + # Ghostty + "ghostty": "ghostty", } # Key: file name (the final path component, excluding the drive and root) # Value: filetype diff --git a/runtime/autoload/dist/script.vim b/runtime/autoload/dist/script.vim index de168f0c09..3f9a5acfd0 100644 --- a/runtime/autoload/dist/script.vim +++ b/runtime/autoload/dist/script.vim @@ -4,7 +4,7 @@ vim9script # Invoked from "scripts.vim" in 'runtimepath' # # Maintainer: The Vim Project -# Last Change: 2025 Dec 22 +# Last Change: 2026 Apr 09 # Former Maintainer: Bram Moolenaar export def DetectFiletype() @@ -45,6 +45,8 @@ def DetectFromHashBang(firstline: string) name = substitute(line1, '^#!.*\\s\+\(\i\+\).*', '\1', '') elseif line1 =~ '^#!\s*[^/\\ ]*\>\([^/\\]\|$\)' name = substitute(line1, '^#!\s*\([^/\\ ]*\>\).*', '\1', '') + elseif line1 =~ '^#!.*\' + name = substitute(line1, '^#!.*\\s\+\(\i\+\).*', '\1', '') else name = substitute(line1, '^#!\s*\S*[/\\]\(\f\+\).*', '\1', '') endif @@ -67,7 +69,7 @@ enddef # Returns an empty string when not recognized. export def Exe2filetype(name: string, line1: string): string # Bourne-like shell scripts: bash bash2 dash ksh ksh93 sh - if name =~ '^\(bash\d*\|dash\|ksh\d*\|sh\)\>' + if name =~ '^\(bash\d*\|d\?ash\|ksh\d*\|sh\)\>' return dist#ft#SetFileTypeSH(line1, false) # csh scripts @@ -115,7 +117,7 @@ export def Exe2filetype(name: string, line1: string): string return 'php' # Python - elseif name =~ 'python' + elseif name =~ 'python' || (name == 'uv' && line1 =~ '\') return 'python' # Groovy diff --git a/runtime/autoload/dist/vim9.vim b/runtime/autoload/dist/vim9.vim index d824673912..a8bb4f95d0 100644 --- a/runtime/autoload/dist/vim9.vim +++ b/runtime/autoload/dist/vim9.vim @@ -3,7 +3,7 @@ vim9script # Vim runtime support library # # Maintainer: The Vim Project -# Last Change: 2026 Apr 06 +# Last Change: 2026 May 30 export def IsSafeExecutable(filetype: string, executable: string): bool if empty(exepath(executable)) @@ -51,7 +51,7 @@ if has('unix') execute $'silent !cmd /c start "" /b {args} {Redir()}' | redraw! enddef endif - elseif exists('$WSL_DISTRO_NAME') # use cmd.exe to start GUI apps in WSL + elseif exists('$WSL_DISTRO_NAME') && executable('cmd.exe') # use cmd.exe to start GUI apps in WSL export def Launch(args: string) const command = (args =~? '\v<\f+\.(exe|com|bat|cmd)>') ? $'cmd.exe /c start /b {args} {Redir()}' @@ -131,15 +131,18 @@ enddef export def Open(file: string) # disable shellslash for shellescape, required on Windows #17995 if exists('+shellslash') && &shellslash - &shellslash = false defer setbufvar('%', '&shellslash', true) + &shellslash = false endif if &shell == 'pwsh' || &shell == 'powershell' - const shell = &shell + defer setbufvar('%', '&shell', &shell) setlocal shell& - defer setbufvar('%', '&shell', shell) endif - Launch($"{Viewer()} {shellescape(file, 1)}") + if has('unix') && !has('win32unix') && !exists('$WSL_DISTRO_NAME') + Launch($"{Viewer()} {shellescape(file)}") + else + Launch($"{Viewer()} {shellescape(file, 1)}") + endif enddef # Uncomment this line to check for compilation errors early diff --git a/runtime/autoload/getscript.vim b/runtime/autoload/getscript.vim index 27a5a49535..04dd19a4c5 100644 --- a/runtime/autoload/getscript.vim +++ b/runtime/autoload/getscript.vim @@ -15,6 +15,7 @@ " 2025 Feb 28 by Vim Project: add support for bzip3 (#16755) " 2025 May 11 by Vim Project: check network connectivity (#17249) " 2025 Dec 21 by Vim Project: make the wget check more robust (#18987) +" 2026 May 20 by Vim Project: use correct shellescape() with ! command " }}} " " GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim @@ -433,9 +434,9 @@ fun! s:GetOneScript(...) let itry= 1 while itry <= 3 if has("win32") || has("win16") || has("win95") - new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile).' '.shellescape(scriptaddr)|bw! + new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile,1).' '.shellescape(scriptaddr,1)|bw! else - exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile)." ".shellescape(scriptaddr) + exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile,1)." ".shellescape(scriptaddr,1) endif if itry == 1 exe "silent vsplit ".fnameescape(tmpfile) @@ -503,9 +504,9 @@ fun! s:GetOneScript(...) " ----------------------------------------------------------------------------- echomsg ".downloading new <".sname.">" if has("win32") || has("win16") || has("win95") - new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid)|bw! + new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname,1)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid,1)|bw! else - exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid) + exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname,1)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid,1) endif " -------------------------------------------------------------------------- @@ -513,7 +514,7 @@ fun! s:GetOneScript(...) " -------------------------------------------------------------------------- if doautoinstall if filereadable(sname) - exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".shellescape(s:autoinstall) + exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname,1)." ".shellescape(s:autoinstall,1) let curdir = fnameescape(substitute(getcwd(),'\','/','ge')) let installdir= curdir."/Installed" if !isdirectory(installdir) @@ -532,33 +533,33 @@ fun! s:GetOneScript(...) " decompress if sname =~ '\.bz2$' - exe "sil !".g:GetLatestVimScripts_bunzip2." ".shellescape(sname) + exe "sil !".g:GetLatestVimScripts_bunzip2." ".shellescape(sname,1) let sname= substitute(sname,'\.bz2$','','') elseif sname =~ '\.bz3$' - exe "sil !".g:GetLatestVimScripts_bunzip3." ".shellescape(sname) + exe "sil !".g:GetLatestVimScripts_bunzip3." ".shellescape(sname,1) let sname= substitute(sname,'\.bz3$','','') elseif sname =~ '\.gz$' - exe "sil !".g:GetLatestVimScripts_gunzip." ".shellescape(sname) + exe "sil !".g:GetLatestVimScripts_gunzip." ".shellescape(sname,1) let sname= substitute(sname,'\.gz$','','') elseif sname =~ '\.xz$' - exe "sil !".g:GetLatestVimScripts_unxz." ".shellescape(sname) + exe "sil !".g:GetLatestVimScripts_unxz." ".shellescape(sname,1) let sname= substitute(sname,'\.xz$','','') else endif " distribute archive(.zip, .tar, .vba, .vmb, ...) contents if sname =~ '\.zip$' - exe "silent !".g:GetLatestVimScripts_unzip." -o ".shellescape(sname) + exe "silent !".g:GetLatestVimScripts_unzip." -o ".shellescape(sname,1) elseif sname =~ '\.tar$' - exe "silent !tar -xvf ".shellescape(sname) + exe "silent !tar -xvf ".shellescape(sname,1) elseif sname =~ '\.tgz$' - exe "silent !tar -zxvf ".shellescape(sname) + exe "silent !tar -zxvf ".shellescape(sname,1) elseif sname =~ '\.taz$' - exe "silent !tar -Zxvf ".shellescape(sname) + exe "silent !tar -Zxvf ".shellescape(sname,1) elseif sname =~ '\.tbz$' - exe "silent !tar -jxvf ".shellescape(sname) + exe "silent !tar -jxvf ".shellescape(sname,1) elseif sname =~ '\.txz$' - exe "silent !tar -Jxvf ".shellescape(sname) + exe "silent !tar -Jxvf ".shellescape(sname,1) elseif sname =~ '\.vba$\|\.vmb$' silent 1split if exists("g:vimball_home") @@ -579,12 +580,12 @@ fun! s:GetOneScript(...) " move plugin to plugin/ or AsNeeded/ directory " --------------------------------------------- if sname =~ '.vim$' - exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".tgtdir + exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname,1)." ".tgtdir else - exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".installdir + exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname,1)." ".installdir endif if tgtdir != "plugin" - exe "silent !".g:GetLatestVimScripts_mv." ".shellescape("plugin/".pname)." ".tgtdir + exe "silent !".g:GetLatestVimScripts_mv." ".shellescape("plugin/".pname,1)." ".tgtdir endif " helptags step diff --git a/runtime/autoload/gzip.vim b/runtime/autoload/gzip.vim index a6fbe2c336..09f35c95ba 100644 --- a/runtime/autoload/gzip.vim +++ b/runtime/autoload/gzip.vim @@ -1,6 +1,6 @@ " Vim autoload file for editing compressed files. " Maintainer: The Vim Project -" Last Change: 2024 Nov 25 +" Last Change: 2026 Apr 26 " Former Maintainer: Bram Moolenaar " These functions are used by the gzip plugin. @@ -82,13 +82,8 @@ fun gzip#read(cmd) let empty = line("'[") == 1 && line("']") == line("$") let tmp = tempname() let tmpe = tmp . "." . expand(":e") - if exists('*fnameescape') - let tmp_esc = fnameescape(tmp) - let tmpe_esc = fnameescape(tmpe) - else - let tmp_esc = escape(tmp, ' ') - let tmpe_esc = escape(tmpe, ' ') - endif + let tmp_esc = fnameescape(tmp) + let tmpe_esc = fnameescape(tmpe) " write the just read lines to a temp file "'[,']w tmp.gz" execute "silent '[,']w " . tmpe_esc " uncompress the temp file: call system("gzip -dn tmp.gz") @@ -101,22 +96,14 @@ fun gzip#read(cmd) let ok = 1 " delete the compressed lines; remember the line number let l = line("'[") - 1 - if exists(":lockmarks") - lockmarks '[,']d _ - else - '[,']d _ - endif + lockmarks '[,']d _ " read in the uncompressed lines "'[-1r tmp" " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options. setlocal nobin - if exists(":lockmarks") - if empty - execute "silent lockmarks " . l . "r ++edit " . tmp_esc - else - execute "silent lockmarks " . l . "r " . tmp_esc - endif + if empty + execute "silent lockmarks " . l . "r ++edit " . tmp_esc else - execute "silent " . l . "r " . tmp_esc + execute "silent lockmarks " . l . "r " . tmp_esc endif " if buffer became empty, delete trailing blank line @@ -143,11 +130,7 @@ fun gzip#read(cmd) " When uncompressed the whole buffer, do autocommands if ok && empty - if exists('*fnameescape') - let fname = fnameescape(expand("%:r")) - else - let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<") - endif + let fname = fnameescape(expand("%:r")) if filereadable(undofile(expand("%"))) exe "sil rundo " . fnameescape(undofile(expand("%"))) endif @@ -191,8 +174,9 @@ fun gzip#appre(cmd) call s:set_compression(readfile(nm, "b", 1)[0]) endif - " Rename to a weird name to avoid the risk of overwriting another file - let nmt = expand(":p:h") . "/X~=@l9q5" + " Rename to a unique name to avoid the risk of overwriting another file + " or being targeted by a symlink in a shared directory. + let nmt = s:samedir_tempname(nm) let nmte = nmt . "." . expand(":e") if rename(nm, nmte) == 0 if &patchmode != "" && getfsize(nm . &patchmode) == -1 @@ -208,22 +192,27 @@ fun gzip#appre(cmd) endfun " find a file name for the file to be compressed. Use "name" without an -" extension if possible. Otherwise use a weird name to avoid overwriting an -" existing file. +" extension if possible. Otherwise use a unique name to avoid overwriting an +" existing file or following a symlink set up by another user. fun s:tempname(name) let fn = fnamemodify(a:name, ":r") if !filereadable(fn) && !isdirectory(fn) return fn endif - return fnamemodify(a:name, ":p:h") . "/X~=@l9q5" + return s:samedir_tempname(a:name) +endfun + +" Generate an unpredictable file name in the same directory as "name", using +" the random component of tempname() to avoid symlink attacks in shared +" directories (e.g. /tmp). +fun s:samedir_tempname(name) + let tmp = tempname() + return fnamemodify(a:name, ":p:h") . "/" . fnamemodify(tmp, ":h:t") . fnamemodify(tmp, ":t") endfun fun s:escape(name) " shellescape() was added by patch 7.0.111 - if exists("*shellescape") - return shellescape(a:name) - endif - return "'" . a:name . "'" + return shellescape(a:name) endfun " vim: set sw=2 : diff --git a/runtime/autoload/python3complete.vim b/runtime/autoload/python3complete.vim index 3e54433f41..0cbfc02ab9 100644 --- a/runtime/autoload/python3complete.vim +++ b/runtime/autoload/python3complete.vim @@ -14,6 +14,10 @@ " i.e. "import url" " Continue parsing on invalid line?? " +" v 0.10 by Vim project +" * disables importing local modules, unless the global Vim variable +" g:pythoncomplete_allow_import is set to non-zero +" " v 0.9 " * Fixed docstring parsing for classes and functions " * Fixed parsing of *args and **kwargs type arguments @@ -131,12 +135,24 @@ class Completer(object): self.parser = PyParser() def evalsource(self,text,line=0): + # vim is imported locally in vimpy3complete(); re-import here so the + # vim.eval() below works (otherwise NameError, silently caught). + import vim sc = self.parser.parse(text,line) + try: allow_imports = int( + vim.eval("get(g:, 'pythoncomplete_allow_import', 0)")) + except Exception: + allow_imports = 0 src = sc.get_code() dbg("source: %s" % src) try: exec(src,self.compldict) except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1])) for l in sc.locals: + # Executing import/from statements harvested from the buffer runs + # arbitrary package code; only do so when the user opted in. + if not allow_imports and (l.startswith('import') + or l.startswith('from ')): + continue try: exec(l,self.compldict) except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l)) @@ -300,13 +316,11 @@ class Scope(object): def get_code(self): str = "" if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n' - for l in self.locals: - if l.startswith('import'): str += l+'\n' str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n' for sub in self.subscopes: str += sub.get_code() for l in self.locals: - if not l.startswith('import'): str += l+'\n' + if not l.startswith('import') and not l.startswith('from '): str += l+'\n' return str diff --git a/runtime/autoload/pythoncomplete.vim b/runtime/autoload/pythoncomplete.vim index aa28bb721f..b4340f7ae2 100644 --- a/runtime/autoload/pythoncomplete.vim +++ b/runtime/autoload/pythoncomplete.vim @@ -12,6 +12,10 @@ " i.e. "import url" " Continue parsing on invalid line?? " +" v 0.10 by Vim project +" * disables importing local modules, unless the global Vim variable +" g:pythoncomplete_allow_import is set to non-zero +" " v 0.9 " * Fixed docstring parsing for classes and functions " * Fixed parsing of *args and **kwargs type arguments @@ -145,12 +149,24 @@ class Completer(object): self.parser = PyParser() def evalsource(self,text,line=0): + # vim is imported locally in vimcomplete(); re-import here so the + # vim.eval() below works (otherwise NameError, silently caught). + import vim sc = self.parser.parse(text,line) + try: allow_imports = int( + vim.eval("get(g:, 'pythoncomplete_allow_import', 0)")) + except Exception: + allow_imports = 0 src = sc.get_code() dbg("source: %s" % src) try: exec(src) in self.compldict except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1])) for l in sc.locals: + # Executing import/from statements harvested from the buffer runs + # arbitrary package code; only do so when the user opted in. + if not allow_imports and (l.startswith('import') + or l.startswith('from ')): + continue try: exec(l) in self.compldict except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l)) @@ -315,13 +331,11 @@ class Scope(object): def get_code(self): str = "" if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n' - for l in self.locals: - if l.startswith('import'): str += l+'\n' str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n' for sub in self.subscopes: str += sub.get_code() for l in self.locals: - if not l.startswith('import'): str += l+'\n' + if not l.startswith('import') and not l.startswith('from '): str += l+'\n' return str diff --git a/runtime/autoload/rust.vim b/runtime/autoload/rust.vim index 5ccbf4b382..6510f23be7 100644 --- a/runtime/autoload/rust.vim +++ b/runtime/autoload/rust.vim @@ -1,5 +1,6 @@ " Description: Helper functions for Rust commands/mappings " Last Modified: 2023-09-11 +" 2026 May 20 by Vim project: use correct shellescape() with ! command " For bugs, patches and license go to https://github.com/rust-lang/rust.vim function! rust#Load() @@ -125,7 +126,7 @@ function! s:Run(dict, rustc_args, args) echohl None endif if !v:shell_error - exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)')) + exe '!' . shellescape(exepath,1) . " " . join(map(a:args, 'shellescape(v:val,1)')) endif endfunction diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim index 110327e95b..3c899f85f6 100644 --- a/runtime/autoload/tar.vim +++ b/runtime/autoload/tar.vim @@ -21,6 +21,11 @@ " 2026 Feb 06 by Vim Project: consider 'nowrapscan' (#19333) " 2026 Feb 07 by Vim Project: make the path traversal detection more robust (#19341) " 2026 Apr 06 by Vim Project: fix bugs with lz4 support (#19925) +" 2026 Apr 09 by Vim Project: fix bugs with zstd support (#19930) +" 2026 Apr 09 by Vim Project: fix bug with dotted filename (#19930) +" 2026 Apr 15 by Vim Project: fix more path traversal issues (#19981) +" 2026 Apr 16 by Vim Project: use g:tar_secure in tar#Extract() +" 2026 May 14 by Vim Project: use correct shellescape() call in Vimuntar() " " Contains many ideas from Michael Toren's " @@ -610,118 +615,139 @@ fun! tar#Extract() let &report= repkeep return endif - - let tarball = expand("%") - let tarbase = substitute(tarball,'\..*$','','') + if fname =~ '^[.]\?[.]/' || simplify(fname) =~ '\.\.[/\\]' + call s:Msg('tar#Extract', 'error', "Path Traversal Attack detected, not extracting!") + let &report= repkeep + return + endif + if has("unix") + if fname =~ '^/' + call s:Msg('tar#Extract', 'error', "Path Traversal Attack detected, not extracting!") + let &report= repkeep + return + endif + else + if fname =~ '^\%(\a:[\\/]\|[\\/]\)' + call s:Msg('tar#Extract', 'error', "Path Traversal Attack detected, not extracting!") + let &report= repkeep + return + endif + endif let extractcmd= s:WinPath(g:tar_extractcmd) - if filereadable(tarbase.".tar") - call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname)) + let tarball = expand("%") + if !filereadable(tarball) + let &report= repkeep + return + endif + + if tarball =~# "\.tar$" + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ". fname endif - elseif filereadable(tarbase.".tgz") + elseif tarball =~# "\.tgz$" let extractcmd= substitute(extractcmd,"-","-z","") - call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tgz {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tar.gz") + elseif tarball =~# "\.tar\.gz$" let extractcmd= substitute(extractcmd,"-","-z","") - call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.gz {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tbz") + elseif tarball =~# "\.tbz$" let extractcmd= substitute(extractcmd,"-","-j","") - call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tbz {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tar.bz2") + elseif tarball =~# "\.tar\.bz2$" let extractcmd= substitute(extractcmd,"-","-j","") - call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz2 {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tar.bz3") + elseif tarball =~# "\.tar\.bz3$" let extractcmd= substitute(extractcmd,"-","-j","") - call system(extractcmd." ".shellescape(tarbase).".tar.bz3 ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz3 {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".txz") + elseif tarball =~# "\.txz$" let extractcmd= substitute(extractcmd,"-","-J","") - call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.txz {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tar.xz") + elseif tarball =~# "\.tar\.xz$" let extractcmd= substitute(extractcmd,"-","-J","") - call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.xz {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tzst") - let extractcmd= substitute(extractcmd,"-","--zstd","") - call system(extractcmd." ".shellescape(tarbase).".tzst ".shellescape(fname)) + elseif tarball =~# "\.tzst$" + let extractcmd= substitute(extractcmd,"-","--zstd -","") + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tzst {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tar.zst") - let extractcmd= substitute(extractcmd,"-","--zstd","") - call system(extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname)) + elseif tarball =~# "\.tar\.zst$" + let extractcmd= substitute(extractcmd,"-","--zstd -","") + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.zst {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tlz4") + elseif tarball =~# "\.tlz4$" if has("linux") let extractcmd= substitute(extractcmd,"-","-I lz4 -","") endif - call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tlz4 {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif - elseif filereadable(tarbase.".tar.lz4") + elseif tarball =~# "\.tar\.lz4$" if has("linux") let extractcmd= substitute(extractcmd,"-","-I lz4 -","") endif - call system(extractcmd." ".shellescape(tarbase).".tar.lz4 ".shellescape(fname)) + call system(extractcmd." ".shellescape(tarball)." ".g:tar_secure.shellescape(fname)) if v:shell_error != 0 - call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.lz4 {fname}: failed!") + call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarball} {fname}: failed!") else echo "***note*** successfully extracted ".fname endif @@ -807,9 +833,9 @@ fun! tar#Vimuntar(...) " if necessary, decompress the tarball; then, extract it if tartail =~ '\.tgz' if executable("gunzip") - silent exe "!gunzip ".shellescape(tartail) + silent exe "!gunzip ".shellescape(tartail, 1) elseif executable("gzip") - silent exe "!gzip -d ".shellescape(tartail) + silent exe "!gzip -d ".shellescape(tartail, 1) else echoerr "unable to decompress<".tartail."> on this system" if simplify(curdir) != simplify(tarhome) diff --git a/runtime/autoload/tohtml.vim b/runtime/autoload/tohtml.vim index d2722a4021..054deabcba 100644 --- a/runtime/autoload/tohtml.vim +++ b/runtime/autoload/tohtml.vim @@ -1,882 +1,886 @@ -" Vim autoload file for the tohtml plugin. -" Maintainer: Ben Fritz -" Last Change: 2023 Sep 03 -" -" Additional contributors: -" -" Original by Bram Moolenaar -" Diff2HTML() added by Christian Brabandt -" -" See Mercurial change logs for more! +vim9script +# Vim autoload file for the tohtml plugin. +# Maintainer: Ben Fritz +# Last Change: 2026-05-22 +# +# Additional contributors: +# +# Original by Bram Moolenaar +# Diff2HTML() added by Christian Brabandt +# Converted to Vim9 by Mao-Yining Vim PR #19915 +# +# See git change logs for more! -" this file uses line continuations -let s:cpo_sav = &cpo -set cpo&vim +# Automatically find charsets from all encodings supported natively by Vim. With +# the 8bit- and 2byte- prefixes, Vim can actually support more encodings than +# this. Let the user specify these however since they won't be supported on +# every system. +# +# Note, not all of Vim's supported encodings have a charset to use. +# +# Names in this list are from: +# http://www.iana.org/assignments/character-sets +# export const encoding_to_charset: {{{ +export const encoding_to_charset = { + 'latin1': 'ISO-8859-1', + 'iso-8859-2': 'ISO-8859-2', + 'iso-8859-3': 'ISO-8859-3', + 'iso-8859-4': 'ISO-8859-4', + 'iso-8859-5': 'ISO-8859-5', + 'iso-8859-6': 'ISO-8859-6', + 'iso-8859-7': 'ISO-8859-7', + 'iso-8859-8': 'ISO-8859-8', + 'iso-8859-9': 'ISO-8859-9', + 'iso-8859-10': '', + 'iso-8859-13': 'ISO-8859-13', + 'iso-8859-14': '', + 'iso-8859-15': 'ISO-8859-15', + 'koi8-r': 'KOI8-R', + 'koi8-u': 'KOI8-U', + 'macroman': 'macintosh', + 'cp437': '', + 'cp775': '', + 'cp850': '', + 'cp852': '', + 'cp855': '', + 'cp857': '', + 'cp860': '', + 'cp861': '', + 'cp862': '', + 'cp863': '', + 'cp865': '', + 'cp866': 'IBM866', + 'cp869': '', + 'cp874': '', + 'cp1250': 'windows-1250', + 'cp1251': 'windows-1251', + 'cp1253': 'windows-1253', + 'cp1254': 'windows-1254', + 'cp1255': 'windows-1255', + 'cp1256': 'windows-1256', + 'cp1257': 'windows-1257', + 'cp1258': 'windows-1258', + 'euc-jp': 'EUC-JP', + 'sjis': 'Shift_JIS', + 'cp932': 'Shift_JIS', + 'cp949': '', + 'euc-kr': 'EUC-KR', + 'cp936': 'GBK', + 'euc-cn': 'GB2312', + 'big5': 'Big5', + 'cp950': 'Big5', + 'utf-8': 'UTF-8', + 'ucs-2': 'UTF-8', + 'ucs-2le': 'UTF-8', + 'utf-16': 'UTF-8', + 'utf-16le': 'UTF-8', + 'ucs-4': 'UTF-8', + 'ucs-4le': 'UTF-8', +} -" Automatically find charsets from all encodings supported natively by Vim. With -" the 8bit- and 2byte- prefixes, Vim can actually support more encodings than -" this. Let the user specify these however since they won't be supported on -" every system. -" -" Note, not all of Vim's supported encodings have a charset to use. -" -" Names in this list are from: -" http://www.iana.org/assignments/character-sets -" g:tohtml#encoding_to_charset: {{{ -let g:tohtml#encoding_to_charset = { - \ 'latin1' : 'ISO-8859-1', - \ 'iso-8859-2' : 'ISO-8859-2', - \ 'iso-8859-3' : 'ISO-8859-3', - \ 'iso-8859-4' : 'ISO-8859-4', - \ 'iso-8859-5' : 'ISO-8859-5', - \ 'iso-8859-6' : 'ISO-8859-6', - \ 'iso-8859-7' : 'ISO-8859-7', - \ 'iso-8859-8' : 'ISO-8859-8', - \ 'iso-8859-9' : 'ISO-8859-9', - \ 'iso-8859-10' : '', - \ 'iso-8859-13' : 'ISO-8859-13', - \ 'iso-8859-14' : '', - \ 'iso-8859-15' : 'ISO-8859-15', - \ 'koi8-r' : 'KOI8-R', - \ 'koi8-u' : 'KOI8-U', - \ 'macroman' : 'macintosh', - \ 'cp437' : '', - \ 'cp775' : '', - \ 'cp850' : '', - \ 'cp852' : '', - \ 'cp855' : '', - \ 'cp857' : '', - \ 'cp860' : '', - \ 'cp861' : '', - \ 'cp862' : '', - \ 'cp863' : '', - \ 'cp865' : '', - \ 'cp866' : 'IBM866', - \ 'cp869' : '', - \ 'cp874' : '', - \ 'cp1250' : 'windows-1250', - \ 'cp1251' : 'windows-1251', - \ 'cp1253' : 'windows-1253', - \ 'cp1254' : 'windows-1254', - \ 'cp1255' : 'windows-1255', - \ 'cp1256' : 'windows-1256', - \ 'cp1257' : 'windows-1257', - \ 'cp1258' : 'windows-1258', - \ 'euc-jp' : 'EUC-JP', - \ 'sjis' : 'Shift_JIS', - \ 'cp932' : 'Shift_JIS', - \ 'cp949' : '', - \ 'euc-kr' : 'EUC-KR', - \ 'cp936' : 'GBK', - \ 'euc-cn' : 'GB2312', - \ 'big5' : 'Big5', - \ 'cp950' : 'Big5', - \ 'utf-8' : 'UTF-8', - \ 'ucs-2' : 'UTF-8', - \ 'ucs-2le' : 'UTF-8', - \ 'utf-16' : 'UTF-8', - \ 'utf-16le' : 'UTF-8', - \ 'ucs-4' : 'UTF-8', - \ 'ucs-4le' : 'UTF-8', - \ } -lockvar g:tohtml#encoding_to_charset -" Notes: -" 1. All UCS/UTF are converted to UTF-8 because it is much better supported -" 2. Any blank spaces are there because Vim supports it but at least one major -" web browser does not according to http://wiki.whatwg.org/wiki/Web_Encodings. -" }}} +# Notes: +# 1. All UCS/UTF are converted to UTF-8 because it is much better supported +# 2. Any blank spaces are there because Vim supports it but at least one major +# web browser does not according to http://wiki.whatwg.org/wiki/Web_Encodings. +# }}} -" Only automatically find encodings supported natively by Vim, let the user -" specify the encoding if it's not natively supported. This function is only -" used when the user specifies the charset, they better know what they are -" doing! -" -" Names in this list are from: -" http://www.iana.org/assignments/character-sets -" g:tohtml#charset_to_encoding: {{{ -let g:tohtml#charset_to_encoding = { - \ 'iso_8859-1:1987' : 'latin1', - \ 'iso-ir-100' : 'latin1', - \ 'iso_8859-1' : 'latin1', - \ 'iso-8859-1' : 'latin1', - \ 'latin1' : 'latin1', - \ 'l1' : 'latin1', - \ 'ibm819' : 'latin1', - \ 'cp819' : 'latin1', - \ 'csisolatin1' : 'latin1', - \ 'iso_8859-2:1987' : 'iso-8859-2', - \ 'iso-ir-101' : 'iso-8859-2', - \ 'iso_8859-2' : 'iso-8859-2', - \ 'iso-8859-2' : 'iso-8859-2', - \ 'latin2' : 'iso-8859-2', - \ 'l2' : 'iso-8859-2', - \ 'csisolatin2' : 'iso-8859-2', - \ 'iso_8859-3:1988' : 'iso-8859-3', - \ 'iso-ir-109' : 'iso-8859-3', - \ 'iso_8859-3' : 'iso-8859-3', - \ 'iso-8859-3' : 'iso-8859-3', - \ 'latin3' : 'iso-8859-3', - \ 'l3' : 'iso-8859-3', - \ 'csisolatin3' : 'iso-8859-3', - \ 'iso_8859-4:1988' : 'iso-8859-4', - \ 'iso-ir-110' : 'iso-8859-4', - \ 'iso_8859-4' : 'iso-8859-4', - \ 'iso-8859-4' : 'iso-8859-4', - \ 'latin4' : 'iso-8859-4', - \ 'l4' : 'iso-8859-4', - \ 'csisolatin4' : 'iso-8859-4', - \ 'iso_8859-5:1988' : 'iso-8859-5', - \ 'iso-ir-144' : 'iso-8859-5', - \ 'iso_8859-5' : 'iso-8859-5', - \ 'iso-8859-5' : 'iso-8859-5', - \ 'cyrillic' : 'iso-8859-5', - \ 'csisolatincyrillic' : 'iso-8859-5', - \ 'iso_8859-6:1987' : 'iso-8859-6', - \ 'iso-ir-127' : 'iso-8859-6', - \ 'iso_8859-6' : 'iso-8859-6', - \ 'iso-8859-6' : 'iso-8859-6', - \ 'ecma-114' : 'iso-8859-6', - \ 'asmo-708' : 'iso-8859-6', - \ 'arabic' : 'iso-8859-6', - \ 'csisolatinarabic' : 'iso-8859-6', - \ 'iso_8859-7:1987' : 'iso-8859-7', - \ 'iso-ir-126' : 'iso-8859-7', - \ 'iso_8859-7' : 'iso-8859-7', - \ 'iso-8859-7' : 'iso-8859-7', - \ 'elot_928' : 'iso-8859-7', - \ 'ecma-118' : 'iso-8859-7', - \ 'greek' : 'iso-8859-7', - \ 'greek8' : 'iso-8859-7', - \ 'csisolatingreek' : 'iso-8859-7', - \ 'iso_8859-8:1988' : 'iso-8859-8', - \ 'iso-ir-138' : 'iso-8859-8', - \ 'iso_8859-8' : 'iso-8859-8', - \ 'iso-8859-8' : 'iso-8859-8', - \ 'hebrew' : 'iso-8859-8', - \ 'csisolatinhebrew' : 'iso-8859-8', - \ 'iso_8859-9:1989' : 'iso-8859-9', - \ 'iso-ir-148' : 'iso-8859-9', - \ 'iso_8859-9' : 'iso-8859-9', - \ 'iso-8859-9' : 'iso-8859-9', - \ 'latin5' : 'iso-8859-9', - \ 'l5' : 'iso-8859-9', - \ 'csisolatin5' : 'iso-8859-9', - \ 'iso-8859-10' : 'iso-8859-10', - \ 'iso-ir-157' : 'iso-8859-10', - \ 'l6' : 'iso-8859-10', - \ 'iso_8859-10:1992' : 'iso-8859-10', - \ 'csisolatin6' : 'iso-8859-10', - \ 'latin6' : 'iso-8859-10', - \ 'iso-8859-13' : 'iso-8859-13', - \ 'iso-8859-14' : 'iso-8859-14', - \ 'iso-ir-199' : 'iso-8859-14', - \ 'iso_8859-14:1998' : 'iso-8859-14', - \ 'iso_8859-14' : 'iso-8859-14', - \ 'latin8' : 'iso-8859-14', - \ 'iso-celtic' : 'iso-8859-14', - \ 'l8' : 'iso-8859-14', - \ 'iso-8859-15' : 'iso-8859-15', - \ 'iso_8859-15' : 'iso-8859-15', - \ 'latin-9' : 'iso-8859-15', - \ 'koi8-r' : 'koi8-r', - \ 'cskoi8r' : 'koi8-r', - \ 'koi8-u' : 'koi8-u', - \ 'macintosh' : 'macroman', - \ 'mac' : 'macroman', - \ 'csmacintosh' : 'macroman', - \ 'ibm437' : 'cp437', - \ 'cp437' : 'cp437', - \ '437' : 'cp437', - \ 'cspc8codepage437' : 'cp437', - \ 'ibm775' : 'cp775', - \ 'cp775' : 'cp775', - \ 'cspc775baltic' : 'cp775', - \ 'ibm850' : 'cp850', - \ 'cp850' : 'cp850', - \ '850' : 'cp850', - \ 'cspc850multilingual' : 'cp850', - \ 'ibm852' : 'cp852', - \ 'cp852' : 'cp852', - \ '852' : 'cp852', - \ 'cspcp852' : 'cp852', - \ 'ibm855' : 'cp855', - \ 'cp855' : 'cp855', - \ '855' : 'cp855', - \ 'csibm855' : 'cp855', - \ 'ibm857' : 'cp857', - \ 'cp857' : 'cp857', - \ '857' : 'cp857', - \ 'csibm857' : 'cp857', - \ 'ibm860' : 'cp860', - \ 'cp860' : 'cp860', - \ '860' : 'cp860', - \ 'csibm860' : 'cp860', - \ 'ibm861' : 'cp861', - \ 'cp861' : 'cp861', - \ '861' : 'cp861', - \ 'cp-is' : 'cp861', - \ 'csibm861' : 'cp861', - \ 'ibm862' : 'cp862', - \ 'cp862' : 'cp862', - \ '862' : 'cp862', - \ 'cspc862latinhebrew' : 'cp862', - \ 'ibm863' : 'cp863', - \ 'cp863' : 'cp863', - \ '863' : 'cp863', - \ 'csibm863' : 'cp863', - \ 'ibm865' : 'cp865', - \ 'cp865' : 'cp865', - \ '865' : 'cp865', - \ 'csibm865' : 'cp865', - \ 'ibm866' : 'cp866', - \ 'cp866' : 'cp866', - \ '866' : 'cp866', - \ 'csibm866' : 'cp866', - \ 'ibm869' : 'cp869', - \ 'cp869' : 'cp869', - \ '869' : 'cp869', - \ 'cp-gr' : 'cp869', - \ 'csibm869' : 'cp869', - \ 'windows-1250' : 'cp1250', - \ 'windows-1251' : 'cp1251', - \ 'windows-1253' : 'cp1253', - \ 'windows-1254' : 'cp1254', - \ 'windows-1255' : 'cp1255', - \ 'windows-1256' : 'cp1256', - \ 'windows-1257' : 'cp1257', - \ 'windows-1258' : 'cp1258', - \ 'extended_unix_code_packed_format_for_japanese' : 'euc-jp', - \ 'cseucpkdfmtjapanese' : 'euc-jp', - \ 'euc-jp' : 'euc-jp', - \ 'shift_jis' : 'sjis', - \ 'ms_kanji' : 'sjis', - \ 'sjis' : 'sjis', - \ 'csshiftjis' : 'sjis', - \ 'ibm-thai' : 'cp874', - \ 'csibmthai' : 'cp874', - \ 'ks_c_5601-1987' : 'cp949', - \ 'iso-ir-149' : 'cp949', - \ 'ks_c_5601-1989' : 'cp949', - \ 'ksc_5601' : 'cp949', - \ 'korean' : 'cp949', - \ 'csksc56011987' : 'cp949', - \ 'euc-kr' : 'euc-kr', - \ 'cseuckr' : 'euc-kr', - \ 'gbk' : 'cp936', - \ 'cp936' : 'cp936', - \ 'ms936' : 'cp936', - \ 'windows-936' : 'cp936', - \ 'gb_2312-80' : 'euc-cn', - \ 'iso-ir-58' : 'euc-cn', - \ 'chinese' : 'euc-cn', - \ 'csiso58gb231280' : 'euc-cn', - \ 'big5' : 'big5', - \ 'csbig5' : 'big5', - \ 'utf-8' : 'utf-8', - \ 'iso-10646-ucs-2' : 'ucs-2', - \ 'csunicode' : 'ucs-2', - \ 'utf-16' : 'utf-16', - \ 'utf-16be' : 'utf-16', - \ 'utf-16le' : 'utf-16le', - \ 'utf-32' : 'ucs-4', - \ 'utf-32be' : 'ucs-4', - \ 'utf-32le' : 'ucs-4le', - \ 'iso-10646-ucs-4' : 'ucs-4', - \ 'csucs4' : 'ucs-4' - \ } -lockvar g:tohtml#charset_to_encoding -"}}} +# Only automatically find encodings supported natively by Vim, let the user +# specify the encoding if it's not natively supported. This function is only +# used when the user specifies the charset, they better know what they are +# doing! +# +# Names in this list are from: +# http://www.iana.org/assignments/character-sets +# export const charset_to_encoding: {{{ +export const charset_to_encoding = { + 'iso_8859-1:1987': 'latin1', + 'iso-ir-100': 'latin1', + 'iso_8859-1': 'latin1', + 'iso-8859-1': 'latin1', + 'latin1': 'latin1', + 'l1': 'latin1', + 'ibm819': 'latin1', + 'cp819': 'latin1', + 'csisolatin1': 'latin1', + 'iso_8859-2:1987': 'iso-8859-2', + 'iso-ir-101': 'iso-8859-2', + 'iso_8859-2': 'iso-8859-2', + 'iso-8859-2': 'iso-8859-2', + 'latin2': 'iso-8859-2', + 'l2': 'iso-8859-2', + 'csisolatin2': 'iso-8859-2', + 'iso_8859-3:1988': 'iso-8859-3', + 'iso-ir-109': 'iso-8859-3', + 'iso_8859-3': 'iso-8859-3', + 'iso-8859-3': 'iso-8859-3', + 'latin3': 'iso-8859-3', + 'l3': 'iso-8859-3', + 'csisolatin3': 'iso-8859-3', + 'iso_8859-4:1988': 'iso-8859-4', + 'iso-ir-110': 'iso-8859-4', + 'iso_8859-4': 'iso-8859-4', + 'iso-8859-4': 'iso-8859-4', + 'latin4': 'iso-8859-4', + 'l4': 'iso-8859-4', + 'csisolatin4': 'iso-8859-4', + 'iso_8859-5:1988': 'iso-8859-5', + 'iso-ir-144': 'iso-8859-5', + 'iso_8859-5': 'iso-8859-5', + 'iso-8859-5': 'iso-8859-5', + 'cyrillic': 'iso-8859-5', + 'csisolatincyrillic': 'iso-8859-5', + 'iso_8859-6:1987': 'iso-8859-6', + 'iso-ir-127': 'iso-8859-6', + 'iso_8859-6': 'iso-8859-6', + 'iso-8859-6': 'iso-8859-6', + 'ecma-114': 'iso-8859-6', + 'asmo-708': 'iso-8859-6', + 'arabic': 'iso-8859-6', + 'csisolatinarabic': 'iso-8859-6', + 'iso_8859-7:1987': 'iso-8859-7', + 'iso-ir-126': 'iso-8859-7', + 'iso_8859-7': 'iso-8859-7', + 'iso-8859-7': 'iso-8859-7', + 'elot_928': 'iso-8859-7', + 'ecma-118': 'iso-8859-7', + 'greek': 'iso-8859-7', + 'greek8': 'iso-8859-7', + 'csisolatingreek': 'iso-8859-7', + 'iso_8859-8:1988': 'iso-8859-8', + 'iso-ir-138': 'iso-8859-8', + 'iso_8859-8': 'iso-8859-8', + 'iso-8859-8': 'iso-8859-8', + 'hebrew': 'iso-8859-8', + 'csisolatinhebrew': 'iso-8859-8', + 'iso_8859-9:1989': 'iso-8859-9', + 'iso-ir-148': 'iso-8859-9', + 'iso_8859-9': 'iso-8859-9', + 'iso-8859-9': 'iso-8859-9', + 'latin5': 'iso-8859-9', + 'l5': 'iso-8859-9', + 'csisolatin5': 'iso-8859-9', + 'iso-8859-10': 'iso-8859-10', + 'iso-ir-157': 'iso-8859-10', + 'l6': 'iso-8859-10', + 'iso_8859-10:1992': 'iso-8859-10', + 'csisolatin6': 'iso-8859-10', + 'latin6': 'iso-8859-10', + 'iso-8859-13': 'iso-8859-13', + 'iso-8859-14': 'iso-8859-14', + 'iso-ir-199': 'iso-8859-14', + 'iso_8859-14:1998': 'iso-8859-14', + 'iso_8859-14': 'iso-8859-14', + 'latin8': 'iso-8859-14', + 'iso-celtic': 'iso-8859-14', + 'l8': 'iso-8859-14', + 'iso-8859-15': 'iso-8859-15', + 'iso_8859-15': 'iso-8859-15', + 'latin-9': 'iso-8859-15', + 'koi8-r': 'koi8-r', + 'cskoi8r': 'koi8-r', + 'koi8-u': 'koi8-u', + 'macintosh': 'macroman', + 'mac': 'macroman', + 'csmacintosh': 'macroman', + 'ibm437': 'cp437', + 'cp437': 'cp437', + '437': 'cp437', + 'cspc8codepage437': 'cp437', + 'ibm775': 'cp775', + 'cp775': 'cp775', + 'cspc775baltic': 'cp775', + 'ibm850': 'cp850', + 'cp850': 'cp850', + '850': 'cp850', + 'cspc850multilingual': 'cp850', + 'ibm852': 'cp852', + 'cp852': 'cp852', + '852': 'cp852', + 'cspcp852': 'cp852', + 'ibm855': 'cp855', + 'cp855': 'cp855', + '855': 'cp855', + 'csibm855': 'cp855', + 'ibm857': 'cp857', + 'cp857': 'cp857', + '857': 'cp857', + 'csibm857': 'cp857', + 'ibm860': 'cp860', + 'cp860': 'cp860', + '860': 'cp860', + 'csibm860': 'cp860', + 'ibm861': 'cp861', + 'cp861': 'cp861', + '861': 'cp861', + 'cp-is': 'cp861', + 'csibm861': 'cp861', + 'ibm862': 'cp862', + 'cp862': 'cp862', + '862': 'cp862', + 'cspc862latinhebrew': 'cp862', + 'ibm863': 'cp863', + 'cp863': 'cp863', + '863': 'cp863', + 'csibm863': 'cp863', + 'ibm865': 'cp865', + 'cp865': 'cp865', + '865': 'cp865', + 'csibm865': 'cp865', + 'ibm866': 'cp866', + 'cp866': 'cp866', + '866': 'cp866', + 'csibm866': 'cp866', + 'ibm869': 'cp869', + 'cp869': 'cp869', + '869': 'cp869', + 'cp-gr': 'cp869', + 'csibm869': 'cp869', + 'windows-1250': 'cp1250', + 'windows-1251': 'cp1251', + 'windows-1253': 'cp1253', + 'windows-1254': 'cp1254', + 'windows-1255': 'cp1255', + 'windows-1256': 'cp1256', + 'windows-1257': 'cp1257', + 'windows-1258': 'cp1258', + 'extended_unix_code_packed_format_for_japanese': 'euc-jp', + 'cseucpkdfmtjapanese': 'euc-jp', + 'euc-jp': 'euc-jp', + 'shift_jis': 'sjis', + 'ms_kanji': 'sjis', + 'sjis': 'sjis', + 'csshiftjis': 'sjis', + 'ibm-thai': 'cp874', + 'csibmthai': 'cp874', + 'ks_c_5601-1987': 'cp949', + 'iso-ir-149': 'cp949', + 'ks_c_5601-1989': 'cp949', + 'ksc_5601': 'cp949', + 'korean': 'cp949', + 'csksc56011987': 'cp949', + 'euc-kr': 'euc-kr', + 'cseuckr': 'euc-kr', + 'gbk': 'cp936', + 'cp936': 'cp936', + 'ms936': 'cp936', + 'windows-936': 'cp936', + 'gb_2312-80': 'euc-cn', + 'iso-ir-58': 'euc-cn', + 'chinese': 'euc-cn', + 'csiso58gb231280': 'euc-cn', + 'big5': 'big5', + 'csbig5': 'big5', + 'utf-8': 'utf-8', + 'iso-10646-ucs-2': 'ucs-2', + 'csunicode': 'ucs-2', + 'utf-16': 'utf-16', + 'utf-16be': 'utf-16', + 'utf-16le': 'utf-16le', + 'utf-32': 'ucs-4', + 'utf-32be': 'ucs-4', + 'utf-32le': 'ucs-4le', + 'iso-10646-ucs-4': 'ucs-4', + 'csucs4': 'ucs-4' +} +#}}} -func! tohtml#Convert2HTML(line1, line2) "{{{ - let s:settings = tohtml#GetUserSettings() +var settings: dict - if !&diff || s:settings.diff_one_file "{{{ - if a:line2 >= a:line1 - let g:html_start_line = a:line1 - let g:html_end_line = a:line2 +export def Convert2HTML(line1: number, line2: number) #{{{ + settings = GetUserSettings() + + if !&diff || settings.diff_one_file #{{{ + if line2 >= line1 + g:html_start_line = line1 + g:html_end_line = line2 else - let g:html_start_line = a:line2 - let g:html_end_line = a:line1 + g:html_start_line = line2 + g:html_end_line = line1 endif - runtime syntax/2html.vim "}}} - else "{{{ - let win_list = [] - let buf_list = [] - windo if &diff | call add(win_list, winbufnr(0)) | endif - let s:settings.whole_filler = 1 - let g:html_diff_win_num = 0 + runtime syntax/2html.vim #}}} + else #{{{ + var win_list = range(1, winnr('$')) + ->filter((_, w) => getwinvar(w, '&diff')) + ->mapnew((_, w) => winbufnr(w)) + var buf_list: list + settings.whole_filler = 1 + g:html_diff_win_num = 0 for window in win_list - " switch to the next buffer to convert - exe ":" .. bufwinnr(window) .. "wincmd w" + # switch to the next buffer to convert + win_gotoid(bufwinid(window)) - " figure out whether current charset and encoding will work, if not - " default to UTF-8 + # figure out whether current charset and encoding will work, if not + # default to UTF-8 if !exists('g:html_use_encoding') && - \ (((&l:fileencoding=='' || (&l:buftype!='' && &l:buftype!=?'help')) - \ && &encoding!=?s:settings.vim_encoding) - \ || &l:fileencoding!='' && &l:fileencoding!=?s:settings.vim_encoding) + (((&l:fileencoding == '' || (&l:buftype != '' && &l:buftype !=? 'help')) + && &encoding !=? settings.vim_encoding) + || &l:fileencoding != '' && &l:fileencoding !=? settings.vim_encoding) echohl WarningMsg echomsg "TOhtml: mismatched file encodings in Diff buffers, using UTF-8" echohl None - let s:settings.vim_encoding = 'utf-8' - let s:settings.encoding = 'UTF-8' + settings.vim_encoding = 'utf-8' + settings.encoding = 'UTF-8' endif - " set up for diff-mode conversion - let g:html_start_line = 1 - let g:html_end_line = line('$') - let g:html_diff_win_num += 1 + # set up for diff-mode conversion + g:html_start_line = 1 + g:html_end_line = line('$') + g:html_diff_win_num += 1 - " convert this file + # convert this file runtime syntax/2html.vim - " remember the HTML buffer for later combination - call add(buf_list, bufnr('%')) + # remember the HTML buffer for later combination + add(buf_list, bufnr('%')) endfor unlet g:html_diff_win_num - call tohtml#Diff2HTML(win_list, buf_list) - endif "}}} - + Diff2HTML(win_list, buf_list) + endif #}}} unlet g:html_start_line unlet g:html_end_line - unlet s:settings -endfunc "}}} + settings = null_dict +enddef #}}} -func! tohtml#Diff2HTML(win_list, buf_list) "{{{ - let xml_line = "" - let tag_close = '>' +export def Diff2HTML(win_list: list, buf_list: list) #{{{ + var xml_line = '' + var tag_close = '>' - let s:old_paste = &paste + var old_paste = &paste set paste - let s:old_magic = &magic + var old_magic = &magic set magic - let html = [] - if !s:settings.no_doc - if s:settings.use_xhtml - if s:settings.encoding != "" - let xml_line = "" + var html = [] + var style: list + var body_line: string + var body_end_line: string + var body_line_num: number + var html5 = 0 + if !settings.no_doc + if settings.use_xhtml + if settings.encoding != '' + xml_line = "" else - let xml_line = "" + xml_line = "" endif - let tag_close = ' />' + tag_close = ' />' endif - let style = [s:settings.use_xhtml ? "" : '-->'] - let body_line = '' + style = [settings.use_xhtml ? '' : '-->'] - let s:html5 = 0 - if s:settings.use_xhtml - call add(html, xml_line) + if settings.use_xhtml + add(html, xml_line) endif - if s:settings.use_xhtml - call add(html, "") - call add(html, '') - elseif s:settings.use_css && !s:settings.no_pre - call add(html, "") - call add(html, '') - let s:html5 = 1 + if settings.use_xhtml + add(html, "") + add(html, '') + elseif settings.use_css && !settings.no_pre + add(html, "") + add(html, '') + html5 = 1 else - call add(html, '') - call add(html, '') + add(html, '') + add(html, '') endif - call add(html, '') + add(html, '') - " include encoding as close to the top as possible, but only if not already - " contained in XML information - if s:settings.encoding != "" && !s:settings.use_xhtml - if s:html5 - call add(html, 'diff') - call add(html, 'diff') + add(html, $'') - let body_line_num = len(html) - call add(html, '') + add(html, '') + body_line_num = len(html) + add(html, '') endif - call add(html, "") + add(html, "
") - call add(html, '') - for buf in a:win_list - call add(html, '') + add(html, '') + for buf in win_list + add(html, '') endfor - call add(html, '') + add(html, '') - let diff_style_start = 0 - let insert_index = 0 + var diff_style_start = 0 + var insert_index = 0 - for buf in a:buf_list - let temp = [] - exe bufwinnr(buf) .. 'wincmd w' + for buf in buf_list + var temp = [] + win_gotoid(bufwinid(buf)) - " If text is folded because of user foldmethod settings, etc. we don't want - " to act on everything in a fold by mistake. + # If text is folded because of user foldmethod settings, etc. we don't want + # to act on everything in a fold by mistake. setlocal nofoldenable - " When not using CSS or when using xhtml, the line can be important. - " Assume it will be the same for all buffers and grab it from the first - " buffer. Similarly, need to grab the body end line as well. - if !s:settings.no_doc + # When not using CSS or when using xhtml, the line can be important. + # Assume it will be the same for all buffers and grab it from the first + # buffer. Similarly, need to grab the body end line as well. + if !settings.no_doc if body_line == '' - 1 - call search('', 'b') - let s:body_end_line = getline('.') + :1 + search('', 'b') + body_end_line = getline('.') endif - " Grab the style information. Some of this will be duplicated so only insert - " it if it's not already there. {{{ - 1 - let style_start = search('^') - 1 - let style_end = search('^') + # Grab the style information. Some of this will be duplicated so only insert + # it if it's not already there. {{{ + :1 + var style_start = search('^') + :1 + var style_end = search('^') if style_start > 0 && style_end > 0 - let buf_styles = getline(style_start + 1, style_end - 1) + var buf_styles = getline(style_start + 1, style_end - 1) for a_style in buf_styles if index(style, a_style) == -1 if diff_style_start == 0 if a_style =~ '\\_s\+.*id='oneCharWidth'.*\_s\+.*id='oneInputWidth'.*\_s\+.*id='oneEmWidth'\)\?\zs/d_ - $ - ??,$d_ - elseif !s:settings.no_modeline - " remove modeline from source files if it is included and we haven't deleted - " due to removing html footer already - $d + # Delete those parts that are not needed so we can include the rest into the + # resulting table. + :1,/^\_s\+.*id='oneCharWidth'.*\_s\+.*id='oneInputWidth'.*\_s\+.*id='oneEmWidth'\)\?\zs/d _ + :$ + :??,$d _ + elseif !settings.no_modeline + # remove modeline from source files if it is included and we haven't deleted + # due to removing html footer already + :$d endif - let temp = getline(1,'$') - " clean out id on the main content container because we already set it on - " the table - let temp[0] = substitute(temp[0], " id='vimCodeElement[^']*'", "", "") - " undo deletion of start and end part - " so we can later save the file as valid html - " TODO: restore using grabbed lines if undolevel is 1? - if !s:settings.no_doc + temp = getline(1, '$') + # clean out id on the main content container because we already set it on + # the table + temp[0] = substitute(temp[0], " id='vimCodeElement[^']*'", "", "") + # undo deletion of start and end part + # so we can later save the file as valid html + # TODO: restore using grabbed lines if undolevel is 1? + if !settings.no_doc normal! 2u - elseif !s:settings.no_modeline + elseif !settings.no_modeline normal! u endif - if s:settings.use_css - call add(html, '') + html += temp + add(html, '') - " Close this buffer - " TODO: the comment above says we're going to allow saving the file - " later...but here we discard it? + # Close this buffer + # TODO: the comment above says we're going to allow saving the file + # later...but here we discard it? quit! endfor - if !s:settings.no_doc - let html[body_line_num] = body_line + if !settings.no_doc + html[body_line_num] = body_line endif - call add(html, '') - call add(html, '
'..bufname(buf)..'
' .. bufname(buf) .. '
') - elseif s:settings.use_xhtml - call add(html, '
') + if settings.use_css + add(html, '
') + elseif settings.use_xhtml + add(html, '
') else - call add(html, '
') + add(html, '
') endif - let html += temp - call add(html, '
') - if !s:settings.no_doc - call add(html, s:body_end_line) - call add(html, '') + add(html, '') + add(html, '') + if !settings.no_doc + add(html, body_end_line) + add(html, '') endif - " The generated HTML is admittedly ugly and takes a LONG time to fold. - " Make sure the user doesn't do syntax folding when loading a generated file, - " using a modeline. - if !s:settings.no_modeline - call add(html, '') + # The generated HTML is admittedly ugly and takes a LONG time to fold. + # Make sure the user doesn't do syntax folding when loading a generated file, + # using a modeline. + if !settings.no_modeline + add(html, '') endif - let i = 1 - let name = "Diff" .. (s:settings.use_xhtml ? ".xhtml" : ".html") - " Find an unused file name if current file name is already in use + var i = 1 + var name = "Diff" .. (settings.use_xhtml ? ".xhtml" : ".html") + # Find an unused file name if current file name is already in use while filereadable(name) - let name = substitute(name, '\d*\.x\?html$', '', '') .. i .. '.' .. fnamemodify(copy(name), ":t:e") - let i += 1 + name = substitute(name, '\d*\.x\?html$', '', '') .. i .. '.' .. fnamemodify(copy(name), ":t:e") + i += 1 endwhile - let s:ei_sav = &eventignore + var ei_sav = &eventignore set eventignore+=FileType - exe "topleft new " .. name - let &eventignore=s:ei_sav - unlet s:ei_sav + execute "topleft new" name + &eventignore = ei_sav setlocal modifiable - " just in case some user autocmd creates content in the new buffer, make sure - " it is empty before proceeding - %d + # just in case some user autocmd creates content in the new buffer, make sure + # it is empty before proceeding + deletebufline(bufnr(), 1, '$') - " set the fileencoding to match the charset we'll be using - let &l:fileencoding=s:settings.vim_encoding + # set the fileencoding to match the charset we'll be using + &l:fileencoding = settings.vim_encoding - " According to http://www.w3.org/TR/html4/charset.html#doc-char-set, the byte - " order mark is highly recommend on the web when using multibyte encodings. But, - " it is not a good idea to include it on UTF-8 files. Otherwise, let Vim - " determine when it is actually inserted. - if s:settings.vim_encoding == 'utf-8' + # According to http://www.w3.org/TR/html4/charset.html#doc-char-set, the byte + # order mark is highly recommend on the web when using multibyte encodings. But, + # it is not a good idea to include it on UTF-8 files. Otherwise, let Vim + # determine when it is actually inserted. + if settings.vim_encoding == 'utf-8' setlocal nobomb else setlocal bomb endif - call append(0, html) + append(0, html) - if !s:settings.no_doc + if !settings.no_doc if len(style) > 0 - 1 - let style_start = search('^')-1 + :1 + var style_start = search('^') - 1 - " add required javascript in reverse order so we can just call append again - " and again without adjusting {{{ + # add required javascript in reverse order so we can just call append again + # and again without adjusting {{{ - let s:uses_script = s:settings.dynamic_folds || s:settings.line_ids + var uses_script = settings.dynamic_folds || settings.line_ids - " insert script closing tag if needed - if s:uses_script - call append(style_start, [ - \ '', - \ s:settings.use_xhtml ? '//]]>' : '-->', - \ "" - \ ]) + # insert script closing tag if needed + if uses_script + append(style_start, [ + '', + settings.use_xhtml ? '//]]>' : '-->', + "" + ]) endif - " insert javascript to get IDs from line numbers, and to open a fold before - " jumping to any lines contained therein - if s:settings.line_ids - call append(style_start, [ - \ " /* Always jump to new location even if the line was hidden inside a fold, or", - \ " * we corrected the raw number to a line ID.", - \ " */", - \ " if (lineElem) {", - \ " lineElem.scrollIntoView(true);", - \ " }", - \ " return true;", - \ "}", - \ "if ('onhashchange' in window) {", - \ " window.onhashchange = JumpToLine;", - \ "}" - \ ]) + # insert javascript to get IDs from line numbers, and to open a fold before + # jumping to any lines contained therein + if settings.line_ids + append(style_start, [ + " /* Always jump to new location even if the line was hidden inside a fold, or", + " * we corrected the raw number to a line ID.", + " */", + " if (lineElem) {", + " lineElem.scrollIntoView(true);", + " }", + " return true;", + "}", + "if ('onhashchange' in window) {", + " window.onhashchange = JumpToLine;", + "}" + ]) - if s:settings.dynamic_folds - call append(style_start, [ - \ "", - \ " /* navigate upwards in the DOM tree to open all folds containing the line */", - \ " var node = lineElem;", - \ " while (node && node.id != 'vimCodeElement"..s:settings.id_suffix.."')", - \ " {", - \ " if (node.className == 'closed-fold')", - \ " {", - \ " /* toggle open the fold ID (remove window ID) */", - \ " toggleFold(node.id.substr(4));", - \ " }", - \ " node = node.parentNode;", - \ " }", - \ ]) + if settings.dynamic_folds + append(style_start, [ + "", + " /* navigate upwards in the DOM tree to open all folds containing the line */", + " var node = lineElem;", + " while (node && node.id != 'vimCodeElement" .. settings.id_suffix .. "')", + " {", + " if (node.className == 'closed-fold')", + " {", + " /* toggle open the fold ID (remove window ID) */", + " toggleFold(node.id.substr(4));", + " }", + " node = node.parentNode;", + " }", + ]) endif endif - if s:settings.line_ids - call append(style_start, [ - \ "", - \ "/* function to open any folds containing a jumped-to line before jumping to it */", - \ "function JumpToLine()", - \ "{", - \ " var lineNum;", - \ " lineNum = window.location.hash;", - \ " lineNum = lineNum.substr(1); /* strip off '#' */", - \ "", - \ " if (lineNum.indexOf('L') == -1) {", - \ " lineNum = 'L'+lineNum;", - \ " }", - \ " if (lineNum.indexOf('W') == -1) {", - \ " lineNum = 'W1'+lineNum;", - \ " }", - \ " var lineElem = document.getElementById(lineNum);" - \ ]) + if settings.line_ids + append(style_start, [ + "", + "/* function to open any folds containing a jumped-to line before jumping to it */", + "function JumpToLine()", + "{", + " var lineNum;", + " lineNum = window.location.hash;", + " lineNum = lineNum.substr(1); /* strip off '#' */", + "", + " if (lineNum.indexOf('L') == -1) {", + " lineNum = 'L'+lineNum;", + " }", + " if (lineNum.indexOf('W') == -1) {", + " lineNum = 'W1'+lineNum;", + " }", + " var lineElem = document.getElementById(lineNum);" + ]) endif - " Insert javascript to toggle matching folds open and closed in all windows, - " if dynamic folding is active. - if s:settings.dynamic_folds - call append(style_start, [ - \ " function toggleFold(objID)", - \ " {", - \ " for (win_num = 1; win_num <= "..len(a:buf_list).."; win_num++)", - \ " {", - \ " var fold;", - \ ' fold = document.getElementById("win"+win_num+objID);', - \ " if(fold.className == 'closed-fold')", - \ " {", - \ " fold.className = 'open-fold';", - \ " }", - \ " else if (fold.className == 'open-fold')", - \ " {", - \ " fold.className = 'closed-fold';", - \ " }", - \ " }", - \ " }", - \ ]) + # Insert javascript to toggle matching folds open and closed in all windows, + # if dynamic folding is active. + if settings.dynamic_folds + append(style_start, [ + " function toggleFold(objID)", + " {", + " for (win_num = 1; win_num <= " .. len(buf_list) .. "; win_num++)", + " {", + " var fold;", + ' fold = document.getElementById("win"+win_num+objID);', + " if(fold.className == 'closed-fold')", + " {", + " fold.className = 'open-fold';", + " }", + " else if (fold.className == 'open-fold')", + " {", + " fold.className = 'closed-fold';", + " }", + " }", + " }", + ]) endif - if s:uses_script - " insert script tag if needed - call append(style_start, [ - \ "", - \ s:settings.use_xhtml ? '//", + settings.use_xhtml ? '//']+ - \ style+ - \ [ s:settings.use_xhtml ? '' : '', - \ '' - \]) - endif "}}} + # Insert styles from all the generated html documents and additional styles + # for the table-based layout of the side-by-side diff. The diff should take + # up the full browser window (but not more), and be static in size, + # horizontally scrollable when the lines are too long. Otherwise, the diff + # is pretty useless for really long lines. {{{ + if settings.use_css + append(style_start, + [''] + + style + + [ settings.use_xhtml ? '' : '', + '' + ]) + endif #}}} endif endif - let &paste = s:old_paste - let &magic = s:old_magic -endfunc "}}} + &paste = old_paste + &magic = old_magic +enddef #}}} -" Gets a single user option and sets it in the passed-in Dict, or gives it the -" default value if the option doesn't actually exist. -func! tohtml#GetOption(settings, option, default) "{{{ - if exists('g:html_'..a:option) - let a:settings[a:option] = g:html_{a:option} +# Gets a single user option and sets it in the passed-in Dict, or gives it the +# default value if the option doesn't actually exist. +export def GetOption(_settings: dict, option: string, default: any) #{{{ + _settings[option] = get(g:, $'html_{option}', default) +enddef #}}} + +# returns a Dict containing the values of all user options for 2html, including +# default values for those not given an explicit value by the user. Discards the +# html_ prefix of the option for nicer looking code. +export def GetUserSettings(): dict #{{{ + if !empty(settings) + # just restore the known options if we've already retrieved them + return settings else - let a:settings[a:option] = a:default - endif -endfunc "}}} + # otherwise figure out which options are set + var user_settings = {} -" returns a Dict containing the values of all user options for 2html, including -" default values for those not given an explicit value by the user. Discards the -" html_ prefix of the option for nicer looking code. -func! tohtml#GetUserSettings() "{{{ - if exists('s:settings') - " just restore the known options if we've already retrieved them - return s:settings - else - " otherwise figure out which options are set - let user_settings = {} - - " Define the correct option if the old option name exists and we haven't - " already defined the correct one. + # Define the correct option if the old option name exists and we haven't + # already defined the correct one. if exists('g:use_xhtml') && !exists("g:html_use_xhtml") echohl WarningMsg echomsg "Warning: g:use_xhtml is deprecated, use g:html_use_xhtml" echohl None - let g:html_use_xhtml = g:use_xhtml + g:html_use_xhtml = g:use_xhtml endif - " get current option settings with appropriate defaults {{{ - call tohtml#GetOption(user_settings, 'no_progress', !has("statusline") ) - call tohtml#GetOption(user_settings, 'diff_one_file', 0 ) - call tohtml#GetOption(user_settings, 'number_lines', &number ) - call tohtml#GetOption(user_settings, 'pre_wrap', &wrap ) - call tohtml#GetOption(user_settings, 'use_css', 1 ) - call tohtml#GetOption(user_settings, 'ignore_conceal', 0 ) - call tohtml#GetOption(user_settings, 'ignore_folding', 0 ) - call tohtml#GetOption(user_settings, 'dynamic_folds', 0 ) - call tohtml#GetOption(user_settings, 'no_foldcolumn', user_settings.ignore_folding) - call tohtml#GetOption(user_settings, 'hover_unfold', 0 ) - call tohtml#GetOption(user_settings, 'no_pre', 0 ) - call tohtml#GetOption(user_settings, 'no_doc', 0 ) - call tohtml#GetOption(user_settings, 'no_links', 0 ) - call tohtml#GetOption(user_settings, 'no_modeline', 0 ) - call tohtml#GetOption(user_settings, 'no_invalid', 0 ) - call tohtml#GetOption(user_settings, 'whole_filler', 0 ) - call tohtml#GetOption(user_settings, 'use_xhtml', 0 ) - call tohtml#GetOption(user_settings, 'line_ids', user_settings.number_lines ) - call tohtml#GetOption(user_settings, 'use_input_for_pc', 'none') - " }}} - - " override those settings that need it {{{ + # get current option settings with appropriate defaults {{{ + GetOption(user_settings, 'no_progress', !has("statusline") ) + GetOption(user_settings, 'diff_one_file', 0 ) + GetOption(user_settings, 'number_lines', &number ) + GetOption(user_settings, 'pre_wrap', &wrap ) + GetOption(user_settings, 'use_css', 1 ) + GetOption(user_settings, 'ignore_conceal', 0 ) + GetOption(user_settings, 'ignore_folding', 0 ) + GetOption(user_settings, 'dynamic_folds', 0 ) + GetOption(user_settings, 'no_foldcolumn', user_settings.ignore_folding) + GetOption(user_settings, 'hover_unfold', 0 ) + GetOption(user_settings, 'no_pre', 0 ) + GetOption(user_settings, 'no_doc', 0 ) + GetOption(user_settings, 'no_links', 0 ) + GetOption(user_settings, 'no_modeline', 0 ) + GetOption(user_settings, 'no_invalid', 0 ) + GetOption(user_settings, 'whole_filler', 0 ) + GetOption(user_settings, 'use_xhtml', 0 ) + GetOption(user_settings, 'line_ids', user_settings.number_lines ) + GetOption(user_settings, 'use_input_for_pc', 'none') + # }}} - " hover opening implies dynamic folding + # override those settings that need it {{{ + + # hover opening implies dynamic folding if user_settings.hover_unfold - let user_settings.dynamic_folds = 1 + user_settings.dynamic_folds = 1 endif - " ignore folding overrides dynamic folding + # ignore folding overrides dynamic folding if user_settings.ignore_folding && user_settings.dynamic_folds - let user_settings.dynamic_folds = 0 - let user_settings.hover_unfold = 0 + user_settings.dynamic_folds = 0 + user_settings.hover_unfold = 0 endif - " dynamic folding with no foldcolumn implies hover opens + # dynamic folding with no foldcolumn implies hover opens if user_settings.dynamic_folds && user_settings.no_foldcolumn - let user_settings.hover_unfold = 1 + user_settings.hover_unfold = 1 endif - " dynamic folding implies css + # dynamic folding implies css if user_settings.dynamic_folds - let user_settings.use_css = 1 + user_settings.use_css = 1 else - let user_settings.no_foldcolumn = 1 " won't do anything but for consistency and for the test suite + user_settings.no_foldcolumn = 1 # won't do anything but for consistency and for the test suite endif - " if we're not using CSS we cannot use a pre section because tags - " aren't allowed inside a
 block
+    # if we're not using CSS we cannot use a pre section because  tags
+    # aren't allowed inside a 
 block
     if !user_settings.use_css
-      let user_settings.no_pre = 1
+      user_settings.no_pre = 1
     endif
 
-    " pre_wrap doesn't do anything if not using pre or not using CSS
+    # pre_wrap doesn't do anything if not using pre or not using CSS
     if user_settings.no_pre || !user_settings.use_css
-      let user_settings.pre_wrap = 0
+      user_settings.pre_wrap = 0
     endif
-    "}}}
+    #}}}
 
-    " set up expand_tabs option after all the overrides so we know the
-    " appropriate defaults {{{
+    # set up expand_tabs option after all the overrides so we know the
+    # appropriate defaults #{{{
     if user_settings.no_pre == 0
-      call tohtml#GetOption(user_settings,
-	    \ 'expand_tabs',
-	    \ &expandtab || &ts != 8 || &vts != '' || user_settings.number_lines ||
-	    \   (user_settings.dynamic_folds && !user_settings.no_foldcolumn))
+      GetOption(user_settings,
+	'expand_tabs',
+	&expandtab || &ts != 8 || &vts != '' || user_settings.number_lines ||
+	(user_settings.dynamic_folds && !user_settings.no_foldcolumn))
     else
-      let user_settings.expand_tabs = 1
+      user_settings.expand_tabs = 1
     endif
-    " }}}
+    # }}}
 
-    " textual options
-    if exists("g:html_use_encoding") "{{{
-      " user specified the desired MIME charset, figure out proper
-      " 'fileencoding' from it or warn the user if we cannot
-      let user_settings.encoding = g:html_use_encoding
-      let user_settings.vim_encoding = tohtml#EncodingFromCharset(g:html_use_encoding)
+    # textual options
+    if exists("g:html_use_encoding") #{{{
+      # user specified the desired MIME charset, figure out proper
+      # 'fileencoding' from it or warn the user if we cannot
+      user_settings.encoding = g:html_use_encoding
+      user_settings.vim_encoding = EncodingFromCharset(g:html_use_encoding)
       if user_settings.vim_encoding == ''
 	echohl WarningMsg
-	echomsg "TOhtml: file encoding for"
-	      \ g:html_use_encoding
-	      \ "unknown, please set 'fileencoding'"
+	echomsg "TOhtml: file encoding for" g:html_use_encoding "unknown, please set 'fileencoding'"
 	echohl None
       endif
     else
-      " Figure out proper MIME charset from 'fileencoding' if possible
-      if &l:fileencoding != '' 
-	" If the buffer is not a "normal" type, the 'fileencoding' value may not
-	" be trusted; since the buffer should not be written the fileencoding is
-	" not intended to be used.
-	if &l:buftype=='' || &l:buftype==?'help'
-	  let user_settings.vim_encoding = &l:fileencoding
-	  call tohtml#CharsetFromEncoding(user_settings)
+      # Figure out proper MIME charset from 'fileencoding' if possible
+      if &l:fileencoding != ''
+	# If the buffer is not a "normal" type, the 'fileencoding' value may not
+	# be trusted; since the buffer should not be written the fileencoding is
+	# not intended to be used.
+	if &l:buftype == '' || &l:buftype ==? 'help'
+	  user_settings.vim_encoding = &l:fileencoding
+	  CharsetFromEncoding(user_settings)
 	else
-	  let user_settings.encoding = '' " trigger detection using &encoding
+	  user_settings.encoding = '' # trigger detection using &encoding
 	endif
       endif
 
-      " else from 'encoding' if possible
+      # else from 'encoding' if possible
       if &l:fileencoding == '' || user_settings.encoding == ''
-	let user_settings.vim_encoding = &encoding
-	call tohtml#CharsetFromEncoding(user_settings)
+	user_settings.vim_encoding = &encoding
+	CharsetFromEncoding(user_settings)
       endif
 
-      " else default to UTF-8 and warn user
+      # else default to UTF-8 and warn user
       if user_settings.encoding == ''
-	let user_settings.vim_encoding = 'utf-8'
-	let user_settings.encoding = 'UTF-8'
+	user_settings.vim_encoding = 'utf-8'
+	user_settings.encoding = 'UTF-8'
 	echohl WarningMsg
 	echomsg "TOhtml: couldn't determine MIME charset, using UTF-8"
 	echohl None
       endif
-    endif "}}}
+    endif #}}}
 
-    " Default to making nothing uncopyable, because we default to
-    " not-standards way of doing things, and also because Microsoft Word and
-    " others paste the  elements anyway.
-    "
-    " html_prevent_copy only has an effect when using CSS.
-    "
-    " All options:
-    "	  f - fold column
-    "	  n - line numbers (also within fold text)
-    "	  t - fold text
-    "	  d - diff filler
-    "	  c - concealed text (reserved future)
-    "	  l - listchars (reserved possible future)
-    "	  s - signs (reserved possible future)
-    "
-    " Normal text is always selectable.
-    let user_settings.prevent_copy = ""
+    # Default to making nothing uncopyable, because we default to
+    # not-standards way of doing things, and also because Microsoft Word and
+    # others paste the  elements anyway.
+    #
+    # html_prevent_copy only has an effect when using CSS.
+    #
+    # All options:
+    #	  f - fold column
+    #	  n - line numbers (also within fold text)
+    #	  t - fold text
+    #	  d - diff filler
+    #	  c - concealed text (reserved future)
+    #	  l - listchars (reserved possible future)
+    #	  s - signs (reserved possible future)
+    #
+    # Normal text is always selectable.
+    user_settings.prevent_copy = ""
     if user_settings.use_css
       if exists("g:html_prevent_copy")
 	if user_settings.dynamic_folds && !user_settings.no_foldcolumn && g:html_prevent_copy =~# 'f'
-	  let user_settings.prevent_copy ..= 'f'
+	  user_settings.prevent_copy ..= 'f'
 	endif
 	if user_settings.number_lines && g:html_prevent_copy =~# 'n'
-	  let user_settings.prevent_copy ..= 'n'
+	  user_settings.prevent_copy ..= 'n'
 	endif
 	if &diff && g:html_prevent_copy =~# 'd'
-	  let user_settings.prevent_copy ..= 'd'
+	  user_settings.prevent_copy ..= 'd'
 	endif
 	if !user_settings.ignore_folding && g:html_prevent_copy =~# 't'
-	  let user_settings.prevent_copy ..= 't'
+	  user_settings.prevent_copy ..= 't'
 	endif
       else
-	let user_settings.prevent_copy = ""
+	user_settings.prevent_copy = ""
       endif
     endif
     if empty(user_settings.prevent_copy)
-      let user_settings.no_invalid = 0
+      user_settings.no_invalid = 0
     endif
 
-    " enforce valid values for use_input_for_pc
+    # enforce valid values for use_input_for_pc
     if user_settings.use_input_for_pc !~# 'fallback\|none\|all'
-      let user_settings.use_input_for_pc = 'none'
+      user_settings.use_input_for_pc = 'none'
       echohl WarningMsg
       echomsg '2html: "' .. g:html_use_input_for_pc .. '" is not valid for g:html_use_input_for_pc'
       echomsg '2html: defaulting to "' .. user_settings.use_input_for_pc .. '"'
@@ -885,67 +889,64 @@ func! tohtml#GetUserSettings() "{{{
     endif
 
     if exists('g:html_id_expr')
-      let user_settings.id_suffix = eval(g:html_id_expr)
+      user_settings.id_suffix = eval(g:html_id_expr)
       if user_settings.id_suffix !~ '^[-_:.A-Za-z0-9]*$'
 	echohl WarningMsg
 	echomsg '2html: g:html_id_expr evaluated to invalid string for HTML id attributes'
 	echomsg '2html: Omitting user-specified suffix'
 	echohl None
 	sleep 3
-	let user_settings.id_suffix=""
+	user_settings.id_suffix = ""
       endif
     else
-      let user_settings.id_suffix=""
+      user_settings.id_suffix = ""
     endif
 
-    " TODO: font
+    # TODO: font
 
     return user_settings
   endif
-endfunc "}}}
+enddef #}}}
 
-" get the proper HTML charset name from a Vim encoding option.
-function! tohtml#CharsetFromEncoding(settings) "{{{
-  let l:vim_encoding = a:settings.vim_encoding
-  if exists('g:html_charset_override') && has_key(g:html_charset_override, l:vim_encoding)
-    let a:settings.encoding = g:html_charset_override[l:vim_encoding]
+# get the proper HTML charset name from a Vim encoding option.
+export def CharsetFromEncoding(_settings: dict) #{{{
+  var vim_encoding = _settings.vim_encoding
+  if exists('g:html_charset_override') && has_key(g:html_charset_override, vim_encoding)
+    _settings.encoding = g:html_charset_override[vim_encoding]
   else
-    if l:vim_encoding =~ '^8bit\|^2byte'
-      " 8bit- and 2byte- prefixes are to indicate encodings available on the
-      " system that Vim will convert with iconv(), look up just the encoding name,
-      " not Vim's prefix.
-      let l:vim_encoding = substitute(l:vim_encoding, '^8bit-\|^2byte-', '', '')
+    if vim_encoding =~ '^8bit\|^2byte'
+      # 8bit- and 2byte- prefixes are to indicate encodings available on the
+      # system that Vim will convert with iconv(), look up just the encoding name,
+      # not Vim's prefix.
+      vim_encoding = substitute(vim_encoding, '^8bit-\|^2byte-', '', '')
     endif
-    if has_key(g:tohtml#encoding_to_charset, l:vim_encoding)
-      let a:settings.encoding = g:tohtml#encoding_to_charset[l:vim_encoding]
+    if has_key(encoding_to_charset, vim_encoding)
+      _settings.encoding = encoding_to_charset[vim_encoding]
     else
-      let a:settings.encoding = ""
+      _settings.encoding = ""
     endif
   endif
-  if a:settings.encoding != ""
-    let l:vim_encoding = tohtml#EncodingFromCharset(a:settings.encoding)
-    if l:vim_encoding != ""
-      " if the Vim encoding to HTML encoding conversion is set up (by default or
-      " by the user) to convert to a different encoding, we need to also change
-      " the Vim encoding of the new buffer
-      let a:settings.vim_encoding = l:vim_encoding
+  if _settings.encoding != ""
+    var vim_encoding2 = EncodingFromCharset(_settings.encoding)
+    if vim_encoding2 != ""
+      # if the Vim encoding to HTML encoding conversion is set up (by default or
+      # by the user) to convert to a different encoding, we need to also change
+      # the Vim encoding of the new buffer
+      _settings.vim_encoding = vim_encoding2
     endif
   endif
-endfun "}}}
+enddef #}}}
 
-" Get the proper Vim encoding option setting from an HTML charset name.
-function! tohtml#EncodingFromCharset(encoding) "{{{
-  if exists('g:html_encoding_override') && has_key(g:html_encoding_override, a:encoding)
-    return g:html_encoding_override[a:encoding]
-  elseif has_key(g:tohtml#charset_to_encoding, tolower(a:encoding))
-    return g:tohtml#charset_to_encoding[tolower(a:encoding)]
+# Get the proper Vim encoding option setting from an HTML charset name.
+export def EncodingFromCharset(encoding: string): string #{{{
+  if exists('g:html_encoding_override') && has_key(g:html_encoding_override, encoding)
+    return g:html_encoding_override[encoding]
+  elseif has_key(charset_to_encoding, tolower(encoding))
+    return charset_to_encoding[tolower(encoding)]
   else
     return ""
   endif
-endfun "}}}
+enddef #}}}
 
-let &cpo = s:cpo_sav
-unlet s:cpo_sav
-
-" Make sure any patches will probably use consistent indent
-"   vim: ts=8 sw=2 sts=2 noet fdm=marker
+# Make sure any patches will probably use consistent indent
+#   vim: ts=8 sw=2 sts=2 noet fdm=marker
diff --git a/runtime/autoload/typeset.vim b/runtime/autoload/typeset.vim
index 3280cb4efd..0cb6149f5b 100644
--- a/runtime/autoload/typeset.vim
+++ b/runtime/autoload/typeset.vim
@@ -2,9 +2,7 @@ vim9script
 
 # Language:           Generic TeX typesetting engine
 # Maintainer:         Nicola Vitacolonna 
-# Latest Revision:    2026 Feb 19
-# Last Change:
-# 2026 Mar 30 by Vim project: Use fnameescape for the ProcessOutput command
+# Latest Revision:    2026 May 20
 
 # Constants and helpers {{{
 const SLASH = !exists("+shellslash") || &shellslash ? '/' : '\'
@@ -62,7 +60,7 @@ def ProcessOutput(qfid: number, wd: string, efm: string, ch: channel, msg: strin
   endif
 
   # Make sure the working directory is correct
-  silent execute "lcd" .. fnameescape(wd)
+  silent execute "lcd" fnameescape(wd)
   setqflist([], 'a', {'id': qfid, 'lines': [msg], 'efm': efm})
   silent lcd -
 enddef
diff --git a/runtime/autoload/vimball.vim b/runtime/autoload/vimball.vim
index fb4df5eb66..352e94d02d 100644
--- a/runtime/autoload/vimball.vim
+++ b/runtime/autoload/vimball.vim
@@ -1,12 +1,9 @@
 " vimball.vim : construct a file containing both paths and files
 " Maintainer: This runtime file is looking for a new maintainer.
 " Original Author:	Charles E. Campbell
-" Date:			Apr 11, 2016
+" Date:			May 20, 2026
 " Version:	37 (with modifications from the Vim Project)
 " GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim
-"  Last Change:
-"   2025 Feb 28 by Vim Project: add support for bzip3 (#16755)
-"   2026 Apr 05 by Vim Project: Detect Path Traversal Attacks
 " Copyright: (c) 2004-2011 by Charles E. Campbell
 "            The VIM LICENSE applies to Vimball.vim, and Vimball.txt
 "            (see |copyright|) except use "Vimball" instead of "Vim".
@@ -105,14 +102,14 @@ fun! vimball#MkVimball(line1,line2,writelevel,...) range
 
   while linenr <= a:line2
    let svfile  = getline(linenr)
- 
+
    if !filereadable(svfile)
     call vimball#ShowMesg(s:ERROR,"unable to read file<".svfile.">")
     call s:ChgDir(curdir)
     call vimball#RestoreSettings()
     return
    endif
- 
+
    " create/switch to mkvimball tab
    if !exists("vbtabnr")
     tabnew
@@ -121,7 +118,7 @@ fun! vimball#MkVimball(line1,line2,writelevel,...) range
    else
     exe "tabn ".vbtabnr
    endif
- 
+
    let lastline= line("$") + 1
    if lastline == 2 && getline("$") == ""
     call setline(1,'" Vimball Archiver by Charles E. Campbell')
@@ -165,7 +162,7 @@ endfun
 
 " ---------------------------------------------------------------------
 " vimball#Vimball: extract and distribute contents from a vimball {{{2
-"                  (invoked the the UseVimball command embedded in 
+"                  (invoked the the UseVimball command embedded in
 "                  vimballs' prologue)
 fun! vimball#Vimball(really,...)
 
@@ -215,7 +212,7 @@ fun! vimball#Vimball(really,...)
   " give title to listing of (extracted) files from Vimball Archive
   if a:really
    echohl Title     | echomsg "Vimball Archive"         | echohl None
-  else             
+  else
    echohl Title     | echomsg "Vimball Archive Listing" | echohl None
    echohl Statement | echomsg "files would be placed under: ".home | echohl None
   endif
@@ -229,12 +226,25 @@ fun! vimball#Vimball(really,...)
    let fsize   = substitute(getline(linenr+1),'^\(\d\+\).\{-}$','\1','')+0
    let fenc    = substitute(getline(linenr+1),'^\d\+\s*\(\S\{-}\)$','\1','')
    let filecnt = filecnt + 1
-   if fname =~ '\.\.'
+   " Do not allow a leading /, .. anywhere, or a Windows drive letter
+   " (e.g. C:/foo) in the file name.  Backslashes were already converted
+   " to forward slashes above, so this also catches \\server\share UNC
+   " paths via the leading-slash check.
+   if fname =~ '\.\.' || fname =~ '^/' || fname =~ '^\a:'
      echomsg "(Vimball) Path Traversal Attack detected, aborting..."
      exe "tabn ".curtabnr
      bw! Vimball
      call s:ChgDir(curdir)
      return
+   " Also, disallow strange paths, that could lead to code execution from
+   " .VimballRecord
+   " Disallow: pipe, quotes and closing paren
+   elseif fname =~ '[|'')"]'
+     echomsg printf("(Vimball) Forbidding strange filename: '%s', aborting...", fname)
+     exe "tabn ".curtabnr
+     bw! Vimball
+     call s:ChgDir(curdir)
+     return
    endif
 
    if a:really
@@ -293,7 +303,7 @@ fun! vimball#Vimball(really,...)
       exe "silent w! ".fnameescape(fnamepath)
     endif
     echo "wrote ".fnameescape(fnamepath)
-    call s:RecordInVar(home,"call delete('".fnamepath."')")
+    call s:RecordInVar(home,"call delete('".escape(fnamepath, '"''|')."')")
     endif
 
     " return to tab with vimball
@@ -368,7 +378,7 @@ fun! vimball#RmVimball(...)
 
   call s:ChgDir(home)
   if filereadable(".VimballRecord")
-   keepalt keepjumps 1split 
+   keepalt keepjumps 1split
    sil! keepalt keepjumps e .VimballRecord
    let keepsrch= @/
    if search('^\M'.curfile."\m: ".'cw')
@@ -416,7 +426,7 @@ fun! vimball#Decompress(fname,...)
   " decompression:
   if     expand("%") =~ '.*\.gz'  && executable("gunzip")
    " handle *.gz with gunzip
-   silent exe "!gunzip ".shellescape(a:fname)
+   silent exe "!gunzip ".shellescape(a:fname,1)
    if v:shell_error != 0
     call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) gunzip may have failed with <".a:fname.">")
    endif
@@ -426,7 +436,7 @@ fun! vimball#Decompress(fname,...)
 
   elseif expand("%") =~ '.*\.gz' && executable("gzip")
    " handle *.gz with gzip -d
-   silent exe "!gzip -d ".shellescape(a:fname)
+   silent exe "!gzip -d ".shellescape(a:fname,1)
    if v:shell_error != 0
     call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "gzip -d" may have failed with <'.a:fname.">")
    endif
@@ -436,7 +446,7 @@ fun! vimball#Decompress(fname,...)
 
   elseif expand("%") =~ '.*\.bz2' && executable("bunzip2")
    " handle *.bz2 with bunzip2
-   silent exe "!bunzip2 ".shellescape(a:fname)
+   silent exe "!bunzip2 ".shellescape(a:fname,1)
    if v:shell_error != 0
     call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip2 may have failed with <".a:fname.">")
    endif
@@ -446,7 +456,7 @@ fun! vimball#Decompress(fname,...)
 
   elseif expand("%") =~ '.*\.bz2' && executable("bzip2")
    " handle *.bz2 with bzip2 -d
-   silent exe "!bzip2 -d ".shellescape(a:fname)
+   silent exe "!bzip2 -d ".shellescape(a:fname,1)
    if v:shell_error != 0
     call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "bzip2 -d" may have failed with <'.a:fname.">")
    endif
@@ -456,7 +466,7 @@ fun! vimball#Decompress(fname,...)
 
   elseif expand("%") =~ '.*\.bz3' && executable("bunzip3")
    " handle *.bz3 with bunzip3
-   silent exe "!bunzip3 ".shellescape(a:fname)
+   silent exe "!bunzip3 ".shellescape(a:fname,1)
    if v:shell_error != 0
     call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip3 may have failed with <".a:fname.">")
    endif
@@ -466,7 +476,7 @@ fun! vimball#Decompress(fname,...)
 
   elseif expand("%") =~ '.*\.bz3' && executable("bzip3")
    " handle *.bz3 with bzip3 -d
-   silent exe "!bzip3 -d ".shellescape(a:fname)
+   silent exe "!bzip3 -d ".shellescape(a:fname,1)
    if v:shell_error != 0
     call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "bzip3 -d" may have failed with <'.a:fname.">")
    endif
@@ -476,7 +486,7 @@ fun! vimball#Decompress(fname,...)
 
   elseif expand("%") =~ '.*\.zip' && executable("unzip")
    " handle *.zip with unzip
-   silent exe "!unzip ".shellescape(a:fname)
+   silent exe "!unzip ".shellescape(a:fname,1)
    if v:shell_error != 0
     call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) unzip may have failed with <".a:fname.">")
    endif
@@ -556,7 +566,7 @@ fun! s:RecordInFile(home)
   if exists("s:recordfile") || exists("s:recorddir")
    let curdir= getcwd()
    call s:ChgDir(a:home)
-   keepalt keepjumps 1split 
+   keepalt keepjumps 1split
 
    let cmd= expand("%:tr").": "
 
diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim
index f4482fd7fc..aad548239a 100644
--- a/runtime/autoload/zip.vim
+++ b/runtime/autoload/zip.vim
@@ -22,6 +22,8 @@
 " 2026 Mar 08 by Vim Project: Make ZipUpdatePS() check for powershell
 " 2026 Apr 01 by Vim Project: Detect more path traversal attacks
 " 2026 Apr 05 by Vim Project: Detect more path traversal attacks
+" 2026 Apr 14 by Vim Project: Detect more path traversal attacks on Windows
+" 2026 Apr 15 by Vim Project: Detect more path traversal attacks on Windows
 " 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,
@@ -405,7 +407,12 @@ fun! zip#Write(fname)
   else
     let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
     let fname   = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
-    " TODO: what to check on MS-Windows to avoid writing absolute paths?
+    " fname should not start with drive letter, UNC path, or leading slash
+    if fname =~ '^\%(\a:[\\/]\|[\\/]\)'
+      call s:Mess('Error', "***error*** (zip#Write) Path Traversal Attack detected, not writing!")
+      call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
+      return
+    endif
   endif
   if fname =~ '^[.]\{1,2}/'
     let gnu_cmd = g:zip_zipcmd . ' -d ' . s:Escape(fnamemodify(zipfile,":p"),0) . ' ' . s:Escape(fname,0)
@@ -499,6 +506,18 @@ fun! zip#Extract()
     call s:Mess('Error', "***error*** (zip#Browse) Path Traversal Attack detected, not extracting!")
     return
   endif
+  " block absolute paths
+  if has("unix")
+    if fname =~ '^/'
+      call s:Mess('Error', "***error*** (zip#Extract) Path Traversal Attack detected, not extracting!")
+      return
+    endif
+  else
+    if fname =~ '^\%(\a:[\\/]\|[\\/]\)'
+      call s:Mess('Error', "***error*** (zip#Extract) Path Traversal Attack detected, not extracting!")
+      return
+    endif
+  endif
   if filereadable(fname)
     call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!")
     return
diff --git a/runtime/colors/blue.vim b/runtime/colors/blue.vim
index 5179667f5a..07b4785ced 100644
--- a/runtime/colors/blue.vim
+++ b/runtime/colors/blue.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Steven Vertigan 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 14
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -124,7 +124,8 @@ hi ToolbarButton guifg=#ffffff guibg=#005faf guisp=NONE gui=NONE ctermfg=231 cte
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#ffa500 guibg=NONE guisp=NONE gui=bold ctermfg=214 ctermbg=NONE cterm=NONE term=NONE
 hi Underlined guifg=NONE guibg=NONE guisp=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#008787 guibg=NONE guisp=NONE gui=NONE ctermfg=30 ctermbg=NONE cterm=NONE term=NONE
+hi VertSplit guifg=#5fffff guibg=NONE guisp=NONE gui=NONE ctermfg=87 ctermbg=NONE cterm=NONE term=NONE
+hi VertSplitNC guifg=#008787 guibg=NONE guisp=NONE gui=NONE ctermfg=30 ctermbg=NONE cterm=NONE term=NONE
 hi Visual guifg=#ffffff guibg=#008787 guisp=NONE gui=NONE ctermfg=231 ctermbg=30 cterm=NONE term=reverse
 hi VisualNOS guifg=#008787 guibg=#ffffff guisp=NONE gui=NONE ctermfg=30 ctermbg=231 cterm=NONE term=NONE
 hi WarningMsg guifg=#d787d7 guibg=NONE guisp=NONE gui=NONE ctermfg=176 ctermbg=NONE cterm=NONE term=standout
@@ -197,7 +198,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkyellow ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkcyan ctermbg=NONE cterm=NONE
+  hi VertSplit ctermfg=cyan ctermbg=NONE cterm=NONE
+  hi VertSplitNC ctermfg=darkcyan ctermbg=NONE cterm=NONE
   hi Visual ctermfg=white ctermbg=darkcyan cterm=NONE
   hi VisualNOS ctermfg=darkcyan ctermbg=white cterm=NONE
   hi WarningMsg ctermfg=magenta ctermbg=NONE cterm=NONE
@@ -268,6 +270,7 @@ if s:t_Co >= 8
   hi Type ctermfg=red ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=cyan ctermbg=NONE cterm=NONE
+  hi VertSplitNC ctermfg=darkcyan ctermbg=NONE cterm=NONE
   hi Visual ctermfg=black ctermbg=cyan cterm=NONE
   hi VisualNOS ctermfg=cyan ctermbg=gray cterm=NONE
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/catppuccin.vim b/runtime/colors/catppuccin.vim
index 96e9c96350..b144332276 100644
--- a/runtime/colors/catppuccin.vim
+++ b/runtime/colors/catppuccin.vim
@@ -2,10 +2,10 @@
 " Description:  Soothing pastel theme for the high-spirited!
 " Author:       The Catppuccin Community 
 " Maintainer:   Mao-Yining 
-" URL:          https://www.github.com/vim/colorschemes
-" Last Change:  2026 Jan 31
+" URL:          https://github.com/vim/colorschemes
+" Last Change:  2026 May 04
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 hi clear
 let g:colors_name = 'catppuccin'
@@ -80,7 +80,7 @@ if &background == 'dark'
   hi PmenuExtra guifg=#6c7086 guibg=#181825 guisp=NONE gui=NONE ctermfg=59 ctermbg=232 cterm=NONE term=NONE
   hi PmenuExtraSel guifg=#6c7086 guibg=#313244 guisp=NONE gui=bold ctermfg=59 ctermbg=236 cterm=bold term=bold
   hi PmenuMatch guifg=#cdd6f4 guibg=NONE guisp=NONE gui=bold ctermfg=189 ctermbg=NONE cterm=bold term=bold
-  hi PmenuMatchSel guifg=NONE guibg=NONE guisp=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold term=bold
+  hi PmenuMatchSel guifg=#cdd6f4 guibg=NONE guisp=NONE gui=bold ctermfg=189 ctermbg=NONE cterm=bold term=bold
   hi PmenuSbar guifg=NONE guibg=#313244 guisp=NONE gui=NONE ctermfg=NONE ctermbg=236 cterm=NONE term=reverse
   hi PmenuSel guifg=NONE guibg=#313244 guisp=NONE gui=bold ctermfg=NONE ctermbg=236 cterm=bold term=bold
   hi PmenuThumb guifg=NONE guibg=#6c7086 guisp=NONE gui=NONE ctermfg=NONE ctermbg=59 cterm=NONE term=NONE
@@ -98,8 +98,8 @@ if &background == 'dark'
   hi SpellLocal guifg=NONE guibg=NONE guisp=#89b4fa gui=undercurl ctermfg=111 ctermbg=NONE cterm=underline term=underline
   hi SpellRare guifg=NONE guibg=NONE guisp=#a6e3a1 gui=undercurl ctermfg=114 ctermbg=NONE cterm=underline term=underline
   hi Statement guifg=#cba6f7 guibg=NONE guisp=NONE gui=NONE ctermfg=183 ctermbg=NONE cterm=NONE term=NONE
-  hi StatusLine guifg=#cdd6f4 guibg=#11111b guisp=NONE gui=NONE ctermfg=189 ctermbg=16 cterm=NONE term=bold,reverse
-  hi StatusLineNC guifg=#45475a guibg=#181825 guisp=NONE gui=NONE ctermfg=240 ctermbg=232 cterm=NONE term=bold,underline
+  hi StatusLine guifg=#cdd6f4 guibg=#11111b guisp=NONE gui=bold ctermfg=189 ctermbg=16 cterm=bold term=bold,reverse
+  hi StatusLineNC guifg=#6c7086 guibg=#181825 guisp=NONE gui=NONE ctermfg=59 ctermbg=232 cterm=NONE term=bold,underline
   hi StorageClass guifg=#f9e2af guibg=NONE guisp=NONE gui=NONE ctermfg=222 ctermbg=NONE cterm=NONE term=NONE
   hi String guifg=#a6e3a1 guibg=NONE guisp=NONE gui=NONE ctermfg=114 ctermbg=NONE cterm=NONE term=NONE
   hi Structure guifg=#f9e2af guibg=NONE guisp=NONE gui=NONE ctermfg=222 ctermbg=NONE cterm=NONE term=NONE
@@ -207,8 +207,8 @@ if &background == 'dark'
     hi PmenuExtra ctermfg=Grey ctermbg=DarkGrey cterm=NONE
     hi PmenuExtraSel ctermfg=Grey ctermbg=DarkYellow cterm=bold
     hi PmenuMatch ctermfg=White ctermbg=NONE cterm=bold
-    hi PmenuMatchSel ctermfg=NONE ctermbg=NONE cterm=bold
-    hi PmenuSbar ctermfg=NONE ctermbg=DarkYellow cterm=NONE
+    hi PmenuMatchSel ctermfg=White ctermbg=NONE cterm=bold
+    hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE
     hi PmenuSel ctermfg=NONE ctermbg=DarkYellow cterm=bold
     hi PmenuThumb ctermfg=NONE ctermbg=Grey cterm=NONE
     hi PreInsert ctermfg=Grey ctermbg=NONE cterm=NONE
@@ -328,8 +328,8 @@ if &background == 'dark'
     hi PmenuExtra ctermfg=Grey ctermbg=DarkGrey cterm=NONE
     hi PmenuExtraSel ctermfg=Grey ctermbg=DarkYellow cterm=bold
     hi PmenuMatch ctermfg=White ctermbg=NONE cterm=bold
-    hi PmenuMatchSel ctermfg=NONE ctermbg=NONE cterm=bold
-    hi PmenuSbar ctermfg=NONE ctermbg=DarkYellow cterm=NONE
+    hi PmenuMatchSel ctermfg=White ctermbg=NONE cterm=bold
+    hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE
     hi PmenuSel ctermfg=NONE ctermbg=DarkYellow cterm=bold
     hi PmenuThumb ctermfg=NONE ctermbg=Grey cterm=NONE
     hi PreInsert ctermfg=Grey ctermbg=NONE cterm=NONE
@@ -466,7 +466,7 @@ if &background == 'light'
   hi PmenuExtra guifg=#9ca0b0 guibg=#e6e9ef guisp=NONE gui=NONE ctermfg=247 ctermbg=255 cterm=NONE term=NONE
   hi PmenuExtraSel guifg=#9ca0b0 guibg=#ccd0da guisp=NONE gui=bold ctermfg=247 ctermbg=253 cterm=bold term=bold
   hi PmenuMatch guifg=#4c4f69 guibg=NONE guisp=NONE gui=bold ctermfg=236 ctermbg=NONE cterm=bold term=bold
-  hi PmenuMatchSel guifg=NONE guibg=NONE guisp=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=bold term=bold
+  hi PmenuMatchSel guifg=#4c4f69 guibg=NONE guisp=NONE gui=bold ctermfg=236 ctermbg=NONE cterm=bold term=bold
   hi PmenuSbar guifg=NONE guibg=#ccd0da guisp=NONE gui=NONE ctermfg=NONE ctermbg=253 cterm=NONE term=reverse
   hi PmenuSel guifg=NONE guibg=#ccd0da guisp=NONE gui=bold ctermfg=NONE ctermbg=253 cterm=bold term=bold
   hi PmenuThumb guifg=NONE guibg=#9ca0b0 guisp=NONE gui=NONE ctermfg=NONE ctermbg=247 cterm=NONE term=NONE
@@ -484,8 +484,8 @@ if &background == 'light'
   hi SpellLocal guifg=NONE guibg=NONE guisp=#1e66f5 gui=undercurl ctermfg=27 ctermbg=NONE cterm=underline term=underline
   hi SpellRare guifg=NONE guibg=NONE guisp=#40a02b gui=undercurl ctermfg=34 ctermbg=NONE cterm=underline term=underline
   hi Statement guifg=#8839ef guibg=NONE guisp=NONE gui=NONE ctermfg=93 ctermbg=NONE cterm=NONE term=NONE
-  hi StatusLine guifg=#4c4f69 guibg=#dce0e8 guisp=NONE gui=NONE ctermfg=236 ctermbg=254 cterm=NONE term=bold,reverse
-  hi StatusLineNC guifg=#bcc0cc guibg=#e6e9ef guisp=NONE gui=NONE ctermfg=250 ctermbg=255 cterm=NONE term=bold,underline
+  hi StatusLine guifg=#4c4f69 guibg=#dce0e8 guisp=NONE gui=bold ctermfg=236 ctermbg=254 cterm=bold term=bold,reverse
+  hi StatusLineNC guifg=#9ca0b0 guibg=#e6e9ef guisp=NONE gui=NONE ctermfg=247 ctermbg=255 cterm=NONE term=bold,underline
   hi StorageClass guifg=#df8e1d guibg=NONE guisp=NONE gui=NONE ctermfg=172 ctermbg=NONE cterm=NONE term=NONE
   hi String guifg=#40a02b guibg=NONE guisp=NONE gui=NONE ctermfg=34 ctermbg=NONE cterm=NONE term=NONE
   hi Structure guifg=#df8e1d guibg=NONE guisp=NONE gui=NONE ctermfg=172 ctermbg=NONE cterm=NONE term=NONE
@@ -593,8 +593,8 @@ if &background == 'light'
     hi PmenuExtra ctermfg=DarkGrey ctermbg=Grey cterm=NONE
     hi PmenuExtraSel ctermfg=DarkGrey ctermbg=Grey cterm=bold
     hi PmenuMatch ctermfg=Black ctermbg=NONE cterm=bold
-    hi PmenuMatchSel ctermfg=NONE ctermbg=NONE cterm=bold
-    hi PmenuSbar ctermfg=NONE ctermbg=Grey cterm=NONE
+    hi PmenuMatchSel ctermfg=Black ctermbg=NONE cterm=bold
+    hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE
     hi PmenuSel ctermfg=NONE ctermbg=Grey cterm=bold
     hi PmenuThumb ctermfg=NONE ctermbg=DarkGrey cterm=NONE
     hi PreInsert ctermfg=Black ctermbg=NONE cterm=NONE
@@ -714,8 +714,8 @@ if &background == 'light'
     hi PmenuExtra ctermfg=DarkGrey ctermbg=Grey cterm=NONE
     hi PmenuExtraSel ctermfg=DarkGrey ctermbg=Grey cterm=bold
     hi PmenuMatch ctermfg=Black ctermbg=NONE cterm=bold
-    hi PmenuMatchSel ctermfg=NONE ctermbg=NONE cterm=bold
-    hi PmenuSbar ctermfg=NONE ctermbg=Grey cterm=NONE
+    hi PmenuMatchSel ctermfg=Black ctermbg=NONE cterm=bold
+    hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE
     hi PmenuSel ctermfg=NONE ctermbg=Grey cterm=bold
     hi PmenuThumb ctermfg=NONE ctermbg=DarkGrey cterm=NONE
     hi PreInsert ctermfg=Black ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/darkblue.vim b/runtime/colors/darkblue.vim
index b490b0599a..b00a05a45a 100644
--- a/runtime/colors/darkblue.vim
+++ b/runtime/colors/darkblue.vim
@@ -3,9 +3,9 @@
 " Author:       Original author Bohdan Vlasyuk 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 14
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -126,7 +126,8 @@ hi ToolbarButton guifg=#ffffff guibg=#0030ff guisp=NONE gui=NONE ctermfg=231 cte
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#90f020 guibg=NONE guisp=NONE gui=NONE ctermfg=118 ctermbg=NONE cterm=NONE term=NONE
 hi Underlined guifg=#80a0ff guibg=NONE guisp=NONE gui=underline ctermfg=111 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#000000 guibg=#808080 guisp=NONE gui=NONE ctermfg=16 ctermbg=102 cterm=NONE term=NONE
+hi VertSplit guifg=#000040 guibg=#c0c0c0 guisp=NONE gui=NONE ctermfg=17 ctermbg=252 cterm=NONE term=NONE
+hi VertSplitNC guifg=#000000 guibg=#808080 guisp=NONE gui=NONE ctermfg=16 ctermbg=102 cterm=NONE term=NONE
 hi Visual guifg=#8080ff guibg=#ffffff guisp=NONE gui=reverse ctermfg=105 ctermbg=231 cterm=reverse term=reverse
 hi VisualNOS guifg=#8080ff guibg=#c0c0c0 guisp=NONE gui=reverse,underline ctermfg=105 ctermbg=252 cterm=reverse,underline term=NONE
 hi WarningMsg guifg=#ff0000 guibg=NONE guisp=NONE gui=NONE ctermfg=196 ctermbg=NONE cterm=NONE term=standout
@@ -196,7 +197,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=green ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=black ctermbg=darkgrey cterm=NONE
+  hi VertSplit ctermfg=black ctermbg=grey cterm=NONE
+  hi VertSplitNC ctermfg=black ctermbg=darkgrey cterm=NONE
   hi Visual ctermfg=blue ctermbg=white cterm=reverse
   hi VisualNOS ctermfg=blue ctermbg=grey cterm=reverse,underline
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
@@ -264,7 +266,8 @@ if s:t_Co >= 8
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=grey ctermbg=black cterm=reverse
+  hi VertSplit ctermfg=darkblue ctermbg=grey cterm=reverse
+  hi VertSplitNC ctermfg=grey ctermbg=black cterm=reverse
   hi Visual ctermfg=blue ctermbg=grey cterm=reverse
   hi VisualNOS ctermfg=blue ctermbg=grey cterm=reverse,underline
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/delek.vim b/runtime/colors/delek.vim
index 541b63ec0e..5a19cd26f5 100644
--- a/runtime/colors/delek.vim
+++ b/runtime/colors/delek.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer David Schweikert 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=light
 
@@ -91,7 +91,8 @@ hi ToolbarButton guifg=#ffffff guibg=#bcbcbc guisp=NONE gui=bold ctermfg=231 cte
 hi ToolbarLine guifg=NONE guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=NONE ctermbg=254 cterm=NONE term=reverse
 hi Type guifg=#0000ff guibg=NONE guisp=NONE gui=bold ctermfg=21 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#6a5acd guibg=NONE guisp=NONE gui=underline ctermfg=62 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#e4e4e4 guibg=#00008b guisp=NONE gui=NONE ctermfg=254 ctermbg=18 cterm=NONE term=NONE
+hi VertSplit guifg=#ffff00 guibg=#00008b guisp=NONE gui=NONE ctermfg=226 ctermbg=18 cterm=NONE term=NONE
+hi VertSplitNC guifg=#e4e4e4 guibg=#00008b guisp=NONE gui=NONE ctermfg=254 ctermbg=18 cterm=NONE term=NONE
 hi Visual guifg=#000000 guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=16 ctermbg=252 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=#ee0000 guisp=NONE gui=NONE ctermfg=NONE ctermbg=196 cterm=NONE term=NONE
 hi WarningMsg guifg=#cd00cd guibg=#ffffff guisp=NONE gui=NONE ctermfg=164 ctermbg=231 cterm=NONE term=standout
@@ -164,7 +165,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=grey cterm=NONE
   hi Type ctermfg=blue ctermbg=NONE cterm=bold
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=grey ctermbg=darkblue cterm=NONE
+  hi VertSplit ctermfg=yellow ctermbg=darkblue cterm=NONE
+  hi VertSplitNC ctermfg=grey ctermbg=darkblue cterm=NONE
   hi Visual ctermfg=white ctermbg=darkgrey cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=darkred cterm=NONE
   hi WarningMsg ctermfg=darkmagenta ctermbg=white cterm=NONE
@@ -236,6 +238,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkblue ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=darkblue ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=darkblue ctermbg=darkyellow cterm=reverse
+  hi VertSplitNC ctermfg=darkblue ctermbg=darkyellow cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkmagenta ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/desert.vim b/runtime/colors/desert.vim
index 8ce22ea80a..02c6371b69 100644
--- a/runtime/colors/desert.vim
+++ b/runtime/colors/desert.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Hans Fugal 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -91,7 +91,8 @@ hi ToolbarButton guifg=#333333 guibg=#ffde9b guisp=NONE gui=bold ctermfg=236 cte
 hi ToolbarLine guifg=NONE guibg=#666666 guisp=NONE gui=NONE ctermfg=NONE ctermbg=241 cterm=NONE term=reverse
 hi Type guifg=#bdb76b guibg=NONE guisp=NONE gui=bold ctermfg=143 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#75a0ff guibg=NONE guisp=NONE gui=underline ctermfg=111 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#7f7f8c guibg=#c2bfa5 guisp=NONE gui=NONE ctermfg=242 ctermbg=144 cterm=NONE term=NONE
+hi VertSplit guifg=#333333 guibg=#c2bfa5 guisp=NONE gui=NONE ctermfg=236 ctermbg=144 cterm=NONE term=NONE
+hi VertSplitNC guifg=#7f7f8c guibg=#c2bfa5 guisp=NONE gui=NONE ctermfg=242 ctermbg=144 cterm=NONE term=NONE
 hi Visual guifg=#f0e68c guibg=#6b8e24 guisp=NONE gui=NONE ctermfg=186 ctermbg=64 cterm=NONE term=reverse
 hi VisualNOS guifg=#f0e68c guibg=#6dceeb guisp=NONE gui=NONE ctermfg=186 ctermbg=81 cterm=NONE term=NONE
 hi WarningMsg guifg=#cd5c5c guibg=NONE guisp=NONE gui=bold ctermfg=167 ctermbg=NONE cterm=bold term=standout
@@ -167,7 +168,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkyellow ctermbg=NONE cterm=bold
   hi Underlined ctermfg=darkblue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkgrey ctermbg=grey cterm=NONE
+  hi VertSplit ctermfg=black ctermbg=grey cterm=NONE
+  hi VertSplitNC ctermfg=darkgrey ctermbg=grey cterm=NONE
   hi Visual ctermfg=white ctermbg=darkgreen cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=bold
@@ -237,6 +239,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkyellow ctermbg=NONE cterm=bold
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=grey ctermbg=black cterm=reverse
+  hi VertSplitNC ctermfg=grey ctermbg=black cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=bold
diff --git a/runtime/colors/elflord.vim b/runtime/colors/elflord.vim
index 1a8e224658..d9852a2316 100644
--- a/runtime/colors/elflord.vim
+++ b/runtime/colors/elflord.vim
@@ -3,9 +3,9 @@
 " Maintainer:   original maintainer Ron Aaron 
 " URL:          https://www.github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -114,7 +114,8 @@ hi ToolbarButton guifg=#000000 guibg=#e5e5e5 guisp=NONE gui=bold ctermfg=16 cter
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#60ff60 guibg=NONE guisp=NONE gui=bold ctermfg=83 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#80a0ff guibg=NONE guisp=NONE gui=underline ctermfg=111 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#000000 guibg=#00cdcd guisp=NONE gui=NONE ctermfg=16 ctermbg=44 cterm=NONE term=NONE
+hi VertSplit guifg=#000000 guibg=#00ffff guisp=NONE gui=NONE ctermfg=16 ctermbg=51 cterm=NONE term=NONE
+hi VertSplitNC guifg=#000000 guibg=#00cdcd guisp=NONE gui=NONE ctermfg=16 ctermbg=44 cterm=NONE term=NONE
 hi Visual guifg=#000000 guibg=#a9a9a9 guisp=NONE gui=NONE ctermfg=16 ctermbg=145 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=#000000 guisp=NONE gui=bold,underline ctermfg=NONE ctermbg=16 cterm=underline term=NONE
 hi WarningMsg guifg=#ff0000 guibg=NONE guisp=NONE gui=NONE ctermfg=196 ctermbg=NONE cterm=NONE term=standout
@@ -188,7 +189,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=green ctermbg=NONE cterm=bold
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=black ctermbg=darkcyan cterm=NONE
+  hi VertSplit ctermfg=black ctermbg=cyan cterm=NONE
+  hi VertSplitNC ctermfg=black ctermbg=darkcyan cterm=NONE
   hi Visual ctermfg=black ctermbg=darkgrey cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=black cterm=underline
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
@@ -263,6 +265,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=darkblue ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=black ctermbg=darkcyan cterm=NONE
+  hi VertSplitNC ctermfg=black ctermbg=darkcyan cterm=NONE
   hi Visual ctermfg=black ctermbg=grey cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/evening.vim b/runtime/colors/evening.vim
index 62a0a8620a..ddfb1f2854 100644
--- a/runtime/colors/evening.vim
+++ b/runtime/colors/evening.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Steven Vertigan 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -59,7 +59,8 @@ hi! link TabPanelFill EndOfBuffer
 hi! link Tag Special
 hi! link Terminal Normal
 hi! link Typedef Type
-hi! link VertSplit StatusLineNC
+hi! link VertSplit StatusLine
+hi! link VertSplitNC StatusLineNC
 hi! link diffBDiffer WarningMsg
 hi! link diffCommon WarningMsg
 hi! link diffDiffer WarningMsg
diff --git a/runtime/colors/habamax.vim b/runtime/colors/habamax.vim
index ed9fba0651..4958ccdb7d 100644
--- a/runtime/colors/habamax.vim
+++ b/runtime/colors/habamax.vim
@@ -3,9 +3,9 @@
 " Author:       Maxim Kim 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 22
+" Last Change:  2026 May 28
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -37,17 +37,17 @@ hi! link TabPanelFill Normal
 hi! link Terminal Normal
 hi! link asciidoctorBlock Special
 hi! link asciidoctorCode String
-hi! link asciidoctorH1Delimiter Statement
-hi! link asciidoctorH2Delimiter Statement
-hi! link asciidoctorH3Delimiter Statement
-hi! link asciidoctorH4Delimiter Statement
-hi! link asciidoctorH5Delimiter Statement
-hi! link asciidoctorH6Delimiter Statement
+hi! link asciidoctorH1 htmlH1
+hi! link asciidoctorH2 htmlH1
+hi! link asciidoctorH3 htmlH1
+hi! link asciidoctorH4 htmlH1
+hi! link asciidoctorH5 htmlH1
+hi! link asciidoctorH6 htmlH1
 hi! link asciidoctorListMarker Constant
 hi! link asciidoctorMacro Special
 hi! link asciidoctorOption Special
 hi! link asciidoctorSetextHeaderDelimiter Statement
-hi! link asciidoctorTitleDelimiter Statement
+hi! link asciidoctorTitle htmlH1
 hi! link javaScriptFunction Statement
 hi! link javaScriptIdentifier Statement
 hi! link lspDiagSignErrorText Removed
@@ -58,11 +58,14 @@ hi! link lspDiagVirtualTextError Removed
 hi! link lspDiagVirtualTextHint Added
 hi! link lspDiagVirtualTextInfo Question
 hi! link lspDiagVirtualTextWarning Changed
+hi! link markdownHeadingRule Special
 hi! link markdownUrl String
+hi! link rstSection htmlH1
 hi! link rubyDefine Statement
 hi! link rubyMacro Statement
 hi! link sqlKeyword Statement
 hi! link sqlSpecial Constant
+hi! link typstMarkupHeading htmlH1
 hi! link vimCommentString Comment
 hi! link vimOper Normal
 hi! link vimParenSep Normal
@@ -107,12 +110,15 @@ hi PmenuExtra guifg=#767676 guibg=#3a3a3a guisp=NONE gui=NONE ctermfg=243 ctermb
 hi PmenuExtraSel guifg=#9e9e9e guibg=#585858 guisp=NONE gui=NONE ctermfg=247 ctermbg=240 cterm=NONE term=NONE
 hi PmenuKind guifg=#5f8787 guibg=#3a3a3a guisp=NONE gui=NONE ctermfg=66 ctermbg=237 cterm=NONE term=NONE
 hi PmenuKindSel guifg=#5f8787 guibg=#585858 guisp=NONE gui=NONE ctermfg=66 ctermbg=240 cterm=NONE term=NONE
-hi PmenuMatch guifg=#ffaf5f guibg=#3a3a3a guisp=NONE gui=NONE ctermfg=215 ctermbg=237 cterm=NONE term=NONE
-hi PmenuMatchSel guifg=#ffaf5f guibg=#585858 guisp=NONE gui=NONE ctermfg=215 ctermbg=240 cterm=NONE term=NONE
-hi PmenuSbar guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
+hi PmenuMatch guifg=#ffaf5f guibg=NONE guisp=NONE gui=NONE ctermfg=215 ctermbg=NONE cterm=NONE term=NONE
+hi PmenuMatchSel guifg=#ffaf5f guibg=NONE guisp=NONE gui=NONE ctermfg=215 ctermbg=NONE cterm=NONE term=NONE
+hi PmenuSbar guifg=NONE guibg=#585858 guisp=NONE gui=NONE ctermfg=NONE ctermbg=240 cterm=NONE term=reverse
 hi PmenuSel guifg=NONE guibg=#585858 guisp=NONE gui=NONE ctermfg=NONE ctermbg=240 cterm=NONE term=bold
 hi PmenuShadow guifg=#767676 guibg=#121212 guisp=NONE gui=NONE ctermfg=243 ctermbg=233 cterm=NONE term=NONE
 hi PmenuThumb guifg=NONE guibg=#767676 guisp=NONE gui=NONE ctermfg=NONE ctermbg=243 cterm=NONE term=NONE
+hi Popup guifg=NONE guibg=#3a3a3a guisp=NONE gui=NONE ctermfg=NONE ctermbg=237 cterm=NONE term=NONE
+hi PopupBorder guifg=#767676 guibg=#3a3a3a guisp=NONE gui=NONE ctermfg=243 ctermbg=237 cterm=NONE term=NONE
+hi PopupTitle guifg=#9e9e9e guibg=#3a3a3a guisp=NONE gui=bold ctermfg=247 ctermbg=237 cterm=bold term=bold
 hi PreProc guifg=#af875f guibg=NONE guisp=NONE gui=NONE ctermfg=137 ctermbg=NONE cterm=NONE term=NONE
 hi Question guifg=#d7af87 guibg=NONE guisp=NONE gui=NONE ctermfg=180 ctermbg=NONE cterm=NONE term=standout
 hi QuickFixLine guifg=NONE guibg=#4f2f4f guisp=NONE gui=NONE ctermfg=251 ctermbg=53 cterm=NONE term=NONE
@@ -136,17 +142,19 @@ hi Title guifg=NONE guibg=NONE guisp=NONE gui=bold ctermfg=NONE ctermbg=NONE cte
 hi TitleBar guifg=#dadada guibg=#3c3c3c guisp=NONE gui=NONE ctermfg=253 ctermbg=237 cterm=NONE term=NONE
 hi TitleBarNC guifg=#767676 guibg=#2c2c2c guisp=NONE gui=NONE ctermfg=243 ctermbg=236 cterm=NONE term=NONE
 hi Todo guifg=#dadada guibg=NONE guisp=NONE gui=bold ctermfg=253 ctermbg=NONE cterm=bold term=bold,reverse
-hi ToolbarButton guifg=#767676 guibg=#1c1c1c guisp=NONE gui=bold,reverse ctermfg=243 ctermbg=234 cterm=bold,reverse term=bold,reverse
+hi ToolbarButton guifg=#5f8787 guibg=#1c1c1c guisp=NONE gui=bold,reverse ctermfg=66 ctermbg=234 cterm=bold,reverse term=bold,reverse
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#5f87af guibg=NONE guisp=NONE gui=NONE ctermfg=67 ctermbg=NONE cterm=NONE term=NONE
 hi Underlined guifg=NONE guibg=NONE guisp=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
+hi VertSplit guifg=#9e9e9e guibg=#9e9e9e guisp=NONE gui=NONE ctermfg=247 ctermbg=247 cterm=NONE term=NONE
+hi VertSplitNC guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
 hi Visual guifg=NONE guibg=#1a3456 guisp=NONE gui=NONE ctermfg=109 ctermbg=234 cterm=reverse term=reverse
 hi VisualNOS guifg=#1c1c1c guibg=#5f8787 guisp=NONE gui=NONE ctermfg=234 ctermbg=66 cterm=NONE term=NONE
 hi WarningMsg guifg=#d75f87 guibg=NONE guisp=NONE gui=NONE ctermfg=168 ctermbg=NONE cterm=NONE term=standout
 hi WildMenu guifg=#1c1c1c guibg=#d7af87 guisp=NONE gui=bold ctermfg=234 ctermbg=180 cterm=bold term=bold
 hi debugBreakpoint guifg=#1c1c1c guibg=#d75f87 guisp=NONE gui=NONE ctermfg=234 ctermbg=168 cterm=NONE term=NONE
 hi debugPC guifg=#1c1c1c guibg=#5f87af guisp=NONE gui=NONE ctermfg=234 ctermbg=67 cterm=NONE term=NONE
+hi htmlH1 guifg=#dadada guibg=NONE guisp=NONE gui=bold ctermfg=253 ctermbg=NONE cterm=bold term=bold
 hi lCursor guifg=#1c1c1c guibg=#5fff00 guisp=NONE gui=NONE ctermfg=234 ctermbg=82 cterm=NONE term=NONE
 
 if s:tgc || s:t_Co >= 256
@@ -202,12 +210,15 @@ if s:t_Co >= 16
   hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold
   hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse
   hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold
-  hi PmenuMatch ctermfg=NONE ctermbg=NONE cterm=bold
-  hi PmenuMatchSel ctermfg=darkyellow ctermbg=NONE cterm=bold
-  hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE
-  hi PmenuSel ctermfg=darkyellow ctermbg=NONE cterm=reverse
+  hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse
+  hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold
+  hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold
   hi PmenuShadow ctermfg=NONE ctermbg=NONE cterm=NONE
-  hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE
+  hi Popup ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PopupBorder ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PopupTitle ctermfg=NONE ctermbg=NONE cterm=bold,reverse
   hi PreProc ctermfg=darkyellow ctermbg=NONE cterm=NONE
   hi Question ctermfg=yellow ctermbg=NONE cterm=NONE
   hi QuickFixLine ctermfg=black ctermbg=magenta cterm=NONE
@@ -231,17 +242,19 @@ if s:t_Co >= 16
   hi TitleBar ctermfg=white ctermbg=black cterm=NONE
   hi TitleBarNC ctermfg=darkgray ctermbg=black cterm=NONE
   hi Todo ctermfg=white ctermbg=NONE cterm=bold
-  hi ToolbarButton ctermfg=darkgray ctermbg=black cterm=bold,reverse
+  hi ToolbarButton ctermfg=NONE ctermbg=NONE cterm=reverse
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkblue ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkgray ctermbg=darkgray cterm=NONE
+  hi VertSplit ctermfg=gray ctermbg=gray cterm=NONE
+  hi VertSplitNC ctermfg=darkgray ctermbg=darkgray cterm=NONE
   hi Visual ctermfg=cyan ctermbg=black cterm=reverse
   hi VisualNOS ctermfg=black ctermbg=darkcyan cterm=NONE
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
   hi WildMenu ctermfg=black ctermbg=yellow cterm=bold
   hi debugBreakpoint ctermfg=black ctermbg=red cterm=NONE
   hi debugPC ctermfg=black ctermbg=darkblue cterm=NONE
+  hi htmlH1 ctermfg=white ctermbg=NONE cterm=bold
   hi lCursor ctermfg=black ctermbg=green cterm=NONE
   finish
 endif
@@ -284,12 +297,15 @@ if s:t_Co >= 8
   hi PmenuExtraSel ctermfg=NONE ctermbg=NONE cterm=bold
   hi PmenuKind ctermfg=NONE ctermbg=NONE cterm=bold,reverse
   hi PmenuKindSel ctermfg=NONE ctermbg=NONE cterm=bold
-  hi PmenuMatch ctermfg=NONE ctermbg=NONE cterm=bold
-  hi PmenuMatchSel ctermfg=darkyellow ctermbg=NONE cterm=bold
-  hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE
-  hi PmenuSel ctermfg=darkyellow ctermbg=NONE cterm=reverse
+  hi PmenuMatch ctermfg=NONE ctermbg=darkred cterm=reverse
+  hi PmenuMatchSel ctermfg=darkred ctermbg=NONE cterm=bold
+  hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PmenuSel ctermfg=NONE ctermbg=NONE cterm=bold
   hi PmenuShadow ctermfg=NONE ctermbg=NONE cterm=NONE
-  hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PmenuThumb ctermfg=NONE ctermbg=NONE cterm=NONE
+  hi Popup ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PopupBorder ctermfg=NONE ctermbg=NONE cterm=reverse
+  hi PopupTitle ctermfg=NONE ctermbg=NONE cterm=bold,reverse
   hi PreProc ctermfg=darkyellow ctermbg=NONE cterm=NONE
   hi Question ctermfg=darkyellow ctermbg=NONE cterm=NONE
   hi QuickFixLine ctermfg=black ctermbg=magenta cterm=NONE
@@ -313,17 +329,19 @@ if s:t_Co >= 8
   hi TitleBar ctermfg=white ctermbg=black cterm=NONE
   hi TitleBarNC ctermfg=darkgray ctermbg=black cterm=NONE
   hi Todo ctermfg=white ctermbg=NONE cterm=bold
-  hi ToolbarButton ctermfg=gray ctermbg=black cterm=reverse
+  hi ToolbarButton ctermfg=NONE ctermbg=NONE cterm=reverse
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkblue ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=gray ctermbg=gray cterm=NONE
+  hi VertSplitNC ctermfg=gray ctermbg=gray cterm=NONE
   hi Visual ctermfg=darkcyan ctermbg=black cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=reverse
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
   hi WildMenu ctermfg=black ctermbg=darkyellow cterm=NONE
   hi debugBreakpoint ctermfg=darkcyan ctermbg=NONE cterm=reverse
   hi debugPC ctermfg=darkblue ctermbg=NONE cterm=reverse
+  hi htmlH1 ctermfg=white ctermbg=NONE cterm=bold
   hi lCursor ctermfg=black ctermbg=green cterm=NONE
   finish
 endif
diff --git a/runtime/colors/industry.vim b/runtime/colors/industry.vim
index 5093293ae6..0bd318a620 100644
--- a/runtime/colors/industry.vim
+++ b/runtime/colors/industry.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Shian Lee.
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -92,7 +92,8 @@ hi Todo guifg=#005fff guibg=#ffff00 guisp=NONE gui=NONE ctermfg=27 ctermbg=226 c
 hi ToolbarLine guifg=NONE guibg=#303030 guisp=NONE gui=NONE ctermfg=NONE ctermbg=236 cterm=NONE term=reverse
 hi Type guifg=#00ff00 guibg=NONE guisp=NONE gui=bold ctermfg=46 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#87afff guibg=NONE guisp=NONE gui=underline ctermfg=111 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#000000 guibg=#6c6c6c guisp=NONE gui=NONE ctermfg=16 ctermbg=242 cterm=NONE term=NONE
+hi VertSplit guifg=#000000 guibg=#dadada guisp=NONE gui=NONE ctermfg=16 ctermbg=253 cterm=NONE term=NONE
+hi VertSplitNC guifg=#000000 guibg=#6c6c6c guisp=NONE gui=NONE ctermfg=16 ctermbg=242 cterm=NONE term=NONE
 hi Visual guifg=#dadada guibg=#6c6c6c guisp=NONE gui=NONE ctermfg=253 ctermbg=242 cterm=NONE term=reverse
 hi VisualNOS guifg=#dadada guibg=#6c6c6c guisp=NONE gui=NONE ctermfg=253 ctermbg=242 cterm=NONE term=NONE
 hi WarningMsg guifg=#ff0000 guibg=NONE guisp=NONE gui=bold ctermfg=196 ctermbg=NONE cterm=bold term=standout
@@ -165,7 +166,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=white ctermbg=darkgrey cterm=NONE
   hi Type ctermfg=green ctermbg=NONE cterm=bold
   hi Underlined ctermfg=darkblue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=black ctermbg=grey cterm=NONE
+  hi VertSplit ctermfg=black ctermbg=white cterm=NONE
+  hi VertSplitNC ctermfg=black ctermbg=grey cterm=NONE
   hi Visual ctermfg=black ctermbg=grey cterm=NONE
   hi VisualNOS ctermfg=white ctermbg=grey cterm=NONE
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=bold
@@ -238,6 +240,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=bold
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=grey ctermbg=black cterm=reverse
+  hi VertSplitNC ctermfg=grey ctermbg=black cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=black ctermbg=grey cterm=NONE
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/koehler.vim b/runtime/colors/koehler.vim
index 8268f4e54c..8247692cea 100644
--- a/runtime/colors/koehler.vim
+++ b/runtime/colors/koehler.vim
@@ -3,9 +3,9 @@
 " Maintainer:   original maintainer Ron Aaron 
 " URL:          https://www.github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 27
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -114,7 +114,8 @@ hi ToolbarButton guifg=#000000 guibg=#e5e5e5 guisp=NONE gui=bold ctermfg=16 cter
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#60ff60 guibg=NONE guisp=NONE gui=bold ctermfg=83 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#add8e6 guibg=NONE guisp=NONE gui=bold,underline ctermfg=153 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#0000ff guibg=#e5e5e5 guisp=NONE gui=NONE ctermfg=21 ctermbg=254 cterm=NONE term=NONE
+hi VertSplit guifg=#0000ff guibg=#ffffff guisp=NONE gui=NONE ctermfg=21 ctermbg=231 cterm=NONE term=NONE
+hi VertSplitNC guifg=#0000ff guibg=#e5e5e5 guisp=NONE gui=NONE ctermfg=21 ctermbg=254 cterm=NONE term=NONE
 hi Visual guifg=NONE guibg=#666666 guisp=NONE gui=reverse ctermfg=NONE ctermbg=59 cterm=reverse term=reverse
 hi VisualNOS guifg=NONE guibg=#000000 guisp=NONE gui=bold,underline ctermfg=NONE ctermbg=16 cterm=underline term=NONE
 hi WarningMsg guifg=#ff0000 guibg=NONE guisp=NONE gui=NONE ctermfg=196 ctermbg=NONE cterm=NONE term=standout
@@ -183,7 +184,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=green ctermbg=NONE cterm=bold
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkblue ctermbg=grey cterm=NONE
+  hi VertSplit ctermfg=darkblue ctermbg=white cterm=NONE
+  hi VertSplitNC ctermfg=darkblue ctermbg=grey cterm=NONE
   hi Visual ctermfg=NONE ctermbg=darkgrey cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=black cterm=underline
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
@@ -251,6 +253,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=bold
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=darkblue ctermbg=grey cterm=NONE
+  hi VertSplitNC ctermfg=darkblue ctermbg=grey cterm=NONE
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=black cterm=underline
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/lunaperche.vim b/runtime/colors/lunaperche.vim
index af745e2cf2..15cd28c3ec 100644
--- a/runtime/colors/lunaperche.vim
+++ b/runtime/colors/lunaperche.vim
@@ -2,9 +2,9 @@
 " Description:  White(perchè il sole)/Black(la luna perchè?) background colorscheme.
 " Author:       Maxim Kim 
 " URL:          https://www.github.com/vim/colorschemes
-" Last Change:  2025 Oct 22
+" Last Change:  2026 Apr 30
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 hi clear
 let g:colors_name = 'lunaperche'
@@ -138,8 +138,8 @@ if &background == 'dark'
   hi PmenuExtraSel guifg=#767676 guibg=#4e4e4e guisp=NONE gui=NONE ctermfg=243 ctermbg=239 cterm=NONE term=NONE
   hi PmenuKind guifg=#ff5f5f guibg=#303030 guisp=NONE gui=NONE ctermfg=203 ctermbg=236 cterm=NONE term=NONE
   hi PmenuKindSel guifg=#ff5f5f guibg=#4e4e4e guisp=NONE gui=NONE ctermfg=203 ctermbg=239 cterm=NONE term=NONE
-  hi PmenuMatch guifg=#d787d7 guibg=#303030 guisp=NONE gui=NONE ctermfg=176 ctermbg=236 cterm=NONE term=NONE
-  hi PmenuMatchSel guifg=#d787d7 guibg=#4e4e4e guisp=NONE gui=NONE ctermfg=176 ctermbg=239 cterm=NONE term=NONE
+  hi PmenuMatch guifg=#d787d7 guibg=NONE guisp=NONE gui=NONE ctermfg=176 ctermbg=NONE cterm=NONE term=NONE
+  hi PmenuMatchSel guifg=#d787d7 guibg=NONE guisp=NONE gui=NONE ctermfg=176 ctermbg=NONE cterm=NONE term=NONE
   hi PmenuSbar guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
   hi PmenuSel guifg=NONE guibg=#4e4e4e guisp=NONE gui=NONE ctermfg=NONE ctermbg=239 cterm=NONE term=bold
   hi PmenuShadow guifg=#767676 guibg=#121212 guisp=NONE gui=NONE ctermfg=243 ctermbg=233 cterm=NONE term=NONE
@@ -171,7 +171,8 @@ if &background == 'dark'
   hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
   hi Type guifg=#5fd75f guibg=NONE guisp=NONE gui=NONE ctermfg=77 ctermbg=NONE cterm=NONE term=NONE
   hi Underlined guifg=NONE guibg=NONE guisp=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline term=underline
-  hi VertSplit guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
+  hi VertSplit guifg=#c6c6c6 guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=251 ctermbg=251 cterm=NONE term=NONE
+  hi VertSplitNC guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
   hi Visual guifg=NONE guibg=#104070 guisp=NONE gui=NONE ctermfg=32 ctermbg=16 cterm=reverse term=reverse
   hi VisualNOS guifg=#000000 guibg=#5fafaf guisp=NONE gui=NONE ctermfg=16 ctermbg=73 cterm=NONE term=NONE
   hi WarningMsg guifg=#ff5f5f guibg=NONE guisp=NONE gui=NONE ctermfg=203 ctermbg=NONE cterm=NONE term=standout
@@ -266,7 +267,8 @@ if &background == 'dark'
     hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
     hi Type ctermfg=green ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
+    hi VertSplit ctermfg=grey ctermbg=grey cterm=NONE
+    hi VertSplitNC ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
     hi Visual ctermfg=darkblue ctermbg=black cterm=reverse
     hi VisualNOS ctermfg=black ctermbg=darkcyan cterm=NONE
     hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
@@ -354,6 +356,7 @@ if &background == 'dark'
     hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
     hi VertSplit ctermfg=grey ctermbg=grey cterm=NONE
+    hi VertSplitNC ctermfg=grey ctermbg=grey cterm=NONE
     hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
     hi VisualNOS ctermfg=black ctermbg=darkcyan cterm=NONE
     hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
@@ -426,8 +429,8 @@ if &background == 'light'
   hi PmenuExtraSel guifg=#767676 guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=243 ctermbg=251 cterm=NONE term=NONE
   hi PmenuKind guifg=#af0000 guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=124 ctermbg=254 cterm=NONE term=NONE
   hi PmenuKindSel guifg=#af0000 guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=124 ctermbg=251 cterm=NONE term=NONE
-  hi PmenuMatch guifg=#af00af guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=127 ctermbg=254 cterm=NONE term=NONE
-  hi PmenuMatchSel guifg=#af00af guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=127 ctermbg=251 cterm=NONE term=NONE
+  hi PmenuMatch guifg=#af00af guibg=NONE guisp=NONE gui=NONE ctermfg=127 ctermbg=NONE cterm=NONE term=NONE
+  hi PmenuMatchSel guifg=#af00af guibg=NONE guisp=NONE gui=NONE ctermfg=127 ctermbg=NONE cterm=NONE term=NONE
   hi PmenuSbar guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
   hi PmenuSel guifg=NONE guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=NONE ctermbg=251 cterm=NONE term=bold
   hi PmenuShadow guifg=#767676 guibg=#303030 guisp=NONE gui=NONE ctermfg=243 ctermbg=236 cterm=NONE term=NONE
@@ -459,7 +462,8 @@ if &background == 'light'
   hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
   hi Type guifg=#008700 guibg=NONE guisp=NONE gui=NONE ctermfg=28 ctermbg=NONE cterm=NONE term=NONE
   hi Underlined guifg=NONE guibg=NONE guisp=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline term=underline
-  hi VertSplit guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
+  hi VertSplit guifg=#000000 guibg=#000000 guisp=NONE gui=NONE ctermfg=16 ctermbg=16 cterm=NONE term=NONE
+  hi VertSplitNC guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
   hi Visual guifg=NONE guibg=#bfdfff guisp=NONE gui=NONE ctermfg=67 ctermbg=231 cterm=reverse term=reverse
   hi VisualNOS guifg=#ffffff guibg=#008787 guisp=NONE gui=NONE ctermfg=231 ctermbg=30 cterm=NONE term=NONE
   hi WarningMsg guifg=#d70000 guibg=NONE guisp=NONE gui=bold ctermfg=160 ctermbg=NONE cterm=bold term=standout
@@ -524,8 +528,8 @@ if &background == 'light'
     hi PmenuExtraSel ctermfg=black ctermbg=darkcyan cterm=NONE
     hi PmenuKind ctermfg=darkred ctermbg=grey cterm=NONE
     hi PmenuKindSel ctermfg=darkred ctermbg=darkcyan cterm=NONE
-    hi PmenuMatch ctermfg=darkmagenta ctermbg=grey cterm=NONE
-    hi PmenuMatchSel ctermfg=darkmagenta ctermbg=darkcyan cterm=NONE
+    hi PmenuMatch ctermfg=darkmagenta ctermbg=NONE cterm=NONE
+    hi PmenuMatchSel ctermfg=darkmagenta ctermbg=NONE cterm=NONE
     hi PmenuSbar ctermfg=NONE ctermbg=NONE cterm=NONE
     hi PmenuSel ctermfg=black ctermbg=darkcyan cterm=NONE
     hi PmenuShadow ctermfg=NONE ctermbg=NONE cterm=NONE
@@ -557,7 +561,8 @@ if &background == 'light'
     hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
     hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
+    hi VertSplit ctermfg=black ctermbg=black cterm=NONE
+    hi VertSplitNC ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
     hi Visual ctermfg=white ctermbg=darkblue cterm=NONE
     hi VisualNOS ctermfg=black ctermbg=cyan cterm=NONE
     hi WarningMsg ctermfg=red ctermbg=NONE cterm=bold
@@ -648,6 +653,7 @@ if &background == 'light'
     hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
     hi VertSplit ctermfg=black ctermbg=black cterm=NONE
+    hi VertSplitNC ctermfg=black ctermbg=black cterm=NONE
     hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
     hi VisualNOS ctermfg=black ctermbg=darkcyan cterm=NONE
     hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/morning.vim b/runtime/colors/morning.vim
index aee04b0326..07b849ecbe 100644
--- a/runtime/colors/morning.vim
+++ b/runtime/colors/morning.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Bram Moolenaar 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=light
 
@@ -92,7 +92,8 @@ hi ToolbarButton guifg=NONE guibg=#bcbcbc guisp=NONE gui=bold ctermfg=NONE cterm
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#2e8b57 guibg=NONE guisp=NONE gui=bold ctermfg=29 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#6a5acd guibg=NONE guisp=NONE gui=underline ctermfg=62 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#bcbcbc guibg=#000000 guisp=NONE gui=NONE ctermfg=250 ctermbg=16 cterm=NONE term=NONE
+hi VertSplit guifg=#eeeeee guibg=#000000 guisp=NONE gui=NONE ctermfg=255 ctermbg=16 cterm=NONE term=NONE
+hi VertSplitNC guifg=#bcbcbc guibg=#000000 guisp=NONE gui=NONE ctermfg=250 ctermbg=16 cterm=NONE term=NONE
 hi Visual guifg=NONE guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=NONE ctermbg=252 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=#0000ff guisp=NONE gui=NONE ctermfg=NONE ctermbg=21 cterm=NONE term=NONE
 hi WarningMsg guifg=#6a0dad guibg=NONE guisp=NONE gui=bold ctermfg=55 ctermbg=NONE cterm=bold term=standout
@@ -162,7 +163,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=bold
   hi Underlined ctermfg=darkblue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkgrey ctermbg=black cterm=NONE
+  hi VertSplit ctermfg=white ctermbg=black cterm=NONE
+  hi VertSplitNC ctermfg=darkgrey ctermbg=black cterm=NONE
   hi Visual ctermfg=NONE ctermbg=white cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=blue cterm=NONE
   hi WarningMsg ctermfg=darkmagenta ctermbg=NONE cterm=bold
@@ -231,6 +233,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=black ctermbg=gray cterm=reverse
+  hi VertSplitNC ctermfg=black ctermbg=gray cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkmagenta ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/murphy.vim b/runtime/colors/murphy.vim
index a5610fc584..21c48e3032 100644
--- a/runtime/colors/murphy.vim
+++ b/runtime/colors/murphy.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Ron Aaron .
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -93,7 +93,8 @@ hi ToolbarButton guifg=#ffffff guibg=#444444 guisp=NONE gui=bold ctermfg=231 cte
 hi ToolbarLine guifg=NONE guibg=#303030 guisp=NONE gui=NONE ctermfg=NONE ctermbg=236 cterm=NONE term=reverse
 hi Type guifg=#bcbcbc guibg=NONE guisp=NONE gui=NONE ctermfg=250 ctermbg=NONE cterm=NONE term=NONE
 hi Underlined guifg=#00afaf guibg=NONE guisp=NONE gui=underline ctermfg=37 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#ffffff guibg=#3a3a3a guisp=NONE gui=NONE ctermfg=231 ctermbg=237 cterm=NONE term=NONE
+hi VertSplit guifg=#ffffff guibg=#00008b guisp=NONE gui=NONE ctermfg=231 ctermbg=18 cterm=NONE term=NONE
+hi VertSplitNC guifg=#ffffff guibg=#3a3a3a guisp=NONE gui=NONE ctermfg=231 ctermbg=237 cterm=NONE term=NONE
 hi Visual guifg=#ffffff guibg=#005f00 guisp=NONE gui=NONE ctermfg=231 ctermbg=22 cterm=NONE term=reverse
 hi VisualNOS guifg=#ffffff guibg=#005f00 guisp=NONE gui=NONE ctermfg=231 ctermbg=22 cterm=NONE term=NONE
 hi WarningMsg guifg=#ffa700 guibg=NONE guisp=NONE gui=bold ctermfg=214 ctermbg=NONE cterm=bold term=standout
@@ -163,7 +164,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=black cterm=NONE
   hi Type ctermfg=grey ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=darkcyan ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=white ctermbg=darkgrey cterm=NONE
+  hi VertSplit ctermfg=white ctermbg=darkblue cterm=NONE
+  hi VertSplitNC ctermfg=white ctermbg=darkgrey cterm=NONE
   hi Visual ctermfg=white ctermbg=darkgreen cterm=NONE
   hi VisualNOS ctermfg=white ctermbg=darkgreen cterm=NONE
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=bold
@@ -231,7 +233,8 @@ if s:t_Co >= 8
   hi ToolbarLine ctermfg=NONE ctermbg=black cterm=NONE
   hi Type ctermfg=grey ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=grey ctermbg=black cterm=reverse
+  hi VertSplit ctermfg=darkblue ctermbg=grey cterm=reverse
+  hi VertSplitNC ctermfg=grey ctermbg=black cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=reverse,underline
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=bold
diff --git a/runtime/colors/pablo.vim b/runtime/colors/pablo.vim
index 8829c0700d..4b85040417 100644
--- a/runtime/colors/pablo.vim
+++ b/runtime/colors/pablo.vim
@@ -3,9 +3,9 @@
 " Maintainer:   Original maintainerRon Aaron 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -92,7 +92,8 @@ hi ToolbarButton guifg=#000000 guibg=#e5e5e5 guisp=NONE gui=bold ctermfg=16 cter
 hi ToolbarLine guifg=NONE guibg=#000000 guisp=NONE gui=NONE ctermfg=NONE ctermbg=16 cterm=NONE term=reverse
 hi Type guifg=#00c000 guibg=NONE guisp=NONE gui=NONE ctermfg=34 ctermbg=NONE cterm=NONE term=NONE
 hi Underlined guifg=#80a0ff guibg=NONE guisp=NONE gui=underline ctermfg=111 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#000000 guibg=#ffffff guisp=NONE gui=NONE ctermfg=16 ctermbg=231 cterm=NONE term=NONE
+hi VertSplit guifg=#ffff00 guibg=#0000ee guisp=NONE gui=NONE ctermfg=226 ctermbg=20 cterm=NONE term=NONE
+hi VertSplitNC guifg=#000000 guibg=#ffffff guisp=NONE gui=NONE ctermfg=16 ctermbg=231 cterm=NONE term=NONE
 hi Visual guifg=#00008b guibg=#a9a9a9 guisp=NONE gui=NONE ctermfg=20 ctermbg=248 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=#000000 guisp=NONE gui=bold,underline ctermfg=NONE ctermbg=16 cterm=underline term=NONE
 hi WarningMsg guifg=#ff0000 guibg=NONE guisp=NONE gui=NONE ctermfg=196 ctermbg=NONE cterm=NONE term=standout
@@ -163,7 +164,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=black cterm=NONE
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=darkgreen ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=black ctermbg=white cterm=NONE
+  hi VertSplit ctermfg=yellow ctermbg=darkblue cterm=NONE
+  hi VertSplitNC ctermfg=black ctermbg=white cterm=NONE
   hi Visual ctermfg=darkblue ctermbg=grey cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=black cterm=underline
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
@@ -234,7 +236,8 @@ if s:t_Co >= 8
   hi ToolbarLine ctermfg=NONE ctermbg=black cterm=NONE
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=bold
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=grey ctermbg=black cterm=reverse
+  hi VertSplit ctermfg=darkblue ctermbg=grey cterm=reverse
+  hi VertSplitNC ctermfg=grey ctermbg=black cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=black ctermbg=grey cterm=NONE
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/peachpuff.vim b/runtime/colors/peachpuff.vim
index cff502b496..a433eee7ad 100644
--- a/runtime/colors/peachpuff.vim
+++ b/runtime/colors/peachpuff.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer David Ne\v{c}as (Yeti) 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 14
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=light
 
@@ -94,7 +94,8 @@ hi ToolbarButton guifg=#ffdab9 guibg=#737373 guisp=NONE gui=bold ctermfg=223 cte
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#2e8b57 guibg=NONE guisp=NONE gui=bold ctermfg=29 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#6a5acd guibg=NONE guisp=NONE gui=underline ctermfg=62 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#ffdab9 guibg=#737373 guisp=NONE gui=NONE ctermfg=223 ctermbg=243 cterm=NONE term=NONE
+hi VertSplit guifg=#ffdab9 guibg=#000000 guisp=NONE gui=NONE ctermfg=223 ctermbg=16 cterm=NONE term=NONE
+hi VertSplitNC guifg=#ffdab9 guibg=#737373 guisp=NONE gui=NONE ctermfg=223 ctermbg=243 cterm=NONE term=NONE
 hi Visual guifg=#000000 guibg=#cccccc guisp=NONE gui=NONE ctermfg=16 ctermbg=252 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=#406090 guisp=NONE gui=NONE ctermfg=NONE ctermbg=25 cterm=NONE term=NONE
 hi WarningMsg guifg=#cd00cd guibg=#ffdab9 guisp=NONE gui=bold ctermfg=164 ctermbg=223 cterm=bold term=standout
@@ -168,7 +169,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=bold
   hi Underlined ctermfg=darkblue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=white ctermbg=darkgrey cterm=NONE
+  hi VertSplit ctermfg=white ctermbg=black cterm=NONE
+  hi VertSplitNC ctermfg=white ctermbg=darkgrey cterm=NONE
   hi Visual ctermfg=black ctermbg=grey cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=darkgrey cterm=NONE
   hi WarningMsg ctermfg=darkmagenta ctermbg=white cterm=bold
@@ -241,6 +243,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=black ctermbg=gray cterm=reverse
+  hi VertSplitNC ctermfg=black ctermbg=gray cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkmagenta ctermbg=NONE cterm=bold
diff --git a/runtime/colors/retrobox.vim b/runtime/colors/retrobox.vim
index afe53ee5a5..59c06855a6 100644
--- a/runtime/colors/retrobox.vim
+++ b/runtime/colors/retrobox.vim
@@ -2,9 +2,9 @@
 " Description:  Retro groove color scheme similar to gruvbox originally designed by morhetz 
 " Author:       Maxim Kim , ported from gruvbox8 of Lifepillar 
 " URL:          https://www.github.com/vim/colorschemes
-" Last Change:  2025 Oct 22
+" Last Change:  2026 Apr 30
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 hi clear
 let g:colors_name = 'retrobox'
@@ -79,8 +79,8 @@ if &background == 'dark'
   hi PmenuExtraSel guifg=#a89984 guibg=#504945 guisp=NONE gui=NONE ctermfg=102 ctermbg=239 cterm=NONE term=NONE
   hi PmenuKind guifg=#fb5944 guibg=#3c3836 guisp=NONE gui=NONE ctermfg=203 ctermbg=237 cterm=NONE term=NONE
   hi PmenuKindSel guifg=#fb5944 guibg=#504945 guisp=NONE gui=NONE ctermfg=203 ctermbg=239 cterm=NONE term=NONE
-  hi PmenuMatch guifg=#d3869b guibg=#3c3836 guisp=NONE gui=NONE ctermfg=175 ctermbg=237 cterm=NONE term=NONE
-  hi PmenuMatchSel guifg=#d3869b guibg=#504945 guisp=NONE gui=NONE ctermfg=175 ctermbg=239 cterm=NONE term=NONE
+  hi PmenuMatch guifg=#d3869b guibg=NONE guisp=NONE gui=NONE ctermfg=175 ctermbg=NONE cterm=NONE term=NONE
+  hi PmenuMatchSel guifg=#d3869b guibg=NONE guisp=NONE gui=NONE ctermfg=175 ctermbg=NONE cterm=NONE term=NONE
   hi PmenuSbar guifg=NONE guibg=#3c3836 guisp=NONE gui=NONE ctermfg=NONE ctermbg=237 cterm=NONE term=reverse
   hi PmenuSel guifg=NONE guibg=#504945 guisp=NONE gui=NONE ctermfg=NONE ctermbg=239 cterm=NONE term=bold
   hi PmenuShadow guifg=#a89984 guibg=#121212 guisp=NONE gui=NONE ctermfg=102 ctermbg=233 cterm=NONE term=NONE
@@ -118,7 +118,8 @@ if &background == 'dark'
   hi Type guifg=#fabd2f guibg=NONE guisp=NONE gui=NONE ctermfg=214 ctermbg=NONE cterm=NONE term=NONE
   hi Typedef guifg=#fabd2f guibg=NONE guisp=NONE gui=NONE ctermfg=214 ctermbg=NONE cterm=NONE term=NONE
   hi Underlined guifg=#83a598 guibg=NONE guisp=NONE gui=underline ctermfg=109 ctermbg=NONE cterm=underline term=underline
-  hi VertSplit guifg=#303030 guibg=#1c1c1c guisp=NONE gui=NONE ctermfg=236 ctermbg=234 cterm=NONE term=NONE
+  hi VertSplit guifg=#504945 guibg=#1c1c1c guisp=NONE gui=NONE ctermfg=239 ctermbg=234 cterm=NONE term=NONE
+  hi VertSplitNC guifg=#303030 guibg=#1c1c1c guisp=NONE gui=NONE ctermfg=236 ctermbg=234 cterm=NONE term=NONE
   hi Visual guifg=NONE guibg=#2a405a guisp=NONE gui=NONE ctermfg=109 ctermbg=234 cterm=reverse term=reverse
   hi WarningMsg guifg=#fb5944 guibg=NONE guisp=NONE gui=bold ctermfg=203 ctermbg=NONE cterm=bold term=standout
   hi WildMenu guifg=#83a598 guibg=#504945 guisp=NONE gui=bold ctermfg=109 ctermbg=239 cterm=bold term=bold
@@ -221,7 +222,8 @@ if &background == 'dark'
     hi Type ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Typedef ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=Blue ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=Black ctermbg=gray cterm=NONE
+    hi VertSplit ctermfg=gray ctermbg=Black cterm=NONE
+    hi VertSplitNC ctermfg=gray ctermbg=Black cterm=NONE
     hi Visual ctermfg=Blue ctermbg=Black cterm=reverse
     hi WarningMsg ctermfg=Red ctermbg=NONE cterm=bold
     hi WildMenu ctermfg=White ctermbg=Black cterm=bold
@@ -316,7 +318,8 @@ if &background == 'dark'
     hi Type ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Typedef ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=Blue ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=Black ctermbg=gray cterm=NONE
+    hi VertSplit ctermfg=gray ctermbg=Black cterm=NONE
+    hi VertSplitNC ctermfg=gray ctermbg=Black cterm=NONE
     hi Visual ctermfg=Black ctermbg=Blue cterm=NONE
     hi WarningMsg ctermfg=Red ctermbg=NONE cterm=bold
     hi WildMenu ctermfg=Blue ctermbg=DarkGray cterm=bold
@@ -389,8 +392,8 @@ if &background == 'light'
   hi PmenuExtraSel guifg=#3c3836 guibg=#bdae93 guisp=NONE gui=NONE ctermfg=237 ctermbg=144 cterm=NONE term=NONE
   hi PmenuKind guifg=#9d0006 guibg=#e5d4b1 guisp=NONE gui=NONE ctermfg=124 ctermbg=187 cterm=NONE term=NONE
   hi PmenuKindSel guifg=#9d0006 guibg=#bdae93 guisp=NONE gui=NONE ctermfg=124 ctermbg=144 cterm=NONE term=NONE
-  hi PmenuMatch guifg=#8f3f71 guibg=#e5d4b1 guisp=NONE gui=NONE ctermfg=126 ctermbg=187 cterm=NONE term=NONE
-  hi PmenuMatchSel guifg=#8f3f71 guibg=#bdae93 guisp=NONE gui=NONE ctermfg=126 ctermbg=144 cterm=NONE term=NONE
+  hi PmenuMatch guifg=#8f3f71 guibg=NONE guisp=NONE gui=NONE ctermfg=126 ctermbg=NONE cterm=NONE term=NONE
+  hi PmenuMatchSel guifg=#8f3f71 guibg=NONE guisp=NONE gui=NONE ctermfg=126 ctermbg=NONE cterm=NONE term=NONE
   hi PmenuSbar guifg=NONE guibg=#e5d4b1 guisp=NONE gui=NONE ctermfg=NONE ctermbg=187 cterm=NONE term=reverse
   hi PmenuSel guifg=NONE guibg=#bdae93 guisp=NONE gui=NONE ctermfg=NONE ctermbg=144 cterm=NONE term=bold
   hi PmenuShadow guifg=#7c6f64 guibg=#303030 guisp=NONE gui=NONE ctermfg=243 ctermbg=236 cterm=NONE term=NONE
@@ -428,7 +431,8 @@ if &background == 'light'
   hi Type guifg=#b57614 guibg=NONE guisp=NONE gui=NONE ctermfg=172 ctermbg=NONE cterm=NONE term=NONE
   hi Typedef guifg=#b57614 guibg=NONE guisp=NONE gui=NONE ctermfg=172 ctermbg=NONE cterm=NONE term=NONE
   hi Underlined guifg=#076678 guibg=NONE guisp=NONE gui=underline ctermfg=23 ctermbg=NONE cterm=underline term=underline
-  hi VertSplit guifg=#bdae93 guibg=#fbf1c7 guisp=NONE gui=NONE ctermfg=144 ctermbg=230 cterm=NONE term=NONE
+  hi VertSplit guifg=#7c6f64 guibg=#fbf1c7 guisp=NONE gui=NONE ctermfg=243 ctermbg=230 cterm=NONE term=NONE
+  hi VertSplitNC guifg=#bdae93 guibg=#fbf1c7 guisp=NONE gui=NONE ctermfg=144 ctermbg=230 cterm=NONE term=NONE
   hi Visual guifg=NONE guibg=#b0d0d0 guisp=NONE gui=NONE ctermfg=23 ctermbg=230 cterm=reverse term=reverse
   hi WarningMsg guifg=#9d0006 guibg=NONE guisp=NONE gui=bold ctermfg=124 ctermbg=NONE cterm=bold term=standout
   hi WildMenu guifg=#076678 guibg=#e5d4b1 guisp=NONE gui=bold ctermfg=23 ctermbg=187 cterm=bold term=bold
@@ -531,7 +535,8 @@ if &background == 'light'
     hi Type ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Typedef ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=Blue ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=DarkGray ctermbg=Grey cterm=NONE
+    hi VertSplit ctermfg=DarkGray ctermbg=White cterm=NONE
+    hi VertSplitNC ctermfg=DarkGray ctermbg=White cterm=NONE
     hi Visual ctermfg=Blue ctermbg=White cterm=reverse
     hi WarningMsg ctermfg=Red ctermbg=NONE cterm=bold
     hi WildMenu ctermfg=Black ctermbg=White cterm=bold
@@ -626,7 +631,8 @@ if &background == 'light'
     hi Type ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Typedef ctermfg=Yellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=Blue ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=White ctermbg=Black cterm=NONE
+    hi VertSplit ctermfg=Black ctermbg=White cterm=NONE
+    hi VertSplitNC ctermfg=Black ctermbg=White cterm=NONE
     hi Visual ctermfg=White ctermbg=Blue cterm=NONE
     hi WarningMsg ctermfg=Red ctermbg=NONE cterm=bold
     hi WildMenu ctermfg=Blue ctermbg=Grey cterm=bold
diff --git a/runtime/colors/shine.vim b/runtime/colors/shine.vim
index 4493bd4b2f..bbd3c9c27a 100644
--- a/runtime/colors/shine.vim
+++ b/runtime/colors/shine.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer is Yasuhiro Matsumoto 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 27
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=light
 
@@ -96,7 +96,8 @@ hi ToolbarButton guifg=NONE guibg=#a8a8a8 guisp=NONE gui=bold ctermfg=NONE cterm
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#2e8b57 guibg=NONE guisp=NONE gui=bold ctermfg=29 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#6a0dad guibg=NONE guisp=NONE gui=underline ctermfg=55 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#a8a8a8 guibg=#a8a8a8 guisp=NONE gui=NONE ctermfg=248 ctermbg=248 cterm=NONE term=NONE
+hi VertSplit guifg=#000000 guibg=#000000 guisp=NONE gui=NONE ctermfg=16 ctermbg=16 cterm=NONE term=NONE
+hi VertSplitNC guifg=#a8a8a8 guibg=#a8a8a8 guisp=NONE gui=NONE ctermfg=248 ctermbg=248 cterm=NONE term=NONE
 hi Visual guifg=#000000 guibg=#a8a8a8 guisp=NONE gui=NONE ctermfg=16 ctermbg=248 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=NONE guisp=NONE gui=bold ctermfg=NONE ctermbg=NONE cterm=underline term=NONE
 hi WarningMsg guifg=#6a0dad guibg=#ffffff guisp=NONE gui=NONE ctermfg=55 ctermbg=231 cterm=NONE term=standout
@@ -170,7 +171,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=bold
   hi Underlined ctermfg=darkmagenta ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
+  hi VertSplit ctermfg=black ctermbg=black cterm=NONE
+  hi VertSplitNC ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
   hi Visual ctermfg=black ctermbg=darkgrey cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkmagenta ctermbg=white cterm=NONE
@@ -243,6 +245,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=black ctermbg=grey cterm=reverse
+  hi VertSplitNC ctermfg=black ctermbg=grey cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkmagenta ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/slate.vim b/runtime/colors/slate.vim
index 9795408bb6..ce9d26900c 100644
--- a/runtime/colors/slate.vim
+++ b/runtime/colors/slate.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Ralph Amissah 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 27
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -93,7 +93,8 @@ hi ToolbarButton guifg=#262626 guibg=#d7d787 guisp=NONE gui=NONE ctermfg=235 cte
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#5f87d7 guibg=NONE guisp=NONE gui=bold ctermfg=68 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#5f87d7 guibg=NONE guisp=NONE gui=underline ctermfg=68 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#666666 guibg=#afaf87 guisp=NONE gui=NONE ctermfg=241 ctermbg=144 cterm=NONE term=NONE
+hi VertSplit guifg=#000000 guibg=#afaf87 guisp=NONE gui=NONE ctermfg=16 ctermbg=144 cterm=NONE term=NONE
+hi VertSplitNC guifg=#666666 guibg=#afaf87 guisp=NONE gui=NONE ctermfg=241 ctermbg=144 cterm=NONE term=NONE
 hi Visual guifg=#d7d787 guibg=#5f8700 guisp=NONE gui=NONE ctermfg=186 ctermbg=64 cterm=NONE term=reverse
 hi VisualNOS guifg=#d7d787 guibg=#5f8700 guisp=NONE gui=NONE ctermfg=186 ctermbg=64 cterm=NONE term=NONE
 hi WarningMsg guifg=#ff8787 guibg=NONE guisp=NONE gui=NONE ctermfg=210 ctermbg=NONE cterm=NONE term=standout
@@ -173,7 +174,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=blue ctermbg=NONE cterm=bold
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkgrey ctermbg=grey cterm=NONE
+  hi VertSplit ctermfg=white ctermbg=black cterm=reverse
+  hi VertSplitNC ctermfg=darkgrey ctermbg=grey cterm=NONE
   hi Visual ctermfg=yellow ctermbg=darkgreen cterm=NONE
   hi VisualNOS ctermfg=darkmagenta ctermbg=darkgreen cterm=NONE
   hi WarningMsg ctermfg=cyan ctermbg=NONE cterm=NONE
@@ -247,6 +249,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkblue ctermbg=NONE cterm=bold
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=grey ctermbg=black cterm=reverse
+  hi VertSplitNC ctermfg=grey ctermbg=black cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=darkmagenta ctermbg=darkgreen cterm=underline
   hi WarningMsg ctermfg=darkcyan ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/torte.vim b/runtime/colors/torte.vim
index 6f53c7d958..e23324fb48 100644
--- a/runtime/colors/torte.vim
+++ b/runtime/colors/torte.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Thorsten Maerz 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 24
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -93,7 +93,8 @@ hi ToolbarButton guifg=#000000 guibg=#e5e5e5 guisp=NONE gui=bold ctermfg=16 cter
 hi ToolbarLine guifg=NONE guibg=#000000 guisp=NONE gui=NONE ctermfg=NONE ctermbg=16 cterm=NONE term=reverse
 hi Type guifg=#60ff60 guibg=NONE guisp=NONE gui=NONE ctermfg=83 ctermbg=NONE cterm=NONE term=NONE
 hi Underlined guifg=#80a0ff guibg=NONE guisp=NONE gui=underline ctermfg=111 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#000000 guibg=#e5e5e5 guisp=NONE gui=NONE ctermfg=16 ctermbg=254 cterm=NONE term=NONE
+hi VertSplit guifg=#000000 guibg=#0000ee guisp=NONE gui=NONE ctermfg=16 ctermbg=20 cterm=NONE term=NONE
+hi VertSplitNC guifg=#000000 guibg=#e5e5e5 guisp=NONE gui=NONE ctermfg=16 ctermbg=254 cterm=NONE term=NONE
 hi Visual guifg=#000000 guibg=#a9a9a9 guisp=NONE gui=bold ctermfg=16 ctermbg=248 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=#000000 guisp=NONE gui=bold,underline ctermfg=NONE ctermbg=16 cterm=underline term=NONE
 hi WarningMsg guifg=#ff0000 guibg=NONE guisp=NONE gui=NONE ctermfg=196 ctermbg=NONE cterm=NONE term=standout
@@ -164,7 +165,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=black cterm=NONE
   hi Type ctermfg=green ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=black ctermbg=grey cterm=NONE
+  hi VertSplit ctermfg=black ctermbg=darkblue cterm=NONE
+  hi VertSplitNC ctermfg=black ctermbg=grey cterm=NONE
   hi Visual ctermfg=black ctermbg=grey cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=black cterm=underline
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
@@ -233,7 +235,8 @@ if s:t_Co >= 8
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkgreen ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=black ctermbg=grey cterm=NONE
+  hi VertSplit ctermfg=grey ctermbg=darkblue cterm=NONE
+  hi VertSplitNC ctermfg=black ctermbg=grey cterm=NONE
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=black cterm=underline
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/unokai.vim b/runtime/colors/unokai.vim
index 60cacf0b56..7c85cba568 100644
--- a/runtime/colors/unokai.vim
+++ b/runtime/colors/unokai.vim
@@ -2,9 +2,9 @@
 " Description:  Color scheme similar to Monokai originally created by Wimer Hazenberg for TextMate
 " Author:       k-37 <60838818+k-37@users.noreply.github.com>
 " URL:          https://github.com/vim/colorschemes
-" Last Change:  2025 Oct 08
+" Last Change:  2026 May 07
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=dark
 
@@ -108,7 +108,8 @@ hi ToolbarButton guifg=#74705d guibg=#f8f8f2 guisp=NONE gui=bold,reverse ctermfg
 hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
 hi Type guifg=#fd971f guibg=NONE guisp=NONE gui=bold ctermfg=208 ctermbg=NONE cterm=bold term=NONE
 hi Underlined guifg=#66d9ef guibg=NONE guisp=NONE gui=underline ctermfg=81 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#74705d guibg=#74705d guisp=NONE gui=NONE ctermfg=244 ctermbg=244 cterm=NONE term=NONE
+hi VertSplit guifg=#bababa guibg=#bababa guisp=NONE gui=NONE ctermfg=250 ctermbg=250 cterm=NONE term=NONE
+hi VertSplitNC guifg=#74705d guibg=#74705d guisp=NONE gui=NONE ctermfg=244 ctermbg=244 cterm=NONE term=NONE
 hi Visual guifg=#a1efe4 guibg=#282923 guisp=NONE gui=reverse ctermfg=116 ctermbg=235 cterm=reverse term=reverse
 hi VisualNOS guifg=#282923 guibg=#80beb5 guisp=NONE gui=NONE ctermfg=235 ctermbg=73 cterm=NONE term=NONE
 hi WarningMsg guifg=#f92672 guibg=NONE guisp=NONE gui=NONE ctermfg=197 ctermbg=NONE cterm=NONE term=standout
@@ -206,7 +207,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
   hi Type ctermfg=darkyellow ctermbg=NONE cterm=bold
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=darkgray ctermbg=darkgray cterm=NONE
+  hi VertSplit ctermfg=gray ctermbg=gray cterm=NONE
+  hi VertSplitNC ctermfg=darkgray ctermbg=darkgray cterm=NONE
   hi Visual ctermfg=cyan ctermbg=black cterm=reverse
   hi VisualNOS ctermfg=black ctermbg=darkcyan cterm=NONE
   hi WarningMsg ctermfg=red ctermbg=NONE cterm=NONE
@@ -298,6 +300,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkyellow ctermbg=NONE cterm=bold
   hi Underlined ctermfg=darkblue ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=gray ctermbg=gray cterm=NONE
+  hi VertSplitNC ctermfg=gray ctermbg=gray cterm=NONE
   hi Visual ctermfg=black ctermbg=darkcyan cterm=NONE
   hi VisualNOS ctermfg=black ctermbg=darkcyan cterm=NONE
   hi WarningMsg ctermfg=darkred ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/wildcharm.vim b/runtime/colors/wildcharm.vim
index fd52078dc4..4009437288 100644
--- a/runtime/colors/wildcharm.vim
+++ b/runtime/colors/wildcharm.vim
@@ -3,9 +3,9 @@
 " Author:       Maxim Kim 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 22
+" Last Change:  2026 Apr 30
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 hi clear
 let g:colors_name = 'wildcharm'
@@ -67,8 +67,8 @@ if &background == 'dark'
   hi PmenuExtraSel guifg=#767676 guibg=#585858 guisp=NONE gui=NONE ctermfg=243 ctermbg=240 cterm=NONE term=NONE
   hi PmenuKind guifg=#ff5f87 guibg=#303030 guisp=NONE gui=NONE ctermfg=204 ctermbg=236 cterm=NONE term=NONE
   hi PmenuKindSel guifg=#ff5f87 guibg=#585858 guisp=NONE gui=NONE ctermfg=204 ctermbg=240 cterm=NONE term=NONE
-  hi PmenuMatch guifg=#d787d7 guibg=#303030 guisp=NONE gui=NONE ctermfg=176 ctermbg=236 cterm=NONE term=NONE
-  hi PmenuMatchSel guifg=#d787d7 guibg=#585858 guisp=NONE gui=NONE ctermfg=176 ctermbg=240 cterm=NONE term=NONE
+  hi PmenuMatch guifg=#d787d7 guibg=NONE guisp=NONE gui=NONE ctermfg=176 ctermbg=NONE cterm=NONE term=NONE
+  hi PmenuMatchSel guifg=#d787d7 guibg=NONE guisp=NONE gui=NONE ctermfg=176 ctermbg=NONE cterm=NONE term=NONE
   hi PmenuSbar guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
   hi PmenuSel guifg=NONE guibg=#585858 guisp=NONE gui=NONE ctermfg=NONE ctermbg=240 cterm=NONE term=bold
   hi PmenuShadow guifg=#767676 guibg=#121212 guisp=NONE gui=NONE ctermfg=243 ctermbg=233 cterm=NONE term=NONE
@@ -100,7 +100,8 @@ if &background == 'dark'
   hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
   hi Type guifg=#ffaf00 guibg=NONE guisp=NONE gui=NONE ctermfg=214 ctermbg=NONE cterm=NONE term=NONE
   hi Underlined guifg=NONE guibg=NONE guisp=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline term=underline
-  hi VertSplit guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
+  hi VertSplit guifg=#9e9e9e guibg=#9e9e9e guisp=NONE gui=NONE ctermfg=247 ctermbg=247 cterm=NONE term=NONE
+  hi VertSplitNC guifg=#767676 guibg=#767676 guisp=NONE gui=NONE ctermfg=243 ctermbg=243 cterm=NONE term=NONE
   hi Visual guifg=NONE guibg=#204060 guisp=NONE gui=NONE ctermfg=81 ctermbg=16 cterm=reverse term=reverse
   hi VisualNOS guifg=#000000 guibg=#00afff guisp=NONE gui=NONE ctermfg=16 ctermbg=39 cterm=NONE term=NONE
   hi WarningMsg guifg=#ffaf00 guibg=NONE guisp=NONE gui=NONE ctermfg=214 ctermbg=NONE cterm=NONE term=standout
@@ -191,7 +192,8 @@ if &background == 'dark'
     hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
     hi Type ctermfg=yellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
+    hi VertSplit ctermfg=grey ctermbg=grey cterm=NONE
+    hi VertSplitNC ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
     hi Visual ctermfg=cyan ctermbg=black cterm=reverse
     hi VisualNOS ctermfg=black ctermbg=blue cterm=NONE
     hi WarningMsg ctermfg=yellow ctermbg=NONE cterm=NONE
@@ -270,6 +272,7 @@ if &background == 'dark'
     hi Type ctermfg=darkyellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
     hi VertSplit ctermfg=grey ctermbg=grey cterm=NONE
+    hi VertSplitNC ctermfg=grey ctermbg=grey cterm=NONE
     hi Visual ctermfg=darkblue ctermbg=black cterm=reverse
     hi VisualNOS ctermfg=black ctermbg=darkblue cterm=NONE
     hi WarningMsg ctermfg=darkyellow ctermbg=NONE cterm=NONE
@@ -331,13 +334,13 @@ if &background == 'light'
   hi Pmenu guifg=NONE guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=NONE ctermbg=254 cterm=NONE term=reverse
   hi PmenuBorder guifg=#808080 guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=240 ctermbg=254 cterm=NONE term=NONE
   hi PmenuExtra guifg=#808080 guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=240 ctermbg=254 cterm=NONE term=NONE
-  hi PmenuExtraSel guifg=#808080 guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=240 ctermbg=252 cterm=NONE term=NONE
+  hi PmenuExtraSel guifg=#808080 guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=240 ctermbg=251 cterm=NONE term=NONE
   hi PmenuKind guifg=#d70000 guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=160 ctermbg=254 cterm=NONE term=NONE
-  hi PmenuKindSel guifg=#d70000 guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=160 ctermbg=252 cterm=NONE term=NONE
-  hi PmenuMatch guifg=#870087 guibg=#e4e4e4 guisp=NONE gui=NONE ctermfg=90 ctermbg=254 cterm=NONE term=NONE
-  hi PmenuMatchSel guifg=#870087 guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=90 ctermbg=252 cterm=NONE term=NONE
+  hi PmenuKindSel guifg=#d70000 guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=160 ctermbg=251 cterm=NONE term=NONE
+  hi PmenuMatch guifg=#870087 guibg=NONE guisp=NONE gui=NONE ctermfg=90 ctermbg=NONE cterm=NONE term=NONE
+  hi PmenuMatchSel guifg=#870087 guibg=NONE guisp=NONE gui=NONE ctermfg=90 ctermbg=NONE cterm=NONE term=NONE
   hi PmenuSbar guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
-  hi PmenuSel guifg=NONE guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=NONE ctermbg=252 cterm=NONE term=bold
+  hi PmenuSel guifg=NONE guibg=#c6c6c6 guisp=NONE gui=NONE ctermfg=NONE ctermbg=251 cterm=NONE term=bold
   hi PmenuShadow guifg=#808080 guibg=#303030 guisp=NONE gui=NONE ctermfg=240 ctermbg=236 cterm=NONE term=NONE
   hi PmenuThumb guifg=NONE guibg=#808080 guisp=NONE gui=NONE ctermfg=NONE ctermbg=240 cterm=NONE term=NONE
   hi PreProc guifg=#008787 guibg=NONE guisp=NONE gui=NONE ctermfg=30 ctermbg=NONE cterm=NONE term=NONE
@@ -367,7 +370,8 @@ if &background == 'light'
   hi ToolbarLine guifg=NONE guibg=NONE guisp=NONE gui=NONE ctermfg=NONE ctermbg=NONE cterm=NONE term=reverse
   hi Type guifg=#af5f00 guibg=NONE guisp=NONE gui=NONE ctermfg=130 ctermbg=NONE cterm=NONE term=NONE
   hi Underlined guifg=NONE guibg=NONE guisp=NONE gui=underline ctermfg=NONE ctermbg=NONE cterm=underline term=underline
-  hi VertSplit guifg=#d0d0d0 guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=252 ctermbg=252 cterm=NONE term=NONE
+  hi VertSplit guifg=#5f5f5f guibg=#5f5f5f guisp=NONE gui=NONE ctermfg=59 ctermbg=59 cterm=NONE term=NONE
+  hi VertSplitNC guifg=#d0d0d0 guibg=#d0d0d0 guisp=NONE gui=NONE ctermfg=252 ctermbg=252 cterm=NONE term=NONE
   hi Visual guifg=NONE guibg=#bfdfff guisp=NONE gui=NONE ctermfg=32 ctermbg=231 cterm=reverse term=reverse
   hi VisualNOS guifg=#ffffff guibg=#005faf guisp=NONE gui=NONE ctermfg=231 ctermbg=25 cterm=NONE term=NONE
   hi WarningMsg guifg=#af5f00 guibg=NONE guisp=NONE gui=NONE ctermfg=130 ctermbg=NONE cterm=NONE term=standout
@@ -458,7 +462,8 @@ if &background == 'light'
     hi ToolbarLine ctermfg=NONE ctermbg=NONE cterm=NONE
     hi Type ctermfg=darkyellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
-    hi VertSplit ctermfg=lightgrey ctermbg=lightgrey cterm=NONE
+    hi VertSplit ctermfg=darkgrey ctermbg=darkgrey cterm=NONE
+    hi VertSplitNC ctermfg=lightgrey ctermbg=lightgrey cterm=NONE
     hi Visual ctermfg=blue ctermbg=white cterm=reverse
     hi VisualNOS ctermfg=white ctermbg=darkblue cterm=NONE
     hi WarningMsg ctermfg=darkyellow ctermbg=NONE cterm=NONE
@@ -537,6 +542,7 @@ if &background == 'light'
     hi Type ctermfg=darkyellow ctermbg=NONE cterm=NONE
     hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
     hi VertSplit ctermfg=black ctermbg=black cterm=NONE
+    hi VertSplitNC ctermfg=black ctermbg=black cterm=NONE
     hi Visual ctermfg=darkblue ctermbg=grey cterm=reverse
     hi VisualNOS ctermfg=black ctermbg=darkblue cterm=NONE
     hi WarningMsg ctermfg=darkyellow ctermbg=NONE cterm=NONE
diff --git a/runtime/colors/zellner.vim b/runtime/colors/zellner.vim
index dc24f9b3a6..1ef6333055 100644
--- a/runtime/colors/zellner.vim
+++ b/runtime/colors/zellner.vim
@@ -4,9 +4,9 @@
 " Maintainer:   Original maintainer Ron Aaron 
 " URL:          https://github.com/vim/colorschemes
 " License:      Same as Vim
-" Last Change:  2025 Oct 08
+" Last Change:  2026 Apr 27
 
-" Generated by Colortemplate v3.0.0-beta10
+" Generated by Colortemplate v3.0.0-rc1
 
 set background=light
 
@@ -93,7 +93,8 @@ hi ToolbarButton guifg=NONE guibg=#a9a9a9 guisp=NONE gui=bold ctermfg=NONE cterm
 hi ToolbarLine guifg=NONE guibg=#d3d3d3 guisp=NONE gui=NONE ctermfg=NONE ctermbg=252 cterm=NONE term=reverse
 hi Type guifg=#0000ff guibg=NONE guisp=NONE gui=NONE ctermfg=21 ctermbg=NONE cterm=NONE term=NONE
 hi Underlined guifg=#6a5acd guibg=NONE guisp=NONE gui=underline ctermfg=62 ctermbg=NONE cterm=underline term=underline
-hi VertSplit guifg=#ffffff guibg=#000000 guisp=NONE gui=NONE ctermfg=231 ctermbg=16 cterm=NONE term=NONE
+hi VertSplit guifg=#ffff00 guibg=#a9a9a9 guisp=NONE gui=NONE ctermfg=226 ctermbg=248 cterm=NONE term=NONE
+hi VertSplitNC guifg=#ffffff guibg=#000000 guisp=NONE gui=NONE ctermfg=231 ctermbg=16 cterm=NONE term=NONE
 hi Visual guifg=#000000 guibg=#ffff00 guisp=NONE gui=NONE ctermfg=16 ctermbg=226 cterm=NONE term=reverse
 hi VisualNOS guifg=NONE guibg=#ff0000 guisp=NONE gui=NONE ctermfg=NONE ctermbg=196 cterm=NONE term=NONE
 hi WarningMsg guifg=#a020f0 guibg=#ffffff guisp=NONE gui=NONE ctermfg=129 ctermbg=231 cterm=NONE term=standout
@@ -166,7 +167,8 @@ if s:t_Co >= 16
   hi ToolbarLine ctermfg=NONE ctermbg=black cterm=NONE
   hi Type ctermfg=blue ctermbg=NONE cterm=NONE
   hi Underlined ctermfg=blue ctermbg=NONE cterm=underline
-  hi VertSplit ctermfg=white ctermbg=black cterm=NONE
+  hi VertSplit ctermfg=yellow ctermbg=darkgrey cterm=NONE
+  hi VertSplitNC ctermfg=white ctermbg=black cterm=NONE
   hi Visual ctermfg=black ctermbg=yellow cterm=NONE
   hi VisualNOS ctermfg=NONE ctermbg=red cterm=NONE
   hi WarningMsg ctermfg=darkmagenta ctermbg=white cterm=NONE
@@ -238,6 +240,7 @@ if s:t_Co >= 8
   hi Type ctermfg=darkblue ctermbg=NONE cterm=bold
   hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline
   hi VertSplit ctermfg=black ctermbg=gray cterm=reverse
+  hi VertSplitNC ctermfg=black ctermbg=gray cterm=reverse
   hi Visual ctermfg=NONE ctermbg=NONE cterm=reverse
   hi VisualNOS ctermfg=NONE ctermbg=NONE cterm=underline
   hi WarningMsg ctermfg=darkmagenta ctermbg=black cterm=NONE
diff --git a/runtime/compiler/gcc.vim b/runtime/compiler/gcc.vim
index 1d5900eb27..6fe751c50a 100644
--- a/runtime/compiler/gcc.vim
+++ b/runtime/compiler/gcc.vim
@@ -7,6 +7,7 @@
 "			added line suggested by Anton Lindqvist 2016 Mar 31
 "			2024 Apr 03 by The Vim Project (removed :CompilerSet definition)
 "			2025 Dec 17 by The Vim Project (correctly parse: 'make: *** [Makefile:2: all] Error 1')
+"			2026 May 28 by The Vim Project (Use %v to parse column number)
 
 if exists("current_compiler")
   finish
@@ -24,9 +25,9 @@ CompilerSet errorformat=
       \\"%f\"%*\\D%l:\ %m,
       \%-G%f:%l:\ %trror:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once,
       \%-G%f:%l:\ %trror:\ for\ each\ function\ it\ appears\ in.),
-      \%f:%l:%c:\ %trror:\ %m,
-      \%f:%l:%c:\ %tarning:\ %m,
-      \%f:%l:%c:\ %m,
+      \%f:%l:%v:\ %trror:\ %m,
+      \%f:%l:%v:\ %tarning:\ %m,
+      \%f:%l:%v:\ %m,
       \%f:%l:\ %trror:\ %m,
       \%f:%l:\ %tarning:\ %m,
       \%f:%l:\ %m,
diff --git a/runtime/compiler/zig.vim b/runtime/compiler/zig.vim
index 44014a3775..0993874f58 100644
--- a/runtime/compiler/zig.vim
+++ b/runtime/compiler/zig.vim
@@ -1,6 +1,9 @@
 " Vim compiler file
 " Compiler: Zig Compiler
-" Upstream: https://github.com/ziglang/zig.vim
+" Upstream: https://codeberg.org/ziglang/zig.vim
+" Last Change:
+" 2026 May 12 by the Vim project (set errormformat)
+" 2026 May 24 by the Vim project (do not escape vars for makeprg)
 
 if exists("current_compiler")
     finish
@@ -11,13 +14,29 @@ let s:save_cpo = &cpo
 set cpo&vim
 
 " a subcommand must be provided for the this compiler (test, build-exe, etc)
-if has('patch-7.4.191')
-    CompilerSet makeprg=zig\ \$*\ \%:S
-else
-    CompilerSet makeprg=zig\ \$*\ \"%\"
-endif
+CompilerSet makeprg=zig\ $*\ %:S
 
-" TODO: improve errorformat as needed.
+CompilerSet errorformat=
+            \%-G,
+            \%-G\ %#+-\ %.%#,
+            \%-Ginstall,
+            \%-Ginstall\ transitive\ failure,
+            \%-Grun,
+            \%-Grun\ transitive\ failure,
+            \%-Gtest,
+            \%-Gtest\ transitive\ failure,
+            \%-Gfailed\ command:\ %.%#,
+            \%-Gerror:\ %*\\d\ compilation\ errors,
+            \%-GBuild\ Summary:\ %.%#,
+            \%-Gerror:\ the\ following\ build\ command\ failed\ with\ exit\ code\ %*\\d:,
+            \%-G.zig-cache%.%#,
+            \%E%f:%l:%c:\ error:\ %m,
+            \%I%f:%l:%c:\ note:\ %m
+
+" zig has no warnings, but zig cc and zig c++ do
+CompilerSet errorformat+=
+            \%W%f:%l:%c:\ warning:\ %m,
+            \%-G%*\\d\ warnings\ generated.
 
 let &cpo = s:save_cpo
 unlet s:save_cpo
diff --git a/runtime/compiler/zig_build.vim b/runtime/compiler/zig_build.vim
index 5a61c9f423..27788836f0 100644
--- a/runtime/compiler/zig_build.vim
+++ b/runtime/compiler/zig_build.vim
@@ -1,7 +1,8 @@
 " Vim compiler file
 " Compiler: Zig Compiler (zig build)
-" Upstream: https://github.com/ziglang/zig.vim
-" Last Change: 2024 Apr 05 by The Vim Project (removed :CompilerSet definition)
+" Upstream: https://codeberg.org/ziglang/zig.vim
+" Last Change: 2024 Apr 05 by the Vim Project (removed :CompilerSet definition)
+" 2026 May 12 by the Vim Project (removed comment)
 
 if exists('current_compiler')
   finish
@@ -13,13 +14,11 @@ let s:save_cpo = &cpo
 set cpo&vim
 
 if exists('g:zig_build_makeprg_params')
-	execute 'CompilerSet makeprg=zig\ build\ '.escape(g:zig_build_makeprg_params, ' \|"').'\ $*'
+  execute 'CompilerSet makeprg=zig\ build\ '.escape(g:zig_build_makeprg_params, ' \|"').'\ $*'
 else
-	CompilerSet makeprg=zig\ build\ $*
+  CompilerSet makeprg=zig\ build\ $*
 endif
 
-" TODO: anything to add to errorformat for zig build specifically?
-
 let &cpo = s:save_cpo
 unlet s:save_cpo
-" vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab
+" vim: tabstop=8 shiftwidth=2 softtabstop=2 expandtab
diff --git a/runtime/compiler/zig_build_exe.vim b/runtime/compiler/zig_build_exe.vim
index 440eff7885..f49304feb1 100644
--- a/runtime/compiler/zig_build_exe.vim
+++ b/runtime/compiler/zig_build_exe.vim
@@ -1,7 +1,9 @@
 " Vim compiler file
 " Compiler: Zig Compiler (zig build-exe)
-" Upstream: https://github.com/ziglang/zig.vim
-" Last Change: 2025 Nov 16 by The Vim Project (set errorformat)
+" Upstream: https://codeberg.org/ziglang/zig.vim
+" Last Change: 2025 Nov 16 by the Vim Project (set errorformat)
+" 2026 May 12 by the Vim project (remove errorformat)
+" 2026 May 24 by the Vim project (do not escape vars for makeprg)
 
 if exists('current_compiler')
   finish
@@ -12,10 +14,8 @@ let current_compiler = 'zig_build_exe'
 let s:save_cpo = &cpo
 set cpo&vim
 
-CompilerSet makeprg=zig\ build-exe\ \%:S\ \$*
-" CompilerSet errorformat=%f:%l:%c: %t%*[^:]: %m, %f:%l:%c: %m, %f:%l: %m
-CompilerSet errorformat&
+CompilerSet makeprg=zig\ build-exe\ %:S\ $*
 
 let &cpo = s:save_cpo
 unlet s:save_cpo
-" vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab
+" vim: tabstop=8 shiftwidth=2 softtabstop=2 expandtab
diff --git a/runtime/compiler/zig_cc.vim b/runtime/compiler/zig_cc.vim
new file mode 100644
index 0000000000..d86bb48efc
--- /dev/null
+++ b/runtime/compiler/zig_cc.vim
@@ -0,0 +1,19 @@
+" Vim compiler file
+" Compiler: Zig Compiler (zig cc)
+" Last Change: 2026 May 12
+" 2026 May 24 by the Vim project (do not escape vars for makeprg)
+
+if exists('current_compiler')
+  finish
+endif
+runtime compiler/zig.vim
+let current_compiler = 'zig_cc'
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+CompilerSet makeprg=zig\ cc\ %:S\ $*
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+" vim: tabstop=8 shiftwidth=2 softtabstop=2 expandtab
diff --git a/runtime/compiler/zig_test.vim b/runtime/compiler/zig_test.vim
index afe57ad4d3..f1992cbffd 100644
--- a/runtime/compiler/zig_test.vim
+++ b/runtime/compiler/zig_test.vim
@@ -1,7 +1,9 @@
 " Vim compiler file
 " Compiler: Zig Compiler (zig test)
-" Upstream: https://github.com/ziglang/zig.vim
-" Last Change: 2025 Nov 16 by The Vim Project (set errorformat)
+" Upstream: https://codeberg.org/ziglang/zig.vim
+" Last Change: 2025 Nov 16 by the Vim Project (set errorformat)
+" 2026 May 12 by the Vim Project (remove error format)
+" 2026 May 24 by the Vim project (do not escape vars for makeprg)
 
 if exists('current_compiler')
   finish
@@ -12,10 +14,8 @@ let current_compiler = 'zig_test'
 let s:save_cpo = &cpo
 set cpo&vim
 
-CompilerSet makeprg=zig\ test\ \%:S\ \$*
-" CompilerSet errorformat=%f:%l:%c: %t%*[^:]: %m, %f:%l:%c: %m, %f:%l: %m
-CompilerSet errorformat&
+CompilerSet makeprg=zig\ test\ %:S\ $*
 
 let &cpo = s:save_cpo
 unlet s:save_cpo
-" vim: tabstop=8 shiftwidth=4 softtabstop=4 expandtab
+" vim: tabstop=8 shiftwidth=2 softtabstop=2 expandtab
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 1286338059..5f59b03b61 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -1,4 +1,4 @@
-*autocmd.txt*	For Vim version 9.2.  Last change: 2026 Feb 25
+*autocmd.txt*	For Vim version 9.2.  Last change: 2026 May 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -423,6 +423,8 @@ Name			triggered by ~
 |TextChangedP|		after a change was made to the text in Insert mode
 			when popup menu visible
 |TextChangedT|		after a change was made to the text in Terminal mode
+|TextPutPost|		after text has been put
+|TextPutPre|		before text is put
 |TextYankPost|		after text has been yanked or deleted
 
 |SafeState|		nothing pending, going to wait for the user to type a
@@ -1367,6 +1369,46 @@ TextChangedP			After a change was made to the text in the
 TextChangedT			After a change was made to the text in the
 				current buffer in Terminal mode.
 				Otherwise the same as TextChanged.
+							*TextPutPost*
+TextPutPost			After text has been put in the current buffer.
+				The following values in |v:event| are mostly
+				the same as |TextYankPost|:
+				   operator	The operation performed,
+						either 'p' or 'P'.
+				   regcontents	Text that was put. For
+						|quote_=|, this is the result
+						of the expression.
+				   regname	Name of the register or empty
+						string for the unnamed
+						register.
+				   regtype	Type of the register, see
+						|getregtype()|.
+				   visual	True if the operation is
+						performed in |Visual| mode.
+				Not triggered when |quote_| is used nor when
+				called recursively.
+				It is not allowed to change the buffer text,
+				see |textlock|.
+				Note that for the |quote_.| register, since
+				the last inserted text is buffered into the
+				input buffer (buffer isn't modified directly),
+				this autocommand is called directly after
+				|TextPutPre|.
+				{only when compiled with the +eval feature}
+							*TextPutPre*
+TextPutPre			Before text has been put in the current buffer.
+				Same values as |TextPutPost| in |v:event|.  It
+				is valid to call |setreg()| in this
+				autocommand, allowing you to process and
+				modify the text in "regcontents" before it is
+				put.  However this does not apply to
+				|quote_#|, |quote_=|, |quote_%|, |quote_:|,
+				|quote_/| or |quote_.|.
+				Not triggered when |quote_| is used nor when
+				called recursively.
+				It is not allowed to change the buffer text,
+				see |textlock|.
+				{only when compiled with the +eval feature}
 							*TextYankPost*
 TextYankPost			After text has been yanked or deleted in the
 				current buffer.  The following values of
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index e0c3f3bcab..9662e8928a 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt*	For Vim version 9.2.  Last change: 2026 Apr 06
+*builtin.txt*	For Vim version 9.2.  Last change: 2026 May 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -107,7 +107,8 @@ ch_getbufnr({handle}, {what})	Number	get buffer number for {handle}/{what}
 ch_getjob({channel})		Job	get the Job of {channel}
 ch_info({handle})		Dict	info about channel {handle}
 ch_listen({address} [, {options}])
-				Channel	listen on {address}
+				Channel	listen on {address} - port on loopback
+					or UNIX domain socket
 ch_log({msg} [, {handle}])	none	write {msg} in the channel log file
 ch_logfile({fname} [, {mode}])	none	start logging channel activity
 ch_open({address} [, {options}])
@@ -706,6 +707,8 @@ tabpagebuflist([{arg}])		List	list of buffer numbers in tab page
 tabpagenr([{arg}])		Number	number of current or last tab page
 tabpagewinnr({tabarg} [, {arg}])
 				Number	number of current window in tab page
+tabpanel_getinfo()		Dict	get current state of the tabpanel
+tabpanel_scroll({n} [, {opts}])	Bool	scroll the tabpanel
 tagfiles()			List	tags files used
 taglist({expr} [, {filename}])	List	list of tags matching {expr}
 tan({expr})			Float	tangent of {expr}
@@ -3671,14 +3674,22 @@ fullcommand({name} [, {vim9}])				*fullcommand()*
 		ambiguous (for user-defined commands) or cannot be shortened
 		this way. |vim9-no-shorten|
 
-		Without the {vim9} argument uses the current script version.
-		If {vim9} is present and FALSE then legacy script rules are
-		used.  When {vim9} is present and TRUE then Vim9 rules are
-		used, e.g. "en" is not a short form of "endif".
-
-		For example `fullcommand('s')`, `fullcommand('sub')`,
-		`fullcommand(':%substitute')` all return "substitute".
+		Without the {vim9} argument, the current script version is
+		used.  When {vim9} is present and FALSE, legacy script rules
+		are used.  When {vim9} is present and TRUE, Vim9 rules are
+		used (e.g., "en" is not a short form of "endif").
 
+		Note: Command validation is not performed.  Results depend on
+		Vim's internal command-specific identification rules.
+		Examples:
+>vim
+		  echo [fullcommand('s')]		|" ['substitute']
+		  echo [fullcommand('sub')]		|" ['substitute']
+		  echo [fullcommand(': mark word')]	|" ['mark']
+		  echo [fullcommand(': markword')]	|" ['']
+		  echo [fullcommand('en')]		|" ['endif']
+		  echo [fullcommand('en', v:true)]	|" ['']
+<
 		Can also be used as a |method|: >
 			GetName()->fullcommand()
 <
@@ -6260,7 +6271,7 @@ insert({object}, {item} [, {idx}])			*insert()*
 		Return type: |Number|
 
 
-instanceof({object}, {class})			*instanceof()* *E614* *E616* *E693*
+instanceof({object}, {class})			*instanceof()* *E616* *E693*
 		The result is a Number, which is |TRUE| when the {object}
 		argument is a direct or indirect instance of a |Class|,
 		|Interface|, or class |:type| alias specified by {class}.
@@ -6866,6 +6877,8 @@ listener_add({callback} [, {buf} [, {unbuffered}]])	*listener_add()*
 		second argument: >
 			GetBuffer()->listener_add(callback)
 <
+		This function is not available in the |sandbox|.
+
 		Return type: |Number|
 
 
@@ -6880,6 +6893,8 @@ listener_flush([{buf}])					*listener_flush()*
 		Can also be used as a |method|: >
 			GetBuffer()->listener_flush()
 <
+		This function is not available in the |sandbox|.
+
 		Return type: void
 
 
@@ -6891,6 +6906,8 @@ listener_remove({id})					*listener_remove()*
 		Can also be used as a |method|: >
 			GetListenerId()->listener_remove()
 <
+		This function is not available in the |sandbox|.
+
 		Return type: |Number|
 
 
@@ -8870,6 +8887,8 @@ redraw_listener_add({opts})				*redraw_listener_add()*
 		Can also be used as a |method|: >
 			GetOpts()->redraw_listener_add()
 <
+		This function is not available in the |sandbox|.
+
 		Return type: |Number|
 
 
@@ -11342,7 +11361,12 @@ strptime({format}, {timestring})			*strptime()*
 		can try different {format} values until you get a non-zero
 		result.
 
+		Note: On MS-Windows, where the C runtime does not provide
+		strptime(), Vim uses a built-in fallback that always uses
+		English locale names regardless of the active locale.
+
 		See also |strftime()|.
+
 		Examples: >
 		  :echo strptime("%Y %b %d %X", "1997 Apr 27 11:49:23")
 <		  862156163 >
@@ -11896,6 +11920,38 @@ tabpagewinnr({tabarg} [, {arg}])			*tabpagewinnr()*
 		Return type: |Number|
 
 
+tabpanel_getinfo()					*tabpanel_getinfo()*
+		Return a |Dictionary| describing the current state of the
+		tabpanel (see |tabpanel|).  The dictionary has these keys:
+			align		"left" or "right"
+			columns		width in screen columns
+			scrollbar	|TRUE| if a scrollbar is shown
+			offset		current scroll offset in rows
+			total		total number of rows rendered
+			max_offset	largest valid value for "offset"
+
+		The "total" and "max_offset" values are only accurate after
+		the tabpanel has been drawn at least once.
+
+		Return type: dict
+
+
+tabpanel_scroll({n} [, {opts}])				*tabpanel_scroll()*
+		Scroll the tabpanel by {n} rows.  Positive values scroll down
+		(later tab pages become visible), negative values scroll up.
+		The new offset is clamped to the valid range.
+
+		When {opts} is a |Dictionary| and its "absolute" entry is
+		|TRUE|, {n} is used as the new absolute scroll offset instead
+		of a delta.
+
+		Returns |TRUE| if the scroll offset changed, |FALSE| otherwise
+		(for example when the tabpanel is not shown, or the offset is
+		already at the requested value).
+
+		Return type: |vim9-boolean|
+
+
 tagfiles()						*tagfiles()*
 		Returns a |List| with the file names used to search for tags
 		for the current buffer.  This is the 'tags' option expanded.
@@ -12015,6 +12071,7 @@ terminalprops()						*terminalprops()*
 		   underline_rgb	whether |t_8u| works **
 		   mouse		mouse type supported
 		   kitty		whether Kitty terminal was detected
+		   decrqm		whether sending DECRQM sequences work
 
 		** value 'u' for unknown, 'y' for yes, 'n' for no
 
@@ -12034,6 +12091,9 @@ terminalprops()						*terminalprops()*
 
 		For "mouse" the value 'u' is unknown
 
+		If "decrqm" is 'y', then Vim will query support for the
+		'termsync' and 'termresize' ("inband") options.
+
 		Also see:
 		- 'ambiwidth' - detected by using |t_u7|.
 		- |v:termstyleresp| and |v:termblinkresp| for the response to
@@ -13326,6 +13386,7 @@ spell			Compiled with spell checking support |spell|.
 startuptime		Compiled with |--startuptime| support.
 statusline		Compiled with support for 'statusline', 'rulerformat'
 			and special formats of 'titlestring' and 'iconstring'.
+statusline_click	Click handlers in 'statusline' |stl-%[FuncName]|
 sun			SunOS version of Vim.
 sun_workshop		Support for Sun |workshop| has been removed.
 syntax			Compiled with syntax highlighting support |syntax|.
@@ -13378,8 +13439,6 @@ vtp			Compiled for vcon support |+vtp| (check vcon to find
 			out if it works in the current console).
 wayland			Compiled with Wayland protocol support.
 wayland_clipboard	Compiled with support for Wayland clipboard.
-wayland_focus_steal	Compiled with support for Wayland clipboard focus
-			stealing.
 wildignore		Compiled with 'wildignore' option.
 wildmenu		Compiled with 'wildmenu' option.
 win16			old version for MS-Windows 3.1 (always false)
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index b5786e8d40..ead590a5da 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1,4 +1,4 @@
-*change.txt*	For Vim version 9.2.  Last change: 2026 Mar 31
+*change.txt*	For Vim version 9.2.  Last change: 2026 May 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -75,18 +75,21 @@ For inserting text see |insert.txt|.
 					*:d* *:de* *:del* *:delete* *:dl* *:dp*
 :[range]d[elete] [x]	Delete [range] lines (default: current line) [into
 			register x].
-			Note these weird abbreviations:
-			   :dl		delete and list
-			   :dell	idem
-			   :delel	idem
-			   :deletl	idem
-			   :deletel	idem
-			   :dp		delete and print
-			   :dep		idem
-			   :delp	idem
-			   :delep	idem
-			   :deletp	idem
-			   :deletep	idem
+			Note these weird abbreviations applicable only to
+			legacy Vim script:
+			  :dl		delete and list
+			  :dell		idem
+			  :delel	idem
+			  :deletl	idem
+			  :deletel	idem
+			  :dp		delete and print
+			  :dep		idem
+			  :delp		idem
+			  :delep	idem
+			  :deletp	idem
+			  :deletep	idem
+			Warning: These give |E492| in |Vim9| script and `:dl`
+			executes as `:dlist`.
 
 :[range]d[elete] [x] {count}
 			Delete {count} lines, starting with [range]
@@ -798,7 +801,8 @@ out then.  Example: >
 	:%s/TESTING
 This deletes "TESTING" from all lines, but only one per line.
 								*E1270*
-For compatibility with Vi these two exceptions are allowed in legacy script:
+For compatibility with Vi these two exceptions are allowed in legacy Vim
+script:
 "\/{string}/" and "\?{string}?" do the same as "//{string}/r".
 "\&{string}&" does the same as "//{string}/".
 				*pattern-delimiter* *E146* *E1241* *E1242*
diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt
index 55b95c632f..839dcc296e 100644
--- a/runtime/doc/channel.txt
+++ b/runtime/doc/channel.txt
@@ -1,4 +1,4 @@
-*channel.txt*	For Vim version 9.2.  Last change: 2026 Apr 06
+*channel.txt*	For Vim version 9.2.  Last change: 2026 Apr 29
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -132,7 +132,7 @@ Start Vim and create a listening channel: >
 	endfunc
 
 	" Start listening on port 8765
-	let server = ch_listen('localhost:8765', {"callback": "OnAccept"})
+	let server = ch_listen('8765', {"callback": "OnAccept"})
 
 From another Vim instance (or any program) you can connect to it: >
 	let channel = ch_open('localhost:8765')
@@ -170,6 +170,7 @@ unreachable on the network.
 	"js"   - Use JS (JavaScript) encoding, more efficient than JSON.
 	"nl"   - Use messages that end in a NL character
 	"raw"  - Use raw messages
+	"blob" - Use raw messages and pass callback data as a |Blob|
 	"lsp"  - Use language server protocol encoding
 	"dap"  - Use debug adapter protocol encoding
 						*channel-callback* *E921*
@@ -189,6 +190,8 @@ unreachable on the network.
 		excluding the NL.
 		When "mode" is "raw" the "msg" argument is the whole message
 		as a string.
+		When "mode" is "blob" the "msg" argument is the whole message
+		as a |Blob|.
 
 		For all callbacks: Use |function()| to bind it to arguments
 		and/or a Dictionary.  Or use the form "dict.function" to bind
@@ -637,8 +640,7 @@ ch_info({handle})						*ch_info()*
 		   "status"	  "open", "buffered" or "closed", like
 				  ch_status()
 		When opened with ch_open():
-		   "hostname"	  the hostname of the address
-		   "port"	  the port of the address
+		   "port"	  the port on loopback
 		   "path"	  the path of the Unix-domain socket
 		   "sock_status"  "open" or "closed"
 		   "sock_mode"	  "NL", "RAW", "JSON" or "JS"
@@ -668,22 +670,23 @@ ch_info({handle})						*ch_info()*
 		Return type: dict
 
 ch_listen({address} [, {options}])		*E1573* *E1574* *ch_listen()*
-		Listen on {address} for incoming channel connections.
-		This creates a server-side channel, unlike |ch_open()|
-		which connects to an existing server.
+		Listen on {address} - port on loopback or UNIX domain socket
+		for incoming channel connections.  This creates a server-side
+		channel, unlike |ch_open()| which connects to an existing
+		server.
 		Returns a Channel.  Use |ch_status()| to check for failure.
 
 		{address} is a String, see |channel-address| for the possible
-		accepted forms, however binding to all interfaces is not
-		allowed for security reasons.
+		accepted forms, however in case of TCP sockets it allows to
+		set only a port and binds to loopback address for security
+		reasons.
 		Note: IPv6 is not yet supported.
 
 		If {options} is given it must be a |Dictionary|.
 		See |channel-open-options|.
-		The "callback" in {options} is invoked when a new
-		connection is accepted.  It receives two arguments: the
-		new Channel and the client address as a String (e.g.
-		"127.0.0.1:12345").
+		The "callback" in {options} is invoked when a new connection
+		is accepted.  It receives two arguments: the new Channel and
+		the client address as a String (e.g. "127.0.0.1:12345").
 
 		Use |ch_open()| to connect to an existing server instead.
 
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index 4a0729d0ed..6427507d7e 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -1,4 +1,4 @@
-*cmdline.txt*	For Vim version 9.2.  Last change: 2026 Mar 17
+*cmdline.txt*	For Vim version 9.2.  Last change: 2026 May 20
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -56,7 +56,7 @@ history tables:
 These are completely separate.  Each history can only be accessed when
 entering the same type of line.
 Use the 'history' option to set the number of lines that are remembered
-(default: 50).
+(default: 200).
 Notes:
 - When you enter a command-line that is exactly the same as an older one, the
   old one is removed (to avoid repeated commands moving older commands out of
@@ -466,14 +466,15 @@ CTRL-L		A match is done on the pattern in front of the cursor.  If
 	                                            *c_CTRL-G* */_CTRL-G*
 CTRL-G		When 'incsearch' is set, entering a search pattern for "/" or
 		"?" and the current match is displayed then CTRL-G will move
-		to the next match (does not take |search-offset| into account)
+		to the next match.  The |search-offset| is applied when 
+		is pressed, but does not affect the match highlighting.
 		Use CTRL-T to move to the previous match.  Hint: on a regular
 		keyboard G is below T.
 	                                            *c_CTRL-T* */_CTRL-T*
 CTRL-T		When 'incsearch' is set, entering a search pattern for "/" or
 		"?" and the current match is displayed then CTRL-T will move
-		to the previous match (does not take |search-offset| into
-		account).
+		to the previous match.  The |search-offset| is applied when
+		 is pressed, but does not affect the match highlighting.
 		Use CTRL-G to move to the next match.  Hint: on a regular
 		keyboard T is above G.
 
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 9869988ab4..57ca36a764 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*eval.txt*	For Vim version 9.2.  Last change: 2026 May 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -170,8 +170,8 @@ Note that " " and "0" are also non-empty strings, thus considered to be TRUE.
 A List, Dictionary or Float is not a Number or String, thus evaluate to FALSE.
 
 		*E611* *E745* *E728* *E703* *E729* *E730* *E731* *E908* *E910*
-		*E913* *E974* *E975* *E976* *E1319* *E1320* *E1321* *E1322*
-		*E1323* *E1324* *E1520* *E1522*
+		*E913* *E974* *E975* *E976* *E1320* *E1322* *E1324* *E1520*
+		*E1522*
 |List|, |Tuple|, |Dictionary|, |Funcref|, |Job|, |Channel|, |Blob|, |Class|
 and |object| types are not automatically converted.
 
@@ -3399,7 +3399,7 @@ text...
 			  s:	script-local variables
 			  l:	local function variables
 			  v:	Vim variables.
-			This does not work in Vim9 script. |vim9-declaration|
+			This does not work in Vim9 script.  |vim9-declaration|
 
 :let			List the values of all variables.  The type of the
 			variable is indicated before the value:
@@ -3675,7 +3675,7 @@ text...
 			all nested `:try`s inside the loop.  The outermost
 			`:endtry` then jumps back to the start of the loop.
 
-			In |Vim9| script `:cont` is the shortest form, to
+			In |Vim9| script `:continue` cannot be shortened, to
 			improve script readability.
 						*:break* *:brea* *E587*
 :brea[k]		When used inside a `:while` or `:for` loop, skips to
@@ -5361,6 +5361,9 @@ a |lambda| expression.
 With the exception of the "available" callback if a callback is not provided,
 Vim will not invoke anything, and this is not an error.
 
+If the "paste" or "copy" callbacks are triggered recursively, then they will
+not be called.
+
 						*clipboard-providers-textlock*
 In both the "paste" and "copy" callbacks, it is not allowed to change the
 buffer text, see |textlock|.
@@ -5382,6 +5385,9 @@ order:
 	   is an empty string, then the type is automatically chosen.
 	2. A |list| of strings to return to Vim, each representing a line.
 
+If an invalid value is returned, then this is not an error.  Instead the
+register will be left unchanged (not cleared).
+
 						*clipboard-providers-copy*
 The "copy" callback returns nothing and takes the following arguments in the
 following order:
diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt
index 3aa41db21a..a9a0e92203 100644
--- a/runtime/doc/filetype.txt
+++ b/runtime/doc/filetype.txt
@@ -1,4 +1,4 @@
-*filetype.txt*	For Vim version 9.2.  Last change: 2026 Apr 07
+*filetype.txt*	For Vim version 9.2.  Last change: 2026 May 29
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -139,6 +139,7 @@ variables can be used to overrule the filetype used for certain extensions:
 
 	file name	variable ~
 	*.app		g:filetype_app
+	*.as		g:filetype_as
 	*.asa		g:filetype_asa		|ft-aspperl-syntax|
 						|ft-aspvbs-syntax|
 	*.asm		g:asmsyntax		|ft-asm-syntax|
@@ -164,6 +165,7 @@ variables can be used to overrule the filetype used for certain extensions:
 	*.int		g:filetype_int
 	*.lsl		g:filetype_lsl
 	*.m		g:filetype_m		|ft-mathematica-syntax|
+	*.mm		g:filetype_mm
 	*.mac		g:filetype_mac
 	*[mM]makefile,*.mk,*.mak,[mM]akefile*
 			g:make_flavor		|ft-make-syntax|
@@ -652,7 +654,6 @@ One command, :DiffGitCached, is provided to show a diff of the current commit
 in the preview window.  It is equivalent to calling "git diff --cached" plus
 any arguments given to the command.
 
-
 The length of the first line of the commit message used for
 syntax highlighting can be configured via `g:gitcommit_summary_length`.
 The default is 50.  Example: >
@@ -975,7 +976,20 @@ By default the following options are set, in accordance with PEP8: >
 To disable this behavior, set the following variable in your vimrc: >
 
 	let g:python_recommended_style = 0
+<
+Python omni-completion |compl-omni| is provided by python3complete.vim (or
+pythoncomplete.vim) for Vim builds with the |+python|/|+python3| interpreter.
+By default it does not inspect the import / from statements found in the
+buffer. This means completion of names defined in the buffer itself (classes,
+functions, variables) works, but completion of members of imported modules is
+not offered.
 
+To enable completion of imported module members, set: >
+	let g:pythoncomplete_allow_import = 1
+<
+WARNING: enabling this causes omni-completion to execute the import statements
+found in the buffer through Python's import machinery, which runs the imported
+modules' top-level code. Only enable this for code you trust.
 
 QF QUICKFIX					    *qf.vim* *ft-qf-plugin*
 
diff --git a/runtime/doc/ft_mp.txt b/runtime/doc/ft_mp.txt
index 7106edf98a..f4ea042576 100644
--- a/runtime/doc/ft_mp.txt
+++ b/runtime/doc/ft_mp.txt
@@ -1,4 +1,4 @@
-*ft_mp.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*ft_mp.txt*	For Vim version 9.2.  Last change: 2026 May 04
 
 This is the documentation for the METAFONT and MetaPost filetype plugins.
 Unless otherwise specified, the commands, settings and mappings defined below
@@ -25,7 +25,7 @@ MetaPost documents, including syntax coloring, indentation, and completion.
 Defining indentation rules for METAFONT and MetaPost code is tricky and
 somewhat subjective, because the syntax is quite liberal. The plugin uses some
 heuristics that work well most of the time, but in particular cases you may
-want to to override the automatic rules, so that the manually defined
+want to override the automatic rules, so that the manually defined
 indentation is preserved by commands like `gg=G`.
 
 This can be achieved by appending `%>`, `%<`, `%=` or `%!` to a line to
diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt
index dde63e9cac..9204fb8ea6 100644
--- a/runtime/doc/gui.txt
+++ b/runtime/doc/gui.txt
@@ -1,4 +1,4 @@
-*gui.txt*	For Vim version 9.2.  Last change: 2026 Apr 07
+*gui.txt*	For Vim version 9.2.  Last change: 2026 Jun 02
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1296,6 +1296,32 @@ A recommended Japanese font is MS Mincho.  You can find info here:
 https://learn.microsoft.com/en-us/typography/font-list/ms-mincho
 It should be distributed with Windows.
 
+
+Full Screen						*gui-fullscreen*
+
+Fullscreen mode is currently only supported in the Windows and GTK GUI
+versions of Vim.
+
+To enable fullscreen mode in the GUI version of Vim, add the "s" flag to the
+'guioptions' setting.
+
+For convenience, you can define a command or mapping to toggle fullscreen
+mode:
+>
+	command ToggleFullscreen {
+	  if &guioptions =~# 's'
+	    set guioptions-=s
+	  else
+	    set guioptions+=s
+	  endif
+	}
+
+	map   &go =~# 's' ? ":se go-=s" : ":se go+=s"
+
+The fullscreen mode will occupy the entire screen area while hiding window
+decorations such as the title bar and borders.
+
+
 ==============================================================================
 8. Shell Commands					*gui-shell*
 
diff --git a/runtime/doc/gui_w32.txt b/runtime/doc/gui_w32.txt
index 2e2e2601d0..26c516d895 100644
--- a/runtime/doc/gui_w32.txt
+++ b/runtime/doc/gui_w32.txt
@@ -1,4 +1,4 @@
-*gui_w32.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*gui_w32.txt*	For Vim version 9.2.  Last change: 2026 May 25
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -505,25 +505,4 @@ To use the system's default title bar colors, set highlighting groups to
 	hi TitleBarNC guibg=NONE guifg=NONE
 <
 
-Full Screen						*gui-w32-fullscreen*
-
-To enable fullscreen mode in the Windows GUI version of Vim, add the 's' flag
-to the 'guioptions' setting.
-
-For convenience, you can define a command or mapping to toggle fullscreen
-mode:
->
-	command ToggleFullscreen {
-	  if &guioptions =~# 's'
-	    set guioptions-=s
-	  else
-	    set guioptions+=s
-	  endif
-	}
-
-	map   &go =~# 's' ? ":se go-=s" : ":se go+=s"
-
-The fullscreen mode will occupy the entire screen area while hiding window
-decorations such as the title bar and borders.
-
  vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt
index 68a6c64766..13f2d89a2d 100644
--- a/runtime/doc/insert.txt
+++ b/runtime/doc/insert.txt
@@ -1,4 +1,4 @@
-*insert.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*insert.txt*	For Vim version 9.2.  Last change: 2026 Jun 02
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1813,14 +1813,15 @@ for the syntax items.  For example, in the Scheme language completion should
 include the "-", call-with-output-file.  Depending on your filetype, this may
 not provide the words you are expecting.  Setting the
 g:omni_syntax_use_iskeyword option to 0 will force the syntax plugin to break
-on word characters.   This can be controlled adding the following to your
+on word characters.  This can be controlled adding the following to your
 vimrc: >
     let g:omni_syntax_use_iskeyword = 0
 
-For plugin developers, the plugin exposes a public function OmniSyntaxList.
-This function can be used to request a List of syntax items.  When editing a
-SQL file (:e syntax.sql) you can use the ":syntax list" command to see the
-various groups and syntax items.  For example: >
+For plugin developers, the plugin exposes a public function
+syntaxcomplete#OmniSyntaxList.  This function can be used to request a List of
+syntax items.  When editing a SQL file (:e syntax.sql) you can use the
+":syntax list" command to see the various groups and syntax items.  For
+example: >
     syntax list
 
 Yields data similar to this:
@@ -1834,22 +1835,22 @@ Yields data similar to this:
                        image float integer timestamp real decimal ~
 
 There are two syntax groups listed here: sqlOperator and sqlType.  To retrieve
-a List of syntax items you can call OmniSyntaxList a number of different
-ways.  To retrieve all syntax items regardless of syntax group:  >
-    echo OmniSyntaxList( [] )
+a List of syntax items you can call syntaxcomplete#OmniSyntaxList a number of
+different ways.  To retrieve all syntax items regardless of syntax group:  >
+    echo syntaxcomplete#OmniSyntaxList( [] )
 
 To retrieve only the syntax items for the sqlOperator syntax group: >
-    echo OmniSyntaxList( ['sqlOperator'] )
+    echo syntaxcomplete#OmniSyntaxList( ['sqlOperator'] )
 
 To retrieve all syntax items for both the sqlOperator and sqlType groups: >
-    echo OmniSyntaxList( ['sqlOperator', 'sqlType'] )
+    echo syntaxcomplete#OmniSyntaxList( ['sqlOperator', 'sqlType'] )
 
 A regular expression can also be used: >
-    echo OmniSyntaxList( ['sql\w\+'] )
+    echo syntaxcomplete#OmniSyntaxList( ['sql\w\+'] )
 
 From within a plugin, you would typically assign the output to a List: >
     let myKeywords = []
-    let myKeywords = OmniSyntaxList( ['sqlKeyword'] )
+    let myKeywords = syntaxcomplete#OmniSyntaxList( ['sqlKeyword'] )
 
 
 SQL							*ft-sql-omni*
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 118e2d44e9..38de46c657 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1,4 +1,4 @@
-*map.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*map.txt*	For Vim version 9.2.  Last change: 2026 May 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -208,8 +208,7 @@ be effective in the current buffer only.  Example: >
 Then you can map ",w" to something else in another buffer: >
 	:map   ,w  /[#&!]
 The local buffer mappings are used before the global ones.  See  below
-to make a short local mapping not taking effect when a longer global one
-exists.
+to make a short local mapping take effect when a longer global one exists.
 The "" argument can also be used to clear mappings: >
 	:unmap  ,w
 	:mapclear 
@@ -1593,7 +1592,10 @@ reported if any are supplied).  However, it is possible to specify that the
 command can take arguments, using the -nargs attribute.  Valid cases are:
 
 	-nargs=0    No arguments are allowed (the default)
-	-nargs=1    Exactly one argument is required, it includes spaces
+	-nargs=1    Exactly one argument is required, it includes spaces;
+		    completion treats white spaces as argument separation
+	-nargs=_    Exactly one argument is required, it includes spaces;
+		    completion treats white spaces as part of the argument
 	-nargs=*    Any number of arguments are allowed (0, 1, or many),
 		    separated by white space
 	-nargs=?    0 or 1 arguments are allowed
@@ -1601,7 +1603,23 @@ command can take arguments, using the -nargs attribute.  Valid cases are:
 
 Arguments are considered to be separated by (unescaped) spaces or tabs in this
 context, except when there is one argument, then the white space is part of
-the argument.
+the argument. The difference between the "-nargs=1" and "-nargs=_": >
+
+	func MyComplete(ArgLead, CmdLine, CursorPos)
+	  return ["one value", "two values", "three values"]
+		\->matchfuzzy(a:ArgLead)
+	endfunc
+	:command -nargs=1 -complete=customlist,MyComplete MyCmd1 echo 
+	:command -nargs=_ -complete=customlist,MyComplete MyCmd2 echo 
+
+Completing ":MyCmd1 two va" will complete with: >
+
+	:MyCmd1 two one value
+
+Completing ":MyCmd2 two va" will complete with: >
+
+	:MyCmd2 two values
+
 
 Note that arguments are used as text, not as expressions.  Specifically,
 "s:var" will use the script-local variable in the script where the command was
@@ -1693,7 +1711,21 @@ For the "custom" argument, the function should return the completion
 candidates one per line in a newline separated string.
 							*E1303*
 For the "customlist" argument, the function should return the completion
-candidates as a Vim List.  Non-string items in the list are ignored.
+candidates as a Vim List.  Each item may be either a string or a |Dictionary|.
+A Dictionary item may have the following keys:
+	word	(required) the text inserted into the command line when the
+		item is selected
+	abbr	alternative text shown in the popup menu in place of "word",
+		when 'wildoptions' contains "pum"; useful when the inserted
+		text and the displayed text should differ
+	kind	short kind text (one or two characters), shown in the popup
+		menu when 'wildoptions' contains "pum"
+	menu	extra text shown after the match in the popup menu
+	info	long description shown in the info popup; the |+popupwin|
+		feature is required to display it
+Items that are neither a string nor a Dictionary, and Dictionary items without
+a "word" key, are ignored.  When 'wildoptions' does not contain "pum", only
+"word" is shown.
 
 The function arguments are:
 	ArgLead		the leading portion of the argument currently being
diff --git a/runtime/doc/netbeans.txt b/runtime/doc/netbeans.txt
index d20ae51907..4803e97497 100644
--- a/runtime/doc/netbeans.txt
+++ b/runtime/doc/netbeans.txt
@@ -1,4 +1,4 @@
-*netbeans.txt*	For Vim version 9.2.  Last change: 2026 Mar 07
+*netbeans.txt*	For Vim version 9.2.  Last change: 2026 Apr 09
 
 
 		  VIM REFERENCE MANUAL	  by Gordon Prieur et al.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index b6ec7e3845..cca9ab13b4 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 9.2.  Last change: 2026 Apr 07
+*options.txt*	For Vim version 9.2.  Last change: 2026 May 25
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -324,12 +324,12 @@ that was last closed are used again.  If this buffer has been edited in this
 window, the values from back then are used.  Otherwise the values from the
 last closed window where the buffer was edited last are used.
 
-It's possible to set a local window option specifically for a type of buffer.
-When you edit another buffer in the same window, you don't want to keep
-using these local window options.  Therefore Vim keeps a global value of the
-local window options, which is used when editing another buffer.  Each window
-has its own copy of these values.  Thus these are local to the window, but
-global to all buffers in the window.  With this you can do: >
+":setlocal" can be used to set a local window option specifically for a type
+of buffer.  When you edit another buffer in the same window, you don't want to
+keep using these local window options.  Meanwhile ":set" also sets a global
+value of a local window option, which is used when editing another buffer.
+Each window has its own copy of these global values, making them local to the
+window, but global to all buffers in the window.  With this you can do: >
 	:e one
 	:set list
 	:e two
@@ -2408,6 +2408,9 @@ A jump table for the options with a short description can be found at |Q_op|.
 		close		show close button: "on" (default) or "off"
 		height		maximum height of the popup
 		highlight	popup highlight group (default: PmenuSel)
+		opacity		opacity percentage 0-100 (default 100, fully
+				opaque).  When less than 100, content beneath
+				the popup shows through.
 		resize		show resize handle: "on" (default) or "off"
 		shadow		"off" (default) or "on" using |hl-PmenuShadow|
 		width		maximum width of the popup
@@ -2415,6 +2418,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 	Example: >
 		:set completepopup=height:10,border:single,highlight:InfoPopup
 		:set completepopup=width:60,border:custom:─;│;─;│;┌;┐;┘;└
+		:set completepopup=border:round,opacity:80
 <
 	When "align" is set to "item", the popup is positioned near the
 	selected item and moves as the selection changes.
@@ -3994,7 +3998,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	|String| and is the |:find| command argument.  The second argument is
 	a |Boolean| and is set to |v:true| when the function is called to get
 	a List of command-line completion matches for the |:find| command.
-	The function should return a List of strings.
+	The function should return a List, which is handled similarly to the
+	return value of a |:command-completion-customlist| function.
 
 	The function is called only once per |:find| command invocation.
 	The function can process all the directories specified in 'path'.
@@ -4707,10 +4712,10 @@ A jump table for the options with a short description can be found at |Q_op|.
 		Photon and MacVim GUIs.
 								*'go-s'*
 	  's'	Enable fullscreen mode.  Currently only supported in the
-		MS-Windows GUI version.  When set, the window will occupy the
-		entire screen and remove window decorations.  Define custom
-		mappings to toggle this mode conveniently.  For detailed usage
-		instructions, see |gui-w32-fullscreen|.
+		MS-Windows and GTK GUI version.  When set, the window will
+		occupy the entire screen and remove window decorations.
+		Define custom mappings to toggle this mode conveniently.
+		For detailed usage instructions, see |gui-fullscreen|.
 								*'go-r'*
 	  'r'	Right-hand scrollbar is always present.
 								*'go-R'*
@@ -4856,7 +4861,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 				     l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,
 				     a:LineNrAbove,b:LineNrBelow,
 				     N:CursorLineNr,r:Question,s:StatusLine,
-				     S:StatusLineNC,c:VertSplit,t:Title,
+				     S:StatusLineNC,c:VertSplit,
+				     |:VertSplitNC,t:Title,
 				     v:Visual,V:VisualNOS,w:WarningMsg,
 				     W:WildMenu,f:Folded,F:FoldColumn,
 				     A:DiffAdd,C:DiffChange,D:DiffDelete,
@@ -4867,7 +4873,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 				     [:PmenuKind,]:PmenuKindSel,
 				     {:PmenuExtra,}:PmenuExtraSel,
 				     x:PmenuSbar,X:PmenuThumb,j:PmenuBorder,
-				     H:PmenuShadow,*:TabLine,
+				     H:PmenuShadow,p:Popup,J:PopupBorder,
+				     Q:PopupTitle,*:TabLine,
 				     #:TabLineSel,_:TabLineFill,!:CursorColumn,
 				     .:CursorLine,o:ColorColumn,q:QuickFixLine,
 				     z:StatusLineTerm,Z:StatusLineTermNC,
@@ -4904,6 +4911,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	|hl-StatusLineNC|  S  status lines of not-current windows
 	|hl-Title|	 t  Titles for output from ":set all", ":autocmd" etc.
 	|hl-VertSplit|	 c  column used to separate vertically split windows
+	|hl-VertSplitNC| |  column separating non-current vertically split
+			    windows
 	|hl-Visual|	 v  Visual mode
 	|hl-VisualNOS|	 V  Visual mode when Vim is "Not Owning the
 			    Selection" Only X11 Gui's |gui-x11|,
@@ -4936,6 +4945,9 @@ A jump table for the options with a short description can be found at |Q_op|.
 	|hl-PmenuMatchSel| <  popup menu matched text in selected line
 	|hl-PmenuBorder|   j  popup menu border characters
 	|hl-PmenuShadow|   H  popup menu shadow
+	|hl-Popup|	 p  popup window body
+	|hl-PopupBorder|   J  popup window border characters
+	|hl-PopupTitle|	 Q  popup window title
 	|hl-PreInsert|	 I  text inserted when "preinsert" is in 'completeopt'
 	|hl-Normal|	 (  Window color (supersedes 'wincolor' option)
 
@@ -6332,6 +6344,54 @@ A jump table for the options with a short description can be found at |Q_op|.
 	NOTE: 'modeline' is set to the Vi default value when 'compatible' is
 	set and to the Vim default value when 'compatible' is reset.
 
+		    *'modelinestrict'* *'mlst'* *'nomodelinestrict'* *'nomlst'*
+'modelinestrict' 'mlst'	boolean (default: on)
+			global
+	When on, only a safe subset of options can be set from a |modeline|.
+	The following options are allowed:
+		'autoindent'
+		'cindent'
+		'commentstring'
+		'expandtab'
+		'filetype'
+		'foldcolumn'
+		'foldenable'
+		'foldmarker'
+		'foldmethod'
+		'modifiable'
+		'readonly'
+		'rightleft'
+		'shiftwidth'
+		'smartindent'
+		'softtabstop'
+		'spell'
+		'spelllang'
+		'tabstop'
+		'textwidth'
+		'varsofttabstop'
+		'vartabstop'
+
+	Any other option set from a modeline will be silently ignored.
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
+	As an exception, `set nomodeline` is honored from within a modeline
+	even when 'modelinestrict' is on.  Other forms (`set modeline=0`,
+	`set modeline!`, `set invmodeline`) are still silently ignored.
+	This lets a file disable further modeline processing for itself.
+
+	The behaviour of 'modeline', 'modelinestrict' and 'modelineexpr' is
+	as follows:
+
+	'modeline'| 'modelinestrict'| 'modelineexpr' | Meaning
+	----------+-----------------+-------------------+--------~
+	   on     |    off          |   on           | All options can be set
+	   on     |    on           |   any          | Only whitelisted
+		  |                 |                | options can be set
+	   on     |    off          |   off          | All options except for
+		  |                 |                | expr options can be set
+	   off    |    any          |   any          | No options can be set
+
 				*'modifiable'* *'ma'* *'nomodifiable'* *'noma'*
 				*E21*
 'modifiable' 'ma'	boolean	(default on)
@@ -6445,7 +6505,10 @@ A jump table for the options with a short description can be found at |Q_op|.
 			be acted upon, i.e. no cursor move.  This implies of
 			course, that right clicking outside a selection will
 			end Visual mode.
-	Overview of what button does what for each model:
+
+	For a detailed description of 'mousemodel' behaviour see
+	|mouse-mode-table|.  Overview of what button does what for each model:
+
 	mouse		    extend		popup(_setpos) ~
 	left click	    place cursor	place cursor
 	left drag	    start selection	start selection
@@ -7022,7 +7085,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 			global
 	Defines a border and optional decorations for the popup menu in
 	completion.  The value is a comma-separated list of keywords.
-	See |'pumopt'| for a consolidated alternative.
+	See 'pumopt' for a consolidated alternative.
 
 	Border styles (at most one):
 	"single"	use thin box-drawing characters
@@ -7058,7 +7121,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 	Determines the maximum number of items to show in the popup menu for
 	Insert mode completion.  When zero as much space as available is used.
 	|ins-completion-menu|.
-	See |'pumopt'| for a consolidated alternative.
+	See 'pumopt' for a consolidated alternative.
 
 						*'pummaxwidth'* *'pmw'*
 'pummaxwidth' 'pmw'	number	(default 0)
@@ -7070,13 +7133,13 @@ A jump table for the options with a short description can be found at |Q_op|.
 
 	This option takes precedence over 'pumwidth'.
 	|ins-completion-menu|.
-	See |'pumopt'| for a consolidated alternative.
+	See 'pumopt' for a consolidated alternative.
 
 						*'pumopt'*
 'pumopt'		string	(default "")
 			global
 	Configures the popup menu used for Insert mode completion.
-	The value is a comma-separated list of key:value pairs and flags.
+	The value is a comma-separated list of "key:value" pairs and flags.
 
 	Keys with values:
 	  border:{style}	set a border style (at most one):
@@ -7098,7 +7161,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 				of 'fillchars' option.
 	  opacity:{n}		opacity percentage 0-100 (default 100).
 				When less than 100, background content shows
-				through the popup menu.
+				through the popup menu.  Requires the GUI,
+				'termguicolors', or a 256-color terminal.
 
 	Flags (no value):
 	  margin		adds one-cell spacing inside the left and
@@ -7106,8 +7170,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	  shadow		draws a shadow at the right and bottom edges.
 
 	Border styles using box-drawing characters ("single", "double",
-	"round") are only available when 'encoding' is "utf-8" and
-	'ambiwidth' is "single".
+	"round") are only available when 'encoding' is "utf-8" and 'ambiwidth'
+	is "single".
 
 	Highlight groups:
 	|hl-PmenuBorder|	used for the border characters
@@ -7130,7 +7194,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 			global
 	Determines the minimum width to use for the popup menu for Insert mode
 	completion.  |ins-completion-menu|.
-	See |'pumopt'| for a consolidated alternative.
+	See 'pumopt' for a consolidated alternative.
 
 						*'pythondll'*
 'pythondll'		string	(default depends on the build)
@@ -7668,8 +7732,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	Minimal number of screen lines to keep above and below the cursor.
 	This will make some context visible around where you are working.  If
 	you set it to a very large value (999) the cursor line will always be
-	in the middle of the window (except at the start or end of the file or
-	when long lines wrap).
+	in the middle of the window (except at the start or end of the file,
+	see 'scrolloffpad', or when long lines wrap).
 	After using the local value, go back the global value with one of
 	these two: >
 		setlocal scrolloff<
@@ -7677,7 +7741,24 @@ A jump table for the options with a short description can be found at |Q_op|.
 <	For scrolling horizontally see 'sidescrolloff'.
 	NOTE: This option is set to 0 when 'compatible' is set.
 
-						*'scrollopt'* *'sbo'*
+						*'scrolloffpad'* *'sop'*
+'scrolloffpad' 'sop'	number	(default 0)
+			global or local to window |global-local|
+	When 'scrolloff' and 'scrolloffpad' are greater than zero, allow
+	the cursor to remain centered when at the end of the file.
+	Normally, 'scrolloff' will not keep the cursor centered at the
+	end of the file.
+
+	A value of 0 disables this feature.  Any value above 0 enables it.
+	For a window-local value, -1 means to use the global value.
+	Values below -1 are invalid.
+
+	After using the local value, go back the global value with one of
+	these two: >
+		setlocal scrolloffpad<
+		setlocal scrolloffpad=-1
+
+<						*'scrollopt'* *'sbo'*
 'scrollopt' 'sbo'	string	(default "ver,jump")
 			global
 	This is a comma-separated list of words that specifies how
@@ -7914,6 +7995,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 	Note: When using a pipe like "| tee", you'll lose the exit code of the
 	shell command.  This might be configurable by your shell, look for
 	the pipefail option (for bash and zsh, use ":set -o pipefail").
+	Only a single "%s" value is allowed.
 	This option cannot be set from a |modeline| or in the |sandbox|, for
 	security reasons.
 
@@ -7957,6 +8039,9 @@ A jump table for the options with a short description can be found at |Q_op|.
 	become obsolete (at least for Unix).
 	This option cannot be set from a |modeline| or in the |sandbox|, for
 	security reasons.
+								*E1577*
+	Only a single "%s" item is allowed in the option value.
+
 
 			*'shellslash'* *'ssl'* *'noshellslash'* *'nossl'*
 'shellslash' 'ssl'	boolean	(default off)
@@ -8118,6 +8203,9 @@ A jump table for the options with a short description can be found at |Q_op|.
 		search count statistics.  The maximum limit can be set with
 		the 'maxsearchcount' option, see also |searchcount()|
 		function.
+	  u	don't give undo and redo messages like			*shm-u*
+		"1 line less; before #1  1 second ago", "Already at oldest
+		change" or "Already at newest change"
 
 	This gives you the opportunity to avoid that a change between buffers
 	requires you to hit , but still gives as useful a message as
@@ -8718,7 +8806,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	{ NF  Evaluate expression between '%{' and '}' and substitute result.
 	      Note that there is no '%' before the closing '}'.  The
 	      expression cannot contain a '}' character, call a function to
-	      work around that.  See |stl-%{| below.
+	      work around that.  See |stl-%{| below.  Use '%0{' to insert the
+	      result verbatim.
 	{% -  This is almost same as { except the result of the expression is
 	      re-evaluated as a statusline format string.  Thus if the
 	      return value of expr contains % items they will get expanded.
@@ -8756,10 +8845,62 @@ A jump table for the options with a short description can be found at |Q_op|.
 	      applied to StatusLineNC for the statusline of non-current
 	      windows.
 	      The number N must be between 1 and 9.  See |hl-User1..9|
-								*stl-%@*
+							*stl-%@*
 	@ -   Inserts a newline.  This only takes effect when the "maxheight"
 	      value of 'statuslineopt' is greater than 1, or for |tabpanel|.
 
+							*stl-%[FuncName]*
+	%[ defines clickable regions in the statusline.  When the user clicks
+	on a region with the mouse, the specified function is called.  The
+	same syntax can also be used in 'tabline' and 'tabpanel'.
+
+	  %[FuncName]	Start of a clickable region.  "FuncName" is the name
+			of a Vim function to call when the region is clicked.
+	  %[]		End of the clickable region.  If omitted, the region
+			extends to the end of the statusline or to the start
+			of the next clickable region.
+
+	A {minwid} value can be used to pass an identifier to the callback:
+	  %3[FuncName]	Starts a clickable region with minwid 3.
+
+	The function receives a single |Dictionary| argument with these
+	entries:
+	  "minwid"	The minwid value from %N[Func] (0 if not specified).
+	  "nclicks"	Number of clicks: 1, 2, or 3.
+	  "button"	Mouse button: "l" (left), "m" (middle), "r" (right).
+	  "mods"	Modifier keys: combination of "s" (shift), "c" (ctrl),
+			"a" (alt).  Empty string if no modifiers.
+	  "winid"	|window-ID| of the window whose statusline was clicked,
+			or 0 when the click was in 'tabline' or 'tabpanel'.
+	  "area"	"statusline", "tabline", or "tabpanel".  Indicates
+			which option the clicked region belongs to.
+	  "tabnr"	(tabpanel only) Tab page number of the clicked label.
+
+	If the function returns non-zero, the statusline is redrawn.
+	Dragging the statusline to resize the window still works even when
+	click handlers are defined.  When used in 'tabline' or 'tabpanel',
+	clicks in %[FuncName] regions are dispatched to the callback
+	instead of the default tab-selection behavior.
+
+	Example: >
+	    func! ClickFile(info)
+		if a:info.button ==# 'l' && a:info.nclicks == 2
+		    browse edit
+		endif
+		return 0
+	    endfunc
+	    set statusline=%[ClickFile]%f%[]\ %l:%c
+<	This makes the filename in the statusline clickable.  Double-clicking
+	it opens the file browser.
+
+	Use `has('statusline_click')` to check if this feature is available.
+	This is useful for backward compatibility: >
+	    if has('statusline_click')
+		set statusline=%[ClickFile]%f%[]\ %l:%c
+	    else
+		set statusline=%f\ %l:%c
+	    endif
+<
 	When displaying a flag, Vim removes the leading comma, if any, when
 	that flag comes right after plaintext.  This will make a nice display
 	when flags are used like in the examples below.
@@ -8793,6 +8934,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	A result of all digits is regarded a number for display purposes.
 	Otherwise the result is taken as flag text and applied to the rules
 	described above.
+								*stl-%0{*
+	With %0{ neither applies: the result is inserted as a literal string.
 
 	Watch out for errors in expressions.  They may render Vim unusable!
 	If you are stuck, hold down ':' or 'Q' to get a prompt, then quit and
@@ -9074,24 +9217,22 @@ A jump table for the options with a short description can be found at |Q_op|.
 	Optional settings for the |tabpanel|,  It can consist of the following
 	items.  Items must be separated by a comma.
 
-		align:{text}	Specifies the position of the tabpanel.
-				Currently supported positions are:
-
-				left	left-side
+	    align:{text}    Specifies the position of the tabpanel.
+			    Currently supported positions are:
+				left	left-side  (default)
 				right	right-side
-
-				(default "left")
-
-		columns:{n}	Number of columns of the tabpanel.
-				If this value is 0 or less than 'columns', the
-				tab panel will not be displayed.
-				(default 20)
-
-		vert		Use a vertical separator for tabpanel.
-				The vertical separator character is taken from
-				"tpl_vert" in 'fillchars'.
-				(default off)
-
+	    columns:{n}	    Number of columns of the tabpanel.  (default 20)
+			    If this value is 0 or less than 'columns', the
+			    tabpanel will not be displayed.
+	    scrollbar	    A one-column scrollbar is always displayed at the
+			    right edge of the tabpanel, regardless of the
+			    "align:" setting.  (default off)
+			    See |tabpanel-scroll|.
+	    vert	    The vertical separator is drawn at the boundary
+			    between the tabpanel and the buffer area.
+			    (default off)
+			    The character to be drawn uses "tpl_vert" from
+			    'fillchars'.
 	Examples: >
 		:set tabpanelopt=columns:16,align:right
 		:set tabpanelopt=
@@ -9229,6 +9370,22 @@ A jump table for the options with a short description can be found at |Q_op|.
 	file names from the list.  This avoids problems when a future version
 	uses another default.
 
+			*'tagsecure'* *'tsc'* *'notagsecure'* *'notsc'*
+'tagsecure' 'tsc'	boolean	(default on)
+			global
+	When on, Vim refuses to follow tag entries whose file field looks like
+	a URL ("scheme://..."), aborting the jump with error |E1576|.  This
+	prevents tag files from causing Vim to open URLs through |netrw|, which
+	would trigger a network request and expose netrw's URL-handling code to
+	attacker-controlled input or lead to environment exfiltration.
+
+	Tag files might be distributed alongside source code (e.g. via Git
+	repositories) and may therefore be untrustworthy.  Only disable
+	this option if you fully control the tag files Vim will read.
+
+	This option cannot be set from a |modeline| or in the |sandbox|, for
+	security reasons.
+
 				*'tagstack'* *'tgst'* *'notagstack'* *'notgst'*
 'tagstack' 'tgst'	boolean	(default on)
 			global
@@ -10078,6 +10235,14 @@ A jump table for the options with a short description can be found at |Q_op|.
 		letter.  Thus "KEEPTHIS and "K_L_M" are stored, but "KeepThis"
 		and "_K_L_M" are not.  Nested List and Dict items may not be
 		read back correctly, you end up with an empty item.
+
+		Restoring |List|, |Dictionary| and |Tuple| variables is done by
+		parsing their textual form with the Vim expression evaluator.
+		Reading a viminfo file with "!" enabled is therefore only safe
+		when the file is trusted.  In particular, do not enable "!"
+		before reading a viminfo file you obtained from another user,
+		downloaded, or that is writable by another account.  See
+		also |viminfo-security|.
 							*viminfo-quote*
 	"	Maximum number of lines saved for each register.  Old name of
 		the '<' item, with the disadvantage that you need to put a
@@ -10435,8 +10600,12 @@ A jump table for the options with a short description can be found at |Q_op|.
 			applies to buffer name completion.
 	"noselect"	If 'wildmenu' is enabled, show the menu but do not
 			preselect the first item.
-	If only one match exists, it is completed fully, unless "noselect" is
-	specified.
+	"noinsert"	If 'wildmenu' is enabled, show the menu and preselect
+			the first match, but do not insert it in the command
+			line.  If both "noinsert" and "noselect" are present,
+			"noselect" takes precedence.
+	If only one match exists, it is completed fully, unless "noselect" or
+	"noinsert" is specified.
 
 	Some useful combinations of colon-separated values:
 	"longest:full"		Start with the longest common string and show
@@ -10704,11 +10873,10 @@ A jump table for the options with a short description can be found at |Q_op|.
 				*'wlsteal'* *'wst'* *'nowlsteal'* *'nowst'*
 'wlsteal' 'wst'		boolean  (default off)
 			global
-			{only when the |+wayland_focus_steal| feature is
-			included}
+	DEPRECATED: This option is no longer used; changing it has no effect.
+
 	When enabled, then allow Vim to steal focus by creating a temporary
-	surface, in order to access the clipboard.  For more information see
-	|wayland-focus-steal|.
+	surface, in order to access the clipboard.
 
 						*'wltimeoutlen'* *'wtm'*
 'wltimeoutlen' 'wtm'	number	(default 500)
@@ -10721,9 +10889,6 @@ A jump table for the options with a short description can be found at |Q_op|.
 	some cases.  On the other hand, it may also mean you receive errors
 	when the compositor takes more time to respond than usual.
 
-	Additionally, this option is also used as the maximum timeout when
-	waiting for a surface to gain focus, see |wayland-focus-steal|.
-
 						*'wrap'* *'nowrap'*
 'wrap'			boolean	(default on)
 			local to window
diff --git a/runtime/doc/pi_netrw.txt b/runtime/doc/pi_netrw.txt
index a86cac36ba..e3c06852cc 100644
--- a/runtime/doc/pi_netrw.txt
+++ b/runtime/doc/pi_netrw.txt
@@ -1047,7 +1047,7 @@ QUICK REFERENCE: MAPS				*netrw-browse-maps* {{{2
 	   C	Setting the editing window                           |netrw-C|
 	   d	Make a directory                                     |netrw-d|
 	   D	Attempt to remove the file(s)/directory(ies)         |netrw-D|
-	   gb	Go to previous bookmarked directory                  |netrw-gb|
+	   gb	Go to bookmark                                       |netrw-gb|
 	   gd	Force treatment as directory                         |netrw-gd|
 	   gf	Force treatment as file                              |netrw-gf|
 	   gh	Quick hide/unhide of dot-files                       |netrw-gh|
@@ -1056,11 +1056,12 @@ QUICK REFERENCE: MAPS				*netrw-browse-maps* {{{2
 	   i	Cycle between thin, long, wide, and tree listings    |netrw-i|
 	   I	Toggle the displaying of the banner                  |netrw-I|
 	   mb	Bookmark current directory                           |netrw-mb|
+	   mB	Delete bookmark                                      |netrw-mB|
 	   mc	Copy marked files to marked-file target directory    |netrw-mc|
 	   md	Apply diff to marked files (up to 3)                 |netrw-md|
 	   me	Place marked files on arg list and edit them         |netrw-me|
 	   mf	Mark a file                                          |netrw-mf|
-	   mF	Unmark files                                         |netrw-mF|
+	   mF	Unmark buffer-local files                            |netrw-mF|
 	   mg	Apply vimgrep to marked files                        |netrw-mg|
 	   mh	Toggle marked file suffices' presence on hiding list |netrw-mh|
 	   mm	Move marked files to marked-file target directory    |netrw-mm|
@@ -1142,6 +1143,8 @@ One may easily "bookmark" the currently browsed directory by using >
 
 	mb
 <
+Note: Bookmarked paths are normalized and stored as absolute paths.
+
 								*.netrwbook*
 Bookmarks are retained in between sessions of vim in a file called .netrwbook
 as a |List|, which is typically stored in the first directory on the user's
@@ -1363,13 +1366,16 @@ Currently, this only works for local files.
 Associated setting variables: |g:netrw_chgperm|
 
 
-CHANGING TO A BOOKMARKED DIRECTORY			*netrw-gb*  {{{2
+CHANGING TO A BOOKMARKED PATH			*netrw-gb*  {{{2
 
-To change directory back to a bookmarked directory, use
+To change to a bookmarked path, use >
 
-	{cnt}gb
+	[{cnt}]gb
 
 Any count may be used to reference any of the bookmarks.
+If {cnt} is omitted, it shows a list of the current bookmarks
+and prompts for a bookmark number to go to.
+
 Note that |netrw-qb| shows both bookmarks and history; to go
 to a location stored in the history see |netrw-u| and |netrw-U|.
 
@@ -1432,10 +1438,13 @@ DELETING BOOKMARKS					*netrw-mB* {{{2
 
 To delete a bookmark, use >
 
-	{cnt}mB
+	[{cnt}]mB
 
 If there are marked files, then mB will remove them from the
 bookmark list.
+If no files are marked and {cnt} is omitted, it shows a list
+of the current bookmarks and prompts for a bookmark number
+to delete.
 
 Alternatively, one may use :NetrwMB! (see |netrw-:NetrwMB|). >
 
@@ -2275,9 +2284,10 @@ Set the marked file copy/move-to target (see |netrw-mc| and |netrw-mm|):
     displayed directory is used for the copy/move-to target.
 
   * Also, if the cursor is in the banner, then the netrw window's currently
-    displayed directory is used for the copy/move-to target.
-    Unless the target already is the current directory.  In which case,
-    typing "mf" clears the target.
+    displayed directory is used for the copy/move-to target - unless that
+    directory is already the target, in which case typing "mt" again clears
+    it.  Repeating "mt" in the banner thus toggles the current directory as
+    the target.
 
   * However, if the cursor is atop a directory name, then that directory is
     used for the copy/move-to target
@@ -2854,10 +2864,6 @@ your browsing preferences.  (see also: |netrw-settings|)
 				such as listing, file removal, etc.
 				 default: ssh
 
-  *g:netrw_tmpfile_escape*	=' &;'
-				escape() is applied to all temporary files
-				to escape these characters.
-
   *g:netrw_timefmt*		specify format string to vim's strftime().
 				The default, "%c", is "the preferred date
 				and time representation for the current
diff --git a/runtime/doc/pi_tar.txt b/runtime/doc/pi_tar.txt
index 0bba3c37d3..5a4dae8f31 100644
--- a/runtime/doc/pi_tar.txt
+++ b/runtime/doc/pi_tar.txt
@@ -1,4 +1,4 @@
-*pi_tar.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*pi_tar.txt*	For Vim version 9.2.  Last change: 2026 Apr 16
 
 		       +====================+
 		       | Tar File Interface |
@@ -101,10 +101,17 @@ Copyright 2005-2017:					*tar-copyright*
 4. History						*tar-history*
 
 	unreleased:
+		Apr 16, 2026	* add missing g:tar_secure into tar#Extract
+		Apr 15, 2026	* add path traversal checks in tar#Extract()
+		Apr 09, 2026	* fix zstd support and dotted filename support
+		Apr 06, 2026	* fix lz4 support
+		Feb 07, 2026	* make path traversal detection more robust
+		Feb 06, 2026	* fix bug with nowrapscan
+		Jul 16, 2025	* update minimum required Vim version
 		Jul 13, 2025	* drop leading /
 		May 19, 2025	* restore working directory after read/write
 		Apr 16, 2025	* decouple from netrw by adding s:WinPath()
-				instead of shelling out to file(1)
+				  instead of shelling out to file(1)
 		Mar 02, 2025	* determine the compression using readblob()
 		Mar 02, 2025	* escape the filename before using :read
 		Mar 01, 2025	* fix syntax error in tar#Read()
diff --git a/runtime/doc/pi_vimball.txt b/runtime/doc/pi_vimball.txt
index 07fc68f7eb..e1770e289e 100644
--- a/runtime/doc/pi_vimball.txt
+++ b/runtime/doc/pi_vimball.txt
@@ -1,4 +1,4 @@
-*pi_vimball.txt*	For Vim version 9.2.  Last change: 2026 Apr 05
+*pi_vimball.txt*	For Vim version 9.2.  Last change: 2026 Apr 16
 
 			       ----------------
 			       Vimball Archiver
@@ -166,6 +166,11 @@ WINDOWS							*vimball-windows*
 ==============================================================================
 4. Vimball History					*vimball-history* {{{1
 
+	unreleased:
+	     Feb 28, 2025 * add support for bzip3 (#16755)
+	     Apr 05, 2026 * Detect path traversal attacks
+	     Apr 09, 2026 * Detect more path traversal attacks
+	     Apr 16, 2026 * Block Windows drive letter paths
 	37 : Jul 18, 2014 * (by request of T. Miedema) added augroup around
 			    the autocmds in vimballPlugin.vim
 	     Jul 06, 2015 * there are two uses of tabc; changed to tabc!
diff --git a/runtime/doc/pi_zip.txt b/runtime/doc/pi_zip.txt
index e9294b4059..81275b24ec 100644
--- a/runtime/doc/pi_zip.txt
+++ b/runtime/doc/pi_zip.txt
@@ -1,4 +1,4 @@
-*pi_zip.txt*	For Vim version 9.2.  Last change: 2026 Apr 05
+*pi_zip.txt*	For Vim version 9.2.  Last change: 2026 May 16
 
 				+====================+
 				| Zip File Interface |
@@ -114,9 +114,9 @@ Copyright: Copyright (C) 2005-2015 Charles E Campbell	 *zip-copyright*
    should be treated as zip files.
 
    Alternatively, one may change *g:zipPlugin_ext* in one's .vimrc.
-   Currently (as of October 2025) it holds: >
+   Currently (as of May 2026) it holds: >
 
-        let g:zipPlugin_ext='*.aar,*.apk,*.celzip,*.crtx,*.docm,*.docx,
+        let g:zipPlugin_ext='*.aar,*.apk,*.cbz,*.celzip,*.crtx,*.docm,*.docx,
        \ *.dotm,*.dotx,*.ear,*.epub,*.gcsx,*.glox,*.gqsx,*.ja,*.jar,*.kmz,
        \ *.odb,*.odc,*.odf,*.odg,*.odi,*.odm,*.odp,*.ods,*.odt,*.otc,*.otf,
        \ *.otg,*.oth,*.oti,*.otp,*.ots,*.ott,*.oxt,*.pkpass,*.potm,*.potx,
diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt
index 6b99ac47ee..2e91244778 100644
--- a/runtime/doc/popup.txt
+++ b/runtime/doc/popup.txt
@@ -1,4 +1,4 @@
-*popup.txt*	For Vim version 9.2.  Last change: 2026 Apr 06
+*popup.txt*	For Vim version 9.2.  Last change: 2026 May 17
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -44,8 +44,11 @@ A popup window can be used for such things as:
 The text in the popup window can be colored with |text-properties|.  It is
 also possible to use syntax highlighting.
 
-The default color used is "Pmenu".  If you prefer something else use the
-"highlight" argument or the 'wincolor' option, e.g.: >
+The default colors are taken from |hl-Popup| (body), |hl-PopupBorder|
+(border) and |hl-PopupTitle| (title), which all link to |hl-Pmenu| by
+default for backward compatibility.  Override them to give general popup
+windows a different look than the popup completion menu, or use the
+"highlight" argument or the 'wincolor' option for a per-popup override: >
 	hi MyPopupColor ctermbg=lightblue guibg=lightblue
 	call setwinvar(winid, '&wincolor', 'MyPopupColor')
 
@@ -712,6 +715,15 @@ The second argument of |popup_create()| is a dictionary with options:
 			when "textprop" is present.
 	textpropid	Used to identify the text property when "textprop" is
 			present.  Use zero to reset.
+	clipwindow	Only used when "textprop" is set.  When TRUE the popup
+			is kept within the window containing the text
+			property: if the text property scrolls past that
+			window's top, bottom, left or right edge, the popup
+			is clipped at that edge instead of being drawn
+			outside it.  Once the text property has scrolled out
+			of the window the popup is hidden.
+			Default FALSE.
+			See |popup-clipwindow|.
 	fixed		When FALSE (the default), and:
 			 - "pos" is "botleft" or "topleft", and
 			 - the popup would be truncated at the right edge of
@@ -751,6 +763,10 @@ The second argument of |popup_create()| is a dictionary with options:
 			border one line of padding is added to put the title
 			on.  You might want to add one or more spaces at the
 			start and end as padding.
+			The title uses |hl-PopupTitle| by default; if
+			"borderhighlight" is set the top border highlight is
+			used instead, and if "highlight"/'wincolor' is set
+			that is used.
 	wrap		TRUE to make the lines wrap (default TRUE).
 	drag		TRUE to allow the popup to be dragged with the mouse
 			by grabbing at the border.  Has no effect if the
@@ -799,6 +815,8 @@ The second argument of |popup_create()| is a dictionary with options:
 			the highlight for the top/right/bottom/left border.
 			Example: ['TopColor', 'RightColor', 'BottomColor,
 			'LeftColor']
+			When not given and "highlight"/'wincolor' is also not
+			set, |hl-PopupBorder| is used.
 	borderchars	List with characters, defining the character to use
 			for the top/right/bottom/left border.  Optionally
 			followed by the character to use for the
@@ -949,6 +967,31 @@ If the window for which the popup was defined is closed, the popup is closed.
 If the popup cannot fit in the desired position, it may show at a nearby
 position.
 
+
+CLIP TEXTPROP POPUP TO HOST WINDOW			*popup-clipwindow*
+
+When the popup is anchored to a text property in a split window, the popup is
+by default drawn relative to the whole screen and may extend past the edges of
+the window that contains the text property (the "host window").  Setting
+"clipwindow" to TRUE keeps the popup within window's content area:
+parts of the popup that fall outside the window are clipped, and the popup is
+hidden once the text property has scrolled entirely past one of the edges.
+
+Example: a tall popup anchored above the cursor that should never spill into
+the window below the split: >
+	call popup_create(body, #{
+		\ textprop: 'marker',
+		\ textpropid: id,
+		\ pos: 'topleft',
+		\ line: -1, col: 0,
+		\ posinvert: v:false,
+		\ clipwindow: v:true,
+		\ })
+<
+With "posinvert" left at its default (TRUE) the popup may be flipped to the
+opposite side of the text property when there is no room; set it to FALSE to
+keep the requested side and rely on "clipwindow" to clip the overflow.
+
 Some hints:
 - To avoid collision with other plugins the text property type name has to be
   unique.  You can also use the "bufnr" item to make it local to a buffer.
@@ -1067,8 +1110,9 @@ The opacity value ranges from 0 to 100:
     1-99	Partially transparent - the popup background is blended with
 		the underlying text, making both partially visible.
 
-The transparency effect requires using the GUI or having 'termguicolors'
-enabled in the terminal. Without it, the opacity setting has no effect.
+The transparency effect requires using the GUI, having 'termguicolors'
+enabled, or running in a 256-color terminal.  On terminals with fewer
+than 256 colors the opacity setting has no effect.
 
 When a popup is transparent:
 - The popup's background color is blended with the background text
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index 581d00b7a7..4b24d12980 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -1,4 +1,4 @@
-*quickfix.txt*  For Vim version 9.2.  Last change: 2026 Feb 14
+*quickfix.txt*  For Vim version 9.2.  Last change: 2026 May 28
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1821,9 +1821,9 @@ Basic items
 	%c		column number (finds a number representing character
 			column of the error, byte index, a  is 1
 			character column)
-	%v		virtual column number (finds a number representing
-			screen column of the error (1  == 8 screen
-			columns))
+	%v		virtual column number (finds a number representing the
+			screen column of the error, where a  is always 8
+			screen columns regardless of 'tabstop')
 	%k		end column number (finds a number representing
 			the character column of the error, byte index, or a
 			number representing screen end column of the error if
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index 9b4959240f..2400246e76 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -1,4 +1,4 @@
-*quickref.txt*	For Vim version 9.2.  Last change: 2026 Apr 07
+*quickref.txt*	For Vim version 9.2.  Last change: 2026 May 17
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -830,6 +830,7 @@ Short explanation of each option:		*option-list*
 'modeline'	  'ml'	    recognize modelines at start or end of file
 'modelineexpr'	  'mle'	    allow setting expression options from a modeline
 'modelines'	  'mls'     number of lines checked for modelines
+'modelinestrict'  'mlst'    only allow safe options in modelines
 'modifiable'	  'ma'	    changes to the text are not possible
 'modified'	  'mod'     buffer has been modified
 'more'			    pause listings when the whole screen is filled
@@ -901,6 +902,7 @@ Short explanation of each option:		*option-list*
 'scrollfocus'	  'scf'     scroll wheel applies to window under pointer
 'scrolljump'	  'sj'	    minimum number of lines to scroll
 'scrolloff'	  'so'	    minimum nr. of lines above and below cursor
+'scrolloffpad'	  'sop'	    vertically center cursor at end of file
 'scrollopt'	  'sbo'     how 'scrollbind' should behave
 'sections'	  'sect'    nroff macros that separate sections
 'secure'		    secure mode for reading .vimrc in current dir
@@ -965,6 +967,7 @@ Short explanation of each option:		*option-list*
 'taglength'	  'tl'	    number of significant characters for a tag
 'tagrelative'	  'tr'	    file names in tag file are relative
 'tags'		  'tag'     list of file names used by the tag command
+'tagsecure'	  'tsc'	    do not open remote files using tag commands
 'tagstack'	  'tgst'    push tags onto the tag stack
 'tcldll'		    name of the Tcl dynamic library
 'term'			    name of the terminal
diff --git a/runtime/doc/recover.txt b/runtime/doc/recover.txt
index c52910c1f7..d52aacd880 100644
--- a/runtime/doc/recover.txt
+++ b/runtime/doc/recover.txt
@@ -195,6 +195,10 @@ recovered file.  Or use |:DiffOrig|.
 Once you are sure the recovery is ok delete the swap file.  Otherwise, you
 will continue to get warning messages that the ".swp" file already exists.
 
+Note: Recovering swap files is best-effort.  Vim attempts to validate fields
+and skip corrupted sections, but the swap file format is intended for files
+you trust.  A crafted swap file may trigger parser bugs; such reports are
+treated as robustness issues rather than security vulnerabilities.
 
 
 ENCRYPTION AND THE SWAP FILE				*:recover-crypt*
diff --git a/runtime/doc/remote.txt b/runtime/doc/remote.txt
index 346f0b4a45..24f3ee9ca2 100644
--- a/runtime/doc/remote.txt
+++ b/runtime/doc/remote.txt
@@ -80,9 +80,10 @@ The following command line arguments are available:
 								*--clientserver*
    --clientserver {method}	Use the specified method {method} as the
 				backend for clientserver functionality.  Can
-				either be "socket" or "x11".
+				either be "socket", "x11", or "mswin".
 				{only available when compiled with both |+X11|
-				and |+socketserver| features}
+				and |+socketserver| features, or
+				|+socketserver| on MS-Windows}
 
 
 Examples ~
@@ -221,12 +222,16 @@ When using gvim, the --remote-wait only works properly this way: >
 <
 ==============================================================================
 4. Socket server specific items			    *socketserver-clientserver*
-				    *E1563* *E1564* *E1565* *E1566* *E1567*
+						    *E1564* *E1565* *E1566*
 
-The communication between client and server is done using Unix domain sockets.
-These sockets are either placed in these directories in the following order of
+NOTE: Vim version before patch 9.2.511 use a different socketserver backend
+which is incompatible with the new one, which is based on channels and JSON.
+
+The communication between client and server is done using channels internally.
+When using the traditional/generic clientserver naming (only available on
+Unix), sockets are placed in these directories in the following order of
 availability:
-    1. "$XDG_RUTIME_DIR/vim" if $XDG_RUNTIME_DIR is set in the environment.
+    1. "$XDG_RUNTIME_DIR/vim" if $XDG_RUNTIME_DIR is set in the environment.
     2. "$TMPDIR/vim-[uid]", where "[uid]" is the uid of the user.  This
        directory will have the access permissions set to 700 so only the user
        can read or write from/to it.  If $TMPDIR is not set, "/tmp" is used.
@@ -238,46 +243,56 @@ absolute or relative path.  If the server id starts with either a "/"
 Otherwise the server id will be the filename of the socket which will be
 placed in the above common directories.  Note that a server id/name can only
 contain slashes "/" if it is taken as a path, so names such as "abc/dir" will
-be invalid.
+be invalid.  This feature is only available on Unix.
 
-Socket server functionality is available in both GTK GUI and terminal versions
-of Vim.  Unless Vim is compiled with |+autoservername| feature, the socket
-server will have to started explicitly, just like X11, even in the GUI.
+						    *socketserver-address*
+In addition, the socketserver can also be created as a |channel-address|. To
+do this, prefix the address with "channel:" (which will be ignored).  This is
+available on both Unix and MS-Windows, and is the only available naming for the
+socketserver backend on Windows.  However, note that |ch_listen()|
+restrictions apply, meaning only port numbers can be used for TCP sockets.
+
+If the name is prefixed with "name:", then the legacy servername behaviour is
+used, so "name:VIM" is the same as "VIM".
+
+Unless Vim is compiled with |+autoservername| feature, the socket server will
+have to started explicitly, similar to X11. This is unless a X11 GUI Vim is
+being used.
 
 If Vim crashes or does not exit cleanly, the socket server will not remove the
 socket file and it will be left around.  This is generally not a problem,
 because if a socket name is taken, Vim checks if the socket in its place is
 dead (not attached to any process), and can replace it instead of finding a
-new name.
-
-To send commands to a Vim socket server from another application, read the
-source file src/os_unix.c, there is detailed description of the protocol used.
+new name.  This is only relevant for Unix.
 
 						    *socketserver-differences*
-Most of the functionality is the same as X11, however unlike X11, where the
-client does not need to be a server in order to communicate with another
-server, the socket server requires the server to be running even as a client.
-The exception is |serverlist()| or the |--serverlist| argument, which does not
-require the server to be running.
+Most of the functionality is the same as the other clientserver backends.
 
-Additionally, the server id or client id will not be a number like X11 or
+However, the server id or client id will not be a number like X11 or
 MS-Windows (shown in hex representation), instead it is the absolute path to
-the socket.  This can be seen via the |v:servername| variable.
+the socket.  This can be seen via the |v:servername| variable.  If the name is
+a channel address, then it will be the address with the "a/" prefix as well.
 
-The |--serverlist| argument will act just like X11, however it only checks the
-given common directories above.  If a custom path is used for a socket, it
-will not be detected, such as a path either not in $XDG_RUNTIME_DIR or
-<$TMPDIR or /tmp>/vim of the |--serverlist| Vim process.
+Note when using |--remote-wait|, the client id will look like "t/". This naming is specifically for this command, and attempting to use
+it as an address will fail.
 
-If you have both |+socketserver| and |+X11| compiled, you will need to add
-|--clientserver| set to "socket" in combination with |--serverlist| to list
-the available servers.  You cannot list both types of backends in one command.
+If on Unix, the |--serverlist| argument will act just like X11, however it
+only checks the given common directories above.  If a custom path is used for
+a socket, it will not be detected, such as a path either not in
+$XDG_RUNTIME_DIR or <$TMPDIR or /tmp>/vim of the |--serverlist| Vim process.
+If on MS-Windows, then the |--serverlist| argument will output nothing.
+
+The |+socketserver| feature is automatically enabled when on Unix or
+MS-Windows, and the |+channel| feature is enabled
 
 						    *socketserver-x11*
-If Vim is compiled with both |+X11| and |+socketserver|, then deciding which
-backend to use is done at startup time, via the |--clientserver| argument.  By
-default if it is not specified, then X11 will be used.  A Vim instance using a
-socket server cannot communicate with one using X11.
+If Vim is compiled with |+socketserver| and another clientserver backend, then
+deciding which backend to use is done at startup time, via the
+|--clientserver| argument.  By default if it is not specified, then the native
+backend (X11 or MS-Window messages) will be used, if available.  A Vim
+instance using a socket server cannot communicate with one using another
+clientserver backend.
 
 ==============================================================================
 5. MacVim specific items				*macvim-clientserver*
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index ac7c78712a..95ccbb6687 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -1,4 +1,4 @@
-*repeat.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*repeat.txt*	For Vim version 9.2.  Last change: 2026 May 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -454,6 +454,9 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
 			nested ":try"s in the script.  The outermost ":endtry"
 			then stops sourcing the script.
 
+			In |Vim9| script `:finish` cannot be shortened, to
+			improve script readability.
+
 All commands and command sequences can be repeated by putting them in a named
 register and then executing it.  There are two ways to get the commands in the
 register:
diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt
index 27f97548b3..774f0777c3 100644
--- a/runtime/doc/spell.txt
+++ b/runtime/doc/spell.txt
@@ -1,4 +1,4 @@
-*spell.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*spell.txt*	For Vim version 9.2.  Last change: 2026 May 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -562,6 +562,11 @@ then Vim will try to guess.
 			avoid running out of memory compression will be done
 			now and then.  This can be tuned with the 'mkspellmem'
 			option.
+								*E1578*
+			There is a limit on how many postponed prefix and
+			compound flags can be stored for one word.  Reduce the
+			number of affix/compound flags on a word in the .dic
+			file that exceeds it.
 
 			After the spell file was written and it was being used
 			in a buffer it will be reloaded automatically.
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 855d5c5a02..48945985e6 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1,4 +1,4 @@
-*starting.txt*	For Vim version 9.2.  Last change: 2026 Mar 17
+*starting.txt*	For Vim version 9.2.  Last change: 2026 Jun 02
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -642,6 +642,12 @@ a slash.  Thus "-R" means recovery and "-/R" readonly.
 		of the output is: >
 			WID: 12345\n
 
+--display {display}					*--display*
+		Run Vim on {display}, connecting to that X server instead of
+		the one in $DISPLAY.  The "--display" long form is accepted
+		only by the GTK+ 2 or GTK+ 3 GUI, see also |-display|.
+		{only available with the |+xterm_clipboard| feature}
+
 --role {role}						*--role*
 		GTK+ 2 GUI only.  Set the role of the main window to {role}.
 		The window role can be used by a window manager to uniquely
@@ -1574,6 +1580,24 @@ Session.  You could have several Session files, one for each project you are
 working on.  Viminfo and Session files together can be used to effectively
 enter Vim and directly start working in your desired setup. |session-file|
 
+							*viminfo-security*
+A viminfo file written by Vim is plain text and contains Vim expressions for
+|List|, |Dictionary| and |Tuple| values.  When "!" is in 'viminfo' at the time
+Vim processes the file as a viminfo file, those expressions are evaluated.
+
+The default value of 'viminfo' does not include "!", so by default no
+expression evaluation happens.
+
+Opening a viminfo file in a buffer (e.g. with |:edit|) is harmless; Vim only
+displays the file contents.  The risk is letting Vim process an untrusted file
+through the viminfo machinery, which happens when:
+- |:rviminfo| is used on the file, or
+- 'viminfofile' is set to point at it, or
+- the file is placed at the path Vim already reads as viminfo
+  |viminfo-file-name|
+
+In any of those cases, do not have "!" in 'viminfo' if you do not trust it.
+
 							*viminfo-read*
 When Vim is started and the 'viminfo' option is non-empty, the contents of
 the viminfo file are read and the info can be used in the appropriate places.
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 907aa323c3..55d51270c1 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1,4 +1,4 @@
-*syntax.txt*	For Vim version 9.2.  Last change: 2026 Mar 22
+*syntax.txt*	For Vim version 9.2.  Last change: 2026 Jun 01
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -402,9 +402,8 @@ the desired value, or restored to their default by removing the variable using
 Remarks:
 - Some truly ancient browsers may not show the background colors.
 - From most browsers you can also print the file (in color)!
-- The latest TOhtml may actually work with older versions of Vim, but some
-  features such as conceal support will not function, and the colors may be
-  incorrect for an old Vim without GUI support compiled in.
+- Colors may be incorrect for Vim without GUI support compiled in.
+- The latest TOhtml requires Vim 9.1 or later.
 
 Here is an example how to run the script over all .c and .h files from a
 Unix shell: >
@@ -849,6 +848,19 @@ ADA
 See |ft-ada-syntax|
 
 
+ALGOL 68					*algol68* *ft-algol68-syntax*
+
+This syntax file currently targets the Algol 68 Genie project using the
+default UPPER stropping regime.  It should also be usable in other
+environments using the UPPER stropping regime, though somewhat less complete.
+
+Highlighting can be further configured with the following variables.
+
+Variable			Highlight ~
+*algol68_no_preludes*		no prelude identifiers, procedures or
+				operators
+
+
 ANT						*ant.vim* *ft-ant-syntax*
 
 The ant syntax file provides syntax highlighting for javascript and python
@@ -1248,6 +1260,7 @@ cpp_no_cpp11		don't highlight C++11 standard items
 cpp_no_cpp14		don't highlight C++14 standard items
 cpp_no_cpp17		don't highlight C++17 standard items
 cpp_no_cpp20		don't highlight C++20 standard items
+cpp_no_cpp23		don't highlight C++23 standard items
 
 
 CSH						*csh.vim* *ft-csh-syntax*
@@ -5978,7 +5991,14 @@ EndOfBuffer	Filler lines (~) after the last line in the buffer.
 							*hl-ErrorMsg*
 ErrorMsg	Error messages on the command line.
 							*hl-VertSplit*
-VertSplit	Column separating vertically split windows.
+VertSplit	Column separating vertically split windows that is adjacent
+		to the current window.  Drawn with the "vert" item of
+		'fillchars'.
+							*hl-VertSplitNC*
+VertSplitNC	Column separating vertically split windows where neither
+		adjacent window is the current window.  Drawn with the
+		"vert" item of 'fillchars'.
+		By default, highlighted like |hl-VertSplit|.
 							*hl-Folded*
 Folded		Line used for closed folds.
 							*hl-FoldColumn*
@@ -6056,6 +6076,18 @@ PmenuShadow	Popup menu: Used for shadow.
 ComplMatchIns	Matched text of the currently inserted completion.
 							*hl-PreInsert*
 PreInsert	Text inserted when "preinsert" is in 'completeopt'.
+							*hl-Popup*
+Popup		Popup window body, used when neither the popup's 'wincolor'
+		nor explicit "highlight" argument is set.  Linked to |hl-Pmenu|
+		by default.
+							*hl-PopupBorder*
+PopupBorder	Popup window border characters, used when "borderhighlight" is
+		not set and the popup's 'wincolor' is also not set.
+		Linked to |hl-Pmenu| by default.
+							*hl-PopupTitle*
+PopupTitle	Popup window title, used when "borderhighlight" is not set and
+		the popup's 'wincolor' is also not set.  Linked to
+		|hl-Pmenu| by default.
 							*hl-PopupSelected*
 PopupSelected	Popup window created with |popup_menu()|.  Linked to
 		|hl-PmenuSel| by default.
@@ -6094,16 +6126,23 @@ SpellRare	Word that is recognized by the spellchecker as one that is
 		hardly ever used. |spell|
 		This will be combined with the highlighting used otherwise.
 							*hl-StatusLine*
-StatusLine	Status line of current window.
+StatusLine	Status line of current window.  The highlight at the status
+		line's edge (StatusLine, or any %#... / %N* in 'statusline')
+		also extends into the adjacent vertical separator cell when
+		the status lines are connected (The "vert" in 'fillchars' is
+		not being drawn).
 							*hl-StatusLineNC*
-StatusLineNC	status lines of not-current windows
+StatusLineNC	status lines of not-current windows.  Like |hl-StatusLine|,
+		the edge highlight also extends into the adjacent vertical
+		separator cell.
 		Note: If this is equal to "StatusLine", Vim will use "^^^" in
 		the status line of the current window.
 							*hl-StatusLineTerm*
 StatusLineTerm	Status line of current window, if it is a |terminal| window.
 							*hl-StatusLineTermNC*
-StatusLineTermNC	Status lines of not-current windows that is a
-			|terminal| window.
+StatusLineTermNC
+		Status lines of not-current windows that is a |terminal|
+		window.
 							*hl-TabLine*
 TabLine		Tab pages line, not active tab page label.
 							*hl-TabLineFill*
@@ -6123,18 +6162,19 @@ Title		Titles for output from ":set all", ":autocmd" etc.
 							*hl-TitleBar*
 TitleBar	Title bar for the active Gui's window.
 		This feature is supported only in the MS-Windows GUI.
-		See |gui-w32-title-bar| for details
+		See |gui-w32-title-bar| for details.
 		Only the `guibg` and `guifg` highlight arguments are effective.
 							*hl-TitleBarNC*
 TitleBarNC	Title bar for inactive Gui's window.
 		This feature is supported only in the MS-Windows GUI.
-		See |gui-w32-title-bar| for details
+		See |gui-w32-title-bar| for details.
 		Only the `guibg` and `guifg` highlight arguments are effective.
 							*hl-Visual*
 Visual		Visual mode selection.
 							*hl-VisualNOS*
 VisualNOS	Visual mode selection when vim is "Not Owning the Selection".
-		Only X11 Gui's |gui-x11| and |xterm-clipboard| supports this.
+		Only X11 Gui's |gui-x11|, |xterm-clipboard| and
+		|wayland-selections| supports this.
 							*hl-WarningMsg*
 WarningMsg	Warning messages.
 							*hl-WildMenu*
@@ -6154,10 +6194,9 @@ Menu		Current font, background and foreground colors of the menus.
 		Also used for the toolbar.
 		Applicable highlight arguments: font, guibg, guifg.
 
-		NOTE: For Motif the font argument actually
-		specifies a fontset at all times, no matter if 'guifontset' is
-		empty, and as such it is tied to the current |:language| when
-		set.
+		NOTE: For Motif the font argument actually specifies a fontset
+		at all times, no matter if 'guifontset' is empty, and as such
+		it is tied to the current |:language| when set.
 
 							*hl-Scrollbar*
 Scrollbar	Current background and foreground of the main window's
@@ -6168,10 +6207,9 @@ Scrollbar	Current background and foreground of the main window's
 Tooltip		Current font, background and foreground of the tooltips.
 		Applicable highlight arguments: font, guibg, guifg.
 
-		NOTE: For Motif the font argument actually
-		specifies a fontset at all times, no matter if 'guifontset' is
-		empty, and as such it is tied to the current |:language| when
-		set.
+		NOTE: For Motif the font argument actually specifies a fontset
+		at all times, no matter if 'guifontset' is empty, and as such
+		it is tied to the current |:language| when set.
 
 ==============================================================================
 15. Linking groups		*:hi-link* *:highlight-link* *E412* *E413*
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt
index 3e307b648a..1b6f781272 100644
--- a/runtime/doc/tabpage.txt
+++ b/runtime/doc/tabpage.txt
@@ -1,4 +1,4 @@
-*tabpage.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*tabpage.txt*	For Vim version 9.2.  Last change: 2026 May 04
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -482,6 +482,42 @@ The vertical separator character is taken from "tpl_vert" in 'fillchars'.
 You can customize the appearance of the tab page labels using the highlight
 groups: |hl-TabPanel| |hl-TabPanelSel| |hl-TabPanelFill|
 
+SCROLLING IN THE TABPANEL				*tabpanel-scroll*
+
+When the total height of the tab page list exceeds the visible screen height,
+mouse wheel events over the tabpanel area scroll the tab page list up or down.
+The scroll step follows the 'mousescroll' setting.  Wheel events inside the
+tabpanel area are consumed by the tabpanel and do not trigger
+|| or || mappings.
+
+The current tab page is always brought into view: when the selected tab page
+changes (by |gt|, |gT|, |:tabnext| etc.), the panel scrolls so the current
+entry is visible.
+
+To show a vertical scrollbar indicating the current scroll position, add
+"scrollbar" to 'tabpanelopt': >
+	:set tabpanelopt+=scrollbar
+
+A one-column scrollbar is always displayed at the right edge of the tabpanel,
+regardless of the "align:" setting in 'tabpanelopt'.  Clicking on the
+scrollbar column moves the thumb to the click position, and the thumb can be
+dragged to scroll continuously.
+
+The scrollbar uses the |hl-PmenuSbar| highlight group for the track and
+|hl-PmenuThumb| for the thumb.
+
+The scroll offset is remembered across redraws.
+
+MOUSE CLICKS IN THE TABPANEL				*tabpanel-mouse*
+
+A left click on a row in the tabpanel selects the tab page that the row
+belongs to.  Unlike the tabline, a double click in the tabpanel does not open
+a new, empty tab page; it is treated the same as a single click.
+
+For finer-grained control, the 'tabpanel' value may contain |stl-%[FuncName]|
+click regions.  Clicks on those regions are dispatched to the callback
+function instead of falling through to tab page selection.
+
 ==============================================================================
 6. Setting 'guitablabel'				*setting-guitablabel*
 
diff --git a/runtime/doc/tags b/runtime/doc/tags
index a24132803b..fd1d18024d 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -542,6 +542,7 @@ $quote	eval.txt	/*$quote*
 'ml'	options.txt	/*'ml'*
 'mle'	options.txt	/*'mle'*
 'mls'	options.txt	/*'mls'*
+'mlst'	options.txt	/*'mlst'*
 'mm'	options.txt	/*'mm'*
 'mmd'	options.txt	/*'mmd'*
 'mmp'	options.txt	/*'mmp'*
@@ -551,6 +552,7 @@ $quote	eval.txt	/*$quote*
 'modeline'	options.txt	/*'modeline'*
 'modelineexpr'	options.txt	/*'modelineexpr'*
 'modelines'	options.txt	/*'modelines'*
+'modelinestrict'	options.txt	/*'modelinestrict'*
 'modifiable'	options.txt	/*'modifiable'*
 'modified'	options.txt	/*'modified'*
 'mopt'	options.txt	/*'mopt'*
@@ -723,10 +725,12 @@ $quote	eval.txt	/*$quote*
 'nomh'	options.txt	/*'nomh'*
 'noml'	options.txt	/*'noml'*
 'nomle'	options.txt	/*'nomle'*
+'nomlst'	options.txt	/*'nomlst'*
 'nommta'	options.txt	/*'nommta'*
 'nomod'	options.txt	/*'nomod'*
 'nomodeline'	options.txt	/*'nomodeline'*
 'nomodelineexpr'	options.txt	/*'nomodelineexpr'*
+'nomodelinestrict'	options.txt	/*'nomodelinestrict'*
 'nomodifiable'	options.txt	/*'nomodifiable'*
 'nomodified'	options.txt	/*'nomodified'*
 'nomore'	options.txt	/*'nomore'*
@@ -799,6 +803,7 @@ $quote	eval.txt	/*$quote*
 'nota'	options.txt	/*'nota'*
 'notagbsearch'	options.txt	/*'notagbsearch'*
 'notagrelative'	options.txt	/*'notagrelative'*
+'notagsecure'	options.txt	/*'notagsecure'*
 'notagstack'	options.txt	/*'notagstack'*
 'notbi'	options.txt	/*'notbi'*
 'notbidi'	options.txt	/*'notbidi'*
@@ -817,6 +822,7 @@ $quote	eval.txt	/*$quote*
 'noto'	options.txt	/*'noto'*
 'notop'	options.txt	/*'notop'*
 'notr'	options.txt	/*'notr'*
+'notsc'	options.txt	/*'notsc'*
 'nottimeout'	options.txt	/*'nottimeout'*
 'nottybuiltin'	options.txt	/*'nottybuiltin'*
 'nottyfast'	options.txt	/*'nottyfast'*
@@ -967,6 +973,7 @@ $quote	eval.txt	/*$quote*
 'scrollfocus'	options.txt	/*'scrollfocus'*
 'scrolljump'	options.txt	/*'scrolljump'*
 'scrolloff'	options.txt	/*'scrolloff'*
+'scrolloffpad'	options.txt	/*'scrolloffpad'*
 'scrollopt'	options.txt	/*'scrollopt'*
 'scs'	options.txt	/*'scs'*
 'sect'	options.txt	/*'sect'*
@@ -1025,6 +1032,7 @@ $quote	eval.txt	/*$quote*
 'so'	options.txt	/*'so'*
 'softtabstop'	options.txt	/*'softtabstop'*
 'sol'	options.txt	/*'sol'*
+'sop'	options.txt	/*'sop'*
 'sourceany'	vi_diff.txt	/*'sourceany'*
 'sp'	options.txt	/*'sp'*
 'spc'	options.txt	/*'spc'*
@@ -1241,6 +1249,7 @@ $quote	eval.txt	/*$quote*
 'taglength'	options.txt	/*'taglength'*
 'tagrelative'	options.txt	/*'tagrelative'*
 'tags'	options.txt	/*'tags'*
+'tagsecure'	options.txt	/*'tagsecure'*
 'tagstack'	options.txt	/*'tagstack'*
 'tal'	options.txt	/*'tal'*
 'tb'	options.txt	/*'tb'*
@@ -1293,6 +1302,7 @@ $quote	eval.txt	/*$quote*
 'transparency'	options.txt	/*'transparency'*
 'trz'	options.txt	/*'trz'*
 'ts'	options.txt	/*'ts'*
+'tsc'	options.txt	/*'tsc'*
 'tsl'	options.txt	/*'tsl'*
 'tsr'	options.txt	/*'tsr'*
 'tsrfu'	options.txt	/*'tsrfu'*
@@ -1579,7 +1589,6 @@ $quote	eval.txt	/*$quote*
 +vtp	various.txt	/*+vtp*
 +wayland	various.txt	/*+wayland*
 +wayland_clipboard	various.txt	/*+wayland_clipboard*
-+wayland_focus_steal	various.txt	/*+wayland_focus_steal*
 +wildignore	various.txt	/*+wildignore*
 +wildmenu	various.txt	/*+wildmenu*
 +windows	various.txt	/*+windows*
@@ -1605,6 +1614,7 @@ $quote	eval.txt	/*$quote*
 --clean	starting.txt	/*--clean*
 --clientserver	remote.txt	/*--clientserver*
 --cmd	starting.txt	/*--cmd*
+--display	starting.txt	/*--display*
 --echo-wid	starting.txt	/*--echo-wid*
 --gui-dialog-file	starting.txt	/*--gui-dialog-file*
 --help	starting.txt	/*--help*
@@ -4606,12 +4616,9 @@ E1315	vim9class.txt	/*E1315*
 E1316	vim9class.txt	/*E1316*
 E1317	vim9class.txt	/*E1317*
 E1318	vim9class.txt	/*E1318*
-E1319	eval.txt	/*E1319*
 E132	userfunc.txt	/*E132*
 E1320	eval.txt	/*E1320*
-E1321	eval.txt	/*E1321*
 E1322	eval.txt	/*E1322*
-E1323	eval.txt	/*E1323*
 E1324	eval.txt	/*E1324*
 E1325	vim9class.txt	/*E1325*
 E1326	vim9class.txt	/*E1326*
@@ -4688,15 +4695,12 @@ E1391	eval.txt	/*E1391*
 E1392	eval.txt	/*E1392*
 E1393	vim9class.txt	/*E1393*
 E1394	vim9class.txt	/*E1394*
-E1395	vim9class.txt	/*E1395*
+E1395	vim9.txt	/*E1395*
 E1396	vim9class.txt	/*E1396*
 E1397	vim9class.txt	/*E1397*
 E1398	vim9class.txt	/*E1398*
 E1399	vim9class.txt	/*E1399*
 E140	message.txt	/*E140*
-E1400	vim9class.txt	/*E1400*
-E1401	vim9class.txt	/*E1401*
-E1402	vim9class.txt	/*E1402*
 E1403	vim9class.txt	/*E1403*
 E1404	vim9class.txt	/*E1404*
 E1405	vim9class.txt	/*E1405*
@@ -4812,11 +4816,9 @@ E156	sign.txt	/*E156*
 E1560	vim9.txt	/*E1560*
 E1561	vim9.txt	/*E1561*
 E1562	options.txt	/*E1562*
-E1563	remote.txt	/*E1563*
 E1564	remote.txt	/*E1564*
 E1565	remote.txt	/*E1565*
 E1566	remote.txt	/*E1566*
-E1567	remote.txt	/*E1567*
 E1568	options.txt	/*E1568*
 E1569	builtin.txt	/*E1569*
 E157	sign.txt	/*E157*
@@ -4826,6 +4828,9 @@ E1572	options.txt	/*E1572*
 E1573	channel.txt	/*E1573*
 E1574	channel.txt	/*E1574*
 E1575	builtin.txt	/*E1575*
+E1576	tagsrch.txt	/*E1576*
+E1577	options.txt	/*E1577*
+E1578	spell.txt	/*E1578*
 E158	sign.txt	/*E158*
 E159	sign.txt	/*E159*
 E16	cmdline.txt	/*E16*
@@ -5315,7 +5320,6 @@ E610	editing.txt	/*E610*
 E611	eval.txt	/*E611*
 E612	sign.txt	/*E612*
 E613	print.txt	/*E613*
-E614	builtin.txt	/*E614*
 E616	builtin.txt	/*E616*
 E617	options.txt	/*E617*
 E618	print.txt	/*E618*
@@ -6062,6 +6066,8 @@ TextChanged	autocmd.txt	/*TextChanged*
 TextChangedI	autocmd.txt	/*TextChangedI*
 TextChangedP	autocmd.txt	/*TextChangedP*
 TextChangedT	autocmd.txt	/*TextChangedT*
+TextPutPost	autocmd.txt	/*TextPutPost*
+TextPutPre	autocmd.txt	/*TextPutPre*
 TextYankPost	autocmd.txt	/*TextYankPost*
 Transact-SQL	ft_sql.txt	/*Transact-SQL*
 Tuple	eval.txt	/*Tuple*
@@ -6328,6 +6334,8 @@ added-win32-GUI	version5.txt	/*added-win32-GUI*
 aff-dic-format	spell.txt	/*aff-dic-format*
 after-directory	options.txt	/*after-directory*
 aleph	options.txt	/*aleph*
+algol68	syntax.txt	/*algol68*
+algol68_no_preludes	syntax.txt	/*algol68_no_preludes*
 alt	intro.txt	/*alt*
 alt-input	debugger.txt	/*alt-input*
 alt-movement	gui_mac.txt	/*alt-movement*
@@ -7619,6 +7627,7 @@ ft-ada-options	ft_ada.txt	/*ft-ada-options*
 ft-ada-plugin	ft_ada.txt	/*ft-ada-plugin*
 ft-ada-syntax	ft_ada.txt	/*ft-ada-syntax*
 ft-ada-variables	ft_ada.txt	/*ft-ada-variables*
+ft-algol68-syntax	syntax.txt	/*ft-algol68-syntax*
 ft-ant-syntax	syntax.txt	/*ft-ant-syntax*
 ft-apache-syntax	syntax.txt	/*ft-apache-syntax*
 ft-arduino-plugin	filetype.txt	/*ft-arduino-plugin*
@@ -7841,6 +7850,7 @@ ft_hare.txt	ft_hare.txt	/*ft_hare.txt*
 ft_mp.txt	ft_mp.txt	/*ft_mp.txt*
 ft_ps1.txt	ft_ps1.txt	/*ft_ps1.txt*
 ft_raku.txt	ft_raku.txt	/*ft_raku.txt*
+ft_recommended_style	usr_51.txt	/*ft_recommended_style*
 ft_rust.txt	ft_rust.txt	/*ft_rust.txt*
 ft_sql.txt	ft_sql.txt	/*ft_sql.txt*
 ftdetect	filetype.txt	/*ftdetect*
@@ -8072,7 +8082,6 @@ g:netrw_ssh_browse_reject	pi_netrw.txt	/*g:netrw_ssh_browse_reject*
 g:netrw_ssh_cmd	pi_netrw.txt	/*g:netrw_ssh_cmd*
 g:netrw_sshport	pi_netrw.txt	/*g:netrw_sshport*
 g:netrw_timefmt	pi_netrw.txt	/*g:netrw_timefmt*
-g:netrw_tmpfile_escape	pi_netrw.txt	/*g:netrw_tmpfile_escape*
 g:netrw_uid	pi_netrw.txt	/*g:netrw_uid*
 g:netrw_use_noswf	pi_netrw.txt	/*g:netrw_use_noswf*
 g:netrw_use_nt_rcp	pi_netrw.txt	/*g:netrw_use_nt_rcp*
@@ -8356,6 +8365,7 @@ gui-font	gui.txt	/*gui-font*
 gui-fontwide	gui.txt	/*gui-fontwide*
 gui-footer	debugger.txt	/*gui-footer*
 gui-fork	gui_x11.txt	/*gui-fork*
+gui-fullscreen	gui.txt	/*gui-fullscreen*
 gui-functions	usr_41.txt	/*gui-functions*
 gui-gnome	gui_x11.txt	/*gui-gnome*
 gui-gnome-session	gui_x11.txt	/*gui-gnome-session*
@@ -8386,7 +8396,6 @@ gui-vert-scroll	gui.txt	/*gui-vert-scroll*
 gui-w32	gui_w32.txt	/*gui-w32*
 gui-w32-cmdargs	gui_w32.txt	/*gui-w32-cmdargs*
 gui-w32-dialogs	gui_w32.txt	/*gui-w32-dialogs*
-gui-w32-fullscreen	gui_w32.txt	/*gui-w32-fullscreen*
 gui-w32-printing	gui_w32.txt	/*gui-w32-printing*
 gui-w32-start	gui_w32.txt	/*gui-w32-start*
 gui-w32-title-bar	gui_w32.txt	/*gui-w32-title-bar*
@@ -8562,8 +8571,11 @@ hl-PmenuSbar	syntax.txt	/*hl-PmenuSbar*
 hl-PmenuSel	syntax.txt	/*hl-PmenuSel*
 hl-PmenuShadow	syntax.txt	/*hl-PmenuShadow*
 hl-PmenuThumb	syntax.txt	/*hl-PmenuThumb*
+hl-Popup	syntax.txt	/*hl-Popup*
+hl-PopupBorder	syntax.txt	/*hl-PopupBorder*
 hl-PopupNotification	syntax.txt	/*hl-PopupNotification*
 hl-PopupSelected	syntax.txt	/*hl-PopupSelected*
+hl-PopupTitle	syntax.txt	/*hl-PopupTitle*
 hl-PreInsert	syntax.txt	/*hl-PreInsert*
 hl-Question	syntax.txt	/*hl-Question*
 hl-QuickFixLine	syntax.txt	/*hl-QuickFixLine*
@@ -8597,6 +8609,7 @@ hl-User1	syntax.txt	/*hl-User1*
 hl-User1..9	syntax.txt	/*hl-User1..9*
 hl-User9	syntax.txt	/*hl-User9*
 hl-VertSplit	syntax.txt	/*hl-VertSplit*
+hl-VertSplitNC	syntax.txt	/*hl-VertSplitNC*
 hl-Visual	syntax.txt	/*hl-Visual*
 hl-VisualNOS	syntax.txt	/*hl-VisualNOS*
 hl-WarningMsg	syntax.txt	/*hl-WarningMsg*
@@ -9951,6 +9964,7 @@ popt-option	print.txt	/*popt-option*
 popup	popup.txt	/*popup*
 popup-buffer	popup.txt	/*popup-buffer*
 popup-callback	popup.txt	/*popup-callback*
+popup-clipwindow	popup.txt	/*popup-clipwindow*
 popup-close	popup.txt	/*popup-close*
 popup-examples	popup.txt	/*popup-examples*
 popup-filter	popup.txt	/*popup-filter*
@@ -10492,6 +10506,7 @@ shm-q	options.txt	/*shm-q*
 shm-r	options.txt	/*shm-r*
 shm-s	options.txt	/*shm-s*
 shm-t	options.txt	/*shm-t*
+shm-u	options.txt	/*shm-u*
 shm-w	options.txt	/*shm-w*
 shm-x	options.txt	/*shm-x*
 short-name-changed	version4.txt	/*short-name-changed*
@@ -10534,6 +10549,7 @@ slow-fast-terminal	term.txt	/*slow-fast-terminal*
 slow-start	starting.txt	/*slow-start*
 slow-terminal	term.txt	/*slow-terminal*
 socket-interface	channel.txt	/*socket-interface*
+socketserver-address	remote.txt	/*socketserver-address*
 socketserver-clientserver	remote.txt	/*socketserver-clientserver*
 socketserver-differences	remote.txt	/*socketserver-differences*
 socketserver-name	remote.txt	/*socketserver-name*
@@ -10718,7 +10734,9 @@ static-tag	tagsrch.txt	/*static-tag*
 status-line	windows.txt	/*status-line*
 statusmsg-variable	eval.txt	/*statusmsg-variable*
 stl-%!	options.txt	/*stl-%!*
+stl-%0{	options.txt	/*stl-%0{*
 stl-%@	options.txt	/*stl-%@*
+stl-%[FuncName]	options.txt	/*stl-%[FuncName]*
 stl-%{	options.txt	/*stl-%{*
 str2blob()	builtin.txt	/*str2blob()*
 str2float()	builtin.txt	/*str2float()*
@@ -11055,6 +11073,10 @@ tabpagebuflist()	builtin.txt	/*tabpagebuflist()*
 tabpagenr()	builtin.txt	/*tabpagenr()*
 tabpagewinnr()	builtin.txt	/*tabpagewinnr()*
 tabpanel	tabpage.txt	/*tabpanel*
+tabpanel-mouse	tabpage.txt	/*tabpanel-mouse*
+tabpanel-scroll	tabpage.txt	/*tabpanel-scroll*
+tabpanel_getinfo()	builtin.txt	/*tabpanel_getinfo()*
+tabpanel_scroll()	builtin.txt	/*tabpanel_scroll()*
 tag	tagsrch.txt	/*tag*
 tag-!	tagsrch.txt	/*tag-!*
 tag-binary-search	tagsrch.txt	/*tag-binary-search*
@@ -11920,6 +11942,7 @@ viminfo-r	options.txt	/*viminfo-r*
 viminfo-read	starting.txt	/*viminfo-read*
 viminfo-read-write	starting.txt	/*viminfo-read-write*
 viminfo-s	options.txt	/*viminfo-s*
+viminfo-security	starting.txt	/*viminfo-security*
 viminfo-timestamp	starting.txt	/*viminfo-timestamp*
 viminfo-write	starting.txt	/*viminfo-write*
 vimrc	starting.txt	/*vimrc*
@@ -11971,8 +11994,6 @@ waittime	channel.txt	/*waittime*
 warningmsg-variable	eval.txt	/*warningmsg-variable*
 wayland	wayland.txt	/*wayland*
 wayland-and-x11	wayland.txt	/*wayland-and-x11*
-wayland-focus-steal	wayland.txt	/*wayland-focus-steal*
-wayland-gnome	wayland.txt	/*wayland-gnome*
 wayland-gui	wayland.txt	/*wayland-gui*
 wayland-persist	wayland.txt	/*wayland-persist*
 wayland-primary-selection	wayland.txt	/*wayland-primary-selection*
diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt
index eb2cb1b3f9..e381d5fc08 100644
--- a/runtime/doc/tagsrch.txt
+++ b/runtime/doc/tagsrch.txt
@@ -1,4 +1,4 @@
-*tagsrch.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*tagsrch.txt*	For Vim version 9.2.  Last change: 2026 May 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -579,6 +579,10 @@ ctags).
 		have an absolute or relative path.  It may contain environment
 		variables and wildcards (although the use of wildcards is
 		doubtful).  It cannot contain a .
+								*E1576*
+		Using a remote file via network protocol (e.g. using
+		http://remote/file.txt) is not allowed unless 'tagsecure'
+		is unset.
 {tagaddress}	The Ex command that positions the cursor on the tag.  It can
 		be any Ex command, although restrictions apply (see
 		|tag-security|).  Posix only allows line numbers and search
@@ -829,8 +833,9 @@ CTRL-W i		Open a new window, with the cursor on the first line
 			Like `[D`  and `]D`, but search in [range] lines
 			(default: whole file).
 			See |:search-args| for [/] and [!].
-			Note that `:dl` works like `:delete` with the "l"
-			flag, not `:dlist`.
+			Note: In legacy Vim script, `:dl` works like
+			`:delete` with the "l" flag, not `:dlist`, whereas in
+			|Vim9| script `:dl` does work like `:dlist`.
 
 							*[_CTRL-D*
 [ CTRL-D		Jump to the first macro definition that contains the
diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt
index 6c9430dc81..01fd88ca66 100644
--- a/runtime/doc/terminal.txt
+++ b/runtime/doc/terminal.txt
@@ -965,6 +965,20 @@ term_start({cmd} [, {options}])			*term_start()*
 		input and one output handle, with no separate handle for
 		stderr.
 
+		Note: term_start() always uses RAW mode for its callbacks.
+		"out_cb" and "err_cb" receive the raw chunk of data as read
+		from the OS.  A single callback invocation may contain
+		multiple lines separated by NL, and (for stdout via a pty)
+		each line may have a trailing CR from the line discipline
+		(ONLCR).  If per-line handling is desired, the callback must
+		split "msg" on NL and strip the trailing CR itself.
+		Example: >
+			func Handle(ch, msg)
+			  for line in split(a:msg, "\n")
+			    echom substitute(line, '\r$', '', '')
+			  endfor
+			endfunc
+<
 		There are extra options:
 		   "term_name"	     name to use for the buffer name, instead
 				     of the command name.
diff --git a/runtime/doc/textprop.txt b/runtime/doc/textprop.txt
index 9fd5ff6686..ce28677913 100644
--- a/runtime/doc/textprop.txt
+++ b/runtime/doc/textprop.txt
@@ -1,4 +1,4 @@
-*textprop.txt*	For Vim version 9.2.  Last change: 2026 Apr 07
+*textprop.txt*	For Vim version 9.2.  Last change: 2026 May 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -177,7 +177,9 @@ prop_add({lnum}, {col}, {props})
 				When omitted "truncate" is used.
 				Note that this applies to the individual text
 				property, the 'wrap' option sets the overall
-				behavior
+				behavior.  "wrap" only takes effect when the
+				'wrap' option is set; with 'nowrap' the text
+				is truncated at the right edge of the window.
 		All fields except "type" are optional.
 
 		It is an error when both "length" and "end_lnum" or "end_col"
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index beddbea4c2..40a961f328 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*todo.txt*	For Vim version 9.2.  Last change: 2026 Apr 29
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -421,8 +421,6 @@ more information.
 
 Add an option to restrict 'incsearch' to not scroll the view. (Tavis Ormandy)
 
-Remove SPACE_IN_FILENAME ? It is only used for completion.
-
 When 'term' starts with "foot" then default t_TI and t_TE to the values used
 for the builtin xterm termcap.
 
@@ -2115,7 +2113,6 @@ es_ES.utf-8" gives an error and doesn't switch messages. (Dominique Pelle,
 
 When $HOME contains special characters, such as a comma, escape them when used
 in an option. (Michael Hordijk, 2009 May 5)
-Turn "esc" argument of expand_env_esc() into string of chars to be escaped.
 
 Should make 'ignorecase' global-local, so that it makes sense setting it from
 a modeline.
diff --git a/runtime/doc/userfunc.txt b/runtime/doc/userfunc.txt
index 6388d12e18..b0051fb27b 100644
--- a/runtime/doc/userfunc.txt
+++ b/runtime/doc/userfunc.txt
@@ -1,4 +1,4 @@
-*userfunc.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*userfunc.txt*	For Vim version 9.2.  Last change: 2026 May 31
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -27,13 +27,13 @@ make them script-local.  If you do use a global function then avoid obvious,
 short names.  A good habit is to start the function name with the name of the
 script, e.g., "HTMLcolor()".
 
-In legacy script it is also possible to use curly braces, see
+In legacy Vim script it is also possible to use curly braces, see
 |curly-braces-names|.
 
 The |autoload| facility is useful to define a function only when it's called.
 
 							*local-function*
-A function local to a legacy script must start with "s:".  A local script
+A function local to a legacy Vim script must start with "s:".  A local script
 function can only be called from within the script and from functions, user
 commands and autocommands defined in the script.  It is also possible to call
 the function from a mapping defined in the script, but then || must be
@@ -195,9 +195,19 @@ See |:verbose-cmd| for more information.
 			When a function ends without an explicit ":return",
 			the number 0 is returned.
 
-			In a :def function *E1095* is given if unreachable
-			code follows after the `:return`.
-			In legacy script there is no check for unreachable
+			In |Vim9| script:
+			- `:return` cannot be shortened, and
+			- *E1095* is given if unreachable code follows after
+			  the `:return`.  For example:
+>vim9
+			  vim9script
+			  var L: func = (): bool => {
+			    return false
+			    echo 'no'  # E1095: Unreachable code after :return
+			  }
+			  echo L()
+<
+			In legacy Vim script there is no check for unreachable
 			lines, thus there is no warning if commands follow
 			`:return`.  Also, there is no check if the following
 			line contains a valid command.  Forgetting the line
diff --git a/runtime/doc/usr_05.txt b/runtime/doc/usr_05.txt
index 56e7fb9e78..4a3444b61a 100644
--- a/runtime/doc/usr_05.txt
+++ b/runtime/doc/usr_05.txt
@@ -1,4 +1,4 @@
-*usr_05.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*usr_05.txt*	For Vim version 9.2.  Last change: 2026 May 11
 
 
 		     VIM USER MANUAL	by Bram Moolenaar
@@ -509,6 +509,16 @@ To highlight in visual mode, use: >
 To disable the effect of the plugin after it has been loaded: >
 	au! hlyank
 
+Additionally, the plugin can also highlight regions that are put using the
+|TextPutPost| autocommand.  This is by default disabled and can be enabled
+using: >
+	:let g:hlput_enable = v:true
+<
+The following configuration variables can be used are "g:hlput_hlgroup" and
+"g:hlput_duration", which have the same effect as their yank counterparts: >
+	:let g:hlput_hlgroup = 'IncSearch'
+	:let g:hlput_duration = 300
+
 ------------------------------------------------------------------------------
 Adding the osc52 package		*osc52-install* *package-osc52*
 ------------------------------------------------------------------------------
diff --git a/runtime/doc/usr_20.txt b/runtime/doc/usr_20.txt
index 2a28395411..5b23ac89d5 100644
--- a/runtime/doc/usr_20.txt
+++ b/runtime/doc/usr_20.txt
@@ -1,4 +1,4 @@
-*usr_20.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*usr_20.txt*	For Vim version 9.2.  Last change: 2026 Jun 02
 
 
 		     VIM USER MANUAL	by Bram Moolenaar
@@ -116,9 +116,18 @@ command.  It's like deleting the ":" or "/" that the line starts with.
 *20.2*	Command line abbreviations
 
 Some of the ":" commands are really long.  We already mentioned that
-":substitute" can be abbreviated to ":s".  This is a generic mechanism, all
-":" commands can be abbreviated.
+":substitute" can be abbreviated to ":s".  This is a generic mechanism, and
+most ":" commands can be abbreviated.  However, in Vim9 script some commands
+cannot be shortened to improve readability - see |vim9-no-shorten|.
 
+The builtin function |fullcommand()| can be used to return an abbreviated
+command's full name.  For example, the following commands echo "edit", "echo",
+and "echowindow":
+>vim
+	:echo fullcommand('e')
+	:echo fullcommand('ec')
+	:echo fullcommand('echow')
+<
 How short can a command get?  There are 26 letters, and many more commands.
 For example, ":set" also starts with ":s", but ":s" doesn't start a ":set"
 command.  Instead ":set" can be abbreviated to ":se".
diff --git a/runtime/doc/usr_30.txt b/runtime/doc/usr_30.txt
index a541c77d21..cae3749969 100644
--- a/runtime/doc/usr_30.txt
+++ b/runtime/doc/usr_30.txt
@@ -1,4 +1,4 @@
-*usr_30.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*usr_30.txt*	For Vim version 9.2.  Last change: 2026 May 23
 
 
 		     VIM USER MANUAL	by Bram Moolenaar
@@ -531,9 +531,9 @@ they do when using only tab characters.
   Vim 5.4 introduced the 'softtabstop' option.  On top of the (hard) tab stops
 used to display the horizontal tab characters in the text, Vim adds extra
 soft tab stops dedicated only to the cursor.  When 'softtabstop' is set to a
-positive value, and the  key will push the cursor to the next soft tab
-stop.  Vim will insert the correct combination of tab characters and spaces to
-make the effect visually.  Likewise pressing  will have the cursor try to
+positive value, the  key will push the cursor to the next soft tab stop.
+Vim will insert the correct combination of tab characters and spaces to
+achieve this effect.  Likewise pressing  will have the cursor try to
 reach the nearest soft tab stop.  The following example uses
 `:set softtabstop=4`
 
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index f0907c41ff..446e2fd43e 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1,4 +1,4 @@
-*usr_41.txt*	For Vim version 9.2.  Last change: 2026 Feb 16
+*usr_41.txt*	For Vim version 9.2.  Last change: 2026 Apr 28
 
 
 		     VIM USER MANUAL	by Bram Moolenaar
@@ -1081,6 +1081,8 @@ Buffers, windows and the argument list:
 	tabpagebuflist()	return List of buffers in a tab page
 	tabpagenr()		get the number of a tab page
 	tabpagewinnr()		like winnr() for a specified tab page
+	tabpanel_getinfo()	get current state of the tabpanel
+	tabpanel_scroll()	scroll the tabpanel
 	winnr()			get the window number for the current window
 	bufwinid()		get the window ID of a specific buffer
 	bufwinnr()		get the window number of a specific buffer
diff --git a/runtime/doc/usr_51.txt b/runtime/doc/usr_51.txt
index 15ca4f5003..82bb0faf22 100644
--- a/runtime/doc/usr_51.txt
+++ b/runtime/doc/usr_51.txt
@@ -1,4 +1,4 @@
-*usr_51.txt*	For Vim version 9.2.  Last change: 2026 Feb 14
+*usr_51.txt*	For Vim version 9.2.  Last change: 2026 Jun 02
 
 
 		     VIM USER MANUAL	by Bram Moolenaar
@@ -134,9 +134,9 @@ for this mapping, but the user might already use it for something else.  To
 allow the user to define which keys a mapping in a plugin uses, the 
 item can be used: >
 
- 20	  map  a  TypecorrAdd;
+ 20	  map  a  (TypecorrAdd)
 
-The "TypecorrAdd;" thing will do the work, more about that further on.
+The "(TypecorrAdd)" thing will do the work, more about that further on.
 
 The user can set the "g:mapleader" variable to the key sequence that they want
 plugin mappings to start with.  Thus if the user has done: >
@@ -152,15 +152,15 @@ already happened to exist. |:map-|
 But what if the user wants to define their own key sequence?  We can allow
 that with this mechanism: >
 
- 19	if !hasmapto('TypecorrAdd;')
- 20	  map  a  TypecorrAdd;
+ 19	if !hasmapto('(TypecorrAdd)')
+ 20	  map  a  (TypecorrAdd)
  21	endif
 
-This checks if a mapping to "TypecorrAdd;" already exists, and only
+This checks if a mapping to "(TypecorrAdd)" already exists, and only
 defines the mapping from "a" if it doesn't.  The user then has a
 chance of putting this in their vimrc file: >
 
-	map ,c  TypecorrAdd;
+	map ,c  (TypecorrAdd)
 
 Then the mapped key sequence will be ",c" instead of "_a" or "\a".
 
@@ -191,13 +191,13 @@ which is again another function.
  can be used with mappings.  It generates a script ID, which identifies
 the current script.  In our typing correction plugin we use it like this: >
 
- 22	noremap  "
-	  \ ])
+  # insert script closing tag if needed
+  if uses_script
+    extend(lines, [
+      '',
+      settings.use_xhtml ? '//]]>' : '-->',
+      ""
+    ])
   endif
 
-  call extend(s:lines, ["",
-	\ ""])
+  extend(lines, ["",
+    ""])
 endif
 
-if s:settings.no_pre
-  " if we're not using CSS we use a font tag which can't have a div inside
-  if s:settings.use_css
-    call extend(s:lines, ["
"]) +if settings.no_pre + # if we're not using CSS we use a font tag which can't have a div inside + if settings.use_css + extend(lines, ["
"]) endif else - call extend(s:lines, ["
"])
+  extend(lines, ["
"])
 endif
 
-exe s:orgwin .. "wincmd w"
+execute $":{orgwin}wincmd w"
 
-" caches of style data
-" initialize to include line numbers if using them
-if s:settings.number_lines
-  let s:stylelist = { s:LINENR_ID : ".LineNr { " .. s:CSS1( s:LINENR_ID ) .. "}" }
+# caches of style data
+# initialize to include line numbers if using them
+var stylelist: dict
+if settings.number_lines
+  stylelist = { [LINENR_ID]: ".LineNr { " .. CSS1(LINENR_ID) .. "}" }
 else
-  let s:stylelist = {}
+  stylelist = {}
 endif
-let s:diffstylelist = {
-      \   s:DIFF_A_ID : ".DiffAdd { " .. s:CSS1( s:DIFF_A_ID ) .. "}",
-      \   s:DIFF_C_ID : ".DiffChange { " .. s:CSS1( s:DIFF_C_ID ) .. "}",
-      \   s:DIFF_D_ID : ".DiffDelete { " .. s:CSS1( s:DIFF_D_ID ) .. "}",
-      \   s:DIFF_T_ID : ".DiffText { " .. s:CSS1( s:DIFF_T_ID ) .. "}"
-      \ }
+var diffstylelist: dict = {
+  [DIFF_A_ID]: ".DiffAdd { " .. CSS1(DIFF_A_ID) .. "}",
+  [DIFF_C_ID]: ".DiffChange { " .. CSS1(DIFF_C_ID) .. "}",
+  [DIFF_D_ID]: ".DiffDelete { " .. CSS1(DIFF_D_ID) .. "}",
+  [DIFF_T_ID]: ".DiffText { " .. CSS1(DIFF_T_ID) .. "}"
+}
 
-" set up progress bar in the status line
-if !s:settings.no_progress
-  " ProgressBar Indicator
-  let s:progressbar={}
+var last_colors_name: string
+# set up progress bar in the status line
+# ProgressBar Indicator
+# Progressbar specific functions
+def SetProgbarColor()
+  if hlID("TOhtmlProgress") != 0
+    hi! link TOhtmlProgress_auto TOhtmlProgress
+  elseif hlID("TOhtmlProgress_auto") == 0 ||
+      last_colors_name == null_string || !exists("g:colors_name") ||
+      g:colors_name != last_colors_name
+    last_colors_name = exists("g:colors_name") ? g:colors_name : "none"
 
-  " Progressbar specific functions
+    var diffatr = synIDattr(synIDtrans(hlID("DiffDelete")), "reverse", whatterm) == '1' ? "fg#" : "bg#"
+    var stlatr = synIDattr(synIDtrans(hlID("StatusLine")), "reverse", whatterm) == '1' ? "fg#" : "bg#"
 
-  func! s:SetProgbarColor()
-    if hlID("TOhtmlProgress") != 0
-      hi! link TOhtmlProgress_auto TOhtmlProgress
-    elseif hlID("TOhtmlProgress_auto")==0 ||
-       \ !exists("s:last_colors_name") || !exists("g:colors_name") ||
-       \ g:colors_name != s:last_colors_name
-      let s:last_colors_name = exists("g:colors_name") ? g:colors_name : "none"
+    var progbar_color = synIDattr(synIDtrans(hlID("DiffDelete")), diffatr, whatterm)
+    var stl_color = synIDattr(synIDtrans(hlID("StatusLine")), stlatr, whatterm)
 
-      let l:diffatr = synIDattr(hlID("DiffDelete")->synIDtrans(), "reverse", s:whatterm) ? "fg#" : "bg#"
-      let l:stlatr = synIDattr(hlID("StatusLine")->synIDtrans(), "reverse", s:whatterm) ? "fg#" : "bg#"
+    if empty(progbar_color)
+      progbar_color = synIDattr(synIDtrans(hlID("DiffDelete")), "reverse", whatterm) == '1' ? fgc : bgc
+    endif
+    if empty(stl_color)
+      stl_color = synIDattr(synIDtrans(hlID("StatusLine")), "reverse", whatterm) == '1' ? fgc : bgc
+    endif
 
-      let l:progbar_color = synIDattr(hlID("DiffDelete")->synIDtrans(), l:diffatr, s:whatterm)
-      let l:stl_color = synIDattr(hlID("StatusLine")->synIDtrans(), l:stlatr, s:whatterm)
-
-      if "" == l:progbar_color
-	let l:progbar_color = synIDattr(hlID("DiffDelete")->synIDtrans(), "reverse", s:whatterm) ? s:fgc : s:bgc
-      endif
-      if "" == l:stl_color
-	let l:stl_color = synIDattr(hlID("StatusLine")->synIDtrans(), "reverse", s:whatterm) ? s:fgc : s:bgc
-      endif
-
-      if l:progbar_color == l:stl_color
-	if s:whatterm == 'cterm'
-	  if l:progbar_color >= (&t_Co/2)
-	    let l:progbar_color-=1
-	  else
-	    let l:progbar_color+=1
-	  endif
+    if progbar_color == stl_color
+      if whatterm == 'cterm'
+	var nr = str2nr(progbar_color)
+	if nr >= (str2nr(&t_Co) / 2)
+	  nr -= 1
 	else
-	  let l:rgb = map(matchlist(l:progbar_color, '#\zs\x\x\ze\(\x\x\)\(\x\x\)')[:2], 'str2nr(v:val, 16)')
-	  let l:avg = (l:rgb[0] + l:rgb[1] + l:rgb[2])/3
-	  if l:avg >= 128
-	    let l:avg_new = l:avg
-	    while l:avg - l:avg_new < 0x15
-	      let l:rgb = map(l:rgb, 'v:val * 3 / 4')
-	      let l:avg_new = (l:rgb[0] + l:rgb[1] + l:rgb[2])/3
-	    endwhile
-	  else
-	    let l:avg_new = l:avg
-	    while l:avg_new - l:avg < 0x15
-	      let l:rgb = map(l:rgb, 'min([max([v:val, 4]) * 5 / 4, 255])')
-	      let l:avg_new = (l:rgb[0] + l:rgb[1] + l:rgb[2])/3
-	    endwhile
-	  endif
-	  let l:progbar_color = printf("#%02x%02x%02x", l:rgb[0], l:rgb[1], l:rgb[2])
+	  nr += 1
 	endif
-	echomsg "diff detected progbar color set to" l:progbar_color
+	progbar_color = string(nr)
+      else
+	var rgb = map(matchlist(progbar_color, '#\zs\x\x\ze\(\x\x\)\(\x\x\)')[: 2], (_, v) => str2nr(v, 16))
+	var avg = (rgb[0] + rgb[1] + rgb[2]) / 3
+	if avg >= 128
+	  var avg_new = avg
+	  while avg - avg_new < 0x15
+	    rgb = map(rgb, (_, v) => v * 3 / 4)
+	    avg_new = (rgb[0] + rgb[1] + rgb[2]) / 3
+	  endwhile
+	else
+	  var avg_new = avg
+	  while avg_new - avg < 0x15
+	    rgb = map(rgb, (_, v) => min([max([v, 4]) * 5 / 4, 255]))
+	    avg_new = (rgb[0] + rgb[1] + rgb[2]) / 3
+	  endwhile
+	endif
+	progbar_color = printf("#%02x%02x%02x", rgb[0], rgb[1], rgb[2])
       endif
-      exe "hi TOhtmlProgress_auto" s:whatterm.."bg="..l:progbar_color
+      echomsg "diff detected progbar color set to" progbar_color
     endif
-  endfun
+    execute "hi TOhtmlProgress_auto" whatterm .. "bg=" .. progbar_color
+  endif
+enddef
 
-  func! s:ProgressBar(title, max_value, winnr)
-    let pgb=copy(s:progressbar)
-    let pgb.title = a:title..' '
-    let pgb.max_value = a:max_value
-    let pgb.winnr = a:winnr
-    let pgb.cur_value = 0
+class ProgressBar #{{{
+  public var title: string
+  public var max_value: number
+  public var winnr: number
+  public var cur_value: number = 0
+  public var items: dict
+  public var last_value: number = 0
+  public var needs_redraw: number = 0
+  public var pb_len: number = 0
+  public var max_len: number = 0
+  public var progress_ticks: list = []
+  var subtractedlen: number
 
-    let pgb.items = { 'title'   : { 'color' : 'Statusline' },
-	  \'bar'     : { 'color' : 'Statusline' , 'fillcolor' : 'TOhtmlProgress_auto' , 'bg' : 'Statusline' } ,
-	  \'counter' : { 'color' : 'Statusline' } }
-    let pgb.last_value = 0
-    let pgb.needs_redraw = 0
-    " Note that you must use len(split) instead of len() if you want to use 
-    " unicode in title.
-    "
-    " Subtract 3 for spacing around the title.
-    " Subtract 4 for the percentage display.
-    " Subtract 2 for spacing before this.
-    " Subtract 2 more for the '|' on either side of the progress bar
-    let pgb.subtractedlen=len(split(pgb.title, '\zs'))+3+4+2+2
-    let pgb.max_len = 0
+  def new(title: string, max_value: number, winnr: number)
+    this.title = title .. ' '
+    this.max_value = max_value
+    this.winnr = winnr
+
+    this.items = {
+      'title': { 'color': 'Statusline' },
+      'bar': { 'color': 'Statusline', 'fillcolor': 'TOhtmlProgress_auto', 'bg': 'Statusline' },
+      'counter': { 'color': 'Statusline' }
+    }
+    # Note that you must use len(split) instead of len() if you want to use
+    # unicode in title.
+    #
+    # Subtract 3 for spacing around the title.
+    # Subtract 4 for the percentage display.
+    # Subtract 2 for spacing before this.
+    # Subtract 2 more for the '|' on either side of the progress bar
+    this.subtractedlen = len(split(this.title, '\zs')) + 3 + 4 + 2 + 2
     set laststatus=2
-    return pgb
-  endfun
+  enddef
 
-  " Function: progressbar.calculate_ticks() {{{1
-  func! s:progressbar.calculate_ticks(pb_len)
-    if a:pb_len<=0
-      let pb_len = 100
+  def Paint()
+    # Recalculate widths.
+    var max_len = winwidth(this.winnr)
+    var pb_len = 0
+    var cur_value: number
+
+    def CalculateTicks(len: number)
+      if len <= 0
+	pb_len = 100
+      else
+	pb_len = len
+      endif
+      this.progress_ticks = range(pb_len + 1)->map((_, v) => v * this.max_value / pb_len)
+    enddef
+
+    # always true on first call because of initial value of this.max_len
+    if max_len != this.max_len
+      this.max_len = max_len
+
+      # Progressbar length
+      pb_len = max_len - this.subtractedlen
+
+      CalculateTicks(pb_len)
+
+      this.needs_redraw = 1
+      cur_value = 0
+      this.pb_len = pb_len
     else
-      let pb_len = a:pb_len
-    endif
-    let self.progress_ticks = map(range(pb_len+1), "v:val * self.max_value / pb_len")
-  endfun
-
-  "Function: progressbar.paint()
-  func! s:progressbar.paint()
-    " Recalculate widths.
-    let max_len = winwidth(self.winnr)
-    let pb_len = 0
-    " always true on first call because of initial value of self.max_len
-    if max_len != self.max_len
-      let self.max_len = max_len
-
-      " Progressbar length
-      let pb_len = max_len - self.subtractedlen
-
-      call self.calculate_ticks(pb_len)
-
-      let self.needs_redraw = 1
-      let cur_value = 0
-      let self.pb_len = pb_len
-    else
-      " start searching at the last found index to make the search for the
-      " appropriate tick value normally take 0 or 1 comparisons
-      let cur_value = self.last_value
-      let pb_len = self.pb_len
+      # start searching at the last found index to make the search for the
+      # appropriate tick value normally take 0 or 1 comparisons
+      cur_value = this.last_value
+      pb_len = this.pb_len
     endif
 
-    let cur_val_max = pb_len > 0 ? pb_len : 100
+    var cur_val_max = pb_len > 0 ? pb_len : 100
 
-    " find the current progress bar position based on precalculated thresholds
-    while cur_value < cur_val_max && self.cur_value > self.progress_ticks[cur_value]
-      let cur_value += 1
+    # find the current progress bar position based on precalculated thresholds
+    while cur_value < cur_val_max && this.cur_value > this.progress_ticks[cur_value]
+      cur_value += 1
     endwhile
 
-    " update progress bar
-    if self.last_value != cur_value || self.needs_redraw || self.cur_value == self.max_value
-      let self.needs_redraw = 1
-      let self.last_value = cur_value
+    # update progress bar
+    if this.last_value != cur_value || this.needs_redraw || this.cur_value == this.max_value
+      this.needs_redraw = 1
+      this.last_value = cur_value
 
-      let t_color  = self.items.title.color
-      let b_fcolor = self.items.bar.fillcolor
-      let b_color  = self.items.bar.color
-      let c_color  = self.items.counter.color
+      var t_color  = this.items.title.color
+      var b_fcolor = this.items.bar.fillcolor
+      var b_color  = this.items.bar.color
+      var c_color  = this.items.counter.color
 
-      let stl =  "%#".t_color."#%-( ".self.title." %)".
-	    \"%#".b_color."#".
-	    \(pb_len>0 ?
-	    \	('|%#'.b_fcolor."#%-(".repeat(" ",cur_value)."%)".
-	    \	 '%#'.b_color."#".repeat(" ",pb_len-cur_value)."|"):
-	    \	('')).
-	    \"%=%#".c_color."#%( ".printf("%3.d ",100*self.cur_value/self.max_value)."%% %)"
-      call setwinvar(self.winnr, '&stl', stl)
+      var stl =  $"%#{t_color}#%-( {this.title} %)%#{b_color}#" ..
+	(pb_len > 0 ? $'|%#{b_fcolor}#%-({repeat(" ", cur_value)}%)%#{b_color}#{repeat(" ", pb_len - cur_value)}|' : (''))
+	.. $"%=%#{c_color}#%( {printf("%3.d ", 100 * this.cur_value / this.max_value)}%% %)"
+      setwinvar(this.winnr, '&stl', stl)
     endif
-  endfun
+  enddef
 
-  func! s:progressbar.incr( ... )
-    let self.cur_value += (a:0 ? a:1 : 1)
-    " if we were making a general-purpose progress bar, we'd need to limit to a
-    " lower limit as well, but since we always increment with a positive value
-    " in this script, we only need limit the upper value
-    let self.cur_value = (self.cur_value > self.max_value ? self.max_value : self.cur_value)
-    call self.paint()
-  endfun
-  " }}}
-  if s:settings.dynamic_folds
-    " to process folds we make two passes through each line
-    let s:pgb = s:ProgressBar("Processing folds:", line('$')*2, s:orgwin)
+  def Incr(delta: number = 1)
+    this.cur_value += delta
+    # if we were making a general-purpose progress bar, we'd need to limit to a
+    # lower limit as well, but since we always increment with a positive value
+    # in this script, we only need limit the upper value
+    this.cur_value = (this.cur_value > this.max_value ? this.max_value : this.cur_value)
+    this.Paint()
+  enddef
+endclass #}}}
+
+var pgb: ProgressBar
+if !settings.no_progress
+  if settings.dynamic_folds
+    # to process folds we make two passes through each line
+    pgb = ProgressBar.new("Processing folds:", line('$') * 2, orgwin)
   endif
 
-  call s:SetProgbarColor()
+  SetProgbarColor()
 endif
 
-let s:build_fun_lines = []
-call add(s:build_fun_lines, [])
-let s:build_fun_lines[-1] =<< trim ENDLET
-    func! s:Add_diff_fill(lnum)
-      let l:filler = diff_filler(a:lnum)
-      if l:filler > 0
-	let l:to_insert = l:filler
-	while l:to_insert > 0
-	  let l:new = repeat(s:difffillchar, 3)
+var build_fun_lines: list
+build_fun_lines =<< trim ENDLET
+  def Add_diff_fill(_lnum: number)
+    var filler = diff_filler(_lnum)
+    if filler > 0
+      var to_insert = filler
+      while to_insert > 0
+	var new = repeat(difffillchar, 3)
 
-	  if l:to_insert > 2 && l:to_insert < l:filler && !s:settings.whole_filler
-	    let l:new = l:new .. " " .. l:filler .. " inserted lines "
-	    let l:to_insert = 2
-	  endif
+	if to_insert > 2 && to_insert < filler && !settings.whole_filler
+	  new = new .. " " .. filler .. " inserted lines "
+	  to_insert = 2
+	endif
 ENDLET
-call add(s:build_fun_lines, [])
-if !s:settings.no_pre
-  let s:build_fun_lines[-1] =<< trim ENDLET
-	  " HTML line wrapping is off--go ahead and fill to the margin
-	  " TODO: what about when CSS wrapping is turned on?
-	  let l:new = l:new .. repeat(s:difffillchar, &columns - strlen(l:new) - s:margin)
+if !settings.no_pre
+  trim_tmp =<< trim ENDLET
+	# HTML line wrapping is off--go ahead and fill to the margin
+	# TODO: what about when CSS wrapping is turned on?
+	new = new .. repeat(difffillchar, &columns - strlen(new) - margin)
   ENDLET
+  build_fun_lines += trim_tmp
 else
-  let s:build_fun_lines[-1] =<< trim ENDLET
-	  let l:new = l:new .. repeat(s:difffillchar, 3)
+  trim_tmp =<< trim ENDLET
+	new = new .. repeat(difffillchar, 3)
   ENDLET
+  build_fun_lines += trim_tmp
 endif
-call add(s:build_fun_lines, [])
-let s:build_fun_lines[-1] =<< trim ENDLET
-	let l:new = s:HtmlFormat_d(l:new, s:DIFF_D_ID, 0)
+trim_tmp =<< trim ENDLET
+	new = HtmlFormat_d(new, DIFF_D_ID, 0)
 ENDLET
-if s:settings.number_lines
-  call add(s:build_fun_lines, [])
-  let s:build_fun_lines[-1] =<< trim ENDLET
-	  " Indent if line numbering is on. Indent gets style of line number
-	  " column.
-	  let l:new = s:HtmlFormat_n(repeat(' ', s:margin), s:LINENR_ID, 0, 0) .. l:new
+build_fun_lines += trim_tmp
+if settings.number_lines
+  trim_tmp =<< trim ENDLET
+	# Indent if line numbering is on. Indent gets style of line number
+	# column.
+	new = HtmlFormat_n(repeat(' ', margin), LINENR_ID, 0, 0) .. new
   ENDLET
+  build_fun_lines += trim_tmp
 endif
-if s:settings.dynamic_folds && !s:settings.no_foldcolumn 
-  call add(s:build_fun_lines, [])
-  let s:build_fun_lines[-1] =<< trim ENDLET
-	  if s:foldcolumn > 0
-	    " Indent for foldcolumn if there is one. Assume it's empty, there should
-	    " not be a fold for deleted lines in diff mode.
-	    let l:new = s:FoldColumn_fill() .. l:new
-	  endif
+if settings.dynamic_folds && !settings.no_foldcolumn
+  trim_tmp =<< trim ENDLET
+	if foldcolumn > 0
+	  # Indent for foldcolumn if there is one. Assume it's empty, there should
+	  # not be a fold for deleted lines in diff mode.
+	  new = FoldColumn_fill() .. new
+	endif
   ENDLET
+  build_fun_lines += trim_tmp
 endif
-" Ignore this comment, just bypassing a highlighting issue: if
-call add(s:build_fun_lines, [])
-let s:build_fun_lines[-1] =<< trim ENDLET
-	call add(s:lines, l:new..s:HtmlEndline)
-	let l:to_insert = l:to_insert - 1
+# Ignore this comment, just bypassing a highlighting issue: if
+trim_tmp =<< trim ENDLET
+	add(lines, new .. HtmlEndline)
+	to_insert -= 1
       endwhile
     endif
-  endfun
+  enddef
 ENDLET
-exec join(flatten(s:build_fun_lines), "\n")
+build_fun_lines += trim_tmp
+execute join(build_fun_lines, "\n")
 
-" First do some preprocessing for dynamic folding. Do this for the entire file
-" so we don't accidentally start within a closed fold or something.
-let s:allfolds = []
+# First do some preprocessing for dynamic folding. Do this for the entire file
+# so we don't accidentally start within a closed fold or something.
+var allfolds: list = []
 
-if s:settings.dynamic_folds
-  let s:lnum = 1
-  let s:end = line('$')
-  " save the fold text and set it to the default so we can find fold levels
-  let s:foldtext_save = &foldtext
-  setlocal foldtext&
+var foldcolumn: number
+if settings.dynamic_folds
+  def ProcessFolds()
+    lnum = 1
+    end = line('$')
+    # save the fold text and set it to the default so we can find fold levels
+    var foldtext_save = &foldtext
+    setlocal foldtext&
 
-  " we will set the foldcolumn in the html to the greater of the maximum fold
-  " level and the current foldcolumn setting
-  let s:foldcolumn = &foldcolumn
+    # we will set the foldcolumn in the html to the greater of the maximum fold
+    # level and the current foldcolumn setting
+    foldcolumn = &foldcolumn
 
-  " get all info needed to describe currently closed folds
-  while s:lnum <= s:end
-    if foldclosed(s:lnum) == s:lnum
-      " default fold text has '+-' and then a number of dashes equal to fold
-      " level, so subtract 2 from index of first non-dash after the dashes
-      " in order to get the fold level of the current fold
-      let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2
-      " store fold info for later use
-      let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"}
-      call add(s:allfolds, s:newfold)
-      " open the fold so we can find any contained folds
-      execute s:lnum.."foldopen"
-    else
-      if !s:settings.no_progress
-	call s:pgb.incr()
-	if s:pgb.needs_redraw
-	  redrawstatus
-	  let s:pgb.needs_redraw = 0
-	endif
-      endif
-      let s:lnum = s:lnum + 1
-    endif
-  endwhile
-
-  " close all folds to get info for originally open folds
-  silent! %foldclose!
-  let s:lnum = 1
-
-  " the originally open folds will be all folds we encounter that aren't
-  " already in the list of closed folds
-  while s:lnum <= s:end
-    if foldclosed(s:lnum) == s:lnum
-      " default fold text has '+-' and then a number of dashes equal to fold
-      " level, so subtract 2 from index of first non-dash after the dashes
-      " in order to get the fold level of the current fold
-      let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2
-      let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"}
-      " only add the fold if we don't already have it
-      if empty(s:allfolds) || index(s:allfolds, s:newfold) == -1
-	let s:newfold.type = "open-fold"
-	call add(s:allfolds, s:newfold)
-      endif
-      " open the fold so we can find any contained folds
-      execute s:lnum.."foldopen"
-    else
-      if !s:settings.no_progress
-	call s:pgb.incr()
-	if s:pgb.needs_redraw
-	  redrawstatus
-	  let s:pgb.needs_redraw = 0
-	endif
-      endif
-      let s:lnum = s:lnum + 1
-    endif
-  endwhile
-
-  " sort the folds so that we only ever need to look at the first item in the
-  " list of folds
-  call sort(s:allfolds, "s:FoldCompare")
-
-  let &l:foldtext = s:foldtext_save
-  unlet s:foldtext_save
-
-  " close all folds again so we can get the fold text as we go
-  silent! %foldclose!
-
-  " Go through and remove folds we don't need to (or cannot) process in the
-  " current conversion range
-  "
-  " If a fold is removed which contains other folds, which are included, we need
-  " to adjust the level of the included folds as used by the conversion logic
-  " (avoiding special cases is good)
-  "
-  " Note any time we remove a fold, either all of the included folds are in it,
-  " or none of them, because we only remove a fold if neither its start nor its
-  " end are within the conversion range.
-  let leveladjust = 0
-  for afold in s:allfolds
-    let removed = 0
-    if exists("g:html_start_line") && exists("g:html_end_line")
-      if afold.firstline < g:html_start_line
-	if afold.lastline <= g:html_end_line && afold.lastline >= g:html_start_line
-	  " if a fold starts before the range to convert but stops within the
-	  " range, we need to include it. Make it start on the first converted
-	  " line.
-	  let afold.firstline = g:html_start_line
-	else
-	  " if the fold lies outside the range or the start and stop enclose
-	  " the entire range, don't bother parsing it
-	  call remove(s:allfolds, index(s:allfolds, afold))
-	  let removed = 1
-	  if afold.lastline > g:html_end_line
-	    let leveladjust += 1
+    # get all info needed to describe currently closed folds
+    while lnum <= end
+      if foldclosed(lnum) == lnum
+	# default fold text has '+-' and then a number of dashes equal to fold
+	# level, so subtract 2 from index of first non-dash after the dashes
+	# in order to get the fold level of the current fold
+	var level = match(foldtextresult(lnum), '+-*\zs[^-]') - 2
+	# store fold info for later use
+	var newfold = {firstline: lnum, lastline: foldclosedend(lnum), level: level, type: "closed-fold"}
+	add(allfolds, newfold)
+	# open the fold so we can find any contained folds
+	execute $":{lnum}foldopen"
+      else
+	if !settings.no_progress
+	  pgb.Incr()
+	  if pgb.needs_redraw
+	    redrawstatus
+	    pgb.needs_redraw = 0
 	  endif
 	endif
-      elseif afold.firstline > g:html_end_line
-	" If the entire fold lies outside the range we need to remove it.
-	call remove(s:allfolds, index(s:allfolds, afold))
-	let removed = 1
+	lnum = lnum + 1
       endif
-    elseif exists("g:html_start_line")
-      if afold.firstline < g:html_start_line
-	" if there is no last line, but there is a first line, the end of the
-	" fold will always lie within the region of interest, so keep it
-	let afold.firstline = g:html_start_line
-      endif
-    elseif exists("g:html_end_line")
-      " if there is no first line we default to the first line in the buffer so
-      " the fold start will always be included if the fold itself is included.
-      " If however the entire fold lies outside the range we need to remove it.
-      if afold.firstline > g:html_end_line
-	call remove(s:allfolds, index(s:allfolds, afold))
-	let removed = 1
-      endif
-    endif
-    if !removed
-      let afold.level -= leveladjust
-      if afold.level+1 > s:foldcolumn
-	let s:foldcolumn = afold.level+1
-      endif
-    endif
-  endfor
+    endwhile
 
-  " if we've removed folds containing the conversion range from processing,
-  " getting foldtext as we go won't know to open the removed folds, so the
-  " foldtext would be wrong; open them now.
-  "
-  " Note that only when a start and an end line is specified will a fold
-  " containing the current range ever be removed.
-  while leveladjust > 0
-    exe g:html_start_line.."foldopen"
-    let leveladjust -= 1
-  endwhile
+    # close all folds to get info for originally open folds
+    silent! :%foldclose!
+    lnum = 1
+
+    # the originally open folds will be all folds we encounter that aren't
+    # already in the list of closed folds
+    while lnum <= end
+      if foldclosed(lnum) == lnum
+	# default fold text has '+-' and then a number of dashes equal to fold
+	# level, so subtract 2 from index of first non-dash after the dashes
+	# in order to get the fold level of the current fold
+	var level = match(foldtextresult(lnum), '+-*\zs[^-]') - 2
+	var newfold = {firstline: lnum, lastline: foldclosedend(lnum), level: level, type: "closed-fold"}
+	# only add the fold if we don't already have it
+	if empty(allfolds) || index(allfolds, newfold) == -1
+	  newfold.type = "open-fold"
+	  add(allfolds, newfold)
+	endif
+	# open the fold so we can find any contained folds
+	execute $":{lnum}foldopen"
+      else
+	if !settings.no_progress
+	  pgb.Incr()
+	  if pgb.needs_redraw
+	    redrawstatus
+	    pgb.needs_redraw = 0
+	  endif
+	endif
+	lnum = lnum + 1
+      endif
+    endwhile
+
+    # sort the folds so that we only ever need to look at the first item in the
+    # list of folds
+    sort(allfolds, FoldCompare)
+
+    &l:foldtext = foldtext_save
+
+    # close all folds again so we can get the fold text as we go
+    silent! :%foldclose!
+
+    # Go through and remove folds we don't need to (or cannot) process in the
+    # current conversion range
+    #
+    # If a fold is removed which contains other folds, which are included, we need
+    # to adjust the level of the included folds as used by the conversion logic
+    # (avoiding special cases is good)
+    #
+    # Note any time we remove a fold, either all of the included folds are in it,
+    # or none of them, because we only remove a fold if neither its start nor its
+    # end are within the conversion range.
+    var leveladjust = 0
+    for afold in allfolds
+      var removed = 0
+      if exists("g:html_start_line") && exists("g:html_end_line")
+	if afold.firstline < g:html_start_line
+	  if afold.lastline <= g:html_end_line && afold.lastline >= g:html_start_line
+	    # if a fold starts before the range to convert but stops within the
+	    # range, we need to include it. Make it start on the first converted
+	    # line.
+	    afold.firstline = g:html_start_line
+	  else
+	    # if the fold lies outside the range or the start and stop enclose
+	    # the entire range, don't bother parsing it
+	    remove(allfolds, index(allfolds, afold))
+	    removed = 1
+	    if afold.lastline > g:html_end_line
+	      leveladjust += 1
+	    endif
+	  endif
+	elseif afold.firstline > g:html_end_line
+	  # If the entire fold lies outside the range we need to remove it.
+	  remove(allfolds, index(allfolds, afold))
+	  removed = 1
+	endif
+      elseif exists("g:html_start_line")
+	if afold.firstline < g:html_start_line
+	  # if there is no last line, but there is a first line, the end of the
+	  # fold will always lie within the region of interest, so keep it
+	  afold.firstline = g:html_start_line
+	endif
+      elseif exists("g:html_end_line")
+	# if there is no first line we default to the first line in the buffer so
+	# the fold start will always be included if the fold itself is included.
+	# If however the entire fold lies outside the range we need to remove it.
+	if afold.firstline > g:html_end_line
+	  remove(allfolds, index(allfolds, afold))
+	  removed = 1
+	endif
+      endif
+      if !removed
+	afold.level -= leveladjust
+	if afold.level + 1 > foldcolumn
+	  foldcolumn = afold.level + 1
+	endif
+      endif
+    endfor
+
+    # if we've removed folds containing the conversion range from processing,
+    # getting foldtext as we go won't know to open the removed folds, so the
+    # foldtext would be wrong; open them now.
+    #
+    # Note that only when a start and an end line is specified will a fold
+    # containing the current range ever be removed.
+    while leveladjust > 0
+      execute $":{g:html_start_line}foldopen"
+      leveladjust -= 1
+    endwhile
+  enddef
+  ProcessFolds()
 endif
 
-" Now loop over all lines in the original text to convert to html.
-" Use html_start_line and html_end_line if they are set.
+# Now loop over all lines in the original text to convert to html.
+# Use html_start_line and html_end_line if they are set.
 if exists("g:html_start_line")
-  let s:lnum = html_start_line
-  if s:lnum < 1 || s:lnum > line("$")
-    let s:lnum = 1
+  lnum = g:html_start_line
+  if lnum < 1 || lnum > line("$")
+    lnum = 1
   endif
 else
-  let s:lnum = 1
+  lnum = 1
 endif
 if exists("g:html_end_line")
-  let s:end = html_end_line
-  if s:end < s:lnum || s:end > line("$")
-    let s:end = line("$")
+  end = g:html_end_line
+  if end < lnum || end > line("$")
+    end = line("$")
   endif
 else
-  let s:end = line("$")
+  end = line("$")
 endif
 
-" stack to keep track of all the folds containing the current line
-let s:foldstack = []
+# stack to keep track of all the folds containing the current line
+var foldstack: list = []
 
-if !s:settings.no_progress
-  let s:pgb = s:ProgressBar("Processing lines:", s:end - s:lnum + 1, s:orgwin)
+if !settings.no_progress
+  pgb = ProgressBar.new("Processing lines:", end - lnum + 1, orgwin)
 endif
 
-if s:settings.number_lines
-  let s:margin = strlen(s:end) + 1
+var margin: number
+if settings.number_lines
+  margin = strlen(end) + 1
 else
-  let s:margin = 0
+  margin = 0
 endif
 
-if has('folding') && !s:settings.ignore_folding
-  let s:foldfillchar = &fillchars[matchend(&fillchars, 'fold:')]
-  if s:foldfillchar == ''
-    let s:foldfillchar = '-'
+var foldfillchar: string
+var charidx: number
+if has('folding') && !settings.ignore_folding
+  charidx = matchend(&fillchars, 'fold:')
+  if charidx >= 0
+    foldfillchar = &fillchars[charidx(&fillchars, charidx)]
+  endif
+  if foldfillchar->empty()
+    foldfillchar = '-'
   endif
 endif
-let s:difffillchar = &fillchars[matchend(&fillchars, 'diff:')]
-if s:difffillchar == ''
-  let s:difffillchar = '-'
+var difffillchar: string
+charidx = matchend(&fillchars, 'diff:')
+if charidx >= 0
+  difffillchar = &fillchars[charidx(&fillchars, charidx)]
+endif
+if difffillchar->empty()
+  difffillchar = '-'
 endif
 
-let s:foldId = 0
-
-if !s:settings.expand_tabs
-  " If keeping tabs, add them to printable characters so we keep them when
-  " formatting text (strtrans() doesn't replace printable chars)
-  let s:old_isprint = &isprint
+var foldId = 0
+var old_isprint: string
+if !settings.expand_tabs
+  # If keeping tabs, add them to printable characters so we keep them when
+  # formatting text (strtrans() doesn't replace printable chars)
+  old_isprint = &isprint
   setlocal isprint+=9
 endif
 
-while s:lnum <= s:end
+def ProcessLines()
+  var all_lines = getline(lnum, end)
+  var start_lnum = lnum
 
-  " If there are filler lines for diff mode, show these above the line.
-  call s:Add_diff_fill(s:lnum)
+  while lnum <= end
 
-  " Start the line with the line number.
-  if s:settings.number_lines
-    let s:numcol = repeat(' ', s:margin - 1 - strlen(s:lnum)) .. s:lnum .. ' '
-  endif
+    # If there are filler lines for diff mode, show these above the line.
+    Add_diff_fill(lnum)
 
-  let s:new = ""
-
-  if has('folding') && !s:settings.ignore_folding && foldclosed(s:lnum) > -1 && !s:settings.dynamic_folds
-    "
-    " This is the beginning of a folded block (with no dynamic folding)
-    let s:new = foldtextresult(s:lnum)
-    if !s:settings.no_pre
-      " HTML line wrapping is off--go ahead and fill to the margin
-      let s:new = s:new .. repeat(s:foldfillchar, &columns - strlen(s:new))
+    # Start the line with the line number.
+    var numcol: string
+    if settings.number_lines
+      numcol = repeat(' ', margin - 1 - strlen(lnum)) .. lnum .. ' '
     endif
 
-    " put numcol in a separate group for sake of unselectable text
-    let s:new = (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0, s:lnum): "") .. s:HtmlFormat_t(s:new, s:FOLDED_ID, 0)
+    var new: string
 
-    " Skip to the end of the fold
-    let s:new_lnum = foldclosedend(s:lnum)
+    if has('folding') && !settings.ignore_folding && foldclosed(lnum) > -1 && !settings.dynamic_folds
+      #
+      # This is the beginning of a folded block (with no dynamic folding)
+      new = foldtextresult(lnum)
+      if !settings.no_pre
+	# HTML line wrapping is off--go ahead and fill to the margin
+	new ..= repeat(foldfillchar, &columns - strlen(new))
+      endif
 
-    if !s:settings.no_progress
-      call s:pgb.incr(s:new_lnum - s:lnum)
-    endif
+      # put numcol in a separate group for sake of unselectable text
+      new = (settings.number_lines ? HtmlFormat_n(numcol, FOLDED_ID, 0, lnum) : "") .. HtmlFormat_t(new, FOLDED_ID, 0)
 
-    let s:lnum = s:new_lnum
+      # Skip to the end of the fold
+      var new_lnum = foldclosedend(lnum)
 
-  else
-    "
-    " A line that is not folded, or doing dynamic folding.
-    "
-    let s:line = getline(s:lnum)
-    let s:len = strlen(s:line)
+      if !settings.no_progress
+	pgb.Incr(new_lnum - lnum)
+      endif
 
-    if s:settings.dynamic_folds
-      " First insert a closing for any open folds that end on this line
-      while !empty(s:foldstack) && get(s:foldstack,0).lastline == s:lnum-1
-	let s:new = s:new..""
-	call remove(s:foldstack, 0)
-      endwhile
+      lnum = new_lnum
 
-      " Now insert an opening for any new folds that start on this line
-      let s:firstfold = 1
-      while !empty(s:allfolds) && get(s:allfolds,0).firstline == s:lnum
-	let s:foldId = s:foldId + 1
-	let s:new ..= ""
+    else
+      #
+      # A line that is not folded, or doing dynamic folding.
+      #
+      var line = all_lines[lnum - start_lnum]
+      var len = strlen(line)
+
+      if settings.dynamic_folds
+	# First insert a closing for any open folds that end on this line
+	while !empty(foldstack) && get(foldstack, 0).lastline == lnum - 1
+	  new ..= ""
+	  remove(foldstack, 0)
+	endwhile
+
+	# Now insert an opening for any new folds that start on this line
+	var firstfold = 1
+	while !empty(allfolds) && get(allfolds, 0).firstline == lnum
+	  foldId = foldId + 1
+	  new ..= ""
 
 
-	" Unless disabled, add a fold column for the opening line of a fold.
-	"
-	" Note that dynamic folds require using css so we just use css to take
-	" care of the leading spaces rather than using   in the case of
-	" html_no_pre to make it easier
-	if !s:settings.no_foldcolumn
-	  " add fold column that can open the new fold
-	  if s:allfolds[0].level > 1 && s:firstfold
-	    let s:new = s:new .. s:FoldColumn_build('|', s:allfolds[0].level - 1, 0, "",
-		  \ 'toggle-open FoldColumn','javascript:toggleFold("fold'..s:foldstack[0].id..s:settings.id_suffix..'");')
+	  # Unless disabled, add a fold column for the opening line of a fold.
+	  #
+	  # Note that dynamic folds require using css so we just use css to take
+	  # care of the leading spaces rather than using   in the case of
+	  # html_no_pre to make it easier
+	  if !settings.no_foldcolumn
+	    # add fold column that can open the new fold
+	    if allfolds[0].level > 1 && firstfold
+	      new ..= FoldColumn_build('|', allfolds[0].level - 1, 0, "",
+		'toggle-open FoldColumn', 'javascript:toggleFold("fold' .. foldstack[0].id .. settings.id_suffix .. '");')
+	    endif
+	    # add the filler spaces separately from the '+' char so that it can be
+	    # shown/hidden separately during a hover unfold
+	    new ..= FoldColumn_build("+", 1, 0, "",
+	      'toggle-open FoldColumn', 'javascript:toggleFold("fold' .. foldId .. settings.id_suffix .. '");')
+	    # If this is not the last fold we're opening on this line, we need
+	    # to keep the filler spaces hidden if the fold is opened by mouse
+	    # hover. If it is the last fold to open in the line, we shouldn't hide
+	    # them, so don't apply the toggle-filler class.
+	    new ..= FoldColumn_build(" ", 1, foldcolumn - allfolds[0].level - 1, "",
+	      'toggle-open FoldColumn' .. (get(allfolds, 1, {firstline: 0}).firstline == lnum ? " toggle-filler" : ""),
+	      'javascript:toggleFold("fold' .. foldId .. settings.id_suffix .. '");')
+
+	    # add fold column that can close the new fold
+	    # only add extra blank space if we aren't opening another fold on the
+	    # same line
+	    var extra_space: number
+	    if get(allfolds, 1, {firstline: 0}).firstline != lnum
+	      extra_space = foldcolumn - allfolds[0].level
+	    else
+	      extra_space = 0
+	    endif
+	    if firstfold
+	      # the first fold in a line has '|' characters from folds opened in
+	      # previous lines, before the '-' for this fold
+	      new ..= FoldColumn_build('|', allfolds[0].level - 1, extra_space, '-',
+		'toggle-closed FoldColumn', 'javascript:toggleFold("fold' .. foldId .. settings.id_suffix .. '");')
+	    else
+	      # any subsequent folds in the line only add a single '-'
+	      new ..= FoldColumn_build("-", 1, extra_space, "",
+		'toggle-closed FoldColumn', 'javascript:toggleFold("fold' .. foldId .. settings.id_suffix .. '");')
+	    endif
+	    firstfold = 0
 	  endif
-	  " add the filler spaces separately from the '+' char so that it can be
-	  " shown/hidden separately during a hover unfold
-	  let s:new = s:new .. s:FoldColumn_build("+", 1, 0, "",
-		\ 'toggle-open FoldColumn', 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
-	  " If this is not the last fold we're opening on this line, we need
-	  " to keep the filler spaces hidden if the fold is opened by mouse
-	  " hover. If it is the last fold to open in the line, we shouldn't hide
-	  " them, so don't apply the toggle-filler class.
-	  let s:new = s:new .. s:FoldColumn_build(" ", 1, s:foldcolumn - s:allfolds[0].level - 1, "",
-		\ 'toggle-open FoldColumn'.. (get(s:allfolds, 1, {'firstline': 0}).firstline == s:lnum ?" toggle-filler" :""),
-		\ 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
 
-	  " add fold column that can close the new fold
-	  " only add extra blank space if we aren't opening another fold on the
-	  " same line
-	  if get(s:allfolds, 1, {'firstline': 0}).firstline != s:lnum
-	    let s:extra_space = s:foldcolumn - s:allfolds[0].level
+	  # Add fold text, moving the span ending to the next line so collapsing
+	  # of folds works correctly.
+	  # Put numcol in a separate group for sake of unselectable text.
+	  new ..= (settings.number_lines ? HtmlFormat_n(numcol, FOLDED_ID, 0, 0) : "") .. substitute(HtmlFormat_t(foldtextresult(lnum), FOLDED_ID, 0), '', HtmlEndline .. '\n\0', '')
+	  new ..= ""
+
+	  # open the fold now that we have the fold text to allow retrieval of
+	  # fold text for subsequent folds
+	  execute $":{lnum}foldopen"
+	  insert(foldstack, remove(allfolds, 0), 0)
+	  foldstack[0].id = foldId
+	endwhile
+
+	# Unless disabled, add a fold column for other lines.
+	#
+	# Note that dynamic folds require using css so we just use css to take
+	# care of the leading spaces rather than using   in the case of
+	# html_no_pre to make it easier
+	if !settings.no_foldcolumn
+	  if empty(foldstack)
+	    # add the empty foldcolumn for unfolded lines if there is a fold
+	    # column at all
+	    if foldcolumn > 0
+	      new = new .. FoldColumn_fill()
+	    endif
 	  else
-	    let s:extra_space = 0
+	    # add the fold column for folds not on the opening line
+	    if get(foldstack, 0).firstline < lnum
+	      new = new .. FoldColumn_build('|', foldstack[0].level, foldcolumn - foldstack[0].level, "",
+		'FoldColumn', 'javascript:toggleFold("fold' .. foldstack[0].id .. settings.id_suffix .. '");')
+	    endif
 	  endif
-	  if s:firstfold
-	    " the first fold in a line has '|' characters from folds opened in
-	    " previous lines, before the '-' for this fold
-	    let s:new ..= s:FoldColumn_build('|', s:allfolds[0].level - 1, s:extra_space, '-',
-		  \ 'toggle-closed FoldColumn', 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
-	  else
-	    " any subsequent folds in the line only add a single '-'
-	    let s:new = s:new .. s:FoldColumn_build("-", 1, s:extra_space, "",
-		  \ 'toggle-closed FoldColumn', 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
-	  endif
-	  let s:firstfold = 0
 	endif
+      endif
 
-	" Add fold text, moving the span ending to the next line so collapsing
-	" of folds works correctly.
-	" Put numcol in a separate group for sake of unselectable text.
-	let s:new = s:new .. (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0, 0) : "") .. substitute(s:HtmlFormat_t(foldtextresult(s:lnum), s:FOLDED_ID, 0), '', s:HtmlEndline..'\n\0', '')
-	let s:new = s:new .. ""
+      # Now continue with the unfolded line text
+      if settings.number_lines
+	new ..= HtmlFormat_n(numcol, LINENR_ID, 0, lnum)
+      elseif settings.line_ids
+	new ..= HtmlFormat_n("", LINENR_ID, 0, lnum)
+      endif
 
-	" open the fold now that we have the fold text to allow retrieval of
-	" fold text for subsequent folds
-	execute s:lnum.."foldopen"
-	call insert(s:foldstack, remove(s:allfolds,0))
-	let s:foldstack[0].id = s:foldId
-      endwhile
+      # Get the diff attribute, if any.
+      var diffattr = diff_hlID(lnum, 1)
 
-      " Unless disabled, add a fold column for other lines.
-      "
-      " Note that dynamic folds require using css so we just use css to take
-      " care of the leading spaces rather than using   in the case of
-      " html_no_pre to make it easier
-      if !s:settings.no_foldcolumn
-	if empty(s:foldstack)
-	  " add the empty foldcolumn for unfolded lines if there is a fold
-	  " column at all
-	  if s:foldcolumn > 0
-	    let s:new = s:new .. s:FoldColumn_fill()
+      # initialize conceal info to act like not concealed, just in case
+      var concealinfo = [0, '']
+
+      # Loop over each character in the line
+      var col = 1
+
+      # most of the time we won't use the diff_id, initialize to zero
+      var diff_id = 0
+
+      while col <= len || (col == 1 && diffattr != 0)
+	var id: number
+	var startcol = col # The start column for processing text
+	if !settings.ignore_conceal && has('conceal')
+	  concealinfo = synconcealed(lnum, col)
+	endif
+	if !settings.ignore_conceal && concealinfo[0]
+	  col = col + 1
+	  # Speed loop (it's small - that's the trick)
+	  # Go along till we find a change in the match sequence number (ending
+	  # the specific concealed region) or until there are no more concealed
+	  # characters.
+	  while col <= len && concealinfo == synconcealed(lnum, col) | col = col + 1 | endwhile
+	elseif diffattr != 0
+	  diff_id = diff_hlID(lnum, col)
+	  id = synID(lnum, col, 1)
+	  col = col + 1
+	  # Speed loop (it's small - that's the trick)
+	  # Go along till we find a change in hlID
+	  while col <= len && id == synID(lnum, col, 1) && diff_id == diff_hlID(lnum, col)
+	    col = col + 1
+	  endwhile
+	  if len < &columns && !settings.no_pre
+	    # Add spaces at the end of the raw text line to extend the changed
+	    # line to the full width.
+	    line = line .. repeat(' ', &columns - virtcol([lnum, len]) - margin)
+	    len = &columns
 	  endif
 	else
-	  " add the fold column for folds not on the opening line
-	  if get(s:foldstack, 0).firstline < s:lnum
-	    let s:new = s:new .. s:FoldColumn_build('|', s:foldstack[0].level, s:foldcolumn - s:foldstack[0].level, "",
-		  \ 'FoldColumn', 'javascript:toggleFold("fold'..s:foldstack[0].id..s:settings.id_suffix..'");')
-	  endif
+	  id = synID(lnum, col, 1)
+	  col = col + 1
+	  # Speed loop (it's small - that's the trick)
+	  # Go along till we find a change in synID
+	  while col <= len && id == synID(lnum, col, 1) | col = col + 1 | endwhile
 	endif
-      endif
-    endif
-
-    " Now continue with the unfolded line text
-    if s:settings.number_lines
-      let s:new = s:new .. s:HtmlFormat_n(s:numcol, s:LINENR_ID, 0, s:lnum)
-    elseif s:settings.line_ids
-      let s:new = s:new .. s:HtmlFormat_n("", s:LINENR_ID, 0, s:lnum)
-    endif
-
-    " Get the diff attribute, if any.
-    let s:diffattr = diff_hlID(s:lnum, 1)
-
-    " initialize conceal info to act like not concealed, just in case
-    let s:concealinfo = [0, '']
-
-    " Loop over each character in the line
-    let s:col = 1
-
-    " most of the time we won't use the diff_id, initialize to zero
-    let s:diff_id = 0
-
-    while s:col <= s:len || (s:col == 1 && s:diffattr)
-      let s:startcol = s:col " The start column for processing text
-      if !s:settings.ignore_conceal && has('conceal')
-	let s:concealinfo = synconcealed(s:lnum, s:col)
-      endif
-      if !s:settings.ignore_conceal && s:concealinfo[0]
-	let s:col = s:col + 1
-	" Speed loop (it's small - that's the trick)
-	" Go along till we find a change in the match sequence number (ending
-	" the specific concealed region) or until there are no more concealed
-	" characters.
-	while s:col <= s:len && s:concealinfo == synconcealed(s:lnum, s:col) | let s:col = s:col + 1 | endwhile
-      elseif s:diffattr
-	let s:diff_id = diff_hlID(s:lnum, s:col)
-	let s:id = synID(s:lnum, s:col, 1)
-	let s:col = s:col + 1
-	" Speed loop (it's small - that's the trick)
-	" Go along till we find a change in hlID
-	while s:col <= s:len && s:id == synID(s:lnum, s:col, 1)
-	      \   && s:diff_id == diff_hlID(s:lnum, s:col) |
-	      \     let s:col = s:col + 1 |
-	      \ endwhile
-	if s:len < &columns && !s:settings.no_pre
-	  " Add spaces at the end of the raw text line to extend the changed
-	  " line to the full width.
-	  let s:line = s:line .. repeat(' ', &columns - virtcol([s:lnum, s:len]) - s:margin)
-	  let s:len = &columns
-	endif
-      else
-	let s:id = synID(s:lnum, s:col, 1)
-	let s:col = s:col + 1
-	" Speed loop (it's small - that's the trick)
-	" Go along till we find a change in synID
-	while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col = s:col + 1 | endwhile
-      endif
-
-      if s:settings.ignore_conceal || !s:concealinfo[0]
-	" Expand tabs if needed
-	let s:expandedtab = strpart(s:line, s:startcol - 1, s:col - s:startcol)
-	if s:settings.expand_tabs
-	  let s:offset = 0
-	  let s:idx = stridx(s:expandedtab, "\t")
-	  let s:tablist = split(&vts,',')
-	  if empty(s:tablist)
-	    let s:tablist = [ &ts ]
-	  endif
-	  let s:tabidx = 0
-	  let s:tabwidth = 0
-	  while s:idx >= 0
-	    if s:startcol + s:idx == 1
-	      let s:i = s:tablist[0]
-	    else
-	      " Get the character, which could be multiple bytes, which falls
-	      " immediately before the found tab. Extract it by matching a
-	      " character just prior to the column where the tab matches.
-	      " We'll use this to get the byte index of the character
-	      " immediately preceding the tab, so we can then look up the
-	      " virtual column that character appears in, to determine how
-	      " much of the current tabstop has been used up.
-	      if s:idx == 0
-		" if the found tab is the first character in the text being
-		" processed, we need to get the character prior to the text,
-		" given by startcol.
-		let s:prevc = matchstr(s:line, '.\%' .. (s:startcol + s:offset) .. 'c')
-	      else
-		" Otherwise, the byte index of the tab into s:expandedtab is
-		" given by s:idx.
-		let s:prevc = matchstr(s:expandedtab, '.\%' .. (s:idx + 1) .. 'c')
-	      endif
-	      let s:vcol = virtcol([s:lnum, s:startcol + s:idx + s:offset - len(s:prevc)])
-
-	      " find the tabstop interval to use for the tab we just found. Keep
-	      " adding tabstops (which could be variable) until we would exceed
-	      " the virtual screen position of the start of the found tab.
-	      while s:vcol >= s:tabwidth + s:tablist[s:tabidx]
-		let s:tabwidth += s:tablist[s:tabidx]
-		if s:tabidx < len(s:tablist)-1
-		  let s:tabidx = s:tabidx+1
-		endif
-	      endwhile
-	      let s:i = s:tablist[s:tabidx] - (s:vcol - s:tabwidth)
+	var expandedtab: string
+	if settings.ignore_conceal || !concealinfo[0]
+	  # Expand tabs if needed
+	  expandedtab = strpart(line, startcol - 1, col - startcol)
+	  if settings.expand_tabs
+	    var offset = 0
+	    var idx = stridx(expandedtab, "\t")
+	    var tablist = mapnew(split(&vts, ','), (_, v) => str2nr(v))
+	    if empty(tablist)
+	      tablist = [&ts]
 	    endif
-	    " update offset to keep the index within the line corresponding to
-	    " actual tab characters instead of replaced spaces; s:idx reflects
-	    " replaced spaces in s:expandedtab, s:offset cancels out all but
-	    " the tab character itself.
-	    let s:offset -= s:i - 1
-	    let s:expandedtab = substitute(s:expandedtab, '\t', repeat(' ', s:i), '')
-	    let s:idx = stridx(s:expandedtab, "\t")
-	  endwhile
-	end
+	    var tabidx = 0
+	    var tabwidth = 0
+	    var i: number
+	    while idx >= 0
+	      if startcol + idx == 1
+		i = tablist[0]
+	      else
+		# Get the character, which could be multiple bytes, which falls
+		# immediately before the found tab. Extract it by matching a
+		# character just prior to the column where the tab matches.
+		# We'll use this to get the byte index of the character
+		# immediately preceding the tab, so we can then look up the
+		# virtual column that character appears in, to determine how
+		# much of the current tabstop has been used up.
+		var prevc: string
+		if idx == 0
+		  # if the found tab is the first character in the text being
+		  # processed, we need to get the character prior to the text,
+		  # given by startcol.
+		  prevc = matchstr(line, '.\%' .. (startcol + offset) .. 'c')
+		else
+		  # Otherwise, the byte index of the tab into expandedtab is
+		  # given by idx.
+		  prevc = matchstr(expandedtab, '.\%' .. (idx + 1) .. 'c')
+		endif
+		var vcol = virtcol([lnum, startcol + idx + offset - len(prevc)])
 
-	" get the highlight group name to use
-	let s:id = synIDtrans(s:id)
-      else
-	" use Conceal highlighting for concealed text
-	let s:id = s:CONCEAL_ID
-	let s:expandedtab = s:concealinfo[1]
-      endif
+		# find the tabstop interval to use for the tab we just found. Keep
+		# adding tabstops (which could be variable) until we would exceed
+		# the virtual screen position of the start of the found tab.
+		while vcol >= tabwidth + tablist[tabidx]
+		  tabwidth += tablist[tabidx]
+		  if tabidx < len(tablist) - 1
+		    tabidx = tabidx + 1
+		  endif
+		endwhile
+		i = tablist[tabidx] - (vcol - tabwidth)
+	      endif
+	      # update offset to keep the index within the line corresponding to
+	      # actual tab characters instead of replaced spaces; idx reflects
+	      # replaced spaces in expandedtab, offset cancels out all but
+	      # the tab character itself.
+	      offset -= i - 1
+	      expandedtab = substitute(expandedtab, '\t', repeat(' ', i), '')
+	      idx = stridx(expandedtab, "\t")
+	    endwhile
+	  endif
 
-      " Output the text with the same synID, with class set to the highlight ID
-      " name, unless it has been concealed completely.
-      if strlen(s:expandedtab) > 0
-	let s:new = s:new .. s:HtmlFormat(s:expandedtab,  s:id, s:diff_id, "", 0)
-      endif
-    endwhile
-  endif
+	  # get the highlight group name to use
+	  id = synIDtrans(id)
+	else
+	  # use Conceal highlighting for concealed text
+	  id = CONCEAL_ID
+	  expandedtab = concealinfo[1]
+	endif
 
-  call extend(s:lines, split(s:new..s:HtmlEndline, '\n', 1))
-  if !s:settings.no_progress && s:pgb.needs_redraw
-    redrawstatus
-    let s:pgb.needs_redraw = 0
-  endif
-  let s:lnum = s:lnum + 1
+	# Output the text with the same synID, with class set to the highlight ID
+	# name, unless it has been concealed completely.
+	if strlen(expandedtab) > 0
+	  new = new .. HtmlFormat(expandedtab, id, diff_id, "", false)
+	endif
+      endwhile
+    endif
 
-  if !s:settings.no_progress
-    call s:pgb.incr()
-  endif
-endwhile
+    extend(lines, split(new .. HtmlEndline, '\n', 1))
+    if !settings.no_progress && pgb.needs_redraw
+      redrawstatus
+      pgb.needs_redraw = 0
+    endif
+    lnum = lnum + 1
 
-" Diff filler is returned based on what needs inserting *before* the given line.
-" So to get diff filler at the end of the buffer, we need to use last line + 1
-call s:Add_diff_fill(s:end+1)
+    if !settings.no_progress
+      pgb.Incr()
+    endif
+  endwhile
+enddef
+ProcessLines()
 
-if s:settings.dynamic_folds
-  " finish off any open folds
-  while !empty(s:foldstack)
-    let s:lines[-1]..=""
-    call remove(s:foldstack, 0)
+# Diff filler is returned based on what needs inserting *before* the given line.
+# So to get diff filler at the end of the buffer, we need to use last line + 1
+Add_diff_fill(end + 1)
+
+if settings.dynamic_folds
+  # finish off any open folds
+  while !empty(foldstack)
+    lines[-1] ..= ""
+    remove(foldstack, 0)
   endwhile
 
-  " add fold column to the style list if not already there
-  let s:id = s:FOLD_C_ID
-  if !has_key(s:stylelist, s:id)
-    let s:stylelist[s:id] = '.FoldColumn { ' .. s:CSS1(s:id) .. '}'
+  # add fold column to the style list if not already there
+  var id = FOLD_C_ID
+  if !has_key(stylelist, id)
+    stylelist[id] = '.FoldColumn { ' .. CSS1(id) .. '}'
   endif
 endif
 
-if s:settings.no_pre
-  if !s:settings.use_css
-    " Close off the font tag that encapsulates the whole 
-    call extend(s:lines, [""])
+if settings.no_pre
+  if !settings.use_css
+    # Close off the font tag that encapsulates the whole 
+    extend(lines, [""])
   else
-    call extend(s:lines, ["
"]) + extend(lines, ["
"]) endif else - call extend(s:lines, ["
"]) + extend(lines, ["
"]) endif -if !s:settings.no_doc - call extend(s:lines, ["", ""]) +if !settings.no_doc + extend(lines, ["", ""]) endif -exe s:newwin .. "wincmd w" -call setline(1, s:lines) -unlet s:lines +execute $":{newwin}wincmd w" +setline(1, lines) -" Mangle modelines so Vim doesn't try to use HTML text as a modeline if editing -" this file in the future; need to do this after generating all the text in case -" the modeline text has different highlight groups which all turn out to be -" stripped from the final output. -%s!\v(%(^|\s+)%([Vv]i%(m%([<=>]?\d+)?)?|ex)):!\1\:!ge +# Mangle modelines so Vim doesn't try to use HTML text as a modeline if editing +# this file in the future; need to do this after generating all the text in case +# the modeline text has different highlight groups which all turn out to be +# stripped from the final output. +:%s!\v(%(^|\s+)%([Vv]i%(m%([<=>]?\d+)?)?|ex)):!\1\:!ge -" The generated HTML is admittedly ugly and takes a LONG time to fold. -" Make sure the user doesn't do syntax folding when loading a generated file, -" using a modeline. -if !s:settings.no_modeline - call append(line('$'), "") +# The generated HTML is admittedly ugly and takes a LONG time to fold. +# Make sure the user doesn't do syntax folding when loading a generated file, +# using a modeline. +if !settings.no_modeline + append(line('$'), "") endif -" Now, when we finally know which, we define the colors and styles -if s:settings.use_css && !s:settings.no_doc - 1;//+1 +# Now, when we finally know which, we define the colors and styles +if settings.use_css && !settings.no_doc + :1;//+1 - " Normal/global attributes - if s:settings.no_pre - call append('.', "body { color: " .. s:fgc .. "; background-color: " .. s:bgc .. "; font-family: ".. s:htmlfont .."; }") - + + # Normal/global attributes + if settings.no_pre + append('.', "body { color: " .. fgc .. "; background-color: " .. bgc .. "; font-family: " .. htmlfont .. "; }") + :+ else - call append('.', "pre { " .. s:whitespace .. "font-family: ".. s:htmlfont .."; color: " .. s:fgc .. "; background-color: " .. s:bgc .. "; }") - + + append('.', "pre { " .. whitespace .. "font-family: " .. htmlfont .. "; color: " .. fgc .. "; background-color: " .. bgc .. "; }") + :+ yank put execute "normal! ^cwbody\e" - " body should not have the wrap formatting, only the pre section - if s:whitespace != '' - exec 's#'..s:whitespace + # body should not have the wrap formatting, only the pre section + if whitespace != '' + execute 's#' .. whitespace endif endif - " fix browser inconsistencies (sometimes within the same browser) of different - " default font size for different elements - call append('.', '* { font-size: 1em; }') - + - " use color scheme styles for links - " browser-default blue/purple colors for links don't look like the existing theme and are unreadable on dark backgrounds - call append('.', 'a { color: inherit; }') - + - " if we use any input elements for unselectable content, make sure they look - " like normal text - if !empty(s:settings.prevent_copy) - if s:settings.use_input_for_pc !=# "none" - call append('.', 'input { border: none; margin: 0; padding: 0; font-family: '..s:htmlfont..'; }') - + - " ch units for browsers which support them, em units for a somewhat - " reasonable fallback. + # fix browser inconsistencies (sometimes within the same browser) of different + # default font size for different elements + append('.', '* { font-size: 1em; }') + :+ + # use color scheme styles for links + # browser-default blue/purple colors for links don't look like the existing theme and are unreadable on dark backgrounds + append('.', 'a { color: inherit; }') + :+ + # if we use any input elements for unselectable content, make sure they look + # like normal text + if !empty(settings.prevent_copy) + if settings.use_input_for_pc !=# "none" + append('.', 'input { border: none; margin: 0; padding: 0; font-family: ' .. htmlfont .. '; }') + :+ + # ch units for browsers which support them, em units for a somewhat + # reasonable fallback. for w in range(1, 20, 1) - call append('.', [ - \ "input[size='"..w.."'] { width: "..w.."em; width: "..w.."ch; }" - \ ]) - + + append('.', [ + "input[size='" .. w .. "'] { width: " .. w .. "em; width: " .. w .. "ch; }" + ]) + :+ endfor endif - if s:settings.use_input_for_pc !=# 'all' - let s:unselectable_styles = [] - if s:settings.prevent_copy =~# 'f' - call add(s:unselectable_styles, 'FoldColumn') + if settings.use_input_for_pc !=# 'all' + var unselectable_styles: list = [] + if settings.prevent_copy =~# 'f' + add(unselectable_styles, 'FoldColumn') endif - if s:settings.prevent_copy =~# 'n' - call add(s:unselectable_styles, 'LineNr') + if settings.prevent_copy =~# 'n' + add(unselectable_styles, 'LineNr') endif - if s:settings.prevent_copy =~# 't' && !s:settings.ignore_folding - call add(s:unselectable_styles, 'Folded') + if settings.prevent_copy =~# 't' && !settings.ignore_folding + add(unselectable_styles, 'Folded') endif - if s:settings.prevent_copy =~# 'd' - call add(s:unselectable_styles, 'DiffDelete') + if settings.prevent_copy =~# 'd' + add(unselectable_styles, 'DiffDelete') endif - if s:settings.use_input_for_pc !=# 'none' - call append('.', [ - \ '/* Note: IE does not support @supports conditionals, but also does not fully support', - \ ' "content:" with custom content, so we *want* the check to fail */', - \ '@supports ( content: attr(data-custom-content) ) {' - \ ]) - +3 + if settings.use_input_for_pc !=# 'none' + append('.', [ + '/* Note: IE does not support @supports conditionals, but also does not fully support', + ' "content:" with custom content, so we *want* the check to fail */', + '@supports ( content: attr(data-custom-content) ) {' + ]) + :+3 endif - " The line number column inside the foldtext is styled just like the fold - " text in Vim, but it should use the prevent_copy settings of line number - " rather than fold text. Apply the prevent_copy styles to foldtext - " specifically for line numbers, which always come after the fold column, - " or at the beginning of the line. - if s:settings.prevent_copy =~# 'n' && !s:settings.ignore_folding - call append('.', [ - \ ' .FoldColumn + .Folded, .Folded:first-child { user-select: none; }', - \ ' .FoldColumn + [data-Folded-content]::before, [data-Folded-content]:first-child::before { content: attr(data-Folded-content); }', - \ ' .FoldColumn + [data-Folded-content]::before, [data-Folded-content]:first-child::before { padding-bottom: 1px; display: inline-block; /* match the 1-px padding of standard items with background */ }', - \ ' .FoldColumn + span[data-Folded-content]::before, [data-Folded-content]:first-child::before { cursor: default; }', - \ ]) - +4 + # The line number column inside the foldtext is styled just like the fold + # text in Vim, but it should use the prevent_copy settings of line number + # rather than fold text. Apply the prevent_copy styles to foldtext + # specifically for line numbers, which always come after the fold column, + # or at the beginning of the line. + if settings.prevent_copy =~# 'n' && !settings.ignore_folding + append('.', [ + ' .FoldColumn + .Folded, .Folded:first-child { user-select: none; }', + ' .FoldColumn + [data-Folded-content]::before, [data-Folded-content]:first-child::before { content: attr(data-Folded-content); }', + ' .FoldColumn + [data-Folded-content]::before, [data-Folded-content]:first-child::before { padding-bottom: 1px; display: inline-block; /* match the 1-px padding of standard items with background */ }', + ' .FoldColumn + span[data-Folded-content]::before, [data-Folded-content]:first-child::before { cursor: default; }', + ]) + :+4 endif - for s:style_name in s:unselectable_styles - call append('.', [ - \ ' .'..s:style_name..' { user-select: none; }', - \ ' [data-'..s:style_name..'-content]::before { content: attr(data-'..s:style_name..'-content); }', - \ ' [data-'..s:style_name..'-content]::before { padding-bottom: 1px; display: inline-block; /* match the 1-px padding of standard items with background */ }', - \ ' span[data-'..s:style_name..'-content]::before { cursor: default; }', - \ ]) - +4 + for style_name in unselectable_styles + append('.', [ + ' .' .. style_name .. ' { user-select: none; }', + ' [data-' .. style_name .. '-content]::before { content: attr(data-' .. style_name .. '-content); }', + ' [data-' .. style_name .. '-content]::before { padding-bottom: 1px; display: inline-block; /* match the 1-px padding of standard items with background */ }', + ' span[data-' .. style_name .. '-content]::before { cursor: default; }', + ]) + :+4 endfor - if s:settings.use_input_for_pc !=# 'none' - " Note, the extra '}' is to match the "@supports" above - call append('.', [ - \ ' input { display: none; }', - \ '}' - \ ]) - +2 + if settings.use_input_for_pc !=# 'none' + # Note, the extra '}' is to match the "@supports" above + append('.', [ + ' input { display: none; }', + '}' + ]) + :+2 endif - unlet s:unselectable_styles endif - " Fix mouse cursor shape for the fallback method of uncopyable text - if s:settings.use_input_for_pc !=# 'none' - if s:settings.prevent_copy =~# 'f' - " Make the cursor show active fold columns as active areas, and empty fold - " columns as not interactive. - call append('.', ['input.FoldColumn { cursor: pointer; }', - \ 'input.FoldColumn[value="'..repeat(' ', s:foldcolumn)..'"] { cursor: default; }' - \ ]) - +2 - if s:settings.use_input_for_pc !=# 'all' - call append('.', [ - \ 'a[data-FoldColumn-content="'..repeat(' ', s:foldcolumn)..'"] { cursor: default; }' - \ ]) - +1 - end + # Fix mouse cursor shape for the fallback method of uncopyable text + if settings.use_input_for_pc !=# 'none' + if settings.prevent_copy =~# 'f' + # Make the cursor show active fold columns as active areas, and empty fold + # columns as not interactive. + append('.', ['input.FoldColumn { cursor: pointer; }', + 'input.FoldColumn[value="' .. repeat(' ', foldcolumn) .. '"] { cursor: default; }' + ]) + :+2 + if settings.use_input_for_pc !=# 'all' + append('.', [ + 'a[data-FoldColumn-content="' .. repeat(' ', foldcolumn) .. '"] { cursor: default; }' + ]) + :+1 + endif endif - " make line number column show as non-interactive if not selectable - if s:settings.prevent_copy =~# 'n' - call append('.', 'input.LineNr { cursor: default; }') - + + # make line number column show as non-interactive if not selectable + if settings.prevent_copy =~# 'n' + append('.', 'input.LineNr { cursor: default; }') + :+ endif - " make fold text and line number column within fold text show as - " non-interactive if not selectable - if (s:settings.prevent_copy =~# 'n' || s:settings.prevent_copy =~# 't') && !s:settings.ignore_folding - call append('.', 'input.Folded { cursor: default; }') - + + # make fold text and line number column within fold text show as + # non-interactive if not selectable + if (settings.prevent_copy =~# 'n' || settings.prevent_copy =~# 't') && !settings.ignore_folding + append('.', 'input.Folded { cursor: default; }') + :+ endif - " make diff filler show as non-interactive if not selectable - if s:settings.prevent_copy =~# 'd' - call append('.', 'input.DiffDelete { cursor: default; }') - + + # make diff filler show as non-interactive if not selectable + if settings.prevent_copy =~# 'd' + append('.', 'input.DiffDelete { cursor: default; }') + :+ endif endif endif endif -if !s:settings.use_css && !s:settings.no_doc - " For Netscape 4, set attributes too, though, strictly speaking, it's - " incorrect. - execute '%s:]*\):\r attributes too, though, strictly speaking, it's + # incorrect. + execute $':%s/]*\)/\r diffstylelist[k]), (_, v) => v != "")) endif - if !empty(s:stylelist) - call append('.', filter(map(keys(s:stylelist), "s:stylelist[v:val]"), 'v:val != ""')) + if !empty(stylelist) + append('.', filter(map(keys(stylelist), (_, k) => stylelist[k]), (_, v) => v != "")) endif endif -" Add hyperlinks -if !s:settings.no_links - %s+\(https\=://\S\{-}\)\(\([.,;:}]\=\(\s\|$\)\)\|[\\"'<>]\|>\|<\|"\)+\1\2+ge +# Add hyperlinks +if !settings.no_links + :%s+\(https\=://\S\{-}\)\(\([.,;:}]\=\(\s\|$\)\)\|[\\"'<>]\|>\|<\|"\)+\1\2+ge endif -" The DTD -if !s:settings.no_doc - if s:settings.use_xhtml - exe "normal! gg$a\n" - elseif s:html5 - exe "normal! gg0i\n" +# The DTD +if !settings.no_doc + if settings.use_xhtml + execute "normal! gg$a\n" + elseif html5 + execute "normal! gg0i\n" else - exe "normal! gg0i\n" + execute "normal! gg0i\n" endif endif -if s:settings.use_xhtml && !s:settings.no_doc - exe "normal! gg/" +syn keyword algol68Operator ABS REPR ROUND ENTIER ARG BIN LENG SHORTEN ODD +syn keyword algol68Operator SHL SHR ROL ROR UP DOWN LEVEL LWB UPB I RE IM +syn keyword algol68Operator OVER MOD ELEM SET CLEAR +syn keyword algol68Operator LT LE GE GT +syn keyword algol68Operator EQ NE +syn keyword algol68Operator AND OR XOR NOT +" Genie short-circuit pseudo operators +syn keyword algol68Operator THEF ANDF ANDTH ELSF ORF OREL +syn keyword algol68Operator ANDTHEN ORELSE +syn keyword algol68Operator MINUSAB PLUSAB TIMESAB DIVAB OVERAB MODAB PLUSTO +syn keyword algol68Operator IS ISNT OF AT +syn keyword algol68Operator SORT ELEMS +syn keyword algol68Repeat FOR FROM BY UPTO DOWNTO TO WHILE DO UNTIL OD +syn keyword algol68Statement PAR BEGIN END EXIT +syn keyword algol68Struct STRUCT +syn keyword algol68PreProc VECTOR +syn keyword algol68Type FLEX HEAP LOC LONG REF SHORT +syn keyword algol68Type VOID BOOL INT REAL COMPL CHAR STRING COMPLEX +syn keyword algol68Type BITS BYTES FILE CHANNEL PIPE SEMA SOUND +syn keyword algol68Type FORMAT STRUCT UNION +" Genie extensions in addition to ROUND and ENTIER +syn keyword algol68Operator FLOOR CEIL NINT TRUNC FRAC FIX + + " 20011222az: Added new items. +syn keyword algol68Todo contained TODO FIXME XXX DEBUG NOTE + + +" String +syn region algol68String matchgroup=algol68String start=+"+ end=+"+ contains=algol68StringEscape +syn match algol68StringEscape contained '""' +syn match algol68StringEscape contained "\\$" + + +syn match algol68Identifier "\<[a-z][a-z0-9_]*\>" + + +" NOTE: monads = `[!%&+\-?^~]`, nomads = `[*/<=>]`, becomes = `:=`, assigns to = `=:` +" monadic operator => "[!%&+\-?^~][*/<=>]\?\%(:=\|=:\)\?" +" dyadic operator => "\%([!%&+\-?^~]\|[*/<=>]\)[*/<=>]\?\%(:=\|=:\)\?" + +" 'becomes' and 'is defined as' symbols +" syn match algol68SymbolOperator ":=\|=" +syn match algol68SymbolOperator "\%([!%&+\-?^~]\|[*/<=>]\)\@1]\|:\)\@1]\|:=\|=:\)\@!" + +" NOT, AND +" syn match algol68SymbolOperator "[~&]" +syn match algol68SymbolOperator "[~&]\%([*/<=>]\|:=\|=:\)\@!" + +" NOT (Genie extension) +" syn match algol68SymbolOperator "\^" +syn match algol68SymbolOperator "\^\%([*/<=>]\|:=\|=:\)\@!" + +" NE, EQ +" syn match algol68SymbolOperator "/=\|=" +syn match algol68SymbolOperator "/=\%(:=\|=:\|:\)\@!" +syn match algol68SymbolOperator "\%([!%&+\-?^~]\|[*/<=>]\|:\)\@1]\|:=\|=:\)\@!" + +" NE (Genie extension) +" syn match algol68SymbolOperator "[~^]=" +syn match algol68SymbolOperator "[~^]=\%([*/<=>]\|:=\|=:\)\@!" + +" LT, GT, LE, GE +" syn match algol68SymbolOperator "[<>]=\?" +syn match algol68SymbolOperator "\%([!%&+\-?^~]\|[*/<=>]\)\@1]\%([*/<=>]\|:=\|=:\)\@!" +syn match algol68SymbolOperator "\%([!%&+\-?^~]\|[*/<=>]\)\@1]=\%([*/<=>]\|:=\|=:\|:\)\@!" + +" -, +, *, OVER, /, MOD, UP +" syn match algol68SymbolOperator "[-+*%/]\|%\*\|\*\*" +syn match algol68SymbolOperator "[-+%]\%([*/<=>]\|:=\|=:\)\@!" +syn match algol68SymbolOperator "\%([!%&+\-?^~]\|[*/<=>]\)\@1]\|:=\|=:\)\@!" +syn match algol68SymbolOperator "\%(%\*\|\*\*\)\%(:=\|=:\)\@!" + +" syn match algol68SymbolOperator "%\*\|\*\*" +syn match algol68SymbolOperator "\%(%\*\|\*\*\)\%(:=\|=:\)\@!" + +" {MINUS,PLUS,TIMES,OVER,DIV,MOD}AB +" syn match algol68SymbolOperator "\%([-+*%/]\|%\*\):=" +syn match algol68SymbolOperator "\%([-+%]\|%\*\):=" +syn match algol68SymbolOperator "\%([!%&+\-?^~]\|[*/<=>]\)\@1]\|:=\|=:\)\@!" + +" IS, ISNT +syn match algol68SymbolOperator ":/\?=:" + +syn match algol68DefiningOperator "\u[A-Z0-9]" contained +syn match algol68DefiningOperator "[!%&+\-?^~][*/<=>]\?\%(:=\|=:\)\?" contained +syn match algol68DefiningOperator "\%([!%&+\-?^~]\|[*/<=>]\)[*/<=>]\?\%(:=\|=:\)\?" contained + +syn match algol68Number "\<\d\+\%(\s\+\d\+\)*\>" + +syn match algol68Float "\c\.\d\+\%(\s\+\d\+\)*\%(\s*[e\\⏨]\s*[-+]\?\s*\d\+\%(\s\+\d\+\)*\)\?\>" +syn match algol68Float "\c\<\d\+\%(\s\+\d\+\)*\%(\s*[e\\⏨]\s*[-+]\?\s*\d\+\%(\s\+\d\+\)*\)\>" +syn match algol68Float "\c\<\d\+\%(\s\+\d\+\)*\s*\.\s*\d\+\%(\s\+\d\+\)*\%(\s*[e\\⏨]\s*[-+]\?\s*\d\+\%(\s\+\d\+\)*\)\?\>" + +syn match algol68HexNumber "\c\<2r\s*[01]\+\%(\s\+[01]\+\)*\>" +syn match algol68HexNumber "\c\<4r\s*[0-3]\+\%(\s\+[0-3]\+\)*\>" +syn match algol68HexNumber "\c\<8r\s*[0-7]\+\%(\s\+[0-7]\+\)*\>" +syn match algol68HexNumber "\c\<16r\s*[0-9a-f]\+\%(\s\+[0-9a-f]\+\)*\>" + + +syn region algol68Special start="\$" end="\$" contains=algol68String +syn region algol68Comment start="Âĸ" end="Âĸ" contains=algol68Todo,algol68SpaceError +syn region algol68Comment start="ÂŖ" end="ÂŖ" contains=algol68Todo,algol68SpaceError +syn region algol68Comment start="#" end="#" contains=algol68Todo,algol68SpaceError +syn region algol68Comment start="\" end="\" contains=algol68Todo,algol68SpaceError +syn region algol68Comment start="\" end="\" contains=algol68Todo,algol68SpaceError +syn region algol68PreProc start="\" end="\" contains=algol68Todo,algol68SpaceError +syn region algol68PreProc start="\" end="\" contains=algol68Todo,algol68SpaceError +" algol68r +syn region algol68Comment start="{" end="}" contains=algol68Todo,algol68SpaceError +syn region algol68Comment start="{{{" end="}}}" contains=algol68Todo,algol68SpaceError + +" ALGOL 68r +syn keyword algol68PreProc DECS CONTEXT configinfo A68CONFIG KEEP FINISH USE SYSPROCS IOSTATE FORALL +" ALGOL 68c +syn keyword algol68PreProc USING ENVIRON FOREACH ASSERT + +if !exists("algol68_no_preludes") + + +" THE STANDARD ENVIRONMENT + +" Enquiries + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Transput Files and Channels + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Transput Event Routines + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Connections to Files + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Positioning on Files + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" I/O on Files (Standard) + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" I/O on Files (Algol68C) + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Enquiries on Files + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Keyboard Control + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Math Constants + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Math Basic Functions + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!\%(\s\{1,7}[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Math Trigonometric Functions + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + " long-long-sinpi/cospi/tanpi/cotpi + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + " a special case in Genie? + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Random Number Generator + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Garbage Collection and Memory + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" I/O on Strings + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" +" Character Type Tests + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" +" Operations on Characters + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" +" Search in Strings + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Time and Date + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Type Operations + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!\%(\s*[a-z0-9]\)\@!" + +" Runtime + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +" UNIX EXTENSIONS + +" Environment Functions + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Processes + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" File types and attributes + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Fetching web page contents and sending requests + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Regular expressions in string manipulation + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Curses support + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +" POSTGRESQL CLIENT ROUTINES + +" Connecting to a server + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Sending queries and retrieving results + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Connection status information + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +" SOUND + + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn keyword algol68Operator RESOLUTION CHANNELS RATE SAMPLES + + +" DRAWING USING THE GNU PLOTTING UTILITIES + +" Setting up a graphics device + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Specifying colours + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Drawing objects + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Drawing text + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +" EXTRA NUMERICAL PROCEDURES + +" COMPLEX Functions + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + " cas casin casinh dcas dcasin dcasinh qcas qcasin qcasinh longcas longlongcas + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + " a special case in Genie? + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" REAL Airy Functions + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" REAL Bessel Functions + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + " only a few could be sensibly merged; we keep them apart + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" REAL Elliptic Integrals + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" REAL Error and Gamma Functions + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + " is the following a special case in Genie? + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "gamma\s*\%(\%(inc\s*\%(gsl\|[pq]\)\)\|inv\|star\)\>\%(\s*\%([a-z_]\|\l\d\+\)\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + + +" Scaling Factors + + " strangely missing some common factors (hecto, deca, deci, centi), + " also myria, and the more extreme factors (quetta, ronna, ronto, quecto) + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +" Physical Constants + +" Fundamental Constants + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Astronomy and Astrophysics + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Atomic and Nuclear Physics + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Time + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Imperial units + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Nautical units + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Volume + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Mass and weight + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Thermal energy and power + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Pressure + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Viscosity + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Light and illumination + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Radioactivity + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + +" Force and energy + syn match algol68Predefined "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +" Functions from GSL + + syn keyword algol68Operator CV RV T INV PINV MEAN DET TRACE NORM DYAD BEFORE ABOVE + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +" Functions from R Mathlib + + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + " note: Genie documents 'r rn chisq' but it's missing in the code? + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + syn match algol68Function "\%(\%([a-z_]\|\l\d\+\)\s\+\)\@8\%(\s*[a-z0-9]\)\@!" + + +endif + +" Define the default highlighting. +hi def link algol68Boolean Boolean +hi def link algol68Comment Comment +hi def link algol68Conditional Conditional +hi def link algol68Constant Constant +hi def link algol68Float Float +hi def link algol68Function Function +hi def link algol68Label Label +hi def link algol68MatrixDelimiter Identifier +hi def link algol68HexNumber Number +hi def link algol68Number Number +hi def link algol68Operator Operator +hi def link algol68Predefined Identifier +hi def link algol68PreProc PreProc +hi def link algol68Repeat Repeat +hi def link algol68SpaceError Error +hi def link algol68Statement Statement +hi def link algol68String String +hi def link algol68StringEscape Special +hi def link algol68Struct algol68Statement +hi def link algol68SymbolOperator algol68Operator +hi def link algol68Todo Todo +hi def link algol68Type Type +hi def link algol68ShowTab Error + +let b:current_syntax = "algol68" + +" vim: ts=8 sw=2 diff --git a/runtime/syntax/autohotkey.vim b/runtime/syntax/autohotkey.vim index a888394923..db3c26ec0a 100644 --- a/runtime/syntax/autohotkey.vim +++ b/runtime/syntax/autohotkey.vim @@ -3,6 +3,8 @@ " Maintainer: Michael Wong " https://github.com/mmikeww/autohotkey.vim " Latest Revision: 2022-07-25 +" Last Change: +" 2026 Apr 20 by Vim project: remove wrong oneline keyword #20018 " Previous Maintainers: SungHyun Nam " Nikolai Weibull @@ -35,7 +37,6 @@ syn region autohotkeyString syn match autohotkeyVariable \ display - \ oneline \ contains=autohotkeyBuiltinVariable \ keepend \ '%\S\{-}%' @@ -123,7 +124,7 @@ syn keyword autohotkeyCommand syn keyword autohotkeyFunction \ InStr RegExMatch RegExReplace StrLen SubStr Asc Chr Func - \ DllCall VarSetCapacity WinActive WinExist IsLabel OnMessage + \ DllCall VarSetCapacity WinActive WinExist IsLabel OnMessage \ Abs Ceil Exp Floor Log Ln Mod Round Sqrt Sin Cos Tan ASin ACos ATan \ FileExist GetKeyState NumGet NumPut StrGet StrPut RegisterCallback \ IsFunc Trim LTrim RTrim IsObject Object Array FileOpen diff --git a/runtime/syntax/autopkgtest.vim b/runtime/syntax/autopkgtest.vim index 5dc1b5f6f5..56698129ee 100644 --- a/runtime/syntax/autopkgtest.vim +++ b/runtime/syntax/autopkgtest.vim @@ -2,6 +2,7 @@ " Language: Debian autopkgtest control files " Maintainer: Debian Vim Maintainers " Last Change: 2025 Jul 05 +" 2026 May 05 by Vim project: fix typos " URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/syntax/autopkgtest.vim " " Specification of the autopkgtest format is available at: @@ -31,10 +32,10 @@ syn match autopkgtestTests contained "[a-z0-9][a-z0-9+.-]\+\%(,\=\s*[a-z0-9][a-z syn match autopkgtestArbitrary contained "[^#]*" syn keyword autopkgtestRestrictions contained \ allow-stderr - \ breaks-testbe - \ build-neede + \ breaks-testbed + \ build-needed \ flaky - \ hint-testsuite-trigger + \ hint-testsuite-triggers \ isolation-container \ isolation-machine \ needs-internet @@ -43,10 +44,11 @@ syn keyword autopkgtestRestrictions contained \ needs-sudo \ rw-build-tree \ skip-foreign-architecture - \ skip-not-installable \ skippable \ superficial -syn keyword autopkgtestDeprecatedRestrictions contained needs-recommends +syn keyword autopkgtestDeprecatedRestrictions contained + \ needs-recommends + \ skip-not-installable syn match autopkgtestFeatures contained 'test-name=[^, ]*\%([, ]*[^, #]\)*,\=' syn match autopkgtestDepends contained '\%(@builddeps@\|@recommends@\|@\)' diff --git a/runtime/syntax/bitbake.vim b/runtime/syntax/bitbake.vim index 9fea3e291a..ac494cf441 100644 --- a/runtime/syntax/bitbake.vim +++ b/runtime/syntax/bitbake.vim @@ -7,6 +7,7 @@ " Last Change: 2022 Jul 25 " 2025 Oct 13 by Vim project: update multiline function syntax #18565 " 2026 Apr 07 by Vim project: update syntax script #19931 +" 2026 Apr 15 by Vim project: allow forward-slashes in bitbake varflags #19983 " " This file is licensed under the MIT license, see COPYING.MIT in " this source distribution for the terms. @@ -59,7 +60,7 @@ syn match bbVarValue ".*$" contained contains=bbString,bbVarDeref,bbV syn region bbVarPyValue start=+${@+ skip=+\\$+ end=+}+ contained contains=@python " Vars metadata flags -syn match bbVarFlagDef "^\([a-zA-Z0-9\-_\.]\+\)\(\[[a-zA-Z0-9\-_\.+]\+\]\)\@=" contains=bbIdentifier nextgroup=bbVarFlagFlag +syn match bbVarFlagDef "^\([a-zA-Z0-9\-_\.+/]\+\)\(\[[a-zA-Z0-9\-_\.+/]\+\]\)\@=" contains=bbIdentifier nextgroup=bbVarFlagFlag syn region bbVarFlagFlag matchgroup=bbArrayBrackets start="\[" end="\]\s*\(:=\|=\|.=\|=.|+=\|=+\|?=\)\@=" contained contains=bbIdentifier nextgroup=bbVarEq " Includes and requires diff --git a/runtime/syntax/c.vim b/runtime/syntax/c.vim index 64bcd3e368..6838109520 100644 --- a/runtime/syntax/c.vim +++ b/runtime/syntax/c.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: C " Maintainer: The Vim Project -" Last Change: 2026 Jan 13 +" Last Change: 2026 Jun 01 " Former Maintainer: Bram Moolenaar " Quit when a (custom) syntax file was already loaded @@ -278,9 +278,9 @@ if exists("c_gnu") syn keyword cOperator __alignof__ syn keyword cOperator typeof __typeof__ syn keyword cOperator __real__ __imag__ - syn keyword cStorageClass __attribute__ __const__ __extension__ - syn keyword cStorageClass inline __inline __inline__ - syn keyword cStorageClass __restrict__ __volatile__ __noreturn__ + syn keyword cStorageClass __attribute__ __extension__ + syn keyword cTypeQualifier __const__ __restrict__ __volatile__ + syn keyword cFunctionSpec inline __inline __inline__ __noreturn__ endif syn keyword cType int long short char void syn keyword cType signed unsigned float double @@ -314,9 +314,11 @@ endif syn keyword cTypedef typedef syn keyword cStructure struct union enum -syn keyword cStorageClass static register auto volatile extern const +syn keyword cStorageClass static register auto extern +syn keyword cTypeQualifier const volatile if !exists("c_no_c99") && !s:in_cpp_family - syn keyword cStorageClass inline restrict + syn keyword cFunctionSpec inline + syn keyword cTypeQualifier restrict endif if (s:ft ==# "c" && !exists("c_no_c23")) || (s:in_cpp_family && !exists("cpp_no_cpp11")) syn keyword cStorageClass constexpr @@ -324,11 +326,11 @@ endif if !exists("c_no_c11") syn keyword cStorageClass _Alignas alignas syn keyword cOperator _Alignof alignof - syn keyword cStorageClass _Atomic + syn keyword cTypeQualifier _Atomic syn keyword cOperator _Generic - syn keyword cStorageClass _Noreturn + syn keyword cFunctionSpec _Noreturn if !s:in_cpp_family - syn keyword cStorageClass noreturn + syn keyword cStandardAttribute noreturn endif syn keyword cOperator _Static_assert static_assert syn keyword cStorageClass _Thread_local thread_local @@ -352,6 +354,11 @@ if !exists("c_no_c11") syn keyword cType atomic_intmax_t atomic_uintmax_t endif +if !exists("c_no_c23") && !s:in_cpp_family + syn keyword cStandardAttribute deprecated fallthrough maybe_unused nodiscard + syn keyword cStandardAttribute unsequenced reproducible +endif + if (s:ft ==# "c" && !exists("c_no_c23")) || (s:in_cpp_family && !exists("cpp_no_cpp20")) syn keyword cType char8_t endif @@ -606,6 +613,9 @@ hi def link cOperator Operator hi def link cStructure Structure hi def link cTypedef Structure hi def link cStorageClass StorageClass +hi def link cTypeQualifier cStorageClass +hi def link cFunctionSpec cStorageClass +hi def link cStandardAttribute cStorageClass hi def link cInclude Include hi def link cPreProc PreProc hi def link cDefine Macro diff --git a/runtime/syntax/cabal.vim b/runtime/syntax/cabal.vim index 74cda51266..ddc905615b 100644 --- a/runtime/syntax/cabal.vim +++ b/runtime/syntax/cabal.vim @@ -5,8 +5,12 @@ " Previous Maintainer: Vincent Berthoux " File Types: .cabal " Last Change: 22 Oct 2022 +" +" 2026 Apr 29 by LÊana: add missing haskell language editions +" 2026 Apr 20 by Vim project: remove wrong oneline keyword #20018 +" " v1.6: Added support for foreign-libraries -" Added highlighting for various fields +" Added highlighting for various fields " v1.5: Incorporated changes from " https://github.com/sdiehl/haskell-vim-proto/blob/master/vim/syntax/cabal.vim " Use `syn keyword` instead of `syn match`. @@ -25,7 +29,7 @@ " Cabal known compiler are highlighted too. " " V1.2: Added cpp-options which was missing. Feature implemented -" by GHC, found with a GHC warning, but undocumented. +" by GHC, found with a GHC warning, but undocumented. " Whatever... " " v1.1: Fixed operator problems and added ftdetect file @@ -186,19 +190,20 @@ syn match cabalVersionRegionA \ contains=cabalVersionOperator,cabalVersion \ keepend \ /\%(==\|\^\?>=\|<=\|<\|>\)\s*\d\+\%(\.\d\+\)*\%(\.\*\)\?\>/ -" version inside `version: ...` +" version inside `version: ...` syn match cabalVersionRegionB \ contains=cabalStatementRegion,cabalVersionOperator,cabalVersion \ /^\s*\%(cabal-\)\?version\s*:.*$/ -syn keyword cabalLanguage Haskell98 Haskell2010 +" See the following link for all Haskell language editions supported by Cabal. +" https://cabal.readthedocs.io/en/stable/cabal-package-description-file.html#pkg-field-default-language +syn keyword cabalLanguage Haskell98 Haskell2010 GHC2021 GHC2024 " title region syn match cabalName contained /:\@<=.*/ syn match cabalNameRegion \ contains=cabalStatementRegion,cabalName \ nextgroup=cabalStatementRegion - \ oneline \ /^\c\s*name\s*:.*$/ " author region @@ -206,7 +211,6 @@ syn match cabalAuthor contained /:\@<=.*/ syn match cabalAuthorRegion \ contains=cabalStatementRegion,cabalStatement,cabalAuthor \ nextgroup=cabalStatementRegion - \ oneline \ /^\c\s*author\s*:.*$/ " maintainer region @@ -214,7 +218,6 @@ syn match cabalMaintainer contained /:\@<=.*/ syn match cabalMaintainerRegion \ contains=cabalStatementRegion,cabalStatement,cabalMaintainer \ nextgroup=cabalStatementRegion - \ oneline \ /^\c\s*maintainer\s*:.*$/ " license region @@ -222,7 +225,6 @@ syn match cabalLicense contained /:\@<=.*/ syn match cabalLicenseRegion \ contains=cabalStatementRegion,cabalStatement,cabalLicense \ nextgroup=cabalStatementRegion - \ oneline \ /^\c\s*license\s*:.*$/ " license-file region @@ -230,7 +232,6 @@ syn match cabalLicenseFile contained /:\@<=.*/ syn match cabalLicenseFileRegion \ contains=cabalStatementRegion,cabalStatement,cabalLicenseFile \ nextgroup=cabalStatementRegion - \ oneline \ /^\c\s*license-file\s*:.*$/ " tested-with region with compilers and versions @@ -238,7 +239,6 @@ syn keyword cabalCompiler contained ghc nhc yhc hugs hbc helium jhc lhc syn match cabalTestedWithRegion \ contains=cabalStatementRegion,cabalStatement,cabalCompiler,cabalVersionRegionA \ nextgroup=cabalStatementRegion - \ oneline \ /^\c\s*tested-with\s*:.*$/ " build type keywords diff --git a/runtime/syntax/cpp.vim b/runtime/syntax/cpp.vim index 5ea52ec502..1c725a4bfd 100644 --- a/runtime/syntax/cpp.vim +++ b/runtime/syntax/cpp.vim @@ -7,6 +7,7 @@ " 2024 May 04 by Vim Project fix digit separator in octals and floats " 2026 Jan 06 by Vim Project orphaning announcement " 2026 Jan 08 by Vim Project highlight capital letter prefixes for numbers +" 2026 May 29 by Vim Project add C++23 stdfloat types (#16498) " quit when a syntax file was already loaded if exists("b:current_syntax") @@ -104,6 +105,11 @@ if !exists("cpp_no_cpp20") syn keyword cppModule import module export endif +" C++ 23 extensions +if !exists("cpp_no_cpp23") + syn keyword cppType float16_t float32_t float64_t float128_t bfloat16_t +endif + " The minimum and maximum operators in GNU C++ syn match cppMinMax "[<>]?" diff --git a/runtime/syntax/django.vim b/runtime/syntax/django.vim index 353221af08..0d0c11b510 100644 --- a/runtime/syntax/django.vim +++ b/runtime/syntax/django.vim @@ -3,6 +3,8 @@ " Maintainer: Dave Hodder " Last Change: 2021 Nov 29 " 2026 Feb 12 by Vim Project add partial support #19386 +" 2026 Apr 17 by Vim Project Update to Django 5.2 version #19994 +" 2026 May 17 by Vim Project Update comparison operators #20225 " quit when a syntax file was already loaded if exists("b:current_syntax") @@ -17,29 +19,28 @@ syn match djangoError "%}\|}}\|#}" " Django template built-in tags and parameters " 'comment' doesn't appear here because it gets special treatment syn keyword djangoStatement contained autoescape csrf_token empty -" FIXME ==, !=, <, >, <=, and >= should be djangoStatements: -" syn keyword djangoStatement contained == != < > <= >= syn keyword djangoStatement contained and as block endblock by cycle debug else elif syn keyword djangoStatement contained extends filter endfilter firstof for syn keyword djangoStatement contained endfor if endif ifchanged endifchanged -syn keyword djangoStatement contained ifequal endifequal ifnotequal -syn keyword djangoStatement contained endifnotequal in include load not now or -syn keyword djangoStatement contained parsed regroup reversed spaceless -syn keyword djangoStatement contained endspaceless ssi templatetag openblock +syn keyword djangoStatement contained in include load not now +syn keyword djangoStatement contained regroup reversed spaceless +syn keyword djangoStatement contained endspaceless templatetag openblock syn keyword djangoStatement contained closeblock openvariable closevariable -syn keyword djangoStatement contained openbrace closebrace opencomment +syn keyword djangoStatement contained openbrace closebrace opencomment or syn keyword djangoStatement contained closecomment widthratio url with endwith -syn keyword djangoStatement contained get_current_language trans noop blocktrans -syn keyword djangoStatement contained endblocktrans get_available_languages -syn keyword djangoStatement contained get_current_language_bidi plural +syn keyword djangoStatement contained get_current_language noop get_available_languages +syn keyword djangoStatement contained get_current_language_bidi get_language_info plural syn keyword djangoStatement contained translate blocktranslate endblocktranslate syn keyword djangoStatement contained partialdef endpartialdef partial +syn keyword djangoStatement contained querystring lorem verbatim localize endlocalize +syn keyword djangoStatement contained localtime endlocaltime timezone endtimezone +syn keyword djangoStatement contained get_current_timezone " Django templete built-in filters syn keyword djangoFilter contained add addslashes capfirst center cut date syn keyword djangoFilter contained default default_if_none dictsort syn keyword djangoFilter contained dictsortreversed divisibleby escape escapejs -syn keyword djangoFilter contained filesizeformat first fix_ampersands +syn keyword djangoFilter contained filesizeformat first syn keyword djangoFilter contained floatformat get_digit join last length length_is syn keyword djangoFilter contained linebreaks linebreaksbr linenumbers ljust syn keyword djangoFilter contained lower make_list phone2numeric pluralize @@ -48,6 +49,8 @@ syn keyword djangoFilter contained safe safeseq stringformat striptags syn keyword djangoFilter contained time timesince timeuntil title truncatechars syn keyword djangoFilter contained truncatewords truncatewords_html unordered_list upper urlencode syn keyword djangoFilter contained urlize urlizetrunc wordcount wordwrap yesno +syn keyword djangoFilter contained force_escape iriencode json_script truncatechars_html +syn keyword djangoFilter contained localize unlocalize localtime utc timezone " Keywords to highlight within comments syn keyword djangoTodo contained TODO FIXME XXX @@ -67,6 +70,9 @@ syn region djangoVarBlock start="{{" end="}}" contains=djangoFilter,djangoArgume syn region djangoComment start="{%\s*comment\(\s\+.\{-}\)\?%}" end="{%\s*endcomment\s*%}" contains=djangoTodo syn region djangoComBlock start="{#" end="#}" contains=djangoTodo +" Match comparison operators within Django statements. +syn match djangoOperator "==\|!=\|<=\|>=\|<\|>" contained containedin=djangoTagBlock + " Define the default highlighting. " Only when an item doesn't have highlighting yet @@ -81,6 +87,6 @@ hi def link djangoError Error hi def link djangoComment Comment hi def link djangoComBlock Comment hi def link djangoTodo Todo - +hi def link djangoOperator Operator let b:current_syntax = "django" diff --git a/runtime/syntax/dockerfile.vim b/runtime/syntax/dockerfile.vim index f1d612f4ad..17b32d2942 100644 --- a/runtime/syntax/dockerfile.vim +++ b/runtime/syntax/dockerfile.vim @@ -1,6 +1,7 @@ " dockerfile.vim - Syntax highlighting for Dockerfiles " Maintainer: Honza Pokorny " Last Change: 2024 Dec 20 +" 2026 Mar 26 by Vim Project: dockerfileShell comments (#19829) " License: BSD " https://docs.docker.com/engine/reference/builder/ @@ -31,7 +32,7 @@ syntax match dockerfileInstruction contained /\v<(SHELL|VOLUME)>/ syntax region dockerfileString contained start=/\v"/ skip=/\v\\./ end=/\v"/ syntax region dockerfileJSON contained keepend start=/\v\[/ skip=/\v\\\_./ end=/\v$/ contains=@JSON -syntax region dockerfileShell contained keepend start=/\v/ skip=/\v\\\_./ end=/\v$/ contains=@Shell +syntax region dockerfileShell contained keepend start=/\v/ skip=/\v\\\_.|^\s*#.*/ end=/\v$/ contains=@Shell syntax region dockerfileValue contained keepend start=/\v/ skip=/\v\\\_./ end=/\v$/ contains=dockerfileString syntax region dockerfileComment start=/\v^\s*#/ end=/\v$/ contains=@Spell diff --git a/runtime/syntax/generator/vim.vim.base b/runtime/syntax/generator/vim.vim.base index d73688927a..48414714fc 100644 --- a/runtime/syntax/generator/vim.vim.base +++ b/runtime/syntax/generator/vim.vim.base @@ -2,7 +2,7 @@ " Language: Vim script " Maintainer: Hirohito Higashi " Doug Kearns -" Last Change: 2026 Feb 20 +" Last Change: 2026 May 24 " Former Maintainer: Charles E. Campbell " DO NOT CHANGE DIRECTLY. @@ -520,7 +520,7 @@ syn match vim9LambdaParams contained \ "(\%(\" \ skipwhite nextgroup=vim9LambdaOperator \ contains=@vim9Continue,vimDefParam,vim9LambdaParen,vim9LambdaReturnType -syn region vim9LambdaReturnType contained start=")\@<=:\s" end="\ze\s*#" end="\ze\s*=>" contains=@vim9Continue,@vimType transparent +syn region vim9LambdaReturnType contained start=")\@1<=:\s" end="\ze\s*#" end="\ze\s*=>" contains=@vim9Continue,@vimType transparent syn region vim9LambdaBlock contained matchgroup=vimSep start="{" end="^\s*\zs}" contains=@vimDefBodyList syn match vim9LambdaOperatorComment contained "#.*" skipwhite skipempty nextgroup=@vimExprList,vim9LambdaBlock,vim9LambdaOperatorComment @@ -630,7 +630,7 @@ syn match vimDelfunction "\" skipwhite nextgroup=vimDelfunct " ===== syn region vimReturnType contained - \ start=":\%(\s\|\n\)\@=" + \ start=")\@1<=:\%(\s\|\n\)\@=" \ skip=+\n\s*\%(\\\|#\\ \)\|^\s*#\\ + \ end="$" \ matchgroup=vim9Comment @@ -697,7 +697,7 @@ if s:vim9script \ contains=vim9DefTypeParam syn region vim9MethodDefReturnType contained - \ start=":\%(\s\|\n\)\@=" + \ start=")\@1<=:\%(\s\|\n\)\@=" \ skip=+\n\s*\%(\\\|#\\ \)\|^\s*#\\ + \ end="$" \ matchgroup=vim9Comment @@ -825,7 +825,7 @@ if s:vim9script \ skipwhite skipnl nextgroup=vimDefComment,vim9AbstractDefReturnType,vimCommentError \ contains=vimDefParam,vim9Comment,vimFunctionParamEquals syn region vim9AbstractDefReturnType contained - \ start=":\s" end="$" matchgroup=vim9Comment end="\ze[#"]" + \ start=")\@1<=:\s" end="$" matchgroup=vim9Comment end="\ze[#"]" \ skipwhite skipnl nextgroup=vimDefComment,vimCommentError \ contains=vimTypeSep \ transparent @@ -1860,10 +1860,11 @@ syn keyword vimSynType contained include skipwhite nextgroup=vimSynIncludeClust syn match vimSynIncludeCluster contained "@[_a-zA-Z0-9]\+\>" " Syntax: keyword {{{2 -syn cluster vimSynKeyGroup contains=@vimContinue,vimSynCchar,vimSynNextgroup,vimSynKeyOpt,vimSynContainedin +syn cluster vimSynKeyGroup contains=@vimContinue,vimSynCchar,vimSynNextgroup,vimSynKeyOpt,vimSynContainedin,vimSynKeyError syn keyword vimSynType contained keyword skipwhite nextgroup=vimSynKeyRegion syn region vimSynKeyRegion contained keepend matchgroup=vimGroupName start="\h\w*\>" skip=+\\\\\|\\|\|\n\s*\%(\\\|"\\ \)+ matchgroup=vimCmdSep end="|\|$" contains=@vimSynKeyGroup syn match vimSynKeyOpt contained "\%#=1\<\%(conceal\|contained\|transparent\|skipempty\|skipwhite\|skipnl\)\>" +syn match vimSynKeyError contained "\" " Syntax: match {{{2 syn cluster vimSynMtchGroup contains=@vimContinue,vimSynCchar,vimSynContains,vimSynContainedin,vimSynError,vimSynMtchOpt,vimSynNextgroup,vimSynRegPat,vimNotation,vimMtchComment @@ -2431,6 +2432,7 @@ if !exists("skip_vim_syntax_inits") hi def link vimSyncError vimError hi def link vimSynConcealError vimError hi def link vimSynError vimError + hi def link vimSynKeyError vimError hi def link vimSynFoldlevelError vimError hi def link vimSynIskeywordError vimError hi def link vimSynSpellError vimError diff --git a/runtime/syntax/graphql.vim b/runtime/syntax/graphql.vim index 01d5ca25ff..53ab1cc93f 100644 --- a/runtime/syntax/graphql.vim +++ b/runtime/syntax/graphql.vim @@ -4,7 +4,7 @@ " Filenames: *.graphql *.graphqls *.gql " URL: https://github.com/jparise/vim-graphql " License: MIT -" Last Change: 2024 Dec 21 +" Last Change: 2026 Apr 21 if !exists('main_syntax') if exists('b:current_syntax') @@ -26,8 +26,13 @@ syn match graphqlOperator "\M..." display syn keyword graphqlBoolean true false syn keyword graphqlNull null syn match graphqlNumber "-\=\<\%(0\|[1-9]\d*\)\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\>" display -syn region graphqlString start=+"+ skip=+\\\\\|\\"+ end=+"\|$+ -syn region graphqlString start=+"""+ skip=+\\"""+ end=+"""+ +syn region graphqlString start=+"+ skip=+\\\\\|\\"+ end=+"\|$+ contains=graphqlEscape +syn region graphqlString start=+"""+ skip=+\\"""+ end=+"""+ contains=graphqlEscape + +syn match graphqlEscape +\\["\\/bfnrt]+ contained display +syn match graphqlEscape +\\u\x\{4}+ contained display +syn match graphqlEscape +\\u{\x\+}+ contained display +syn match graphqlEscape +\\""\"+ contained display syn keyword graphqlKeyword repeatable nextgroup=graphqlKeyword skipwhite syn keyword graphqlKeyword on nextgroup=graphqlType,graphqlDirectiveLocation skipwhite @@ -45,11 +50,11 @@ syn match graphqlVariable "\<\$\h\w*\>" display syn match graphqlName "\<\h\w*\>" display syn match graphqlType "\<_*\u\w*\>" display -" https://spec.graphql.org/October2021/#ExecutableDirectiveLocation +" https://spec.graphql.org/September2025/#ExecutableDirectiveLocation syn keyword graphqlDirectiveLocation QUERY MUTATION SUBSCRIPTION FIELD syn keyword graphqlDirectiveLocation FRAGMENT_DEFINITION FRAGMENT_SPREAD syn keyword graphqlDirectiveLocation INLINE_FRAGMENT VARIABLE_DEFINITION -" https://spec.graphql.org/October2021/#TypeSystemDirectiveLocation +" https://spec.graphql.org/September2025/#TypeSystemDirectiveLocation syn keyword graphqlDirectiveLocation SCHEMA SCALAR OBJECT FIELD_DEFINITION syn keyword graphqlDirectiveLocation ARGUMENT_DEFINITION INTERFACE UNION syn keyword graphqlDirectiveLocation ENUM ENUM_VALUE INPUT_OBJECT @@ -73,6 +78,7 @@ hi def link graphqlBoolean Boolean hi def link graphqlNull Keyword hi def link graphqlNumber Number hi def link graphqlString String +hi def link graphqlEscape Special hi def link graphqlDirective PreProc hi def link graphqlDirectiveLocation Special diff --git a/runtime/syntax/help.vim b/runtime/syntax/help.vim index 81ac28f845..ecaf453677 100644 --- a/runtime/syntax/help.vim +++ b/runtime/syntax/help.vim @@ -1,8 +1,9 @@ " Vim syntax file " Language: Vim help file " Maintainer: Doug Kearns -" Last Change: 2025 Nov 13 " Former Maintainer: Bram Moolenaar +" Last Change: 2025 Nov 13 +" 2026 Apr 09 by Vim project: improve pattern for translated syntaxt.txt #19942 " Quit when a (custom) syntax file was already loaded if exists("b:current_syntax") @@ -307,7 +308,7 @@ hi def link helpDiffAdded Added hi def link helpDiffChanged Changed hi def link helpDiffRemoved Removed -if has('textprop') && expand('%:p') =~ '[/\\]doc[/\\]syntax.txt' +if has('textprop') && expand('%:p') =~? '[/\\]doc[/\\]syntax.\(txt\|\a\ax\)$' " highlight groups with their respective color import 'dist/vimhelp.vim' call vimhelp.HighlightGroups() diff --git a/runtime/syntax/javacc.vim b/runtime/syntax/javacc.vim index a80572d510..f81e12d29b 100644 --- a/runtime/syntax/javacc.vim +++ b/runtime/syntax/javacc.vim @@ -3,6 +3,7 @@ " Maintainer: Claudio Fleiner " URL: http://www.fleiner.com/vim/syntax/javacc.vim " Last Change: 2012 Oct 05 +" 2026 May 11 by Vim project: check for existence of javaFuncDef before clearing it " Uses java.vim, and adds a few special things for JavaCC Parser files. " Those files usually have the extension *.jj @@ -33,7 +34,9 @@ syn clear javaError2 " remove function definitions (they look different) (first define in " in case it was not defined in java.vim) "syn match javaFuncDef "--" -syn clear javaFuncDef +if hlexists('javaFuncDef') + syn clear javaFuncDef +endif syn match javaFuncDef "[$_a-zA-Z][$_a-zA-Z0-9_. \[\]]*([^-+*/()]*)[ \t]*:" contains=javaType syn keyword javaccPackages options DEBUG_PARSER DEBUG_LOOKAHEAD DEBUG_TOKEN_MANAGER diff --git a/runtime/syntax/javascript.vim b/runtime/syntax/javascript.vim index c89fcedce6..c910a668a2 100644 --- a/runtime/syntax/javascript.vim +++ b/runtime/syntax/javascript.vim @@ -1,18 +1,12 @@ " Vim syntax file -" Language: JavaScript -" Maintainer: Claudio Fleiner -" Updaters: Scott Shattuck (ss) -" URL: http://www.fleiner.com/vim/syntax/javascript.vim -" Changes: (ss) added keywords, reserved words, and other identifiers -" (ss) repaired several quoting and grouping glitches -" (ss) fixed regex parsing issue with multiple qualifiers [gi] -" (ss) additional factoring of keywords, globals, and members -" Last Change: 2022 Jun 09 -" 2013 Jun 12: adjusted javaScriptRegexpString (Kevin Locke) -" 2018 Apr 14: adjusted javaScriptRegexpString (LongJohnCoder) -" 2024 Aug 14: fix a few stylistic issues (#15480) -" 2025 Aug 07: as is a reserved keyword (#17912) -" 2025 Sep 24: using is a reserved keyword (Devin Weaver) +" Language: JavaScript +" Maintainer: This runtime file is looking for a maintainer. +" Previous Maintainer: Claudio Fleiner +" Contributors: Scott Shattuck +" Kevin Locke +" LongJohnCoder +" Devin Weaver +" Last Change: 2026 Apr 26 " tuning parameters: " unlet javaScript_fold @@ -52,7 +46,14 @@ syn match javaScriptNumber "\<\d\+\(_\d\+\)*[eE][+-]\?\d\+\>" syn match javaScriptNumber "\<[1-9]\d*\(_\d\+\)*\(\.\(\d\+\(_\d\+\)*\([eE][+-]\?\d\+\)\?\)\?\)\?\>" syn match javaScriptNumber "\<\(\d\+\(_\d\+\)*\)\?\.\d\+\(_\d\+\)*\([eE][+-]\?\d\+\)\?\>" syn match javaScriptNumber "\<\d\+\(_\d\+\)*\.\(\d\+\(_\d\+\)*\([eE][+-]\?\d\+\)\?\)\?\>" -syn region javaScriptRegexpString start=+[,(=+]\s*/[^/*]+ms=e-1,me=e-1 skip=+\\\\\|\\/+ end=+/[gimuys]\{0,2\}\s*$+ end=+/[gimuys]\{0,2\}\s*[+;.,)\]}]+me=e-1 end=+/[gimuys]\{0,2\}\s\+\/+me=e-1 contains=@htmlPreproc,javaScriptComment oneline +syn region javaScriptRegexpString + \ start=+\%([,(=+]\s*\)\@8<=/[^/*]+ + \ skip=+\\\\\|\\/+ + \ end=+/[dgimsuvy]\{0,7\}\ze\s*$+ + \ end=+/[dgimsuvy]\{0,7\}\ze\s*[+;.,)\]}]+ + \ end=+/[dgimsuvy]\{0,7\}\ze\s\+\/+ + \ contains=@htmlPreproc,javaScriptComment + \ oneline syn keyword javaScriptConditional if else switch syn keyword javaScriptRepeat while for do in of diff --git a/runtime/syntax/jjdescription.vim b/runtime/syntax/jjdescription.vim index bd1c6f22fd..f7b76ba260 100644 --- a/runtime/syntax/jjdescription.vim +++ b/runtime/syntax/jjdescription.vim @@ -3,16 +3,19 @@ " Maintainer: Gregory Anders " Last Change: 2024 May 8 " 2025 Apr 17 by Vim Project (don't require space to start comments, #17130) +" 2026 Apr 09 by Vim Project (anchor status regex to beginning of line, #19879) +" 2026 Apr 09 by Vim Project (detect renames of files, #19879) if exists('b:current_syntax') finish endif -syn match jjAdded "A .*" contained -syn match jjRemoved "D .*" contained -syn match jjChanged "M .*" contained +syn match jjAdded "^JJ:\s\+\zsA\s.*" contained +syn match jjRemoved "^JJ:\s\+\zsD\s.*" contained +syn match jjChanged "^JJ:\s\+\zsM\s.*" contained +syn match jjRenamed "^JJ:\s\+\zsR\s.*" contained -syn region jjComment start="^JJ:" end="$" contains=jjAdded,jjRemoved,jjChanged +syn region jjComment start="^JJ:" end="$" contains=jjAdded,jjRemoved,jjChanged,jjRenamed syn include @jjCommitDiff syntax/diff.vim syn region jjCommitDiff start=/\%(^diff --\%(git\|cc\|combined\) \)\@=/ end=/^\%(diff --\|$\|@@\@!\|[^[:alnum:]\ +-]\S\@!\)\@=/ fold contains=@jjCommitDiff @@ -21,5 +24,6 @@ hi def link jjComment Comment hi def link jjAdded Added hi def link jjRemoved Removed hi def link jjChanged Changed +hi def link jjRenamed Changed let b:current_syntax = 'jjdescription' diff --git a/runtime/syntax/karel.vim b/runtime/syntax/karel.vim index 85c78529e6..a9cdc8277d 100644 --- a/runtime/syntax/karel.vim +++ b/runtime/syntax/karel.vim @@ -1,6 +1,6 @@ " Vim syntax file " Language: KAREL -" Last Change: 2024-11-17 +" Last Change: 2026-05-28 " Maintainer: Kirill Morozov " Credits: Jay Strybis for the initial implementation and Patrick Knosowski " for a couple of fixes. @@ -61,10 +61,10 @@ hi def link karelFunction Function syn keyword karelClause EVAL FROM IN WHEN WITH hi def link karelClause Keyword -syn keyword karelConditional IF THEN ELSE ENDIF SELECT ENDSELECT CASE +syn keyword karelConditional IF THEN ELSE ENDIF SELECT ENDSELECT CASE OF hi def link karelConditional Conditional -syn keyword karelRepeat WHILE DO ENDWHILE FOR +syn keyword karelRepeat WHILE DO ENDWHILE FOR TO DOWNTO hi def link karelRepeat Repeat syn keyword karelProcedure ABORT_TASK ACT_SCREEN ACT_TBL ADD_BYNAMEPC ADD_DICT ADD_INTPC ADD_REALPC ADD_STRINGPC APPEND_NODE APPEND_QUEUE diff --git a/runtime/syntax/make.vim b/runtime/syntax/make.vim index 0e973237a5..530b41e0e9 100644 --- a/runtime/syntax/make.vim +++ b/runtime/syntax/make.vim @@ -9,6 +9,7 @@ " 2025 Oct 25 by Vim project: update makeTargetinDefine highlighting (#18570) " 2025 Dec 23 by Vim project: fix too greedy match (#18938) " 2025 Dec 23 by Vim project: wrong highlight with paranthesis inside quotes (#18818) +" 2026 Apr 17 by Vim project: wrong highlight $ inside quotes (#19986) " quit when a syntax file was already loaded if exists("b:current_syntax") @@ -41,7 +42,7 @@ endif syn match makeIdent "\$\$\w*" syn match makeIdent "\$\$\$\$\w*" containedin=makeDefine syn match makeIdent "\$[^({]" -syn match makeIdent "\$\$[^({]" containedin=makeDefine +syn match makeIdent "\$\$[^({\"']" containedin=makeDefine if get(b:, 'make_flavor', s:make_flavor) == 'microsoft' syn region makeIdent start="\$(" end=")" contains=makeStatement,makeIdent,makeDString,makeSString syn region makeIdent start="\${" end="}" contains=makeStatement,makeIdent,makeDString,makeSString diff --git a/runtime/syntax/mbsync.vim b/runtime/syntax/mbsync.vim index daef41ddd3..eacd46ddbf 100644 --- a/runtime/syntax/mbsync.vim +++ b/runtime/syntax/mbsync.vim @@ -4,6 +4,7 @@ " Last Change: 2025 Apr 13 " 2025 Jun 04 by Vim project: match TLSType configuration variable " 2026 Jan 15 by Vim project: support TLSVersions keyword +" 2026 May 20 by Vim project: handle sync keyword #20243 " " Syntax support for mbsync config file @@ -132,7 +133,28 @@ syn match mbsCConfStPattern '^Patterns\?\s\+\ze.*$' contains=mbsCConfI syn match mbsCConfStMaxSize '^MaxSize\s\+\ze.*$' contains=mbsCConfItemK contained nextgroup=mbsSize transparent syn match mbsCConfStMaxMessages '^MaxMessages\s\+\ze.*$' contains=mbsCConfItemK contained nextgroup=mbsNumber transparent syn match mbsCConfStExpireUnread '^ExpireUnread\s\+\ze.*$' contains=mbsCConfItemK contained nextgroup=mbsBool transparent -syn match mbsCConfSyncOpt 'None\|All\|\%(\s\+\%(Pull\|Push\|New\|ReNew\|Delete\|Flags\)\)\+' display contained +" Properly matching mbsCConfSyncOpt: +" +" None is a special case. From mbsync's man page: +" "None may not be combined with any other operation." +" Once "None" is out of the way, first try to match operations, including: +" - New, Old, Upgrade, Gone, Flags +" - ReNew (deprecated synonym for Upgrade) +" - Delete (deprecated synonym for Gone) +" - All and Full, since they can be combined with other flags +" Then try to match the "second style" (as defined by mbsync's man page), +" which is a concatenation of direction Flags (Pull/Push) and of the +" operations seen above (New, Old, Upgrade/Renew, Gone/Delete, Flags, Full). +" Note that while "PullFull" exists, "PullAll" is not handled by mbsync's +" parser. +" Last but not least, match "\s+%(All of the above, except None) as multiple +" operations may be given to Sync. +syn match mbsCConfSyncOpt /\v( + \None + \|%(Pull|Push|New|Old|Upgrade|ReNew|Gone|Delete|Flags|Full|All + \|%(Pull|Push)%(New|Old|Upgrade|ReNew|Gone|Delete|Flags|Full)) + \%(\s+%(Pull|Push|New|Old|Upgrade|ReNew|Gone|Delete|Flags|Full|All + \|%(Pull|Push)%(New|Old|Upgrade|ReNew|Gone|Delete|Flags|Full)))*)$/ display contained syn match mbsCConfStSync '^Sync\s\+\ze.*$' contains=mbsCConfItemK contained nextgroup=mbsCConfSyncOpt transparent syn keyword mbsCConfManipOpt None Far Near Both contained syn match mbsCConfStCreate '^Create\s\+\ze.*$' contains=mbsCConfItemK contained nextgroup=mbsCConfManipOpt transparent diff --git a/runtime/syntax/monk.vim b/runtime/syntax/monk.vim index 3af810173a..22c91417a9 100644 --- a/runtime/syntax/monk.vim +++ b/runtime/syntax/monk.vim @@ -2,6 +2,7 @@ " Language: Monk (See-Beyond Technologies) " Maintainer: Mike Litherland " Last Change: 2012 Feb 03 by Thilo Six +" 2026 Apr 20 by Vim project: remove wrong oneline keyword #20018 " This syntax file is good enough for my needs, but others " may desire more features. Suggestions and bug reports @@ -33,8 +34,8 @@ syn case ignore " Fascist highlighting: everything that doesn't fit the rules is an error... -syn match monkError oneline ![^ \t()";]*! -syn match monkError oneline ")" +syn match monkError ![^ \t()";]*! +syn match monkError ")" " Quoted and backquoted stuff @@ -131,51 +132,51 @@ syn keyword monkFunc valid-integer? verify-type " using variables is a day's work for a trained secretary... " This is a useful lax approximation: -syn match monkNumber oneline "[-#+0-9.][-#+/0-9a-f@i.boxesfdl]*" -syn match monkError oneline ![-#+0-9.][-#+/0-9a-f@i.boxesfdl]*[^-#+/0-9a-f@i.boxesfdl \t()";][^ \t()";]*! +syn match monkNumber "[-#+0-9.][-#+/0-9a-f@i.boxesfdl]*" +syn match monkError ![-#+0-9.][-#+/0-9a-f@i.boxesfdl]*[^-#+/0-9a-f@i.boxesfdl \t()";][^ \t()";]*! -syn match monkOther oneline ![+-][ \t()";]!me=e-1 -syn match monkOther oneline ![+-]$! +syn match monkOther ![+-][ \t()";]!me=e-1 +syn match monkOther ![+-]$! " ... so that a single + or -, inside a quoted context, would not be " interpreted as a number (outside such contexts, it's a monkFunc) -syn match monkDelimiter oneline !\.[ \t()";]!me=e-1 -syn match monkDelimiter oneline !\.$! +syn match monkDelimiter !\.[ \t()";]!me=e-1 +syn match monkDelimiter !\.$! " ... and a single dot is not a number but a delimiter " Simple literals: -syn match monkBoolean oneline "#[tf]" -syn match monkError oneline !#[tf][^ \t()";]\+! +syn match monkBoolean "#[tf]" +syn match monkError !#[tf][^ \t()";]\+! -syn match monkChar oneline "#\\" -syn match monkChar oneline "#\\." -syn match monkError oneline !#\\.[^ \t()";]\+! -syn match monkChar oneline "#\\space" -syn match monkError oneline !#\\space[^ \t()";]\+! -syn match monkChar oneline "#\\newline" -syn match monkError oneline !#\\newline[^ \t()";]\+! +syn match monkChar "#\\" +syn match monkChar "#\\." +syn match monkError !#\\.[^ \t()";]\+! +syn match monkChar "#\\space" +syn match monkError !#\\space[^ \t()";]\+! +syn match monkChar "#\\newline" +syn match monkError !#\\newline[^ \t()";]\+! " This keeps all other stuff unhighlighted, except *stuff* and : -syn match monkOther oneline ,[a-z!$%&*/:<=>?^_~][-a-z!$%&*/:<=>?^_~0-9+.@]*, -syn match monkError oneline ,[a-z!$%&*/:<=>?^_~][-a-z!$%&*/:<=>?^_~0-9+.@]*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*, +syn match monkOther ,[a-z!$%&*/:<=>?^_~][-a-z!$%&*/:<=>?^_~0-9+.@]*, +syn match monkError ,[a-z!$%&*/:<=>?^_~][-a-z!$%&*/:<=>?^_~0-9+.@]*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*, -syn match monkOther oneline "\.\.\." -syn match monkError oneline !\.\.\.[^ \t()";]\+! +syn match monkOther "\.\.\." +syn match monkError !\.\.\.[^ \t()";]\+! " ... a special identifier -syn match monkConstant oneline ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[ \t()";],me=e-1 -syn match monkConstant oneline ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*$, -syn match monkError oneline ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*, +syn match monkConstant ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[ \t()";],me=e-1 +syn match monkConstant ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*$, +syn match monkError ,\*[-a-z!$%&*/:<=>?^_~0-9+.@]*\*[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*, -syn match monkConstant oneline ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[ \t()";],me=e-1 -syn match monkConstant oneline ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>$, -syn match monkError oneline ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*, +syn match monkConstant ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[ \t()";],me=e-1 +syn match monkConstant ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>$, +syn match monkError ,<[-a-z!$%&*/:<=>?^_~0-9+.@]*>[^-a-z!$%&*/:<=>?^_~0-9+.@ \t()";]\+[^ \t()";]*, " Monk input and output structures -syn match monkSyntax oneline "\(\~input\|\[I\]->\)[^ \t]*" -syn match monkFunc oneline "\(\~output\|\[O\]->\)[^ \t]*" +syn match monkSyntax "\(\~input\|\[I\]->\)[^ \t]*" +syn match monkFunc "\(\~output\|\[O\]->\)[^ \t]*" " Non-quoted lists, and strings: diff --git a/runtime/syntax/odin.vim b/runtime/syntax/odin.vim index efa107b79f..42f3767a43 100644 --- a/runtime/syntax/odin.vim +++ b/runtime/syntax/odin.vim @@ -4,14 +4,14 @@ vim9script # Language: Odin # Maintainer: Maxim Kim # Website: https://github.com/habamax/vim-odin -# Last Change: 2026-02-02 +# Last Change: 2026-05-28 if exists("b:current_syntax") finish endif -syntax keyword odinKeyword using transmute cast auto_cast distinct opaque where dynamic -syntax keyword odinKeyword struct enum union const bit_field bit_set +syntax keyword odinKeyword using transmute cast auto_cast distinct where dynamic +syntax keyword odinKeyword struct enum union bit_field bit_set syntax keyword odinKeyword package proc map import export foreign syntax keyword odinKeyword size_of offset_of type_info_of typeid_of type_of align_of syntax keyword odinKeyword return defer diff --git a/runtime/syntax/org.vim b/runtime/syntax/org.vim index f4e938f9ee..75264be5d4 100644 --- a/runtime/syntax/org.vim +++ b/runtime/syntax/org.vim @@ -3,6 +3,7 @@ " Previous Maintainer: Luca Saccarola " Maintainer: This runtime file is looking for a new maintainer. " Last Change: 2025 Aug 05 +" 2026 Apr 09: Link to generic Bold/Italic groups " " Reference Specification: Org mode manual " GNU Info: `$ info Org` @@ -18,17 +19,17 @@ syn case ignore " Bold syn region orgBold matchgroup=orgBoldDelimiter start="\(^\|[- '"({\]]\)\@<=\*\ze[^ ]" end="^\@!\*\([^\k\*]\|$\)\@=" keepend -hi def link orgBold markdownBold +hi def link orgBold Bold hi def link orgBoldDelimiter orgBold " Italic syn region orgItalic matchgroup=orgItalicDelimiter start="\(^\|[- '"({\]]\)\@<=\/\ze[^ ]" end="^\@!\/\([^\k\/]\|$\)\@=" keepend -hi def link orgItalic markdownItalic +hi def link orgItalic Italic hi def link orgItalicDelimiter orgItalic " Strikethrogh syn region orgStrikethrough matchgroup=orgStrikethroughDelimiter start="\(^\|[ '"({\]]\)\@<=+\ze[^ ]" end="^\@!+\([^\k+]\|$\)\@=" keepend -hi def link orgStrikethrough markdownStrike +hi def orgStrikethrough term=strikethrough cterm=strikethrough gui=strikethrough hi def link orgStrikethroughDelimiter orgStrikethrough " Underline diff --git a/runtime/syntax/pilrc.vim b/runtime/syntax/pilrc.vim index f0e5f9bbc7..afa527aeea 100644 --- a/runtime/syntax/pilrc.vim +++ b/runtime/syntax/pilrc.vim @@ -1,7 +1,8 @@ " Vim syntax file " Language: pilrc - a resource compiler for Palm OS development " Maintainer: Brian Schau -" Last change: 2003 May 11 +" Last Change: 2003 May 11 +" 2026 May 30 by Vim project: Fix typo #20369 " Available on: http://www.schau.com/pilrcvim/pilrc.vim " quit when a syntax file was already loaded @@ -72,7 +73,7 @@ syn keyword pilrcType WARNING WEEKSTARTDAY " Country syn keyword pilrcCountry Australia Austria Belgium Brazil Canada Denmark -syn keyword pilrcCountry Finland France Germany HongKong Iceland Indian +syn keyword pilrcCountry Finland France Germany HongKong Iceland India syn keyword pilrcCountry Indonesia Ireland Italy Japan Korea Luxembourg Malaysia syn keyword pilrcCountry Mexico Netherlands NewZealand Norway Philippines syn keyword pilrcCountry RepChina Singapore Spain Sweden Switzerland Thailand diff --git a/runtime/syntax/qml.vim b/runtime/syntax/qml.vim index d6f2abec37..e395d83c2a 100644 --- a/runtime/syntax/qml.vim +++ b/runtime/syntax/qml.vim @@ -4,6 +4,7 @@ " Maintainer: Chase Knowlden " Changes: `git log` is your friend " Last Change: 2023 Aug 16 +" 2026 Apr 16 by Vim project: handle ?. optional chaining #19988 " " This file is bassed on the original work done by Warwick Allison " whose did about 99% of the work here. @@ -44,6 +45,7 @@ syn match qmlObjectLiteralType "[A-Za-z][_A-Za-z0-9]*\s*\({\)\@=" syn region qmlTernaryColon start="?" end=":" contains=@qmlExpr,qmlBraces,qmlParens,qmlLineComment syn match qmlBindingProperty "\<[A-Za-z][_A-Za-z.0-9]*\s*:" syn match qmlNullishCoalescing "??" +syn match qmlOptionalChaining "?\." syn keyword qmlConditional if else switch syn keyword qmlRepeat while for do in diff --git a/runtime/syntax/sgf.vim b/runtime/syntax/sgf.vim new file mode 100644 index 0000000000..48ee1ba89e --- /dev/null +++ b/runtime/syntax/sgf.vim @@ -0,0 +1,41 @@ +" Vim syntax file +" Language: Smart Game Format +" Maintainer: Borys Lykah +" Last Change: 2026 May 30 + +" Quit when a syntax file was already loaded +if exists("b:current_syntax") + finish +endif + +syn match sgfDelimiter "[();]" + +syn keyword sgfMoveProp B W nextgroup=sgfValue skipwhite +syn keyword sgfSetupProp AB AE AW PL nextgroup=sgfValue skipwhite +syn keyword sgfMarkupProp AR CR DD DM FG GB GW HO LB LN MA SL SQ TR UC VW nextgroup=sgfValue skipwhite +syn keyword sgfRootProp AP CA FF GM ST SZ nextgroup=sgfValue skipwhite +syn keyword sgfGameInfoProp AN BR BT CP DT EV GC GN HA KM ON OT PB PC PW RE RO RU SO TM US WR WT nextgroup=sgfValue skipwhite +syn keyword sgfCommentProp C nextgroup=sgfCommentValue skipwhite + +syn match sgfProperty "\<[A-Za-z]\+\ze\s*\[" nextgroup=sgfValue skipwhite + +syn match sgfEscape "\\." contained +syn region sgfValue contained matchgroup=sgfBracket start="\[" end="\]" skip="\\\\\|\\\]" contains=sgfEscape keepend nextgroup=sgfValue skipwhite +syn region sgfCommentValue contained matchgroup=sgfBracket start="\[" end="\]" skip="\\\\\|\\\]" contains=sgfEscape,@Spell keepend nextgroup=sgfCommentValue skipwhite + +hi def link sgfDelimiter Delimiter +hi def link sgfMoveProp Statement +hi def link sgfSetupProp Type +hi def link sgfMarkupProp Identifier +hi def link sgfRootProp PreProc +hi def link sgfGameInfoProp Label +hi def link sgfCommentProp Comment +hi def link sgfProperty Identifier +hi def link sgfBracket Delimiter +hi def link sgfEscape SpecialChar +hi def link sgfValue String +hi def link sgfCommentValue Comment + +let b:current_syntax = "sgf" + +" vim: ts=8 diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim index 05eb488d53..044f2a9e3e 100644 --- a/runtime/syntax/sh.vim +++ b/runtime/syntax/sh.vim @@ -3,28 +3,7 @@ " Maintainer: This runtime file is looking for a new maintainer. " Previous Maintainers: Charles E. Campbell " Lennart Schultz -" Last Change: 2024 Mar 04 by Vim Project {{{1 -" 2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> improved bracket expressions, #15941 -" 2025 Jan 06 add $PS0 to bashSpecialVariables #16394 -" 2025 Jan 18 add bash coproc, remove duplicate syn keywords #16467 -" 2025 Mar 21 update shell capability detection #16939 -" 2025 Apr 03 command substitution opening paren at EOL #17026 -" 2025 Apr 10 improve shell detection #17084 -" 2025 Apr 29 match escaped chars in test operands #17221 -" 2025 May 06 improve single-quote string matching in parameter expansions -" 2025 May 06 match KornShell compound arrays -" 2025 May 10 improve wildcard character class lists -" 2025 May 21 improve supported KornShell features -" 2025 Jun 16 change how sh_fold_enabled is reset #17557 -" 2025 Jul 18 properly delete :commands #17785 -" 2025 Aug 23 bash: add support for ${ cmd;} and ${|cmd;} #18084 -" 2025 Sep 23 simplify ksh logic, update sh statements #18355 -" 2026 Jan 15 highlight command switches that contain a digit -" 2026 Feb 11 improve support for KornShell function names and variables -" 2026 Feb 15 improve comment handling #19414 -" 2026 Mar 23 improve matching of function definitions #19638 -" 2026 Apr 02 improve matching of function definitions #19849 -" }}} +" Last Change: 2026 May 17 by Vim Project " Version: 208 " Former URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH " For options and settings, please use: :help ft-sh-syntax @@ -279,7 +258,7 @@ syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial syn cluster shDerefVarList contains=shDerefOffset,shDerefOp,shDerefVarArray,shDerefOpError syn cluster shEchoList contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote syn cluster shExprList1 contains=shBracketExpr,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq -syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest +syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest,shFunctionNameError syn cluster shFunctionCmds contains=shFor,shCaseEsac,shIf,shRepeat,shDblBrace,shDblParen if exists("b:is_ksh88") || exists("b:is_mksh") " Offer "shFunctionCmds" as is. @@ -305,7 +284,7 @@ if exists("b:is_kornshell") || exists("b:is_bash") endif syn cluster shPPSLeftList contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable syn cluster shPPSRightList contains=shDeref,shDerefSimple,shEscape,shPosnParm -syn cluster shSubShList contains=shBracketExpr,@shCommandSubList,shCommandSubBQ,shSubshare,shValsub,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator +syn cluster shSubShList contains=shBracketExpr,@shCommandSubList,shCommandSubBQ,shSubshare,shValsub,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator,shFunctionNameError syn cluster shTestList contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr syn cluster shNoZSList contains=shSpecialNoZS syn cluster shForList contains=shTestOpr,shNumber,shDerefSimple,shDeref,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shArithmetic @@ -664,40 +643,48 @@ endif ShFoldFunctions syn region shFunctionExpr matchgroup=shFunctionExprRegion start="{" end="}" contains=@shFunctionList contained skipwhite skipnl nextgroup=shQuickComment ShFoldFunctions syn region shFunctionSubSh matchgroup=shFunctionSubShRegion start="(" end=")" contains=@shFunctionList contained skipwhite skipnl nextgroup=shQuickComment +syn match shFunctionParens "()" contained + if exists("b:is_bash") syn keyword shFunctionKey coproc - syn match shFunctionCmdOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionCmdTwo "\%#=1\%(\%(\<\k\+\>\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*\%(\<\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" contained skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionTwo "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh - syn match shFunctionFour "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(\%(()\ze\)\=\)\@>\_s*((\@!" contained skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionCmdOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionCmdTwo "\%#=1\%(\%(\<\k\+\>\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*\%(\<\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" contained skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionTwo "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionThree "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens + syn match shFunctionFour "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(\%(()\ze\)\=\)\@>\_s*((\@!" contained skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens + " Claim empty array assignments. + syn match shArrayEmptyDecl "\%#=1\ze\%(\<\h\w*=\)\@>()" transparent nextgroup=shVariable + + if !exists("g:sh_no_error") + syn match shFunctionNameError "\%#=1\%(\%(\<\h\w*\)\@>=\)\%(\%(\w\+\)\@>=\=\)\+()" skipwhite skipnl nextgroup=shExpr,shSubSh + endif elseif exists("b:is_ksh88") " AT&T ksh88 - syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr + syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens syn match shFunctionTwo "\<\h\w*\>\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens elseif exists("b:is_mksh") " MirBSD ksh is the wild west of absurd and abstruse function names... - syn match shFunctionCmdOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionTwo "\%#=1\%(\%(\<\w\+\|[@!+.%,:-]\+\)*[-A-Za-z_.%,0-9:]\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionCmdOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionTwo "\%#=1\%(\%(\<\w\+\|[@!+.%,:-]\+\)*[-A-Za-z_.%,0-9:]\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionThree "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens elseif exists("b:is_kornshell") " ksh93 - syn match shFunctionCmdOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr + syn match shFunctionCmdOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens syn match shFunctionTwo "\%(\<\h\+\|\.\)[A-Za-z_.0-9]*\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionThree "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens syn match shNamespaceOne "\<\h\w*\>\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr else - syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionCmdTwo "\<\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" contained skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionTwo "\<\h\w*\>\s*()\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*(" skipwhite skipnl nextgroup=shFunctionSubSh - syn match shFunctionFour "\<\h\w*\>\s*()\ze\_s*(" contained skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionCmdTwo "\<\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" contained skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionTwo "\<\h\w*\>\s*()\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*(" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens + syn match shFunctionFour "\<\h\w*\>\s*()\ze\_s*(" contained skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens endif if !exists("g:sh_no_error") @@ -751,13 +738,15 @@ endif if exists("b:is_bash") syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOffset syn match shDerefVar contained "{\@<=!\h\w*" nextgroup=@shDerefVarList + syn match shDerefSpecial contained "\({!\)\@<=[[:alnum:]*#@_]\+" nextgroup=@shDerefVarList,shDerefOp endif if (exists("b:is_kornshell") && !exists("b:is_ksh88")) syn match shDerefVar contained "{\@<=!\h\w*[[:alnum:]_.]*" nextgroup=@shDerefVarList + syn match shDerefSpecial contained "\({!\)\@<=[[:alnum:]*#@_]\+" nextgroup=@shDerefVarList,shDerefOp endif syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOffset,shDerefOpError -syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp +syn match shDerefSpecial contained "\({[#]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp syn match shDerefVar contained "{\@<=\h\w*" nextgroup=@shDerefVarList syn match shDerefVar contained '\d' nextgroup=@shDerefVarList if exists("b:is_kornshell") || exists("b:is_posix") @@ -964,6 +953,9 @@ if !exists("skip_sh_syntax_inits") hi def link shInError Error hi def link shParenError Error hi def link shTestError Error + if exists("b:is_bash") + hi def link shFunctionNameError Error + endif if exists("b:is_kornshell") || exists("b:is_posix") hi def link shDTestError Error endif @@ -984,6 +976,7 @@ if !exists("skip_sh_syntax_inits") hi def link shCtrlSeq Special hi def link shExprRegion Delimiter hi def link shFunctionKey Keyword + hi def link shFunctionParens Delimiter hi def link shFunctionOne Function hi def link shFunctionTwo shFunctionOne hi def link shFunctionThree shFunctionOne diff --git a/runtime/syntax/shared/debversions.vim b/runtime/syntax/shared/debversions.vim index 2548ddd350..e6982803ae 100644 --- a/runtime/syntax/shared/debversions.vim +++ b/runtime/syntax/shared/debversions.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: Debian version information " Maintainer: Debian Vim Maintainers -" Last Change: 2026 Jan 01 +" Last Change: 2026 May 21 " URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/syntax/shared/debversions.vim let s:cpo = &cpo @@ -12,7 +12,7 @@ let g:debSharedSupportedVersions = [ \ 'oldstable', 'stable', 'testing', 'unstable', 'experimental', 'sid', 'rc-buggy', \ 'bookworm', 'trixie', 'forky', 'duke', \ - \ 'jammy', 'noble', 'questing', 'resolute', + \ 'jammy', 'noble', 'questing', 'resolute', 'stonking', \ 'devel' \ ] " Historic version names, no longer under standard support diff --git a/runtime/syntax/shared/typescriptcommon.vim b/runtime/syntax/shared/typescriptcommon.vim index 9a909c6755..1cb1740f8e 100644 --- a/runtime/syntax/shared/typescriptcommon.vim +++ b/runtime/syntax/shared/typescriptcommon.vim @@ -306,13 +306,13 @@ syntax keyword typescriptRepeat do while for nextgroup=typescript syntax keyword typescriptRepeat for nextgroup=typescriptLoopParen,typescriptAsyncFor skipwhite skipempty syntax keyword typescriptBranch break continue containedin=typescriptBlock syntax keyword typescriptCase case nextgroup=@typescriptPrimitive skipwhite containedin=typescriptBlock -syntax keyword typescriptDefault default containedin=typescriptBlock nextgroup=@typescriptValue,typescriptClassKeyword,typescriptInterfaceKeyword skipwhite oneline +syntax keyword typescriptDefault default containedin=typescriptBlock nextgroup=@typescriptValue,typescriptClassKeyword,typescriptInterfaceKeyword skipwhite syntax keyword typescriptStatementKeyword with syntax keyword typescriptStatementKeyword yield skipwhite nextgroup=@typescriptValue containedin=typescriptBlock syntax keyword typescriptTry try syntax keyword typescriptExceptions throw finally -syntax keyword typescriptExceptions catch nextgroup=typescriptCall skipwhite skipempty oneline +syntax keyword typescriptExceptions catch nextgroup=typescriptCall skipwhite skipempty syntax keyword typescriptDebugger debugger syntax keyword typescriptAsyncFor await nextgroup=typescriptLoopParen skipwhite skipempty contained @@ -1766,9 +1766,9 @@ endif " patch " patch for generated code syntax keyword typescriptGlobal Promise - \ nextgroup=typescriptGlobalPromiseDot,typescriptFuncCallArg,typescriptTypeArguments oneline + \ nextgroup=typescriptGlobalPromiseDot,typescriptFuncCallArg,typescriptTypeArguments syntax keyword typescriptGlobal Map WeakMap - \ nextgroup=typescriptGlobalPromiseDot,typescriptFuncCallArg,typescriptTypeArguments oneline + \ nextgroup=typescriptGlobalPromiseDot,typescriptFuncCallArg,typescriptTypeArguments syntax keyword typescriptConstructor contained constructor \ nextgroup=@typescriptCallSignature diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_00.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_00.dump new file mode 100644 index 0000000000..d3fae329b8 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_00.dump @@ -0,0 +1,20 @@ +>#+0#0000e05#ffffff0| +0#0000000&@73 +| +0#0000e05&@3|A|l|g|o|l| |6|8| |p|r|e|l|u|d|e| |i|d|e|n|t|i|f|i|e|r| |f|r|o|m| |t|h|e| |G|e|n|i|e| |s|o|u|r|c|e| |c|o|d|e| |f|i|l|e|s|.| +0#0000000&@9 +| +0#0000e05&@3| +0#0000000&@70 +| +0#0000e05&@3|P|r|o|v|i|d|e|d| |a|s| |a| |b|a|s|e| |t|o| |v|e|r|i|f|y| |t|h|e| |c|o|r@1|e|c|t| |s|y|n|t|a|x| |h|i|g|h|l|i|g|h|t|i|n|g| +0#0000000&@10 +| +0#0000e05&@3|o|f| |t|h|e| |a|l|g|o|l|6|8|.|v|i|m| |s|y|n|t|a|x| |f|i|l|e| |f|o|r| |t|h|e| |V|i|m| |e|d|i|t|o|r|.| +0#0000000&@20 +| +0#0000e05&@3| +0#0000000&@70 +| +0#0000e05&@3|T|h|e|r|e|'|s| |f|o|u|r| |s|e|c|t|i|o|n|s|,| |e|a|c|h| |r|e|p|r|e|s|e|n|t|i|n|g| |a|n| |o|r|i|g|i|n|a|l| |f|i|l|e|,| +0#0000000&@12 +| +0#0000e05&@3|t|h|a|t| |a|r|e| |e|n|c|l|o|s|e|d| |i|n| |t|h|e| |U|n|i|x|-|'|m|o|r|e|'| |f|o|r|m| |t|o| |s|t|a|n|d| |o|u|t|.| +0#0000000&@15 +| +0#0000e05&@3| +0#0000000&@70 +| +0#0000e05&@3|S|o|m|e| |i|n|f|o|r|m|a|l| |c|o|m@1|e|n|t|s| |f|r|o|m| |t|h|e| |s|o|u|r|c|e| |c|o|d|e| |l|e|f|t| |i|n|t|a|c|t| |a|s| +0#0000000&@12 +| +0#0000e05&@3|a| |c|o|m@1|e|n|t| |i|n| |A|l|g|o|l| |6|8| |s|y|n|t|a|x|.| +0#0000000&@41 +| +0#0000e05&@3| +0#0000000&@70 +| +0#0000e05&@3|D|e|p|e|n|d|i|n|g| |o|n| |t|h|e| |l|a|n|g|u|a|g|e| |c|o|n|t|e|x|t| |t|h|e|r|e|'|s| |d|u|p|l|i|c|a|t|e|s| |i|n| |t|h|e| +0#0000000&@11 +| +0#0000e05&@3|l|i|s|t|,| |t|h|a|t| |a|r|e| |k|e|p|t| |f|o|r| |c|l|a|r|i|t|y| |g|i|v|e|n| |t|h|e| |a|s@1|o|c|i|a|t|e|d| |i|n|f|o|r|m|a|l| +0#0000000&@9 +| +0#0000e05&@3|c|o|m@1|e|n|t| |a|s@1|o|c|i|a|t|e|d| |w|i|t|h| |t|h|e|m|.| +0#0000000&@41 +| +0#0000e05&@3| +0#0000000&@70 +| +0#0000e05&@3|S|o|m|e| |e|n|t|r|i|e|s| |d|e|l|i|b|e|r|a|t|e|l|y| |c|o|n|t|a|i|n| |t|w|o| |i|d|e|n|t|i|f|i|e|r| |v|a|r|i|a|n|t|s| |t|h|a|t| +0#0000000&@8 +| +0#0000e05&@3|m|a|y| |b|e| |u|s|e|d| |a|s| |a|l|t|e|r|n|a|t|i|v|e| |f|o|r|m| |i|n| |a|n| |A|l|g|o|l| |6|8| |G|e|n|i|e| |p|r|o|g|r|a|m|.| +0#0000000&@9 +| +0#0000e05&@3| +0#0000000&@70 +@57|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_01.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_01.dump new file mode 100644 index 0000000000..b6eaacce62 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_01.dump @@ -0,0 +1,20 @@ +| +0#0000e05#ffffff0@3|l|i|s|t|,| |t|h|a|t| |a|r|e| |k|e|p|t| |f|o|r| |c|l|a|r|i|t|y| |g|i|v|e|n| |t|h|e| |a|s@1|o|c|i|a|t|e|d| |i|n|f|o|r|m|a|l| +0#0000000&@9 +| +0#0000e05&@3|c|o|m@1|e|n|t| |a|s@1|o|c|i|a|t|e|d| |w|i|t|h| |t|h|e|m|.| +0#0000000&@41 +| +0#0000e05&@3| +0#0000000&@70 +| +0#0000e05&@3|S|o|m|e| |e|n|t|r|i|e|s| |d|e|l|i|b|e|r|a|t|e|l|y| |c|o|n|t|a|i|n| |t|w|o| |i|d|e|n|t|i|f|i|e|r| |v|a|r|i|a|n|t|s| |t|h|a|t| +0#0000000&@8 +| +0#0000e05&@3|m|a|y| |b|e| |u|s|e|d| |a|s| |a|l|t|e|r|n|a|t|i|v|e| |f|o|r|m| |i|n| |a|n| |A|l|g|o|l| |6|8| |G|e|n|i|e| |p|r|o|g|r|a|m|.| +0#0000000&@9 +| +0#0000e05&@2> | +0#0000000&@70 +| +0#0000e05&@3|T|h|e| |i|d|e|n|t|i|f|i|e|r|s| |a|r|e| |p|r|e|s|e|n|t|e|d| |i|n| |t|w|o| |v|a|r|i|a|n|t|s| |s|e|p|a|r|a|t|e|d| |b|y| |a| +0#0000000&@10 +| +0#0000e05&@3|t|a|b|u|l|a|t|o|r|;| |f|i|r|s|t| |w|i|t|h| |s|p|a|c|e|s|,| |t|h|e|n| |i|n| |c|a|n|o|n|i|c|a|l| |f|o|r|m| |w|i|t|h|o|u|t| +0#0000000&@10 +| +0#0000e05&@3|s|p|a|c|e|s|.| |V|a|r|i|a|n|t|s| |w|i|t|h| |s|p|a|c|e|s| |a|r|e| |s|u|p@1|o|r|t|e|d| |b|y| |t|h|e| |V|i|m| |s|y|n|t|a|x| +0#0000000&@10 +| +0#0000e05&@3|f|i|l|e| |a|s| |t|h|e| |A|l|g|o|l| |6|8| |l|a|n|g|u|a|g|e| |d|o|e|s|.| +0#0000000&@35 +| +0#0000e05&@3|B|u|t| |n|o|t|e| |t|h|a|t| |w|h|i|l|e| |A|l|g|o|l| |6|8| |a|l@1|o|w|s| |a|r|b|i|t|r|a|r|y| |s|p|a|c|i|n|g| |w|i|t|h|i|n| +0#0000000&@10 +| +0#0000e05&@3|i|d|e|n|t|i|f|i|e|r|s| |-| |e|v|e|n| |a|s| |e|x|t|r|e|m|e| |a|s| |w|r|i|t|i|n|g| |o|n|e| |c|h|a|r|a|c|t|e|r| |p|e|r| +0#0000000&@12 +| +0#0000e05&@3|l|i|n|e|!| |-| |t|h|e| |V|i|m| |s|y|n|t|a|x| |f|i|l|e| |f|o|r| |A|l|g|o|l| |6|8| |h|a|d| |d|e|l|i|b|e|r|a|t|e|l|y| +0#0000000&@13 +| +0#0000e05&@3|b|e@1|n| |d|e|f|i|n|e|d| |i|n| |a| |w|a|y| |r|e|s|t|r|i|c|t|i|n|g| |t|h|e| |h|i|g|h|l|i|g|h|t|e|d| |o|p|t|i|o|n|s|;| +0#0000000&@12 +| +0#0000e05&@3|s|p|a|c|i|n|g| |c|a|n| |u|s|u|a|l@1|y| |b|e| |i|n|s|e|r|t|e|d| |w|h|e|r|e| |"|n|a|t|u|r|a|l| |w|o|r|d|s|"| |w|o|u|l|d| +0#0000000&@11 +| +0#0000e05&@3|a|l@1|o|w| |a| |s|e|p|a|r|a|t|i|o|n| |(|s|a|y| |f|o|r| |'|i|n|t|w|i|d|t|h|'| |y|o|u| |m|a|y| |w|r|i|t|e|,| |e|.|g|.|,| +0#0000000&@11 +| +0#0000e05&@3|'|i|n|t| |w|i|d|t|h|'| |b|u|t| |n|o|t| |'|i|n|t| |w|i|d| |t|h|'|;| |t|h|e| |l|a|t@1|e|r| |w|o|u|l|d| |n|o|t| |g|e|t| +0#0000000&@12 +| +0#0000e05&@3|h|i|g|h|l|i|g|h|t|e|d|)|.| +0#0000000&@57 +| +0#0000e05&@3| +0#0000000&@70 +@57|1|9|,|4| @10|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_02.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_02.dump new file mode 100644 index 0000000000..8fdc1e0d27 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_02.dump @@ -0,0 +1,20 @@ +| +0#0000e05#ffffff0@3| +0#0000000&@70 +| +0#0000e05&@3|M|o|d|e|l|i|n|e|s| |a|r|e| |s|e|t| |t|o| |s|i|m|p|l|y| |i|n|s|p|e|c|t| |t|h|e| |c|o|r@1|e|c|t| |h|i|g|h|l|i|g|h|t|i|n|g| +0#0000000&@10 +| +0#0000e05&@3|i|n| |t|h|i|s| |f|i|l|e|.| +0#0000000&@57 +| +0#0000e05&@3| +0#0000000&@70 +| +0#0000e05&@3|J|a|n|i|s| |P|a|p|a|n|a|g|n|o|u|,| |2|0|2|6|-|0|5|-|1|9| +0#0000000&@42 +>#+0#0000e05&| +0#0000000&@73 +@75 +|#+0#0000e05&|:@12| +0#0000000&@60 +|p+0#0000e05&|r|e|l|u|d|e|.|c| +0#0000000&@65 +|:+0#0000e05&@12|#| +0#0000000&@60 +@75 +|#+0#0000e05&| |P|r|i|m|i|t|i|v|e| |A|6|8| |m|o|i|d|s|.| |#| +0#0000000&@50 +@2|V+0#00e0003&|O|I|D| +0#0000000&@41|V+0#00e0003&|O|I|D| +0#0000000&@22 +|#+0#0000e05&| |S|t|a|n|d|a|r|d| |p|r|e|c|i|s|i|o|n|.| |#| +0#0000000&@51 +@2|I+0#00e0003&|N|T| +0#0000000&@42|I+0#00e0003&|N|T| +0#0000000&@23 +@2|R+0#00e0003&|E|A|L| +0#0000000&@41|R+0#00e0003&|E|A|L| +0#0000000&@22 +@2|C+0#00e0003&|O|M|P|L|E|X| +0#0000000&@38|C+0#00e0003&|O|M|P|L|E|X| +0#0000000&@19 +@2|C+0#00e0003&|O|M|P|L| +0#0000000&@40|C+0#00e0003&|O|M|P|L| +0#0000000&@21 +@2|B+0#00e0003&|I|T|S| +0#0000000&@41|B+0#00e0003&|I|T|S| +0#0000000&@22 +@57|3|7|,|1| @10|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_03.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_03.dump new file mode 100644 index 0000000000..635879786c --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_03.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|B+0#00e0003&|I|T|S| +0#0000000&@41|B+0#00e0003&|I|T|S| +0#0000000&@22 +@2|B+0#00e0003&|Y|T|E|S| +0#0000000&@40|B+0#00e0003&|Y|T|E|S| +0#0000000&@21 +|#+0#0000e05&| |M|u|l|t|i|p|l|e| |p|r|e|c|i|s|i|o|n|.| |#| +0#0000000&@51 +@2|I+0#00e0003&|N|T| +0#0000000&@42|I+0#00e0003&|N|T| +0#0000000&@23 +@2|R+0#00e0003&|E|A|L| +0#0000000&@41|R+0#00e0003&|E|A|L| +0#0000000&@22 +@2>C+0#00e0003&|O|M|P|L|E|X| +0#0000000&@38|C+0#00e0003&|O|M|P|L|E|X| +0#0000000&@19 +@2|C+0#00e0003&|O|M|P|L| +0#0000000&@40|C+0#00e0003&|O|M|P|L| +0#0000000&@21 +@2|B+0#00e0003&|I|T|S| +0#0000000&@41|B+0#00e0003&|I|T|S| +0#0000000&@22 +@2|B+0#00e0003&|Y|T|E|S| +0#0000000&@40|B+0#00e0003&|Y|T|E|S| +0#0000000&@21 +@2|R+0#00e0003&|E|A|L| +0#0000000&@41|R+0#00e0003&|E|A|L| +0#0000000&@22 +@2|I+0#00e0003&|N|T| +0#0000000&@42|I+0#00e0003&|N|T| +0#0000000&@23 +@2|C+0#00e0003&|O|M|P|L|E|X| +0#0000000&@38|C+0#00e0003&|O|M|P|L|E|X| +0#0000000&@19 +@2|C+0#00e0003&|O|M|P|L| +0#0000000&@40|C+0#00e0003&|O|M|P|L| +0#0000000&@21 +@2|B+0#00e0003&|I|T|S| +0#0000000&@41|B+0#00e0003&|I|T|S| +0#0000000&@22 +|#+0#0000e05&| |O|t|h|e|r|.| |#| +0#0000000&@64 +@2|B+0#00e0003&|O@1|L| +0#0000000&@41|B+0#00e0003&|O@1|L| +0#0000000&@22 +@2|C+0#00e0003&|H|A|R| +0#0000000&@41|C+0#00e0003&|H|A|R| +0#0000000&@22 +@2|S+0#00e0003&|T|R|I|N|G| +0#0000000&@39|S+0#00e0003&|T|R|I|N|G| +0#0000000&@20 +@2|F+0#00e0003&|I|L|E| +0#0000000&@41|F+0#00e0003&|I|L|E| +0#0000000&@22 +@57|5@1|,|3| @10|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_04.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_04.dump new file mode 100644 index 0000000000..b2cb836327 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_04.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|F+0#00e0003&|I|L|E| +0#0000000&@41|F+0#00e0003&|I|L|E| +0#0000000&@22 +@2|C+0#00e0003&|H|A|N@1|E|L| +0#0000000&@38|C+0#00e0003&|H|A|N@1|E|L| +0#0000000&@19 +@2|P+0#00e0003&|I|P|E| +0#0000000&@41|P+0#00e0003&|I|P|E| +0#0000000&@22 +@2|F+0#00e0003&|O|R|M|A|T| +0#0000000&@39|F+0#00e0003&|O|R|M|A|T| +0#0000000&@20 +@2|S+0#00e0003&|E|M|A| +0#0000000&@41|S+0#00e0003&|E|M|A| +0#0000000&@22 +@2>S+0#00e0003&|O|U|N|D| +0#0000000&@40|S+0#00e0003&|O|U|N|D| +0#0000000&@21 +|#+0#0000e05&| |I|d|e|n|t|i|f|i|e|r|s|.| |#| +0#0000000&@58 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |p|i|;+0#0000000&| @1|q+0#00e0e07&|p|i|;+0#0000000&| @26|l+0#00e0e07&|o|n|g|l|o|n|g|p|i|;+0#0000000&| @1|q+0#00e0e07&|p|i| +0#0000000&@10 +|#+0#0000e05&| |#| +0#0000000&@71 +@2|b+0#00e0e07&|i|t|s| |l|e|n|g|t|h|s|;+0#0000000&| @32|b+0#00e0e07&|i|t|s|l|e|n|g|t|h|s| +0#0000000&@15 +@2|b+0#00e0e07&|i|t|s| |s|h|o|r|t|h|s|;+0#0000000&| @32|b+0#00e0e07&|i|t|s@1|h|o|r|t|h|s| +0#0000000&@15 +@2|b+0#00e0e07&|i|t|s| |w|i|d|t|h|;+0#0000000&| @34|b+0#00e0e07&|i|t|s|w|i|d|t|h| +0#0000000&@17 +@2|b+0#00e0e07&|y|t|e|s| |l|e|n|g|t|h|s|;+0#0000000&| @31|b+0#00e0e07&|y|t|e|s|l|e|n|g|t|h|s| +0#0000000&@14 +@2|b+0#00e0e07&|y|t|e|s| |s|h|o|r|t|h|s|;+0#0000000&| @31|b+0#00e0e07&|y|t|e|s@1|h|o|r|t|h|s| +0#0000000&@14 +@2|b+0#00e0e07&|y|t|e|s| |w|i|d|t|h|;+0#0000000&| @33|b+0#00e0e07&|y|t|e|s|w|i|d|t|h| +0#0000000&@16 +@2|c+0#00e0e07&|o|m|p|l| |l|e|n|g|t|h|s|;+0#0000000&| @31|c+0#00e0e07&|o|m|p|l@1|e|n|g|t|h|s| +0#0000000&@14 +@2|c+0#00e0e07&|o|m|p|l| |s|h|o|r|t|h|s|;+0#0000000&| @31|c+0#00e0e07&|o|m|p|l|s|h|o|r|t|h|s| +0#0000000&@14 +@2|e+0#00e0e07&|x|p| |w|i|d|t|h|;+0#0000000&| @35|e+0#00e0e07&|x|p|w|i|d|t|h| +0#0000000&@18 +@2|i+0#00e0e07&|n|f|i|n|i|t|y|;+0#0000000&| @36|i+0#00e0e07&|n|f|i|n|i|t|y| +0#0000000&@18 +@57|7|3|,|3| @10|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_05.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_05.dump new file mode 100644 index 0000000000..5184f646c1 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_05.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|i+0#00e0e07&|n|f|i|n|i|t|y|;+0#0000000&| @36|i+0#00e0e07&|n|f|i|n|i|t|y| +0#0000000&@18 +@2|i+0#00e0e07&|n|f|;+0#0000000&| @41|i+0#00e0e07&|n|f| +0#0000000&@23 +@2|i+0#00e0e07&|n|t| |l|e|n|g|t|h|s|;+0#0000000&| @33|i+0#00e0e07&|n|t|l|e|n|g|t|h|s| +0#0000000&@16 +@2|i+0#00e0e07&|n|t| |s|h|o|r|t|h|s|;+0#0000000&| @33|i+0#00e0e07&|n|t|s|h|o|r|t|h|s| +0#0000000&@16 +@2|i+0#00e0e07&|n|t| |w|i|d|t|h|;+0#0000000&| @35|i+0#00e0e07&|n|t|w|i|d|t|h| +0#0000000&@18 +@2>l+0#00e0e07&|o|n|g| |b|i|t|s| |w|i|d|t|h|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|b|i|t|s|w|i|d|t|h| +0#0000000&@13 +@2|l+0#00e0e07&|o|n|g| |b|y|t|e|s| |w|i|d|t|h|;+0#0000000&| @28|l+0#00e0e07&|o|n|g|b|y|t|e|s|w|i|d|t|h| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |e|x|p| |w|i|d|t|h|;+0#0000000&| @30|l+0#00e0e07&|o|n|g|e|x|p|w|i|d|t|h| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |i|n|t| |w|i|d|t|h|;+0#0000000&| @30|l+0#00e0e07&|o|n|g|i|n|t|w|i|d|t|h| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |e|x|p|w|i|d|t|h|;+0#0000000&| @26|l+0#00e0e07&|o|n|g|l|o|n|g|e|x|p|w|i|d|t|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |i|n|f|i|n|i|t|y|;+0#0000000&| @26|l+0#00e0e07&|o|n|g|l|o|n|g|i|n|f|i|n|i|t|y| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |i|n|f|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|l|o|n|g|i|n|f| +0#0000000&@15 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |i|n|t|w|i|d|t|h|;+0#0000000&| @26|l+0#00e0e07&|o|n|g|l|o|n|g|i|n|t|w|i|d|t|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |m|a|x|i|n|t|;+0#0000000&| @28|l+0#00e0e07&|o|n|g|l|o|n|g|m|a|x|i|n|t| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |m|a|x|r|e|a|l|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|l|o|n|g|m|a|x|r|e|a|l| +0#0000000&@11 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |m|i|n|i|n|f|;+0#0000000&| @28|l+0#00e0e07&|o|n|g|l|o|n|g|m|i|n|i|n|f| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |m|i|n|r|e|a|l|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|l|o|n|g|m|i|n|r|e|a|l| +0#0000000&@11 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |m|i|n|u|s| |i|n|f|i|n|i|t|y|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g|m|i|n|u|s|i|n|f|i|n|i|t|y| +0#0000000&@5 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |r|e|a|l| |w|i|d|t|h|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|r|e|a|l|w|i|d|t|h| +0#0000000&@9 +@57|9|1|,|3| @10|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_06.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_06.dump new file mode 100644 index 0000000000..1cee8296ef --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_06.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |l|o|n|g| |r|e|a|l| |w|i|d|t|h|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|r|e|a|l|w|i|d|t|h| +0#0000000&@9 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|m|a|l@1| |r|e|a|l|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|s|m|a|l@1|r|e|a|l| +0#0000000&@9 +@2|l+0#00e0e07&|o|n|g| |r|e|a|l| |w|i|d|t|h|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|r|e|a|l|w|i|d|t|h| +0#0000000&@13 +@2|m+0#00e0e07&|a|x| |a|b|s| |c|h|a|r|;+0#0000000&| @32|m+0#00e0e07&|a|x|a|b|s|c|h|a|r| +0#0000000&@16 +@2|m+0#00e0e07&|a|x| |b|i|t|s|;+0#0000000&| @36|m+0#00e0e07&|a|x|b|i|t|s| +0#0000000&@19 +@2>m+0#00e0e07&|a|x| |i|n|t|;+0#0000000&| @37|m+0#00e0e07&|a|x|i|n|t| +0#0000000&@20 +@2|m+0#00e0e07&|a|x| |r|e|a|l|;+0#0000000&| @36|m+0#00e0e07&|a|x|r|e|a|l| +0#0000000&@19 +@2|m+0#00e0e07&|i|n| |i|n|f|;+0#0000000&| @37|m+0#00e0e07&|i|n|i|n|f| +0#0000000&@20 +@2|m+0#00e0e07&|i|n| |r|e|a|l|;+0#0000000&| @36|m+0#00e0e07&|i|n|r|e|a|l| +0#0000000&@19 +@2|m+0#00e0e07&|i|n|u|s| |i|n|f|i|n|i|t|y|;+0#0000000&| @30|m+0#00e0e07&|i|n|u|s|i|n|f|i|n|i|t|y| +0#0000000&@13 +@2|m+0#00e0e07&|p|r|a|d|i|x|;+0#0000000&| @37|m+0#00e0e07&|p|r|a|d|i|x| +0#0000000&@19 +@2|n+0#00e0e07&|a|n|;+0#0000000&| @41|n+0#00e0e07&|a|n| +0#0000000&@23 +@2|p+0#00e0e07&|i|;+0#0000000&| @42|p+0#00e0e07&|i| +0#0000000&@24 +@2|r+0#00e0e07&|e|a|l| |l|e|n|g|t|h|s|;+0#0000000&| @32|r+0#00e0e07&|e|a|l@1|e|n|g|t|h|s| +0#0000000&@15 +@2|r+0#00e0e07&|e|a|l| |s|h|o|r|t|h|s|;+0#0000000&| @32|r+0#00e0e07&|e|a|l|s|h|o|r|t|h|s| +0#0000000&@15 +@2|r+0#00e0e07&|e|a|l| |w|i|d|t|h|;+0#0000000&| @34|r+0#00e0e07&|e|a|l|w|i|d|t|h| +0#0000000&@17 +@2|s+0#00e0e07&|m|a|l@1| |r|e|a|l|;+0#0000000&| @34|s+0#00e0e07&|m|a|l@1|r|e|a|l| +0#0000000&@17 +@2|c+0#00e0e07&|l|o|c|k|;+0#0000000&| @39|c+0#00e0e07&|l|o|c|k| +0#0000000&@21 +@2|c+0#00e0e07&|p|u| |t|i|m|e|;+0#0000000&| @36|c+0#00e0e07&|p|u|t|i|m|e| +0#0000000&@19 +@57|1|0|9|,|3| @9|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_07.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_07.dump new file mode 100644 index 0000000000..13bf3a590f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_07.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|p|u| |t|i|m|e|;+0#0000000&| @36|c+0#00e0e07&|p|u|t|i|m|e| +0#0000000&@19 +@2|s+0#00e0e07&|e|c|o|n|d|s|;+0#0000000&| @37|s+0#00e0e07&|e|c|o|n|d|s| +0#0000000&@19 +@2|w+0#00e0e07&|a|l@1| |c|l|o|c|k|;+0#0000000&| @34|w+0#00e0e07&|a|l@1|c|l|o|c|k| +0#0000000&@17 +@2|w+0#00e0e07&|a|l@1| |s|e|c|o|n|d|s|;+0#0000000&| @32|w+0#00e0e07&|a|l@1|s|e|c|o|n|d|s| +0#0000000&@15 +@2|w+0#00e0e07&|a|l@1| |t|i|m|e|;+0#0000000&| @35|w+0#00e0e07&|a|l@1|t|i|m|e| +0#0000000&@18 +@2>b+0#00e0e07&|l|o|c|k|s|;+0#0000000&| @38|b+0#00e0e07&|l|o|c|k|s| +0#0000000&@20 +@2|c+0#00e0e07&|o|l@1|e|c|t|i|o|n|s|;+0#0000000&| @33|c+0#00e0e07&|o|l@1|e|c|t|i|o|n|s| +0#0000000&@15 +@2|c+0#00e0e07&|o|l@1|e|c|t| |s|e|c|o|n|d|s|;+0#0000000&| @29|c+0#00e0e07&|o|l@1|e|c|t|s|e|c|o|n|d|s| +0#0000000&@12 +@2|g+0#00e0e07&|a|r|b|a|g|e|;+0#0000000&| @37|g+0#00e0e07&|a|r|b|a|g|e| +0#0000000&@19 +@2|g+0#00e0e07&|a|r|b|a|g|e| |c|o|l@1|e|c|t|i|o|n|s|;+0#0000000&| @25|g+0#00e0e07&|a|r|b|a|g|e|c|o|l@1|e|c|t|i|o|n|s| +0#0000000&@8 +@2|g+0#00e0e07&|a|r|b|a|g|e| |f|r|e@1|d|;+0#0000000&| @31|g+0#00e0e07&|a|r|b|a|g|e|f|r|e@1|d| +0#0000000&@14 +@2|g+0#00e0e07&|a|r|b|a|g|e| |r|e|f|u|s|e|d|;+0#0000000&| @29|g+0#00e0e07&|a|r|b|a|g|e|r|e|f|u|s|e|d| +0#0000000&@12 +@2|g+0#00e0e07&|a|r|b|a|g|e| |s|e|c|o|n|d|s|;+0#0000000&| @29|g+0#00e0e07&|a|r|b|a|g|e|s|e|c|o|n|d|s| +0#0000000&@12 +@2|o+0#00e0e07&|n| |g|c| |e|v|e|n|t|;+0#0000000&| @33|o+0#00e0e07&|n|g|c|e|v|e|n|t| +0#0000000&@17 +@2|s+0#00e0e07&|w|e@1|p|s|;+0#0000000&| @38|s+0#00e0e07&|w|e@1|p|s| +0#0000000&@20 +@2|s+0#00e0e07&|w|e@1|p|s| |r|e|f|u|s|e|d|;+0#0000000&| @30|s+0#00e0e07&|w|e@1|p|s|r|e|f|u|s|e|d| +0#0000000&@13 +@2|s+0#00e0e07&|t|a|c|k| |p|o|i|n|t|e|r|;+0#0000000&| @31|s+0#00e0e07&|t|a|c|k|p|o|i|n|t|e|r| +0#0000000&@14 +@2|s+0#00e0e07&|y|s|t|e|m| |s|t|a|c|k| |p|o|i|n|t|e|r|;+0#0000000&| @24|s+0#00e0e07&|y|s|t|e|m|s|t|a|c|k|p|o|i|n|t|e|r| +0#0000000&@8 +@2|s+0#00e0e07&|y|s|t|e|m| |s|t|a|c|k| |s|i|z|e|;+0#0000000&| @27|s+0#00e0e07&|y|s|t|e|m|s|t|a|c|k|s|i|z|e| +0#0000000&@11 +@57|1|2|7|,|3| @9|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_08.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_08.dump new file mode 100644 index 0000000000..ece94c30cd --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_08.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|s+0#00e0e07&|y|s|t|e|m| |s|t|a|c|k| |s|i|z|e|;+0#0000000&| @27|s+0#00e0e07&|y|s|t|e|m|s|t|a|c|k|s|i|z|e| +0#0000000&@11 +@2|a+0#00e0e07&|c|t|u|a|l| |s|t|a|c|k| |s|i|z|e|;+0#0000000&| @27|a+0#00e0e07&|c|t|u|a|l|s|t|a|c|k|s|i|z|e| +0#0000000&@11 +@2|h+0#00e0e07&|e|a|p| |p|o|i|n|t|e|r|;+0#0000000&| @32|h+0#00e0e07&|e|a|p@1|o|i|n|t|e|r| +0#0000000&@15 +@2|s+0#00e0e07&|y|s|t|e|m| |h|e|a|p| |p|o|i|n|t|e|r|;+0#0000000&| @25|s+0#00e0e07&|y|s|t|e|m|h|e|a|p@1|o|i|n|t|e|r| +0#0000000&@9 +@2|g+0#00e0e07&|c| |h|e|a|p|;+0#0000000&| @37|g+0#00e0e07&|c|h|e|a|p| +0#0000000&@20 +@2>s+0#00e0e07&|w|e@1|p| |h|e|a|p|;+0#0000000&| @34|s+0#00e0e07&|w|e@1|p|h|e|a|p| +0#0000000&@17 +@2|p+0#00e0e07&|r|e@1|m|p|t|i|v|e| |g|c|;+0#0000000&| @31|p+0#00e0e07&|r|e@1|m|p|t|i|v|e|g|c| +0#0000000&@14 +@2|p+0#00e0e07&|r|e@1|m|p|t|i|v|e| |s|w|e@1|p|;+0#0000000&| @28|p+0#00e0e07&|r|e@1|m|p|t|i|v|e|s|w|e@1|p| +0#0000000&@11 +@2|p+0#00e0e07&|r|e@1|m|p|t|i|v|e| |s|w|e@1|p|h|e|a|p|;+0#0000000&| @24|p+0#00e0e07&|r|e@1|m|p|t|i|v|e|s|w|e@1|p|h|e|a|p| +0#0000000&@7 +@2|b+0#00e0e07&|a|c|k|t|r|a|c|e|;+0#0000000&| @35|b+0#00e0e07&|a|c|k|t|r|a|c|e| +0#0000000&@17 +@2|b+0#00e0e07&|r|e|a|k|;+0#0000000&| @39|b+0#00e0e07&|r|e|a|k| +0#0000000&@21 +@2|d+0#00e0e07&|e|b|u|g|;+0#0000000&| @39|d+0#00e0e07&|e|b|u|g| +0#0000000&@21 +@2|m+0#00e0e07&|o|n|i|t|o|r|;+0#0000000&| @37|m+0#00e0e07&|o|n|i|t|o|r| +0#0000000&@19 +@2|a+0#00e0e07&|b|e|n|d|;+0#0000000&| @39|a+0#00e0e07&|b|e|n|d| +0#0000000&@21 +@2|e+0#00e0e07&|v|a|l|u|a|t|e|;+0#0000000&| @36|e+0#00e0e07&|v|a|l|u|a|t|e| +0#0000000&@18 +@2|s+0#00e0e07&|y|s|t|e|m|;+0#0000000&| @38|s+0#00e0e07&|y|s|t|e|m| +0#0000000&@20 +@2|s+0#00e0e07&|l|e@1|p|;+0#0000000&| @39|s+0#00e0e07&|l|e@1|p| +0#0000000&@21 +|#+0#0000e05&| |M|a|c|h|i|n|e| |e|n|v|i|r|o|n| |p|a|r|a|m|e|t|e|r|s|.| |#| +0#0000000&@43 +@2|i+0#00e0e07&|3|2|m|a|c|h|;+0#0000000&| @37|i+0#00e0e07&|3|2|m|a|c|h| +0#0000000&@19 +@57|1|4|5|,|3| @9|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_09.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_09.dump new file mode 100644 index 0000000000..9e5f83ba28 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_09.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|i+0#00e0e07&|3|2|m|a|c|h|;+0#0000000&| @37|i+0#00e0e07&|3|2|m|a|c|h| +0#0000000&@19 +@2|r+0#00e0e07&|6|4|m|a|c|h|;+0#0000000&| @37|r+0#00e0e07&|6|4|m|a|c|h| +0#0000000&@19 +@2|i+0#00e0e07&|6|4|m|a|c|h|;+0#0000000&| @37|i+0#00e0e07&|6|4|m|a|c|h| +0#0000000&@19 +@2|r+0#00e0e07&|1|2|8|m|a|c|h|;+0#0000000&| @36|r+0#00e0e07&|1|2|8|m|a|c|h| +0#0000000&@18 +|#+0#0000e05&| |B|I|T|S| |p|r|o|c|e|d|u|r|e|s|.| |#| +0#0000000&@54 +@2>b+0#00e0e07&|i|t|s| |p|a|c|k|;+0#0000000&| @35|b+0#00e0e07&|i|t|s|p|a|c|k| +0#0000000&@18 +|#+0#0000e05&| |R|N|G| |p|r|o|c|e|d|u|r|e|s|.| |#| +0#0000000&@55 +@2|f+0#00e0e07&|i|r|s|t| |r|a|n|d|o|m|;+0#0000000&| @32|f+0#00e0e07&|i|r|s|t|r|a|n|d|o|m| +0#0000000&@15 +@2|n+0#00e0e07&|e|x|t| |r|a|n|d|o|m|;+0#0000000&| @33|n+0#00e0e07&|e|x|t|r|a|n|d|o|m| +0#0000000&@16 +@2|r+0#00e0e07&|a|n|d|o|m|;+0#0000000&| @38|r+0#00e0e07&|a|n|d|o|m| +0#0000000&@20 +@2|r+0#00e0e07&|n|d|;+0#0000000&| @41|r+0#00e0e07&|n|d| +0#0000000&@23 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |n|e|x|t|r|a|n|d|o|m|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|n|e|x|t|r|a|n|d|o|m| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |r|a|n|d|o|m|;+0#0000000&| @28|l+0#00e0e07&|o|n|g|l|o|n|g|r|a|n|d|o|m| +0#0000000&@12 +|#+0#0000e05&| |P|r|i|o|r|i|t|i|e|s|.| |#| +0#0000000&@59 +|#+0#0000e05&| |I|N|T| |o|p|s|.| |#| +0#0000000&@62 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@57|1|6|3|,|3| @9|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_10.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_10.dump new file mode 100644 index 0000000000..e013bdea40 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_10.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|O+0#af5f00255&|D@1| +0#0000000&@42|O+0#af5f00255&|D@1| +0#0000000&@23 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2>^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@57|1|8|1|,|3| @9|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_100.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_100.dump new file mode 100644 index 0000000000..d5aded4938 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_100.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|t+0#00e0e07&|r|a|n|s|p|o|r|t| |5|;+0#0000000&| @33|t+0#00e0e07&|r|a|n|s|p|o|r|t|5| +0#0000000&@16 +@2|z+0#00e0e07&|e|t|a| |i|n|t|;+0#0000000&| @36|z+0#00e0e07&|e|t|a|i|n|t| +0#0000000&@19 +@2|z+0#00e0e07&|e|t|a| |m|1| |i|n|t|;+0#0000000&| @33|z+0#00e0e07&|e|t|a|m|1|i|n|t| +0#0000000&@17 +@2|z+0#00e0e07&|e|t|a| |m|1|;+0#0000000&| @37|z+0#00e0e07&|e|t|a|m|1| +0#0000000&@20 +@2|z+0#00e0e07&|e|t|a|;+0#0000000&| @40|z+0#00e0e07&|e|t|a| +0#0000000&@22 +>#+0#0000e05&| |V|e|c|t|o|r| |a|n|d| |m|a|t|r|i|x| |p|r|e|t@1|y| |p|r|i|n|t|.| |#| +0#0000000&@39 +@2|p+0#00e0e07&|r|i|n|t| |v|e|c|t|o|r|;+0#0000000&| @32|p+0#00e0e07&|r|i|n|t|v|e|c|t|o|r| +0#0000000&@15 +@2|p+0#00e0e07&|r|i|n|t| |m|a|t|r|i|x|;+0#0000000&| @32|p+0#00e0e07&|r|i|n|t|m|a|t|r|i|x| +0#0000000&@15 +|#+0#0000e05&| |V|e|c|t|o|r| |a|n|d| |m|a|t|r|i|x| |m|o|n|a|d|i|c|.| |#| +0#0000000&@44 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|C+0#af5f00255&|V| +0#0000000&@43|C+0#af5f00255&|V| +0#0000000&@24 +@2|R+0#af5f00255&|V| +0#0000000&@43|R+0#af5f00255&|V| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|T+0#af5f00255&| +0#0000000&@44|T+0#af5f00255&| +0#0000000&@25 +@2|I+0#af5f00255&|N|V| +0#0000000&@42|I+0#af5f00255&|N|V| +0#0000000&@23 +@2|P+0#af5f00255&|I|N|V| +0#0000000&@41|P+0#af5f00255&|I|N|V| +0#0000000&@22 +@2|M+0#af5f00255&|E|A|N| +0#0000000&@41|M+0#af5f00255&|E|A|N| +0#0000000&@22 +@57|1|7|6|8|,|1| @7|8|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_101.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_101.dump new file mode 100644 index 0000000000..a63518f77d --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_101.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|M+0#af5f00255&|E|A|N| +0#0000000&@41|M+0#af5f00255&|E|A|N| +0#0000000&@22 +@2|D+0#af5f00255&|E|T| +0#0000000&@42|D+0#af5f00255&|E|T| +0#0000000&@23 +@2|T+0#af5f00255&|R|A|C|E| +0#0000000&@40|T+0#af5f00255&|R|A|C|E| +0#0000000&@21 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2>++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|T+0#af5f00255&| +0#0000000&@44|T+0#af5f00255&| +0#0000000&@25 +@2|I+0#af5f00255&|N|V| +0#0000000&@42|I+0#af5f00255&|N|V| +0#0000000&@23 +@2|D+0#af5f00255&|E|T| +0#0000000&@42|D+0#af5f00255&|E|T| +0#0000000&@23 +@2|T+0#af5f00255&|R|A|C|E| +0#0000000&@40|T+0#af5f00255&|R|A|C|E| +0#0000000&@21 +|#+0#0000e05&| |V|e|c|t|o|r| |a|n|d| |m|a|t|r|i|x| |d|y|a|d|i|c|.| |#| +0#0000000&@45 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@57|1|7|8|6|,|3| @7|8|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_102.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_102.dump new file mode 100644 index 0000000000..a6cda51542 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_102.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2>-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|B+0#af5f00255&|E|F|O|R|E| +0#0000000&@39|B+0#af5f00255&|E|F|O|R|E| +0#0000000&@20 +@2|A+0#af5f00255&|B|O|V|E| +0#0000000&@40|A+0#af5f00255&|B|O|V|E| +0#0000000&@21 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@57|1|8|0|4|,|3| @7|8|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_103.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_103.dump new file mode 100644 index 0000000000..12f20396de --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_103.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2>-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +|#+0#0000e05&| |V|e|c|t|o|r| |a|n|d| |m|a|t|r|i|x| |s|c|a|l|i|n|g|.| |#| +0#0000000&@44 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@57|1|8|2@1|,|3| @7|8|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_104.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_104.dump new file mode 100644 index 0000000000..1a3abfcc6c --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_104.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2>*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +|#+0#0000e05&| |M|a|t|r|i|x| |t|i|m|e|s| |v|e|c|t|o|r| |o|r| |m|a|t|r|i|x|.| |#| +0#0000000&@40 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +|#+0#0000e05&| |V|e|c|t|o|r| |a|n|d| |m|a|t|r|i|x| |m|i|s|c|e|l@1|a|n|e|o|u|s|.| |#| +0#0000000&@38 +@2|v+0#00e0e07&|e|c|t|o|r| |e|c|h|o|;+0#0000000&| @33|v+0#00e0e07&|e|c|t|o|r|e|c|h|o| +0#0000000&@16 +@2|m+0#00e0e07&|a|t|r|i|x| |e|c|h|o|;+0#0000000&| @33|m+0#00e0e07&|a|t|r|i|x|e|c|h|o| +0#0000000&@16 +@2|c+0#00e0e07&|o|m|p|l| |v|e|c|t|o|r| |e|c|h|o|;+0#0000000&| @27|c+0#00e0e07&|o|m|p|l|v|e|c|t|o|r|e|c|h|o| +0#0000000&@11 +@2|c+0#00e0e07&|o|m|p|l| |m|a|t|r|i|x| |e|c|h|o|;+0#0000000&| @27|c+0#00e0e07&|o|m|p|l|m|a|t|r|i|x|e|c|h|o| +0#0000000&@11 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|N+0#af5f00255&|O|R|M| +0#0000000&@41|N+0#af5f00255&|O|R|M| +0#0000000&@22 +@57|1|8|4|0|,|3| @7|8|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_105.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_105.dump new file mode 100644 index 0000000000..80e0a5d931 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_105.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|N+0#af5f00255&|O|R|M| +0#0000000&@41|N+0#af5f00255&|O|R|M| +0#0000000&@22 +@2|D+0#af5f00255&|Y|A|D| +0#0000000&@41|D+0#af5f00255&|Y|A|D| +0#0000000&@22 +|#+0#0000e05&| |P|r|i|n|c|i|p|l|e| |C|o|m|p|o|n|e|n|t| |A|n|a|l|y|s|i|s|.| |#| +0#0000000&@41 +@2|p+0#00e0e07&|c|a|c|v|;+0#0000000&| @39|p+0#00e0e07&|c|a|c|v| +0#0000000&@21 +@2|p+0#00e0e07&|c|a|s|v|d|;+0#0000000&| @38|p+0#00e0e07&|c|a|s|v|d| +0#0000000&@20 +>#+0#0000e05&| |T|o|t|a|l| |L|e|a|s|t| |S|q|u|a|r|e| |r|e|g|r|e|s@1|i|o|n|.| |#| +0#0000000&@40 +@2|o+0#00e0e07&|l|s|;+0#0000000&| @41|o+0#00e0e07&|l|s| +0#0000000&@23 +@2|t+0#00e0e07&|l|s|;+0#0000000&| @41|t+0#00e0e07&|l|s| +0#0000000&@23 +|#+0#0000e05&| |P|a|r|t|i|a|l| |L|e|a|s|t| |S|q|u|a|r|e|s| |r|e|g|r|e|s@1|i|o|n|.| |#| +0#0000000&@37 +@2|p+0#00e0e07&|c|r|;+0#0000000&| @41|p+0#00e0e07&|c|r| +0#0000000&@23 +@2|p+0#00e0e07&|l|s|1|;+0#0000000&| @40|p+0#00e0e07&|l|s|1| +0#0000000&@22 +@2|p+0#00e0e07&|l|s|2|;+0#0000000&| @40|p+0#00e0e07&|l|s|2| +0#0000000&@22 +|#+0#0000e05&| |R|o|u|t|i|n|e| |l|e|f|t| |c|o|l|u|m|n|s|,| |a| |G|S|L| |a|l|t|e|r|n|a|t|i|v|e| |t|o| |t|r|i|m@1|i|n|g| |c|o|l|u|m|n|s|.| |#| +0#0000000&@10 +@2|l+0#00e0e07&|e|f|t| |c|o|l|u|m|n|s|;+0#0000000&| @32|l+0#00e0e07&|e|f|t|c|o|l|u|m|n|s| +0#0000000&@15 +|#+0#0000e05&| |M|o@1|r|e|-|P|e|n|r|o|s|e| |p|s|e|u|d|o| |i|n|v|e|r|s|e|.| |#| +0#0000000&@41 +@2|p+0#00e0e07&|s|e|u|d|o| |i|n|v|;+0#0000000&| @34|p+0#00e0e07&|s|e|u|d|o|i|n|v| +0#0000000&@17 +|#+0#0000e05&| |L|U| |d|e|c|o|m|p|o|s|i|t|i|o|n|.| |#| +0#0000000&@53 +@2|l+0#00e0e07&|u| |d|e|c|o|m|p|;+0#0000000&| @35|l+0#00e0e07&|u|d|e|c|o|m|p| +0#0000000&@18 +@2|l+0#00e0e07&|u| |d|e|t|;+0#0000000&| @38|l+0#00e0e07&|u|d|e|t| +0#0000000&@21 +@57|1|8|5|8|,|1| @7|8@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_106.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_106.dump new file mode 100644 index 0000000000..1956ffb0da --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_106.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|u| |d|e|t|;+0#0000000&| @38|l+0#00e0e07&|u|d|e|t| +0#0000000&@21 +@2|l+0#00e0e07&|u| |i|n|v|;+0#0000000&| @38|l+0#00e0e07&|u|i|n|v| +0#0000000&@21 +@2|l+0#00e0e07&|u| |s|o|l|v|e|;+0#0000000&| @36|l+0#00e0e07&|u|s|o|l|v|e| +0#0000000&@19 +@2|c+0#00e0e07&|o|m|p|l|e|x| |l|u| |d|e|c|o|m|p|;+0#0000000&| @27|c+0#00e0e07&|o|m|p|l|e|x|l|u|d|e|c|o|m|p| +0#0000000&@11 +@2|c+0#00e0e07&|o|m|p|l|e|x| |l|u| |d|e|t|;+0#0000000&| @30|c+0#00e0e07&|o|m|p|l|e|x|l|u|d|e|t| +0#0000000&@14 +@2>c+0#00e0e07&|o|m|p|l|e|x| |l|u| |i|n|v|;+0#0000000&| @30|c+0#00e0e07&|o|m|p|l|e|x|l|u|i|n|v| +0#0000000&@14 +@2|c+0#00e0e07&|o|m|p|l|e|x| |l|u| |s|o|l|v|e|;+0#0000000&| @28|c+0#00e0e07&|o|m|p|l|e|x|l|u|s|o|l|v|e| +0#0000000&@12 +|#+0#0000e05&| |S|V|D| |d|e|c|o|m|p|o|s|i|t|i|o|n|.| |#| +0#0000000&@52 +@2|s+0#00e0e07&|v|d| |d|e|c|o|m|p|;+0#0000000&| @34|s+0#00e0e07&|v|d@1|e|c|o|m|p| +0#0000000&@17 +@2|s+0#00e0e07&|v|d| |s|o|l|v|e|;+0#0000000&| @35|s+0#00e0e07&|v|d|s|o|l|v|e| +0#0000000&@18 +|#+0#0000e05&| |Q|R| |d|e|c|o|m|p|o|s|i|t|i|o|n|.| |#| +0#0000000&@53 +@2|q+0#00e0e07&|r| |d|e|c|o|m|p|;+0#0000000&| @35|q+0#00e0e07&|r|d|e|c|o|m|p| +0#0000000&@18 +@2|q+0#00e0e07&|r| |s|o|l|v|e|;+0#0000000&| @36|q+0#00e0e07&|r|s|o|l|v|e| +0#0000000&@19 +@2|q+0#00e0e07&|r| |l|s@1|o|l|v|e|;+0#0000000&| @34|q+0#00e0e07&|r|l|s@1|o|l|v|e| +0#0000000&@17 +|#+0#0000e05&| |C|h|o|l|e|s|k|y| |d|e|c|o|m|p|o|s|i|t|i|o|n|.| |#| +0#0000000&@47 +@2|c+0#00e0e07&|h|o|l|e|s|k|y| |d|e|c|o|m|p|;+0#0000000&| @29|c+0#00e0e07&|h|o|l|e|s|k|y|d|e|c|o|m|p| +0#0000000&@12 +@2|c+0#00e0e07&|h|o|l|e|s|k|y| |s|o|l|v|e|;+0#0000000&| @30|c+0#00e0e07&|h|o|l|e|s|k|y|s|o|l|v|e| +0#0000000&@13 +|#+0#0000e05&| |C|o|n|s|t|a|n|t|s| |e|x| |G|S|L|.| |#| +0#0000000&@53 +@2|c+0#00e0e07&|g|s| |s|p|e@1|d| |o|f| |l|i|g|h|t|;+0#0000000&| @26|c+0#00e0e07&|g|s@1|p|e@1|d|o|f|l|i|g|h|t| +0#0000000&@11 +@57|1|8|7|6|,|3| @7|8|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_107.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_107.dump new file mode 100644 index 0000000000..213b74c54f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_107.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|g|s| |s|p|e@1|d| |o|f| |l|i|g|h|t|;+0#0000000&| @26|c+0#00e0e07&|g|s@1|p|e@1|d|o|f|l|i|g|h|t| +0#0000000&@11 +@2|c+0#00e0e07&|g|s| |g|r|a|v|i|t|a|t|i|o|n|a|l| |c|o|n|s|t|a|n|t|;+0#0000000&| @18|c+0#00e0e07&|g|s|g|r|a|v|i|t|a|t|i|o|n|a|l|c|o|n|s|t|a|n|t| +0#0000000&@2 +@2|c+0#00e0e07&|g|s| |p|l|a|n|c|k| |c|o|n|s|t|a|n|t|;+0#0000000&| @25|c+0#00e0e07&|g|s|p|l|a|n|c|k|c|o|n|s|t|a|n|t| +0#0000000&@9 +@2|c+0#00e0e07&|g|s| |p|l|a|n|c|k| |c|o|n|s|t|a|n|t| |b|a|r|;+0#0000000&| @21|c+0#00e0e07&|g|s|p|l|a|n|c|k|c|o|n|s|t|a|n|t|b|a|r| +0#0000000&@6 +@2|c+0#00e0e07&|g|s| |a|s|t|r|o|n|o|m|i|c|a|l| |u|n|i|t|;+0#0000000&| @23|c+0#00e0e07&|g|s|a|s|t|r|o|n|o|m|i|c|a|l|u|n|i|t| +0#0000000&@7 +@2>c+0#00e0e07&|g|s| |l|i|g|h|t| |y|e|a|r|;+0#0000000&| @30|c+0#00e0e07&|g|s|l|i|g|h|t|y|e|a|r| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |p|a|r|s|e|c|;+0#0000000&| @34|c+0#00e0e07&|g|s|p|a|r|s|e|c| +0#0000000&@17 +@2|c+0#00e0e07&|g|s| |g|r|a|v| |a|c@1|e|l|;+0#0000000&| @30|c+0#00e0e07&|g|s|g|r|a|v|a|c@1|e|l| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |e|l|e|c|t|r|o|n| |v|o|l|t|;+0#0000000&| @27|c+0#00e0e07&|g|s|e|l|e|c|t|r|o|n|v|o|l|t| +0#0000000&@11 +@2|c+0#00e0e07&|g|s| |m|a|s@1| |e|l|e|c|t|r|o|n|;+0#0000000&| @27|c+0#00e0e07&|g|s|m|a|s@1|e|l|e|c|t|r|o|n| +0#0000000&@11 +@2|c+0#00e0e07&|g|s| |m|a|s@1| |m|u|o|n|;+0#0000000&| @31|c+0#00e0e07&|g|s|m|a|s@1|m|u|o|n| +0#0000000&@15 +@2|c+0#00e0e07&|g|s| |m|a|s@1| |p|r|o|t|o|n|;+0#0000000&| @29|c+0#00e0e07&|g|s|m|a|s@1|p|r|o|t|o|n| +0#0000000&@13 +@2|c+0#00e0e07&|g|s| |m|a|s@1| |n|e|u|t|r|o|n|;+0#0000000&| @28|c+0#00e0e07&|g|s|m|a|s@1|n|e|u|t|r|o|n| +0#0000000&@12 +@2|c+0#00e0e07&|g|s| |r|y|d|b|e|r|g|;+0#0000000&| @33|c+0#00e0e07&|g|s|r|y|d|b|e|r|g| +0#0000000&@16 +@2|c+0#00e0e07&|g|s| |b|o|l|t|z|m|a|n@1|;+0#0000000&| @31|c+0#00e0e07&|g|s|b|o|l|t|z|m|a|n@1| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |b|o|h|r| |m|a|g|n|e|t|o|n|;+0#0000000&| @27|c+0#00e0e07&|g|s|b|o|h|r|m|a|g|n|e|t|o|n| +0#0000000&@11 +@2|c+0#00e0e07&|g|s| |n|u|c|l|e|a|r| |m|a|g|n|e|t|o|n|;+0#0000000&| @24|c+0#00e0e07&|g|s|n|u|c|l|e|a|r|m|a|g|n|e|t|o|n| +0#0000000&@8 +@2|c+0#00e0e07&|g|s| |e|l|e|c|t|r|o|n| |m|a|g|n|e|t|i|c| |m|o|m|e|n|t|;+0#0000000&| @16|c+0#00e0e07&|g|s|e|l|e|c|t|r|o|n|m|a|g|n|e|t|i|c|m|o|m|e|n|t| +0#0000000&@1 +@2|c+0#00e0e07&|g|s| |p|r|o|t|o|n| |m|a|g|n|e|t|i|c| |m|o|m|e|n|t|;+0#0000000&| @18|c+0#00e0e07&|g|s|p|r|o|t|o|n|m|a|g|n|e|t|i|c|m|o|m|e|n|t| +0#0000000&@3 +@57|1|8|9|4|,|3| @7|9|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_108.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_108.dump new file mode 100644 index 0000000000..f1ed88294b --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_108.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|g|s| |p|r|o|t|o|n| |m|a|g|n|e|t|i|c| |m|o|m|e|n|t|;+0#0000000&| @18|c+0#00e0e07&|g|s|p|r|o|t|o|n|m|a|g|n|e|t|i|c|m|o|m|e|n|t| +0#0000000&@3 +@2|c+0#00e0e07&|g|s| |m|o|l|a|r| |g|a|s|;+0#0000000&| @31|c+0#00e0e07&|g|s|m|o|l|a|r|g|a|s| +0#0000000&@15 +@2|c+0#00e0e07&|g|s| |s|t|a|n|d|a|r|d| |g|a|s| |v|o|l|u|m|e|;+0#0000000&| @21|c+0#00e0e07&|g|s@1|t|a|n|d|a|r|d|g|a|s|v|o|l|u|m|e| +0#0000000&@6 +@2|c+0#00e0e07&|g|s| |m|i|n|u|t|e|;+0#0000000&| @34|c+0#00e0e07&|g|s|m|i|n|u|t|e| +0#0000000&@17 +@2|c+0#00e0e07&|g|s| |h|o|u|r|;+0#0000000&| @36|c+0#00e0e07&|g|s|h|o|u|r| +0#0000000&@19 +@2>c+0#00e0e07&|g|s| |d|a|y|;+0#0000000&| @37|c+0#00e0e07&|g|s|d|a|y| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |w|e@1|k|;+0#0000000&| @36|c+0#00e0e07&|g|s|w|e@1|k| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |i|n|c|h|;+0#0000000&| @36|c+0#00e0e07&|g|s|i|n|c|h| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |f|o@1|t|;+0#0000000&| @36|c+0#00e0e07&|g|s|f|o@1|t| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |y|a|r|d|;+0#0000000&| @36|c+0#00e0e07&|g|s|y|a|r|d| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |m|i|l|e|;+0#0000000&| @36|c+0#00e0e07&|g|s|m|i|l|e| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |n|a|u|t|i|c|a|l| |m|i|l|e|;+0#0000000&| @27|c+0#00e0e07&|g|s|n|a|u|t|i|c|a|l|m|i|l|e| +0#0000000&@11 +@2|c+0#00e0e07&|g|s| |f|a|t|h|o|m|;+0#0000000&| @34|c+0#00e0e07&|g|s|f|a|t|h|o|m| +0#0000000&@17 +@2|c+0#00e0e07&|g|s| |m|i|l|;+0#0000000&| @37|c+0#00e0e07&|g|s|m|i|l| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |p|o|i|n|t|;+0#0000000&| @35|c+0#00e0e07&|g|s|p|o|i|n|t| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |t|e|x|p|o|i|n|t|;+0#0000000&| @32|c+0#00e0e07&|g|s|t|e|x|p|o|i|n|t| +0#0000000&@15 +@2|c+0#00e0e07&|g|s| |m|i|c|r|o|n|;+0#0000000&| @34|c+0#00e0e07&|g|s|m|i|c|r|o|n| +0#0000000&@17 +@2|c+0#00e0e07&|g|s| |a|n|g|s|t|r|o|m|;+0#0000000&| @32|c+0#00e0e07&|g|s|a|n|g|s|t|r|o|m| +0#0000000&@15 +@2|c+0#00e0e07&|g|s| |h|e|c|t|a|r|e|;+0#0000000&| @33|c+0#00e0e07&|g|s|h|e|c|t|a|r|e| +0#0000000&@16 +@57|1|9|1|2|,|3| @7|9|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_109.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_109.dump new file mode 100644 index 0000000000..5da23e17ab --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_109.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|g|s| |h|e|c|t|a|r|e|;+0#0000000&| @33|c+0#00e0e07&|g|s|h|e|c|t|a|r|e| +0#0000000&@16 +@2|c+0#00e0e07&|g|s| |a|c|r|e|;+0#0000000&| @36|c+0#00e0e07&|g|s|a|c|r|e| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |b|a|r|n|;+0#0000000&| @36|c+0#00e0e07&|g|s|b|a|r|n| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |l|i|t|e|r|;+0#0000000&| @35|c+0#00e0e07&|g|s|l|i|t|e|r| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |u|s| |g|a|l@1|o|n|;+0#0000000&| @31|c+0#00e0e07&|g|s|u|s|g|a|l@1|o|n| +0#0000000&@15 +@2>c+0#00e0e07&|g|s| |q|u|a|r|t|;+0#0000000&| @35|c+0#00e0e07&|g|s|q|u|a|r|t| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |p|i|n|t|;+0#0000000&| @36|c+0#00e0e07&|g|s|p|i|n|t| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |c|u|p|;+0#0000000&| @37|c+0#00e0e07&|g|s|c|u|p| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |f|l|u|i|d| |o|u|n|c|e|;+0#0000000&| @29|c+0#00e0e07&|g|s|f|l|u|i|d|o|u|n|c|e| +0#0000000&@13 +@2|c+0#00e0e07&|g|s| |t|a|b|l|e| |s|p|o@1|n|;+0#0000000&| @29|c+0#00e0e07&|g|s|t|a|b|l|e|s|p|o@1|n| +0#0000000&@13 +@2|c+0#00e0e07&|g|s| |t|e|a| |s|p|o@1|n|;+0#0000000&| @31|c+0#00e0e07&|g|s|t|e|a|s|p|o@1|n| +0#0000000&@15 +@2|c+0#00e0e07&|g|s| |c|a|n|a|d|i|a|n| |g|a|l@1|o|n|;+0#0000000&| @25|c+0#00e0e07&|g|s|c|a|n|a|d|i|a|n|g|a|l@1|o|n| +0#0000000&@9 +@2|c+0#00e0e07&|g|s| |u|k| |g|a|l@1|o|n|;+0#0000000&| @31|c+0#00e0e07&|g|s|u|k|g|a|l@1|o|n| +0#0000000&@15 +@2|c+0#00e0e07&|g|s| |m|i|l|e|s| |p|e|r| |h|o|u|r|;+0#0000000&| @26|c+0#00e0e07&|g|s|m|i|l|e|s|p|e|r|h|o|u|r| +0#0000000&@11 +@2|c+0#00e0e07&|g|s| |k|i|l|o|m|e|t|e|r|s| |p|e|r| |h|o|u|r|;+0#0000000&| @21|c+0#00e0e07&|g|s|k|i|l|o|m|e|t|e|r|s|p|e|r|h|o|u|r| +0#0000000&@6 +@2|c+0#00e0e07&|g|s| |k|n|o|t|;+0#0000000&| @36|c+0#00e0e07&|g|s|k|n|o|t| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |p|o|u|n|d| |m|a|s@1|;+0#0000000&| @30|c+0#00e0e07&|g|s|p|o|u|n|d|m|a|s@1| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |o|u|n|c|e| |m|a|s@1|;+0#0000000&| @30|c+0#00e0e07&|g|s|o|u|n|c|e|m|a|s@1| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |t|o|n|;+0#0000000&| @37|c+0#00e0e07&|g|s|t|o|n| +0#0000000&@20 +@57|1|9|3|0|,|3| @7|9|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_11.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_11.dump new file mode 100644 index 0000000000..96ceb5bbe5 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_11.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|V|E|R| +0#0000000&@41|O+0#af5f00255&|V|E|R| +0#0000000&@22 +@2|%+0#af5f00255&| +0#0000000&@44|%+0#af5f00255&| +0#0000000&@25 +@2|M+0#af5f00255&|O|D| +0#0000000&@42|M+0#af5f00255&|O|D| +0#0000000&@23 +@2|%+0#af5f00255&|*| +0#0000000&@43|%+0#af5f00255&|*| +0#0000000&@24 +@2>*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|%+0#af5f00255&|:|=| +0#0000000&@42|%+0#af5f00255&|:|=| +0#0000000&@23 +@2|%+0#af5f00255&|*|:|=| +0#0000000&@41|%+0#af5f00255&|*|:|=| +0#0000000&@22 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@39|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|O|D|A|B| +0#0000000&@40|M+0#af5f00255&|O|D|A|B| +0#0000000&@21 +@57|1|9@1|,|3| @9|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_110.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_110.dump new file mode 100644 index 0000000000..b06226adc0 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_110.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|g|s| |t|o|n|;+0#0000000&| @37|c+0#00e0e07&|g|s|t|o|n| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |m|e|t|r|i|c|t|o|n|;+0#0000000&| @31|c+0#00e0e07&|g|s|m|e|t|r|i|c|t|o|n| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |u|k|t|o|n|;+0#0000000&| @35|c+0#00e0e07&|g|s|u|k|t|o|n| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |t|r|o|y| |o|u|n|c|e|;+0#0000000&| @30|c+0#00e0e07&|g|s|t|r|o|y|o|u|n|c|e| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |c|a|r|a|t|;+0#0000000&| @35|c+0#00e0e07&|g|s|c|a|r|a|t| +0#0000000&@18 +@2>c+0#00e0e07&|g|s| |u|n|i|f|i|e|d| |a|t|o|m|i|c| |m|a|s@1|;+0#0000000&| @21|c+0#00e0e07&|g|s|u|n|i|f|i|e|d|a|t|o|m|i|c|m|a|s@1| +0#0000000&@6 +@2|c+0#00e0e07&|g|s| |g|r|a|m| |f|o|r|c|e|;+0#0000000&| @30|c+0#00e0e07&|g|s|g|r|a|m|f|o|r|c|e| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |p|o|u|n|d| |f|o|r|c|e|;+0#0000000&| @29|c+0#00e0e07&|g|s|p|o|u|n|d|f|o|r|c|e| +0#0000000&@13 +@2|c+0#00e0e07&|g|s| |k|i|l|o| |p|o|u|n|d| |f|o|r|c|e|;+0#0000000&| @24|c+0#00e0e07&|g|s|k|i|l|o|p|o|u|n|d|f|o|r|c|e| +0#0000000&@9 +@2|c+0#00e0e07&|g|s| |p|o|u|n|d|a|l|;+0#0000000&| @33|c+0#00e0e07&|g|s|p|o|u|n|d|a|l| +0#0000000&@16 +@2|c+0#00e0e07&|g|s| |c|a|l|o|r|i|e|;+0#0000000&| @33|c+0#00e0e07&|g|s|c|a|l|o|r|i|e| +0#0000000&@16 +@2|c+0#00e0e07&|g|s| |b|t|u|;+0#0000000&| @37|c+0#00e0e07&|g|s|b|t|u| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |t|h|e|r|m|;+0#0000000&| @35|c+0#00e0e07&|g|s|t|h|e|r|m| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |h|o|r|s|e|p|o|w|e|r|;+0#0000000&| @30|c+0#00e0e07&|g|s|h|o|r|s|e|p|o|w|e|r| +0#0000000&@13 +@2|c+0#00e0e07&|g|s| |b|a|r|;+0#0000000&| @37|c+0#00e0e07&|g|s|b|a|r| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |s|t|d| |a|t|m|o|s|p|h|e|r|e|;+0#0000000&| @26|c+0#00e0e07&|g|s@1|t|d|a|t|m|o|s|p|h|e|r|e| +0#0000000&@10 +@2|c+0#00e0e07&|g|s| |t|o|r@1|;+0#0000000&| @36|c+0#00e0e07&|g|s|t|o|r@1| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |m|e|t|e|r| |o|f| |m|e|r|c|u|r|y|;+0#0000000&| @24|c+0#00e0e07&|g|s|m|e|t|e|r|o|f|m|e|r|c|u|r|y| +0#0000000&@9 +@2|c+0#00e0e07&|g|s| |i|n|c|h| |o|f| |m|e|r|c|u|r|y|;+0#0000000&| @25|c+0#00e0e07&|g|s|i|n|c|h|o|f|m|e|r|c|u|r|y| +0#0000000&@10 +@57|1|9|4|8|,|3| @7|9|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_111.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_111.dump new file mode 100644 index 0000000000..65797fff22 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_111.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|g|s| |i|n|c|h| |o|f| |m|e|r|c|u|r|y|;+0#0000000&| @25|c+0#00e0e07&|g|s|i|n|c|h|o|f|m|e|r|c|u|r|y| +0#0000000&@10 +@2|c+0#00e0e07&|g|s| |i|n|c|h| |o|f| |w|a|t|e|r|;+0#0000000&| @27|c+0#00e0e07&|g|s|i|n|c|h|o|f|w|a|t|e|r| +0#0000000&@12 +@2|c+0#00e0e07&|g|s| |p|s|i|;+0#0000000&| @37|c+0#00e0e07&|g|s|p|s|i| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |p|o|i|s|e|;+0#0000000&| @35|c+0#00e0e07&|g|s|p|o|i|s|e| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |s|t|o|k|e|s|;+0#0000000&| @34|c+0#00e0e07&|g|s@1|t|o|k|e|s| +0#0000000&@17 +@2>c+0#00e0e07&|g|s| |f|a|r|a|d|a|y|;+0#0000000&| @33|c+0#00e0e07&|g|s|f|a|r|a|d|a|y| +0#0000000&@16 +@2|c+0#00e0e07&|g|s| |e|l|e|c|t|r|o|n| |c|h|a|r|g|e|;+0#0000000&| @25|c+0#00e0e07&|g|s|e|l|e|c|t|r|o|n|c|h|a|r|g|e| +0#0000000&@9 +@2|c+0#00e0e07&|g|s| |g|a|u|s@1|;+0#0000000&| @35|c+0#00e0e07&|g|s|g|a|u|s@1| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |s|t|i|l|b|;+0#0000000&| @35|c+0#00e0e07&|g|s@1|t|i|l|b| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |l|u|m|e|n|;+0#0000000&| @35|c+0#00e0e07&|g|s|l|u|m|e|n| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |l|u|x|;+0#0000000&| @37|c+0#00e0e07&|g|s|l|u|x| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |p|h|o|t|;+0#0000000&| @36|c+0#00e0e07&|g|s|p|h|o|t| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |f|o@1|t| |c|a|n|d|l|e|;+0#0000000&| @29|c+0#00e0e07&|g|s|f|o@1|t|c|a|n|d|l|e| +0#0000000&@13 +@2|c+0#00e0e07&|g|s| |l|a|m|b|e|r|t|;+0#0000000&| @33|c+0#00e0e07&|g|s|l|a|m|b|e|r|t| +0#0000000&@16 +@2|c+0#00e0e07&|g|s| |f|o@1|t| |l|a|m|b|e|r|t|;+0#0000000&| @28|c+0#00e0e07&|g|s|f|o@1|t|l|a|m|b|e|r|t| +0#0000000&@12 +@2|c+0#00e0e07&|g|s| |c|u|r|i|e|;+0#0000000&| @35|c+0#00e0e07&|g|s|c|u|r|i|e| +0#0000000&@18 +@2|c+0#00e0e07&|g|s| |r|o|e|n|t|g|e|n|;+0#0000000&| @32|c+0#00e0e07&|g|s|r|o|e|n|t|g|e|n| +0#0000000&@15 +@2|c+0#00e0e07&|g|s| |r|a|d|;+0#0000000&| @37|c+0#00e0e07&|g|s|r|a|d| +0#0000000&@20 +@2|c+0#00e0e07&|g|s| |s|o|l|a|r| |m|a|s@1|;+0#0000000&| @30|c+0#00e0e07&|g|s@1|o|l|a|r|m|a|s@1| +0#0000000&@14 +@57|1|9|6@1|,|3| @7|9|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_112.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_112.dump new file mode 100644 index 0000000000..06c67aaf22 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_112.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|g|s| |s|o|l|a|r| |m|a|s@1|;+0#0000000&| @30|c+0#00e0e07&|g|s@1|o|l|a|r|m|a|s@1| +0#0000000&@14 +@2|c+0#00e0e07&|g|s| |b|o|h|r| |r|a|d|i|u|s|;+0#0000000&| @29|c+0#00e0e07&|g|s|b|o|h|r@1|a|d|i|u|s| +0#0000000&@13 +@2|c+0#00e0e07&|g|s| |n|e|w|t|o|n|;+0#0000000&| @34|c+0#00e0e07&|g|s|n|e|w|t|o|n| +0#0000000&@17 +@2|c+0#00e0e07&|g|s| |d|y|n|e|;+0#0000000&| @36|c+0#00e0e07&|g|s|d|y|n|e| +0#0000000&@19 +@2|c+0#00e0e07&|g|s| |j|o|u|l|e|;+0#0000000&| @35|c+0#00e0e07&|g|s|j|o|u|l|e| +0#0000000&@18 +@2>c+0#00e0e07&|g|s| |e|r|g|;+0#0000000&| @37|c+0#00e0e07&|g|s|e|r|g| +0#0000000&@20 +@2|m+0#00e0e07&|k|s|a| |s|p|e@1|d| |o|f| |l|i|g|h|t|;+0#0000000&| @25|m+0#00e0e07&|k|s|a|s|p|e@1|d|o|f|l|i|g|h|t| +0#0000000&@10 +@2|m+0#00e0e07&|k|s|a| |g|r|a|v|i|t|a|t|i|o|n|a|l| |c|o|n|s|t|a|n|t|;+0#0000000&| @17|m+0#00e0e07&|k|s|a|g|r|a|v|i|t|a|t|i|o|n|a|l|c|o|n|s|t|a|n|t| +0#0000000&@1 +@2|m+0#00e0e07&|k|s|a| |p|l|a|n|c|k| |c|o|n|s|t|a|n|t|;+0#0000000&| @24|m+0#00e0e07&|k|s|a|p|l|a|n|c|k|c|o|n|s|t|a|n|t| +0#0000000&@8 +@2|m+0#00e0e07&|k|s|a| |p|l|a|n|c|k| |c|o|n|s|t|a|n|t| |b|a|r|;+0#0000000&| @20|m+0#00e0e07&|k|s|a|p|l|a|n|c|k|c|o|n|s|t|a|n|t|b|a|r| +0#0000000&@5 +@2|m+0#00e0e07&|k|s|a| |v|a|c|u@1|m| |p|e|r|m|e|a|b|i|l|i|t|y|;+0#0000000&| @20|m+0#00e0e07&|k|s|a|v|a|c|u@1|m|p|e|r|m|e|a|b|i|l|i|t|y| +0#0000000&@4 +@2|m+0#00e0e07&|k|s|a| |a|s|t|r|o|n|o|m|i|c|a|l| |u|n|i|t|;+0#0000000&| @22|m+0#00e0e07&|k|s|a@1|s|t|r|o|n|o|m|i|c|a|l|u|n|i|t| +0#0000000&@6 +@2|m+0#00e0e07&|k|s|a| |l|i|g|h|t| |y|e|a|r|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|l|i|g|h|t|y|e|a|r| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |p|a|r|s|e|c|;+0#0000000&| @33|m+0#00e0e07&|k|s|a|p|a|r|s|e|c| +0#0000000&@16 +@2|m+0#00e0e07&|k|s|a| |g|r|a|v| |a|c@1|e|l|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|g|r|a|v|a|c@1|e|l| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |e|l|e|c|t|r|o|n| |v|o|l|t|;+0#0000000&| @26|m+0#00e0e07&|k|s|a|e|l|e|c|t|r|o|n|v|o|l|t| +0#0000000&@10 +@2|m+0#00e0e07&|k|s|a| |m|a|s@1| |e|l|e|c|t|r|o|n|;+0#0000000&| @26|m+0#00e0e07&|k|s|a|m|a|s@1|e|l|e|c|t|r|o|n| +0#0000000&@10 +@2|m+0#00e0e07&|k|s|a| |m|a|s@1| |m|u|o|n|;+0#0000000&| @30|m+0#00e0e07&|k|s|a|m|a|s@1|m|u|o|n| +0#0000000&@14 +@2|m+0#00e0e07&|k|s|a| |m|a|s@1| |p|r|o|t|o|n|;+0#0000000&| @28|m+0#00e0e07&|k|s|a|m|a|s@1|p|r|o|t|o|n| +0#0000000&@12 +@57|1|9|8|4|,|3| @7|9|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_113.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_113.dump new file mode 100644 index 0000000000..4a960e3ed0 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_113.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|m+0#00e0e07&|k|s|a| |m|a|s@1| |p|r|o|t|o|n|;+0#0000000&| @28|m+0#00e0e07&|k|s|a|m|a|s@1|p|r|o|t|o|n| +0#0000000&@12 +@2|m+0#00e0e07&|k|s|a| |m|a|s@1| |n|e|u|t|r|o|n|;+0#0000000&| @27|m+0#00e0e07&|k|s|a|m|a|s@1|n|e|u|t|r|o|n| +0#0000000&@11 +@2|m+0#00e0e07&|k|s|a| |r|y|d|b|e|r|g|;+0#0000000&| @32|m+0#00e0e07&|k|s|a|r|y|d|b|e|r|g| +0#0000000&@15 +@2|m+0#00e0e07&|k|s|a| |b|o|l|t|z|m|a|n@1|;+0#0000000&| @30|m+0#00e0e07&|k|s|a|b|o|l|t|z|m|a|n@1| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |b|o|h|r| |m|a|g|n|e|t|o|n|;+0#0000000&| @26|m+0#00e0e07&|k|s|a|b|o|h|r|m|a|g|n|e|t|o|n| +0#0000000&@10 +@2>m+0#00e0e07&|k|s|a| |n|u|c|l|e|a|r| |m|a|g|n|e|t|o|n|;+0#0000000&| @23|m+0#00e0e07&|k|s|a|n|u|c|l|e|a|r|m|a|g|n|e|t|o|n| +0#0000000&@7 +@2|m+0#00e0e07&|k|s|a| |e|l|e|c|t|r|o|n| |m|a|g|n|e|t|i|c| |m|o|m|e|n|t|;+0#0000000&| @15|m+0#00e0e07&|k|s|a|e|l|e|c|t|r|o|n|m|a|g|n|e|t|i|c|m|o|m|e|n|t| +0#0000000& +@2|m+0#00e0e07&|k|s|a| |p|r|o|t|o|n| |m|a|g|n|e|t|i|c| |m|o|m|e|n|t|;+0#0000000&| @17|m+0#00e0e07&|k|s|a|p|r|o|t|o|n|m|a|g|n|e|t|i|c|m|o|m|e|n|t| +0#0000000&@2 +@2|m+0#00e0e07&|k|s|a| |m|o|l|a|r| |g|a|s|;+0#0000000&| @30|m+0#00e0e07&|k|s|a|m|o|l|a|r|g|a|s| +0#0000000&@14 +@2|m+0#00e0e07&|k|s|a| |s|t|a|n|d|a|r|d| |g|a|s| |v|o|l|u|m|e|;+0#0000000&| @20|m+0#00e0e07&|k|s|a|s|t|a|n|d|a|r|d|g|a|s|v|o|l|u|m|e| +0#0000000&@5 +@2|m+0#00e0e07&|k|s|a| |m|i|n|u|t|e|;+0#0000000&| @33|m+0#00e0e07&|k|s|a|m|i|n|u|t|e| +0#0000000&@16 +@2|m+0#00e0e07&|k|s|a| |h|o|u|r|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|h|o|u|r| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |d|a|y|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|d|a|y| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |w|e@1|k|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|w|e@1|k| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |i|n|c|h|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|i|n|c|h| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |f|o@1|t|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|f|o@1|t| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |y|a|r|d|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|y|a|r|d| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |m|i|l|e|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|m|i|l|e| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |n|a|u|t|i|c|a|l| |m|i|l|e|;+0#0000000&| @26|m+0#00e0e07&|k|s|a|n|a|u|t|i|c|a|l|m|i|l|e| +0#0000000&@10 +@57|2|0@1|2|,|3| @7|9|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_114.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_114.dump new file mode 100644 index 0000000000..63da3ff3cd --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_114.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|m+0#00e0e07&|k|s|a| |n|a|u|t|i|c|a|l| |m|i|l|e|;+0#0000000&| @26|m+0#00e0e07&|k|s|a|n|a|u|t|i|c|a|l|m|i|l|e| +0#0000000&@10 +@2|m+0#00e0e07&|k|s|a| |f|a|t|h|o|m|;+0#0000000&| @33|m+0#00e0e07&|k|s|a|f|a|t|h|o|m| +0#0000000&@16 +@2|m+0#00e0e07&|k|s|a| |m|i|l|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|m|i|l| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |p|o|i|n|t|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|p|o|i|n|t| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |t|e|x|p|o|i|n|t|;+0#0000000&| @31|m+0#00e0e07&|k|s|a|t|e|x|p|o|i|n|t| +0#0000000&@14 +@2>m+0#00e0e07&|k|s|a| |m|i|c|r|o|n|;+0#0000000&| @33|m+0#00e0e07&|k|s|a|m|i|c|r|o|n| +0#0000000&@16 +@2|m+0#00e0e07&|k|s|a| |a|n|g|s|t|r|o|m|;+0#0000000&| @31|m+0#00e0e07&|k|s|a@1|n|g|s|t|r|o|m| +0#0000000&@14 +@2|m+0#00e0e07&|k|s|a| |h|e|c|t|a|r|e|;+0#0000000&| @32|m+0#00e0e07&|k|s|a|h|e|c|t|a|r|e| +0#0000000&@15 +@2|m+0#00e0e07&|k|s|a| |a|c|r|e|;+0#0000000&| @35|m+0#00e0e07&|k|s|a@1|c|r|e| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |b|a|r|n|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|b|a|r|n| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |l|i|t|e|r|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|l|i|t|e|r| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |u|s| |g|a|l@1|o|n|;+0#0000000&| @30|m+0#00e0e07&|k|s|a|u|s|g|a|l@1|o|n| +0#0000000&@14 +@2|m+0#00e0e07&|k|s|a| |q|u|a|r|t|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|q|u|a|r|t| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |p|i|n|t|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|p|i|n|t| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |c|u|p|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|c|u|p| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |f|l|u|i|d| |o|u|n|c|e|;+0#0000000&| @28|m+0#00e0e07&|k|s|a|f|l|u|i|d|o|u|n|c|e| +0#0000000&@12 +@2|m+0#00e0e07&|k|s|a| |t|a|b|l|e| |s|p|o@1|n|;+0#0000000&| @28|m+0#00e0e07&|k|s|a|t|a|b|l|e|s|p|o@1|n| +0#0000000&@12 +@2|m+0#00e0e07&|k|s|a| |t|e|a| |s|p|o@1|n|;+0#0000000&| @30|m+0#00e0e07&|k|s|a|t|e|a|s|p|o@1|n| +0#0000000&@14 +@2|m+0#00e0e07&|k|s|a| |c|a|n|a|d|i|a|n| |g|a|l@1|o|n|;+0#0000000&| @24|m+0#00e0e07&|k|s|a|c|a|n|a|d|i|a|n|g|a|l@1|o|n| +0#0000000&@8 +@57|2|0|2|0|,|3| @7|9|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_115.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_115.dump new file mode 100644 index 0000000000..3adb052b28 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_115.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|m+0#00e0e07&|k|s|a| |c|a|n|a|d|i|a|n| |g|a|l@1|o|n|;+0#0000000&| @24|m+0#00e0e07&|k|s|a|c|a|n|a|d|i|a|n|g|a|l@1|o|n| +0#0000000&@8 +@2|m+0#00e0e07&|k|s|a| |u|k| |g|a|l@1|o|n|;+0#0000000&| @30|m+0#00e0e07&|k|s|a|u|k|g|a|l@1|o|n| +0#0000000&@14 +@2|m+0#00e0e07&|k|s|a| |m|i|l|e|s| |p|e|r| |h|o|u|r|;+0#0000000&| @25|m+0#00e0e07&|k|s|a|m|i|l|e|s|p|e|r|h|o|u|r| +0#0000000&@10 +@2|m+0#00e0e07&|k|s|a| |k|i|l|o|m|e|t|e|r|s| |p|e|r| |h|o|u|r|;+0#0000000&| @20|m+0#00e0e07&|k|s|a|k|i|l|o|m|e|t|e|r|s|p|e|r|h|o|u|r| +0#0000000&@5 +@2|m+0#00e0e07&|k|s|a| |k|n|o|t|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|k|n|o|t| +0#0000000&@18 +@2>m+0#00e0e07&|k|s|a| |p|o|u|n|d| |m|a|s@1|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|p|o|u|n|d|m|a|s@1| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |o|u|n|c|e| |m|a|s@1|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|o|u|n|c|e|m|a|s@1| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |t|o|n|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|t|o|n| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |m|e|t|r|i|c|t|o|n|;+0#0000000&| @30|m+0#00e0e07&|k|s|a|m|e|t|r|i|c|t|o|n| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |u|k|t|o|n|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|u|k|t|o|n| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |t|r|o|y| |o|u|n|c|e|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|t|r|o|y|o|u|n|c|e| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |c|a|r|a|t|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|c|a|r|a|t| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |u|n|i|f|i|e|d| |a|t|o|m|i|c| |m|a|s@1|;+0#0000000&| @20|m+0#00e0e07&|k|s|a|u|n|i|f|i|e|d|a|t|o|m|i|c|m|a|s@1| +0#0000000&@5 +@2|m+0#00e0e07&|k|s|a| |g|r|a|m| |f|o|r|c|e|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|g|r|a|m|f|o|r|c|e| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |p|o|u|n|d| |f|o|r|c|e|;+0#0000000&| @28|m+0#00e0e07&|k|s|a|p|o|u|n|d|f|o|r|c|e| +0#0000000&@12 +@2|m+0#00e0e07&|k|s|a| |k|i|l|o| |p|o|u|n|d| |f|o|r|c|e|;+0#0000000&| @23|m+0#00e0e07&|k|s|a|k|i|l|o|p|o|u|n|d|f|o|r|c|e| +0#0000000&@8 +@2|m+0#00e0e07&|k|s|a| |p|o|u|n|d|a|l|;+0#0000000&| @32|m+0#00e0e07&|k|s|a|p|o|u|n|d|a|l| +0#0000000&@15 +@2|m+0#00e0e07&|k|s|a| |c|a|l|o|r|i|e|;+0#0000000&| @32|m+0#00e0e07&|k|s|a|c|a|l|o|r|i|e| +0#0000000&@15 +@2|m+0#00e0e07&|k|s|a| |b|t|u|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|b|t|u| +0#0000000&@19 +@57|2|0|3|8|,|3| @7|9|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_116.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_116.dump new file mode 100644 index 0000000000..70464388c6 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_116.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|m+0#00e0e07&|k|s|a| |b|t|u|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|b|t|u| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |t|h|e|r|m|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|t|h|e|r|m| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |h|o|r|s|e|p|o|w|e|r|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|h|o|r|s|e|p|o|w|e|r| +0#0000000&@12 +@2|m+0#00e0e07&|k|s|a| |b|a|r|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|b|a|r| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |s|t|d|a|t|m|o|s|p|h|e|r|e|;+0#0000000&| @26|m+0#00e0e07&|k|s|a|s|t|d|a|t|m|o|s|p|h|e|r|e| +0#0000000&@9 +@2>m+0#00e0e07&|k|s|a| |t|o|r@1|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|t|o|r@1| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |m|e|t|e|r| |o|f| |m|e|r|c|u|r|y|;+0#0000000&| @23|m+0#00e0e07&|k|s|a|m|e|t|e|r|o|f|m|e|r|c|u|r|y| +0#0000000&@8 +@2|m+0#00e0e07&|k|s|a| |i|n|c|h| |o|f| |m|e|r|c|u|r|y|;+0#0000000&| @24|m+0#00e0e07&|k|s|a|i|n|c|h|o|f|m|e|r|c|u|r|y| +0#0000000&@9 +@2|m+0#00e0e07&|k|s|a| |i|n|c|h| |o|f| |w|a|t|e|r|;+0#0000000&| @26|m+0#00e0e07&|k|s|a|i|n|c|h|o|f|w|a|t|e|r| +0#0000000&@11 +@2|m+0#00e0e07&|k|s|a| |p|s|i|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|p|s|i| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |p|o|i|s|e|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|p|o|i|s|e| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |s|t|o|k|e|s|;+0#0000000&| @33|m+0#00e0e07&|k|s|a|s|t|o|k|e|s| +0#0000000&@16 +@2|m+0#00e0e07&|k|s|a| |f|a|r|a|d|a|y|;+0#0000000&| @32|m+0#00e0e07&|k|s|a|f|a|r|a|d|a|y| +0#0000000&@15 +@2|m+0#00e0e07&|k|s|a| |e|l|e|c|t|r|o|n| |c|h|a|r|g|e|;+0#0000000&| @24|m+0#00e0e07&|k|s|a|e|l|e|c|t|r|o|n|c|h|a|r|g|e| +0#0000000&@8 +@2|m+0#00e0e07&|k|s|a| |g|a|u|s@1|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|g|a|u|s@1| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |s|t|i|l|b|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|s|t|i|l|b| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |l|u|m|e|n|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|l|u|m|e|n| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |l|u|x|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|l|u|x| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |p|h|o|t|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|p|h|o|t| +0#0000000&@18 +@57|2|0|5|6|,|3| @7|9|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_117.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_117.dump new file mode 100644 index 0000000000..931c7e9440 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_117.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|m+0#00e0e07&|k|s|a| |p|h|o|t|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|p|h|o|t| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |f|o@1|t| |c|a|n|d|l|e|;+0#0000000&| @28|m+0#00e0e07&|k|s|a|f|o@1|t|c|a|n|d|l|e| +0#0000000&@12 +@2|m+0#00e0e07&|k|s|a| |l|a|m|b|e|r|t|;+0#0000000&| @32|m+0#00e0e07&|k|s|a|l|a|m|b|e|r|t| +0#0000000&@15 +@2|m+0#00e0e07&|k|s|a| |f|o@1|t| |l|a|m|b|e|r|t|;+0#0000000&| @27|m+0#00e0e07&|k|s|a|f|o@1|t|l|a|m|b|e|r|t| +0#0000000&@11 +@2|m+0#00e0e07&|k|s|a| |c|u|r|i|e|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|c|u|r|i|e| +0#0000000&@17 +@2>m+0#00e0e07&|k|s|a| |r|o|e|n|t|g|e|n|;+0#0000000&| @31|m+0#00e0e07&|k|s|a|r|o|e|n|t|g|e|n| +0#0000000&@14 +@2|m+0#00e0e07&|k|s|a| |r|a|d|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|r|a|d| +0#0000000&@19 +@2|m+0#00e0e07&|k|s|a| |s|o|l|a|r| |m|a|s@1|;+0#0000000&| @29|m+0#00e0e07&|k|s|a|s|o|l|a|r|m|a|s@1| +0#0000000&@13 +@2|m+0#00e0e07&|k|s|a| |b|o|h|r| |r|a|d|i|u|s|;+0#0000000&| @28|m+0#00e0e07&|k|s|a|b|o|h|r@1|a|d|i|u|s| +0#0000000&@12 +@2|m+0#00e0e07&|k|s|a| |v|a|c|u@1|m| |p|e|r|m|i|t@1|i|v|i|t|y|;+0#0000000&| @20|m+0#00e0e07&|k|s|a|v|a|c|u@1|m|p|e|r|m|i|t@1|i|v|i|t|y| +0#0000000&@4 +@2|m+0#00e0e07&|k|s|a| |n|e|w|t|o|n|;+0#0000000&| @33|m+0#00e0e07&|k|s|a|n|e|w|t|o|n| +0#0000000&@16 +@2|m+0#00e0e07&|k|s|a| |d|y|n|e|;+0#0000000&| @35|m+0#00e0e07&|k|s|a|d|y|n|e| +0#0000000&@18 +@2|m+0#00e0e07&|k|s|a| |j|o|u|l|e|;+0#0000000&| @34|m+0#00e0e07&|k|s|a|j|o|u|l|e| +0#0000000&@17 +@2|m+0#00e0e07&|k|s|a| |e|r|g|;+0#0000000&| @36|m+0#00e0e07&|k|s|a|e|r|g| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |f|i|n|e| |s|t|r|u|c|t|u|r|e|;+0#0000000&| @26|n+0#00e0e07&|u|m|f|i|n|e|s|t|r|u|c|t|u|r|e| +0#0000000&@10 +@2|n+0#00e0e07&|u|m| |a|v|o|g|a|d|r|o|;+0#0000000&| @32|n+0#00e0e07&|u|m|a|v|o|g|a|d|r|o| +0#0000000&@15 +@2|n+0#00e0e07&|u|m| |y|o|t@1|a|;+0#0000000&| @35|n+0#00e0e07&|u|m|y|o|t@1|a| +0#0000000&@18 +@2|n+0#00e0e07&|u|m| |z|e|t@1|a|;+0#0000000&| @35|n+0#00e0e07&|u|m|z|e|t@1|a| +0#0000000&@18 +@2|n+0#00e0e07&|u|m| |e|x|a|;+0#0000000&| @37|n+0#00e0e07&|u|m|e|x|a| +0#0000000&@20 +@57|2|0|7|4|,|3| @7|9|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_118.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_118.dump new file mode 100644 index 0000000000..f48a517ea6 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_118.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|n+0#00e0e07&|u|m| |e|x|a|;+0#0000000&| @37|n+0#00e0e07&|u|m|e|x|a| +0#0000000&@20 +@2|n+0#00e0e07&|u|m| |p|e|t|a|;+0#0000000&| @36|n+0#00e0e07&|u|m|p|e|t|a| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |t|e|r|a|;+0#0000000&| @36|n+0#00e0e07&|u|m|t|e|r|a| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |g|i|g|a|;+0#0000000&| @36|n+0#00e0e07&|u|m|g|i|g|a| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |m|e|g|a|;+0#0000000&| @36|n+0#00e0e07&|u|m@1|e|g|a| +0#0000000&@19 +@2>n+0#00e0e07&|u|m| |k|i|l|o|;+0#0000000&| @36|n+0#00e0e07&|u|m|k|i|l|o| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |m|i|l@1|i|;+0#0000000&| @35|n+0#00e0e07&|u|m@1|i|l@1|i| +0#0000000&@18 +@2|n+0#00e0e07&|u|m| |m|i|c|r|o|;+0#0000000&| @35|n+0#00e0e07&|u|m@1|i|c|r|o| +0#0000000&@18 +@2|n+0#00e0e07&|u|m| |n|a|n|o|;+0#0000000&| @36|n+0#00e0e07&|u|m|n|a|n|o| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |p|i|c|o|;+0#0000000&| @36|n+0#00e0e07&|u|m|p|i|c|o| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |f|e|m|t|o|;+0#0000000&| @35|n+0#00e0e07&|u|m|f|e|m|t|o| +0#0000000&@18 +@2|n+0#00e0e07&|u|m| |a|t@1|o|;+0#0000000&| @36|n+0#00e0e07&|u|m|a|t@1|o| +0#0000000&@19 +@2|n+0#00e0e07&|u|m| |z|e|p|t|o|;+0#0000000&| @35|n+0#00e0e07&|u|m|z|e|p|t|o| +0#0000000&@18 +@2|n+0#00e0e07&|u|m| |y|o|c|t|o|;+0#0000000&| @35|n+0#00e0e07&|u|m|y|o|c|t|o| +0#0000000&@18 +|#+0#0000e05&| |F@1|T|.| |#| +0#0000000&@66 +@2|p+0#00e0e07&|r|i|m|e|f|a|c|t|o|r|s|;+0#0000000&| @32|p+0#00e0e07&|r|i|m|e|f|a|c|t|o|r|s| +0#0000000&@14 +@2|f+0#00e0e07&@1|t| |c|o|m|p|l|e|x| |f|o|r|w|a|r|d|;+0#0000000&| @25|f+0#00e0e07&@1|t|c|o|m|p|l|e|x|f|o|r|w|a|r|d| +0#0000000&@9 +@2|f+0#00e0e07&@1|t| |c|o|m|p|l|e|x| |b|a|c|k|w|a|r|d|;+0#0000000&| @24|f+0#00e0e07&@1|t|c|o|m|p|l|e|x|b|a|c|k|w|a|r|d| +0#0000000&@8 +@2|f+0#00e0e07&@1|t| |c|o|m|p|l|e|x| |i|n|v|e|r|s|e|;+0#0000000&| @25|f+0#00e0e07&@1|t|c|o|m|p|l|e|x|i|n|v|e|r|s|e| +0#0000000&@9 +@57|2|0|9|2|,|3| @7|9@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_119.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_119.dump new file mode 100644 index 0000000000..75e30b06fc --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_119.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|f+0#00e0e07&@1|t| |c|o|m|p|l|e|x| |i|n|v|e|r|s|e|;+0#0000000&| @25|f+0#00e0e07&@1|t|c|o|m|p|l|e|x|i|n|v|e|r|s|e| +0#0000000&@9 +@2|f+0#00e0e07&@1|t| |f|o|r|w|a|r|d|;+0#0000000&| @33|f+0#00e0e07&@1|t|f|o|r|w|a|r|d| +0#0000000&@16 +@2|f+0#00e0e07&@1|t| |b|a|c|k|w|a|r|d|;+0#0000000&| @32|f+0#00e0e07&@1|t|b|a|c|k|w|a|r|d| +0#0000000&@15 +@2|f+0#00e0e07&@1|t| |i|n|v|e|r|s|e|;+0#0000000&| @33|f+0#00e0e07&@1|t|i|n|v|e|r|s|e| +0#0000000&@16 +|#+0#0000e05&| |L|a|p|l|a|c|e|.| |#| +0#0000000&@62 +@2>l+0#00e0e07&|a|p|l|a|c|e|;+0#0000000&| @37|l+0#00e0e07&|a|p|l|a|c|e| +0#0000000&@19 +@75 +@75 +|#+0#0000e05&| |v|i|m|:| |s|y|n|t|a|x|=|a|l|g|o|l|6|8| |t|s|=|4|8| +0#0000000&@47 +|#+0#0000e05&| +0#0000000&@73 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|2|1@1|0|,|3| @7|B|o|t| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_12.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_12.dump new file mode 100644 index 0000000000..eb3df3b95e --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_12.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|M+0#af5f00255&|O|D|A|B| +0#0000000&@40|M+0#af5f00255&|O|D|A|B| +0#0000000&@21 +|#+0#0000e05&| |R|E|A|L| |o|p|s|.| |#| +0#0000000&@61 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2>S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|R+0#af5f00255&|O|U|N|D| +0#0000000&@40|R+0#af5f00255&|O|U|N|D| +0#0000000&@21 +@2|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@39|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@20 +@2|F+0#af5f00255&|L|O@1|R| +0#0000000&@40|F+0#af5f00255&|L|O@1|R| +0#0000000&@21 +@2|C+0#af5f00255&|E|I|L| +0#0000000&@41|C+0#af5f00255&|E|I|L| +0#0000000&@22 +@2|N+0#af5f00255&|I|N|T| +0#0000000&@41|N+0#af5f00255&|I|N|T| +0#0000000&@22 +@2|T+0#af5f00255&|R|U|N|C| +0#0000000&@40|T+0#af5f00255&|R|U|N|C| +0#0000000&@21 +@2|F+0#af5f00255&|R|A|C| +0#0000000&@41|F+0#af5f00255&|R|A|C| +0#0000000&@22 +@2|F+0#af5f00255&|I|X| +0#0000000&@42|F+0#af5f00255&|I|X| +0#0000000&@23 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@57|2|1|7|,|3| @8|1|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_13.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_13.dump new file mode 100644 index 0000000000..00849c3523 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_13.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2>N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@57|2|3|5|,|3| @8|1|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_14.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_14.dump new file mode 100644 index 0000000000..9da6626028 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_14.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2>/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +|#+0#0000e05&| |P|r|o|c|e|d|u|r|e|s| |#| +0#0000000&@60 +@2|a+0#00e0e07&|r|c| |c|o|s| |d|g|;+0#0000000&| @1|a+0#00e0e07&|c|o|s| |d|g|;+0#0000000&| @24|a+0#00e0e07&|r|c@1|o|s|d|g|;+0#0000000&| @1|a+0#00e0e07&|c|o|s|d|g| +0#0000000&@9 +@2|a+0#00e0e07&|r|c| |c|o|s|h|;+0#0000000&| @1|a+0#00e0e07&|c|o|s|h|;+0#0000000&| @28|a+0#00e0e07&|r|c@1|o|s|h|;+0#0000000&| @1|a+0#00e0e07&|c|o|s|h| +0#0000000&@11 +@2|a+0#00e0e07&|r|c| |c|o|t|;+0#0000000&| @1|a+0#00e0e07&|c|o|t|;+0#0000000&| @30|a+0#00e0e07&|r|c@1|o|t|;+0#0000000&| @1|a+0#00e0e07&|c|o|t| +0#0000000&@13 +@2|a+0#00e0e07&|r|c| |c|o|t| |d|g|;+0#0000000&| @1|a+0#00e0e07&|c|o|t| |d|g|;+0#0000000&| @24|a+0#00e0e07&|r|c@1|o|t|d|g|;+0#0000000&| @1|a+0#00e0e07&|c|o|t|d|g| +0#0000000&@9 +@2|a+0#00e0e07&|r|c| |c|s|c|;+0#0000000&| @1|a+0#00e0e07&|c|s|c|;+0#0000000&| @30|a+0#00e0e07&|r|c@1|s|c|;+0#0000000&| @1|a+0#00e0e07&|c|s|c| +0#0000000&@13 +@2|a+0#00e0e07&|r|c| |c|s|c| |d|g|;+0#0000000&| @1|a+0#00e0e07&|c|s|c| |d|g|;+0#0000000&| @24|a+0#00e0e07&|r|c@1|s|c|d|g|;+0#0000000&| @1|a+0#00e0e07&|c|s|c|d|g| +0#0000000&@9 +@2|a+0#00e0e07&|r|c| |s|e|c|;+0#0000000&| @1|a+0#00e0e07&|s|e|c|;+0#0000000&| @30|a+0#00e0e07&|r|c|s|e|c|;+0#0000000&| @1|a+0#00e0e07&|s|e|c| +0#0000000&@13 +@2|a+0#00e0e07&|r|c| |s|e|c| |d|g|;+0#0000000&| @1|a+0#00e0e07&|s|e|c| |d|g|;+0#0000000&| @24|a+0#00e0e07&|r|c|s|e|c|d|g|;+0#0000000&| @1|a+0#00e0e07&|s|e|c|d|g| +0#0000000&@9 +@57|2|5|3|,|3| @8|1@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_15.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_15.dump new file mode 100644 index 0000000000..3c99c60926 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_15.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|a+0#00e0e07&|r|c| |s|e|c| |d|g|;+0#0000000&| @1|a+0#00e0e07&|s|e|c| |d|g|;+0#0000000&| @24|a+0#00e0e07&|r|c|s|e|c|d|g|;+0#0000000&| @1|a+0#00e0e07&|s|e|c|d|g| +0#0000000&@9 +@2|a+0#00e0e07&|r|c| |s|i|n| |d|g|;+0#0000000&| @1|a+0#00e0e07&|s|i|n| |d|g|;+0#0000000&| @24|a+0#00e0e07&|r|c|s|i|n|d|g|;+0#0000000&| @1|a+0#00e0e07&|s|i|n|d|g| +0#0000000&@9 +@2|a+0#00e0e07&|r|c| |s|i|n|h|;+0#0000000&| @1|a+0#00e0e07&|s|i|n|h|;+0#0000000&| @28|a+0#00e0e07&|r|c|s|i|n|h|;+0#0000000&| @1|a+0#00e0e07&|s|i|n|h| +0#0000000&@11 +@2|a+0#00e0e07&|r|c| |t|a|n| |d|g|;+0#0000000&| @1|a+0#00e0e07&|t|a|n| |d|g|;+0#0000000&| @24|a+0#00e0e07&|r|c|t|a|n|d|g|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|d|g| +0#0000000&@9 +@2|a+0#00e0e07&|r|c| |t|a|n|h|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|h|;+0#0000000&| @28|a+0#00e0e07&|r|c|t|a|n|h|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|h| +0#0000000&@11 +@2>a+0#00e0e07&|r|c| |c|o|s|;+0#0000000&| @1|a+0#00e0e07&|c|o|s|;+0#0000000&| @30|a+0#00e0e07&|r|c@1|o|s|;+0#0000000&| @1|a+0#00e0e07&|c|o|s| +0#0000000&@13 +@2|a+0#00e0e07&|r|c| |s|i|n|;+0#0000000&| @1|a+0#00e0e07&|s|i|n|;+0#0000000&| @30|a+0#00e0e07&|r|c|s|i|n|;+0#0000000&| @1|a+0#00e0e07&|s|i|n| +0#0000000&@13 +@2|a+0#00e0e07&|r|c| |t|a|n|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|;+0#0000000&| @30|a+0#00e0e07&|r|c|t|a|n|;+0#0000000&| @1|a+0#00e0e07&|t|a|n| +0#0000000&@13 +@2|c+0#00e0e07&|a|s|;+0#0000000&| @41|c+0#00e0e07&|a|s| +0#0000000&@23 +@2|c+0#00e0e07&|b|r|t|;+0#0000000&| @40|c+0#00e0e07&|b|r|t| +0#0000000&@22 +@2|c+0#00e0e07&|o|s| |d|g|;+0#0000000&| @38|c+0#00e0e07&|o|s|d|g| +0#0000000&@21 +@2|c+0#00e0e07&|o|s|h|;+0#0000000&| @40|c+0#00e0e07&|o|s|h| +0#0000000&@22 +@2|c+0#00e0e07&|o|s| |p|i|;+0#0000000&| @38|c+0#00e0e07&|o|s|p|i| +0#0000000&@21 +@2|c+0#00e0e07&|o|t| |d|g|;+0#0000000&| @38|c+0#00e0e07&|o|t|d|g| +0#0000000&@21 +@2|c+0#00e0e07&|o|t|;+0#0000000&| @41|c+0#00e0e07&|o|t| +0#0000000&@23 +@2|c+0#00e0e07&|o|t| |p|i|;+0#0000000&| @38|c+0#00e0e07&|o|t|p|i| +0#0000000&@21 +@2|c+0#00e0e07&|s|c| |d|g|;+0#0000000&| @38|c+0#00e0e07&|s|c|d|g| +0#0000000&@21 +@2|c+0#00e0e07&|s|c|;+0#0000000&| @41|c+0#00e0e07&|s|c| +0#0000000&@23 +@2|c+0#00e0e07&|u|r|t|;+0#0000000&| @40|c+0#00e0e07&|u|r|t| +0#0000000&@22 +@57|2|7|1|,|3| @8|1|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_16.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_16.dump new file mode 100644 index 0000000000..4e448abc4a --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_16.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|u|r|t|;+0#0000000&| @40|c+0#00e0e07&|u|r|t| +0#0000000&@22 +@2|e+0#00e0e07&|r|f|c|;+0#0000000&| @40|e+0#00e0e07&|r|f|c| +0#0000000&@22 +@2|e+0#00e0e07&|r|f|;+0#0000000&| @41|e+0#00e0e07&|r|f| +0#0000000&@23 +@2|g+0#00e0e07&|a|m@1|a|;+0#0000000&| @39|g+0#00e0e07&|a|m@1|a| +0#0000000&@21 +@2|i+0#00e0e07&|n|v| |e|r|f|c|;+0#0000000&| @36|i+0#00e0e07&|n|v|e|r|f|c| +0#0000000&@19 +@2>i+0#00e0e07&|n|v| |e|r|f|;+0#0000000&| @37|i+0#00e0e07&|n|v|e|r|f| +0#0000000&@20 +@2|i+0#00e0e07&|n|v|e|r|s|e| |e|r|f|c|;+0#0000000&| @32|i+0#00e0e07&|n|v|e|r|s|e@1|r|f|c| +0#0000000&@15 +@2|i+0#00e0e07&|n|v|e|r|s|e| |e|r|f|;+0#0000000&| @33|i+0#00e0e07&|n|v|e|r|s|e@1|r|f| +0#0000000&@16 +@2|l+0#00e0e07&|n|1|p|;+0#0000000&| @40|l+0#00e0e07&|n|1|p| +0#0000000&@22 +@2|l+0#00e0e07&|n| |g|a|m@1|a|;+0#0000000&| @36|l+0#00e0e07&|n|g|a|m@1|a| +0#0000000&@19 +@2|s+0#00e0e07&|e|c| |d|g|;+0#0000000&| @38|s+0#00e0e07&|e|c|d|g| +0#0000000&@21 +@2|s+0#00e0e07&|e|c|;+0#0000000&| @41|s+0#00e0e07&|e|c| +0#0000000&@23 +@2|s+0#00e0e07&|i|n| |d|g|;+0#0000000&| @38|s+0#00e0e07&|i|n|d|g| +0#0000000&@21 +@2|s+0#00e0e07&|i|n|h|;+0#0000000&| @40|s+0#00e0e07&|i|n|h| +0#0000000&@22 +@2|s+0#00e0e07&|i|n| |p|i|;+0#0000000&| @38|s+0#00e0e07&|i|n|p|i| +0#0000000&@21 +@2|t+0#00e0e07&|a|n| |d|g|;+0#0000000&| @38|t+0#00e0e07&|a|n|d|g| +0#0000000&@21 +@2|t+0#00e0e07&|a|n|h|;+0#0000000&| @40|t+0#00e0e07&|a|n|h| +0#0000000&@22 +@2|t+0#00e0e07&|a|n| |p|i|;+0#0000000&| @38|t+0#00e0e07&|a|n|p|i| +0#0000000&@21 +@2|c+0#00e0e07&|o|s|;+0#0000000&| @41|c+0#00e0e07&|o|s| +0#0000000&@23 +@57|2|8|9|,|3| @8|1|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_17.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_17.dump new file mode 100644 index 0000000000..9b5fa34f69 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_17.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|o|s|;+0#0000000&| @41|c+0#00e0e07&|o|s| +0#0000000&@23 +@2|e+0#00e0e07&|x|p|;+0#0000000&| @41|e+0#00e0e07&|x|p| +0#0000000&@23 +@2|l+0#00e0e07&|n|;+0#0000000&| @42|l+0#00e0e07&|n| +0#0000000&@24 +@2|l+0#00e0e07&|o|g|;+0#0000000&| @41|l+0#00e0e07&|o|g| +0#0000000&@23 +@2|s+0#00e0e07&|i|n|;+0#0000000&| @41|s+0#00e0e07&|i|n| +0#0000000&@23 +@2>s+0#00e0e07&|q|r|t|;+0#0000000&| @40|s+0#00e0e07&|q|r|t| +0#0000000&@22 +@2|t+0#00e0e07&|a|n|;+0#0000000&| @41|t+0#00e0e07&|a|n| +0#0000000&@23 +|#+0#0000e05&| |M|i|s|c|e|l@1|a|n|e|o|u|s|.| |#| +0#0000000&@56 +@2|a+0#00e0e07&|r|c| |t|a|n|2|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|2|;+0#0000000&| @28|a+0#00e0e07&|r|c|t|a|n|2|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|2| +0#0000000&@11 +@2|a+0#00e0e07&|r|c| |t|a|n|2| |d|g|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|2| |d|g|;+0#0000000&| @22|a+0#00e0e07&|r|c|t|a|n|2|d|g|;+0#0000000&| @1|a+0#00e0e07&|t|a|n|2|d|g| +0#0000000&@7 +@2|b+0#00e0e07&|e|t|a|;+0#0000000&| @40|b+0#00e0e07&|e|t|a| +0#0000000&@22 +@2|b+0#00e0e07&|e|t|a|i|n|c|;+0#0000000&| @37|b+0#00e0e07&|e|t|a|i|n|c| +0#0000000&@19 +@2|c+0#00e0e07&|h|o@1|s|e|;+0#0000000&| @38|c+0#00e0e07&|h|o@1|s|e| +0#0000000&@20 +@2|f+0#00e0e07&|a|c|t|;+0#0000000&| @40|f+0#00e0e07&|a|c|t| +0#0000000&@22 +@2|g+0#00e0e07&|a|m@1|a| |i|n|c|;+0#0000000&| @35|g+0#00e0e07&|a|m@1|a|i|n|c| +0#0000000&@18 +@2|g+0#00e0e07&|a|m@1|a| |i|n|c|f|;+0#0000000&| @34|g+0#00e0e07&|a|m@1|a|i|n|c|f| +0#0000000&@17 +@2|g+0#00e0e07&|a|m@1|a| |i|n|c|g|;+0#0000000&| @34|g+0#00e0e07&|a|m@1|a|i|n|c|g| +0#0000000&@17 +@2|g+0#00e0e07&|a|m@1|a| |i|n|c|g|f|;+0#0000000&| @33|g+0#00e0e07&|a|m@1|a|i|n|c|g|f| +0#0000000&@16 +@2|l+0#00e0e07&|j|e|1|2|6|;+0#0000000&| @38|l+0#00e0e07&|j|e|1|2|6| +0#0000000&@20 +@57|3|0|7|,|3| @8|1|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_18.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_18.dump new file mode 100644 index 0000000000..a7682a2165 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_18.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|j|e|1|2|6|;+0#0000000&| @38|l+0#00e0e07&|j|e|1|2|6| +0#0000000&@20 +@2|l+0#00e0e07&|j|f|1|2|6|;+0#0000000&| @38|l+0#00e0e07&|j|f|1|2|6| +0#0000000&@20 +@2|l+0#00e0e07&|n| |b|e|t|a|;+0#0000000&| @37|l+0#00e0e07&|n|b|e|t|a| +0#0000000&@20 +@2|l+0#00e0e07&|n| |c|h|o@1|s|e|;+0#0000000&| @35|l+0#00e0e07&|n|c|h|o@1|s|e| +0#0000000&@18 +@2|l+0#00e0e07&|n| |f|a|c|t|;+0#0000000&| @37|l+0#00e0e07&|n|f|a|c|t| +0#0000000&@20 +>#+0#0000e05&| |C|O|M|P|L|E|X| |o|p|s|.| |#| +0#0000000&@58 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +@2|R+0#af5f00255&|E| +0#0000000&@43|R+0#af5f00255&|E| +0#0000000&@24 +@2|I+0#af5f00255&|M| +0#0000000&@43|I+0#af5f00255&|M| +0#0000000&@24 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|A+0#af5f00255&|R|G| +0#0000000&@42|A+0#af5f00255&|R|G| +0#0000000&@23 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|C+0#af5f00255&|O|N|J| +0#0000000&@41|C+0#af5f00255&|O|N|J| +0#0000000&@22 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@57|3|2|5|,|1| @8|1|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_19.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_19.dump new file mode 100644 index 0000000000..3ba4d30f0e --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_19.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2>++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@57|3|4|3|,|3| @8|1|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_20.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_20.dump new file mode 100644 index 0000000000..fdfce7d921 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_20.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +@2|c+0#00e0e07&|o|m|p|l|e|x| |a|r|c@1|o|s|h|;+0#0000000&| @1|c+0#00e0e07&|a|c|o|s|h|;+0#0000000&| @20|c+0#00e0e07&|o|m|p|l|e|x|a|r|c@1|o|s|h|;+0#0000000&| @1|c+0#00e0e07&|a|c|o|s|h| +0#0000000&@3 +@2|c+0#00e0e07&|o|m|p|l|e|x| |a|r|c@1|o|s|;+0#0000000&| @1|c+0#00e0e07&|a|c|o|s|;+0#0000000&| @22|c+0#00e0e07&|o|m|p|l|e|x|a|r|c@1|o|s|;+0#0000000&| @1|c+0#00e0e07&|a|c|o|s| +0#0000000&@5 +@2|c+0#00e0e07&|o|m|p|l|e|x| |a|r|c|s|i|n|h|;+0#0000000&| @1|c+0#00e0e07&|a|s|i|n|h|;+0#0000000&| @20|c+0#00e0e07&|o|m|p|l|e|x|a|r|c|s|i|n|h|;+0#0000000&| @1|c+0#00e0e07&|a|s|i|n|h| +0#0000000&@3 +@2>c+0#00e0e07&|o|m|p|l|e|x| |a|r|c|s|i|n|;+0#0000000&| @1|c+0#00e0e07&|a|s|i|n|;+0#0000000&| @22|c+0#00e0e07&|o|m|p|l|e|x|a|r|c|s|i|n|;+0#0000000&| @1|c+0#00e0e07&|a|s|i|n| +0#0000000&@5 +@2|c+0#00e0e07&|o|m|p|l|e|x| |a|r|c|t|a|n|h|;+0#0000000&| @1|c+0#00e0e07&|a|t|a|n|h|;+0#0000000&| @20|c+0#00e0e07&|o|m|p|l|e|x|a|r|c|t|a|n|h|;+0#0000000&| @1|c+0#00e0e07&|a|t|a|n|h| +0#0000000&@3 +@2|c+0#00e0e07&|o|m|p|l|e|x| |a|r|c|t|a|n|;+0#0000000&| @1|c+0#00e0e07&|a|t|a|n|;+0#0000000&| @22|c+0#00e0e07&|o|m|p|l|e|x|a|r|c|t|a|n|;+0#0000000&| @1|c+0#00e0e07&|a|t|a|n| +0#0000000&@5 +@2|c+0#00e0e07&|o|m|p|l|e|x| |c|o|s|h|;+0#0000000&| @1|c+0#00e0e07&@1|o|s|h|;+0#0000000&| @24|c+0#00e0e07&|o|m|p|l|e|x|c|o|s|h|;+0#0000000&| @1|c+0#00e0e07&@1|o|s|h| +0#0000000&@7 +@2|c+0#00e0e07&|o|m|p|l|e|x| |c|o|s|;+0#0000000&| @1|c+0#00e0e07&@1|o|s|;+0#0000000&| @26|c+0#00e0e07&|o|m|p|l|e|x|c|o|s|;+0#0000000&| @1|c+0#00e0e07&@1|o|s| +0#0000000&@9 +@2|c+0#00e0e07&|o|m|p|l|e|x| |e|x|p|;+0#0000000&| @1|c+0#00e0e07&|e|x|p|;+0#0000000&| @26|c+0#00e0e07&|o|m|p|l|e|x|e|x|p|;+0#0000000&| @1|c+0#00e0e07&|e|x|p| +0#0000000&@9 +@2|c+0#00e0e07&|o|m|p|l|e|x| |l|n|;+0#0000000&| @1|c+0#00e0e07&|l|n|;+0#0000000&| @28|c+0#00e0e07&|o|m|p|l|e|x|l|n|;+0#0000000&| @1|c+0#00e0e07&|l|n| +0#0000000&@11 +@2|c+0#00e0e07&|o|m|p|l|e|x| |s|i|n|h|;+0#0000000&| @1|c+0#00e0e07&|s|i|n|h|;+0#0000000&| @24|c+0#00e0e07&|o|m|p|l|e|x|s|i|n|h|;+0#0000000&| @1|c+0#00e0e07&|s|i|n|h| +0#0000000&@7 +@2|c+0#00e0e07&|o|m|p|l|e|x| |s|i|n|;+0#0000000&| @1|c+0#00e0e07&|s|i|n|;+0#0000000&| @26|c+0#00e0e07&|o|m|p|l|e|x|s|i|n|;+0#0000000&| @1|c+0#00e0e07&|s|i|n| +0#0000000&@9 +@2|c+0#00e0e07&|o|m|p|l|e|x| |s|q|r|t|;+0#0000000&| @1|c+0#00e0e07&|s|q|r|t|;+0#0000000&| @24|c+0#00e0e07&|o|m|p|l|e|x|s|q|r|t|;+0#0000000&| @1|c+0#00e0e07&|s|q|r|t| +0#0000000&@7 +@2|c+0#00e0e07&|o|m|p|l|e|x| |t|a|n|h|;+0#0000000&| @1|c+0#00e0e07&|t|a|n|h|;+0#0000000&| @24|c+0#00e0e07&|o|m|p|l|e|x|t|a|n|h|;+0#0000000&| @1|c+0#00e0e07&|t|a|n|h| +0#0000000&@7 +@2|c+0#00e0e07&|o|m|p|l|e|x| |t|a|n|;+0#0000000&| @1|c+0#00e0e07&|t|a|n|;+0#0000000&| @26|c+0#00e0e07&|o|m|p|l|e|x|t|a|n|;+0#0000000&| @1|c+0#00e0e07&|t|a|n| +0#0000000&@9 +|#+0#0000e05&| |B|O@1|L| |o|p|s|.| |#| +0#0000000&@61 +@2|N+0#af5f00255&|O|T| +0#0000000&@42|N+0#af5f00255&|O|T| +0#0000000&@23 +@57|3|6|1|,|3| @8|1|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_21.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_21.dump new file mode 100644 index 0000000000..b037850de0 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_21.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|N+0#af5f00255&|O|T| +0#0000000&@42|N+0#af5f00255&|O|T| +0#0000000&@23 +@2|~+0#af5f00255&| +0#0000000&@44|~+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|O+0#af5f00255&|R| +0#0000000&@43|O+0#af5f00255&|R| +0#0000000&@24 +@2|A+0#af5f00255&|N|D| +0#0000000&@42|A+0#af5f00255&|N|D| +0#0000000&@23 +@2>&+0#af5f00255&| +0#0000000&@44|&+0#af5f00255&| +0#0000000&@25 +@2|X+0#af5f00255&|O|R| +0#0000000&@42|X+0#af5f00255&|O|R| +0#0000000&@23 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +|#+0#0000e05&| |C|H|A|R| |o|p|s|.| |#| +0#0000000&@61 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@57|3|7|9|,|3| @8|1|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_22.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_22.dump new file mode 100644 index 0000000000..f10e7fb4ef --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_22.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2>N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|R+0#af5f00255&|E|P|R| +0#0000000&@41|R+0#af5f00255&|E|P|R| +0#0000000&@22 +@2|i+0#00e0e07&|s| |a|l|n|u|m|;+0#0000000&| @36|i+0#00e0e07&|s|a|l|n|u|m| +0#0000000&@19 +@2|i+0#00e0e07&|s| |a|l|p|h|a|;+0#0000000&| @36|i+0#00e0e07&|s|a|l|p|h|a| +0#0000000&@19 +@2|i+0#00e0e07&|s| |c|n|t|r|l|;+0#0000000&| @36|i+0#00e0e07&|s|c|n|t|r|l| +0#0000000&@19 +@2|i+0#00e0e07&|s| |d|i|g|i|t|;+0#0000000&| @36|i+0#00e0e07&|s|d|i|g|i|t| +0#0000000&@19 +@2|i+0#00e0e07&|s| |g|r|a|p|h|;+0#0000000&| @36|i+0#00e0e07&|s|g|r|a|p|h| +0#0000000&@19 +@2|i+0#00e0e07&|s| |l|o|w|e|r|;+0#0000000&| @36|i+0#00e0e07&|s|l|o|w|e|r| +0#0000000&@19 +@2|i+0#00e0e07&|s| |p|r|i|n|t|;+0#0000000&| @36|i+0#00e0e07&|s|p|r|i|n|t| +0#0000000&@19 +@57|3|9|7|,|3| @8|1|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_23.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_23.dump new file mode 100644 index 0000000000..044dfb4a58 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_23.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|i+0#00e0e07&|s| |p|r|i|n|t|;+0#0000000&| @36|i+0#00e0e07&|s|p|r|i|n|t| +0#0000000&@19 +@2|i+0#00e0e07&|s| |p|u|n|c|t|;+0#0000000&| @36|i+0#00e0e07&|s|p|u|n|c|t| +0#0000000&@19 +@2|i+0#00e0e07&|s| |s|p|a|c|e|;+0#0000000&| @36|i+0#00e0e07&|s@1|p|a|c|e| +0#0000000&@19 +@2|i+0#00e0e07&|s| |u|p@1|e|r|;+0#0000000&| @36|i+0#00e0e07&|s|u|p@1|e|r| +0#0000000&@19 +@2|i+0#00e0e07&|s| |x|d|i|g|i|t|;+0#0000000&| @35|i+0#00e0e07&|s|x|d|i|g|i|t| +0#0000000&@18 +@2>t+0#00e0e07&|o| |l|o|w|e|r|;+0#0000000&| @36|t+0#00e0e07&|o|l|o|w|e|r| +0#0000000&@19 +@2|t+0#00e0e07&|o| |u|p@1|e|r|;+0#0000000&| @36|t+0#00e0e07&|o|u|p@1|e|r| +0#0000000&@19 +|#+0#0000e05&| |B|I|T|S| |o|p|s|.| |#| +0#0000000&@61 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|B+0#af5f00255&|I|N| +0#0000000&@42|B+0#af5f00255&|I|N| +0#0000000&@23 +@2|N+0#af5f00255&|O|T| +0#0000000&@42|N+0#af5f00255&|O|T| +0#0000000&@23 +@2|~+0#af5f00255&| +0#0000000&@44|~+0#af5f00255&| +0#0000000&@25 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@57|4|1|5|,|3| @8|1|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_24.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_24.dump new file mode 100644 index 0000000000..112129dbf9 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_24.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2>>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|A+0#af5f00255&|N|D| +0#0000000&@42|A+0#af5f00255&|N|D| +0#0000000&@23 +@2|&+0#af5f00255&| +0#0000000&@44|&+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|R| +0#0000000&@43|O+0#af5f00255&|R| +0#0000000&@24 +@2|X+0#af5f00255&|O|R| +0#0000000&@42|X+0#af5f00255&|O|R| +0#0000000&@23 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|V|E|R| +0#0000000&@41|O+0#af5f00255&|V|E|R| +0#0000000&@22 +@2|M+0#af5f00255&|O|D| +0#0000000&@42|M+0#af5f00255&|O|D| +0#0000000&@23 +@2|S+0#af5f00255&|H|L| +0#0000000&@42|S+0#af5f00255&|H|L| +0#0000000&@23 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@57|4|3@1|,|3| @8|2|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_25.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_25.dump new file mode 100644 index 0000000000..dce5d316da --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_25.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|S+0#af5f00255&|H|R| +0#0000000&@42|S+0#af5f00255&|H|R| +0#0000000&@23 +@2|D+0#af5f00255&|O|W|N| +0#0000000&@41|D+0#af5f00255&|O|W|N| +0#0000000&@22 +@2|R+0#af5f00255&|O|L| +0#0000000&@42|R+0#af5f00255&|O|L| +0#0000000&@23 +@2|R+0#af5f00255&|O|R| +0#0000000&@42|R+0#af5f00255&|O|R| +0#0000000&@23 +@2>E+0#af5f00255&|L|E|M| +0#0000000&@41|E+0#af5f00255&|L|E|M| +0#0000000&@22 +@2|S+0#af5f00255&|E|T| +0#0000000&@42|S+0#af5f00255&|E|T| +0#0000000&@23 +@2|C+0#af5f00255&|L|E|A|R| +0#0000000&@40|C+0#af5f00255&|L|E|A|R| +0#0000000&@21 +|#+0#0000e05&| |L|O|N|G| |L|O|N|G| |I|N|T| |i|n| |s|o|f|t|w|a|r|e| |#| +0#0000000&@45 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|O+0#af5f00255&|D@1| +0#0000000&@42|O+0#af5f00255&|D@1| +0#0000000&@23 +@2|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@39|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@20 +@2|R+0#af5f00255&|O|U|N|D| +0#0000000&@40|R+0#af5f00255&|O|U|N|D| +0#0000000&@21 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@57|4|5|1|,|3| @8|2|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_26.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_26.dump new file mode 100644 index 0000000000..4c7e8b7a43 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_26.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|V|E|R| +0#0000000&@41|O+0#af5f00255&|V|E|R| +0#0000000&@22 +@2|%+0#af5f00255&| +0#0000000&@44|%+0#af5f00255&| +0#0000000&@25 +@2|M+0#af5f00255&|O|D| +0#0000000&@42|M+0#af5f00255&|O|D| +0#0000000&@23 +@2|%+0#af5f00255&|*| +0#0000000&@43|%+0#af5f00255&|*| +0#0000000&@24 +@2>++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|%+0#af5f00255&|:|=| +0#0000000&@42|%+0#af5f00255&|:|=| +0#0000000&@23 +@2|%+0#af5f00255&|*|:|=| +0#0000000&@41|%+0#af5f00255&|*|:|=| +0#0000000&@22 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@39|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|O|D|A|B| +0#0000000&@40|M+0#af5f00255&|O|D|A|B| +0#0000000&@21 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@57|4|6|9|,|3| @8|2@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_27.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_27.dump new file mode 100644 index 0000000000..76db54947a --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_27.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2>>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +|#+0#0000e05&| |L|O|N|G| |L|O|N|G| |R|E|A|L| |i|n| |s|o|f|t|w|a|r|e| |#| +0#0000000&@44 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@57|4|8|7|,|3| @8|2@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_28.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_28.dump new file mode 100644 index 0000000000..1c7ba5f03a --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_28.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c@1|o|s|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|s| |d|g|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c@1|o|s|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|s|d|g| +0#0000000& +@2>l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c@1|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|s|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c@1|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|s|h| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c@1|o|t|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|t| |d|g|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c@1|o|t|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|t|d|g| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c@1|o|t|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|t|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c@1|o|t|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|t| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c@1|s|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|c|s|c| |d|g|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c@1|s|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|c|s|c|d|g| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c@1|s|c|;+0#0000000&| @1|q+0#00e0e07&|a|c|s|c|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c@1|s|c|;+0#0000000&| @1|q+0#00e0e07&|a|c|s|c| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|s|e|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|s|e|c| |d|g|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|s|e|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|s|e|c|d|g| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|s|e|c|;+0#0000000&| @1|q+0#00e0e07&|a|s|e|c|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|s|e|c|;+0#0000000&| @1|q+0#00e0e07&|a|s|e|c| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|s|i|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|s|i|n| |d|g|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|s|i|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|s|i|n|d|g| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|a|s|i|n|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|a|s|i|n|h| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|t|a|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n| |d|g|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|t|a|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|d|g| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|h| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|a|s|;+0#0000000&| @1|q+0#00e0e07&|c|a|s|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|c|a|s|;+0#0000000&| @1|q+0#00e0e07&|c|a|s| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|b|r|t|;+0#0000000&| @1|q+0#00e0e07&|c|b|r|t|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|c|b|r|t|;+0#0000000&| @1|q+0#00e0e07&|c|b|r|t| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|s|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|o|s| |d|g|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|s|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|o|s|d|g| +0#0000000&@4 +@57|5|0|5|,|3| @8|2|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_29.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_29.dump new file mode 100644 index 0000000000..e1e7b78383 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_29.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|s|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|o|s| |d|g|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|s|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|o|s|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|c|o|s|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|c|o|s|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|s|p|i|;+0#0000000&| @1|q+0#00e0e07&|c|o|s| |p|i|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|s|p|i|;+0#0000000&| @1|q+0#00e0e07&|c|o|s|p|i| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|t|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|o|t| |d|g|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|t|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|o|t|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|t|p|i|;+0#0000000&| @1|q+0#00e0e07&|c|o|t| |p|i|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|t|p|i|;+0#0000000&| @1|q+0#00e0e07&|c|o|t|p|i| +0#0000000&@4 +@2>l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|t|;+0#0000000&| @1|q+0#00e0e07&|c|o|t|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|t|;+0#0000000&| @1|q+0#00e0e07&|c|o|t| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|s|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|s|c| |d|g|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|c|s|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|c|s|c|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|s|c|;+0#0000000&| @1|q+0#00e0e07&|c|s|c|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|c|s|c|;+0#0000000&| @1|q+0#00e0e07&|c|s|c| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|u|r|t|;+0#0000000&| @1|q+0#00e0e07&|c|u|r|t|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|c|u|r|t|;+0#0000000&| @1|q+0#00e0e07&|c|u|r|t| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |e|r|f|c|;+0#0000000&| @1|q+0#00e0e07&|e|r|f|c|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|e|r|f|c|;+0#0000000&| @1|q+0#00e0e07&|e|r|f|c| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |e|r|f|;+0#0000000&| @1|q+0#00e0e07&|e|r|f|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|e|r|f|;+0#0000000&| @1|q+0#00e0e07&|e|r|f| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |g|a|m@1|a|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g@1|a|m@1|a|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |i|n|v|e|r|f|c|;+0#0000000&| @1|q+0#00e0e07&|i|n|v|e|r|f|c|;+0#0000000&| @16|l+0#00e0e07&|o|n|g|l|o|n|g|i|n|v|e|r|f|c|;+0#0000000&| @1|q+0#00e0e07&|i|n|v|e|r|f|c| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |i|n|v|e|r|f|;+0#0000000&| @1|q+0#00e0e07&|i|n|v|e|r|f|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|l|o|n|g|i|n|v|e|r|f|;+0#0000000&| @1|q+0#00e0e07&|i|n|v|e|r|f| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |l|n|g|a|m@1|a|;+0#0000000&| @1|q+0#00e0e07&|l|n|g|a|m@1|a|;+0#0000000&| @16|l+0#00e0e07&|o|n|g|l|o|n|g|l|n|g|a|m@1|a|;+0#0000000&| @1|q+0#00e0e07&|l|n|g|a|m@1|a| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|e|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|s|e|c| |d|g|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|s|e|c|d|g|;+0#0000000&| @1|q+0#00e0e07&|s|e|c|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|e|c|;+0#0000000&| @1|q+0#00e0e07&|s|e|c|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|s|e|c|;+0#0000000&| @1|q+0#00e0e07&|s|e|c| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|i|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|s|i|n| |d|g|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|s|i|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|s|i|n|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|s|i|n|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|s|i|n|h| +0#0000000&@6 +@57|5|2|3|,|3| @8|2|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_30.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_30.dump new file mode 100644 index 0000000000..de50a0279d --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_30.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|s|i|n|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|s|i|n|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|i|n|p|i|;+0#0000000&| @1|q+0#00e0e07&|s|i|n| |p|i|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|s|i|n|p|i|;+0#0000000&| @1|q+0#00e0e07&|s|i|n|p|i| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |t|a|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|t|a|n| |d|g|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|t|a|n|d|g|;+0#0000000&| @1|q+0#00e0e07&|t|a|n|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|t|a|n|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|t|a|n|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |t|a|n|p|i|;+0#0000000&| @1|q+0#00e0e07&|t|a|n| |p|i|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|l|o|n|g|t|a|n|p|i|;+0#0000000&| @1|q+0#00e0e07&|t|a|n|p|i| +0#0000000&@4 +@2>l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c@1|o|s|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|s|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c@1|o|s|;+0#0000000&| @1|q+0#00e0e07&|a|c|o|s| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|s|i|n|;+0#0000000&| @1|q+0#00e0e07&|a|s|i|n|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|s|i|n|;+0#0000000&| @1|q+0#00e0e07&|a|s|i|n| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|t|a|n|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|t|a|n|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|s|;+0#0000000&| @1|q+0#00e0e07&|c|o|s|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|s|;+0#0000000&| @1|q+0#00e0e07&|c|o|s| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |e|x|p|;+0#0000000&| @1|q+0#00e0e07&|e|x|p|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|e|x|p|;+0#0000000&| @1|q+0#00e0e07&|e|x|p| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |l|n|;+0#0000000&| @1|q+0#00e0e07&|l|n|;+0#0000000&| @26|l+0#00e0e07&|o|n|g|l|o|n|g|l|n|;+0#0000000&| @1|q+0#00e0e07&|l|n| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |l|o|g|;+0#0000000&| @1|q+0#00e0e07&|l|o|g|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|l|o|g|;+0#0000000&| @1|q+0#00e0e07&|l|o|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|i|n|;+0#0000000&| @1|q+0#00e0e07&|s|i|n|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|s|i|n|;+0#0000000&| @1|q+0#00e0e07&|s|i|n| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |s|q|r|t|;+0#0000000&| @1|q+0#00e0e07&|s|q|r|t|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|s|q|r|t|;+0#0000000&| @1|q+0#00e0e07&|s|q|r|t| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |t|a|n|;+0#0000000&| @1|q+0#00e0e07&|t|a|n|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|t|a|n|;+0#0000000&| @1|q+0#00e0e07&|t|a|n| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|t|a|n|2|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|2|d|g|;+0#0000000&| @14|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|t|a|n|2|d|g|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|2|d +|g| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |a|r|c|t|a|n|2|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|2|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|l|o|n|g|a|r|c|t|a|n|2|;+0#0000000&| @1|q+0#00e0e07&|a|t|a|n|2| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |b|e|t|a|;+0#0000000&| @1|q+0#00e0e07&|b|e|t|a|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|b|e|t|a|;+0#0000000&| @1|q+0#00e0e07&|b|e|t|a| +0#0000000&@6 +@57|5|4|1|,|3| @8|2|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_31.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_31.dump new file mode 100644 index 0000000000..e33d2a7a54 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_31.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |l|o|n|g| |b|e|t|a|;+0#0000000&| @1|q+0#00e0e07&|b|e|t|a|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|o|n|g|b|e|t|a|;+0#0000000&| @1|q+0#00e0e07&|b|e|t|a| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |g|a|m@1|a| |i|n|c|f|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|i|n|c|f|;+0#0000000&| @11|l+0#00e0e07&|o|n|g|l|o|n|g@1|a|m@1|a|i|n|c|f|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|i +|n|c|f| +0#0000000&@71 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |g|a|m@1|a| |i|n|c|g|f|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|i|n|c|g|f|;+0#0000000&| @9|l+0#00e0e07&|o|n|g|l|o|n|g@1|a|m@1|a|i|n|c|g|f|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a +|i|n|c|g|f| +0#0000000&@69 +@2>l+0#00e0e07&|o|n|g| |l|o|n|g| |g|a|m@1|a| |i|n|c|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|i|n|c|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|l|o|n|g@1|a|m@1|a|i|n|c|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|i|n +|c| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |l|n| |b|e|t|a|;+0#0000000&| @1|q+0#00e0e07&|l|n|b|e|t|a|;+0#0000000&| @17|l+0#00e0e07&|o|n|g|l|o|n|g|l|n|b|e|t|a|;+0#0000000&| @1|q+0#00e0e07&|l|n|b|e|t|a| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |b|e|t|a| |i|n|c|;+0#0000000&| @1|q+0#00e0e07&|b|e|t|a|i|n|c|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|b|e|t|a|i|n|c|;+0#0000000&| @1|q+0#00e0e07&|b|e|t|a|i|n|c| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |g|a|m@1|a| |i|n|c|g|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|i|n|c|g|;+0#0000000&| @11|l+0#00e0e07&|o|n|g|l|o|n|g@1|a|m@1|a|i|n|c|g|;+0#0000000&| @1|q+0#00e0e07&|g|a|m@1|a|i +|n|c|g| +0#0000000&@71 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@57|5@1|6|,|3| @8|2|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_32.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_32.dump new file mode 100644 index 0000000000..365d6598fc --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_32.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2>M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@57|5|7|2|,|3| @8|2|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_33.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_33.dump new file mode 100644 index 0000000000..91872d2518 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_33.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2>U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +|#+0#0000e05&| |L|O|N|G| |L|O|N|G| |C|O|M|P|L|E|X| |i|n| |s|o|f|t|w|a|r|e| |#| +0#0000000&@41 +@2|R+0#af5f00255&|E| +0#0000000&@43|R+0#af5f00255&|E| +0#0000000&@24 +@2|I+0#af5f00255&|M| +0#0000000&@43|I+0#af5f00255&|M| +0#0000000&@24 +@2|A+0#af5f00255&|R|G| +0#0000000&@42|A+0#af5f00255&|R|G| +0#0000000&@23 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|C+0#af5f00255&|O|N|J| +0#0000000&@41|C+0#af5f00255&|O|N|J| +0#0000000&@22 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@57|5|9|0|,|3| @8|2|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_34.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_34.dump new file mode 100644 index 0000000000..5941681bca --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_34.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2>^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@57|6|0|8|,|3| @8|2|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_35.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_35.dump new file mode 100644 index 0000000000..79add5e861 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_35.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |c|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|c|a|c|o|s|h|;+0#0000000&| @8|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|a|r|c@1|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|c +|a|c|o|s|h| +0#0000000&@69 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |c|o|s|;+0#0000000&| @1|q+0#00e0e07&|c|a|c|o|s|;+0#0000000&| @10|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|a|r|c@1|o|s|;+0#0000000&| @1|q+0#00e0e07&|c|a +|c|o|s| +0#0000000&@71 +@2>l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|c|a|s|i|n|h|;+0#0000000&| @8|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|a|r|c|s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|c +|a|s|i|n|h| +0#0000000&@69 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |s|i|n|;+0#0000000&| @1|q+0#00e0e07&|c|a|s|i|n|;+0#0000000&| @10|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|a|r|c|s|i|n|;+0#0000000&| @1|q+0#00e0e07&|c|a +|s|i|n| +0#0000000&@71 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|c|a|t|a|n|h|;+0#0000000&| @8|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|a|r|c|t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|c +|a|t|a|n|h| +0#0000000&@69 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |t|a|n|;+0#0000000&| @1|q+0#00e0e07&|c|a|t|a|n|;+0#0000000&| @10|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|a|r|c|t|a|n|;+0#0000000&| @1|q+0#00e0e07&|c|a +|t|a|n| +0#0000000&@71 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |c|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|c@1|o|s|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|c|o|s|h|;+0#0000000&| @1|q+0#00e0e07&|c@1|o|s +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |c|o|s|;+0#0000000&| @1|q+0#00e0e07&|c@1|o|s|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|c|o|s|;+0#0000000&| @1|q+0#00e0e07&|c@1|o|s| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |e|x|p|;+0#0000000&| @1|q+0#00e0e07&|c|e|x|p|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|e|x|p|;+0#0000000&| @1|q+0#00e0e07&|c|e|x|p| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |l|n|;+0#0000000&| @1|q+0#00e0e07&|c|l|n|;+0#0000000&| @17|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|l|n|;+0#0000000&| @1|q+0#00e0e07&|c|l|n| +0#0000000&@2 +@57|6|2|5|,|3| @8|2|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_36.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_36.dump new file mode 100644 index 0000000000..f70e5a7caa --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_36.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |l|n|;+0#0000000&| @1|q+0#00e0e07&|c|l|n|;+0#0000000&| @17|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|l|n|;+0#0000000&| @1|q+0#00e0e07&|c|l|n| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|c|s|i|n|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|s|i|n|h|;+0#0000000&| @1|q+0#00e0e07&|c|s|i|n +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |s|i|n|;+0#0000000&| @1|q+0#00e0e07&|c|s|i|n|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|s|i|n|;+0#0000000&| @1|q+0#00e0e07&|c|s|i|n| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |s|q|r|t|;+0#0000000&| @1|q+0#00e0e07&|c|s|q|r|t|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|s|q|r|t|;+0#0000000&| @1|q+0#00e0e07&|c|s|q|r +|t| +0#0000000&@73 +@2>l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|c|t|a|n|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|t|a|n|h|;+0#0000000&| @1|q+0#00e0e07&|c|t|a|n +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |c|o|m|p|l|e|x| |t|a|n|;+0#0000000&| @1|q+0#00e0e07&|c|t|a|n|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|l|o|n|g|c|o|m|p|l|e|x|t|a|n|;+0#0000000&| @1|q+0#00e0e07&|c|t|a|n| +0#0000000& +|#+0#0000e05&| |B|Y|T|E|S| |o|p|s|.| |#| +0#0000000&@60 +@2|b+0#00e0e07&|y|t|e|s|p|a|c|k|;+0#0000000&| @35|b+0#00e0e07&|y|t|e|s|p|a|c|k| +0#0000000&@17 +@2|E+0#af5f00255&|L|E|M| +0#0000000&@41|E+0#af5f00255&|L|E|M| +0#0000000&@22 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|++0#af5f00255&|=|:| +0#0000000&@42|++0#af5f00255&|=|:| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|T|O| +0#0000000&@39|P+0#af5f00255&|L|U|S|T|O| +0#0000000&@20 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@57|6|3|6|,|3| @8|3|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_37.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_37.dump new file mode 100644 index 0000000000..fd354a5c90 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_37.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2>>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +|#+0#0000e05&| |L|O|N|G| |B|Y|T|E|S| |o|p|s|.| |#| +0#0000000&@55 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|l+0#00e0e07&|o|n|g| |b|y|t|e|s| |p|a|c|k|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|b|y|t|e|s|p|a|c|k| +0#0000000&@13 +@2|E+0#af5f00255&|L|E|M| +0#0000000&@41|E+0#af5f00255&|L|E|M| +0#0000000&@22 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@57|6|5|2|,|3| @8|3|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_38.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_38.dump new file mode 100644 index 0000000000..4320f4eb40 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_38.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|++0#af5f00255&|=|:| +0#0000000&@42|++0#af5f00255&|=|:| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|T|O| +0#0000000&@39|P+0#af5f00255&|L|U|S|T|O| +0#0000000&@20 +@2>=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@57|6|7|0|,|3| @8|3|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_39.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_39.dump new file mode 100644 index 0000000000..9f0effc26f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_39.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +|#+0#0000e05&| |S|T|R|I|N|G| |o|p|s|.| |#| +0#0000000&@59 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2>^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@57|6|8@1|,|3| @8|3|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_40.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_40.dump new file mode 100644 index 0000000000..b50b0d4150 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_40.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|++0#af5f00255&|=|:| +0#0000000&@42|++0#af5f00255&|=|:| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|T|O| +0#0000000&@39|P+0#af5f00255&|L|U|S|T|O| +0#0000000&@20 +@2>*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|L|E|M| +0#0000000&@41|E+0#af5f00255&|L|E|M| +0#0000000&@22 +@2|r+0#00e0e07&|e|a|l| |p|a|t|h|;+0#0000000&| @35|r+0#00e0e07&|e|a|l|p|a|t|h| +0#0000000&@18 +|#+0#0000e05&| |S|E|M|A| |o|p|s|.| |#| +0#0000000&@61 +@2|L+0#af5f00255&|E|V|E|L| +0#0000000&@40|L+0#af5f00255&|E|V|E|L| +0#0000000&@21 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|D+0#af5f00255&|O|W|N| +0#0000000&@41|D+0#af5f00255&|O|W|N| +0#0000000&@22 +@2|L+0#af5f00255&|E|V|E|L| +0#0000000&@40|L+0#af5f00255&|E|V|E|L| +0#0000000&@21 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|D+0#af5f00255&|O|W|N| +0#0000000&@41|D+0#af5f00255&|O|W|N| +0#0000000&@22 +|#+0#0000e05&| |R|O|W|S| |o|p|s|.| |#| +0#0000000&@61 +@2|E+0#af5f00255&|L|E|M|S| +0#0000000&@40|E+0#af5f00255&|L|E|M|S| +0#0000000&@21 +@2|L+0#af5f00255&|W|B| +0#0000000&@42|L+0#af5f00255&|W|B| +0#0000000&@23 +@2|U+0#af5f00255&|P|B| +0#0000000&@42|U+0#af5f00255&|P|B| +0#0000000&@23 +@57|7|0|6|,|3| @8|3@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_41.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_41.dump new file mode 100644 index 0000000000..b402707852 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_41.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|U+0#af5f00255&|P|B| +0#0000000&@42|U+0#af5f00255&|P|B| +0#0000000&@23 +@2|E+0#af5f00255&|L|E|M|S| +0#0000000&@40|E+0#af5f00255&|L|E|M|S| +0#0000000&@21 +@2|L+0#af5f00255&|W|B| +0#0000000&@42|L+0#af5f00255&|W|B| +0#0000000&@23 +@2|U+0#af5f00255&|P|B| +0#0000000&@42|U+0#af5f00255&|P|B| +0#0000000&@23 +@2|S+0#af5f00255&|O|R|T| +0#0000000&@41|S+0#af5f00255&|O|R|T| +0#0000000&@22 +>#+0#0000e05&| |S|o|m|e| |"|t|e|r|m|i|n|a|t|o|r|s| |#| +0#0000000&@53 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +|#+0#0000e05&| |S|O|U|N|D|/|R|I|F@1| |p|r|o|c|s|.| |#| +0#0000000&@53 +@2|n+0#00e0e07&|e|w|s|o|u|n|d|;+0#0000000&| @36|n+0#00e0e07&|e|w|s|o|u|n|d| +0#0000000&@18 +@2|g+0#00e0e07&|e|t|s|o|u|n|d|;+0#0000000&| @36|g+0#00e0e07&|e|t|s|o|u|n|d| +0#0000000&@18 +@2|s+0#00e0e07&|e|t|s|o|u|n|d|;+0#0000000&| @36|s+0#00e0e07&|e|t|s|o|u|n|d| +0#0000000&@18 +@2|R+0#af5f00255&|E|S|O|L|U|T|I|O|N| +0#0000000&@35|R+0#af5f00255&|E|S|O|L|U|T|I|O|N| +0#0000000&@16 +@2|C+0#af5f00255&|H|A|N@1|E|L|S| +0#0000000&@37|C+0#af5f00255&|H|A|N@1|E|L|S| +0#0000000&@18 +@2|R+0#af5f00255&|A|T|E| +0#0000000&@41|R+0#af5f00255&|A|T|E| +0#0000000&@22 +@2|S+0#af5f00255&|A|M|P|L|E|S| +0#0000000&@38|S+0#af5f00255&|A|M|P|L|E|S| +0#0000000&@19 +|#+0#0000e05&| |S|e|t| |u|p| |s|t|a|n|d|e|n|v| |-| |t|r|a|n|s|p|u|t|.| |#| +0#0000000&@43 +@2|l+0#00e0e07&|o|n|g| |p|i|;+0#0000000&| @1|d+0#00e0e07&|p|i|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|p|i|;+0#0000000&| @1|d+0#00e0e07&|p|i| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |m|a|x| |b|i|t|s|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|m|a|x|b|i|t|s| +0#0000000&@15 +@57|7|2|4|,|1| @8|3|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_42.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_42.dump new file mode 100644 index 0000000000..1539712108 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_42.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |m|a|x| |b|i|t|s|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|m|a|x|b|i|t|s| +0#0000000&@15 +@2|l+0#00e0e07&|o|n|g| |m|a|x| |i|n|t|;+0#0000000&| @32|l+0#00e0e07&|o|n|g|m|a|x|i|n|t| +0#0000000&@16 +@2|l+0#00e0e07&|o|n|g| |s|m|a|l@1| |r|e|a|l|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|s|m|a|l@1|r|e|a|l| +0#0000000&@13 +@2|l+0#00e0e07&|o|n|g| |m|a|x| |r|e|a|l|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|m|a|x|r|e|a|l| +0#0000000&@15 +@2|l+0#00e0e07&|o|n|g| |m|i|n| |r|e|a|l|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|m|i|n|r|e|a|l| +0#0000000&@15 +@2>l+0#00e0e07&|o|n|g| |i|n|f|i|n|i|t|y|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|i|n|f|i|n|i|t|y| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |m|i|n|u|s| |i|n|f|i|n|i|t|y|;+0#0000000&| @25|l+0#00e0e07&|o|n|g|m|i|n|u|s|i|n|f|i|n|i|t|y| +0#0000000&@9 +@2|l+0#00e0e07&|o|n|g| |i|n|f|;+0#0000000&| @36|l+0#00e0e07&|o|n|g|i|n|f| +0#0000000&@19 +@2|l+0#00e0e07&|o|n|g| |m|i|n| |i|n|f|;+0#0000000&| @32|l+0#00e0e07&|o|n|g|m|i|n|i|n|f| +0#0000000&@16 +|#+0#0000e05&| |L|O|N|G| |I|N|T| |i|n| |s|o|f|t|w|a|r|e| |#| +0#0000000&@50 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@57|7|4|2|,|3| @8|3|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_43.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_43.dump new file mode 100644 index 0000000000..d1ff0625f4 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_43.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|O+0#af5f00255&|D@1| +0#0000000&@42|O+0#af5f00255&|D@1| +0#0000000&@23 +@2|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@39|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@20 +@2|R+0#af5f00255&|O|U|N|D| +0#0000000&@40|R+0#af5f00255&|O|U|N|D| +0#0000000&@21 +@2>++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|V|E|R| +0#0000000&@41|O+0#af5f00255&|V|E|R| +0#0000000&@22 +@2|%+0#af5f00255&| +0#0000000&@44|%+0#af5f00255&| +0#0000000&@25 +@2|M+0#af5f00255&|O|D| +0#0000000&@42|M+0#af5f00255&|O|D| +0#0000000&@23 +@2|%+0#af5f00255&|*| +0#0000000&@43|%+0#af5f00255&|*| +0#0000000&@24 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|%+0#af5f00255&|:|=| +0#0000000&@42|%+0#af5f00255&|:|=| +0#0000000&@23 +@2|%+0#af5f00255&|*|:|=| +0#0000000&@41|%+0#af5f00255&|*|:|=| +0#0000000&@22 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@57|7|6|0|,|3| @8|3|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_44.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_44.dump new file mode 100644 index 0000000000..53aa1512b6 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_44.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@39|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|O|D|A|B| +0#0000000&@40|M+0#af5f00255&|O|D|A|B| +0#0000000&@21 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2>E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@57|7@1|8|,|3| @8|3|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_45.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_45.dump new file mode 100644 index 0000000000..f729cd8786 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_45.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2>++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +|#+0#0000e05&| |L|O|N|G| |R|E|A|L| |i|n| |s|o|f|t|w|a|r|e| |#| +0#0000000&@49 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|s| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c@1|o|s|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c@1|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|t|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c@1|o|t|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|t| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c@1|o|t|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|s|c|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c@1|s|c|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|s|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c@1|s|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|e|c|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c|s|e|c|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c| +0#0000000&@8 +@57|7|9|6|,|3| @8|3|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_46.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_46.dump new file mode 100644 index 0000000000..6a96f5d2bc --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_46.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |a|r|c| |s|e|c|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c|s|e|c|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|e|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c|s|e|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|i|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c|s|i|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|d|g| +0#0000000&@4 +@2>l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |c|a|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|a|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|s| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |c|b|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|b|r|t|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|c|b|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|b|r|t| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |c|o|s| |d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|s| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|s|d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|h|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |c|o|s| |p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|s| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|s|p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|p|i| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|o|t|;+0#0000000&| @1|d+0#00e0e07&|c|o|t|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|o|t|;+0#0000000&| @1|d+0#00e0e07&|c|o|t| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |c|o|t| |d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|t| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|t|d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|t|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|o|t| |p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|t| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|t|p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|t|p|i| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|s|c|;+0#0000000&| @1|d+0#00e0e07&|c|s|c|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|s|c|;+0#0000000&| @1|d+0#00e0e07&|c|s|c| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |c|s|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|c|s|c| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|s|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|c|s|c|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|u|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|u|r|t|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|c|u|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|u|r|t| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|e|r|f|c|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|e|r|f|c| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |e|r|f|;+0#0000000&| @1|d+0#00e0e07&|e|r|f|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|e|r|f|;+0#0000000&| @1|d+0#00e0e07&|e|r|f| +0#0000000&@12 +@57|8|1|4|,|3| @8|3|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_47.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_47.dump new file mode 100644 index 0000000000..9dd995011f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_47.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |e|r|f|;+0#0000000&| @1|d+0#00e0e07&|e|r|f|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|e|r|f|;+0#0000000&| @1|d+0#00e0e07&|e|r|f| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|;+0#0000000&| @25|l+0#00e0e07&|o|n|g@1|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |i|n|v| |e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|c|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|i|n|v|e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|c| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |i|n|v| |e|r|f|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|i|n|v|e|r|f|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |l|n| |g|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|g|a|m@1|a|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|n|g|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|g|a|m@1|a| +0#0000000&@4 +@2>l+0#00e0e07&|o|n|g| |s|e|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|s|e|c| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|s|e|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|s|e|c|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |s|e|c|;+0#0000000&| @1|d+0#00e0e07&|s|e|c|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|s|e|c|;+0#0000000&| @1|d+0#00e0e07&|s|e|c| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |s|i|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|s|i|n| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|s|i|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|h|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |s|i|n| |p|i|;+0#0000000&| @1|d+0#00e0e07&|s|i|n| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|s|i|n|p|i|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|p|i| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |t|a|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|t|a|n| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|t|a|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|h|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |t|a|n| |p|i|;+0#0000000&| @1|d+0#00e0e07&|t|a|n| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|t|a|n|p|i|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|p|i| +0#0000000&@8 +|#+0#0000e05&| |R@1|.| |#| +0#0000000&@67 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c@1|o|s|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|o|s| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |e|x|p|;+0#0000000&| @1|d+0#00e0e07&|e|x|p|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|e|x|p|;+0#0000000&| @1|d+0#00e0e07&|e|x|p| +0#0000000&@12 +@57|8|3|2|,|3| @8|3|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_48.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_48.dump new file mode 100644 index 0000000000..122fc24934 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_48.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |e|x|p|;+0#0000000&| @1|d+0#00e0e07&|e|x|p|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|e|x|p|;+0#0000000&| @1|d+0#00e0e07&|e|x|p| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |l|n|;+0#0000000&| @1|d+0#00e0e07&|l|n|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|l|n|;+0#0000000&| @1|d+0#00e0e07&|l|n| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |l|o|g|;+0#0000000&| @1|d+0#00e0e07&|l|o|g|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|l|o|g|;+0#0000000&| @1|d+0#00e0e07&|l|o|g| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|s|i|n| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|s|q|r|t|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|s|q|r|t| +0#0000000&@10 +@2>l+0#00e0e07&|o|n|g| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|t|a|n| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |n|e|x|t| |r|a|n|d|o|m|;+0#0000000&| @28|l+0#00e0e07&|o|n|g|n|e|x|t|r|a|n|d|o|m| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |r|a|n|d|o|m|;+0#0000000&| @33|l+0#00e0e07&|o|n|g|r|a|n|d|o|m| +0#0000000&@16 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|2|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|2|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|2| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2|d|g|;+0#0000000&| @17|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|2|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2|d|g| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|;+0#0000000&| @18|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|f|;+0#0000000&| @16|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|f| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|g|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g|f|;+0#0000000&| @14|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|g|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g +|f| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |l|n| |b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|b|e|t|a|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|n|b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|b|e|t|a| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |b|e|t|a| |i|n|c|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a|i|n|c|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|b|e|t|a|i|n|c|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a|i|n|c| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|g|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g|;+0#0000000&| @16|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|g|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g| +0#0000000& +@2|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@57|8|5|0|,|3| @8|4|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_49.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_49.dump new file mode 100644 index 0000000000..0ab7fc78b5 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_49.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2>*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@57|8|6|7|,|3| @8|4|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_50.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_50.dump new file mode 100644 index 0000000000..b9fe193873 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_50.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2>L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +|#+0#0000e05&| |L|O|N|G| |C|O|M|P|L|E|X| |i|n| |s|o|f|t|w|a|r|e| |#| +0#0000000&@46 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@57|8@1|5|,|3| @8|4|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_51.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_51.dump new file mode 100644 index 0000000000..22c416ed6c --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_51.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|R+0#af5f00255&|E| +0#0000000&@43|R+0#af5f00255&|E| +0#0000000&@24 +@2>I+0#af5f00255&|M| +0#0000000&@43|I+0#af5f00255&|M| +0#0000000&@24 +@2|A+0#af5f00255&|R|G| +0#0000000&@42|A+0#af5f00255&|R|G| +0#0000000&@23 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|C+0#af5f00255&|O|N|J| +0#0000000&@41|C+0#af5f00255&|O|N|J| +0#0000000&@22 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@57|9|0|3|,|3| @8|4|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_52.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_52.dump new file mode 100644 index 0000000000..988cc3b46e --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_52.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2>N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c@1|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c@1|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|@+0#4040ff13&@2 +| +0#0000000&@56|9|2|1|,|3| @8|4|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_53.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_53.dump new file mode 100644 index 0000000000..89be262ec0 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_53.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n +|h| +0#0000000&@73 +@2>l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s|h| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |e|x|p|;+0#0000000&| @1|d+0#00e0e07&|c|e|x|p|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|e|x|p|;+0#0000000&| @1|d+0#00e0e07&|c|e|x|p| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |l|n|;+0#0000000&| @1|d+0#00e0e07&|c|l|n|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|l|n|;+0#0000000&| @1|d+0#00e0e07&|c|l|n| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n|;+0#0000000&| @19|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n| +0#0000000&@3 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|s|q|r|t|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|s|q|r|t| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n|h| +0#0000000&@2 +|#+0#0000e05&| |L|O|N|G| |B|I|T|S| |i|n| |s|o|f|t|w|a|r|e| |#| +0#0000000&@49 +@2|l+0#00e0e07&|o|n|g|b|i|t|s|p|a|c|k|;+0#0000000&| @32|l+0#00e0e07&|o|n|g|b|i|t|s|p|a|c|k| +0#0000000&@14 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|B+0#af5f00255&|I|N| +0#0000000&@42|B+0#af5f00255&|I|N| +0#0000000&@23 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@57|9|3|6|,|3| @8|4@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_54.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_54.dump new file mode 100644 index 0000000000..56336f2ceb --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_54.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|N+0#af5f00255&|O|T| +0#0000000&@42|N+0#af5f00255&|O|T| +0#0000000&@23 +@2|~+0#af5f00255&| +0#0000000&@44|~+0#af5f00255&| +0#0000000&@25 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2>E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|A+0#af5f00255&|N|D| +0#0000000&@42|A+0#af5f00255&|N|D| +0#0000000&@23 +@2|&+0#af5f00255&| +0#0000000&@44|&+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|R| +0#0000000&@43|O+0#af5f00255&|R| +0#0000000&@24 +@2|X+0#af5f00255&|O|R| +0#0000000&@42|X+0#af5f00255&|O|R| +0#0000000&@23 +@2|S+0#af5f00255&|H|L| +0#0000000&@42|S+0#af5f00255&|H|L| +0#0000000&@23 +@57|9|5|4|,|3| @8|4|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_55.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_55.dump new file mode 100644 index 0000000000..b397d5e771 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_55.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|S+0#af5f00255&|H|L| +0#0000000&@42|S+0#af5f00255&|H|L| +0#0000000&@23 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|S+0#af5f00255&|H|R| +0#0000000&@42|S+0#af5f00255&|H|R| +0#0000000&@23 +@2|D+0#af5f00255&|O|W|N| +0#0000000&@41|D+0#af5f00255&|O|W|N| +0#0000000&@22 +@2|E+0#af5f00255&|L|E|M| +0#0000000&@41|E+0#af5f00255&|L|E|M| +0#0000000&@22 +@2>S+0#af5f00255&|E|T| +0#0000000&@42|S+0#af5f00255&|E|T| +0#0000000&@23 +@2|C+0#af5f00255&|L|E|A|R| +0#0000000&@40|C+0#af5f00255&|L|E|A|R| +0#0000000&@21 +@2|l+0#00e0e07&|o|n|g| |p|i|;+0#0000000&| @1|d+0#00e0e07&|p|i|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|p|i|;+0#0000000&| @1|d+0#00e0e07&|p|i| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |m|a|x| |b|i|t|s|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|m|a|x|b|i|t|s| +0#0000000&@15 +@2|l+0#00e0e07&|o|n|g| |m|a|x| |i|n|t|;+0#0000000&| @32|l+0#00e0e07&|o|n|g|m|a|x|i|n|t| +0#0000000&@16 +@2|l+0#00e0e07&|o|n|g| |s|m|a|l@1| |r|e|a|l|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|s|m|a|l@1|r|e|a|l| +0#0000000&@13 +@2|l+0#00e0e07&|o|n|g| |m|a|x| |r|e|a|l|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|m|a|x|r|e|a|l| +0#0000000&@15 +@2|l+0#00e0e07&|o|n|g| |m|i|n| |r|e|a|l|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|m|i|n|r|e|a|l| +0#0000000&@15 +@2|l+0#00e0e07&|o|n|g| |i|n|f|i|n|i|t|y|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|i|n|f|i|n|i|t|y| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |m|i|n|u|s| |i|n|f|i|n|i|t|y|;+0#0000000&| @25|l+0#00e0e07&|o|n|g|m|i|n|u|s|i|n|f|i|n|i|t|y| +0#0000000&@9 +@2|l+0#00e0e07&|o|n|g| |i|n|f|;+0#0000000&| @36|l+0#00e0e07&|o|n|g|i|n|f| +0#0000000&@19 +@2|l+0#00e0e07&|o|n|g| |m|i|n| |i|n|f|;+0#0000000&| @32|l+0#00e0e07&|o|n|g|m|i|n|i|n|f| +0#0000000&@16 +|#+0#0000e05&| |L|O|N|G| |I|N|T| |a|s| |1|2|8| |b|i|t| |#| +0#0000000&@51 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@57|9|7|2|,|3| @8|4|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_56.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_56.dump new file mode 100644 index 0000000000..491d91bae2 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_56.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2>S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|O+0#af5f00255&|D@1| +0#0000000&@42|O+0#af5f00255&|D@1| +0#0000000&@23 +@2|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@39|E+0#af5f00255&|N|T|I|E|R| +0#0000000&@20 +@2|R+0#af5f00255&|O|U|N|D| +0#0000000&@40|R+0#af5f00255&|O|U|N|D| +0#0000000&@21 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|V|E|R| +0#0000000&@41|O+0#af5f00255&|V|E|R| +0#0000000&@22 +@2|%+0#af5f00255&| +0#0000000&@44|%+0#af5f00255&| +0#0000000&@25 +@2|M+0#af5f00255&|O|D| +0#0000000&@42|M+0#af5f00255&|O|D| +0#0000000&@23 +@2|%+0#af5f00255&|*| +0#0000000&@43|%+0#af5f00255&|*| +0#0000000&@24 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@57|9@1|0|,|3| @8|4|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_57.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_57.dump new file mode 100644 index 0000000000..8a148f6890 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_57.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|%+0#af5f00255&|:|=| +0#0000000&@42|%+0#af5f00255&|:|=| +0#0000000&@23 +@2>%+0#af5f00255&|*|:|=| +0#0000000&@41|%+0#af5f00255&|*|:|=| +0#0000000&@22 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@39|O+0#af5f00255&|V|E|R|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|O|D|A|B| +0#0000000&@40|M+0#af5f00255&|O|D|A|B| +0#0000000&@21 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@57|1|0@1|8|,|3| @7|4|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_58.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_58.dump new file mode 100644 index 0000000000..235c9bb9b9 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_58.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2>G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +|#+0#0000e05&| |L|O|N|G| |R|E|A|L| |a|s| |1|2|8| |b|i|t| |#| +0#0000000&@50 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|S+0#af5f00255&|I|G|N| +0#0000000&@41|S+0#af5f00255&|I|G|N| +0#0000000&@22 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@57|1|0|2|6|,|3| @7|4|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_59.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_59.dump new file mode 100644 index 0000000000..05a6dacc15 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_59.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2>L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@57|1|0|4@1|,|3| @7|4|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_60.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_60.dump new file mode 100644 index 0000000000..73b30fdd42 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_60.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2><+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|s| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c@1|o|s|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c@1|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|t| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c@1|o|t|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|t|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c@1|o|t|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|t| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|s|c|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c@1|s|c|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|s|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c@1|s|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c|d|g| +0#0000000&@4 +@57|1|0|6|2|,|3| @7|5|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_61.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_61.dump new file mode 100644 index 0000000000..033cacb540 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_61.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |a|r|c| |c|s|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c@1|s|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|c|s|c|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|e|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c|s|e|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|e|c|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|i|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c|s|i|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|d|g| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n| |d|g|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|d|g| +0#0000000&@4 +@2>l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|h|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|h| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |c|b|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|b|r|t|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|c|b|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|b|r|t| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |c|o|s| |d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|s| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|s|d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|h|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |c|o|s| |p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|s| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|s|p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|p|i| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|o|t| |d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|t| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|t|d|g|;+0#0000000&| @1|d+0#00e0e07&|c|o|t|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|o|t|;+0#0000000&| @1|d+0#00e0e07&|c|o|t|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|o|t|;+0#0000000&| @1|d+0#00e0e07&|c|o|t| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |c|o|t| |p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|t| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|o|t|p|i|;+0#0000000&| @1|d+0#00e0e07&|c|o|t|p|i| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|s|c|;+0#0000000&| @1|d+0#00e0e07&|c|s|c|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|s|c|;+0#0000000&| @1|d+0#00e0e07&|c|s|c| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |c|s|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|c|s|c| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|c|s|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|c|s|c|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|u|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|u|r|t|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|c|u|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|u|r|t| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|e|r|f|c|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|e|r|f|c| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |e|r|f|;+0#0000000&| @1|d+0#00e0e07&|e|r|f|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|e|r|f|;+0#0000000&| @1|d+0#00e0e07&|e|r|f| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |i|n|v| |e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|c|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|i|n|v|e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|c| +0#0000000&@4 +@57|1|0|8|0|,|3| @7|5|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_62.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_62.dump new file mode 100644 index 0000000000..d56b2f36bc --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_62.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |i|n|v| |e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|c|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|i|n|v|e|r|f|c|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|c| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |i|n|v| |e|r|f|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|i|n|v|e|r|f|;+0#0000000&| @1|d+0#00e0e07&|i|n|v|e|r|f| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|;+0#0000000&| @25|l+0#00e0e07&|o|n|g@1|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |l|n| |g|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|g|a|m@1|a|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|l|n|g|a|m@1|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|g|a|m@1|a| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |s|e|c|;+0#0000000&| @1|d+0#00e0e07&|s|e|c|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|s|e|c|;+0#0000000&| @1|d+0#00e0e07&|s|e|c| +0#0000000&@12 +@2>l+0#00e0e07&|o|n|g| |s|e|c| |d|g|;+0#0000000&| @1|d+0#00e0e07&|s|e|c| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|s|e|c|d|g|;+0#0000000&| @1|d+0#00e0e07&|s|e|c|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |s|i|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|s|i|n| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|s|i|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|h|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |s|i|n| |p|i|;+0#0000000&| @1|d+0#00e0e07&|s|i|n| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|s|i|n|p|i|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|p|i| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |t|a|n| |d|g|;+0#0000000&| @1|d+0#00e0e07&|t|a|n| |d|g|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|t|a|n|d|g|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|d|g| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|h|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|h| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |t|a|n| |p|i|;+0#0000000&| @1|d+0#00e0e07&|t|a|n| |p|i|;+0#0000000&| @23|l+0#00e0e07&|o|n|g|t|a|n|p|i|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|p|i| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c@1|o|s|;+0#0000000&| @1|d+0#00e0e07&|a|c|o|s| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|a|s|i|n| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n| +0#0000000&@8 +@2|l+0#00e0e07&|o|n|g| |c|a|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|a|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|s| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|o|s|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|o|s| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |e|x|p|;+0#0000000&| @1|d+0#00e0e07&|e|x|p|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|e|x|p|;+0#0000000&| @1|d+0#00e0e07&|e|x|p| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |l|n|;+0#0000000&| @1|d+0#00e0e07&|l|n|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|l|n|;+0#0000000&| @1|d+0#00e0e07&|l|n| +0#0000000&@14 +@57|1|0|9|8|,|3| @7|5|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_63.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_63.dump new file mode 100644 index 0000000000..94f4564065 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_63.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |l|n|;+0#0000000&| @1|d+0#00e0e07&|l|n|;+0#0000000&| @31|l+0#00e0e07&|o|n|g|l|n|;+0#0000000&| @1|d+0#00e0e07&|l|n| +0#0000000&@14 +@2|l+0#00e0e07&|o|n|g| |l|o|g|;+0#0000000&| @1|d+0#00e0e07&|l|o|g|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|l|o|g|;+0#0000000&| @1|d+0#00e0e07&|l|o|g| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|s|i|n|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|s|i|n| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|s|q|r|t|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|s|q|r|t| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|t|a|n|;+0#0000000&| @29|l+0#00e0e07&|o|n|g|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|t|a|n| +0#0000000&@12 +@2>l+0#00e0e07&|o|n|g| |n|e|x|t| |r|a|n|d|o|m|;+0#0000000&| @28|l+0#00e0e07&|o|n|g|n|e|x|t|r|a|n|d|o|m| +0#0000000&@12 +@2|l+0#00e0e07&|o|n|g| |r|a|n|d|o|m|;+0#0000000&| @33|l+0#00e0e07&|o|n|g|r|a|n|d|o|m| +0#0000000&@16 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|2| |d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2|d|g|;+0#0000000&| @17|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|2|d|g|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2|d|g| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |a|r|c| |t|a|n|2|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|a|r|c|t|a|n|2|;+0#0000000&| @1|d+0#00e0e07&|a|t|a|n|2| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a|;+0#0000000&| @27|l+0#00e0e07&|o|n|g|b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a| +0#0000000&@10 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|g|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g|f|;+0#0000000&| @14|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|g|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g +|f| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|f|;+0#0000000&| @16|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|f|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|f| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|;+0#0000000&| @18|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |l|n| |b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|b|e|t|a|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|l|n|b|e|t|a|;+0#0000000&| @1|d+0#00e0e07&|l|n|b|e|t|a| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |b|e|t|a| |i|n|c|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a|i|n|c|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|b|e|t|a|i|n|c|;+0#0000000&| @1|d+0#00e0e07&|b|e|t|a|i|n|c| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |g|a|m@1|a| |i|n|c|g|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g|;+0#0000000&| @16|l+0#00e0e07&|o|n|g@1|a|m@1|a|i|n|c|g|;+0#0000000&| @1|d+0#00e0e07&|g|a|m@1|a|i|n|c|g| +0#0000000& +|#+0#0000e05&| |L|O|N|G| |B|I|T|S| |a|s| |1|2|8| |b|i|t| |#| +0#0000000&@50 +@2|l+0#00e0e07&|o|n|g| |b|i|t|s| |p|a|c|k|;+0#0000000&| @30|l+0#00e0e07&|o|n|g|b|i|t|s|p|a|c|k| +0#0000000&@14 +@57|1@2|6|,|3| @7|5|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_64.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_64.dump new file mode 100644 index 0000000000..822f2dc9f4 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_64.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |b|i|t|s| |p|a|c|k|;+0#0000000&| @30|l+0#00e0e07&|o|n|g|b|i|t|s|p|a|c|k| +0#0000000&@14 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|B+0#af5f00255&|I|N| +0#0000000&@42|B+0#af5f00255&|I|N| +0#0000000&@23 +@2>N+0#af5f00255&|O|T| +0#0000000&@42|N+0#af5f00255&|O|T| +0#0000000&@23 +@2|~+0#af5f00255&| +0#0000000&@44|~+0#af5f00255&| +0#0000000&@25 +@2|A+0#af5f00255&|N|D| +0#0000000&@42|A+0#af5f00255&|N|D| +0#0000000&@23 +@2|&+0#af5f00255&| +0#0000000&@44|&+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|R| +0#0000000&@43|O+0#af5f00255&|R| +0#0000000&@24 +@2|X+0#af5f00255&|O|R| +0#0000000&@42|X+0#af5f00255&|O|R| +0#0000000&@23 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|V|E|R| +0#0000000&@41|O+0#af5f00255&|V|E|R| +0#0000000&@22 +@2|M+0#af5f00255&|O|D| +0#0000000&@42|M+0#af5f00255&|O|D| +0#0000000&@23 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@57|1@1|3@1|,|3| @7|5|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_65.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_65.dump new file mode 100644 index 0000000000..964744a8d7 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_65.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2>N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&| +0#0000000&@44|<+0#af5f00255&| +0#0000000&@25 +@2|>+0#af5f00255&| +0#0000000&@44|>+0#af5f00255&| +0#0000000&@25 +@2|L+0#af5f00255&|T| +0#0000000&@43|L+0#af5f00255&|T| +0#0000000&@24 +@2|G+0#af5f00255&|T| +0#0000000&@43|G+0#af5f00255&|T| +0#0000000&@24 +@2|E+0#af5f00255&|L|E|M| +0#0000000&@41|E+0#af5f00255&|L|E|M| +0#0000000&@22 +@2|S+0#af5f00255&|E|T| +0#0000000&@42|S+0#af5f00255&|E|T| +0#0000000&@23 +@2|C+0#af5f00255&|L|E|A|R| +0#0000000&@40|C+0#af5f00255&|L|E|A|R| +0#0000000&@21 +@2|S+0#af5f00255&|H|L| +0#0000000&@42|S+0#af5f00255&|H|L| +0#0000000&@23 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|S+0#af5f00255&|H|R| +0#0000000&@42|S+0#af5f00255&|H|R| +0#0000000&@23 +@2|D+0#af5f00255&|O|W|N| +0#0000000&@41|D+0#af5f00255&|O|W|N| +0#0000000&@22 +@57|1@1|5|1|,|3| @7|5|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_66.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_66.dump new file mode 100644 index 0000000000..1175ee123d --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_66.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|D+0#af5f00255&|O|W|N| +0#0000000&@41|D+0#af5f00255&|O|W|N| +0#0000000&@22 +@2|R+0#af5f00255&|O|L| +0#0000000&@42|R+0#af5f00255&|O|L| +0#0000000&@23 +@2|R+0#af5f00255&|O|R| +0#0000000&@42|R+0#af5f00255&|O|R| +0#0000000&@23 +|#+0#0000e05&| |L|O|N|G| |C|O|M|P|L|E|X| |a|s| |2| |x| |1|2|8| |b|i|t|.| |#| +0#0000000&@42 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2>S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +@2|I+0#af5f00255&| +0#0000000&@44|I+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|*| +0#0000000&@43|++0#af5f00255&|*| +0#0000000&@24 +@2|R+0#af5f00255&|E| +0#0000000&@43|R+0#af5f00255&|E| +0#0000000&@24 +@2|I+0#af5f00255&|M| +0#0000000&@43|I+0#af5f00255&|M| +0#0000000&@24 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|A+0#af5f00255&|R|G| +0#0000000&@42|A+0#af5f00255&|R|G| +0#0000000&@23 +@2|++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|C+0#af5f00255&|O|N|J| +0#0000000&@41|C+0#af5f00255&|O|N|J| +0#0000000&@22 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@57|1@1|6|9|,|3| @7|5@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_67.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_67.dump new file mode 100644 index 0000000000..3c1140468a --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_67.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2|~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2>++0#af5f00255&| +0#0000000&@44|++0#af5f00255&| +0#0000000&@25 +@2|-+0#af5f00255&| +0#0000000&@44|-+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&| +0#0000000&@44|*+0#af5f00255&| +0#0000000&@25 +@2|/+0#af5f00255&| +0#0000000&@44|/+0#af5f00255&| +0#0000000&@25 +@2|*+0#af5f00255&@1| +0#0000000&@43|*+0#af5f00255&@1| +0#0000000&@24 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|^+0#af5f00255&| +0#0000000&@44|^+0#af5f00255&| +0#0000000&@25 +@2|++0#af5f00255&|:|=| +0#0000000&@42|++0#af5f00255&|:|=| +0#0000000&@23 +@2|-+0#af5f00255&|:|=| +0#0000000&@42|-+0#af5f00255&|:|=| +0#0000000&@23 +@2|*+0#af5f00255&|:|=| +0#0000000&@42|*+0#af5f00255&|:|=| +0#0000000&@23 +@2|/+0#af5f00255&|:|=| +0#0000000&@42|/+0#af5f00255&|:|=| +0#0000000&@23 +@2|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@39|P+0#af5f00255&|L|U|S|A|B| +0#0000000&@20 +@2|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@38|M+0#af5f00255&|I|N|U|S|A|B| +0#0000000&@19 +@2|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@57|1@1|8|7|,|3| @7|5|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_68.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_68.dump new file mode 100644 index 0000000000..c709ceaa10 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_68.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@38|T+0#af5f00255&|I|M|E|S|A|B| +0#0000000&@19 +@2|D+0#af5f00255&|I|V|A|B| +0#0000000&@40|D+0#af5f00255&|I|V|A|B| +0#0000000&@21 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c@1|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c@1|o|s|;+0#0000000&| @1|d+0#00e0e07&|c|a|c|o|s| +0#0000000& +@2>l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|s|i|n| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n|h|;+0#0000000&| @13|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n +|h| +0#0000000&@73 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|r|c| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n|;+0#0000000&| @15|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|r|c|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |a|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n|h|;+0#0000000&| @16|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|a|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|a|t|a|n|h| +0#0000000& +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|c|o|s|h|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s|h| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|c|o|s|;+0#0000000&| @1|d+0#00e0e07&|c@1|o|s| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |e|x|p|;+0#0000000&| @1|d+0#00e0e07&|c|e|x|p|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|e|x|p|;+0#0000000&| @1|d+0#00e0e07&|c|e|x|p| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |l|n|;+0#0000000&| @1|d+0#00e0e07&|c|l|n|;+0#0000000&| @22|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|l|n|;+0#0000000&| @1|d+0#00e0e07&|c|l|n| +0#0000000&@6 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|s|i|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n|h| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|s|i|n|;+0#0000000&| @1|d+0#00e0e07&|c|s|i|n| +0#0000000&@4 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|s|q|r|t|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|s|q|r|t| +0#0000000&@2 +@57|1|2|0|4|,|3| @7|5|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_69.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_69.dump new file mode 100644 index 0000000000..6bf96c41fd --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_69.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|s|q|r|t|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|s|q|r|t|;+0#0000000&| @1|d+0#00e0e07&|c|s|q|r|t| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n|h|;+0#0000000&| @18|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|t|a|n|h|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n|h| +0#0000000&@2 +@2|l+0#00e0e07&|o|n|g| |c|o|m|p|l|e|x| |t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n|;+0#0000000&| @20|l+0#00e0e07&|o|n|g|c|o|m|p|l|e|x|t|a|n|;+0#0000000&| @1|d+0#00e0e07&|c|t|a|n| +0#0000000&@4 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |g|a|m@1|a| |i|n|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |d|g|a|m@1|a|i|n|c|;+0#0000000&| @8|m+0#00e0e07&|p|f|r|l|o|n|g@1|a|m@1|a|i|n|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|d|g|a|m +@1|a|i|n|c| +0#0000000&@69 +@2>m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |b|e|t|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|b|e|t|a|;+0#0000000&| @12|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|b|e|t|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q|b|e|t +|a| +0#0000000&@73 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |g|a|m@1|a|i|n|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|g|a|m@1|a|i|n|c|;+0#0000000&| @4|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g@1|a|m@1|a|i|n|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r +|q|g|a|m@1|a|i|n|c| +0#0000000&@65 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |l|n|b|e|t|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|l|n|b|e|t|a|;+0#0000000&| @8|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|l|n|b|e|t|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q|l +|n|b|e|t|a| +0#0000000&@69 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |b|e|t|a|i|n|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|b|e|t|a|i|n|c|;+0#0000000&| @6|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|b|e|t|a|i|n|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q +|b|e|t|a|i|n|c| +0#0000000&@67 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |e|r|f|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|e|r|f|c|;+0#0000000&| @12|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|e|r|f|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q|e|r|f +|c| +0#0000000&@73 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |e|r|f|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|e|r|f|;+0#0000000&| @14|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|e|r|f|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q|e|r|f| +0#0000000& +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |g|a|m@1|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|g|a|m@1|a|;+0#0000000&| @10|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g@1|a|m@1|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q|g|a +|m@1|a| +0#0000000&@71 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |i|n|v|e|r|f|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|i|n|v|e|r|f|c|;+0#0000000&| @6|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|i|n|v|e|r|f|c|;+0#0000000&| @1|m+0#00e0e07&|p|@+0#4040ff13&@2 +| +0#0000000&@56|1|2|1|9|,|3| @7|5|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_70.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_70.dump new file mode 100644 index 0000000000..d8062c52b3 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_70.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |i|n|v|e|r|f|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|i|n|v|e|r|f|c|;+0#0000000&| @6|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|i|n|v|e|r|f|c|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q +|i|n|v|e|r|f|c| +0#0000000&@67 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |i|n|v|e|r|f|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|i|n|v|e|r|f|;+0#0000000&| @8|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|i|n|v|e|r|f|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q|i +|n|v|e|r|f| +0#0000000&@69 +@2|m+0#00e0e07&|p|f|r| |l|o|n|g| |l|o|n|g| |l|n|g|a|m@1|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r| |q|l|n|g|a|m@1|a|;+0#0000000&| @6|m+0#00e0e07&|p|f|r|l|o|n|g|l|o|n|g|l|n|g|a|m@1|a|;+0#0000000&| @1|m+0#00e0e07&|p|f|r|q +|l|n|g|a|m@1|a| +0#0000000&@67 +@2>m+0#00e0e07&|p|f|r| |m|p|;+0#0000000&| @37|m+0#00e0e07&|p|f|r|m|p| +0#0000000&@20 +@2|b+0#00e0e07&|l|a|n|k| |c|h|a|r|a|c|t|e|r|;+0#0000000&| @29|b+0#00e0e07&|l|a|n|k|c|h|a|r|a|c|t|e|r| +0#0000000&@12 +@2|f+0#00e0e07&|o|r|m|f|e@1|d| |c|h|a|r|a|c|t|e|r|;+0#0000000&| @26|f+0#00e0e07&|o|r|m|f|e@1|d|c|h|a|r|a|c|t|e|r| +0#0000000&@9 +@2|f+0#00e0e07&|o|r|m|f|e@1|d| |c|h|a|r|;+0#0000000&| @31|f+0#00e0e07&|o|r|m|f|e@1|d|c|h|a|r| +0#0000000&@14 +@2|n+0#00e0e07&|e|w|l|i|n|e| |c|h|a|r|a|c|t|e|r|;+0#0000000&| @27|n+0#00e0e07&|e|w|l|i|n|e|c|h|a|r|a|c|t|e|r| +0#0000000&@10 +@2|n+0#00e0e07&|e|w|l|i|n|e| |c|h|a|r|;+0#0000000&| @32|n+0#00e0e07&|e|w|l|i|n|e|c|h|a|r| +0#0000000&@15 +@2|n+0#00e0e07&|u|l@1| |c|h|a|r|a|c|t|e|r|;+0#0000000&| @30|n+0#00e0e07&|u|l@1|c|h|a|r|a|c|t|e|r| +0#0000000&@13 +@2|t+0#00e0e07&|a|b| |c|h|a|r|a|c|t|e|r|;+0#0000000&| @31|t+0#00e0e07&|a|b|c|h|a|r|a|c|t|e|r| +0#0000000&@14 +@2|t+0#00e0e07&|a|b| |c|h|a|r|;+0#0000000&| @36|t+0#00e0e07&|a|b|c|h|a|r| +0#0000000&@19 +@2|b+0#00e0e07&|l|a|n|k| |c|h|a|r|;+0#0000000&| @34|b+0#00e0e07&|l|a|n|k|c|h|a|r| +0#0000000&@17 +@2|b+0#00e0e07&|l|a|n|k|;+0#0000000&| @39|b+0#00e0e07&|l|a|n|k| +0#0000000&@21 +@2|e+0#00e0e07&|o|f| |c|h|a|r|a|c|t|e|r|;+0#0000000&| @31|e+0#00e0e07&|o|f|c|h|a|r|a|c|t|e|r| +0#0000000&@14 +@2|e+0#00e0e07&|o|f| |c|h|a|r|;+0#0000000&| @36|e+0#00e0e07&|o|f|c|h|a|r| +0#0000000&@19 +@57|1|2@1|9|,|3| @7|5|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_71.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_71.dump new file mode 100644 index 0000000000..071aff9467 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_71.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|e+0#00e0e07&|o|f| |c|h|a|r|;+0#0000000&| @36|e+0#00e0e07&|o|f|c|h|a|r| +0#0000000&@19 +@2|e+0#00e0e07&|r@1|o|r| |c|h|a|r|;+0#0000000&| @34|e+0#00e0e07&|r@1|o|r|c|h|a|r| +0#0000000&@17 +@2|e+0#00e0e07&|x|p| |c|h|a|r|;+0#0000000&| @36|e+0#00e0e07&|x|p|c|h|a|r| +0#0000000&@19 +@2|f+0#00e0e07&|l|i|p|;+0#0000000&| @40|f+0#00e0e07&|l|i|p| +0#0000000&@22 +@2|f+0#00e0e07&|l|o|p|;+0#0000000&| @40|f+0#00e0e07&|l|o|p| +0#0000000&@22 +@2>n+0#00e0e07&|u|l@1| |c|h|a|r|;+0#0000000&| @35|n+0#00e0e07&|u|l@1|c|h|a|r| +0#0000000&@18 +@2|b+0#00e0e07&|i|t|s|;+0#0000000&| @40|b+0#00e0e07&|i|t|s| +0#0000000&@22 +@2|w+0#00e0e07&|h|o|l|e|;+0#0000000&| @39|w+0#00e0e07&|h|o|l|e| +0#0000000&@21 +@2|f+0#00e0e07&|i|x|e|d|;+0#0000000&| @39|f+0#00e0e07&|i|x|e|d| +0#0000000&@21 +@2|f+0#00e0e07&|l|o|a|t|;+0#0000000&| @39|f+0#00e0e07&|l|o|a|t| +0#0000000&@21 +@2|r+0#00e0e07&|e|a|l|;+0#0000000&| @40|r+0#00e0e07&|e|a|l| +0#0000000&@22 +@2|s+0#00e0e07&|t|a|n|d| |i|n|;+0#0000000&| @36|s+0#00e0e07&|t|a|n|d|i|n| +0#0000000&@19 +@2|s+0#00e0e07&|t|a|n|d| |o|u|t|;+0#0000000&| @35|s+0#00e0e07&|t|a|n|d|o|u|t| +0#0000000&@18 +@2|s+0#00e0e07&|t|a|n|d| |b|a|c|k|;+0#0000000&| @34|s+0#00e0e07&|t|a|n|d|b|a|c|k| +0#0000000&@17 +@2|s+0#00e0e07&|t|a|n|d| |e|r@1|o|r|;+0#0000000&| @33|s+0#00e0e07&|t|a|n|d|e|r@1|o|r| +0#0000000&@16 +@2|s+0#00e0e07&|t|a|n|d| |i|n| |c|h|a|n@1|e|l|;+0#0000000&| @28|s+0#00e0e07&|t|a|n|d|i|n|c|h|a|n@1|e|l| +0#0000000&@12 +@2|s+0#00e0e07&|t|a|n|d| |o|u|t| |c|h|a|n@1|e|l|;+0#0000000&| @27|s+0#00e0e07&|t|a|n|d|o|u|t|c|h|a|n@1|e|l| +0#0000000&@11 +@2|s+0#00e0e07&|t|a|n|d| |d|r|a|w| |c|h|a|n@1|e|l|;+0#0000000&| @26|s+0#00e0e07&|t|a|n|d@1|r|a|w|c|h|a|n@1|e|l| +0#0000000&@10 +@2|s+0#00e0e07&|t|a|n|d| |b|a|c|k| |c|h|a|n@1|e|l|;+0#0000000&| @26|s+0#00e0e07&|t|a|n|d|b|a|c|k|c|h|a|n@1|e|l| +0#0000000&@10 +@57|1|2|4|6|,|3| @7|5|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_72.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_72.dump new file mode 100644 index 0000000000..e308519e14 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_72.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|s+0#00e0e07&|t|a|n|d| |b|a|c|k| |c|h|a|n@1|e|l|;+0#0000000&| @26|s+0#00e0e07&|t|a|n|d|b|a|c|k|c|h|a|n@1|e|l| +0#0000000&@10 +@2|s+0#00e0e07&|t|a|n|d| |e|r@1|o|r| |c|h|a|n@1|e|l|;+0#0000000&| @25|s+0#00e0e07&|t|a|n|d|e|r@1|o|r|c|h|a|n@1|e|l| +0#0000000&@9 +@2|m+0#00e0e07&|a|k|e| |t|e|r|m|;+0#0000000&| @35|m+0#00e0e07&|a|k|e|t|e|r|m| +0#0000000&@18 +@2|c+0#00e0e07&|h|a|r| |i|n| |s|t|r|i|n|g|;+0#0000000&| @30|c+0#00e0e07&|h|a|r|i|n|s|t|r|i|n|g| +0#0000000&@14 +@2|l+0#00e0e07&|a|s|t| |c|h|a|r| |i|n| |s|t|r|i|n|g|;+0#0000000&| @25|l+0#00e0e07&|a|s|t|c|h|a|r|i|n|s|t|r|i|n|g| +0#0000000&@10 +@2>s+0#00e0e07&|t|r|i|n|g| |i|n| |s|t|r|i|n|g|;+0#0000000&| @28|s+0#00e0e07&|t|r|i|n|g|i|n|s|t|r|i|n|g| +0#0000000&@12 +@2|i+0#00e0e07&|d|f|;+0#0000000&| @41|i+0#00e0e07&|d|f| +0#0000000&@23 +@2|t+0#00e0e07&|e|r|m|;+0#0000000&| @40|t+0#00e0e07&|e|r|m| +0#0000000&@22 +@2|p+0#00e0e07&|r|o|g|r|a|m| |i|d|f|;+0#0000000&| @33|p+0#00e0e07&|r|o|g|r|a|m|i|d|f| +0#0000000&@16 +|#+0#0000e05&| |E|v|e|n|t| |r|o|u|t|i|n|e|s|.| |#| +0#0000000&@55 +@2|o+0#00e0e07&|n| |f|i|l|e| |e|n|d|;+0#0000000&| @33|o+0#00e0e07&|n|f|i|l|e@1|n|d| +0#0000000&@17 +@2|o+0#00e0e07&|n| |p|a|g|e| |e|n|d|;+0#0000000&| @33|o+0#00e0e07&|n|p|a|g|e@1|n|d| +0#0000000&@17 +@2|o+0#00e0e07&|n| |l|i|n|e| |e|n|d|;+0#0000000&| @33|o+0#00e0e07&|n|l|i|n|e@1|n|d| +0#0000000&@17 +@2|o+0#00e0e07&|n| |l|o|g|i|c|a|l| |f|i|l|e| |e|n|d|;+0#0000000&| @25|o+0#00e0e07&|n|l|o|g|i|c|a|l|f|i|l|e@1|n|d| +0#0000000&@10 +@2|o+0#00e0e07&|n| |p|h|y|s|i|c|a|l| |f|i|l|e| |e|n|d|;+0#0000000&| @24|o+0#00e0e07&|n|p|h|y|s|i|c|a|l|f|i|l|e@1|n|d| +0#0000000&@9 +@2|o+0#00e0e07&|n| |f|o|r|m|a|t| |e|n|d|;+0#0000000&| @31|o+0#00e0e07&|n|f|o|r|m|a|t|e|n|d| +0#0000000&@15 +@2|o+0#00e0e07&|n| |f|o|r|m|a|t| |e|r@1|o|r|;+0#0000000&| @29|o+0#00e0e07&|n|f|o|r|m|a|t|e|r@1|o|r| +0#0000000&@13 +@2|o+0#00e0e07&|n| |v|a|l|u|e| |e|r@1|o|r|;+0#0000000&| @30|o+0#00e0e07&|n|v|a|l|u|e@1|r@1|o|r| +0#0000000&@14 +@2|o+0#00e0e07&|n| |o|p|e|n| |e|r@1|o|r|;+0#0000000&| @31|o+0#00e0e07&|n|o|p|e|n|e|r@1|o|r| +0#0000000&@15 +@57|1|2|6|4|,|3| @7|6|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_73.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_73.dump new file mode 100644 index 0000000000..959c29a4ac --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_73.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|o+0#00e0e07&|n| |o|p|e|n| |e|r@1|o|r|;+0#0000000&| @31|o+0#00e0e07&|n|o|p|e|n|e|r@1|o|r| +0#0000000&@15 +@2|o+0#00e0e07&|n| |t|r|a|n|s|p|u|t| |e|r@1|o|r|;+0#0000000&| @27|o+0#00e0e07&|n|t|r|a|n|s|p|u|t|e|r@1|o|r| +0#0000000&@11 +|#+0#0000e05&| |E|n|q|u|i|r|i|e|s| |o|n| |f|i|l|e|s|.| |#| +0#0000000&@51 +@2|d+0#00e0e07&|r|a|w| |p|o|s@1|i|b|l|e|;+0#0000000&| @31|d+0#00e0e07&|r|a|w|p|o|s@1|i|b|l|e| +0#0000000&@14 +@2|e+0#00e0e07&|n|d| |o|f| |f|i|l|e|;+0#0000000&| @33|e+0#00e0e07&|n|d|o|f@1|i|l|e| +0#0000000&@17 +@2>e+0#00e0e07&|n|d| |o|f| |l|i|n|e|;+0#0000000&| @33|e+0#00e0e07&|n|d|o|f|l|i|n|e| +0#0000000&@17 +@2|e+0#00e0e07&|o|f|;+0#0000000&| @41|e+0#00e0e07&|o|f| +0#0000000&@23 +@2|e+0#00e0e07&|o|l|n|;+0#0000000&| @40|e+0#00e0e07&|o|l|n| +0#0000000&@22 +@2|r+0#00e0e07&|e|w|i|n|d| |p|o|s@1|i|b|l|e|;+0#0000000&| @29|r+0#00e0e07&|e|w|i|n|d|p|o|s@1|i|b|l|e| +0#0000000&@12 +@2|b+0#00e0e07&|i|n| |p|o|s@1|i|b|l|e|;+0#0000000&| @32|b+0#00e0e07&|i|n|p|o|s@1|i|b|l|e| +0#0000000&@15 +@2|c+0#00e0e07&|o|m|p|r|e|s@1|i|b|l|e|;+0#0000000&| @32|c+0#00e0e07&|o|m|p|r|e|s@1|i|b|l|e| +0#0000000&@14 +@2|g+0#00e0e07&|e|t| |p|o|s@1|i|b|l|e|;+0#0000000&| @32|g+0#00e0e07&|e|t|p|o|s@1|i|b|l|e| +0#0000000&@15 +@2|p+0#00e0e07&|u|t| |p|o|s@1|i|b|l|e|;+0#0000000&| @32|p+0#00e0e07&|u|t|p|o|s@1|i|b|l|e| +0#0000000&@15 +@2|r+0#00e0e07&|e|i|d|f| |p|o|s@1|i|b|l|e|;+0#0000000&| @30|r+0#00e0e07&|e|i|d|f|p|o|s@1|i|b|l|e| +0#0000000&@13 +@2|r+0#00e0e07&|e|s|e|t| |p|o|s@1|i|b|l|e|;+0#0000000&| @30|r+0#00e0e07&|e|s|e|t|p|o|s@1|i|b|l|e| +0#0000000&@13 +@2|s+0#00e0e07&|e|t| |p|o|s@1|i|b|l|e|;+0#0000000&| @32|s+0#00e0e07&|e|t|p|o|s@1|i|b|l|e| +0#0000000&@15 +|#+0#0000e05&| |H|a|n|d|l|i|n|g| |o|f| |f|i|l|e|s|.| |#| +0#0000000&@52 +@2|o+0#00e0e07&|p|e|n|;+0#0000000&| @40|o+0#00e0e07&|p|e|n| +0#0000000&@22 +@2|a+0#00e0e07&|p@1|e|n|d|;+0#0000000&| @38|a+0#00e0e07&|p@1|e|n|d| +0#0000000&@20 +@57|1|2|8|2|,|3| @7|6|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_74.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_74.dump new file mode 100644 index 0000000000..8b03053ea4 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_74.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|a+0#00e0e07&|p@1|e|n|d|;+0#0000000&| @38|a+0#00e0e07&|p@1|e|n|d| +0#0000000&@20 +@2|e+0#00e0e07&|s|t|a|b|l|i|s|h|;+0#0000000&| @35|e+0#00e0e07&|s|t|a|b|l|i|s|h| +0#0000000&@17 +@2|a+0#00e0e07&|s@1|o|c|i|a|t|e|;+0#0000000&| @35|a+0#00e0e07&|s@1|o|c|i|a|t|e| +0#0000000&@17 +@2|c+0#00e0e07&|o@1|k|e|d|;+0#0000000&| @38|c+0#00e0e07&|o@1|k|e|d| +0#0000000&@20 +@2|r+0#00e0e07&|a|w|;+0#0000000&| @41|r+0#00e0e07&|a|w| +0#0000000&@23 +@2>r+0#00e0e07&|e|w|i|n|d|;+0#0000000&| @38|r+0#00e0e07&|e|w|i|n|d| +0#0000000&@20 +@2|b+0#00e0e07&|a|c|k|s|p|a|c|e|;+0#0000000&| @35|b+0#00e0e07&|a|c|k|s|p|a|c|e| +0#0000000&@17 +@2|c+0#00e0e07&|l|o|s|e|;+0#0000000&| @39|c+0#00e0e07&|l|o|s|e| +0#0000000&@21 +@2|c+0#00e0e07&|r|e|a|t|e|;+0#0000000&| @38|c+0#00e0e07&|r|e|a|t|e| +0#0000000&@20 +@2|e+0#00e0e07&|r|a|s|e|;+0#0000000&| @39|e+0#00e0e07&|r|a|s|e| +0#0000000&@21 +@2|l+0#00e0e07&|o|c|k|;+0#0000000&| @40|l+0#00e0e07&|o|c|k| +0#0000000&@22 +@2|n+0#00e0e07&|e|w|l|i|n|e|;+0#0000000&| @37|n+0#00e0e07&|e|w|l|i|n|e| +0#0000000&@19 +@2|n+0#00e0e07&|e|w|p|a|g|e|;+0#0000000&| @37|n+0#00e0e07&|e|w|p|a|g|e| +0#0000000&@19 +@2|r+0#00e0e07&|e|s|e|t|;+0#0000000&| @39|r+0#00e0e07&|e|s|e|t| +0#0000000&@21 +@2|s+0#00e0e07&|c|r|a|t|c|h|;+0#0000000&| @37|s+0#00e0e07&|c|r|a|t|c|h| +0#0000000&@19 +@2|s+0#00e0e07&|p|a|c|e|;+0#0000000&| @39|s+0#00e0e07&|p|a|c|e| +0#0000000&@21 +@2|s+0#00e0e07&|e|t|;+0#0000000&| @41|s+0#00e0e07&|e|t| +0#0000000&@23 +@2|s+0#00e0e07&|e@1|k|;+0#0000000&| @40|s+0#00e0e07&|e@1|k| +0#0000000&@22 +@2|r+0#00e0e07&|e|a|d|;+0#0000000&| @40|r+0#00e0e07&|e|a|d| +0#0000000&@22 +@57|1|3|0@1|,|3| @7|6|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_75.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_75.dump new file mode 100644 index 0000000000..7f750d9cb6 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_75.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|r+0#00e0e07&|e|a|d|;+0#0000000&| @40|r+0#00e0e07&|e|a|d| +0#0000000&@22 +@2|r+0#00e0e07&|e|a|d| |b|i|n|;+0#0000000&| @36|r+0#00e0e07&|e|a|d|b|i|n| +0#0000000&@19 +@2|r+0#00e0e07&|e|a|d|f|;+0#0000000&| @39|r+0#00e0e07&|e|a|d|f| +0#0000000&@21 +@2|p+0#00e0e07&|r|i|n|t| |b|i|n|;+0#0000000&| @35|p+0#00e0e07&|r|i|n|t|b|i|n| +0#0000000&@18 +@2|p+0#00e0e07&|r|i|n|t|f|;+0#0000000&| @38|p+0#00e0e07&|r|i|n|t|f| +0#0000000&@20 +@2>p+0#00e0e07&|r|i|n|t|;+0#0000000&| @39|p+0#00e0e07&|r|i|n|t| +0#0000000&@21 +@2|w+0#00e0e07&|r|i|t|e| |b|i|n|;+0#0000000&| @35|w+0#00e0e07&|r|i|t|e|b|i|n| +0#0000000&@18 +@2|w+0#00e0e07&|r|i|t|e|f|;+0#0000000&| @38|w+0#00e0e07&|r|i|t|e|f| +0#0000000&@20 +@2|w+0#00e0e07&|r|i|t|e|;+0#0000000&| @39|w+0#00e0e07&|r|i|t|e| +0#0000000&@21 +@2|g+0#00e0e07&|e|t|;+0#0000000&| @41|g+0#00e0e07&|e|t| +0#0000000&@23 +@2|g+0#00e0e07&|e|t|f|;+0#0000000&| @40|g+0#00e0e07&|e|t|f| +0#0000000&@22 +@2|g+0#00e0e07&|e|t| |b|i|n|;+0#0000000&| @37|g+0#00e0e07&|e|t|b|i|n| +0#0000000&@20 +@2|p+0#00e0e07&|u|t|;+0#0000000&| @41|p+0#00e0e07&|u|t| +0#0000000&@23 +@2|p+0#00e0e07&|u|t|f|;+0#0000000&| @40|p+0#00e0e07&|u|t|f| +0#0000000&@22 +@2|p+0#00e0e07&|u|t| |b|i|n|;+0#0000000&| @37|p+0#00e0e07&|u|t|b|i|n| +0#0000000&@20 +@2|g+0#00e0e07&|e|t|s|;+0#0000000&| @40|g+0#00e0e07&|e|t|s| +0#0000000&@22 +@2|g+0#00e0e07&|e|t|s|f|;+0#0000000&| @39|g+0#00e0e07&|e|t|s|f| +0#0000000&@21 +@2|p+0#00e0e07&|u|t|s|;+0#0000000&| @40|p+0#00e0e07&|u|t|s| +0#0000000&@22 +@2|p+0#00e0e07&|u|t|s|f|;+0#0000000&| @39|p+0#00e0e07&|u|t|s|f| +0#0000000&@21 +@57|1|3|1|8|,|3| @7|6|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_76.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_76.dump new file mode 100644 index 0000000000..06a1dc700d --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_76.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|p+0#00e0e07&|u|t|s|f|;+0#0000000&| @39|p+0#00e0e07&|u|t|s|f| +0#0000000&@21 +@2|s+0#00e0e07&|t|r|i|n|g|;+0#0000000&| @38|s+0#00e0e07&|t|r|i|n|g| +0#0000000&@20 +@2|s+0#00e0e07&|t|r|i|n|g|f|;+0#0000000&| @37|s+0#00e0e07&|t|r|i|n|g|f| +0#0000000&@19 +@2|r+0#00e0e07&|e|a|d| |l|i|n|e|;+0#0000000&| @35|r+0#00e0e07&|e|a|d|l|i|n|e| +0#0000000&@18 +|#+0#0000e05&| |S|e|t| |u|p| |s|t|a|n|d|e|n|v| |-| |e|x|t|e|n|s|i|o|n|s|.| |#| +0#0000000&@41 +>#+0#0000e05&| |U|N|I|X| |t|h|i|n|g|s|.| |#| +0#0000000&@58 +@2|r+0#00e0e07&|o|w|s|;+0#0000000&| @40|r+0#00e0e07&|o|w|s| +0#0000000&@22 +@2|c+0#00e0e07&|o|l|u|m|n|s|;+0#0000000&| @37|c+0#00e0e07&|o|l|u|m|n|s| +0#0000000&@19 +@2|a+0#00e0e07&|r|g|c|;+0#0000000&| @40|a+0#00e0e07&|r|g|c| +0#0000000&@22 +@2|a+0#00e0e07&|6|8|g| |a|r|g|c|;+0#0000000&| @35|a+0#00e0e07&|6|8|g|a|r|g|c| +0#0000000&@18 +@2|e+0#00e0e07&|r@1|n|o|;+0#0000000&| @39|e+0#00e0e07&|r@1|n|o| +0#0000000&@21 +@2|f+0#00e0e07&|o|r|k|;+0#0000000&| @40|f+0#00e0e07&|o|r|k| +0#0000000&@22 +@2|g+0#00e0e07&|e|t| |p|w|d|;+0#0000000&| @37|g+0#00e0e07&|e|t|p|w|d| +0#0000000&@20 +@2|s+0#00e0e07&|e|t| |p|w|d|;+0#0000000&| @37|s+0#00e0e07&|e|t|p|w|d| +0#0000000&@20 +@2|f+0#00e0e07&|i|l|e| |i|s| |d|i|r|e|c|t|o|r|y|;+0#0000000&| @27|f+0#00e0e07&|i|l|e|i|s|d|i|r|e|c|t|o|r|y| +0#0000000&@11 +@2|f+0#00e0e07&|i|l|e| |i|s| |b|l|o|c|k| |d|e|v|i|c|e|;+0#0000000&| @24|f+0#00e0e07&|i|l|e|i|s|b|l|o|c|k|d|e|v|i|c|e| +0#0000000&@9 +@2|f+0#00e0e07&|i|l|e| |i|s| |c|h|a|r| |d|e|v|i|c|e|;+0#0000000&| @25|f+0#00e0e07&|i|l|e|i|s|c|h|a|r|d|e|v|i|c|e| +0#0000000&@10 +@2|f+0#00e0e07&|i|l|e| |i|s| |r|e|g|u|l|a|r|;+0#0000000&| @29|f+0#00e0e07&|i|l|e|i|s|r|e|g|u|l|a|r| +0#0000000&@13 +@2|f+0#00e0e07&|i|l|e| |i|s| |f|i|f|o|;+0#0000000&| @32|f+0#00e0e07&|i|l|e|i|s|f|i|f|o| +0#0000000&@16 +@57|1|3@1|6|,|1| @7|6|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_77.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_77.dump new file mode 100644 index 0000000000..c719c821c7 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_77.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|f+0#00e0e07&|i|l|e| |i|s| |f|i|f|o|;+0#0000000&| @32|f+0#00e0e07&|i|l|e|i|s|f|i|f|o| +0#0000000&@16 +@2|f+0#00e0e07&|i|l|e| |i|s| |l|i|n|k|;+0#0000000&| @32|f+0#00e0e07&|i|l|e|i|s|l|i|n|k| +0#0000000&@16 +@2|f+0#00e0e07&|i|l|e| |m|o|d|e|;+0#0000000&| @35|f+0#00e0e07&|i|l|e|m|o|d|e| +0#0000000&@18 +@2|a+0#00e0e07&|r|g|v|;+0#0000000&| @40|a+0#00e0e07&|r|g|v| +0#0000000&@22 +@2|a+0#00e0e07&|6|8|g| |a|r|g|v|;+0#0000000&| @35|a+0#00e0e07&|6|8|g|a|r|g|v| +0#0000000&@18 +@2>r+0#00e0e07&|e|s|e|t| |e|r@1|n|o|;+0#0000000&| @33|r+0#00e0e07&|e|s|e|t|e|r@1|n|o| +0#0000000&@16 +@2|s+0#00e0e07&|t|r| |e|r@1|o|r|;+0#0000000&| @35|s+0#00e0e07&|t|r|e|r@1|o|r| +0#0000000&@18 +@2|e+0#00e0e07&|x|e|c|;+0#0000000&| @40|e+0#00e0e07&|x|e|c| +0#0000000&@22 +@2|e+0#00e0e07&|x|e|c|v|e|;+0#0000000&| @38|e+0#00e0e07&|x|e|c|v|e| +0#0000000&@20 +@2|c+0#00e0e07&|r|e|a|t|e| |p|i|p|e|;+0#0000000&| @33|c+0#00e0e07&|r|e|a|t|e|p|i|p|e| +0#0000000&@16 +@2|e+0#00e0e07&|x|e|c| |s|u|b|;+0#0000000&| @36|e+0#00e0e07&|x|e|c|s|u|b| +0#0000000&@19 +@2|e+0#00e0e07&|x|e|c|v|e| |c|h|i|l|d|;+0#0000000&| @32|e+0#00e0e07&|x|e|c|v|e|c|h|i|l|d| +0#0000000&@15 +@2|e+0#00e0e07&|x|e|c| |s|u|b| |p|i|p|e|l|i|n|e|;+0#0000000&| @27|e+0#00e0e07&|x|e|c|s|u|b|p|i|p|e|l|i|n|e| +0#0000000&@11 +@2|e+0#00e0e07&|x|e|c|v|e| |c|h|i|l|d|p|i|p|e|;+0#0000000&| @28|e+0#00e0e07&|x|e|c|v|e|c|h|i|l|d|p|i|p|e| +0#0000000&@11 +@2|e+0#00e0e07&|x|e|c| |s|u|b| |o|u|t|p|u|t|;+0#0000000&| @29|e+0#00e0e07&|x|e|c|s|u|b|o|u|t|p|u|t| +0#0000000&@13 +@2|e+0#00e0e07&|x|e|c|v|e| |o|u|t|p|u|t|;+0#0000000&| @31|e+0#00e0e07&|x|e|c|v|e|o|u|t|p|u|t| +0#0000000&@14 +@2|g+0#00e0e07&|e|t| |e|n|v|;+0#0000000&| @37|g+0#00e0e07&|e|t|e|n|v| +0#0000000&@20 +@2|w+0#00e0e07&|a|i|t| |p|i|d|;+0#0000000&| @36|w+0#00e0e07&|a|i|t|p|i|d| +0#0000000&@19 +@2|u+0#00e0e07&|t|c| |t|i|m|e|;+0#0000000&| @36|u+0#00e0e07&|t|c|t|i|m|e| +0#0000000&@19 +@57|1|3|5|4|,|3| @7|6|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_78.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_78.dump new file mode 100644 index 0000000000..b5aaa68ecd --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_78.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|u+0#00e0e07&|t|c| |t|i|m|e|;+0#0000000&| @36|u+0#00e0e07&|t|c|t|i|m|e| +0#0000000&@19 +@2|l+0#00e0e07&|o|c|a|l| |t|i|m|e|;+0#0000000&| @34|l+0#00e0e07&|o|c|a|l|t|i|m|e| +0#0000000&@17 +@2|g+0#00e0e07&|r|e|p| |i|n| |s|t|r|i|n|g|;+0#0000000&| @30|g+0#00e0e07&|r|e|p|i|n|s|t|r|i|n|g| +0#0000000&@14 +@2|g+0#00e0e07&|r|e|p| |i|n| |s|u|b|s|t|r|i|n|g|;+0#0000000&| @27|g+0#00e0e07&|r|e|p|i|n|s|u|b|s|t|r|i|n|g| +0#0000000&@11 +@2|s+0#00e0e07&|u|b| |i|n| |s|t|r|i|n|g|;+0#0000000&| @31|s+0#00e0e07&|u|b|i|n|s|t|r|i|n|g| +0#0000000&@15 +@2>p+0#00e0e07&|e@1|k| |c|h|a|r|;+0#0000000&| @35|p+0#00e0e07&|e@1|k|c|h|a|r| +0#0000000&@18 +@2|g+0#00e0e07&|e|t| |d|i|r|e|c|t|o|r|y|;+0#0000000&| @31|g+0#00e0e07&|e|t|d|i|r|e|c|t|o|r|y| +0#0000000&@14 +@2|h+0#00e0e07&|t@1|p| |t|i|m|e|o|u|t|;+0#0000000&| @32|h+0#00e0e07&|t@1|p|t|i|m|e|o|u|t| +0#0000000&@15 +@2|h+0#00e0e07&|t@1|p|s| |t|i|m|e|o|u|t|;+0#0000000&| @31|h+0#00e0e07&|t@1|p|s|t|i|m|e|o|u|t| +0#0000000&@14 +@2|h+0#00e0e07&|t@1|p| |c|o|n|t|e|n|t|;+0#0000000&| @32|h+0#00e0e07&|t@1|p|c|o|n|t|e|n|t| +0#0000000&@15 +@2|h+0#00e0e07&|t@1|p|s| |c|o|n|t|e|n|t|;+0#0000000&| @31|h+0#00e0e07&|t@1|p|s|c|o|n|t|e|n|t| +0#0000000&@14 +|#+0#0000e05&| |D|r|a|w|i|n|g|.| |#| +0#0000000&@62 +@2|d+0#00e0e07&|r|a|w| |d|e|v|i|c|e|;+0#0000000&| @33|d+0#00e0e07&|r|a|w|d|e|v|i|c|e| +0#0000000&@16 +@2|m+0#00e0e07&|a|k|e| |d|e|v|i|c|e|;+0#0000000&| @33|m+0#00e0e07&|a|k|e|d|e|v|i|c|e| +0#0000000&@16 +@2|d+0#00e0e07&|r|a|w| |a|s|p|e|c|t|;+0#0000000&| @33|d+0#00e0e07&|r|a|w|a|s|p|e|c|t| +0#0000000&@16 +@2|d+0#00e0e07&|r|a|w| |c|l|e|a|r|;+0#0000000&| @34|d+0#00e0e07&|r|a|w|c|l|e|a|r| +0#0000000&@17 +@2|d+0#00e0e07&|r|a|w| |e|r|a|s|e|;+0#0000000&| @34|d+0#00e0e07&|r|a|w|e|r|a|s|e| +0#0000000&@17 +@2|d+0#00e0e07&|r|a|w| |f|l|u|s|h|;+0#0000000&| @34|d+0#00e0e07&|r|a|w|f|l|u|s|h| +0#0000000&@17 +@2|d+0#00e0e07&|r|a|w| |s|h|o|w|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|s|h|o|w| +0#0000000&@18 +@57|1|3|7|2|,|3| @7|6|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_79.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_79.dump new file mode 100644 index 0000000000..96f6512611 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_79.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|d+0#00e0e07&|r|a|w| |s|h|o|w|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|s|h|o|w| +0#0000000&@18 +@2|d+0#00e0e07&|r|a|w| |f|i|l@1| |s|t|y|l|e|;+0#0000000&| @29|d+0#00e0e07&|r|a|w|f|i|l@1|s|t|y|l|e| +0#0000000&@13 +@2|d+0#00e0e07&|r|a|w| |g|e|t| |c|o|l|o|u|r| |n|a|m|e|;+0#0000000&| @24|d+0#00e0e07&|r|a|w|g|e|t|c|o|l|o|u|r|n|a|m|e| +0#0000000&@9 +@2|d+0#00e0e07&|r|a|w| |g|e|t| |c|o|l|o|r| |n|a|m|e|;+0#0000000&| @25|d+0#00e0e07&|r|a|w|g|e|t|c|o|l|o|r|n|a|m|e| +0#0000000&@10 +@2|d+0#00e0e07&|r|a|w| |c|o|l|o|r|;+0#0000000&| @34|d+0#00e0e07&|r|a|w|c|o|l|o|r| +0#0000000&@17 +@2>d+0#00e0e07&|r|a|w| |c|o|l|o|u|r|;+0#0000000&| @33|d+0#00e0e07&|r|a|w|c|o|l|o|u|r| +0#0000000&@16 +@2|d+0#00e0e07&|r|a|w| |b|a|c|k|g|r|o|u|n|d| |c|o|l|o|r|;+0#0000000&| @23|d+0#00e0e07&|r|a|w|b|a|c|k|g|r|o|u|n|d|c|o|l|o|r| +0#0000000&@7 +@2|d+0#00e0e07&|r|a|w| |b|a|c|k|g|r|o|u|n|d| |c|o|l|o|u|r|;+0#0000000&| @22|d+0#00e0e07&|r|a|w|b|a|c|k|g|r|o|u|n|d|c|o|l|o|u|r| +0#0000000&@6 +@2|d+0#00e0e07&|r|a|w| |c|i|r|c|l|e|;+0#0000000&| @33|d+0#00e0e07&|r|a|w|c|i|r|c|l|e| +0#0000000&@16 +@2|d+0#00e0e07&|r|a|w| |b|a|l@1|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|b|a|l@1| +0#0000000&@18 +@2|d+0#00e0e07&|r|a|w| |s|t|a|r|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|s|t|a|r| +0#0000000&@18 +@2|d+0#00e0e07&|r|a|w| |p|o|i|n|t|;+0#0000000&| @34|d+0#00e0e07&|r|a|w|p|o|i|n|t| +0#0000000&@17 +@2|d+0#00e0e07&|r|a|w| |l|i|n|e|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|l|i|n|e| +0#0000000&@18 +@2|d+0#00e0e07&|r|a|w| |m|o|v|e|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|m|o|v|e| +0#0000000&@18 +@2|d+0#00e0e07&|r|a|w| |r|e|c|t|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|r|e|c|t| +0#0000000&@18 +@2|d+0#00e0e07&|r|a|w| |t|e|x|t|;+0#0000000&| @35|d+0#00e0e07&|r|a|w|t|e|x|t| +0#0000000&@18 +@2|d+0#00e0e07&|r|a|w| |l|i|n|e|s|t|y|l|e|;+0#0000000&| @30|d+0#00e0e07&|r|a|w|l|i|n|e|s|t|y|l|e| +0#0000000&@13 +@2|d+0#00e0e07&|r|a|w| |f|o|n|t| |n|a|m|e|;+0#0000000&| @30|d+0#00e0e07&|r|a|w|f|o|n|t|n|a|m|e| +0#0000000&@14 +@2|d+0#00e0e07&|r|a|w| |l|i|n|e|w|i|d|t|h|;+0#0000000&| @30|d+0#00e0e07&|r|a|w|l|i|n|e|w|i|d|t|h| +0#0000000&@13 +@57|1|3|9|0|,|3| @7|6@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_80.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_80.dump new file mode 100644 index 0000000000..c23bf1283b --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_80.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|d+0#00e0e07&|r|a|w| |l|i|n|e|w|i|d|t|h|;+0#0000000&| @30|d+0#00e0e07&|r|a|w|l|i|n|e|w|i|d|t|h| +0#0000000&@13 +@2|d+0#00e0e07&|r|a|w| |f|o|n|t| |s|i|z|e|;+0#0000000&| @30|d+0#00e0e07&|r|a|w|f|o|n|t|s|i|z|e| +0#0000000&@14 +@2|d+0#00e0e07&|r|a|w| |t|e|x|t| |a|n|g|l|e|;+0#0000000&| @29|d+0#00e0e07&|r|a|w|t|e|x|t|a|n|g|l|e| +0#0000000&@13 +@2|d+0#00e0e07&|r|a|w| |c|o|l|o|r| |n|a|m|e|;+0#0000000&| @29|d+0#00e0e07&|r|a|w|c|o|l|o|r|n|a|m|e| +0#0000000&@13 +@2|d+0#00e0e07&|r|a|w| |c|o|l|o|u|r| |n|a|m|e|;+0#0000000&| @28|d+0#00e0e07&|r|a|w|c|o|l|o|u|r|n|a|m|e| +0#0000000&@12 +@2>d+0#00e0e07&|r|a|w| |b|a|c|k|g|r|o|u|n|d| |c|o|l|o|r| |n|a|m|e|;+0#0000000&| @18|d+0#00e0e07&|r|a|w|b|a|c|k|g|r|o|u|n|d|c|o|l|o|r|n|a|m|e| +0#0000000&@3 +@2|d+0#00e0e07&|r|a|w| |b|a|c|k|g|r|o|u|n|d| |c|o|l|o|u|r| |n|a|m|e|;+0#0000000&| @17|d+0#00e0e07&|r|a|w|b|a|c|k|g|r|o|u|n|d|c|o|l|o|u|r|n|a|m|e| +0#0000000&@2 +@2|c+0#00e0e07&|u|r|s|e|s| |s|t|a|r|t|;+0#0000000&| @32|c+0#00e0e07&|u|r|s|e|s@1|t|a|r|t| +0#0000000&@15 +@2|c+0#00e0e07&|u|r|s|e|s| |e|n|d|;+0#0000000&| @34|c+0#00e0e07&|u|r|s|e|s|e|n|d| +0#0000000&@17 +@2|c+0#00e0e07&|u|r|s|e|s| |c|l|e|a|r|;+0#0000000&| @32|c+0#00e0e07&|u|r|s|e|s|c|l|e|a|r| +0#0000000&@15 +@2|c+0#00e0e07&|u|r|s|e|s| |r|e|f|r|e|s|h|;+0#0000000&| @30|c+0#00e0e07&|u|r|s|e|s|r|e|f|r|e|s|h| +0#0000000&@13 +@2|c+0#00e0e07&|u|r|s|e|s| |g|r|e@1|n|;+0#0000000&| @32|c+0#00e0e07&|u|r|s|e|s|g|r|e@1|n| +0#0000000&@15 +@2|c+0#00e0e07&|u|r|s|e|s| |c|y|a|n|;+0#0000000&| @33|c+0#00e0e07&|u|r|s|e|s|c|y|a|n| +0#0000000&@16 +@2|c+0#00e0e07&|u|r|s|e|s| |r|e|d|;+0#0000000&| @34|c+0#00e0e07&|u|r|s|e|s|r|e|d| +0#0000000&@17 +@2|c+0#00e0e07&|u|r|s|e|s| |y|e|l@1|o|w|;+0#0000000&| @31|c+0#00e0e07&|u|r|s|e|s|y|e|l@1|o|w| +0#0000000&@14 +@2|c+0#00e0e07&|u|r|s|e|s| |m|a|g|e|n|t|a|;+0#0000000&| @30|c+0#00e0e07&|u|r|s|e|s|m|a|g|e|n|t|a| +0#0000000&@13 +@2|c+0#00e0e07&|u|r|s|e|s| |b|l|u|e|;+0#0000000&| @33|c+0#00e0e07&|u|r|s|e|s|b|l|u|e| +0#0000000&@16 +@2|c+0#00e0e07&|u|r|s|e|s| |w|h|i|t|e|;+0#0000000&| @32|c+0#00e0e07&|u|r|s|e|s|w|h|i|t|e| +0#0000000&@15 +@2|c+0#00e0e07&|u|r|s|e|s| |g|r|e@1|n| |i|n|v|e|r|s|e|;+0#0000000&| @24|c+0#00e0e07&|u|r|s|e|s|g|r|e@1|n|i|n|v|e|r|s|e| +0#0000000&@8 +@57|1|4|0|8|,|3| @7|6@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_81.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_81.dump new file mode 100644 index 0000000000..3e53a609db --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_81.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|u|r|s|e|s| |g|r|e@1|n| |i|n|v|e|r|s|e|;+0#0000000&| @24|c+0#00e0e07&|u|r|s|e|s|g|r|e@1|n|i|n|v|e|r|s|e| +0#0000000&@8 +@2|c+0#00e0e07&|u|r|s|e|s| |c|y|a|n| |i|n|v|e|r|s|e|;+0#0000000&| @25|c+0#00e0e07&|u|r|s|e|s|c|y|a|n|i|n|v|e|r|s|e| +0#0000000&@9 +@2|c+0#00e0e07&|u|r|s|e|s| |r|e|d| |i|n|v|e|r|s|e|;+0#0000000&| @26|c+0#00e0e07&|u|r|s|e|s|r|e|d|i|n|v|e|r|s|e| +0#0000000&@10 +@2|c+0#00e0e07&|u|r|s|e|s| |y|e|l@1|o|w| |i|n|v|e|r|s|e|;+0#0000000&| @23|c+0#00e0e07&|u|r|s|e|s|y|e|l@1|o|w|i|n|v|e|r|s|e| +0#0000000&@7 +@2|c+0#00e0e07&|u|r|s|e|s| |m|a|g|e|n|t|a| |i|n|v|e|r|s|e|;+0#0000000&| @22|c+0#00e0e07&|u|r|s|e|s|m|a|g|e|n|t|a|i|n|v|e|r|s|e| +0#0000000&@6 +@2>c+0#00e0e07&|u|r|s|e|s| |b|l|u|e| |i|n|v|e|r|s|e|;+0#0000000&| @25|c+0#00e0e07&|u|r|s|e|s|b|l|u|e|i|n|v|e|r|s|e| +0#0000000&@9 +@2|c+0#00e0e07&|u|r|s|e|s| |w|h|i|t|e| |i|n|v|e|r|s|e|;+0#0000000&| @24|c+0#00e0e07&|u|r|s|e|s|w|h|i|t|e|i|n|v|e|r|s|e| +0#0000000&@8 +@2|c+0#00e0e07&|u|r|s|e|s| |g|e|t| |c|h|a|r|;+0#0000000&| @29|c+0#00e0e07&|u|r|s|e|s|g|e|t|c|h|a|r| +0#0000000&@13 +@2|c+0#00e0e07&|u|r|s|e|s| |p|u|t| |c|h|a|r|;+0#0000000&| @29|c+0#00e0e07&|u|r|s|e|s|p|u|t|c|h|a|r| +0#0000000&@13 +@2|c+0#00e0e07&|u|r|s|e|s| |m|o|v|e|;+0#0000000&| @33|c+0#00e0e07&|u|r|s|e|s|m|o|v|e| +0#0000000&@16 +@2|c+0#00e0e07&|u|r|s|e|s| |l|i|n|e|s|;+0#0000000&| @32|c+0#00e0e07&|u|r|s|e|s|l|i|n|e|s| +0#0000000&@15 +@2|c+0#00e0e07&|u|r|s|e|s| |c|o|l|u|m|n|s|;+0#0000000&| @30|c+0#00e0e07&|u|r|s|e|s|c|o|l|u|m|n|s| +0#0000000&@13 +@2|c+0#00e0e07&|u|r|s|e|s| |d|e|l|c|h|a|r|;+0#0000000&| @30|c+0#00e0e07&|u|r|s|e|s|d|e|l|c|h|a|r| +0#0000000&@13 +@2|p+0#00e0e07&|q| |c|o|n@1|e|c|t| |d|b|;+0#0000000&| @31|p+0#00e0e07&|q|c|o|n@1|e|c|t|d|b| +0#0000000&@15 +@2|p+0#00e0e07&|q| |f|i|n|i|s|h|;+0#0000000&| @35|p+0#00e0e07&|q|f|i|n|i|s|h| +0#0000000&@18 +@2|p+0#00e0e07&|q| |r|e|s|e|t|;+0#0000000&| @36|p+0#00e0e07&|q|r|e|s|e|t| +0#0000000&@19 +@2|p+0#00e0e07&|q| |p|a|r|a|m|e|t|e|r| |s|t|a|t|u|s|;+0#0000000&| @25|p+0#00e0e07&|q|p|a|r|a|m|e|t|e|r|s|t|a|t|u|s| +0#0000000&@9 +@2|p+0#00e0e07&|q| |e|x|e|c|;+0#0000000&| @37|p+0#00e0e07&|q|e|x|e|c| +0#0000000&@20 +@2|p+0#00e0e07&|q| |f|n|u|m|b|e|r|;+0#0000000&| @34|p+0#00e0e07&|q|f|n|u|m|b|e|r| +0#0000000&@17 +@57|1|4|2|6|,|3| @7|6|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_82.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_82.dump new file mode 100644 index 0000000000..4047d639e8 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_82.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|p+0#00e0e07&|q| |f|n|u|m|b|e|r|;+0#0000000&| @34|p+0#00e0e07&|q|f|n|u|m|b|e|r| +0#0000000&@17 +@2|p+0#00e0e07&|q| |n|t|u|p|l|e|s|;+0#0000000&| @34|p+0#00e0e07&|q|n|t|u|p|l|e|s| +0#0000000&@17 +@2|p+0#00e0e07&|q| |n|f|i|e|l|d|s|;+0#0000000&| @34|p+0#00e0e07&|q|n|f|i|e|l|d|s| +0#0000000&@17 +@2|p+0#00e0e07&|q| |c|m|d| |s|t|a|t|u|s|;+0#0000000&| @31|p+0#00e0e07&|q|c|m|d|s|t|a|t|u|s| +0#0000000&@15 +@2|p+0#00e0e07&|q| |c|m|d| |t|u|p|l|e|s|;+0#0000000&| @31|p+0#00e0e07&|q|c|m|d|t|u|p|l|e|s| +0#0000000&@15 +@2>p+0#00e0e07&|q| |e|r@1|o|r| |m|e|s@1|a|g|e|;+0#0000000&| @28|p+0#00e0e07&|q|e|r@1|o|r|m|e|s@1|a|g|e| +0#0000000&@12 +@2|p+0#00e0e07&|q| |r|e|s|u|l|t| |e|r@1|o|r| |m|e|s@1|a|g|e|;+0#0000000&| @21|p+0#00e0e07&|q|r|e|s|u|l|t|e|r@1|o|r|m|e|s@1|a|g|e| +0#0000000&@6 +@2|p+0#00e0e07&|q| |d|b|;+0#0000000&| @39|p+0#00e0e07&|q|d|b| +0#0000000&@22 +@2|p+0#00e0e07&|q| |u|s|e|r|;+0#0000000&| @37|p+0#00e0e07&|q|u|s|e|r| +0#0000000&@20 +@2|p+0#00e0e07&|q| |p|a|s@1|;+0#0000000&| @37|p+0#00e0e07&|q|p|a|s@1| +0#0000000&@20 +@2|p+0#00e0e07&|q| |h|o|s|t|;+0#0000000&| @37|p+0#00e0e07&|q|h|o|s|t| +0#0000000&@20 +@2|p+0#00e0e07&|q| |p|o|r|t|;+0#0000000&| @37|p+0#00e0e07&|q|p|o|r|t| +0#0000000&@20 +@2|p+0#00e0e07&|q| |t@1|y|;+0#0000000&| @38|p+0#00e0e07&|q|t@1|y| +0#0000000&@21 +@2|p+0#00e0e07&|q| |o|p|t|i|o|n|s|;+0#0000000&| @34|p+0#00e0e07&|q|o|p|t|i|o|n|s| +0#0000000&@17 +@2|p+0#00e0e07&|q| |p|r|o|t|o|c|o|l| |v|e|r|s|i|o|n|;+0#0000000&| @25|p+0#00e0e07&|q|p|r|o|t|o|c|o|l|v|e|r|s|i|o|n| +0#0000000&@9 +@2|p+0#00e0e07&|q| |s|e|r|v|e|r| |v|e|r|s|i|o|n|;+0#0000000&| @27|p+0#00e0e07&|q|s|e|r|v|e|r|v|e|r|s|i|o|n| +0#0000000&@11 +@2|p+0#00e0e07&|q| |s|o|c|k|e|t|;+0#0000000&| @35|p+0#00e0e07&|q|s|o|c|k|e|t| +0#0000000&@18 +@2|p+0#00e0e07&|q| |b|a|c|k|e|n|d| |p|i|d|;+0#0000000&| @30|p+0#00e0e07&|q|b|a|c|k|e|n|d|p|i|d| +0#0000000&@14 +@2|p+0#00e0e07&|q| |f|n|a|m|e|;+0#0000000&| @36|p+0#00e0e07&|q|f|n|a|m|e| +0#0000000&@19 +@57|1|4@2|,|3| @7|6|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_83.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_83.dump new file mode 100644 index 0000000000..5308ba0090 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_83.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|p+0#00e0e07&|q| |f|n|a|m|e|;+0#0000000&| @36|p+0#00e0e07&|q|f|n|a|m|e| +0#0000000&@19 +@2|p+0#00e0e07&|q| |f@1|o|r|m|a|t|;+0#0000000&| @34|p+0#00e0e07&|q|f@1|o|r|m|a|t| +0#0000000&@17 +@2|p+0#00e0e07&|q| |g|e|t| |v|a|l|u|e|;+0#0000000&| @32|p+0#00e0e07&|q|g|e|t|v|a|l|u|e| +0#0000000&@16 +@2|p+0#00e0e07&|q| |g|e|t| |i|s| |n|u|l@1|;+0#0000000&| @30|p+0#00e0e07&|q|g|e|t|i|s|n|u|l@1| +0#0000000&@15 +@2|s+0#00e0e07&|i|g| |s|e|g|v|;+0#0000000&| @36|s+0#00e0e07&|i|g|s|e|g|v| +0#0000000&@19 +> @74 +|#+0#0000e05&|:@12| +0#0000000&@60 +|p+0#0000e05&|r|e|l|u|d|e|-|b|i|t|s|.|c| +0#0000000&@60 +|:+0#0000e05&@12|#| +0#0000000&@60 +@75 +|#+0#0000e05&| |M|u|l|t|i|p|l|e| |p|r|e|c|i|s|i|o|n| |B|I|T|S|.| |#| +0#0000000&@46 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |b|i|t|s| |w|i|d|t|h|;+0#0000000&| @24|l+0#00e0e07&|o|n|g|l|o|n|g|b|i|t|s|w|i|d|t|h| +0#0000000&@9 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |m|a|x| |b|i|t|s|;+0#0000000&| @26|l+0#00e0e07&|o|n|g|l|o|n|g|m|a|x|b|i|t|s| +0#0000000&@11 +@2|l+0#00e0e07&|o|n|g| |l|o|n|g| |b|i|t|s| |p|a|c|k|;+0#0000000&| @25|l+0#00e0e07&|o|n|g|l|o|n|g|b|i|t|s|p|a|c|k| +0#0000000&@10 +@2|L+0#af5f00255&|E|N|G| +0#0000000&@41|L+0#af5f00255&|E|N|G| +0#0000000&@22 +@2|A+0#af5f00255&|B|S| +0#0000000&@42|A+0#af5f00255&|B|S| +0#0000000&@23 +@2|B+0#af5f00255&|I|N| +0#0000000&@42|B+0#af5f00255&|I|N| +0#0000000&@23 +@2|N+0#af5f00255&|O|T| +0#0000000&@42|N+0#af5f00255&|O|T| +0#0000000&@23 +@2|~+0#af5f00255&| +0#0000000&@44|~+0#af5f00255&| +0#0000000&@25 +@57|1|4|6|2|,|0|-|1| @5|6|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_84.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_84.dump new file mode 100644 index 0000000000..cb12a1f91a --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_84.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|~+0#af5f00255&| +0#0000000&@44|~+0#af5f00255&| +0#0000000&@25 +@2|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@38|S+0#af5f00255&|H|O|R|T|E|N| +0#0000000&@19 +@2|=+0#af5f00255&| +0#0000000&@44|=+0#af5f00255&| +0#0000000&@25 +@2|E+0#af5f00255&|Q| +0#0000000&@43|E+0#af5f00255&|Q| +0#0000000&@24 +@2|/+0#af5f00255&|=| +0#0000000&@43|/+0#af5f00255&|=| +0#0000000&@24 +@2>~+0#af5f00255&|=| +0#0000000&@43|~+0#af5f00255&|=| +0#0000000&@24 +@2|^+0#af5f00255&|=| +0#0000000&@43|^+0#af5f00255&|=| +0#0000000&@24 +@2|N+0#af5f00255&|E| +0#0000000&@43|N+0#af5f00255&|E| +0#0000000&@24 +@2|<+0#af5f00255&|=| +0#0000000&@43|<+0#af5f00255&|=| +0#0000000&@24 +@2|L+0#af5f00255&|E| +0#0000000&@43|L+0#af5f00255&|E| +0#0000000&@24 +@2|>+0#af5f00255&|=| +0#0000000&@43|>+0#af5f00255&|=| +0#0000000&@24 +@2|G+0#af5f00255&|E| +0#0000000&@43|G+0#af5f00255&|E| +0#0000000&@24 +@2|A+0#af5f00255&|N|D| +0#0000000&@42|A+0#af5f00255&|N|D| +0#0000000&@23 +@2|&+0#af5f00255&| +0#0000000&@44|&+0#af5f00255&| +0#0000000&@25 +@2|O+0#af5f00255&|R| +0#0000000&@43|O+0#af5f00255&|R| +0#0000000&@24 +@2|X+0#af5f00255&|O|R| +0#0000000&@42|X+0#af5f00255&|O|R| +0#0000000&@23 +@2|S+0#af5f00255&|H|L| +0#0000000&@42|S+0#af5f00255&|H|L| +0#0000000&@23 +@2|U+0#af5f00255&|P| +0#0000000&@43|U+0#af5f00255&|P| +0#0000000&@24 +@2|S+0#af5f00255&|H|R| +0#0000000&@42|S+0#af5f00255&|H|R| +0#0000000&@23 +@57|1|4|8|0|,|3| @7|7|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_85.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_85.dump new file mode 100644 index 0000000000..319058cc76 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_85.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|S+0#af5f00255&|H|R| +0#0000000&@42|S+0#af5f00255&|H|R| +0#0000000&@23 +@2|D+0#af5f00255&|O|W|N| +0#0000000&@41|D+0#af5f00255&|O|W|N| +0#0000000&@22 +@2|E+0#af5f00255&|L|E|M| +0#0000000&@41|E+0#af5f00255&|L|E|M| +0#0000000&@22 +@2|S+0#af5f00255&|E|T| +0#0000000&@42|S+0#af5f00255&|E|T| +0#0000000&@23 +@2|C+0#af5f00255&|L|E|A|R| +0#0000000&@40|C+0#af5f00255&|L|E|A|R| +0#0000000&@21 +> @74 +|#+0#0000e05&|:@12| +0#0000000&@60 +|p+0#0000e05&|r|e|l|u|d|e|-|m|a|t|h|l|i|b|.|c| +0#0000000&@57 +|:+0#0000e05&@12|#| +0#0000000&@60 +@75 +|#+0#0000e05&| |R| |s|p|e|c|i|f|i|c| |s|p|e|c|i|a|l| |f|u|n|c|t|i|o|n|s| |#| +0#0000000&@42 +@2|r+0#00e0e07&| |d|i| |g|a|m@1|a|;+0#0000000&| @34|r+0#00e0e07&|d|i|g|a|m@1|a| +0#0000000&@18 +@2|r+0#00e0e07&| |t|r|i| |g|a|m@1|a|;+0#0000000&| @33|r+0#00e0e07&|t|r|i|g|a|m@1|a| +0#0000000&@17 +@2|r+0#00e0e07&| |t|e|t|r|a| |g|a|m@1|a|;+0#0000000&| @31|r+0#00e0e07&|t|e|t|r|a|g|a|m@1|a| +0#0000000&@15 +@2|r+0#00e0e07&| |p|e|n|t|a| |g|a|m@1|a|;+0#0000000&| @31|r+0#00e0e07&|p|e|n|t|a|g|a|m@1|a| +0#0000000&@15 +@2|r+0#00e0e07&| |p|s|i| |g|a|m@1|a|;+0#0000000&| @33|r+0#00e0e07&|p|s|i|g|a|m@1|a| +0#0000000&@17 +|#+0#0000e05&| |R| |d|i|s|t|r|i|b|u|t|i|o|n| |r|e|l|a|t|e|d| |f|u|n|c|t|i|o|n|s| |#| +0#0000000&@38 +@2|r+0#00e0e07&| |r| |t|;+0#0000000&| @39|r+0#00e0e07&@1|t| +0#0000000&@23 +@2|r+0#00e0e07&| |r| |c|h|i|s|q|;+0#0000000&| @35|r+0#00e0e07&@1|c|h|i|s|q| +0#0000000&@19 +@57|1|4|9|8|,|0|-|1| @5|7|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_86.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_86.dump new file mode 100644 index 0000000000..d80320472f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_86.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|r+0#00e0e07&| |r| |c|h|i|s|q|;+0#0000000&| @35|r+0#00e0e07&@1|c|h|i|s|q| +0#0000000&@19 +@2|r+0#00e0e07&| |r| |e|x|p|;+0#0000000&| @37|r+0#00e0e07&@1|e|x|p| +0#0000000&@21 +@2|r+0#00e0e07&| |r| |g|e|o|m|;+0#0000000&| @36|r+0#00e0e07&@1|g|e|o|m| +0#0000000&@20 +@2|r+0#00e0e07&| |r| |p|o|i|s|;+0#0000000&| @36|r+0#00e0e07&@1|p|o|i|s| +0#0000000&@20 +@2|r+0#00e0e07&| |r| |s|i|g|n|r|a|n|k|;+0#0000000&| @32|r+0#00e0e07&@1|s|i|g|n|r|a|n|k| +0#0000000&@16 +@2>r+0#00e0e07&| |r| |b|e|t|a|;+0#0000000&| @36|r+0#00e0e07&@1|b|e|t|a| +0#0000000&@20 +@2|r+0#00e0e07&| |r| |b|i|n|o|m|;+0#0000000&| @35|r+0#00e0e07&@1|b|i|n|o|m| +0#0000000&@19 +@2|r+0#00e0e07&| |r| |c|a|u|c|h|y|;+0#0000000&| @34|r+0#00e0e07&@1|c|a|u|c|h|y| +0#0000000&@18 +@2|r+0#00e0e07&| |r| |f|;+0#0000000&| @39|r+0#00e0e07&@1|f| +0#0000000&@23 +@2|r+0#00e0e07&| |r| |l|o|g|i|s|;+0#0000000&| @35|r+0#00e0e07&@1|l|o|g|i|s| +0#0000000&@19 +@2|r+0#00e0e07&| |r| |l|n|o|r|m|;+0#0000000&| @35|r+0#00e0e07&@1|l|n|o|r|m| +0#0000000&@19 +@2|r+0#00e0e07&| |r|n| |b|i|n|o|m|;+0#0000000&| @34|r+0#00e0e07&@1|n|b|i|n|o|m| +0#0000000&@18 +@2|r+0#00e0e07&| |r| |n|o|r|m|;+0#0000000&| @36|r+0#00e0e07&@1|n|o|r|m| +0#0000000&@20 +@2|r+0#00e0e07&| |r| |u|n|i|f|;+0#0000000&| @36|r+0#00e0e07&@1|u|n|i|f| +0#0000000&@20 +@2|r+0#00e0e07&| |r| |w|e|i|b|u|l@1|;+0#0000000&| @33|r+0#00e0e07&@1|w|e|i|b|u|l@1| +0#0000000&@17 +@2|r+0#00e0e07&| |r| |w|i|l|c|o|x|;+0#0000000&| @34|r+0#00e0e07&@1|w|i|l|c|o|x| +0#0000000&@18 +@2|r+0#00e0e07&| |d| |t|;+0#0000000&| @39|r+0#00e0e07&|d|t| +0#0000000&@23 +@2|r+0#00e0e07&| |d| |c|h|i|s|q|;+0#0000000&| @35|r+0#00e0e07&|d|c|h|i|s|q| +0#0000000&@19 +@2|r+0#00e0e07&| |d| |e|x|p|;+0#0000000&| @37|r+0#00e0e07&|d|e|x|p| +0#0000000&@21 +@57|1|5|1|6|,|3| @7|7|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_87.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_87.dump new file mode 100644 index 0000000000..286f75b7b9 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_87.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|r+0#00e0e07&| |d| |e|x|p|;+0#0000000&| @37|r+0#00e0e07&|d|e|x|p| +0#0000000&@21 +@2|r+0#00e0e07&| |d| |g|e|o|m|;+0#0000000&| @36|r+0#00e0e07&|d|g|e|o|m| +0#0000000&@20 +@2|r+0#00e0e07&| |d| |p|o|i|s|;+0#0000000&| @36|r+0#00e0e07&|d|p|o|i|s| +0#0000000&@20 +@2|r+0#00e0e07&| |d| |n|o|r|m|;+0#0000000&| @36|r+0#00e0e07&|d|n|o|r|m| +0#0000000&@20 +@2|r+0#00e0e07&| |d| |b|e|t|a|;+0#0000000&| @36|r+0#00e0e07&|d|b|e|t|a| +0#0000000&@20 +@2>r+0#00e0e07&| |d| |b|i|n|o|m|;+0#0000000&| @35|r+0#00e0e07&|d|b|i|n|o|m| +0#0000000&@19 +@2|r+0#00e0e07&| |d|n| |c|h|i|s|q|;+0#0000000&| @34|r+0#00e0e07&|d|n|c|h|i|s|q| +0#0000000&@18 +@2|r+0#00e0e07&| |d| |c|a|u|c|h|y|;+0#0000000&| @34|r+0#00e0e07&|d|c|a|u|c|h|y| +0#0000000&@18 +@2|r+0#00e0e07&| |d| |f|;+0#0000000&| @39|r+0#00e0e07&|d|f| +0#0000000&@23 +@2|r+0#00e0e07&| |d| |l|o|g|i|s|;+0#0000000&| @35|r+0#00e0e07&|d|l|o|g|i|s| +0#0000000&@19 +@2|r+0#00e0e07&| |d| |l|n|o|r|m|;+0#0000000&| @35|r+0#00e0e07&|d|l|n|o|r|m| +0#0000000&@19 +@2|r+0#00e0e07&| |d|n| |b|i|n|o|m|;+0#0000000&| @34|r+0#00e0e07&|d|n|b|i|n|o|m| +0#0000000&@18 +@2|r+0#00e0e07&| |d| |n|t|;+0#0000000&| @38|r+0#00e0e07&|d|n|t| +0#0000000&@22 +@2|r+0#00e0e07&| |d| |u|n|i|f|;+0#0000000&| @36|r+0#00e0e07&|d|u|n|i|f| +0#0000000&@20 +@2|r+0#00e0e07&| |d| |w|e|i|b|u|l@1|;+0#0000000&| @33|r+0#00e0e07&|d|w|e|i|b|u|l@1| +0#0000000&@17 +@2|r+0#00e0e07&| |d| |n|f|;+0#0000000&| @38|r+0#00e0e07&|d|n|f| +0#0000000&@22 +@2|r+0#00e0e07&| |d| |h|y|p|e|r|;+0#0000000&| @35|r+0#00e0e07&|d|h|y|p|e|r| +0#0000000&@19 +@2|r+0#00e0e07&| |r| |h|y|p|e|r|;+0#0000000&| @35|r+0#00e0e07&@1|h|y|p|e|r| +0#0000000&@19 +@2|r+0#00e0e07&| |p| |t|;+0#0000000&| @39|r+0#00e0e07&|p|t| +0#0000000&@23 +@57|1|5|3|4|,|3| @7|7|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_88.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_88.dump new file mode 100644 index 0000000000..003da31b64 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_88.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|r+0#00e0e07&| |p| |t|;+0#0000000&| @39|r+0#00e0e07&|p|t| +0#0000000&@23 +@2|r+0#00e0e07&| |q| |t|;+0#0000000&| @39|r+0#00e0e07&|q|t| +0#0000000&@23 +@2|r+0#00e0e07&| |p| |c|h|i|s|q|;+0#0000000&| @35|r+0#00e0e07&|p|c|h|i|s|q| +0#0000000&@19 +@2|r+0#00e0e07&| |q| |c|h|i|s|q|;+0#0000000&| @35|r+0#00e0e07&|q|c|h|i|s|q| +0#0000000&@19 +@2|r+0#00e0e07&| |p| |e|x|p|;+0#0000000&| @37|r+0#00e0e07&|p|e|x|p| +0#0000000&@21 +@2>r+0#00e0e07&| |q| |e|x|p|;+0#0000000&| @37|r+0#00e0e07&|q|e|x|p| +0#0000000&@21 +@2|r+0#00e0e07&| |p| |g|e|o|m|;+0#0000000&| @36|r+0#00e0e07&|p|g|e|o|m| +0#0000000&@20 +@2|r+0#00e0e07&| |q| |g|e|o|m|;+0#0000000&| @36|r+0#00e0e07&|q|g|e|o|m| +0#0000000&@20 +@2|r+0#00e0e07&| |p| |p|o|i|s|;+0#0000000&| @36|r+0#00e0e07&|p@1|o|i|s| +0#0000000&@20 +@2|r+0#00e0e07&| |q| |p|o|i|s|;+0#0000000&| @36|r+0#00e0e07&|q|p|o|i|s| +0#0000000&@20 +@2|r+0#00e0e07&| |p| |n|o|r|m|;+0#0000000&| @36|r+0#00e0e07&|p|n|o|r|m| +0#0000000&@20 +@2|r+0#00e0e07&| |q| |n|o|r|m|;+0#0000000&| @36|r+0#00e0e07&|q|n|o|r|m| +0#0000000&@20 +@2|r+0#00e0e07&| |p| |b|e|t|a|;+0#0000000&| @36|r+0#00e0e07&|p|b|e|t|a| +0#0000000&@20 +@2|r+0#00e0e07&| |q| |b|e|t|a|;+0#0000000&| @36|r+0#00e0e07&|q|b|e|t|a| +0#0000000&@20 +@2|r+0#00e0e07&| |p| |b|i|n|o|m|;+0#0000000&| @35|r+0#00e0e07&|p|b|i|n|o|m| +0#0000000&@19 +@2|r+0#00e0e07&| |q| |b|i|n|o|m|;+0#0000000&| @35|r+0#00e0e07&|q|b|i|n|o|m| +0#0000000&@19 +@2|r+0#00e0e07&| |p|n| |c|h|i|s|q|;+0#0000000&| @34|r+0#00e0e07&|p|n|c|h|i|s|q| +0#0000000&@18 +@2|r+0#00e0e07&| |q|n| |c|h|i|s|q|;+0#0000000&| @34|r+0#00e0e07&|q|n|c|h|i|s|q| +0#0000000&@18 +@2|r+0#00e0e07&| |p| |c|a|u|c|h|y|;+0#0000000&| @34|r+0#00e0e07&|p|c|a|u|c|h|y| +0#0000000&@18 +@57|1|5@1|2|,|3| @7|7|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_89.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_89.dump new file mode 100644 index 0000000000..8449603297 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_89.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|r+0#00e0e07&| |p| |c|a|u|c|h|y|;+0#0000000&| @34|r+0#00e0e07&|p|c|a|u|c|h|y| +0#0000000&@18 +@2|r+0#00e0e07&| |q| |c|a|u|c|h|y|;+0#0000000&| @34|r+0#00e0e07&|q|c|a|u|c|h|y| +0#0000000&@18 +@2|r+0#00e0e07&| |p| |f|;+0#0000000&| @39|r+0#00e0e07&|p|f| +0#0000000&@23 +@2|r+0#00e0e07&| |q| |f|;+0#0000000&| @39|r+0#00e0e07&|q|f| +0#0000000&@23 +@2|r+0#00e0e07&| |p| |l|o|g|i|s|;+0#0000000&| @35|r+0#00e0e07&|p|l|o|g|i|s| +0#0000000&@19 +@2>r+0#00e0e07&| |q| |l|o|g|i|s|;+0#0000000&| @35|r+0#00e0e07&|q|l|o|g|i|s| +0#0000000&@19 +@2|r+0#00e0e07&| |p| |l| |n|o|r|m|;+0#0000000&| @34|r+0#00e0e07&|p|l|n|o|r|m| +0#0000000&@19 +@2|r+0#00e0e07&| |q| |l| |n|o|r|m|;+0#0000000&| @34|r+0#00e0e07&|q|l|n|o|r|m| +0#0000000&@19 +@2|r+0#00e0e07&| |p|n| |b|i|n|o|m|;+0#0000000&| @34|r+0#00e0e07&|p|n|b|i|n|o|m| +0#0000000&@18 +@2|r+0#00e0e07&| |q|n| |b|i|n|o|m|;+0#0000000&| @34|r+0#00e0e07&|q|n|b|i|n|o|m| +0#0000000&@18 +@2|r+0#00e0e07&| |p| |n|t|;+0#0000000&| @38|r+0#00e0e07&|p|n|t| +0#0000000&@22 +@2|r+0#00e0e07&| |q| |n|t|;+0#0000000&| @38|r+0#00e0e07&|q|n|t| +0#0000000&@22 +@2|r+0#00e0e07&| |p| |u|n|i|f|;+0#0000000&| @36|r+0#00e0e07&|p|u|n|i|f| +0#0000000&@20 +@2|r+0#00e0e07&| |q| |u|n|i|f|;+0#0000000&| @36|r+0#00e0e07&|q|u|n|i|f| +0#0000000&@20 +@2|r+0#00e0e07&| |p| |w|e|i|b|u|l@1|;+0#0000000&| @33|r+0#00e0e07&|p|w|e|i|b|u|l@1| +0#0000000&@17 +@2|r+0#00e0e07&| |q| |w|e|i|b|u|l@1|;+0#0000000&| @33|r+0#00e0e07&|q|w|e|i|b|u|l@1| +0#0000000&@17 +@2|r+0#00e0e07&| |p| |t|u|k|e|y|;+0#0000000&| @35|r+0#00e0e07&|p|t|u|k|e|y| +0#0000000&@19 +@2|r+0#00e0e07&| |q| |t|u|k|e|y|;+0#0000000&| @35|r+0#00e0e07&|q|t|u|k|e|y| +0#0000000&@19 +@2|r+0#00e0e07&| |p| |n|f|;+0#0000000&| @38|r+0#00e0e07&|p|n|f| +0#0000000&@22 +@57|1|5|7|0|,|3| @7|7|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_90.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_90.dump new file mode 100644 index 0000000000..885763d829 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_90.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|r+0#00e0e07&| |p| |n|f|;+0#0000000&| @38|r+0#00e0e07&|p|n|f| +0#0000000&@22 +@2|r+0#00e0e07&| |q| |n|f|;+0#0000000&| @38|r+0#00e0e07&|q|n|f| +0#0000000&@22 +@2|r+0#00e0e07&| |p| |h|y|p|e|r|;+0#0000000&| @35|r+0#00e0e07&|p|h|y|p|e|r| +0#0000000&@19 +@2|r+0#00e0e07&| |q| |h|y|p|e|r|;+0#0000000&| @35|r+0#00e0e07&|q|h|y|p|e|r| +0#0000000&@19 +@2|r+0#00e0e07&| |d| |s|i|g|n| |r|a|n|k|;+0#0000000&| @31|r+0#00e0e07&|d|s|i|g|n|r|a|n|k| +0#0000000&@16 +@2>r+0#00e0e07&| |d| |w|i|l|c|o|x|;+0#0000000&| @34|r+0#00e0e07&|d|w|i|l|c|o|x| +0#0000000&@18 +@2|r+0#00e0e07&| |p| |s|i|g|n| |r|a|n|k|;+0#0000000&| @31|r+0#00e0e07&|p|s|i|g|n|r|a|n|k| +0#0000000&@16 +@2|r+0#00e0e07&| |q| |s|i|g|n| |r|a|n|k|;+0#0000000&| @31|r+0#00e0e07&|q|s|i|g|n|r|a|n|k| +0#0000000&@16 +@2|r+0#00e0e07&| |p| |w|i|l|c|o|x|;+0#0000000&| @34|r+0#00e0e07&|p|w|i|l|c|o|x| +0#0000000&@18 +@2|r+0#00e0e07&| |q| |w|i|l|c|o|x|;+0#0000000&| @34|r+0#00e0e07&|q|w|i|l|c|o|x| +0#0000000&@18 +@75 +|#+0#0000e05&|:@12| +0#0000000&@60 +|p+0#0000e05&|r|e|l|u|d|e|-|g|s|l|.|c| +0#0000000&@61 +|:+0#0000e05&@12|#| +0#0000000&@60 +@75 +|#+0#0000e05&| |S|t|a|n|d|a|r|d| |p|r|e|l|u|d|e| |d|e|f|i|n|i|t|i|o|n|s| |f|r|o|m| |G|S|L|.| |#| +0#0000000&@32 +@2|a+0#00e0e07&|i|r|y| |a|i|;+0#0000000&| @37|a+0#00e0e07&|i|r|y|a|i| +0#0000000&@20 +@2|a+0#00e0e07&|i|r|y| |a|i| |s|c|a|l|e|d|;+0#0000000&| @30|a+0#00e0e07&|i|r|y|a|i|s|c|a|l|e|d| +0#0000000&@14 +@2|a+0#00e0e07&|i|r|y| |b|i|;+0#0000000&| @37|a+0#00e0e07&|i|r|y|b|i| +0#0000000&@20 +@57|1|5|8@1|,|3| @7|7|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_91.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_91.dump new file mode 100644 index 0000000000..cb310a5f60 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_91.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|a+0#00e0e07&|i|r|y| |b|i|;+0#0000000&| @37|a+0#00e0e07&|i|r|y|b|i| +0#0000000&@20 +@2|a+0#00e0e07&|i|r|y| |b|i| |s|c|a|l|e|d|;+0#0000000&| @30|a+0#00e0e07&|i|r|y|b|i|s|c|a|l|e|d| +0#0000000&@14 +@2|b+0#00e0e07&|e|s@1|e|l| |i|n|0|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|i|n|0| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |i|n|1|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|i|n|1| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |i|n|0| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|i|n|0|s|c|a|l|e|d| +0#0000000&@11 +@2>b+0#00e0e07&|e|s@1|e|l| |i|n|1| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|i|n|1|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |j|n|0|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|j|n|0| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |j|n|1|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|j|n|1| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|0|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|k|n|0| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|1|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|k|n|1| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|0| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|k|n|0|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|1| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|k|n|1|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |y|n|0|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|y|n|0| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |y|n|1|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|y|n|1| +0#0000000&@17 +@2|e+0#00e0e07&|x|p|i|n|t|e|1|;+0#0000000&| @36|e+0#00e0e07&|x|p|i|n|t|e|1| +0#0000000&@18 +@2|e+0#00e0e07&|x|p|i|n|t|e|i|;+0#0000000&| @36|e+0#00e0e07&|x|p|i|n|t|e|i| +0#0000000&@18 +@2|d+0#00e0e07&|a|w|s|o|n|;+0#0000000&| @38|d+0#00e0e07&|a|w|s|o|n| +0#0000000&@20 +@2|e+0#00e0e07&|x|p|r|e|l|;+0#0000000&| @38|e+0#00e0e07&|x|p|r|e|l| +0#0000000&@20 +@2|b+0#00e0e07&|e|t|a| |i|n|c| |g|s|l|;+0#0000000&| @32|b+0#00e0e07&|e|t|a|i|n|c|g|s|l| +0#0000000&@16 +@57|1|6|0|6|,|3| @7|7|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_92.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_92.dump new file mode 100644 index 0000000000..6ac506289c --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_92.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|b+0#00e0e07&|e|t|a| |i|n|c| |g|s|l|;+0#0000000&| @32|b+0#00e0e07&|e|t|a|i|n|c|g|s|l| +0#0000000&@16 +@2|p+0#00e0e07&|o|c|h|;+0#0000000&| @40|p+0#00e0e07&|o|c|h| +0#0000000&@22 +@2|d+0#00e0e07&|i|g|a|m@1|a|;+0#0000000&| @37|d+0#00e0e07&|i|g|a|m@1|a| +0#0000000&@19 +@2|a+0#00e0e07&|i|r|y| |a|i| |d|e|r|i|v|a|t|i|v|e|;+0#0000000&| @26|a+0#00e0e07&|i|r|y|a|i|d|e|r|i|v|a|t|i|v|e| +0#0000000&@10 +@2|a+0#00e0e07&|i|r|y| |a|i| |d|e|r|i|v|;+0#0000000&| @31|a+0#00e0e07&|i|r|y|a|i|d|e|r|i|v| +0#0000000&@15 +@2>a+0#00e0e07&|i|r|y| |a|i| |d|e|r|i|v| |s|c|a|l|e|d|;+0#0000000&| @24|a+0#00e0e07&|i|r|y|a|i|d|e|r|i|v|s|c|a|l|e|d| +0#0000000&@9 +@2|a+0#00e0e07&|i|r|y| |b|i| |d|e|r|i|v|a|t|i|v|e|;+0#0000000&| @26|a+0#00e0e07&|i|r|y|b|i|d|e|r|i|v|a|t|i|v|e| +0#0000000&@10 +@2|a+0#00e0e07&|i|r|y| |b|i| |d|e|r|i|v|;+0#0000000&| @31|a+0#00e0e07&|i|r|y|b|i|d|e|r|i|v| +0#0000000&@15 +@2|a+0#00e0e07&|i|r|y| |b|i| |d|e|r|i|v| |s|c|a|l|e|d|;+0#0000000&| @24|a+0#00e0e07&|i|r|y|b|i|d|e|r|i|v|s|c|a|l|e|d| +0#0000000&@9 +@2|a+0#00e0e07&|i|r|y| |z|e|r|o| |a|i| |d|e|r|i|v|;+0#0000000&| @26|a+0#00e0e07&|i|r|y|z|e|r|o|a|i|d|e|r|i|v| +0#0000000&@11 +@2|a+0#00e0e07&|i|r|y| |z|e|r|o| |a|i|;+0#0000000&| @32|a+0#00e0e07&|i|r|y|z|e|r|o|a|i| +0#0000000&@16 +@2|a+0#00e0e07&|i|r|y| |z|e|r|o| |b|i| |d|e|r|i|v|;+0#0000000&| @26|a+0#00e0e07&|i|r|y|z|e|r|o|b|i|d|e|r|i|v| +0#0000000&@11 +@2|a+0#00e0e07&|i|r|y| |z|e|r|o| |b|i|;+0#0000000&| @32|a+0#00e0e07&|i|r|y|z|e|r|o|b|i| +0#0000000&@16 +@2|a+0#00e0e07&|n|g|l|e| |r|e|s|t|r|i|c|t| |p|o|s|;+0#0000000&| @26|a+0#00e0e07&|n|g|l|e|r|e|s|t|r|i|c|t|p|o|s| +0#0000000&@10 +@2|a+0#00e0e07&|n|g|l|e| |r|e|s|t|r|i|c|t| |s|y|m@1|;+0#0000000&| @25|a+0#00e0e07&|n|g|l|e|r|e|s|t|r|i|c|t|s|y|m@1| +0#0000000&@9 +@2|a+0#00e0e07&|t|a|n| |i|n|t|;+0#0000000&| @36|a+0#00e0e07&|t|a|n|i|n|t| +0#0000000&@19 +@2|b+0#00e0e07&|e|s@1|e|l| |i|l|0| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|i|l|0|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |i|l|1| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|i|l|1|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |i|l|2| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|i|l|2|s|c|a|l|e|d| +0#0000000&@11 +@57|1|6|2|4|,|3| @7|7@1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_93.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_93.dump new file mode 100644 index 0000000000..c6208fcdbe --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_93.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|b+0#00e0e07&|e|s@1|e|l| |i|l|2| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|i|l|2|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |i|l| |s|c|a|l|e|d|;+0#0000000&| @28|b+0#00e0e07&|e|s@1|e|l|i|l|s|c|a|l|e|d| +0#0000000&@12 +@2|b+0#00e0e07&|e|s@1|e|l| |i|n|;+0#0000000&| @35|b+0#00e0e07&|e|s@1|e|l|i|n| +0#0000000&@18 +@2|b+0#00e0e07&|e|s@1|e|l| |i|n| |s|c|a|l|e|d|;+0#0000000&| @28|b+0#00e0e07&|e|s@1|e|l|i|n|s|c|a|l|e|d| +0#0000000&@12 +@2|b+0#00e0e07&|e|s@1|e|l| |i|n|u|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|i|n|u| +0#0000000&@17 +@2>b+0#00e0e07&|e|s@1|e|l| |i|n|u| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|i|n|u|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |j|l|0|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|j|l|0| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |j|l|1|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|j|l|1| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |j|l|2|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|j|l|2| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |j|l|;+0#0000000&| @35|b+0#00e0e07&|e|s@1|e|l|j|l| +0#0000000&@18 +@2|b+0#00e0e07&|e|s@1|e|l| |j|n|;+0#0000000&| @35|b+0#00e0e07&|e|s@1|e|l|j|n| +0#0000000&@18 +@2|b+0#00e0e07&|e|s@1|e|l| |k|l|0| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|k|l|0|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |k|l|1| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|k|l|1|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |k|l|2| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|k|l|2|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |k|l| |s|c|a|l|e|d|;+0#0000000&| @28|b+0#00e0e07&|e|s@1|e|l|k|l|s|c|a|l|e|d| +0#0000000&@12 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|;+0#0000000&| @35|b+0#00e0e07&|e|s@1|e|l|k|n| +0#0000000&@18 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n| |s|c|a|l|e|d|;+0#0000000&| @28|b+0#00e0e07&|e|s@1|e|l|k|n|s|c|a|l|e|d| +0#0000000&@12 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|_|s|c|a|l|e|d|;+0#0000000&| @28|b+0#00e0e07&|e|s@1|e|l|k|n|_|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|u|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|k|n|u| +0#0000000&@17 +@57|1|6|4|2|,|3| @7|7|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_94.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_94.dump new file mode 100644 index 0000000000..58684097b8 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_94.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|b+0#00e0e07&|e|s@1|e|l| |k|n|u|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|k|n|u| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |k|n|u| |s|c|a|l|e|d|;+0#0000000&| @27|b+0#00e0e07&|e|s@1|e|l|k|n|u|s|c|a|l|e|d| +0#0000000&@11 +@2|b+0#00e0e07&|e|s@1|e|l| |l|n| |k|n|u|;+0#0000000&| @31|b+0#00e0e07&|e|s@1|e|l@1|n|k|n|u| +0#0000000&@15 +@2|b+0#00e0e07&|e|s@1|e|l| |y|l|0|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|y|l|0| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |y|l|1|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|y|l|1| +0#0000000&@17 +@2>b+0#00e0e07&|e|s@1|e|l| |y|l|2|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|y|l|2| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |y|l|;+0#0000000&| @35|b+0#00e0e07&|e|s@1|e|l|y|l| +0#0000000&@18 +@2|b+0#00e0e07&|e|s@1|e|l| |y|n|;+0#0000000&| @35|b+0#00e0e07&|e|s@1|e|l|y|n| +0#0000000&@18 +@2|b+0#00e0e07&|e|s@1|e|l| |y|n|u|;+0#0000000&| @34|b+0#00e0e07&|e|s@1|e|l|y|n|u| +0#0000000&@17 +@2|b+0#00e0e07&|e|s@1|e|l| |z|e|r|o| |j|0|;+0#0000000&| @30|b+0#00e0e07&|e|s@1|e|l|z|e|r|o|j|0| +0#0000000&@14 +@2|b+0#00e0e07&|e|s@1|e|l| |z|e|r|o| |j|1|;+0#0000000&| @30|b+0#00e0e07&|e|s@1|e|l|z|e|r|o|j|1| +0#0000000&@14 +@2|b+0#00e0e07&|e|s@1|e|l| |z|e|r|o| |j|n|u|;+0#0000000&| @29|b+0#00e0e07&|e|s@1|e|l|z|e|r|o|j|n|u| +0#0000000&@13 +@2|c+0#00e0e07&|h|i|;+0#0000000&| @41|c+0#00e0e07&|h|i| +0#0000000&@23 +@2|c+0#00e0e07&|i|;+0#0000000&| @42|c+0#00e0e07&|i| +0#0000000&@24 +@2|c+0#00e0e07&|l|a|u|s|e|n|;+0#0000000&| @37|c+0#00e0e07&|l|a|u|s|e|n| +0#0000000&@19 +@2|c+0#00e0e07&|o|n|i|c|a|l| |p|0|;+0#0000000&| @34|c+0#00e0e07&|o|n|i|c|a|l|p|0| +0#0000000&@17 +@2|c+0#00e0e07&|o|n|i|c|a|l| |p|1|;+0#0000000&| @34|c+0#00e0e07&|o|n|i|c|a|l|p|1| +0#0000000&@17 +@2|c+0#00e0e07&|o|n|i|c|a|l| |p|c|y|l|r|e|g|;+0#0000000&| @29|c+0#00e0e07&|o|n|i|c|a|l|p|c|y|l|r|e|g| +0#0000000&@12 +@2|c+0#00e0e07&|o|n|i|c|a|l| |p|h|a|l|f|;+0#0000000&| @31|c+0#00e0e07&|o|n|i|c|a|l|p|h|a|l|f| +0#0000000&@14 +@57|1|6@1|0|,|3| @7|7|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_95.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_95.dump new file mode 100644 index 0000000000..6aa96a487b --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_95.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|c+0#00e0e07&|o|n|i|c|a|l| |p|h|a|l|f|;+0#0000000&| @31|c+0#00e0e07&|o|n|i|c|a|l|p|h|a|l|f| +0#0000000&@14 +@2|c+0#00e0e07&|o|n|i|c|a|l| |p|m|h|a|l|f|;+0#0000000&| @30|c+0#00e0e07&|o|n|i|c|a|l|p|m|h|a|l|f| +0#0000000&@13 +@2|c+0#00e0e07&|o|n|i|c|a|l| |p|s|p|h|r|e|g|;+0#0000000&| @29|c+0#00e0e07&|o|n|i|c|a|l|p|s|p|h|r|e|g| +0#0000000&@12 +@2|d+0#00e0e07&|e|b|y|e| |1|;+0#0000000&| @37|d+0#00e0e07&|e|b|y|e|1| +0#0000000&@20 +@2|d+0#00e0e07&|e|b|y|e| |2|;+0#0000000&| @37|d+0#00e0e07&|e|b|y|e|2| +0#0000000&@20 +@2>d+0#00e0e07&|e|b|y|e| |3|;+0#0000000&| @37|d+0#00e0e07&|e|b|y|e|3| +0#0000000&@20 +@2|d+0#00e0e07&|e|b|y|e| |4|;+0#0000000&| @37|d+0#00e0e07&|e|b|y|e|4| +0#0000000&@20 +@2|d+0#00e0e07&|e|b|y|e| |5|;+0#0000000&| @37|d+0#00e0e07&|e|b|y|e|5| +0#0000000&@20 +@2|d+0#00e0e07&|e|b|y|e| |6|;+0#0000000&| @37|d+0#00e0e07&|e|b|y|e|6| +0#0000000&@20 +@2|d+0#00e0e07&|i|l|o|g|;+0#0000000&| @39|d+0#00e0e07&|i|l|o|g| +0#0000000&@21 +@2|d+0#00e0e07&|o|u|b|l|e|f|a|c|t|;+0#0000000&| @34|d+0#00e0e07&|o|u|b|l|e|f|a|c|t| +0#0000000&@16 +@2|e+0#00e0e07&|l@1|i|n|t| |d|;+0#0000000&| @36|e+0#00e0e07&|l@1|i|n|t|d| +0#0000000&@19 +@2|e+0#00e0e07&|l@1|i|n|t| |e|c|o|m|p|;+0#0000000&| @32|e+0#00e0e07&|l@1|i|n|t|e|c|o|m|p| +0#0000000&@15 +@2|e+0#00e0e07&|l@1|i|n|t| |e|;+0#0000000&| @36|e+0#00e0e07&|l@1|i|n|t|e| +0#0000000&@19 +@2|e+0#00e0e07&|l@1|i|n|t| |f|;+0#0000000&| @36|e+0#00e0e07&|l@1|i|n|t|f| +0#0000000&@19 +@2|e+0#00e0e07&|l@1|i|n|t| |k|c|o|m|p|;+0#0000000&| @32|e+0#00e0e07&|l@1|i|n|t|k|c|o|m|p| +0#0000000&@15 +@2|e+0#00e0e07&|l@1|i|n|t| |p|c|o|m|p|;+0#0000000&| @32|e+0#00e0e07&|l@1|i|n|t|p|c|o|m|p| +0#0000000&@15 +@2|e+0#00e0e07&|l@1|i|n|t| |p|;+0#0000000&| @36|e+0#00e0e07&|l@1|i|n|t|p| +0#0000000&@19 +@2|e+0#00e0e07&|l@1|i|n|t| |r|c|;+0#0000000&| @35|e+0#00e0e07&|l@1|i|n|t|r|c| +0#0000000&@18 +@57|1|6|7|8|,|3| @7|7|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_96.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_96.dump new file mode 100644 index 0000000000..1508414d61 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_96.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|e+0#00e0e07&|l@1|i|n|t| |r|c|;+0#0000000&| @35|e+0#00e0e07&|l@1|i|n|t|r|c| +0#0000000&@18 +@2|e+0#00e0e07&|l@1|i|n|t| |r|d|;+0#0000000&| @35|e+0#00e0e07&|l@1|i|n|t|r|d| +0#0000000&@18 +@2|e+0#00e0e07&|l@1|i|n|t| |r|f|;+0#0000000&| @35|e+0#00e0e07&|l@1|i|n|t|r|f| +0#0000000&@18 +@2|e+0#00e0e07&|l@1|i|n|t| |r|j|;+0#0000000&| @35|e+0#00e0e07&|l@1|i|n|t|r|j| +0#0000000&@18 +@2|e+0#00e0e07&|t|a|i|n|t|;+0#0000000&| @38|e+0#00e0e07&|t|a|i|n|t| +0#0000000&@20 +@2>e+0#00e0e07&|t|a|;+0#0000000&| @41|e+0#00e0e07&|t|a| +0#0000000&@23 +@2|e+0#00e0e07&|x|p|i|n|t| |3|;+0#0000000&| @36|e+0#00e0e07&|x|p|i|n|t|3| +0#0000000&@19 +@2|e+0#00e0e07&|x|p|i|n|t| |e|2|;+0#0000000&| @35|e+0#00e0e07&|x|p|i|n|t|e|2| +0#0000000&@18 +@2|e+0#00e0e07&|x|p|i|n|t| |e|n|;+0#0000000&| @35|e+0#00e0e07&|x|p|i|n|t|e|n| +0#0000000&@18 +@2|e+0#00e0e07&|x|p|m|1|;+0#0000000&| @39|e+0#00e0e07&|x|p|m|1| +0#0000000&@21 +@2|e+0#00e0e07&|x|p|r|e|l|2|;+0#0000000&| @37|e+0#00e0e07&|x|p|r|e|l|2| +0#0000000&@19 +@2|e+0#00e0e07&|x|p|r|e|l|n|;+0#0000000&| @37|e+0#00e0e07&|x|p|r|e|l|n| +0#0000000&@19 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |0|;+0#0000000&| @31|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|0| +0#0000000&@15 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |1|;+0#0000000&| @31|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|1| +0#0000000&@15 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |2|;+0#0000000&| @31|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|2| +0#0000000&@15 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |3|h|a|l|f|;+0#0000000&| @27|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|3|h|a|l|f| +0#0000000&@11 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |h|a|l|f|;+0#0000000&| @28|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|h|a|l|f| +0#0000000&@12 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |i|n|c|0|;+0#0000000&| @28|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|i|n|c|0| +0#0000000&@12 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |i|n|t|;+0#0000000&| @29|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|i|n|t| +0#0000000&@13 +@57|1|6|9|6|,|3| @7|8|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_97.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_97.dump new file mode 100644 index 0000000000..ebd0d93b16 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_97.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |i|n|t|;+0#0000000&| @29|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|i|n|t| +0#0000000&@13 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |m|1|;+0#0000000&| @30|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|m|1| +0#0000000&@14 +@2|f+0#00e0e07&|e|r|m|i| |d|i|r|a|c| |m|h|a|l|f|;+0#0000000&| @27|f+0#00e0e07&|e|r|m|i|d|i|r|a|c|m|h|a|l|f| +0#0000000&@11 +@2|g+0#00e0e07&|a|m@1|a| |i|n|c| |g|s|l|;+0#0000000&| @31|g+0#00e0e07&|a|m@1|a|i|n|c|g|s|l| +0#0000000&@15 +@2|g+0#00e0e07&|a|m@1|a| |i|n|c| |p|;+0#0000000&| @33|g+0#00e0e07&|a|m@1|a|i|n|c|p| +0#0000000&@17 +@2>g+0#00e0e07&|a|m@1|a| |i|n|c| |q|;+0#0000000&| @33|g+0#00e0e07&|a|m@1|a|i|n|c|q| +0#0000000&@17 +@2|g+0#00e0e07&|a|m@1|a| |i|n|v|;+0#0000000&| @35|g+0#00e0e07&|a|m@1|a|i|n|v| +0#0000000&@18 +@2|g+0#00e0e07&|a|m@1|a| |s|t|a|r|;+0#0000000&| @34|g+0#00e0e07&|a|m@1|a|s|t|a|r| +0#0000000&@17 +@2|g+0#00e0e07&|e|g|e|n|p|o|l|y| |1| |r|e|a|l|;+0#0000000&| @28|g+0#00e0e07&|e|g|e|n|p|o|l|y|1|r|e|a|l| +0#0000000&@12 +@2|g+0#00e0e07&|e|g|e|n|p|o|l|y| |2| |r|e|a|l|;+0#0000000&| @28|g+0#00e0e07&|e|g|e|n|p|o|l|y|2|r|e|a|l| +0#0000000&@12 +@2|g+0#00e0e07&|e|g|e|n|p|o|l|y| |3| |r|e|a|l|;+0#0000000&| @28|g+0#00e0e07&|e|g|e|n|p|o|l|y|3|r|e|a|l| +0#0000000&@12 +@2|g+0#00e0e07&|e|g|e|n|p|o|l|y| |n| |r|e|a|l|;+0#0000000&| @28|g+0#00e0e07&|e|g|e|n|p|o|l|y|n|r|e|a|l| +0#0000000&@12 +@2|h+0#00e0e07&|e|r|m|i|t|e| |f|u|n|c|;+0#0000000&| @32|h+0#00e0e07&|e|r|m|i|t|e|f|u|n|c| +0#0000000&@15 +@2|h+0#00e0e07&|y|p|o|t|;+0#0000000&| @39|h+0#00e0e07&|y|p|o|t| +0#0000000&@21 +@2|h+0#00e0e07&|z|e|t|a|;+0#0000000&| @39|h+0#00e0e07&|z|e|t|a| +0#0000000&@21 +@2|l+0#00e0e07&|a|g|u|e|r@1|e| |1| |r|e|a|l|;+0#0000000&| @29|l+0#00e0e07&|a|g|u|e|r@1|e|1|r|e|a|l| +0#0000000&@13 +@2|l+0#00e0e07&|a|g|u|e|r@1|e| |2| |r|e|a|l|;+0#0000000&| @29|l+0#00e0e07&|a|g|u|e|r@1|e|2|r|e|a|l| +0#0000000&@13 +@2|l+0#00e0e07&|a|g|u|e|r@1|e| |3| |r|e|a|l|;+0#0000000&| @29|l+0#00e0e07&|a|g|u|e|r@1|e|3|r|e|a|l| +0#0000000&@13 +@2|l+0#00e0e07&|a|g|u|e|r@1|e| |n| |r|e|a|l|;+0#0000000&| @29|l+0#00e0e07&|a|g|u|e|r@1|e|n|r|e|a|l| +0#0000000&@13 +@57|1|7|1|4|,|3| @7|8|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_98.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_98.dump new file mode 100644 index 0000000000..bab62eb934 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_98.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|a|g|u|e|r@1|e| |n| |r|e|a|l|;+0#0000000&| @29|l+0#00e0e07&|a|g|u|e|r@1|e|n|r|e|a|l| +0#0000000&@13 +@2|l+0#00e0e07&|a|m|b|e|r|t| |w|0|;+0#0000000&| @34|l+0#00e0e07&|a|m|b|e|r|t|w|0| +0#0000000&@17 +@2|l+0#00e0e07&|a|m|b|e|r|t| |w|m|1|;+0#0000000&| @33|l+0#00e0e07&|a|m|b|e|r|t|w|m|1| +0#0000000&@16 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |h|3|d|0|;+0#0000000&| @31|l+0#00e0e07&|e|g|e|n|d|r|e|h|3|d|0| +0#0000000&@14 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |h|3|d|1|;+0#0000000&| @31|l+0#00e0e07&|e|g|e|n|d|r|e|h|3|d|1| +0#0000000&@14 +@2>l+0#00e0e07&|e|g|e|n|d|r|e| |h|3|d|;+0#0000000&| @32|l+0#00e0e07&|e|g|e|n|d|r|e|h|3|d| +0#0000000&@15 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |p|1|;+0#0000000&| @33|l+0#00e0e07&|e|g|e|n|d|r|e|p|1| +0#0000000&@16 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |p|2|;+0#0000000&| @33|l+0#00e0e07&|e|g|e|n|d|r|e|p|2| +0#0000000&@16 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |p|3|;+0#0000000&| @33|l+0#00e0e07&|e|g|e|n|d|r|e|p|3| +0#0000000&@16 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |p|l|;+0#0000000&| @33|l+0#00e0e07&|e|g|e|n|d|r|e|p|l| +0#0000000&@16 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |q|0|;+0#0000000&| @33|l+0#00e0e07&|e|g|e|n|d|r|e|q|0| +0#0000000&@16 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |q|1|;+0#0000000&| @33|l+0#00e0e07&|e|g|e|n|d|r|e|q|1| +0#0000000&@16 +@2|l+0#00e0e07&|e|g|e|n|d|r|e| |q|l|;+0#0000000&| @33|l+0#00e0e07&|e|g|e|n|d|r|e|q|l| +0#0000000&@16 +@2|l+0#00e0e07&|n| |c|o|s|h|;+0#0000000&| @37|l+0#00e0e07&|n|c|o|s|h| +0#0000000&@20 +@2|l+0#00e0e07&|n| |d|o|u|b|l|e|f|a|c|t|;+0#0000000&| @31|l+0#00e0e07&|n|d|o|u|b|l|e|f|a|c|t| +0#0000000&@14 +@2|l+0#00e0e07&|n| |p|o|c|h|;+0#0000000&| @37|l+0#00e0e07&|n|p|o|c|h| +0#0000000&@20 +@2|l+0#00e0e07&|n| |s|i|n|h|;+0#0000000&| @37|l+0#00e0e07&|n|s|i|n|h| +0#0000000&@20 +@2|l+0#00e0e07&|n|1| |p|l|u|s|x|m|x|;+0#0000000&| @33|l+0#00e0e07&|n|1|p|l|u|s|x|m|x| +0#0000000&@16 +@2|l+0#00e0e07&|n|1| |p|l|u|s|x|;+0#0000000&| @35|l+0#00e0e07&|n|1|p|l|u|s|x| +0#0000000&@18 +@57|1|7|3|2|,|3| @7|8|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_all_preludes_99.dump b/runtime/syntax/testdir/dumps/algol68_all_preludes_99.dump new file mode 100644 index 0000000000..69bd54b749 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_all_preludes_99.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@1|l+0#00e0e07&|n|1| |p|l|u|s|x|;+0#0000000&| @35|l+0#00e0e07&|n|1|p|l|u|s|x| +0#0000000&@18 +@2|l+0#00e0e07&|n| |a|b|s|;+0#0000000&| @38|l+0#00e0e07&|n|a|b|s| +0#0000000&@21 +@2|p+0#00e0e07&|o|c|h| |r|e|l|;+0#0000000&| @36|p+0#00e0e07&|o|c|h|r|e|l| +0#0000000&@19 +@2|p+0#00e0e07&|s|i| |1| |i|n|t|;+0#0000000&| @35|p+0#00e0e07&|s|i|1|i|n|t| +0#0000000&@19 +@2|p+0#00e0e07&|s|i| |1| |p|i|y|;+0#0000000&| @35|p+0#00e0e07&|s|i|1|p|i|y| +0#0000000&@19 +@2>p+0#00e0e07&|s|i| |1|;+0#0000000&| @39|p+0#00e0e07&|s|i|1| +0#0000000&@22 +@2|p+0#00e0e07&|s|i| |i|n|t|;+0#0000000&| @37|p+0#00e0e07&|s|i@1|n|t| +0#0000000&@20 +@2|p+0#00e0e07&|s|i|n|;+0#0000000&| @40|p+0#00e0e07&|s|i|n| +0#0000000&@22 +@2|p+0#00e0e07&|s|i|;+0#0000000&| @41|p+0#00e0e07&|s|i| +0#0000000&@23 +@2|s+0#00e0e07&|h|i|;+0#0000000&| @41|s+0#00e0e07&|h|i| +0#0000000&@23 +@2|s+0#00e0e07&|i|n|c|;+0#0000000&| @40|s+0#00e0e07&|i|n|c| +0#0000000&@22 +@2|s+0#00e0e07&|i|;+0#0000000&| @42|s+0#00e0e07&|i| +0#0000000&@24 +@2|s+0#00e0e07&|y|n|c|h|r|o|t|r|o|n| |1|;+0#0000000&| @31|s+0#00e0e07&|y|n|c|h|r|o|t|r|o|n|1| +0#0000000&@14 +@2|s+0#00e0e07&|y|n|c|h|r|o|t|r|o|n| |2|;+0#0000000&| @31|s+0#00e0e07&|y|n|c|h|r|o|t|r|o|n|2| +0#0000000&@14 +@2|t+0#00e0e07&|a|y|l|o|r| |c|o|e|f@1|;+0#0000000&| @32|t+0#00e0e07&|a|y|l|o|r|c|o|e|f@1| +0#0000000&@15 +@2|t+0#00e0e07&|r|a|n|s|p|o|r|t| |2|;+0#0000000&| @33|t+0#00e0e07&|r|a|n|s|p|o|r|t|2| +0#0000000&@16 +@2|t+0#00e0e07&|r|a|n|s|p|o|r|t| |3|;+0#0000000&| @33|t+0#00e0e07&|r|a|n|s|p|o|r|t|3| +0#0000000&@16 +@2|t+0#00e0e07&|r|a|n|s|p|o|r|t| |4|;+0#0000000&| @33|t+0#00e0e07&|r|a|n|s|p|o|r|t|4| +0#0000000&@16 +@2|t+0#00e0e07&|r|a|n|s|p|o|r|t| |5|;+0#0000000&| @33|t+0#00e0e07&|r|a|n|s|p|o|r|t|5| +0#0000000&@16 +@57|1|7|5|0|,|3| @7|8|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_denotations_00.dump b/runtime/syntax/testdir/dumps/algol68_denotations_00.dump new file mode 100644 index 0000000000..55331838a5 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_denotations_00.dump @@ -0,0 +1,20 @@ +>#+0#0000e05#ffffff0| +0#0000000&@73 +| +0#0000e05&@3|A|l|g|o|l| |6|8| |D|e|n|o|t|a|t|i|o|n|s| +0#0000000&@50 +|#+0#0000e05&| +0#0000000&@73 +@75 +@75 +|#+0#0000e05&| |B|O@1|L| |#| +0#0000000&@66 +@75 +|B+0#00e0003&|O@1|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|T+0#e000002&|R|U|E| +0#0000000&@61 +|B+0#00e0003&|O@1|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|F+0#e000002&|A|L|S|E| +0#0000000&@60 +@75 +@75 +|#+0#0000e05&| |I|N|T| |#| +0#0000000&@67 +@75 +|I+0#00e0003&|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|0+0#e000002&| +0#0000000&@65 +|I+0#00e0003&|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2| +0#0000000&@64 +@75 +|#+0#0000e05&| |w|h|i|t|e|s|p|a|c|e| |#| +0#0000000&@60 +|I+0#00e0003&|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|1+0#e000002&| |0@2| |0@2| +0#0000000&@57 +@75 +@57|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/algol68_denotations_01.dump b/runtime/syntax/testdir/dumps/algol68_denotations_01.dump new file mode 100644 index 0000000000..a265b14050 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_denotations_01.dump @@ -0,0 +1,20 @@ +|I+0#00e0003#ffffff0|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|0+0#e000002&| +0#0000000&@65 +|I+0#00e0003&|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2| +0#0000000&@64 +@75 +|#+0#0000e05&| |w|h|i|t|e|s|p|a|c|e| |#| +0#0000000&@60 +|I+0#00e0003&|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|1+0#e000002&| |0@2| |0@2| +0#0000000&@57 +> @74 +|#+0#0000e05&| |m|o|n|a|d|i|c| |o|p|e|r|a|t|o|r|s| |#| +0#0000000&@53 +|I+0#00e0003&|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|-+0#af5f00255&|4+0#e000002&|2| +0#0000000&@63 +|I+0#00e0003&|N|T| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|++0#af5f00255&|4+0#e000002&|2| +0#0000000&@63 +@75 +@75 +|#+0#0000e05&| |R|E|A|L| |#| +0#0000000&@66 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2| +0#0000000&@62 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2| +0#0000000&@60 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|e|4|2| +0#0000000&@60 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|E|4|2| +0#0000000&@60 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|\|4|2| +0#0000000&@60 +@57|1|9|,|0|-|1| @7|1|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_denotations_02.dump b/runtime/syntax/testdir/dumps/algol68_denotations_02.dump new file mode 100644 index 0000000000..15f03772d3 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_denotations_02.dump @@ -0,0 +1,20 @@ +|R+0#00e0003#ffffff0|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|\|4|2| +0#0000000&@60 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|⏨|4|2| +0#0000000&@60 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|e|-|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|E|-|4|2| +0#0000000&@59 +>R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|\|-|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|⏨|-|4|2| +0#0000000&@59 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|e|+|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|E|+|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|\|+|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|⏨|+|4|2| +0#0000000&@59 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|e|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|E|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|\|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|⏨|4|2| +0#0000000&@59 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|e|-|4|2| +0#0000000&@58 +@57|3|7|,|1| @9|3|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_denotations_03.dump b/runtime/syntax/testdir/dumps/algol68_denotations_03.dump new file mode 100644 index 0000000000..37eb216d2b --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_denotations_03.dump @@ -0,0 +1,20 @@ +|R+0#00e0003#ffffff0|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|e|-|4|2| +0#0000000&@58 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|E|-|4|2| +0#0000000&@58 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|\|-|4|2| +0#0000000&@58 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|⏨|-|4|2| +0#0000000&@58 +@75 +>R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|e|+|4|2| +0#0000000&@58 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|E|+|4|2| +0#0000000&@58 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|\|+|4|2| +0#0000000&@58 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|.+0#e000002&|4|2|⏨|+|4|2| +0#0000000&@58 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|e|4|2| +0#0000000&@57 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|E|4|2| +0#0000000&@57 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|\|4|2| +0#0000000&@57 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|⏨|4|2| +0#0000000&@57 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|e|-|4|2| +0#0000000&@56 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|E|-|4|2| +0#0000000&@56 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|\|-|4|2| +0#0000000&@56 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|⏨|-|4|2| +0#0000000&@56 +@57|5@1|,|1| @9|5|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_denotations_04.dump b/runtime/syntax/testdir/dumps/algol68_denotations_04.dump new file mode 100644 index 0000000000..6b62493585 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_denotations_04.dump @@ -0,0 +1,20 @@ +|R+0#00e0003#ffffff0|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|⏨|-|4|2| +0#0000000&@56 +@75 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|e|+|4|2| +0#0000000&@56 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|E|+|4|2| +0#0000000&@56 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|\|+|4|2| +0#0000000&@56 +>R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|2|.|4|2|⏨|+|4|2| +0#0000000&@56 +@75 +|#+0#0000e05&| |w|h|i|t|e|s|p|a|c|e| |#| +0#0000000&@60 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&| |2| |.| |4| |2| |e| |+| |4| |2| +0#0000000&@48 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&| |2| |.| |4| |2| |\| |+| |4| |2| +0#0000000&@48 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&| |2| |.| |4| |2| |⏨| |+| |4| |2| +0#0000000&@48 +@75 +|#+0#0000e05&| |m|o|n|a|d|i|c| |o|p|e|r|a|t|o|r|s| |#| +0#0000000&@53 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|-+0#af5f00255&|4+0#e000002&|2|.|4|2| +0#0000000&@59 +|R+0#00e0003&|E|A|L| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|++0#af5f00255&|4+0#e000002&|2|.|4|2| +0#0000000&@59 +@75 +@75 +|#+0#0000e05&| |B|I|T|S| |#| +0#0000000&@66 +@75 +@57|7|3|,|1| @9|6|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_denotations_05.dump b/runtime/syntax/testdir/dumps/algol68_denotations_05.dump new file mode 100644 index 0000000000..ff50200250 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_denotations_05.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@74 +|B+0#00e0003&|I|T|S| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|2+0#e000002&|r|1|0|1|0|1|0| +0#0000000&@57 +|B+0#00e0003&|I|T|S| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|4+0#e000002&|r|2@2| +0#0000000&@60 +|B+0#00e0003&|I|T|S| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|8+0#e000002&|r|5|2| +0#0000000&@61 +|B+0#00e0003&|I|T|S| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|6|r|2|a| +0#0000000&@60 +> @74 +|#+0#0000e05&| |w|h|i|t|e|s|p|a|c|e| |#| +0#0000000&@60 +|B+0#00e0003&|I|T|S| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|2+0#e000002&|r| |1|0|1|0| |1|0|1|0| +0#0000000&@53 +@75 +|#+0#0000e05&| |u|n|m|a|t|c|h|e|d| |b|y| |b|a|d| |p|a|t@1|e|r|n| |i|n| |l|e|g|a|c|y| |v|e|r|s|i|o|n|s| |o|f| |s|y|n|t|a|x| |f|i|l|e| |#| +0#0000000&@12 +|B+0#00e0003&|I|T|S| +0#0000000&|x| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|6|r|9@1| +0#0000000&@60 +@75 +@75 +|#+0#0000e05&| |S|T|R|I|N|G| |#| +0#0000000&@64 +@75 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|F|o@1| |B|a|r|"| +0#0000000&@54 +@75 +|#+0#0000e05&| |q|u|o|t|e| |e|s|c|a|p|e| |#| +0#0000000&@58 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|"+0#e000e06&@1|"+0#e000002&| +0#0000000&@59 +@57|9|1|,|0|-|1| @7|8|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_denotations_06.dump b/runtime/syntax/testdir/dumps/algol68_denotations_06.dump new file mode 100644 index 0000000000..7b30e05a50 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_denotations_06.dump @@ -0,0 +1,20 @@ +|S+0#00e0003#ffffff0|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|"+0#e000e06&@1|"+0#e000002&| +0#0000000&@59 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&| |"+0#e000e06&@1| +0#e000002&|"| +0#0000000&@57 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|F|o@1|"+0#e000e06&@1|"+0#e000002&| +0#0000000&@56 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|"+0#e000e06&@1|B+0#e000002&|a|r|"| +0#0000000&@56 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|F|o@1|"+0#e000e06&@1|B+0#e000002&|a|r|"| +0#0000000&@53 +> @74 +|#+0#0000e05&| |l|i|n|e| |c|o|n|t|i|n|u|a|t|i|o|n| |#| +0#0000000&@53 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|F|o@1|\+0#e000e06&| +0#0000000&@58 +| +0#e000002&|B|a|r|"| +0#0000000&@69 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|F|o@1|"+0#e000e06&@1|\| +0#0000000&@56 +|B+0#e000002&|a|r|"| +0#0000000&@70 +|S+0#00e0003&|T|R|I|N|G| +0#0000000&|s| |=+0#af5f00255&| +0#0000000&|"+0#e000002&|F|o@1|\+0#e000e06&| +0#0000000&@58 +|"+0#e000e06&@1|B+0#e000002&|a|r|"| +0#0000000&@68 +@75 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|1|0|9|,|0|-|1| @6|B|o|t| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_00.dump b/runtime/syntax/testdir/dumps/algol68_operators_00.dump new file mode 100644 index 0000000000..ada4e90321 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_00.dump @@ -0,0 +1,20 @@ +>#+0#0000e05#ffffff0| +0#0000000&@73 +| +0#0000e05&@3|A|l|g|o|l| |6|8| |O|p|e|r|a|t|o|r|s| +0#0000000&@52 +|#+0#0000e05&| +0#0000000&@73 +@75 +@75 +|#+0#0000e05&|:@24| +0#0000000&@48 +|P+0#0000e05&|r|e|l|u|d|e| |S|y|m|b|o|l|i|c| |O|p|e|r|a|t|o|r|s| +0#0000000&@48 +|:+0#0000e05&@24|#| +0#0000000&@48 +@75 +@75 +|#+0#0000e05&| |I|D|E|N|T|I|T|Y| |#| +0#0000000&@62 +@75 +|x| |:+0#af5f00255&|=|:| +0#0000000&@1|y| @66 +|x| |:+0#af5f00255&|/|=|:| +0#0000000&|y| @66 +@75 +|#+0#0000e05&| |B|O@1|L| |#| +0#0000000&@66 +@75 +|~+0#af5f00255&|T+0#e000002&|R|U|E| +0#0000000&@69 +|T+0#e000002&|R|U|E| +0#0000000&|&+0#af5f00255&| +0#0000000&|F+0#e000002&|A|L|S|E| +0#0000000&@62 +@57|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_01.dump b/runtime/syntax/testdir/dumps/algol68_operators_01.dump new file mode 100644 index 0000000000..454ee00233 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_01.dump @@ -0,0 +1,20 @@ +|x+0&#ffffff0| |:+0#af5f00255&|/|=|:| +0#0000000&|y| @66 +@75 +|#+0#0000e05&| |B|O@1|L| |#| +0#0000000&@66 +@75 +|~+0#af5f00255&|T+0#e000002&|R|U|E| +0#0000000&@69 +>T+0#e000002&|R|U|E| +0#0000000&|&+0#af5f00255&| +0#0000000&|F+0#e000002&|A|L|S|E| +0#0000000&@62 +|T+0#e000002&|R|U|E| +0#0000000&|=+0#af5f00255&| +0#0000000&|F+0#e000002&|A|L|S|E| +0#0000000&@62 +|T+0#e000002&|R|U|E| +0#0000000&|/+0#af5f00255&|=| +0#0000000&|F+0#e000002&|A|L|S|E| +0#0000000&@61 +@75 +|#+0#0000e05&| |I|N|T| |#| +0#0000000&@67 +@75 +|++0#af5f00255&|4+0#e000002&|2| +0#0000000&@71 +|-+0#af5f00255&|4+0#e000002&|2| +0#0000000&@71 +@75 +|4+0#e000002&|2| +0#0000000&|++0#af5f00255&|*| +0#0000000&|8+0#e000002&|7| +0#0000000&@66 +@75 +|4+0#e000002&|2| +0#0000000&|++0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|-+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|*+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +@57|1|9|,|1| @10|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_02.dump b/runtime/syntax/testdir/dumps/algol68_operators_02.dump new file mode 100644 index 0000000000..fd6b5e6ddf --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_02.dump @@ -0,0 +1,20 @@ +|4+0#e000002#ffffff0|2| +0#0000000&|*+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|%+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|%+0#af5f00255&|*| +0#0000000&|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|/+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|*+0#af5f00255&@1| +0#0000000&|8+0#e000002&|7| +0#0000000&@66 +>4+0#e000002&|2| +0#0000000&|^+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +@75 +|i| |++0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +|i| |-+0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +|i| |*+0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +|i| |%+0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +|i| |%+0#af5f00255&|*|:|=| +0#0000000&|4+0#e000002&|2| +0#0000000&@65 +@75 +|4+0#e000002&|2| +0#0000000&|=+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|/+0#af5f00255&|=| +0#0000000&|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|<+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|<+0#af5f00255&|=| +0#0000000&|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|>+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@66 +|4+0#e000002&|2| +0#0000000&|>+0#af5f00255&|=| +0#0000000&|8+0#e000002&|7| +0#0000000&@66 +@57|3|7|,|1| @10|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_03.dump b/runtime/syntax/testdir/dumps/algol68_operators_03.dump new file mode 100644 index 0000000000..9fd9ff691b --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_03.dump @@ -0,0 +1,20 @@ +|4+0#e000002#ffffff0|2| +0#0000000&|>+0#af5f00255&|=| +0#0000000&|8+0#e000002&|7| +0#0000000&@66 +@75 +|#+0#0000e05&| |R|E|A|L| |#| +0#0000000&@66 +@75 +|++0#af5f00255&|4+0#e000002&|.|2| +0#0000000&@70 +>-+0#af5f00255&|4+0#e000002&|.|2| +0#0000000&@70 +@75 +|4+0#e000002&|.|2| +0#0000000&|++0#af5f00255&|*| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@64 +@75 +|4+0#e000002&|.|2| +0#0000000&|++0#af5f00255&| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@65 +|4+0#e000002&|.|2| +0#0000000&|-+0#af5f00255&| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@65 +|4+0#e000002&|.|2| +0#0000000&|*+0#af5f00255&| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@65 +|4+0#e000002&|.|2| +0#0000000&|/+0#af5f00255&| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@65 +@75 +|4+0#e000002&|.|2| +0#0000000&|*+0#af5f00255&@1| +0#0000000&|8+0#e000002&|7| +0#0000000&@65 +|4+0#e000002&|.|2| +0#0000000&|^+0#af5f00255&| +0#0000000&@1|8+0#e000002&|7| +0#0000000&@65 +@75 +|r| |++0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +|r| |-+0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +@57|5@1|,|1| @10|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_04.dump b/runtime/syntax/testdir/dumps/algol68_operators_04.dump new file mode 100644 index 0000000000..bb78b6673a --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_04.dump @@ -0,0 +1,20 @@ +|r+0&#ffffff0| |-+0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +|r| |*+0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +|r| |/+0#af5f00255&|:|=| +0#0000000&@1|4+0#e000002&|2| +0#0000000&@65 +@75 +|4+0#e000002&|.|2| +0#0000000&|=+0#af5f00255&| +0#0000000&@1|8+0#e000002&|.|7| +0#0000000&@64 +>4+0#e000002&|.|2| +0#0000000&|/+0#af5f00255&|=| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@64 +|4+0#e000002&|.|2| +0#0000000&|<+0#af5f00255&| +0#0000000&@1|8+0#e000002&|.|7| +0#0000000&@64 +|4+0#e000002&|.|2| +0#0000000&|<+0#af5f00255&|=| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@64 +|4+0#e000002&|.|2| +0#0000000&|>+0#af5f00255&| +0#0000000&@1|8+0#e000002&|.|7| +0#0000000&@64 +|4+0#e000002&|.|2| +0#0000000&|>+0#af5f00255&|=| +0#0000000&|8+0#e000002&|.|7| +0#0000000&@64 +@75 +|#+0#0000e05&| |C|H|A|R| |#| +0#0000000&@66 +@75 +|"+0#e000002&|a|"| +0#0000000&|=+0#af5f00255&| +0#0000000&@1|"+0#e000002&|b|"| +0#0000000&@64 +|"+0#e000002&|a|"| +0#0000000&|/+0#af5f00255&|=| +0#0000000&|"+0#e000002&|b|"| +0#0000000&@64 +|"+0#e000002&|a|"| +0#0000000&|<+0#af5f00255&| +0#0000000&@1|"+0#e000002&|b|"| +0#0000000&@64 +|"+0#e000002&|a|"| +0#0000000&|<+0#af5f00255&|=| +0#0000000&|"+0#e000002&|b|"| +0#0000000&@64 +|"+0#e000002&|a|"| +0#0000000&|>+0#af5f00255&| +0#0000000&@1|"+0#e000002&|b|"| +0#0000000&@64 +|"+0#e000002&|a|"| +0#0000000&|>+0#af5f00255&|=| +0#0000000&|"+0#e000002&|b|"| +0#0000000&@64 +@57|7|3|,|1| @10|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_05.dump b/runtime/syntax/testdir/dumps/algol68_operators_05.dump new file mode 100644 index 0000000000..f5dd278e91 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_05.dump @@ -0,0 +1,20 @@ +|"+0#e000002#ffffff0|a|"| +0#0000000&|>+0#af5f00255&|=| +0#0000000&|"+0#e000002&|b|"| +0#0000000&@64 +@75 +|#+0#0000e05&| |S|T|R|I|N|G| |#| +0#0000000&@64 +@75 +|"+0#e000002&|a@2|"| +0#0000000&|=+0#af5f00255&| +0#0000000&@1|"+0#e000002&|b@2|"| +0#0000000&@60 +>"+0#e000002&|a@2|"| +0#0000000&|/+0#af5f00255&|=| +0#0000000&|"+0#e000002&|b@2|"| +0#0000000&@60 +|"+0#e000002&|a@2|"| +0#0000000&|<+0#af5f00255&| +0#0000000&@1|"+0#e000002&|b@2|"| +0#0000000&@60 +|"+0#e000002&|a@2|"| +0#0000000&|<+0#af5f00255&|=| +0#0000000&|"+0#e000002&|b@2|"| +0#0000000&@60 +|"+0#e000002&|a@2|"| +0#0000000&|>+0#af5f00255&| +0#0000000&@1|"+0#e000002&|b@2|"| +0#0000000&@60 +|"+0#e000002&|a@2|"| +0#0000000&|>+0#af5f00255&|=| +0#0000000&|"+0#e000002&|b@2|"| +0#0000000&@60 +@75 +|"+0#e000002&|a@2|"| +0#0000000&|++0#af5f00255&| +0#0000000&|"+0#e000002&|b@2|"| +0#0000000&@61 +|"+0#e000002&|a@2|"| +0#0000000&|++0#af5f00255&| +0#0000000&|"+0#e000002&|b|"| +0#0000000&@63 +@3|4+0#e000002&|2| +0#0000000&|*+0#af5f00255&| +0#0000000&|"+0#e000002&|a@2|"| +0#0000000&@61 +|"+0#e000002&|a@2|"| +0#0000000&|*+0#af5f00255&| +0#0000000&|4+0#e000002&|2| +0#0000000&@64 +@75 +@4|s| |++0#af5f00255&|:|=| +0#0000000&|"+0#e000002&|a@2|"| +0#0000000&@59 +|"+0#e000002&|a@2|"| +0#0000000&|++0#af5f00255&|=|:| +0#0000000&|s| @63 +@4|s| |*+0#af5f00255&|:|=| +0#0000000&|5+0#e000002&| +0#0000000&@63 +@57|9|1|,|1| @10|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_06.dump b/runtime/syntax/testdir/dumps/algol68_operators_06.dump new file mode 100644 index 0000000000..743b45ec81 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_06.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@3|s| |*+0#af5f00255&|:|=| +0#0000000&|5+0#e000002&| +0#0000000&@63 +@75 +@75 +|#+0#0000e05&|:@16| +0#0000000&@56 +|S+0#0000e05&|y|m|b|o|l|i|c| |O|p|e|r|a|t|o|r|s| +0#0000000&@56 +>:+0#0000e05&@16|#| +0#0000000&@56 +@75 +@75 +|#+0#0000e05&| |M|o|n|a|d|i|c| |#| +0#0000000&@63 +@75 +|#+0#0000e05&| |m|o|n|a|d| |#| +0#0000000&@65 +@75 +|!| @73 +|%+0#af5f00255&| +0#0000000&@73 +|&+0#af5f00255&| +0#0000000&@73 +|++0#af5f00255&| +0#0000000&@73 +|-+0#af5f00255&| +0#0000000&@73 +|?| @73 +|^+0#af5f00255&| +0#0000000&@73 +@57|1|0|9|,|1| @8|1|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_07.dump b/runtime/syntax/testdir/dumps/algol68_operators_07.dump new file mode 100644 index 0000000000..87cdc7eaf5 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_07.dump @@ -0,0 +1,20 @@ +|^+0#af5f00255#ffffff0| +0#0000000&@73 +|~+0#af5f00255&| +0#0000000&@73 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@56 +@75 +>!|:|=| @71 +|%+0#af5f00255&|:|=| +0#0000000&@71 +|&|:|=| @71 +|++0#af5f00255&|:|=| +0#0000000&@71 +|-+0#af5f00255&|:|=| +0#0000000&@71 +|?|:|=| @71 +|^|:|=| @71 +|~|:|=| @71 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@53 +@75 +|!|=|:| @71 +|%|=|:| @71 +|&|=|:| @71 +@57|1|2|7|,|1| @8|1|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_08.dump b/runtime/syntax/testdir/dumps/algol68_operators_08.dump new file mode 100644 index 0000000000..228551dd8f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_08.dump @@ -0,0 +1,20 @@ +|&+0&#ffffff0|=|:| @71 +|++0#af5f00255&|=|:| +0#0000000&@71 +|-|=|:| @71 +|?|=|:| @71 +|^+0#af5f00255&|=|:+0#0000000&| @71 +>~+0#af5f00255&|=|:+0#0000000&| @71 +@75 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d| |#| +0#0000000&@58 +@75 +|!|*| @72 +|!|/| @72 +|!|<| @72 +|!|=| @72 +|!|>| @72 +|%+0#af5f00255&|*| +0#0000000&@72 +|%|/| @72 +|%|<| @72 +|%|=| @72 +@57|1|4|5|,|1| @8|1|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_09.dump b/runtime/syntax/testdir/dumps/algol68_operators_09.dump new file mode 100644 index 0000000000..8dcc813d81 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_09.dump @@ -0,0 +1,20 @@ +|%+0&#ffffff0|=| @72 +|%|>| @72 +|&|*| @72 +|&|/| @72 +|&|<| @72 +>&|=| @72 +|&|>| @72 +|++0#af5f00255&|*| +0#0000000&@72 +|+|/| @72 +|+|<| @72 +|+|=| @72 +|+|>| @72 +|-|*| @72 +|-|/| @72 +|-|<| @72 +|-|=| @72 +|-|>| @72 +|?|*| @72 +|?|/| @72 +@57|1|6|3|,|1| @8|1|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_10.dump b/runtime/syntax/testdir/dumps/algol68_operators_10.dump new file mode 100644 index 0000000000..80e8367591 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_10.dump @@ -0,0 +1,20 @@ +|?+0&#ffffff0|/| @72 +|?|<| @72 +|?|=| @72 +|?|>| @72 +|^|*| @72 +>^|/| @72 +|^|<| @72 +|^+0#af5f00255&|=| +0#0000000&@72 +|^|>| @72 +|~|*| @72 +|~|/| @72 +|~|<| @72 +|~+0#af5f00255&|=| +0#0000000&@72 +|~|>| @72 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@49 +@75 +|!|*|:|=| @70 +|!|/|:|=| @70 +@57|1|8|1|,|1| @8|1|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_11.dump b/runtime/syntax/testdir/dumps/algol68_operators_11.dump new file mode 100644 index 0000000000..7aaa4e2829 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_11.dump @@ -0,0 +1,20 @@ +|!+0&#ffffff0|/|:|=| @70 +|!|<|:|=| @70 +|!|=|:|=| @70 +|!|>|:|=| @70 +|%+0#af5f00255&|*|:|=| +0#0000000&@70 +>%|/|:|=| @70 +|%|<|:|=| @70 +|%|=|:|=| @70 +|%|>|:|=| @70 +|&|*|:|=| @70 +|&|/|:|=| @70 +|&|<|:|=| @70 +|&|=|:|=| @70 +|&|>|:|=| @70 +|+|*|:|=| @70 +|+|/|:|=| @70 +|+|<|:|=| @70 +|+|=|:|=| @70 +|+|>|:|=| @70 +@57|1|9@1|,|1| @8|1|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_12.dump b/runtime/syntax/testdir/dumps/algol68_operators_12.dump new file mode 100644 index 0000000000..04f9cf67ac --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_12.dump @@ -0,0 +1,20 @@ +|++0&#ffffff0|>|:|=| @70 +|-|*|:|=| @70 +|-|/|:|=| @70 +|-|<|:|=| @70 +|-|=|:|=| @70 +>-|>|:|=| @70 +|?|*|:|=| @70 +|?|/|:|=| @70 +|?|<|:|=| @70 +|?|=|:|=| @70 +|?|>|:|=| @70 +|^|*|:|=| @70 +|^|/|:|=| @70 +|^|<|:|=| @70 +|^|=|:|=| @70 +|^|>|:|=| @70 +|~|*|:|=| @70 +|~|/|:|=| @70 +|~|<|:|=| @70 +@57|2|1|7|,|1| @8|2|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_13.dump b/runtime/syntax/testdir/dumps/algol68_operators_13.dump new file mode 100644 index 0000000000..1ad237b754 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_13.dump @@ -0,0 +1,20 @@ +|~+0&#ffffff0|<|:|=| @70 +|~|=|:|=| @70 +|~|>|:|=| @70 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@46 +> @74 +|!|*|=|:| @70 +|!|/|=|:| @70 +|!|<|=|:| @70 +|!|=@1|:| @70 +|!|>|=|:| @70 +|%|*|=|:| @70 +|%|/|=|:| @70 +|%|<|=|:| @70 +|%|=@1|:| @70 +|%|>|=|:| @70 +|&|*|=|:| @70 +|&|/|=|:| @70 +|&|<|=|:| @70 +@57|2|3|5|,|0|-|1| @6|2|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_14.dump b/runtime/syntax/testdir/dumps/algol68_operators_14.dump new file mode 100644 index 0000000000..7e910f241d --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_14.dump @@ -0,0 +1,20 @@ +|&+0&#ffffff0|<|=|:| @70 +|&|=@1|:| @70 +|&|>|=|:| @70 +|+|*|=|:| @70 +|+|/|=|:| @70 +>+|<|=|:| @70 +|+|=@1|:| @70 +|+|>|=|:| @70 +|-|*|=|:| @70 +|-|/|=|:| @70 +|-|<|=|:| @70 +|-|=@1|:| @70 +|-|>|=|:| @70 +|?|*|=|:| @70 +|?|/|=|:| @70 +|?|<|=|:| @70 +|?|=@1|:| @70 +|?|>|=|:| @70 +|^|*|=|:| @70 +@57|2|5|3|,|1| @8|2|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_15.dump b/runtime/syntax/testdir/dumps/algol68_operators_15.dump new file mode 100644 index 0000000000..388653d547 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_15.dump @@ -0,0 +1,20 @@ +|^+0&#ffffff0|*|=|:| @70 +|^|/|=|:| @70 +|^|<|=|:| @70 +|^|=@1|:| @70 +|^|>|=|:| @70 +>~|*|=|:| @70 +|~|/|=|:| @70 +|~|<|=|:| @70 +|~|=@1|:| @70 +|~|>|=|:| @70 +@75 +@75 +|#+0#0000e05&| |D|y|a|d|i|c| |#| +0#0000000&@64 +@75 +|#+0#0000e05&| |m|o|n|a|d| |#| +0#0000000&@65 +@75 +|!| @73 +|%+0#af5f00255&| +0#0000000&@73 +|&+0#af5f00255&| +0#0000000&@73 +@57|2|7|1|,|1| @8|2|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_16.dump b/runtime/syntax/testdir/dumps/algol68_operators_16.dump new file mode 100644 index 0000000000..2973b4d3c5 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_16.dump @@ -0,0 +1,20 @@ +|&+0#af5f00255#ffffff0| +0#0000000&@73 +|++0#af5f00255&| +0#0000000&@73 +|-+0#af5f00255&| +0#0000000&@73 +|?| @73 +|^+0#af5f00255&| +0#0000000&@73 +>~+0#af5f00255&| +0#0000000&@73 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@56 +@75 +|!|:|=| @71 +|%+0#af5f00255&|:|=| +0#0000000&@71 +|&|:|=| @71 +|++0#af5f00255&|:|=| +0#0000000&@71 +|-+0#af5f00255&|:|=| +0#0000000&@71 +|?|:|=| @71 +|^|:|=| @71 +|~|:|=| @71 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@53 +@57|2|8|9|,|1| @8|2|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_17.dump b/runtime/syntax/testdir/dumps/algol68_operators_17.dump new file mode 100644 index 0000000000..fd46be4aba --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_17.dump @@ -0,0 +1,20 @@ +|#+0#0000e05#ffffff0| |m|o|n|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@53 +@75 +|!|=|:| @71 +|%|=|:| @71 +|&|=|:| @71 +>++0#af5f00255&|=|:| +0#0000000&@71 +|-|=|:| @71 +|?|=|:| @71 +|^+0#af5f00255&|=|:+0#0000000&| @71 +|~+0#af5f00255&|=|:+0#0000000&| @71 +@75 +@75 +|#+0#0000e05&| |n|o|m|a|d| |#| +0#0000000&@65 +@75 +|*+0#af5f00255&| +0#0000000&@73 +|/+0#af5f00255&| +0#0000000&@73 +|<+0#af5f00255&| +0#0000000&@73 +|=+0#af5f00255&| +0#0000000&@73 +|>+0#af5f00255&| +0#0000000&@73 +@57|3|0|7|,|1| @8|3|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_18.dump b/runtime/syntax/testdir/dumps/algol68_operators_18.dump new file mode 100644 index 0000000000..9849f44df1 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_18.dump @@ -0,0 +1,20 @@ +|>+0#af5f00255#ffffff0| +0#0000000&@73 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@56 +@75 +|*+0#af5f00255&|:|=| +0#0000000&@71 +>/+0#af5f00255&|:|=| +0#0000000&@71 +|<|:|=| @71 +|=|:|=| @71 +|>|:|=| @71 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@53 +@75 +|*|=|:| @71 +|/|=|:| @71 +|<|=|:| @71 +|=@1|:| @71 +|>|=|:| @71 +@75 +@75 +@57|3|2|5|,|1| @8|3|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_19.dump b/runtime/syntax/testdir/dumps/algol68_operators_19.dump new file mode 100644 index 0000000000..1d3b4f809f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_19.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@74 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d| |#| +0#0000000&@58 +@75 +|!|*| @72 +|!|/| @72 +>!|<| @72 +|!|=| @72 +|!|>| @72 +|%+0#af5f00255&|*| +0#0000000&@72 +|%|/| @72 +|%|<| @72 +|%|=| @72 +|%|>| @72 +|&|*| @72 +|&|/| @72 +|&|<| @72 +|&|=| @72 +|&|>| @72 +|++0#af5f00255&|*| +0#0000000&@72 +@57|3|4|3|,|1| @8|3|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_20.dump b/runtime/syntax/testdir/dumps/algol68_operators_20.dump new file mode 100644 index 0000000000..e614a0760f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_20.dump @@ -0,0 +1,20 @@ +|++0#af5f00255#ffffff0|*| +0#0000000&@72 +|+|/| @72 +|+|<| @72 +|+|=| @72 +|+|>| @72 +>-|*| @72 +|-|/| @72 +|-|<| @72 +|-|=| @72 +|-|>| @72 +|?|*| @72 +|?|/| @72 +|?|<| @72 +|?|=| @72 +|?|>| @72 +|^|*| @72 +|^|/| @72 +|^|<| @72 +|^+0#af5f00255&|=| +0#0000000&@72 +@57|3|6|1|,|1| @8|3|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_21.dump b/runtime/syntax/testdir/dumps/algol68_operators_21.dump new file mode 100644 index 0000000000..600ed9dd4b --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_21.dump @@ -0,0 +1,20 @@ +|^+0#af5f00255#ffffff0|=| +0#0000000&@72 +|^|>| @72 +|~|*| @72 +|~|/| @72 +|~|<| @72 +>~+0#af5f00255&|=| +0#0000000&@72 +|~|>| @72 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@49 +@75 +|!|*|:|=| @70 +|!|/|:|=| @70 +|!|<|:|=| @70 +|!|=|:|=| @70 +|!|>|:|=| @70 +|%+0#af5f00255&|*|:|=| +0#0000000&@70 +|%|/|:|=| @70 +|%|<|:|=| @70 +|%|=|:|=| @70 +@57|3|7|9|,|1| @8|3|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_22.dump b/runtime/syntax/testdir/dumps/algol68_operators_22.dump new file mode 100644 index 0000000000..f351924ac2 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_22.dump @@ -0,0 +1,20 @@ +|%+0&#ffffff0|=|:|=| @70 +|%|>|:|=| @70 +|&|*|:|=| @70 +|&|/|:|=| @70 +|&|<|:|=| @70 +>&|=|:|=| @70 +|&|>|:|=| @70 +|+|*|:|=| @70 +|+|/|:|=| @70 +|+|<|:|=| @70 +|+|=|:|=| @70 +|+|>|:|=| @70 +|-|*|:|=| @70 +|-|/|:|=| @70 +|-|<|:|=| @70 +|-|=|:|=| @70 +|-|>|:|=| @70 +|?|*|:|=| @70 +|?|/|:|=| @70 +@57|3|9|7|,|1| @8|3|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_23.dump b/runtime/syntax/testdir/dumps/algol68_operators_23.dump new file mode 100644 index 0000000000..d353bc22e3 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_23.dump @@ -0,0 +1,20 @@ +|?+0&#ffffff0|/|:|=| @70 +|?|<|:|=| @70 +|?|=|:|=| @70 +|?|>|:|=| @70 +|^|*|:|=| @70 +>^|/|:|=| @70 +|^|<|:|=| @70 +|^|=|:|=| @70 +|^|>|:|=| @70 +|~|*|:|=| @70 +|~|/|:|=| @70 +|~|<|:|=| @70 +|~|=|:|=| @70 +|~|>|:|=| @70 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@46 +@75 +|!|*|=|:| @70 +|!|/|=|:| @70 +@57|4|1|5|,|1| @8|4|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_24.dump b/runtime/syntax/testdir/dumps/algol68_operators_24.dump new file mode 100644 index 0000000000..2ce8a38ccb --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_24.dump @@ -0,0 +1,20 @@ +|!+0&#ffffff0|/|=|:| @70 +|!|<|=|:| @70 +|!|=@1|:| @70 +|!|>|=|:| @70 +|%|*|=|:| @70 +>%|/|=|:| @70 +|%|<|=|:| @70 +|%|=@1|:| @70 +|%|>|=|:| @70 +|&|*|=|:| @70 +|&|/|=|:| @70 +|&|<|=|:| @70 +|&|=@1|:| @70 +|&|>|=|:| @70 +|+|*|=|:| @70 +|+|/|=|:| @70 +|+|<|=|:| @70 +|+|=@1|:| @70 +|+|>|=|:| @70 +@57|4|3@1|,|1| @8|4|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_25.dump b/runtime/syntax/testdir/dumps/algol68_operators_25.dump new file mode 100644 index 0000000000..a4b8646913 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_25.dump @@ -0,0 +1,20 @@ +|++0&#ffffff0|>|=|:| @70 +|-|*|=|:| @70 +|-|/|=|:| @70 +|-|<|=|:| @70 +|-|=@1|:| @70 +>-|>|=|:| @70 +|?|*|=|:| @70 +|?|/|=|:| @70 +|?|<|=|:| @70 +|?|=@1|:| @70 +|?|>|=|:| @70 +|^|*|=|:| @70 +|^|/|=|:| @70 +|^|<|=|:| @70 +|^|=@1|:| @70 +|^|>|=|:| @70 +|~|*|=|:| @70 +|~|/|=|:| @70 +|~|<|=|:| @70 +@57|4|5|1|,|1| @8|4|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_26.dump b/runtime/syntax/testdir/dumps/algol68_operators_26.dump new file mode 100644 index 0000000000..68d0741e2c --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_26.dump @@ -0,0 +1,20 @@ +|~+0&#ffffff0|<|=|:| @70 +|~|=@1|:| @70 +|~|>|=|:| @70 +@75 +@75 +>#+0#0000e05&| |n|o|m|a|d|,| |n|o|m|a|d| |#| +0#0000000&@58 +@75 +|*+0#af5f00255&@1| +0#0000000&@72 +|*|/| @72 +|*|<| @72 +|*|=| @72 +|*|>| @72 +|/|*| @72 +|/@1| @72 +|/|<| @72 +|/+0#af5f00255&|=| +0#0000000&@72 +|/|>| @72 +|<|*| @72 +|<|/| @72 +@57|4|6|9|,|1| @8|4|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_27.dump b/runtime/syntax/testdir/dumps/algol68_operators_27.dump new file mode 100644 index 0000000000..061bd17dd2 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_27.dump @@ -0,0 +1,20 @@ +|<+0&#ffffff0|/| @72 +|<@1| @72 +|<+0#af5f00255&|=| +0#0000000&@72 +|<|>| @72 +|=|*| @72 +>=|/| @72 +|=|<| @72 +|=@1| @72 +|=|>| @72 +|>|*| @72 +|>|/| @72 +|>|<| @72 +|>+0#af5f00255&|=| +0#0000000&@72 +|>@1| @72 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@49 +@75 +|*@1|:|=| @70 +|*|/|:|=| @70 +@57|4|8|7|,|1| @8|4|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_28.dump b/runtime/syntax/testdir/dumps/algol68_operators_28.dump new file mode 100644 index 0000000000..edaa688014 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_28.dump @@ -0,0 +1,20 @@ +|*+0&#ffffff0|/|:|=| @70 +|*|<|:|=| @70 +|*|=|:|=| @70 +|*|>|:|=| @70 +|/|*|:|=| @70 +>/@1|:|=| @70 +|/|<|:|=| @70 +|/|=|:|=| @70 +|/|>|:|=| @70 +|<|*|:|=| @70 +|<|/|:|=| @70 +|<@1|:|=| @70 +|<|=|:|=| @70 +|<|>|:|=| @70 +|=|*|:|=| @70 +|=|/|:|=| @70 +|=|<|:|=| @70 +|=@1|:|=| @70 +|=|>|:|=| @70 +@57|5|0|5|,|1| @8|5|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_29.dump b/runtime/syntax/testdir/dumps/algol68_operators_29.dump new file mode 100644 index 0000000000..fac15e117c --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_29.dump @@ -0,0 +1,20 @@ +|=+0&#ffffff0|>|:|=| @70 +|>|*|:|=| @70 +|>|/|:|=| @70 +|>|<|:|=| @70 +|>|=|:|=| @70 +>>@1|:|=| @70 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@46 +@75 +|*@1|=|:| @70 +|*|/|=|:| @70 +|*|<|=|:| @70 +|*|=@1|:| @70 +|*|>|=|:| @70 +|/|*|=|:| @70 +|/@1|=|:| @70 +|/|<|=|:| @70 +|/|=@1|:| @70 +|/|>|=|:| @70 +@57|5|2|3|,|1| @8|5|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_30.dump b/runtime/syntax/testdir/dumps/algol68_operators_30.dump new file mode 100644 index 0000000000..ce64ae4e66 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_30.dump @@ -0,0 +1,20 @@ +|/+0&#ffffff0|>|=|:| @70 +|<|*|=|:| @70 +|<|/|=|:| @70 +|<@1|=|:| @70 +|<|=@1|:| @70 +><|>|=|:| @70 +|=|*|=|:| @70 +|=|/|=|:| @70 +|=|<|=|:| @70 +|=@2|:| @70 +|=|>|=|:| @70 +|>|*|=|:| @70 +|>|/|=|:| @70 +|>|<|=|:| @70 +|>|=@1|:| @70 +|>@1|=|:| @70 +@75 +@75 +|#+0#0000e05&|:@12| +0#0000000&@60 +@57|5|4|1|,|1| @8|5|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_31.dump b/runtime/syntax/testdir/dumps/algol68_operators_31.dump new file mode 100644 index 0000000000..2dff68eb03 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_31.dump @@ -0,0 +1,20 @@ +|#+0#0000e05#ffffff0|:@12| +0#0000000&@60 +|S+0#0000e05&|y|m|b|o|l|i|c| |O|p|e|r|a|t|o|r| |D|e|c|l|a|r|a|t|i|o|n|s| +0#0000000&@44 +|:+0#0000e05&@12|#| +0#0000000&@60 +@75 +@75 +>#+0#0000e05&| |M|o|n|a|d|i|c| |#| +0#0000000&@63 +@75 +@75 +|#+0#0000e05&| |m|o|n|a|d| |#| +0#0000000&@65 +@75 +|O+0#af5f00255&|P| +0#0000000&|!| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +|O+0#af5f00255&|P| +0#0000000&|%| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +|O+0#af5f00255&|P| +0#0000000&|&| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +|O+0#af5f00255&|P| +0#0000000&|+| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +|O+0#af5f00255&|P| +0#0000000&|-| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +|O+0#af5f00255&|P| +0#0000000&|?| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +|O+0#af5f00255&|P| +0#0000000&|^| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +|O+0#af5f00255&|P| +0#0000000&|~| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @50 +@75 +@57|5@1|9|,|1| @8|5|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_32.dump b/runtime/syntax/testdir/dumps/algol68_operators_32.dump new file mode 100644 index 0000000000..a5ce947142 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_32.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@74 +|#+0#0000e05&| |m|o|n|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@56 +@75 +|O+0#af5f00255&|P| +0#0000000&|!|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|%|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +>O+0#af5f00255&|P| +0#0000000&|&|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|+|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|-|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|?|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|^|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|~|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@53 +@75 +|O+0#af5f00255&|P| +0#0000000&|!|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|%|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|&|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|+|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|-|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +@57|5|7@1|,|1| @8|5|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_33.dump b/runtime/syntax/testdir/dumps/algol68_operators_33.dump new file mode 100644 index 0000000000..31b2a8669f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_33.dump @@ -0,0 +1,20 @@ +|O+0#af5f00255#ffffff0|P| +0#0000000&|-|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|?|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|^|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|~|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @49 +@75 +>#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d| |#| +0#0000000&@58 +@75 +|O+0#af5f00255&|P| +0#0000000&|!|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|!|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|!|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|!|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|!|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|%|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|%|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|%|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|%|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|%|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|&|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|&|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +@57|5|9|5|,|1| @8|6|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_34.dump b/runtime/syntax/testdir/dumps/algol68_operators_34.dump new file mode 100644 index 0000000000..4fd4b83104 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_34.dump @@ -0,0 +1,20 @@ +|O+0#af5f00255#ffffff0|P| +0#0000000&|&|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|&|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|&|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|&|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|+|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +>O+0#af5f00255&|P| +0#0000000&|+|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|+|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|+|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|+|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|-|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|-|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|-|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|-|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|-|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|?|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|?|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|?|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|?|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|?|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +@57|6|1|3|,|1| @8|6|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_35.dump b/runtime/syntax/testdir/dumps/algol68_operators_35.dump new file mode 100644 index 0000000000..8cec412cfd --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_35.dump @@ -0,0 +1,20 @@ +|O+0#af5f00255#ffffff0|P| +0#0000000&|?|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|^|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|^|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|^|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|^|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +>O+0#af5f00255&|P| +0#0000000&|^|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|~|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|~|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|~|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|~|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +|O+0#af5f00255&|P| +0#0000000&|~|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @49 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@49 +@75 +|O+0#af5f00255&|P| +0#0000000&|!|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|!|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|!|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|!|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|!|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +@57|6|3|1|,|1| @8|6|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_36.dump b/runtime/syntax/testdir/dumps/algol68_operators_36.dump new file mode 100644 index 0000000000..efc908f807 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_36.dump @@ -0,0 +1,20 @@ +|O+0#af5f00255#ffffff0|P| +0#0000000&|!|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +>O+0#af5f00255&|P| +0#0000000&|%|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +@57|6|4|9|,|1| @8|6|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_37.dump b/runtime/syntax/testdir/dumps/algol68_operators_37.dump new file mode 100644 index 0000000000..b09f78e1de --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_37.dump @@ -0,0 +1,20 @@ +|O+0#af5f00255#ffffff0|P| +0#0000000&|-|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +>O+0#af5f00255&|P| +0#0000000&|?|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +@75 +@57|6@1|7|,|1| @8|6|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_38.dump b/runtime/syntax/testdir/dumps/algol68_operators_38.dump new file mode 100644 index 0000000000..b50485636f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_38.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@74 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@46 +@75 +|O+0#af5f00255&|P| +0#0000000&|!|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|!|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +>O+0#af5f00255&|P| +0#0000000&|!|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|!|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|!|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|%|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|&|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +@57|6|8|5|,|1| @8|6|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_39.dump b/runtime/syntax/testdir/dumps/algol68_operators_39.dump new file mode 100644 index 0000000000..d344788ed2 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_39.dump @@ -0,0 +1,20 @@ +|O+0#af5f00255#ffffff0|P| +0#0000000&|+|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|+|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +>O+0#af5f00255&|P| +0#0000000&|-|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|-|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|?|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +@57|7|0|3|,|1| @8|7|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_40.dump b/runtime/syntax/testdir/dumps/algol68_operators_40.dump new file mode 100644 index 0000000000..4c6975af0f --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_40.dump @@ -0,0 +1,20 @@ +|O+0#af5f00255#ffffff0|P| +0#0000000&|^|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|^|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +>O+0#af5f00255&|P| +0#0000000&|~|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +|O+0#af5f00255&|P| +0#0000000&|~|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @48 +@75 +@75 +|#+0#0000e05&| |D|y|a|d|i|c| |#| +0#0000000&@64 +@75 +@75 +|#+0#0000e05&| |m|o|n|a|d| |#| +0#0000000&@65 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|!| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +|P+0#af5f00255&|R|I|O| +0#0000000&|%| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +|P+0#af5f00255&|R|I|O| +0#0000000&|&| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +|P+0#af5f00255&|R|I|O| +0#0000000&|+| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +|P+0#af5f00255&|R|I|O| +0#0000000&|-| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +@57|7|2|1|,|1| @8|7|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_41.dump b/runtime/syntax/testdir/dumps/algol68_operators_41.dump new file mode 100644 index 0000000000..1bf03b29b0 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_41.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|-| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +|P+0#af5f00255&|R|I|O| +0#0000000&|?| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +|P+0#af5f00255&|R|I|O| +0#0000000&|^| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +|P+0#af5f00255&|R|I|O| +0#0000000&|~| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @31 +@75 +>#+0#0000e05&| |m|o|n|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@56 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@53 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +@57|7|3|9|,|1| @8|7|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_42.dump b/runtime/syntax/testdir/dumps/algol68_operators_42.dump new file mode 100644 index 0000000000..67a6dc68b6 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_42.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|!|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +>P+0#af5f00255&|R|I|O| +0#0000000&|?|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +@75 +|#+0#0000e05&| |n|o|m|a|d| |#| +0#0000000&@65 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @32 +|P+0#af5f00255&|R|I|O| +0#0000000&|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @32 +|P+0#af5f00255&|R|I|O| +0#0000000&|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @32 +|P+0#af5f00255&|R|I|O| +0#0000000&|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @32 +|P+0#af5f00255&|R|I|O| +0#0000000&|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @32 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@56 +@75 +@57|7|5|7|,|1| @8|7|6|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_43.dump b/runtime/syntax/testdir/dumps/algol68_operators_43.dump new file mode 100644 index 0000000000..6591b825bd --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_43.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@74 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +>P+0#af5f00255&|R|I|O| +0#0000000&|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@53 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @28 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d| |#| +0#0000000&@58 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +@57|7@1|5|,|1| @8|7|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_44.dump b/runtime/syntax/testdir/dumps/algol68_operators_44.dump new file mode 100644 index 0000000000..7101b67f73 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_44.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|!|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +>P+0#af5f00255&|R|I|O| +0#0000000&|%|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +@57|7|9|3|,|1| @8|8|0|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_45.dump b/runtime/syntax/testdir/dumps/algol68_operators_45.dump new file mode 100644 index 0000000000..d144261703 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_45.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|+|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +>P+0#af5f00255&|R|I|O| +0#0000000&|-|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +@57|8|1@1|,|1| @8|8|2|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_46.dump b/runtime/syntax/testdir/dumps/algol68_operators_46.dump new file mode 100644 index 0000000000..d875433e43 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_46.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|~|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T| +0#0000000&|:| |4+0#e000002&|2|;+0#0000000&| @29 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@49 +> @74 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@57|8|2|9|,|0|-|1| @6|8|4|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_47.dump b/runtime/syntax/testdir/dumps/algol68_operators_47.dump new file mode 100644 index 0000000000..eed82de3ff --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_47.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|&|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +>P+0#af5f00255&|R|I|O| +0#0000000&|+|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@57|8|4|7|,|1| @8|8|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_48.dump b/runtime/syntax/testdir/dumps/algol68_operators_48.dump new file mode 100644 index 0000000000..2dcce8217e --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_48.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|^|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +>P+0#af5f00255&|R|I|O| +0#0000000&|~|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@75 +|#+0#0000e05&| |m|o|n|a|d|,| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@46 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|!|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|!|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@57|8|6|5|,|1| @8|8|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_49.dump b/runtime/syntax/testdir/dumps/algol68_operators_49.dump new file mode 100644 index 0000000000..559323935a --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_49.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|%|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|%|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|%|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +>P+0#af5f00255&|R|I|O| +0#0000000&|&|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|&|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|&|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|+|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|+|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@57|8@1|3|,|1| @8|8|9|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_50.dump b/runtime/syntax/testdir/dumps/algol68_operators_50.dump new file mode 100644 index 0000000000..6ae4d93bcc --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_50.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|-|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|-|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|-|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +>P+0#af5f00255&|R|I|O| +0#0000000&|?|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|?|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|?|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|^|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|^|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|~|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|~|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |n|o|m|a|d| |#| +0#0000000&@58 +@57|9|0|1|,|1| @8|9|1|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_51.dump b/runtime/syntax/testdir/dumps/algol68_operators_51.dump new file mode 100644 index 0000000000..cb41edfe04 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_51.dump @@ -0,0 +1,20 @@ +|#+0#0000e05#ffffff0| |n|o|m|a|d|,| |n|o|m|a|d| |#| +0#0000000&@58 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|*@1| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*@1| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +>P+0#af5f00255&|R|I|O| +0#0000000&|*|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|/@1| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/@1| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|<@1| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<@1| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +@57|9|1|9|,|1| @8|9|3|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_52.dump b/runtime/syntax/testdir/dumps/algol68_operators_52.dump new file mode 100644 index 0000000000..43a110c3e1 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_52.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|=|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|=@1| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=@1| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|>| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|>| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|*| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|*| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +>P+0#af5f00255&|R|I|O| +0#0000000&|>|/| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|/| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|<| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|<| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +|P+0#af5f00255&|R|I|O| +0#0000000&|>@1| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>@1| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @30 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |n|o|m|a|d|,| |b|e|c|o|m|e|s| |#| +0#0000000&@49 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|*@1|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*@1|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/@1|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/@1|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@57|9|3|7|,|1| @8|9|5|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_53.dump b/runtime/syntax/testdir/dumps/algol68_operators_53.dump new file mode 100644 index 0000000000..9de98c7a42 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_53.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|/@1|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/@1|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +>P+0#af5f00255&|R|I|O| +0#0000000&|<|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<@1|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<@1|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=@1|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=@1|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|>|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|>|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|*|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|*|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|/|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|/|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|<|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|<|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|=|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|=|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>@1|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>@1|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@57|9|5@1|,|1| @8|9|7|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_54.dump b/runtime/syntax/testdir/dumps/algol68_operators_54.dump new file mode 100644 index 0000000000..c69e6b0d20 --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_54.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|>@1|:|=| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>@1|:|=| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@75 +|#+0#0000e05&| |n|o|m|a|d|,| |n|o|m|a|d|,| |a|s@1|i|g|n|s| |t|o| |#| +0#0000000&@46 +@75 +|P+0#af5f00255&|R|I|O| +0#0000000&|*@1|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*@1|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +>P+0#af5f00255&|R|I|O| +0#0000000&|*|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|*|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|*|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/@1|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/@1|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|/|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|/|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<@1|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<@1|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|<|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@57|9|7|3|,|1| @8|9|8|%| diff --git a/runtime/syntax/testdir/dumps/algol68_operators_55.dump b/runtime/syntax/testdir/dumps/algol68_operators_55.dump new file mode 100644 index 0000000000..02fe4c291b --- /dev/null +++ b/runtime/syntax/testdir/dumps/algol68_operators_55.dump @@ -0,0 +1,20 @@ +|P+0#af5f00255#ffffff0|R|I|O| +0#0000000&|<|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|<|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|=@2|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=@2|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +>P+0#af5f00255&|R|I|O| +0#0000000&|=|>|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|=|>|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|*|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|*|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|/|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|/|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|<|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|<|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>|=@1|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>|=@1|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +|P+0#af5f00255&|R|I|O| +0#0000000&|>@1|=|:| |=+0#af5f00255&| +0#0000000&|1+0#e000002&|;+0#0000000&| |O+0#af5f00255&|P| +0#0000000&|>@1|=|:| |=+0#af5f00255&| +0#0000000&|(|I+0#00e0003&|N|T| +0#0000000&|a|,| |I+0#00e0003&|N|T| +0#0000000&|b|)| |I+0#00e0003&|N|T|:+0#0000000&| |4+0#e000002&|2|;+0#0000000&| @26 +@75 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|9@1|1|,|1| @8|B|o|t| diff --git a/runtime/syntax/testdir/dumps/dockerfile_00.dump b/runtime/syntax/testdir/dumps/dockerfile_00.dump new file mode 100644 index 0000000000..6f55b91d7c --- /dev/null +++ b/runtime/syntax/testdir/dumps/dockerfile_00.dump @@ -0,0 +1,20 @@ +>#+0#0000e05#ffffff0| |I|s@1|u|e| |#|8|3|6|4| |(|D|o|c|k|e|r| |s|y|n|t|a|x| |h|i|g|h|l|i|g|h|t|i|n|g| |-| |C|o|m@1|e|n|t|s| |b|r|e|a|k| |u|p| |R|U|N| |h|i|g|h|l|i|g|h|t +|i|n|g| +0#0000000&@71 +|#+0#0000e05&| |i|n| |m|u|l|t|i|-|l|i|n|e| |m|o|d|e|)| +0#0000000&@53 +@75 +|F+0#af5f00255&|R|O|M| +0#0000000&|d|e|b|i|a|n|:|1|0|.|3| @58 +@75 +|R+0#af5f00255&|U|N| +0#0000000&|a|p|t|-|g|e|t| |u|p|d|a|t|e| |-+0#e000e06&|y| +0#0000000&|\+0#af5f00255&| +0#0000000&@51 +@4|&+0#af5f00255&@1| +0#0000000&|a|p|t|-|g|e|t| |u|p|g|r|a|d|e| |-+0#e000e06&|y| +0#0000000&|\+0#af5f00255&| +0#0000000&@47 +@4|&+0#af5f00255&@1| +0#0000000&|a|p|t|-|g|e|t| |i|n|s|t|a|l@1| |-+0#e000e06&|y| +0#0000000&|c|u|r|l| |g+0#af5f00255&|r|e|p| +0#0000000&|s+0#af5f00255&|e|d| +0#0000000&|u|n|z|i|p| |g|i|t| |s|u|d|o| |j|q| |g|e|t@1|e|x|t| |\+0#af5f00255&| +0#0000000&@7 +@4|#+0#0000e05&| |A|z|u|r|e| |C|L|I| +0#0000000&@59 +@4|&+0#af5f00255&@1| +0#0000000&|c+0#af5f00255&|d| +0#0000000&|/|t|m|p| |\+0#af5f00255&| +0#0000000&@58 +@4|&+0#af5f00255&@1| +0#0000000&|c|u|r|l| |-+0#e000e06&|s|L| +0#0000000&|h|t@1|p|s|:|/@1|a|k|a|.|m|s|/|I|n|s|t|a|l@1|A|z|u|r|e|C|L|I|D|e|b| ||+0#af5f00255&| +0#0000000&|b|a|s|h| |\+0#af5f00255&| +0#0000000&@16 +@4|#+0#0000e05&| |C|l|e|a|n|-|u|p| |A|p|t| |C|a|c|h|e|s| +0#0000000&@49 +@4|&+0#af5f00255&@1| +0#0000000&|a|p|t|-|g|e|t| |c|l|e|a|n| |\+0#af5f00255&| +0#0000000&@52 +@4|&+0#af5f00255&@1| +0#0000000&|r+0#af5f00255&|m| +0#0000000&|-+0#e000e06&|r|f| +0#0000000&|/|v|a|r|/|l|i|b|/|a|p|t|/|l|i|s|t|s| @42 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|1|,|1| @10|A|l@1| diff --git a/runtime/syntax/testdir/dumps/javascript_00.dump b/runtime/syntax/testdir/dumps/javascript_00.dump new file mode 100644 index 0000000000..eca4c4b605 --- /dev/null +++ b/runtime/syntax/testdir/dumps/javascript_00.dump @@ -0,0 +1,20 @@ +>/+0#0000e05#ffffff0@1| |I|s@1|u|e| |#|2|0@1|6|9| |(|J|a|v|a|S|c|r|i|p|t| |s|y|n|t|a|x| |h|i|g|h|l|i|g|h|t|i|n|g| |n|o|t| |w|o|r|k|i|n|g| |p|r|o|p|e|r|l|y| |w|i|t|h| |r +|e|g|e|x| +0#0000000&@70 +|/+0#0000e05&@1| @2|p|a|t@1|e|r|n|s| |c|o|n|t|a|i|n|i|n|g| |q|u|o|t|a|t|i|o|n| |m|a|r|k|s|)| +0#0000000&@33 +@75 +|c+0#af5f00255&|o|n|s|t| +0#0000000&|c|o|n|t|a|i|n|s|S|y|m|b|o|l|s| |=| |p|a|s@1|w|o|r|d|.|m|a|t|c|h|(|/+0#e000002&|[|!|"|.@2|/|g|)+0#0000000&|;| @24 +@75 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|1|,|1| @10|A|l@1| diff --git a/runtime/syntax/testdir/dumps/make_01_00.dump b/runtime/syntax/testdir/dumps/make_01_00.dump index d476fcd2ac..cf31afb973 100644 --- a/runtime/syntax/testdir/dumps/make_01_00.dump +++ b/runtime/syntax/testdir/dumps/make_01_00.dump @@ -14,7 +14,7 @@ @75 |d+0#00e0e07&|e|f|a|u|l|t|:| +0#0000000&@66 | +0#e000002&@7|$+0#00e0e07&|(|c+0#af5f00255&|a|l@1| +0#00e0e07&|s|a|y|,|"+0#e000002&|H|e|l@1|o| |(|w|o|r|l|d|)|!|"|)+0#00e0e07&| +0#0000000&@38 -|~+0#4040ff13&| @73 -|~| @73 -|~| @73 -| +0#0000000&@56|1|,|1| @10|A|l@1| +@75 +|f+0#00e0e07&|o@1|:| +0#0000000&@70 +| +0#e000002&@7|e|c|h|o| |"|b|a|r|$+0#00e0e07&@1|"+0#e000002&| |b|a|z| +0#0000000&@50 +@57|1|,|1| @10|A|l@1| diff --git a/runtime/syntax/testdir/dumps/python2_strings_05.dump b/runtime/syntax/testdir/dumps/python2_strings_05.dump index 0ed41d8b3a..730e067fdf 100644 --- a/runtime/syntax/testdir/dumps/python2_strings_05.dump +++ b/runtime/syntax/testdir/dumps/python2_strings_05.dump @@ -1,7 +1,7 @@ |a+0#e000002#ffffff0|n|d| |l|i|t|e|r|a|l| |\|t| |a|n|d| |\|0|4|0| |a|n|d| |\|x|F@1| +0#0000000&@42 |a+0#e000002&|n|d| |e|s|c|a|p|e|s| |\+0#e000e06&|u|0@1|A|1| +0#e000002&|a|n|d| |\+0#e000e06&|U|0@2|1|0|6|0|5|"+0#e000002&@2| +0#0000000&@38 @75 ->#+0#0000e05&| |v|i|m|:| |s|y|n|t|a|x|=|p|y|t|h|o|n|2| +0#0000000&@53 +>#+0#0000e05&| |v|i|m|:| |f|t|=|p|y|t|h|o|n|2| +0#0000000&@57 |~+0#4040ff13&| @73 |~| @73 |~| @73 diff --git a/runtime/syntax/testdir/dumps/sh_03_01.dump b/runtime/syntax/testdir/dumps/sh_03_01.dump index 3ac5b4bc7a..81e2c87de5 100644 --- a/runtime/syntax/testdir/dumps/sh_03_01.dump +++ b/runtime/syntax/testdir/dumps/sh_03_01.dump @@ -17,4 +17,4 @@ |:+0#0000e05&| +0#0000000&|'+0#af5f00255&|$+0#e000002&|{|V|a|r|i|a|b|l|e|B|:|-|$|{|V|a|r|i|a|b|l|e|C|:|-|e|n|g|}@1|'+0#af5f00255&| +0#0000000&@39 @75 |#+0#0000e05&| |A|n|o|t|h|e|r| |t|e|s|t| +0#0000000&@60 -@57|1|8|,|0|-|1| @7|8|1|%| +@57|1|8|,|0|-|1| @7|6|5|%| diff --git a/runtime/syntax/testdir/dumps/sh_03_02.dump b/runtime/syntax/testdir/dumps/sh_03_02.dump index 6d03697c7b..f34582e496 100644 --- a/runtime/syntax/testdir/dumps/sh_03_02.dump +++ b/runtime/syntax/testdir/dumps/sh_03_02.dump @@ -1,7 +1,11 @@ |#+0#0000e05#ffffff0| |A|n|o|t|h|e|r| |t|e|s|t| +0#0000000&@60 |V+0#00e0e07&|a|r|i|a|b|l|e|=+0#0000000&|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|D|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|E|:+0#af5f00255&|=|e+0#0000000&|n|g|}+0#e000e06&@3| +0#0000000&@6 @7|:+0#0000e05&| +0#0000000&@7|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|=|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|D|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|E|:+0#af5f00255&|=|e+0#0000000&|n|g|}+0#e000e06&@3 -> +0#0000000&@74 +| +0#0000000&@74 +|#+0#0000e05&| |s|p|e|c|i|a|l| |v|a|r|i|a|b|l|e|s| +0#0000000&@55 +>e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|!|#|}|"+0#af5f00255&| +0#e000002&@11|#+0#0000e05&| |l|a|s|t| |p|o|s|i|t|i|o|n|a|l| |a|r|g|u|m|e|n|t| +0#0000000&@24 +|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|!|@|}|"+0#af5f00255&| +0#e000002&@11|#+0#0000e05&| |d|e|r|e|f| +0#0000000&@43 +|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|#|P|A|T|H|}|"+0#af5f00255&| +0#e000002&@8|#+0#0000e05&| |l|e|n|g|t|h| +0#0000000&@42 |~+0#4040ff13&| @73 |~| @73 |~| @73 @@ -13,8 +17,4 @@ |~| @73 |~| @73 |~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -| +0#0000000&@56|3@1|,|0|-|1| @7|B|o|t| +| +0#0000000&@56|3|5|,|1| @9|B|o|t| diff --git a/runtime/syntax/testdir/dumps/sh_06_00.dump b/runtime/syntax/testdir/dumps/sh_06_00.dump index b21039227e..8005105917 100644 --- a/runtime/syntax/testdir/dumps/sh_06_00.dump +++ b/runtime/syntax/testdir/dumps/sh_06_00.dump @@ -11,7 +11,7 @@ |#+0#0000e05&| +0#0000000&@73 |#+0#0000e05&| |D|i|s|p|l|a|y| |s|o|m|e| |H|e|l|p| +0#0000000&@55 |#+0#0000e05&| +0#0000000&@73 -|U+0#00e0e07&|s|a|g|e| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@64 +|U+0#00e0e07&|s|a|g|e| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@64 @75 |#+0#0000e05&| |d|o|e|s| |t|h|i|s| |c|o|m@1|e|n|t| |w|o|r|k|?| +0#0000000&@49 |V+0#00e0e07&|a|r|i|a|b|l|e|N|a|m|e|=+0#0000000&|"+0#af5f00255&|$+0#e000e06&|{|B|a|s|i|c|C|o|n|f|i|g|N|a|m|e|}|_+0#e000002&|*|"+0#af5f00255&| +0#0000000&@39 diff --git a/runtime/syntax/testdir/dumps/sh_06_01.dump b/runtime/syntax/testdir/dumps/sh_06_01.dump index e7cedb4b8e..409fea9b6e 100644 --- a/runtime/syntax/testdir/dumps/sh_06_01.dump +++ b/runtime/syntax/testdir/dumps/sh_06_01.dump @@ -1,4 +1,4 @@ -|U+0#00e0e07#ffffff0|s|a|g|e| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@64 +|U+0#00e0e07#ffffff0|s|a|g|e| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@64 @75 |#+0#0000e05&| |d|o|e|s| |t|h|i|s| |c|o|m@1|e|n|t| |w|o|r|k|?| +0#0000000&@49 |V+0#00e0e07&|a|r|i|a|b|l|e|N|a|m|e|=+0#0000000&|"+0#af5f00255&|$+0#e000e06&|{|B|a|s|i|c|C|o|n|f|i|g|N|a|m|e|}|_+0#e000002&|*|"+0#af5f00255&| +0#0000000&@39 diff --git a/runtime/syntax/testdir/dumps/sh_06_03.dump b/runtime/syntax/testdir/dumps/sh_06_03.dump index 6a54bcd9af..98bad3092d 100644 --- a/runtime/syntax/testdir/dumps/sh_06_03.dump +++ b/runtime/syntax/testdir/dumps/sh_06_03.dump @@ -4,7 +4,7 @@ |#+0#0000e05&| +0#0000000&@73 |#+0#0000e05&| |C|r|e|a|t|e| |a| |b|a|c|k|u|p| |u|s|i|n|g| |f|b|a|c|k|u|p|/|f|r|e|c|o|v|e|r| +0#0000000&@34 >#+0#0000e05&| +0#0000000&@73 -|E+0#00e0e07&|x|e|c|u|t|e|F|b|a|c|k|u|p| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&|#+0#0000e05&| |T|E|S|T|I|N|G| +0#0000000&@45 +|E+0#00e0e07&|x|e|c|u|t|e|F|b|a|c|k|u|p| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&|#+0#0000e05&| |T|E|S|T|I|N|G| +0#0000000&@45 @75 |[+0#af5f00255&| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|D|e|b|u|g|S|c|r|i|p|t|"+0#af5f00255&| +0#0000000&|]+0#af5f00255&| +0#0000000&@3|&+0#af5f00255&@1| +0#0000000&|s+0#af5f00255&|e|t| +0#00e0e07&|-+0#e000e06&|x| +0#00e0e07&||+0#af5f00255&@1| +0#0000000&|s+0#af5f00255&|e|t| +0#00e0e07&|++0#e000e06&|x| +0#0000000&@33 @75 diff --git a/runtime/syntax/testdir/dumps/sh_07_00.dump b/runtime/syntax/testdir/dumps/sh_07_00.dump index f6dbd2b798..0629360f5e 100644 --- a/runtime/syntax/testdir/dumps/sh_07_00.dump +++ b/runtime/syntax/testdir/dumps/sh_07_00.dump @@ -14,7 +14,7 @@ | | +0#0000000&@73 |#+0#0000e05&| |a|v|a|i|l|a|b|l|e|!| +0#0000000&@62 |#+0#0000e05&| +0#0000000&@73 -|F+0#00e0e07&|u|n|c|t|i|o|n|1| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 +|F+0#00e0e07&|u|n|c|t|i|o|n|1| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 @75 |e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|F+0#e000002&|u|n|c|t|i|o|n|1|:| |f|o|r| |l|o@1|p| |i|n|s|i|d|e| |a| |f|u|n|c|t|i|o|n|:|\+0#e000e06&|t|\|c|"+0#af5f00255&| +0#0000000&@25 |i|s|_|d|a|s|h|:| |1|,| |i|s|_|p|o|s|i|x|:| |1|,| |i|s|_|s|h|:| |1|,| @22|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_07_01.dump b/runtime/syntax/testdir/dumps/sh_07_01.dump index 4c4fbcb902..d07fa5a55a 100644 --- a/runtime/syntax/testdir/dumps/sh_07_01.dump +++ b/runtime/syntax/testdir/dumps/sh_07_01.dump @@ -2,7 +2,7 @@ | | +0#0000000&@73 |#+0#0000e05&| |a|v|a|i|l|a|b|l|e|!| +0#0000000&@62 |#+0#0000e05&| +0#0000000&@73 -|F+0#00e0e07&|u|n|c|t|i|o|n|1| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 +|F+0#00e0e07&|u|n|c|t|i|o|n|1| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 @75 >e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|F+0#e000002&|u|n|c|t|i|o|n|1|:| |f|o|r| |l|o@1|p| |i|n|s|i|d|e| |a| |f|u|n|c|t|i|o|n|:|\+0#e000e06&|t|\|c|"+0#af5f00255&| +0#0000000&@25 |[+0#af5f00255&| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|*|"+0#af5f00255&| +0#0000000&|]+0#af5f00255&| +0#0000000&||+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|n+0#e000002&|o|n|e|\+0#e000e06&|c|"+0#af5f00255&| +0#0000000&@49 diff --git a/runtime/syntax/testdir/dumps/sh_07_02.dump b/runtime/syntax/testdir/dumps/sh_07_02.dump index 61842b5ebf..8776cdb13e 100644 --- a/runtime/syntax/testdir/dumps/sh_07_02.dump +++ b/runtime/syntax/testdir/dumps/sh_07_02.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| +0#0000000&@73 |#+0#0000e05&| |F|o|r| |l|o@1|p| |w|i|t|h| |'|i|n| |l|i|s|t|'| |$|*| +0#0000000&@46 |#+0#0000e05&| +0#0000000&@73 ->F+0#00e0e07&|u|n|c|t|i|o|n|2| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 +>F+0#00e0e07&|u|n|c|t|i|o|n|2| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 @75 |e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|F+0#e000002&|u|n|c|t|i|o|n|2|:| |f|o|r| |l|o@1|p| |i|n|s|i|d|e| |a| |f|u|n|c|t|i|o|n|:|\+0#e000e06&|t|\|c|"+0#af5f00255&| +0#0000000&@25 |f+0#af5f00255&|o|r| +0#0000000&|V|a|r| |i+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|*| +0#0000000&@61 diff --git a/runtime/syntax/testdir/dumps/sh_07_03.dump b/runtime/syntax/testdir/dumps/sh_07_03.dump index a42f25710c..4e9308cd25 100644 --- a/runtime/syntax/testdir/dumps/sh_07_03.dump +++ b/runtime/syntax/testdir/dumps/sh_07_03.dump @@ -1,6 +1,6 @@ |#+0#0000e05#ffffff0| |F|o|r| |l|o@1|p| |w|i|t|h| |'|i|n| |l|i|s|t|'| |$|@|.| |W|o|r|k|s| |t|h|e| |s|a|m|e| |w|a|y| |a|s| |$|*| +0#0000000&@20 |#+0#0000e05&| +0#0000000&@73 -|F+0#00e0e07&|u|n|c|t|i|o|n|3| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 +|F+0#00e0e07&|u|n|c|t|i|o|n|3| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 @75 |e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|F+0#e000002&|u|n|c|t|i|o|n|3|:| |f|o|r| |l|o@1|p| |i|n|s|i|d|e| |a| |f|u|n|c|t|i|o|n|:|\+0#e000e06&|t|\|c|"+0#af5f00255&| +0#0000000&@25 >f+0#af5f00255&|o|r| +0#0000000&|V|a|r| |i+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|@| +0#0000000&@61 @@ -15,6 +15,6 @@ |#+0#0000e05&| +0#0000000&@73 |#+0#0000e05&| |F|o|r| |l|o@1|p| |w|i|t|h| |'|i|n| |l|i|s|t|'| |"|$|@|"|.| |S|p|e|c|i|a|l| |c|a|s|e|.| |W|o|r|k|s| |l|i|k|e| |"|$|1|"| |"|$|2|"| |.@2| +0#0000000&@4 |#+0#0000e05&| +0#0000000&@73 -|F+0#00e0e07&|u|n|c|t|i|o|n|4| |(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 +|F+0#00e0e07&|u|n|c|t|i|o|n|4| |(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 @75 @57|4|8|,|1| @9|5|6|%| diff --git a/runtime/syntax/testdir/dumps/sh_bash_00.dump b/runtime/syntax/testdir/dumps/sh_bash_00.dump index 85966ebd75..15093831d7 100644 --- a/runtime/syntax/testdir/dumps/sh_bash_00.dump +++ b/runtime/syntax/testdir/dumps/sh_bash_00.dump @@ -14,7 +14,7 @@ |e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|s+0#e000002&|e|v|e|n|'+0#af5f00255&| +0#e000002&@3|;+0#e000e06&|}| +0#0000000&@48 |e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|e+0#e000002&|i|g|h|t|'+0#af5f00255&|;+0#e000e06&| @2|}| +0#0000000&@49 |t+0#af5f00255&|y|p|e|s|e|t| +0#e000e06&|n+0#00e0e07&|i|n|e|=+0#0000000&|$+0#e000e06&|{| |p+0#af5f00255&|w|d|;| +0#e000e06&|}| +0#0000000&@52 -|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|n+0#e000002&|i|n|e|'+0#af5f00255&| +0#e000002&|;+0#e000e06&| | +0#0000000&@52 +|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|n+0#e000002&|i|n|e|'+0#af5f00255&| +0#e000002&|;+0#e000e06&| +0#0000000&@53 | +0#e000e06&|}| +0#0000000&@72 @75 |i|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_bash_01.dump b/runtime/syntax/testdir/dumps/sh_bash_01.dump index 18961a7983..1a65e23fc2 100644 --- a/runtime/syntax/testdir/dumps/sh_bash_01.dump +++ b/runtime/syntax/testdir/dumps/sh_bash_01.dump @@ -1,7 +1,7 @@ |e+0#af5f00255#ffffff0|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|s+0#e000002&|e|v|e|n|'+0#af5f00255&| +0#e000002&@3|;+0#e000e06&|}| +0#0000000&@48 |e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|e+0#e000002&|i|g|h|t|'+0#af5f00255&|;+0#e000e06&| @2|}| +0#0000000&@49 |t+0#af5f00255&|y|p|e|s|e|t| +0#e000e06&|n+0#00e0e07&|i|n|e|=+0#0000000&|$+0#e000e06&|{| |p+0#af5f00255&|w|d|;| +0#e000e06&|}| +0#0000000&@52 -|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|n+0#e000002&|i|n|e|'+0#af5f00255&| +0#e000002&|;+0#e000e06&| | +0#0000000&@52 +|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|n+0#e000002&|i|n|e|'+0#af5f00255&| +0#e000002&|;+0#e000e06&| +0#0000000&@53 | +0#e000e06&|}| +0#0000000&@72 > @74 |v+0#e000e06&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@60 @@ -12,9 +12,9 @@ |p+0#af5f00255&|r|i|n|t|f| +0#e000e06&|'+0#af5f00255&|%+0#e000002&|s|\|n|'+0#af5f00255&| +0#e000e06&|"+0#af5f00255&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| |t|w|e|l|v|e| @4|;|}|"+0#af5f00255&| +0#0000000&@31 |u+0#00e0e07&|n|l|u|c|k|y|=+0#0000000&|$+0#e000e06&|{||+0#af5f00255&|v+0#e000e06&|a|l|s|u|b|f|u|n|c| |t|h|i|r|t|e@1|n| +0#0000000&@44 |}+0#e000e06&| +0#0000000&@73 -|t+0#af5f00255&|y|p|e|s|e|t| +0#e000e06&|n+0#00e0e07&|o|t|a|f|l|o|a|t|=+0#0000000&|$+0#e000e06&|{||+0#af5f00255&|v+0#e000e06&|a|l|s|u|b|f|u|n|c| |n|o|t|a|n|u|m|b|e|r| @5|;+0#af5f00255&| +0#e000e06&| +0#0000000&@24 +|t+0#af5f00255&|y|p|e|s|e|t| +0#e000e06&|n+0#00e0e07&|o|t|a|f|l|o|a|t|=+0#0000000&|$+0#e000e06&|{||+0#af5f00255&|v+0#e000e06&|a|l|s|u|b|f|u|n|c| |n|o|t|a|n|u|m|b|e|r| @5|;+0#af5f00255&| +0#0000000&@25 | +0#e000e06&|}| +0#0000000&@72 |e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|u|n|l|u|c|k|y| +0#e000002&|$+0#e000e06&|n|o|t|a|n|u|m|b|e|r| +0#0000000&@49 |$+0#e000e06&|{||+0#af5f00255&|e|c|h|o| +0#e000002&|f|o|u|r|t|e@1|n|;+0#af5f00255&|}+0#e000e06&| +0#0000000&@56 |$+0#e000e06&|{||+0#af5f00255&|e|c|h|o| +0#e000002&|f|i|f|t|e@1|n| +0#0000000&@59 -@57|1|9|,|0|-|1| @7|9|2|%| +@57|1|9|,|0|-|1| @7|7|2|%| diff --git a/runtime/syntax/testdir/dumps/sh_bash_02.dump b/runtime/syntax/testdir/dumps/sh_bash_02.dump index 677a1ab127..f7ea1a3001 100644 --- a/runtime/syntax/testdir/dumps/sh_bash_02.dump +++ b/runtime/syntax/testdir/dumps/sh_bash_02.dump @@ -1,5 +1,9 @@ |$+0#e000e06#ffffff0|{||+0#af5f00255&|e|c|h|o| +0#e000002&|f|i|f|t|e@1|n| +0#0000000&@59 ->}+0#e000e06&| +0#0000000&@73 +|}+0#e000e06&| +0#0000000&@73 +@75 +|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|!|#|}|"+0#af5f00255&| +0#e000002&@11|#+0#0000e05&| |l|a|s|t| |p|o|s|i|t|i|o|n|a|l| |a|r|g|u|m|e|n|t| +0#0000000&@24 +|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|!|@|}|"+0#af5f00255&| +0#e000002&@11|#+0#0000e05&| |d|e|r|e|f| +0#0000000&@43 +>e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|#|P|A|T|H|}|"+0#af5f00255&| +0#e000002&@8|#+0#0000e05&| |l|e|n|g|t|h| +0#0000000&@42 |~+0#4040ff13&| @73 |~| @73 |~| @73 @@ -13,8 +17,4 @@ |~| @73 |~| @73 |~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -| +0#0000000&@56|3@1|,|1| @9|B|o|t| +| +0#0000000&@56|3|7|,|1| @9|B|o|t| diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_00.dump b/runtime/syntax/testdir/dumps/sh_functions_bash_00.dump index 7045450954..e78273f4f3 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_bash_00.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_bash_00.dump @@ -4,17 +4,17 @@ | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| +0#0000000&|-+0#e000e06&|i| +0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| +0#0000000&@58 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(+0#e000e06&|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(+0#e000e06&|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64 +| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(+0#e000e06&|)| +0#0000000&@64 | +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:| @67 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 |i|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_01.dump b/runtime/syntax/testdir/dumps/sh_functions_bash_01.dump index a7ee351d9f..aba361e65e 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_bash_01.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_bash_01.dump @@ -1,20 +1,20 @@ ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 ||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| |e|l|s|e|w|h|e|r|e| @51 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 +|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(+0#e000e06&|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| +0#0000000&@63 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| |0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| |2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 +| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(+0#e000e06&|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66 +| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(+0#e000e06&|)| +0#0000000&@66 | +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| +0#0000000&@60 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:| @67 -@57|1|9|,|1| @9|3|6|%| +@57|1|9|,|1| @9|1|6|%| diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_02.dump b/runtime/syntax/testdir/dumps/sh_functions_bash_02.dump index c11eb911e2..8901e58ac3 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_bash_02.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_bash_02.dump @@ -2,19 +2,19 @@ ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|i+0#00e0e07#ffffff0|f@1|y|(|)| +0#0000000&|f+0#af5f00255&|o|r| |(@1|;@1|)@1| +0#0000000&@55 +| +0#0000e05#a8a8a8255@1|i+0#00e0e07#ffffff0|f@1|y|(+0#e000e06&|)| +0#0000000&|f+0#af5f00255&|o|r| |(@1|;@1|)@1| +0#0000000&@55 |-+0#0000e05#a8a8a8255| >d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| +0#0000000&@63 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|f@1|y| @68 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 |-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62 -||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|!+0#00e0e07&|?|#|(|)| +0#0000000&@54 +||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|!+0#00e0e07&|?|#|(+0#e000e06&|)| +0#0000000&@54 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|(+0#af5f00255&| +0#0000000&@67 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|@+0#00e0e07&|Îą|!| +0#0000000&|{+0#e000e06&| +0#0000000&@50 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#e000e06&| +0#0000000&@63 |2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|@|Îą|!+0#af5f00255&| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@56 |2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|)+0#af5f00255&| +0#0000000&@67 -||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|e+0#af5f00255&|v|a|l| +0#0000000&|!+0#af5f00255&|?+0#0000000&|\+0#e000e06&|#| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@54 -@57|3|7|,|1| @9|8|6|%| +||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|e+0#af5f00255&|v|a|l| +0#0000000&|!+0#af5f00255&|?+0#0000000&|\+0#e000e06&|#| +0#0000000&|"+0#af5f00255&|\+0#e000e06&|"|$|1|\|"|"+0#af5f00255&| +0#0000000&@50 +@57|3|7|,|1| @9|4|0|%| diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_03.dump b/runtime/syntax/testdir/dumps/sh_functions_bash_03.dump index a18749ada0..98fcc942e8 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_bash_03.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_bash_03.dump @@ -1,20 +1,20 @@ -||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|e+0#af5f00255&|v|a|l| +0#0000000&|!+0#af5f00255&|?+0#0000000&|\+0#e000e06&|#| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@54 +||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|e+0#af5f00255&|v|a|l| +0#0000000&|!+0#af5f00255&|?+0#0000000&|\+0#e000e06&|#| +0#0000000&|"+0#af5f00255&|\+0#e000e06&|"|$|1|\|"|"+0#af5f00255&| +0#0000000&@50 ||+0#0000e05#a8a8a8255| |f+0#af5f00255#ffffff0|i| +0#0000000&@70 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|n+0#00e0e07#ffffff0|a|m|e|s|p|a|c|e| |(|)| +0#0000000&@60 +| +0#0000e05#a8a8a8255@1|n+0#00e0e07#ffffff0|a|m|e|s|p|a|c|e| |(+0#e000e06&|)| +0#0000000&@60 |-+0#0000e05#a8a8a8255| |{+0#e000e06#ffffff0| +0#0000000&|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|#|;+0#af5f00255&| +0#0000000&@62 ||+0#0000e05#a8a8a8255| >}+0#e000e06#ffffff0|;+0#0000000&| |n|a|m|e|s|p|a|c|e| |$+0#e000e06&|@| +0#0000000&@57 -|~+0#4040ff13&| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -| +0#0000000&@56|5@1|,|1| @9|B|o|t| +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 +| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |W|h|e|t|h|e|r| |"|=|"| |b|e|l|o|n|g|s| |t|o| |a| |n|a|m|e| |o|r| |d|e|l|i|m|i|t|s| |a| |n|a|m|e| |d|e|p|e|n|d|s| |o|n| |w|h|e|t|h|e|r| +0#0000000&@3 +| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |t|h|e| |r|e|s|e|r|v|e|d| |w|o|r|d| |"|f|u|n|c|t|i|o|n|"| |i|s| |p|r|e|s|e|n|t|,| |i|f| |s|o|,| |t|h|e|n| |"|=|"| |i|s| |p|a|r|t| |o|f| +0#0000000&@3 +| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |t|h|e| |f|u|n|c|t|i|o|n| |n|a|m|e|;| |e|l|s|e|,| |"|=|"| |d|e|l|i|m|i|t|s| |t|h|e| |n|a|m|e| |o|f| |a| |v|a|r|i|a|b|l|e| |w|h|e|n| |t|h|i|s| +0#0000000& +| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |n|a|m|e| |i|s| |g|i|v|e|n| |i|n| |a|l|p|h|a|n|u|m|e|r|i|c| |c|h|a|r|a|c|t|e|r|s| |a|n|d| |"|_|"|s| |b|e|f|o|r|e| |t|h|e| |l|e|f|t|m|o|s|t| +0#0000000&@1 +| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |"|=|"|;| |o|t|h|e|r|w|i|s|e|,| |"|=|"| |i|s| |p|a|r|t| |o|f| |t|h|e| |f|u|n|c|t|i|o|n| |n|a|m|e| |w|h|e|n| |t|h|i|s| |n|a|m|e| |h|a|s| +0#0000000&@3 +| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |o|n|e| |o|r| |m|o|r|e| |s|u|p@1|o|r|t|e|d| |N|O|N|-|a|l|p|h|a|n|u|m|e|r|i|c| |(|o|r| |"|_|"|)| |c|h|a|r|a|c|t|e|r|s| |b|e|f|o|r|e| |"|=|"|.| +0#0000000& +| +0#0000e05#a8a8a8255@1|x+0#00e0e07#ffffff0|s|=+0#0000000&|(+0#e000e06&|)| +0#0000000&@67 +| +0#0000e05#a8a8a8255@1|(+0#e000e06#ffffff0| +0#0000000&@71 +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@3|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|(@1| |1+0#e000002&| +0#e000e06&|+| |$|{|#|x|s|[|*+0#0000000&|]+0#e000e06&|}| |)@1| +0#0000000&@43 +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@3|x+0#00e0e07&|s|=+0#0000000&|(+0#e000e06&|)| +0#0000000&@63 +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@3|{| +0#0000000&@67 +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@7|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|(@1| |2+0#e000002&| +0#e000e06&|+| |$|{|#|x|s|[|*+0#0000000&|]+0#e000e06&|}| |)@1| +0#0000000&@39 +@57|5@1|,|1| @9|6|3|%| diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_04.dump b/runtime/syntax/testdir/dumps/sh_functions_bash_04.dump new file mode 100644 index 0000000000..d1be88c7d3 --- /dev/null +++ b/runtime/syntax/testdir/dumps/sh_functions_bash_04.dump @@ -0,0 +1,20 @@ +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@7|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|(@1| |2+0#e000002&| +0#e000e06&|+| |$|{|#|x|s|[|*+0#0000000&|]+0#e000e06&|}| |)@1| +0#0000000&@39 +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@7|x+0#00e0e07&|s|=+0#0000000&|(+0#e000e06&|)| +0#0000000&@59 +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@7|i+0#af5f00255&|f| |:+0#e000e06&|;+0#af5f00255&| +0#e000e06&|t+0#af5f00255&|h|e|n| +0#e000e06&|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|(@1| |3+0#e000002&| +0#e000e06&|+| |$|{|#|x|s|[|*+0#0000000&|]+0#e000e06&|}| |)@1|;+0#af5f00255&| +0#e000e06&|f+0#af5f00255&|i| +0#0000000&@24 +| +0#0000e05#a8a8a8255@1| +0#e000e06#ffffff0@3|}| +0#0000000&@67 +| +0#0000e05#a8a8a8255@1|)+0#e000e06#ffffff0| +0#0000000&@71 +| +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@72 +|-+0#0000e05#a8a8a8255| |i+0#00e0e07#ffffff0|δ|=|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@65 +|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|=+0#00e0e07&|i|d|=|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@60 +|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|=+0#00e0e07&@2|(+0#e000e06&|)| +0#0000000&@59 +|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|i+0#af5f00255&|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|*|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;| +0#0000000&|=+0#af5f00255&@2| +0#0000000&|$+0#e000e06&|*| +0#0000000&@34 +|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|}+0#e000e06&|;+0#af5f00255&| +0#0000000&|=+0#af5f00255&|i|d|=| +0#0000000&|$+0#e000e06&|*| +0#0000000&@58 +||+0#0000e05#a8a8a8255| |)+0#af5f00255#ffffff0|;+0#0000000&| |i+0#af5f00255&|d|=| +0#0000000&|i|δ|=+0#af5f00255&| +0#0000000&|i|δ|=+0#af5f00255&| +0#0000000&|i|δ|=+0#af5f00255&| +0#0000000&@54 +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 +|-+0#0000e05#a8a8a8255| |f+0#af5f00255#ffffff0|u|n|c|t|i|o|n| +0#0000000&|f+0#00e0e07&|=|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@57 +|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|f+0#00e0e07&|=|f| +0#0000000&|{+0#e000e06&| +0#0000000&@54 +|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|f+0#00e0e07&|=|f|=| +0#0000000&@51 +|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|i+0#af5f00255&|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|*|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;| +0#0000000&|f|\+0#e000e06&|=|f+0#0000000&|\+0#e000e06&|=| +0#0000000&|$+0#e000e06&|*| +0#0000000&@31 +|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|}+0#e000e06&|;+0#af5f00255&| +0#0000000&|f|\+0#e000e06&|=|f+0#0000000&| |$+0#e000e06&|*| +0#0000000&@58 +||+0#0000e05#a8a8a8255| |)+0#af5f00255#ffffff0|;+0#0000000&| |f+0#00e0e07&|=+0#0000000&| |f|\|=+0#af5f00255&| +0#0000000&|f+0#00e0e07&|=+0#0000000&| |f+0#00e0e07&|=+0#0000000&| @57 +@57|7|3|,|0|-|1| @7|8|7|%| diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_05.dump b/runtime/syntax/testdir/dumps/sh_functions_bash_05.dump new file mode 100644 index 0000000000..9b805c1891 --- /dev/null +++ b/runtime/syntax/testdir/dumps/sh_functions_bash_05.dump @@ -0,0 +1,20 @@ +||+0#0000e05#a8a8a8255| |)+0#af5f00255#ffffff0|;+0#0000000&| |f+0#00e0e07&|=+0#0000000&| |f|\|=+0#af5f00255&| +0#0000000&|f+0#00e0e07&|=+0#0000000&| |f+0#00e0e07&|=+0#0000000&| @57 +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 +| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |P|a|r|e|n|s| |a|r|e| |n|o|t| |e|s|c|a|p|e|d|,| |h|e|n|c|e| |t|h|i|s| |i|s| |i|n|v|a|l|i|d| |v|a|r|i|a|b|l|e| |a|s@1|i|g|n|m|e|n|t|.| +0#0000000&@4 +| +0#0000e05#a8a8a8255@1|f+0#ffffff16#ff404010|=|f|(|)| +0#0000000#ffffff0@67 +| +0#0000e05#a8a8a8255@1|{+0#e000e06#ffffff0| +0#0000000&@71 +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3>f+0#ffffff16#ff404010|=|f|=|(|)| +0#0000000#ffffff0@62 +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|(+0#af5f00255&| +0#0000000&@67 +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@7|f+0#ffffff16#ff404010|=|f|=|f|(|)| +0#0000000#ffffff0@57 +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@7|i+0#af5f00255&|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i| +0#0000000&@48 +| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|)+0#af5f00255&| +0#0000000&@67 +| +0#0000e05#a8a8a8255@1|}+0#e000e06#ffffff0| +0#0000000&@71 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|9|1|,|5| @9|B|o|t| diff --git a/runtime/syntax/testdir/dumps/sh_functions_dash_00.dump b/runtime/syntax/testdir/dumps/sh_functions_dash_00.dump index f4465f4ea0..a7f92e5165 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_dash_00.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_dash_00.dump @@ -3,18 +3,18 @@ | +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|s|h|_|f|o|l|d|_|e|n|a|b|l|e|d| |=| |1| |+| |2| |+| |4| +0#0000000&@22 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64 +| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(+0#e000e06&|)| +0#0000000&@64 | +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 ||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| |e|l|s|e|w|h|e|r|e| @51 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 +| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(+0#e000e06&|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 |i|s|_|d|a|s|h|:| |1|,| |i|s|_|p|o|s|i|x|:| |1|,| |i|s|_|s|h|:| |1|,| @22|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_functions_dash_01.dump b/runtime/syntax/testdir/dumps/sh_functions_dash_01.dump index 5762b7be64..1294700034 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_dash_01.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_dash_01.dump @@ -1,10 +1,10 @@ | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 ||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| |e|l|s|e|w|h|e|r|e| @51 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 +| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(+0#e000e06&|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 | +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66 +| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(+0#e000e06&|)| +0#0000000&@66 | +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| +0#0000000&@60 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 @@ -12,9 +12,9 @@ | +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 |-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62 -||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i+0#00e0e07&|d|2|(|)| +0#0000000&@63 +||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i+0#00e0e07&|d|2|(+0#e000e06&|)| +0#0000000&@63 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|(+0#af5f00255&| +0#0000000&@67 -|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|i+0#00e0e07&|d|1|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 +|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|i+0#00e0e07&|d|1|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#e000e06&| +0#0000000&@63 @57|1|9|,|0|-|1| @7|6|1|%| diff --git a/runtime/syntax/testdir/dumps/sh_functions_dash_02.dump b/runtime/syntax/testdir/dumps/sh_functions_dash_02.dump index e7d2985902..e1aa1d46d6 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_dash_02.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_dash_02.dump @@ -4,7 +4,7 @@ ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i|d|2| |"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@60 ||+0#0000e05#a8a8a8255| |f+0#af5f00255#ffffff0|i| +0#0000000&@70 | +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|u|n|c|t|i|o|n| |(|)| +0#0000000&@61 +| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|u|n|c|t|i|o|n| |(+0#e000e06&|)| +0#0000000&@61 |-+0#0000e05#a8a8a8255| |{+0#e000e06#ffffff0| +0#0000000&|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|#|;+0#af5f00255&| +0#0000000&@62 ||+0#0000e05#a8a8a8255| |}+0#e000e06#ffffff0|;+0#0000000&| |f|u|n|c|t|i|o|n| |$+0#e000e06&|@| +0#0000000&@58 |~+0#4040ff13&| @73 diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_00.dump b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_00.dump index 8c4edd229c..e1d5e01558 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_00.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_00.dump @@ -4,17 +4,17 @@ | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| +0#0000000&|-+0#e000e06&|i| +0#0000000&|1+0#e000002&|0| +0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| +0#0000000&@55 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(+0#e000e06&|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(+0#e000e06&|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64 +| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(+0#e000e06&|)| +0#0000000&@64 | +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 |i|s|_|k|o|r|n|s|h|e|l@1|:| |1|,| |i|s|_|k|s|h|2|0|2|0|:| |1|,| @25|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_01.dump b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_01.dump index 6e74c342dc..c466ead0f4 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_01.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_01.dump @@ -1,19 +1,19 @@ ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 ||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| |e|l|s|e|w|h|e|r|e| @51 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 +|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(+0#e000e06&|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| +0#0000000&@63 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| |0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| |2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 +| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(+0#e000e06&|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66 +| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(+0#e000e06&|)| +0#0000000&@66 | +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| +0#0000000&@60 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_02.dump b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_02.dump index cca29de74d..0fb4817dab 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_02.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_02.dump @@ -2,14 +2,14 @@ ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|i+0#00e0e07#ffffff0|f@1|y|(|)| +0#0000000&|f+0#af5f00255&|o|r| |(@1|;@1|)@1| +0#0000000&@55 +| +0#0000e05#a8a8a8255@1|i+0#00e0e07#ffffff0|f@1|y|(+0#e000e06&|)| +0#0000000&|f+0#af5f00255&|o|r| |(@1|;@1|)@1| +0#0000000&@55 |-+0#0000e05#a8a8a8255| >d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| +0#0000000&@63 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|f@1|y| @68 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 |-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62 -||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i+0#00e0e07&|d|_|(|)| +0#0000000&@63 +||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i+0#00e0e07&|d|_|(+0#e000e06&|)| +0#0000000&@63 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|(+0#af5f00255&| +0#0000000&@67 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|n+0#00e0e07&|.|s|e|t| +0#0000000&|{+0#e000e06&| +0#0000000&@48 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|n|"+0#af5f00255&| +0#0000000&@51 diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh88_00.dump b/runtime/syntax/testdir/dumps/sh_functions_ksh88_00.dump index f4a6e0311c..799e458df2 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_ksh88_00.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_ksh88_00.dump @@ -4,17 +4,17 @@ | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| +0#0000000&|-+0#e000e06&|i| +0#0000000&|1+0#e000002&|0| +0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| +0#0000000&@55 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(+0#e000e06&|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(+0#e000e06&|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64 +| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(+0#e000e06&|)| +0#0000000&@64 | +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 |i|s|_|k|o|r|n|s|h|e|l@1|:| |1|,| |i|s|_|k|s|h|8@1|:| |1|,| @27|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh88_01.dump b/runtime/syntax/testdir/dumps/sh_functions_ksh88_01.dump index 3426afb1af..e72cee2b18 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_ksh88_01.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_ksh88_01.dump @@ -1,19 +1,19 @@ ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 ||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| |e|l|s|e|w|h|e|r|e| @51 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 +|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(+0#e000e06&|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| +0#0000000&@63 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| |0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| |2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 +| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(+0#e000e06&|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66 +| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(+0#e000e06&|)| +0#0000000&@66 | +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| +0#0000000&@60 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh88_02.dump b/runtime/syntax/testdir/dumps/sh_functions_ksh88_02.dump index 4df14699ad..c7fe98e65f 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_ksh88_02.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_ksh88_02.dump @@ -3,7 +3,7 @@ | +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 |-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62 -||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3>i+0#00e0e07&|d|2|(|)| +0#0000000&@63 +||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3>i+0#00e0e07&|d|2|(+0#e000e06&|)| +0#0000000&@63 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|(+0#af5f00255&| +0#0000000&@67 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|i+0#00e0e07&|d|1| +0#0000000&|{+0#e000e06&| +0#0000000&@50 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51 diff --git a/runtime/syntax/testdir/dumps/sh_functions_mksh_00.dump b/runtime/syntax/testdir/dumps/sh_functions_mksh_00.dump index ac300ee600..5cb6c2fd49 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_mksh_00.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_mksh_00.dump @@ -4,17 +4,17 @@ | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 | +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| +0#0000000&|-+0#e000e06&|i|1|0| +0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| +0#0000000&@56 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 -| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(+0#e000e06&|)| +0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&| |d|o@1|s|i|e| @47 +| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(+0#e000e06&|)| +0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| +0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| |d|o|n|e@1| @46 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64 +| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(+0#e000e06&|)| +0#0000000&@64 | +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 |i|s|_|k|o|r|n|s|h|e|l@1|:| |1|,| |i|s|_|m|k|s|h|:| |1|,| @28|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_functions_mksh_01.dump b/runtime/syntax/testdir/dumps/sh_functions_mksh_01.dump index 3426afb1af..e72cee2b18 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_mksh_01.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_mksh_01.dump @@ -1,19 +1,19 @@ ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 +| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(+0#e000e06&|)| +0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| |w|h|i|l|e|s| @32 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 +|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(+0#e000e06&|)| +0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56 ||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| +0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| |e|l|s|e|w|h|e|r|e| @51 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 +|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(+0#e000e06&|)| +0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| |d+0#af5f00255&|o| +0#0000000&@42 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| +0#0000000&@63 ||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| |0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| |2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 +| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(+0#e000e06&|)| +0#0000000&|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| +0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| |c|a|s|e|d| @33 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 -| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66 +| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(+0#e000e06&|)| +0#0000000&@66 | +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| +0#0000000&@60 |-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70 ||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67 diff --git a/runtime/syntax/testdir/dumps/sh_functions_mksh_02.dump b/runtime/syntax/testdir/dumps/sh_functions_mksh_02.dump index 5fed5e6358..aa72e6f518 100644 --- a/runtime/syntax/testdir/dumps/sh_functions_mksh_02.dump +++ b/runtime/syntax/testdir/dumps/sh_functions_mksh_02.dump @@ -3,9 +3,9 @@ | +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68 | +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72 |-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| |:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62 -||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3>%+0#00e0e07&@2|(|)| +0#0000000&@63 +||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3>%+0#00e0e07&@2|(+0#e000e06&|)| +0#0000000&@63 |-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|(+0#af5f00255&| +0#0000000&@67 -|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|@+0#00e0e07&|a|:|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@48 +|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|@+0#00e0e07&|a|:|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@48 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51 |3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#e000e06&| +0#0000000&@63 |2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|@|a|:| |"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@56 diff --git a/runtime/syntax/testdir/dumps/sh_generic_07.dump b/runtime/syntax/testdir/dumps/sh_generic_07.dump index 7589946109..6c7c45c6c1 100644 --- a/runtime/syntax/testdir/dumps/sh_generic_07.dump +++ b/runtime/syntax/testdir/dumps/sh_generic_07.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| |$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| +0#0000000&@43 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|e+0#af5f00255&|v|a|l| +0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| |2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| +0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9 -@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 +@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50 @8|}+0#e000e06&| +0#0000000&@65 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| |t|e|n|}| +0#0000000&@43 diff --git a/runtime/syntax/testdir/dumps/sh_generic_10.dump b/runtime/syntax/testdir/dumps/sh_generic_10.dump index cf4178f5e5..dbd1f398df 100644 --- a/runtime/syntax/testdir/dumps/sh_generic_10.dump +++ b/runtime/syntax/testdir/dumps/sh_generic_10.dump @@ -1,5 +1,5 @@ | +0&#ffffff0@74 -|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 +|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 @8|t+0#af5f00255&|r|u|e| +0#0000000&@62 |}+0#e000e06&| +0#0000000&@73 @75 @@ -15,6 +15,6 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| +0#0000000&@37 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|3|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|f+0#00e0e07&|o@1|3|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 @57|1|5|4|,|1| @8|7|9|%| diff --git a/runtime/syntax/testdir/dumps/sh_generic_11.dump b/runtime/syntax/testdir/dumps/sh_generic_11.dump index f1eb6e296d..fcb44b04ca 100644 --- a/runtime/syntax/testdir/dumps/sh_generic_11.dump +++ b/runtime/syntax/testdir/dumps/sh_generic_11.dump @@ -1,7 +1,7 @@ | +0&#ffffff0@7|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|4|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 +|f+0#00e0e07&|o@1|4|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@24 >}+0#e000e06&| +0#0000000&@73 @75 @@ -9,7 +9,7 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@20 |}+0#e000e06&| +0#0000000&@73 @75 -|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 +|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |s|u|b|s|h|e|l@1| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@21 |)+0#af5f00255&| +0#0000000&@73 @75 diff --git a/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump b/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump index 187550a491..20ebec5e04 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| |$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| +0#0000000&@43 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|e+0#af5f00255&|v|a|l| +0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| |2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| +0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9 -@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 +@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50 @8|}+0#e000e06&| +0#0000000&@65 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| |t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43 diff --git a/runtime/syntax/testdir/dumps/sh_ksh2020_10.dump b/runtime/syntax/testdir/dumps/sh_ksh2020_10.dump index cf4178f5e5..dbd1f398df 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh2020_10.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh2020_10.dump @@ -1,5 +1,5 @@ | +0&#ffffff0@74 -|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 +|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 @8|t+0#af5f00255&|r|u|e| +0#0000000&@62 |}+0#e000e06&| +0#0000000&@73 @75 @@ -15,6 +15,6 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| +0#0000000&@37 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|3|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|f+0#00e0e07&|o@1|3|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 @57|1|5|4|,|1| @8|7|9|%| diff --git a/runtime/syntax/testdir/dumps/sh_ksh2020_11.dump b/runtime/syntax/testdir/dumps/sh_ksh2020_11.dump index f1eb6e296d..fcb44b04ca 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh2020_11.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh2020_11.dump @@ -1,7 +1,7 @@ | +0&#ffffff0@7|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|4|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 +|f+0#00e0e07&|o@1|4|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@24 >}+0#e000e06&| +0#0000000&@73 @75 @@ -9,7 +9,7 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@20 |}+0#e000e06&| +0#0000000&@73 @75 -|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 +|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |s|u|b|s|h|e|l@1| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@21 |)+0#af5f00255&| +0#0000000&@73 @75 diff --git a/runtime/syntax/testdir/dumps/sh_ksh88_07.dump b/runtime/syntax/testdir/dumps/sh_ksh88_07.dump index f2b2a7f5d2..f70edcc3d8 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh88_07.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh88_07.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| |$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| +0#0000000&@43 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|e+0#af5f00255&|v|a|l| +0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| |2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| +0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9 -@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 +@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50 @8|}+0#e000e06&| +0#0000000&@65 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| |t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43 diff --git a/runtime/syntax/testdir/dumps/sh_ksh88_10.dump b/runtime/syntax/testdir/dumps/sh_ksh88_10.dump index 54507b7d6e..b7fefdea5d 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh88_10.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh88_10.dump @@ -15,6 +15,6 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| +0#0000000&@37 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|3|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|f+0#00e0e07&|o@1|3|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 @57|1|5|4|,|1| @8|7|9|%| diff --git a/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump b/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump index 187550a491..20ebec5e04 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| |$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| +0#0000000&@43 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|e+0#af5f00255&|v|a|l| +0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| |2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| +0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9 -@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 +@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50 @8|}+0#e000e06&| +0#0000000&@65 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| |t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43 diff --git a/runtime/syntax/testdir/dumps/sh_ksh93_generic_10.dump b/runtime/syntax/testdir/dumps/sh_ksh93_generic_10.dump index cf4178f5e5..dbd1f398df 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93_generic_10.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93_generic_10.dump @@ -1,5 +1,5 @@ | +0&#ffffff0@74 -|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 +|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 @8|t+0#af5f00255&|r|u|e| +0#0000000&@62 |}+0#e000e06&| +0#0000000&@73 @75 @@ -15,6 +15,6 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| +0#0000000&@37 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|3|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|f+0#00e0e07&|o@1|3|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 @57|1|5|4|,|1| @8|7|9|%| diff --git a/runtime/syntax/testdir/dumps/sh_ksh93_generic_11.dump b/runtime/syntax/testdir/dumps/sh_ksh93_generic_11.dump index f1eb6e296d..fcb44b04ca 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93_generic_11.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93_generic_11.dump @@ -1,7 +1,7 @@ | +0&#ffffff0@7|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|4|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 +|f+0#00e0e07&|o@1|4|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@24 >}+0#e000e06&| +0#0000000&@73 @75 @@ -9,7 +9,7 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@20 |}+0#e000e06&| +0#0000000&@73 @75 -|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 +|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |s|u|b|s|h|e|l@1| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@21 |)+0#af5f00255&| +0#0000000&@73 @75 diff --git a/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump b/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump index 187550a491..20ebec5e04 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| |$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| +0#0000000&@43 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|e+0#af5f00255&|v|a|l| +0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| |2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| +0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9 -@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 +@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50 @8|}+0#e000e06&| +0#0000000&@65 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| |t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43 diff --git a/runtime/syntax/testdir/dumps/sh_ksh93u_10.dump b/runtime/syntax/testdir/dumps/sh_ksh93u_10.dump index cf4178f5e5..dbd1f398df 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93u_10.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93u_10.dump @@ -1,5 +1,5 @@ | +0&#ffffff0@74 -|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 +|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 @8|t+0#af5f00255&|r|u|e| +0#0000000&@62 |}+0#e000e06&| +0#0000000&@73 @75 @@ -15,6 +15,6 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| +0#0000000&@37 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|3|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|f+0#00e0e07&|o@1|3|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 @57|1|5|4|,|1| @8|7|9|%| diff --git a/runtime/syntax/testdir/dumps/sh_ksh93u_11.dump b/runtime/syntax/testdir/dumps/sh_ksh93u_11.dump index f1eb6e296d..fcb44b04ca 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93u_11.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93u_11.dump @@ -1,7 +1,7 @@ | +0&#ffffff0@7|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|4|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 +|f+0#00e0e07&|o@1|4|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@24 >}+0#e000e06&| +0#0000000&@73 @75 @@ -9,7 +9,7 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@20 |}+0#e000e06&| +0#0000000&@73 @75 -|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 +|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |s|u|b|s|h|e|l@1| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@21 |)+0#af5f00255&| +0#0000000&@73 @75 diff --git a/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump b/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump index 187550a491..20ebec5e04 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| |$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| +0#0000000&@43 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|e+0#af5f00255&|v|a|l| +0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| |2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| +0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9 -@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 +@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50 @8|}+0#e000e06&| +0#0000000&@65 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| |t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43 diff --git a/runtime/syntax/testdir/dumps/sh_ksh93v_10.dump b/runtime/syntax/testdir/dumps/sh_ksh93v_10.dump index cf4178f5e5..dbd1f398df 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93v_10.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93v_10.dump @@ -1,5 +1,5 @@ | +0&#ffffff0@74 -|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 +|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 @8|t+0#af5f00255&|r|u|e| +0#0000000&@62 |}+0#e000e06&| +0#0000000&@73 @75 @@ -15,6 +15,6 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| +0#0000000&@37 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|3|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|f+0#00e0e07&|o@1|3|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 @57|1|5|4|,|1| @8|7|9|%| diff --git a/runtime/syntax/testdir/dumps/sh_ksh93v_11.dump b/runtime/syntax/testdir/dumps/sh_ksh93v_11.dump index f1eb6e296d..fcb44b04ca 100644 --- a/runtime/syntax/testdir/dumps/sh_ksh93v_11.dump +++ b/runtime/syntax/testdir/dumps/sh_ksh93v_11.dump @@ -1,7 +1,7 @@ | +0&#ffffff0@7|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|4|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 +|f+0#00e0e07&|o@1|4|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@24 >}+0#e000e06&| +0#0000000&@73 @75 @@ -9,7 +9,7 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@20 |}+0#e000e06&| +0#0000000&@73 @75 -|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 +|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |s|u|b|s|h|e|l@1| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@21 |)+0#af5f00255&| +0#0000000&@73 @75 diff --git a/runtime/syntax/testdir/dumps/sh_mksh_07.dump b/runtime/syntax/testdir/dumps/sh_mksh_07.dump index 7589946109..6c7c45c6c1 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_07.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_07.dump @@ -3,7 +3,7 @@ |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| |$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| +0#0000000&@43 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| +0#0000000&|e+0#af5f00255&|v|a|l| +0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| |2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| +0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9 -@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 +@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@52 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50 @8|}+0#e000e06&| +0#0000000&@65 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| |t|e|n|}| +0#0000000&@43 diff --git a/runtime/syntax/testdir/dumps/sh_mksh_10.dump b/runtime/syntax/testdir/dumps/sh_mksh_10.dump index 665c13ad92..f037f91d2b 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_10.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_10.dump @@ -1,5 +1,5 @@ | +0&#ffffff0@74 -|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 +|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@57 @8|t+0#af5f00255&|r|u|e| +0#0000000&@62 |}+0#e000e06&| +0#0000000&@73 @75 @@ -7,7 +7,7 @@ @8|f+0#af5f00255&|a|l|s|e| +0#0000000&@61 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|f+0#00e0e07&|o@1|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@58 +|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|f+0#00e0e07&|o@1|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@58 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |B|a|s|h|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| |(|m|k|s|h|-|o|n|l|y|)| +0#0000000&@30 |}+0#e000e06&| +0#0000000&@73 @75 @@ -15,6 +15,6 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |f|u|n|c|t|i|o|n| +0#0000000&@37 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|3|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|f+0#00e0e07&|o@1|3|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 @57|1|5|4|,|1| @8|7|9|%| diff --git a/runtime/syntax/testdir/dumps/sh_mksh_11.dump b/runtime/syntax/testdir/dumps/sh_mksh_11.dump index 4730aa2763..8ce924e8b9 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_11.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_11.dump @@ -1,7 +1,7 @@ | +0&#ffffff0@7|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X| |f|u|n|c|t|i|o|n| +0#0000000&@47 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#00e0e07&|o@1|4|.|g|e|t|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 +|f+0#00e0e07&|o@1|4|.|g|e|t|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@62 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@24 >}+0#e000e06&| +0#0000000&@73 @75 @@ -9,7 +9,7 @@ @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |K|o|r|n|S|h|e|l@1|-|s|t|y|l|e| |k|s|h|9|3| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@20 |}+0#e000e06&| +0#0000000&@73 @75 -|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 +|_+0#00e0e07&|f|o@1|6|.|u|n|s|e|t|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@59 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |P|O|S|I|X|-|s|t|y|l|e| |s|u|b|s|h|e|l@1| |d|i|s|c|i|p|l|i|n|e| |f|u|n|c|t|i|o|n| +0#0000000&@21 |)+0#af5f00255&| +0#0000000&@73 @75 diff --git a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_00.dump b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_00.dump index 1af1bd6b4e..73b9046cf8 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_00.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_00.dump @@ -3,18 +3,18 @@ @75 |#+0#0000e05&| |V|a|l|i|d| |f|u|n|c|t|i|o|n| |n|a|m|e|s| +0#0000000&@52 @75 -|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|7+0#00e0e07&|f|o|@|o|.|f|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@54 +|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|7+0#00e0e07&|f|o|@|o|.|f|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@54 @8|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|G+0#e000002&|i|b@1|e|r|i|s|h| |n|o|t|-|K|o|r|n|S|h|e|l@1| |f|u|n|c|t|i|o|n| |(|t|h|e| |e|n|d|i|n|g| |'|(|)|'| |i|s| |a| |b|a|s|h|i|s |m| |m|k|s|h| |a|l@1|o|w|s|)|"+0#af5f00255&| +0#0000000&@59 |}+0#e000e06&| +0#0000000&@73 -|!+0#00e0e07&|:|@|-|+|.|8|v|f|o|%|o|,|_|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@56 +|!+0#00e0e07&|:|@|-|+|.|8|v|f|o|%|o|,|_|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@56 @8|e+0#af5f00255&|c|h|o| +0#e000002&|'+0#af5f00255&|G+0#e000002&|i|b@1|e|r|i|s|h| |P|O|S|I|X| |f|u|n|c|t|i|o|n|'+0#af5f00255&| +0#0000000&@35 |}+0#e000e06&| +0#0000000&@73 @75 -|,+0#00e0e07&|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 +|,+0#00e0e07&|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|a+0#00e0e07&|%|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@58 +|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|a+0#00e0e07&|%|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@58 @8|f|o@1| @63 |i|s|_|k|o|r|n|s|h|e|l@1|:| |1|,| |i|s|_|m|k|s|h|:| |1|,| @28|1|,|1| @10|T|o|p| diff --git a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_01.dump b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_01.dump index beae9b47d5..205bbcc961 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_01.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_01.dump @@ -1,20 +1,20 @@ -|,+0#00e0e07#ffffff0|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 +|,+0#00e0e07#ffffff0|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|a+0#00e0e07&|%|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@58 +|f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|a+0#00e0e07&|%|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@58 @8>f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|%+0#00e0e07&|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 +|%+0#00e0e07&|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|.+0#00e0e07&|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 +|.+0#00e0e07&|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|-+0#00e0e07&|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 +|-+0#00e0e07&|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @57|1|8|,|2|-|9| @7|1@1|%| diff --git a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_02.dump b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_02.dump index 2aeb5366cb..232bc86758 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_02.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_02.dump @@ -1,20 +1,20 @@ |}+0#e000e06#ffffff0| +0#0000000&@73 @75 -|_+0#00e0e07&|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 +|_+0#00e0e07&|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@69 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 > @74 -|++0#00e0e07&|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 +|++0#00e0e07&|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|.+0#00e0e07&|b|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 +|.+0#00e0e07&|b|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|!+0#00e0e07&|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 +|!+0#00e0e07&|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|@+0#00e0e07&|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 +|@+0#00e0e07&|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 @57|3|6|,|0|-|1| @7|2|8|%| diff --git a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_03.dump b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_03.dump index 8225b5869e..3f61dfaeec 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_03.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_03.dump @@ -1,20 +1,20 @@ -|@+0#00e0e07#ffffff0|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 +|@+0#00e0e07#ffffff0|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|!+0#00e0e07&@1|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@67 +|!+0#00e0e07&@1|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@67 @8>f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|!+0#00e0e07&|a|!|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|!+0#00e0e07&|a|!|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|@+0#00e0e07&|a|@@1|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@65 +|@+0#00e0e07&|a|@@1|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@65 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @75 -|++0#00e0e07&|a|+|a|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 +|++0#00e0e07&|a|+|a|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@66 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 @57|5|4|,|2|-|9| @7|4@1|%| diff --git a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_04.dump b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_04.dump index 0e1dd04131..c04f2881fe 100644 --- a/runtime/syntax/testdir/dumps/sh_mksh_gibberish_04.dump +++ b/runtime/syntax/testdir/dumps/sh_mksh_gibberish_04.dump @@ -1,6 +1,6 @@ |}+0#e000e06#ffffff0| +0#0000000&@73 @75 -|a+0#00e0e07&|:|(|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 +|a+0#00e0e07&|:|(+0#e000e06&|)| +0#0000000&|{+0#e000e06&| +0#0000000&@68 @8|f|o@1| @63 |}+0#e000e06&| +0#0000000&@73 > @74 diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_01.dump b/runtime/syntax/testdir/dumps/vim_ex_def_01.dump index f13f4f4e3c..92211445a8 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_def_01.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_def_01.dump @@ -17,4 +17,4 @@ @75 |d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@55 |e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68 -@57|1|9|,|1| @9|1|2|%| +@57|1|9|,|1| @9|1@1|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_02.dump b/runtime/syntax/testdir/dumps/vim_ex_def_02.dump index 14cffbda09..0f575f8436 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_def_02.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_def_02.dump @@ -17,4 +17,4 @@ |e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68 @75 |d+0#af5f00255&|e|f| +0#0000000&|<+0#e000e06&|S|I|D|>|F+0#0000000&|o@1|(+0#e000e06&|)|:+0#0000000&| |n+0#00e0003&|u|m|b|e|r| +0#0000000&@52 -@57|3|7|,|0|-|1| @7|2|8|%| +@57|3|7|,|0|-|1| @7|2|7|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_03.dump b/runtime/syntax/testdir/dumps/vim_ex_def_03.dump index 4ab6ef5e9b..3c325f4809 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_def_03.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_def_03.dump @@ -17,4 +17,4 @@ |e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68 @75 |d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&|)|:+0#0000000&| |v+0#00e0003&|o|i|d| +0#0000000&|#+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@49 -@57|5@1|,|3| @9|4|5|%| +@57|5@1|,|3| @9|4|2|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_04.dump b/runtime/syntax/testdir/dumps/vim_ex_def_04.dump index 6b5e93d8dc..cccc2bad10 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_def_04.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_def_04.dump @@ -17,4 +17,4 @@ @75 |d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@65 |e+0#af5f00255&|n|d@1|e|f| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@55 -@57|7|3|,|0|-|1| @7|6|2|%| +@57|7|3|,|0|-|1| @7|5|8|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_05.dump b/runtime/syntax/testdir/dumps/vim_ex_def_05.dump index 6519226746..56950e93fa 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_def_05.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_def_05.dump @@ -17,4 +17,4 @@ @75 |"+0#0000e05&| |I|s@1|u|e| |#|1|6|2|4|3| |(|V|i|m| |s|c|r|i|p|t| |d|e|f| |p|a|r|a|m|e|t|e|r|s| |s|y|n|t|a|x| |h|i|g|h|l|i|g|h|t| |i|s| |w|r|o|n|g|)| +0#0000000&@6 @75 -@57|9|0|,|0|-|1| @7|7|8|%| +@57|9|0|,|0|-|1| @7|7|3|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_06.dump b/runtime/syntax/testdir/dumps/vim_ex_def_06.dump index 3c4b3ab06c..317bb43f31 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_def_06.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_def_06.dump @@ -17,4 +17,4 @@ |e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68 @75 @75 -@57|1|0|8|,|1| @8|9|5|%| +@57|1|0|8|,|1| @8|8|9|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_def_07.dump b/runtime/syntax/testdir/dumps/vim_ex_def_07.dump index 87f3964bd0..381b7ae553 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_def_07.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_def_07.dump @@ -4,17 +4,17 @@ |s+0#af5f00255&|i|l|e|n|t|!| +0#0000000&|d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@57 |e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68 > @74 +@75 +|"+0#0000e05&| |U|n|r|e|p|o|r|t|e|d| |i|s@1|u|e| |(|r|e|t|u|r|n| |t|y|p|e| |c|o|l|o|n| |m|u|s|t| |f|o|l@1|o|w| |i|m@1|e|d|i|a|t|e|l|y| |a|f|t|e|r| |c|l|o|s|i|n|g +| |p|a|r|a|m|e|t|e|r|-|l|i|s|t| |p|a|r|e|n|)| +0#0000000&@52 +@75 +|d+0#af5f00255&|e|f| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@65 +|:| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|n|o|t| |a| |m|i|s|m|a|t|c|h|e|d| |r|e|t|u|r|n| |t|y|p|e|"| +0#0000000&@37 +|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68 +@75 |~+0#4040ff13&| @73 |~| @73 |~| @73 |~| @73 |~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 | +0#0000000&@56|1|2|6|,|0|-|1| @6|B|o|t| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_06.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_06.dump index 67ba95814c..3bcb86e4e3 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_06.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_06.dump @@ -17,4 +17,4 @@ @6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d| +0#0000000&@57 @6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d|i|n| |o|p|t|i|o|n| +0#0000000&@47 @6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d|i|n|=|t+0#0000001#ffff4012|e|s|t|C|o|n|t|a|i|n|e|r| +0#0000000#ffffff0@41 -@57|1|0|5|,|0|-|1| @6|2|7|%| +@57|1|0|5|,|0|-|1| @6|2|6|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_07.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_07.dump index 696f88cb07..a4be8bb7d6 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_07.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_07.dump @@ -17,4 +17,4 @@ @6|"+0#0000e05&|\| |k|e|y|w|o|r|d| |3| +0#0000000&@56 @6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|3| @58 @75 -@57|1|2@1|,|7| @8|3|2|%| +@57|1|2@1|,|7| @8|3|1|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_08.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_08.dump index 156ff01e59..744f23d907 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_08.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_08.dump @@ -17,4 +17,4 @@ @6|"+0#0000e05&|\| |c@1|h|a|r| |o|p|t|i|o|n| +0#0000000&@53 @6|\+0#e000e06&| +0#0000000&|c+0#e000e06&@1|h|a|r|=|&+0#e000002&| +0#0000000&@59 @6|"+0#0000e05&|\| |c|o|n|t|a|i|n|e|d| |o|p|t|i|o|n| +0#0000000&@49 -@57|1|4|0|,|7| @8|3|7|%| +@57|1|4|0|,|7| @8|3|6|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump index a7ed5c811e..e42e016cc4 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_09.dump @@ -17,4 +17,4 @@ @6|"+0#0000e05&|\| +0#0000000&|f+0#0000e05&|o|l|d| +0#0000000&|o+0#0000e05&|p|t|i|o|n| +0#0000000&@54 @6|\+0#e000e06&| +0#0000000&|f+0#e000e06&|o|l|d| +0#0000000&@62 @6|"+0#0000e05&|\| |d|i|s|p|l|a|y| |o|p|t|i|o|n| +0#0000000&@51 -@57|1|5|8|,|7| @8|4|2|%| +@57|1|5|8|,|7| @8|4|1|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_10.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_10.dump index 7031132d74..983f1d5faf 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_10.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_10.dump @@ -17,4 +17,4 @@ @6|\+0#e000e06&| +0#0000000&|e+0#00e0003&|n|d|=|"+0#e000002&|e|n|d|-|p|a|t@1|e|r|n|"| +0#0000000&@49 @6|"+0#0000e05&|\| |c|o|n|c|e|a|l| |o|p|t|i|o|n| +0#0000000&@51 @6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|c|e|a|l| +0#0000000&@59 -@57|1|7|6|,|7| @8|4|7|%| +@57|1|7|6|,|7| @8|4|5|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_11.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_11.dump index c14f06636a..1e7ba63640 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_11.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_11.dump @@ -17,4 +17,4 @@ @6|\+0#e000e06&| +0#0000000&|s+0#e000e06&|k|i|p|n|l| +0#0000000&@60 @6|"+0#0000e05&|\| |c|o|n|t|a|i|n|s| |o|p|t|i|o|n| +0#0000000&@50 @6|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|s|=|t+0#0000001#ffff4012|e|s|t|C|o|n|t|a|i|n|e|d|1|,|t|e|s|t|C|o|n|t|a|i|n|e|d|2| +0#0000000#ffffff0@28 -@57|1|9|4|,|7| @8|5|2|%| +@57|1|9|4|,|7| @8|5|0|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_12.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_12.dump index 28a905a8f8..a7489b5653 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_12.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_12.dump @@ -17,4 +17,4 @@ |s+0#af5f00255&|y|n| +0#0000000&|c+0#00e0003&|l|u|s|t|e|r| +0#0000000&|t|e|s|t|C|l|u|s|t|e|r| @51 @6|"+0#0000e05&|\| |O|P|T|I|O|N|S| +0#0000000&@58 @6|"+0#0000e05&|\| |c|o|n|t|a|i|n|s| |o|p|t|i|o|n| +0#0000000&@50 -@57|2|1|2|,|7| @8|5|7|%| +@57|2|1|2|,|7| @8|5@1|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_13.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_13.dump index e828336806..c9068bdb5f 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_13.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_13.dump @@ -17,4 +17,4 @@ |s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t|e|s|t|N|e|x|t|3| |k|e|y|w|o|r|d| @45 |s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t|e|s|t|N|e|x|t|4| |k|e|y|w|o|r|d| @45 |s+0#af5f00255&|y|n| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|t|e|s|t|N|e|x|t|5| |k|e|y|w|o|r|d| @45 -@57|2|3|0|,|7| @8|6|2|%| +@57|2|3|0|,|7| @8|6|0|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_14.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_14.dump index f648fee758..13cf00d224 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_14.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_14.dump @@ -17,4 +17,4 @@ @6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|4| @58 @6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|5| @58 @6|\+0#e000e06&| +0#0000000&|k|e|y|w|o|r|d|6| @58 -@57|2|4|8|,|0|-|1| @6|6|7|%| +@57|2|4|8|,|0|-|1| @6|6|5|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_15.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_15.dump index 6945ec2c62..4bec90ecb3 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_15.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_15.dump @@ -17,4 +17,4 @@ @6|\+0#e000e06&| +0#0000000&|t+0#0000001#ffff4012|e|x|t|N|e|x|t|6|,+0#0000000#ffffff0| @56 @6|"+0#0000e05&|\| +0#0000000&|c+0#0000e05&|o|m@1|e|n|t| +0#0000000&@58 @6|\+0#e000e06&| +0#0000000&|t+0#0000001#ffff4012|e|x|t|N|e|x|t|7| +0#0000000#ffffff0|,| @55 -@57|2|6@1|,|7| @8|7|2|%| +@57|2|6@1|,|7| @8|7|0|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_16.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_16.dump index 3d1a002d69..8d668d55a1 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_16.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_16.dump @@ -17,4 +17,4 @@ @6|\+0#e000e06&| +0#0000000&|,| |t+0#0000001#ffff4012|e|x|t|N|e|x|t|1|7| +0#0000000#ffffff0|,| |t+0#0000001#ffff4012|e|x|t|N|e|x|t|1|8| +0#0000000#ffffff0|,| @39 @6|"+0#0000e05&|\| +0#0000000&|c+0#0000e05&|o|m@1|e|n|t| +0#0000000&@58 @6|\+0#e000e06&| +0#0000000&|t+0#0000001#ffff4012|e|x|t|N|e|x|t|1|9|,+0#0000000#ffffff0| |@+0#0000001#ffff4012|t|e|s|t|C|l|u|s|t|e|r| +0#0000000#ffffff0@42 -@57|2|8|4|,|7| @8|7@1|%| +@57|2|8|4|,|7| @8|7|5|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_17.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_17.dump index c923c00d45..056116d2a6 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_17.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_17.dump @@ -17,4 +17,4 @@ |f+0#af5f00255&|u|n|c|t|i|o|n|!| +0#0000000&|s+0#e000e06&|:|C+0#0000000&|o|n|t|a|i|n|e|d|G|r|o|u|p|(+0#e000e06&|)| +0#0000000&@46 @2|"+0#0000e05&| |.@2| +0#0000000&@67 @2|f+0#af5f00255&|o|r| +0#0000000&|c+0#00e0e07&|l|u|s|t|e|r| +0#0000000&|i+0#af5f00255&|n| +0#0000000&|[+0#e000e06&|'+0#e000002&|m|a|r|k|d|o|w|n|H|i|g|h|l|i|g|h|t|_|z|s|h|'|,+0#0000000&| |'+0#e000002&|z|s|h|'|]+0#e000e06&| +0#0000000&@25 -@57|3|0|2|,|7| @8|8|2|%| +@57|3|0|2|,|7| @8|8|0|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_18.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_18.dump index 605dc0cba1..e96cf04d38 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_18.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_18.dump @@ -17,4 +17,4 @@ |"+0#0000e05&| |I|s@1|u|e| |#|1|8|4|9|1| |(|T|w|o| |"+0#e000002&|)|"|s+0#0000e05&| |a|r|e| |i|n|c|o|r@1|e|c|t|l|y| |c|o|l|o|r|e|d| |'|v|i|m|O|p|e|r|E|r@1|o|r|'| |i|n| |s|y|n|t|a|x|/|m |a|i|l|.|v|i|m|)| +0#0000000&@66 @75 -@57|3|2|0|,|0|-|1| @6|8|7|%| +@57|3|2|0|,|0|-|1| @6|8|4|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_19.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_19.dump index 3dbd5826bf..34b80d9e2e 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_19.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_19.dump @@ -17,4 +17,4 @@ @75 |"+0#0000e05&| |C|o|d|e| |>| |K|e|y|w|o|r|d|s| |{@2|2| +0#0000000&@52 |s+0#af5f00255&|y|n|t|a|x| +0#0000000&|c+0#00e0003&|l|u|s|t|e|r| +0#0000000&|t|y|p|s|t|C|o|d|e|K|e|y|w|o|r|d|s| @42 -@57|3@1|6|,|1| @8|9|2|%| +@57|3@1|6|,|1| @8|8|9|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_20.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_20.dump index e05dc99127..ed355d795c 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_20.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_20.dump @@ -17,4 +17,4 @@ @4|\+0#e000e06&| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|s|=| +0#0000000&@59 @12|"+0#0000e05&|\| +0#0000000&|c+0#0000e05&|o|m@1|e|n|t| +0#0000000&@52 @12|\+0#e000e06&| +0#0000000&@1|t+0#0000001#ffff4012|y|p|s|t|C|o|d|e|C|o|n|d|i|t|i|o|n|a|l| +0#0000000#ffffff0@39 -@57|3|5|4|,|0|-|1| @6|9|7|%| +@57|3|5|4|,|0|-|1| @6|9|4|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_21.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_21.dump index e0746ea9d6..20477577ec 100644 --- a/runtime/syntax/testdir/dumps/vim_ex_syntax_21.dump +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_21.dump @@ -11,10 +11,10 @@ |s+0#af5f00255&|y|n| +0#0000000&|r+0#00e0003&|e|g|i|o|n| +0#0000000&@1|s|l|r|n|r|c|C|m|d|L|i|n|e| @6|m+0#e000e06&|a|t|c|h|g|r|o|u|p|=|s+0#0000000&|l|r|n|r|c|C|m|d| |s+0#00e0003&|t|a|r|t|=|"+0#e000002&|\|<|\+0#e000e06&|(|a+0#e000002&|u|t|o|b|a|u|d|\+0#e000e06&|||.+0#e000002& @2|\+0#e000e06&|||v+0#e000002&|i|s|i|b|l|e|_|h|e|a|d|e|r|s|\+0#e000e06&|)|\+0#e000002&|>|"| +0#0000000&|e+0#00e0003&|n|d|=|"+0#e000002&|$|"| +0#0000000&|o+0#e000e06&|n|e|l|i|n|e| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|s|=|s+0#0000001#ffff4012|l|r|n|r|c|\|(|S|t|r|i|n|g|\|||C|o|m@1|e|n|t|\|) | +0#0000000#ffffff0@74 -|~+0#4040ff13&| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -|~| @73 -| +0#0000000&@56|3|7|2|,|0|-|1| @6|B|o|t| +|"+0#0000e05&| |:|s|y|n|t|a|x| |k|e|y|w|o|r|d| |—| |o|n|e|l|i|n|e| |a|c@1|e|p|t|e|d| |b|u|t| |m|e|a|n|i|n|g|l|e|s@1| +0#0000000&@22 +|s+0#af5f00255&|y|n|t|a|x| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|T|e|s|t|K|w| |f|o@1| |b|a|r| |o+0#ffffff16#ff404010|n|e|l|i|n|e| +0#0000000#ffffff0@37 +|s+0#af5f00255&|y|n|t|a|x| +0#0000000&|k+0#00e0003&|e|y|w|o|r|d| +0#0000000&|T|e|s|t|K|w|2| |o+0#ffffff16#ff404010|n|e|l|i|n|e| +0#0000000#ffffff0|b|a|z| |q|u@1|x| @35 +@75 +|"+0#0000e05&| |:|s|y|n|t|a|x| |m|a|t|c|h| |—| |o|n|e|l|i|n|e| |a|c@1|e|p|t|e|d| |b|u|t| |m|e|a|n|i|n|g|l|e|s@1| +0#0000000&@24 +|s+0#af5f00255&|y|n|t|a|x| +0#0000000&|m+0#00e0003&|a|t|c|h| +0#0000000&|T|e|s|t|M|a|t|c|h| |/+0#e000002&|\|<|f|o@1|\|>|/| +0#0000000&|o+0#ffffff16#ff404010|n|e|l|i|n|e| +0#0000000#ffffff0@34 +@57|3|7|2|,|0|-|1| @6|9|8|%| diff --git a/runtime/syntax/testdir/dumps/vim_ex_syntax_22.dump b/runtime/syntax/testdir/dumps/vim_ex_syntax_22.dump new file mode 100644 index 0000000000..7c1765f636 --- /dev/null +++ b/runtime/syntax/testdir/dumps/vim_ex_syntax_22.dump @@ -0,0 +1,20 @@ +|s+0#af5f00255#ffffff0|y|n|t|a|x| +0#0000000&|m+0#00e0003&|a|t|c|h| +0#0000000&|T|e|s|t|M|a|t|c|h| |/+0#e000002&|\|<|f|o@1|\|>|/| +0#0000000&|o+0#ffffff16#ff404010|n|e|l|i|n|e| +0#0000000#ffffff0@34 +|s+0#af5f00255&|y|n|t|a|x| +0#0000000&|m+0#00e0003&|a|t|c|h| +0#0000000&|T|e|s|t|M|a|t|c|h|2| |o+0#ffffff16#ff404010|n|e|l|i|n|e| +0#0000000#ffffff0|/+0#e000002&|\|<|b|a|r|\|>|/| +0#0000000&@33 +@75 +|"+0#0000e05&| |:|s|y|n|t|a|x| |r|e|g|i|o|n| |—| |o|n|e|l|i|n|e| |i|s| |m|e|a|n|i|n|g|f|u|l| |h|e|r|e| +0#0000000&@29 +|s+0#af5f00255&|y|n|t|a|x| +0#0000000&|r+0#00e0003&|e|g|i|o|n| +0#0000000&|T|e|s|t|R|e|g|i|o|n| |s+0#00e0003&|t|a|r|t|=|/+0#e000002&|{|/| +0#0000000&|e+0#00e0003&|n|d|=|/+0#e000002&|}|/| +0#0000000&|o+0#e000e06&|n|e|l|i|n|e| +0#0000000&@24 +>s+0#af5f00255&|y|n|t|a|x| +0#0000000&|r+0#00e0003&|e|g|i|o|n| +0#0000000&|T|e|s|t|R|e|g|i|o|n|2| |o+0#e000e06&|n|e|l|i|n|e| +0#0000000&|s+0#00e0003&|t|a|r|t|=|/+0#e000002&|"|/| +0#0000000&|e+0#00e0003&|n|d|=|/+0#e000002&|"|/| +0#0000000&@23 +|s+0#af5f00255&|y|n|t|a|x| +0#0000000&|r+0#00e0003&|e|g|i|o|n| +0#0000000&|T|e|s|t|R|e|g|i|o|n|3| |s+0#00e0003&|t|a|r|t|=|/+0#e000002&|\|/|\|*|/| +0#0000000&|e+0#00e0003&|n|d|=|/+0#e000002&|\|*|\|/@1| +0#0000000&|o+0#e000e06&|n|e|l|i|n|e| +0#0000000&|c+0#e000e06&|o|n|t|a|i|n|e|d|i|n|=|A|L@1| +0#0000000&@1 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|3|8@1|,|1| @8|B|o|t| diff --git a/runtime/syntax/testdir/input/algol68_all_preludes.a68 b/runtime/syntax/testdir/input/algol68_all_preludes.a68 new file mode 100644 index 0000000000..557aabc0ba --- /dev/null +++ b/runtime/syntax/testdir/input/algol68_all_preludes.a68 @@ -0,0 +1,2114 @@ +# + Algol 68 prelude identifier from the Genie source code files. + + Provided as a base to verify the correct syntax highlighting + of the algol68.vim syntax file for the Vim editor. + + There's four sections, each representing an original file, + that are enclosed in the Unix-'more' form to stand out. + + Some informal comments from the source code left intact as + a comment in Algol 68 syntax. + + Depending on the language context there's duplicates in the + list, that are kept for clarity given the associated informal + comment associated with them. + + Some entries deliberately contain two identifier variants that + may be used as alternative form in an Algol 68 Genie program. + + The identifiers are presented in two variants separated by a + tabulator; first with spaces, then in canonical form without + spaces. Variants with spaces are supported by the Vim syntax + file as the Algol 68 language does. + But note that while Algol 68 allows arbitrary spacing within + identifiers - even as extreme as writing one character per + line! - the Vim syntax file for Algol 68 had deliberately + been defined in a way restricting the highlighted options; + spacing can usually be inserted where "natural words" would + allow a separation (say for 'intwidth' you may write, e.g., + 'int width' but not 'int wid th'; the latter would not get + highlighted). + + Modelines are set to simply inspect the correct highlighting + in this file. + + Janis Papanagnou, 2026-05-19 +# + +#::::::::::::: +prelude.c +:::::::::::::# + +# Primitive A68 moids. # + VOID VOID +# Standard precision. # + INT INT + REAL REAL + COMPLEX COMPLEX + COMPL COMPL + BITS BITS + BYTES BYTES +# Multiple precision. # + INT INT + REAL REAL + COMPLEX COMPLEX + COMPL COMPL + BITS BITS + BYTES BYTES + REAL REAL + INT INT + COMPLEX COMPLEX + COMPL COMPL + BITS BITS +# Other. # + BOOL BOOL + CHAR CHAR + STRING STRING + FILE FILE + CHANNEL CHANNEL + PIPE PIPE + FORMAT FORMAT + SEMA SEMA + SOUND SOUND +# Identifiers. # + long long pi; qpi; longlongpi; qpi +# # + bits lengths; bitslengths + bits shorths; bitsshorths + bits width; bitswidth + bytes lengths; byteslengths + bytes shorths; bytesshorths + bytes width; byteswidth + compl lengths; compllengths + compl shorths; complshorths + exp width; expwidth + infinity; infinity + inf; inf + int lengths; intlengths + int shorths; intshorths + int width; intwidth + long bits width; longbitswidth + long bytes width; longbyteswidth + long exp width; longexpwidth + long int width; longintwidth + long long expwidth; longlongexpwidth + long long infinity; longlonginfinity + long long inf; longlonginf + long long intwidth; longlongintwidth + long long maxint; longlongmaxint + long long maxreal; longlongmaxreal + long long mininf; longlongmininf + long long minreal; longlongminreal + long long minus infinity; longlongminusinfinity + long long real width; longlongrealwidth + long long small real; longlongsmallreal + long real width; longrealwidth + max abs char; maxabschar + max bits; maxbits + max int; maxint + max real; maxreal + min inf; mininf + min real; minreal + minus infinity; minusinfinity + mpradix; mpradix + nan; nan + pi; pi + real lengths; reallengths + real shorths; realshorths + real width; realwidth + small real; smallreal + clock; clock + cpu time; cputime + seconds; seconds + wall clock; wallclock + wall seconds; wallseconds + wall time; walltime + blocks; blocks + collections; collections + collect seconds; collectseconds + garbage; garbage + garbage collections; garbagecollections + garbage freed; garbagefreed + garbage refused; garbagerefused + garbage seconds; garbageseconds + on gc event; ongcevent + sweeps; sweeps + sweeps refused; sweepsrefused + stack pointer; stackpointer + system stack pointer; systemstackpointer + system stack size; systemstacksize + actual stack size; actualstacksize + heap pointer; heappointer + system heap pointer; systemheappointer + gc heap; gcheap + sweep heap; sweepheap + preemptive gc; preemptivegc + preemptive sweep; preemptivesweep + preemptive sweepheap; preemptivesweepheap + backtrace; backtrace + break; break + debug; debug + monitor; monitor + abend; abend + evaluate; evaluate + system; system + sleep; sleep +# Machine environ parameters. # + i32mach; i32mach + r64mach; r64mach + i64mach; i64mach + r128mach; r128mach +# BITS procedures. # + bits pack; bitspack +# RNG procedures. # + first random; firstrandom + next random; nextrandom + random; random + rnd; rnd + long long nextrandom; longlongnextrandom + long long random; longlongrandom +# Priorities. # +# INT ops. # + + + + - - + ABS ABS + SIGN SIGN + ODD ODD + = = + /= /= + ~= ~= + ^= ^= + < < + <= <= + > > + >= >= + EQ EQ + NE NE + LT LT + LE LE + GT GT + GE GE + + + + - - + * * + OVER OVER + % % + MOD MOD + %* %* + ** ** + UP UP + ^ ^ + / / + +:= +:= + -:= -:= + *:= *:= + %:= %:= + %*:= %*:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + OVERAB OVERAB + MODAB MODAB +# REAL ops. # + + + + - - + ABS ABS + SIGN SIGN + ROUND ROUND + ENTIER ENTIER + FLOOR FLOOR + CEIL CEIL + NINT NINT + TRUNC TRUNC + FRAC FRAC + FIX FIX + = = + /= /= + ~= ~= + ^= ^= + < < + <= <= + > > + >= >= + EQ EQ + NE NE + LT LT + LE LE + GT GT + GE GE + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + ** ** + UP UP + ^ ^ + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB +# Procedures # + arc cos dg; acos dg; arccosdg; acosdg + arc cosh; acosh; arccosh; acosh + arc cot; acot; arccot; acot + arc cot dg; acot dg; arccotdg; acotdg + arc csc; acsc; arccsc; acsc + arc csc dg; acsc dg; arccscdg; acscdg + arc sec; asec; arcsec; asec + arc sec dg; asec dg; arcsecdg; asecdg + arc sin dg; asin dg; arcsindg; asindg + arc sinh; asinh; arcsinh; asinh + arc tan dg; atan dg; arctandg; atandg + arc tanh; atanh; arctanh; atanh + arc cos; acos; arccos; acos + arc sin; asin; arcsin; asin + arc tan; atan; arctan; atan + cas; cas + cbrt; cbrt + cos dg; cosdg + cosh; cosh + cos pi; cospi + cot dg; cotdg + cot; cot + cot pi; cotpi + csc dg; cscdg + csc; csc + curt; curt + erfc; erfc + erf; erf + gamma; gamma + inv erfc; inverfc + inv erf; inverf + inverse erfc; inverseerfc + inverse erf; inverseerf + ln1p; ln1p + ln gamma; lngamma + sec dg; secdg + sec; sec + sin dg; sindg + sinh; sinh + sin pi; sinpi + tan dg; tandg + tanh; tanh + tan pi; tanpi + cos; cos + exp; exp + ln; ln + log; log + sin; sin + sqrt; sqrt + tan; tan +# Miscellaneous. # + arc tan2; atan2; arctan2; atan2 + arc tan2 dg; atan2 dg; arctan2dg; atan2dg + beta; beta + betainc; betainc + choose; choose + fact; fact + gamma inc; gammainc + gamma incf; gammaincf + gamma incg; gammaincg + gamma incgf; gammaincgf + lje126; lje126 + ljf126; ljf126 + ln beta; lnbeta + ln choose; lnchoose + ln fact; lnfact +# COMPLEX ops. # + I I + +* +* + I I + +* +* + RE RE + IM IM + ABS ABS + ARG ARG + + + + - - + CONJ CONJ + = = + /= /= + ~= ~= + ^= ^= + EQ EQ + NE NE + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB + complex arccosh; cacosh; complexarccosh; cacosh + complex arccos; cacos; complexarccos; cacos + complex arcsinh; casinh; complexarcsinh; casinh + complex arcsin; casin; complexarcsin; casin + complex arctanh; catanh; complexarctanh; catanh + complex arctan; catan; complexarctan; catan + complex cosh; ccosh; complexcosh; ccosh + complex cos; ccos; complexcos; ccos + complex exp; cexp; complexexp; cexp + complex ln; cln; complexln; cln + complex sinh; csinh; complexsinh; csinh + complex sin; csin; complexsin; csin + complex sqrt; csqrt; complexsqrt; csqrt + complex tanh; ctanh; complextanh; ctanh + complex tan; ctan; complextan; ctan +# BOOL ops. # + NOT NOT + ~ ~ + ABS ABS + OR OR + AND AND + & & + XOR XOR + = = + /= /= + ~= ~= + ^= ^= + EQ EQ + NE NE +# CHAR ops. # + = = + /= /= + ~= ~= + ^= ^= + < < + <= <= + > > + >= >= + EQ EQ + NE NE + LT LT + LE LE + GT GT + GE GE + ABS ABS + REPR REPR + is alnum; isalnum + is alpha; isalpha + is cntrl; iscntrl + is digit; isdigit + is graph; isgraph + is lower; islower + is print; isprint + is punct; ispunct + is space; isspace + is upper; isupper + is xdigit; isxdigit + to lower; tolower + to upper; toupper +# BITS ops. # + ABS ABS + BIN BIN + NOT NOT + ~ ~ + = = + /= /= + ~= ~= + ^= ^= + <= <= + >= >= + EQ EQ + NE NE + LE LE + GE GE + < < + > > + LT LT + GT GT + AND AND + & & + OR OR + XOR XOR + + + + - - + * * + OVER OVER + MOD MOD + SHL SHL + UP UP + SHR SHR + DOWN DOWN + ROL ROL + ROR ROR + ELEM ELEM + SET SET + CLEAR CLEAR +# LONG LONG INT in software # + + + + - - + ABS ABS + SIGN SIGN + ODD ODD + ENTIER ENTIER + ROUND ROUND + + + + - - + * * + OVER OVER + % % + MOD MOD + %* %* + +:= +:= + -:= -:= + *:= *:= + %:= %:= + %*:= %*:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + OVERAB OVERAB + MODAB MODAB + / / + EQ EQ + NE NE + GE GE + GT GT + LE LE + LT LT + = = + >= >= + > > + <= <= + < < + /= /= + ^= ^= + ~= ~= + ** ** + UP UP + ^ ^ + I I + +* +* +# LONG LONG REAL in software # + ABS ABS + + + + - - + SIGN SIGN + long long arccosdg; qacos dg; longlongarccosdg; qacosdg + long long arccosh; qacosh; longlongarccosh; qacosh + long long arccotdg; qacot dg; longlongarccotdg; qacotdg + long long arccot; qacot; longlongarccot; qacot + long long arccscdg; qacsc dg; longlongarccscdg; qacscdg + long long arccsc; qacsc; longlongarccsc; qacsc + long long arcsecdg; qasec dg; longlongarcsecdg; qasecdg + long long arcsec; qasec; longlongarcsec; qasec + long long arcsindg; qasin dg; longlongarcsindg; qasindg + long long arcsinh; qasinh; longlongarcsinh; qasinh + long long arctandg; qatan dg; longlongarctandg; qatandg + long long arctanh; qatanh; longlongarctanh; qatanh + long long cas; qcas; longlongcas; qcas + long long cbrt; qcbrt; longlongcbrt; qcbrt + long long cosdg; qcos dg; longlongcosdg; qcosdg + long long cosh; qcosh; longlongcosh; qcosh + long long cospi; qcos pi; longlongcospi; qcospi + long long cotdg; qcot dg; longlongcotdg; qcotdg + long long cotpi; qcot pi; longlongcotpi; qcotpi + long long cot; qcot; longlongcot; qcot + long long cscdg; qcsc dg; longlongcscdg; qcscdg + long long csc; qcsc; longlongcsc; qcsc + long long curt; qcurt; longlongcurt; qcurt + long long erfc; qerfc; longlongerfc; qerfc + long long erf; qerf; longlongerf; qerf + long long gamma; qgamma; longlonggamma; qgamma + long long inverfc; qinverfc; longlonginverfc; qinverfc + long long inverf; qinverf; longlonginverf; qinverf + long long lngamma; qlngamma; longlonglngamma; qlngamma + long long secdg; qsec dg; longlongsecdg; qsecdg + long long sec; qsec; longlongsec; qsec + long long sindg; qsin dg; longlongsindg; qsindg + long long sinh; qsinh; longlongsinh; qsinh + long long sinpi; qsin pi; longlongsinpi; qsinpi + long long tandg; qtan dg; longlongtandg; qtandg + long long tanh; qtanh; longlongtanh; qtanh + long long tanpi; qtan pi; longlongtanpi; qtanpi + long long arccos; qacos; longlongarccos; qacos + long long arcsin; qasin; longlongarcsin; qasin + long long arctan; qatan; longlongarctan; qatan + long long cos; qcos; longlongcos; qcos + long long exp; qexp; longlongexp; qexp + long long ln; qln; longlongln; qln + long long log; qlog; longlonglog; qlog + long long sin; qsin; longlongsin; qsin + long long sqrt; qsqrt; longlongsqrt; qsqrt + long long tan; qtan; longlongtan; qtan + long long arctan2dg; qatan2dg; longlongarctan2dg; qatan2dg + long long arctan2; qatan2; longlongarctan2; qatan2 + long long beta; qbeta; longlongbeta; qbeta + long long gamma incf; qgammaincf; longlonggammaincf; qgammaincf + long long gamma incgf; qgammaincgf; longlonggammaincgf; qgammaincgf + long long gamma inc; qgammainc; longlonggammainc; qgammainc + long long ln beta; qlnbeta; longlonglnbeta; qlnbeta + long long beta inc; qbetainc; longlongbetainc; qbetainc + long long gamma incg; qgammaincg; longlonggammaincg; qgammaincg + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + < < + LT LT + <= <= + LE LE + > > + GT GT + >= >= + GE GE + ** ** + UP UP + ^ ^ + I I + +* +* +# LONG LONG COMPLEX in software # + RE RE + IM IM + ARG ARG + ABS ABS + + + + - - + CONJ CONJ + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB + long long complex arc cosh; qcacosh; longlongcomplexarccosh; qcacosh + long long complex arc cos; qcacos; longlongcomplexarccos; qcacos + long long complex arc sinh; qcasinh; longlongcomplexarcsinh; qcasinh + long long complex arc sin; qcasin; longlongcomplexarcsin; qcasin + long long complex arc tanh; qcatanh; longlongcomplexarctanh; qcatanh + long long complex arc tan; qcatan; longlongcomplexarctan; qcatan + long long complex cosh; qccosh; longlongcomplexcosh; qccosh + long long complex cos; qccos; longlongcomplexcos; qccos + long long complex exp; qcexp; longlongcomplexexp; qcexp + long long complex ln; qcln; longlongcomplexln; qcln + long long complex sinh; qcsinh; longlongcomplexsinh; qcsinh + long long complex sin; qcsin; longlongcomplexsin; qcsin + long long complex sqrt; qcsqrt; longlongcomplexsqrt; qcsqrt + long long complex tanh; qctanh; longlongcomplextanh; qctanh + long long complex tan; qctan; longlongcomplextan; qctan +# BYTES ops. # + bytespack; bytespack + ELEM ELEM + + + + +:= +:= + PLUSAB PLUSAB + +=: +=: + PLUSTO PLUSTO + = = + /= /= + ~= ~= + ^= ^= + < < + <= <= + > > + >= >= + EQ EQ + NE NE + LT LT + LE LE + GT GT + GE GE +# LONG BYTES ops. # + LENG LENG + SHORTEN SHORTEN + long bytes pack; longbytespack + ELEM ELEM + + + + +:= +:= + PLUSAB PLUSAB + +=: +=: + PLUSTO PLUSTO + = = + /= /= + ~= ~= + ^= ^= + < < + <= <= + > > + >= >= + EQ EQ + NE NE + LT LT + LE LE + GT GT + GE GE +# STRING ops. # + = = + /= /= + ~= ~= + ^= ^= + < < + <= <= + >= >= + > > + EQ EQ + NE NE + LT LT + LE LE + GE GE + GT GT + + + + +:= +:= + PLUSAB PLUSAB + *:= *:= + TIMESAB TIMESAB + +=: +=: + PLUSTO PLUSTO + * * + ELEM ELEM + real path; realpath +# SEMA ops. # + LEVEL LEVEL + UP UP + DOWN DOWN + LEVEL LEVEL + UP UP + DOWN DOWN +# ROWS ops. # + ELEMS ELEMS + LWB LWB + UPB UPB + ELEMS ELEMS + LWB LWB + UPB UPB + SORT SORT +# Some "terminators # + LENG LENG + SHORTEN SHORTEN +# SOUND/RIFF procs. # + newsound; newsound + getsound; getsound + setsound; setsound + RESOLUTION RESOLUTION + CHANNELS CHANNELS + RATE RATE + SAMPLES SAMPLES +# Set up standenv - transput. # + long pi; dpi; longpi; dpi + long max bits; longmaxbits + long max int; longmaxint + long small real; longsmallreal + long max real; longmaxreal + long min real; longminreal + long infinity; longinfinity + long minus infinity; longminusinfinity + long inf; longinf + long min inf; longmininf +# LONG INT in software # + + + + - - + ABS ABS + LENG LENG + SHORTEN SHORTEN + SIGN SIGN + LENG LENG + SHORTEN SHORTEN + LENG LENG + SHORTEN SHORTEN + ODD ODD + ENTIER ENTIER + ROUND ROUND + + + + - - + * * + OVER OVER + % % + MOD MOD + %* %* + +:= +:= + -:= -:= + *:= *:= + %:= %:= + %*:= %*:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + OVERAB OVERAB + MODAB MODAB + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + < < + LT LT + <= <= + LE LE + > > + GT GT + >= >= + GE GE + / / + ** ** + UP UP + ^ ^ + I I + +* +* + LENG LENG + SHORTEN SHORTEN +# LONG REAL in software # + + + + - - + ABS ABS + long arc cos dg; dacos dg; longarccosdg; dacosdg + long arc cosh; dacosh; longarccosh; dacosh + long arc cot; dacot; longarccot; dacot + long arc cot dg; dacot dg; longarccotdg; dacotdg + long arc csc; dacsc; longarccsc; dacsc + long arc csc dg; dacsc dg; longarccscdg; dacscdg + long arc sec; dasec; longarcsec; dasec + long arc sec dg; dasec dg; longarcsecdg; dasecdg + long arc sin dg; dasin dg; longarcsindg; dasindg + long arc sinh; dasinh; longarcsinh; dasinh + long arc tan dg; datan dg; longarctandg; datandg + long arc tanh; datanh; longarctanh; datanh + long cas; dcas; longcas; dcas + long cbrt; dcbrt; longcbrt; dcbrt + long cos dg; dcos dg; longcosdg; dcosdg + long cosh; dcosh; longcosh; dcosh + long cos pi; dcos pi; longcospi; dcospi + long cot; dcot; longcot; dcot + long cot dg; dcot dg; longcotdg; dcotdg + long cot pi; dcot pi; longcotpi; dcotpi + long csc; dcsc; longcsc; dcsc + long csc dg; dcsc dg; longcscdg; dcscdg + long curt; dcurt; longcurt; dcurt + long erfc; derfc; longerfc; derfc + long erf; derf; longerf; derf + long gamma; dgamma; longgamma; dgamma + long inv erfc; dinverfc; longinverfc; dinverfc + long inv erf; dinverf; longinverf; dinverf + long ln gamma; dlngamma; longlngamma; dlngamma + long sec dg; dsec dg; longsecdg; dsecdg + long sec; dsec; longsec; dsec + long sin dg; dsin dg; longsindg; dsindg + long sinh; dsinh; longsinh; dsinh + long sin pi; dsin pi; longsinpi; dsinpi + long tan dg; dtan dg; longtandg; dtandg + long tanh; dtanh; longtanh; dtanh + long tan pi; dtan pi; longtanpi; dtanpi +# RR. # + long arc cos; dacos; longarccos; dacos + long arc sin; dasin; longarcsin; dasin + long arc tan; datan; longarctan; datan + long cos; dcos; longcos; dcos + long exp; dexp; longexp; dexp + long ln; dln; longln; dln + long log; dlog; longlog; dlog + long sin; dsin; longsin; dsin + long sqrt; dsqrt; longsqrt; dsqrt + long tan; dtan; longtan; dtan + long next random; longnextrandom + long random; longrandom + long arc tan2; datan2; longarctan2; datan2 + long arc tan2 dg; datan2dg; longarctan2dg; datan2dg + long beta; dbeta; longbeta; dbeta + long gamma inc; dgammainc; longgammainc; dgammainc + long gamma incf; dgammaincf; longgammaincf; dgammaincf + long gamma incgf; dgammaincgf; longgammaincgf; dgammaincgf + long ln beta; dlnbeta; longlnbeta; dlnbeta + long beta inc; dbetainc; longbetainc; dbetainc + long gamma incg; dgammaincg; longgammaincg; dgammaincg + SIGN SIGN + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + < < + LT LT + <= <= + LE LE + > > + GT GT + >= >= + GE GE + ** ** + UP UP + ^ ^ + I I + +* +* +# LONG COMPLEX in software # + LENG LENG + SHORTEN SHORTEN + LENG LENG + SHORTEN SHORTEN + RE RE + IM IM + ARG ARG + ABS ABS + + + + - - + CONJ CONJ + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB + long complex arc cos; dcacos; longcomplexarccos; dcacos + long complex arc cosh; dcacosh; longcomplexarccosh; dcacosh + long complex arc sin; dcasin; longcomplexarcsin; dcasin + long complex arc sinh; dcasinh; longcomplexarcsinh; dcasinh + long complex arc tan; dcatan; longcomplexarctan; dcatan + long complex arc tanh; dcatanh; longcomplexarctanh; dcatanh + long complex cos; dccos; longcomplexcos; dccos + long complex cosh; dccosh; longcomplexcosh; dccosh + long complex exp; dcexp; longcomplexexp; dcexp + long complex ln; dcln; longcomplexln; dcln + long complex sin; dcsin; longcomplexsin; dcsin + long complex sinh; dcsin; longcomplexsinh; dcsin + long complex sqrt; dcsqrt; longcomplexsqrt; dcsqrt + long complex tan; dctan; longcomplextan; dctan + long complex tanh; dctanh; longcomplextanh; dctanh +# LONG BITS in software # + longbitspack; longbitspack + ABS ABS + BIN BIN + SHORTEN SHORTEN + LENG LENG + NOT NOT + ~ ~ + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + <= <= + LE LE + >= >= + GE GE + AND AND + & & + OR OR + XOR XOR + SHL SHL + UP UP + SHR SHR + DOWN DOWN + ELEM ELEM + SET SET + CLEAR CLEAR + long pi; dpi; longpi; dpi + long max bits; longmaxbits + long max int; longmaxint + long small real; longsmallreal + long max real; longmaxreal + long min real; longminreal + long infinity; longinfinity + long minus infinity; longminusinfinity + long inf; longinf + long min inf; longmininf +# LONG INT as 128 bit # + + + + - - + ABS ABS + LENG LENG + SHORTEN SHORTEN + SIGN SIGN + ODD ODD + ENTIER ENTIER + ROUND ROUND + + + + - - + * * + OVER OVER + % % + MOD MOD + %* %* + ** ** + UP UP + ^ ^ + +:= +:= + -:= -:= + *:= *:= + %:= %:= + %*:= %*:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + OVERAB OVERAB + MODAB MODAB + / / + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + < < + LT LT + <= <= + LE LE + > > + GT GT + >= >= + GE GE +# LONG REAL as 128 bit # + + + + - - + ABS ABS + SIGN SIGN + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + ** ** + UP UP + ^ ^ + LENG LENG + SHORTEN SHORTEN + LENG LENG + SHORTEN SHORTEN + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + < < + LT LT + <= <= + LE LE + > > + GT GT + >= >= + GE GE + long arc cos dg; dacos dg; longarccosdg; dacosdg + long arc cosh; dacosh; longarccosh; dacosh + long arc cot dg; dacot dg; longarccotdg; dacotdg + long arc cot; dacot; longarccot; dacot + long arc csc; dacsc; longarccsc; dacsc + long arc csc dg; dacsc dg; longarccscdg; dacscdg + long arc sec dg; dasec dg; longarcsecdg; dasecdg + long arc sin dg; dasin dg; longarcsindg; dasindg + long arc sinh; dasinh; longarcsinh; dasinh + long arc tan dg; datan dg; longarctandg; datandg + long arc tanh; datanh; longarctanh; datanh + long cbrt; dcbrt; longcbrt; dcbrt + long cos dg; dcos dg; longcosdg; dcosdg + long cosh; dcosh; longcosh; dcosh + long cos pi; dcos pi; longcospi; dcospi + long cot dg; dcot dg; longcotdg; dcotdg + long cot; dcot; longcot; dcot + long cot pi; dcot pi; longcotpi; dcotpi + long csc; dcsc; longcsc; dcsc + long csc dg; dcsc dg; longcscdg; dcscdg + long curt; dcurt; longcurt; dcurt + long erfc; derfc; longerfc; derfc + long erf; derf; longerf; derf + long inv erfc; dinverfc; longinverfc; dinverfc + long inv erf; dinverf; longinverf; dinverf + long gamma; dgamma; longgamma; dgamma + long ln gamma; dlngamma; longlngamma; dlngamma + long sec; dsec; longsec; dsec + long sec dg; dsec dg; longsecdg; dsecdg + long sin dg; dsin dg; longsindg; dsindg + long sinh; dsinh; longsinh; dsinh + long sin pi; dsin pi; longsinpi; dsinpi + long tan dg; dtan dg; longtandg; dtandg + long tanh; dtanh; longtanh; dtanh + long tan pi; dtan pi; longtanpi; dtanpi + long arc cos; dacos; longarccos; dacos + long arc sin; dasin; longarcsin; dasin + long arc tan; datan; longarctan; datan + long cas; dcas; longcas; dcas + long cos; dcos; longcos; dcos + long exp; dexp; longexp; dexp + long ln; dln; longln; dln + long log; dlog; longlog; dlog + long sin; dsin; longsin; dsin + long sqrt; dsqrt; longsqrt; dsqrt + long tan; dtan; longtan; dtan + long next random; longnextrandom + long random; longrandom + long arc tan2 dg; datan2dg; longarctan2dg; datan2dg + long arc tan2; datan2; longarctan2; datan2 + long beta; dbeta; longbeta; dbeta + long gamma incgf; dgammaincgf; longgammaincgf; dgammaincgf + long gamma incf; dgammaincf; longgammaincf; dgammaincf + long gamma inc; dgammainc; longgammainc; dgammainc + long ln beta; dlnbeta; longlnbeta; dlnbeta + long beta inc; dbetainc; longbetainc; dbetainc + long gamma incg; dgammaincg; longgammaincg; dgammaincg +# LONG BITS as 128 bit # + long bits pack; longbitspack + SHORTEN SHORTEN + LENG LENG + ABS ABS + BIN BIN + NOT NOT + ~ ~ + AND AND + & & + OR OR + XOR XOR + + + + - - + * * + OVER OVER + MOD MOD + = = + /= /= + ~= ~= + ^= ^= + <= <= + >= >= + EQ EQ + NE NE + LE LE + GE GE + < < + > > + LT LT + GT GT + ELEM ELEM + SET SET + CLEAR CLEAR + SHL SHL + UP UP + SHR SHR + DOWN DOWN + ROL ROL + ROR ROR +# LONG COMPLEX as 2 x 128 bit. # + LENG LENG + SHORTEN SHORTEN + I I + +* +* + I I + +* +* + RE RE + IM IM + ABS ABS + ARG ARG + + + + - - + CONJ CONJ + = = + /= /= + ~= ~= + ^= ^= + EQ EQ + NE NE + + + + - - + * * + / / + ** ** + UP UP + ^ ^ + +:= +:= + -:= -:= + *:= *:= + /:= /:= + PLUSAB PLUSAB + MINUSAB MINUSAB + TIMESAB TIMESAB + DIVAB DIVAB + long complex arc cosh; dcacosh; longcomplexarccosh; dcacosh + long complex arc cos; dcacos; longcomplexarccos; dcacos + long complex arc sinh; dcasinh; longcomplexarcsinh; dcasinh + long complex arc sin; dcasin; longcomplexarcsin; dcasin + long complex arc tanh; dcatanh; longcomplexarctanh; dcatanh + long complex arc tan; dcatan; longcomplexarctan; dcatan + long complex atanh; dcatanh; longcomplexatanh; dcatanh + long complex cosh; dccosh; longcomplexcosh; dccosh + long complex cos; dccos; longcomplexcos; dccos + long complex exp; dcexp; longcomplexexp; dcexp + long complex ln; dcln; longcomplexln; dcln + long complex sinh; dcsinh; longcomplexsinh; dcsinh + long complex sin; dcsin; longcomplexsin; dcsin + long complex sqrt; dcsqrt; longcomplexsqrt; dcsqrt + long complex tanh; dctanh; longcomplextanh; dctanh + long complex tan; dctan; longcomplextan; dctan + mpfr long gamma inc; mpfr dgammainc; mpfrlonggammainc; mpfrdgammainc + mpfr long long beta; mpfr qbeta; mpfrlonglongbeta; mpfrqbeta + mpfr long long gammainc; mpfr qgammainc; mpfrlonglonggammainc; mpfrqgammainc + mpfr long long lnbeta; mpfr qlnbeta; mpfrlonglonglnbeta; mpfrqlnbeta + mpfr long long betainc; mpfr qbetainc; mpfrlonglongbetainc; mpfrqbetainc + mpfr long long erfc; mpfr qerfc; mpfrlonglongerfc; mpfrqerfc + mpfr long long erf; mpfr qerf; mpfrlonglongerf; mpfrqerf + mpfr long long gamma; mpfr qgamma; mpfrlonglonggamma; mpfrqgamma + mpfr long long inverfc; mpfr qinverfc; mpfrlonglonginverfc; mpfrqinverfc + mpfr long long inverf; mpfr qinverf; mpfrlonglonginverf; mpfrqinverf + mpfr long long lngamma; mpfr qlngamma; mpfrlonglonglngamma; mpfrqlngamma + mpfr mp; mpfrmp + blank character; blankcharacter + formfeed character; formfeedcharacter + formfeed char; formfeedchar + newline character; newlinecharacter + newline char; newlinechar + null character; nullcharacter + tab character; tabcharacter + tab char; tabchar + blank char; blankchar + blank; blank + eof character; eofcharacter + eof char; eofchar + error char; errorchar + exp char; expchar + flip; flip + flop; flop + null char; nullchar + bits; bits + whole; whole + fixed; fixed + float; float + real; real + stand in; standin + stand out; standout + stand back; standback + stand error; standerror + stand in channel; standinchannel + stand out channel; standoutchannel + stand draw channel; standdrawchannel + stand back channel; standbackchannel + stand error channel; standerrorchannel + make term; maketerm + char in string; charinstring + last char in string; lastcharinstring + string in string; stringinstring + idf; idf + term; term + program idf; programidf +# Event routines. # + on file end; onfileend + on page end; onpageend + on line end; onlineend + on logical file end; onlogicalfileend + on physical file end; onphysicalfileend + on format end; onformatend + on format error; onformaterror + on value error; onvalueerror + on open error; onopenerror + on transput error; ontransputerror +# Enquiries on files. # + draw possible; drawpossible + end of file; endoffile + end of line; endofline + eof; eof + eoln; eoln + rewind possible; rewindpossible + bin possible; binpossible + compressible; compressible + get possible; getpossible + put possible; putpossible + reidf possible; reidfpossible + reset possible; resetpossible + set possible; setpossible +# Handling of files. # + open; open + append; append + establish; establish + associate; associate + cooked; cooked + raw; raw + rewind; rewind + backspace; backspace + close; close + create; create + erase; erase + lock; lock + newline; newline + newpage; newpage + reset; reset + scratch; scratch + space; space + set; set + seek; seek + read; read + read bin; readbin + readf; readf + print bin; printbin + printf; printf + print; print + write bin; writebin + writef; writef + write; write + get; get + getf; getf + get bin; getbin + put; put + putf; putf + put bin; putbin + gets; gets + getsf; getsf + puts; puts + putsf; putsf + string; string + stringf; stringf + read line; readline +# Set up standenv - extensions. # +# UNIX things. # + rows; rows + columns; columns + argc; argc + a68g argc; a68gargc + errno; errno + fork; fork + get pwd; getpwd + set pwd; setpwd + file is directory; fileisdirectory + file is block device; fileisblockdevice + file is char device; fileischardevice + file is regular; fileisregular + file is fifo; fileisfifo + file is link; fileislink + file mode; filemode + argv; argv + a68g argv; a68gargv + reset errno; reseterrno + str error; strerror + exec; exec + execve; execve + create pipe; createpipe + exec sub; execsub + execve child; execvechild + exec sub pipeline; execsubpipeline + execve childpipe; execvechildpipe + exec sub output; execsuboutput + execve output; execveoutput + get env; getenv + wait pid; waitpid + utc time; utctime + local time; localtime + grep in string; grepinstring + grep in substring; grepinsubstring + sub in string; subinstring + peek char; peekchar + get directory; getdirectory + http timeout; httptimeout + https timeout; httpstimeout + http content; httpcontent + https content; httpscontent +# Drawing. # + draw device; drawdevice + make device; makedevice + draw aspect; drawaspect + draw clear; drawclear + draw erase; drawerase + draw flush; drawflush + draw show; drawshow + draw fill style; drawfillstyle + draw get colour name; drawgetcolourname + draw get color name; drawgetcolorname + draw color; drawcolor + draw colour; drawcolour + draw background color; drawbackgroundcolor + draw background colour; drawbackgroundcolour + draw circle; drawcircle + draw ball; drawball + draw star; drawstar + draw point; drawpoint + draw line; drawline + draw move; drawmove + draw rect; drawrect + draw text; drawtext + draw linestyle; drawlinestyle + draw font name; drawfontname + draw linewidth; drawlinewidth + draw font size; drawfontsize + draw text angle; drawtextangle + draw color name; drawcolorname + draw colour name; drawcolourname + draw background color name; drawbackgroundcolorname + draw background colour name; drawbackgroundcolourname + curses start; cursesstart + curses end; cursesend + curses clear; cursesclear + curses refresh; cursesrefresh + curses green; cursesgreen + curses cyan; cursescyan + curses red; cursesred + curses yellow; cursesyellow + curses magenta; cursesmagenta + curses blue; cursesblue + curses white; curseswhite + curses green inverse; cursesgreeninverse + curses cyan inverse; cursescyaninverse + curses red inverse; cursesredinverse + curses yellow inverse; cursesyellowinverse + curses magenta inverse; cursesmagentainverse + curses blue inverse; cursesblueinverse + curses white inverse; curseswhiteinverse + curses get char; cursesgetchar + curses put char; cursesputchar + curses move; cursesmove + curses lines; curseslines + curses columns; cursescolumns + curses delchar; cursesdelchar + pq connect db; pqconnectdb + pq finish; pqfinish + pq reset; pqreset + pq parameter status; pqparameterstatus + pq exec; pqexec + pq fnumber; pqfnumber + pq ntuples; pqntuples + pq nfields; pqnfields + pq cmd status; pqcmdstatus + pq cmd tuples; pqcmdtuples + pq error message; pqerrormessage + pq result error message; pqresulterrormessage + pq db; pqdb + pq user; pquser + pq pass; pqpass + pq host; pqhost + pq port; pqport + pq tty; pqtty + pq options; pqoptions + pq protocol version; pqprotocolversion + pq server version; pqserverversion + pq socket; pqsocket + pq backend pid; pqbackendpid + pq fname; pqfname + pq fformat; pqfformat + pq get value; pqgetvalue + pq get is null; pqgetisnull + sig segv; sigsegv + +#::::::::::::: +prelude-bits.c +:::::::::::::# + +# Multiple precision BITS. # + long long bits width; longlongbitswidth + long long max bits; longlongmaxbits + long long bits pack; longlongbitspack + LENG LENG + ABS ABS + BIN BIN + NOT NOT + ~ ~ + SHORTEN SHORTEN + = = + EQ EQ + /= /= + ~= ~= + ^= ^= + NE NE + <= <= + LE LE + >= >= + GE GE + AND AND + & & + OR OR + XOR XOR + SHL SHL + UP UP + SHR SHR + DOWN DOWN + ELEM ELEM + SET SET + CLEAR CLEAR + +#::::::::::::: +prelude-mathlib.c +:::::::::::::# + +# R specific special functions # + r di gamma; rdigamma + r tri gamma; rtrigamma + r tetra gamma; rtetragamma + r penta gamma; rpentagamma + r psi gamma; rpsigamma +# R distribution related functions # + r r t; rrt + r r chisq; rrchisq + r r exp; rrexp + r r geom; rrgeom + r r pois; rrpois + r r signrank; rrsignrank + r r beta; rrbeta + r r binom; rrbinom + r r cauchy; rrcauchy + r r f; rrf + r r logis; rrlogis + r r lnorm; rrlnorm + r rn binom; rrnbinom + r r norm; rrnorm + r r unif; rrunif + r r weibull; rrweibull + r r wilcox; rrwilcox + r d t; rdt + r d chisq; rdchisq + r d exp; rdexp + r d geom; rdgeom + r d pois; rdpois + r d norm; rdnorm + r d beta; rdbeta + r d binom; rdbinom + r dn chisq; rdnchisq + r d cauchy; rdcauchy + r d f; rdf + r d logis; rdlogis + r d lnorm; rdlnorm + r dn binom; rdnbinom + r d nt; rdnt + r d unif; rdunif + r d weibull; rdweibull + r d nf; rdnf + r d hyper; rdhyper + r r hyper; rrhyper + r p t; rpt + r q t; rqt + r p chisq; rpchisq + r q chisq; rqchisq + r p exp; rpexp + r q exp; rqexp + r p geom; rpgeom + r q geom; rqgeom + r p pois; rppois + r q pois; rqpois + r p norm; rpnorm + r q norm; rqnorm + r p beta; rpbeta + r q beta; rqbeta + r p binom; rpbinom + r q binom; rqbinom + r pn chisq; rpnchisq + r qn chisq; rqnchisq + r p cauchy; rpcauchy + r q cauchy; rqcauchy + r p f; rpf + r q f; rqf + r p logis; rplogis + r q logis; rqlogis + r p l norm; rplnorm + r q l norm; rqlnorm + r pn binom; rpnbinom + r qn binom; rqnbinom + r p nt; rpnt + r q nt; rqnt + r p unif; rpunif + r q unif; rqunif + r p weibull; rpweibull + r q weibull; rqweibull + r p tukey; rptukey + r q tukey; rqtukey + r p nf; rpnf + r q nf; rqnf + r p hyper; rphyper + r q hyper; rqhyper + r d sign rank; rdsignrank + r d wilcox; rdwilcox + r p sign rank; rpsignrank + r q sign rank; rqsignrank + r p wilcox; rpwilcox + r q wilcox; rqwilcox + +#::::::::::::: +prelude-gsl.c +:::::::::::::# + +# Standard prelude definitions from GSL. # + airy ai; airyai + airy ai scaled; airyaiscaled + airy bi; airybi + airy bi scaled; airybiscaled + bessel in0; besselin0 + bessel in1; besselin1 + bessel in0 scaled; besselin0scaled + bessel in1 scaled; besselin1scaled + bessel jn0; besseljn0 + bessel jn1; besseljn1 + bessel kn0; besselkn0 + bessel kn1; besselkn1 + bessel kn0 scaled; besselkn0scaled + bessel kn1 scaled; besselkn1scaled + bessel yn0; besselyn0 + bessel yn1; besselyn1 + expinte1; expinte1 + expintei; expintei + dawson; dawson + exprel; exprel + beta inc gsl; betaincgsl + poch; poch + digamma; digamma + airy ai derivative; airyaiderivative + airy ai deriv; airyaideriv + airy ai deriv scaled; airyaiderivscaled + airy bi derivative; airybiderivative + airy bi deriv; airybideriv + airy bi deriv scaled; airybiderivscaled + airy zero ai deriv; airyzeroaideriv + airy zero ai; airyzeroai + airy zero bi deriv; airyzerobideriv + airy zero bi; airyzerobi + angle restrict pos; anglerestrictpos + angle restrict symm; anglerestrictsymm + atan int; atanint + bessel il0 scaled; besselil0scaled + bessel il1 scaled; besselil1scaled + bessel il2 scaled; besselil2scaled + bessel il scaled; besselilscaled + bessel in; besselin + bessel in scaled; besselinscaled + bessel inu; besselinu + bessel inu scaled; besselinuscaled + bessel jl0; besseljl0 + bessel jl1; besseljl1 + bessel jl2; besseljl2 + bessel jl; besseljl + bessel jn; besseljn + bessel kl0 scaled; besselkl0scaled + bessel kl1 scaled; besselkl1scaled + bessel kl2 scaled; besselkl2scaled + bessel kl scaled; besselklscaled + bessel kn; besselkn + bessel kn scaled; besselknscaled + bessel kn_scaled; besselkn_scaled + bessel knu; besselknu + bessel knu scaled; besselknuscaled + bessel ln knu; bessellnknu + bessel yl0; besselyl0 + bessel yl1; besselyl1 + bessel yl2; besselyl2 + bessel yl; besselyl + bessel yn; besselyn + bessel ynu; besselynu + bessel zero j0; besselzeroj0 + bessel zero j1; besselzeroj1 + bessel zero jnu; besselzerojnu + chi; chi + ci; ci + clausen; clausen + conical p0; conicalp0 + conical p1; conicalp1 + conical pcylreg; conicalpcylreg + conical phalf; conicalphalf + conical pmhalf; conicalpmhalf + conical psphreg; conicalpsphreg + debye 1; debye1 + debye 2; debye2 + debye 3; debye3 + debye 4; debye4 + debye 5; debye5 + debye 6; debye6 + dilog; dilog + doublefact; doublefact + ellint d; ellintd + ellint ecomp; ellintecomp + ellint e; ellinte + ellint f; ellintf + ellint kcomp; ellintkcomp + ellint pcomp; ellintpcomp + ellint p; ellintp + ellint rc; ellintrc + ellint rd; ellintrd + ellint rf; ellintrf + ellint rj; ellintrj + etaint; etaint + eta; eta + expint 3; expint3 + expint e2; expinte2 + expint en; expinten + expm1; expm1 + exprel2; exprel2 + expreln; expreln + fermi dirac 0; fermidirac0 + fermi dirac 1; fermidirac1 + fermi dirac 2; fermidirac2 + fermi dirac 3half; fermidirac3half + fermi dirac half; fermidirachalf + fermi dirac inc0; fermidiracinc0 + fermi dirac int; fermidiracint + fermi dirac m1; fermidiracm1 + fermi dirac mhalf; fermidiracmhalf + gamma inc gsl; gammaincgsl + gamma inc p; gammaincp + gamma inc q; gammaincq + gamma inv; gammainv + gamma star; gammastar + gegenpoly 1 real; gegenpoly1real + gegenpoly 2 real; gegenpoly2real + gegenpoly 3 real; gegenpoly3real + gegenpoly n real; gegenpolynreal + hermite func; hermitefunc + hypot; hypot + hzeta; hzeta + laguerre 1 real; laguerre1real + laguerre 2 real; laguerre2real + laguerre 3 real; laguerre3real + laguerre n real; laguerrenreal + lambert w0; lambertw0 + lambert wm1; lambertwm1 + legendre h3d0; legendreh3d0 + legendre h3d1; legendreh3d1 + legendre h3d; legendreh3d + legendre p1; legendrep1 + legendre p2; legendrep2 + legendre p3; legendrep3 + legendre pl; legendrepl + legendre q0; legendreq0 + legendre q1; legendreq1 + legendre ql; legendreql + ln cosh; lncosh + ln doublefact; lndoublefact + ln poch; lnpoch + ln sinh; lnsinh + ln1 plusxmx; ln1plusxmx + ln1 plusx; ln1plusx + ln abs; lnabs + poch rel; pochrel + psi 1 int; psi1int + psi 1 piy; psi1piy + psi 1; psi1 + psi int; psiint + psin; psin + psi; psi + shi; shi + sinc; sinc + si; si + synchrotron 1; synchrotron1 + synchrotron 2; synchrotron2 + taylor coeff; taylorcoeff + transport 2; transport2 + transport 3; transport3 + transport 4; transport4 + transport 5; transport5 + zeta int; zetaint + zeta m1 int; zetam1int + zeta m1; zetam1 + zeta; zeta +# Vector and matrix pretty print. # + print vector; printvector + print matrix; printmatrix +# Vector and matrix monadic. # + + + + - - + CV CV + RV RV + + + + - - + T T + INV INV + PINV PINV + MEAN MEAN + DET DET + TRACE TRACE + + + + - - + + + + - - + T T + INV INV + DET DET + TRACE TRACE +# Vector and matrix dyadic. # + = = + /= /= + + + + - - + +:= +:= + PLUSAB PLUSAB + -:= -:= + MINUSAB MINUSAB + = = + /= /= + + + + - - + BEFORE BEFORE + ABOVE ABOVE + +:= +:= + PLUSAB PLUSAB + -:= -:= + MINUSAB MINUSAB + = = + /= /= + + + + - - + +:= +:= + PLUSAB PLUSAB + -:= -:= + MINUSAB MINUSAB + = = + /= /= + + + + - - + +:= +:= + PLUSAB PLUSAB + -:= -:= + MINUSAB MINUSAB +# Vector and matrix scaling. # + * * + / / + * * + / / + * * + / / + * * + / / + *:= *:= + /:= /:= + *:= *:= + /:= /:= + *:= *:= + /:= /:= + *:= *:= + /:= /:= + * * +# Matrix times vector or matrix. # + * * +# Vector and matrix miscellaneous. # + vector echo; vectorecho + matrix echo; matrixecho + compl vector echo; complvectorecho + compl matrix echo; complmatrixecho + * * + NORM NORM + DYAD DYAD +# Principle Component Analysis. # + pcacv; pcacv + pcasvd; pcasvd +# Total Least Square regression. # + ols; ols + tls; tls +# Partial Least Squares regression. # + pcr; pcr + pls1; pls1 + pls2; pls2 +# Routine left columns, a GSL alternative to trimming columns. # + left columns; leftcolumns +# Moore-Penrose pseudo inverse. # + pseudo inv; pseudoinv +# LU decomposition. # + lu decomp; ludecomp + lu det; ludet + lu inv; luinv + lu solve; lusolve + complex lu decomp; complexludecomp + complex lu det; complexludet + complex lu inv; complexluinv + complex lu solve; complexlusolve +# SVD decomposition. # + svd decomp; svddecomp + svd solve; svdsolve +# QR decomposition. # + qr decomp; qrdecomp + qr solve; qrsolve + qr lssolve; qrlssolve +# Cholesky decomposition. # + cholesky decomp; choleskydecomp + cholesky solve; choleskysolve +# Constants ex GSL. # + cgs speed of light; cgsspeedoflight + cgs gravitational constant; cgsgravitationalconstant + cgs planck constant; cgsplanckconstant + cgs planck constant bar; cgsplanckconstantbar + cgs astronomical unit; cgsastronomicalunit + cgs light year; cgslightyear + cgs parsec; cgsparsec + cgs grav accel; cgsgravaccel + cgs electron volt; cgselectronvolt + cgs mass electron; cgsmasselectron + cgs mass muon; cgsmassmuon + cgs mass proton; cgsmassproton + cgs mass neutron; cgsmassneutron + cgs rydberg; cgsrydberg + cgs boltzmann; cgsboltzmann + cgs bohr magneton; cgsbohrmagneton + cgs nuclear magneton; cgsnuclearmagneton + cgs electron magnetic moment; cgselectronmagneticmoment + cgs proton magnetic moment; cgsprotonmagneticmoment + cgs molar gas; cgsmolargas + cgs standard gas volume; cgsstandardgasvolume + cgs minute; cgsminute + cgs hour; cgshour + cgs day; cgsday + cgs week; cgsweek + cgs inch; cgsinch + cgs foot; cgsfoot + cgs yard; cgsyard + cgs mile; cgsmile + cgs nautical mile; cgsnauticalmile + cgs fathom; cgsfathom + cgs mil; cgsmil + cgs point; cgspoint + cgs texpoint; cgstexpoint + cgs micron; cgsmicron + cgs angstrom; cgsangstrom + cgs hectare; cgshectare + cgs acre; cgsacre + cgs barn; cgsbarn + cgs liter; cgsliter + cgs us gallon; cgsusgallon + cgs quart; cgsquart + cgs pint; cgspint + cgs cup; cgscup + cgs fluid ounce; cgsfluidounce + cgs table spoon; cgstablespoon + cgs tea spoon; cgsteaspoon + cgs canadian gallon; cgscanadiangallon + cgs uk gallon; cgsukgallon + cgs miles per hour; cgsmilesperhour + cgs kilometers per hour; cgskilometersperhour + cgs knot; cgsknot + cgs pound mass; cgspoundmass + cgs ounce mass; cgsouncemass + cgs ton; cgston + cgs metricton; cgsmetricton + cgs ukton; cgsukton + cgs troy ounce; cgstroyounce + cgs carat; cgscarat + cgs unified atomic mass; cgsunifiedatomicmass + cgs gram force; cgsgramforce + cgs pound force; cgspoundforce + cgs kilo pound force; cgskilopoundforce + cgs poundal; cgspoundal + cgs calorie; cgscalorie + cgs btu; cgsbtu + cgs therm; cgstherm + cgs horsepower; cgshorsepower + cgs bar; cgsbar + cgs std atmosphere; cgsstdatmosphere + cgs torr; cgstorr + cgs meter of mercury; cgsmeterofmercury + cgs inch of mercury; cgsinchofmercury + cgs inch of water; cgsinchofwater + cgs psi; cgspsi + cgs poise; cgspoise + cgs stokes; cgsstokes + cgs faraday; cgsfaraday + cgs electron charge; cgselectroncharge + cgs gauss; cgsgauss + cgs stilb; cgsstilb + cgs lumen; cgslumen + cgs lux; cgslux + cgs phot; cgsphot + cgs foot candle; cgsfootcandle + cgs lambert; cgslambert + cgs foot lambert; cgsfootlambert + cgs curie; cgscurie + cgs roentgen; cgsroentgen + cgs rad; cgsrad + cgs solar mass; cgssolarmass + cgs bohr radius; cgsbohrradius + cgs newton; cgsnewton + cgs dyne; cgsdyne + cgs joule; cgsjoule + cgs erg; cgserg + mksa speed of light; mksaspeedoflight + mksa gravitational constant; mksagravitationalconstant + mksa planck constant; mksaplanckconstant + mksa planck constant bar; mksaplanckconstantbar + mksa vacuum permeability; mksavacuumpermeability + mksa astronomical unit; mksaastronomicalunit + mksa light year; mksalightyear + mksa parsec; mksaparsec + mksa grav accel; mksagravaccel + mksa electron volt; mksaelectronvolt + mksa mass electron; mksamasselectron + mksa mass muon; mksamassmuon + mksa mass proton; mksamassproton + mksa mass neutron; mksamassneutron + mksa rydberg; mksarydberg + mksa boltzmann; mksaboltzmann + mksa bohr magneton; mksabohrmagneton + mksa nuclear magneton; mksanuclearmagneton + mksa electron magnetic moment; mksaelectronmagneticmoment + mksa proton magnetic moment; mksaprotonmagneticmoment + mksa molar gas; mksamolargas + mksa standard gas volume; mksastandardgasvolume + mksa minute; mksaminute + mksa hour; mksahour + mksa day; mksaday + mksa week; mksaweek + mksa inch; mksainch + mksa foot; mksafoot + mksa yard; mksayard + mksa mile; mksamile + mksa nautical mile; mksanauticalmile + mksa fathom; mksafathom + mksa mil; mksamil + mksa point; mksapoint + mksa texpoint; mksatexpoint + mksa micron; mksamicron + mksa angstrom; mksaangstrom + mksa hectare; mksahectare + mksa acre; mksaacre + mksa barn; mksabarn + mksa liter; mksaliter + mksa us gallon; mksausgallon + mksa quart; mksaquart + mksa pint; mksapint + mksa cup; mksacup + mksa fluid ounce; mksafluidounce + mksa table spoon; mksatablespoon + mksa tea spoon; mksateaspoon + mksa canadian gallon; mksacanadiangallon + mksa uk gallon; mksaukgallon + mksa miles per hour; mksamilesperhour + mksa kilometers per hour; mksakilometersperhour + mksa knot; mksaknot + mksa pound mass; mksapoundmass + mksa ounce mass; mksaouncemass + mksa ton; mksaton + mksa metricton; mksametricton + mksa ukton; mksaukton + mksa troy ounce; mksatroyounce + mksa carat; mksacarat + mksa unified atomic mass; mksaunifiedatomicmass + mksa gram force; mksagramforce + mksa pound force; mksapoundforce + mksa kilo pound force; mksakilopoundforce + mksa poundal; mksapoundal + mksa calorie; mksacalorie + mksa btu; mksabtu + mksa therm; mksatherm + mksa horsepower; mksahorsepower + mksa bar; mksabar + mksa stdatmosphere; mksastdatmosphere + mksa torr; mksatorr + mksa meter of mercury; mksameterofmercury + mksa inch of mercury; mksainchofmercury + mksa inch of water; mksainchofwater + mksa psi; mksapsi + mksa poise; mksapoise + mksa stokes; mksastokes + mksa faraday; mksafaraday + mksa electron charge; mksaelectroncharge + mksa gauss; mksagauss + mksa stilb; mksastilb + mksa lumen; mksalumen + mksa lux; mksalux + mksa phot; mksaphot + mksa foot candle; mksafootcandle + mksa lambert; mksalambert + mksa foot lambert; mksafootlambert + mksa curie; mksacurie + mksa roentgen; mksaroentgen + mksa rad; mksarad + mksa solar mass; mksasolarmass + mksa bohr radius; mksabohrradius + mksa vacuum permittivity; mksavacuumpermittivity + mksa newton; mksanewton + mksa dyne; mksadyne + mksa joule; mksajoule + mksa erg; mksaerg + num fine structure; numfinestructure + num avogadro; numavogadro + num yotta; numyotta + num zetta; numzetta + num exa; numexa + num peta; numpeta + num tera; numtera + num giga; numgiga + num mega; nummega + num kilo; numkilo + num milli; nummilli + num micro; nummicro + num nano; numnano + num pico; numpico + num femto; numfemto + num atto; numatto + num zepto; numzepto + num yocto; numyocto +# FFT. # + primefactors; primefactors + fft complex forward; fftcomplexforward + fft complex backward; fftcomplexbackward + fft complex inverse; fftcomplexinverse + fft forward; fftforward + fft backward; fftbackward + fft inverse; fftinverse +# Laplace. # + laplace; laplace + + +# vim: syntax=algol68 ts=48 +# diff --git a/runtime/syntax/testdir/input/algol68_denotations.a68 b/runtime/syntax/testdir/input/algol68_denotations.a68 new file mode 100644 index 0000000000..f3ff57b976 --- /dev/null +++ b/runtime/syntax/testdir/input/algol68_denotations.a68 @@ -0,0 +1,117 @@ +# + Algol 68 Denotations +# + + +# BOOL # + +BOOL x = TRUE +BOOL x = FALSE + + +# INT # + +INT x = 0 +INT x = 42 + +# whitespace # +INT x = 1 000 000 + +# monadic operators # +INT x = -42 +INT x = +42 + + +# REAL # + +REAL x = .42 +REAL x = 42.42 + +REAL x = 42e42 +REAL x = 42E42 +REAL x = 42\42 +REAL x = 42⏨42 + +REAL x = 42e-42 +REAL x = 42E-42 +REAL x = 42\-42 +REAL x = 42⏨-42 + +REAL x = 42e+42 +REAL x = 42E+42 +REAL x = 42\+42 +REAL x = 42⏨+42 + +REAL x = .42e42 +REAL x = .42E42 +REAL x = .42\42 +REAL x = .42⏨42 + +REAL x = .42e-42 +REAL x = .42E-42 +REAL x = .42\-42 +REAL x = .42⏨-42 + +REAL x = .42e+42 +REAL x = .42E+42 +REAL x = .42\+42 +REAL x = .42⏨+42 + +REAL x = 42.42e42 +REAL x = 42.42E42 +REAL x = 42.42\42 +REAL x = 42.42⏨42 + +REAL x = 42.42e-42 +REAL x = 42.42E-42 +REAL x = 42.42\-42 +REAL x = 42.42⏨-42 + +REAL x = 42.42e+42 +REAL x = 42.42E+42 +REAL x = 42.42\+42 +REAL x = 42.42⏨+42 + +# whitespace # +REAL x = 4 2 . 4 2 e + 4 2 +REAL x = 4 2 . 4 2 \ + 4 2 +REAL x = 4 2 . 4 2 ⏨ + 4 2 + +# monadic operators # +REAL x = -42.42 +REAL x = +42.42 + + +# BITS # + +BITS x = 2r101010 +BITS x = 4r222 +BITS x = 8r52 +BITS x = 16r2a + +# whitespace # +BITS x = 2r 1010 1010 + +# unmatched by bad pattern in legacy versions of syntax file # +BITS x = 16r99 + + +# STRING # + +STRING s = "Foo Bar" + +# quote escape # +STRING s = """" +STRING s = " "" " +STRING s = "Foo""" +STRING s = """Bar" +STRING s = "Foo""Bar" + +# line continuation # +STRING s = "Foo\ + Bar" +STRING s = "Foo""\ +Bar" +STRING s = "Foo\ +""Bar" + diff --git a/runtime/syntax/testdir/input/algol68_operators.a68 b/runtime/syntax/testdir/input/algol68_operators.a68 new file mode 100644 index 0000000000..c54058e044 --- /dev/null +++ b/runtime/syntax/testdir/input/algol68_operators.a68 @@ -0,0 +1,997 @@ +# + Algol 68 Operators +# + + +#::::::::::::::::::::::::: +Prelude Symbolic Operators +:::::::::::::::::::::::::# + + +# IDENTITY # + +x :=: y +x :/=: y + +# BOOL # + +~TRUE +TRUE & FALSE +TRUE = FALSE +TRUE /= FALSE + +# INT # + ++42 +-42 + +42 +* 87 + +42 + 87 +42 - 87 +42 * 87 +42 % 87 +42 %* 87 +42 / 87 +42 ** 87 +42 ^ 87 + +i +:= 42 +i -:= 42 +i *:= 42 +i %:= 42 +i %*:= 42 + +42 = 87 +42 /= 87 +42 < 87 +42 <= 87 +42 > 87 +42 >= 87 + +# REAL # + ++4.2 +-4.2 + +4.2 +* 8.7 + +4.2 + 8.7 +4.2 - 8.7 +4.2 * 8.7 +4.2 / 8.7 + +4.2 ** 87 +4.2 ^ 87 + +r +:= 42 +r -:= 42 +r *:= 42 +r /:= 42 + +4.2 = 8.7 +4.2 /= 8.7 +4.2 < 8.7 +4.2 <= 8.7 +4.2 > 8.7 +4.2 >= 8.7 + +# CHAR # + +"a" = "b" +"a" /= "b" +"a" < "b" +"a" <= "b" +"a" > "b" +"a" >= "b" + +# STRING # + +"aaa" = "bbb" +"aaa" /= "bbb" +"aaa" < "bbb" +"aaa" <= "bbb" +"aaa" > "bbb" +"aaa" >= "bbb" + +"aaa" + "bbb" +"aaa" + "b" + 42 * "aaa" +"aaa" * 42 + + s +:= "aaa" +"aaa" +=: s + s *:= 5 + + +#::::::::::::::::: +Symbolic Operators +:::::::::::::::::# + + +# Monadic # + +# monad # + +! +% +& ++ +- +? +^ +~ + +# monad, becomes # + +!:= +%:= +&:= ++:= +-:= +?:= +^:= +~:= + +# monad, assigns to # + +!=: +%=: +&=: ++=: +-=: +?=: +^=: +~=: + + +# monad, nomad # + +!* +!/ +!< +!= +!> +%* +%/ +%< +%= +%> +&* +&/ +&< +&= +&> ++* ++/ ++< ++= ++> +-* +-/ +-< +-= +-> +?* +?/ +?< +?= +?> +^* +^/ +^< +^= +^> +~* +~/ +~< +~= +~> + +# monad, nomad, becomes # + +!*:= +!/:= +!<:= +!=:= +!>:= +%*:= +%/:= +%<:= +%=:= +%>:= +&*:= +&/:= +&<:= +&=:= +&>:= ++*:= ++/:= ++<:= ++=:= ++>:= +-*:= +-/:= +-<:= +-=:= +->:= +?*:= +?/:= +?<:= +?=:= +?>:= +^*:= +^/:= +^<:= +^=:= +^>:= +~*:= +~/:= +~<:= +~=:= +~>:= + +# monad, nomad, assigns to # + +!*=: +!/=: +!<=: +!==: +!>=: +%*=: +%/=: +%<=: +%==: +%>=: +&*=: +&/=: +&<=: +&==: +&>=: ++*=: ++/=: ++<=: ++==: ++>=: +-*=: +-/=: +-<=: +-==: +->=: +?*=: +?/=: +?<=: +?==: +?>=: +^*=: +^/=: +^<=: +^==: +^>=: +~*=: +~/=: +~<=: +~==: +~>=: + + +# Dyadic # + +# monad # + +! +% +& ++ +- +? +^ +~ + +# monad, becomes # + +!:= +%:= +&:= ++:= +-:= +?:= +^:= +~:= + +# monad, assigns to # + +!=: +%=: +&=: ++=: +-=: +?=: +^=: +~=: + + +# nomad # + +* +/ +< += +> + +# nomad, becomes # + +*:= +/:= +<:= +=:= +>:= + +# nomad, assigns to # + +*=: +/=: +<=: +==: +>=: + + +# monad, nomad # + +!* +!/ +!< +!= +!> +%* +%/ +%< +%= +%> +&* +&/ +&< +&= +&> ++* ++/ ++< ++= ++> +-* +-/ +-< +-= +-> +?* +?/ +?< +?= +?> +^* +^/ +^< +^= +^> +~* +~/ +~< +~= +~> + +# monad, nomad, becomes # + +!*:= +!/:= +!<:= +!=:= +!>:= +%*:= +%/:= +%<:= +%=:= +%>:= +&*:= +&/:= +&<:= +&=:= +&>:= ++*:= ++/:= ++<:= ++=:= ++>:= +-*:= +-/:= +-<:= +-=:= +->:= +?*:= +?/:= +?<:= +?=:= +?>:= +^*:= +^/:= +^<:= +^=:= +^>:= +~*:= +~/:= +~<:= +~=:= +~>:= + +# monad, nomad, assigns to # + +!*=: +!/=: +!<=: +!==: +!>=: +%*=: +%/=: +%<=: +%==: +%>=: +&*=: +&/=: +&<=: +&==: +&>=: ++*=: ++/=: ++<=: ++==: ++>=: +-*=: +-/=: +-<=: +-==: +->=: +?*=: +?/=: +?<=: +?==: +?>=: +^*=: +^/=: +^<=: +^==: +^>=: +~*=: +~/=: +~<=: +~==: +~>=: + + +# nomad, nomad # + +** +*/ +*< +*= +*> +/* +// +/< +/= +/> +<* + +=* +=/ +=< +== +=> +>* +>/ +>< +>= +>> + +# nomad, nomad, becomes # + +**:= +*/:= +*<:= +*=:= +*>:= +/*:= +//:= +/<:= +/=:= +/>:= +<*:= +:= +=*:= +=/:= +=<:= +==:= +=>:= +>*:= +>/:= +><:= +>=:= +>>:= + +# nomad, nomad, assigns to # + +**=: +*/=: +*<=: +*==: +*>=: +/*=: +//=: +/<=: +/==: +/>=: +<*=: +=: +=*=: +=/=: +=<=: +===: +=>=: +>*=: +>/=: +><=: +>==: +>>=: + + +#::::::::::::: +Symbolic Operator Declarations +:::::::::::::# + + +# Monadic # + + +# monad # + +OP ! = (INT a) INT : 42; +OP % = (INT a) INT : 42; +OP & = (INT a) INT : 42; +OP + = (INT a) INT : 42; +OP - = (INT a) INT : 42; +OP ? = (INT a) INT : 42; +OP ^ = (INT a) INT : 42; +OP ~ = (INT a) INT : 42; + +# monad, becomes # + +OP !:= = (INT a) INT: 42; +OP %:= = (INT a) INT: 42; +OP &:= = (INT a) INT: 42; +OP +:= = (INT a) INT: 42; +OP -:= = (INT a) INT: 42; +OP ?:= = (INT a) INT: 42; +OP ^:= = (INT a) INT: 42; +OP ~:= = (INT a) INT: 42; + +# monad, assigns to # + +OP !=: = (INT a) INT: 42; +OP %=: = (INT a) INT: 42; +OP &=: = (INT a) INT: 42; +OP +=: = (INT a) INT: 42; +OP -=: = (INT a) INT: 42; +OP ?=: = (INT a) INT: 42; +OP ^=: = (INT a) INT: 42; +OP ~=: = (INT a) INT: 42; + +# monad, nomad # + +OP !* = (INT a) INT : 42; +OP !/ = (INT a) INT : 42; +OP !< = (INT a) INT : 42; +OP != = (INT a) INT : 42; +OP !> = (INT a) INT : 42; +OP %* = (INT a) INT : 42; +OP %/ = (INT a) INT : 42; +OP %< = (INT a) INT : 42; +OP %= = (INT a) INT : 42; +OP %> = (INT a) INT : 42; +OP &* = (INT a) INT : 42; +OP &/ = (INT a) INT : 42; +OP &< = (INT a) INT : 42; +OP &= = (INT a) INT : 42; +OP &> = (INT a) INT : 42; +OP +* = (INT a) INT : 42; +OP +/ = (INT a) INT : 42; +OP +< = (INT a) INT : 42; +OP += = (INT a) INT : 42; +OP +> = (INT a) INT : 42; +OP -* = (INT a) INT : 42; +OP -/ = (INT a) INT : 42; +OP -< = (INT a) INT : 42; +OP -= = (INT a) INT : 42; +OP -> = (INT a) INT : 42; +OP ?* = (INT a) INT : 42; +OP ?/ = (INT a) INT : 42; +OP ?< = (INT a) INT : 42; +OP ?= = (INT a) INT : 42; +OP ?> = (INT a) INT : 42; +OP ^* = (INT a) INT : 42; +OP ^/ = (INT a) INT : 42; +OP ^< = (INT a) INT : 42; +OP ^= = (INT a) INT : 42; +OP ^> = (INT a) INT : 42; +OP ~* = (INT a) INT : 42; +OP ~/ = (INT a) INT : 42; +OP ~< = (INT a) INT : 42; +OP ~= = (INT a) INT : 42; +OP ~> = (INT a) INT : 42; + +# monad, nomad, becomes # + +OP !*:= = (INT a) INT: 42; +OP !/:= = (INT a) INT: 42; +OP !<:= = (INT a) INT: 42; +OP !=:= = (INT a) INT: 42; +OP !>:= = (INT a) INT: 42; +OP %*:= = (INT a) INT: 42; +OP %/:= = (INT a) INT: 42; +OP %<:= = (INT a) INT: 42; +OP %=:= = (INT a) INT: 42; +OP %>:= = (INT a) INT: 42; +OP &*:= = (INT a) INT: 42; +OP &/:= = (INT a) INT: 42; +OP &<:= = (INT a) INT: 42; +OP &=:= = (INT a) INT: 42; +OP &>:= = (INT a) INT: 42; +OP +*:= = (INT a) INT: 42; +OP +/:= = (INT a) INT: 42; +OP +<:= = (INT a) INT: 42; +OP +=:= = (INT a) INT: 42; +OP +>:= = (INT a) INT: 42; +OP -*:= = (INT a) INT: 42; +OP -/:= = (INT a) INT: 42; +OP -<:= = (INT a) INT: 42; +OP -=:= = (INT a) INT: 42; +OP ->:= = (INT a) INT: 42; +OP ?*:= = (INT a) INT: 42; +OP ?/:= = (INT a) INT: 42; +OP ?<:= = (INT a) INT: 42; +OP ?=:= = (INT a) INT: 42; +OP ?>:= = (INT a) INT: 42; +OP ^*:= = (INT a) INT: 42; +OP ^/:= = (INT a) INT: 42; +OP ^<:= = (INT a) INT: 42; +OP ^=:= = (INT a) INT: 42; +OP ^>:= = (INT a) INT: 42; +OP ~*:= = (INT a) INT: 42; +OP ~/:= = (INT a) INT: 42; +OP ~<:= = (INT a) INT: 42; +OP ~=:= = (INT a) INT: 42; +OP ~>:= = (INT a) INT: 42; + +# monad, nomad, assigns to # + +OP !*=: = (INT a) INT: 42; +OP !/=: = (INT a) INT: 42; +OP !<=: = (INT a) INT: 42; +OP !==: = (INT a) INT: 42; +OP !>=: = (INT a) INT: 42; +OP %*=: = (INT a) INT: 42; +OP %/=: = (INT a) INT: 42; +OP %<=: = (INT a) INT: 42; +OP %==: = (INT a) INT: 42; +OP %>=: = (INT a) INT: 42; +OP &*=: = (INT a) INT: 42; +OP &/=: = (INT a) INT: 42; +OP &<=: = (INT a) INT: 42; +OP &==: = (INT a) INT: 42; +OP &>=: = (INT a) INT: 42; +OP +*=: = (INT a) INT: 42; +OP +/=: = (INT a) INT: 42; +OP +<=: = (INT a) INT: 42; +OP +==: = (INT a) INT: 42; +OP +>=: = (INT a) INT: 42; +OP -*=: = (INT a) INT: 42; +OP -/=: = (INT a) INT: 42; +OP -<=: = (INT a) INT: 42; +OP -==: = (INT a) INT: 42; +OP ->=: = (INT a) INT: 42; +OP ?*=: = (INT a) INT: 42; +OP ?/=: = (INT a) INT: 42; +OP ?<=: = (INT a) INT: 42; +OP ?==: = (INT a) INT: 42; +OP ?>=: = (INT a) INT: 42; +OP ^*=: = (INT a) INT: 42; +OP ^/=: = (INT a) INT: 42; +OP ^<=: = (INT a) INT: 42; +OP ^==: = (INT a) INT: 42; +OP ^>=: = (INT a) INT: 42; +OP ~*=: = (INT a) INT: 42; +OP ~/=: = (INT a) INT: 42; +OP ~<=: = (INT a) INT: 42; +OP ~==: = (INT a) INT: 42; +OP ~>=: = (INT a) INT: 42; + + +# Dyadic # + + +# monad # + +PRIO ! = 1; OP ! = (INT a, INT b) INT : 42; +PRIO % = 1; OP % = (INT a, INT b) INT : 42; +PRIO & = 1; OP & = (INT a, INT b) INT : 42; +PRIO + = 1; OP + = (INT a, INT b) INT : 42; +PRIO - = 1; OP - = (INT a, INT b) INT : 42; +PRIO ? = 1; OP ? = (INT a, INT b) INT : 42; +PRIO ^ = 1; OP ^ = (INT a, INT b) INT : 42; +PRIO ~ = 1; OP ~ = (INT a, INT b) INT : 42; + +# monad, becomes # + +PRIO !:= = 1; OP !:= = (INT a, INT b) INT: 42; +PRIO %:= = 1; OP %:= = (INT a, INT b) INT: 42; +PRIO &:= = 1; OP &:= = (INT a, INT b) INT: 42; +PRIO +:= = 1; OP +:= = (INT a, INT b) INT: 42; +PRIO -:= = 1; OP -:= = (INT a, INT b) INT: 42; +PRIO ?:= = 1; OP ?:= = (INT a, INT b) INT: 42; +PRIO ^:= = 1; OP ^:= = (INT a, INT b) INT: 42; +PRIO ~:= = 1; OP ~:= = (INT a, INT b) INT: 42; + +# monad, assigns to # + +PRIO !=: = 1; OP !=: = (INT a, INT b) INT: 42; +PRIO %=: = 1; OP %=: = (INT a, INT b) INT: 42; +PRIO &=: = 1; OP &=: = (INT a, INT b) INT: 42; +PRIO +=: = 1; OP +=: = (INT a, INT b) INT: 42; +PRIO -=: = 1; OP -=: = (INT a, INT b) INT: 42; +PRIO ?=: = 1; OP ?=: = (INT a, INT b) INT: 42; +PRIO ^=: = 1; OP ^=: = (INT a, INT b) INT: 42; +PRIO ~=: = 1; OP ~=: = (INT a, INT b) INT: 42; + +# nomad # + +PRIO * = 1; OP * = (INT a, INT b) INT: 42; +PRIO / = 1; OP / = (INT a, INT b) INT: 42; +PRIO < = 1; OP < = (INT a, INT b) INT: 42; +PRIO = = 1; OP = = (INT a, INT b) INT: 42; +PRIO > = 1; OP > = (INT a, INT b) INT: 42; + +# nomad, becomes # + +PRIO *:= = 1; OP *:= = (INT a, INT b) INT: 42; +PRIO /:= = 1; OP /:= = (INT a, INT b) INT: 42; +PRIO <:= = 1; OP <:= = (INT a, INT b) INT: 42; +PRIO =:= = 1; OP =:= = (INT a, INT b) INT: 42; +PRIO >:= = 1; OP >:= = (INT a, INT b) INT: 42; + +# nomad, assigns to # + +PRIO *=: = 1; OP *=: = (INT a, INT b) INT: 42; +PRIO /=: = 1; OP /=: = (INT a, INT b) INT: 42; +PRIO <=: = 1; OP <=: = (INT a, INT b) INT: 42; +PRIO ==: = 1; OP ==: = (INT a, INT b) INT: 42; +PRIO >=: = 1; OP >=: = (INT a, INT b) INT: 42; + +# monad, nomad # + +PRIO !* = 1; OP !* = (INT a, INT b) INT : 42; +PRIO !/ = 1; OP !/ = (INT a, INT b) INT : 42; +PRIO !< = 1; OP !< = (INT a, INT b) INT : 42; +PRIO != = 1; OP != = (INT a, INT b) INT : 42; +PRIO !> = 1; OP !> = (INT a, INT b) INT : 42; +PRIO %* = 1; OP %* = (INT a, INT b) INT : 42; +PRIO %/ = 1; OP %/ = (INT a, INT b) INT : 42; +PRIO %< = 1; OP %< = (INT a, INT b) INT : 42; +PRIO %= = 1; OP %= = (INT a, INT b) INT : 42; +PRIO %> = 1; OP %> = (INT a, INT b) INT : 42; +PRIO &* = 1; OP &* = (INT a, INT b) INT : 42; +PRIO &/ = 1; OP &/ = (INT a, INT b) INT : 42; +PRIO &< = 1; OP &< = (INT a, INT b) INT : 42; +PRIO &= = 1; OP &= = (INT a, INT b) INT : 42; +PRIO &> = 1; OP &> = (INT a, INT b) INT : 42; +PRIO +* = 1; OP +* = (INT a, INT b) INT : 42; +PRIO +/ = 1; OP +/ = (INT a, INT b) INT : 42; +PRIO +< = 1; OP +< = (INT a, INT b) INT : 42; +PRIO += = 1; OP += = (INT a, INT b) INT : 42; +PRIO +> = 1; OP +> = (INT a, INT b) INT : 42; +PRIO -* = 1; OP -* = (INT a, INT b) INT : 42; +PRIO -/ = 1; OP -/ = (INT a, INT b) INT : 42; +PRIO -< = 1; OP -< = (INT a, INT b) INT : 42; +PRIO -= = 1; OP -= = (INT a, INT b) INT : 42; +PRIO -> = 1; OP -> = (INT a, INT b) INT : 42; +PRIO ?* = 1; OP ?* = (INT a, INT b) INT : 42; +PRIO ?/ = 1; OP ?/ = (INT a, INT b) INT : 42; +PRIO ?< = 1; OP ?< = (INT a, INT b) INT : 42; +PRIO ?= = 1; OP ?= = (INT a, INT b) INT : 42; +PRIO ?> = 1; OP ?> = (INT a, INT b) INT : 42; +PRIO ^* = 1; OP ^* = (INT a, INT b) INT : 42; +PRIO ^/ = 1; OP ^/ = (INT a, INT b) INT : 42; +PRIO ^< = 1; OP ^< = (INT a, INT b) INT : 42; +PRIO ^= = 1; OP ^= = (INT a, INT b) INT : 42; +PRIO ^> = 1; OP ^> = (INT a, INT b) INT : 42; +PRIO ~* = 1; OP ~* = (INT a, INT b) INT : 42; +PRIO ~/ = 1; OP ~/ = (INT a, INT b) INT : 42; +PRIO ~< = 1; OP ~< = (INT a, INT b) INT : 42; +PRIO ~= = 1; OP ~= = (INT a, INT b) INT : 42; +PRIO ~> = 1; OP ~> = (INT a, INT b) INT : 42; + +# monad, nomad, becomes # + +PRIO !*:= = 1; OP !*:= = (INT a, INT b) INT: 42; +PRIO !/:= = 1; OP !/:= = (INT a, INT b) INT: 42; +PRIO !<:= = 1; OP !<:= = (INT a, INT b) INT: 42; +PRIO !=:= = 1; OP !=:= = (INT a, INT b) INT: 42; +PRIO !>:= = 1; OP !>:= = (INT a, INT b) INT: 42; +PRIO %*:= = 1; OP %*:= = (INT a, INT b) INT: 42; +PRIO %/:= = 1; OP %/:= = (INT a, INT b) INT: 42; +PRIO %<:= = 1; OP %<:= = (INT a, INT b) INT: 42; +PRIO %=:= = 1; OP %=:= = (INT a, INT b) INT: 42; +PRIO %>:= = 1; OP %>:= = (INT a, INT b) INT: 42; +PRIO &*:= = 1; OP &*:= = (INT a, INT b) INT: 42; +PRIO &/:= = 1; OP &/:= = (INT a, INT b) INT: 42; +PRIO &<:= = 1; OP &<:= = (INT a, INT b) INT: 42; +PRIO &=:= = 1; OP &=:= = (INT a, INT b) INT: 42; +PRIO &>:= = 1; OP &>:= = (INT a, INT b) INT: 42; +PRIO +*:= = 1; OP +*:= = (INT a, INT b) INT: 42; +PRIO +/:= = 1; OP +/:= = (INT a, INT b) INT: 42; +PRIO +<:= = 1; OP +<:= = (INT a, INT b) INT: 42; +PRIO +=:= = 1; OP +=:= = (INT a, INT b) INT: 42; +PRIO +>:= = 1; OP +>:= = (INT a, INT b) INT: 42; +PRIO -*:= = 1; OP -*:= = (INT a, INT b) INT: 42; +PRIO -/:= = 1; OP -/:= = (INT a, INT b) INT: 42; +PRIO -<:= = 1; OP -<:= = (INT a, INT b) INT: 42; +PRIO -=:= = 1; OP -=:= = (INT a, INT b) INT: 42; +PRIO ->:= = 1; OP ->:= = (INT a, INT b) INT: 42; +PRIO ?*:= = 1; OP ?*:= = (INT a, INT b) INT: 42; +PRIO ?/:= = 1; OP ?/:= = (INT a, INT b) INT: 42; +PRIO ?<:= = 1; OP ?<:= = (INT a, INT b) INT: 42; +PRIO ?=:= = 1; OP ?=:= = (INT a, INT b) INT: 42; +PRIO ?>:= = 1; OP ?>:= = (INT a, INT b) INT: 42; +PRIO ^*:= = 1; OP ^*:= = (INT a, INT b) INT: 42; +PRIO ^/:= = 1; OP ^/:= = (INT a, INT b) INT: 42; +PRIO ^<:= = 1; OP ^<:= = (INT a, INT b) INT: 42; +PRIO ^=:= = 1; OP ^=:= = (INT a, INT b) INT: 42; +PRIO ^>:= = 1; OP ^>:= = (INT a, INT b) INT: 42; +PRIO ~*:= = 1; OP ~*:= = (INT a, INT b) INT: 42; +PRIO ~/:= = 1; OP ~/:= = (INT a, INT b) INT: 42; +PRIO ~<:= = 1; OP ~<:= = (INT a, INT b) INT: 42; +PRIO ~=:= = 1; OP ~=:= = (INT a, INT b) INT: 42; +PRIO ~>:= = 1; OP ~>:= = (INT a, INT b) INT: 42; + +# monad, nomad, assigns to # + +PRIO !*=: = 1; OP !*=: = (INT a, INT b) INT: 42; +PRIO !/=: = 1; OP !/=: = (INT a, INT b) INT: 42; +PRIO !<=: = 1; OP !<=: = (INT a, INT b) INT: 42; +PRIO !==: = 1; OP !==: = (INT a, INT b) INT: 42; +PRIO !>=: = 1; OP !>=: = (INT a, INT b) INT: 42; +PRIO %*=: = 1; OP %*=: = (INT a, INT b) INT: 42; +PRIO %/=: = 1; OP %/=: = (INT a, INT b) INT: 42; +PRIO %<=: = 1; OP %<=: = (INT a, INT b) INT: 42; +PRIO %==: = 1; OP %==: = (INT a, INT b) INT: 42; +PRIO %>=: = 1; OP %>=: = (INT a, INT b) INT: 42; +PRIO &*=: = 1; OP &*=: = (INT a, INT b) INT: 42; +PRIO &/=: = 1; OP &/=: = (INT a, INT b) INT: 42; +PRIO &<=: = 1; OP &<=: = (INT a, INT b) INT: 42; +PRIO &==: = 1; OP &==: = (INT a, INT b) INT: 42; +PRIO &>=: = 1; OP &>=: = (INT a, INT b) INT: 42; +PRIO +*=: = 1; OP +*=: = (INT a, INT b) INT: 42; +PRIO +/=: = 1; OP +/=: = (INT a, INT b) INT: 42; +PRIO +<=: = 1; OP +<=: = (INT a, INT b) INT: 42; +PRIO +==: = 1; OP +==: = (INT a, INT b) INT: 42; +PRIO +>=: = 1; OP +>=: = (INT a, INT b) INT: 42; +PRIO -*=: = 1; OP -*=: = (INT a, INT b) INT: 42; +PRIO -/=: = 1; OP -/=: = (INT a, INT b) INT: 42; +PRIO -<=: = 1; OP -<=: = (INT a, INT b) INT: 42; +PRIO -==: = 1; OP -==: = (INT a, INT b) INT: 42; +PRIO ->=: = 1; OP ->=: = (INT a, INT b) INT: 42; +PRIO ?*=: = 1; OP ?*=: = (INT a, INT b) INT: 42; +PRIO ?/=: = 1; OP ?/=: = (INT a, INT b) INT: 42; +PRIO ?<=: = 1; OP ?<=: = (INT a, INT b) INT: 42; +PRIO ?==: = 1; OP ?==: = (INT a, INT b) INT: 42; +PRIO ?>=: = 1; OP ?>=: = (INT a, INT b) INT: 42; +PRIO ^*=: = 1; OP ^*=: = (INT a, INT b) INT: 42; +PRIO ^/=: = 1; OP ^/=: = (INT a, INT b) INT: 42; +PRIO ^<=: = 1; OP ^<=: = (INT a, INT b) INT: 42; +PRIO ^==: = 1; OP ^==: = (INT a, INT b) INT: 42; +PRIO ^>=: = 1; OP ^>=: = (INT a, INT b) INT: 42; +PRIO ~*=: = 1; OP ~*=: = (INT a, INT b) INT: 42; +PRIO ~/=: = 1; OP ~/=: = (INT a, INT b) INT: 42; +PRIO ~<=: = 1; OP ~<=: = (INT a, INT b) INT: 42; +PRIO ~==: = 1; OP ~==: = (INT a, INT b) INT: 42; +PRIO ~>=: = 1; OP ~>=: = (INT a, INT b) INT: 42; + +# nomad, nomad # + +PRIO ** = 1; OP ** = (INT a, INT b) INT: 42; +PRIO */ = 1; OP */ = (INT a, INT b) INT: 42; +PRIO *< = 1; OP *< = (INT a, INT b) INT: 42; +PRIO *= = 1; OP *= = (INT a, INT b) INT: 42; +PRIO *> = 1; OP *> = (INT a, INT b) INT: 42; +PRIO /* = 1; OP /* = (INT a, INT b) INT: 42; +PRIO // = 1; OP // = (INT a, INT b) INT: 42; +PRIO /< = 1; OP /< = (INT a, INT b) INT: 42; +PRIO /= = 1; OP /= = (INT a, INT b) INT: 42; +PRIO /> = 1; OP /> = (INT a, INT b) INT: 42; +PRIO <* = 1; OP <* = (INT a, INT b) INT: 42; +PRIO = 1; OP <> = (INT a, INT b) INT: 42; +PRIO =* = 1; OP =* = (INT a, INT b) INT: 42; +PRIO =/ = 1; OP =/ = (INT a, INT b) INT: 42; +PRIO =< = 1; OP =< = (INT a, INT b) INT: 42; +PRIO == = 1; OP == = (INT a, INT b) INT: 42; +PRIO => = 1; OP => = (INT a, INT b) INT: 42; +PRIO >* = 1; OP >* = (INT a, INT b) INT: 42; +PRIO >/ = 1; OP >/ = (INT a, INT b) INT: 42; +PRIO >< = 1; OP >< = (INT a, INT b) INT: 42; +PRIO >= = 1; OP >= = (INT a, INT b) INT: 42; +PRIO >> = 1; OP >> = (INT a, INT b) INT: 42; + +# nomad, nomad, becomes # + +PRIO **:= = 1; OP **:= = (INT a, INT b) INT: 42; +PRIO */:= = 1; OP */:= = (INT a, INT b) INT: 42; +PRIO *<:= = 1; OP *<:= = (INT a, INT b) INT: 42; +PRIO *=:= = 1; OP *=:= = (INT a, INT b) INT: 42; +PRIO *>:= = 1; OP *>:= = (INT a, INT b) INT: 42; +PRIO /*:= = 1; OP /*:= = (INT a, INT b) INT: 42; +PRIO //:= = 1; OP //:= = (INT a, INT b) INT: 42; +PRIO /<:= = 1; OP /<:= = (INT a, INT b) INT: 42; +PRIO /=:= = 1; OP /=:= = (INT a, INT b) INT: 42; +PRIO />:= = 1; OP />:= = (INT a, INT b) INT: 42; +PRIO <*:= = 1; OP <*:= = (INT a, INT b) INT: 42; +PRIO := = 1; OP <>:= = (INT a, INT b) INT: 42; +PRIO =*:= = 1; OP =*:= = (INT a, INT b) INT: 42; +PRIO =/:= = 1; OP =/:= = (INT a, INT b) INT: 42; +PRIO =<:= = 1; OP =<:= = (INT a, INT b) INT: 42; +PRIO ==:= = 1; OP ==:= = (INT a, INT b) INT: 42; +PRIO =>:= = 1; OP =>:= = (INT a, INT b) INT: 42; +PRIO >*:= = 1; OP >*:= = (INT a, INT b) INT: 42; +PRIO >/:= = 1; OP >/:= = (INT a, INT b) INT: 42; +PRIO ><:= = 1; OP ><:= = (INT a, INT b) INT: 42; +PRIO >=:= = 1; OP >=:= = (INT a, INT b) INT: 42; +PRIO >>:= = 1; OP >>:= = (INT a, INT b) INT: 42; + +# nomad, nomad, assigns to # + +PRIO **=: = 1; OP **=: = (INT a, INT b) INT: 42; +PRIO */=: = 1; OP */=: = (INT a, INT b) INT: 42; +PRIO *<=: = 1; OP *<=: = (INT a, INT b) INT: 42; +PRIO *==: = 1; OP *==: = (INT a, INT b) INT: 42; +PRIO *>=: = 1; OP *>=: = (INT a, INT b) INT: 42; +PRIO /*=: = 1; OP /*=: = (INT a, INT b) INT: 42; +PRIO //=: = 1; OP //=: = (INT a, INT b) INT: 42; +PRIO /<=: = 1; OP /<=: = (INT a, INT b) INT: 42; +PRIO /==: = 1; OP /==: = (INT a, INT b) INT: 42; +PRIO />=: = 1; OP />=: = (INT a, INT b) INT: 42; +PRIO <*=: = 1; OP <*=: = (INT a, INT b) INT: 42; +PRIO =: = 1; OP <>=: = (INT a, INT b) INT: 42; +PRIO =*=: = 1; OP =*=: = (INT a, INT b) INT: 42; +PRIO =/=: = 1; OP =/=: = (INT a, INT b) INT: 42; +PRIO =<=: = 1; OP =<=: = (INT a, INT b) INT: 42; +PRIO ===: = 1; OP ===: = (INT a, INT b) INT: 42; +PRIO =>=: = 1; OP =>=: = (INT a, INT b) INT: 42; +PRIO >*=: = 1; OP >*=: = (INT a, INT b) INT: 42; +PRIO >/=: = 1; OP >/=: = (INT a, INT b) INT: 42; +PRIO ><=: = 1; OP ><=: = (INT a, INT b) INT: 42; +PRIO >==: = 1; OP >==: = (INT a, INT b) INT: 42; +PRIO >>=: = 1; OP >>=: = (INT a, INT b) INT: 42; + diff --git a/runtime/syntax/testdir/input/dockerfile.dockerfile b/runtime/syntax/testdir/input/dockerfile.dockerfile new file mode 100644 index 0000000000..0126470e46 --- /dev/null +++ b/runtime/syntax/testdir/input/dockerfile.dockerfile @@ -0,0 +1,14 @@ +# Issue #8364 (Docker syntax highlighting - Comments break up RUN highlighting +# in multi-line mode) + +FROM debian:10.3 + +RUN apt-get update -y \ + && apt-get upgrade -y \ + && apt-get install -y curl grep sed unzip git sudo jq gettext \ + # Azure CLI + && cd /tmp \ + && curl -sL https://aka.ms/InstallAzureCLIDeb | bash \ + # Clean-up Apt Caches + && apt-get clean \ + && rm -rf /var/lib/apt/lists diff --git a/runtime/syntax/testdir/input/javascript.js b/runtime/syntax/testdir/input/javascript.js new file mode 100644 index 0000000000..b0b76eca28 --- /dev/null +++ b/runtime/syntax/testdir/input/javascript.js @@ -0,0 +1,5 @@ +// Issue #20069 (JavaScript syntax highlighting not working properly with regex +// patterns containing quotation marks) + +const containsSymbols = password.match(/[!".../g); + diff --git a/runtime/syntax/testdir/input/make_01.mak b/runtime/syntax/testdir/input/make_01.mak index e97c13c0aa..082972a59c 100644 --- a/runtime/syntax/testdir/input/make_01.mak +++ b/runtime/syntax/testdir/input/make_01.mak @@ -14,3 +14,6 @@ endef default: $(call say,"Hello (world)!") + +foo: + echo "bar$$" baz diff --git a/runtime/syntax/testdir/input/python2_strings.py b/runtime/syntax/testdir/input/python2_strings.py index a5625b7d65..7ac32da161 100644 --- a/runtime/syntax/testdir/input/python2_strings.py +++ b/runtime/syntax/testdir/input/python2_strings.py @@ -79,4 +79,4 @@ test = UR"""Raw Unicode string with quotes ' and " and literal \t and \040 and \xFF and escapes \u00A1 and \U00010605""" -# vim: syntax=python2 +# vim: ft=python2 diff --git a/runtime/syntax/testdir/input/sh_03.sh b/runtime/syntax/testdir/input/sh_03.sh index 8dd6dab9c3..d2ac8f0a4a 100644 --- a/runtime/syntax/testdir/input/sh_03.sh +++ b/runtime/syntax/testdir/input/sh_03.sh @@ -31,3 +31,7 @@ Variable="${VariableB:-${VariableC:-eng}}" # :- is ksh and bash Variable=${VariableB:-${VariableC:-${VariableD:-${VariableE:=eng}}}} : ${VariableB:=${VariableC:-${VariableD:-${VariableE:=eng}}}} +# special variables +echo "${!#}" # last positional argument +echo "${!@}" # deref +echo "${#PATH}" # length diff --git a/runtime/syntax/testdir/input/sh_bash.bash b/runtime/syntax/testdir/input/sh_bash.bash index 35b536c4e3..798ce44ebe 100644 --- a/runtime/syntax/testdir/input/sh_bash.bash +++ b/runtime/syntax/testdir/input/sh_bash.bash @@ -14,7 +14,7 @@ echo ${ echo 'six' echo ${ echo 'seven' ;} echo ${ echo 'eight'; } typeset nine=${ pwd; } -echo ${ echo 'nine' ; +echo ${ echo 'nine' ; } valsubfunc() { @@ -25,9 +25,13 @@ echo "${|valsubfunc eleven; }" printf '%s\n' "${|valsubfunc twelve ;}" unlucky=${|valsubfunc thirteen } -typeset notafloat=${|valsubfunc notanumber ; +typeset notafloat=${|valsubfunc notanumber ; } echo $unlucky $notanumber ${|echo fourteen;} ${|echo fifteen } + +echo "${!#}" # last positional argument +echo "${!@}" # deref +echo "${#PATH}" # length diff --git a/runtime/syntax/testdir/input/sh_functions_bash.sh b/runtime/syntax/testdir/input/sh_functions_bash.sh index 161f14f978..714d2a74b3 100644 --- a/runtime/syntax/testdir/input/sh_functions_bash.sh +++ b/runtime/syntax/testdir/input/sh_functions_bash.sh @@ -47,9 +47,50 @@ if :; then } @Îą! "$1" ) - eval !?\# "$1" + eval !?\# "\"$1\"" fi namespace () { echo $#; }; namespace $@ + +# Whether "=" belongs to a name or delimits a name depends on whether +# the reserved word "function" is present, if so, then "=" is part of +# the function name; else, "=" delimits the name of a variable when this +# name is given in alphanumeric characters and "_"s before the leftmost +# "="; otherwise, "=" is part of the function name when this name has +# one or more supported NON-alphanumeric (or "_") characters before "=". +xs=() +( + echo $(( 1 + ${#xs[*]} )) + xs=() + { + echo $(( 2 + ${#xs[*]} )) + xs=() + if :; then echo $(( 3 + ${#xs[*]} )); fi + } +) + +iδ=() ( + =id=() { + ===() + if :; then echo $*; fi; === $* + }; =id= $* +); id= iδ= iδ= iδ= + +function f=() ( + function f=f { + function f=f= + if :; then echo $*; fi; f\=f\= $* + }; f\=f $* +); f= f\= f= f= + +# Parens are not escaped, hence this is invalid variable assignment. +f=f() +{ + f=f=() + ( + f=f=f() + if :; then :; fi + ) +} diff --git a/runtime/syntax/testdir/input/vim_ex_def.vim b/runtime/syntax/testdir/input/vim_ex_def.vim index 7b1d39f4d1..a48273f875 100644 --- a/runtime/syntax/testdir/input/vim_ex_def.vim +++ b/runtime/syntax/testdir/input/vim_ex_def.vim @@ -124,3 +124,10 @@ enddef silent! def Foo() enddef + +" Unreported issue (return type colon must follow immediately after closing parameter-list paren) + +def Foo() +: echo "not a mismatched return type" +enddef + diff --git a/runtime/syntax/testdir/input/vim_ex_syntax.vim b/runtime/syntax/testdir/input/vim_ex_syntax.vim index 851931206c..f8412446ba 100644 --- a/runtime/syntax/testdir/input/vim_ex_syntax.vim +++ b/runtime/syntax/testdir/input/vim_ex_syntax.vim @@ -375,3 +375,15 @@ syntax cluster typstCodeKeywords syn match slrnrcColorInit contained "^\s*color\s\+\S\+" skipwhite nextgroup=slrnrcColorVal\(Str\)\= contains=slrnrcColor\(Obj\|ObjStr\)\= syn region slrnrcCmdLine matchgroup=slrnrcCmd start="\<\(autobaud\|...\|visible_headers\)\>" end="$" oneline contains=slrnrc\(String\|Comment\) +" :syntax keyword — oneline accepted but meaningless +syntax keyword TestKw foo bar oneline +syntax keyword TestKw2 oneline baz quux + +" :syntax match — oneline accepted but meaningless +syntax match TestMatch /\/ oneline +syntax match TestMatch2 oneline /\/ + +" :syntax region — oneline is meaningful here +syntax region TestRegion start=/{/ end=/}/ oneline +syntax region TestRegion2 oneline start=/"/ end=/"/ +syntax region TestRegion3 start=/\/\*/ end=/\*\// oneline containedin=ALL diff --git a/runtime/syntax/testdir/runtest.vim b/runtime/syntax/testdir/runtest.vim index f71ccf1638..b3a6612b77 100644 --- a/runtime/syntax/testdir/runtest.vim +++ b/runtime/syntax/testdir/runtest.vim @@ -76,7 +76,14 @@ let s:vimcmdSyntaxFname = fnameescape(syntaxDir .. '/testdir/vimcmd') if filereadable(s:vimcmdSyntaxFname) call delete('vimcmd') call filecopy(s:vimcmdSyntaxFname, 'vimcmd') - exe 'au ExitPre call delete("' .. fnameescape(getcwd() .. '/vimcmd') .. '")' + " Work around uneventful support for ":cquit". + exe printf("%s\n%s\n%s", + \ 'def s:DeleteVimcmdCopy()', + \ 'delete("' .. fnameescape(getcwd() .. '/vimcmd') .. '")', + \ 'enddef') +else + def s:DeleteVimcmdCopy() + enddef endif source util/screendump.vim @@ -87,6 +94,7 @@ exe 'cd ' .. fnameescape(syntaxDir) " MS-Windows the console only has 16 colors and the GUI can't run in a " terminal. if !CanRunVimInTerminal() + call s:DeleteVimcmdCopy() call Fatal('Cannot make screendumps, aborting') endif @@ -240,6 +248,7 @@ def s:TermWaitAndPollRuler(buf: number, in_name_and_out_name: string): list +" Upstream: https://github.com/redavy/vim-tolk +" Last Update: 28 May 2026 + +if exists("b:current_syntax") + finish +endif + +" Keywords +syn keyword tolkKeyword do if as fun asm get try var val lazy +syn keyword tolkKeyword else enum true tolk const false throw +syn keyword tolkKeyword redef while catch return assert import +syn keyword tolkKeyword global repeat contract mutate struct +syn keyword tolkKeyword match type null void never + +" Strings +syn region tolkString start=+"+ end=+"+ +syn region tolkString start=+'+ end=+'+ + +" Numbers +syn match tolkNumber "\<[0-9]\+\>" +syn match tolkNumber "\<0[xX][0-9a-fA-F]\+\>" +syn match tolkNumber "\<[0-9]\+\.[0-9]\+\>" + +" Comments +syn match tolkComment "//.*$" +syn region tolkComment start="/\*" end="\*/" + +" Highlights +hi link tolkKeyword Keyword +hi link tolkString String +hi link tolkNumber Number +hi link tolkComment Comment + +let b:current_syntax = "tolk" diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index 06875ecfb7..2b6f48e63c 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -2,7 +2,7 @@ " Language: Vim script " Maintainer: Hirohito Higashi " Doug Kearns -" Last Change: 2026 Apr 07 +" Last Change: 2026 May 24 " Former Maintainer: Charles E. Campbell " DO NOT CHANGE DIRECTLY. @@ -68,25 +68,25 @@ syn keyword vimOption contained al aleph ari allowrevins ambw ambiwidth arab ara syn keyword vimOption contained co columns com comments cms commentstring cp compatible cpt complete cfu completefunc cia completeitemalign cot completeopt cpp completepopup csl completeslash cto completetimeout cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dia diffanchors dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile skipwhite nextgroup=vimSetEqual,vimSetMod syn keyword vimOption contained efm errorformat ek esckeys ei eventignore eiw eventignorewin et expandtab ex exrc fenc fileencoding fencs fileencodings ff fileformat ffs fileformats fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight skipwhite nextgroup=vimSetEqual,vimSetMod syn keyword vimOption contained hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert ims imsearch imsf imstatusfunc 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 lhi lhistory 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 skipwhite nextgroup=vimSetEqual,vimSetMod -syn keyword vimOption contained mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot msc maxsearchcount mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus 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 ost osctimeoutlen 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 skipwhite nextgroup=vimSetEqual,vimSetMod -syn keyword vimOption contained popt printoptions prompt pb pumborder ph pumheight pmw pummaxwidth pumopt pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions 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 skipwhite nextgroup=vimSetEqual,vimSetMod -syn keyword vimOption contained sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline stlo statuslineopt su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors skipwhite nextgroup=vimSetEqual,vimSetMod -syn keyword vimOption contained trz termresize tsy termsync 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 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 skipwhite nextgroup=vimSetEqual,vimSetMod -syn keyword vimOption contained wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wst wlsteal wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod +syn keyword vimOption contained mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot msc maxsearchcount mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines mlst modelinestrict ma modifiable mod modified more mouse mousef mousefocus 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 ost osctimeoutlen 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 skipwhite nextgroup=vimSetEqual,vimSetMod +syn keyword vimOption contained pmbfn printmbfont popt printoptions prompt pb pumborder ph pumheight pmw pummaxwidth pumopt pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions 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 sop scrolloffpad 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 skipwhite nextgroup=vimSetEqual,vimSetMod +syn keyword vimOption contained shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline stlo statuslineopt su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tsc tagsecure tgst tagstack tcldll term tbidi termbidi skipwhite nextgroup=vimSetEqual,vimSetMod +syn keyword vimOption contained tenc termencoding tgc termguicolors trz termresize tsy termsync 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 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 skipwhite nextgroup=vimSetEqual,vimSetMod +syn keyword vimOption contained wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod " vimOptions: These are the turn-off setting variants {{{2 " GEN_SYN_VIM: vimOption turn-off, START_STR='syn keyword vimOption contained', END_STR='' syn keyword vimOption contained noari noallowrevins noarab noarabic noarshape noarabicshape noacd noautochdir noac noautocomplete noai noautoindent noar noautoread noasd noautoshelldir noaw noautowrite noawa noautowriteall nobk nobackup nobeval noballooneval nobevalterm noballoonevalterm nobin nobinary nobomb nobri nobreakindent nobl nobuflisted nocdh nocdhome nocin nocindent nocp nocompatible nocf noconfirm noci nocopyindent nocsre nocscoperelative nocst nocscopetag nocsverb nocscopeverbose nocrb nocursorbind nocuc nocursorcolumn nocul nocursorline nodeco nodelcombine nodiff nodg nodigraph noed noedcompatible noemo noemoji noeof noendoffile noeol noendofline noea noequalalways noeb noerrorbells noek noesckeys noet noexpandtab noex noexrc nofic nofileignorecase -syn keyword vimOption contained nofixeol nofixendofline nofen nofoldenable nofs nofsync nogd nogdefault noguipty nohid nohidden nohk nohkmap nohkp nohkmapp nohls nohlsearch noicon noic noignorecase noimc noimcmdline noimd noimdisable nois noincsearch noinf noinfercase noim noinsertmode nojs nojoinspaces nolnr nolangnoremap nolrm nolangremap nolz nolazyredraw nolbr nolinebreak nolisp nolist nolpl noloadplugins nomagic noml nomodeline nomle nomodelineexpr noma nomodifiable nomod nomodified nomore nomousef nomousefocus nomh nomousehide nomousemev nomousemoveevent nonu nonumber noodev noopendevice nopaste nopi nopreserveindent nopvw nopreviewwindow noprompt noro noreadonly nornu norelativenumber noremap nors norestorescreen nori norevins norl norightleft noru noruler -syn keyword vimOption contained noscb noscrollbind noscf noscrollfocus nosecure nossl noshellslash nostmp noshelltemp nosr noshiftround nosn noshortname nosc noshowcmd nosft noshowfulltag nosm noshowmatch nosmd noshowmode noscs nosmartcase nosi nosmartindent nosta nosmarttab nosms nosmoothscroll nospell nosb nosplitbelow nospr nosplitright nosol nostartofline noswf noswapfile notbs notagbsearch notr notagrelative notgst notagstack notbidi notermbidi notgc notermguicolors notsy notermsync noterse nota notextauto notx notextmode notop notildeop noto notimeout notitle nottimeout notbi nottybuiltin notf nottyfast noudf noundofile novb novisualbell nowarn nowiv noweirdinvert nowic nowildignorecase nowmnu nowildmenu nowfb nowinfixbuf nowfh nowinfixheight nowfw nowinfixwidth -syn keyword vimOption contained nowst nowlsteal nowrap nows nowrapscan nowrite nowa nowriteany nowb nowritebackup noxtermcodes +syn keyword vimOption contained nofixeol nofixendofline nofen nofoldenable nofs nofsync nogd nogdefault noguipty nohid nohidden nohk nohkmap nohkp nohkmapp nohls nohlsearch noicon noic noignorecase noimc noimcmdline noimd noimdisable nois noincsearch noinf noinfercase noim noinsertmode nojs nojoinspaces nolnr nolangnoremap nolrm nolangremap nolz nolazyredraw nolbr nolinebreak nolisp nolist nolpl noloadplugins nomagic noml nomodeline nomle nomodelineexpr nomlst nomodelinestrict noma nomodifiable nomod nomodified nomore nomousef nomousefocus nomh nomousehide nomousemev nomousemoveevent nonu nonumber noodev noopendevice nopaste nopi nopreserveindent nopvw nopreviewwindow noprompt noro noreadonly nornu norelativenumber noremap nors norestorescreen nori norevins norl norightleft +syn keyword vimOption contained noru noruler noscb noscrollbind noscf noscrollfocus nosecure nossl noshellslash nostmp noshelltemp nosr noshiftround nosn noshortname nosc noshowcmd nosft noshowfulltag nosm noshowmatch nosmd noshowmode noscs nosmartcase nosi nosmartindent nosta nosmarttab nosms nosmoothscroll nospell nosb nosplitbelow nospr nosplitright nosol nostartofline noswf noswapfile notbs notagbsearch notr notagrelative notsc notagsecure notgst notagstack notbidi notermbidi notgc notermguicolors notsy notermsync noterse nota notextauto notx notextmode notop notildeop noto notimeout notitle nottimeout notbi nottybuiltin notf nottyfast noudf noundofile novb novisualbell nowarn nowiv noweirdinvert nowic nowildignorecase nowmnu nowildmenu nowfb nowinfixbuf nowfh nowinfixheight +syn keyword vimOption contained nowfw nowinfixwidth nowrap nows nowrapscan nowrite nowa nowriteany nowb nowritebackup noxtermcodes " vimOptions: These are the invertible variants {{{2 " GEN_SYN_VIM: vimOption invertible, START_STR='syn keyword vimOption contained', END_STR='' syn keyword vimOption contained invari invallowrevins invarab invarabic invarshape invarabicshape invacd invautochdir invac invautocomplete invai invautoindent invar invautoread invasd invautoshelldir invaw invautowrite invawa invautowriteall invbk invbackup invbeval invballooneval invbevalterm invballoonevalterm invbin invbinary invbomb invbri invbreakindent invbl invbuflisted invcdh invcdhome invcin invcindent invcp invcompatible invcf invconfirm invci invcopyindent invcsre invcscoperelative invcst invcscopetag invcsverb invcscopeverbose invcrb invcursorbind invcuc invcursorcolumn invcul invcursorline invdeco invdelcombine invdiff invdg invdigraph inved invedcompatible invemo invemoji inveof invendoffile inveol invendofline invea invequalalways inveb inverrorbells -syn keyword vimOption contained invek invesckeys invet invexpandtab invex invexrc invfic invfileignorecase invfixeol invfixendofline invfen invfoldenable invfs invfsync invgd invgdefault invguipty invhid invhidden invhk invhkmap invhkp invhkmapp invhls invhlsearch invicon invic invignorecase invimc invimcmdline invimd invimdisable invis invincsearch invinf invinfercase invim invinsertmode invjs invjoinspaces invlnr invlangnoremap invlrm invlangremap invlz invlazyredraw invlbr invlinebreak invlisp invlist invlpl invloadplugins invmagic invml invmodeline invmle invmodelineexpr invma invmodifiable invmod invmodified invmore invmousef invmousefocus invmh invmousehide invmousemev invmousemoveevent invnu invnumber invodev invopendevice invpaste invpi invpreserveindent -syn keyword vimOption contained invpvw invpreviewwindow invprompt invro invreadonly invrnu invrelativenumber invremap invrs invrestorescreen invri invrevins invrl invrightleft invru invruler invscb invscrollbind invscf invscrollfocus invsecure invssl invshellslash invstmp invshelltemp invsr invshiftround invsn invshortname invsc invshowcmd invsft invshowfulltag invsm invshowmatch invsmd invshowmode invscs invsmartcase invsi invsmartindent invsta invsmarttab invsms invsmoothscroll invspell invsb invsplitbelow invspr invsplitright invsol invstartofline invswf invswapfile invtbs invtagbsearch invtr invtagrelative invtgst invtagstack invtbidi invtermbidi invtgc invtermguicolors invtsy invtermsync invterse invta invtextauto invtx invtextmode invtop invtildeop invto invtimeout -syn keyword vimOption contained invtitle invttimeout invtbi invttybuiltin invtf invttyfast invudf invundofile invvb invvisualbell invwarn invwiv invweirdinvert invwic invwildignorecase invwmnu invwildmenu invwfb invwinfixbuf invwfh invwinfixheight invwfw invwinfixwidth invwst invwlsteal invwrap invws invwrapscan invwrite invwa invwriteany invwb invwritebackup invxtermcodes +syn keyword vimOption contained invek invesckeys invet invexpandtab invex invexrc invfic invfileignorecase invfixeol invfixendofline invfen invfoldenable invfs invfsync invgd invgdefault invguipty invhid invhidden invhk invhkmap invhkp invhkmapp invhls invhlsearch invicon invic invignorecase invimc invimcmdline invimd invimdisable invis invincsearch invinf invinfercase invim invinsertmode invjs invjoinspaces invlnr invlangnoremap invlrm invlangremap invlz invlazyredraw invlbr invlinebreak invlisp invlist invlpl invloadplugins invmagic invml invmodeline invmle invmodelineexpr invmlst invmodelinestrict invma invmodifiable invmod invmodified invmore invmousef invmousefocus invmh invmousehide invmousemev invmousemoveevent invnu invnumber invodev invopendevice invpaste +syn keyword vimOption contained invpi invpreserveindent invpvw invpreviewwindow invprompt invro invreadonly invrnu invrelativenumber invremap invrs invrestorescreen invri invrevins invrl invrightleft invru invruler invscb invscrollbind invscf invscrollfocus invsecure invssl invshellslash invstmp invshelltemp invsr invshiftround invsn invshortname invsc invshowcmd invsft invshowfulltag invsm invshowmatch invsmd invshowmode invscs invsmartcase invsi invsmartindent invsta invsmarttab invsms invsmoothscroll invspell invsb invsplitbelow invspr invsplitright invsol invstartofline invswf invswapfile invtbs invtagbsearch invtr invtagrelative invtsc invtagsecure invtgst invtagstack invtbidi invtermbidi invtgc invtermguicolors invtsy invtermsync invterse invta invtextauto +syn keyword vimOption contained invtx invtextmode invtop invtildeop invto invtimeout invtitle invttimeout invtbi invttybuiltin invtf invttyfast invudf invundofile invvb invvisualbell invwarn invwiv invweirdinvert invwic invwildignorecase invwmnu invwildmenu invwfb invwinfixbuf invwfh invwinfixheight invwfw invwinfixwidth invwrap invws invwrapscan invwrite invwa invwriteany invwb invwritebackup invxtermcodes " termcap codes (which can also be set) {{{2 " GEN_SYN_VIM: vimOption term output code, START_STR='syn keyword vimOption contained', END_STR='skipwhite nextgroup=vimSetEqual,vimSetMod' 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 t_BS t_ES skipwhite nextgroup=vimSetEqual,vimSetMod @@ -107,11 +107,11 @@ syn keyword vimOptionVarName contained al aleph ari allowrevins ambw ambiwidth a syn keyword vimOptionVarName contained co columns com comments cms commentstring cp compatible cpt complete cfu completefunc cia completeitemalign cot completeopt cpp completepopup csl completeslash cto completetimeout cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dia diffanchors dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile syn keyword vimOptionVarName contained efm errorformat ek esckeys ei eventignore eiw eventignorewin et expandtab ex exrc fenc fileencoding fencs fileencodings ff fileformat ffs fileformats fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight syn keyword vimOptionVarName contained hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert ims imsearch imsf imstatusfunc 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 lhi lhistory 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 -syn keyword vimOptionVarName contained mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot msc maxsearchcount mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse mousef mousefocus 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 ost osctimeoutlen 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 -syn keyword vimOptionVarName contained pmbfn printmbfont popt printoptions prompt pb pumborder ph pumheight pmw pummaxwidth pumopt pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions 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 -syn keyword vimOptionVarName contained shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline stlo statuslineopt su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi -syn keyword vimOptionVarName contained tenc termencoding tgc termguicolors trz termresize tsy termsync 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 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 -syn keyword vimOptionVarName contained wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wst wlsteal wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes +syn keyword vimOptionVarName contained mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot msc maxsearchcount mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines mlst modelinestrict ma modifiable mod modified more mouse mousef mousefocus 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 ost osctimeoutlen 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 +syn keyword vimOptionVarName contained pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt pb pumborder ph pumheight pmw pummaxwidth pumopt pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber remap rop renderoptions 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 sop scrolloffpad 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 +syn keyword vimOptionVarName contained sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline stpl showtabpanel ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline stlo statuslineopt su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax tpl tabpanel tplo tabpanelopt ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tsc tagsecure +syn keyword vimOptionVarName contained tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors trz termresize tsy termsync 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 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 +syn keyword vimOptionVarName contained wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight whl winhighlight wmh winminheight wmw winminwidth winptydll wiw winwidth wse wlseat wtm wltimeoutlen wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes " GEN_SYN_VIM: vimOption term output code variable, START_STR='syn keyword vimOptionVarName contained', END_STR='' syn keyword vimOptionVarName 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 t_BS t_ES syn keyword vimOptionVarName 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 @@ -126,16 +126,16 @@ syn match vimOptionVarName contained "t_k;" " unsupported settings: some were supported by vi but don't do anything in vim {{{2 " GEN_SYN_VIM: Missing vimOption, START_STR='syn keyword vimErrSetting contained', END_STR='' -syn keyword vimErrSetting contained akm altkeymap anti antialias ap autoprint bf beautify biosk bioskey consk conskey fk fkmap fl flash gr graphic ht hardtabs macatsui mesg novice open opt optimize oft osfiletype redraw slow slowopen sourceany w1200 w300 w9600 -syn keyword vimErrSetting contained noakm noaltkeymap noanti noantialias noap noautoprint nobf nobeautify nobiosk nobioskey noconsk noconskey nofk nofkmap nofl noflash nogr nographic nomacatsui nomesg nonovice noopen noopt nooptimize noredraw noslow noslowopen nosourceany -syn keyword vimErrSetting contained invakm invaltkeymap invanti invantialias invap invautoprint invbf invbeautify invbiosk invbioskey invconsk invconskey invfk invfkmap invfl invflash invgr invgraphic invmacatsui invmesg invnovice invopen invopt invoptimize invredraw invslow invslowopen invsourceany +syn keyword vimErrSetting contained akm altkeymap anti antialias ap autoprint bf beautify biosk bioskey consk conskey fk fkmap fl flash gr graphic ht hardtabs macatsui mesg novice open opt optimize oft osfiletype redraw slow slowopen sourceany w1200 w300 w9600 wst wlsteal +syn keyword vimErrSetting contained noakm noaltkeymap noanti noantialias noap noautoprint nobf nobeautify nobiosk nobioskey noconsk noconskey nofk nofkmap nofl noflash nogr nographic nomacatsui nomesg nonovice noopen noopt nooptimize noredraw noslow noslowopen nosourceany nowst nowlsteal +syn keyword vimErrSetting contained invakm invaltkeymap invanti invantialias invap invautoprint invbf invbeautify invbiosk invbioskey invconsk invconskey invfk invfkmap invfl invflash invgr invgraphic invmacatsui invmesg invnovice invopen invopt invoptimize invredraw invslow invslowopen invsourceany invwst invwlsteal " AutoCmd Events {{{2 syn case ignore " GEN_SYN_VIM: vimAutoEvent, START_STR='syn keyword vimAutoEvent contained', END_STR='skipwhite nextgroup=vimAutoEventSep,@vimAutocmdPattern' 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 CmdlineLeavePre 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 skipwhite nextgroup=vimAutoEventSep,@vimAutocmdPattern -syn keyword vimAutoEvent contained FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave InsertLeavePre KeyInputPre MenuPopup ModeChanged OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SafeState SafeStateAgain SessionLoadPost SessionLoadPre SessionWritePost ShellCmdPost ShellFilterPost SigUSR1 SourceCmd SourcePost SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabClosedPre TabEnter TabLeave TabNew TermChanged TerminalOpen TerminalWinOpen TermResponse TermResponseAll TextChanged TextChangedI TextChangedP TextChangedT TextYankPost VimEnter VimLeave VimLeavePre VimResized VimResume VimSuspend WinClosed WinEnter WinLeave WinNew WinNewPre skipwhite nextgroup=vimAutoEventSep,@vimAutocmdPattern -syn keyword vimAutoEvent contained WinResized WinScrolled skipwhite nextgroup=vimAutoEventSep,@vimAutocmdPattern +syn keyword vimAutoEvent contained FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave InsertLeavePre KeyInputPre MenuPopup ModeChanged OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SafeState SafeStateAgain SessionLoadPost SessionLoadPre SessionWritePost ShellCmdPost ShellFilterPost SigUSR1 SourceCmd SourcePost SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabClosedPre TabEnter TabLeave TabNew TermChanged TerminalOpen TerminalWinOpen TermResponse TermResponseAll TextChanged TextChangedI TextChangedP TextChangedT TextPutPost TextPutPre TextYankPost VimEnter VimLeave VimLeavePre VimResized VimResume VimSuspend WinClosed WinEnter skipwhite nextgroup=vimAutoEventSep,@vimAutocmdPattern +syn keyword vimAutoEvent contained WinLeave WinNew WinNewPre WinResized WinScrolled skipwhite nextgroup=vimAutoEventSep,@vimAutocmdPattern syn keyword vimAutoEvent contained User skipwhite nextgroup=vimUserAutoEvent syn match vimUserAutoEvent contained "\<\h\w*\>" skipwhite nextgroup=vimUserAutoEventSep,vimAutocmdMod,vimAutocmdBlock @@ -146,8 +146,8 @@ syn keyword vimGroup contained Added Bold BoldItalic Boolean Changed Character C " 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 DiffTextAdd PmenuSbar TabLineSel TabLineFill TabPanel TabPanelSel TabPanelFill Cursor lCursor TitleBar TitleBarNC QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuMatch PmenuMatchSel PmenuExtra PmenuExtraSel PmenuBorder PopupSelected MessageWindow PopupNotification PreInsert Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb PmenuShadow Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn MatchParen StatusLineTerm StatusLineTermNC ToolbarLine -syn keyword vimHLGroup contained ToolbarButton TitleBar TitleBarNC Menu Tooltip Scrollbar CursorIM ComplMatchIns LineNrAbove LineNrBelow MsgArea Terminal User1 User2 User3 User4 User5 User6 User7 User8 User9 +syn keyword vimHLGroup contained ErrorMsg IncSearch ModeMsg NonText StatusLine StatusLineNC EndOfBuffer VertSplit VertSplitNC VisualNOS DiffText DiffTextAdd PmenuSbar TabLineSel TabLineFill TabPanel TabPanelSel TabPanelFill Cursor lCursor TitleBar TitleBarNC QuickFixLine CursorLineSign CursorLineFold CurSearch PmenuKind PmenuKindSel PmenuMatch PmenuMatchSel PmenuExtra PmenuExtraSel PmenuBorder PopupSelected Popup PopupBorder PopupTitle MessageWindow PopupNotification PreInsert Normal Directory LineNr CursorLineNr MoreMsg Question Search SpellBad SpellCap SpellRare SpellLocal PmenuThumb PmenuShadow Pmenu PmenuSel SpecialKey Title WarningMsg WildMenu Folded FoldColumn SignColumn Visual DiffAdd DiffChange DiffDelete TabLine CursorColumn CursorLine ColorColumn MatchParen +syn keyword vimHLGroup contained StatusLineTerm StatusLineTermNC ToolbarLine ToolbarButton TitleBar TitleBarNC Menu Tooltip Scrollbar CursorIM ComplMatchIns LineNrAbove LineNrBelow MsgArea Terminal User1 User2 User3 User4 User5 User6 User7 User8 User9 syn match vimHLGroup contained "\" syn case match @@ -159,9 +159,10 @@ syn keyword vimFuncName contained getbufline getbufoneline getbufvar getcellpixe syn keyword vimFuncName contained histget histnr hlID hlexists hlget hlset hostname iconv id indent index indexof input inputdialog inputlist inputrestore inputsave inputsecret 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 list2tuple 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 syn keyword vimFuncName contained ngettext 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 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 preinserted 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 redraw_listener_add redraw_listener_remove syn keyword vimFuncName contained 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 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 -syn keyword vimFuncName contained simplify sin sinh slice sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2blob str2float str2list str2nr strcharlen strcharpart strchars 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 -syn keyword vimFuncName contained 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 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_null_tuple 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 tuple2list type typename undofile undotree uniq uri_decode uri_encode utf16idx values virtcol virtcol2col -syn keyword vimFuncName contained visualmode wildmenumode wildtrigger 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 simplify sin sinh slice sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2blob str2float str2list str2nr strcharlen strcharpart strchars 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 tabpanel_getinfo tabpanel_scroll 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 +syn keyword vimFuncName contained 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 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_null_tuple 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 tuple2list type typename undofile undotree uniq uri_decode uri_encode +syn keyword vimFuncName contained utf16idx values virtcol virtcol2col visualmode wildmenumode wildtrigger 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 + " MacVim specific syn keyword vimFuncName contained showdefinition @@ -577,7 +578,7 @@ syn match vim9LambdaParams contained \ "(\%(\" \ skipwhite nextgroup=vim9LambdaOperator \ contains=@vim9Continue,vimDefParam,vim9LambdaParen,vim9LambdaReturnType -syn region vim9LambdaReturnType contained start=")\@<=:\s" end="\ze\s*#" end="\ze\s*=>" contains=@vim9Continue,@vimType transparent +syn region vim9LambdaReturnType contained start=")\@1<=:\s" end="\ze\s*#" end="\ze\s*=>" contains=@vim9Continue,@vimType transparent syn region vim9LambdaBlock contained matchgroup=vimSep start="{" end="^\s*\zs}" contains=@vimDefBodyList syn match vim9LambdaOperatorComment contained "#.*" skipwhite skipempty nextgroup=@vimExprList,vim9LambdaBlock,vim9LambdaOperatorComment @@ -687,7 +688,7 @@ syn match vimDelfunction "\" skipwhite nextgroup=vimDelfunct " ===== syn region vimReturnType contained - \ start=":\%(\s\|\n\)\@=" + \ start=")\@1<=:\%(\s\|\n\)\@=" \ skip=+\n\s*\%(\\\|#\\ \)\|^\s*#\\ + \ end="$" \ matchgroup=vim9Comment @@ -754,7 +755,7 @@ if s:vim9script \ contains=vim9DefTypeParam syn region vim9MethodDefReturnType contained - \ start=":\%(\s\|\n\)\@=" + \ start=")\@1<=:\%(\s\|\n\)\@=" \ skip=+\n\s*\%(\\\|#\\ \)\|^\s*#\\ + \ end="$" \ matchgroup=vim9Comment @@ -882,7 +883,7 @@ if s:vim9script \ skipwhite skipnl nextgroup=vimDefComment,vim9AbstractDefReturnType,vimCommentError \ contains=vimDefParam,vim9Comment,vimFunctionParamEquals syn region vim9AbstractDefReturnType contained - \ start=":\s" end="$" matchgroup=vim9Comment end="\ze[#"]" + \ start=")\@1<=:\s" end="$" matchgroup=vim9Comment end="\ze[#"]" \ skipwhite skipnl nextgroup=vimDefComment,vimCommentError \ contains=vimTypeSep \ transparent @@ -1925,10 +1926,11 @@ syn keyword vimSynType contained include skipwhite nextgroup=vimSynIncludeClust syn match vimSynIncludeCluster contained "@[_a-zA-Z0-9]\+\>" " Syntax: keyword {{{2 -syn cluster vimSynKeyGroup contains=@vimContinue,vimSynCchar,vimSynNextgroup,vimSynKeyOpt,vimSynContainedin +syn cluster vimSynKeyGroup contains=@vimContinue,vimSynCchar,vimSynNextgroup,vimSynKeyOpt,vimSynContainedin,vimSynKeyError syn keyword vimSynType contained keyword skipwhite nextgroup=vimSynKeyRegion syn region vimSynKeyRegion contained keepend matchgroup=vimGroupName start="\h\w*\>" skip=+\\\\\|\\|\|\n\s*\%(\\\|"\\ \)+ matchgroup=vimCmdSep end="|\|$" contains=@vimSynKeyGroup syn match vimSynKeyOpt contained "\%#=1\<\%(conceal\|contained\|transparent\|skipempty\|skipwhite\|skipnl\)\>" +syn match vimSynKeyError contained "\" " Syntax: match {{{2 syn cluster vimSynMtchGroup contains=@vimContinue,vimSynCchar,vimSynContains,vimSynContainedin,vimSynError,vimSynMtchOpt,vimSynNextgroup,vimSynRegPat,vimNotation,vimMtchComment @@ -2496,6 +2498,7 @@ if !exists("skip_vim_syntax_inits") hi def link vimSyncError vimError hi def link vimSynConcealError vimError hi def link vimSynError vimError + hi def link vimSynKeyError vimError hi def link vimSynFoldlevelError vimError hi def link vimSynIskeywordError vimError hi def link vimSynSpellError vimError diff --git a/runtime/syntax/zig.vim b/runtime/syntax/zig.vim index 121b0195b0..bf09977a5a 100644 --- a/runtime/syntax/zig.vim +++ b/runtime/syntax/zig.vim @@ -1,6 +1,6 @@ " Vim syntax file " Language: Zig -" Upstream: https://github.com/ziglang/zig.vim +" Upstream: https://codeberg.org/ziglang/zig.vim if exists("b:current_syntax") finish diff --git a/runtime/syntax/zir.vim b/runtime/syntax/zir.vim index 6553d322b7..998e6a3ed6 100644 --- a/runtime/syntax/zir.vim +++ b/runtime/syntax/zir.vim @@ -1,6 +1,6 @@ " Vim syntax file " Language: Zir -" Upstream: https://github.com/ziglang/zig.vim +" Upstream: https://codeberg.org/ziglang/zig.vim if exists("b:current_syntax") finish diff --git a/runtime/tools/ccfilter.c b/runtime/tools/ccfilter.c index ae1443e203..269e4ee662 100644 --- a/runtime/tools/ccfilter.c +++ b/runtime/tools/ccfilter.c @@ -249,14 +249,15 @@ int main( int argc, char *argv[] ) stay = (echogets(Line2, echo) != NULL); while ( stay && (Line2[0] == '|') ) - { for (p=&Line2[2]; (*p) && (isspace((unsigned char)*p)); p++); - strcat( Reason, ": " ); - strcat( Reason, p ); + { size_t n; + for (p=&Line2[2]; (*p) && (isspace((unsigned char)*p)); p++); + n = strlen(Reason); + snprintf( Reason + n, LINELENGTH - n, ": %s", p ); Line2[0] = 0; stay = (echogets(Line2, echo) != NULL); } prefetch = 1; - strcpy( Line, Line2 ); + snprintf( Line, LINELENGTH, "%s", Line2 ); break; case COMPILER_IRIX: Col = 1; @@ -291,8 +292,8 @@ int main( int argc, char *argv[] ) prefetch = 0; } else - { strcat( Line, "\n" ); - strcat( Line, Line2 ); + { size_t n = strlen(Line); + snprintf( Line + n, LINELENGTH - n, "\n%s", Line2 ); } } } diff --git a/src/INSTALL b/src/INSTALL index ab760cd13a..054df8ac24 100644 --- a/src/INSTALL +++ b/src/INSTALL @@ -61,10 +61,20 @@ To build Vim on Ubuntu from scratch on a clean system using git: % sudo apt install libxt-dev % make reconfig - Add GUI support: + Add Wayland clipboard support: + % sudo apt install libwayland-dev + % make reconfig + + Add GUI (GTK3) support: % sudo apt install libgtk-3-dev % make reconfig + Add GUI (GTK4) support: + % sudo apt install libgtk-4-dev + (GTK4 is not the default; configure with + --enable-gui=gtk4 to select it.) + % make reconfig + Add Python 3 support: % sudo apt install libpython3-dev Uncomment this line in Makefile: diff --git a/src/INSTALLpc.txt b/src/INSTALLpc.txt index 5ea4d7a04e..5021496860 100644 --- a/src/INSTALLpc.txt +++ b/src/INSTALLpc.txt @@ -183,7 +183,7 @@ src/INSTALLpc.txt file for instructions. 2. MSYS2 with MinGW =================== -2.1 Buidling x86 32bit or 64bit versions. +2.1 Building x86 32bit or 64bit versions. 2.1.1. Setup the basic msys2 environment @@ -303,7 +303,7 @@ To build Vim with the address sanitizer (ASAN), execute the following command: CXX=clang++ make -f Make_ming.mak DEBUG=yes ASAN=yes -2.2 Buidling an Arch64 version of Vim +2.2 Building an Arch64 version of Vim 2.2.1. Setup the basic msys2 environment diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 0cb83ac484..24db4ccfff 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -744,7 +744,7 @@ XPM = no endif ifdef XPM ifneq ($(XPM),no) -CFLAGS += -DFEAT_XPM_W32 -I $(XPM)/include -I $(XPM)/../include +CFLAGS += -DFEAT_XPM_W32 -I $(XPM)/include -I $(XPM)/include/X11 -I $(XPM)/../include endif endif @@ -877,10 +877,12 @@ OBJ = \ $(OUTDIR)/session.o \ $(OUTDIR)/sha256.o \ $(OUTDIR)/sign.o \ + $(OUTDIR)/socketserver.o \ $(OUTDIR)/spell.o \ $(OUTDIR)/spellfile.o \ $(OUTDIR)/spellsuggest.o \ $(OUTDIR)/strings.o \ + $(OUTDIR)/strptime.o \ $(OUTDIR)/syntax.o \ $(OUTDIR)/tabpanel.o \ $(OUTDIR)/tag.o \ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index a59b083e72..3b9ccb98f8 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -772,6 +772,7 @@ OBJ = \ $(OUTDIR)\session.obj \ $(OUTDIR)\sha256.obj \ $(OUTDIR)\sign.obj \ + $(OUTDIR)\socketserver.obj \ $(OUTDIR)\spell.obj \ $(OUTDIR)\spellfile.obj \ $(OUTDIR)\spellsuggest.obj \ @@ -785,6 +786,7 @@ OBJ = \ $(OUTDIR)\textobject.obj \ $(OUTDIR)\textprop.obj \ $(OUTDIR)\time.obj \ + $(OUTDIR)\strptime.obj \ $(OUTDIR)\tuple.obj \ $(OUTDIR)\typval.obj \ $(OUTDIR)\ui.obj \ @@ -1766,6 +1768,8 @@ $(OUTDIR)/sha256.obj: $(OUTDIR) sha256.c $(INCL) $(OUTDIR)/sign.obj: $(OUTDIR) sign.c $(INCL) +$(OUTDIR)/socketserver.obj: $(OUTDIR) socketserver.c $(INCL) + $(OUTDIR)/spell.obj: $(OUTDIR) spell.c $(INCL) $(OUTDIR)/spellfile.obj: $(OUTDIR) spellfile.c $(INCL) @@ -1792,6 +1796,8 @@ $(OUTDIR)/textprop.obj: $(OUTDIR) textprop.c $(INCL) $(OUTDIR)/time.obj: $(OUTDIR) time.c $(INCL) +$(OUTDIR)/strptime.obj: $(OUTDIR) strptime.c $(INCL) + $(OUTDIR)/tuple.obj: $(OUTDIR) tuple.c $(INCL) $(OUTDIR)/typval.obj: $(OUTDIR) typval.c $(INCL) @@ -2014,6 +2020,7 @@ proto.h: \ proto/session.pro \ proto/sha256.pro \ proto/sign.pro \ + proto/socketserver.pro \ proto/spell.pro \ proto/spellfile.pro \ proto/spellsuggest.pro \ diff --git a/src/Make_vms.mms b/src/Make_vms.mms index a238a8ab9e..e019897fac 100644 --- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -2,7 +2,7 @@ # Makefile for Vim on OpenVMS # # Maintainer: Zoltan Arpadffy -# Last change: 2025-07-04 Steven M. Schweda +# Last change: 2026-05-04 # # This script has been tested on VMS 6.2 to 9.2 on VAX, ALPHA, IA64 and X86_64 # with MMS and MMK @@ -49,6 +49,10 @@ MODEL = HUGE # If you have XPM installed you might want to build Motif version with toolbar # XPM = YES +# Large-file support. Unavailable on VAX and very old Alpha. +# To disable, define NOLARGE. +# NOLARGE = YES + # Comment out if you want the compiler version with :ver command. # NOTE: This part can make some complications if you're using some # predefined symbols/flags for your compiler. If does, just leave behind @@ -108,23 +112,23 @@ ALPHA_X_ALPHA = 1 IA64_X_IA64 = 1 VAX_X_VAX = 1 X86_64_X_X86_64 = 1 -.IFDEF ARCH # ARCH +.IFDEF ARCH # ARCH ARCH_NAME = $(ARCH) -.ELSE # ARCH +.ELSE # ARCH ARCH_NAME = $(MMS$ARCH_NAME) -.ENDIF # ARCH -.IFDEF $(ARCH_NAME)_X_ALPHA # $(ARCH_NAME)_X_ALPHA +.ENDIF # ARCH +.IFDEF $(ARCH_NAME)_X_ALPHA # $(ARCH_NAME)_X_ALPHA __ALPHA__ = 1 -.ENDIF # $(ARCH_NAME)_X_ALPHA -.IFDEF $(ARCH_NAME)_X_IA64 # $(ARCH_NAME)_X_IA64 +.ENDIF # $(ARCH_NAME)_X_ALPHA +.IFDEF $(ARCH_NAME)_X_IA64 # $(ARCH_NAME)_X_IA64 __IA64__ = 1 -.ENDIF # $(ARCH_NAME)_X_IA64 -.IFDEF $(ARCH_NAME)_X_VAX # $(ARCH_NAME)_X_VAX +.ENDIF # $(ARCH_NAME)_X_IA64 +.IFDEF $(ARCH_NAME)_X_VAX # $(ARCH_NAME)_X_VAX __VAX__ = 1 -.ENDIF # $(ARCH_NAME)_X_VAX -.IFDEF $(ARCH_NAME)_X_X86_64 # $(ARCH_NAME)_X_X86_64 +.ENDIF # $(ARCH_NAME)_X_VAX +.IFDEF $(ARCH_NAME)_X_X86_64 # $(ARCH_NAME)_X_X86_64 __X86_64__ = 1 -.ENDIF # $(ARCH_NAME)_X_X86_64 +.ENDIF # $(ARCH_NAME)_X_X86_64 .ELSE # MMS$ARCH_NAME .IFDEF __MMK__ # __MMK__ .IFDEF ARCH # ARCH @@ -234,8 +238,7 @@ PREFIX = /prefix=all/name=(upper,short) /repository=[.$(DEST)] # This makes Alpha consistent. FLOAT = /float = ieee_float /ieee_mode = denorm_results -# Large-file support. Unavailable on VAX and very old Alpha. To -# disable, define NOLARGE. +# Large-file support. Unavailable on VAX and very old Alpha. .IFDEF NOLARGE .ELSE LARGE_DEF = , "_LARGEFILE" @@ -811,15 +814,14 @@ $(TARGET) : $(OBJ) .c.obj : # Override /optimize for selected modules on VAX. .IFDEF __VAX__ # __VAX__ - @ mod = f$parse( "$@", , , "NAME", "SYNTAX_ONLY") - @ mod = "+"+ f$edit( mod, "LOWERCASE")+ "+" - @ optim_qual = "" - @ if (f$locate( mod, "+$(VAX_NOOPTIM_LIST)+") .lt. - + -@ mod = f$parse( "$@", , , "NAME", "SYNTAX_ONLY") + -@ mod = "+"+ f$edit( mod, "LOWERCASE")+ "+" + -@ optim_qual = "" + -@ if (f$locate( mod, "+$(VAX_NOOPTIM_LIST)+") .lt. - f$length( "+$(VAX_NOOPTIM_LIST)+")) then optim_qual = "/nooptim" - @ if (f$locate( mod, "+$(VAX_NOOPTIM_LIST)+") .lt. - + -@ if (f$locate( mod, "+$(VAX_NOOPTIM_LIST)+") .lt. - f$length( "+$(VAX_NOOPTIM_LIST)+")) then - - @ write sys$output - - " *** NOTE: USING SPECIAL /NOOPTIMIZE RULE. ***" + write sys$output "*** NOTE: USING SPECIAL /NOOPTIMIZE RULE. ***" $(CC_DEF) $(ALL_CFLAGS) 'optim_qual' $< /object = $@ .ELSE # __VAX__ $(CC_DEF) $(ALL_CFLAGS) $< /object = $@ @@ -1468,8 +1470,8 @@ lua_env : [.$(DEST)]gui_gtk_x11.obj : gui_gtk_x11.c vim.h [.$(DEST)]config.h feature.h os_unix.h \ ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \ gui.h beval.h option.h ex_cmds.h proto.h \ - errors.h globals.h gui_gtk_f.h [-.runtime]vim32x32_png.h \ - [-.runtime]vim16x16_png.h [-.runtime]vim48x48_png.h version.h + errors.h globals.h gui_gtk_f.h [-.runtime]vim32x32.xpm \ + [-.runtime]vim16x16.xpm [-.runtime]vim48x48.xpm version.h [.$(DEST)]gui_x11.obj : gui_x11.c vim.h [.$(DEST)]config.h feature.h os_unix.h \ ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \ gui.h beval.h option.h ex_cmds.h proto.h \ diff --git a/src/Makefile b/src/Makefile index 09d2eef127..bd03bcf94b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1232,6 +1232,23 @@ GTK_MAN_TARGETS = yes GTK_TESTTARGET = gui GTK_BUNDLE = +### GTK4 GUI +GTK4_SRC = gui.c gui_gtk4.c gui_gtk4_f.c \ + $(GRESOURCE_SRC) +GTK4_OBJ = objects/gui.o objects/gui_gtk4.o \ + objects/gui_gtk4_f.o \ + $(GRESOURCE_OBJ) +GTK4_DEFS = -DFEAT_GUI_GTK $(NARROW_PROTO) +GTK4_IPATH = $(GUI_INC_LOC) +GTK4_LIBS_DIR = $(GUI_LIB_LOC) +GTK4_LIBS1 = +GTK4_LIBS2 = $(GTK_LIBNAME) +GTK4_INSTALL = install_normal install_gui_extra +GTK4_TARGETS = installglinks +GTK4_MAN_TARGETS = yes +GTK4_TESTTARGET = gui +GTK4_BUNDLE = + ### Motif GUI MOTIF_SRC = gui.c gui_motif.c gui_x11.c gui_beval.c \ gui_xmdlg.c gui_xmebw.c @@ -1306,8 +1323,8 @@ MACVIMGUI_BUNDLE = macvim MACVIMGUI_TESTARG = VIMPROG=../$(RELEASEDIR)/MacVim.app/Contents/MacOS/$(VIMTARGET) # All GUI files -ALL_GUI_SRC = gui.c gui_gtk.c gui_gtk_f.c gui_motif.c gui_xmdlg.c gui_xmebw.c gui_gtk_x11.c gui_x11.c gui_haiku.cc -ALL_GUI_PRO = proto/gui.pro proto/gui_gtk.pro proto/gui_motif.pro proto/gui_xmdlg.pro proto/gui_gtk_x11.pro proto/gui_x11.pro proto/gui_w32.pro proto/gui_photon.pro +ALL_GUI_SRC = gui.c gui_gtk.c gui_gtk_f.c gui_gtk4.c gui_gtk4_f.c gui_motif.c gui_xmdlg.c gui_xmebw.c gui_gtk_x11.c gui_x11.c gui_haiku.cc +ALL_GUI_PRO = proto/gui.pro proto/gui_gtk.pro proto/gui_gtk4.pro proto/gui_motif.pro proto/gui_xmdlg.pro proto/gui_gtk_x11.pro proto/gui_x11.pro proto/gui_w32.pro proto/gui_photon.pro ALL_GUI_SRC += MacVim/gui_macvim.m MacVim/MMBackend.m MacVim/MacVim.m @@ -1573,6 +1590,7 @@ BASIC_SRC = \ session.c \ sha256.c \ sign.c \ + socketserver.c \ sound.c \ spell.c \ spellfile.c \ @@ -1635,8 +1653,6 @@ genwaylandproto: # Needed for parallel jobs to work auto/wayland/ext-data-control-v1.h: auto/wayland/ext-data-control-v1.c auto/wayland/wlr-data-control-unstable-v1.h: auto/wayland/wlr-data-control-unstable-v1.c -auto/wayland/primary-selection-unstable-v1.h: auto/wayland/primary-selection-unstable-v1.c -auto/wayland/xdg-shell.h: auto/wayland/xdg-shell.c # Unittest files JSON_TEST_SRC = json_test.c @@ -1753,6 +1769,7 @@ OBJ_COMMON = \ objects/session.o \ objects/sha256.o \ objects/sign.o \ + objects/socketserver.o \ objects/sound.o \ objects/spell.o \ objects/spellfile.o \ @@ -2173,7 +2190,9 @@ proto/%.pro: %.c @$(PYTHON) $(GEN_PROTO_CMD) $< $(GEN_PROTO_ARG) proto/gui_gtk_gresources.pro: auto/gui_gtk_gresources.c - @$(PYTHON) $(GEN_PROTO_CMD) $< $(GEN_PROTO_ARG) + @if test -n "$(GLIB_COMPILE_RESOURCES)"; then \ + $(PYTHON) $(GEN_PROTO_CMD) $< $(GEN_PROTO_ARG) ; \ + fi notags: -rm -f tags @@ -3202,7 +3221,9 @@ GUI_GTK_RES_INPUTS = \ ../pixmaps/stock_vim_window_split_vertical.png auto/gui_gtk_gresources.c: gui_gtk_res.xml $(GUI_GTK_RES_INPUTS) - $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=../pixmaps --generate --c-name=gui_gtk --manual-register gui_gtk_res.xml + if test -z "$(GLIB_COMPILE_RESOURCES)"; then touch $@; else \ + $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=../pixmaps --generate --c-name=gui_gtk --manual-register gui_gtk_res.xml; \ + fi auto/gui_gtk_gresources.h: gui_gtk_res.xml $(GUI_GTK_RES_INPUTS) if test -z "$(GLIB_COMPILE_RESOURCES)"; then touch $@; else \ $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=../pixmaps --generate --c-name=gui_gtk --manual-register gui_gtk_res.xml; \ @@ -3393,6 +3414,13 @@ objects/gui_gtk_gresources.o: auto/gui_gtk_gresources.c objects/gui_gtk_x11.o: gui_gtk_x11.c $(CCC) -o $@ gui_gtk_x11.c +objects/gui_gtk4.o: gui_gtk4.c + $(CCC) -o $@ gui_gtk4.c + +objects/gui_gtk4_f.o: gui_gtk4_f.c + $(CCC) -o $@ gui_gtk4_f.c + + objects/gui_haiku.o: gui_haiku.cc $(CCC) -o $@ gui_haiku.cc @@ -3600,6 +3628,9 @@ objects/sha256.o: sha256.c objects/sign.o: sign.c $(CCC) -o $@ sign.c +objects/socketserver.o: socketserver.c + $(CCC) -o $@ socketserver.c + objects/sound.o: sound.c $(CCC) -o $@ sound.c @@ -3708,12 +3739,6 @@ objects/wlr-data-control-unstable-v1.o: auto/wayland/wlr-data-control-unstable-v objects/ext-data-control-v1.o: auto/wayland/ext-data-control-v1.c $(CCC) $(WAYLAND_CFLAGS) $(WAYLAND_CPPFLAGS) -o $@ auto/wayland/ext-data-control-v1.c -objects/xdg-shell.o: auto/wayland/xdg-shell.c - $(CCC) $(WAYLAND_CFLAGS) $(WAYLAND_CPPFLAGS) -o $@ auto/wayland/xdg-shell.c - -objects/primary-selection-unstable-v1.o: auto/wayland/primary-selection-unstable-v1.c - $(CCC) $(WAYLAND_CFLAGS) $(WAYLAND_CPPFLAGS) -o $@ auto/wayland/primary-selection-unstable-v1.c - objects/netbeans.o: netbeans.c $(CCC) -o $@ netbeans.c @@ -4378,6 +4403,11 @@ objects/sign.o: sign.c vim.h protodef.h auto/config.h feature.h os_unix.h ascii. structs.h regexp.h gui.h libvterm/include/vterm.h \ libvterm/include/vterm_keycodes.h xdiff/xdiff.h xdiff/../vim.h alloc.h \ ex_cmds.h spell.h proto.h globals.h errors.h +objects/socketserver.o: socketserver.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \ + structs.h regexp.h gui.h libvterm/include/vterm.h \ + libvterm/include/vterm_keycodes.h xdiff/xdiff.h xdiff/../vim.h alloc.h \ + ex_cmds.h spell.h proto.h globals.h errors.h objects/sound.o: sound.c vim.h protodef.h auto/config.h feature.h os_unix.h \ ascii.h keymap.h termdefs.h macros.h option.h beval.h \ structs.h regexp.h gui.h libvterm/include/vterm.h \ @@ -4568,6 +4598,11 @@ objects/gui_gtk.o: gui_gtk.c vim.h protodef.h auto/config.h feature.h os_unix.h structs.h regexp.h gui.h libvterm/include/vterm.h \ libvterm/include/vterm_keycodes.h xdiff/xdiff.h xdiff/../vim.h alloc.h \ ex_cmds.h spell.h proto.h globals.h errors.h ../pixmaps/stock_icons.h +objects/gui_gtk4.o: gui_gtk4.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + ascii.h keymap.h termdefs.h macros.h option.h beval.h \ + structs.h regexp.h gui.h libvterm/include/vterm.h \ + libvterm/include/vterm_keycodes.h xdiff/xdiff.h xdiff/../vim.h alloc.h \ + ex_cmds.h spell.h proto.h globals.h errors.h objects/gui_gtk_x11.o: gui_gtk_x11.c vim.h protodef.h auto/config.h feature.h \ os_unix.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \ structs.h regexp.h gui.h libvterm/include/vterm.h \ @@ -4835,6 +4870,7 @@ proto/search.pro: search.c proto/session.pro: session.c proto/sha256.pro: sha256.c proto/sign.pro: sign.c +proto/socketserver.pro: socketserver.c proto/sound.pro: sound.c proto/spell.pro: spell.c proto/spellfile.pro: spellfile.c @@ -4873,6 +4909,7 @@ proto/winclip.pro: winclip.c proto/window.pro: window.c proto/gui.pro: gui.c proto/gui_gtk.pro: gui_gtk.c +proto/gui_gtk4.pro: gui_gtk4.c proto/gui_motif.pro: gui_motif.c proto/gui_xmdlg.pro: gui_xmdlg.c proto/gui_gtk_x11.pro: gui_gtk_x11.c diff --git a/src/arglist.c b/src/arglist.c index 6fccf69c26..84de912f01 100644 --- a/src/arglist.c +++ b/src/arglist.c @@ -541,7 +541,7 @@ check_arg_idx(win_T *win) { // We are not editing the current entry in the argument list. // Set "arg_had_last" if we are editing the last one. - win->w_arg_idx_invalid = TRUE; + win->w_arg_idx_invalid = true; if (win->w_arg_idx != WARGCOUNT(win) - 1 && arg_had_last == FALSE && ALIST(win) == &global_alist @@ -557,7 +557,7 @@ check_arg_idx(win_T *win) { // We are editing the current entry in the argument list. // Set "arg_had_last" if it's also the last one - win->w_arg_idx_invalid = FALSE; + win->w_arg_idx_invalid = false; if (win->w_arg_idx == WARGCOUNT(win) - 1 && win->w_alist == &global_alist) arg_had_last = TRUE; diff --git a/src/auto/configure b/src/auto/configure index eec35c2719..9ec6f2f0d8 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -856,7 +856,6 @@ enable_netbeans enable_channel enable_terminal enable_autoservername -enable_socketserver enable_multibyte enable_rightleft enable_arabic @@ -864,11 +863,11 @@ enable_farsi enable_xim enable_fontset with_wayland -enable_wayland_focus_steal with_x enable_gui enable_gtk2_check enable_gnome_check +enable_gtk4_check enable_gtk3_check enable_motif_check enable_macvim_check @@ -1542,19 +1541,16 @@ Optional Features: --disable-channel Disable process communication support. --enable-terminal Enable terminal emulation support. --enable-autoservername Automatically define servername at vim startup. - --enable-socketserver Use sockets for clientserver communication. --enable-multibyte Include multibyte editing support. --disable-rightleft Do not include Right-to-Left language support. --disable-arabic Do not include Arabic language support. --disable-farsi Deprecated. --enable-xim Include XIM input support. --enable-fontset Include X fontset output support. - --enable-wayland-focus-steal - Include focus stealing support for Wayland - clipboard. - --enable-gui=OPTS X11 GUI. default=auto OPTS=auto/no/gtk2/gnome2/gtk3/motif/haiku/photon/carbon/macvim + --enable-gui=OPTS X11 GUI. default=auto OPTS=auto/no/gtk2/gnome2/gtk3/gtk4/motif/haiku/photon/carbon/macvim --enable-gtk2-check If auto-select GUI, check for GTK+ 2 default=yes --enable-gnome-check If GTK GUI, check for GNOME default=no + --enable-gtk4-check If auto-select GUI, check for GTK 4 default=yes --enable-gtk3-check If auto-select GUI, check for GTK+ 3 default=yes --enable-motif-check If auto-select GUI, check for Motif default=yes --enable-macvim-check If auto-select GUI, check for MacVim default=yes @@ -5352,7 +5348,7 @@ fi CPPFLAGS=$SAVE_CPPFLAGS CFLAGS=$SAVE_CFLAGS - if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then + if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3 -a "X$enable_gui" != Xgtk4; then with_x=no fi fi @@ -9321,36 +9317,6 @@ if test "$enable_autoservername" = "yes"; then fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --enable-socketserver argument" >&5 -printf %s "checking --enable-socketserver argument... " >&6; } -# Check whether --enable-socketserver was given. -if test ${enable_socketserver+y} -then : - enableval=$enable_socketserver; enable_socketserver=$enableval -else case e in #( - e) if test "x$features" = xtiny -then : - enable_socketserver=no_msg - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cannot use socketserver with tiny features" >&5 -printf "%s\n" "cannot use socketserver with tiny features" >&6; } -else case e in #( - e) enable_socketserver=yes ;; -esac -fi ;; -esac -fi - - -if test "$enable_socketserver" = "yes"; then - printf "%s\n" "#define WANT_SOCKETSERVER 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } -elif test "$enable_socketserver" = "no"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --enable-multibyte argument" >&5 printf %s "checking --enable-multibyte argument... " >&6; } # Check whether --enable-multibyte was given. @@ -9510,30 +9476,6 @@ printf %s "checking for wayland... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --enable-wayland-focus-steal argument" >&5 -printf %s "checking --enable-wayland-focus-steal argument... " >&6; } - # Check whether --enable-wayland-focus-steal was given. -if test ${enable_wayland_focus_steal+y} -then : - enableval=$enable_wayland_focus_steal; enable_wayland_fs=$enableval -else case e in #( - e) enable_wayland_fs="yes" ;; -esac -fi - - - if test "$enable_wayland_fs" = "yes" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - printf "%s\n" "#define FEAT_WAYLAND_CLIPBOARD_FS 1" >>confdefs.h - -else case e in #( - e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } ;; -esac -fi - printf "%s\n" "#define HAVE_WAYLAND 1" >>confdefs.h WAYLAND_CPPFLAGS=`$PKG_CONFIG --cflags-only-I wayland-client` @@ -9550,16 +9492,6 @@ fi objects/ext-data-control-v1.o \ objects/wayland.o" - if test "$enable_wayland_fs" = "yes" -then : - as_fn_append WAYLAND_SRC " \ - auto/wayland/xdg-shell.c \ - auto/wayland/primary-selection-unstable-v1.c" - as_fn_append WAYLAND_OBJ " \ - objects/xdg-shell.o \ - objects/primary-selection-unstable-v1.o" -fi - @@ -9574,8 +9506,11 @@ CPPFLAGS=$cppflags_save CFLAGS=$cflags_save fi +if test "x$enable_gui" = "xgtk4"; then + with_x=no +fi test -z "$with_x" && with_x=yes -test "${enable_gui-yes}" != no -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" && with_x=yes +test "${enable_gui-yes}" != no -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" -a "x$enable_gui" != "xgtk4" && with_x=yes if test "$with_x" = no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: defaulting to: don't HAVE_X11" >&5 printf "%s\n" "defaulting to: don't HAVE_X11" >&6; } @@ -10743,11 +10678,11 @@ printf "%s\n" "#define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t" >>confdefs.h fi fi -if test "x$with_x" = xno -a "x$with_x_arg" = xyes; then +if test "x$with_x" = xno -a "x$with_x_arg" = xyes -a "x$enable_gui" != "xgtk4"; then as_fn_error $? "could not configure X" "$LINENO" 5 fi -test "x$with_x" = xno -a "x$HAIKU" != "xyes" -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" && enable_gui=no +test "x$with_x" = xno -a "x$HAIKU" != "xyes" -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" -a "x$enable_gui" != xgtk4 && enable_gui=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --enable-gui argument" >&5 printf %s "checking --enable-gui argument... " >&6; } @@ -10766,6 +10701,7 @@ enable_gui_canon=`echo "_$enable_gui" | \ SKIP_GTK2=YES SKIP_GTK3=YES +SKIP_GTK4=YES SKIP_GNOME=YES SKIP_MOTIF=YES SKIP_PHOTON=YES @@ -10797,7 +10733,7 @@ printf "%s\n" "no GUI support" >&6; } SKIP_PHOTON=YES ;; yes|""|auto) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: automatic GUI support" >&5 printf "%s\n" "automatic GUI support" >&6; } - gui_auto=yes ;; + gui_auto=yes ;; photon) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Photon GUI support" >&5 printf "%s\n" "Photon GUI support" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Sorry, $enable_gui GUI is not supported" >&5 @@ -10813,7 +10749,7 @@ printf "%s\n" "no GUI support" >&6; } SKIP_MACVIM=YES ;; yes|""|auto) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: automatic GUI support" >&5 printf "%s\n" "automatic GUI support" >&6; } - gui_auto=yes ;; + gui_auto=yes ;; macvim) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: MacVim GUI support" >&5 printf "%s\n" "MacVim GUI support" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Sorry, $enable_gui GUI is not supported" >&5 @@ -10830,6 +10766,7 @@ printf "%s\n" "yes/auto - automatic GUI support" >&6; } gui_auto=yes SKIP_GTK2= SKIP_GTK3= + SKIP_GTK4= SKIP_GNOME= SKIP_MACVIM= SKIP_MOTIF=;; @@ -10843,6 +10780,9 @@ printf "%s\n" "GNOME 2.x GUI support" >&6; } gtk3) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: GTK+ 3.x GUI support" >&5 printf "%s\n" "GTK+ 3.x GUI support" >&6; } SKIP_GTK3=;; + gtk4) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: GTK 4.x GUI support" >&5 +printf "%s\n" "GTK 4.x GUI support" >&6; } + SKIP_GTK4=;; motif) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Motif GUI support" >&5 printf "%s\n" "Motif GUI support" >&6; } SKIP_MOTIF=;; @@ -10892,6 +10832,25 @@ printf "%s\n" "$enable_gnome_check" >&6; } fi fi +if test "x$SKIP_GTK4" != "xYES" -a "$enable_gui_canon" != "gtk4"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether or not to look for GTK 4" >&5 +printf %s "checking whether or not to look for GTK 4... " >&6; } + # Check whether --enable-gtk4-check was given. +if test ${enable_gtk4_check+y} +then : + enableval=$enable_gtk4_check; +else case e in #( + e) enable_gtk4_check="yes" ;; +esac +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_gtk4_check" >&5 +printf "%s\n" "$enable_gtk4_check" >&6; } + if test "x$enable_gtk4_check" = "xno"; then + SKIP_GTK4=YES + fi +fi + if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether or not to look for GTK+ 3" >&5 printf %s "checking whether or not to look for GTK+ 3... " >&6; } @@ -11022,6 +10981,8 @@ printf "%s\n" "gtk test disabled" >&6; } gtk_pkg_name="gtk+-2.0" ;; #( 3.*) : gtk_pkg_name="gtk+-3.0" ;; #( + 4.*) : + gtk_pkg_name="gtk4" ;; #( *) : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} @@ -11038,7 +10999,7 @@ then : printf "%s\n" "found" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 printf %s "checking for GTK - version >= $min_gtk_version... " >&6; } - GTK_CPPFLAGS=`$PKG_CONFIG --cflags-only-I $gtk_pkg_name` + GTK_CPPFLAGS=`$PKG_CONFIG --cflags-only-I $gtk_pkg_name` GTK_CFLAGS=`$PKG_CONFIG --cflags-only-other $gtk_pkg_name` GTK_LIBDIR=`$PKG_CONFIG --libs-only-L $gtk_pkg_name` GTK_LIBS=`$PKG_CONFIG --libs $gtk_pkg_name` @@ -11162,6 +11123,7 @@ fi if test -n "$GTK_CPPFLAGS"; then SKIP_GTK2=YES + SKIP_GTK4=YES SKIP_GNOME=YES SKIP_MOTIF=YES GUITYPE=GTK @@ -11172,6 +11134,196 @@ fi fi fi +if test -z "$SKIP_GTK4"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5 +printf %s "checking --disable-gtktest argument... " >&6; } + # Check whether --enable-gtktest was given. +if test ${enable_gtktest+y} +then : + enableval=$enable_gtktest; +else case e in #( + e) enable_gtktest=yes ;; +esac +fi + + if test "x$enable_gtktest" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5 +printf "%s\n" "gtk test enabled" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5 +printf "%s\n" "gtk test disabled" >&6; } + fi + + if test "x$PKG_CONFIG" != "xno"; then + + min_gtk_version="4.10.0" + + if test "$PKG_CONFIG" != "no"; then + case $min_gtk_version in #( + 2.*) : + gtk_pkg_name="gtk+-2.0" ;; #( + 3.*) : + gtk_pkg_name="gtk+-3.0" ;; #( + 4.*) : + gtk_pkg_name="gtk4" ;; #( + *) : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "The configure script does not know which pkg-config name to use for GTK $min_gtk_version\" +See 'config.log' for more details" "$LINENO" 5; } ;; +esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pkg-config $gtk_pkg_name" >&5 +printf %s "checking for pkg-config $gtk_pkg_name... " >&6; } + if "$PKG_CONFIG" --exists "$gtk_pkg_name" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 +printf "%s\n" "found" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 +printf %s "checking for GTK - version >= $min_gtk_version... " >&6; } + GTK_CPPFLAGS=`$PKG_CONFIG --cflags-only-I $gtk_pkg_name` + GTK_CFLAGS=`$PKG_CONFIG --cflags-only-other $gtk_pkg_name` + GTK_LIBDIR=`$PKG_CONFIG --libs-only-L $gtk_pkg_name` + GTK_LIBS=`$PKG_CONFIG --libs $gtk_pkg_name` + gtk_major_version=`$PKG_CONFIG --modversion $gtk_pkg_name | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` + gtk_minor_version=`$PKG_CONFIG --modversion $gtk_pkg_name | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` + gtk_micro_version=`$PKG_CONFIG --modversion $gtk_pkg_name | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes; found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&5 +printf "%s\n" "yes; found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&6; } + +else case e in #( + e) + GTK_CPPFLAGS="" + GTK_CFLAGS="" + GTK_LIBDIR="" + GTK_LIBS="" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no; consider installing your distro GTK -dev package" >&5 +printf "%s\n" "no; consider installing your distro GTK -dev package" >&6; } + if test "$fail_if_missing" = "yes" -a "$gui_auto" != "yes"; then + as_fn_error $? "pkg-config could not find $gtk_pkg_name" "$LINENO" 5 + fi + ;; +esac +fi + fi + + gtktest_success="yes" + if test "$enable_gtktest" = "yes"; then + { + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $GTK_CPPFLAGS" + CFLAGS="$CFLAGS $GTK_CFLAGS" + LIBS="$LIBS $GTK_LIBS" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ability to compile GTK test program" >&5 +printf %s "checking ability to compile GTK test program... " >&6; } + if test "$cross_compiling" = yes +then : + echo $ac_n "cross compiling; assumed OK... $ac_c" +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#if STDC_HEADERS +# include +# include +#endif + +int +main () +{ + int ex_major = $gtk_major_version; + int ex_minor = $gtk_minor_version; + int ex_micro = $gtk_micro_version; + + #if $gtk_major_version == 2 + guint ob_major = gtk_major_version; + guint ob_minor = gtk_minor_version; + guint ob_micro = gtk_micro_version; + #else + guint ob_major = gtk_get_major_version(); + guint ob_minor = gtk_get_minor_version(); + guint ob_micro = gtk_get_micro_version(); + #endif + + if ((ob_major > ex_major) || + ((ob_major == ex_major) + && (ob_minor > ex_minor)) || + ((ob_major == ex_major) + && (ob_minor == ex_minor) + && (ob_micro >= ex_micro))) + return 0; + else + return 1; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + gtktest_success="yes"; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else case e in #( + e) gtktest_success="no"; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + CPPFLAGS="$ac_save_CPPFLAGS" + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + } + fi + + if test "$gtktest_success" = "yes"; then + GUI_LIB_LOC="$GTK_LIBDIR" + GTK_LIBNAME="$GTK_LIBS" + GUI_INC_LOC="$GTK_CPPFLAGS" + else + GTK_CPPFLAGS="" + GTK_CFLAGS="" + GTK_LIBDIR="" + GTK_LIBS="" + if test "$fail_if_missing" = "yes" -a "$gui_auto" != "yes"; then + as_fn_error $? "Failed to compile GTK test program." "$LINENO" 5 + fi + fi + + + + + + if test -n "$GTK_CPPFLAGS"; then + SKIP_GTK3=YES + SKIP_GTK2=YES + SKIP_GNOME=YES + SKIP_MOTIF=YES + GUITYPE=GTK4 + + printf "%s\n" "#define USE_GTK4 1" >>confdefs.h + + X_LIBS= + X_PRE_LIBS= + X_EXTRA_LIBS= + X_LIB= + if test "$enable_xim" = "auto"; then + enable_xim="yes" + fi + fi + fi +fi + if test -z "$SKIP_GTK2"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5 printf %s "checking --disable-gtktest argument... " >&6; } @@ -11202,6 +11354,8 @@ printf "%s\n" "gtk test disabled" >&6; } gtk_pkg_name="gtk+-2.0" ;; #( 3.*) : gtk_pkg_name="gtk+-3.0" ;; #( + 4.*) : + gtk_pkg_name="gtk4" ;; #( *) : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} @@ -11218,7 +11372,7 @@ then : printf "%s\n" "found" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 printf %s "checking for GTK - version >= $min_gtk_version... " >&6; } - GTK_CPPFLAGS=`$PKG_CONFIG --cflags-only-I $gtk_pkg_name` + GTK_CPPFLAGS=`$PKG_CONFIG --cflags-only-I $gtk_pkg_name` GTK_CFLAGS=`$PKG_CONFIG --cflags-only-other $gtk_pkg_name` GTK_LIBDIR=`$PKG_CONFIG --libs-only-L $gtk_pkg_name` GTK_LIBS=`$PKG_CONFIG --libs $gtk_pkg_name` @@ -12041,7 +12195,7 @@ printf "%s\n" "$NARROW_PROTO" >&6; } fi -if test "$enable_xsmp" = "yes"; then +if test "$enable_xsmp" = "yes" -a "x$with_x" != "xno"; then cppflags_save=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_fn_c_check_header_compile "$LINENO" "X11/SM/SMlib.h" "ac_cv_header_X11_SM_SMlib_h" "$ac_includes_default" @@ -14822,18 +14976,18 @@ then : fi if test "$enable_largefile,$enable_year2038" != no,no then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CPPFLAGS option for large files" >&5 -printf %s "checking for $CPPFLAGS option for large files... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable large file support" >&5 +printf %s "checking for $CC option to enable large file support... " >&6; } if test ${ac_cv_sys_largefile_opts+y} then : printf %s "(cached) " >&6 else case e in #( - e) ac_save_CPPFLAGS=$CPPFLAGS + e) ac_save_CC="$CC" ac_opt_found=no - for ac_opt in "none needed" "-D_FILE_OFFSET_BITS=64" "-D_LARGE_FILES=1"; do + for ac_opt in "none needed" "-D_FILE_OFFSET_BITS=64" "-D_LARGE_FILES=1" "-n32"; do if test x"$ac_opt" != x"none needed" then : - CPPFLAGS="$ac_save_CPPFLAGS $ac_opt" + CC="$ac_save_CC $ac_opt" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -14862,12 +15016,12 @@ then : if test x"$ac_opt" = x"none needed" then : # GNU/Linux s390x and alpha need _FILE_OFFSET_BITS=64 for wide ino_t. - CPPFLAGS="$CPPFLAGS -DFTYPE=ino_t" + CC="$CC -DFTYPE=ino_t" if ac_fn_c_try_compile "$LINENO" then : else case e in #( - e) CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" + e) CC="$CC -D_FILE_OFFSET_BITS=64" if ac_fn_c_try_compile "$LINENO" then : ac_opt='-D_FILE_OFFSET_BITS=64' @@ -14883,7 +15037,7 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test $ac_opt_found = no || break done - CPPFLAGS=$ac_save_CPPFLAGS + CC="$ac_save_CC" test $ac_opt_found = yes || ac_cv_sys_largefile_opts="support not detected" ;; esac @@ -14907,14 +15061,16 @@ printf "%s\n" "#define _FILE_OFFSET_BITS 64" >>confdefs.h printf "%s\n" "#define _LARGE_FILES 1" >>confdefs.h ;; #( + "-n32") : + CC="$CC -n32" ;; #( *) : as_fn_error $? "internal error: bad value for \$ac_cv_sys_largefile_opts" "$LINENO" 5 ;; esac if test "$enable_year2038" != no then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CPPFLAGS option for timestamps after 2038" >&5 -printf %s "checking for $CPPFLAGS option for timestamps after 2038... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option for timestamps after 2038" >&5 +printf %s "checking for $CC option for timestamps after 2038... " >&6; } if test ${ac_cv_sys_year2038_opts+y} then : printf %s "(cached) " >&6 diff --git a/src/auto/wayland/Makefile b/src/auto/wayland/Makefile index e88b3b86e7..6d0534ec82 100644 --- a/src/auto/wayland/Makefile +++ b/src/auto/wayland/Makefile @@ -1,16 +1,10 @@ # List of files to generate GEN_XML = protocols/ext-data-control-v1.xml \ - protocols/primary-selection-unstable-v1.xml \ - protocols/wlr-data-control-unstable-v1.xml \ - protocols/xdg-shell.xml + protocols/wlr-data-control-unstable-v1.xml GEN_SRC = ext-data-control-v1.c \ - primary-selection-unstable-v1.c \ - wlr-data-control-unstable-v1.c \ - xdg-shell.c + wlr-data-control-unstable-v1.c GEN_INCLUDE = ext-data-control-v1.h \ - primary-selection-unstable-v1.h \ - wlr-data-control-unstable-v1.h \ - xdg-shell.h + wlr-data-control-unstable-v1.h # Default target all: $(GEN_SRC) $(GEN_INCLUDE) @@ -29,16 +23,6 @@ wlr-data-control-unstable-v1.c: wlr-data-control-unstable-v1.h: wayland-scanner client-header protocols/wlr-data-control-unstable-v1.xml $@ -primary-selection-unstable-v1.c: - wayland-scanner private-code protocols/primary-selection-unstable-v1.xml $@ -primary-selection-unstable-v1.h: - wayland-scanner client-header protocols/primary-selection-unstable-v1.xml $@ - -xdg-shell.c: - wayland-scanner private-code protocols/xdg-shell.xml $@ -xdg-shell.h: - wayland-scanner client-header protocols/xdg-shell.xml $@ - $(GEN_SRC) $(GEN_INCLUDE): $(GEN_XML) $(GEN_XML): diff --git a/src/auto/wayland/protocols/primary-selection-unstable-v1.xml b/src/auto/wayland/protocols/primary-selection-unstable-v1.xml deleted file mode 100644 index e5a39e34ce..0000000000 --- a/src/auto/wayland/protocols/primary-selection-unstable-v1.xml +++ /dev/null @@ -1,225 +0,0 @@ - - - - Copyright Š 2015, 2016 Red Hat - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice (including the next - paragraph) shall be included in all copies or substantial portions of the - Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - - - This protocol provides the ability to have a primary selection device to - match that of the X server. This primary selection is a shortcut to the - common clipboard selection, where text just needs to be selected in order - to allow copying it elsewhere. The de facto way to perform this action - is the middle mouse button, although it is not limited to this one. - - Clients wishing to honor primary selection should create a primary - selection source and set it as the selection through - wp_primary_selection_device.set_selection whenever the text selection - changes. In order to minimize calls in pointer-driven text selection, - it should happen only once after the operation finished. Similarly, - a NULL source should be set when text is unselected. - - wp_primary_selection_offer objects are first announced through the - wp_primary_selection_device.data_offer event. Immediately after this event, - the primary data offer will emit wp_primary_selection_offer.offer events - to let know of the mime types being offered. - - When the primary selection changes, the client with the keyboard focus - will receive wp_primary_selection_device.selection events. Only the client - with the keyboard focus will receive such events with a non-NULL - wp_primary_selection_offer. Across keyboard focus changes, previously - focused clients will receive wp_primary_selection_device.events with a - NULL wp_primary_selection_offer. - - In order to request the primary selection data, the client must pass - a recent serial pertaining to the press event that is triggering the - operation, if the compositor deems the serial valid and recent, the - wp_primary_selection_source.send event will happen in the other end - to let the transfer begin. The client owning the primary selection - should write the requested data, and close the file descriptor - immediately. - - If the primary selection owner client disappeared during the transfer, - the client reading the data will receive a - wp_primary_selection_device.selection event with a NULL - wp_primary_selection_offer, the client should take this as a hint - to finish the reads related to the no longer existing offer. - - The primary selection owner should be checking for errors during - writes, merely cancelling the ongoing transfer if any happened. - - - - - The primary selection device manager is a singleton global object that - provides access to the primary selection. It allows to create - wp_primary_selection_source objects, as well as retrieving the per-seat - wp_primary_selection_device objects. - - - - - Create a new primary selection source. - - - - - - - Create a new data device for a given seat. - - - - - - - - Destroy the primary selection device manager. - - - - - - - - Replaces the current selection. The previous owner of the primary - selection will receive a wp_primary_selection_source.cancelled event. - - To unset the selection, set the source to NULL. - - - - - - - - Introduces a new wp_primary_selection_offer object that may be used - to receive the current primary selection. Immediately following this - event, the new wp_primary_selection_offer object will send - wp_primary_selection_offer.offer events to describe the offered mime - types. - - - - - - - The wp_primary_selection_device.selection event is sent to notify the - client of a new primary selection. This event is sent after the - wp_primary_selection.data_offer event introducing this object, and after - the offer has announced its mimetypes through - wp_primary_selection_offer.offer. - - The data_offer is valid until a new offer or NULL is received - or until the client loses keyboard focus. The client must destroy the - previous selection data_offer, if any, upon receiving this event. - - - - - - - Destroy the primary selection device. - - - - - - - A wp_primary_selection_offer represents an offer to transfer the contents - of the primary selection clipboard to the client. Similar to - wl_data_offer, the offer also describes the mime types that the data can - be converted to and provides the mechanisms for transferring the data - directly to the client. - - - - - To transfer the contents of the primary selection clipboard, the client - issues this request and indicates the mime type that it wants to - receive. The transfer happens through the passed file descriptor - (typically created with the pipe system call). The source client writes - the data in the mime type representation requested and then closes the - file descriptor. - - The receiving client reads from the read end of the pipe until EOF and - closes its end, at which point the transfer is complete. - - - - - - - - Destroy the primary selection offer. - - - - - - Sent immediately after creating announcing the - wp_primary_selection_offer through - wp_primary_selection_device.data_offer. One event is sent per offered - mime type. - - - - - - - - The source side of a wp_primary_selection_offer, it provides a way to - describe the offered data and respond to requests to transfer the - requested contents of the primary selection clipboard. - - - - - This request adds a mime type to the set of mime types advertised to - targets. Can be called several times to offer multiple types. - - - - - - - Destroy the primary selection source. - - - - - - Request for the current primary selection contents from the client. - Send the specified mime type over the passed file descriptor, then - close it. - - - - - - - - This primary selection source is no longer valid. The client should - clean up and destroy this primary selection source. - - - - diff --git a/src/auto/wayland/protocols/xdg-shell.xml b/src/auto/wayland/protocols/xdg-shell.xml deleted file mode 100644 index c4d4685a3f..0000000000 --- a/src/auto/wayland/protocols/xdg-shell.xml +++ /dev/null @@ -1,1415 +0,0 @@ - - - - - Copyright Š 2008-2013 Kristian Høgsberg - Copyright Š 2013 Rafael Antognolli - Copyright Š 2013 Jasper St. Pierre - Copyright Š 2010-2013 Intel Corporation - Copyright Š 2015-2017 Samsung Electronics Co., Ltd - Copyright Š 2015-2017 Red Hat Inc. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice (including the next - paragraph) shall be included in all copies or substantial portions of the - Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - - - - The xdg_wm_base interface is exposed as a global object enabling clients - to turn their wl_surfaces into windows in a desktop environment. It - defines the basic functionality needed for clients and the compositor to - create windows that can be dragged, resized, maximized, etc, as well as - creating transient windows such as popup menus. - - - - - - - - - - - - - - - Destroy this xdg_wm_base object. - - Destroying a bound xdg_wm_base object while there are surfaces - still alive created by this xdg_wm_base object instance is illegal - and will result in a defunct_surfaces error. - - - - - - Create a positioner object. A positioner object is used to position - surfaces relative to some parent surface. See the interface description - and xdg_surface.get_popup for details. - - - - - - - This creates an xdg_surface for the given surface. While xdg_surface - itself is not a role, the corresponding surface may only be assigned - a role extending xdg_surface, such as xdg_toplevel or xdg_popup. It is - illegal to create an xdg_surface for a wl_surface which already has an - assigned role and this will result in a role error. - - This creates an xdg_surface for the given surface. An xdg_surface is - used as basis to define a role to a given surface, such as xdg_toplevel - or xdg_popup. It also manages functionality shared between xdg_surface - based surface roles. - - See the documentation of xdg_surface for more details about what an - xdg_surface is and how it is used. - - - - - - - - A client must respond to a ping event with a pong request or - the client may be deemed unresponsive. See xdg_wm_base.ping - and xdg_wm_base.error.unresponsive. - - - - - - - The ping event asks the client if it's still alive. Pass the - serial specified in the event back to the compositor by sending - a "pong" request back with the specified serial. See xdg_wm_base.pong. - - Compositors can use this to determine if the client is still - alive. It's unspecified what will happen if the client doesn't - respond to the ping request, or in what timeframe. Clients should - try to respond in a reasonable amount of time. The “unresponsive” - error is provided for compositors that wish to disconnect unresponsive - clients. - - A compositor is free to ping in any way it wants, but a client must - always respond to any xdg_wm_base object it created. - - - - - - - - The xdg_positioner provides a collection of rules for the placement of a - child surface relative to a parent surface. Rules can be defined to ensure - the child surface remains within the visible area's borders, and to - specify how the child surface changes its position, such as sliding along - an axis, or flipping around a rectangle. These positioner-created rules are - constrained by the requirement that a child surface must intersect with or - be at least partially adjacent to its parent surface. - - See the various requests for details about possible rules. - - At the time of the request, the compositor makes a copy of the rules - specified by the xdg_positioner. Thus, after the request is complete the - xdg_positioner object can be destroyed or reused; further changes to the - object will have no effect on previous usages. - - For an xdg_positioner object to be considered complete, it must have a - non-zero size set by set_size, and a non-zero anchor rectangle set by - set_anchor_rect. Passing an incomplete xdg_positioner object when - positioning a surface raises an invalid_positioner error. - - - - - - - - - Notify the compositor that the xdg_positioner will no longer be used. - - - - - - Set the size of the surface that is to be positioned with the positioner - object. The size is in surface-local coordinates and corresponds to the - window geometry. See xdg_surface.set_window_geometry. - - If a zero or negative size is set the invalid_input error is raised. - - - - - - - - Specify the anchor rectangle within the parent surface that the child - surface will be placed relative to. The rectangle is relative to the - window geometry as defined by xdg_surface.set_window_geometry of the - parent surface. - - When the xdg_positioner object is used to position a child surface, the - anchor rectangle may not extend outside the window geometry of the - positioned child's parent surface. - - If a negative size is set the invalid_input error is raised. - - - - - - - - - - - - - - - - - - - - - - Defines the anchor point for the anchor rectangle. The specified anchor - is used derive an anchor point that the child surface will be - positioned relative to. If a corner anchor is set (e.g. 'top_left' or - 'bottom_right'), the anchor point will be at the specified corner; - otherwise, the derived anchor point will be centered on the specified - edge, or in the center of the anchor rectangle if no edge is specified. - - - - - - - - - - - - - - - - - - - Defines in what direction a surface should be positioned, relative to - the anchor point of the parent surface. If a corner gravity is - specified (e.g. 'bottom_right' or 'top_left'), then the child surface - will be placed towards the specified gravity; otherwise, the child - surface will be centered over the anchor point on any axis that had no - gravity specified. If the gravity is not in the ‘gravity’ enum, an - invalid_input error is raised. - - - - - - - The constraint adjustment value define ways the compositor will adjust - the position of the surface, if the unadjusted position would result - in the surface being partly constrained. - - Whether a surface is considered 'constrained' is left to the compositor - to determine. For example, the surface may be partly outside the - compositor's defined 'work area', thus necessitating the child surface's - position be adjusted until it is entirely inside the work area. - - The adjustments can be combined, according to a defined precedence: 1) - Flip, 2) Slide, 3) Resize. - - - - Don't alter the surface position even if it is constrained on some - axis, for example partially outside the edge of an output. - - - - - Slide the surface along the x axis until it is no longer constrained. - - First try to slide towards the direction of the gravity on the x axis - until either the edge in the opposite direction of the gravity is - unconstrained or the edge in the direction of the gravity is - constrained. - - Then try to slide towards the opposite direction of the gravity on the - x axis until either the edge in the direction of the gravity is - unconstrained or the edge in the opposite direction of the gravity is - constrained. - - - - - Slide the surface along the y axis until it is no longer constrained. - - First try to slide towards the direction of the gravity on the y axis - until either the edge in the opposite direction of the gravity is - unconstrained or the edge in the direction of the gravity is - constrained. - - Then try to slide towards the opposite direction of the gravity on the - y axis until either the edge in the direction of the gravity is - unconstrained or the edge in the opposite direction of the gravity is - constrained. - - - - - Invert the anchor and gravity on the x axis if the surface is - constrained on the x axis. For example, if the left edge of the - surface is constrained, the gravity is 'left' and the anchor is - 'left', change the gravity to 'right' and the anchor to 'right'. - - If the adjusted position also ends up being constrained, the resulting - position of the flip_x adjustment will be the one before the - adjustment. - - - - - Invert the anchor and gravity on the y axis if the surface is - constrained on the y axis. For example, if the bottom edge of the - surface is constrained, the gravity is 'bottom' and the anchor is - 'bottom', change the gravity to 'top' and the anchor to 'top'. - - The adjusted position is calculated given the original anchor - rectangle and offset, but with the new flipped anchor and gravity - values. - - If the adjusted position also ends up being constrained, the resulting - position of the flip_y adjustment will be the one before the - adjustment. - - - - - Resize the surface horizontally so that it is completely - unconstrained. - - - - - Resize the surface vertically so that it is completely unconstrained. - - - - - - - Specify how the window should be positioned if the originally intended - position caused the surface to be constrained, meaning at least - partially outside positioning boundaries set by the compositor. The - adjustment is set by constructing a bitmask describing the adjustment to - be made when the surface is constrained on that axis. - - If no bit for one axis is set, the compositor will assume that the child - surface should not change its position on that axis when constrained. - - If more than one bit for one axis is set, the order of how adjustments - are applied is specified in the corresponding adjustment descriptions. - - The default adjustment is none. - - - - - - - Specify the surface position offset relative to the position of the - anchor on the anchor rectangle and the anchor on the surface. For - example if the anchor of the anchor rectangle is at (x, y), the surface - has the gravity bottom|right, and the offset is (ox, oy), the calculated - surface position will be (x + ox, y + oy). The offset position of the - surface is the one used for constraint testing. See - set_constraint_adjustment. - - An example use case is placing a popup menu on top of a user interface - element, while aligning the user interface element of the parent surface - with some user interface element placed somewhere in the popup surface. - - - - - - - - - - When set reactive, the surface is reconstrained if the conditions used - for constraining changed, e.g. the parent window moved. - - If the conditions changed and the popup was reconstrained, an - xdg_popup.configure event is sent with updated geometry, followed by an - xdg_surface.configure event. - - - - - - Set the parent window geometry the compositor should use when - positioning the popup. The compositor may use this information to - determine the future state the popup should be constrained using. If - this doesn't match the dimension of the parent the popup is eventually - positioned against, the behavior is undefined. - - The arguments are given in the surface-local coordinate space. - - - - - - - - Set the serial of an xdg_surface.configure event this positioner will be - used in response to. The compositor may use this information together - with set_parent_size to determine what future state the popup should be - constrained using. - - - - - - - - An interface that may be implemented by a wl_surface, for - implementations that provide a desktop-style user interface. - - It provides a base set of functionality required to construct user - interface elements requiring management by the compositor, such as - toplevel windows, menus, etc. The types of functionality are split into - xdg_surface roles. - - Creating an xdg_surface does not set the role for a wl_surface. In order - to map an xdg_surface, the client must create a role-specific object - using, e.g., get_toplevel, get_popup. The wl_surface for any given - xdg_surface can have at most one role, and may not be assigned any role - not based on xdg_surface. - - A role must be assigned before any other requests are made to the - xdg_surface object. - - The client must call wl_surface.commit on the corresponding wl_surface - for the xdg_surface state to take effect. - - Creating an xdg_surface from a wl_surface which has a buffer attached or - committed is a client error, and any attempts by a client to attach or - manipulate a buffer prior to the first xdg_surface.configure call must - also be treated as errors. - - After creating a role-specific object and setting it up (e.g. by sending - the title, app ID, size constraints, parent, etc), the client must - perform an initial commit without any buffer attached. The compositor - will reply with initial wl_surface state such as - wl_surface.preferred_buffer_scale followed by an xdg_surface.configure - event. The client must acknowledge it and is then allowed to attach a - buffer to map the surface. - - Mapping an xdg_surface-based role surface is defined as making it - possible for the surface to be shown by the compositor. Note that - a mapped surface is not guaranteed to be visible once it is mapped. - - For an xdg_surface to be mapped by the compositor, the following - conditions must be met: - (1) the client has assigned an xdg_surface-based role to the surface - (2) the client has set and committed the xdg_surface state and the - role-dependent state to the surface - (3) the client has committed a buffer to the surface - - A newly-unmapped surface is considered to have met condition (1) out - of the 3 required conditions for mapping a surface if its role surface - has not been destroyed, i.e. the client must perform the initial commit - again before attaching a buffer. - - - - - - - - - - - - - - Destroy the xdg_surface object. An xdg_surface must only be destroyed - after its role object has been destroyed, otherwise - a defunct_role_object error is raised. - - - - - - This creates an xdg_toplevel object for the given xdg_surface and gives - the associated wl_surface the xdg_toplevel role. - - See the documentation of xdg_toplevel for more details about what an - xdg_toplevel is and how it is used. - - - - - - - This creates an xdg_popup object for the given xdg_surface and gives - the associated wl_surface the xdg_popup role. - - If null is passed as a parent, a parent surface must be specified using - some other protocol, before committing the initial state. - - See the documentation of xdg_popup for more details about what an - xdg_popup is and how it is used. - - - - - - - - - The window geometry of a surface is its "visible bounds" from the - user's perspective. Client-side decorations often have invisible - portions like drop-shadows which should be ignored for the - purposes of aligning, placing and constraining windows. - - The window geometry is double-buffered state, see wl_surface.commit. - - When maintaining a position, the compositor should treat the (x, y) - coordinate of the window geometry as the top left corner of the window. - A client changing the (x, y) window geometry coordinate should in - general not alter the position of the window. - - Once the window geometry of the surface is set, it is not possible to - unset it, and it will remain the same until set_window_geometry is - called again, even if a new subsurface or buffer is attached. - - If never set, the value is the full bounds of the surface, - including any subsurfaces. This updates dynamically on every - commit. This unset is meant for extremely simple clients. - - The arguments are given in the surface-local coordinate space of - the wl_surface associated with this xdg_surface, and may extend outside - of the wl_surface itself to mark parts of the subsurface tree as part of - the window geometry. - - When applied, the effective window geometry will be the set window - geometry clamped to the bounding rectangle of the combined - geometry of the surface of the xdg_surface and the associated - subsurfaces. - - The effective geometry will not be recalculated unless a new call to - set_window_geometry is done and the new pending surface state is - subsequently applied. - - The width and height of the effective window geometry must be - greater than zero. Setting an invalid size will raise an - invalid_size error. - - - - - - - - - - When a configure event is received, if a client commits the - surface in response to the configure event, then the client - must make an ack_configure request sometime before the commit - request, passing along the serial of the configure event. - - For instance, for toplevel surfaces the compositor might use this - information to move a surface to the top left only when the client has - drawn itself for the maximized or fullscreen state. - - If the client receives multiple configure events before it - can respond to one, it only has to ack the last configure event. - Acking a configure event that was never sent raises an invalid_serial - error. - - A client is not required to commit immediately after sending - an ack_configure request - it may even ack_configure several times - before its next surface commit. - - A client may send multiple ack_configure requests before committing, but - only the last request sent before a commit indicates which configure - event the client really is responding to. - - Sending an ack_configure request consumes the serial number sent with - the request, as well as serial numbers sent by all configure events - sent on this xdg_surface prior to the configure event referenced by - the committed serial. - - It is an error to issue multiple ack_configure requests referencing a - serial from the same configure event, or to issue an ack_configure - request referencing a serial from a configure event issued before the - event identified by the last ack_configure request for the same - xdg_surface. Doing so will raise an invalid_serial error. - - - - - - - The configure event marks the end of a configure sequence. A configure - sequence is a set of one or more events configuring the state of the - xdg_surface, including the final xdg_surface.configure event. - - Where applicable, xdg_surface surface roles will during a configure - sequence extend this event as a latched state sent as events before the - xdg_surface.configure event. Such events should be considered to make up - a set of atomically applied configuration states, where the - xdg_surface.configure commits the accumulated state. - - Clients should arrange their surface for the new states, and then send - an ack_configure request with the serial sent in this configure event at - some point before committing the new surface. - - If the client receives multiple configure events before it can respond - to one, it is free to discard all but the last event it received. - - - - - - - - - This interface defines an xdg_surface role which allows a surface to, - among other things, set window-like properties such as maximize, - fullscreen, and minimize, set application-specific metadata like title and - id, and well as trigger user interactive operations such as interactive - resize and move. - - A xdg_toplevel by default is responsible for providing the full intended - visual representation of the toplevel, which depending on the window - state, may mean things like a title bar, window controls and drop shadow. - - Unmapping an xdg_toplevel means that the surface cannot be shown - by the compositor until it is explicitly mapped again. - All active operations (e.g., move, resize) are canceled and all - attributes (e.g. title, state, stacking, ...) are discarded for - an xdg_toplevel surface when it is unmapped. The xdg_toplevel returns to - the state it had right after xdg_surface.get_toplevel. The client - can re-map the toplevel by performing a commit without any buffer - attached, waiting for a configure event and handling it as usual (see - xdg_surface description). - - Attaching a null buffer to a toplevel unmaps the surface. - - - - - This request destroys the role surface and unmaps the surface; - see "Unmapping" behavior in interface section for details. - - - - - - - - - - - - Set the "parent" of this surface. This surface should be stacked - above the parent surface and all other ancestor surfaces. - - Parent surfaces should be set on dialogs, toolboxes, or other - "auxiliary" surfaces, so that the parent is raised when the dialog - is raised. - - Setting a null parent for a child surface unsets its parent. Setting - a null parent for a surface which currently has no parent is a no-op. - - Only mapped surfaces can have child surfaces. Setting a parent which - is not mapped is equivalent to setting a null parent. If a surface - becomes unmapped, its children's parent is set to the parent of - the now-unmapped surface. If the now-unmapped surface has no parent, - its children's parent is unset. If the now-unmapped surface becomes - mapped again, its parent-child relationship is not restored. - - The parent toplevel must not be one of the child toplevel's - descendants, and the parent must be different from the child toplevel, - otherwise the invalid_parent protocol error is raised. - - - - - - - Set a short title for the surface. - - This string may be used to identify the surface in a task bar, - window list, or other user interface elements provided by the - compositor. - - The string must be encoded in UTF-8. - - - - - - - Set an application identifier for the surface. - - The app ID identifies the general class of applications to which - the surface belongs. The compositor can use this to group multiple - surfaces together, or to determine how to launch a new application. - - For D-Bus activatable applications, the app ID is used as the D-Bus - service name. - - The compositor shell will try to group application surfaces together - by their app ID. As a best practice, it is suggested to select app - ID's that match the basename of the application's .desktop file. - For example, "org.freedesktop.FooViewer" where the .desktop file is - "org.freedesktop.FooViewer.desktop". - - Like other properties, a set_app_id request can be sent after the - xdg_toplevel has been mapped to update the property. - - See the desktop-entry specification [0] for more details on - application identifiers and how they relate to well-known D-Bus - names and .desktop files. - - [0] https://standards.freedesktop.org/desktop-entry-spec/ - - - - - - - Clients implementing client-side decorations might want to show - a context menu when right-clicking on the decorations, giving the - user a menu that they can use to maximize or minimize the window. - - This request asks the compositor to pop up such a window menu at - the given position, relative to the local surface coordinates of - the parent surface. There are no guarantees as to what menu items - the window menu contains, or even if a window menu will be drawn - at all. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. - - - - - - - - - - Start an interactive, user-driven move of the surface. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. The passed - serial is used to determine the type of interactive move (touch, - pointer, etc). - - The server may ignore move requests depending on the state of - the surface (e.g. fullscreen or maximized), or if the passed serial - is no longer valid. - - If triggered, the surface will lose the focus of the device - (wl_pointer, wl_touch, etc) used for the move. It is up to the - compositor to visually indicate that the move is taking place, such as - updating a pointer cursor, during the move. There is no guarantee - that the device focus will return when the move is completed. - - - - - - - - These values are used to indicate which edge of a surface - is being dragged in a resize operation. - - - - - - - - - - - - - - - Start a user-driven, interactive resize of the surface. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. The passed - serial is used to determine the type of interactive resize (touch, - pointer, etc). - - The server may ignore resize requests depending on the state of - the surface (e.g. fullscreen or maximized). - - If triggered, the client will receive configure events with the - "resize" state enum value and the expected sizes. See the "resize" - enum value for more details about what is required. The client - must also acknowledge configure events using "ack_configure". After - the resize is completed, the client will receive another "configure" - event without the resize state. - - If triggered, the surface also will lose the focus of the device - (wl_pointer, wl_touch, etc) used for the resize. It is up to the - compositor to visually indicate that the resize is taking place, - such as updating a pointer cursor, during the resize. There is no - guarantee that the device focus will return when the resize is - completed. - - The edges parameter specifies how the surface should be resized, and - is one of the values of the resize_edge enum. Values not matching - a variant of the enum will cause the invalid_resize_edge protocol error. - The compositor may use this information to update the surface position - for example when dragging the top left corner. The compositor may also - use this information to adapt its behavior, e.g. choose an appropriate - cursor image. - - - - - - - - - The different state values used on the surface. This is designed for - state values like maximized, fullscreen. It is paired with the - configure event to ensure that both the client and the compositor - setting the state can be synchronized. - - States set in this way are double-buffered, see wl_surface.commit. - - - - The surface is maximized. The window geometry specified in the configure - event must be obeyed by the client, or the xdg_wm_base.invalid_surface_state - error is raised. - - The client should draw without shadow or other - decoration outside of the window geometry. - - - - - The surface is fullscreen. The window geometry specified in the - configure event is a maximum; the client cannot resize beyond it. For - a surface to cover the whole fullscreened area, the geometry - dimensions must be obeyed by the client. For more details, see - xdg_toplevel.set_fullscreen. - - - - - The surface is being resized. The window geometry specified in the - configure event is a maximum; the client cannot resize beyond it. - Clients that have aspect ratio or cell sizing configuration can use - a smaller size, however. - - - - - Client window decorations should be painted as if the window is - active. Do not assume this means that the window actually has - keyboard or pointer focus. - - - - - The window is currently in a tiled layout and the left edge is - considered to be adjacent to another part of the tiling grid. - - The client should draw without shadow or other decoration outside of - the window geometry on the left edge. - - - - - The window is currently in a tiled layout and the right edge is - considered to be adjacent to another part of the tiling grid. - - The client should draw without shadow or other decoration outside of - the window geometry on the right edge. - - - - - The window is currently in a tiled layout and the top edge is - considered to be adjacent to another part of the tiling grid. - - The client should draw without shadow or other decoration outside of - the window geometry on the top edge. - - - - - The window is currently in a tiled layout and the bottom edge is - considered to be adjacent to another part of the tiling grid. - - The client should draw without shadow or other decoration outside of - the window geometry on the bottom edge. - - - - - The surface is currently not ordinarily being repainted; for - example because its content is occluded by another window, or its - outputs are switched off due to screen locking. - - - - - The left edge of the window is currently constrained, meaning it - shouldn't attempt to resize from that edge. It can for example mean - it's tiled next to a monitor edge on the constrained side of the - window. - - - - - The right edge of the window is currently constrained, meaning it - shouldn't attempt to resize from that edge. It can for example mean - it's tiled next to a monitor edge on the constrained side of the - window. - - - - - The top edge of the window is currently constrained, meaning it - shouldn't attempt to resize from that edge. It can for example mean - it's tiled next to a monitor edge on the constrained side of the - window. - - - - - The bottom edge of the window is currently constrained, meaning it - shouldn't attempt to resize from that edge. It can for example mean - it's tiled next to a monitor edge on the constrained side of the - window. - - - - - - - Set a maximum size for the window. - - The client can specify a maximum size so that the compositor does - not try to configure the window beyond this size. - - The width and height arguments are in window geometry coordinates. - See xdg_surface.set_window_geometry. - - Values set in this way are double-buffered, see wl_surface.commit. - - The compositor can use this information to allow or disallow - different states like maximize or fullscreen and draw accurate - animations. - - Similarly, a tiling window manager may use this information to - place and resize client windows in a more effective way. - - The client should not rely on the compositor to obey the maximum - size. The compositor may decide to ignore the values set by the - client and request a larger size. - - If never set, or a value of zero in the request, means that the - client has no expected maximum size in the given dimension. - As a result, a client wishing to reset the maximum size - to an unspecified state can use zero for width and height in the - request. - - Requesting a maximum size to be smaller than the minimum size of - a surface is illegal and will result in an invalid_size error. - - The width and height must be greater than or equal to zero. Using - strictly negative values for width or height will result in a - invalid_size error. - - - - - - - - Set a minimum size for the window. - - The client can specify a minimum size so that the compositor does - not try to configure the window below this size. - - The width and height arguments are in window geometry coordinates. - See xdg_surface.set_window_geometry. - - Values set in this way are double-buffered, see wl_surface.commit. - - The compositor can use this information to allow or disallow - different states like maximize or fullscreen and draw accurate - animations. - - Similarly, a tiling window manager may use this information to - place and resize client windows in a more effective way. - - The client should not rely on the compositor to obey the minimum - size. The compositor may decide to ignore the values set by the - client and request a smaller size. - - If never set, or a value of zero in the request, means that the - client has no expected minimum size in the given dimension. - As a result, a client wishing to reset the minimum size - to an unspecified state can use zero for width and height in the - request. - - Requesting a minimum size to be larger than the maximum size of - a surface is illegal and will result in an invalid_size error. - - The width and height must be greater than or equal to zero. Using - strictly negative values for width and height will result in a - invalid_size error. - - - - - - - - Maximize the surface. - - After requesting that the surface should be maximized, the compositor - will respond by emitting a configure event. Whether this configure - actually sets the window maximized is subject to compositor policies. - The client must then update its content, drawing in the configured - state. The client must also acknowledge the configure when committing - the new content (see ack_configure). - - It is up to the compositor to decide how and where to maximize the - surface, for example which output and what region of the screen should - be used. - - If the surface was already maximized, the compositor will still emit - a configure event with the "maximized" state. - - If the surface is in a fullscreen state, this request has no direct - effect. It may alter the state the surface is returned to when - unmaximized unless overridden by the compositor. - - - - - - Unmaximize the surface. - - After requesting that the surface should be unmaximized, the compositor - will respond by emitting a configure event. Whether this actually - un-maximizes the window is subject to compositor policies. - If available and applicable, the compositor will include the window - geometry dimensions the window had prior to being maximized in the - configure event. The client must then update its content, drawing it in - the configured state. The client must also acknowledge the configure - when committing the new content (see ack_configure). - - It is up to the compositor to position the surface after it was - unmaximized; usually the position the surface had before maximizing, if - applicable. - - If the surface was already not maximized, the compositor will still - emit a configure event without the "maximized" state. - - If the surface is in a fullscreen state, this request has no direct - effect. It may alter the state the surface is returned to when - unmaximized unless overridden by the compositor. - - - - - - Make the surface fullscreen. - - After requesting that the surface should be fullscreened, the - compositor will respond by emitting a configure event. Whether the - client is actually put into a fullscreen state is subject to compositor - policies. The client must also acknowledge the configure when - committing the new content (see ack_configure). - - The output passed by the request indicates the client's preference as - to which display it should be set fullscreen on. If this value is NULL, - it's up to the compositor to choose which display will be used to map - this surface. - - If the surface doesn't cover the whole output, the compositor will - position the surface in the center of the output and compensate with - with border fill covering the rest of the output. The content of the - border fill is undefined, but should be assumed to be in some way that - attempts to blend into the surrounding area (e.g. solid black). - - If the fullscreened surface is not opaque, the compositor must make - sure that other screen content not part of the same surface tree (made - up of subsurfaces, popups or similarly coupled surfaces) are not - visible below the fullscreened surface. - - - - - - - Make the surface no longer fullscreen. - - After requesting that the surface should be unfullscreened, the - compositor will respond by emitting a configure event. - Whether this actually removes the fullscreen state of the client is - subject to compositor policies. - - Making a surface unfullscreen sets states for the surface based on the following: - * the state(s) it may have had before becoming fullscreen - * any state(s) decided by the compositor - * any state(s) requested by the client while the surface was fullscreen - - The compositor may include the previous window geometry dimensions in - the configure event, if applicable. - - The client must also acknowledge the configure when committing the new - content (see ack_configure). - - - - - - Request that the compositor minimize your surface. There is no - way to know if the surface is currently minimized, nor is there - any way to unset minimization on this surface. - - If you are looking to throttle redrawing when minimized, please - instead use the wl_surface.frame event for this, as this will - also work with live previews on windows in Alt-Tab, Expose or - similar compositor features. - - - - - - This configure event asks the client to resize its toplevel surface or - to change its state. The configured state should not be applied - immediately. See xdg_surface.configure for details. - - The width and height arguments specify a hint to the window - about how its surface should be resized in window geometry - coordinates. See set_window_geometry. - - If the width or height arguments are zero, it means the client - should decide its own window dimension. This may happen when the - compositor needs to configure the state of the surface but doesn't - have any information about any previous or expected dimension. - - The states listed in the event specify how the width/height - arguments should be interpreted, and possibly how it should be - drawn. - - Clients must send an ack_configure in response to this event. See - xdg_surface.configure and xdg_surface.ack_configure for details. - - - - - - - - - The close event is sent by the compositor when the user - wants the surface to be closed. This should be equivalent to - the user clicking the close button in client-side decorations, - if your application has any. - - This is only a request that the user intends to close the - window. The client may choose to ignore this request, or show - a dialog to ask the user to save their data, etc. - - - - - - - - The configure_bounds event may be sent prior to a xdg_toplevel.configure - event to communicate the bounds a window geometry size is recommended - to constrain to. - - The passed width and height are in surface coordinate space. If width - and height are 0, it means bounds is unknown and equivalent to as if no - configure_bounds event was ever sent for this surface. - - The bounds can for example correspond to the size of a monitor excluding - any panels or other shell components, so that a surface isn't created in - a way that it cannot fit. - - The bounds may change at any point, and in such a case, a new - xdg_toplevel.configure_bounds will be sent, followed by - xdg_toplevel.configure and xdg_surface.configure. - - - - - - - - - - - - - - - - - This event advertises the capabilities supported by the compositor. If - a capability isn't supported, clients should hide or disable the UI - elements that expose this functionality. For instance, if the - compositor doesn't advertise support for minimized toplevels, a button - triggering the set_minimized request should not be displayed. - - The compositor will ignore requests it doesn't support. For instance, - a compositor which doesn't advertise support for minimized will ignore - set_minimized requests. - - Compositors must send this event once before the first - xdg_surface.configure event. When the capabilities change, compositors - must send this event again and then send an xdg_surface.configure - event. - - The configured state should not be applied immediately. See - xdg_surface.configure for details. - - The capabilities are sent as an array of 32-bit unsigned integers in - native endianness. - - - - - - - - A popup surface is a short-lived, temporary surface. It can be used to - implement for example menus, popovers, tooltips and other similar user - interface concepts. - - A popup can be made to take an explicit grab. See xdg_popup.grab for - details. - - When the popup is dismissed, a popup_done event will be sent out, and at - the same time the surface will be unmapped. See the xdg_popup.popup_done - event for details. - - Explicitly destroying the xdg_popup object will also dismiss the popup and - unmap the surface. Clients that want to dismiss the popup when another - surface of their own is clicked should dismiss the popup using the destroy - request. - - A newly created xdg_popup will be stacked on top of all previously created - xdg_popup surfaces associated with the same xdg_toplevel. - - The parent of an xdg_popup must be mapped (see the xdg_surface - description) before the xdg_popup itself. - - The client must call wl_surface.commit on the corresponding wl_surface - for the xdg_popup state to take effect. - - - - - - - - - This destroys the popup. Explicitly destroying the xdg_popup - object will also dismiss the popup, and unmap the surface. - - If this xdg_popup is not the "topmost" popup, the - xdg_wm_base.not_the_topmost_popup protocol error will be sent. - - - - - - This request makes the created popup take an explicit grab. An explicit - grab will be dismissed when the user dismisses the popup, or when the - client destroys the xdg_popup. This can be done by the user clicking - outside the surface, using the keyboard, or even locking the screen - through closing the lid or a timeout. - - If the compositor denies the grab, the popup will be immediately - dismissed. - - This request must be used in response to some sort of user action like a - button press, key press, or touch down event. The serial number of the - event should be passed as 'serial'. - - The parent of a grabbing popup must either be an xdg_toplevel surface or - another xdg_popup with an explicit grab. If the parent is another - xdg_popup it means that the popups are nested, with this popup now being - the topmost popup. - - Nested popups must be destroyed in the reverse order they were created - in, e.g. the only popup you are allowed to destroy at all times is the - topmost one. - - When compositors choose to dismiss a popup, they may dismiss every - nested grabbing popup as well. When a compositor dismisses popups, it - will follow the same dismissing order as required from the client. - - If the topmost grabbing popup is destroyed, the grab will be returned to - the parent of the popup, if that parent previously had an explicit grab. - - If the parent is a grabbing popup which has already been dismissed, this - popup will be immediately dismissed. If the parent is a popup that did - not take an explicit grab, an error will be raised. - - During a popup grab, the client owning the grab will receive pointer - and touch events for all their surfaces as normal (similar to an - "owner-events" grab in X11 parlance), while the top most grabbing popup - will always have keyboard focus. - - - - - - - - This event asks the popup surface to configure itself given the - configuration. The configured state should not be applied immediately. - See xdg_surface.configure for details. - - The x and y arguments represent the position the popup was placed at - given the xdg_positioner rule, relative to the upper left corner of the - window geometry of the parent surface. - - For version 2 or older, the configure event for an xdg_popup is only - ever sent once for the initial configuration. Starting with version 3, - it may be sent again if the popup is setup with an xdg_positioner with - set_reactive requested, or in response to xdg_popup.reposition requests. - - - - - - - - - - The popup_done event is sent out when a popup is dismissed by the - compositor. The client should destroy the xdg_popup object at this - point. - - - - - - - - Reposition an already-mapped popup. The popup will be placed given the - details in the passed xdg_positioner object, and a - xdg_popup.repositioned followed by xdg_popup.configure and - xdg_surface.configure will be emitted in response. Any parameters set - by the previous positioner will be discarded. - - The passed token will be sent in the corresponding - xdg_popup.repositioned event. The new popup position will not take - effect until the corresponding configure event is acknowledged by the - client. See xdg_popup.repositioned for details. The token itself is - opaque, and has no other special meaning. - - If multiple reposition requests are sent, the compositor may skip all - but the last one. - - If the popup is repositioned in response to a configure event for its - parent, the client should send an xdg_positioner.set_parent_configure - and possibly an xdg_positioner.set_parent_size request to allow the - compositor to properly constrain the popup. - - If the popup is repositioned together with a parent that is being - resized, but not in response to a configure event, the client should - send an xdg_positioner.set_parent_size request. - - - - - - - - The repositioned event is sent as part of a popup configuration - sequence, together with xdg_popup.configure and lastly - xdg_surface.configure to notify the completion of a reposition request. - - The repositioned event is to notify about the completion of a - xdg_popup.reposition request. The token argument is the token passed - in the xdg_popup.reposition request. - - Immediately after this event is emitted, xdg_popup.configure and - xdg_surface.configure will be sent with the updated size and position, - as well as a new configure serial. - - The client should optionally update the content of the popup, but must - acknowledge the new popup configuration for the new position to take - effect. See xdg_surface.ack_configure for details. - - - - - - diff --git a/src/autocmd.c b/src/autocmd.c index dd47834ccd..8e196f6bce 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -196,6 +196,8 @@ static keyvalue_T event_tab[NUM_EVENTS] = { KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDI, "TextChangedI"), KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDP, "TextChangedP"), KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDT, "TextChangedT"), + KEYVALUE_ENTRY(-EVENT_TEXTPUTPOST, "TextPutPost"), + KEYVALUE_ENTRY(-EVENT_TEXTPUTPRE, "TextPutPre"), KEYVALUE_ENTRY(-EVENT_TEXTYANKPOST, "TextYankPost"), KEYVALUE_ENTRY(EVENT_USER, "User"), KEYVALUE_ENTRY(EVENT_VIMENTER, "VimEnter"), @@ -260,7 +262,7 @@ static int current_augroup = AUGROUP_DEFAULT; static int au_need_clean = FALSE; // need to delete marked patterns static event_T event_name2nr(char_u *start, char_u **end); -static char_u *event_nr2name(event_T event); +static string_T *event_nr2name(event_T event); static int au_get_grouparg(char_u **argp); static int do_autocmd_event(event_T event, char_u *pat, int once, int nested, char_u *cmd, int forceit, int group, int flags); static int apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap); @@ -304,6 +306,8 @@ show_autocmd(AutoPat *ap, event_T event) goto theend; if (event != last_event || ap->group != last_group) { + string_T *event_name; + if (ap->group != AUGROUP_DEFAULT) { if (AUGROUP_NAME(ap->group) == NULL) @@ -312,7 +316,8 @@ show_autocmd(AutoPat *ap, event_T event) msg_puts_attr((char *)AUGROUP_NAME(ap->group), HL_ATTR(HLF_T)); msg_puts(" "); } - msg_puts_attr((char *)event_nr2name(event), HL_ATTR(HLF_T)); + event_name = event_nr2name(event); + msg_puts_attr((char *)event_name->string, HL_ATTR(HLF_T)); last_event = event; last_group = ap->group; msg_putchar('\n'); @@ -484,9 +489,12 @@ aubuflocal_remove(buf_T *buf) au_remove_pat(ap); if (p_verbose >= 6) { + string_T *event_name; + verbose_enter(); + event_name = event_nr2name(event); smsg(_("auto-removing autocommand: %s "), - event_nr2name(event), buf->b_fnum); + event_name->string, buf->b_fnum); verbose_leave(); } } @@ -709,13 +717,14 @@ event_name2nr(char_u *start, char_u **end) /* * Return the name for event "event". */ - static char_u * + static string_T * event_nr2name(event_T event) { int i; -#define CACHE_SIZE 12 + enum {CACHE_SIZE = 12}; static int cache_tab[CACHE_SIZE]; static int cache_last_index = -1; + static string_T unknown = STR_LITERAL_INIT("Unknown"); if (cache_last_index < 0) { @@ -730,7 +739,7 @@ event_nr2name(event_T event) for (i = cache_last_index; cache_tab[i] >= 0; ) { if ((event_T)abs(event_tab[cache_tab[i]].key) == event) - return event_tab[cache_tab[i]].value.string; + return &event_tab[cache_tab[i]].value; if (i == 0) i = CACHE_SIZE - 1; @@ -754,12 +763,11 @@ event_nr2name(event_T event) else ++cache_last_index; cache_tab[cache_last_index] = i; - break; + return &event_tab[i].value; } } - return (i == NUM_EVENTS) ? (char_u *)"Unknown" : - event_tab[i].value.string; + return &unknown; } /* @@ -2024,6 +2032,25 @@ has_cmdundefined(void) } #if defined(FEAT_EVAL) + +/* + * Return TRUE when there is a TextPutPost autocommand defined. + */ + int +has_textputpost(void) +{ + return (first_autopat[(int)EVENT_TEXTPUTPOST] != NULL); +} + +/* + * Return TRUE when there is a TextPutPre autocommand defined. + */ + int +has_textputpre(void) +{ + return (first_autopat[(int)EVENT_TEXTPUTPRE] != NULL); +} + /* * Return TRUE when there is a TextYankPost autocommand defined. */ @@ -2367,7 +2394,7 @@ apply_autocmds_group( // Remember that FileType was triggered. Used for did_filetype(). if (event == EVENT_FILETYPE) - curbuf->b_did_filetype = TRUE; + curbuf->b_did_filetype = true; tail = gettail(fname); @@ -2476,7 +2503,7 @@ apply_autocmds_group( restore_search_patterns(); if (did_save_redobuff) restoreRedobuff(&save_redo); - curbuf->b_did_filetype = FALSE; + curbuf->b_did_filetype = false; while (au_pending_free_buf != NULL) { buf_T *b = au_pending_free_buf->b_next; @@ -2518,7 +2545,7 @@ BYPASS_AU: aubuflocal_remove(buf); if (retval == OK && event == EVENT_FILETYPE) - curbuf->b_au_did_filetype = TRUE; + curbuf->b_au_did_filetype = true; return retval; } @@ -2609,11 +2636,7 @@ auto_next_pat( int stop_at_last) // stop when 'last' flag is set { AutoPat *ap; - AutoCmd *cp; - char_u *name; - char *s; estack_T *entry; - char_u *namep; entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1; @@ -2637,12 +2660,17 @@ auto_next_pat( apc->sfname, apc->tail, ap->allow_dirs)) : ap->buflocal_nr == apc->arg_bufnr) { - name = event_nr2name(apc->event); - s = _("%s Autocommands for \"%s\""); - namep = alloc(STRLEN(s) + STRLEN(name) + ap->patlen + 1); + string_T *event_name; + char *fmt; + char_u *namep; + AutoCmd *cp; + + event_name = event_nr2name(apc->event); + fmt = _("%s Autocommands for \"%s\""); + namep = alloc(STRLEN(fmt) + event_name->length + ap->patlen + 1); if (namep != NULL) { - sprintf((char *)namep, s, (char *)name, (char *)ap->pat); + sprintf((char *)namep, fmt, (char *)event_name->string, (char *)ap->pat); if (p_verbose >= 8) { verbose_enter(); @@ -3344,7 +3372,6 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv) AutoCmd *ac; list_T *event_list; dict_T *event_dict; - char_u *event_name = NULL; char_u *pat = NULL; char_u *name = NULL; int group = AUGROUP_ALL; @@ -3423,6 +3450,8 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv) for (event = (event_T)0; (int)event < NUM_EVENTS; event = (event_T)((int)event + 1)) { + string_T *event_name; + if (event_arg != NUM_EVENTS && event != event_arg) continue; @@ -3431,7 +3460,7 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv) // iterate through all the patterns for this autocmd event FOR_ALL_AUTOCMD_PATTERNS(event, ap) { - char_u *group_name; + string_T group_name; if (ap->pat == NULL) // pattern has been removed continue; @@ -3442,7 +3471,11 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv) if (pat != NULL && STRCMP(pat, ap->pat) != 0) continue; - group_name = get_augroup_name(NULL, ap->group); + group_name.string = get_augroup_name(NULL, ap->group); + if (group_name.string == NULL) + STR_LITERAL_SET(group_name, ""); + else + group_name.length = STRLEN(group_name.string); // iterate through all the commands for this pattern and add one // item for each cmd. @@ -3456,10 +3489,10 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv) return; } - if (dict_add_string(event_dict, "event", event_name) == FAIL - || dict_add_string(event_dict, "group", - group_name == NULL ? (char_u *)"" - : group_name) == FAIL + if (dict_add_string_len(event_dict, "event", + event_name->string, (int)event_name->length) == FAIL + || dict_add_string_len(event_dict, "group", + group_name.string, (int)group_name.length) == FAIL || (ap->buflocal_nr != 0 && (dict_add_number(event_dict, "bufnr", ap->buflocal_nr) == FAIL)) diff --git a/src/beval.h b/src/beval.h index 83d9c8ecdb..aa8b283b5f 100644 --- a/src/beval.h +++ b/src/beval.h @@ -11,7 +11,7 @@ #define BEVAL__H #ifdef FEAT_GUI_GTK -# ifdef USE_GTK3 +# if defined(USE_GTK3) || defined(USE_GTK4) # include # else # include diff --git a/src/blob.c b/src/blob.c index bbdf2873d0..ad2b02bbbc 100644 --- a/src/blob.c +++ b/src/blob.c @@ -263,33 +263,47 @@ write_blob(FILE *fd, blob_T *blob) * Convert a blob to a readable form: "0z00112233.44556677.8899" */ char_u * -blob2string(blob_T *blob, char_u **tofree, char_u *numbuf) +blob2string(blob_T *blob, char_u **tofree, char_u *numbuf UNUSED) { - int i; - garray_T ga; + static const char hex_chars[] = "0123456789ABCDEF"; + int blen; + size_t total; + char_u *buf; + char_u *p; + char_u *src; - if (blob == NULL) + if (blob == NULL || (blen = blob_len(blob)) == 0) { *tofree = NULL; return (char_u *)"0z"; } - // Store bytes in the growarray. - ga_init2(&ga, 1, 4000); - GA_CONCAT_LITERAL(&ga, "0z"); - for (i = 0; i < blob_len(blob); i++) + // 2 ("0z") + 2 hex per byte + one '.' every 4 bytes + NUL terminator. + total = 2 + (size_t)blen * 2 + (size_t)((blen - 1) / 4) + 1; + buf = alloc(total); + if (buf == NULL) { - size_t numbuflen; + *tofree = NULL; + return (char_u *)"0z"; + } + + p = buf; + *p++ = '0'; + *p++ = 'z'; + src = (char_u *)blob->bv_ga.ga_data; + for (int i = 0; i < blen; i++) + { + unsigned b; if (i > 0 && (i & 3) == 0) - GA_CONCAT_LITERAL(&ga, "."); - numbuflen = vim_snprintf_safelen((char *)numbuf, NUMBUFLEN, - "%02X", blob_get(blob, i)); - ga_concat_len(&ga, numbuf, numbuflen); + *p++ = '.'; + b = src[i]; + *p++ = hex_chars[b >> 4]; + *p++ = hex_chars[b & 0xf]; } - ga_append(&ga, NUL); // append a NUL at the end - *tofree = ga.ga_data; - return *tofree; + *p = NUL; + *tofree = buf; + return buf; } /* diff --git a/src/buffer.c b/src/buffer.c index 9c2c63eec6..14d2cf1ff9 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -49,7 +49,8 @@ static int value_changed(char_u *str, char_u **last); static int build_stl_str_hl_local(stl_mode_T mode, win_T *wp, char_u *out, size_t outlen, char_u **fmt_arg, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, - stl_hlrec_T **hltab, stl_hlrec_T **tabtab, int *lbreaks); + stl_hlrec_T **hltab, stl_hlrec_T **tabtab, + stl_clickrec_T **clicktab, int *lbreaks, int *carry_hl); #endif static int append_arg_number(win_T *wp, char_u *buf, size_t buflen, int add_file); static void free_buffer(buf_T *); @@ -258,7 +259,7 @@ open_buffer( // The autocommands in readfile() may change the buffer, but only AFTER // reading the file. set_bufref(&old_curbuf, curbuf); - curbuf->b_modified_was_set = FALSE; + curbuf->b_modified_was_set = false; // mark cursor position as being invalid curwin->w_valid = 0; @@ -277,7 +278,7 @@ open_buffer( { int old_msg_silent = msg_silent; #ifdef UNIX - int save_bin = curbuf->b_p_bin; + int save_bin = curbuf->b_p_bin; int perm; #endif #ifdef FEAT_NETBEANS_INTG @@ -735,6 +736,11 @@ aucmd_abort: unblock_autocmds(); } + // When a quickfix buffer is deleted from a window, clear the + // 'winfixheight' option. + if (bt_quickfix(buf) && win_valid && win->w_buffer == buf) + win->w_p_wfh = FALSE; + // Remember if the buffer may be hidden soon, or is already hidden. hiding_buf = buf->b_nwindows <= 0 || ((win_valid || closed_popup) && win->w_buffer == buf && buf->b_nwindows == 1); @@ -827,7 +833,7 @@ aucmd_abort: buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED; // Init the options when loaded again. - buf->b_p_initialized = FALSE; + buf->b_p_initialized = false; } buf_clear_file(buf); if (del_buf) @@ -850,7 +856,7 @@ buf_clear_file(buf_T *buf) { buf->b_ml.ml_line_count = 1; unchanged(buf, TRUE, TRUE); - buf->b_shortname = FALSE; + buf->b_shortname = false; buf->b_p_eof = FALSE; buf->b_start_eof = FALSE; buf->b_p_eol = TRUE; @@ -2004,8 +2010,8 @@ enter_buffer(buf_T *buf) curwin->w_cursor.lnum = 1; curwin->w_cursor.col = 0; curwin->w_cursor.coladd = 0; - curwin->w_set_curswant = TRUE; - curwin->w_topline_was_set = FALSE; + curwin->w_set_curswant = true; + curwin->w_topline_was_set = false; // mark cursor position as being invalid curwin->w_valid = 0; @@ -2017,7 +2023,7 @@ enter_buffer(buf_T *buf) // ":ball" used in an autocommand. If there already is a filetype we // might prefer to keep it. if (*curbuf->b_p_ft == NUL) - curbuf->b_did_filetype = FALSE; + curbuf->b_did_filetype = false; open_buffer(FALSE, NULL, 0); } @@ -2297,7 +2303,7 @@ buflist_new( free_buffer_stuff(buf, FALSE); // delete local variables et al. // Init the options. - buf->b_p_initialized = FALSE; + buf->b_p_initialized = false; buf_copy_options(buf, BCO_ENTER); #ifdef FEAT_KEYMAP @@ -2377,15 +2383,15 @@ buflist_new( buf->b_fname = buf->b_sfname; #ifdef UNIX if (st.st_dev == (dev_T)-1) - buf->b_dev_valid = FALSE; + buf->b_dev_valid = false; else { - buf->b_dev_valid = TRUE; + buf->b_dev_valid = true; buf->b_dev = st.st_dev; buf->b_ino = st.st_ino; } #endif - buf->b_u_synced = TRUE; + buf->b_u_synced = true; buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED; if (flags & BLN_DUMMY) buf->b_flags |= BF_DUMMY; @@ -2628,7 +2634,7 @@ buflist_getfile( curwin->w_cursor.col = col; check_cursor_col(); curwin->w_cursor.coladd = 0; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } retval = OK; } @@ -2658,7 +2664,7 @@ buflist_getfpos(void) curwin->w_cursor.col = fpos->col; check_cursor_col(); curwin->w_cursor.coladd = 0; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } } @@ -3347,7 +3353,7 @@ get_winopts(buf_T *buf) #endif #ifdef FEAT_FOLDING curwin->w_fold_manual = wp->w_fold_manual; - curwin->w_foldinvalid = TRUE; + curwin->w_foldinvalid = true; cloneFoldGrowArray(&wp->w_folds, &curwin->w_folds); #endif } @@ -3357,7 +3363,7 @@ get_winopts(buf_T *buf) copy_winopt(&wip->wi_opt, &curwin->w_onebuf_opt); #ifdef FEAT_FOLDING curwin->w_fold_manual = wip->wi_fold_manual; - curwin->w_foldinvalid = TRUE; + curwin->w_foldinvalid = true; cloneFoldGrowArray(&wip->wi_folds, &curwin->w_folds); #endif } @@ -3674,16 +3680,16 @@ setfname( buf->b_fname = buf->b_sfname; #ifdef UNIX if (st.st_dev == (dev_T)-1) - buf->b_dev_valid = FALSE; + buf->b_dev_valid = false; else { - buf->b_dev_valid = TRUE; + buf->b_dev_valid = true; buf->b_dev = st.st_dev; buf->b_ino = st.st_ino; } #endif - buf->b_shortname = FALSE; + buf->b_shortname = false; buf_name_changed(buf); return OK; @@ -3897,12 +3903,12 @@ buf_setino(buf_T *buf) if (buf->b_fname != NULL && mch_stat((char *)buf->b_fname, &st) >= 0) { - buf->b_dev_valid = TRUE; + buf->b_dev_valid = true; buf->b_dev = st.st_dev; buf->b_ino = st.st_ino; } else - buf->b_dev_valid = FALSE; + buf->b_dev_valid = false; } /* @@ -3951,9 +3957,8 @@ fileinfo( name = curbuf->b_fname; else name = curbuf->b_ffname; - home_replace(shorthelp ? curbuf : NULL, name, (char_u *)buffer + bufferlen, - IOSIZE - (int)bufferlen, TRUE); - bufferlen += STRLEN(buffer + bufferlen); + bufferlen += home_replace(shorthelp ? curbuf : NULL, name, + (char_u *)buffer + bufferlen, IOSIZE - (int)bufferlen, TRUE); } bufferlen += vim_snprintf_safelen( @@ -4088,7 +4093,7 @@ maketitle(void) if (stl_syntax & STL_IN_TITLE) build_stl_str_hl(curwin, title_str, sizeof(buf), p_titlestring, (char_u *)"titlestring", 0, - 0, maxlen, NULL, NULL); + 0, maxlen, NULL, NULL, NULL); else #endif title_str = p_titlestring; @@ -4261,7 +4266,8 @@ maketitle(void) #ifdef FEAT_STL_OPT if (stl_syntax & STL_IN_ICON) build_stl_str_hl(curwin, icon_str, sizeof(buf), p_iconstring, - (char_u *)"iconstring", 0, 0, 0, NULL, NULL); + (char_u *)"iconstring", 0, 0, 0, NULL, NULL, + NULL); else #endif icon_str = p_iconstring; @@ -4357,8 +4363,10 @@ typedef struct Separate, Highlight, TabPage, + ClickFunc, Trunc } stl_type; + char_u *stl_clickfunc; // function name for ClickFunc items } stl_item_T; static size_t stl_items_len = 20; // Initial value, grows as needed. @@ -4366,6 +4374,7 @@ static stl_item_T *stl_items = NULL; static int *stl_groupitem = NULL; static stl_hlrec_T *stl_hltab = NULL; static stl_hlrec_T *stl_tabtab = NULL; +static stl_clickrec_T *stl_clicktab = NULL; static int *stl_separator_locations = NULL; /* @@ -4393,10 +4402,12 @@ build_stl_str_hl( int fillchar, int maxwidth, stl_hlrec_T **hltab, // return: HL attributes (can be NULL) - stl_hlrec_T **tabtab) // return: tab page nrs (can be NULL) + stl_hlrec_T **tabtab, // return: tab page nrs (can be NULL) + stl_clickrec_T **clicktab) // return: click func regions (can be NULL) { return build_stl_str_hl_local(STL_MODE_SINGLE, wp, out, outlen, &fmt, - opt_name, opt_scope, fillchar, maxwidth, hltab, tabtab, NULL); + opt_name, opt_scope, fillchar, maxwidth, hltab, tabtab, clicktab, + NULL, NULL); } int @@ -4410,10 +4421,14 @@ build_stl_str_hl_mline( int fillchar, int maxwidth, stl_hlrec_T **hltab, // return: HL attributes (can be NULL) - stl_hlrec_T **tabtab) // return: tab page nrs (can be NULL) + stl_hlrec_T **tabtab, // return: tab page nrs (can be NULL) + stl_clickrec_T **clicktab, // return: click func regions (can be NULL) + int *carry_hl) // (in/out) %# / %* highlight carried across + // line breaks (can be NULL) { return build_stl_str_hl_local(STL_MODE_MULTI, wp, out, outlen, fmt, - opt_name, opt_scope, fillchar, maxwidth, hltab, tabtab, NULL); + opt_name, opt_scope, fillchar, maxwidth, hltab, tabtab, clicktab, + NULL, carry_hl); } # ifdef ENABLE_STL_MODE_MULTI_NL @@ -4428,10 +4443,14 @@ build_stl_str_hl_mline_nl( int fillchar, int maxwidth, stl_hlrec_T **hltab, // return: HL attributes (can be NULL) - stl_hlrec_T **tabtab) // return: tab page nrs (can be NULL) + stl_hlrec_T **tabtab, // return: tab page nrs (can be NULL) + stl_clickrec_T **clicktab, // return: click func regions (can be NULL) + int *carry_hl) // (in/out) %# / %* highlight carried across + // line breaks (can be NULL) { return build_stl_str_hl_local(STL_MODE_MULTI_NL, wp, out, outlen, fmt, - opt_name, opt_scope, fillchar, maxwidth, hltab, tabtab, NULL); + opt_name, opt_scope, fillchar, maxwidth, hltab, tabtab, clicktab, + NULL, carry_hl); } # endif @@ -4452,7 +4471,8 @@ get_stl_rendered_height( ++emsg_off; (void)build_stl_str_hl_local(STL_MODE_GET_RENDERED_HEIGHT, wp, buf, sizeof(buf), &fmt, - opt_name, opt_scope, 0, 0, NULL, NULL, &rendered_height); + opt_name, opt_scope, 0, 0, NULL, NULL, NULL, &rendered_height, + NULL); --emsg_off; return rendered_height; } @@ -4487,7 +4507,10 @@ build_stl_str_hl_local( int maxwidth, stl_hlrec_T **hltab, // return: HL attributes (can be NULL) stl_hlrec_T **tabtab, // return: tab page nrs (can be NULL) - int *rendered_height) // return: stl rendered height (can be NULL) + stl_clickrec_T **clicktab, // return: click func regions (can be NULL) + int *rendered_height, // return: stl rendered height (can be NULL) + int *carry_hl) // (in/out) %# / %* highlight carried across + // line breaks (can be NULL) { linenr_T lnum; colnr_T len; @@ -4548,6 +4571,7 @@ build_stl_str_hl_local( // end of the list. stl_hltab = ALLOC_MULT(stl_hlrec_T, stl_items_len + 1); stl_tabtab = ALLOC_MULT(stl_hlrec_T, stl_items_len + 1); + stl_clicktab = ALLOC_MULT(stl_clickrec_T, stl_items_len + 1); stl_separator_locations = ALLOC_MULT(int, stl_items_len); } @@ -4611,6 +4635,18 @@ build_stl_str_hl_local( # endif p = out; curitem = 0; + + // Pre-insert a Highlight item from carry_hl so that %# / %* set on a + // previous multi-line statusline row continues to apply on this row. + if (carry_hl != NULL && *carry_hl != 0) + { + stl_items[curitem].stl_type = Highlight; + stl_items[curitem].stl_start = p; + stl_items[curitem].stl_minwid = *carry_hl; + stl_items[curitem].stl_clickfunc = NULL; + curitem++; + } + prevchar_isflag = TRUE; prevchar_isitem = FALSE; for (s = usefmt; *s != NUL; ) @@ -4642,6 +4678,12 @@ build_stl_str_hl_local( break; stl_tabtab = new_hlrec; + stl_clickrec_T *new_clickrec = vim_realloc(stl_clicktab, + sizeof(stl_clickrec_T) * (new_len + 1)); + if (new_clickrec == NULL) + break; + stl_clicktab = new_clickrec; + int *new_separator_locs = vim_realloc(stl_separator_locations, sizeof(int) * new_len); if (new_separator_locs == NULL) @@ -4651,6 +4693,8 @@ build_stl_str_hl_local( stl_items_len = new_len; } + stl_items[curitem].stl_clickfunc = NULL; + if (*s != '%') prevchar_isflag = prevchar_isitem = FALSE; @@ -4685,8 +4729,39 @@ build_stl_str_hl_local( if (*s == NUL) // ignore trailing % break; + if (*s == STL_CLICKFUNC) + { + // %[] - end click region + if (s[1] == ']') + { + stl_items[curitem].stl_type = ClickFunc; + stl_items[curitem].stl_start = p; + stl_items[curitem].stl_minwid = 0; + stl_items[curitem].stl_clickfunc = NULL; + s += 2; + curitem++; + continue; + } + // %[FuncName] - start click region + if (ASCII_ISALPHA(s[1]) || s[1] == '_') + { + char_u *rb = vim_strchr(s + 1, ']'); + if (rb != NULL) + { + stl_items[curitem].stl_type = ClickFunc; + stl_items[curitem].stl_start = p; + stl_items[curitem].stl_minwid = 0; + stl_items[curitem].stl_clickfunc = + vim_strnsave(s + 1, rb - s - 1); + s = rb + 1; + curitem++; + continue; + } + } + } if (*s == STL_LINEBREAK) { + // Plain %@ - line break if (mode == STL_MODE_MULTI # ifdef ENABLE_STL_MODE_MULTI_NL || mode == STL_MODE_MULTI_NL @@ -4904,6 +4979,9 @@ build_stl_str_hl_local( maxwid = 50; } } + // Keep the uncapped value for %N[FuncName] click-region IDs; the 50 + // cap below applies only when minwid is used as a padding width. + int raw_minwid = minwid * l; minwid = (minwid > 50 ? 50 : minwid) * l; if (*s == '(') { @@ -4978,7 +5056,8 @@ build_stl_str_hl_local( if (reevaluate) s++; - itemisflag = TRUE; + // %0{} keeps the result verbatim + itemisflag = zeropad ? FALSE : TRUE; t = p; while ((*s != '}' || (reevaluate && s[-1] != '%')) && *s != NUL && p + 1 < out + outlen) @@ -4986,7 +5065,7 @@ build_stl_str_hl_local( if (*s != '}') // missing '}' or out of space break; s++; - if (reevaluate) + if (reevaluate && p > out) p[-1] = NUL; // remove the % at the end of %{% expr %} else *p = NUL; @@ -5015,7 +5094,7 @@ build_stl_str_hl_local( do_unlet((char_u *)"g:actual_curbuf", TRUE); do_unlet((char_u *)"g:actual_curwin", TRUE); - if (str != NULL && *str != NUL) + if (!zeropad && str != NULL && *str != NUL) { if (*skipdigits(str) == NUL) { @@ -5243,6 +5322,44 @@ build_stl_str_hl_local( ++s; continue; } + + case STL_CLICKFUNC: + // %N[] - end click region (with minwid, minwid is ignored) + if (*s == ']') + { + stl_items[curitem].stl_type = ClickFunc; + stl_items[curitem].stl_start = p; + stl_items[curitem].stl_minwid = 0; + stl_items[curitem].stl_clickfunc = NULL; + s++; + curitem++; + continue; + } + // %N[FuncName] with minwid + if (ASCII_ISALPHA(*s) || *s == '_') + { + char_u *rb = vim_strchr(s, ']'); + if (rb != NULL) + { + stl_items[curitem].stl_type = ClickFunc; + stl_items[curitem].stl_start = p; + // The stl_minwid field is overloaded: it may be the + // "min" part of %. used for padding, or an + // identifier passed to the %N[FuncName] callback. Store + // the uncapped value so IDs above 50 are preserved. + stl_items[curitem].stl_minwid = raw_minwid; + stl_items[curitem].stl_clickfunc = + vim_strnsave(s, rb - s); + s = rb + 1; + curitem++; + continue; + } + } + continue; + + case STL_LINEBREAK: + // %N@ - line break (already handled above, fallback) + continue; } stl_items[curitem].stl_start = p; @@ -5363,6 +5480,17 @@ find_linebreak: outputlen = (size_t)(p - out); itemcnt = curitem; + // Remember the most recent %# / %* highlight so the next row of a + // multi-line statusline can resume it. + if (carry_hl != NULL) + { + int last_hl = 0; + for (l = 0; l < itemcnt; l++) + if (stl_items[l].stl_type == Highlight) + last_hl = stl_items[l].stl_minwid; + *carry_hl = last_hl; + } + if (mode == STL_MODE_MULTI # ifdef ENABLE_STL_MODE_MULTI_NL || mode == STL_MODE_MULTI_NL @@ -5398,6 +5526,10 @@ find_linebreak: if (mode == STL_MODE_GET_RENDERED_HEIGHT) { + // Free click function names that were allocated during parsing. + for (l = 0; l < itemcnt; l++) + if (stl_items[l].stl_type == ClickFunc) + vim_free(stl_items[l].stl_clickfunc); if (rendered_height != NULL) *rendered_height = rheight; return 0; @@ -5571,6 +5703,34 @@ find_linebreak: sp->userhl = 0; } + // Store the info about click function regions. + if (clicktab != NULL) + { + stl_clickrec_T *cp; + + *clicktab = stl_clicktab; + cp = stl_clicktab; + for (l = 0; l < itemcnt; l++) + { + if (stl_items[l].stl_type == ClickFunc) + { + cp->start = stl_items[l].stl_start; + cp->funcname = stl_items[l].stl_clickfunc; + cp->minwid = stl_items[l].stl_minwid; + cp++; + } + } + cp->start = NULL; + cp->funcname = NULL; + } + else + { + // Free click function names when caller doesn't need them. + for (l = 0; l < itemcnt; l++) + if (stl_items[l].stl_type == ClickFunc) + vim_free(stl_items[l].stl_clickfunc); + } + redraw_not_allowed = save_redraw_not_allowed; // A user function may reset KeyTyped, restore it. diff --git a/src/bufwrite.c b/src/bufwrite.c index c90447aad6..2f445038a9 100644 --- a/src/bufwrite.c +++ b/src/bufwrite.c @@ -1160,7 +1160,7 @@ buf_write( got_int = FALSE; // Mark the buffer as 'being saved' to prevent changed buffer warnings - buf->b_saving = TRUE; + buf->b_saving = true; // If we are not appending or filtering, the file exists, and the // 'writebackup', 'backup' or 'patchmode' option is set, need a backup. @@ -1407,13 +1407,13 @@ buf_write( // may try again with 'shortname' set if (!(buf->b_shortname || buf->b_p_sn)) { - buf->b_shortname = TRUE; + buf->b_shortname = true; did_set_shortname = TRUE; continue; } // setting shortname didn't help if (did_set_shortname) - buf->b_shortname = FALSE; + buf->b_shortname = false; break; } #endif @@ -2543,7 +2543,7 @@ fail: nofail: // Done saving, we accept changed buffer warnings again - buf->b_saving = FALSE; + buf->b_saving = false; vim_free(backup); if (buffer != smallbuf) @@ -2661,7 +2661,7 @@ nofail: #ifdef FEAT_VIMINFO // Make sure marks will be written out to the viminfo file later, even when // the file is new. - curbuf->b_marks_read = TRUE; + curbuf->b_marks_read = true; #endif got_int |= prev_got_int; diff --git a/src/change.c b/src/change.c index 52e251ee84..a6084a87d5 100644 --- a/src/change.c +++ b/src/change.c @@ -61,7 +61,7 @@ change_warning(int col) out_flush(); ui_delay(1002L, TRUE); // give the user time to think about it } - curbuf->b_did_warn = TRUE; + curbuf->b_did_warn = true; redraw_cmdline = FALSE; // don't redraw and erase the message if (msg_row < Rows - 1) showmode(); @@ -702,7 +702,7 @@ changed_common( // This is the first of a new sequence of undo-able changes // and it's at some distance of the last change. Use a new // position in the changelist. - curbuf->b_new_change = FALSE; + curbuf->b_new_change = false; if (curbuf->b_changelistlen == JUMPLISTSIZE) { @@ -897,7 +897,7 @@ changedOneline(buf_T *buf, linenr_T lnum) else { // set the area that must be redisplayed to one line - buf->b_mod_set = TRUE; + buf->b_mod_set = true; buf->b_mod_top = lnum; buf->b_mod_bot = lnum + 1; buf->b_mod_xlines = 0; @@ -1035,7 +1035,7 @@ changed_lines_buf( else { // set the area that must be redisplayed - buf->b_mod_set = TRUE; + buf->b_mod_set = true; buf->b_mod_top = lnum; buf->b_mod_bot = lnume + xtra; buf->b_mod_xlines = xtra; diff --git a/src/channel.c b/src/channel.c index 64c6ee19b3..0902ba3822 100644 --- a/src/channel.c +++ b/src/channel.c @@ -839,7 +839,7 @@ channel_connect( * Returns the channel for success. * Returns NULL for failure. */ - static channel_T * + channel_T * channel_open_unix( const char *path, void (*nb_close_cb)(void)) @@ -1309,6 +1309,46 @@ channel_set_options(channel_T *channel, jobopt_T *opt) channel->ch_part[PART_IN].ch_io = opt->jo_io[PART_IN]; } +/* + * Parse the address for socketserver and store port in "port", or the path in + * "unix_path" if it is a unix domain socket. Returns OK on success and FAIL on + * failure. + */ + int +channel_parse_socketserver_address( + char_u *address, + int *port, + char_u **unix_path, + bool quiet) +{ + char *rest; + long val; + + if (*address == NUL) + goto fail; + + if (!STRNCMP(address, "unix:", 5)) + { + *unix_path = vim_strsave(address + 5); + return OK; + } + + val = strtol((char *)(address), &rest, 10); + if (val < 0 || val >= 65536 || *rest != NUL) + { + if (!quiet) + semsg(_(e_invalid_argument_str), address); + return FAIL; + } + *port = (int)val; + + return OK; +fail: + if (!quiet) + semsg(_(e_invalid_argument_str), address); + return FAIL; +} + /* * Implements ch_open(). */ @@ -1419,8 +1459,7 @@ theend: channel_T * channel_listen_func(typval_T *argvars) { - char_u *address; - char_u *p; + char_u *arg; char *rest; int port; int is_unix = FALSE; @@ -1428,62 +1467,31 @@ channel_listen_func(typval_T *argvars) channel_T *channel = NULL; if (in_vim9script() - && (check_for_string_arg(argvars, 0) == FAIL - || check_for_opt_dict_arg(argvars, 1) == FAIL)) + && check_for_string_arg(argvars, 0) == FAIL) return NULL; - address = tv_get_string(&argvars[0]); - if (argvars[1].v_type != VAR_UNKNOWN - && check_for_nonnull_dict_arg(argvars, 1) == FAIL) - return NULL; - - if (*address == NUL) + arg = tv_get_string(&argvars[0]); + if (*arg == NUL) { - semsg(_(e_invalid_argument_str), address); + semsg(_(e_invalid_argument_str), arg); return NULL; } - if (!STRNCMP(address, "unix:", 5)) + if (!STRNCMP(arg, "unix:", 5)) { is_unix = TRUE; - address += 5; + arg += 5; port = 0; } - else if (*address == '[') - { - // ipv6 address - p = vim_strchr(address + 1, ']'); - if (p == NULL || *++p != ':') - { - semsg(_(e_invalid_argument_str), address); - return NULL; - } - port = strtol((char *)(p + 1), &rest, 10); - if (port < 0 || port >= 65536 || *rest != NUL) - { - semsg(_(e_invalid_argument_str), address); - return NULL; - } - // strip '[' and ']' - ++address; - *(p - 1) = NUL; - } else { - // ipv4 address - p = vim_strchr(address, ':'); - if (p == NULL) - { - semsg(_(e_invalid_argument_str), address); - return NULL; - } - port = strtol((char *)(p + 1), &rest, 10); + port = strtol((char *)(arg), &rest, 10); if (port < 0 || port >= 65536 || *rest != NUL) { - semsg(_(e_invalid_argument_str), address); + semsg(_(e_invalid_argument_str), arg); return NULL; } - *p = NUL; + *arg = NUL; } // parse options @@ -1500,9 +1508,9 @@ channel_listen_func(typval_T *argvars) } if (is_unix) - channel = channel_listen_unix((char *)address, NULL); + channel = channel_listen_unix((char *)arg, NULL, true); else - channel = channel_listen((char *)address, port, NULL); + channel = channel_listen(port, NULL); if (channel != NULL) { opt.jo_set = JO_ALL; @@ -1520,7 +1528,6 @@ theend: */ channel_T * channel_listen( - char *hostname, int port_in, void (*nb_close_cb)(void)) { @@ -1532,12 +1539,6 @@ channel_listen( int val = 1; channel_T *channel; - if (hostname == NULL || *hostname == NUL) - { - ch_error(NULL, "Hostname/address not defined."); - return NULL; - } - #ifdef MSWIN channel_init_winsock(); #endif @@ -1554,42 +1555,7 @@ channel_listen( vim_memset((char *)&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(port_in); - -#ifdef FEAT_IPV6 - struct addrinfo hints; - struct addrinfo *res = NULL; - int err; - - CLEAR_FIELD(hints); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - if ((err = getaddrinfo(hostname, NULL, &hints, &res)) != 0) - { - ch_error(channel, "in getaddrinfo() in channel_listen()"); - PERROR(_(e_gethostbyname_in_channel_listen)); - channel_free(channel); - return NULL; - } - memcpy(&server.sin_addr, - &((struct sockaddr_in *)res->ai_addr)->sin_addr, - sizeof(server.sin_addr)); - freeaddrinfo(res); -#else - if ((host = gethostbyname(hostname)) == NULL) - { - ch_error(channel, "in gethostbyname() in channel_listen()"); - PERROR(_(e_gethostbyname_in_channel_listen)); - channel_free(channel); - return NULL; - } - - char *p; - - // When using host->h_addr_list[0] directly ubsan warns for it to - // not be aligned. First copy the pointer to avoid that. - memcpy(&p, &host->h_addr_list[0], sizeof(p)); - memcpy((char *)&server.sin_addr, p, host->h_length); -#endif + server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sd = socket(AF_INET, SOCK_STREAM, 0); if (sd == -1) @@ -1651,7 +1617,7 @@ channel_listen( channel->ch_listen = TRUE; channel->CH_SOCK_FD = (sock_T)sd; channel->ch_nb_close_cb = nb_close_cb; - channel->ch_hostname = (char *)vim_strsave((char_u *)hostname); + channel->ch_hostname = (char *)vim_strsave((char_u *)""); channel->ch_port = port_in; channel->ch_to_be_closed |= (1U << PART_SOCK); @@ -1664,13 +1630,15 @@ channel_listen( /* * Listen to a Unix domain socket channel. + * If "replace" is true, then unlink the path first beforehand. * Returns the channel for success. * Returns NULL for failure. */ channel_T * channel_listen_unix( char *path, - void (*nb_close_cb)(void)) + void (*nb_close_cb)(void), + bool replace) { int sd = -1; struct sockaddr_un server; @@ -1712,8 +1680,9 @@ channel_listen_unix( return NULL; } - // Unlink the socket in case it already exists - unlink(server.sun_path); + if (replace) + // Unlink the socket in case it already exists + unlink(server.sun_path); // Bind the socket to the path server_len = offsetof(struct sockaddr_un, sun_path) + path_len + 1; @@ -1854,7 +1823,7 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options) { // Special mode: send last-but-one line when appending a line // to the buffer. - in_part->ch_bufref.br_buf->b_write_to_channel = TRUE; + in_part->ch_bufref.br_buf->b_write_to_channel = true; in_part->ch_buf_append = TRUE; in_part->ch_buf_top = in_part->ch_bufref.br_buf->b_ml.ml_line_count + 1; @@ -2083,7 +2052,7 @@ channel_buffer_free(buf_T *buf) /* * Write any lines waiting to be written to "channel". */ - static void + void channel_write_input(channel_T *channel) { chanpart_T *in_part = &channel->ch_part[PART_IN]; @@ -2154,7 +2123,7 @@ channel_write_new_lines(buf_T *buf) } } if (!found_one) - buf->b_write_to_channel = FALSE; + buf->b_write_to_channel = false; } /* @@ -2464,7 +2433,7 @@ channel_save(channel_T *channel, ch_part_T part, char_u *buf, int len, * Try to fill the buffer of "reader". * Returns FALSE when nothing was added. */ - static int + int channel_fill(js_read_T *reader) { channel_T *channel = (channel_T *)reader->js_cookie; @@ -2584,11 +2553,12 @@ channel_process_lspdap_http_hdr(js_read_T *reader) /* * Use the read buffer of "channel"/"part" and parse a JSON message that is - * complete. The messages are added to the queue. + * complete. The messages are added to the queue. If "socketserver" is true, + * then ignore the channel mode. * Return TRUE if there is more to read. */ - static int -channel_parse_json(channel_T *channel, ch_part_T part) + int +channel_parse_json(channel_T *channel, ch_part_T part, bool socketserver) { js_read_T reader; typval_T listtv; @@ -2607,8 +2577,8 @@ channel_parse_json(channel_T *channel, ch_part_T part) reader.js_cookie = channel; reader.js_cookie_arg = part; - if (chanpart->ch_mode == CH_MODE_LSP - || chanpart->ch_mode == CH_MODE_DAP) + if (!socketserver && (chanpart->ch_mode == CH_MODE_LSP + || chanpart->ch_mode == CH_MODE_DAP)) status = channel_process_lspdap_http_hdr(&reader); // When a message is incomplete we wait for a short while for more to @@ -2626,14 +2596,16 @@ channel_parse_json(channel_T *channel, ch_part_T part) { // Only accept the response when it is a list with at least two // items. - if ((chanpart->ch_mode == CH_MODE_LSP || chanpart->ch_mode == CH_MODE_DAP) + if (!socketserver && (chanpart->ch_mode == CH_MODE_LSP + || chanpart->ch_mode == CH_MODE_DAP) && listtv.v_type != VAR_DICT) { ch_error(channel, "Did not receive a LSP dict, discarding"); clear_tv(&listtv); } - else if (chanpart->ch_mode != CH_MODE_LSP && chanpart->ch_mode != CH_MODE_DAP - && (listtv.v_type != VAR_LIST || listtv.vval.v_list->lv_len < 2)) + else if (!socketserver && chanpart->ch_mode != CH_MODE_LSP + && chanpart->ch_mode != CH_MODE_DAP + && (listtv.v_type != VAR_LIST || listtv.vval.v_list->lv_len < 2)) { if (listtv.v_type != VAR_LIST) ch_error(channel, "Did not receive a list, discarding"); @@ -2768,7 +2740,7 @@ remove_cb_node(cbq_T *head, cbq_T *node) * Remove "node" from the queue that it is in and free it. * Caller should have freed or used node->jq_value. */ - static void + void remove_json_node(jsonq_T *head, jsonq_T *node) { if (node->jq_prev == NULL) @@ -3169,7 +3141,7 @@ append_to_buffer( { aco_save_T aco; linenr_T lnum = buffer->b_ml.ml_line_count; - int save_write_to = buffer->b_write_to_channel; + bool save_write_to = buffer->b_write_to_channel; chanpart_T *ch_part = &channel->ch_part[part]; int save_p_ma = buffer->b_p_ma; int empty = (buffer->b_ml.ml_flags & ML_EMPTY) ? 1 : 0; @@ -3189,7 +3161,7 @@ append_to_buffer( if (save_write_to) { --lnum; - buffer->b_write_to_channel = FALSE; + buffer->b_write_to_channel = false; } // Append to the buffer @@ -3268,7 +3240,7 @@ append_to_buffer( // Find channels reading from this buffer and adjust their // next-to-read line number. - buffer->b_write_to_channel = TRUE; + buffer->b_write_to_channel = true; FOR_ALL_CHANNELS(ch) { chanpart_T *in_part = &ch->ch_part[PART_IN]; @@ -3313,6 +3285,7 @@ channel_use_json_head(channel_T *channel, ch_part_T part) may_invoke_callback(channel_T *channel, ch_part_T part) { char_u *msg = NULL; + blob_T *blob = NULL; typval_T *listtv = NULL; typval_T argv[CH_JSON_MAX_ARGS]; int seq_nr = -1; @@ -3324,9 +3297,14 @@ may_invoke_callback(channel_T *channel, ch_part_T part) buf_T *buffer = NULL; char_u *p; int called_otc; // one time callbackup + int raw_len = 0; - if (channel->ch_nb_close_cb != NULL) - // this channel is handled elsewhere (netbeans) + if (channel->ch_nb_close_cb != NULL +#ifdef FEAT_SOCKETSERVER + || channel->ch_socketserver +#endif + ) + // this channel is handled elsewhere (netbeans or socketserver) return FALSE; // Use a message-specific callback, part callback or channel callback @@ -3365,7 +3343,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part) (void)channel_collapse(channel, part, FALSE); // Parse readahead, return when there is still no message. - channel_parse_json(channel, part); + channel_parse_json(channel, part, false); if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL) return FALSE; } @@ -3484,15 +3462,42 @@ may_invoke_callback(channel_T *channel, ch_part_T part) { // For a raw channel we don't know where the message ends, just // get everything we have. - // Convert NUL to NL, the internal representation. - msg = channel_get_all(channel, part, NULL); + raw_len = 0; + msg = channel_get_all(channel, part, + ch_mode == CH_MODE_BLOB ? &raw_len : NULL); } if (msg == NULL) return FALSE; // out of memory (and avoids Coverity warning) - argv[1].v_type = VAR_STRING; - argv[1].vval.v_string = msg; + if (ch_mode == CH_MODE_BLOB) + { + blob = blob_alloc(); + if (blob == NULL) + { + vim_free(msg); + return FALSE; + } + if (ga_grow(&blob->bv_ga, raw_len) == FAIL) + { + blob_free(blob); + vim_free(msg); + return FALSE; + } + if (raw_len > 0) + { + mch_memmove(blob->bv_ga.ga_data, msg, (size_t)raw_len); + blob->bv_ga.ga_len = raw_len; + } + argv[1].v_type = VAR_BLOB; + argv[1].vval.v_blob = blob; + ++blob->bv_refcount; + } + else + { + argv[1].v_type = VAR_STRING; + argv[1].vval.v_string = msg; + } } called_otc = FALSE; @@ -3610,46 +3615,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part) // invoke the channel callback ch_log(channel, "Invoking channel callback %s", (char *)callback->cb_name); -#ifdef FEAT_TERMINAL - // For a terminal job in RAW mode (term_start()), split msg on - // NL and invoke the callback once per line with trailing CR - // stripped. This ensures out_cb/err_cb receive one line at a - // time regardless of how much data arrives in a single read. - if (ch_mode == CH_MODE_RAW && msg != NULL - && channel->ch_job != NULL - && channel->ch_job->jv_tty_out != NULL) - { - char_u *cp = msg; - char_u *nl; - - while ((nl = vim_strchr(cp, NL)) != NULL) - { - long_u len = (long_u)(nl - cp); - - if (len > 0 && cp[len - 1] == CAR) - --len; - argv[1].vval.v_string = vim_strnsave(cp, len); - if (argv[1].vval.v_string != NULL) - invoke_callback(channel, callback, argv); - vim_free(argv[1].vval.v_string); - cp = nl + 1; - } - if (*cp != NUL) - { - long_u len = STRLEN(cp); - - if (len > 0 && cp[len - 1] == CAR) - --len; - argv[1].vval.v_string = vim_strnsave(cp, len); - if (argv[1].vval.v_string != NULL) - invoke_callback(channel, callback, argv); - vim_free(argv[1].vval.v_string); - } - argv[1].vval.v_string = msg; - } - else -#endif - invoke_callback(channel, callback, argv); + invoke_callback(channel, callback, argv); } } } @@ -3658,6 +3624,8 @@ may_invoke_callback(channel_T *channel, ch_part_T part) if (listtv != NULL) free_tv(listtv); + if (blob != NULL) + blob_unref(blob); vim_free(msg); return TRUE; @@ -3703,7 +3671,7 @@ channel_readahead_pointer(channel_T *channel, ch_part_T part) if (head->jq_next == NULL) // Parse json from readahead, there might be a complete message to // process. - channel_parse_json(channel, part); + channel_parse_json(channel, part, false); return head->jq_next; } @@ -3768,46 +3736,77 @@ channel_part_info(channel_T *channel, dict_T *dict, char *name, ch_part_T part) chanpart_T *chanpart = &channel->ch_part[part]; char namebuf[20]; // longest is "sock_timeout" size_t tail; - char *status; - char *s = ""; + string_T s; vim_strncpy((char_u *)namebuf, (char_u *)name, 4); - STRCAT(namebuf, "_"); tail = STRLEN(namebuf); + STRCPY(namebuf + tail, "_"); + tail += STRLEN_LITERAL("_"); STRCPY(namebuf + tail, "status"); if (chanpart->ch_fd != INVALID_FD) - status = "open"; + STR_LITERAL_SET(s, "open"); else if (channel_has_readahead(channel, part)) - status = "buffered"; + STR_LITERAL_SET(s, "buffered"); else - status = "closed"; - dict_add_string(dict, namebuf, (char_u *)status); + STR_LITERAL_SET(s, "closed"); + dict_add_string_len(dict, namebuf, s.string, (int)s.length); STRCPY(namebuf + tail, "mode"); switch (chanpart->ch_mode) { - case CH_MODE_NL: s = "NL"; break; - case CH_MODE_RAW: s = "RAW"; break; - case CH_MODE_JSON: s = "JSON"; break; - case CH_MODE_JS: s = "JS"; break; - case CH_MODE_LSP: s = "LSP"; break; - case CH_MODE_DAP: s = "DAP"; break; + case CH_MODE_NL: + STR_LITERAL_SET(s, "NL"); + break; + case CH_MODE_RAW: + STR_LITERAL_SET(s, "RAW"); + break; + case CH_MODE_BLOB: + STR_LITERAL_SET(s, "BLOB"); + break; + case CH_MODE_JSON: + STR_LITERAL_SET(s, "JSON"); + break; + case CH_MODE_JS: + STR_LITERAL_SET(s, "JS"); + break; + case CH_MODE_LSP: + STR_LITERAL_SET(s, "LSP"); + break; + case CH_MODE_DAP: + STR_LITERAL_SET(s, "DAP"); + break; + default: + STR_LITERAL_SET(s, ""); + break; } - dict_add_string(dict, namebuf, (char_u *)s); + dict_add_string_len(dict, namebuf, s.string, (int)s.length); STRCPY(namebuf + tail, "io"); if (part == PART_SOCK) - s = "socket"; + STR_LITERAL_SET(s, "socket"); else switch (chanpart->ch_io) { - case JIO_NULL: s = "null"; break; - case JIO_PIPE: s = "pipe"; break; - case JIO_FILE: s = "file"; break; - case JIO_BUFFER: s = "buffer"; break; - case JIO_OUT: s = "out"; break; + case JIO_NULL: + STR_LITERAL_SET(s, "null"); + break; + case JIO_PIPE: + STR_LITERAL_SET(s, "pipe"); + break; + case JIO_FILE: + STR_LITERAL_SET(s, "file"); + break; + case JIO_BUFFER: + STR_LITERAL_SET(s, "buffer"); + break; + case JIO_OUT: + STR_LITERAL_SET(s, "out"); + break; + default: + STR_LITERAL_SET(s, ""); + break; } - dict_add_string(dict, namebuf, (char_u *)s); + dict_add_string_len(dict, namebuf, s.string, (int)s.length); STRCPY(namebuf + tail, "timeout"); dict_add_number(dict, namebuf, chanpart->ch_timeout); @@ -3822,10 +3821,7 @@ channel_info(channel_T *channel, dict_T *dict) if (channel->ch_hostname != NULL) { if (channel->ch_port) - { - dict_add_string(dict, "hostname", (char_u *)channel->ch_hostname); dict_add_number(dict, "port", channel->ch_port); - } else // Unix-domain socket. dict_add_string(dict, "path", (char_u *)channel->ch_hostname); @@ -3922,6 +3918,11 @@ channel_close(channel_T *channel, int invoke_close_cb) } channel->ch_nb_close_cb = NULL; +#ifdef FEAT_SOCKETSERVER + channel->ch_socketserver = false; + channel->ch_ss_accept_cb = NULL; + channel->ch_ss_close_cb = NULL; +#endif #ifdef FEAT_TERMINAL term_channel_closed(channel); @@ -4261,6 +4262,10 @@ channel_close_now(channel_T *channel) ch_log(channel, "Closing channel because all readable fds are closed"); if (channel->ch_nb_close_cb != NULL) (*channel->ch_nb_close_cb)(); +#ifdef FEAT_SOCKETSERVER + if (channel->ch_ss_close_cb != NULL) + channel->ch_ss_close_cb(channel); +#endif channel_close(channel, TRUE); } @@ -4332,6 +4337,14 @@ channel_read(channel_T *channel, ch_part_T part, char *func) channel_gui_register_one(newchannel, PART_SOCK); #endif +#ifdef FEAT_SOCKETSERVER + if (channel->ch_ss_accept_cb != NULL) + { + channel->ch_ss_accept_cb(newchannel); + return; + } +#endif + if (client.ss_family == AF_INET) { #ifdef HAVE_INET_NTOP @@ -4403,6 +4416,16 @@ channel_read(channel_T *channel, ch_part_T part, char *func) #endif } +#ifdef FEAT_SOCKETSERVER + + void +channel_check(channel_T *channel, ch_part_T part) +{ + channel_read(channel, part, "channel_check"); +} + +#endif + /* * Read from RAW or NL "channel"/"part". Blocks until there is something to * read or the timeout expires. @@ -4423,14 +4446,16 @@ channel_read_block( readq_T *node; ch_log(channel, "Blocking %s read, timeout: %d msec", - mode == CH_MODE_RAW ? "RAW" : "NL", timeout); + mode == CH_MODE_RAW ? "RAW" + : mode == CH_MODE_BLOB ? "BLOB" : "NL", timeout); while (TRUE) { node = channel_peek(channel, part); if (node != NULL) { - if (mode == CH_MODE_RAW || (mode == CH_MODE_NL + if (mode == CH_MODE_RAW || mode == CH_MODE_BLOB + || (mode == CH_MODE_NL && channel_first_nl(node) != NULL)) // got a complete message break; @@ -4454,7 +4479,7 @@ channel_read_block( } // We have a complete message now. - if (mode == CH_MODE_RAW || outlen != NULL) + if (mode == CH_MODE_RAW || mode == CH_MODE_BLOB || outlen != NULL) { msg = channel_get_all(channel, part, outlen); } @@ -4490,7 +4515,8 @@ channel_read_block( } } if (ch_log_active()) - ch_log(channel, "Returning %d bytes", (int)STRLEN(msg)); + ch_log(channel, "Returning %d bytes", + outlen != NULL ? *outlen : (int)STRLEN(msg)); return msg; } @@ -4542,7 +4568,7 @@ channel_read_json_block( // received messages. (void)channel_collapse(channel, part, FALSE); - more = channel_parse_json(channel, part); + more = channel_parse_json(channel, part, false); // search for message "id" if (channel_get_json(channel, part, id, TRUE, rettv) == OK) @@ -4701,7 +4727,7 @@ common_channel_read(typval_T *argvars, typval_T *rettv, int raw, int blob) if (opt.jo_set & JO_TIMEOUT) timeout = opt.jo_timeout; - if (blob) + if (blob || mode == CH_MODE_BLOB) { int outlen = 0; char_u *p = channel_read_block(channel, part, @@ -5143,9 +5169,10 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval) part_send = channel_part_send(channel); ch_mode = channel_get_mode(channel, part_send); - if (ch_mode == CH_MODE_RAW || ch_mode == CH_MODE_NL) + if (ch_mode == CH_MODE_RAW || ch_mode == CH_MODE_BLOB + || ch_mode == CH_MODE_NL) { - emsg(_(e_cannot_use_evalexpr_sendexpr_with_raw_or_nl_channel)); + emsg(_(e_cannot_use_evalexpr_sendexpr_with_raw_nl_or_blob_channel)); return; } @@ -5206,7 +5233,7 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval) id = di->di_tv.vval.v_number; } if (ch_mode == CH_MODE_LSP && !dict_has_key(d, "jsonrpc")) - dict_add_string(d, "jsonrpc", (char_u *)"2.0"); + dict_add_string_len(d, "jsonrpc", (char_u *)"2.0", STRLEN_LITERAL("2.0")); text = json_encode_lsp_msg(&argvars[1]); } else @@ -6028,4 +6055,17 @@ channel_to_string_buf(typval_T *varp, char_u *buf) return buf; } +/* + * Return the channel with the given ID. Returns NULL if not found. + */ + channel_T * +channel_find(int ch_id) +{ + channel_T *ch; + FOR_ALL_CHANNELS(ch) + if (ch->ch_id == ch_id) + return ch; + return NULL; +} + #endif // FEAT_JOB_CHANNEL diff --git a/src/charset.c b/src/charset.c index 8ad768d354..bf7c59620f 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1468,7 +1468,8 @@ win_lbr_chartabsize( if (max_head_vcol == 0 || vcol + size + added < max_head_vcol) head += cnt * head_mid; - else if (max_head_vcol > vcol + head_prev + prev_rem) + else if (width2 > 0 + && max_head_vcol > vcol + head_prev + prev_rem) head += (max_head_vcol - (vcol + head_prev + prev_rem) + width2 - 1) / width2 * head_mid; else if (max_head_vcol < 0) diff --git a/src/cindent.c b/src/cindent.c index ddd268176b..94c01db7e8 100644 --- a/src/cindent.c +++ b/src/cindent.c @@ -1153,7 +1153,7 @@ find_match_char(int c, int ind_maxparen) // XXX cursor_save = curwin->w_cursor; ind_maxp_wk = ind_maxparen; retry: - if ((trypos = findmatchlimit(NULL, c, 0, ind_maxp_wk)) != NULL) + if ((trypos = findmatchlimit(NULL, c, FM_SKIPCOMM, ind_maxp_wk)) != NULL) { // check if the ( is in a // comment if ((colnr_T)cin_skip2pos(trypos) > trypos->col) @@ -1396,7 +1396,7 @@ cin_iswhileofdo (char_u *p, linenr_T lnum) // XXX ++p; ++curwin->w_cursor.col; } - if ((trypos = findmatchlimit(NULL, 0, 0, + if ((trypos = findmatchlimit(NULL, 0, FM_SKIPCOMM, curbuf->b_ind_maxparen)) != NULL && *cin_skipcomment(ml_get_pos(trypos) + 1) == ';') retval = TRUE; @@ -1732,7 +1732,7 @@ find_start_brace(void) // XXX static pos_T pos_copy; cursor_save = curwin->w_cursor; - while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL) + while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP | FM_SKIPCOMM, 0)) != NULL) { pos_copy = *trypos; // copy pos_T, next findmatch will change it trypos = &pos_copy; @@ -2547,7 +2547,7 @@ get_c_indent(void) line = ml_get_curline(); look_col = (int)(look - line); curwin->w_cursor.col = look_col + 1; - if ((trypos = findmatchlimit(NULL, ')', 0, + if ((trypos = findmatchlimit(NULL, ')', FM_SKIPCOMM, curbuf->b_ind_maxparen)) != NULL && trypos->lnum == our_paren_pos.lnum diff --git a/src/clientserver.c b/src/clientserver.c index 53abca5e8d..95978c59fe 100644 --- a/src/clientserver.c +++ b/src/clientserver.c @@ -15,11 +15,6 @@ #if defined(FEAT_CLIENTSERVER) -# ifdef FEAT_SOCKETSERVER -# include -# include "sys/un.h" -# endif - static void cmdsrv_main(int *argc, char **argv, char_u *serverName_arg, char_u **serverStr); static char_u *serverMakeName(char_u *arg, char *cmd); @@ -206,23 +201,6 @@ exec_on_server(mparm_T *parmp) serverInitMessaging(); # endif -# ifdef FEAT_SOCKETSERVER - // If servername is specified and we are using sockets, always init the - // sockt server. We may need to receive replies back to us. If --serverlist - // is passed, the socket server will be uninitialized before listing - // sockets then initialized after. This is so we don't add our own socket - // in the list. This does not happen in serverlist(). - if ((parmp->serverArg || parmp->serverName_arg != NULL) && - clientserver_method == CLIENTSERVER_METHOD_SOCKET) - { - parmp->servername = serverMakeName(parmp->serverName_arg, - parmp->argv[0]); - if (socket_server_init(parmp->servername) == OK) - TIME_MSG("initialize socket server"); - made_name = TRUE; - } -# endif - /* * When a command server argument was found, execute it. This may * exit Vim when it was successful. Otherwise it's executed further @@ -242,10 +220,12 @@ exec_on_server(mparm_T *parmp) parmp->servername = serverMakeName(parmp->serverName_arg, parmp->argv[0]); # ifdef MSWIN - if (parmp->servername != NULL) + if (parmp->servername != NULL && clientserver_method == CLIENTSERVER_METHOD_MSWIN) { serverSetName(parmp->servername); +# ifndef FEAT_SOCKETSERVER vim_free(parmp->servername); +# endif } # endif } @@ -262,16 +242,31 @@ prepare_server(mparm_T *parmp) * Only register nongui-vim's with an explicit --servername argument, * or when compiling with autoservername. * When running as root --servername is also required. + * + * If we are Windows and socketserver is being used, then don't use + * autoservername, since traditional naming isn't supported. */ if ( -# ifdef FEAT_X11 - X_DISPLAY != NULL && +# if defined(FEAT_X11) || (defined(FEAT_SOCKETSERVER) && !defined(MSWIN)) + ( +# ifdef FEAT_X11 + X_DISPLAY != NULL +# endif +# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER) && !defined(MSWIN) + || +# endif +# if defined(FEAT_SOCKETSERVER) && !defined(MSWIN) + clientserver_method == CLIENTSERVER_METHOD_SOCKET +# endif + ) && # endif - parmp->servername != NULL && ( # if defined(FEAT_AUTOSERVERNAME) || defined(FEAT_GUI) ( +# if defined(FEAT_SOCKETSERVER) && defined(MSWIN) + clientserver_method != CLIENTSERVER_METHOD_SOCKET && +# endif # if defined(FEAT_AUTOSERVERNAME) 1 # else @@ -284,12 +279,10 @@ prepare_server(mparm_T *parmp) # endif parmp->serverName_arg != NULL)) { + # ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - { - if (socket_server_init(parmp->servername) == OK) - TIME_MSG("initialize socket server"); - } + socketserver_start(parmp->servername, false); # endif # ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11) @@ -300,10 +293,15 @@ prepare_server(mparm_T *parmp) # endif vim_free(parmp->servername); } -# ifdef FEAT_X11 else - serverDelayedStartName = parmp->servername; + { +# ifdef FEAT_X11 + if (clientserver_method == CLIENTSERVER_METHOD_X11) + serverDelayedStartName = parmp->servername; + else # endif + vim_free(parmp->servername); + } # endif /* @@ -343,9 +341,6 @@ cmdsrv_main( # define ARGTYPE_SEND 3 int silent = FALSE; int tabs = FALSE; -# ifdef FEAT_SOCKETSERVER - char_u *receiver; -# endif # ifdef MSWIN HWND srv; # elif defined(MAC_CLIENTSERVER) @@ -355,6 +350,9 @@ cmdsrv_main( setup_term_clip(); # endif +# ifdef FEAT_SOCKETSERVER + channel_T *ch = NULL; +# endif sname = serverMakeName(serverName_arg, argv[0]); if (sname == NULL) @@ -436,9 +434,8 @@ cmdsrv_main( # ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - ret = socket_server_send( - sname, *serverStr, NULL, &receiver, - 0, -1, silent); + ret = socketserver_send(sname, *serverStr, NULL, false, -1, + silent, &ch); # endif # ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11) @@ -456,8 +453,10 @@ cmdsrv_main( ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, 0, silent); # endif # ifdef MSWIN - // Win32 always works? - ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, 0, silent); + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN) + // Win32 always works? + ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, 0, + silent); # endif if (ret < 0) { @@ -517,26 +516,27 @@ cmdsrv_main( char_u *p = NULL; int j; # ifdef MSWIN - p = serverGetReply(srv, NULL, TRUE, TRUE, 0); - if (p == NULL) - break; -# elif defined(MAC_CLIENTSERVER) + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN) + p = serverGetReply(srv, NULL, TRUE, TRUE, 0); +# endif +# ifdef MAC_CLIENTSERVER if (serverReadReply(srv, &p, 0) < 0) break; -# else -# ifdef FEAT_SOCKETSERVER +# endif +# ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET - && socket_server_read_reply(receiver, &p, -1) == FAIL) + && (ch == NULL + || socketserver_read_reply(sname, &p, -1, true) + == FAIL)) break; -# endif -# ifdef FEAT_X11 +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11 && serverReadReply(xterm_dpy, srv, &p, TRUE, -1) < 0) break; -# endif +# endif if (p == NULL) break; -# endif j = atoi((char *)p); vim_free(p); if (j >= 0 && j < numFiles) @@ -550,6 +550,13 @@ cmdsrv_main( done[j] = 1; } } +# ifdef FEAT_SOCKETSERVER + if (ch != NULL) + { + channel_close(ch, false); + channel_clear(ch); + } +# endif # ifdef FEAT_GUI_MSWIN Shell_NotifyIcon(NIM_DELETE, &ni); # endif @@ -558,29 +565,29 @@ cmdsrv_main( } else if (STRICMP(argv[i], "--remote-expr") == 0) { + int status = OK; + if (i == *argc - 1) mainerr_arg_missing((char_u *)argv[i]); -# if defined(MSWIN) +# ifdef MSWIN // Win32 always works? + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN + && serverSendToVim(sname, (char_u *)argv[i + 1], + &res, NULL, 1, 0, FALSE) < 0) + status = FAIL; +# endif +# ifdef MAC_CLIENTSERVER if (serverSendToVim(sname, (char_u *)argv[i + 1], &res, NULL, 1, 0, FALSE) < 0) -# elif defined(MAC_CLIENTSERVER) - if (serverSendToVim(sname, (char_u *)argv[i + 1], - &res, NULL, 1, 0, FALSE) < 0) - goto expr_fail; -# else -# ifdef FEAT_SOCKETSERVER - if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - { - if (!socket_server_valid()) - mch_errmsg(_("Socket server not online:" - "Send expression failed")); - else if (socket_server_send(sname, (char_u *)argv[i + 1], - &res, NULL, 1, 0, FALSE) < 0) - goto expr_fail; - } -# endif -# ifdef FEAT_X11 + status = FAIL; +# endif +# ifdef FEAT_SOCKETSERVER + if (clientserver_method == CLIENTSERVER_METHOD_SOCKET + && socketserver_send(sname, (char_u *)argv[i + 1], + &res, 1, 0, false, NULL) < 0) + status = FAIL; +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11) { if (xterm_dpy == NULL) @@ -588,15 +595,11 @@ cmdsrv_main( else if (serverSendToVim(xterm_dpy, sname, (char_u *)argv[i + 1], &res, NULL, 1, 0, 1, FALSE) < 0) - goto expr_fail; + status = FAIL; } -# endif - if (FALSE) # endif + if (status == FAIL) { -# if !defined(MSWIN) -expr_fail: -# endif if (res != NULL && *res != NUL) { // Output error from remote @@ -608,29 +611,26 @@ expr_fail: } else if (STRICMP(argv[i], "--serverlist") == 0) { -# if defined(MSWIN) || defined(MAC_CLIENTSERVER) - // Win32 always works? +# ifdef MSWIN + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN) + // Win32 always works? + res = serverGetVimNames(); +# endif +# ifdef MAC_CLIENTSERVER res = serverGetVimNames(); -# else -# ifdef FEAT_SOCKETSERVER +# endif +# ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - { - int was_init = socket_server_valid(); - - // Don't want to add ourselves to the list. So shutdown the - // server before listing then startup back again. - socket_server_uninit(); - res = socket_server_list_sockets(); - - if (was_init) - socket_server_init(NULL); - } +# ifdef MSWIN + res = vim_strsave((char_u *)""); +# else + res = socketserver_list(); # endif -# ifdef FEAT_X11 +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11 && xterm_dpy != NULL) res = serverGetVimNames(xterm_dpy); -# endif # endif if (did_emsg) mch_errmsg("\n"); @@ -659,9 +659,6 @@ expr_fail: if (didone) { -# ifdef FEAT_SOCKETSERVER - socket_server_uninit(); -# endif display_errors(); // display any collected messages exit(exiterr); // Mission accomplished - get out } @@ -688,13 +685,10 @@ build_drop_cmd( string_T cdp; char_u *cwd; // reset wildignore temporarily -# define STRING_INIT(s) \ - {(char_u *)(s), STRLEN_LITERAL(s)} const string_T wig[] = { - STRING_INIT(":let g:_wig=&wig|set wig="), - STRING_INIT(":let &wig=g:_wig|unlet g:_wig") + STR_LITERAL_INIT(":let g:_wig=&wig|set wig="), + STR_LITERAL_INIT(":let &wig=g:_wig|unlet g:_wig") }; -# undef STRING_INIT if (filec > 0 && filev[0][0] == '+') { @@ -821,12 +815,12 @@ serverMakeName(char_u *arg, char *cmd) if (arg != NULL && *arg != NUL) { # ifdef FEAT_SOCKETSERVER - // If we are using a socket server, we want to preserve the original - // name if it is a path, else uppercase it if its just a generic name. + // When using socketserver backend, do not change the name if path or + // channel address. if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) { - if (arg[0] == '/' || STRNCMP(arg, "./", 2) == 0 || - STRNCMP(arg, "../", 3) == 0) + if (STRNICMP(arg, "channel:", 8) == 0 || arg[0] == '/' || + STRNCMP(arg, "./", 2) == 0 || STRNCMP(arg, "../", 3) == 0) p = vim_strsave(arg); else p = vim_strsave_up(arg); @@ -867,6 +861,8 @@ make_connection(void) static int check_connection(void) { + if (clientserver_method != CLIENTSERVER_METHOD_X11) + return OK; make_connection(); if (X_DISPLAY == NULL) { @@ -895,10 +891,8 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr) # ifdef MAC_CLIENTSERVER int w; // This is the port number ('w' is a bit confusing) # endif -# ifdef FEAT_SOCKETSERVER - char_u *client = NULL; -# endif # endif + int ret = OK; if (check_restricted() || check_secure()) return; @@ -915,39 +909,34 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr) if (server_name == NULL) return; // type error; errmsg already given keys = tv_get_string_buf(&argvars[1], buf); -# if defined(MSWIN) +# ifdef MSWIN + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN + && serverSendToVim(server_name, keys, &r, &w, expr, + timeout, TRUE) < 0) + ret = FAIL; +# endif +# ifdef MAC_CLIENTSERVER if (serverSendToVim(server_name, keys, &r, &w, expr, timeout, TRUE) < 0) -# elif defined(MAC_CLIENTSERVER) - if (serverSendToVim(server_name, keys, &r, &w, expr, timeout, TRUE) < 0) - goto fail; -# else -# ifdef FEAT_SOCKETSERVER - if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - if (socket_server_send(server_name, keys, &r, &client, expr, - timeout * 1000, TRUE) < 0) - goto fail; -# endif -# ifdef FEAT_X11 + ret = FAIL; +# endif +# ifdef FEAT_SOCKETSERVER + if (clientserver_method == CLIENTSERVER_METHOD_SOCKET + && socketserver_send(server_name, keys, &r, expr, + timeout * 1000, true, NULL) < 0) + ret = FAIL; +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11) if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, timeout, 0, TRUE) < 0) - goto fail; -# endif + ret = FAIL; # endif -# if !defined(MSWIN) - if (FALSE) + if (ret == FAIL) { -fail: -# else - { -# endif if (r != NULL) { emsg((char *)r); // sending worked but evaluation failed vim_free(r); -# ifdef FEAT_SOCKETSERVER - vim_free(client); -# endif } else semsg(_(e_unable_to_send_to_str), server_name); @@ -959,42 +948,39 @@ fail: if (argvars[2].v_type != VAR_UNKNOWN) { dictitem_T v; -# if defined(FEAT_SOCKETSERVER) - struct sockaddr_un addr; - char_u str[sizeof(addr.sun_path)]; -# else - char_u str[30]; +# if defined(MSWIN) || defined(FEAT_X11) || defined(MAC_CLIENTSERVER) + char_u sbuf[30]; # endif + char_u *str = NULL; char_u *idvar; idvar = tv_get_string_chk(&argvars[2]); if (idvar != NULL && *idvar != NUL) { - str[0] = NUL; # ifdef MSWIN - sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); -# elif defined(MAC_CLIENTSERVER) - sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); -# else -# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11) - sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); -# endif -# ifdef FEAT_SOCKETSERVER - if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - vim_snprintf((char *)str, sizeof(addr.sun_path), - "%s", client); -# endif + { + sprintf((char *)sbuf, PRINTF_HEX_LONG_U, (long_u)w); + str = sbuf; + } # endif +# ifdef MAC_CLIENTSERVER + sprintf((char *)sbuf, PRINTF_HEX_LONG_U, (long_u)w); + str = sbuf; +# endif +# ifdef FEAT_SOCKETSERVER + if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) + str = server_name; +# endif + if (str == NULL) + str = (char_u *)""; + v.di_tv.v_type = VAR_STRING; v.di_tv.vval.v_string = vim_strsave(str); set_var(idvar, &v.di_tv, FALSE); vim_free(v.di_tv.vval.v_string); } } -# ifdef FEAT_SOCKETSERVER - vim_free(client); -# endif } #endif @@ -1076,22 +1062,26 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv) if (serverid == NULL) return; // type error; errmsg already given # ifdef MSWIN - sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n); - if (n == 0) - rettv->vval.v_number = -1; - else + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN) { - s = serverGetReply((HWND)n, FALSE, FALSE, FALSE, 0); - rettv->vval.v_number = (s != NULL); + sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n); + if (n == 0) + rettv->vval.v_number = -1; + else + { + s = serverGetReply((HWND)n, FALSE, FALSE, FALSE, 0); + rettv->vval.v_number = (s != NULL); + } } -# elif defined(MAC_CLIENTSERVER) +# endif +# ifdef MAC_CLIENTSERVER rettv->vval.v_number = serverPeekReply(serverStrToPort(serverid), &s); -# else -# ifdef FEAT_SOCKETSERVER +# endif +# ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - rettv->vval.v_number = socket_server_peek_reply(serverid, &s); -# endif -# ifdef FEAT_X11 + rettv->vval.v_number = socketserver_peek_reply(serverid, &s); +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11) { if (check_connection() == FAIL) @@ -1100,7 +1090,6 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv) rettv->vval.v_number = serverPeekReply(X_DISPLAY, serverStrToWin(serverid), &s); } -# endif # endif if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) @@ -1145,27 +1134,31 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv) timeout = tv_get_number(&argvars[1]); # ifdef MSWIN - sscanf((char *)serverid, SCANF_HEX_LONG_U, &n); - if (n != 0) - r = serverGetReply((HWND)n, FALSE, TRUE, TRUE, timeout); - if (r == NULL) - emsg(_(e_unable_to_read_server_reply)); -# elif defined(MAC_CLIENTSERVER) + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN) + { + sscanf((char *)serverid, SCANF_HEX_LONG_U, &n); + if (n != 0) + r = serverGetReply((HWND)n, FALSE, TRUE, TRUE, timeout); + if (r == NULL) + emsg(_(e_unable_to_read_server_reply)); + } +# endif +# ifdef MAC_CLIENTSERVER if (serverReadReply(serverStrToPort(serverid), &r, timeout) < 0) emsg(_(e_unable_to_read_server_reply)); -# else -# ifdef FEAT_SOCKETSERVER +# endif +# ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET && - socket_server_read_reply(serverid, &r, timeout * 1000) == FAIL) + socketserver_read_reply(serverid, &r, timeout * 1000, false) + == FAIL) emsg(_(e_unable_to_read_server_reply)); -# endif -# ifdef FEAT_X11 +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11 && (check_connection() == FAIL || serverReadReply(X_DISPLAY, serverStrToWin(serverid), &r, FALSE, timeout) < 0)) emsg(_(e_unable_to_read_server_reply)); -# endif # endif } # endif @@ -1211,19 +1204,20 @@ f_remote_startserver(typval_T *argvars UNUSED, typval_T *rettv UNUSED) char_u *server = tv_get_string_chk(&argvars[0]); # ifdef MSWIN - serverSetName(server); -# elif defined(MAC_CLIENTSERVER) + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN) + serverSetName(server); +# endif +# ifdef MAC_CLIENTSERVER serverRegisterName(server); -# else -# ifdef FEAT_SOCKETSERVER +# endif +# ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - socket_server_init(server); -# endif -# ifdef FEAT_X11 + socketserver_start(server, true); +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11 && check_connection() == OK) serverRegisterName(X_DISPLAY, server); -# endif # endif # else @@ -1238,6 +1232,7 @@ f_server2client(typval_T *argvars UNUSED, typval_T *rettv) char_u buf[NUMBUFLEN]; char_u *server; char_u *reply; + int ret = OK; rettv->vval.v_number = -1; if (check_restricted() || check_secure()) @@ -1255,30 +1250,26 @@ f_server2client(typval_T *argvars UNUSED, typval_T *rettv) # ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET && - socket_server_send_reply(server, reply) == FAIL) - goto fail; + socketserver_send_reply(server, reply) == FAIL) + ret = FAIL; # endif - # ifdef FEAT_X11 - if (clientserver_method == CLIENTSERVER_METHOD_X11 && - check_connection() == FAIL) - return; - if (clientserver_method == CLIENTSERVER_METHOD_X11 && serverSendReply(server, reply) < 0) + ret = FAIL; # endif # ifdef MSWIN - if (serverSendReply(server, reply) < 0) -# elif defined(MAC_CLIENTSERVER) - if (serverSendReply(server, reply) < 0) + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN + && serverSendReply(server, reply) < 0) + ret = FAIL; # endif -# if defined(FEAT_SOCKETSERVER) && !defined(FEAT_X11) && !defined(MSWIN) && !defined(MAC_CLIENTSERVER) - if (FALSE) +# ifdef MAC_CLIENTSERVER + if (serverSendReply(server, reply) < 0) + ret = FAIL; # endif + + if (ret == FAIL) { -# ifdef FEAT_SOCKETSERVER -fail: -# endif emsg(_(e_unable_to_send_to_client)); return; } @@ -1294,21 +1285,28 @@ f_serverlist(typval_T *argvars UNUSED, typval_T *rettv) char_u *r = NULL; # ifdef FEAT_CLIENTSERVER -# if defined(MSWIN) || defined(MAC_CLIENTSERVER) +# ifdef MSWIN + if (clientserver_method == CLIENTSERVER_METHOD_MSWIN) + r = serverGetVimNames(); +# endif +# ifdef MAC_CLIENTSERVER r = serverGetVimNames(); -# else -# ifdef FEAT_SOCKETSERVER +# endif +# ifdef FEAT_SOCKETSERVER if (clientserver_method == CLIENTSERVER_METHOD_SOCKET) - r = socket_server_list_sockets(); +# ifdef MSWIN + r = vim_strsave((char_u *)""); +# else + r = socketserver_list(); # endif -# ifdef FEAT_X11 +# endif +# ifdef FEAT_X11 if (clientserver_method == CLIENTSERVER_METHOD_X11) { make_connection(); if (X_DISPLAY != NULL) r = serverGetVimNames(X_DISPLAY); } -# endif # endif # endif rettv->v_type = VAR_STRING; diff --git a/src/clipboard.c b/src/clipboard.c index 7af6115e27..64e073d9b4 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -42,39 +42,6 @@ static int clip_provider_is_available(char_u *provider); # include "wayland.h" -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - -// Structures used for focus stealing -typedef struct { - struct wl_shm_pool *pool; - int fd; - - struct wl_buffer *buffer; - bool available; - - int width; - int height; - int stride; - int size; -} clip_wl_buffer_store_T; - -typedef struct { - void *user_data; - void (*on_focus)(void *data, uint32_t serial); - - struct wl_surface *surface; - struct wl_keyboard *keyboard; - - struct { - struct xdg_surface *surface; - struct xdg_toplevel *toplevel; - } shell; - - bool got_focus; -} clip_wl_fs_surface_T; // fs = focus steal - -# endif // FEAT_WAYLAND_CLIPBOARD_FS - // Represents either the regular or primary selection typedef struct { char_u *contents; // Non-null if we own selection, @@ -84,10 +51,6 @@ typedef struct { // else NULL if we don't. vwl_data_offer_T *offer; // Current offer for the selection -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - bool requires_focus; // If focus needs to be given to us to - // work -# endif bool own_success; // Used by clip_wl_own_selection() bool available; // If selection is ready to serve/use @@ -101,10 +64,6 @@ typedef struct { typedef struct { vwl_seat_T *seat; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - clip_wl_buffer_store_T *fs_buffer; -# endif - clip_wl_selection_T regular; clip_wl_selection_T primary; } clip_wl_T; @@ -1936,7 +1895,8 @@ clip_x11_set_selection(Clipboard_T *cbd UNUSED) # endif -# if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) +# if (defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)) \ + && !defined(USE_GTK4) /* * Get the contents of the X CUT_BUFFER0 and put it in "cbd". */ @@ -2365,290 +2325,6 @@ clip_wl_get_selection_type(clip_wl_selection_T *sel) return WAYLAND_SELECTION_NONE; } -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -/* - * If globals required for focus stealing method are available. - */ - static bool -clip_wl_focus_stealing_available(void) -{ - return wayland_ct->gobjects.wl_compositor != NULL && - wayland_ct->gobjects.wl_shm != NULL && - wayland_ct->gobjects.xdg_wm_base != NULL; -} - -/* - * Called when compositor isn't using the buffer anymore, we can reuse it - * again. - */ - static void -wl_buffer_listener_release( - void *data, - struct wl_buffer *buffer UNUSED) -{ - clip_wl_buffer_store_T *store = data; - - store->available = true; -} - -static struct wl_buffer_listener wl_buffer_listener = { - .release = wl_buffer_listener_release -}; - -/* - * Destroy a buffer store structure. - */ - static void -clip_wl_destroy_buffer_store(clip_wl_buffer_store_T *store) -{ - if (store == NULL) - return; - if (store->buffer != NULL) - wl_buffer_destroy(store->buffer); - if (store->pool != NULL) - wl_shm_pool_destroy(store->pool); - - close(store->fd); - - vim_free(store); -} - -/* - * Initialize a buffer and its backing memory pool. - */ - static clip_wl_buffer_store_T * -clip_wl_init_buffer_store(int width, int height) -{ - int fd, r; - clip_wl_buffer_store_T *store; - - store = alloc(sizeof(*store)); - - if (store == NULL) - return NULL; - - store->available = false; - - store->width = width; - store->height = height; - store->stride = store->width * 4; - store->size = store->stride * store->height; - - fd = mch_create_anon_file(); - r = ftruncate(fd, store->size); - - if (r == -1) - { - if (fd >= 0) - close(fd); - return NULL; - } - - store->pool = wl_shm_create_pool( - wayland_ct->gobjects.wl_shm, - fd, - store->size); - store->buffer = wl_shm_pool_create_buffer( - store->pool, - 0, - store->width, - store->height, - store->stride, - WL_SHM_FORMAT_ARGB8888); - - store->fd = fd; - - wl_buffer_add_listener(store->buffer, &wl_buffer_listener, store); - - if (vwl_connection_roundtrip(wayland_ct) == FAIL) - { - clip_wl_destroy_buffer_store(store); - return NULL; - } - - store->available = true; - - return store; -} - -/* - * Configure xdg_surface - */ - static void -xdg_surface_listener_configure( - void *data UNUSED, - struct xdg_surface *surface, - uint32_t serial) -{ - xdg_surface_ack_configure(surface, serial); -} - - -static struct xdg_surface_listener xdg_surface_listener = { - .configure = xdg_surface_listener_configure -}; - -/* - * Destroy a focus stealing structure. - */ - static void -clip_wl_destroy_fs_surface(clip_wl_fs_surface_T *store) -{ - if (store == NULL) - return; - if (store->shell.toplevel != NULL) - xdg_toplevel_destroy(store->shell.toplevel); - if (store->shell.surface != NULL) - xdg_surface_destroy(store->shell.surface); - if (store->surface != NULL) - wl_surface_destroy(store->surface); - if (store->keyboard != NULL) - { - if (wl_keyboard_get_version(store->keyboard) >= 3) - wl_keyboard_release(store->keyboard); - else - wl_keyboard_destroy(store->keyboard); - } - vim_free(store); -} - -VWL_FUNCS_DUMMY_KEYBOARD_EVENTS() - -/* - * Called when the keyboard focus is on our surface - */ - static void -clip_wl_fs_keyboard_listener_enter( - void *data, - struct wl_keyboard *keyboard UNUSED, - uint32_t serial, - struct wl_surface *surface UNUSED, - struct wl_array *keys UNUSED) -{ - clip_wl_fs_surface_T *store = data; - - store->got_focus = true; - - if (store->on_focus != NULL) - store->on_focus(store->user_data, serial); -} - - -static struct wl_keyboard_listener vwl_fs_keyboard_listener = { - .enter = clip_wl_fs_keyboard_listener_enter, - .key = clip_wl_fs_keyboard_listener_key, - .keymap = clip_wl_fs_keyboard_listener_keymap, - .leave = clip_wl_fs_keyboard_listener_leave, - .modifiers = clip_wl_fs_keyboard_listener_modifiers, - .repeat_info = clip_wl_fs_keyboard_listener_repeat_info -}; - -/* - * Create an invisible surface in order to gain focus and call on_focus() with - * serial that was given. - */ - static int -clip_wl_init_fs_surface( - vwl_seat_T *seat, - clip_wl_buffer_store_T *buffer_store, - void (*on_focus)(void *, uint32_t), - void *user_data) -{ - clip_wl_fs_surface_T *store; -# ifdef ELAPSED_FUNC - elapsed_T start_tv; -# endif - - if (wayland_ct->gobjects.wl_compositor == NULL - || wayland_ct->gobjects.xdg_wm_base == NULL - || buffer_store == NULL - || seat == NULL) - return FAIL; - - store = ALLOC_CLEAR_ONE(clip_wl_fs_surface_T); - - if (store == NULL) - return FAIL; - - // Get keyboard - store->keyboard = vwl_seat_get_keyboard(seat); - - if (store->keyboard == NULL) - goto fail; - - wl_keyboard_add_listener(store->keyboard, &vwl_fs_keyboard_listener, store); - - if (vwl_connection_dispatch(wayland_ct) < 0) - goto fail; - - store->surface = wl_compositor_create_surface( - wayland_ct->gobjects.wl_compositor); - store->shell.surface = xdg_wm_base_get_xdg_surface( - wayland_ct->gobjects.xdg_wm_base, store->surface); - store->shell.toplevel = xdg_surface_get_toplevel(store->shell.surface); - - xdg_toplevel_set_title(store->shell.toplevel, "Vim clipboard"); - - xdg_surface_add_listener(store->shell.surface, - &xdg_surface_listener, NULL); - - wl_surface_commit(store->surface); - - store->on_focus = on_focus; - store->user_data = user_data; - store->got_focus = FALSE; - - if (vwl_connection_roundtrip(wayland_ct) == FAIL) - goto fail; - - // We may get the enter event early, if we do then we will set `got_focus` - // to TRUE. - if (store->got_focus) - goto early_exit; - - // Buffer hasn't been released yet, abort. This shouldn't happen but still - // check for it. - if (!buffer_store->available) - goto fail; - - buffer_store->available = false; - - wl_surface_attach(store->surface, buffer_store->buffer, 0, 0); - wl_surface_damage(store->surface, 0, 0, - buffer_store->width, buffer_store->height); - wl_surface_commit(store->surface); - - // Dispatch events until we receive the enter event. Add a max delay of - // 'p_wtm' when waiting for it (may be longer depending on how long we poll - // when dispatching events) -# ifdef ELAPSED_FUNC - ELAPSED_INIT(start_tv); -# endif - - while (vwl_connection_dispatch(wayland_ct) >= 0) - { - if (store->got_focus) - break; - -# ifdef ELAPSED_FUNC - if (ELAPSED_FUNC(start_tv) >= p_wtm) - goto fail; -# endif - } -early_exit: - clip_wl_destroy_fs_surface(store); - vwl_connection_flush(wayland_ct); - - return OK; -fail: - clip_wl_destroy_fs_surface(store); - vwl_connection_flush(wayland_ct); - - return FAIL; -} - -# endif // FEAT_WAYLAND_CLIPBOARD_FS - static bool wl_data_offer_listener_event_offer( void *data UNUSED, @@ -2815,23 +2491,6 @@ clip_init_wayland(void) clip_wl.primary.device = clip_wl.regular.device; } -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - if (clip_wl.regular.available - && clip_wl.regular.manager->protocol == VWL_DATA_PROTOCOL_CORE - && clip_wl_focus_stealing_available()) - clip_wl.regular.requires_focus = true; - if (clip_wl.primary.available - && clip_wl.primary.manager->protocol == VWL_DATA_PROTOCOL_PRIMARY - && clip_wl_focus_stealing_available()) - clip_wl.primary.requires_focus = true; - - if (clip_wl.regular.requires_focus || clip_wl.primary.requires_focus) - { - // Initialize buffer to use for focus stealing - clip_wl.fs_buffer = clip_wl_init_buffer_store(1, 1); - } -# endif - if (!clip_wl.regular.available && !clip_wl.primary.available) return FAIL; @@ -2861,10 +2520,6 @@ clip_uninit_wayland(void) clip_lose_selection(&clip_plus); } -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - clip_wl_destroy_buffer_store(clip_wl.fs_buffer); -# endif - // Don't want to double free if (clip_wl.regular.manager != clip_wl.primary.manager) vwl_data_device_manager_discard(clip_wl.primary.manager); @@ -3036,23 +2691,10 @@ clip_wl_request_selection(Clipboard_T *cbd) if (!sel->available) goto clear; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - if (sel->requires_focus) - { - // We don't care about the on_focus callback since once we gain - // focus the data offer events will come immediately. - if (clip_wl_init_fs_surface(clip_wl.seat, - clip_wl.fs_buffer, NULL, NULL) == FAIL) - goto clear; - } - else -# endif - { - // Dispatch any events that still queued up before checking for a data - // offer. - if (vwl_connection_roundtrip(wayland_ct) == FAIL) - goto clear; - } + // Dispatch any events that still queued up before checking for a data + // offer. + if (vwl_connection_roundtrip(wayland_ct) == FAIL) + goto clear; if (sel->offer == NULL) goto clear; @@ -3253,16 +2895,7 @@ clip_wl_own_selection(Clipboard_T *cbd) vwl_data_source_offer(sel->source, supported_mimes[i]); sel->own_success = false; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - if (sel->requires_focus) - { - if (clip_wl_init_fs_surface(clip_wl.seat, clip_wl.fs_buffer, - clip_wl_do_set_selection, sel) == FAIL) - goto fail; - } - else -# endif - clip_wl_do_set_selection(sel, 0); + clip_wl_do_set_selection(sel, 0); if (!sel->own_success) goto fail; @@ -3670,7 +3303,7 @@ did_set_clipboard(optset_T *args UNUSED) vim_regfree(clip_exclude_prog); clip_exclude_prog = new_exclude_prog; # endif -# ifdef FEAT_GUI_GTK +# if defined(FEAT_GUI_GTK) && !defined(USE_GTK4) if (gui.in_use) { gui_gtk_set_selection_targets((GdkAtom)GDK_SELECTION_PRIMARY); @@ -3800,6 +3433,7 @@ clip_provider_get_callback( static void clip_provider_copy(char_u *reg, char_u *provider) { + static bool recursive = false; callback_T callback; typval_T rettv; typval_T argvars[4]; @@ -3807,6 +3441,9 @@ clip_provider_copy(char_u *reg, char_u *provider) char_u type[2 + NUMBUFLEN] = {0}; list_T *list = NULL; + if (recursive) + return; + if (clip_provider_get_callback( reg, provider, @@ -3869,7 +3506,9 @@ clip_provider_copy(char_u *reg, char_u *provider) argvars[3].v_type = VAR_UNKNOWN; textlock++; + recursive = true; call_callback(&callback, -1, &rettv, 3, argvars); + recursive = false; clear_tv(&rettv); textlock--; @@ -3880,6 +3519,7 @@ clip_provider_copy(char_u *reg, char_u *provider) static void clip_provider_paste(char_u *reg, char_u *provider) { + static bool recursive = false; callback_T callback; typval_T argvars[2]; typval_T rettv; @@ -3887,6 +3527,9 @@ clip_provider_paste(char_u *reg, char_u *provider) char_u *reg_type; list_T *lines; + if (recursive) + return; + if (clip_provider_get_callback( reg, provider, @@ -3900,7 +3543,9 @@ clip_provider_paste(char_u *reg, char_u *provider) argvars[1].v_type = VAR_UNKNOWN; textlock++; + recursive = true; ret = call_callback(&callback, -1, &rettv, 1, argvars); + recursive = false; textlock--; if (ret == FAIL) @@ -3971,7 +3616,7 @@ clip_provider_paste(char_u *reg, char_u *provider) } *curval++ = NULL; - if (*reg_type != NUL && (STRLEN(reg_type) <= 0 + if (*reg_type != NUL && (STRLEN(reg_type) == 0 || get_yank_type(®_type, &yank_type, &block_len) == FAIL)) { emsg(e_invalid_argument); diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 0916421f46..dabc4374e9 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -36,7 +36,7 @@ static int compl_match_arraysize; static int compl_startcol; static int compl_selected; // cmdline before expansion -static char_u *cmdline_orig = NULL; +static string_T cmdline_orig = {NULL, 0}; #define SHOW_MATCH(m) (showtail ? showmatches_gettail(matches[m]) : matches[m]) @@ -338,11 +338,15 @@ nextwild( // Save cmdline before inserting selected item if (!wild_navigate && ccline->cmdbuff != NULL) { - vim_free(cmdline_orig); - cmdline_orig = vim_strnsave(ccline->cmdbuff, ccline->cmdlen); + vim_free(cmdline_orig.string); + cmdline_orig.string = vim_strnsave(ccline->cmdbuff, ccline->cmdlen); + if (cmdline_orig.string == NULL) + cmdline_orig.length = 0; + else + cmdline_orig.length = ccline->cmdlen; } - if (p != NULL && !got_int && !(options & WILD_NOSELECT)) + if (p != NULL && !got_int && !(options & (WILD_NOSELECT | WILD_NOINSERT))) { size_t plen = STRLEN(p); int difflen; @@ -376,7 +380,8 @@ nextwild( if (xp->xp_numfiles <= 0 && p == NULL) beep_flush(); - else if (xp->xp_numfiles == 1 && !(options & WILD_NOSELECT) + else if (xp->xp_numfiles == 1 + && !(options & (WILD_NOSELECT | WILD_NOINSERT)) && !wild_navigate) // free expanded pattern (void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE); @@ -407,10 +412,16 @@ cmdline_pum_create( compl_match_arraysize = numMatches; for (int i = 0; i < numMatches; i++) { - compl_match_array[i].pum_text = SHOW_MATCH(i); - compl_match_array[i].pum_info = NULL; - compl_match_array[i].pum_extra = NULL; - compl_match_array[i].pum_kind = NULL; + compl_match_array[i].pum_text = (xp->xp_files_abbr != NULL + && xp->xp_files_abbr[i] != NULL) + ? xp->xp_files_abbr[i] + : SHOW_MATCH(i); + compl_match_array[i].pum_info = xp->xp_files_info != NULL + ? xp->xp_files_info[i] : NULL; + compl_match_array[i].pum_extra = xp->xp_files_menu != NULL + ? xp->xp_files_menu[i] : NULL; + compl_match_array[i].pum_kind = xp->xp_files_kind != NULL + ? xp->xp_files_kind[i] : NULL; compl_match_array[i].pum_user_abbr_hlattr = -1; compl_match_array[i].pum_user_kind_hlattr = -1; } @@ -432,6 +443,8 @@ cmdline_pum_create( void cmdline_pum_display(void) { + if (p_po > 0 && p_po < 100 && !pum_redraw_in_same_position()) + pum_call_update_screen(); pum_display(compl_match_array, compl_match_arraysize, compl_selected); } @@ -458,6 +471,7 @@ cmdline_pum_remove(cmdline_info_T *cclp UNUSED, int defer_redraw) RedrawingDisabled = 0; #endif + term_set_sync_output(TERM_SYNC_OUTPUT_ENABLE); pum_undisplay(); VIM_CLEAR(compl_match_array); compl_match_arraysize = 0; @@ -471,6 +485,7 @@ cmdline_pum_remove(cmdline_info_T *cclp UNUSED, int defer_redraw) else pum_call_update_screen(); redrawcmd(); + term_set_sync_output(TERM_SYNC_OUTPUT_DISABLE); // When a function is called (e.g. for 'foldtext') KeyTyped might be reset // as a side effect. @@ -1012,6 +1027,31 @@ find_longest_match(expand_T *xp, int options) return ss; } + void +free_xp_files_extra(expand_T *xp, int numfiles) +{ + if (xp->xp_files_abbr != NULL) + { + FreeWild(numfiles, xp->xp_files_abbr); + xp->xp_files_abbr = NULL; + } + if (xp->xp_files_kind != NULL) + { + FreeWild(numfiles, xp->xp_files_kind); + xp->xp_files_kind = NULL; + } + if (xp->xp_files_menu != NULL) + { + FreeWild(numfiles, xp->xp_files_menu); + xp->xp_files_menu = NULL; + } + if (xp->xp_files_info != NULL) + { + FreeWild(numfiles, xp->xp_files_info); + xp->xp_files_info = NULL; + } +} + /* * Do wildcard expansion on the string "str". * Chars that should not be expanded must be preceded with a backslash. @@ -1078,6 +1118,7 @@ ExpandOne( if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) { FreeWild(xp->xp_numfiles, xp->xp_files); + free_xp_files_extra(xp, xp->xp_numfiles); xp->xp_numfiles = -1; VIM_CLEAR(xp->xp_orig); @@ -1179,6 +1220,7 @@ ExpandCleanup(expand_T *xp) { if (xp->xp_numfiles >= 0) { + free_xp_files_extra(xp, xp->xp_numfiles); FreeWild(xp->xp_numfiles, xp->xp_files); xp->xp_numfiles = -1; } @@ -1188,7 +1230,7 @@ ExpandCleanup(expand_T *xp) void clear_cmdline_orig(void) { - VIM_CLEAR(cmdline_orig); + VIM_CLEAR_STRING(cmdline_orig); } /* @@ -1247,7 +1289,7 @@ showmatches_oneline( // Expansion was done before and special characters // were escaped, need to halve backslashes. Also // $HOME has been replaced with ~/. - exp_path = expand_env_save_opt(matches[j], TRUE); + exp_path = expand_env_save_opt(matches[j], TRUE, NULL); path = exp_path != NULL ? exp_path : matches[j]; halved_slash = backslash_halve_save(path); isdir = mch_isdir(halved_slash != NULL ? halved_slash @@ -1289,7 +1331,11 @@ showmatches_oneline( * inserted as a normal character. */ int -showmatches(expand_T *xp, int display_wildmenu, int display_list, int noselect) +showmatches( + expand_T *xp, + int display_wildmenu, + int display_list, + int wim_flags_arg) { cmdline_info_T *ccline = get_cmdline_info(); int numMatches; @@ -1300,6 +1346,9 @@ showmatches(expand_T *xp, int display_wildmenu, int display_list, int noselect) int columns; int attr; int showtail; + int noselect = (wim_flags_arg & WIM_NOSELECT); + int noinsert = (wim_flags_arg & WIM_NOINSERT); + int cmdline_unchanged = noselect || noinsert; if (xp->xp_numfiles == -1) { @@ -1322,7 +1371,7 @@ showmatches(expand_T *xp, int display_wildmenu, int display_list, int noselect) && vim_strchr(p_wop, WOP_PUM) != NULL) { int retval = cmdline_pum_create(ccline, xp, matches, numMatches, - showtail && !noselect); + showtail && !cmdline_unchanged); if (retval == EXPAND_OK) { compl_selected = noselect ? -1 : 0; @@ -1408,7 +1457,10 @@ showmatches(expand_T *xp, int display_wildmenu, int display_list, int noselect) } if (xp->xp_numfiles == -1) + { FreeWild(numMatches, matches); + free_xp_files_extra(xp, numMatches); + } return EXPAND_OK; } @@ -1707,11 +1759,12 @@ set_cmd_index(char_u *cmd, exarg_T *eap, expand_T *xp, int *complp) // Isolate the command and search for it in the command table. // Exceptions: // - the 'k' command can directly be followed by any character, but do - // accept "keepmarks", "keepalt" and "keepjumps". As fuzzy matching can - // find matches anywhere in the command name, do this only for command - // expansion based on regular expression and not for fuzzy matching. + // accept "keepmarks", "keepalt" and "keepjumps". Bypass also when + // 'ignorecase' is set so a lowercase ":kz" still completes a user + // command like :Kz (#20241), and for fuzzy matching as that can find + // matches anywhere in the command name. // - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r' - if (!fuzzy && (*cmd == 'k' && cmd[1] != 'e')) + if (!fuzzy && !p_ic && (*cmd == 'k' && cmd[1] != 'e')) { eap->cmdidx = CMD_k; p = cmd + 1; @@ -1826,9 +1879,7 @@ set_context_for_wildcard_arg( // An argument can contain just about everything, except // characters that end the command and white space. else if (c == '|' || c == '\n' || c == '"' || (VIM_ISWHITE(c) -#ifdef SPACE_IN_FILENAME && (!(eap != NULL && (eap->argt & EX_NOSPC)) || usefilter) -#endif )) { len = 0; // avoid getting stuck when space is in 'isfname' @@ -3115,7 +3166,7 @@ expand_files_and_dirs( if (xp->xp_context == EXPAND_FINDFUNC) { #ifdef FEAT_EVAL - ret = expand_findfunc(pat, matches, numMatches); + ret = expand_findfunc(xp, pat, matches, numMatches); #endif } else @@ -4110,6 +4161,110 @@ ExpandUserDefined( return OK; } + void +expand_process_user_list( + list_T *retlist, + char_u ***matches, + int *numMatches, + expand_T *xp) +{ + listitem_T *li; + garray_T ga; + garray_T ga_abbr; + garray_T ga_kind; + garray_T ga_menu; + garray_T ga_info; + int have_extra = FALSE; + int i; + + ga_init2(&ga, sizeof(char *), 3); + ga_init2(&ga_abbr, sizeof(char *), 3); + ga_init2(&ga_kind, sizeof(char *), 3); + ga_init2(&ga_menu, sizeof(char *), 3); + ga_init2(&ga_info, sizeof(char *), 3); + // Loop over the items in the list. + FOR_ALL_LIST_ITEMS(retlist, li) + { + typval_T *tv = &li->li_tv; + char_u *p = NULL; + char_u *abbr = NULL; + char_u *kind = NULL; + char_u *menu = NULL; + char_u *info = NULL; + + if (tv->v_type == VAR_STRING) + { + if (tv->vval.v_string == NULL) + continue; // Skip NULL strings + p = vim_strsave(tv->vval.v_string); + } + else if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) + { + dict_T *d = tv->vval.v_dict; + char_u *word = dict_get_string(d, "word", FALSE); + + if (word == NULL) + continue; // "word" is required + p = vim_strsave(word); + abbr = dict_get_string(d, "abbr", TRUE); + kind = dict_get_string(d, "kind", TRUE); + menu = dict_get_string(d, "menu", TRUE); + info = dict_get_string(d, "info", TRUE); + if (abbr != NULL || kind != NULL || menu != NULL || info != NULL) + have_extra = TRUE; + } + else + continue; // Skip other types + + if (p == NULL + || ga_grow(&ga, 1) == FAIL + || ga_grow(&ga_abbr, 1) == FAIL + || ga_grow(&ga_kind, 1) == FAIL + || ga_grow(&ga_menu, 1) == FAIL + || ga_grow(&ga_info, 1) == FAIL) + { + vim_free(p); + vim_free(abbr); + vim_free(kind); + vim_free(menu); + vim_free(info); + break; + } + + ((char_u **)ga.ga_data)[ga.ga_len++] = p; + ((char_u **)ga_abbr.ga_data)[ga_abbr.ga_len++] = abbr; + ((char_u **)ga_kind.ga_data)[ga_kind.ga_len++] = kind; + ((char_u **)ga_menu.ga_data)[ga_menu.ga_len++] = menu; + ((char_u **)ga_info.ga_data)[ga_info.ga_len++] = info; + } + + *matches = ga.ga_data; + *numMatches = ga.ga_len; + if (have_extra && ga.ga_len > 0) + { + xp->xp_files_abbr = (char_u **)ga_abbr.ga_data; + xp->xp_files_kind = (char_u **)ga_kind.ga_data; + xp->xp_files_menu = (char_u **)ga_menu.ga_data; + xp->xp_files_info = (char_u **)ga_info.ga_data; + } + else + { + // No extra info collected; free the placeholder NULL entries. + for (i = 0; i < ga_abbr.ga_len; i++) + vim_free(((char_u **)ga_abbr.ga_data)[i]); + vim_free(ga_abbr.ga_data); + for (i = 0; i < ga_kind.ga_len; i++) + vim_free(((char_u **)ga_kind.ga_data)[i]); + vim_free(ga_kind.ga_data); + for (i = 0; i < ga_menu.ga_len; i++) + vim_free(((char_u **)ga_menu.ga_data)[i]); + vim_free(ga_menu.ga_data); + for (i = 0; i < ga_info.ga_len; i++) + vim_free(((char_u **)ga_info.ga_data)[i]); + vim_free(ga_info.ga_data); + } +} + /* * Expand names with a list returned by a function defined by the user. */ @@ -4120,8 +4275,6 @@ ExpandUserList( int *numMatches) { list_T *retlist; - listitem_T *li; - garray_T ga; *matches = NULL; *numMatches = 0; @@ -4129,32 +4282,8 @@ ExpandUserList( if (retlist == NULL) return FAIL; - ga_init2(&ga, sizeof(char *), 3); - // Loop over the items in the list. - FOR_ALL_LIST_ITEMS(retlist, li) - { - char_u *p; - - if (li->li_tv.v_type != VAR_STRING || li->li_tv.vval.v_string == NULL) - continue; // Skip non-string items and empty strings - - p = vim_strsave(li->li_tv.vval.v_string); - if (p == NULL) - break; - - if (ga_grow(&ga, 1) == FAIL) - { - vim_free(p); - break; - } - - ((char_u **)ga.ga_data)[ga.ga_len] = p; - ++ga.ga_len; - } + expand_process_user_list(retlist, matches, numMatches, xp); list_unref(retlist); - - *matches = ga.ga_data; - *numMatches = ga.ga_len; return OK; } #endif @@ -4727,7 +4856,8 @@ f_cmdcomplete_info(typval_T *argvars UNUSED, typval_T *rettv) || ccline->xpc == NULL || ccline->xpc->xp_files == NULL) return; retdict = rettv->vval.v_dict; - ret = dict_add_string(retdict, "cmdline_orig", cmdline_orig); + ret = dict_add_string_len(retdict, "cmdline_orig", + cmdline_orig.string, (int)cmdline_orig.length); if (ret == OK) ret = dict_add_number(retdict, "pum_visible", pum_visible()); if (ret == OK) @@ -4776,7 +4906,7 @@ copy_substring_from_pos(pos_T *start, pos_T *end, char_u **match, segment_len = is_single_line ? (end->col - start->col) : (int)(ml_get_len(start->lnum) - start->col); if (ga_grow(&ga, segment_len + 2) != OK) - return FAIL; + goto fail; ga_concat_len(&ga, start_ptr, segment_len); if (!is_single_line) @@ -4797,7 +4927,7 @@ copy_substring_from_pos(pos_T *start, pos_T *end, char_u **match, line = ml_get(lnum); linelen = (int)ml_get_len(lnum); if (ga_grow(&ga, linelen + 2) != OK) - return FAIL; + goto fail; ga_concat_len(&ga, line, linelen); if (exacttext) GA_CONCAT_LITERAL(&ga, "\\n"); @@ -4811,13 +4941,13 @@ copy_substring_from_pos(pos_T *start, pos_T *end, char_u **match, word_end = find_word_end(end_line + end->col); segment_len = (int)(word_end - end_line); if (ga_grow(&ga, segment_len) != OK) - return FAIL; + goto fail; ga_concat_len(&ga, end_line + (is_single_line ? end->col : 0), segment_len - (is_single_line ? end->col : 0)); // Null-terminate if (ga_grow(&ga, 1) != OK) - return FAIL; + goto fail; ga_append(&ga, NUL); *match = (char_u *)ga.ga_data; @@ -4825,6 +4955,10 @@ copy_substring_from_pos(pos_T *start, pos_T *end, char_u **match, match_end->col = segment_len; return OK; + +fail: + ga_clear(&ga); + return FAIL; } /* @@ -5020,8 +5154,8 @@ expand_pattern_in_buf( } // Extract the matching text prepended to completed word - if (!copy_substring_from_pos(&cur_match_pos, &end_match_pos, &full_match, - &word_end_pos)) + if (copy_substring_from_pos(&cur_match_pos, &end_match_pos, &full_match, + &word_end_pos) == FAIL) break; if (exacttext) @@ -5062,7 +5196,10 @@ expand_pattern_in_buf( if (match != NULL) { if (ga_grow(&ga, 1) == FAIL) + { + VIM_CLEAR(match); goto cleanup; + } ((char_u **)ga.ga_data)[ga.ga_len++] = match; if (ga.ga_len > TAG_MANY) break; diff --git a/src/config.h.in b/src/config.h.in index f15d8800cd..e4273f5b7c 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -12,9 +12,6 @@ /* Define unless no Wayland support found */ #undef HAVE_WAYLAND -/* Define if you want focus stealing support with Wayland clipboard */ -#undef FEAT_WAYLAND_CLIPBOARD_FS - /* Define when terminfo support found */ #undef TERMINFO @@ -499,6 +496,9 @@ /* Define if GTK+ GUI is to be linked against GTK+ 3 */ #undef USE_GTK3 +/* Define if GTK GUI is to be linked against GTK 4 */ +#undef USE_GTK4 + /* Define if we have isinf() */ #undef HAVE_ISINF diff --git a/src/configure.ac b/src/configure.ac index 5c49888c57..664bf6b1e3 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -413,7 +413,7 @@ if test "$vim_cv_uname_output" = Darwin; then dnl Assume we don't want X11 unless it was specifically asked for dnl (--with-x) or Motif or GTK GUI is used. - if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then + if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3 -a "X$enable_gui" != Xgtk4; then with_x=no fi fi @@ -2541,22 +2541,6 @@ if test "$enable_autoservername" = "yes"; then AC_DEFINE(FEAT_AUTOSERVERNAME) fi -AC_MSG_CHECKING(--enable-socketserver argument) -AC_ARG_ENABLE(socketserver, - [ --enable-socketserver Use sockets for clientserver communication.], - [enable_socketserver=$enableval], - AS_IF([test "x$features" = xtiny], - [enable_socketserver=no_msg - AC_MSG_RESULT([cannot use socketserver with tiny features])], - [enable_socketserver=yes])) - -if test "$enable_socketserver" = "yes"; then - AC_DEFINE(WANT_SOCKETSERVER) - AC_MSG_RESULT([yes]) -elif test "$enable_socketserver" = "no"; then - AC_MSG_RESULT([no]) -fi - AC_MSG_CHECKING(--enable-multibyte argument) AC_ARG_ENABLE(multibyte, [ --enable-multibyte Include multibyte editing support.], , @@ -2639,18 +2623,6 @@ if test "$with_wayland" = yes; then if "$PKG_CONFIG" --exists 'wayland-client'; then AC_MSG_RESULT([yes]) - AC_MSG_CHECKING(--enable-wayland-focus-steal argument) - AC_ARG_ENABLE(wayland-focus-steal, - [AS_HELP_STRING([--enable-wayland-focus-steal], - [Include focus stealing support for Wayland clipboard.])], - [enable_wayland_fs=$enableval], - enable_wayland_fs="yes") - - AS_IF([test "$enable_wayland_fs" = "yes"], - [AC_MSG_RESULT([yes]) - AC_DEFINE(FEAT_WAYLAND_CLIPBOARD_FS)], - [AC_MSG_RESULT([no])]) - AC_DEFINE(HAVE_WAYLAND) WAYLAND_CPPFLAGS=`$PKG_CONFIG --cflags-only-I wayland-client` WAYLAND_CFLAGS=`$PKG_CONFIG --cflags-only-other wayland-client` @@ -2666,14 +2638,6 @@ if test "$with_wayland" = yes; then objects/ext-data-control-v1.o \ objects/wayland.o" - AS_IF([test "$enable_wayland_fs" = "yes"], - [AS_VAR_APPEND([WAYLAND_SRC], " \ - auto/wayland/xdg-shell.c \ - auto/wayland/primary-selection-unstable-v1.c") - AS_VAR_APPEND([WAYLAND_OBJ], " \ - objects/xdg-shell.o \ - objects/primary-selection-unstable-v1.o")]) - AC_SUBST(WAYLAND_CPPFLAGS) AC_SUBST(WAYLAND_CFLAGS) AC_SUBST(WAYLAND_LIBS) @@ -2687,8 +2651,15 @@ CPPFLAGS=$cppflags_save CFLAGS=$cflags_save fi +dnl GTK4 does not use X11 APIs directly, so skip X11 detection entirely. +dnl This avoids pulling libICE/libSM/libX11/libXt into build dependencies +dnl for GTK4-only builds, even when --with-x=yes is passed (e.g. by a +dnl distro's default packaging script). +if test "x$enable_gui" = "xgtk4"; then + with_x=no +fi test -z "$with_x" && with_x=yes -test "${enable_gui-yes}" != no -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" && with_x=yes +test "${enable_gui-yes}" != no -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" -a "x$enable_gui" != "xgtk4" && with_x=yes if test "$with_x" = no; then AC_MSG_RESULT(defaulting to: don't HAVE_X11) else @@ -2803,15 +2774,16 @@ else fi dnl Check if --with-x was given but it doesn't work. -if test "x$with_x" = xno -a "x$with_x_arg" = xyes; then +dnl GTK4 always forces with_x=no above, so don't treat that as a failure. +if test "x$with_x" = xno -a "x$with_x_arg" = xyes -a "x$enable_gui" != "xgtk4"; then AC_MSG_ERROR([could not configure X]) fi -test "x$with_x" = xno -a "x$HAIKU" != "xyes" -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" && enable_gui=no +test "x$with_x" = xno -a "x$HAIKU" != "xyes" -a "x$MACOS_X" != "xyes" -a "x$QNX" != "xyes" -a "x$enable_gui" != xgtk4 && enable_gui=no AC_MSG_CHECKING(--enable-gui argument) AC_ARG_ENABLE(gui, - [ --enable-gui[=OPTS] X11 GUI. [default=auto] [OPTS=auto/no/gtk2/gnome2/gtk3/motif/haiku/photon/carbon/macvim]], , enable_gui="auto") + [ --enable-gui[=OPTS] X11 GUI. [default=auto] [OPTS=auto/no/gtk2/gnome2/gtk3/gtk4/motif/haiku/photon/carbon/macvim]], , enable_gui="auto") dnl Canonicalize the --enable-gui= argument so that it can be easily compared. dnl Do not use character classes for portability with old tools. @@ -2821,6 +2793,7 @@ enable_gui_canon=`echo "_$enable_gui" | \ dnl Skip everything by default. SKIP_GTK2=YES SKIP_GTK3=YES +SKIP_GTK4=YES SKIP_GNOME=YES SKIP_MOTIF=YES SKIP_PHOTON=YES @@ -2845,7 +2818,7 @@ elif test "x$QNX" = "xyes" -a "x$with_x" = "xno" ; then no) AC_MSG_RESULT(no GUI support) SKIP_PHOTON=YES ;; yes|""|auto) AC_MSG_RESULT(automatic GUI support) - gui_auto=yes ;; + gui_auto=yes ;; photon) AC_MSG_RESULT(Photon GUI support) ;; *) AC_MSG_RESULT([Sorry, $enable_gui GUI is not supported]) SKIP_PHOTON=YES ;; @@ -2857,7 +2830,7 @@ elif test "x$MACOS_X" = "xyes" -a "x$with_x" = "xno" ; then no) AC_MSG_RESULT(no GUI support) SKIP_MACVIM=YES ;; yes|""|auto) AC_MSG_RESULT(automatic GUI support) - gui_auto=yes ;; + gui_auto=yes ;; macvim) AC_MSG_RESULT(MacVim GUI support) ;; *) AC_MSG_RESULT([Sorry, $enable_gui GUI is not supported]) SKIP_MACVIM=YES ;; @@ -2870,6 +2843,7 @@ else gui_auto=yes SKIP_GTK2= SKIP_GTK3= + SKIP_GTK4= SKIP_GNOME= SKIP_MACVIM= SKIP_MOTIF=;; @@ -2880,6 +2854,8 @@ else SKIP_GTK2=;; gtk3) AC_MSG_RESULT(GTK+ 3.x GUI support) SKIP_GTK3=;; + gtk4) AC_MSG_RESULT(GTK 4.x GUI support) + SKIP_GTK4=;; motif) AC_MSG_RESULT(Motif GUI support) SKIP_MOTIF=;; *) AC_MSG_RESULT([Sorry, $enable_gui GUI is not supported]) ;; @@ -2911,6 +2887,17 @@ if test "x$SKIP_GNOME" != "xYES" -a "$enable_gui_canon" != "gnome2"; then fi fi +if test "x$SKIP_GTK4" != "xYES" -a "$enable_gui_canon" != "gtk4"; then + AC_MSG_CHECKING(whether or not to look for GTK 4) + AC_ARG_ENABLE(gtk4-check, + [ --enable-gtk4-check If auto-select GUI, check for GTK 4 [default=yes]], + , enable_gtk4_check="yes") + AC_MSG_RESULT($enable_gtk4_check) + if test "x$enable_gtk4_check" = "xno"; then + SKIP_GTK4=YES + fi +fi + if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then AC_MSG_CHECKING(whether or not to look for GTK+ 3) AC_ARG_ENABLE(gtk3-check, @@ -3000,6 +2987,7 @@ AC_DEFUN(AM_PATH_GTK, AS_CASE([$min_gtk_version], [2.*], [gtk_pkg_name="gtk+-2.0"], [3.*], [gtk_pkg_name="gtk+-3.0"], + [4.*], [gtk_pkg_name="gtk4"], [AC_MSG_FAILURE([The configure script does not know which pkg-config name to use for GTK $min_gtk_version"])]) AC_MSG_CHECKING([for pkg-config $gtk_pkg_name]) @@ -3007,9 +2995,9 @@ AC_DEFUN(AM_PATH_GTK, [ AC_MSG_RESULT(found) AC_MSG_CHECKING([for GTK - version >= $min_gtk_version]) - dnl We should be using PKG_CHECK_MODULES() instead of this hack. - dnl But I guess the dependency on pkgconfig.m4 is not wanted or - dnl something like that. +dnl We should be using PKG_CHECK_MODULES() instead of this hack. +dnl But I guess the dependency on pkgconfig.m4 is not wanted or +dnl something like that. GTK_CPPFLAGS=`$PKG_CONFIG --cflags-only-I $gtk_pkg_name` GTK_CFLAGS=`$PKG_CONFIG --cflags-only-other $gtk_pkg_name` GTK_LIBDIR=`$PKG_CONFIG --libs-only-L $gtk_pkg_name` @@ -3188,7 +3176,7 @@ AC_DEFUN([GNOME_INIT],[ ]) dnl --------------------------------------------------------------------------- -dnl Check for GTK3. If it succeeds, skip the check for GTK2. +dnl Check for GTK3. If it succeeds, skip the check for GTK2/GTK4 dnl --------------------------------------------------------------------------- if test -z "$SKIP_GTK3"; then AC_MSG_CHECKING(--disable-gtktest argument) @@ -3207,6 +3195,7 @@ if test -z "$SKIP_GTK3"; then GUI_INC_LOC="$GTK_CPPFLAGS"]) if test -n "$GTK_CPPFLAGS"; then SKIP_GTK2=YES + SKIP_GTK4=YES SKIP_GNOME=YES SKIP_MOTIF=YES GUITYPE=GTK @@ -3216,6 +3205,47 @@ if test -z "$SKIP_GTK3"; then fi fi +dnl --------------------------------------------------------------------------- +dnl Check for GTK4. If it succeeds, skip the check for GTK3/GTK2. +dnl --------------------------------------------------------------------------- +if test -z "$SKIP_GTK4"; then + AC_MSG_CHECKING(--disable-gtktest argument) + AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and run a test GTK program], + , enable_gtktest=yes) + if test "x$enable_gtktest" = "xyes" ; then + AC_MSG_RESULT(gtk test enabled) + else + AC_MSG_RESULT(gtk test disabled) + fi + + if test "x$PKG_CONFIG" != "xno"; then + AM_PATH_GTK(4.10.0, + [GUI_LIB_LOC="$GTK_LIBDIR" + GTK_LIBNAME="$GTK_LIBS" + GUI_INC_LOC="$GTK_CPPFLAGS"]) + if test -n "$GTK_CPPFLAGS"; then + SKIP_GTK3=YES + SKIP_GTK2=YES + SKIP_GNOME=YES + SKIP_MOTIF=YES + GUITYPE=GTK4 + AC_SUBST(GTK_LIBNAME) + AC_DEFINE(USE_GTK4) + dnl GTK4 does not use any X11 APIs directly. + dnl GTK4 itself links against X11 for its backend, so the + dnl dynamic linker resolves X11 symbols via GTK4's dependency. + X_LIBS= + X_PRE_LIBS= + X_EXTRA_LIBS= + X_LIB= + dnl automatically enable XIM for GTK4 + if test "$enable_xim" = "auto"; then + enable_xim="yes" + fi + fi + fi +fi + dnl --------------------------------------------------------------------------- dnl Check for GTK2. If it fails, then continue on for Motif as before... dnl --------------------------------------------------------------------------- @@ -3470,8 +3500,9 @@ EOF fi dnl Look for XSMP support - but don't necessarily restrict it to X11 GUIs -dnl use the X11 include path -if test "$enable_xsmp" = "yes"; then +dnl use the X11 include path. Skip when X11 is not in use; USE_XSMP itself +dnl requires HAVE_X11, so the header check would be wasted otherwise. +if test "$enable_xsmp" = "yes" -a "x$with_x" != "xno"; then cppflags_save=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" AC_CHECK_HEADERS(X11/SM/SMlib.h) diff --git a/src/diff.c b/src/diff.c index 9ac64d7f6a..a29c434110 100644 --- a/src/diff.c +++ b/src/diff.c @@ -820,7 +820,7 @@ diff_write_buffer(buf_T *buf, diffin_T *din, linenr_T start, linenr_T end) // Allocating memory failed. This can happen, because we try to read // the whole buffer text into memory. Set the failed flag, the diff // will be retried with external diff. The flag is never reset. - buf->b_diff_failed = TRUE; + buf->b_diff_failed = true; if (p_verbose > 0) { verbose_enter(); @@ -2747,11 +2747,11 @@ diff_set_topline(win_T *fromwin, win_T *towin) } // safety check (if diff info gets outdated strange things may happen) - towin->w_botfill = FALSE; + towin->w_botfill = false; if (towin->w_topline > towin->w_buffer->b_ml.ml_line_count) { towin->w_topline = towin->w_buffer->b_ml.ml_line_count; - towin->w_botfill = TRUE; + towin->w_botfill = true; } if (towin->w_topline < 1) { diff --git a/src/drawline.c b/src/drawline.c index c415d0a131..c6eb697c0a 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -1464,12 +1464,11 @@ win_line( { area_highlighting = TRUE; vi_attr = HL_ATTR(HLF_V); -#if defined(FEAT_CLIPBOARD) && defined(FEAT_X11) - if (X_DISPLAY && - ((clip_star.available && !clip_star.owned +#if defined(FEAT_CLIPBOARD) && (defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD)) + if ((clip_star.available && !clip_star.owned && clip_isautosel_star()) - || (clip_plus.available && !clip_plus.owned - && clip_isautosel_plus()))) + || (clip_plus.available && !clip_plus.owned + && clip_isautosel_plus())) vi_attr = HL_ATTR(HLF_VNC); #endif } @@ -2053,12 +2052,19 @@ win_line( wlv.draw_state = WL_CMDLINE; if (wp == cmdwin_win) { - // Draw the cmdline character. wlv.n_extra = 1; - wlv.c_extra = cmdwin_type; wlv.c_final = NUL; - wlv.char_attr = - hl_combine_attr(get_win_attr(wp), HL_ATTR(HLF_AT)); + if (wlv.row == wlv.startrow) + { + wlv.c_extra = cmdwin_type; + wlv.char_attr = hl_combine_attr( + get_win_attr(wp), HL_ATTR(HLF_AT)); + } + else + { + wlv.c_extra = ' '; + wlv.char_attr = get_win_attr(wp); + } } } #ifdef FEAT_FOLDING @@ -2473,7 +2479,11 @@ win_line( // displaying that character. // Or when not wrapping and at the rightmost column. - int only_below_follows = !wp->w_p_wrap && wlv.col == wp->w_width - 1; + // Use the displayed width so a double-width or last + // character filling the rightmost column is detected too. + int only_below_follows = !wp->w_p_wrap + && wlv.col + win_chartabsize(wp, ptr, wlv.vcol) + >= wp->w_width; int suffix_flags = text_prop_suffix_flags[text_prop_next]; text_prop_follows = (suffix_flags @@ -4031,7 +4041,7 @@ win_line( curwin->w_cline_row = startrow; curwin->w_cline_height = wlv.row - startrow; #ifdef FEAT_FOLDING - curwin->w_cline_folded = FALSE; + curwin->w_cline_folded = false; #endif curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); } diff --git a/src/drawscreen.c b/src/drawscreen.c index 8fa00e8eb1..7e1c40c383 100644 --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -69,6 +69,7 @@ static void win_update(win_T *wp); #ifdef FEAT_STL_OPT static void redraw_custom_statusline(win_T *wp); #endif +static void borrow_stl_vsep_hl(void); #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) static int did_update_one_window; #endif @@ -160,6 +161,11 @@ update_screen(int type_arg) } updating_screen = TRUE; + // Hide the cursor while redrawing when sync output is not active, to + // avoid visible cursor flicker on terminals like Windows ConPTY. + int hid_cursor = !sync_output_active(); + if (hid_cursor) + cursor_off(); term_set_sync_output(TERM_SYNC_OUTPUT_ENABLE); #ifdef FEAT_PROP_POPUP @@ -212,7 +218,7 @@ update_screen(int type_arg) wp->w_redr_type = UPD_NOT_VALID; if (W_WINROW(wp) + wp->w_height + wp->w_status_height <= msg_scrolled) - wp->w_redr_status = TRUE; + wp->w_redr_status = true; } } } @@ -371,10 +377,22 @@ update_screen(int type_arg) pum_will_redraw = save_pum_will_redraw; pum_may_redraw(); + // Redraw vertical separators to update VertSplit/VertSplitNC highlights + // when the current window has changed. + if (redraw_vseps) + { + redraw_vseps = FALSE; + FOR_ALL_WINDOWS(wp) + if (wp->w_vsep_width > 0) + draw_vsep_win(wp, 0); + } + + borrow_stl_vsep_hl(); + // Reset b_mod_set flags. Going through all windows is probably faster // than going through all buffers (there could be many buffers). FOR_ALL_WINDOWS(wp) - wp->w_buffer->b_mod_set = FALSE; + wp->w_buffer->b_mod_set = false; #ifdef FEAT_PROP_POPUP // Display popup windows on top of the windows and command line. @@ -437,6 +455,8 @@ update_screen(int type_arg) #endif term_set_sync_output(TERM_SYNC_OUTPUT_DISABLE); + if (hid_cursor) + cursor_on(); return OK; } @@ -479,7 +499,7 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) row = statusline_row(wp); - wp->w_redr_status = FALSE; + wp->w_redr_status = false; if (wp->w_status_height == 0) { // no status line, can only be last window @@ -491,7 +511,7 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) || (!ignore_pum && pum_visible())) { // Don't redraw right now, do it later. - wp->w_redr_status = TRUE; + wp->w_redr_status = true; } #ifdef FEAT_STL_OPT else if (*p_stl != NUL || *wp->w_p_stl != NUL) @@ -600,16 +620,96 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) */ if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing()) { - if (stl_connected(wp)) - fillchar = fillchar_status(&attr, wp); - else - fillchar = fillchar_vsep(&attr, wp); for (i = 0; i < wp->w_status_height; i++) - screen_putchar(fillchar, row + i, W_ENDCOL(wp), attr); + { + int r = row + i; + if (stl_connected(wp)) + fillchar = fillchar_status(&attr, wp); + else + fillchar = fillchar_vsep(&attr, wp, r); + screen_putchar(fillchar, r, W_ENDCOL(wp), attr); + } } busy = FALSE; } +/* + * Borrow status line edge highlight to adjacent vsep cells. + * - When the pair involves curwin: borrow curwin's edge attr so custom + * statusline highlights flow into the vsep cell. + * - When both windows are non-current: borrow the left window's right-edge + * attr only if the status fillchar is a space, so StatusLineNC blends + * over the join without changing visible characters. + * - Cells where the vsep char is drawn (stl_connected == FALSE) are left + * untouched so the VertSplit highlight is preserved. + */ + static void +borrow_stl_vsep_hl(void) +{ + win_T *left = NULL; + win_T *right = NULL; + + if (!redrawing()) + return; + + FOR_ALL_WINDOWS(left) + { + if (left->w_status_height == 0 || left->w_vsep_width == 0) + continue; + if (!stl_connected(left)) + continue; + + // Find a right neighbour whose status line rows overlap. + win_T *neighbour = NULL; + int start = 0; + int end = 0; + + FOR_ALL_WINDOWS(right) + { + if (right == left || right->w_status_height == 0) + continue; + if (right->w_wincol != W_ENDCOL(left) + 1) + continue; + int l_stl_row = W_WINROW(left) + left->w_height; + int r_stl_row = W_WINROW(right) + right->w_height; + + start = l_stl_row > r_stl_row ? l_stl_row : r_stl_row; + end = l_stl_row + left->w_status_height + < r_stl_row + right->w_status_height + ? l_stl_row + left->w_status_height + : r_stl_row + right->w_status_height; + if (start < end) + { + neighbour = right; + break; + } + } + if (neighbour == NULL) + continue; + + // For non-current pairs only borrow when the status fillchar is a + // space; otherwise the visible character would be repainted with a + // foreign highlight. + int hl; + if (left != curwin && neighbour != curwin + && fillchar_status(&hl, left) != ' ') + continue; + + // Source: prefer curwin's side; otherwise left window's right edge. + int dst_col = W_ENDCOL(left); + int src_col = (neighbour == curwin) + ? neighbour->w_wincol : W_ENDCOL(left) - 1; + + for (int r = start; r < end; r++) + { + unsigned dst_off = LineOffset[r] + dst_col; + + ScreenAttrs[dst_off] = ScreenAttrs[LineOffset[r] + src_col]; + screen_char(dst_off, r, dst_col); + } + } +} + #ifdef FEAT_STL_OPT /* * Redraw the status line according to 'statusline' and take care of any @@ -643,7 +743,7 @@ showruler(int always) if (pum_visible()) { // Don't redraw right now, do it later. - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; return; } #if defined(FEAT_STL_OPT) @@ -1432,7 +1532,7 @@ fold_line( { curwin->w_cline_row = row; curwin->w_cline_height = 1; - curwin->w_cline_folded = TRUE; + curwin->w_cline_folded = true; curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); } @@ -1553,7 +1653,7 @@ win_update(win_T *wp) if (type == UPD_NOT_VALID) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; wp->w_lines_valid = 0; } @@ -2836,13 +2936,13 @@ win_update(win_T *wp) if (wp->w_redr_type != 0) { // Don't update for changes in buffer again. - i = curbuf->b_mod_set; - curbuf->b_mod_set = FALSE; + bool b = curbuf->b_mod_set; + curbuf->b_mod_set = false; j = curbuf->b_mod_xlines; curbuf->b_mod_xlines = 0; curs_columns(TRUE); win_update(curwin); - curbuf->b_mod_set = i; + curbuf->b_mod_set = b; curbuf->b_mod_xlines = j; } // Other windows might have w_redr_type raised in update_topline(). @@ -3364,7 +3464,7 @@ redraw_buf_and_status_later(buf_T *buf, int type) if (wp->w_buffer == buf) { redraw_win_later(wp, type); - wp->w_redr_status = TRUE; + wp->w_redr_status = true; } } } @@ -3381,7 +3481,7 @@ status_redraw_all(void) FOR_ALL_WINDOWS(wp) if (wp->w_status_height) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; redraw_later(UPD_VALID); } } @@ -3397,7 +3497,7 @@ status_redraw_curbuf(void) FOR_ALL_WINDOWS(wp) if (wp->w_status_height != 0 && wp->w_buffer == curbuf) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; redraw_later(UPD_VALID); } } @@ -3418,6 +3518,7 @@ redraw_statuslines(void) if (ret) pop_highlight_overrides(); } + borrow_stl_vsep_hl(); if (redraw_tabline) draw_tabline(); @@ -3434,7 +3535,7 @@ redraw_statuslines(void) win_redraw_last_status(frame_T *frp) { if (frp->fr_layout == FR_LEAF) - frp->fr_win->w_redr_status = TRUE; + frp->fr_win->w_redr_status = true; else if (frp->fr_layout == FR_ROW) { FOR_ALL_FRAMES(frp, frp->fr_child) @@ -3481,6 +3582,28 @@ redraw_win_range_later( } } +/* + * Like redraw_win_range_later() but do not raise the global must_redraw. + * Use this from inside an update_screen() pass (where the redraw will be + * picked up this cycle), to avoid triggering an extra full redraw cycle. + */ + void +redraw_win_range_now( + win_T *wp, + linenr_T first, + linenr_T last) +{ + if (last >= wp->w_topline && first < wp->w_botline) + { + if (wp->w_redraw_top == 0 || wp->w_redraw_top > first) + wp->w_redraw_top = first; + if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < last) + wp->w_redraw_bot = last; + if (wp->w_redr_type < UPD_VALID) + wp->w_redr_type = UPD_VALID; + } +} + #ifdef FEAT_EVAL static bool redraw_cb_in_progress = false; @@ -3493,6 +3616,9 @@ f_redraw_listener_add(typval_T *argvars, typval_T *rettv) bool got_one = false; static int id; + if (check_secure()) + return; + if (redraw_cb_in_progress) { emsg(_(e_cannot_add_redraw_listener_in_listener_callback)); diff --git a/src/edit.c b/src/edit.c index d150e9e534..88d86bc49a 100644 --- a/src/edit.c +++ b/src/edit.c @@ -468,7 +468,7 @@ edit( // set curwin->w_curswant for next K_DOWN or K_UP if (!arrow_used) - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // If there is no typeahead may check for timestamps (e.g., for when a // menu invoked a shell command). @@ -1141,6 +1141,10 @@ doESCkey: case K_COMMAND: // command case K_SCRIPT_COMMAND: // command { + bufref_T save_curbuf; + varnumber_T tick = CHANGEDTICK(curbuf); + + set_bufref(&save_curbuf, curbuf); do_cmdkey_command(c, 0); #ifdef FEAT_TERMINAL @@ -1148,10 +1152,15 @@ doESCkey: // Started a terminal that gets the input, exit Insert mode. goto doESCkey; #endif - if (curbuf->b_u_synced) - // The command caused undo to be synced. Need to save the - // line for undo before inserting the next char. + if (curbuf->b_u_synced + || (bufref_valid(&save_curbuf) + && curbuf == save_curbuf.br_buf + && tick != CHANGEDTICK(curbuf))) + { + // The command synced undo or changed this buffer. + // Save the cursor line before the next typed edit. ins_need_undo = TRUE; + } } break; @@ -2511,7 +2520,19 @@ stop_arrow(void) else if (ins_need_undo) { if (u_save_cursor() == OK) + { + // A command or event may have moved the cursor before the next + // edit. Pull Insstart back only when the cursor moved above it, + // so that later edits can properly decide whether an extra undo + // entry is needed. Advancing Insstart would mis-place '[ after a + // register paste. + if (LT_POS(curwin->w_cursor, Insstart)) + { + Insstart = curwin->w_cursor; + Insstart_textlen = (colnr_T)linetabsize_str(ml_get_curline()); + } ins_need_undo = FALSE; + } } #ifdef FEAT_FOLDING @@ -2606,34 +2627,48 @@ stop_insert( { pos_T tpos = curwin->w_cursor; colnr_T prev_col = end_insert_pos->col; + colnr_T strip_col; curwin->w_cursor = *end_insert_pos; check_cursor_col(); // make sure it is not past the line - for (;;) - { - if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) - --curwin->w_cursor.col; - cc = gchar_cursor(); - if (!VIM_ISWHITE(cc)) - break; - if (del_char(TRUE) == FAIL) - break; // should not happen - } - if (curwin->w_cursor.lnum != tpos.lnum) - curwin->w_cursor = tpos; - else if (curwin->w_cursor.col < prev_col) - { - // reset tpos, could have been invalidated in the loop above - tpos = curwin->w_cursor; - tpos.col++; - if (cc != NUL && gchar_pos(&tpos) == NUL) - ++curwin->w_cursor.col; // put cursor back on the NUL - } - // may have started Visual mode, adjust the position for - // deleted characters. - if (VIsual_active) - check_visual_pos(); + // Where the loop would actually start (back up if on NUL). + strip_col = curwin->w_cursor.col; + if (gchar_cursor() == NUL && strip_col > 0) + --strip_col; + + // Don't strip if non-whitespace follows: setline() from a + // mapping or CursorHoldI autocmd may have inserted content. + if (*skipwhite(ml_get_curline() + strip_col) == NUL) + { + curwin->w_cursor.col = strip_col; + for (;;) + { + cc = gchar_cursor(); + if (!VIM_ISWHITE(cc)) + break; + if (del_char(TRUE) == FAIL) + break; // should not happen + } + if (curwin->w_cursor.lnum != tpos.lnum) + curwin->w_cursor = tpos; + else if (curwin->w_cursor.col < prev_col) + { + // reset tpos, could have been invalidated in the loop above + tpos = curwin->w_cursor; + tpos.col++; + if (cc != NUL && gchar_pos(&tpos) == NUL) + ++curwin->w_cursor.col; // put cursor back on the NUL + } + + // may have started Visual mode, adjust the position for + // deleted characters. + if (VIsual_active) + check_visual_pos(); + } + else + // Non-whitespace follows, keep original cursor. + curwin->w_cursor = tpos; } } did_ai = FALSE; @@ -2749,7 +2784,7 @@ beginline(int flags) && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr) ++curwin->w_cursor.col; } - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } adjust_skipcol(); } @@ -2777,7 +2812,7 @@ oneright(void) coladvance(getviscol() + ((*ptr != TAB && vim_isprintc((*mb_ptr2char)(ptr))) ? ptr2cells(ptr) : 1)); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // Return OK if the cursor moved, FAIL otherwise (at window edge). return (prevpos.col != curwin->w_cursor.col || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL; @@ -2798,7 +2833,7 @@ oneright(void) return FAIL; curwin->w_cursor.col += l; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; adjust_skipcol(); return OK; } @@ -2845,7 +2880,7 @@ oneleft(void) curwin->w_cursor.coladd = 0; } - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; adjust_skipcol(); return OK; } @@ -2853,7 +2888,7 @@ oneleft(void) if (curwin->w_cursor.col == 0) return FAIL; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; --curwin->w_cursor.col; // if the character on the left of the current cursor is a multi-byte @@ -3800,7 +3835,7 @@ ins_esc( // When an autoindent was removed, curswant stays after the // indent if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col) - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // Remember the last Insert position in the '^ mark. if ((cmdmod.cmod_flags & CMOD_KEEPJUMPS) == 0) @@ -4749,7 +4784,7 @@ ins_left(void) start_arrow(&tpos); --(curwin->w_cursor.lnum); coladvance((colnr_T)MAXCOL); - curwin->w_set_curswant = TRUE; // so we stay at the end + curwin->w_set_curswant = true; // so we stay at the end } else vim_beep(BO_CRSR); @@ -4809,7 +4844,7 @@ ins_s_left(void) if (!end_change) AppendCharToRedobuff(K_S_LEFT); (void)bck_word(1L, FALSE, FALSE); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } else vim_beep(BO_CRSR); @@ -4831,7 +4866,7 @@ ins_right(void) start_arrow_with_change(&curwin->w_cursor, end_change); if (!end_change) AppendCharToRedobuff(K_RIGHT); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (virtual_active()) oneright(); else @@ -4854,7 +4889,7 @@ ins_right(void) && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { start_arrow(&curwin->w_cursor); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; ++curwin->w_cursor.lnum; curwin->w_cursor.col = 0; } @@ -4879,7 +4914,7 @@ ins_s_right(void) if (!end_change) AppendCharToRedobuff(K_S_RIGHT); (void)fwd_word(1L, FALSE, 0); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } else vim_beep(BO_CRSR); diff --git a/src/errors.h b/src/errors.h index fde1324a17..8cb60ba0c4 100644 --- a/src/errors.h +++ b/src/errors.h @@ -1139,11 +1139,8 @@ EXTERN char e_cant_find_postscript_resource_file_str_ps[] EXTERN char e_cant_read_postscript_resource_file_str[] INIT(= N_("E457: Can't read PostScript resource file \"%s\"")); #endif -#ifdef FEAT_GUI_X11 -EXTERN char e_cannot_allocate_colormap_entry_some_colors_may_be_incorrect[] - INIT(= N_("E458: Cannot allocate colormap entry, some colors may be incorrect")); -#endif -#if defined(UNIX) || defined(FEAT_SESSION) +// E458 unused +#if defined(UNIX) || defined(FEAT_SESSION) || defined(FEAT_SOCKETSERVER) EXTERN char e_cannot_go_back_to_previous_directory[] INIT(= N_("E459: Cannot go back to previous directory")); #endif @@ -2385,8 +2382,8 @@ EXTERN char e_using_job_as_number[] INIT(= N_("E910: Using a Job as a Number")); EXTERN char e_using_job_as_float[] INIT(= N_("E911: Using a Job as a Float")); -EXTERN char e_cannot_use_evalexpr_sendexpr_with_raw_or_nl_channel[] - INIT(= N_("E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel")); +EXTERN char e_cannot_use_evalexpr_sendexpr_with_raw_nl_or_blob_channel[] + INIT(= N_("E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw, nl or blob channel")); EXTERN char e_using_channel_as_number[] INIT(= N_("E913: Using a Channel as a Number")); EXTERN char e_using_channel_as_float[] @@ -3572,7 +3569,8 @@ 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")); -// E1406 unused +EXTERN char e_public_and_protected_member_have_same_name_str_str[] + INIT(= N_("E1406: Public and protected member have the same name: %s and _%s")); 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[] @@ -3784,16 +3782,14 @@ EXTERN char e_diff_anchors_with_hidden_windows[] INIT(= N_("E1562: Diff anchors cannot be used with hidden diff windows")); #endif #ifdef FEAT_SOCKETSERVER -EXTERN char e_socket_path_too_big[] - INIT(= N_("E1563: Socket path is too big")); EXTERN char e_socket_name_no_slashes[] - INIT(= N_("E1564: Socket name cannot have slashes in it without being a path")); + INIT(= N_("E1564: Socket name '%s' cannot have slashes in it without being a path")); EXTERN char e_socket_server_not_online[] INIT(= N_("E1565: Socket server is not online, call remote_startserver() first")); EXTERN char e_socket_server_failed_connecting[] - INIT(= N_("E1566: Failed connecting to socket %s: %s")); -EXTERN char e_socket_server_unavailable[] - INIT(= N_("E1567: Cannot start socket server, socket path is unavailable")); + INIT(= N_("E1566: Failed connecting to socket '%s'")); +EXTERN char e_socket_server_version_mismatch[] + INIT(= N_("E1567: Socket server protocol version mismatch, check what Vim version you are using")); #endif EXTERN char e_osc_response_timed_out[] INIT(= N_("E1568: OSC command response timed out: %.*s")); @@ -3817,3 +3813,11 @@ EXTERN char e_gethostbyname_in_channel_listen[] EXTERN char e_cannot_create_pipes[] INIT(= N_("E1575: Cannot create pipes")); #endif +EXTERN char e_tag_file_entry_must_not_be_url[] + INIT(= N_("E1576: Tag file entry must not be a URL")); +EXTERN char e_invalid_format_string_single_percent_s[] + INIT(= N_("E1577: Invalid format string, only one \"%s\" is allowed")); +#ifdef FEAT_SPELL +EXTERN char e_too_many_postponed_prefixes_spell[] + INIT(= N_("E1578: Too many postponed prefixes and/or compound flags")); +#endif diff --git a/src/eval.c b/src/eval.c index 6f7c9960a2..7d212b5b30 100644 --- a/src/eval.c +++ b/src/eval.c @@ -6579,15 +6579,9 @@ class_tv2string(typval_T *tv, char_u **tofree) class_name.string = cl->class_name.string; class_name.length = cl->class_name.length; if (IS_INTERFACE(cl)) - { - s.string = (char_u *)"interface"; - s.length = 9; - } + STR_LITERAL_SET(s, "interface"); else if (IS_ENUM(cl)) - { - s.string = (char_u *)"enum"; - s.length = 4; - } + STR_LITERAL_SET(s, "enum"); } rsize = s.length + 1 + class_name.length + 1; diff --git a/src/evalfunc.c b/src/evalfunc.c index d476191a60..da6f49551d 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -1931,6 +1931,11 @@ typedef struct #else # define TERM_FUNC(name) NULL #endif +#ifdef FEAT_TABPANEL +# define TABPANEL_FUNC(name) name +#else +# define TABPANEL_FUNC(name) NULL +#endif static const funcentry_T global_functions[] = { @@ -2992,6 +2997,10 @@ static const funcentry_T global_functions[] = ret_number, f_tabpagenr}, {"tabpagewinnr", 1, 2, FEARG_1, arg2_number_string, ret_number, f_tabpagewinnr}, + {"tabpanel_getinfo", 0, 0, 0, NULL, + ret_dict_any, TABPANEL_FUNC(f_tabpanel_getinfo)}, + {"tabpanel_scroll", 1, 2, FEARG_1, arg2_number_dict_any, + ret_bool, TABPANEL_FUNC(f_tabpanel_scroll)}, {"tagfiles", 0, 0, 0, NULL, ret_list_string, f_tagfiles}, {"taglist", 1, 2, FEARG_1, arg2_string, @@ -4392,6 +4401,9 @@ f_echoraw(typval_T *argvars, typval_T *rettv UNUSED) { char_u *str; + if (check_secure()) + return; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; @@ -7136,6 +7148,13 @@ f_has(typval_T *argvars, typval_T *rettv) 1 #else 0 +#endif + }, + {"gui_gtk4", +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) + 1 +#else + 0 #endif }, {"gui_gnome", @@ -7531,6 +7550,13 @@ f_has(typval_T *argvars, typval_T *rettv) 1 #else 0 +#endif + }, + {"statusline_click", +#ifdef FEAT_STL_OPT + 1 +#else + 0 #endif }, {"netbeans_intg", @@ -7714,13 +7740,6 @@ f_has(typval_T *argvars, typval_T *rettv) 1 #else 0 -#endif - }, - {"wayland_focus_steal", -#ifdef FEAT_WAYLAND_CLIPBOARD_FS - 1 -#else - 0 #endif }, {"wildignore", 1}, @@ -10449,6 +10468,7 @@ f_getreginfo(typval_T *argvars, typval_T *rettv) { int regname; char_u buf[NUMBUFLEN + 2]; + size_t buflen; long reglen = 0; dict_T *dict; list_T *list; @@ -10472,23 +10492,34 @@ f_getreginfo(typval_T *argvars, typval_T *rettv) return; (void)dict_add_list(dict, "regcontents", list); - buf[0] = NUL; - buf[1] = NUL; switch (get_reg_type(regname, ®len)) { - case MLINE: buf[0] = 'V'; break; - case MCHAR: buf[0] = 'v'; break; + case MLINE: + buf[0] = 'V'; + buf[1] = NUL; + buflen = 1; + break; + case MCHAR: + buf[0] = 'v'; + buf[1] = NUL; + buflen = 1; + break; case MBLOCK: - vim_snprintf((char *)buf, sizeof(buf), "%c%ld", Ctrl_V, - reglen + 1); - break; + buflen = vim_snprintf_safelen((char *)buf, sizeof(buf), + "%c%ld", Ctrl_V, reglen + 1); + break; + default: + buf[0] = NUL; + buflen = 0; + break; } - (void)dict_add_string(dict, (char *)"regtype", buf); + (void)dict_add_string_len(dict, (char *)"regtype", buf, (int)buflen); buf[0] = get_register_name(get_unname_register()); buf[1] = NUL; + buflen = (buf[0] == NUL) ? 0 : 1; if (regname == '"') - (void)dict_add_string(dict, (char *)"points_to", buf); + (void)dict_add_string_len(dict, (char *)"points_to", buf, (int)buflen); else { dictitem_T *item = dictitem_alloc((char_u *)"isunnamed"); @@ -10506,11 +10537,11 @@ f_getreginfo(typval_T *argvars, typval_T *rettv) static void return_register(int regname, typval_T *rettv) { - char_u buf[2] = {0, 0}; + char_u buf[2] = {NUL, NUL}; buf[0] = (char_u)regname; rettv->v_type = VAR_STRING; - rettv->vval.v_string = vim_strsave(buf); + rettv->vval.v_string = vim_strnsave(buf, (buf[0] == NUL) ? 0 : 1); } /* @@ -10617,7 +10648,7 @@ repeat_string(typval_T *str_tv, int n, typval_T *rettv) int slen; int len; char_u *r; - int i; + int done; p = tv_get_string(str_tv); rettv->v_type = VAR_STRING; @@ -10632,8 +10663,17 @@ repeat_string(typval_T *str_tv, int n, typval_T *rettv) if (r == NULL) return; - for (i = 0; i < n; i++) - mch_memmove(r + i * slen, p, (size_t)slen); + mch_memmove(r, p, (size_t)slen); + done = slen; + while (done < len) + { + int copy_len = done; + + if (copy_len > len - done) + copy_len = len - done; + mch_memmove(r + done, r, (size_t)copy_len); + done += copy_len; + } r[len] = NUL; rettv->vval.v_string = r; @@ -10875,7 +10915,7 @@ search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) if (flags & SP_NOMOVE) curwin->w_cursor = save_cursor; else - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; theend: p_ws = save_p_ws; @@ -11467,7 +11507,7 @@ set_position(typval_T *argvars, typval_T *rettv, int charpos) if (curswant >= 0) { curwin->w_curswant = curswant - 1; - curwin->w_set_curswant = FALSE; + curwin->w_set_curswant = false; } check_cursor(); rettv->vval.v_number = 0; @@ -12018,7 +12058,7 @@ f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv) if (len != 0) { word = ml_get_cursor(); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } } else if (*curbuf->b_s.b_p_spl != NUL) diff --git a/src/evalvars.c b/src/evalvars.c index f91e1e1eae..9d48d2c817 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -37,7 +37,7 @@ static hashtab_T compat_hashtab; #define VV_RO 2 // read-only #define VV_RO_SBX 4 // read-only in the sandbox -#define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}} +#define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {s}} typedef struct vimvar vimvar_T; @@ -218,12 +218,6 @@ evalvars_init(void) for (i = 0; i < VV_LEN; ++i) { p = &vimvars[i]; - if (STRLEN(p->vv_name) > DICTITEM16_KEY_LEN) - { - iemsg("Name too long, increase size of dictitem16_T"); - getout(1); - } - STRCPY(p->vv_di.di_key, p->vv_name); if (p->vv_flags & VV_RO) p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; else if (p->vv_flags & VV_RO_SBX) diff --git a/src/evalwindow.c b/src/evalwindow.c index 53116c7a1d..c93979e08c 100644 --- a/src/evalwindow.c +++ b/src/evalwindow.c @@ -794,7 +794,7 @@ f_win_execute(typval_T *argvars, typval_T *rettv) // Update the status line if the cursor moved. if (win_valid(wp) && !EQUAL_POS(curpos, wp->w_cursor)) - wp->w_redr_status = TRUE; + wp->w_redr_status = true; // In case the command moved the cursor or changed the Visual area, // check it is valid. @@ -1256,7 +1256,7 @@ f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) if (dict_has_key(dict, "curswant")) { curwin->w_curswant = (colnr_T)dict_get_number(dict, "curswant"); - curwin->w_set_curswant = FALSE; + curwin->w_set_curswant = false; } if (dict_has_key(dict, "topline")) diff --git a/src/ex_cmds.c b/src/ex_cmds.c index efb0c66dc0..7999cba0e0 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3205,7 +3205,7 @@ do_ecmd( // Since we are starting to edit a file, consider the filetype to be // unset. Helps for when an autocommand changes files and expects syntax // highlighting to work in the other file. - curbuf->b_did_filetype = FALSE; + curbuf->b_did_filetype = false; /* * other_file oldbuf @@ -3430,7 +3430,7 @@ do_ecmd( curwin->w_cursor.col = solcol; check_cursor_col(); curwin->w_cursor.coladd = 0; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } else beginline(BL_SOL | BL_FIX); @@ -4001,10 +4001,10 @@ ex_substitute(exarg_T *eap) #endif 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; + char_u *sub = NULL; // init for GCC + string_T pat = {NULL, 0}; int delimiter; - int sublen; + size_t sublen; int got_quit = FALSE; int got_match = FALSE; int which_pat; @@ -4012,12 +4012,12 @@ ex_substitute(exarg_T *eap) char_u *p; int save_State; linenr_T first_line = 0; // first changed line - linenr_T last_line= 0; // below last changed line AFTER the + linenr_T last_line = 0; // below last changed line AFTER the // change linenr_T old_line_count = curbuf->b_ml.ml_line_count; linenr_T line2; long nmatch; // number of lines in match - char_u *sub_firstline; // allocated copy of first sub line + string_T sub_firstline; // allocated copy of first sub line int endcolumn = FALSE; // cursor in last column when done pos_T old_cursor = curwin->w_cursor; int start_nsubs; @@ -4047,7 +4047,7 @@ ex_substitute(exarg_T *eap) if (eap->cmd[0] == 's' && *cmd != NUL && !VIM_ISWHITE(*cmd) && vim_strchr((char_u *)"0123456789cegriIp|\"", *cmd) == NULL) { - // don't accept alphanumeric for separator + // don't accept alphanumeric for separator if (check_regexp_delim(*cmd) == FAIL) return; #ifdef FEAT_EVAL @@ -4076,20 +4076,19 @@ ex_substitute(exarg_T *eap) } if (*cmd != '&') which_pat = RE_SEARCH; // use last '/' pattern - pat = (char_u *)""; // empty search pattern - patlen = 0; + STR_LITERAL_SET(pat, ""); // empty search pattern delimiter = *cmd++; // remember delimiter character } else // find the end of the regexp { which_pat = RE_LAST; // use last used regexp delimiter = *cmd++; // remember delimiter character - pat = cmd; // remember start of search pat + pat.string = cmd; // remember start of search pat cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), &eap->arg, NULL, NULL); + pat.length = (size_t)(cmd - pat.string); if (cmd[0] == delimiter) // end delimiter found *cmd++ = NUL; // replace it with a NUL - patlen = STRLEN(pat); } /* @@ -4141,9 +4140,11 @@ ex_substitute(exarg_T *eap) emsg(_(e_no_previous_substitute_regular_expression)); return; } - pat = NULL; // search_regcomp() will use previous pattern - patlen = 0; + pat.string = NULL; // search_regcomp() will use previous pattern + pat.length = 0; sub = vim_strsave(old_sub); + if (sub == NULL) + return; // Vi compatibility quirk: repeating with ":s" keeps the cursor in the // last column after using "$". @@ -4154,7 +4155,7 @@ ex_substitute(exarg_T *eap) // more efficient. // TODO: find a generic solution to make line-joining operations more // efficient, avoid allocating a string that grows in size. - if (pat != NULL && STRCMP(pat, "\\n") == 0 + if (pat.string != NULL && STRCMP(pat.string, "\\n") == 0 && *sub == NUL && (*cmd == NUL || (cmd[1] == NUL && (*cmd == 'g' || *cmd == 'l' || *cmd == 'p' || *cmd == '#')))) @@ -4189,9 +4190,9 @@ ex_substitute(exarg_T *eap) } if (!keeppatterns) - save_re_pat(RE_SUBST, pat, patlen, magic_isset()); + save_re_pat(RE_SUBST, pat.string, pat.length, magic_isset()); // put pattern in history - add_to_history(HIST_SEARCH, pat, patlen, TRUE, NUL); + add_to_history(HIST_SEARCH, pat.string, pat.length, TRUE, NUL); vim_free(sub); return; @@ -4326,7 +4327,7 @@ ex_substitute(exarg_T *eap) return; } - if (search_regcomp(pat, patlen, NULL, RE_SUBST, which_pat, SEARCH_HIS, ®match) == FAIL) + if (search_regcomp(pat.string, pat.length, NULL, RE_SUBST, which_pat, SEARCH_HIS, ®match) == FAIL) { if (subflags.do_error) emsg(_(e_invalid_command)); @@ -4340,7 +4341,8 @@ ex_substitute(exarg_T *eap) else if (subflags.do_ic == 'I') regmatch.rmm_ic = FALSE; - sub_firstline = NULL; + sub_firstline.string = NULL; + sub_firstline.length = 0; /* * If the substitute pattern starts with "\=" then it's an expression. @@ -4385,12 +4387,13 @@ ex_substitute(exarg_T *eap) colnr_T copycol; colnr_T matchcol; colnr_T prev_matchcol = MAXCOL; - char_u *new_end, *new_start = NULL; - unsigned new_start_len = 0; - char_u *p1; + string_T new_start = {NULL, 0}; + size_t new_start_size = 0; + char_u *new_end; int did_sub = FALSE; int lastone; - int len, copy_len, needed_len; + size_t copy_len; + size_t needed_size; long nmatch_tl = 0; // nr of lines matched below lnum int do_again; // do it again after joining lines int skip_match = FALSE; @@ -4439,7 +4442,7 @@ ex_substitute(exarg_T *eap) * accordingly. * * The new text is built up in new_start[]. It has some extra - * room to avoid using alloc()/free() too often. new_start_len is + * room to avoid using alloc()/free() too often. new_start_size is * the length of the allocated memory at new_start. * * Make a copy of the old line, so it won't be taken away when @@ -4467,6 +4470,10 @@ ex_substitute(exarg_T *eap) */ for (;;) { + string_T tmp; + char_u *p1; + size_t n; + // Advance "lnum" to the line where the match starts. The // match does not start in the first line when there is a line // break before \zs. @@ -4475,7 +4482,7 @@ ex_substitute(exarg_T *eap) lnum += regmatch.startpos[0].lnum; sub_firstlnum += regmatch.startpos[0].lnum; nmatch -= regmatch.startpos[0].lnum; - VIM_CLEAR(sub_firstline); + VIM_CLEAR_STRING(sub_firstline); } // Match might be after the last line for "\n\zs" matching at @@ -4483,13 +4490,14 @@ ex_substitute(exarg_T *eap) if (lnum > curbuf->b_ml.ml_line_count) break; - if (sub_firstline == NULL) + if (sub_firstline.string == NULL) { - sub_firstline = vim_strnsave(ml_get(sub_firstlnum), - ml_get_len(sub_firstlnum)); - if (sub_firstline == NULL) + sub_firstline.length = ml_get_len(sub_firstlnum); + sub_firstline.string = + vim_strnsave(ml_get(sub_firstlnum), sub_firstline.length); + if (sub_firstline.string == NULL) { - vim_free(new_start); + vim_free(new_start.string); goto outofmem; } } @@ -4508,7 +4516,7 @@ ex_substitute(exarg_T *eap) && regmatch.endpos[0].lnum == 0 && matchcol == regmatch.endpos[0].col) { - if (sub_firstline[matchcol] == NUL) + if (sub_firstline.string[matchcol] == NUL) // We already were at the end of the line. Don't look // for a match in this line again. skip_match = TRUE; @@ -4516,7 +4524,7 @@ ex_substitute(exarg_T *eap) { // search for a match at next column if (has_mbyte) - matchcol += mb_ptr2len(sub_firstline + matchcol); + matchcol += mb_ptr2len(sub_firstline.string + matchcol); else ++matchcol; } @@ -4540,7 +4548,7 @@ ex_substitute(exarg_T *eap) // Avoids that ":s/\nB\@=//gc" get stuck. if (nmatch > 1) { - matchcol = (colnr_T)STRLEN(sub_firstline); + matchcol = (colnr_T)sub_firstline.length; nmatch = 1; skip_match = TRUE; } @@ -4619,7 +4627,7 @@ ex_substitute(exarg_T *eap) } else { - char_u *orig_line = NULL; + string_T orig_line = {NULL, 0}; int len_change = 0; int save_p_lz = p_lz; #ifdef FEAT_FOLDING @@ -4635,33 +4643,36 @@ ex_substitute(exarg_T *eap) // avoid calling update_screen() in vgetorpeek() p_lz = FALSE; - if (new_start != NULL) + if (new_start.string != NULL) { // There already was a substitution, we would // like to show this to the user. We cannot // really update the line, it would change // what matches. Temporarily replace the line // and change it back afterwards. - orig_line = vim_strnsave(ml_get(lnum), - ml_get_len(lnum)); - if (orig_line != NULL) + orig_line.length = ml_get_len(lnum); + orig_line.string = vim_strnsave(ml_get(lnum), orig_line.length); + if (orig_line.string != NULL) { - char_u *new_line = concat_str(new_start, - sub_firstline + copycol); + string_T new_line; - if (new_line == NULL) - VIM_CLEAR(orig_line); + new_line.string = concat_str(new_start.string, + sub_firstline.string + copycol); + if (new_line.string == NULL) + VIM_CLEAR_STRING(orig_line); else { + new_line.length = + new_start.length + (sub_firstline.length - copycol); // Position the cursor relative to the // end of the line, the previous // substitute may have inserted or // deleted characters before the // cursor. - len_change = (int)STRLEN(new_line) - - (int)STRLEN(orig_line); + len_change = + (int)new_line.length - (int)orig_line.length; curwin->w_cursor.col += len_change; - ml_replace(lnum, new_line, FALSE); + ml_replace(lnum, new_line.string, FALSE); } } } @@ -4718,8 +4729,8 @@ ex_substitute(exarg_T *eap) p_lz = save_p_lz; // restore the line - if (orig_line != NULL) - ml_replace(lnum, orig_line, FALSE); + if (orig_line.string != NULL) + ml_replace(lnum, orig_line.string, FALSE); } need_wait_return = FALSE; // no hit-return prompt @@ -4767,7 +4778,7 @@ ex_substitute(exarg_T *eap) // get stuck when pressing 'n'. if (nmatch > 1) { - matchcol = (colnr_T)STRLEN(sub_firstline); + matchcol = (colnr_T)sub_firstline.length; skip_match = TRUE; } goto skip; @@ -4801,11 +4812,10 @@ ex_substitute(exarg_T *eap) #endif // Get length of substitution part, including the NUL. // When it fails sublen is zero. - sublen = vim_regsub_multi(®match, - sub_firstlnum - regmatch.startpos[0].lnum, - sub, sub_firstline, 0, - REGSUB_BACKSLASH - | (magic_isset() ? REGSUB_MAGIC : 0)); + sublen = (size_t)vim_regsub_multi(®match, + sub_firstlnum - regmatch.startpos[0].lnum, + sub, sub_firstline.string, 0, + REGSUB_BACKSLASH | (magic_isset() ? REGSUB_MAGIC : 0)); #ifdef FEAT_EVAL --textlock; @@ -4841,7 +4851,8 @@ ex_substitute(exarg_T *eap) // needed. if (nmatch == 1) { - p1 = sub_firstline; + tmp.string = sub_firstline.string; + tmp.length = sub_firstline.length; #ifdef FEAT_PROP_POPUP if (curbuf->b_has_textprop) { @@ -4856,7 +4867,7 @@ ex_substitute(exarg_T *eap) apc_flags &= ~APC_SAVE_FOR_UNDO; // Offset for column byte number of the text property // in the resulting buffer afterwards. - total_added += bytes_added; + total_added += (colnr_T)bytes_added; } #endif } @@ -4873,8 +4884,8 @@ ex_substitute(exarg_T *eap) total_added + regmatch.startpos[0].col, -MAXCOL, apc_flags)) apc_flags &= ~APC_SAVE_FOR_UNDO; - total_added -= (colnr_T)STRLEN( - sub_firstline + regmatch.startpos[0].col); + total_added -= + (colnr_T)(sub_firstline.length - regmatch.startpos[0].col); // Props in the last line may be moved or deleted if (adjust_prop_columns(lastlnum, @@ -4920,29 +4931,32 @@ ex_substitute(exarg_T *eap) } } #endif - p1 = ml_get(lastlnum); + tmp.string = ml_get(lastlnum); + tmp.length = ml_get_len(lastlnum); nmatch_tl += nmatch - 1; #ifdef FEAT_PROP_POPUP if (curbuf->b_has_textprop) - total_added += (colnr_T)STRLEN( - p1 + regmatch.endpos[0].col); + total_added += + (colnr_T)(tmp.length - regmatch.endpos[0].col); #endif } - copy_len = regmatch.startpos[0].col - copycol; - needed_len = copy_len + ((unsigned)STRLEN(p1) - - regmatch.endpos[0].col) + sublen + 1; - if (new_start == NULL) + + copy_len = (size_t)(regmatch.startpos[0].col - copycol); + needed_size = copy_len + + (tmp.length - (size_t)regmatch.endpos[0].col) + sublen + 1; + + if (new_start.string == NULL) { /* * Get some space for a temporary buffer to do the * substitution into (and some extra space to avoid * too many calls to alloc()/free()). */ - new_start_len = needed_len + 50; - if ((new_start = alloc_clear(new_start_len)) == NULL) + new_start_size = needed_size + 50; + if ((new_start.string = alloc_clear(new_start_size)) == NULL) goto outofmem; - *new_start = NUL; - new_end = new_start; + *new_start.string = NUL; + new_start.length = 0; } else { @@ -4951,40 +4965,45 @@ ex_substitute(exarg_T *eap) * substitution into. If not, make it larger (with a bit * extra to avoid too many calls to alloc()/free()). */ - len = (unsigned)STRLEN(new_start); - needed_len += len; - if (needed_len > (int)new_start_len) + needed_size += new_start.length; + if (needed_size > new_start_size) { - new_start_len = needed_len + 50; - if ((p1 = alloc_clear(new_start_len)) == NULL) + new_start_size = needed_size + 50; + if ((p1 = alloc_clear(new_start_size)) == NULL) { - vim_free(new_start); + vim_free(new_start.string); goto outofmem; } - mch_memmove(p1, new_start, (size_t)(len + 1)); - vim_free(new_start); - new_start = p1; + mch_memmove(p1, new_start.string, new_start.length + 1); + vim_free(new_start.string); + new_start.string = p1; } - new_end = new_start + len; } /* * copy the text up to the part that matched */ - mch_memmove(new_end, sub_firstline + copycol, (size_t)copy_len); - new_end += copy_len; + mch_memmove(new_start.string + new_start.length, + sub_firstline.string + copycol, copy_len); + new_start.length += copy_len; - if ((int)new_start_len - copy_len < sublen) - sublen = new_start_len - copy_len - 1; + // new text added here + new_end = new_start.string + new_start.length; + + if (new_start_size - copy_len < sublen) + sublen = new_start_size - copy_len - 1; #ifdef FEAT_EVAL ++textlock; #endif - (void)vim_regsub_multi(®match, - sub_firstlnum - regmatch.startpos[0].lnum, - sub, new_end, sublen, - REGSUB_COPY | REGSUB_BACKSLASH - | (magic_isset() ? REGSUB_MAGIC : 0)); + n = (size_t)vim_regsub_multi(®match, + sub_firstlnum - regmatch.startpos[0].lnum, + sub, new_end, (int)sublen, + REGSUB_COPY | REGSUB_BACKSLASH | (magic_isset() ? REGSUB_MAGIC : 0)); + + if (n > 0) + new_start.length += n - 1; // remove 1 for the NUL + #ifdef FEAT_EVAL --textlock; #endif @@ -5000,9 +5019,15 @@ ex_substitute(exarg_T *eap) if (nmatch > 1) { sub_firstlnum += nmatch - 1; - vim_free(sub_firstline); - sub_firstline = vim_strnsave(ml_get(sub_firstlnum), - ml_get_len(sub_firstlnum)); + vim_free(sub_firstline.string); + sub_firstline.length = ml_get_len(sub_firstlnum); + sub_firstline.string = + vim_strnsave(ml_get(sub_firstlnum), sub_firstline.length); + if (sub_firstline.string == NULL) + { + vim_free(new_start.string); + goto outofmem; + } // When going beyond the last line, stop substituting. if (sub_firstlnum <= line2) do_again = TRUE; @@ -5017,8 +5042,14 @@ ex_substitute(exarg_T *eap) { // Already hit end of the buffer, sub_firstlnum is one // less than what it ought to be. - vim_free(sub_firstline); - sub_firstline = vim_strsave((char_u *)""); + vim_free(sub_firstline.string); + sub_firstline.string = vim_strnsave((char_u *)"", 0); + if (sub_firstline.string == NULL) + { + vim_free(new_start.string); + goto outofmem; + } + sub_firstline.length = 0; copycol = 0; } @@ -5034,14 +5065,16 @@ ex_substitute(exarg_T *eap) { if (p1[0] == '\\' && p1[1] != NUL) // remove backslash { - STRMOVE(p1, p1 + 1); + n = (size_t)(new_start.length - (p1 - new_start.string)); + mch_memmove(p1, p1 + 1, n + 1); + --new_start.length; #ifdef FEAT_PROP_POPUP if (curbuf->b_has_textprop) { // When text properties are changed, need to save // for undo first, unless done already. if (adjust_prop_columns(lnum, - (colnr_T)(p1 - new_start), -1, + (colnr_T)(p1 - new_start.string), -1, apc_flags)) apc_flags &= ~APC_SAVE_FOR_UNDO; } @@ -5051,10 +5084,10 @@ ex_substitute(exarg_T *eap) { if (u_inssub(lnum) == OK) // prepare for undo { - colnr_T plen = (colnr_T)(p1 - new_start + 1); + colnr_T plen = (colnr_T)(p1 - new_start.string + 1); *p1 = NUL; // truncate up to the CR - ml_append(lnum - 1, new_start, plen, FALSE); + ml_append(lnum - 1, new_start.string, plen, FALSE); mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L); if (subflags.do_ask) appended_lines(lnum - 1, 1L); @@ -5075,8 +5108,10 @@ ex_substitute(exarg_T *eap) // move the cursor to the new line, like Vi ++curwin->w_cursor.lnum; // copy the rest - STRMOVE(new_start, p1 + 1); - p1 = new_start - 1; + n = new_start.length - (size_t)plen; + mch_memmove(new_start.string, p1 + 1, n + 1); + new_start.length = n; + p1 = new_start.string - 1; } } else if (has_mbyte) @@ -5100,7 +5135,7 @@ skip: || got_quit || lnum > line2 || !(subflags.do_all || do_again) - || (sub_firstline[matchcol] == NUL && nmatch <= 1 + || (sub_firstline.string[matchcol] == NUL && nmatch <= 1 && !re_multiline(regmatch.regprog))); nmatch = -1; @@ -5120,7 +5155,7 @@ skip: matchcol, NULL)) == 0 || regmatch.startpos[0].lnum > 0) { - if (new_start != NULL) + if (new_start.string != NULL) { /* * Copy the rest of the line, that didn't match. @@ -5129,14 +5164,16 @@ skip: * have changed the number of characters. Same for * "prev_matchcol". */ - STRCAT(new_start, sub_firstline + copycol); - matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol; - prev_matchcol = (colnr_T)STRLEN(sub_firstline) - - prev_matchcol; + STRCPY(new_start.string + new_start.length, + sub_firstline.string + copycol); + new_start.length += sub_firstline.length - (size_t)copycol; + matchcol = (colnr_T)(sub_firstline.length - matchcol); + prev_matchcol = (colnr_T)(sub_firstline.length + - prev_matchcol); if (u_savesub(lnum) != OK) break; - ml_replace(lnum, new_start, TRUE); + ml_replace(lnum, new_start.string, TRUE); #ifdef FEAT_PROP_POPUP if (text_props != NULL) add_text_props(lnum, text_props, text_prop_count); @@ -5182,12 +5219,14 @@ skip: } sub_firstlnum = lnum; - vim_free(sub_firstline); // free the temp buffer - sub_firstline = new_start; - new_start = NULL; - matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol; - prev_matchcol = (colnr_T)STRLEN(sub_firstline) - - prev_matchcol; + vim_free(sub_firstline.string); // free the temp buffer + sub_firstline.string = new_start.string; + sub_firstline.length = new_start.length; + new_start.string = NULL; + new_start.length = 0; + matchcol = (colnr_T)(sub_firstline.length - matchcol); + prev_matchcol = (colnr_T)(sub_firstline.length + - prev_matchcol); copycol = 0; } if (nmatch == -1 && !lastone) @@ -5213,8 +5252,8 @@ skip: if (did_sub) ++sub_nlines; - vim_free(new_start); // for when substitute was cancelled - VIM_CLEAR(sub_firstline); // free the copy of the original line + vim_free(new_start.string); // for when substitute was cancelled + VIM_CLEAR_STRING(sub_firstline); // free the copy of the original line } line_breakcheck(); @@ -5230,7 +5269,7 @@ skip: } outofmem: - vim_free(sub_firstline); // may have to free allocated copy of the line + vim_free(sub_firstline.string); // may have to free allocated copy of the line #ifdef FEAT_PROP_POPUP vim_free(text_props); diff --git a/src/ex_cmds.h b/src/ex_cmds.h index 661d7c58a9..e2f5ce3e08 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -31,7 +31,8 @@ #define EX_BANG 0x002 // allow a ! after the command name #define EX_EXTRA 0x004 // allow extra args after command name #define EX_XFILE 0x008 // expand wildcards in extra part -#define EX_NOSPC 0x010 // no spaces allowed in the extra part +#define EX_NOSPC 0x010 // extra part is a single argument (no split on + // whitespace) #define EX_DFLALL 0x020 // default file range is 1,$ #define EX_WHOLEFOLD 0x040 // extend range to include whole fold also // when less than two numbers given @@ -60,6 +61,7 @@ #define EX_EXPR_ARG 0x8000000 // argument is an expression #define EX_WHOLE 0x10000000 // command name cannot be shortened in Vim9 #define EX_EXPORT 0x20000000 // command can be used after :export +#define EX_ARGSPACE 0x40000000 // completion: keep spaces in arg lead #define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed #define EX_FILE1 (EX_FILES | EX_NOSPC) // 1 file, defaults to current file @@ -360,7 +362,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_CMDWIN|EX_LOCK_OK|EX_EXPORT, + EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE|EX_EXPORT, ADDR_NONE), EXCMD(CMD_close, "close", ex_close, EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, @@ -468,7 +470,7 @@ EXCMD(CMD_debuggreedy, "debuggreedy", ex_debuggreedy, EX_RANGE|EX_ZEROR|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_OTHER), EXCMD(CMD_def, "def", ex_function, - EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, + EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE|EX_EXPORT, ADDR_NONE), EXCMD(CMD_defcompile, "defcompile", ex_defcompile, EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_TRLBAR|EX_EXTRA, @@ -552,7 +554,7 @@ EXCMD(CMD_echomsg, "echomsg", ex_execute, EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_echoconsole, "echoconsole", ex_execute, - EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, + EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_echon, "echon", ex_echo, EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, @@ -573,16 +575,16 @@ EXCMD(CMD_endif, "endif", ex_endif, EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), EXCMD(CMD_endinterface, "endinterface", ex_wrongmodifier, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), EXCMD(CMD_endclass, "endclass", ex_wrongmodifier, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), EXCMD(CMD_enddef, "enddef", ex_endfunction, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), EXCMD(CMD_endenum, "endenum", ex_wrongmodifier, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), EXCMD(CMD_endfunction, "endfunction", ex_endfunction, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, @@ -1233,7 +1235,7 @@ EXCMD(CMD_put, "put", ex_put, EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_REGSTR|EX_TRLBAR|EX_ZEROR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY, ADDR_LINES), EXCMD(CMD_public, "public", ex_wrongmodifier, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), EXCMD(CMD_pwd, "pwd", ex_pwd, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, @@ -1512,7 +1514,7 @@ EXCMD(CMD_startreplace, "startreplace", ex_startinsert, EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_static, "static", ex_wrongmodifier, - EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), EXCMD(CMD_stopinsert, "stopinsert", ex_stopinsert, EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 5ac487da22..414de8cbde 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -141,7 +141,7 @@ browse_save_fname(buf_T *buf) char_u *fname; fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"), - NULL, NULL, NULL, NULL, buf); + (char_u *)"Untitled", NULL, NULL, NULL, buf); if (fname == NULL) return; @@ -253,6 +253,10 @@ dialog_changed( # ifdef FEAT_BROWSE // May get file name, when there is none browse_save_fname(buf); + + // User cancelled the file dialog; keep the buffer modified. + if (buf->b_fname == NULL) + return; # endif empty_bufname = buf->b_fname == NULL ? TRUE : FALSE; if (empty_bufname) @@ -265,13 +269,12 @@ dialog_changed( return; } - // restore to empty when write failed + // restore to empty when write failed or was cancelled if (empty_bufname) { buf->b_fname = NULL; VIM_CLEAR(buf->b_ffname); VIM_CLEAR(buf->b_sfname); - unchanged(buf, TRUE, FALSE); } } else if (ret == VIM_NO) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index a8aee02c99..c1f8a72113 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -4031,6 +4031,13 @@ find_ex_command( if (eap->cmdidx == CMD_final && p - eap->cmd == 4 && !vim9) eap->cmdidx = CMD_finally; + // Force ":ho" to be unresolved. Without this, find_ex_command() + // matches it to CMD_horizontal (the only "ho*" entry), which makes + // fullcommand("ho") return "horizontal" even though ":ho" cannot be + // used as the modifier (cmdmods[] requires 3 chars, "hor"). + if (eap->cmdidx == CMD_horizontal && p - eap->cmd == 2) + eap->cmdidx = CMD_SIZE; + #ifdef FEAT_EVAL if (eap->cmdidx < CMD_SIZE && vim9 @@ -5252,7 +5259,8 @@ expand_filename( || vim_strchr(eap->arg, '~') != NULL) { expand_env_esc(eap->arg, NameBuff, MAXPATHL, - TRUE, TRUE, NULL); + (char_u *)(" \t" PATH_ESC_WILDCARDS), + TRUE, NULL); has_wildcards = mch_has_wildcard(NameBuff); p = NameBuff; } @@ -7071,7 +7079,7 @@ call_findfunc(char_u *pat, int cmdcomplete) * Returns OK on success and FAIL otherwise. */ int -expand_findfunc(char_u *pat, char_u ***files, int *numMatches) +expand_findfunc(expand_T *xp, char_u *pat, char_u ***files, int *numMatches) { list_T *l; int len; @@ -7091,26 +7099,7 @@ expand_findfunc(char_u *pat, char_u ***files, int *numMatches) return FAIL; } - *files = ALLOC_MULT(char_u *, len); - if (*files == NULL) - { - list_free(l); - return FAIL; - } - - // Copy all the List items - listitem_T *li; - int idx = 0; - FOR_ALL_LIST_ITEMS(l, li) - { - if (li->li_tv.v_type == VAR_STRING) - { - (*files)[idx] = vim_strsave(li->li_tv.vval.v_string); - idx++; - } - } - - *numMatches = idx; + expand_process_user_list(l, files, numMatches, xp); list_free(l); return OK; @@ -7143,8 +7132,16 @@ findfunc_find_file(char_u *findarg, int findarg_len, int count) else { listitem_T *li = list_find(fname_list, count - 1); - if (li != NULL && li->li_tv.v_type == VAR_STRING) - ret_fname = vim_strsave(li->li_tv.vval.v_string); + + if (li != NULL) + { + typval_T *tv = &li->li_tv; + + if (tv->v_type == VAR_STRING && tv->vval.v_string != NULL) + ret_fname = vim_strsave(tv->vval.v_string); + else if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) + ret_fname = dict_get_string(tv->vval.v_dict, "word", TRUE); + } } } @@ -7925,7 +7922,7 @@ ex_syncbind(exarg_T *eap UNUSED) curwin->w_scbind_pos = topline; redraw_later(UPD_VALID); cursor_correct(); - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; } } curwin = save_curwin; @@ -8374,7 +8371,7 @@ do_sleep(long msec, int hide_cursor) // actual time passed done = ELAPSED_FUNC(start_tv); #else - // guestimate time passed (will actually be more) + // guesstimate time passed (will actually be more) done += wait_now; #endif } @@ -9028,6 +9025,7 @@ ex_redrawstatus(exarg_T *eap UNUSED) status_redraw_all(); else status_redraw_curbuf(); + redraw_vseps = TRUE; if (msg_scrolled && (State & MODE_CMDLINE)) return; // redraw later @@ -10387,7 +10385,7 @@ ex_setfiletype(exarg_T *eap) set_option_value_give_err((char_u *)"filetype", 0L, arg, OPT_LOCAL); if (arg != eap->arg) - curbuf->b_did_filetype = FALSE; + curbuf->b_did_filetype = false; } static void diff --git a/src/ex_eval.c b/src/ex_eval.c index 00e4d5fcf3..966c4f78a2 100644 --- a/src/ex_eval.c +++ b/src/ex_eval.c @@ -275,7 +275,7 @@ cause_errthrow( { char *tmsg; - // Skip the extra "Vim " prefix for message "E458". + // Skip the extra "Vim " prefix for message "E457". tmsg = elem->msg; if (STRNCMP(tmsg, "Vim E", 5) == 0 && VIM_ISDIGIT(tmsg[5]) diff --git a/src/ex_getln.c b/src/ex_getln.c index 70fd8bc59d..787fb56af0 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -584,7 +584,7 @@ may_do_incsearch_highlighting( // May redraw the status line to show the cursor position. if (p_ru && curwin->w_status_height > 0) - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; update_screen(UPD_SOME_VALID); highlight_match = FALSE; @@ -614,14 +614,18 @@ may_adjust_incsearch_highlighting( incsearch_state_T *is_state, int c) { - int skiplen, patlen; - pos_T t; - char_u *pat; - int search_flags = SEARCH_NOOF; - int i; - int save; - int bslsh = FALSE; - int search_delim; + int skiplen, patlen; + pos_T t; + char_u *pat; + char_u *dircp = NULL; + char_u *searchstr; + char_u *strcopy = NULL; + size_t searchstrlen; + size_t patlen_s; + soffset_T offset; + int search_flags = SEARCH_NOOF; + int i; + int search_delim; // Parsing range may already set the last search pattern. // NOTE: must call restore_last_search_pattern() before returning! @@ -639,31 +643,16 @@ may_adjust_incsearch_highlighting( return FAIL; } - if (search_delim == ccline.cmdbuff[skiplen]) - { - pat = last_search_pattern(); - if (pat == NULL) - { - restore_last_search_pattern(); - return FAIL; - } - skiplen = 0; - patlen = (int)last_search_pattern_len(); - } - else - pat = ccline.cmdbuff + skiplen; + pat = ccline.cmdbuff + skiplen; + searchstr = pat; + searchstrlen = (size_t)patlen; + patlen_s = (size_t)(ccline.cmdlen - skiplen); // do not search for the search end delimiter, // unless it is part of the pattern - if (patlen > 2 && firstc == pat[patlen - 1]) - { - patlen--; - if (pat[patlen - 1] == '\\') - { - pat[patlen - 1] = firstc; - bslsh = TRUE; - } - } + (void)parse_search_pattern_offset(&pat, &patlen_s, search_delim, + SEARCH_OPT, &strcopy, &searchstr, + &searchstrlen, &dircp, &offset); cursor_off(); out_flush(); @@ -681,18 +670,39 @@ may_adjust_incsearch_highlighting( if (!p_hls) search_flags += SEARCH_KEEP; ++emsg_off; - save = pat[patlen]; - pat[patlen] = NUL; i = searchit(curwin, curbuf, &t, NULL, c == Ctrl_G ? FORWARD : BACKWARD, - pat, patlen, count, search_flags, RE_SEARCH, NULL); + searchstr, searchstrlen, count, search_flags, RE_SEARCH, NULL); --emsg_off; - pat[patlen] = save; - if (bslsh) - pat[patlen - 1] = '\\'; + if (dircp != NULL) + *dircp = search_delim; if (i) { - is_state->search_start = is_state->match_start; + pos_T match_start = is_state->match_start; + pos_T match_end = is_state->match_end; + long off = offset.off; + + is_state->search_start = match_start; + if (!offset.line && (offset.end || off != 0)) + { + if (offset.end) + { + is_state->search_start = match_end; + (void)decl(&is_state->search_start); + } + while (off > 0) + { + if (incl(&is_state->search_start) == -1) + break; + --off; + } + while (off < 0) + { + if (decl(&is_state->search_start) == -1) + break; + ++off; + } + } is_state->match_end = t; is_state->match_start = t; if (c == Ctrl_T && firstc != '?') @@ -733,6 +743,7 @@ may_adjust_incsearch_highlighting( } else vim_beep(BO_ERROR); + vim_free(strcopy); restore_last_search_pattern(); return FAIL; } @@ -947,6 +958,7 @@ cmdline_wildchar_complete( int cmdpos_before; int options = WILD_NO_BEEP; int wim_noselect = p_wmnu && (wim_flags[0] & WIM_NOSELECT); + int wim_noinsert = p_wmnu && (wim_flags[0] & WIM_NOINSERT); if (wim_flags[wim_index] & WIM_BUFLASTUSED) options |= WILD_BUFLASTUSED; @@ -957,7 +969,8 @@ cmdline_wildchar_complete( && !*did_wild_list && (wim_flags[wim_index] & WIM_LIST)) { - (void)showmatches(xp, FALSE, TRUE, wim_noselect); + (void)showmatches(xp, FALSE, TRUE, + p_wmnu ? wim_flags[wim_index] : 0); redrawcmd(); *did_wild_list = TRUE; } @@ -995,6 +1008,8 @@ cmdline_wildchar_complete( { if (wim_noselect || wim_list) options |= WILD_NOSELECT; + if (wim_noinsert) + options |= WILD_NOINSERT; res = nextwild(xp, WILD_EXPAND_KEEP, options, escape); } @@ -1017,26 +1032,28 @@ cmdline_wildchar_complete( } // Display matches - if (res == OK && xp->xp_numfiles > (wim_noselect ? 0 : 1)) + if (res == OK && xp->xp_numfiles > ((wim_noselect || wim_noinsert) ? 0 : 1)) { if (wim_longest) { int found_longest_prefix = (ccline.cmdpos != cmdpos_before); if (wim_list || (p_wmnu && wim_full)) - (void)showmatches(xp, p_wmnu, wim_list, TRUE); + (void)showmatches(xp, p_wmnu, wim_list, WIM_NOSELECT); else if (!found_longest_prefix) { int wim_list_next = (wim_flags[1] & WIM_LIST); int wim_full_next = (wim_flags[1] & WIM_FULL); int wim_noselect_next = (wim_flags[1] & WIM_NOSELECT); + int wim_noinsert_next = (wim_flags[1] & WIM_NOINSERT); if (wim_list_next || (p_wmnu && (wim_full_next - || wim_noselect_next))) + || wim_noselect_next || wim_noinsert_next))) { - if (wim_full_next && !wim_noselect_next) + if (wim_full_next && !wim_noselect_next && !wim_noinsert_next) nextwild(xp, WILD_NEXT, options, escape); else (void)showmatches(xp, p_wmnu, wim_list_next, - wim_noselect_next); + p_wmnu ? wim_flags[1] : 0); + if (wim_list_next) *did_wild_list = TRUE; } @@ -1044,8 +1061,10 @@ cmdline_wildchar_complete( } else { - if (wim_list || (p_wmnu && (wim_full || wim_noselect))) - (void)showmatches(xp, p_wmnu, wim_list, wim_noselect); + if (wim_list || (p_wmnu && (wim_full || wim_noselect + || wim_noinsert))) + (void)showmatches(xp, p_wmnu, wim_list, + p_wmnu ? wim_flags[0] : 0); else vim_beep(BO_WILD); } @@ -1829,7 +1848,7 @@ getcmdline_int( FOR_ALL_WINDOWS(wp) if (*p_stl != NUL || *wp->w_p_stl != NUL) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; found_one = TRUE; } @@ -2170,7 +2189,7 @@ getcmdline_int( { // Trigger the popup menu when wildoptions=pum showmatches(&xpc, p_wmnu, wim_flags[wim_index] & WIM_LIST, - wim_flags[0] & WIM_NOSELECT); + p_wmnu ? wim_flags[0] : 0); } if (nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK) @@ -2285,7 +2304,7 @@ getcmdline_int( goto cmdline_not_changed; case Ctrl_D: - if (showmatches(&xpc, FALSE, TRUE, wim_flags[0] & WIM_NOSELECT) + if (showmatches(&xpc, FALSE, TRUE, p_wmnu ? wim_flags[0] : 0) == EXPAND_NOTHING) break; // Use ^D as normal char instead @@ -2686,7 +2705,17 @@ cmdline_changed: && (ccline.cmdpos != prev_cmdpos || (prev_cmdbuff != NULL && STRCMP(prev_cmdbuff, ccline.cmdbuff) != 0))) + { trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED); +#ifdef FEAT_PROP_POPUP + // Show popup updates from the autocmd without a manual :redraw. + if (popup_need_redraw()) + { + update_screen(0); + redrawcmd(); + } +#endif + } // Trigger CursorMovedC autocommands. if (ccline.cmdpos != prev_cmdpos) @@ -2898,6 +2927,8 @@ check_opt_wim(void) new_wim_flags[idx] |= WIM_BUFLASTUSED; else if (i == 8 && STRNCMP(p, "noselect", 8) == 0) new_wim_flags[idx] |= WIM_NOSELECT; + else if (i == 8 && STRNCMP(p, "noinsert", 8) == 0) + new_wim_flags[idx] |= WIM_NOINSERT; else return FAIL; p += i; @@ -4112,6 +4143,8 @@ redrawcmd(void) sb_text_restart_cmdline(); msg_start(); + // Reset lines_left so a wrapped cmdline isn't truncated by msg_no_more. + msg_starthere(); redrawcmdprompt(); // Don't use more prompt, truncate the cmdline if it doesn't fit. @@ -4878,6 +4911,7 @@ open_cmdwin(void) exmode_active = 0; State = MODE_NORMAL; + check_cursor(); setmouse(); clear_showcmd(); diff --git a/src/feature.h b/src/feature.h index 58a2a3c1aa..ce898a5651 100644 --- a/src/feature.h +++ b/src/feature.h @@ -296,6 +296,14 @@ # define FEAT_POSTSCRIPT #endif +/* + * +gtk_print Native GTK print dialog for :hardcopy (GTK4). + * Uses GtkPrintOperation + Pango/Cairo instead of PostScript. + */ +#if defined(FEAT_PRINTER) && defined(FEAT_GUI_GTK) && defined(USE_GTK4) +# define FEAT_GUI_GTK_PRINT +#endif + /* * +diff Displaying diffs in a nice way. * Can be enabled in autoconf already. @@ -439,6 +447,10 @@ # else // # define FEAT_XFONTSET # endif +#else +# if defined(USE_GTK4) +# undef FEAT_XFONTSET +# endif #endif /* @@ -513,7 +525,8 @@ /* * GUI dark theme variant */ -#if (defined(FEAT_GUI_GTK) && defined(USE_GTK3)) || defined(FEAT_GUI_MSWIN) +#if (defined(FEAT_GUI_GTK) && (defined(USE_GTK3) || defined(USE_GTK4))) \ + || defined(FEAT_GUI_MSWIN) # define FEAT_GUI_DARKTHEME #endif @@ -817,7 +830,7 @@ * +X11 Unix only. Include code for xterm title saving and X * clipboard. Only works if HAVE_X11 is also defined. */ -#if defined(FEAT_NORMAL) || defined(FEAT_GUI_MOTIF) +#if (defined(FEAT_NORMAL) || defined(FEAT_GUI_MOTIF)) && !defined(USE_GTK4) # define WANT_X11 #endif @@ -922,7 +935,8 @@ #if defined(FEAT_NORMAL) \ && (defined(UNIX) || defined(VMS)) \ - && defined(WANT_X11) && defined(HAVE_X11) + && defined(WANT_X11) && defined(HAVE_X11) \ + && !defined(USE_GTK4) # define FEAT_XCLIPBOARD # ifndef FEAT_CLIPBOARD # define FEAT_CLIPBOARD @@ -937,13 +951,6 @@ # endif #endif -/* - * +wayland_focus_steal Focus stealing support for Wayland clipboard - */ -#if !defined(FEAT_WAYLAND_CLIPBOARD) && defined(FEAT_WAYLAND_CLIPBOARD_FS) -# undef FEAT_WAYLAND_CLIPBOARD_FS -#endif - /* * +dnd Drag'n'drop support. Always used for the GTK+ GUI and MacVim. */ @@ -963,9 +970,16 @@ #endif /* - * +socketserver Use UNIX domain sockets for clientserver communication + * The +channel feature requires +eval. */ -#if defined(UNIX) && defined(WANT_SOCKETSERVER) +#if !defined(FEAT_EVAL) && defined(FEAT_JOB_CHANNEL) +# undef FEAT_JOB_CHANNEL +#endif + +/* + * +socketserver Use channels for clientserver communication + */ +#if (defined(UNIX) || defined(MSWIN)) && defined(FEAT_JOB_CHANNEL) # define FEAT_SOCKETSERVER #endif @@ -981,6 +995,9 @@ #if (defined(MSWIN) || defined(FEAT_XCLIPBOARD) || defined(FEAT_SOCKETSERVER) || defined(MAC_CLIENTSERVER)) \ && defined(FEAT_EVAL) # define FEAT_CLIENTSERVER +# if defined(FEAT_SOCKETSERVER) && (defined(FEAT_XCLIPBOARD) || defined(MSWIN)) +# define FEAT_CLIENTSERVER_BACKENDS +# endif #endif /* @@ -1069,14 +1086,6 @@ * +tgetent */ - -/* - * The +channel feature requires +eval. - */ -#if !defined(FEAT_EVAL) && defined(FEAT_JOB_CHANNEL) -# undef FEAT_JOB_CHANNEL -#endif - /* * The Netbeans feature requires +eval and +job_channel */ diff --git a/src/fileio.c b/src/fileio.c index f9b4e3781c..218b3a907e 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -236,7 +236,7 @@ readfile( #endif size_t fnamelen = 0; - curbuf->b_au_did_filetype = FALSE; // reset before triggering any autocommands + curbuf->b_au_did_filetype = false; // reset before triggering any autocommands curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read @@ -3200,11 +3200,13 @@ set_rw_fname(char_u *fname, char_u *sfname) void msg_add_fname(buf_T *buf, char_u *fname) { + size_t IObufflen = 0; + if (fname == NULL) fname = (char_u *)"-stdin-"; - home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE); - IObuff[0] = '"'; - STRCAT(IObuff, "\" "); + IObuff[IObufflen++] = '"'; + IObufflen += home_replace(buf, fname, IObuff + IObufflen, IOSIZE - 4, TRUE); + STRCPY(IObuff + IObufflen, "\" "); } /* @@ -4705,7 +4707,7 @@ buf_reload(buf_T *buf, int orig_mode, int reload_options) int old_msg_silent = msg_silent; curbuf->b_flags |= BF_CHECK_RO; // check for RO again - curbuf->b_keep_filetype = TRUE; // don't detect 'filetype' + curbuf->b_keep_filetype = true; // don't detect 'filetype' if (shortmess(SHM_FILEINFO)) msg_silent = 1; @@ -4762,7 +4764,7 @@ buf_reload(buf_T *buf, int orig_mode, int reload_options) curwin->w_cursor = old_cursor; check_cursor(); update_topline(); - curbuf->b_keep_filetype = FALSE; + curbuf->b_keep_filetype = false; #ifdef FEAT_FOLDING { win_T *wp; @@ -4852,8 +4854,8 @@ getfpermwfd(WIN32_FIND_DATAW *wfd, char_u *perm) return getfpermst(&st, perm); } - static char_u * -getftypewfd(WIN32_FIND_DATAW *wfd) + static void +getftypewfd(WIN32_FIND_DATAW *wfd, string_T *ret) { DWORD flag = wfd->dwFileAttributes; DWORD tag = wfd->dwReserved0; @@ -4861,20 +4863,40 @@ getftypewfd(WIN32_FIND_DATAW *wfd) if (flag & FILE_ATTRIBUTE_REPARSE_POINT) { if (tag == IO_REPARSE_TAG_MOUNT_POINT) - return (char_u*)"junction"; + { + ret->string = (char_u *)"junction"; + ret->length = STRLEN_LITERAL("junction"); + return; + } if (tag == IO_REPARSE_TAG_SYMLINK) { if (flag & FILE_ATTRIBUTE_DIRECTORY) - return (char_u*)"linkd"; + { + ret->string = (char_u *)"linkd"; + ret->length = STRLEN_LITERAL("linkd"); + return; + } - return (char_u*)"link"; + ret->string = (char_u *)"link"; + ret->length = STRLEN_LITERAL("link"); + return; } - return (char_u*)"reparse"; // unknown reparse point type - } - if (flag & FILE_ATTRIBUTE_DIRECTORY) - return (char_u*)"dir"; - return (char_u*)"file"; + // unknown reparse point type + ret->string = (char_u *)"reparse"; + ret->length = STRLEN_LITERAL("reparse"); + return; + } + + if (flag & FILE_ATTRIBUTE_DIRECTORY) + { + ret->string = (char_u *)"dir"; + ret->length = STRLEN_LITERAL("dir"); + return; + } + + ret->string = (char_u *)"file"; + ret->length = STRLEN_LITERAL("file"); } static dict_T * @@ -4884,6 +4906,7 @@ create_readdirex_item(WIN32_FIND_DATAW *wfd) char_u *p; varnumber_T size, time; char_u permbuf[] = "---------"; + string_T s; item = dict_alloc(); if (item == NULL) @@ -4911,14 +4934,15 @@ create_readdirex_item(WIN32_FIND_DATAW *wfd) if (dict_add_number(item, "time", time) == FAIL) goto theend; - if (dict_add_string(item, "type", getftypewfd(wfd)) == FAIL) + getftypewfd(wfd, &s); + if (dict_add_string_len(item, "type", s.string, (int)s.length) == FAIL) goto theend; if (dict_add_string(item, "perm", getfpermwfd(wfd, permbuf)) == FAIL) goto theend; - if (dict_add_string(item, "user", (char_u*)"") == FAIL) + if (dict_add_string_len(item, "user", (char_u *)"", 0) == FAIL) goto theend; - if (dict_add_string(item, "group", (char_u*)"") == FAIL) + if (dict_add_string_len(item, "group", (char_u *)"", 0) == FAIL) goto theend; return item; @@ -4934,11 +4958,12 @@ create_readdirex_item(char_u *path, char_u *name) dict_T *item; char *p; size_t pathlen, len; + size_t namelen; stat_T st; int ret, link = FALSE; varnumber_T size; char_u permbuf[] = "---------"; - char_u *q = NULL; + string_T q = {NULL, 0}; struct passwd *pw; struct group *gr; @@ -4948,7 +4973,8 @@ create_readdirex_item(char_u *path, char_u *name) item->dv_refcount++; pathlen = STRLEN(path); - len = pathlen + 1 + STRLEN(name) + 1; + namelen = STRLEN(name); + len = pathlen + 1 + namelen + 1; p = alloc(len); if (p == NULL) goto theend; @@ -4962,11 +4988,11 @@ create_readdirex_item(char_u *path, char_u *name) link = TRUE; ret = mch_stat(p, &st); if (ret < 0) - q = (char_u*)"link"; + STR_LITERAL_SET(q, "link"); } vim_free(p); - if (dict_add_string(item, "name", name) == FAIL) + if (dict_add_string_len(item, "name", name, (int)namelen) == FAIL) goto theend; if (ret >= 0) @@ -4985,32 +5011,41 @@ create_readdirex_item(char_u *path, char_u *name) if (link) { if (S_ISDIR(st.st_mode)) - q = (char_u*)"linkd"; + STR_LITERAL_SET(q, "linkd"); else - q = (char_u*)"link"; + STR_LITERAL_SET(q, "link"); } else - q = getftypest(&st); - if (dict_add_string(item, "type", q) == FAIL) + { + q.string = getftypest(&st); + q.length = STRLEN(q.string); + } + if (dict_add_string_len(item, "type", q.string, (int)q.length) == FAIL) goto theend; if (dict_add_string(item, "perm", getfpermst(&st, permbuf)) == FAIL) goto theend; pw = getpwuid(st.st_uid); if (pw == NULL) - q = (char_u*)""; + STR_LITERAL_SET(q, ""); else - q = (char_u*)pw->pw_name; - if (dict_add_string(item, "user", q) == FAIL) + { + q.string = (char_u *)pw->pw_name; + q.length = STRLEN(q.string); + } + if (dict_add_string_len(item, "user", q.string, (int)q.length) == FAIL) goto theend; # if !defined(VMS) || (defined(VMS) && defined(HAVE_XOS_R_H)) gr = getgrgid(st.st_gid); if (gr == NULL) - q = (char_u*)""; + STR_LITERAL_SET(q, ""); else - q = (char_u*)gr->gr_name; + { + q.string = (char_u *)gr->gr_name; + q.length = STRLEN(q.string); + } # endif - if (dict_add_string(item, "group", q) == FAIL) + if (dict_add_string_len(item, "group", q.string, (int)q.length) == FAIL) goto theend; } else @@ -5019,13 +5054,21 @@ create_readdirex_item(char_u *path, char_u *name) goto theend; if (dict_add_number(item, "time", -1) == FAIL) goto theend; - if (dict_add_string(item, "type", q == NULL ? (char_u*)"" : q) == FAIL) + if (q.string == NULL) + { + if (dict_add_string_len(item, "type", (char_u *)"", 0) == FAIL) + goto theend; + } + else + { + if (dict_add_string_len(item, "type", q.string, (int)q.length) == FAIL) + goto theend; + } + if (dict_add_string_len(item, "perm", (char_u *)"", 0) == FAIL) goto theend; - if (dict_add_string(item, "perm", (char_u*)"") == FAIL) + if (dict_add_string_len(item, "user", (char_u *)"", 0) == FAIL) goto theend; - if (dict_add_string(item, "user", (char_u*)"") == FAIL) - goto theend; - if (dict_add_string(item, "group", (char_u*)"") == FAIL) + if (dict_add_string_len(item, "group", (char_u *)"", 0) == FAIL) goto theend; } return item; diff --git a/src/filepath.c b/src/filepath.c index 4f6912a8f3..07bd0d6354 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -442,27 +442,29 @@ repeat: if (p != NULL) { + size_t dirnamelen = 0; + if (c == '.') { - size_t namelen; - mch_dirname(dirname, MAXPATHL); if (has_homerelative) { s = vim_strsave(dirname); if (s != NULL) { - home_replace(NULL, s, dirname, MAXPATHL, TRUE); + dirnamelen = home_replace(NULL, s, dirname, MAXPATHL, TRUE); vim_free(s); } } - namelen = STRLEN(dirname); + + if (dirnamelen == 0) + dirnamelen = STRLEN(dirname); // Do not call shorten_fname() here since it removes the prefix // even though the path does not have a prefix. - if (fnamencmp(p, dirname, namelen) == 0) + if (fnamencmp(p, dirname, dirnamelen) == 0) { - p += namelen; + p += dirnamelen; if (vim_ispathsep(*p)) { while (*p && vim_ispathsep(*p)) @@ -480,11 +482,11 @@ repeat: } else { - home_replace(NULL, p, dirname, MAXPATHL, TRUE); + dirnamelen = home_replace(NULL, p, dirname, MAXPATHL, TRUE); // Only replace it when it starts with '~' if (*dirname == '~') { - s = vim_strsave(dirname); + s = vim_strnsave(dirname, dirnamelen); if (s != NULL) { *fnamep = s; @@ -823,6 +825,9 @@ f_chdir(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (check_secure()) + return; + if (argvars[0].v_type != VAR_STRING) { // Returning an empty string means it failed. @@ -1727,6 +1732,8 @@ f_readdir(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) == FAIL) return; + if (check_secure()) + return; if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL @@ -1780,6 +1787,8 @@ f_readdirex(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) == FAIL) return; + if (check_secure()) + return; if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL @@ -2051,6 +2060,9 @@ read_file_or_blob(typval_T *argvars, typval_T *rettv, int always_blob) void f_readblob(typval_T *argvars, typval_T *rettv) { + if (check_secure()) + return; + if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL || check_for_opt_number_arg(argvars, 1) == FAIL @@ -2067,6 +2079,9 @@ f_readblob(typval_T *argvars, typval_T *rettv) void f_readfile(typval_T *argvars, typval_T *rettv) { + if (check_secure()) + return; + if (in_vim9script() && (check_for_nonempty_string_arg(argvars, 0) == FAIL || check_for_opt_string_arg(argvars, 1) == FAIL @@ -2711,7 +2726,7 @@ f_filecopy(typval_T *argvars, typval_T *rettv) * 'src'. * If anything fails (except when out of space) dst equals src. */ - void + size_t home_replace( buf_T *buf, // when not NULL, check for help files char_u *src, // input file name @@ -2724,21 +2739,19 @@ home_replace( size_t len; char_u *homedir_env, *homedir_env_orig; char_u *p; + char_u *dst_start; if (src == NULL) { *dst = NUL; - return; + return 0; } /* * If the file is a help file, remove the path completely. */ if (buf != NULL && buf->b_help) - { - vim_snprintf((char *)dst, dstlen, "%s", gettail(src)); - return; - } + return vim_snprintf_safelen((char *)dst, dstlen, "%s", gettail(src)); /* * We check both the value of the $HOME environment variable and the @@ -2780,6 +2793,7 @@ home_replace( if (!one) src = skipwhite(src); + dst_start = dst; // remember the start while (*src && dstlen > 0) { /* @@ -2829,6 +2843,8 @@ home_replace( if (homedir_env != homedir_env_orig) vim_free(homedir_env); + + return (size_t)(dst - dst_start); } /* @@ -4145,7 +4161,7 @@ gen_expand_wildcards( */ if ((has_env_var(p) && !(flags & EW_NOTENV)) || *p == '~') { - p = expand_env_save_opt(p, TRUE); + p = expand_env_save_opt(p, TRUE, (char_u *)PATH_ESC_WILDCARDS); if (p == NULL) p = pat[i]; #ifdef UNIX diff --git a/src/findfile.c b/src/findfile.c index 0c5d1cf252..af9523dcda 100644 --- a/src/findfile.c +++ b/src/findfile.c @@ -1808,7 +1808,7 @@ find_file_in_path_option( // copy file name into NameBuff, expanding environment variables save_char = ptr[len]; ptr[len] = NUL; - file_to_findlen = expand_env_esc(ptr, NameBuff, MAXPATHL, FALSE, TRUE, NULL); + file_to_findlen = expand_env_esc(ptr, NameBuff, MAXPATHL, NULL, TRUE, NULL); ptr[len] = save_char; vim_free(*file_to_find); @@ -2412,6 +2412,10 @@ expand_path_option( { buflen = copy_option_part(&path_option, buf, MAXPATHL, " ,"); + // do not expand backticks, could have been set via a modeline + if (vim_strchr(buf, '`') != NULL) + continue; + if (buf[0] == '.' && (buf[1] == NUL || vim_ispathsep(buf[1]))) { size_t plen; diff --git a/src/fold.c b/src/fold.c index 9618c21c62..19c444c14c 100644 --- a/src/fold.c +++ b/src/fold.c @@ -501,7 +501,7 @@ newFoldLevelWin(win_T *wp) fp = (fold_T *)wp->w_folds.ga_data; for (i = 0; i < wp->w_folds.ga_len; ++i) fp[i].fd_flags = FD_LEVEL; - wp->w_fold_manual = FALSE; + wp->w_fold_manual = false; } changed_window_setting_win(wp); } @@ -692,7 +692,7 @@ foldCreate(linenr_T start, linenr_T end) if (use_level && !closed && level < curwin->w_p_fdl) closeFold(start, 1L); if (!use_level) - curwin->w_fold_manual = TRUE; + curwin->w_fold_manual = true; fp->fd_flags = FD_CLOSED; fp->fd_small = MAYBE; @@ -805,7 +805,7 @@ deleteFold( clearFolding(win_T *win) { deleteFoldRecurse(&win->w_folds); - win->w_foldinvalid = FALSE; + win->w_foldinvalid = false; } // foldUpdate() {{{2 @@ -875,7 +875,7 @@ foldUpdate(win_T *wp, linenr_T top, linenr_T bot) void foldUpdateAll(win_T *win) { - win->w_foldinvalid = TRUE; + win->w_foldinvalid = true; redraw_win_later(win, UPD_NOT_VALID); } @@ -1219,7 +1219,7 @@ checkupdate(win_T *wp) return; foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all - wp->w_foldinvalid = FALSE; + wp->w_foldinvalid = false; } // setFoldRepeat() {{{2 @@ -1387,7 +1387,7 @@ setManualFoldWin( found->fd_flags = FD_CLOSED; done |= DONE_ACTION; } - wp->w_fold_manual = TRUE; + wp->w_fold_manual = true; if (done & DONE_ACTION) changed_window_setting_win(wp); done |= DONE_FOLD; @@ -2177,7 +2177,7 @@ foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) // Need to update all folds. top = 1; bot = wp->w_buffer->b_ml.ml_line_count; - wp->w_foldinvalid = FALSE; + wp->w_foldinvalid = false; // Mark all folds as maybe-small. setSmallMaybe(&wp->w_folds); @@ -2679,14 +2679,14 @@ foldUpdateIEMSRecurse( // The first fold depends on the containing fold. if (topflags == FD_OPEN) { - flp->wp->w_fold_manual = TRUE; + flp->wp->w_fold_manual = true; fp->fd_flags = FD_OPEN; } else if (i <= 0) { fp->fd_flags = topflags; if (topflags != FD_LEVEL) - flp->wp->w_fold_manual = TRUE; + flp->wp->w_fold_manual = true; } else fp->fd_flags = (fp - 1)->fd_flags; @@ -3548,7 +3548,7 @@ put_folds(FILE *fd, win_T *wp) { if (put_line(fd, "silent! normal! zE") == FAIL || put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL - || put_line(fd, "let &fdl = &fdl") == FAIL) + || put_line(fd, "&fdl = &fdl") == FAIL) return FAIL; } @@ -3576,7 +3576,7 @@ put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off) // Do nested folds first, they will be created closed. if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL) return FAIL; - if (fprintf(fd, "sil! %ld,%ldfold", fp->fd_top + off, + if (fprintf(fd, "sil! :%ld,%ldfold", fp->fd_top + off, fp->fd_top + off + fp->fd_len - 1) < 0 || put_eol(fd) == FAIL) return FAIL; @@ -3610,7 +3610,7 @@ put_foldopen_recurse( { // open nested folds while this fold is open // ignore errors - if (fprintf(fd, "%ld", fp->fd_top + off) < 0 + if (fprintf(fd, ":%ld", fp->fd_top + off) < 0 || put_eol(fd) == FAIL || put_line(fd, "sil! normal! zo") == FAIL) return FAIL; @@ -3651,7 +3651,7 @@ put_foldopen_recurse( static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off) { - if (fprintf(fd, "%ld", fp->fd_top + off) < 0 + if (fprintf(fd, ":%ld", fp->fd_top + off) < 0 || put_eol(fd) == FAIL || fprintf(fd, "sil! normal! z%c", fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0 diff --git a/src/fuzzy.c b/src/fuzzy.c index 9a94acea20..c8709c1079 100644 --- a/src/fuzzy.c +++ b/src/fuzzy.c @@ -31,7 +31,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - +#define USING_FLOAT_STUFF #include "vim.h" #if defined(FEAT_EVAL) || defined(FEAT_PROTO) @@ -85,6 +85,7 @@ fuzzy_match( int complete = FALSE; int score = 0; int numMatches = 0; + int pat_chars = 0; score_t fzy_score; *outScore = 0; @@ -118,6 +119,17 @@ fuzzy_match( complete = TRUE; *p = NUL; } + // match_positions() always writes pat_chars entries, + // so bail if they won't fit. + pat_chars = MB_CHARLEN(pat); + if (pat_chars > maxMatches) + pat_chars = maxMatches; + if (numMatches > maxMatches - pat_chars) + { + numMatches = 0; + *outScore = FUZZY_SCORE_NONE; + break; + } score = FUZZY_SCORE_NONE; if (has_match(pat, str)) @@ -143,7 +155,7 @@ fuzzy_match( else *outScore += score; - numMatches += MB_CHARLEN(pat); + numMatches += pat_chars; if (complete || numMatches >= maxMatches) break; @@ -690,7 +702,12 @@ fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED) { if (!VIM_ISWHITE(PTR2CHAR(p))) { - ga_grow(match_positions, 1); + if (ga_grow(match_positions, 1) == FAIL) + { + ga_clear(match_positions); + vim_free(match_positions); + return NULL; + } ((int_u *)match_positions->ga_data)[match_positions->ga_len] = matches[j]; match_positions->ga_len++; @@ -848,11 +865,15 @@ search_for_fuzzy_match( } else { - if (fuzzy_match_str(*ptr, pattern) != FUZZY_SCORE_NONE) + char_u *line = *ptr; + char_u *p = skipwhite(line); + if (fuzzy_match_str(p, pattern) != FUZZY_SCORE_NONE) { found_new_match = TRUE; *pos = current_pos; - *len = (int)ml_get_buf_len(buf, current_pos.lnum); + *ptr = p; + *len = (int)ml_get_buf_len(buf, current_pos.lnum) - + (int)(p - line); break; } } diff --git a/src/gc.c b/src/gc.c index f15d1dffe0..f1bd6b7245 100644 --- a/src/gc.c +++ b/src/gc.c @@ -208,6 +208,9 @@ garbage_collect(int testing) #ifdef FEAT_NETBEANS_INTG abort = abort || set_ref_in_nb_channel(copyID); #endif +#ifdef FEAT_SOCKETSERVER + abort = abort || set_ref_in_socketserver_channel(copyID); +#endif #ifdef FEAT_TIMERS abort = abort || set_ref_in_timer(copyID); diff --git a/src/getchar.c b/src/getchar.c index bc6a9acbc9..0c4872ec8a 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -714,6 +714,11 @@ stuffRedoReadbuff(char_u *s) void stuffReadbuffLen(char_u *s, long len) { +#ifdef FEAT_EVAL + if (add_last_insert == 1) // Only add if this is the first call, for + // recursive calls, ignore. + ga_concat_len(&last_insert_ga, s, (size_t)len); +#endif add_buff(&readbuf1, s, len); } @@ -2013,7 +2018,7 @@ vgetc(void) continue; } #endif -#if defined(FEAT_GUI) && defined(FEAT_GUI_GTK) && defined(FEAT_MENU) +#if defined(FEAT_GUI) && defined(FEAT_GUI_GTK) && !defined(USE_GTK4) && defined(FEAT_MENU) // GTK: normally selects the menu, but it's passed until // here to allow mapping it. Intercept and invoke the GTK // behavior if it's not mapped. @@ -2205,7 +2210,7 @@ vgetc(void) #ifdef FEAT_EVAL /* - * Handle the InsertCharPre autocommand. + * Handle the KeyInputPre autocommand. * "c" is the character that was typed. * Return new input character. */ @@ -2658,6 +2663,9 @@ parse_queued_messages(void) // Process the queued netbeans messages. netbeans_parse_messages(); # endif +# ifdef FEAT_SOCKETSERVER + socketserver_parse_messages(); +# endif # ifdef FEAT_JOB_CHANNEL // Write any buffer lines still to be written. channel_write_any_lines(); @@ -4296,6 +4304,13 @@ getcmdkeycmd( // to a single Esc here. if (c1 == K_ESC) c1 = ESC; + +#ifdef FEAT_GUI + // Translate K_CSI to CSI. The special key is only used to + // avoid it being recognized as the start of a special key. + if (c1 == K_CSI) + c1 = CSI; +#endif } if (got_int) diff --git a/src/globals.h b/src/globals.h index 727aec840a..d85680d444 100644 --- a/src/globals.h +++ b/src/globals.h @@ -104,6 +104,14 @@ EXTERN int redrawing_for_callback INIT(= 0); */ EXTERN short *TabPageIdxs INIT(= NULL); +// Click regions for 'tabline' (%[FuncName]). +EXTERN stl_click_region_T *tabline_stl_click INIT(= NULL); +EXTERN int tabline_stl_click_count INIT(= 0); + +// Click regions for 'tabpanel' (%[FuncName]). +EXTERN stl_click_region_T *tabpanel_stl_click INIT(= NULL); +EXTERN int tabpanel_stl_click_count INIT(= 0); + #ifdef FEAT_PROP_POPUP // Array with size Rows x Columns containing zindex of popups. EXTERN short *popup_mask INIT(= NULL); @@ -845,6 +853,8 @@ EXTERN guicolor_T cterm_normal_fg_gui_color INIT(= INVALCOLOR); EXTERN guicolor_T cterm_normal_bg_gui_color INIT(= INVALCOLOR); EXTERN guicolor_T cterm_normal_ul_gui_color INIT(= INVALCOLOR); #endif +EXTERN guicolor_T fallback_fg_rgb INIT(= INVALCOLOR); // RGB fallback foreground color from guifg, ctermfg or deduced from 'background' +EXTERN guicolor_T fallback_bg_rgb INIT(= INVALCOLOR); // RGB fallback background color from guibg, ctermbg or deduced from 'background' #ifdef FEAT_TERMRESPONSE EXTERN int is_mac_terminal INIT(= FALSE); // recognized Terminal.app #endif @@ -1086,6 +1096,7 @@ EXTERN tabpage_T *first_tabpage; EXTERN tabpage_T *curtab; EXTERN tabpage_T *lastused_tabpage; EXTERN int redraw_tabline INIT(= FALSE); // need to redraw tabline +EXTERN int redraw_vseps INIT(= FALSE); // need to redraw vseps #if defined(FEAT_TABPANEL) EXTERN int redraw_tabpanel INIT(= FALSE); // need to redraw tabpanel @@ -2117,25 +2128,28 @@ EXTERN int wayland_no_connect INIT(= FALSE); #endif -#if defined(FEAT_CLIENTSERVER) && !defined(MSWIN) +#if defined(FEAT_CLIENTSERVER) // Backend for clientserver functionality typedef enum { CLIENTSERVER_METHOD_NONE, +# ifdef FEAT_X11 CLIENTSERVER_METHOD_X11, +# endif +# ifdef MSWIN + CLIENTSERVER_METHOD_MSWIN, +# endif +# ifdef FEAT_SOCKETSERVER CLIENTSERVER_METHOD_SOCKET +# endif } clientserver_method_T; -// Default to X11 if compiled with support for it, else use socket server. -# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER) EXTERN clientserver_method_T clientserver_method -# else -// Since we aren't going to be changing clientserver_method, make it constant to -// allow compiler optimizations. -EXTERN const clientserver_method_T clientserver_method -# endif + # ifdef FEAT_X11 INIT(= CLIENTSERVER_METHOD_X11); +# elif defined(MSWIN) +INIT(= CLIENTSERVER_METHOD_MSWIN); # elif defined(FEAT_SOCKETSERVER) INIT(= CLIENTSERVER_METHOD_SOCKET); # else @@ -2160,3 +2174,11 @@ EXTERN bool inside_redraw_on_start_cb INIT(= false); // If greater than zero, then silence the W23/W24 warning. EXTERN int silence_w23_w24_msg INIT( = 0); + +#ifdef FEAT_EVAL +// Used by TextPutPost/TextPutPre autocommands for the '.' register. If +// "add_last_insert" is == 1, then "stuff_inserted" will add the last inserted +// text to "last_insert_ga". +EXTERN garray_T last_insert_ga INIT5(0, 0, 1, 64, NULL); +EXTERN int add_last_insert INIT(= 0); +#endif diff --git a/src/gui.c b/src/gui.c index 64dba3e3e7..ed26c4c471 100644 --- a/src/gui.c +++ b/src/gui.c @@ -158,13 +158,7 @@ gui_start(char_u *arg UNUSED) choose_clipmethod(); #endif -#if defined(FEAT_SOCKETSERVER) && defined(FEAT_GUI_GTK) - // Install socket server listening socket if we are running it - if (socket_server_valid()) - gui_gtk_init_socket_server(); -#endif - -#ifdef FEAT_GUI_MSWIN +#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK) // Enable fullscreen mode if (vim_strchr(p_go, GO_FULLSCREEN) != NULL) gui_mch_set_fullscreen(TRUE); @@ -198,7 +192,7 @@ gui_attempt_start(void) static int recursive = 0; ++recursive; - gui.starting = TRUE; + gui.starting = true; #ifdef FEAT_GUI_GTK gui.event_time = GDK_CURRENT_TIME; @@ -388,8 +382,8 @@ gui_read_child_pipe(int fd) void gui_prepare(int *argc, char **argv) { - gui.in_use = FALSE; // No GUI yet (maybe later) - gui.starting = FALSE; // No GUI yet (maybe later) + gui.in_use = false; // No GUI yet (maybe later) + gui.starting = false; // No GUI yet (maybe later) gui_mch_prepare(argc, argv); } @@ -412,17 +406,17 @@ gui_init_check(void) } gui.shell_created = false; - gui.dying = FALSE; - gui.in_focus = TRUE; // so the guicursor setting works + gui.dying = false; + gui.in_focus = true; // so the guicursor setting works gui.dragged_sb = SBAR_NONE; gui.dragged_wp = NULL; - gui.pointer_hidden = FALSE; + gui.pointer_hidden = false; gui.col = 0; gui.row = 0; gui.num_cols = Columns; gui.num_rows = Rows; - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; gui.scroll_region_top = 0; gui.scroll_region_bot = Rows - 1; gui.scroll_region_left = 0; @@ -457,7 +451,7 @@ gui_init_check(void) gui.menu_font = NOFONT; # endif # endif - gui.menu_is_active = TRUE; // default: include menu + gui.menu_is_active = true; // default: include menu # if !(defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM)) gui.menu_height = MENU_DEFAULT_HEIGHT; gui.menu_width = 0; @@ -674,7 +668,7 @@ gui_init(void) /* * Create the GUI shell. */ - gui.in_use = TRUE; // Must be set after menus have been set up + gui.in_use = true; // Must be set after menus have been set up if (gui_mch_init() == FAIL) goto error; @@ -785,9 +779,11 @@ gui_init(void) // It was still there to make F10 work. if (vim_strchr(p_go, GO_MENUS) == NULL) { - --gui.starting; + bool save_starting = gui.starting; + + gui.starting = false; gui_mch_enable_menu(FALSE); - ++gui.starting; + gui.starting = save_starting; gui_mch_update(); } # endif @@ -863,7 +859,7 @@ error2: #endif error: - gui.in_use = FALSE; + gui.in_use = false; clip_init(FALSE); } @@ -874,7 +870,7 @@ gui_exit(int rc) // don't free the fonts, it leads to a BUS error // richard@whitequeen.com Jul 99 free_highlight_fonts(); - gui.in_use = FALSE; + gui.in_use = false; gui_mch_exit(rc); } @@ -1183,7 +1179,7 @@ gui_check_pos(void) if (gui.col >= screen_Columns) gui.col = screen_Columns - 1; if (gui.cursor_row >= screen_Rows || gui.cursor_col >= screen_Columns) - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; } /* @@ -1249,7 +1245,7 @@ gui_update_cursor( if (gui.row >= screen_Rows || gui.col >= screen_Columns) return; - gui.cursor_is_valid = TRUE; + gui.cursor_is_valid = true; /* * How the cursor is drawn depends on the current mode. @@ -1620,6 +1616,9 @@ again: // Flush pending output before redrawing out_flush(); +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) + gui_gtk_init_decor_height(); +#endif gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width; gui.num_rows = (pixel_height - gui_get_base_height()) / gui.char_height; @@ -1681,9 +1680,11 @@ again: gui_may_resize_shell(void) { if (new_pixel_height) + { // careful: gui_resize_shell() may postpone the resize again if we // were called indirectly by it gui_resize_shell(new_pixel_width, new_pixel_height); + } } int @@ -1724,9 +1725,20 @@ gui_set_shellsize( if (!gui.shell_created) return; +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) + // Get the scrollbar width + height if possible + gui_mch_update_scrollbar_size(); +#endif + #if defined(MSWIN) || defined(FEAT_GUI_GTK) // If not setting to a user specified size and maximized, calculate the // number of characters that fit in the maximized window. + // FIXME: gui_mch_newfont() is called here even when the font hasn't + // changed at all. For example, ":set guioptions=k" triggers this path + // via gui_init_which_components() -> gui_set_shellsize(FALSE, ...). + // The intent is to keep the window size and recalculate Rows/Columns, + // which has nothing to do with fonts. This should be a separate + // function with a more descriptive name. if (!mustset && (vim_strchr(p_go, GO_KEEPWINSIZE) != NULL || gui_mch_maximized())) { @@ -1881,7 +1893,7 @@ gui_clear_block( // Invalidate cursor if it was in this block if ( gui.cursor_row >= row1 && gui.cursor_row <= row2 && gui.cursor_col >= col1 && gui.cursor_col <= col2) - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; } /* @@ -1953,7 +1965,7 @@ gui_write( case 'C': // Clear screen clip_scroll_selection(9999); gui_mch_clear_all(); - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; force_scrollbar = TRUE; break; case 'M': // Move cursor @@ -2735,7 +2747,7 @@ gui_outstr_nowrap( if (gui.cursor_row == gui.row && gui.cursor_col >= col && gui.cursor_col < col + len) - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; } #ifdef FEAT_SIGN_ICONS @@ -2776,7 +2788,7 @@ gui_undraw_cursor(void) // Cursor_is_valid is reset when the cursor is undrawn, also reset it // here in case it wasn't needed to undraw it. - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; } void @@ -2988,7 +3000,7 @@ gui_delete_lines(int row, int count) && gui.cursor_col <= gui.scroll_region_right) { if (gui.cursor_row < row + count) - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; else if (gui.cursor_row <= gui.scroll_region_bot) gui.cursor_row -= count; } @@ -3016,7 +3028,7 @@ gui_insert_lines(int row, int count) if (gui.cursor_row <= gui.scroll_region_bot - count) gui.cursor_row += count; else if (gui.cursor_row <= gui.scroll_region_bot) - gui.cursor_is_valid = FALSE; + gui.cursor_is_valid = false; } } } @@ -3555,7 +3567,9 @@ gui_init_which_components(char_u *oldval UNUSED) #ifdef FEAT_GUI_MSWIN static int prev_titlebar = FALSE; int using_titlebar = FALSE; +#endif +#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK) static int prev_fullscreen = FALSE; int using_fullscreen = FALSE; #endif @@ -3590,30 +3604,30 @@ gui_init_which_components(char_u *oldval UNUSED) p_go = temp; } } - gui.menu_is_active = FALSE; + gui.menu_is_active = false; #endif for (i = 0; i < 3; i++) - gui.which_scrollbars[i] = FALSE; + gui.which_scrollbars[i] = false; for (p = p_go; *p; p++) switch (*p) { case GO_LEFT: - gui.which_scrollbars[SBAR_LEFT] = TRUE; + gui.which_scrollbars[SBAR_LEFT] = true; break; case GO_RIGHT: - gui.which_scrollbars[SBAR_RIGHT] = TRUE; + gui.which_scrollbars[SBAR_RIGHT] = true; break; case GO_VLEFT: if (win_hasvertsplit()) - gui.which_scrollbars[SBAR_LEFT] = TRUE; + gui.which_scrollbars[SBAR_LEFT] = true; break; case GO_VRIGHT: if (win_hasvertsplit()) - gui.which_scrollbars[SBAR_RIGHT] = TRUE; + gui.which_scrollbars[SBAR_RIGHT] = true; break; case GO_BOT: - gui.which_scrollbars[SBAR_BOTTOM] = TRUE; + gui.which_scrollbars[SBAR_BOTTOM] = true; break; #ifdef FEAT_GUI_DARKTHEME case GO_DARKTHEME: @@ -3622,7 +3636,7 @@ gui_init_which_components(char_u *oldval UNUSED) #endif #ifdef FEAT_MENU case GO_MENUS: - gui.menu_is_active = TRUE; + gui.menu_is_active = true; break; #endif case GO_GREY: @@ -3632,6 +3646,8 @@ gui_init_which_components(char_u *oldval UNUSED) case GO_TITLEBAR: using_titlebar = TRUE; break; +#endif +#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK) case GO_FULLSCREEN: using_fullscreen = TRUE; break; @@ -3663,7 +3679,9 @@ gui_init_which_components(char_u *oldval UNUSED) gui_mch_set_titlebar_colors(); prev_titlebar = using_titlebar; } +#endif +#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK) if (using_fullscreen != prev_fullscreen) { gui_mch_set_fullscreen(using_fullscreen); @@ -3784,12 +3802,24 @@ gui_init_which_components(char_u *oldval UNUSED) // Don't do this while starting up though. // Don't change Rows when adding menu/toolbar/tabline. // Don't change Columns when adding vertical toolbar. - if (!gui.starting && need_set_size != (RESIZE_VERT | RESIZE_HOR)) - (void)char_avail(); - if ((need_set_size & RESIZE_VERT) == 0) - Rows = prev_Rows; - if ((need_set_size & RESIZE_HOR) == 0) - Columns = prev_Columns; + { + // Save the size gui_set_shellsize() determined before + // char_avail() processes spurious configure events that may + // corrupt Rows/Columns. + long post_Rows = Rows; + long post_Columns = Columns; + + if (!gui.starting && need_set_size != (RESIZE_VERT | RESIZE_HOR)) + (void)char_avail(); + if ((need_set_size & RESIZE_VERT) == 0) + Rows = prev_Rows; + else + Rows = post_Rows; + if ((need_set_size & RESIZE_HOR) == 0) + Columns = prev_Columns; + else + Columns = post_Columns; + } #endif } // When the console tabline appears or disappears the window positions @@ -3840,14 +3870,29 @@ gui_update_tabline(void) out_flush(); if (!showit != !shown) + { + // Save Rows/Columns before showing/hiding the tabline. + // gui_mch_show_tabline() processes GTK events (via + // gui_mch_update) which may trigger a spurious configure event + // that temporarily corrupts Rows. Restore the original values so + // that gui_set_shellsize() uses the correct row/column count. + int save_Rows = Rows; + int save_Columns = Columns; + gui_mch_show_tabline(showit); + Rows = save_Rows; + Columns = save_Columns; + + // Resize the outer window to compensate for the tabline height + // change. This is also needed when called from draw_tabline() + // (e.g. after :tabclose), where no caller will do the resize. + // When called from gui_init_which_components() the subsequent + // gui_set_shellsize() call will redo this to the same dimensions, + // which is harmless. + gui_set_shellsize(FALSE, showit, RESIZE_VERT); + } if (showit != 0) gui_mch_update_tabline(); - - // When the tabs change from hidden to shown or from shown to - // hidden the size of the text area should remain the same. - if (!showit != !shown) - gui_set_shellsize(FALSE, showit, RESIZE_VERT); } } @@ -3888,7 +3933,7 @@ get_tabline_label( // Can't use NameBuff directly, build_stl_str_hl() uses it. build_stl_str_hl(curwin, res, MAXPATHL, *opt, opt_name, 0, - 0, (int)Columns, NULL, NULL); + 0, (int)Columns, NULL, NULL, NULL); STRCPY(NameBuff, res); // Back to the original curtab. diff --git a/src/gui.h b/src/gui.h index 56b5cc1613..1fcf374f6d 100644 --- a/src/gui.h +++ b/src/gui.h @@ -15,7 +15,17 @@ # ifdef VMS # include "gui_gtk_vms.h" # endif -# include +# ifdef USE_GTK4 +// Types used in proto files but not available without X11 headers +typedef void *Widget; +typedef void *XtAppContext; +typedef void Display; +typedef unsigned long Window; +typedef unsigned long Atom; +typedef GdkEvent GdkEventKey; // GTK4: GdkEventKey merged into GdkEvent +# else +# include +# endif # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wstrict-prototypes" # include @@ -249,23 +259,23 @@ typedef long guicolor_T; // handle for a GUI color; for X11 this should typedef struct Gui { - int in_focus; // Vim has input focus - int in_use; // Is the GUI being used? - int starting; // GUI will start in a little while + bool in_focus; // Vim has input focus + bool in_use; // Is the GUI being used? + bool starting; // GUI will start in a little while bool shell_created; // Has the shell been created yet? - int dying; // Is vim dying? Then output to terminal - int dofork; // Use fork() when GUI is starting + bool dying; // Is vim dying? Then output to terminal + bool dofork; // Use fork() when GUI is starting #ifdef GUI_MAY_SPAWN - int dospawn; // Use spawn() when GUI is starting + bool dospawn; // Use spawn() when GUI is starting #endif int dragged_sb; // Which scrollbar being dragged, if any? win_T *dragged_wp; // Which WIN's sb being dragged, if any? - int pointer_hidden; // Is the mouse pointer hidden? + bool pointer_hidden; // Is the mouse pointer hidden? int col; // Current cursor column in GUI display int row; // Current cursor row in GUI display int cursor_col; // Physical cursor column in GUI display int cursor_row; // Physical cursor row in GUI display - char cursor_is_valid; // There is a cursor at cursor_row/col + bool cursor_is_valid; // There is a cursor at cursor_row/col int num_cols; // Number of columns int num_rows; // Number of rows int scroll_region_top; // Top (first) line of scroll region @@ -277,9 +287,9 @@ typedef struct Gui int scrollbar_height; // Height of horizontal scrollbar int left_sbar_x; // Calculated x coord for left scrollbar int right_sbar_x; // Calculated x coord for right scrollbar - int force_redraw; // Force a redraw even e.g. not resized + bool force_redraw; // Force a redraw even e.g. not resized #ifdef FEAT_DIRECTX - int directx_enabled; // DirectX (DirectWrite) rendering active + bool directx_enabled; // DirectX (DirectWrite) rendering active #endif #ifdef FEAT_MENU @@ -287,11 +297,11 @@ typedef struct Gui int menu_height; // Height of the menu bar int menu_width; // Width of the menu bar # endif - char menu_is_active; // TRUE if menu is present + bool menu_is_active; // true if menu is present #endif scrollbar_T bottom_sbar; // Bottom scrollbar - int which_scrollbars[3];// Which scrollbar boxes are active? + bool which_scrollbars[3];// Which scrollbar boxes are active? int prev_wrap; // For updating the horizontal scrollbar int char_width; // Width of char cell in pixels int char_height; // Height of char cell in pixels, includes @@ -306,7 +316,7 @@ typedef struct Gui GuiFont ital_font; // Italic font GuiFont boldital_font; // Bold-Italic font #else - int font_can_bold; // Whether norm_font supports bold weight. + bool font_can_bold; // Whether norm_font supports bold weight. // The styled font variants are not used. #endif @@ -359,11 +369,10 @@ typedef struct Gui Bool rsrc_rev_video; // Use reverse video? char_u *geom; // Geometry, eg "80x24" - Bool color_approx; // Some color was approximated #endif #ifdef FEAT_GUI_GTK -# ifndef USE_GTK3 +# if !defined(USE_GTK3) && !defined(USE_GTK4) int visibility; // Is shell partially/fully obscured? # endif GdkCursor *blank_pointer; // Blank pointer @@ -384,7 +393,7 @@ typedef struct Gui GtkWidget *menubar_h; // menubar handle GtkWidget *toolbar_h; // toolbar handle # endif -# ifdef USE_GTK3 +# if defined(USE_GTK3) || defined(USE_GTK4) GdkRGBA *fgcolor; // GDK-styled foreground color GdkRGBA *bgcolor; // GDK-styled background color GdkRGBA *spcolor; // GDK-styled special color @@ -393,7 +402,7 @@ typedef struct Gui GdkColor *bgcolor; // GDK-styled background color GdkColor *spcolor; // GDK-styled special color # endif -# ifdef USE_GTK3 +# if defined(USE_GTK3) || defined(USE_GTK4) cairo_surface_t *surface; // drawarea surface # else GdkGC *text_gc; // cached GC for normal text @@ -405,7 +414,9 @@ typedef struct Gui GtkWidget *tabline; // tab pages line handle # endif +# ifndef USE_GTK4 GtkAccelGroup *accel_group; +# endif GtkWidget *filedlg; // file selection dialog char_u *browse_fname; // file name from filedlg @@ -486,6 +497,10 @@ typedef struct Gui #ifdef FEAT_GUI_SCROLL_WHEEL_FORCE int scroll_wheel_force; #endif + +#if defined(FEAT_GUI_GTK) && defined(USE_GTK4) + int decor_height; +#endif } gui_T; extern gui_T gui; // this is defined in gui.c @@ -576,7 +591,7 @@ typedef enum * For Solaris Studio, that is not the case. An explicit type cast is needed * to suppress warnings on that particular conversion. */ -# if defined(__SUNPRO_C) && defined(USE_GTK3) +# if defined(__SUNPRO_C) && (defined(USE_GTK3) || defined(USE_GTK4)) # define FUNC2GENERIC(func) (void *)(func) # else # define FUNC2GENERIC(func) G_CALLBACK(func) diff --git a/src/gui_beval.c b/src/gui_beval.c index d3c0ee39a5..fd29697168 100644 --- a/src/gui_beval.c +++ b/src/gui_beval.c @@ -16,7 +16,9 @@ #if !(defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MACVIM)) # ifdef FEAT_GUI_GTK -# if GTK_CHECK_VERSION(3,0,0) +# ifdef USE_GTK4 +# include +# elif GTK_CHECK_VERSION(3,0,0) # include # else # include @@ -390,7 +392,11 @@ pointer_event(BalloonEval *beval, int x, int y, unsigned state) beval->x = x; beval->y = y; +# ifdef USE_GTK4 + if (state & (int)GDK_ALT_MASK) +# else if (state & (int)GDK_MOD1_MASK) +# endif { /* * Alt is pressed -- enter super-evaluate-mode, @@ -416,14 +422,24 @@ key_event(BalloonEval *beval, unsigned keyval, int is_keypress) { switch (keyval) { +# ifdef USE_GTK4 + case GDK_KEY_Shift_L: + case GDK_KEY_Shift_R: +# else case GDK_Shift_L: case GDK_Shift_R: +# endif beval->showState = ShS_UPDATE_PENDING; (*beval->msgCB)(beval, (is_keypress) ? (int)GDK_SHIFT_MASK : 0); break; +# ifdef USE_GTK4 + case GDK_KEY_Control_L: + case GDK_KEY_Control_R: +# else case GDK_Control_L: case GDK_Control_R: +# endif beval->showState = ShS_UPDATE_PENDING; (*beval->msgCB)(beval, (is_keypress) ? (int)GDK_CONTROL_MASK : 0); diff --git a/src/gui_gtk.c b/src/gui_gtk.c index 77f96179e1..84eae6d41b 100644 --- a/src/gui_gtk.c +++ b/src/gui_gtk.c @@ -2611,3 +2611,12 @@ recent_func_log_func(const gchar *log_domain UNUSED, // http://bugzilla.gnome.org/show_bug.cgi?id=664587 } #endif + + void +gui_mch_set_fullscreen(int flag) +{ + if (flag) + gtk_window_fullscreen(GTK_WINDOW(gui.mainwin)); + else + gtk_window_unfullscreen(GTK_WINDOW(gui.mainwin)); +} diff --git a/src/gui_gtk4.c b/src/gui_gtk4.c new file mode 100644 index 0000000000..c3c6f6cc69 --- /dev/null +++ b/src/gui_gtk4.c @@ -0,0 +1,5307 @@ +/* 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. + * + * GTK4 GUI implementation: main window, events, drawing, menus, + * scrollbars, dialogs, and toolbar. This is a clean implementation for + * GTK4, separate from gui_gtk_x11.c which handles GTK2/GTK3. + * + * GTK4 differences from GTK3: + * - No GdkWindow (use GdkSurface for top-level only) + * - No GtkContainer (use gtk_widget_set_parent/gtk_box_append) + * - Events via GtkEventController, not signal+mask + * - Drawing via GtkSnapshot or gtk_drawing_area_set_draw_func + * - No gtk_dialog_run (async dialogs) + * - No GdkAtom (string-based content types) + * - No GtkSocket/GtkPlug + * - gtk_window_new() takes no arguments + */ + +#include "vim.h" + +#ifdef FEAT_GUI_GTK + +#include +#include +#include +#include "gui_gtk4_f.h" + +/* + * Geometry string parser, replacing XParseGeometry to remove X11 dependency. + * Format: [WIDTHxHEIGHT][{+-}XOFF{+-}YOFF] + */ +#define NoValue 0x0000 +#define XValue 0x0001 +#define YValue 0x0002 +#define WidthValue 0x0004 +#define HeightValue 0x0008 +#define XNegative 0x0010 +#define YNegative 0x0020 + + static int +vim_parse_geometry(const char *str, int *x, int *y, + unsigned int *width, unsigned int *height) +{ + int mask = NoValue; + char *end; + long val; + + if (str == NULL || *str == NUL) + return mask; + + // Parse width + if (*str != '+' && *str != '-') + { + val = strtol(str, &end, 10); + if (end != str) + { + *width = (unsigned int)val; + mask |= WidthValue; + str = end; + } + } + + // Parse 'x' or 'X' separator and height + if (*str == 'x' || *str == 'X') + { + str++; + val = strtol(str, &end, 10); + if (end != str) + { + *height = (unsigned int)val; + mask |= HeightValue; + str = end; + } + } + + // Parse x offset + if (*str == '+' || *str == '-') + { + int negative = (*str == '-'); + str++; + val = strtol(str, &end, 10); + if (end != str) + { + *x = negative ? -(int)val : (int)val; + mask |= XValue; + if (negative) + mask |= XNegative; + str = end; + } + } + + // Parse y offset + if (*str == '+' || *str == '-') + { + int negative = (*str == '-'); + str++; + val = strtol(str, &end, 10); + if (end != str) + { + *y = negative ? -(int)val : (int)val; + mask |= YValue; + if (negative) + mask |= YNegative; + } + } + + return mask; +} + +#if defined(FEAT_MOUSESHAPE) +// Last set mouse pointer shape +static int last_shape = 0; +#endif + +#define DEFAULT_FONT "Monospace 10" + +// Menu action group for GMenu-based menus +static GSimpleActionGroup *menu_action_group = NULL; + +// Cursor blinking state +static enum { + BLINK_NONE, + BLINK_OFF, + BLINK_ON +} blink_state = BLINK_NONE; + +// GTK4 main loop compatibility +static int gtk4_main_loop_level = 0; +static int gtk4_main_loop_quit = FALSE; + +#ifdef USE_GRESOURCE +# include "auto/gui_gtk_gresources.h" +#endif + +typedef gboolean timeout_cb_type; + +/* + * Table of special key mappings. + */ +static struct special_key +{ + guint key_sym; + char_u code0; + char_u code1; +} +const special_keys[] = +{ + {GDK_KEY_Up, 'k', 'u'}, + {GDK_KEY_Down, 'k', 'd'}, + {GDK_KEY_Left, 'k', 'l'}, + {GDK_KEY_Right, 'k', 'r'}, + {GDK_KEY_F1, 'k', '1'}, + {GDK_KEY_F2, 'k', '2'}, + {GDK_KEY_F3, 'k', '3'}, + {GDK_KEY_F4, 'k', '4'}, + {GDK_KEY_F5, 'k', '5'}, + {GDK_KEY_F6, 'k', '6'}, + {GDK_KEY_F7, 'k', '7'}, + {GDK_KEY_F8, 'k', '8'}, + {GDK_KEY_F9, 'k', '9'}, + {GDK_KEY_F10, 'k', ';'}, + {GDK_KEY_F11, 'F', '1'}, + {GDK_KEY_F12, 'F', '2'}, + {GDK_KEY_Help, '%', '1'}, + {GDK_KEY_Undo, '&', '8'}, + {GDK_KEY_BackSpace, 'k', 'b'}, + {GDK_KEY_Insert, 'k', 'I'}, + {GDK_KEY_Delete, 'k', 'D'}, + {GDK_KEY_Home, 'k', 'h'}, + {GDK_KEY_End, '@', '7'}, + {GDK_KEY_Prior, 'k', 'P'}, + {GDK_KEY_Next, 'k', 'N'}, + {GDK_KEY_Print, '%', '9'}, + {GDK_KEY_KP_Left, 'k', 'l'}, + {GDK_KEY_KP_Right, 'k', 'r'}, + {GDK_KEY_KP_Up, 'k', 'u'}, + {GDK_KEY_KP_Down, 'k', 'd'}, + {GDK_KEY_KP_Insert, KS_EXTRA, (char_u)KE_KINS}, + {GDK_KEY_KP_Delete, KS_EXTRA, (char_u)KE_KDEL}, + {GDK_KEY_KP_Home, 'K', '1'}, + {GDK_KEY_KP_End, 'K', '4'}, + {GDK_KEY_KP_Prior, 'K', '3'}, + {GDK_KEY_KP_Next, 'K', '5'}, + {GDK_KEY_KP_Add, 'K', '6'}, + {GDK_KEY_KP_Subtract, 'K', '7'}, + {GDK_KEY_KP_Divide, 'K', '8'}, + {GDK_KEY_KP_Multiply, 'K', '9'}, + {GDK_KEY_KP_Enter, 'K', 'A'}, + {GDK_KEY_KP_Decimal, 'K', 'B'}, + {GDK_KEY_KP_0, 'K', 'C'}, + {GDK_KEY_KP_1, 'K', 'D'}, + {GDK_KEY_KP_2, 'K', 'E'}, + {GDK_KEY_KP_3, 'K', 'F'}, + {GDK_KEY_KP_4, 'K', 'G'}, + {GDK_KEY_KP_5, 'K', 'H'}, + {GDK_KEY_KP_6, 'K', 'I'}, + {GDK_KEY_KP_7, 'K', 'J'}, + {GDK_KEY_KP_8, 'K', 'K'}, + {GDK_KEY_KP_9, 'K', 'L'}, + {0, 0, 0} +}; + + static int +keyval_to_string(unsigned int keyval, char_u *string) +{ + int len; + guint32 uc; + + uc = gdk_keyval_to_unicode(keyval); + if (uc != 0) + { + len = utf_char2bytes((int)uc, string); + } + else + { + len = 1; + switch (keyval) + { + case GDK_KEY_Tab: case GDK_KEY_KP_Tab: case GDK_KEY_ISO_Left_Tab: + string[0] = TAB; + break; + case GDK_KEY_Linefeed: + string[0] = NL; + break; + case GDK_KEY_Return: case GDK_KEY_ISO_Enter: case GDK_KEY_3270_Enter: + string[0] = CAR; + break; + case GDK_KEY_Escape: + string[0] = ESC; + break; + default: + len = 0; + break; + } + } + string[len] = NUL; + return len; +} + + static int +modifiers_gdk2vim(guint state) +{ + int modifiers = 0; + + if (state & GDK_SHIFT_MASK) + modifiers |= MOD_MASK_SHIFT; + if (state & GDK_CONTROL_MASK) + modifiers |= MOD_MASK_CTRL; + if (state & GDK_ALT_MASK) + modifiers |= MOD_MASK_ALT; + if (state & GDK_META_MASK) + modifiers |= MOD_MASK_META; + if (state & GDK_SUPER_MASK) + modifiers |= MOD_MASK_CMD; + + return modifiers; +} + +static GtkWidget *vbox; // the main vertical box + +// Forward declarations for event callbacks +static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height, gpointer data); +static gboolean key_press_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data); +static void key_release_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data); +static void button_press_event(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data); +static void button_release_event(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data); +static void motion_notify_event(GtkEventControllerMotion *controller, double x, double y, gpointer data); +static void enter_notify_event(GtkEventControllerMotion *controller, double x, double y, gpointer data); +static void leave_notify_event(GtkEventControllerMotion *controller, gpointer data); +static gboolean scroll_event(GtkEventControllerScroll *controller, double dx, double dy, gpointer data); +static void focus_in_event(GtkEventControllerFocus *controller, gpointer data); +static void focus_out_event(GtkEventControllerFocus *controller, gpointer data); +#ifdef FEAT_MENU +static gboolean menubar_popover_closed_hook(GSignalInvocationHint *ihint, guint n_param_values, const GValue *param_values, gpointer data); +#endif +#ifdef FEAT_DND +static gboolean drop_cb(GtkDropTarget *target, const GValue *value, double x, double y, gpointer data); +#endif +#ifdef FEAT_GUI_TABLINE +static void on_select_tab(GtkNotebook *notebook, gpointer *page, gint idx, gpointer data); +static void on_tab_reordered(GtkNotebook *notebook, gpointer *page, gint idx, gpointer data); +#endif +static void mainwin_destroy_cb(GObject *object, gpointer data); +static gboolean delete_event_cb(GtkWindow *window, gpointer data); +static void mainwin_fullscreened_cb(GObject *obj, GParamSpec *pspec, gpointer user_data); +static void drawarea_realize_cb(GtkWidget *widget, gpointer data); +static void drawarea_unrealize_cb(GtkWidget *widget, gpointer data); +static void drawarea_resize_cb(GtkDrawingArea *area, int width, int height, gpointer data); +static void drawarea_scale_factor_cb(GObject *object, GParamSpec *pspec, gpointer data); +static cairo_surface_t *create_backing_surface(int width, int height); +static void clipboard_changed_cb(GdkClipboard *clipboard, gpointer user_data); +#ifdef FEAT_MENU +static void show_menubar_popover(void); +#endif + +/* + * Parse the GUI related command-line arguments. Any arguments used are + * deleted from argv, and *argc is decremented accordingly. This is called + * when vim is started, whether or not the GUI has been started. + */ + void +gui_mch_prepare(int *argc, char **argv) +{ + // Don't call gtk_init() here. It will be called in + // gui_mch_init_check() after the fork. Calling it before fork + // breaks the display connection in the child process, causing gvim + // to fail to start without --nofork. +} + +/* + * Free all GUI related resources. + */ + void +gui_mch_free_all(void) +{ +} + + static guint +timeout_add(int time, timeout_cb_type (*callback)(gpointer), int *flagp) +{ + return g_timeout_add((guint)time, (GSourceFunc)callback, flagp); +} + + static void +timeout_remove(guint timer) +{ + g_source_remove(timer); +} + +static long_u blink_waittime = 700; +static long_u blink_ontime = 400; +static long_u blink_offtime = 250; +static guint blink_timer = 0; + + static timeout_cb_type +blink_cb(gpointer data UNUSED) +{ + if (blink_state == BLINK_ON) + { + gui_undraw_cursor(); + blink_state = BLINK_OFF; + blink_timer = timeout_add(blink_offtime, blink_cb, NULL); + } + else + { + gui_update_cursor(TRUE, FALSE); + blink_state = BLINK_ON; + blink_timer = timeout_add(blink_ontime, blink_cb, NULL); + } + return FALSE; +} + + int +gui_mch_is_blinking(void) +{ + return blink_state != BLINK_NONE; +} + + int +gui_mch_is_blink_off(void) +{ + return blink_state == BLINK_OFF; +} + + void +gui_mch_set_blinking(long waittime, long on, long off) +{ + blink_waittime = waittime; + blink_ontime = on; + blink_offtime = off; +} + + void +gui_mch_stop_blink(int may_call_gui_update_cursor) +{ + if (blink_timer) + { + timeout_remove(blink_timer); + blink_timer = 0; + } + if (blink_state == BLINK_OFF && may_call_gui_update_cursor) + gui_update_cursor(TRUE, FALSE); + blink_state = BLINK_NONE; +} + + void +gui_mch_start_blink(void) +{ + if (blink_timer) + { + timeout_remove(blink_timer); + blink_timer = 0; + } + if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) + { + blink_timer = timeout_add(blink_waittime, blink_cb, NULL); + blink_state = BLINK_ON; + gui_update_cursor(TRUE, FALSE); + } +} + + int +gui_mch_early_init_check(int give_message UNUSED) +{ + return OK; +} + + int +gui_mch_init_check(void) +{ + // This defaults to argv[0], but we want it to match the name of the + // shipped gvim.desktop so that Vim's windows can be associated with this + // file. Also sets WM_CLASS on X11. + g_set_prgname("gvim"); + + // Suppress noisy EGL warnings when GL is not available. Only set + // this when actually starting the GUI, so non-GUI invocations are + // not affected. + if (g_getenv("EGL_LOG_LEVEL") == NULL) + setenv("EGL_LOG_LEVEL", "fatal", 0); + + // Call gtk_init() here after fork(). Calling it before fork() breaks + // the display connection in the child process. + gtk_init(); + return OK; +} + +/* + * Initialise the GUI. Create all the windows, set up all the callbacks etc. + * Returns OK for success, FAIL when the GUI can't be started. + */ + int +gui_mch_init(void) +{ + // Allocate GdkRGBA color structs. + gui.fgcolor = g_new(GdkRGBA, 1); + gui.bgcolor = g_new(GdkRGBA, 1); + gui.spcolor = g_new(GdkRGBA, 1); + + gui.def_norm_pixel = 0x00000000; // black + gui.def_back_pixel = 0x00ffffff; // white + gui.norm_pixel = gui.def_norm_pixel; + gui.back_pixel = gui.def_back_pixel; + + gui.scrollbar_width = SB_DEFAULT_WIDTH; + gui.scrollbar_height = SB_DEFAULT_WIDTH; + + // Create the main window. + gui.mainwin = gtk_window_new(); + gtk_widget_set_name(gui.mainwin, "vim-main-window"); + + // Create the PangoContext used for drawing all text. + gui.text_context = gtk_widget_create_pango_context(gui.mainwin); + pango_context_set_base_dir(gui.text_context, PANGO_DIRECTION_LTR); + + g_signal_connect(G_OBJECT(gui.mainwin), "close-request", + G_CALLBACK(delete_event_cb), NULL); + g_signal_connect(G_OBJECT(gui.mainwin), "notify::fullscreened", + G_CALLBACK(mainwin_fullscreened_cb), NULL); + + // A vertical box holds the menubar, toolbar and main text window. + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE); + gtk_window_set_child(GTK_WINDOW(gui.mainwin), vbox); + +#ifdef FEAT_MENU + { + GMenu *gmenu = g_menu_new(); + gui.menubar = gtk_popover_menu_bar_new_from_model( + G_MENU_MODEL(gmenu)); + g_object_set_data_full(G_OBJECT(gui.menubar), "vim-gmenu", + gmenu, g_object_unref); + gtk_widget_set_name(gui.menubar, "vim-menubar"); + gtk_widget_set_visible(gui.menubar, FALSE); + gtk_box_append(GTK_BOX(vbox), gui.menubar); + } + // Return keyboard focus to the drawing area when a menubar popover + // closes (issue #20274). GtkPopoverMenuBar owns its popovers + // privately, so attach via an emission hook on GtkPopover::closed + // and filter for popovers under our menubar inside the callback. + { + GTypeClass *cls = g_type_class_ref(GTK_TYPE_POPOVER); + guint sig_id = g_signal_lookup("closed", GTK_TYPE_POPOVER); + + if (sig_id != 0) + g_signal_add_emission_hook(sig_id, 0, + menubar_popover_closed_hook, NULL, NULL); + if (cls != NULL) + g_type_class_unref(cls); + } +#endif + +#ifdef FEAT_TOOLBAR + gui.toolbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_name(gui.toolbar, "vim-toolbar"); + gtk_widget_set_visible(gui.toolbar, FALSE); + gtk_box_append(GTK_BOX(vbox), gui.toolbar); +#endif + +#ifdef FEAT_GUI_TABLINE + gui.tabline = gtk_notebook_new(); + gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), TRUE); + gtk_notebook_set_scrollable(GTK_NOTEBOOK(gui.tabline), TRUE); + gtk_widget_set_visible(gui.tabline, FALSE); + gtk_box_append(GTK_BOX(vbox), gui.tabline); + + g_signal_connect(G_OBJECT(gui.tabline), "switch-page", + G_CALLBACK(on_select_tab), NULL); + g_signal_connect(G_OBJECT(gui.tabline), "page-reordered", + G_CALLBACK(on_tab_reordered), NULL); +#endif + + // The form widget manages absolute positioning of scrollbars and the draw + // area. + gui.formwin = vim_form_new(); + gtk_widget_set_name(gui.formwin, "vim-gtk-form"); + gtk_widget_set_vexpand(gui.formwin, TRUE); + gtk_widget_set_hexpand(gui.formwin, TRUE); + gtk_box_append(GTK_BOX(vbox), gui.formwin); + + // The drawing area for the editor content. + gui.drawarea = gtk_drawing_area_new(); + gui.surface = NULL; + gtk_widget_set_focusable(gui.drawarea, TRUE); + gtk_widget_set_vexpand(gui.drawarea, TRUE); + gtk_widget_set_hexpand(gui.drawarea, TRUE); + vim_form_put(VIM_FORM(gui.formwin), gui.drawarea, 0, 0); + + // Set up drawing. + gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(gui.drawarea), + (GtkDrawingAreaDrawFunc)draw_event, NULL, NULL); + + g_signal_connect(G_OBJECT(gui.drawarea), "realize", + G_CALLBACK(drawarea_realize_cb), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "unrealize", + G_CALLBACK(drawarea_unrealize_cb), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "resize", + G_CALLBACK(drawarea_resize_cb), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "notify::scale-factor", + G_CALLBACK(drawarea_scale_factor_cb), NULL); + + // Set up event controllers. + { + GtkEventController *key_ctrl = gtk_event_controller_key_new(); + g_signal_connect(key_ctrl, "key-pressed", + G_CALLBACK(key_press_event), NULL); + g_signal_connect(key_ctrl, "key-released", + G_CALLBACK(key_release_event), NULL); + gtk_widget_add_controller(gui.drawarea, key_ctrl); +#ifdef FEAT_XIM + xim_init(); +#endif + } + + { + GtkGesture *click = gtk_gesture_click_new(); + gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(click), 0); + g_signal_connect(click, "pressed", + G_CALLBACK(button_press_event), NULL); + g_signal_connect(click, "released", + G_CALLBACK(button_release_event), NULL); + gtk_widget_add_controller(gui.drawarea, GTK_EVENT_CONTROLLER(click)); + } + + { + GtkEventController *motion = gtk_event_controller_motion_new(); + g_signal_connect(motion, "motion", + G_CALLBACK(motion_notify_event), NULL); + g_signal_connect(motion, "enter", + G_CALLBACK(enter_notify_event), NULL); + g_signal_connect(motion, "leave", + G_CALLBACK(leave_notify_event), NULL); + gtk_widget_add_controller(gui.drawarea, motion); + } + + { + GtkEventController *scroll = gtk_event_controller_scroll_new( + GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES + | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE); + g_signal_connect(scroll, "scroll", + G_CALLBACK(scroll_event), NULL); + gtk_widget_add_controller(gui.drawarea, scroll); + } + + { + GtkEventController *focus = gtk_event_controller_focus_new(); + g_signal_connect(focus, "enter", + G_CALLBACK(focus_in_event), NULL); + g_signal_connect(focus, "leave", + G_CALLBACK(focus_out_event), NULL); + gtk_widget_add_controller(gui.drawarea, focus); + } + +#ifdef FEAT_DND + // Set up drag-and-drop target for files and text. + { + GtkDropTarget *drop = gtk_drop_target_new(G_TYPE_INVALID, GDK_ACTION_COPY); + GType types[] = { GDK_TYPE_FILE_LIST, G_TYPE_STRING }; + gtk_drop_target_set_gtypes(drop, types, 2); + g_signal_connect(drop, "drop", + G_CALLBACK(drop_cb), NULL); + gtk_widget_add_controller(gui.drawarea, GTK_EVENT_CONTROLLER(drop)); + } +#endif + + gui.border_offset = gui.border_width; + + // Create a blank (invisible) cursor for hiding the mouse pointer. + gui.blank_pointer = gdk_cursor_new_from_name("none", NULL); + + { + GdkDisplay *display = gtk_widget_get_display(gui.mainwin); + GdkClipboard *primary = gdk_display_get_primary_clipboard(display); + GdkClipboard *board = gdk_display_get_clipboard(display); + + if (primary != NULL) + g_signal_connect(primary, "changed", + G_CALLBACK(clipboard_changed_cb), &clip_star); + if (board != NULL) + g_signal_connect(board, "changed", + G_CALLBACK(clipboard_changed_cb), &clip_plus); + } + + return OK; +} + +/* + * Called when the foreground or background color has been changed. + */ + static void +surface_fill_bg(void) +{ + if (gui.surface != NULL) + { + cairo_t *cr = cairo_create(gui.surface); + cairo_set_source_rgba(cr, + gui.bgcolor->red, gui.bgcolor->green, + gui.bgcolor->blue, gui.bgcolor->alpha); + cairo_paint(cr); + cairo_destroy(cr); + } +} + + void +gui_mch_new_colors(void) +{ + surface_fill_bg(); + if (gui.drawarea != NULL && gtk_widget_get_realized(gui.drawarea)) + gtk_widget_queue_draw(gui.drawarea); +} + +/* + * Open the GUI window which was created by a call to gui_mch_init(). + */ + int +gui_mch_open(void) +{ + guicolor_T fg_pixel = INVALCOLOR; + guicolor_T bg_pixel = INVALCOLOR; + guint pixel_width; + guint pixel_height; + + if (gui.geom != NULL) + { + int mask; + unsigned int w, h; + int x = 0; + int y = 0; + + mask = vim_parse_geometry((char *)gui.geom, &x, &y, &w, &h); + + if (mask & WidthValue) + Columns = w; + if (mask & HeightValue) + { + if (p_window > (long)h - 1 || !option_was_set((char_u *)"window")) + p_window = h - 1; + Rows = h; + } + limit_screen_size(); + + VIM_CLEAR(gui.geom); + } + + // Use 80x24 as the default GUI size, unless geometry was specified. + if (Columns > 80 && gui.geom == NULL) + Columns = 80; + if (Rows > 24 && gui.geom == NULL) + Rows = 24; + pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width); + pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height); + gtk_window_set_default_size(GTK_WINDOW(gui.mainwin), + pixel_width, pixel_height); + + if (foreground_argument != NULL) + fg_pixel = gui_get_color((char_u *)foreground_argument); + if (fg_pixel == INVALCOLOR) + fg_pixel = gui_get_color((char_u *)"Black"); + + if (background_argument != NULL) + bg_pixel = gui_get_color((char_u *)background_argument); + if (bg_pixel == INVALCOLOR) + bg_pixel = gui_get_color((char_u *)"White"); + + if (found_reverse_arg) + { + gui.def_norm_pixel = bg_pixel; + gui.def_back_pixel = fg_pixel; + } + else + { + gui.def_norm_pixel = fg_pixel; + gui.def_back_pixel = bg_pixel; + } + + set_normal_colors(); + gui_check_colors(); + highlight_gui_started(); + + g_signal_connect(G_OBJECT(gui.mainwin), "destroy", + G_CALLBACK(mainwin_destroy_cb), NULL); + // Resize is handled by GtkForm's size_allocate callback. + + gtk_widget_set_visible(gui.mainwin, TRUE); + + // Make sure the drawing area gets keyboard focus. + gtk_widget_grab_focus(gui.drawarea); + gui_focus_change(TRUE); + + return OK; +} + + void +gui_mch_exit(int rc UNUSED) +{ + if (gui.mainwin != NULL) + gtk_window_destroy(GTK_WINDOW(gui.mainwin)); +} + + int +gui_mch_get_winpos(int *x, int *y) +{ + // GTK4 does not provide a window position API. + *x = 0; + *y = 0; + return FAIL; +} + + void +gui_mch_set_winpos(int x UNUSED, int y UNUSED) +{ + // GTK4/Wayland: window positioning not available +} + + int +gui_mch_maximized(void) +{ + return gtk_window_is_maximized(GTK_WINDOW(gui.mainwin)); +} + + void +gui_mch_unmaximize(void) +{ + if (gui.mainwin != NULL) + gtk_window_unmaximize(GTK_WINDOW(gui.mainwin)); +} + + void +gui_mch_set_fullscreen(int flag) +{ + if (gui.mainwin == NULL) + return; + if (flag) + gtk_window_fullscreen(GTK_WINDOW(gui.mainwin)); + else + gtk_window_unfullscreen(GTK_WINDOW(gui.mainwin)); +} + + static void +mainwin_fullscreened_cb(GObject *obj, + GParamSpec *pspec UNUSED, gpointer user_data UNUSED) +{ + // Force a redraw of the drawing area when entering fullscreen mode. + if (gtk_window_is_fullscreen(GTK_WINDOW(obj))) + gui_focus_change(TRUE); +} + +/* + * Called when the font changed while the window is maximized or GO_KEEPWINSIZE + * is set. Recalculate Rows and Columns based on the current window size. + * + * NOTE: gui_set_shellsize() calls this when GO_KEEPWINSIZE ('k') is in + * 'guioptions', even when the font hasn't actually changed (e.g. just setting + * "guioptions=k" triggers it via gui_init_which_components()). This is + * arguably a design problem in the common code, but we must not call + * gui_set_shellsize() back from here or it will cause infinite recursion and + * crash. Use gui_resize_shell() to recalculate Rows/Columns from the current + * window size instead. + */ + void +gui_mch_newfont(void) +{ + int w, h; + + w = gtk_widget_get_width(gui.formwin); + h = gtk_widget_get_height(gui.formwin); + w -= get_menu_tool_width(); + h -= get_menu_tool_height(); + gui_resize_shell(w, h); +} + + void +gui_mch_settitle(char_u *title, char_u *icon UNUSED) +{ + if (title != NULL && gui.mainwin != NULL) + gtk_window_set_title(GTK_WINDOW(gui.mainwin), (const char *)title); +} + +/* + * Get height of window decorations, that we cannot determine directly. For + * example, the GtkHeaderBar widget. This is called in gui_resize_shell(), we + * cannot call it in gui_set_shellsize(), because that may be called before the + * drawarea/formwin is resized, which may cause the drawarea to be bigger than + * it actually is (while the window size is up to date), causing a negative + * "decor_height". + */ + void +gui_gtk_init_decor_height(void) +{ + int h = gtk_widget_get_height(gui.mainwin); + + if (h == 0) + return; + + h -= get_menu_tool_height(); + h -= gtk_widget_get_height(gui.formwin); + + gui.decor_height = h; +} + + void +gui_mch_set_shellsize(int width, int height, + int min_width UNUSED, int min_height UNUSED, + int base_width UNUSED, int base_height UNUSED, + int direction UNUSED) +{ + width += get_menu_tool_width(); + height += get_menu_tool_height(); + + // GtkWindow default size also includes client side decorations, so must + // include it also. + height += gui.decor_height; + + gtk_window_set_default_size(GTK_WINDOW(gui.mainwin), width, height); +} + + void +gui_mch_get_screen_dimensions(int *screen_w, int *screen_h) +{ + GdkDisplay *display = gtk_widget_get_display(gui.mainwin); + GdkSurface *surface = gtk_native_get_surface(GTK_NATIVE(gui.mainwin)); + + if (surface != NULL) + { + GdkMonitor *monitor = gdk_display_get_monitor_at_surface(display, + surface); + if (monitor != NULL) + { + GdkRectangle geom; + gdk_monitor_get_geometry(monitor, &geom); + *screen_w = geom.width; + *screen_h = geom.height; + return; + } + } + + *screen_w = 800; + *screen_h = 600; +} + +#ifdef FEAT_MENU + void +gui_mch_enable_menu(int showit) +{ + if (gui.menubar != NULL) + gtk_widget_set_visible(gui.menubar, showit); +} +#endif + +#ifdef FEAT_TOOLBAR + void +gui_mch_show_toolbar(int showit) +{ + if (gui.toolbar != NULL) + gtk_widget_set_visible(gui.toolbar, showit); +} +#endif + + void +gui_mch_set_dark_theme(int dark) +{ + // GTK4: use GtkSettings + GtkSettings *settings = gtk_settings_get_default(); + if (settings != NULL) + g_object_set(settings, "gtk-application-prefer-dark-theme", + (gboolean)dark, NULL); +} + +/* + * ============================================================ + * Font handling + * ============================================================ + */ + + int +gui_mch_adjust_charheight(void) +{ + PangoFontMetrics *metrics; + int ascent; + int descent; + + metrics = pango_context_get_metrics(gui.text_context, gui.norm_font, + pango_context_get_language(gui.text_context)); + ascent = pango_font_metrics_get_ascent(metrics); + descent = pango_font_metrics_get_descent(metrics); + pango_font_metrics_unref(metrics); + + gui.char_height = (ascent + descent + (PANGO_SCALE * 15) / 16) + / PANGO_SCALE + p_linespace; + gui.char_ascent = PANGO_PIXELS(ascent + p_linespace * PANGO_SCALE / 2); + gui.char_ascent = MAX(gui.char_ascent, 0); + gui.char_height = MAX(gui.char_height, gui.char_ascent + 1); + + return OK; +} + +typedef struct { + PangoFontDescription *result; + gboolean done; +} FontDialogData; + + static void +font_dialog_finish_cb(GObject *source, GAsyncResult *res, gpointer data) +{ + FontDialogData *fdd = (FontDialogData *)data; + fdd->result = gtk_font_dialog_choose_font_finish( + GTK_FONT_DIALOG(source), res, NULL); + fdd->done = TRUE; +} + + static gboolean +font_filter(gpointer item, gpointer data UNUSED) +{ + if (PANGO_IS_FONT_FAMILY(item)) + return pango_font_family_is_monospace(PANGO_FONT_FAMILY(item)); + if (PANGO_IS_FONT_FACE(item)) + { + PangoFontFamily *family = pango_font_face_get_family( + PANGO_FONT_FACE(item)); + if (family != NULL) + return pango_font_family_is_monospace(family); + } + return TRUE; +} + + char_u * +gui_mch_font_dialog(char_u *oldval) +{ + GtkFontDialog *dlg; + PangoFontDescription *initial = NULL; + char_u *fontname = NULL; + FontDialogData fdd; + + dlg = gtk_font_dialog_new(); + gtk_font_dialog_set_modal(dlg, TRUE); + gtk_font_dialog_set_filter(dlg, + GTK_FILTER(gtk_custom_filter_new( + (GtkCustomFilterFunc)font_filter, NULL, NULL))); + + if (oldval != NULL && oldval[0] != NUL) + { + char_u *oldname; + + if (output_conv.vc_type != CONV_NONE) + oldname = string_convert(&output_conv, oldval, NULL); + else + oldname = oldval; + + if (STRLEN(oldname) > 0 && !vim_isdigit(oldname[STRLEN(oldname) - 1])) + { + char_u *p = vim_strnsave(oldname, STRLEN(oldname) + 3); + if (p != NULL) + { + STRCPY(p + STRLEN(p), " 10"); + if (oldname != oldval) + vim_free(oldname); + oldname = p; + } + } + + initial = pango_font_description_from_string((const char *)oldname); + if (oldname != oldval) + vim_free(oldname); + } + else + initial = pango_font_description_from_string(DEFAULT_FONT); + + fdd.result = NULL; + fdd.done = FALSE; + + gtk_font_dialog_choose_font(dlg, GTK_WINDOW(gui.mainwin), + initial, NULL, font_dialog_finish_cb, &fdd); + + while (!fdd.done) + g_main_context_iteration(NULL, TRUE); + + if (fdd.result != NULL) + { + char *name = pango_font_description_to_string(fdd.result); + if (name != NULL) + { + char_u *p; + + p = vim_strsave_escaped((char_u *)name, (char_u *)","); + g_free(name); + if (p != NULL && input_conv.vc_type != CONV_NONE) + { + fontname = string_convert(&input_conv, p, NULL); + vim_free(p); + } + else + fontname = p; + } + pango_font_description_free(fdd.result); + } + + if (initial != NULL) + pango_font_description_free(initial); + g_object_unref(dlg); + + return fontname; +} + +/* + * Build a table of glyphs for ASCII characters 32..126. + * This avoids the overhead of itemize+shape for the common case. + */ + static void +ascii_glyph_table_init(void) +{ + char_u ascii_chars[2 * 128]; + PangoAttrList *attr_list; + GList *item_list; + int i; + + if (gui.ascii_glyphs != NULL) + pango_glyph_string_free(gui.ascii_glyphs); + if (gui.ascii_font != NULL) + g_object_unref(gui.ascii_font); + + gui.ascii_glyphs = NULL; + gui.ascii_font = NULL; + + for (i = 0; i < 128; ++i) + { + if (i >= 32 && i < 127) + ascii_chars[2 * i] = i; + else + ascii_chars[2 * i] = '?'; + ascii_chars[2 * i + 1] = ' '; + } + + attr_list = pango_attr_list_new(); + item_list = pango_itemize(gui.text_context, (const char *)ascii_chars, + 0, sizeof(ascii_chars), attr_list, NULL); + + if (item_list != NULL && item_list->next == NULL) + { + PangoItem *item; + int width; + + item = (PangoItem *)item_list->data; + width = gui.char_width * PANGO_SCALE; + + gui.ascii_font = item->analysis.font; + g_object_ref(gui.ascii_font); + + gui.ascii_glyphs = pango_glyph_string_new(); + + pango_shape((const char *)ascii_chars, sizeof(ascii_chars), + &item->analysis, gui.ascii_glyphs); + + if (gui.ascii_glyphs->num_glyphs == (int)sizeof(ascii_chars)) + { + for (i = 0; i < gui.ascii_glyphs->num_glyphs; ++i) + { + PangoGlyphGeometry *geom; + + geom = &gui.ascii_glyphs->glyphs[i].geometry; + geom->x_offset += MAX(0, width - geom->width) / 2; + geom->width = width; + } + } + else + { + pango_glyph_string_free(gui.ascii_glyphs); + gui.ascii_glyphs = NULL; + g_object_unref(gui.ascii_font); + gui.ascii_font = NULL; + } + } + + g_list_foreach(item_list, (GFunc)(void *)&pango_item_free, NULL); + g_list_free(item_list); + pango_attr_list_unref(attr_list); +} + + static void +get_styled_font_variants(void) +{ + PangoFontDescription *bold_font_desc; + PangoFont *plain_font; + PangoFont *bold_font; + + gui.font_can_bold = FALSE; + + plain_font = pango_context_load_font(gui.text_context, gui.norm_font); + if (plain_font == NULL) + return; + + bold_font_desc = pango_font_description_copy_static(gui.norm_font); + pango_font_description_set_weight(bold_font_desc, PANGO_WEIGHT_BOLD); + + bold_font = pango_context_load_font(gui.text_context, bold_font_desc); + if (bold_font != NULL) + { + gui.font_can_bold = (bold_font != plain_font); + g_object_unref(bold_font); + } + + pango_font_description_free(bold_font_desc); + g_object_unref(plain_font); +} + + int +gui_mch_init_font(char_u *font_name, int fontset UNUSED) +{ + PangoFontDescription *font_desc; + PangoLayout *layout; + int width; + + if (font_name == NULL) + font_name = (char_u *)DEFAULT_FONT; + + font_desc = gui_mch_get_font(font_name, FALSE); + if (font_desc == NULL) + return FAIL; + + gui_mch_free_font(gui.norm_font); + gui.norm_font = font_desc; + + pango_context_set_font_description(gui.text_context, font_desc); + + layout = pango_layout_new(gui.text_context); + pango_layout_set_text(layout, "MW", 2); + pango_layout_get_size(layout, &width, NULL); + g_object_unref(layout); + + gui.char_width = (width / 2 + PANGO_SCALE - 1) / PANGO_SCALE; + if (gui.char_width <= 0) + gui.char_width = 8; + + gui_mch_adjust_charheight(); + + hl_set_font_name(font_name); + + get_styled_font_variants(); + ascii_glyph_table_init(); + + // im window position depends on cursor size which depends on font metrics + // update the position after we've initialized font + im_set_position(gui.row, gui.col); + + return OK; +} + + GuiFont +gui_mch_get_font(char_u *name, int report_error) +{ + PangoFontDescription *font; + + if (name == NULL) + return NULL; + + font = pango_font_description_from_string((const char *)name); + if (font == NULL) + { + if (report_error) + semsg(_(e_unknown_font_str), name); + return NULL; + } + + // Ensure a size is set + if (pango_font_description_get_size(font) <= 0) + pango_font_description_set_size(font, 10 * PANGO_SCALE); + + return font; +} + + char_u * +gui_mch_get_fontname(GuiFont font, char_u *name UNUSED) +{ + if (font != NOFONT) + { + char *desc = pango_font_description_to_string(font); + char_u *ret = vim_strsave((char_u *)desc); + g_free(desc); + return ret; + } + return NULL; +} + + void +gui_mch_free_font(GuiFont font) +{ + if (font != NOFONT) + pango_font_description_free(font); +} + + void +gui_mch_expand_font( + optexpand_T *args, + void *param, + int (*add_match)(char_u *val)) +{ + PangoFontFamily **font_families = NULL; + int n_families = 0; + int wide = *(int *)param; + + if (args->oe_include_orig_val && *args->oe_opt_value == NUL && !wide) + { + // If guifont is empty, suggest the default so the user can modify it. + if (add_match((char_u *)DEFAULT_FONT) != OK) + return; + } + + pango_context_list_families( + gui.text_context, + &font_families, + &n_families); + + for (int i = 0; i < n_families; i++) + { + if (!wide && !pango_font_family_is_monospace(font_families[i])) + continue; + + const char *fam_name = pango_font_family_get_name(font_families[i]); + if (input_conv.vc_type != CONV_NONE) + { + char_u *buf = string_convert(&input_conv, + (char_u *)fam_name, NULL); + if (buf != NULL) + { + if (add_match(buf) != OK) + { + vim_free(buf); + break; + } + vim_free(buf); + } + else + break; + } + else + { + if (add_match((char_u *)fam_name) != OK) + break; + } + } + + g_free(font_families); +} + +/* + * ============================================================ + * Color handling + * ============================================================ + */ + + guicolor_T +gui_mch_get_color(char_u *name) +{ + if (!gui.in_use) + return INVALCOLOR; + + if (name != NULL) + return gui_get_color_cmn(name); + + return INVALCOLOR; +} + + guicolor_T +gui_mch_get_rgb_color(int r, int g, int b) +{ + return gui_get_rgb_color_cmn(r, g, b); +} + + static GdkRGBA +color_to_rgba(guicolor_T color) +{ + GdkRGBA rgba; + rgba.red = ((color & 0xff0000) >> 16) / 255.0; + rgba.green = ((color & 0xff00) >> 8) / 255.0; + rgba.blue = (color & 0xff) / 255.0; + rgba.alpha = 1.0; + return rgba; +} + + void +gui_mch_set_fg_color(guicolor_T color) +{ + *gui.fgcolor = color_to_rgba(color); +} + + void +gui_mch_set_bg_color(guicolor_T color) +{ + *gui.bgcolor = color_to_rgba(color); +} + + void +gui_mch_set_sp_color(guicolor_T color) +{ + *gui.spcolor = color_to_rgba(color); +} + + guicolor_T +gui_mch_get_rgb(guicolor_T pixel) +{ + return pixel; +} + +/* + * ============================================================ + * Drawing + * ============================================================ + */ + +static void set_cairo_source_from_pixel(cairo_t *cr, guicolor_T pixel); + + static void +draw_event(GtkDrawingArea *area UNUSED, cairo_t *cr, + int width, int height, gpointer data UNUSED) +{ + // Surface creation/resizing is handled by drawarea_resize_cb. + // Here we only paint the surface to the widget. + + // Fill background with Vim's background color + set_cairo_source_from_pixel(cr, gui.back_pixel); + cairo_rectangle(cr, 0, 0, width, height); + cairo_fill(cr); + + // Paint the Vim surface on top + if (gui.surface != NULL) + { + cairo_set_source_surface(cr, gui.surface, 0, 0); + cairo_paint(cr); + } +} + + static void +set_cairo_source_from_pixel(cairo_t *cr, guicolor_T pixel) +{ + cairo_set_source_rgb(cr, + ((pixel & 0xff0000) >> 16) / 255.0, + ((pixel & 0xff00) >> 8) / 255.0, + (pixel & 0xff) / 255.0); +} + + static int +get_drawarea_scale(void) +{ + int scale = 1; + + if (gui.drawarea != NULL) + scale = gtk_widget_get_scale_factor(gui.drawarea); + if (scale < 1) + scale = 1; + return scale; +} + + static cairo_surface_t * +create_backing_surface(int width, int height) +{ + cairo_surface_t *surf; + int scale; + + if (width <= 0 || height <= 0) + return NULL; + + scale = get_drawarea_scale(); + surf = cairo_image_surface_create( + CAIRO_FORMAT_ARGB32, width * scale, height * scale); + cairo_surface_set_device_scale(surf, (double)scale, (double)scale); + return surf; +} + + void +gui_mch_clear_block(int row1, int col1, int row2, int col2) +{ + cairo_t *cr; + + if (gui.surface == NULL) + return; + + cr = cairo_create(gui.surface); + set_cairo_source_from_pixel(cr, gui.back_pixel); + cairo_rectangle(cr, + FILL_X(col1), FILL_Y(row1), + (col2 - col1 + 1) * gui.char_width, + (row2 - row1 + 1) * gui.char_height); + cairo_fill(cr); + cairo_destroy(cr); + + if (gui.drawarea != NULL) + gtk_widget_queue_draw(gui.drawarea); +} + + void +gui_mch_clear_all(void) +{ + cairo_t *cr; + + if (gui.surface == NULL) + return; + + cr = cairo_create(gui.surface); + set_cairo_source_from_pixel(cr, gui.back_pixel); + cairo_paint(cr); + cairo_destroy(cr); + + if (gui.drawarea != NULL) + gtk_widget_queue_draw(gui.drawarea); +} + + static void +surface_copy_rect(int dest_x, int dest_y, + int src_x, int src_y, + int width, int height) +{ + cairo_t *cr; + cairo_surface_t *tmp; + + if (gui.surface == NULL || width <= 0 || height <= 0) + return; + + // Use a temporary surface to avoid overlap issues + tmp = create_backing_surface(width, height); + if (tmp == NULL) + return; + cr = cairo_create(tmp); + cairo_set_source_surface(cr, gui.surface, -src_x, -src_y); + cairo_paint(cr); + cairo_destroy(cr); + + cr = cairo_create(gui.surface); + cairo_set_source_surface(cr, tmp, dest_x, dest_y); + cairo_paint(cr); + cairo_destroy(cr); + cairo_surface_destroy(tmp); +} + + void +gui_mch_delete_lines(int row, int num_lines) +{ + int ncols = gui.scroll_region_right - gui.scroll_region_left + 1; + int nrows = gui.scroll_region_bot - row + 1; + int src_nrows = nrows - num_lines; + + surface_copy_rect( + FILL_X(gui.scroll_region_left), FILL_Y(row), + FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines), + gui.char_width * ncols + 1, gui.char_height * src_nrows); + gui_clear_block( + gui.scroll_region_bot - num_lines + 1, gui.scroll_region_left, + gui.scroll_region_bot, gui.scroll_region_right); + + gtk_widget_queue_draw(gui.drawarea); +} + + void +gui_mch_insert_lines(int row, int num_lines) +{ + int ncols = gui.scroll_region_right - gui.scroll_region_left + 1; + int nrows = gui.scroll_region_bot - row + 1; + int src_nrows = nrows - num_lines; + + surface_copy_rect( + FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines), + FILL_X(gui.scroll_region_left), FILL_Y(row), + gui.char_width * ncols + 1, gui.char_height * src_nrows); + gui_clear_block( + row, gui.scroll_region_left, + row + num_lines - 1, gui.scroll_region_right); + + gtk_widget_queue_draw(gui.drawarea); +} + + void +gui_mch_draw_hollow_cursor(guicolor_T color) +{ + cairo_t *cr; + int i = 1; + + if (gui.surface == NULL) + return; + + cr = cairo_create(gui.surface); + gui_mch_set_fg_color(color); + cairo_set_source_rgba(cr, + gui.fgcolor->red, gui.fgcolor->green, + gui.fgcolor->blue, gui.fgcolor->alpha); + if (mb_lefthalve(gui.row, gui.col)) + i = 2; + cairo_set_line_width(cr, 1.0); + cairo_rectangle(cr, + FILL_X(gui.col) + 0.5, FILL_Y(gui.row) + 0.5, + i * gui.char_width - 1, gui.char_height - 1); + cairo_stroke(cr); + cairo_destroy(cr); + + gtk_widget_queue_draw(gui.drawarea); +} + + void +gui_mch_draw_part_cursor(int w, int h, guicolor_T color) +{ + cairo_t *cr; + + if (gui.surface == NULL) + return; + + gui_mch_set_fg_color(color); + cr = cairo_create(gui.surface); + cairo_set_source_rgba(cr, + gui.fgcolor->red, gui.fgcolor->green, + gui.fgcolor->blue, gui.fgcolor->alpha); + cairo_rectangle(cr, +#ifdef FEAT_RIGHTLEFT + CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : +#endif + FILL_X(gui.col), FILL_Y(gui.row) + gui.char_height - h, + w, h); + cairo_fill(cr); + cairo_destroy(cr); + + gtk_widget_queue_draw(gui.drawarea); +} + + void +gui_mch_flash(int msec) +{ + // Invert the screen, wait, then invert back + if (gui.surface == NULL) + return; + + gui_mch_invert_rectangle(0, 0, (int)Rows - 1, (int)Columns - 1); + gui_mch_flush(); + ui_delay((long)msec, TRUE); + gui_mch_invert_rectangle(0, 0, (int)Rows - 1, (int)Columns - 1); +} + + void +gui_mch_invert_rectangle(int r, int c, int nr, int nc) +{ + cairo_t *cr; + + if (gui.surface == NULL) + return; + + cr = cairo_create(gui.surface); + cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_rectangle(cr, + FILL_X(c), FILL_Y(r), + (nc + 1) * gui.char_width, (nr + 1) * gui.char_height); + cairo_fill(cr); + cairo_destroy(cr); + + gtk_widget_queue_draw(gui.drawarea); +} + +/* + * ============================================================ + * Event handling + * ============================================================ + */ + + static gboolean +key_press_event(GtkEventControllerKey *controller UNUSED, + guint key_sym, guint keycode UNUSED, + GdkModifierType state, gpointer data UNUSED) +{ + char_u string[32], string2[32]; + int len; + int i; + int modifiers; + int key; + char_u *s, *d; + +#ifdef FEAT_XIM + // Let the input method have a go at the key event. + // If it consumed the event, we're done. + if (xic != NULL) + { + GdkEvent *event = gtk_event_controller_get_current_event( + GTK_EVENT_CONTROLLER(controller)); + if (event != NULL && gtk_im_context_filter_keypress(xic, event)) + return TRUE; + } +#endif + +#ifdef FEAT_MENU + if (key_sym == GDK_KEY_F10 && gui.menubar != NULL) + { + static char_u k10[] = {K_SPECIAL, 'k', ';', 0}; + + if (check_map(k10, State, FALSE, TRUE, FALSE, NULL, NULL) == NULL) + { + show_menubar_popover(); + return TRUE; + } + } +#endif + + len = keyval_to_string(key_sym, string2); + + if (len > 1 && input_conv.vc_type != CONV_NONE) + len = convert_input(string2, len, sizeof(string2)); + + s = string2; + d = string; + for (i = 0; i < len; ++i) + { + *d++ = s[i]; + if (d[-1] == CSI && d + 2 < string + sizeof(string)) + { + *d++ = KS_EXTRA; + *d++ = (int)KE_CSI; + } + } + len = d - string; + + // Shift-Tab results in Left_Tab + if (key_sym == GDK_KEY_ISO_Left_Tab) + { + key_sym = GDK_KEY_Tab; + state |= GDK_SHIFT_MASK; + } + + // Check for special keys + if (len == 0 || len == 1) + { + for (i = 0; special_keys[i].key_sym != 0; i++) + { + if (special_keys[i].key_sym == key_sym) + { + string[0] = CSI; + string[1] = special_keys[i].code0; + string[2] = special_keys[i].code1; + len = -3; + break; + } + } + } + + if (len == 0) + return TRUE; + + if (len == -3) + key = TO_SPECIAL(string[1], string[2]); + else + { + string[len] = NUL; + key = mb_ptr2char(string); + } + + modifiers = modifiers_gdk2vim(state); + + key = simplify_key(key, &modifiers); + if (key == CSI) + key = K_CSI; + if (IS_SPECIAL(key)) + { + string[0] = CSI; + string[1] = K_SECOND(key); + string[2] = K_THIRD(key); + len = 3; + } + else + { + key = may_adjust_key_for_ctrl(modifiers, key); + modifiers = may_remove_shift_modifier(modifiers, key); + len = mb_char2bytes(key, string); + } + + if (modifiers != 0) + { + string2[0] = CSI; + string2[1] = KS_MODIFIER; + string2[2] = modifiers; + add_to_input_buf(string2, 3); + } + + { + int int_ch = check_for_interrupt(key, modifiers); + if (int_ch != NUL) + { + trash_input_buf(); + string[0] = int_ch; + len = 1; + } + } + + add_to_input_buf(string, len); + + if (p_mh) + gui_mch_mousehide(TRUE); + + return TRUE; +} + + static void +key_release_event(GtkEventControllerKey *controller UNUSED, + guint keyval UNUSED, guint keycode UNUSED, + GdkModifierType state UNUSED, gpointer data UNUSED) +{ +} + +static int mouse_timed_out = TRUE; +static guint mouse_click_timer = 0; + + static timeout_cb_type +mouse_click_timer_cb(gpointer data) +{ + *(int *)data = TRUE; + return FALSE; +} + + static int +modifiers_gdk2mouse(guint state) +{ + int modifiers = 0; + + if (state & GDK_SHIFT_MASK) + modifiers |= MOUSE_SHIFT; + if (state & GDK_CONTROL_MASK) + modifiers |= MOUSE_CTRL; + if (state & GDK_ALT_MASK) + modifiers |= MOUSE_ALT; + + return modifiers; +} + +// Track which mouse button is currently pressed for drag detection. +// GtkEventControllerMotion's modifier state may not include button masks +// on all backends (e.g. Wayland), so we track it ourselves. +// -1 means no button is pressed (MOUSE_LEFT is 0x00, so can't use 0). +static int mouse_pressed_button = -1; + + static void +button_press_event(GtkGestureClick *gesture, int n_press UNUSED, + double x, double y, gpointer data UNUSED) +{ + int button; + int repeated_click = FALSE; + int_u vim_modifiers; + guint btn; + GdkModifierType state; + GdkEvent *event; + + event = gtk_event_controller_get_current_event( + GTK_EVENT_CONTROLLER(gesture)); + state = gdk_event_get_modifier_state(event); + btn = gdk_button_event_get_button(event); + + if (!mouse_timed_out && mouse_click_timer) + { + timeout_remove(mouse_click_timer); + mouse_click_timer = 0; + repeated_click = TRUE; + } + + mouse_timed_out = FALSE; + mouse_click_timer = timeout_add(p_mouset, mouse_click_timer_cb, + &mouse_timed_out); + + switch (btn) + { + case 1: button = MOUSE_LEFT; break; + case 2: button = MOUSE_MIDDLE; break; + case 3: button = MOUSE_RIGHT; break; + case 8: button = MOUSE_X1; break; + case 9: button = MOUSE_X2; break; + default: return; + } + + mouse_pressed_button = button; + vim_modifiers = modifiers_gdk2mouse(state); + gui_send_mouse_event(button, (int)x, (int)y, repeated_click, vim_modifiers); +} + + static void +button_release_event(GtkGestureClick *gesture, int n_press UNUSED, + double x, double y, gpointer data UNUSED) +{ + int vim_modifiers; + GdkModifierType state; + GdkEvent *event; + + event = gtk_event_controller_get_current_event( + GTK_EVENT_CONTROLLER(gesture)); + state = gdk_event_get_modifier_state(event); + vim_modifiers = modifiers_gdk2mouse(state); + + mouse_pressed_button = -1; + gui_send_mouse_event(MOUSE_RELEASE, (int)x, (int)y, FALSE, vim_modifiers); +} + +static double prev_mouse_x = -1.0; +static double prev_mouse_y = -1.0; + + static void +motion_notify_event(GtkEventControllerMotion *controller UNUSED, + double x, double y, gpointer data UNUSED) +{ + if (mouse_pressed_button >= 0) + { + GdkModifierType state; + GdkEvent *event; + + event = gtk_event_controller_get_current_event( + GTK_EVENT_CONTROLLER(controller)); + if (event != NULL) + { + state = gdk_event_get_modifier_state(event); + gui_send_mouse_event(MOUSE_DRAG, (int)x, (int)y, + FALSE, modifiers_gdk2mouse(state)); + } + } + + // Only unhide if mouse actually moved. GTK seems to send a motion event + // when switching tabs, causing the cursor to unhide. + if (p_mh && fabs(prev_mouse_x - x) > 0.05 + && fabs(prev_mouse_y - y) > 0.05) + gui_mch_mousehide(FALSE); + + prev_mouse_x = x; + prev_mouse_y = y; +} + + static void +enter_notify_event(GtkEventControllerMotion *controller UNUSED, + double x UNUSED, double y UNUSED, gpointer data UNUSED) +{ + if (blink_state == BLINK_NONE) + gui_mch_start_blink(); + + prev_mouse_x = x; + prev_mouse_y = y; + + // Make sure keyboard input goes to the drawing area. + if (!gtk_widget_has_focus(gui.drawarea)) + gtk_widget_grab_focus(gui.drawarea); +} + + static void +leave_notify_event(GtkEventControllerMotion *controller UNUSED, + gpointer data UNUSED) +{ + if (blink_state != BLINK_NONE) + gui_mch_stop_blink(TRUE); +} + + static gboolean +scroll_event(GtkEventControllerScroll *controller UNUSED, + double dx UNUSED, double dy, gpointer data UNUSED) +{ + int button; + int_u vim_modifiers; + int x, y; + GdkModifierType state; + GdkEvent *event; + + event = gtk_event_controller_get_current_event( + GTK_EVENT_CONTROLLER(controller)); + if (event == NULL) + return FALSE; + state = gdk_event_get_modifier_state(event); + + if (dy < 0) + button = MOUSE_4; // scroll up + else if (dy > 0) + button = MOUSE_5; // scroll down + else if (dx < 0) + button = MOUSE_7; // scroll left + else if (dx > 0) + button = MOUSE_6; // scroll right + else + return FALSE; + + vim_modifiers = modifiers_gdk2mouse(state); + + gui_mch_getmouse(&x, &y); + gui_send_mouse_event(button, x, y, FALSE, vim_modifiers); + + return TRUE; +} + + static void +focus_in_event(GtkEventControllerFocus *controller UNUSED, + gpointer data UNUSED) +{ + gui_focus_change(TRUE); + if (blink_state == BLINK_NONE) + gui_mch_start_blink(); +} + + static void +focus_out_event(GtkEventControllerFocus *controller UNUSED, + gpointer data UNUSED) +{ + gui_focus_change(FALSE); + if (blink_state != BLINK_NONE) + gui_mch_stop_blink(TRUE); +} + +#ifdef FEAT_MENU + static gboolean +grab_drawarea_focus_idle(gpointer data UNUSED) +{ + if (gui.drawarea != NULL && !gtk_widget_has_focus(gui.drawarea)) + gtk_widget_grab_focus(gui.drawarea); + return G_SOURCE_REMOVE; +} + + static gboolean +menubar_popover_closed_hook(GSignalInvocationHint *ihint UNUSED, + guint n_param_values, const GValue *param_values, + gpointer data UNUSED) +{ + GObject *obj; + GtkWidget *popover; + GtkWidget *parent; + + if (n_param_values < 1 || gui.menubar == NULL || gui.drawarea == NULL) + return TRUE; + obj = g_value_get_object(¶m_values[0]); + if (!GTK_IS_POPOVER(obj)) + return TRUE; + popover = GTK_WIDGET(obj); + + // Only react to popovers that descend from the menubar. + for (parent = gtk_widget_get_parent(popover); + parent != NULL; + parent = gtk_widget_get_parent(parent)) + { + if (parent != gui.menubar) + continue; + // Defer the grab to the next main loop iteration; calling it + // synchronously while GTK is still completing the popover close + // has no effect (issue #20274). + g_idle_add(grab_drawarea_focus_idle, NULL); + break; + } + return TRUE; // keep the emission hook installed +} +#endif + + static void +drawarea_realize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED) +{ + int w, h; + + // Use formwin size since drawarea may not have its final size yet + if (gui.formwin != NULL) + { + w = gtk_widget_get_width(gui.formwin); + h = gtk_widget_get_height(gui.formwin); + } + else + { + w = gtk_widget_get_width(widget); + h = gtk_widget_get_height(widget); + } + + if (w <= 0) w = 800; + if (h <= 0) h = 600; + + if (gui.surface != NULL) + cairo_surface_destroy(gui.surface); + gui.surface = create_backing_surface(w, h); + + gui_mch_new_colors(); +} + + static void +drawarea_unrealize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED) +{ +#ifdef FEAT_XIM + im_shutdown(); +#endif + if (gui.surface != NULL) + { + cairo_surface_destroy(gui.surface); + gui.surface = NULL; + } +} + +// Debounced resize: drawarea_resize_cb only resizes the backing surface +// (preserving old content) and (re)arms a short timeout. The actual +// gui_resize_shell() runs from drawarea_resize_apply_cb once the user has +// stopped dragging for ~100 ms, by which time no input is pending and +// update_screen() will not bail in screenclear()'s wake. +static guint drawarea_resize_timeout_id = 0; +static int drawarea_resize_pending_w = 0; +static int drawarea_resize_pending_h = 0; + + static gboolean +drawarea_resize_apply_cb(gpointer data UNUSED) +{ + int width = drawarea_resize_pending_w; + int height = drawarea_resize_pending_h; + + drawarea_resize_timeout_id = 0; + + if (width <= 0 || height <= 0) + return G_SOURCE_REMOVE; + if (updating_screen) + { + drawarea_resize_timeout_id = g_timeout_add(50, + drawarea_resize_apply_cb, NULL); + return G_SOURCE_REMOVE; + } + + gui.force_redraw = TRUE; + gui_resize_shell(width, height); + if (gui.in_use) + redraw_all_later(UPD_CLEAR); + return G_SOURCE_REMOVE; +} + + static void +drawarea_resize_cb(GtkDrawingArea *area UNUSED, int width, int height, + gpointer data UNUSED) +{ + cairo_t *cr; + cairo_surface_t *old_surface; + int scale = get_drawarea_scale(); + + if (width <= 0 || height <= 0) + return; + + drawarea_resize_pending_w = width; + drawarea_resize_pending_h = height; + + // Keep the backing surface in sync with the drawing area so GTK keeps + // showing the previous frame. Re-creating it preserves the old + // contents. + if (gui.surface != NULL) + { + int sw = cairo_image_surface_get_width(gui.surface) / scale; + int sh = cairo_image_surface_get_height(gui.surface) / scale; + if (sw != width || sh != height) + { + old_surface = gui.surface; + gui.surface = create_backing_surface(width, height); + if (gui.surface != NULL) + { + cr = cairo_create(gui.surface); + set_cairo_source_from_pixel(cr, gui.back_pixel); + cairo_paint(cr); + cairo_set_source_surface(cr, old_surface, 0, 0); + cairo_paint(cr); + cairo_destroy(cr); + } + cairo_surface_destroy(old_surface); + } + } + else + { + gui.surface = create_backing_surface(width, height); + if (gui.surface != NULL) + { + cr = cairo_create(gui.surface); + set_cairo_source_from_pixel(cr, gui.back_pixel); + cairo_paint(cr); + cairo_destroy(cr); + } + } + + // Debounce: (re)arm the apply timeout, so gui_resize_shell() only + // runs once the resize stream settles. + if (drawarea_resize_timeout_id != 0) + g_source_remove(drawarea_resize_timeout_id); + drawarea_resize_timeout_id = g_timeout_add(100, + drawarea_resize_apply_cb, NULL); +} + + static void +drawarea_scale_factor_cb(GObject *object UNUSED, + GParamSpec *pspec UNUSED, gpointer data UNUSED) +{ + int w, h; + + if (gui.drawarea == NULL) + return; + + w = gtk_widget_get_width(gui.drawarea); + h = gtk_widget_get_height(gui.drawarea); + if (w <= 0 || h <= 0) + return; + + if (gui.surface != NULL) + cairo_surface_destroy(gui.surface); + gui.surface = create_backing_surface(w, h); + + if (gui.surface != NULL) + { + cairo_t *cr = cairo_create(gui.surface); + set_cairo_source_from_pixel(cr, gui.back_pixel); + cairo_paint(cr); + cairo_destroy(cr); + } + gtk_widget_queue_draw(gui.drawarea); + if (gui.in_use) + redraw_all_later(UPD_CLEAR); +} + +#ifdef FEAT_DND +/* + * Drag-and-drop handler for files and text. + */ + static gboolean +drop_cb(GtkDropTarget *target UNUSED, const GValue *value, + double x, double y, gpointer data UNUSED) +{ + if (G_VALUE_HOLDS(value, GDK_TYPE_FILE_LIST)) + { + GSList *files = g_value_get_boxed(value); + int nfiles = g_slist_length(files); + char_u **fnames; + int i; + + if (nfiles <= 0) + return FALSE; + + fnames = ALLOC_MULT(char_u *, nfiles); + if (fnames == NULL) + return FALSE; + + i = 0; + for (GSList *l = files; l != NULL; l = l->next) + { + GFile *file = l->data; + char *path = g_file_get_path(file); + if (path != NULL) + fnames[i++] = vim_strsave((char_u *)path); + g_free(path); + } + nfiles = i; + + if (nfiles > 0) + gui_handle_drop((int)x, (int)y, 0, fnames, nfiles); + else + vim_free(fnames); + + return TRUE; + } + else if (G_VALUE_HOLDS(value, G_TYPE_STRING)) + { + const char *text = g_value_get_string(value); + char_u dropkey[6] = {CSI, KS_MODIFIER, 0, + CSI, KS_EXTRA, (char_u)KE_DROP}; + + if (text == NULL || *text == NUL) + return FALSE; + + dnd_yank_drag_data((char_u *)text, (long)STRLEN(text)); + add_to_input_buf(dropkey + 3, 3); + + return TRUE; + } + + return FALSE; +} +#endif + + static void +mainwin_destroy_cb(GObject *object UNUSED, gpointer data UNUSED) +{ + gui.mainwin = NULL; + gui.drawarea = NULL; + if (!exiting) + gui_shell_closed(); +} + + static gboolean +delete_event_cb(GtkWindow *window UNUSED, gpointer data UNUSED) +{ + gui_shell_closed(); + return TRUE; +} + +/* + * ============================================================ + * Misc functions + * ============================================================ + */ + + static timeout_cb_type +input_timer_cb(gpointer data) +{ + int *timed_out = (int *)data; + + *timed_out = TRUE; + return FALSE; // don't call me again +} + + void +gui_mch_update(void) +{ + int cnt = 0; + + while (g_main_context_pending(NULL) && !vim_is_input_buf_full() + && ++cnt < 100) + g_main_context_iteration(NULL, TRUE); +} + +#ifdef FEAT_JOB_CHANNEL + static timeout_cb_type +channel_poll_cb(gpointer data UNUSED) +{ + // Using an event handler for a channel that may be disconnected does + // not work, it hangs. Instead poll for messages. + channel_handle_events(TRUE); + parse_queued_messages(); + return TRUE; // Keep repeating +} +#endif + + int +gui_mch_wait_for_chars(long wtime) +{ + int focus; + guint timer; + static int timed_out; + int retval = FAIL; +#ifdef FEAT_JOB_CHANNEL + guint channel_timer = 0; +#endif + + timed_out = FALSE; + + if (wtime >= 0) + timer = timeout_add(wtime == 0 ? 1L : wtime, + input_timer_cb, &timed_out); + else + timer = 0; + +#ifdef FEAT_JOB_CHANNEL + // If there is a channel with the keep_open flag we need to poll for input + // on them. + if (channel_any_keep_open()) + channel_timer = timeout_add(20, channel_poll_cb, NULL); +#endif + + focus = gui.in_focus; + + do + { + // Stop or start blinking when focus changes + if (gui.in_focus != focus) + { + if (gui.in_focus) + gui_mch_start_blink(); + else + gui_mch_stop_blink(TRUE); + focus = gui.in_focus; + } + +#ifdef MESSAGE_QUEUE +# ifdef FEAT_TIMERS + did_add_timer = FALSE; +# endif + parse_queued_messages(); +# ifdef FEAT_TIMERS + if (did_add_timer) + goto theend; +# endif +#endif + + if (gui.mainwin == NULL) + goto theend; + + // gtk_main_quit() is a wake-up request; consume it so later + // waits resume. + if (gtk4_main_loop_quit) + { + gtk4_main_loop_quit = FALSE; + goto theend; + } + + if (!input_available()) + { + ++gtk4_main_loop_level; + g_main_context_iteration(NULL, TRUE); + --gtk4_main_loop_level; + } + + if (input_available()) + { + retval = OK; + goto theend; + } + } while (wtime < 0 || !timed_out); + + gui_mch_update(); + +theend: + if (timer != 0 && !timed_out) + timeout_remove(timer); +#ifdef FEAT_JOB_CHANNEL + if (channel_timer != 0) + timeout_remove(channel_timer); +#endif + + return retval; +} + + void +gui_mch_flush(void) +{ + // Ensure the offscreen surface content gets painted to the widget. + if (gui.drawarea != NULL) + gtk_widget_queue_draw(gui.drawarea); + if (gui.mainwin != NULL && gtk_widget_get_realized(gui.mainwin)) + gdk_display_flush(gtk_widget_get_display(gui.mainwin)); +} + + void +gui_mch_beep(void) +{ + GdkDisplay *display; + + if (gui.mainwin != NULL && gtk_widget_get_realized(gui.mainwin)) + { + display = gtk_widget_get_display(gui.mainwin); + if (display != NULL) + gdk_display_beep(display); + } +} + + void * +gui_mch_get_display(void) +{ + if (gui.mainwin != NULL && gtk_widget_get_display(gui.mainwin)) + return gtk_widget_get_display(gui.mainwin); + return NULL; +} + + void +gui_mch_iconify(void) +{ + gtk_window_minimize(GTK_WINDOW(gui.mainwin)); +} + + void +gui_mch_set_foreground(void) +{ + gtk_window_present(GTK_WINDOW(gui.mainwin)); +} + + static int +query_pointer_pos(int *x, int *y) +{ + GtkNative *native; + GdkSurface *surface; + GdkDisplay *display; + GdkSeat *seat; + GdkDevice *pointer; + double sx, sy, nx, ny; + graphene_point_t src, dst; + + if (gui.drawarea == NULL) + return FALSE; + native = gtk_widget_get_native(gui.drawarea); + if (native == NULL) + return FALSE; + surface = gtk_native_get_surface(native); + if (surface == NULL) + return FALSE; + display = gtk_widget_get_display(gui.drawarea); + if (display == NULL) + return FALSE; + seat = gdk_display_get_default_seat(display); + if (seat == NULL) + return FALSE; + pointer = gdk_seat_get_pointer(seat); + if (pointer == NULL) + return FALSE; + + if (!gdk_surface_get_device_position(surface, pointer, &sx, &sy, NULL)) + return FALSE; + + gtk_native_get_surface_transform(native, &nx, &ny); + src.x = (float)(sx - nx); + src.y = (float)(sy - ny); + if (!gtk_widget_compute_point(GTK_WIDGET(native), gui.drawarea, + &src, &dst)) + return FALSE; + + *x = (int)dst.x; + *y = (int)dst.y; + return TRUE; +} + + void +gui_mch_getmouse(int *x, int *y) +{ + if (!query_pointer_pos(x, y)) + { + *x = 0; + *y = 0; + } +} + + void +gui_mch_setmouse(int x UNUSED, int y UNUSED) +{ + // GTK4/Wayland: cannot warp pointer +} + + void +gui_mch_mousehide(int hide) +{ + if (gui.pointer_hidden == hide) + return; + + gui.pointer_hidden = hide; + if (gui.blank_pointer != NULL) + { + if (hide) + gtk_widget_set_cursor(gui.drawarea, gui.blank_pointer); + else +#ifdef FEAT_MOUSESHAPE + mch_set_mouse_shape(last_shape); +#else + gtk_widget_set_cursor(gui.drawarea, NULL); +#endif + } +} + + int +gui_mch_haskey(char_u *name) +{ + int i; + + for (i = 0; special_keys[i].key_sym != 0; i++) + if (name[0] == special_keys[i].code0 + && name[1] == special_keys[i].code1) + return OK; + return FAIL; +} + + void +gui_mch_forked(void) +{ +} + +/* + * ============================================================ + * Scrollbar + * ============================================================ + */ + + void +gui_mch_enable_scrollbar(scrollbar_T *sb, int flag) +{ + if (sb->id != NULL) + gtk_widget_set_visible(sb->id, flag); +} + +/* + * ============================================================ + * Menu stubs + * ============================================================ + */ + + void +gui_mch_menu_grey(vimmenu_T *menu, int grey) +{ + if (menu->id == NULL || menu_action_group == NULL) + return; + + // For toolbar items, use gtk_widget_set_sensitive + if (menu->parent != NULL && menu_is_toolbar(menu->parent->name)) + { + if (menu->id != (GtkWidget *)1) + gtk_widget_set_sensitive(menu->id, !grey); + return; + } + + // For menu items, enable/disable the GSimpleAction + if (menu->label != NULL) + { + GAction *action = g_action_map_lookup_action( + G_ACTION_MAP(menu_action_group), + (const char *)menu->label); + if (action != NULL) + g_simple_action_set_enabled(G_SIMPLE_ACTION(action), !grey); + } +} + +#if defined(FEAT_MENU) +/* + * Make menu item hidden or not hidden. + */ + void +gui_mch_menu_hidden(vimmenu_T *menu, int hidden) +{ + if (menu->id == 0) + return; + + if (hidden) + { + if (gtk_widget_get_visible(menu->id)) + { + gtk_widget_set_visible(menu->id, FALSE); + gui_mch_update(); + } + } + else + { + if (!gtk_widget_get_visible(menu->id)) + { + gtk_widget_set_visible(menu->id, TRUE); + gui_mch_update(); + } + } +} + + void +gui_mch_draw_menubar(void) +{ + // Just make sure that the visual changes get effect immediately + gui_mch_update(); +} +#endif + +/* + * ============================================================ + * Tabline + * ============================================================ + */ + +#ifdef FEAT_GUI_TABLINE + void +gui_mch_show_tabline(int showit) +{ + if (gui.tabline != NULL) + gtk_widget_set_visible(gui.tabline, showit); +} + + int +gui_mch_showing_tabline(void) +{ + return gui.tabline != NULL && gtk_widget_get_visible(gui.tabline); +} + +static int ignore_tabline_evt = FALSE; + + void +gui_mch_update_tabline(void) +{ + GtkWidget *page; + GtkWidget *event_box; + GtkWidget *label; + tabpage_T *tp; + int nr = 0; + int tab_num; + int curtabidx = 0; + char_u *labeltext; + + if (gui.tabline == NULL) + return; + + ignore_tabline_evt = TRUE; + + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr) + { + if (tp == curtab) + curtabidx = nr; + + tab_num = nr + 1; + + page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr); + if (page == NULL) + { + page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_visible(page, TRUE); + event_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_visible(event_box, TRUE); + label = gtk_label_new("-Empty-"); + gtk_box_append(GTK_BOX(event_box), label); + gtk_widget_set_visible(label, TRUE); + gtk_notebook_insert_page(GTK_NOTEBOOK(gui.tabline), + page, event_box, nr); + gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(gui.tabline), + page, TRUE); + } + + event_box = gtk_notebook_get_tab_label(GTK_NOTEBOOK(gui.tabline), page); + g_object_set_data(G_OBJECT(event_box), "tab_num", + GINT_TO_POINTER(tab_num)); + label = gtk_widget_get_first_child(event_box); + get_tabline_label(tp, FALSE); + labeltext = CONVERT_TO_UTF8(NameBuff); + if (label != NULL && GTK_IS_LABEL(label)) + gtk_label_set_text(GTK_LABEL(label), (const char *)labeltext); + CONVERT_TO_UTF8_FREE(labeltext); + + get_tabline_label(tp, TRUE); + labeltext = CONVERT_TO_UTF8(NameBuff); + gtk_widget_set_tooltip_text(event_box, (const gchar *)labeltext); + CONVERT_TO_UTF8_FREE(labeltext); + } + + while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr) != NULL) + gtk_notebook_remove_page(GTK_NOTEBOOK(gui.tabline), nr); + + if (gtk_notebook_get_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx) + gtk_notebook_set_current_page(GTK_NOTEBOOK(gui.tabline), curtabidx); + + ignore_tabline_evt = FALSE; +} + + void +gui_mch_set_curtab(int nr) +{ + if (gui.tabline != NULL) + gtk_notebook_set_current_page(GTK_NOTEBOOK(gui.tabline), nr - 1); +} + +/* + * Handle selecting one of the tabs. + */ + static void +on_select_tab( + GtkNotebook *notebook UNUSED, + gpointer *page UNUSED, + gint idx, + gpointer data UNUSED) +{ + if (!ignore_tabline_evt) + send_tabline_event(idx + 1); +} + +/* + * Handle reordering the tabs (using D&D). + */ + static void +on_tab_reordered( + GtkNotebook *notebook UNUSED, + gpointer *page UNUSED, + gint idx, + gpointer data UNUSED) +{ + if (ignore_tabline_evt) + return; + + if ((tabpage_index(curtab) - 1) < idx) + tabpage_move(idx + 1); + else + tabpage_move(idx); +} +#endif + +/* + * ============================================================ + * Sign support + * ============================================================ + */ + +#if defined(FEAT_SIGN_ICONS) +# define SIGN_WIDTH (2 * gui.char_width) +# define SIGN_HEIGHT (gui.char_height) + + void +gui_mch_drawsign(int row, int col, int typenr) +{ + GdkPixbuf *sign; + cairo_t *cr; + int width, height; + + sign = (GdkPixbuf *)sign_get_image(typenr); + if (sign == NULL || gui.surface == NULL) + return; + + cr = cairo_create(gui.surface); + + width = gdk_pixbuf_get_width(sign); + height = gdk_pixbuf_get_height(sign); + + // Scale to fit the sign area if needed + if (width != SIGN_WIDTH || height != SIGN_HEIGHT) + { + GdkPixbuf *scaled = gdk_pixbuf_scale_simple(sign, + SIGN_WIDTH, SIGN_HEIGHT, GDK_INTERP_BILINEAR); + if (scaled != NULL) + { + gdk_cairo_set_source_pixbuf(cr, scaled, + FILL_X(col), FILL_Y(row)); + g_object_unref(scaled); + } + else + gdk_cairo_set_source_pixbuf(cr, sign, + FILL_X(col), FILL_Y(row)); + } + else + gdk_cairo_set_source_pixbuf(cr, sign, + FILL_X(col), FILL_Y(row)); + + cairo_paint(cr); + cairo_destroy(cr); + + gtk_widget_queue_draw(gui.drawarea); +} + + void * +gui_mch_register_sign(char_u *signfile) +{ + if (signfile[0] != NUL && signfile[0] != '-' && gui.in_use) + { + GdkPixbuf *sign; + GError *error = NULL; + + sign = gdk_pixbuf_new_from_file((const char *)signfile, &error); + if (error == NULL) + return sign; + + semsg("E255: %s", error->message); + g_error_free(error); + } + return NULL; +} + + void +gui_mch_destroy_sign(void *sign) +{ + if (sign != NULL) + g_object_unref(sign); +} +#endif + +/* + * ============================================================ + * Stubs for functions not yet implemented or not applicable in GTK4 + * ============================================================ + */ + +/* + * Ligature and text drawing support. + * Ported from gui_gtk_x11.c (GTK3) to support 'guiligatures' in GTK4. + */ + +#define INSERT_PANGO_ATTR(Attribute, AttrList, Start, End) \ + G_STMT_START{ \ + PangoAttribute *tmp_attr_; \ + tmp_attr_ = (Attribute); \ + tmp_attr_->start_index = (Start); \ + tmp_attr_->end_index = (End); \ + pango_attr_list_insert((AttrList), tmp_attr_); \ + }G_STMT_END + +/* + * Apply the 'guifontwide' font to double-width characters in the string. + */ + static void +apply_wide_font_attr(char_u *s, int len, PangoAttrList *attr_list) +{ + char_u *start = NULL; + char_u *p; + int uc; + + for (p = s; p < s + len; p += utf_byte2len(*p)) + { + uc = utf_ptr2char(p); + + if (start == NULL) + { + if (uc >= 0x80 && utf_char2cells(uc) == 2) + start = p; + } + else if (uc < 0x80 + || (utf_char2cells(uc) != 2 && !utf_iscomposing(uc))) + { + INSERT_PANGO_ATTR(pango_attr_font_desc_new(gui.wide_font), + attr_list, start - s, p - s); + start = NULL; + } + } + + if (start != NULL) + INSERT_PANGO_ATTR(pango_attr_font_desc_new(gui.wide_font), + attr_list, start - s, len); +} + +/* + * Count the number of display cells occupied by a glyph cluster. + */ + static int +count_cluster_cells(char_u *s, PangoItem *item, + PangoGlyphString *glyphs, int i, + int *cluster_width, + int *last_glyph_rbearing) +{ + char_u *p; + int next; + int start, end; + int width; + int uc; + int cellcount = 0; + + width = glyphs->glyphs[i].geometry.width; + + for (next = i + 1; next < glyphs->num_glyphs; ++next) + { + if (glyphs->glyphs[next].attr.is_cluster_start) + break; + else if (glyphs->glyphs[next].geometry.width > width) + width = glyphs->glyphs[next].geometry.width; + } + + start = item->offset + glyphs->log_clusters[i]; + end = item->offset + ((next < glyphs->num_glyphs) ? + glyphs->log_clusters[next] : item->length); + + for (p = s + start; p < s + end; p += utf_byte2len(*p)) + { + uc = utf_ptr2char(p); + if (uc < 0x80) + ++cellcount; + else if (!utf_iscomposing(uc)) + cellcount += utf_char2cells(uc); + } + + if (last_glyph_rbearing != NULL + && cellcount > 0 && next == glyphs->num_glyphs) + { + PangoRectangle ink_rect; + + pango_font_get_glyph_extents(item->analysis.font, + glyphs->glyphs[i].glyph, + &ink_rect, NULL); + + if (PANGO_RBEARING(ink_rect) > 0) + *last_glyph_rbearing = PANGO_RBEARING(ink_rect); + } + + if (cellcount > 0) + *cluster_width = width; + + return cellcount; +} + +/* + * Handle combining characters that form a zero-width cluster. + */ + static void +setup_zero_width_cluster(PangoItem *item, PangoGlyphInfo *glyph, + int last_cellcount, int last_cluster_width, + int last_glyph_rbearing) +{ + PangoRectangle ink_rect; + PangoRectangle logical_rect; + int width; + + width = last_cellcount * gui.char_width * PANGO_SCALE; + glyph->geometry.x_offset = -width + MAX(0, width - last_cluster_width) / 2; + glyph->geometry.width = 0; + + pango_font_get_glyph_extents(item->analysis.font, + glyph->glyph, + &ink_rect, &logical_rect); + if (ink_rect.x < 0) + { + glyph->geometry.x_offset += last_glyph_rbearing; + glyph->geometry.y_offset = logical_rect.height + - (gui.char_height - p_linespace) * PANGO_SCALE; + } + else + glyph->geometry.x_offset = -width + MAX(0, width - ink_rect.width) / 2; +} + +/* + * Draw a single glyph string segment: background, foreground, and fake bold. + */ + static void +draw_glyph_string(int row, int col, int num_cells, int flags, + PangoFont *font, PangoGlyphString *glyphs, + cairo_t *cr) +{ + if (!(flags & DRAW_TRANSP)) + { + cairo_set_source_rgba(cr, + gui.bgcolor->red, gui.bgcolor->green, gui.bgcolor->blue, + gui.bgcolor->alpha); + cairo_rectangle(cr, + FILL_X(col), FILL_Y(row), + num_cells * gui.char_width, gui.char_height); + cairo_fill(cr); + } + + cairo_set_source_rgba(cr, + gui.fgcolor->red, gui.fgcolor->green, gui.fgcolor->blue, + gui.fgcolor->alpha); + cairo_move_to(cr, TEXT_X(col), TEXT_Y(row)); + pango_cairo_show_glyph_string(cr, font, glyphs); + + // Redraw with offset of 1 to emulate bold + if ((flags & DRAW_BOLD) && !gui.font_can_bold) + { + cairo_move_to(cr, TEXT_X(col) + 1, TEXT_Y(row)); + pango_cairo_show_glyph_string(cr, font, glyphs); + } +} + +/* + * Draw underline, undercurl, and strikethrough decorations. + */ + static void +draw_under(int flags, int row, int col, int cells, cairo_t *cr) +{ + // Draw underline + if (flags & DRAW_UNDERL) + { + int y = FILL_Y(row + 1) - 1; + cairo_set_source_rgba(cr, + gui.fgcolor->red, gui.fgcolor->green, + gui.fgcolor->blue, gui.fgcolor->alpha); + cairo_set_line_width(cr, 1.0); + cairo_move_to(cr, FILL_X(col), y + 0.5); + cairo_line_to(cr, FILL_X(col + cells), y + 0.5); + cairo_stroke(cr); + } + + // Draw undercurl + if (flags & DRAW_UNDERC) + { + static const int val[8] = {1, 0, 0, 0, 1, 2, 2, 2}; + int y = FILL_Y(row + 1) - 1; + int i, offset; + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgba(cr, + gui.spcolor->red, gui.spcolor->green, + gui.spcolor->blue, gui.spcolor->alpha); + cairo_move_to(cr, FILL_X(col) + 1, y - 2 + 0.5); + for (i = FILL_X(col) + 1; i < FILL_X(col + cells); ++i) + { + offset = val[i % 8]; + cairo_line_to(cr, i, y - offset + 0.5); + } + cairo_stroke(cr); + } + + // Draw strikethrough + if (flags & DRAW_STRIKE) + { + int y = FILL_Y(row) + gui.char_height / 2; + cairo_set_source_rgba(cr, + gui.fgcolor->red, gui.fgcolor->green, + gui.fgcolor->blue, gui.fgcolor->alpha); + cairo_set_line_width(cr, 1.0); + cairo_move_to(cr, FILL_X(col), y + 0.5); + cairo_line_to(cr, FILL_X(col + cells), y + 0.5); + cairo_stroke(cr); + } +} + +/* + * Draw a string of characters on the screen. + * "force_pango" is set when ligature characters require Pango shaping + * instead of the fast ASCII glyph cache path. + * Returns the number of display cells used. + */ + int +gui_gtk_draw_string_ext( + int row, + int col, + char_u *s, + int len, + int flags, + int force_pango) +{ + GdkRectangle area; + PangoGlyphString *glyphs; + int column_offset = 0; + int i; + cairo_t *cr; + + if (gui.text_context == NULL || gui.surface == NULL) + return len; + + // Restrict all drawing to the current screen line. + area.x = gui.border_offset; + area.y = FILL_Y(row); + area.width = gui.num_cols * gui.char_width; + area.height = gui.char_height; + + cr = cairo_create(gui.surface); + cairo_rectangle(cr, area.x, area.y, area.width, area.height); + cairo_clip(cr); + + glyphs = pango_glyph_string_new(); + + // Fast path for pure ASCII: use cached glyph table. + // Skip this path when force_pango is set (ligatures need shaping). + if (!(flags & DRAW_ITALIC) + && !((flags & DRAW_BOLD) && gui.font_can_bold) + && gui.ascii_glyphs != NULL + && !force_pango) + { + char_u *p; + + for (p = s; p < s + len; ++p) + if (*p & 0x80) + goto not_ascii; + + pango_glyph_string_set_size(glyphs, len); + + for (i = 0; i < len; ++i) + { + glyphs->glyphs[i] = gui.ascii_glyphs->glyphs[2 * s[i]]; + glyphs->log_clusters[i] = i; + } + + draw_glyph_string(row, col, len, flags, gui.ascii_font, glyphs, cr); + + column_offset = len; + } + else + { +not_ascii:; + PangoAttrList *attr_list; + GList *item_list; + int cluster_width; + int last_glyph_rbearing; + int cells = 0; + + // Safety check: pango crashes with invalid utf-8. + if (!utf_valid_string(s, s + len)) + { + column_offset = len; + goto skipitall; + } + + cluster_width = PANGO_SCALE * gui.char_width; + last_glyph_rbearing = PANGO_SCALE * gui.char_width; + + attr_list = pango_attr_list_new(); + + // If 'guifontwide' is set then use that for double-width characters. + if (gui.wide_font != NULL) + apply_wide_font_attr(s, len, attr_list); + + if ((flags & DRAW_BOLD) && gui.font_can_bold) + INSERT_PANGO_ATTR(pango_attr_weight_new(PANGO_WEIGHT_BOLD), + attr_list, 0, len); + if (flags & DRAW_ITALIC) + INSERT_PANGO_ATTR(pango_attr_style_new(PANGO_STYLE_ITALIC), + attr_list, 0, len); + + item_list = pango_itemize(gui.text_context, + (const char *)s, 0, len, attr_list, NULL); + + while (item_list != NULL) + { + PangoItem *item; + int item_cells = 0; + + item = (PangoItem *)item_list->data; + item_list = g_list_delete_link(item_list, item_list); + + // Force LTR direction; Vim handles bidi on its own. + item->analysis.level = (item->analysis.level + 1) & (~1U); + + pango_shape_full((const char *)s + item->offset, item->length, + (const char *)s, len, &item->analysis, glyphs); + + // Fixed-width hack: assign a fixed width to each glyph based on + // the number of cells it occupies, handling composing characters + // and cluster boundaries properly. + for (i = 0; i < glyphs->num_glyphs; ++i) + { + PangoGlyphInfo *glyph; + + glyph = &glyphs->glyphs[i]; + + if (glyph->attr.is_cluster_start) + { + int cellcount; + + cellcount = count_cluster_cells( + s, item, glyphs, i, &cluster_width, + (item_list != NULL) ? &last_glyph_rbearing : NULL); + + if (cellcount > 0) + { + int width; + + width = cellcount * gui.char_width * PANGO_SCALE; + glyph->geometry.x_offset += + MAX(0, width - cluster_width) / 2; + glyph->geometry.width = width; + } + else + { + setup_zero_width_cluster(item, glyph, cells, + cluster_width, + last_glyph_rbearing); + } + + item_cells += cellcount; + cells = cellcount; + } + else if (i > 0) + { + int width; + + if (glyph->geometry.x_offset >= 0) + { + glyphs->glyphs[i].geometry.width = + glyphs->glyphs[i - 1].geometry.width; + glyphs->glyphs[i - 1].geometry.width = 0; + } + width = cells * gui.char_width * PANGO_SCALE; + glyph->geometry.x_offset += + MAX(0, width - cluster_width) / 2; + } + else + { + glyph->geometry.width = 0; + } + } + + draw_glyph_string(row, col + column_offset, item_cells, + flags, item->analysis.font, glyphs, cr); + + pango_item_free(item); + + column_offset += item_cells; + } + + pango_attr_list_unref(attr_list); + } + +skipitall: + draw_under(flags, row, col, column_offset, cr); + + pango_glyph_string_free(glyphs); + + cairo_destroy(cr); + + if (gui.drawarea != NULL) + gtk_widget_queue_draw(gui.drawarea); + + return column_offset; +} + +/* + * Draw a string of characters on the screen using the current font and colors. + * Splits the string into ASCII and ligature/UTF-8 segments so that ligature + * characters are sent through Pango for proper shaping, while plain ASCII + * uses the fast cached glyph path. + * Returns the number of display cells used. + */ + int +gui_gtk_draw_string(int row, int col, char_u *s, int len, int flags) +{ + char_u *conv_buf = NULL; + int convlen; + int len_sum; + int byte_sum; + char_u *cs; + int needs_pango; + int should_need_pango = FALSE; + int slen; + int is_ligature; + int is_utf8; + char_u backup_ch; + + if (gui.text_context == NULL || gui.surface == NULL) + return len; + + if (output_conv.vc_type != CONV_NONE) + { + convlen = len; + conv_buf = string_convert(&output_conv, s, &convlen); + if (conv_buf != NULL) + { + s = conv_buf; + len = convlen; + } + } + + /* + * Ligature support: + * Split the string into segments that are either pure ASCII (fast path) + * or ligature/UTF-8 (Pango path). A single ligature character between + * ASCII characters is treated as ASCII since it can't form a ligature + * on its own. + */ + len_sum = 0; + byte_sum = 0; + cs = s; + + // First char decides starting mode. + is_utf8 = (*cs & 0x80); + is_ligature = gui.ligatures_map[*cs] && (len > 1); + if (is_ligature) + is_ligature = gui.ligatures_map[*(cs + 1)]; + if (!is_utf8 && len > 1) + is_utf8 = (*(cs + 1) & 0x80) != 0; + needs_pango = is_utf8 || is_ligature; + + while (cs < s + len) + { + slen = 0; + while (slen < (len - byte_sum)) + { + is_ligature = gui.ligatures_map[*(cs + slen)]; + // Look ahead: single ligature char between ASCII is ASCII. + if (is_ligature && !needs_pango) + { + if ((slen + 1) < (len - byte_sum)) + is_ligature = gui.ligatures_map[*(cs + slen + 1)]; + else + is_ligature = 0; + } + is_utf8 = *(cs + slen) & 0x80; + // ASCII followed by UTF-8 could be combining. + if ((!is_utf8) && ((slen + 1) < (len - byte_sum))) + is_utf8 = (*(cs + slen + 1) & 0x80); + should_need_pango = (is_ligature || is_utf8); + if (needs_pango != should_need_pango) + break; + if (needs_pango) + { + if (is_ligature) + { + slen++; + } + else + { + if ((*(cs + slen) & 0xC0) == 0x80) + { + while ((slen < (len - byte_sum)) + && ((*(cs + slen) & 0xC0) == 0x80)) + slen++; + } + else if ((*(cs + slen) & 0xE0) == 0xC0) + slen++; + else if ((*(cs + slen) & 0xF0) == 0xE0) + slen += 2; + else if ((*(cs + slen) & 0xF8) == 0xF0) + slen += 3; + else + slen++; + } + } + else + { + slen++; + } + } + + if (slen < len) + { + backup_ch = *(cs + slen); + *(cs + slen) = NUL; + } + len_sum += gui_gtk_draw_string_ext(row, col + len_sum, cs, slen, + flags, needs_pango); + if (slen < len) + *(cs + slen) = backup_ch; + cs += slen; + byte_sum += slen; + needs_pango = should_need_pango; + } + vim_free(conv_buf); + return len_sum; +} + + int +gui_get_x11_windis(Window *win UNUSED, Display **dis UNUSED) +{ + // GTK4: not applicable + return FAIL; +} + +#if defined(FEAT_MENU) + void +gui_gtk_set_mnemonics(int enable UNUSED) +{ + // TODO: implement? +} + + static void +popupmenu_closed_cb(GtkPopover *popover, gpointer data UNUSED) +{ + gtk_widget_unparent(GTK_WIDGET(popover)); + if (gui.drawarea != NULL) + gtk_widget_queue_draw(gui.drawarea); +} + +typedef struct { + GtkPopover *popover; + vimmenu_T *menu; +} popup_item_data_T; + + static void +popup_item_clicked_cb(GtkButton *button UNUSED, gpointer data) +{ + popup_item_data_T *d = data; + + if (d->popover != NULL) + gtk_popover_popdown(d->popover); + if (d->menu != NULL) + { + gui_menu_cb(d->menu); + gui_mch_flush(); + } +} + + static void +popup_item_data_free(gpointer data, GClosure *closure UNUSED) +{ + g_free(data); +} + +/* + * Open a popup for the given menu at point (x, y). + */ + static void +gui_gtk_popup_at(vimmenu_T *menu, int x, int y) +{ + GtkWidget *popover; + GtkWidget *box; + GtkWidget *parent; + GdkRectangle rect; + vimmenu_T *child; + int mode; + int natural_width = 0; + + if (menu == NULL || menu->children == NULL) + return; + + // Attach the popover to drawarea's parent rather than to drawarea itself. + // GtkDrawingArea is a leaf widget whose snapshot does not iterate children, + // and parenting a popover to it has been observed to leave the drawing area + // blank while the popover is open. + parent = gtk_widget_get_parent(gui.drawarea); + if (parent == NULL) + parent = gui.drawarea; + + // Build the popover by hand instead of using gtk_popover_menu_new_from_model. + // GtkPopoverMenu relies on the "menu." action-group lookup walking up + // the parent chain, which has been observed to silently fail on some + // compositors when the popover is parented via gtk_widget_set_parent. Wiring + // each menu item to a plain "clicked" signal sidesteps that entirely. + popover = gtk_popover_new(); + gtk_widget_set_parent(popover, parent); + gtk_popover_set_has_arrow(GTK_POPOVER(popover), FALSE); + gtk_popover_set_position(GTK_POPOVER(popover), GTK_POS_BOTTOM); + gtk_widget_add_css_class(popover, "menu"); + + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_popover_set_child(GTK_POPOVER(popover), box); + + mode = get_menu_mode_flag(); + + for (child = menu->children; child != NULL; child = child->next) + { + GtkWidget *item; + char_u *label; + popup_item_data_T *cb_data; + + if (menu_is_separator(child->name)) + { + item = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); + gtk_box_append(GTK_BOX(box), item); + continue; + } + + label = CONVERT_TO_UTF8(child->dname); + item = gtk_button_new_with_mnemonic( + label != NULL ? (const char *)label : ""); + CONVERT_TO_UTF8_FREE(label); + + gtk_widget_add_css_class(item, "flat"); + gtk_widget_add_css_class(item, "model"); + gtk_button_set_has_frame(GTK_BUTTON(item), FALSE); + gtk_widget_set_halign(item, GTK_ALIGN_FILL); + { + GtkWidget *btn_label = gtk_button_get_child(GTK_BUTTON(item)); + if (GTK_IS_LABEL(btn_label)) + gtk_label_set_xalign(GTK_LABEL(btn_label), 0.0); + } + + if (!(child->modes & child->enabled & mode)) + gtk_widget_set_sensitive(item, FALSE); + + cb_data = g_new0(popup_item_data_T, 1); + cb_data->popover = GTK_POPOVER(popover); + cb_data->menu = child; + g_signal_connect_data(item, "clicked", + G_CALLBACK(popup_item_clicked_cb), + cb_data, popup_item_data_free, 0); + + gtk_box_append(GTK_BOX(box), item); + } + + rect.x = x; + rect.y = y; + // GtkPopover with GTK_POS_BOTTOM centres horizontally on the pointing-to + // rectangle. Use the box's natural width so the popover's left edge ends + // up at the cursor (down-and-to-the-right of the pointer). + gtk_widget_measure(box, GTK_ORIENTATION_HORIZONTAL, -1, + NULL, &natural_width, NULL, NULL); + rect.width = natural_width > 0 ? natural_width : 1; + rect.height = 1; + gtk_popover_set_pointing_to(GTK_POPOVER(popover), &rect); + + g_signal_connect(popover, "closed", + G_CALLBACK(popupmenu_closed_cb), NULL); + gtk_popover_popup(GTK_POPOVER(popover)); +} + + void +gui_make_popup(char_u *path_name, int mouse_pos) +{ + vimmenu_T *menu; + int x, y; + + menu = gui_find_menu(path_name); + if (menu == NULL || menu->submenu_id == NULL) + return; + + if (mouse_pos) + gui_mch_getmouse(&x, &y); + else + { + // Find the cursor position relative to parent of drawarea + GtkWidget *parent = gtk_widget_get_parent(gui.drawarea); + graphene_point_t point; + if (parent == NULL) + parent = gui.drawarea; + + if (!gtk_widget_compute_point(gui.drawarea, parent, + &GRAPHENE_POINT_INIT(0, 0), &point)) + x = y = 0; + else + { + x = point.x; + y = point.y; + } + + x += FILL_X(curwin->w_wincol + curwin->w_wcol + 1) + 1; + y += FILL_Y(W_WINROW(curwin) + curwin->w_wrow + 1) + 1; + } + + gui_gtk_popup_at(menu, x, y); + +} +#endif // FEAT_MENU + + int +get_menu_tool_width(void) +{ + return 0; +} + + int +get_menu_tool_height(void) +{ + GtkWidget *widgets[] = { +#ifdef FEAT_MENU + gui.menubar, +#endif +#ifdef FEAT_TOOLBAR + gui.toolbar, +#endif +#ifdef FEAT_GUI_TABLINE + gui.tabline +#endif + }; + + int height = 0; + + for (int i = 0; i < ARRAY_LENGTH(widgets); i++) + { + GtkRequisition min; + GtkRequisition nat; + int h; + + if (widgets[i] == NULL || !gtk_widget_get_visible(widgets[i])) + continue; + + h = gtk_widget_get_height(widgets[i]); + + if (h == 0) + { + // Allocation hasn't been updated yet (widget just became visible). + // Query the preferred height so the caller gets a valid value + // before the layout pass runs. Use the maximum of minimum and + // natural height: GTK may allocate min_h even when natural_h is + // smaller (e.g. GtkNotebook tab bar has min_h > natural_h due to + // CSS). + gtk_widget_get_preferred_size(widgets[i], &min, &nat); + height += MAX(min.height, nat.height); + } + else + height += h; + } + return height; +} + +/* + * Get the GdkClipboard for the given Clipboard_T. + * clip_star (*) uses PRIMARY, clip_plus (+) uses CLIPBOARD. + */ + static GdkClipboard * +gtk4_get_clipboard(Clipboard_T *cbd) +{ + GdkDisplay *display; + + if (gui.mainwin == NULL) + return NULL; + + display = gtk_widget_get_display(gui.mainwin); + if (display == NULL) + return NULL; + + if (cbd == &clip_plus) + return gdk_display_get_clipboard(display); + else + return gdk_display_get_primary_clipboard(display); +} + +typedef struct { + Clipboard_T *cbd; + gboolean done; +} ClipReadData; + +/* + * Callback for gdk_clipboard_read_text_async(). + */ + static void +clip_read_text_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + GdkClipboard *clipboard = GDK_CLIPBOARD(source); + ClipReadData *crd = (ClipReadData *)user_data; + Clipboard_T *cbd = crd->cbd; + char *text; + GError *error = NULL; + + text = gdk_clipboard_read_text_finish(clipboard, result, &error); + if (text != NULL) + { + char_u *tmpbuf = NULL; + char_u *p; + int len; + int motion_type = MAUTO; + + len = (int)STRLEN(text); + + // Convert from UTF-8 to 'encoding' if needed. + if (input_conv.vc_type != CONV_NONE) + { + tmpbuf = string_convert(&input_conv, (char_u *)text, &len); + if (tmpbuf != NULL) + p = tmpbuf; + else + p = (char_u *)text; + } + else + p = (char_u *)text; + + // Chop off any trailing NUL bytes. + while (len > 0 && p[len - 1] == NUL) + --len; + + clip_yank_selection(motion_type, p, (long)len, cbd); + vim_free(tmpbuf); + g_free(text); + } + else + { + if (error != NULL) + g_error_free(error); + } + crd->done = TRUE; +} + +/* + * Request the selection from the clipboard. + */ + void +clip_mch_request_selection(Clipboard_T *cbd) +{ + GdkClipboard *clipboard; + ClipReadData crd; + time_t start; + + clipboard = gtk4_get_clipboard(cbd); + if (clipboard == NULL) + return; + + crd.cbd = cbd; + crd.done = FALSE; + gdk_clipboard_read_text_async(clipboard, NULL, clip_read_text_cb, &crd); + + // Spin until the async callback fires, with a 3-second wall-clock + // timeout as a safety net. + start = time(NULL); + while (!crd.done && time(NULL) < start + 3) + g_main_context_iteration(NULL, TRUE); +} + +static int in_clipboard_set = FALSE; + +/* + * Send the current selection to the clipboard. + */ + void +clip_mch_set_selection(Clipboard_T *cbd) +{ + GdkClipboard *clipboard; + char_u *str = NULL; + long_u len; + int motion_type; + + clipboard = gtk4_get_clipboard(cbd); + if (clipboard == NULL) + return; + + // Get the selection text from the register. + clip_get_selection(cbd); + motion_type = clip_convert_selection(&str, &len, cbd); + if (motion_type < 0 || str == NULL) + return; + + // Convert from 'encoding' to UTF-8 if needed. + if (output_conv.vc_type != CONV_NONE) + { + char_u *conv_str; + int conv_len = (int)len; + + conv_str = string_convert(&output_conv, str, &conv_len); + if (conv_str != NULL) + { + vim_free(str); + str = conv_str; + len = conv_len; + } + } + + // Ensure NUL-terminated string for GTK. + { + char_u *nul_str = alloc(len + 1); + + if (nul_str != NULL) + { + mch_memmove(nul_str, str, len); + nul_str[len] = NUL; + in_clipboard_set = TRUE; + gdk_clipboard_set_text(clipboard, (const char *)nul_str); + in_clipboard_set = FALSE; + vim_free(nul_str); + } + } + + vim_free(str); +} + + static void +clipboard_changed_cb(GdkClipboard *clipboard, gpointer user_data) +{ + Clipboard_T *cbd = (Clipboard_T *)user_data; + + if (in_clipboard_set) + return; + if (gdk_clipboard_is_local(clipboard)) + return; + clip_lose_selection(cbd); +} + +/* + * Own the selection. In GTK4, ownership is implicit when content is set + * on the clipboard. Return OK to indicate we can own it. + */ + int +clip_mch_own_selection(Clipboard_T *cbd UNUSED) +{ + return OK; +} + +/* + * Disown the selection. In GTK4, we clear the clipboard content to + * release ownership. + */ + void +clip_mch_lose_selection(Clipboard_T *cbd) +{ + GdkClipboard *clipboard; + + clipboard = gtk4_get_clipboard(cbd); + if (clipboard == NULL) + return; + + // Only release ownership if we still own it. Otherwise we would + // clobber another application's clipboard content with NULL, which + // happens when this is called from clipboard_changed_cb after a + // foreign app took the selection. + if (gdk_clipboard_is_local(clipboard)) + gdk_clipboard_set_content(clipboard, NULL); +} + +// Balloon eval - use GTK4 tooltip + void +gui_mch_post_balloon(BalloonEval *beval UNUSED, char_u *mesg) +{ + if (mesg != NULL && gui.drawarea != NULL) + { + char_u *text = CONVERT_TO_UTF8(mesg); + gtk_widget_set_tooltip_text(gui.drawarea, (const char *)text); + CONVERT_TO_UTF8_FREE(text); + } + else if (gui.drawarea != NULL) + gtk_widget_set_tooltip_text(gui.drawarea, NULL); +} + + BalloonEval * +gui_mch_create_beval_area(void *target UNUSED, char_u *mesg UNUSED, + void (*mesgCB)(BalloonEval *, int) UNUSED, void *clientData UNUSED) +{ + return NULL; +} + + void +gui_mch_enable_beval_area(BalloonEval *beval UNUSED) +{ +} + + void +gui_mch_disable_beval_area(BalloonEval *beval UNUSED) +{ +} + +// GTK4 does not have gtk_main_level/gtk_main_quit. +// Provide compatibility stubs using a simple flag. + guint +gtk_main_level(void) +{ + return gtk4_main_loop_level; +} + + void +gtk_main_quit(void) +{ + gtk4_main_loop_quit = TRUE; +} + +#if defined(FEAT_MOUSESHAPE) + +// Table of CSS cursor names corresponding to Vim's mouse shape IDs. +// Keep in sync with the mshape_names[] table in misc2.c. +static const char *mshape_css_names[] = +{ + "default", // arrow + "none", // blank + "text", // beam + "ns-resize", // updown + "nwse-resize", // udsizing + "ew-resize", // leftright + "ew-resize", // lrsizing + "progress", // busy + "not-allowed", // no + "crosshair", // crosshair + "pointer", // hand1 + "pointer", // hand2 + "default", // pencil (no CSS analogue) + "help", // question + "default", // right-arrow (no CSS analogue) + "default", // up-arrow (no CSS analogue) + "default" // last entry +}; + + void +mch_set_mouse_shape(int shape) +{ + GdkCursor *c; + const char *css_name = "default"; + + if (gui.drawarea == NULL) + return; + + if (shape == MSHAPE_HIDE || gui.pointer_hidden) + gtk_widget_set_cursor(gui.drawarea, gui.blank_pointer); + else + { + if (shape >= MSHAPE_NUMBERED) + css_name = "default"; + else if (shape < (int)ARRAY_LENGTH(mshape_css_names)) + css_name = mshape_css_names[shape]; + else + return; + + // GTK4: gdk_cursor_new_from_name(name, fallback) + c = gdk_cursor_new_from_name(css_name, NULL); + gtk_widget_set_cursor(gui.drawarea, c); + g_object_unref(G_OBJECT(c)); + } + if (shape != MSHAPE_HIDE) + last_shape = shape; +} + +#else // !FEAT_MOUSESHAPE + + void +mch_set_mouse_shape(int shape UNUSED) +{ +} + +#endif // FEAT_MOUSESHAPE + + + +/* + * Menus, scrollbars, dialogs, toolbar. + * (merged from gui_gtk4.c) + */ + + + +static int last_text_area_w = 0; +static int last_text_area_h = 0; + +/* + * ============================================================ + * Menu functions + * ============================================================ + * TODO: Implement using GMenu + GtkPopoverMenuBar + */ + +/* + * Icon name table for toolbar buttons. + * Must match toolbar_names[] in menu.c. + */ +static const char * const toolbar_icon_names[] = +{ + /* 00 */ "document-new", + /* 01 */ "document-open", + /* 02 */ "document-save", + /* 03 */ "edit-undo", + /* 04 */ "edit-redo", + /* 05 */ "edit-cut", + /* 06 */ "edit-copy", + /* 07 */ "edit-paste", + /* 08 */ "document-print", + /* 09 */ "help-browser", + /* 10 */ "edit-find", + /* 11 */ "document-save", // save all (no standard icon) + /* 12 */ "document-save", // session save + /* 13 */ "document-new", // session new + /* 14 */ "document-open", // session load + /* 15 */ "system-run", + /* 16 */ "edit-find-replace", + /* 17 */ "window-close", + /* 18 */ "window-maximize-symbolic", // maximize + /* 19 */ "window-minimize-symbolic", // minimize + /* 20 */ "window-maximize-symbolic", // split (no standard icon) + /* 21 */ "utilities-terminal", // shell + /* 22 */ "go-previous", + /* 23 */ "go-next", + /* 24 */ "help-browser", // find help + /* 25 */ "edit-find", // convert (no standard icon) + /* 26 */ "go-jump", + /* 27 */ "go-previous", // back (reuse) + /* 28 */ "go-next", // forward (reuse) + /* 29 */ "image-missing", + /* 30 */ "image-missing", +}; + + static void +toolbar_button_clicked_cb(GtkWidget *widget UNUSED, gpointer data) +{ + gui_menu_cb((vimmenu_T *)data); +} + + static GtkWidget * +create_toolbar_icon(vimmenu_T *menu) +{ + char_u buf[MAXPATHL]; + GtkWidget *image = NULL; + + // Try specified icon file first + if (menu->iconfile != NULL) + { + expand_env(menu->iconfile, buf, MAXPATHL); + if (vim_fexists(buf)) + { + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale( + (const char *)buf, 24, 24, TRUE, NULL); + if (pixbuf != NULL) + { + GdkTexture *texture = + gdk_texture_new_for_pixbuf(pixbuf); + image = gtk_image_new_from_paintable( + GDK_PAINTABLE(texture)); + g_object_unref(texture); + g_object_unref(pixbuf); + } + } + } + + // Use themed icon + if (image == NULL) + { + const char *icon_name = "image-missing"; + int n = (int)ARRAY_LENGTH(toolbar_icon_names); + + if (menu->iconidx >= 0 && menu->iconidx < n) + icon_name = toolbar_icon_names[menu->iconidx]; + + image = gtk_image_new_from_icon_name(icon_name); + } + + return image; +} + +/* + * GTK4 Menu system using GMenu + GSimpleActionGroup + GtkPopoverMenuBar. + * + * Each menu/submenu has a GMenu stored in menu->submenu_id (cast to + * GtkWidget* to fit the struct field type). + * Actions are added to a GSimpleActionGroup attached to gui.mainwin. + */ + +static int menu_action_id = 0; + + static void +menu_action_cb(GSimpleAction *action UNUSED, GVariant *parameter UNUSED, + gpointer data) +{ + // Force-close any open popover menus in the menubar. + // GTK4 marks them as not-visible but Vim's custom main loop + // may not process the rendering update, so we flush explicitly. + if (gui.menubar != NULL) + { + GtkWidget *item; + + for (item = gtk_widget_get_first_child(gui.menubar); + item != NULL; + item = gtk_widget_get_next_sibling(item)) + { + GtkWidget *child; + + for (child = gtk_widget_get_first_child(item); + child != NULL; + child = gtk_widget_get_next_sibling(child)) + { + if (GTK_IS_POPOVER(child)) + gtk_popover_popdown(GTK_POPOVER(child)); + } + } + } + + gui_menu_cb((vimmenu_T *)data); + gui_mch_flush(); +} + + static char * +make_action_name(vimmenu_T *menu) +{ + // Create a unique action name from the menu pointer + static char buf[64]; + vim_snprintf(buf, sizeof(buf), "menu%d", menu_action_id++); + return buf; +} + + void +gui_mch_add_menu(vimmenu_T *menu, int idx UNUSED) +{ + GMenu *submenu; + + if (menu->name[0] == ']' || menu_is_popup(menu->name)) + { + // Popup menus - just create a GMenu, don't add to menubar + submenu = g_menu_new(); + menu->submenu_id = (GtkWidget *)(gpointer)submenu; + return; + } + + if (menu->parent != NULL && menu->parent->submenu_id == NULL) + return; + if (!menu_is_menubar(menu->name)) + return; + + // Create a submenu for this menu + submenu = g_menu_new(); + menu->submenu_id = (GtkWidget *)(gpointer)submenu; + + // Add to parent menu or menubar's model + { + GMenu *parent_menu; + char_u *label; + + label = CONVERT_TO_UTF8(menu->dname); + + if (menu->parent != NULL) + parent_menu = (GMenu *)(gpointer)menu->parent->submenu_id; + else + parent_menu = (GMenu *)(gpointer)g_object_get_data( + G_OBJECT(gui.menubar), "vim-gmenu"); + + if (parent_menu != NULL) + g_menu_append_submenu(parent_menu, (const char *)label, + G_MENU_MODEL(submenu)); + + CONVERT_TO_UTF8_FREE(label); + } +} + + void +gui_mch_add_menu_item(vimmenu_T *menu, int idx UNUSED) +{ + vimmenu_T *parent = menu->parent; + +#ifdef FEAT_TOOLBAR + if (parent != NULL && menu_is_toolbar(parent->name)) + { + if (menu_is_separator(menu->name)) + { + GtkWidget *sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); + gtk_box_append(GTK_BOX(gui.toolbar), sep); + menu->id = sep; + } + else + { + GtkWidget *btn; + GtkWidget *icon; + char_u *tooltip; + + icon = create_toolbar_icon(menu); + btn = gtk_button_new(); + gtk_button_set_child(GTK_BUTTON(btn), icon); + gtk_widget_set_focusable(btn, FALSE); + gtk_widget_add_css_class(btn, "flat"); + + tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]); + if (tooltip != NULL && utf_valid_string(tooltip, NULL)) + gtk_widget_set_tooltip_text(btn, (const gchar *)tooltip); + CONVERT_TO_UTF8_FREE(tooltip); + + g_signal_connect(btn, "clicked", + G_CALLBACK(toolbar_button_clicked_cb), menu); + + gtk_box_append(GTK_BOX(gui.toolbar), btn); + menu->id = btn; + } + return; + } +#endif + + // Menu items (non-toolbar) + if (parent == NULL || parent->submenu_id == NULL) + return; + + { + GMenu *parent_menu = (GMenu *)(gpointer)parent->submenu_id; + + if (menu_is_separator(menu->name)) + { + // GMenu doesn't have real separators; use a section + GMenu *section = g_menu_new(); + g_menu_append_section(parent_menu, NULL, G_MENU_MODEL(section)); + g_object_unref(section); + menu->id = NULL; + } + else + { + char *action_name; + char detailed[80]; + char_u *label; + GSimpleAction *action; + + // Create a unique action + action_name = make_action_name(menu); + action = g_simple_action_new(action_name, NULL); + g_signal_connect(action, "activate", + G_CALLBACK(menu_action_cb), menu); + + if (menu_action_group == NULL) + { + menu_action_group = g_simple_action_group_new(); + gtk_widget_insert_action_group(gui.mainwin, "menu", + G_ACTION_GROUP(menu_action_group)); + } + g_action_map_add_action(G_ACTION_MAP(menu_action_group), + G_ACTION(action)); + g_object_unref(action); + + label = CONVERT_TO_UTF8(menu->dname); + vim_snprintf(detailed, sizeof(detailed), "menu.%s", action_name); + g_menu_append(parent_menu, (const char *)label, detailed); + CONVERT_TO_UTF8_FREE(label); + + menu->id = (GtkWidget *)1; // non-NULL marker + // Store action name for later use (grey/enable) + menu->label = (GtkWidget *)vim_strsave( + (char_u *)action_name); + } + } +} + + void +gui_mch_toggle_tearoffs(int enable UNUSED) +{ + // GTK4: tearoff menus don't exist. +} + + void +gui_mch_menu_set_tip(vimmenu_T *menu UNUSED) +{ +} + +/* + * Return TRUE if "menu" has a corresponding entry in its parent's GMenu. + * Popup menus, toolbar children and orphaned submenus do not. + */ + static int +menu_has_gmenu_slot(vimmenu_T *menu) +{ + if (menu == NULL || menu->name == NULL) + return FALSE; + if (menu->name[0] == ']' || menu_is_popup(menu->name)) + return FALSE; + if (menu->parent != NULL) + { + if (menu_is_toolbar(menu->parent->name)) + return FALSE; + if (menu->parent->submenu_id == NULL) + return FALSE; + return TRUE; + } + return menu_is_menubar(menu->name); +} + +/* + * Find the parent GMenu containing the entry for "menu" and the position of + * that entry. Returns TRUE on success. + */ + static int +get_gmenu_pos_in_parent(vimmenu_T *menu, GMenu **parent_out, int *pos_out) +{ + GMenu *parent_gmenu; + vimmenu_T *first_sibling; + vimmenu_T *sib; + int pos = 0; + + if (!menu_has_gmenu_slot(menu)) + return FALSE; + + if (menu->parent != NULL) + { + parent_gmenu = (GMenu *)(gpointer)menu->parent->submenu_id; + first_sibling = menu->parent->children; + } + else + { + if (gui.menubar == NULL) + return FALSE; + parent_gmenu = (GMenu *)(gpointer)g_object_get_data( + G_OBJECT(gui.menubar), "vim-gmenu"); + first_sibling = root_menu; + } + if (parent_gmenu == NULL) + return FALSE; + + for (sib = first_sibling; sib != NULL && sib != menu; sib = sib->next) + if (menu_has_gmenu_slot(sib)) + pos++; + if (sib != menu) + return FALSE; + + *parent_out = parent_gmenu; + *pos_out = pos; + return TRUE; +} + + void +gui_mch_destroy_menu(vimmenu_T *menu) +{ + GMenu *parent_gmenu = NULL; + int pos = 0; + + // For toolbar buttons and separators, remove from the toolbar box. + if (menu->id != NULL && menu->id != (GtkWidget *)1) + { + GtkWidget *parent_widget = gtk_widget_get_parent(menu->id); + + if (parent_widget != NULL) + gtk_box_remove(GTK_BOX(parent_widget), menu->id); + } + menu->id = NULL; + + // Remove the entry from the parent GMenu so the visible menu updates. + if (get_gmenu_pos_in_parent(menu, &parent_gmenu, &pos)) + g_menu_remove(parent_gmenu, pos); + + // Remove the GAction created for this item and free its name. + if (menu->label != NULL) + { + if (menu_action_group != NULL) + g_action_map_remove_action(G_ACTION_MAP(menu_action_group), + (const char *)menu->label); + VIM_CLEAR(menu->label); + } + + // Release our reference on the submenu GMenu (if any). + if (menu->submenu_id != NULL) + { + g_object_unref(menu->submenu_id); + menu->submenu_id = NULL; + } +} + + void +gui_mch_show_popupmenu(vimmenu_T *menu) +{ + int x, y; + + gui_mch_getmouse(&x, &y); + gui_gtk_popup_at(menu, x, y); +} + + static void +show_menubar_popover(void) +{ + GMenu *gmenu; + GtkWidget *popover; + GdkRectangle rect; + + if (gui.menubar == NULL || gui.drawarea == NULL) + return; + gmenu = (GMenu *)g_object_get_data(G_OBJECT(gui.menubar), "vim-gmenu"); + if (gmenu == NULL || g_menu_model_get_n_items(G_MENU_MODEL(gmenu)) == 0) + return; + + popover = gtk_popover_menu_new_from_model(G_MENU_MODEL(gmenu)); + gtk_widget_set_parent(popover, gui.drawarea); + gtk_popover_set_has_arrow(GTK_POPOVER(popover), FALSE); + gtk_popover_set_position(GTK_POPOVER(popover), GTK_POS_BOTTOM); + rect.x = 0; + rect.y = 0; + rect.width = 1; + rect.height = 1; + gtk_popover_set_pointing_to(GTK_POPOVER(popover), &rect); + g_signal_connect(popover, "closed", + G_CALLBACK(popupmenu_closed_cb), NULL); + gtk_popover_popup(GTK_POPOVER(popover)); +} + +/* + * ============================================================ + * Scrollbar functions + * ============================================================ + */ + + void +gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max) +{ + GtkAdjustment *adj; + + if (sb->id == NULL) + return; + if (!GTK_IS_WIDGET(sb->id) || !GTK_IS_SCROLLBAR(sb->id)) + return; + + adj = gtk_scrollbar_get_adjustment(GTK_SCROLLBAR(sb->id)); + gtk_adjustment_set_lower(adj, 0.0); + gtk_adjustment_set_upper(adj, (gdouble)max + 1); + gtk_adjustment_set_value(adj, (gdouble)val); + gtk_adjustment_set_step_increment(adj, 1.0); + gtk_adjustment_set_page_increment(adj, (gdouble)(size > 2 ? size - 2 : 1)); + gtk_adjustment_set_page_size(adj, (gdouble)size); +} + + void +gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h) +{ + if (sb->id != NULL) + vim_form_move_resize(VIM_FORM(gui.formwin), sb->id, x, y, w, h); +} + + int +gui_mch_get_scrollbar_xpadding(void) +{ + int formwin_w = gtk_widget_get_width(gui.formwin); + int sbar_w = 0; + int xpad; + + if (gui.which_scrollbars[SBAR_LEFT]) + sbar_w += gui.scrollbar_width; + if (gui.which_scrollbars[SBAR_RIGHT]) + sbar_w += gui.scrollbar_width; + + xpad = formwin_w - last_text_area_w - sbar_w; + return (xpad < 0) ? 0 : xpad; +} + + int +gui_mch_get_scrollbar_ypadding(void) +{ + int formwin_h = gtk_widget_get_height(gui.formwin); + int ypad; + + ypad = formwin_h - last_text_area_h; + if (gui.which_scrollbars[SBAR_BOTTOM]) + ypad -= gui.scrollbar_height; + + return (ypad < 0) ? 0 : ypad; +} + + static void +adjustment_value_changed(GtkAdjustment *adj, gpointer data UNUSED) +{ + scrollbar_T *sb = (scrollbar_T *)g_object_get_data(G_OBJECT(adj), "vim-sb"); + long value = (long)gtk_adjustment_get_value(adj); + + if (sb != NULL) + gui_drag_scrollbar(sb, value, FALSE); +} + + void +gui_mch_create_scrollbar(scrollbar_T *sb, int orient) +{ + GtkAdjustment *adj; + if (orient == SBAR_HORIZ) + sb->id = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL); + else + sb->id = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL); + + gtk_widget_add_css_class(sb->id, "vim-scrollbar"); + adj = gtk_scrollbar_get_adjustment(GTK_SCROLLBAR(sb->id)); + + gtk_widget_set_visible(sb->id, FALSE); + vim_form_put(VIM_FORM(gui.formwin), sb->id, 0, 0); + + g_object_set_data(G_OBJECT(adj), "vim-sb", (gpointer)sb); + g_signal_connect(G_OBJECT(adj), "value-changed", + G_CALLBACK(adjustment_value_changed), NULL); +} + + void +gui_mch_destroy_scrollbar(scrollbar_T *sb) +{ + if (sb->id != NULL) + { + vim_form_remove(VIM_FORM(gui.formwin), sb->id); + sb->id = NULL; + } +} + +/* + * Try getting the actual size of the scrollbar, and update gui.scrollbar_width + * and gui.scrollbar_height. + */ + void +gui_mch_update_scrollbar_size(void) +{ + win_T *wp; + int w = -1, h = -1; + GtkWidget *sbar; + + FOR_ALL_WINDOWS(wp) + { + sbar = wp->w_scrollbars[SBAR_LEFT].id; + + if (sbar == NULL || !gtk_widget_get_visible(sbar) + || (!gui.which_scrollbars[SBAR_LEFT] + && wp->w_scrollbars[SBAR_RIGHT].id != NULL)) + sbar = wp->w_scrollbars[SBAR_RIGHT].id; + + if (sbar != NULL && gtk_widget_get_visible(sbar)) + { + GtkRequisition min, nat; + int sw; + + // Use preferred size, since widget may not have its size allocated + // yet. + gtk_widget_get_preferred_size(sbar, &min, &nat); + sw = MAX(min.width, nat.width); + if (sw > 0) + { + w = sw; + break; + } + } + + } + + sbar = gui.bottom_sbar.id; + if (sbar != NULL && gtk_widget_get_visible(sbar)) + { + GtkRequisition min, nat; + int sh; + + gtk_widget_get_preferred_size(sbar, &min, &nat); + sh = MAX(min.height, nat.height); + + if (sh > 0) + h = sh; + } + + if (w != -1) + gui.scrollbar_width = w; + if (h != -1) + gui.scrollbar_height = h; +} + +/* + * ============================================================ + * Text area position + * ============================================================ + */ + + void +gui_mch_set_text_area_pos(int x, int y, int w, int h) +{ + last_text_area_w = w; + last_text_area_h = h; + // Don't use vim_form_move_resize for drawarea because its + // set_size_request would prevent the window from shrinking. + // Just update position; the actual allocation is handled by + // vim_form_size_allocate which gives drawarea the formwin's full size. + vim_form_move(VIM_FORM(gui.formwin), gui.drawarea, x, y); + + // Surface sizing is owned by drawarea_resize_cb; don't recreate it + // here. Recreating on every text-area change wiped any preserved + // content whenever a sub-cell resize shifted the cell grid, and + // update_screen() may bail (char_avail()) during a drag and leave + // the fresh surface blank. +} + +/* + * ============================================================ + * Browse dialogs + * ============================================================ + */ + +/* + * Blocking helper: run a GtkFileDialog and wait for result. + */ +typedef struct { + GFile *result; + gboolean done; +} FileDialogData; + + static void +file_dialog_open_cb(GObject *source, GAsyncResult *res, gpointer data) +{ + FileDialogData *fdd = (FileDialogData *)data; + fdd->result = gtk_file_dialog_open_finish( + GTK_FILE_DIALOG(source), res, NULL); + fdd->done = TRUE; +} + + static void +file_dialog_save_cb(GObject *source, GAsyncResult *res, gpointer data) +{ + FileDialogData *fdd = (FileDialogData *)data; + fdd->result = gtk_file_dialog_save_finish( + GTK_FILE_DIALOG(source), res, NULL); + fdd->done = TRUE; +} + + static void +file_dialog_folder_cb(GObject *source, GAsyncResult *res, gpointer data) +{ + FileDialogData *fdd = (FileDialogData *)data; + fdd->result = gtk_file_dialog_select_folder_finish( + GTK_FILE_DIALOG(source), res, NULL); + fdd->done = TRUE; +} + + char_u * +gui_mch_browse(int saving, + char_u *title, + char_u *dflt, + char_u *ext UNUSED, + char_u *initdir, + char_u *filter UNUSED) +{ + GtkFileDialog *dlg; + FileDialogData fdd; + char_u dirbuf[MAXPATHL]; + char_u *result = NULL; + + title = CONVERT_TO_UTF8(title); + + if (initdir == NULL || *initdir == NUL) + mch_dirname(dirbuf, MAXPATHL); + else if (vim_FullName(initdir, dirbuf, MAXPATHL - 2, FALSE) == FAIL) + dirbuf[0] = NUL; + add_pathsep(dirbuf); + + gui_mch_mousehide(FALSE); + + dlg = gtk_file_dialog_new(); + gtk_file_dialog_set_modal(dlg, TRUE); + if (title != NULL) + gtk_file_dialog_set_title(dlg, (const char *)title); + + { + GFile *dir = g_file_new_for_path((const char *)dirbuf); + gtk_file_dialog_set_initial_folder(dlg, dir); + g_object_unref(dir); + } + + if (saving && dflt != NULL && *dflt != NUL) + gtk_file_dialog_set_initial_name(dlg, (const char *)dflt); + + fdd.result = NULL; + fdd.done = FALSE; + + if (saving) + gtk_file_dialog_save(dlg, GTK_WINDOW(gui.mainwin), NULL, + file_dialog_save_cb, &fdd); + else + gtk_file_dialog_open(dlg, GTK_WINDOW(gui.mainwin), NULL, + file_dialog_open_cb, &fdd); + + while (!fdd.done) + g_main_context_iteration(NULL, TRUE); + + if (fdd.result != NULL) + { + char *path = g_file_get_path(fdd.result); + if (path != NULL) + { + result = vim_strsave((char_u *)path); + g_free(path); + } + g_object_unref(fdd.result); + } + + g_object_unref(dlg); + CONVERT_TO_UTF8_FREE(title); + + return result; +} + + char_u * +gui_mch_browsedir(char_u *title, char_u *initdir) +{ + GtkFileDialog *dlg; + FileDialogData fdd; + char_u *result = NULL; + + title = CONVERT_TO_UTF8(title); + gui_mch_mousehide(FALSE); + + dlg = gtk_file_dialog_new(); + gtk_file_dialog_set_modal(dlg, TRUE); + if (title != NULL) + gtk_file_dialog_set_title(dlg, (const char *)title); + + if (initdir != NULL && *initdir != NUL) + { + GFile *dir = g_file_new_for_path((const char *)initdir); + gtk_file_dialog_set_initial_folder(dlg, dir); + g_object_unref(dir); + } + + fdd.result = NULL; + fdd.done = FALSE; + + gtk_file_dialog_select_folder(dlg, GTK_WINDOW(gui.mainwin), NULL, + file_dialog_folder_cb, &fdd); + + while (!fdd.done) + g_main_context_iteration(NULL, TRUE); + + if (fdd.result != NULL) + { + char *path = g_file_get_path(fdd.result); + if (path != NULL) + { + result = vim_strsave((char_u *)path); + g_free(path); + } + g_object_unref(fdd.result); + } + + g_object_unref(dlg); + CONVERT_TO_UTF8_FREE(title); + + return result; +} + +/* + * ============================================================ + * Message dialog + * ============================================================ + */ + +typedef struct { + int response; + gboolean done; +} AlertDialogData; + + static void +alert_dialog_cb(GObject *source, GAsyncResult *res, gpointer data) +{ + AlertDialogData *add = (AlertDialogData *)data; + add->response = gtk_alert_dialog_choose_finish( + GTK_ALERT_DIALOG(source), res, NULL); + add->done = TRUE; +} + + int +gui_mch_dialog( + int type UNUSED, + char_u *title, + char_u *message, + char_u *buttons, + int dfltbutton, + char_u *textfield UNUSED, + int ex_cmd UNUSED) +{ + GtkAlertDialog *dlg; + AlertDialogData add; + char_u *p; + char_u *buf = NULL; + int butcount = 0; + int i; + const char *btn_labels[64]; + char_u *btn_conv[64]; + + title = CONVERT_TO_UTF8(title); + message = CONVERT_TO_UTF8(message); + + // Parse button labels from the "&Yes\n&No\n&Cancel" format + if (buttons != NULL) + { + buf = vim_strsave(buttons); + if (buf != NULL) + { + p = buf; + while (*p != NUL && butcount < 63) + { + char_u *start = p; + while (*p != NUL && *p != '\n') + ++p; + if (*p == '\n') + *p++ = NUL; + // Skip '&' mnemonic marker + if (*start == '&') + ++start; + btn_conv[butcount] = CONVERT_TO_UTF8(start); + btn_labels[butcount] = (const char *)btn_conv[butcount]; + butcount++; + } + } + } + btn_labels[butcount] = NULL; + + dlg = gtk_alert_dialog_new("%s", message ? (char *)message : ""); + if (title != NULL) + gtk_alert_dialog_set_detail(dlg, (const char *)title); + gtk_alert_dialog_set_buttons(dlg, btn_labels); + gtk_alert_dialog_set_modal(dlg, TRUE); + + if (dfltbutton > 0 && dfltbutton <= butcount) + gtk_alert_dialog_set_default_button(dlg, dfltbutton - 1); + if (butcount > 0) + gtk_alert_dialog_set_cancel_button(dlg, butcount - 1); + + add.response = -1; + add.done = FALSE; + + gtk_alert_dialog_choose(dlg, GTK_WINDOW(gui.mainwin), NULL, + alert_dialog_cb, &add); + + while (!add.done) + g_main_context_iteration(NULL, TRUE); + + g_object_unref(dlg); + + for (i = 0; i < butcount; i++) + CONVERT_TO_UTF8_FREE(btn_conv[i]); + vim_free(buf); + CONVERT_TO_UTF8_FREE(title); + CONVERT_TO_UTF8_FREE(message); + + // GTK returns 0-based index, Vim wants 1-based + return add.response >= 0 ? add.response + 1 : 0; +} + +/* + * ============================================================ + * Find/Replace dialogs + * ============================================================ + */ + +/* + * ============================================================ + * Find/Replace dialog + * ============================================================ + */ + +typedef struct +{ + GtkWidget *dialog; + GtkWidget *what; // Find what entry + GtkWidget *with; // Replace with entry + GtkWidget *wword; // Whole word check + GtkWidget *mcase; // Match case check + GtkWidget *up; // Direction up radio + GtkWidget *down; // Direction down radio +} SharedFindReplace; + +static SharedFindReplace find_widgets = {0}; +static SharedFindReplace repl_widgets = {0}; + + static void +find_replace_cb(GtkWidget *widget UNUSED, gpointer data) +{ + int flags; + char_u *find_text; + char_u *repl_text; + gboolean direction_down; + SharedFindReplace *sfr; + + flags = GPOINTER_TO_INT(data); + + if (flags == FRD_FINDNEXT) + { + repl_text = NULL; + sfr = &find_widgets; + } + else + { + repl_text = (char_u *)gtk_editable_get_text( + GTK_EDITABLE(repl_widgets.with)); + sfr = &repl_widgets; + } + + find_text = (char_u *)gtk_editable_get_text(GTK_EDITABLE(sfr->what)); + direction_down = gtk_check_button_get_active( + GTK_CHECK_BUTTON(sfr->down)); + + if (gtk_check_button_get_active(GTK_CHECK_BUTTON(sfr->wword))) + flags |= FRD_WHOLE_WORD; + if (gtk_check_button_get_active(GTK_CHECK_BUTTON(sfr->mcase))) + flags |= FRD_MATCH_CASE; + + repl_text = CONVERT_FROM_UTF8(repl_text); + find_text = CONVERT_FROM_UTF8(find_text); + gui_do_findrepl(flags, find_text, repl_text, direction_down); + CONVERT_FROM_UTF8_FREE(repl_text); + CONVERT_FROM_UTF8_FREE(find_text); +} + + static void +dialog_destroyed_cb(GtkWidget *widget UNUSED, gpointer data) +{ + *(GtkWidget **)data = NULL; +} + + static void +find_replace_dialog_create(char_u *arg, int do_replace) +{ + SharedFindReplace *frdp; + char_u *entry_text; + int wword = FALSE; + int mcase = !p_ic; + GtkWidget *vertbox, *grid, *hbox, *tmp, *btn; + gboolean sensitive; + + frdp = do_replace ? &repl_widgets : &find_widgets; + entry_text = get_find_dialog_text(arg, &wword, &mcase); + + if (entry_text != NULL && output_conv.vc_type != CONV_NONE) + { + char_u *old = entry_text; + entry_text = string_convert(&output_conv, entry_text, NULL); + vim_free(old); + } + + // If the dialog already exists, just raise it. + if (frdp->dialog) + { + if (entry_text != NULL) + { + gtk_editable_set_text(GTK_EDITABLE(frdp->what), + (char *)entry_text); + gtk_check_button_set_active(GTK_CHECK_BUTTON(frdp->wword), + (gboolean)wword); + gtk_check_button_set_active(GTK_CHECK_BUTTON(frdp->mcase), + (gboolean)mcase); + } + gtk_window_present(GTK_WINDOW(frdp->dialog)); + gtk_widget_grab_focus(frdp->what); + vim_free(entry_text); + return; + } + + // Create a new dialog window. + frdp->dialog = gtk_window_new(); + gtk_window_set_transient_for(GTK_WINDOW(frdp->dialog), + GTK_WINDOW(gui.mainwin)); + gtk_window_set_destroy_with_parent(GTK_WINDOW(frdp->dialog), TRUE); + gtk_window_set_title(GTK_WINDOW(frdp->dialog), + do_replace ? _("VIM - Search and Replace...") + : _("VIM - Search...")); + gtk_window_set_resizable(GTK_WINDOW(frdp->dialog), FALSE); + + g_signal_connect(frdp->dialog, "destroy", + G_CALLBACK(dialog_destroyed_cb), &frdp->dialog); + + vertbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); + gtk_widget_set_margin_start(vertbox, 12); + gtk_widget_set_margin_end(vertbox, 12); + gtk_widget_set_margin_top(vertbox, 12); + gtk_widget_set_margin_bottom(vertbox, 12); + gtk_window_set_child(GTK_WINDOW(frdp->dialog), vertbox); + + // Grid for labels + entries + grid = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(grid), 6); + gtk_grid_set_column_spacing(GTK_GRID(grid), 6); + gtk_box_append(GTK_BOX(vertbox), grid); + + // "Find what:" label + entry + tmp = gtk_label_new(_("Find what:")); + gtk_label_set_xalign(GTK_LABEL(tmp), 0.0); + gtk_grid_attach(GTK_GRID(grid), tmp, 0, 0, 1, 1); + + frdp->what = gtk_entry_new(); + gtk_widget_set_hexpand(frdp->what, TRUE); + sensitive = (entry_text != NULL && entry_text[0] != NUL); + if (entry_text != NULL) + gtk_editable_set_text(GTK_EDITABLE(frdp->what), (char *)entry_text); + gtk_grid_attach(GTK_GRID(grid), frdp->what, 1, 0, 1, 1); + + if (do_replace) + { + // "Replace with:" label + entry + tmp = gtk_label_new(_("Replace with:")); + gtk_label_set_xalign(GTK_LABEL(tmp), 0.0); + gtk_grid_attach(GTK_GRID(grid), tmp, 0, 1, 1, 1); + + frdp->with = gtk_entry_new(); + gtk_widget_set_hexpand(frdp->with, TRUE); + gtk_grid_attach(GTK_GRID(grid), frdp->with, 1, 1, 1, 1); + } + + // Checkboxes + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_append(GTK_BOX(vertbox), hbox); + + frdp->wword = gtk_check_button_new_with_label(_("Match whole word only")); + gtk_check_button_set_active(GTK_CHECK_BUTTON(frdp->wword), + (gboolean)wword); + gtk_box_append(GTK_BOX(hbox), frdp->wword); + + frdp->mcase = gtk_check_button_new_with_label(_("Match case")); + gtk_check_button_set_active(GTK_CHECK_BUTTON(frdp->mcase), + (gboolean)mcase); + gtk_box_append(GTK_BOX(hbox), frdp->mcase); + + // Direction radio buttons + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_append(GTK_BOX(vertbox), hbox); + + tmp = gtk_label_new(_("Direction:")); + gtk_box_append(GTK_BOX(hbox), tmp); + + frdp->up = gtk_check_button_new_with_label(_("Up")); + gtk_box_append(GTK_BOX(hbox), frdp->up); + + frdp->down = gtk_check_button_new_with_label(_("Down")); + gtk_check_button_set_group(GTK_CHECK_BUTTON(frdp->down), + GTK_CHECK_BUTTON(frdp->up)); + gtk_check_button_set_active(GTK_CHECK_BUTTON(frdp->down), TRUE); + gtk_box_append(GTK_BOX(hbox), frdp->down); + + // Action buttons + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); + gtk_widget_set_halign(hbox, GTK_ALIGN_END); + gtk_box_append(GTK_BOX(vertbox), hbox); + + btn = gtk_button_new_with_label(_("Find Next")); + gtk_widget_set_sensitive(btn, sensitive); + g_signal_connect(btn, "clicked", G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(do_replace ? FRD_R_FINDNEXT : FRD_FINDNEXT)); + gtk_box_append(GTK_BOX(hbox), btn); + + if (do_replace) + { + btn = gtk_button_new_with_label(_("Replace")); + g_signal_connect(btn, "clicked", G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(FRD_REPLACE)); + gtk_box_append(GTK_BOX(hbox), btn); + + btn = gtk_button_new_with_label(_("Replace All")); + g_signal_connect(btn, "clicked", G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(FRD_REPLACEALL)); + gtk_box_append(GTK_BOX(hbox), btn); + } + + btn = gtk_button_new_with_label(_("Close")); + g_signal_connect_swapped(btn, "clicked", + G_CALLBACK(gtk_window_destroy), frdp->dialog); + gtk_box_append(GTK_BOX(hbox), btn); + + // Connect Enter key in entry to Find Next + g_signal_connect_swapped(frdp->what, "activate", + G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(do_replace ? FRD_R_FINDNEXT : FRD_FINDNEXT)); + + gtk_window_present(GTK_WINDOW(frdp->dialog)); + gtk_widget_grab_focus(frdp->what); + if (do_replace && entry_text != NULL && entry_text[0] != NUL) + gtk_widget_grab_focus(frdp->with); + + vim_free(entry_text); +} + + void +gui_mch_find_dialog(exarg_T *eap) +{ + if (gui.in_use) + find_replace_dialog_create(eap->arg, FALSE); +} + + void +gui_mch_replace_dialog(exarg_T *eap) +{ + if (gui.in_use) + find_replace_dialog_create(eap->arg, TRUE); +} + +/* + * ============================================================ + * Help find (for :helpfind command) + * ============================================================ + */ + + void +ex_helpfind(exarg_T *eap UNUSED) +{ + do_cmdline_cmd((char_u *)"emenu ToolBar.FindHelp"); +} + + +/* + * ============================================================ + * Printing with GtkPrintOperation + * ============================================================ + */ +#ifdef FEAT_GUI_GTK_PRINT + +typedef struct +{ + linenr_T first_line; // first line to print (from range) + linenr_T last_line; // last line to print (from range) + int n_pages; // total number of pages + int lines_per_page; // lines that fit on one page + PangoFontDescription *font_desc; + int do_syntax; // whether to use syntax highlighting + double line_height; // line height in points + double char_width; // character width in points +} print_data_T; + +/* + * "begin-print" signal handler. + * Calculate pagination based on page size and font metrics. + */ + static void +print_begin_cb( + GtkPrintOperation *op, + GtkPrintContext *context, + gpointer user_data) +{ + print_data_T *pd = (print_data_T *)user_data; + PangoLayout *layout; + PangoFontMetrics *metrics; + double page_height; + int total_lines; + + page_height = gtk_print_context_get_height(context); + + // Create a PangoLayout to measure font metrics on the print surface. + layout = gtk_print_context_create_pango_layout(context); + pango_layout_set_font_description(layout, pd->font_desc); + + metrics = pango_context_get_metrics( + pango_layout_get_context(layout), + pd->font_desc, NULL); + + pd->line_height = (double)(pango_font_metrics_get_ascent(metrics) + + pango_font_metrics_get_descent(metrics)) / PANGO_SCALE; + pd->char_width = (double)pango_font_metrics_get_approximate_char_width( + metrics) / PANGO_SCALE; + + pango_font_metrics_unref(metrics); + g_object_unref(layout); + + if (pd->line_height <= 0) + pd->line_height = 12.0; + + pd->lines_per_page = (int)(page_height / pd->line_height); + if (pd->lines_per_page <= 0) + pd->lines_per_page = 1; + + total_lines = (int)(pd->last_line - pd->first_line + 1); + pd->n_pages = (total_lines + pd->lines_per_page - 1) / pd->lines_per_page; + if (pd->n_pages <= 0) + pd->n_pages = 1; + + gtk_print_operation_set_n_pages(op, pd->n_pages); +} + +/* + * "draw-page" signal handler. + * Render one page of buffer text with optional syntax highlighting. + */ + static void +print_draw_page_cb( + GtkPrintOperation *op UNUSED, + GtkPrintContext *context, + int page_nr, + gpointer user_data) +{ + print_data_T *pd = (print_data_T *)user_data; + cairo_t *cr; + linenr_T lnum; + linenr_T first; + linenr_T last; + int page_line; + double y; + + cr = gtk_print_context_get_cairo_context(context); + + first = pd->first_line + (linenr_T)page_nr * pd->lines_per_page; + last = first + pd->lines_per_page - 1; + if (last > pd->last_line) + last = pd->last_line; + + y = 0; + page_line = 0; + + for (lnum = first; lnum <= last; ++lnum, ++page_line) + { + char_u *line; + PangoLayout *layout; + PangoAttrList *attr_list; + + line = ml_get(lnum); + layout = gtk_print_context_create_pango_layout(context); + pango_layout_set_font_description(layout, pd->font_desc); + + attr_list = pango_attr_list_new(); + +# ifdef FEAT_SYN_HL + if (pd->do_syntax && syntax_present(curwin)) + { + colnr_T col; + int prev_syn_id = -1; + int attr_start = 0; + long_u prev_fg = 0; + int prev_bold = FALSE; + int prev_italic = FALSE; + int len = (int)STRLEN(line); + + for (col = 0; col < len; ) + { + int id; + int outputlen; + long_u fg_color; + int is_bold; + int is_italic; + + if (has_mbyte) + { + outputlen = (*mb_ptr2len)(line + col); + if (outputlen < 1) + outputlen = 1; + } + else + outputlen = 1; + + id = syn_get_id(curwin, lnum, col, 1, NULL, FALSE); + if (id > 0) + id = syn_get_final_id(id); + else + id = 0; + // syn_get_id may invalidate the line pointer. + line = ml_get(lnum); + + fg_color = highlight_gui_color_rgb(id, TRUE); + is_bold = (highlight_has_attr(id, HL_BOLD, 'g') != NULL); + is_italic = (highlight_has_attr(id, HL_ITALIC, 'g') != NULL); + + // When attributes change, flush the previous run. + if (id != prev_syn_id && col > 0) + { + if (prev_fg != 0 && prev_fg != (long_u)0xffffffL) + { + PangoAttribute *a = pango_attr_foreground_new( + (guint16)(((prev_fg >> 16) & 0xff) * 257), + (guint16)(((prev_fg >> 8) & 0xff) * 257), + (guint16)((prev_fg & 0xff) * 257)); + a->start_index = attr_start; + a->end_index = col; + pango_attr_list_insert(attr_list, a); + } + if (prev_bold) + { + PangoAttribute *a = pango_attr_weight_new( + PANGO_WEIGHT_BOLD); + a->start_index = attr_start; + a->end_index = col; + pango_attr_list_insert(attr_list, a); + } + if (prev_italic) + { + PangoAttribute *a = pango_attr_style_new( + PANGO_STYLE_ITALIC); + a->start_index = attr_start; + a->end_index = col; + pango_attr_list_insert(attr_list, a); + } + attr_start = col; + } + + prev_syn_id = id; + prev_fg = fg_color; + prev_bold = is_bold; + prev_italic = is_italic; + + col += outputlen; + } + + // Flush the last run. + if (attr_start < len) + { + if (prev_fg != 0 && prev_fg != (long_u)0xffffffL) + { + PangoAttribute *a = pango_attr_foreground_new( + (guint16)(((prev_fg >> 16) & 0xff) * 257), + (guint16)(((prev_fg >> 8) & 0xff) * 257), + (guint16)((prev_fg & 0xff) * 257)); + a->start_index = attr_start; + a->end_index = len; + pango_attr_list_insert(attr_list, a); + } + if (prev_bold) + { + PangoAttribute *a = pango_attr_weight_new( + PANGO_WEIGHT_BOLD); + a->start_index = attr_start; + a->end_index = len; + pango_attr_list_insert(attr_list, a); + } + if (prev_italic) + { + PangoAttribute *a = pango_attr_style_new( + PANGO_STYLE_ITALIC); + a->start_index = attr_start; + a->end_index = len; + pango_attr_list_insert(attr_list, a); + } + } + } +# endif // FEAT_SYN_HL + + pango_layout_set_attributes(layout, attr_list); + + // Expand tabs. Use a tab array matching Vim's tabstop. + { + PangoTabArray *tabs; + int tab_width = (int)(curbuf->b_p_ts * pd->char_width); + + if (tab_width <= 0) + tab_width = (int)(8 * pd->char_width); + tabs = pango_tab_array_new(1, TRUE); + pango_tab_array_set_tab(tabs, 0, PANGO_TAB_LEFT, tab_width); + pango_layout_set_tabs(layout, tabs); + pango_tab_array_free(tabs); + } + + pango_layout_set_text(layout, (const char *)line, -1); + + cairo_move_to(cr, 0, y); + pango_cairo_show_layout(cr, layout); + + pango_attr_list_unref(attr_list); + g_object_unref(layout); + + y += pd->line_height; + } +} + +/* + * Main entry point for GTK4 native printing. + * Called from ex_hardcopy() when running in a GTK4 GUI. + */ + void +gui_gtk4_hardcopy(exarg_T *eap) +{ + GtkPrintOperation *op; + GtkPrintOperationResult res; + print_data_T pd; + char_u *font_name; + + static GtkPrintSettings *settings = NULL; + + CLEAR_FIELD(pd); + pd.first_line = eap->line1; + pd.last_line = eap->line2; + + // Use 'printfont' if set, otherwise fall back to 'guifont'. + font_name = *p_pfn != NUL ? p_pfn : p_guifont; + if (font_name == NULL || *font_name == NUL) + font_name = (char_u *)"Monospace 10"; + + pd.font_desc = pango_font_description_from_string((const char *)font_name); + if (pd.font_desc == NULL) + { + semsg(_(e_unknown_font_str), font_name); + return; + } + + // Ensure the font description has a size (default 10pt if missing). + if (pango_font_description_get_size(pd.font_desc) == 0) + pango_font_description_set_size(pd.font_desc, 10 * PANGO_SCALE); + +# ifdef FEAT_SYN_HL + pd.do_syntax = syntax_present(curwin); +# endif + + op = gtk_print_operation_new(); + + if (settings != NULL) + gtk_print_operation_set_print_settings(op, settings); + + gtk_print_operation_set_job_name(op, + curbuf->b_fname != NULL + ? (const char *)curbuf->b_fname : "Vim"); + gtk_print_operation_set_show_progress(op, TRUE); + gtk_print_operation_set_unit(op, GTK_UNIT_POINTS); + + g_signal_connect(op, "begin-print", G_CALLBACK(print_begin_cb), &pd); + g_signal_connect(op, "draw-page", G_CALLBACK(print_draw_page_cb), &pd); + + res = gtk_print_operation_run(op, + GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, + GTK_WINDOW(gui.mainwin), NULL); + + if (res == GTK_PRINT_OPERATION_RESULT_APPLY) + { + if (settings != NULL) + g_object_unref(settings); + settings = g_object_ref( + gtk_print_operation_get_print_settings(op)); + } + + g_object_unref(op); + pango_font_description_free(pd.font_desc); +} + +#endif // FEAT_GUI_GTK_PRINT + +#endif // FEAT_GUI_GTK diff --git a/src/gui_gtk4_f.c b/src/gui_gtk4_f.c new file mode 100644 index 0000000000..14ff85f625 --- /dev/null +++ b/src/gui_gtk4_f.c @@ -0,0 +1,279 @@ +/* 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. + */ + +#include "vim.h" +#include +#include "gui_gtk4_f.h" + +/* + * Child widget at position (x, y). + */ +typedef struct +{ + GtkWidget *widget; + int x; + int y; +} VimFormChild; + +/* + * Similar to the GtkFixed widget, allows absolute position and sizing of child + * widgets within. Vim already has logic for positioning and sizing UI elements, + * so this is needed to take advantage of that. We don't use GtkFixed directly + * since we need to override some vfuncs. + */ +struct _VimForm +{ + GtkWidget parent; + + GList *children; + + // See vim_form_size_allocate() + guint resize_idle_id; + int last_width; + int last_height; +}; + +G_DEFINE_TYPE(VimForm, vim_form, GTK_TYPE_WIDGET) + +static void vim_form_snapshot(GtkWidget *widget, GtkSnapshot *snapshot); +static void vim_form_size_allocate(GtkWidget *widget, int width, int height, int baseline); +static void vim_form_measure(GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *minimum_baseline, int *natural_baseline); +static gboolean vim_form_contains(GtkWidget *widget, double x, double y); + + static void +vim_form_dispose(GObject *obj) +{ + VimForm *self = VIM_FORM(obj); + GList *ele = self->children; + + while (ele != NULL) + { + VimFormChild *child = ele->data; + + ele = ele->next; + gtk_widget_unparent(child->widget); + g_free(child); + } + g_list_free(self->children); + self->children = NULL; + + G_OBJECT_CLASS(vim_form_parent_class)->dispose(obj); +} + + static void +vim_form_class_init(VimFormClass *class) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class); + GObjectClass *obj_class = G_OBJECT_CLASS(class); + + widget_class->snapshot = vim_form_snapshot; + widget_class->size_allocate = vim_form_size_allocate; + widget_class->measure = vim_form_measure; + widget_class->contains = vim_form_contains; + + obj_class->dispose = vim_form_dispose; +} + + static void +vim_form_init(VimForm *self) +{ + +} + + GtkWidget * +vim_form_new(void) +{ + return g_object_new(VIM_TYPE_FORM, NULL); +} + +/* + * Transform the child + */ + static void +vim_form_position_child(VimForm *self, VimFormChild *child) +{ + GtkRequisition requisition; + GskTransform *transform; + int w, h; + + gtk_widget_get_preferred_size(child->widget, &requisition, NULL); + w = requisition.width; + h = requisition.height; + + // If widget has no size request, use parent size + if (w <= 0) + w = gtk_widget_get_width(GTK_WIDGET(self)); + if (h <= 0) + h = gtk_widget_get_height(GTK_WIDGET(self)); + if (w <= 0) w = 1; + if (h <= 0) h = 1; + + transform = gsk_transform_translate(NULL, + &GRAPHENE_POINT_INIT((float)child->x, (float)child->y)); + gtk_widget_allocate(child->widget, w, h, -1, transform); +} + +/* + * Place the given widget at the point (x, y). + */ + void +vim_form_put(VimForm *self, GtkWidget *widget, int x, int y) +{ + VimFormChild *child; + + child = g_new(VimFormChild, 1); + + child->widget = widget; + child->x = x; + child->y = y; + + gtk_widget_set_size_request(child->widget, -1, -1); + + self->children = g_list_append(self->children, child); + + gtk_widget_set_parent(widget, GTK_WIDGET(self)); + vim_form_position_child(self, child); +} + +/* + * Move the widget (which should have already been added using vim_form_put()) + * to the given point (x, y). + */ + void +vim_form_move(VimForm *self, GtkWidget *widget, int x, int y) +{ + for (GList *ele = self->children; ele != NULL; ele = ele->next) + { + VimFormChild *child = ele->data; + if (child->widget == widget) + { + child->x = x; + child->y = y; + vim_form_position_child(self, child); + return; + } + } +} + +/* + * Move and resize the child. + */ + void +vim_form_move_resize( + VimForm *self, + GtkWidget *widget, + gint x, + gint y, + gint w, + gint h) +{ + gtk_widget_set_size_request(widget, w, h); + vim_form_move(self, widget, x, y); +} + + void +vim_form_remove(VimForm *self, GtkWidget *widget) +{ + for (GList *ele = self->children; ele != NULL; ele = ele->next) + { + VimFormChild *child = ele->data; + if (child->widget == widget) + { + self->children = g_list_remove_link(self->children, ele); + g_list_free_1(ele); + gtk_widget_unparent(widget); + g_free(child); + return; + } + } +} + + static void +vim_form_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) +{ + VimForm *self = VIM_FORM(widget); + + for (GList *ele = self->children; ele != NULL; ele = ele->next) + { + VimFormChild *child = ele->data; + gtk_widget_snapshot_child(widget, child->widget, snapshot); + } +} + + static gboolean +vim_form_resize_idle_cb(VimForm *self) +{ + int w, h; + + self->resize_idle_id = 0; + + // Use drawarea's actual allocation, not formwin's + if (gui.drawarea == NULL) + goto exit; + w = gtk_widget_get_width(gui.drawarea); + h = gtk_widget_get_height(gui.drawarea); + + if (w > 1 && h > 1) + gui_resize_shell(w, h); + +exit: + g_object_unref(self); + return G_SOURCE_REMOVE; +} + + static void +vim_form_size_allocate( + GtkWidget *widget, + int width, + int height, + int baseline) +{ + VimForm *self = VIM_FORM(widget); + + for (GList *ele = self->children; ele != NULL; ele = ele->next) + vim_form_position_child(self, ele->data); + + // Notify Vim about size change via idle callback + if (width != self->last_width || height != self->last_height) + { + self->last_width = width; + self->last_height = height; + + if (self->resize_idle_id == 0) + self->resize_idle_id = g_idle_add( + (GSourceFunc)vim_form_resize_idle_cb, g_object_ref(self)); + } +} + + static void +vim_form_measure( + GtkWidget *widget UNUSED, + GtkOrientation orientation UNUSED, + int for_size UNUSED, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline) +{ + *minimum = 1; + *natural = 1; + *minimum_baseline = -1; + *natural_baseline = -1; +} + + +/* + * Make the form itself input-transparent so clicks on its empty area fall + * through to the drawarea below, while the scrollbar children stay pickable. + */ + static gboolean +vim_form_contains(GtkWidget *widget UNUSED, double x UNUSED, double y UNUSED) +{ + return FALSE; +} diff --git a/src/gui_gtk4_f.h b/src/gui_gtk4_f.h new file mode 100644 index 0000000000..d795b86c2e --- /dev/null +++ b/src/gui_gtk4_f.h @@ -0,0 +1,24 @@ +/* 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. + */ + +#ifndef GUI_GTK4_FORM_H +#define GUI_GTK4_FORM_H + +#include + +#define VIM_TYPE_FORM (vim_form_get_type()) +G_DECLARE_FINAL_TYPE(VimForm, vim_form, VIM, FORM, GtkWidget) + +GtkWidget *vim_form_new(void); +void vim_form_put(VimForm *self, GtkWidget *widget, int x, int y); +void vim_form_move(VimForm *self, GtkWidget *widget, int x, int y); +void vim_form_move_resize(VimForm *self, GtkWidget *widget, gint x, gint y, gint w, gint h); +void vim_form_remove(VimForm *self, GtkWidget *widget); + +#endif diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 21e8768abc..8b57eef088 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -80,13 +80,6 @@ extern void bonobo_dock_item_set_behavior(BonoboDockItem *dock_item, BonoboDockI # include #endif -#ifdef FEAT_SOCKETSERVER -# include - -// Used to track the source for the listening socket -static uint socket_server_source_id = 0; -#endif - /* * Easy-to-use macro for multihead support. */ @@ -408,11 +401,13 @@ static int using_gnome = 0; * Width and height are of gui.mainwin. */ typedef struct resize_history { - int used; // If true, can't match for discard. Only matches once. + int used; // If true, can't match for discard. Only matches once. int width; int height; + int from_shellsize; // TRUE if recorded by gui_mch_set_shellsize (not + // a pre-record from gui_mch_show_tabline). # ifdef ENABLE_RESIZE_HISTORY_LOG - int seq; // for ch_log messages + int seq; // for ch_log messages # endif struct resize_history *next; } resize_hist_T; @@ -422,13 +417,28 @@ static resize_hist_T *latest_resize_hist; // list of stale resize requests static resize_hist_T *old_resize_hists; +// On Wayland (and GTK3 with CSD), gtk_window_resize(w, h) results in +// gtk_window_get_size() returning (w - csd_w, h - csd_h). These offsets are +// computed once from the first confirmed resize response and applied to all +// subsequent gtk_window_resize() calls so the form gets the intended size. +static int mch_csd_width = 0; +static int mch_csd_height = 0; + +// Expected form widget width for the most recent gui_mch_set_shellsize() +// call (set only after mch_csd_width is known). Used in +// form_configure_event() to clamp slightly-narrow configure responses that +// result from CSD under-compensation, preventing column loss. +static int mch_pending_form_w = 0; + /* * Used when calling gtk_window_resize(). * Create a resize request history item, put previous request on stale list. * Width/height are the size of the request for the gui.mainwin. + * from_shellsize is TRUE when called from gui_mch_set_shellsize (vs a + * stale pre-record from gui_mch_show_tabline). */ static void -alloc_resize_hist(int width, int height) +alloc_resize_hist(int width, int height, int from_shellsize) { // alloc a new resize hist, save current in list of old history resize_hist_T *prev_hist = latest_resize_hist; @@ -436,6 +446,7 @@ alloc_resize_hist(int width, int height) new_hist->width = width; new_hist->height = height; + new_hist->from_shellsize = from_shellsize; latest_resize_hist = new_hist; // previous hist item becomes head of list @@ -657,7 +668,7 @@ gui_mch_prepare(int *argc, char **argv) break; #ifdef FEAT_NETBEANS_INTG case ARG_NETBEANS: - gui.dofork = FALSE; // don't fork() when starting GUI + gui.dofork = false; // don't fork() when starting GUI netbeansArg = argv[i]; break; #endif @@ -671,7 +682,7 @@ gui_mch_prepare(int *argc, char **argv) // Only when the GUI can start. if ((option->flags & ARG_NEEDS_GUI) && gui_mch_early_init_check(FALSE) == OK) - gui.starting = TRUE; + gui.starting = true; if (option->flags & ARG_KEEP) ++i; @@ -1692,7 +1703,7 @@ gui_mch_early_init_check(int give_message) q = mch_getenv((char_u *)"WAYLAND_DISPLAY"); if ((p == NULL || *p == NUL) && (q == NULL || *q == NUL)) { - gui.dying = TRUE; + gui.dying = true; if (give_message) emsg(_((char *)e_cannot_open_display)); return FAIL; @@ -1733,7 +1744,7 @@ gui_mch_init_check(void) // Don't use gtk_init() or gnome_init(), it exits on failure. if (!gtk_init_check(&gui_argc, &gui_argv)) { - gui.dying = TRUE; + gui.dying = true; emsg(_((char *)e_cannot_open_display)); return FAIL; } @@ -2672,54 +2683,6 @@ global_event_filter(GdkXEvent *xev, } #endif // !USE_GNOME_SESSION -#if defined(FEAT_SOCKETSERVER) - -/* - * Callback for new events from the socket server listening socket - */ - static int -socket_server_poll_in(int fd UNUSED, GIOCondition cond, void *user_data UNUSED) -{ - if (cond & G_IO_IN) - socket_server_accept_client(); - else if (cond & (G_IO_ERR | G_IO_HUP)) - { - socket_server_uninit(); - return FALSE; - } - - return TRUE; -} - -/* - * Initialize socket server for use in the GUI (does not actually initialize the - * socket server, only attaches a source). - */ - void -gui_gtk_init_socket_server(void) -{ - if (socket_server_source_id > 0) - return; - // Register source for file descriptor to global default context - socket_server_source_id = g_unix_fd_add(socket_server_get_fd(), - G_IO_IN | G_IO_ERR | G_IO_HUP, socket_server_poll_in, NULL); -} - -/* - * Remove the source for the socket server listening socket. - */ - void -gui_gtk_uninit_socket_server(void) -{ - if (socket_server_source_id > 0) - { - g_source_remove(socket_server_source_id); - socket_server_source_id = 0; - } -} - -#endif - static GdkPixbuf * pixbuf_new_from_png_data(const unsigned char *data, unsigned int len) { @@ -2887,6 +2850,18 @@ mainwin_screen_changed_cb(GtkWidget *widget, } } + static gboolean +mainwin_state_event_cb(GtkWidget *widget UNUSED, + GdkEventWindowState *event, + gpointer user_data UNUSED) +{ + if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) + // To redraw the text area when switching to fullscreen mode, we will + // reuse the `gui_focus_change` method. + gui_focus_change(TRUE); + return FALSE; +} + /* * After the drawing area comes up, we calculate all colors and create the * dummy blank cursor. @@ -3102,7 +3077,25 @@ get_item_dimensions(GtkWidget *widget, GtkOrientation orientation) GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); + if (allocation.height > 1) + return allocation.height; + + // Allocation hasn't been updated yet (widget just became visible, + // e.g. tab bar shown asynchronously on Wayland). Query the preferred + // height so the caller gets a valid value before the layout pass + // runs. Use the maximum of minimum and natural height: GTK may + // allocate min_h even when natural_h is smaller (e.g. GtkNotebook + // tab bar has min_h > natural_h due to CSS). +# if GTK_CHECK_VERSION(3,0,0) + { + gint min_h = 0, natural_h = 0; + + gtk_widget_get_preferred_height(widget, &min_h, &natural_h); + return MAX(min_h, natural_h); + } +# else return allocation.height; +# endif # else if (orientation == GTK_ORIENTATION_HORIZONTAL) return widget->allocation.height; @@ -3147,7 +3140,11 @@ get_menu_tool_height(void) height += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_HORIZONTAL); #endif #ifdef FEAT_GUI_TABLINE - if (gui.tabline != NULL) + // Only include the tabline height when tabs are actually shown. After + // gtk_notebook_set_show_tabs(FALSE) the widget allocation is not updated + // until the GTK main loop runs, so reading it would give a stale value. + if (gui.tabline != NULL + && gtk_notebook_get_show_tabs(GTK_NOTEBOOK(gui.tabline))) height += get_item_dimensions(gui.tabline, GTK_ORIENTATION_HORIZONTAL); #endif @@ -3438,6 +3435,17 @@ on_tabline_menu(GtkWidget *widget, GdkEvent *event) if (bevent->button == 3) { # if GTK_CHECK_VERSION(3,22,2) +# ifdef GDK_WINDOWING_WAYLAND + if (gui.is_wayland) + { + int x2, y2; + gui_gtk_get_pointer(gui.mainwin, &x2, &y2, NULL); + gtk_menu_popup_at_rect(GTK_MENU(widget), + gtk_widget_get_window(gui.mainwin), &(GdkRectangle){x2, y2, 1, 1}, + GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL); + } + else +# endif gtk_menu_popup_at_pointer(GTK_MENU(widget), event); # else gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL, @@ -3513,6 +3521,19 @@ gui_mch_show_tabline(int showit) if (!showit != !gtk_notebook_get_show_tabs(GTK_NOTEBOOK(gui.tabline))) { +# ifdef TRACK_RESIZE_HISTORY + // When the tabline visibility changes, GTK defers the formwin + // relayout. The resulting configure event fires while the mainwin is + // still at its current size. Pre-record that size so it becomes a + // stale (discardable) entry once gui_mch_set_shellsize() records the + // new target size. + { + int w, h; + + gtk_window_get_size(GTK_WINDOW(gui.mainwin), &w, &h); + alloc_resize_hist(w, h, FALSE); + } +# endif // Note: this may cause a resize event gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit); update_window_manager_hints(0, 0); @@ -3583,7 +3604,7 @@ gui_mch_update_tabline(void) gtk_notebook_insert_page(GTK_NOTEBOOK(gui.tabline), page, event_box, - nr++); + nr); # if GTK_CHECK_VERSION(2,10,0) gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(gui.tabline), page, @@ -3828,6 +3849,9 @@ gui_mch_init(void) g_signal_connect(G_OBJECT(gui.mainwin), "screen-changed", G_CALLBACK(&mainwin_screen_changed_cb), NULL); + g_signal_connect(G_OBJECT(gui.mainwin), "window-state-event", + G_CALLBACK(&mainwin_state_event_cb), NULL); + gui.accel_group = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(gui.mainwin), gui.accel_group); @@ -4171,7 +4195,7 @@ gui_mch_init(void) G_CALLBACK(scroll_event), NULL); // Pretend we don't have input focus, we will get an event if we do. - gui.in_focus = FALSE; + gui.in_focus = false; // Handle changes to the "Xft/DPI" setting. { @@ -4284,6 +4308,22 @@ gui_mch_new_colors(void) } } +/* + * One-shot idle callback to issue a corrective gtk_window_resize() after the + * startup configure event has been processed. At startup + * gui_mch_set_shellsize() runs before the CSD offsets are known (they are + * measured from the first configure response), so the window ends up + * mch_csd_height pixels too short and mch_csd_width pixels too narrow. This + * callback re-issues the shellsize with the now-known offsets so the physical + * window matches Vim's model. + */ + static gboolean +startup_resize_correction_cb(gpointer data UNUSED) +{ + gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH); + return FALSE; // one-shot +} + /* * This signal informs us about the need to rearrange our sub-widgets. */ @@ -4321,6 +4361,41 @@ form_configure_event(GtkWidget *widget UNUSED, && match_stale_width_height(w, h)) // discard stale event return TRUE; + + // On Wayland (GTK3 CSD), gtk_window_resize(w, req_h) results in + // gtk_window_get_size() returning (req_w - csd_w, req_h - csd_h). + // Compute the offsets once from the first confirmed resize response. + if ((mch_csd_height == 0 || mch_csd_width == 0) + && latest_resize_hist != NULL + && !latest_resize_hist->used + && latest_resize_hist->from_shellsize + && gui.char_height > 0) + { + int pot_csd_w = latest_resize_hist->width - w; + int pot_csd_h = latest_resize_hist->height - h; + + if (pot_csd_w > 0 && pot_csd_w < gui.char_width) + { + mch_csd_width = pot_csd_w; + // The resize that triggered this startup event was issued without + // CSD compensation; retroactively set the expected form width so + // that the clamp below corrects Columns for this same event. + mch_pending_form_w = (int)Columns * gui.char_width + + gui_get_base_width(); + } + if (pot_csd_h > 0 && pot_csd_h < gui.char_height) + { + mch_csd_height = pot_csd_h; + // Similarly, correct the form height for this event so that Rows + // is computed correctly despite the missing CSD compensation. + usable_height += mch_csd_height; + } + // The window was resized without CSD compensation and is physically + // too small. Schedule a corrective resize (now that offsets are + // known) so the window actually fits the geometry Vim has just set. + if ((mch_csd_height > 0 || mch_csd_width > 0) && gtk_socket_id == 0) + g_idle_add(startup_resize_correction_cb, NULL); + } clear_resize_hists(); #endif @@ -4354,9 +4429,22 @@ form_configure_event(GtkWidget *widget UNUSED, if (gtk_socket_id != 0) usable_height -= (gui.char_height - (gui.char_height/2)); // sic. - gui_gtk_form_freeze(GTK_FORM(gui.formwin)); - gui_resize_shell(event->width, usable_height); - gui_gtk_form_thaw(GTK_FORM(gui.formwin)); + // If the configure event delivers a form width that is slightly less than + // the width we intended (mch_pending_form_w), the difference is within + // one char_width and is due to CSD under-compensation. Clamp to the + // intended width so that column count does not drift downward. + { + int use_width = event->width; + +#ifdef TRACK_RESIZE_HISTORY + if (mch_pending_form_w > event->width + && mch_pending_form_w - event->width < gui.char_width) + use_width = mch_pending_form_w; +#endif + gui_gtk_form_freeze(GTK_FORM(gui.formwin)); + gui_resize_shell(use_width, usable_height); + gui_gtk_form_thaw(GTK_FORM(gui.formwin)); + } return TRUE; } @@ -4855,8 +4943,22 @@ gui_mch_set_shellsize(int width, int height, width += get_menu_tool_width(); height += get_menu_tool_height(); + // Compensate for CSD frame: on Wayland (GTK3 with CSD), the compositor + // subtracts the decoration margin from the requested size. mch_csd_width + // and mch_csd_height are computed from the first startup resize response + // and are 0 on X11. + width += mch_csd_width; + height += mch_csd_height; + + // Record the form width we expect the compositor to deliver. Used in + // form_configure_event() to clamp configure responses that are slightly + // narrower than intended (due to CSD startup underestimate), preventing + // column loss. Only meaningful once mch_csd_width has been measured. + mch_pending_form_w = (mch_csd_width > 0) + ? width - get_menu_tool_width() - mch_csd_width : 0; + #ifdef TRACK_RESIZE_HISTORY - alloc_resize_hist(width, height); // track the resize request + alloc_resize_hist(width, height, TRUE); #endif if (gtk_socket_id == 0) gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height); @@ -5168,7 +5270,7 @@ get_styled_font_variants(void) PangoFont *plain_font; PangoFont *bold_font; - gui.font_can_bold = FALSE; + gui.font_can_bold = false; plain_font = pango_context_load_font(gui.text_context, gui.norm_font); diff --git a/src/gui_motif.c b/src/gui_motif.c index 9f4a5856d0..e7e8a5340b 100644 --- a/src/gui_motif.c +++ b/src/gui_motif.c @@ -578,7 +578,7 @@ gui_x11_create_widgets(void) gui_x11_callbacks(textArea, vimForm); // Pretend we don't have input focus, we will get an event if we do. - gui.in_focus = FALSE; + gui.in_focus = false; } /* diff --git a/src/gui_w32.c b/src/gui_w32.c index 093c84176e..724266aebb 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -3731,7 +3731,7 @@ gui_mch_delete_lines( // scrolling such that the cursor ends up in the top-left character on // the screen... But why? (Webb) // It's probably fixed by disabling drawing the cursor while scrolling. - // gui.cursor_is_valid = FALSE; + // gui.cursor_is_valid = false; gui_clear_block(gui.scroll_region_bot - num_lines + 1, gui.scroll_region_left, diff --git a/src/gui_x11.c b/src/gui_x11.c index a61d47a077..dffa10cb64 100644 --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -1146,7 +1146,7 @@ gui_mch_prepare(int *argc, char **argv) #ifdef FEAT_NETBEANS_INTG if (strncmp("-nb", argv[arg], 3) == 0) { - gui.dofork = FALSE; // don't fork() when starting GUI + gui.dofork = false; // don't fork() when starting GUI netbeansArg = argv[arg]; mch_memmove(&argv[arg], &argv[arg + 1], (--*argc - arg) * sizeof(char *)); @@ -1197,7 +1197,7 @@ gui_mch_init_check(void) #endif if (app_context == NULL || gui.dpy == NULL) { - gui.dying = TRUE; + gui.dying = true; emsg(_(e_cannot_open_display)); return FAIL; } @@ -1419,9 +1419,6 @@ gui_mch_init(void) #endif } - if (gui.color_approx) - emsg(_(e_cannot_allocate_colormap_entry_some_colors_may_be_incorrect)); - #ifdef FEAT_BEVAL_GUI gui_init_tooltip_font(); #endif diff --git a/src/gui_xim.c b/src/gui_xim.c index c6537ba941..283fbf461c 100644 --- a/src/gui_xim.c +++ b/src/gui_xim.c @@ -18,15 +18,19 @@ #endif #if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) -# if GTK_CHECK_VERSION(3,0,0) +# ifdef USE_GTK4 +# include +# elif GTK_CHECK_VERSION(3,0,0) # include # else # include # endif -# ifdef MSWIN -# include -# else -# include +# if !defined(USE_GTK4) +# ifdef MSWIN +# include +# else +# include +# endif # endif #endif @@ -198,11 +202,24 @@ static int im_preedit_trailing = 0; // number of characters after cursor # ifndef FEAT_GUI_MACVIM static unsigned long im_commit_handler_id = 0; +# ifdef USE_GTK4 +static unsigned int im_activatekey_keyval = GDK_KEY_VoidSymbol; +# else static unsigned int im_activatekey_keyval = GDK_VoidSymbol; +# endif static unsigned int im_activatekey_state = 0; static GtkWidget *preedit_window = NULL; static GtkWidget *preedit_label = NULL; +# ifdef USE_GTK4 +static int preedit_label_width = 0; // last measured popover natural width +static int preedit_popover_height = 0; // last measured popover natural height +// CSS provider that styles the preedit popover frame; rebuilt whenever +// gui.back_pixel changes so the popover background matches the editor's +// background colour and fully covers the cursor cell. +static GtkCssProvider *preedit_css_provider = NULL; +static guicolor_T preedit_css_cached_bg = INVALCOLOR; +# endif static void im_preedit_window_set_position(void); # endif @@ -246,9 +263,28 @@ im_set_position(int row, int col) area.x = FILL_X(col); area.y = FILL_Y(row); - area.width = gui.char_width * (mb_lefthalve(row, col) ? 2 : 1); + // The screen buffer may not be allocated yet when this is called from + // xim_init() during gui_mch_init() to seed the IM's initial cursor + // location, so guard mb_lefthalve() against a NULL LineOffset[]. + area.width = gui.char_width + * ((ScreenLines != NULL && mb_lefthalve(row, col)) ? 2 : 1); area.height = gui.char_height; +# ifdef USE_GTK4 + // Stretch the cursor rect height to cover the preedit popover so the + // IM's candidate window is placed below the popover rather than on + // top of it. Coordinates stay in client-widget (drawarea) space; + // GTK4's IM module translates to the surface internally. + if (p_imst == IM_OVER_THE_SPOT) + { + int popover_h = preedit_popover_height; + if (popover_h <= 0) + popover_h = gui.char_height; + if (popover_h > area.height) + area.height = popover_h; + } +# endif + gtk_im_context_set_cursor_location(xic, &area); if (p_imst == IM_OVER_THE_SPOT) @@ -289,12 +325,46 @@ im_add_to_input(char_u *str, int len) static void im_preedit_window_set_position(void) { - int x, y, width, height; - int screen_x, screen_y, screen_width, screen_height; - if (preedit_window == NULL) return; +# ifdef USE_GTK4 + // GTK4: The popover is parented to gui.mainwin (the toplevel) rather + // than gui.drawarea, because GtkDrawingArea is a leaf widget that does + // not support children and causes snapshot/redraw artifacts when used + // as a popover parent. Translate the cursor cell coordinates from + // drawarea space to mainwin space, and use the cached label width as + // the anchor rect width so the popover's left edge aligns with the + // cursor cell: + // popup_origin.x = anchor.x + anchor.w/2 - popup_w/2 + // With anchor.w == label_w and popup_w ≈ label_w (after CSS zeroing + // popover frame padding), popup_origin.x ≈ anchor.x. + GdkRectangle rect; + graphene_point_t pt_in, pt_out; + + pt_in.x = FILL_X(gui.col); + pt_in.y = FILL_Y(gui.row); + if (!gtk_widget_compute_point(gui.drawarea, gui.mainwin, + &pt_in, &pt_out)) + { + pt_out.x = pt_in.x; + pt_out.y = pt_in.y; + } + rect.x = (int)pt_out.x; + rect.y = (int)pt_out.y; + rect.width = preedit_label_width; + rect.height = 0; + // make up for the difference between GVim's line height and GtkLabel's line height + int offset = gui.char_height - preedit_popover_height; + gtk_popover_set_offset(GTK_POPOVER(preedit_window), 0, offset); + // make the arrow pointer at start so that it only starts sliding + // horizontally when screen border is reached + gtk_widget_set_halign(preedit_window, GTK_ALIGN_START); + gtk_popover_set_pointing_to(GTK_POPOVER(preedit_window), &rect); +# else + int x, y, width, height; + int screen_x, screen_y, screen_width, screen_height; + gui_gtk_get_screen_geom_of_win(gui.drawarea, 0, 0, &screen_x, &screen_y, &screen_width, &screen_height); gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y); @@ -306,6 +376,7 @@ im_preedit_window_set_position(void) if (y + height > screen_y + screen_height) y = screen_y + screen_height - height; gtk_window_move(GTK_WINDOW(preedit_window), x, y); +# endif } static void @@ -328,15 +399,97 @@ im_preedit_window_open(void) if (preedit_window == NULL) { +# ifdef USE_GTK4 + // GTK4: use GtkPopover (xdg_popup) so the compositor keeps keyboard + // focus on the drawing area and does not disable text-input-v3. + // See issue #20257. Parent the popover to gui.mainwin (a real + // container) rather than gui.drawarea: GtkDrawingArea is a leaf + // widget and using it as a popover parent causes snapshot artifacts + // (white-out) on the drawing area. + preedit_window = gtk_popover_new(); + gtk_popover_set_autohide(GTK_POPOVER(preedit_window), FALSE); + gtk_popover_set_has_arrow(GTK_POPOVER(preedit_window), FALSE); + // Pin the popover below the anchor. Together with anchor.h == 0 in + // im_preedit_window_set_position() this lands the popover's top edge + // exactly on FILL_Y(row), so the popover covers the cursor cell rather + // than landing above it (the default GTK_POS_TOP would do that and + // only flip to bottom when there is no room above, which is flaky). + gtk_popover_set_position(GTK_POPOVER(preedit_window), GTK_POS_BOTTOM); + gtk_widget_set_can_focus(preedit_window, FALSE); + gtk_widget_set_focusable(preedit_window, FALSE); + gtk_widget_set_can_target(preedit_window, FALSE); + gtk_widget_set_parent(preedit_window, gui.mainwin); +# else preedit_window = gtk_window_new(GTK_WINDOW_POPUP); gtk_window_set_transient_for(GTK_WINDOW(preedit_window), GTK_WINDOW(gui.mainwin)); +# endif preedit_label = gtk_label_new(""); gtk_widget_set_name(preedit_label, "vim-gui-preedit-area"); +# ifdef USE_GTK4 + gtk_label_set_xalign(GTK_LABEL(preedit_label), 0.0); + gtk_widget_set_halign(preedit_label, GTK_ALIGN_START); + gtk_widget_set_valign(preedit_label, GTK_ALIGN_START); + // Tag the popover with a CSS class so the minimal frame CSS below + // (no border, no rounded corners, no shadow, no padding) applies + // only to our preedit popover and not other popovers in the app. + gtk_widget_add_css_class(preedit_window, "vim-preedit-popover"); + gtk_popover_set_child(GTK_POPOVER(preedit_window), preedit_label); +# else gtk_container_add(GTK_CONTAINER(preedit_window), preedit_label); +# endif } -# if GTK_CHECK_VERSION(3,16,0) +# ifdef USE_GTK4 + // Build (or rebuild on background-colour change) the CSS that flattens + // the popover frame and paints its background with gui.back_pixel. + // Using a solid background instead of `background: transparent` makes + // the popover surface fully cover the cursor cell even when the popover + // surface is allocated a pixel or two larger than the glyph bounding + // box (e.g. due to residual theme insets) -- otherwise the blinking + // text cursor at the cell origin shows through the popover frame. + if (preedit_css_provider == NULL || preedit_css_cached_bg != gui.back_pixel) + { + GdkDisplay *display = gdk_display_get_default(); + gchar *css; + + if (preedit_css_provider != NULL) + { + gtk_style_context_remove_provider_for_display(display, + GTK_STYLE_PROVIDER(preedit_css_provider)); + g_object_unref(preedit_css_provider); + } + preedit_css_provider = gtk_css_provider_new(); + css = g_strdup_printf( + "popover.vim-preedit-popover,\n" + "popover.vim-preedit-popover > contents,\n" + "popover.vim-preedit-popover label {\n" + " border: none;\n" + " border-radius: 0;\n" + " box-shadow: none;\n" + " padding: 0;\n" + " margin: 0;\n" + " min-width: 0;\n" + " min-height: 0;\n" + " background-color: #%02lx%02lx%02lx;\n" + "}\n" + "popover.vim-preedit-popover > arrow {\n" + " background: transparent;\n" + " border: none;\n" + "}\n", + (unsigned long)((gui.back_pixel >> 16) & 0xff), + (unsigned long)((gui.back_pixel >> 8) & 0xff), + (unsigned long)(gui.back_pixel & 0xff)); + gtk_css_provider_load_from_string(preedit_css_provider, css); + g_free(css); + gtk_style_context_add_provider_for_display(display, + GTK_STYLE_PROVIDER(preedit_css_provider), G_MAXUINT); + preedit_css_cached_bg = gui.back_pixel; + } +# endif + +# ifndef USE_GTK4 +# if GTK_CHECK_VERSION(3,16,0) { GtkStyleContext * const context = gtk_widget_get_style_context(preedit_label); @@ -344,8 +497,10 @@ im_preedit_window_open(void) gchar *css = NULL; const char * const fontname = pango_font_description_get_family(gui.norm_font); - gint fontsize - = pango_font_description_get_size(gui.norm_font) / PANGO_SCALE; + // Since font sizes can be specified as non-integer values like 10.5, + // they must be handled as floating-point (gdouble). + gdouble fontsize + = (gdouble)pango_font_description_get_size(gui.norm_font) / PANGO_SCALE; gchar *fontsize_propval = NULL; if (!pango_font_description_get_size_is_absolute(gui.norm_font)) @@ -358,7 +513,7 @@ im_preedit_window_open(void) fontsize = dpi * fontsize / 72; } if (fontsize > 0) - fontsize_propval = g_strdup_printf("%dpx", fontsize); + fontsize_propval = g_strdup_printf("%dpx", (gint)(fontsize + 0.5)); else fontsize_propval = g_strdup_printf("inherit"); @@ -386,7 +541,7 @@ im_preedit_window_open(void) g_free(fontsize_propval); g_object_unref(provider); } -# elif GTK_CHECK_VERSION(3,0,0) +# elif GTK_CHECK_VERSION(3,0,0) gtk_widget_override_font(preedit_label, gui.norm_font); vim_snprintf(buf, sizeof(buf), "#%06X", gui.norm_pixel); @@ -397,7 +552,7 @@ im_preedit_window_open(void) gdk_rgba_parse(&color, buf); gtk_widget_override_background_color(preedit_label, GTK_STATE_FLAG_NORMAL, &color); -# else +# else gtk_widget_modify_font(preedit_label, gui.norm_font); vim_snprintf(buf, sizeof(buf), "#%06X", (unsigned)gui.norm_pixel); @@ -407,23 +562,97 @@ im_preedit_window_open(void) vim_snprintf(buf, sizeof(buf), "#%06X", (unsigned)gui.back_pixel); gdk_color_parse(buf, &color); gtk_widget_modify_bg(preedit_window, GTK_STATE_NORMAL, &color); -# endif +# endif +# endif // !USE_GTK4 gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL); if (preedit_string[0] != NUL) { +# ifdef USE_GTK4 + // GTK4: drive all styling (font + foreground + background) via + // PangoAttributes on the label rather than CSS. This pins the + // preedit text to gui.norm_font (family + weight + style + size) + // and the editor colors without going through CSS DPI conversion + // or selector matching. These attributes are merged with whatever + // the IM gave us (e.g. underline for composing range). + PangoAttribute *pa; + + if (attr_list == NULL) + attr_list = pango_attr_list_new(); + + if (gui.norm_font != NULL) + { + pa = pango_attr_font_desc_new(gui.norm_font); + pa->start_index = 0; + pa->end_index = G_MAXUINT; + pango_attr_list_insert(attr_list, pa); + } + + pa = pango_attr_foreground_new( + ((gui.norm_pixel >> 16) & 0xff) * 257, + ((gui.norm_pixel >> 8) & 0xff) * 257, + (gui.norm_pixel & 0xff) * 257); + pa->start_index = 0; + pa->end_index = G_MAXUINT; + pango_attr_list_insert(attr_list, pa); + + pa = pango_attr_background_new( + ((gui.back_pixel >> 16) & 0xff) * 257, + ((gui.back_pixel >> 8) & 0xff) * 257, + (gui.back_pixel & 0xff) * 257); + pa->start_index = 0; + pa->end_index = G_MAXUINT; + pango_attr_list_insert(attr_list, pa); +# endif gtk_label_set_text(GTK_LABEL(preedit_label), preedit_string); gtk_label_set_attributes(GTK_LABEL(preedit_label), attr_list); layout = gtk_label_get_layout(GTK_LABEL(preedit_label)); pango_layout_get_pixel_size(layout, &w, &h); h = MAX(h, gui.char_height); - gtk_window_resize(GTK_WINDOW(preedit_window), w, h); +# ifdef USE_GTK4 + // Cache label/popover size derived from the Pango layout, which is + // available without mapping the popover. Using these for positioning + // avoids calling gtk_popover_set_pointing_to() after popup, which + // triggers a GDK "compositor doesn't support moving popups" warning + // on compositors without xdg_popup.reposition (e.g. Weston). + preedit_label_width = w; + preedit_popover_height = h; + // Report an enlarged cursor rectangle that covers both the cursor + // cell and the preedit popover. This way the IM (e.g. fcitx5) + // places its candidate window below the popover instead of on top + // of it. Coordinates are in client-widget (drawarea) space. + if (xic != NULL) + { + GdkRectangle area; + + area.x = FILL_X(gui.col); + area.y = FILL_Y(gui.row); + area.width = preedit_label_width; + area.height = MAX(gui.char_height, preedit_popover_height); + gtk_im_context_set_cursor_location(xic, &area); + } + + // Pop down before re-anchoring: on compositors that lack + // xdg_popup.reposition (e.g. Weston), calling set_pointing_to() on + // a mapped popover triggers GDK's remap fallback and a warning. + // Doing the popdown ourselves makes the next popup land at the new + // anchor cleanly without that warning. + if (gtk_widget_get_mapped(preedit_window)) + gtk_popover_popdown(GTK_POPOVER(preedit_window)); + + im_preedit_window_set_position(); + + gtk_widget_queue_resize(preedit_window); + gtk_popover_popup(GTK_POPOVER(preedit_window)); +# else + gtk_window_resize(GTK_WINDOW(preedit_window), w, h); gtk_widget_show_all(preedit_window); im_preedit_window_set_position(); +# endif } g_free(preedit_string); @@ -433,8 +662,13 @@ im_preedit_window_open(void) static void im_preedit_window_close(void) { - if (preedit_window != NULL) - gtk_widget_hide(preedit_window); + if (preedit_window == NULL) + return; +# ifdef USE_GTK4 + gtk_popover_popdown(GTK_POPOVER(preedit_window)); +# else + gtk_widget_hide(preedit_window); +# endif } static void @@ -946,10 +1180,11 @@ xim_init(void) # ifndef FEAT_GUI_MACVIM g_return_if_fail(gui.drawarea != NULL); +# ifndef USE_GTK4 g_return_if_fail(gtk_widget_get_window(gui.drawarea) != NULL); +# endif xic = gtk_im_multicontext_new(); - g_object_ref(xic); im_commit_handler_id = g_signal_connect(G_OBJECT(xic), "commit", G_CALLBACK(&im_commit_cb), NULL); @@ -960,7 +1195,20 @@ xim_init(void) g_signal_connect(G_OBJECT(xic), "preedit_end", G_CALLBACK(&im_preedit_end_cb), NULL); +# ifdef USE_GTK4 + gtk_im_context_set_client_widget(xic, gui.drawarea); + + // Seed the cursor location immediately. GTK4's Wayland IM module + // batches text-input-v3 state and sends it on the next commit cycle + // (typically triggered by focus_in). Without this seed the very + // first commit would carry the protocol default (0, 0, 0, 0) for the + // cursor rectangle, and the IM's candidate window for the very first + // composition would appear at the top-left of the surface instead of + // next to the cursor. + im_set_position(gui.row, gui.col); +# else gtk_im_context_set_client_window(xic, gtk_widget_get_window(gui.drawarea)); +# endif # endif } @@ -979,6 +1227,25 @@ im_shutdown(void) xic = NULL; } # endif +# ifdef USE_GTK4 + // GTK4: a widget added via gtk_widget_set_parent() must be detached + // with gtk_widget_unparent() before its parent is finalized, otherwise + // GTK prints "Finalizing ..., but it still has children left". + if (preedit_window != NULL) + { + gtk_widget_unparent(preedit_window); + preedit_window = NULL; + preedit_label = NULL; + } + if (preedit_css_provider != NULL) + { + gtk_style_context_remove_provider_for_display(gdk_display_get_default(), + GTK_STYLE_PROVIDER(preedit_css_provider)); + g_object_unref(preedit_css_provider); + preedit_css_provider = NULL; + preedit_css_cached_bg = INVALCOLOR; + } +# endif im_is_active = FALSE; # ifndef FEAT_GUI_MACVIM im_commit_handler_id = 0; @@ -989,6 +1256,7 @@ im_shutdown(void) } # ifndef FEAT_GUI_MACVIM +# ifndef USE_GTK4 /* * Convert the string argument to keyval and state for GdkEventKey. * If str is valid return TRUE, otherwise FALSE. @@ -1058,7 +1326,9 @@ im_xim_isvalid_imactivate(void) &im_activatekey_keyval, &im_activatekey_state); } +# endif // !USE_GTK4 +# ifndef USE_GTK4 static void im_synthesize_keypress(unsigned int keyval, unsigned int state) { @@ -1086,6 +1356,7 @@ im_synthesize_keypress(unsigned int keyval, unsigned int state) gdk_event_free((GdkEvent *)event); } +# endif // !USE_GTK4 # endif // FEAT_GUI_MACVIM void @@ -1107,6 +1378,11 @@ xim_reset(void) { xim_set_focus(gui.in_focus); +# ifdef USE_GTK4 + im_shutdown(); + xim_init(); + xim_set_focus(gui.in_focus); +# else if (im_activatekey_keyval != GDK_VoidSymbol) { if (im_is_active) @@ -1123,6 +1399,7 @@ xim_reset(void) xim_init(); xim_set_focus(gui.in_focus); } +# endif } } # endif @@ -1132,13 +1409,14 @@ xim_reset(void) xim_has_preediting = FALSE; } -# if !defined(FEAT_GUI_MACVIM) || defined(PROTO) +# if !defined(FEAT_GUI_MACVIM) +# ifndef USE_GTK4 int xim_queue_key_press_event(GdkEventKey *event, int down) { -# ifdef FEAT_GUI_GTK +# ifdef FEAT_GUI_GTK if (event->state & GDK_SUPER_MASK) return FALSE; -# endif +# endif if (down) { // Workaround GTK2 XIM 'feature' that always converts keypad keys to @@ -1267,7 +1545,24 @@ xim_queue_key_press_event(GdkEventKey *event, int down) return FALSE; } -# endif +# else // USE_GTK4 +// GTK4: imactivatekey is not supported because GTK4's GtkIMContext +// does not allow synthesizing key events for IM activation. + int +im_xim_isvalid_imactivate(void) +{ + // Empty string is always valid (means no activation key). + // Any other value is not supported in GTK4. + return p_imak[0] == NUL; +} + + int +xim_queue_key_press_event(GdkEvent *event UNUSED, int down UNUSED) +{ + return FALSE; +} +# endif // !USE_GTK4 +# endif // FEAT_GUI_MACVIM # if !defined(FEAT_GUI_MACVIM) || defined(PROTO) int @@ -1542,7 +1837,8 @@ xim_real_init(Window x11_window, Display *x11_display) if (gui.rsrc_input_method != NULL && *gui.rsrc_input_method != NUL) { - strcpy(tmp, gui.rsrc_input_method); + vim_strncpy((char_u *)tmp, (char_u *)gui.rsrc_input_method, + sizeof(tmp) - 1); for (ns = s = tmp; ns != NULL && *s != NUL;) { s = (char *)skipwhite((char_u *)s); @@ -1609,7 +1905,8 @@ xim_real_init(Window x11_window, Display *x11_display) } found = False; - strcpy(tmp, gui.rsrc_preedit_type_name); + vim_strncpy((char_u *)tmp, (char_u *)gui.rsrc_preedit_type_name, + sizeof(tmp) - 1); for (s = tmp; s && !found; ) { while (*s && SAFE_isspace(*s)) diff --git a/src/hardcopy.c b/src/hardcopy.c index 55d4384182..2eb63ea588 100644 --- a/src/hardcopy.c +++ b/src/hardcopy.c @@ -489,7 +489,8 @@ prt_header( printer_page_num = pagenum; build_stl_str_hl(curwin, tbuf, (size_t)(width + IOSIZE), p_header, - (char_u *)"printheader", 0, ' ', width, NULL, NULL); + (char_u *)"printheader", 0, ' ', width, NULL, NULL, + NULL); // Reset line numbers curwin->w_cursor.lnum = tmp_lnum; @@ -559,6 +560,16 @@ ex_hardcopy(exarg_T *eap) CLEAR_FIELD(settings); settings.has_color = TRUE; +#ifdef FEAT_GUI_GTK_PRINT + // Use the native GTK print dialog only for interactive printing; + // ":hardcopy >file" must fall through to the PostScript writer. + if (gui.in_use && *eap->arg != '>') + { + gui_gtk4_hardcopy(eap); + return; + } +#endif + #ifdef FEAT_POSTSCRIPT if (*eap->arg == '>') { diff --git a/src/help.c b/src/help.c index 7bb6a0d7dc..c8155054d1 100644 --- a/src/help.c +++ b/src/help.c @@ -634,7 +634,7 @@ prepare_help_buffer(void) { char_u *p; - curbuf->b_help = TRUE; + curbuf->b_help = true; #ifdef FEAT_QUICKFIX set_string_option_direct((char_u *)"buftype", -1, (char_u *)"help", OPT_FREE|OPT_LOCAL, 0); diff --git a/src/highlight.c b/src/highlight.c index 782820ed11..d38b30a8a2 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -184,7 +184,8 @@ typedef struct typedef struct hl_overrides_S hl_overrides_T; struct hl_overrides_S { - hl_override_T *arr; // May be NULL if "arr" was freed + hl_override_T *arr; // May be NULL if "arr" was freed or no highlight + // overrides (all values set to default) int len; hl_overrides_T *next; // Used to handle recursive calls @@ -272,6 +273,7 @@ static char *(highlight_init_both[]) = { "default link EndOfBuffer NonText", CENT("VertSplit term=reverse cterm=reverse", "VertSplit term=reverse cterm=reverse gui=reverse"), + "default link VertSplitNC VertSplit", #ifdef FEAT_CLIPBOARD CENT("VisualNOS term=underline,bold cterm=underline,bold", "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold"), @@ -310,6 +312,9 @@ static char *(highlight_init_both[]) = { "default link PmenuExtraSel PmenuSel", "default link PmenuBorder Pmenu", "default link PopupSelected PmenuSel", + "default link Popup Pmenu", + "default link PopupBorder Pmenu", + "default link PopupTitle Pmenu", "default link MessageWindow WarningMsg", "default link PopupNotification WarningMsg", "default link PreInsert Added", @@ -528,6 +533,9 @@ highlight_link_id(int id) } #endif +static void resolve_fallback_fg_to_rgb(void); +static void resolve_fallback_bg_to_rgb(void); + void init_highlight( int both, // include groups where 'bg' doesn't matter @@ -611,6 +619,8 @@ init_highlight( } } #endif + resolve_fallback_fg_to_rgb(); + resolve_fallback_bg_to_rgb(); } #if defined(FEAT_EVAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) @@ -1972,6 +1982,8 @@ do_highlight( redraw_all_later(UPD_NOT_VALID); } #endif + resolve_fallback_fg_to_rgb(); + resolve_fallback_bg_to_rgb(); #ifdef FEAT_VTP control_console_color_rgb(); #endif @@ -2086,6 +2098,8 @@ restore_cterm_colors(void) cterm_normal_bg_gui_color = INVALCOLOR; cterm_normal_ul_gui_color = INVALCOLOR; # endif + fallback_fg_rgb = INVALCOLOR; + fallback_bg_rgb = INVALCOLOR; #endif } @@ -3124,10 +3138,228 @@ hl_combine_attr(int char_attr, int prim_attr) return get_attr_entry(&term_attr_table, &new_en); } +// ANSI color order: Black, Red, Green, Yellow, Blue, Magenta, +// Cyan, White, then bright variants. Approximate RGB values used when +// only a cterm color number is known (no guifg/guibg). Real terminal +// palettes may differ if the user reconfigured their emulator, but +// these are reasonable xterm-ish defaults. +static const long_u cterm_color_16[16] = { + 0x000000, 0xc00000, 0x008000, 0x808000, + 0x0000c0, 0xc000c0, 0x004080, 0xc0c0c0, + 0x808080, 0xff8080, 0x00ff00, 0xffff00, + 0x6060ff, 0xff40ff, 0x00ffff, 0xffffff +}; + +#ifdef FEAT_TERMGUICOLORS +/* + * Convert a cterm color number (1-16) to an RGB value. + * Used as a fallback when 'termguicolors' is set but only cterm colors are + * specified (no guifg/guibg). + * Returns INVALCOLOR if the color number is out of range. + */ + static guicolor_T +cterm_color_to_rgb(int color_nr) +{ + if (color_nr < 1 || color_nr > 16) + return INVALCOLOR; + return (guicolor_T)cterm_color_16[color_nr - 1]; +} +#endif + +/* + * Convert an xterm 256-color index (0-255) to an approximate RGB triple. + * Uses the standard xterm palette: 0-15 ANSI (cterm_color_16), 16-231 + * 6x6x6 cube, 232-255 grayscale ramp. + */ + static void +cterm_idx_to_rgb(int idx, int *r, int *g, int *b) +{ + static const int cube[] = { 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF }; + + if (idx < 0 || idx > 255) + { + *r = *g = *b = 0; + return; + } + if (idx < 16) + { + long_u rgb = cterm_color_16[idx]; + *r = (rgb >> 16) & 0xFF; + *g = (rgb >> 8) & 0xFF; + *b = rgb & 0xFF; + } + else if (idx < 232) + { + int n = idx - 16; + *r = cube[n / 36 % 6]; + *g = cube[n / 6 % 6]; + *b = cube[n % 6]; + } + else + { + int v = 8 + (idx - 232) * 10; + *r = *g = *b = v; + } +} + +/* + * Approximate an RGB triple to the nearest xterm 256-color index. + * Searches the 6x6x6 cube and the grayscale ramp; returns 0-255. + */ + static int +rgb_to_cterm_idx(int r, int g, int b) +{ + static const int cube[] = { 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF }; + int best = 0; + long best_d = -1; + int i; + + // Search the 6x6x6 cube. + for (i = 16; i < 232; ++i) + { + int n = i - 16; + int cr = cube[n / 36 % 6]; + int cg = cube[n / 6 % 6]; + int cb = cube[n % 6]; + long d = (cr - r) * (cr - r) + (cg - g) * (cg - g) + (cb - b) * (cb - b); + if (best_d < 0 || d < best_d) + { + best_d = d; + best = i; + } + } + // Search the grayscale ramp. + for (i = 232; i < 256; ++i) + { + int v = 8 + (i - 232) * 10; + long d = (v - r) * (v - r) + (v - g) * (v - g) + (v - b) * (v - b); + if (d < best_d) + { + best_d = d; + best = i; + } + } + return best; +} + +/* + * Resolve a color to an RGB triple. Prefer the gui RGB value (set by + * guifg/guibg) when valid, otherwise convert the cterm 256-color index. + * Returns true on success; false when no color is defined. + * cterm_c is 1-based (0 means "no color"). + */ + static bool +resolve_color_to_rgb(int cterm_c, guicolor_T rgb UNUSED, int *r, int *g, int *b) +{ +#ifdef FEAT_TERMGUICOLORS + if (!COLOR_INVALID(rgb)) + { + *r = (rgb >> 16) & 0xFF; + *g = (rgb >> 8) & 0xFF; + *b = rgb & 0xFF; + return true; + } +#endif + if (cterm_c > 0) + { + cterm_idx_to_rgb(cterm_c - 1, r, g, b); + return true; + } + return false; +} + +/* + * get a RGB fallback color from gui, cterm or default color + */ + static guicolor_T +resolve_fallback_color(int cterm_c, guicolor_T rgb, guicolor_T default_rgb) +{ + int red, green, blue; + if (!resolve_color_to_rgb(cterm_c, rgb, &red, &green, &blue)) + return default_rgb; + else + return (red << 16) | (green << 8) | blue; +} + +/* + * get a RGB fallback foreground color from guifg, ctermfg or deduced from background + */ + static void +resolve_fallback_fg_to_rgb(void) +{ + guicolor_T fgcolor_or_gui_fgcolor = INVALCOLOR; +#ifdef FEAT_TERMGUICOLORS + fgcolor_or_gui_fgcolor = cterm_normal_fg_gui_color; +#endif +#ifdef FEAT_GUI + if (gui.in_use) + fgcolor_or_gui_fgcolor = gui.norm_pixel; +#endif + fallback_fg_rgb = resolve_fallback_color(cterm_normal_fg_color, fgcolor_or_gui_fgcolor, (*p_bg == 'l') ? 0x000000 : 0xFFFFFF); +} + +/* + * get a RGB fallback background color from guifg, ctermbg or deduced from background + */ + static void +resolve_fallback_bg_to_rgb(void) +{ + guicolor_T bgcolor_or_gui_bgcolor = INVALCOLOR; +#ifdef FEAT_TERMGUICOLORS + bgcolor_or_gui_bgcolor = cterm_normal_bg_gui_color; +#endif +#ifdef FEAT_GUI + if (gui.in_use) + bgcolor_or_gui_bgcolor = gui.back_pixel; +#endif + fallback_bg_rgb = resolve_fallback_color(cterm_normal_bg_color, bgcolor_or_gui_bgcolor, (*p_bg == 'l') ? 0xFFFFFF : 0x000000); +} + +/* + * Blend two colors expressed as (cterm 256 index, gui RGB) pairs and + * return the nearest 1-based cterm 256-color index. Prefers the gui + * RGB so highlight definitions like "guibg=#2D2A3D" without ctermbg + * still produce a meaningful blend in 256-color terminals. + * + * "default_rgb" is used as the underlying color when neither under_c + * nor under_rgb is set; pass 0xFFFFFF for fg-style blends (so text + * fades toward white) or 0x000000 for bg-style blends (so the popup + * fades toward terminal default dark). + * + * Requires t_colors >= 256; otherwise returns popup_c unchanged. + */ + static int +blend_cterm_colors(int popup_c, guicolor_T popup_rgb, + int under_c, guicolor_T under_rgb, + int default_rgb, + int blend_val) +{ + int pr, pg, pb, ur, ug, ub, r, g, b; + + if (t_colors < 256) + return popup_c; + if (!resolve_color_to_rgb(popup_c, popup_rgb, &pr, &pg, &pb)) + return under_c; + if (blend_val <= 0) + return rgb_to_cterm_idx(pr, pg, pb) + 1; + if (!resolve_color_to_rgb(under_c, under_rgb, &ur, &ug, &ub)) + { + ur = (default_rgb >> 16) & 0xFF; + ug = (default_rgb >> 8) & 0xFF; + ub = default_rgb & 0xFF; + } + if (blend_val >= 100) + return rgb_to_cterm_idx(ur, ug, ub) + 1; + r = pr + (ur - pr) * blend_val / 100; + g = pg + (ug - pg) * blend_val / 100; + b = pb + (ub - pb) * blend_val / 100; + return rgb_to_cterm_idx(r, g, b) + 1; +} + #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) /* * Blend two RGB colors based on blend value (0-100). - * blend: 0=use popup color, 100=use background color + * blend: 0=return first argument color, 100=return second argument color * If bg_color is INVALCOLOR, high blend means more visible (return INVALCOLOR). */ static guicolor_T @@ -3135,7 +3367,9 @@ blend_colors(guicolor_T popup_color, guicolor_T bg_color, int blend_val) { int r1, g1, b1, r2, g2, b2, r, g, b; - if (popup_color == INVALCOLOR) + // CTERMCOLOR is a sentinel meaning "use the cterm color"; for blending + // it has no real RGB so treat it like INVALCOLOR. + if (COLOR_INVALID(popup_color)) return INVALCOLOR; // Fully transparent: use underlying color as-is. @@ -3146,15 +3380,8 @@ blend_colors(guicolor_T popup_color, guicolor_T bg_color, int blend_val) g1 = (popup_color >> 8) & 0xFF; b1 = popup_color & 0xFF; - if (bg_color == INVALCOLOR) - { - // Background color unknown: fade popup color to black as blend increases - // This makes background text more visible at high blend values - r = r1 * (100 - blend_val) / 100; - g = g1 * (100 - blend_val) / 100; - b = b1 * (100 - blend_val) / 100; - return (r << 16) | (g << 8) | b; - } + if (COLOR_INVALID(bg_color)) + bg_color = fallback_bg_rgb; r2 = (bg_color >> 16) & 0xFF; g2 = (bg_color >> 8) & 0xFF; @@ -3214,23 +3441,29 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED) // blend_fg=TRUE: fade underlying text toward popup bg. if (popup_aep->ae_u.gui.bg_color != INVALCOLOR) { - int base_fg = 0xFFFFFF; + int base_fg = fallback_fg_rgb; if (char_aep != NULL && char_aep->ae_u.gui.fg_color != INVALCOLOR) base_fg = char_aep->ae_u.gui.fg_color; new_en.ae_u.gui.fg_color = blend_colors( - base_fg, popup_aep->ae_u.gui.bg_color, blend); + popup_aep->ae_u.gui.bg_color, base_fg, blend); } } - else if (popup_aep->ae_u.gui.fg_color != INVALCOLOR) + else { - // blend_fg=FALSE: use popup foreground + // blend_fg=FALSE: popup text is opaque. Replace the + // underlying cell's attribute flags, fg and special + // color with the popup's, so the underlying syntax + // highlighting and any decoration (textprop undercurl, + // ...) do not bleed through. + new_en.ae_attr = popup_aep->ae_attr; new_en.ae_u.gui.fg_color = popup_aep->ae_u.gui.fg_color; + new_en.ae_u.gui.sp_color = popup_aep->ae_u.gui.sp_color; } // Blend background color: blend popup bg toward underlying bg if (popup_aep->ae_u.gui.bg_color != INVALCOLOR) { - guicolor_T underlying_bg = INVALCOLOR; + guicolor_T underlying_bg = fallback_bg_rgb; if (char_aep != NULL) underlying_bg = char_aep->ae_u.gui.bg_color; new_en.ae_u.gui.bg_color = blend_colors( @@ -3266,39 +3499,122 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED) popup_aep = syn_cterm_attr2entry(popup_attr); if (popup_aep != NULL) { - // Blend foreground color - if (popup_aep->ae_u.cterm.fg_color > 0) - new_en.ae_u.cterm.fg_color = popup_aep->ae_u.cterm.fg_color; - // Use popup background color (cterm colors don't support blending) - if (popup_aep->ae_u.cterm.bg_color > 0) - new_en.ae_u.cterm.bg_color = popup_aep->ae_u.cterm.bg_color; + if (!blend_fg) + { + // blend_fg=FALSE: popup text is opaque. Replace the + // underlying cell's attribute flags, fg and underline + // color with the popup's, so the underlying syntax + // highlighting and any decoration (textprop undercurl, + // ...) do not bleed through. When the popup has no fg + // (e.g. "guifg=NONE") fall back to Normal's fg so the + // text is still readable instead of taking on whatever + // the underlying cell happened to have. + new_en.ae_attr = popup_aep->ae_attr; + if (popup_aep->ae_u.cterm.fg_color > 0) + new_en.ae_u.cterm.fg_color = + popup_aep->ae_u.cterm.fg_color; + else if (cterm_normal_fg_color > 0) + new_en.ae_u.cterm.fg_color = cterm_normal_fg_color; + else + new_en.ae_u.cterm.fg_color = 16; // white-ish + new_en.ae_u.cterm.ul_color = popup_aep->ae_u.cterm.ul_color; #ifdef FEAT_TERMGUICOLORS - // Blend RGB colors for termguicolors mode - if (blend_fg) - { - // blend_fg=TRUE: fade underlying text toward popup bg. - if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR) - { - int base_fg = 0xFFFFFF; - if (char_aep != NULL - && char_aep->ae_u.cterm.fg_rgb != INVALCOLOR) - base_fg = char_aep->ae_u.cterm.fg_rgb; - new_en.ae_u.cterm.fg_rgb = blend_colors( - base_fg, popup_aep->ae_u.cterm.bg_rgb, blend); - } + new_en.ae_u.cterm.ul_rgb = popup_aep->ae_u.cterm.ul_rgb; +#endif } - else if (popup_aep->ae_u.cterm.fg_rgb != INVALCOLOR) - // blend_fg=FALSE: use popup foreground - new_en.ae_u.cterm.fg_rgb = popup_aep->ae_u.cterm.fg_rgb; - if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR) + else { - // Blend popup bg toward underlying bg - guicolor_T underlying_bg = INVALCOLOR; + // blend_fg=TRUE: fade underlying fg toward popup bg in + // the 256-color palette. Used when the popup is over a + // cell rendered with cterm colors (no termguicolors RGB). + int under_fg = (char_aep != NULL) + ? char_aep->ae_u.cterm.fg_color : 0; + guicolor_T under_fg_rgb = INVALCOLOR; + guicolor_T popup_bg_rgb = INVALCOLOR; +#ifdef FEAT_TERMGUICOLORS if (char_aep != NULL) - underlying_bg = char_aep->ae_u.cterm.bg_rgb; - new_en.ae_u.cterm.bg_rgb = blend_colors( - popup_aep->ae_u.cterm.bg_rgb, - underlying_bg, blend); + under_fg_rgb = char_aep->ae_u.cterm.fg_rgb; + popup_bg_rgb = popup_aep->ae_u.cterm.bg_rgb; +#endif + new_en.ae_u.cterm.fg_color = blend_cterm_colors( + popup_aep->ae_u.cterm.bg_color, popup_bg_rgb, + under_fg, under_fg_rgb, fallback_fg_rgb, blend); + } + // Approximate cterm bg by blending with the underlying bg + // in the 256-color palette and mapping to the nearest entry. + { + int under_bg = (char_aep != NULL) + ? char_aep->ae_u.cterm.bg_color : 0; + guicolor_T under_bg_rgb = INVALCOLOR; + guicolor_T popup_bg_rgb = INVALCOLOR; +#ifdef FEAT_TERMGUICOLORS + if (char_aep != NULL) + under_bg_rgb = char_aep->ae_u.cterm.bg_rgb; + popup_bg_rgb = popup_aep->ae_u.cterm.bg_rgb; +#endif + new_en.ae_u.cterm.bg_color = blend_cterm_colors( + popup_aep->ae_u.cterm.bg_color, popup_bg_rgb, + under_bg, under_bg_rgb, fallback_bg_rgb, blend); + } +#ifdef FEAT_TERMGUICOLORS + // Blend RGB colors for termguicolors mode. + // Fall back to cterm color converted to RGB when + // gui color is not set. + { + guicolor_T popup_bg = popup_aep->ae_u.cterm.bg_rgb; + guicolor_T popup_fg = popup_aep->ae_u.cterm.fg_rgb; + + if (COLOR_INVALID(popup_bg) + && popup_aep->ae_u.cterm.bg_color > 0) + popup_bg = cterm_color_to_rgb( + popup_aep->ae_u.cterm.bg_color); + if (COLOR_INVALID(popup_fg) + && popup_aep->ae_u.cterm.fg_color > 0) + popup_fg = cterm_color_to_rgb( + popup_aep->ae_u.cterm.fg_color); + + if (blend_fg) + { + // blend_fg=TRUE: fade underlying text toward popup bg. + if (popup_bg != INVALCOLOR) + { + int base_fg = fallback_fg_rgb; + // CTERMCOLOR is a sentinel meaning "use the cterm + // color"; treat it as no underlying color so it is + // not blended in as a real near-white pixel. + if (char_aep != NULL + && !COLOR_INVALID(char_aep->ae_u.cterm.fg_rgb)) + base_fg = char_aep->ae_u.cterm.fg_rgb; + new_en.ae_u.cterm.fg_rgb = blend_colors( + popup_bg, base_fg, blend); + } + } + else + { + // blend_fg=FALSE: popup text is opaque. Replace fg + // with popup's so the underlying syntax highlighting + // fg does not bleed. ae_attr was already set above + // for this branch. When the popup has no fg fall + // back to Normal's fg, then to white, so the text + // stays readable instead of rendering as default + // (which can be black on dark themes). + if (!COLOR_INVALID(popup_fg)) + new_en.ae_u.cterm.fg_rgb = popup_fg; + else if (!COLOR_INVALID(cterm_normal_fg_gui_color)) + new_en.ae_u.cterm.fg_rgb = cterm_normal_fg_gui_color; + else + new_en.ae_u.cterm.fg_rgb = fallback_fg_rgb; + } + if (popup_bg != INVALCOLOR) + { + // Blend popup bg toward underlying bg + guicolor_T underlying_bg = fallback_bg_rgb; + if (char_aep != NULL + && !COLOR_INVALID(char_aep->ae_u.cterm.bg_rgb)) + underlying_bg = char_aep->ae_u.cterm.bg_rgb; + new_en.ae_u.cterm.bg_rgb = blend_colors( + popup_bg, underlying_bg, blend); + } } #endif } @@ -3359,7 +3675,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED) // blend=100 (transparent): fg = underlying_fg (text visible) if (popup_aep->ae_u.gui.bg_color != INVALCOLOR) { - int base_fg = 0xFFFFFF; + int base_fg = fallback_fg_rgb; if (char_aep != NULL && char_aep->ae_u.gui.fg_color != INVALCOLOR) base_fg = char_aep->ae_u.gui.fg_color; @@ -3369,7 +3685,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED) // Blend bg: popup bg toward underlying bg. if (popup_aep->ae_u.gui.bg_color != INVALCOLOR) { - guicolor_T underlying_bg = INVALCOLOR; + guicolor_T underlying_bg = fallback_bg_rgb; if (char_aep != NULL) underlying_bg = char_aep->ae_u.gui.bg_color; new_en.ae_u.gui.bg_color = blend_colors( @@ -3404,21 +3720,48 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED) popup_aep = syn_cterm_attr2entry(popup_attr); if (popup_aep != NULL) { - // Blend cterm fg: use popup bg (hides text when opaque) - if (popup_aep->ae_u.cterm.fg_color > 0) - new_en.ae_u.cterm.fg_color = - popup_aep->ae_u.cterm.fg_color; - // Use popup cterm bg. - if (popup_aep->ae_u.cterm.bg_color > 0) - new_en.ae_u.cterm.bg_color = - popup_aep->ae_u.cterm.bg_color; + // Blend cterm fg: pum_bg toward underlying_fg in the + // 256-color palette (mirrors the fg_rgb blend below). + { + int under_fg = (char_aep != NULL) + ? char_aep->ae_u.cterm.fg_color : 0; + guicolor_T under_fg_rgb = INVALCOLOR; + guicolor_T popup_bg_rgb = INVALCOLOR; +#ifdef FEAT_TERMGUICOLORS + if (char_aep != NULL) + under_fg_rgb = char_aep->ae_u.cterm.fg_rgb; + popup_bg_rgb = popup_aep->ae_u.cterm.bg_rgb; +#endif + new_en.ae_u.cterm.fg_color = blend_cterm_colors( + popup_aep->ae_u.cterm.bg_color, popup_bg_rgb, + under_fg, under_fg_rgb, fallback_fg_rgb, blend); + } + // Approximate cterm bg by blending with the underlying bg + // in the 256-color palette and mapping to the nearest entry. + { + int under_bg = (char_aep != NULL) + ? char_aep->ae_u.cterm.bg_color : 0; + guicolor_T under_bg_rgb = INVALCOLOR; + guicolor_T popup_bg_rgb = INVALCOLOR; +#ifdef FEAT_TERMGUICOLORS + if (char_aep != NULL) + under_bg_rgb = char_aep->ae_u.cterm.bg_rgb; + popup_bg_rgb = popup_aep->ae_u.cterm.bg_rgb; +#endif + new_en.ae_u.cterm.bg_color = blend_cterm_colors( + popup_aep->ae_u.cterm.bg_color, popup_bg_rgb, + under_bg, under_bg_rgb, fallback_bg_rgb, blend); + } #ifdef FEAT_TERMGUICOLORS // Blend fg_rgb: pum_bg toward underlying_fg. + // CTERMCOLOR is a sentinel meaning "use the cterm color"; + // treat it as no underlying color so it is not blended in + // as a real near-white pixel. if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR) { - int base_fg = 0xFFFFFF; + int base_fg = fallback_fg_rgb; if (char_aep != NULL - && char_aep->ae_u.cterm.fg_rgb != INVALCOLOR) + && !COLOR_INVALID(char_aep->ae_u.cterm.fg_rgb)) base_fg = char_aep->ae_u.cterm.fg_rgb; new_en.ae_u.cterm.fg_rgb = blend_colors( popup_aep->ae_u.cterm.bg_rgb, base_fg, blend); @@ -3426,8 +3769,9 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED) // Blend bg_rgb. if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR) { - guicolor_T underlying_bg = INVALCOLOR; - if (char_aep != NULL) + guicolor_T underlying_bg = fallback_bg_rgb; + if (char_aep != NULL + && !COLOR_INVALID(char_aep->ae_u.cterm.bg_rgb)) underlying_bg = char_aep->ae_u.cterm.bg_rgb; new_en.ae_u.cterm.bg_rgb = blend_colors( popup_aep->ae_u.cterm.bg_rgb, @@ -5768,9 +6112,10 @@ set_highlight_attr(hl_override_T *arr, int len, bool update_ids) bool push_highlight_overrides(hl_override_T *arr, int len) { - // Don't want to do anything if "arr" is NULL or if "arr" is already the - // current override. - if (arr == NULL || (overrides != NULL && overrides->arr == arr)) + // Don't want to do anything if "arr" is already the current override. If + // "arr" is NULL (but overrides->arr is not), then still push an override, + // but "->arr" will just be NULL so any previous overrides are cleared. + if (overrides != NULL && overrides->arr == arr) return false; hl_overrides_T *set; @@ -5795,7 +6140,8 @@ push_highlight_overrides(hl_override_T *arr, int len) memcpy(highlight_attr, highlight_attr_raw, sizeof(highlight_attr)); // Update highlight_attr[] array - set_highlight_attr(arr, len, false); + if (arr != NULL) + set_highlight_attr(arr, len, false); return true; } diff --git a/src/if_cscope.c b/src/if_cscope.c index 7962000777..54cae51f75 100644 --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -829,11 +829,11 @@ cs_create_connection(int i) int to_cs[2], from_cs[2]; # endif int cmdlen; - int len; char *prog, *cmd, *ppath = NULL; size_t proglen; # ifdef MSWIN int fd; + int len; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; @@ -872,7 +872,6 @@ err_closing: else if (csinfo[i].pid == 0) // child: run cscope. { char **argv = NULL; - int argc = 0; if (dup2(to_cs[0], STDIN_FILENO) == -1) PERROR("cs_create_connection 1"); @@ -956,48 +955,93 @@ err_closing: // run the cscope command # ifdef UNIX - vim_snprintf(cmd, cmdlen, "/bin/sh -c \"exec %s -dl -f %s", - prog, csinfo[i].fname); -# else - vim_snprintf(cmd, cmdlen, "%s -dl -f %s", prog, csinfo[i].fname); -# endif - if (csinfo[i].ppath != NULL) { - len = (int)STRLEN(cmd); - vim_snprintf(cmd + len, cmdlen - len, " -P%s", csinfo[i].ppath); - } - if (csinfo[i].flags != NULL) - { - len = (int)STRLEN(cmd); - vim_snprintf(cmd + len, cmdlen - len, " %s", csinfo[i].flags); - } -# ifdef UNIX - // terminate the -c command argument - STRCAT(cmd, "\""); + garray_T ga_argv; + char **tok = NULL; + int tokc = 0; - // on Win32 we still need prog - vim_free(prog); -# endif - vim_free(ppath); + ga_init2(&ga_argv, sizeof(char *), 8); + + // 'cscopeprg' may be multi-word (e.g. "cscope --foo"); + // split it into separate argv entries. + if (build_argv_from_string((char_u *)prog, &tok, &tokc) == FAIL) + exit(EXIT_FAILURE); + for (int k = 0; k < tokc; ++k) + { + if (ga_grow(&ga_argv, 1) == FAIL) + exit(EXIT_FAILURE); + ((char **)ga_argv.ga_data)[ga_argv.ga_len++] = tok[k]; + } + VIM_CLEAR(tok); + + // Literal arguments: "-dl", "-f", fname. + if (ga_grow(&ga_argv, 3) == FAIL) + exit(EXIT_FAILURE); + ((char **)ga_argv.ga_data)[ga_argv.ga_len++] = + (char *)vim_strsave((char_u *)"-dl"); + ((char **)ga_argv.ga_data)[ga_argv.ga_len++] = + (char *)vim_strsave((char_u *)"-f"); + ((char **)ga_argv.ga_data)[ga_argv.ga_len++] = + (char *)vim_strsave((char_u *)csinfo[i].fname); + + // "-P" as a single argv entry, if set. + if (ppath != NULL) + { + size_t plen = STRLEN(ppath) + 3; + char *parg = alloc(plen); + + if (parg == NULL || ga_grow(&ga_argv, 1) == FAIL) + exit(EXIT_FAILURE); + vim_snprintf(parg, plen, "-P%s", ppath); + ((char **)ga_argv.ga_data)[ga_argv.ga_len++] = parg; + } + + // 'flags' is intended to be a sequence of cscope tokens + // like "-q -i somefile"; split it the same way as prog. + if (csinfo[i].flags != NULL) + { + if (build_argv_from_string((char_u *)csinfo[i].flags, + &tok, &tokc) == FAIL) + exit(EXIT_FAILURE); + for (int k = 0; k < tokc; ++k) + { + if (ga_grow(&ga_argv, 1) == FAIL) + exit(EXIT_FAILURE); + ((char **)ga_argv.ga_data)[ga_argv.ga_len++] = tok[k]; + } + vim_free(tok); + } + + // NULL-terminate argv. + if (ga_grow(&ga_argv, 1) == FAIL) + exit(EXIT_FAILURE); + ((char **)ga_argv.ga_data)[ga_argv.ga_len] = NULL; + + vim_free(prog); + vim_free(ppath); + vim_free(cmd); -# if defined(UNIX) # if defined(HAVE_SETSID) || defined(HAVE_SETPGID) - // Change our process group to avoid cscope receiving SIGWINCH. + // Change our process group to avoid cscope receiving SIGWINCH. # if defined(HAVE_SETSID) - (void)setsid(); + (void)setsid(); # else - if (setpgid(0, 0) == -1) - PERROR(_("cs_create_connection setpgid failed")); + if (setpgid(0, 0) == -1) + PERROR(_("cs_create_connection setpgid failed")); # endif # endif - if (build_argv_from_string((char_u *)cmd, &argv, &argc) == FAIL) - exit(EXIT_FAILURE); - if (execvp(argv[0], argv) == -1) - PERROR(_("cs_create_connection exec failed")); + argv = (char **)ga_argv.ga_data; + if (argv[0] == NULL || execvp(argv[0], argv) == -1) + { + fprintf(stderr, "%s\n", + _("cs_create_connection exec failed")); + fflush(stderr); + } - exit(127); - // NOTREACHED + exit(127); + // NOTREACHED + } } else // parent. { @@ -1016,6 +1060,19 @@ err_closing: } # else // MSWIN + vim_snprintf(cmd, cmdlen, "%s -dl -f %s", prog, csinfo[i].fname); + if (csinfo[i].ppath != NULL) + { + len = (int)STRLEN(cmd); + vim_snprintf(cmd + len, cmdlen - len, " -P%s", csinfo[i].ppath); + } + if (csinfo[i].flags != NULL) + { + len = (int)STRLEN(cmd); + vim_snprintf(cmd + len, cmdlen - len, " %s", csinfo[i].flags); + } + vim_free(ppath); + // Create a new process to run cscope and use pipes to talk with it GetStartupInfo(&si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; diff --git a/src/if_lua.c b/src/if_lua.c index fc2e392f2d..3a60e920e0 100644 --- a/src/if_lua.c +++ b/src/if_lua.c @@ -1687,7 +1687,7 @@ luaV_window_newindex(lua_State *L) luaV_checksandbox(L); # endif w->w_cursor.col = v - 1; - w->w_set_curswant = TRUE; + w->w_set_curswant = true; update_screen(UPD_VALID); } else if (strncmp(s, "width", 5) == 0) diff --git a/src/if_mzsch.c b/src/if_mzsch.c index a6043e1d82..c7a40909a5 100644 --- a/src/if_mzsch.c +++ b/src/if_mzsch.c @@ -2128,7 +2128,7 @@ set_cursor(void *data, int argc, Scheme_Object **argv) win->win->w_cursor.lnum = lnum; win->win->w_cursor.col = col; - win->win->w_set_curswant = TRUE; + win->win->w_set_curswant = true; update_screen(UPD_VALID); raise_if_error(); diff --git a/src/if_ruby.c b/src/if_ruby.c index b5b0079ece..5c867afc14 100644 --- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -1692,7 +1692,7 @@ window_set_cursor(VALUE self, VALUE pos) col = RARRAY_PTR(pos)[1]; win->w_cursor.lnum = NUM2LONG(lnum); win->w_cursor.col = NUM2UINT(col); - win->w_set_curswant = TRUE; + win->w_set_curswant = true; check_cursor(); // put cursor on an existing line update_screen(UPD_NOT_VALID); return Qnil; diff --git a/src/if_tcl.c b/src/if_tcl.c index 3aebcbd0fd..8c70b6eb10 100644 --- a/src/if_tcl.c +++ b/src/if_tcl.c @@ -1103,7 +1103,7 @@ winselfcmd( // TODO: should check column win->w_cursor.lnum = val1; win->w_cursor.col = col2vim(val2); - win->w_set_curswant = TRUE; + win->w_set_curswant = true; flags |= FL_UPDATE_SCREEN; break; diff --git a/src/if_xcmdsrv.c b/src/if_xcmdsrv.c index 070e0db099..43e1e34070 100644 --- a/src/if_xcmdsrv.c +++ b/src/if_xcmdsrv.c @@ -1333,7 +1333,7 @@ server_parse_message( // Initialize the result property. ga_init2(&reply, 1, 100); - (void)ga_grow(&reply, 50 + STRLEN(p_enc)); + (void)ga_grow(&reply, 50 + STRLEN(p_enc) + STRLEN(serial)); sprintf(reply.ga_data, "%cr%c-E %s%c-s %s%c-r ", 0, 0, p_enc, 0, serial, 0); reply.ga_len = 14 + STRLEN(p_enc) + STRLEN(serial); diff --git a/src/indent.c b/src/indent.c index 8fe4177c30..9f19f6eb6e 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1454,7 +1454,7 @@ change_indent( curwin->w_cursor.col = 0; else curwin->w_cursor.col = (colnr_T)new_cursor_col; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; changed_cline_bef_curs(); // May have to adjust the start of the insert. diff --git a/src/insexpand.c b/src/insexpand.c index b1cc29b7e5..c5f908485b 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -67,26 +67,26 @@ static char *ctrl_x_msgs[] = }; #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) -static char *ctrl_x_mode_names[] = { - "keyword", - "ctrl_x", - "scroll", - "whole_line", - "files", - "tags", - "path_patterns", - "path_defines", - "unknown", // CTRL_X_FINISHED - "dictionary", - "thesaurus", - "cmdline", - "function", - "omni", - "spell", - NULL, // CTRL_X_LOCAL_MSG only used in "ctrl_x_msgs" - "eval", - "cmdline", - "register", +static string_T ctrl_x_mode_names[] = { + STR_LITERAL_INIT("keyword"), + STR_LITERAL_INIT("ctrl_x"), + STR_LITERAL_INIT("scroll"), + STR_LITERAL_INIT("whole_line"), + STR_LITERAL_INIT("files"), + STR_LITERAL_INIT("tags"), + STR_LITERAL_INIT("path_patterns"), + STR_LITERAL_INIT("path_defines"), + STR_LITERAL_INIT("unknown"), // CTRL_X_FINISHED + STR_LITERAL_INIT("dictionary"), + STR_LITERAL_INIT("thesaurus"), + STR_LITERAL_INIT("cmdline"), + STR_LITERAL_INIT("function"), + STR_LITERAL_INIT("omni"), + STR_LITERAL_INIT("spell"), + {NULL, 0}, // CTRL_X_LOCAL_MSG is only used in "ctrl_x_msgs" + STR_LITERAL_INIT("eval"), + STR_LITERAL_INIT("cmdline"), + STR_LITERAL_INIT("register"), }; #endif @@ -494,10 +494,6 @@ has_compl_option(int dict_opt) int vim_is_ctrl_x_key(int c) { - // Always allow ^R - let its results then be checked - if (c == Ctrl_R && ctrl_x_mode != CTRL_X_REGISTER) - return TRUE; - // Accept and if the popup menu is visible. if (ins_compl_pum_key(c)) return TRUE; @@ -1386,13 +1382,13 @@ ins_compl_dict_alloc(compl_T *match) if (dict == NULL) return NULL; - dict_add_string(dict, "word", match->cp_str.string); + dict_add_string_len(dict, "word", match->cp_str.string, (int)match->cp_str.length); dict_add_string(dict, "abbr", match->cp_text[CPT_ABBR]); dict_add_string(dict, "menu", match->cp_text[CPT_MENU]); dict_add_string(dict, "kind", match->cp_text[CPT_KIND]); dict_add_string(dict, "info", match->cp_text[CPT_INFO]); if (match->cp_user_data.v_type == VAR_UNKNOWN) - dict_add_string(dict, "user_data", (char_u *)""); + dict_add_string_len(dict, "user_data", (char_u *)"", 0); else dict_add_tv(dict, "user_data", &match->cp_user_data); @@ -1828,8 +1824,9 @@ ins_compl_show_pum(void) if (!pum_wanted() || !pum_enough_matches()) return; - // Update the screen later, before drawing the popup menu over it. - pum_call_update_screen(); + // Avoid redrawing the screen under a pum that stays in place. + if (!pum_redraw_in_same_position()) + pum_call_update_screen(); if (compl_match_array == NULL) // Need to build the popup menu list. @@ -2887,21 +2884,21 @@ set_ctrl_x_mode(int c) * Trigger CompleteDone event and adds relevant information to v:event */ static void -trigger_complete_done_event(int mode UNUSED, char_u *word UNUSED) +trigger_complete_done_event(int mode UNUSED, string_T *word UNUSED) { #if defined(FEAT_EVAL) save_v_event_T save_v_event; dict_T *v_event = get_v_event(&save_v_event); - char_u *mode_str = NULL; + string_T *mode_str; - mode = mode & ~CTRL_X_WANT_IDENT; - if (ctrl_x_mode_names[mode]) - mode_str = (char_u *)ctrl_x_mode_names[mode]; + if (word == NULL || word->string == NULL) + (void)dict_add_string_len(v_event, "complete_word", (char_u *)"", 0); + else + (void)dict_add_string_len(v_event, "complete_word", word->string, (int)word->length); - (void)dict_add_string(v_event, "complete_word", - word == NULL ? (char_u *)"" : word); - (void)dict_add_string(v_event, "complete_type", - mode_str != NULL ? mode_str : (char_u *)""); + mode_str = &ctrl_x_mode_names[mode & ~CTRL_X_WANT_IDENT]; + (void)dict_add_string_len(v_event, "complete_type", + (mode_str->string == NULL) ? (char_u *)"" : mode_str->string, (int)mode_str->length); dict_set_items_ro(v_event); #endif @@ -2919,7 +2916,7 @@ trigger_complete_done_event(int mode UNUSED, char_u *word UNUSED) ins_compl_stop(int c, int prev_mode, int retval) { int want_cindent; - char_u *word = NULL; + string_T word = {NULL, 0}; // Remove pre-inserted text when present. if (ins_compl_preinsert_effect() && ins_compl_win_active(curwin)) @@ -2956,7 +2953,7 @@ ins_compl_stop(int c, int prev_mode, int retval) want_cindent = FALSE; // don't do it again } } - else + else if (!compl_autocomplete || compl_used_match) { int prev_col = curwin->w_cursor.col; @@ -2978,7 +2975,12 @@ ins_compl_stop(int c, int prev_mode, int retval) && (c == CAR || c == K_KENTER || c == NL))) && pum_visible()) { - word = vim_strsave(compl_shown_match->cp_str.string); + word.string = vim_strnsave(compl_shown_match->cp_str.string, + compl_shown_match->cp_str.length); + if (word.string == NULL) + word.length = 0; + else + word.length = compl_shown_match->cp_str.length; retval = TRUE; } @@ -3032,7 +3034,7 @@ ins_compl_stop(int c, int prev_mode, int retval) } compl_autocomplete = FALSE; compl_from_nonkeyword = FALSE; - compl_best_matches = 0; + compl_num_bests = 0; compl_ins_end_col = 0; if (c == Ctrl_C && cmdwin_type != 0) @@ -3044,8 +3046,8 @@ ins_compl_stop(int c, int prev_mode, int retval) do_c_expr_indent(); // Trigger the CompleteDone event to give scripts a chance to act // upon the end of completion. - trigger_complete_done_event(prev_mode, word); - vim_free(word); + trigger_complete_done_event(prev_mode, &word); + vim_free(word.string); return retval; } @@ -3153,7 +3155,7 @@ ins_compl_prep(int c) else if (ctrl_x_mode_not_default()) { // We're already in CTRL-X mode, do we stay in it? - if (!vim_is_ctrl_x_key(c)) + if (c != Ctrl_R && !vim_is_ctrl_x_key(c)) { ctrl_x_mode = ctrl_x_mode_scroll() ? CTRL_X_NORMAL : CTRL_X_FINISHED; edit_submode = NULL; @@ -3181,7 +3183,7 @@ ins_compl_prep(int c) // reset continue_* if we left expansion-mode, if we stay they'll be // (re)set properly in ins_complete() - if (!vim_is_ctrl_x_key(c)) + if (c != Ctrl_R && !vim_is_ctrl_x_key(c)) { compl_cont_status = 0; compl_cont_mode = 0; @@ -3633,6 +3635,9 @@ expand_by_function(int type, char_u *base, callback_T *cb) int save_State = State; int retval; int is_cpt_function = (cb != NULL); + int use_sandbox = is_cpt_function + && was_set_insecurely(curwin, + (char_u *)"complete", OPT_LOCAL); if (!is_cpt_function) { @@ -3654,8 +3659,12 @@ expand_by_function(int type, char_u *base, callback_T *cb) // switching to another window, it should not be needed and may end up in // Insert mode in another buffer. ++textlock; + if (use_sandbox) + ++sandbox; retval = call_callback(cb, 0, &rettv, 2, args); + if (use_sandbox) + --sandbox; // Call a function, which returns a list or dict. if (retval == OK) @@ -3959,13 +3968,22 @@ f_complete_check(typval_T *argvars UNUSED, typval_T *rettv) /* * Return Insert completion mode name string */ - static char_u * -ins_compl_mode(void) + static void +ins_compl_mode(string_T *ret) { if (ctrl_x_mode_not_defined_yet() || ctrl_x_mode_scroll() || compl_started) - return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT]; + { + string_T *mode; - return (char_u *)""; + mode = &ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT]; + ret->string = (mode->string == NULL) ? (char_u *)"" : mode->string; + ret->length = mode->length; + } + else + { + ret->string = (char_u *)""; + ret->length = 0; + } } /* @@ -4028,7 +4046,7 @@ ins_compl_update_sequence_numbers(void) static void fill_complete_info_dict(dict_T *di, compl_T *match, int add_match) { - dict_add_string(di, "word", match->cp_str.string); + dict_add_string_len(di, "word", match->cp_str.string, (int)match->cp_str.length); dict_add_string(di, "abbr", match->cp_text[CPT_ABBR]); dict_add_string(di, "menu", match->cp_text[CPT_MENU]); dict_add_string(di, "kind", match->cp_text[CPT_KIND]); @@ -4037,7 +4055,7 @@ fill_complete_info_dict(dict_T *di, compl_T *match, int add_match) dict_add_bool(di, "match", match->cp_in_match_array); if (match->cp_user_data.v_type == VAR_UNKNOWN) // Add an empty string for backwards compatibility - dict_add_string(di, "user_data", (char_u *)""); + dict_add_string_len(di, "user_data", (char_u *)"", 0); else dict_add_tv(di, "user_data", &match->cp_user_data); } @@ -4088,7 +4106,12 @@ get_complete_info(list_T *what_list, dict_T *retdict) } if (ret == OK && (what_flag & CI_WHAT_MODE)) - ret = dict_add_string(retdict, "mode", ins_compl_mode()); + { + string_T mode; + + ins_compl_mode(&mode); + ret = dict_add_string_len(retdict, "mode", mode.string, (int)mode.length); + } if (ret == OK && (what_flag & CI_WHAT_PUM_VISIBLE)) ret = dict_add_number(retdict, "pum_visible", pum_visible()); @@ -4782,7 +4805,32 @@ get_next_cmdline_completion(void) if (expand_cmdline(&compl_xp, compl_pattern.string, (int)compl_pattern.length, &num_matches, &matches) == EXPAND_OK) - ins_compl_add_matches(num_matches, matches, FALSE); + { + int add_r = OK; + int dir = compl_direction; + + for (int i = 0; i < num_matches && add_r != FAIL; i++) + { + char_u *(cptext[CPT_COUNT]) = {NULL, NULL, NULL, NULL}; + + if (compl_xp.xp_files_abbr != NULL) + cptext[CPT_ABBR] = compl_xp.xp_files_abbr[i]; + if (compl_xp.xp_files_kind != NULL) + cptext[CPT_KIND] = compl_xp.xp_files_kind[i]; + if (compl_xp.xp_files_menu != NULL) + cptext[CPT_MENU] = compl_xp.xp_files_menu[i]; + if (compl_xp.xp_files_info != NULL) + cptext[CPT_INFO] = compl_xp.xp_files_info[i]; + + add_r = ins_compl_add(matches[i], -1, NULL, cptext, NULL, dir, + CP_FAST, FALSE, NULL, FUZZY_SCORE_NONE); + if (add_r == OK) + // if dir was BACKWARD then honor it just once + dir = FORWARD; + } + FreeWild(num_matches, matches); + free_xp_files_extra(&compl_xp, num_matches); + } } /* @@ -5406,7 +5454,7 @@ ins_compl_get_exp(pos_T *ini) buf_T *buf; FOR_ALL_BUFFERS(buf) - buf->b_scanned = 0; + buf->b_scanned = false; if (!st_cleared) { CLEAR_FIELD(st); @@ -5530,7 +5578,7 @@ ins_compl_get_exp(pos_T *ini) { // Mark a buffer scanned when it has been scanned completely if (buf_valid(st.ins_buf) && (type == 0 || type == CTRL_X_PATH_PATTERNS)) - st.ins_buf->b_scanned = TRUE; + st.ins_buf->b_scanned = true; compl_started = FALSE; } @@ -5783,7 +5831,8 @@ find_common_prefix(size_t *prefix_len, int curbuf_only) } if (!match_limit_exceeded && (!curbuf_only - || cpt_sources_array[cur_source].cs_flag == '.')) + || (cur_source != -1 + && cpt_sources_array[cur_source].cs_flag == '.'))) { if (first == NULL && STRNCMP(ins_compl_leader(), compl->cp_str.string, ins_compl_leader_len()) == 0) @@ -6064,7 +6113,7 @@ find_next_completion_match( compl_shown_match = compl_shown_match->cp_next; --compl_pending; } - if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) + else if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) { compl_shown_match = compl_shown_match->cp_prev; ++compl_pending; @@ -6747,6 +6796,9 @@ get_userdefined_compl_info( pos_T pos; int save_State = State; int is_cpt_function = (cb != NULL); + int use_sandbox = is_cpt_function + && was_set_insecurely(curwin, + (char_u *)"complete", OPT_LOCAL); if (!is_cpt_function) { @@ -6769,7 +6821,11 @@ get_userdefined_compl_info( args[2].v_type = VAR_UNKNOWN; pos = curwin->w_cursor; ++textlock; + if (use_sandbox) + ++sandbox; col = call_callback_retnr(cb, 2, args); + if (use_sandbox) + --sandbox; --textlock; State = save_State; diff --git a/src/job.c b/src/job.c index 0c7de3079b..20b55b16cd 100644 --- a/src/job.c +++ b/src/job.c @@ -27,6 +27,8 @@ handle_mode(typval_T *item, jobopt_T *opt, ch_mode_T *modep, int jo) *modep = CH_MODE_NL; else if (STRCMP(val, "raw") == 0) *modep = CH_MODE_RAW; + else if (STRCMP(val, "blob") == 0) + *modep = CH_MODE_BLOB; else if (STRCMP(val, "js") == 0) *modep = CH_MODE_JS; else if (STRCMP(val, "json") == 0) diff --git a/src/json.c b/src/json.c index a21ed6e771..b9cbc0d594 100644 --- a/src/json.c +++ b/src/json.c @@ -18,7 +18,7 @@ #if defined(FEAT_EVAL) -static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int depth); +static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int options); /* * Encode "val" into a JSON format string. @@ -28,7 +28,7 @@ static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int option static int json_encode_gap(garray_T *gap, typval_T *val, int options) { - if (json_encode_item(gap, val, get_copyID(), options, 0) == FAIL) + if (json_encode_item(gap, val, get_copyID(), options) == FAIL) { ga_clear(gap); gap->ga_data = vim_strsave((char_u *)""); @@ -51,6 +51,8 @@ json_encode(typval_T *val, int options) // Store bytes in the growarray. ga_init2(&ga, 1, 4000); json_encode_gap(&ga, val, options); + if (options & JSON_NL) + ga_append(&ga, NL); ga_append(&ga, NUL); return ga.ga_data; } @@ -264,31 +266,61 @@ is_simple_key(char_u *key) return TRUE; } +typedef enum { + ENC_LIST, + ENC_TUPLE, + ENC_DICT, +} json_enc_type_T; + +typedef struct { + json_enc_type_T je_type; + int je_options; // options when this container was entered + union { + struct { + list_T *list; + listitem_T *li; // current item + } l; + struct { + tuple_T *tuple; + int idx; // current index + int len; + } t; + struct { + dict_T *dict; + hashitem_T *hi; // current entry + int todo; // remaining entries + } d; + } je_u; +} json_enc_frame_T; + /* * Encode "val" into "gap". + * Uses an explicit stack to avoid deep recursion on nested structures. * Return FAIL or OK. */ static int -json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int depth) +json_encode_item(garray_T *gap, typval_T *val, int copyID, int options) { - char_u numbuf[NUMBUFLEN]; - char_u *res; - blob_T *b; - list_T *l; - tuple_T *tuple; - dict_T *d; - int i; + char_u numbuf[NUMBUFLEN]; + char_u *res; + blob_T *b; + list_T *l; + tuple_T *tuple; + dict_T *d; + int i; + garray_T stack; + typval_T *cur_val; + json_enc_frame_T *frame; - if (depth > p_mfd) + ga_init2(&stack, sizeof(json_enc_frame_T), 100); + cur_val = val; + + for (;;) { - emsg(_(e_function_call_depth_is_higher_than_maxfuncdepth)); - return FAIL; - } - - switch (val->v_type) + switch (cur_val->v_type) { case VAR_BOOL: - switch ((long)val->vval.v_number) + switch ((long)cur_val->vval.v_number) { case VVAL_FALSE: GA_CONCAT_LITERAL(gap, "false"); break; case VVAL_TRUE: GA_CONCAT_LITERAL(gap, "true"); break; @@ -296,7 +328,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept break; case VAR_SPECIAL: - switch ((long)val->vval.v_number) + switch ((long)cur_val->vval.v_number) { case VVAL_NONE: if ((options & JSON_JS) != 0 && (options & JSON_NO_NONE) == 0) @@ -312,13 +344,13 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept size_t numbuflen; numbuflen = vim_snprintf_safelen((char *)numbuf, sizeof(numbuf), - "%lld", (varnumber_T)val->vval.v_number); + "%lld", (varnumber_T)cur_val->vval.v_number); ga_concat_len(gap, numbuf, numbuflen); } break; case VAR_STRING: - res = val->vval.v_string; + res = cur_val->vval.v_string; write_string(gap, res); break; @@ -330,43 +362,52 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept case VAR_CLASS: case VAR_OBJECT: case VAR_TYPEALIAS: - semsg(_(e_cannot_json_encode_str), vartype_name(val->v_type)); - return FAIL; + semsg(_(e_cannot_json_encode_str), vartype_name(cur_val->v_type)); + goto theend; case VAR_BLOB: - b = val->vval.v_blob; + b = cur_val->vval.v_blob; if (b == NULL || b->bv_ga.ga_len == 0) GA_CONCAT_LITERAL(gap, "[]"); else { - ga_append(gap, '['); - for (i = 0; i < b->bv_ga.ga_len; i++) + int blen = b->bv_ga.ga_len; + char_u *src; + char_u *dst; + + // Worst case: '[' + ']' + per-byte 3 digits + comma = 2 + 4*blen + if (ga_grow(gap, 2 + 4 * blen) == FAIL) + goto theend; + src = (char_u *)b->bv_ga.ga_data; + dst = (char_u *)gap->ga_data + gap->ga_len; + *dst++ = '['; + for (i = 0; i < blen; i++) { - int byte = blob_get(b, i); + int byte = src[i]; if (i > 0) - ga_append(gap, ','); - // blob bytes are 0-255, use simple conversion + *dst++ = ','; if (byte >= 100) { - ga_append(gap, '0' + byte / 100); - ga_append(gap, '0' + (byte / 10) % 10); - ga_append(gap, '0' + byte % 10); + *dst++ = '0' + byte / 100; + *dst++ = '0' + (byte / 10) % 10; + *dst++ = '0' + byte % 10; } else if (byte >= 10) { - ga_append(gap, '0' + byte / 10); - ga_append(gap, '0' + byte % 10); + *dst++ = '0' + byte / 10; + *dst++ = '0' + byte % 10; } else - ga_append(gap, '0' + byte); + *dst++ = '0' + byte; } - ga_append(gap, ']'); + *dst++ = ']'; + gap->ga_len = (int)(dst - (char_u *)gap->ga_data); } break; case VAR_LIST: - l = val->vval.v_list; + l = cur_val->vval.v_list; if (l == NULL) GA_CONCAT_LITERAL(gap, "[]"); else @@ -375,26 +416,28 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept GA_CONCAT_LITERAL(gap, "[]"); else { - listitem_T *li; - l->lv_copyID = copyID; ga_append(gap, '['); CHECK_LIST_MATERIALIZE(l); - for (li = l->lv_first; li != NULL && !got_int; ) + if (l->lv_first != NULL) { - if (json_encode_item(gap, &li->li_tv, copyID, - options & JSON_JS, - depth + 1) == FAIL) - return FAIL; - if ((options & JSON_JS) - && li->li_next == NULL - && li->li_tv.v_type == VAR_SPECIAL - && li->li_tv.vval.v_number == VVAL_NONE) - // add an extra comma if the last item is v:none - ga_append(gap, ','); - li = li->li_next; - if (li != NULL) - ga_append(gap, ','); + if (stack.ga_len >= p_mfd) + { + emsg(_(e_function_call_depth_is_higher_than_maxfuncdepth)); + goto theend; + } + if (ga_grow(&stack, 1) == FAIL) + goto theend; + frame = ((json_enc_frame_T *)stack.ga_data) + + stack.ga_len; + frame->je_type = ENC_LIST; + frame->je_options = options; + frame->je_u.l.list = l; + frame->je_u.l.li = l->lv_first; + ++stack.ga_len; + options = options & JSON_JS; + cur_val = &l->lv_first->li_tv; + continue; } ga_append(gap, ']'); l->lv_copyID = 0; @@ -403,7 +446,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept break; case VAR_TUPLE: - tuple = val->vval.v_tuple; + tuple = cur_val->vval.v_tuple; if (tuple == NULL) GA_CONCAT_LITERAL(gap, "[]"); else @@ -414,33 +457,37 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept { int len = TUPLE_LEN(tuple); - tuple->tv_copyID = copyID; - ga_append(gap, '['); - for (i = 0; i < len && !got_int; i++) + if (len > 0) { - typval_T *t_item = TUPLE_ITEM(tuple, i); - if (json_encode_item(gap, t_item, copyID, - options & JSON_JS, - depth + 1) == FAIL) - return FAIL; - - if ((options & JSON_JS) - && i == len - 1 - && t_item->v_type == VAR_SPECIAL - && t_item->vval.v_number == VVAL_NONE) - // add an extra comma if the last item is v:none - ga_append(gap, ','); - if (i <= len - 2) - ga_append(gap, ','); + tuple->tv_copyID = copyID; + ga_append(gap, '['); + if (stack.ga_len >= p_mfd) + { + emsg(_(e_function_call_depth_is_higher_than_maxfuncdepth)); + goto theend; + } + if (ga_grow(&stack, 1) == FAIL) + goto theend; + frame = ((json_enc_frame_T *)stack.ga_data) + + stack.ga_len; + frame->je_type = ENC_TUPLE; + frame->je_options = options; + frame->je_u.t.tuple = tuple; + frame->je_u.t.idx = 0; + frame->je_u.t.len = len; + ++stack.ga_len; + options = options & JSON_JS; + cur_val = TUPLE_ITEM(tuple, 0); + continue; } - ga_append(gap, ']'); - tuple->tv_copyID = 0; + else + GA_CONCAT_LITERAL(gap, "[]"); } } break; case VAR_DICT: - d = val->vval.v_dict; + d = cur_val->vval.v_dict; if (d == NULL) GA_CONCAT_LITERAL(gap, "{}"); else @@ -449,46 +496,60 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept GA_CONCAT_LITERAL(gap, "{}"); else { - int first = TRUE; int todo = (int)d->dv_hashtab.ht_used; hashitem_T *hi; - d->dv_copyID = copyID; - ga_append(gap, '{'); + if (todo > 0) + { + d->dv_copyID = copyID; + ga_append(gap, '{'); - for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; - ++hi) - if (!HASHITEM_EMPTY(hi)) - { - --todo; - if (first) - first = FALSE; - else - ga_append(gap, ','); - if ((options & JSON_JS) + // Find first non-empty hash entry + for (hi = d->dv_hashtab.ht_array; + HASHITEM_EMPTY(hi); ++hi) + ; + --todo; + + // Write first key + if ((options & JSON_JS) && is_simple_key(hi->hi_key)) - ga_concat(gap, hi->hi_key); - else - write_string(gap, hi->hi_key); - ga_append(gap, ':'); - if (json_encode_item(gap, &dict_lookup(hi)->di_tv, - copyID, options | JSON_NO_NONE, - depth + 1) == FAIL) - return FAIL; + ga_concat(gap, hi->hi_key); + else + write_string(gap, hi->hi_key); + ga_append(gap, ':'); + + if (stack.ga_len >= p_mfd) + { + emsg(_(e_function_call_depth_is_higher_than_maxfuncdepth)); + goto theend; } - ga_append(gap, '}'); - d->dv_copyID = 0; + if (ga_grow(&stack, 1) == FAIL) + goto theend; + frame = ((json_enc_frame_T *)stack.ga_data) + + stack.ga_len; + frame->je_type = ENC_DICT; + frame->je_options = options; + frame->je_u.d.dict = d; + frame->je_u.d.hi = hi; + frame->je_u.d.todo = todo; + ++stack.ga_len; + options = options | JSON_NO_NONE; + cur_val = &dict_lookup(hi)->di_tv; + continue; + } + else + GA_CONCAT_LITERAL(gap, "{}"); } } break; case VAR_FLOAT: #if defined(HAVE_MATH_H) - if (isnan(val->vval.v_float)) + if (isnan(cur_val->vval.v_float)) GA_CONCAT_LITERAL(gap, "NaN"); - else if (isinf(val->vval.v_float)) + else if (isinf(cur_val->vval.v_float)) { - if (val->vval.v_float < 0.0) + if (cur_val->vval.v_float < 0.0) GA_CONCAT_LITERAL(gap, "-Infinity"); else GA_CONCAT_LITERAL(gap, "Infinity"); @@ -499,17 +560,151 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options, int dept size_t numbuflen; numbuflen = vim_snprintf_safelen((char *)numbuf, sizeof(numbuf), - "%g", val->vval.v_float); + "%g", cur_val->vval.v_float); ga_concat_len(gap, numbuf, numbuflen); } break; + case VAR_UNKNOWN: case VAR_ANY: case VAR_VOID: internal_error_no_abort("json_encode_item()"); - return FAIL; + goto theend; } - return OK; + + // Process the completed item by advancing containers or + // returning when the stack is empty. + for (;;) + { + int advance = FALSE; + + if (stack.ga_len == 0) + { + ga_clear(&stack); + return OK; + } + + frame = ((json_enc_frame_T *)stack.ga_data) + + stack.ga_len - 1; + switch (frame->je_type) + { + case ENC_LIST: + { + listitem_T *li = frame->je_u.l.li; + + // JSON_JS: add trailing comma if last item is v:none + if ((frame->je_options & JSON_JS) + && li->li_next == NULL + && li->li_tv.v_type == VAR_SPECIAL + && li->li_tv.vval.v_number == VVAL_NONE) + ga_append(gap, ','); + + li = li->li_next; + frame->je_u.l.li = li; + if (li != NULL && !got_int) + { + ga_append(gap, ','); + options = frame->je_options & JSON_JS; + cur_val = &li->li_tv; + advance = TRUE; + break; + } + ga_append(gap, ']'); + frame->je_u.l.list->lv_copyID = 0; + --stack.ga_len; + break; + } + + case ENC_TUPLE: + { + int idx = frame->je_u.t.idx; + int len = frame->je_u.t.len; + + // JSON_JS: add trailing comma if last item is v:none + if ((frame->je_options & JSON_JS) && idx == len - 1) + { + typval_T *t_item = + TUPLE_ITEM(frame->je_u.t.tuple, idx); + + if (t_item->v_type == VAR_SPECIAL + && t_item->vval.v_number == VVAL_NONE) + ga_append(gap, ','); + } + + ++idx; + frame->je_u.t.idx = idx; + if (idx < len && !got_int) + { + ga_append(gap, ','); + options = frame->je_options & JSON_JS; + cur_val = TUPLE_ITEM(frame->je_u.t.tuple, idx); + advance = TRUE; + break; + } + ga_append(gap, ']'); + frame->je_u.t.tuple->tv_copyID = 0; + --stack.ga_len; + break; + } + + case ENC_DICT: + { + hashitem_T *hi = frame->je_u.d.hi; + int todo = frame->je_u.d.todo; + + if (todo > 0 && !got_int) + { + // Advance to next non-empty entry + for (++hi; HASHITEM_EMPTY(hi); ++hi) + ; + --todo; + frame->je_u.d.hi = hi; + frame->je_u.d.todo = todo; + + ga_append(gap, ','); + if ((frame->je_options & JSON_JS) + && is_simple_key(hi->hi_key)) + ga_concat(gap, hi->hi_key); + else + write_string(gap, hi->hi_key); + ga_append(gap, ':'); + + options = frame->je_options | JSON_NO_NONE; + cur_val = &dict_lookup(hi)->di_tv; + advance = TRUE; + break; + } + ga_append(gap, '}'); + frame->je_u.d.dict->dv_copyID = 0; + --stack.ga_len; + break; + } + } + if (advance) + break; + } + } + +theend: + // Clean up copyIDs for remaining frames on error/failure + for (i = 0; i < stack.ga_len; i++) + { + frame = ((json_enc_frame_T *)stack.ga_data) + i; + switch (frame->je_type) + { + case ENC_LIST: + frame->je_u.l.list->lv_copyID = 0; + break; + case ENC_TUPLE: + frame->je_u.t.tuple->tv_copyID = 0; + break; + case ENC_DICT: + frame->je_u.d.dict->dv_copyID = 0; + break; + } + } + ga_clear(&stack); + return FAIL; } /* diff --git a/src/libvterm/README b/src/libvterm/README index 56c6e222be..875c448cbb 100644 --- a/src/libvterm/README +++ b/src/libvterm/README @@ -7,7 +7,7 @@ The original can be found: https://github.com/neovim/libvterm Modifications: -- revisions up to 839 have been included +- revisions up to 843 have been included - Added a .gitignore file. - use TRUE and FALSE instead of true and false - use int or unsigned int instead of bool diff --git a/src/libvterm/include/vterm.h b/src/libvterm/include/vterm.h index 48deebe25e..54e9e49242 100644 --- a/src/libvterm/include/vterm.h +++ b/src/libvterm/include/vterm.h @@ -452,6 +452,8 @@ typedef struct { int (*resize)(int rows, int cols, VTermStateFields *fields, void *user); int (*setlineinfo)(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user); int (*sb_clear)(void *user); + // ABI-compat only enabled if vterm_state_callbacks_has_premove() is invoked + int (*premove)(VTermRect dest, void *user); } VTermStateCallbacks; // VIM: added @@ -488,6 +490,8 @@ VTermState *vterm_obtain_state(VTerm *vt); void vterm_state_set_callbacks(VTermState *state, const VTermStateCallbacks *callbacks, void *user); void *vterm_state_get_cbdata(VTermState *state); +void vterm_state_callbacks_has_premove(VTermState *state); + void vterm_state_set_unrecognised_fallbacks(VTermState *state, const VTermStateFallbacks *fallbacks, void *user); void *vterm_state_get_unrecognised_fbdata(VTermState *state); @@ -578,6 +582,8 @@ typedef struct { int (*sb_pushline)(int cols, const VTermScreenCell *cells, void *user); int (*sb_popline)(int cols, VTermScreenCell *cells, void *user); int (*sb_clear)(void* user); + /* ABI-compat this is only used if vterm_screen_callbacks_has_pushline4() is called */ + int (*sb_pushline4)(int cols, const VTermScreenCell *cells, int continuation, void *user); } VTermScreenCallbacks; // Return the screen of the vterm. @@ -590,6 +596,8 @@ VTermScreen *vterm_obtain_screen(VTerm *vt); void vterm_screen_set_callbacks(VTermScreen *screen, const VTermScreenCallbacks *callbacks, void *user); void *vterm_screen_get_cbdata(VTermScreen *screen); +void vterm_screen_callbacks_has_pushline4(VTermScreen *screen); + void vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermStateFallbacks *fallbacks, void *user); void *vterm_screen_get_unrecognised_fbdata(VTermScreen *screen); diff --git a/src/libvterm/src/screen.c b/src/libvterm/src/screen.c index fd76777c41..5ed8dd48ae 100644 --- a/src/libvterm/src/screen.c +++ b/src/libvterm/src/screen.c @@ -49,6 +49,7 @@ struct VTermScreen const VTermScreenCallbacks *callbacks; void *cbdata; + int callbacks_has_pushline4; VTermDamageSize damage_merge; /* start_row == -1 => no damage */ @@ -209,28 +210,41 @@ static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user) return 1; } -static void sb_pushline_from_row(VTermScreen *screen, int row) +static void sb_pushline_from_row(VTermScreen *screen, int row, int continuation) { VTermPos pos; pos.row = row; for(pos.col = 0; pos.col < screen->cols; pos.col++) vterm_screen_get_cell(screen, pos, screen->sb_buffer + pos.col); - (screen->callbacks->sb_pushline)(screen->cols, screen->sb_buffer, screen->cbdata); + if(screen->callbacks_has_pushline4 && screen->callbacks->sb_pushline4) + (screen->callbacks->sb_pushline4)(screen->cols, screen->sb_buffer, continuation, screen->cbdata); + else + (screen->callbacks->sb_pushline)(screen->cols, screen->sb_buffer, screen->cbdata); +} + +static int premove(VTermRect rect, void *user) +{ + VTermScreen *screen = user; + + if(((screen->callbacks && screen->callbacks->sb_pushline) || + (screen->callbacks_has_pushline4 && screen->callbacks && screen->callbacks->sb_pushline4)) && + rect.start_row == 0 && rect.start_col == 0 && // starts top-left corner + rect.end_col == screen->cols && // full width + screen->buffer == screen->buffers[BUFIDX_PRIMARY]) { // not altscreen + for(int row = 0; row < rect.end_row; row++) { + const VTermLineInfo *lineinfo = vterm_state_get_lineinfo(screen->state, row); + sb_pushline_from_row(screen, row, lineinfo->continuation); + } + } + + return 1; } static int moverect_internal(VTermRect dest, VTermRect src, void *user) { VTermScreen *screen = user; - if(screen->callbacks && screen->callbacks->sb_pushline && - dest.start_row == 0 && dest.start_col == 0 && // starts top-left corner - dest.end_col == screen->cols && // full width - screen->buffer == screen->buffers[BUFIDX_PRIMARY]) { // not altscreen - for(int row = 0; row < src.start_row; row++) - sb_pushline_from_row(screen, row); - } - int cols = src.end_col - src.start_col; int downward = src.start_row - dest.start_row; @@ -685,9 +699,12 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new if(old_row >= 0 && bufidx == BUFIDX_PRIMARY) { /* Push spare lines to scrollback buffer */ - if(screen->callbacks && screen->callbacks->sb_pushline) - for(int row = 0; row <= old_row; row++) - sb_pushline_from_row(screen, row); + if((screen->callbacks && screen->callbacks->sb_pushline) || + (screen->callbacks_has_pushline4 && screen->callbacks && screen->callbacks->sb_pushline4)) + for(int row = 0; row <= old_row; row++) { + const VTermLineInfo *lineinfo = old_lineinfo + row; + sb_pushline_from_row(screen, row, lineinfo->continuation); + } if(active) statefields->pos.row -= (old_row + 1); } @@ -880,6 +897,7 @@ static VTermStateCallbacks state_cbs = { &resize, // resize &setlineinfo, // setlineinfo &sb_clear, //sb_clear + &premove, // premove }; /* @@ -914,6 +932,7 @@ static VTermScreen *screen_new(VTerm *vt) screen->callbacks = NULL; screen->cbdata = NULL; + screen->callbacks_has_pushline4 = 0; screen->buffers[BUFIDX_PRIMARY] = alloc_buffer(screen, rows, cols); @@ -927,6 +946,7 @@ static VTermScreen *screen_new(VTerm *vt) } vterm_state_set_callbacks(screen->state, &state_cbs, screen); + vterm_state_callbacks_has_premove(screen->state); return screen; } @@ -1127,6 +1147,11 @@ void *vterm_screen_get_cbdata(VTermScreen *screen) return screen->cbdata; } +void vterm_screen_callbacks_has_pushline4(VTermScreen *screen) +{ + screen->callbacks_has_pushline4 = 1; +} + void vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermStateFallbacks *fallbacks, void *user) { vterm_state_set_unrecognised_fallbacks(screen->state, fallbacks, user); diff --git a/src/libvterm/src/state.c b/src/libvterm/src/state.c index fca833326e..70bce0a236 100644 --- a/src/libvterm/src/state.c +++ b/src/libvterm/src/state.c @@ -78,6 +78,7 @@ static VTermState *vterm_state_new(VTerm *vt) state->callbacks = NULL; state->cbdata = NULL; + state->callbacks_has_premove = 0; state->selection.callbacks = NULL; state->selection.user = NULL; @@ -133,6 +134,33 @@ static void scroll(VTermState *state, VTermRect rect, int downward, int rightwar else if(rightward < -cols) rightward = -cols; + if(state->callbacks_has_premove && state->callbacks && state->callbacks->premove) { + // TODO: technically this logic is wrong if both downward != 0 and rightward != 0 + + /* Work out what subsection of the destination area is about to be destroyed */ + if(downward > 0) + /* about to destroy the top */ + (*state->callbacks->premove)((VTermRect){ + .start_row = rect.start_row, .end_row = rect.start_row + downward, + .start_col = rect.start_col, .end_col = rect.end_col}, state->cbdata); + else if(downward < 0) + /* about to destroy the bottom */ + (*state->callbacks->premove)((VTermRect){ + .start_row = rect.end_row + downward, .end_row = rect.end_row, + .start_col = rect.start_col, .end_col = rect.end_col}, state->cbdata); + + if(rightward > 0) + /* about to destroy the left */ + (*state->callbacks->premove)((VTermRect){ + .start_row = rect.start_row, .end_row = rect.end_row, + .start_col = rect.start_col, .end_col = rect.start_col + rightward}, state->cbdata); + else if(rightward < 0) + /* about to destroy the right */ + (*state->callbacks->premove)((VTermRect){ + .start_row = rect.start_row, .end_row = rect.end_row, + .start_col = rect.end_col + rightward, .end_col = rect.end_col}, state->cbdata); + } + // Update lineinfo if full line if(rect.start_col == 0 && rect.end_col == state->cols && rightward == 0) { int height = rect.end_row - rect.start_row - abs(downward); @@ -392,6 +420,9 @@ static int on_text(const char bytes[], size_t len, void *user) width = this_width; // TODO: should be += ? } + if (width < 0) + width = 0; + while(i < npoints && vterm_unicode_is_combining(codepoints[i])) i++; @@ -1612,7 +1643,9 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha case 0x74: switch(CSI_ARG(args[0])) { case 8: // CSI 8 ; rows ; cols t set size - if (argcount == 3) + if (argcount == 3 && + !CSI_ARG_IS_MISSING(args[1]) && !CSI_ARG_IS_MISSING(args[2]) && + CSI_ARG(args[1]) > 0 && CSI_ARG(args[2]) > 0) on_resize(CSI_ARG(args[1]), CSI_ARG(args[2]), state); break; default: @@ -2319,6 +2352,11 @@ void vterm_state_set_callbacks(VTermState *state, const VTermStateCallbacks *cal } } +void vterm_state_callbacks_has_premove(VTermState *state) +{ + state->callbacks_has_premove = 1; +} + void *vterm_state_get_cbdata(VTermState *state) { return state->cbdata; diff --git a/src/libvterm/src/vterm_internal.h b/src/libvterm/src/vterm_internal.h index 0f80fa4315..b9830b9db3 100644 --- a/src/libvterm/src/vterm_internal.h +++ b/src/libvterm/src/vterm_internal.h @@ -70,6 +70,7 @@ struct VTermState const VTermStateCallbacks *callbacks; void *cbdata; + int callbacks_has_premove; const VTermStateFallbacks *fallbacks; void *fbdata; diff --git a/src/libvterm/t/12state_scroll.test b/src/libvterm/t/12state_scroll.test index c1f2791d00..5605131bc7 100644 --- a/src/libvterm/t/12state_scroll.test +++ b/src/libvterm/t/12state_scroll.test @@ -127,24 +127,28 @@ PUSH "\e[100;105r\eD" PUSH "\e[5;2r\eD" RESET -WANTSTATE -s+me +WANTSTATE -s+Pme !Scroll Down move+erase emulation PUSH "\e[S" + premove 0..1,0..80 moverect 1..25,0..80 -> 0..24,0..80 erase 24..25,0..80 ?cursor = 0,0 PUSH "\e[2S" + premove 0..2,0..80 moverect 2..25,0..80 -> 0..23,0..80 erase 23..25,0..80 ?cursor = 0,0 !Scroll Up move+erase emulation PUSH "\e[T" + premove 24..25,0..80 moverect 0..24,0..80 -> 1..25,0..80 erase 0..1,0..80 ?cursor = 0,0 PUSH "\e[2T" + premove 23..25,0..80 moverect 0..23,0..80 -> 2..25,0..80 erase 0..2,0..80 ?cursor = 0,0 diff --git a/src/libvterm/t/13state_edit.test b/src/libvterm/t/13state_edit.test index d3f3e9e40b..84d22cc9ac 100644 --- a/src/libvterm/t/13state_edit.test +++ b/src/libvterm/t/13state_edit.test @@ -268,7 +268,7 @@ PUSH "\e[2\"q" PUSH "\eP\$q\"q\e\\" output "\eP1\$r2\"q\e\\" -WANTSTATE -s+m +WANTSTATE -s+Pm !ICH move+erase emuation RESET @@ -278,12 +278,14 @@ PUSH "ACD" PUSH "\e[2D" ?cursor = 0,1 PUSH "\e[@" + premove 0..1,79..80 moverect 0..1,1..79 -> 0..1,2..80 erase 0..1,1..2 ?cursor = 0,1 PUSH "B" ?cursor = 0,2 PUSH "\e[3@" + premove 0..1,77..80 moverect 0..1,2..77 -> 0..1,5..80 erase 0..1,2..5 @@ -295,10 +297,12 @@ PUSH "ABBC" PUSH "\e[3D" ?cursor = 0,1 PUSH "\e[P" + premove 0..1,1..2 moverect 0..1,2..80 -> 0..1,1..79 erase 0..1,79..80 ?cursor = 0,1 PUSH "\e[3P" + premove 0..1,1..4 moverect 0..1,4..80 -> 0..1,1..77 erase 0..1,77..80 ?cursor = 0,1 diff --git a/src/libvterm/t/62screen_damage.test b/src/libvterm/t/62screen_damage.test index 3b1b238527..2f11c759dd 100644 --- a/src/libvterm/t/62screen_damage.test +++ b/src/libvterm/t/62screen_damage.test @@ -146,9 +146,9 @@ PUSH "\e[25H\r\nABCDE\b\b\b\e[2P\r\n" sb_pushline 80 = moverect 1..25,0..80 -> 0..24,0..80 damage 24..25,0..80 = 24<41 42 43 44 45> + sb_pushline 80 = moverect 24..25,4..80 -> 24..25,2..78 damage 24..25,78..80 - sb_pushline 80 = DAMAGEFLUSH moverect 1..25,0..80 -> 0..24,0..80 damage 24..25,0..80 diff --git a/src/libvterm/t/69screen_pushline.test b/src/libvterm/t/69screen_pushline.test new file mode 100644 index 0000000000..735ea29479 --- /dev/null +++ b/src/libvterm/t/69screen_pushline.test @@ -0,0 +1,17 @@ +INIT +WANTSTATE +WANTSCREEN b + +RESET + +!Spillover text marks continuation on second line +PUSH "A"x85 +PUSH "\r\n" + ?lineinfo 0 = + ?lineinfo 1 = cont + +!Continuation mark sent to sb_pushline +PUSH "\n"x23 + sb_pushline 80 = 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 +PUSH "\n" + sb_pushline 80 cont = 41 41 41 41 41 diff --git a/src/libvterm/t/harness.c b/src/libvterm/t/harness.c index 5285d94ec0..6fc34fe043 100644 --- a/src/libvterm/t/harness.c +++ b/src/libvterm/t/harness.c @@ -326,6 +326,18 @@ static int movecursor(VTermPos pos, VTermPos oldpos UNUSED, int visible UNUSED, return 1; } +static int want_premove = 0; +static int premove(VTermRect rect, void *user UNUSED) +{ + if(!want_premove) + return 0; + + printf("premove %d..%d,%d..%d\n", + rect.start_row, rect.end_row, rect.start_col, rect.end_col); + + return 1; +} + static int want_scrollrect = 0; static int scrollrect(VTermRect rect, int downward, int rightward, void *user UNUSED) { @@ -509,6 +521,7 @@ VTermStateCallbacks state_cbs = { NULL, // resize state_setlineinfo, // setlineinfo state_sb_clear, // sb_clear + premove, // premove }; static int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user UNUSED) @@ -590,7 +603,7 @@ static int screen_damage(VTermRect rect, void *user UNUSED) } static int want_screen_scrollback = 0; -static int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user UNUSED) +static int screen_sb_pushline4(int cols, const VTermScreenCell *cells, int continuation, void *user UNUSED) { int eol; int c; @@ -602,7 +615,7 @@ static int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user while(eol && !cells[eol-1].chars[0]) eol--; - printf("sb_pushline %d =", cols); + printf("sb_pushline %d%s =", cols, continuation ? " cont" : ""); for(c = 0; c < eol; c++) printf(" %02X", cells[c].chars[0]); printf("\n"); @@ -647,9 +660,10 @@ VTermScreenCallbacks screen_cbs = { settermprop, // settermprop NULL, // bell NULL, // resize - screen_sb_pushline, // sb_pushline + NULL, // sb_pushline screen_sb_popline, // sb_popline screen_sb_clear, // sb_clear + screen_sb_pushline4, // sb_pushline4 }; int main(int argc UNUSED, char **argv UNUSED) @@ -689,6 +703,7 @@ int main(int argc UNUSED, char **argv UNUSED) if(!state) { state = vterm_obtain_state(vt); vterm_state_set_callbacks(state, &state_cbs, NULL); + vterm_state_callbacks_has_premove(state); /* In some tests we want to check the behaviour of overflowing the * buffer, so make it nicely small */ @@ -713,6 +728,9 @@ int main(int argc UNUSED, char **argv UNUSED) case 's': want_scrollrect = sense; break; + case 'P': + want_premove = sense; + break; case 'm': want_moverect = sense; break; @@ -740,6 +758,7 @@ int main(int argc UNUSED, char **argv UNUSED) if(!screen) screen = vterm_obtain_screen(vt); vterm_screen_set_callbacks(screen, &screen_cbs, NULL); + vterm_screen_callbacks_has_pushline4(screen); while(line[i] == ' ') i++; diff --git a/src/libvterm/t/run-test.pl b/src/libvterm/t/run-test.pl index 3440465cda..819b5b4d4e 100644 --- a/src/libvterm/t/run-test.pl +++ b/src/libvterm/t/run-test.pl @@ -124,7 +124,7 @@ sub do_line elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) { $line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2"; } - elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|sb_clear|settermprop|setmousefunc|selection-query) ?/ ) { + elsif( $line =~ m/^(?:movecursor|scrollrect|premove|moverect|erase|damage|sb_pushline|sb_popline|sb_clear|settermprop|setmousefunc|selection-query) ?/ ) { # no conversion } elsif( $line =~ m/^(selection-set) (.*?) (\[?)(.*?)(\]?)$/ ) { diff --git a/src/list.c b/src/list.c index c9e9d686bd..3074bb93f2 100644 --- a/src/list.c +++ b/src/list.c @@ -1368,7 +1368,8 @@ list_slice_or_index( { // copy the item to "var1" to avoid that freeing the list makes it // invalid. - listitem_T *li = check_range_index_one(list, (long *)&n1, TRUE, TRUE); + long index = n1; + listitem_T *li = check_range_index_one(list, &index, TRUE, TRUE); if (li == NULL) return FAIL; copy_tv(&li->li_tv, &var1); diff --git a/src/macros.h b/src/macros.h index 9007b5b37a..3b246b2200 100644 --- a/src/macros.h +++ b/src/macros.h @@ -373,6 +373,15 @@ s.length = 0; \ } while (0) +#define STR_LITERAL_INIT(s) \ + {(char_u *)(s), STRLEN_LITERAL(s)} + +#define STR_LITERAL_SET(str, s) \ + do { \ + (str).string = (char_u *)(s); \ + (str).length = STRLEN_LITERAL(s); \ + } while (0) + // Whether a command index indicates a user command. #define IS_USER_CMDIDX(idx) ((int)(idx) < 0) diff --git a/src/main.c b/src/main.c index 02fe853c28..562b1d4dad 100644 --- a/src/main.c +++ b/src/main.c @@ -205,7 +205,7 @@ main // Check if the current executable file is for the GUI subsystem. gui.starting = mch_is_gui_executable(); # elif defined(FEAT_GUI_MSWIN) - gui.starting = TRUE; + gui.starting = true; # endif # ifdef FEAT_CLIENTSERVER @@ -243,7 +243,7 @@ main * :gui. */ # ifdef ALWAYS_USE_GUI - gui.starting = TRUE; + gui.starting = true; # else # if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) /* @@ -254,7 +254,7 @@ main { if (gui_init_check() == FAIL) { - gui.starting = FALSE; + gui.starting = false; // When running "evim" or "gvim -y" we need the menus, exit if we // don't have them. @@ -942,9 +942,6 @@ vim_main2(void) may_req_bg_color(); # endif - // Same reason for termresponse, don't want the terminal sending out the - // DECRPM response after Vim has exited. - send_decrqm_modes(); // start in insert mode if (p_im) @@ -1101,7 +1098,7 @@ common_init_2(mparm_T *paramp) #endif #ifdef FEAT_GUI - gui.dofork = TRUE; // default is to use fork() + gui.dofork = true; // default is to use fork() #endif /* @@ -1925,6 +1922,9 @@ getout(int exitval) #ifdef FEAT_ODB_EDITOR odb_end(); #endif +#ifdef FEAT_SOCKETSERVER + socketserver_stop(); +#endif #ifdef FEAT_CSCOPE cs_end(); #endif @@ -1988,10 +1988,10 @@ early_arg_scan(mparm_T *parmp UNUSED) # ifdef FEAT_GUI if (strstr(argv[i], "-wait") != 0) // don't fork() when starting the GUI to edit files ourself - gui.dofork = FALSE; + gui.dofork = false; # endif } -# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER) +# ifdef FEAT_CLIENTSERVER_BACKENDS else if (STRNICMP(argv[i], "--clientserver", 14) == 0) { char_u *arg; @@ -2001,8 +2001,14 @@ early_arg_scan(mparm_T *parmp UNUSED) if (STRICMP(arg, "socket") == 0) clientserver_method = CLIENTSERVER_METHOD_SOCKET; +# ifdef FEAT_X11 else if (STRICMP(arg, "x11") == 0) clientserver_method = CLIENTSERVER_METHOD_X11; +# endif +# ifdef MSWIN + else if (STRICMP(arg, "mswin") == 0) + clientserver_method = CLIENTSERVER_METHOD_MSWIN; +# endif else mainerr(ME_UNKNOWN_OPTION, arg); } @@ -2105,7 +2111,7 @@ parse_command_name(mparm_T *parmp) || TOLOWER_ASC(initstr[1]) == 'g')) { # ifdef FEAT_GUI - gui.starting = TRUE; + gui.starting = true; # endif parmp->evim_mode = TRUE; ++initstr; @@ -2119,12 +2125,12 @@ parse_command_name(mparm_T *parmp) ++initstr; # endif # ifdef GUI_MAY_SPAWN - gui.dospawn = FALSE; // No need to spawn a new process. + gui.dospawn = false; // No need to spawn a new process. # endif } # ifdef GUI_MAY_SPAWN else - gui.dospawn = TRUE; // Not "gvim". Need to spawn gvim.exe. + gui.dospawn = true; // Not "gvim". Need to spawn gvim.exe. # endif @@ -2267,7 +2273,7 @@ command_line_scan(mparm_T *parmp) cmdline_width = Columns = 80; // need to init Columns info_message = TRUE; // use mch_msg(), not mch_errmsg() # if defined(FEAT_GUI) && !defined(ALWAYS_USE_GUI) && !defined(VIMDLL) - gui.starting = FALSE; // not starting GUI, will exit + gui.starting = false; // not starting GUI, will exit # endif list_version(); msg_putchar('\n'); @@ -2293,7 +2299,7 @@ command_line_scan(mparm_T *parmp) else if (STRNICMP(argv[0] + argv_idx, "nofork", 6) == 0) { # ifdef FEAT_GUI - gui.dofork = FALSE; // don't fork() when starting GUI + gui.dofork = false; // don't fork() when starting GUI # endif } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) @@ -2328,9 +2334,9 @@ command_line_scan(mparm_T *parmp) ; // already processed -- no arg else if (STRNICMP(argv[0] + argv_idx, "servername", 10) == 0 || STRNICMP(argv[0] + argv_idx, "serversend", 10) == 0 -# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER) + // Don't put this under FEAT_CLIENTSERVER_BACKENDS, just + // let it be ignored. Makes tests less complicated || STRNICMP(argv[0] + argv_idx, "clientserver", 12) == 0 -# endif ) { // already processed -- snatch the following arg @@ -2411,7 +2417,7 @@ command_line_scan(mparm_T *parmp) case 'f': // "-f" GUI: run in foreground. Amiga: open // window directly, not with newcli # ifdef FEAT_GUI - gui.dofork = FALSE; // don't fork() when starting GUI + gui.dofork = false; // don't fork() when starting GUI # endif break; @@ -2428,7 +2434,7 @@ command_line_scan(mparm_T *parmp) case 'h': // "-h" give help message # ifdef FEAT_GUI_GNOME // Tell usage() to exit for "gvim". - gui.starting = FALSE; + gui.starting = false; # endif usage(); break; @@ -2458,7 +2464,7 @@ command_line_scan(mparm_T *parmp) case 'y': // "-y" easy mode # ifdef FEAT_GUI - gui.starting = TRUE; // start GUI a bit later + gui.starting = true; // start GUI a bit later # endif parmp->evim_mode = TRUE; break; @@ -2588,7 +2594,7 @@ command_line_scan(mparm_T *parmp) case 'v': // "-v" Vi-mode (as if called "vi") exmode_active = 0; # if defined(FEAT_GUI) && !defined(VIMDLL) - gui.starting = FALSE; // don't start GUI + gui.starting = false; // don't start GUI # endif break; @@ -2778,7 +2784,7 @@ scripterror: */ # ifdef FEAT_GUI if (term_is_gui((char_u *)argv[0])) - gui.starting = TRUE; // start GUI a bit later + gui.starting = true; // start GUI a bit later else # endif parmp->term = (char_u *)argv[0]; @@ -3592,7 +3598,7 @@ source_startup_scripts(mparm_T *parmp) main_start_gui(void) { # ifdef FEAT_GUI - gui.starting = TRUE; // start GUI a bit later + gui.starting = true; // start GUI a bit later # else mch_errmsg(_(e_gui_cannot_be_used_not_enabled_at_compile_time)); mch_errmsg("\n"); @@ -3679,7 +3685,7 @@ mainerr( gui.in_use = mch_is_gui_executable(); #endif #ifdef FEAT_GUI_MSWIN - gui.starting = FALSE; // Needed to show as error. + gui.starting = false; // Needed to show as error. #endif init_longVersion(); @@ -3834,8 +3840,8 @@ usage(void) main_msg(_("-Y\t\t\tDo not connect to Wayland compositor")); # endif # ifdef FEAT_CLIENTSERVER -# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER) - main_msg(_("--clientserver Backend for clientserver communication")); +# ifdef FEAT_CLIENTSERVER_BACKENDS + main_msg(_("--clientserver Backend for clientserver communication")); # endif main_msg(_("--remote \tEdit in a Vim server if possible")); main_msg(_("--remote-silent Same, don't complain if there is no server")); @@ -3906,7 +3912,7 @@ usage(void) if (gui.starting) { mch_msg("\n"); - gui.dofork = FALSE; + gui.dofork = false; } else # endif diff --git a/src/map.c b/src/map.c index 98dfe6df93..0d9a7f88c6 100644 --- a/src/map.c +++ b/src/map.c @@ -277,6 +277,8 @@ map_add( else { mp->m_script_ctx = current_sctx; + if (cmdmod.cmod_flags & CMOD_LEGACY) + mp->m_script_ctx.sc_version = 1; mp->m_script_ctx.sc_lnum += SOURCING_LNUM; } #endif @@ -871,6 +873,8 @@ do_map( #ifdef FEAT_EVAL mp->m_expr = expr; mp->m_script_ctx = current_sctx; + if (cmdmod.cmod_flags & CMOD_LEGACY) + mp->m_script_ctx.sc_version = 1; mp->m_script_ctx.sc_lnum += SOURCING_LNUM; #endif mp_result[keyround - 1] = mp; @@ -1822,11 +1826,10 @@ eval_map_expr( save_cursor = curwin->w_cursor; save_msg_col = msg_col; save_msg_row = msg_row; + + current_sctx.sc_version = mp->m_script_ctx.sc_version; if (mp->m_script_ctx.sc_version == SCRIPT_VERSION_VIM9) - { current_sctx.sc_sid = mp->m_script_ctx.sc_sid; - current_sctx.sc_version = SCRIPT_VERSION_VIM9; - } // Note: the evaluation may make "mp" invalid. p = eval_to_string(expr, FALSE, FALSE); @@ -2084,13 +2087,19 @@ makemap( did_cpo = TRUE; if (did_cpo) { - if (fprintf(fd, "let s:cpo_save=&cpo") < 0 + if (fprintf(fd, "cpo_save = &cpo") < 0 || put_eol(fd) < 0 || fprintf(fd, "set cpo&vim") < 0 || put_eol(fd) < 0) return FAIL; } } +#ifdef FEAT_EVAL + // If it is not vim9 use legacy + if (mp->m_expr && mp->m_script_ctx.sc_version < SCRIPT_VERSION_VIM9 + && fputs("legacy ", fd) < 0) + return FAIL; +#endif if (c1 && putc(c1, fd) < 0) return FAIL; if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0) @@ -2125,9 +2134,7 @@ makemap( } if (did_cpo) - if (fprintf(fd, "let &cpo=s:cpo_save") < 0 - || put_eol(fd) < 0 - || fprintf(fd, "unlet s:cpo_save") < 0 + if (fprintf(fd, "&cpo = cpo_save") < 0 || put_eol(fd) < 0) return FAIL; return OK; diff --git a/src/mark.c b/src/mark.c index 7cd4f31bcb..eb77d8af9f 100644 --- a/src/mark.c +++ b/src/mark.c @@ -1454,7 +1454,7 @@ get_namedfm(void) * Add information about mark 'mname' to list 'l' */ static int -add_mark(list_T *l, char_u *mname, pos_T *pos, int bufnr, char_u *fname) +add_mark(list_T *l, char_u *mname, size_t mnamelen, pos_T *pos, int bufnr, char_u *fname) { dict_T *d; list_T *lpos; @@ -1481,7 +1481,7 @@ add_mark(list_T *l, char_u *mname, pos_T *pos, int bufnr, char_u *fname) list_append_number(lpos, pos->col < MAXCOL ? pos->col + 1 : MAXCOL); list_append_number(lpos, pos->coladd); - if (dict_add_string(d, "mark", mname) == FAIL + if (dict_add_string_len(d, "mark", mname, (int)mnamelen) == FAIL || dict_add_list(d, "pos", lpos) == FAIL || (fname != NULL && dict_add_string(d, "file", fname) == FAIL)) { @@ -1500,25 +1500,26 @@ add_mark(list_T *l, char_u *mname, pos_T *pos, int bufnr, char_u *fname) get_buf_local_marks(buf_T *buf, list_T *l) { char_u mname[3] = "' "; + size_t mnamelen = STRLEN_LITERAL("' "); int i; // Marks 'a' to 'z' for (i = 0; i < NMARKS; ++i) { mname[1] = 'a' + i; - add_mark(l, mname, &buf->b_namedm[i], buf->b_fnum, NULL); + add_mark(l, mname, mnamelen, &buf->b_namedm[i], buf->b_fnum, NULL); } // Mark '' is a window local mark and not a buffer local mark - add_mark(l, (char_u *)"''", &curwin->w_pcmark, curbuf->b_fnum, NULL); + add_mark(l, (char_u *)"''", STRLEN_LITERAL("''"), &curwin->w_pcmark, curbuf->b_fnum, NULL); - add_mark(l, (char_u *)"'\"", &buf->b_last_cursor, buf->b_fnum, NULL); - add_mark(l, (char_u *)"'[", &buf->b_op_start, buf->b_fnum, NULL); - add_mark(l, (char_u *)"']", &buf->b_op_end, buf->b_fnum, NULL); - add_mark(l, (char_u *)"'^", &buf->b_last_insert, buf->b_fnum, NULL); - add_mark(l, (char_u *)"'.", &buf->b_last_change, buf->b_fnum, NULL); - add_mark(l, (char_u *)"'<", &buf->b_visual.vi_start, buf->b_fnum, NULL); - add_mark(l, (char_u *)"'>", &buf->b_visual.vi_end, buf->b_fnum, NULL); + add_mark(l, (char_u *)"'\"", STRLEN_LITERAL("'\""), &buf->b_last_cursor, buf->b_fnum, NULL); + add_mark(l, (char_u *)"'[", STRLEN_LITERAL("'["), &buf->b_op_start, buf->b_fnum, NULL); + add_mark(l, (char_u *)"']", STRLEN_LITERAL("']"), &buf->b_op_end, buf->b_fnum, NULL); + add_mark(l, (char_u *)"'^", STRLEN_LITERAL("'^"), &buf->b_last_insert, buf->b_fnum, NULL); + add_mark(l, (char_u *)"'.", STRLEN_LITERAL("'."), &buf->b_last_change, buf->b_fnum, NULL); + add_mark(l, (char_u *)"'<", STRLEN_LITERAL("'<"), &buf->b_visual.vi_start, buf->b_fnum, NULL); + add_mark(l, (char_u *)"'>", STRLEN_LITERAL("'>"), &buf->b_visual.vi_end, buf->b_fnum, NULL); } /* @@ -1528,6 +1529,7 @@ get_buf_local_marks(buf_T *buf, list_T *l) get_global_marks(list_T *l) { char_u mname[3] = "' "; + size_t mnamelen = STRLEN_LITERAL("' "); int i; char_u *name; @@ -1541,7 +1543,7 @@ get_global_marks(list_T *l) if (name != NULL) { mname[1] = i >= NMARKS ? i - NMARKS + '0' : i + 'A'; - add_mark(l, mname, &namedfm[i].fmark.mark, + add_mark(l, mname, mnamelen, &namedfm[i].fmark.mark, namedfm[i].fmark.fnum, name); if (namedfm[i].fmark.fnum != 0) vim_free(name); diff --git a/src/match.c b/src/match.c index 912abfd74b..709ac30495 100644 --- a/src/match.c +++ b/src/match.c @@ -1048,10 +1048,12 @@ f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) # if defined(FEAT_CONCEAL) if (cur->mit_conceal_char) { - char_u buf[MB_MAXBYTES + 1]; + char_u buf[MB_MAXBYTES + 1]; + int buflen; - buf[(*mb_char2bytes)(cur->mit_conceal_char, buf)] = NUL; - dict_add_string(dict, "conceal", (char_u *)&buf); + buflen = (*mb_char2bytes)(cur->mit_conceal_char, buf); + buf[buflen] = NUL; + dict_add_string_len(dict, "conceal", (char_u *)&buf, buflen); } # endif list_append_dict(rettv->vval.v_list, dict); diff --git a/src/memline.c b/src/memline.c index c15946a6eb..51b09cc1ca 100644 --- a/src/memline.c +++ b/src/memline.c @@ -305,9 +305,9 @@ ml_open(buf_T *buf) * When 'updatecount' is non-zero swap file may be opened later. */ if (p_uc && buf->b_p_swf) - buf->b_may_swap = TRUE; + buf->b_may_swap = true; else - buf->b_may_swap = FALSE; + buf->b_may_swap = false; /* * Open the memfile. No swap file is created yet. @@ -793,7 +793,7 @@ ml_open_file(buf_T *buf) fname = vim_tempname('s', FALSE); if (fname != NULL) (void)mf_open_file(mfp, fname); // consumes fname! - buf->b_may_swap = FALSE; + buf->b_may_swap = false; return; } #endif @@ -851,7 +851,7 @@ ml_open_file(buf_T *buf) } // don't try to open a swap file again - buf->b_may_swap = FALSE; + buf->b_may_swap = false; } /* @@ -1021,7 +1021,7 @@ set_b0_fname(ZERO_BL *b0p, buf_T *buf) forward_slash(b0p->b0_fname); # endif #else - size_t flen, ulen; + size_t flen; char_u uname[B0_UNAME_SIZE]; /* @@ -1031,11 +1031,12 @@ set_b0_fname(ZERO_BL *b0p, buf_T *buf) * First replace home dir path with "~/" with home_replace(). * Then insert the user name to get "~user/". */ - home_replace(NULL, buf->b_ffname, b0p->b0_fname, + flen = home_replace(NULL, buf->b_ffname, b0p->b0_fname, B0_FNAME_SIZE_CRYPT, TRUE); if (b0p->b0_fname[0] == '~') { - flen = STRLEN(b0p->b0_fname); + size_t ulen; + // If there is no user name or it is too long, don't use "~/" if (get_user_name(uname, B0_UNAME_SIZE) == FAIL || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1) @@ -1690,6 +1691,15 @@ ml_recover(int checkext) dp->db_txt_end = page_count * mfp->mf_page_size; } + if (dp->db_txt_start < HEADER_SIZE + || dp->db_txt_start > dp->db_txt_end) + { + ml_append(lnum++, (char_u *)_("??? block header corrupted"), + (colnr_T)0, TRUE); + ++error; + has_error = TRUE; + dp->db_txt_start = dp->db_txt_end; + } // Make sure there is a NUL at the end of the block so we // don't go over the end when copying text. *((char_u *)dp + dp->db_txt_end - 1) = NUL; @@ -2225,9 +2235,11 @@ get_b0_dict(char_u *fname, dict_T *d) if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) { if (ml_check_b0_id(&b0) == FAIL) - dict_add_string(d, "error", (char_u *)"Not a swap file"); + dict_add_string_len(d, "error", + (char_u *)"Not a swap file", STRLEN_LITERAL("Not a swap file")); else if (b0_magic_wrong(&b0)) - dict_add_string(d, "error", (char_u *)"Magic number mismatch"); + dict_add_string_len(d, "error", + (char_u *)"Magic number mismatch", STRLEN_LITERAL("Magic number mismatch")); else { // we have swap information @@ -2245,11 +2257,11 @@ get_b0_dict(char_u *fname, dict_T *d) } } else - dict_add_string(d, "error", (char_u *)"Cannot read file"); + dict_add_string_len(d, "error", (char_u *)"Cannot read file", STRLEN_LITERAL("Cannot read file")); close(fd); } else - dict_add_string(d, "error", (char_u *)"Cannot open file"); + dict_add_string_len(d, "error", (char_u *)"Cannot open file", STRLEN_LITERAL("Cannot open file")); } #endif @@ -2442,9 +2454,9 @@ recov_file_names(char_u **names, char_u *path, int prepend_dot) char_u *p; int i; #ifndef MSWIN - int shortname = curbuf->b_shortname; + bool shortname = curbuf->b_shortname; - curbuf->b_shortname = FALSE; + curbuf->b_shortname = false; #endif string_T ret; @@ -2493,7 +2505,7 @@ recov_file_names(char_u **names, char_u *path, int prepend_dot) /* * Also try with 'shortname' set, in case the file is on a DOS filesystem. */ - curbuf->b_shortname = TRUE; + curbuf->b_shortname = true; # ifdef VMS names[num_names] = modname(path, (char_u *)"_sw%", FALSE); # else @@ -5108,7 +5120,7 @@ findswapname( vim_free(fname2); if (same) { - buf->b_shortname = TRUE; + buf->b_shortname = true; vim_free(fname); fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); @@ -5178,7 +5190,7 @@ findswapname( fname[n - 1] = 'p'; if (r >= 0) // "file.swx" seems to exist { - buf->b_shortname = TRUE; + buf->b_shortname = true; vim_free(fname); fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); @@ -5332,24 +5344,32 @@ findswapname( if (swap_exists_action != SEA_NONE && choice == SEA_CHOICE_NONE) { - char_u *name; - int dialog_result; - size_t len = STRLEN(_("Swap file \"")); + string_T prefix = {(char_u *)_("Swap file \""), 0}; + string_T suffix = {(char_u *)_("\" already exists!"), 0}; + size_t message_size; + string_T message; + char_u *tofree; + int dialog_result; - name = alloc(STRLEN(fname) - + len - + STRLEN(_("\" already exists!")) + 5); - if (name != NULL) + prefix.length = STRLEN(prefix.string); + suffix.length = STRLEN(suffix.string); + message_size = prefix.length + + STRLEN(fname) + + suffix.length + 5; + message.string = tofree = alloc(message_size); + if (message.string != NULL) { - STRCPY(name, _("Swap file \"")); - home_replace(NULL, fname, name + len, 1000, TRUE); - STRCAT(name, _("\" already exists!")); + STRCPY(message.string, prefix.string); + message.length = prefix.length; + message.length += home_replace(NULL, fname, + message.string + message.length, (int)(message_size - message.length), TRUE); + STRCPY(message.string + message.length, suffix.string); } + else + message.string = (char_u *)_("Swap file already exists!"); dialog_result = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"), - name == NULL - ? (char_u *)_("Swap file already exists!") - : name, + message.string, # ifdef HAVE_PROCESS_STILL_RUNNING process_still_running ? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") : @@ -5362,7 +5382,7 @@ findswapname( dialog_result++; # endif choice = dialog_result; - vim_free(name); + vim_free(tofree); // pretend screen didn't scroll, need redraw anyway msg_scrolled = 0; @@ -6234,7 +6254,7 @@ goto_byte(long cnt) curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = (colnr_T)boff; curwin->w_cursor.coladd = 0; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } check_cursor(); diff --git a/src/menu.c b/src/menu.c index 4be7847788..0a5482cf26 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1075,6 +1075,10 @@ free_menu(vimmenu_T **menup) // Also may rebuild a tearoff'ed menu if (gui.in_use) gui_mch_destroy_menu(menu); +# ifdef USE_GTK4 + // GTK4 uses "menu->label" for action name + vim_free((char_u *)menu->label); +# endif #endif // Don't change *menup until after calling gui_mch_destroy_menu(). The @@ -3275,15 +3279,17 @@ menuitem_getinfo(char_u *menu_name, vimmenu_T *menu, int modes, dict_T *dict) if (status == OK) { char_u buf[NUMBUFLEN]; + int buflen; if (has_mbyte) - buf[utf_char2bytes(menu->mnemonic, buf)] = NUL; + buflen = utf_char2bytes(menu->mnemonic, buf); else { buf[0] = (char_u)menu->mnemonic; - buf[1] = NUL; + buflen = (buf[0] == NUL) ? 0 : 1; } - status = dict_add_string(dict, "shortcut", buf); + buf[buflen] = NUL; + status = dict_add_string_len(dict, "shortcut", buf, buflen); } if (status == OK && menu->children == NULL) { @@ -3296,14 +3302,17 @@ menuitem_getinfo(char_u *menu_name, vimmenu_T *menu, int modes, dict_T *dict) { if (menu->strings[bit] != NULL) { - char_u *tofree = NULL; + if (*menu->strings[bit] == NUL) + status = dict_add_string_len(dict, "rhs", + (char_u *)"", STRLEN_LITERAL("")); + else + { + char_u *tofree = NULL; - status = dict_add_string(dict, "rhs", - *menu->strings[bit] == NUL - ? (char_u *)"" - : (tofree = str2special_save( - menu->strings[bit], FALSE, FALSE))); - vim_free(tofree); + status = dict_add_string(dict, "rhs", + tofree = str2special_save(menu->strings[bit], FALSE, FALSE)); + vim_free(tofree); + } } if (status == OK) status = dict_add_bool(dict, "noremenu", diff --git a/src/misc1.c b/src/misc1.c index bbc60f23c0..ce4db318d4 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -621,7 +621,7 @@ check_status(buf_T *buf) FOR_ALL_WINDOWS(wp) if (wp->w_buffer == buf && wp->w_status_height) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; set_must_redraw(UPD_VALID); } } @@ -1405,7 +1405,7 @@ init_vimdir(void) char_u * expand_env_save(char_u *src) { - return expand_env_save_opt(src, FALSE); + return expand_env_save_opt(src, FALSE, NULL); } /* @@ -1413,13 +1413,13 @@ expand_env_save(char_u *src) * expand "~" at the start. */ char_u * -expand_env_save_opt(char_u *src, int one) +expand_env_save_opt(char_u *src, int one, char_u *esc_chars) { char_u *p; p = alloc(MAXPATHL); if (p != NULL) - expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL); + expand_env_esc(src, p, MAXPATHL, esc_chars, one, NULL); return p; } @@ -1435,7 +1435,7 @@ expand_env( char_u *dst, // where to put the result int dstlen) // maximum length of the result { - return expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL); + return expand_env_esc(src, dst, dstlen, NULL, FALSE, NULL); } size_t @@ -1443,7 +1443,7 @@ expand_env_esc( char_u *srcp, // input string e.g. "$HOME/vim.hlp" char_u *dst, // where to put the result int dstlen, // maximum length of the result - int esc, // escape spaces in expanded variables + char_u *esc_chars, // chars to escape in expanded vars int one, // "srcp" is one file name char_u *startstr) // start again after this (can be NULL) { @@ -1662,11 +1662,13 @@ expand_env_esc( } #endif - // If "var" contains white space, escape it with a backslash. - // Required for ":e ~/tt" when $HOME includes a space. - if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL) + // If "var" contains any character from "esc_chars", escape it + // with a backslash. The historical use is escaping spaces so + // that ":e ~/tt" works when $HOME contains a space. + if (esc_chars != NULL && var != NULL + && vim_strpbrk(var, esc_chars) != NULL) { - char_u *p = vim_strsave_escaped(var, (char_u *)" \t"); + char_u *p = vim_strsave_escaped(var, esc_chars); if (p != NULL) { @@ -2291,7 +2293,7 @@ prepare_to_exit(void) #ifdef FEAT_GUI if (gui.in_use) { - gui.dying = TRUE; + gui.dying = true; out_trash(); // trash any pending output } else diff --git a/src/misc2.c b/src/misc2.c index 0a55fbf7a4..68dd351be4 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -24,15 +24,16 @@ virtual_active(void) { unsigned int cur_ve_flags = get_ve_flags(); + if (cur_ve_flags == VE_ALL + || ((cur_ve_flags & VE_INSERT) && (State & MODE_INSERT))) + return TRUE; + // While an operator is being executed we return "virtual_op", because // VIsual_active has already been reset, thus we can't check for "block" // being used. if (virtual_op != MAYBE) return virtual_op; - return (cur_ve_flags == VE_ALL - || ((cur_ve_flags & VE_BLOCK) && VIsual_active - && VIsual_mode == Ctrl_V) - || ((cur_ve_flags & VE_INSERT) && (State & MODE_INSERT))); + return (cur_ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V; } /* @@ -719,7 +720,7 @@ set_leftcol(colnr_T leftcol) } if (retval) - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; redraw_later(UPD_NOT_VALID); return retval; } @@ -915,8 +916,6 @@ static char_u modifier_keys_table[] = NUL }; -#define STRING_INIT(s) \ - {(char_u *)(s), STRLEN_LITERAL(s)} static struct key_name_entry { int enabled; // is this entry available (TRUE/FALSE)? @@ -926,209 +925,208 @@ static struct key_name_entry } key_names_table[] = // Must be sorted by the 'name.string' field in ascending order because it is used by bsearch()! { - {TRUE, K_BS, STRING_INIT("BackSpace"), TRUE}, - {TRUE, '|', STRING_INIT("Bar"), FALSE}, - {TRUE, K_BS, STRING_INIT("BS"), FALSE}, - {TRUE, '\\', STRING_INIT("Bslash"), FALSE}, - {TRUE, K_COMMAND, STRING_INIT("Cmd"), FALSE}, - {TRUE, CAR, STRING_INIT("CR"), FALSE}, - {TRUE, CSI, STRING_INIT("CSI"), FALSE}, - {TRUE, K_CURSORHOLD, STRING_INIT("CursorHold"), FALSE}, + {TRUE, K_BS, STR_LITERAL_INIT("BackSpace"), TRUE}, + {TRUE, '|', STR_LITERAL_INIT("Bar"), FALSE}, + {TRUE, K_BS, STR_LITERAL_INIT("BS"), FALSE}, + {TRUE, '\\', STR_LITERAL_INIT("Bslash"), FALSE}, + {TRUE, K_COMMAND, STR_LITERAL_INIT("Cmd"), FALSE}, + {TRUE, CAR, STR_LITERAL_INIT("CR"), FALSE}, + {TRUE, CSI, STR_LITERAL_INIT("CSI"), FALSE}, + {TRUE, K_CURSORHOLD, STR_LITERAL_INIT("CursorHold"), FALSE}, { #ifdef FEAT_MOUSE_DEC TRUE, #else FALSE, #endif - K_DEC_MOUSE, STRING_INIT("DecMouse"), FALSE}, - {TRUE, K_DEL, STRING_INIT("Del"), FALSE}, - {TRUE, K_DEL, STRING_INIT("Delete"), TRUE}, - {TRUE, K_DOWN, STRING_INIT("Down"), FALSE}, - {TRUE, K_DROP, STRING_INIT("Drop"), FALSE}, - {TRUE, K_END, STRING_INIT("End"), FALSE}, - {TRUE, CAR, STRING_INIT("Enter"), TRUE}, - {TRUE, ESC, STRING_INIT("Esc"), FALSE}, + K_DEC_MOUSE, STR_LITERAL_INIT("DecMouse"), FALSE}, + {TRUE, K_DEL, STR_LITERAL_INIT("Del"), FALSE}, + {TRUE, K_DEL, STR_LITERAL_INIT("Delete"), TRUE}, + {TRUE, K_DOWN, STR_LITERAL_INIT("Down"), FALSE}, + {TRUE, K_DROP, STR_LITERAL_INIT("Drop"), FALSE}, + {TRUE, K_END, STR_LITERAL_INIT("End"), FALSE}, + {TRUE, CAR, STR_LITERAL_INIT("Enter"), TRUE}, + {TRUE, ESC, STR_LITERAL_INIT("Esc"), FALSE}, - {TRUE, K_F1, STRING_INIT("F1"), FALSE}, - {TRUE, K_F10, STRING_INIT("F10"), FALSE}, - {TRUE, K_F11, STRING_INIT("F11"), FALSE}, - {TRUE, K_F12, STRING_INIT("F12"), FALSE}, - {TRUE, K_F13, STRING_INIT("F13"), FALSE}, - {TRUE, K_F14, STRING_INIT("F14"), FALSE}, - {TRUE, K_F15, STRING_INIT("F15"), FALSE}, - {TRUE, K_F16, STRING_INIT("F16"), FALSE}, - {TRUE, K_F17, STRING_INIT("F17"), FALSE}, - {TRUE, K_F18, STRING_INIT("F18"), FALSE}, - {TRUE, K_F19, STRING_INIT("F19"), FALSE}, + {TRUE, K_F1, STR_LITERAL_INIT("F1"), FALSE}, + {TRUE, K_F10, STR_LITERAL_INIT("F10"), FALSE}, + {TRUE, K_F11, STR_LITERAL_INIT("F11"), FALSE}, + {TRUE, K_F12, STR_LITERAL_INIT("F12"), FALSE}, + {TRUE, K_F13, STR_LITERAL_INIT("F13"), FALSE}, + {TRUE, K_F14, STR_LITERAL_INIT("F14"), FALSE}, + {TRUE, K_F15, STR_LITERAL_INIT("F15"), FALSE}, + {TRUE, K_F16, STR_LITERAL_INIT("F16"), FALSE}, + {TRUE, K_F17, STR_LITERAL_INIT("F17"), FALSE}, + {TRUE, K_F18, STR_LITERAL_INIT("F18"), FALSE}, + {TRUE, K_F19, STR_LITERAL_INIT("F19"), FALSE}, - {TRUE, K_F2, STRING_INIT("F2"), FALSE}, - {TRUE, K_F20, STRING_INIT("F20"), FALSE}, - {TRUE, K_F21, STRING_INIT("F21"), FALSE}, - {TRUE, K_F22, STRING_INIT("F22"), FALSE}, - {TRUE, K_F23, STRING_INIT("F23"), FALSE}, - {TRUE, K_F24, STRING_INIT("F24"), FALSE}, - {TRUE, K_F25, STRING_INIT("F25"), FALSE}, - {TRUE, K_F26, STRING_INIT("F26"), FALSE}, - {TRUE, K_F27, STRING_INIT("F27"), FALSE}, - {TRUE, K_F28, STRING_INIT("F28"), FALSE}, - {TRUE, K_F29, STRING_INIT("F29"), FALSE}, + {TRUE, K_F2, STR_LITERAL_INIT("F2"), FALSE}, + {TRUE, K_F20, STR_LITERAL_INIT("F20"), FALSE}, + {TRUE, K_F21, STR_LITERAL_INIT("F21"), FALSE}, + {TRUE, K_F22, STR_LITERAL_INIT("F22"), FALSE}, + {TRUE, K_F23, STR_LITERAL_INIT("F23"), FALSE}, + {TRUE, K_F24, STR_LITERAL_INIT("F24"), FALSE}, + {TRUE, K_F25, STR_LITERAL_INIT("F25"), FALSE}, + {TRUE, K_F26, STR_LITERAL_INIT("F26"), FALSE}, + {TRUE, K_F27, STR_LITERAL_INIT("F27"), FALSE}, + {TRUE, K_F28, STR_LITERAL_INIT("F28"), FALSE}, + {TRUE, K_F29, STR_LITERAL_INIT("F29"), FALSE}, - {TRUE, K_F3, STRING_INIT("F3"), FALSE}, - {TRUE, K_F30, STRING_INIT("F30"), FALSE}, - {TRUE, K_F31, STRING_INIT("F31"), FALSE}, - {TRUE, K_F32, STRING_INIT("F32"), FALSE}, - {TRUE, K_F33, STRING_INIT("F33"), FALSE}, - {TRUE, K_F34, STRING_INIT("F34"), FALSE}, - {TRUE, K_F35, STRING_INIT("F35"), FALSE}, - {TRUE, K_F36, STRING_INIT("F36"), FALSE}, - {TRUE, K_F37, STRING_INIT("F37"), FALSE}, + {TRUE, K_F3, STR_LITERAL_INIT("F3"), FALSE}, + {TRUE, K_F30, STR_LITERAL_INIT("F30"), FALSE}, + {TRUE, K_F31, STR_LITERAL_INIT("F31"), FALSE}, + {TRUE, K_F32, STR_LITERAL_INIT("F32"), FALSE}, + {TRUE, K_F33, STR_LITERAL_INIT("F33"), FALSE}, + {TRUE, K_F34, STR_LITERAL_INIT("F34"), FALSE}, + {TRUE, K_F35, STR_LITERAL_INIT("F35"), FALSE}, + {TRUE, K_F36, STR_LITERAL_INIT("F36"), FALSE}, + {TRUE, K_F37, STR_LITERAL_INIT("F37"), FALSE}, - {TRUE, K_F4, STRING_INIT("F4"), FALSE}, - {TRUE, K_F5, STRING_INIT("F5"), FALSE}, - {TRUE, K_F6, STRING_INIT("F6"), FALSE}, - {TRUE, K_F7, STRING_INIT("F7"), FALSE}, - {TRUE, K_F8, STRING_INIT("F8"), FALSE}, - {TRUE, K_F9, STRING_INIT("F9"), FALSE}, + {TRUE, K_F4, STR_LITERAL_INIT("F4"), FALSE}, + {TRUE, K_F5, STR_LITERAL_INIT("F5"), FALSE}, + {TRUE, K_F6, STR_LITERAL_INIT("F6"), FALSE}, + {TRUE, K_F7, STR_LITERAL_INIT("F7"), FALSE}, + {TRUE, K_F8, STR_LITERAL_INIT("F8"), FALSE}, + {TRUE, K_F9, STR_LITERAL_INIT("F9"), FALSE}, - {TRUE, K_FOCUSGAINED, STRING_INIT("FocusGained"), FALSE}, - {TRUE, K_FOCUSLOST, STRING_INIT("FocusLost"), FALSE}, + {TRUE, K_FOCUSGAINED, STR_LITERAL_INIT("FocusGained"), FALSE}, + {TRUE, K_FOCUSLOST, STR_LITERAL_INIT("FocusLost"), FALSE}, #ifdef FEAT_GUI_MACVIM - {TRUE, K_FORCECLICK, STRING_INIT("ForceClick"), FALSE}, + {TRUE, K_FORCECLICK, STR_LITERAL_INIT("ForceClick"), FALSE}, #endif - {TRUE, K_HELP, STRING_INIT("Help"), FALSE}, - {TRUE, K_HOME, STRING_INIT("Home"), FALSE}, - {TRUE, K_IGNORE, STRING_INIT("Ignore"), FALSE}, - {TRUE, K_INS, STRING_INIT("Ins"), TRUE}, - {TRUE, K_INS, STRING_INIT("Insert"), FALSE}, + {TRUE, K_HELP, STR_LITERAL_INIT("Help"), FALSE}, + {TRUE, K_HOME, STR_LITERAL_INIT("Home"), FALSE}, + {TRUE, K_IGNORE, STR_LITERAL_INIT("Ignore"), FALSE}, + {TRUE, K_INS, STR_LITERAL_INIT("Ins"), TRUE}, + {TRUE, K_INS, STR_LITERAL_INIT("Insert"), FALSE}, { #ifdef FEAT_MOUSE_JSB TRUE, #else FALSE, #endif - K_JSBTERM_MOUSE, STRING_INIT("JsbMouse"), FALSE}, - {TRUE, K_K0, STRING_INIT("k0"), FALSE}, - {TRUE, K_K1, STRING_INIT("k1"), FALSE}, - {TRUE, K_K2, STRING_INIT("k2"), FALSE}, - {TRUE, K_K3, STRING_INIT("k3"), FALSE}, - {TRUE, K_K4, STRING_INIT("k4"), FALSE}, - {TRUE, K_K5, STRING_INIT("k5"), FALSE}, - {TRUE, K_K6, STRING_INIT("k6"), FALSE}, - {TRUE, K_K7, STRING_INIT("k7"), FALSE}, - {TRUE, K_K8, STRING_INIT("k8"), FALSE}, - {TRUE, K_K9, STRING_INIT("k9"), FALSE}, + K_JSBTERM_MOUSE, STR_LITERAL_INIT("JsbMouse"), FALSE}, + {TRUE, K_K0, STR_LITERAL_INIT("k0"), FALSE}, + {TRUE, K_K1, STR_LITERAL_INIT("k1"), FALSE}, + {TRUE, K_K2, STR_LITERAL_INIT("k2"), FALSE}, + {TRUE, K_K3, STR_LITERAL_INIT("k3"), FALSE}, + {TRUE, K_K4, STR_LITERAL_INIT("k4"), FALSE}, + {TRUE, K_K5, STR_LITERAL_INIT("k5"), FALSE}, + {TRUE, K_K6, STR_LITERAL_INIT("k6"), FALSE}, + {TRUE, K_K7, STR_LITERAL_INIT("k7"), FALSE}, + {TRUE, K_K8, STR_LITERAL_INIT("k8"), FALSE}, + {TRUE, K_K9, STR_LITERAL_INIT("k9"), FALSE}, - {TRUE, K_KDEL, STRING_INIT("kDel"), FALSE}, - {TRUE, K_KDIVIDE, STRING_INIT("kDivide"), FALSE}, - {TRUE, K_KEND, STRING_INIT("kEnd"), FALSE}, - {TRUE, K_KENTER, STRING_INIT("kEnter"), FALSE}, - {TRUE, K_KHOME, STRING_INIT("kHome"), FALSE}, - {TRUE, K_KINS, STRING_INIT("kInsert"), FALSE}, - {TRUE, K_KMINUS, STRING_INIT("kMinus"), FALSE}, - {TRUE, K_KMULTIPLY, STRING_INIT("kMultiply"), FALSE}, - {TRUE, K_KPAGEDOWN, STRING_INIT("kPageDown"), FALSE}, - {TRUE, K_KPAGEUP, STRING_INIT("kPageUp"), FALSE}, - {TRUE, K_KPLUS, STRING_INIT("kPlus"), FALSE}, - {TRUE, K_KPOINT, STRING_INIT("kPoint"), FALSE}, - {TRUE, K_LEFT, STRING_INIT("Left"), FALSE}, - {TRUE, K_LEFTDRAG, STRING_INIT("LeftDrag"), FALSE}, - {TRUE, K_LEFTMOUSE, STRING_INIT("LeftMouse"), FALSE}, - {TRUE, K_LEFTMOUSE_NM, STRING_INIT("LeftMouseNM"), FALSE}, - {TRUE, K_LEFTRELEASE, STRING_INIT("LeftRelease"), FALSE}, - {TRUE, K_LEFTRELEASE_NM, STRING_INIT("LeftReleaseNM"), FALSE}, - {TRUE, NL, STRING_INIT("LF"), TRUE}, - {TRUE, NL, STRING_INIT("LineFeed"), TRUE}, - {TRUE, '<', STRING_INIT("lt"), FALSE}, - {TRUE, K_MIDDLEDRAG, STRING_INIT("MiddleDrag"), FALSE}, - {TRUE, K_MIDDLEMOUSE, STRING_INIT("MiddleMouse"), FALSE}, - {TRUE, K_MIDDLERELEASE, STRING_INIT("MiddleRelease"), FALSE}, - {TRUE, K_MOUSE, STRING_INIT("Mouse"), FALSE}, - {TRUE, K_MOUSEDOWN, STRING_INIT("MouseDown"), TRUE}, - {TRUE, K_MOUSEMOVE, STRING_INIT("MouseMove"), FALSE}, - {TRUE, K_MOUSEUP, STRING_INIT("MouseUp"), TRUE}, + {TRUE, K_KDEL, STR_LITERAL_INIT("kDel"), FALSE}, + {TRUE, K_KDIVIDE, STR_LITERAL_INIT("kDivide"), FALSE}, + {TRUE, K_KEND, STR_LITERAL_INIT("kEnd"), FALSE}, + {TRUE, K_KENTER, STR_LITERAL_INIT("kEnter"), FALSE}, + {TRUE, K_KHOME, STR_LITERAL_INIT("kHome"), FALSE}, + {TRUE, K_KINS, STR_LITERAL_INIT("kInsert"), FALSE}, + {TRUE, K_KMINUS, STR_LITERAL_INIT("kMinus"), FALSE}, + {TRUE, K_KMULTIPLY, STR_LITERAL_INIT("kMultiply"), FALSE}, + {TRUE, K_KPAGEDOWN, STR_LITERAL_INIT("kPageDown"), FALSE}, + {TRUE, K_KPAGEUP, STR_LITERAL_INIT("kPageUp"), FALSE}, + {TRUE, K_KPLUS, STR_LITERAL_INIT("kPlus"), FALSE}, + {TRUE, K_KPOINT, STR_LITERAL_INIT("kPoint"), FALSE}, + {TRUE, K_LEFT, STR_LITERAL_INIT("Left"), FALSE}, + {TRUE, K_LEFTDRAG, STR_LITERAL_INIT("LeftDrag"), FALSE}, + {TRUE, K_LEFTMOUSE, STR_LITERAL_INIT("LeftMouse"), FALSE}, + {TRUE, K_LEFTMOUSE_NM, STR_LITERAL_INIT("LeftMouseNM"), FALSE}, + {TRUE, K_LEFTRELEASE, STR_LITERAL_INIT("LeftRelease"), FALSE}, + {TRUE, K_LEFTRELEASE_NM, STR_LITERAL_INIT("LeftReleaseNM"), FALSE}, + {TRUE, NL, STR_LITERAL_INIT("LF"), TRUE}, + {TRUE, NL, STR_LITERAL_INIT("LineFeed"), TRUE}, + {TRUE, '<', STR_LITERAL_INIT("lt"), FALSE}, + {TRUE, K_MIDDLEDRAG, STR_LITERAL_INIT("MiddleDrag"), FALSE}, + {TRUE, K_MIDDLEMOUSE, STR_LITERAL_INIT("MiddleMouse"), FALSE}, + {TRUE, K_MIDDLERELEASE, STR_LITERAL_INIT("MiddleRelease"), FALSE}, + {TRUE, K_MOUSE, STR_LITERAL_INIT("Mouse"), FALSE}, + {TRUE, K_MOUSEDOWN, STR_LITERAL_INIT("MouseDown"), TRUE}, + {TRUE, K_MOUSEMOVE, STR_LITERAL_INIT("MouseMove"), FALSE}, + {TRUE, K_MOUSEUP, STR_LITERAL_INIT("MouseUp"), TRUE}, { #ifdef FEAT_MOUSE_NET TRUE, #else FALSE, #endif - K_NETTERM_MOUSE, STRING_INIT("NetMouse"), FALSE}, - {TRUE, NL, STRING_INIT("NewLine"), TRUE}, - {TRUE, NL, STRING_INIT("NL"), FALSE}, - {TRUE, K_ZERO, STRING_INIT("Nul"), FALSE}, - {TRUE, OSC, STRING_INIT("OSC"), FALSE}, - {TRUE, K_PAGEDOWN, STRING_INIT("PageDown"), FALSE}, - {TRUE, K_PAGEUP, STRING_INIT("PageUp"), FALSE}, - {TRUE, K_PE, STRING_INIT("PasteEnd"), FALSE}, - {TRUE, K_PS, STRING_INIT("PasteStart"), FALSE}, - {TRUE, K_PLUG, STRING_INIT("Plug"), FALSE}, + K_NETTERM_MOUSE, STR_LITERAL_INIT("NetMouse"), FALSE}, + {TRUE, NL, STR_LITERAL_INIT("NewLine"), TRUE}, + {TRUE, NL, STR_LITERAL_INIT("NL"), FALSE}, + {TRUE, K_ZERO, STR_LITERAL_INIT("Nul"), FALSE}, + {TRUE, OSC, STR_LITERAL_INIT("OSC"), FALSE}, + {TRUE, K_PAGEDOWN, STR_LITERAL_INIT("PageDown"), FALSE}, + {TRUE, K_PAGEUP, STR_LITERAL_INIT("PageUp"), FALSE}, + {TRUE, K_PE, STR_LITERAL_INIT("PasteEnd"), FALSE}, + {TRUE, K_PS, STR_LITERAL_INIT("PasteStart"), FALSE}, + {TRUE, K_PLUG, STR_LITERAL_INIT("Plug"), FALSE}, { #ifdef FEAT_MOUSE_PTERM TRUE, #else FALSE, #endif - K_PTERM_MOUSE, STRING_INIT("PtermMouse"), FALSE}, - {TRUE, CAR, STRING_INIT("Return"), TRUE}, - {TRUE, K_RIGHT, STRING_INIT("Right"), FALSE}, - {TRUE, K_RIGHTDRAG, STRING_INIT("RightDrag"), FALSE}, - {TRUE, K_RIGHTMOUSE, STRING_INIT("RightMouse"), FALSE}, - {TRUE, K_RIGHTRELEASE, STRING_INIT("RightRelease"), FALSE}, - {TRUE, K_SCRIPT_COMMAND, STRING_INIT("ScriptCmd"), FALSE}, - {TRUE, K_MOUSEUP, STRING_INIT("ScrollWheelDown"), FALSE}, - {TRUE, K_MOUSERIGHT, STRING_INIT("ScrollWheelLeft"), FALSE}, - {TRUE, K_MOUSELEFT, STRING_INIT("ScrollWheelRight"), FALSE}, - {TRUE, K_MOUSEDOWN, STRING_INIT("ScrollWheelUp"), FALSE}, - {TRUE, K_SGR_MOUSE, STRING_INIT("SgrMouse"), FALSE}, - {TRUE, K_SGR_MOUSERELEASE, STRING_INIT("SgrMouseRelease"), FALSE}, + K_PTERM_MOUSE, STR_LITERAL_INIT("PtermMouse"), FALSE}, + {TRUE, CAR, STR_LITERAL_INIT("Return"), TRUE}, + {TRUE, K_RIGHT, STR_LITERAL_INIT("Right"), FALSE}, + {TRUE, K_RIGHTDRAG, STR_LITERAL_INIT("RightDrag"), FALSE}, + {TRUE, K_RIGHTMOUSE, STR_LITERAL_INIT("RightMouse"), FALSE}, + {TRUE, K_RIGHTRELEASE, STR_LITERAL_INIT("RightRelease"), FALSE}, + {TRUE, K_SCRIPT_COMMAND, STR_LITERAL_INIT("ScriptCmd"), FALSE}, + {TRUE, K_MOUSEUP, STR_LITERAL_INIT("ScrollWheelDown"), FALSE}, + {TRUE, K_MOUSERIGHT, STR_LITERAL_INIT("ScrollWheelLeft"), FALSE}, + {TRUE, K_MOUSELEFT, STR_LITERAL_INIT("ScrollWheelRight"), FALSE}, + {TRUE, K_MOUSEDOWN, STR_LITERAL_INIT("ScrollWheelUp"), FALSE}, + {TRUE, K_SGR_MOUSE, STR_LITERAL_INIT("SgrMouse"), FALSE}, + {TRUE, K_SGR_MOUSERELEASE, STR_LITERAL_INIT("SgrMouseRelease"), FALSE}, { #ifdef FEAT_EVAL TRUE, #else FALSE, #endif - K_SNR, STRING_INIT("SNR"), FALSE}, - {TRUE, ' ', STRING_INIT("Space"), FALSE}, + K_SNR, STR_LITERAL_INIT("SNR"), FALSE}, + {TRUE, ' ', STR_LITERAL_INIT("Space"), FALSE}, #ifdef FEAT_GUI_MACVIM - {TRUE, K_SWIPEDOWN, STRING_INIT("SwipeDown"), FALSE}, - {TRUE, K_SWIPELEFT, STRING_INIT("SwipeLeft"), FALSE}, - {TRUE, K_SWIPERIGHT, STRING_INIT("SwipeRight"), FALSE}, - {TRUE, K_SWIPEUP, STRING_INIT("SwipeUp"), FALSE}, + {TRUE, K_SWIPEDOWN, STR_LITERAL_INIT("SwipeDown"), FALSE}, + {TRUE, K_SWIPELEFT, STR_LITERAL_INIT("SwipeLeft"), FALSE}, + {TRUE, K_SWIPERIGHT, STR_LITERAL_INIT("SwipeRight"), FALSE}, + {TRUE, K_SWIPEUP, STR_LITERAL_INIT("SwipeUp"), FALSE}, #endif - {TRUE, TAB, STRING_INIT("Tab"), FALSE}, - {TRUE, K_TAB, STRING_INIT("Tab"), FALSE}, - {TRUE, K_UNDO, STRING_INIT("Undo"), FALSE}, - {TRUE, K_UP, STRING_INIT("Up"), FALSE}, + {TRUE, TAB, STR_LITERAL_INIT("Tab"), FALSE}, + {TRUE, K_TAB, STR_LITERAL_INIT("Tab"), FALSE}, + {TRUE, K_UNDO, STR_LITERAL_INIT("Undo"), FALSE}, + {TRUE, K_UP, STR_LITERAL_INIT("Up"), FALSE}, { #ifdef FEAT_MOUSE_URXVT TRUE, #else FALSE, #endif - K_URXVT_MOUSE, STRING_INIT("UrxvtMouse"), FALSE}, - {TRUE, K_X1DRAG, STRING_INIT("X1Drag"), FALSE}, - {TRUE, K_X1MOUSE, STRING_INIT("X1Mouse"), FALSE}, - {TRUE, K_X1RELEASE, STRING_INIT("X1Release"), FALSE}, - {TRUE, K_X2DRAG, STRING_INIT("X2Drag"), FALSE}, - {TRUE, K_X2MOUSE, STRING_INIT("X2Mouse"), FALSE}, - {TRUE, K_X2RELEASE, STRING_INIT("X2Release"), FALSE}, - {TRUE, K_CSI, STRING_INIT("xCSI"), FALSE}, - {TRUE, K_XDOWN, STRING_INIT("xDown"), FALSE}, - {TRUE, K_XEND, STRING_INIT("xEnd"), FALSE}, - {TRUE, K_XF1, STRING_INIT("xF1"), FALSE}, - {TRUE, K_XF2, STRING_INIT("xF2"), FALSE}, - {TRUE, K_XF3, STRING_INIT("xF3"), FALSE}, - {TRUE, K_XF4, STRING_INIT("xF4"), FALSE}, - {TRUE, K_XHOME, STRING_INIT("xHome"), FALSE}, - {TRUE, K_XLEFT, STRING_INIT("xLeft"), FALSE}, - {TRUE, K_OSC, STRING_INIT("xOSC"), FALSE}, - {TRUE, K_XRIGHT, STRING_INIT("xRight"), FALSE}, - {TRUE, K_XUP, STRING_INIT("xUp"), FALSE}, - {TRUE, K_ZEND, STRING_INIT("zEnd"), FALSE}, - {TRUE, K_ZHOME, STRING_INIT("zHome"), FALSE} + K_URXVT_MOUSE, STR_LITERAL_INIT("UrxvtMouse"), FALSE}, + {TRUE, K_X1DRAG, STR_LITERAL_INIT("X1Drag"), FALSE}, + {TRUE, K_X1MOUSE, STR_LITERAL_INIT("X1Mouse"), FALSE}, + {TRUE, K_X1RELEASE, STR_LITERAL_INIT("X1Release"), FALSE}, + {TRUE, K_X2DRAG, STR_LITERAL_INIT("X2Drag"), FALSE}, + {TRUE, K_X2MOUSE, STR_LITERAL_INIT("X2Mouse"), FALSE}, + {TRUE, K_X2RELEASE, STR_LITERAL_INIT("X2Release"), FALSE}, + {TRUE, K_CSI, STR_LITERAL_INIT("xCSI"), FALSE}, + {TRUE, K_XDOWN, STR_LITERAL_INIT("xDown"), FALSE}, + {TRUE, K_XEND, STR_LITERAL_INIT("xEnd"), FALSE}, + {TRUE, K_XF1, STR_LITERAL_INIT("xF1"), FALSE}, + {TRUE, K_XF2, STR_LITERAL_INIT("xF2"), FALSE}, + {TRUE, K_XF3, STR_LITERAL_INIT("xF3"), FALSE}, + {TRUE, K_XF4, STR_LITERAL_INIT("xF4"), FALSE}, + {TRUE, K_XHOME, STR_LITERAL_INIT("xHome"), FALSE}, + {TRUE, K_XLEFT, STR_LITERAL_INIT("xLeft"), FALSE}, + {TRUE, K_OSC, STR_LITERAL_INIT("xOSC"), FALSE}, + {TRUE, K_XRIGHT, STR_LITERAL_INIT("xRight"), FALSE}, + {TRUE, K_XUP, STR_LITERAL_INIT("xUp"), FALSE}, + {TRUE, K_ZEND, STR_LITERAL_INIT("zEnd"), FALSE}, + {TRUE, K_ZHOME, STR_LITERAL_INIT("zHome"), FALSE} // NOTE: When adding a long name update MAX_KEY_NAME_LEN. }; -#undef STRING_INIT /* * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given @@ -2157,29 +2155,26 @@ cursorentry_T shape_table[SHAPE_IDX_COUNT] = * Table with names for mouse shapes. Keep in sync with all the tables for * mch_set_mouse_shape()!. */ -# define STRING_INIT(s) \ - {(char_u *)(s), STRLEN_LITERAL(s)} static string_T mshape_names[] = { - STRING_INIT("arrow"), // default, must be the first one - STRING_INIT("blank"), // hidden - STRING_INIT("beam"), - STRING_INIT("updown"), - STRING_INIT("udsizing"), - STRING_INIT("leftright"), - STRING_INIT("lrsizing"), - STRING_INIT("busy"), - STRING_INIT("no"), - STRING_INIT("crosshair"), - STRING_INIT("hand1"), - STRING_INIT("hand2"), - STRING_INIT("pencil"), - STRING_INIT("question"), - STRING_INIT("rightup-arrow"), - STRING_INIT("up-arrow"), + STR_LITERAL_INIT("arrow"), // default, must be the first one + STR_LITERAL_INIT("blank"), // hidden + STR_LITERAL_INIT("beam"), + STR_LITERAL_INIT("updown"), + STR_LITERAL_INIT("udsizing"), + STR_LITERAL_INIT("leftright"), + STR_LITERAL_INIT("lrsizing"), + STR_LITERAL_INIT("busy"), + STR_LITERAL_INIT("no"), + STR_LITERAL_INIT("crosshair"), + STR_LITERAL_INIT("hand1"), + STR_LITERAL_INIT("hand2"), + STR_LITERAL_INIT("pencil"), + STR_LITERAL_INIT("question"), + STR_LITERAL_INIT("rightup-arrow"), + STR_LITERAL_INIT("up-arrow"), {NULL, 0} }; -# undef STRING_INIT # define MSHAPE_NAMES_COUNT (ARRAY_LENGTH(mshape_names) - 1) # endif diff --git a/src/mouse.c b/src/mouse.c index 4b3db2dc49..c520f6c58c 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -19,6 +19,13 @@ */ static long mouse_hor_step = 6; static long mouse_vert_step = 3; +static win_T *dragwin = NULL; // window being dragged +static int stl_click_handler(win_T *wp, int mrow, int mcol, int which_button, + int mods); +static int stl_click_handler_regions(stl_click_region_T *regions, + int region_count, int winid, + char_u *area_name, int mrow, int mcol, + int which_button, int mods); void mouse_set_vert_scroll_step(long step) @@ -234,6 +241,9 @@ do_mouse( int in_status_line; // mouse in status line static int in_tab_line = FALSE; // mouse clicked in tab line static int in_tabpanel = FALSE; // mouse clicked in tabpanel +#ifdef FEAT_TABPANEL + static bool in_tabpanel_scrollbar = false; // dragging tabpanel scrollbar +#endif int in_sep_line; // mouse in vertical separator line int c1, c2; #if defined(FEAT_FOLDING) @@ -340,6 +350,9 @@ do_mouse( got_click = TRUE; in_tab_line = FALSE; in_tabpanel = FALSE; +#ifdef FEAT_TABPANEL + in_tabpanel_scrollbar = false; +#endif } else { @@ -348,15 +361,31 @@ do_mouse( if (!is_drag) // release, reset got_click { got_click = FALSE; - if (in_tab_line || in_tabpanel) + if (in_tab_line || in_tabpanel +#ifdef FEAT_TABPANEL + || in_tabpanel_scrollbar +#endif + ) { in_tab_line = FALSE; in_tabpanel = FALSE; +#ifdef FEAT_TABPANEL + in_tabpanel_scrollbar = false; +#endif return FALSE; } } } +#ifdef FEAT_TABPANEL + // Continue a scrollbar drag before any tab-selection handling. + if (is_drag && in_tabpanel_scrollbar) + { + tabpanel_drag_scrollbar(mouse_row); + return FALSE; + } +#endif + // CTRL right mouse button does CTRL-T if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT) { @@ -488,6 +517,26 @@ do_mouse( if (mouse_col < firstwin->w_wincol || mouse_col >= firstwin->w_wincol + topframe->fr_width) { + // A click on the scrollbar column starts a drag interaction and + // preempts tab-selection. + if (is_click && !is_drag && mouse_on_tabpanel_scrollbar()) + { + in_tabpanel_scrollbar = TRUE; + tabpanel_drag_scrollbar(mouse_row); + return FALSE; + } + + // Dispatch 'tabpanel' %[FuncName] click regions before falling through + // to tab-page selection. On drag events fall through to the normal + // tab-drag handling. + if (is_click && !is_drag + && stl_click_handler_regions(tabpanel_stl_click, + tabpanel_stl_click_count, + 0, (char_u *)"tabpanel", + mouse_row, mouse_col, + which_button, mod_mask)) + return FALSE; + tp_label.is_panel = true; tp_label.just_in = true; tp_label.nr = get_tabpagenr_on_tabpanel(); @@ -501,6 +550,17 @@ do_mouse( // Check for clicking in the tab page line. if (TabPageIdxs != NULL && mouse_row == 0 && firstwin->w_winrow > 0) { + // Dispatch 'tabline' %[FuncName] click regions before falling through + // to tab-page selection. On drag events fall through to the normal + // tab-drag handling. + if (is_click && !is_drag + && stl_click_handler_regions(tabline_stl_click, + tabline_stl_click_count, + 0, (char_u *)"tabline", + mouse_row, mouse_col, + which_button, mod_mask)) + return FALSE; + tp_label.just_in = true; tp_label.nr = TabPageIdxs[mouse_col]; @@ -532,9 +592,13 @@ do_mouse( c1 = tp_label.nr; if (c1 >= 0) { - if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) + if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK + && !tp_label.is_panel) { - // double click opens new page + // Double-click on the tabline opens a new, empty tab page. + // The tabpanel has no "empty area" (every row maps to a tab) + // and this behavior is not documented for tabpanel, so fall + // through to the regular tab-switch path there. end_visual_mode_keep_button(); tabpage_new(); tabpage_move(c1 == 0 ? 9999 : c1 - 1); @@ -761,6 +825,22 @@ do_mouse( in_status_line = (jump_flags & IN_STATUS_LINE); in_sep_line = (jump_flags & IN_SEP_LINE); + // Check for statusline click handler early, before visual mode or + // other button-specific handling can interfere. + if (in_status_line && is_click && !is_drag + && stl_click_handler(dragwin, mouse_row, mouse_col, + which_button, mod_mask)) + { +#ifdef FEAT_MOUSESHAPE + if (!drag_status_line) + { + drag_status_line = TRUE; + update_mouseshape(-1); + } +#endif + return FALSE; + } + #ifdef FEAT_NETBEANS_INTG if (isNetbeansBuffer(curbuf) && !(jump_flags & (IN_STATUS_LINE | IN_SEP_LINE))) @@ -1079,7 +1159,7 @@ do_mouse( find_end_of_word(&curwin->w_cursor); } } - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } if (is_click) redraw_curbuf_later(UPD_INVERTED); // update the inversion @@ -1251,6 +1331,17 @@ ins_mousescroll(int dir) cap.oap = &oa; cap.arg = dir; +#ifdef FEAT_TABPANEL + if (mouse_row >= 0 && mouse_col >= 0 + && (dir == MSCR_UP || dir == MSCR_DOWN) + && mouse_on_tabpanel()) + { + (void)tabpanel_scroll(dir == MSCR_UP ? 1 : -1, + mouse_vert_step > 0 ? mouse_vert_step : 3); + return; + } +#endif + switch (dir) { case MSCR_UP: @@ -1304,7 +1395,7 @@ ins_mousescroll(int dir) int did_scroll = (orig_topline != curwin->w_topline || orig_leftcol != curwin->w_leftcol); - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; curwin = old_curwin; curbuf = curwin->w_buffer; @@ -1641,7 +1732,156 @@ mouse_model_popup(void) return (p_mousem[0] == 'p'); } -static win_T *dragwin = NULL; // window being dragged +/* + * Call a click-region callback function. + * "regions"/"region_count" describe the resolved click regions, + * "winid" is stored as the "winid" key in the info dict (0 for tabline). + * Returns TRUE if the function was called and handled the click. + */ + static int +stl_click_handler_regions( + stl_click_region_T *regions, + int region_count, + int winid, + char_u *area_name, + int mrow, + int mcol, + int which_button, + int mods) +{ +#ifdef FEAT_EVAL + int n; + int nclicks; + char_u button_str[2]; + char_u mods_str[4]; + int mi = 0; + dict_T *info; + typval_T argvars[2]; + typval_T rettv; + funcexe_T funcexe; + int col = mcol; + + if (regions == NULL || region_count == 0) + return FALSE; + + // Find the click region at the given row and column. + for (n = 0; n < region_count; n++) + { + if (regions[n].row == mrow + && col >= regions[n].col_start + && col < regions[n].col_end) + break; + } + if (n >= region_count || regions[n].funcname == NULL) + return FALSE; + + // Build the info dictionary. + info = dict_alloc(); + if (info == NULL) + return FALSE; + + dict_add_number(info, "minwid", regions[n].minwid); + + // Determine number of clicks. + // MOD_MASK_2CLICK=0x20, MOD_MASK_3CLICK=0x40, MOD_MASK_4CLICK=0x60 + nclicks = ((mods & MOD_MASK_MULTI_CLICK) >> 5) + 1; + if (nclicks > 3) + nclicks = 3; + dict_add_number(info, "nclicks", nclicks); + + // Button. + if (which_button == MOUSE_LEFT) + button_str[0] = 'l'; + else if (which_button == MOUSE_RIGHT) + button_str[0] = 'r'; + else + button_str[0] = 'm'; + button_str[1] = NUL; + dict_add_string_len(info, "button", button_str, 1); + + // Modifiers. + if (mods & MOD_MASK_SHIFT) + mods_str[mi++] = 's'; + if (mods & MOD_MASK_CTRL) + mods_str[mi++] = 'c'; + if (mods & MOD_MASK_ALT) + mods_str[mi++] = 'a'; + mods_str[mi] = NUL; + dict_add_string_len(info, "mods", mods_str, mi); + + dict_add_number(info, "winid", winid); + + // "area": which option the clicked region belongs to. Lets a shared + // dispatcher distinguish 'statusline', 'tabline' and 'tabpanel' without + // having to overload winid == 0. + dict_add_string(info, "area", area_name); + + // Expose tab page number for 'tabpanel' regions. + if (regions[n].tabnr > 0) + dict_add_number(info, "tabnr", regions[n].tabnr); + + // Call the function with the info dict as argument. + argvars[0].v_type = VAR_DICT; + argvars[0].vval.v_dict = info; + ++info->dv_refcount; + argvars[1].v_type = VAR_UNKNOWN; + + rettv.v_type = VAR_NUMBER; + rettv.vval.v_number = 0; + + CLEAR_FIELD(funcexe); + funcexe.fe_evaluate = TRUE; + (void)call_func(regions[n].funcname, -1, + &rettv, 1, argvars, &funcexe); + + n = (int)rettv.vval.v_number; + clear_tv(&rettv); + dict_unref(info); + + if (n != 0) + { + // Make sure the tabline gets redrawn too when the callback asks for + // a redraw (redraw_statuslines() only redraws the tabline when + // redraw_tabline is set). For tabpanel the whole screen needs to be + // refreshed. + if (winid == 0) + redraw_tabline = TRUE; +# ifdef FEAT_TABPANEL + if (STRCMP(area_name, "tabpanel") == 0) + redraw_all_later(UPD_NOT_VALID); +# endif + redraw_statuslines(); + } + + return TRUE; +#else + (void)regions; + (void)region_count; + (void)winid; + (void)area_name; + (void)mrow; + (void)mcol; + (void)which_button; + (void)mods; + return FALSE; +#endif +} + +/* + * Call a statusline click handler function for window "wp". + * Returns TRUE if the function was called and handled the click. + */ + static int +stl_click_handler(win_T *wp, int mrow, int mcol, int which_button, int mods) +{ + if (wp == NULL) + return FALSE; + return stl_click_handler_regions(wp->w_stl_click, wp->w_stl_click_count, + wp->w_id, (char_u *)"statusline", + mrow, mcol, which_button, mods); +} + +// dragwin is declared near the top of the file /* * Reset the window being dragged. To be called when switching tab page. @@ -2172,7 +2412,7 @@ retnomove: } curwin->w_curswant = col; - curwin->w_set_curswant = FALSE; // May still have been TRUE + curwin->w_set_curswant = false; // May still have been TRUE if (coladvance(col) == FAIL) // Mouse click beyond end of line { if (inclusive != NULL) @@ -2235,6 +2475,17 @@ nv_mousescroll(cmdarg_T *cap) { win_T *old_curwin = curwin; +#ifdef FEAT_TABPANEL + if (mouse_row >= 0 && mouse_col >= 0 + && (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) + && mouse_on_tabpanel()) + { + (void)tabpanel_scroll(cap->arg == MSCR_UP ? 1 : -1, + mouse_vert_step > 0 ? mouse_vert_step : 3); + return; + } +#endif + if (mouse_row >= 0 && mouse_col >= 0) { // Find the window at the mouse pointer coordinates. @@ -2262,7 +2513,7 @@ nv_mousescroll(cmdarg_T *cap) // Call the common mouse scroll function shared with other modes. do_mousescroll(cap); - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; curwin = old_curwin; curbuf = curwin->w_buffer; } diff --git a/src/move.c b/src/move.c index ee9a8eb5aa..14271240fd 100644 --- a/src/move.c +++ b/src/move.c @@ -279,6 +279,31 @@ update_topline_redraw(void) update_screen(0); } +/* + * Return true when 'scrolloffpad' may augment 'scrolloff'. + * This only applies to automatic cursor visibility correction. + * For now 'scrolloffpad' is treated as boolean: 0 disables, > 0 enables. + */ + static bool +use_scrolloffpad(void) +{ + return get_scrolloff_value() > 0 && get_scrolloffpad_value() > 0; +} + +/* + * Return TRUE when there are not enough real buffer lines below "lnum" to + * satisfy the requested "so" context. + */ + static bool +scrolloffpad_eof_pressure(linenr_T lnum, long so) +{ + if (!use_scrolloffpad() || so <= 0) + return false; + + // Use subtraction to avoid signed overflow in "lnum + so". + return lnum > curbuf->b_ml.ml_line_count - so; +} + /* * Update curwin->w_topline to move the cursor onto the screen. */ @@ -295,6 +320,7 @@ update_topline(void) int check_botline = FALSE; long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; int save_so = *so_ptr; + bool eof_pressure; // Cursor is updated instead when this is TRUE for 'splitkeep'. if (skip_update_topline) @@ -318,6 +344,7 @@ update_topline(void) // When dragging with the mouse, don't scroll that quickly if (mouse_dragging > 0) *so_ptr = mouse_dragging - 1; + eof_pressure = scrolloffpad_eof_pressure(curwin->w_cursor.lnum, *so_ptr); linenr_T old_topline = curwin->w_topline; #ifdef FEAT_DIFF @@ -405,11 +432,21 @@ update_topline(void) // cursor in the middle of the window. Otherwise put the cursor // near the top of the window. if (n >= halfheight) - scroll_cursor_halfway(FALSE, FALSE); + { + if (eof_pressure) + scroll_cursor_halfway(TRUE, TRUE); + else + scroll_cursor_halfway(FALSE, FALSE); + } else { - scroll_cursor_top(scrolljump_value(), FALSE); - check_botline = TRUE; + if (eof_pressure) + scroll_cursor_halfway(TRUE, TRUE); + else + { + scroll_cursor_top(scrolljump_value(), FALSE); + check_botline = TRUE; + } } } @@ -436,51 +473,52 @@ update_topline(void) if (!(curwin->w_valid & VALID_BOTLINE_AP)) validate_botline(); - if (curwin->w_botline <= curbuf->b_ml.ml_line_count) + if (curwin->w_botline <= curbuf->b_ml.ml_line_count || use_scrolloffpad()) { if (curwin->w_cursor.lnum < curwin->w_botline) { - if (((long)curwin->w_cursor.lnum + if (((long)curwin->w_cursor.lnum >= (long)curwin->w_botline - *so_ptr #ifdef FEAT_FOLDING || hasAnyFolding(curwin) #endif )) - { - lineoff_T loff; - - // Cursor is (a few lines) above botline, check if there are - // 'scrolloff' window lines below the cursor. If not, need to - // scroll. - n = curwin->w_empty_rows; - loff.lnum = curwin->w_cursor.lnum; -#ifdef FEAT_FOLDING - // In a fold go to its last line. - (void)hasFolding(loff.lnum, NULL, &loff.lnum); -#endif -#ifdef FEAT_DIFF - loff.fill = 0; - n += curwin->w_filler_rows; -#endif - loff.height = 0; - while (loff.lnum < curwin->w_botline -#ifdef FEAT_DIFF - && (loff.lnum + 1 < curwin->w_botline || loff.fill == 0) -#endif - ) { - n += loff.height; - if (n >= *so_ptr) - break; - botline_forw(&loff); + lineoff_T loff; + + // Cursor is (a few lines) above botline, check if there + // are 'scrolloff' window lines below the cursor. + // If not, need to scroll. + n = eof_pressure ? 0 : curwin->w_empty_rows; + loff.lnum = curwin->w_cursor.lnum; +#ifdef FEAT_FOLDING + // In a fold go to its last line. + (void)hasFolding(loff.lnum, NULL, &loff.lnum); +#endif +#ifdef FEAT_DIFF + loff.fill = 0; + n += curwin->w_filler_rows; +#endif + loff.height = 0; + while (loff.lnum < curwin->w_botline +#ifdef FEAT_DIFF + && (loff.lnum + 1 < curwin->w_botline + || loff.fill == 0) +#endif + ) + { + n += loff.height; + if (n >= *so_ptr) + break; + botline_forw(&loff); + } + if (n >= *so_ptr && !eof_pressure) + // sufficient context, no need to scroll + check_botline = FALSE; } - if (n >= *so_ptr) + else // sufficient context, no need to scroll check_botline = FALSE; - } - else - // sufficient context, no need to scroll - check_botline = FALSE; } if (check_botline) { @@ -506,9 +544,14 @@ update_topline(void) line_count = curwin->w_cursor.lnum - curwin->w_botline + 1 + *so_ptr; if (line_count <= curwin->w_height + 1) - scroll_cursor_bot(scrolljump_value(), FALSE); + { + if (eof_pressure) + scroll_cursor_halfway(TRUE, TRUE); + else + scroll_cursor_bot(scrolljump_value(), FALSE); + } else - scroll_cursor_halfway(FALSE, FALSE); + scroll_cursor_halfway(eof_pressure, eof_pressure); } } } @@ -608,7 +651,7 @@ update_curswant_force(void) - curwin->w_virtcol_first_char #endif ; - curwin->w_set_curswant = FALSE; + curwin->w_set_curswant = false; } /* @@ -724,7 +767,7 @@ set_topline(win_T *wp, linenr_T lnum) if (wp->w_botline > wp->w_buffer->b_ml.ml_line_count + 1) wp->w_botline = wp->w_buffer->b_ml.ml_line_count + 1; wp->w_topline = lnum; - wp->w_topline_was_set = TRUE; + wp->w_topline_was_set = true; #ifdef FEAT_DIFF if (lnum != prev_topline) // Keep the filler lines when the topline didn't change. @@ -1142,9 +1185,9 @@ curwin_col_off2(void) curs_columns( int may_scroll) // when TRUE, may scroll horizontally { - int diff; + long diff; int extra; // offset for first screen line - int off_left, off_right; + long off_left, off_right; int n; int p_lines; int width1; // text width for first screen line @@ -1264,13 +1307,12 @@ curs_columns( #endif /* * If Cursor is left of the screen, scroll rightwards. - * If Cursor is right of the screen, scroll leftwards + * If Cursor is right of the screen, scroll leftwards. * If we get closer to the edge than 'sidescrolloff', scroll a little - * extra + * extra. */ - off_left = (int)startcol - (int)curwin->w_leftcol - siso; - off_right = (int)endcol - (int)(curwin->w_leftcol + curwin->w_width - - siso) + 1; + off_left = startcol - curwin->w_leftcol - siso; + off_right = endcol - curwin->w_leftcol - (curwin->w_width - siso) + 1; if (off_left < 0 || off_right > 0) { if (off_left < 0) @@ -1287,9 +1329,9 @@ curs_columns( if (diff < p_ss) diff = p_ss; if (off_left < 0) - new_leftcol = curwin->w_leftcol - diff; + new_leftcol = curwin->w_leftcol - (int)diff; else - new_leftcol = curwin->w_leftcol + diff; + new_leftcol = curwin->w_leftcol + (int)diff; } if (new_leftcol < 0) new_leftcol = 0; @@ -2350,9 +2392,11 @@ botline_forw(lineoff_T *lp) else #ifdef FEAT_FOLDING if (hasFolding(lp->lnum, NULL, &lp->lnum)) - // Add a closed fold - lp->height = 1; - else + { + // Add a closed fold. + lp->height = 1; + } + else #endif lp->height = PLINES_NOFILL(lp->lnum); } @@ -2804,8 +2848,9 @@ scroll_cursor_bot(int min_scroll, int set_topbot) * Scroll up if the cursor is off the bottom of the screen a bit. * Otherwise put it at 1/2 of the screen. */ + bool eof_pressure = scrolloffpad_eof_pressure(cln, so); if (line_count >= curwin->w_height && line_count > min_scroll) - scroll_cursor_halfway(FALSE, TRUE); + scroll_cursor_halfway(eof_pressure, TRUE); else if (line_count > 0) { if (do_sms) @@ -2999,7 +3044,7 @@ scroll_cursor_halfway(int atend, int prefer_above) #ifdef FEAT_DIFF curwin->w_topfill = topfill; if (old_topline > curwin->w_topline + curwin->w_height) - curwin->w_botfill = FALSE; + curwin->w_botfill = false; check_topfill(curwin, FALSE); #endif curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); @@ -3046,7 +3091,8 @@ cursor_correct(void) if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1 && mouse_dragging == 0) { - below_wanted = 0; + if (!use_scrolloffpad()) + below_wanted = 0; max_off = (curwin->w_height - 1) / 2; if (above_wanted > max_off) above_wanted = max_off; @@ -3412,7 +3458,7 @@ do_check_cursorbind(void) // Only scroll when 'scrollbind' hasn't done this. if (!curwin->w_p_scb) update_topline(); - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; } } diff --git a/src/msvc-latest.bat b/src/msvc-latest.bat index 4529fa02eb..93ac705702 100644 --- a/src/msvc-latest.bat +++ b/src/msvc-latest.bat @@ -39,18 +39,16 @@ if "%VSVEROPT%"=="" ( ) rem Search Visual Studio Community, Professional or above. +set InstallDir= for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" %VSVEROPT% -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( set InstallDir=%%i ) -if exist "%InstallDir%\VC\Auxiliary\Build\vcvarsall.bat" ( - call "%InstallDir%\VC\Auxiliary\Build\vcvarsall.bat" %* - goto done -) - -rem Search Visual Studio 2017 Express. -rem (Visual Studio 2017 Express uses different component IDs.) -for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" %VSVEROPT% -products Microsoft.VisualStudio.Product.WDExpress -property installationPath`) do ( - set InstallDir=%%i +if not defined InstallDir ( + rem Search Visual Studio 2017 Express. + rem (Visual Studio 2017 Express uses different component IDs.) + for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" %VSVEROPT% -products Microsoft.VisualStudio.Product.WDExpress -property installationPath`) do ( + set InstallDir=%%i + ) ) if exist "%InstallDir%\VC\Auxiliary\Build\vcvarsall.bat" ( call "%InstallDir%\VC\Auxiliary\Build\vcvarsall.bat" %* @@ -60,7 +58,14 @@ if exist "%InstallDir%\VC\Auxiliary\Build\vcvarsall.bat" ( call ) -:done +if defined VCToolsVersion ( + if "%VSVEROPT%"=="-latest" ( + echo VCTools %VCToolsVersion% %VSCMD_ARG_TGT_ARCH% + for /f "tokens=1,2 delims=." %%I in ("%VCToolsVersion%") do ( + title VCTools %%I.%%J %VSCMD_ARG_TGT_ARCH% + ) + ) +) if "%VSWHERE_SET%"=="yes" ( set VSWHERE= set VSWHERE_SET= diff --git a/src/msvc2015.bat b/src/msvc2015.bat index b541719ac2..2ee864ca6a 100644 --- a/src/msvc2015.bat +++ b/src/msvc2015.bat @@ -12,4 +12,18 @@ rem If you use Community (or Professional) edition, you can also use "x64" rem option: rem msvc2015 x64 +set Platform= +if not exist "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" ( + echo Error: vcvarsall.bat not found. + exit /b 1 +) call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" %* +if defined VisualStudioVersion ( + if defined Platform ( + echo VS 2015 ^(%VisualStudioVersion%^) %Platform% + title VS 2015 %Platform% + ) else ( + echo VS 2015 ^(%VisualStudioVersion%^) x86 + title VS 2015 x86 + ) +) diff --git a/src/msvc2017.bat b/src/msvc2017.bat index c7731c92c9..569eddd153 100644 --- a/src/msvc2017.bat +++ b/src/msvc2017.bat @@ -11,3 +11,7 @@ rem msvc2017 x86_amd64 set "VSVEROPT=-version [15.0^,16.0^)" call "%~dp0msvc-latest.bat" %* set VSVEROPT= +if defined VCToolsVersion ( + echo VS 2017 ^(%VCToolsVersion%^) %VSCMD_ARG_TGT_ARCH% + title VS 2017 %VSCMD_ARG_TGT_ARCH% +) diff --git a/src/msvc2019.bat b/src/msvc2019.bat index a45ef2c564..16a893f1dc 100644 --- a/src/msvc2019.bat +++ b/src/msvc2019.bat @@ -11,3 +11,7 @@ rem msvc2019 x64 set "VSVEROPT=-version [16.0^,17.0^)" call "%~dp0msvc-latest.bat" %* set VSVEROPT= +if defined VCToolsVersion ( + echo VS 2019 ^(%VCToolsVersion%^) %VSCMD_ARG_TGT_ARCH% + title VS 2019 %VSCMD_ARG_TGT_ARCH% +) diff --git a/src/msvc2022.bat b/src/msvc2022.bat index b707410070..67a9491b67 100644 --- a/src/msvc2022.bat +++ b/src/msvc2022.bat @@ -11,3 +11,7 @@ rem msvc2022 x64 set "VSVEROPT=-version [17.0^,18.0^)" call "%~dp0msvc-latest.bat" %* set VSVEROPT= +if defined VCToolsVersion ( + echo VS 2022 ^(%VCToolsVersion%^) %VSCMD_ARG_TGT_ARCH% + title VS 2022 %VSCMD_ARG_TGT_ARCH% +) diff --git a/src/netbeans.c b/src/netbeans.c index 12098982ef..20aae0d3ae 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -486,7 +486,7 @@ nb_parse_cmd(char_u *cmd) buf_T *buf; FOR_ALL_BUFFERS(buf) - buf->b_has_sign_column = FALSE; + buf->b_has_sign_column = false; // The IDE is breaking the connection. netbeans_close(); @@ -595,8 +595,8 @@ nb_free(void) vim_free(buf.signmap); if (buf.bufp != NULL && buf_valid(buf.bufp)) { - buf.bufp->b_netbeans_file = FALSE; - buf.bufp->b_was_netbeans_file = FALSE; + buf.bufp->b_netbeans_file = false; + buf.bufp->b_was_netbeans_file = false; } } VIM_CLEAR(buf_list); @@ -2211,11 +2211,11 @@ nb_do_cmd( } if (*args == 'T') { - buf->bufp->b_netbeans_file = TRUE; - buf->bufp->b_was_netbeans_file = TRUE; + buf->bufp->b_netbeans_file = true; + buf->bufp->b_was_netbeans_file = true; } else - buf->bufp->b_netbeans_file = FALSE; + buf->bufp->b_netbeans_file = false; // ===================================================================== } else if (streq((char *)cmd, "specialKeys")) diff --git a/src/normal.c b/src/normal.c index 06209fe696..ba053ff1e9 100644 --- a/src/normal.c +++ b/src/normal.c @@ -1847,7 +1847,7 @@ display_showcmd(void) if (*p_sloc == 's') { if (showcmd_is_clear) - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; else win_redr_status(curwin, FALSE); } @@ -2000,7 +2000,7 @@ check_scrollbind(linenr_T topline_diff, long leftcol_diff) redraw_later(UPD_VALID); cursor_correct(); - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; } // do the horizontal scroll @@ -2316,7 +2316,7 @@ find_decl( } else { - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // "n" searches forward now reset_search_dir(); } @@ -2793,8 +2793,10 @@ nv_zet(cmdarg_T *cap) n = curwin->w_width - curwin_col_off(); if ((long)col + siso < n) col = 0; + else if (siso - n < INT_MAX - col) + col = (int)(col + siso - n + 1); else - col = col + siso - n + 1; + col = INT_MAX; if (curwin->w_leftcol != col) { curwin->w_leftcol = col; @@ -2925,14 +2927,14 @@ nv_zet(cmdarg_T *cap) // "zx": re-apply 'foldlevel' and open folds at the cursor case 'x': curwin->w_p_fen = TRUE; - curwin->w_foldinvalid = TRUE; // recompute folds + curwin->w_foldinvalid = true; // recompute folds newFoldLevel(); // update right now foldOpenCursor(); break; // "zX": undo manual opens/closes, re-apply 'foldlevel' case 'X': curwin->w_p_fen = TRUE; - curwin->w_foldinvalid = TRUE; // recompute folds + curwin->w_foldinvalid = true; // recompute folds old_fdl = -1; // force an update break; @@ -3877,7 +3879,7 @@ nv_right(cmdarg_T *cap) ++curwin->w_cursor.lnum; curwin->w_cursor.col = 0; curwin->w_cursor.coladd = 0; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; cap->oap->inclusive = FALSE; } continue; @@ -3897,7 +3899,7 @@ nv_right(cmdarg_T *cap) } else if (past_line) { - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (virtual_active()) oneright(); else @@ -3955,7 +3957,7 @@ nv_left(cmdarg_T *cap) { --(curwin->w_cursor.lnum); coladvance((colnr_T)MAXCOL); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // When the NL before the first char has to be deleted we // put the cursor on the NUL after the previous line. @@ -4224,7 +4226,7 @@ normal_search( cap->oap->motion_type = MCHAR; cap->oap->inclusive = FALSE; cap->oap->use_reg_one = TRUE; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; CLEAR_FIELD(sia); i = do_search(cap->oap, dir, dir, pat, patlen, cap->count1, @@ -4291,7 +4293,7 @@ nv_csearch(cmdarg_T *cap) return; } - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // Include a Tab for "tx" and for "dfx". if (gchar_cursor() == TAB && virtual_active() && cap->arg == FORWARD && (t_cmd || cap->oap->op_type != OP_NOP)) @@ -4433,7 +4435,7 @@ nv_bracket_block(cmdarg_T *cap, pos_T *old_pos) { setpcmark(); curwin->w_cursor = *pos; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; #ifdef FEAT_FOLDING if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP) @@ -4497,7 +4499,7 @@ nv_brackets(cmdarg_T *cap) (linenr_T)MAXLNUM, FALSE, FALSE); vim_free(ptr); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } } else @@ -4522,7 +4524,7 @@ nv_brackets(cmdarg_T *cap) else flag = '}'; // "][" or "[]" - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // Imitate strange Vi behaviour: When using "]]" with an operator // we also stop at '}'. if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, flag, @@ -4607,7 +4609,7 @@ nv_brackets(cmdarg_T *cap) break; } else - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; # ifdef FEAT_FOLDING if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped) foldOpenCursor(); @@ -4667,7 +4669,7 @@ nv_percent(cmdarg_T *cap) { setpcmark(); curwin->w_cursor = *pos; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; curwin->w_cursor.coladd = 0; adjust_for_sel(cap); } @@ -4692,7 +4694,7 @@ nv_brace(cmdarg_T *cap) cap->oap->use_reg_one = TRUE; // The motion used to be inclusive for "(", but that is not what Vi does. cap->oap->inclusive = FALSE; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (findsent(cap->arg, cap->count1) == FAIL) { @@ -4732,7 +4734,7 @@ nv_findpar(cmdarg_T *cap) cap->oap->motion_type = MCHAR; cap->oap->inclusive = FALSE; cap->oap->use_reg_one = TRUE; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, NUL, FALSE)) { clearopbeep(cap->oap); @@ -4780,7 +4782,7 @@ nv_kundo(cmdarg_T *cap) } #endif u_undo((int)cap->count1); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } /* @@ -4985,7 +4987,7 @@ nv_replace(cmdarg_T *cap) if (has_mbyte) mb_adjust_cursor(); curbuf->b_op_end = curwin->w_cursor; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; set_last_insert(cap->nchar); } } @@ -5035,7 +5037,7 @@ v_swap_corners(int cmdchar) old_cursor = curwin->w_cursor; curwin->w_cursor = VIsual; VIsual = old_cursor; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } } @@ -5189,7 +5191,7 @@ n_swapchar(cmdarg_T *cap) check_cursor(); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (did_change) { changed_lines(startpos.lnum, startpos.col, curwin->w_cursor.lnum + 1, @@ -5226,7 +5228,7 @@ nv_cursormark(cmdarg_T *cap, int flag, pos_T *pos) if (cap->cmdchar == '`') cap->oap->use_reg_one = TRUE; cap->oap->inclusive = FALSE; // ignored if not MCHAR - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } /* @@ -5413,7 +5415,7 @@ nv_pcmark(cmdarg_T *cap) pos = movemark((int)cap->count1); if (pos == (pos_T *)-1) // jump to other file { - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; check_cursor(); } else if (pos != NULL) // can jump @@ -5553,7 +5555,7 @@ nv_visual(cmdarg_T *cap) coladvance(curwin->w_curswant); } else - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; redraw_curbuf_later(UPD_INVERTED); // show the inversion } else @@ -5815,7 +5817,7 @@ nv_g_home_m_cmd(cmdarg_T *cap) while (VIM_ISWHITE(i) && oneright() == OK); curwin->w_valid &= ~VALID_WCOL; } - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; #ifdef FEAT_FOLDING if (hasAnyFolding(curwin)) { @@ -5856,7 +5858,7 @@ nv_g_underscore_cmd(cmdarg_T *cap) while (curwin->w_cursor.col > 0 && VIM_ISWHITE(ptr[curwin->w_cursor.col])) --curwin->w_cursor.col; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; adjust_for_sel(cap); } @@ -6105,7 +6107,7 @@ nv_g_cmd(cmdarg_T *cap) coladvance((colnr_T)(i * cap->count0 / 100)); else coladvance((colnr_T)(i / 2)); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } break; @@ -6137,7 +6139,7 @@ nv_g_cmd(cmdarg_T *cap) case 'e': case 'E': oap->motion_type = MCHAR; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; oap->inclusive = TRUE; if (bckend_word(cap->count1, cap->nchar == 'E', FALSE) == FAIL) clearopbeep(oap); @@ -6411,7 +6413,7 @@ nv_redo_or_register(cmdarg_T *cap) return; u_redo((int)cap->count1); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } /* @@ -6434,7 +6436,7 @@ nv_Undo(cmdarg_T *cap) return; u_undoline(); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } /* @@ -6513,7 +6515,7 @@ set_op_var(int optype) /* * Handle linewise operator "dd", "yy", etc. * - * "_" is is a strange motion command that helps make operators more logical. + * "_" is a strange motion command that helps make operators more logical. * It is actually implemented, but not documented in the real Vi. This motion * command actually refers to "the current line". Commands like "dd" and "yy" * are really an alternate form of "d_" and "y_". It does accept a count, so @@ -6571,7 +6573,7 @@ nv_pipe(cmdarg_T *cap) curwin->w_curswant = 0; // keep curswant at the column where we wanted to go, not where // we ended; differs if line is too short - curwin->w_set_curswant = FALSE; + curwin->w_set_curswant = false; } /* @@ -6583,7 +6585,7 @@ nv_bck_word(cmdarg_T *cap) { cap->oap->motion_type = MCHAR; cap->oap->inclusive = FALSE; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (bck_word(cap->count1, cap->arg, FALSE) == FAIL) clearopbeep(cap->oap); #ifdef FEAT_FOLDING @@ -6653,7 +6655,7 @@ nv_wordcmd(cmdarg_T *cap) } cap->oap->motion_type = MCHAR; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (word_end) n = end_word(cap->count1, cap->arg, flag, FALSE); else @@ -6933,7 +6935,7 @@ nv_esc(cmdarg_T *cap) { end_visual_mode(); // stop Visual check_cursor_col(); // make sure cursor is not beyond EOL - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; redraw_curbuf_later(UPD_INVERTED); } else if (no_reason) @@ -6959,7 +6961,7 @@ nv_esc(cmdarg_T *cap) void set_cursor_for_append_to_line(void) { - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if (get_ve_flags() == VE_ALL) { int save_State = State; @@ -7244,7 +7246,7 @@ nv_object( if (flag == FAIL) clearopbeep(cap->oap); adjust_cursor_col(); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } /* diff --git a/src/ops.c b/src/ops.c index 715897331e..0ebdb381d9 100644 --- a/src/ops.c +++ b/src/ops.c @@ -1719,7 +1719,7 @@ op_insert(oparg_T *oap, long count1) if (oap->block_mode && curwin->w_cursor.coladd == 0) { // Move the cursor to the character right of the block. - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; while (*ml_get_cursor() != NUL && (curwin->w_cursor.col < bd.textcol + bd.textlen)) ++curwin->w_cursor.col; @@ -2390,7 +2390,7 @@ do_join( check_cursor_col(); curwin->w_cursor.coladd = 0; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; theend: vim_free(spaces); @@ -3273,7 +3273,7 @@ theend: if (visual) curwin->w_cursor = save_cursor; else if (did_change) - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; else if (virtual_active()) curwin->w_cursor.coladd = save_coladd; @@ -4270,7 +4270,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) if (l > 1) oap->end.col += l - 1; } - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // oap->empty is set when start and end are the same. The inclusive // flag affects this too, unless yanking and the end is on a NUL. diff --git a/src/option.c b/src/option.c index d17cca1705..668a74fbbd 100644 --- a/src/option.c +++ b/src/option.c @@ -714,7 +714,7 @@ set_init_1(int clean_arg) set_option_value_give_err((char_u *)"bg", 0L, (char_u *)"dark", 0); #endif - curbuf->b_p_initialized = TRUE; + curbuf->b_p_initialized = true; curbuf->b_p_ac = -1; curbuf->b_p_ar = -1; // no local 'autoread' value #ifdef HAVE_FSYNC @@ -822,8 +822,9 @@ set_option_default( long def_val = (long)(long_i)options[opt_idx].def_val[dvi]; if ((long *)varp == &curwin->w_p_so - || (long *)varp == &curwin->w_p_siso) - // 'scrolloff' and 'sidescrolloff' local values have a + || (long *)varp == &curwin->w_p_siso + || (long *)varp == &curwin->w_p_sop) + // 'scrolloff', 'sidescrolloff', and 'scrolloffpad' local values have a // different default value than the global default. *(long *)varp = -1; else @@ -1561,13 +1562,57 @@ get_opt_op(char_u *arg) return op; } +// Options that are allowed in a modeline when 'modelinestrict' is on. +static char *modeline_whitelist[] = +{ + "autoindent", + "cindent", + "commentstring", + "expandtab", + "filetype", + "foldcolumn", + "foldenable", + "foldmarker", + "foldmethod", + "modifiable", + "readonly", + "rightleft", + "shiftwidth", + "smartindent", + "softtabstop", + "spell", + "spelllang", + "tabstop", + "textwidth", + "varsofttabstop", + "vartabstop", + NULL +}; + +/* + * Return TRUE if option "name" is in the modeline whitelist. + */ + static bool +is_modeline_whitelisted(char *name) +{ + for (int i = 0; modeline_whitelist[i] != NULL; i++) + if (STRCMP(name, modeline_whitelist[i]) == 0) + return true; + return false; +} + /* * Validate whether the value of the option in "opt_idx" can be changed. * Returns FAIL if the option can be skipped or cannot be changed. Returns OK * if it can be changed. */ static int -validate_opt_idx(int opt_idx, int opt_flags, long_u flags, char **errmsg) +validate_opt_idx( + int opt_idx, + int opt_flags, + long_u flags, + char **errmsg, + set_prefix_T prefix) { // Skip all options that are not window-local (used when showing // an already loaded buffer in a window). @@ -1593,6 +1638,16 @@ validate_opt_idx(int opt_idx, int opt_flags, long_u flags, char **errmsg) *errmsg = e_not_allowed_in_modeline_when_modelineexpr_is_off; return FAIL; } + // When 'modelinestrict' is on, only whitelisted options may be + // set from a modeline. Silently skip others. + if (p_mlstr && opt_idx >= 0) + { + // special case: allow disabling modeline + if (options[opt_idx].indir == PV_ML && prefix == PREFIX_NO) + return OK; + else if (!is_modeline_whitelisted(options[opt_idx].fullname)) + return FAIL; + } #ifdef FEAT_DIFF // In diff mode some options are overruled. This avoids that // 'foldmethod' becomes "marker" instead of "diff" and that @@ -2556,8 +2611,9 @@ do_set_option_numeric( value = NO_LOCAL_UNDOLEVEL; else if (opt_flags == OPT_LOCAL && ((long *)varp == &curwin->w_p_siso - || (long *)varp == &curwin->w_p_so)) - // for 'scrolloff'/'sidescrolloff' -1 means using the global value + || (long *)varp == &curwin->w_p_so + || (long *)varp == &curwin->w_p_sop)) + // for 'scrolloff'/'sidescrolloff'/'scrolloffpad' -1 means using the global value value = -1; else value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL); @@ -2599,6 +2655,12 @@ do_set_option_numeric( else if (op == OP_REMOVING) value = *(long *)varp - value; + if ((long *)varp == &curwin->w_p_sop && value < -1) + { + errmsg = e_invalid_argument; + goto skip; + } + errmsg = set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags); @@ -2830,7 +2892,7 @@ do_set_option( } // Make sure the option value can be changed. - if (validate_opt_idx(opt_idx, opt_flags, flags, &errmsg) == FAIL) + if (validate_opt_idx(opt_idx, opt_flags, flags, &errmsg, prefix) == FAIL) goto skip; int cp_val = p_cp; @@ -3231,7 +3293,8 @@ option_expand(int opt_idx, char_u *val) char_u ** var = (char_u **)options[opt_idx].var; int esc = var == &p_tags || var == &p_path; - expand_env_esc(val, NameBuff, MAXPATHL, esc, FALSE, + expand_env_esc(val, NameBuff, MAXPATHL, + esc ? (char_u *)" \t" : NULL, FALSE, #ifdef FEAT_SPELL var == &p_sps ? (char_u *)"file:" : #endif @@ -4151,7 +4214,7 @@ did_set_modified(optset_T *args) if (!args->os_newval.boolean) save_file_ff(curbuf); // Buffer is unchanged redraw_titles(); - curbuf->b_modified_was_set = args->os_newval.boolean; + curbuf->b_modified_was_set = !!args->os_newval.boolean; return NULL; } @@ -4455,7 +4518,7 @@ did_set_readonly(optset_T *args) // when 'readonly' is set may give W10 again if (curbuf->b_p_ro) - curbuf->b_did_warn = FALSE; + curbuf->b_did_warn = false; redraw_titles(); @@ -4500,7 +4563,6 @@ did_set_maxsearchcount(optset_T *args UNUSED) #undef MAX_SEARCH_COUNT } - #if defined(BACKSLASH_IN_FILENAME) /* * Process the updated 'shellslash' option value. @@ -5386,7 +5448,7 @@ set_bool_option( if (curwin->w_curswant != MAXCOL && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0 && (options[opt_idx].flags & P_HLONLY) == 0) - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if ((opt_flags & OPT_NO_REDRAW) == 0) check_redraw(options[opt_idx].flags); @@ -5512,6 +5574,11 @@ check_num_option_bounds( errmsg = e_argument_must_be_positive; p_so = 0; } + if (p_sop < 0 && full_screen) + { + errmsg = e_invalid_argument; + p_sop = 0; + } if (p_siso < 0 && full_screen) { errmsg = e_argument_must_be_positive; @@ -5621,7 +5688,7 @@ set_num_option( if (curwin->w_curswant != MAXCOL && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0 && (options[opt_idx].flags & P_HLONLY) == 0) - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if ((opt_flags & OPT_NO_REDRAW) == 0) check_redraw(options[opt_idx].flags); @@ -6929,6 +6996,9 @@ unset_global_local_option(char_u *name, void *from) case PV_SO: curwin->w_p_so = -1; break; + case PV_SOP: + curwin->w_p_sop = -1; + break; # ifdef FEAT_FIND_ID case PV_DEF: clear_string_option(&buf->b_p_def); @@ -7070,6 +7140,7 @@ get_varp_scope(struct vimoption *p, int scope) case PV_TC: return (char_u *)&(curbuf->b_p_tc); case PV_SISO: return (char_u *)&(curwin->w_p_siso); case PV_SO: return (char_u *)&(curwin->w_p_so); + case PV_SOP: return (char_u *)&(curwin->w_p_sop); #ifdef FEAT_FIND_ID case PV_DEF: return (char_u *)&(curbuf->b_p_def); case PV_INC: return (char_u *)&(curbuf->b_p_inc); @@ -7155,6 +7226,8 @@ get_varp(struct vimoption *p) ? (char_u *)&(curwin->w_p_siso) : p->var; case PV_SO: return curwin->w_p_so >= 0 ? (char_u *)&(curwin->w_p_so) : p->var; + case PV_SOP: return curwin->w_p_sop != -1 + ? (char_u *)&(curwin->w_p_sop) : p->var; #ifdef FEAT_FIND_ID case PV_DEF: return *curbuf->b_p_def != NUL ? (char_u *)&(curbuf->b_p_def) : p->var; @@ -7559,6 +7632,7 @@ copy_winopt(winopt_T *from, winopt_T *to) to->wo_crb_save = from->wo_crb_save; to->wo_siso = from->wo_siso; to->wo_so = from->wo_so; + to->wo_sop = from->wo_sop; #ifdef FEAT_SPELL to->wo_spell = from->wo_spell; #endif @@ -8095,7 +8169,7 @@ buf_copy_options(buf_T *buf, int flags) else buf->b_p_vts_array = NULL; #endif - buf->b_help = FALSE; + buf->b_help = false; if (buf->b_p_bt[0] == 'h') clear_string_option(&buf->b_p_bt); buf->b_p_ma = p_ma; @@ -8106,7 +8180,7 @@ buf_copy_options(buf_T *buf, int flags) // When the options should be copied (ignoring BCO_ALWAYS), set the // flag that indicates that the options have been initialized. if (should_copy) - buf->b_p_initialized = TRUE; + buf->b_p_initialized = true; } check_buf_options(buf); // make sure we don't have NULLs @@ -9189,6 +9263,16 @@ get_scrolloff_value(void) return curwin->w_p_so < 0 ? p_so : curwin->w_p_so; } +/* + * Return the effective 'scrolloffpad' value for the current window, using the + * global value when appropriate. + */ + long +get_scrolloffpad_value(void) +{ + return curwin->w_p_sop == -1 ? p_sop : curwin->w_p_sop; +} + /* * Return the effective 'sidescrolloff' value for the current window, using the * global value when appropriate. diff --git a/src/option.h b/src/option.h index e2f415726d..023002739c 100644 --- a/src/option.h +++ b/src/option.h @@ -277,8 +277,9 @@ typedef enum { #define SHM_RECORDING 'q' // short recording message #define SHM_FILEINFO 'F' // no file info messages #define SHM_SEARCHCOUNT 'S' // no search stats: '[1/10]' +#define SHM_UNDO 'u' // undo messages #define SHM_POSIX "AS" // POSIX value -#define SHM_ALL "rmfixlnwaWtToOsAIcCqFS" // all possible flags for 'shm' +#define SHM_ALL "rmfixlnwaWtToOsAIcCqFSu" // all possible flags for 'shm' #define SHM_LEN 30 // max length of all flags together // plus a NUL character @@ -364,9 +365,10 @@ typedef enum { #define STL_USER_HL '*' // highlight from (User)1..9 or 0 #define STL_HIGHLIGHT '#' // highlight name #define STL_LINEBREAK '@' // insert a line break +#define STL_CLICKFUNC '[' // click handler region #define STL_TABPAGENR 'T' // tab page label nr #define STL_TABCLOSENR 'X' // tab page close nr -#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaNS{#@") +#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaNS{#@[") // flags used for parsed 'wildmode' #define WIM_FULL 0x01 @@ -374,6 +376,7 @@ typedef enum { #define WIM_LIST 0x04 #define WIM_BUFLASTUSED 0x08 #define WIM_NOSELECT 0x10 +#define WIM_NOINSERT 0x20 // flags for the 'wildoptions' option // each defined char should be unique over all values. @@ -823,6 +826,7 @@ EXTERN char_u *p_msm; // 'mkspellmem' EXTERN int p_ml; // 'modeline' EXTERN int p_mle; // 'modelineexpr' EXTERN long p_mls; // 'modelines' +EXTERN int p_mlstr; // 'modelinestrict' EXTERN int p_ma; // 'modifiable' #ifdef FEAT_GUI_MACVIM EXTERN int p_mmta; // 'macmeta' @@ -921,6 +925,7 @@ EXTERN long p_sj; // 'scrolljump' EXTERN int p_scf; // 'scrollfocus' #endif EXTERN long p_so; // 'scrolloff' +EXTERN long p_sop; // 'scrolloffpad' EXTERN char_u *p_sbo; // 'scrollopt' EXTERN char_u *p_sections; // 'sections' EXTERN int p_secure; // 'secure' @@ -1047,6 +1052,7 @@ EXTERN unsigned tc_flags; // flags from 'tagcase' EXTERN long p_tl; // 'taglength' EXTERN int p_tr; // 'tagrelative' EXTERN char_u *p_tags; // 'tags' +EXTERN int p_tagsecure; // 'tagsecure' EXTERN int p_tgst; // 'tagstack' #if defined(DYNAMIC_TCL) EXTERN char_u *p_tcldll; // 'tcldll' @@ -1177,9 +1183,6 @@ EXTERN long p_wmw; // 'winminwidth' EXTERN long p_wiw; // 'winwidth' #ifdef FEAT_WAYLAND EXTERN char_u *p_wse; // 'wlseat' -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -EXTERN int p_wst; // 'wlsteal' -# endif EXTERN long p_wtm; // 'wltimeoutlen' #endif #if defined(MSWIN) && defined(FEAT_TERMINAL) @@ -1405,6 +1408,7 @@ enum , WV_SMS , WV_SISO , WV_SO + , WV_SOP #ifdef FEAT_SPELL , WV_SPELL #endif diff --git a/src/optiondefs.h b/src/optiondefs.h index 1bf67a8ce6..adfbea22b2 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -212,6 +212,7 @@ #define PV_SMS OPT_WIN(WV_SMS) #define PV_SISO OPT_BOTH(OPT_WIN(WV_SISO)) #define PV_SO OPT_BOTH(OPT_WIN(WV_SO)) +#define PV_SOP OPT_BOTH(OPT_WIN(WV_SOP)) #ifdef FEAT_SPELL # define PV_SPELL OPT_WIN(WV_SPELL) #endif @@ -315,7 +316,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,E:DiffTextAdd,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,k:PmenuMatch,<:PmenuMatchSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,j:PmenuBorder,H:PmenuShadow,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea,h:ComplMatchIns,%:TabPanel,^:TabPanelSel,&:TabPanelFill,I:PreInsert" +#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,|:VertSplitNC,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,E:DiffTextAdd,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,k:PmenuMatch,<:PmenuMatchSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,j:PmenuBorder,H:PmenuShadow,p:Popup,J:PopupBorder,Q:PopupTitle,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea,h:ComplMatchIns,%:TabPanel,^:TabPanelSel,&:TabPanelFill,I:PreInsert" // Default python version for pyx* commands #if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) @@ -1895,6 +1896,9 @@ static struct vimoption options[] = {"modelines", "mls", P_NUM|P_VI_DEF, (char_u *)&p_mls, PV_NONE, NULL, NULL, {(char_u *)5L, (char_u *)0L} SCTX_INIT}, + {"modelinestrict", "mlst", P_BOOL|P_VI_DEF|P_SECURE, + (char_u *)&p_mlstr, PV_NONE, NULL, NULL, + {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"modifiable", "ma", P_BOOL|P_VI_DEF|P_NOGLOB, (char_u *)&p_ma, PV_MA, did_set_modifiable, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, @@ -2373,6 +2377,9 @@ static struct vimoption options[] = {"scrolloff", "so", P_NUM|P_VI_DEF|P_VIM|P_RALL, (char_u *)&p_so, PV_SO, NULL, NULL, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, + {"scrolloffpad", "sop", P_NUM|P_VI_DEF|P_VIM|P_RALL, + (char_u *)&p_sop, PV_SOP, NULL, NULL, + {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"scrollopt", "sbo", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, (char_u *)&p_sbo, PV_NONE, did_set_scrollopt, expand_set_scrollopt, {(char_u *)"ver,jump", (char_u *)0L} @@ -2426,7 +2433,7 @@ static struct vimoption options[] = (char_u *)0L} SCTX_INIT}, {"shellpipe", "sp", P_STRING|P_VI_DEF|P_SECURE, #ifdef FEAT_QUICKFIX - (char_u *)&p_sp, PV_NONE, NULL, NULL, + (char_u *)&p_sp, PV_NONE, did_set_shellpipe_redir, NULL, { # if defined(UNIX) (char_u *)"| tee", @@ -2443,7 +2450,7 @@ static struct vimoption options[] = (char_u *)&p_shq, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"shellredir", "srr", P_STRING|P_VI_DEF|P_SECURE, - (char_u *)&p_srr, PV_NONE, NULL, NULL, + (char_u *)&p_srr, PV_NONE, did_set_shellpipe_redir, NULL, {(char_u *)">", (char_u *)0L} SCTX_INIT}, {"shellslash", "ssl", P_BOOL|P_VI_DEF, #ifdef BACKSLASH_IN_FILENAME @@ -2741,6 +2748,9 @@ static struct vimoption options[] = (char_u *)"./tags,tags", #endif (char_u *)0L} SCTX_INIT}, + {"tagsecure", "tsc", P_BOOL|P_VI_DEF|P_SECURE, + (char_u *)&p_tagsecure, PV_NONE, NULL, NULL, + {(char_u *)TRUE, (char_u *)TRUE} SCTX_INIT}, {"tagstack", "tgst", P_BOOL|P_VI_DEF, (char_u *)&p_tgst, PV_NONE, NULL, NULL, {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, @@ -3149,14 +3159,9 @@ static struct vimoption options[] = {(char_u *)NULL, (char_u *)0L} #endif SCTX_INIT}, - {"wlsteal", "wst", P_BOOL|P_VI_DEF, -#ifdef FEAT_WAYLAND_CLIPBOARD_FS - (char_u *)&p_wst, PV_NONE, did_set_wlsteal, NULL, - {(char_u *)FALSE, (char_u *)0L} -#else + {"wlsteal", "wst", P_BOOL|P_VI_DEF, // Deprecated (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)NULL, (char_u *)0L} -#endif SCTX_INIT}, {"wltimeoutlen", "wtm", P_NUM|P_VI_DEF, #ifdef FEAT_WAYLAND diff --git a/src/optionstr.c b/src/optionstr.c index f687a60967..506b0c6f91 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -30,7 +30,7 @@ static char *(p_briopt_values[]) = {"shift:", "min:", "sbr", "list:", "column:", #endif #if defined(FEAT_TABPANEL) // Note: Keep this in sync with tabpanelopt_changed() -static char *(p_tplo_values[]) = {"align:", "columns:", "vert", NULL}; +static char *(p_tplo_values[]) = {"align:", "columns:", "scrollbar", "vert", NULL}; static char *(p_tplo_align_values[]) = {"left", "right", NULL}; #endif #if defined(FEAT_DIFF) @@ -73,11 +73,11 @@ static char *(p_kpc_protocol_values[]) = {"none", "mok2", "kitty", NULL}; #ifdef FEAT_PROP_POPUP // Note: Keep this in sync with parse_popup_option() static char *(p_popup_cpp_option_values[]) = {"align:", "border:", - "borderhighlight:", "close:", "height:", "highlight:", "resize:", - "shadow:", "width:", NULL}; + "borderhighlight:", "close:", "height:", "highlight:", "opacity:", + "resize:", "shadow:", "width:", NULL}; static char *(p_popup_pvp_option_values[]) = {"border:", - "borderhighlight:", "close:", "height:", "highlight:", "resize:", - "shadow:", "width:", NULL}; + "borderhighlight:", "close:", "height:", "highlight:", "opacity:", + "resize:", "shadow:", "width:", NULL}; static char *(p_popup_option_on_off_values[]) = {"on", "off", NULL}; static char *(p_popup_cpp_border_values[]) = {"single", "double", "round", "ascii", "on", "off", "custom:", NULL}; @@ -116,7 +116,7 @@ static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm" #endif static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", "none", "NONE", NULL}; // Note: Keep this in sync with check_opt_wim() -static char *(p_wim_values[]) = {"full", "longest", "list", "lastused", "noselect", NULL}; +static char *(p_wim_values[]) = {"full", "longest", "list", "lastused", "noselect", "noinsert", NULL}; static char *(p_wop_values[]) = {"fuzzy", "tagfile", "pum", "exacttext", NULL}; #ifdef FEAT_WAK static char *(p_wak_values[]) = {"yes", "menu", "no", NULL}; @@ -671,8 +671,30 @@ check_stl_option(char_u *s) if (!*s) break; s++; + if (*s == STL_CLICKFUNC) + { + if (s[1] == ']') + { + // %[] - end click region + s += 2; + continue; + } + if (ASCII_ISALPHA(s[1]) || s[1] == '_') + { + // %[FuncName] - start click region + char_u *rb = vim_strchr(s + 2, ']'); + if (rb != NULL) + { + s = rb + 1; + continue; + } + } + // Bare %[ is invalid + return illegal_char(errbuf, errbuflen, *s); + } if (*s == STL_LINEBREAK) { + // Plain %@ - line break s++; continue; } @@ -694,6 +716,32 @@ check_stl_option(char_u *s) s++; if (*s == STL_USER_HL) continue; + if (*s == STL_CLICKFUNC) + { + // %N[FuncName] or %N[] + if (s[1] == ']') + { + s += 2; + continue; + } + if (ASCII_ISALPHA(s[1]) || s[1] == '_') + { + char_u *rb = vim_strchr(s + 2, ']'); + if (rb != NULL) + { + s = rb + 1; + continue; + } + } + // Bare %N[ is invalid + return illegal_char(errbuf, errbuflen, *s); + } + if (*s == STL_LINEBREAK) + { + // %N@ - line break + s++; + continue; + } if (*s == '.') { s++; @@ -1374,7 +1422,7 @@ did_set_buftype(optset_T *args UNUSED) if (curwin->w_status_height) { - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; redraw_later(UPD_VALID); } curbuf->b_help = (curbuf->b_p_bt[0] == 'h'); @@ -4141,6 +4189,43 @@ expand_set_sessionoptions( } #endif +/* + * Validate 'shellpipe'/'shellredir' option. + */ + char * +did_set_shellpipe_redir(optset_T *args) +{ + char_u *p; + bool seen = false; + + for (p = args->os_newval.string; *p != NUL; ++p) + { + if (*p != '%') + continue; + + if (p[1] == NUL) + return e_invalid_format_string_single_percent_s; + + if (p[1] == '%') + { + ++p; // skip second % + continue; + } + + if (p[1] == 's') + { + if (seen) + return e_invalid_format_string_single_percent_s; + + seen = true; + ++p; // consume 's' + continue; + } + return e_invalid_format_string_single_percent_s; + } + return NULL; +} + /* * The 'shortmess' option is changed. */ @@ -4346,6 +4431,10 @@ expand_set_spellsuggest(optexpand_T *args, int *numMatches, char_u ***matches) char * did_set_splitkeep(optset_T *args UNUSED) { + win_T *wp; + tabpage_T *tp; + FOR_ALL_TAB_WINDOWS(tp, wp) + wp->w_prev_height = wp->w_height; return did_set_opt_strings(p_spk, p_spk_values, FALSE); } @@ -5385,7 +5474,7 @@ do_filetype_autocmd(char_u **varp, int opt_flags, int value_changed) secure = 0; ++ft_recursive; - curbuf->b_did_filetype = TRUE; + curbuf->b_did_filetype = true; // Only pass TRUE for "force" when the value changed or not // used recursively, to avoid endless recurrence. apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname, @@ -5573,7 +5662,7 @@ did_set_string_option( if (curwin->w_curswant != MAXCOL && (get_option_flags(opt_idx) & (P_CURSWANT | P_RALL)) != 0 && (get_option_flags(opt_idx) & P_HLONLY) == 0) - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; if ((opt_flags & OPT_NO_REDRAW) == 0) { diff --git a/src/os_amiga.h b/src/os_amiga.h index 1407613744..257972012b 100644 --- a/src/os_amiga.h +++ b/src/os_amiga.h @@ -11,7 +11,6 @@ */ #define CASE_INSENSITIVE_FILENAME // ignore case when comparing file names -#define SPACE_IN_FILENAME #define USE_FNAME_CASE // adjust case of file names #define USE_TERM_CONSOLE #define HAVE_AVAIL_MEM diff --git a/src/os_dos.h b/src/os_dos.h index f53434824e..72a876755f 100644 --- a/src/os_dos.h +++ b/src/os_dos.h @@ -109,7 +109,6 @@ #define CLEAN_RUNTIMEPATH "$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after" #define CASE_INSENSITIVE_FILENAME // ignore case when comparing file names -#define SPACE_IN_FILENAME #define BACKSLASH_IN_FILENAME #define USE_CRNL // lines end in CR-NL instead of NL #define HAVE_DUP // have dup() diff --git a/src/os_mac.h b/src/os_mac.h index 930dcd9593..8ea2c9d64a 100644 --- a/src/os_mac.h +++ b/src/os_mac.h @@ -74,7 +74,6 @@ #define USE_EXE_NAME // to find $VIM #define CASE_INSENSITIVE_FILENAME // ignore case when comparing file names -#define SPACE_IN_FILENAME #define USE_FNAME_CASE // make ":e os_Mac.c" open the file in its // original case, as "os_mac.c" diff --git a/src/os_mswin.c b/src/os_mswin.c index 6eaf84f6ce..bfd0f1a386 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -2658,32 +2658,30 @@ struct charset_pair BYTE charset; }; -# define STRING_INIT(s) \ - {(char_u *)(s), STRLEN_LITERAL(s)} static struct charset_pair charset_pairs[] = { - {STRING_INIT("ANSI"), ANSI_CHARSET}, - {STRING_INIT("CHINESEBIG5"), CHINESEBIG5_CHARSET}, - {STRING_INIT("DEFAULT"), DEFAULT_CHARSET}, - {STRING_INIT("HANGEUL"), HANGEUL_CHARSET}, - {STRING_INIT("OEM"), OEM_CHARSET}, - {STRING_INIT("SHIFTJIS"), SHIFTJIS_CHARSET}, - {STRING_INIT("SYMBOL"), SYMBOL_CHARSET}, - {STRING_INIT("ARABIC"), ARABIC_CHARSET}, - {STRING_INIT("BALTIC"), BALTIC_CHARSET}, - {STRING_INIT("EASTEUROPE"), EASTEUROPE_CHARSET}, - {STRING_INIT("GB2312"), GB2312_CHARSET}, - {STRING_INIT("GREEK"), GREEK_CHARSET}, - {STRING_INIT("HEBREW"), HEBREW_CHARSET}, - {STRING_INIT("JOHAB"), JOHAB_CHARSET}, - {STRING_INIT("MAC"), MAC_CHARSET}, - {STRING_INIT("RUSSIAN"), RUSSIAN_CHARSET}, - {STRING_INIT("THAI"), THAI_CHARSET}, - {STRING_INIT("TURKISH"), TURKISH_CHARSET} + {STR_LITERAL_INIT("ANSI"), ANSI_CHARSET}, + {STR_LITERAL_INIT("CHINESEBIG5"), CHINESEBIG5_CHARSET}, + {STR_LITERAL_INIT("DEFAULT"), DEFAULT_CHARSET}, + {STR_LITERAL_INIT("HANGEUL"), HANGEUL_CHARSET}, + {STR_LITERAL_INIT("OEM"), OEM_CHARSET}, + {STR_LITERAL_INIT("SHIFTJIS"), SHIFTJIS_CHARSET}, + {STR_LITERAL_INIT("SYMBOL"), SYMBOL_CHARSET}, + {STR_LITERAL_INIT("ARABIC"), ARABIC_CHARSET}, + {STR_LITERAL_INIT("BALTIC"), BALTIC_CHARSET}, + {STR_LITERAL_INIT("EASTEUROPE"), EASTEUROPE_CHARSET}, + {STR_LITERAL_INIT("GB2312"), GB2312_CHARSET}, + {STR_LITERAL_INIT("GREEK"), GREEK_CHARSET}, + {STR_LITERAL_INIT("HEBREW"), HEBREW_CHARSET}, + {STR_LITERAL_INIT("JOHAB"), JOHAB_CHARSET}, + {STR_LITERAL_INIT("MAC"), MAC_CHARSET}, + {STR_LITERAL_INIT("RUSSIAN"), RUSSIAN_CHARSET}, + {STR_LITERAL_INIT("THAI"), THAI_CHARSET}, + {STR_LITERAL_INIT("TURKISH"), TURKISH_CHARSET} # ifdef VIETNAMESE_CHARSET , - {STRING_INIT("VIETNAMESE"), VIETNAMESE_CHARSET} + {STR_LITERAL_INIT("VIETNAMESE"), VIETNAMESE_CHARSET} # endif }; @@ -2696,23 +2694,22 @@ struct quality_pair static struct quality_pair quality_pairs[] = { # ifdef CLEARTYPE_QUALITY - {STRING_INIT("CLEARTYPE"), CLEARTYPE_QUALITY}, + {STR_LITERAL_INIT("CLEARTYPE"), CLEARTYPE_QUALITY}, # endif # ifdef ANTIALIASED_QUALITY - {STRING_INIT("ANTIALIASED"), ANTIALIASED_QUALITY}, + {STR_LITERAL_INIT("ANTIALIASED"), ANTIALIASED_QUALITY}, # endif # ifdef NONANTIALIASED_QUALITY - {STRING_INIT("NONANTIALIASED"), NONANTIALIASED_QUALITY}, + {STR_LITERAL_INIT("NONANTIALIASED"), NONANTIALIASED_QUALITY}, # endif # ifdef PROOF_QUALITY - {STRING_INIT("PROOF"), PROOF_QUALITY}, + {STR_LITERAL_INIT("PROOF"), PROOF_QUALITY}, # endif # ifdef DRAFT_QUALITY - {STRING_INIT("DRAFT"), DRAFT_QUALITY}, + {STR_LITERAL_INIT("DRAFT"), DRAFT_QUALITY}, # endif - {STRING_INIT("DEFAULT"), DEFAULT_QUALITY} + {STR_LITERAL_INIT("DEFAULT"), DEFAULT_QUALITY} }; -# undef STRING_INIT /* * Convert a charset ID to a name. diff --git a/src/os_unix.c b/src/os_unix.c index e65bf88dc4..4b9b804e2f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -147,123 +147,6 @@ Window x11_window = 0; Display *x11_display = NULL; #endif -#if defined(FEAT_SOCKETSERVER) -# include -# include - -# define SOCKET_SERVER_MAX_BACKLOG 5 -# define SOCKET_SERVER_MAX_CMD_SIZE 16384 -# define SOCKET_SERVER_MAX_MSG 6 - -static int socket_server_fd = -1; -static char_u *socket_server_path = NULL; - -typedef enum { - SS_MSG_TYPE_ENCODING = 'e', // Encoding of message. - SS_MSG_TYPE_STRING = 'c', // Script to execute or reply string. - SS_MSG_TYPE_SERIAL = 's', // Serial of pending command - SS_MSG_TYPE_CODE = 'r', // Result code for an expression sent - SS_MSG_TYPE_SENDER = 'd' // Location of socket for the client that - // sent the command. -} ss_msg_type_T; - -typedef enum { - SS_CMD_TYPE_EXPR = 'E', // An expression - SS_CMD_TYPE_KEYSTROKES = 'K', // Series of keystrokes - SS_CMD_TYPE_REPLY = 'R', // Reply from an expression - SS_CMD_TYPE_NOTIFY = 'N', // A notification - SS_CMD_TYPE_ALIVE = 'A', // Check if server is still responsive -} ss_cmd_type_T; - -// Represents a message in a command. A command can contain multiple messages. -// Each message starts with a single byte representing the type, then a uint32 -// representing the length of the contents, and then the actual contents. -// Everything is in native byte order. -// -// While contents may contain NULL characters, such as when it is a number, it -// is always NULL terminated. Note that the NULL terminator does not count in -// the length. -typedef struct { - char_u msg_type; // Type of message - uint32_t msg_len; // Total length of contents - char_u *msg_contents; // Actual contents of message -} ss_msg_T; - -// Represents a command sent over a socket. Each socket starts with a byte -// representing the type, then a uint32 representing the number of messages, -// then a uint32 representing the total size of the messages in bytes, and then -// the actual messages. Everything is in native byte order. -typedef struct { - char_u cmd_type; // Type of command - uint32_t cmd_num; // Number of messages - uint32_t cmd_len; // Combined size of all - // messages - ss_msg_T cmd_msgs[SOCKET_SERVER_MAX_MSG]; // Array of messages -} ss_cmd_T; - -# define SS_CMD_INFO_SIZE (sizeof(char_u) + (sizeof(uint32_t) * 2)) -# define SS_MSG_INFO_SIZE (sizeof(char_u) + sizeof(uint32_t)) - -// Represents a pending reply from a command sent to a Vim server. When a -// command is sent out, we generate unique serial number with it. When we -// receive any reply, we check which pending command has a matching serial -// number, and is therefore the reply for that pending command. -// -// The reason we just don't use the existing fd created by the connect() call, -// and communicate using that, is that it can't handle recursive calls, ex: -// call remote_expr('B', 'remote_expr("A", "")') -// -// This idea is taken from the existing X server functionality -typedef struct ss_pending_cmd_S { - uint32_t serial; // Serial number expected in result - char_u code; // Result code, can be 0 or -1. - char_u *result; // Result of command - - struct ss_pending_cmd_S *next; // Next in list -} ss_pending_cmd_T; - -static ss_pending_cmd_T *ss_pending_cmds; - -// Serial is always greater than zero -static uint32_t ss_serial = 0; - -// Represents a reply from a server2client call. Each client that calls a -// server2client call to us has its own ss_reply_T. Each time a client sends -// data using server2client, Vim creates a ss_reply_T if it doesn't exist and -// adds the string to the array. When remote_read is called, the server id is -// used to find the specific ss_reply_T, and a single string is popped from the -// array. -// -// This idea is taken from the existing X server functionality -typedef struct { - char_u *sender; - garray_T strings; -} ss_reply_T; - -static garray_T ss_replies; - -static char_u *socket_server_get_path_from_name(char_u *name); -static int socket_server_connect(char_u *name, char_u **path, int silent); -static void socket_server_init_pending_cmd(ss_pending_cmd_T *pending); -static void socket_server_pop_pending_cmd(ss_pending_cmd_T *pending); -static void socket_server_init_cmd(ss_cmd_T *cmd, ss_cmd_type_T type); -static int socket_server_append_msg(ss_cmd_T *cmd, char_u type, - char_u *contents, int len); -static void socket_server_free_cmd(ss_cmd_T *cmd); -static char_u *socket_server_encode_cmd(ss_cmd_T *cmd, size_t *sz); -static int socket_server_decode_cmd(ss_cmd_T *cmd, int socket_fd, int timeout); -static int socket_server_write(int sock_fd, char_u *data, size_t sz, - int timeout); -static ss_reply_T *socket_server_get_reply(char_u *sender, int *index); -static ss_reply_T *socket_server_add_reply(char_u *sender); -static void socket_server_remove_reply(char_u *sender); -static void socket_server_exec_cmd(ss_cmd_T *cmd, int fd); -static int socket_server_dispatch(int timeout); -static int socket_server_check_alive(char_u *name); -static int socket_server_name_is_valid(char_u *name); - -#endif // FEAT_SOCKETSERVER - static int ignore_sigtstp = FALSE; static int get_x11_title(int); @@ -3788,10 +3671,6 @@ mch_exit(int r) x11_export_final_selection(); #endif -#ifdef FEAT_SOCKETSERVER - socket_server_uninit(); -#endif - #ifdef FEAT_GUI if (!gui.in_use) #endif @@ -5981,7 +5860,11 @@ mch_get_cmd_output_direct( } BLOCK_SIGNALS(&curset); +# ifdef VMS + pid = 0; // VMS does not have fork +# else pid = fork(); +# endif if (pid == -1) { UNBLOCK_SIGNALS(&curset); @@ -6819,9 +6702,6 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted) // each channel may use in, out and err struct pollfd fds[7 + 3 * MAX_OPEN_CHANNELS]; int nfd; -# ifdef FEAT_SOCKETSERVER - int socket_server_idx = -1; -# endif # ifdef FEAT_WAYLAND_CLIPBOARD int wayland_idx = -1; # endif @@ -6848,16 +6728,6 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted) fds[0].events = POLLIN; nfd = 1; -# ifdef FEAT_SOCKETSERVER - if (socket_server_fd != -1) - { - socket_server_idx = nfd; - fds[nfd].fd = socket_server_fd; - fds[nfd].events = POLLIN; - nfd++; - } -# endif - # ifdef FEAT_WAYLAND if ((wayland_fd = wayland_prepare_read()) >= 0) { @@ -6913,19 +6783,6 @@ RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted) finished = FALSE; # endif -# ifdef FEAT_SOCKETSERVER - if (socket_server_idx >= 0) - { - if (fds[socket_server_idx].revents & POLLIN) - { - if (socket_server_accept_client() == FAIL) - socket_server_uninit(); - } - else if (fds[socket_server_idx].revents & (POLLHUP | POLLERR)) - socket_server_uninit(); - } -# endif - # ifdef FEAT_WAYLAND if (wayland_idx >= 0) wayland_poll_check(fds[wayland_idx].revents); @@ -7011,16 +6868,6 @@ select_eintr: # endif maxfd = fd; -# ifdef FEAT_SOCKETSERVER - if (socket_server_fd != -1) - { - FD_SET(socket_server_fd, &rfds); - - if (maxfd < socket_server_fd) - maxfd = socket_server_fd; - } -# endif - # ifdef FEAT_WAYLAND if ((wayland_fd = wayland_prepare_read()) >= 0) { @@ -7120,13 +6967,6 @@ select_eintr: finished = FALSE; # endif -# ifdef FEAT_SOCKETSERVER - if (ret > 0 && socket_server_fd != -1 - && FD_ISSET(socket_server_fd, &rfds) - && socket_server_accept_client() == FAIL) - socket_server_uninit(); -# endif - # ifdef FEAT_WAYLAND if (wayland_fd != -1) wayland_select_check(ret > 0 && FD_ISSET(wayland_fd, &rfds)); @@ -7188,16 +7028,9 @@ select_eintr: if (finished || msec == 0) break; -# if defined(FEAT_CLIENTSERVER) && !defined(MAC_CLIENTSERVER) -# ifdef FEAT_X11 +# if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) && !defined(MAC_CLIENTSERVER) if (clientserver_method == CLIENTSERVER_METHOD_X11 && server_waiting()) break; -# endif -# ifdef FEAT_SOCKETSERVER - if (clientserver_method == CLIENTSERVER_METHOD_SOCKET && - socket_server_waiting_accept()) - break; -# endif # endif // We're going to loop around again, find out for how long @@ -7291,13 +7124,10 @@ mch_expand_wildcards( int check_spaces; static int did_find_nul = FALSE; int ampersand = FALSE; -# define STRING_INIT(s) \ - {(char_u *)(s), STRLEN_LITERAL(s)} // vimglob() function to define for Posix shell - static string_T sh_vimglob_func = STRING_INIT("vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >"); + static string_T sh_vimglob_func = STR_LITERAL_INIT("vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >"); // vimglob() function with globstar setting enabled, only for bash >= 4.X - static string_T sh_globstar_opt = STRING_INIT("[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; "); -# undef STRING_INIT + static string_T sh_globstar_opt = STR_LITERAL_INIT("[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; "); *num_file = 0; // default: no files found @@ -9281,1565 +9111,3 @@ mch_create_anon_file(void) } return fd; } - -#if defined(FEAT_SOCKETSERVER) - -/* - * Initialize socket server called "name" (the socket filename). If "name" is a - * path (starts with a '/', './', or '../'), it is assumed to be the path to - * the desired socket. If the socket path is already taken, append an - * incrementing number to the path until we find a socket filename that can be - * used. If NULL is passed as the name, the previous socket path is used (only - * if not NULL). Returns OK on success and FAIL on failure. - */ - int -socket_server_init(char_u *name) -{ - struct sockaddr_un addr; - char_u *path; - int num_printed; - int fd; - int i = 1; - - if (socket_server_valid() || (name == NULL && socket_server_path == NULL)) - return FAIL; - if (name == NULL) - name = socket_server_path; - - path = alloc(sizeof(addr.sun_path)); - - if (path == NULL) - return FAIL; - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - - if (fd == -1) - { - vim_free(path); - return FAIL; - } - - addr.sun_family = AF_UNIX; - - // If name is not a path, find a common directory to place the - // socket. - if (name[0] == '/' || STRNCMP(name, "./", 2) == 0 || - STRNCMP(name, "../", 3) == 0) - num_printed = - vim_snprintf((char *)path, sizeof(addr.sun_path), "%s", name); - else - { - const char_u *dir; - char_u *buf; - - // Check if there are slashes in the name - if (vim_strchr(name, '/') != NULL) - { - emsg(_(e_socket_name_no_slashes)); - goto fail; - } - - dir = mch_getenv("XDG_RUNTIME_DIR"); - - if (dir == NULL) - { - // Use $TMPDIR or /tmp if $XDG_RUNTIME_DIR is not set. - const char_u *tmpdir = mch_getenv("TMPDIR"); - size_t sz; - - if (tmpdir != NULL) - dir = tmpdir; - else - dir = (char_u *)"/tmp"; - - sz = STRLEN(dir) + 25; - buf = alloc(sz); - - if (buf == NULL) - goto fail; - - vim_snprintf((char *)buf, sz, "%s/vim-%lu", dir, - (unsigned long int)getuid()); - } - else - { - buf = alloc(STRLEN(dir) + STRLEN("vim") + 2); - - if (buf == NULL) - goto fail; - - sprintf((char *)buf, "%s/vim", dir); - } - - // Always set directory permissions to 0700 for security - if (vim_mkdir(buf, 0700) == -1 && errno != EEXIST) - { - semsg(_("Failed creating socket directory: %s"), strerror(errno)); - vim_free(buf); - goto fail; - } - - num_printed = vim_snprintf((char *)path, sizeof(addr.sun_path), - "%s/%s", buf, name); - - vim_free(buf); - } - - // Check if path was too big - if ((size_t)num_printed >= sizeof(addr.sun_path)) - { - emsg(_(e_socket_path_too_big)); - goto fail; - } - - vim_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); - - // Bind to a suitable path/address - while (i < 1000) - { - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) - == -1) - { - int fd2; - - if (errno != EADDRINUSE) - { - emsg(_(e_socket_server_unavailable)); - goto fail; - } - - // If the socket is dead, remove it and try again - fd2 = socket_server_connect((char_u *)addr.sun_path, NULL, TRUE); - - if (fd2 == -1) - { - mch_remove(addr.sun_path); - continue; - } - else - close(fd2); - } - else - break; - - num_printed = vim_snprintf(addr.sun_path, sizeof(addr.sun_path), - "%s%d", path, i); - - if ((size_t)num_printed >= sizeof(addr.sun_path)) - { - // Address too big - emsg(_(e_socket_path_too_big)); - goto fail; - } - - i++; - } - - if (i >= 1000) - { - emsg(_(e_socket_server_unavailable)); - goto fail; - } - - // Start listening for connections - if (listen(fd, SOCKET_SERVER_MAX_BACKLOG) == -1) - goto fail; - - // Set global path and vvar to the absolute path - if ((socket_server_path = alloc(MAXPATHL)) == NULL) - goto fail; - - socket_server_path[0] = NUL; - - if (mch_FullName((char_u *)addr.sun_path, socket_server_path, - MAXPATHL, FALSE) == FAIL) - { - vim_free(socket_server_path); - goto fail; - } - - serverName = vim_strsave(socket_server_path); -# ifdef FEAT_EVAL - set_vim_var_string(VV_SEND_SERVER, serverName, -1); -# endif - - socket_server_fd = fd; - -# ifdef FEAT_GUI_GTK - if (gui.in_use) - // Initialize source for GUI if we are using it - gui_gtk_init_socket_server(); -# endif - - vim_free(path); - return OK; -fail: - close(fd); - vim_free(path); - socket_server_uninit(); - return FAIL; -} - - void -socket_server_uninit(void) -{ - if (socket_server_fd != -1) - { - close(socket_server_fd); - socket_server_fd = -1; - } - - if (socket_server_path != NULL) - { - mch_remove(socket_server_path); - vim_free(socket_server_path); - socket_server_path = NULL; - } -# ifdef FEAT_GUI_GTK - if (gui.in_use) - gui_gtk_uninit_socket_server(); -# endif -} - -/* - * List available sockets that can be connected to, only in common directories - * that Vim knows about. Vim instances with custom socket paths will not be - * detected. Returns a newline separated string on success and NULL on failure. - */ - char_u * -socket_server_list_sockets(void) -{ - garray_T str; - string_T buf; - string_T path; - DIR *dirp; - struct dirent *dp; - struct sockaddr_un addr; - char_u *known_dirs[] = { - mch_getenv("XDG_RUNTIME_DIR"), - mch_getenv("TMPDIR"), - (char_u *)"/tmp" - }; - - if ((buf.string = alloc(sizeof(addr.sun_path))) == NULL) - return NULL; - if ((path.string = alloc(sizeof(addr.sun_path))) == NULL) - { - vim_free(buf.string); - return NULL; - } - buf.length = 0; - path.length = 0; - - ga_init2(&str, 1, 100); - - for (size_t i = 0 ; i < ARRAY_LENGTH(known_dirs); i++) - { - char_u *dir = known_dirs[i]; - - if (dir == NULL) - continue; - - if (STRCMP(dir, "/tmp") == 0 || - (known_dirs[1] != NULL && STRCMP(dir, known_dirs[1]) == 0)) - path.length = vim_snprintf_safelen((char *)path.string, sizeof(addr.sun_path), - "%s/vim-%lu", dir, (unsigned long int)getuid()); - else - path.length = vim_snprintf_safelen((char *)path.string, sizeof(addr.sun_path), - "%s/vim", dir); - - dirp = opendir((char *)path.string); - if (dirp == NULL) - continue; - - // Loop through directory - while ((dp = readdir(dirp)) != NULL) - { - if (STRCMP(dp->d_name, ".") == 0 || STRCMP(dp->d_name, "..") == 0) - continue; - - buf.length = vim_snprintf_safelen((char *)buf.string, sizeof(addr.sun_path), - "%s/%s", path.string, dp->d_name); - - // Don't want to send to ourselves, but we do want to list our - // server name (if we are a server). - if (socket_server_path == NULL - || STRCMP(socket_server_path, buf.string) != 0) - { - // Try sending an ALIVE command. This is more assuring than a - // simple connect, and *also seems to make tests less flaky*. - // - // We could also use a lock file which may be better, but this - // has worked fine so far... - 64bitman - if (!socket_server_check_alive(buf.string)) - continue; - } - - ga_concat_len(&str, (char_u *)dp->d_name, buf.length - (path.length + 1)); - ga_append(&str, '\n'); - } - - closedir(dirp); - - break; - } - - vim_free(path.string); - vim_free(buf.string); - - ga_append(&str, NUL); - - return str.ga_data; -} - -/* - * Called when the server has received a new command. If so, parse it and do the - * stuff it says, and possibly send back a reply. Returns OK if client was - * accepted, else FAIL. - */ - int -socket_server_accept_client(void) -{ - int fd = accept(socket_server_fd, NULL, NULL); - ss_cmd_T cmd; - - if (fd == -1) - return FAIL; - - if (socket_server_decode_cmd(&cmd, fd, 1000) == FAIL) - goto exit; - -# ifdef FEAT_EVAL - ch_log(NULL, "accepted new client on socket %s", socket_server_path); -# endif - - socket_server_exec_cmd(&cmd, fd); - socket_server_free_cmd(&cmd); - -exit: - close(fd); - return OK; -} - -/* - * Check if socket server is able to be used - */ - int -socket_server_valid(void) -{ - return socket_server_fd != -1 && socket_server_path != NULL; -} - -/* - * If "name" is a pathless name such as "VIM", search known directories for the - * socket named "name", and return the alloc'ed path to it. If "name" starts - * with a '/', './' or '../', then a copy of "name" is returned. Returns NULL - * on failure or if no socket was found. - */ - static char_u * -socket_server_get_path_from_name(char_u *name) -{ - char_u *buf; - stat_T s; - const char_u *known_dirs[] = { - mch_getenv("XDG_RUNTIME_DIR"), - mch_getenv("TMPDIR"), - (char_u *)"/tmp" - }; - - if (name == NULL) - return NULL; - - // Ignore if name is a path - if (name[0] == '/' || STRNCMP(name, "./", 2) == 0 || - STRNCMP(name, "../", 3) == 0) - return vim_strsave(name); - - buf = alloc(MAXPATHL); - - if (buf == NULL) - return NULL; - - for (size_t i = 0; i < ARRAY_LENGTH(known_dirs); i++) - { - const char_u *dir = known_dirs[i]; - - if (dir == NULL) - continue; - else if (STRCMP(dir, "/tmp") == 0 || - (known_dirs[1] != NULL && STRCMP(dir, known_dirs[1]) == 0)) - vim_snprintf((char *)buf, MAXPATHL, "%s/vim-%lu/%s", dir, - (unsigned long int)getuid(), name); - else - vim_snprintf((char *)buf, MAXPATHL, "%s/vim/%s", dir, name); - - if (mch_stat((char *)buf,&s) == 0 && S_ISSOCK(s.st_mode)) - { - if (STRCMP(buf, socket_server_path) == 0) - // Can't connect to itself - break; - return buf; - } - } - - vim_free(buf); - return NULL; -} - -/* - * Send command to socket named "name". Returns 0 for OK, -1 on error. - */ - int -socket_server_send( - char_u *name, // Socket path or a general name - char_u *str, // What to send - char_u **result, // Set to result of expr - char_u **receiver, // Full path of "name" - int is_expr, // Is it an expression or keystrokes? - int timeout, // In milliseconds - int silent) // Don't complain if socket doesn't exist -{ - ss_cmd_T cmd; - int socket_fd; - size_t sz; - char_u *final; - char_u *path; -# ifdef ELAPSED_FUNC - elapsed_T start_tv; -# endif - - if (!socket_server_valid()) - { - emsg(_(e_socket_server_not_online)); - return -1; - } - - socket_fd = socket_server_connect(name, &path, silent); - - if (socket_fd == -1) - return -1; - -# ifdef FEAT_EVAL - ch_log(NULL, "socket_server_send(%s, %s)", path, str); -# endif - - // Execute locally if target is ourselves - if (serverName != NULL && STRICMP(path, serverName) == 0) - { - vim_free(path); - close(socket_fd); - return sendToLocalVim(str, is_expr, result); - } - - socket_server_init_cmd(&cmd, - is_expr ? SS_CMD_TYPE_EXPR : SS_CMD_TYPE_KEYSTROKES); - - socket_server_append_msg(&cmd, SS_MSG_TYPE_ENCODING, p_enc, STRLEN(p_enc)); - - // Add +1 in case of empty string - socket_server_append_msg(&cmd, SS_MSG_TYPE_STRING, str, STRLEN(str) + 1); - - // Tell server who we are so it can save our socket path internally for - // later use with server2client - socket_server_append_msg(&cmd, SS_MSG_TYPE_SENDER, socket_server_path, - STRLEN(socket_server_path)); - - if (is_expr) - { - ss_serial++; - socket_server_append_msg(&cmd, SS_MSG_TYPE_SERIAL, - (char_u *)&ss_serial, sizeof(ss_serial)); - } - - final = socket_server_encode_cmd(&cmd, &sz); - - if (final == NULL || - socket_server_write(socket_fd, final, sz, 1000) == FAIL) - { - if (final != NULL) - emsg(_(e_failed_to_send_command_to_destination_program)); - - vim_free(path); - socket_server_free_cmd(&cmd); - close(socket_fd); - vim_free(final); - return -1; - } - socket_server_free_cmd(&cmd); - vim_free(final); - - - close(socket_fd); - if (!is_expr) - { - if (receiver != NULL) - *receiver = path; - else - vim_free(path); - - // Exit, we aren't waiting for a response - return 0; - } - - ss_pending_cmd_T pending; - - socket_server_init_pending_cmd(&pending); - -# ifdef ELAPSED_FUNC - ELAPSED_INIT(start_tv); -# endif - - // Wait for server to send back result - while (socket_server_dispatch(500) >= 0) - { - if (pending.result != NULL) - break; - -# ifdef ELAPSED_FUNC - if (ELAPSED_FUNC(start_tv) >= (timeout > 0 ? timeout : 1000)) - break; -# endif - } - - if (pending.result == NULL) - { - socket_server_pop_pending_cmd(&pending); - vim_free(path); - return -1; - } - - if (result != NULL) - *result = pending.result; - else - vim_free(pending.result); - - if (receiver != NULL) - *receiver = path; - else - vim_free(path); - - socket_server_pop_pending_cmd(&pending); - - return pending.code == 0 ? 0 : -1; -} - -/* - * Wait for replies from "client" and place result in "str". Returns OK on - * success and FAIL on failure. Timeout is in milliseconds - */ - int -socket_server_read_reply(char_u *client, char_u **str, int timeout UNUSED) -{ - ss_reply_T *reply = NULL; -# ifdef ELAPSED_FUNC - elapsed_T start_tv; -# endif - - if (!socket_server_name_is_valid(client)) - return -1; - - if (!socket_server_valid()) - return -1; - -# ifdef ELAPSED_FUNC - if (timeout > 0) - ELAPSED_INIT(start_tv); -# endif - - // Try seeing if there already is a reply in the queue - goto get_reply; - - while (socket_server_dispatch(500) >= 0) - { - int fd; - -# ifdef ELAPSED_FUNC - if (timeout > 0 && ELAPSED_FUNC(start_tv) >= timeout) - break; -# endif - -get_reply: - reply = socket_server_get_reply(client, NULL); - - if (reply != NULL) - break; - - // Check if sender is down by connecting to it as a test. A simple - // connect will do. - fd = socket_server_connect(client, NULL, TRUE); - - if (fd == -1) - return FAIL; - else - close(fd); - } - - if (reply == NULL || reply->strings.ga_data == NULL || - reply->strings.ga_len <= 0) - { - return FAIL; - } - - // Consume the string - *str = ((char_u **)reply->strings.ga_data)[0]; - - for (int i = 1; i < reply->strings.ga_len; i++) - { - ((char_u **)reply->strings.ga_data)[i - 1] = - ((char_u **)reply->strings.ga_data)[i]; - } - reply->strings.ga_len--; - - if (reply->strings.ga_len < 1) - // Last string removed, remove the reply - socket_server_remove_reply(client); - - - return OK; -} - -/* - * Check for any replies for "sender". Returns 1 if there is and places the - * reply in "str" without consuming it. Returns 0 if otherwise and -1 on - * error. - */ - int -socket_server_peek_reply(char_u *sender, char_u **str) -{ - ss_reply_T *reply; - - if (!socket_server_name_is_valid(sender)) - return -1; - - if (!socket_server_valid()) - return 0; - - reply = socket_server_get_reply(sender, NULL); - - if (reply != NULL && reply->strings.ga_len > 0) - { - if (str != NULL) - *str = ((char_u **)reply->strings.ga_data)[0]; - return 1; - } - - return 0; -} - -/* - * Send a string to "client" as a reply (notification). Returns OK on success - * and FAIL on failure. - */ - int -socket_server_send_reply(char_u *client, char_u *str) -{ - int socket_fd; - ss_cmd_T cmd; - size_t sz; - char_u *final; - - if (!socket_server_name_is_valid(client)) - return FAIL; - - if (!socket_server_valid()) - { - emsg(_(e_socket_server_not_online)); - return FAIL; - } - - socket_fd = socket_server_connect(client, NULL, TRUE); - - if (socket_fd == -1) - return FAIL; - - socket_server_init_cmd(&cmd, SS_CMD_TYPE_NOTIFY); - - socket_server_append_msg(&cmd, SS_MSG_TYPE_ENCODING, p_enc, STRLEN(p_enc)); - socket_server_append_msg(&cmd, SS_MSG_TYPE_STRING, str, STRLEN(str)); - socket_server_append_msg(&cmd, SS_MSG_TYPE_SENDER, - socket_server_path, STRLEN(socket_server_path)); - - final = socket_server_encode_cmd(&cmd, &sz); - - if (final == NULL || - socket_server_write(socket_fd, final, sz, 1000) == FAIL) - { - socket_server_free_cmd(&cmd); - vim_free(final); - close(socket_fd); - return FAIL; - } - - socket_server_free_cmd(&cmd); - vim_free(final); - close(socket_fd); - - return OK; -} - -/* - * Connect to a socket using "name". "path" is set to the full path of "name" - * used to create the socket, only if its not NULL. Returns fd on success and -1 - * on failure. - */ - static int -socket_server_connect(char_u *name, char_u **path, int silent) -{ - int socket_fd; - int res; - struct sockaddr_un addr; - - char_u *socket_path = socket_server_get_path_from_name(name); - - if (socket_path == NULL) - { - if (!silent) - semsg(_(e_no_registered_server_named_str), name); - return -1; - } - if (STRLEN(socket_path) >= sizeof(addr.sun_path)) - { - // Path too big - vim_free(socket_path); - return -1; - } - - socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); - - if (socket_fd == -1) - { - vim_free(socket_path); - return -1; - } - - addr.sun_family = AF_UNIX; - vim_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socket_path); - - res = connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)); - - if (res == -1) - { - if (!silent) - semsg(_(e_socket_server_failed_connecting), socket_path, - strerror(errno)); - close(socket_fd); - vim_free(socket_path); - return -1; - } - - if (path != NULL) - *path = socket_path; - else - vim_free(socket_path); - - return socket_fd; - -} - -/* - * Add a new pending command to the list of pending commands. Returns OK on - * success and FAIL on failure - */ - static void -socket_server_init_pending_cmd(ss_pending_cmd_T *pending) -{ - pending->code = 0; - pending->result = NULL; - pending->serial = ss_serial; - pending->next = ss_pending_cmds; - ss_pending_cmds = pending; -} - -/* - * Remove pending command from the list, does not free the result string. - */ - static void -socket_server_pop_pending_cmd(ss_pending_cmd_T *pending) -{ - if (ss_pending_cmds == pending) - { - ss_pending_cmds = pending->next; - return; - } - - for (ss_pending_cmd_T *cmd = ss_pending_cmds; cmd != NULL; cmd = cmd->next) - { - if (cmd->next == pending) - { - cmd->next = pending->next; - return; - } - } -} - -/* - * Initialize command structure to empty state - */ - static void -socket_server_init_cmd(ss_cmd_T *cmd, ss_cmd_type_T type) -{ - cmd->cmd_len = 0; - cmd->cmd_num = 0; - cmd->cmd_type = type; -} - -/* - * Append a message to a command. Note that "len" is the length of contents. - * Returns OK on success and FAIL on failure - */ - static int -socket_server_append_msg(ss_cmd_T *cmd, char_u type, char_u *contents, int len) -{ - ss_msg_T *msg = cmd->cmd_msgs + cmd->cmd_num; - - if (cmd->cmd_num >= SOCKET_SERVER_MAX_MSG) - return FAIL; - - // Check if command will be too big. - if (SS_CMD_INFO_SIZE + cmd->cmd_len + SS_MSG_INFO_SIZE + len - > SOCKET_SERVER_MAX_CMD_SIZE) - return FAIL; - - msg->msg_contents = alloc(len); - - if (msg->msg_contents == NULL) - return FAIL; - - msg->msg_type = type; - msg->msg_len = len; - memcpy(msg->msg_contents, contents, len); - - cmd->cmd_len += SS_MSG_INFO_SIZE + len; - cmd->cmd_num++; - - return OK; -} - -/* - * Free all resources associated with a command object. - */ - static void -socket_server_free_cmd(ss_cmd_T *cmd) -{ - for (uint32_t i = 0; i < cmd->cmd_num; i++) - { - ss_msg_T *msg = cmd->cmd_msgs + i; - - vim_free(msg->msg_contents); - } -} - -/* - * Encode command struct and return the final message to send. Returns NULL on - * failure. - */ - static char_u * -socket_server_encode_cmd(ss_cmd_T *cmd, size_t *sz) -{ - size_t size; - char_u *buf; - char_u *start; - - size = SS_CMD_INFO_SIZE + cmd->cmd_len; - buf = alloc(size); - - if (buf == NULL) - return NULL; - - start = buf; - memcpy(start, &cmd->cmd_type, sizeof(cmd->cmd_type)); - start += sizeof(cmd->cmd_type); - memcpy(start, &cmd->cmd_num, sizeof(cmd->cmd_num)); - start += sizeof(cmd->cmd_num); - memcpy(start, &cmd->cmd_len, sizeof(cmd->cmd_len)); - start += sizeof(cmd->cmd_len); - - // Append messages to buffer - for (uint32_t i = 0; i < cmd->cmd_num; i++) - { - ss_msg_T *msg = cmd->cmd_msgs + i; - - memcpy(start, &msg->msg_type, sizeof(msg->msg_type)); - start += sizeof(msg->msg_type); - memcpy(start, &msg->msg_len, sizeof(msg->msg_len)); - start += sizeof(msg->msg_len); - - memcpy(start, msg->msg_contents, msg->msg_len); - start += msg->msg_len; - } - - *sz = size; - - return buf; -} - -/* - * Read from "socket_fd" an entire command and return the result in "cmd". The - * socket fd should be at the start of the command. Returns OK on success and - * FAIL on failure. - */ - static int -socket_server_decode_cmd(ss_cmd_T *cmd, int socket_fd, int timeout) -{ - int got_cmd_info = FALSE; // Consists of type, num, and len - size_t total_r = 0; - char_u *buf; - char_u *cur; -# ifdef ELAPSED_FUNC - elapsed_T start_tv; -# endif - - // We also poll the socket server listening file descriptor to handle - // recursive remote calls between Vim instances, such as when one Vim - // instance calls remote_expr for an expression that calls remote_expr to - // itself again. -# ifndef HAVE_SELECT - struct pollfd pfd; - - pfd.fd = socket_fd; - pfd.events = POLLIN; -# else - fd_set rfds; - struct timeval tv; - - FD_ZERO(&rfds); - FD_SET(socket_fd, &rfds); -# endif - - buf = alloc(SS_CMD_INFO_SIZE); - - if (buf == NULL) - return FAIL; - - // We may exit in the middle of the loop and free the messages, we don't - // want to free an uninitialized pointer. - memset(cmd, 0, sizeof(*cmd)); - -# ifdef ELAPSED_FUNC - ELAPSED_INIT(start_tv); -# endif - - while (TRUE) - { - int ret; - ssize_t r = 0; - -# ifndef HAVE_SELECT - ret = poll(&pfd, 1, timeout); -# else - tv.tv_sec = 0; - tv.tv_usec = 500 * 1000; - ret = select(socket_fd + 1, &rfds, NULL, NULL, &tv); -# endif - if (ret < 0) - goto fail; - if (ret == 0) - goto continue_loop; - - // Get cmd info first so we know the total size of all messages, and - // can read it all in one go. - if (!got_cmd_info) - { - r = read(socket_fd, buf + total_r, SS_CMD_INFO_SIZE - total_r); - - if ((size_t)r >= SS_CMD_INFO_SIZE - total_r) - { - char_u *tmp; - - got_cmd_info = TRUE; - - memcpy(&cmd->cmd_type, buf, sizeof(cmd->cmd_type)); - memcpy(&cmd->cmd_num, buf + sizeof(cmd->cmd_type), - sizeof(cmd->cmd_num)); - memcpy(&cmd->cmd_len, - buf + sizeof(cmd->cmd_type) + sizeof(cmd->cmd_num), - sizeof(cmd->cmd_len)); - - if (cmd->cmd_num > SOCKET_SERVER_MAX_MSG) - // Too many messages to handle or invalid number - goto fail; - - if (cmd->cmd_num == 0) - // No messages to read - goto exit; - - // Now that we now the total size of messages, we can realloc - // the buffer to contain all data - tmp = vim_realloc(buf, SS_CMD_INFO_SIZE + cmd->cmd_len); - - if (tmp == NULL) - goto fail; - - buf = tmp; - cur = buf + SS_CMD_INFO_SIZE; - - continue; - } - } - else - { - // Read message data - r = read(socket_fd, cur + total_r, cmd->cmd_len - total_r); - - if ((size_t)r >= cmd->cmd_len - total_r) - break; - } - - if (r == -1 || r == 0) - goto fail; - - total_r += r; - -continue_loop: -# ifdef ELAPSED_FUNC - if (ELAPSED_FUNC(start_tv) >= timeout) - goto fail; -# endif - } - - // Parse message data - for (uint32_t i = 0; i < cmd->cmd_num; i++) - { - ss_msg_T *msg = cmd->cmd_msgs + i; - - memcpy(&msg->msg_type, cur, sizeof(msg->msg_type)); - cur += sizeof(msg->msg_type); - memcpy(&msg->msg_len, cur, sizeof(msg->msg_len)); - cur += sizeof(msg->msg_len); - - msg->msg_contents = alloc(msg->msg_len + 1); - - if (msg->msg_contents == NULL) - goto fail; - - memcpy(msg->msg_contents, cur, msg->msg_len); - msg->msg_contents[msg->msg_len] = 0; // NULL terminate it - - // Move pointer to start of next message - cur += msg->msg_len; - } - -exit: - vim_free(buf); - return OK; -fail: - socket_server_free_cmd(cmd); - vim_free(buf); - return FAIL; -} - -/* - * Low level function that writes to a socket with a timeout in milliseconds. - * Returns OK on success and FAIL on failure. - */ - static int -socket_server_write(int socket_fd, char_u *data, size_t sz, int timeout) -{ - char_u *cur = data; - size_t total_w = 0; -# ifdef ELAPSED_FUNC - elapsed_T start_tv; -# endif -# ifndef HAVE_SELECT - struct pollfd pfd; - - pfd.fd = socket_fd; - pfd.events = POLLOUT; -# else - fd_set wfds; - struct timeval tv; - - FD_ZERO(&wfds); - FD_SET(socket_fd, &wfds); -# endif - -# ifdef ELAPSED_FUNC - ELAPSED_INIT(start_tv); -# endif - - while (total_w < sz) - { - int ret; - ssize_t written; - - errno = 0; -# ifndef HAVE_SELECT - ret = poll(&pfd, 1, timeout); -# else - tv.tv_sec = 0; - tv.tv_usec = 500 * 1000; - ret = select(socket_fd + 1, NULL, &wfds, NULL, &tv); -# endif - if (ret < 0) - return FAIL; - else if (ret == 0) - goto continue_loop; - - written = write(socket_fd, cur, sz - total_w); - - if (written == -1) - return FAIL; - - total_w += written; - -continue_loop: -# ifdef ELAPSED_FUNC - if (ELAPSED_FUNC(start_tv) >= timeout) - return FAIL; -# endif - } - - return OK; -} - - static ss_reply_T * -socket_server_get_reply(char_u *sender, int *index) -{ - for (int i = 0; i < ss_replies.ga_len; i++) - { - ss_reply_T *reply = ((ss_reply_T *)ss_replies.ga_data) + i; - - if (STRCMP(reply->sender, sender) == 0) - { - if (index != NULL) - *index = i; - return reply; - } - } - return NULL; -} - -/* - * Add reply to list of replies. Returns a pointer to the ss_reply_T that was - * initialized or was found. - */ - static ss_reply_T * -socket_server_add_reply(char_u *sender) -{ - ss_reply_T *reply; - - if (ss_replies.ga_growsize == 0) - ga_init2(&ss_replies, sizeof(ss_reply_T), 1); - - reply = socket_server_get_reply(sender, NULL); - - if (reply == NULL && ga_grow(&ss_replies, 1) == OK) - { - reply = ((ss_reply_T *)ss_replies.ga_data) + ss_replies.ga_len++; - - reply->sender = vim_strsave(sender); - - if (reply->sender == NULL) - return NULL; - - ga_init2(&reply->strings, sizeof(char_u *), 5); - } - - return reply; -} - - static void -socket_server_remove_reply(char_u *sender) -{ - int index; - ss_reply_T *reply = socket_server_get_reply(sender, &index); - - if (reply != NULL) - { - ss_reply_T *arr = ss_replies.ga_data; - - // Free strings - vim_free(reply->sender); - ga_clear_strings(&reply->strings); - - // Move all elements after the removed reply forward by one - for (int i = index + 1; i < ss_replies.ga_len; i++) - arr[i - 1] = arr[i]; - ss_replies.ga_len--; - } -} - -/* - * Execute the actions given by command. "fd" is the socket of the client that - * sent the command. - */ - static void -socket_server_exec_cmd(ss_cmd_T *cmd, int fd) -{ - char_u *str = NULL; - char_u *enc = NULL; - char_u *sender = NULL; - uint32_t serial = 0; - char_u rcode = 0; - char_u *to_free; - char_u *to_free2; - - for (uint32_t i = 0; i < cmd->cmd_num; i++) - { - ss_msg_T *msg = cmd->cmd_msgs + i; - - if (msg->msg_type == SS_MSG_TYPE_STRING) - str = msg->msg_contents; - if (msg->msg_type == SS_MSG_TYPE_ENCODING) - enc = msg->msg_contents; - if (msg->msg_type == SS_MSG_TYPE_SERIAL) - memcpy(&serial, msg->msg_contents, sizeof(serial)); - if (msg->msg_type == SS_MSG_TYPE_CODE) - memcpy(&rcode, msg->msg_contents, sizeof(rcode)); - else if (msg->msg_type == SS_MSG_TYPE_SENDER) - { - sender = msg->msg_contents; - - // Save in global - vim_free(client_socket); - client_socket = vim_strsave(sender); - } - } - -# ifdef FEAT_EVAL - ch_log(NULL, "socket_server_exec_cmd(): encoding: %s, result: %s", - enc == NULL ? (char_u *)"(null)" : enc, - str == NULL ? (char_u *)"(null)" : str); -# endif - - if (cmd->cmd_type == SS_CMD_TYPE_EXPR || - cmd->cmd_type == SS_CMD_TYPE_KEYSTROKES) - { - // Either an expression or keystrokes. - if (socket_server_valid() && enc != NULL && str != NULL) - { - str = serverConvert(enc, str, &to_free); - - if (cmd->cmd_type == SS_CMD_TYPE_KEYSTROKES) - server_to_input_buf(str); - else if (sender != NULL) - { - // Evaluate expression and send reply containing result - char_u *result; - size_t sz; - char_u *buf; - char_u code; - - result = eval_client_expr_to_string(str); - - code = result == NULL ? -1 : 0; - - // Send reply - ss_cmd_T rcmd; - - socket_server_init_cmd(&rcmd, SS_CMD_TYPE_REPLY); - - // Don't care about errors, server will just ignore command if - // its missing something. - if (result != NULL) - socket_server_append_msg(&rcmd, SS_MSG_TYPE_STRING, result, - STRLEN(result) + 1); // We add +1 in case "result" - // is an empty string. - else - // An error occurred, return an error msg instead - socket_server_append_msg(&rcmd, SS_MSG_TYPE_STRING, - (char_u *)_(e_invalid_expression_received), - STRLEN(e_invalid_expression_received)); - - socket_server_append_msg(&rcmd, SS_MSG_TYPE_CODE, - &code, sizeof(code)); - - socket_server_append_msg(&rcmd, SS_MSG_TYPE_ENCODING, p_enc, - STRLEN(p_enc)); - - socket_server_append_msg(&rcmd, SS_MSG_TYPE_SERIAL, - (char_u *)&serial, sizeof(serial)); - - buf = socket_server_encode_cmd(&rcmd, &sz); - - if (buf != NULL) - { - int fd2 = socket_server_connect(sender, NULL, TRUE); - - if (fd2 >= 0) - socket_server_write(fd2, buf, sz, 1000); - vim_free(buf); - close(fd2); - } - - socket_server_free_cmd(&rcmd); - vim_free(result); - } - vim_free(to_free); - } - return; - } - else if (cmd->cmd_type == SS_CMD_TYPE_REPLY) - { - // A reply from a previous command we set up, update the corresponding - // pending command. - if (serial > 0 && str != NULL) - { - for (ss_pending_cmd_T *pending = ss_pending_cmds; pending != NULL; - pending = pending->next) - { - if (serial == pending->serial && pending->result == NULL) - { - str = serverConvert(enc, str, &to_free); - - pending->code = rcode; - - if (to_free == NULL) - pending->result = vim_strsave(str); - else - pending->result = str; - break; - } - } - } - return; - } - else if (cmd->cmd_type == SS_CMD_TYPE_NOTIFY) - { - // Notification, execute autocommands and save the reply for later use - if (sender != NULL && str != NULL && enc != NULL) - { - ss_reply_T *reply; - - str = serverConvert(enc, str, &to_free); - sender = serverConvert(enc, sender, &to_free2); - - reply = socket_server_add_reply(sender); - - if (reply != NULL) - ga_copy_string(&reply->strings, str); - - apply_autocmds(EVENT_REMOTEREPLY, sender, str, TRUE, curbuf); - - vim_free(to_free); - vim_free(to_free2); - } - return; - } - else if (cmd->cmd_type == SS_CMD_TYPE_ALIVE) - { - // Client wants to check if we are still responsive, send back a single - // byte as a YES. - char_u buf[1] = {1}; -# ifndef HAVE_SELECT - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN; -# else - fd_set rfds; - struct timeval tv; - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); -# endif - - if (write(fd, buf, 1) == -1) - return; - - // Poll until client closes their end - -# ifndef HAVE_SELECT - poll(&pfd, 1, 1000); -# else - tv.tv_sec = 1; - tv.tv_usec = 0; - select(fd + 1, &rfds, NULL, NULL, &tv); -# endif - return; - } - - // Command type is invalid, do nothing - return; -} - -/* - * Poll the socket server fd until a new connection is accepted. Returns 0 on - * success, 1 if it timed out or if poll returned empty, and -1 on error. - */ - static int -socket_server_dispatch(int timeout) -{ - int ret; -# ifndef HAVE_SELECT - struct pollfd pfd; - - pfd.fd = socket_server_fd; - pfd.events = POLLIN; -# else - fd_set rfds; - fd_set efds; - struct timeval tv; - - FD_ZERO(&rfds); - FD_ZERO(&efds); - FD_SET(socket_server_fd, &rfds); - FD_SET(socket_server_fd, &efds); -# endif - -# ifndef HAVE_SELECT - ret = poll(&pfd, 1, timeout); -# else - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - ret = select(socket_server_fd + 1, &rfds, NULL, &efds, &tv); -# endif - - if (ret < 0) - return -1; - else if (ret == 0) - return 1; - -# ifndef HAVE_SELECT - if (pfd.revents & POLLIN) -# else - if (FD_ISSET(socket_server_fd, &rfds)) -# endif - { - socket_server_accept_client(); - return 0; - } -# ifndef HAVE_SELECT - else if (pfd.revents & (POLLHUP | POLLERR)) -# else - else if (FD_ISSET(socket_server_fd, &efds)) -# endif - // Connection was closed - return -1; - else - return 1; - - return -1; -} - -/* - * Check if socket "name" is responsive by sending an ALIVE command. This does - * not require the socket server to be active. - */ - static int -socket_server_check_alive(char_u *name) -{ - int socket_fd; - int ret; - size_t sz; - char_u *final; - char_u buf[1] = {0}; -# ifndef HAVE_SELECT - struct pollfd pfd; -# else - fd_set rfds; - struct timeval tv; -# endif - - socket_fd = socket_server_connect(name, NULL, TRUE); - - if (socket_fd == -1) - return FALSE; - -# ifndef HAVE_SELECT - pfd.fd = socket_fd; - pfd.events = POLLIN; -# else - FD_ZERO(&rfds); - FD_SET(socket_fd, &rfds); -# endif - - ss_cmd_T cmd; - - socket_server_init_cmd(&cmd, SS_CMD_TYPE_ALIVE); - - final = socket_server_encode_cmd(&cmd, &sz); - - if (final == NULL || - socket_server_write(socket_fd, final, sz, 1000) == FAIL) - { - vim_free(final); - close(socket_fd); - return FALSE; - } - vim_free(final); - - // Poll for response -# ifndef HAVE_SELECT - ret = poll(&pfd, 1, 1000); -# else - tv.tv_sec = 1; - tv.tv_usec = 0; - ret = select(socket_fd + 1, &rfds, NULL, NULL, &tv); -# endif - - if (ret > 0) - if (read(socket_fd, buf, 1) == -1) - { - close(socket_fd); - return FALSE; - } - - close(socket_fd); - return buf[0] == 1; -} - -/* - * Get file descriptor of listening socket - */ - int -socket_server_get_fd(void) -{ - return socket_server_fd; -} - - -/* - * Check if socket name is a valid name - */ - static int -socket_server_name_is_valid(char_u *name) -{ - if (STRLEN(name) == 0 || (name[0] != '/' && vim_strchr(name, '/') != NULL)) - { - semsg(_(e_invalid_server_id_used_str), name); - return FALSE; - } - return TRUE; -} - -/* - * Returns TRUE if there are clients queued in the listening socket waiting to - * be accepted - */ - int -socket_server_waiting_accept(void) -{ - int ret; -# ifndef HAVE_SELECT - struct pollfd pfd; - - pfd.fd = socket_server_fd; - pfd.events = POLLIN; - - ret = poll(&pfd, 1, 0); - - if (ret > 0 && pfd.revents & POLLIN) - return TRUE; -# else - fd_set rfds; - struct timeval tv; - - if (socket_server_fd == -1) - return FALSE; - - FD_ZERO(&rfds); - FD_SET(socket_server_fd, &rfds); - - tv.tv_sec = 0; - tv.tv_usec = 0; - ret = select(socket_server_fd + 1, &rfds, NULL, NULL, &tv); - - if (ret > 0 && FD_ISSET(socket_server_fd, &rfds)) - return TRUE; -# endif - - return FALSE; -} - -#endif // FEAT_SOCKETSERVER diff --git a/src/os_vms.c b/src/os_vms.c index bb93544f09..17fa067743 100644 --- a/src/os_vms.c +++ b/src/os_vms.c @@ -858,7 +858,12 @@ RealWaitForChar( * appropriate time conversion function accordingly. */ #if __IEEE_FLOAT -# define LIB_CVTX_TO_INTERNAL_TIME lib$cvts_to_internal_time // IEEE +// allow fallback for older Alphas +# ifdef lib$cvts_to_internal_time +# define LIB_CVTX_TO_INTERNAL_TIME lib$cvts_to_internal_time // IEEE +# else +# define LIB_CVTX_TO_INTERNAL_TIME lib$cvtf_to_internal_time +# endif #else # define LIB_CVTX_TO_INTERNAL_TIME lib$cvtf_to_internal_time // VAX #endif // __IEEE_FLOAT CVTS diff --git a/src/os_vms_conf.h b/src/os_vms_conf.h index 5831cb1f74..ddc83b3dc5 100644 --- a/src/os_vms_conf.h +++ b/src/os_vms_conf.h @@ -12,7 +12,6 @@ #include // Required early for large-file support #define CASE_INSENSITIVE_FILENAME // Open VMS is case insensitive -#define SPACE_IN_FILENAME // There could be space between user and passwd #define FNAME_ILLEGAL "|*#?%" // Illegal characters in a file name #define BINARY_FILE_IO // Use binary fileio #define USE_GETCWD @@ -59,9 +58,6 @@ // Define to `int' if doesn't define. // #undef uid_t -// Define to `unsigned int' or other type that is 32 bit. -#define UINT32_T unsigned int - // Define to `int' if doesn't define. // #undef gid_t @@ -170,7 +166,6 @@ # define ULONG_LONG_MAX (4294967295U) #else // ALPHA, IA64, X86_64 -# define HAVE_FSEEKO /* Use off_t. */ # define HAVE_GETTIMEOFDAY # define HAVE_USLEEP # define HAVE_STRCASECMP @@ -187,7 +182,11 @@ # define HAVE_ISNAN # endif -# define HAVE_XOS_R_H +# if defined(X86_64) +# define HAVE_FSEEKO +# define HAVE_STDINT_H +# define HAVE_XOS_R_H +# endif #endif /* VAX [else] */ @@ -209,7 +208,7 @@ # define HAVE_LOCALE_H # define BROKEN_LOCALE # undef DYNAMIC_ICONV -# define HAVE_STRFTIME +# define HAVE_STRFTIME #endif #if defined(USE_ICONV) @@ -232,3 +231,10 @@ # define USE_FONTSET # undef X_LOCALE #endif + +// Define needed types from stdint - older VMS do not have stdint.h +#ifndef HAVE_STDINT_H + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#endif diff --git a/src/os_win32.c b/src/os_win32.c index e7216c1220..31fa169a5a 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -2730,10 +2730,7 @@ executable_exists( { pathext.string = mch_getenv("PATHEXT"); if (pathext.string == NULL) - { - pathext.string = (char_u *)".com;.exe;.bat;.cmd"; - pathext.length = 19; - } + STR_LITERAL_SET(pathext, ".com;.exe;.bat;.cmd"); else pathext.length = STRLEN(pathext.string); @@ -2774,10 +2771,7 @@ executable_exists( // Prepend single "." to pathext, it means no extension added. if (pathext.string == NULL) - { - pathext.string = (char_u *)"."; - pathext.length = 1; - } + STR_LITERAL_SET(pathext, "."); else if (noext == TRUE) { char_u *tmp; @@ -2828,10 +2822,7 @@ executable_exists( * is an executable file. */ if (pathbuf.string == NULL) - { - pathbuf.string = (char_u *)"."; - pathbuf.length = 1; - } + STR_LITERAL_SET(pathbuf, "."); p = pathbuf.string; while (*p) { @@ -7113,9 +7104,19 @@ cursor_visible(BOOL fVisible) s_cursor_visible = fVisible; if (vtp_working) + { + // In vtp mode, visibility is controlled solely by DECTCEM. Skip + // mch_update_cursor() since shape is independent of visibility and + // re-emitting DECSCUSR can cause the terminal to briefly redisplay + // the cursor while a redraw is in progress. vtp_printf("\033[?25%c", fVisible ? 'h' : 'l'); + return; + } # ifdef MCH_CURSOR_SHAPE + // Non-vtp Windows console: SetConsoleCursorInfo() consults + // s_cursor_visible inside mch_set_cursor_shape(), so the call is needed + // to apply the new visibility. mch_update_cursor(); # endif } @@ -8099,7 +8100,8 @@ mch_fopen(const char *name, const char *mode) vim_free(wm); #if defined(DEBUG) && _MSC_VER >= 1400 - _set_fmode(oldMode); + if (oldMode != 0) + _set_fmode(oldMode); #endif return f; } diff --git a/src/os_win32.h b/src/os_win32.h index 6f395eede7..cfdff674fd 100644 --- a/src/os_win32.h +++ b/src/os_win32.h @@ -29,6 +29,12 @@ #ifndef HAVE_STRFTIME # define HAVE_STRFTIME // guessed #endif +#ifndef HAVE_STRPTIME +# define HAVE_STRPTIME // provided by src/strptime.c +#endif +#ifndef HAVE_TZSET +# define HAVE_TZSET // CRT has tzset() / _tzset() +#endif #define HAVE_MEMSET #ifndef HAVE_LOCALE_H # define HAVE_LOCALE_H 1 @@ -228,3 +234,6 @@ Trace(char *pszFormat, ...); // Windows Version #define MAKE_VER(major, minor, build) \ (((major) << 24) | ((minor) << 16) | (build)) + +// The Windows CRT does not declare strptime(); Vim provides it in strptime.c. +char *strptime(const char *buf, const char *fmt, struct tm *tm); diff --git a/src/po/it.po b/src/po/it.po index 217e85eb37..8da30e86bf 100644 --- a/src/po/it.po +++ b/src/po/it.po @@ -4,18 +4,19 @@ # Vlad Sandrini , 2002 # Luciano Montanaro , 2006 # -# Ogni commento è benvenuto... # Every remark is very welcome... +# Ogni commento è benvenuto... # -# Translation done under Linux and using an Italian keyboard. -# English words left in the text are unmodified at plural. -# Option names are mostly left untouched. +# Traduzione fatta in ambiebte Linux, usnado una tastiera italiana. +# Le parole inglesi presenti nel testo sono sempre al singolare. +# I nomi delle opzioni sono quasi sempre lasciati in inglese. +# I nomi dei modi di Vim sono lasciati in inglese. # msgid "" msgstr "" "Report-Msgid-Bugs-To: vim-dev@vim.org\n" -"POT-Creation-Date: 2026-04-02 17:32+0200\n" -"PO-Revision-Date: 2026-04-02 20:20+0100\n" +"POT-Creation-Date: 2026-05-21 07:38+0200\n" +"PO-Revision-Date: 2026-05-21 08:20+0100\n" "Last-Translator: Antonio Colombo \n" "Language-Team: Italian\n" "Language: it\n" @@ -344,7 +345,7 @@ msgid "xchacha20v2: using default algorithm \"%d\" for Key derivation." msgstr "xchacha20v2: uso algoritmo predefinito \"%d\" per ricavare la Chiave." msgid "Entering Debug mode. Type \"cont\" to continue." -msgstr "Entro modalità Debug. Batti \"cont\" per continuare." +msgstr "Entro modo Debug. Batti \"cont\" per continuare." #, c-format msgid "Oldval = \"%s\"" @@ -634,7 +635,7 @@ msgstr "" "W21: Versione richiesta di python 3.x non supportata, ignoro il file: %s" msgid "Entering Ex mode. Type \"visual\" to go to Normal mode." -msgstr "Entro modalità Ex. Batti \"visual\" per tornare a modalità Normale." +msgstr "Entro modo Ex. Batti \"visual\" per tornare a modo Normal." #, c-format msgid "Executing: %s" @@ -959,9 +960,11 @@ msgstr "VIM - Sostituisci..." msgid "VIM - Search..." msgstr "VIM - Cerca..." +#. "Find what:" label + entry msgid "Find what:" msgstr "Trovare:" +#. "Replace with:" label + entry msgid "Replace with:" msgstr "Sostituire con:" @@ -995,6 +998,12 @@ msgstr "Sostituisci Tutto" msgid "_Close" msgstr "_Chiudi" +msgid "Direction:" +msgstr "Direzione:" + +msgid "Close" +msgstr "Chiudi" + msgid "Vim: Received \"die\" request from session manager\n" msgstr "Vim: Ricevuta richiesta \"die\" dal Session Manager\n" @@ -1076,7 +1085,7 @@ msgstr "Font%d: %s" #, c-format msgid "Font%d width is not twice that of font0" -msgstr "La larghezza di font%d non è doppia di quella di font0" +msgstr "La larghezza di font%d non è doppia di quella di Font0" #, c-format msgid "Font0 width: %d" @@ -1648,19 +1657,19 @@ msgid "-f or --nofork\tForeground: Don't fork when starting GUI" msgstr "-f opp. --nofork\tForeground: Non usare 'fork' inizializzando GUI" msgid "-v\t\t\tVi mode (like \"vi\")" -msgstr "-v\t\t\tModalità Vi (come \"vi\")" +msgstr "-v\t\t\tModo Vi (come \"vi\")" msgid "-e\t\t\tEx mode (like \"ex\")" -msgstr "-e\t\t\tModalità Ex (come \"ex\")" +msgstr "-e\t\t\tModo Ex (come \"ex\")" msgid "-E\t\t\tImproved Ex mode" -msgstr "-E\t\t\tModalità Ex migliorata" +msgstr "-E\t\t\tModo Ex migliorata" msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")" -msgstr "-s\t\t\tModalità Silenziosa (batch) (solo per \"ex\")" +msgstr "-s\t\t\tModo Silenzioso (batch) (solo per \"ex\")" msgid "-d\t\t\tDiff mode (like \"vimdiff\")" -msgstr "-d\t\t\tModalità Diff (come \"vimdiff\")" +msgstr "-d\t\t\tModo Diff (come \"vimdiff\")" msgid "-y\t\t\tEasy mode (like \"evim\", modeless)" msgstr "-y\t\t\tModo Facile (come \"evim\", senza modi)" @@ -1669,7 +1678,7 @@ msgid "-R\t\t\tReadonly mode (like \"view\")" msgstr "-R\t\t\tModo Sola-Lettura (come \"view\")" msgid "-Z\t\t\tRestricted mode (like \"rvim\")" -msgstr "-Z\t\t\tModalità Ristretta (come \"rvim\")" +msgstr "-Z\t\t\tModo Restricted (come \"rvim\")" msgid "-m\t\t\tModifications (writing files) not allowed" msgstr "-m\t\t\tModifiche (riscritture file) non consentita" @@ -1678,7 +1687,7 @@ msgid "-M\t\t\tModifications in text not allowed" msgstr "-M\t\t\tModifiche nel testo non consentite" msgid "-b\t\t\tBinary mode" -msgstr "-b\t\t\tModalità Binaria" +msgstr "-b\t\t\tModo Bynary" msgid "-l\t\t\tLisp mode" msgstr "-l\t\t\tModo Lisp" @@ -1693,7 +1702,7 @@ msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]" msgstr "-V[N][fname]\t\tVerbosità [livello N] [log su file fname]" msgid "-D\t\t\tDebugging mode" -msgstr "-D\t\t\tModalità Debug" +msgstr "-D\t\t\tModo Debug" msgid "-n\t\t\tNo swap file, use memory only" msgstr "-n\t\t\tNiente file di swap, usa solo memoria" @@ -1714,10 +1723,10 @@ msgid "-dev \t\tUse for I/O" msgstr "-dev \t\tUsa per I/O" msgid "-A\t\t\tStart in Arabic mode" -msgstr "-A\t\t\tComincia in modalità Araba" +msgstr "-A\t\t\tComincia in modo Arabic" msgid "-H\t\t\tStart in Hebrew mode" -msgstr "-H\t\t\tComincia in modalità Ebraica" +msgstr "-H\t\t\tComincia in modo Hebrew" msgid "-T \tSet terminal type to " msgstr "-T \tImposta tipo terminale a " @@ -1767,7 +1776,7 @@ msgstr "" "-S \tEsegui comandi in file dopo caricamento primo file" msgid "-s \tRead Normal mode commands from file " -msgstr "-s \tLeggi comandi in modalità normale da file " +msgstr "-s \tLeggi comandi in modo Normal da file " msgid "-w \tAppend all typed commands to file " msgstr "-w \tAggiungi tutti i comandi immessi a file " @@ -1987,8 +1996,8 @@ msgid "" "Maybe no changes were made or Vim did not update the swap file." msgstr "" "\n" -"Forse non ci sono state modifiche oppure Vim non ha aggiornato il file di " -" swap." +"Forse non ci sono state modifiche oppure Vim non ha aggiornato il file di " +"swap." msgid " cannot be used with this version of Vim.\n" msgstr " impossibile da usare con questa versione di Vim.\n" @@ -2074,6 +2083,9 @@ msgstr "???BLOCCO MANCANTE" msgid "??? from here until ???END lines may be messed up" msgstr "??? da qui fino a ???END le righe possono essere fuori ordine" +msgid "??? block header corrupted" +msgstr "??? intestazione di blocco non valida" + msgid "??? from here until ???END lines may have been inserted/deleted" msgstr "" "??? da qui fino a ???END righe possono essere state inserite/cancellate" @@ -2209,7 +2221,7 @@ msgid "" " [not usable on this computer]" msgstr "" "\n" -" [not utilizzabile su questo computer]" +" [non utilizzabile su questo computer]" msgid " [cannot be read]" msgstr " [non leggibile]" @@ -2293,12 +2305,12 @@ msgstr "File di swap \"" msgid "\" already exists!" msgstr "\" già esistente!" -msgid "VIM - ATTENTION" -msgstr "VIM - ATTENZIONE" - msgid "Swap file already exists!" msgstr "Il file di swap esiste già!" +msgid "VIM - ATTENTION" +msgstr "VIM - ATTENZIONE" + msgid "" "&Open Read-Only\n" "&Edit anyway\n" @@ -2426,6 +2438,7 @@ msgstr " (Interrotto)" msgid "Beep!" msgstr "Beep!" +#, c-format msgid "Executing directly: \"%s\"" msgstr "Eseguo direttamente: \"%s\"" @@ -2559,7 +2572,7 @@ msgid "Vim exiting with %d\n" msgstr "Vim esce con %d\n" msgid "cannot change console mode ?!\n" -msgstr "non posso modificare modalità console ?!\n" +msgstr "non posso modificare modo Console ?!\n" msgid "mch_get_shellsize: not a console??\n" msgstr "mch_get_shellsize: non una console??\n" @@ -3702,6 +3715,9 @@ msgstr "" msgid "without GUI." msgstr "senza GUI." +msgid "with GTK4 GUI." +msgstr "con GUI GTK4." + msgid "with GTK3 GUI." msgstr "con GUI GTK3." @@ -3811,7 +3827,7 @@ msgid "type :help version9 for version info" msgstr "batti :help version9 per informazioni su versione" msgid "Running in Vi compatible mode" -msgstr "Eseguo in modalità compatibile Vi" +msgstr "Eseguo in modo compatibile Vi" msgid "type :set nocp for Vim defaults" msgstr "batti :set nocp per valori predefiniti Vim" @@ -3823,7 +3839,7 @@ msgid "menu Help->Orphans for information " msgstr "menu Aiuto->Orfani per informazioni " msgid "Running modeless, typed text is inserted" -msgstr "Esecuzione senza modalità: solo inserimento" +msgstr "Esecuzione senza modo: il testo immesso viene inserito" msgid "menu Edit->Global Settings->Toggle Insert Mode " msgstr "menu Modifica->Impost.Globali->Modal.Inser. SÃŦ/No" @@ -5081,7 +5097,7 @@ msgstr "" "E327: Parte del percorso di questo elemento di MenÚ non è un sotto-MenÚ" msgid "E328: Menu only exists in another mode" -msgstr "E328: I MenÚ esistono solo in un'altra modalità" +msgstr "E328: I MenÚ esistono solo in un altro Modo" #, c-format msgid "E329: No menu \"%s\"" @@ -5106,7 +5122,7 @@ msgstr "E334: MenÚ non trovato: %s" #, c-format msgid "E335: Menu not defined for %s mode" -msgstr "E335: MenÚ non definito per la modalità %s" +msgstr "E335: MenÚ non definito per il modo %s" msgid "E336: Menu path must lead to a sub-menu" msgstr "E336: Il percorso MenÚ deve condurre ad un sotto-MenÚ" @@ -5115,7 +5131,7 @@ msgid "E337: Menu not found - check menu names" msgstr "E337: MenÚ non trovato - controlla nomi MenÚ" msgid "E338: Sorry, no file browser in console mode" -msgstr "E338: Spiacente, niente esplorazione file in modalità console" +msgstr "E338: Spiacente, niente esplorazione file in modo Console" msgid "E339: Pattern too long" msgstr "E339: Espressione troppo lunga" @@ -5187,7 +5203,7 @@ msgid "E358: 'langmap': Extra characters after semicolon: %s" msgstr "E358: 'langmap': Caratteri in piÚ dopo il ';': %s" msgid "E359: Screen mode setting not supported" -msgstr "E359: Impostazione modalità schermo non supportata" +msgstr "E359: Impostazione modo schermo non supportata" msgid "E360: Cannot execute shell with -f option" msgstr "E360: Non posso eseguire la shell con l'opzione -f" @@ -5525,11 +5541,6 @@ msgstr "E456: Non trovo file risorse PostScript \"%s.ps\"" msgid "E457: Can't read PostScript resource file \"%s\"" msgstr "E457: Non riesco a leggere file risorse PostScript \"%s\"" -msgid "E458: Cannot allocate colormap entry, some colors may be incorrect" -msgstr "" -"E458: Non riesco ad allocare elemento di colormap, alcuni colori possono " -"essere errati" - msgid "E459: Cannot go back to previous directory" msgstr "E459: Non posso tornare alla directory precedente" @@ -5869,7 +5880,7 @@ msgid "E545: Missing colon" msgstr "E545: Manca ':'" msgid "E546: Illegal mode" -msgstr "E546: Modalità non consentita" +msgstr "E546: Modo non consentito" msgid "E547: Illegal mouseshape" msgstr "E547: Forma del mouse non consentita" @@ -6192,6 +6203,9 @@ msgstr "E647: Identificativo buffer non valido in setDot" msgid "E648: Invalid buffer identifier in close" msgstr "E648: Identificativo buffer non valido in close" +msgid "E649: Invalid identifier name in defineAnnoType" +msgstr "E649: Nome identificativo non valido in defineAnnoType" + msgid "E650: Invalid buffer identifier in defineAnnoType" msgstr "E650: Identificativo buffer non valido in defineAnnoType" @@ -6654,7 +6668,7 @@ msgid "E784: Cannot close last tab page" msgstr "E784: Non posso chiudere l'ultima pagina di schede" msgid "E785: complete() can only be used in Insert mode" -msgstr "E785: complete() puÃ˛ essere usata solo in modalità inserimento" +msgstr "E785: complete() puÃ˛ essere usata solo in modo Insert" msgid "E786: Range not allowed" msgstr "E786: Intervallo non consentito" @@ -7121,8 +7135,10 @@ msgstr "E910: Uso di un Job come un Numero" msgid "E911: Using a Job as a Float" msgstr "E911: Uso di un Job come un Numero-a-virgola-mobile" -msgid "E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" -msgstr "E912: Impossibile usare ch_evalexpr() con un canale grezzo o nl" +msgid "" +"E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw, nl or blob channel" +msgstr "E912: Impossibile usare ch_evalexpr()/ch_sendexpr con un canale " +"grezzo o nl o blob" msgid "E913: Using a Channel as a Number" msgstr "E913: Uso di un Canale come un Numero" @@ -9208,11 +9224,11 @@ msgstr "E1545: Stack delle Liste quickfix non disponibile" msgid "E1546: Cannot switch to a closing buffer" msgstr "E1546: Non posso passare a un buffer che si sta chiudendo" -msgid "E1547: This version of Vim does support :redrawtabpanel" -msgstr "E1547: Questa versione di Vim supporta :redrawtabpanel" +msgid "E1547: This version of Vim does not support :redrawtabpanel" +msgstr "E1547: Questa versione di Vim non supporta :redrawtabpanel" msgid "E1548: Wayland connection is unavailable" -msgstr "E1548: Connession a Wayland non disponibile" +msgstr "E1548: Connessione a Wayland non disponibile" #, c-format msgid "E1549: Cannot have more than %d diff anchors" @@ -9321,6 +9337,13 @@ msgstr "" msgid "E1575: Cannot create pipes" msgstr "E1575: Non posso create delle pipe" +msgid "E1576: Tag file entry must not be a URL" +msgstr "E1576: Il puntatore nel file di tag non dev'essere un URL" + +#, c-format +msgid "E1577: Invalid format string, only one \"%s\" is allowed" +msgstr "E1577: Stringa di formato non valida, solo un \"%s\" è consentito" + #. type of cmdline window or 0 #. result of cmdline window or 0 #. buffer of cmdline window or NULL @@ -9863,6 +9886,9 @@ msgstr "" "i nomi di file in un file di tag sono espressi a partire dalla\n" "posizione del file di tag" +msgid "a :tag command cannot access remote files" +msgstr "un comando :tag non puÃ˛ accedere a file remoti" + msgid "a :tag command will use the tagstack" msgstr "un comando :tag userà la pila dei tag (tagstack)" @@ -9911,6 +9937,9 @@ msgstr "" "numero di righe dello schermo da mostrare attorno alla riga che contiene\n" "il cursore" +msgid "vertically center cursor even at end of file" +msgstr "centrare il cursore verticalmente anche a fine file" + msgid "long lines wrap" msgstr "mandare a capo righe lunghe" @@ -10516,11 +10545,6 @@ msgstr "" msgid "Wayland seat to use" msgstr "Seggio Wayland da usare" -msgid "" -"Enable wayland focus stealing functionality in order to access the clipboard" -msgstr "" -"Abilita funzionalità cattura focus in Wayland per accedere agli appunti" - msgid "\"startsel\" and/or \"stopsel\"; what special keys can do" msgstr "\"startsel\" e/o \"stopsel\"; cosa fare usando tasti speciali" @@ -10640,6 +10664,9 @@ msgstr "larghezza massima del menÚ dinamico" msgid "popup border style" msgstr "stile bordo menÚ dinamico" +msgid "additional options for the popup menu" +msgstr "impostazioni opzionali per il menÚ dinamico (popup)" + msgid "user defined function for Insert mode completion" msgstr "funzione definita dall'utente per il completamento in modo Insert" @@ -10877,6 +10904,11 @@ msgstr "" "consentire impostazione di opzioni tramite espressioni\n" "da modeline" +msgid "only allow safe options to be set from a modeline" +msgstr "" +"consentire solo impostazione di opzioni non pericolose tramite " +"modeline" + msgid "number of lines to check for modelines" msgstr "numero di righe da controllare per modeline" diff --git a/src/po/sr.po b/src/po/sr.po index c8c1537898..5187a3f3f0 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: vim-dev@vim.org\n" -"POT-Creation-Date: 2026-03-30 11:05+0900\n" -"PO-Revision-Date: 2026-02-20 09:34+0400\n" +"POT-Creation-Date: 2026-04-29 19:49+0000\n" +"PO-Revision-Date: 2026-05-01 10:09+0400\n" "Last-Translator: Ivan PeÅĄić \n" "Language-Team: Serbian\n" "Language: sr\n" @@ -2038,6 +2038,9 @@ msgstr "???ПРАЗАН БЛОК" msgid "???LINES MISSING" msgstr "???НЕДОСĐĸĐĐˆĐŖ ЛИНИЈЕ" +msgid "???ILLEGAL BLOCK NUMBER" +msgstr "???НЕИСПРАВАН БРОЈ БЛОКА" + msgid "???BLOCK MISSING" msgstr "???НЕДОСĐĸАЈЕ БЛОК" @@ -2386,6 +2389,10 @@ msgstr " (ĐŸŅ€ĐĩĐēиĐŊŅƒŅ‚Đž)" msgid "Beep!" msgstr "БииĐŋ!" +#, c-format +msgid "Executing directly: \"%s\"" +msgstr "Đ”Đ¸Ņ€ĐĩĐēŅ‚ĐŊĐž ҁĐĩ Đ¸ĐˇĐ˛Ņ€ŅˆĐ°Đ˛Đ°: „%s”" + #, c-format msgid "Calling shell to execute: \"%s\"" msgstr "Позива ҁĐĩ ĐēĐžĐŧаĐŊĐ´ĐŊĐž ĐžĐēŅ€ŅƒĐļĐĩҚĐĩ да Đ¸ĐˇĐ˛Ņ€ŅˆĐ¸: „%s”" @@ -2600,7 +2607,7 @@ msgid "" "Cannot execute shell sh\n" msgstr "" "\n" -"КоĐŧаĐŊĐ´ĐŊĐž ĐžĐēŅ€ŅƒĐļĐĩҚĐĩ sh ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ Đ¸ĐˇĐ˛Ņ€ŅˆĐ¸\n" +"НĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ Đ¸ĐˇĐ˛Ņ€ŅˆĐ¸ ĐēĐžĐŧаĐŊĐ´ĐŊĐž ĐžĐēŅ€ŅƒĐļĐĩҚĐĩ sh\n" msgid "" "\n" @@ -2614,7 +2621,7 @@ msgid "" "Cannot create pipes\n" msgstr "" "\n" -"ĐĸĐžĐēОви ĐŋĐžĐ´Đ°Ņ‚Đ°Đēа ĐŊĐĩ ĐŧĐžĐŗŅƒ да ҁĐĩ ĐēŅ€ĐĩĐ¸Ņ€Đ°Ņ˜Ņƒ\n" +"НĐĩ ĐŧĐžĐŗŅƒ да ҁĐĩ ĐēŅ€ĐĩĐ¸Ņ€Đ°Ņ˜Ņƒ Ņ‚ĐžĐēОви ĐŋĐžĐ´Đ°Ņ‚Đ°Đēа\n" msgid "" "\n" @@ -2628,7 +2635,7 @@ msgid "" "Cannot execute shell " msgstr "" "\n" -"КоĐŧаĐŊĐ´ĐŊĐž ĐžĐēŅ€ŅƒĐļĐĩҚĐĩ ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ Đ¸ĐˇĐ˛Ņ€ŅˆĐ¸ " +"НĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ Đ¸ĐˇĐ˛Ņ€ŅˆĐ¸ ĐēĐžĐŧаĐŊĐ´ĐŊĐž ĐžĐēŅ€ŅƒĐļĐĩҚĐĩ " msgid "" "\n" @@ -2642,14 +2649,14 @@ msgstr "XSMP ҘĐĩ Đ¸ĐˇĐŗŅƒĐąĐ¸Đž ICE вĐĩĐˇŅƒ" #, c-format msgid "Could not load gpm library: %s" -msgstr "БибĐģĐ¸ĐžŅ‚ĐĩĐēа gpm ĐŊĐ¸Ņ˜Đĩ ĐŧĐžĐŗĐģа да ҁĐĩ ŅƒŅ‡Đ¸Ņ‚Đ°: %s" +msgstr "ĐĐ¸Ņ˜Đĩ ĐŧĐžĐŗĐģа да ҁĐĩ ŅƒŅ‡Đ¸Ņ‚Đ° gpm йийĐģĐ¸ĐžŅ‚ĐĩĐēа: %s" #, c-format msgid "dlerror = \"%s\"" msgstr "dlerror = „%s”" msgid "Opening the X display failed" -msgstr "ĐžŅ‚Đ˛Đ°Ņ€Đ°ŅšĐĩ X ĐŋŅ€Đ¸ĐēаСа ĐŊĐ¸Ņ˜Đĩ ҃ҁĐŋĐĩĐģĐž" +msgstr "ĐĐ¸Ņ˜Đĩ ҃ҁĐŋĐĩĐģĐž ĐžŅ‚Đ˛Đ°Ņ€Đ°ŅšĐĩ X ĐŋŅ€Đ¸ĐēаСа" msgid "XSMP handling save-yourself request" msgstr "XSMP ĐžĐŋҁĐģ҃Đļ҃ҘĐĩ ŅĐ°Ņ‡ŅƒĐ˛Đ°Ņ˜-ҁĐĩ ĐˇĐ°Ņ…Ņ‚Đĩв" @@ -2669,7 +2676,7 @@ msgid "Failed creating socket directory: %s" msgstr "НĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ ĐēŅ€ĐĩĐ¸Ņ€Đ° ŅĐžĐēĐĩŅ‚ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Ņ˜ŅƒĐŧ: %s" msgid "At line" -msgstr "Код ĐģиĐŊĐ¸Ņ˜Đĩ" +msgstr "На ĐģиĐŊĐ¸Ņ˜Đ¸" #, c-format msgid "Vim: Caught %s event\n" @@ -5465,10 +5472,6 @@ msgstr "E456: PostScript resource Ņ„Đ°Ņ˜Đģ „%s.ps” ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ msgid "E457: Can't read PostScript resource file \"%s\"" msgstr "E457: PostScript resource Ņ„Đ°Ņ˜Đģ „%s” ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ Ņ‡Đ¸Ņ‚Đ°" -msgid "E458: Cannot allocate colormap entry, some colors may be incorrect" -msgstr "" -"E458: colormap ŅŅ‚Đ°Đ˛Đēа ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ аĐģĐžŅ†Đ¸Ņ€Đ°, ĐŊĐĩĐēĐĩ ĐąĐžŅ˜Đĩ ҁ҃ ĐŧĐžĐļда ĐŊĐĩĐ¸ŅĐŋŅ€Đ°Đ˛ĐŊĐĩ" - msgid "E459: Cannot go back to previous directory" msgstr "E459: НĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ ОдĐĩ ĐŊаСад ĐŊа ĐŋŅ€ĐĩŅ‚Ņ…ĐžĐ´ĐŊи Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Ņ˜ŅƒĐŧ" @@ -6123,6 +6126,9 @@ msgstr "E647: НĐĩĐ¸ŅĐŋŅ€Đ°Đ˛ĐŊи идĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžŅ€ ĐąĐ°Ņ„ĐĩŅ€Đ° ҃ se msgid "E648: Invalid buffer identifier in close" msgstr "E648: НĐĩĐ¸ŅĐŋŅ€Đ°Đ˛ĐŊи идĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžŅ€ ĐąĐ°Ņ„ĐĩŅ€Đ° ҃ close" +msgid "E649: Invalid identifier name in defineAnnoType" +msgstr "E649: НĐĩĐ¸ŅĐŋŅ€Đ°Đ˛ĐŊĐž иĐŧĐĩ идĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžŅ€Đ° ҃ defineAnnoType" + msgid "E650: Invalid buffer identifier in defineAnnoType" msgstr "E650: НĐĩĐ¸ŅĐŋŅ€Đ°Đ˛ĐŊи идĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžŅ€ ĐąĐ°Ņ„ĐĩŅ€Đ° ҃ defineAnnoType" @@ -7046,10 +7052,11 @@ msgstr "E910: ĐŸĐžŅĐ°Đž ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ ĐēаО Đ‘Ņ€ĐžŅ˜" msgid "E911: Using a Job as a Float" msgstr "E911: ĐŸĐžŅĐ°Đž ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ ĐēаО ПоĐēŅ€ĐĩŅ‚ĐŊи" -msgid "E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" +msgid "" +"E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw, nl or blob channel" msgstr "" -"E912: Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ˜Đ° ch_evalexpr()/ch_sendexpr() ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ ŅĐ° raw иĐģи " -"nl ĐēаĐŊаĐģĐžĐŧ" +"E912: Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ˜Đ° ch_evalexpr()/ch_sendexpr() ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ ŅĐ° raw, nl " +"иĐģи blob ĐēаĐŊаĐģĐžĐŧ" msgid "E913: Using a Channel as a Number" msgstr "E913: КаĐŊаĐģ ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ ĐēаО Đ‘Ņ€ĐžŅ˜" @@ -8411,10 +8418,8 @@ msgstr "E1291: НĐĩваĐļĐĩŅ›Đ¸ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚: %ld" msgid "E1292: Command-line window is already open" msgstr "E1292: ĐŸŅ€ĐžĐˇĐžŅ€ ĐēĐžĐŧаĐŊĐ´ĐŊĐĩ ĐģиĐŊĐ¸Ņ˜Đĩ ҘĐĩ вĐĩŅ› ĐžŅ‚Đ˛ĐžŅ€ĐĩĐŊ" -msgid "E1293: Cannot use a negative id after adding a textprop with text" -msgstr "" -"E1293: НаĐēĐžĐŊ Đ´ĐžĐ´Đ°Đ˛Đ°ŅšĐ° Ņ‚ĐĩĐēҁ҂ ĐžŅĐžĐąĐ¸ĐŊĐĩ ŅĐ° Ņ‚ĐĩĐēŅŅ‚ĐžĐŧ ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ ҃ĐŋĐžŅ‚Ņ€Đĩйи " -"ĐŊĐĩĐŗĐ°Ņ‚Đ¸Đ˛Đ°ĐŊ id" +msgid "E1293: Cannot use a negative id for a text property" +msgstr "E1293: За Ņ‚ĐĩĐēҁ҂ ĐžŅĐžĐąĐ¸ĐŊ҃ ĐŧĐžĐļĐĩ да ҁĐĩ ҃ĐŋĐžŅ‚Ņ€Đĩйи ĐŊĐĩĐŗĐ°Ņ‚Đ¸Đ˛Đ°ĐŊ id" msgid "E1294: Can only use text_align when column is zero" msgstr "E1294: Када ҘĐĩ ĐēĐžĐģĐžĐŊа ĐŊ҃Đģа, ĐŧĐžĐļĐĩ да ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ ŅĐ°ĐŧĐž text_align" @@ -8559,13 +8564,6 @@ msgstr "E1335: ĐŖ ĐŋŅ€ĐžĐŧĐĩĐŊŅ™Đ¸Đ˛Ņƒ „%s” ҃ ĐēĐģĐ°ŅĐ¸ „%s” ĐŊĐĩ ĐŧĐž msgid "E1337: Class variable \"%s\" not found in class \"%s\"" msgstr "E1337: ĐŸŅ€ĐžĐŧĐĩĐŊŅ™Đ¸Đ˛Đ° ĐēĐģĐ°ŅĐĩ „%s” ĐŊĐ¸Ņ˜Đĩ ĐŋŅ€ĐžĐŊĐ°Ņ’ĐĩĐŊа ҃ ĐēĐģĐ°ŅĐ¸ „%s”" -msgid "" -"E1339: Cannot add a textprop with text after using a textprop with a " -"negative id" -msgstr "" -"E1339: ĐĸĐĩĐēҁ҂ ĐžŅĐžĐąĐ¸ĐŊа ŅĐ° Ņ‚ĐĩĐēŅŅ‚ĐžĐŧ ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ дОда ĐŊаĐēĐžĐŊ ҃ĐŋĐžŅ‚Ņ€ĐĩĐąĐĩ Ņ‚ĐĩĐēҁ҂ " -"ĐžŅĐžĐąĐ¸ĐŊĐĩ ŅĐ° ĐŊĐĩĐŗĐ°Ņ‚Đ¸Đ˛ĐŊиĐŧ id" - #, c-format msgid "E1340: Argument already declared in the class: %s" msgstr "E1340: ĐŅ€ĐŗŅƒĐŧĐĩĐŊŅ‚ ҘĐĩ вĐĩŅ› Đ´ĐĩŅ„Đ¸ĐŊĐ¸ŅĐ°ĐŊ ҃ ĐēĐģĐ°ŅĐ¸: %s" @@ -9100,7 +9098,7 @@ msgstr "E1545: ĐĄŅ‚ĐĩĐē Quickfix ĐģĐ¸ŅŅ‚Đĩ ĐŊĐ¸Ņ˜Đĩ Đ´ĐžŅŅ‚ŅƒĐŋаĐŊ" msgid "E1546: Cannot switch to a closing buffer" msgstr "E1546: НĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ ĐŋŅ€ĐĩŅ’Đĩ ĐŊа ĐąĐ°Ņ„ĐĩŅ€ ĐēĐžŅ˜Đ¸ ҁĐĩ ĐˇĐ°Ņ‚Đ˛Đ°Ņ€Đ°" -msgid "E1547: This version of Vim does support :redrawtabpanel" +msgid "E1547: This version of Vim does not support :redrawtabpanel" msgstr "E1547: Ова вĐĩŅ€ĐˇĐ¸Ņ˜Đ° Vim ĐĩĐ´Đ¸Ņ‚ĐžŅ€Đ° ĐŊĐĩ ĐŋĐžĐ´Ņ€Đļава :redrawtabpanel" msgid "E1548: Wayland connection is unavailable" @@ -9193,6 +9191,21 @@ msgstr "" "E1571: ĐœĐžŅ€Đ° да ҁĐĩ ĐŊавĐĩĐ´Đĩ ĐąĐ°Ņ€ĐĩĐŧ ҘĐĩĐ´ĐŊа Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ˜Đ° ĐŋĐžĐ˛Ņ€Đ°Ņ‚ĐŊĐžĐŗ ĐŋОСива Са " "redraw_listener_add" +msgid "E1572: 'listchars' field \"leadtab\" requires \"tab\" to be specified" +msgstr "E1572: 'listchars' ĐŋĐžŅ™Đĩ „leadtab” ĐˇĐ°Ņ…Ņ‚Đĩва да ҁĐĩ ĐŊавĐĩĐ´Đĩ „tab”" + +msgid "E1573: Cannot listen on port" +msgstr "E1573: НĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ ҁĐģŅƒŅˆĐ° ĐŊа ĐŋĐžŅ€Ņ‚Ņƒ" + +msgid "E1574: gethostbyname(): cannot resolve hostname in channel_listen()" +msgstr "E1574: gethostbyname(): ĐŊĐĩ ĐŧĐžĐļĐĩ да ҁĐĩ Ņ€Đ°ĐˇŅ€ĐĩŅˆĐ¸ иĐŧĐĩ Ņ…ĐžŅŅ‚Đ° ҃ channel_listen()" + +msgid "E1575: Cannot create pipes" +msgstr "E1575: НĐĩ ĐŧĐžĐŗŅƒ да ҁĐĩ ĐēŅ€ĐĩĐ¸Ņ€Đ°Ņ˜Ņƒ Ņ‚ĐžĐēОви ĐŋĐžĐ´Đ°Ņ‚Đ°Đēа" + +msgid "E1576: Tag file entry must not be a URL" +msgstr "E1576: ĐĄŅ‚Đ°Đ˛Đēа ҃ Ņ„Đ°Ņ˜Đģ҃ ОСĐŊаĐēа ĐŊĐĩ ҁĐŧĐĩ да ĐąŅƒĐ´Đĩ URL" + msgid "--No lines in buffer--" msgstr "--ĐŖ ĐąĐ°Ņ„ĐĩŅ€Ņƒ ĐŊĐĩĐŧа ĐģиĐŊĐ¸Ņ˜Đ°--" @@ -9750,6 +9763,9 @@ msgstr "ҁĐēŅ€ĐžĐģĐžĐ˛Đ°ŅšĐĩ ĐŋĐž ĐĩĐēŅ€Đ°ĐŊҁĐēĐžŅ˜ ĐģиĐŊĐ¸Ņ˜Đ¸" msgid "number of screen lines to show around the cursor" msgstr "ĐąŅ€ĐžŅ˜ ĐĩĐēŅ€Đ°ĐŊҁĐēĐ¸Ņ… ĐģиĐŊĐ¸Ņ˜Đ° ĐēĐžŅ˜Đĩ ҁĐĩ ĐŋŅ€Đ¸ĐēĐ°ĐˇŅƒŅ˜Ņƒ ĐžĐēĐž ĐēŅƒŅ€ŅĐžŅ€Đ°" +msgid "vertically center cursor even at end of file" +msgstr "҆ĐĩĐŊŅ‚Ņ€Đ¸Ņ€Đ°Ņ˜ ĐēŅƒŅ€ŅĐžŅ€ ĐŋĐž вĐĩŅ€Ņ‚Đ¸ĐēаĐģи Ņ‡Đ°Đē и ĐŊа ĐēŅ€Đ°Ņ˜Ņƒ Ņ„Đ°Ņ˜Đģа" + msgid "long lines wrap" msgstr "Đ´ŅƒĐŗĐĩ ĐģиĐŊĐ¸Ņ˜Đĩ ҁĐĩ ĐžĐąĐ°Đ˛Đ¸Ņ˜Đ°Ņ˜Ņƒ" @@ -9805,6 +9821,12 @@ msgstr "ĐąŅ€ĐžŅ˜ ĐģиĐŊĐ¸Ņ˜Đ° ĐēĐžŅ˜Đ¸ ҁĐēŅ€ĐžĐģ҃Ҙ҃ CTRL-F и CTRL-B" msgid "don't redraw while executing macros" msgstr "ĐĩĐēŅ€Đ°ĐŊ ҁĐĩ ĐŊĐĩ Đ¸ŅŅ†Ņ€Ņ‚Đ°Đ˛Đ° Ņ‚ĐžĐēĐžĐŧ Đ¸ĐˇĐ˛Ņ€ŅˆĐ°Đ˛Đ°ŅšĐ° ĐŧаĐēŅ€ĐžĐ°" +msgid "configure method of receiving terminal size changes" +msgstr "ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ¸ŅĐ°ŅšĐĩ ĐŧĐĩŅ‚ĐžĐ´Đĩ ĐŋŅ€Đ¸Ņ˜ĐĩĐŧа ĐŋŅ€ĐžĐŧĐĩĐŊа вĐĩĐģĐ¸Ņ‡Đ¸ĐŊĐĩ Ņ‚ĐĩŅ€ĐŧиĐŊаĐģа" + +msgid "enable terminal sync mode" +msgstr "҃ĐēŅ™ŅƒŅ‡Đ¸Đ˛Đ°ŅšĐĩ Ņ€ĐĩĐļиĐŧа ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐ¸ĐˇĐ°Ņ†Đ¸Ņ˜Đĩ Ņ‚ĐĩŅ€ĐŧиĐŊаĐģа" + msgid "timeout for 'hlsearch' and :match highlighting in msec" msgstr "Ņ‚Đ°Ņ˜ĐŧĐ°ŅƒŅ‚ Са 'hlsearch' и :match Đ¸ŅŅ‚Đ¸Ņ†Đ°ŅšĐĩ ҃ ĐŧиĐģĐ¸ŅĐĩĐē҃ĐŊдаĐŧа" @@ -9866,6 +9888,9 @@ msgstr "Đ¸ŅŅ‚Đ¸Ņ‡Ņƒ ҁĐĩ ŅĐ˛Đ° ĐŋĐžĐ´ŅƒĐ´Đ°Ņ€Đ°ŅšĐ° ĐŋĐžŅĐģĐĩĐ´ŅšĐĩ ĐēĐžŅ€Đ¸ msgid "highlight group to use for the window" msgstr "ĐŗŅ€ŅƒĐŋа Đ¸ŅŅ‚Đ¸Ņ†Đ°ŅšĐ° ĐēĐžŅ˜Đ° ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ Са ĐŋŅ€ĐžĐˇĐžŅ€" +msgid "highlight group mappings for the window" +msgstr "ĐŧаĐŋĐ¸Ņ€Đ°ŅšĐ° ĐŗŅ€ŅƒĐŋа Đ¸ŅŅ‚Đ¸Ņ†Đ°ŅšĐ° Са ĐŋŅ€ĐžĐˇĐžŅ€" + msgid "use GUI colors for the terminal" msgstr "Са Ņ‚ĐĩŅ€ĐŧиĐŊаĐģ ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đĩ ГКИ ĐąĐžŅ˜Đĩ" @@ -9911,6 +9936,9 @@ msgstr "0, 1 иĐģи 2; Đēада ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸ ŅŅ‚Đ°Ņ‚ŅƒŅĐŊа ĐģиĐŊĐ¸Ņ˜ msgid "alternate format to be used for a status line" msgstr "аĐģŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊи Ņ„ĐžŅ€ĐŧĐ°Ņ‚ ĐēĐžŅ˜Đ¸ Ņ›Đĩ ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸Ņ‚Đ¸ Са ŅŅ‚Đ°Ņ‚ŅƒŅĐŊ҃ ĐģиĐŊĐ¸Ņ˜Ņƒ" +msgid "optional settings for the status line" +msgstr "ĐŊĐĩОйавĐĩСĐŊа ĐŋОдĐĩŅˆĐ°Đ˛Đ°ŅšĐ° Са ŅŅ‚Đ°Ņ‚ŅƒŅĐŊ҃ ĐģиĐŊĐ¸Ņ˜Ņƒ" + msgid "make all windows the same size when adding/removing windows" msgstr "" "ĐŋĐžŅŅ‚Đ°Đ˛Ņ™Đ° ŅĐ˛Đĩ ĐŋŅ€ĐžĐˇĐžŅ€Đĩ ĐŊа Đ¸ŅŅ‚Ņƒ вĐĩĐģĐ¸Ņ‡Đ¸ĐŊ҃ Đēада ҁĐĩ ĐŋŅ€ĐžĐˇĐžŅ€Đ¸\n" @@ -10315,11 +10343,6 @@ msgstr "" msgid "Wayland seat to use" msgstr "Wayland ҁĐĩĐ´Đ¸ŅˆŅ‚Đĩ ĐēĐžŅ˜Đĩ ҁĐĩ ĐēĐžŅ€Đ¸ŅŅ‚Đ¸" -msgid "" -"Enable wayland focus stealing functionality in order to access the clipboard" -msgstr "" -"ĐŖĐēŅ™ŅƒŅ‡ŅƒŅ˜Đĩ wayland Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģĐŊĐžŅŅ‚ ĐēŅ€Đ°Ņ’Đĩ Ņ„ĐžĐēŅƒŅĐ° да йи ҁĐĩ ĐŋŅ€Đ¸ŅŅ‚ŅƒĐŋиĐģĐž ĐēĐģиĐŋĐąĐžŅ€Đ´Ņƒ" - msgid "\"startsel\" and/or \"stopsel\"; what special keys can do" msgstr "„startsel” и/иĐģи „stopsel”; ŅˆŅ‚Đ° ĐŧĐžĐŗŅƒ да ŅƒŅ€Đ°Đ´Đĩ ҁĐŋĐĩŅ†Đ¸Ņ˜Đ°ĐģĐŊи Ņ‚Đ°ŅŅ‚ĐĩŅ€Đ¸" @@ -10425,6 +10448,9 @@ msgstr "ĐŧаĐēŅĐ¸ĐŧаĐģĐŊа ŅˆĐ¸Ņ€Đ¸ĐŊа Đ¸ŅĐēĐ°Ņ‡ŅƒŅ›ĐĩĐŗ ĐŧĐĩĐŊĐ¸Ņ˜Đ°" msgid "popup border style" msgstr "ŅŅ‚Đ¸Đģ ĐžĐēĐ˛Đ¸Ņ€Đ° Đ¸ŅĐēĐ°Ņ‡ŅƒŅ›ĐĩĐŗ ĐŋŅ€ĐžĐˇĐžŅ€Đ°" +msgid "additional options for the popup menu" +msgstr "Đ´ĐžĐ´Đ°Ņ‚ĐŊĐĩ ĐžĐŋŅ†Đ¸Ņ˜Đĩ Са Đ¸ŅĐēĐ°Ņ‡ŅƒŅ›Đ¸ ĐŧĐĩĐŊи" + msgid "user defined function for Insert mode completion" msgstr "ĐēĐžŅ€Đ¸ŅĐŊĐ¸Ņ‡Đēи Đ´ĐĩŅ„Đ¸ĐŊĐ¸ŅĐ°ĐŊа Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ˜Đ° Са Đ´ĐžĐ˛Ņ€ŅˆĐ°Đ˛Đ°ŅšĐĩ ҃ Ņ€ĐĩĐļиĐŧ҃ ĐŖĐŧĐĩŅ‚Đ°ŅšĐĩ" @@ -10640,6 +10666,9 @@ msgstr "" msgid "allow setting expression options from a modeline" msgstr "ĐžĐŧĐžĐŗŅƒŅ›Đ°Đ˛Đ°ŅšĐĩ ĐŋĐžŅŅ‚Đ°Đ˛Ņ™Đ°ŅšĐ° ĐžĐŋŅ†Đ¸Ņ˜Đ° Đ¸ĐˇŅ€Đ°ĐˇĐ° иС Ņ€ĐĩĐļиĐŧҁĐēĐĩ ĐģиĐŊĐ¸Ņ˜Đĩ" +msgid "only allow safe options to be set from a modeline" +msgstr "иС Ņ€ĐĩĐļиĐŧҁĐēĐĩ ĐģиĐŊĐ¸Ņ˜Đĩ ĐŧĐžĐŗŅƒ да ҁĐĩ ĐŋĐžŅŅ‚Đ°Đ˛Đĩ ŅĐ°ĐŧĐž ĐąĐĩСйĐĩĐ´ĐŊĐĩ ĐžĐŋŅ†Đ¸Ņ˜Đĩ" + msgid "number of lines to check for modelines" msgstr "ĐąŅ€ĐžŅ˜ ĐģиĐŊĐ¸Ņ˜Đ° ĐēĐžŅ˜Đĩ ҁĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ°Đ˛Đ°Ņ˜Ņƒ ĐŊа ĐŋĐžŅŅ‚ĐžŅ˜Đ°ŅšĐĩ Ņ€ĐĩĐļиĐŧҁĐēĐĩ ĐģиĐŊĐ¸Ņ˜Đĩ" diff --git a/src/po/vim.pot b/src/po/vim.pot index b2e3b0f647..00c192a621 100644 --- a/src/po/vim.pot +++ b/src/po/vim.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Vim\n" "Report-Msgid-Bugs-To: vim-dev@vim.org\n" -"POT-Creation-Date: 2026-04-07 19:50+0000\n" +"POT-Creation-Date: 2026-05-23 19:49+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -254,9 +254,6 @@ msgstr "" msgid "%d of %d edited" msgstr "" -msgid "Socket server not online:Send expression failed" -msgstr "" - msgid "No display: Send expression failed.\n" msgstr "" @@ -921,9 +918,11 @@ msgstr "" msgid "VIM - Search..." msgstr "" +#. "Find what:" label + entry msgid "Find what:" msgstr "" +#. "Replace with:" label + entry msgid "Replace with:" msgstr "" @@ -957,6 +956,12 @@ msgstr "" msgid "_Close" msgstr "" +msgid "Direction:" +msgstr "" + +msgid "Close" +msgstr "" + msgid "Vim: Received \"die\" request from session manager\n" msgstr "" @@ -1714,7 +1719,8 @@ msgstr "" msgid "-Y\t\t\tDo not connect to Wayland compositor" msgstr "" -msgid "--clientserver Backend for clientserver communication" +msgid "" +"--clientserver Backend for clientserver communication" msgstr "" msgid "--remote \tEdit in a Vim server if possible" @@ -1969,6 +1975,9 @@ msgstr "" msgid "??? from here until ???END lines may be messed up" msgstr "" +msgid "??? block header corrupted" +msgstr "" + msgid "??? from here until ???END lines may have been inserted/deleted" msgstr "" @@ -2158,10 +2167,10 @@ msgstr "" msgid "\" already exists!" msgstr "" -msgid "VIM - ATTENTION" +msgid "Swap file already exists!" msgstr "" -msgid "Swap file already exists!" +msgid "VIM - ATTENTION" msgstr "" msgid "" @@ -2520,10 +2529,6 @@ msgstr "" msgid "XSMP SmcOpenConnection failed: %s" msgstr "" -#, c-format -msgid "Failed creating socket directory: %s" -msgstr "" - msgid "At line" msgstr "" @@ -2795,6 +2800,10 @@ msgstr "" msgid " (not supported)" msgstr "" +#, c-format +msgid "Failed creating socket directory: %s" +msgstr "" + #, c-format msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\"" msgstr "" @@ -3451,6 +3460,9 @@ msgstr "" msgid "without GUI." msgstr "" +msgid "with GTK4 GUI." +msgstr "" + msgid "with GTK3 GUI." msgstr "" @@ -5222,9 +5234,6 @@ msgstr "" msgid "E457: Can't read PostScript resource file \"%s\"" msgstr "" -msgid "E458: Cannot allocate colormap entry, some colors may be incorrect" -msgstr "" - msgid "E459: Cannot go back to previous directory" msgstr "" @@ -6769,7 +6778,8 @@ msgstr "" msgid "E911: Using a Job as a Float" msgstr "" -msgid "E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" +msgid "" +"E912: Cannot use ch_evalexpr()/ch_sendexpr() with a raw, nl or blob channel" msgstr "" msgid "E913: Using a Channel as a Number" @@ -8476,6 +8486,10 @@ msgstr "" msgid "E1405: Class \"%s\" cannot be used as a value" msgstr "" +#, c-format +msgid "E1406: Public and protected member have the same name: %s and _%s" +msgstr "" + msgid "E1407: Cannot use a Typealias as a variable or value" msgstr "" @@ -8818,20 +8832,20 @@ msgstr "" msgid "E1562: Diff anchors cannot be used with hidden diff windows" msgstr "" -msgid "E1563: Socket path is too big" -msgstr "" - -msgid "E1564: Socket name cannot have slashes in it without being a path" +#, c-format +msgid "E1564: Socket name '%s' cannot have slashes in it without being a path" msgstr "" msgid "E1565: Socket server is not online, call remote_startserver() first" msgstr "" #, c-format -msgid "E1566: Failed connecting to socket %s: %s" +msgid "E1566: Failed connecting to socket '%s'" msgstr "" -msgid "E1567: Cannot start socket server, socket path is unavailable" +msgid "" +"E1567: Socket server protocol version mismatch, check what Vim version you " +"are using" msgstr "" #, c-format @@ -8859,6 +8873,16 @@ msgstr "" msgid "E1575: Cannot create pipes" msgstr "" +msgid "E1576: Tag file entry must not be a URL" +msgstr "" + +#, c-format +msgid "E1577: Invalid format string, only one \"%s\" is allowed" +msgstr "" + +msgid "E1578: Too many postponed prefixes and/or compound flags" +msgstr "" + #. type of cmdline window or 0 #. result of cmdline window or 0 #. buffer of cmdline window or NULL @@ -9341,6 +9365,9 @@ msgstr "" msgid "file names in a tags file are relative to the tags file" msgstr "" +msgid "a :tag command cannot access remote files" +msgstr "" + msgid "a :tag command will use the tagstack" msgstr "" @@ -9383,6 +9410,9 @@ msgstr "" msgid "number of screen lines to show around the cursor" msgstr "" +msgid "vertically center cursor even at end of file" +msgstr "" + msgid "long lines wrap" msgstr "" @@ -9916,10 +9946,6 @@ msgstr "" msgid "Wayland seat to use" msgstr "" -msgid "" -"Enable wayland focus stealing functionality in order to access the clipboard" -msgstr "" - msgid "\"startsel\" and/or \"stopsel\"; what special keys can do" msgstr "" @@ -10223,6 +10249,9 @@ msgstr "" msgid "allow setting expression options from a modeline" msgstr "" +msgid "only allow safe options to be set from a modeline" +msgstr "" + msgid "number of lines to check for modelines" msgstr "" diff --git a/src/popupmenu.c b/src/popupmenu.c index 2ee720087d..b7929607d9 100644 --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -953,6 +953,10 @@ pum_redraw(void) // Use current window for highlight overrides when using 'winhighlight' override_success = push_highlight_overrides(curwin->w_hl, curwin->w_hl_len); + // Batch the underlying screen update and the pum drawing into a single + // synchronized output frame to avoid flicker. + term_set_sync_output(TERM_SYNC_OUTPUT_ENABLE); + hlf_T hlfsNorm[3]; hlf_T hlfsSel[3]; // "word"/"abbr" @@ -1187,6 +1191,8 @@ pum_redraw(void) if (override_success) pop_highlight_overrides(); + + term_set_sync_output(TERM_SYNC_OUTPUT_DISABLE); } #if defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX) @@ -1477,7 +1483,7 @@ pum_set_selected(int n, int repeat UNUSED) // window is not resized, skip the preview window's // status line redrawing. if (ins_compl_active() && !resized) - curwin->w_redr_status = FALSE; + curwin->w_redr_status = false; // Return cursor to where we were validate_cursor(); @@ -1507,7 +1513,7 @@ pum_set_selected(int n, int repeat UNUSED) // StatusLineNC for a moment and cause flicker. pum_will_redraw = !resized; save_redr_status = curwin_save->w_redr_status; - curwin_save->w_redr_status = FALSE; + curwin_save->w_redr_status = false; update_screen(0); pum_pretend_not_visible = FALSE; pum_will_redraw = FALSE; @@ -1611,8 +1617,12 @@ pum_visible(void) static int pum_in_same_position(void) { + int row = (State & MODE_CMDLINE) + ? cmdline_row + : curwin->w_wrow + W_WINROW(curwin); + return pum_window != curwin - || (pum_win_row == curwin->w_wrow + W_WINROW(curwin) + || (pum_win_row == row && pum_win_height == curwin->w_height && pum_win_col == curwin->w_wincol && pum_win_width == curwin->w_width); diff --git a/src/popupwin.c b/src/popupwin.c index d5fdbb8d26..87ea44de50 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -16,16 +16,72 @@ #if defined(FEAT_PROP_POPUP) typedef struct { - char *pp_name; + string_T pp_name; poppos_T pp_val; } poppos_entry_T; +// Snapshot of the popup's drawn rectangle. Used to redraw what becomes +// exposed when the popup moves, resizes, hides or closes. "active" is TRUE +// when the popup is an opacity popup that contributes to the blended +// background; non-opacity popups rely on popup_mask instead. +typedef struct { + int active; + int winrow; + int wincol; + int height; + int width; + int leftoff; + int zindex; +} popup_area_T; + +// Snapshot of the screen cells under an opacity popup's padding, captured +// before win_update() overwrites them so the padding can be re-blended +// against the original background. "lines" is NULL when no snapshot was +// taken; popup_free_saved_screen() releases all owned buffers. +typedef struct { + schar_T *lines; + int *attrs; + u8char_T *linesuc; + int start_row; + int start_col; + int rows; + int cols; +} popup_saved_screen_T; + +// Snapshot of popup style/option fields used by popup_setoptions() to detect +// which option changes require a redraw or reposition. +typedef struct { + linenr_T firstline; + int blend; + int flags; + int zindex; + char_u *scrollbar_highlight; + char_u *thumb_highlight; + char_u *border_highlight[4]; +} popup_style_snapshot_T; + +// Snapshot of popup layout fields used by popup_adjust_position() to detect +// whether the position or size changed and the popup mask must be refreshed. +typedef struct { + int winrow; + int wincol; + int width; + int height; + int leftcol; + int leftoff; + int has_scrollbar; + int topoff; + int bottomoff; + int leftclip; + int rightclip; +} popup_layout_T; + static poppos_entry_T poppos_entries[] = { - {"botleft", POPPOS_BOTLEFT}, - {"topleft", POPPOS_TOPLEFT}, - {"botright", POPPOS_BOTRIGHT}, - {"topright", POPPOS_TOPRIGHT}, - {"center", POPPOS_CENTER} + {STR_LITERAL_INIT("botleft"), POPPOS_BOTLEFT}, + {STR_LITERAL_INIT("topleft"), POPPOS_TOPLEFT}, + {STR_LITERAL_INIT("botright"), POPPOS_BOTRIGHT}, + {STR_LITERAL_INIT("topright"), POPPOS_TOPRIGHT}, + {STR_LITERAL_INIT("center"), POPPOS_CENTER} }; #ifdef HAS_MESSAGE_WINDOW @@ -46,8 +102,20 @@ static void may_start_message_win_timer(win_T *wp); static int popup_on_cmdline = FALSE; static void popup_adjust_position(win_T *wp); +static bool popup_area_changed(win_T *wp, popup_area_T *area); +static void popup_redraw_exposed_area(popup_area_T *area); +static void popup_save_area(win_T *wp, popup_area_T *area); +static void popup_free_saved_screen(popup_saved_screen_T *saved_screen); +static void popup_save_padding_screen(win_T *wp, + popup_saved_screen_T *saved_screen); +static bool popup_layout_changed(win_T *wp, popup_layout_T *layout); +static bool popup_style_changed(win_T *wp, popup_style_snapshot_T *style); +static void popup_save_style(win_T *wp, popup_style_snapshot_T *style); +static void popup_save_layout(win_T *wp, popup_layout_T *layout); static void redraw_under_popup_area(int winrow, int wincol, int height, int width, int leftoff); +static void redraw_overlapped_opacity_popups(int winrow, int wincol, + int height, int width, int leftoff, int zindex); /* * Get option value for "key", which is "line" or "col". @@ -474,7 +542,7 @@ get_pos_entry(dict_T *d, int give_error) return POPPOS_NONE; for (nr = 0; nr < (int)ARRAY_LENGTH(poppos_entries); ++nr) - if (STRCMP(str, poppos_entries[nr].pp_name) == 0) + if (STRCMP(str, poppos_entries[nr].pp_name.string) == 0) return poppos_entries[nr].pp_val; if (give_error) @@ -774,6 +842,15 @@ apply_general_options(win_T *wp, dict_T *dict) wp->w_popup_flags &= ~POPF_POSINVERT; } + nr = dict_get_bool(dict, "clipwindow", -1); + if (nr != -1) + { + if (nr) + wp->w_popup_flags |= POPF_CLIPWINDOW; + else + wp->w_popup_flags &= ~POPF_CLIPWINDOW; + } + nr = dict_get_bool(dict, "resize", -1); if (nr != -1) { @@ -880,7 +957,7 @@ apply_general_options(win_T *wp, dict_T *dict) int i; CHECK_LIST_MATERIALIZE(list); - wp->w_border_highlight_isset = TRUE; + wp->w_border_highlight_isset = true; // Clear all highlights if list is empty if (list->lv_len == 0) { @@ -1256,6 +1333,404 @@ popup_extra_width(win_T *wp) + wp->w_has_scrollbar; } +/* + * Return the host window used to clip popup "wp" when POPF_CLIPWINDOW is set, + * or NULL when no clipping should be applied (option off, or the host window + * is no longer valid). The textprop window is used as the host; popups not + * anchored to a textprop are not clipped. + */ + static win_T * +popup_get_clipwin(win_T *wp) +{ + if (!(wp->w_popup_flags & POPF_CLIPWINDOW)) + return NULL; + if (win_valid(wp->w_popup_prop_win)) + return wp->w_popup_prop_win; + return NULL; +} + +// Per-popup clip geometry derived from w_popup_{top,bottom}off and +// w_popup_{left,right}clip. Filled by popup_compute_clip(). +// +// *_extra : original border+padding at each edge. +// clip_*_content : how many *content* rows/cols are clipped at each edge +// (border/padding is consumed first; the rest comes off +// w_height/w_width). >= 0. +// eff_border[], +// eff_padding[] : per-edge border/padding sizes (indexed [top,right,bot,left] +// matching wp->w_popup_border / wp->w_popup_padding). The +// clip consumes the border first, then the padding, so when +// only the border is clipped the padding still survives. +// Drawing code can replace +// `wp->w_popup_border[N] > 0 && wp->w_popup_*clip == 0` +// with a single `cl.eff_border[N] > 0` test. +// eff_*_extra : eff_border + eff_padding at that edge (visible decoration). +// eff_height : drawn extent = eff_top_extra + visible content + eff_bot_extra. +// eff_width : drawn extent = eff_left_extra + visible content + eff_right_extra +// (does NOT include w_leftcol or scrollbar; see callers). +typedef struct { + int top_extra; + int bot_extra; + int left_extra; + int right_extra; + + int clip_top_content; + int clip_bot_content; + int clip_left_content; + int clip_right_content; + + int eff_top_extra; + int eff_bot_extra; + int eff_left_extra; + int eff_right_extra; + + int eff_border[4]; + int eff_padding[4]; + + int eff_height; + int eff_width; +} popup_clip_T; + + static void +popup_compute_clip(win_T *wp, popup_clip_T *cl) +{ + int h, w; + + cl->top_extra = popup_top_extra(wp); + cl->bot_extra = wp->w_popup_padding[2] + wp->w_popup_border[2]; + cl->left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3]; + cl->right_extra = wp->w_popup_border[1] + wp->w_popup_padding[1]; + + cl->clip_top_content = wp->w_popup_topoff - cl->top_extra; + if (cl->clip_top_content < 0) + cl->clip_top_content = 0; + cl->clip_bot_content = wp->w_popup_bottomoff - cl->bot_extra; + if (cl->clip_bot_content < 0) + cl->clip_bot_content = 0; + cl->clip_left_content = wp->w_popup_leftclip - cl->left_extra; + if (cl->clip_left_content < 0) + cl->clip_left_content = 0; + cl->clip_right_content = wp->w_popup_rightclip - cl->right_extra; + if (cl->clip_right_content < 0) + cl->clip_right_content = 0; + + // Border is consumed before padding: when only the border row/column is + // clipped, the adjacent padding row/column is still visible. Horizontal + // edges keep the previous all-or-nothing behaviour for now; the drawing + // code there still uses original w_popup_border / w_popup_padding offsets. + { + int clip = wp->w_popup_topoff; + int b = wp->w_popup_border[0]; + int p = wp->w_popup_padding[0]; + int rem; + + if (clip >= b) + { + cl->eff_border[0] = 0; + rem = clip - b; + cl->eff_padding[0] = (rem >= p) ? 0 : p - rem; + } + else + { + cl->eff_border[0] = b; + cl->eff_padding[0] = p; + } + } + { + int clip = wp->w_popup_bottomoff; + int b = wp->w_popup_border[2]; + int p = wp->w_popup_padding[2]; + int rem; + + if (clip >= b) + { + cl->eff_border[2] = 0; + rem = clip - b; + cl->eff_padding[2] = (rem >= p) ? 0 : p - rem; + } + else + { + cl->eff_border[2] = b; + cl->eff_padding[2] = p; + } + } + cl->eff_border[1] = wp->w_popup_rightclip > 0 ? 0 : wp->w_popup_border[1]; + cl->eff_border[3] = wp->w_popup_leftclip > 0 ? 0 : wp->w_popup_border[3]; + cl->eff_padding[1] = wp->w_popup_rightclip > 0 ? 0 : wp->w_popup_padding[1]; + cl->eff_padding[3] = wp->w_popup_leftclip > 0 ? 0 : wp->w_popup_padding[3]; + + // When a clip on one edge runs past the content rows, the excess must + // eat into the OPPOSITE edge's decorations. Otherwise the surviving + // padding/border can land outside the host (e.g. a popup whose body is + // wholly below the host still drew its top padding onto the status row). + { + int excess = wp->w_popup_bottomoff - cl->bot_extra - wp->w_height; + if (excess > 0) + { + if (excess >= cl->eff_padding[0]) + { + excess -= cl->eff_padding[0]; + cl->eff_padding[0] = 0; + if (excess >= cl->eff_border[0]) + cl->eff_border[0] = 0; + else + cl->eff_border[0] -= excess; + } + else + cl->eff_padding[0] -= excess; + } + } + { + int excess = wp->w_popup_topoff - cl->top_extra - wp->w_height; + if (excess > 0) + { + if (excess >= cl->eff_padding[2]) + { + excess -= cl->eff_padding[2]; + cl->eff_padding[2] = 0; + if (excess >= cl->eff_border[2]) + cl->eff_border[2] = 0; + else + cl->eff_border[2] -= excess; + } + else + cl->eff_padding[2] -= excess; + } + } + + cl->eff_top_extra = cl->eff_border[0] + cl->eff_padding[0]; + cl->eff_bot_extra = cl->eff_border[2] + cl->eff_padding[2]; + cl->eff_left_extra = wp->w_popup_leftclip > 0 ? 0 : cl->left_extra; + cl->eff_right_extra = wp->w_popup_rightclip > 0 ? 0 : cl->right_extra; + + h = wp->w_height - cl->clip_top_content - cl->clip_bot_content; + if (h < 0) + h = 0; + cl->eff_height = cl->eff_top_extra + h + cl->eff_bot_extra; + + w = wp->w_width - cl->clip_left_content - cl->clip_right_content; + if (w < 0) + w = 0; + cl->eff_width = cl->eff_left_extra + w + cl->eff_right_extra; +} + +// Snapshot of the popup window geometry that update_popups() temporarily +// mutates so that win_update() draws within the host-window clip rectangle. +// Saved before the clip is applied, restored after win_update() returns so +// callers continue to see the popup's logical geometry. +// Field names omit the "w_" prefix to avoid clashing with struct-field +// macros like w_p_wrap (= w_onebuf_opt.wo_wrap). +typedef struct { + int height; + int width; + int winrow; + int wincol; + int leftcol; + int p_wrap; + linenr_T topline; +} popup_geom_save_T; + + static void +popup_geom_save(win_T *wp, popup_geom_save_T *sv) +{ + sv->height = wp->w_height; + sv->width = wp->w_width; + sv->winrow = wp->w_winrow; + sv->wincol = wp->w_wincol; + sv->leftcol = wp->w_leftcol; + sv->p_wrap = wp->w_p_wrap; + sv->topline = wp->w_topline; +} + + static void +popup_geom_restore(win_T *wp, popup_geom_save_T *sv) +{ + wp->w_p_wrap = sv->p_wrap; + wp->w_leftcol = sv->leftcol; + wp->w_wincol = sv->wincol; + wp->w_winrow = sv->winrow; + wp->w_topline = sv->topline; + wp->w_width = sv->width; + wp->w_height = sv->height; +} + +/* + * Compute a screen row for a textprop that has scrolled above the host + * window's top. textpos2screenpos() cannot return a row above topline, so + * compute the virtual column directly from the prop's *own* line and then + * extrapolate a (possibly-negative) row by counting how many buffer lines + * lie between the prop and topline. The popup_topoff clip path turns the + * negative row into a top-clip animation as the prop rolls off the top edge. + * + * Probing at topline with the prop's tp_col would inherit topline's tab + * stops / multi-byte widths, so the popup's wincol would jitter every time + * a wider/narrower line scrolled into the topmost position. + */ + static void +popup_screenpos_above_top( + win_T *prop_win, + pos_T *pos, + linenr_T prop_lnum, + int *screen_row, + int *screen_scol, + int *screen_ccol, + int *screen_ecol) +{ + pos_T probe = *pos; + colnr_T scol = 0, ccol = 0, ecol = 0; + int coloff; + + probe.lnum = prop_lnum; + getvcol(prop_win, &probe, &scol, &ccol, &ecol, 0); + coloff = (int)win_col_off(prop_win) - (int)prop_win->w_leftcol + + prop_win->w_wincol + 1; + *screen_scol = (int)scol + coloff; + *screen_ccol = (int)ccol + coloff; + *screen_ecol = (int)ecol + coloff; + *screen_row = prop_win->w_winrow + 1 + - (int)(prop_win->w_topline - prop_lnum); +} + +/* + * Hide popup "wp" because its anchoring textprop is no longer reachable. + * Marks the popup as POPF_HIDDEN (no-op when already hidden) and schedules a + * redraw of the host window so any leftover decorations are cleared. + */ + static void +popup_hide_for_textprop(win_T *wp) +{ + if ((wp->w_popup_flags & POPF_HIDDEN) != 0) + return; + wp->w_popup_flags |= POPF_HIDDEN; + if (win_valid(wp->w_popup_prop_win)) + redraw_win_later(wp->w_popup_prop_win, UPD_SOME_VALID); +} + +/* + * For "clipwindow" popups: search the lines above prop_win->w_topline for the + * popup's anchoring textprop and report whether one was found. When + * "max_reach" is > 0, only the last "max_reach" lines before topline are + * scanned; pass 0 to scan all lines from line 1. Returns false when the + * popup is not "clipwindow", topline is already at line 1, or no prop matches. + */ + static bool +popup_find_prop_above_top( + win_T *wp, + win_T *prop_win, + int max_reach, + textprop_T *prop, + linenr_T *found_lnum) +{ + linenr_T first; + + if (!(wp->w_popup_flags & POPF_CLIPWINDOW) || prop_win->w_topline <= 1) + return false; + + first = max_reach > 0 ? prop_win->w_topline - max_reach : 1; + if (first < 1) + first = 1; + return find_prop_in_lines(prop_win, + wp->w_popup_prop_type, wp->w_popup_prop_id, + prop, found_lnum, first, prop_win->w_topline - 1); +} + +/* + * Compute and assign w_popup_topoff/bottomoff/leftclip/rightclip from the + * host (textprop) window's content rectangle when POPF_CLIPWINDOW is set. + * The popup's logical geometry (w_winrow, w_height, w_width) is preserved; + * only the *off/clip fields record how much of each edge falls outside. + * Returns true when the popup has scrolled completely past one of the host + * edges, in which case the caller must hide it. + */ + static bool +popup_compute_clipwindow_offsets(win_T *wp) +{ + win_T *cw = popup_get_clipwin(wp); + int extra_h, extra_w; + int popup_top, popup_bottom, popup_left, popup_right; + int total_h, total_w; + + if (cw == NULL) + return false; + + extra_h = popup_top_extra(wp) + + wp->w_popup_padding[2] + wp->w_popup_border[2]; + extra_w = popup_extra_width(wp); + + popup_top = wp->w_winrow; + popup_bottom = wp->w_winrow + wp->w_height + extra_h; + popup_left = wp->w_wincol; + popup_right = wp->w_wincol + wp->w_width + extra_w; + total_h = wp->w_height + extra_h; + total_w = wp->w_width + extra_w; + + if (popup_top < cw->w_winrow) + wp->w_popup_topoff = cw->w_winrow - popup_top; + if (popup_bottom > cw->w_winrow + cw->w_height) + wp->w_popup_bottomoff = popup_bottom - (cw->w_winrow + cw->w_height); + if (popup_left < cw->w_wincol) + wp->w_popup_leftclip = cw->w_wincol - popup_left; + if (popup_right > cw->w_wincol + cw->w_width) + wp->w_popup_rightclip = popup_right - (cw->w_wincol + cw->w_width); + + return wp->w_popup_topoff >= total_h + || wp->w_popup_bottomoff >= total_h + || wp->w_popup_leftclip >= total_w + || wp->w_popup_rightclip >= total_w; +} + +/* + * Mutate "wp"'s window geometry so win_update() draws only the rows/columns + * that fit within the host-window clip rectangle for "clipwindow" popups. + * The caller must save the original geometry with popup_geom_save() before + * this call and restore it with popup_geom_restore() after win_update(). + * + * Vertical clip: shrink w_height by the clipped content rows; advance + * w_topline and w_winrow when rows are cut off the top so the first visible + * content row lands on the host's top edge. + * + * Horizontal clip: when the right side is clipped, just shrink w_width. + * When the left side is clipped, advance w_leftcol so the hidden buffer + * columns scroll off and shift w_wincol so the first visible column lands on + * the host's left edge. Disable wrap so the transient w_width reduction does + * not reflow wrapped lines: the popup's logical width is unchanged, we just + * want to truncate cells that fall outside the host at draw time. + */ + static void +popup_apply_winupdate_clip(win_T *wp, popup_clip_T *cl) +{ + if (wp->w_popup_topoff > 0 || wp->w_popup_bottomoff > 0) + { + wp->w_height -= cl->clip_top_content + cl->clip_bot_content; + if (wp->w_height < 0) + wp->w_height = 0; + if (cl->clip_top_content > 0) + { + wp->w_topline += cl->clip_top_content; + wp->w_winrow += cl->clip_top_content; + } + } + if (wp->w_popup_leftclip > 0 || wp->w_popup_rightclip > 0) + { + if (cl->clip_left_content > 0 || cl->clip_right_content > 0) + wp->w_p_wrap = FALSE; + if (cl->clip_right_content > 0) + { + wp->w_width -= cl->clip_right_content; + if (wp->w_width < 0) + wp->w_width = 0; + } + if (cl->clip_left_content > 0) + { + wp->w_leftcol += cl->clip_left_content; + wp->w_wincol += cl->clip_left_content; + wp->w_width -= cl->clip_left_content; + if (wp->w_width < 0) + wp->w_width = 0; + } + } +} + /* * Adjust the position and size of the popup to fit on the screen. */ @@ -1282,12 +1757,7 @@ popup_adjust_position(win_T *wp) int extra_height = top_extra + bot_extra; int extra_width = left_extra + right_extra; int w_height_before_limit; - int org_winrow = wp->w_winrow; - int org_wincol = wp->w_wincol; - int org_width = wp->w_width; - int org_height = wp->w_height; - int org_leftcol = wp->w_leftcol; - int org_leftoff = wp->w_popup_leftoff; + popup_layout_T org_layout; int minwidth, minheight; int maxheight = Rows; int wantline = wp->w_wantline; // adjusted for textprop @@ -1295,11 +1765,17 @@ popup_adjust_position(win_T *wp) int use_wantcol = wantcol != 0; int adjust_height_for_top_aligned = FALSE; + popup_save_layout(wp, &org_layout); + wp->w_winrow = 0; wp->w_wincol = 0; wp->w_leftcol = 0; wp->w_popup_leftoff = 0; wp->w_popup_rightoff = 0; + wp->w_popup_topoff = 0; + wp->w_popup_bottomoff = 0; + wp->w_popup_leftclip = 0; + wp->w_popup_rightclip = 0; // May need to update the "cursorline" highlighting, which may also change // "topline" @@ -1317,20 +1793,24 @@ popup_adjust_position(win_T *wp) int screen_ccol; int screen_ecol; - // Popup window is positioned relative to a text property. + // Popup window is positioned relative to a text property. With + // "clipwindow", keep the popup visible while the textprop has just + // scrolled above the host's top: extrapolate a negative screen_row + // from a prop above topline so the top-clip path can roll the popup + // off the top edge. Unhiding is done in check_popup_unhidden(). + bool prop_above_top = false; if (!find_visible_prop(prop_win, wp->w_popup_prop_type, wp->w_popup_prop_id, &prop, &prop_lnum)) { - // Text property is no longer visible, hide the popup. - // Unhiding the popup is done in check_popup_unhidden(). - if ((wp->w_popup_flags & POPF_HIDDEN) == 0) + if (popup_find_prop_above_top(wp, prop_win, 0, + &prop, &prop_lnum)) + prop_above_top = true; + else { - wp->w_popup_flags |= POPF_HIDDEN; - if (win_valid(wp->w_popup_prop_win)) - redraw_win_later(wp->w_popup_prop_win, UPD_SOME_VALID); + popup_hide_for_textprop(wp); + return; } - return; } // Compute the desired position from the position of the text @@ -1340,7 +1820,11 @@ popup_adjust_position(win_T *wp) if (wp->w_popup_pos == POPPOS_TOPLEFT || wp->w_popup_pos == POPPOS_BOTLEFT) pos.col += prop.tp_len - 1; - textpos2screenpos(prop_win, &pos, &screen_row, + if (prop_above_top) + popup_screenpos_above_top(prop_win, &pos, prop_lnum, &screen_row, + &screen_scol, &screen_ccol, &screen_ecol); + else + textpos2screenpos(prop_win, &pos, &screen_row, &screen_scol, &screen_ccol, &screen_ecol); if (screen_scol == 0) @@ -1410,16 +1894,26 @@ popup_adjust_position(win_T *wp) || wp->w_popup_pos == POPPOS_BOTLEFT)) { wp->w_wincol = wantcol - 1; - // Need to see at least one character after the decoration. - if (wp->w_wincol > firstwin->w_wincol + topframe->fr_width - left_extra - 1) - wp->w_wincol = firstwin->w_wincol + topframe->fr_width - left_extra - 1; + // Need to see at least one character of content plus the right + // border/padding/shadow after the decoration. + if (wp->w_wincol > firstwin->w_wincol + topframe->fr_width + - left_extra - right_extra - 1) + wp->w_wincol = firstwin->w_wincol + topframe->fr_width + - left_extra - right_extra - 1; } } + // Keep the popup out of the tabpanel area so the available width is + // computed correctly below. + if (wp->w_wincol < firstwin->w_wincol) + wp->w_wincol = firstwin->w_wincol; + // When centering or right aligned, use maximum width. // When left aligned use the space available, but shift to the left when we // hit the right of the screen. - maxspace = firstwin->w_wincol + topframe->fr_width - wp->w_wincol - left_extra; + // Reserve room for the right border/padding/shadow so the popup fits. + maxspace = firstwin->w_wincol + topframe->fr_width + - wp->w_wincol - left_extra - right_extra; maxwidth = maxspace; if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth) { @@ -1481,6 +1975,27 @@ popup_adjust_position(win_T *wp) // backwards. // TODO: more accurate wrapping wp->w_width = 1; + // Pre-scan every buffer line to find the widest one, so the popup width + // stays stable when scrolling changes which lines are visible. + { + linenr_T ln; + int saved_w_width = wp->w_width; + + if (wp->w_width < maxwidth) + wp->w_width = maxwidth; + for (ln = 1; ln <= wp->w_buffer->b_ml.ml_line_count; ++ln) + { + int len = linetabsize(wp, ln) + margin_width; + + if (wp->w_maxwidth > 0 && len > wp->w_maxwidth) + len = wp->w_maxwidth; + if (saved_w_width < len) + saved_w_width = len; + if (wp->w_maxwidth > 0 && saved_w_width >= wp->w_maxwidth) + break; + } + wp->w_width = saved_w_width; + } if (wp->w_firstline < 0) lnum = wp->w_buffer->b_ml.ml_line_count; else @@ -1566,7 +2081,7 @@ popup_adjust_position(win_T *wp) if (wp->w_buffer->b_term != NULL && !term_is_finished(wp->w_buffer)) // Terminal window with running job never has a scrollbar, adjusts to // window height. - wp->w_has_scrollbar = FALSE; + wp->w_has_scrollbar = false; #endif maxwidth_no_scrollbar = maxwidth; if (wp->w_has_scrollbar) @@ -1615,9 +2130,10 @@ popup_adjust_position(win_T *wp) } if (center_hor) { - wp->w_wincol = (firstwin->w_wincol + topframe->fr_width - wp->w_width - extra_width) / 2; - if (wp->w_wincol < 0) - wp->w_wincol = 0; + wp->w_wincol = firstwin->w_wincol + + (topframe->fr_width - wp->w_width - extra_width) / 2; + if (wp->w_wincol < firstwin->w_wincol) + wp->w_wincol = firstwin->w_wincol; } else if (wp->w_popup_pos == POPPOS_BOTRIGHT || wp->w_popup_pos == POPPOS_TOPRIGHT) @@ -1678,8 +2194,11 @@ popup_adjust_position(win_T *wp) else if (wp->w_popup_pos == POPPOS_BOTRIGHT || wp->w_popup_pos == POPPOS_BOTLEFT) { - if ((wp->w_height + extra_height) <= wantline) - // bottom aligned: may move down + if ((wp->w_height + extra_height) <= wantline + || (wp->w_popup_flags & POPF_CLIPWINDOW)) + // bottom aligned: may move down. With "clipwindow" the popup + // keeps its natural position even if it overflows the screen, + // because the clip logic handles the overflow. wp->w_winrow = wantline - (wp->w_height + extra_height); else if (wantline * 2 >= Rows || !(wp->w_popup_flags & POPF_POSINVERT)) { @@ -1727,16 +2246,20 @@ popup_adjust_position(win_T *wp) } if (adjust_height_for_top_aligned && wp->w_want_scrollbar + && !(wp->w_popup_flags & POPF_CLIPWINDOW) && wp->w_winrow + wp->w_height + extra_height > Rows) { // Bottom of the popup goes below the last line, reduce the height and - // add a scrollbar. + // add a scrollbar. For "clipwindow" popups the host-window clip + // already truncates the popup to fit inside the host, so we must not + // also force a scrollbar here -- that would widen the popup by one + // column the moment its decoration crossed the screen edge. wp->w_height = Rows - wp->w_winrow - extra_height; #ifdef FEAT_TERMINAL if (wp->w_buffer->b_term == NULL || term_is_finished(wp->w_buffer)) #endif { - wp->w_has_scrollbar = TRUE; + wp->w_has_scrollbar = true; if (width_with_scrollbar > 0) wp->w_width = width_with_scrollbar; } @@ -1745,35 +2268,78 @@ popup_adjust_position(win_T *wp) // make sure w_winrow is valid if (wp->w_winrow >= Rows) wp->w_winrow = Rows - 1; - else if (wp->w_winrow < 0) + else if (wp->w_winrow < 0 && !(wp->w_popup_flags & POPF_CLIPWINDOW)) wp->w_winrow = 0; - if (wp->w_wincol + wp->w_width > firstwin->w_wincol + topframe->fr_width) - wp->w_wincol = firstwin->w_wincol + topframe->fr_width - wp->w_width; - else if (wp->w_wincol < firstwin->w_wincol) + if (wp->w_wincol + wp->w_width + extra_width + > firstwin->w_wincol + topframe->fr_width) + wp->w_wincol = firstwin->w_wincol + topframe->fr_width + - wp->w_width - extra_width; + if (wp->w_wincol < firstwin->w_wincol) wp->w_wincol = firstwin->w_wincol; if (wp->w_wincol < 0) wp->w_wincol = 0; + // If the popup is wider than the available area (e.g. minwidth larger than + // the work area between tabpanels), clip the content width so the right + // border/padding/shadow stays visible instead of being pushed off the + // screen or into the tabpanel. + if (wp->w_wincol + wp->w_width + extra_width + > firstwin->w_wincol + topframe->fr_width) + { + int avail = firstwin->w_wincol + topframe->fr_width + - wp->w_wincol - extra_width; + wp->w_width = avail > 0 ? avail : 0; + } - if (wp->w_height != org_height) + // Same for the bottom edge: shift up so the border/padding/shadow stays + // on screen, and clip the height if the popup is taller than the screen. + // For "clipwindow" popups the host-window clip below handles overflow, so + // skip these screen-edge clamps -- otherwise a synthesised negative + // w_winrow (popup partially above the host's top edge) would be snapped + // back to 0 and defeat the top-clip animation. + if (!(wp->w_popup_flags & POPF_CLIPWINDOW)) + { + if (wp->w_winrow + wp->w_height + extra_height > Rows) + wp->w_winrow = Rows - wp->w_height - extra_height; + if (wp->w_winrow < 0) + wp->w_winrow = 0; + if (wp->w_winrow + wp->w_height + extra_height > Rows) + { + int avail = Rows - wp->w_winrow - extra_height; + wp->w_height = avail > 0 ? avail : 0; + } + } + + if (wp->w_height != org_layout.height) win_comp_scroll(wp); + // Confine the popup to its host window for "clipwindow". The popup's + // logical geometry stays untouched; only w_popup_topoff/bottomoff/ + // leftclip/rightclip record how many rows/columns of each edge fall + // outside the host so the drawing code can skip them. When the popup + // has fully scrolled past one of the host edges, hide it instead of + // leaving stray decorations behind. + if (popup_compute_clipwindow_offsets(wp)) + { + popup_hide_for_textprop(wp); + return; + } + wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer); if (win_valid(wp->w_popup_prop_win)) { wp->w_popup_prop_changedtick = CHANGEDTICK(wp->w_popup_prop_win->w_buffer); wp->w_popup_prop_topline = wp->w_popup_prop_win->w_topline; + wp->w_popup_prop_winrow = wp->w_popup_prop_win->w_winrow; + wp->w_popup_prop_wincol = wp->w_popup_prop_win->w_wincol; + wp->w_popup_prop_width = wp->w_popup_prop_win->w_width; + wp->w_popup_prop_winheight = wp->w_popup_prop_win->w_height; } // Need to update popup_mask if the position or size changed. // And redraw windows and statuslines that were behind the popup. - if (org_winrow != wp->w_winrow - || org_wincol != wp->w_wincol - || org_leftcol != wp->w_leftcol - || org_leftoff != wp->w_popup_leftoff - || org_width != wp->w_width - || org_height != wp->w_height) + if (popup_layout_changed(wp, &org_layout)) { redraw_win_later(wp, UPD_NOT_VALID); if (wp->w_popup_flags & POPF_ON_CMDLINE) @@ -2104,6 +2670,19 @@ parse_popup_option(win_T *wp, int is_preview) if (wp != NULL && menu) wp->w_popup_flags |= POPF_INFO_MENU; } + else if (STRNCMP(s, "opacity:", 8) == 0) + { + if (dig != p || x < 0 || x > 100) + return FAIL; + if (wp != NULL) + { + if (x < 100) + wp->w_popup_flags |= POPF_OPACITY; + else + wp->w_popup_flags &= ~POPF_OPACITY; + wp->w_popup_blend = 100 - x; + } + } else return FAIL; } @@ -2285,6 +2864,9 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) dict_T *d = NULL; int i; + if (check_secure()) + return NULL; + if (argvars != NULL) { if (in_vim9script() @@ -2395,10 +2977,11 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) buf->b_locked = TRUE; // prevent deleting the buffer // Avoid that 'buftype' is reset when this buffer is entered. - buf->b_p_initialized = TRUE; + buf->b_p_initialized = true; } wp->w_p_wrap = TRUE; // 'wrap' is default on wp->w_p_so = 0; // 'scrolloff' zero + wp->w_p_sop = 0; // 'scrolloffpad' zero if (tp != NULL) { @@ -3020,9 +3603,39 @@ f_popup_close(typval_T *argvars, typval_T *rettv UNUSED) popup_close_and_callback(wp, &argvars[1]); } +/* + * Clear popup_mask entries for the cells covered by "wp" so that + * screen_fill / screen_puts calls made before the next update_screen() + * (e.g. msg_clr_eos triggered by a status message) are not silently + * dropped by skip_for_popup(). Without this the popup's chars survive + * on screen until may_update_popup_mask() runs and the affected cells + * happen to be redrawn. + */ + static void +popup_clear_mask_for(win_T *wp) +{ + int r, c; + int row_start, col_start, row_end, col_end; + + if (popup_mask == NULL || !popup_visible) + return; + + row_start = MAX(wp->w_winrow, 0); + col_start = MAX(wp->w_wincol, 0); + row_end = MIN(wp->w_winrow + popup_height(wp), (int)screen_Rows); + col_end = MIN(wp->w_wincol + popup_width(wp), (int)screen_Columns); + + for (r = row_start; r < row_end; ++r) + for (c = col_start; c < col_end; ++c) + popup_mask[r * screen_Columns + c] = 0; +} + void popup_hide(win_T *wp) { + popup_area_T old_area; + int was_visible = (wp->w_popup_flags & POPF_HIDDEN) == 0; + #ifdef FEAT_TERMINAL if (error_if_term_popup_window()) return; @@ -3030,13 +3643,24 @@ popup_hide(win_T *wp) if ((wp->w_popup_flags & POPF_HIDDEN) != 0) return; + popup_save_area(wp, &old_area); + wp->w_popup_flags |= POPF_HIDDEN; // Do not decrement b_nwindows, we still reference the buffer. if (wp->w_winrow + popup_height(wp) >= cmdline_row) clear_cmdline = TRUE; - redraw_all_later(UPD_NOT_VALID); + + if (was_visible) + popup_clear_mask_for(wp); + + if (old_area.active) + popup_redraw_exposed_area(&old_area); + else + redraw_all_later(UPD_NOT_VALID); + status_redraw_all(); - popup_mask_refresh = TRUE; + if (!old_area.active) + popup_mask_refresh = TRUE; } /* @@ -3063,12 +3687,25 @@ f_popup_hide(typval_T *argvars, typval_T *rettv UNUSED) void popup_show(win_T *wp) { + bool popup_active; + if ((wp->w_popup_flags & POPF_HIDDEN) == 0) return; + popup_active = (wp->w_popup_flags & POPF_OPACITY) && wp->w_popup_blend > 0; wp->w_popup_flags &= ~POPF_HIDDEN; - redraw_all_later(UPD_NOT_VALID); - popup_mask_refresh = TRUE; + if (popup_active) + { + wp->w_redr_type = UPD_NOT_VALID; + wp->w_lines_valid = 0; + if (must_redraw < UPD_VALID) + must_redraw = UPD_VALID; + } + else + { + redraw_all_later(UPD_NOT_VALID); + popup_mask_refresh = TRUE; + } } /* @@ -3109,14 +3746,7 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED) { int id; win_T *wp; -#ifdef FEAT_PROP_POPUP - int old_popup_active; -#endif - int old_winrow; - int old_wincol; - int old_popup_height; - int old_popup_width; - int old_popup_leftoff; + popup_area_T old_area; if (in_vim9script() && (check_for_number_arg(argvars, 0) == FAIL @@ -3128,15 +3758,7 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED) if (wp == NULL) return; -#ifdef FEAT_PROP_POPUP - old_popup_active = (wp->w_popup_flags & POPF_OPACITY) - && wp->w_popup_blend > 0; -#endif - old_winrow = wp->w_winrow; - old_wincol = wp->w_wincol; - old_popup_height = popup_height(wp); - old_popup_width = popup_width(wp); - old_popup_leftoff = wp->w_popup_leftoff; + popup_save_area(wp, &old_area); if (check_for_string_or_list_arg(argvars, 1) == FAIL) return; @@ -3153,16 +3775,8 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED) must_redraw = UPD_VALID; popup_adjust_position(wp); -#ifdef FEAT_PROP_POPUP - if (old_popup_active - && (old_winrow != wp->w_winrow - || old_wincol != wp->w_wincol - || old_popup_height != popup_height(wp) - || old_popup_width != popup_width(wp) - || old_popup_leftoff != wp->w_popup_leftoff)) - redraw_under_popup_area(old_winrow, old_wincol, - old_popup_height, old_popup_width, old_popup_leftoff); -#endif + if (popup_area_changed(wp, &old_area)) + popup_redraw_exposed_area(&old_area); } /* @@ -3171,9 +3785,10 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED) void f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED) { - int id; - win_T *wp; - buf_T *buf; + int id; + win_T *wp; + buf_T *buf; + popup_area_T old_area; rettv->v_type = VAR_BOOL; rettv->vval.v_number = VVAL_FALSE; @@ -3201,6 +3816,8 @@ f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED) if (wp->w_buffer != buf) { + popup_save_area(wp, &old_area); + wp->w_buffer->b_nwindows--; win_init_popup_win(wp, buf); set_local_options_default(wp, FALSE); @@ -3209,6 +3826,9 @@ f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED) swap_exists_action = SEA_NONE; redraw_win_later(wp, UPD_NOT_VALID); popup_adjust_position(wp); + + if (popup_area_changed(wp, &old_area)) + popup_redraw_exposed_area(&old_area); } rettv->vval.v_number = VVAL_TRUE; } @@ -3216,10 +3836,21 @@ f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED) static void popup_free(win_T *wp) { + popup_area_T old_area; + int was_visible = (wp->w_popup_flags & POPF_HIDDEN) == 0; + + popup_save_area(wp, &old_area); + sign_undefine_by_name(popup_get_sign_name(wp), FALSE); wp->w_buffer->b_locked = FALSE; if (wp->w_winrow + popup_height(wp) >= cmdline_row) clear_cmdline = TRUE; + + if (was_visible) + popup_clear_mask_for(wp); + + popup_redraw_exposed_area(&old_area); + win_free_popup(wp); #ifdef HAS_MESSAGE_WINDOW @@ -3227,9 +3858,11 @@ popup_free(win_T *wp) message_win = NULL; #endif - redraw_all_later(UPD_NOT_VALID); + if (!old_area.active) + redraw_all_later(UPD_NOT_VALID); status_redraw_all(); - popup_mask_refresh = TRUE; + if (!old_area.active) + popup_mask_refresh = TRUE; } static void @@ -3347,6 +3980,397 @@ close_all_popups(int force) return; } +/* + * Save the current popup area that may need to be restored later. + */ + static void +popup_save_area(win_T *wp, popup_area_T *area) +{ + area->active = (wp->w_popup_flags & POPF_OPACITY) && wp->w_popup_blend > 0; + area->winrow = wp->w_winrow; + area->wincol = wp->w_wincol; + area->height = popup_height(wp); + area->width = popup_width(wp); + area->leftoff = wp->w_popup_leftoff; + area->zindex = wp->w_zindex; +} + +/* + * Save popup style-related fields that affect redraw/reposition decisions. + */ + static void +popup_save_style(win_T *wp, popup_style_snapshot_T *style) +{ + int i; + + style->firstline = wp->w_firstline; + style->blend = wp->w_popup_blend; + style->flags = wp->w_popup_flags; + style->zindex = wp->w_zindex; + style->scrollbar_highlight = wp->w_scrollbar_highlight; + style->thumb_highlight = wp->w_thumb_highlight; + for (i = 0; i < 4; i++) + style->border_highlight[i] = wp->w_border_highlight[i]; +} + +/* + * Return true if style changes require at least a popup redraw. + */ + static bool +popup_style_changed(win_T *wp, popup_style_snapshot_T *style) +{ + int i; + + if (style->firstline != wp->w_firstline + || style->flags != wp->w_popup_flags + || style->scrollbar_highlight != wp->w_scrollbar_highlight + || style->thumb_highlight != wp->w_thumb_highlight) + return true; + for (i = 0; i < 4; i++) + if (style->border_highlight[i] != wp->w_border_highlight[i]) + return true; + return false; +} + +/* + * Save popup layout fields that affect mask refresh and local redraw. + */ + static void +popup_save_layout(win_T *wp, popup_layout_T *layout) +{ + layout->winrow = wp->w_winrow; + layout->wincol = wp->w_wincol; + layout->width = wp->w_width; + layout->height = wp->w_height; + layout->leftcol = wp->w_leftcol; + layout->leftoff = wp->w_popup_leftoff; + layout->has_scrollbar = wp->w_has_scrollbar; + layout->topoff = wp->w_popup_topoff; + layout->bottomoff = wp->w_popup_bottomoff; + layout->leftclip = wp->w_popup_leftclip; + layout->rightclip = wp->w_popup_rightclip; +} + +/* + * Return true when the popup layout changed. + */ + static bool +popup_layout_changed(win_T *wp, popup_layout_T *layout) +{ + return layout->winrow != wp->w_winrow + || layout->wincol != wp->w_wincol + || layout->leftcol != wp->w_leftcol + || layout->leftoff != wp->w_popup_leftoff + || layout->width != wp->w_width + || layout->height != wp->w_height + || layout->has_scrollbar != wp->w_has_scrollbar + || layout->topoff != wp->w_popup_topoff + || layout->bottomoff != wp->w_popup_bottomoff + || layout->leftclip != wp->w_popup_leftclip + || layout->rightclip != wp->w_popup_rightclip; +} + +/* + * Return true when the popup no longer covers the saved area. + */ + static bool +popup_area_changed(win_T *wp, popup_area_T *area) +{ + return area->winrow != wp->w_winrow + || area->wincol != wp->w_wincol + || area->height != popup_height(wp) + || area->width != popup_width(wp) + || area->leftoff != wp->w_popup_leftoff; +} + +/* + * If "wp" is a visible opacity popup at or below "zindex" whose drawn area + * overlaps the rectangle, mark it for full redraw so its blended background + * is recomputed. + */ + static void +mark_overlapped_opacity_popup(win_T *wp, int area_top, int area_bot, + int area_left, int area_right, int zindex) +{ + if ((wp->w_popup_flags & POPF_HIDDEN) + || (wp->w_popup_flags & POPF_OPACITY) == 0 + || wp->w_popup_blend == 0 + || wp->w_zindex > zindex + || wp->w_winrow >= area_bot + || wp->w_winrow + popup_height(wp) <= area_top + || wp->w_wincol >= area_right + || wp->w_wincol + popup_width(wp) - wp->w_popup_leftoff + <= area_left) + return; + + wp->w_redr_type = UPD_NOT_VALID; + wp->w_lines_valid = 0; +} + +/* + * Mark lower or equal zindex opacity popups that overlap with a popup area + * for redraw. Their blended background may have included the old popup. + */ + static void +redraw_overlapped_opacity_popups(int winrow, int wincol, int height, int width, + int leftoff, int zindex) +{ + win_T *wp; + int area_top = winrow; + int area_bot = winrow + height; + int area_left = wincol; + int area_right = wincol + width - leftoff; + + FOR_ALL_POPUPWINS(wp) + mark_overlapped_opacity_popup(wp, area_top, area_bot, area_left, + area_right, zindex); + FOR_ALL_POPUPWINS_IN_TAB(curtab, wp) + mark_overlapped_opacity_popup(wp, area_top, area_bot, area_left, + area_right, zindex); + + if (must_redraw < UPD_VALID) + must_redraw = UPD_VALID; +} + +/* + * Replace pum_bg_* cells [left, right) of screen row "r" with the underlying + * buffer text, so the pum's opacity padding shows the buffer through. Cells + * outside any window (or past the end of the buffer line) become spaces. + * + * Used after an opacity popup that overlapped pum_bg_* is dismissed: the + * stale popup content held in pum_bg_* would otherwise leak through the + * pum's opacity blend as a ghost. This walks the buffer line and writes + * the displayed character at each visual column directly into pum_bg_*. + * + * Limitations: handles plain text and tabs; folds, conceal, virtual text and + * other rendering features fall back to a space, which still beats showing a + * stale popup char. + */ + static void +refill_pum_bg_row_from_buffer(int r, int left, int right) +{ + int line_cp = r; + int col_cp = left; + win_T *wp; + linenr_T lnum; + int row_for_lnum; + int col_for_lnum = 0; + char_u *line; + char_u *p; + int win_text_col; + int screen_col; + int soff_base = (r - pum_bg_top) * pum_bg_cols; + int c; + + // Default: fill the range with spaces so trailing/empty cells render as + // plain pum bg through opacity. + for (c = left; c < right; ++c) + { + pum_bg_lines[soff_base + c] = ' '; + if (pum_bg_attrs != NULL) + pum_bg_attrs[soff_base + c] = 0; + if (enc_utf8 && pum_bg_linesUC != NULL) + pum_bg_linesUC[soff_base + c] = 0; + if (enc_utf8) + { + int k; + for (k = 0; k < MAX_MCO; ++k) + if (pum_bg_linesC[k] != NULL) + pum_bg_linesC[k][soff_base + c] = 0; + } + } + + wp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP); + if (wp == NULL || line_cp < 0 || line_cp >= wp->w_height) + return; + if (wp->w_buffer == NULL || wp->w_buffer->b_ml.ml_mfp == NULL) + return; + + // Compute the buffer line for this screen row. + row_for_lnum = line_cp; + if (mouse_comp_pos(wp, &row_for_lnum, &col_for_lnum, &lnum, NULL)) + return; // past end of buffer + if (lnum < 1 || lnum > wp->w_buffer->b_ml.ml_line_count) + return; + + line = ml_get_buf(wp->w_buffer, lnum, FALSE); + if (line == NULL) + return; + + // Walk the buffer line and write each displayed cell into pum_bg_*. + // win_text_col is the screen column where the buffer text starts inside + // the window (after sign/number/fold columns and horizontal scroll). + win_text_col = wp->w_wincol + win_col_off(wp); + if (!wp->w_p_wrap) + win_text_col -= wp->w_leftcol; + screen_col = win_text_col; + p = line; + while (*p != NUL && screen_col < right) + { + int char_cells; + int byte_count; + int soff = soff_base + screen_col; + int in_range = (screen_col >= left && screen_col < right); + + if (*p == '\t') + { + int ts = (int)wp->w_buffer->b_p_ts; + char_cells = ts > 0 ? ts - ((screen_col - win_text_col) % ts) : 1; + byte_count = 1; + if (in_range) + { + pum_bg_lines[soff] = ' '; + if (enc_utf8 && pum_bg_linesUC != NULL) + pum_bg_linesUC[soff] = 0; + } + } + else if (has_mbyte) + { + char_cells = mb_ptr2cells(p); + byte_count = mb_ptr2len(p); + if (in_range) + { + pum_bg_lines[soff] = *p; + if (enc_utf8 && pum_bg_linesUC != NULL) + pum_bg_linesUC[soff] = (*p < 0x80) ? 0 : mb_ptr2char(p); + } + } + else + { + char_cells = 1; + byte_count = 1; + if (in_range) + { + pum_bg_lines[soff] = (*p < 0x20) ? ' ' : *p; + if (enc_utf8 && pum_bg_linesUC != NULL) + pum_bg_linesUC[soff] = 0; + } + } + if (in_range && pum_bg_attrs != NULL) + pum_bg_attrs[soff] = 0; + + // For wide chars / tabs the trailing cells are zeroed already (by the + // initial space fill we did above). Just skip past them. + p += byte_count; + screen_col += char_cells; + } +} + +/* + * Redraw what becomes exposed when an opacity popup moves, resizes or closes. + */ + static void +popup_redraw_exposed_area(popup_area_T *area) +{ + if (!area->active) + return; + + redraw_under_popup_area(area->winrow, area->wincol, area->height, + area->width, area->leftoff); + redraw_overlapped_opacity_popups(area->winrow, area->wincol, + area->height, area->width, area->leftoff, area->zindex); + + // If the closing/moving popup overlapped the pum's saved background, + // pum_bg_* still holds the dismissed popup's content. When the pum + // next blends opacity it would restore those stale chars at padding + // cells, leaving a ghost. + // + // We can't re-snapshot via update_screen from here: the surrounding + // update_screen has updating_screen set, so a nested call would no-op. + // Instead, replace the overlapping pum_bg_* cells with the actual + // underlying buffer text so the pum's opacity padding shows the buffer + // through, just as it would if the popup had never been there. + if (pum_bg_lines != NULL + && area->winrow < pum_bg_bot + && area->winrow + area->height > pum_bg_top) + { + int top = MAX(area->winrow, pum_bg_top); + int bot = MIN(area->winrow + area->height, pum_bg_bot); + int left = MAX(area->wincol, 0); + int right = MIN(area->wincol + area->width, pum_bg_cols); + int r; + + for (r = top; r < bot; ++r) + refill_pum_bg_row_from_buffer(r, left, right); + } +} + +/* + * Release saved screen data used for opacity padding redraw. + */ + static void +popup_free_saved_screen(popup_saved_screen_T *saved_screen) +{ + vim_free(saved_screen->lines); + vim_free(saved_screen->attrs); + vim_free(saved_screen->linesuc); + CLEAR_POINTER(saved_screen); +} + +/* + * Save the screen area that opacity padding may need to blend against. + * On entry "saved_screen" must be zero-initialised. When the snapshot is + * unavailable (no opacity popup, no padding, allocation failure) "lines" is + * left NULL and callers should fall back to plain screen_fill(). The caller + * must always release the snapshot with popup_free_saved_screen(). + */ + static void +popup_save_padding_screen(win_T *wp, popup_saved_screen_T *saved_screen) +{ + if (screen_opacity_popup == NULL + || (wp->w_popup_padding[0] == 0 && wp->w_popup_padding[1] == 0 + && wp->w_popup_padding[2] == 0 && wp->w_popup_padding[3] == 0)) + return; + + saved_screen->start_row = wp->w_winrow + wp->w_popup_border[0]; + saved_screen->start_col = wp->w_wincol + wp->w_popup_border[3]; + saved_screen->rows = wp->w_popup_padding[0] + wp->w_height + + wp->w_popup_padding[2]; + saved_screen->cols = wp->w_popup_padding[3] + wp->w_width + + wp->w_popup_padding[1]; + + // Include one column to the left to handle wide chars that overlap the + // padding boundary. + if (saved_screen->start_col > 0) + { + --saved_screen->start_col; + ++saved_screen->cols; + } + + saved_screen->lines = ALLOC_MULT(schar_T, + saved_screen->rows * saved_screen->cols); + saved_screen->attrs = ALLOC_MULT(int, + saved_screen->rows * saved_screen->cols); + if (enc_utf8) + saved_screen->linesuc = ALLOC_MULT(u8char_T, + saved_screen->rows * saved_screen->cols); + + if (saved_screen->lines == NULL || saved_screen->attrs == NULL) + return; + + for (int r = 0; r < saved_screen->rows; r++) + { + int screen_row = saved_screen->start_row + r; + + if (screen_row >= 0 && screen_row < screen_Rows) + for (int c = 0; c < saved_screen->cols; c++) + { + int screen_col = saved_screen->start_col + c; + + if (screen_col >= 0 && screen_col < screen_Columns) + { + int off = LineOffset[screen_row] + screen_col; + int save_off = r * saved_screen->cols + c; + + saved_screen->lines[save_off] = ScreenLines[off]; + saved_screen->attrs[save_off] = ScreenAttrs[off]; + if (enc_utf8 && saved_screen->linesuc != NULL) + saved_screen->linesuc[save_off] = ScreenLinesUC[off]; + } + } + } +} + /* * Force windows under a popup area to redraw. */ @@ -3384,7 +4408,7 @@ redraw_under_popup_area(int winrow, int wincol, int height, int width, int lefto redrawWinline(twp, lnum); } else if (line_cp == twp->w_height) - twp->w_redr_status = TRUE; + twp->w_redr_status = true; } } } @@ -3399,13 +4423,7 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED) dict_T *dict; int id; win_T *wp; - int old_winrow; - int old_wincol; - int old_height; - int old_width; - int old_popup_height; - int old_popup_width; - int old_popup_leftoff; + popup_area_T old_area; if (in_vim9script() && (check_for_number_arg(argvars, 0) == FAIL @@ -3421,14 +4439,7 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED) return; dict = argvars[1].vval.v_dict; - // Save old position for redrawing - old_winrow = wp->w_winrow; - old_wincol = wp->w_wincol; - old_height = wp->w_height; - old_width = wp->w_width; - old_popup_height = popup_height(wp); - old_popup_width = popup_width(wp); - old_popup_leftoff = wp->w_popup_leftoff; + popup_save_area(wp, &old_area); apply_move_options(wp, dict); @@ -3441,14 +4452,11 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED) // redrawing the affected lines in regular windows to clear the old // position. Transparent popups don't participate in popup_mask, so // we need to manually mark the old area's lines for redraw. - if (old_winrow != wp->w_winrow || old_wincol != wp->w_wincol - || old_height != wp->w_height || old_width != wp->w_width) + if (popup_area_changed(wp, &old_area)) { redraw_win_later(wp, UPD_NOT_VALID); - if ((wp->w_popup_flags & POPF_OPACITY) && wp->w_popup_blend > 0) - redraw_under_popup_area(old_winrow, old_wincol, - old_popup_height, old_popup_width, old_popup_leftoff); + popup_redraw_exposed_area(&old_area); } } @@ -3461,24 +4469,10 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED) dict_T *dict; int id; win_T *wp; - linenr_T old_firstline; -#ifdef FEAT_PROP_POPUP - int old_blend; - int old_popup_active; -#endif - int old_winrow; - int old_wincol; - int old_popup_height; - int old_popup_width; - int old_popup_leftoff; - int old_zindex; - int old_popup_flags; - char_u *old_scrollbar_highlight; - char_u *old_thumb_highlight; - char_u *old_border_highlight[4]; + popup_area_T old_area; + popup_style_snapshot_T old_style; int need_redraw = FALSE; int need_reposition = FALSE; - int i; if (in_vim9script() && (check_for_number_arg(argvars, 0) == FAIL @@ -3493,23 +4487,8 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED) if (check_for_nonnull_dict_arg(argvars, 1) == FAIL) return; dict = argvars[1].vval.v_dict; - old_firstline = wp->w_firstline; -#ifdef FEAT_PROP_POPUP - old_blend = wp->w_popup_blend; - old_popup_active = (wp->w_popup_flags & POPF_OPACITY) - && wp->w_popup_blend > 0; -#endif - old_winrow = wp->w_winrow; - old_wincol = wp->w_wincol; - old_popup_height = popup_height(wp); - old_popup_width = popup_width(wp); - old_popup_leftoff = wp->w_popup_leftoff; - old_zindex = wp->w_zindex; - old_popup_flags = wp->w_popup_flags; - old_scrollbar_highlight = wp->w_scrollbar_highlight; - old_thumb_highlight = wp->w_thumb_highlight; - for (i = 0; i < 4; i++) - old_border_highlight[i] = wp->w_border_highlight[i]; + popup_save_area(wp, &old_area); + popup_save_style(wp, &old_style); (void)apply_options(wp, dict, FALSE); @@ -3520,28 +4499,16 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED) wp->w_topline = wp->w_firstline; // Check if visual options changed and redraw if needed - if (old_firstline != wp->w_firstline) - need_redraw = TRUE; - if (old_zindex != wp->w_zindex) + if (old_style.zindex != wp->w_zindex) { need_redraw = TRUE; need_reposition = TRUE; } - if (old_popup_flags != wp->w_popup_flags) - { + else if (popup_style_changed(wp, &old_style)) need_redraw = TRUE; + + if (old_style.flags != wp->w_popup_flags) need_reposition = TRUE; - } - if (old_scrollbar_highlight != wp->w_scrollbar_highlight) - need_redraw = TRUE; - if (old_thumb_highlight != wp->w_thumb_highlight) - need_redraw = TRUE; - for (i = 0; i < 4; i++) - if (old_border_highlight[i] != wp->w_border_highlight[i]) - { - need_redraw = TRUE; - break; - } if (need_reposition) { @@ -3560,16 +4527,14 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED) must_redraw = UPD_VALID; } -#ifdef FEAT_PROP_POPUP // Force redraw if opacity value changed - if (old_blend != wp->w_popup_blend) + if (old_style.blend != wp->w_popup_blend) { redraw_win_later(wp, UPD_NOT_VALID); // Also redraw windows below the popup redraw_all_later(UPD_NOT_VALID); popup_mask_refresh = TRUE; } -#endif // Always recalculate popup position/size: other options like border, // close, padding may have changed without affecting w_popup_flags. @@ -3577,16 +4542,8 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED) // position or size actually changed. popup_adjust_position(wp); -#ifdef FEAT_PROP_POPUP - if (old_popup_active - && (old_winrow != wp->w_winrow - || old_wincol != wp->w_wincol - || old_popup_height != popup_height(wp) - || old_popup_width != popup_width(wp) - || old_popup_leftoff != wp->w_popup_leftoff)) - redraw_under_popup_area(old_winrow, old_wincol, - old_popup_height, old_popup_width, old_popup_leftoff); -#endif + if (popup_area_changed(wp, &old_area)) + popup_redraw_exposed_area(&old_area); } /* @@ -3840,6 +4797,8 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv) dict_add_number(dict, "resize", (wp->w_popup_flags & POPF_RESIZE) != 0); dict_add_number(dict, "posinvert", (wp->w_popup_flags & POPF_POSINVERT) != 0); + dict_add_number(dict, "clipwindow", + (wp->w_popup_flags & POPF_CLIPWINDOW) != 0); // Return opacity (0-100) by converting from internal blend value dict_add_number(dict, "opacity", (wp->w_popup_flags & POPF_OPACITY) ? 100 - wp->w_popup_blend : 100); @@ -3886,14 +4845,18 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv) for (i = 0; i < (int)ARRAY_LENGTH(poppos_entries); ++i) if (wp->w_popup_pos == poppos_entries[i].pp_val) { - dict_add_string(dict, "pos", - (char_u *)poppos_entries[i].pp_name); + dict_add_string_len(dict, "pos", + poppos_entries[i].pp_name.string, + (int)poppos_entries[i].pp_name.length); break; } - dict_add_string(dict, "close", (char_u *)( - wp->w_popup_close == POPCLOSE_BUTTON ? "button" - : wp->w_popup_close == POPCLOSE_CLICK ? "click" : "none")); + if (wp->w_popup_close == POPCLOSE_BUTTON) + dict_add_string_len(dict, "close", (char_u *)"button", STRLEN_LITERAL("button")); + else if (wp->w_popup_close == POPCLOSE_CLICK) + dict_add_string_len(dict, "close", (char_u *)"click", STRLEN_LITERAL("click")); + else + dict_add_string_len(dict, "close", (char_u *)"none", STRLEN_LITERAL("none")); #if defined(FEAT_TIMERS) dict_add_number(dict, "time", wp->w_popup_timer != NULL @@ -4303,11 +5266,23 @@ check_popup_unhidden(win_T *wp) { textprop_T prop; linenr_T lnum; + bool found = false; - if ((wp->w_popup_flags & POPF_HIDDEN_FORCE) == 0 - && find_visible_prop(wp->w_popup_prop_win, - wp->w_popup_prop_type, wp->w_popup_prop_id, - &prop, &lnum)) + if ((wp->w_popup_flags & POPF_HIDDEN_FORCE) != 0) + return FALSE; + if (find_visible_prop(wp->w_popup_prop_win, + wp->w_popup_prop_type, wp->w_popup_prop_id, + &prop, &lnum)) + found = true; + // The textprop may have scrolled just above the host window's top. + // Unhide the popup so popup_adjust_position() can roll it partially + // onto the host's top edge via the top-clip path. Limit the search + // to the popup's own height so we do not resurrect a popup whose + // prop is already further off-screen than the popup can extend. + else if (popup_find_prop_above_top(wp, wp->w_popup_prop_win, + popup_height(wp), &prop, &lnum)) + found = true; + if (found) { wp->w_popup_flags &= ~POPF_HIDDEN; wp->w_popup_prop_topline = 0; // force repositioning @@ -4331,7 +5306,11 @@ popup_need_position_adjust(win_T *wp) if (win_valid(wp->w_popup_prop_win) && (wp->w_popup_prop_changedtick != CHANGEDTICK(wp->w_popup_prop_win->w_buffer) - || wp->w_popup_prop_topline != wp->w_popup_prop_win->w_topline)) + || wp->w_popup_prop_topline != wp->w_popup_prop_win->w_topline + || wp->w_popup_prop_winrow != wp->w_popup_prop_win->w_winrow + || wp->w_popup_prop_wincol != wp->w_popup_prop_win->w_wincol + || wp->w_popup_prop_width != wp->w_popup_prop_win->w_width + || wp->w_popup_prop_winheight != wp->w_popup_prop_win->w_height)) return TRUE; // May need to adjust the width if the cursor moved. @@ -4413,12 +5392,14 @@ redraw_win_under_opacity_popup(win_T *wp) linenr_T lnum; (void)mouse_comp_pos(twp, &line_cp, &col_cp, &lnum, NULL); - redrawWinline(twp, lnum); + // Called from inside update_screen(); raising must_redraw + // would loop the outer redraw indefinitely. + redraw_win_range_now(twp, lnum, lnum); } else if (line_cp == twp->w_height) // Status bar line: mark for redraw to prevent // opacity blend accumulation. - twp->w_redr_status = TRUE; + twp->w_redr_status = true; } } } @@ -4438,6 +5419,37 @@ popup_is_under_opacity(int row, int col) return opacity_zindex[row * opacity_zindex_cols + col] > screen_zindex; } +/* + * Return TRUE if cell (row, col) is covered by a lower-zindex opacity popup. + */ + int +popup_is_over_opacity(int row, int col) +{ + win_T *wp; + + FOR_ALL_POPUPWINS(wp) + if ((wp->w_popup_flags & POPF_OPACITY) + && wp->w_popup_blend > 0 + && !(wp->w_popup_flags & POPF_HIDDEN) + && wp->w_zindex < screen_zindex + && row >= wp->w_winrow + && row < wp->w_winrow + popup_height(wp) + && col >= wp->w_wincol + && col < wp->w_wincol + popup_width(wp)) + return TRUE; + FOR_ALL_POPUPWINS_IN_TAB(curtab, wp) + if ((wp->w_popup_flags & POPF_OPACITY) + && wp->w_popup_blend > 0 + && !(wp->w_popup_flags & POPF_HIDDEN) + && wp->w_zindex < screen_zindex + && row >= wp->w_winrow + && row < wp->w_winrow + popup_height(wp) + && col >= wp->w_wincol + && col < wp->w_wincol + popup_width(wp)) + return TRUE; + return FALSE; +} + /* * Return TRUE if any cell in row "row" from "start_col" to "end_col" * (exclusive) is covered by a higher-zindex opacity popup. @@ -4593,7 +5605,18 @@ may_update_popup_mask(int type) } width = popup_width(wp); - height = popup_height(wp); + // Match the drawn extent computed by update_popups so that cells + // outside the clipped popup are not marked as popup-owned and the + // background window can draw through them. + if (wp->w_popup_topoff > 0 || wp->w_popup_bottomoff > 0) + { + popup_clip_T cl; + + popup_compute_clip(wp, &cl); + height = cl.eff_height; + } + else + height = popup_height(wp); popup_update_mask(wp, width, height); // Popup with partial transparency do not block lower layers from @@ -4602,18 +5625,25 @@ may_update_popup_mask(int type) if ((wp->w_popup_flags & POPF_OPACITY) && wp->w_popup_blend > 0) continue; - for (line = wp->w_winrow; - line < wp->w_winrow + height && line < screen_Rows; ++line) - for (col = wp->w_wincol; - col < wp->w_wincol + width - wp->w_popup_leftoff - && col < screen_Columns; ++col) - if (wp->w_zindex < POPUPMENU_ZINDEX - && pum_visible() - && pum_under_menu(line, col, FALSE)) - mask[line * screen_Columns + col] = POPUPMENU_ZINDEX; - else if (wp->w_popup_mask_cells == NULL - || !popup_masked(wp, width, height, col, line)) - mask[line * screen_Columns + col] = wp->w_zindex; + { + int mask_start = wp->w_winrow + wp->w_popup_topoff; + int mask_end = mask_start + height; + int mask_col_start = wp->w_wincol + wp->w_popup_leftclip; + int mask_col_end = wp->w_wincol + width - wp->w_popup_leftoff + - wp->w_popup_rightclip; + + for (line = mask_start; + line < mask_end && line < screen_Rows; ++line) + for (col = mask_col_start; + col < mask_col_end && col < screen_Columns; ++col) + if (wp->w_zindex < POPUPMENU_ZINDEX + && pum_visible() + && pum_under_menu(line, col, FALSE)) + mask[line * screen_Columns + col] = POPUPMENU_ZINDEX; + else if (wp->w_popup_mask_cells == NULL + || !popup_masked(wp, width, height, col, line)) + mask[line * screen_Columns + col] = wp->w_zindex; + } } // Only check which lines are to be updated if not already @@ -4671,7 +5701,7 @@ may_update_popup_mask(int type) if (line_cp >= wp->w_height) // In (or below) status line - wp->w_redr_status = TRUE; + wp->w_redr_status = true; else { // compute the position in the buffer line @@ -4773,26 +5803,20 @@ static void draw_opacity_padding_cell( int row, int col, - schar_T *saved_screenlines, - int *saved_screenattrs, - u8char_T *saved_screenlinesuc, - int save_start_row, - int save_start_col, - int save_rows, - int save_cols, + popup_saved_screen_T *saved_screen, int pad_start_col, int pad_end_col) { int off = LineOffset[row] + col; - int r = row - save_start_row; - int c = col - save_start_col; + int r = row - saved_screen->start_row; + int c = col - saved_screen->start_col; - if (r >= 0 && r < save_rows && c >= 0 && c < save_cols) + if (r >= 0 && r < saved_screen->rows && c >= 0 && c < saved_screen->cols) { - int save_off = r * save_cols + c; + int save_off = r * saved_screen->cols + c; // If this is the second cell of a wide background character, blend // the wide character instead of overwriting it. - if (enc_utf8 && saved_screenlinesuc != NULL) + if (enc_utf8 && saved_screen->linesuc != NULL) { int base_col = col - 1; int base_off = off - 1; @@ -4811,9 +5835,9 @@ draw_opacity_padding_cell( } if (!wide_prev && save_off > 0) { - if (saved_screenlinesuc[save_off - 1] != 0 - && utf_char2cells(saved_screenlinesuc[save_off - 1]) == 2 - && saved_screenlines[save_off] == 0) + if (saved_screen->linesuc[save_off - 1] != 0 + && utf_char2cells(saved_screen->linesuc[save_off - 1]) == 2 + && saved_screen->lines[save_off] == 0) wide_prev = TRUE; } @@ -4832,7 +5856,7 @@ draw_opacity_padding_cell( // covered by the popup background. ScreenLines[base_off] = ' '; ScreenLinesUC[base_off] = 0; - ScreenAttrs[base_off] = saved_screenattrs[base_save_off]; + ScreenAttrs[base_off] = saved_screen->attrs[base_save_off]; popup_set_base_screen_cell(row, base_col, ScreenLines[base_off], ScreenAttrs[base_off], @@ -4840,8 +5864,10 @@ draw_opacity_padding_cell( screen_char(base_off, row, base_col); // Draw padding in the right half. + // Use left half's attr since the right half of a + // wide char may have an unreliable attr value. ScreenLines[off] = ' '; - ScreenAttrs[off] = saved_screenattrs[save_off]; + ScreenAttrs[off] = saved_screen->attrs[base_save_off]; if (enc_utf8) ScreenLinesUC[off] = 0; int popup_attr_val = @@ -4855,10 +5881,53 @@ draw_opacity_padding_cell( screen_char(off, row, col); return; } + // The content drawing cleared the left half to a + // space (wide char didn't fit at content edge), + // but the saved data has a wide char. Restore it + // spanning both the content cell and padding cell. + if (base_save_off >= 0 + && saved_screen->linesuc[base_save_off] != 0 + && utf_char2cells( + saved_screen->linesuc[base_save_off]) == 2 + && ScreenLines[base_off] == ' ' + && ScreenLinesUC[base_off] == 0) + { + int popup_attr_val = + get_win_attr(screen_opacity_popup); + int blend = + screen_opacity_popup->w_popup_blend; + + ScreenLines[base_off] = + saved_screen->lines[base_save_off]; + ScreenLinesUC[base_off] = + saved_screen->linesuc[base_save_off]; + ScreenAttrs[base_off] = + saved_screen->attrs[base_save_off]; + ScreenAttrs[base_off] = hl_blend_attr( + ScreenAttrs[base_off], + popup_attr_val, blend, TRUE); + + ScreenLines[off] = 0; + ScreenLinesUC[off] = 0; + ScreenAttrs[off] = ScreenAttrs[base_off]; + + popup_set_base_screen_cell(row, base_col, + ScreenLines[base_off], + ScreenAttrs[base_off], + ScreenLinesUC[base_off]); + popup_set_base_screen_cell(row, col, + ScreenLines[off], + ScreenAttrs[off], + ScreenLinesUC[off]); + screen_char(base_off, row, base_col); + return; + } // Draw padding in the right half. + // Use left half's attr since the right half of a + // wide char may have an unreliable attr value. ScreenLines[off] = ' '; - ScreenAttrs[off] = saved_screenattrs[save_off]; + ScreenAttrs[off] = saved_screen->attrs[base_save_off]; if (enc_utf8 && ScreenLinesUC != NULL) ScreenLinesUC[off] = 0; int popup_attr_val = get_win_attr(screen_opacity_popup); @@ -4874,12 +5943,12 @@ draw_opacity_padding_cell( // Base cell is inside the saved area, redraw the wide char. if (save_off > 0) { - ScreenLines[base_off] = saved_screenlines[base_save_off]; - ScreenAttrs[base_off] = saved_screenattrs[base_save_off]; - ScreenLines[off] = saved_screenlines[save_off]; - ScreenAttrs[off] = saved_screenattrs[save_off]; - ScreenLinesUC[base_off] = saved_screenlinesuc[base_save_off]; - ScreenLinesUC[off] = saved_screenlinesuc[save_off]; + ScreenLines[base_off] = saved_screen->lines[base_save_off]; + ScreenAttrs[base_off] = saved_screen->attrs[base_save_off]; + ScreenLines[off] = saved_screen->lines[save_off]; + ScreenAttrs[off] = saved_screen->attrs[save_off]; + ScreenLinesUC[base_off] = saved_screen->linesuc[base_save_off]; + ScreenLinesUC[off] = saved_screen->linesuc[save_off]; int popup_attr_val = get_win_attr(screen_opacity_popup); int blend = screen_opacity_popup->w_popup_blend; @@ -4895,10 +5964,10 @@ draw_opacity_padding_cell( return; } } - ScreenLines[off] = saved_screenlines[save_off]; - ScreenAttrs[off] = saved_screenattrs[save_off]; - if (enc_utf8 && saved_screenlinesuc != NULL) - ScreenLinesUC[off] = saved_screenlinesuc[save_off]; + ScreenLines[off] = saved_screen->lines[save_off]; + ScreenAttrs[off] = saved_screen->attrs[save_off]; + if (enc_utf8 && saved_screen->linesuc != NULL) + ScreenLinesUC[off] = saved_screen->linesuc[save_off]; // If the saved character is wide and would extend past the padding // area into the content area, replace with a space to avoid @@ -4930,19 +5999,11 @@ fill_opacity_padding( int end_row, int start_col, int end_col, - schar_T *saved_screenlines, - int *saved_screenattrs, - u8char_T *saved_screenlinesuc, - int save_start_row, - int save_start_col, - int save_rows, - int save_cols) + popup_saved_screen_T *saved_screen) { for (int pad_row = start_row; pad_row < end_row; pad_row++) for (int pad_col = start_col; pad_col < end_col; pad_col++) - draw_opacity_padding_cell(pad_row, pad_col, - saved_screenlines, saved_screenattrs, saved_screenlinesuc, - save_start_row, save_start_col, save_rows, save_cols, + draw_opacity_padding_cell(pad_row, pad_col, saved_screen, start_col, end_col); } @@ -5004,6 +6065,14 @@ update_popups(void (*win_update)(win_T *wp)) { int title_len = 0; int title_wincol; + popup_clip_T cl; + + // Compute the clip geometry once per iteration; w_popup_*off/clip, + // w_height, w_width, w_popup_border and w_popup_padding are stable + // for the duration of this iteration (popup_apply_winupdate_clip() + // mutates w_height/w_width temporarily but the result is restored + // before any code below reads cl again). + popup_compute_clip(wp, &cl); override_success = push_highlight_overrides(wp->w_hl, wp->w_hl_len); @@ -5067,65 +6136,11 @@ update_popups(void (*win_update)(win_T *wp)) } #endif - // Save background ScreenLines for padding opacity. - // We need to save it before win_update() overwrites it. - schar_T *saved_screenlines = NULL; - int *saved_screenattrs = NULL; - u8char_T *saved_screenlinesuc = NULL; - int save_start_row = 0; - int save_start_col = 0; - int save_rows = 0; - int save_cols = 0; + // Save background ScreenLines for padding opacity before win_update() + // overwrites them. + popup_saved_screen_T saved_screen = { 0 }; - if (screen_opacity_popup != NULL - && (wp->w_popup_padding[0] > 0 || wp->w_popup_padding[1] > 0 - || wp->w_popup_padding[2] > 0 || wp->w_popup_padding[3] > 0)) - { - // Calculate the area to save (all padding regions including top/bottom) - save_start_row = wp->w_winrow + wp->w_popup_border[0]; - save_start_col = wp->w_wincol + wp->w_popup_border[3]; - save_rows = wp->w_popup_padding[0] + wp->w_height + wp->w_popup_padding[2]; - save_cols = wp->w_popup_padding[3] + wp->w_width + wp->w_popup_padding[1]; - - // Include one column to the left to handle wide chars that overlap - // the padding boundary. - if (save_start_col > 0) - { - --save_start_col; - ++save_cols; - } - - // Allocate buffers - saved_screenlines = ALLOC_MULT(schar_T, save_rows * save_cols); - saved_screenattrs = ALLOC_MULT(int, save_rows * save_cols); - if (enc_utf8) - saved_screenlinesuc = ALLOC_MULT(u8char_T, save_rows * save_cols); - - // Save the background - if (saved_screenlines != NULL && saved_screenattrs != NULL) - { - for (int r = 0; r < save_rows; r++) - { - int screen_row = save_start_row + r; - if (screen_row >= 0 && screen_row < screen_Rows) - { - for (int c = 0; c < save_cols; c++) - { - int screen_col = save_start_col + c; - if (screen_col >= 0 && screen_col < screen_Columns) - { - int off = LineOffset[screen_row] + screen_col; - int save_off = r * save_cols + c; - saved_screenlines[save_off] = ScreenLines[off]; - saved_screenattrs[save_off] = ScreenAttrs[off]; - if (enc_utf8 && saved_screenlinesuc != NULL) - saved_screenlinesuc[save_off] = ScreenLinesUC[off]; - } - } - } - } - } - } + popup_save_padding_screen(wp, &saved_screen); // Set flags in popup_transparent[] for masked cells. update_popup_transparent(wp, 1); @@ -5143,13 +6158,25 @@ update_popups(void (*win_update)(win_T *wp)) // Draw the popup text, unless it's off screen. if (wp->w_winrow < screen_Rows && wp->w_wincol < screen_Columns) { + popup_geom_save_T saved; + + popup_geom_save(wp, &saved); + // May need to update the "cursorline" highlighting, which may also // change "topline" if (wp->w_popup_last_curline != wp->w_cursor.lnum) popup_highlight_curline(wp); + // Clip the buffer's drawn extent to the host window when + // "clipwindow" is set. The transient mutations are reverted by + // popup_geom_restore() so callers continue to see the popup's + // logical geometry via popup_getoptions/popup_getpos. + popup_apply_winupdate_clip(wp, &cl); + win_update(wp); + popup_geom_restore(wp, &saved); + // move the cursor into the visible lines, otherwise executing // commands with win_execute() may cause the text to jump. if (wp->w_cursor.lnum < wp->w_topline) @@ -5161,6 +6188,12 @@ update_popups(void (*win_update)(win_T *wp)) wp->w_winrow -= top_off; wp->w_wincol -= left_extra; + // "clipwindow" with top-clip shifts all popup decorations down so the + // first visible row of the popup lands at the host window's top edge. + // Apply the shift before drawing borders/padding/etc. and restore at + // the end of this popup's iteration. + wp->w_winrow += wp->w_popup_topoff; + // Add offset for border and padding if not done already. if ((wp->w_flags & WFLAG_WCOL_OFF_ADDED) == 0) { @@ -5173,8 +6206,22 @@ update_popups(void (*win_update)(win_T *wp)) wp->w_flags |= WFLAG_WROW_OFF_ADDED; } - total_width = popup_width(wp) - wp->w_popup_rightoff; - total_height = popup_height(wp); + // When clipped by "clipwindow", drop the border/padding slot at the + // clipped edge that we will not render, so the popup ends exactly on + // the last visible content row (no empty trailing side-border row) + // and starts on the first visible row when top-clipped. When + // unclipped, fall back to the full popup geometry (cl.eff_width + // excludes w_leftcol and the scrollbar, which popup_width() folds in). + if (wp->w_popup_leftclip > 0 || wp->w_popup_rightclip > 0) + total_width = cl.eff_width; + else + total_width = popup_width(wp) - wp->w_popup_rightoff; + if (total_width < 0) + total_width = 0; + if (wp->w_popup_topoff > 0 || wp->w_popup_bottomoff > 0) + total_height = cl.eff_height; + else + total_height = popup_height(wp); popup_attr = get_win_attr(wp); if (wp->w_winrow + total_height > cmdline_row) @@ -5209,9 +6256,13 @@ update_popups(void (*win_update)(win_T *wp)) for (i = 0; i < 4; ++i) { - border_attr[i] = popup_attr; if (wp->w_border_highlight[i] != NULL) border_attr[i] = syn_name2attr(wp->w_border_highlight[i]); + else if (wp->w_hlfwin_id != 0 + || (wp->w_popup_flags & POPF_INFO)) + border_attr[i] = popup_attr; + else + border_attr[i] = HL_ATTR(HLF_POPB); // Apply blend to border attributes for popup with opacitys if ((wp->w_popup_flags & POPF_OPACITY) && wp->w_popup_blend > 0) @@ -5228,6 +6279,16 @@ update_popups(void (*win_update)(win_T *wp)) title_wincol = wp->w_wincol + 1; if (wp->w_popup_title != NULL) { + int title_attr; + + if (wp->w_popup_border[0] > 0 && wp->w_border_highlight[0] != NULL) + title_attr = border_attr[0]; + else if (wp->w_hlfwin_id != 0 + || (wp->w_popup_flags & POPF_INFO)) + title_attr = popup_attr; + else + title_attr = HL_ATTR(HLF_POPT); + title_len = vim_strsize(wp->w_popup_title); // truncate the title if too long @@ -5241,8 +6302,7 @@ update_popups(void (*win_update)(win_T *wp)) trunc_string(wp->w_popup_title, title_text, total_width - 2, title_byte_len + 1); screen_puts(title_text, wp->w_winrow, title_wincol, - wp->w_popup_border[0] > 0 - ? border_attr[0] : popup_attr); + title_attr); vim_free(title_text); } @@ -5250,19 +6310,19 @@ update_popups(void (*win_update)(win_T *wp)) } else screen_puts(wp->w_popup_title, wp->w_winrow, title_wincol, - wp->w_popup_border[0] > 0 ? border_attr[0] : popup_attr); + title_attr); } - wincol = wp->w_wincol - wp->w_popup_leftoff; - top_padding = wp->w_popup_padding[0]; - if (wp->w_popup_border[0] > 0) + wincol = wp->w_wincol - wp->w_popup_leftoff + wp->w_popup_leftclip; + top_padding = cl.eff_padding[0]; + if (cl.eff_border[0] > 0) { // top border; do not draw over the title if (title_len > 0) { screen_fill(wp->w_winrow, wp->w_winrow + 1, wincol < 0 ? 0 : wincol, title_wincol, - wp->w_popup_border[3] != 0 && wp->w_popup_leftoff == 0 + cl.eff_border[3] != 0 && wp->w_popup_leftoff == 0 ? border_char[4] : border_char[0], border_char[0], border_attr[0]); screen_fill(wp->w_winrow, wp->w_winrow + 1, @@ -5273,18 +6333,19 @@ update_popups(void (*win_update)(win_T *wp)) { screen_fill(wp->w_winrow, wp->w_winrow + 1, wincol < 0 ? 0 : wincol, wincol + total_width, - wp->w_popup_border[3] != 0 && wp->w_popup_leftoff == 0 + cl.eff_border[3] != 0 && wp->w_popup_leftoff == 0 ? border_char[4] : border_char[0], border_char[0], border_attr[0]); } - if (wp->w_popup_border[1] > 0) + if (cl.eff_border[1] > 0) { buf[mb_char2bytes(border_char[5], buf)] = NUL; screen_puts(buf, wp->w_winrow, wincol + total_width - 1, border_attr[1]); } } - else if (wp->w_popup_padding[0] == 0 && popup_top_extra(wp) > 0) + else if (cl.eff_padding[0] == 0 && popup_top_extra(wp) > 0 + && wp->w_popup_topoff == 0) top_padding = 1; if (top_padding > 0 || wp->w_popup_padding[2] > 0) @@ -5300,23 +6361,18 @@ update_popups(void (*win_update)(win_T *wp)) } if (top_padding > 0) { - row = wp->w_winrow + wp->w_popup_border[0]; + row = wp->w_winrow + cl.eff_border[0]; if (title_len > 0 && row == wp->w_winrow) { // top padding and no border; do not draw over the title - if (screen_opacity_popup != NULL && saved_screenlines != NULL) + if (screen_opacity_popup != NULL && saved_screen.lines != NULL) { // Left of title fill_opacity_padding(row, row + 1, padcol, title_wincol, - saved_screenlines, saved_screenattrs, - saved_screenlinesuc, save_start_row, save_start_col, - save_rows, save_cols); + &saved_screen); // Right of title fill_opacity_padding(row, row + 1, - title_wincol + title_len, padendcol, - saved_screenlines, saved_screenattrs, - saved_screenlinesuc, save_start_row, save_start_col, - save_rows, save_cols); + title_wincol + title_len, padendcol, &saved_screen); } else { @@ -5329,12 +6385,10 @@ update_popups(void (*win_update)(win_T *wp)) top_padding -= 1; } // Draw remaining top padding rows - if (screen_opacity_popup != NULL && saved_screenlines != NULL) + if (screen_opacity_popup != NULL && saved_screen.lines != NULL) { fill_opacity_padding(row, row + top_padding, padcol, padendcol, - saved_screenlines, saved_screenattrs, - saved_screenlinesuc, save_start_row, save_start_col, - save_rows, save_cols); + &saved_screen); } else { @@ -5381,25 +6435,26 @@ update_popups(void (*win_update)(win_T *wp)) attr_thumb = highlight_attr[HLF_PST]; } - for (i = wp->w_popup_border[0]; - i < total_height - wp->w_popup_border[2]; ++i) + // The side-border loop spans the popup's drawn extent. cl.eff_border + // and cl.eff_padding collapse the clipped edges to 0 so the loop + // covers the full visible area without leaving an empty trailing row. + for (i = cl.eff_border[0]; i < total_height - cl.eff_border[2]; ++i) { int pad_left; // left and right padding only needed next to the body int do_padding = - i >= wp->w_popup_border[0] + wp->w_popup_padding[0] - && i < total_height - wp->w_popup_border[2] - - wp->w_popup_padding[2]; + i >= cl.eff_border[0] + cl.eff_padding[0] + && i < total_height - cl.eff_border[2] - cl.eff_padding[2]; row = wp->w_winrow + i; // left border - if (wp->w_popup_border[3] > 0 && wincol >= 0) + if (cl.eff_border[3] > 0 && wincol >= 0) { buf[mb_char2bytes(border_char[3], buf)] = NUL; screen_puts(buf, row, wincol, border_attr[3]); } - if (do_padding && wp->w_popup_padding[3] > 0) + if (do_padding && cl.eff_padding[3] > 0) { int col = wincol + wp->w_popup_border[3]; @@ -5412,11 +6467,9 @@ update_popups(void (*win_update)(win_T *wp)) } if (pad_left > 0) { - if (screen_opacity_popup != NULL && saved_screenlines != NULL) + if (screen_opacity_popup != NULL && saved_screen.lines != NULL) fill_opacity_padding(row, row + 1, col, col + pad_left, - saved_screenlines, saved_screenattrs, - saved_screenlinesuc, save_start_row, - save_start_col, save_rows, save_cols); + &saved_screen); else screen_fill(row, row + 1, col, col + pad_left, ' ', ' ', popup_attr); @@ -5438,23 +6491,21 @@ update_popups(void (*win_update)(win_T *wp)) screen_putchar(' ', row, scroll_col, popup_attr); } // right border - if (wp->w_popup_border[1] > 0) + if (cl.eff_border[1] > 0) { buf[mb_char2bytes(border_char[1], buf)] = NUL; screen_puts(buf, row, wincol + total_width - 1, border_attr[1]); } // right padding - if (do_padding && wp->w_popup_padding[1] > 0) + if (do_padding && cl.eff_padding[1] > 0) { int pad_col_start = wincol + wp->w_popup_border[3] + wp->w_popup_padding[3] + wp->w_width + wp->w_leftcol; int pad_col_end = pad_col_start + wp->w_popup_padding[1]; - if (screen_opacity_popup != NULL && saved_screenlines != NULL) + if (screen_opacity_popup != NULL && saved_screen.lines != NULL) fill_opacity_padding(row, row + 1, pad_col_start, pad_col_end, - saved_screenlines, saved_screenattrs, - saved_screenlinesuc, save_start_row, save_start_col, - save_rows, save_cols); + &saved_screen); else screen_fill(row, row + 1, pad_col_start, pad_col_end, ' ', ' ', popup_attr); @@ -5473,39 +6524,43 @@ update_popups(void (*win_update)(win_T *wp)) } } - if (wp->w_popup_padding[2] > 0) + if (cl.eff_padding[2] > 0) { - // bottom padding - row = wp->w_winrow + wp->w_popup_border[0] - + wp->w_popup_padding[0] + wp->w_height; - if (screen_opacity_popup != NULL && saved_screenlines != NULL) - fill_opacity_padding(row, row + wp->w_popup_padding[2], - padcol, padendcol, saved_screenlines, saved_screenattrs, - saved_screenlinesuc, save_start_row, save_start_col, - save_rows, save_cols); + // bottom padding -- sits right after the visible content rows. + // Derive the row from total_height so it always lands inside the + // popup's drawn extent, including the corner case where the top + // clip consumes more rows than the content itself (so the visible + // content height is zero). A formula based on + // w_height - clip_top_content - clip_bot_content can go negative + // there and would draw the padding above w_winrow. + row = wp->w_winrow + total_height + - cl.eff_padding[2] - cl.eff_border[2]; + if (screen_opacity_popup != NULL && saved_screen.lines != NULL) + fill_opacity_padding(row, row + cl.eff_padding[2], + padcol, padendcol, &saved_screen); else - screen_fill(row, row + wp->w_popup_padding[2], + screen_fill(row, row + cl.eff_padding[2], padcol, padendcol, ' ', ' ', popup_attr); } - if (wp->w_popup_border[2] > 0) + if (cl.eff_border[2] > 0) { // bottom border row = wp->w_winrow + total_height - 1; screen_fill(row, row + 1, wincol < 0 ? 0 : wincol, wincol + total_width, - wp->w_popup_border[3] != 0 && wp->w_popup_leftoff == 0 + cl.eff_border[3] != 0 && wp->w_popup_leftoff == 0 ? border_char[7] : border_char[2], border_char[2], border_attr[2]); - if (wp->w_popup_border[1] > 0) + if (cl.eff_border[1] > 0) { buf[mb_char2bytes(border_char[6], buf)] = NUL; screen_puts(buf, row, wincol + total_width - 1, border_attr[2]); } } - if (wp->w_popup_shadow) + if (wp->w_popup_shadow && wp->w_popup_bottomoff == 0) { // bottom shadow row = wp->w_winrow + total_height; @@ -5524,13 +6579,7 @@ update_popups(void (*win_update)(win_T *wp)) update_popup_transparent(wp, 0); - // Free saved background data - if (saved_screenlines != NULL) - vim_free(saved_screenlines); - if (saved_screenattrs != NULL) - vim_free(saved_screenattrs); - if (saved_screenlinesuc != NULL) - vim_free(saved_screenlinesuc); + popup_free_saved_screen(&saved_screen); // Clear popup with opacity context. screen_opacity_popup = NULL; @@ -5545,6 +6594,10 @@ update_popups(void (*win_update)(win_T *wp)) if (override_success) pop_highlight_overrides(); + + // Undo the topoff shift applied before drawing the borders so the + // next iteration sees the popup's logical winrow. + wp->w_winrow -= wp->w_popup_topoff; } #ifdef FEAT_PROP_POPUP @@ -5741,6 +6794,10 @@ popup_hide_info(void) { popup_on_cmdline = wp->w_popup_flags & POPF_ON_CMDLINE; popup_hide(wp); + if (State & MODE_CMDLINE) + // Cmdline mode doesn't normally call update_screen(), so it's + // necessary to use pum_call_update_screen() here. + pum_call_update_screen(); } } diff --git a/src/profiler.c b/src/profiler.c index aa127a419f..2aa5aa50ac 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -392,7 +392,7 @@ ex_profile(exarg_T *eap) if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL) { VIM_CLEAR(profile_fname); - profile_fname = expand_env_save_opt(e, TRUE); + profile_fname = expand_env_save_opt(e, TRUE, NULL); do_profiling = PROF_YES; profile_zero(&prof_wait_time); set_vim_var_nr(VV_PROFILING, 1L); diff --git a/src/proto.h b/src/proto.h index 9c8c8d14b3..971a95659d 100644 --- a/src/proto.h +++ b/src/proto.h @@ -277,6 +277,9 @@ void mbyte_im_set_active(int active_arg); # include "job.pro" # include "channel.pro" # endif +# ifdef FEAT_SOCKETSERVER +# include "socketserver.pro" +# endif # ifdef FEAT_EVAL // Not generated automatically so that we can add an extra attribute. @@ -302,8 +305,12 @@ extern char_u *vimpty_getenv(const char_u *string); // in misc2.c # include "gui_w32.pro" # endif # ifdef FEAT_GUI_GTK -# include "gui_gtk.pro" -# include "gui_gtk_x11.pro" +# ifdef USE_GTK4 +# include "gui_gtk4.pro" +# else +# include "gui_gtk.pro" +# include "gui_gtk_x11.pro" +# endif # endif # ifdef FEAT_GUI_MOTIF # include "gui_motif.pro" diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro index ce1f75910a..abff7fd414 100644 --- a/src/proto/autocmd.pro +++ b/src/proto/autocmd.pro @@ -29,6 +29,8 @@ int has_textchangedP(void); int has_insertcharpre(void); int has_keyinputpre(void); int has_cmdundefined(void); +int has_textputpost(void); +int has_textputpre(void); int has_textyankpost(void); int has_completechanged(void); int has_modechanged(void); diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro index 438ddb1a86..7c29256426 100644 --- a/src/proto/buffer.pro +++ b/src/proto/buffer.pro @@ -49,9 +49,9 @@ int col_print(char_u *buf, size_t buflen, int col, int vcol); void maketitle(void); void resettitle(void); void free_titles(void); -int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab); -int build_stl_str_hl_mline(win_T *wp, char_u *out, size_t outlen, char_u **fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab); -int build_stl_str_hl_mline_nl(win_T *wp, char_u *out, size_t outlen, char_u **fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab); +int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab, stl_clickrec_T **clicktab); +int build_stl_str_hl_mline(win_T *wp, char_u *out, size_t outlen, char_u **fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab, stl_clickrec_T **clicktab, int *carry_hl); +int build_stl_str_hl_mline_nl(win_T *wp, char_u *out, size_t outlen, char_u **fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab, stl_clickrec_T **clicktab, int *carry_hl); int get_stl_rendered_height(win_T *wp, char_u *fmt, char_u *opt_name, int opt_scope); int get_rel_pos(win_T *wp, char_u *buf, int buflen); char_u *fix_fname(char_u *fname); diff --git a/src/proto/channel.pro b/src/proto/channel.pro index 201770c0ab..9604a92e64 100644 --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -7,15 +7,18 @@ int channel_unref(channel_T *channel); int free_unused_channels_contents(int copyID, int mask); void free_unused_channels(int copyID, int mask); void channel_gui_register_all(void); +channel_T *channel_open_unix(const char *path, void (*nb_close_cb)(void)); channel_T *channel_open(const char *hostname, int port, int waittime, void (*nb_close_cb)(void)); +int channel_parse_socketserver_address(char_u *address, int *port, char_u **unix_path, bool quiet); channel_T *channel_listen_func(typval_T *argvars); -channel_T *channel_listen(char *hostname, int port_in, void (*nb_close_cb)(void)); -channel_T *channel_listen_unix(char *path, void (*nb_close_cb)(void)); +channel_T *channel_listen(int port_in, void (*nb_close_cb)(void)); +channel_T *channel_listen_unix(char *path, void (*nb_close_cb)(void), bool replace); void ch_close_part(channel_T *channel, ch_part_T part); void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err); void channel_set_job(channel_T *channel, job_T *job, jobopt_T *options); void channel_write_in(channel_T *channel); void channel_buffer_free(buf_T *buf); +void channel_write_input(channel_T *channel); void channel_write_any_lines(void); void channel_write_new_lines(buf_T *buf); readq_T *channel_peek(channel_T *channel, ch_part_T part); @@ -23,6 +26,9 @@ char_u *channel_first_nl(readq_T *node); char_u *channel_get(channel_T *channel, ch_part_T part, int *outlen); void channel_consume(channel_T *channel, ch_part_T part, int len); int channel_collapse(channel_T *channel, ch_part_T part, int want_nl); +int channel_fill(js_read_T *reader); +int channel_parse_json(channel_T *channel, ch_part_T part, bool socketserver); +void remove_json_node(jsonq_T *head, jsonq_T *node); int channel_can_write_to(channel_T *channel); int channel_is_open(channel_T *channel); void channel_close(channel_T *channel, int invoke_close_cb); @@ -30,6 +36,7 @@ void channel_clear(channel_T *channel); void channel_free_all(void); void channel_may_read(channel_T *channel, ch_part_T part, char *func); void channel_may_read_close(channel_T *channel, char *func); +void channel_check(channel_T *channel, ch_part_T part); int channel_in_blocking_wait(void); channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, ch_part_T part); void channel_handle_events(int only_keep_open); @@ -61,4 +68,5 @@ void f_ch_sendraw(typval_T *argvars, typval_T *rettv); void f_ch_setoptions(typval_T *argvars, typval_T *rettv); void f_ch_status(typval_T *argvars, typval_T *rettv); char_u *channel_to_string_buf(typval_T *varp, char_u *buf); +channel_T *channel_find(int ch_id); /* vim: set ft=c : */ diff --git a/src/proto/cmdexpand.pro b/src/proto/cmdexpand.pro index 388523d6f0..390868a51f 100644 --- a/src/proto/cmdexpand.pro +++ b/src/proto/cmdexpand.pro @@ -8,17 +8,19 @@ 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); +void free_xp_files_extra(expand_T *xp, int numfiles); 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); void clear_cmdline_orig(void); -int showmatches(expand_T *xp, int display_wildmenu, int display_list, int noselect); +int showmatches(expand_T *xp, int display_wildmenu, int display_list, int wim_flags_arg); char_u *addstar(char_u *fname, int len, int context); void set_expand_context(expand_T *xp); void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline); int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches); int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *(*func)(expand_T *, int), int escaped); int ExpandGenericExt(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *(*func)(expand_T *, int), int escaped, int sortStartIdx); +void expand_process_user_list(list_T *retlist, char_u ***matches, int *numMatches, expand_T *xp); void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options, int dirs); int wildmenu_translate_key(cmdline_info_T *cclp, int key, expand_T *xp, int did_wild_list); int wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp); diff --git a/src/proto/drawscreen.pro b/src/proto/drawscreen.pro index dcf98cb6fb..da2662aca7 100644 --- a/src/proto/drawscreen.pro +++ b/src/proto/drawscreen.pro @@ -25,6 +25,7 @@ void redraw_statuslines(void); void win_redraw_last_status(frame_T *frp); void redrawWinline(win_T *wp, linenr_T lnum); void redraw_win_range_later(win_T *wp, linenr_T first, linenr_T last); +void redraw_win_range_now(win_T *wp, linenr_T first, linenr_T last); void f_redraw_listener_add(typval_T *argvars, typval_T *rettv); void f_redraw_listener_remove(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro index 5082f95430..7c3dfbb0df 100644 --- a/src/proto/ex_docmd.pro +++ b/src/proto/ex_docmd.pro @@ -48,7 +48,7 @@ void ex_stop(exarg_T *eap); void handle_drop(int filec, char_u **filev, int split, void (*callback)(void *), void *cookie); void handle_any_postponed_drop(void); void ex_edit(exarg_T *eap); -int expand_findfunc(char_u *pat, char_u ***files, int *numMatches); +int expand_findfunc(expand_T *xp, char_u *pat, char_u ***files, int *numMatches); char *did_set_findfunc(optset_T *args); void free_findfunc_option(void); int set_ref_in_findfunc(int copyID); diff --git a/src/proto/filepath.pro b/src/proto/filepath.pro index d00a66775f..ac87623834 100644 --- a/src/proto/filepath.pro +++ b/src/proto/filepath.pro @@ -36,7 +36,7 @@ char_u *do_browse(int flags, char_u *title, char_u *dflt, char_u *ext, char_u *i void f_browse(typval_T *argvars, typval_T *rettv); void f_browsedir(typval_T *argvars, typval_T *rettv); void f_filecopy(typval_T *argvars, typval_T *rettv); -void home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, int one); +size_t home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, int one); char_u *home_replace_save(buf_T *buf, char_u *src); int fullpathcmp(char_u *s1, char_u *s2, int checkname, int expandenv); char_u *gettail(char_u *fname); diff --git a/src/proto/gui_gtk.pro b/src/proto/gui_gtk.pro index 7b87ba00bd..9b69c69418 100644 --- a/src/proto/gui_gtk.pro +++ b/src/proto/gui_gtk.pro @@ -21,4 +21,5 @@ void gui_make_popup(char_u *path_name, int mouse_pos); void gui_mch_find_dialog(exarg_T *eap); void gui_mch_replace_dialog(exarg_T *eap); void ex_helpfind(exarg_T *eap); +void gui_mch_set_fullscreen(int flag); /* vim: set ft=c : */ diff --git a/src/proto/gui_gtk4.pro b/src/proto/gui_gtk4.pro new file mode 100644 index 0000000000..0a1ba1296c --- /dev/null +++ b/src/proto/gui_gtk4.pro @@ -0,0 +1,111 @@ +/* gui_gtk4.c */ +void gui_mch_prepare(int *argc, char **argv); +void gui_mch_free_all(void); +int gui_mch_is_blinking(void); +int gui_mch_is_blink_off(void); +void gui_mch_set_blinking(long waittime, long on, long off); +void gui_mch_stop_blink(int may_call_gui_update_cursor); +void gui_mch_start_blink(void); +int gui_mch_early_init_check(int give_message); +int gui_mch_init_check(void); +int gui_mch_init(void); +void gui_mch_new_colors(void); +int gui_mch_open(void); +void gui_mch_exit(int rc); +int gui_mch_get_winpos(int *x, int *y); +void gui_mch_set_winpos(int x, int y); +int gui_mch_maximized(void); +void gui_mch_unmaximize(void); +void gui_mch_set_fullscreen(int flag); +void gui_mch_newfont(void); +void gui_mch_settitle(char_u *title, char_u *icon); +void gui_gtk_init_decor_height(void); +void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction); +void gui_mch_get_screen_dimensions(int *screen_w, int *screen_h); +void gui_mch_enable_menu(int showit); +void gui_mch_show_toolbar(int showit); +void gui_mch_set_dark_theme(int dark); +int gui_mch_adjust_charheight(void); +char_u *gui_mch_font_dialog(char_u *oldval); +int gui_mch_init_font(char_u *font_name, int fontset); +GuiFont gui_mch_get_font(char_u *name, int report_error); +char_u *gui_mch_get_fontname(GuiFont font, char_u *name); +void gui_mch_free_font(GuiFont font); +void gui_mch_expand_font(optexpand_T *args, void *param, int (*add_match)(char_u *val)); +guicolor_T gui_mch_get_color(char_u *name); +guicolor_T gui_mch_get_rgb_color(int r, int g, int b); +void gui_mch_set_fg_color(guicolor_T color); +void gui_mch_set_bg_color(guicolor_T color); +void gui_mch_set_sp_color(guicolor_T color); +guicolor_T gui_mch_get_rgb(guicolor_T pixel); +void gui_mch_clear_block(int row1, int col1, int row2, int col2); +void gui_mch_clear_all(void); +void gui_mch_delete_lines(int row, int num_lines); +void gui_mch_insert_lines(int row, int num_lines); +void gui_mch_draw_hollow_cursor(guicolor_T color); +void gui_mch_draw_part_cursor(int w, int h, guicolor_T color); +void gui_mch_flash(int msec); +void gui_mch_invert_rectangle(int r, int c, int nr, int nc); +void gui_mch_update(void); +int gui_mch_wait_for_chars(long wtime); +void gui_mch_flush(void); +void gui_mch_beep(void); +void *gui_mch_get_display(void); +void gui_mch_iconify(void); +void gui_mch_set_foreground(void); +void gui_mch_getmouse(int *x, int *y); +void gui_mch_setmouse(int x, int y); +void gui_mch_mousehide(int hide); +int gui_mch_haskey(char_u *name); +void gui_mch_forked(void); +void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag); +void gui_mch_menu_grey(vimmenu_T *menu, int grey); +void gui_mch_menu_hidden(vimmenu_T *menu, int hidden); +void gui_mch_draw_menubar(void); +void gui_mch_show_tabline(int showit); +int gui_mch_showing_tabline(void); +void gui_mch_update_tabline(void); +void gui_mch_set_curtab(int nr); +void gui_mch_drawsign(int row, int col, int typenr); +void *gui_mch_register_sign(char_u *signfile); +void gui_mch_destroy_sign(void *sign); +int gui_gtk_draw_string_ext(int row, int col, char_u *s, int len, int flags, int force_pango); +int gui_gtk_draw_string(int row, int col, char_u *s, int len, int flags); +int gui_get_x11_windis(Window *win, Display **dis); +void gui_gtk_set_mnemonics(int enable); +void gui_make_popup(char_u *path_name, int mouse_pos); +int get_menu_tool_width(void); +int get_menu_tool_height(void); +void clip_mch_request_selection(Clipboard_T *cbd); +void clip_mch_set_selection(Clipboard_T *cbd); +int clip_mch_own_selection(Clipboard_T *cbd); +void clip_mch_lose_selection(Clipboard_T *cbd); +void gui_mch_post_balloon(BalloonEval *beval, char_u *mesg); +BalloonEval *gui_mch_create_beval_area(void *target, char_u *mesg, void (*mesgCB)(BalloonEval *, int), void *clientData); +void gui_mch_enable_beval_area(BalloonEval *beval); +void gui_mch_disable_beval_area(BalloonEval *beval); +guint gtk_main_level(void); +void gtk_main_quit(void); +void mch_set_mouse_shape(int shape); +void gui_mch_add_menu(vimmenu_T *menu, int idx); +void gui_mch_add_menu_item(vimmenu_T *menu, int idx); +void gui_mch_toggle_tearoffs(int enable); +void gui_mch_menu_set_tip(vimmenu_T *menu); +void gui_mch_destroy_menu(vimmenu_T *menu); +void gui_mch_show_popupmenu(vimmenu_T *menu); +void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max); +void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h); +int gui_mch_get_scrollbar_xpadding(void); +int gui_mch_get_scrollbar_ypadding(void); +void gui_mch_create_scrollbar(scrollbar_T *sb, int orient); +void gui_mch_destroy_scrollbar(scrollbar_T *sb); +void gui_mch_update_scrollbar_size(void); +void gui_mch_set_text_area_pos(int x, int y, int w, int h); +char_u *gui_mch_browse(int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter); +char_u *gui_mch_browsedir(char_u *title, char_u *initdir); +int gui_mch_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, char_u *textfield, int ex_cmd); +void gui_mch_find_dialog(exarg_T *eap); +void gui_mch_replace_dialog(exarg_T *eap); +void ex_helpfind(exarg_T *eap); +void gui_gtk4_hardcopy(exarg_T *eap); +/* vim: set ft=c : */ diff --git a/src/proto/gui_gtk_x11.pro b/src/proto/gui_gtk_x11.pro index 5a57240135..696f6a07af 100644 --- a/src/proto/gui_gtk_x11.pro +++ b/src/proto/gui_gtk_x11.pro @@ -8,8 +8,6 @@ void gui_mch_stop_blink(int may_call_gui_update_cursor); void gui_mch_start_blink(void); int gui_mch_early_init_check(int give_message); int gui_mch_init_check(void); -void gui_gtk_init_socket_server(void); -void gui_gtk_uninit_socket_server(void); void gui_mch_set_dark_theme(int dark); void gui_mch_show_tabline(int showit); int gui_mch_showing_tabline(void); diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro index d24a61d151..706629490d 100644 --- a/src/proto/misc1.pro +++ b/src/proto/misc1.pro @@ -29,9 +29,9 @@ void free_homedir(void); void free_users(void); void init_vimdir(void); char_u *expand_env_save(char_u *src); -char_u *expand_env_save_opt(char_u *src, int one); +char_u *expand_env_save_opt(char_u *src, int one, char_u *esc_chars); size_t expand_env(char_u *src, char_u *dst, int dstlen); -size_t expand_env_esc(char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr); +size_t expand_env_esc(char_u *srcp, char_u *dst, int dstlen, char_u *esc_chars, int one, char_u *startstr); char_u *vim_getenv(char_u *name, int *mustfree); void vim_unsetenv(char_u *var); void vim_unsetenv_ext(char_u *var); diff --git a/src/proto/option.pro b/src/proto/option.pro index f4da0a365f..d327b59803 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -155,6 +155,7 @@ int option_was_set(char_u *name); int reset_option_was_set(char_u *name); int can_bs(int what); long get_scrolloff_value(void); +long get_scrolloffpad_value(void); long get_sidescrolloff_value(void); unsigned int get_bkc_flags(buf_T *buf); char_u *get_flp_value(buf_T *buf); diff --git a/src/proto/optionstr.pro b/src/proto/optionstr.pro index 08896413da..f6e85794ea 100644 --- a/src/proto/optionstr.pro +++ b/src/proto/optionstr.pro @@ -152,6 +152,7 @@ char *did_set_selectmode(optset_T *args); int expand_set_selectmode(optexpand_T *args, int *numMatches, char_u ***matches); char *did_set_sessionoptions(optset_T *args); int expand_set_sessionoptions(optexpand_T *args, int *numMatches, char_u ***matches); +char *did_set_shellpipe_redir(optset_T *args); char *did_set_shortmess(optset_T *args); int expand_set_shortmess(optexpand_T *args, int *numMatches, char_u ***matches); char *did_set_showbreak(optset_T *args); diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro index 7513e400f0..aca289d1f7 100644 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -96,15 +96,4 @@ void stop_timeout(void); volatile sig_atomic_t *start_timeout(long msec); void delete_timer(void); int mch_create_anon_file(void); -int socket_server_init(char_u *name); -void socket_server_uninit(void); -char_u *socket_server_list_sockets(void); -int socket_server_accept_client(void); -int socket_server_valid(void); -int socket_server_send(char_u *name, char_u *str, char_u **result, char_u **receiver, int is_expr, int timeout, int silent); -int socket_server_read_reply(char_u *client, char_u **str, int timeout); -int socket_server_peek_reply(char_u *sender, char_u **str); -int socket_server_send_reply(char_u *client, char_u *str); -int socket_server_get_fd(void); -int socket_server_waiting_accept(void); /* vim: set ft=c : */ diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro index d6ac2b72a0..14e4a6fd29 100644 --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -53,6 +53,7 @@ int popup_do_filter(int c); int popup_no_mapping(void); void popup_check_cursor_pos(void); int popup_is_under_opacity(int row, int col); +int popup_is_over_opacity(int row, int col); int popup_is_under_opacity_range(int row, int start_col, int end_col); void may_update_popup_mask(int type); void may_update_popup_position(void); diff --git a/src/proto/screen.pro b/src/proto/screen.pro index 2dce886917..a1d5714d8f 100644 --- a/src/proto/screen.pro +++ b/src/proto/screen.pro @@ -48,7 +48,7 @@ void clearmode(void); void draw_tabline(void); void get_trans_bufname(buf_T *buf); int fillchar_status(int *attr, win_T *wp); -int fillchar_vsep(int *attr, win_T *wp); +int fillchar_vsep(int *attr, win_T *wp, int row); int redrawing(void); int messaging(void); void comp_col(void); diff --git a/src/proto/search.pro b/src/proto/search.pro index 445817762d..3e700a6d8e 100644 --- a/src/proto/search.pro +++ b/src/proto/search.pro @@ -24,6 +24,7 @@ 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, size_t patlen, long count, int options, int pat_use, searchit_arg_T *extra_arg); void set_search_direction(int cdir); +int parse_search_pattern_offset(char_u **pat, size_t *patlen, int search_delim, int options, char_u **strcopy, char_u **searchstr, size_t *searchstrlen, char_u **dircp, soffset_T *offset); 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); diff --git a/src/proto/socketserver.pro b/src/proto/socketserver.pro new file mode 100644 index 0000000000..69d292c3ab --- /dev/null +++ b/src/proto/socketserver.pro @@ -0,0 +1,11 @@ +/* socketserver.c */ +int socketserver_start(char_u *name, bool quiet); +void socketserver_stop(void); +char_u *socketserver_list(void); +int set_ref_in_socketserver_channel(int copyID); +void socketserver_parse_messages(void); +int socketserver_send(char_u *name, char_u *str, char_u **result, bool is_expr, int timeout, bool silent, channel_T **ch); +int socketserver_send_reply(char_u *client, char_u *str); +int socketserver_read_reply(char_u *client, char_u **str, int timeout, bool remotewait); +int socketserver_peek_reply(char_u *sender, char_u **str); +/* vim: set ft=c : */ diff --git a/src/proto/tabpanel.pro b/src/proto/tabpanel.pro index d62d13f3a1..42f4dd8b66 100644 --- a/src/proto/tabpanel.pro +++ b/src/proto/tabpanel.pro @@ -1,7 +1,15 @@ /* tabpanel.c */ int tabpanelopt_changed(void); +void tabpanel_forget_tabpage(const tabpage_T *tp); int tabpanel_width(void); int tabpanel_leftcol(void); void draw_tabpanel(void); int get_tabpagenr_on_tabpanel(void); +bool mouse_on_tabpanel(void); +bool mouse_on_tabpanel_scrollbar(void); +bool tabpanel_drag_scrollbar(int screen_row); +bool tabpanel_scroll(int dir, int count); +bool tabpanel_set_offset(int offset); +void f_tabpanel_getinfo(typval_T *argvars, typval_T *rettv); +void f_tabpanel_scroll(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/proto/term.pro b/src/proto/term.pro index 82c794f4f9..3f099338be 100644 --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -96,8 +96,8 @@ void swap_tcap(void); void ansi_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx); void cterm_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx); int term_replace_keycodes(char_u *ta_buf, int ta_len, int len_arg); -void send_decrqm_modes(void); void term_disable_dec(void); void term_set_win_resize(bool state); +int sync_output_active(void); void term_set_sync_output(int flags); /* vim: set ft=c : */ diff --git a/src/proto/textprop.pro b/src/proto/textprop.pro index d3ecf6d14c..be9d80c6e3 100644 --- a/src/proto/textprop.pro +++ b/src/proto/textprop.pro @@ -16,6 +16,7 @@ int get_text_props(buf_T *buf, linenr_T lnum, char_u **props, int will_change); int prop_count_above_below(buf_T *buf, linenr_T lnum); int count_props(linenr_T lnum, int only_starting, int last_line); void sort_text_props(buf_T *buf, textprop_T *props, int *idxs, int count); +bool find_prop_in_lines(win_T *wp, int type_id, int id, textprop_T *prop, linenr_T *found_lnum, linenr_T first_lnum, linenr_T last_lnum); bool find_visible_prop(win_T *wp, int type_id, int id, textprop_T *prop, linenr_T *found_lnum); char_u *props_add_count_header(char_u *line, int line_len, int textlen, int *new_len); void add_text_props(linenr_T lnum, textprop_T *text_props, int text_prop_count); diff --git a/src/proto/wayland.pro b/src/proto/wayland.pro index f4f87d988b..770b5e1114 100644 --- a/src/proto/wayland.pro +++ b/src/proto/wayland.pro @@ -3,7 +3,6 @@ int vwl_connection_flush(vwl_connection_T *self); int vwl_connection_dispatch(vwl_connection_T *self); int vwl_connection_roundtrip(vwl_connection_T *self); vwl_seat_T *vwl_connection_get_seat(vwl_connection_T *self, const char *label); -struct wl_keyboard *vwl_seat_get_keyboard(vwl_seat_T *self); int wayland_init_connection(const char *display); void wayland_uninit_connection(void); int wayland_prepare_read(void); diff --git a/src/quickfix.c b/src/quickfix.c index 527760d669..0c7a9c9a52 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -1412,7 +1412,6 @@ qf_parse_file_pfx( *fields->namebuf = NUL; if (tail && *tail) { - STRMOVE(IObuff, skipwhite(tail)); qfl->qf_multiscan = TRUE; return QF_MULTISCAN; } @@ -1579,7 +1578,15 @@ restofline: { // global file names status = qf_parse_file_pfx(idx, fields, qfl, tail); if (status == QF_MULTISCAN) + { + char_u *s = skipwhite(tail); + int new_linelen = (int)STRLEN(s); + if (new_linelen >= linelen) + return QF_IGNORE_LINE; + linebuf = s; + linelen = new_linelen; goto restofline; + } } if (fmt_ptr->flags == '-') // generally exclude this line { @@ -3619,6 +3626,32 @@ qf_jump_edit_buffer( return retval; } +/* + * Return the byte index in the current line for screen column "vcol" + * (zero-based). A is always counted as 8 screen columns, matching the + * column numbers compilers report for the "%v" item in 'errorformat', + * regardless of the buffer's 'tabstop'. + */ + static int +qf_screen_col_to_idx(colnr_T vcol) +{ + char_u *line = ml_get_curline(); + char_u *p = line; + colnr_T col = 0; + + while (*p != NUL && col < vcol) + { + if (*p == TAB) + col += 8 - (col % 8); + else + col += ptr2cells(p); + if (col > vcol) + break; + MB_PTR_ADV(p); + } + return (int)(p - line); +} + /* * Go to the error line in the current file using either line/column number or * a search pattern. @@ -3646,10 +3679,10 @@ qf_jump_goto_line( { curwin->w_cursor.coladd = 0; if (qf_viscol == TRUE) - coladvance(qf_col - 1); + curwin->w_cursor.col = qf_screen_col_to_idx(qf_col - 1); else curwin->w_cursor.col = qf_col - 1; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; check_cursor(); } else @@ -4401,6 +4434,9 @@ qf_mark_adjust( if (qfp->qf_fnum == curbuf->b_fnum) { found_one = TRUE; + if (qfp->qf_cleared) + continue; + if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) { if (amount == MAXLNUM) @@ -4768,7 +4804,7 @@ qf_win_goto(win_T *win, linenr_T lnum) curwin->w_curswant = 0; update_topline(); // scroll to show the line redraw_later(UPD_VALID); - curwin->w_redr_status = TRUE; // update ruler + curwin->w_redr_status = true; // update ruler curwin = old_curwin; curbuf = curwin->w_buffer; } @@ -5271,12 +5307,12 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid) 0L, (char_u *)"qf", OPT_LOCAL); curbuf->b_p_ma = FALSE; - curbuf->b_keep_filetype = TRUE; // don't detect 'filetype' + curbuf->b_keep_filetype = true; // don't detect 'filetype' apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL, FALSE, curbuf); apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL, FALSE, curbuf); - curbuf->b_keep_filetype = FALSE; + curbuf->b_keep_filetype = false; --curbuf_lock; // make sure it will be redrawn @@ -7176,6 +7212,7 @@ get_qfline_items(qfline_T *qfp, list_T *list) int bufnum; dict_T *dict; char_u buf[2]; + size_t buflen; // Handle entries with a non-existing buffer number. bufnum = qfp->qf_fnum; @@ -7189,6 +7226,7 @@ get_qfline_items(qfline_T *qfp, list_T *list) buf[0] = qfp->qf_type; buf[1] = NUL; + buflen = (buf[0] == NUL) ? 0 : 1; if (dict_add_number(dict, "bufnr", (long)bufnum) == FAIL || dict_add_number(dict, "lnum", (long)qfp->qf_lnum) == FAIL || dict_add_number(dict, "end_lnum", (long)qfp->qf_end_lnum) == FAIL @@ -7199,7 +7237,7 @@ get_qfline_items(qfline_T *qfp, list_T *list) || dict_add_string(dict, "module", qfp->qf_module) == FAIL || dict_add_string(dict, "pattern", qfp->qf_pattern) == FAIL || dict_add_string(dict, "text", qfp->qf_text) == FAIL - || dict_add_string(dict, "type", buf) == FAIL + || dict_add_string_len(dict, "type", buf, (int)buflen) == FAIL || (qfp->qf_user_data.v_type != VAR_UNKNOWN && dict_add_tv(dict, "user_data", &qfp->qf_user_data) == FAIL ) || dict_add_number(dict, "valid", (long)qfp->qf_valid) == FAIL) @@ -7484,7 +7522,7 @@ qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict) int status = OK; if (flags & QF_GETLIST_TITLE) - status = dict_add_string(retdict, "title", (char_u *)""); + status = dict_add_string_len(retdict, "title", (char_u *)"", 0); if ((status == OK) && (flags & QF_GETLIST_ITEMS)) { list_T *l = list_alloc(); @@ -7498,7 +7536,7 @@ qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict) if ((status == OK) && (flags & QF_GETLIST_WINID)) status = dict_add_number(retdict, "winid", qf_winid(qi)); if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) - status = dict_add_string(retdict, "context", (char_u *)""); + status = dict_add_string_len(retdict, "context", (char_u *)"", 0); if ((status == OK) && (flags & QF_GETLIST_ID)) status = dict_add_number(retdict, "id", 0); if ((status == OK) && (flags & QF_GETLIST_IDX)) @@ -7512,7 +7550,7 @@ qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict) if ((status == OK) && (flags & QF_GETLIST_QFBUFNR)) status = qf_getprop_qfbufnr(qi, retdict); if ((status == OK) && (flags & QF_GETLIST_QFTF)) - status = dict_add_string(retdict, "quickfixtextfunc", (char_u *)""); + status = dict_add_string_len(retdict, "quickfixtextfunc", (char_u *)"", 0); return status; } @@ -7589,7 +7627,7 @@ qf_getprop_ctx(qf_list_T *qfl, dict_T *retdict) status = FAIL; } else - status = dict_add_string(retdict, "context", (char_u *)""); + status = dict_add_string_len(retdict, "context", (char_u *)"", 0); return status; } @@ -7628,7 +7666,7 @@ qf_getprop_qftf(qf_list_T *qfl, dict_T *retdict) clear_tv(&tv); } else - status = dict_add_string(retdict, "quickfixtextfunc", (char_u *)""); + status = dict_add_string_len(retdict, "quickfixtextfunc", (char_u *)"", 0); return status; } @@ -8164,13 +8202,16 @@ qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, dictitem_T *di) } /* - * Set the current index in the specified quickfix list + * Set the 'quickfixtextfunc' in the specified quickfix/location list */ static int qf_setprop_qftf(qf_info_T *qi UNUSED, qf_list_T *qfl, dictitem_T *di) { callback_T cb; + if (check_restricted() || check_secure()) + return FAIL; + free_callback(&qfl->qf_qftf_cb); cb = get_callback(&di->di_tv); if (cb.cb_name == NULL || *cb.cb_name == NUL) diff --git a/src/regexp.h b/src/regexp.h index 7a0c3abac6..aa685a54d0 100644 --- a/src/regexp.h +++ b/src/regexp.h @@ -123,6 +123,8 @@ typedef struct char_u *pattern; int nsubexp; // number of () int nstate; + void *listbuf[2]; // cached list buffers for + // nfa_regmatch() nfa_state_T state[1]; // actually longer.. } nfa_regprog_T; diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index 610c6bd678..4bd588b4e4 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -5797,9 +5797,21 @@ nfa_regmatch( // Allocate memory for the lists of nodes. size = (prog->nstate + 1) * sizeof(nfa_thread_T); - list[0].t = alloc(size); + // Reuse cached list buffers from prog when available (top-level call). + // Recursive calls must allocate their own buffers. + if (toplevel && prog->listbuf[0] != NULL) + { + list[0].t = (nfa_thread_T *)prog->listbuf[0]; + list[1].t = (nfa_thread_T *)prog->listbuf[1]; + prog->listbuf[0] = NULL; + prog->listbuf[1] = NULL; + } + else + { + list[0].t = alloc(size); + list[1].t = alloc(size); + } list[0].len = prog->nstate + 1; - list[1].t = alloc(size); list[1].len = prog->nstate + 1; if (list[0].t == NULL || list[1].t == NULL) goto theend; @@ -7287,9 +7299,18 @@ nextchar: #endif theend: - // Free memory - vim_free(list[0].t); - vim_free(list[1].t); + // Cache list buffers in prog for reuse, or free if prog already has + // cached buffers (recursive call case). + if (prog->listbuf[0] == NULL && list[0].t != NULL && list[1].t != NULL) + { + prog->listbuf[0] = list[0].t; + prog->listbuf[1] = list[1].t; + } + else + { + vim_free(list[0].t); + vim_free(list[1].t); + } vim_free(listids); #undef ADD_STATE_IF_MATCH #ifdef NFA_REGEXP_DEBUG_LOG @@ -7644,6 +7665,8 @@ nfa_regcomp(char_u *expr, int re_flags) goto fail; state_ptr = prog->state; prog->re_in_use = FALSE; + prog->listbuf[0] = NULL; + prog->listbuf[1] = NULL; /* * PASS 2 @@ -7707,6 +7730,8 @@ nfa_regfree(regprog_T *prog) vim_free(((nfa_regprog_T *)prog)->match_text); vim_free(((nfa_regprog_T *)prog)->pattern); + vim_free(((nfa_regprog_T *)prog)->listbuf[0]); + vim_free(((nfa_regprog_T *)prog)->listbuf[1]); vim_free(prog); } diff --git a/src/register.c b/src/register.c index a20e5c1d0f..358fe6454f 100644 --- a/src/register.c +++ b/src/register.c @@ -352,6 +352,16 @@ get_register( { reg->y_array[i].string = vim_strnsave(y_current->y_array[i].string, y_current->y_array[i].length); + if (reg->y_array[i].string == NULL) + { + // The allocation failed so clean up and exit + while (--i >= 0) + vim_free(reg->y_array[i].string); + vim_free(reg->y_array); + vim_free(reg); + return (void *)NULL; + } + reg->y_array[i].length = y_current->y_array[i].length; } } @@ -777,22 +787,18 @@ do_execreg( static void put_reedit_in_typebuf(int silent) { - char_u buf[3]; - if (restart_edit == NUL) return; - if (restart_edit == 'V') - { - buf[0] = 'g'; - buf[1] = 'R'; - buf[2] = NUL; - } - else - { - buf[0] = restart_edit == 'I' ? 'i' : restart_edit; - buf[1] = NUL; - } + char_u buf[] = { K_SPECIAL, KS_EXTRA, KE_COMMAND, + // :startinsert + 's', 't', 'a', 'r', 't', 'i', CAR, NUL }; + if (restart_edit == 'R') + buf[8] = 'r'; // :startreplace + else if (restart_edit == 'V') + buf[8] = 'g'; // :startgreplace + else if (restart_edit == 'A') + buf[8] = '!'; // :startinsert! if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, silent) == OK) restart_edit = NUL; } @@ -1075,6 +1081,36 @@ shift_delete_registers(void) } #if defined(FEAT_EVAL) + static void +add_regtype_to_dict(int regname, dict_T *dict, char_u *buf, int bufsize) +{ + size_t buflen; + long reglen; + // Register type + switch (get_reg_type(regname, ®len)) + { + case MLINE: + buf[0] = 'V'; + buf[1] = NUL; + buflen = 1; + break; + case MCHAR: + buf[0] = 'v'; + buf[1] = NUL; + buflen = 1; + break; + case MBLOCK: + buflen = vim_snprintf_safelen((char *)buf, bufsize, + "%c%ld", Ctrl_V, reglen + 1); + break; + default: + buf[0] = NUL; + buflen = 0; + break; + } + (void)dict_add_string_len(dict, "regtype", buf, (int)buflen); +} + void yank_do_autocmd(oparg_T *oap, yankreg_T *reg) { @@ -1083,7 +1119,7 @@ yank_do_autocmd(oparg_T *oap, yankreg_T *reg) list_T *list; int n; char_u buf[NUMBUFLEN + 2]; - long reglen = 0; + size_t buflen; save_v_event_T save_v_event; if (recursive) @@ -1104,7 +1140,8 @@ yank_do_autocmd(oparg_T *oap, yankreg_T *reg) // register name or empty string for unnamed operation buf[0] = (char_u)oap->regname; buf[1] = NUL; - (void)dict_add_string(v_event, "regname", buf); + buflen = (buf[0] == NUL) ? 0 : 1; + (void)dict_add_string_len(v_event, "regname", buf, (int)buflen); // motion type: inclusive or exclusive (void)dict_add_bool(v_event, "inclusive", oap->inclusive); @@ -1113,21 +1150,10 @@ yank_do_autocmd(oparg_T *oap, yankreg_T *reg) buf[0] = get_op_char(oap->op_type); buf[1] = get_extra_op_char(oap->op_type); buf[2] = NUL; - (void)dict_add_string(v_event, "operator", buf); + buflen = (buf[0] == NUL) ? 0 : (buf[1] == NUL) ? 1 : 2; + (void)dict_add_string_len(v_event, "operator", buf, (int)buflen); - // register type - buf[0] = NUL; - buf[1] = NUL; - switch (get_reg_type(oap->regname, ®len)) - { - case MLINE: buf[0] = 'V'; break; - case MCHAR: buf[0] = 'v'; break; - case MBLOCK: - vim_snprintf((char *)buf, sizeof(buf), "%c%ld", Ctrl_V, - reglen + 1); - break; - } - (void)dict_add_string(v_event, "regtype", buf); + add_regtype_to_dict(oap->regname, v_event, buf, sizeof(buf)); // selection type - visual or not (void)dict_add_bool(v_event, "visual", oap->is_VIsual); @@ -1144,6 +1170,102 @@ yank_do_autocmd(oparg_T *oap, yankreg_T *reg) // Empty the dictionary, v:event is still valid restore_v_event(v_event, &save_v_event); } + + static void +put_do_autocmd( + int regname, + yankreg_T *reg, // May be NULL, if special register + string_T *insert, // Not NULL if special register, except '.' + bool post, // If Post or Pre + int dir) // BACKWARD for 'P', FORWARD for 'p' +{ + static bool recursive = false; + dict_T *v_event; + list_T *list; + int n; + char_u buf[NUMBUFLEN + 2]; + size_t buflen; + save_v_event_T save_v_event; + + if (recursive || regname == '_') + return; + + if (regname != '.' && insert == NULL + && reg == NULL) + // Can happen when pasting text in normal mode in a terminal buffer + return; + + v_event = get_v_event(&save_v_event); + + list = list_alloc(); + if (list == NULL) + return; + + // Make sure regcontents will be up to date +# ifdef FEAT_CLIPBOARD_PROVIDER + inc_clip_provider(); + call_clip_provider_request(regname); +# endif +# ifdef FEAT_CLIPBOARD + if (clipmethod != CLIPMETHOD_PROVIDER) + regname = may_get_selection(regname); +# endif + + if (regname == '.') + { + if (last_insert_ga.ga_data != NULL) + // Get the last inserted text to place in "regcontents" + list_append_string(list, last_insert_ga.ga_data, + (int)last_insert_ga.ga_len); + } + else if (insert != NULL) + { + list_append_string(list, insert->string, (int)insert->length); + } + else + { + for (n = 0; n < reg->y_size; n++) + list_append_string(list, reg->y_array[n].string, + (int)reg->y_array[n].length); + } + + list->lv_lock = VAR_FIXED; + (void)dict_add_list(v_event, "regcontents", list); + + // register name or empty string for unnamed operation + buf[0] = (char_u)regname; + buf[1] = NUL; + buflen = (buf[0] == NUL) ? 0 : 1; + (void)dict_add_string_len(v_event, "regname", buf, (int)buflen); + + // kind of operation (P, p) + buf[0] = dir == BACKWARD ? 'P' : 'p'; + buf[1] = NUL; + buflen = 1; + (void)dict_add_string_len(v_event, "operator", buf, (int)buflen); + + add_regtype_to_dict(regname, v_event, buf, sizeof(buf)); +# ifdef FEAT_CLIPBOARD_PROVIDER + dec_clip_provider(); +# endif + + (void)dict_add_bool(v_event, "visual", VIsual_active); + + // Lock the dictionary and its keys + dict_set_items_ro(v_event); + + recursive = true; + textlock++; + if (post) + apply_autocmds(EVENT_TEXTPUTPOST, NULL, NULL, FALSE, curbuf); + else + apply_autocmds(EVENT_TEXTPUTPRE, NULL, NULL, FALSE, curbuf); + textlock--; + recursive = false; + + // Empty the dictionary, v:event is still valid + restore_v_event(v_event, &save_v_event); +} #endif /* @@ -1608,6 +1730,7 @@ do_put( adjust_clip_reg(®name); #endif #ifdef FEAT_CLIPBOARD_PROVIDER + inc_clip_provider(); call_clip_provider_request(regname); #endif #ifdef FEAT_CLIPBOARD @@ -1629,8 +1752,33 @@ do_put( { if (VIsual_active) stuffcharReadbuff(VIsual_mode); + +#ifdef FEAT_EVAL + bool has_textput_events = has_textputpre() || has_textputpost(); + if (has_textput_events) + add_last_insert++; +#endif + (void)stuff_inserted((dir == FORWARD ? (count == -1 ? 'o' : 'a') : (count == -1 ? 'O' : 'i')), count, FALSE); + +#ifdef FEAT_EVAL + // Since the text is not inserted into the buffer immediately, just call + // TextPutPost after TextPutPre. + if (has_textputpre()) + put_do_autocmd('.', NULL, NULL, false, dir); +#endif +#ifdef FEAT_CLIPBOARD_PROVIDER + dec_clip_provider(); +#endif +#ifdef FEAT_EVAL + if (has_textputpost()) + put_do_autocmd('.', NULL, NULL, true, dir); + + if (has_textput_events && --add_last_insert == 0) + ga_clear(&last_insert_ga); +#endif + // Putting the text is done later, so can't really move the cursor to // the next character. Use "l" to simulate it. if ((flags & PUT_CURSEND) && gchar_cursor() != NUL) @@ -1646,7 +1794,12 @@ do_put( insert_string.string = expr_result; else if (get_spec_reg(regname, &insert_string.string, &allocated, TRUE) && insert_string.string == NULL) + { +#ifdef FEAT_CLIPBOARD_PROVIDER + dec_clip_provider(); +#endif return; + } // Autocommands may be executed when saving lines for undo. This might // make "y_array" invalid, so we start undo now to avoid that. @@ -1714,9 +1867,22 @@ do_put( y_size = 1; // use fake one-line yank register y_array = &insert_string; } +#ifdef FEAT_EVAL + if (has_textputpre()) + put_do_autocmd(regname, NULL, &insert_string, false, dir); +#endif } else { +#ifdef FEAT_EVAL + if (has_textputpre()) + { + // Make sure to call this before we set the variables, as setreg() + // may be called and invalidate them. + get_yank_register(regname, FALSE); + put_do_autocmd(regname, y_current, NULL, false, dir); + } +#endif get_yank_register(regname, FALSE); y_type = y_current->y_type; @@ -1863,8 +2029,8 @@ do_put( // move to start of next multi-byte character curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor()); else - if (c != TAB || cur_ve_flags != VE_ALL) - ++curwin->w_cursor.col; + if (c != TAB || cur_ve_flags != VE_ALL) + ++curwin->w_cursor.col; ++col; } else @@ -2365,7 +2531,7 @@ error: } msgmore(nr_lines); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; // Make sure the cursor is not after the NUL. int len = ml_get_curline_len(); @@ -2382,6 +2548,21 @@ end: curbuf->b_op_start = orig_start; curbuf->b_op_end = orig_end; } + +#ifdef FEAT_CLIPBOARD_PROVIDER + dec_clip_provider(); +#endif + +#ifdef FEAT_EVAL + if (has_textputpost()) + { + if (insert_string.string == NULL) + put_do_autocmd(regname, y_current, NULL, true, dir); + else + put_do_autocmd(regname, NULL, &insert_string, true, dir); + } +#endif + if (allocated) vim_free(insert_string.string); if (regname == '=') diff --git a/src/screen.c b/src/screen.c index 2e7ad97eaf..bd0f0aead7 100644 --- a/src/screen.c +++ b/src/screen.c @@ -134,7 +134,7 @@ get_win_attr(win_T *wp) if (wp->w_popup_flags & POPF_INFO) win_attr = HL_ATTR(HLF_PSI); // PmenuSel else - win_attr = HL_ATTR(HLF_PNI); // Pmenu + win_attr = HL_ATTR(HLF_POP); // Popup } #endif @@ -445,6 +445,21 @@ skip_for_popup(int row, int col) #endif ) return TRUE; + // Protect cells under the pum from background draws (vsep, status line). + // Excluded for wildmenu pum (MODE_CMDLINE): pum_row can be stale while + // the cmdline grows. +#ifdef FEAT_PROP_POPUP + if (screen_zindex < POPUPMENU_ZINDEX + && pum_visible() + && (State & MODE_CMDLINE) == 0 + && pum_under_menu(row, col, FALSE)) + return TRUE; +#else + if (pum_visible() + && (State & MODE_CMDLINE) == 0 + && pum_under_menu(row, col, FALSE)) + return TRUE; +#endif #ifdef FEAT_PROP_POPUP if (blocked_by_popup(row, col)) return TRUE; @@ -453,6 +468,52 @@ skip_for_popup(int row, int col) } #ifdef FEAT_PROP_POPUP +/* + * Cached attributes of the current opacity popup, computed once per + * screen_line() to avoid recomputing them inside the per-cell loop. + */ +typedef struct { + int popup_attr; // get_win_attr(screen_opacity_popup) + int blend; // screen_opacity_popup->w_popup_blend +} popup_opacity_T; + + static inline void +popup_opacity_init(popup_opacity_T *po) +{ + po->popup_attr = get_win_attr(screen_opacity_popup); + po->blend = screen_opacity_popup->w_popup_blend; +} + +/* + * Read the underlying base screen attribute at (row, col), falling back + * to "fallback" when the position is outside base_screenattrs. + */ + static inline int +popup_base_attr_or(int row, int col, int fallback) +{ + int base = fallback; + + popup_get_base_screen_cell(row, col, NULL, &base, NULL); + return base; +} + +/* + * Blend "char_attr" through the cached opacity popup over "base_attr". + * "blend_fg" is TRUE when both fg and bg should blend (space cells), FALSE + * when only bg should blend so the popup fg is preserved (text cells). + */ + static inline int +popup_blend_with_base( + const popup_opacity_T *po, + int char_attr, + int base_attr, + int blend_fg) +{ + int combined = hl_combine_attr(po->popup_attr, char_attr); + + return hl_blend_attr(base_attr, combined, po->blend, blend_fg); +} + /* * For a double-wide character at a popup boundary with opacity:0 * (blend==100), the two cells may have different underlying attrs. @@ -543,6 +604,15 @@ screen_line( // 2: occupies two display cells bool override_success = push_highlight_overrides(wp->w_hl, wp->w_hl_len); +#ifdef FEAT_PROP_POPUP + popup_opacity_T po; // cached when drawing an opacity popup + int drawing_opacity_popup = + screen_opacity_popup != NULL + && (flags & SLF_POPUP); + CLEAR_FIELD(po); + if (drawing_opacity_popup) + popup_opacity_init(&po); +#endif // Check for illegal row and col, just in case. if (row >= Rows) @@ -659,128 +729,100 @@ screen_line( // For popup with opacity windows: if drawing a space, show the // underlying character with the popup's attributes blended in. int opacity_blank = FALSE; - // Check if the popup is drawing a space and the background is the - // second cell of a wide character. Skip drawing to preserve the - // wide character that was drawn in the previous cell. - if (screen_opacity_popup != NULL - && (flags & SLF_POPUP) + // Popup with opacity: when drawing a space, blend the popup attrs + // onto whatever is underneath instead of overwriting it. + if (drawing_opacity_popup && ScreenLines[off_from] == ' ' - && (!enc_utf8 || ScreenLinesUC[off_from] == 0) - && ScreenLines[off_to] == 0 - && (!enc_utf8 || ScreenLinesUC[off_to] == 0) - && off_to > 0 - && enc_utf8 && ScreenLinesUC[off_to - 1] != 0 - && utf_char2cells(ScreenLinesUC[off_to - 1]) == 2) + && (!enc_utf8 || ScreenLinesUC[off_from] == 0)) { - // This is the second cell of a wide character. Don't overwrite it. - opacity_blank = TRUE; - redraw_this = FALSE; - } - else if (screen_opacity_popup != NULL - && (flags & SLF_POPUP) - && ScreenLines[off_from] == ' ' - && (!enc_utf8 || ScreenLinesUC[off_from] == 0) - && (ScreenLines[off_to] != 0 - || (enc_utf8 && ScreenLinesUC[off_to] != 0))) - { - int bg_char_cells = 1; - if (enc_utf8 && ScreenLinesUC[off_to] != 0) - bg_char_cells = utf_char2cells(ScreenLinesUC[off_to]); + int popup_src_attr = ScreenAttrs[off_from]; + int bg_is_empty = ScreenLines[off_to] == 0 + && (!enc_utf8 || ScreenLinesUC[off_to] == 0); - // For wide background character, check if the next popup cell - // is also a space. If not, the wide char would be partially - // covered by a popup character, so don't show it. - if (bg_char_cells == 2) + // Case A: target cell is the second half of a wide char from a + // previous draw. Don't overwrite it. + if (bg_is_empty + && off_to > 0 + && enc_utf8 && ScreenLinesUC[off_to - 1] != 0 + && utf_char2cells(ScreenLinesUC[off_to - 1]) == 2) { - if (col + 1 >= endcol || off_from + 1 >= max_off_from - || off_to + 1 >= max_off_to) - { - // Wide char doesn't fit at the edge. Replace with a - // blended space so opacity is still applied. - int char_attr = ScreenAttrs[off_from]; - int popup_attr = get_win_attr(screen_opacity_popup); - int combined = hl_combine_attr(popup_attr, char_attr); - int blend = screen_opacity_popup->w_popup_blend; - ScreenLines[off_to] = ' '; - if (enc_utf8) - ScreenLinesUC[off_to] = 0; - int base_attr = ScreenAttrs[off_to]; - popup_get_base_screen_cell(row, col + coloff, - NULL, &base_attr, NULL); - ScreenAttrs[off_to] = hl_blend_attr(base_attr, - combined, blend, TRUE); - screen_char(off_to, row, col + coloff); - opacity_blank = TRUE; - redraw_this = FALSE; - goto skip_opacity; - } - int next_off_from = off_from + 1; - if (!(ScreenLines[next_off_from] == ' ' - && (!enc_utf8 || ScreenLinesUC[next_off_from] == 0))) - { - // Next cell is not a space, don't show the wide char. - goto skip_opacity; - } + opacity_blank = TRUE; + redraw_this = FALSE; } + // Case B: target cell holds a real character — blend popup attrs + // over it, preserving the underlying glyph. + else if (ScreenLines[off_to] != 0 + || (enc_utf8 && ScreenLinesUC[off_to] != 0)) + { + int bg_char_cells = (enc_utf8 && ScreenLinesUC[off_to] != 0) + ? utf_char2cells(ScreenLinesUC[off_to]) : 1; - opacity_blank = TRUE; - // Keep the underlying character and blend its foreground color - // from popup background color to original color. - // Combine the popup window color with the character's own - // attribute (e.g. match highlight) so that its background - // color is preserved on blank cells. - int char_attr = ScreenAttrs[off_from]; - int popup_attr = get_win_attr(screen_opacity_popup); - int combined = hl_combine_attr(popup_attr, char_attr); - int blend = screen_opacity_popup->w_popup_blend; - int base_attr = ScreenAttrs[off_to]; - popup_get_base_screen_cell(row, col + coloff, - NULL, &base_attr, NULL); - ScreenAttrs[off_to] = hl_blend_attr(base_attr, - combined, blend, TRUE); - screen_char(off_to, row, col + coloff); - // For wide background character, also update the second cell - // with its own base attr (it may be outside the popup area). - if (bg_char_cells == 2) - { - int base_attr2 = ScreenAttrs[off_to + 1]; - popup_get_base_screen_cell(row, col + coloff + 1, - NULL, &base_attr2, NULL); - ScreenAttrs[off_to + 1] = hl_blend_attr(base_attr2, - combined, blend, TRUE); - if (blend == 100) - resolve_wide_char_opacity_attrs(row, - col + coloff, col + coloff + 1, - &ScreenAttrs[off_to], &ScreenAttrs[off_to + 1]); + if (bg_char_cells == 2) + { + if (col + 1 >= endcol || off_from + 1 >= max_off_from + || off_to + 1 >= max_off_to) + { + // Wide char doesn't fit at the edge. Replace with a + // blended space so opacity is still applied. + int base_attr; + ScreenLines[off_to] = ' '; + if (enc_utf8) + ScreenLinesUC[off_to] = 0; + base_attr = popup_base_attr_or(row, col + coloff, + ScreenAttrs[off_to]); + ScreenAttrs[off_to] = popup_blend_with_base(&po, + popup_src_attr, base_attr, TRUE); + screen_char(off_to, row, col + coloff); + opacity_blank = TRUE; + redraw_this = FALSE; + goto skip_opacity; + } + // Wide bg char must be followed by a popup space, otherwise + // a popup glyph would corrupt its right half. + if (!(ScreenLines[off_from + 1] == ' ' + && (!enc_utf8 || ScreenLinesUC[off_from + 1] == 0))) + goto skip_opacity; + } + + // Keep the underlying character and blend the popup attrs over + // it. blend_fg=TRUE because we're drawing a space, so the + // foreground (the underlying glyph) should also blend. + opacity_blank = TRUE; + int base_attr = popup_base_attr_or(row, col + coloff, + ScreenAttrs[off_to]); + ScreenAttrs[off_to] = popup_blend_with_base(&po, + popup_src_attr, base_attr, TRUE); + screen_char(off_to, row, col + coloff); + // For wide bg char also blend the second cell; its base may be + // outside the popup area. + if (bg_char_cells == 2) + { + int base_attr2 = popup_base_attr_or(row, col + coloff + 1, + ScreenAttrs[off_to + 1]); + ScreenAttrs[off_to + 1] = popup_blend_with_base(&po, + popup_src_attr, base_attr2, TRUE); + if (po.blend == 100) + resolve_wide_char_opacity_attrs(row, + col + coloff, col + coloff + 1, + &ScreenAttrs[off_to], &ScreenAttrs[off_to + 1]); + } + redraw_this = FALSE; + } + // Case C: popup space overlaps the second half of a destroyed wide + // character. Blend so the cell matches its neighbors instead of + // appearing as a solid-colored gap. + else if (bg_is_empty) + { + int base_attr; + ScreenLines[off_to] = ' '; + base_attr = popup_base_attr_or(row, col + coloff, + ScreenAttrs[off_to]); + ScreenAttrs[off_to] = popup_blend_with_base(&po, + popup_src_attr, base_attr, TRUE); + screen_char(off_to, row, col + coloff); + opacity_blank = TRUE; + redraw_this = FALSE; } - redraw_this = FALSE; - } - // When a popup space overlaps the second half of a destroyed wide - // character (e.g., the first half was overwritten by popup content), - // the underlying cell has ScreenLines == 0 and no valid wide char - // at the previous cell. Apply opacity blending so that the cell - // matches surrounding opacity-blended cells instead of appearing - // as a solid-colored gap. - else if (screen_opacity_popup != NULL - && (flags & SLF_POPUP) - && ScreenLines[off_from] == ' ' - && (!enc_utf8 || ScreenLinesUC[off_from] == 0) - && ScreenLines[off_to] == 0 - && (!enc_utf8 || ScreenLinesUC[off_to] == 0)) - { - int char_attr = ScreenAttrs[off_from]; - int popup_attr = get_win_attr(screen_opacity_popup); - int combined = hl_combine_attr(popup_attr, char_attr); - int blend = screen_opacity_popup->w_popup_blend; - ScreenLines[off_to] = ' '; - int base_attr = ScreenAttrs[off_to]; - popup_get_base_screen_cell(row, col + coloff, - NULL, &base_attr, NULL); - ScreenAttrs[off_to] = hl_blend_attr(base_attr, - combined, blend, TRUE); - screen_char(off_to, row, col + coloff); - opacity_blank = TRUE; - redraw_this = FALSE; } skip_opacity: #endif @@ -936,40 +978,37 @@ skip_opacity: ScreenAttrs[off_to] = ScreenAttrs[off_from]; #ifdef FEAT_PROP_POPUP - // For popup with opacity text: blend background with underlying. - if (screen_opacity_popup != NULL - && (flags & SLF_POPUP) - && screen_opacity_popup->w_popup_blend > 0) + // For popup with opacity text: blend popup attrs over the underlying + // base. blend_fg=FALSE so the popup foreground (the real glyph) is + // preserved while only the background blends. + if (drawing_opacity_popup && po.blend > 0) { - int char_attr = ScreenAttrs[off_from]; - int popup_attr = get_win_attr(screen_opacity_popup); - int blend = screen_opacity_popup->w_popup_blend; - int combined = hl_combine_attr(popup_attr, char_attr); - int underlying_attr = 0; + int popup_src_attr = ScreenAttrs[off_from]; + int scol1 = col + coloff; + int base1 = popup_base_attr_or(row, scol1, 0); - popup_get_base_screen_cell(row, col + coloff, - NULL, &underlying_attr, NULL); - ScreenAttrs[off_to] = hl_blend_attr(underlying_attr, - combined, blend, FALSE); - - // For double-wide characters, the second cell may have a - // different underlying attr (e.g. at popup boundary), - // so blend it independently. if (char_cells == 2) { - int underlying_attr2 = 0; + int base2 = popup_base_attr_or(row, scol1 + 1, 0); - popup_get_base_screen_cell(row, col + coloff + 1, - NULL, &underlying_attr2, NULL); - ScreenAttrs[off_to + 1] = hl_blend_attr( - underlying_attr2, combined, blend, - FALSE); - if (blend == 100) - resolve_wide_char_opacity_attrs(row, - col + coloff, col + coloff + 1, - &ScreenAttrs[off_to], - &ScreenAttrs[off_to + 1]); + // Terminals can't render different bg colors for the two + // halves of a wide char. If one half is over a lower + // opacity popup and the other isn't, use the non-popup + // side for both halves to avoid color leaking. + int over1 = popup_is_over_opacity(row, scol1); + int over2 = popup_is_over_opacity(row, scol1 + 1); + if (over1 != over2) + { + if (over1) + base1 = base2; + else + base2 = base1; + } + ScreenAttrs[off_to + 1] = popup_blend_with_base(&po, + popup_src_attr, base2, FALSE); } + ScreenAttrs[off_to] = popup_blend_with_base(&po, + popup_src_attr, base1, FALSE); } else #endif @@ -1127,7 +1166,7 @@ skip_opacity: { int c; - c = fillchar_vsep(&hl, wp); + c = fillchar_vsep(&hl, wp, row); if (ScreenLines[off_to] != (schar_T)c || (enc_utf8 && (int)ScreenLinesUC[off_to] != (c >= 0x80 ? c : 0)) @@ -1178,21 +1217,44 @@ rl_mirror(char_u *str) #endif /* - * Draw the verticap separator right of window "wp" starting with line "row". + * Draw the vertical separator right of window "wp" starting with line "row". + * Includes status line rows so the VertSplit/VertSplitNC highlight is + * refreshed after a current window change even for non-current windows + * whose status lines are not redrawn. */ void draw_vsep_win(win_T *wp, int row) { - int hl; - int c; - if (!wp->w_vsep_width) return; - // draw the vertical separator right of this window - c = fillchar_vsep(&hl, wp); - screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height, - W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl); + int content_end = W_WINROW(wp) + wp->w_height; + + // Content rows: VertSplit/VertSplitNC based on adjacency. Include the + // WinBar row (above the content) when redrawing from the top so that + // the separator highlight is updated on current-window changes. + int start_row = (row == 0) ? wp->w_winrow : W_WINROW(wp) + row; + for (int r = start_row; r < content_end; ++r) + { + int hl; + int c = fillchar_vsep(&hl, wp, r); + screen_fill(r, r + 1, W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl); + } + + // Status line rows: when the status line is connected with the right + // neighbour the separator cell is the status line fillchar; otherwise + // it is the vsep char. + if (wp->w_status_height != 0) + { + int hl; + int c; + if (stl_connected(wp)) + c = fillchar_status(&hl, wp); + else + c = fillchar_vsep(&hl, wp, content_end); + for (int r = content_end; r < content_end + wp->w_status_height; ++r) + screen_fill(r, r + 1, W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl); + } } /* @@ -1304,6 +1366,7 @@ win_redr_custom( int opt_scope = 0; stl_hlrec_T *hltab; stl_hlrec_T *tabtab; + stl_clickrec_T *clicktab; win_T *ewp; int p_crb_save; bool override_success = false; @@ -1397,6 +1460,37 @@ win_redr_custom( char_u *stl_tmp = (stl == NULL) ? (char_u *)"" : stl; int col_save = col; + // Determine where click regions for this draw will be stored, and reset + // the destination so each row in the loop below can append. This must + // be done before the loop because for a multi-line statusline each row + // contributes its own click regions. + stl_click_region_T **out_regions = NULL; + int *out_count = NULL; + int region_base_col = 0; + if (!draw_ruler) + { + if (wp != NULL) + { + out_regions = &wp->w_stl_click; + out_count = &wp->w_stl_click_count; + region_base_col = wp->w_wincol; + } + else + { + // 'tabline': store regions in global state since there is no + // associated window. + out_regions = &tabline_stl_click; + out_count = &tabline_stl_click_count; + region_base_col = firstwin->w_wincol; + } + + for (n = 0; n < *out_count; n++) + vim_free((*out_regions)[n].funcname); + VIM_CLEAR(*out_regions); + *out_count = 0; + } + + int carry_hl = 0; for (int i = 0; i < stlh_cnt; i++) { col = col_save; @@ -1404,7 +1498,9 @@ win_redr_custom( width = build_stl_str_hl_mline(ewp, buf, sizeof(buf), &stl_tmp, opt_name, opt_scope, - fillchar, maxwidth, &hltab, &tabtab); + fillchar, maxwidth, &hltab, &tabtab, + &clicktab, + &carry_hl); // Make all characters printable. p = transstr(buf); @@ -1454,6 +1550,76 @@ win_redr_custom( curattr = highlight_user[hltab[n].userhl - 1]; } screen_puts(p, row + i, col, curattr); + + // Append click regions for this row. clicktab reflects the line + // just rendered, so each row of a multi-line statusline contributes + // its own regions. + if (out_regions != NULL) + { + int click_count = 0; + for (n = 0; clicktab[n].start != NULL; n++) + click_count++; + + if (click_count > 0) + { + stl_click_region_T *new_arr = vim_realloc(*out_regions, + sizeof(stl_click_region_T) + * (*out_count + click_count)); + if (new_arr != NULL) + { + char_u *cur_funcname = NULL; + int cur_minwid = 0; + int region_start = region_base_col; + + *out_regions = new_arr; + + len = 0; + p = buf; + for (n = 0; clicktab[n].start != NULL; n++) + { + len += vim_strnsize(p, + (int)(clicktab[n].start - p)); + p = clicktab[n].start; + + if (cur_funcname != NULL) + { + stl_click_region_T *r = + &(*out_regions)[*out_count]; + r->row = row + i; + r->col_start = region_start; + r->col_end = region_base_col + len; + r->funcname = vim_strsave(cur_funcname); + r->minwid = cur_minwid; + r->tabnr = 0; + (*out_count)++; + } + + cur_funcname = clicktab[n].funcname; + cur_minwid = clicktab[n].minwid; + region_start = region_base_col + len; + } + + // Close final region if it extends to the end. + if (cur_funcname != NULL) + { + stl_click_region_T *r = + &(*out_regions)[*out_count]; + r->row = row + i; + r->col_start = region_start; + r->col_end = region_base_col + maxwidth; + r->funcname = vim_strsave(cur_funcname); + r->minwid = cur_minwid; + r->tabnr = 0; + (*out_count)++; + } + } + } + } + + // Free the funcname strings allocated by build_stl_str_hl_local() + // for this line. They have been copied into the region array above. + for (n = 0; clicktab[n].start != NULL; n++) + vim_free(clicktab[n].funcname); } ewp->w_p_crb = p_crb_save; @@ -1707,6 +1873,21 @@ screen_puts_len( force_redraw_this = force_redraw_next; force_redraw_next = FALSE; + // When drawing pum text with opacity, blend the popup bg with the + // saved underlying bg so text cells match the padding cells that + // use hl_pum_blend_attr. Without this, popup text appears on a + // solid bg while padding shows a blended bg, creating a visible + // seam. + int cell_attr = attr; + if (screen_pum_blend > 0 && pum_bg_attrs != NULL + && row >= pum_bg_top && row < pum_bg_bot + && col < pum_bg_cols) + { + int soff = (row - pum_bg_top) * pum_bg_cols + col; + cell_attr = hl_blend_attr(pum_bg_attrs[soff], attr, + screen_pum_blend, FALSE); + } + need_redraw = ScreenLines[off] != c || (mbyte_cells == 2 && ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0)) @@ -1718,7 +1899,7 @@ screen_puts_len( (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c) || (ScreenLinesUC[off] != 0 && screen_comp_differs(off, u8cc)))) - || ScreenAttrs[off] != attr + || ScreenAttrs[off] != cell_attr || exmode_active; if ((need_redraw || force_redraw_this) && !skip_for_popup(row, col)) @@ -1783,7 +1964,7 @@ screen_puts_len( && (*mb_off2cells)(off + 1, max_off) > 1))) ScreenLines[off + mbyte_blen] = 0; ScreenLines[off] = c; - ScreenAttrs[off] = attr; + ScreenAttrs[off] = cell_attr; ScreenCols[off] = -1; if (enc_utf8) { @@ -1804,7 +1985,10 @@ screen_puts_len( if (mbyte_cells == 2) { ScreenLines[off + 1] = 0; - ScreenAttrs[off + 1] = attr; + ScreenLinesUC[off + 1] = 0; + for (int ci = 0; ci < Screen_mco; ++ci) + ScreenLinesC[ci][off + 1] = 0; + ScreenAttrs[off + 1] = cell_attr; ScreenCols[off + 1] = -1; } screen_char(off, row, col); @@ -1812,7 +1996,7 @@ screen_puts_len( else if (mbyte_cells == 2) { ScreenLines[off + 1] = ptr[1]; - ScreenAttrs[off + 1] = attr; + ScreenAttrs[off + 1] = cell_attr; ScreenCols[off + 1] = -1; screen_char_2(off, row, col); } @@ -2263,11 +2447,28 @@ screen_char(unsigned off, int row, int col) // output the final blended result. // Also suppress if this is a wide character whose second cell // is under an opacity popup. - if (popup_is_under_opacity(row, col) - || (enc_utf8 && ScreenLinesUC[off] != 0 + if (popup_is_under_opacity(row, col)) + { + // If this is a wide character whose left half is under an opacity + // popup but right half is not, clear the right half so the old + // blended value doesn't remain as a ghost after popup_move(). + if (enc_utf8 && ScreenLinesUC[off] != 0 && utf_char2cells(ScreenLinesUC[off]) == 2 && col + 1 < screen_Columns - && popup_is_under_opacity(row, col + 1))) + && !popup_is_under_opacity(row, col + 1)) + { + int off2 = off + 1; + ScreenLines[off2] = ' '; + ScreenLinesUC[off2] = 0; + screen_char(off2, row, col + 1); + } + screen_cur_col = 9999; + return; + } + if (enc_utf8 && ScreenLinesUC[off] != 0 + && utf_char2cells(ScreenLinesUC[off]) == 2 + && col + 1 < screen_Columns + && popup_is_under_opacity(row, col + 1)) { screen_cur_col = 9999; return; @@ -2688,8 +2889,58 @@ skip_opacity_fill: && col < pum_bg_cols) { int soff = (row - pum_bg_top) * pum_bg_cols + col; + + // Skip the trailing cell of a wide background char: its + // leading cell already emitted the full wide glyph via + // screen_char(); drawing here would clobber the right half. + // Only applies when the previous cell was actually processed + // in this fill range -- if the fill starts here (col == + // start_col), the "wide lead" is outside our range (e.g., + // popup text wrote a narrow cell there), so we fall through + // to the regular blend path which renders a blended space. + if (enc_utf8 && pum_bg_linesUC != NULL + && col > start_col + && pum_bg_linesUC[soff] == 0 + && pum_bg_linesUC[soff - 1] != 0 + && utf_char2cells(pum_bg_linesUC[soff - 1]) == 2) + { + ScreenLines[off] = 0; + if (ScreenLinesUC != NULL) + ScreenLinesUC[off] = 0; + ScreenAttrs[off] = ScreenAttrs[off - 1]; + goto next_col; + } + int underlying_attr = pum_bg_attrs[soff]; + // If restoring the leading cell of a wide background char + // would extend past the end of the fill range (e.g. into a + // popup border cell on the right edge), render a blended + // space instead so the border at col+1 is preserved. + // Likewise, if this cell is the trailing half of a wide + // background char whose leading cell is outside the fill + // range (e.g., popup text wrote a narrow cell there), + // restoring the trailing alone would emit a stray NUL. + if (enc_utf8 && pum_bg_linesUC != NULL + && ((pum_bg_linesUC[soff] != 0 + && utf_char2cells(pum_bg_linesUC[soff]) == 2 + && col + 1 >= end_col) + || (col == start_col + && pum_bg_linesUC[soff] == 0 + && col > 0 + && pum_bg_linesUC[soff - 1] != 0 + && utf_char2cells(pum_bg_linesUC[soff - 1]) + == 2))) + { + ScreenLines[off] = ' '; + if (ScreenLinesUC != NULL) + ScreenLinesUC[off] = 0; + ScreenAttrs[off] = hl_pum_blend_attr(underlying_attr, + attr, screen_pum_blend); + screen_char(off, row, col); + goto next_col; + } + // Restore underlying character so text shows through. ScreenLines[off] = pum_bg_lines[soff]; if (enc_utf8 && pum_bg_linesUC != NULL @@ -3775,7 +4026,7 @@ win_ins_lines( */ if (!did_delete) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; redraw_cmdline = TRUE; nextrow = W_WINROW(wp) + wp->w_height + wp->w_status_height; lastrow = nextrow + line_count; @@ -3791,7 +4042,7 @@ win_ins_lines( // deletion will have messed up other windows if (did_delete) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; win_rest_invalid(W_NEXT(wp)); } return FAIL; @@ -3841,7 +4092,7 @@ win_del_lines( if (screen_ins_lines(0, W_WINROW(wp) + wp->w_height - line_count, line_count, (int)Rows, clear_attr, NULL) == FAIL) { - wp->w_redr_status = TRUE; + wp->w_redr_status = true; win_rest_invalid(wp->w_next); } } @@ -3957,7 +4208,7 @@ win_rest_invalid(win_T *wp) while (wp != NULL) { redraw_win_later(wp, UPD_NOT_VALID); - wp->w_redr_status = TRUE; + wp->w_redr_status = true; wp = wp->w_next; } redraw_cmdline = TRUE; @@ -5031,16 +5282,43 @@ fillchar_status(int *attr, win_T *wp) return fill; } +/* + * Return true if the vertical separator of "wp" at screen row "row" is + * adjacent to the current window. The separator is owned by "wp" and drawn + * at its right edge. + */ + static bool +vsep_row_is_curwin(win_T *wp, int row) +{ + if (wp == curwin) + return true; + + // Check if curwin is immediately to the right of wp's separator and + // "row" is within curwin's row range (winbar + content + status line). + if (curwin->w_wincol == W_ENDCOL(wp) + wp->w_vsep_width + && row >= curwin->w_winrow + && row < W_WINROW(curwin) + curwin->w_height + + curwin->w_status_height) + return true; + + return false; +} + /* * Get the character to use in a separator between vertically split windows. * Get its attributes in "*attr". + * Use VertSplit when the separator is adjacent to the current window, + * VertSplitNC otherwise. */ int -fillchar_vsep(int *attr, win_T *wp) +fillchar_vsep(int *attr, win_T *wp, int row) { bool override_success = push_highlight_overrides(wp->w_hl, wp->w_hl_len); - *attr = HL_ATTR(HLF_C); + if (vsep_row_is_curwin(wp, row)) + *attr = HL_ATTR(HLF_C); + else + *attr = HL_ATTR(HLF_CNC); if (override_success) pop_highlight_overrides(); diff --git a/src/scriptfile.c b/src/scriptfile.c index df90fe7711..d0735ffe44 100644 --- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -199,12 +199,10 @@ estack_sfile(estack_arg_T which UNUSED) switch (entry->es_type) { case ETYPE_SCRIPT: - type_name.string = (char_u *)"script "; - type_name.length = 7; + STR_LITERAL_SET(type_name, "script "); break; case ETYPE_UFUNC: - type_name.string = (char_u *)"function "; - type_name.length = 9; + STR_LITERAL_SET(type_name, "function "); break; default: break; diff --git a/src/search.c b/src/search.c index dceffd6113..d7a0299abc 100644 --- a/src/search.c +++ b/src/search.c @@ -1225,6 +1225,109 @@ first_submatch(regmmatch_T *rp) } #endif +/* + * Parse a search pattern followed by an optional offset (e.g. "pat/e+1"). + * On entry "*pat" points at the start of the pattern and "*patlen" is its + * length. Updates the in/out parameters: + * *pat / *patlen - moved past the pattern and offset + * *strcopy - allocated copy if "\?" or "\/" was unescaped + * (caller must vim_free() it) + * *searchstr and *searchstrlen - pointer/length of the search pattern only + * *dircp - location of the trailing delimiter that was + * replaced with NUL (or NULL); caller may restore + * it + * *offset - parsed offset (line/end/off) + * + * Returns the length of the parsed pattern + offset (used by get_address() + * to know how much of the command line was consumed). + */ + int +parse_search_pattern_offset( + char_u **pat, + size_t *patlen, + int search_delim, + int options, + char_u **strcopy, + char_u **searchstr, + size_t *searchstrlen, + char_u **dircp, + soffset_T *offset) +{ + int cmdlen = 0; + char_u *p; + char_u *ps; + + if (*pat == NULL || **pat == NUL) + return 0; + + ps = *strcopy; + *searchstr = *pat; + *searchstrlen = *patlen; + *dircp = NULL; + + /* + * Find end of regular expression. + * If there is a matching '/' or '?', toss it. + */ + p = skip_regexp_ex(*pat, search_delim, magic_isset(), + strcopy, NULL, NULL); + if (*strcopy != ps) + { + size_t len = STRLEN(*strcopy); + // made a copy of "pat" to change "\?" to "?" + cmdlen += (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; + } + + offset->line = FALSE; + offset->end = FALSE; + offset->off = 0; + /* + * Check for a line offset or a character offset. + * For get_address (echo off) we don't check for a character + * offset, because it is meaningless and the 's' could be a + * substitute command. + */ + if (*p == '+' || *p == '-' || VIM_ISDIGIT(*p)) + offset->line = TRUE; + else if ((options & SEARCH_OPT) + && (*p == 'e' || *p == 's' || *p == 'b')) + { + if (*p == 'e') // end + offset->end = SEARCH_END; + ++p; + } + if (VIM_ISDIGIT(*p) || *p == '+' || *p == '-') // got an offset + { + // 'nr' or '+nr' or '-nr' + if (VIM_ISDIGIT(*p) || VIM_ISDIGIT(*(p + 1))) + offset->off = atol((char *)p); + else if (*p == '-') // single '-' + offset->off = -1; + else // single '+' + offset->off = 1; + ++p; + while (VIM_ISDIGIT(*p)) // skip number + ++p; + } + + // compute length of search command for get_address() + cmdlen += (int)(p - *pat); + *patlen -= p - *pat; + *pat = p; // put pat after search command + + return cmdlen; +} + /* * Highest level string search function. * Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc' @@ -1267,7 +1370,6 @@ do_search( long c; char_u *dircp; char_u *strcopy = NULL; - char_u *ps; int show_search_stats; char_u *msgbuf = NULL; size_t msgbuflen = 0; @@ -1379,66 +1481,9 @@ do_search( if (pat != NULL && *pat != NUL) // look for (new) offset { - /* - * Find end of regular expression. - * If there is a matching '/' or '?', toss it. - */ - ps = strcopy; - p = skip_regexp_ex(pat, search_delim, magic_isset(), - &strcopy, NULL, NULL); - if (strcopy != ps) - { - size_t len = STRLEN(strcopy); - // made a copy of "pat" to change "\?" to "?" - 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; - } - spats[0].off.line = FALSE; - spats[0].off.end = FALSE; - spats[0].off.off = 0; - /* - * Check for a line offset or a character offset. - * For get_address (echo off) we don't check for a character - * offset, because it is meaningless and the 's' could be a - * substitute command. - */ - if (*p == '+' || *p == '-' || VIM_ISDIGIT(*p)) - spats[0].off.line = TRUE; - else if ((options & SEARCH_OPT) - && (*p == 'e' || *p == 's' || *p == 'b')) - { - if (*p == 'e') // end - spats[0].off.end = SEARCH_END; - ++p; - } - if (VIM_ISDIGIT(*p) || *p == '+' || *p == '-') // got an offset - { - // 'nr' or '+nr' or '-nr' - if (VIM_ISDIGIT(*p) || VIM_ISDIGIT(*(p + 1))) - spats[0].off.off = atol((char *)p); - else if (*p == '-') // single '-' - spats[0].off.off = -1; - else // single '+' - spats[0].off.off = 1; - ++p; - while (VIM_ISDIGIT(*p)) // skip number - ++p; - } - - // compute length of search command for get_address() - searchcmdlen += (int)(p - pat); - - patlen -= p - pat; - pat = p; // put pat after search command + searchcmdlen += parse_search_pattern_offset(&pat, &patlen, + search_delim, options, &strcopy, &searchstr, + &searchstrlen, &dircp, &spats[0].off); } show_search_stats = FALSE; @@ -1723,7 +1768,7 @@ do_search( if (options & SEARCH_MARK) setpcmark(); curwin->w_cursor = pos; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; end_do_search: if ((options & SEARCH_KEEP) || (cmdmod.cmod_flags & CMOD_KEEPPATTERNS)) @@ -2130,7 +2175,7 @@ find_mps_values( * flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#') * FM_FORWARD search forwards (when initc is '/', '*' or '#') * FM_BLOCKSTOP stop at start/end of block ({ or } in column 0) - * FM_SKIPCOMM skip comments (not implemented yet!) + * FM_SKIPCOMM skip over comments (cursor must start outside a block comment) * * "oap" is only used to set oap->motion_type for a linewise motion, it can be * NULL @@ -2166,6 +2211,8 @@ findmatchlimit( int comment_col = MAXCOL; // start of / / comment int lispcomm = FALSE; // inside of Lisp-style comment int lisp = curbuf->b_p_lisp; // engage Lisp-specific hacks ;) + int skip_comments = (flags & FM_SKIPCOMM) != 0; + int in_block_comment = FALSE; // inside /* */ block comment pos = curwin->w_cursor; pos.coladd = 0; @@ -2394,10 +2441,14 @@ findmatchlimit( CLEAR_POS(&match_pos); // backward search: Check if this line contains a single-line comment - if ((backwards && comment_dir) || lisp) + if ((backwards && comment_dir) || lisp || skip_comments) comment_col = check_linecomment(linep); if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) lispcomm = TRUE; // find match inside this comment + // skip // comment portion at starting position + if (skip_comments && !in_block_comment && comment_col != MAXCOL + && backwards && pos.col > (colnr_T)comment_col) + pos.col = comment_col; while (!got_int) { @@ -2425,11 +2476,15 @@ findmatchlimit( line_breakcheck(); // Check if this line contains a single-line comment - if (comment_dir || lisp) + if (comment_dir || lisp || skip_comments) comment_col = check_linecomment(linep); // skip comment if (lisp && comment_col != MAXCOL) pos.col = comment_col; + else if (skip_comments && !in_block_comment + && comment_col != MAXCOL + && pos.col > (colnr_T)comment_col) + pos.col = comment_col; } else { @@ -2460,7 +2515,7 @@ findmatchlimit( pos.col = 0; do_quotes = -1; line_breakcheck(); - if (lisp) // find comment pos in new line + if (lisp || skip_comments) // find comment pos in new line comment_col = check_linecomment(linep); } else @@ -2472,6 +2527,37 @@ findmatchlimit( } } + // Track block comment state when FM_SKIPCOMM is set. + // Backward: '/' of end-marker enters comment; '*' of start-marker exits. + // Forward: '/' of start-marker enters comment; '/' of end-marker exits. + if (skip_comments && !comment_dir) + { + if (backwards) + { + // Guard pos.col < comment_col: don't misread '*/' at the '//' + // position as a block-comment end-marker. + if (!in_block_comment && pos.col > 0 + && linep[pos.col - 1] == '*' && linep[pos.col] == '/' + && (comment_col == MAXCOL || (int)pos.col < comment_col)) + in_block_comment = TRUE; + else if (in_block_comment && pos.col > 0 + && linep[pos.col - 1] == '/' && linep[pos.col] == '*') + in_block_comment = FALSE; + } + else + { + // Guard pos.col < comment_col: don't treat '/*' inside a '//' + // comment as a block-comment start-marker. + if (!in_block_comment && linep[pos.col] == '/' + && linep[pos.col + 1] == '*' + && (comment_col == MAXCOL || (int)pos.col < comment_col)) + in_block_comment = TRUE; + else if (in_block_comment && pos.col > 0 + && linep[pos.col - 1] == '*' && linep[pos.col] == '/') + in_block_comment = FALSE; + } + } + /* * If FM_BLOCKSTOP given, stop at a '{' or '}' in column 0. */ @@ -2715,6 +2801,11 @@ findmatchlimit( && check_prevcol(linep, pos.col - 1, '#', NULL)) break; + // Skip matches inside comments when FM_SKIPCOMM is set. + if (skip_comments && (in_block_comment + || (comment_col != MAXCOL && (int)pos.col >= comment_col))) + break; + // Check for match outside of quotes, and inside of // quotes when the start is also inside of quotes. if ((!inquote || start_in_quotes == TRUE) @@ -3968,7 +4059,7 @@ search_line: if (action != ACTION_SHOW) { curwin->w_cursor.col = (colnr_T)(startp - line); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } # if defined(FEAT_QUICKFIX) diff --git a/src/session.c b/src/session.c index 94b0640abf..17537cff15 100644 --- a/src/session.c +++ b/src/session.c @@ -105,7 +105,7 @@ ses_arglist( if (fputs(cmd, fd) < 0 || put_eol(fd) == FAIL) return FAIL; - if (put_line(fd, "%argdel") == FAIL) + if (put_line(fd, ":%argdel") == FAIL) return FAIL; for (i = 0; i < gap->ga_len; ++i) { @@ -122,7 +122,7 @@ ses_arglist( s = buf; } } - if (fputs("$argadd ", fd) < 0 + if (fputs(":$argadd ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL || put_eol(fd) == FAIL) { @@ -220,7 +220,7 @@ ses_win_rec(FILE *fd, frame_T *fr) // Go back to the first window. if (count > 0 && (fprintf(fd, fr->fr_layout == FR_COL - ? "%dwincmd k" : "%dwincmd h", count) < 0 + ? ":%dwincmd k" : ":%dwincmd h", count) < 0 || put_eol(fd) == FAIL)) return FAIL; @@ -259,14 +259,14 @@ ses_winsizes( // restore height when not full height if (wp->w_height + wp->w_status_height < topframe->fr_height && (fprintf(fd, - "exe '%dresize ' . ((&lines * %ld + %ld) / %ld)", + "exe ':%dresize ' .. ((&lines * %ld + %ld) / %ld)", n, (long)wp->w_height, Rows / 2, Rows) < 0 || put_eol(fd) == FAIL)) return FAIL; // restore width when not full width if (wp->w_width < Columns && (fprintf(fd, - "exe 'vert %dresize ' . ((&columns * %ld + %ld) / %ld)", + "exe 'vert :%dresize ' .. ((&columns * %ld + %ld) / %ld)", n, (long)wp->w_width, Columns / 2, Columns) < 0 || put_eol(fd) == FAIL)) return FAIL; @@ -339,7 +339,7 @@ put_view( if (wp->w_arg_idx != current_arg_idx && wp->w_arg_idx < WARGCOUNT(wp) && flagp == &ssop_flags) { - if (fprintf(fd, "%ldargu", (long)wp->w_arg_idx + 1) < 0 + if (fprintf(fd, ":%ldargu", (long)wp->w_arg_idx + 1) < 0 || put_eol(fd) == FAIL) return FAIL; did_next = TRUE; @@ -469,29 +469,32 @@ put_view( // Restore the cursor line in the file and relatively in the // window. Don't use "G", it changes the jumplist. + if (put_line(fd, "{") == FAIL) + return FAIL; + if (wp->w_height <= 0) { - if (fprintf(fd, "let s:l = %ld", (long)wp->w_cursor.lnum) < 0) + if (fprintf(fd, " var l: number = %ld", (long)wp->w_cursor.lnum) < 0) return FAIL; } else if (fprintf(fd, - "let s:l = %ld - ((%ld * winheight(0) + %ld) / %ld)", + " var l: number = %ld - ((%ld * winheight(0) + %ld) / %ld)", (long)wp->w_cursor.lnum, (long)(wp->w_cursor.lnum - wp->w_topline), (long)wp->w_height / 2, (long)wp->w_height) < 0) return FAIL; if (put_eol(fd) == FAIL - || put_line(fd, "if s:l < 1 | let s:l = 1 | endif") == FAIL - || put_line(fd, "keepjumps exe s:l") == FAIL - || put_line(fd, "normal! zt") == FAIL - || fprintf(fd, "keepjumps %ld", (long)wp->w_cursor.lnum) < 0 + || put_line(fd, " if l < 1 | l = 1 | endif") == FAIL + || put_line(fd, " keepjumps exe \":\" .. l") == FAIL + || put_line(fd, " normal! zt") == FAIL + || fprintf(fd, " keepjumps :%ld", (long)wp->w_cursor.lnum) < 0 || put_eol(fd) == FAIL) return FAIL; // Restore the cursor column and left offset when not wrapping. if (wp->w_cursor.col == 0) { - if (put_line(fd, "normal! 0") == FAIL) + if (put_line(fd, " normal! 0") == FAIL) return FAIL; } else @@ -499,24 +502,27 @@ put_view( if (!wp->w_p_wrap && wp->w_leftcol > 0 && wp->w_width > 0) { if (fprintf(fd, - "let s:c = %ld - ((%ld * winwidth(0) + %ld) / %ld)", + " var c: number = %ld - ((%ld * winwidth(0) + %ld) / %ld)", (long)wp->w_virtcol + 1, (long)(wp->w_virtcol - wp->w_leftcol), (long)wp->w_width / 2, (long)wp->w_width) < 0 || put_eol(fd) == FAIL - || put_line(fd, "if s:c > 0") == FAIL + || put_line(fd, " if c > 0") == FAIL || fprintf(fd, - " exe 'normal! ' . s:c . '|zs' . %ld . '|'", + " exe 'normal! ' .. c .. '|zs' .. %ld .. '|'", (long)wp->w_virtcol + 1) < 0 || put_eol(fd) == FAIL - || put_line(fd, "else") == FAIL - || put_view_curpos(fd, wp, " ") == FAIL - || put_line(fd, "endif") == FAIL) + || put_line(fd, " else") == FAIL + || put_view_curpos(fd, wp, " ") == FAIL + || put_line(fd, " endif") == FAIL) return FAIL; } - else if (put_view_curpos(fd, wp, "") == FAIL) + else if (put_view_curpos(fd, wp, " ") == FAIL) return FAIL; } + + if (put_line(fd, "}") == FAIL) + return FAIL; } // Local directory, if the current flag is not view options or the "curdir" @@ -566,7 +572,7 @@ store_session_globals(FILE *fd) *t = 'n'; else if (*t == '\r') *t = 'r'; - if ((fprintf(fd, "let %s = %c%s%c", + if ((fprintf(fd, "g:%s = %c%s%c", this_var->di_key, (this_var->di_tv.v_type == VAR_STRING) ? '"' : ' ', @@ -591,7 +597,7 @@ store_session_globals(FILE *fd) f = -f; sign = '-'; } - if ((fprintf(fd, "let %s = %c%f", + if ((fprintf(fd, "g:%s = %c%f", this_var->di_key, sign, f) < 0) || put_eol(fd) == FAIL) return FAIL; @@ -638,12 +644,21 @@ makeopens( // Begin by setting the this_session variable, and then other // sessionable variables. # ifdef FEAT_EVAL - if (put_line(fd, "let v:this_session=expand(\":p\")") == FAIL) + + if (put_line(fd, "v:this_session = expand(\":p\")") == FAIL) goto fail; if (put_line(fd, "doautoall SessionLoadPre") == FAIL) goto fail; + if (put_line(fd, "var save_splitbelow: bool") == FAIL + || put_line(fd, "var save_splitright: bool") == FAIL + || put_line(fd, "var save_winminheight: number") == FAIL + || put_line(fd, "var save_winminwidth: number") == FAIL + || put_line(fd, "var wipebuf: number = -1") == FAIL + || put_line(fd, "var shortmess_save: string") == FAIL) + goto fail; + if (ssop_flags & SSOP_GLOBALS) if (store_session_globals(fd) == FAIL) goto fail; @@ -659,7 +674,7 @@ makeopens( // Now a :cd command to the session directory or the current directory if (ssop_flags & SSOP_SESDIR) { - if (put_line(fd, "exe \"cd \" . escape(expand(\":p:h\"), ' ')") + if (put_line(fd, "exe \"cd \" .. escape(expand(\":p:h\"), ' ')") == FAIL) goto fail; } @@ -681,14 +696,14 @@ makeopens( // Remember the buffer number. if (put_line(fd, "if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''") == FAIL) goto fail; - if (put_line(fd, " let s:wipebuf = bufnr('%')") == FAIL) + if (put_line(fd, " wipebuf = bufnr('%')") == FAIL) goto fail; if (put_line(fd, "endif") == FAIL) goto fail; // Save 'shortmess' if not storing options. if ((ssop_flags & SSOP_OPTIONS) == 0 - && put_line(fd, "let s:shortmess_save = &shortmess") == FAIL) + && put_line(fd, "shortmess_save = &shortmess") == FAIL) goto fail; // Set 'shortmess' for the following. @@ -842,16 +857,16 @@ makeopens( if (tab_topframe->fr_layout != FR_LEAF) { // Save current window layout. - if (put_line(fd, "let s:save_splitbelow = &splitbelow") == FAIL - || put_line(fd, "let s:save_splitright = &splitright") + if (put_line(fd, "save_splitbelow = &splitbelow") == FAIL + || put_line(fd, "save_splitright = &splitright") == FAIL) goto fail; if (put_line(fd, "set splitbelow splitright") == FAIL) goto fail; if (ses_win_rec(fd, tab_topframe) == FAIL) goto fail; - if (put_line(fd, "let &splitbelow = s:save_splitbelow") == FAIL - || put_line(fd, "let &splitright = s:save_splitright") + if (put_line(fd, "&splitbelow = save_splitbelow") == FAIL + || put_line(fd, "&splitright = save_splitright") == FAIL) goto fail; } @@ -882,8 +897,8 @@ makeopens( // cursor can be set. This is done again below. // winminheight and winminwidth need to be set to avoid an error if // the user has set winheight or winwidth. - if (put_line(fd, "let s:save_winminheight = &winminheight") == FAIL - || put_line(fd, "let s:save_winminwidth = &winminwidth") + if (put_line(fd, "save_winminheight = &winminheight") == FAIL + || put_line(fd, "save_winminwidth = &winminwidth") == FAIL) goto fail; if (put_line(fd, "set winminheight=0") == FAIL @@ -933,7 +948,7 @@ makeopens( cur_arg_idx = next_arg_idx; // Restore cursor to the current window if it's not the first one. - if (cnr > 1 && (fprintf(fd, "%dwincmd w", cnr) < 0 + if (cnr > 1 && (fprintf(fd, ":%dwincmd w", cnr) < 0 || put_eol(fd) == FAIL)) goto fail; @@ -958,15 +973,13 @@ makeopens( goto fail; // Wipe out an empty unnamed buffer we started in. - if (put_line(fd, "if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0") + if (put_line(fd, "if wipebuf != -1 && len(win_findbuf(wipebuf)) == 0") == FAIL) goto fail; - if (put_line(fd, " silent exe 'bwipe ' . s:wipebuf") == FAIL) + if (put_line(fd, " silent exe 'bwipe ' .. wipebuf") == FAIL) goto fail; if (put_line(fd, "endif") == FAIL) goto fail; - if (put_line(fd, "unlet! s:wipebuf") == FAIL) - goto fail; // Re-apply 'winheight' and 'winwidth'. if (fprintf(fd, "set winheight=%ld winwidth=%ld", @@ -981,22 +994,22 @@ makeopens( } else { - if (put_line(fd, "let &shortmess = s:shortmess_save") == FAIL) + if (put_line(fd, "&shortmess = shortmess_save") == FAIL) goto fail; } if (restore_height_width) { // Restore 'winminheight' and 'winminwidth'. - if (put_line(fd, "let &winminheight = s:save_winminheight") == FAIL - || put_line(fd, "let &winminwidth = s:save_winminwidth") == FAIL) + if (put_line(fd, "&winminheight = save_winminheight") == FAIL + || put_line(fd, "&winminwidth = save_winminwidth") == FAIL) goto fail; } // Lastly, execute the x.vim file if it exists. - if (put_line(fd, "let s:sx = expand(\":p:r\").\"x.vim\"") == FAIL - || put_line(fd, "if filereadable(s:sx)") == FAIL - || put_line(fd, " exe \"source \" . fnameescape(s:sx)") == FAIL + if (put_line(fd, "var sx: string = expand(\":p:r\") .. \"x.vim\"") == FAIL + || put_line(fd, "if filereadable(sx)") == FAIL + || put_line(fd, " exe \"source \" .. fnameescape(sx)") == FAIL || put_line(fd, "endif") == FAIL) goto fail; @@ -1145,9 +1158,9 @@ write_session_file(char_u *filename) fd = open_exfile(filename, TRUE, APPENDBIN); failed = (fd == NULL - || put_line(fd, "let v:this_session = Save_VV_this_session") + || put_line(fd, "v:this_session = g:Save_VV_this_session") == FAIL - || put_line(fd, "unlet Save_VV_this_session") == FAIL); + || put_line(fd, "unlet g:Save_VV_this_session") == FAIL); if (fd != NULL && fclose(fd) != 0) failed = TRUE; @@ -1185,6 +1198,10 @@ ex_mkrc(exarg_T *eap) char_u *viewFile = NULL; unsigned *flagp; #endif +#if defined(FEAT_EVAL) + int sid; + scriptitem_T *si = NULL; +#endif if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) { @@ -1266,6 +1283,10 @@ ex_mkrc(exarg_T *eap) mksession_nl = TRUE; #endif + // Enforce vim9script + if (put_line(fd, "vim9script") == FAIL) + failed = TRUE; + // Write the version command for :mkvimrc if (eap->cmdidx == CMD_mkvimrc) (void)put_line(fd, "version 6.0"); @@ -1273,7 +1294,7 @@ ex_mkrc(exarg_T *eap) #ifdef FEAT_SESSION if (eap->cmdidx == CMD_mksession) { - if (put_line(fd, "let SessionLoad = 1") == FAIL) + if (put_line(fd, "g:SessionLoad = 1") == FAIL) failed = TRUE; } @@ -1291,23 +1312,47 @@ ex_mkrc(exarg_T *eap) #ifdef FEAT_SESSION if (!view_session || (eap->cmdidx == CMD_mksession - && (*flagp & SSOP_OPTIONS))) + && (*flagp & (SSOP_OPTIONS | SSOP_LOCALOPTIONS)))) #endif { + bool do_mappings = true; int flags = OPT_GLOBAL; #ifdef FEAT_SESSION - if (eap->cmdidx == CMD_mksession && (*flagp & SSOP_SKIP_RTP)) - flags |= OPT_SKIPRTP; + failed |= put_line(fd, "var cpo_save: string") == FAIL; + + if (eap->cmdidx == CMD_mksession) + { + if (*flagp & SSOP_SKIP_RTP) + flags |= OPT_SKIPRTP; + + // SSOP_LOCALOPTIONS requires only local mappings + do_mappings = *flagp & SSOP_OPTIONS; + } #endif - failed |= (makemap(fd, NULL) == FAIL + + if (do_mappings) + failed |= (makemap(fd, NULL) == FAIL || makeset(fd, flags, FALSE) == FAIL); + +#if defined(FEAT_EVAL) + // Save delay load import modules. + // Either SSOP_LOCALOPTIONS or SSOP_OPTIONS require them + for (sid = 1; sid <= script_items.ga_len; ++sid) + { + si = SCRIPT_ITEM(sid); + if (si->sn_autoload_prefix && + (fprintf(fd, "import autoload '%s'", si->sn_name) < 0 || + put_eol(fd) == FAIL)) + failed = TRUE; + } +#endif } #ifdef FEAT_SESSION if (!failed && view_session) { - if (put_line(fd, "let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1") == FAIL) + if (put_line(fd, "const so_save: number = &g:so | const siso_save: number = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1") == FAIL) failed = TRUE; if (eap->cmdidx == CMD_mksession) { @@ -1349,11 +1394,11 @@ ex_mkrc(exarg_T *eap) } else { + failed |= put_line(fd, "var cpo_save: string") == FAIL; failed |= (put_view(fd, curwin, curtab, !using_vdir, flagp, -1, NULL) == FAIL); } - if (put_line(fd, "let &g:so = s:so_save | let &g:siso = s:siso_save") - == FAIL) + if (put_line(fd, "&g:so = so_save | &g:siso = siso_save") == FAIL) failed = TRUE; # ifdef FEAT_SEARCH_EXTRA if (no_hlsearch && put_line(fd, "nohlsearch") == FAIL) @@ -1363,12 +1408,13 @@ ex_mkrc(exarg_T *eap) failed = TRUE; if (eap->cmdidx == CMD_mksession) { - if (put_line(fd, "unlet SessionLoad") == FAIL) + if (put_line(fd, "unlet g:SessionLoad") == FAIL) failed = TRUE; } } #endif - if (put_line(fd, "\" vim: set ft=vim :") == FAIL) + + if (put_line(fd, "# vim: set ft=vim :") == FAIL) failed = TRUE; failed |= fclose(fd); diff --git a/src/sign.c b/src/sign.c index c90856812a..a8dfd05eee 100644 --- a/src/sign.c +++ b/src/sign.c @@ -254,7 +254,7 @@ insert_sign(buf_T *buf, // buffer to store sign in buf->b_signlist = newsign; # ifdef FEAT_NETBEANS_INTG if (netbeans_active()) - buf->b_has_sign_column = TRUE; + buf->b_has_sign_column = true; # endif } else @@ -322,9 +322,10 @@ sign_get_info(sign_entry_T *sign) return NULL; dict_add_number(d, "id", sign->se_id); - dict_add_string(d, "group", - (sign->se_group == NULL) ? (char_u *)"" - : sign->se_group->sg_name); + if (sign->se_group == NULL) + dict_add_string_len(d, "group", (char_u *)"", 0); + else + dict_add_string(d, "group", sign->se_group->sg_name); dict_add_number(d, "lnum", sign->se_lnum); dict_add_string(d, "name", sign_typenr2name(sign->se_typenr)); dict_add_number(d, "priority", sign->se_priority); @@ -1777,32 +1778,40 @@ sign_getinfo(sign_T *sp, dict_T *retdict) { char_u *p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); if (p == NULL) - p = (char_u *)"NONE"; - dict_add_string(retdict, "linehl", p); + dict_add_string_len(retdict, "linehl", + (char_u *)"NONE", STRLEN_LITERAL("NONE")); + else + dict_add_string(retdict, "linehl", p); } if (sp->sn_text_hl > 0) { char_u *p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); if (p == NULL) - p = (char_u *)"NONE"; - dict_add_string(retdict, "texthl", p); + dict_add_string_len(retdict, "texthl", + (char_u *)"NONE", STRLEN_LITERAL("NONE")); + else + dict_add_string(retdict, "texthl", p); } if (sp->sn_cul_hl > 0) { char_u *p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE); if (p == NULL) - p = (char_u *)"NONE"; - dict_add_string(retdict, "culhl", p); + dict_add_string_len(retdict, "culhl", + (char_u *)"NONE", STRLEN_LITERAL("NONE")); + else + dict_add_string(retdict, "culhl", p); } if (sp->sn_num_hl > 0) { char_u *p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE); if (p == NULL) - p = (char_u *)"NONE"; - dict_add_string(retdict, "numhl", p); + dict_add_string_len(retdict, "numhl", + (char_u *)"NONE", STRLEN_LITERAL("NONE")); + else + dict_add_string(retdict, "numhl", p); } } diff --git a/src/socketserver.c b/src/socketserver.c new file mode 100644 index 0000000000..48c00c3580 --- /dev/null +++ b/src/socketserver.c @@ -0,0 +1,1412 @@ +/* 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. + */ + +/* + * socketserver.c: Socketserver clientserver functionality + */ + +#include "vim.h" + +#ifdef FEAT_SOCKETSERVER + +// Always greater than one. +# define PROTOCOL_VER 1 + +/* + * Any message sent to a Vim server or received from a Vim server is a simple + * JSON object with the following fields: + * { + * "version": PROTOCOL_VER -- Protocol version, if different, then ignore. + * + * "type": "expr"|"keystrokes"|"notify"|"reply"|"ver" -- The type of message + * + * "str": string -- What to execute for the command or contents of result + * + * ?"code": number -- Return code for expression + * + * ?"sender": string -- Address of client that sent command if it is a server. + * + * ?"wait": bool -- Used by --remote-wait since the client is not a server. + * } + */ + +/* + * Represents a reply from a server2client call. Each client that calls a + * server2client call to us has its own ss_reply_T. Each time a client sends + * data using server2client, Vim creates a ss_reply_T if it doesn't exist and + * adds the string to the array. When remote_read is called, the server id is + * used to find the specific ss_reply_T, and a single string is popped from the + * array. + */ +typedef struct +{ + char_u *sender; // Includes "type:" prefix if any + garray_T strings; +} ss_reply_T; + +static channel_T *server_channel = NULL; +static char_u *server_address = NULL; // Includes "type:" prefix if any +static bool server_is_unix = false; +static char_u *server_addr_cwd = NULL; // CWD when server was started, used + // to handle relative file paths. +static garray_T server_replies; + +static channel_T *client_channels = NULL; + +# define FOR_ALL_CLIENTS(ch) \ + for (ch = client_channels; ch != NULL; ch = ch->ch_ss_next) + +static void socketserver_cleanup(void); +static char_u *socketserver_create_path(char_u *name, bool quiet); +static char_u *socketserver_get_path(char_u *name, bool new, bool quiet, bool ignore, bool *fatal); +static void socketserver_accept(channel_T *channel); +static void socketserver_close(channel_T *channel); +static ss_reply_T *socketserver_add_reply(char_u *sender); + +/* + * Start the socketserver using the given name. Returns OK on success and FAIL + * on failure. + */ + int +socketserver_start(char_u *name, bool quiet) +{ + char_u *address = NULL; + int port; + bool is_unix = false; + channel_T *channel; + char_u *buf; + char_u dirbuf[MAXPATHL]; + + if (server_channel != NULL) + return OK; + + if (STRNICMP(name, "channel:", 8) == 0) + { + if (channel_parse_socketserver_address(name + 8, &port, &address, quiet) + == FAIL) + return FAIL; + if (address != NULL) + is_unix = true; + } + else + { + address = socketserver_create_path(name, quiet); + if (address == NULL) + return FAIL; + is_unix = true; + } + + if (is_unix) + channel = channel_listen_unix((char *)address, NULL, false); + else + channel = channel_listen(port, NULL); + + if (channel == NULL) + { + vim_free(address); + return FAIL; + } + + channel->ch_socketserver = true; + channel->ch_ss_accept_cb = socketserver_accept; + channel->ch_ss_close_cb = socketserver_close; + + server_channel = channel; + server_is_unix = is_unix; + + VIM_CLEAR(serverName); + + if (STRNICMP(name, "channel:", 8) == 0) + buf = vim_strsave(name); + else + { + buf = alloc(MAXPATHL + 1); + if (buf != NULL) + { + buf[0] = NUL; + mch_FullName(address, buf, MAXPATHL, false); + } + } + vim_free(address); + + if (buf != NULL) + { + server_address = vim_strsave(buf); + serverName = buf; + set_vim_var_string(VV_SEND_SERVER, serverName, -1); + } + + vim_free(server_addr_cwd); + if (mch_dirname(dirbuf, sizeof(dirbuf)) == OK) + server_addr_cwd = vim_strsave(dirbuf); + else + server_addr_cwd = NULL; + + ga_init2(&server_replies, sizeof(ss_reply_T), 2); + + ch_log(NULL, "socketserver: started server at %s", name); + + return OK; +} + +/* + * Stop running the socketserver if it is. Note that this does not stop Vim from + * becoming a client. + */ + void +socketserver_stop(void) +{ + if (server_channel == NULL) + return; + + channel_close(server_channel, false); + channel_clear(server_channel); + + socketserver_cleanup(); + + ch_log(NULL, "socketserver: shutting down server"); +} + +/* + * Cleanup server stuff. Do not close client channels, as those are not part of + * the actual server. + */ + static void +socketserver_cleanup(void) +{ +# ifdef UNIX + if (server_is_unix && server_address != NULL) + { + char_u *path = server_address; + char_u dirbuf[MAXPATHL]; + + if (STRNICMP(path, "channel:unix:", 13) == 0) + path += 13; + else if (STRNICMP(path, "name:", 5) == 0) + path += 5; + + if (*path == '/') + mch_remove(path); + // Go to the directory where the server was started. This is to handle + // when Vim changes directories and the servername is a relative path. + else if (server_addr_cwd != NULL + && mch_dirname(dirbuf, sizeof(dirbuf)) == OK) + { + if (mch_chdir((char *)server_addr_cwd) == 0) + { + mch_remove(path); + if (mch_chdir((char *)dirbuf) < 0) + emsg(_(e_cannot_go_back_to_previous_directory)); + } + } + } +# endif + + server_channel = NULL; + VIM_CLEAR(server_address); + VIM_CLEAR(server_addr_cwd); + + // Free all replies + for (int i = 0; i < server_replies.ga_len; i++) + { + ss_reply_T *reply = (ss_reply_T *)server_replies.ga_data + i; + + vim_free(reply->sender); + ga_clear_strings(&reply->strings); + } + ga_clear(&server_replies); +} + +/* + * List available sockets that can be connected to, only in common directories + * that Vim knows about. Vim instances with custom socket paths will not be + * detected. Returns a newline separated string on success and NULL on failure. + */ + char_u * +socketserver_list(void) +{ +# ifdef MSWIN + // Only support addresses on Windows + return vim_strsave((char_u *)""); +# else + garray_T str; + string_T buf; + string_T path; + DIR *dirp; + struct dirent *dp; + const char_u *known_dirs[] = { + mch_getenv("XDG_RUNTIME_DIR"), + mch_getenv("TMPDIR"), + (char_u *)"/tmp" + }; + + if ((buf.string = alloc(MAXPATHL)) == NULL) + return NULL; + if ((path.string = alloc(MAXPATHL)) == NULL) + { + vim_free(buf.string); + return NULL; + } + buf.length = 0; + path.length = 0; + + ga_init2(&str, 1, 100); + + for (size_t i = 0 ; i < ARRAY_LENGTH(known_dirs); i++) + { + const char_u *dir = known_dirs[i]; + + if (dir == NULL) + continue; + + if (STRCMP(dir, "/tmp") == 0 || + (known_dirs[1] != NULL && STRCMP(dir, known_dirs[1]) == 0)) + path.length = vim_snprintf_safelen((char *)path.string, MAXPATHL, + "%s/vim-%lu", dir, (unsigned long int)getuid()); + else + path.length = vim_snprintf_safelen((char *)path.string, MAXPATHL, + "%s/vim", dir); + + dirp = opendir((char *)path.string); + if (dirp == NULL) + continue; + + // Loop through directory + while ((dp = readdir(dirp)) != NULL) + { + if (STRCMP(dp->d_name, ".") == 0 || STRCMP(dp->d_name, "..") == 0) + continue; + + buf.length = vim_snprintf_safelen((char *)buf.string, MAXPATHL, + "%s/%s", path.string, dp->d_name); + + ga_concat_len(&str, (char_u *)dp->d_name, + buf.length - (path.length + 1)); + ga_append(&str, '\n'); + } + + closedir(dirp); + + break; + } + + vim_free(path.string); + vim_free(buf.string); + + ga_append(&str, NUL); + + return str.ga_data; +# endif +} + +/* + * If "name" is a path (starts with a '/', './', or '../'), it is assumed to be + * the path to the desired socket. If the socket path is already taken, append + * an incrementing number to the path until we find a socket filename that can + * be used. Returns alloced string or NULL on failure. + */ + static char_u * +socketserver_create_path(char_u *name, bool quiet) +{ +# ifdef MSWIN + // Only support channel addresses on Windows + if (STRNICMP(name, "channel:", 8) == 0 && STRLEN(name) > 8) + return vim_strsave(name + 8); + else + { + if (!quiet) + semsg(_(e_invalid_argument_str), name); + return NULL; + } +# else + char_u *buf = NULL; + int buflen = STRLEN(name) + NUMBUFLEN; + char_u *path = NULL; + bool fatal = false; + + if (STRNICMP(name, "channel:", 8) == 0 && STRLEN(name) > 8) + return vim_strsave(name + 8); + if (STRNICMP(name, "name:", 5) == 0) + name += 5; + + for (int i = 0; i < 1000; i++) + { + if (buf != NULL) + { + vim_snprintf((char *)buf, buflen, "%s%d", name, i); + path = socketserver_get_path(buf, true, quiet, true, &fatal); + } + else + path = socketserver_get_path(name, true, quiet, true, &fatal); + + if (fatal) + break; + + if (path == NULL) + { + if (buf == NULL) + { + buf = alloc(buflen); + if (buf == NULL) + { + semsg(_(e_out_of_memory_allocating_nr_bytes), buflen); + return NULL; + } + } + continue; + } + break; + } + vim_free(buf); + + return path; +# endif +} + +/* + * If "name" is a pathless name such as "VIM", search known directories for the + * socket named "name", and return the alloc'ed path to it. If "name" starts + * with a '/', './' or '../', then a copy of "name" is returned. + * + * If "name" starts with "channel:", then return the address part + * + * If "new" is true, then return a path if the name does not exist in the known + * location. + * + * If "ignore" is true, then don't emit an error message if a suitable path + * could not be found. + * + * If "fatal" is not NULL, then it is set to true if error is fatal. + * + * Returns path on success and NULL on failure. + */ + static char_u * +socketserver_get_path( + char_u *name, + bool new UNUSED, + bool quiet, + bool ignore UNUSED, + bool *fatal) +{ +# ifdef MSWIN + // Only support channel addresses on Windows + if (STRNICMP(name, "channel:", 8) == 0 && STRLEN(name) > 8) + return vim_strsave(name + 8); + else + { + if (!quiet) + semsg(_(e_invalid_argument_str), name); + if (fatal != NULL) + *fatal = true; + return NULL; + } +# else + char_u *buf; + bool res = false; + channel_T *channel; + const char_u *known_dirs[] = { + mch_getenv("XDG_RUNTIME_DIR"), + mch_getenv("TMPDIR"), + (char_u *)"/tmp" + }; + + if (name == NULL) + { + if (fatal != NULL) + *fatal = true; + return NULL; + } + + // Ignore if name is a path + if (name[0] == '/' || STRNCMP(name, "./", 2) == 0 || + STRNCMP(name, "../", 3) == 0) + return vim_strsave(name); + + if (STRNICMP(name, "channel:", 8) == 0 && STRLEN(name) > 8) + return vim_strsave(name + 8); + + if (STRNICMP(name, "name:", 5) == 0) + name += 5; + + if (vim_strchr(name, '/') != NULL) + { + if (!quiet) + semsg(_(e_socket_name_no_slashes), name); + if (fatal != NULL) + *fatal = true; + return NULL; + } + + buf = alloc(MAXPATHL); + + if (buf == NULL) + { + if (fatal != NULL) + *fatal = true; + semsg(_(e_out_of_memory_allocating_nr_bytes), MAXPATHL); + return NULL; + } + + for (size_t i = 0; i < ARRAY_LENGTH(known_dirs); i++) + { + const char_u *dir = known_dirs[i]; + bool got = false; + + if (dir == NULL) + continue; + else if (STRCMP(dir, "/tmp") == 0 || + (known_dirs[1] != NULL && STRCMP(dir, known_dirs[1]) == 0)) + { + // "/tmp" or $TMPDIR, must suffix dir with uid + vim_snprintf((char *)buf, MAXPATHL, "%s/vim-%lu", dir, + (unsigned long int)getuid()); + if (vim_mkdir(buf, 0700) == -1 && errno != EEXIST) + continue; + + vim_snprintf((char *)buf, MAXPATHL, "%s/vim-%lu/%s", dir, + (unsigned long int)getuid(), name); + } + else + { + vim_snprintf((char *)buf, MAXPATHL, "%s/vim", dir); + if (vim_mkdir(buf, 0700) == -1 && errno != EEXIST) + continue; + + vim_snprintf((char *)buf, MAXPATHL, "%s/vim/%s", dir, name); + } + + // If looking for a new socket path, and "buf" currently exists, check + // if it is a dead socket, if it is then remove it. + if (new) + { + emsg_silent++; + channel = channel_open_unix((char *)buf, NULL); + emsg_silent--; + + if (channel != NULL) + { + channel_close(channel, false); + channel_clear(channel); + } + else + { + mch_remove(buf); + got = true; + } + } + + res = true; + if (got || (!new && mch_access((char *)buf, F_OK) == 0)) + { + if (server_address != NULL && STRCMP(buf, server_address) == 0) + // Can't connect to itself + break; + return buf; + } + break; + } + + if (!quiet) + { + if (!res) + semsg(_("Failed creating socket directory: %s"), strerror(errno)); + else if (!ignore) + semsg(_(e_invalid_server_id_used_str), name); + } + if (!res && fatal != NULL) + *fatal = true; + + vim_free(buf); + return NULL; +# endif +} + +/* + * Callback for when client channel is closed + */ + static void +socketserver_client_close(channel_T *channel) +{ + if (channel == client_channels) + client_channels = channel->ch_ss_next; + if (channel->ch_ss_prev != NULL) + channel->ch_ss_prev->ch_ss_next = channel->ch_ss_next; + if (channel->ch_ss_next != NULL) + channel->ch_ss_next->ch_ss_prev = channel->ch_ss_prev; + + ch_log(NULL, "socketserver: client channel closed"); +} + +/* + * Callback for when server channel accepted new client. + */ + static void +socketserver_accept(channel_T *channel) +{ + channel->ch_socketserver = true; + channel->ch_ss_close_cb = socketserver_client_close; + + channel->ch_ss_next = client_channels; + channel->ch_ss_prev = NULL; + if (client_channels != NULL) + client_channels->ch_ss_prev = channel; + client_channels = channel; + + // We will read the command from the client later in the input loop. + ch_log(NULL, "socketserver: accepted new client"); +} + +/* + * Callback for when server channel is closed + */ + static void +socketserver_close(channel_T *channel UNUSED) +{ + socketserver_cleanup(); + + ch_log(NULL, "socketserver: server channel closed"); +} + +/* + * Mark references to socketserver channels + */ + int +set_ref_in_socketserver_channel(int copyID) +{ + bool abort = false; + channel_T *channel; + typval_T tv; + + tv.v_type = VAR_CHANNEL; + tv.vval.v_channel = server_channel; + abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL, NULL); + + FOR_ALL_CLIENTS(channel) + { + if (abort) + break; + + tv.v_type = VAR_CHANNEL; + tv.vval.v_channel = channel; + abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL, NULL); + } + return abort; +} + +/* + * Serialize "msg" into a string and send it over the given channel "ch". Also + * adds version header to "msg", if "ver" is true. Returns OK on success and + * FAIL on failure. + */ + static int +socketserver_send_message(channel_T *ch, dict_T *msg, char *func, bool ver) +{ + typval_T tv; + char_u *buf; + int ret; + + if (ver) + dict_add_number(msg, "version", PROTOCOL_VER); + + tv.v_type = VAR_DICT; + tv.vval.v_dict = msg; + buf = json_encode(&tv, JSON_NL); + + if (buf != NULL) + { + emsg_silent++; + ret = channel_send(ch, PART_SOCK, buf, (int)STRLEN(buf), func); + emsg_silent--; + } + else + return FAIL; + vim_free(buf); + return ret; +} + +/* + * Execute the JSON message represented by "dict". + */ + static void +socketserver_exec(channel_T *channel, dict_T *message) +{ + dictitem_T *di; + char_u *type; + char_u *str = NULL; + char_u *sender = NULL; + char_u idbuf[11 + NUMBUFLEN]; + + di = dict_find(message, (char_u *)"type", -1); + if (di == NULL || di->di_tv.v_type != VAR_STRING) + return; + else + type = di->di_tv.vval.v_string; + + di = dict_find(message, (char_u *)"str", -1); + if (di != NULL && di->di_tv.v_type == VAR_STRING) + str = di->di_tv.vval.v_string; + + di = dict_find(message, (char_u *)"sender", -1); + if (di != NULL && di->di_tv.v_type == VAR_STRING) + { + sender = di->di_tv.vval.v_string; + + // Save in global + vim_free(client_socket); + client_socket = vim_strsave(sender); + } + + di = dict_find(message, (char_u *)"wait", -1); + if (di != NULL && di->di_tv.v_type == VAR_BOOL && di->di_tv.vval.v_number) + { + // Client is not a server, but still wants a response later. Save the + // ID of the channel connection that we will use to send back a response, + vim_snprintf((char *)idbuf, sizeof(idbuf), "remotewait:%d", + channel->ch_id); + + sender = idbuf; + vim_free(client_socket); + client_socket = vim_strsave(sender); + } + + ch_log(NULL, "socketserver_exec(): result: %s", + str == NULL ? (char_u *)"(null)" : str); + + if (STRCMP(type, "expr") == 0 && str != NULL) + { + // Evaluate expression and send back reply + dict_T *dict; + char_u *result; + int code; + + dict = dict_alloc(); + if (dict == NULL) + return; + + result = eval_client_expr_to_string(str); + code = result == NULL ? -1 : 0; + + dict_add_string(dict, "type", (char_u *)"reply"); + if (result != NULL) + { + dict_add_string(dict, "str", result); + vim_free(result); + } + else + // Error occurred, return error message + dict_add_string(dict, "str", + (char_u *)_(e_invalid_expression_received)); + + dict_add_number(dict, "code", code); + + socketserver_send_message(channel, dict, "socketserver_exec", true); + dict_unref(dict); + } + else if (STRCMP(type, "keystrokes") == 0 && str != NULL) + { + // Execute keystrokes + server_to_input_buf(str); + } + else if (STRCMP(type, "notify") == 0) + { + // Notification, execute autocommands and save the reply for later use + if (sender != NULL && str != NULL) + { + ss_reply_T *reply; + + reply = socketserver_add_reply(sender); + + if (reply != NULL) + ga_copy_string(&reply->strings, str); + + apply_autocmds(EVENT_REMOTEREPLY, sender, str, TRUE, curbuf); + } + } + else if (STRCMP(type, "ver") == 0) + { + // A message we sent previously had the wrong version. Emit an error + // message to alert the user. + emsg(_(e_socket_server_version_mismatch)); + } + else + ch_error(NULL, "socketserver: unknown command type '%s'", type); +} + + static int +socketserver_get_message(channel_T *channel, typval_T **tv) +{ + jsonq_T *head = &channel->ch_part[PART_SOCK].ch_json_head; + jsonq_T *json_msg = head->jq_next; + int ver; + + if (json_msg == NULL) + { + // Check the readahead buffer + channel_parse_json(channel, PART_SOCK, true); + json_msg = head->jq_next; + } + if (json_msg == NULL) + return FAIL; + *tv = json_msg->jq_value; + remove_json_node(head, json_msg); + + if ((*tv)->v_type != VAR_DICT) + { + ch_error(NULL, "socketserver: message is not a JSON object"); + free_tv(*tv); + return FAIL; + } + + ver = dict_get_number((*tv)->vval.v_dict, "version"); + + if (ver != 0 && ver != PROTOCOL_VER) + { + dict_T *dict; + + ch_error(NULL, "socketserver: message has different version %d", ver); + free_tv(*tv); + + // Send back a special error + dict = dict_alloc(); + if (dict != NULL) + { + dict_add_string(dict, "type", (char_u *)"ver"); + socketserver_send_message(channel, dict, + "socketserver_get_message", false); + dict_unref(dict); + } + return FAIL; + } + + return OK; +} + +/* + * Parse any commands in the queue and execute them. + */ + void +socketserver_parse_messages(void) +{ + typval_T *tv; + + for (channel_T *ch = client_channels; ch != NULL;) + { + // Make sure to save next channel in case "ch" is freed. Not sure if + // this can actually happen but be safe. + channel_T *next = ch->ch_ss_next; + + // Get the JSON message if there is any from the queue for this channel. + if (socketserver_get_message(ch, &tv) == FAIL) + { + ch = next; + continue; + } + + socketserver_exec(ch, tv->vval.v_dict); + free_tv(tv); + ch = next; + } +} + + +/* + * Poll until there is something to read on "channel". Also handle other + * socketserver channels in the meantime. If "channel" is NULL, then poll all + * channels once then exit. If "timeout" is -1, then wait forever unless + * interrupted. + * + * Return OK on success and FAIL on failure or timeout. + */ + static int +socketserver_wait(channel_T *channel, int timeout) +{ + while (true) + { + int ret; + channel_T *ch; +# ifdef HAVE_SELECT + fd_set rfds; + struct timeval tv; + int maxfd = -1; + + if (timeout != -1) + { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + } + + FD_ZERO(&rfds); + + if (channel != NULL) + { + if (channel->CH_SOCK_FD == INVALID_FD) + // Shouldn't happen + return FAIL; + + maxfd = channel->CH_SOCK_FD; + FD_SET(channel->CH_SOCK_FD, &rfds); + } + if (server_channel != NULL && server_channel->CH_SOCK_FD != INVALID_FD) + { + FD_SET(server_channel->CH_SOCK_FD, &rfds); + if (server_channel->CH_SOCK_FD > maxfd) + maxfd = server_channel->CH_SOCK_FD; + } + + FOR_ALL_CLIENTS(ch) + { + if (ch->CH_SOCK_FD != INVALID_FD) + { + FD_SET(ch->CH_SOCK_FD, &rfds); + if (maxfd < (int)ch->CH_SOCK_FD) + maxfd = (int)ch->CH_SOCK_FD; + } + } + + if (maxfd == -1) + return FAIL; + + ret = select(maxfd + 1, &rfds, NULL, NULL, timeout == -1 ? NULL : &tv); + +# ifdef EINTR + if (ret == -1 && errno == EINTR) + { + if (got_int) + break; + continue; + } +# endif + + if (ret > 0) + { + if (server_channel != NULL + && server_channel->CH_SOCK_FD != INVALID_FD + && FD_ISSET(server_channel->CH_SOCK_FD, &rfds)) + channel_check(server_channel, PART_SOCK); + + FOR_ALL_CLIENTS(ch) + if (ch->CH_SOCK_FD != INVALID_FD + && FD_ISSET(ch->CH_SOCK_FD, &rfds)) + channel_check(ch, PART_SOCK); + + socketserver_parse_messages(); + + if (channel == NULL) + return OK; + + if (channel->CH_SOCK_FD != INVALID_FD + && FD_ISSET(channel->CH_SOCK_FD, &rfds)) + { + channel_check(channel, PART_SOCK); + return OK; + } + continue; + } +# else + struct pollfd fds[MAX_OPEN_CHANNELS + 1]; + int nfd = 0; + int channel_idx = -1; + int server_idx = -1; + + if (channel != NULL) + { + if (channel->CH_SOCK_FD == INVALID_FD) + // Shouldn't happen + return FAIL; + + channel_idx = nfd; + fds[nfd].fd = channel->CH_SOCK_FD; + fds[nfd++].events = POLLIN; + } + if (server_channel != NULL && server_channel->CH_SOCK_FD != INVALID_FD) + { + server_idx = nfd; + fds[nfd].fd = server_channel->CH_SOCK_FD; + fds[nfd++].events = POLLIN; + } + + FOR_ALL_CLIENTS(ch) + if (ch->CH_SOCK_FD != INVALID_FD) + { + fds[nfd].fd = ch->CH_SOCK_FD; + fds[nfd].events = POLLIN; + ch->ch_part[PART_SOCK].ch_poll_idx = nfd; + nfd++; + } + + ret = poll(fds, nfd, timeout); + +# ifdef EINTR + if (ret == -1 && errno == EINTR) + { + if (got_int) + break; + continue; + } +# endif + + if (ret > 0) + { + if (server_channel != NULL + && server_channel->CH_SOCK_FD != INVALID_FD + && fds[server_idx].revents & POLLIN) + channel_check(server_channel, PART_SOCK); + + FOR_ALL_CLIENTS(ch) + if (ch->CH_SOCK_FD != INVALID_FD + && fds[ch->ch_part[PART_SOCK].ch_poll_idx] + .revents & POLLIN) + channel_check(ch, PART_SOCK); + + socketserver_parse_messages(); + + if (channel == NULL) + return OK; + + if (channel->CH_SOCK_FD != INVALID_FD + && fds[channel_idx].revents & POLLIN) + { + channel_check(channel, PART_SOCK); + return OK; + } + continue; + } +# endif + break; + } + return FAIL; +} + +/* + * Parse "name" and create or get the channel connection for it. If "wait" is + * not NULL, then if the client name is a channel ID, then it will be set to + * true. Returns NULL on + * failure. + */ + static channel_T * +socketserver_get_channel(char_u *name, bool quiet, bool *wait) +{ + char_u *address = NULL; + int port; + bool is_unix = false; + channel_T *channel; + + if (STRNICMP(name, "channel:", 8) == 0) + { + if (channel_parse_socketserver_address(name + 8, &port, &address, true) + == FAIL) + return NULL; + if (address != NULL) + is_unix = true; + } + else if (STRNICMP(name, "remotewait:", 11) == 0) + { + // Channel ID name, find channel with that ID. + int id; + + if (name[11] == NUL) + return NULL; + id = strtol((char *)name + 11, NULL, 10); + if (wait != NULL) + *wait = true; + + return channel_find(id); + } + else + { + address = socketserver_get_path(name, false, quiet, false, NULL); + if (address == NULL) + return NULL; + is_unix = true; + } + + if (is_unix) + channel = channel_open_unix((char *)address, NULL); + else + channel = channel_open("localhost", port, 1000, NULL); + + if (channel == NULL && !quiet) + semsg(_(e_socket_server_failed_connecting), name); + + vim_free(address); + + return channel; +} + +/* + * Send command to address "name". If "ch" is not NULL, it is set to the channel + * for the connection between us and the server, and the channel will not just + * be closed immediately, this is used for --remote-wait. Returns 0 for OK, -1 + * on error. + */ + int +socketserver_send( + char_u *name, + char_u *str, + char_u **result, + bool is_expr, + int timeout, + bool silent, + channel_T **ch) +{ + int rcode = -1; + channel_T *channel; + dict_T *dict; + dictitem_T *di; + typval_T *resp_tv = NULL; + + if (*name == NUL) + { + semsg(_(e_unable_to_send_to_str), name); + return -1; + } + + // Execute locally if target is ourselves + if (serverName != NULL && STRICMP(name, serverName) == 0) + return sendToLocalVim(str, is_expr, result); + + channel = socketserver_get_channel(name, silent, NULL); + if (channel == NULL) + return -1; + + dict = dict_alloc(); + if (dict == NULL) + goto exit; + + dict_add_string(dict, "type", (char_u *)(is_expr ? "expr" : "keystrokes")); + dict_add_string(dict, "str", str); + + // Tell server who we are so it can save our socket path internally for + // later use with server2client. Only do this if we are actually a server. + // + // If we are not a server, then --remote-wait will not work. To handle this + // case, we add "wait" to the JSON message set to true, so that the server + // will create an internal address for our connection to it. This is + // only used for --remote-wait, not exposed to user. + if (server_address != NULL) + dict_add_string(dict, "sender", server_address); + else if (ch != NULL) + dict_add_bool(dict, "wait", true); + + if (socketserver_send_message(channel, dict, "socketserver_send", true) + == FAIL) + { + semsg(_(e_unable_to_send_to_str), name); + dict_unref(dict); + goto exit; + } + dict_unref(dict); + + if (!is_expr) + { + // Exit, we aren't waiting for a response + rcode = 0; + + if (ch != NULL) + { + *ch = channel; + + channel->ch_ss_next = client_channels; + channel->ch_ss_prev = NULL; + channel->ch_ss_close_cb = socketserver_client_close; + client_channels = channel; + + return rcode; + } + goto exit; + } + + if (timeout == 0) + timeout = 1000; + + // To handle recursive calls, we must handle any socketserver channels as + // well. + while (socketserver_wait(channel, timeout) == OK) + if (socketserver_get_message(channel, &resp_tv) == OK) + break; + + if (resp_tv == NULL) + { + // Channel closed, don't make this an error, because this may be the + // result of the expression (e.g. --remote-expr 'execute("qa!")') + rcode = 0; + goto exit; + } + + dict = resp_tv->vval.v_dict; + + di = dict_find(dict, (char_u *)"type", -1); + if (di == NULL || di->di_tv.v_type != VAR_STRING || + (STRCMP(di->di_tv.vval.v_string, "reply") != 0 + && STRCMP(di->di_tv.vval.v_string, "ver") != 0)) + { + ch_error(NULL, "socketserver: unknown reply type"); + free_tv(resp_tv); + goto exit; + } + + if (STRCMP(di->di_tv.vval.v_string, "ver") == 0) + { + emsg(_(e_socket_server_version_mismatch)); + free_tv(resp_tv); + goto exit; + } + + if (result != NULL) + { + di = dict_find(dict, (char_u *)"str", -1); + if (di != NULL && di->di_tv.v_type == VAR_STRING) + *result = vim_strsave(di->di_tv.vval.v_string); + else + { + free_tv(resp_tv); + goto exit; + } + } + + di = dict_find(dict, (char_u *)"code", -1); + if (di != NULL && di->di_tv.v_type == VAR_NUMBER) + rcode = di->di_tv.vval.v_number; + + free_tv(resp_tv); + +exit: + channel_close(channel, false); + channel_clear(channel); + return rcode; +} + + static ss_reply_T * +socketserver_get_reply(char_u *sender, int *index) +{ + for (int i = 0; i < server_replies.ga_len; i++) + { + ss_reply_T *reply = ((ss_reply_T *)server_replies.ga_data) + i; + + if (STRCMP(reply->sender, sender) == 0) + { + if (index != NULL) + *index = i; + return reply; + } + } + return NULL; +} + +/* + * Add reply to list of replies. Returns a pointer to the ss_reply_T that was + * initialized or was found. + */ + static ss_reply_T * +socketserver_add_reply(char_u *sender) +{ + ss_reply_T *reply; + + if (server_replies.ga_growsize == 0) + ga_init2(&server_replies, sizeof(ss_reply_T), 1); + + reply = socketserver_get_reply(sender, NULL); + + if (reply == NULL && ga_grow(&server_replies, 1) == OK) + { + reply = ((ss_reply_T *)server_replies.ga_data) + server_replies.ga_len++; + + reply->sender = vim_strsave(sender); + + if (reply->sender == NULL) + return NULL; + + ga_init2(&reply->strings, sizeof(char_u *), 5); + } + + return reply; +} + + static void +socketserver_remove_reply(char_u *sender) +{ + int index; + ss_reply_T *reply = socketserver_get_reply(sender, &index); + + if (reply != NULL) + { + ss_reply_T *arr = server_replies.ga_data; + int len = server_replies.ga_len; + + // Free strings + vim_free(reply->sender); + ga_clear_strings(&reply->strings); + + // Move all elements after the removed reply forward by one + if (len > 1) + mch_memmove(arr + index, arr + index + 1, + sizeof(ss_reply_T) * (len - index - 1)); + server_replies.ga_len--; + } +} + +/* + * Send a string to "client" as a reply (notification). Returns OK on success + * and FAIL on failure. + */ + int +socketserver_send_reply(char_u *client, char_u *str) +{ + dict_T *dict; + channel_T *channel; + int ret = OK; + bool wait = false; + + if (*client == NUL) + { + semsg(_(e_invalid_server_id_used_str), client); + return FAIL; + } + + if (server_channel == NULL || server_address == NULL) + { + emsg(_(e_socket_server_not_online)); + return FAIL; + } + + channel = socketserver_get_channel(client, false, &wait); + if (channel == NULL) + return FAIL; + + dict = dict_alloc(); + if (dict == NULL) + { + ret = FAIL; + goto exit; + } + + dict_add_string(dict, "type", (char_u *)"notify"); + dict_add_string(dict, "str", str); + if (server_address != NULL) + dict_add_string(dict, "sender", server_address); + + ret = socketserver_send_message(channel, dict, + "socketserver_send_reply", true); + dict_unref(dict); + +exit: + // Don't want to close the channel if client is referenced by channel ID. + // This allows --remote-wait to work with multiple files. + if (!wait) + { + channel_close(channel, false); + channel_clear(channel); + } + + return ret; +} + +/* + * Wait for reply from "client" and place result in "str". Returns OK on success + * and FAIL on failure. Timeout is in milliseconds + */ + int +socketserver_read_reply( + char_u *client, + char_u **str, + int timeout, + bool remotewait) +{ + ss_reply_T *reply = NULL; + char_u *actual; + + if (*client == NUL) + { + semsg(_(e_invalid_server_id_used_str), client); + return FAIL; + } + + if (!remotewait && (server_channel == NULL || server_address == NULL)) + { + emsg(_(e_socket_server_not_online)); + return FAIL; + } + + actual = socketserver_get_path(client, false, false, false, NULL); + if (actual == NULL) + return FAIL; + + while (true) + { + reply = socketserver_get_reply(actual, NULL); + if (reply != NULL) + break; + if (socketserver_wait(NULL, timeout) == FAIL) + break; + } + + if (reply == NULL || reply->strings.ga_len == 0) + { + vim_free(actual); + return FAIL; + } + + // Consume the string + *str = ((char_u **)reply->strings.ga_data)[0]; + + if (reply->strings.ga_len > 1) + mch_memmove((char_u **)reply->strings.ga_data, + ((char_u **)reply->strings.ga_data) + 1, + sizeof(char_u *) * (reply->strings.ga_len - 1)); + reply->strings.ga_len--; + + if (reply->strings.ga_len < 1) + // Last string removed, remove the reply + socketserver_remove_reply(actual); + + vim_free(actual); + + return OK; +} + +/* + * Check for any replies for "sender". Returns 1 if there is and places the + * reply in "str" without consuming it (note that a copy is not created). + * Returns 0 if otherwise and -1 on + * error. + */ + int +socketserver_peek_reply(char_u *sender, char_u **str) +{ + ss_reply_T *reply; + char_u *actual; + + if (*sender == NUL) + { + semsg(_(e_invalid_server_id_used_str), sender); + return FAIL; + } + + if (server_channel == NULL || server_address == NULL) + { + emsg(_(e_socket_server_not_online)); + return FAIL; + } + + actual = socketserver_get_path(sender, false, false, false, NULL); + if (actual == NULL) + return FAIL; + + reply = socketserver_get_reply(actual, NULL); + vim_free(actual); + + if (reply != NULL && reply->strings.ga_len > 0) + { + if (str != NULL) + *str = ((char_u **)reply->strings.ga_data)[0]; + return 1; + } + return 0; +} + +#endif // FEAT_SOCKETSERVER diff --git a/src/spell.c b/src/spell.c index 01eb57e3a9..b48ee87b03 100644 --- a/src/spell.c +++ b/src/spell.c @@ -2589,7 +2589,7 @@ open_spellbuf(void) if (buf == NULL) return NULL; - buf->b_spell = TRUE; + buf->b_spell = true; buf->b_p_swf = TRUE; // may create a swap file #ifdef FEAT_CRYPT buf->b_p_key = empty_option; diff --git a/src/spell.h b/src/spell.h index 1f473732a9..4cef842fa2 100644 --- a/src/spell.h +++ b/src/spell.h @@ -119,6 +119,7 @@ struct slang_S // Info from the .sug file. Loaded on demand. time_t sl_sugtime; // timestamp for .sug file char_u *sl_sbyts; // soundfolded word bytes + long sl_sbyts_len; // length of sl_sbyts idx_T *sl_sidxs; // soundfolded word indexes buf_T *sl_sugbuf; // buffer with word number table int sl_sugloaded; // TRUE when .sug file was loaded or failed to diff --git a/src/spellfile.c b/src/spellfile.c index c570920795..8a373f343f 100644 --- a/src/spellfile.c +++ b/src/spellfile.c @@ -290,6 +290,9 @@ #define CF_WORD 0x01 #define CF_UPPER 0x02 +// Max allowed length for COMPOUND section +#define COMPOUND_MAX_LEN 100000 + /* * Loop through all the siblings of a node (including the node) */ @@ -310,7 +313,7 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to); static void set_sal_first(slang_T *lp); static int *mb_str2wide(char_u *s); static int spell_read_tree(FILE *fd, char_u **bytsp, long *bytsp_len, idx_T **idxsp, int prefixtree, int prefixcnt); -static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx_T startidx, int prefixtree, int maxprefcondnr); +static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx_T startidx, int prefixtree, int maxprefcondnr, int depth); static void set_spell_charflags(char_u *flags, int cnt, char_u *upp); static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp); static void set_map_str(slang_T *lp, char_u *map); @@ -594,7 +597,7 @@ endOK: * Returns the total number of words. */ static void -tree_count_words(char_u *byts, idx_T *idxs) +tree_count_words(char_u *byts, long byts_len, idx_T *idxs) { int depth; idx_T arridx[MAXWLEN]; @@ -632,8 +635,8 @@ tree_count_words(char_u *byts, idx_T *idxs) ++wordcount[depth]; // Skip over any other NUL bytes (same word with different - // flags). - while (byts[n + 1] == 0) + // flags). But don't go over the end. + while (n + 1 < byts_len && byts[n + 1] == 0) { ++n; ++curi[depth]; @@ -729,8 +732,8 @@ suggest_load_files(void) * : * Read the trie with the soundfolded words. */ - if (spell_read_tree(fd, &slang->sl_sbyts, NULL, &slang->sl_sidxs, - FALSE, 0) != 0) + if (spell_read_tree(fd, &slang->sl_sbyts, &slang->sl_sbyts_len, + &slang->sl_sidxs, FALSE, 0) != 0) { someerror: semsg(_(e_error_while_reading_sug_file_str), @@ -779,8 +782,10 @@ someerror: * Need to put word counts in the word tries, so that we can find * a word by its number. */ - tree_count_words(slang->sl_fbyts, slang->sl_fidxs); - tree_count_words(slang->sl_sbyts, slang->sl_sidxs); + tree_count_words(slang->sl_fbyts, slang->sl_fbyts_len, + slang->sl_fidxs); + tree_count_words(slang->sl_sbyts, slang->sl_sbyts_len, + slang->sl_sidxs); nextone: if (fd != NULL) @@ -1219,6 +1224,8 @@ read_compound(FILE *fd, slang_T *slang, int len) char_u *crp; int cnt; garray_T *gap; + size_t patsize; + size_t flagsize; if (todo < 2) return SP_FORMERROR; // need at least two bytes @@ -1275,16 +1282,19 @@ read_compound(FILE *fd, slang_T *slang, int len) // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$". // Inserting backslashes may double the length, "^\(\)$" is 7 bytes. // Conversion to utf-8 may double the size. - c = todo * 2 + 7; + if ((size_t)todo > COMPOUND_MAX_LEN) + return SP_FORMERROR; + patsize = (size_t)todo * 2 + 7; if (enc_utf8) - c += todo * 2; - pat = alloc(c); + patsize += (size_t)todo * 2; + flagsize = (size_t)todo + 1; + pat = alloc(patsize); if (pat == NULL) return SP_OTHERERROR; // We also need a list of all flags that can appear at the start and one // for all flags. - cp = alloc(todo + 1); + cp = alloc(flagsize); if (cp == NULL) { vim_free(pat); @@ -1293,7 +1303,7 @@ read_compound(FILE *fd, slang_T *slang, int len) slang->sl_compstartflags = cp; *cp = NUL; - ap = alloc(todo + 1); + ap = alloc(flagsize); if (ap == NULL) { vim_free(pat); @@ -1305,7 +1315,7 @@ read_compound(FILE *fd, slang_T *slang, int len) // And a list of all patterns in their original form, for checking whether // compounding may work in match_compoundrule(). This is freed when we // encounter a wildcard, the check doesn't work then. - crp = alloc(todo + 1); + crp = alloc(flagsize); slang->sl_comprules = crp; pp = pat; @@ -1595,8 +1605,11 @@ spell_read_tree( if (len <= 0) return 0; - // Allocate the byte array. - bp = alloc(len); + // Allocate the byte array. Zero-initialize so that any position the + // tree does not visit reads as 0; a stray BY_INDEX shared reference + // into such a slot then behaves as end-of-word in spellsuggest() + // instead of consuming an arbitrary heap byte as a siblingcount. + bp = alloc_clear(len); if (bp == NULL) return SP_OTHERERROR; *bytsp = bp; @@ -1610,9 +1623,11 @@ spell_read_tree( *idxsp = ip; // Recursively read the tree and store it in the array. - idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt); + idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt, 0); if (idx < 0) return idx; + if (idx != len) + return SP_FORMERROR; return 0; } @@ -1634,7 +1649,8 @@ read_tree_node( int maxidx, // size of arrays idx_T startidx, // current index in "byts" and "idxs" int prefixtree, // TRUE for reading PREFIXTREE - int maxprefcondnr) // maximum for + int maxprefcondnr, // maximum for + int depth) // recursion level { int len; int i; @@ -1644,6 +1660,12 @@ read_tree_node( int c2; #define SHARED_MASK 0x8000000 + // Bail out on a crafted .spl whose tree recurses beyond the maximum + // word length: each tree level corresponds to one byte of a word, so + // any well-formed file has depth <= MAXWLEN. + if (depth > MAXWLEN) + return SP_FORMERROR; + len = getc(fd); // if (len <= 0) return SP_TRUNCERROR; @@ -1729,7 +1751,7 @@ read_tree_node( { idxs[startidx + i] = idx; idx = read_tree_node(fd, byts, idxs, maxidx, idx, - prefixtree, maxprefcondnr); + prefixtree, maxprefcondnr, depth + 1); if (idx < 0) break; } @@ -1991,8 +2013,8 @@ static int str_equal(char_u *s1, char_u *s2); static void add_fromto(spellinfo_T *spin, garray_T *gap, char_u *from, char_u *to); static int sal_to_bool(char_u *s); static int get_affix_flags(afffile_T *affile, char_u *afflist); -static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist); -static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist); +static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist, int *cntp); +static int get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist, int *cntp); static int store_aff_word(spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile, hashtab_T *ht, hashtab_T *xht, int condit, int flags, char_u *pfxlist, int pfxlen); static void *getroom(spellinfo_T *spin, size_t len, int align); static char_u *getroom_save(spellinfo_T *spin, char_u *s); @@ -2736,10 +2758,12 @@ spell_read_aff(spellinfo_T *spin, char_u *fname) char_u buf[MAXLINELEN]; aff_entry->ae_cond = getroom_save(spin, items[4]); + // Note: this silently truncates the buffer, but this should + // not happen in practice if (*items[0] == 'P') - sprintf((char *)buf, "^%s", items[4]); + vim_snprintf((char *)buf, sizeof(buf), "^%s", items[4]); else - sprintf((char *)buf, "%s$", items[4]); + vim_snprintf((char *)buf, sizeof(buf), "%s$", items[4]); aff_entry->ae_prog = vim_regcomp(buf, RE_MAGIC + RE_STRING + RE_STRICT); if (aff_entry->ae_prog == NULL) @@ -3333,6 +3357,26 @@ check_renumber(spellinfo_T *spin) } } +/* + * Append one affix or compound ID to "store_afflist". + * Returns FAIL when this would overrun the fixed-size buffer. + */ + static int +store_afflist_add( + char_u *store_afflist, + int *cntp, + int id) +{ + if (*cntp >= MAXWLEN - 1) + { + emsg(_(e_too_many_postponed_prefixes_spell)); + return FAIL; + } + store_afflist[(*cntp)++] = id; + store_afflist[*cntp] = NUL; + return OK; +} + /* * Return TRUE if flag "flag" appears in affix list "afflist". */ @@ -3492,6 +3536,7 @@ spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) char_u *afflist; char_u store_afflist[MAXWLEN]; int pfxlen; + int totlen; int need_affix; char_u *dw; char_u *pc; @@ -3641,6 +3686,7 @@ spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) flags = 0; store_afflist[0] = NUL; pfxlen = 0; + totlen = 0; need_affix = FALSE; if (afflist != NULL) { @@ -3652,13 +3698,30 @@ spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) need_affix = TRUE; if (affile->af_pfxpostpone) + { // Need to store the list of prefix IDs with the word. - pfxlen = get_pfxlist(affile, afflist, store_afflist); + if (get_pfxlist(affile, afflist, store_afflist, &totlen) + == FAIL) + { + retval = FAIL; + vim_free(pc); + break; + } + pfxlen = totlen; + } if (spin->si_compflags != NULL) + { // Need to store the list of compound flags with the word. // Concatenate them to the list of prefix IDs. - get_compflags(affile, afflist, store_afflist + pfxlen); + if (get_compflags(affile, afflist, store_afflist, &totlen) + == FAIL) + { + retval = FAIL; + vim_free(pc); + break; + } + } } // Add the word to the word tree(s). @@ -3729,18 +3792,18 @@ get_affix_flags(afffile_T *affile, char_u *afflist) /* * Get the list of prefix IDs from the affix list "afflist". * Used for PFXPOSTPONE. - * Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL - * and return the number of affixes. + * Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL. + * Returns FAIL when the fixed-size buffer would overflow. */ static int get_pfxlist( afffile_T *affile, char_u *afflist, - char_u *store_afflist) + char_u *store_afflist, + int *cntp) { char_u *p; char_u *prevp; - int cnt = 0; int id; char_u key[AH_KEY_LEN]; hashitem_T *hi; @@ -3757,32 +3820,32 @@ get_pfxlist( if (!HASHITEM_EMPTY(hi)) { id = HI2AH(hi)->ah_newID; - if (id != 0) - store_afflist[cnt++] = id; + if (id != 0 && store_afflist_add(store_afflist, cntp, id) == FAIL) + return FAIL; } } if (affile->af_flagtype == AFT_NUM && *p == ',') ++p; } - store_afflist[cnt] = NUL; - return cnt; + return OK; } /* * Get the list of compound IDs from the affix list "afflist" that are used * for compound words. * Puts the flags in "store_afflist[]". + * Returns FAIL when the fixed-size buffer would overflow. */ - static void + static int get_compflags( afffile_T *affile, char_u *afflist, - char_u *store_afflist) + char_u *store_afflist, + int *cntp) { char_u *p; char_u *prevp; - int cnt = 0; char_u key[AH_KEY_LEN]; hashitem_T *hi; @@ -3794,14 +3857,16 @@ get_compflags( // A flag is a compound flag if it appears in "af_comp". vim_strncpy(key, prevp, p - prevp); hi = hash_find(&affile->af_comp, key); - if (!HASHITEM_EMPTY(hi)) - store_afflist[cnt++] = HI2CI(hi)->ci_newID; + if (!HASHITEM_EMPTY(hi) + && store_afflist_add(store_afflist, cntp, + HI2CI(hi)->ci_newID) == FAIL) + return FAIL; } if (affile->af_flagtype == AFT_NUM && *p == ',') ++p; } - store_afflist[cnt] = NUL; + return OK; } /* @@ -3906,7 +3971,9 @@ store_aff_word( else p += STRLEN(ae->ae_chop); } - STRCAT(newword, p); + // Note: this silently truncates the buffer, but this should + // not happen in practice + STRNCAT(newword, p, MAXWLEN - STRLEN(newword) - 1); } else { @@ -3922,7 +3989,9 @@ store_aff_word( *p = NUL; } if (ae->ae_add != NULL) - STRCAT(newword, ae->ae_add); + // Note: this silently truncates the buffer, but this should + // not happen in practice + STRNCAT(newword, ae->ae_add, MAXWLEN - STRLEN(newword) - 1); } use_flags = flags; @@ -3955,10 +4024,20 @@ store_aff_word( if (affile->af_pfxpostpone || spin->si_compflags != NULL) { + int listlen = 0; + if (affile->af_pfxpostpone) + { // Get prefix IDS from the affix list. - use_pfxlen = get_pfxlist(affile, - ae->ae_flags, store_afflist); + if (get_pfxlist(affile, ae->ae_flags, + store_afflist, &listlen) + == FAIL) + { + retval = FAIL; + break; + } + use_pfxlen = listlen; + } else use_pfxlen = 0; use_pfxlist = store_afflist; @@ -3970,14 +4049,30 @@ store_aff_word( for (j = 0; j < use_pfxlen; ++j) if (pfxlist[i] == use_pfxlist[j]) break; - if (j == use_pfxlen) - use_pfxlist[use_pfxlen++] = pfxlist[i]; + if (j == use_pfxlen + && store_afflist_add(use_pfxlist, + &listlen, pfxlist[i]) + == FAIL) + { + retval = FAIL; + break; + } + use_pfxlen = listlen; } + if (retval == FAIL) + break; if (spin->si_compflags != NULL) // Get compound IDS from the affix list. - get_compflags(affile, ae->ae_flags, - use_pfxlist + use_pfxlen); + if (get_compflags(affile, ae->ae_flags, + use_pfxlist, &listlen) + == FAIL) + { + retval = FAIL; + break; + } + if (retval == FAIL) + break; // Combine the list of compound flags. // Concatenate them to the prefix IDs list. @@ -3988,12 +4083,17 @@ store_aff_word( use_pfxlist[j] != NUL; ++j) if (pfxlist[i] == use_pfxlist[j]) break; - if (use_pfxlist[j] == NUL) + if (use_pfxlist[j] == NUL + && store_afflist_add(use_pfxlist, + &listlen, pfxlist[i]) + == FAIL) { - use_pfxlist[j++] = pfxlist[i]; - use_pfxlist[j] = NUL; + retval = FAIL; + break; } } + if (retval == FAIL) + break; } } @@ -6208,6 +6308,7 @@ spell_add_word( char_u line[MAXWLEN * 2]; long fpos, fpos_next = 0; int i; + size_t linelen; char_u *spf; if (!valid_spell_word(word, word + len)) @@ -6284,7 +6385,9 @@ spell_add_word( fpos_next = ftell(fd); if (fpos_next < 0) break; // should never happen - if (STRNCMP(word, line, len) == 0 + linelen = STRLEN(line); + if (linelen >= (size_t)len + && STRNCMP(word, line, len) == 0 && (line[len] == '/' || line[len] < ' ')) { // Found duplicate word. Remove it by writing a '#' at diff --git a/src/strings.c b/src/strings.c index 82ebdb644d..ff63a3ef40 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1262,43 +1262,42 @@ blob_from_string(char_u *str, blob_T *blob) static int string_from_blob(blob_T *blob, long *start_idx, string_T *ret) { - garray_T str_ga; - long blen; - int idx; + long blen = blob_len(blob); + long start = *start_idx; + char_u *src; + char_u *nl; + long line_len; - ga_init2(&str_ga, sizeof(char), 80); - - blen = blob_len(blob); - - for (idx = *start_idx; idx < blen; idx++) - { - char_u byte = (char_u)blob_get(blob, idx); - if (byte == NL) - { - idx++; - break; - } - - if (byte == NUL) - byte = NL; - - ga_append(&str_ga, byte); - } - - if (str_ga.ga_data != NULL) - { - ret->string = vim_strnsave(str_ga.ga_data, str_ga.ga_len); - ret->length = str_ga.ga_len; - } - else + if (start >= blen) { ret->string = vim_strsave((char_u *)""); ret->length = 0; + *start_idx = blen; + return (ret->string == NULL) ? FAIL : OK; } - *start_idx = idx; - ga_clear(&str_ga); - return (ret->string == NULL) ? FAIL : OK; + src = (char_u *)blob->bv_ga.ga_data + start; + nl = (char_u *)memchr(src, NL, (size_t)(blen - start)); + line_len = (nl == NULL) ? (blen - start) : (long)(nl - src); + + ret->string = alloc(line_len + 1); + if (ret->string == NULL) + { + ret->length = 0; + return FAIL; + } + if (line_len > 0) + mch_memmove(ret->string, src, (size_t)line_len); + ret->string[line_len] = NUL; + ret->length = (size_t)line_len; + + // A NUL byte in the blob represents a NL in the resulting string. + for (long i = 0; i < line_len; i++) + if (ret->string[i] == NUL) + ret->string[i] = NL; + + *start_idx = start + line_len + (nl != NULL ? 1 : 0); + return OK; } /* @@ -1486,11 +1485,14 @@ f_blob2str(typval_T *argvars, typval_T *rettv) garray_T blob_ga; int nul_size = (from_prop & ENC_4BYTE) ? 4 : 2; ga_init2(&blob_ga, 1, blen + nul_size); - for (long i = 0; i < blen; i++) - ga_append(&blob_ga, (int)(unsigned char)blob_get(blob, i)); - // Add NUL terminator (2 bytes for UTF-16/UCS-2, 4 bytes for UTF-32/UCS-4) - for (int i = 0; i < nul_size; i++) - ga_append(&blob_ga, NUL); + if (ga_grow(&blob_ga, blen + nul_size) == OK) + { + if (blen > 0) + mch_memmove(blob_ga.ga_data, blob->bv_ga.ga_data, (size_t)blen); + // NUL terminator (2 bytes for UTF-16/UCS-2, 4 bytes for UTF-32/UCS-4) + vim_memset((char_u *)blob_ga.ga_data + blen, 0, (size_t)nul_size); + blob_ga.ga_len = blen + nul_size; + } // Convert the entire blob at once vimconv_T vimconv; @@ -1601,10 +1603,7 @@ f_str2blob(typval_T *argvars, typval_T *rettv) string_T str = {li->li_tv.vval.v_string, 0}; if (str.string == NULL) - { - str.string = (char_u *)""; - str.length = 0; - } + STR_LITERAL_SET(str, ""); else str.length = STRLEN(str.string); diff --git a/src/strptime.c b/src/strptime.c new file mode 100644 index 0000000000..0d1663cf03 --- /dev/null +++ b/src/strptime.c @@ -0,0 +1,806 @@ +/* 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. + */ + +/* + * strptime.c: portable strptime() fallback for platforms whose C runtime + * does not provide one (currently the MSVC / MinGW CRT on Windows). + * + * Ported from NetBSD's lib/libc/time/strptime.c (rev 1.67, 2024-06-07). + * The original BSD 2-clause licence follows below and must be preserved. + * Windows-specific adjustments: + * - Locale-specific weekday / month / AM-PM tables are hard-coded in + * English; this matches what strftime() emits in the "C" locale on + * Windows and is sufficient for Vim's strptime() test suite. + * - The NetBSD-specific fromzone()/tzalloc() path is stubbed out because + * the Windows CRT does not ship the IANA tzfile loader. + * - The tm_gmtoff / tm_zone BSD extensions are not available in the + * Windows CRT's struct tm, so the %Z / %z conversion parses the input + * without storing the offset (matching NetBSD behavior when those + * fields are not compiled in). + */ + +/*- + * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Klaus Klein. + * Heavily optimised by David Laight + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "vim.h" + +#ifdef MSWIN + +/* Constants lifted from NetBSD's . */ +#define TM_YEAR_BASE 1900 +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define SECSPERHOUR 3600 +#define SECSPERMIN 60 +#define HOURSPERDAY 24 + +#define isleap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) +/* isleap_sum avoids integer overflow when adding the 1900 base. */ +#define isleap_sum(a, b) \ + isleap(((unsigned)(a) + (unsigned)(b)) % 400) + +/* + * _get_tzname() is provided by the UCRT and by the MSVC CRT. Older MinGW + * builds linking against msvcrt.dll fall back to the deprecated tzname[] + * global (mingw-w64 already exposes the POSIX-named tzname[]). + */ +#if defined(_UCRT) || defined(_MSC_VER) +# define USE_GET_TZNAME +#endif + +/* Locale tables (English / "C" locale). */ +static const char *const c_day[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +}; +static const char *const c_abday[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; +static const char *const c_mon[] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; +static const char *const c_abmon[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; +static const char *const c_am_pm[] = { "AM", "PM" }; +static const char c_d_t_fmt[] = "%a %b %e %H:%M:%S %Y"; +static const char c_d_fmt[] = "%m/%d/%y"; +static const char c_t_fmt[] = "%H:%M:%S"; +static const char c_t_fmt_ampm[] = "%I:%M:%S %p"; + +static const unsigned char *conv_num(const unsigned char *, int *, + unsigned int, unsigned int); +static const unsigned char *find_string(const unsigned char *, int *, + const char * const *, const char * const *, int); + +/* + * We do not implement alternate representations. However, we always + * check whether a given modifier is allowed for a certain conversion. + */ +#define ALT_E 0x01 +#define ALT_O 0x02 +#define LEGAL_ALT(x) { if (alt_format & ~(x)) return NULL; } + +#define S_YEAR (1 << 0) +#define S_MON (1 << 1) +#define S_YDAY (1 << 2) +#define S_MDAY (1 << 3) +#define S_WDAY (1 << 4) +#define S_HOUR (1 << 5) + +#define HAVE_MDAY(s) (s & S_MDAY) +#define HAVE_MON(s) (s & S_MON) +#define HAVE_WDAY(s) (s & S_WDAY) +#define HAVE_YDAY(s) (s & S_YDAY) +#define HAVE_YEAR(s) (s & S_YEAR) +#define HAVE_HOUR(s) (s & S_HOUR) + +/* RFC-822/RFC-2822 */ +static const char *const nast[5] = { + "EST", "CST", "MST", "PST", "\0\0\0" +}; +static const char *const nadt[5] = { + "EDT", "CDT", "MDT", "PDT", "\0\0\0" +}; + +/* + * Table to determine the ordinal date for the start of a month. + * Ref: http://en.wikipedia.org/wiki/ISO_week_date + */ +static const int start_of_month[2][13] = { + /* non-leap year */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* leap year */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +/* + * Calculate the week day of the first day of a year. Valid for + * the Gregorian calendar, which began Sept 14, 1752 in the UK + * and its colonies. Ref: + * http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week + */ + static int +first_wday_of(int yr) +{ + return ((2 * (3 - (yr / 100) % 4)) + (yr % 100) + ((yr % 100) / 4) + + (isleap(yr) ? 6 : 0) + 1) % 7; +} + +#define delim(p) ((p) == '\0' || isspace((unsigned char)(p))) + +/* + * Stub replacing NetBSD's fromzone(): the Windows CRT does not provide + * tzalloc() / tzgetgmtoff() and the associated IANA tzfile loader, so + * we simply decline to recognize arbitrary timezone names. The %Z / %z + * numeric and RFC-822/2822 forms are still handled by the caller. + */ + static int +fromzone(const unsigned char **bp UNUSED, struct tm *tm UNUSED, + int mandatory UNUSED) +{ + return 0; +} + + char * +strptime(const char *buf, const char *fmt, struct tm *tm) +{ + unsigned char c; + const unsigned char *bp, *ep, *zname; + int alt_format, i, split_year = 0, neg = 0, state = 0, + day_offset = -1, week_offset = 0, offs, mandatory; + const char *new_fmt; + + bp = (const unsigned char *)buf; + + while (bp != NULL && (c = *fmt++) != '\0') + { + /* Clear `alternate' modifier prior to new conversion. */ + alt_format = 0; + i = 0; + + /* Eat up white-space. */ + if (isspace(c)) + { + while (isspace(*bp)) + bp++; + continue; + } + + if (c != '%') + goto literal; + + +again: switch (c = *fmt++) + { + case '%': /* "%%" is converted to "%". */ +literal: + if (c != *bp++) + return NULL; + LEGAL_ALT(0); + continue; + + /* + * "Alternative" modifiers. Just set the appropriate flag + * and start over again. + */ + case 'E': /* "%E?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_E; + goto again; + + case 'O': /* "%O?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_O; + goto again; + + /* + * "Complex" conversion rules, implemented through recursion. + */ + case 'c': /* Date and time, using the locale's format. */ + new_fmt = c_d_t_fmt; + state |= S_WDAY | S_MON | S_MDAY | S_YEAR; + goto recurse; + + case 'D': /* The date as "%m/%d/%y". */ + new_fmt = "%m/%d/%y"; + LEGAL_ALT(0); + state |= S_MON | S_MDAY | S_YEAR; + goto recurse; + + case 'F': /* The date as "%Y-%m-%d". */ + new_fmt = "%Y-%m-%d"; + LEGAL_ALT(0); + state |= S_MON | S_MDAY | S_YEAR; + goto recurse; + + case 'R': /* The time as "%H:%M". */ + new_fmt = "%H:%M"; + LEGAL_ALT(0); + goto recurse; + + case 'r': /* The time in 12-hour clock representation. */ + new_fmt = c_t_fmt_ampm; + LEGAL_ALT(0); + goto recurse; + + case 'T': /* The time as "%H:%M:%S". */ + new_fmt = "%H:%M:%S"; + LEGAL_ALT(0); + goto recurse; + + case 'X': /* The time, using the locale's format. */ + new_fmt = c_t_fmt; + goto recurse; + + case 'x': /* The date, using the locale's format. */ + new_fmt = c_d_fmt; + state |= S_MON | S_MDAY | S_YEAR; + recurse: + bp = (const unsigned char *)strptime((const char *)bp, + new_fmt, tm); + LEGAL_ALT(ALT_E); + continue; + + /* + * "Elementary" conversion rules. + */ + case 'A': /* The day of week, using the locale's form. */ + case 'a': + bp = find_string(bp, &tm->tm_wday, c_day, c_abday, 7); + LEGAL_ALT(0); + state |= S_WDAY; + continue; + + case 'B': /* The month, using the locale's form. */ + case 'b': + case 'h': + bp = find_string(bp, &tm->tm_mon, c_mon, c_abmon, 12); + LEGAL_ALT(0); + state |= S_MON; + continue; + + case 'C': /* The century number. */ + i = 20; + bp = conv_num(bp, &i, 0, 99); + + i = i * 100 - TM_YEAR_BASE; + if (split_year) + i += tm->tm_year % 100; + split_year = 1; + tm->tm_year = i; + LEGAL_ALT(ALT_E); + state |= S_YEAR; + continue; + + case 'd': /* The day of month. */ + case 'e': + bp = conv_num(bp, &tm->tm_mday, 1, 31); + LEGAL_ALT(ALT_O); + state |= S_MDAY; + continue; + + case 'k': /* The hour (24-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'H': + bp = conv_num(bp, &tm->tm_hour, 0, 23); + LEGAL_ALT(ALT_O); + state |= S_HOUR; + continue; + + case 'l': /* The hour (12-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'I': + bp = conv_num(bp, &tm->tm_hour, 1, 12); + if (tm->tm_hour == 12) + tm->tm_hour = 0; + LEGAL_ALT(ALT_O); + state |= S_HOUR; + continue; + + case 'j': /* The day of year. */ + i = 1; + bp = conv_num(bp, &i, 1, 366); + tm->tm_yday = i - 1; + LEGAL_ALT(0); + state |= S_YDAY; + continue; + + case 'M': /* The minute. */ + bp = conv_num(bp, &tm->tm_min, 0, 59); + LEGAL_ALT(ALT_O); + continue; + + case 'm': /* The month. */ + i = 1; + bp = conv_num(bp, &i, 1, 12); + tm->tm_mon = i - 1; + LEGAL_ALT(ALT_O); + state |= S_MON; + continue; + + case 'p': /* The locale's equivalent of AM/PM. */ + bp = find_string(bp, &i, c_am_pm, NULL, 2); + if (HAVE_HOUR(state) && tm->tm_hour > 11) + return NULL; + tm->tm_hour += i * 12; + LEGAL_ALT(0); + continue; + + case 'S': /* The seconds. */ + bp = conv_num(bp, &tm->tm_sec, 0, 61); + LEGAL_ALT(ALT_O); + continue; + + case 's': /* seconds since the epoch */ + { + const time_t TIME_MAX = (time_t)((sizeof(time_t) == 8) + ? LLONG_MAX : INT_MAX); + time_t sse, d; + + if (*bp < '0' || *bp > '9') + { + bp = NULL; + continue; + } + + sse = *bp++ - '0'; + while (*bp >= '0' && *bp <= '9') + { + d = *bp++ - '0'; + if (sse > TIME_MAX / 10) + { + bp = NULL; + break; + } + sse *= 10; + if (sse > TIME_MAX - d) + { + bp = NULL; + break; + } + sse += d; + } + if (bp == NULL) + continue; + + { + struct tm *lt = localtime(&sse); + + if (lt == NULL) + bp = NULL; + else + { + *tm = *lt; + state |= S_YDAY | S_WDAY | + S_MON | S_MDAY | S_YEAR; + } + } + continue; + } + + case 'U': /* The week of year, beginning on sunday. */ + case 'W': /* The week of year, beginning on monday. */ + /* + * This is bogus, as we can not assume any valid + * information present in the tm structure at this + * point to calculate a real value, so save the + * week for now in case it can be used later. + */ + bp = conv_num(bp, &i, 0, 53); + LEGAL_ALT(ALT_O); + if (c == 'U') + day_offset = TM_SUNDAY; + else + day_offset = TM_MONDAY; + week_offset = i; + continue; + + case 'w': /* The day of week, beginning on sunday. */ + bp = conv_num(bp, &tm->tm_wday, 0, 6); + LEGAL_ALT(ALT_O); + state |= S_WDAY; + continue; + + case 'u': /* The day of week, monday = 1. */ + bp = conv_num(bp, &i, 1, 7); + tm->tm_wday = i % 7; + LEGAL_ALT(ALT_O); + state |= S_WDAY; + continue; + + case 'g': /* ISO week year without century (parsed, ignored). */ + bp = conv_num(bp, &i, 0, 99); + continue; + + case 'G': /* ISO week year with century (parsed, ignored). */ + do + bp++; + while (isdigit(*bp)); + continue; + + case 'V': /* ISO 8601:1988 week number (parsed, ignored). */ + bp = conv_num(bp, &i, 1, 53); + continue; + + case 'Y': /* The year. */ + i = TM_YEAR_BASE; /* just for data sanity... */ + bp = conv_num(bp, &i, 0, 9999); + tm->tm_year = i - TM_YEAR_BASE; + LEGAL_ALT(ALT_E); + state |= S_YEAR; + continue; + + case 'y': /* The year within 100 years of the epoch. */ + /* LEGAL_ALT(ALT_E | ALT_O); */ + bp = conv_num(bp, &i, 0, 99); + + if (split_year) + /* preserve century */ + i += (tm->tm_year / 100) * 100; + else + { + split_year = 1; + if (i <= 68) + i = i + 2000 - TM_YEAR_BASE; + else + i = i + 1900 - TM_YEAR_BASE; + } + tm->tm_year = i; + state |= S_YEAR; + continue; + + case 'Z': + case 'z': + tzset(); + mandatory = c == 'z'; + /* + * We recognize all ISO 8601 formats: + * Z = Zulu time/UTC + * [+-]hhmm + * [+-]hh:mm + * [+-]hh + * We recognize all RFC-822/RFC-2822 formats: + * UT|GMT + * North American : UTC offsets + * E[DS]T = Eastern : -4 | -5 + * C[DS]T = Central : -5 | -6 + * M[DS]T = Mountain: -6 | -7 + * P[DS]T = Pacific : -7 | -8 + * Nautical/Military + * [A-IL-M] = -1 ... -9 (J not used) + * [N-Y] = +1 ... +12 + * Note: J maybe used to denote non-nautical + * local time + */ + if (mandatory) + while (isspace(*bp)) + bp++; + + zname = bp; + switch (*bp++) + { + case 'G': + if (*bp++ != 'M') + goto namedzone; + /*FALLTHROUGH*/ + case 'U': + if (*bp++ != 'T') + goto namedzone; + else if (!delim(*bp) && *bp++ != 'C') + goto namedzone; + /*FALLTHROUGH*/ + case 'Z': + if (!delim(*bp)) + goto namedzone; + tm->tm_isdst = 0; + continue; + case '+': + neg = 0; + break; + case '-': + neg = 1; + break; + default: +namedzone: + bp = zname; + + /* Nautical / Military style */ + if (delim(bp[1]) && + ((*bp >= 'A' && *bp <= 'I') || + (*bp >= 'L' && *bp <= 'Y'))) + { + bp++; + continue; + } + /* 'J' is local time */ + if (delim(bp[1]) && *bp == 'J') + { + bp++; + continue; + } + + /* + * From our 3 letter hard-coded table. + */ + if (delim(bp[0]) || delim(bp[1]) || + delim(bp[2]) || !delim(bp[3])) + goto loadzone; + ep = find_string(bp, &i, nast, NULL, 4); + if (ep != NULL) + { + bp = ep; + continue; + } + ep = find_string(bp, &i, nadt, NULL, 4); + if (ep != NULL) + { + tm->tm_isdst = 1; + bp = ep; + continue; + } + /* + * Our current timezone. Prefer _get_tzname() over the + * tzname[] global, which UCRT marks deprecated because it + * may be inaccurate after locale changes. + */ +#ifdef USE_GET_TZNAME + { + char tzbuf[2][32]; + const char *tznames[2] = { tzbuf[0], tzbuf[1] }; + size_t tzlen; + + _tzset(); + if (_get_tzname(&tzlen, tzbuf[0], sizeof(tzbuf[0]), 0) != 0) + tzbuf[0][0] = NUL; + if (_get_tzname(&tzlen, tzbuf[1], sizeof(tzbuf[1]), 1) != 0) + tzbuf[1][0] = NUL; + ep = find_string(bp, &i, tznames, NULL, 2); + } +#else + ep = find_string(bp, &i, + (const char *const *)tzname, NULL, 2); +#endif + if (ep != NULL) + { + tm->tm_isdst = i; + bp = ep; + continue; + } +loadzone: + /* + * The hard way, load the zone! + */ + if (fromzone(&bp, tm, mandatory)) + continue; + goto out; + } + offs = 0; + for (i = 0; i < 4; ) + { + if (isdigit(*bp)) + { + offs = offs * 10 + (*bp++ - '0'); + i++; + continue; + } + if (i == 2 && *bp == ':') + { + bp++; + continue; + } + break; + } + if (isdigit(*bp)) + goto out; + switch (i) + { + case 2: + offs *= SECSPERHOUR; + break; + case 4: + i = offs % 100; + offs /= 100; + if (i >= SECSPERMIN) + goto out; + /* Convert minutes into decimal */ + offs = offs * SECSPERHOUR + i * SECSPERMIN; + break; + default: +out: + if (mandatory) + return NULL; + bp = zname; + continue; + } + /* ISO 8601 & RFC 3339 limit to 23:59 max */ + if (offs >= (HOURSPERDAY * SECSPERHOUR)) + goto out; + if (neg) + offs = -offs; + tm->tm_isdst = 0; /* XXX */ + continue; + + /* + * Miscellaneous conversions. + */ + case 'n': /* Any kind of white-space. */ + case 't': + while (isspace(*bp)) + bp++; + LEGAL_ALT(0); + continue; + + + default: /* Unknown/unsupported conversion. */ + return NULL; + } + } + + if (!HAVE_YDAY(state) && HAVE_YEAR(state)) + { + if (HAVE_MON(state) && HAVE_MDAY(state)) + { + /* calculate day of year (ordinal date) */ + tm->tm_yday = start_of_month[isleap_sum(tm->tm_year, + TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1); + state |= S_YDAY; + } + else if (day_offset != -1) + { + /* + * Set the date to the first Sunday (or Monday) + * of the specified week of the year. + */ + if (!HAVE_WDAY(state)) + { + tm->tm_wday = day_offset; + state |= S_WDAY; + } + tm->tm_yday = (7 - + first_wday_of(tm->tm_year + TM_YEAR_BASE) + + day_offset) % 7 + (week_offset - 1) * 7 + + tm->tm_wday - day_offset; + state |= S_YDAY; + } + } + + if (HAVE_YDAY(state) && HAVE_YEAR(state)) + { + int leap; + + if (!HAVE_MON(state)) + { + /* calculate month of day of year */ + i = 0; + leap = isleap_sum(tm->tm_year, TM_YEAR_BASE); + while (tm->tm_yday >= start_of_month[leap][i]) + i++; + if (i > 12) + { + i = 1; + tm->tm_yday -= start_of_month[leap][12]; + tm->tm_year++; + } + tm->tm_mon = i - 1; + state |= S_MON; + } + + if (!HAVE_MDAY(state)) + { + /* calculate day of month */ + leap = isleap_sum(tm->tm_year, TM_YEAR_BASE); + tm->tm_mday = tm->tm_yday - + start_of_month[leap][tm->tm_mon] + 1; + state |= S_MDAY; + } + + if (!HAVE_WDAY(state)) + { + /* calculate day of week */ + i = 0; + week_offset = first_wday_of(tm->tm_year); + while (i++ <= tm->tm_yday) + { + if (week_offset++ >= 6) + week_offset = 0; + } + tm->tm_wday = week_offset; + state |= S_WDAY; + } + } + + return (char *)bp; +} + + + static const unsigned char * +conv_num(const unsigned char *buf, int *dest, unsigned int llim, + unsigned int ulim) +{ + unsigned int result = 0; + unsigned char ch; + + /* The limit also determines the number of valid digits. */ + unsigned int rulim = ulim; + + ch = *buf; + if (ch < '0' || ch > '9') + return NULL; + + do + { + result *= 10; + result += ch - '0'; + rulim /= 10; + ch = *++buf; + } while ((result * 10 <= ulim) && rulim && ch >= '0' && ch <= '9'); + + if (result < llim || result > ulim) + return NULL; + + *dest = result; + return buf; +} + + static const unsigned char * +find_string(const unsigned char *bp, int *tgt, const char *const *n1, + const char *const *n2, int c) +{ + int i; + size_t len; + + /* check full name - then abbreviated ones */ + for (; n1 != NULL; n1 = n2, n2 = NULL) + { + for (i = 0; i < c; i++, n1++) + { + len = strlen(*n1); + if (STRNICMP(*n1, bp, len) == 0) + { + *tgt = i; + return bp + len; + } + } + } + + /* Nothing matched */ + return NULL; +} + +#endif // MSWIN diff --git a/src/structs.h b/src/structs.h index a7a84ebf5c..a67bbe7333 100644 --- a/src/structs.h +++ b/src/structs.h @@ -349,6 +349,8 @@ typedef struct #define w_p_siso w_onebuf_opt.wo_siso // 'sidescrolloff' local value long wo_so; #define w_p_so w_onebuf_opt.wo_so // 'scrolloff' local value + long wo_sop; +#define w_p_sop w_onebuf_opt.wo_sop // 'scrolloffpad' local value #ifdef FEAT_TERMINAL char_u *wo_twk; # define w_p_twk w_onebuf_opt.wo_twk // 'termwinkey' @@ -676,6 +678,17 @@ typedef struct expand int xp_selected; // selected index in completion char_u *xp_orig; // originally expanded string char_u **xp_files; // list of files + char_u **xp_files_abbr; // optional parallel array of display + // strings (override xp_files for the + // pum text); NULL if unused + char_u **xp_files_kind; // optional parallel array of "kind" + // strings; NULL if unused + char_u **xp_files_menu; // optional parallel array of "menu" + // strings (shown after the match); + // NULL if unused + char_u **xp_files_info; // optional parallel array of "info" + // strings (shown in info popup); + // NULL if unused char_u *xp_line; // text being completed #define EXPAND_BUF_LEN 256 char_u xp_buf[EXPAND_BUF_LEN]; // buffer for returned match @@ -1436,6 +1449,27 @@ typedef struct int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID } stl_hlrec_T; +/* + * Used for statusline click function regions. + */ +typedef struct { + char_u *start; // position in output buffer where region starts + char_u *funcname; // function name (NULL = end/close marker) + int minwid; // minwid value from %N@Func@ +} stl_clickrec_T; + +/* + * Per-window resolved click regions (screen column based). + */ +typedef struct { + int row; // screen row where region lives + int col_start; // screen column where region starts + int col_end; // screen column where region ends + char_u *funcname; // function name (allocated copy) + int minwid; // minwid value + int tabnr; // tab page number (tabpanel only, 0 otherwise) +} stl_click_region_T; + /* * Syntax items - usually buffer-specific. @@ -2648,6 +2682,7 @@ typedef enum { CH_MODE_NL = 0, CH_MODE_RAW, + CH_MODE_BLOB, CH_MODE_JSON, CH_MODE_JS, CH_MODE_LSP, // Language Server Protocol (http + json) @@ -2763,6 +2798,13 @@ struct channel_S { void (*ch_nb_close_cb)(void); // callback for Netbeans when channel is // closed +#ifdef FEAT_SOCKETSERVER + bool ch_socketserver; // If channel is used by socketserver + void (*ch_ss_close_cb)(channel_T *); + void (*ch_ss_accept_cb)(channel_T *); + channel_T *ch_ss_next; + channel_T *ch_ss_prev; +#endif #ifdef MSWIN int ch_named_pipe; // using named pipe instead of pty @@ -3213,7 +3255,7 @@ struct file_buffer // b_sfname #ifdef UNIX - int b_dev_valid; // TRUE when b_dev has a valid number + bool b_dev_valid; // true when b_dev has a valid number dev_t b_dev; // device number ino_t b_ino; // inode number #endif @@ -3239,14 +3281,14 @@ struct file_buffer varnumber_T b_last_changedtick_pum; // b:changedtick for TextChangedP varnumber_T b_last_changedtick_i; // b:changedtick for TextChangedI - int b_saving; // Set to TRUE if we are in the middle of + bool b_saving; // Set to true if we are in the middle of // saving the buffer. /* * Changes to a buffer require updating of the display. To minimize the * work, remember changes made and update everything at once. */ - int b_mod_set; // TRUE when there are changes since the last + bool b_mod_set; // true when there are changes since the last // time the display was updated linenr_T b_mod_top; // topmost lnum that was changed linenr_T b_mod_bot; // lnum below last changed line, AFTER the @@ -3285,7 +3327,7 @@ struct file_buffer */ pos_T b_changelist[JUMPLISTSIZE]; int b_changelistlen; // number of active entries - int b_new_change; // set by u_savecommon() + bool b_new_change; // set in u_savecommon() /* * Character table, only used in charset.c for 'iskeyword' @@ -3307,12 +3349,12 @@ struct file_buffer pos_T b_op_end; #ifdef FEAT_VIMINFO - int b_marks_read; // Have we read viminfo marks yet? + bool b_marks_read; // Have we read viminfo marks yet? #endif - int b_modified_was_set; // did ":set modified" - int b_did_filetype; // FileType event found - int b_keep_filetype; // value for did_filetype when starting + bool b_modified_was_set; // did ":set modified" + bool b_did_filetype; // FileType event found + bool b_keep_filetype; // value for did_filetype when starting // to execute autocommands // Set by the apply_autocmds_group function if the given event is equal to @@ -3321,7 +3363,7 @@ struct file_buffer // // Relying on this value requires one to reset it prior calling // apply_autocmds_group(). - int b_au_did_filetype; + bool b_au_did_filetype; /* * The following only used in undo.c. @@ -3331,7 +3373,7 @@ struct file_buffer // if b_u_curhead is not NULL u_header_T *b_u_curhead; // pointer to current header int b_u_numhead; // current number of headers - int b_u_synced; // entry lists are synced + bool b_u_synced; // entry lists are synced long b_u_seq_last; // last used undo sequence number long b_u_save_nr_last; // counter for last file write long b_u_seq_cur; // uh_seq of header below which we are now @@ -3345,7 +3387,7 @@ struct file_buffer linenr_T b_u_line_lnum; // line number of line in u_line colnr_T b_u_line_colnr; // optional column number - int b_scanned; // ^N/^P have scanned this buffer + bool b_scanned; // ^N/^P have scanned this buffer // flags for use of ":lmap" and IM control long b_p_iminsert; // input mode for insert @@ -3368,7 +3410,7 @@ struct file_buffer * They are here because their value depends on the type of file * or contents of the file being edited. */ - int b_p_initialized; // set when options initialized + bool b_p_initialized; // set when options initialized #ifdef FEAT_EVAL sctx_T b_p_script_ctx[BV_COUNT]; // SCTXs for buffer-local options @@ -3594,7 +3636,7 @@ struct file_buffer list_T *b_recorded_changes; #endif #ifdef FEAT_PROP_POPUP - int b_has_textprop; // TRUE when text props were added + bool b_has_textprop; // true when text props were added hashtab_T *b_proptypes; // text property types local to buffer proptype_T **b_proparray; // entries of b_proptypes sorted on tp_id #endif @@ -3610,23 +3652,23 @@ struct file_buffer // When a buffer is created, it starts without a swap file. b_may_swap is // then set to indicate that a swap file may be opened later. It is reset // if a swap file could not be opened. - int b_may_swap; - int b_did_warn; // Set to 1 if user has been warned on first + bool b_may_swap; + bool b_did_warn; // Set to true if user has been warned on first // change of a read-only file // Two special kinds of buffers: // help buffer - used for help files, won't use a swap file. // spell buffer - used for spell info, never displayed and doesn't have a // file name. - int b_help; // TRUE for help file buffer (when set b_p_bt + bool b_help; // true for help file buffer (when set b_p_bt // is "help") #ifdef FEAT_SPELL - int b_spell; // TRUE for a spell file buffer, most fields + bool b_spell; // true for a spell file buffer, most fields // are not used! Use the B_SPELL macro to // access b_spell without #ifdef. #endif - int b_shortname; // this file has an 8.3 file name + bool b_shortname; // this file has an 8.3 file name #ifdef FEAT_JOB_CHANNEL char_u *b_prompt_text; // set by prompt_setprompt() @@ -3668,18 +3710,18 @@ struct file_buffer #ifdef FEAT_SIGNS sign_entry_T *b_signlist; // list of placed signs # ifdef FEAT_NETBEANS_INTG - int b_has_sign_column; // Flag that is set when a first sign is + bool b_has_sign_column; // Flag that is set when a first sign is // added and remains set until the end of // the netbeans session. # endif #endif #ifdef FEAT_NETBEANS_INTG - int b_netbeans_file; // TRUE when buffer is owned by NetBeans - int b_was_netbeans_file;// TRUE if b_netbeans_file was once set + bool b_netbeans_file; // true when buffer is owned by NetBeans + bool b_was_netbeans_file;// true if b_netbeans_file was once set #endif #ifdef FEAT_JOB_CHANNEL - int b_write_to_channel; // TRUE when appended lines are written to + bool b_write_to_channel; // true when appended lines are written to // a channel. #endif @@ -3700,7 +3742,7 @@ struct file_buffer // window. #endif #ifdef FEAT_DIFF - int b_diff_failed; // internal diff failed for this buffer + bool b_diff_failed; // internal diff failed for this buffer #endif }; // file_buffer @@ -4051,7 +4093,7 @@ struct window_S // used to try to stay in the same column // for up/down cursor motions. - int w_set_curswant; // If set, then update w_curswant the next + bool w_set_curswant; // If set, then update w_curswant the next // time through cursupdate() to the // current virtual column @@ -4082,7 +4124,7 @@ struct window_S */ linenr_T w_topline; // buffer line number of the line at the // top of the window - char w_topline_was_set; // flag set to TRUE when topline is set, + bool w_topline_was_set; // flag set to true when topline is set, // e.g. by winrestview() linenr_T w_botline; // number of the line below the bottom of @@ -4091,9 +4133,9 @@ struct window_S #ifdef FEAT_DIFF int w_topfill; // number of filler lines above w_topline int w_old_topfill; // w_topfill at last redraw - int w_botfill; // TRUE when filler lines are actually + bool w_botfill; // true when filler lines are actually // below w_topline (at end of file) - int w_old_botfill; // w_botfill at last redraw + bool w_old_botfill; // w_botfill at last redraw #endif colnr_T w_leftcol; // screen column number of the left most // character in the window; used when @@ -4129,6 +4171,8 @@ struct window_S int w_prev_height; // previous height used for 'splitkeep' int w_stl_rendered_height; // rendered height of window-local 'stl' // (number of "%@" + 1) + stl_click_region_T *w_stl_click; // statusline click regions + int w_stl_click_count; // number of click regions int w_status_height; // number of status lines. // If 'statuslineopt' was changed, this // member holds the previous value until @@ -4138,7 +4182,7 @@ struct window_S int w_vsep_width; // Number of separator columns (0 or 1). pos_save_T w_save_cursor; // backup of cursor pos and topline - int w_do_win_fix_cursor;// if TRUE cursor may be invalid + bool w_do_win_fix_cursor;// if true cursor may be invalid #ifdef FEAT_PROP_POPUP int w_popup_flags; // POPF_ values @@ -4146,7 +4190,7 @@ struct window_S int w_popup_handled; // POPUP_HANDLE[0-9] flags char_u *w_popup_title; poppos_T w_popup_pos; - int w_popup_fixed; // do not shift popup to fit on screen + bool w_popup_fixed; // do not shift popup to fit on screen int w_popup_prop_type; // when not zero: textprop type ID win_T *w_popup_prop_win; // window to search for textprop int w_popup_prop_id; // when not zero: textprop ID @@ -4160,18 +4204,26 @@ struct window_S int w_wantcol; // "col" for popup window int w_firstline; // "firstline" for popup window int w_want_scrollbar; // when zero don't use a scrollbar - int w_has_scrollbar; // 1 if scrollbar displayed, 0 otherwise + bool w_has_scrollbar; // true if scrollbar displayed char_u *w_scrollbar_highlight; // "scrollbarhighlight" char_u *w_thumb_highlight; // "thumbhighlight" int w_popup_padding[4]; // popup padding top/right/bot/left int w_popup_border[4]; // popup border top/right/bot/left char_u *w_border_highlight[4]; // popup border highlight - int w_border_highlight_isset; // borderhighlight was explicitly set + bool w_border_highlight_isset; // borderhighlight was explicitly set int w_border_char[8]; // popup border characters int w_popup_shadow; // popup shadow (right and bottom edges) int w_popup_leftoff; // columns left of the screen int w_popup_rightoff; // columns right of the screen + int w_popup_topoff; // rows above the host window's top + // when "clipwindow" is set + int w_popup_bottomoff; // rows below the host window's bottom + // when "clipwindow" is set + int w_popup_leftclip; // columns left of the host window's left + // when "clipwindow" is set + int w_popup_rightclip; // columns right of the host window's right + // when "clipwindow" is set varnumber_T w_popup_last_changedtick; // b:changedtick of popup buffer // when position was computed varnumber_T w_popup_prop_changedtick; // b:changedtick of buffer with @@ -4180,6 +4232,14 @@ struct window_S int w_popup_prop_topline; // w_topline of window with // w_popup_prop_type when position was // computed + int w_popup_prop_winrow; // w_winrow of host window when + // position was computed + int w_popup_prop_wincol; // w_wincol of host window when + // position was computed + int w_popup_prop_width; // w_width of host window when + // position was computed + int w_popup_prop_winheight; // w_height of host window when + // position was computed linenr_T w_popup_last_curline; // last known w_cursor.lnum of window // with "cursorline" set callback_T w_close_cb; // popup close callback @@ -4233,7 +4293,7 @@ struct window_S */ int w_cline_height; // current size of cursor line #ifdef FEAT_FOLDING - int w_cline_folded; // cursor line is folded + bool w_cline_folded; // cursor line is folded #endif int w_cline_row; // starting row of the cursor line @@ -4272,9 +4332,9 @@ struct window_S #ifdef FEAT_FOLDING garray_T w_folds; // array of nested folds - char w_fold_manual; // when TRUE: some folds are opened/closed + bool w_fold_manual; // when true: some folds are opened/closed // manually - char w_foldinvalid; // when TRUE: folding needs to be + bool w_foldinvalid; // when true: folding needs to be // recomputed #endif #ifdef FEAT_LINEBREAK @@ -4294,7 +4354,7 @@ struct window_S // w_redr_type is UPD_REDRAW_TOP linenr_T w_redraw_top; // when != 0: first line needing redraw linenr_T w_redraw_bot; // when != 0: last line needing redraw - int w_redr_status; // if TRUE status line must be redrawn + bool w_redr_status; // if true status line must be redrawn // remember what is shown in the ruler for this window (if 'ruler' set) pos_T w_ru_cursor; // cursor position shown in ruler @@ -4304,14 +4364,14 @@ struct window_S #ifdef FEAT_DIFF int w_ru_topfill; // topfill shown in ruler #endif - char w_ru_empty; // TRUE if ruler shows 0-1 (empty line) + bool w_ru_empty; // true if ruler shows 0-1 (empty line) int w_alt_fnum; // alternate file (for # and CTRL-^) alist_T *w_alist; // pointer to arglist for this window int w_arg_idx; // current index in argument list (can be // out of range!) - int w_arg_idx_invalid; // editing another file than w_arg_idx + bool w_arg_idx_invalid; // editing another file than w_arg_idx char_u *w_localdir; // absolute path of local directory or // NULL diff --git a/src/tabpanel.c b/src/tabpanel.c index 2a6dbe8318..f7889a5e59 100644 --- a/src/tabpanel.c +++ b/src/tabpanel.c @@ -17,6 +17,10 @@ static void do_by_tplmode(int tplmode, int col_start, int col_end, int *pcurtab_row, int *ptabpagenr); +static void tabpanel_free_click_regions(void); +static void tabpanel_append_click_regions(stl_clickrec_T *clicktab, + char_u *buf, int row, int col_start, int col_end, int tabnr); +static void draw_tabpanel_scrollbar(int screen_col); // set pcurtab_row. don't redraw tabpanel. #define TPLMODE_GET_CURTAB_ROW 0 @@ -28,6 +32,7 @@ static void do_by_tplmode(int tplmode, int col_start, int col_end, #define TPL_FILLCHAR ' ' #define VERT_LEN 1 +#define SCROLL_LEN 1 // tpl_align's values #define ALIGN_LEFT 0 @@ -37,7 +42,12 @@ static char_u *opt_name = (char_u *)"tabpanel"; static int opt_scope = OPT_LOCAL; static int tpl_align = ALIGN_LEFT; static int tpl_columns = 20; -static int tpl_is_vert = FALSE; +static bool tpl_is_vert = false; +static bool tpl_scrollbar = false; +static int tpl_scroll_offset = 0; +static int tpl_total_rows = 0; +static int tpl_scrollbar_col = -1; // screen column of scrollbar, -1 if none +static tabpage_T *tpl_last_curtab = NULL; // last curtab seen by draw_tabpanel typedef struct { win_T *wp; @@ -58,7 +68,8 @@ tabpanelopt_changed(void) char_u *p; int new_align = ALIGN_LEFT; long new_columns = 20; - int new_is_vert = FALSE; + bool new_is_vert = false; + bool new_scrollbar = false; p = p_tplo; while (*p != NUL) @@ -89,7 +100,12 @@ tabpanelopt_changed(void) else if (STRNCMP(p, "vert", 4) == 0) { p += 4; - new_is_vert = TRUE; + new_is_vert = true; + } + else if (STRNCMP(p, "scrollbar", 9) == 0) + { + p += 9; + new_scrollbar = true; } if (*p != ',' && *p != NUL) @@ -101,11 +117,26 @@ tabpanelopt_changed(void) tpl_align = new_align; tpl_columns = new_columns; tpl_is_vert = new_is_vert; + tpl_scrollbar = new_scrollbar; + + // Re-center the current tab on the next redraw. + tpl_last_curtab = NULL; shell_new_columns(); return OK; } +/* + * Drop any internal reference to "tp", so draw_tabpanel() never compares + * against a dangling pointer after the tabpage has been freed. + */ + void +tabpanel_forget_tabpage(const tabpage_T *tp) +{ + if (tpl_last_curtab == tp) + tpl_last_curtab = NULL; +} + /* * Return the width of tabpanel. */ @@ -135,6 +166,133 @@ tabpanel_leftcol(void) return tpl_align == ALIGN_RIGHT ? 0 : tabpanel_width(); } +/* + * Free previously resolved 'tabpanel' click regions. + */ + static void +tabpanel_free_click_regions(void) +{ + int n; + + if (tabpanel_stl_click != NULL) + { + for (n = 0; n < tabpanel_stl_click_count; n++) + vim_free(tabpanel_stl_click[n].funcname); + VIM_CLEAR(tabpanel_stl_click); + } + tabpanel_stl_click_count = 0; +} + +/* + * Convert click records produced by build_stl_str_hl() for one line of + * 'tabpanel' into screen-column based regions and append them to the global + * tabpanel_stl_click array. The caller keeps ownership of the funcname + * strings inside "clicktab" — this function makes its own copies. + */ + static void +tabpanel_append_click_regions( + stl_clickrec_T *clicktab, + char_u *buf, + int row, + int col_start, + int col_end, + int tabnr) +{ + int count = 0; + int n; + int base_col; + int acc_width = 0; + int max_w = col_end - col_start; + char_u *p; + char_u *cur_funcname = NULL; + int cur_minwid = 0; + int region_start_col; + stl_click_region_T *new_arr; + int limit; + + if (clicktab == NULL) + return; + + for (n = 0; clicktab[n].start != NULL; n++) + count++; + if (count == 0) + return; + + base_col = (tpl_align == ALIGN_RIGHT ? topframe->fr_width : 0) + col_start; + region_start_col = base_col; + + // Grow the global array to make room for up to "count" more regions + // (one close for each record plus a possible trailing region). + new_arr = vim_realloc(tabpanel_stl_click, + sizeof(stl_click_region_T) * (tabpanel_stl_click_count + count + 1)); + if (new_arr == NULL) + return; + tabpanel_stl_click = new_arr; + + p = buf; + for (n = 0; clicktab[n].start != NULL; n++) + { + acc_width += vim_strnsize(p, (int)(clicktab[n].start - p)); + p = clicktab[n].start; + limit = acc_width < max_w ? acc_width : max_w; + + if (cur_funcname != NULL) + { + stl_click_region_T *r = + &tabpanel_stl_click[tabpanel_stl_click_count]; + r->row = row; + r->col_start = region_start_col; + r->col_end = base_col + limit; + r->funcname = vim_strsave(cur_funcname); + r->minwid = cur_minwid; + r->tabnr = tabnr; + tabpanel_stl_click_count++; + } + + cur_funcname = clicktab[n].funcname; + cur_minwid = clicktab[n].minwid; + region_start_col = base_col + limit; + } + + // Close the final region if it extends to the end. + if (cur_funcname != NULL) + { + stl_click_region_T *r = &tabpanel_stl_click[tabpanel_stl_click_count]; + r->row = row; + r->col_start = region_start_col; + r->col_end = base_col + max_w; + r->funcname = vim_strsave(cur_funcname); + r->minwid = cur_minwid; + r->tabnr = tabnr; + tabpanel_stl_click_count++; + } +} + +/* + * Ensure the current tab is visible by adjusting tpl_scroll_offset when + * the selected tab has changed since the previous redraw. Mouse wheel or + * scrollbar drag operations leave curtab unchanged, so the user's chosen + * offset is preserved in those cases. + */ + static void +follow_curtab_if_needed(int curtab_row) +{ + if (Rows <= 0 || curtab == tpl_last_curtab) + return; + + if (curtab_row < tpl_scroll_offset) + tpl_scroll_offset = curtab_row; + else if (curtab_row >= tpl_scroll_offset + Rows) + tpl_scroll_offset = curtab_row - Rows + 1; + + int max_offset = tpl_total_rows > Rows ? tpl_total_rows - Rows : 0; + + if (tpl_scroll_offset < 0) + tpl_scroll_offset = 0; + else if (tpl_scroll_offset > max_offset) + tpl_scroll_offset = max_offset; +} + /* * draw the tabpanel. */ @@ -150,49 +308,92 @@ draw_tabpanel(void) int is_right = tpl_align == ALIGN_RIGHT; if (maxwidth == 0) + { + tabpanel_free_click_regions(); return; + } + + // Discard old click regions — they'll be rebuilt during redraw below. + tabpanel_free_click_regions(); // Reset got_int to avoid build_stl_str_hl() isn't evaluated. got_int = FALSE; + int sb_len = tpl_scrollbar ? SCROLL_LEN : 0; + int sb_screen_col = -1; + + // The scrollbar is always placed at the right edge of the tabpanel, + // regardless of 'align'. The vertical separator sits at the panel's + // boundary with the buffer area (left edge for align:right, right edge + // for align:left). if (tpl_is_vert) { if (is_right) { - // draw main contents in tabpanel + // Panel on the right: vert at panel's left edge, scrollbar at + // panel's right edge (= screen's right edge). do_by_tplmode(TPLMODE_GET_CURTAB_ROW, VERT_LEN, - maxwidth - VERT_LEN, &curtab_row, NULL); - do_by_tplmode(TPLMODE_REDRAW, VERT_LEN, maxwidth, &curtab_row, - NULL); - // draw vert separator in tabpanel + maxwidth - sb_len, &curtab_row, NULL); + follow_curtab_if_needed(curtab_row); + do_by_tplmode(TPLMODE_REDRAW, VERT_LEN, maxwidth - sb_len, + &curtab_row, NULL); for (vsrow = 0; vsrow < Rows; vsrow++) screen_putchar(curwin->w_fill_chars.tpl_vert, vsrow, topframe->fr_width, vs_attr); + if (tpl_scrollbar) + sb_screen_col = topframe->fr_width + maxwidth - SCROLL_LEN; } else { - // draw main contents in tabpanel - do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, maxwidth - VERT_LEN, + // Panel on the left: scrollbar just left of vert, vert at + // panel's right edge (boundary with buffer). + do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, + maxwidth - VERT_LEN - sb_len, &curtab_row, NULL); + follow_curtab_if_needed(curtab_row); + do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth - VERT_LEN - sb_len, &curtab_row, NULL); - do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth - VERT_LEN, - &curtab_row, NULL); - // draw vert separator in tabpanel for (vsrow = 0; vsrow < Rows; vsrow++) screen_putchar(curwin->w_fill_chars.tpl_vert, vsrow, maxwidth - VERT_LEN, vs_attr); + if (tpl_scrollbar) + sb_screen_col = maxwidth - VERT_LEN - SCROLL_LEN; } } else { - do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, maxwidth, &curtab_row, NULL); - do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth, &curtab_row, NULL); + if (is_right) + { + // Panel on the right, no vert: scrollbar at screen's right edge. + do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, maxwidth - sb_len, + &curtab_row, NULL); + follow_curtab_if_needed(curtab_row); + do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth - sb_len, + &curtab_row, NULL); + if (tpl_scrollbar) + sb_screen_col = topframe->fr_width + maxwidth - SCROLL_LEN; + } + else + { + do_by_tplmode(TPLMODE_GET_CURTAB_ROW, 0, maxwidth - sb_len, + &curtab_row, NULL); + follow_curtab_if_needed(curtab_row); + do_by_tplmode(TPLMODE_REDRAW, 0, maxwidth - sb_len, + &curtab_row, NULL); + if (tpl_scrollbar) + sb_screen_col = maxwidth - SCROLL_LEN; + } } + tpl_scrollbar_col = sb_screen_col; + if (sb_screen_col >= 0) + draw_tabpanel_scrollbar(sb_screen_col); + got_int |= saved_got_int; // A user function may reset KeyTyped, restore it. KeyTyped = saved_KeyTyped; + tpl_last_curtab = curtab; redraw_tabpanel = FALSE; } @@ -445,8 +646,7 @@ do_by_tplmode( args.col_end = col_end; if (tplmode != TPLMODE_GET_CURTAB_ROW && args.maxrow > 0) - while (args.offsetrow + args.maxrow <= *pcurtab_row) - args.offsetrow += args.maxrow; + args.offsetrow = tpl_scroll_offset; tp = first_tabpage; @@ -466,11 +666,9 @@ do_by_tplmode( { args.attr = attr_tpls; if (tplmode == TPLMODE_GET_CURTAB_ROW) - { + // Capture the row of the current tab and keep iterating so + // tpl_total_rows receives the true content height below. *pcurtab_row = row; - do_unlet((char_u *)"g:actual_curtabpage", TRUE); - break; - } } else args.attr = attr_tpl; @@ -490,13 +688,17 @@ do_by_tplmode( if (usefmt != NULL && *usefmt != NUL) { + int carry_hl = 0; + while (*usefmt != NUL) { char_u buf[IOSIZE]; stl_hlrec_T *hltab; stl_hlrec_T *tabtab; + stl_clickrec_T *clicktab = NULL; - if (args.maxrow <= row - args.offsetrow) + if (tplmode != TPLMODE_GET_CURTAB_ROW + && args.maxrow <= row - args.offsetrow) break; buf[0] = NUL; @@ -507,13 +709,33 @@ do_by_tplmode( #endif (args.cwp, buf, sizeof(buf), &usefmt, opt_name, opt_scope, TPL_FILLCHAR, - args.col_end - args.col_start, &hltab, &tabtab); + args.col_end - args.col_start, &hltab, &tabtab, + tplmode == TPLMODE_REDRAW ? &clicktab : NULL, + &carry_hl); args.prow = &row; args.pcol = &col; draw_tabpanel_with_highlight(tplmode, buf, hltab, &args); + // Record any %[FuncName] click regions for this line once + // the text has been drawn. Only visible rows participate. + if (tplmode == TPLMODE_REDRAW && clicktab != NULL) + { + int screen_row = row - args.offsetrow; + int m; + + if (screen_row >= 0 && screen_row < args.maxrow) + tabpanel_append_click_regions(clicktab, buf, + screen_row, args.col_start, args.col_end, + (int)v.vval.v_number); + // We took ownership of the click records — free the + // function names (matches the non-NULL clicktab path in + // build_stl_str_hl()). + for (m = 0; clicktab[m].start != NULL; m++) + vim_free(clicktab[m].funcname); + } + // Move to next line for %@ if (*usefmt != NUL) { @@ -546,6 +768,250 @@ do_by_tplmode( // fill the area of TabPanelFill. screen_fill_tailing_area(tplmode, MAX(row - args.offsetrow, 0), args.maxrow, args.col_start, args.col_end, attr_tplf); + + // Capture the true content height during the GET_CURTAB_ROW pass, which + // ignores maxrow and therefore walks every tab. REDRAW stops at the + // visible edge so its "row" is clamped and unusable here. + if (tplmode == TPLMODE_GET_CURTAB_ROW) + tpl_total_rows = row; +} + +/* + * Draw the tabpanel scrollbar (track + thumb) at screen column 'screen_col'. + * The scrollbar spans the full screen height. The thumb position and size + * are derived from tpl_scroll_offset, tpl_total_rows and Rows. + */ + static void +draw_tabpanel_scrollbar(int screen_col) +{ + int attr_sb = HL_ATTR(HLF_PSB); + int attr_thumb = HL_ATTR(HLF_PST); + int thumb_top = 0; + int thumb_height = 0; + + if (tpl_total_rows > Rows && Rows > 0) + { + int max_offset = tpl_total_rows - Rows; + int track_range; + + thumb_height = Rows * Rows / tpl_total_rows; + if (thumb_height < 1) + thumb_height = 1; + + // Map tpl_scroll_offset onto the track: at offset 0 the thumb's top + // is at row 0, at the maximum offset its bottom reaches the last + // row. This is the exact inverse of tabpanel_drag_scrollbar(). + track_range = Rows - thumb_height; + if (track_range > 0 && max_offset > 0) + thumb_top = track_range * tpl_scroll_offset / max_offset; + else + thumb_top = 0; + if (thumb_top + thumb_height > Rows) + thumb_top = Rows - thumb_height; + if (thumb_top < 0) + thumb_top = 0; + } + + for (int r = 0; r < Rows; r++) + { + bool on_thumb = thumb_height > 0 + && r >= thumb_top && r < thumb_top + thumb_height; + screen_putchar(TPL_FILLCHAR, r, screen_col, + on_thumb ? attr_thumb : attr_sb); + } +} + +/* + * Return true if the mouse is currently positioned over the tabpanel area. + */ + bool +mouse_on_tabpanel(void) +{ + if (tabpanel_width() == 0) + return false; + return mouse_col < firstwin->w_wincol + || mouse_col >= firstwin->w_wincol + topframe->fr_width; +} + +/* + * Return true if the mouse is currently on the scrollbar column. + * The scrollbar column is tracked by draw_tabpanel() and is -1 when the + * scrollbar is not enabled or not yet drawn. + */ + bool +mouse_on_tabpanel_scrollbar(void) +{ + return tpl_scrollbar && tpl_scrollbar_col >= 0 + && mouse_col == tpl_scrollbar_col; +} + +/* + * Move the scrollbar thumb so it is vertically centred on screen row + * 'screen_row', updating tpl_scroll_offset accordingly. Used for both + * initial clicks and subsequent drag events. + * Returns true if the event was consumed (offset changed or not). + */ + bool +tabpanel_drag_scrollbar(int screen_row) +{ + int thumb_height; + int max_offset; + int track_range; + int thumb_top; + int new_offset; + + if (!tpl_scrollbar || Rows <= 0 || tpl_total_rows <= Rows) + return false; + + thumb_height = Rows * Rows / tpl_total_rows; + if (thumb_height < 1) + thumb_height = 1; + track_range = Rows - thumb_height; + if (track_range <= 0) + return true; + + max_offset = tpl_total_rows - Rows; + thumb_top = screen_row - thumb_height / 2; + if (thumb_top < 0) + thumb_top = 0; + if (thumb_top > track_range) + thumb_top = track_range; + + new_offset = thumb_top * max_offset / track_range; + if (new_offset != tpl_scroll_offset) + { + tpl_scroll_offset = new_offset; + redraw_tabpanel = TRUE; + } + return true; +} + +/* + * Scroll the tabpanel by 'count' rows in direction 'dir' (1 = down, -1 = up). + * Returns true if the offset changed and a redraw was scheduled. + */ + bool +tabpanel_scroll(int dir, int count) +{ + int max_offset; + int new_offset; + + if (tabpanel_width() == 0) + return false; + + max_offset = tpl_total_rows - Rows; + if (max_offset < 0) + max_offset = 0; + + new_offset = tpl_scroll_offset + (dir > 0 ? count : -count); + if (new_offset < 0) + new_offset = 0; + if (new_offset > max_offset) + new_offset = max_offset; + if (new_offset == tpl_scroll_offset) + return false; + + tpl_scroll_offset = new_offset; + redraw_tabpanel = TRUE; + return true; +} + +/* + * Set the tabpanel scroll offset to "offset" (clamped to the valid range). + * Returns true if the offset changed and a redraw was scheduled. + */ + bool +tabpanel_set_offset(int offset) +{ + int max_offset; + + if (tabpanel_width() == 0) + return false; + + max_offset = tpl_total_rows - Rows; + if (max_offset < 0) + max_offset = 0; + + if (offset < 0) + offset = 0; + if (offset > max_offset) + offset = max_offset; + if (offset == tpl_scroll_offset) + return false; + + tpl_scroll_offset = offset; + redraw_tabpanel = TRUE; + return true; +} + +/* + * "tabpanel_getinfo()" function + */ + void +f_tabpanel_getinfo(typval_T *argvars UNUSED, typval_T *rettv) +{ + dict_T *d; + int max_offset; + + if (rettv_dict_alloc(rettv) == FAIL) + return; + d = rettv->vval.v_dict; + + max_offset = tpl_total_rows - Rows; + if (max_offset < 0) + max_offset = 0; + + dict_add_string(d, "align", + (char_u *)(tpl_align == ALIGN_RIGHT ? "right" : "left")); + dict_add_number(d, "columns", tabpanel_width()); + dict_add_bool(d, "scrollbar", tpl_scrollbar); + dict_add_number(d, "offset", tpl_scroll_offset); + dict_add_number(d, "total", tpl_total_rows); + dict_add_number(d, "max_offset", max_offset); +} + +/* + * "tabpanel_scroll()" function + */ + void +f_tabpanel_scroll(typval_T *argvars, typval_T *rettv) +{ + varnumber_T n; + int absolute = 0; + bool changed; + + rettv->v_type = VAR_BOOL; + rettv->vval.v_number = VVAL_FALSE; + + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_opt_dict_arg(argvars, 1) == FAIL)) + return; + + n = tv_get_number_chk(&argvars[0], NULL); + if (argvars[1].v_type != VAR_UNKNOWN) + { + if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) + { + emsg(_(e_dictionary_required)); + return; + } + absolute = dict_get_bool(argvars[1].vval.v_dict, "absolute", FALSE); + } + + // Clamp to int range to avoid signed overflow when casting and negating. + if (n > INT_MAX) + n = INT_MAX; + else if (n < -INT_MAX) + n = -INT_MAX; + + if (absolute) + changed = tabpanel_set_offset((int)n); + else + changed = tabpanel_scroll(n >= 0 ? 1 : -1, + (int)(n >= 0 ? n : -n)); + + rettv->vval.v_number = changed ? VVAL_TRUE : VVAL_FALSE; } #endif // FEAT_TABPANEL diff --git a/src/tag.c b/src/tag.c index d3e27e6023..24d33bc11d 100644 --- a/src/tag.c +++ b/src/tag.c @@ -476,7 +476,7 @@ do_tag( curwin->w_cursor.lnum = saved_fmark.mark.lnum; } curwin->w_cursor.col = saved_fmark.mark.col; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; check_cursor(); #ifdef FEAT_FOLDING if ((fdo_flags & FDO_TAG) && old_KeyTyped) @@ -3080,7 +3080,7 @@ find_tags( int save_emsg_off; - int help_save; + bool help_save; #ifdef FEAT_MULTI_LANG int i; char_u *saved_pat = NULL; // copy of pat[] @@ -3122,13 +3122,13 @@ find_tags( * Initialize a few variables */ if (st.help_only) // want tags from help file - curbuf->b_help = TRUE; // will be restored later + curbuf->b_help = true; // will be restored later #ifdef FEAT_CSCOPE else if (use_cscope) { // Make sure we don't mix help and cscope, confuses Coverity. st.help_only = FALSE; - curbuf->b_help = FALSE; + curbuf->b_help = false; } #endif @@ -3898,7 +3898,7 @@ jumpto_tag( if (GETFILE_SUCCESS(getfile_result)) // got to the right file { - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; postponed_split = 0; save_magic_overruled = magic_overruled; @@ -4135,10 +4135,21 @@ expand_tag_fname(char_u *fname, char_u *tag_fname, int expand) char_u *expanded_fname = NULL; expand_T xpc; + // Refuse to follow URLs from tag files unless 'tagsecure' is false. + // Tag entries are expected to reference local source files; a URL would + // otherwise be passed to netrw and trigger a network request. + if (p_tagsecure && path_with_url(fname)) + { + emsg(_(e_tag_file_entry_must_not_be_url)); + return NULL; + } + /* * Expand file name (for environment variables) when needed. + * Disallow backticks, they could execute arbitrary shell + * commands. This is not needed for tag filenames. */ - if (expand && mch_has_wildcard(fname)) + if (expand && mch_has_wildcard(fname) && vim_strchr(fname, '`') == NULL) { ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; diff --git a/src/term.c b/src/term.c index e72e658338..d60465e41d 100644 --- a/src/term.c +++ b/src/term.c @@ -154,6 +154,9 @@ static termrequest_T rcs_status = TERMREQUEST_INIT; // Request window's position report: static termrequest_T winpos_status = TERMREQUEST_INIT; +// Request DECRQM (DEC mode) report: +static termrequest_T decrqm_status = TERMREQUEST_INIT; + static termrequest_T *all_termrequests[] = { &crv_status, &u7_status, @@ -165,6 +168,7 @@ static termrequest_T *all_termrequests[] = { &rbm_status, &rcs_status, &winpos_status, + &decrqm_status, NULL }; @@ -686,15 +690,17 @@ static tcap_entry_T builtin_sync_output[] = { }; #endif +#ifdef FEAT_TERMRESPONSE /* * List of DECRQM modes that Vim supports */ static const int dec_modes[] = { 2026, // Synchronized output -#ifdef UNIX +# ifdef UNIX 2048 // In-band terminal resize events -#endif +# endif }; +#endif #ifdef FEAT_TERMGUICOLORS /* @@ -1545,8 +1551,10 @@ typedef struct { #define TPR_MOUSE 3 // term response indicates kitty #define TPR_KITTY 4 +// can send DECRQM requests to terminal +#define TPR_DECRQM 5 // table size -#define TPR_COUNT 5 +#define TPR_COUNT 6 static termprop_T term_props[TPR_COUNT]; @@ -1570,6 +1578,8 @@ init_term_props(int all) term_props[TPR_MOUSE].tpr_set_by_termresponse = TRUE; term_props[TPR_KITTY].tpr_name = "kitty"; term_props[TPR_KITTY].tpr_set_by_termresponse = FALSE; + term_props[TPR_DECRQM].tpr_name = "decrqm"; + term_props[TPR_DECRQM].tpr_set_by_termresponse = TRUE; for (i = 0; i < TPR_COUNT; ++i) if (all || term_props[i].tpr_set_by_termresponse) @@ -1593,7 +1603,8 @@ f_terminalprops(typval_T *argvars UNUSED, typval_T *rettv) value[0] = term_props[i].tpr_status; value[1] = NUL; - dict_add_string(rettv->vval.v_dict, term_props[i].tpr_name, value); + dict_add_string_len(rettv->vval.v_dict, term_props[i].tpr_name, + value, (value[0] == NUL) ? 0 : 1); } # endif } @@ -5182,16 +5193,21 @@ handle_version_response(int first, int *arg, int argc, char_u *tp) if (version == 95) { // Mac Terminal.app sends 1;95;0 + // + // Terminal.app doesn't seem to handle DECRQM sequences + // properly, see issue #19852. if (arg[0] == 1 && arg[2] == 0) { term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; + term_props[TPR_DECRQM].tpr_status = TPR_NO; } // iTerm2 sends 0;95;0 else if (arg[0] == 0 && arg[2] == 0) { // iTerm2 can do SGR mouse reporting term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; + term_props[TPR_DECRQM].tpr_status = TPR_YES; } // old iTerm2 sends 0;95; else if (arg[0] == 0 && arg[2] == -1) @@ -5229,7 +5245,9 @@ handle_version_response(int first, int *arg, int argc, char_u *tp) // Assuming any version number over 2500 is not an // xterm (without the limit for rxvt and screen). if (arg[1] >= 2500) + { term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; + } else if (version == 136 && arg[2] == 0) { @@ -5257,6 +5275,7 @@ handle_version_response(int first, int *arg, int argc, char_u *tp) // Kitty can handle SGR mouse reporting. term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; + term_props[TPR_DECRQM].tpr_status = TPR_YES; } // GNU screen sends 83;30600;0, 83;40500;0, etc. @@ -5267,6 +5286,9 @@ handle_version_response(int first, int *arg, int argc, char_u *tp) { term_props[TPR_CURSOR_STYLE].tpr_status = TPR_NO; term_props[TPR_CURSOR_BLINK].tpr_status = TPR_NO; + term_props[TPR_DECRQM].tpr_status = TPR_NO; // screen doesn't seem + // to handle DECRQM + // sequences } // Xterm first responded to this request at patch level @@ -5350,6 +5372,23 @@ handle_version_response(int first, int *arg, int argc, char_u *tp) need_flush = TRUE; } + // Only request DEC modes via DECRQM when the terminal is known to + // handle it. Not for Apple Terminal.app or GNU screen, they echo + // the trailing "p" to the screen. See issue #19852. + if (decrqm_status.tr_progress == STATUS_GET + && term_props[TPR_DECRQM].tpr_status == TPR_YES) + { + MAY_WANT_TO_LOG_THIS; + LOG_TR1("Sending DECRQM requests"); + for (int i = 0; i < (int)ARRAY_LENGTH(dec_modes); i++) + { + vim_snprintf((char *)IObuff, IOSIZE, "\033[?%d$p", dec_modes[i]); + out_str(IObuff); + } + termrequest_sent(&decrqm_status); + need_flush = TRUE; + } + if (need_flush) out_flush(); #endif @@ -5758,6 +5797,13 @@ handle_csi( key_name[0] = (int)KS_EXTRA; key_name[1] = (int)KE_IGNORE; +#ifdef FEAT_TERMRESPONSE + // Mark the DECRQM request as answered so it is not sent again and + // stoptermcap() does not wait for it. + if (decrqm_status.tr_progress == STATUS_SENT) + decrqm_status.tr_progress = STATUS_GOT; +#endif + if (setting >= 0 && setting <= 4) { LOG_TRN("Received DECRPM mode %d: %s", arg[0], tp); @@ -5959,7 +6005,7 @@ check_for_color_response(char_u *resp, int len) char *new_bg_val = (3 * '6' < *tp_r + *tp_g + *tp_b) ? "light" : "dark"; - LOG_TRN("Received RBG response: %s", tp); + LOG_TRN("Received RBG response: r=%d g=%d b=%d", rval, gval, bval); #ifdef FEAT_TERMRESPONSE rbg_status.tr_progress = STATUS_GOT; # ifdef FEAT_TERMINAL @@ -5981,7 +6027,7 @@ check_for_color_response(char_u *resp, int len) #if defined(FEAT_TERMRESPONSE) && defined(FEAT_TERMINAL) else { - LOG_TRN("Received RFG response: %s", tp); + LOG_TRN("Received RFG response: r=%d g=%d b=%d", rval, gval, bval); rfg_status.tr_progress = STATUS_GOT; fg_r = rval; fg_g = gval; @@ -7992,24 +8038,6 @@ term_replace_keycodes(char_u *ta_buf, int ta_len, int len_arg) return len; } -/* - * Query the settings for the DEC modes we support - */ - void -send_decrqm_modes(void) -{ - if (termcap_active && cur_tmode == TMODE_RAW) - { - // Request setting of relevant DEC modes via DECRQM - for (int i = 0; i < (int)ARRAY_LENGTH(dec_modes); i++) - { - vim_snprintf((char *)IObuff, IOSIZE, "\033[?%d$p", dec_modes[i]); - out_str(IObuff); - } - out_flush(); - } -} - /* * Should be called when cleaning up terminal state. */ @@ -8068,6 +8096,17 @@ term_set_win_resize(bool state) } #endif + int +sync_output_active(void) +{ +#ifdef FEAT_GUI + if (gui.in_use) + return TRUE; +#endif + return p_tsy && (sync_output_setting == 1 || sync_output_setting == 2) + && *T_BSU != NUL && *T_ESU != NUL; +} + /* * Enable or disable synchronized output if possible. Specification can be found * here: diff --git a/src/terminal.c b/src/terminal.c index b675ba361c..30c48b6eb6 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -61,9 +61,11 @@ typedef struct { typedef struct sb_line_S { int sb_cols; // can differ per line + int sb_bytes; // length in bytes of text cellattr_T *sb_cells; // allocated cellattr_T sb_fill_attr; // for short line char_u *sb_text; // for tl_scrollback_postponed + char_u continuation; } sb_line_T; #ifdef MSWIN @@ -148,6 +150,8 @@ struct terminal_S { garray_T tl_scrollback; int tl_scrollback_scrolled; garray_T tl_scrollback_postponed; + int tl_scrollback_snapshot; + int tl_buffer_scrolled; char_u *tl_highlight_name; // replaces "Terminal"; allocated @@ -642,7 +646,7 @@ term_start( set_string_option_direct((char_u *)"buftype", -1, (char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0); // Avoid that 'buftype' is reset when this buffer is entered. - curbuf->b_p_initialized = TRUE; + curbuf->b_p_initialized = true; // Mark the buffer as not modifiable. It can only be made modifiable after // the job finished. @@ -1386,6 +1390,112 @@ update_cursor(term_T *term, int redraw) } } +/* + * Find the location of a scrollbackline in the buffer + */ + static void +scrollbackline_pos_in_buf(term_T *term, int row, linenr_T *lnum, int *start_col, size_t *start_pos) +{ + sb_line_T *lines = (sb_line_T *)term->tl_scrollback.ga_data; + linenr_T calc_lnum = term->tl_buffer_scrolled; + size_t calc_pos = 0; + int calc_col = 0; + int i; + + if (row < 0 || row >= term->tl_scrollback.ga_len) + return; + + if (row > term->tl_scrollback_scrolled) + { + // Lookback how far along in the top line we are + for (i = term->tl_scrollback_scrolled + 1; i > 0 && lines[i].continuation; --i) + { + calc_pos += lines[i - 1].sb_bytes; + calc_col += lines[i - 1].sb_cols; + } + i = term->tl_scrollback_scrolled + 1; + calc_lnum = term->tl_buffer_scrolled + 1; + // Do not count this line's bytes/cols twice + if (lines[i].continuation) + ++i; + } + else + { + i = 1; + calc_lnum = 1; + } + + for (; i <= row; ++i) + { + if (!lines[i].continuation) + { + ++calc_lnum; + calc_pos = 0; + calc_col = 0; + } + else + { + calc_pos += lines[i - 1].sb_bytes; + calc_col += lines[i - 1].sb_cols; + } + } + + *lnum = calc_lnum; + if (start_col) + *start_col = calc_col; + if (start_pos) + *start_pos = calc_pos; +} + +/* + * Find the location of a buffer line in the scrollback + */ + static void +bufline_pos_in_scrollback(term_T *term, linenr_T lnum, int col, int *row, int *wrapped_col) +{ + buf_T *buf = term->tl_buffer; + sb_line_T *lines = (sb_line_T *)term->tl_scrollback.ga_data; + linenr_T calc_row = term->tl_scrollback_scrolled; + int calc_col = col; + linenr_T l; + + if (lnum > buf->b_ml.ml_line_count) + return; + + if (lnum > term->tl_buffer_scrolled) + { + calc_row = term->tl_scrollback_scrolled; + l = term->tl_buffer_scrolled + 1; + + while (calc_row < term->tl_scrollback.ga_len && lines[calc_row].continuation) + ++calc_row; + } + else + { + calc_row = 0; + l = 1; + } + + while (calc_row < term->tl_scrollback.ga_len && l < lnum) + { + ++calc_row; + if (!lines[calc_row].continuation) + ++l; + } + + while (calc_row + 1 < term->tl_scrollback.ga_len && lines[calc_row + 1].continuation + && calc_col >= lines[calc_row].sb_cols) + { + calc_col -= lines[calc_row].sb_cols; + ++calc_row; + } + + if (row) + *row = calc_row; + if (wrapped_col) + *wrapped_col = calc_col; +} + /* * Invoked when "msg" output from a job was received. Write it to the terminal * of "buffer". @@ -1913,13 +2023,14 @@ term_try_stop_job(buf_T *buf) * Add the last line of the scrollback buffer to the buffer in the window. */ static void -add_scrollback_line_to_buffer(term_T *term, char_u *text, int len) +add_scrollback_line_to_buffer(term_T *term, char_u *text, int len, int append) { buf_T *buf = term->tl_buffer; int empty = (buf->b_ml.ml_flags & ML_EMPTY); linenr_T lnum = buf->b_ml.ml_line_count; #ifdef MSWIN + char_u *tmp = text; if (!enc_utf8 && enc_codepage > 0) { WCHAR *ret = NULL; @@ -1932,13 +2043,32 @@ add_scrollback_line_to_buffer(term_T *term, char_u *text, int len) WideCharToMultiByte_alloc(enc_codepage, 0, ret, length, (char **)&text, &len, 0, 0); vim_free(ret); - ml_append_buf(term->tl_buffer, lnum, text, len, FALSE); - vim_free(text); } } - else #endif - ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE); + + if (append) + { + char_u *prev_text = ml_get_buf(buf, lnum, FALSE); + size_t prev_len = STRLEN(prev_text); + + char_u *both = alloc(len + prev_len + 2); + if (both == NULL) + return; + vim_strncpy(both, prev_text, prev_len + 1); + vim_strncpy(both + prev_len, text, len + 1); + + curbuf = buf; + ml_replace(lnum, both, FALSE); + curbuf = curwin->w_buffer; + } + else + ml_append_buf(buf, lnum, text, len + 1, FALSE); + +#ifdef MSWIN + if (tmp != text) + vim_free(text); +#endif if (empty) { // Delete the empty line that was in the empty buffer. @@ -1994,6 +2124,7 @@ add_empty_scrollback(term_T *term, cellattr_T *fill_attr, int lnum) } } line->sb_cols = 0; + line->sb_bytes = 0; line->sb_cells = NULL; line->sb_fill_attr = *fill_attr; ++term->tl_scrollback.ga_len; @@ -2010,16 +2141,33 @@ cleanup_scrollback(term_T *term) { sb_line_T *line; garray_T *gap; + char_u *bufline; + size_t bufline_length; curbuf = term->tl_buffer; gap = &term->tl_scrollback; - while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled - && gap->ga_len > 0) + bufline = ml_get_buf(curbuf, curbuf->b_ml.ml_line_count, FALSE); + bufline_length = STRLEN(bufline); + while (term->tl_scrollback_snapshot && gap->ga_len > 0) { - ml_delete(curbuf->b_ml.ml_line_count); line = (sb_line_T *)gap->ga_data + gap->ga_len - 1; + if (line->sb_bytes < 0 || (size_t)line->sb_bytes > bufline_length) + break; + bufline_length -= line->sb_bytes; + if (!bufline_length) + { + ml_delete(curbuf->b_ml.ml_line_count); + bufline = ml_get_buf(curbuf, curbuf->b_ml.ml_line_count, FALSE); + bufline_length = STRLEN(bufline); + } vim_free(line->sb_cells); --gap->ga_len; + --term->tl_scrollback_snapshot; + } + if (bufline_length < STRLEN(bufline)) + { + char_u *shortened = vim_strnsave(bufline, bufline_length); + ml_replace(curbuf->b_ml.ml_line_count, shortened, FALSE); } curbuf = curwin->w_buffer; if (curbuf == term->tl_buffer) @@ -2033,6 +2181,7 @@ cleanup_scrollback(term_T *term) update_snapshot(term_T *term) { VTermScreen *screen; + VTermState *state; int len; int lines_skipped = 0; VTermPos pos; @@ -2048,6 +2197,7 @@ update_snapshot(term_T *term) cleanup_scrollback(term); screen = vterm_obtain_screen(term->tl_vterm); + state = vterm_obtain_state(term->tl_vterm); fill_attr = new_fill_attr = term->tl_default_color; for (pos.row = 0; pos.row < term->tl_rows; ++pos.row) { @@ -2072,7 +2222,10 @@ update_snapshot(term_T *term) // Line was skipped, add an empty line. --lines_skipped; if (add_empty_scrollback(term, &fill_attr, 0) == OK) - add_scrollback_line_to_buffer(term, (char_u *)"", 0); + { + add_scrollback_line_to_buffer(term, (char_u *)"", 0, 0); + ++term->tl_scrollback_snapshot; + } } if (len == 0) @@ -2084,9 +2237,12 @@ update_snapshot(term_T *term) { garray_T ga; int width; + const VTermLineInfo *lineinfo; sb_line_T *line = (sb_line_T *)term->tl_scrollback.ga_data + term->tl_scrollback.ga_len; + lineinfo = vterm_state_get_lineinfo(state, pos.row); + ga_init2(&ga, 1, 100); for (pos.col = 0; pos.col < len; pos.col += width) { @@ -2114,24 +2270,29 @@ update_snapshot(term_T *term) int i; int c; - for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i) + for (i = 0; i < VTERM_MAX_CHARS_PER_CELL && + ((c = cell.chars[i]) > 0 || i == 0); ++i) ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c, (char_u *)ga.ga_data + ga.ga_len); } } } line->sb_cols = len; + line->sb_bytes = ga.ga_len; line->sb_cells = p; line->sb_fill_attr = new_fill_attr; + line->continuation = (char_u)lineinfo->continuation; fill_attr = new_fill_attr; ++term->tl_scrollback.ga_len; + ++term->tl_scrollback_snapshot; if (ga_grow(&ga, 1) == FAIL) - add_scrollback_line_to_buffer(term, (char_u *)"", 0); + add_scrollback_line_to_buffer(term, (char_u *)"", 0, 0); else { *((char_u *)ga.ga_data + ga.ga_len) = NUL; - add_scrollback_line_to_buffer(term, ga.ga_data, ga.ga_len); + add_scrollback_line_to_buffer(term, ga.ga_data, ga.ga_len, + lineinfo->continuation); } ga_clear(&ga); } @@ -2146,7 +2307,10 @@ update_snapshot(term_T *term) ++pos.row) { if (add_empty_scrollback(term, &fill_attr, 0) == OK) - add_scrollback_line_to_buffer(term, (char_u *)"", 0); + { + add_scrollback_line_to_buffer(term, (char_u *)"", 0, 0); + ++term->tl_scrollback_snapshot; + } } term->tl_dirty_snapshot = FALSE; @@ -2191,7 +2355,7 @@ may_move_terminal_to_buffer(term_T *term, int redraw) // Update the snapshot only if something changes or the buffer does not // have all the lines. if (term->tl_dirty_snapshot || term->tl_buffer->b_ml.ml_line_count - <= term->tl_scrollback_scrolled) + <= term->tl_buffer_scrolled) update_snapshot(term); if (redraw) @@ -2287,7 +2451,9 @@ cleanup_vterm(term_T *term) static void term_enter_normal_mode(void) { - term_T *term = curbuf->b_term; + term_T *term = curbuf->b_term; + linenr_T lnum; + int col; set_terminal_mode(term, TRUE); @@ -2296,15 +2462,16 @@ term_enter_normal_mode(void) // Move the window cursor to the position of the cursor in the // terminal. - curwin->w_cursor.lnum = term->tl_scrollback_scrolled - + term->tl_cursor_pos.row + 1; - check_cursor(); - if (coladvance(term->tl_cursor_pos.col) == FAIL) - coladvance(MAXCOL); - curwin->w_set_curswant = TRUE; + lnum = term->tl_buffer_scrolled + 1 + term->tl_cursor_pos.row; + col = term->tl_cursor_pos.col; + scrollbackline_pos_in_buf(term, term->tl_cursor_pos.row + term->tl_scrollback_scrolled, &lnum, &col, NULL); - // Display the same lines as in the terminal. - curwin->w_topline = term->tl_scrollback_scrolled + 1; + curwin->w_cursor.lnum = lnum; + check_cursor(); + if (coladvance(col) == FAIL) + coladvance(MAXCOL); + curwin->w_set_curswant = true; + curwin->w_topline = term->tl_buffer_scrolled + 1; } /* @@ -3401,7 +3568,7 @@ handle_settermprop( if (term == curbuf->b_term) { maketitle(); - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; } break; @@ -3488,20 +3655,27 @@ limit_scrollback(term_T *term, garray_T *gap, int update_buffer) int todo = MAX(term->tl_buffer->b_p_twsl / 10, gap->ga_len - term->tl_buffer->b_p_twsl); int i; + sb_line_T *sb_lines = (sb_line_T *)gap->ga_data; curbuf = term->tl_buffer; for (i = 0; i < todo; ++i) { - vim_free(((sb_line_T *)gap->ga_data + i)->sb_cells); - if (update_buffer) + if (update_buffer && (!sb_lines[i].continuation || !i)) + { ml_delete(1); + --term->tl_buffer_scrolled; + } + vim_free(sb_lines[i].sb_cells); } + // Continue until end of wrapped line + for (; todo < gap->ga_len && sb_lines[todo].continuation; ++todo) + vim_free(sb_lines[todo].sb_cells); curbuf = curwin->w_buffer; gap->ga_len -= todo; mch_memmove(gap->ga_data, - (sb_line_T *)gap->ga_data + todo, - sizeof(sb_line_T) * gap->ga_len); + (sb_line_T *)gap->ga_data + todo, + sizeof(sb_line_T) * gap->ga_len); if (update_buffer) { win_T *curwin_save = curwin; @@ -3526,7 +3700,7 @@ limit_scrollback(term_T *term, garray_T *gap, int update_buffer) * Handle a line that is pushed off the top of the screen. */ static int -handle_pushline(int cols, const VTermScreenCell *cells, void *user) +handle_pushline(int cols, const VTermScreenCell *cells, int continuation, void *user) { term_T *term = (term_T *)user; garray_T *gap; @@ -3605,16 +3779,20 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user) *(text + text_len) = NUL; } if (update_buffer) - add_scrollback_line_to_buffer(term, text, text_len); + add_scrollback_line_to_buffer(term, text, text_len, continuation); line = (sb_line_T *)gap->ga_data + gap->ga_len; line->sb_cols = len; + line->sb_bytes = text_len; line->sb_cells = p; line->sb_fill_attr = fill_attr; + line->continuation = (char_u)continuation; if (update_buffer) { line->sb_text = NULL; ++term->tl_scrollback_scrolled; + if (!continuation) + ++term->tl_buffer_scrolled; ga_clear(&ga); // free the text } else @@ -3656,17 +3834,20 @@ handle_postponed_scrollback(term_T *term) text = pp_line->sb_text; if (text == NULL) text = (char_u *)""; - add_scrollback_line_to_buffer(term, text, (int)STRLEN(text)); + add_scrollback_line_to_buffer(term, text, (int)STRLEN(text), pp_line->continuation); vim_free(pp_line->sb_text); line = (sb_line_T *)term->tl_scrollback.ga_data + term->tl_scrollback.ga_len; line->sb_cols = pp_line->sb_cols; + line->sb_bytes = pp_line->sb_bytes; line->sb_cells = pp_line->sb_cells; line->sb_fill_attr = pp_line->sb_fill_attr; line->sb_text = NULL; ++term->tl_scrollback_scrolled; ++term->tl_scrollback.ga_len; + if (!pp_line->continuation) + ++term->tl_buffer_scrolled; } ga_clear(&term->tl_scrollback_postponed); @@ -3690,9 +3871,10 @@ static VTermScreenCallbacks screen_callbacks = { handle_settermprop, // settermprop handle_bell, // bell handle_resize, // resize - handle_pushline, // sb_pushline + NULL, // sb_pushline NULL, // sb_popline - NULL // sb_clear + NULL, // sb_clear + handle_pushline // sb_pushline4 }; /* @@ -4248,16 +4430,21 @@ term_get_attr(win_T *wp, linenr_T lnum, int col) term_T *term = buf->b_term; sb_line_T *line; cellattr_T *cellattr; + int sb_line = -1; + int sb_col = col; - if (lnum > term->tl_scrollback.ga_len) + if (term->tl_scrollback.ga_len) + bufline_pos_in_scrollback(term, lnum, col, &sb_line, &sb_col); + + if (sb_line < 0) cellattr = &term->tl_default_color; else { - line = (sb_line_T *)term->tl_scrollback.ga_data + lnum - 1; - if (col < 0 || col >= line->sb_cols) + line = (sb_line_T *)term->tl_scrollback.ga_data + sb_line; + if (sb_col < 0 || sb_col >= line->sb_cols) cellattr = &line->sb_fill_attr; else - cellattr = line->sb_cells + col; + cellattr = line->sb_cells + sb_col; } return cell2attr(term, wp, &cellattr->attrs, &cellattr->fg, &cellattr->bg); } @@ -4976,6 +5163,7 @@ create_vterm(term_T *term, int rows, int cols) vterm_screen_set_callbacks(screen, &screen_callbacks, term); vterm_screen_set_damage_merge(screen, VTERM_DAMAGE_SCROLL); + vterm_screen_callbacks_has_pushline4(screen); // TODO: depends on 'encoding'. vterm_set_utf8(vterm, 1); @@ -5490,8 +5678,10 @@ read_dump_file(FILE *fd, VTermPos *cursor_pos) if (max_cells < ga_cell.ga_len) max_cells = ga_cell.ga_len; line->sb_cols = ga_cell.ga_len; + line->sb_bytes = ga_text.ga_len; line->sb_cells = ga_cell.ga_data; line->sb_fill_attr = term->tl_default_color; + line->continuation = 0; ++term->tl_scrollback.ga_len; ga_init(&ga_cell); @@ -6312,11 +6502,24 @@ f_term_getline(typval_T *argvars, typval_T *rettv) if (term->tl_vterm == NULL) { - linenr_T lnum = row + term->tl_scrollback_scrolled + 1; + linenr_T lnum = 0; + size_t offset = 0; + int sb_row = term->tl_scrollback_scrolled + row; + sb_line_T *line; + + if (sb_row < 0 || sb_row >= term->tl_scrollback.ga_len) + return; + line = (sb_line_T *)term->tl_scrollback.ga_data + sb_row; + + scrollbackline_pos_in_buf(term, sb_row, &lnum, NULL, &offset); // vterm is finished, get the text from the buffer if (lnum > 0 && lnum <= buf->b_ml.ml_line_count) - rettv->vval.v_string = vim_strsave(ml_get_buf(buf, lnum, FALSE)); + { + char_u *p = ml_get_buf(buf, lnum, FALSE); + if (STRLEN(p) >= offset + line->sb_bytes) + rettv->vval.v_string = vim_strnsave(p + offset, line->sb_bytes); + } } else { @@ -6355,7 +6558,7 @@ f_term_getscrolled(typval_T *argvars, typval_T *rettv) buf = term_get_buf(argvars, "term_getscrolled()"); if (buf == NULL) return; - rettv->vval.v_number = buf->b_term->tl_scrollback_scrolled; + rettv->vval.v_number = buf->b_term->tl_buffer_scrolled; } /* @@ -6569,12 +6772,22 @@ f_term_scrape(typval_T *argvars, typval_T *rettv) } else { - linenr_T lnum = pos.row + term->tl_scrollback_scrolled; + int sb_row = term->tl_scrollback_scrolled + pos.row; + linenr_T lnum = 0; + size_t offset = 0; - if (lnum < 0 || lnum >= term->tl_scrollback.ga_len) + scrollbackline_pos_in_buf(term, sb_row, &lnum, NULL, &offset); + + if (sb_row >= term->tl_scrollback.ga_len || lnum <= 0 || lnum > buf->b_ml.ml_line_count) return; - p = ml_get_buf(buf, lnum + 1, FALSE); - line = (sb_line_T *)term->tl_scrollback.ga_data + lnum; + + line = (sb_line_T *)term->tl_scrollback.ga_data + sb_row; + p = ml_get_buf(buf, lnum, FALSE); + + if (STRLEN(p) < offset + line->sb_bytes) + return; + + p += offset; } for (pos.col = 0; pos.col < term->tl_cols; ) @@ -6584,14 +6797,14 @@ f_term_scrape(typval_T *argvars, typval_T *rettv) VTermScreenCellAttrs attrs; VTermColor fg, bg; char_u rgb[8]; + size_t rgblen; char_u mbs[MB_MAXBYTES * VTERM_MAX_CHARS_PER_CELL + 1]; - int off = 0; + size_t mbslen; int i; if (screen == NULL) { cellattr_T *cellattr; - int len; // vterm has finished, get the cell from scrollback if (pos.col >= line->sb_cols) @@ -6601,10 +6814,10 @@ f_term_scrape(typval_T *argvars, typval_T *rettv) attrs = cellattr->attrs; fg = cellattr->fg; bg = cellattr->bg; - len = mb_ptr2len(p); - mch_memmove(mbs, p, len); - mbs[len] = NUL; - p += len; + mbslen = mb_ptr2len(p); + mch_memmove(mbs, p, mbslen); + mbs[mbslen] = NUL; + p += mbslen; } else { @@ -6612,13 +6825,15 @@ f_term_scrape(typval_T *argvars, typval_T *rettv) if (vterm_screen_get_cell(screen, pos, &cell) == 0) break; + + mbslen = 0; for (i = 0; i < VTERM_MAX_CHARS_PER_CELL; ++i) { if (cell.chars[i] == 0) break; - off += (*utf_char2bytes)((int)cell.chars[i], mbs + off); + mbslen += (*utf_char2bytes)((int)cell.chars[i], mbs + mbslen); } - mbs[off] = NUL; + mbs[mbslen] = NUL; width = cell.width; attrs = cell.attrs; fg = cell.fg; @@ -6629,14 +6844,14 @@ f_term_scrape(typval_T *argvars, typval_T *rettv) break; list_append_dict(l, dcell); - dict_add_string(dcell, "chars", mbs); + dict_add_string_len(dcell, "chars", mbs, (int)mbslen); - vim_snprintf((char *)rgb, 8, "#%02x%02x%02x", - fg.red, fg.green, fg.blue); - dict_add_string(dcell, "fg", rgb); - vim_snprintf((char *)rgb, 8, "#%02x%02x%02x", - bg.red, bg.green, bg.blue); - dict_add_string(dcell, "bg", rgb); + rgblen = vim_snprintf_safelen((char *)rgb, sizeof(rgb), + "#%02x%02x%02x", fg.red, fg.green, fg.blue); + dict_add_string_len(dcell, "fg", rgb, (int)rgblen); + rgblen = vim_snprintf_safelen((char *)rgb, sizeof(rgb), + "#%02x%02x%02x", bg.red, bg.green, bg.blue); + dict_add_string_len(dcell, "bg", rgb, (int)rgblen); dict_add_number(dcell, "attr", cell2attr(term, NULL, &attrs, &fg, &bg)); diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 06ac5512a3..3dee2cf5f4 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -249,6 +249,7 @@ NEW_TESTS = \ test_plugin_helpcurwin \ test_plugin_helptoc \ test_plugin_man \ + test_plugin_matchit \ test_plugin_matchparen \ test_plugin_netrw \ test_plugin_osc52 \ @@ -528,6 +529,7 @@ NEW_TESTS_RES = \ test_plugin_helpcurwin.res \ test_plugin_helptoc.res \ test_plugin_man.res \ + test_plugin_matchit.res \ test_plugin_matchparen.res \ test_plugin_netrw.res \ test_plugin_osc52.res \ diff --git a/src/testdir/Makefile b/src/testdir/Makefile index 2e1d900b88..181dee36cb 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -2,6 +2,11 @@ # Makefile to run all tests for Vim # +# The old-style tests (*.in) use shared filenames in the working directory +# (test.ok, test.out, X*, viminfo), so running them in parallel causes races +# and spurious failures. +.NOTPARALLEL: + # Use console or GUI. VIMPROG = ../vim XXDPROG = ../xxd/xxd diff --git a/src/testdir/commondumps.vim b/src/testdir/commondumps.vim index 27d59bcdd1..40206041bd 100644 --- a/src/testdir/commondumps.vim +++ b/src/testdir/commondumps.vim @@ -10,7 +10,7 @@ enddef def TryChangingLastJumpMark(marks: dict>) const pos: list = get(marks, line('.'), []) if !empty(pos) - setpos("'`", pos) + setcharpos("'`", pos) endif enddef @@ -56,7 +56,7 @@ def FoldAndMarkDumpDiffParts(letters: list) var marks: dict> = {} for idx in range(parts[1]->len()) if !empty(letters) - setpos(("'" .. remove(letters, 0)), parts[1][idx]) + setcharpos(("'" .. remove(letters, 0)), parts[1][idx]) endif # Point "bs" to "cs", "cs" to "as", "as" to "cs". marks[parts[1][idx][1]] = parts[2][idx] diff --git a/src/testdir/dumps/Test_VertSplitNC_1.dump b/src/testdir/dumps/Test_VertSplitNC_1.dump new file mode 100644 index 0000000000..804bf60eac --- /dev/null +++ b/src/testdir/dumps/Test_VertSplitNC_1.dump @@ -0,0 +1,12 @@ +>V+0&#ffffff0|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|<+0#ffffff16#0000e05|o| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p| |<+0#0000001#a8a8a8255| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p| |<| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p +| +0#0000000#ffffff0@74 diff --git a/src/testdir/dumps/Test_VertSplitNC_2.dump b/src/testdir/dumps/Test_VertSplitNC_2.dump new file mode 100644 index 0000000000..8afa526ac0 --- /dev/null +++ b/src/testdir/dumps/Test_VertSplitNC_2.dump @@ -0,0 +1,12 @@ +|V+0&#ffffff0|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&>V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|<+0#0000001#a8a8a8255|o| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p| +0#ffffff16#0000e05|<| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p| |<+0#0000001#a8a8a8255| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p +| +0#0000000#ffffff0@74 diff --git a/src/testdir/dumps/Test_VertSplitNC_3.dump b/src/testdir/dumps/Test_VertSplitNC_3.dump new file mode 100644 index 0000000000..614de055ea --- /dev/null +++ b/src/testdir/dumps/Test_VertSplitNC_3.dump @@ -0,0 +1,12 @@ +|V+0&#ffffff0|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&>V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|V|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @8||+0#6c6c6c255&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7||+0#40ff4011&|V+0#0000000&|e|r|t|S|p|l|i|t|N|C| |t|e|s|t| @7 +|<+0#0000001#a8a8a8255|o| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p| |<| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p| +0#ffffff16#0000e05|<| |N|a|m|e|]| |[|+|]| |1|,|1| @5|T|o|p +| +0#0000000#ffffff0@74 diff --git a/src/testdir/dumps/Test_VertSplitNC_whl1.dump b/src/testdir/dumps/Test_VertSplitNC_whl1.dump new file mode 100644 index 0000000000..b6267ef1ae --- /dev/null +++ b/src/testdir/dumps/Test_VertSplitNC_whl1.dump @@ -0,0 +1,12 @@ +> +0&#ffffff0@36||+1&&| +0&&@36 +|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|[+0#ffffff16#e000002|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1| |[+1#0000000#ffffff0|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_VertSplitNC_whl2.dump b/src/testdir/dumps/Test_VertSplitNC_whl2.dump new file mode 100644 index 0000000000..825775e591 --- /dev/null +++ b/src/testdir/dumps/Test_VertSplitNC_whl2.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@36||+1&&> +0&&@36 +|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|[+1#0000000&|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1| +3&&|[|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_VertSplitNC_winbar_1.dump b/src/testdir/dumps/Test_VertSplitNC_winbar_1.dump new file mode 100644 index 0000000000..4fbee462da --- /dev/null +++ b/src/testdir/dumps/Test_VertSplitNC_winbar_1.dump @@ -0,0 +1,12 @@ +|w+0&#ffffff0|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&| +0#0000000#e0e0e08| +2#ffffff16#6c6c6c255|I|t|e|m| | +0#0000000#e0e0e08@29 +|w+0&#ffffff0|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&>w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|[+0#0000001#a8a8a8255|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|T|o|p| +0#ffffff16#0000e05|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|T|o|p +| +0#0000000#ffffff0@74 diff --git a/src/testdir/dumps/Test_VertSplitNC_winbar_2.dump b/src/testdir/dumps/Test_VertSplitNC_winbar_2.dump new file mode 100644 index 0000000000..765328356e --- /dev/null +++ b/src/testdir/dumps/Test_VertSplitNC_winbar_2.dump @@ -0,0 +1,12 @@ +>w+0&#ffffff0|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&| +0#0000000#e0e0e08| +2#ffffff16#6c6c6c255|I|t|e|m| | +0#0000000#e0e0e08@29 +|w+0&#ffffff0|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|w|i|n|b|a|r| |t|e|s|t| @25||+0#40ff4011&|w+0#0000000&|i|n|b|a|r| |t|e|s|t| @25 +|[+0#ffffff16#0000e05|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|T|o|p| |[+0#0000001#a8a8a8255|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|T|o|p +| +0#0000000#ffffff0@74 diff --git a/src/testdir/dumps/Test_clientserver_1.dump b/src/testdir/dumps/Test_clientserver_1.dump new file mode 100644 index 0000000000..a4a0b42564 --- /dev/null +++ b/src/testdir/dumps/Test_clientserver_1.dump @@ -0,0 +1,8 @@ +|~+0#4040ff13#ffffff0| @73 +|~| @73 +|~| @73 +|E+0#ffffff16#e000002|1|5|6|7|:| |S|o|c|k|e|t| |s|e|r|v|e|r| |p|r|o|t|o|c|o|l| |v|e|r|s|i|o|n| |m|i|s|m|a|t|c|h|,| |c|h|e|c|k| |w|h|a|t| |V|i|m| |v|e|r|s|i|o|n| |y|o|u| +|a|r|e| |u|s|i|n|g| +0#0000000#ffffff0@65 +|E+0#ffffff16#e000002|2|4|1|:| |U|n|a|b|l|e| |t|o| |s|e|n|d| |t|o| |c|h|a|n@1|e|l|:|2|0@2| +0#0000000#ffffff0@38 +@75 +|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_cmdwin_wrap_prefix.dump b/src/testdir/dumps/Test_cmdwin_wrap_prefix.dump new file mode 100644 index 0000000000..19ed264481 --- /dev/null +++ b/src/testdir/dumps/Test_cmdwin_wrap_prefix.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@39 +|~+0#4040ff13&| @38 +|[+1#0000000&|N|o| |N|a|m|e|]| @12|0|,|0|-|1| @9|A|l@1 +|:+0#4040ff13&|e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|a@31|" +| +0#0000000&|X|Y>Z| @35 +|~+0#4040ff13&| @38 +|~| @38 +|~| @38 +|~| @38 +|~| @38 +|[+3#0000000&|C|o|m@1|a|n|d| |L|i|n|e|]| @7|1|,|4|2| @10|A|l@1 +| +0&&@39 diff --git a/src/testdir/dumps/Test_compl_findfunc_dict_01.dump b/src/testdir/dumps/Test_compl_findfunc_dict_01.dump new file mode 100644 index 0000000000..3c93811384 --- /dev/null +++ b/src/testdir/dumps/Test_compl_findfunc_dict_01.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @3| +0#0000001#e0e0e08|X|p|l|a|i|n| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|1| |F| |f|i|l|e| @1| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|2| |F| |f|i|l|e| @1| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|X|d|i|r|1| @1|D| |d|i|r| @2| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|X|d|i|r|2| @1|D| |d|i|r| @2| +0#4040ff13#ffffff0@53 +|:+0#0000000&|f|i|n|d| |X|p|l|a|i|n> @62 diff --git a/src/testdir/dumps/Test_compl_findfunc_dict_02.dump b/src/testdir/dumps/Test_compl_findfunc_dict_02.dump new file mode 100644 index 0000000000..0e39d0486b --- /dev/null +++ b/src/testdir/dumps/Test_compl_findfunc_dict_02.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @3| +0#0000001#ffd7ff255|X|p|l|a|i|n| @8| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|1| |F| |f|i|l|e| @1| +0#4040ff13#ffffff0@53 +|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|2| |F| |f|i|l|e| @1|╔+0&#e0e0e08|═@8|X| +0#4040ff13#ffffff0@42 +|~| @3| +0#0000001#e0e0e08|X|d|i|r|1| @1|D| |d|i|r| @2|║| |1|s|t| |d|i|r| |║| +0#4040ff13#ffffff0@42 +|~| @3| +0#0000001#ffd7ff255|X|d|i|r|2| @1|D| |d|i|r| @2|╚+0&#e0e0e08|═@8|⇲| +0#4040ff13#ffffff0@42 +|:+0#0000000&|f|i|n|d| |X|d|i|r|1> @63 diff --git a/src/testdir/dumps/Test_customlist_info_popup_01.dump b/src/testdir/dumps/Test_customlist_info_popup_01.dump new file mode 100644 index 0000000000..a17ff601eb --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_01.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @26|╔+0#0000001#e0e0e08|═@12|X| +0#4040ff13#ffffff0@31 +|~| @6| +0#0000001#e0e0e08|🍎*&| +&@4|f| |f|r|u|i|t| @4|║| |A| |r|e|d| |f|r|u|i|t| |║| +0#4040ff13#ffffff0@31 +|~| @6| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4|╚+0&#e0e0e08|═@12|⇲| +0#4040ff13#ffffff0@31 +|~| @6| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| | +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#ffd7ff255|p|l|a|i|n| @13| +0#4040ff13#ffffff0@46 +|:+0#0000000&|D|i|c|t|C|m|d| |a|p@1|l|e> @60 diff --git a/src/testdir/dumps/Test_customlist_info_popup_02.dump b/src/testdir/dumps/Test_customlist_info_popup_02.dump new file mode 100644 index 0000000000..c8c9c54ae3 --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_02.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @6| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4|╔+0&#e0e0e08|═@15|X| +0#4040ff13#ffffff0@28 +|~| @6| +0#0000001#e0e0e08|🍌*&| +&@4|f| |f|r|u|i|t| @4|║| |A| |y|e|l@1|o|w| |f|r|u|i|t| |║| +0#4040ff13#ffffff0@28 +|~| @6| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| |╚+0&#e0e0e08|═@15|⇲| +0#4040ff13#ffffff0@28 +|~| @6| +0#0000001#ffd7ff255|p|l|a|i|n| @13| +0#4040ff13#ffffff0@46 +|:+0#0000000&|D|i|c|t|C|m|d| |b|a|n|a|n|a> @59 diff --git a/src/testdir/dumps/Test_customlist_info_popup_03.dump b/src/testdir/dumps/Test_customlist_info_popup_03.dump new file mode 100644 index 0000000000..4aa47adfcb --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_03.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @6| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4|╔+0&#e0e0e08|═@20|X| +0#4040ff13#ffffff0@23 +|~| @6| +0#0000001#e0e0e08|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| |║| |A|n| |o|r|a|n|g|e| |v|e|g|e|t|a|b|l|e| |║| +0#4040ff13#ffffff0@23 +|~| @6| +0#0000001#ffd7ff255|p|l|a|i|n| @13|╚+0&#e0e0e08|═@20|⇲| +0#4040ff13#ffffff0@23 +|:+0#0000000&|D|i|c|t|C|m|d| |c|a|r@1|o|t> @59 diff --git a/src/testdir/dumps/Test_customlist_info_popup_04.dump b/src/testdir/dumps/Test_customlist_info_popup_04.dump new file mode 100644 index 0000000000..18cb1ba1f9 --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_04.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @6| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| | +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#e0e0e08|p|l|a|i|n| @13| +0#4040ff13#ffffff0@46 +|:+0#0000000&|D|i|c|t|C|m|d| |p|l|a|i|n> @60 diff --git a/src/testdir/dumps/Test_customlist_info_popup_05.dump b/src/testdir/dumps/Test_customlist_info_popup_05.dump new file mode 100644 index 0000000000..a4b6d1517c --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_05.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @6| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| | +0#4040ff13#ffffff0@46 +|~| @6| +0#0000001#ffd7ff255|p|l|a|i|n| @13| +0#4040ff13#ffffff0@46 +|:+0#0000000&|D|i|c|t|C|m|d| > @65 diff --git a/src/testdir/dumps/Test_customlist_info_popup_06.dump b/src/testdir/dumps/Test_customlist_info_popup_06.dump new file mode 100644 index 0000000000..7b8eba89db --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_06.dump @@ -0,0 +1,12 @@ +|D+0&#ffffff0|i|c|t|C|m|d| |a|p@1|l|e> @13|╔+0#0000001#e0e0e08|═@12|X| +0#0000000#ffffff0@32 +|~+0#4040ff13&| @5| +0#0000001#e0e0e08|🍎*&| +&@4|f| |f|r|u|i|t| @4|║| |A| |r|e|d| |f|r|u|i|t| |║| +0#4040ff13#ffffff0@32 +|~| @5| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4|╚+0&#e0e0e08|═@12|⇲| +0#4040ff13#ffffff0@32 +|~| @5| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| | +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#ffd7ff255|p|l|a|i|n| @13| +0#4040ff13#ffffff0@47 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |C|o|m@1|a|n|d|-|l|i|n|e| |c|o|m|p|l|e|t|i|o|n| |(|^|V|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_customlist_info_popup_07.dump b/src/testdir/dumps/Test_customlist_info_popup_07.dump new file mode 100644 index 0000000000..a0202af08b --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_07.dump @@ -0,0 +1,12 @@ +|D+0&#ffffff0|i|c|t|C|m|d| |b|a|n|a|n|a> @60 +|~+0#4040ff13&| @5| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4|╔+0&#e0e0e08|═@15|X| +0#4040ff13#ffffff0@29 +|~| @5| +0#0000001#e0e0e08|🍌*&| +&@4|f| |f|r|u|i|t| @4|║| |A| |y|e|l@1|o|w| |f|r|u|i|t| |║| +0#4040ff13#ffffff0@29 +|~| @5| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| |╚+0&#e0e0e08|═@15|⇲| +0#4040ff13#ffffff0@29 +|~| @5| +0#0000001#ffd7ff255|p|l|a|i|n| @13| +0#4040ff13#ffffff0@47 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |C|o|m@1|a|n|d|-|l|i|n|e| |c|o|m|p|l|e|t|i|o|n| |(|^|V|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |4| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_customlist_info_popup_08.dump b/src/testdir/dumps/Test_customlist_info_popup_08.dump new file mode 100644 index 0000000000..90f9de7f70 --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_08.dump @@ -0,0 +1,12 @@ +|D+0&#ffffff0|i|c|t|C|m|d| |c|a|r@1|o|t> @60 +|~+0#4040ff13&| @5| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4|╔+0&#e0e0e08|═@20|X| +0#4040ff13#ffffff0@24 +|~| @5| +0#0000001#e0e0e08|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| |║| |A|n| |o|r|a|n|g|e| |v|e|g|e|t|a|b|l|e| |║| +0#4040ff13#ffffff0@24 +|~| @5| +0#0000001#ffd7ff255|p|l|a|i|n| @13|╚+0&#e0e0e08|═@20|⇲| +0#4040ff13#ffffff0@24 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |C|o|m@1|a|n|d|-|l|i|n|e| |c|o|m|p|l|e|t|i|o|n| |(|^|V|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |3| |o|f| |4| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_customlist_info_popup_09.dump b/src/testdir/dumps/Test_customlist_info_popup_09.dump new file mode 100644 index 0000000000..5b048f8499 --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_09.dump @@ -0,0 +1,12 @@ +|D+0&#ffffff0|i|c|t|C|m|d| |p|l|a|i|n> @61 +|~+0#4040ff13&| @5| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| | +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#e0e0e08|p|l|a|i|n| @13| +0#4040ff13#ffffff0@47 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |C|o|m@1|a|n|d|-|l|i|n|e| |c|o|m|p|l|e|t|i|o|n| |(|^|V|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |4| |o|f| |4| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_customlist_info_popup_10.dump b/src/testdir/dumps/Test_customlist_info_popup_10.dump new file mode 100644 index 0000000000..67775f75a7 --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_10.dump @@ -0,0 +1,12 @@ +|D+0&#ffffff0|i|c|t|C|m|d| > @66 +|~+0#4040ff13&| @5| +0#0000001#ffd7ff255|🍎*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#ffd7ff255|🍌*&| +&@4|f| |f|r|u|i|t| @4| +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#ffd7ff255|c|a|r@1|o|t| |v| |v|e|g|e|t|a|b|l|e| | +0#4040ff13#ffffff0@47 +|~| @5| +0#0000001#ffd7ff255|p|l|a|i|n| @13| +0#4040ff13#ffffff0@47 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |C|o|m@1|a|n|d|-|l|i|n|e| |c|o|m|p|l|e|t|i|o|n| |(|^|V|^|N|^|P|)| |B+0#e000002&|a|c|k| |a|t| |o|r|i|g|i|n|a|l| +0#0000000&@22 diff --git a/src/testdir/dumps/Test_customlist_info_popup_11.dump b/src/testdir/dumps/Test_customlist_info_popup_11.dump new file mode 100644 index 0000000000..830dfcff04 --- /dev/null +++ b/src/testdir/dumps/Test_customlist_info_popup_11.dump @@ -0,0 +1,12 @@ +|s+0&#ffffff0|i|g|n| |u|n|d|e|f|i|n|e> @61 +|~+0#4040ff13&| @2| +0#0000001#e0e0e08|u|n|d|e|f|i|n|e| @6| +0#4040ff13#ffffff0@54 +|~| @2| +0#0000001#ffd7ff255|u|n|p|l|a|c|e| @7| +0#4040ff13#ffffff0@54 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |C|o|m@1|a|n|d|-|l|i|n|e| |c|o|m|p|l|e|t|i|o|n| |(|^|V|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |2| +0#0000000&@26 diff --git a/src/testdir/dumps/Test_diff_anchors_07.dump b/src/testdir/dumps/Test_diff_anchors_07.dump index 310fa6544b..eda58e9fd7 100644 --- a/src/testdir/dumps/Test_diff_anchors_07.dump +++ b/src/testdir/dumps/Test_diff_anchors_07.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@22||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255| @20||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@21 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@22||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|3+0#0000000#5fd7ff255| @20||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@21 |~+0&#ffffff0| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|1| @5|A|l@1| |X+3&&|d|i|f|i|l|e|3| @3|1|,|1| @5|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|1| @5|A|l@1| +3&&|X|d|i|f|i|l|e|3| @3|1|,|1| @5|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_01.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_01.dump index a0ffa9f301..5616d5f371 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_01.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_01.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_02.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_02.dump index 9e5c9dc94e..3d66db8d6e 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_02.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_02.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| |X+3&&|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| +3&&|X|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_03.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_03.dump index 76f8617683..fdab541440 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_03.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_03.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| |X+3&&|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| +3&&|X|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_04.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_04.dump index 1c069d8ded..705446a3dd 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_04.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_04.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| |X+3&&|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| +3&&|X|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_05.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_05.dump index 87bbc572e5..5daf6573d3 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_05.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_05.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_06.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_06.dump index 1f5917cf47..6cae25e1d4 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_06.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_06.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| |X+3&&|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| +3&&|X|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_07.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_07.dump index 1c069d8ded..705446a3dd 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_07.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_07.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| |X+3&&|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @10|3|,|1| @11|B|o|t| +3&&|X|d|i|f|i|l|e|2| @10|3|,|1| @11|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_08.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_08.dump index aadabe077d..a2ade506e4 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_08.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_08.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|1| @5|A|l@1| |X+3&&|d|i|f|i|l|e|3| @3|1|,|1| @5|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|1| @5|A|l@1| +3&&|X|d|i|f|i|l|e|3| @3|1|,|1| @5|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_13.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_13.dump index 99cb0ded0f..af99924276 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_13.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_13.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|1| @5|A|l@1| |X+3&&|d|i|f|i|l|e|3| @3|1|,|1| @5|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|1| @5|A|l@1| +3&&|X|d|i|f|i|l|e|3| @3|1|,|1| @5|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_14.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_14.dump index 3c35c7741a..c6a418a4b4 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_14.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_14.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| |X+3&&|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| +3&&|X|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_15.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_15.dump index 432cadb94d..cf6bce8d0d 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_15.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_15.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| |X+3&&|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| +3&&|X|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_16.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_16.dump index b95c2661a6..4bff316f42 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_16.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_16.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| |X+3&&|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| +3&&|X|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_17.dump b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_17.dump index 7daaf7a9ac..9496933153 100644 --- a/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_17.dump +++ b/src/testdir/dumps/Test_diff_anchors_scrollbind_topline_17.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| |X+3&&|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|1| @5|A|l@1| |X|d|i|f|i|l|e|2| @3|5|,|1| @5|B|o|t| +3&&|X|d|i|f|i|l|e|3| @3|5|,|1| @5|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_get_put_linematch_16.dump b/src/testdir/dumps/Test_diff_get_put_linematch_16.dump index d4649d2052..eeb984d682 100644 --- a/src/testdir/dumps/Test_diff_get_put_linematch_16.dump +++ b/src/testdir/dumps/Test_diff_get_put_linematch_16.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|D+0#0000000#5fd7ff255|E|F| @31 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25||+1&&| +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25 |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|9|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|6|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|9|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|6|,|1| @11|A|l@1 |:+0&&|d|i|f@1|p|u|t| @66 diff --git a/src/testdir/dumps/Test_diff_get_put_linematch_17.dump b/src/testdir/dumps/Test_diff_get_put_linematch_17.dump index 69737fa58c..b8426a39a4 100644 --- a/src/testdir/dumps/Test_diff_get_put_linematch_17.dump +++ b/src/testdir/dumps/Test_diff_get_put_linematch_17.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|D+0#0000000#5fd7ff255|E|F| @31 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25||+1&&| +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25 |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|9|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|8|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|9|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|8|,|1| @11|A|l@1 |:+0&&|d|i|f@1|p|u|t| @66 diff --git a/src/testdir/dumps/Test_diff_get_put_linematch_18.dump b/src/testdir/dumps/Test_diff_get_put_linematch_18.dump index 49ab243871..2b94da9551 100644 --- a/src/testdir/dumps/Test_diff_get_put_linematch_18.dump +++ b/src/testdir/dumps/Test_diff_get_put_linematch_18.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|D+0#0000000#5fd7ff255|E|F| @31 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25||+1&&| +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25 |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|6|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|9|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|6|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|9|,|1| @11|A|l@1 |:+0&&|d|i|f@1|p|u|t| @66 diff --git a/src/testdir/dumps/Test_diff_get_put_linematch_19.dump b/src/testdir/dumps/Test_diff_get_put_linematch_19.dump index cbea3e5602..8fdd9f608a 100644 --- a/src/testdir/dumps/Test_diff_get_put_linematch_19.dump +++ b/src/testdir/dumps/Test_diff_get_put_linematch_19.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|D+0#0000000#ffffff0|E|F| @31||+1&&| +0#0000e05#a8a8a8255@1|D+0#0000000#ffffff0|E|F| @31 | +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25||+1&&| +0#0000e05#a8a8a8255@1>s+0#0000000#ffffff0|o|m|e|t|h|i|n|g| @25 |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|1|3|,|1| @10|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|1|7|,|1| @10|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| |[|+|]| @6|1|3|,|1| @10|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|1|7|,|1| @10|A|l@1 |:+0&&|d|i|f@1|p|u|t| @66 diff --git a/src/testdir/dumps/Test_diff_get_put_linematch_3.dump b/src/testdir/dumps/Test_diff_get_put_linematch_3.dump index cb62a9ef71..ce905130e9 100644 --- a/src/testdir/dumps/Test_diff_get_put_linematch_3.dump +++ b/src/testdir/dumps/Test_diff_get_put_linematch_3.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|5|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| |[|+|]| @6|5|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|5|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| |[|+|]| @6|5|,|1| @11|A|l@1 |:+0&&|5|,|1|0|d|i|f@1|g|e|t| @62 diff --git a/src/testdir/dumps/Test_diff_get_put_linematch_4.dump b/src/testdir/dumps/Test_diff_get_put_linematch_4.dump index 16c2cd874d..c6ea6ddc85 100644 --- a/src/testdir/dumps/Test_diff_get_put_linematch_4.dump +++ b/src/testdir/dumps/Test_diff_get_put_linematch_4.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|5|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| |[|+|]| @6|5|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|5|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| |[|+|]| @6|5|,|1| @11|A|l@1 |:+0&&|4|,|1|7|d|i|f@1|g|e|t| @62 diff --git a/src/testdir/dumps/Test_diff_inline_multiline_07.dump b/src/testdir/dumps/Test_diff_inline_multiline_07.dump index de58a6ac30..b76d549b27 100644 --- a/src/testdir/dumps/Test_diff_inline_multiline_07.dump +++ b/src/testdir/dumps/Test_diff_inline_multiline_07.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_inline_multiline_08.dump b/src/testdir/dumps/Test_diff_inline_multiline_08.dump index 901ea4699d..51c35f5afd 100644 --- a/src/testdir/dumps/Test_diff_inline_multiline_08.dump +++ b/src/testdir/dumps/Test_diff_inline_multiline_08.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_inline_multiline_09.dump b/src/testdir/dumps/Test_diff_inline_multiline_09.dump index 91f59cda25..dc36ed8ffc 100644 --- a/src/testdir/dumps/Test_diff_inline_multiline_09.dump +++ b/src/testdir/dumps/Test_diff_inline_multiline_09.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_inline_multiline_10.dump b/src/testdir/dumps/Test_diff_inline_multiline_10.dump index 212c247975..ad86c4684d 100644 --- a/src/testdir/dumps/Test_diff_inline_multiline_10.dump +++ b/src/testdir/dumps/Test_diff_inline_multiline_10.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| |X+3&&|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @10|1|,|1| @11|A|l@1| +3&&|X|d|i|f|i|l|e|2| @10|1|,|1| @11|A|l@1 |:+0&&> @73 diff --git a/src/testdir/dumps/Test_diff_rnu_01.dump b/src/testdir/dumps/Test_diff_rnu_01.dump index dc7c0f9101..d51d66674c 100644 --- a/src/testdir/dumps/Test_diff_rnu_01.dump +++ b/src/testdir/dumps/Test_diff_rnu_01.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_rnu_02.dump b/src/testdir/dumps/Test_diff_rnu_02.dump index 32ffc4003d..d33a2ee0ab 100644 --- a/src/testdir/dumps/Test_diff_rnu_02.dump +++ b/src/testdir/dumps/Test_diff_rnu_02.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_rnu_03.dump b/src/testdir/dumps/Test_diff_rnu_03.dump index 8c8b938449..0d29b84081 100644 --- a/src/testdir/dumps/Test_diff_rnu_03.dump +++ b/src/testdir/dumps/Test_diff_rnu_03.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_scroll_1.dump b/src/testdir/dumps/Test_diff_scroll_1.dump index ee53c35bbb..9713461012 100644 --- a/src/testdir/dumps/Test_diff_scroll_1.dump +++ b/src/testdir/dumps/Test_diff_scroll_1.dump @@ -8,5 +8,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|d+0#0000000#5fd7ff255|o|l|o|r| @29 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|s+0#0000000#5fd7ff255|i|t| @31 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|a+0#0000000#5fd7ff255|m|e|t|,| @29 -|X+1&#ffffff0|l|e|f|t| @13|5|,|0|-|1| @9|T|o|p| |X+3&&|r|i|g|h|t| @12|5|,|0|-|1| @9|T|o|p +|X+1&#ffffff0|l|e|f|t| @13|5|,|0|-|1| @9|T|o|p| +3&&|X|r|i|g|h|t| @12|5|,|0|-|1| @9|T|o|p |"+0&&|X|r|i|g|h|t|"| |3@1|L|,| |2|6|3|B| @56 diff --git a/src/testdir/dumps/Test_diff_scroll_2.dump b/src/testdir/dumps/Test_diff_scroll_2.dump index 4cac386a6c..d6cd1b9c99 100644 --- a/src/testdir/dumps/Test_diff_scroll_2.dump +++ b/src/testdir/dumps/Test_diff_scroll_2.dump @@ -8,5 +8,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|d+0#0000000#5fd7ff255|o|l|o|r| @29 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|s+0#0000000#5fd7ff255|i|t| @31 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|a+0#0000000#5fd7ff255|m|e|t|,| @29 -|X+1&#ffffff0|l|e|f|t| @13|6|,|1| @11|T|o|p| |X+3&&|r|i|g|h|t| @12|6|,|1| @11|T|o|p +|X+1&#ffffff0|l|e|f|t| @13|6|,|1| @11|T|o|p| +3&&|X|r|i|g|h|t| @12|6|,|1| @11|T|o|p |"+0&&|X|r|i|g|h|t|"| |3@1|L|,| |2|6|3|B| @56 diff --git a/src/testdir/dumps/Test_diff_scroll_change_03.dump b/src/testdir/dumps/Test_diff_scroll_change_03.dump index 6d0c8600f6..5a4088975b 100644 --- a/src/testdir/dumps/Test_diff_scroll_change_03.dump +++ b/src/testdir/dumps/Test_diff_scroll_change_03.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|7|,|3| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|5|,|3| @10|B|o|t +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|7|,|3| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|5|,|3| @10|B|o|t | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_topline_1.dump b/src/testdir/dumps/Test_diff_topline_1.dump index 1d4c9145f0..5b5122621c 100644 --- a/src/testdir/dumps/Test_diff_topline_1.dump +++ b/src/testdir/dumps/Test_diff_topline_1.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|4| @32 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|5| @32 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|6| @32 -|[+1&#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|4|2|%| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|1|,|1| @10|1|9|% +|[+1&#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|4|2|%| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|1|,|1| @10|1|9|% | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_topline_2.dump b/src/testdir/dumps/Test_diff_topline_2.dump index 2d28bd373a..a0f3db79c0 100644 --- a/src/testdir/dumps/Test_diff_topline_2.dump +++ b/src/testdir/dumps/Test_diff_topline_2.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|4| @32 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|5| @32 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|6| @32 -|[+1&#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|4|2|%| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|1|,|1| @10|1|9|% +|[+1&#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|4|2|%| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|1|,|1| @10|1|9|% |9+0&&| @73 diff --git a/src/testdir/dumps/Test_diff_topline_4.dump b/src/testdir/dumps/Test_diff_topline_4.dump index 6043d7ad73..94414b1e79 100644 --- a/src/testdir/dumps/Test_diff_topline_4.dump +++ b/src/testdir/dumps/Test_diff_topline_4.dump @@ -16,5 +16,5 @@ | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|1+0#0000000#5fd7ff255|9| @32 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|0| @32 | +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|2+0#0000000#5fd7ff255|1| @32 -|[+1&#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|T|o|p| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|T|o|p +|[+1&#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|T|o|p| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|0|,|1| @10|T|o|p | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_with_cul_bri_01.dump b/src/testdir/dumps/Test_diff_with_cul_bri_01.dump index 8151088e04..3855fa17c5 100644 --- a/src/testdir/dumps/Test_diff_with_cul_bri_01.dump +++ b/src/testdir/dumps/Test_diff_with_cul_bri_01.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |1|,|1| @5|A|l@1| |<+3&&| |N|a|m|e|]| |[|+|]| |1|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 +|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |1|,|1| @5|A|l@1| +3&&|<| |N|a|m|e|]| |[|+|]| |1|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_with_cul_bri_02.dump b/src/testdir/dumps/Test_diff_with_cul_bri_02.dump index 62126f6b39..c1ae50d6d4 100644 --- a/src/testdir/dumps/Test_diff_with_cul_bri_02.dump +++ b/src/testdir/dumps/Test_diff_with_cul_bri_02.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |2|,|1| @5|A|l@1| |<+3&&| |N|a|m|e|]| |[|+|]| |2|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 +|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |2|,|1| @5|A|l@1| +3&&|<| |N|a|m|e|]| |[|+|]| |2|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_with_cul_bri_03.dump b/src/testdir/dumps/Test_diff_with_cul_bri_03.dump index f32be7385b..bdf8be065e 100644 --- a/src/testdir/dumps/Test_diff_with_cul_bri_03.dump +++ b/src/testdir/dumps/Test_diff_with_cul_bri_03.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |3|,|1| @5|A|l@1| |<+3&&| |N|a|m|e|]| |[|+|]| |3|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 +|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |3|,|1| @5|A|l@1| +3&&|<| |N|a|m|e|]| |[|+|]| |3|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_with_cul_bri_04.dump b/src/testdir/dumps/Test_diff_with_cul_bri_04.dump index 9489f9ab04..aa3ce8e5d4 100644 --- a/src/testdir/dumps/Test_diff_with_cul_bri_04.dump +++ b/src/testdir/dumps/Test_diff_with_cul_bri_04.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |4|,|1| @5|A|l@1| |<+3&&| |N|a|m|e|]| |[|+|]| |4|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 +|<+1#0000000&|o| |N|a|m|e|]| |[|+|]| |4|,|1| @5|A|l@1| +3&&|<| |N|a|m|e|]| |[|+|]| |4|,|1| @5|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @2|0|,|0|-|1| @3|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_with_cursorline_01.dump b/src/testdir/dumps/Test_diff_with_cursorline_01.dump index 31d8b2a189..0b9bcb9bda 100644 --- a/src/testdir/dumps/Test_diff_with_cursorline_01.dump +++ b/src/testdir/dumps/Test_diff_with_cursorline_01.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_with_cursorline_02.dump b/src/testdir/dumps/Test_diff_with_cursorline_02.dump index 9aef7d1fa3..68014acb2c 100644 --- a/src/testdir/dumps/Test_diff_with_cursorline_02.dump +++ b/src/testdir/dumps/Test_diff_with_cursorline_02.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_diff_with_cursorline_03.dump b/src/testdir/dumps/Test_diff_with_cursorline_03.dump index 5bc9e13167..595de46ce1 100644 --- a/src/testdir/dumps/Test_diff_with_cursorline_03.dump +++ b/src/testdir/dumps/Test_diff_with_cursorline_03.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|4|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|4|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_display_visual_block_scroll.dump b/src/testdir/dumps/Test_display_visual_block_scroll.dump deleted file mode 100644 index 36eae0c024..0000000000 --- a/src/testdir/dumps/Test_display_visual_block_scroll.dump +++ /dev/null @@ -1,7 +0,0 @@ -|{+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 -|}+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 -|{+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 -|f+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 ->g| +0#0000001#a8a8a8255| +0#0000000#ffffff0@72 -|}| @73 -|-+2&&@1| |V|I|S|U|A|L| |L|I|N|E| |-@1| +0&&@29|7| @8|1@1|,|1| @9|B|o|t| diff --git a/src/testdir/dumps/Test_hor_scroll_1.dump b/src/testdir/dumps/Test_hor_scroll_1.dump index 615afb8e12..65b16f3ccc 100644 --- a/src/testdir/dumps/Test_hor_scroll_1.dump +++ b/src/testdir/dumps/Test_hor_scroll_1.dump @@ -4,5 +4,5 @@ @19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32 @19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32 |~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|2|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|2|1| @10|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|2|1| @2|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|2|1| @10|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_hor_scroll_2.dump b/src/testdir/dumps/Test_hor_scroll_2.dump index dfe2e98ae0..2b6afa0ecd 100644 --- a/src/testdir/dumps/Test_hor_scroll_2.dump +++ b/src/testdir/dumps/Test_hor_scroll_2.dump @@ -4,5 +4,5 @@ @10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22 @10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22 |~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|3|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|3|1| @10|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|3|1| @2|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|3|1| @10|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_hor_scroll_3.dump b/src/testdir/dumps/Test_hor_scroll_3.dump index db9fd6ff1b..93f94a0ecc 100644 --- a/src/testdir/dumps/Test_hor_scroll_3.dump +++ b/src/testdir/dumps/Test_hor_scroll_3.dump @@ -4,5 +4,5 @@ @19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32 @19| +0&#e0e0e08||+1&#ffffff0| +0&&@19| +0&#e0e0e08| +0&#ffffff0@32 |~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|2|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|2|1| @10|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|2|1| @2|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|2|1| @10|A|l@1 |:+0&&|w|i|n|d|o| |:|s|e|t| |c|u|r|s|o|r|l|i|n|e| @52 diff --git a/src/testdir/dumps/Test_hor_scroll_4.dump b/src/testdir/dumps/Test_hor_scroll_4.dump index 81821604d0..830423ad35 100644 --- a/src/testdir/dumps/Test_hor_scroll_4.dump +++ b/src/testdir/dumps/Test_hor_scroll_4.dump @@ -4,5 +4,5 @@ @10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22 @10| +0&#e0e0e08| +0&#ffffff0@8||+1&&| +0&&@29| +0&#e0e0e08| +0&#ffffff0@22 |~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|3|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|3|1| @10|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|3|1| @2|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|3|1| @10|A|l@1 |:+0&&|w|i|n|d|o| |:|s|e|t| |c|u|r|s|o|r|l|i|n|e| @52 diff --git a/src/testdir/dumps/Test_hor_scroll_5.dump b/src/testdir/dumps/Test_hor_scroll_5.dump index f2986f3796..d706910fc0 100644 --- a/src/testdir/dumps/Test_hor_scroll_5.dump +++ b/src/testdir/dumps/Test_hor_scroll_5.dump @@ -4,5 +4,5 @@ @20||+1&&| +0&&@53 @20||+1&&| +0&&@53 |~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @52 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|4|1| @2|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|4|1| @10|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|4|1| @2|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @22|1|,|4|1| @10|A|l@1 |:+0&&|w|i|n|d|o| |:|s|e|t| |n|o|c|u|r|s|o|r|l|i|n|e| |n|o|c|u|r|s|o|r|c|o|l|u|m|n| @35 diff --git a/src/testdir/dumps/Test_linematch_3diffs1.dump b/src/testdir/dumps/Test_linematch_3diffs1.dump index d8f23e84bd..a010d27617 100644 --- a/src/testdir/dumps/Test_linematch_3diffs1.dump +++ b/src/testdir/dumps/Test_linematch_3diffs1.dump @@ -16,5 +16,5 @@ |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 |~| @23||+1#0000000&|~+0#4040ff13&| @22||+1#0000000&|~+0#4040ff13&| @22 -|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|0|-|1| @3|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|0|-|1| @3|A|l@1| |X+3&&|d|i|f|i|l|e|3| @3|1|,|0|-|1| @3|A|l@1 +|X+1#0000000&|d|i|f|i|l|e|1| @4|1|,|0|-|1| @3|A|l@1| |X|d|i|f|i|l|e|2| @3|1|,|0|-|1| @3|A|l@1| +3&&|X|d|i|f|i|l|e|3| @3|1|,|0|-|1| @3|A|l@1 |"+0&&|X|d|i|f|i|l|e|3|"| |5|L|,| |4|5|B| @56 diff --git a/src/testdir/dumps/Test_listchars_01.dump b/src/testdir/dumps/Test_listchars_01.dump index 72fff585c2..a7de310690 100644 --- a/src/testdir/dumps/Test_listchars_01.dump +++ b/src/testdir/dumps/Test_listchars_01.dump @@ -6,5 +6,5 @@ |~| @18||+1#0000000&|~+0#4040ff13&| @3||+1#0000000&|~+0#4040ff13&| @31 |~| @18||+1#0000000&|~+0#4040ff13&| @3||+1#0000000&|~+0#4040ff13&| @31 |~| @18||+1#0000000&|~+0#4040ff13&| @3||+1#0000000&|~+0#4040ff13&| @31 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<|]| |1|,| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @3|1|,|1| @9|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<|]| |1|,| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @3|1|,|1| @9|A|l@1 | +0&&@59 diff --git a/src/testdir/dumps/Test_listchars_02.dump b/src/testdir/dumps/Test_listchars_02.dump index b7be52e890..d7e05df9ae 100644 --- a/src/testdir/dumps/Test_listchars_02.dump +++ b/src/testdir/dumps/Test_listchars_02.dump @@ -6,5 +6,5 @@ |~| @18||+1#0000000&|~+0#4040ff13&| @2||+1#0000000&|~+0#4040ff13&| @32 |~| @18||+1#0000000&|~+0#4040ff13&| @2||+1#0000000&|~+0#4040ff13&| @32 |~| @18||+1#0000000&|~+0#4040ff13&| @2||+1#0000000&|~+0#4040ff13&| @32 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<| |1|,| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @3|1|,|1| @10|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<| |1|,| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @3|1|,|1| @10|A|l@1 | +0&&@59 diff --git a/src/testdir/dumps/Test_listchars_03.dump b/src/testdir/dumps/Test_listchars_03.dump index 13aca6d2f7..d54b3e50fa 100644 --- a/src/testdir/dumps/Test_listchars_03.dump +++ b/src/testdir/dumps/Test_listchars_03.dump @@ -6,5 +6,5 @@ |~| @18||+1#0000000&|~+0#4040ff13&| @1||+1#0000000&|~+0#4040ff13&| @33 |~| @18||+1#0000000&|~+0#4040ff13&| @1||+1#0000000&|~+0#4040ff13&| @33 |~| @18||+1#0000000&|~+0#4040ff13&| @1||+1#0000000&|~+0#4040ff13&| @33 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<| |1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @4|1|,|1| @10|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<| |1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @4|1|,|1| @10|A|l@1 | +0&&@59 diff --git a/src/testdir/dumps/Test_listchars_04.dump b/src/testdir/dumps/Test_listchars_04.dump index e62c5aff20..694e6eadca 100644 --- a/src/testdir/dumps/Test_listchars_04.dump +++ b/src/testdir/dumps/Test_listchars_04.dump @@ -6,5 +6,5 @@ |~| @18||+1#0000000&|~+0#4040ff13&| ||+1#0000000&|~+0#4040ff13&| @34 |~| @18||+1#0000000&|~+0#4040ff13&| ||+1#0000000&|~+0#4040ff13&| @34 |~| @18||+1#0000000&|~+0#4040ff13&| ||+1#0000000&|~+0#4040ff13&| @34 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<|1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @4|1|,|1| @11|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<|1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @4|1|,|1| @11|A|l@1 | +0&&@59 diff --git a/src/testdir/dumps/Test_listchars_05.dump b/src/testdir/dumps/Test_listchars_05.dump index 89b759fb42..7ecb79738a 100644 --- a/src/testdir/dumps/Test_listchars_05.dump +++ b/src/testdir/dumps/Test_listchars_05.dump @@ -6,5 +6,5 @@ |~| @18||+1#0000000&|~+0#4040ff13&||+1#0000000&|~+0#4040ff13&| @35 |~| @18||+1#0000000&|~+0#4040ff13&||+1#0000000&|~+0#4040ff13&| @35 |~| @18||+1#0000000&|~+0#4040ff13&||+1#0000000&|~+0#4040ff13&| @35 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 | +0&&@59 diff --git a/src/testdir/dumps/Test_listchars_06.dump b/src/testdir/dumps/Test_listchars_06.dump index 9f4b5d30e2..9176c5fded 100644 --- a/src/testdir/dumps/Test_listchars_06.dump +++ b/src/testdir/dumps/Test_listchars_06.dump @@ -6,5 +6,5 @@ |~| @18||+1#0000000&|~+0#4040ff13&| @3||+1#0000000&|~+0#4040ff13&| @31 |~| @18||+1#0000000&|~+0#4040ff13&| @3||+1#0000000&|~+0#4040ff13&| @31 |~| @18||+1#0000000&|~+0#4040ff13&| @3||+1#0000000&|~+0#4040ff13&| @31 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<+3&&|]| |1|,| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @3|1|,|1| @9|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| +3&&|<|]| |1|,| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @3|1|,|1| @9|A|l@1 |:+0&&|s|e|t| |n|o|w|r|a|p| |f|o|l|d|c|o|l|u|m|n|=|4| @35 diff --git a/src/testdir/dumps/Test_listchars_07.dump b/src/testdir/dumps/Test_listchars_07.dump index ad81656a50..572bf248ff 100644 --- a/src/testdir/dumps/Test_listchars_07.dump +++ b/src/testdir/dumps/Test_listchars_07.dump @@ -6,5 +6,5 @@ |~| @18||+1#0000000&|~+0#4040ff13&||+1#0000000&|~+0#4040ff13&| @35 |~| @18||+1#0000000&|~+0#4040ff13&||+1#0000000&|~+0#4040ff13&| @35 |~| @18||+1#0000000&|~+0#4040ff13&||+1#0000000&|~+0#4040ff13&| @35 -|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| |<+3&&| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +|<+1#0000000&|a|m|e|]| |[|+|]| |1|,|1| @3|A|l@1| +3&&|<| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 |:+0&&|s|e|t| |n|o|w|r|a|p| |f|o|l|d|c|o|l|u|m|n|=|4| @35 diff --git a/src/testdir/dumps/Test_matchparen_sh_case_1.dump b/src/testdir/dumps/Test_matchparen_sh_case_1.dump index 8494e0e3ab..7eccca7536 100644 --- a/src/testdir/dumps/Test_matchparen_sh_case_1.dump +++ b/src/testdir/dumps/Test_matchparen_sh_case_1.dump @@ -1,5 +1,5 @@ |#+0#0000e05#ffffff0|!|/|b|i|n|/|s|h| +0#0000000&@65 -|S+0#00e0e07&|U|S|U|W|U|_|P|R|I|N|T|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@58 +|S+0#00e0e07&|U|S|U|W|U|_|P|R|I|N|T|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@58 @2|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|{|L|E|V|E|L|}|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&@54 @4|"+0#af5f00255&|$+0#e000e06&|S|U|S|U|W|U|_|S|H|_|N|O|T|I|C|E|"+0#af5f00255&>)| +0#0000000&@50 @4|$+0#e000e06&|{|S|U|S|U|W|U|_|S|}| +0#0000000&|&+0#af5f00255&@1| +0#0000000&|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|1+0#e000002&| +0#0000000&@47 diff --git a/src/testdir/dumps/Test_matchparen_sh_case_2.dump b/src/testdir/dumps/Test_matchparen_sh_case_2.dump index ae1adfb74b..8e87b98445 100644 --- a/src/testdir/dumps/Test_matchparen_sh_case_2.dump +++ b/src/testdir/dumps/Test_matchparen_sh_case_2.dump @@ -1,5 +1,5 @@ |#+0#0000e05#ffffff0|!|/|b|i|n|/|s|h| +0#0000000&@65 -|S+0#00e0e07&|U|S|U|W|U|_|P|R|I|N|T|(|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@58 +|S+0#00e0e07&|U|S|U|W|U|_|P|R|I|N|T|(+0#e000e06&|)| +0#0000000&|(+0#af5f00255&| +0#0000000&@58 @2|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|{|L|E|V|E|L|}|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&@54 @4|"+0#af5f00255&|$+0#e000e06&|S|U|S|U|W|U|_|S|H|_|N|O|T|I|C|E|"+0#af5f00255&|)| +0#0000000&|f|o@1|b|a|r> @43 @4|$+0#e000e06&|{|S|U|S|U|W|U|_|S|}| +0#0000000&|&+0#af5f00255&@1| +0#0000000&|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|1+0#e000002&| +0#0000000&@47 diff --git a/src/testdir/dumps/Test_multistatusline_carry_hl_01.dump b/src/testdir/dumps/Test_multistatusline_carry_hl_01.dump new file mode 100644 index 0000000000..724d844bd6 --- /dev/null +++ b/src/testdir/dumps/Test_multistatusline_carry_hl_01.dump @@ -0,0 +1,9 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|L+3#0000000&|1|A| @68|L+0&#ffff4012|1|B +|L|2| |c|a|r@1|i|e|d| |S|e|a|r|c|h| @57 +|L+3&#ffffff0|3| |r|e|s|e|t| @66 +|L+0#ffff4012#4040ff13|4| |u|s|e|r|2| @66 +|L|5| |c|a|r@1|i|e|d| |u|s|e|r|2| @58 +|L+3#0000000#ffffff0|6| |r|e|s|e|t| @66 +| +0&&@74 diff --git a/src/testdir/dumps/Test_osc52_paste_05.dump b/src/testdir/dumps/Test_osc52_paste_05.dump new file mode 100644 index 0000000000..32448367fb --- /dev/null +++ b/src/testdir/dumps/Test_osc52_paste_05.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@74 +|h|e|l@1|o| @69 +>t|e|s|t| @70 +|w|o|r|l|d|!| @68 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|3|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_popup_clipwindow_bottom_clip.dump b/src/testdir/dumps/Test_popup_clipwindow_bottom_clip.dump new file mode 100644 index 0000000000..b5d79480fb --- /dev/null +++ b/src/testdir/dumps/Test_popup_clipwindow_bottom_clip.dump @@ -0,0 +1,14 @@ +>h+0&#ffffff0|o|s|t| |l|i|n|e| |1| @28 +|h|o|s|t| |l|i|n|e| |2| @28 +|h|o|s|t| |l|i|n|e| |3| @28 +|h|o|s|t|╔+0#0000001#e0e0e08|═@8|╗| +0#0000000#ffffff0@24 +|h|o|s|t|║+0#0000001#e0e0e08| |p|o|p|u|p| |A| |║| +0#0000000#ffffff0@24 +|h|o|s|t|║+0#0000001#e0e0e08| |p|o|p|u|p| |B| |║| +0#0000000#ffffff0@24 +|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @8|1|,|1| @11|T|o|p +| +0&&@39 +|~+0#4040ff13&| @38 +|~| @38 +|~| @38 +|~| @38 +|[+1#0000000&|N|o| |N|a|m|e|]| @12|0|,|0|-|1| @9|A|l@1 +| +0&&@39 diff --git a/src/testdir/dumps/Test_popup_clipwindow_hidden.dump b/src/testdir/dumps/Test_popup_clipwindow_hidden.dump new file mode 100644 index 0000000000..c5f8930695 --- /dev/null +++ b/src/testdir/dumps/Test_popup_clipwindow_hidden.dump @@ -0,0 +1,14 @@ +|h+0&#ffffff0|o|s|t| |l|i|n|e| |4|5| @27 +|h|o|s|t| |l|i|n|e| |4|6| @27 +|h|o|s|t| |l|i|n|e| |4|7| @27 +|h|o|s|t| |l|i|n|e| |4|8| @27 +|h|o|s|t| |l|i|n|e| |4|9| @27 +>h|o|s|t| |l|i|n|e| |5|0| @27 +|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @8|5|0|,|1| @10|B|o|t +| +0&&@39 +|~+0#4040ff13&| @38 +|~| @38 +|~| @38 +|~| @38 +|[+1#0000000&|N|o| |N|a|m|e|]| @12|0|,|0|-|1| @9|A|l@1 +| +0&&@39 diff --git a/src/testdir/dumps/Test_popup_clipwindow_left_clip.dump b/src/testdir/dumps/Test_popup_clipwindow_left_clip.dump new file mode 100644 index 0000000000..5d38f98d2a --- /dev/null +++ b/src/testdir/dumps/Test_popup_clipwindow_left_clip.dump @@ -0,0 +1,14 @@ +| +0&#ffffff0@26||+1&&>h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|═+0#0000001#e0e0e08@7|╗| +0#0000000#ffffff0|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&| +0&&|p+0#0000001#e0e0e08|o|p|u|p| |A|║| |n+0#0000000#ffffff0|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&| +0&&|p+0#0000001#e0e0e08|o|p|u|p| |B|║| |n+0#0000000#ffffff0|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&| +0&&|p+0#0000001#e0e0e08|o|p|u|p| |C|║| |n+0#0000000#ffffff0|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|═+0#0000001#e0e0e08@7|╝| +0#0000000#ffffff0|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +|~+0#4040ff13&| @25||+1#0000000&|h+0&&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d +| @31|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popup_clipwindow_right_clip.dump b/src/testdir/dumps/Test_popup_clipwindow_right_clip.dump new file mode 100644 index 0000000000..6427f94a5a --- /dev/null +++ b/src/testdir/dumps/Test_popup_clipwindow_right_clip.dump @@ -0,0 +1,14 @@ +>h+0&#ffffff0|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&| +0&&@26 +|h|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e|╔+0#0000001#e0e0e08|═@3||+1#0000000#ffffff0|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e|║+0#0000001#e0e0e08| |p|o|p||+1#0000000#ffffff0|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e|║+0#0000001#e0e0e08| |p|o|p||+1#0000000#ffffff0|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e|║+0#0000001#e0e0e08| |p|o|p||+1#0000000#ffffff0|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e|╚+0#0000001#e0e0e08|═@3||+1#0000000#ffffff0|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&|~+0#4040ff13&| @25 +|h+0#0000000&|o|s|t| |c|o|n|t|e|n|t| |l|i|n|e| |a|b|c|d||+1&&|~+0#4040ff13&| @25 +| +0#0000000&@31|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popup_clipwindow_top_clip.dump b/src/testdir/dumps/Test_popup_clipwindow_top_clip.dump new file mode 100644 index 0000000000..9876f15cce --- /dev/null +++ b/src/testdir/dumps/Test_popup_clipwindow_top_clip.dump @@ -0,0 +1,14 @@ +| +0&#ffffff0@39 +|~+0#4040ff13&| @38 +|~| @38 +|~| @38 +|~| @38 +|[+1#0000000&|N|o| |N|a|m|e|]| @12|0|,|0|-|1| @9|A|l@1 +>h+0&&|o|s|t|║+0#0000001#e0e0e08| |p|o|p|u|p| |B| |║| +0#0000000#ffffff0@24 +|h|o|s|t|║+0#0000001#e0e0e08| |p|o|p|u|p| |C| |║| +0#0000000#ffffff0@24 +|h|o|s|t|╚+0#0000001#e0e0e08|═@8|╝| +0#0000000#ffffff0@24 +|h|o|s|t| |l|i|n|e| |4| @28 +|h|o|s|t| |l|i|n|e| |5| @28 +|h|o|s|t| |l|i|n|e| |6| @28 +|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @8|1|,|1| @11|T|o|p +| +0&&@39 diff --git a/src/testdir/dumps/Test_popup_opacity_move_after_close.dump b/src/testdir/dumps/Test_popup_opacity_move_after_close.dump new file mode 100644 index 0000000000..9b1edba5a6 --- /dev/null +++ b/src/testdir/dumps/Test_popup_opacity_move_after_close.dump @@ -0,0 +1,8 @@ +>a+0&#ffffff0|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y +|z| @23 +|a|b|c|d|e|f|g|h|i|j|k|╔+0#0000001#ffd7ff255|═@4|╗|s+0#0000000#ffffff0|t|u|v|w|x|y +|z| @9|║+0#0000001#ffd7ff255|A| +0#875f87255&@3|║+0#0000001&| +0#0000000#ffffff0@6 +|a|b|c|d|e|f|g|h|i|j|k|╚+0#0000001#ffd7ff255|═@4|╝|s+0#0000000#ffffff0|t|u|v|w|x|y +|z| @23 +|@+0#4040ff13&@2| @21 +| +0#0000000&@12|1|,|1| @4|T|o|p| diff --git a/src/testdir/dumps/Test_popup_prop_not_visible_01.dump b/src/testdir/dumps/Test_popup_prop_not_visible_01.dump index dbcfda1161..20f4d46586 100644 --- a/src/testdir/dumps/Test_popup_prop_not_visible_01.dump +++ b/src/testdir/dumps/Test_popup_prop_not_visible_01.dump @@ -6,5 +6,5 @@ |~+0#4040ff13&| @41||+1#0000000&|~+0#4040ff13&| @29 |~| @41||+1#0000000&|~+0#4040ff13&| @29 |~| @41||+1#0000000&|~+0#4040ff13&| @29 -|[+1#0000000&|N|o| |N|a|m|e|]| @15|0|,|0|-|1| @9|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @2|1|,|0|-|1| @6|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| @15|0|,|0|-|1| @9|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @2|1|,|0|-|1| @6|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_popup_prop_not_visible_01a.dump b/src/testdir/dumps/Test_popup_prop_not_visible_01a.dump index 0b97cb832d..e048949de9 100644 --- a/src/testdir/dumps/Test_popup_prop_not_visible_01a.dump +++ b/src/testdir/dumps/Test_popup_prop_not_visible_01a.dump @@ -6,5 +6,5 @@ |~+0#4040ff13&| @41||+1#0000000&|~+0#4040ff13&| @29 |~| @41||+1#0000000&|~+0#4040ff13&| @29 |~| @41||+1#0000000&|~+0#4040ff13&| @29 -|[+1#0000000&|N|o| |N|a|m|e|]| @15|0|,|0|-|1| @9|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @2|1|,|0|-|1| @6|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| @15|0|,|0|-|1| @9|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @2|1|,|0|-|1| @6|A|l@1 |:+0&&|c|a|l@1| |p|o|p|u|p|_|h|i|d|e|(|g|:|s|o|m|e|_|i|d|)| @47 diff --git a/src/testdir/dumps/Test_popup_prop_not_visible_01b.dump b/src/testdir/dumps/Test_popup_prop_not_visible_01b.dump index e8a5c2e353..c91b201003 100644 --- a/src/testdir/dumps/Test_popup_prop_not_visible_01b.dump +++ b/src/testdir/dumps/Test_popup_prop_not_visible_01b.dump @@ -6,5 +6,5 @@ |~+0#4040ff13&| @41||+1#0000000&|~+0#4040ff13&| @29 |~| @41||+1#0000000&|~+0#4040ff13&| @29 |~| @41||+1#0000000&|~+0#4040ff13&| @29 -|[+1#0000000&|N|o| |N|a|m|e|]| @15|0|,|0|-|1| @9|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @2|1|,|0|-|1| @6|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| @15|0|,|0|-|1| @9|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @2|1|,|0|-|1| @6|A|l@1 |:+0&&|c|a|l@1| |p|o|p|u|p|_|s|h|o|w|(|g|:|s|o|m|e|_|i|d|)| @47 diff --git a/src/testdir/dumps/Test_popup_prop_not_visible_02.dump b/src/testdir/dumps/Test_popup_prop_not_visible_02.dump index 1d1a5531c9..e4b2aec90f 100644 --- a/src/testdir/dumps/Test_popup_prop_not_visible_02.dump +++ b/src/testdir/dumps/Test_popup_prop_not_visible_02.dump @@ -6,5 +6,5 @@ |~+0#4040ff13#ffffff0| @55||+1#0000000&|~+0#4040ff13&| @15 |~| @55||+1#0000000&|~+0#4040ff13&| @15 |~| @55||+1#0000000&|~+0#4040ff13&| @15 -|[+1#0000000&|N|o| |N|a|m|e|]| @29|0|,|0|-|1| @9|A|l@1| |<+3&&|m|e|]| |[|+|]| |1|,|0|-|1| @2 +|[+1#0000000&|N|o| |N|a|m|e|]| @29|0|,|0|-|1| @9|A|l@1| +3&&|<|m|e|]| |[|+|]| |1|,|0|-|1| @2 |:+0&&|v|e|r|t| |r|e|s|i|z|e| |-|1|4| @58 diff --git a/src/testdir/dumps/Test_popup_prop_not_visible_03.dump b/src/testdir/dumps/Test_popup_prop_not_visible_03.dump index caaa881fe3..a056cd867a 100644 --- a/src/testdir/dumps/Test_popup_prop_not_visible_03.dump +++ b/src/testdir/dumps/Test_popup_prop_not_visible_03.dump @@ -6,5 +6,5 @@ |~+0#4040ff13&| @63||+1#0000000&|~+0#4040ff13&| @7 |~| @63||+1#0000000&|~+0#4040ff13&| @7 |~| @63||+1#0000000&|~+0#4040ff13&| @7 -|[+1#0000000&|N|o| |N|a|m|e|]| @37|0|,|0|-|1| @9|A|l@1| |<+3&&|[|+|]| |1|,|0|- +|[+1#0000000&|N|o| |N|a|m|e|]| @37|0|,|0|-|1| @9|A|l@1| +3&&|<|[|+|]| |1|,|0|- |:+0&&|v|e|r|t| |r|e|s|i|z|e| |-|8| @59 diff --git a/src/testdir/dumps/Test_popup_settext_scrollbar_disappear_1.dump b/src/testdir/dumps/Test_popup_settext_scrollbar_disappear_1.dump new file mode 100644 index 0000000000..d11662fe75 --- /dev/null +++ b/src/testdir/dumps/Test_popup_settext_scrollbar_disappear_1.dump @@ -0,0 +1,15 @@ +> +0&#ffffff0@49 +|~+0#4040ff13&| @48 +|~| @2|╔+0#0000001#ffd7ff255|═@30|╗| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|║+0#0000001#ffd7ff255|h|e|l@1|o| |w|o|r|l|d| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@12 +|~| @2|╚+0#0000001#ffd7ff255|═@30|╝| +0#4040ff13#ffffff0@12 +| +0#0000000&@31|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_popup_settext_scrollbar_disappear_2.dump b/src/testdir/dumps/Test_popup_settext_scrollbar_disappear_2.dump new file mode 100644 index 0000000000..52dc32b8d4 --- /dev/null +++ b/src/testdir/dumps/Test_popup_settext_scrollbar_disappear_2.dump @@ -0,0 +1,15 @@ +> +0&#ffffff0@49 +|~+0#4040ff13&| @48 +|~| @2|╔+0#0000001#ffd7ff255|═@29|╗| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255|s|h|o|r|t| @24|║| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|║+0#0000001#ffd7ff255| +0#4040ff13&@29|║+0#0000001&| +0#4040ff13#ffffff0@13 +|~| @2|╚+0#0000001#ffd7ff255|═@29|╝| +0#4040ff13#ffffff0@13 +|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t@1|e|x|t|(|g|:|p|,| |[|'|s|h|o|r|t|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_popupwin_20.dump b/src/testdir/dumps/Test_popupwin_20.dump index 692708beb0..e6c8421786 100644 --- a/src/testdir/dumps/Test_popupwin_20.dump +++ b/src/testdir/dumps/Test_popupwin_20.dump @@ -5,8 +5,8 @@ |5+0#0000000#ffffff0| @40||| @11||| @17|X+0#0000001#ffd7ff255 |6+0#0000000#ffffff0| |++0#0000001#ffd7ff255|-@8| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@5|+|-@11|+| @18 |7| ||+0#0000001#ffd7ff255|b|o|r|d|e|r| |T|L| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@3|p|a|d@1|i|n|g|s| @1| +0#0000000#ffffff0@38 -|8| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@13||+0#0000001#ffd7ff255| @2|w|r|a|p@1|e|d| |l|o|n|g|e|r| |t|e| @2|| -|9+0#0000000#ffffff0| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@13||+0#0000001#ffd7ff255| @2|x|t| @17|| +|8| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@17||+0#0000001#ffd7ff255| @2|w|r|a|p@1|e|d| |l|o|n|g|e| @2|| +|9+0#0000000#ffffff0| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@17||+0#0000001#ffd7ff255| @2|r| |t|e|x|t| @9|| |1+0#0000000#ffffff0|0| @19| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@38 |1@1| @46||+0#0000001#ffd7ff255| @2|r|i|g|h|t| |a|l|i|g|n|e|d| |t|e|x|t| @2|| |1+0#0000000#ffffff0|2| @72 diff --git a/src/testdir/dumps/Test_popupwin_21.dump b/src/testdir/dumps/Test_popupwin_21.dump index 6398549db8..d4f92f359b 100644 --- a/src/testdir/dumps/Test_popupwin_21.dump +++ b/src/testdir/dumps/Test_popupwin_21.dump @@ -5,8 +5,8 @@ |5+0#0000000#ffffff0| @40|║| @11|║| @17|X+0#0000001#ffd7ff255 |6+0#0000000#ffffff0| |╔+0#0000001#ffd7ff255|═@8| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@5|╚|═@11|╝| @18 |7| |║+0#0000001#ffd7ff255|b|o|r|d|e|r| |T|L| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@3|p|a|d@1|i|n|g|s| @1| +0#0000000#ffffff0@38 -|8| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@13|║+0#0000001#ffd7ff255| @2|w|r|a|p@1|e|d| |l|o|n|g|e|r| |t|e| @2|║ -|9+0#0000000#ffffff0| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@13|║+0#0000001#ffd7ff255| @2|x|t| @17|║ +|8| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@17|║+0#0000001#ffd7ff255| @2|w|r|a|p@1|e|d| |l|o|n|g|e| @2|║ +|9+0#0000000#ffffff0| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@17|║+0#0000001#ffd7ff255| @2|r| |t|e|x|t| @9|║ |1+0#0000000#ffffff0|0| @19| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@38 |1@1| @46|║+0#0000001#ffd7ff255| @2|r|i|g|h|t| |a|l|i|g|n|e|d| |t|e|x|t| @2|║ |1+0#0000000#ffffff0|2| @72 diff --git a/src/testdir/dumps/Test_popupwin_drag_minwidth_1.dump b/src/testdir/dumps/Test_popupwin_drag_minwidth_1.dump index fbeec7a901..5e20f29281 100644 --- a/src/testdir/dumps/Test_popupwin_drag_minwidth_1.dump +++ b/src/testdir/dumps/Test_popupwin_drag_minwidth_1.dump @@ -1,10 +1,10 @@ >╔+0#0000001#ffd7ff255|═@73 -|║|0| @72 -|║|1| @72 -|║|2| @72 -|║|3| @72 -|║|4| @72 -|║|5| @72 -|║|6| @72 -|║|7| @72 -|║|8| @72 +|║|0| @71| +0#0000000#0000001 +|║+0#0000001#ffd7ff255|1| @71| +0#0000000#0000001 +|║+0#0000001#ffd7ff255|2| @71| +0#0000000#a8a8a8255 +|║+0#0000001#ffd7ff255|3| @71| +0#0000000#a8a8a8255 +|║+0#0000001#ffd7ff255|4| @71| +0#0000000#a8a8a8255 +|║+0#0000001#ffd7ff255|5| @71| +0#0000000#a8a8a8255 +|║+0#0000001#ffd7ff255|6| @71| +0#0000000#a8a8a8255 +|║+0#0000001#ffd7ff255|7| @71| +0#0000000#a8a8a8255 +|╚+0#0000001#ffd7ff255|═@73 diff --git a/src/testdir/dumps/Test_popupwin_drag_minwidth_2.dump b/src/testdir/dumps/Test_popupwin_drag_minwidth_2.dump index b4edcfea03..8d8a9983b4 100644 --- a/src/testdir/dumps/Test_popupwin_drag_minwidth_2.dump +++ b/src/testdir/dumps/Test_popupwin_drag_minwidth_2.dump @@ -2,9 +2,9 @@ |~+0#4040ff13&| @73 |~| @73 |~| @73 -|~| @26|╔+0#0000001#ffd7ff255|═@44|╗ -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|0| @42| +0#0000000#0000001|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|1| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|2| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|3| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -| +0#0000000#ffffff0@27|╚+0#0000001#ffd7ff255|═@44|╝ +|~| @27|╔+0#0000001#ffd7ff255|═@43|╗ +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|0| @41| +0#0000000#0000001|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|1| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|2| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|3| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +| +0#0000000#ffffff0@28|╚+0#0000001#ffd7ff255|═@43|╝ diff --git a/src/testdir/dumps/Test_popupwin_drag_minwidth_3.dump b/src/testdir/dumps/Test_popupwin_drag_minwidth_3.dump index e429d3809e..d714ac2760 100644 --- a/src/testdir/dumps/Test_popupwin_drag_minwidth_3.dump +++ b/src/testdir/dumps/Test_popupwin_drag_minwidth_3.dump @@ -1,10 +1,10 @@ > +0&#ffffff0@74 |~+0#4040ff13&| @73 -|~| @26|╔+0#0000001#ffd7ff255|═@44|╗ -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|0| @42| +0#0000000#0000001|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|1| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|2| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|3| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|4| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|~+0#4040ff13#ffffff0| @26|║+0#0000001#ffd7ff255|5| @42| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -| +0#0000000#ffffff0@27|╚+0#0000001#ffd7ff255|═@44|╝ +|~| @27|╔+0#0000001#ffd7ff255|═@43|╗ +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|0| @41| +0#0000000#0000001|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|1| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|2| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|3| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|4| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|~+0#4040ff13#ffffff0| @27|║+0#0000001#ffd7ff255|5| @41| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +| +0#0000000#ffffff0@28|╚+0#0000001#ffd7ff255|═@43|╝ diff --git a/src/testdir/dumps/Test_popupwin_firstline_1.dump b/src/testdir/dumps/Test_popupwin_firstline_1.dump index b3b0349305..5e79f57b54 100644 --- a/src/testdir/dumps/Test_popupwin_firstline_1.dump +++ b/src/testdir/dumps/Test_popupwin_firstline_1.dump @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 |2| @73 |3| @73 -|4| @32|3+0#0000001#ffd7ff255@4| | +0#0000000#a8a8a8255| +0&#ffffff0@33 -|5| @32|4+0#0000001#ffd7ff255@1| @3| +0#0000000#0000001| +0&#ffffff0@33 -|6| @32|5+0#0000001#ffd7ff255| @4| +0#0000000#0000001| +0&#ffffff0@33 -|7| @32|6+0#0000001#ffd7ff255@5| +0#0000000#a8a8a8255| +0&#ffffff0@33 +|4| @27|3+0#0000001#ffd7ff255@4| @10| +0#0000000#a8a8a8255| +0&#ffffff0@28 +|5| @27|4+0#0000001#ffd7ff255@1| @13| +0#0000000#0000001| +0&#ffffff0@28 +|6| @27|5+0#0000001#ffd7ff255| @14| +0#0000000#0000001| +0&#ffffff0@28 +|7| @27|6+0#0000001#ffd7ff255@5| @9| +0#0000000#a8a8a8255| +0&#ffffff0@28 |8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_mask_3.dump b/src/testdir/dumps/Test_popupwin_mask_3.dump index 40681fb4ca..8bd605af9b 100644 --- a/src/testdir/dumps/Test_popupwin_mask_3.dump +++ b/src/testdir/dumps/Test_popupwin_mask_3.dump @@ -1,12 +1,12 @@ >1+0&#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7| +0&#e0e0e08@9 |1+0&#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|x+0#0000001#ffd7ff255@8|8+0#0000000#ffffff0|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3| +0&#e0e0e08|s|o|m|e| |0+0&#ffffff0|4|1|t+0&#e0e0e08| -|1+0&#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|y+0#0000001#ffd7ff255@8|8+0#0000000#ffffff0|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3| +0&#e0e0e08|3+0&#ffffff0|8|3|t+0&#e0e0e08|h|0+0&#ffffff0|4|1|l+0&#e0e0e08|i +|1+0&#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|y+0#0000001#ffd7ff255@8|8+0#0000000#ffffff0|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3| +0&#e0e0e08|3+0&#ffffff0|8|3|t+0&#e0e0e08|h|0+0&#ffffff0|4|1|l+0&#e0e0e08| |1+0&#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3| +0&#e0e0e08@8|4+0&#ffffff0|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|═+0#0000001#ffd7ff255@10 -|1+0#0000000#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|║+0#0000001#ffd7ff255| @4|9+0#0000000#ffffff0|4|0| +0#0000001#ffd7ff255@3 -|1+0#0000000#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|║+0#0000001#ffd7ff255| |j|u|s|t|9+0#0000000#ffffff0|4|0|e+0#0000001#ffd7ff255| |l|i +|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|═+0#0000001#ffd7ff255@9|X +|1+0#0000000#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|║+0#0000001#ffd7ff255| @4|9+0#0000000#ffffff0|4|0| +0#0000001#ffd7ff255@2|║ +|1+0#0000000#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|║+0#0000001#ffd7ff255| |j|u|s|t|9+0#0000000#ffffff0|4|0|e+0#0000001#ffd7ff255| @1|║ |1+0#0000000#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|║+0#0000001#ffd7ff255| @10|2+0#0000000#ffffff0 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|╚+0#0000001#ffd7ff255|═|7+0#0000000#ffffff0|3|8|═+0#0000001#ffd7ff255@4|1+0#0000000#ffffff0|4|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 diff --git a/src/testdir/dumps/Test_popupwin_mask_5.dump b/src/testdir/dumps/Test_popupwin_mask_5.dump index 78cc6f0858..63ba30dea6 100644 --- a/src/testdir/dumps/Test_popupwin_mask_5.dump +++ b/src/testdir/dumps/Test_popupwin_mask_5.dump @@ -6,8 +6,8 @@ |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 |1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -| +0&#e0e0e08@11|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|═+0#0000001#ffd7ff255@13|X|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|o+0&#e0e0e08|m|e| |5+0&#ffffff0|6|7|t+0&#e0e0e08| @3|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| @4|2+0#0000000#ffffff0|9|3| +0#0000001#ffd7ff255@6|║|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 -|:| |t+0&#e0e0e08|h| +0&#ffffff0@2|l+0&#e0e0e08|i|n|e| | +0&#ffffff0@28|║+0#0000001#ffd7ff255| |j|u|s|t| +0#0000000#ffffff0@2|e+0#0000001#ffd7ff255| |l|i|n|e| |║|,+0#0000000#ffffff0|1| @10|T|o|p| +|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|═+0#0000001#ffd7ff255@13|X|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 +| +0&#e0e0e08@11|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| @4|2+0#0000000#ffffff0|9|3| +0#0000001#ffd7ff255@6|║|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 +|o+0&#e0e0e08|m|e| |5+0&#ffffff0|6|7|t+0&#e0e0e08| @3|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| |j|u|s|t|2+0#0000000#ffffff0|9|3|e+0#0000001#ffd7ff255| |l|i|n|e| |║|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 +|1|2|t+0&#e0e0e08|h|5+0&#ffffff0|6|7|l+0&#e0e0e08|i|n|e| |1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| @10|3+0#0000000#ffffff0|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2 +| +0&#e0e0e08@6| +0&#ffffff0@33|╚+0#0000001#ffd7ff255|═| +0#0000000#ffffff0@2|═+0#0000001#ffd7ff255@4| +0#0000000#ffffff0@3|═+0#0000001#ffd7ff255@1|╝|,+0#0000000#ffffff0|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump new file mode 100644 index 0000000000..120ab96151 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump @@ -0,0 +1,12 @@ +>X+0&#ffffff0| @2|X| @2|X| @2|X| @2|X| @42 +|X| |P+0#ffffff16#5f5fff255|o|p|u|p| +0#000087255&|X| @2|X+0#0000000#ffffff0| @2|X| @42 +|X| | +0#000087255#5f5fff255@1|X| @2|X| @2|X+0#0000000#ffffff0| @2|X| @42 +|X| @2|X| @2|X| @2|X| @2|X| @42 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_2.dump b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_2.dump new file mode 100644 index 0000000000..c14b46ac47 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_2.dump @@ -0,0 +1,12 @@ +>X+0&#ffffff0| @2|X| @2|X| @2|X| @2|X| @42 +|X| |P+0#ffffff16#000087255|o|p|u|p| +0#5f5fff255&|X| @2|X+0#0000000#ffffff0| @2|X| @42 +|X| | +0#5f5fff255#000087255@1|X| @2|X| @2|X+0#0000000#ffffff0| @2|X| @42 +|X| @2|X| @2|X| @2|X| @2|X| @42 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_3.dump b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_3.dump new file mode 100644 index 0000000000..bb9e359c81 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_3.dump @@ -0,0 +1,12 @@ +>X+0#000000255#ffd7af255| @2|X| @2|X| @2|X| @2|X| @42 +|X| |P+0f5fd7255|o|p|u|p| +0#000087255&|X| @2|X+0#000000255#ffd7af255| @2|X| @42 +|X| | +0#000087255#5f5fd7255@1|X| @2|X| @2|X+0#000000255#ffd7af255| @2|X| @42 +|X| @2|X| @2|X| @2|X| @2|X| @42 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +| +0#000000255&@41|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_4.dump b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_4.dump new file mode 100644 index 0000000000..c9f7d70df8 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_4.dump @@ -0,0 +1,12 @@ +>X+0#000000255#ffdab9255| @2|X| @2|X| @2|X| @2|X| @42 +|X| |P+0ᨁe3255|o|p|u|p| +0#000099255&|X| @2|X+0#000000255#ffdab9255| @2|X| @42 +|X| | +0#000099255#6657e3255@1|X| @2|X| @2|X+0#000000255#ffdab9255| @2|X| @42 +|X| @2|X| @2|X| @2|X| @2|X| @42 +|~+0#0000ff255&| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +|~| @58 +| +0#000000255&@41|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump b/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump index 89700f9c40..932ebb7249 100644 --- a/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump +++ b/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump @@ -1,7 +1,7 @@ >1+0&#ffffff0| @73 |2| @73 -|3| @7|f+0#ff404010#5fd7ff255|o@1| @1|b+0#0000000&|a|r| +0&#ffffff0@57 -|4| @7|b+0fd7ff255|a|z| @4| +0&#ffffff0@57 +|3| @7|f+0#ff404010#87d7ff255|o@1| +0#5fafd7255&@1|b+0#ffffff16&|a|r| +0#0000000#ffffff0@57 +|4| @7|b+0#ffffff16#87d7ff255|a|z| +0#5fafd7255&@4| +0#0000000#ffffff0@57 |5| @73 |6| @73 |7| @73 diff --git a/src/testdir/dumps/Test_popupwin_opacity_textprop_undercurl.dump b/src/testdir/dumps/Test_popupwin_opacity_textprop_undercurl.dump new file mode 100644 index 0000000000..434f04cd85 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_opacity_textprop_undercurl.dump @@ -0,0 +1,8 @@ +>a+0&#ffffff0@2| |b@2| |c|P+0#e5e9f0255#a9abb1255|O|P|U|P|d+0#04060c255&|C+0#e5e9f0255&|O|N|T|E|N|T|f+0#04060c255&| |g@2| |h@2| @7| +0#0000000#ffffff0@10 +|i@2| |j@2| |k|k+0#04060c255#a9abb1255@1| |l@2| |m@2| |n@2| |o@2| |p@2| @7| +0#0000000#ffffff0@10 +|q@2| |r@2| |s|s+0#04060c255#a9abb1255@1| |m+0#e5e9f0255&|i|d@1|l|e|u+0#04060c255&| |v@2| |w@2| |x@2| @7| +0#0000000#ffffff0@10 +|y@2| |z@2| |1@2| |2@2| |3@2| |4@2| |5@2| |6@2| @18 +|~+0#0000ff255&| @48 +|~| @48 +|~| @48 +| +0#0000000&@31|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump b/src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump index 825706cef4..594b3bfe49 100644 --- a/src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump +++ b/src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump @@ -1,6 +1,6 @@ >r+0&#ffffff0|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 |r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 -|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |o+0#ffffff255#000045255|p|a|c|i|t|y|x+0#8080c5255&|o+0#ffffff255&|v|e|r||+1#8080c5255&|v+0#ffffff255&|s|p|l|i|t|i+0#8080c5255&|n|d|o|w| |t+0#0000000#ffffff0|e|x|t| |h|e|r|e| |x@3| @2 +|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |o+0#ffffff255#7f7fc5255|p|a|c|i|t|y|x+0#000046255&|o+0#ffffff255&|v|e|r||+1#000046255&|v+0#ffffff255&|s|p|l|i|t|i+0#000046255&|n|d|o|w| |t+0#0000000#ffffff0|e|x|t| |h|e|r|e| |x@3| @2 |r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 |r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 |r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 diff --git a/src/testdir/dumps/Test_popupwin_opacity_vsplit_2.dump b/src/testdir/dumps/Test_popupwin_opacity_vsplit_2.dump index 4b766456da..52a4b95d23 100644 --- a/src/testdir/dumps/Test_popupwin_opacity_vsplit_2.dump +++ b/src/testdir/dumps/Test_popupwin_opacity_vsplit_2.dump @@ -1,6 +1,6 @@ |r+0&#ffffff0|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 |r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 -|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |o+0#ffffff255#000045255|p|a|c|i|t|y|x+0#8080c5255&|o+0#ffffff255&|v|e|r||+1#8080c5255&|v+0#ffffff255&|s|p|l|i|t|i+0#8080c5255&|n|d|o|w| |t+0#0000000#ffffff0|e|x|t| |h|e|r|e| |x@3| @2 +|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |o+0#ffffff255#7f7fc5255|p|a|c|i|t|y|x+0#000046255&|o+0#ffffff255&|v|e|r||+1#000046255&|v+0#ffffff255&|s|p|l|i|t|i+0#000046255&|n|d|o|w| |t+0#0000000#ffffff0|e|x|t| |h|e|r|e| |x@3| @2 |r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 |r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 >r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @2 diff --git a/src/testdir/dumps/Test_popupwin_opacity_wide_1.dump b/src/testdir/dumps/Test_popupwin_opacity_wide_1.dump index be464f7721..3a1112ed43 100644 --- a/src/testdir/dumps/Test_popupwin_opacity_wide_1.dump +++ b/src/testdir/dumps/Test_popupwin_opacity_wide_1.dump @@ -1,13 +1,13 @@ ->い*0&#ffffff0|え|ãƒŧ@15|い|!+&| |1| @3 -|い*&|え|ãƒŧ@15|い|!+&| |2| @3 -|い*&|え|ãƒŧ@15|い|!+&| |3| @3 -|い*&|え*0#ffffff16#e000002|ãƒŧ@6| +&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |4| @3 -|い*&| +0#ffffff16#e000002|ã‚Ģ*&|ナ|フ|ãƒĢ|ãĒ| +&|ãƒŧ*&@1| +&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |5| @3 -|い*&| +0#ffffff16#e000002|ポ*&|ッ|プ|ã‚ĸ|ッ|プ|で|─+&|╮| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |6| @3 -|い*&| +0#ffffff16#e000002|最*&|上|åˇ| +&|ãŧ*&|čĩ¤|い|ãĒ|│+&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |7| @3 -|い*&| +0#ffffff16#e000002|│|あ*&|い|う|え|お|ãƒŧ@1|│+&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |8| @3 -|い*&| +&|│+0#ffffff16#0000e05|ãƒŧ*&@6|│+&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |9| @3 -|い*&| +&|╰+0#ffffff16#0000e05|─@13|╯| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |1|0| @2 +>い*0&#ffffff0|え*0#600000255#df7f7f255|ãƒŧ@6| +&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |1| @3 +|い*&| +0#600000255#df7f7f255|ã‚Ģ*0#ffffff255&|ナ|フ|ãƒĢ|ãĒ| +0#600000255&|ãƒŧ*&@1| +&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |2| @3 +|い*&| +0#600000255#df7f7f255|ポ*0#ffffff255#a03f6f255|ッ|プ|ã‚ĸ|ッ|プ|で|─+0#df7f7f255&|╮| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |3| @3 +|い*&| +0#600000255#df7f7f255|最*0#ffffff255#a03f6f255|上|åˇ| +0#df7f7f255&|ãŧ*&|čĩ¤|い|ãĒ|│+&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |4| @3 +|い*&| +0#600000255#df7f7f255|│+0#df7f7f255#a03f6f255|あ*&|い|う|え|お|ãƒŧ*0#600030255&@1|│+0#df7f7f255&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |5| @3 +|い*&| +&|│+0#ffffff255#7f7fdf255|ãƒŧ*0#000060255&@6|│+0#ffffff255&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |6| @3 +|い*&| +&|╰+0#ffffff255#7f7fdf255|─@13|╯| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |7| @3 +|い*&|え|ãƒŧ@15|い|!+&| |8| @3 +|い*&|え|ãƒŧ@15|い|!+&| |9| @3 +|い*&|え|ãƒŧ@15|い|!+&| |1|0| @2 |い*&|え|ãƒŧ@15|い|!+&| |1@1| @2 |い*&|え|ãƒŧ@15|い|!+&| |1|2| @2 |い*&|え|ãƒŧ@15|い|!+&| |1|3| @2 diff --git a/src/testdir/dumps/Test_popupwin_opacity_wide_2.dump b/src/testdir/dumps/Test_popupwin_opacity_wide_2.dump index 50ca50354a..4910201869 100644 --- a/src/testdir/dumps/Test_popupwin_opacity_wide_2.dump +++ b/src/testdir/dumps/Test_popupwin_opacity_wide_2.dump @@ -1,15 +1,15 @@ >い*0&#ffffff0|え|ãƒŧ@15|い|!+&| |1| @3 |い*&|え|ãƒŧ@15|い|!+&| |2| @3 -|い*&|え|ãƒŧ@15|い|!+&| |3| @3 -|い*&|え|ãƒŧ@15|い|!+&| |4| @3 -|い*&|え|ãƒŧ@15|い|!+&| |5| @3 -|い*&| +&|╭+0#ffffff16#0000e05|─@13|╮| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |6| @3 -|い*&| +&|│+0#ffffff16#0000e05|あ*&|め|ん|ãŧ|čĩ¤|い|ãĒ|│+&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |7| @3 -|い*&| +&|│+0#ffffff16#0000e05|あ*&|い|う|え|お| +&| +0&#e000002|ãƒŧ*&|│+&| |ãƒŧ*&@5|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |8| @3 -|い*&| +&|│+0#ffffff16#0000e05|ãƒŧ*&@4| +&| +0&#e000002|ã‚Ģ*&|ナ|フ|ãƒĢ|ãĒ|ãƒŧ@2|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |9| @3 -|い*&| +&|╰+0#ffffff16#0000e05|─@10|─+0&#e000002|ポ*&|ッ|プ|ã‚ĸ|ッ|プ|で|ãƒŧ|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |1|0| @2 -|い*&|え|ãƒŧ@4| +&| +0#ffffff16#e000002|最*&|上|åˇ|ãƒŧ@4|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |1@1| @2 -|い*&|え|ãƒŧ@4| +&| +0#ffffff16#e000002|ãƒŧ*&@7|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |1|2| @2 +|い*&| +&|╭+0#ffffff255#7f7fdf255|─@13|╮| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |3| @3 +|い*&| +&|│+0#ffffff255#7f7fdf255|あ*&|め|ん|ãŧ|čĩ¤|い|ãĒ|│+&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |4| @3 +|い*&| +&|│+0#ffffff255#7f7fdf255|あ*&|い|う|え|お|ãƒŧ*0#000060255&@1|│+0#ffffff255&| +0#0000000#ffffff0|ãƒŧ*&@7|い|!+&| |5| @3 +|い*&| +&|│+0#ffffff255#7f7fdf255|ãƒŧ*0#000060255&@4| +&| +0#600030255#a03f6f255|ãƒŧ*&|│+0#df7f7f255&| +0#600000255#df7f7f255|ãƒŧ*&@5|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |6| @3 +|い*&| +&|╰+0#ffffff255#7f7fdf255|─@10|─+0#df7f7f255#a03f6f255|ã‚Ģ*0#ffffff255&|ナ*0&#df7f7f255|フ|ãƒĢ|ãĒ|ãƒŧ*0#600000255&@2|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |7| @3 +|い*&|え|ãƒŧ@4| +&| +0#600000255#df7f7f255|ポ*0#ffffff255&|ッ|プ|ã‚ĸ|ッ|プ|で|ãƒŧ*0#600000255&|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |8| @3 +|い*&|え|ãƒŧ@4| +&| +0#600000255#df7f7f255|最*0#ffffff255&|上|åˇ|ãƒŧ*0#600000255&@4|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |9| @3 +|い*&|え|ãƒŧ@4| +&| +0#600000255#df7f7f255|ãƒŧ*&@7|ãƒŧ*0#0000000#ffffff0@1|い|!+&| |1|0| @2 +|い*&|え|ãƒŧ@15|い|!+&| |1@1| @2 +|い*&|え|ãƒŧ@15|い|!+&| |1|2| @2 |い*&|え|ãƒŧ@15|い|!+&| |1|3| @2 |い*&|え|ãƒŧ@15|い|!+&| |1|4| @2 |:| @25|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump b/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump index 17aa447f86..8028c98c23 100644 --- a/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump +++ b/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump @@ -1,7 +1,7 @@ >b+0&#ffffff0|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 -|b|a|c|k|b|l|u|e|n|p|o|p|u|p|t| |h|e|r|e| @54 -|b|a|c|k|g|r|o|r|e|d| |p|o|p|u|p|h|e|r|e| @54 +|b|a|c|k|b+0#ffffff16#8787d7255|l|u|e|n+0#00005f255&|p+0#ffffff16&|o|p|u|p|t+0#0000000#ffffff0| |h|e|r|e| @54 +|b|a|c|k|g|r|o|r+0#ffffff16#ffffff255|e|d| +0#0000000#ffffff0|p+0#ffffff16#ffffff255|o|p|u|p|h+0#0000000#ffffff0|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 diff --git a/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump b/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump index 03b9f4a59f..d09818da58 100644 --- a/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump +++ b/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump @@ -1,7 +1,7 @@ >b+0&#ffffff0|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 -|b|a|c|k|b|l|u|e|n|p|o|p|u|p|t| |h|e|r|e| @54 -|b|a|c|k|g|r|o|r|e|d| |p|o|p|u|p|h|e|r|e| @54 +|b|a|c|k|b+0#ffffff16#8787d7255|l|u|e|n+0#00005f255&|p+0#ffffff16&|o|p|u|p|t+0#0000000#ffffff0| |h|e|r|e| @54 +|b|a|c|k|g|r|o|r+0#ffffff16#ffffff255|e|d| +0#0000000#ffffff0|p+0#ffffff16#ffffff255|o|p|u|p|h+0#0000000#ffffff0|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 |b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_10.dump b/src/testdir/dumps/Test_popupwin_previewpopup_10.dump index fdf16b4906..7003b43fd9 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_10.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_10.dump @@ -2,12 +2,12 @@ |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54 |t|h|r|e@1| @69 |f|o|u|r| @70 -|f|i|v|e| @27|╔+0#0000001#ffd7ff255| |X|h|e|a|d|e|r|.|h| |═@29|X -|s+0#0000000#ffffff0|i|x| @28|║+0#0000001#ffd7ff255|1+0#e000002&|0| +0#0000001&@37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|s+0#0000000#ffffff0|e|v|e|n| @26|║+0#0000001#ffd7ff255|s|e|a|r|c|h|e|d| |w|o|r|d| |i|s| |h|e|r|e| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0#0000001#ffd7ff255|1+0#e000002&|2| +0#0000001&@37| +0#0000000#0000001|║+0#0000001#ffd7ff255 -|n+0#0000000#ffffff0|i|n|e| @27|║+0#0000001#ffd7ff255|1+0#e000002&|3| +0#0000001&@37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0#0000001#ffd7ff255|═@40|⇲ +|f|i|v|e| @28|╔+0#0000001#ffd7ff255| |X|h|e|a|d|e|r|.|h| |═@28|X +|s+0#0000000#ffffff0|i|x| @29|║+0#0000001#ffd7ff255|1+0#e000002&|0| +0#0000001&@36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|s+0#0000000#ffffff0|e|v|e|n| @27|║+0#0000001#ffd7ff255|s|e|a|r|c|h|e|d| |w|o|r|d| |i|s| |h|e|r|e| @17| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @10|║+0#0000001#ffd7ff255|1+0#e000002&|2| +0#0000001&@36| +0#0000000#0000001|║+0#0000001#ffd7ff255 +|n+0#0000000#ffffff0|i|n|e| @28|║+0#0000001#ffd7ff255|1+0#e000002&|3| +0#0000001&@36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @12|╚+0#0000001#ffd7ff255|═@39|⇲ |v+0#0000000#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_4.dump b/src/testdir/dumps/Test_popupwin_previewpopup_4.dump index f8d411dadb..d6a90df432 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_4.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_4.dump @@ -2,12 +2,12 @@ |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54 |t|h|r|e@1| @69 |f|o|u|r| @70 -|f|i|v|e| @27|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X -|s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255 -|s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255 -|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0|║+0&#afffff255 -|n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255 -|t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲ +|f|i|v|e| @28|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@29|X +|s+0&#ffffff0|i|x| @29|║+0&#afffff255|2|6| @36| +0&#a8a8a8255|║+0&#afffff255 +|s+0&#ffffff0|e|v|e|n| @27|║+0&#afffff255|2|7| @36| +0&#a8a8a8255|║+0&#afffff255 +|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @10|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @17| +0|║+0&#afffff255 +|n+0&#ffffff0|i|n|e| @28|║+0&#afffff255|2|9| @36| +0&#a8a8a8255|║+0&#afffff255 +|t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @12|╚+0&#afffff255|═@39|⇲ |v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_5.dump b/src/testdir/dumps/Test_popupwin_previewpopup_5.dump index 8f1b98f489..b0815fde77 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_5.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_5.dump @@ -2,12 +2,12 @@ |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54 |t|h|r|e@1| @69 |f|o|u|r| @70 -|f|i|v|e| @27|╔+0&#afffff255| |t|e|s|t|d|i|r|/|X|t|a|g|f|i|l|e| |═@22|X -|s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255 -|s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255 -|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0|║+0&#afffff255 -|n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255 -|t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲ +|f|i|v|e| @28|╔+0&#afffff255| |t|e|s|t|d|i|r|/|X|t|a|g|f|i|l|e| |═@21|X +|s+0&#ffffff0|i|x| @29|║+0&#afffff255|2|6| @36| +0&#a8a8a8255|║+0&#afffff255 +|s+0&#ffffff0|e|v|e|n| @27|║+0&#afffff255|2|7| @36| +0&#a8a8a8255|║+0&#afffff255 +|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @10|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @17| +0|║+0&#afffff255 +|n+0&#ffffff0|i|n|e| @28|║+0&#afffff255|2|9| @36| +0&#a8a8a8255|║+0&#afffff255 +|t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @12|╚+0&#afffff255|═@39|⇲ |v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_7.dump b/src/testdir/dumps/Test_popupwin_previewpopup_7.dump index f510b8b778..add98bfcfe 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_7.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_7.dump @@ -2,12 +2,12 @@ |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54 |t|h|r|e@1| @69 |f|o|u|r| @70 -|f|i|v|e| @27|╔+0#0000001#ffd7ff255| |X|t|a|g|f|i|l|e| |═@30|X -|s+0#0000000#ffffff0|i|x| @28|║+0#0000001#ffd7ff255|2|0| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|s+0#0000000#ffffff0|e|v|e|n| @26|║+0#0000001#ffd7ff255|t|h|e|w|o|r|d| |i|s| |h|e|r|e| @24| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0#0000001#ffd7ff255|2@1| @37| +0#0000000#0000001|║+0#0000001#ffd7ff255 -|n+0#0000000#ffffff0|i|n|e| @27|║+0#0000001#ffd7ff255|2|3| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0#0000001#ffd7ff255|═@40|⇲ +|f|i|v|e| @28|╔+0#0000001#ffd7ff255| |X|t|a|g|f|i|l|e| |═@29|X +|s+0#0000000#ffffff0|i|x| @29|║+0#0000001#ffd7ff255|2|0| @36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|s+0#0000000#ffffff0|e|v|e|n| @27|║+0#0000001#ffd7ff255|t|h|e|w|o|r|d| |i|s| |h|e|r|e| @23| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @10|║+0#0000001#ffd7ff255|2@1| @36| +0#0000000#0000001|║+0#0000001#ffd7ff255 +|n+0#0000000#ffffff0|i|n|e| @28|║+0#0000001#ffd7ff255|2|3| @36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @12|╚+0#0000001#ffd7ff255|═@39|⇲ |v+0#0000000#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_8.dump b/src/testdir/dumps/Test_popupwin_previewpopup_8.dump index 6e88fffcae..c5e75e19b9 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_8.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_8.dump @@ -2,12 +2,12 @@ |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54 |t|h|r|e@1| @69 |f|o|u|r| @70 -|f|i|v|e| @27|╔+0#0000001#ffd7ff255| |X|h|e|a|d|e|r|.|h| |═@29|X -|s+0#0000000#ffffff0|i|x| @28|║+0#0000001#ffd7ff255|1+0#e000002&|0| +0#0000001&@37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|s+0#0000000#ffffff0|e|v|e|n| @26|║+0#0000001#ffd7ff255|s|e|a|r|c|h|e|d| |w|o|r|d| |i|s| |h|e|r|e| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0#0000001#ffd7ff255|1+0#e000002&|2| +0#0000001&@37| +0#0000000#0000001|║+0#0000001#ffd7ff255 -|n+0#0000000#ffffff0|i|n|e| @27|║+0#0000001#ffd7ff255|1+0#e000002&|3| +0#0000001&@37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0#0000001#ffd7ff255|═@40|⇲ +|f|i|v|e| @28|╔+0#0000001#ffd7ff255| |X|h|e|a|d|e|r|.|h| |═@28|X +|s+0#0000000#ffffff0|i|x| @29|║+0#0000001#ffd7ff255|1+0#e000002&|0| +0#0000001&@36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|s+0#0000000#ffffff0|e|v|e|n| @27|║+0#0000001#ffd7ff255|s|e|a|r|c|h|e|d| |w|o|r|d| |i|s| |h|e|r|e| @17| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @10|║+0#0000001#ffd7ff255|1+0#e000002&|2| +0#0000001&@36| +0#0000000#0000001|║+0#0000001#ffd7ff255 +|n+0#0000000#ffffff0|i|n|e| @28|║+0#0000001#ffd7ff255|1+0#e000002&|3| +0#0000001&@36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @12|╚+0#0000001#ffd7ff255|═@39|⇲ |v+0#0000000#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_9.dump b/src/testdir/dumps/Test_popupwin_previewpopup_9.dump index 09f8a45a14..f555a00dcd 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_9.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_9.dump @@ -2,12 +2,12 @@ |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54 |t|h|r|e@1| @69 |f|o|u|r| @70 -|f|i|v|e| @27|╔+0#0000001#ffd7ff255| |X|h|e|a|d|e|r|.|h| |═@29|X -|s+0#0000000#ffffff0|i|x| @28|║+0#0000001#ffd7ff255|1+0#e000002&|0| +0#0000001&@37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|s+0#0000000#ffffff0|e|v|e|n| @26|║+0#0000001#ffd7ff255|s|e|a|r|c|h|e|d| |w|o|r|d| |i|s| |h|e|r|e| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0#0000001#ffd7ff255|1+0#e000002&|2| +0#0000001&@37| +0#0000000#0000001|║+0#0000001#ffd7ff255 -|n+0#0000000#ffffff0|i|n|e| @27|║+0#0000001#ffd7ff255|1+0#e000002&|3| +0#0000001&@37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0#0000001#ffd7ff255|═@40|⇲ +|f|i|v|e| @28|╔+0#0000001#ffd7ff255| |X|h|e|a|d|e|r|.|h| |═@28|X +|s+0#0000000#ffffff0|i|x| @29|║+0#0000001#ffd7ff255|1+0#e000002&|0| +0#0000001&@36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|s+0#0000000#ffffff0|e|v|e|n| @27|║+0#0000001#ffd7ff255|s|e|a|r|c|h|e|d| |w|o|r|d| |i|s| |h|e|r|e| @17| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @10|║+0#0000001#ffd7ff255|1+0#e000002&|2| +0#0000001&@36| +0#0000000#0000001|║+0#0000001#ffd7ff255 +|n+0#0000000#ffffff0|i|n|e| @28|║+0#0000001#ffd7ff255|1+0#e000002&|3| +0#0000001&@36| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 +|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @12|╚+0#0000001#ffd7ff255|═@39|⇲ |v+0#0000000#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/dumps/Test_popupwin_wrap_1.dump b/src/testdir/dumps/Test_popupwin_wrap_1.dump index 5643dc75c6..0a04f26849 100644 --- a/src/testdir/dumps/Test_popupwin_wrap_1.dump +++ b/src/testdir/dumps/Test_popupwin_wrap_1.dump @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 |2| @73 -|╔+0#0000001#ffd7ff255|═@73 -|║| |o+0&#e0e0e08|n|e| @67| +0&#ffd7ff255| +0#0000000#0000001 -|║+0#0000001#ffd7ff255| |a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d| | +0#0000000#0000001 -|║+0#0000001#ffd7ff255| |f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s| @52| +0#0000000#a8a8a8255 -|╚+0#0000001#ffd7ff255|═@73 -|8+0#0000000#ffffff0| @73 +|╔+0#0000001#ffd7ff255|═@71|╗| +0#0000000#ffffff0 +|║+0#0000001#ffd7ff255| |o+0&#e0e0e08|n|e| @65| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0 +|║+0#0000001#ffd7ff255| |a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a| | +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0 +|║+0#0000001#ffd7ff255| |s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s| @48| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0 +|╚+0#0000001#ffd7ff255|═@71|╝| +0#0000000#ffffff0 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_wrap_2.dump b/src/testdir/dumps/Test_popupwin_wrap_2.dump index 3a02fc5c95..e9b35f648e 100644 --- a/src/testdir/dumps/Test_popupwin_wrap_2.dump +++ b/src/testdir/dumps/Test_popupwin_wrap_2.dump @@ -1,10 +1,10 @@ >1+0&#ffffff0| @73 |2| @73 -|╔+0#0000001#ffd7ff255|═@73 -|║| |a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d| | +0#0000000#a8a8a8255 -|║+0#0000001#ffd7ff255| |f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s| @52| +0#0000000#0000001 -|║+0#0000001#ffd7ff255| |t+0&#e0e0e08|h|r|e@1| @65| +0&#ffd7ff255| +0#0000000#0000001 -|╚+0#0000001#ffd7ff255|═@73 -|8+0#0000000#ffffff0| @73 +|╔+0#0000001#ffd7ff255|═@71|╗| +0#0000000#ffffff0 +|║+0#0000001#ffd7ff255| |a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a| | +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0 +|║+0#0000001#ffd7ff255| |s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s|d|f|a|s| @48| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0 +|║+0#0000001#ffd7ff255| |t+0&#e0e0e08|h|r|e@1| @63| +0&#ffd7ff255| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0 +|╚+0#0000001#ffd7ff255|═@71|╝| +0#0000000#ffffff0 +|8| @73 |9| @73 @57|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_prop_diff_mode_2.dump b/src/testdir/dumps/Test_prop_diff_mode_2.dump index 243ec0dc18..453665d998 100644 --- a/src/testdir/dumps/Test_prop_diff_mode_2.dump +++ b/src/testdir/dumps/Test_prop_diff_mode_2.dump @@ -6,5 +6,5 @@ |~+0#4040ff13#ffffff0| @28||+1#0000000&| +0#af5f00255&@1|5| |0+0#0000000#ffd7ff255@2|9+2&#ff404010| +0&#ffd7ff255@20 |~+0#4040ff13#ffffff0| @28||+1#0000000&| +0#af5f00255&@3|<+0#0000000#ffd7ff255|t|e|x|t|>| @18 |~+0#4040ff13#ffffff0| @28||+1#0000000&|~+0#4040ff13&| @27 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1|-|7| @5|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1|-|7| @5|A|l@1 |:+0&&|w|i|n|d|o| |s|e|t| |n|u|m|b|e|r| @42 diff --git a/src/testdir/dumps/Test_prop_with_text_after_wide_char_1.dump b/src/testdir/dumps/Test_prop_with_text_after_wide_char_1.dump new file mode 100644 index 0000000000..36dfed3ff2 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_after_wide_char_1.dump @@ -0,0 +1,8 @@ +>x+0&#ffffff0@42|åŖ*& +|s+&|e|c|o|n|d| |l|i|n|e| @33 +|t|h|i|r|d| |l|i|n|e| @34 +|~+0#4040ff13&| @43 +|~| @43 +|~| @43 +|~| @43 +| +0#0000000&@26|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_prop_with_text_after_wide_char_2.dump b/src/testdir/dumps/Test_prop_with_text_after_wide_char_2.dump new file mode 100644 index 0000000000..50136517f4 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_after_wide_char_2.dump @@ -0,0 +1,8 @@ +>x+0&#ffffff0@38|>+0#4040ff13& +|b+0#0000000&|e|t|w|e@1|n| |l|i|n|e| @27 +|x@31| @7 +|l|a|s|t| |l|i|n|e| @30 +|~+0#4040ff13&| @38 +|~| @38 +|~| @38 +| +0#0000000&@21|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_pumopt_opacity_50.dump b/src/testdir/dumps/Test_pumopt_opacity_50.dump index d9e44da0f7..32e366ab32 100644 --- a/src/testdir/dumps/Test_pumopt_opacity_50.dump +++ b/src/testdir/dumps/Test_pumopt_opacity_50.dump @@ -13,8 +13,8 @@ |B|A|C|K|G|R|O|U|N|D|B|A|C|K|G|R|O|U|N|D|B|A|C|K|G|R|O|U|N|D|B|A|C|K|G|R|O|U|N|D|B|A|C|K|G|R|O|U|N|D|B|A|C|K|G|R|O|U|N|D|B|A|C|K|G|R|O|U|N|D|B|A|C|K|G |R|O|U|N|D| @69 |h|e|l@1|o> @69 -|h+0#0000001#e0e0e08|e|l@1|o| @9| +0#4040ff13#ffffff0@59 -|h+0#0000001#ffd7ff255|e|l|p| @10| +0#4040ff13#ffffff0@59 +|h+0#0000001#dadada255|e|l@1|o| +0#5f5fd7255&@9| +0#4040ff13#ffffff0@59 +|h+0#0000001#ffd7ff255|e|l|p| +0#875fff255&@10| +0#4040ff13#ffffff0@59 |~| @73 |~| @73 |-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |2| +0#0000000&@33 diff --git a/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump b/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump new file mode 100644 index 0000000000..1ae8db5a1c --- /dev/null +++ b/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump @@ -0,0 +1,20 @@ +|ãģ*0&#ffffff0|げ> +&@70 +|ãģ*0#0000001#ffd787255|げ|ãģ*0#875f00255&|げ|ãģ|げ|æŧĸ*4#ff875f255&| +&| +4#e000e06#ffffff0|テ*&|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãĩ*0#ffffff16#87afaf255|が|æŧĸ|字|ãģ*0#00005f255&|げ|æŧĸ*4#875faf255&| +&| +4#e000e06#ffffff0|テ*&|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ã‚Ģ*0#ffffff16#87afaf255|ã‚ŋ|ã‚Ģ|ナ|候|誜|æŧĸ*4#875faf255&| +&| +4#e000e06#ffffff0|テ*&|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ*4#e000e06&|字|テ|゚|ト|あ*0#0000000&|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_pumopt_opacity_textprop_undercurl.dump b/src/testdir/dumps/Test_pumopt_opacity_textprop_undercurl.dump new file mode 100644 index 0000000000..a1242fde84 --- /dev/null +++ b/src/testdir/dumps/Test_pumopt_opacity_textprop_undercurl.dump @@ -0,0 +1,20 @@ +|p+0&#ffffff0|o|p|u|p|-|i|t|e|m|-|1> @62 +|p+0#000000255#dedede255|o|p|u|p|-|i|t|e|m|-|1|d+0#5f5f5f255&@2| +0#0000000#ffffff0|e@2| |f@2| |g@2| |h@2| @43 +|p+0#000000255#ffc5ff255|o|p|u|p|-|i|t|e|m|-|2|d+0#804680255&@2| +0#0000000#ffffff0|e@2| |f@2| |g@2| |h@2| @43 +|p+0#000000255#ffc5ff255|o|p|u|p|-|i|t|e|m|-|3|d+0#804680255&@2| +0#0000000#ffffff0|e@2| |f@2| |g@2| |h@2| @43 +|a@2| |b@2| |c@2| |d@2| |e@2| |f@2| |g@2| |h@2| @43 +|a@2| |b@2| |c@2| |d@2| |e@2| |f@2| |g@2| |h@2| @43 +|a@2| |b@2| |c@2| |d@2| |e@2| |f@2| |g@2| |h@2| @43 +|a@2| |b@2| |c@2| |d@2| |e@2| |f@2| |g@2| |h@2| @43 +|a@2| |b@2| |c@2| |d@2| |e@2| |f@2| |g@2| |h@2| @43 +|~+0#0000ff255&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_pumopt_opacity_wide_bg.dump b/src/testdir/dumps/Test_pumopt_opacity_wide_bg.dump new file mode 100644 index 0000000000..6b9bb9935a --- /dev/null +++ b/src/testdir/dumps/Test_pumopt_opacity_wide_bg.dump @@ -0,0 +1,20 @@ +|ãģ*0&#ffffff0|げ> +&@70 +|╭+0#0000001#ffd7ff255|─@15|╮|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|│+0#0000001#ffd7ff255| +0&#dadada255|ãģ*&|げ|げ*0#5f5f5f255&|ãģ|げ|æŧĸ|字| +&|│+0#0000001#ffd7ff255|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|│+0#0000001#ffd7ff255| |ãĩ*&|が|æŧĸ|字|げ*0#875f87255&|æŧĸ|字| +&|│+0#0000001&|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|│+0#0000001#ffd7ff255| |ã‚Ģ*&|ã‚ŋ|ã‚Ģ|ナ|候|誜|字*0#875f87255&| +&|│+0#0000001&|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|╰+0#0000001#ffd7ff255|─@15|╯|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_pumopt_opacity_wide_bg_shifted.dump b/src/testdir/dumps/Test_pumopt_opacity_wide_bg_shifted.dump new file mode 100644 index 0000000000..f67556307b --- /dev/null +++ b/src/testdir/dumps/Test_pumopt_opacity_wide_bg_shifted.dump @@ -0,0 +1,20 @@ +|ãģ*0&#ffffff0|げ> +&@70 +|╭+0#0000001#ffd7ff255|─@15|╮|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|│+0#0000001#ffd7ff255| +0&#dadada255|ãģ*&|げ| +0#5f5f5f255&|げ*&|ãģ|げ|æŧĸ|字|│+0#0000001#ffd7ff255| +0#0000000#ffffff0|゚*&|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|│+0#0000001#ffd7ff255| |ãĩ*&|が|æŧĸ|字|げ*0#875f87255&|æŧĸ|字| +&|│+0#0000001&|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|│+0#0000001#ffd7ff255| |ã‚Ģ*&|ã‚ŋ|ã‚Ģ|ナ|候|誜| +0#875f87255&|字*&|│+0#0000001&| +0#0000000#ffffff0|゚*&|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|╰+0#0000001#ffd7ff255|─@15|╯|゚*0#0000000#ffffff0|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|a|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|a|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|a|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|a|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|a|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|a|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@34 +|a|ãģ*&|げ|ãģ|げ|ãģ|げ|æŧĸ|字|テ|゚|ト|あ|い|う|え|お|ã‚Ģ|ã‚ŋ|ã‚Ģ|ナ| +&@33 +|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_scrolloffpad_basic_1.dump b/src/testdir/dumps/Test_scrolloffpad_basic_1.dump new file mode 100644 index 0000000000..af38b016a3 --- /dev/null +++ b/src/testdir/dumps/Test_scrolloffpad_basic_1.dump @@ -0,0 +1,20 @@ +|l+0&#ffffff0|i|n|e| |9|1| @70 +|l|i|n|e| |9|2| @70 +|l|i|n|e| |9|3| @70 +|l|i|n|e| |9|4| @70 +|l|i|n|e| |9|5| @70 +|l|i|n|e| |9|6| @70 +|l|i|n|e| |9|7| @70 +|l|i|n|e| |9|8| @70 +|l|i|n|e| |9@1| @70 +>l|i|n|e| |1|0@1| @69 +|~+0#4040ff13&| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +| +0#0000000&@59|1|0@1|,|1| @8|B|o|t| diff --git a/src/testdir/dumps/Test_scrolloffpad_basic_2.dump b/src/testdir/dumps/Test_scrolloffpad_basic_2.dump new file mode 100644 index 0000000000..0702019465 --- /dev/null +++ b/src/testdir/dumps/Test_scrolloffpad_basic_2.dump @@ -0,0 +1,20 @@ +>l+0&#ffffff0|i|n|e| |1| @71 +|l|i|n|e| |2| @71 +|l|i|n|e| |3| @71 +|l|i|n|e| |4| @71 +|l|i|n|e| |5| @71 +|l|i|n|e| |6| @71 +|l|i|n|e| |7| @71 +|l|i|n|e| |8| @71 +|l|i|n|e| |9| @71 +|l|i|n|e| |1|0| @70 +|l|i|n|e| |1@1| @70 +|l|i|n|e| |1|2| @70 +|l|i|n|e| |1|3| @70 +|l|i|n|e| |1|4| @70 +|l|i|n|e| |1|5| @70 +|l|i|n|e| |1|6| @70 +|l|i|n|e| |1|7| @70 +|l|i|n|e| |1|8| @70 +|l|i|n|e| |1|9| @70 +@60|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_scrolloffpad_basic_3.dump b/src/testdir/dumps/Test_scrolloffpad_basic_3.dump new file mode 100644 index 0000000000..72eed1e33f --- /dev/null +++ b/src/testdir/dumps/Test_scrolloffpad_basic_3.dump @@ -0,0 +1,20 @@ +|l+0&#ffffff0|i|n|e| |8|2| @70 +|l|i|n|e| |8|3| @70 +|l|i|n|e| |8|4| @70 +|l|i|n|e| |8|5| @70 +|l|i|n|e| |8|6| @70 +|l|i|n|e| |8|7| @70 +|l|i|n|e| |8@1| @70 +|l|i|n|e| |8|9| @70 +|l|i|n|e| |9|0| @70 +|l|i|n|e| |9|1| @70 +|l|i|n|e| |9|2| @70 +|l|i|n|e| |9|3| @70 +|l|i|n|e| |9|4| @70 +|l|i|n|e| |9|5| @70 +|l|i|n|e| |9|6| @70 +|l|i|n|e| |9|7| @70 +|l|i|n|e| |9|8| @70 +|l|i|n|e| |9@1| @70 +>l|i|n|e| |1|0@1| @69 +@60|1|0@1|,|1| @8|B|o|t| diff --git a/src/testdir/dumps/Test_scrolloffpad_smoothscroll_1.dump b/src/testdir/dumps/Test_scrolloffpad_smoothscroll_1.dump new file mode 100644 index 0000000000..af38b016a3 --- /dev/null +++ b/src/testdir/dumps/Test_scrolloffpad_smoothscroll_1.dump @@ -0,0 +1,20 @@ +|l+0&#ffffff0|i|n|e| |9|1| @70 +|l|i|n|e| |9|2| @70 +|l|i|n|e| |9|3| @70 +|l|i|n|e| |9|4| @70 +|l|i|n|e| |9|5| @70 +|l|i|n|e| |9|6| @70 +|l|i|n|e| |9|7| @70 +|l|i|n|e| |9|8| @70 +|l|i|n|e| |9@1| @70 +>l|i|n|e| |1|0@1| @69 +|~+0#4040ff13&| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +| +0#0000000&@59|1|0@1|,|1| @8|B|o|t| diff --git a/src/testdir/dumps/Test_scrolloffpad_smoothscroll_2.dump b/src/testdir/dumps/Test_scrolloffpad_smoothscroll_2.dump new file mode 100644 index 0000000000..3b66ce6218 --- /dev/null +++ b/src/testdir/dumps/Test_scrolloffpad_smoothscroll_2.dump @@ -0,0 +1,20 @@ +|l+0&#ffffff0|i|n|e| |9|2| @70 +|l|i|n|e| |9|3| @70 +|l|i|n|e| |9|4| @70 +|l|i|n|e| |9|5| @70 +|l|i|n|e| |9|6| @70 +|l|i|n|e| |9|7| @70 +|l|i|n|e| |9|8| @70 +|l|i|n|e| |9@1| @70 +|L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| >L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N +|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| |L|O|N|G| @6 +|~+0#4040ff13&| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +|~| @76 +| +0#0000000&@59|1|0@1|,|4|1| @7|B|o|t| diff --git a/src/testdir/dumps/Test_smooth_diff_change_line_1.dump b/src/testdir/dumps/Test_smooth_diff_change_line_1.dump index c634f1dd31..28f2e1d995 100644 --- a/src/testdir/dumps/Test_smooth_diff_change_line_1.dump +++ b/src/testdir/dumps/Test_smooth_diff_change_line_1.dump @@ -16,5 +16,5 @@ |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_smooth_diff_change_line_2.dump b/src/testdir/dumps/Test_smooth_diff_change_line_2.dump index 691fe289fd..4c2d28d0e6 100644 --- a/src/testdir/dumps/Test_smooth_diff_change_line_2.dump +++ b/src/testdir/dumps/Test_smooth_diff_change_line_2.dump @@ -16,5 +16,5 @@ |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|4| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|7| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|4| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|7| @11|A|l@1 |-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@62 diff --git a/src/testdir/dumps/Test_smooth_diff_change_line_3.dump b/src/testdir/dumps/Test_smooth_diff_change_line_3.dump index c4178404d8..e47fb5d34b 100644 --- a/src/testdir/dumps/Test_smooth_diff_change_line_3.dump +++ b/src/testdir/dumps/Test_smooth_diff_change_line_3.dump @@ -16,5 +16,5 @@ |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|4| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|6| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|4| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|6| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_smooth_diff_change_line_3a.dump b/src/testdir/dumps/Test_smooth_diff_change_line_3a.dump index d13141eb28..0c7e70c273 100644 --- a/src/testdir/dumps/Test_smooth_diff_change_line_3a.dump +++ b/src/testdir/dumps/Test_smooth_diff_change_line_3a.dump @@ -16,5 +16,5 @@ |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|4| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|6| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|4| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|6| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_smooth_diff_change_line_4.dump b/src/testdir/dumps/Test_smooth_diff_change_line_4.dump index b789df3fb7..37ce70a758 100644 --- a/src/testdir/dumps/Test_smooth_diff_change_line_4.dump +++ b/src/testdir/dumps/Test_smooth_diff_change_line_4.dump @@ -16,5 +16,5 @@ |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|1| @11|A|l@1 | +0&&@74 diff --git a/src/testdir/dumps/Test_smooth_incsearch_1.dump b/src/testdir/dumps/Test_smooth_incsearch_1.dump deleted file mode 100644 index 830b855d1d..0000000000 --- a/src/testdir/dumps/Test_smooth_incsearch_1.dump +++ /dev/null @@ -1,8 +0,0 @@ -|<+0#4040ff13#ffffff0@2| +0#af5f00255&|a+0#0000000&@27| @7 -| +0#af5f00255&|1|2| | +0#0000000&@35 -| +0#af5f00255&|1|3| | +0#0000000&@35 -| +0#af5f00255&|1|4| |b+1#0000000&|b+0&&@2| @31 -| +0#af5f00255&|1|5| | +0#0000000&@35 -| +0#af5f00255&|1|6| | +0#0000000&@35 -| +0#af5f00255&|1|7| | +0#0000000&@35 -|/|b> @37 diff --git a/src/testdir/dumps/Test_smooth_incsearch_2.dump b/src/testdir/dumps/Test_smooth_incsearch_2.dump deleted file mode 100644 index 349e12861b..0000000000 --- a/src/testdir/dumps/Test_smooth_incsearch_2.dump +++ /dev/null @@ -1,8 +0,0 @@ -|<+0#4040ff13#ffffff0@2| +0#af5f00255&|a+0#0000000&@27| @7 -| +0#af5f00255&|1|2| | +0#0000000&@35 -| +0#af5f00255&|1|3| | +0#0000000&@35 -| +0#af5f00255&|1|4| |b+1#0000000&@1|b+0&&@1| @31 -| +0#af5f00255&|1|5| | +0#0000000&@35 -| +0#af5f00255&|1|6| | +0#0000000&@35 -| +0#af5f00255&|1|7| | +0#0000000&@35 -|/|b@1> @36 diff --git a/src/testdir/dumps/Test_smooth_incsearch_3.dump b/src/testdir/dumps/Test_smooth_incsearch_3.dump deleted file mode 100644 index 0be3d21932..0000000000 --- a/src/testdir/dumps/Test_smooth_incsearch_3.dump +++ /dev/null @@ -1,8 +0,0 @@ -|<+0#4040ff13#ffffff0@2| +0#af5f00255&|a+0#0000000&@27| @7 -| +0#af5f00255&|1|2| | +0#0000000&@35 -| +0#af5f00255&|1|3| | +0#0000000&@35 -| +0#af5f00255&|1|4| |b+1#0000000&@2|b+0&&| @31 -| +0#af5f00255&|1|5| | +0#0000000&@35 -| +0#af5f00255&|1|6| | +0#0000000&@35 -| +0#af5f00255&|1|7| | +0#0000000&@35 -|/|b@2> @35 diff --git a/src/testdir/dumps/Test_smooth_incsearch_4.dump b/src/testdir/dumps/Test_smooth_incsearch_4.dump deleted file mode 100644 index c81c24b407..0000000000 --- a/src/testdir/dumps/Test_smooth_incsearch_4.dump +++ /dev/null @@ -1,8 +0,0 @@ -|<+0#4040ff13#ffffff0@2| +0#af5f00255&|a+0#0000000&@27| @7 -| +0#af5f00255&|1|2| | +0#0000000&@35 -| +0#af5f00255&|1|3| | +0#0000000&@35 -| +0#af5f00255&|1|4| |b+1#0000000&@3| +0&&@31 -| +0#af5f00255&|1|5| | +0#0000000&@35 -| +0#af5f00255&|1|6| | +0#0000000&@35 -| +0#af5f00255&|1|7| | +0#0000000&@35 -|/|b@3> @34 diff --git a/src/testdir/dumps/Test_statusline_vsep_borrow_hl_01.dump b/src/testdir/dumps/Test_statusline_vsep_borrow_hl_01.dump new file mode 100644 index 0000000000..ee71fb0591 --- /dev/null +++ b/src/testdir/dumps/Test_statusline_vsep_borrow_hl_01.dump @@ -0,0 +1,6 @@ +| +0&#ffffff0@19||+1&&> +0&&@19||+1&&| +0&&@16||+1&&| +0&&@17 +|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16 +|~| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16 +|~| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16 +|L+2#ff404010#ffff4012| @17|R+2#4040ff13#40ff4011| +0#ff404010#ffff4012|L| @17|R+0#4040ff13#40ff4011| |L+2#ff404010#ffff4012| @14|R+2#4040ff13#40ff4011| |L+2#ff404010#ffff4012| @15|R+2#4040ff13#40ff4011 +| +0#0000000#ffffff0@77 diff --git a/src/testdir/dumps/Test_statusline_vsep_borrow_hl_02.dump b/src/testdir/dumps/Test_statusline_vsep_borrow_hl_02.dump new file mode 100644 index 0000000000..60703a35f0 --- /dev/null +++ b/src/testdir/dumps/Test_statusline_vsep_borrow_hl_02.dump @@ -0,0 +1,6 @@ +| +0&#ffffff0@19||+1&&| +0&&@19||+1&&> +0&&@19||+1&&| +0&&@14 +|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @13 +|~| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @13 +|~| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @13 +|L+2#ff404010#ffff4012| @17|R+2#4040ff13#40ff4011| |L+2#ff404010#ffff4012| @17|R+2#4040ff13#40ff4011| +0#ff404010#ffff4012|L| @17|R+0#4040ff13#40ff4011| |L+2#ff404010#ffff4012| @12|R+2#4040ff13#40ff4011 +| +0#0000000#ffffff0@77 diff --git a/src/testdir/dumps/Test_switchwin_clear_pum_02.dump b/src/testdir/dumps/Test_switchwin_clear_pum_02.dump index 39013c09fd..cf5f9dbc9c 100644 --- a/src/testdir/dumps/Test_switchwin_clear_pum_02.dump +++ b/src/testdir/dumps/Test_switchwin_clear_pum_02.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|w+1#0000000&|i|n|_|b| |[|+|]| @9|1|,|1|0| @10|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|9| @11|A|l@1 +|w+1#0000000&|i|n|_|b| |[|+|]| @9|1|,|1|0| @10|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|9| @11|A|l@1 |-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@62 diff --git a/src/testdir/dumps/Test_tabpanel_carry_hl_01.dump b/src/testdir/dumps/Test_tabpanel_carry_hl_01.dump new file mode 100644 index 0000000000..87a130f293 --- /dev/null +++ b/src/testdir/dumps/Test_tabpanel_carry_hl_01.dump @@ -0,0 +1,9 @@ +|L+2&#ffffff0|1|A| @16> +0&&@39 +|L+0&#ffff4012|1|B| @16|~+0#4040ff13#ffffff0| @38 +|L+0#0000000#ffff4012|2| |c|a|r@1|i|e|d| |S|e|a|r|c|h| @2|~+0#4040ff13#ffffff0| @38 +|L+2#0000000&|3| |r|e|s|e|t| @11|~+0#4040ff13&| @38 +|L+0#ffff4012#4040ff13|4| |u|s|e|r|2| @11|~+0#4040ff13#ffffff0| @38 +|L+0#ffff4012#4040ff13|5| |c|a|r@1|i|e|d| @9|~+0#4040ff13#ffffff0| @38 +|L+2#0000000&|6| |r|e|s|e|t| @11|~+0#4040ff13&| @38 +| +1#0000000&@19|~+0#4040ff13&| @38 +| +1#0000000&@19| +0&&@21|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/dumps/Test_tabpanel_drawing_2_0.dump b/src/testdir/dumps/Test_tabpanel_drawing_2_0.dump index 23fe3c8e47..c6d034efb7 100644 --- a/src/testdir/dumps/Test_tabpanel_drawing_2_0.dump +++ b/src/testdir/dumps/Test_tabpanel_drawing_2_0.dump @@ -1,10 +1,10 @@ -| +0&#ffffff0@57||+1&&|++2&&| |[|N|o| |N|a|m|e|]| @7 -> +0&&@57||+1&&| @18 -|a+0&&@2| @54||+1&&| @18 -|~+0#4040ff13&| @56||+1#0000000&| @18 -|~+0#4040ff13&| @56||+1#0000000&| @18 -|~+0#4040ff13&| @56||+1#0000000&| @18 -|~+0#4040ff13&| @56||+1#0000000&| @18 -|~+0#4040ff13&| @56||+1#0000000&| @18 -|~+0#4040ff13&| @56||+1#0000000&| @18 -|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@27|2|,|1| @10|A|l@1| ||+1&&| @18 +| +0&#ffffff0@44||+1&&|++2&&| |[|N|o| |N|a|m|e|]| @7 +> +0&&@44||+1&&| @18 +|a+0&&@2| @41||+1&&| @18 +|~+0#4040ff13&| @43||+1#0000000&| @18 +|~+0#4040ff13&| @43||+1#0000000&| @18 +|~+0#4040ff13&| @43||+1#0000000&| @18 +|~+0#4040ff13&| @43||+1#0000000&| @18 +|~+0#4040ff13&| @43||+1#0000000&| @18 +|~+0#4040ff13&| @43||+1#0000000&| @18 +|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@14|2|,|1| @10|A|l@1| ||+1&&| @18 diff --git a/src/testdir/dumps/Test_tabpanel_drawing_2_1.dump b/src/testdir/dumps/Test_tabpanel_drawing_2_1.dump index d82adb29a8..92276717e1 100644 --- a/src/testdir/dumps/Test_tabpanel_drawing_2_1.dump +++ b/src/testdir/dumps/Test_tabpanel_drawing_2_1.dump @@ -1,10 +1,10 @@ -|++2&#ffffff0| |[|N|o| |N|a|m|e|]| @7||+1&&| +0&&@57 -| +1&&@18||> +0&&@57 -| +1&&@18|||a+0&&@2| @54 -| +1&&@18|||~+0#4040ff13&| @56 -| +1#0000000&@18|||~+0#4040ff13&| @56 -| +1#0000000&@18|||~+0#4040ff13&| @56 -| +1#0000000&@18|||~+0#4040ff13&| @56 -| +1#0000000&@18|||~+0#4040ff13&| @56 -| +1#0000000&@18|||~+0#4040ff13&| @56 -| +1#0000000&@18|||-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@27|2|,|1| @10|A|l@1| +|++2&#ffffff0| |[|N|o| |N|a|m|e|]| @7||+1&&| +0&&@44 +| +1&&@18||> +0&&@44 +| +1&&@18|||a+0&&@2| @41 +| +1&&@18|||~+0#4040ff13&| @43 +| +1#0000000&@18|||~+0#4040ff13&| @43 +| +1#0000000&@18|||~+0#4040ff13&| @43 +| +1#0000000&@18|||~+0#4040ff13&| @43 +| +1#0000000&@18|||~+0#4040ff13&| @43 +| +1#0000000&@18|||~+0#4040ff13&| @43 +| +1#0000000&@18|||-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@14|2|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_tabpanel_drawing_scrolling_3.dump b/src/testdir/dumps/Test_tabpanel_drawing_scrolling_3.dump index b041b672f6..0ee2efe9db 100644 --- a/src/testdir/dumps/Test_tabpanel_drawing_scrolling_3.dump +++ b/src/testdir/dumps/Test_tabpanel_drawing_scrolling_3.dump @@ -6,5 +6,5 @@ | +1&&@19| +0#af5f00255&@1|6| ||+1#0000000&| +0#af5f00255&|3|0| |t+0#0000000&|e|x|t| |t|e|x|t| |t|e|x|t| |t | +1&&@19| +0#af5f00255&@1|7| ||+1#0000000&| +0#af5f00255&|3|1| |t+0#0000000&|e|x|t| |t|e|x|t| |t|e|x|t| |t | +1&&@19| +0#af5f00255&@1|8| ||+1#0000000&| +0#af5f00255&|3|2| |t+0#0000000&|e|x|t| |t|e|x|t| |t|e|x|t| |t -| +1&&@19|<| |1|,| |<+3&&|.|t|x|t| |[|+|]| |2|8|,|1| @2|2|6|% +| +1&&@19|<| |1|,| +3&&|<|.|t|x|t| |[|+|]| |2|8|,|1| @2|2|6|% | +1&&@19| +0&&@24 diff --git a/src/testdir/dumps/Test_tabpanel_many_tabpages_4.dump b/src/testdir/dumps/Test_tabpanel_many_tabpages_4.dump index aa1ae3e18b..3f462354c4 100644 --- a/src/testdir/dumps/Test_tabpanel_many_tabpages_4.dump +++ b/src/testdir/dumps/Test_tabpanel_many_tabpages_4.dump @@ -1,10 +1,10 @@ -|1+2&#ffffff0@1|:|t|a|b| @3> +0&&@34 +|5+8#0000001#e0e0e08|:|t|a|b| @4> +0#0000000#ffffff0@34 +|6+8#0000001#e0e0e08|:|t|a|b| @4|~+0#4040ff13#ffffff0| @33 +|7+8#0000001#e0e0e08|:|t|a|b| @4|~+0#4040ff13#ffffff0| @33 +|8+8#0000001#e0e0e08|:|t|a|b| @4|~+0#4040ff13#ffffff0| @33 +|9+8#0000001#e0e0e08|:|t|a|b| @4|~+0#4040ff13#ffffff0| @33 +|1+8#0000001#e0e0e08|0|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 +|1+2#0000000&@1|:|t|a|b| @3|~+0#4040ff13&| @33 |1+8#0000001#e0e0e08|2|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 |1+8#0000001#e0e0e08|3|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 -|1+8#0000001#e0e0e08|4|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 -|1+8#0000001#e0e0e08|5|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 -|1+8#0000001#e0e0e08|6|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 -|1+8#0000001#e0e0e08|7|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 -|1+8#0000001#e0e0e08|8|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 -|1+8#0000001#e0e0e08|9|:|t|a|b| @3|~+0#4040ff13#ffffff0| @33 -|2+8#0000001#e0e0e08|0|:|t|a|b| @3|:+0#0000000#ffffff0|t|a|b|n|e|x|t| |-|3| @6|0|,|0|-|1| @7|A|l@1| +|1+8#0000001#e0e0e08|4|:|t|a|b| @3|:+0#0000000#ffffff0|t|a|b|n|e|x|t| |-|3| @6|0|,|0|-|1| @7|A|l@1| diff --git a/src/testdir/dumps/Test_wildmenu_pum_22.dump b/src/testdir/dumps/Test_wildmenu_pum_22.dump index e774d5dda2..463195169e 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_22.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_22.dump @@ -3,7 +3,7 @@ |:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|l+0#0000000&|o|n|g|e|s|t|,+0#e000e06&|f+0#0000000&|u|l@1| @48 |:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|f+0#0000000&|u|l@1| @56 |:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e| @62 -|:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e> @62 +|:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n>e| @62 |~+0#4040ff13&| @73 |~| @73 |[+3#0000000&|C|o|m@1|a|n|d| |L|i|n|e|]| @60 diff --git a/src/testdir/dumps/Test_wildmenu_pum_info_async_update.dump b/src/testdir/dumps/Test_wildmenu_pum_info_async_update.dump new file mode 100644 index 0000000000..249f509e23 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_info_async_update.dump @@ -0,0 +1,14 @@ +| +0&#ffffff0@49 +|~+0#4040ff13&| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @19|╔+0#0000001#e0e0e08|═@5|X| +0#4040ff13#ffffff0@20 +|~| @3| +0#0000001#e0e0e08|1| @13|║| |d|o|n|e| |║| +0#4040ff13#ffffff0@20 +|~| @3| +0#0000001#ffd7ff255|2| @13|╚+0&#e0e0e08|═@5|⇲| +0#4040ff13#ffffff0@20 +|:+0#0000000&|T|e|s|t| |1> @42 diff --git a/src/testdir/dumps/Test_wildtrigger_wrapped_cmdline_1.dump b/src/testdir/dumps/Test_wildtrigger_wrapped_cmdline_1.dump new file mode 100644 index 0000000000..409cf54fa4 --- /dev/null +++ b/src/testdir/dumps/Test_wildtrigger_wrapped_cmdline_1.dump @@ -0,0 +1,8 @@ +|~+0#4040ff13#ffffff0| @28 +|~| @28 +|~| @28 +|~| @28 +|~| @28 +|~| @28 +|:+0#0000000&|e| |x@26 +@13> @16 diff --git a/src/testdir/dumps/Test_winbar_vsep_active.dump b/src/testdir/dumps/Test_winbar_vsep_active.dump new file mode 100644 index 0000000000..9a0e234045 --- /dev/null +++ b/src/testdir/dumps/Test_winbar_vsep_active.dump @@ -0,0 +1,20 @@ +| +0&#ffffff0@19||+0#000000255&| +0#0000000&@18||+0#000000255&| +0#0000000&@18 +|~+0#4040ff13&| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+0#000000255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|<+1#0000000&|N|o| |N|a|m|e|]| |0|,|0|-|1| @1|A|l@1| |<|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1| |<|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1 +| +0&#e0e0e08| +2#ffffff16#6c6c6c255|S|t|e|p| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|N|e|x|t| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|F|i|n|i|s|h| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|C|o||+1#87afff255#ffffff0| +0#0000000&@28 +> @29||+1#87afff255&|~+0#4040ff13&| @27 +|~| @28||+1#87afff255&|~+0#4040ff13&| @27 +|~| @28||+1#87afff255&|~+0#4040ff13&| @27 +|~| @28||+1#87afff255&|~+0#4040ff13&| @27 +|~| @28||+1#87afff255&|~+0#4040ff13&| @27 +|~| @28||+1#87afff255&|~+0#4040ff13&| @27 +|~| @28||+1#87afff255&|~+0#4040ff13&| @27 +|[+3#0000000&|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @6|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @5|A|l@1 +| +0&&@59 diff --git a/src/testdir/dumps/Test_winbar_vsep_inactive.dump b/src/testdir/dumps/Test_winbar_vsep_inactive.dump new file mode 100644 index 0000000000..2e6f17fe78 --- /dev/null +++ b/src/testdir/dumps/Test_winbar_vsep_inactive.dump @@ -0,0 +1,20 @@ +> +0&#ffffff0@19||+1#87afff255&| +0#0000000&@18||+0#000000255&| +0#0000000&@18 +|~+0#4040ff13&| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|~| @18||+1#87afff255&|~+0#4040ff13&| @17||+0#000000255&|~+0#4040ff13&| @17 +|<+3#0000000&|N|o| |N|a|m|e|]| |0|,|0|-|1| @1|A|l@1| |<+1&&|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1| |<|N|o| |N|a|m|e|]| |0|,|0|-|1| |A|l@1 +| +0&#e0e0e08| +2#ffffff16#6c6c6c255|S|t|e|p| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|N|e|x|t| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|F|i|n|i|s|h| | +0#0000000#e0e0e08@1| +2#ffffff16#6c6c6c255|C|o||+0#000000255#ffffff0| +0#0000000&@28 +@30||+0#000000255&|~+0#4040ff13&| @27 +|~| @28||+0#000000255&|~+0#4040ff13&| @27 +|~| @28||+0#000000255&|~+0#4040ff13&| @27 +|~| @28||+0#000000255&|~+0#4040ff13&| @27 +|~| @28||+0#000000255&|~+0#4040ff13&| @27 +|~| @28||+0#000000255&|~+0#4040ff13&| @27 +|~| @28||+0#000000255&|~+0#4040ff13&| @27 +|[+1#0000000&|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @6|A|l@1| |[|N|o| |N|a|m|e|]| @5|0|,|0|-|1| @5|A|l@1 +| +0&&@59 diff --git a/src/testdir/dumps/Test_winhighlight_14.dump b/src/testdir/dumps/Test_winhighlight_14.dump index 1ea869d656..176bf6ea99 100644 --- a/src/testdir/dumps/Test_winhighlight_14.dump +++ b/src/testdir/dumps/Test_winhighlight_14.dump @@ -4,5 +4,5 @@ |S+8&&|i|x| @33||+1&&|S+0&&|i|x| @33 |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|3| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|5| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|3| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|5| @11|A|l@1 |:+0&&|w|i|n|c|m|d| |l| @65 diff --git a/src/testdir/dumps/Test_winhighlight_15.dump b/src/testdir/dumps/Test_winhighlight_15.dump index a90302a86f..7d69f21b56 100644 --- a/src/testdir/dumps/Test_winhighlight_15.dump +++ b/src/testdir/dumps/Test_winhighlight_15.dump @@ -4,5 +4,5 @@ |S+8#0000000#ffffff0|i|x| @33||+1&&|S+0#ffffff16#e000002|i|x| @33 |~+0#4040ff13#ffffff0| @35||+1#0000000&|~+0#4040ff13#e000002| @35 |~+0&#ffffff0| @35||+1#0000000&|~+0#4040ff13#e000002| @35 -|[+1#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|3| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|5| @11|A|l@1 +|[+1#0000000#ffffff0|N|o| |N|a|m|e|]| |[|+|]| @5|3|,|3| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|5| @11|A|l@1 |:+0&&|s|e|t|l|o|c|a|l| |w|h|l|=|N|o|r|m|a|l|:|E|r@1|o|r|M|s|g| @45 diff --git a/src/testdir/dumps/Test_winhighlight_2.dump b/src/testdir/dumps/Test_winhighlight_2.dump index b84ef70531..72f754114e 100644 --- a/src/testdir/dumps/Test_winhighlight_2.dump +++ b/src/testdir/dumps/Test_winhighlight_2.dump @@ -4,5 +4,5 @@ |S|i|x| @33||+1&&|S+0&&|i|x| @33 |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 |:+0&&|w|i|n|c|m|d| |l| @65 diff --git a/src/testdir/dumps/Test_winhighlight_6.dump b/src/testdir/dumps/Test_winhighlight_6.dump index f5753e1187..e482465ca4 100644 --- a/src/testdir/dumps/Test_winhighlight_6.dump +++ b/src/testdir/dumps/Test_winhighlight_6.dump @@ -4,5 +4,5 @@ |S|i|x| @33||+1&&|S+0&&|i|x| @33 |~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 |:+0&&|s|e|t|l|o|c|a|l| |w|h|l|=|V|e|r|t|S|p|l|i|t|:|E|r@1|o|r|M|s|g| @42 diff --git a/src/testdir/dumps/Test_winhighlight_hlsearch_2.dump b/src/testdir/dumps/Test_winhighlight_hlsearch_2.dump index 30d643854e..37a9087bba 100644 --- a/src/testdir/dumps/Test_winhighlight_hlsearch_2.dump +++ b/src/testdir/dumps/Test_winhighlight_hlsearch_2.dump @@ -16,5 +16,5 @@ |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 |~| @35||+1#0000000&|~+0#4040ff13&| @35 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @5|2|,|1| @11|A|l@1 |/+0&&|F> @72 diff --git a/src/testdir/dumps/Test_winscrolled_once_only_1.dump b/src/testdir/dumps/Test_winscrolled_once_only_1.dump index 56d640107e..7407f46863 100644 --- a/src/testdir/dumps/Test_winscrolled_once_only_1.dump +++ b/src/testdir/dumps/Test_winscrolled_once_only_1.dump @@ -5,6 +5,6 @@ |a+0#0000000&@2| @26||+1&&|~+0#4040ff13&| @27 |b+0#0000000&@2| @26||+1&&|~+0#4040ff13&| @27 |~| @28||+1#0000000&|~+0#4040ff13&| @27 -|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1| |[+3&&|N|o| |N|a|m|e|]| |[|+|]| @1|2|,|1| @7|B|o|t +|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1| +3&&|[|N|o| |N|a|m|e|]| |[|+|]| @1|2|,|1| @7|B|o|t |1+0&&| |1|0@2| |[|'|r|o|w|'|,| |[@1|'|c|o|l|'|,| |[@1|'|l|e|a|f|'|,| |1|0@1|2|]|,| |[|'|l|e|a|f|'|,| |1|0@1|1|]@2|,| |[ |'|l|e|a|f|'|,| |1|0@2|]@2| @44 diff --git a/src/testdir/samples/Test_tohtml_basic.c.html b/src/testdir/samples/Test_tohtml_basic.c.html index 9046d847c7..ecabe8e367 100644 --- a/src/testdir/samples/Test_tohtml_basic.c.html +++ b/src/testdir/samples/Test_tohtml_basic.c.html @@ -4,7 +4,7 @@ /home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic.c.html - + diff --git a/src/testdir/samples/Test_tohtml_basic_no_css.c.html b/src/testdir/samples/Test_tohtml_basic_no_css.c.html index 272b71248a..0cba690cf7 100644 --- a/src/testdir/samples/Test_tohtml_basic_no_css.c.html +++ b/src/testdir/samples/Test_tohtml_basic_no_css.c.html @@ -4,7 +4,7 @@ /home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic_no_css.c.html - + diff --git a/src/testdir/samples/combining_chars.txt b/src/testdir/samples/combining_chars.txt new file mode 100644 index 0000000000..d9a3c171fb --- /dev/null +++ b/src/testdir/samples/combining_chars.txt @@ -0,0 +1,200 @@ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aˁˁˁˁˁ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ +aĖĖĖĖĖáŒ diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 81c2edd5ce..70adeb8d81 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -1199,10 +1199,10 @@ endfunc " Closing a window might cause an endless loop " E814 for older Vims func Test_autocmd_bufwipe_in_SessLoadPost() + set noswapfile edit Xtest tabnew file Xsomething - set noswapfile mksession! let content =<< trim [CODE] @@ -5967,4 +5967,162 @@ func Test_autocmd_add_secure() call assert_fails('sandbox call autocmd_delete([{"event": "BufRead"}])', 'E48:') endfunc +func Test_TextPutX() + enew! + + let g:pre_event = [] + let g:post_event = [] + au TextPutPre * let g:pre_event = copy(v:event) + au TextPutPost * let g:post_event = copy(v:event) + + call setreg('a', ['foo'], 'v') + norm "ap + call assert_equal( + \ #{regcontents: ['foo'], regname: 'a', operator: 'p', + \ visual: v:false, regtype: 'v'}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + + call setreg('', ['hello'], 'V') + norm P + call assert_equal( + \ #{regcontents: ['hello'], regname: '', operator: 'P', + \ visual: v:false, regtype: 'V'}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + + call setreg('', ['maybe', 'true'], 'V') + norm Vp + call assert_equal( + \ #{regcontents: ['maybe', 'true'], regname: '', operator: 'P', + \ regtype: 'V', visual: v:true}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + call assert_equal({}, v:event) + + call feedkeys("iinserted text\below\", 'x') + norm ".p + call assert_equal( + \ #{regcontents: ["inserted text\nbelow"], regname: '.', + \ operator: 'p', regtype: 'v', visual: v:false}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + + call feedkeys("\"=201\p", 'x') + call assert_equal( + \ #{regcontents: ["201"], regname: '=', + \ operator: 'p', regtype: 'v', visual: v:false}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + + vsplit some.txt + wincmd l + norm "#p + call assert_equal( + \ #{regcontents: ["some.txt"], regname: '#', + \ operator: 'p', regtype: 'v', visual: v:false}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + wincmd h + bw! + + if has('clipboard_working') + let @+ = 'clipboard' + + norm "+p + call assert_equal( + \ #{regcontents: ["clipboard"], regname: '+', + \ operator: 'p', regtype: 'v', visual: v:false}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + endif + + %delete " Clear buffer + + au! TextPutPre + au! TextPutPost + let g:pre_event = [] + let g:post_event = [] + + au TextPutPre * call setreg(v:event['regname'], + \ getreg('', 0, v:true) + ['!']) " Unnamed register should be same as regname + + call setreg('', ['hello', 'world']) + norm p + call assert_equal(['', 'hello', 'world', '!'], getline(1, '$')) + + au! TextPutPre + + " Test that special registers cannot be modified + %delete + au TextPutPre * call setreg('=', '"modified"') | let g:pre_event = copy(v:event) + + " Set up the expression register to evaluate to a known value. + call feedkeys("\"=\"original\"\p", 'x') + + " The original value is what got put, not the modified one. + call assert_equal(['original'], getline(1, '$')) + + " v:event still reports the original value. + call assert_equal(['original'], g:pre_event['regcontents']) + + au! TextPutPre + let g:pre_event = [] + + for round in range(2) + " Recursive ". register calls have the same contents for post and pre. + au TextPutPre * put . | let g:pre_event = copy(v:event) + au TextPutPost * let g:post_event = copy(v:event) + + call feedkeys("iinserted\", 'x') + norm! ".p + + call assert_equal( + \ #{regcontents: ["inserted"], regname: '.', + \ operator: 'p', regtype: 'v', visual: v:false}, + \ g:pre_event) + call assert_equal(g:pre_event, g:post_event) + + au! TextPutPre + au! TextPutPost + + " Pasting ". register without TextPutPre/TextPutPost autocommands should + " not interfere with these autocommands in the next round. + norm! ".p + endfor + + unlet g:post_event + unlet g:pre_event + bwipe! +endfunc + +" Test that attempting to put text in normal mode terminal buffer does not +" result in a crash. This only happens when terminal is only window in tabpage +" it seems. +func Test_TextPutPost_term_norm() + CheckFeature terminal + + tabnew + term ++curwin + + let bnr = bufnr('$') + call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) + + call feedkeys("\\", 'xt') + call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) + + let err = 0 + + try + call feedkeys("p", 'xt') + catch /^Vim\%((\S\+)\)\=:E21:/ + let err = 1 + endtry + + call assert_true(err) + + unlet err + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim index bb164f70ea..b309108c94 100644 --- a/src/testdir/test_breakindent.vim +++ b/src/testdir/test_breakindent.vim @@ -988,6 +988,7 @@ func Test_visual_starts_before_skipcol() let buf = RunVimInTerminal('-S XvisualStartsBeforeSkipcol', #{rows: 6}) call term_sendkeys(buf, "v$") + call WaitForAssert({-> assert_match('VISUAL.*\d', term_getline(buf, 6))}, 1000) call VerifyScreenDump(buf, 'Test_visual_starts_before_skipcol_1', {}) call term_sendkeys(buf, "\:setlocal showbreak=+++\gv") call VerifyScreenDump(buf, 'Test_visual_starts_before_skipcol_2', {}) diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim index 934bc6fe1e..4f0f1acb24 100644 --- a/src/testdir/test_buffer.vim +++ b/src/testdir/test_buffer.vim @@ -342,6 +342,28 @@ func Test_goto_buf_with_confirm() close! endfunc +" Test for issue #20132: when saving an unnamed buffer fails the modified +" flag must be kept, otherwise the buffer is silently discarded. +func Test_dialog_changed_keep_modified_on_write_fail() + CheckUnix + CheckNotGui + CheckFeature dialog_con + CheckNotFeature dialog_con_gui + CheckNotRoot + + call writefile(['existing'], 'Untitled', 'D') + call setfperm('Untitled', 'r--r--r--') + + new + call setline(1, 'test') + call feedkeys('y', 'L') + silent! confirm bdel + call assert_true(&modified) + call assert_equal(['existing'], readfile('Untitled')) + + bw! +endfunc + " Test for splitting buffer with 'switchbuf' func Test_buffer_switchbuf() new Xswitchbuf diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim index e95c7c2e0e..a175cd2748 100644 --- a/src/testdir/test_cd.vim +++ b/src/testdir/test_cd.vim @@ -263,7 +263,7 @@ func Test_cd_completion() let dir = d " Yay! We found a suitable dir! break - catch /:E472:/ + catch /:\(E472\|E344\):/ " Just skip directories where "cd" fails continue finally diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 6cd55ca9f9..f35a1b8556 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -1390,6 +1390,64 @@ func Test_out_cb_lambda() endtry endfunc +func Test_out_cb_blob_mode() + let g:Ch_blob_bytes = [] + func OutBlobCb(chan, msg) + call assert_equal(v:t_blob, type(a:msg)) + let g:Ch_blob_bytes += blob2list(a:msg) + endfunc + + let cmd = [s:python, '-c', + \ 'import sys,time;' + \ .. 'sys.stdout.buffer.write(bytes([0, 1, 2, 10, 255]));' + \ .. 'sys.stdout.flush();' + \ .. 'time.sleep(0.1)'] + let job = job_start(cmd, #{ + \ out_mode: 'blob', + \ out_cb: 'OutBlobCb', + \ }) + try + call WaitForAssert({-> assert_equal([0, 1, 2, 10, 255], g:Ch_blob_bytes)}) + finally + call job_stop(job) + delfunc OutBlobCb + unlet g:Ch_blob_bytes + endtry +endfunc + +func Test_pty_out_cb_blob_mode() + CheckUnix + + let g:Ch_blob_bytes = [] + func PtyBlobCb(chan, msg) + call assert_equal(v:t_blob, type(a:msg)) + let g:Ch_blob_bytes += blob2list(a:msg) + endfunc + + " Put the pty in raw mode so the line discipline does not translate LF + " to CRLF or strip NUL bytes, then write bytes that include NULs on + " both sides of an embedded LF. + let cmd = [s:python, '-c', + \ 'import os,sys,time;' + \ .. 'os.system("stty raw -echo");' + \ .. 'sys.stdout.buffer.write(bytes([65, 0, 66, 10, 67, 0, 68]));' + \ .. 'sys.stdout.flush();' + \ .. 'time.sleep(0.1)'] + let job = job_start(cmd, #{ + \ pty: 1, + \ out_mode: 'blob', + \ out_cb: 'PtyBlobCb', + \ }) + try + call WaitForAssert({-> assert_equal( + \ [65, 0, 66, 10, 67, 0, 68], g:Ch_blob_bytes)}) + finally + call job_stop(job) + delfunc PtyBlobCb + unlet g:Ch_blob_bytes + endtry +endfunc + func Test_close_and_exit_cb() let g:test_is_flaky = 1 let g:retdict = {'ret': {}} @@ -2778,7 +2836,7 @@ endfunction func Test_listen() call ch_log('Test_listen()') - let server = ch_listen('127.0.0.1:12345', {'callback': function('s:test_listen_accept')}) + let server = ch_listen('12345', {'callback': function('s:test_listen_accept')}) if ch_status(server) == 'fail' call assert_report("Can't listen channel") return @@ -2799,35 +2857,36 @@ func Test_listen() call assert_match('127.0.0.1:', g:server_received_addr) endfunc -func Test_listen_invalid_address() - call ch_log('Test_listen_invalid_address()') - - " empty address - call assert_fails("call ch_listen('')", 'E475:') +func Test_listen_invalid_argument() + call ch_log('Test_listen_invalid_argument()') " missing port - call assert_fails("call ch_listen('localhost')", 'E475:') + call assert_fails("call ch_listen('')", 'E475:') " port number too large - call assert_fails("call ch_listen('localhost:99999')", 'E475:') + call assert_fails("call ch_listen('99999')", 'E475:') " port number zero should let the OS assign an available port - let ch = ch_listen('localhost:0') + let ch = ch_listen('0') call assert_equal('open', ch_status(ch)) call assert_notequal(0, ch_info(ch).port) call ch_close(ch) " port number negative - call assert_fails("call ch_listen('localhost:-1')", 'E475:') + call assert_fails("call ch_listen('-1')", 'E475:') - " invalid ipv6 format (missing closing bracket) - call assert_fails("call ch_listen('[::1:8765')", 'E475:') - - " invalid ipv6 format (missing port) + " make sure we don't accept hostname/IP address + call assert_fails("call ch_listen('127.0.0.1:4500')", 'E475:') + call assert_fails("call ch_listen('127.0.0.1')", 'E475:') + call assert_fails("call ch_listen('localhost:4500')", 'E475:') + call assert_fails("call ch_listen('localhost')", 'E475:') call assert_fails("call ch_listen('[::1]')", 'E475:') +endfunc - " TODO: IPv6 should actually work - call assert_fails("call ch_listen('[::1]:9999')", 'E1574:') +func Test_listen_info_no_hostname() + let ch = ch_listen('0') + call assert_fails("call ch_info(ch).hostname", 'E716:') + call ch_close(ch) endfunc func Test_channel_lsp_mode() @@ -2921,24 +2980,26 @@ func Test_error_callback_terminal() call assert_equal('RAW', dict.err_mode) call assert_equal('pipe', dict.err_io) call term_sendkeys(buf, "XXXX\") - call term_wait(buf) + " term_wait() does not wait for the err_io 'pipe' callback to fire, so use + " WaitForAssert() to poll until sh has written the error message. + call WaitForAssert({-> assert_match('sh:.*XXXX:.*not found', g:error)}, 5000) call term_sendkeys(buf, "exit\") - call term_wait(buf) - call assert_match('XXX.*exit', g:out) - call assert_match('sh:.*XXXX:.*not found', g:error) + call WaitForAssert({-> assert_match('XXX.*exit', g:out)}, 5000) delfunc s:Out delfunc s:Err unlet! g:out g:error endfunc -" Verify that term_start() with out_cb/err_cb delivers one line per callback -" call (no embedded newlines, no trailing CR), matching the user's expectation. -func Test_term_start_cb_per_line() +" Verify that term_start() with out_cb/err_cb delivers data in RAW mode, +" preserving embedded newlines in the raw chunk received from read(). If +" per-line handling is desired, it is the callback's responsibility to split +" on NL and strip the trailing CR. +func Test_term_start_cb_raw_chunk() CheckUnix CheckFeature terminal let g:Ch_msgs = [] - let script_file = 'Xterm_cb_per_line.sh' + let script_file = 'Xterm_cb_raw_chunk.sh' call writefile(["#!/bin/sh", \ "printf 'err:1\\nerr:2\\n' >&2", \ "printf 'out:3\\n'"], script_file, 'D') @@ -2946,10 +3007,16 @@ func Test_term_start_cb_per_line() let ptybuf = term_start('./' .. script_file, { \ 'out_cb': {ch, msg -> add(g:Ch_msgs, msg)}, \ 'err_cb': {ch, msg -> add(g:Ch_msgs, msg)}}) - call WaitForAssert({-> assert_equal(3, len(g:Ch_msgs))}, 5000) - " Each line must arrive as a separate callback call with no embedded CR/NL. - call assert_equal(['err:1', 'err:2', 'out:3'], g:Ch_msgs) + " Wait until both the raw stderr chunk and a stdout chunk have arrived. + call WaitForAssert({-> assert_true( + \ index(g:Ch_msgs, "err:1\nerr:2\n") >= 0 + \ && match(g:Ch_msgs, 'out:3') >= 0)}, 5000) + " stderr (via pipe) arrives as a single raw chunk with embedded NL, + " not split per line. stdout (via PTY) is delivered, but its exact + " CR/LF shape depends on the PTY line discipline, so we only check that + " 'out:3' appears somewhere in the received chunks. call job_stop(term_getjob(ptybuf)) + exe 'bwipe! ' .. ptybuf unlet g:Ch_msgs endfunc diff --git a/src/testdir/test_cindent.vim b/src/testdir/test_cindent.vim index 4884dbb304..f050d82f8c 100644 --- a/src/testdir/test_cindent.vim +++ b/src/testdir/test_cindent.vim @@ -5526,5 +5526,85 @@ def Test_find_brace_backwards() bwipe! enddef +" Brackets inside comments must not affect C indent calculation (FM_SKIPCOMM) +def Test_cindent_comment_brackets() + # stray } in inline block comment must not confuse enclosing-brace search + new + setl cindent sw=4 + var code =<< trim [CODE] + int foo() { + /* } */ + int bar; + } + [CODE] + setline(1, code) + cursor(3, 1) + normal == + assert_equal(' int bar;', getline(3)) + bwipe! + + # stray } in // line comment: same + new + setl cindent sw=4 + var code2 =<< trim [CODE] + int foo() { + // } + int bar; + } + [CODE] + setline(1, code2) + cursor(3, 1) + normal == + assert_equal(' int bar;', getline(3)) + bwipe! + + # stray } on continuation line inside multi-line block comment + new + setl cindent sw=4 + var code3 =<< trim [CODE] + int foo() { + /* + } + */ + int bar; + } + [CODE] + setline(1, code3) + cursor(5, 1) + normal == + assert_equal(' int bar;', getline(5)) + bwipe! + + # { in inline block comment must not be treated as enclosing brace + new + setl cindent sw=4 + var code4 =<< trim [CODE] + int foo() { + /* { */ + int bar; + } + [CODE] + setline(1, code4) + cursor(3, 1) + normal == + assert_equal(' int bar;', getline(3)) + bwipe! + + # ) in inline block comment must not be treated as enclosing brace + new + setl cindent sw=4 + var code5 =<< trim [CODE] + some_func(arg1, + /* ) */ arg2, + arg3); + [CODE] + setline(1, code5) + cursor(3, 1) + normal == + assert_equal(' arg3);', getline(3)) + bwipe! + +enddef + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_clientserver.vim b/src/testdir/test_clientserver.vim index 96a9c31b02..ea14145f44 100644 --- a/src/testdir/test_clientserver.vim +++ b/src/testdir/test_clientserver.vim @@ -1,5 +1,6 @@ " Tests for the +clientserver feature. +source util/screendump.vim CheckFeature job if !has('clientserver') @@ -16,10 +17,6 @@ endif source util/shared.vim -" Unlike X11, we need the socket server running if we want to send commands to -" a server via sockets. -RunSocketServer - func Check_X11_Connection() if has('x11') CheckX11 @@ -151,6 +148,7 @@ func Test_client_server() " Edit multiple files using --remote call system(cmd .. ' --remote Xclientfile1 Xclientfile2 Xclientfile3') + call WaitForAssert({-> assert_equal('3', remote_expr(name, 'argc()'))}) call assert_match(".*Xclientfile1\n.*Xclientfile2\n.*Xclientfile3\n", remote_expr(name, 'argv()')) eval name->remote_send(":%bw!\") @@ -197,9 +195,9 @@ func Test_client_server() " When using socket server, server id is not a number, but the path to the " socket. - if has('socketserver') && !has('X11') - call assert_fails("let x = remote_read('vim/10')", ['E573:.*vim/10']) - call assert_fails("call server2client('a/b/c', 'xyz')", ['E573:.*a/b/c']) + if (has('socketserver') && !has('X11') && !has('win32')) || index(v:argv, "socket") != -1 + call assert_fails("let x = remote_read('vim/10')", ['E1564:']) + call assert_fails("call server2client('x/b/c', 'xyz')", ['E1564:']) else call assert_fails("let x = remote_read('vim10')", \ has('unix') ? ['E573:.*vim10'] : 'E277:') @@ -251,89 +249,65 @@ func Test_client_server_stopinsert() endtry endfunc -" Test if socket server and X11 backends can be chosen and work properly. -func Test_client_server_x11_and_socket_server() - CheckNotMSWindows - CheckFeature socketserver - CheckFeature x11 +" Test if socket server, X11, and mswin backends can be chosen and work properly. +func Test_client_server_multiple_backends() + CheckFeature socketserver - let g:test_is_flaky = 1 - let cmd = GetVimCommand() + let g:test_is_flaky = 1 + let cmd = GetVimCommand() - if cmd == '' - throw 'GetVimCommand() failed' - endif - call Check_X11_Connection() - - let types = ['socket', 'x11'] - - for type in types - let name = 'VIMTEST_' .. toupper(type) - let actual_cmd = cmd .. ' --clientserver ' .. type - let actual_cmd .= ' --servername ' .. name - let job = job_start(actual_cmd, {'stoponexit': 'kill', 'out_io': 'null'}) - - call WaitForAssert({-> assert_equal("run", job_status(job))}) - call WaitForAssert({-> assert_match(name, system(cmd .. ' --clientserver ' .. type .. ' --serverlist'))}) - - call assert_match(name, system(actual_cmd .. ' --remote-expr "v:servername"')) - - call system(actual_cmd .. " --remote-expr 'execute(\"qa!\")'") - try - call WaitForAssert({-> assert_equal("dead", job_status(job))}) - finally - if job_status(job) != 'dead' - call assert_report('Server did not exit') - call job_stop(job, 'kill') - endif - endtry - endfor -endfunc - -" Test if socket server works in the GUI -func Test_client_server_socket_server_gui() - CheckNotMSWindows - CheckFeature socketserver - CheckFeature gui_gtk - - let g:test_is_flaky = 1 - let cmd = GetVimCommand() - - if cmd == '' - throw 'GetVimCommand() failed' - endif - call Check_X11_Connection() - - let name = 'VIMTESTSOCKET' - let cmd .= ' --clientserver socket' - let cmd .= ' --servername ' .. name - - let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'}) - - call WaitForAssert({-> assert_equal("run", job_status(job))}) - call WaitForAssert({-> assert_match(name, system(cmd .. ' --serverlist'))}) - - call system(cmd .. " --remote-expr 'execute(\"gui\")'") - - call assert_match('1', system(cmd .. " --remote-expr 'has(\"gui_running\")'")) - call assert_match(name, system(cmd .. ' --remote-expr "v:servername"')) - - call system(cmd .. " --remote-expr 'execute(\"qa!\")'") - try - call WaitForAssert({-> assert_equal("dead", job_status(job))}) - finally - if job_status(job) != 'dead' - call assert_report('Server did not exit') - call job_stop(job, 'kill') + if cmd == '' + throw 'GetVimCommand() failed' endif - endtry -endfunc + call Check_X11_Connection() + + let types = [ + \ ['socket', "channel:2000"], + \ ['x11', "TEST"], + \ ['mswin', "TEST"], + \ ] + + for [type, expected] in types + if (type == 'x11' && (!has('x11') || !empty($WAYLAND_DISPLAY) || empty($DISPLAY)) + \ || (type == 'mswin' && !has('win32'))) + continue + endif + if has('win32') && has('gui_running') + " Windows gVim --remote-expr shows a dialog window, which blocks tests + " from running. Using --gui-dialog-file does not seem to work either. + continue + endif + + let actual_cmd = cmd .. ' --clientserver ' .. type + let actual_cmd ..= ' --servername ' .. expected + let job = job_start(actual_cmd, {'stoponexit': 'kill', 'out_io': 'null'}) + + call WaitForAssert({-> assert_equal("run", job_status(job))}) + call assert_match(expected, system(actual_cmd .. ' --remote-expr "v:servername"')) + + " On Windows using --remote-expr causes E282, possibly due to some shell + " escaping quirk? When gtk gui is running, using system() seems to cause a + " deadlock when using the x11 backend only... don't use it for now... + if has('win32') || has('gui_running') + call job_stop(job, 'kill') + else + call system(actual_cmd .. " --remote-expr 'execute(\"qa!\")'") + endif + try + call WaitForAssert({-> assert_equal("dead", job_status(job))}) + finally + if job_status(job) != 'dead' + call assert_report('Server did not exit') + call job_stop(job, 'kill') + endif + endtry + endfor + endfunc " Test if custom paths work for socketserver -func Test_client_socket_server_custom_path() - CheckNotMSWindows +func Test_client_server_socketserver_custom_path() CheckFeature socketserver - CheckNotFeature x11 + CheckNotMSWindows let g:test_is_flaky = 1 let cmd = GetVimCommand() @@ -347,7 +321,7 @@ func Test_client_socket_server_custom_path() let paths = ['./' .. name, '../testdir/' .. name, getcwd(-1) .. '/' .. name] for path in paths - let actual = cmd .. ' --servername ' .. path + let actual = cmd .. ' --clientserver socket --servername ' .. path let job = job_start(actual, {'stoponexit': 'kill', 'out_io': 'null'}) @@ -366,6 +340,170 @@ func Test_client_socket_server_custom_path() endfor endfunc +" Test if "channel:" prefix works correctly to use channel address for +" socketserver. +func Test_client_server_socketserver_address() + CheckFeature socketserver + + let g:test_is_flaky = 1 + let cmd = GetVimCommand() + + if cmd == '' + throw 'GetVimCommand() failed' + endif + + let actual = cmd .. ' --clientserver socket --servername channel:2000' + + let job = job_start(actual, {'stoponexit': 'kill', 'out_io': 'null'}) + + call WaitForAssert({-> assert_equal("run", job_status(job))}) + + if !has('win32') || !has('gui_running') + " Does not work with gVim on Windows because it shows an OK dialog box which + " blocks tests from running + call assert_match('channel:2000', system(actual .. ' --remote-expr "v:servername"')) + endif + + if has('win32') + call job_stop(job, 'kill') + else + call system(actual .. " --remote-expr 'execute(\"qa!\")'") + endif + try + call WaitForAssert({-> assert_equal("dead", job_status(job))}) + finally + if job_status(job) != 'dead' + call assert_report('Server did not exit') + call job_stop(job, 'kill') + endif + endtry +endfunc + +" Test if --remote-wait works properly with multiple files +func Test_client_server_multiple_remote_wait() + CheckRunVimInTerminal + + call Check_X11_Connection() + + let buf = RunVimInTerminal('--servername TEST', {'rows': 8}) + call TermWait(buf) + + call writefile(["1"], 'XRemoteOne', 'D') + call writefile(["2"], 'XRemoteTwo', 'D') + + let cmd = GetVimCommand() + + if cmd == '' + throw 'GetVimCommand() failed' + endif + + let actual = cmd .. ' -n --servername TEST --remote-wait ./XRemoteOne ./XRemoteTwo' + let job = job_start(actual, {'stoponexit': 'kill', 'out_io': 'null'}) + + sleep 500m " Wait for server to receive request + call assert_equal("run", job_status(job)) + + call term_sendkeys(buf, "\:next\") + call TermWait(buf) + call assert_equal("run", job_status(job)) + + call term_sendkeys(buf, "\:q!\") " Don't use qa! because we only want to quit one file + call WaitForAssert({-> assert_equal("dead", job_status(job))}) +endfunc + +" Check if socket is removed even if Vim changes directory +func Test_client_server_socketserver_chdir() + CheckFeature socketserver + CheckRunVimInTerminal + CheckNotMSWindows + + let buf = RunVimInTerminal('--clientserver socket --servername ./TEST', + \ {'rows': 8}) + call TermWait(buf) + + call term_sendkeys(buf, "\:cd ../\") + call StopVimInTerminal(buf) + + call assert_equal("", glob("./TEST")) +endfunc + +func DummyServerCallback(ch, addr) + let msg = json_encode(#{type: "ver"}) .. "\n" + call ch_sendraw(a:ch, msg) +endfunc + +" Test if commands with different version are ignored and handled properly. +func Test_client_server_socketserver_version_mismatch() + CheckFeature socketserver + CheckRunVimInTerminal + CheckScreendump + + let cmd = GetVimCommand() + + if cmd == '' + throw 'GetVimCommand() failed' + endif + + let buf = RunVimInTerminal('--clientserver socket --servername + \ channel:2000', {'rows': 8}) + call TermWait(buf) + + let ch = ch_open('localhost:2000', #{mode: 'nl'}) + let msg = json_encode(#{ + \ type: "expr", + \ str: "v:servername", + \ version: 999999999 + \ }) .. "\n" + + call ch_sendraw(ch, msg) + let resp = ch_readraw(ch) + + call assert_equal(#{type: "ver"}, json_decode(resp)) + + call StopVimInTerminal(buf) + + let ch = ch_listen("2000", #{ + \ mode: 'nl', + \ callback: function('DummyServerCallback') + \ }) + + let buf = RunVimInTerminal('--clientserver socket --servername channel:3000', {'rows': 8}) + call TermWait(buf) + + call term_sendkeys(buf, "\:echo remote_expr('channel:2000', 'v:servername', '', 1)\") + call TermWait(buf) + + call VerifyScreenDump(buf, 'Test_clientserver_1', #{wait: 3000}) + + call StopVimInTerminal(buf) +endfunc + +" Test if invalid messages do not crash Vim socketserver. +func Test_clientserver_socketserver_invalid_msg() + CheckFeature socketserver + CheckRunVimInTerminal + + let cmd = GetVimCommand() + + if cmd == '' + throw 'GetVimCommand() failed' + endif + + let buf = RunVimInTerminal('--clientserver socket --servername + \ channel:3000', {'rows': 8}) + call TermWait(buf) + + let ch = ch_open('localhost:3000', #{mode: 'nl'}) + + call ch_sendraw(ch, "wjdaljdsjalsj\n") + call ch_sendraw(ch, "{\"type\": \"unknown\"}\n") + + call assert_match("channel:3000", system(cmd .. " --clientserver socket --servername channel:3000 --remote-expr 'v:servername'")) + call assert_equal("running", term_getstatus(buf)) + + call StopVimInTerminal(buf) +endfunc + " Uncomment this line to get a debugging log " call ch_logfile('channellog', 'w') diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 2810e0b7e8..31fb1f8ffc 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -2947,7 +2947,7 @@ func Test_wildmenu_pum() " When the popup is open, entering the cmdline window should close the popup call term_sendkeys(buf, "\sign \\") - call WaitForTermCurPosAndLinesToMatch(buf, [6, (strlen(':sign define') + 1)], g:test_timeout, (rows, '^You discovered the command-line window! You can close it with ":q"\.')) + call WaitForTermCurPosAndLinesToMatch(buf, [6, strlen(':sign define')], g:test_timeout, (rows, '^You discovered the command-line window! You can close it with ":q"\.')) call WaitFor({buf_ -> {-> term_scrape(buf, 6)->slice(1, 5)->filter({_, v -> v.fg == '#af5f00'})->len() == 4}}(buf), g:test_timeout) call VerifyScreenDump(buf, 'Test_wildmenu_pum_22', {}) call term_sendkeys(buf, ":q\") @@ -3190,6 +3190,48 @@ func Test_wildmenu_pum() call StopVimInTerminal(buf) endfunc +" Test that popup_settext() from a CmdlineChanged autocmd updates the +" cmdline-mode info popup without needing an explicit :redraw (#20175). +func Test_wildmenu_pum_info_async_update() + CheckScreendump + CheckRunVimInTerminal + + let lines =<< trim END + vim9script + set completeopt=menuone,popup + set wildmenu wildoptions=pum wildcharm= + augroup Test + au! + au CmdlineChanged : UpdateInfo() + augroup END + + def UpdateInfo() + if getcmdcompltype() != 'customlist,Complete' + return + endif + var id = popup_findinfo() + if id != 0 + id->popup_settext('done') + popup_show(id) + endif + enddef + + def Complete(_, _, _): list> + return [{word: '1', info: 'lazy'}, {word: '2', info: 'lazy'}] + enddef + + command! -nargs=1 -complete=customlist,Complete Test echo + END + call writefile(lines, 'XtestWildmenuInfoAsync', 'D') + let buf = RunVimInTerminal('-S XtestWildmenuInfoAsync', #{rows: 14, cols: 50}) + call term_sendkeys(buf, ":Test \") + call TermWait(buf, 200) + call VerifyScreenDump(buf, 'Test_wildmenu_pum_info_async_update', {}) + + call term_sendkeys(buf, "\") + call StopVimInTerminal(buf) +endfunc + " Test for wildmenumode() with the cmdline popup menu func Test_wildmenumode_with_pum() set wildmenu @@ -4053,6 +4095,27 @@ func Test_fuzzy_completion_cmd_k() set wildoptions& endfunc +" Issue #20241: with 'ignorecase', a lowercase "k"-prefixed input should +" still complete a user command starting with "K". +func Test_cmdline_complete_user_cmd_k_with_ignorecase() + command! Kz echo "hello" + command! Gz echo "here" + + set noignorecase + call assert_equal([], getcompletion('kz', 'cmdline')) + call assert_equal([], getcompletion('gz', 'cmdline')) + call assert_equal(['Kz'], getcompletion('Kz', 'cmdline')) + call assert_equal(['Gz'], getcompletion('Gz', 'cmdline')) + + set ignorecase + call assert_equal(['Kz'], getcompletion('kz', 'cmdline')) + call assert_equal(['Gz'], getcompletion('gz', 'cmdline')) + + set ignorecase& + delcommand Kz + delcommand Gz +endfunc + " Test for fuzzy completion for user defined custom completion function func Test_fuzzy_completion_custom_func() func Tcompl(a, c, p) @@ -4594,6 +4657,149 @@ func Test_custom_completion() delfunc Check_customlist_completion endfunc +" Test that 'customlist' completion accepts dict items with extra info +" (kind/menu/info) for display in the popup menu, and that string items still +" work in the same list. +func Test_customlist_dict_completion() + func DictComp(A, L, P) + return [ + \ {'word': 'apple', 'kind': 'f', 'menu': 'fruit', 'info': 'A red fruit'}, + \ {'word': 'banana', 'kind': 'f', 'menu': 'fruit', 'info': 'A yellow fruit'}, + \ {'word': 'carrot', 'kind': 'v', 'menu': 'vegetable', 'info': 'An orange vegetable'}, + \ 'plain', + \ ] + endfunc + command -nargs=1 -complete=customlist,DictComp DictCmd echo + + " getcompletion() returns only the "word" of each item; string items pass + " through unchanged. + call assert_equal(['apple', 'banana', 'carrot', 'plain'], + \ getcompletion('', 'customlist,DictComp')) + + " Items missing a "word" key are silently skipped. + func DictCompMissingWord(A, L, P) + return [{'kind': 'x'}, {'word': 'ok'}] + endfunc + call assert_equal(['ok'], + \ getcompletion('', 'customlist,DictCompMissingWord')) + + " Tab completion still selects the word. + call feedkeys(":DictCmd a\\\"\", 'xt') + call assert_equal('"DictCmd apple', @:) + + " "abbr" overrides display only; "word" is what gets inserted. + func DictCompAbbr(A, L, P) + return [{'word': 'apple', 'abbr': 'APPLE🍎'}] + endfunc + call assert_equal(['apple'], + \ getcompletion('', 'customlist,DictCompAbbr')) + command -nargs=1 -complete=customlist,DictCompAbbr DictAbbrCmd echo + call feedkeys(":DictAbbrCmd \\\"\", 'xt') + call assert_equal('"DictAbbrCmd apple', @:) + + delcommand DictAbbrCmd + delcommand DictCmd + delfunc DictComp + delfunc DictCompMissingWord + delfunc DictCompAbbr +endfunc + +func Test_customlist_dict_completion_info_popup() + CheckScreendump + + let lines =<< trim END + func DictComp(A, L, P) + return [ + \ {'word': 'apple', 'kind': 'f', 'menu': 'fruit', 'info': 'A red fruit', 'abbr': '🍎'}, + \ {'word': 'banana', 'kind': 'f', 'menu': 'fruit', 'info': 'A yellow fruit', 'abbr': '🍌'}, + \ {'word': 'carrot', 'kind': 'v', 'menu': 'vegetable', 'info': 'An orange vegetable'}, + \ 'plain', + \ ] + endfunc + command -nargs=1 -complete=customlist,DictComp DictCmd echo + set wildmenu wildoptions=pum completeopt=menu,popup + END + call writefile(lines, 'XTest_customlist_info_popup', 'D') + let rows = 12 + let buf = RunVimInTerminal('-S XTest_customlist_info_popup', {'rows': rows}) + + call term_sendkeys(buf, ":DictCmd \") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd apple') + 1)], g:test_timeout, ((rows - 4), 'A red fruit')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_01', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd banana') + 1)], g:test_timeout, ((rows - 3), 'A yellow fruit')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_02', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd carrot') + 1)], g:test_timeout, ((rows - 2), 'An orange vegetable')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_03', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd plain') + 1)], g:test_timeout, ((rows - 1), '^\~\s\+plain\s\+$')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_04', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd ') + 1)], g:test_timeout) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_05', {}) + + call term_sendkeys(buf, "\") + + " Tests for Insert mode i_CTRL-X_CTRL-V + call term_sendkeys(buf, "iDictCmd \\") + call VerifyScreenDump(buf, 'Test_customlist_info_popup_06', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_customlist_info_popup_07', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_customlist_info_popup_08', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_customlist_info_popup_09', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_customlist_info_popup_10', {}) + + " Starting another i_CTRL-X_CTRL-V completion should not leak memory + call term_sendkeys(buf, "\sign un\\") + call VerifyScreenDump(buf, 'Test_customlist_info_popup_11', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_cmdline_complete_findfunc_dict() + CheckScreendump + + let lines =<< trim END + set wildmenu wildoptions=pum completeopt=menu,popup + func FindComplete(cmdarg, cmdcomplete) + return [ + \ 'Xplain', + \ {'word': 'Xfile1', 'kind': 'F', 'menu': 'file', 'info': '1st file'}, + \ {'word': 'Xfile2', 'kind': 'F', 'menu': 'file', 'info': '2nd file'}, + \ {'word': 'Xdir1', 'kind': 'D', 'menu': 'dir', 'info': '1st dir'}, + \ {'word': 'Xdir2', 'kind': 'D', 'menu': 'dir', 'info': '2nd dir'}, + \ ] + endfunc + set findfunc=FindComplete + END + call writefile(lines, 'XTest_compl_findfunc_dict', 'D') + let rows = 12 + let buf = RunVimInTerminal('-S XTest_compl_findfunc_dict', {'rows': rows}) + + call term_sendkeys(buf, ":find \") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':find Xplain') + 1)], g:test_timeout, ((rows - 5), '^\~\s\+Xplain\s\+$')) + call VerifyScreenDump(buf, 'Test_compl_findfunc_dict_01', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':find Xdir1') + 1)], g:test_timeout, ((rows - 2), '1st dir')) + call VerifyScreenDump(buf, 'Test_compl_findfunc_dict_02', {}) + + call term_sendkeys(buf, "\") + call StopVimInTerminal(buf) +endfunc + func Test_custom_completion_with_glob() func TestGlobComplete(A, L, P) return split(glob('Xglob*'), "\n") @@ -5249,6 +5455,32 @@ func Test_wildtrigger_update_screen() call StopVimInTerminal(buf) endfunc +" Wrapped cmdline must not be truncated when wildtrigger() redraws on every +" keystroke. +func Test_wildtrigger_wrapped_cmdline() + CheckScreendump + + let lines =<< trim [SCRIPT] + set wildmenu wildmode=noselect:lastused,full wildoptions=pum + cnoremap =wildtrigger()[-1] + [SCRIPT] + call writefile(lines, 'XTest_wildtrigger_wrap', 'D') + let rows = 8 + let cols = 30 + let buf = RunVimInTerminal('-S XTest_wildtrigger_wrap', {'rows': rows, 'cols': cols}) + + call term_sendkeys(buf, ":e ") + for i in range(40) + call term_sendkeys(buf, "x\") + endfor + + call WaitForTermCurPosAndLinesToMatch(buf, [rows, ((3 + 40) - cols + 1)]) + call VerifyScreenDump(buf, 'Test_wildtrigger_wrapped_cmdline_1', {}) + + call term_sendkeys(buf, "\") + call StopVimInTerminal(buf) +endfunc + " Issue #17969: With 'noselect', the popup menu should appear next to the " environment variable being expanded. Disable 'showtail' when completing " file paths when 'noselect' is present. @@ -5390,4 +5622,147 @@ func Test_breaklist_args_fails() call assert_fails(':breaklist extra', 'E488:') endfunc +func Test_rulerformat_empty() + set ruler rulerformat=%!'%{}%' + try + redraw + catch + endtry + set ruler& + set rulerformat& +endfunc + +func Test_cmdline_complete_with_space() + call mkdir('Xspc', 'R') + let save_cwd = getcwd() + cd Xspc + call writefile([], 'foo bar') + call writefile([], 'baz') + call writefile([], 'bz') + + " This should expand to foo\ bar, not add 3 space separated + " files: foo baz bz + call feedkeys(":badd foo b\\\"\", 'xt') + call assert_equal('"badd foo\ bar', @:) + + call chdir(save_cwd) +endfunc + +func Test_wildmode_noinsert() + command! -nargs=1 -complete=custom,T MyCmd echo + func T(a, c, p) + return "oneA\noneB\noneC" + endfunc + + set wildmenu wildoptions=pum wildmode=noinsert,full wildchar= + call feedkeys(":MyCmd o\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd oneB', @:) + call feedkeys(":MyCmd o\\\\\"\", 'xt') + call assert_equal('"MyCmd oneC', @:) + + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd oneA', @:) + + " CTRL-P from highlighted first item returns to original text + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + " Another CTRL-P wraps to the last match + call feedkeys(":MyCmd o\\\\\"\", 'xt') + call assert_equal('"MyCmd oneC', @:) + + set wildoptions= + call feedkeys(":MyCmd o\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd oneB', @:) + + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd oneA', @:) + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + + " 'nowildmenu' should make 'noinsert' ineffective + set nowildmenu + call feedkeys(":MyCmd o\\\"\", 'xt') + call assert_equal('"MyCmd oneA', @:) + + " 'noselect' takes precedence over 'noinsert' + set wildmenu wildoptions=pum wildmode=noselect:noinsert,full + call feedkeys(":MyCmd o\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd oneA', @:) + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + + set wildmode=noinsert + call feedkeys(":MyCmd o\\\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + + set wildmode=noinsert,full + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd oneB', @:) + call feedkeys(":MyCmd o\\\\"\", 'xt') + call assert_equal('"MyCmd o', @:) + + " 'longest' takes precedence over 'noinsert' + set wildmode=noinsert:longest + call feedkeys(":MyCmd o\\\"\", 'xt') + call assert_equal('"MyCmd one', @:) + + set wildmode& + call feedkeys(":set wildmode=noi\\\"\", 'xt') + call assert_equal('"set wildmode=noinsert', @:) + + set wildmode=noinsert:lastused,full + call assert_equal('noinsert:lastused,full', &wildmode) + call assert_fails('set wildmode=noinser', 'E474:') + + " Single match with 'noinsert': item shown highlighted, C-Y commits + command! -nargs=1 -complete=custom,T1 MyCmd1 echo + func T1(a, c, p) + return "oneA" + endfunc + set wildmenu wildoptions=pum wildmode=noinsert,full + call feedkeys(":MyCmd1 o\\\"\", 'xt') + call assert_equal('"MyCmd1 o', @:) + call feedkeys(":MyCmd1 o\\\\"\", 'xt') + call assert_equal('"MyCmd1 oneA', @:) + delcommand MyCmd1 + delfunc T1 + + set wildmenu& wildoptions& wildmode& wildchar& + delcommand MyCmd + delfunc T +endfunc + +func Test_cmdline_compl_env_var_wildcard() + CheckUnix + + let d = tempname() + call mkdir(d .. '/[x]', 'pR') + call writefile(['hello'], d .. '/[x]/file.txt') + let $XWILD = d .. '/[x]' + + call feedkeys(":e $XWILD/fi\\\"\", 'xt') + call assert_match('\[x\]/file\.txt$', @:) + call assert_equal([d .. '/[x]/file.txt'], glob('$XWILD/*', 0, 1)) + + edit $XWILD/file.txt + call assert_equal('hello', getline(1)) + bwipe! + + if has('profile') + let prof = d .. '/[x]/prof.out' + profile start $XWILD/prof.out + profile stop + call assert_true(filereadable(prof)) + call delete(prof) + endif + + unlet $XWILD +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_cmdmods.vim b/src/testdir/test_cmdmods.vim index 3b0deab7b5..7efe6e3111 100644 --- a/src/testdir/test_cmdmods.vim +++ b/src/testdir/test_cmdmods.vim @@ -50,12 +50,18 @@ def Test_cmdmods_array() enddef def Test_keep_cmdmods_names() - # :k only available in legacy script - legacy call assert_equal('k', fullcommand(':k')) - legacy call assert_equal('k', fullcommand(':ke')) - # single character commands not supported in Vim9 - assert_equal('', fullcommand(':k')) - assert_equal('keepmarks', fullcommand(':ke')) + # :k is only available in legacy Vim script + assert_equal('k', fullcommand(':k', false)) + # many single character commands are not supported in Vim9 script, incl. :k + assert_equal('', fullcommand(':k', true)) + # :k{a-zA-Z'} in legacy Vim script + assert_equal('k', fullcommand(':ka', false)) + assert_equal('', fullcommand(':ka', true)) + # :ke is an exception - it is 'keepmarks', not 'k', in Vim9 script + assert_equal('k', fullcommand(':ke', false)) + assert_equal('keepmarks', fullcommand(':ke', true)) + # :kee* shortenings + assert_equal('keepmarks', fullcommand(':kee', false)) assert_equal('keepmarks', fullcommand(':kee')) assert_equal('keepmarks', fullcommand(':keep')) assert_equal('keepmarks', fullcommand(':keepm')) @@ -63,14 +69,17 @@ def Test_keep_cmdmods_names() assert_equal('keepmarks', fullcommand(':keepmar')) assert_equal('keepmarks', fullcommand(':keepmark')) assert_equal('keepmarks', fullcommand(':keepmarks')) + assert_equal('keepalt', fullcommand(':keepa', false)) assert_equal('keepalt', fullcommand(':keepa')) assert_equal('keepalt', fullcommand(':keepal')) assert_equal('keepalt', fullcommand(':keepalt')) + assert_equal('keepjumps', fullcommand(':keepj', false)) assert_equal('keepjumps', fullcommand(':keepj')) assert_equal('keepjumps', fullcommand(':keepju')) assert_equal('keepjumps', fullcommand(':keepjum')) assert_equal('keepjumps', fullcommand(':keepjump')) assert_equal('keepjumps', fullcommand(':keepjumps')) + assert_equal('keeppatterns', fullcommand(':keepp', false)) assert_equal('keeppatterns', fullcommand(':keepp')) assert_equal('keeppatterns', fullcommand(':keeppa')) assert_equal('keeppatterns', fullcommand(':keeppat')) diff --git a/src/testdir/test_cmdwin.vim b/src/testdir/test_cmdwin.vim index b25862dad7..360dc67bb8 100644 --- a/src/testdir/test_cmdwin.vim +++ b/src/testdir/test_cmdwin.vim @@ -611,4 +611,38 @@ func Test_cmdwin_showcmd() call StopVimInTerminal(buf) endfunc +func Test_cmdwin_cursor_position() + " When the cmdline fills the screen width exactly, pressing CTRL-F to open + " the cmdwin should place the cursor on the last character, not past it. + let cmd = 'echo "' .. repeat('a', &columns - 8) .. '"' + call assert_equal(&columns - 1, len(cmd)) + let g:cmdwin_col = 0 + let g:cmdwin_line = '' + call feedkeys(':' .. cmd .. "\" .. + \ ":let g:cmdwin_col = col('.')\" .. + \ ":let g:cmdwin_line = getline('.')\" .. + \ ":q\", 'x!') + call assert_equal(len(cmd), g:cmdwin_col) + call assert_equal(cmd, g:cmdwin_line) + unlet g:cmdwin_col g:cmdwin_line +endfunc + +func Test_cmdwin_no_prefix_on_wrapped_line() + CheckScreendump + + let lines =<< trim END + augroup vimHints | au! | augroup END + END + call writefile(lines, 'Xcmdwin_wrap', 'D') + + let buf = RunVimInTerminal('-S Xcmdwin_wrap', #{rows: 12, cols: 40}) + let cmd = 'echo "' .. repeat('a', 40 - 8) .. '"XYZ' + call term_sendkeys(buf, ':' .. cmd .. "\") + call TermWait(buf, 100) + call VerifyScreenDump(buf, 'Test_cmdwin_wrap_prefix', {}) + + call term_sendkeys(buf, ":q\") + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_codestyle.vim b/src/testdir/test_codestyle.vim index ed68e3510e..91ca236177 100644 --- a/src/testdir/test_codestyle.vim +++ b/src/testdir/test_codestyle.vim @@ -46,11 +46,21 @@ def Test_source_files() PerformCheck(fname, ';;\+$', 'double semicolon', '') # some files don't stick to the Vim style rules - if fname =~ 'iscygpty.c' + if fname =~ 'iscygpty.c' || fname =~ 'strptime.c' continue endif - var skip = 'getline(".") =~ "condition) {" || getline(".") =~ "vimglob_func" || getline(".") =~ "{\"" || getline(".") =~ "{\\d" || getline(".") =~ "{{{"' + # ignore patterns: + # - condition) { + # - vimglob_func + # - struct initializer: {" + # - numeric initializer: {\d + # - fold marker {{{ + # - compound literals: (\w\+) *{ + + + var skip = 'getline(".") =~ "condition) {" || getline(".") =~ "vimglob_func" || getline(".") =~ "{\"" ||' + skip ..= ' getline(".") =~ "{\\d" || getline(".") =~ "{{{" || getline(".") =~ "(\\w\\+) *{"' PerformCheck(fname, ')\s*{', 'curly after closing paren', skip) # Examples in comments use double quotes. @@ -195,4 +205,27 @@ def Test_indent_of_source_files() endfor enddef +def Test_runtime_wrong_shellescape() + # Check that shellescape() is called with the {special} argument (a second, + # non-zero argument) when its result is used in a ":!" ex command. + # This could cause code injection! + var pattern = '\Xid`', 'D') + call assert_fails('cscope add Xcscope2.out`id>Xid`', 'E609:') + call assert_false(filereadable('Xid')) + cscope kill -1 call CscopeSetupOrClean(0) endfunc diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim index 73169649df..e541da886d 100644 --- a/src/testdir/test_cursor_func.vim +++ b/src/testdir/test_cursor_func.vim @@ -124,7 +124,8 @@ func Test_screenpos() setlocal nonumber display=lastline so=0 exe "normal G\\" redraw - call assert_equal({'row': winrow + wininfo.height - 1, + let winbar_height = get(wininfo, 'winbar', 0) + call assert_equal({'row': winrow + wininfo.height - 1 + winbar_height, \ 'col': wincol + 7, \ 'curscol': wincol + 7, \ 'endcol': wincol + 7}, winid->screenpos(line('$'), 8)) diff --git a/src/testdir/test_digraph.vim b/src/testdir/test_digraph.vim index 96b2b63baf..23d8a83aad 100644 --- a/src/testdir/test_digraph.vim +++ b/src/testdir/test_digraph.vim @@ -510,14 +510,11 @@ func Test_entering_digraph() CheckRunVimInTerminal let buf = RunVimInTerminal('', {'rows': 6}) call term_sendkeys(buf, "i\") - call TermWait(buf) - call assert_equal('?', term_getline(buf, 1)) + call WaitForAssert({-> assert_equal('?', term_getline(buf, 1))}, 1000) call term_sendkeys(buf, "1") - call TermWait(buf) - call assert_equal('1', term_getline(buf, 1)) + call WaitForAssert({-> assert_equal('1', term_getline(buf, 1))}, 1000) call term_sendkeys(buf, "2") - call TermWait(buf) - call assert_equal('ÂŊ', term_getline(buf, 1)) + call WaitForAssert({-> assert_equal('ÂŊ', term_getline(buf, 1))}, 1000) call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_display.vim b/src/testdir/test_display.vim index cbb4f4fc6d..5fee797162 100644 --- a/src/testdir/test_display.vim +++ b/src/testdir/test_display.vim @@ -260,6 +260,7 @@ func Test_display_scroll_update_visual() let buf = RunVimInTerminal('-S XupdateVisual.vim', #{rows: 8, cols: 60}) call term_sendkeys(buf, "VG7kk") + call WaitForAssert({-> assert_match('VISUAL.*\d\+\s\+\d', term_getline(buf, 8))}, 1000) call VerifyScreenDump(buf, 'Test_display_scroll_update_visual', {}) call StopVimInTerminal(buf) diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim index 4b2d476429..f3085e42b0 100644 --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -2073,6 +2073,7 @@ func Test_edit_ctrl_r_failed() " trying to insert a blob produces an error call term_sendkeys(buf, "i\=0z\") + call WaitForAssert({-> assert_match('^E976:', term_getline(buf, 5))}, 1000) " ending Insert mode should put the cursor back on the ':' call term_sendkeys(buf, ":\") @@ -2460,4 +2461,60 @@ func Test_edit_CAR_with_completion() bw! endfunc +func Test_autoindent_no_strip_after_cmd_setline() + new + setlocal autoindent + inoremap call setline('.', 'v v')call cursor(line('.'), 2) + call feedkeys("Go\\", 'tx') + call assert_equal('v v', getline(2)) + bwipe! +endfunc + +func Test_autoindent_no_strip_after_cursorholdi() + CheckFeature timers + new + setlocal autoindent + set updatetime=50 + au CursorHoldI call setline('.', 'v v') + call setline(1, ' x') + call cursor(1, 2) + call timer_start(120, {-> feedkeys("\", 't')}) + call feedkeys("o", 'tx!') + call assert_equal('v v', getline(2)) + set updatetime& + bwipe! +endfunc + +" Issue #20130: '[ must mark the start of the paste after CTRL-R CTRL-P + edit. +func Test_open_square_mark_after_ctrl_r_ctrl_p_paste() + new + call setline(1, ['a', 'b', 'c', 'd']) + call cursor(4, 1) + + call feedkeys("Vggyjo\\\"\\", 'xt') + + call assert_equal(['a', 'b', 'a', 'b', 'c', 'd', 'c', 'd'], + \ getline(1, '$')) + call assert_equal([0, 3, 1, 0], getpos("'[")) + bwipe! +endfunc + +func Test_autoindent_no_strip_cross_line() + new + setlocal autoindent + inoremap {}normal! == + + call setline(1, '') + call feedkeys("i\\", 'tx') + + call assert_equal('{', getline(1)) + call assert_equal('', getline(2)) + call assert_equal('}', getline(3)) + call assert_equal([0, 2, 1, 0], getpos('.')) + + " Overwrite @. register with simple content to avoid affecting later tests. + call feedkeys("Go\", 'tnix') + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim index 39b1227aef..e1afbfbe2c 100644 --- a/src/testdir/test_eval_stuff.vim +++ b/src/testdir/test_eval_stuff.vim @@ -765,7 +765,10 @@ func s:Paste(reg) else return ("c", []) endif + endif + if exists("g:vim_paste_recursive") + call getreg(a:reg) endif endfunc @@ -773,6 +776,9 @@ func s:Copy(reg, type, lines) if exists("g:vim_copy_count") let g:vim_copy_count[a:reg] += 1 endif + if exists("g:vim_copy_recursive") + call setreg(a:reg, a:lines) + endif let g:vim_copy = { \ "reg": a:reg, @@ -1127,6 +1133,52 @@ func Test_clipboard_provider_accessed_once() bw! + new + " Emitting TextPutPre/TextPutPost/TextYankPost may cause a clipboard access + " + " Note that TextPutPost will always cause a second clipboard access, since a + " TextPutPre may have changed the clipboard, meaning another "paste" call is + " needed to make sure everything is up to date. + augroup TextAutocmd + autocmd! + autocmd TextPutPost * let g:putpost = 1 + autocmd TextPutPre * let g:putpre = 1 + autocmd TextYankPost * let g:yankpost = 1 + augroup END + + let g:putpost = 0 + let g:putpre = 0 + let g:yankpost = 0 + + let g:vim_paste_count = {'*': 0, '+': 0} + let g:vim_copy_count = {'*': 0, '+': 0} + + call setline(1, "hello world!") + + yank + + + yank * + + put + + + put * + + call assert_equal(2, g:vim_paste_count['+']) + call assert_equal(1, g:vim_copy_count['+']) + + call assert_equal(2, g:vim_paste_count['*']) + call assert_equal(1, g:vim_copy_count['*']) + + call assert_equal(1, g:putpost) + call assert_equal(1, g:putpre) + call assert_equal(1, g:yankpost) + + bw! + unlet g:putpost + unlet g:putpre + unlet g:yankpost + autocmd! TextAutocmd + set clipmethod& set clipboard& endfunc @@ -1303,4 +1355,34 @@ func Test_clipboard_provider_clipboard_option() set clipboard& endfunc +" Test that callback aren't called recursively +func Test_clipboard_provider_recursive() + let v:clipproviders["test"] = { + \ "paste": { + \ '+': function("s:Paste"), + \ '*': function("s:Paste") + \ }, + \ "copy": { + \ '+': function("s:Copy"), + \ '*': function("s:Copy") + \ } + \ } + set clipmethod=test + + let g:vim_paste = "count" + let g:vim_paste_count = {'*': 0, '+': 0} + let g:vim_copy_count = {'*': 0, '+': 0} + let g:vim_paste_recursive = 1 + let g:vim_copy_recursive = 1 + + call getreg('+') + call assert_equal(1, g:vim_paste_count['+']) + call setreg('+', 'test') + call assert_equal(1, g:vim_copy_count['+']) + + set clipmethod& + unlet g:vim_paste_recursive + unlet g:vim_copy_recursive +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim index c671adfe94..0de0771f78 100644 --- a/src/testdir/test_excmd.vim +++ b/src/testdir/test_excmd.vim @@ -61,7 +61,7 @@ func Test_copy() exe "normal! gg4:yank\" call assert_equal("L1\nL2\nL1\nL2\n", @") - close! + bw! endfunc " Test for the :file command @@ -105,7 +105,7 @@ func Test_drop_cmd() call assert_equal(1, winnr('$')) " Check for setting the argument list call assert_equal(['Xdropfile'], argv()) - enew | only! + enew | only! | bw! Xdropfile endfunc " Test for the :append command @@ -133,7 +133,7 @@ func Test_append_cmd() call assert_equal([' L1', ' L2', ' L3'], getline(1, '$')) call assert_true(&autoindent) set autoindent& - close! + bw! endfunc func Test_append_cmd_empty_buf() @@ -181,7 +181,7 @@ func Test_insert_cmd() call assert_equal([' L2', ' L3', ' L1'], getline(1, '$')) call assert_true(&autoindent) set autoindent& - close! + bw! endfunc func Test_insert_cmd_empty_buf() @@ -229,7 +229,7 @@ func Test_change_cmd() call assert_equal([' L4', ' L5', 'L2', 'L3'], getline(1, '$')) call assert_true(&autoindent) set autoindent& - close! + bw! endfunc " Test for the :language command @@ -537,14 +537,14 @@ func Test_read_cmd() edit Xcmdfile read call assert_equal(['one', 'one'], getline(1, '$')) - close! + bw! new read Xcmdfile call assert_equal(['', 'one'], getline(1, '$')) call deletebufline('', 1, '$') call feedkeys("Qr Xcmdfile\visual\", 'xt') call assert_equal(['one'], getline(1, '$')) - close! + bw! endfunc " Test for running Ex commands when text is locked. @@ -611,7 +611,7 @@ func Test_excmd_delete() call assert_equal([' bar'], split(execute('deletp'), "\n")) call setline(1, ['foo', "\tbar"]) call assert_equal([' bar'], split(execute('deletep'), "\n")) - close! + bw! endfunc " Test for commands that are blocked in a sandbox @@ -673,6 +673,13 @@ func Sandbox_tests() if has('unix') call assert_fails('cd `pwd`', 'E48:') endif + call assert_fails("call echoraw('test')", 'E48:') + call assert_fails("echoconsole 'test'", 'E48:') + call assert_fails("call readfile('Xsomefile')", 'E48:') + call assert_fails("call readblob('Xsomefile')", 'E48:') + call assert_fails("call readdir('.')", 'E48:') + call assert_fails("call readdirex('.')", 'E48:') + call assert_fails("call chdir('.')", 'E48:') " some options cannot be changed in a sandbox call assert_fails('set exrc', 'E48:') call assert_fails('set cdpath', 'E48:') diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index 6bd96aed3a..9dd8767fba 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -138,7 +138,7 @@ def s:GetFilenameChecks(): dict> bass: ['file.bass'], bc: ['file.bc'], bdf: ['file.bdf'], - beancount: ['file.beancount'], + beancount: ['file.beancount', 'file.bean'], bib: ['file.bib'], bicep: ['file.bicep'], bicep-params: ['file.bicepparam'], @@ -327,6 +327,9 @@ def s:GetFilenameChecks(): dict> gedcom: ['file.ged', 'lltxxxxx.txt', '/tmp/lltmp', '/tmp/lltmp-file', 'any/tmp/lltmp', 'any/tmp/lltmp-file'], gel: ['file.gel'], gemtext: ['file.gmi', 'file.gemini'], + ghostty: ['ghostty/config', 'ghostty/keymaps.ghostty', '/.config/ghostty/config', '/.config/ghostty/keymaps.ghostty', + '~/Library/Application Support/com.mitchellh.ghostty/config.ghostty', '~/Library/Application Support/com.mitchellh.ghostty/config', + '~/.config/ghostty/themes/Custom Theme', '/usr/share/ghostty/themes/Builtin Theme'], gift: ['file.gift'], 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'], @@ -431,6 +434,7 @@ def s:GetFilenameChecks(): dict> julia: ['file.jl'], just: ['justfile', 'Justfile', '.justfile', 'config.just'], karel: ['file.kl', 'file.KL'], + kawasaki_as: ['file.pg'], kconfig: ['Kconfig', 'Kconfig.debug', 'Kconfig.file', 'Config.in', 'Config.in.host'], kdl: ['file.kdl'], kerml: ['file.kerml'], @@ -634,7 +638,7 @@ def s:GetFilenameChecks(): dict> pilrc: ['file.rcp'], pine: ['.pinerc', 'pinerc', '.pinercex', 'pinercex'], pinfo: ['/etc/pinforc', '/.pinforc', 'any/.pinforc', 'any/etc/pinforc'], - pkl: ['file.pkl', 'file.pcf'], + pkl: ['file.pkl', 'file.pcf', 'any/PklProject'], pli: ['file.pli', 'file.pl1'], plm: ['file.plm', 'file.p36', 'file.pac'], plp: ['file.plp'], @@ -737,6 +741,7 @@ def s:GetFilenameChecks(): dict> services: ['/etc/services', 'any/etc/services'], setserial: ['/etc/serial.conf', 'any/etc/serial.conf'], sexplib: ['file.sexp'], + sgf: ['file.sgf'], 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', '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', @@ -901,6 +906,7 @@ def s:GetFilenameChecks(): dict> tla: ['file.tla'], tli: ['file.tli'], tmux: ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf', 'tmux.conf.local'], + tolk: ['file.tolk'], toml: ['file.toml', 'uv.lock', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config', '.black', 'any/containers/containers.conf', 'any/containers/containers.conf.d/file.conf', 'any/containers/containers.conf.modules/file.conf', 'any/containers/containers.conf.modules/any/file.conf', @@ -981,7 +987,7 @@ def s:GetFilenameChecks(): dict> xml: ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.fsproj', 'file.fsproj.user', 'file.vbproj', 'file.vbproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu', 'file.atom', 'file.rss', 'file.cdxml', 'file.psc1', 'file.mpd', 'fonts.conf', 'file.xcu', 'file.xlb', 'file.xlc', 'file.xba', 'file.xpr', - 'file.xpfm', 'file.spfm', 'file.bxml', 'file.mmi', 'file.slnx', 'Directory.Packages.props', 'Directory.Build.targets', 'Directory.Build.props'], + 'file.xpfm', 'file.spfm', 'file.bxml', 'file.mmi', 'file.slnx', 'Directory.Packages.props', 'Directory.Build.targets', 'Directory.Build.props', 'file.reanim'], xmodmap: ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'], xpm: ['file.xpm'], xpm2: ['file.xpm2'], @@ -991,7 +997,7 @@ def s:GetFilenameChecks(): dict> xslt: ['file.xsl', 'file.xslt'], yacc: ['file.yy', 'file.yxx', 'file.y++'], yaml: ['file.yaml', 'file.yml', 'file.eyaml', 'file.kyaml', 'file.kyml', 'any/.bundle/config', '.clangd', '.clang-format', '.clang-tidy', 'file.mplstyle', 'matplotlibrc', 'yarn.lock', - '/home/user/.kube/config', '/home/user/.kube/kuberc', '.condarc', 'condarc', '.mambarc', 'mambarc', 'pixi.lock'], + '/home/user/.kube/config', '/home/user/.kube/kuberc', '.condarc', 'condarc', '.mambarc', 'mambarc', 'pixi.lock', 'buf.lock', 'file.ksy'], yang: ['file.yang'], yara: ['file.yara', 'file.yar'], yuck: ['file.yuck'], @@ -1084,7 +1090,10 @@ def s:GetScriptChecks(): dict>> ['#!/path/bash2'], ['#!/path/dash'], ['#!/path/ksh'], - ['#!/path/ksh93']], + ['#!/path/ksh93'], + ['#!/path/ash'], + ['#!/path/busybox ash'], + ['#!/path/busybox sh']], csh: [['#!/path/csh']], tcsh: [['#!/path/tcsh']], zsh: [['#!/path/zsh']], @@ -1108,7 +1117,8 @@ def s:GetScriptChecks(): dict>> php: [['#!/path/php']], python: [['#!/path/python'], ['#!/path/python2'], - ['#!/path/python3']], + ['#!/path/python3'], + ['#!/usr/bin/env -S uv run --script']], groovy: [['#!/path/groovy']], ruby: [['#!/path/ruby']], javascript: [['#!/path/node'], @@ -1884,6 +1894,27 @@ func Test_html_file() call assert_equal('htmlangular', &filetype) bwipe! + " HTML Angular ng-template element + let content = ['{{ foo }}'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('htmlangular', &filetype) + bwipe! + + " HTML Angular ng-content element + let content = ['
'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('htmlangular', &filetype) + bwipe! + + " Word containing 'ng-template' as a suffix must not trigger htmlangular + let content = ['
', '

Not Angular

', '
'] + call writefile(content, 'Xfile.html', 'D') + split Xfile.html + call assert_equal('html', &filetype) + bwipe! + " Django Template let content = ['{% if foobar %}', \ '
    ', @@ -2064,6 +2095,37 @@ func Test_m4_file() endtry endfunc +func Test_mm_file() + filetype on + + call writefile(['#import "test.h"'], 'Xfile.mm', 'D') + split Xfile.mm + call assert_equal('objcpp', &filetype) + bwipe! + + call writefile(['// Objective-C++ line comment'], 'Xfile.mm', 'D') + split Xfile.mm + call assert_equal('objcpp', &filetype) + bwipe! + + call writefile(['.TH VIM 1 "YYYY Mth DD"'], 'Xfile.mm', 'D') + split Xfile.mm + call assert_equal('nroff', &filetype) + bwipe! + + try + let g:filetype_mm = 'objcpp' + call writefile(['.TH VIM 1 "YYYY Mth DD"'], 'Xfile_override.mm', 'D') + split Xfile_override.mm + call assert_equal('objcpp', &filetype) + bwipe! + finally + unlet! g:filetype_mm + endtry + + filetype off +endfunc + func Test_mod_file() filetype on @@ -2775,11 +2837,17 @@ endfunc func Test_inc_file() filetype on + " pov call writefile(['this is the fallback'], 'Xfile.inc', 'D') split Xfile.inc call assert_equal('pov', &filetype) bwipe! + call writefile(['!Comment with formular a = b/c'], 'Xfile.inc') + split Xfile.inc + call assert_equal('pov', &filetype) + bwipe! + " ObjectScript routine call writefile(['ROUTINE Sample [Type=INC]'], 'Xfile.inc', 'D') split Xfile.inc @@ -2832,6 +2900,11 @@ func Test_inc_file() call assert_equal('bitbake', &filetype) bwipe! + call writefile(['MACHINE ?= "qemu"'], 'Xfile.inc') + split Xfile.inc + call assert_equal('bitbake', &filetype) + bwipe! + call writefile(['MACHINE ??= "qemu"'], 'Xfile.inc') split Xfile.inc call assert_equal('bitbake', &filetype) @@ -2852,6 +2925,16 @@ func Test_inc_file() call assert_equal('bitbake', &filetype) bwipe! + call writefile(['FOO_BAR[baz] = "foobar"'], 'Xfile.inc') + split Xfile.inc + call assert_equal('bitbake', &filetype) + bwipe! + + call writefile(['FOO_BAR_foo/bar[baz/bazzer] = "foobar"'], 'Xfile.inc') + split Xfile.inc + call assert_equal('bitbake', &filetype) + bwipe! + call writefile(['MACHINEOVERRIDES =. "qemuall:"'], 'Xfile.inc') split Xfile.inc call assert_equal('bitbake', &filetype) @@ -3432,4 +3515,49 @@ func Test_app_file() filetype off endfunc +func Test_cucumber_code_injection() + CheckFeature ruby + filetype plugin on + + call mkdir('Xcucu/features/step_definitions', 'pR') + call writefile([ + \ 'Feature: demo', + \ ' Scenario: trigger', + \ ' Given xyzzy', + \ ], 'Xcucu/features/test.feature') + let marker = getcwd() . '/Xcucu/MARKER' + " Malicious step: terminates the regex literal, injects Ruby system(), + " comments the trailing slash. With the fix, the pattern is passed to + " Regexp.new() instead of Kernel.eval() and the payload is inert. + call writefile([ + \ 'Given /xyzzy/; system("touch ' . marker . '"); #/ do', + \ 'end', + \ ], 'Xcucu/features/step_definitions/poc.rb') + + new Xcucu/features/test.feature + call assert_equal('cucumber', &filetype) + call cursor(3, 1) + " Triggers s:jump -> s:steps -> s:stepmatch on every discovered step, + " including the malicious one. Suppress preview and error messages. + silent! normal [d + call assert_false(filereadable(marker), 'Ruby injection executed') + bwipe! + filetype plugin off +endfunc + +func Test_as_file() + filetype on + + call writefile([], 'Xfile.as', 'D') + split Xfile.as + call assert_equal('atlas', &filetype) + bwipe! + call writefile(['', '.NETCONF 192.168.1.11,"TIMESYS-",255.255.255.0,192.168.0.1,0.0.0.0,0.0.0.0," "'], 'Xfile.as', 'D') + split Xfile.as + call assert_equal('kawasaki_as', &filetype) + bwipe! + + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_find_complete.vim b/src/testdir/test_find_complete.vim index 079fb78043..db1860dc40 100644 --- a/src/testdir/test_find_complete.vim +++ b/src/testdir/test_find_complete.vim @@ -161,4 +161,28 @@ func Test_find_complete() set path& endfunc +" Verify that backticks in 'path' are not executed +func Test_find_completion_backtick_in_path() + CheckUnix + CheckExecutable id + set nomodelinestrict modeline + + let lines =<< trim END + // vim: set path+=`id>Xrce_marker` : + END + + call writefile(lines, 'Xpoc.c', 'D') + new Xpoc.c + call assert_match('`id>Xrce_marker`', &path) + " Triggering completion must not execute the backtick command. + call getcompletion('', 'file_in_path') + call assert_false(filereadable('Xrce_marker')) + call feedkeys(":find \t\n", "xt") + call assert_false(filereadable('Xrce_marker')) + + bwipe! + call delete('Xrce_marker') + set modelinestrict& modeline& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_findfile.vim b/src/testdir/test_findfile.vim index 42c3fb6431..a5f1f6fdd4 100644 --- a/src/testdir/test_findfile.vim +++ b/src/testdir/test_findfile.vim @@ -329,22 +329,22 @@ func Test_findfunc() set findfunc=FindFuncBasic find Xfindfunc3 - call assert_match('Xfindfunc3.c', @%) + call assert_match('Xfindfunc3\.c', @%) bw! 2find Xfind - call assert_match('Xfindfunc2.c', @%) + call assert_match('Xfindfunc2\.c', @%) bw! call assert_fails('4find Xfind', 'E347: No more file "Xfind" found in path') call assert_fails('find foobar', 'E345: Can''t find file "foobar" in path') sfind Xfindfunc2.c - call assert_match('Xfindfunc2.c', @%) + call assert_match('Xfindfunc2\.c', @%) call assert_equal(2, winnr('$')) %bw! call assert_fails('sfind foobar', 'E345: Can''t find file "foobar" in path') tabfind Xfindfunc3.c - call assert_match('Xfindfunc3.c', @%) + call assert_match('Xfindfunc3\.c', @%) call assert_equal(2, tabpagenr()) %bw! call assert_fails('tabfind foobar', 'E345: Can''t find file "foobar" in path') @@ -352,12 +352,44 @@ func Test_findfunc() " Test garbage collection call test_garbagecollect_now() find Xfindfunc2 - call assert_match('Xfindfunc2.c', @%) + call assert_match('Xfindfunc2\.c', @%) bw! delfunc FindFuncBasic call test_garbagecollect_now() call assert_fails('find Xfindfunc2', 'E117: Unknown function: FindFuncBasic') + " 'findfunc' with dicts in the returned list + func FindFuncDict(pat, cmdcomplete) + return [ + \ #{word: 'Xfindfunc1.c', abbr: 'Xff1.c'}, + \ #{word: 'Xfindfunc2.c'}, + \ 'Xfindfunc3.c', + "\ invalid values + \ #{abbr: 'XXX'}, + \ test_null_dict(), + \ test_null_string(), + \ ] + endfunc + + set findfunc=FindFuncDict + find Xfind + call assert_match('Xfindfunc1\.c', @%) + bw! + 2find Xfind + call assert_match('Xfindfunc2\.c', @%) + bw! + 3find Xfind + call assert_match('Xfindfunc3\.c', @%) + bw! + " These invalid values should not crash + 4find Xfind + 5find Xfind + 6find Xfind + call assert_fails('7find Xfind', 'E347: No more file "Xfind" found in path') + call assert_equal('', @%) + %bw! + delfunc FindFuncDict + " Buffer-local option func GlobalFindFunc(pat, cmdcomplete) return ['global'] diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim index c377a95737..d4b3a5093b 100644 --- a/src/testdir/test_fold.vim +++ b/src/testdir/test_fold.vim @@ -1766,7 +1766,7 @@ func Test_foldtext_in_modeline() bw! endfunc - set modeline modelineexpr + set modeline modelineexpr nomodelinestrict call Check_foldtext_in_modeline('setlocal') call Check_foldtext_in_modeline('set') @@ -1792,7 +1792,7 @@ func Test_foldtext_in_modeline() call assert_equal(['after'], readfile('Xmodelinefoldtext_write')) bwipe! - set modeline& modelineexpr& + set modeline& modelineexpr& modelinestrict& delfunc ModelineFoldText delfunc Check_foldtext_in_modeline endfunc @@ -1849,7 +1849,7 @@ func Test_foldexpr_in_modeline() bw! endfunc - set modeline modelineexpr + set modeline modelineexpr nomodelinestrict call Check_foldexpr_in_modeline('setlocal') call Check_foldexpr_in_modeline('set') @@ -1875,7 +1875,7 @@ func Test_foldexpr_in_modeline() call assert_equal(['after'], readfile('Xmodelinefoldexpr_write')) bwipe! - set modeline& modelineexpr& + set modeline& modelineexpr& modelinestrict& delfunc ModelineFoldExpr delfunc Check_foldexpr_in_modeline endfunc diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index 9c090b267d..6b1761bc85 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -328,9 +328,12 @@ func Test_strptime() call assert_equal(1484653763, strptime('%Y-%m-%d %T', '2017-01-17 11:49:23')) - " Force DST and check that it's considered - let $TZ = 'WINTER0SUMMER,J1,J365' - call assert_equal(1484653763 - 3600, strptime('%Y-%m-%d %T', '2017-01-17 11:49:23')) + " Force DST and check that it's considered. + " MS-Windows CRT tzset() does not parse POSIX TZ strings with DST rules. + if !has('win32') + let $TZ = 'WINTER0SUMMER,J1,J365' + call assert_equal(1484653763 - 3600, strptime('%Y-%m-%d %T', '2017-01-17 11:49:23')) + endif call assert_fails('call strptime()', 'E119:') call assert_fails('call strptime("xxx")', 'E119:') @@ -4652,4 +4655,41 @@ func Test_uriencoding() call v9.CheckLegacyAndVim9Success(lines) endfunc +" Note: legacy func, not vim9 def, to avoid the test file being vim9script +func Test_vim9_def_fc_sandbox() + sandbox def! g:Bad() + system('echo unsafe') + enddef + + call assert_fails('call g:Bad()', 'E48:') + delfunction g:Bad +endfunc + +func Test_vim9_def_call_dfunc_fc_sandbox() + " Inner has FC_SANDBOX, outer does not. + " Calling outer goes through call_dfunc into inner, exercising + " the sandbox handling in call_dfunc and func_return. + sandbox def! g:Inner() + system('echo unsafe') + enddef + + def! g:Outer() + g:Inner() + enddef + + call assert_fails('call g:Outer()', 'E48:') + delfunction g:Inner + delfunction g:Outer +endfunc + +" Deferred body inside a sandboxed def function must still run sandboxed. +func Test_vim9_def_defer_fc_sandbox() + sandbox def! g:BadDefer() + defer system('echo unsafe') + enddef + + call assert_fails('call g:BadDefer()', 'E48:') + delfunction g:BadDefer +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim index 468fa5daff..8f59358611 100644 --- a/src/testdir/test_gui.vim +++ b/src/testdir/test_gui.vim @@ -1961,4 +1961,82 @@ func Test_guioptions_clipboard() let &guioptions = save_guioptions endfunc +" Tests for GUI window geometry: initial size from -geometry option and +" size stability after :tabnew / :tabclose. +" +" Background: on GTK3 with client-side decorations (Wayland), the window +" compositor subtracts the CSD frame from the requested size, causing the +" window to open a few pixels too small (wrong &columns/&lines) and to shrink +" further with each :tabnew/:tabclose cycle. + +" Test that a GUI window opened with -geometry=WxH has exactly W columns +" and H lines. +" +" Without the CSD fix, on GTK3/Wayland the compositor subtracts the frame +" margin from the requested pixel size, so the window is a character cell too +" narrow and too short. +func Test_geometry_exact_size() + CheckCanRunGui + CheckFeature gui_gtk + + let after =<< trim [CODE] + call writefile([string(&columns), string(&lines)], 'Xtest_geomsize') + qall + [CODE] + + " Hide the menu bar so it does not widen the minimum window size. + if RunVim(['set guioptions-=m'], after, '-f -g -geometry 40x15') + let result = readfile('Xtest_geomsize') + call assert_equal('40', result[0], 'columns should match -geometry width') + call assert_equal('15', result[1], 'lines should match -geometry height') + endif + + call delete('Xtest_geomsize') +endfunc + +" Test that the window size is unchanged after opening and closing a tab. +" +" Each :tabnew/:tabclose cycle triggers a tabline show/hide, which causes +" asynchronous GTK layout events. Without the fix, stale configure events +" from these layout passes are mis-interpreted as user resizes, reducing +" &columns and &lines with every cycle. Three cycles are performed to +" amplify any drift. +func Test_tabnew_tabclose_size_stable() + CheckCanRunGui + CheckFeature gui_gtk + + let after =<< trim [CODE] + let cols0 = &columns + let rows0 = &lines + tabnew + sleep 300m + tabclose + sleep 300m + tabnew + sleep 300m + tabclose + sleep 300m + tabnew + sleep 300m + tabclose + sleep 300m + call writefile([string(cols0), string(rows0), string(&columns), string(&lines)], 'Xtest_tabsize') + qall + [CODE] + + if RunVim(['set guioptions-=m'], after, '-f -g -geometry 40x15') + let result = readfile('Xtest_tabsize') + call assert_equal('40', result[0], 'initial columns should match -geometry width') + call assert_equal('15', result[1], 'initial lines should match -geometry height') + call assert_equal(result[0], result[2], + \ 'columns changed after 3x tabnew/tabclose: ' + \ .. result[0] .. ' -> ' .. result[2]) + call assert_equal(result[1], result[3], + \ 'lines changed after 3x tabnew/tabclose: ' + \ .. result[1] .. ' -> ' .. result[3]) + endif + + call delete('Xtest_tabsize') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim index 6b45e8ea82..36aee04f9d 100644 --- a/src/testdir/test_highlight.vim +++ b/src/testdir/test_highlight.vim @@ -765,6 +765,7 @@ func Test_visual_sbr() let buf = RunVimInTerminal('-S Xtest_visual_sbr', {'rows': 6,'columns': 60}) call term_sendkeys(buf, "v$") + call WaitForAssert({-> assert_match('VISUAL.*\d\+\s\+\d', term_getline(buf, 6))}, 1000) call VerifyScreenDump(buf, 'Test_visual_sbr_1', {}) " clean up @@ -820,6 +821,8 @@ endfunc " Test for 'highlight' option func Test_highlight_opt() let save_hl = &highlight + " "K" is intentionally an unused 'highlight' flag character; if you add a + " new HLF_ entry, pick a different letter or update this test. call assert_fails('set highlight=K:b', 'E474:') set highlight=f\ r call assert_equal('f r', &highlight) @@ -1621,7 +1624,7 @@ func Test_winhighlight_popupwin() hi B ctermbg=blue ctermfg=white redraw! # Remove intro message - win_execute(g:id, "set filetype=c whl=Pmenu:A,cType:B") + win_execute(g:id, "set filetype=c whl=Popup:A,PopupBorder:A,cType:B") END call writefile(lines, 'Xtest_winhighlight_popupwin', 'D') @@ -1680,4 +1683,93 @@ func Test_winhighlight_occasion() call StopVimInTerminal(buf) endfunc +func Test_VertSplitNC() + CheckScreendump + + let lines =<< trim END + hi StatusLine ctermfg=White ctermbg=DarkBlue cterm=NONE + hi StatusLineNC ctermfg=Black ctermbg=Gray cterm=NONE + hi VertSplit ctermfg=Green ctermbg=NONE cterm=NONE + hi VertSplitNC ctermfg=DarkGray ctermbg=NONE cterm=NONE + call setline(1, repeat(['VertSplitNC test'], 20)) + vsplit + vsplit + END + call writefile(lines, 'Xtest_vertsplitNC', 'D') + + let buf = RunVimInTerminal('-S Xtest_vertsplitNC', {'rows': 12}) + call TermWait(buf) + + " Left window is current: left separator is VertSplit, right is VertSplitNC + call VerifyScreenDump(buf, 'Test_VertSplitNC_1', {}) + + " Move to middle window: both separators should be VertSplit + call term_sendkeys(buf, "\l") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_VertSplitNC_2', {}) + + " Move to right window: right separator is VertSplitNC, left is VertSplit + call term_sendkeys(buf, "\l") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_VertSplitNC_3', {}) + + call StopVimInTerminal(buf) +endfunc + +" Test that 'winhighlight' of window left of separator does not apply when +" drawing the window to the right of the separator. +func Test_VertSplitNC_winhighlight() + CheckScreendump + + let lines =<< trim END + vsplit + set winhighlight=StatusLine:ErrorMsg + END + call writefile(lines, 'Xtest_vertsplitNC_winhighlight', 'D') + + let buf = RunVimInTerminal('-S Xtest_vertsplitNC_winhighlight', {'rows': 12}) + call TermWait(buf) + + call VerifyScreenDump(buf, 'Test_VertSplitNC_whl1', {}) + + call term_sendkeys(buf, "\\") " Go to window with empty winhighlight + call TermWait(buf) + + call VerifyScreenDump(buf, 'Test_VertSplitNC_whl2', {}) + + call StopVimInTerminal(buf) +endfunc + +" Test that VertSplit (not VertSplitNC) is used for the separator rows +" adjacent to a window with a winbar. +func Test_VertSplitNC_winbar() + CheckScreendump + + let lines =<< trim END + hi StatusLine ctermfg=White ctermbg=DarkBlue cterm=NONE + hi StatusLineNC ctermfg=Black ctermbg=Gray cterm=NONE + hi VertSplit ctermfg=Green ctermbg=NONE cterm=NONE + hi VertSplitNC ctermfg=DarkGray ctermbg=NONE cterm=NONE + call setline(1, repeat(['winbar test'], 20)) + vsplit + wincmd w + nnoremenu 1.10 WinBar.Item :echo 'test' + END + call writefile(lines, 'Xtest_vertsplitNC_winbar', 'D') + + let buf = RunVimInTerminal('-S Xtest_vertsplitNC_winbar', {'rows': 12}) + call TermWait(buf) + + " Right window (with winbar) is current: the separator should use + " VertSplit for all rows including the winbar row. + call VerifyScreenDump(buf, 'Test_VertSplitNC_winbar_1', {}) + + " Move to left window: the separator should use VertSplitNC. + call term_sendkeys(buf, "\h") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_VertSplitNC_winbar_2', {}) + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_indent.vim b/src/testdir/test_indent.vim index 52d7be1390..c19be6328e 100644 --- a/src/testdir/test_indent.vim +++ b/src/testdir/test_indent.vim @@ -29,7 +29,7 @@ func Test_preserveindent() call assert_equal("\t \t l", getline(1)) set sw& et& pi& - close! + bw! endfunc " Test for indent() @@ -42,7 +42,7 @@ func Test_indent_func() call assert_equal(4, indent(1)) call setline(1, " \t abc") call assert_equal(12, indent(1)) - close! + bw! endfunc " Test for reindenting a line using the '=' operator @@ -56,7 +56,7 @@ func Test_reindent() call setline(1, ['foo', 'bar']) call feedkeys('ggVG=', 'xt') call assert_equal(['foo', 'bar'], getline(1, 2)) - close! + bw! endfunc " Test indent operator creating one undo entry @@ -103,7 +103,7 @@ func Test_preproc_indent() call assert_equal('#define FOO 1', getline(1)) set cindent& - close! + bw! endfunc func Test_userlabel_indent() @@ -116,7 +116,7 @@ func Test_userlabel_indent() normal GV= call assert_equal('läbÊl:', getline(2)) - close! + bw! endfunc " Test that struct members are aligned @@ -141,7 +141,7 @@ func Test_struct_indent() call setline(1, 'return (struct a) {') normal gg=G call assert_equal(getline(2), getline(3)) - close! + bw! endfunc " Test for 'copyindent' @@ -156,7 +156,7 @@ func Test_copyindent() call feedkeys("ol", 'xt') call assert_equal(" \t l", getline(2)) set sw& ai& et& ci& - close! + bw! endfunc " Test for changing multiple lines with lisp indent @@ -166,7 +166,7 @@ func Test_lisp_indent_change_multiline() call setline(1, ['(if a', ' (if b', ' (return 5)))']) normal! jc2j(return 4)) call assert_equal(' (return 4))', getline(2)) - close! + bw! endfunc func Test_lisp_indent() @@ -179,7 +179,7 @@ func Test_lisp_indent() normal! jostr1" normal! jostr2" call assert_equal([' ;; comment', ' ;; comment', ' \ abc', ' \ abc', '', ' ;; ret', ' " str1\', ' str1"', ' " st\b', ' str2"'], getline(2, 11)) - close! + bw! endfunc func Test_lisp_indent_quoted() @@ -195,7 +195,7 @@ endfunc " Test for setting the 'indentexpr' from a modeline func Test_modeline_indent_expr() let modeline = &modeline - set modeline + set modeline nomodelinestrict func GetIndent() return line('.') * 2 endfunc @@ -206,10 +206,10 @@ func Test_modeline_indent_expr() exe "normal Oa\nb\n" call assert_equal([' a', ' b'], getline(1, 2)) - set modelineexpr& + set modelineexpr& modelinestrict& delfunc GetIndent let &modeline = modeline - close! + bw! endfunc func Test_indent_func_with_gq() @@ -321,7 +321,7 @@ func Test_indent_overflow_count() norm! V2147483647> " indents by INT_MAX call assert_equal(2147483647, indent(1)) - close! + bw! endfunc func Test_indent_overflow_count2() @@ -335,7 +335,7 @@ func Test_indent_overflow_count2() call setline(1, "\tabc") norm! << call assert_equal(0, indent(1)) - close! + bw! endfunc " Test that mouse shape is restored to Normal mode after using "gq" when diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim index bf16a93617..7eda457e1a 100644 --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -674,7 +674,7 @@ func Test_scroll_info_window() call ScrollInfoWindowTest("", 0, 1) call ScrollInfoWindowTest("pagedown", 1, 4) call ScrollInfoWindowTest("pagedown", 2, 7) - call ScrollInfoWindowTest("pagedown", 3, 11) + call ScrollInfoWindowTest("pagedown", 3, 10) call ScrollInfoWindowTest("pageup", 3, 1) endfunc @@ -3696,10 +3696,16 @@ func Test_complete_opt_fuzzy() call feedkeys("Goa\\\", 'tx') call assert_equal('aaaa', getline('.')) + %d + set autoindent + set completeopt=menuone,fuzzy + call feedkeys("A\hello world\word is on fire\w\\\", 'tx') + call assert_equal("\thello world", getline('.')) + " clean up set omnifunc= bw! - set complete& completeopt& + set complete& completeopt& autoindent& autocmd! AAAAA_Group augroup! AAAAA_Group delfunc OnPumChange @@ -6289,4 +6295,40 @@ func Test_ins_register_preinsert_autocomplete() delfunc TestOmni endfunc +func Test_autocomplete_with_auto_format() + call test_override("char_avail", 1) + new + setlocal formatoptions=tcq textwidth=9 autocomplete noautoindent + call feedkeys("ia b c d\ie f g\", 'tx') + call assert_equal(['a b c e f', 'gd'], getline(1, '$')) + + %delete + setlocal autoindent + call feedkeys("ia b c d\ie f g\", 'tx') + call assert_equal(['a b c e f', 'gd'], getline(1, '$')) + + bw! + call test_override("char_avail", 0) +endfunc + +func Test_completion_with_mapped_ctrl_r() + new + let b:n = 0 + let @a = 'AABBCCDDEE' + " Ctrl-R mapping is triggered + inoremap let b:n += 1 + inoremap call complete(col('.'), []) + call feedkeys("i\\<*C-R>abcde\", 'tx') + call assert_equal(1, b:n) + call assert_equal('abcde', getline('.')) + + " Ctrl-X Ctrl-R still works with Ctrl-R mapped + call feedkeys("ccAAB\<*C-X>\<*C-R>\<*C-Y>\", 'tx') + call assert_equal(1, b:n) + call assert_equal('AABBCCDDEE', getline('.')) + + let @a = '' + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable diff --git a/src/testdir/test_listener.vim b/src/testdir/test_listener.vim index 8cbd15377a..6b91e8d046 100644 --- a/src/testdir/test_listener.vim +++ b/src/testdir/test_listener.vim @@ -801,4 +801,15 @@ func Test_listener_blockwise_paste() bwipe! endfunc +func Test_listener_add_in_sandbox() + call assert_fails( + \ 'sandbox call redraw_listener_add({"on_start": function("tr")})', + \ 'E48:') + call assert_fails( + \ 'sandbox call listener_add({"on_start": function("tr")})', + \ 'E48:') + call assert_fails('sandbox call listener_flush()', 'E48:') + call assert_fails('sandbox call listener_remove(1)', 'E48:') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim index 01f2d1f944..29f42848d4 100644 --- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -1124,7 +1124,11 @@ func Test_map_cmdkey() call setline(1, ['some short lines', 'of test text']) call feedkeys(":bar\x\\"\r", 'xt') call assert_equal('"barx', @:) - unmap! + + " test for chars with 0x80 or 0x9b bytes + map let x = '洛å›ē四最倒倀' + call feedkeys("\", 'xt') + call assert_equal('洛å›ē四最倒倀', x) " test for calling a function let lines =<< trim END @@ -1137,7 +1141,10 @@ func Test_map_cmdkey() source Xscript call feedkeys("\", 'xt') call assert_equal(32, g:x) + unlet g:x + unmap + unmap! unmap unmap! %bw! diff --git a/src/testdir/test_marks.vim b/src/testdir/test_marks.vim index ed09221449..61bfade627 100644 --- a/src/testdir/test_marks.vim +++ b/src/testdir/test_marks.vim @@ -254,7 +254,14 @@ func Test_marks_k_cmd() call setline(1, ['foo', 'bar', 'baz', 'qux']) 1,3kr call assert_equal([0, 3, 1, 0], getpos("'r")) + " whitespace before mark + 4k f + call assert_equal([0, 4, 1, 0], getpos("'f")) + :2 k g + call assert_equal([0, 2, 1, 0], getpos("'g")) bw! + call assert_fails(':kz7', 'E488: Trailing characters: z7') + call assert_fails(':execute ":k^"', 'E191: Argument must be a letter or forward/backward quote') endfunc " Test for file marks (A-Z) diff --git a/src/testdir/test_matchfuzzy.vim b/src/testdir/test_matchfuzzy.vim index eb4c8c6567..dfeb074d7f 100644 --- a/src/testdir/test_matchfuzzy.vim +++ b/src/testdir/test_matchfuzzy.vim @@ -322,4 +322,13 @@ func Test_matchfuzzy_initialized() call StopVimInTerminal(buf) endfunc +func Test_matchfuzzy_long_multiword_no_overflow() + let word = repeat('a', 100) + let pat_ok = repeat(word . ' ', 9) . word + call assert_equal([word], matchfuzzy([word], pat_ok)) + + let pat_overflow = repeat(word . ' ', 14) . word + call assert_equal([[], [], []], matchfuzzypos([word], pat_overflow)) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim index 5fa84e9542..2e5a16e4b8 100644 --- a/src/testdir/test_messages.vim +++ b/src/testdir/test_messages.vim @@ -439,7 +439,7 @@ func Test_mode_cleared_after_silent_message() let buf = RunVimInTerminal('-S XsilentMessageMode', {'rows': 10}) call term_sendkeys(buf, 'v') - call TermWait(buf) + call WaitForAssert({-> assert_match('VISUAL.*\d\+\s\+\d', term_getline(buf, 10))}, 1000) call VerifyScreenDump(buf, 'Test_mode_cleared_after_silent_message_1', {}) call term_sendkeys(buf, 'd') @@ -458,6 +458,8 @@ func Test_echo_verbose_system() CheckNotMac " the macos TMPDIR is too long for snapshot testing let buf = RunVimInTerminal('', {'rows': 10}) + " give it some time to handle DECRQM response + call TermWait(buf, 50) call term_sendkeys(buf, ":4 verbose echo system('seq 20')\") " Note that the screendump is filtered to remove the name of the temp file call VerifyScreenDump(buf, 'Test_verbose_system_1', {}) @@ -835,4 +837,69 @@ func Test_fileinfo_after_last_bd() call StopVimInTerminal(buf) endfunc +func Test_undo_messages() + new + + " Normal undo/redo messages + redir => result + call setline(1, 'foo') + undo + undo + redo + redo + redir END + let msg_list = split(result, "\n") + call assert_match("^1 line less; before #1", msg_list[0]) + call assert_equal("Already at oldest change", msg_list[1]) + call assert_match("^1 more line; after #1", msg_list[2]) + call assert_equal("Already at newest change", msg_list[3]) + + " Ignore undo/redo messages + redir => result + set shortmess+=u + call setline(1, 'foo') + undo + undo + redo + redo + redir END + let msg_list = split(result, "\n") + call assert_equal([], msg_list) + set shortmess& + + " undo_time() path: :earlier and :later go through a separate + " message site than u_doit(); make sure SHM_UNDO suppresses it too. + enew! + call setline(1, 'a') + call setline(1, 'b') + call setline(1, 'c') + + redir => result + earlier 1 + earlier 999 + earlier 999 + later 1 + later 999 + redir END + let msg_list = split(result, "\n") + call assert_match('^1 line less; before #', msg_list[0]) + call assert_match('^1 changes; before #', msg_list[1]) + call assert_match('^1 changes; before #', msg_list[2]) + call assert_match('^1 more line; after #', msg_list[3]) + call assert_equal('Already at newest change', msg_list[4]) + + set shortmess+=u + redir => result + earlier 1 + earlier 999 + later 1 + later 999 + later 999 + redir END + call assert_equal([], split(result, "\n")) + + set shortmess& + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim index 9dbd0094e2..9bf1b47ff5 100644 --- a/src/testdir/test_mksession.vim +++ b/src/testdir/test_mksession.vim @@ -75,9 +75,9 @@ func Test_mksession() \ ' four leadinG spaces', \ 'two consecutive tabs', \ 'two tabs in one line', - \ 'one ä multibyteCharacter', - \ 'aä Ä two multiByte characters', - \ 'Aäöü three mulTibyte characters', + \ 'one ä multibyteCharacter', + \ 'aä Ä two multiByte characters', + \ 'AäÃļÃŧ three mulTibyte characters', \ 'short line', \ ]) let tmpfile = 'Xtemp' @@ -126,33 +126,33 @@ func Test_mksession() mksession! Xtest_mks.out let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! [0$]\\|^ *exe ''normal!\\)"') let expected = [ - \ 'normal! 016|', - \ 'normal! 016|', - \ 'normal! 016|', - \ 'normal! 08|', - \ 'normal! 08|', - \ 'normal! 016|', - \ 'normal! 016|', - \ 'normal! 016|', - \ 'normal! $', - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", - \ " normal! 08|", - \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", - \ " normal! 08|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|" + \ ' normal! 016|', + \ ' normal! 016|', + \ ' normal! 016|', + \ ' normal! 08|', + \ ' normal! 08|', + \ ' normal! 016|', + \ ' normal! 016|', + \ ' normal! 016|', + \ ' normal! $', + \ " exe 'normal! ' .. c .. '|zs' .. 16 .. '|'", + \ " normal! 016|", + \ " exe 'normal! ' .. c .. '|zs' .. 16 .. '|'", + \ " normal! 016|", + \ " exe 'normal! ' .. c .. '|zs' .. 16 .. '|'", + \ " normal! 016|", + \ " exe 'normal! ' .. c .. '|zs' .. 8 .. '|'", + \ " normal! 08|", + \ " exe 'normal! ' .. c .. '|zs' .. 8 .. '|'", + \ " normal! 08|", + \ " exe 'normal! ' .. c .. '|zs' .. 16 .. '|'", + \ " normal! 016|", + \ " exe 'normal! ' .. c .. '|zs' .. 16 .. '|'", + \ " normal! 016|", + \ " exe 'normal! ' .. c .. '|zs' .. 16 .. '|'", + \ " normal! 016|", + \ " exe 'normal! ' .. c .. '|zs' .. 16 .. '|'", + \ " normal! 016|" \ ] call assert_equal(expected, li) tabclose! @@ -1066,7 +1066,7 @@ func Test_mksession_winminheight() let found_restore = 0 let lines = readfile('Xtest_mks.out') for line in lines - if line =~ '= s:save_winmin\(width\|height\)' + if line =~ '= save_winmin\(width\|height\)' let found_restore += 1 endif endfor @@ -1088,11 +1088,11 @@ func Test_mksession_shortmess() for line in lines let line = trim(line) - if line ==# 'let s:shortmess_save = &shortmess' + if line ==# 'shortmess_save = &shortmess' let found_save += 1 endif - if found_save !=# 0 && line ==# 'let &shortmess = s:shortmess_save' + if found_save !=# 0 && line ==# '&shortmess = shortmess_save' let found_restore += 1 endif endfor @@ -1109,7 +1109,7 @@ func Test_mksession_shortmess() let found_restore = 0 let lines = readfile('Xtest_mks.out') for line in lines - if line =~# 's:shortmess_save' + if line =~# '\(var \)\@ dummy-test dummy9.Test() .. "" + END + call writefile(plugin_sources, root . '/plugin/dummy9.vim') + + call mkdir(root . '/autoload', 'p') + let auto_sources =<< trim END + vim9script + const ref_txt = 'Hello from vim9 dummy plugin!' + export def Test(): string + writefile([ref_txt], 'XDummyOutput') + return has("gui_running") ? '' : $':echomsg "{ref_txt}"' + enddef + END + call writefile(auto_sources, root . '/autoload/dummy9.vim') + + " clean up later + defer delete(base, 'rf') + + " Load and check the plugin + const ref_txt = 'Hello from vim9 dummy plugin!' + let &packpath .= ',' . base + packadd dummy9 + messages clear + normal dummy-test + + if !has('gui_running') + call assert_match(ref_txt, execute('messages'), 'No vim9 plugin dummy.Test() execution') + endif + call assert_true(filereadable('XDummyOutput'), 'Output file was not created by Vim9 plugin') + call assert_equal([ref_txt], readfile('XDummyOutput')) + call delete('XDummyOutput') + + " Create a session file + mksession! XDummySession.vim + defer delete('XDummySession.vim') + call assert_true(filereadable('XDummySession.vim'), 'Session file was not created') + + " Check the session file mappings are operational + let test_sources =<< trim END + " load session + source XDummySession.vim + " execute vim9 expression mapping + normal dummy-test + " on my way + cq + END + call writefile(test_sources, 'XTest.vim', 'D') + " spawn a new Vim instance to load the session and execute the mapping + call system(GetVimCommand('XTest.vim')) + defer delete('XDummyOutput') + call assert_true(filereadable('XDummyOutput'), + \ 'Expected output file was not created by Vim9 plugin') + call assert_equal([ref_txt], readfile('XDummyOutput')) + +endfunc + +" Test legacy vimscript expression mappings +func Test_mksession_legacy_expr_mappings() + + CheckFeature packages + + " Create a dummy vim9 plugin + const base = getcwd() . '/rtdir' + const root = base . '/pack/test/opt/dummy' + call mkdir(root . '/plugin', 'p') + + " clean up later + defer delete(base, 'rf') + + let plugin_sources =<< trim END + nnoremap dummy-test dummy#Test() . "" + END + call writefile(plugin_sources, root . '/plugin/dummy.vim') + + call mkdir(root . '/autoload', 'p') + let auto_sources =<< trim END + const s:ref_txt = 'Hello from good old dummy plugin!' + func dummy#Test() + call writefile([s:ref_txt], 'XDummyOutput') + return has("gui_running") ? '' : $':echomsg "{s:ref_txt}"' + endfunc + END + call writefile(auto_sources, root . '/autoload/dummy.vim') + + " Load and check the plugin + const ref_txt = 'Hello from good old dummy plugin!' + let &packpath .= ',' . base + packadd dummy + messages clear + normal dummy-test + + if !has("gui_running") + call assert_match(ref_txt, execute('messages'), 'No vim9 plugin dummy.Test() execution') + endif + call assert_true(filereadable('XDummyOutput'), 'Output file was not created by legacy plugin') + call assert_equal([ref_txt], readfile('XDummyOutput')) + call delete('XDummyOutput') + + " Create a session file + mksession! XDummySession.vim + defer delete('XDummySession.vim') + call assert_true(filereadable('XDummySession.vim'), 'Session file was not created') + + " Check the session file mappings are operational + let test_sources =<< trim END + " load session + source XDummySession.vim + " execute legacy vimscript expression mapping + normal dummy-test + " on my way + cq + END + call writefile(test_sources, 'XTest.vim', 'D') + " spawn a new Vim instance to load the session and execute the mapping + call system(GetVimCommand('XTest.vim')) + defer delete('XDummyOutput') + call assert_true(filereadable('XDummyOutput'), + \ 'Expected output file was not created by legacy vim plugin') + call assert_equal([ref_txt], readfile('XDummyOutput')) + +endfunc + +" Test sessions cursor position management +func Test_mksession_cursor_position() + + " Set windows test scenario + let files = [] + for i in range(10) + let file = $'Xfile{i}' + exe $"{i ? 'split' : 'edit'} {file}" + call append(0, $"Session file cursor position testing {i}") + " Force cursor position restoring commands + setlocal nowrap + normal dd29zl + " Check expected position + call assert_equal([0, 1, 30, 0], getpos('.'), $"Fail to set cursor position for {file}") + write! + let files += [file] + endfor + + " Save session + mksession! Xtest_curpos + + " Test restoring session + %bwipe! + try + source Xtest_curpos + catch + call assert_report("Failure sourcing session file") + endtry + + " Check cursor position + for file in files + exe $"drop {file}" + call assert_equal([0, 1, 30, 0], getpos('.'), $"Cursor position not restored correctly for {file}") + endfor + + " Clean up + call delete('Xtest_curpos') + for file in files + call delete(file) + endfor +endfunc + +" Test sessions global and local mappings +func Test_mksession_localmappings() + + " Create sessions. Mapping execution is tested running a file + let valid_sessions = [] " keep map info + let invalid_sessions = [] " do not keep map info + " localoptions requires a buffer + setlocal noswapfile + silent write XDummy + defer delete('XDummy') + + for option in ["&", "=options", "=localoptions"] + for global in [0, 1] + + " select options + exe "set sessionoptions" .. option + + " mapping + exe "nnoremap" . (global ? " " : " ") + \ . "dummy-test silent write XDummyOutput" + let case = $"mapping_{global ? "global" : "local"}_{option}" + + " test mapping + normal dummy-test + call assert_true(filereadable("XDummyOutput"), $"Output file was not created by {case}") + call delete("XDummyOutput") + + " session + let sessionfile = "XSession_" . case + exe $"mksession {sessionfile}" + + if global && option =~ "localoptions" + let invalid_sessions += [sessionfile] + else + let valid_sessions += [sessionfile] + endif + + " clear mappings + nmapclear + nmapclear + + endfor + endfor + + " Check the session files are operational + for session in valid_sessions + + let test_sources =<< trim eval END + " load session + silent source {session} + " execute legacy vimscript expression mapping + normal dummy-test + " on my way + cq + END + + call writefile(test_sources, 'XTest.vim') + call system(GetVimCommand('XTest.vim')) + call assert_true(filereadable('XDummyOutput'), + \ $"Expected map not defined in session file {session}") + call delete('XDummyOutput') + call delete(session) + + endfor + + for session in invalid_sessions + + let test_sources =<< trim eval END + " load session + silent source {session} + " execute legacy vimscript expression mapping + normal dummy-test + " on my way + cq + END + + call writefile(test_sources, 'XTest.vim') + call system(GetVimCommand('XTest.vim')) + call assert_false(filereadable('XDummyOutput'), + \ $"Unexpected map defined in session file {session}") + if filereadable('XDummyOutput') + call delete('XDummyOutput') + endif + call delete(session) + endfor + +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_mksession_utf8.vim b/src/testdir/test_mksession_utf8.vim index d467dc20c6..90695f0c8d 100644 --- a/src/testdir/test_mksession_utf8.vim +++ b/src/testdir/test_mksession_utf8.vim @@ -64,34 +64,38 @@ func Test_mksession_utf8() mksession! test_mks.out let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"') let expected =<< trim [DATA] - normal! 016| - normal! 016| - normal! 016| - normal! 08| - normal! 08| - normal! 016| - normal! 016| - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' + | normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' normal! 016| - exe 'normal! ' . s:c . '|zs' . 8 . '|' normal! 08| - exe 'normal! ' . s:c . '|zs' . 8 . '|' normal! 08| - exe 'normal! ' . s:c . '|zs' . 16 . '|' normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' - normal! 016| - exe 'normal! ' . s:c . '|zs' . 16 . '|' normal! 016| + exe 'normal! ' .. c .. '|zs' .. 16 .. '|' + normal! 016| + exe 'normal! ' .. c .. '|zs' .. 16 .. '|' + normal! 016| + exe 'normal! ' .. c .. '|zs' .. 16 .. '|' + normal! 016| + exe 'normal! ' .. c .. '|zs' .. 8 .. '|' + normal! 08| + exe 'normal! ' .. c .. '|zs' .. 8 .. '|' + normal! 08| + exe 'normal! ' .. c .. '|zs' .. 16 .. '|' + normal! 016| + exe 'normal! ' .. c .. '|zs' .. 16 .. '|' + normal! 016| + exe 'normal! ' .. c .. '|zs' .. 16 .. '|' + normal! 016| + exe 'normal! ' .. c .. '|zs' .. 16 .. '|' + normal! 016| [DATA] + " remove indent marker + call remove(expected, 0) + call assert_equal(expected, li) tabclose! diff --git a/src/testdir/test_modeline.vim b/src/testdir/test_modeline.vim index 79fc7d14d5..c436cbc270 100644 --- a/src/testdir/test_modeline.vim +++ b/src/testdir/test_modeline.vim @@ -47,7 +47,7 @@ endfunc func Test_modeline_syntax() call writefile(['vim: set syn=c :', 'nothing'], 'Xmodeline_syntax', 'D') let modeline = &modeline - set modeline + set modeline nomodelinestrict syntax enable split Xmodeline_syntax call assert_equal("c", &syntax) @@ -55,6 +55,7 @@ func Test_modeline_syntax() bwipe! let &modeline = modeline + set modelinestrict syntax off endfunc @@ -62,13 +63,14 @@ func Test_modeline_keymap() CheckFeature keymap call writefile(['vim: set keymap=greek :', 'nothing'], 'Xmodeline_keymap', 'D') let modeline = &modeline - set modeline + set modeline nomodelinestrict split Xmodeline_keymap call assert_equal("greek", &keymap) call assert_match('greek\|grk', b:keymap_name) bwipe! let &modeline = modeline + set modelinestrict set keymap= iminsert=0 imsearch=-1 endfunc @@ -145,7 +147,8 @@ endfunc func Test_modeline_colon() let modeline = &modeline - set modeline + let modelinestrict = &modelinestrict + set modeline nomodelinestrict call writefile(['// vim: set showbreak=\: ts=2: sw=2'], 'Xmodeline_colon', 'D') edit Xmodeline_colon @@ -159,6 +162,7 @@ func Test_modeline_colon() call assert_equal(8, &sw) let &modeline = modeline + let &modelinestrict = modelinestrict endfunc func s:modeline_fails(what, text, error) @@ -170,7 +174,8 @@ func s:modeline_fails(what, text, error) let fname = "Xmodeline_fails_" . a:what call writefile(['vim: set ' . a:text . ' :', 'nothing'], fname, 'D') let modeline = &modeline - set modeline + let modelinestrict = &modelinestrict + set modeline nomodelinestrict filetype plugin on syntax enable call assert_fails('split ' . fname, a:error) @@ -179,6 +184,7 @@ func s:modeline_fails(what, text, error) bwipe! let &modeline = modeline + let &modelinestrict = modelinestrict filetype plugin off syntax off endfunc @@ -277,6 +283,61 @@ func Test_modeline_fails_modelineexpr() call s:modeline_fails('titlestring', 'titlestring=Something()', 'E992:') endfunc +func Test_modeline_complete_uses_sandbox() + let modeline = &modeline + let modelineexpr = &modelineexpr + let modelinestrict = &modelinestrict + + func! ModelineCompletePwnFindstart(findstart, base) + if a:findstart + call writefile(['findstart'], 'Xmodeline_complete_proof') + return 0 + endif + return ['match'] + endfunc + + func! ModelineCompletePwnMatches(findstart, base) + if a:findstart + return 0 + endif + call writefile(['matches'], 'Xmodeline_complete_proof') + return ['match'] + endfunc + + try + set modeline modelineexpr nomodelinestrict + + call writefile([ + \ 'vim: set complete=FModelineCompletePwnFindstart :', + \ 'body', + \ ], 'Xmodeline_complete_attack', 'D') + call delete('Xmodeline_complete_proof') + edit Xmodeline_complete_attack + call cursor(2, 1) + call assert_fails('call feedkeys("i\\", "xt")', 'E48:') + call assert_false(filereadable('Xmodeline_complete_proof')) + bwipe! + + call writefile([ + \ 'vim: set complete=FModelineCompletePwnMatches :', + \ 'body', + \ ], 'Xmodeline_complete_attack', 'D') + call delete('Xmodeline_complete_proof') + edit Xmodeline_complete_attack + call cursor(2, 1) + call assert_fails('call feedkeys("i\\", "xt")', 'E48:') + call assert_false(filereadable('Xmodeline_complete_proof')) + bwipe! + finally + let &modeline = modeline + let &modelineexpr = modelineexpr + let &modelinestrict = modelinestrict + call delete('Xmodeline_complete_proof') + delfunc ModelineCompletePwnFindstart + delfunc ModelineCompletePwnMatches + endtry +endfunc + func Test_modeline_setoption_verbose() let modeline = &modeline set modeline @@ -348,20 +409,23 @@ endfunc " Some options cannot be set from the modeline when 'diff' option is set func Test_modeline_diff_buffer() + set nomodelinestrict call writefile(['vim: diff foldmethod=marker wrap'], 'Xmdifile', 'D') set foldmethod& nowrap new Xmdifile call assert_equal('manual', &foldmethod) call assert_false(&wrap) set wrap& + set modelinestrict bw endfunc func Test_modeline_disable() - set modeline + set modeline nomodelinestrict call writefile(['vim: sw=2', 'vim: nomodeline', 'vim: sw=3'], 'Xmodeline_disable', 'D') edit Xmodeline_disable call assert_equal(2, &sw) + set modelinestrict endfunc " If 'nowrap' is set from a modeline, '>' is used forcibly as lcs-extends. @@ -373,6 +437,7 @@ func Test_modeline_nowrap_lcs_extends() \ 'ddd vim: nowrap', \ ], 'Xmodeline_nowrap', 'D') set noequalalways + set nomodelinestrict 11new | 20vsplit func Check_modeline_nowrap(expect_insecure, expect_secure, set_cmd) @@ -493,4 +558,164 @@ func Test_modeline_nowrap_lcs_extends() set equalalways& endfunc +func Test_modeline_strict_allowed() + let modeline = &modeline + set modeline modelinestrict + + " Whitelisted options should work + call writefile(['vim: set ts=2 sw=4 et foldmarker=[,]:'], 'Xmodeline_strict', 'D') + split Xmodeline_strict + call assert_equal(2, &ts) + call assert_equal(4, &sw) + call assert_equal(1, &et) + call assert_equal('[,]', &foldmarker) + bwipe! + + " 'filetype' should work + call writefile(['vim: set ft=python :'], 'Xmodeline_strict') + filetype plugin on + split Xmodeline_strict + call assert_equal("python", &filetype) + bwipe! + filetype plugin off + + " 'spell' and 'spelllang' should work + call writefile(['vim: set spell spelllang=de :'], 'Xmodeline_strict') + split Xmodeline_strict + call assert_equal(1, &spell) + call assert_equal("de", &spelllang) + bwipe! + + " 'foldmethod' should work + call writefile(['vim: set fdm=marker :'], 'Xmodeline_strict') + split Xmodeline_strict + call assert_equal("marker", &foldmethod) + bwipe! + + " 'autoindent' and 'cindent' should work + call writefile(['vim: set ai cin :'], 'Xmodeline_strict') + split Xmodeline_strict + call assert_equal(1, &ai) + call assert_equal(1, &cin) + bwipe! + + " 'textwidth' + call writefile(['vim: set tw=10 :'], 'Xmodeline_strict') + split Xmodeline_strict + call assert_equal(10, &textwidth) + bwipe! + + let &modeline = modeline + set modelinestrict +endfunc + +func Test_modeline_strict_blocked() + let modeline = &modeline + set modeline modelinestrict + + " 'wrap' is not whitelisted, should be silently skipped + set wrap + call writefile(['vim: set nowrap :'], 'Xmodeline_strict_fail') + split Xmodeline_strict_fail + call assert_equal(1, &wrap) + bwipe! + + " 'number' is not whitelisted, should be silently skipped + set nonumber + call writefile(['vim: set number :'], 'Xmodeline_strict_fail') + split Xmodeline_strict_fail + call assert_equal(0, &number) + bwipe! + + " Whitelisted options still work alongside blocked ones + set wrap nonumber + call writefile(['vim: set nowrap ts=3 number :'], 'Xmodeline_strict_fail') + split Xmodeline_strict_fail + call assert_equal(1, &wrap) + call assert_equal(3, &ts) + call assert_equal(0, &number) + bwipe! + + let &modeline = modeline +endfunc + +func Test_modeline_strict_off() + let modeline = &modeline + set modeline nomodelinestrict + + " With modelinestrict off, non-whitelisted options should work + call writefile(['vim: set number :'], 'Xmodeline_strict_off', 'D') + split Xmodeline_strict_off + call assert_equal(1, &number) + bwipe! + + let &modeline = modeline + set modelinestrict& +endfunc + +func Test_modeline_strict_cannot_be_set_from_modeline() + let modeline = &modeline + set modeline modelinestrict + + " 'modelinestrict' itself cannot be set from a modeline (P_SECURE) + call writefile(['vim: set nomodelinestrict :'], 'Xmodeline_strict_ml', 'D') + call assert_fails('split Xmodeline_strict_ml', 'E520:') + call assert_equal(1, &modelinestrict) + bwipe! + + let &modeline = modeline +endfunc + +func Test_modeline_nomodeline_with_modelinestrict() + let modeline = &modeline + let modelinestrict = &modelinestrict + let modelines = &modelines + set modelinestrict modeline modelines=5 + let ml_before = &g:modeline + + call writefile(['# vim: set nomodeline:', 'line2'], 'Xnoml', 'D') + split Xnoml + call assert_equal(0, &l:modeline, 'b_p_ml should be off') + call assert_equal(ml_before, &g:modeline, 'global p_ml must not change') + bwipe! + + " A fresh buffer must still inherit the unchanged global default + new + call assert_equal(ml_before, &l:modeline, + \ 'new buffer should inherit unchanged global') + bwipe! + + let &modeline = modeline + let &modelinestrict = modelinestrict + let &modelines = modelines +endfunc + +func Test_modeline_nomodeline_skips_trailing_modelines() + let modeline = &modeline + let modelinestrict = &modelinestrict + let ts_save = &ts + set modeline modelinestrict ts=8 + + " Line 1 disables modelines; the trailing modeline must therefore + " never execute even though 'tabstop' is whitelisted. + call writefile([ + \ '# vim: set nomodeline :', + \ 'middle line 1', + \ 'middle line 2', + \ 'middle line 3', + \ '# vim: set ts=99 :', + \ ], 'Xmodeline_disable_top', 'D') + split Xmodeline_disable_top + + call assert_equal(0, &l:modeline, + \ 'top modeline must have disabled b_p_ml') + call assert_equal(8, &ts, + \ 'trailing modeline must not have run after nomodeline') + + bwipe! + let &modeline = modeline + let &modelinestrict = modelinestrict + let &ts = ts_save +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_mswin_event.vim b/src/testdir/test_mswin_event.vim index 96d1247db6..101051748e 100644 --- a/src/testdir/test_mswin_event.vim +++ b/src/testdir/test_mswin_event.vim @@ -704,6 +704,10 @@ func Test_mswin_event_mouse() CheckMSWindows new + if !has('gui_running') + let g:test_is_flaky = 1 + endif + set mousemodel=extend call test_override('no_query_mouse', 1) call WaitForResponses() diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim index 4f435610bd..eea7891236 100644 --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -1196,6 +1196,31 @@ func Test_normal17_z_scroll_hor2() bw! endfunc +func Test_large_sidescrolloff_no_overflow() + 10new + 20vsp + setlocal nowrap sidescrolloff=2147483647 + call setline(1, repeat('a', 40)) + + normal! $ + redraw! + call assert_equal(29, winsaveview().leftcol) + + normal! zs + redraw! + call assert_equal(29, winsaveview().leftcol) + + normal! ze + redraw! + call assert_equal(29, winsaveview().leftcol) + + normal! 0 + redraw! + call assert_equal(0, winsaveview().leftcol) + + bw! +endfunc + " Test for commands that scroll the window horizontally. Test with folds. " H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands func Test_vert_scroll_cmds() diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index c2f9d9c6d6..686defdb44 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -318,7 +318,7 @@ func Test_set_completion() " Expand abbreviation of options. call feedkeys(":set ts\\\"\", 'tx') - call assert_equal('"set tabstop termsync thesaurus thesaurusfunc ttyscroll', @:) + call assert_equal('"set tabstop tagsecure termsync thesaurus thesaurusfunc ttyscroll', @:) " Expand current value call feedkeys(":set suffixes=\\\"\", 'tx') @@ -593,6 +593,12 @@ func Test_set_completion_string_values() if exists('+tabclose') call assert_equal('left uselast', join(sort(getcompletion('set tabclose=', 'cmdline'))), ' ') endif + if has('tabpanel') + call assert_equal(['align:', 'columns:', 'scrollbar', 'vert'], + \ getcompletion('set tabpanelopt=', 'cmdline')) + call assert_equal(['left', 'right'], + \ getcompletion('set tabpanelopt=align:', 'cmdline')) + endif if exists('+termwintype') call assert_equal('conpty', getcompletion('set termwintype=', 'cmdline')[1]) endif @@ -657,6 +663,22 @@ func Test_set_completion_string_values() call feedkeys(":set completepopup=height:10,align:\\\"\", 'xt') call assert_equal('"set completepopup=height:10,align:item', @:) call assert_equal([], getcompletion('set completepopup=bogusname:', 'cmdline')) + + " opacity: numeric, 0..100 only + call assert_true(index(getcompletion('set completepopup=', 'cmdline'), + \ 'opacity:') >= 0) + call assert_true(index(getcompletion('set previewpopup=', 'cmdline'), + \ 'opacity:') >= 0) + set completepopup=border:on,opacity:0 + set completepopup=border:on,opacity:50 + set completepopup=border:on,opacity:100 + call assert_fails('set completepopup=opacity:101', 'E474:') + call assert_fails('set completepopup=opacity:abc', 'E474:') + call assert_fails('set completepopup=opacity:-10', 'E474:') + set previewpopup=opacity:30 + call assert_fails('set previewpopup=opacity:200', 'E474:') + call assert_fails('set previewpopup=opacity:-10', 'E474:') + set previewpopup& completepopup& " diffopt: special handling of algorithm: and inline: @@ -667,7 +689,7 @@ func Test_set_completion_string_values() " highlight: special parsing, including auto-completing highlight groups " after ':' - call assert_equal([&hl, '8'], getcompletion('set hl=', 'cmdline')[0:1]) + call assert_equal([escape(&hl, '|'), '8'], getcompletion('set hl=', 'cmdline')[0:1]) call assert_equal('8', getcompletion('set hl+=', 'cmdline')[0]) call assert_equal(['8:', '8b', '8i'], getcompletion('set hl+=8', 'cmdline')[0:2]) call assert_equal('8bi', getcompletion('set hl+=8b', 'cmdline')[0]) @@ -877,9 +899,6 @@ func Test_set_option_errors() call assert_fails('set commentstring=x', 'E537:') call assert_fails('let &commentstring = "x"', 'E537:') call assert_fails('set complete=x', 'E539:') - call assert_fails('set rulerformat=%-', 'E539:') - call assert_fails('set rulerformat=%(', 'E542:') - call assert_fails('set rulerformat=%15(%%', 'E542:') " Test for 'statusline' errors call assert_fails('set statusline=%$', 'E539:') @@ -897,6 +916,11 @@ func Test_set_option_errors() call assert_fails('set tabline=%(', 'E542:') call assert_fails('set tabline=%)', 'E542:') + " Test for 'rulerformat' errors + call assert_fails('set rulerformat=%-', 'E539:') + call assert_fails('set rulerformat=%(', 'E542:') + call assert_fails('set rulerformat=%15(%%', 'E542:') + if has('cursorshape') " This invalid value for 'guicursor' used to cause Vim to crash. call assert_fails('set guicursor=i-ci,r-cr:h', 'E545:') @@ -1190,7 +1214,7 @@ func Test_backupskip() qall [CODE] call writefile(after, 'Xafter', 'D') - let cmd = GetVimProg() . ' --not-a-term -S Xafter --cmd "set enc=utf8"' + let cmd = GetVimProg() . ' --clean --not-a-term -S Xafter --cmd "set enc=utf8"' let saveenv = {} for var in ['TMPDIR', 'TMP', 'TEMP'] @@ -1198,9 +1222,9 @@ func Test_backupskip() call setenv(var, '/duplicate/path') endfor - " unset $HOME, so that it won't try to read init files + " set $HOME='', so that Vim won't try to read init files let saveenv['HOME'] = getenv("HOME") - call setenv('HOME', v:null) + call setenv('HOME', '') exe 'silent !' . cmd call assert_equal(['errors:'], readfile('Xtestout')) @@ -1433,7 +1457,7 @@ func Test_shortmess_F3() if has('nanotime') sleep 10m else - sleep 2 + sleep 3 endif call writefile(['bar'], 'X_dummy') bprev @@ -1443,7 +1467,7 @@ func Test_shortmess_F3() if has('nanotime') sleep 10m else - sleep 2 + sleep 3 endif call writefile(['baz'], 'X_dummy') checktime @@ -1500,6 +1524,45 @@ func Test_local_scrolloff() set siso& endfunc +func Test_local_scrolloffpad() + let save_g_sop = &g:sop + let save_l_sop = &l:sop + set sop=0 + call assert_equal(0, &g:sop) + call assert_equal(-1, &l:sop) + call assert_equal(0, &sop) + setglobal sop=1 + call assert_equal(1, &g:sop) + call assert_equal(1, &sop) + split + call assert_equal(1, &g:sop) + call assert_equal(-1, &l:sop) + call assert_equal(1, &sop) + setlocal sop=0 + call assert_equal(0, &l:sop) + call assert_equal(0, &sop) + call assert_equal(1, &g:sop) + wincmd p + call assert_equal(1, &sop) + wincmd p + setlocal sop< + call assert_equal(-1, &l:sop) + call assert_equal(1, &sop) + setlocal sop=2 + call assert_equal(2, &l:sop) + call assert_equal(2, &sop) + setlocal sop=-1 + call assert_equal(-1, &l:sop) + call assert_equal(1, &sop) " Uses global value because local is -1 + call assert_fails("setlocal sop=-2", 'E474:') + call assert_equal(-1, &l:sop) + call assert_equal(1, &sop) + call assert_fails("setlocal sop=foo", 'E521:') + close + let &g:sop = save_g_sop + let &l:sop = save_l_sop +endfunc + func Test_writedelay() " Workaround for MacVim GUI: This test fails sometimes after Test_VIM_POSIX. " Because, 'writedelay' makes no effect while its GUI window focus is lost, @@ -1645,7 +1708,7 @@ endfunc " Test for changing options in a sandbox func Test_opt_sandbox() - for opt in ['backupdir', 'cdpath', 'exrc', 'findfunc'] + for opt in ['backupdir', 'cdpath', 'exrc', 'findfunc', 'tagsecure'] call assert_fails('sandbox set ' .. opt .. '?', 'E48:') call assert_fails('sandbox let &' .. opt .. ' = 1', 'E48:') endfor @@ -2607,6 +2670,8 @@ func Test_string_option_revert_on_failure() \ ['selection', 'exclusive', 'a123'], \ ['selectmode', 'cmd', 'a123'], \ ['sessionoptions', 'options', 'a123'], + \ ['shellpipe', '>%s', "%s%s%s"], + \ ['shellredir', '>%s', "%s%s%s"], \ ['shortmess', 'w', '2'], \ ['showbreak', '>>', "\x01"], \ ['showcmdloc', 'statusline', 'a123'], diff --git a/src/testdir/test_plugin_matchit.vim b/src/testdir/test_plugin_matchit.vim new file mode 100644 index 0000000000..1c8144278d --- /dev/null +++ b/src/testdir/test_plugin_matchit.vim @@ -0,0 +1,58 @@ +" Tests for the matchit plugin + +func SetUp() + filetype plugin on + packadd matchit + call assert_equal('(MatchitNormalForward)', maparg('%', 'n', 0)) +endfunc + +func TearDown() + filetype plugin off +endfunc + +func s:Setup(lines, ft) + new + call setline(1, a:lines) + exe "setl ft=".. a:ft + call assert_true(exists('b:match_words')) + call assert_true(!empty(b:match_words)) +endfunc + +func s:PercentTo(arg) + call call('cursor', a:arg) + normal % + return line('.') +endfunc + +func Test_html_matchit_simple_tag() + call s:Setup(['', 'some text', ''], 'html') + call assert_equal(3, s:PercentTo([1, 2])) + call assert_equal(1, s:PercentTo([3, 3])) + call assert_equal(2, s:PercentTo([2, 2])) + normal % + call assert_equal(2, line('.')) + bwipe! +endfunc + +func Test_html_matchit_tag_with_attribute() + call s:Setup(['', 'some text', ''], 'html') + call assert_equal(3, s:PercentTo([1, 2])) + call assert_equal(1, s:PercentTo([3, 3])) + call assert_equal(2, s:PercentTo([2, 2])) + normal % + call assert_equal(2, line('.')) + bwipe! +endfunc + +func Test_html_matchit_tag_multiline_attributes() + call s:Setup(['', + \ 'some text', ''], 'html') + call assert_equal(6, s:PercentTo([1, 2])) + call assert_equal(1, s:PercentTo([6, 3])) + call assert_equal(5, s:PercentTo([5, 2])) + normal % + call assert_equal(5, line('.')) + bwipe! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_plugin_matchparen.vim b/src/testdir/test_plugin_matchparen.vim index a05fc5ddd2..136d55a31b 100644 --- a/src/testdir/test_plugin_matchparen.vim +++ b/src/testdir/test_plugin_matchparen.vim @@ -8,8 +8,8 @@ source util/screendump.vim " Test for scrolling that modifies buffer during visual block func Test_visual_block_scroll() - CheckScreendump - + CheckRunVimInTerminal + let g:test_is_flaky = 1 let lines =<< trim END source $VIMRUNTIME/plugin/matchparen.vim set scrolloff=1 @@ -23,7 +23,13 @@ func Test_visual_block_scroll() let buf = RunVimInTerminal('-S '.filename, #{rows: 7}) call term_sendkeys(buf, "V\\") - call VerifyScreenDump(buf, 'Test_display_visual_block_scroll', {}) + call WaitForAssert({-> assert_equal('{', trim(term_getline(buf, 1)))}, 1000) + call assert_equal('}', trim(term_getline(buf, 2))) + call assert_equal('{', trim(term_getline(buf, 3))) + call assert_equal('f', trim(term_getline(buf, 4))) + call assert_equal('g', trim(term_getline(buf, 5))) + call assert_equal('}', trim(term_getline(buf, 6))) + call assert_match('VISUAL LINE .*1,1\s\+Bot', term_getline(buf, 7)) call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim index b234670928..22477c68a8 100644 --- a/src/testdir/test_plugin_netrw.vim +++ b/src/testdir/test_plugin_netrw.vim @@ -138,6 +138,40 @@ function Test_NetrwValidateHostname(hostname) abort return s:NetrwValidateHostname(a:hostname) endfunction +" Test unmarking all files via s:NetrwUnMarkFile() +function Test_NetrwUnMarkFile() + " set up: init global and buffer-local mark lists + new + + " initializing the global mark list, the loop handles the buffer-local + let s:netrwmarkfilelist = ['test_file'] + + " making sure every buffer has a mark list and match pattern + let ibuf = 1 + while ibuf <= bufnr('$') + let s:netrwmarkfilelist_{ibuf} = ['test_mark'] + let s:netrwmarkfilemtch_{ibuf} = 'test_mark' + let ibuf = ibuf + 1 + endwhile + + call s:NetrwUnMarkFile(1) + + call assert_false(exists('s:netrwmarkfilelist'), 'Global list should be wiped') + call assert_false(exists('s:netrwmarkfilelist_' . bufnr('$')), 'Last buffer-local list should be wiped') + call assert_false(exists('s:netrwmarkfilemtch_' . bufnr('$')), 'Last buffer-local match str should be wiped') + call assert_false(exists('s:netrwmarkfilelist_1'), 'First buffer-local list should be wiped') + call assert_false(exists('s:netrwmarkfilemtch_1'), 'First buffer-local match str should be wiped') + + " wipe out the test buffer + bw +endfunction + +function Test_MakeBookmark(netrw_curdir, fname) + new + let b:netrw_curdir = a:netrw_curdir + call s:MakeBookmark(a:fname) + bw +endfunction " }}} END @@ -296,7 +330,9 @@ func Test_netrw_parse_special_char_user() call assert_equal(result.path, 'test.txt') endfunction -func Test_netrw_empty_buffer_fastpath_wipe() +" Note: Test_netrw_a_empty_buffer_fastpath_wipe() should run before +" any other tests that open a netrw buffer (e.g, :Explore). +func Test_netrw_a_empty_buffer_fastpath_wipe() " SetUp() may have opened some buffers let previous = bufnr('$') let g:netrw_fastbrowse=0 @@ -574,6 +610,7 @@ endfunc func Test_netrw_hostname() let valid_hostnames = [ \ 'localhost', + \ '_gateway', \ '127.0.0.1', \ '::1', \ '0:0:0:0:0:0:0:1', @@ -604,9 +641,184 @@ func Test_netrw_FileUrlEdit_pipe_injection() call assert_false(filereadable(fname), 'Command injection via pipe in file URL') endfunc +" The remote filename after '.' was allowed to contain shell metacharacters +" and rode unescaped into the tempfile name passed to sftp/file_cmd, giving a +" shell injection on :e sftp://host/foo.txt;. +func Test_netrw_tempfile_suffix_injection() + CheckUnix + CheckExecutable id + let save_sftp = g:netrw_sftp_cmd + let save_file = exists('g:netrw_file_cmd') ? g:netrw_file_cmd : v:null + let g:netrw_sftp_cmd = 'true' + let g:netrw_file_cmd = 'true' + let fname = 'Xrce_marker' + try + call delete(fname) + sil! call netrw#NetRead(2, 'sftp://localhost/foo.txt;id>'..fname) + call assert_false(filereadable(fname), 'Command injection via sftp:// tempfile suffix') + + call delete(fname) + sil! call netrw#NetRead(2, 'file://localhost/foo.txt;id>'..fname) + call assert_false(filereadable(fname), 'Command injection via file:// tempfile suffix') + finally + call delete(fname) + let g:netrw_sftp_cmd = save_sftp + if save_file is v:null + unlet! g:netrw_file_cmd + else + let g:netrw_file_cmd = save_file + endif + endtry +endfunc + func Test_netrw_RFC2396() let fname = 'a%20b' call assert_equal('a b', netrw#RFC2396(fname)) endfunc +func Test_netrw_Home_tilde() + Explore ~ + call assert_match('Netrw Directory Listing', getline(2)) + bw! +endfunc + +func Test_netrw_unmark_all() + call Test_NetrwUnMarkFile() +endfunc + +" Creating a bookmark from a marked file should use b:netrw_curdir as head directory +func Test_netrw_bookmark_marked_file() + let save_keepdir = g:netrw_keepdir + let save_workdir = getcwd() + let save_bookmarklist = exists('g:netrw_bookmarklist') ? g:netrw_bookmarklist : v:null + + " Make sure Vim's working directory diverge from Netrw's + let g:netrw_keepdir = 1 + let g:netrw_bookmarklist = [] + let test_workdir = getcwd() . '/Xtest_workdir' + let test_netrw_curdir = test_workdir . '/Xtest_netrw_curdir' + call mkdir(test_netrw_curdir, 'p') + call writefile([], test_netrw_curdir . '/test_file') + + execute 'cd ' . test_workdir + call Test_MakeBookmark(test_netrw_curdir, 'test_file') + + " Bookmark paths should be absolute and normalized to prevent duplicates on win32 + let expected_path = netrw#fs#AbsPath(test_netrw_curdir . '/test_file') + if has('win32') + let expected_path = substitute(expected_path, '\\', '/', 'ge') + endif + let expected_path = simplify(expected_path) + + call assert_equal(1, len(g:netrw_bookmarklist)) + call assert_equal(expected_path, g:netrw_bookmarklist[0]) + call assert_true(isabsolutepath(g:netrw_bookmarklist[0]), 'Bookmark paths should be absolute') + + " Tear down + execute 'cd ' . save_workdir + call delete(test_workdir, 'rf') + + let g:netrw_keepdir = save_keepdir + if save_bookmarklist is v:null + unlet! g:netrw_bookmarklist + else + let g:netrw_bookmarklist = save_bookmarklist + endif + + bw! +endfunc + +" Typing gb or mB without a count should prompt +" for a bookmark number through an inputlist(). +" Expected dialog output (gb): # | Goto Bookmark: +" 1| /foo/bar/baz +" +" Expected dialog output (mB): # | Delete Bookmark: +" 1| /foo/bar/baz +func Test_netrw_bookmark_goto_delete_prompt() + let save_home = g:netrw_home + let save_bookmarklist = exists('g:netrw_bookmarklist') ? g:netrw_bookmarklist : v:null + + let g:netrw_home = getcwd() + let g:netrw_bookmarklist = ['/foo/bar/baz'] + Explore . + + " Inject 'q' to cancel the inputlist() prompt + call feedkeys('q', 't') + let dialog_out = execute('normal gb') + call assert_match('Goto Bookmark:', dialog_out) + + call feedkeys('q', 't') + let dialog_out = execute('normal mB') + call assert_match('Delete Bookmark:', dialog_out) + + " Tear down + call delete(g:netrw_home . '/.netrwbook') + call delete(g:netrw_home . '/.netrwhist') + let g:netrw_home = save_home + if save_bookmarklist is v:null + unlet! g:netrw_bookmarklist + else + let g:netrw_bookmarklist = save_bookmarklist + endif + + bw! +endfunc + +func Test_netrw_mf_command_injection() + CheckUnix + CheckExecutable touch + let path = tempname() + let fname = 'x" . execute("silent! !touch poc") . "' + call mkdir(path, 'R') + let _cwd = getcwd() + exe "cd " path + call writefile([], fname) + Explore . + call search('^x') + :norm mf + :norm mf + call assert_false(filereadable('poc'), 'Command injection via mf command') + exe "cd " _cwd + bw! +endfunc + +function Test_netrw_NetrwMaps_CR_dirname() + CheckNotMSWindows + + let tmpdir = tempname() . '/evil:let g:netrw_pwn=1' + call mkdir(tmpdir, 'pR') + call assert_true(isdirectory(tmpdir)) + exe ":Explore " tmpdir + " Fire D + " If the commands are injected successfully, + " this fails with + " Vim(let):E488: Trailing characters: \ @ command line script + call feedkeys("D\\", "xt") + call assert_false(exists("g:netrw_pwn")) + + unlet! g:netrw_pwn + bw! +endfunction + +func Test_netrw_injection() + let g:netrw_home = getcwd() + let savefile = g:netrw_home . '/.netrwhist' + let g:netrw_dirhistmax = 10 + let g:netrw_dirhistcnt = 1 + let g:netrw_dirhist_1 = "x'|let g:injected = 1|let y='z" + call delete(savefile) + try + call netrw#Call('NetrwBookHistSave') + call assert_true(filereadable(savefile), savefile . ' must be written') + unlet g:netrw_dirhist_1 + execute 'source ' . fnameescape(savefile) + call assert_false(exists("g:injected"), 'injected statement must not execute') + call assert_equal("x'|let g:injected = 1|let y='z", g:netrw_dirhist_1, 'dirname must round-trip') + finally + call delete(savefile) + unlet! g:netrw_home g:netrw_dirhistmax g:netrw_dirhistcnt g:netrw_dirhist_1 g:injected + endtry +endfunc + " vim:ts=8 sts=2 sw=2 et diff --git a/src/testdir/test_plugin_osc52.vim b/src/testdir/test_plugin_osc52.vim index f14d3b8c16..afb13ef908 100644 --- a/src/testdir/test_plugin_osc52.vim +++ b/src/testdir/test_plugin_osc52.vim @@ -90,6 +90,20 @@ func Test_osc52_paste() call VerifyScreenDump(buf, 'Test_osc52_paste_04', {}) + " Test that TextPutPost (e.g. from hlyank plugin) doesn't make "paste" + " callback be called twice for osc52. + call term_sendkeys(buf, "\:au TextPutPost * let g:test = 1\") + call TermWait(buf) + + call term_sendkeys(buf, "\"+p") + call TermWait(buf) + + call term_sendkeys(buf, "\]52;c;" .. + \ base64_encode(str2blob(["test"])) .. "\\\") + call TermWait(buf) + + call VerifyScreenDump(buf, 'Test_osc52_paste_05', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_plugin_tar.vim b/src/testdir/test_plugin_tar.vim index d6dbdd7613..e19e5d809c 100644 --- a/src/testdir/test_plugin_tar.vim +++ b/src/testdir/test_plugin_tar.vim @@ -22,8 +22,8 @@ def g:Test_tar_basic() assert_match('^" Browsing tarfile .*/X.tar', getline(2)) assert_match('^" Select a file with cursor and press ENTER, "x" to extract a file', getline(3)) assert_match('^$', getline(4)) - assert_match('testtar/', getline(5)) - assert_match('testtar/file1.txt', getline(6)) + assert_equal('testtar/', getline(5)) + assert_equal('testtar/file1.txt', getline(6)) ### Check ENTER on header :1 @@ -78,7 +78,7 @@ def g:Test_tar_evil() assert_match('^" Select a file with cursor and press ENTER, "x" to extract a file', getline(3)) assert_match('^" Note: Path Traversal Attack detected', getline(4)) assert_match('^$', getline(5)) - assert_match('/etc/ax-pwn', getline(6)) + assert_equal('/etc/ax-pwn', getline(6)) ### Check ENTER on header :1 @@ -86,6 +86,11 @@ def g:Test_tar_evil() assert_equal("X.tar", @%) assert_equal(1, b:leading_slash) + ### Press x to extract + :6 + var mess = execute(":normal x", '') + assert_match('(tar#Extract) Path Traversal Attack detected, not extracting!', mess) + ### Check ENTER on file :6 exe ":normal \" @@ -141,63 +146,194 @@ def g:Test_tar_path_traversal_with_nowrapscan() assert_match('^" Select a file with cursor and press ENTER, "x" to extract a file', getline(3)) assert_match('^" Note: Path Traversal Attack detected', getline(4)) assert_match('^$', getline(5)) - assert_match('/etc/ax-pwn', getline(6)) + assert_equal('/etc/ax-pwn', getline(6)) assert_equal(1, b:leading_slash) bw! enddef -def g:Test_tar_lz4_extract() - CheckExecutable lz4 - - delete('X.txt') - delete('Xarchive.tar') - delete('Xarchive.tar.lz4') - call writefile(['hello'], 'X.txt') - call system('tar -cf Xarchive.tar X.txt') +def CreateTar(archivename: string, content: string, outputdir: string) + var tempdir = tempname() + mkdir(tempdir, 'R') + call writefile([content], tempdir .. '/X.txt') + assert_true(filereadable(tempdir .. '/X.txt')) + call system('tar -C ' .. tempdir .. ' -cf ' .. outputdir .. '/' .. archivename .. ' X.txt') assert_equal(0, v:shell_error) +enddef - call system('lz4 -z Xarchive.tar Xarchive.tar.lz4') +def CreateTgz(archivename: string, content: string, outputdir: string) + var tempdir = tempname() + mkdir(tempdir, 'R') + call writefile([content], tempdir .. '/X.txt') + assert_true(filereadable(tempdir .. '/X.txt')) + call system('tar -C ' .. tempdir .. ' -czf ' .. outputdir .. '/' .. archivename .. ' X.txt') + assert_equal(0, v:shell_error) +enddef + +def CreateTbz(archivename: string, content: string, outputdir: string) + var tempdir = tempname() + mkdir(tempdir, 'R') + call writefile([content], tempdir .. '/X.txt') + assert_true(filereadable(tempdir .. '/X.txt')) + call system('tar -C ' .. tempdir .. ' -cjf ' .. outputdir .. '/' .. archivename .. ' X.txt') + assert_equal(0, v:shell_error) +enddef + +def CreateTxz(archivename: string, content: string, outputdir: string) + var tempdir = tempname() + mkdir(tempdir, 'R') + call writefile([content], tempdir .. '/X.txt') + assert_true(filereadable(tempdir .. '/X.txt')) + call system('tar -C ' .. tempdir .. ' -cJf ' .. outputdir .. '/' .. archivename .. ' X.txt') + assert_equal(0, v:shell_error) +enddef + +def CreateTzst(archivename: string, content: string, outputdir: string) + var tempdir = tempname() + mkdir(tempdir, 'R') + call writefile([content], tempdir .. '/X.txt') + assert_true(filereadable(tempdir .. '/X.txt')) + call system('tar --zstd -C ' .. tempdir .. ' -cf ' .. outputdir .. '/' .. archivename .. ' X.txt') + assert_equal(0, v:shell_error) +enddef + +def CreateTlz4(archivename: string, content: string, outputdir: string) + var tempdir = tempname() + mkdir(tempdir, 'R') + call writefile([content], tempdir .. '/X.txt') + assert_true(filereadable(tempdir .. '/X.txt')) + call system('tar -C ' .. tempdir .. ' -cf ' .. tempdir .. '/Xarchive.tar X.txt') + assert_equal(0, v:shell_error) + assert_true(filereadable(tempdir .. '/Xarchive.tar')) + call system('lz4 -z ' .. tempdir .. '/Xarchive.tar ' .. outputdir .. '/' .. archivename) + assert_equal(0, v:shell_error) +enddef + +# XXX: Add test for .tar.bz3 +def g:Test_extraction() + var control = [ + {create: CreateTar, + archive: 'Xarchive.tar'}, + {create: CreateTgz, + archive: 'Xarchive.tgz'}, + {create: CreateTgz, + archive: 'Xarchive.tar.gz'}, + {create: CreateTbz, + archive: 'Xarchive.tbz'}, + {create: CreateTbz, + archive: 'Xarchive.tar.bz2'}, + {create: CreateTxz, + archive: 'Xarchive.txz'}, + {create: CreateTxz, + archive: 'Xarchive.tar.xz'}, + ] + + if executable('lz4') == 1 + control->add({ + create: CreateTlz4, + archive: 'Xarchive.tar.lz4' + }) + control->add({ + create: CreateTlz4, + archive: 'Xarchive.tlz4' + }) + endif + if executable('zstd') == 1 + control->add({ + create: CreateTzst, + archive: 'Xarchive.tar.zst' + }) + control->add({ + create: CreateTzst, + archive: 'Xarchive.tzst' + }) + endif + + for c in control + var dir = tempname() + mkdir(dir, 'R') + call(c.create, [c.archive, 'hello', dir]) + + delete('X.txt') + execute 'edit ' .. dir .. '/' .. c.archive + assert_equal('X.txt', getline(5), 'line 5 wrong in archive: ' .. c.archive) + :5 + normal x + assert_equal(0, v:shell_error, 'vshell error not 0') + assert_true(filereadable('X.txt'), 'X.txt not readable for archive: ' .. c.archive) + assert_equal(['hello'], readfile('X.txt'), 'X.txt wrong contents for archive: ' .. c.archive) + delete('X.txt') + delete(dir .. '/' .. c.archive) + bw! + endfor +enddef + +def g:Test_extract_with_dotted_dir() + delete('X.txt') + writefile(['when they kiss they spit white noise'], 'X.txt') + + var dirname = tempname() + mkdir(dirname, 'R') + dirname = dirname .. '/foo.bar' + mkdir(dirname, 'R') + var tarpath = dirname .. '/Xarchive.tar.gz' + system('tar -czf ' .. tarpath .. ' X.txt') + assert_true(filereadable(tarpath)) assert_equal(0, v:shell_error) delete('X.txt') - delete('Xarchive.tar') - defer delete('Xarchive.tar.lz4') + defer delete(tarpath) - e Xarchive.tar.lz4 - assert_match('X.txt', getline(5)) + execute 'e ' .. tarpath + assert_equal('X.txt', getline(5)) :5 normal x assert_true(filereadable('X.txt')) - assert_equal(['hello'], readfile('X.txt')) + assert_equal(['when they kiss they spit white noise'], readfile('X.txt')) delete('X.txt') bw! enddef -def g:Test_tlz4_extract() - CheckExecutable lz4 - +def g:Test_extract_with_dotted_filename() delete('X.txt') - delete('Xarchive.tar') - delete('Xarchive.tlz4') - call writefile(['goodbye'], 'X.txt') - call system('tar -cf Xarchive.tar X.txt') - assert_equal(0, v:shell_error) + writefile(['holiday inn'], 'X.txt') - call system('lz4 -z Xarchive.tar Xarchive.tlz4') + var dirname = tempname() + mkdir(dirname, 'R') + var tarpath = dirname .. '/Xarchive.foo.tar.gz' + system('tar -czf ' .. tarpath .. ' X.txt') + assert_true(filereadable(tarpath)) assert_equal(0, v:shell_error) delete('X.txt') - delete('Xarchive.tar') - defer delete('Xarchive.tlz4') + defer delete(tarpath) - e Xarchive.tlz4 - assert_match('X.txt', getline(5)) + execute 'e ' .. tarpath + assert_equal('X.txt', getline(5)) :5 normal x assert_true(filereadable('X.txt')) - assert_equal(['goodbye'], readfile('X.txt')) + assert_equal(['holiday inn'], readfile('X.txt')) delete('X.txt') bw! enddef + +def g:Test_extract_command_injection() + CheckExecutable gunzip + CheckExecutable touch + var tgz = eval('0z1F8B08087795056A000364756D6D792E74617200EDCE2B12C2300004D01C254' .. + '7480269CE534080A8495BD1DBF3996106C3A08A7ACFACD8157B59A7690BFB4A0FC3707C666E357D' .. + 'E65BC8B5A47CC8A5D61A522EA5B510D3CEBF5ED679197B8CE17CEDB7F9D4C76FBB5F3D000000000' .. + '000000000FCD11D32415E2C00280000') + var dirname = tempname() + + mkdir(dirname, 'R') + var tar = dirname .. "/';%$(touch pwned)'.tgz" + writefile(tgz, tar) + new + exe "e " .. fnameescape(tar) + exe ":Vimuntar " .. dirname + assert_false(filereadable(dirname .. "/pwned")) + bw! +enddef diff --git a/src/testdir/test_plugin_termdebug.vim b/src/testdir/test_plugin_termdebug.vim index f651806483..4e89252228 100644 --- a/src/testdir/test_plugin_termdebug.vim +++ b/src/testdir/test_plugin_termdebug.vim @@ -162,10 +162,10 @@ func Test_termdebug_basic() Break 9 call term_wait(gdb_buf) redraw! - call assert_equal([ + call WaitForAssert({-> assert_equal([ \ {'lnum': 9, 'id': 1014, 'name': 'debugBreakpoint1.0', \ 'priority': 110, 'group': 'TermDebug'}], - \ sign_getplaced('', #{group: 'TermDebug'})[0].signs) + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)}) Run call term_wait(gdb_buf, 400) redraw! @@ -324,12 +324,12 @@ func Test_termdebug_tbreak() call term_wait(gdb_buf) redraw! " both temporary and normal breakpoint signs were displayed... - call assert_equal([ + call WaitForAssert({-> assert_equal([ \ {'lnum': temp_bp_line, 'id': 1014, 'name': 'debugBreakpoint1.0', \ 'priority': 110, 'group': 'TermDebug'}, \ {'lnum': bp_line, 'id': 2014, 'name': 'debugBreakpoint2.0', \ 'priority': 110, 'group': 'TermDebug'}], - \ sign_getplaced('', #{group: 'TermDebug'})[0].signs) + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)}) Run call term_wait(gdb_buf, 400) @@ -717,10 +717,10 @@ func Test_termdebug_toggle_break() call term_wait(gdb_buf) redraw! - call assert_equal([ + call WaitForAssert({-> assert_equal([ \ {'lnum': bp_line, 'id': 1014, 'name': 'debugBreakpoint1.0', \ 'priority': 110, 'group': 'TermDebug'}], - \ sign_getplaced('', #{group: 'TermDebug'})[0].signs) + \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)}) RunOrContinue call term_wait(gdb_buf, 400) diff --git a/src/testdir/test_plugin_vimball.vim b/src/testdir/test_plugin_vimball.vim index 2d5b4ba768..30093ef719 100644 --- a/src/testdir/test_plugin_vimball.vim +++ b/src/testdir/test_plugin_vimball.vim @@ -83,3 +83,30 @@ func Test_vimball_path_traversal() call assert_false(filereadable('../XVimball/Xtest.txt')) call s:teardown() endfunc + +func Test_vimball_path_traversal_drive_letter() + call s:Mkvimball() + call delete('XVimball', 'rf') + sp Xtest.vmb + " try to write to a Windows-style absolute path with a drive letter + 4s#XVimball#C:/&# + so % + call feedkeys("\", "it") + + let mess = execute(':mess')->split('\n')[-1] + call assert_match('(Vimball) Path Traversal Attack detected, aborting\.\.\.', mess) + call s:teardown() +endfunc + +func Test_vimball_evil_filenames() + call s:Mkvimball() + call delete('XVimball', 'rf') + sp Xtest.vmb + 4s#XVimball#pwn')# + so % + call feedkeys("\", "it") + + let mess = execute(':mess')->split('\n')[-1] + call assert_match('(Vimball) Forbidding strange filename:.* aborting\.\.\.', mess) + call s:teardown() +endfunc diff --git a/src/testdir/test_plugin_zip.vim b/src/testdir/test_plugin_zip.vim index 3d39e24ef7..4357131543 100644 --- a/src/testdir/test_plugin_zip.vim +++ b/src/testdir/test_plugin_zip.vim @@ -22,7 +22,7 @@ def g:Test_zip_basic() ### Check header assert_match('^" zip\.vim version v\d\+', getline(1)) - assert_match('^" Browsing zipfile .*/X.zip', getline(2)) + assert_match('^" Browsing zipfile .*/X\.zip', getline(2)) assert_match('^" Select a file with cursor and press ENTER', getline(3)) assert_match('^$', getline(4)) @@ -43,7 +43,7 @@ def g:Test_zip_basic() :1 search('file.txt') exe ":normal \" - assert_match('zipfile://.*/X.zip::Xzip/file.txt', @%) + assert_match('zipfile://.*/X\.zip::Xzip/file\.txt', @%) assert_equal('one', getline(1)) ### Check editing file @@ -68,7 +68,7 @@ def g:Test_zip_basic() assert_true(filereadable("Xzip/file.txt")) ## Check not overwriting existing file - assert_match(' .* not overwriting!', execute("normal x")) + assert_match(' .* not overwriting!', execute("normal x")) delete("Xzip", "rf") @@ -118,7 +118,7 @@ def g:Test_zip_basic() ### Check when "zip" report failure if executable("false") g:zip_zipcmd = "false" - assert_match('sorry, unable to update .*/X.zip with Xzip/file.txt', + assert_match('sorry, unable to update .*/X\.zip with Xzip/file\.txt', execute("write")) endif bw!|bw @@ -189,7 +189,7 @@ def g:Test_zip_glob_fname() fname = 'a[a].txt' search('\V' .. fname) exe ":normal \" - assert_match('zipfile://.*/X.zip::zipglob/a\[a\].txt', @%) + assert_match('zipfile://.*/X\.zip::zipglob/a\[a\]\.txt', @%) assert_equal('a test file with []', getline(1)) bw @@ -198,7 +198,7 @@ def g:Test_zip_glob_fname() fname = 'a*.txt' search('\V' .. fname) exe ":normal \" - assert_match('zipfile://.*/X.zip::zipglob/a\*.txt', @%) + assert_match('zipfile://.*/X\.zip::zipglob/a\*\.txt', @%) assert_equal('a test file with a*', getline(1)) bw @@ -207,7 +207,7 @@ def g:Test_zip_glob_fname() fname = 'a?.txt' search('\V' .. fname) exe ":normal \" - assert_match('zipfile://.*/X.zip::zipglob/a?.txt', @%) + assert_match('zipfile://.*/X\.zip::zipglob/a?\.txt', @%) assert_equal('a test file with a?', getline(1)) bw @@ -216,7 +216,7 @@ def g:Test_zip_glob_fname() fname = 'a\.txt' search('\V' .. escape(fname, '\\')) exe ":normal \" - assert_match('zipfile://.*/X.zip::zipglob/a\\.txt', @%) + assert_match('zipfile://.*/X\.zip::zipglob/a\\\.txt', @%) assert_equal('a test file with a\', getline(1)) bw @@ -225,7 +225,7 @@ def g:Test_zip_glob_fname() fname = 'a\\.txt' search('\V' .. escape(fname, '\\')) exe ":normal \" - assert_match('zipfile://.*/X.zip::zipglob/a\\\\.txt', @%) + assert_match('zipfile://.*/X\.zip::zipglob/a\\\\\.txt', @%) assert_equal('a test file with a double \', getline(1)) bw diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim index 52e915dce1..d9d77a7ad0 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -723,6 +723,9 @@ func Test_popup_and_preview_autocommand() au! au BufAdd * nested tab sball augroup END + " Let pythoncomplete follow the buffer's 'import os' (off by default + " since v9.2.0561) so 'os.' can be completed. + let g:pythoncomplete_allow_import = 1 set omnifunc=pythoncomplete#Complete call setline(1, 'import os') " make the line long @@ -745,6 +748,7 @@ func Test_popup_and_preview_autocommand() augroup END augroup! MyBufAdd bw! + unlet g:pythoncomplete_allow_import endfunc func s:run_popup_and_previewwindow_dump(lines, dumpfile) @@ -2457,6 +2461,140 @@ func Test_pumopt_opacity_screendump() call StopVimInTerminal(buf) endfunc +" Test pumopt opacity with multibyte background text and multibyte popup +" items. Exercises the wide-character alignment in the blend path: +" - a wide background character whose trailing cell falls inside the pum +" fill range must not be re-emitted after screen_char() has already drawn +" the full glyph (would clobber the right half); +" - a wide background character at the right edge of the fill range must +" not spill into the adjacent border cell. +func Test_pumopt_opacity_wide_bg() + CheckScreendump + let lines =<< trim END + set pumopt=opacity:50,border:round + set completeopt=menu + call setline(1, '') + for i in range(20) + call append(line('$'), 'ãģげãģげãģげæŧĸ字テ゚トあいうえおã‚Ģã‚ŋã‚Ģナ') + endfor + normal gg + inoremap call complete(col('.'), + \ ['ãģげ', 'ãĩがæŧĸ字', 'ã‚Ģã‚ŋã‚ĢãƒŠå€™čŖœ']) + END + call writefile(lines, 'Xpumoptopacitywide', 'D') + let buf = RunVimInTerminal('-S Xpumoptopacitywide', {}) + call TermWait(buf) + call term_sendkeys(buf, "i\") + call TermWait(buf, 100) + call VerifyScreenDump(buf, 'Test_pumopt_opacity_wide_bg', {}) + call term_sendkeys(buf, "\\u") + call TermWait(buf) + call StopVimInTerminal(buf) +endfunc + +" hl_pum_blend_attr() treated the CTERMCOLOR sentinel as a real near-white +" color, leaking white bg onto textprop-covered cells under pum opacity. +" Triggered by a textprop hl that only sets guisp. +func Test_pumopt_opacity_textprop_undercurl() + CheckScreendump + let lines =<< trim END + set termguicolors + set t_Cs= t_Ce= + set pumopt=opacity:50 + set completeopt=menu + call setline(1, '') + for i in range(8) + call append(line('$'), 'aaa bbb ccc ddd eee fff ggg hhh') + endfor + hi MyError guisp=#ec7279 + call prop_type_add('mytype', #{highlight: 'MyError', combine: 1}) + for s:l in range(2, 8) + call prop_add(s:l, 5, #{type: 'mytype', length: 20}) + endfor + normal gg + inoremap call complete(col('.'), + \ ['popup-item-1', 'popup-item-2', 'popup-item-3']) + END + call writefile(lines, 'Xpumoptopacitytextprop', 'D') + let buf = RunVimInTerminal('-S Xpumoptopacitytextprop', {}) + call TermWait(buf) + call term_sendkeys(buf, "i\") + call TermWait(buf, 100) + call VerifyScreenDump(buf, 'Test_pumopt_opacity_textprop_undercurl', {}) + call term_sendkeys(buf, "\\u") + call TermWait(buf) + call StopVimInTerminal(buf) +endfunc + +" Test pumopt opacity when every other background line is shifted by one +" narrow cell, so the background's wide-character boundaries do not align +" with the popup's wide-character grid. Exercises the blend path when: +" - pum_bg has the trailing half of a wide character at col == start_col +" (its leading half was overwritten by the popup text's clear_next_cell +" narrow space), where restoring the trailing alone would emit a stray +" NUL; a blended space must be rendered instead. +" - clearing of ScreenLinesUC[off + 1] when screen_puts_len writes a wide +" character on a cell whose trailing previously held a different wide +" char's leading codepoint. +func Test_pumopt_opacity_wide_bg_shifted() + CheckScreendump + let lines =<< trim END + set pumopt=opacity:50,border:round + set completeopt=menu + call setline(1, '') + let base = 'ãģげãģげãģげæŧĸ字テ゚トあいうえおã‚Ģã‚ŋã‚Ģナ' + for i in range(20) + call append(line('$'), (i % 2 == 0 ? '' : 'a') .. base) + endfor + normal gg + inoremap call complete(col('.'), + \ ['ãģげ', 'ãĩがæŧĸ字', 'ã‚Ģã‚ŋã‚ĢãƒŠå€™čŖœ']) + END + call writefile(lines, 'Xpumoptopacityshifted', 'D') + let buf = RunVimInTerminal('-S Xpumoptopacityshifted', {}) + call TermWait(buf) + call term_sendkeys(buf, "i\") + call TermWait(buf, 100) + call VerifyScreenDump(buf, 'Test_pumopt_opacity_wide_bg_shifted', {}) + call term_sendkeys(buf, "\\u") + call TermWait(buf) + call StopVimInTerminal(buf) +endfunc + +" Test that opaque popup text uses the popup's own attributes (fg and flags +" like italic) rather than inheriting them from the syntax-highlighted +" multibyte background cell underneath. Without this guard, popup text +" picks up the fg/italic of whatever buffer text happened to sit under +" each cell. +func Test_pumopt_opacity_text_attrs() + CheckScreendump + let lines =<< trim END + set pumopt=opacity:50 + set completeopt=menu + hi clear + hi Pmenu guifg=#ffffff guibg=#004488 ctermfg=white ctermbg=darkblue + hi PmenuSel guifg=#000000 guibg=#ffcc00 ctermfg=black ctermbg=yellow + hi Special guifg=#ff66cc cterm=italic gui=italic + call setline(1, '') + for i in range(20) + call append(line('$'), 'ãģげãģげãģげæŧĸ字テ゚トあいうえおã‚Ģã‚ŋã‚Ģナ') + endfor + call matchadd('Special', 'æŧĸ字\|テ゚ト') + normal gg + inoremap call complete(col('.'), + \ ['ãģげ', 'ãĩがæŧĸ字', 'ã‚Ģã‚ŋã‚ĢãƒŠå€™čŖœ']) + END + call writefile(lines, 'Xpumoptopacityattrs', 'D') + let buf = RunVimInTerminal('-S Xpumoptopacityattrs', {}) + call TermWait(buf) + call term_sendkeys(buf, "i\") + call TermWait(buf, 100) + call VerifyScreenDump(buf, 'Test_pumopt_opacity_text_attrs', {}) + call term_sendkeys(buf, "\\u") + call TermWait(buf) + call StopVimInTerminal(buf) +endfunc + " Test pumopt opacity:100 (fully opaque, same as default) func Test_pumopt_opacity_100() CheckScreendump @@ -2480,4 +2618,36 @@ func Test_pumopt_opacity_100() call StopVimInTerminal(buf) endfunc +" When an opacity popup above another one is closed, moving the lower popup +" into the old area must blend against the restored background, not the stale +" contents of the closed popup. +func Test_popup_opacity_move_after_close() + CheckScreendump + let lines =<< trim END + call setline(1, repeat(['abcdefghijklmnopqrstuvwxyz'], 8)) + let g:popup_a = popup_create('A', #{ + \ line: 3, col: 5, padding: [0, 4, 0, 0], border: [], + \ opacity: 50, zindex: 10 + \ }) + let g:popup_b = popup_create('BBBB', #{ + \ line: 3, col: 12, border: [], opacity: 50, zindex: 20 + \ }) + func MovePopupA(timer) abort + call popup_close(g:popup_b) + call popup_move(g:popup_a, #{col: 12}) + endfunc + call timer_start(100, 'MovePopupA') + END + + call writefile(lines, 'Xpopupopacitymove', 'D') + let buf = RunVimInTerminal('-S Xpopupopacitymove', #{rows: 8, cols: 25}) + call TermWait(buf, 150) + call VerifyScreenDump(buf, 'Test_popup_opacity_move_after_close', {}) + call StopVimInTerminal(buf) +endfunc + +func Test_popup_create_sandbox() + call assert_fails('sandbox call popup_create("hello", {})', 'E48:') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index 023d890676..11e431246a 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -1412,6 +1412,18 @@ endfunc func Test_popup_option_values() new + " Save old values + let save_g_so = &g:so + let save_l_so = &l:so + let save_g_sop = &g:sop + let save_l_sop = &l:sop + + let save_nu = &l:nu + let save_wrap = &l:wrap + let save_ofu = &l:ofu + let save_path = &l:path + let save_stl = &l:stl + " window-local setlocal number setlocal nowrap @@ -1421,6 +1433,8 @@ func Test_popup_option_values() setlocal path=/there " global/window-local setlocal statusline=2 + set scrolloff=5 + set scrolloffpad=1 let winid = popup_create('hello', {}) call assert_equal(0, getwinvar(winid, '&number')) @@ -1429,12 +1443,27 @@ func Test_popup_option_values() call assert_equal(&g:path, getwinvar(winid, '&path')) call assert_equal(&g:statusline, getwinvar(winid, '&statusline')) - " 'scrolloff' is reset to zero + " 'scrolloff' and 'scrolloffpad' are reset to zero call assert_equal(5, &scrolloff) call assert_equal(0, getwinvar(winid, '&scrolloff')) + call assert_equal(1, &scrolloffpad) + call assert_equal(0, getwinvar(winid, '&scrolloffpad')) call popup_close(winid) - bwipe + + " Restore old values + let &g:so = save_g_so + let &l:so = save_l_so + let &g:sop = save_g_sop + let &l:sop = save_l_sop + + let &l:nu = save_nu + let &l:wrap = save_wrap + let &l:ofu = save_ofu + let &l:path = save_path + let &l:stl = save_stl + + bwipe! endfunc func Test_popup_atcursor() @@ -2534,6 +2563,32 @@ func Test_popup_settext() call StopVimInTerminal(buf) endfunc +func Test_popup_settext_scrollbar_disappear() + CheckScreendump + + let lines =<< trim END + let g:p = popup_create(repeat(['hello world'], 30), #{ + \ line: 3, + \ col: 5, + \ pos: 'topleft', + \ minheight: 10, + \ maxheight: 10, + \ minwidth: 30, + \ border: [1, 1, 1, 1], + \ }) + END + call writefile(lines, 'XtestPopupScrollDisappear', 'D') + let buf = RunVimInTerminal('-S XtestPopupScrollDisappear', #{rows: 15, cols: 50}) + call VerifyScreenDump(buf, 'Test_popup_settext_scrollbar_disappear_1', {}) + + " Shrinking the buffer makes the scrollbar disappear. The right border + " column must not leave stray characters where the scrollbar used to be. + call term_sendkeys(buf, ":call popup_settext(g:p, ['short'])\") + call VerifyScreenDump(buf, 'Test_popup_settext_scrollbar_disappear_2', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_popup_settext_getline() let id = popup_create('', #{ tabpage: 0 }) call popup_settext(id, ['a','b']) @@ -3086,7 +3141,7 @@ func Test_popupwin_with_buffer_and_filter() call assert_equal(1, popup_getpos(winid).firstline) redraw call feedkeys("G", 'xt') - call assert_equal(99, popup_getpos(winid).firstline) + call assert_equal(96, popup_getpos(winid).firstline) call popup_close(winid) exe 'bwipe! ' .. bufnr @@ -4467,6 +4522,222 @@ func Test_popup_setoptions_other_tab() call prop_type_delete('textprop') endfunc +func Test_popup_clipwindow_option() + " Default: clipwindow is off. + let id = popup_create('TEST', #{}) + call assert_equal(0, popup_getoptions(id).clipwindow) + call popup_close(id) + + " popup_create() honours the option. + let id = popup_create('TEST', #{clipwindow: v:true}) + call assert_equal(1, popup_getoptions(id).clipwindow) + + " popup_setoptions() can toggle it off and on. + call popup_setoptions(id, #{clipwindow: v:false}) + call assert_equal(0, popup_getoptions(id).clipwindow) + call popup_setoptions(id, #{clipwindow: v:true}) + call assert_equal(1, popup_getoptions(id).clipwindow) + + call popup_close(id) +endfunc + +func Test_popup_clipwindow_hide_when_prop_off_screen() + " A "clipwindow" popup attached to a textprop should be hidden once the + " host window scrolls so the textprop is far enough off-screen that even + " the partially-clipped popup would no longer overlap, and unhidden again + " when the prop scrolls back into reach. + call prop_type_add('clipprop', {}) + new + call setline(1, range(1, 200)->mapnew({_, v -> 'line ' .. v})) + call prop_add(5, 1, #{type: 'clipprop', length: 5}) + let host = win_getid() + + let id = popup_create('attached', #{ + \ textprop: 'clipprop', + \ textpropwin: host, + \ line: -1, + \ wrap: v:false, + \ fixed: v:true, + \ clipwindow: v:true, + \ }) + redraw + call assert_equal(1, popup_getpos(id).visible) + + " Scroll the host so the prop is far below topline; popup hides. + call win_execute(host, 'normal! Gzb') + redraw + call assert_equal(0, popup_getpos(id).visible) + + " Scroll back so the prop is on the first visible line; popup unhides. + call win_execute(host, 'normal! ggzt') + redraw + call assert_equal(1, popup_getpos(id).visible) + + call popup_close(id) + bwipe! + call prop_type_delete('clipprop') +endfunc + +func Test_popup_clipwindow_top_clip() + CheckScreendump + + let lines =<< trim END + vim9script + set nowrap + :botright new + :resize 6 + setline(1, range(1, 30)->mapnew((_, v) => 'host line ' .. v)) + prop_type_add('clipprop', {}) + prop_add(2, 1, {type: 'clipprop', length: 4}) + popup_create(['popup A', 'popup B', 'popup C'], { + textprop: 'clipprop', + line: -4, + col: 0, + border: [], + padding: [0, 1, 0, 1], + highlight: 'PmenuSel', + wrap: false, + fixed: true, + posinvert: false, + clipwindow: true, + }) + END + call writefile(lines, 'XtestPopupClipwindowTop', 'D') + let buf = RunVimInTerminal('-S XtestPopupClipwindowTop', #{rows: 14, cols: 40}) + call VerifyScreenDump(buf, 'Test_popup_clipwindow_top_clip', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_popup_clipwindow_bottom_clip() + CheckScreendump + + let lines =<< trim END + vim9script + set nowrap + :topleft new + :resize 6 + setline(1, range(1, 30)->mapnew((_, v) => 'host line ' .. v)) + prop_type_add('clipprop', {}) + prop_add(2, 1, {type: 'clipprop', length: 4}) + popup_create(['popup A', 'popup B', 'popup C'], { + textprop: 'clipprop', + line: 1, + col: 0, + border: [], + padding: [0, 1, 0, 1], + highlight: 'PmenuSel', + wrap: false, + fixed: true, + posinvert: false, + clipwindow: true, + }) + END + call writefile(lines, 'XtestPopupClipwindowBottom', 'D') + let buf = RunVimInTerminal('-S XtestPopupClipwindowBottom', #{rows: 14, cols: 40}) + call VerifyScreenDump(buf, 'Test_popup_clipwindow_bottom_clip', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_popup_clipwindow_left_clip() + CheckScreendump + + let lines =<< trim END + vim9script + set nowrap + :vert botright new + :vert resize 22 + set laststatus=0 + setline(1, repeat(['host content line abcdef'], 20)) + prop_type_add('clipprop', {}) + prop_add(5, 6, {type: 'clipprop', length: 4}) + popup_create(['popup A', 'popup B', 'popup C'], { + textprop: 'clipprop', + line: 0, + col: -10, + border: [], + padding: [0, 1, 0, 1], + highlight: 'PmenuSel', + wrap: false, + fixed: true, + posinvert: false, + clipwindow: true, + }) + END + call writefile(lines, 'XtestPopupClipwindowLeft', 'D') + let buf = RunVimInTerminal('-S XtestPopupClipwindowLeft', #{rows: 14, cols: 50}) + call VerifyScreenDump(buf, 'Test_popup_clipwindow_left_clip', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_popup_clipwindow_right_clip() + CheckScreendump + + let lines =<< trim END + vim9script + set nowrap + :vert topleft new + :vert resize 22 + set laststatus=0 + setline(1, repeat(['host content line abcdef'], 20)) + prop_type_add('clipprop', {}) + prop_add(5, 14, {type: 'clipprop', length: 4}) + popup_create(['popup A', 'popup B', 'popup C'], { + textprop: 'clipprop', + line: 0, + col: 0, + border: [], + padding: [0, 1, 0, 1], + highlight: 'PmenuSel', + wrap: false, + fixed: true, + posinvert: false, + clipwindow: true, + }) + END + call writefile(lines, 'XtestPopupClipwindowRight', 'D') + let buf = RunVimInTerminal('-S XtestPopupClipwindowRight', #{rows: 14, cols: 50}) + call VerifyScreenDump(buf, 'Test_popup_clipwindow_right_clip', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_popup_clipwindow_hidden() + CheckScreendump + + let lines =<< trim END + vim9script + set nowrap + :topleft new + :resize 6 + setline(1, range(1, 50)->mapnew((_, v) => 'host line ' .. v)) + prop_type_add('clipprop', {}) + prop_add(2, 1, {type: 'clipprop', length: 4}) + popup_create(['popup A', 'popup B', 'popup C'], { + textprop: 'clipprop', + line: -4, + col: 0, + border: [], + padding: [0, 1, 0, 1], + highlight: 'PmenuSel', + wrap: false, + fixed: true, + posinvert: false, + clipwindow: true, + }) + # Scroll the host so the textprop is far below topline; the popup is + # then hidden because the prop has scrolled out of the host window. + win_execute(win_getid(), 'normal! Gzb') + END + call writefile(lines, 'XtestPopupClipwindowHidden', 'D') + let buf = RunVimInTerminal('-S XtestPopupClipwindowHidden', #{rows: 14, cols: 40}) + call VerifyScreenDump(buf, 'Test_popup_clipwindow_hidden', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_popup_prop_not_visible() CheckScreendump @@ -4909,6 +5180,32 @@ func Test_popup_opacity_zero() call StopVimInTerminal(buf) endfunc +func Test_popup_opacity_terminal_no_freeze() + CheckFeature terminal + CheckUnix + let g:test_is_flaky = 1 + + let origwin = win_getid() + let termbuf = term_start(&shell, #{hidden: 1}) + let winid = popup_create(termbuf, #{minwidth: 40, minheight: 10, + \ border: [1, 1, 1, 1], opacity: 10}) + call WaitForAssert({-> assert_equal("run", job_status(term_getjob(termbuf)))}) + call WaitForAssert({-> assert_equal(' ', screenstring(screenrow(), screencol() - 1))}) + + " Before the fix typing froze Vim: redraw under an opacity popup raised + " must_redraw every cycle, trapping terminal_loop in its redraw loop. + call feedkeys('x', 'xt') + call term_wait(termbuf) + redraw + call WaitForAssert({-> assert_equal('x', screenstring(screenrow(), screencol() - 1))}) + + call feedkeys("\", 'xt') + call feedkeys("exit\", 'xt') + call WaitForAssert({-> assert_equal("dead", job_status(term_getjob(termbuf)))}) + call feedkeys(":quit\", 'xt') + call assert_equal(origwin, win_getid()) +endfunc + func Test_popup_getwininfo_tabnr() tab split let winid1 = popup_create('sup', #{tabpage: 1}) @@ -4932,6 +5229,7 @@ func Test_popup_opacity_wide_char_overlap() " higher-zindex popup are properly blended (no holes or missing chars). let lines =<< trim END set encoding=utf-8 + set termguicolors for i in range(1, 20) call setline(i, 'いえãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧãƒŧい! ' .. i) endfor @@ -4939,7 +5237,7 @@ func Test_popup_opacity_wide_char_overlap() hi MyPopup2 ctermbg=darkred ctermfg=white let g:p1 = popup_create(['あめんãŧčĩ¤ã„ãĒ','あいうえお'], #{ \ opacity: 50, - \ line: 6, + \ line: 3, \ col: 4, \ border: [], \ borderchars: ['─','│','─','│','╭','╮','╯','╰'], @@ -4950,7 +5248,7 @@ func Test_popup_opacity_wide_char_overlap() \}) let g:p2 = popup_create(['ã‚ĢナフãƒĢãĒ','ポップã‚ĸップで','æœ€ä¸Šåˇ'], #{ \ opacity: 50, - \ line: 4, + \ line: 1, \ col: 3, \ minwidth: 15, \ minheight: 3, @@ -4963,9 +5261,9 @@ func Test_popup_opacity_wide_char_overlap() let buf = RunVimInTerminal('-S XtestPopupOpacityWide', #{rows: 15, cols: 45}) call VerifyScreenDump(buf, 'Test_popupwin_opacity_wide_1', {}) - " Move popups far apart so they don't overlap. - " Tests right edge of popup where wide chars span content/padding boundary. - call term_sendkeys(buf, ":call popup_move(g:p2, #{line: 14, col: 16})\") + " Move p2 so it partially overlaps with p1 at a different position. + " Tests wide chars at the overlap boundary of two opacity popups. + call term_sendkeys(buf, ":call popup_move(g:p2, #{line: 6, col: 16})\") call TermWait(buf) call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_opacity_wide_2', {}) @@ -5064,6 +5362,40 @@ func Test_popup_opacity_vsplit() call StopVimInTerminal(buf) endfunc +func Test_popup_opacity_textprop_undercurl() + CheckScreendump + + " hl_blend_attr() treated the CTERMCOLOR sentinel as a real near-white + " color, leaking white bg onto textprop-covered cells under an opacity + " popup. Triggered by a textprop hl that only sets guisp. + let lines =<< trim END + set termguicolors + set t_Cs= t_Ce= + call setline(1, ['aaa bbb ccc ddd eee fff ggg hhh', + \ 'iii jjj kkk lll mmm nnn ooo ppp', + \ 'qqq rrr sss ttt uuu vvv www xxx', + \ 'yyy zzz 111 222 333 444 555 666']) + hi MyError guisp=#ec7279 + call prop_type_add('mytype', #{highlight: 'MyError', combine: 1}) + for s:l in range(1, line('$')) + call prop_add(s:l, 5, #{type: 'mytype', length: 20}) + endfor + hi PanelBg guibg=#0b1021 guifg=#e5e9f0 + call popup_create(['POPUP CONTENT', ' ', ' middle '], #{ + \ line: 1, col: 10, + \ minwidth: 30, minheight: 3, + \ opacity: 35, + \ highlight: 'PanelBg', + \ zindex: 200, + \ }) + END + call writefile(lines, 'XtestPopupOpacityTextprop', 'D') + let buf = RunVimInTerminal('-S XtestPopupOpacityTextprop', #{rows: 8, cols: 50}) + call VerifyScreenDump(buf, 'Test_popupwin_opacity_textprop_undercurl', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_popup_close_b_nwindows() edit Xfoo setlocal bufhidden=wipe @@ -5102,4 +5434,91 @@ func Test_popupwin_close_status_redraw() call StopVimInTerminal(buf) endfunc +func Test_popupwin_close_copen_redraw() + CheckMSWindows + CheckFeature quickfix + + func! s:OpenPopup() + call popup_create(repeat(['ZZZZZZZZZ'], 10), #{ + \ pos: 'botright', + \ col: &columns, + \ line: &lines, + \ filter: function('s:PopupFilter'), + \ }) + endfunc + func! s:PopupFilter(winid, key) + if a:key ==# 'q' + call popup_close(a:winid) + copen + endif + return 1 + endfunc + + enew! + call setline(1, range(1, 30)) + call setqflist(map(range(1, 20), + \ {_, v -> {'bufnr': bufnr('%'), 'lnum': v, 'col': 1, 'text': 'item ' .. v}})) + + call s:OpenPopup() + redraw + call feedkeys('q', 'xt') + redraw + cclose + redraw + + call s:OpenPopup() + redraw + call feedkeys('q', 'xt') + redraw + + for row in range(&lines - 9, &lines) + let line = join(map(range(1, &columns), 'screenstring(row, v:val)'), '') + call assert_notmatch('Z', line) + endfor + + cclose + bwipe! + delfunc s:OpenPopup + delfunc s:PopupFilter +endfunc + +func Test_popup_opacity_fade_to_background() + CheckScreendump + + " Opacity popup spanning a vertical split should redraw both windows + " underneath, not just the left one (blend accumulation bug). + let lines =<< trim END + call setline(1, repeat(['X X X X X'], 4)) + hi PopupColor guibg=blue + let g:pop_id = popup_create(['Popup'], #{ + \ line: 2, col: 3, + \ minwidth: 10, + \ minheight: 2, + \ highlight: 'PopupColor', + \ opacity: 60, + \ zindex: 50, + \}) + END + call writefile(lines, 'XtestPopupOpacityFadeToBackground', 'D') + let buf = RunVimInTerminal('-S XtestPopupOpacityFadeToBackground', #{rows: 12, cols: 60}) + " light background without Normal color set + call VerifyScreenDump(buf, 'Test_popupwin_opacity_fade_to_background_1', {}) + + " dark background without Normal color set + call term_sendkeys(buf, ":set background=dark\") + call VerifyScreenDump(buf, 'Test_popupwin_opacity_fade_to_background_2', {}) + + " light background with Normal cterm color set + call term_sendkeys(buf, ":set background=light\") + call term_sendkeys(buf, ":highlight Normal ctermfg=16 ctermbg=223\") + call VerifyScreenDump(buf, 'Test_popupwin_opacity_fade_to_background_3', {}) + + " light background with Normal gui color set + call term_sendkeys(buf, ":set termguicolors\") + call term_sendkeys(buf, ":highlight Normal ctermfg=NONE ctermbg=NONE guifg=#000000 guibg=#ffdab9\") + call VerifyScreenDump(buf, 'Test_popupwin_opacity_fade_to_background_4', {}) + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 5326c3dfb6..6ffc1828a9 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -2271,7 +2271,7 @@ func Test_switchbuf() " If opening a file changes 'switchbuf', then the new value should be " retained. - set modeline&vim + set modeline&vim nomodelinestrict call writefile(["vim: switchbuf=split"], 'Xqftestfile1', 'D') enew | only set switchbuf&vim @@ -2290,7 +2290,7 @@ func Test_switchbuf() call delete('Xqftestfile2') call delete('Xqftestfile3') - set switchbuf&vim + set switchbuf&vim modelinestrict enew | only endfunc @@ -2334,6 +2334,53 @@ func Test_adjust_lnum() call Xadjust_qflnum('l') endfunc +func Xqf_undo_after_delete(cchar) + call s:setup_commands(a:cchar) + + enew | only + + let fname = 'Xqfundofile' . a:cchar + call s:create_test_file(fname) + exe 'edit ' . fname + + Xgetexpr [fname . ':5:Line5', + \ fname . ':10:Line10', + \ fname . ':15:Line15'] + + " Delete the line of the second error and undo the deletion. + 10delete + let l = g:Xgetlist() + call assert_equal(5, l[0].lnum) + call assert_equal(10, l[1].lnum) + call assert_equal(14, l[2].lnum) + + undo + call assert_equal('Line10', getline(10)) + let l = g:Xgetlist() + call assert_equal(5, l[0].lnum) + call assert_equal(10, l[1].lnum) + call assert_equal(15, l[2].lnum) + + " Redo and undo again to make sure the line number does not drift. + redo + call assert_equal(14, g:Xgetlist()[2].lnum) + undo + let l = g:Xgetlist() + call assert_equal(10, l[1].lnum) + call assert_equal(15, l[2].lnum) + + call g:Xsetlist([], 'f') + enew! + call delete(fname) +endfunc + +func Test_qf_undo_after_delete() + call setloclist(0, []) + call Xqf_undo_after_delete('c') + call setqflist([]) + call Xqf_undo_after_delete('l') +endfunc + " Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands func s:test_xgrep(cchar) call s:setup_commands(a:cchar) @@ -5004,6 +5051,34 @@ func Test_viscol() set efm& endfunc +" Test that '%v' is not affected by 'tabstop': a is always counted as +" 8 screen columns, matching the column numbers reported by compilers. +func Test_viscol_tabstop() + enew + call writefile(["\tABCDEFGH"], 'Xfile1', 'D') + edit Xfile1 + set efm=%f:%l:%v:%m + + " gcc reports column 9 for 'A' (the expands to 8 columns). The jump + " must land on 'A' (byte 2) for any 'tabstop' value. + for ts in [8, 4, 2, 13] + exe 'setlocal tabstop=' .. ts + cexpr "Xfile1:1:9:XX" + call assert_equal(2, col('.'), 'tabstop=' .. ts) + endfor + + " A multi-byte character after the tab: 'ä' is 2 bytes but 1 screen cell, + " so screen column 10 is the next character 'b' (byte 4). + call writefile(["\täbc"], 'Xfile1') + edit! Xfile1 + setlocal tabstop=4 + cexpr "Xfile1:1:10:XX" + call assert_equal(4, col('.')) + + enew | only + set efm& +endfunc + " Test for the quickfix window buffer func Xqfbuf_test(cchar) call s:setup_commands(a:cchar) @@ -7006,4 +7081,76 @@ func Test_quickfix_longline_noeol() call assert_equal(['okay'], readfile("XDONE")) endfunc +func Test_efm_overlongline() + let save_efm = &efm + " %r captures the tail. + set efm=%+O(%.%#)%r,%f:%l:%m + + " First line is longer than IOSIZE (1025) so the parser puts it in + " growbuf; the %r tail then far exceeds IObuff. + let lines = ['(short)' .. repeat('x', 4000), 'Xfile:10:msg'] + call writefile(lines, 'Xqferrlong', 'D') + + " Must complete without hanging or crashing. + cgetfile Xqferrlong + + " The well-formed line that follows is still parsed. + let well_formed = filter(getqflist(), 'v:val.lnum == 10') + call assert_equal(1, len(well_formed)) + call assert_equal('msg', well_formed[0].text) + + let &efm = save_efm + call setqflist([], 'f') +endfunc + +func Xtest_set_qftf_in_sandbox(cchar) + call s:setup_commands(a:cchar) + + call g:Xsetlist([{'filename': 'test.c', 'lnum': 1, 'text': 'trigger'}]) + let g:qftf_fn_called = v:false + func Qftf_Fn(d) + let g:qftf_fn_called = v:true + return [] + endfunc + + let g:caught_exception = v:false + try + sandbox call g:Xsetlist([], 'a', #{quickfixtextfunc: 'g:Qftf_Fn'}) + catch /E48:/ + let g:caught_exception = v:true + endtry + copen + cclose + + call assert_equal(v:true, g:caught_exception) + call assert_equal(v:false, g:qftf_fn_called) + + delfunc Qftf_Fn + unlet g:caught_exception + unlet g:qftf_fn_called + %bw! +endfunc + +" Test for setting the 'quickfixtextfunc' in a sandbox +func Test_set_qftf_in_sandbox() + call Xtest_set_qftf_in_sandbox('c') + call Xtest_set_qftf_in_sandbox('l') +endfunc + +" Test for the 'statusline' height remaining at one when the quickfix buffer +" is wiped out when quickfix window is the only window open. +func Test_qf_statusline_height() + %bw! + copen + wincmd p + let prev_wh = winheight('.') + wincmd p + only + bw! + copen + wincmd p + call assert_equal(prev_wh, winheight('.')) + %bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_recover.vim b/src/testdir/test_recover.vim index b36d23e18d..69caa89135 100644 --- a/src/testdir/test_recover.vim +++ b/src/testdir/test_recover.vim @@ -344,7 +344,21 @@ func Test_recover_corrupted_swap_file() call assert_fails('recover Xfile1', 'E312:') call assert_equal('Xfile1', @%) call assert_equal(['???MANY LINES MISSING'], getline(1, '$')) + bw! + " use an out-of-bounds db_txt_start in the data block (would cause OOB + " read past dp->db_index[] in ml_recover() without the bounds check) + let b = copy(save_b) + let b[8200:8203] = s:little_endian ? 0zFEFFFFFF : 0zFFFFFFFE + if s:system_64bit + let b[8208:8215] = 0z00FFFFFF.FFFFFF00 + else + let b[8208:8211] = 0z00FFFF00 + endif + call writefile(b, sn) + call assert_fails('recover Xfile1', 'E312:') + call assert_equal('Xfile1', @%) + call assert_match('??? block header corrupted', getline(1)) bw! call delete(sn) endfunc diff --git a/src/testdir/test_registers.vim b/src/testdir/test_registers.vim index 245340c82a..bb1dd31f3e 100644 --- a/src/testdir/test_registers.vim +++ b/src/testdir/test_registers.vim @@ -582,21 +582,41 @@ func Test_clipboard_regs_both_unnamed() bwipe! endfunc -" Test for restarting the current mode (insert or virtual replace) after +" Test for restarting the current mode (insert or (virtual) replace) after " executing the contents of a register -func Test_put_reg_restart_mode() +func Test_exec_reg_restart_mode() new - call append(0, 'editor') - normal gg + let @r = "ivim \" - call feedkeys("i\@r\=mode()\", 'xt') + + call setline(1, 'editor') + normal gg + call feedkeys("i\@r\=mode(1)\", 'xt') call assert_equal('vimi editor', getline(1)) call setline(1, 'editor') normal gg - call feedkeys("gR\@r\=mode()\", 'xt') + call feedkeys("R\@r\=mode(1)\", 'xt') call assert_equal('vimReditor', getline(1)) + call setline(1, 'editor') + normal gg + call feedkeys("gR\@r\=mode(1)\", 'xt') + call assert_equal('vimRvditor', getline(1)) + + " If the register doesn't return to Normal mode, Vim should stay in whatever + " mode the register ends up with, and should not insert extra text. #20085 + for [s0, expected] in + \ [['i', 'vim editor,i'], ['R', 'vim or,R'], ['gR', 'vim or,Rv']] + let @r = $"{s0}vim " + for s1 in ['i', 'R', 'gR'] + call setline(1, 'editor') + normal gg + call feedkeys($"{s1}\@r\,\=mode(1)\", 'xt') + call assert_equal(expected, getline(1)) + endfor + endfor + bwipe! endfunc diff --git a/src/testdir/test_remote.vim b/src/testdir/test_remote.vim index ad959e629c..9f23bb0ce1 100644 --- a/src/testdir/test_remote.vim +++ b/src/testdir/test_remote.vim @@ -16,18 +16,6 @@ func Verify_remote_feature_works() let buf = RunVimInTerminal('--servername XVIMTEST', {'rows': 8}) call TermWait(buf) - " For some reason when the socket server is being used, the terminal Vim never - " receives the `:w! XVimRemoteTest.txt` command from term_sendkeys. - if has('socketserver') && !has('X11') - if match(serverlist(), "XVIMTEST") == -1 - call StopVimInTerminal(buf) - throw s:skip - endif - - let s:remote = 1 - return - endif - let cmd = GetVimCommandCleanTerm() .. '--serverlist' call term_sendkeys(buf, ":r! " .. cmd .. "\") call TermWait(buf) @@ -71,6 +59,14 @@ func Test_remote_servername() " 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 XTEST.txt', {'rows': 5, 'wait_for_ruler': 0}) + + " It may take a while for the command to be sent to XVIMTEST and be executed. + " Do a blocking --remote-expr so that is assured the command was executed. + botright new + let buf3 = RunVimInTerminal('--servername XVIMTEST --remote-expr "v:servername"', {'rows': 5, 'wait_for_ruler': 0}) + call WaitForAssert({-> assert_equal("finished", term_getstatus(buf3))}) + exe buf3 .. 'bw!' + " job should be no-longer running, so we can just close it exe buf2 .. 'bw!' call term_sendkeys(buf, ":sil :3,$d\") diff --git a/src/testdir/test_restricted.vim b/src/testdir/test_restricted.vim index 2d8c8ce5f7..21133089ee 100644 --- a/src/testdir/test_restricted.vim +++ b/src/testdir/test_restricted.vim @@ -95,6 +95,7 @@ func Test_restricted_mode() if has('unix') call assert_fails('cd `pwd`', 'E145:') endif + call assert_fails("call setqflist([], 'a', {'id': 1, 'quickfixtextfunc': 'tr'})", 'E145:') call writefile(v:errors, 'Xresult') qa! @@ -220,4 +221,49 @@ func Test_restricted_cscope() call delete('XResult_cscope') endfunc +func Test_vim9_storeenv_sandbox() + let lines =<< trim END + vim9script + + function g:LegacySetEnv() + let $VIM_SANDBOX_TEST = 'legacy' + endfunc + + def Vim9SetEnv() + $VIM_SANDBOX_TEST = 'vim9_bypass' + enddef + + # Legacy path should be blocked by check_secure() + var legacy_blocked = false + try + legacy sandbox call LegacySetEnv() + catch /E48/ + legacy_blocked = true + endtry + assert_true(legacy_blocked, 'legacy $ENV assignment should be blocked in sandbox') + assert_false(exists('$VIM_SANDBOX_TEST')) + + # Vim9 path should also be blocked by check_secure() + var vim9_blocked = false + try + sandbox Vim9SetEnv() + catch /E48/ + vim9_blocked = true + endtry + assert_true(vim9_blocked, 'Vim9 ISN_STOREENV should be blocked in sandbox') + assert_false(exists('$VIM_SANDBOX_TEST')) + writefile([ + legacy_blocked, + vim9_blocked, + string(v:errors)], 'XResult_storeenv') + qa + END + call writefile(lines, 'Xtest_storeenv_sandbox.vim', 'D') + let expected = ['true', 'true', '[]'] + if RunVim([], [], '-u NONE -N -i NONE --not-a-term -S Xtest_storeenv_sandbox.vim') + call assert_equal(expected, readfile('XResult_storeenv')) + endif + call delete('XResult_storeenv') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim index 99fd32a009..6d4fc81b81 100644 --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -903,7 +903,7 @@ endfunc " skipcol should not reset when doing incremental search on the same word func Test_smoothscroll_incsearch() - CheckScreendump + CheckRunVimInTerminal let lines =<< trim END set smoothscroll number scrolloff=0 incsearch @@ -913,15 +913,24 @@ func Test_smoothscroll_incsearch() END call writefile(lines, 'XSmoothIncsearch', 'D') let buf = RunVimInTerminal('-S XSmoothIncsearch', #{rows: 8, cols: 40}) + let g:test_is_flaky = 1 call term_sendkeys(buf, "/b") - call VerifyScreenDump(buf, 'Test_smooth_incsearch_1', {}) + call WaitForAssert({-> assert_match('^/b\s*$', term_getline(buf, 8))}, 1000) + let view1 = map(range(1, 7), {_, i -> term_getline(buf, i)}) + call term_sendkeys(buf, "b") - call VerifyScreenDump(buf, 'Test_smooth_incsearch_2', {}) + call WaitForAssert({-> assert_match('^/bb\s*$', term_getline(buf, 8))}, 1000) + call assert_equal(view1, map(range(1, 7), {_, i -> term_getline(buf, i)})) + call term_sendkeys(buf, "b") - call VerifyScreenDump(buf, 'Test_smooth_incsearch_3', {}) + call WaitForAssert({-> assert_match('^/bbb\s*$', term_getline(buf, 8))}, 1000) + call assert_equal(view1, map(range(1, 7), {_, i -> term_getline(buf, i)})) + call term_sendkeys(buf, "b") - call VerifyScreenDump(buf, 'Test_smooth_incsearch_4', {}) + call WaitForAssert({-> assert_match('^/bbbb\s*$', term_getline(buf, 8))}, 1000) + call assert_equal(view1, map(range(1, 7), {_, i -> term_getline(buf, i)})) + call term_sendkeys(buf, "\") call StopVimInTerminal(buf) @@ -1439,4 +1448,707 @@ func Test_smoothscroll_listchars_eol() bwipe! endfunc +" scrolloffpad contract: +" - augment scrolloff only under EOF pressure (insufficient real lines below); +" - do not change explicit "z" viewport placement command semantics; +" - current scope is EOF-only, so BOF behavior remains unchanged. +func Test_scrolloffpad_zb_keeps_bottom_command_semantics() + new + resize 12 + setlocal scrolloff=10 + call setline(1, map(range(1, 300), 'printf("line %d", v:val)')) + + setlocal scrolloffpad=0 + normal! gg150Gzb + let baseline = [line('.'), line('w$'), winline()] + + setlocal scrolloffpad=1 + normal! gg150Gzb + call assert_equal(baseline, [line('.'), line('w$'), winline()]) + + bwipe! +endfunc + +func Test_scrolloffpad_zminus_keeps_bottom_beginline_semantics() + new + resize 12 + setlocal scrolloff=10 + call setline(1, map(range(1, 300), 'printf(" line %d", v:val)')) + + setlocal scrolloffpad=0 + normal! gg150Gz- + let baseline = [line('.'), line('w$'), winline(), col('.')] + call assert_equal(match(getline('.'), '\S') + 1, col('.')) + + setlocal scrolloffpad=1 + normal! gg150Gz- + call assert_equal(baseline, [line('.'), line('w$'), winline(), col('.')]) + call assert_equal(match(getline('.'), '\S') + 1, col('.')) + + bwipe! +endfunc + +func Test_scrolloffpad_zb_is_one_shot_then_scrolloff_reapplies() + new + resize 12 + setlocal scrolloff=10 + call setline(1, map(range(1, 300), 'printf("line %d", v:val)')) + + let after_zb = {} + let after_j = {} + for sop in [0, 1] + let &l:scrolloffpad = sop + normal! gg150Gzb + let after_zb[sop] = [line('.'), line('w$'), winline(), winsaveview().topline] + + normal! j + let after_j[sop] = [line('.'), line('w$'), winline(), winsaveview().topline] + call assert_notequal(after_zb[sop][3], after_j[sop][3]) + call assert_true(line('.') < line('w$')) + endfor + call assert_equal(after_zb[0], after_zb[1]) + call assert_equal(after_j[0], after_j[1]) + + bwipe! +endfunc + +func Test_scrolloffpad_has_no_mid_buffer_effect() + new + resize 12 + setlocal scrolloff=10 scrolloffpad=0 + call setline(1, map(range(1, 500), 'printf("line %d", v:val)')) + + normal! gg150G + let topline_without_pad = winsaveview().topline + + setlocal scrolloffpad=1 + normal! gg150G + let topline_with_pad = winsaveview().topline + + call assert_equal(topline_without_pad, topline_with_pad) + + bwipe! +endfunc + +func Test_scrolloffpad_changes_eof_pressure_only() + new + resize 12 + setlocal scrolloff=10 scrolloffpad=0 + call setline(1, map(range(1, 200), 'printf("line %d", v:val)')) + + normal! ggG + let view_without_pad = winsaveview() + let cursor_without_pad = line('.') + let row_without_pad = winline() + + setlocal scrolloffpad=1 + normal! ggG + let view_with_pad = winsaveview() + let row_with_pad = winline() + + call assert_equal(line('$'), line('.')) + call assert_equal(cursor_without_pad, line('.')) + call assert_notequal(view_without_pad.topline, view_with_pad.topline) + call assert_true(row_with_pad < row_without_pad) + + bwipe! +endfunc + +func Test_scrolloffpad_large_scrolloff_no_overflow() + new + resize 12 + call setline(1, map(range(1, 200), 'printf("line %d", v:val)')) + setlocal scrolloff=2147483647 scrolloffpad=0 + + normal! ggG + let view_without_pad = winsaveview() + let row_without_pad = winline() + + setlocal scrolloffpad=1 + normal! ggG + let view_with_pad = winsaveview() + let row_with_pad = winline() + + call assert_equal(line('$'), line('.')) + call assert_notequal(view_without_pad.topline, view_with_pad.topline) + call assert_true(row_with_pad < row_without_pad) + + bwipe! +endfunc + +func Test_scrolloffpad_boolean_gate_values() + new + resize 12 + setlocal scrolloff=10 + call setline(1, map(range(1, 200), 'printf("line %d", v:val)')) + + let views = {} + let rows = {} + for sop in [0, 1, 2] + let &l:scrolloffpad = sop + normal! ggG + let views[sop] = winsaveview() + let rows[sop] = winline() + call assert_equal(line('$'), line('.')) + endfor + + call assert_equal(views[1].topline, views[2].topline) + call assert_equal(rows[1], rows[2]) + call assert_notequal(views[0].topline, views[1].topline) + call assert_true(rows[1] < rows[0]) + + bwipe! +endfunc + +func Test_scrolloffpad_requires_scrolloff_nonzero() + new + resize 12 + call setline(1, map(range(1, 200), 'printf("line %d", v:val)')) + + let states = {} + for so in [0, 10] + let states[so] = {} + for sop in [0, 1] + let &l:scrolloff = so + let &l:scrolloffpad = sop + normal! ggG + let states[so][sop] = [line('.'), line('w0'), line('w$'), winline()] + call assert_equal(line('$'), line('.')) + endfor + endfor + + call assert_equal(states[0][0], states[0][1]) + call assert_notequal(states[10][0], states[10][1]) + call assert_true(states[10][1][3] < states[10][0][3]) + + bwipe! +endfunc + +func Test_scrolloffpad_search_to_eof() + new + resize 12 + setlocal scrolloff=10 + call setline(1, map(range(1, 200), 'printf("line %d", v:val)')) + call setline(line('$'), 'EOF TARGET') + + let states = {} + for sop in [0, 1] + let &l:scrolloffpad = sop + normal! gg + call assert_true(search('EOF TARGET') > 0) + let states[sop] = [line('.'), line('w0'), line('w$'), winline()] + call assert_equal(line('$'), line('.')) + endfor + + call assert_notequal(states[0], states[1]) + call assert_true(states[1][3] < states[0][3]) + + bwipe! +endfunc + +func Test_scrolloffpad_paging_to_eof() + new + resize 12 + setlocal scrolloff=10 + call setline(1, map(range(1, 240), 'printf("line %d", v:val)')) + + let states = {} + for sop in [0, 1] + let &l:scrolloffpad = sop + normal! gg + + let prev = -1 + for _ in range(1, 200) + execute "normal! \" + if line('.') == prev + break + endif + let prev = line('.') + endfor + + let states[sop] = [line('.'), line('w0'), line('w$'), winline()] + call assert_equal(line('$'), line('w$')) + endfor + + call assert_notequal(states[0], states[1]) + call assert_true(states[1][3] < states[0][3]) + + bwipe! +endfunc + +func Test_scrolloffpad_autocmd_append_at_eof() + let states = {} + for sop in [0, 1] + new + resize 12 + setlocal scrolloff=10 + let &l:scrolloffpad = sop + call setline(1, map(range(1, 120), 'printf("line %d", v:val)')) + + let b:scrolloffpad_appended = 0 + augroup ScrolloffpadAppendAtEof + autocmd! + autocmd CursorMoved if b:scrolloffpad_appended == 0 && line('.') == line('$') | call append('$', 'appended') | let b:scrolloffpad_appended = 1 | endif + augroup END + + normal! ggG + doautocmd CursorMoved + let states[sop] = [ + \ line('.'), + \ line('$'), + \ line('w0'), + \ line('w$'), + \ winline(), + \ b:scrolloffpad_appended, + \ ] + + call assert_equal(1, b:scrolloffpad_appended) + call assert_equal(states[sop][1] - 1, states[sop][0]) + + augroup ScrolloffpadAppendAtEof + autocmd! + augroup END + bwipe! + endfor + + call assert_notequal(states[0], states[1]) + call assert_true(states[1][4] < states[0][4]) + +endfunc + +func Test_scrolloffpad_eof_no_reverse_scroll_on_j() + new + resize 20 + setlocal scrolloff=20 scrolloffpad=1 + call setline(1, map(range(1, 80), 'printf("line %d", v:val)')) + + normal! gg + let prev_topline = winsaveview().topline + for lnum in range(2, line('$')) + normal! j + let cur_topline = winsaveview().topline + call assert_true( + \ cur_topline >= prev_topline, + \ printf('topline moved backwards at line %d: %d -> %d', + \ lnum, prev_topline, cur_topline)) + let prev_topline = cur_topline + endfor + + bwipe! +endfunc + +func Test_scrolloffpad_bof_unchanged() + new + resize 12 + setlocal scrolloff=10 scrolloffpad=0 + call setline(1, map(range(1, 200), 'printf("line %d", v:val)')) + + normal! Ggg + let view_without_pad = winsaveview() + let w0_without_pad = line('w0') + + setlocal scrolloffpad=1 + normal! Ggg + let view_with_pad = winsaveview() + let w0_with_pad = line('w0') + + call assert_equal(1, w0_without_pad) + call assert_equal(1, w0_with_pad) + call assert_equal(view_without_pad.topline, view_with_pad.topline) + + bwipe! +endfunc + +func Test_scrolloffpad_mouse_drag_uses_drag_scrolloff() + CheckFeature mouse + + let save_mouse = &mouse + set mouse=a + + new + resize 20 + call setline(1, map(range(1, 240), 'printf("line %d", v:val)')) + setlocal scrolloff=50 + + let after_drag = {} + for sop in [0, 1] + let &l:scrolloffpad = sop + normal! gg160Gzt + normal! v + call test_setmouse(2, 1) + call feedkeys("\", 'xt') + call test_setmouse(3, 1) + call feedkeys("\", 'xt') + let after_drag[sop] = [winsaveview().topline, line('.'), winline()] + call feedkeys("\", 'xt') + endfor + + call assert_equal(after_drag[0], after_drag[1]) + + bwipe! + let &mouse = save_mouse +endfunc + +func Test_scrolloffpad_basic() + CheckScreendump + CheckRunVimInTerminal + + let save_termwinsize = &termwinsize + set termwinsize= + + let lines =<< trim END + set scrolloff=10 + set scrolloffpad=5 + enew! + call setline(1, map(range(1, 100), 'printf("line %d", v:val)')) + normal! gg + END + call writefile(lines, 'XScrolloffpadBasic', 'D') + + let buf = RunVimInTerminal('-S XScrolloffpadBasic', {'rows': 20, 'cols': 78}) + + " Enabled: scrolloffpad > 0, expect EOF centering/padding + call term_sendkeys(buf, "\:\normal! G\") + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_scrolloffpad_basic_1', {}) + + " Beginning-of-file is unchanged (Top) + call term_sendkeys(buf, "\:\normal! gg\") + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_scrolloffpad_basic_2', {}) + + " Gating: disable scrolloffpad, then go to EOF again + " Expect normal EOF behavior (no extra centering/padding) + call term_sendkeys(buf, "\:\set scrolloffpad=0\") + call term_sendkeys(buf, "\:\normal! G\") + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_scrolloffpad_basic_3', {}) + + call StopVimInTerminal(buf) + let &termwinsize = save_termwinsize +endfunc + +func Test_scrolloffpad_smoothscroll() + CheckScreendump + CheckRunVimInTerminal + + let save_termwinsize = &termwinsize + set termwinsize= + + let lines =<< trim END + set smoothscroll scrolloff=10 scrolloffpad=1 + enew! + call setline(1, map(range(1, 100), 'printf("line %d", v:val)')) + normal! gg + END + call writefile(lines, 'XScrolloffpadSmoothscroll', 'D') + + let buf = RunVimInTerminal('-S XScrolloffpadSmoothscroll', #{rows: 20, cols: 78}) + + call term_sendkeys(buf, "\:\normal! G\") + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_scrolloffpad_smoothscroll_1', {}) + + call term_sendkeys(buf, "\:\call setline(line('$'), repeat('LONG ', 30))\") + call term_sendkeys(buf, "\:\normal! 41|\") + call term_sendkeys(buf, "\") + call TermWait(buf) + call VerifyScreenDump(buf, 'Test_scrolloffpad_smoothscroll_2', {}) + + call StopVimInTerminal(buf) + let &termwinsize = save_termwinsize +endfunc + +func Test_scrolloffpad_insert_eof() + let save_so = &scrolloff + let save_sop = &scrolloffpad + + set scrolloff=10 scrolloffpad=1 + enew! + call setline(1, map(range(1, 200), 'printf("line %d", v:val)')) + normal! G + + let topline_before = winsaveview().topline + call feedkeys("i\", 'xt') + call assert_equal(topline_before, winsaveview().topline) + + exe "normal! \" + let topline_after = winsaveview().topline + call feedkeys("i\", 'xt') + call assert_equal(topline_after, winsaveview().topline) + + let &scrolloff = save_so + let &scrolloffpad = save_sop + bwipe! +endfunc + +func Test_scrolloffpad_in_diff_mode() + CheckFeature diff + + let save_so = &scrolloff + let save_sop = &scrolloffpad + let save_splitright = &splitright + + set nosplitright + set scrolloff=10 + set scrolloffpad=0 + + enew + call setline(1, map(range(1, 100), {_, v -> 'line ' .. v})) + diffthis + + vnew + call setline(1, map(range(1, 100), {_, v -> 'line ' .. v})) + " Make buffers minimally different to avoid diff folding everything. + call setline(50, 'DIFF LINE 50') + diffthis + + windo normal! zR + windo normal! gg + wincmd = + + let rows_without = [] + let rows_with = [] + let near_states = [] + let eof_states = [] + for sop in [0, 1] + let &scrolloffpad = sop + + " Near EOF with real text visible in both windows. + windo normal! 99G + for w in range(1, winnr('$')) + execute w .. 'wincmd w' + let state = [line('.'), line('w0'), line('w$'), winline()] + call assert_equal(99, state[0]) + call assert_equal(100, state[2]) + if sop == 0 + call add(near_states, state) + endif + endfor + call assert_equal(near_states[0], near_states[1]) + + " EOF in both windows: scrolloffpad should raise the cursor row. + windo normal! G + for w in range(1, winnr('$')) + execute w .. 'wincmd w' + let state = [line('.'), line('w0'), line('w$'), winline()] + call assert_equal(line('$'), state[0]) + if sop == 0 + call add(eof_states, state) + call add(rows_without, state[3]) + else + call add(rows_with, state[3]) + endif + endfor + call assert_equal(eof_states[0], eof_states[1]) + endfor + + call assert_true(rows_with[0] < rows_without[0]) + call assert_true(rows_with[1] < rows_without[1]) + + windo diffoff + %bwipe! + let &scrolloff = save_so + let &scrolloffpad = save_sop + let &splitright = save_splitright +endfunc + +func Test_scrolloffpad_diff_eof_filler_behavior() + CheckFeature diff + + let save_so = &scrolloff + let save_sop = &scrolloffpad + let save_diffopt = &diffopt + let save_splitright = &splitright + + set diffopt+=filler + set scrolloff=10 + set scrolloffpad=0 + set nosplitright + + 20new + call setline(1, map(range(1, 100), {_, v -> 'left ' .. v})) + diffthis + let short_wid = win_getid() + + vnew + call setline(1, map(range(1, 120), {_, v -> 'right ' .. v})) + diffthis + let long_wid = win_getid() + + call assert_true(win_gotoid(short_wid)) + let short_height = winheight(0) + call assert_true(win_gotoid(long_wid)) + let long_height = winheight(0) + call assert_equal(short_height, long_height) + call assert_equal(20, short_height) + + let ordered_diff_wids = [long_wid, short_wid] + let states = {} + for sop in [0, 1] + execute 'set scrolloffpad=' .. sop + for wid in ordered_diff_wids + call assert_true(win_gotoid(wid)) + normal! gg + endfor + for wid in ordered_diff_wids + call assert_true(win_gotoid(wid)) + normal! G + endfor + + call assert_true(win_gotoid(short_wid)) + let short_view = winsaveview() + let short_state = [ + \ line('.'), + \ line('$'), + \ winline(), + \ short_view.topline, + \ short_view.topfill, + \ diff_filler(line('$') + 1), + \ ] + call assert_equal(short_state[1], short_state[0]) + call assert_true(short_state[5] > 0) + + call assert_true(win_gotoid(long_wid)) + let long_view = winsaveview() + let long_state = [ + \ line('.'), + \ line('$'), + \ winline(), + \ long_view.topline, + \ long_view.topfill, + \ ] + call assert_true(long_state[0] > 0 && long_state[0] <= long_state[1]) + call assert_equal(short_state[0], long_state[0]) + + let states[sop] = [short_state, long_state] + endfor + + let short_without = states[0][0] + let short_with = states[1][0] + " Environment/layout can shift direction of movement; require only that + " scrolloffpad changes the short-window viewport state under EOF filler. + call assert_true(short_with[2] != short_without[2] + \ || short_with[3] != short_without[3] + \ || short_with[4] != short_without[4]) + + windo diffoff + call assert_true(win_gotoid(short_wid)) + only! + %bwipe! + let &scrolloff = save_so + let &scrolloffpad = save_sop + let &diffopt = save_diffopt + let &splitright = save_splitright +endfunc + +func Test_scrolloffpad_with_folds() + CheckRunVimInTerminal + CheckFeature folding + let g:test_is_flaky = 1 + + let save_termwinsize = &termwinsize + set termwinsize= + + let lines =<< trim END + set scrolloff=10 + set scrolloffpad=1 + + enew + call setline(1, map(range(1, 120), {_, v -> 'line ' . v})) + + " Create a large fold near the end of the file. + " Fold lines 60-110, leaving 111-120 visible after the fold. + set foldmethod=manual + set foldenable + normal! gg + normal! 60G + normal! zf50j + normal! gg + END + call writefile(lines, 'XScrolloffpadFolds', 'D') + + let buf = RunVimInTerminal('-S XScrolloffpadFolds', #{rows: 20, cols: 78}) + + " Case 1: Jump to end-of-file. + " With folds present, scrolloffpad should still keep the cursor positioned + " with padding below EOF. + call term_sendkeys(buf, "\:\normal! G\") + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_equal('line 120', trim(term_getline(buf, 10)))}, + \ 1000) + call assert_equal('line 111', trim(term_getline(buf, 1))) + call assert_equal('line 119', trim(term_getline(buf, 9))) + call assert_equal('~', trim(term_getline(buf, 11))) + call assert_match('120,1\s\+Bot', term_getline(buf, 20)) + + " Case 2: Move to the folded line to ensure the fold is actually in view. + call term_sendkeys(buf, "\:\normal! 60G\") + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_match('^\s*+-- 51 lines: line 60--', + \ term_getline(buf, 10))}, 1000) + call assert_equal('line 51', trim(term_getline(buf, 1))) + call assert_equal('line 59', trim(term_getline(buf, 9))) + call assert_equal('line 111', trim(term_getline(buf, 11))) + call assert_equal('line 119', trim(term_getline(buf, 19))) + call assert_match('60,1\s\+98%', term_getline(buf, 20)) + + " Case 3: Close the fold explicitly and go to EOF again. + " Behavior should remain stable with closed folds. + call term_sendkeys(buf, "\:\normal! zc\") + call term_sendkeys(buf, "\:\normal! G\") + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_equal('line 120', trim(term_getline(buf, 10)))}, + \ 1000) + call assert_equal('line 111', trim(term_getline(buf, 1))) + call assert_equal('line 119', trim(term_getline(buf, 9))) + call assert_equal('~', trim(term_getline(buf, 11))) + call assert_match('120,1\s\+Bot', term_getline(buf, 20)) + + call StopVimInTerminal(buf) + let &termwinsize = save_termwinsize +endfunc + +" Resizing to "textoff" after 'smoothscroll' skips part of a wrapped line must +" not crash. +func Test_smoothscroll_textoff_showbreak() + CheckOption smoothscroll + CheckRunVimInTerminal + + let donefile = 'XTest_crash_textoff_showbreak_done' + defer delete(donefile) + let lines =<< trim END + set noswapfile + + set scrolloff=0 + set lines=12 columns=40 + + call setline(1, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') + set number wrap smoothscroll showbreak=> + vsplit + + let textoff = getwininfo(win_getid())[0].textoff + execute "normal! 0\" + redraw + execute 'vertical resize' textoff + redraw + call writefile(['done'], 'XTest_crash_textoff_showbreak_done') + END + call writefile(lines, 'XTest_crash_textoff_showbreak', 'D') + + let buf = 0 + let buf = term_start([GetVimProg(), '--clean'], #{term_rows: 24, term_cols: 80}) + call TermWait(buf, 200) + call term_sendkeys(buf, ":source XTest_crash_textoff_showbreak\") + call WaitForAssert({-> assert_true(filereadable(donefile))}) + let status = term_getstatus(buf) + call assert_equal('running', status) + call assert_true(filereadable(donefile)) + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim index 725d08b59a..c4178fdece 100644 --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -700,6 +700,27 @@ func Test_search_cmdline7() call feedkeys("//e\\", 'tx') call assert_equal('1 bbvimb', getline('.')) call assert_equal(4, col('.')) + call cursor(1, 1) + call feedkeys("//+1\\", 'tx') + call assert_equal(' 2 bbvimb', getline('.')) + call assert_equal([0, 2, 1, 0], getpos('.')) + call setline(1, 'blah blah blah') + call feedkeys("gg0/blah/e\\", 'tx') + call assert_equal([0, 1, 9, 0], getpos('.')) + call feedkeys("gg0/blah/e\\\", 'tx') + call assert_equal([0, 1, 14, 0], getpos('.')) + call feedkeys("gg0/blah/e\\\\", 'tx') + call assert_equal([0, 1, 9, 0], getpos('.')) + call cursor(1, col('$')) + call feedkeys("?blah?e\\", 'tx') + call assert_equal([0, 1, 9, 0], getpos('.')) + call feedkeys("gg0/blah/e+1\\", 'tx') + call assert_equal([0, 1, 10, 0], getpos('.')) + call feedkeys("gg0/blah/e-2\\", 'tx') + call assert_equal([0, 1, 7, 0], getpos('.')) + call setline(1, 'a/b a/b a/b') + call feedkeys("gg0/a\\/b/e\\", 'tx') + call assert_equal([0, 1, 7, 0], getpos('.')) set noincsearch call test_override("char_avail", 0) @@ -1032,6 +1053,7 @@ func Test_hlsearch_and_visual() \ ], 'Xhlvisual_script', 'D') let buf = RunVimInTerminal('-S Xhlvisual_script', {'rows': 6, 'cols': 40}) call term_sendkeys(buf, "vjj") + call WaitForAssert({-> assert_match('VISUAL.*-\d', term_getline(buf, 6))}, 1000) call VerifyScreenDump(buf, 'Test_hlsearch_visual_1', {}) call term_sendkeys(buf, "\") @@ -2179,6 +2201,7 @@ func Test_incsearch_highlighting_newline() [CODE] call writefile(commands, 'Xincsearch_nl', 'D') let buf = RunVimInTerminal('-S Xincsearch_nl', {'rows': 5, 'cols': 10}) + call TermWait(buf, 100) call term_sendkeys(buf, '/test') call VerifyScreenDump(buf, 'Test_incsearch_newline1', {}) " Need to send one key at a time to force a redraw diff --git a/src/testdir/test_search_stat.vim b/src/testdir/test_search_stat.vim index b2a81070b6..59d21c4e74 100644 --- a/src/testdir/test_search_stat.vim +++ b/src/testdir/test_search_stat.vim @@ -411,16 +411,23 @@ func Test_search_stat_and_incsearch() call writefile(lines, 'Xsearchstat_inc', 'D') let buf = RunVimInTerminal('-S Xsearchstat_inc', #{rows: 10}) + call TermWait(buf, 100) call term_sendkeys(buf, "/abc") call TermWait(buf) + " The first 3 chars on line 2 should have highlighting, but the following not + " So assert the attr value of those 4 chars + call WaitForAssert({-> assert_true( + \ term_scrape(buf, 2)[0].attr == term_scrape(buf, 2)[1].attr && + \ term_scrape(buf, 2)[1].attr == term_scrape(buf, 2)[2].attr && + \ term_scrape(buf, 2)[2].attr != term_scrape(buf, 2)[3].attr)}, 1000) call VerifyScreenDump(buf, 'Test_searchstat_inc_1', {}) call term_sendkeys(buf, "\") - call TermWait(buf) + call WaitForAssert({-> assert_match('^3', term_getline(buf, 1))}, 1000) call VerifyScreenDump(buf, 'Test_searchstat_inc_2', {}) call term_sendkeys(buf, "\") - call TermWait(buf) + call WaitForAssert({-> assert_match('^1', term_getline(buf, 1))}, 1000) call VerifyScreenDump(buf, 'Test_searchstat_inc_3', {}) call term_sendkeys(buf, "\:qa\") diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim index 58a2d58707..3b7f727d80 100644 --- a/src/testdir/test_spell.vim +++ b/src/testdir/test_spell.vim @@ -912,7 +912,10 @@ func Test_spellsuggest_too_deep() " This was incrementing "depth" over MAXWLEN. new norm s000G00ũ000000000000 - sil norm ..vzG................vvzG0 v z= + try + sil norm ..vzG................vvzG0 v z= + catch /E759:/ + endtry bwipe! endfunc diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim index b72974ed07..07156818d9 100644 --- a/src/testdir/test_spellfile.vim +++ b/src/testdir/test_spellfile.vim @@ -334,6 +334,10 @@ func Test_spellfile_format_error() " SN_COMPOUND: incorrect comppatlen call Spellfile_Test(0z080000000007040101000000020165, 'E758:') + " SN_COMPOUND: oversized sectionlen + let v = eval('0z08004000000803010161' .. repeat('61', 50) .. 'FF') + call Spellfile_Test(v, 'E759:') + " SN_INFO: missing info call Spellfile_Test(0z0F0000000005040101, '') @@ -368,6 +372,24 @@ func Test_spellfile_format_error() " LWORDTREE: incorrect sibling node count call Spellfile_Test(0zFF00000001040000000000000000, 'E759:') + " LWORDTREE: declared nodecount larger than the tree actually fills. + " Root has two siblings: 'x' (recurses into an end-of-word at idx 3..4) + " and BY_INDEX targeting position 9. Tree fills positions 0..4, leaving + " 5..9 unwritten — byts[9] would be uninitialized without the fix. + call Spellfile_Test(0zFF0000000A02780100000979010000000000000000000000, 'E759:') + + " LWORDTREE: recursion depth past MAXWLEN. A linear chain of 254 + " (siblingcount=1, byte='a') frames drives read_tree_node to depth + " MAXWLEN where the new guard rejects. The trailing (01 00) gives the + " chain a clean end-of-word so an *unguarded* parser would accept the + " file silently — that's what makes this a meaningful regression test + " for the depth check specifically (a deeper chain would also crash + " unguarded builds via stack overflow, which we don't want in CI). + let v = eval('0zFF00000200' .. repeat('0161', 255) + \ .. '0100' .. repeat('00', 8)) + + call Spellfile_Test(v, 'E759:') + " KWORDTREE: missing tree node call Spellfile_Test(0zFF0000000000000004, 'E758:') @@ -1165,5 +1187,64 @@ func Test_mkspell_empty_dic() call delete('XtestEmpty.spl') endfunc +" This used to cause a buffer overflow +func Test_mkspell_no_buffer_overflow() + CheckNotMSWindows + + let aff_lines = ['SET ISO8859-1', 'SFX A Y 1', + \ 'SFX A 0 s ' .. repeat(nr2char(0xff), 491)] + call writefile(aff_lines, 'Xbof.aff', 'D') + call writefile(['1', 'word/A'], 'Xbof.dic', 'D') + " Must not crash; ignore any conversion/regex errors. + try + mkspell! Xbof.spl Xbof + catch + endtry + defer delete('Xbof.spl') + + let long = repeat(nr2char(0xff), 200) + let aff2_lines = ['SET ISO8859-1', 'SFX A Y 1', + \ 'SFX A 0 ' .. long .. ' .'] + call writefile(aff2_lines, 'Xbof2.aff', 'D') + call writefile(['1', long .. '/A'], 'Xbof2.dic', 'D') + try + mkspell! Xbof2.spl Xbof2 + catch + endtry + defer delete('Xbof2.spl') +endfunc + +func Test_mkspell_no_affixlist_overflow() + let aff_lines = [ + \ 'SET ISO8859-1', + \ 'PFXPOSTPONE', + \ 'PFX A Y 1', + \ 'PFX A 0 pre .', + \ ] + call writefile(aff_lines, 'Xaffbof.aff', 'D') + call writefile(['1', 'word/' .. repeat('A', 300)], 'Xaffbof.dic', 'D') + + call assert_fails('mkspell! Xaffbof.spl Xaffbof', + \ 'Too many postponed prefixes and/or compound flags') + call assert_false(filereadable('Xaffbof.spl')) +endfunc + +func Test_mkspell_no_compflag_overflow() + " Overflow the compound-flag path in get_compflags(): a word whose + " affix list repeats a compound flag many times accumulates one ID per + " occurrence, overrunning store_afflist[MAXWLEN]. + let aff_lines = [ + \ 'SET ISO8859-1', + \ 'COMPOUNDFLAG c', + \ ] + call writefile(aff_lines, 'Xcompbof.aff', 'D') + + " Repeat the compound flag 'c' far past MAXWLEN. + call writefile(['1', 'word/' .. repeat('c', 300)], 'Xcompbof.dic', 'D') + + call assert_fails('mkspell! Xcompbof.spl Xcompbof', + \ 'Too many postponed prefixes and/or compound flags') + call assert_false(filereadable('Xcompbof.spl')) +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 8400105e21..fc7d18d2d7 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -637,7 +637,7 @@ func Test_invalid_args() endfor endif - if has('gui_gtk') + if has('gui_gtk') && has("xterm_clipboard") let out = split(system(GetVimCommand() .. ' --display'), "\n") call assert_equal(1, v:shell_error) call assert_match('^VIM - Vi IMproved .* (.*)$', out[0]) diff --git a/src/testdir/test_statusline.vim b/src/testdir/test_statusline.vim index 174c1a4754..48c7bb6696 100644 --- a/src/testdir/test_statusline.vim +++ b/src/testdir/test_statusline.vim @@ -282,6 +282,16 @@ func Test_statusline() call assert_match('^vimLineComment\s*$', s:get_statusline()) syntax off + " %0{: result of expression is inserted verbatim + set statusline=%{'\ x'} + call assert_match('^x\s*$', s:get_statusline()) + set statusline=%0{'\ x'} + call assert_match('^ x\s*$', s:get_statusline()) + set statusline=%{'000'} + call assert_match('^0\s*$', s:get_statusline()) + set statusline=%0{'000'} + call assert_match('^000\s*$', s:get_statusline()) + "%{%expr%}: evaluates expressions present in result of expr func! Inner_eval() return '%n some other text' @@ -721,4 +731,297 @@ func Test_statusline_singlebyte_negative() let [&columns, &ls, &stl, &enc] = [_columns, _ls, _stl, _enc] endfunc +func g:StlClickTestFunc(info) + let g:stl_click_info = a:info + return 0 +endfunc + +func g:StlClickReturn1(info) + let g:stl_click_info = a:info + return 1 +endfunc + +func Test_statusline_click_handler() + let save_mouse = &mouse + let save_stl = &statusline + let save_ls = &laststatus + set mouse=a + set laststatus=2 + + " Basic click handler + set statusline=%[StlClickTestFunc][Click]%[]\ %f + redraw! + + " Click on the [Click] region + let stl_row = win_screenpos(0)[0] + winheight(0) + call test_setmouse(stl_row, 2) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal('l', g:stl_click_info.button) + call assert_equal(1, g:stl_click_info.nclicks) + call assert_equal(0, g:stl_click_info.minwid) + call assert_equal(win_getid(), g:stl_click_info.winid) + call assert_equal('statusline', g:stl_click_info.area) + unlet! g:stl_click_info + + " Click outside click region (on the filename part) + call test_setmouse(stl_row, 20) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_false(exists('g:stl_click_info')) + + " Test with minwid + set statusline=%42[StlClickTestFunc][Click]%[]\ %f + redraw! + call test_setmouse(stl_row, 2) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal(42, g:stl_click_info.minwid) + unlet! g:stl_click_info + + " Test middle click + call test_setmouse(stl_row, 2) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal('m', g:stl_click_info.button) + unlet! g:stl_click_info + let &mouse = save_mouse + let &statusline = save_stl + let &laststatus = save_ls +endfunc + +func Test_statusline_click_multiple_regions() + let save_mouse = &mouse + let save_stl = &statusline + let save_ls = &laststatus + set mouse=a + set laststatus=2 + + " Two adjacent click regions with different minwid + set statusline=%1[StlClickTestFunc][AAA]%[]%2[StlClickTestFunc][BBB]%[] + redraw! + + let stl_row = win_screenpos(0)[0] + winheight(0) + + " Click on [AAA] region (col 2) + call test_setmouse(stl_row, 2) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal(1, g:stl_click_info.minwid) + unlet! g:stl_click_info + + " Click on [BBB] region (col 7) + call test_setmouse(stl_row, 7) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal(2, g:stl_click_info.minwid) + unlet! g:stl_click_info + + let &mouse = save_mouse + let &statusline = save_stl + let &laststatus = save_ls +endfunc + +" Click on a region in any row of a multi-line statusline (issue #20116). +func Test_statusline_click_multiline() + let save_mouse = &mouse + let save_stl = &statusline + let save_ls = &laststatus + let save_stlo = &statuslineopt + set mouse=a + set laststatus=2 + + " First row contains the click region, second row is filled with fillchar. + set statusline=%[StlClickTestFunc][Click]%[]%@\ \ \ \ + set statuslineopt=maxheight:2,fixedheight + redraw! + + let stl_row = win_screenpos(0)[0] + winheight(0) + + " Click on [Click] in the first row of the multi-line statusline. + call test_setmouse(stl_row, 2) + call feedkeys("\\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal(0, g:stl_click_info.minwid) + unlet! g:stl_click_info + + " A click region on the second row should also be recognized. + set statusline=row1%@%2[StlClickTestFunc][Click2]%[] + redraw! + call test_setmouse(stl_row + 1, 2) + call feedkeys("\\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal(2, g:stl_click_info.minwid) + unlet! g:stl_click_info + + let &mouse = save_mouse + let &statusline = save_stl + let &laststatus = save_ls + let &statuslineopt = save_stlo +endfunc + +func Test_statusline_click_region_extends_to_end() + let save_mouse = &mouse + let save_stl = &statusline + let save_ls = &laststatus + set mouse=a + set laststatus=2 + + " Click region without %[] extends to end of statusline + set statusline=xxx%[StlClickTestFunc]Clickable + redraw! + + let stl_row = win_screenpos(0)[0] + winheight(0) + + " Click near the end of the statusline + call test_setmouse(stl_row, 15) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_true(exists('g:stl_click_info')) + unlet! g:stl_click_info + + " Click on "xxx" (before the click region) + call test_setmouse(stl_row, 1) + call feedkeys("\", 'xt') + call feedkeys("\", 'xt') + call assert_false(exists('g:stl_click_info')) + + let &mouse = save_mouse + let &statusline = save_stl + let &laststatus = save_ls +endfunc + +func Test_statusline_click_option_validation() + " Valid formats should not produce errors + let save_stl = &statusline + set statusline=%[Func]text%[] + set statusline=%3[Func]text%[] + set statusline=%[Func]text + set statusline=%[Func_Name]text%[] + " %@ alone is still valid (line break) + set statusline=%@ + let &statusline = save_stl +endfunc + +func Test_statusline_click_linebreak_still_works() + " Ensure %@ without FuncName still works as line break + let save_stl = &statusline + let save_ls = &laststatus + set laststatus=2 + + " This should not error - %@ is line break + set statusline=line1%@line2 + redraw! + + let &statusline = save_stl + let &laststatus = save_ls +endfunc + +func Test_tabline_click_handler() + let save_mouse = &mouse + let save_tal = &tabline + let save_stal = &showtabline + if has('gui') + let save_go = &guioptions + set guioptions-=e + endif + set mouse=a + set showtabline=2 + + " Two adjacent click regions in 'tabline' with different minwid. + set tabline=%1[StlClickTestFunc][AAA]%[]%2[StlClickTestFunc][BBB]%[] + redraw! + + " Click on [AAA] region (tabline is row 1). + call test_setmouse(1, 2) + call feedkeys("\\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal('l', g:stl_click_info.button) + call assert_equal(1, g:stl_click_info.nclicks) + call assert_equal(1, g:stl_click_info.minwid) + " winid is 0 for tabline clicks (no associated window). + call assert_equal(0, g:stl_click_info.winid) + call assert_equal('tabline', g:stl_click_info.area) + unlet! g:stl_click_info + + " Click on [BBB] region. + call test_setmouse(1, 7) + call feedkeys("\\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal(2, g:stl_click_info.minwid) + unlet! g:stl_click_info + + " Middle click on [AAA]. + call test_setmouse(1, 2) + call feedkeys("\\", 'xt') + call assert_true(exists('g:stl_click_info')) + call assert_equal('m', g:stl_click_info.button) + unlet! g:stl_click_info + + " Click outside any %[...] region: no callback, no error. + set tabline=xxx%1[StlClickTestFunc][YYY]%[] + redraw! + call test_setmouse(1, 1) + call feedkeys("\\", 'xt') + call assert_false(exists('g:stl_click_info')) + + let &mouse = save_mouse + let &tabline = save_tal + let &showtabline = save_stal + if has('gui') + let &guioptions = save_go + endif +endfunc + +func Test_statusline_empty() + set laststatus=2 statusline=%!'%{}%' + try + redraw! + catch + endtry + set laststatus& + set statusline& +endfunc + +func Test_statusline_vsep_borrow_hl() + CheckScreendump + + " borrow_stl_vsep_hl(): vsep cells adjacent to a status line should + " borrow the highlight of the neighbouring window's status line edge so + " that custom highlights flow into the separator column. + " - vsep next to curwin: curwin's edge hl is borrowed. + " - vsep between two non-current windows: the left window's right-edge + " hl is borrowed when the status fillchar is a space. + let lines =<< trim END + hi User1 ctermfg=Red ctermbg=Yellow + hi User2 ctermfg=Blue ctermbg=Green + set laststatus=2 + set statusline=%1*L%=%2*R + vsplit + vsplit + vsplit + " curwin is now the leftmost window; move to the second one so the + " layout becomes: NC | cur | NC | NC. + 2wincmd w + END + call writefile(lines, 'XTest_statusline_vsep_borrow_hl', 'D') + + let buf = RunVimInTerminal('-S XTest_statusline_vsep_borrow_hl', + \ {'rows': 6, 'cols': 78}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_statusline_vsep_borrow_hl_01', {}) + + " Move curwin to the third window: NC | NC | cur | NC. + " Now the leftmost vsep is between two non-current windows. + call term_sendkeys(buf, "\l\") + call VerifyScreenDump(buf, 'Test_statusline_vsep_borrow_hl_02', {}) + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_statuslineopt.vim b/src/testdir/test_statuslineopt.vim index 6454dbff87..653529e356 100644 --- a/src/testdir/test_statuslineopt.vim +++ b/src/testdir/test_statuslineopt.vim @@ -235,6 +235,35 @@ func Test_multistatusline_highlight() call StopVimInTerminal(buf) endfunc +func Test_multistatusline_carry_hl() + CheckScreendump + + " %#XX# / %N* set on one row should persist on subsequent rows until %* + " (or another %# / %*) changes it. + let lines =<< trim END + func MyStatusLine() + return 'L1A%=%#Search#L1B%@' + \ .. 'L2 carried Search%@' + \ .. '%*L3 reset%@' + \ .. '%2*L4 user2%@' + \ .. 'L5 carried user2%@' + \ .. '%*L6 reset' + endfunc + + hi User2 ctermfg=Yellow ctermbg=Blue + set laststatus=2 + set statuslineopt=maxheight:6 + set statusline=%!MyStatusLine() + END + call writefile(lines, 'XTest_multistatusline_carry_hl', 'D') + + let buf = g:RunVimInTerminal('-S XTest_multistatusline_carry_hl', {'rows': 9}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_multistatusline_carry_hl_01', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_statuslineopt_default_stl() CheckScreendump diff --git a/src/testdir/test_tabline.vim b/src/testdir/test_tabline.vim index 21f66cfcde..7ae0602489 100644 --- a/src/testdir/test_tabline.vim +++ b/src/testdir/test_tabline.vim @@ -250,4 +250,14 @@ func Test_tabline_mouse_enable() endfor endfunc +func Test_tabline_empty() + set showtabline=2 tabline=%!'%{}%' + try + redraw! + catch + endtry + set showtabline& + set tabline& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_tabpanel.vim b/src/testdir/test_tabpanel.vim index f983e2b37d..3b5fe390f4 100644 --- a/src/testdir/test_tabpanel.vim +++ b/src/testdir/test_tabpanel.vim @@ -249,6 +249,76 @@ function Test_tabpanel_mouse() let &showtabline = save_showtabline endfunc +func g:TplClickTestFunc(info) + let g:tpl_click_info = a:info + return 0 +endfunc + +function Test_tabpanel_click_handler() + let save_mouse = &mouse + let save_stal = &showtabline + let save_stpl = &showtabpanel + let save_tpl = &tabpanel + let save_tplo = &tabpanelopt + set mouse=a + set showtabline=0 + set showtabpanel=2 + set tabpanelopt=columns:16 + tabnew + tabnew + + " Place two adjacent %[FuncName] regions on every tab label. + set tabpanel=%1[TplClickTestFunc][A]%[]%2[TplClickTestFunc][B]%[] + redraw! + + " Click on [A] region in the first tab label (row 1). + call test_setmouse(1, 2) + call feedkeys("\\", 'xt') + call assert_true(exists('g:tpl_click_info')) + call assert_equal('l', g:tpl_click_info.button) + call assert_equal(1, g:tpl_click_info.nclicks) + call assert_equal(1, g:tpl_click_info.minwid) + call assert_equal(0, g:tpl_click_info.winid) + call assert_equal('tabpanel', g:tpl_click_info.area) + call assert_equal(1, g:tpl_click_info.tabnr) + unlet! g:tpl_click_info + + " Click on [B] region in the second tab label (row 2). + call test_setmouse(2, 5) + call feedkeys("\\", 'xt') + call assert_true(exists('g:tpl_click_info')) + call assert_equal(2, g:tpl_click_info.minwid) + call assert_equal(2, g:tpl_click_info.tabnr) + unlet! g:tpl_click_info + + " Middle click on [A] in tab 3. + call test_setmouse(3, 2) + call feedkeys("\\", 'xt') + call assert_true(exists('g:tpl_click_info')) + call assert_equal('m', g:tpl_click_info.button) + call assert_equal(1, g:tpl_click_info.minwid) + call assert_equal(3, g:tpl_click_info.tabnr) + unlet! g:tpl_click_info + + " A click outside any region (but still in the panel) must not fire the + " callback, and should fall through to the normal tab selection. + set tabpanel=xxx%1[TplClickTestFunc][Y]%[] + redraw! + tabfirst + call test_setmouse(2, 1) + call feedkeys("\\", 'xt') + call assert_false(exists('g:tpl_click_info')) + call assert_equal(2, tabpagenr()) + + tabonly! + call s:reset() + let &tabpanel = save_tpl + let &tabpanelopt = save_tplo + let &showtabpanel = save_stpl + let &showtabline = save_stal + let &mouse = save_mouse +endfunc + function Test_tabpanel_drawing() CheckScreendump @@ -302,7 +372,7 @@ function Test_tabpanel_drawing_2() END call writefile(lines, 'XTest_tabpanel_drawing_2', 'D') - let buf = RunVimInTerminal('-S XTest_tabpanel_drawing_2', {'rows': 10, 'cols': 78}) + let buf = RunVimInTerminal('-S XTest_tabpanel_drawing_2', {'rows': 10, 'cols': 65}) call term_sendkeys(buf, "ggo") call VerifyScreenDump(buf, 'Test_tabpanel_drawing_2_0', {}) @@ -481,6 +551,7 @@ function Test_tabpanel_visual() let buf = RunVimInTerminal('-S XTest_tabpanel_visual', {'rows': 10, 'cols': 45}) call term_sendkeys(buf, "v2w") + call WaitForAssert({-> assert_match('VISUAL.*\d', term_getline(buf, 10))}, 1000) call VerifyScreenDump(buf, 'Test_tabpanel_visual_0', {}) call term_sendkeys(buf, "\0jw") call term_sendkeys(buf, "v2wge") @@ -892,8 +963,133 @@ func Test_tabpanel_large_columns() call assert_fails(':set tabpanelopt=columns:-1', 'E474:') endfunc +func Test_tabpanel_scroll_many_tabs() + let save_lines = &lines + let save_showtabpanel = &showtabpanel + let save_tabpanelopt = &tabpanelopt + + " Make the screen short so the tab page list exceeds the visible height. + set lines=8 + set showtabpanel=2 + set tabpanelopt= + for i in range(20) + tabnew + endfor + + " Should not crash with many tabs (scroll behaviour is always on). + redraw! + + " Toggling scrollbar must also not crash. + set tabpanelopt=scrollbar + redraw! + + set tabpanelopt= + redraw! + + " Right alignment with scrollbar. + set tabpanelopt=align:right,scrollbar + redraw! + + " Vertical separator with scrollbar. + set tabpanelopt=columns:10,vert,scrollbar + redraw! + + " Cleanup. + %bwipeout! + let &tabpanelopt = save_tabpanelopt + let &showtabpanel = save_showtabpanel + let &lines = save_lines +endfunc + +" The scrollbar thumb must follow the current tab when it is moved by +" gt/gT/:tabnext/:tablast, so that the selected tab is always visible. +func Test_tabpanel_scrollbar_follows_curtab() + let save_lines = &lines + let save_columns = &columns + let save_showtabpanel = &showtabpanel + let save_tabpanelopt = &tabpanelopt + + set lines=10 columns=40 + set showtabpanel=2 tabpanelopt=scrollbar,columns:8 + for i in range(49) + tabnew + endfor + let sb_col = 8 + + " With curtab at the top of the list, row 1 shows the thumb and the + " last row shows the track. Record the two attrs for comparison. + tabfirst + redraw + let attr_thumb = screenattr(1, sb_col) + let attr_track = screenattr(&lines, sb_col) + call assert_notequal(attr_thumb, attr_track) + + " Jump to a tab far outside the visible range: thumb must leave the top. + 30tabnext + redraw + call assert_equal(attr_track, screenattr(1, sb_col)) + + " Back to the first tab: thumb returns to the top. + tabfirst + redraw + call assert_equal(attr_thumb, screenattr(1, sb_col)) + call assert_equal(attr_track, screenattr(&lines, sb_col)) + + " gT from the first tab wraps to the last: thumb moves to the bottom. + normal! gT + redraw + call assert_equal(attr_track, screenattr(1, sb_col)) + call assert_equal(attr_thumb, screenattr(&lines, sb_col)) + + " gt from the last tab wraps to the first: thumb returns to the top. + normal! gt + redraw + call assert_equal(attr_thumb, screenattr(1, sb_col)) + call assert_equal(attr_track, screenattr(&lines, sb_col)) + + %bwipeout! + let &tabpanelopt = save_tabpanelopt + let &showtabpanel = save_showtabpanel + let &lines = save_lines + let &columns = save_columns +endfunc + +" With 31 tabs on 24 rows, :tablast must place the scrollbar thumb's +" bottom at the last screen row. Before the fix, integer truncation in +" thumb_top left a one-row gap at the bottom. +func Test_tabpanel_scrollbar_reaches_bottom() + let save_lines = &lines + let save_columns = &columns + let save_showtabpanel = &showtabpanel + let save_tabpanelopt = &tabpanelopt + + set lines=24 columns=40 + set showtabpanel=2 tabpanelopt=scrollbar,columns:8 + for i in range(30) + tabnew + endfor + let sb_col = 8 + + " Identify the thumb attr while the thumb is at the top. + tabfirst + redraw + let attr_thumb = screenattr(1, sb_col) + let attr_track = screenattr(&lines, sb_col) + call assert_notequal(attr_thumb, attr_track) + + " :tablast must push the thumb all the way to the bottom. + tablast + redraw + call assert_equal(attr_thumb, screenattr(&lines, sb_col)) + + %bwipeout! + let &tabpanelopt = save_tabpanelopt + let &showtabpanel = save_showtabpanel + let &lines = save_lines + let &columns = save_columns +endfunc + func Test_tabpanel_variable_height() - CheckFeature tabpanel let save_lines = &lines let save_showtabpanel = &showtabpanel @@ -923,4 +1119,121 @@ func Test_tabpanel_variable_height() %bwipeout! endfunc +func Test_tabpanel_empty() + set showtabpanel=2 tabpanel=%!'%{}%' + try + redraw! + catch + endtry + set showtabpanel& + set tabpanel& +endfunc + +func Test_tabpanel_carry_hl() + CheckScreendump + + " %#XX# / %N* set on one row of a tabpanel should persist on subsequent + " rows until %* (or another %# / %*) changes it. Both "%@" and "\n" are + " accepted as line breaks in 'tabpanel'. + let lines =<< trim END + func MyTabPanel() + return "L1A\n" + \ .. "%#Search#L1B\n" + \ .. "L2 carried Search\n" + \ .. "%*L3 reset\n" + \ .. "%2*L4 user2\n" + \ .. "L5 carried\n" + \ .. "%*L6 reset" + endfunc + + hi User2 ctermfg=Yellow ctermbg=Blue + set showtabpanel=2 + set tabpanelopt=columns:20 + set tabpanel=%!MyTabPanel() + END + call writefile(lines, 'XTest_tabpanel_carry_hl', 'D') + + let buf = RunVimInTerminal('-S XTest_tabpanel_carry_hl', {'rows': 9, 'cols': 60}) + call VerifyScreenDump(buf, 'Test_tabpanel_carry_hl_01', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_tabpanel_getinfo_and_scroll() + CheckScreendump + + let lines =<< trim END + set showtabpanel=2 tabpanelopt=columns:20 + set showtabline=0 + for i in range(40) + tabnew + endfor + tabfirst + redraw + func WriteResult(label) + call writefile([a:label, string(tabpanel_getinfo())], 'Xresult', 'a') + endfunc + call delete('Xresult') + call WriteResult('initial') + let g:r1 = tabpanel_scroll(1) + redraw + call WriteResult('after_scroll_1') + call tabpanel_scroll(-10) + redraw + call WriteResult('after_scroll_minus10') + let g:max = tabpanel_getinfo().max_offset + call tabpanel_scroll(g:max, #{absolute: 1}) + redraw + call WriteResult('after_abs_max') + call tabpanel_scroll(99999, #{absolute: 1}) + redraw + call WriteResult('after_abs_overflow') + call tabpanel_scroll(-5, #{absolute: 1}) + redraw + call WriteResult('after_abs_negative') + let g:r_zero = tabpanel_scroll(0, #{absolute: 1}) + let g:r_neg_at_zero = tabpanel_scroll(-1) + call writefile([ + \ 'r1=' .. g:r1, + \ 'max=' .. g:max, + \ 'r_zero=' .. g:r_zero, + \ 'r_neg_at_zero=' .. g:r_neg_at_zero, + \ ], 'Xflags') + END + call writefile(lines, 'XTest_tabpanel_getinfo', 'D') + + let buf = RunVimInTerminal('-S XTest_tabpanel_getinfo', {'rows': 10, 'cols': 45}) + call WaitForAssert({-> assert_true(filereadable('Xflags'))}) + call StopVimInTerminal(buf) + + let results = readfile('Xresult') + let flags = readfile('Xflags') + call delete('Xresult') + call delete('Xflags') + + " Parse [label, dict] pairs. + let info = {} + for i in range(0, len(results) - 1, 2) + let info[results[i]] = eval(results[i + 1]) + endfor + + call assert_equal('left', info.initial.align) + call assert_equal(20, info.initial.columns) + call assert_false(has_key(info.initial, 'scroll')) + call assert_equal(0, info.initial.offset) + call assert_true(info.initial.total > 0) + call assert_true(info.initial.max_offset > 0) + + call assert_equal(1, info.after_scroll_1.offset) + call assert_equal(0, info.after_scroll_minus10.offset) + + let max = info.initial.max_offset + call assert_equal(max, info.after_abs_max.offset) + call assert_equal(max, info.after_abs_overflow.offset) + call assert_equal(0, info.after_abs_negative.offset) + + call assert_equal(['r1=v:true', 'max=' .. max, + \ 'r_zero=v:false', 'r_neg_at_zero=v:false'], flags) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim index bbab3c70e8..7df75cff5c 100644 --- a/src/testdir/test_tagjump.vim +++ b/src/testdir/test_tagjump.vim @@ -1693,4 +1693,50 @@ func Test_tag_excmd_with_number_vim9script() bwipe! endfunc +" Test that backtick expressions in tag filenames are not expanded. +" This prevents command injection via malicious tags files. +func Test_tag_backtick_filename_not_expanded() + let pwned_file = 'Xtags_pwnd' + call assert_false(filereadable(pwned_file)) + + let tagline = "main\t`touch " .. pwned_file .. "`\t/^int main/;\"\tf" + call writefile([tagline], 'Xbt_tags', 'D') + call writefile(['int main(int argc, char **argv) {', '}'], 'Xbt_main.c', 'D') + + set tags=Xbt_tags + sp Xbt_main.c + + " The :tag command should fail to find the file, but must NOT execute + " the backtick shell command. + call assert_fails('tag main', 'E429:') + call assert_false(filereadable(pwned_file)) + + set tags& + bwipe! +endfunc + +func Test_tagjump_refuse_url() + call writefile([ + \ "XTagURL\thttp://127.0.0.1:1/$XTAG_SECRET/file.c\t/^int main" + \ ], 'Xtags', 'D') + let save_tagsecure = &tagsecure + let save_tags = &tags + set tags=Xtags + + " E1576: Tag file entry must not be a URL + set tagsecure + call assert_fails('tag XTagURL', 'E1576:') + set tsc + call assert_fails('tag XTagURL', 'E1576:') + + " E429: File does not exist + set notagsecure + call assert_fails('tag XTagURL', 'E429:') + set notsc + call assert_fails('tag XTagURL', 'E429:') + + let &tagsecure = save_tagsecure + let &tags = save_tags +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim index edf64d2830..adabeeedbf 100644 --- a/src/testdir/test_termcodes.vim +++ b/src/testdir/test_termcodes.vim @@ -359,7 +359,7 @@ func Test_term_mouse_middle_click_insert_mode() let &term = save_term let &ttymouse = save_ttymouse call test_override('no_query_mouse', 0) - close! + bw! endfunc " Test for switching window using mouse in insert mode @@ -1720,6 +1720,7 @@ func Test_xx01_term_style_response() \ underline_rgb: 'u', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'u' \ }, terminalprops()) set t_RV= @@ -1755,6 +1756,7 @@ func Test_xx02_iTerm2_response() \ underline_rgb: 'u', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'y' \ }, terminalprops()) set t_RV= @@ -1775,6 +1777,7 @@ func Run_libvterm_konsole_response(code) \ underline_rgb: 'u', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'u' \ }, terminalprops()) endfunc @@ -1818,6 +1821,7 @@ func Test_xx04_Mac_Terminal_response() \ underline_rgb: 'y', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'n' \ }, terminalprops()) call assert_equal("\[58;2;%lu;%lu;%lum", &t_8u) @@ -1849,6 +1853,7 @@ func Test_xx05_mintty_response() \ underline_rgb: 'y', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'u' \ }, terminalprops()) set t_RV= @@ -1885,6 +1890,7 @@ func Test_xx06_screen_response() \ underline_rgb: 'y', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'n' \ }, terminalprops()) set t_RV= @@ -1910,6 +1916,7 @@ func Do_check_t_8u_set_reset(set_by_user) \ underline_rgb: 'u', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'u' \ }, terminalprops()) call assert_equal(a:set_by_user ? default_value : '', &t_8u) endfunc @@ -1949,6 +1956,7 @@ func Test_xx07_xterm_response() \ underline_rgb: 'y', \ mouse: 'u', \ kitty: 'u', + \ decrqm: 'u' \ }, terminalprops()) " xterm >= 95 < 277 "xterm2" @@ -1965,6 +1973,7 @@ func Test_xx07_xterm_response() \ underline_rgb: 'u', \ mouse: '2', \ kitty: 'u', + \ decrqm: 'u' \ }, terminalprops()) " xterm >= 277: "sgr" @@ -1981,6 +1990,7 @@ func Test_xx07_xterm_response() \ underline_rgb: 'u', \ mouse: 's', \ kitty: 'u', + \ decrqm: 'u' \ }, terminalprops()) " xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset, @@ -2010,6 +2020,7 @@ func Test_xx08_kitty_response() \ underline_rgb: 'y', \ mouse: 's', \ kitty: 'y', + \ decrqm: 'y' \ }, terminalprops()) call feedkeys("\[?1u") " simulate the kitty keyboard protocol is enabled @@ -3055,6 +3066,11 @@ func Test_term_win_resize() let buf = RunVimInTerminal('-S XTestWinResize', #{rows: 15, cols: 20}) + " Must add a delay, since status report is sent internally by vim only when + " version response is received, which may come after we send the status report + " here. + sleep 100m + " Send status report call term_sendkeys(buf, "\[?2048;1$y") call TermWait(buf) diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index 7ccf6dc385..8360284fc3 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -2456,4 +2456,29 @@ func Test_terminal_disable_kitty_keyboard() bwipe! endfunc +func Test_terminal_unwraps() + CheckNotMSWindows + + 30vnew + + redraw + let buf = term_start("echo 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15") + " Wait until both wrapped lines have appeared in the terminal + call WaitForAssert({-> assert_equal('14+15', term_getline(buf, 2))}) + + " A long wrapped line appears as 2 lines in libvterm + let l = term_getline(buf, 1) + call assert_equal('1+2+3+4+5+6+7+8+9+10+11+12+13+', l) + + let l = term_getline(buf, 2) + call assert_equal('14+15', l) + + call TermWait(buf) + " It should appear as a single buffer line in vim + let lastline = getline('$') + call assert_equal('1+2+3+4+5+6+7+8+9+10+11+12+13+14+15', lastline) + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim index 04c7c925e3..2e80f6fe44 100644 --- a/src/testdir/test_terminal3.vim +++ b/src/testdir/test_terminal3.vim @@ -1241,4 +1241,80 @@ func Test_terminal_csi_args_overflow() call StopVimInTerminal(buf) endfunc +func Test_terminal_output_combining_chars() + CheckUnix + new + let cmd = "cat samples/combining_chars.txt" + let buf = term_start(cmd, {'curwin': 1, 'term_finish': 'open', 'term_rows': 10, 'term_cols': 30}) + call WaitForAssert({-> assert_match('finished', term_getstatus(buf))}) + call TermWait(buf) + let lines = getbufline(buf, 1, '$') + " get byte lengths to confirm combining chars present + let lens = map(copy(lines), 'len(v:val)') + let expected = repeat([11], 190) + repeat([14], 10) + call assert_equal(expected, lens) + bw! +endfunc + +" This caused a Crash +func Test_terminal_csi_resize_oob() + return + CheckUnix + CheckExecutable printf + + " CSI 8 ; rows ; cols t with missing, zero or negative dimensions reached + " on_resize()/resize_buffer() unvalidated, causing a negative-size memmove() + " and out-of-bounds set_lineinfo()/DECALN accesses in libvterm. Rendering + " these must not crash Vim. + + " Sequences: + " 1 resize_buffer negative-size memmove + " 2 set_lineinfo OOB after corrupt resize + " 3 DECALN putglyph OOB after corrupt resize + let seqs = ["\[8;0;t", + \ "\[8;;t\[J", + \ "\[8;;0t\#8"] + + for seq in seqs + let buf = term_start([&shell, &shellcmdflag, 'printf "%s" ' .. shellescape(seq)], + \ #{term_rows: 10, term_cols: 40}) + call TermWait(buf) + " Getting here without a crash (and no ASAN report) is the test. + call assert_true(bufexists(buf)) + exe 'bwipe! ' .. buf + endfor +endfunc + +" This caused a Crash, but Vim builds libvterm using -DWCWIDTH_FUNCTION=utf_uint2cells +" which wouldn't return -1 and therefore does not reproduce here +func Test_terminal_negative_col_oob() + CheckUnix + CheckExecutable printf + + " A wcwidth() == -1 codepoint (U+0087, \302\207 in UTF-8) drove + " state->pos.col negative, then used as an array index in the tabstop + " helpers and moverect_internal(). These are single-byte / single-bit + " out-of-bounds accesses that do not crash a normal build, so this test + " is only meaningful under a sanitizer build; otherwise it just confirms + " Vim does not crash. + + " Sequences: + " 1. clear_col_tabstop OOB read + " 2. is_col_tabstop OOB read + " 3. set_col_tabstop OOB write (HTS) + " 4. moverect_internal memmove (insert mode) + + let seqs = ["\302\207\[g", + \ "\302\207\302\207\t", + \ "\302\207\H", + \ "\[4h\302\2070"] + for seq in seqs + let buf = term_start([&shell, &shellcmdflag, 'printf "%s" ' .. shellescape(seq)], + \ #{term_rows: 10, term_cols: 40}) + call TermWait(buf) + call assert_true(bufexists(buf)) + exe 'bwipe! ' .. buf + endfor +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index f94acfc97c..7d868ec064 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -3574,6 +3574,56 @@ func Test_props_with_text_after_nowrap() call StopVimInTerminal(buf) endfunc +func Test_props_with_text_after_wide_char_at_end() + CheckScreendump + CheckRunVimInTerminal + + " The buffer line ends with a double-width character exactly at the window + " width and has wrapping "after" virtual text. This must not leave blank + " lines or "@@@", see issue #20384. + let lines =<< trim END + vim9script + set nowrap + setline(1, [repeat('x', 43) .. 'åŖ', 'second line', 'third line']) + prop_type_add('errtype', {highlight: 'WarningMsg', text_wrap: 'wrap'}) + prop_add(1, 0, {type: 'errtype', text_padding_left: 3, text: 'E>'}) + END + call writefile(lines, 'XscriptPropsAfterWideChar', 'D') + let buf = RunVimInTerminal('-S XscriptPropsAfterWideChar', #{rows: 8, cols: 45}) + call VerifyScreenDump(buf, 'Test_prop_with_text_after_wide_char_1', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_props_with_text_after_wide_char_overflow() + CheckScreendump + CheckRunVimInTerminal + + " Like above, but the last character reaches the rightmost column without + " starting on it: a double-width character that does not fit in the last + " column, and a that expands up to the window width. Both must be + " detected as filling the line so the wrapping "after" text does not cause + " blank lines, "@@@" or a spurious wrap with 'nowrap'. + let lines =<< trim END + vim9script + set nowrap tabstop=8 noexpandtab + setline(1, [ + repeat('x', 39) .. 'åŖ', + 'between line', + repeat('x', 32) .. "\t", + 'last line', + ]) + prop_type_add('errtype', {highlight: 'WarningMsg', text_wrap: 'wrap'}) + prop_add(1, 0, {type: 'errtype', text_padding_left: 3, text: 'E>'}) + prop_add(3, 0, {type: 'errtype', text_padding_left: 3, text: 'E>'}) + END + call writefile(lines, 'XscriptPropsAfterWideOverflow', 'D') + let buf = RunVimInTerminal('-S XscriptPropsAfterWideOverflow', #{rows: 8, cols: 40}) + call VerifyScreenDump(buf, 'Test_prop_with_text_after_wide_char_2', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_prop_with_text_below_cul() CheckScreendump CheckRunVimInTerminal @@ -4907,4 +4957,38 @@ func Test_textprop_materialize_list() call assert_equal([], prop_list(1, #{ids: 3->range()})) endfunc +func Test_prop_find_floating_vtext() + new + call setline(1, ['111', '222', '333']) + let tn = 'test' + call prop_type_add(tn, {'highlight': 'Search'}) + for ln in range(1, 3) + call prop_add(ln, 0, {'type': tn, 'text': '-----', 'text_align': 'above'}) + endfor + " forward search must find the virtual text on the starting line + let found = prop_find({'type': tn, 'lnum': 1, 'col': 1}) + call assert_equal(1, found.lnum) + call assert_equal('-----', found.text) + " backward search must also find the virtual text on the starting line + let found = prop_find({'type': tn, 'lnum': 1, 'col': 1}, 'b') + call assert_equal(1, found.lnum) + call assert_equal('-----', found.text) + bwipe! + call prop_type_delete(tn) + " Also cover 'below' and 'right' aligned virtual text (also tp_col==MAXCOL) + for align in ['below', 'right'] + new + call setline(1, ['aaa', 'bbb']) + call prop_type_add(tn, {'highlight': 'Search'}) + call prop_add(1, 0, {'type': tn, 'text': 'VT', 'text_align': align}) + let found = prop_find({'type': tn, 'lnum': 1, 'col': 1}) + call assert_equal(1, found.lnum, 'forward, align=' .. align) + call assert_equal('VT', found.text, 'forward, align=' .. align) + let found = prop_find({'type': tn, 'lnum': 1, 'col': 1}, 'b') + call assert_equal(1, found.lnum, 'backward, align=' .. align) + call assert_equal('VT', found.text, 'backward, align=' .. align) + bwipe! + call prop_type_delete(tn) + endfor +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_undo.vim b/src/testdir/test_undo.vim index ad724aa04d..21b9dcfdab 100644 --- a/src/testdir/test_undo.vim +++ b/src/testdir/test_undo.vim @@ -924,5 +924,84 @@ func Test_restore_cursor_position_after_undo() bw! endfunc +func Test_undo_line_backspace_after_insert_cmd_cursor_movement() + new + setlocal backspace=eol undolevels=100 + call setline(1, ['', '', 'abc', 'def']) + call cursor(4, 1) + + let v:errmsg = '' + call feedkeys("i\setlocal undolevels=101 | call cursor(3, 1)\" + \ .. "\\\u", 'xt') + + call assert_equal('', v:errmsg) + call assert_equal(['', '', 'abc', 'def'], getline(1, '$')) + bwipe! +endfunc + +func Test_undo_line_backspace_after_insert_func_edit() + new + setlocal backspace=eol undolevels=100 + + let v:errmsg = '' + call feedkeys("i\" + \ .. "\call setline(2, 'abc')\" + \ .. "\\u", 'xt') + + call assert_equal('', v:errmsg) + call assert_equal([''], getline(1, '$')) + bwipe! +endfunc + +func Test_undo_line_backspace_after_insert_cmd_edit() + new + setlocal backspace=eol undolevels=100 + + let v:errmsg = '' + call feedkeys("i\" + \ .. "\s/.*/abc/\" + \ .. "\\u", 'xt') + + call assert_equal('', v:errmsg) + call assert_equal([''], getline(1, '$')) + bwipe! +endfunc + +" Corrupted undo file via cyclic cross-references caused +" double free +func Test_corrupted_undofile() + CheckFeature persistent_undo + let _uf = &undofile + set undofile + new + call setline(1, 'hello') + let b=eval('0z56696D9F556E446FE50002F3AEFE62965A91903610' .. + \ 'F0E23CC8A69D5B87CEA6D28E75489B0D2CA02ED7993C' .. + \ '00000001000000000000000000000000000000010000' .. + \ '00010000000100000001000000010000000100000000' .. + \ '3B9ACA00005FD0000000010000000000000000000000' .. + \ '00000000010000000100000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '00000000000000000000000000000000000000000000' .. + \ '000000000000000000000000000000000000003B9ACA' .. + \ '00003581E7AA') + call writefile(b, 'Xundo', 'bD') + rundo Xundo + bw! + let &undofile = _uf +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim index 5afd8f1278..8b90a826e4 100644 --- a/src/testdir/test_usercommands.vim +++ b/src/testdir/test_usercommands.vim @@ -339,6 +339,9 @@ func Test_CmdErrors() com! -nargs=1 DoCmd : call assert_fails('DoCmd', 'E471:') + com! -nargs=_ DoCmd : + call assert_fails('DoCmd', 'E471:') + com! -nargs=+ DoCmd : call assert_fails('DoCmd', 'E471:') @@ -360,6 +363,14 @@ func CustomCompleteList(A, L, P) return [ "Monday", "Tuesday", "Wednesday", {}, test_null_string()] endfunc +func CustomCompleteListWithSpaces(A, L, P) + return [ "Monday Here", "Tuesday There", "Wednesday OK", {}, test_null_string()] +endfunc + +func CustomCompleteListFuzzy(A, L, P) + return [ "Monday Here", "Tuesday There", "Wednesday OK", {}, test_null_string()]->matchfuzzy(a:A) +endfunc + func Test_CmdCompletion() call feedkeys(":com -\\\"\", 'tx') call assert_equal('"com -addr bang bar buffer complete count keepscript nargs range register', @:) @@ -368,7 +379,7 @@ func Test_CmdCompletion() call assert_equal('"com -nargs=0 -addr bang bar buffer complete count keepscript nargs range register', @:) call feedkeys(":com -nargs=\\\"\", 'tx') - call assert_equal('"com -nargs=* + 0 1 ?', @:) + call assert_equal('"com -nargs=* + 0 1 ? _', @:) call feedkeys(":com -addr=\\\"\", 'tx') call assert_equal('"com -addr=arguments buffers lines loaded_buffers other quickfix tabs windows', @:) @@ -391,7 +402,6 @@ func Test_CmdCompletion() exe 'delcommand ' .. cmd endfor delcommand MissingFeature - delcommand RunSocketServer command! DoCmd1 : command! DoCmd2 : @@ -426,15 +436,27 @@ func Test_CmdCompletion() call feedkeys(":DoCmd \\\"\", 'tx') call assert_equal('"DoCmd mswin xterm', @:) + com! -nargs=_ -complete=behave DoCmd : + call feedkeys(":DoCmd \\\"\", 'tx') + call assert_equal('"DoCmd mswin xterm', @:) + com! -nargs=1 -complete=retab DoCmd : call feedkeys(":DoCmd \\\"\", 'tx') call assert_equal('"DoCmd -indentonly', @:) + com! -nargs=_ -complete=retab DoCmd : + call feedkeys(":DoCmd \\\"\", 'tx') + call assert_equal('"DoCmd -indentonly', @:) + " Test for file name completion com! -nargs=1 -complete=file DoCmd : call feedkeys(":DoCmd READM\\\"\", 'tx') call assert_equal('"DoCmd README.txt', @:) + com! -nargs=_ -complete=file DoCmd : + call feedkeys(":DoCmd READM\\\"\", 'tx') + call assert_equal('"DoCmd README.txt', @:) + " Test for buffer name completion com! -nargs=1 -complete=buffer DoCmd : let bnum = bufadd('BufForUserCmd') @@ -445,6 +467,15 @@ func Test_CmdCompletion() call feedkeys(":DoCmd BufFor\\\"\", 'tx') call assert_equal('"DoCmd BufFor', @:) + com! -nargs=_ -complete=buffer DoCmd : + let bnum = bufadd('BufForUserCmd') + call setbufvar(bnum, '&buflisted', 1) + call feedkeys(":DoCmd BufFor\\\"\", 'tx') + call assert_equal('"DoCmd BufForUserCmd', @:) + bwipe BufForUserCmd + call feedkeys(":DoCmd BufFor\\\"\", 'tx') + call assert_equal('"DoCmd BufFor', @:) + com! -nargs=* -complete=custom,CustomComplete DoCmd : call feedkeys(":DoCmd \\\"\", 'tx') call assert_equal('"DoCmd January February Mars', @:) @@ -453,6 +484,14 @@ func Test_CmdCompletion() call feedkeys(":DoCmd \\\"\", 'tx') call assert_equal('"DoCmd Monday Tuesday Wednesday', @:) + com! -nargs=_ -complete=customlist,CustomCompleteListWithSpaces DoCmd : + call feedkeys(":DoCmd \\\"\", 'tx') + call assert_equal('"DoCmd Monday Here Tuesday There Wednesday OK', @:) + + com! -nargs=_ -complete=customlist,CustomCompleteListFuzzy DoCmd : + call feedkeys(":DoCmd mo he\\\"\", 'tx') + call assert_equal('"DoCmd Monday Here', @:) + com! -nargs=+ -complete=custom,CustomCompleteList DoCmd : call assert_fails("call feedkeys(':DoCmd \', 'tx')", 'E730:') @@ -555,6 +594,27 @@ func Test_addr_all() delcommand DoSomething endfunc +func Test_nargs_underscore_fargs() + " -nargs=_ must behave like -nargs=1 for /: + " the whole argument is one token, whitespace is part of it. + let g:res = [] + com! -nargs=1 DoCmd1 call add(g:res, []) + com! -nargs=_ DoCmdU call add(g:res, []) + DoCmd1 a b c + DoCmdU a b c + call assert_equal([['a b c'], ['a b c']], g:res) + + let g:res = [] + com! -nargs=_ DoCmdQ call add(g:res, ) + DoCmdQ a b c + call assert_equal(['a b c'], g:res) + + delcom DoCmd1 + delcom DoCmdU + delcom DoCmdQ + unlet g:res +endfunc + func Test_command_list() command! DoCmd : call assert_equal("\n Name Args Address Complete Definition" @@ -614,6 +674,10 @@ func Test_command_list() call assert_equal("\n Name Args Address Complete Definition" \ .. "\n DoCmd 1 arglist :", \ execute('command DoCmd')) + command! -nargs=_ -complete=arglist DoCmd : + call assert_equal("\n Name Args Address Complete Definition" + \ .. "\n DoCmd _ arglist :", + \ execute('command DoCmd')) command! -nargs=* -complete=augroup DoCmd : call assert_equal("\n Name Args Address Complete Definition" \ .. "\n DoCmd * augroup :", @@ -636,6 +700,10 @@ func Test_command_list() call assert_equal("\n Name Args Address Complete Definition" \ .. "\n DoCmd 1 :", \ execute('command DoCmd')) + command! -nargs=_ DoCmd : + call assert_equal("\n Name Args Address Complete Definition" + \ .. "\n DoCmd _ :", + \ execute('command DoCmd')) command! -nargs=* DoCmd : call assert_equal("\n Name Args Address Complete Definition" \ .. "\n DoCmd * :", diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 5043fad23f..c5f564ec75 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -3131,6 +3131,28 @@ def Test_type_specification_in_assignment() Foo() END v9.CheckSourceFailure(lines, "E476: Invalid command: MyVar: string = 'abc'", 1) + + # redeclare an existing def local variable with a type + lines =<< trim END + vim9script + def Foo() + var n: number = 10 + var n: number = 20 + enddef + Foo() + END + v9.CheckSourceFailure(lines, 'E1017: Variable already declared: n', 2) + + # redeclare an existing def local constant with a type + lines =<< trim END + vim9script + def Foo() + const x: number = 1 + const x: number = 2 + enddef + Foo() + END + v9.CheckSourceFailure(lines, 'E1017: Variable already declared: x', 2) enddef let g:someVar = 'X' diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index b74f324aef..3f95ee8b25 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -1,7 +1,6 @@ " Test using builtin functions in the Vim9 script language. source util/screendump.vim -source util/socketserver.vim import './util/vim9.vim' as v9 " Test for passing too many or too few arguments to builtin functions @@ -3525,11 +3524,12 @@ enddef def Test_remote_expr() CheckFeature clientserver - TrySocketServer + CheckNotMSWindows - if !g:socketserver_only + if has("x11") CheckEnv DISPLAY endif + 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']) @@ -3551,10 +3551,12 @@ enddef def Test_remote_peek() CheckFeature clientserver - TrySocketServer - if !g:socketserver_only + CheckNotMSWindows + + if has("x11") CheckEnv DISPLAY endif + 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', 'E1174: String required for argument 2']) v9.CheckSourceDefExecAndScriptFailure(['remote_peek("")'], 'E573: Invalid server id used') @@ -3562,7 +3564,12 @@ enddef def Test_remote_read() CheckFeature clientserver - CheckEnv DISPLAY + CheckNotMSWindows + + if has("x11") + CheckEnv DISPLAY + endif + 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') @@ -3570,10 +3577,12 @@ enddef def Test_remote_send() CheckFeature clientserver - TrySocketServer - if !g:socketserver_only + CheckNotMSWindows + + if has("x11") CheckEnv DISPLAY endif + 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']) @@ -3582,10 +3591,12 @@ enddef def Test_remote_startserver() CheckFeature clientserver - TrySocketServer - if !g:socketserver_only + CheckNotMSWindows + + if has("x11") CheckEnv DISPLAY endif + v9.CheckSourceDefAndScriptFailure(['remote_startserver({})'], ['E1013: Argument 1: type mismatch, expected string but got dict', 'E1174: String required for argument 1']) enddef diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 5db6c65d12..7d725e3745 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -1,4 +1,4 @@ -" Test Vim9 classes +" Tests for Vim9 script classes import './util/vim9.vim' as v9 @@ -42,7 +42,8 @@ def Test_class_basic() END v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2) - # The complete "endclass" should be specified. + # Test for "endclass" cannot be shortened. Test_shortened_invalid_vim9() in + # test_vim9_script.vim has complete coverage (:endc to :endclas) lines =<< trim END vim9script class Something @@ -50,6 +51,14 @@ def Test_class_basic() END v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3) + # "endclass" cannot be shortened (variant incl. colon-whitespace) + lines =<< trim END + vim9script + class Something + : endcla + END + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcla', 3) + # Additional words after "endclass" lines =<< trim END vim9script @@ -1353,13 +1362,14 @@ def Test_instance_variable_access() echo Foo.new() .Add(1).Add(2).x echo Foo.new() - .Add(1) + .Add(1) .Add(2) .x END v9.CheckSourceSuccess(lines) - # Test for "public" cannot be abbreviated + # Test for "public" cannot be shortened. Test_shortened_invalid_vim9() in + # test_vim9_script.vim has complete coverage (:pub to :publi) lines =<< trim END vim9script class Something @@ -1452,7 +1462,8 @@ enddef " Test for class variable access def Test_class_variable_access() - # Test for "static" cannot be abbreviated + # Test for "static" cannot be shortened. Test_shortened_invalid_vim9() in + # test_vim9_script.vim has complete coverage (:stat and :stati) var lines =<< trim END vim9script class Something @@ -2943,7 +2954,8 @@ def Test_abstract_class() END v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1) - # Test for "abstract" cannot be abbreviated + # Test for "abstract" cannot be shortened. Test_shortened_invalid_vim9() in + # test_vim9_script.vim has complete coverage (:abs to :abstrac) lines =<< trim END vim9script abs class A @@ -5143,7 +5155,7 @@ def Test_dup_member_variable() var _val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4) + v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 4) # Duplicate public and protected member variable lines =<< trim END @@ -5153,7 +5165,7 @@ def Test_dup_member_variable() public var val = 10 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4) + v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 4) # Duplicate class member variable lines =<< trim END @@ -5163,7 +5175,7 @@ def Test_dup_member_variable() static var _s: string = "def" endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4) + v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: s and _s', 4) # Duplicate public and protected class member variable lines =<< trim END @@ -5173,7 +5185,7 @@ def Test_dup_member_variable() static var _s: string = "def" endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4) + v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: s and _s', 4) # Duplicate class and object member variable lines =<< trim END @@ -5230,7 +5242,7 @@ def Test_dup_member_variable() var _val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9) + v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 9) # Duplicate object member variable in a derived class lines =<< trim END @@ -5244,7 +5256,7 @@ def Test_dup_member_variable() var val = 20 endclass END - v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9) + v9.CheckSourceFailure(lines, 'E1406: Public and protected member have the same name: val and _val', 9) # Two member variables with a common prefix lines =<< trim END @@ -5572,15 +5584,6 @@ def Test_abstract_method() END v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3) - # Abbreviate the "abstract" keyword - lines =<< trim END - vim9script - class A - abs def Foo() - endclass - END - v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3) - # Use "abstract" with a member variable lines =<< trim END vim9script @@ -11869,4 +11872,19 @@ func Test_class_member_lambda() call v9.CheckSourceSuccess(lines) endfunc +" Test for colon and whitespace before class, endclass, static, and abstract +def Test_colon_whitespace() + var lines =<< trim END + : vim9script + : class C + # TODO: Fix :public - gives E1065 + # : public var p = true + : static var s = true + : endclass + : abstract class A + : endclass + END + v9.CheckSourceSuccess(lines) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index 1380440c40..cec81f3ed6 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -952,7 +952,7 @@ func Test_command_modifier_confirm() call term_sendkeys(buf, ":call Getout()\n") call WaitForAssert({-> assert_match('(Y)es, \[N\]o: ', term_getline(buf, 8))}, 1000) call term_sendkeys(buf, "y") - call WaitForAssert({-> assert_match('(Y)es, \[N\]o: ', term_getline(buf, 8))}, 1000) + call WaitForAssert({-> assert_match('Press ENTER or type command to continue', term_getline(buf, 8))}, 1000) call term_sendkeys(buf, "\") call TermWait(buf) call StopVimInTerminal(buf) @@ -2094,6 +2094,24 @@ def Test_lambda_crash() v9.CheckScriptFailureList(lines, ["E1356:", "E1405:"]) enddef +def Test_skipped_lambda_after_else() + var lines =<< trim END + vim9script + def g:Warn(msg: string) + if has('patch-9.0.0321') + echo msg + else + timer_start(100, (_) => { + echohl WarningMsg | echom msg | echohl None + }, {repeat: 0}) + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + delfunc! g:Warn +enddef + def s:check_previewpopup(expected_title: string) var id = popup_findpreview() assert_notequal(id, 0) @@ -2103,8 +2121,8 @@ def s:check_previewpopup(expected_title: string) set previewpopup& enddef -" Test for the 'previewpopup' option def Test_previewpopup() + # Test for the 'previewpopup' option CheckFeature quickfix set previewpopup=height:10,width:60 pedit Xppfile @@ -2127,5 +2145,56 @@ def Test_syntax_enable_clear() syntax clear enddef +" Test for using legacy expression evaluation in a vim9script map +def Test_map_legacy_expr() + var lines =<< trim END + legacy inoremap 'hello' . 'world' + new + feedkeys("a\", 'xt') + assert_equal(['helloworld'], getline(1, '$')) + bw! + END + v9.CheckDefAndScriptSuccess(lines) +enddef + +" :call on a funcref stored in a dict member used to fail with E1017 in Vim9 +" script because get_lval() treated the subscript as a re-declaration. +def Test_call_dict_funcref() + var lines =<< trim END + vim9script + var d: dict = {} + var marker = '' + def F() + marker = 'called' + enddef + d.key = F + d['k2'] = F + call d.key() + assert_equal('called', marker) + marker = '' + call d['k2']() + assert_equal('called', marker) + END + v9.CheckScriptSuccess(lines) +enddef + +" :delfunction on a funcref stored in a dict member used to fail with E1017 in +" Vim9 script for the same reason as :call. +def Test_delfunction_dict_funcref() + var lines =<< trim END + vim9script + func g:LegacyFunc() + endfunc + var d: dict = {} + d.key = g:LegacyFunc + d['k2'] = g:LegacyFunc + delfunction d.key + assert_false(has_key(d, 'key')) + delfunction d['k2'] + assert_false(has_key(d, 'k2')) + delfunction g:LegacyFunc + END + v9.CheckScriptSuccess(lines) +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 be4c8f6d5b..4e05c86687 100644 --- a/src/testdir/test_vim9_enum.vim +++ b/src/testdir/test_vim9_enum.vim @@ -1,8 +1,8 @@ -" Test Vim9 enums +" Tests for Vim9 script enums import './util/vim9.vim' as v9 -" Test for parsing an enum definition +" Test for parsing an enum definition {{{1 def Test_enum_parse() # enum supported only in a Vim9 script var lines =<< trim END @@ -11,6 +11,14 @@ def Test_enum_parse() END v9.CheckSourceFailure(lines, 'E1414: Enum can only be defined in Vim9 script', 1) + # ":enum" and ":endenum" + lines =<< trim END + vim9script + :enum Foo + :endenum + END + v9.CheckSourceSuccess(lines) + # First character in an enum name should be capitalized. lines =<< trim END vim9script @@ -46,10 +54,10 @@ def Test_enum_parse() # The complete "enum" should be specified. lines =<< trim END vim9script - enu Something + enu Nah endenum END - v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enu', 2) + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enu Nah', 2) # The complete "endenum" should be specified. lines =<< trim END @@ -59,6 +67,14 @@ def Test_enum_parse() END v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enden', 3) + # "endenum" cannot be shortened (variant incl. whitespace and colon) + lines =<< trim END + vim9script + enum NoAbbrev + : endenu + END + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endenu', 3) + # Only the complete word "endenum" should be recognized lines =<< trim END vim9script @@ -271,6 +287,16 @@ def Test_enum_parse() END v9.CheckSourceFailure(lines, 'E1418: Invalid enum value declaration: $%@', 4) + # Additional command after "enumvalue" + lines =<< trim END + vim9script + enum NoAdditionalCmd + One, | var y = 10 + Two + endenum + END + v9.CheckSourceFailure(lines, "E1418: Invalid enum value declaration: | var y = 10", 3) + # Duplicate enum value lines =<< trim END vim9script @@ -352,6 +378,7 @@ def Test_enum_parse() v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: n: number = 10', 3) enddef +" Test for basic enum declaration and errors {{{1 def Test_basic_enum() # Declare a simple enum var lines =<< trim END @@ -493,7 +520,7 @@ def Test_basic_enum() v9.CheckSourceFailure(lines, 'E1421: Enum "Fruit" cannot be used as a value', 6) enddef -" Test for type() and typename() of an enum +" Test for type() and typename() of an enum {{{1 def Test_enum_type() var lines =<< trim END vim9script @@ -525,7 +552,7 @@ def Test_enum_type() v9.CheckSourceSuccess(lines) enddef -" Try modifying an enum or an enum item +" Test for trying to modify an enum or an enum item {{{1 def Test_enum_modify() # Try assigning an unsupported value to an enum var lines =<< trim END @@ -652,7 +679,7 @@ def Test_enum_modify() v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be modified', 1) enddef -" Test for using enum in an expression +" Test for using enum in an expression {{{1 def Test_enum_expr() var lines =<< trim END vim9script @@ -691,7 +718,7 @@ def Test_enum_expr() v9.CheckSourceFailure(lines, 'E1425: Using an Enum "Color" as a String', 5) enddef -" Using an enum in a lambda function +" Test for using an enum in a lambda function {{{1 def Test_enum_lambda() var lines =<< trim END vim9script @@ -708,7 +735,7 @@ def Test_enum_lambda() v9.CheckSourceSuccess(lines) enddef -" Comparison using enums +" Test for comparison using enums {{{1 def Test_enum_compare() var lines =<< trim END vim9script @@ -761,7 +788,7 @@ def Test_enum_compare() v9.CheckSourceSuccess(lines) enddef -" Test for using an enum as a default argument to a function +" Test for using an enum as a default argument to a function {{{1 def Test_enum_default_arg() var lines =<< trim END vim9script @@ -777,7 +804,7 @@ def Test_enum_default_arg() v9.CheckSourceSuccess(lines) enddef -" Test for enum garbage collection +" Test for enum garbage collection {{{1 func Test_enum_garbagecollect() let lines =<< trim END vim9script @@ -826,7 +853,7 @@ func Test_enum_garbagecollect() call v9.CheckSourceSuccess(lines) endfunc -" Test for the enum values class variable +" Test for the enum values class variable {{{1 def Test_enum_values() var lines =<< trim END vim9script @@ -912,7 +939,7 @@ def Test_enum_values() v9.CheckSourceSuccess(lines) enddef -" Test comments in enums +" Test for using comments in enums {{{1 def Test_enum_comments() var lines =<< trim END vim9script @@ -951,7 +978,7 @@ def Test_enum_comments() v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 4) enddef -" Test trailing whitespace after enum values +" Test for trailing whitespace after enum values {{{1 def Test_enum_whitespace() var lines =<< trim END vim9script @@ -966,7 +993,7 @@ def Test_enum_whitespace() lines =<< trim END vim9script enum Car - Honda(), + Honda(), Ford() endenum defcompile @@ -974,7 +1001,7 @@ def Test_enum_whitespace() v9.CheckSourceSuccess(lines) enddef -" Test string() with enums +" Test for using string() with enums {{{1 def Test_enum_string() var lines =<< trim END vim9script @@ -1004,7 +1031,7 @@ def Test_enum_string() v9.CheckSourceSuccess(lines) enddef -" Test for importing an enum +" Test for importing an enum {{{1 def Test_enum_import() var lines =<< trim END vim9script @@ -1040,7 +1067,7 @@ def Test_enum_import() v9.CheckScriptSuccess(lines) enddef -" Test for using test_refcount() with enum +" Test for using test_refcount() with enum {{{1 def Test_enum_refcount() var lines =<< trim END vim9script @@ -1099,7 +1126,7 @@ def Test_enum_refcount() v9.CheckSourceSuccess(lines) enddef -" Test for defining an enum with additional object variables and methods +" Test for defining an enum with additional object variables and methods {{{1 def Test_enum_enhanced() var lines =<< trim END vim9script @@ -1140,7 +1167,7 @@ def Test_enum_enhanced() v9.CheckSourceSuccess(lines) enddef -" Test for the enum value 'name' variable +" Test for the enum value 'name' variable {{{1 def Test_enum_name() # Check the names of enum values var lines =<< trim END @@ -1221,7 +1248,7 @@ def Test_enum_name() v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: name', 4) enddef -" Test for the enum value 'ordinal' variable +" Test for the enum value 'ordinal' variable {{{1 def Test_enum_ordinal() # Check the ordinal values of enum items var lines =<< trim END @@ -1302,7 +1329,7 @@ def Test_enum_ordinal() v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: ordinal', 4) enddef -" Test for trying to create a new enum object using the constructor +" Test for trying to create a new enum object using the constructor {{{1 def Test_enum_invoke_constructor() var lines =<< trim END vim9script @@ -1360,7 +1387,7 @@ def Test_enum_invoke_constructor() v9.CheckSourceFailureList(lines, ['E1100:', 'E1100:'], 1) enddef -" Test for checking "this" in an enum constructor +" Test for checking "this" in an enum constructor {{{1 def Test_enum_this_in_constructor() var lines =<< trim END vim9script @@ -1378,7 +1405,7 @@ def Test_enum_this_in_constructor() v9.CheckSourceSuccess(lines) enddef -" Test for using member variables in an enum object +" Test for using member variables in an enum object {{{1 def Test_enum_object_variable() var lines =<< trim END vim9script @@ -1483,7 +1510,7 @@ def Test_enum_object_variable() v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 8) enddef -" Test for using a custom constructor with an enum +" Test for using a custom constructor with an enum {{{1 def Test_enum_custom_constructor() # space before "(" var lines =<< trim END @@ -1556,7 +1583,7 @@ def Test_enum_custom_constructor() v9.CheckSourceSuccess(lines) enddef -" Test for using class variables in an enum class +" Test for using class variables in an enum class {{{1 def Test_enum_class_variable() var lines =<< trim END vim9script @@ -1571,7 +1598,7 @@ def Test_enum_class_variable() v9.CheckSourceSuccess(lines) enddef -" Test for converting a string to an enum value +" Test for converting a string to an enum value {{{1 def Test_enum_eval() var lines =<< trim END vim9script @@ -1588,7 +1615,7 @@ def Test_enum_eval() v9.CheckSourceSuccess(lines) enddef -" Test for using "values" in an enum class variable +" Test for using "values" in an enum class variable {{{1 def Test_use_enum_values_in_class_variable() var lines =<< trim END vim9script @@ -1601,7 +1628,7 @@ def Test_use_enum_values_in_class_variable() v9.CheckSourceSuccess(lines) enddef -" Test for using lambda block in enums +" Test for using lambda block in enums {{{1 def Test_lambda_block_in_enum() # This used to crash Vim var lines =<< trim END @@ -1632,7 +1659,7 @@ def Test_lambda_block_in_enum() v9.CheckScriptSuccess(lines) enddef -" Echo an enum +" Test for echoing an enum {{{1 def Test_enum_echo() var lines =<< trim END vim9script @@ -1647,8 +1674,8 @@ def Test_enum_echo() v9.CheckScriptSuccess(lines) enddef -" Test for garbage collecting an enum with a complex member variables. -func Test_class_selfref_gc() +" Test for garbage collecting an enum with a complex member variables {{{1 +func Test_enum_selfref_gc() let lines =<< trim END vim9script enum Foo @@ -1664,7 +1691,7 @@ func Test_class_selfref_gc() call v9.CheckSourceSuccess(lines) endfunc -" Test for defining an enum in a function +" Test for defining an enum in a function {{{1 def Test_enum_defined_in_function() var lines =<< trim END vim9script @@ -1678,5 +1705,5 @@ def Test_enum_defined_in_function() END v9.CheckScriptFailure(lines, 'E1435: Enum can only be used in a script', 2) enddef - +" }}} " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 549145f2f1..a2faec225d 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -389,6 +389,12 @@ def Test_endfunc_enddef() enddef there END v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6) + + lines =<< trim END + def ShortEnddef() + endd + END + v9.CheckScriptFailure(lines, 'E1065: Command cannot be shortened: endd', 2) enddef def Test_missing_endfunc_enddef() diff --git a/src/testdir/test_vim9_interface.vim b/src/testdir/test_vim9_interface.vim index 742b871f16..f576e28475 100644 --- a/src/testdir/test_vim9_interface.vim +++ b/src/testdir/test_vim9_interface.vim @@ -1,8 +1,8 @@ -" Tests for Vim9 interface +" Tests for Vim9 script interfaces import './util/vim9.vim' as v9 -" Tests for basic interface declaration and errors +" Test for basic interface declaration and errors {{{1 def Test_interface_basics() var lines =<< trim END vim9script @@ -13,6 +13,14 @@ def Test_interface_basics() END v9.CheckSourceSuccess(lines) + # ":interface" and ":endinterface" + lines =<< trim END + vim9script + :interface I + :endinterface + END + v9.CheckSourceSuccess(lines) + lines =<< trim END interface SomethingWrong static var count = 7 @@ -78,6 +86,14 @@ def Test_interface_basics() END v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endin', 3) + # "endinterface" cannot be shortened (variant incl. colon-whitespace) + lines =<< trim END + vim9script + interface Short + : endint + END + v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endint', 3) + # Additional commands after "interface name" lines =<< trim END vim9script @@ -86,6 +102,14 @@ def Test_interface_basics() END v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2) + # Additional command after "endinterface" + lines =<< trim END + vim9script + interface NoTrailingCmd + endinterface | echo 'no' + END + v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'no'", 3) + lines =<< trim END vim9script export interface EnterExit @@ -124,6 +148,7 @@ def Test_interface_basics() v9.CheckScriptSuccess(lines) enddef +" Test for mismatched end command for class and interface {{{1 def Test_class_interface_wrong_end() var lines =<< trim END vim9script @@ -142,7 +167,7 @@ def Test_class_interface_wrong_end() v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4) enddef -" Test for using string() with an interface +" Test for using string() with an interface {{{1 def Test_interface_to_string() var lines =<< trim END vim9script @@ -154,6 +179,7 @@ def Test_interface_to_string() v9.CheckSourceSuccess(lines) enddef +" Test for a class implementing an interface {{{1 def Test_class_implements_interface() var lines =<< trim END vim9script @@ -281,13 +307,21 @@ def Test_class_implements_interface() END v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4) - # Trailing characters after a class name + # Trailing characters after an interface name lines =<< trim END vim9script - class A bbb - endclass + interface I nah + endinterface END - v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2) + v9.CheckSourceFailure(lines, 'E488: Trailing characters: nah', 2) + + # Additional words after "endinterface" + lines =<< trim END + vim9script + interface NoTrailingChars + endinterface nah + END + v9.CheckSourceFailure(lines, "E488: Trailing characters: nah", 3) # using "implements" with a non-existing class lines =<< trim END @@ -519,6 +553,7 @@ def Test_class_implements_interface() v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2) enddef +" Test for calling a method via an interface-typed variable {{{1 def Test_call_interface_method() var lines =<< trim END vim9script @@ -639,7 +674,7 @@ def Test_call_interface_method() v9.CheckSourceSuccess(lines) enddef -" Test for implementing an imported interface +" Test for implementing an imported interface {{{1 def Test_implement_imported_interface() var lines =<< trim END vim9script @@ -671,7 +706,7 @@ def Test_implement_imported_interface() v9.CheckScriptSuccess(lines) enddef -" Test for changing the member access of an interface in a implementation class +" Test for changing the member access of an interface in a implementation class {{{1 def Test_change_interface_member_access() var lines =<< trim END vim9script @@ -696,7 +731,7 @@ def Test_change_interface_member_access() v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7) enddef -" Test for using a interface method using a child object +" Test for using a interface method using a child object {{{1 def Test_interface_method_from_child() var lines =<< trim END vim9script @@ -732,8 +767,8 @@ def Test_interface_method_from_child() v9.CheckSourceSuccess(lines) enddef -" Test for using an interface method using a child object when it is overridden -" by the child class. +" Test for using an interface method using a child object when ... {{{1 +" it is overridden by the child class. def Test_interface_overridden_method_from_child() var lines =<< trim END vim9script @@ -772,7 +807,7 @@ def Test_interface_overridden_method_from_child() v9.CheckSourceSuccess(lines) enddef -" Test for interface inheritance +" Test for interface inheritance {{{1 def Test_interface_inheritance() var lines =<< trim END vim9script @@ -880,8 +915,8 @@ def Test_interface_inheritance() v9.CheckSourceSuccess(lines) enddef -" A interface cannot have a static variable or a static method or a protected -" variable or a protected method or a public variable +" Test for an interface cannot have a static variable/method ... {{{1 +" a protected variable/method, or a public variable def Test_interface_with_unsupported_members() var lines =<< trim END vim9script @@ -956,7 +991,7 @@ def Test_interface_with_unsupported_members() v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3) enddef -" Test for extending an interface +" Test for extending an interface {{{1 def Test_extend_interface() var lines =<< trim END vim9script @@ -1079,8 +1114,8 @@ def Test_extend_interface() v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11) enddef -" Test for a child class implementing an interface when some of the methods are -" defined in the parent class. +" Test for a child class implementing an interface when some ... {{{1 +" of the methods are defined in the parent class def Test_child_class_implements_interface() var lines =<< trim END vim9script @@ -1263,7 +1298,7 @@ def Test_child_class_implements_interface() v9.CheckSourceFailure(lines, 'E1382: Variable "var3": type mismatch, expected list> but got list>', 22) enddef -" Test for extending an interface with duplicate variables and methods +" Test for extending an interface with duplicate variables and methods {{{1 def Test_interface_extends_with_dup_members() var lines =<< trim END vim9script @@ -1304,8 +1339,8 @@ def Test_interface_extends_with_dup_members() v9.CheckSourceSuccess(lines) enddef -" Test for implementing an interface with different ordering for the interface -" member variables. +" Test for implementing an interface with different ordering for {{{1 +" the interface member variables def Test_implement_interface_with_different_variable_order() var lines =<< trim END vim9script @@ -1329,7 +1364,7 @@ def Test_implement_interface_with_different_variable_order() v9.CheckSourceSuccess(lines) enddef -" Test for inheriting interfaces from an imported super class +" Test for inheriting interfaces from an imported super class {{{1 def Test_interface_inheritance_with_imported_super() var lines =<< trim END vim9script @@ -1367,7 +1402,7 @@ def Test_interface_inheritance_with_imported_super() v9.CheckSourceSuccess(lines) enddef -" Test for defining an interface in a function +" Test for defining an interface in a function {{{1 def Test_interface_defined_in_function() var lines =<< trim END vim9script @@ -1381,8 +1416,8 @@ def Test_interface_defined_in_function() v9.CheckScriptFailure(lines, 'E1436: Interface can only be used in a script', 2) enddef -" Test for using "any" type for a variable in a sub-class while it has a -" concrete type in the interface +" Test for using "any" type for a variable in a sub-class while ... {{{1 +" it has a concrete type in the interface def Test_implements_using_var_type_any() var lines =<< trim END vim9script @@ -1411,7 +1446,7 @@ def Test_implements_using_var_type_any() v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list> but got dict', 1) enddef -" Test interface garbage collection +" Test interface garbage collection {{{1 func Test_interface_garbagecollect() let lines =<< trim END vim9script @@ -1455,5 +1490,5 @@ func Test_interface_garbagecollect() END call v9.CheckSourceSuccess(lines) endfunc - +" }}} " 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 eefb6174d8..2f54f6da62 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -3,6 +3,7 @@ import './util/vim9.vim' as v9 source util/screendump.vim +" Test for has('vim9script') def Test_vim9script_feature() # example from the help, here the feature is always present var lines =<< trim END @@ -1216,7 +1217,7 @@ def Test_error_in_catch() v9.CheckDefExecFailure(lines, 'E684:', 4) enddef -" :while at the very start of a function that :continue jumps to +" Test for :while at the very start of a function that :continue jumps to def s:TryContinueFunc() while g:Count < 2 g:sequence ..= 't' @@ -1330,8 +1331,8 @@ def Test_nocatch_throw_silenced() source XthrowSilenced enddef -" g:DeletedFunc() is found when compiling Test_try_catch_throw() and then -" deleted, this should give a runtime error. +" Test for g:DeletedFunc() is found when compiling Test_try_catch_throw() and +" then deleted, this should give a runtime error. def DeletedFunc(): list return ['delete me'] enddef @@ -1522,7 +1523,7 @@ def Try_catch_skipped() endif enddef -" The skipped try/endtry was updating the wrong instruction. +" Test for when the skipped try/endtry was updating the wrong instruction. def Test_try_catch_skipped() var instr = execute('disassemble Try_catch_skipped') assert_match("NEWLIST size 0\n", instr) @@ -4376,62 +4377,144 @@ def Run_test_reject_declaration() g:StopVimInTerminal(buf) enddef -def Test_minimal_command_name_length() - var names = [ - 'cons', - 'brea', - 'cat', - 'catc', - 'con', - 'cont', - 'conti', - 'contin', - 'continu', - 'el', - 'els', - 'elsei', - 'endfo', - 'en', - 'end', - 'endi', - 'endw', - 'endt', - 'endtr', - 'exp', - 'expo', - 'expor', - 'fina', - 'finall', - 'fini', - 'finis', - 'imp', - 'impo', - 'impor', - 'retu', - 'retur', - 'th', - 'thr', - 'thro', - 'wh', - 'whi', - 'whil', - ] - for name in names - v9.CheckDefAndScriptFailure([name .. ' '], 'E1065:') +" Test shortened commands that are invalid in Vim9 script +def Test_shortened_invalid_vim9() + # Many Vim9 script commands cannot be shortened/abbreviated. + # SHORTENED is a list of dicts, each with a single key (the exact shortened + # command) and a list value with four items: + # [0] list Lines passed to the check function (without 'vim9script' + # for SourceFailure lines) + # [1] number Line number where the error is expected ('vimscript', + # which is not in the list, is line 1 in the + # 'SourceFailure' and 'DefFailure lines, so needs to be + # included in the count) + # [2] string 'DefAndScriptFailure', 'SourceFailure', or 'DefFailure' + # specifying the applicable 'Check' function to call + const SHORTENED: list>> = [ + # abstract + {abs: [['abs class A'], 1, 'DefAndScriptFailure']}, + {abst: [['abst class A'], 1, 'DefAndScriptFailure']}, + {abstr: [['abstr class A'], 1, 'DefAndScriptFailure']}, + {abstra: [['abstra class A'], 1, 'DefAndScriptFailure']}, + {abstrac: [['abstrac class A'], 1, 'DefAndScriptFailure']}, + # break + {brea: [['for k in range(0, 2)', 'brea', 'endfor'], 2, 'DefAndScriptFailure']}, + # catch + {cat: [['try', 'echo 0', 'cat'], 3, 'DefAndScriptFailure']}, + {catc: [['try', 'echo 0', 'catc'], 3, 'DefAndScriptFailure']}, + # class - n/a because :clas is :clast + # const + {cons: [['cons C = 0'], 1, 'DefAndScriptFailure']}, + # continue + {con: [['var n: number', 'while n < 9', '++n', 'con'], 4, 'DefAndScriptFailure']}, + {cont: [['var n: number', 'while n < 9', '++n', 'cont'], 4, 'DefAndScriptFailure']}, + {conti: [['var n: number', 'while n < 9', '++n', 'conti'], 4, 'DefAndScriptFailure']}, + {contin: [['var n: number', 'while n < 9', '++n', 'contin'], 4, 'DefAndScriptFailure']}, + {continu: [['var n: number', 'while n < 9', '++n', 'continu'], 4, 'DefAndScriptFailure']}, + # def has no applicable shortened form (:de is :delete) + # else + {els: [['if true', 'els'], 2, 'DefAndScriptFailure']}, + # elseif + {elsei: [['if true', 'elsei false'], 2, 'DefAndScriptFailure']}, + # endclass + {endc: [['class C', 'endc'], 3, 'SourceFailure']}, + {endcl: [['class C', 'endcl'], 3, 'SourceFailure']}, + {endcla: [['class C', 'endcla'], 3, 'SourceFailure']}, + {endclas: [['class C', 'endclas'], 3, 'SourceFailure']}, + # enddef + # (NB: The separate DefFailure check tests them nested - + # DefAndScriptFailure cannot be used for testing :endd[e]) + {endd: [['def D()', 'endd'], 3, 'SourceFailure']}, + {endde: [['def D()', 'endde'], 3, 'SourceFailure']}, + {endd: [['var R: func = (): bool => {', 'def D()', 'endd', '}'], 4, 'DefFailure']}, + {endde: [['var R: func = (): bool => {', 'def D()', 'endde', '}'], 4, 'DefFailure']}, + # endenum + {ende: [['enum E', 'ende'], 3, 'SourceFailure']}, + {enden: [['enum E', 'enden'], 3, 'SourceFailure']}, + {endenu: [['enum E', 'endenu'], 3, 'SourceFailure']}, + # endfor + {endfo: [['for n in range(0, 2)', 'endfo'], 2, 'DefAndScriptFailure']}, + # endif + {en: [['if true', 'en'], 2, 'DefAndScriptFailure']}, + {end: [['if true', 'end'], 2, 'DefAndScriptFailure']}, + {endi: [['if true', 'endi'], 2, 'DefAndScriptFailure']}, + # endinterface + {endin: [['interface I', 'endin'], 3, 'SourceFailure']}, + {endint: [['interface I', 'endint'], 3, 'SourceFailure']}, + {endinte: [['interface I', 'endinte'], 3, 'SourceFailure']}, + {endinter: [['interface I', 'endinter'], 3, 'SourceFailure']}, + {endinterf: [['interface I', 'endinterf'], 3, 'SourceFailure']}, + {endinterfa: [['interface I', 'endinterfa'], 3, 'SourceFailure']}, + {endinterfac: [['interface I', 'endinterfac'], 3, 'SourceFailure']}, + # endtry + {endt: [['try', 'echo 0', 'endt'], 3, 'DefAndScriptFailure']}, + {endtr: [['try', 'echo 0', 'endtr'], 3, 'DefAndScriptFailure']}, + # endwhile + {endw: [['var n = 9', 'while n > 0', '--n', 'endw'], 4, 'DefAndScriptFailure']}, + {endwh: [['var n = 9', 'while n > 0', '--n', 'endwh'], 4, 'DefAndScriptFailure']}, + {endwhi: [['var n = 9', 'while n > 0', '--n', 'endwhi'], 4, 'DefAndScriptFailure']}, + {endwhil: [['var n = 9', 'while n > 0', '--n', 'endwhil'], 4, 'DefAndScriptFailure']}, + # enum + {enu: [['enu E', 'endenum'], 2, 'SourceFailure']}, + # export + {exp: [['exp var b: bool'], 2, 'SourceFailure']}, + {expo: [['expo var b: bool'], 2, 'SourceFailure']}, + {expor: [['expor var b: bool'], 2, 'SourceFailure']}, + # final has no applicable shortened form (because :fina is short for :finally) + # finally + {fina: [['try', '# Do something', 'fina'], 3, 'DefAndScriptFailure']}, + # finish + {fini: [['fini'], 1, 'DefAndScriptFailure']}, + # import + {imp: [['imp $"{$VIMRUNTIME}/autoload/ccomplete.vim"'], 2, 'SourceFailure']}, + {impo: [['impo $"{$VIMRUNTIME}/autoload/ccomplete.vim"'], 2, 'SourceFailure']}, + {impor: [['impor $"{$VIMRUNTIME}/autoload/ccomplete.vim"'], 2, 'SourceFailure']}, + # interface + {inte: [['inte I', 'endinterface'], 2, 'SourceFailure']}, + {inter: [['inter I', 'endinterface'], 2, 'SourceFailure']}, + {interf: [['interf I', 'endinterface'], 2, 'SourceFailure']}, + {interfa: [['interfa I', 'endinterface'], 2, 'SourceFailure']}, + {interfac: [['interfac I', 'endinterface'], 2, 'SourceFailure']}, + # public + {pub: [['class P', 'pub var b: bool', 'endclass'], 3, 'SourceFailure']}, + {publ: [['class P', 'publ var b: bool', 'endclass'], 3, 'SourceFailure']}, + {publi: [['class P', 'publi var b: bool', 'endclass'], 3, 'SourceFailure']}, + # return (NB: line is 0 - for CheckDefAndScriptFailure the first line of the Vim9 script lambda function is considered 0) + {retu: [['var R: func = (): bool => {', 'retu false', '}'], 0, 'DefAndScriptFailure']}, + {retur: [['var R: func = (): bool => {', 'retur false', '}'], 0, 'DefAndScriptFailure']}, + # static + {stat: [['class S', 'stat var b: bool', 'endclass'], 3, 'SourceFailure']}, + {stati: [['class S', 'stati var b: bool', 'endclass'], 3, 'SourceFailure']}, + # this + {thi: [['thi'], 1, 'DefAndScriptFailure']}, + # throw + {th: [['try', 'th 9', 'catch 9', 'echo "Should give E1065"', 'thr'], 2, 'DefAndScriptFailure']}, + {thr: [['try', 'thr 9', 'catch 9', 'echo "Should give E1065"', 'thr'], 2, 'DefAndScriptFailure']}, + {thro: [['try', 'thro 9', 'catch 9', 'echo "Should give E1065"', 'thro'], 2, 'DefAndScriptFailure']}, + # type + {ty: [['ty ListOfBools = list'], 1, 'DefAndScriptFailure']}, + {typ: [['typ ListOfBools = list'], 1, 'DefAndScriptFailure']}, + # var + {va: [['va b: bool'], 1, 'DefAndScriptFailure']}, + # while + {wh: [['var n = 9', 'wh n > 0', '--n', 'endwhile'], 2, 'DefAndScriptFailure']}, + {whi: [['var n = 9', 'whi n > 0', '--n', 'endwhile'], 2, 'DefAndScriptFailure']}, + {whil: [['var n = 9', 'whil n > 0', '--n', 'endwhile'], 2, 'DefAndScriptFailure']}, + ] + for short in SHORTENED + const CMD: string = short->keys()[0] + const LINES: list = short[CMD][0] + const E1065: string = "E1065: Command cannot be shortened: " .. CMD + const LNUM: number = short[CMD][1] + const CHECK: string = short[CMD][2] + if CHECK == 'SourceFailure' + v9.CheckSourceFailure(['vim9script', LINES]->flattennew(), E1065, LNUM) + elseif CHECK == 'DefAndScriptFailure' + v9.CheckDefAndScriptFailure(LINES, E1065, LNUM) + elseif CHECK == 'DefFailure' + v9.CheckDefFailure(LINES, E1065, LNUM) + endif endfor - - var lines =<< trim END - vim9script - def SomeFunc() - endd - END - v9.CheckScriptFailure(lines, 'E1065:') - lines =<< trim END - vim9script - def SomeFunc() - endde - END - v9.CheckScriptFailure(lines, 'E1065:') enddef def Test_unset_any_variable() @@ -5759,6 +5842,28 @@ def Test_multikey_dict_in_block() unlet g:TestDict enddef +" Test for overriding a block level variable with a new script level variable +" and referring to it in a function. +def Test_block_var_override_with_script_var() + var lines =<< trim END + vim9script + + if true + var lines = ['a'] + lines->filter((_, _) => true) + endif + + var lines = [] + + def Fx() + lines->add('b') + enddef + Fx() + assert_equal(['b'], lines) + END + v9.CheckSourceSuccess(lines) +enddef + " Test for using the type() function with void def Test_type_func_with_void() var lines =<< trim END @@ -5770,27 +5875,6 @@ def Test_type_func_with_void() v9.CheckSourceFailure(lines, 'E1031: Cannot use void value', 4) enddef -" Keep this last, it messes up highlighting. -def Test_substitute_cmd() - new - setline(1, 'something') - :substitute(some(other( - assert_equal('otherthing', getline(1)) - bwipe! - - # also when the context is Vim9 script - var lines =<< trim END - vim9script - new - setline(1, 'something') - :substitute(some(other( - assert_equal('otherthing', getline(1)) - bwipe! - END - writefile(lines, 'Xvim9lines', 'D') - source Xvim9lines -enddef - def Test_call_stack_string() CheckScreendump var lines =<< trim END @@ -5825,4 +5909,213 @@ def Test_call_stack_string() g:StopVimInTerminal(buf) enddef +def Test_g_variable_not_shadowed_by_function() + var lines =<< trim END + vim9script + g:F = 1 + def F() + return 2 + enddef + def Check() + var x = g:F + assert_equal(1, x) + enddef + Check() + END + v9.CheckScriptSuccess(lines) +enddef + +" Test g: variable shadowed by script-local function in various expression contexts. +def Test_g_variable_shadow_multi_context() + var lines =<< trim END + vim9script + g:F = 1 + def F(): number + return 2 + enddef + + # 1. Assignment to local + def AssignCheck() + var x = g:F + assert_equal(1, x) + enddef + + # 2. Function argument + def ArgCheck(val: number): number + return val * 10 + enddef + def CallArg() + assert_equal(10, ArgCheck(g:F)) + enddef + + # 3. Return value + def ReturnCheck(): number + return g:F + enddef + + # 4. Binary operation + def BinaryCheck(): number + return g:F + 5 + enddef + + # 5. List literal element + def ListCheck(): list + return [g:F, 2, 3] + enddef + + # 6. Dict literal value + def DictCheck(): dict + return {val: g:F} + enddef + + # 7. Conditional expression + def CondCheck(): string + return g:F == 1 ? 'yes' : 'no' + enddef + + # 8. Loop condition (only evaluated once but still loads) + def LoopCheck(): number + var i = 0 + while i < g:F + i += 1 + endwhile + return i + enddef + + AssignCheck() + CallArg() + assert_equal(1, ReturnCheck()) + assert_equal(6, BinaryCheck()) + assert_equal([1, 2, 3], ListCheck()) + assert_equal({val: 1}, DictCheck()) + assert_equal('yes', CondCheck()) + assert_equal(1, LoopCheck()) + END + v9.CheckScriptSuccess(lines) + unlet g:F +enddef + +" Test that dead elseif conditions are skipped without errors inside a :def function +def Test_skip_elseif_dead_branch() + var lines =<< trim END + vim9script + def CompileTest() + if true + echo 'ok' + else + var x = 0 + if x > 0 + echo 'pos' + elseif x < 0 + echo 'neg' + endif + endif + enddef + CompileTest() + END + v9.CheckScriptSuccess(lines) +enddef + +" Another variation: using has() in a dead branch that would fail if compiled +def Test_skip_elseif_with_has_in_dead_branch() + var lines =<< trim END + vim9script + def HasTest() + if true + echo 'ok' + else + var x = 0 + if x > 0 + echo 'pos' + elseif has('clipboard') + echo 'neg' + endif + endif + enddef + HasTest() + END + v9.CheckScriptSuccess(lines) +enddef + +def Test_if_false_elseif_true_still_takes_elseif() + var lines =<< trim END + vim9script + var result = '' + def F() + if false + result = 'A' + elseif true + result = 'B' + else + result = 'C' + endif + enddef + F() + assert_equal('B', result) + END + v9.CheckScriptSuccess(lines) +enddef + +" Test for correct fullcommand() outputs: return the correct command (or '') +def Test_builtin_fullcommand() + # :hor is the minimum abbreviation of :horizontal; :ho is invalid + assert_equal('', fullcommand('ho', true)) + assert_equal('horizontal', fullcommand('hor', true)) + + # :k is an invalid one-letter command in Vim9 script + assert_equal('', fullcommand('k', true)) + assert_equal('', fullcommand(':k', true)) + assert_equal('', fullcommand('karrrrrgh!', true)) + assert_equal('k', fullcommand('k', false)) + assert_equal('k', fullcommand(':k', false)) + assert_equal('k', fullcommand('karrrrrgh!', false)) + + # :dl is "delete and list" in legacy Vim script but, because :dl itself is + # invalid in Vim9 script, :dl is 'dlist' in Vim9 script + assert_equal('delete', fullcommand('dl', v:false)) + assert_equal('dlist', fullcommand('dl', v:true)) + + # Substitute :s two and three letter commands in legacy Vim script are + # invalid in Vim9 script + assert_equal('', fullcommand('sIr', true)) + assert_equal('', fullcommand('sIrarrrrrgh!', true)) + assert_equal('substitute', fullcommand('sIr', false)) + assert_equal('substitute', fullcommand('sIrarrrrrgh!', false)) + + # Three :s? commands are exceptionss, returning different commands depending + # on whether the scope is legacy Vim script or Vim9 script + assert_equal('scriptnames', fullcommand('sc', true)) + assert_equal('simalt', fullcommand('si', true)) + assert_equal('srewind', fullcommand('sr', true)) + assert_equal('substitute', fullcommand('sc', false)) + assert_equal('substitute', fullcommand('si', false)) + assert_equal('substitute', fullcommand('sr', false)) + + # :finally cannot be shortened in Vim9 script but :final should return 'final' + assert_equal('', fullcommand('fina', true)) + assert_equal('final', fullcommand('final', true)) + assert_equal('', fullcommand('finall', true)) +enddef + +" Keep this last, it messes up highlighting. +def Test_substitute_cmd() + new + setline(1, 'something') + :substitute(some(other( + assert_equal('otherthing', getline(1)) + bwipe! + + # also when the context is Vim9 script + var lines =<< trim END + vim9script + new + setline(1, 'something') + :substitute(some(other( + assert_equal('otherthing', getline(1)) + bwipe! + END + writefile(lines, 'Xvim9lines', 'D') + source Xvim9lines +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim index 49f34a578c..a07ed6eadf 100644 --- a/src/testdir/test_vimscript.vim +++ b/src/testdir/test_vimscript.vim @@ -7702,6 +7702,33 @@ func Test_function_long_generic_name() delfunc TestFunc endfunc +" Test using fullcommand() {{{1 +func Test_builtin_fullcommand() + " :hor is the minimum abbreviation of :horizontal; :ho is invalid + call assert_equal('', fullcommand('ho')) + call assert_equal('horizontal', fullcommand('hor')) + + " :k takes one {a-zA-Z'} mark argument and optional whitespace + call assert_equal('k', fullcommand('k')) + call assert_equal('k', fullcommand(':k')) + call assert_equal('k', fullcommand('karrrrrgh!')) + + " :dl is "delete and list" in a legacy Vim script scope + call assert_equal('delete', fullcommand('dl')) + + " :s two and three letter commands + call assert_equal('substitute', fullcommand('sIr')) + call assert_equal('substitute', fullcommand('sIrarrrrrgh!')) + + " :finally + call assert_equal('finally', fullcommand('fina')) + " 'final' - returns 'final', a Vim9 script-exclusive keyword + " - is a valid shortening of :finally in legacy Vim script + call assert_equal('final', fullcommand('final')) + call assert_equal('finally', fullcommand('finall')) + +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 7819025f6b..902bbbfd1e 100644 --- a/src/testdir/test_virtualedit.vim +++ b/src/testdir/test_virtualedit.vim @@ -753,4 +753,39 @@ func Test_virtualedit_getpos_stable_past_eol_after_visual() bwipe! endfunc +func Test_virtualedit_insert() + new + set virtualedit=insert + + call feedkeys("ifoobar\\\\baz\", 'tnix') + call assert_equal('foobar baz', getline(1)) + + call feedkeys("ccFOOBAR\\\\BAZ\", 'tnix') + call assert_equal('FOOBAR BAZ', getline(1)) + + set virtualedit& + bwipe! +endfunc + +func Test_set_virtualedit_on_mode_change() + new + set virtualedit=all + augroup testing + au ModeChanged n:* set virtualedit=onemore + au ModeChanged *:n set virtualedit=all + au ModeChanged i:* call cursor(getpos("'^")[1:]) + augroup END + + call feedkeys("ilkj\", 'tnix') + call assert_equal([0, 1, 4, 0], getpos('.')) + + call feedkeys("cclkj\", 'tnix') + call assert_equal([0, 1, 4, 0], getpos('.')) + + au! testing ModeChanged + augroup! testing + 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 ac27354d48..d92f651d9a 100644 --- a/src/testdir/test_visual.vim +++ b/src/testdir/test_visual.vim @@ -1321,6 +1321,7 @@ func Test_visual_block_with_virtualedit() let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50}) call term_sendkeys(buf, "\gg$") + call WaitForAssert({-> assert_match('VISUAL.*\dx\d', term_getline(buf, 8))}, 1000) call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {}) call term_sendkeys(buf, "\gg\G$") diff --git a/src/testdir/test_wayland.vim b/src/testdir/test_wayland.vim index c690d0cfe9..9049075637 100644 --- a/src/testdir/test_wayland.vim +++ b/src/testdir/test_wayland.vim @@ -31,31 +31,6 @@ func s:PreTest() set cpm=wayland endfunc -func s:SetupFocusStealing() - CheckFeature wayland_focus_steal - if !executable('wayland-info') - throw "Skipped: wayland-info program not available" - endif - - " Starting a headless compositor won't expose a keyboard capability for its - " seat, so we must use the user's existing Wayland session if they are in one. - let $WAYLAND_DISPLAY = s:old_wayland_display - - exe 'wlrestore! ' .. $WAYLAND_DISPLAY - - " Check if we have keyboard capability for seat - if system("wayland-info -i wl_seat | grep capabilities") !~? "keyboard" - throw "Skipped: seat does not have keyboard" - endif - - let $VIM_WAYLAND_FORCE_FS=1 - wlrestore! -endfunc - -func s:UnsetupFocusStealing() - unlet $VIM_WAYLAND_FORCE_FS -endfunc - func s:CheckClientserver() CheckFeature clientserver @@ -487,31 +462,6 @@ func Test_wayland_seat() set wlseat& endfunc -" Test focus stealing -func Test_wayland_focus_steal() - CheckFeature wayland_focus_steal - call s:PreTest() - call s:SetupFocusStealing() - - call system('wl-copy regular') - - call assert_equal('regular', getreg('+')) - - call system('wl-copy -p primary') - - call assert_equal('primary', getreg('*')) - - call setreg('+', 'REGULAR') - - call assert_equal('REGULAR', system('wl-paste -n')) - - call setreg('*', 'PRIMARY') - - call assert_equal('PRIMARY', system('wl-paste -p -n')) - - call s:UnsetupFocusStealing() -endfunc - " Test when environment is not suitable for Wayland func Test_wayland_bad_environment() call s:PreTest() @@ -564,32 +514,6 @@ func Test_wayland_lost_selection() endfunc -" Same as above but for the focus stealing method -func Test_wayland_lost_selection_focus_steal() - call s:PreTest() - call s:SetupFocusStealing() - - call setreg('+', 'regular') - call setreg('*', 'primary') - - call assert_equal('regular', getreg('+')) - call assert_equal('primary', getreg('*')) - - call system('wl-copy overwrite') - call system('wl-copy -p overwrite') - - call assert_equal('overwrite', getreg('+')) - call assert_equal('overwrite-primary', getreg('*')) - - call setreg('+', 'regular') - call setreg('*', 'primary') - - call assert_equal('regular', getreg('+')) - call assert_equal('primary', getreg('*')) - - call s:UnsetupFocusStealing() -endfunc - " Test when there are no supported mime types for the selection func Test_wayland_no_mime_types_supported() call s:PreTest() diff --git a/src/testdir/test_winbar.vim b/src/testdir/test_winbar.vim index 59241746b9..3a9ca68e8d 100644 --- a/src/testdir/test_winbar.vim +++ b/src/testdir/test_winbar.vim @@ -157,6 +157,36 @@ func Test_winbar_not_visible_custom_statusline() call StopVimInTerminal(buf) endfunction +" The vertical separator on the WinBar row must follow VertSplit/VertSplitNC +" when the current window changes. +func Test_winbar_vsep_highlight_after_focus_change() + CheckScreendump + + let lines =<< trim END + vim9script + wincmd s + wincmd v + wincmd v + wincmd j + wincmd v + nnoremenu 1.10 WinBar.Step :Step + nnoremenu 1.20 WinBar.Next :Next + nnoremenu 1.30 WinBar.Finish :Finish + nnoremenu 1.40 WinBar.Cont :Continue + hi Vertsplit term=reverse ctermfg=111 + hi VertsplitNC term=reverse ctermfg=16 + END + call writefile(lines, 'XtestWinbarVsep', 'D') + let buf = RunVimInTerminal('-S XtestWinbarVsep', #{rows: 20, cols: 60}) + + call VerifyScreenDump(buf, 'Test_winbar_vsep_active', {}) + + call term_sendkeys(buf, "\k") + call VerifyScreenDump(buf, 'Test_winbar_vsep_inactive', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_drag_statusline_with_winbar() call SetupWinbar() let save_mouse = &mouse diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim index aa631b2905..e7f391ed9c 100644 --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -113,7 +113,39 @@ func Test_window_cmd_wincmd_gf() call assert_notequal(fname, bufname("%")) new | only! + au! test_window_cmd_wincmd_gf augroup! test_window_cmd_wincmd_gf + delfunc s:swap_exists + bw! +endfunc + +func Test_abort_in_wincmd_f() + let fname = 'test_f.txt' + let swp_fname = $'.{fname}.swp' + call writefile([], fname, 'D') + call writefile([], swp_fname, 'D') + " Remove the catch-all that runtest.vim adds + au! SwapExists + augroup test_window_cmd_wincmd_f + autocmd! + " (A)bort + autocmd SwapExists test_f.txt let v:swapchoice = 'a' + augroup END + + call setline(1, fname) + call assert_equal(1, winnr('$')) + try + wincmd f + catch /^Vim:Interrupt$/ + " expected interrupt by abort + endtry + call assert_equal(1, winnr('$')) + new | only! + + " See :h W19 for the background of this au!. Ideally other tests + " should also follow this. + au! test_window_cmd_wincmd_f + augroup! test_window_cmd_wincmd_f bw! endfunc @@ -1992,6 +2024,16 @@ func Test_splitkeep_screen_cursor_pos() set splitkeep& endfunc +func Test_splitkeep_cmdheight() + set splitkeep=screen + call setline(1, range(&lines)) + norm! G + set cmdheight=2 + call assert_equal(&lines - 1, line('.')) + %bwipeout! + set splitkeep& cmdheight& +endfunc + func Test_splitkeep_cursor() CheckScreendump let lines =<< trim END diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim index 472dfd4ee9..990683b172 100644 --- a/src/testdir/test_xxd.vim +++ b/src/testdir/test_xxd.vim @@ -476,7 +476,7 @@ func Test_xxd_buffer_overflow() endif new let input = repeat('A', 256) - call writefile(['-9223372036854775808: ' . repeat("\e[1;32m41\e[0m ", 256) . ' ' . "\e[1;32m" . repeat('A', 256) . "\e[0m"], 'Xxdexpected', 'D') + call writefile(['9223372036854775808: ' . repeat("\e[1;32m41\e[0m ", 256) . ' ' . "\e[1;32m" . repeat('A', 256) . "\e[0m"], 'Xxdexpected', 'D') exe 'r! printf ' . input . '| ' . s:xxd_cmd . ' -Ralways -g1 -c256 -d -o 9223372036854775808 > Xxdout' call assert_equalfile('Xxdexpected', 'Xxdout') call delete('Xxdout') @@ -663,6 +663,22 @@ call writefile(data,'Xinput') endfunc +func Test_xxd_color_bits() + " Binary output (-b) should be colored per byte like the hex output, + " see issue #20385. Bytes cover the white/yellow/green/blue color groups. + let s:test = 1 + call writefile(0z000941FF, 'Xxxdbits') + + %d + exe '0r! ' . s:xxd_cmd . ' -b -R always -c 4 Xxxdbits' + $d + let expected = [ + \ "00000000: \e[1;37m00000000\e[0m \e[1;33m00001001\e[0m \e[1;32m01000001\e[0m \e[1;34m11111111\e[0m \e[1;37m.\e[0m\e[1;33m.\e[0m\e[1;32mA\e[0m\e[1;34m.\e[0m"] + call assert_equal(expected, getline(1, '$'), s:Mess(s:test)) + + call delete('Xxxdbits') +endfunc + func Test_xxd_color2() CheckScreendump CheckUnix diff --git a/src/testdir/util/check.vim b/src/testdir/util/check.vim index fff8bc4551..67cb4efed9 100644 --- a/src/testdir/util/check.vim +++ b/src/testdir/util/check.vim @@ -356,17 +356,6 @@ func CheckGithubActions() endif endfunc -command RunSocketServer call RunSocketServer() -func RunSocketServer() - if has("socketserver") && v:servername == "" - try - call remote_startserver('VIMSOCKETSERVERTEST') - catch " not possible to start a remote server - throw 'Skipped: Cannot start remote server' - endtry - endif -endfunc - let &cpo = s:cpo_save unlet s:cpo_save " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/util/gen_opt_test.vim b/src/testdir/util/gen_opt_test.vim index 1cd0fec7ce..250ed669b6 100644 --- a/src/testdir/util/gen_opt_test.vim +++ b/src/testdir/util/gen_opt_test.vim @@ -24,6 +24,7 @@ while search("^'[^']*'.*\\n.*|global-local", 'W') endwhile call extend(global_locals, #{ \ scrolloff: -1, + \ scrolloffpad: -1, \ sidescrolloff: -1, \ undolevels: -123456, \}) @@ -93,6 +94,7 @@ let test_values = { \ 'scroll': [[0, 1, 2, 15], [-1, 999]], \ 'scrolljump': [[-100, -1, 0, 1, 2, 15], [-101, 999]], \ 'scrolloff': [[0, 1, 8, 999], [-1]], + \ 'scrolloffpad': [[0, 1, 2, 3], [-1]], \ 'shiftwidth': [[0, 1, 8, 999], [-1]], \ 'showtabpanel': [[0, 1, 2], []], \ 'sidescroll': [[0, 1, 8, 999], [-1]], @@ -305,6 +307,10 @@ let test_values = { \ 'sessionoptions': [['', 'blank', 'curdir', 'sesdir', \ 'help,options,slash'], \ ['xxx', 'curdir,sesdir']], + \ 'shellpipe': [[ '', '>', '>%s2>&1', '\|tee', '\|&tee', '2>&1\|tee', '%%'], + \ ['%s%s%s', '%s%p%d']], + \ 'shellredir': [[ '', '>', '>%s2>&1', '\|tee', '\|&tee', '2>&1\|tee', '%%'], + \ ['%s%s%s', '%s%p%d']], \ 'showcmdloc': [['', 'last', 'statusline', 'tabline'], ['xxx']], \ 'signcolumn': [['', 'auto', 'no', 'yes', 'number'], ['xxx', 'no,yes']], \ 'spellfile': [['', 'file.en.add', 'xxx.en.add,yyy.gb.add,zzz.ja.add', @@ -328,9 +334,11 @@ let test_values = { \ 'tabline': [['', 'xxx'], ['%$', '%{', '%{%', '%{%}', '%(', '%)']], \ 'tabpanel': [['', 'aaa', 'bbb'], []], \ 'tabpanelopt': [['', 'align:left', 'align:right', 'vert', 'columns:0', - \ 'columns:20', 'columns:999'], + \ 'columns:20', 'columns:999', 'scrollbar', + \ 'columns:15,vert,scrollbar', + \ 'align:right,columns:12,vert,scrollbar'], \ ['xxx', 'align:', 'align:middle', 'colomns:', 'cols:10', - \ 'cols:-1']], + \ 'cols:-1', 'scroll', 'scrol', 'scrollbarx']], \ 'tagcase': [['followic', 'followscs', 'ignore', 'match', 'smart'], \ ['', 'xxx', 'smart,match']], \ 'termencoding': [(has('gui_gtk') || has('gui_macvim')) ? [] : ['', 'utf-8'], ['xxx']], @@ -361,6 +369,7 @@ let test_values = { \ ['xxx']], \ 'wildmode': [['', 'full', 'longest', 'list', 'lastused', 'list:full', \ 'noselect', 'noselect,full', 'noselect:lastused,full', + \ 'noinsert', 'noinsert,full', 'noinsert:lastused,full', \ 'full,longest', 'full,full,full,full'], \ ['xxx', 'a4', 'full,full,full,full,full']], \ 'wildoptions': [['', 'tagfile', 'pum', 'fuzzy'], ['xxx']], diff --git a/src/testdir/util/socketserver.vim b/src/testdir/util/socketserver.vim deleted file mode 100644 index 5492db626d..0000000000 --- a/src/testdir/util/socketserver.vim +++ /dev/null @@ -1,17 +0,0 @@ -" Check if only the socketserver backend is available for clientserver (only on -" Unix), and set g:socketserver_only to v:true along with starting the -" socketserver. -command TrySocketServer call TrySocketServer() -func TrySocketServer() - if has("socketserver") && !has("x11") - let g:socketserver_only = v:true - - if v:servername == "" - call remote_startserver('VIMSOCKETSERVERTEST') - endif - else - let g:socketserver_only = v:false - endif -endfunc - -" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/textprop.c b/src/textprop.c index 33165a8e43..a049edec9b 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -965,7 +965,7 @@ f_prop_add_list(typval_T *argvars, typval_T *rettv UNUSED) // This must be done _before_ we start adding properties because property // changes trigger buffer (memline) reorganisation, which needs this flag // to be correctly set. - buf->b_has_textprop = TRUE; // this is never reset + buf->b_has_textprop = true; // this is never reset FOR_ALL_LIST_ITEMS(argvars[1].vval.v_list, li) { if (li->li_tv.v_type != VAR_LIST || li->li_tv.vval.v_list == NULL) @@ -1187,7 +1187,7 @@ prop_add_common( // This must be done _before_ we add the property because property changes // trigger buffer (memline) reorganisation, which needs this flag to be // correctly set. - buf->b_has_textprop = TRUE; // this is never reset + buf->b_has_textprop = true; // this is never reset prop_add_one(buf, type_name, id, text, text_padding_left, flags, start_lnum, end_lnum, start_col, end_col); @@ -1396,25 +1396,28 @@ sort_text_props( } /* - * Find text property "type_id" in the visible lines of window "wp". - * Match "id" when it is > 0. - * Returns false when not found. + * Find text property "type_id" in lines [first_lnum, last_lnum] of window + * "wp"'s buffer. Match "id" when it is > 0. Returns false when not found. */ bool -find_visible_prop( +find_prop_in_lines( win_T *wp, int type_id, int id, textprop_T *prop, - linenr_T *found_lnum) + linenr_T *found_lnum, + linenr_T first_lnum, + linenr_T last_lnum) { - // return when "type_id" no longer exists if (text_prop_type_by_id(wp->w_buffer, type_id) == NULL) return false; - // w_botline may not have been updated yet. - validate_botline_win(wp); - for (linenr_T lnum = wp->w_topline; lnum < wp->w_botline; ++lnum) + if (first_lnum < 1) + first_lnum = 1; + if (last_lnum > wp->w_buffer->b_ml.ml_line_count) + last_lnum = wp->w_buffer->b_ml.ml_line_count; + + for (linenr_T lnum = first_lnum; lnum <= last_lnum; ++lnum) { char_u *props; int count = get_text_props(wp->w_buffer, lnum, &props, FALSE); @@ -1432,6 +1435,25 @@ find_visible_prop( return false; } +/* + * Find text property "type_id" in the visible lines of window "wp". + * Match "id" when it is > 0. + * Returns false when not found. + */ + bool +find_visible_prop( + win_T *wp, + int type_id, + int id, + textprop_T *prop, + linenr_T *found_lnum) +{ + // w_botline may not have been updated yet. + validate_botline_win(wp); + return find_prop_in_lines(wp, type_id, id, prop, found_lnum, + wp->w_topline, wp->w_botline - 1); +} + /* * Set the text properties for line "lnum" to "tps" array with "count" entries. * If "count" is zero text properties are removed. @@ -1727,23 +1749,26 @@ prop_fill_dict(dict_T *dict, textprop_T *prop, buf_T *buf) dict_add_number(dict, "type_bufnr", 0); if (virtualtext_prop) { + string_T text_align = {NULL, 0}; + // virtual text property - u.tp_text must be set by caller dict_add_string(dict, "text", prop->u.tp_text); // text_align - char_u *text_align = NULL; if (prop->tp_flags & TP_FLAG_ALIGN_RIGHT) - text_align = (char_u *)"right"; + STR_LITERAL_SET(text_align, "right"); else if (prop->tp_flags & TP_FLAG_ALIGN_ABOVE) - text_align = (char_u *)"above"; + STR_LITERAL_SET(text_align, "above"); else if (prop->tp_flags & TP_FLAG_ALIGN_BELOW) - text_align = (char_u *)"below"; - if (text_align != NULL) - dict_add_string(dict, "text_align", text_align); + STR_LITERAL_SET(text_align, "below"); + if (text_align.string != NULL) + dict_add_string_len(dict, "text_align", + text_align.string, (int)text_align.length); // text_wrap if (prop->tp_flags & TP_FLAG_WRAP) - dict_add_string(dict, "text_wrap", (char_u *)"wrap"); + dict_add_string_len(dict, "text_wrap", + (char_u *)"wrap", STRLEN_LITERAL("wrap")); if (prop->tp_padleft != 0) dict_add_number(dict, "text_padding_left", prop->tp_padleft); } @@ -1964,12 +1989,16 @@ f_prop_find(typval_T *argvars, typval_T *rettv) // after `col`, depending on the search direction. if (lnum == lnum_start) { + bool is_floating_vtext = prop.tp_id < 0 + && prop.tp_col == MAXCOL; if (dir == BACKWARD) { - if (prop.tp_col > col) + // Virtual text with MAXCOL always matches any column + if (!is_floating_vtext && prop.tp_col > col) continue; } - else if (prop.tp_col + prop.tp_len - (prop.tp_len != 0) < col) + else if (!is_floating_vtext + && prop.tp_col + prop.tp_len - (prop.tp_len != 0) < col) continue; } if (both ? prop.tp_id == id && prop.tp_type == type_id diff --git a/src/time.c b/src/time.c index 16112d6eeb..8166b09d1f 100644 --- a/src/time.c +++ b/src/time.c @@ -381,6 +381,10 @@ f_strptime(typval_T *argvars, typval_T *rettv) convert_setup(&conv, p_enc, enc); if (conv.vc_type != CONV_NONE) fmt = string_convert(&conv, fmt, NULL); +# ifdef HAVE_TZSET + // Pick up any change to $TZ so mktime() uses the requested timezone. + tzset(); +# endif if (fmt == NULL || strptime((char *)str, (char *)fmt, &tmval) == NULL || (rettv->vval.v_number = mktime(&tmval)) == -1) diff --git a/src/ui.c b/src/ui.c index b1d1e1e188..fea5506e60 100644 --- a/src/ui.c +++ b/src/ui.c @@ -406,20 +406,10 @@ inchar_loop( # endif if ((resize_func != NULL && resize_func(TRUE)) -# if defined(FEAT_CLIENTSERVER) && defined(UNIX) && !defined(MAC_CLIENTSERVER) - || ( -# ifdef FEAT_X11 - (clientserver_method == CLIENTSERVER_METHOD_X11 && - server_waiting()) -# endif -# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER) - || -# endif -# ifdef FEAT_SOCKETSERVER - (clientserver_method == CLIENTSERVER_METHOD_SOCKET && - socket_server_waiting_accept()) -# endif - ) +# if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) && !defined(MAC_CLIENTSERVER) + || + (clientserver_method == CLIENTSERVER_METHOD_X11 && + server_waiting()) # endif # ifdef MESSAGE_QUEUE || interrupted diff --git a/src/undo.c b/src/undo.c index 2e3bfd4a3a..85ab669534 100644 --- a/src/undo.c +++ b/src/undo.c @@ -495,12 +495,12 @@ u_savecommon( size = bot - top - 1; /* - * If curbuf->b_u_synced == TRUE make a new header. + * If curbuf->b_u_synced is true make a new header. */ if (curbuf->b_u_synced) { // Need to create new entry in b_changelist. - curbuf->b_new_change = TRUE; + curbuf->b_new_change = true; if (get_undolevel() >= 0) { @@ -559,7 +559,7 @@ u_savecommon( { if (old_curhead != NULL) u_freebranch(curbuf, old_curhead, NULL); - curbuf->b_u_synced = FALSE; + curbuf->b_u_synced = false; return OK; } @@ -653,7 +653,7 @@ u_savecommon( // entry now. Following deleted/inserted lines go to // the re-used entry. u_getbot(); - curbuf->b_u_synced = FALSE; + curbuf->b_u_synced = false; // Move the found entry to become the last entry. The // order of undo/redo doesn't matter for the entries @@ -740,7 +740,7 @@ u_savecommon( uep->ue_array = NULL; uep->ue_next = curbuf->b_u_newhead->uh_entry; curbuf->b_u_newhead->uh_entry = uep; - curbuf->b_u_synced = FALSE; + curbuf->b_u_synced = false; undo_undoes = FALSE; #ifdef U_DEBUG @@ -2081,38 +2081,54 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name UNUSED) corruption_error("duplicate uh_seq", file_name); goto error; } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL - && uhp_table[j]->uh_seq == uhp->uh_next.seq) - { - uhp->uh_next.ptr = uhp_table[j]; - SET_FLAG(j); - break; - } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL - && uhp_table[j]->uh_seq == uhp->uh_prev.seq) - { - uhp->uh_prev.ptr = uhp_table[j]; - SET_FLAG(j); - break; - } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL - && uhp_table[j]->uh_seq == uhp->uh_alt_next.seq) - { - uhp->uh_alt_next.ptr = uhp_table[j]; - SET_FLAG(j); - break; - } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL - && uhp_table[j]->uh_seq == uhp->uh_alt_prev.seq) - { - uhp->uh_alt_prev.ptr = uhp_table[j]; - SET_FLAG(j); - break; - } + { + int seq = uhp->uh_next.seq; + uhp->uh_next.ptr = NULL; + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && i != j + && uhp_table[j]->uh_seq == seq) + { + uhp->uh_next.ptr = uhp_table[j]; + SET_FLAG(j); + break; + } + } + { + int seq = uhp->uh_prev.seq; + uhp->uh_prev.ptr = NULL; + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && i != j + && uhp_table[j]->uh_seq == seq) + { + uhp->uh_prev.ptr = uhp_table[j]; + SET_FLAG(j); + break; + } + } + { + int seq = uhp->uh_alt_next.seq; + uhp->uh_alt_next.ptr = NULL; + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && i != j + && uhp_table[j]->uh_seq == seq) + { + uhp->uh_alt_next.ptr = uhp_table[j]; + SET_FLAG(j); + break; + } + } + { + int seq = uhp->uh_alt_prev.seq; + uhp->uh_alt_prev.ptr = NULL; + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && i != j + && uhp_table[j]->uh_seq == seq) + { + uhp->uh_alt_prev.ptr = uhp_table[j]; + SET_FLAG(j); + break; + } + } if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq) { old_idx = i; @@ -2146,7 +2162,7 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name UNUSED) curbuf->b_u_save_nr_last = last_save_nr; curbuf->b_u_save_nr_cur = last_save_nr; - curbuf->b_u_synced = TRUE; + curbuf->b_u_synced = true; vim_free(uhp_table); # ifdef U_DEBUG @@ -2199,7 +2215,7 @@ u_undo(int count) * original vi. If this happens twice in one macro the result will not * be compatible. */ - if (curbuf->b_u_synced == FALSE) + if (!curbuf->b_u_synced) { u_sync(TRUE); count = 1; @@ -2262,7 +2278,8 @@ u_doit(int startcount) beep_flush(); if (count == startcount - 1) { - msg(_("Already at oldest change")); + if (!shortmess(SHM_UNDO)) + msg(_("Already at oldest change")); return; } break; @@ -2277,7 +2294,8 @@ u_doit(int startcount) beep_flush(); // nothing to redo if (count == startcount - 1) { - msg(_("Already at newest change")); + if (!shortmess(SHM_UNDO)) + msg(_("Already at newest change")); return; } break; @@ -2333,7 +2351,7 @@ undo_time( } // First make sure the current undoable change is synced. - if (curbuf->b_u_synced == FALSE) + if (!curbuf->b_u_synced) u_sync(TRUE); u_newcount = 0; @@ -2530,10 +2548,13 @@ undo_time( if (closest == closest_start) { - if (step < 0) - msg(_("Already at oldest change")); - else - msg(_("Already at newest change")); + if (!shortmess(SHM_UNDO)) + { + if (step < 0) + msg(_("Already at oldest change")); + else + msg(_("Already at newest change")); + } return; } @@ -2996,7 +3017,8 @@ u_undo_end( #endif if (global_busy // no messages now, wait until global is finished - || !messaging()) // 'lazyredraw' set, don't do messages now + || !messaging() // 'lazyredraw' set, don't do messages now + || shortmess(SHM_UNDO)) return; if (curbuf->b_ml.ml_flags & ML_EMPTY) @@ -3078,7 +3100,7 @@ u_sync( return; // XIM is busy, don't break an undo sequence #endif if (get_undolevel() < 0) - curbuf->b_u_synced = TRUE; // no entries, nothing to do + curbuf->b_u_synced = true; // no entries, nothing to do else { u_getbot(); // compute ue_bot of previous u_save @@ -3215,7 +3237,7 @@ ex_undojoin(exarg_T *eap UNUSED) return; // no entries, nothing to do else // Append next change to the last entry - curbuf->b_u_synced = FALSE; + curbuf->b_u_synced = false; } /* @@ -3226,7 +3248,7 @@ ex_undojoin(exarg_T *eap UNUSED) u_unchanged(buf_T *buf) { u_unch_branch(buf->b_u_oldhead); - buf->b_did_warn = FALSE; + buf->b_did_warn = false; } /* @@ -3319,7 +3341,7 @@ u_get_headentry(void) /* * u_getbot(): compute the line number of the previous u_save - * It is called only when b_u_synced is FALSE. + * It is called only when b_u_synced is false. */ static void u_getbot(void) @@ -3353,7 +3375,7 @@ u_getbot(void) curbuf->b_u_newhead->uh_getbot_entry = NULL; } - curbuf->b_u_synced = TRUE; + curbuf->b_u_synced = true; } /* @@ -3480,7 +3502,7 @@ u_freeentry(u_entry_T *uep, long n) u_clearall(buf_T *buf) { buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL; - buf->b_u_synced = TRUE; + buf->b_u_synced = true; buf->b_u_numhead = 0; buf->b_u_line_ptr.ul_line = NULL; buf->b_u_line_ptr.ul_len = 0; diff --git a/src/usercmd.c b/src/usercmd.c index cef1d18b79..2d47569653 100644 --- a/src/usercmd.c +++ b/src/usercmd.c @@ -344,15 +344,18 @@ set_context_in_user_cmdarg( return set_context_in_map_cmd(xp, (char_u *)"map", arg, forceit, FALSE, FALSE, CMD_map); // Find start of last argument. - p = arg; - while (*p) + if (!(argt & EX_ARGSPACE)) { - if (*p == ' ') - // argument starts after a space - arg = p + 1; - else if (*p == '\\' && *(p + 1) != NUL) - ++p; // skip over escaped character - MB_PTR_ADV(p); + p = arg; + while (*p) + { + if (*p == ' ') + // argument starts after a space + arg = p + 1; + else if (*p == '\\' && *(p + 1) != NUL) + ++p; // skip over escaped character + MB_PTR_ADV(p); + } } xp->xp_pattern = arg; xp->xp_context = context; @@ -451,7 +454,7 @@ get_user_cmd_flags(expand_T *xp UNUSED, int idx) char_u * get_user_cmd_nargs(expand_T *xp UNUSED, int idx) { - static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"}; + static char *user_cmd_nargs[] = {"0", "1", "_", "*", "?", "+"}; if (idx < 0 || idx >= (int)ARRAY_LENGTH(user_cmd_nargs)) return NULL; @@ -640,13 +643,14 @@ uc_list(char_u *name, size_t name_len) len = 0; // Arguments - switch ((int)(a & (EX_EXTRA|EX_NOSPC|EX_NEEDARG))) + switch ((int)(a & (EX_EXTRA|EX_NOSPC|EX_NEEDARG|EX_ARGSPACE))) { case 0: IObuff[len++] = '0'; break; case (EX_EXTRA): IObuff[len++] = '*'; break; case (EX_EXTRA|EX_NOSPC): IObuff[len++] = '?'; break; case (EX_EXTRA|EX_NEEDARG): IObuff[len++] = '+'; break; case (EX_EXTRA|EX_NOSPC|EX_NEEDARG): IObuff[len++] = '1'; break; + case (EX_EXTRA|EX_NOSPC|EX_NEEDARG|EX_ARGSPACE): IObuff[len++] = '_'; break; } do @@ -975,6 +979,8 @@ uc_scan_attr( *argt |= (EX_EXTRA | EX_NOSPC); else if (*val == '+') *argt |= (EX_EXTRA | EX_NEEDARG); + else if (*val == '_') + *argt |= (EX_EXTRA | EX_NOSPC | EX_NEEDARG | EX_ARGSPACE); else goto wrong_nargs; } diff --git a/src/userfunc.c b/src/userfunc.c index e861a9eacb..66b55449e3 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1132,7 +1132,7 @@ get_function_body( { if (!nesting_inline[nesting] && nesting_def[nesting] && p < cmd + 6) - semsg(_(e_command_cannot_be_shortened_str), "enddef"); + semsg(_(e_command_cannot_be_shortened_str), cmd); if (nesting-- == 0) { char_u *nextcmd = NULL; @@ -3038,6 +3038,11 @@ call_user_func( if (fp->uf_def_status != UF_NOT_COMPILED) { + if (fp->uf_flags & FC_SANDBOX) + { + using_sandbox = TRUE; + ++sandbox; + } #ifdef FEAT_PROFILE ufunc_T *caller = fc->fc_caller == NULL ? NULL : fc->fc_caller->fc_func; #endif @@ -3050,6 +3055,8 @@ call_user_func( if (call_def_function(fp, argcount, argvars, 0, funcexe->fe_partial, funcexe->fe_object, fc, rettv) == FAIL) retval = FCERR_FAILED; + if (using_sandbox) + --sandbox; funcdepth_decrement(); #ifdef FEAT_PROFILE if (do_profiling == PROF_YES && (fp->uf_profiling @@ -5605,18 +5612,27 @@ define_function( if (fudi.fd_dict != NULL) { + char_u *func_name = vim_strnsave(name, namelen); + + if (func_name == NULL) + { + VIM_CLEAR(fp); + goto erret; + } if (fudi.fd_di == NULL) { // add new dict entry fudi.fd_di = dictitem_alloc(fudi.fd_newkey); if (fudi.fd_di == NULL) { + vim_free(func_name); VIM_CLEAR(fp); goto erret; } if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) { vim_free(fudi.fd_di); + vim_free(func_name); VIM_CLEAR(fp); goto erret; } @@ -5625,7 +5641,7 @@ define_function( // overwrite existing dict entry clear_tv(&fudi.fd_di->di_tv); fudi.fd_di->di_tv.v_type = VAR_FUNC; - fudi.fd_di->di_tv.vval.v_string = vim_strnsave(name, namelen); + fudi.fd_di->di_tv.vval.v_string = func_name; // behave like "dict" was used flags |= FC_DICT; @@ -6257,7 +6273,7 @@ ex_delfunction(exarg_T *eap) int is_global = FALSE; p = eap->arg; - name = trans_function_name_ext(&p, &is_global, eap->skip, 0, &fudi, + name = trans_function_name_ext(&p, &is_global, eap->skip, TFN_NO_DECL, &fudi, NULL, NULL, NULL); vim_free(fudi.fd_newkey); if (name == NULL) @@ -6807,7 +6823,7 @@ ex_call(exarg_T *eap) return; } - tofree = trans_function_name_ext(&arg, NULL, FALSE, TFN_INT, + tofree = trans_function_name_ext(&arg, NULL, FALSE, TFN_INT | TFN_NO_DECL, &fudi, &partial, vim9script ? &type : NULL, &ufunc); if (fudi.fd_newkey != NULL) { diff --git a/src/version.c b/src/version.c index 6cd598877a..f53e87ee07 100644 --- a/src/version.c +++ b/src/version.c @@ -678,11 +678,6 @@ static char *(features[]) = "+wayland_clipboard", #else "-wayland_clipboard", -#endif -#ifdef FEAT_WAYLAND_CLIPBOARD_FS - "+wayland_focus_steal", -#else - "-wayland_focus_steal", #endif "+wildignore", "+wildmenu", @@ -749,6 +744,540 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 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, +/**/ + 341, +/**/ + 340, +/**/ + 339, +/**/ + 338, +/**/ + 337, +/**/ + 336, +/**/ + 335, +/**/ + 334, +/**/ + 333, +/**/ + 332, +/**/ + 331, +/**/ + 330, +/**/ + 329, +/**/ + 328, +/**/ + 327, +/**/ + 326, +/**/ + 325, +/**/ + 324, +/**/ + 323, +/**/ + 322, /**/ 321, /**/ @@ -1739,7 +2268,9 @@ list_version(void) #if !defined(FEAT_GUI) msg_puts(_("without GUI.")); #elif defined(FEAT_GUI_GTK) -# if defined(USE_GTK3) +# if defined(USE_GTK4) + msg_puts(_("with GTK4 GUI.")); +# elif defined(USE_GTK3) msg_puts(_("with GTK3 GUI.")); # elif defined(FEAT_GUI_GNOME) msg_puts(_("with GTK2-GNOME GUI.")); diff --git a/src/vim.h b/src/vim.h index 9faf1a7974..0208616dfa 100644 --- a/src/vim.h +++ b/src/vim.h @@ -691,6 +691,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define POPF_INFO_MENU 0x400 // align info popup with popup menu #define POPF_POSINVERT 0x800 // vertical position can be inverted #define POPF_OPACITY 0x1000 // popup has opacity/transparency setting +#define POPF_CLIPWINDOW 0x2000 // confine popup to its host window's rect // flags used in w_popup_handled #define POPUP_HANDLED_1 0x01 // used by mouse_find_win() @@ -906,6 +907,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define WILD_NOSELECT 0x4000 #define WILD_MAY_EXPAND_PATTERN 0x8000 #define WILD_FUNC_TRIGGER 0x10000 // called from wildtrigger() +#define WILD_NOINSERT 0x20000 // Flags for expand_wildcards() #define EW_DIR 0x01 // include directory names @@ -1096,7 +1098,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define FM_BACKWARD 0x01 // search backwards #define FM_FORWARD 0x02 // search forwards #define FM_BLOCKSTOP 0x04 // stop at start/end of block -#define FM_SKIPCOMM 0x08 // skip comments +#define FM_SKIPCOMM 0x08 // skip comments (cursor must start outside) // Values for action argument for do_buffer() and close_buffer() #define DOBUF_GOTO 0 // go to specified buffer @@ -1485,6 +1487,8 @@ enum auto_event EVENT_TEXTCHANGEDI, // text was modified in Insert mode EVENT_TEXTCHANGEDP, // TextChangedI with popup menu visible EVENT_TEXTCHANGEDT, // text was modified in Terminal mode + EVENT_TEXTPUTPOST, // after some text was put + EVENT_TEXTPUTPRE, // before some text was put EVENT_TEXTYANKPOST, // after some text was yanked EVENT_USER, // user defined autocommand EVENT_VIMENTER, // after starting Vim @@ -1536,6 +1540,7 @@ typedef enum , HLF_S // status lines , HLF_SNC // status lines of not-current windows , HLF_C // column to separate vertically split windows + , HLF_CNC // column to separate vertically split non-current windows , HLF_T // Titles for output from ":set all", ":autocmd" etc. , HLF_V // Visual mode , HLF_VNC // Visual mode, autoselecting and not clipboard owner @@ -1566,6 +1571,9 @@ typedef enum , HLF_PST // popup menu scrollbar thumb , HLF_PMB // popup menu border , HLF_PMS // popup menu shadow + , HLF_POP // popup window body + , HLF_POPB // popup window border + , HLF_POPT // popup window title , HLF_TP // tabpage line , HLF_TPS // tabpage line selected , HLF_TPF // tabpage line filler @@ -1587,10 +1595,11 @@ typedef enum // The HL_FLAGS must be in the same order as the HLF_ enums! // When changing this also adjust the default for 'highlight'. #define HL_FLAGS {'8', '~', '@', 'd', 'e', 'h', 'i', 'l', 'y', 'm', 'M', \ - 'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', 't', 'v', 'V', \ + 'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', '|', 't', 'v', 'V', \ 'w', 'W', 'f', 'F', 'A', 'C', 'D', 'T', 'E', '-', '>', \ 'B', 'P', 'R', 'L', \ '+', '=', 'k', '<','[', ']', '{', '}', 'x', 'X', 'j', 'H', \ + 'p', 'J', 'Q', \ '*', '#', '_', '!', '.', 'o', 'q', \ 'z', 'Z', 'g', \ '%', '^', '&', 'I', '('} @@ -2361,7 +2370,7 @@ typedef struct Atom sel_atom; // PRIMARY/CLIPBOARD selection ID # endif -# ifdef FEAT_GUI_GTK +# if defined(FEAT_GUI_GTK) && !defined(USE_GTK4) GdkAtom gtk_sel_atom; // PRIMARY/CLIPBOARD selection ID # endif @@ -3101,4 +3110,17 @@ long elapsed(DWORD start_tick); // Flags used by getvcol() #define GETVCOL_END_EXCL_LBR 1 +// Used by expand_env_esc() callers that feed the result to +// wildcard expansion, so that such characters embedded in +// environment variable values are treated as literal. +#ifdef VMS +# define PATH_ESC_WILDCARDS "*?%" +#else +# ifdef MSWIN +# define PATH_ESC_WILDCARDS "*?[" +# else +# define PATH_ESC_WILDCARDS "*?[{" +# endif +#endif + #endif // VIM__H diff --git a/src/vim9class.c b/src/vim9class.c index 8edd022bd9..908fb95a35 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -461,13 +461,14 @@ extends_check_dup_members( { class_T *p_cl = extends_cl; ocmember_T *c_m = members + c_i; - char_u *pstr = (*c_m->ocm_name.string == '_') - ? c_m->ocm_name.string + 1 : c_m->ocm_name.string; + bool c_protected = (*c_m->ocm_name.string == '_'); + char_u *pstr = c_m->ocm_name.string + c_protected; // Check in all the parent classes in the lineage while (p_cl != NULL) { int p_member_count = p_cl->class_obj_member_count; + if (p_member_count == 0) { p_cl = p_cl->class_extends; @@ -478,12 +479,17 @@ extends_check_dup_members( // Compare against all the members in the parent class for (int p_i = 0; p_i < p_member_count; p_i++) { - ocmember_T *p_m = p_members + p_i; - char_u *qstr = (*p_m->ocm_name.string == '_') - ? p_m->ocm_name.string + 1 : p_m->ocm_name.string; + ocmember_T *p_m = p_members + p_i; + bool p_protected = (*p_m->ocm_name.string == '_'); + char_u *qstr = p_m->ocm_name.string + p_protected; if (STRCMP(pstr, qstr) == 0) { - semsg(_(e_duplicate_variable_str), c_m->ocm_name.string); + if (c_protected != p_protected) + semsg(_(e_public_and_protected_member_have_same_name_str_str), + pstr, pstr); + else + semsg(_(e_duplicate_variable_str), + c_m->ocm_name.string); return FALSE; } } @@ -1040,18 +1046,18 @@ is_duplicate_variable( char_u *varname, char_u *varname_end) { - string_T pstr = {varname, (size_t)(varname_end - varname)}; // Note: the .string field may - // point to a string longer - // than the .length field. - // So we need to use STRNCMP() - // to compare it. + // Note: the .string field may point to a string longer than the .length + // field. So we need to use STRNCMP() to compare it. + string_T pstr = {varname, (size_t)(varname_end - varname)}; int dup = FALSE; + bool p_protected = false; // Step over a leading '_'. if (*pstr.string == '_') { pstr.string++; pstr.length--; + p_protected = true; } // loop == 1: class variables, loop == 2: object variables @@ -1062,12 +1068,14 @@ is_duplicate_variable( { ocmember_T *m = ((ocmember_T *)vgap->ga_data) + i; string_T qstr = {m->ocm_name.string, m->ocm_name.length}; + bool q_protected = false; // Step over a leading '_'. if (*qstr.string == '_') { qstr.string++; qstr.length--; + q_protected = true; } if (pstr.length == qstr.length @@ -1076,7 +1084,11 @@ is_duplicate_variable( char_u save_c = *varname_end; *varname_end = NUL; - semsg(_(e_duplicate_variable_str), varname); + if (p_protected != q_protected) + semsg(_(e_public_and_protected_member_have_same_name_str_str), + pstr.string, pstr.string); + else + semsg(_(e_duplicate_variable_str), varname); *varname_end = save_c; dup = TRUE; break; @@ -2218,10 +2230,14 @@ early_ret: fullen = 12; } + // skip ':' and blanks + for (; VIM_ISWHITE(*p) || *p == ':'; ++p) + ; + char_u *cmd_start = p; if (checkforcmd(&p, end_name, shortlen)) { - if (STRNCMP(line, end_name, fullen) != 0) - semsg(_(e_command_cannot_be_shortened_str), line); + if (STRNCMP(cmd_start, end_name, fullen) != 0) + semsg(_(e_command_cannot_be_shortened_str), cmd_start); else if (*p == '|' || !ends_excmd2(line, p)) semsg(_(e_trailing_characters_str), p); else diff --git a/src/vim9cmds.c b/src/vim9cmds.c index db81229eed..1a8ff15f48 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -215,7 +215,7 @@ compile_lock_unlock( // These checks are reminiscent of the variable_exists function. // But most of the matches require special handling. - // If bare name is is locally accessible, except for local var, + // If bare name is locally accessible, except for local var, // then put it on the stack to use with ISN_LOCKUNLOCK. // This could be v.memb, v[idx_key]; bare class variable, // function arg. The item on the stack, will be passed @@ -623,6 +623,13 @@ compile_elseif(char_u *arg, cctx_T *cctx) return p; } + if (scope->se_skip_save == SKIP_YES) + { + // Enclosing outer block is dead, skip this elseif + skip_expr_cctx(&p, cctx); + return p; + } + if (cctx->ctx_skip == SKIP_UNKNOWN) { int moved_cmdmod = FALSE; diff --git a/src/vim9compile.c b/src/vim9compile.c index c9976160e4..aa9384bbe9 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -253,6 +253,11 @@ find_script_var(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack) { int idx; + if (ufunc->uf_block_depth == 0 && sav->sav_block_id == 0) + // If the function was defined at the script level (not inside a + // block), script-scope variables are always visible. + return sav; + // Go over the blocks that this function was defined in. If the // variable block ID matches it was visible to the function. for (idx = 0; idx < ufunc->uf_block_depth; ++idx) @@ -1165,9 +1170,15 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free) lvar = reserve_local(cctx, func_name, name_end - name_start, ASSIGN_CONST, ufunc->uf_func_type); if (lvar == NULL) + { + func_ptr_unref(ufunc); goto theend; + } if (generate_FUNCREF(cctx, ufunc, NULL, FALSE, 0, &funcref_isn_idx) == FAIL) + { + func_ptr_unref(ufunc); goto theend; + } r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); } @@ -1944,7 +1955,8 @@ compile_lhs_var_dest( int cmdidx, char_u *var_start, char_u *var_end, - int is_decl) + int is_decl, + int has_cmd) // "var" before "var_start" { int declare_error = FALSE; @@ -1999,8 +2011,8 @@ compile_lhs_var_dest( char_u *p = skipwhite(lhs->lhs_end); if (p[0] == '.' && p[1] == '=') emsg(_(e_dot_equal_not_supported_with_script_version_two)); - else if (p[0] == ':') - // type specified in a non-var assignment + else if (p[0] == ':' && !has_cmd) + // type specified in an assignment without "var" semsg(_(e_trailing_characters_str), p); else semsg(_(e_variable_already_declared_str), lhs->lhs_name); @@ -2304,7 +2316,7 @@ compile_lhs( { // compile the LHS destination if (compile_lhs_var_dest(cctx, lhs, cmdidx, var_start, var_end, - is_decl) == FAIL) + is_decl, has_cmd) == FAIL) return FAIL; } diff --git a/src/vim9execute.c b/src/vim9execute.c index 1bc25ed98e..68ca777d06 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -742,6 +742,9 @@ call_dfunc( else ectx->ec_outer_ref = NULL; + if (ufunc->uf_flags & FC_SANDBOX) + ++sandbox; + ++ufunc->uf_calls; // Set execution state to the start of the called function. @@ -1290,6 +1293,9 @@ func_return(ectx_T *ectx) if (dfunc->df_defer_var_idx > 0) invoke_defer_funcs(ectx); + if (dfunc->df_ufunc->uf_flags & FC_SANDBOX) + --sandbox; + // No check for uf_refcount being zero, cannot think of a way that would // happen. --dfunc->df_ufunc->uf_calls; @@ -2151,10 +2157,8 @@ fill_partial_and_closure( // and local variables) so that the closure can use it later. // Store a reference to the partial so we can handle that. if (GA_GROW_FAILS(&ectx->ec_funcrefs, 1)) - { - vim_free(pt); + // caller needs to free pt return FAIL; - } // Extra variable keeps the count of closures created in the current // function call. ++(((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_frame_idx @@ -4472,7 +4476,7 @@ exec_instructions(ectx_T *ectx) // store $ENV case ISN_STOREENV: - if (check_restricted()) + if (check_secure() || check_restricted()) goto theend; --ectx->ec_stack.ga_len; tv = STACK_TV_BOT(0); @@ -5117,7 +5121,10 @@ exec_instructions(ectx_T *ectx) if (fill_partial_and_closure(pt, ufunc, extra == NULL ? NULL : &extra->fre_loopvar_info, ectx) == FAIL) + { + vim_free(pt); goto theend; + } tv = STACK_TV_BOT(0); ++ectx->ec_stack.ga_len; tv->vval.v_partial = pt; diff --git a/src/vim9expr.c b/src/vim9expr.c index 0344976c9d..9d6033464c 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -946,7 +946,7 @@ compile_load( case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL) { if (is_expr && ASCII_ISUPPER(*name) - && (find_func(name, FALSE) != NULL + && (find_func(name, TRUE) != NULL || gfatab.gfat_args.ga_len > 0)) res = generate_funcref(cctx, name, &gfatab, TRUE); @@ -1741,6 +1741,29 @@ compile_tuple( return generate_NEWTUPLE(cctx, count, FALSE); } +/* + * Restore "*arg" from a temporary cmdline copy. + */ + static void +restore_cmdline_arg(evalarg_T *evalarg, char_u **arg, cctx_T *cctx) +{ + garray_T *gap; + char_u *line; + size_t off; + + if (!evalarg->eval_using_cmdline || cctx == NULL) + return; + + gap = &evalarg->eval_tofree_ga; + if (gap->ga_len == 0) + return; + + off = *arg - ((char_u **)gap->ga_data)[gap->ga_len - 1]; + line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum]; + *arg = line + off; + evalarg->eval_using_cmdline = FALSE; +} + /* * Parse a lambda: "(arg, arg) => expr" * "*arg" points to the '('. @@ -1803,18 +1826,7 @@ compile_lambda(char_u **arg, cctx_T *cctx) compile_def_function(ufunc, FALSE, compile_type, cctx); } - // The last entry in evalarg.eval_tofree_ga is a copy of the last line and - // "*arg" may point into it. Point into the original line to avoid a - // dangling pointer. - if (evalarg.eval_using_cmdline) - { - garray_T *gap = &evalarg.eval_tofree_ga; - size_t off = *arg - ((char_u **)gap->ga_data)[gap->ga_len - 1]; - - *arg = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum] - + off; - evalarg.eval_using_cmdline = FALSE; - } + restore_cmdline_arg(&evalarg, arg, cctx); clear_evalarg(&evalarg, NULL); @@ -2348,6 +2360,7 @@ skip_expr_cctx(char_u **arg, cctx_T *cctx) init_evalarg(&evalarg); evalarg.eval_cctx = cctx; skip_expr(arg, &evalarg); + restore_cmdline_arg(&evalarg, arg, cctx); clear_evalarg(&evalarg, NULL); } diff --git a/src/vim9type.c b/src/vim9type.c index 3d9282f601..1bd94a60cb 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -2658,10 +2658,7 @@ type_name_class_or_obj(char *name, type_T *type, char **tofree) name = "enum"; } else - { - class_name.string = (char_u *)"any"; - class_name.length = 3; - } + STR_LITERAL_SET(class_name, "any"); size_t len = STRLEN(name) + class_name.length + 3; *tofree = alloc(len); @@ -2695,10 +2692,7 @@ type_name_func(type_T *type, char **tofree) string_T arg_type; if (type->tt_args == NULL) - { - arg_type.string = (char_u *)"[unknown]"; - arg_type.length = 9; - } + STR_LITERAL_SET(arg_type, "[unknown]"); else { arg_type.string = (char_u *)type_name(type->tt_args[i], &arg_free); diff --git a/src/viminfo.c b/src/viminfo.c index 8b6aa3e70a..95ec55ebb3 100644 --- a/src/viminfo.c +++ b/src/viminfo.c @@ -435,6 +435,8 @@ write_viminfo_bufferlist(FILE *fp) fputs(_("\n# Buffer list:\n"), fp); FOR_ALL_BUFFERS(buf) { + size_t linelen; + if (buf->b_fname == NULL || !buf->b_p_bl || bt_quickfix(buf) @@ -445,8 +447,8 @@ write_viminfo_bufferlist(FILE *fp) if (max_buffers-- == 0) break; putc('%', fp); - home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE); - vim_snprintf_add((char *)line, LINE_BUF_LEN, "\t%ld\t%d", + linelen = home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE); + vim_snprintf((char *)line + linelen, LINE_BUF_LEN - linelen, "\t%ld\t%d", (long)buf->b_last_cursor.lnum, buf->b_last_cursor.col); viminfo_writestring(fp, line); @@ -1706,7 +1708,7 @@ read_viminfo_register(vir_T *virp, int force) if (size == limit) { string_T *new_array = (string_T *) - alloc(limit * 2 * sizeof(string_T)); + alloc((size_t)limit * 2 * sizeof(string_T)); if (new_array == NULL) { @@ -2533,7 +2535,7 @@ check_marks_read(void) // Always set b_marks_read; needed when 'viminfo' is changed to include // the ' parameter after opening a buffer. - curbuf->b_marks_read = TRUE; + curbuf->b_marks_read = true; } static int diff --git a/src/wayland.c b/src/wayland.c index 6461337aab..7dedf62990 100644 --- a/src/wayland.c +++ b/src/wayland.c @@ -22,12 +22,6 @@ * times, and saves new selections/offers as events come in. When we * want retrieve the selection, the currently saved data offer is * used from the respective data device. - * - * The focus stealing code is implemented in clipboard.c, and is - * based off of wl-clipboard's implementation. The idea using of - * extensive macros to reduce boilerplate code also comes from - * wl-clipboard as well. The project page for wl-clipboard can be - * found here: https://github.com/bugaevc/wl-clipboard */ #include "vim.h" @@ -336,38 +330,6 @@ wl_registry_listener_event_global( ct->gobjects.ext_data_control_manager_v1 = wl_registry_bind(registry, name, &ext_data_control_manager_v1_interface, 1); - -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - else if (p_wst) - { - if (STRCMP(interface, wl_data_device_manager_interface.name) == 0) - ct->gobjects.wl_data_device_manager = - wl_registry_bind(registry, name, - &wl_data_device_manager_interface, 1); - - else if (STRCMP(interface, wl_shm_interface.name) == 0) - ct->gobjects.wl_shm = - wl_registry_bind(registry, name, - &wl_shm_interface, 1); - - else if (STRCMP(interface, wl_compositor_interface.name) == 0) - ct->gobjects.wl_compositor = - wl_registry_bind(registry, name, - &wl_compositor_interface, 1); - - else if (STRCMP(interface, xdg_wm_base_interface.name) == 0) - ct->gobjects.xdg_wm_base = - wl_registry_bind(registry, name, - &xdg_wm_base_interface, 1); - - else if (STRCMP(interface, - zwp_primary_selection_device_manager_v1_interface.name) - == 0) - ct->gobjects.zwp_primary_selection_device_manager_v1 = - wl_registry_bind(registry, name, - &zwp_primary_selection_device_manager_v1_interface, 1); - } -# endif // FEAT_WAYLAND_CLIPBOARD_FS #endif // FEAT_WAYLAND_CLIPBOARD } @@ -386,28 +348,11 @@ wl_registry_listener_event_global_remove( { } -#ifdef FEAT_WAYLAND_CLIPBOARD_FS - static void -xdg_wm_base_listener_event_ping( - void *data UNUSED, - struct xdg_wm_base *xdg_base, - uint32_t serial) -{ - xdg_wm_base_pong(xdg_base, serial); -} -#endif - static const struct wl_registry_listener wl_registry_listener = { .global = wl_registry_listener_event_global, .global_remove = wl_registry_listener_event_global_remove }; -#ifdef FEAT_WAYLAND_CLIPBOARD_FS -static const struct xdg_wm_base_listener xdg_wm_base_listener = { - .ping = xdg_wm_base_listener_event_ping -}; -#endif - static void vwl_connection_destroy(vwl_connection_T *self); #ifdef FEAT_WAYLAND_CLIPBOARD @@ -428,10 +373,7 @@ static void vwl_connection_destroy(vwl_connection_T *self); vwl_connection_new(const char *display) { vwl_connection_T *ct; -#ifdef FEAT_WAYLAND_CLIPBOARD_FS - const char_u *env; - bool force_fs; -#endif + if (wayland_no_connect) return NULL; @@ -469,46 +411,12 @@ vwl_connection_new(const char *display) wl_registry_add_listener(ct->registry.proxy, &wl_registry_listener, ct); -#ifdef FEAT_WAYLAND_CLIPBOARD_FS - env = mch_getenv("VIM_WAYLAND_FORCE_FS"); - force_fs = (env != NULL && STRCMP(env, "1") == 0); - - if (force_fs) - p_wst = TRUE; -#endif - if (vwl_connection_roundtrip(ct) == FAIL) { vwl_connection_destroy(ct); return NULL; } -#ifdef FEAT_WAYLAND_CLIPBOARD_FS - if (force_fs) - { - // Force using focus stealing method - VWL_DESTROY_GOBJECT(ct, ext_data_control_manager_v1) - VWL_DESTROY_GOBJECT(ct, zwlr_data_control_manager_v1) - } - - // If data control protocols are available, we don't need the other global - // objects. - else if (VWL_GOBJECT_AVAIL(ct, ext_data_control_manager_v1) - || VWL_GOBJECT_AVAIL(ct, zwlr_data_control_manager_v1)) - { - VWL_DESTROY_GOBJECT(ct, wl_data_device_manager) - VWL_DESTROY_GOBJECT(ct, wl_shm) - VWL_DESTROY_GOBJECT(ct, wl_compositor) - VWL_DESTROY_GOBJECT(ct, xdg_wm_base) - VWL_DESTROY_GOBJECT(ct, zwp_primary_selection_device_manager_v1) - } - - // Start responding to pings from the compositor if we have xdg_wm_base - if (VWL_GOBJECT_AVAIL(ct, xdg_wm_base)) - xdg_wm_base_add_listener(ct->gobjects.xdg_wm_base, - &xdg_wm_base_listener, NULL); -#endif - return ct; } @@ -544,13 +452,6 @@ vwl_connection_destroy(vwl_connection_T *self) # ifdef FEAT_WAYLAND_CLIPBOARD VWL_DESTROY_GOBJECT(self, ext_data_control_manager_v1) VWL_DESTROY_GOBJECT(self, zwlr_data_control_manager_v1) -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - VWL_DESTROY_GOBJECT(self, wl_data_device_manager) - VWL_DESTROY_GOBJECT(self, wl_shm) - VWL_DESTROY_GOBJECT(self, wl_compositor) - VWL_DESTROY_GOBJECT(self, xdg_wm_base) - VWL_DESTROY_GOBJECT(self, zwp_primary_selection_device_manager_v1) -# endif # endif for (int i = 0; i < self->gobjects.seats.ga_len; i++) @@ -592,21 +493,6 @@ vwl_connection_get_seat(vwl_connection_T *self, const char *label) return NULL; } -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -/* - * Get keyboard object from seat and return it. NULL is returned on - * failure such as when a keyboard is not available for seat. - */ - struct wl_keyboard * -vwl_seat_get_keyboard(vwl_seat_T *self) -{ - if (!(self->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) - return NULL; - - return wl_seat_get_keyboard(self->proxy); -} -# endif - #endif /* @@ -896,27 +782,6 @@ vwl_connection_get_data_device_manager( if (zwlr_data_control_manager_v1_get_version(manager->proxy) >= 2) *supported |= WAYLAND_SELECTION_PRIMARY; } -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - else if (self->gobjects.wl_data_device_manager != NULL - && req_sel == WAYLAND_SELECTION_REGULAR) - { - manager->proxy = self->gobjects.wl_data_device_manager; - manager->protocol = VWL_DATA_PROTOCOL_CORE; - - *supported |= WAYLAND_SELECTION_REGULAR; - } - - if (req_sel == WAYLAND_SELECTION_PRIMARY - && !(*supported & WAYLAND_SELECTION_PRIMARY)) - if (self->gobjects.zwp_primary_selection_device_manager_v1 != NULL) - { - manager->proxy = - self->gobjects.zwp_primary_selection_device_manager_v1; - manager->protocol = VWL_DATA_PROTOCOL_PRIMARY; - - *supported |= WAYLAND_SELECTION_PRIMARY; - } -# endif if (!(*supported & req_sel)) { @@ -944,16 +809,6 @@ vwl_data_device_manager_get_data_device( device->proxy = zwlr_data_control_manager_v1_get_data_device( self->proxy, seat->proxy); break; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - case VWL_DATA_PROTOCOL_CORE: - device->proxy = wl_data_device_manager_get_data_device( - self->proxy, seat->proxy); - break; - case VWL_DATA_PROTOCOL_PRIMARY: - device->proxy = zwp_primary_selection_device_manager_v1_get_device( - self->proxy, seat->proxy); - break; -# endif default: vim_free(device); return NULL; @@ -978,17 +833,6 @@ vwl_data_device_manager_create_data_source(vwl_data_device_manager_T *self) source->proxy = zwlr_data_control_manager_v1_create_data_source( self->proxy); break; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - case VWL_DATA_PROTOCOL_CORE: - source->proxy = wl_data_device_manager_create_data_source( - self->proxy); - break; - case VWL_DATA_PROTOCOL_PRIMARY: - source->proxy = - zwp_primary_selection_device_manager_v1_create_source( - self->proxy); - break; -# endif default: vim_free(source); return NULL; @@ -1018,18 +862,6 @@ vwl_data_device_wrap_offer_proxy(vwl_data_device_T *self, void *proxy) return offer; } -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -# define VWL_CODE_DATA_PROXY_FS_DESTROY(type) \ - case VWL_DATA_PROTOCOL_CORE: \ - wl_data_##type##_destroy(self->proxy); \ - break; \ - case VWL_DATA_PROTOCOL_PRIMARY: \ - zwp_primary_selection_##type##_v1_destroy(self->proxy); \ - break; -# else -# define VWL_CODE_DATA_PROXY_FS_DESTROY(type) -# endif - # define VWL_FUNC_DATA_PROXY_DESTROY(type) \ void \ vwl_data_##type##_destroy(vwl_data_##type##_T *self) \ @@ -1044,7 +876,6 @@ vwl_data_device_wrap_offer_proxy(vwl_data_device_T *self, void *proxy) case VWL_DATA_PROTOCOL_WLR: \ zwlr_data_control_##type##_v1_destroy(self->proxy); \ break; \ - VWL_CODE_DATA_PROXY_FS_DESTROY(type) \ default: \ break; \ } \ @@ -1067,14 +898,6 @@ vwl_data_offer_destroy(vwl_data_offer_T *self) case VWL_DATA_PROTOCOL_WLR: zwlr_data_control_offer_v1_destroy(self->proxy); break; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - case VWL_DATA_PROTOCOL_CORE: - wl_data_offer_destroy(self->proxy); - break; - case VWL_DATA_PROTOCOL_PRIMARY: - zwp_primary_selection_offer_v1_destroy(self->proxy); - break; -# endif default: break; } @@ -1147,11 +970,6 @@ VWL_FUNC_DATA_DEVICE_EVENT_DATA_OFFER( ext_data_control_device_v1, ext_data_control_offer_v1) VWL_FUNC_DATA_DEVICE_EVENT_DATA_OFFER( zwlr_data_control_device_v1, zwlr_data_control_offer_v1) -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -VWL_FUNC_DATA_DEVICE_EVENT_DATA_OFFER(wl_data_device, wl_data_offer) -VWL_FUNC_DATA_DEVICE_EVENT_DATA_OFFER( - zwp_primary_selection_device_v1, zwp_primary_selection_offer_v1) -# endif VWL_FUNC_DATA_DEVICE_EVENT_SELECTION( ext_data_control_device_v1, ext_data_control_offer_v1 @@ -1165,13 +983,6 @@ VWL_FUNC_DATA_DEVICE_EVENT_PRIMARY_SELECTION( VWL_FUNC_DATA_DEVICE_EVENT_PRIMARY_SELECTION( zwlr_data_control_device_v1, zwlr_data_control_offer_v1 ) -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -VWL_FUNC_DATA_DEVICE_EVENT_SELECTION( - wl_data_device, wl_data_offer -) -VWL_FUNC_DATA_DEVICE_EVENT_PRIMARY_SELECTION( - zwp_primary_selection_device_v1, zwp_primary_selection_offer_v1) -# endif VWL_FUNC_DATA_DEVICE_EVENT_FINISHED(ext_data_control_device_v1) VWL_FUNC_DATA_DEVICE_EVENT_FINISHED(zwlr_data_control_device_v1) @@ -1192,18 +1003,6 @@ static const struct zwlr_data_control_device_v1_listener zwlr_data_control_device_v1_listener_event_primary_selection, .finished = zwlr_data_control_device_v1_listener_event_finished }; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -static const struct wl_data_device_listener wl_data_device_listener = { - .data_offer = wl_data_device_listener_event_data_offer, - .selection = wl_data_device_listener_event_selection, -}; -static const struct zwp_primary_selection_device_v1_listener - zwp_primary_selection_device_v1_listener = { - .data_offer = zwp_primary_selection_device_v1_listener_event_data_offer, - .selection = - zwp_primary_selection_device_v1_listener_event_primary_selection, -}; -# endif # define VWL_FUNC_DATA_SOURCE_EVENT_SEND(source_type) \ static void \ @@ -1226,17 +1025,9 @@ static const struct zwp_primary_selection_device_v1_listener VWL_FUNC_DATA_SOURCE_EVENT_SEND(ext_data_control_source_v1) VWL_FUNC_DATA_SOURCE_EVENT_SEND(zwlr_data_control_source_v1) -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -VWL_FUNC_DATA_SOURCE_EVENT_SEND(wl_data_source) -VWL_FUNC_DATA_SOURCE_EVENT_SEND(zwp_primary_selection_source_v1) -# endif VWL_FUNC_DATA_SOURCE_EVENT_CANCELLED(ext_data_control_source_v1) VWL_FUNC_DATA_SOURCE_EVENT_CANCELLED(zwlr_data_control_source_v1) -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -VWL_FUNC_DATA_SOURCE_EVENT_CANCELLED(wl_data_source) -VWL_FUNC_DATA_SOURCE_EVENT_CANCELLED(zwp_primary_selection_source_v1) -# endif static const struct ext_data_control_source_v1_listener ext_data_control_source_v1_listener = { @@ -1248,17 +1039,6 @@ static const struct zwlr_data_control_source_v1_listener .send = zwlr_data_control_source_v1_listener_event_send, .cancelled = zwlr_data_control_source_v1_listener_event_cancelled }; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -static const struct wl_data_source_listener wl_data_source_listener = { - .send = wl_data_source_listener_event_send, - .cancelled = wl_data_source_listener_event_cancelled -}; -static const struct zwp_primary_selection_source_v1_listener - zwp_primary_selection_source_v1_listener = { - .send = zwp_primary_selection_source_v1_listener_event_send, - .cancelled = zwp_primary_selection_source_v1_listener_event_cancelled -}; -# endif # define VWL_FUNC_DATA_OFFER_EVENT_OFFER(offer_type) \ static void \ @@ -1282,10 +1062,6 @@ static const struct zwp_primary_selection_source_v1_listener VWL_FUNC_DATA_OFFER_EVENT_OFFER(ext_data_control_offer_v1) VWL_FUNC_DATA_OFFER_EVENT_OFFER(zwlr_data_control_offer_v1) -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -VWL_FUNC_DATA_OFFER_EVENT_OFFER(wl_data_offer) -VWL_FUNC_DATA_OFFER_EVENT_OFFER(zwp_primary_selection_offer_v1) -# endif static const struct ext_data_control_offer_v1_listener ext_data_control_offer_v1_listener = { @@ -1295,30 +1071,6 @@ static const struct zwlr_data_control_offer_v1_listener zwlr_data_control_offer_v1_listener = { .offer = zwlr_data_control_offer_v1_listener_event_offer }; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -static const struct wl_data_offer_listener - wl_data_offer_listener = { - .offer = wl_data_offer_listener_event_offer -}; -static const struct zwp_primary_selection_offer_v1_listener - zwp_primary_selection_offer_v1_listener = { - .offer = zwp_primary_selection_offer_v1_listener_event_offer -}; -# endif - -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -# define VWL_CODE_DATA_PROXY_FS_ADD_LISTENER(type) \ - case VWL_DATA_PROTOCOL_CORE: \ - wl_data_##type##_add_listener(self->proxy, \ - &wl_data_##type##_listener, self); \ - break; \ - case VWL_DATA_PROTOCOL_PRIMARY: \ - zwp_primary_selection_##type##_v1_add_listener(self->proxy, \ - &zwp_primary_selection_##type##_v1_listener, self); \ - break; -# else -# define VWL_CODE_DATA_PROXY_FS_ADD_LISTENER(type) -# endif # define VWL_FUNC_DATA_PROXY_ADD_LISTENER(type) \ void \ @@ -1341,7 +1093,6 @@ static const struct zwp_primary_selection_offer_v1_listener zwlr_data_control_##type##_v1_add_listener(self->proxy, \ &zwlr_data_control_##type##_v1_listener, self); \ break; \ - VWL_CODE_DATA_PROXY_FS_ADD_LISTENER(type) \ default: \ break; \ } \ @@ -1350,7 +1101,6 @@ static const struct zwp_primary_selection_offer_v1_listener VWL_FUNC_DATA_PROXY_ADD_LISTENER(device) VWL_FUNC_DATA_PROXY_ADD_LISTENER(source) VWL_FUNC_DATA_PROXY_ADD_LISTENER(offer) - /* * Set the given selection to source. If a data control protocol is being used, * "serial" is ignored. @@ -1375,11 +1125,6 @@ vwl_data_device_set_selection( case VWL_DATA_PROTOCOL_WLR: zwlr_data_control_device_v1_set_selection(self->proxy, proxy); break; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - case VWL_DATA_PROTOCOL_CORE: - wl_data_device_set_selection(self->proxy, proxy, serial); - break; -# endif default: break; } @@ -1398,12 +1143,6 @@ vwl_data_device_set_selection( self->proxy, proxy ); break; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - case VWL_DATA_PROTOCOL_PRIMARY: - zwp_primary_selection_device_v1_set_selection( - self->proxy, proxy, serial); - break; -# endif default: break; } @@ -1421,14 +1160,6 @@ vwl_data_source_offer(vwl_data_source_T *self, const char *mime_type) case VWL_DATA_PROTOCOL_WLR: zwlr_data_control_source_v1_offer(self->proxy, mime_type); break; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - case VWL_DATA_PROTOCOL_CORE: - wl_data_source_offer(self->proxy, mime_type); - break; - case VWL_DATA_PROTOCOL_PRIMARY: - zwp_primary_selection_source_v1_offer(self->proxy, mime_type); - break; -# endif default: break; } @@ -1448,14 +1179,6 @@ vwl_data_offer_receive( case VWL_DATA_PROTOCOL_WLR: zwlr_data_control_offer_v1_receive(self->proxy, mime_type, fd); break; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - case VWL_DATA_PROTOCOL_CORE: - wl_data_offer_receive(self->proxy, mime_type, fd); - break; - case VWL_DATA_PROTOCOL_PRIMARY: - zwp_primary_selection_offer_v1_receive(self->proxy, mime_type, fd); - break; -# endif default: break; } diff --git a/src/wayland.h b/src/wayland.h index 80eb52cc33..398e9d3e60 100644 --- a/src/wayland.h +++ b/src/wayland.h @@ -19,10 +19,6 @@ #ifdef FEAT_WAYLAND_CLIPBOARD # include "auto/wayland/wlr-data-control-unstable-v1.h" # include "auto/wayland/ext-data-control-v1.h" -# ifdef FEAT_WAYLAND_CLIPBOARD_FS -# include "auto/wayland/xdg-shell.h" -# include "auto/wayland/primary-selection-unstable-v1.h" -# endif #endif #ifdef FEAT_WAYLAND_CLIPBOARD @@ -32,10 +28,6 @@ typedef enum { VWL_DATA_PROTOCOL_NONE, VWL_DATA_PROTOCOL_EXT, VWL_DATA_PROTOCOL_WLR, -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - VWL_DATA_PROTOCOL_CORE, - VWL_DATA_PROTOCOL_PRIMARY -# endif } vwl_data_protocol_T; #endif // FEAT_WAYLAND_CLIPBOARD @@ -68,14 +60,6 @@ struct vwl_connection_S { #ifdef FEAT_WAYLAND_CLIPBOARD struct zwlr_data_control_manager_v1 *zwlr_data_control_manager_v1; struct ext_data_control_manager_v1 *ext_data_control_manager_v1; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - struct wl_data_device_manager *wl_data_device_manager; - struct wl_shm *wl_shm; - struct wl_compositor *wl_compositor; - struct xdg_wm_base *xdg_wm_base; - struct zwp_primary_selection_device_manager_v1 - *zwp_primary_selection_device_manager_v1; -# endif #endif } gobjects; }; @@ -149,61 +133,6 @@ struct vwl_data_device_manager_S { vwl_data_protocol_T protocol; }; -# ifdef FEAT_WAYLAND_CLIPBOARD_FS - -// Dummy functions to handle keyboard events we don't care about. - -# define VWL_FUNCS_DUMMY_KEYBOARD_EVENTS() \ - static void \ -clip_wl_fs_keyboard_listener_keymap( \ - void *data UNUSED, \ - struct wl_keyboard *keyboard UNUSED, \ - uint32_t format UNUSED, \ - int fd, \ - uint32_t size UNUSED) \ -{ \ - close(fd); \ -} \ - static void \ -clip_wl_fs_keyboard_listener_leave( \ - void *data UNUSED, \ - struct wl_keyboard *keyboard UNUSED, \ - uint32_t serial UNUSED, \ - struct wl_surface *surface UNUSED) \ -{ \ -} \ - static void \ -clip_wl_fs_keyboard_listener_key( \ - void *data UNUSED, \ - struct wl_keyboard *keyboard UNUSED, \ - uint32_t serial UNUSED, \ - uint32_t time UNUSED, \ - uint32_t key UNUSED, \ - uint32_t state UNUSED) \ -{ \ -} \ - static void \ -clip_wl_fs_keyboard_listener_modifiers( \ - void *data UNUSED, \ - struct wl_keyboard *keyboard UNUSED, \ - uint32_t serial UNUSED, \ - uint32_t mods_depressed UNUSED, \ - uint32_t mods_latched UNUSED, \ - uint32_t mods_locked UNUSED, \ - uint32_t group UNUSED) \ -{ \ -} \ - static void \ -clip_wl_fs_keyboard_listener_repeat_info( \ - void *data UNUSED, \ - struct wl_keyboard *keyboard UNUSED, \ - int32_t rate UNUSED, \ - int32_t delay UNUSED) \ -{ \ -} - -# endif - #endif // FEAT_WAYLAND_CLIPBOARD // Global Wayland connection. Is also set to NULL when the connection is lost. diff --git a/src/window.c b/src/window.c index 38bc4677e7..bd56885008 100644 --- a/src/window.c +++ b/src/window.c @@ -682,9 +682,21 @@ wingotofile: if (do_ecmd(0, ptr, NULL, NULL, ECMD_LASTL, ECMD_HIDE, NULL) == FAIL) { + /* + * Note: if FEAT_EVAL is defined and do_ecmd() is aborted resulting + * in got_int be true, win_close() unconditionally fails. In such + * case, the window split for do_ecmd() is left unclosed, i.e. the + * current window is just duplicated. To avoid this, save and load + * got_int value before and after closing the window. + */ + sig_atomic_t old_got_int = got_int; + got_int = FALSE; + // Failed to open the file, close the window // opened for it. win_close(curwin, FALSE); + got_int = got_int || old_got_int; + goto_tabpage_win(oldtab, oldwin); } else @@ -724,7 +736,7 @@ wingotofile: Prenum1, ACTION_SPLIT, (linenr_T)1, (linenr_T)MAXLNUM, FALSE, FALSE); vim_free(ptr); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; break; #endif @@ -4784,6 +4796,9 @@ free_tabpage(tabpage_T *tp) if (tp == lastused_tabpage) lastused_tabpage = NULL; +#ifdef FEAT_TABPANEL + tabpanel_forget_tabpage(tp); +#endif vim_free(tp->tp_localdir); vim_free(tp->tp_prevdir); @@ -5777,7 +5792,7 @@ win_enter_ext(win_T *wp, int flags) if (curwin_invalid == 0) { prevwin = curwin; // remember for CTRL-W p - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; } curwin = wp; curbuf = wp->w_buffer; @@ -5818,16 +5833,21 @@ win_enter_ext(win_T *wp, int flags) } maketitle(); - curwin->w_redr_status = TRUE; + curwin->w_redr_status = true; #ifdef FEAT_TERMINAL if (bt_terminal(curwin->w_buffer)) // terminal is likely in another mode redraw_mode = TRUE; #endif redraw_tabline = TRUE; + redraw_vseps = TRUE; #if defined(FEAT_TABPANEL) redraw_tabpanel = TRUE; #endif + // Need to schedule a redraw so that the vertical separator highlight is + // updated for the new current window. The status line redraw of curwin + // is already requested via "curwin->w_redr_status". + redraw_later(UPD_VALID); if (restart_edit) redraw_later(UPD_VALID); // causes status line redraw @@ -5966,6 +5986,7 @@ win_alloc(win_T *after, int hidden) // use global option value for global-local options new_wp->w_allbuf_opt.wo_so = new_wp->w_p_so = -1; + new_wp->w_allbuf_opt.wo_sop = new_wp->w_p_sop = -1; new_wp->w_allbuf_opt.wo_siso = new_wp->w_p_siso = -1; // We won't calculate w_fraction until resizing the window @@ -6045,6 +6066,14 @@ win_free( remove_highlight_overrides(wp->w_hl); vim_free(wp->w_hl); + // Free statusline click regions. + if (wp->w_stl_click != NULL) + { + for (i = 0; i < wp->w_stl_click_count; i++) + vim_free(wp->w_stl_click[i].funcname); + vim_free(wp->w_stl_click); + } + clear_winopt(&wp->w_onebuf_opt); clear_winopt(&wp->w_allbuf_opt); @@ -6496,7 +6525,7 @@ frame_comp_pos(frame_T *topfrp, int *row, int *col) wp->w_winrow = *row; wp->w_wincol = *col; redraw_win_later(wp, UPD_NOT_VALID); - wp->w_redr_status = TRUE; + wp->w_redr_status = true; } // WinBar will not show if the window height is zero h = VISIBLE_HEIGHT(wp) + wp->w_status_height; @@ -7240,7 +7269,7 @@ win_fix_scroll(int resize) { // Cursor position in this window may now be invalid. It is kept // potentially invalid until the window is made the current window. - wp->w_do_win_fix_cursor = TRUE; + wp->w_do_win_fix_cursor = true; // If window has moved update botline to keep the same screenlines. if (*p_spk == 's' && wp->w_winrow != wp->w_prev_winrow @@ -7298,7 +7327,7 @@ win_fix_cursor(int normal) || wp->w_buffer->b_ml.ml_line_count < wp->w_height) return; - wp->w_do_win_fix_cursor = FALSE; + wp->w_do_win_fix_cursor = false; // Determine valid cursor range. long so = MIN(wp->w_height / 2, get_scrolloff_value()); linenr_T lnum = wp->w_cursor.lnum; @@ -7368,7 +7397,7 @@ win_new_height(win_T *wp, int height) } wp->w_height = height; - wp->w_redr_status = TRUE; + wp->w_redr_status = true; win_comp_scroll(wp); // There is no point in adjusting the scroll position when exiting. Some @@ -7514,7 +7543,7 @@ win_new_width(win_T *wp, int width) curs_columns(TRUE); // validate w_wrow redraw_win_later(wp, UPD_NOT_VALID); - wp->w_redr_status = TRUE; + wp->w_redr_status = true; } void @@ -7574,6 +7603,7 @@ command_height(void) // Recompute window positions. win_comp_pos(); + win_fix_scroll(true); cmdline_row = Rows - p_ch; redraw_cmdline = TRUE; diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c index 535f0add32..323d5a3982 100644 --- a/src/xxd/xxd.c +++ b/src/xxd/xxd.c @@ -74,6 +74,8 @@ * 26.11.2025 update indent in exit_with_usage() * 19.03.2026 Add -t option to end output with terminating null * 25.03.2026 Fix color output issues + * 26.04.2026 Use unsigned long for printing offsets + * 31.05.2026 Colorize binary output * * (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com) * @@ -154,7 +156,7 @@ extern void perror __P((char *)); # endif #endif -char version[] = "xxd 2026-03-25 by Juergen Weigert et al."; +char version[] = "xxd 2026-05-31 by Juergen Weigert et al."; #ifdef WIN32 char osver[] = " (Win32)"; #else @@ -1172,7 +1174,7 @@ main(int argc, char *argv[]) { if (p == 0) { - addrlen = sprintf(l, decimal_offset ? "%08ld:" : "%08lx:", + addrlen = sprintf(l, decimal_offset ? "%08lu:" : "%08lx:", ((unsigned long)(n + seekoff + displayoff))); for (c = addrlen; c < LLEN_NO_COLOR; l[c++] = ' ') ; @@ -1193,8 +1195,15 @@ main(int argc, char *argv[]) } else /* hextype == HEX_BITS */ { + if (color) + cur_color = get_color_char(e, ebcdic); + for (i = 7; i >= 0; i--) - l[c++] = (e & (1 << i)) ? '1' : '0'; + { + if (color) + colors[c] = cur_color; + l[c++] = (e & (1 << i)) ? '1' : '0'; + } } if (e) nonzero++;