diff options
168 files changed, 3332 insertions, 3639 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index d9b67eafe7..0d58d2bd85 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,7 @@ env: CIRRUS_CLONE_DEPTH: '2' LANG: en_US.UTF-8 - CMAKE_EXTRA_FLAGS: -DCI_BUILD=ON -DMIN_LOG_LEVEL=3 + CMAKE_EXTRA_FLAGS: -DCI_BUILD=ON freebsd_task: name: FreeBSD diff --git a/.clang-tidy b/.clang-tidy index 1fe87ba501..1c7d13e2b0 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,3 +1,4 @@ +WarningsAsErrors: '*' Checks: > -*, diff --git a/.github/scripts/install_deps.sh b/.github/scripts/install_deps.sh new file mode 100755 index 0000000000..4727b5d08d --- /dev/null +++ b/.github/scripts/install_deps.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +os=$(uname -s) +if [[ $os == Linux ]]; then + sudo apt-get update + sudo apt-get install -y autoconf automake build-essential cmake curl gettext libtool-bin locales-all ninja-build pkg-config unzip "$@" +elif [[ $os == Darwin ]]; then + brew update --quiet + brew install automake ninja "$@" +fi diff --git a/.github/scripts/install_deps_ubuntu.sh b/.github/scripts/install_deps_ubuntu.sh deleted file mode 100755 index 012409ba4a..0000000000 --- a/.github/scripts/install_deps_ubuntu.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -PACKAGES=( - autoconf - automake - build-essential - cmake - cpanminus - curl - gettext - libtool-bin - locales-all - ninja-build - pkg-config - unzip -) - -sudo apt-get update -sudo apt-get install -y "${PACKAGES[@]}" diff --git a/.github/scripts/reviews.js b/.github/scripts/reviews.js index cc6aaa1e8b..0ed382ac30 100644 --- a/.github/scripts/reviews.js +++ b/.github/scripts/reviews.js @@ -69,10 +69,6 @@ module.exports = async ({github, context}) => { reviewers.add("justinmk") } - if (labels.includes('refactor')) { - reviewers.add("bfredl") - } - if (labels.includes('test')) { reviewers.add("justinmk") } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c27100072f..4814e89a69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,8 +16,16 @@ concurrency: cancel-in-progress: true env: - CI_BUILD_DIR: ${{ github.workspace }} - UNCRUSTIFY_VERSION: uncrustify-0.75.0 + ASAN_OPTIONS: detect_leaks=1:check_initialization_order=1:handle_abort=1:handle_sigill=1:log_path=${{ github.workspace }}/build/log/asan:intercept_tls_get_addr=0 + BIN_DIR: ${{ github.workspace }}/bin + BUILD_DIR: ${{ github.workspace }}/build + DEPS_BUILD_DIR: ${{ github.workspace }}/nvim-deps + INSTALL_PREFIX: ${{ github.workspace }}/nvim-install + LOG_DIR: ${{ github.workspace }}/build/log + NVIM_LOG_FILE: ${{ github.workspace }}/build/.nvimlog + TSAN_OPTIONS: log_path=${{ github.workspace }}/build/log/tsan + UBSAN_OPTIONS: "print_stacktrace=1 log_path=${{ github.workspace }}/build/log/ubsan" + VALGRIND_LOG: ${{ github.workspace }}/build/log/valgrind-%p.log # TEST_FILE: test/functional/core/startup_spec.lua # TEST_FILTER: foo @@ -27,17 +35,13 @@ jobs: runs-on: ubuntu-22.04 timeout-minutes: 10 env: - CC: gcc + CACHE_UNCRUSTIFY: ${{ github.workspace }}/.cache/uncrustify + UNCRUSTIFY_VERSION: uncrustify-0.75.0 steps: - uses: actions/checkout@v3 - - name: Setup common environment variables - run: ./.github/workflows/env.sh lint - - - name: Install apt packages - run: | - ./.github/scripts/install_deps_ubuntu.sh - sudo apt-get install -y lua-check + - name: Install dependencies + run: ./.github/scripts/install_deps.sh lua-check - name: Cache uncrustify id: cache-uncrustify @@ -61,13 +65,15 @@ jobs: build_dir=uncrustify/build cmake -S $source_dir -B $build_dir -G Ninja -D CMAKE_BUILD_TYPE=Release cmake --build $build_dir - mkdir -p $CACHE_DIR + mkdir -p .cache cp $build_dir/uncrustify ${{ env.CACHE_UNCRUSTIFY }} - uses: ./.github/actions/cache - name: Build third-party deps - run: ./ci/before_script.sh + run: | + cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja + cmake --build $DEPS_BUILD_DIR - if: "!cancelled()" name: Determine if run should be aborted @@ -90,7 +96,7 @@ jobs: - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: lintsh - run: make lintsh + run: cmake --build build --target lintsh - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: uncrustify @@ -107,8 +113,7 @@ jobs: - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: check uncrustify - run: | - git diff --color --exit-code + run: git diff --color --exit-code lintc: # This job tests two things: it lints the code but also builds neovim using @@ -119,18 +124,13 @@ jobs: if: (github.event_name == 'pull_request' && github.base_ref == 'master') || (github.event_name == 'push' && github.ref == 'refs/heads/master') runs-on: ubuntu-22.04 timeout-minutes: 10 - env: - CC: gcc steps: - uses: actions/checkout@v3 - - name: Setup common environment variables - run: ./.github/workflows/env.sh lintc - - - name: Install apt packages + - name: Install dependencies run: | sudo add-apt-repository ppa:neovim-ppa/stable - ./.github/scripts/install_deps_ubuntu.sh + ./.github/scripts/install_deps.sh sudo apt-get install -y \ libluajit-5.1-dev \ libmsgpack-dev \ @@ -148,15 +148,23 @@ jobs: # lua-luv-dev # Remove comments from packages once we start using these external - # dependencies. See env.sh for more context. + # dependencies. - uses: ./.github/actions/cache - name: Build third-party deps - run: ./ci/before_script.sh + run: | + # Ideally all dependencies should external for this job, but some + # dependencies don't have the required version available. We use the + # bundled versions for these with the hopes of being able to remove them + # later on. + cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja -D USE_BUNDLED=OFF -D USE_BUNDLED_LUV=ON -D USE_BUNDLED_LIBVTERM=ON + cmake --build $DEPS_BUILD_DIR - - name: Build nvim - run: make + - name: Build + run: | + cmake -B build -G Ninja + cmake --build build - if: "!cancelled()" name: Determine if run should be aborted @@ -179,18 +187,17 @@ jobs: - flavor: asan cc: clang runner: ubuntu-22.04 - os: linux + flags: -D CLANG_ASAN_UBSAN=ON - flavor: tsan cc: clang runner: ubuntu-22.04 - os: linux + flags: -D CLANG_TSAN=ON - flavor: uchar cc: gcc runner: ubuntu-22.04 - os: linux + flags: -D UNSIGNED_CHAR=ON - cc: clang runner: macos-12 - os: osx # functionaltest-lua is our dumping ground for non-mainline configurations. # 1. Check that the tests pass with PUC Lua instead of LuaJIT. @@ -198,38 +205,57 @@ jobs: - flavor: functionaltest-lua cc: gcc runner: ubuntu-22.04 - os: linux + deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON + flags: -D PREFER_LUA=ON runs-on: ${{ matrix.runner }} timeout-minutes: 45 env: CC: ${{ matrix.cc }} - CI_OS_NAME: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - - name: Setup common environment variables - run: ./.github/workflows/env.sh ${{ matrix.flavor }} + - name: Set up environment + run: | + ulimit -c unlimited + echo "$BIN_DIR" >> $GITHUB_PATH - - name: Install apt packages - if: matrix.os == 'linux' - run: ./.github/scripts/install_deps_ubuntu.sh + - name: Create log dir + run: mkdir -p "$LOG_DIR" - - name: Install brew packages - if: matrix.os == 'osx' - run: | - brew update --quiet - brew install automake cpanminus ninja + - name: Install dependencies + run: ./.github/scripts/install_deps.sh cpanminus - name: Setup interpreter packages - run: ./ci/install.sh + run: | + # Use default CC to avoid compilation problems when installing Python modules. + echo "Install neovim module for Python." + CC=cc python3 -m pip -q install --user --upgrade pynvim + + echo "Install neovim RubyGem." + gem install --no-document --bindir "$BIN_DIR" --user-install --pre neovim + + echo "Install neovim npm package" + npm install -g neovim + npm link neovim + + if [[ $RUNNER_OS != macOS ]]; then + sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log" + perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION' + fi + + - run: echo "DEPS_BUILD_DIR=$HOME/nvim-deps" >> $GITHUB_ENV - uses: ./.github/actions/cache - name: Build third-party deps - run: ./ci/before_script.sh + run: | + cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja ${{ matrix.deps_flags }} + cmake --build $DEPS_BUILD_DIR - name: Build - run: ./ci/run_tests.sh build_nvim + run: | + cmake -B build -G Ninja -D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.flags }} + cmake --build build - if: "!cancelled()" name: Determine if run should be aborted @@ -237,39 +263,106 @@ jobs: run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT - if: matrix.flavor != 'tsan' && matrix.flavor != 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') - name: Unittests + name: Unittest timeout-minutes: 5 - run: ./ci/run_tests.sh unittests + run: cmake --build build --target unittest - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Functionaltests + - if: matrix.flavor != 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') + name: Functionaltest + timeout-minutes: 15 + run: cmake --build build --target functionaltest + + - if: matrix.flavor == 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') + name: Functionaltest with PUC Lua timeout-minutes: 15 - run: ./ci/run_tests.sh functionaltests + run: cmake --build build --target functionaltest-lua - if: matrix.flavor != 'tsan' && (success() || failure() && steps.abort_job.outputs.status == 'success') - name: Oldtests - run: ./ci/run_tests.sh oldtests + name: Oldtest + run: make oldtest - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Install nvim - run: ./ci/run_tests.sh install_nvim + name: Install + run: cmake --install build + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Installtests + run: | + "$INSTALL_PREFIX/bin/nvim" --version + if ! "$INSTALL_PREFIX/bin/nvim" -u NONE -e -c ':help' -c ':qall'; then + echo "Running ':help' in the installed nvim failed." + echo "Maybe the helptags have not been generated properly." + echo 'Failed running :help' + exit 1 + fi + + # Check that all runtime files were installed + for file in $(git -C runtime ls-files '*.vim' '*.ps' '*.dict' '*.py' '*.tutor'); do + if ! test -e "$INSTALL_PREFIX/share/nvim/runtime/$file"; then + printf "%s%s" 'It appears that %s is not installed.' "$file" + exit 1 + fi + done + + # Check that some runtime files are installed and are executables + for file in $(git -C runtime ls-files '*.awk' '*.sh' '*.bat'); do + if ! test -x "$INSTALL_PREFIX/share/nvim/runtime/$file"; then + printf "%s%s" 'It appears that %s is not installed or is not executable.' "$file" + exit 1 + fi + done + + # Check that generated syntax file has function names, #5060. + genvimsynf=syntax/vim/generated.vim + gpat='syn keyword vimFuncName .*eval' + if ! grep -q "$gpat" "$INSTALL_PREFIX/share/nvim/runtime/$genvimsynf"; then + echo "It appears that $genvimsynf does not contain $gpat." + exit 1 + fi + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Show logs + run: cat $(find "$LOG_DIR" -type f) + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Show core dumps + run: | + # TODO(dundargoc): app should be luajit for unittests + app="build/bin/nvim" + if test "$RUNNER_OS" = macOS; then + cores="$(find /cores/ -type f -print)" + else + cores="$(find ./ -type f \( -name 'core.*' -o -name core -o -name nvim.core \) -print)" + fi + + if test -z "$cores"; then + exit 0 + fi + for core in $cores; do + if test "$RUNNER_OS" = macOS; then + lldb -Q -o "bt all" -f "$app" -c "$core" + else + gdb -n -batch -ex 'thread apply all bt full' "$app" -c "$core" + fi + done + echo 'Core dumps found' + exit 1 old_cmake: name: Test oldest supported cmake runs-on: ubuntu-22.04 timeout-minutes: 15 env: - CI_OS_NAME: linux CMAKE_URL: 'https://cmake.org/files/v3.10/cmake-3.10.0-Linux-x86_64.sh' CMAKE_VERSION: '3.10.0' steps: - uses: actions/checkout@v3 - - name: Setup common environment variables - run: ./.github/workflows/env.sh old_cmake + - name: Set up environment + run: echo "$BIN_DIR" >> $GITHUB_PATH - - name: Install apt packages - run: ./.github/scripts/install_deps_ubuntu.sh + - name: Install dependencies + run: ./.github/scripts/install_deps.sh - name: Install minimum required version of cmake run: | @@ -290,7 +383,7 @@ jobs: run: make deps - name: Build - run: make CMAKE_FLAGS="-D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX -D MIN_LOG_LEVEL=3" + run: make CMAKE_FLAGS="-D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX" - name: Install run: make install @@ -298,23 +391,28 @@ jobs: windows: runs-on: windows-2019 timeout-minutes: 45 - env: - DEPS_BUILD_DIR: ${{ github.workspace }}/nvim-deps - name: windows (MSVC_64) + name: windows steps: - uses: actions/checkout@v3 - uses: ./.github/actions/cache - name: Set env - run: ./.github/workflows/env.ps1 + run: | + $installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) { + & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | ForEach-Object { + $name, $value = $_ -split '=', 2 + "$name=$value" >> $env:GITHUB_ENV + } + } - name: Build deps run: | cmake -S cmake.deps -B $env:DEPS_BUILD_DIR -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' cmake --build $env:DEPS_BUILD_DIR - - name: Build nvim + - name: Build run: | cmake -B build -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' -D CI_BUILD=ON cmake --build build @@ -349,15 +447,15 @@ jobs: "status=${{ job.status }}" >> $env:GITHUB_OUTPUT - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Run functionaltests + name: Run functionaltest timeout-minutes: 15 run: cmake --build build --target functionaltest - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Run oldtests + name: Run oldtest run: | # Add MSYS to path, required for e.g. `find` used in test scripts. - # But would break functionaltests, where its `more` would be used then. + # But would break functionaltest, where its `more` would be used then. $OldPath = $env:PATH $env:PATH = "C:\msys64\usr\bin;$env:PATH" & "C:\msys64\mingw64\bin\mingw32-make.exe" -C $(Convert-Path src\nvim\testdir) VERBOSE=1 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a11a87f93a..497a79d2d1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,28 +13,19 @@ jobs: contents: read security-events: write - strategy: - fail-fast: false - matrix: - language: [ 'cpp' ] - steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup common environment variables - run: ./.github/workflows/env.sh - - - name: Install apt packages - run: ./.github/scripts/install_deps_ubuntu.sh + - name: Install dependencies + run: ./.github/scripts/install_deps.sh - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: - languages: ${{ matrix.language }} + languages: cpp - - if: matrix.language == 'cpp' - run: make + - run: make - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 87e2cb1453..e63f119958 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -11,9 +11,7 @@ jobs: - uses: actions/checkout@v3 - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y autoconf automake build-essential cmake gettext libtool-bin locales ninja-build pkg-config unzip + run: ./.github/scripts/install_deps.sh - name: Download Coverity run: | diff --git a/.github/workflows/env.ps1 b/.github/workflows/env.ps1 deleted file mode 100644 index 8ac267f2f9..0000000000 --- a/.github/workflows/env.ps1 +++ /dev/null @@ -1,7 +0,0 @@ -$installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) { - & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | ForEach-Object { - $name, $value = $_ -split '=', 2 - "$name=$value" >> $env:GITHUB_ENV - } -} diff --git a/.github/workflows/env.sh b/.github/workflows/env.sh deleted file mode 100755 index b4cdb3a8d9..0000000000 --- a/.github/workflows/env.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash -set -e -u - -FLAVOR=${1:-} - -BUILD_DIR=$CI_BUILD_DIR/build -BIN_DIR=$CI_BUILD_DIR/bin -DEPS_BUILD_DIR=$HOME/nvim-deps -INSTALL_PREFIX=$CI_BUILD_DIR/nvim-install -LOG_DIR=$BUILD_DIR/log -NVIM_LOG_FILE=$BUILD_DIR/.nvimlog -VALGRIND_LOG=$LOG_DIR/valgrind-%p.log -CACHE_DIR=$CI_BUILD_DIR/.cache -CACHE_UNCRUSTIFY=$CACHE_DIR/uncrustify -DEPS_CMAKE_FLAGS= -FUNCTIONALTEST=functionaltest -CMAKE_FLAGS="-D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX -D MIN_LOG_LEVEL=3" -CLANG_SANITIZER= -ASAN_OPTIONS= -UBSAN_OPTIONS= -TSAN_OPTIONS= - -case "$FLAVOR" in - asan) - CLANG_SANITIZER=ASAN_UBSAN - ASAN_OPTIONS="detect_leaks=1:check_initialization_order=1:handle_abort=1:handle_sigill=1:log_path=$LOG_DIR/asan:intercept_tls_get_addr=0" - UBSAN_OPTIONS="print_stacktrace=1 log_path=$LOG_DIR/ubsan" - ;; - tsan) - TSAN_OPTIONS=log_path=$LOG_DIR/tsan - CLANG_SANITIZER=TSAN - ;; - uchar) - CMAKE_FLAGS+=" -D UNSIGNED_CHAR=ON" - ;; - lintc) - # Re-enable once system deps are available - # CMAKE_FLAGS+=" -D LIBLUV_LIBRARY:FILEPATH=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/lua/5.1/luv.so -D LIBLUV_INCLUDE_DIR:PATH=/usr/include/lua5.1" - - # Ideally all dependencies should external for this job, but some - # dependencies don't have the required version available. We use the - # bundled versions for these with the hopes of being able to remove them - # later on. - DEPS_CMAKE_FLAGS+=" -D USE_BUNDLED=OFF -D USE_BUNDLED_LUV=ON -D USE_BUNDLED_LIBVTERM=ON" - ;; - functionaltest-lua) - CMAKE_FLAGS+=" -D PREFER_LUA=ON" - FUNCTIONALTEST=functionaltest-lua - DEPS_CMAKE_FLAGS+=" -D USE_BUNDLED_LUAJIT=OFF" - ;; - *) - ;; -esac - -cat <<EOF >> "$GITHUB_ENV" -CMAKE_FLAGS=$CMAKE_FLAGS -BUILD_DIR=$BUILD_DIR -BIN_DIR=$BIN_DIR -DEPS_BUILD_DIR=$DEPS_BUILD_DIR -DEPS_CMAKE_FLAGS=$DEPS_CMAKE_FLAGS -FUNCTIONALTEST=$FUNCTIONALTEST -INSTALL_PREFIX=$INSTALL_PREFIX -LOG_DIR=$LOG_DIR -NVIM_LOG_FILE=$NVIM_LOG_FILE -VALGRIND_LOG=$VALGRIND_LOG -CACHE_DIR=$CACHE_DIR -CACHE_UNCRUSTIFY=$CACHE_UNCRUSTIFY -CLANG_SANITIZER=$CLANG_SANITIZER -ASAN_OPTIONS=$ASAN_OPTIONS -UBSAN_OPTIONS=$UBSAN_OPTIONS -TSAN_OPTIONS=$TSAN_OPTIONS -EOF - -cat <<EOF >> "$GITHUB_PATH" -$BIN_DIR -EOF diff --git a/.github/workflows/lintcommit.yml b/.github/workflows/lintcommit.yml index 9941a01a9b..afedbe0b12 100644 --- a/.github/workflows/lintcommit.yml +++ b/.github/workflows/lintcommit.yml @@ -15,9 +15,7 @@ jobs: with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} - path: pr_nvim - uses: rhysd/action-setup-vim@v1 with: neovim: true - - run: wget https://raw.githubusercontent.com/neovim/neovim/master/scripts/lintcommit.lua - - run: nvim --clean -es +"cd pr_nvim" +"lua dofile('../lintcommit.lua').main({trace=false})" + - run: nvim --clean -es +"lua require('scripts.lintcommit').main({trace=false})" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 838caf3fca..a05038f32a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,20 +111,24 @@ jobs: windows: runs-on: windows-2019 - env: - DEPS_BUILD_DIR: ${{ github.workspace }}/nvim-deps - CMAKE_BUILD_TYPE: "RelWithDebInfo" name: windows (MSVC_64) steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - name: Set env - run: ./.github/workflows/env.ps1 + run: | + $installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) { + & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | ForEach-Object { + $name, $value = $_ -split '=', 2 + "$name=$value" >> $env:GITHUB_ENV + } + } - name: Build deps run: | - cmake -S cmake.deps -B $env:DEPS_BUILD_DIR -G Ninja -DCMAKE_BUILD_TYPE='RelWithDebInfo' - cmake --build $env:DEPS_BUILD_DIR + cmake -S cmake.deps -B .deps -G Ninja -DCMAKE_BUILD_TYPE='RelWithDebInfo' + cmake --build .deps - name: build package run: | cmake -B build -G Ninja -DCMAKE_BUILD_TYPE='RelWithDebInfo' diff --git a/ci/before_script.sh b/ci/before_script.sh deleted file mode 100755 index 9797d3ae30..0000000000 --- a/ci/before_script.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -# Test some of the configuration variables. -if [[ -n "${GCOV}" ]] && [[ ! $(type -P "${GCOV}") ]]; then - echo "\$GCOV: '${GCOV}' is not executable." - exit 1 -fi - -if test "${FUNCTIONALTEST}" = "functionaltest-lua" ; then - DEPS_CMAKE_FLAGS="${DEPS_CMAKE_FLAGS} -D USE_BUNDLED_LUA=ON" -fi - -mkdir -p "${DEPS_BUILD_DIR}" -cd "${DEPS_BUILD_DIR}" -echo "Configuring with '${DEPS_CMAKE_FLAGS}'." -# shellcheck disable=SC2086 -cmake -G Ninja ${DEPS_CMAKE_FLAGS} "${CI_BUILD_DIR}/cmake.deps/" - -ninja || exit 1 - -cd "${CI_BUILD_DIR}" - -# Install cluacov for Lua coverage. -if [[ "$USE_LUACOV" == 1 ]]; then - "${DEPS_BUILD_DIR}/usr/bin/luarocks" install cluacov -fi - -rm -rf "${LOG_DIR}" -mkdir -p "${LOG_DIR}" diff --git a/ci/install.sh b/ci/install.sh deleted file mode 100755 index d65c86032b..0000000000 --- a/ci/install.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -# Use default CC to avoid compilation problems when installing Python modules. -echo "Install neovim module for Python." -CC=cc python3 -m pip -q install --user --upgrade pynvim - -echo "Install neovim RubyGem." -gem install --no-document --bindir "$BIN_DIR" --user-install --pre neovim - -echo "Install neovim npm package" -npm install -g neovim -npm link neovim - -if [[ $CI_OS_NAME != osx ]]; then - sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log" - perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION' -fi diff --git a/ci/run_tests.sh b/ci/run_tests.sh deleted file mode 100755 index 22ed4a4332..0000000000 --- a/ci/run_tests.sh +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -fail() { - local test_name="$1" - local message="$2" - - : "${message:=Test $test_name failed}" - - local full_msg="$test_name :: $message" - echo "Failed: $full_msg" - exit 1 -} - -print_core() { - local app="$1" - local core="$2" - if test "$app" = quiet ; then - echo "Found core $core" - return 0 - fi - echo "======= Core file $core =======" - if test "${CI_OS_NAME}" = osx ; then - lldb -Q -o "bt all" -f "${app}" -c "${core}" - else - gdb -n -batch -ex 'thread apply all bt full' "${app}" -c "${core}" - fi -} - -check_core_dumps() { - local del= - if test "$1" = "--delete" ; then - del=1 - shift - fi - local app="${1:-${BUILD_DIR}/bin/nvim}" - local cores - if test "${CI_OS_NAME}" = osx ; then - cores="$(find /cores/ -type f -print)" - local _sudo='sudo' - else - cores="$(find ./ -type f \( -name 'core.*' -o -name core -o -name nvim.core \) -print)" - local _sudo= - fi - - if test -z "${cores}" ; then - return - fi - local core - for core in $cores; do - if test "$del" = "1" ; then - print_core "$app" "$core" >&2 - "$_sudo" rm "$core" - else - print_core "$app" "$core" - fi - done - if test "$app" != quiet ; then - fail 'cores' 'Core dumps found' - fi -} - -check_logs() { - # Iterate through each log to remove an useless warning. - # shellcheck disable=SC2044 - for log in $(find "${1}" -type f -name "${2}"); do - sed -i "${log}" \ - -e '/Warning: noted but unhandled ioctl/d' \ - -e '/could cause spurious value errors to appear/d' \ - -e '/See README_MISSING_SYSCALL_OR_IOCTL for guidance/d' - done - - # Now do it again, but only consider files with size > 0. - local err="" - # shellcheck disable=SC2044 - for log in $(find "${1}" -type f -name "${2}" -size +0); do - cat "${log}" - err=1 - rm "${log}" - done - if test -n "${err}" ; then - fail 'logs' 'Runtime errors detected.' - fi -} - -valgrind_check() { - check_logs "${1}" "valgrind-*" -} - -check_sanitizer() { - if test -n "${CLANG_SANITIZER}"; then - check_logs "${1}" "*san.*" | cat - fi -} - -unittests() {( - ulimit -c unlimited || true - if ! ninja -C "${BUILD_DIR}" unittest; then - fail 'unittests' 'Unit tests failed' - fi - check_core_dumps "$(command -v luajit)" -)} - -functionaltests() {( - ulimit -c unlimited || true - if ! ninja -C "${BUILD_DIR}" "${FUNCTIONALTEST}"; then - fail 'functionaltests' 'Functional tests failed' - fi - check_sanitizer "${LOG_DIR}" - valgrind_check "${LOG_DIR}" - check_core_dumps -)} - -oldtests() {( - ulimit -c unlimited || true - if ! make oldtest; then - reset - fail 'oldtests' 'Legacy tests failed' - fi - check_sanitizer "${LOG_DIR}" - valgrind_check "${LOG_DIR}" - check_core_dumps -)} - -check_runtime_files() {( - local test_name="$1" ; shift - local message="$1" ; shift - local tst="$1" ; shift - - cd runtime || exit - for file in $(git ls-files "$@") ; do - # Check that test is not trying to work with files with spaces/etc - # Prefer failing the build over using more robust construct because files - # with IFS are not welcome. - if ! test -e "$file" ; then - fail "$test_name" "It appears that $file is only a part of the file name" - fi - if ! test "$tst" "$INSTALL_PREFIX/share/nvim/runtime/$file" ; then - fail "$test_name" "$(printf "%s%s" "$message" "$file")" - fi - done -)} - -install_nvim() {( - if ! ninja -C "${BUILD_DIR}" install; then - fail 'install' 'make install failed' - fi - - "${INSTALL_PREFIX}/bin/nvim" --version - if ! "${INSTALL_PREFIX}/bin/nvim" -u NONE -e -c ':help' -c ':qall' ; then - echo "Running ':help' in the installed nvim failed." - echo "Maybe the helptags have not been generated properly." - fail 'help' 'Failed running :help' - fi - - # Check that all runtime files were installed - check_runtime_files \ - 'runtime-install' \ - 'It appears that %s is not installed.' \ - -e \ - '*.vim' '*.ps' '*.dict' '*.py' '*.tutor' - - # Check that some runtime files are installed and are executables - check_runtime_files \ - 'not-exe' \ - 'It appears that %s is not installed or is not executable.' \ - -x \ - '*.awk' '*.sh' '*.bat' - - # Check that generated syntax file has function names, #5060. - local genvimsynf=syntax/vim/generated.vim - local gpat='syn keyword vimFuncName .*eval' - if ! grep -q "$gpat" "${INSTALL_PREFIX}/share/nvim/runtime/$genvimsynf" ; then - fail 'funcnames' "It appears that $genvimsynf does not contain $gpat." - fi -)} - -build_nvim() { - check_core_dumps --delete quiet - - if test -n "${CLANG_SANITIZER}" ; then - CMAKE_FLAGS="${CMAKE_FLAGS} -D CLANG_${CLANG_SANITIZER}=ON" - fi - - mkdir -p "${BUILD_DIR}" - cd "${BUILD_DIR}" - echo "Configuring with '${CMAKE_FLAGS} $*'." - # shellcheck disable=SC2086 - cmake -G Ninja ${CMAKE_FLAGS} "$@" "${CI_BUILD_DIR}" - - echo "Building nvim." - ninja nvim || exit 1 - - # Invoke nvim to trigger *San early. - if ! (bin/nvim --version && bin/nvim -u NONE -e -cq | cat -vet) ; then - check_sanitizer "${LOG_DIR}" - exit 1 - fi - check_sanitizer "${LOG_DIR}" - - cd "${CI_BUILD_DIR}" -} - -# Run all tests (with some caveats) if no input argument is given -if (($# == 0)); then - tests=('build_nvim') - - # Additional threads aren't created in the unit/old tests - if test "$CLANG_SANITIZER" != "TSAN"; then - if test "${FUNCTIONALTEST}" != "functionaltest-lua"; then - tests+=('unittests') - fi - tests+=('oldtests') - fi - - tests+=('functionaltests' 'install_nvim') -else - tests=("$@") -fi - -for i in "${tests[@]}"; do - eval "$i" || exit -done - -if [[ -s "${GCOV_ERROR_FILE}" ]]; then - echo '=== Unexpected gcov errors: ===' - cat "${GCOV_ERROR_FILE}" - exit 1 -fi diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake index 3ac15f91ea..fe346661b5 100644 --- a/cmake/RunTests.cmake +++ b/cmake/RunTests.cmake @@ -1,13 +1,5 @@ # Set LC_ALL to meet expectations of some locale-sensitive tests. set(ENV{LC_ALL} "en_US.UTF-8") - -if(POLICY CMP0012) - # Avoid policy warning due to CI=true. This is needed even if the main - # project has already set this policy as project settings aren't inherited - # when using cmake script mode (-P). - cmake_policy(SET CMP0012 NEW) -endif() - set(ENV{VIMRUNTIME} ${WORKING_DIR}/runtime) set(ENV{NVIM_RPLUGIN_MANIFEST} ${BUILD_DIR}/Xtest_rplugin_manifest) set(ENV{XDG_CONFIG_HOME} ${BUILD_DIR}/Xtest_xdg/config) @@ -99,7 +91,7 @@ if(NOT res EQUAL 0) endif() # Dump the logfile on CI (if not displayed and moved already). - if($ENV{CI}) + if(CI_BUILD) if(EXISTS $ENV{NVIM_LOG_FILE} AND NOT EXISTS $ENV{NVIM_LOG_FILE}.displayed) file(READ $ENV{NVIM_LOG_FILE} out) message(STATUS "$NVIM_LOG_FILE: $ENV{NVIM_LOG_FILE}\n${out}") diff --git a/cmake/WindowsDllCopy.cmake b/cmake/WindowsDllCopy.cmake index c07dc51b8a..b51e66e5cc 100644 --- a/cmake/WindowsDllCopy.cmake +++ b/cmake/WindowsDllCopy.cmake @@ -23,8 +23,9 @@ foreach(DLL_NAME ${DLLS}) message(FATAL_ERROR "Unable to find dependency ${DLL_NAME}") endif() - message("Copying ${DLL_NAME} to ${DST}") + if($ENV{CI} MATCHES "true") + message("Copying ${DLL_NAME} to ${DST}") + endif() execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${DLL_PATH} ${DST}) unset(DLL_PATH CACHE) endforeach() - diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index b438595b5f..2afb22bb43 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -47,6 +47,9 @@ The following changes may require adaptations in user config or plugins. • libiconv is now a required build dependency. +• Unsaved changes are now preserved rather than discarded when |channel-stdio| + is closed. + ============================================================================== NEW FEATURES *news-features* @@ -63,7 +66,7 @@ The following new APIs or features were added. < (or the Vimscript equivalent) to their |config| file. -• Run Lua scripts from your shell using |-l|. > +• Added support for running Lua scripts from shell using |-l|. > nvim -l foo.lua --arg1 --arg2 < Also works with stdin: > echo "print(42)" | nvim -l - diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 17f1c822ff..e4106358f1 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6201,8 +6201,10 @@ A jump table for the options with a short description can be found at |Q_op|. this label. < - Where to truncate line if too long. Default is at the start. No width fields allowed. - = - Separation point between alignment sections. Each section will - be separated by an equal number of spaces. + = - Separation point between alignment sections. Each section will + be separated by an equal number of spaces. With one %= what + comes after it will be right-aligned. With two %= there is a + middle part, with white space left and right of it. No width fields allowed. # - Set highlight group. The name must follow and then a # again. Thus use %#HLname# for highlight group HLname. The same diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index bb3b670b24..97fc211c36 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -267,7 +267,6 @@ Options: 'pumblend' pseudo-transparent popupmenu 'scrollback' 'signcolumn' supports up to 9 dynamic/fixed columns - 'statusline' supports unlimited alignment sections 'tabline' %@Func@foo%X can call any function on mouse-click 'winblend' pseudo-transparency in floating windows |api-floatwin| 'winhighlight' window-local highlights @@ -292,6 +291,7 @@ These Nvim features were later integrated into Vim. - |WinScrolled| - |:sign-define| "numhl" argument - |:source| works with anonymous (no file) scripts +- 'statusline' supports unlimited alignment sections ============================================================================== 5. Changed features *nvim-features-changed* diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 1f605b72f3..ca91f3f402 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -2449,6 +2449,7 @@ local function match_pattern(name, path, tail, pat) return false end end + -- If the pattern contains a / match against the full path, otherwise just the tail local fullpat = '^' .. pat .. '$' local matches @@ -2526,64 +2527,64 @@ function M.match(args) name = api.nvim_buf_get_name(bufnr) end - if name then - name = normalize_path(name) - end - local ft, on_detect - -- First check for the simple case where the full path exists as a key - local path = vim.fn.fnamemodify(name, ':p') - ft, on_detect = dispatch(filename[path], path, bufnr) - if ft then - return ft, on_detect - end + if name then + name = normalize_path(name) - -- Next check against just the file name - local tail = vim.fn.fnamemodify(name, ':t') - ft, on_detect = dispatch(filename[tail], path, bufnr) - if ft then - return ft, on_detect - end + -- First check for the simple case where the full path exists as a key + local path = vim.fn.fnamemodify(name, ':p') + ft, on_detect = dispatch(filename[path], path, bufnr) + if ft then + return ft, on_detect + end - -- Next, check the file path against available patterns with non-negative priority - local j = 1 - for i, v in ipairs(pattern_sorted) do - local k = next(v) - local opts = v[k][2] - if opts.priority < 0 then - j = i - break + -- Next check against just the file name + local tail = vim.fn.fnamemodify(name, ':t') + ft, on_detect = dispatch(filename[tail], path, bufnr) + if ft then + return ft, on_detect end - local filetype = v[k][1] - local matches = match_pattern(name, path, tail, k) - if matches then - ft, on_detect = dispatch(filetype, path, bufnr, matches) - if ft then - return ft, on_detect + -- Next, check the file path against available patterns with non-negative priority + local j = 1 + for i, v in ipairs(pattern_sorted) do + local k = next(v) + local opts = v[k][2] + if opts.priority < 0 then + j = i + break + end + + local filetype = v[k][1] + local matches = match_pattern(name, path, tail, k) + if matches then + ft, on_detect = dispatch(filetype, path, bufnr, matches) + if ft then + return ft, on_detect + end end end - end - -- Next, check file extension - local ext = vim.fn.fnamemodify(name, ':e') - ft, on_detect = dispatch(extension[ext], path, bufnr) - if ft then - return ft, on_detect - end + -- Next, check file extension + local ext = vim.fn.fnamemodify(name, ':e') + ft, on_detect = dispatch(extension[ext], path, bufnr) + if ft then + return ft, on_detect + end - -- Next, check patterns with negative priority - for i = j, #pattern_sorted do - local v = pattern_sorted[i] - local k = next(v) + -- Next, check patterns with negative priority + for i = j, #pattern_sorted do + local v = pattern_sorted[i] + local k = next(v) - local filetype = v[k][1] - local matches = match_pattern(name, path, tail, k) - if matches then - ft, on_detect = dispatch(filetype, path, bufnr, matches) - if ft then - return ft, on_detect + local filetype = v[k][1] + local matches = match_pattern(name, path, tail, k) + if matches then + ft, on_detect = dispatch(filetype, path, bufnr, matches) + if ft then + return ft, on_detect + end end end end @@ -2603,7 +2604,9 @@ function M.match(args) -- If the function tries to use the filename that is nil then it will fail, -- but this enables checks which do not need a filename to still work. local ok - ok, ft = pcall(require('vim.filetype.detect').match_contents, contents, name) + ok, ft = pcall(require('vim.filetype.detect').match_contents, contents, name, function(ext) + return dispatch(extension[ext], name, bufnr) + end) if ok and ft then return ft end diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index edffdde9c7..b3d9fedeae 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -1420,7 +1420,7 @@ local patterns_hashbang = { ---@private -- File starts with "#!". -local function match_from_hashbang(contents, path) +local function match_from_hashbang(contents, path, dispatch_extension) local first_line = contents[1] -- Check for a line like "#!/usr/bin/env {options} bash". Turn it into -- "#!/usr/bin/bash" to make matching easier. @@ -1473,6 +1473,11 @@ local function match_from_hashbang(contents, path) return ft end end + + -- If nothing matched, check the extension table. For a hashbang like + -- '#!/bin/env foo', this will set the filetype to 'fooscript' assuming + -- the filetype for the 'foo' extension is 'fooscript' in the extension table. + return dispatch_extension(name) end local patterns_text = { @@ -1652,10 +1657,10 @@ local function match_from_text(contents, path) return cvs_diff(path, contents) end -M.match_contents = function(contents, path) +function M.match_contents(contents, path, dispatch_extension) local first_line = contents[1] if first_line:find('^#!') then - return match_from_hashbang(contents, path) + return match_from_hashbang(contents, path, dispatch_extension) else return match_from_text(contents, path) end diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index 96b1e24ba9..4127198576 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -96,11 +96,13 @@ function M.get_parser(bufnr, lang, opts) if bufnr == nil or bufnr == 0 then bufnr = a.nvim_get_current_buf() end - if lang == nil then - lang = a.nvim_buf_get_option(bufnr, 'filetype') - end - if parsers[bufnr] == nil or parsers[bufnr]:lang() ~= lang then + if parsers[bufnr] == nil then + lang = lang or a.nvim_buf_get_option(bufnr, 'filetype') + parsers[bufnr] = M._create_parser(bufnr, lang, opts) + elseif lang and parsers[bufnr]:lang() ~= lang then + -- Only try to create a new parser if lang is provided + -- and it doesn't match the stored parser parsers[bufnr] = M._create_parser(bufnr, lang, opts) end @@ -411,6 +413,7 @@ function M.show_tree(opts) vim.bo[b].buflisted = false vim.bo[b].buftype = 'nofile' vim.bo[b].bufhidden = 'wipe' + vim.bo[b].filetype = 'query' local title = opts.title if not title then @@ -425,9 +428,6 @@ function M.show_tree(opts) pg:draw(b) - vim.fn.matchadd('Comment', '\\[[0-9:-]\\+\\]') - vim.fn.matchadd('String', '".*"') - a.nvim_buf_clear_namespace(buf, pg.ns, 0, -1) a.nvim_buf_set_keymap(b, 'n', '<CR>', '', { desc = 'Jump to the node under the cursor in the source buffer', @@ -467,6 +467,15 @@ function M.show_tree(opts) end_col = math.max(0, pos.end_col), hl_group = 'Visual', }) + + local topline, botline = vim.fn.line('w0', win), vim.fn.line('w$', win) + + -- Move the cursor if highlighted range is completely out of view + if pos.lnum < topline and pos.end_lnum < topline then + a.nvim_win_set_cursor(win, { pos.end_lnum + 1, 0 }) + elseif pos.lnum > botline and pos.end_lnum > botline then + a.nvim_win_set_cursor(win, { pos.lnum + 1, 0 }) + end end, }) diff --git a/runtime/lua/vim/treesitter/playground.lua b/runtime/lua/vim/treesitter/playground.lua index be7764e6f0..001bc2d5bf 100644 --- a/runtime/lua/vim/treesitter/playground.lua +++ b/runtime/lua/vim/treesitter/playground.lua @@ -136,6 +136,8 @@ function TSPlayground:new(bufnr, lang) return t end +local decor_ns = api.nvim_create_namespace('ts.playground') + --- Write the contents of this Playground into {bufnr}. --- ---@param bufnr number Buffer number to write into. @@ -144,22 +146,28 @@ function TSPlayground:draw(bufnr) vim.bo[bufnr].modifiable = true local lines = {} ---@type string[] for _, item in self:iter() do - lines[#lines + 1] = table.concat({ - string.rep(' ', item.depth), - item.text, - item.lnum == item.end_lnum - and string.format(' [%d:%d-%d]', item.lnum + 1, item.col + 1, item.end_col) - or string.format( - ' [%d:%d-%d:%d]', - item.lnum + 1, - item.col + 1, - item.end_lnum + 1, - item.end_col - ), - self.opts.lang and string.format(' %s', item.lang) or '', - }) + lines[#lines + 1] = string.rep(' ', item.depth) .. item.text end api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) + + api.nvim_buf_clear_namespace(bufnr, decor_ns, 0, -1) + + for i, item in self:iter() do + local range_str + if item.lnum == item.end_lnum then + range_str = string.format('[%d:%d-%d]', item.lnum + 1, item.col + 1, item.end_col) + else + range_str = + string.format('[%d:%d-%d:%d]', item.lnum + 1, item.col + 1, item.end_lnum + 1, item.end_col) + end + + local lang_str = self.opts.lang and string.format(' %s', item.lang) or '' + + api.nvim_buf_set_extmark(bufnr, decor_ns, i - 1, 0, { + virt_text = { { range_str, 'Comment' }, { lang_str, 'Title' } }, + }) + end + vim.bo[bufnr].modifiable = false end diff --git a/scripts/lintcommit.lua b/scripts/lintcommit.lua index 71796a5e02..977f7e7e46 100644 --- a/scripts/lintcommit.lua +++ b/scripts/lintcommit.lua @@ -128,10 +128,10 @@ local function validate_commit(commit_message) return [[There should only be one whitespace after the colon.]] end - -- Check that first character after space isn't uppercase. - if string.match(after_colon:sub(2,2), '%u') then - return [[First character should not be uppercase.]] - end + -- Allow lowercase or ALL_UPPER but not Titlecase. + if after_colon:match(' *%u%l') then + return [[Description should not be Capitalized.]] + end -- Check that description isn't just whitespaces if vim.trim(after_colon) == "" then @@ -231,7 +231,8 @@ function M._test() ['refactor(): empty scope'] = false, ['ci( ): whitespace as scope'] = false, ['ci: period at end of sentence.'] = false, - ['ci: Starting sentence capitalized'] = false, + ['ci: Capitalized first word'] = false, + ['ci: UPPER_CASE first word'] = true, ['unknown: using unknown type'] = false, ['ci: you\'re saying this commit message just goes on and on and on and on and on and on for way too long?'] = false, } diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 5953dd3ab9..22cbec0d06 100755 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -78,8 +78,7 @@ if(ENABLE_IWYU) endif() if(MSVC) - # TODO(dundargoc): bump warning level - target_compile_options(main_lib INTERFACE -W2) + target_compile_options(main_lib INTERFACE -W3) # Disable warnings that give too many false positives. target_compile_options(main_lib INTERFACE -wd4311 -wd4146) @@ -106,30 +105,6 @@ if(HAVE_WIMPLICIT_FALLTHROUGH_FLAG) target_compile_options(main_lib INTERFACE -Wimplicit-fallthrough) endif() -option(ENABLE_COMPILER_SUGGESTIONS "Enable -Wsuggest compiler warnings" OFF) -if(ENABLE_COMPILER_SUGGESTIONS) - # Clang doesn't have -Wsuggest-attribute so check for each one. - check_c_compiler_flag(-Wsuggest-attribute=pure HAVE_WSUGGEST_ATTRIBUTE_PURE) - if(HAVE_WSUGGEST_ATTRIBUTE_PURE) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=pure) - endif() - - check_c_compiler_flag(-Wsuggest-attribute=const HAVE_WSUGGEST_ATTRIBUTE_CONST) - if(HAVE_WSUGGEST_ATTRIBUTE_CONST) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=const) - endif() - - check_c_compiler_flag(-Wsuggest-attribute=malloc HAVE_WSUGGEST_ATTRIBUTE_MALLOC) - if(HAVE_WSUGGEST_ATTRIBUTE_MALLOC) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=malloc) - endif() - - check_c_compiler_flag(-Wsuggest-attribute=cold HAVE_WSUGGEST_ATTRIBUTE_COLD) - if(HAVE_WSUGGEST_ATTRIBUTE_COLD) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=cold) - endif() -endif() - if(MINGW) # Use POSIX compatible stdio in Mingw target_compile_definitions(main_lib INTERFACE __USE_MINGW_ANSI_STDIO) @@ -406,13 +381,16 @@ list(REMOVE_ITEM NVIM_SOURCES ${to_remove}) # xdiff, mpack, lua-cjson: inlined external project, we don't maintain it. #9306 if(MSVC) set_source_files_properties( - ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} /wd4090 /wd4244") + ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -wd4090 -wd4244 -wd4267") else() set_source_files_properties( ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-conversion -Wno-missing-noreturn -Wno-missing-format-attribute -Wno-double-promotion -Wno-strict-prototypes") endif() # Log level (MIN_LOG_LEVEL in log.h) +if($ENV{CI} MATCHES "true") + set(MIN_LOG_LEVEL 3) +endif() if("${MIN_LOG_LEVEL}" MATCHES "^$") # Minimize logging for release-type builds. target_compile_definitions(main_lib INTERFACE MIN_LOG_LEVEL=$<IF:$<CONFIG:Debug>,1,3>) diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index a2cb297b15..aff7622dc5 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -12,6 +12,7 @@ #include "nvim/api/autocmd.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" @@ -107,25 +108,24 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) break; case kObjectTypeString: group = augroup_find(opts->group.data.string.data); - if (group < 0) { - api_set_error(err, kErrorTypeValidation, "invalid augroup passed."); + VALIDATE_S((group >= 0), "group", opts->group.data.string.data, { goto cleanup; - } + }); break; case kObjectTypeInteger: group = (int)opts->group.data.integer; char *name = augroup_name(group); - if (!augroup_exists(name)) { - api_set_error(err, kErrorTypeValidation, "invalid augroup passed."); + VALIDATE_INT(augroup_exists(name), "group", opts->group.data.integer, { goto cleanup; - } + }); break; default: - api_set_error(err, kErrorTypeValidation, "group must be a string or an integer."); - goto cleanup; + VALIDATE_EXP(false, "group", "String or Integer", api_typename(opts->group.type), { + goto cleanup; + }); } - if (opts->event.type != kObjectTypeNil) { + if (HAS_KEY(opts->event)) { check_event = true; Object v = opts->event; @@ -134,57 +134,49 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) event_set[event_nr] = true; } else if (v.type == kObjectTypeArray) { FOREACH_ITEM(v.data.array, event_v, { - if (event_v.type != kObjectTypeString) { - api_set_error(err, - kErrorTypeValidation, - "Every event must be a string in 'event'"); + VALIDATE_T("event item", kObjectTypeString, event_v.type, { goto cleanup; - } + }); GET_ONE_EVENT(event_nr, event_v, cleanup); event_set[event_nr] = true; }) } else { - api_set_error(err, - kErrorTypeValidation, - "Not a valid 'event' value. Must be a string or an array"); - goto cleanup; + VALIDATE_EXP(false, "event", "String or Array", NULL, { + goto cleanup; + }); } } - if (opts->pattern.type != kObjectTypeNil && opts->buffer.type != kObjectTypeNil) { - api_set_error(err, kErrorTypeValidation, - "Cannot use both 'pattern' and 'buffer'"); + VALIDATE((!HAS_KEY(opts->pattern) || !HAS_KEY(opts->buffer)), + "%s", "Cannot use both 'pattern' and 'buffer'", { goto cleanup; - } + }); int pattern_filter_count = 0; - if (opts->pattern.type != kObjectTypeNil) { + if (HAS_KEY(opts->pattern)) { Object v = opts->pattern; if (v.type == kObjectTypeString) { pattern_filters[pattern_filter_count] = v.data.string.data; pattern_filter_count += 1; } else if (v.type == kObjectTypeArray) { - if (v.data.array.size > AUCMD_MAX_PATTERNS) { - api_set_error(err, kErrorTypeValidation, - "Too many patterns. Please limit yourself to %d or fewer", - AUCMD_MAX_PATTERNS); + VALIDATE((v.data.array.size <= AUCMD_MAX_PATTERNS), + "Too many patterns (maximum of %d)", AUCMD_MAX_PATTERNS, { goto cleanup; - } + }); FOREACH_ITEM(v.data.array, item, { - if (item.type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'pattern': must be a string"); + VALIDATE_T("pattern", kObjectTypeString, item.type, { goto cleanup; - } + }); pattern_filters[pattern_filter_count] = item.data.string.data; pattern_filter_count += 1; }); } else { - api_set_error(err, kErrorTypeValidation, - "Not a valid 'pattern' value. Must be a string or an array"); - goto cleanup; + VALIDATE_EXP(false, "pattern", "String or Array", api_typename(v.type), { + goto cleanup; + }); } } @@ -194,34 +186,33 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) goto cleanup; } - snprintf((char *)pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); - ADD(buffers, CSTR_TO_OBJ((char *)pattern_buflocal)); + snprintf(pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); + ADD(buffers, CSTR_TO_OBJ(pattern_buflocal)); } else if (opts->buffer.type == kObjectTypeArray) { if (opts->buffer.data.array.size > AUCMD_MAX_PATTERNS) { - api_set_error(err, - kErrorTypeValidation, - "Too many buffers. Please limit yourself to %d or fewer", AUCMD_MAX_PATTERNS); + api_set_error(err, kErrorTypeValidation, "Too many buffers (maximum of %d)", + AUCMD_MAX_PATTERNS); goto cleanup; } FOREACH_ITEM(opts->buffer.data.array, bufnr, { - if (bufnr.type != kObjectTypeInteger && bufnr.type != kObjectTypeBuffer) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'buffer': must be an integer"); + VALIDATE_EXP((bufnr.type == kObjectTypeInteger || bufnr.type == kObjectTypeBuffer), + "buffer", "Integer", api_typename(bufnr.type), { goto cleanup; - } + }); buf_T *buf = find_buffer_by_handle((Buffer)bufnr.data.integer, err); if (ERROR_SET(err)) { goto cleanup; } - snprintf((char *)pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); - ADD(buffers, CSTR_TO_OBJ((char *)pattern_buflocal)); + snprintf(pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); + ADD(buffers, CSTR_TO_OBJ(pattern_buflocal)); + }); + } else if (HAS_KEY(opts->buffer)) { + VALIDATE_EXP(false, "buffer", "Integer or Array", api_typename(opts->buffer.type), { + goto cleanup; }); - } else if (opts->buffer.type != kObjectTypeNil) { - api_set_error(err, kErrorTypeValidation, - "Invalid value for 'buffer': must be an integer or array of integers"); - goto cleanup; } FOREACH_ITEM(buffers, bufnr, { @@ -319,7 +310,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) PUT(autocmd_info, "pattern", - STRING_OBJ(cstr_to_string((char *)ap->pat))); + STRING_OBJ(cstr_to_string(ap->pat))); PUT(autocmd_info, "event", @@ -421,10 +412,8 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc { int64_t autocmd_id = -1; char *desc = NULL; - Array patterns = ARRAY_DICT_INIT; Array event_array = ARRAY_DICT_INIT; - AucmdExecutable aucmd = AUCMD_EXECUTABLE_INIT; Callback cb = CALLBACK_NONE; @@ -432,30 +421,23 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc goto cleanup; } - if (opts->callback.type != kObjectTypeNil && opts->command.type != kObjectTypeNil) { - api_set_error(err, kErrorTypeValidation, "specify either 'callback' or 'command', not both"); + VALIDATE((!HAS_KEY(opts->callback) || !HAS_KEY(opts->command)), + "%s", "Cannot use both 'callback' and 'command'", { goto cleanup; - } else if (opts->callback.type != kObjectTypeNil) { - // TODO(tjdevries): It's possible we could accept callable tables, - // but we don't do that many other places, so for the moment let's - // not do that. + }); + + if (HAS_KEY(opts->callback)) { + // NOTE: We could accept callable tables, but that isn't common in the API. Object *callback = &opts->callback; switch (callback->type) { case kObjectTypeLuaRef: - if (callback->data.luaref == LUA_NOREF) { - api_set_error(err, - kErrorTypeValidation, - "must pass an actual value"); + VALIDATE_S((callback->data.luaref != LUA_NOREF), "callback", "<no value>", { goto cleanup; - } - - if (!nlua_ref_is_function(callback->data.luaref)) { - api_set_error(err, - kErrorTypeValidation, - "must pass a function for callback"); + }); + VALIDATE_S(nlua_ref_is_function(callback->data.luaref), "callback", "<not a function>", { goto cleanup; - } + }); cb.type = kCallbackLua; cb.data.luaref = api_new_luaref(callback->data.luaref); @@ -465,28 +447,25 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc cb.data.funcref = string_to_cstr(callback->data.string); break; default: - api_set_error(err, - kErrorTypeException, - "'callback' must be a lua function or name of vim function"); - goto cleanup; + VALIDATE_EXP(false, "callback", "Lua function or Vim function name", + api_typename(callback->type), { + goto cleanup; + }); } aucmd.type = CALLABLE_CB; aucmd.callable.cb = cb; - } else if (opts->command.type != kObjectTypeNil) { + } else if (HAS_KEY(opts->command)) { Object *command = &opts->command; - if (command->type == kObjectTypeString) { - aucmd.type = CALLABLE_EX; - aucmd.callable.cmd = string_to_cstr(command->data.string); - } else { - api_set_error(err, - kErrorTypeValidation, - "'command' must be a string"); + VALIDATE_T("command", kObjectTypeString, command->type, { goto cleanup; - } + }); + aucmd.type = CALLABLE_EX; + aucmd.callable.cmd = string_to_cstr(command->data.string); } else { - api_set_error(err, kErrorTypeValidation, "must pass one of: 'command', 'callback'"); - goto cleanup; + VALIDATE(false, "%s", "Required: 'command' or 'callback'", { + goto cleanup; + }); } bool is_once = api_object_to_bool(opts->once, "once", false, err); @@ -501,25 +480,20 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc goto cleanup; } - if (opts->desc.type != kObjectTypeNil) { - if (opts->desc.type == kObjectTypeString) { - desc = opts->desc.data.string.data; - } else { - api_set_error(err, - kErrorTypeValidation, - "'desc' must be a string"); + if (HAS_KEY(opts->desc)) { + VALIDATE_T("desc", kObjectTypeString, opts->desc.type, { goto cleanup; - } + }); + desc = opts->desc.data.string.data; } if (patterns.size == 0) { ADD(patterns, STRING_OBJ(STATIC_CSTR_TO_STRING("*"))); } - if (event_array.size == 0) { - api_set_error(err, kErrorTypeValidation, "'event' is a required key"); + VALIDATE_R((event_array.size > 0), "event", { goto cleanup; - } + }); autocmd_id = next_autocmd_id++; FOREACH_ITEM(event_array, event_str, { @@ -564,10 +538,9 @@ cleanup: void nvim_del_autocmd(Integer id, Error *err) FUNC_API_SINCE(9) { - if (id <= 0) { - api_set_error(err, kErrorTypeException, "Invalid autocmd id"); + VALIDATE_INT((id > 0), "autocmd id", id, { return; - } + }); if (!autocmd_delete_id(id)) { api_set_error(err, kErrorTypeException, "Failed to delete autocmd"); } @@ -610,11 +583,10 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err) goto cleanup; } - if (opts->pattern.type != kObjectTypeNil && opts->buffer.type != kObjectTypeNil) { - api_set_error(err, kErrorTypeValidation, - "Cannot use both 'pattern' and 'buffer'"); + VALIDATE((!HAS_KEY(opts->pattern) || !HAS_KEY(opts->buffer)), + "%s", "Cannot use both 'pattern' and 'buffer'", { goto cleanup; - } + }); int au_group = get_augroup_from_object(opts->group, err); if (au_group == AUGROUP_ERROR) { @@ -772,32 +744,29 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) break; case kObjectTypeString: au_group = augroup_find(opts->group.data.string.data); - if (au_group == AUGROUP_ERROR) { - api_set_error(err, - kErrorTypeValidation, - "invalid augroup: %s", opts->group.data.string.data); + VALIDATE_S((au_group != AUGROUP_ERROR), "group", opts->group.data.string.data, { goto cleanup; - } + }); break; case kObjectTypeInteger: au_group = (int)opts->group.data.integer; char *name = augroup_name(au_group); - if (!augroup_exists(name)) { - api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group); + VALIDATE_INT(augroup_exists(name), "group", (int64_t)au_group, { goto cleanup; - } + }); break; default: - api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer."); - goto cleanup; + VALIDATE_EXP(false, "group", "String or Integer", api_typename(opts->group.type), { + goto cleanup; + }); } - if (opts->buffer.type != kObjectTypeNil) { + if (HAS_KEY(opts->buffer)) { Object buf_obj = opts->buffer; - if (buf_obj.type != kObjectTypeInteger && buf_obj.type != kObjectTypeBuffer) { - api_set_error(err, kErrorTypeException, "invalid buffer: %d", buf_obj.type); + VALIDATE_EXP((buf_obj.type == kObjectTypeInteger || buf_obj.type == kObjectTypeBuffer), + "buffer", "Integer", api_typename(buf_obj.type), { goto cleanup; - } + }); buf = find_buffer_by_handle((Buffer)buf_obj.data.integer, err); @@ -814,7 +783,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) ADD(patterns, STRING_OBJ(STATIC_CSTR_TO_STRING(""))); } - if (opts->data.type != kObjectTypeNil) { + if (HAS_KEY(opts->data)) { data = &opts->data; } @@ -825,7 +794,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) GET_ONE_EVENT(event_nr, event_str, cleanup) FOREACH_ITEM(patterns, pat, { - char *fname = opts->buffer.type == kObjectTypeNil ? pat.data.string.data : NULL; + char *fname = !HAS_KEY(opts->buffer) ? pat.data.string.data : NULL; did_aucmd |= apply_autocmds_group(event_nr, fname, NULL, true, au_group, buf, NULL, data); }) @@ -840,45 +809,19 @@ cleanup: api_free_array(patterns); } -static bool check_autocmd_string_array(Array arr, char *k, Error *err) -{ - FOREACH_ITEM(arr, entry, { - if (entry.type != kObjectTypeString) { - api_set_error(err, - kErrorTypeValidation, - "All entries in '%s' must be strings", - k); - return false; - } - - // Disallow newlines in the middle of the line. - const String l = entry.data.string; - if (memchr(l.data, NL, l.size)) { - api_set_error(err, kErrorTypeValidation, - "String cannot contain newlines"); - return false; - } - }) - return true; -} - static bool unpack_string_or_array(Array *array, Object *v, char *k, bool required, Error *err) { if (v->type == kObjectTypeString) { ADD(*array, copy_object(*v, NULL)); } else if (v->type == kObjectTypeArray) { - if (!check_autocmd_string_array(v->data.array, k, err)) { + if (!check_string_array(v->data.array, k, true, err)) { return false; } *array = copy_array(v->data.array, NULL); } else { - if (required) { - api_set_error(err, - kErrorTypeValidation, - "'%s' must be an array or a string.", - k); + VALIDATE_EXP(!required, k, "Array or String", api_typename(v->type), { return false; - } + }); } return true; @@ -894,27 +837,22 @@ static int get_augroup_from_object(Object group, Error *err) return AUGROUP_DEFAULT; case kObjectTypeString: au_group = augroup_find(group.data.string.data); - if (au_group == AUGROUP_ERROR) { - api_set_error(err, - kErrorTypeValidation, - "invalid augroup: %s", group.data.string.data); - + VALIDATE_S((au_group != AUGROUP_ERROR), "group", group.data.string.data, { return AUGROUP_ERROR; - } + }); return au_group; case kObjectTypeInteger: au_group = (int)group.data.integer; char *name = augroup_name(au_group); - if (!augroup_exists(name)) { - api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group); + VALIDATE_INT(augroup_exists(name), "group", (int64_t)au_group, { return AUGROUP_ERROR; - } - + }); return au_group; default: - api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer."); - return AUGROUP_ERROR; + VALIDATE_EXP(false, "group", "String or Integer", api_typename(group.type), { + return AUGROUP_ERROR; + }); } } @@ -923,24 +861,25 @@ static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, Ob { const char pattern_buflocal[BUFLOCAL_PAT_LEN]; - if (pattern.type != kObjectTypeNil && buffer.type != kObjectTypeNil) { - api_set_error(err, kErrorTypeValidation, - "cannot pass both: 'pattern' and 'buffer' for the same autocmd"); + VALIDATE((!HAS_KEY(pattern) || !HAS_KEY(buffer)), + "%s", "Cannot use both 'pattern' and 'buffer' for the same autocmd", { return false; - } else if (pattern.type != kObjectTypeNil) { + }); + + if (HAS_KEY(pattern)) { Object *v = &pattern; if (v->type == kObjectTypeString) { char *pat = v->data.string.data; size_t patlen = aucmd_pattern_length(pat); while (patlen) { - ADD(*patterns, STRING_OBJ(cbuf_to_string((char *)pat, patlen))); + ADD(*patterns, STRING_OBJ(cbuf_to_string(pat, patlen))); pat = aucmd_next_pattern(pat, patlen); patlen = aucmd_pattern_length(pat); } } else if (v->type == kObjectTypeArray) { - if (!check_autocmd_string_array(v->data.array, "pattern", err)) { + if (!check_string_array(v->data.array, "pattern", true, err)) { return false; } @@ -949,25 +888,22 @@ static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, Ob char *pat = entry.data.string.data; size_t patlen = aucmd_pattern_length(pat); while (patlen) { - ADD(*patterns, STRING_OBJ(cbuf_to_string((char *)pat, patlen))); + ADD(*patterns, STRING_OBJ(cbuf_to_string(pat, patlen))); pat = aucmd_next_pattern(pat, patlen); patlen = aucmd_pattern_length(pat); } }) } else { - api_set_error(err, - kErrorTypeValidation, - "'pattern' must be a string or table"); - return false; + VALIDATE_EXP(false, "pattern", "String or Table", api_typename(v->type), { + return false; + }); } - } else if (buffer.type != kObjectTypeNil) { - if (buffer.type != kObjectTypeInteger && buffer.type != kObjectTypeBuffer) { - api_set_error(err, - kErrorTypeValidation, - "'buffer' must be an integer"); + } else if (HAS_KEY(buffer)) { + VALIDATE_EXP((buffer.type == kObjectTypeInteger || buffer.type == kObjectTypeBuffer), + "buffer", "Integer", api_typename(buffer.type), { return false; - } + }); buf_T *buf = find_buffer_by_handle((Buffer)buffer.data.integer, err); if (ERROR_SET(err)) { @@ -975,7 +911,7 @@ static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, Ob } snprintf((char *)pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); - ADD(*patterns, STRING_OBJ(cstr_to_string((char *)pattern_buflocal))); + ADD(*patterns, STRING_OBJ(cstr_to_string(pattern_buflocal))); } return true; diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index fe9e6077d6..bbdb66988b 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -16,6 +16,7 @@ #include "nvim/api/buffer.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" @@ -179,11 +180,9 @@ Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer, if (is_lua) { for (size_t j = 0; cbs[j].name; j++) { if (strequal(cbs[j].name, k.data)) { - if (v->type != kObjectTypeLuaRef) { - api_set_error(err, kErrorTypeValidation, - "%s is not a function", cbs[j].name); + VALIDATE_T(cbs[j].name, kObjectTypeLuaRef, v->type, { goto error; - } + }); *(cbs[j].dest) = v->data.luaref; v->data.luaref = LUA_NOREF; key_used = true; @@ -194,26 +193,23 @@ Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer, if (key_used) { continue; } else if (strequal("utf_sizes", k.data)) { - if (v->type != kObjectTypeBoolean) { - api_set_error(err, kErrorTypeValidation, "utf_sizes must be boolean"); + VALIDATE_T("utf_sizes", kObjectTypeBoolean, v->type, { goto error; - } + }); cb.utf_sizes = v->data.boolean; key_used = true; } else if (strequal("preview", k.data)) { - if (v->type != kObjectTypeBoolean) { - api_set_error(err, kErrorTypeValidation, "preview must be boolean"); + VALIDATE_T("preview", kObjectTypeBoolean, v->type, { goto error; - } + }); cb.preview = v->data.boolean; key_used = true; } } - if (!key_used) { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); + VALIDATE_S(key_used, "'opts' key", k.data, { goto error; - } + }); } return buf_updates_register(buf, channel_id, cb, send_buffer); @@ -297,10 +293,9 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, start = normalize_index(buf, start, true, &oob); end = normalize_index(buf, end, true, &oob); - if (strict_indexing && oob) { - api_set_error(err, kErrorTypeValidation, "Index out of bounds"); + VALIDATE((!strict_indexing || !oob), "%s", "Index out of bounds", { return rv; - } + }); if (start >= end) { // Return 0-length array @@ -325,28 +320,6 @@ end: return rv; } -static bool check_string_array(Array arr, bool disallow_nl, Error *err) -{ - for (size_t i = 0; i < arr.size; i++) { - if (arr.items[i].type != kObjectTypeString) { - api_set_error(err, - kErrorTypeValidation, - "All items in the replacement array must be strings"); - return false; - } - // Disallow newlines in the middle of the line. - if (disallow_nl) { - const String l = arr.items[i].data.string; - if (memchr(l.data, NL, l.size)) { - api_set_error(err, kErrorTypeValidation, - "String cannot contain newlines"); - return false; - } - } - } - return true; -} - /// Sets (replaces) a line-range in the buffer. /// /// Indexing is zero-based, end-exclusive. Negative indices are interpreted @@ -383,20 +356,15 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ start = normalize_index(buf, start, true, &oob); end = normalize_index(buf, end, true, &oob); - if (strict_indexing && oob) { - api_set_error(err, kErrorTypeValidation, "Index out of bounds"); + VALIDATE((!strict_indexing || !oob), "%s", "Index out of bounds", { return; - } - - if (start > end) { - api_set_error(err, - kErrorTypeValidation, - "Argument \"start\" is higher than \"end\""); + }); + VALIDATE((start <= end), "%s", "'start' is higher than 'end'", { return; - } + }); bool disallow_nl = (channel_id != VIML_INTERNAL_CALL); - if (!check_string_array(replacement, disallow_nl, err)) { + if (!check_string_array(replacement, "replacement string", disallow_nl, err)) { return; } @@ -453,10 +421,9 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ for (size_t i = 0; i < to_replace; i++) { int64_t lnum = start + (int64_t)i; - if (lnum >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, "Index value is too high"); + VALIDATE(lnum < MAXLNUM, "%s", "Index out of bounds", { goto end; - } + }); if (ml_replace((linenr_T)lnum, lines[i], false) == FAIL) { api_set_error(err, kErrorTypeException, "Failed to replace line"); @@ -473,10 +440,9 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ for (size_t i = to_replace; i < new_len; i++) { int64_t lnum = start + (int64_t)i - 1; - if (lnum >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, "Index value is too high"); + VALIDATE(lnum < MAXLNUM, "%s", "Index out of bounds", { goto end; - } + }); if (ml_append((linenr_T)lnum, lines[i], 0, false) == FAIL) { api_set_error(err, kErrorTypeException, "Failed to insert line"); @@ -563,16 +529,14 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In // check range is ordered and everything! // start_row, end_row within buffer len (except add text past the end?) start_row = normalize_index(buf, start_row, false, &oob); - if (oob) { - api_set_error(err, kErrorTypeValidation, "start_row out of bounds"); + VALIDATE_RANGE((!oob), "start_row", { return; - } + }); end_row = normalize_index(buf, end_row, false, &oob); - if (oob) { - api_set_error(err, kErrorTypeValidation, "end_row out of bounds"); + VALIDATE_RANGE((!oob), "end_row", { return; - } + }); char *str_at_start = NULL; char *str_at_end = NULL; @@ -580,26 +544,24 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In // Another call to ml_get_buf() may free the line, so make a copy. str_at_start = xstrdup(ml_get_buf(buf, (linenr_T)start_row, false)); size_t len_at_start = strlen(str_at_start); - if (start_col < 0 || (size_t)start_col > len_at_start) { - api_set_error(err, kErrorTypeValidation, "start_col out of bounds"); + VALIDATE_RANGE((start_col >= 0 && (size_t)start_col <= len_at_start), "start_col", { goto early_end; - } + }); // Another call to ml_get_buf() may free the line, so make a copy. str_at_end = xstrdup(ml_get_buf(buf, (linenr_T)end_row, false)); size_t len_at_end = strlen(str_at_end); - if (end_col < 0 || (size_t)end_col > len_at_end) { - api_set_error(err, kErrorTypeValidation, "end_col out of bounds"); + VALIDATE_RANGE((end_col >= 0 && (size_t)end_col <= len_at_end), "end_col", { goto early_end; - } + }); - if (start_row > end_row || (end_row == start_row && start_col > end_col)) { - api_set_error(err, kErrorTypeValidation, "start is higher than end"); + VALIDATE((start_row <= end_row && !(end_row == start_row && start_col > end_col)), + "%s", "'start' is higher than 'end'", { goto early_end; - } + }); bool disallow_nl = (channel_id != VIML_INTERNAL_CALL); - if (!check_string_array(replacement, disallow_nl, err)) { + if (!check_string_array(replacement, "replacement string", disallow_nl, err)) { goto early_end; } @@ -702,10 +664,9 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In for (size_t i = 0; i < to_replace; i++) { int64_t lnum = start_row + (int64_t)i; - if (lnum >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, "Index value is too high"); + VALIDATE((lnum < MAXLNUM), "%s", "Index out of bounds", { goto end; - } + }); if (ml_replace((linenr_T)lnum, lines[i], false) == FAIL) { api_set_error(err, kErrorTypeException, "Failed to replace line"); @@ -720,10 +681,9 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In for (size_t i = to_replace; i < new_len; i++) { int64_t lnum = start_row + (int64_t)i - 1; - if (lnum >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, "Index value is too high"); + VALIDATE((lnum < MAXLNUM), "%s", "Index out of bounds", { goto end; - } + }); if (ml_append((linenr_T)lnum, lines[i], 0, false) == FAIL) { api_set_error(err, kErrorTypeException, "Failed to insert line"); @@ -800,10 +760,9 @@ ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer, { Array rv = ARRAY_DICT_INIT; - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); + VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { return rv; - } + }); buf_T *buf = find_buffer_by_handle(buffer, err); @@ -820,18 +779,16 @@ ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer, start_row = normalize_index(buf, start_row, false, &oob); end_row = normalize_index(buf, end_row, false, &oob); - if (oob) { - api_set_error(err, kErrorTypeValidation, "Index out of bounds"); + VALIDATE((!oob), "%s", "Index out of bounds", { return rv; - } + }); // nvim_buf_get_lines doesn't care if the start row is greater than the end // row (it will just return an empty array), but nvim_buf_get_text does in // order to maintain symmetry with nvim_buf_set_text. - if (start_row > end_row) { - api_set_error(err, kErrorTypeValidation, "start is higher than end"); + VALIDATE((start_row <= end_row), "%s", "'start' is higher than 'end'", { return rv; - } + }); bool replace_nl = (channel_id != VIML_INTERNAL_CALL); @@ -907,10 +864,9 @@ Integer nvim_buf_get_offset(Buffer buffer, Integer index, Error *err) return -1; } - if (index < 0 || index > buf->b_ml.ml_line_count) { - api_set_error(err, kErrorTypeValidation, "Index out of bounds"); + VALIDATE((index >= 0 && index <= buf->b_ml.ml_line_count), "%s", "Index out of bounds", { return 0; - } + }); return ml_find_line_or_offset(buf, (int)index + 1, NULL, true); } @@ -1118,8 +1074,9 @@ void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err) } else if (strequal("unload", k.data)) { unload = api_object_to_bool(v, "unload", false, err); } else { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); - return; + VALIDATE_S(false, "'opts' key", k.data, { + return; + }); } } @@ -1174,20 +1131,16 @@ Boolean nvim_buf_del_mark(Buffer buffer, String name, Error *err) return res; } - if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, - "Mark name must be a single character"); + VALIDATE_S((name.size == 1), "mark name (must be a single char)", name.data, { return res; - } + }); fmark_T *fm = mark_get(buf, curwin, NULL, kMarkAllNoResolve, *name.data); // fm is NULL when there's no mark with the given name - if (fm == NULL) { - api_set_error(err, kErrorTypeValidation, "Invalid mark name: '%c'", - *name.data); + VALIDATE_S((fm != NULL), "mark name", name.data, { return res; - } + }); // mark.lnum is 0 when the mark is not valid in the buffer, or is not set. if (fm->mark.lnum != 0 && fm->fnum == buf->handle) { @@ -1224,11 +1177,9 @@ Boolean nvim_buf_set_mark(Buffer buffer, String name, Integer line, Integer col, return res; } - if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, - "Mark name must be a single character"); + VALIDATE_S((name.size == 1), "mark name (must be a single char)", name.data, { return res; - } + }); res = set_mark(buf, name, line, col, err); @@ -1257,21 +1208,18 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) return rv; } - if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, - "Mark name must be a single character"); + VALIDATE_S((name.size == 1), "mark name (must be a single char)", name.data, { return rv; - } + }); fmark_T *fm; pos_T pos; char mark = *name.data; fm = mark_get(buf, curwin, NULL, kMarkAllNoResolve, mark); - if (fm == NULL) { - api_set_error(err, kErrorTypeValidation, "Invalid mark name"); + VALIDATE_S((fm != NULL), "mark name", name.data, { return rv; - } + }); // (0, 0) uppercase/file mark set in another buffer. if (fm->fnum != buf->handle) { pos.lnum = 0; diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index abd265f2cf..81b70b07d0 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -11,6 +11,7 @@ #include "nvim/api/command.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" #include "nvim/buffer_defs.h" @@ -99,10 +100,9 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err) { Dictionary result = ARRAY_DICT_INIT; - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); + VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { return result; - } + }); // Parse command line exarg_T ea; @@ -127,7 +127,7 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err) // otherwise split arguments by whitespace. if (ea.argt & EX_NOSPC) { if (*ea.arg != NUL) { - ADD(args, STRING_OBJ(cstrn_to_string((char *)ea.arg, length))); + ADD(args, STRING_OBJ(cstrn_to_string(ea.arg, length))); } } else { size_t end = 0; @@ -153,9 +153,9 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err) } if (cmd != NULL) { - PUT(result, "cmd", CSTR_TO_OBJ((char *)cmd->uc_name)); + PUT(result, "cmd", CSTR_TO_OBJ(cmd->uc_name)); } else { - PUT(result, "cmd", CSTR_TO_OBJ((char *)get_command_name(NULL, ea.cmdidx))); + PUT(result, "cmd", CSTR_TO_OBJ(get_command_name(NULL, ea.cmdidx))); } if (ea.argt & EX_RANGE) { @@ -237,7 +237,7 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err) break; } PUT(result, "addr", CSTR_TO_OBJ(addr)); - PUT(result, "nextcmd", CSTR_TO_OBJ((char *)ea.nextcmd)); + PUT(result, "nextcmd", CSTR_TO_OBJ(ea.nextcmd)); Dictionary mods = ARRAY_DICT_INIT; @@ -512,7 +512,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error } else if (cmd->count.type != kObjectTypeInteger || cmd->count.data.integer < 0) { VALIDATION_ERROR("'count' must be a non-negative Integer"); } - set_cmd_count(&ea, cmd->count.data.integer, true); + set_cmd_count(&ea, (linenr_T)cmd->count.data.integer, true); } if (HAS_KEY(cmd->reg)) { @@ -998,14 +998,14 @@ void nvim_buf_del_user_command(Buffer buffer, String name, Error *err) } } - api_set_error(err, kErrorTypeException, "No such user-defined command: %s", name.data); + api_set_error(err, kErrorTypeException, "Invalid command (not found): %s", name.data); } void create_user_command(String name, Object command, Dict(user_command) *opts, int flags, Error *err) { uint32_t argt = 0; - long def = -1; + int64_t def = -1; cmd_addr_T addr_type_arg = ADDR_NONE; int compl = EXPAND_NOTHING; char *compl_arg = NULL; @@ -1014,20 +1014,17 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, LuaRef compl_luaref = LUA_NOREF; LuaRef preview_luaref = LUA_NOREF; - if (!uc_validate_name(name.data)) { - api_set_error(err, kErrorTypeValidation, "Invalid command name"); + VALIDATE_S(uc_validate_name(name.data), "command name", name.data, { goto err; - } - - if (mb_islower(name.data[0])) { - api_set_error(err, kErrorTypeValidation, "'name' must begin with an uppercase letter"); + }); + VALIDATE_S(!mb_islower(name.data[0]), "command name (must start with uppercase)", + name.data, { goto err; - } - - if (HAS_KEY(opts->range) && HAS_KEY(opts->count)) { - api_set_error(err, kErrorTypeValidation, "'range' and 'count' are mutually exclusive"); + }); + VALIDATE((!HAS_KEY(opts->range) || !HAS_KEY(opts->count)), "%s", + "Cannot use both 'range' and 'count'", { goto err; - } + }); if (opts->nargs.type == kObjectTypeInteger) { switch (opts->nargs.data.integer) { @@ -1038,14 +1035,14 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, argt |= EX_EXTRA | EX_NOSPC | EX_NEEDARG; break; default: - api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'"); - goto err; + VALIDATE_INT(false, "nargs", (int64_t)opts->nargs.data.integer, { + goto err; + }); } } else if (opts->nargs.type == kObjectTypeString) { - if (opts->nargs.data.string.size > 1) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'"); + VALIDATE_S((opts->nargs.data.string.size <= 1), "nargs", opts->nargs.data.string.data, { goto err; - } + }); switch (opts->nargs.data.string.data[0]) { case '*': @@ -1058,18 +1055,19 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, argt |= EX_EXTRA | EX_NEEDARG; break; default: - api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'"); - goto err; + VALIDATE_S(false, "nargs", opts->nargs.data.string.data, { + goto err; + }); } } else if (HAS_KEY(opts->nargs)) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'"); - goto err; + VALIDATE_S(false, "nargs", "", { + goto err; + }); } - if (HAS_KEY(opts->complete) && !argt) { - api_set_error(err, kErrorTypeValidation, "'complete' used without 'nargs'"); + VALIDATE((!HAS_KEY(opts->complete) || argt), "%s", "'complete' used without 'nargs'", { goto err; - } + }); if (opts->range.type == kObjectTypeBoolean) { if (opts->range.data.boolean) { @@ -1077,20 +1075,20 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, addr_type_arg = ADDR_LINES; } } else if (opts->range.type == kObjectTypeString) { - if (opts->range.data.string.data[0] == '%' && opts->range.data.string.size == 1) { - argt |= EX_RANGE | EX_DFLALL; - addr_type_arg = ADDR_LINES; - } else { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'range'"); + VALIDATE_S((opts->range.data.string.data[0] == '%' && opts->range.data.string.size == 1), + "range", "", { goto err; - } + }); + argt |= EX_RANGE | EX_DFLALL; + addr_type_arg = ADDR_LINES; } else if (opts->range.type == kObjectTypeInteger) { argt |= EX_RANGE | EX_ZEROR; def = opts->range.data.integer; addr_type_arg = ADDR_LINES; } else if (HAS_KEY(opts->range)) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'range'"); - goto err; + VALIDATE_S(false, "range", "", { + goto err; + }); } if (opts->count.type == kObjectTypeBoolean) { @@ -1104,23 +1102,25 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, addr_type_arg = ADDR_OTHER; def = opts->count.data.integer; } else if (HAS_KEY(opts->count)) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'count'"); - goto err; + VALIDATE_S(false, "count", "", { + goto err; + }); } - if (opts->addr.type == kObjectTypeString) { - if (parse_addr_type_arg(opts->addr.data.string.data, (int)opts->addr.data.string.size, - &addr_type_arg) != OK) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'addr'"); + if (HAS_KEY(opts->addr)) { + VALIDATE_T("addr", kObjectTypeString, opts->addr.type, { goto err; - } + }); + + VALIDATE_S(OK == parse_addr_type_arg(opts->addr.data.string.data, + (int)opts->addr.data.string.size, &addr_type_arg), "addr", + opts->addr.data.string.data, { + goto err; + }); if (addr_type_arg != ADDR_LINES) { argt |= EX_ZEROR; } - } else if (HAS_KEY(opts->addr)) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'addr'"); - goto err; } if (api_object_to_bool(opts->bang, "bang", false, err)) { @@ -1156,23 +1156,25 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, compl = EXPAND_USER_LUA; compl_luaref = api_new_luaref(opts->complete.data.luaref); } else if (opts->complete.type == kObjectTypeString) { - if (parse_compl_arg(opts->complete.data.string.data, - (int)opts->complete.data.string.size, &compl, &argt, - &compl_arg) != OK) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'complete'"); + VALIDATE_S(OK == parse_compl_arg(opts->complete.data.string.data, + (int)opts->complete.data.string.size, &compl, &argt, + &compl_arg), + "complete", opts->complete.data.string.data, { goto err; - } + }); } else if (HAS_KEY(opts->complete)) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'complete'"); - goto err; + VALIDATE_EXP(false, "complete", "Function or String", NULL, { + goto err; + }); } - if (opts->preview.type == kObjectTypeLuaRef) { + if (HAS_KEY(opts->preview)) { + VALIDATE_T("preview", kObjectTypeLuaRef, opts->preview.type, { + goto err; + }); + argt |= EX_PREVIEW; preview_luaref = api_new_luaref(opts->preview.data.luaref); - } else if (HAS_KEY(opts->preview)) { - api_set_error(err, kErrorTypeValidation, "Invalid value for 'preview'"); - goto err; } switch (command.type) { @@ -1188,8 +1190,9 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, rep = command.data.string.data; break; default: - api_set_error(err, kErrorTypeValidation, "'command' must be a string or Lua function"); - goto err; + VALIDATE_EXP(false, "command", "Function or String", NULL, { + goto err; + }); } if (uc_add_command(name.data, name.size, rep, argt, def, flags, compl, compl_arg, compl_luaref, diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index ab3b3485e4..91486abf38 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -11,6 +11,7 @@ #include "nvim/api/extmark.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/decoration.h" @@ -218,10 +219,9 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, return rv; } - if (!ns_initialized((uint32_t)ns_id)) { - api_set_error(err, kErrorTypeValidation, "Invalid ns_id"); + VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, { return rv; - } + }); bool details = false; for (size_t i = 0; i < opts.size; i++) { @@ -233,12 +233,14 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, } else if (v->type == kObjectTypeInteger) { details = v->data.integer; } else { - api_set_error(err, kErrorTypeValidation, "details is not an boolean"); - return rv; + VALIDATE_EXP(false, "details", "Boolean or Integer", api_typename(v->type), { + return rv; + }); } } else { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); - return rv; + VALIDATE_S(false, "'opts' key", k.data, { + return rv; + }); } } @@ -301,10 +303,9 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e return rv; } - if (!ns_initialized((uint32_t)ns_id)) { - api_set_error(err, kErrorTypeValidation, "Invalid ns_id"); + VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, { return rv; - } + }); Integer limit = -1; bool details = false; @@ -313,10 +314,9 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e String k = opts.items[i].key; Object *v = &opts.items[i].value; if (strequal("limit", k.data)) { - if (v->type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, "limit is not an integer"); + VALIDATE_T("limit", kObjectTypeInteger, v->type, { return rv; - } + }); limit = v->data.integer; } else if (strequal("details", k.data)) { if (v->type == kObjectTypeBoolean) { @@ -324,12 +324,14 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e } else if (v->type == kObjectTypeInteger) { details = v->data.integer; } else { - api_set_error(err, kErrorTypeValidation, "details is not an boolean"); - return rv; + VALIDATE_EXP(false, "details", "Boolean or Integer", api_typename(v->type), { + return rv; + }); } } else { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); - return rv; + VALIDATE_S(false, "'opts' key", k.data, { + return rv; + }); } } @@ -501,27 +503,27 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer goto error; } - if (!ns_initialized((uint32_t)ns_id)) { - api_set_error(err, kErrorTypeValidation, "Invalid ns_id"); + VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, { goto error; - } + }); uint32_t id = 0; - if (opts->id.type == kObjectTypeInteger && opts->id.data.integer > 0) { + if (HAS_KEY(opts->id)) { + VALIDATE_EXP((opts->id.type == kObjectTypeInteger && opts->id.data.integer > 0), + "id", "positive Integer", NULL, { + goto error; + }); + id = (uint32_t)opts->id.data.integer; - } else if (HAS_KEY(opts->id)) { - api_set_error(err, kErrorTypeValidation, "id is not a positive integer"); - goto error; } int line2 = -1; // For backward compatibility we support "end_line" as an alias for "end_row" if (HAS_KEY(opts->end_line)) { - if (HAS_KEY(opts->end_row)) { - api_set_error(err, kErrorTypeValidation, "cannot use both end_row and end_line"); + VALIDATE(!HAS_KEY(opts->end_row), "%s", "cannot use both 'end_row' and 'end_line'", { goto error; - } + }); opts->end_row = opts->end_line; } @@ -534,31 +536,29 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer bool strict = true; OPTION_TO_BOOL(strict, strict, true); - if (opts->end_row.type == kObjectTypeInteger) { + if (HAS_KEY(opts->end_row)) { + VALIDATE_T("end_row", kObjectTypeInteger, opts->end_row.type, { + goto error; + }); + Integer val = opts->end_row.data.integer; - if (val < 0 || (val > buf->b_ml.ml_line_count && strict)) { - api_set_error(err, kErrorTypeValidation, "end_row value outside range"); + VALIDATE_RANGE((val >= 0 && !(val > buf->b_ml.ml_line_count && strict)), "end_row", { goto error; - } else { - line2 = (int)val; - } - } else if (HAS_KEY(opts->end_row)) { - api_set_error(err, kErrorTypeValidation, "end_row is not an integer"); - goto error; + }); + line2 = (int)val; } colnr_T col2 = -1; - if (opts->end_col.type == kObjectTypeInteger) { + if (HAS_KEY(opts->end_col)) { + VALIDATE_T("end_col", kObjectTypeInteger, opts->end_col.type, { + goto error; + }); + Integer val = opts->end_col.data.integer; - if (val < 0 || val > MAXCOL) { - api_set_error(err, kErrorTypeValidation, "end_col value outside range"); + VALIDATE_RANGE((val >= 0 && val <= MAXCOL), "end_col", { goto error; - } else { - col2 = (int)val; - } - } else if (HAS_KEY(opts->end_col)) { - api_set_error(err, kErrorTypeValidation, "end_col is not an integer"); - goto error; + }); + col2 = (int)val; } // uncrustify:off @@ -588,31 +588,37 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } } - if (opts->conceal.type == kObjectTypeString) { + if (HAS_KEY(opts->conceal)) { + VALIDATE_T("conceal", kObjectTypeString, opts->conceal.type, { + goto error; + }); + String c = opts->conceal.data.string; decor.conceal = true; if (c.size) { decor.conceal_char = utf_ptr2char(c.data); } has_decor = true; - } else if (HAS_KEY(opts->conceal)) { - api_set_error(err, kErrorTypeValidation, "conceal is not a String"); - goto error; } - if (opts->virt_text.type == kObjectTypeArray) { + if (HAS_KEY(opts->virt_text)) { + VALIDATE_T("virt_text", kObjectTypeArray, opts->virt_text.type, { + goto error; + }); + decor.virt_text = parse_virt_text(opts->virt_text.data.array, err, &decor.virt_text_width); has_decor = true; if (ERROR_SET(err)) { goto error; } - } else if (HAS_KEY(opts->virt_text)) { - api_set_error(err, kErrorTypeValidation, "virt_text is not an Array"); - goto error; } - if (opts->virt_text_pos.type == kObjectTypeString) { + if (HAS_KEY(opts->virt_text_pos)) { + VALIDATE_T("virt_text_pos", kObjectTypeString, opts->virt_text_pos.type, { + goto error; + }); + String str = opts->virt_text_pos.data.string; if (strequal("eol", str.data)) { decor.virt_text_pos = kVTEndOfLine; @@ -621,21 +627,19 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } else if (strequal("right_align", str.data)) { decor.virt_text_pos = kVTRightAlign; } else { - api_set_error(err, kErrorTypeValidation, "virt_text_pos: invalid value"); - goto error; + VALIDATE_S(false, "virt_text_pos", "", { + goto error; + }); } - } else if (HAS_KEY(opts->virt_text_pos)) { - api_set_error(err, kErrorTypeValidation, "virt_text_pos is not a String"); - goto error; } - if (opts->virt_text_win_col.type == kObjectTypeInteger) { + if (HAS_KEY(opts->virt_text_win_col)) { + VALIDATE_T("virt_text_win_col", kObjectTypeInteger, opts->virt_text_win_col.type, { + goto error; + }); + decor.col = (int)opts->virt_text_win_col.data.integer; decor.virt_text_pos = kVTWinCol; - } else if (HAS_KEY(opts->virt_text_win_col)) { - api_set_error(err, kErrorTypeValidation, - "virt_text_win_col is not a Number of the correct size"); - goto error; } OPTION_TO_BOOL(decor.virt_text_hide, virt_text_hide, false); @@ -650,25 +654,29 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } else if (strequal("blend", str.data)) { decor.hl_mode = kHlModeBlend; } else { - api_set_error(err, kErrorTypeValidation, - "virt_text_pos: invalid value"); - goto error; + VALIDATE_S(false, "virt_text_pos", "", { + goto error; + }); } } else if (HAS_KEY(opts->hl_mode)) { - api_set_error(err, kErrorTypeValidation, "hl_mode is not a String"); - goto error; + VALIDATE_T("hl_mode", kObjectTypeString, opts->hl_mode.type, { + goto error; + }); } bool virt_lines_leftcol = false; OPTION_TO_BOOL(virt_lines_leftcol, virt_lines_leftcol, false); - if (opts->virt_lines.type == kObjectTypeArray) { + if (HAS_KEY(opts->virt_lines)) { + VALIDATE_T("virt_lines", kObjectTypeArray, opts->virt_lines.type, { + goto error; + }); + Array a = opts->virt_lines.data.array; for (size_t j = 0; j < a.size; j++) { - if (a.items[j].type != kObjectTypeArray) { - api_set_error(err, kErrorTypeValidation, "virt_text_line item is not an Array"); + VALIDATE_T("virt_text_line", kObjectTypeArray, a.items[j].type, { goto error; - } + }); int dummig; VirtText jtem = parse_virt_text(a.items[j].data.array, err, &dummig); kv_push(decor.virt_lines, ((struct virt_line){ jtem, virt_lines_leftcol })); @@ -677,36 +685,33 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } has_decor = true; } - } else if (HAS_KEY(opts->virt_lines)) { - api_set_error(err, kErrorTypeValidation, "virt_lines is not an Array"); - goto error; } OPTION_TO_BOOL(decor.virt_lines_above, virt_lines_above, false); - if (opts->priority.type == kObjectTypeInteger) { + if (HAS_KEY(opts->priority)) { + VALIDATE_T("priority", kObjectTypeInteger, opts->priority.type, { + goto error; + }); + Integer val = opts->priority.data.integer; - if (val < 0 || val > UINT16_MAX) { - api_set_error(err, kErrorTypeValidation, "priority is not a valid value"); + VALIDATE_RANGE((val >= 0 && val <= UINT16_MAX), "priority", { goto error; - } + }); decor.priority = (DecorPriority)val; - } else if (HAS_KEY(opts->priority)) { - api_set_error(err, kErrorTypeValidation, "priority is not a Number of the correct size"); - goto error; } - if (opts->sign_text.type == kObjectTypeString) { - if (!init_sign_text(&decor.sign_text, - opts->sign_text.data.string.data)) { - api_set_error(err, kErrorTypeValidation, "sign_text is not a valid value"); + if (HAS_KEY(opts->sign_text)) { + VALIDATE_T("sign_text", kObjectTypeString, opts->sign_text.type, { goto error; - } + }); + + VALIDATE_S(init_sign_text(&decor.sign_text, opts->sign_text.data.string.data), + "sign_text", "", { + goto error; + }); has_decor = true; - } else if (HAS_KEY(opts->sign_text)) { - api_set_error(err, kErrorTypeValidation, "sign_text is not a String"); - goto error; } bool right_gravity = true; @@ -714,11 +719,10 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer // Only error out if they try to set end_right_gravity without // setting end_col or end_row - if (line2 == -1 && col2 == -1 && HAS_KEY(opts->end_right_gravity)) { - api_set_error(err, kErrorTypeValidation, - "cannot set end_right_gravity without setting end_row or end_col"); + VALIDATE(!(line2 == -1 && col2 == -1 && HAS_KEY(opts->end_right_gravity)), + "%s", "cannot set end_right_gravity without end_row or end_col", { goto error; - } + }); bool end_right_gravity = false; OPTION_TO_BOOL(end_right_gravity, end_right_gravity, false); @@ -728,7 +732,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer bool ephemeral = false; OPTION_TO_BOOL(ephemeral, ephemeral, false); - if (opts->spell.type == kObjectTypeNil) { + if (!HAS_KEY(opts->spell)) { decor.spell = kNone; } else { bool spell = false; @@ -742,16 +746,15 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer has_decor = true; } - if (line < 0) { - api_set_error(err, kErrorTypeValidation, "line value outside range"); + VALIDATE_RANGE((line >= 0), "line", { goto error; - } else if (line > buf->b_ml.ml_line_count) { - if (strict) { - api_set_error(err, kErrorTypeValidation, "line value outside range"); + }); + + if (line > buf->b_ml.ml_line_count) { + VALIDATE_RANGE(!strict, "line", { goto error; - } else { - line = buf->b_ml.ml_line_count; - } + }); + line = buf->b_ml.ml_line_count; } else if (line < buf->b_ml.ml_line_count) { len = ephemeral ? MAXCOL : strlen(ml_get_buf(buf, (linenr_T)line + 1, false)); } @@ -759,15 +762,14 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer if (col == -1) { col = (Integer)len; } else if (col > (Integer)len) { - if (strict) { - api_set_error(err, kErrorTypeValidation, "col value outside range"); + VALIDATE_RANGE(!strict, "col", { goto error; - } else { - col = (Integer)len; - } + }); + col = (Integer)len; } else if (col < -1) { - api_set_error(err, kErrorTypeValidation, "col value outside range"); - goto error; + VALIDATE_RANGE(false, "col", { + goto error; + }); } if (col2 >= 0) { @@ -781,12 +783,10 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer line2 = (int)line; } if (col2 > (Integer)len) { - if (strict) { - api_set_error(err, kErrorTypeValidation, "end_col value outside range"); + VALIDATE_RANGE(!strict, "end_col", { goto error; - } else { - col2 = (int)len; - } + }); + col2 = (int)len; } } else if (line2 >= 0) { col2 = 0; @@ -829,10 +829,9 @@ Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *er if (!buf) { return false; } - if (!ns_initialized((uint32_t)ns_id)) { - api_set_error(err, kErrorTypeValidation, "Invalid ns_id"); + VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, { return false; - } + }); return extmark_del(buf, (uint32_t)ns_id, (uint32_t)id); } @@ -887,14 +886,13 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In return 0; } - if (line < 0 || line >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, "Line number outside range"); + VALIDATE_RANGE((line >= 0 && line < MAXLNUM), "line number", { return 0; - } - if (col_start < 0 || col_start > MAXCOL) { - api_set_error(err, kErrorTypeValidation, "Column value outside range"); + }); + VALIDATE_RANGE((col_start >= 0 && col_start <= MAXCOL), "column", { return 0; - } + }); + if (col_end < 0 || col_end > MAXCOL) { col_end = MAXCOL; } @@ -950,10 +948,10 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, return; } - if (line_start < 0 || line_start >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, "Line number outside range"); + VALIDATE_RANGE((line_start >= 0 && line_start < MAXLNUM), "line number", { return; - } + }); + if (line_end < 0 || line_end > MAXLNUM) { line_end = MAXLNUM; } @@ -1034,11 +1032,10 @@ void nvim_set_decoration_provider(Integer ns_id, Dict(set_decoration_provider) * continue; } - if (v->type != kObjectTypeLuaRef) { - api_set_error(err, kErrorTypeValidation, - "%s is not a function", cbs[i].name); + VALIDATE_T(cbs[i].name, kObjectTypeLuaRef, v->type, { goto error; - } + }); + *(cbs[i].dest) = v->data.luaref; v->data.luaref = LUA_NOREF; } @@ -1075,39 +1072,39 @@ static bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, in *col = MAXCOL; return true; } else if (id < 0) { - api_set_error(err, kErrorTypeValidation, "Mark id must be positive"); - return false; + VALIDATE_INT(false, "mark id", id, { + return false; + }); } ExtmarkInfo extmark = extmark_from_id(buf, (uint32_t)ns_id, (uint32_t)id); - if (extmark.row >= 0) { - *row = extmark.row; - *col = extmark.col; - return true; - } else { - api_set_error(err, kErrorTypeValidation, "No mark with requested id"); + + VALIDATE_INT((extmark.row >= 0), "mark id (not found)", id, { return false; - } + }); + *row = extmark.row; + *col = extmark.col; + return true; // Check if it is a position } else if (obj.type == kObjectTypeArray) { Array pos = obj.data.array; - if (pos.size != 2 - || pos.items[0].type != kObjectTypeInteger - || pos.items[1].type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, - "Position must have 2 integer elements"); + VALIDATE_EXP((pos.size == 2 + && pos.items[0].type == kObjectTypeInteger + && pos.items[1].type == kObjectTypeInteger), + "mark position", "2 Integer items", NULL, { return false; - } + }); + Integer pos_row = pos.items[0].data.integer; Integer pos_col = pos.items[1].data.integer; *row = (int)(pos_row >= 0 ? pos_row : MAXLNUM); *col = (colnr_T)(pos_col >= 0 ? pos_col : MAXCOL); return true; } else { - api_set_error(err, kErrorTypeValidation, - "Position must be a mark id Integer or position Array"); - return false; + VALIDATE_EXP(false, "mark position", "mark id Integer or 2-item Array", NULL, { + return false; + }); } } // adapted from sign.c:sign_define_init_text. @@ -1151,17 +1148,14 @@ VirtText parse_virt_text(Array chunks, Error *err, int *width) VirtText virt_text = KV_INITIAL_VALUE; int w = 0; for (size_t i = 0; i < chunks.size; i++) { - if (chunks.items[i].type != kObjectTypeArray) { - api_set_error(err, kErrorTypeValidation, "Chunk is not an array"); + VALIDATE_T("chunk", kObjectTypeArray, chunks.items[i].type, { goto free_exit; - } + }); Array chunk = chunks.items[i].data.array; - if (chunk.size == 0 || chunk.size > 2 - || chunk.items[0].type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "Chunk is not an array with one or two strings"); + VALIDATE((chunk.size > 0 && chunk.size <= 2 && chunk.items[0].type == kObjectTypeString), + "%s", "Invalid chunk: expected Array with 1 or 2 Strings", { goto free_exit; - } + }); String str = chunk.items[0].data.string; diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index bfcb99754f..ddaed3a254 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -9,6 +9,7 @@ #include "nvim/api/options.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/autocmd.h" #include "nvim/buffer_defs.h" #include "nvim/eval/window.h" @@ -25,54 +26,56 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_type, void **from, Error *err) { - if (opts->scope.type == kObjectTypeString) { + if (HAS_KEY(opts->scope)) { + VALIDATE_T("scope", kObjectTypeString, opts->scope.type, { + return FAIL; + }); + if (!strcmp(opts->scope.data.string.data, "local")) { *scope = OPT_LOCAL; } else if (!strcmp(opts->scope.data.string.data, "global")) { *scope = OPT_GLOBAL; } else { - api_set_error(err, kErrorTypeValidation, "invalid scope: must be 'local' or 'global'"); - return FAIL; + VALIDATE_EXP(false, "scope", "'local' or 'global'", NULL, { + return FAIL; + }); } - } else if (HAS_KEY(opts->scope)) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: scope"); - return FAIL; } *opt_type = SREQ_GLOBAL; - if (opts->win.type == kObjectTypeInteger) { + if (HAS_KEY(opts->win)) { + VALIDATE_T("win", kObjectTypeInteger, opts->win.type, { + return FAIL; + }); + *opt_type = SREQ_WIN; *from = find_window_by_handle((int)opts->win.data.integer, err); if (ERROR_SET(err)) { return FAIL; } - } else if (HAS_KEY(opts->win)) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: win"); - return FAIL; } - if (opts->buf.type == kObjectTypeInteger) { + if (HAS_KEY(opts->buf)) { + VALIDATE_T("buf", kObjectTypeInteger, opts->buf.type, { + return FAIL; + }); + *scope = OPT_LOCAL; *opt_type = SREQ_BUF; *from = find_buffer_by_handle((int)opts->buf.data.integer, err); if (ERROR_SET(err)) { return FAIL; } - } else if (HAS_KEY(opts->buf)) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: buf"); - return FAIL; } - if (HAS_KEY(opts->scope) && HAS_KEY(opts->buf)) { - api_set_error(err, kErrorTypeValidation, "scope and buf cannot be used together"); + VALIDATE((!HAS_KEY(opts->scope) || !HAS_KEY(opts->buf)), "%s", + "cannot use both 'scope' and 'buf'", { return FAIL; - } - - if (HAS_KEY(opts->win) && HAS_KEY(opts->buf)) { - api_set_error(err, kErrorTypeValidation, "buf and win cannot be used together"); + }); + VALIDATE((!HAS_KEY(opts->win) || !HAS_KEY(opts->buf)), "%s", "cannot use both 'buf' and 'win'", { return FAIL; - } + }); return OK; } @@ -132,8 +135,9 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) } break; default: - api_set_error(err, kErrorTypeValidation, "unknown option '%s'", name.data); - return rv; + VALIDATE_S(false, "option", name.data, { + return rv; + }); } return rv; @@ -181,7 +185,7 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error switch (value.type) { case kObjectTypeInteger: - numval = value.data.integer; + numval = (long)value.data.integer; break; case kObjectTypeBoolean: numval = value.data.boolean ? 1 : 0; @@ -193,8 +197,9 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error scope |= OPT_CLEAR; break; default: - api_set_error(err, kErrorTypeValidation, "invalid value for option"); - return; + VALIDATE_EXP(false, name.data, "Integer/Boolean/String", api_typename(value.type), { + return; + }); } access_option_value_for(name.data, &numval, &stringval, scope, opt_type, to, false, err); @@ -351,21 +356,18 @@ static Object get_option_from(void *from, int type, String name, Error *err) { Object rv = OBJECT_INIT; - if (name.size == 0) { - api_set_error(err, kErrorTypeValidation, "Empty option name"); + VALIDATE_S(name.size > 0, "option name", "<empty>", { return rv; - } + }); // Return values int64_t numval; char *stringval = NULL; - int flags = get_option_value_strict(name.data, &numval, &stringval, type, from); - if (!flags) { - api_set_error(err, kErrorTypeValidation, "Invalid option name: '%s'", - name.data); + int flags = get_option_value_strict(name.data, &numval, &stringval, type, from); + VALIDATE_S(flags != 0, "option name", name.data, { return rv; - } + }); if (flags & SOPT_BOOL) { rv.type = kObjectTypeBoolean; @@ -374,20 +376,15 @@ static Object get_option_from(void *from, int type, String name, Error *err) rv.type = kObjectTypeInteger; rv.data.integer = numval; } else if (flags & SOPT_STRING) { - if (stringval) { - rv.type = kObjectTypeString; - rv.data.string.data = stringval; - rv.data.string.size = strlen(stringval); - } else { - api_set_error(err, kErrorTypeException, - "Failed to get value for option '%s'", - name.data); + if (!stringval) { + api_set_error(err, kErrorTypeException, "Failed to get option '%s'", name.data); + return rv; } + rv.type = kObjectTypeString; + rv.data.string.data = stringval; + rv.data.string.size = strlen(stringval); } else { - api_set_error(err, - kErrorTypeException, - "Unknown type for option '%s'", - name.data); + api_set_error(err, kErrorTypeException, "Unknown type for option '%s'", name.data); } return rv; @@ -402,29 +399,22 @@ static Object get_option_from(void *from, int type, String name, Error *err) /// @param[out] err Details of an error that may have occurred void set_option_to(uint64_t channel_id, void *to, int type, String name, Object value, Error *err) { - if (name.size == 0) { - api_set_error(err, kErrorTypeValidation, "Empty option name"); + VALIDATE_S(name.size > 0, "option name", "<empty>", { return; - } + }); int flags = get_option_value_strict(name.data, NULL, NULL, type, to); - - if (flags == 0) { - api_set_error(err, kErrorTypeValidation, "Invalid option name '%s'", - name.data); + VALIDATE_S(flags != 0, "option name", name.data, { return; - } + }); if (value.type == kObjectTypeNil) { if (type == SREQ_GLOBAL) { - api_set_error(err, kErrorTypeException, "Cannot unset option '%s'", - name.data); + api_set_error(err, kErrorTypeException, "Cannot unset option '%s'", name.data); return; } else if (!(flags & SOPT_GLOBAL)) { - api_set_error(err, - kErrorTypeException, - "Cannot unset option '%s' " - "because it doesn't have a global value", + api_set_error(err, kErrorTypeException, + "Cannot unset option '%s' because it doesn't have a global value", name.data); return; } else { @@ -437,39 +427,23 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object char *stringval = NULL; if (flags & SOPT_BOOL) { - if (value.type != kObjectTypeBoolean) { - api_set_error(err, - kErrorTypeValidation, - "Option '%s' requires a Boolean value", - name.data); + VALIDATE(value.type == kObjectTypeBoolean, "Option '%s' value must be Boolean", name.data, { return; - } - + }); numval = value.data.boolean; } else if (flags & SOPT_NUM) { - if (value.type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, - "Option '%s' requires an integer value", - name.data); + VALIDATE(value.type == kObjectTypeInteger, "Option '%s' value must be Integer", name.data, { return; - } - - if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) { - api_set_error(err, kErrorTypeValidation, - "Value for option '%s' is out of range", - name.data); + }); + VALIDATE((value.data.integer <= INT_MAX && value.data.integer >= INT_MIN), + "Option '%s' value is out of range", name.data, { return; - } - + }); numval = (int)value.data.integer; } else { - if (value.type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "Option '%s' requires a string value", - name.data); + VALIDATE(value.type == kObjectTypeString, "Option '%s' value must be String", name.data, { return; - } - + }); stringval = value.data.string.data; } diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 519f2cc5bf..c996e19eb9 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -821,12 +821,41 @@ int object_to_hl_id(Object obj, const char *what, Error *err) } else if (obj.type == kObjectTypeInteger) { return MAX((int)obj.data.integer, 0); } else { - api_set_error(err, kErrorTypeValidation, - "%s is not a valid highlight", what); + api_set_error(err, kErrorTypeValidation, "Invalid highlight: %s", what); return 0; } } +char *api_typename(ObjectType t) +{ + switch (t) { + case kObjectTypeNil: + return "nil"; + case kObjectTypeBoolean: + return "Boolean"; + case kObjectTypeInteger: + return "Integer"; + case kObjectTypeFloat: + return "Float"; + case kObjectTypeString: + return "String"; + case kObjectTypeArray: + return "Array"; + case kObjectTypeDictionary: + return "Dict"; + case kObjectTypeLuaRef: + return "Function"; + case kObjectTypeBuffer: + return "Buffer"; + case kObjectTypeWindow: + return "Window"; + case kObjectTypeTabpage: + return "Tabpage"; + default: + abort(); + } +} + HlMessage parse_hl_msg(Array chunks, Error *err) { HlMessage hl_msg = KV_INITIAL_VALUE; diff --git a/src/nvim/api/private/validate.c b/src/nvim/api/private/validate.c new file mode 100644 index 0000000000..c4dd5bcac8 --- /dev/null +++ b/src/nvim/api/private/validate.c @@ -0,0 +1,77 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/private/validate.c.generated.h" +#endif + +/// Creates "Invalid …" message and sets it on `err`. +void api_err_invalid(Error *err, const char *name, const char *val_s, int64_t val_n, bool quote_val) +{ + ErrorType errtype = kErrorTypeValidation; + // Treat `name` without whitespace as a parameter (surround in quotes). + // Treat `name` with whitespace as a description (no quotes). + char *has_space = strchr(name, ' '); + + // No value. + if (val_s && val_s[0] == '\0') { + api_set_error(err, errtype, has_space ? "Invalid %s" : "Invalid '%s'", name); + return; + } + + // Number value. + if (val_s == NULL) { + api_set_error(err, errtype, has_space ? "Invalid %s: %" PRId64 : "Invalid '%s': %" PRId64, + name, val_n); + return; + } + + // String value. + if (has_space) { + api_set_error(err, errtype, quote_val ? "Invalid %s: '%s'" : "Invalid %s: %s", name, val_s); + } else { + api_set_error(err, errtype, quote_val ? "Invalid '%s': '%s'" : "Invalid '%s': %s", name, val_s); + } +} + +/// Creates "Invalid …: expected …" message and sets it on `err`. +void api_err_exp(Error *err, const char *name, const char *expected, const char *actual) +{ + ErrorType errtype = kErrorTypeValidation; + // Treat `name` without whitespace as a parameter (surround in quotes). + // Treat `name` with whitespace as a description (no quotes). + char *has_space = strchr(name, ' '); + + if (!actual) { + api_set_error(err, errtype, + has_space ? "Invalid %s: expected %s" : "Invalid '%s': expected %s", + name, expected); + return; + } + + api_set_error(err, errtype, + has_space ? "Invalid %s: expected %s, got %s" : "Invalid '%s': expected %s, got %s", + name, expected, actual); +} + +bool check_string_array(Array arr, char *name, bool disallow_nl, Error *err) +{ + snprintf(IObuff, sizeof(IObuff), "'%s' item", name); + for (size_t i = 0; i < arr.size; i++) { + VALIDATE_T(IObuff, kObjectTypeString, arr.items[i].type, { + return false; + }); + // Disallow newlines in the middle of the line. + if (disallow_nl) { + const String l = arr.items[i].data.string; + VALIDATE(!memchr(l.data, NL, l.size), "'%s' item contains newlines", name, { + return false; + }); + } + } + return true; +} diff --git a/src/nvim/api/private/validate.h b/src/nvim/api/private/validate.h new file mode 100644 index 0000000000..469fed0f83 --- /dev/null +++ b/src/nvim/api/private/validate.h @@ -0,0 +1,62 @@ +#ifndef NVIM_API_PRIVATE_VALIDATE_H +#define NVIM_API_PRIVATE_VALIDATE_H + +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" + +#define VALIDATE(cond, fmt_, fmt_arg1, code) \ + do { \ + if (!(cond)) { \ + api_set_error(err, kErrorTypeValidation, fmt_, fmt_arg1); \ + code; \ + } \ + } while (0) + +#define VALIDATE_INT(cond, name, val_, code) \ + do { \ + if (!(cond)) { \ + api_err_invalid(err, name, NULL, val_, false); \ + code; \ + } \ + } while (0) + +#define VALIDATE_S(cond, name, val_, code) \ + do { \ + if (!(cond)) { \ + api_err_invalid(err, name, val_, 0, true); \ + code; \ + } \ + } while (0) + +#define VALIDATE_EXP(cond, name, expected, actual, code) \ + do { \ + if (!(cond)) { \ + api_err_exp(err, name, expected, actual); \ + code; \ + } \ + } while (0) + +#define VALIDATE_T(name, expected_t, actual_t, code) \ + do { \ + if (expected_t != actual_t) { \ + api_err_exp(err, name, api_typename(expected_t), api_typename(actual_t)); \ + code; \ + } \ + } while (0) + +#define VALIDATE_RANGE(cond, name, code) \ + do { \ + if (!(cond)) { \ + api_err_invalid(err, name, "out of range", 0, false); \ + code; \ + } \ + } while (0) + +#define VALIDATE_R(cond, name, code) \ + VALIDATE(cond, "Required: '%s'", name, code); + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/private/validate.h.generated.h" +#endif + +#endif // NVIM_API_PRIVATE_VALIDATE_H diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 3ad625234c..61f2c881b3 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -12,6 +12,7 @@ #include "klib/kvec.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/api/ui.h" #include "nvim/autocmd.h" #include "nvim/channel.h" @@ -291,22 +292,20 @@ void nvim_ui_set_option(uint64_t channel_id, String name, Object value, Error *e ui_set_option(ui, false, name, value, error); } -static void ui_set_option(UI *ui, bool init, String name, Object value, Error *error) +static void ui_set_option(UI *ui, bool init, String name, Object value, Error *err) { if (strequal(name.data, "override")) { - if (value.type != kObjectTypeBoolean) { - api_set_error(error, kErrorTypeValidation, "override must be a Boolean"); + VALIDATE_T("override", kObjectTypeBoolean, value.type, { return; - } + }); ui->override = value.data.boolean; return; } if (strequal(name.data, "rgb")) { - if (value.type != kObjectTypeBoolean) { - api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean"); + VALIDATE_T("rgb", kObjectTypeBoolean, value.type, { return; - } + }); ui->rgb = value.data.boolean; // A little drastic, but only takes effect for legacy uis. For linegrid UI // only changes metadata for nvim_list_uis(), no refresh needed. @@ -317,62 +316,56 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, Error *e } if (strequal(name.data, "term_name")) { - if (value.type != kObjectTypeString) { - api_set_error(error, kErrorTypeValidation, "term_name must be a String"); + VALIDATE_T("term_name", kObjectTypeString, value.type, { return; - } + }); set_tty_option("term", string_to_cstr(value.data.string)); return; } if (strequal(name.data, "term_colors")) { - if (value.type != kObjectTypeInteger) { - api_set_error(error, kErrorTypeValidation, "term_colors must be a Integer"); + VALIDATE_T("term_colors", kObjectTypeInteger, value.type, { return; - } + }); t_colors = (int)value.data.integer; return; } if (strequal(name.data, "term_background")) { - if (value.type != kObjectTypeString) { - api_set_error(error, kErrorTypeValidation, "term_background must be a String"); + VALIDATE_T("term_background", kObjectTypeString, value.type, { return; - } + }); set_tty_background(value.data.string.data); return; } if (strequal(name.data, "stdin_fd")) { - if (value.type != kObjectTypeInteger || value.data.integer < 0) { - api_set_error(error, kErrorTypeValidation, "stdin_fd must be a non-negative Integer"); + VALIDATE_T("stdin_fd", kObjectTypeInteger, value.type, { return; - } - - if (starting != NO_SCREEN) { - api_set_error(error, kErrorTypeValidation, - "stdin_fd can only be used with first attached ui"); + }); + VALIDATE_INT((value.data.integer >= 0), "stdin_fd", value.data.integer, { return; - } + }); + VALIDATE((starting == NO_SCREEN), "%s", "stdin_fd can only be used with first attached UI", { + return; + }); stdin_fd = (int)value.data.integer; return; } if (strequal(name.data, "stdin_tty")) { - if (value.type != kObjectTypeBoolean) { - api_set_error(error, kErrorTypeValidation, "stdin_tty must be a Boolean"); + VALIDATE_T("stdin_tty", kObjectTypeBoolean, value.type, { return; - } + }); stdin_isatty = value.data.boolean; return; } if (strequal(name.data, "stdout_tty")) { - if (value.type != kObjectTypeBoolean) { - api_set_error(error, kErrorTypeValidation, "stdout_tty must be a Boolean"); + VALIDATE_T("stdout_tty", kObjectTypeBoolean, value.type, { return; - } + }); stdout_isatty = value.data.boolean; return; } @@ -383,17 +376,15 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, Error *e for (UIExtension i = 0; i < kUIExtCount; i++) { if (strequal(name.data, ui_ext_names[i]) || (i == kUIPopupmenu && is_popupmenu)) { - if (value.type != kObjectTypeBoolean) { - api_set_error(error, kErrorTypeValidation, "%s must be a Boolean", - name.data); + VALIDATE_EXP((value.type == kObjectTypeBoolean), name.data, "Boolean", + api_typename(value.type), { return; - } + }); bool boolval = value.data.boolean; if (!init && i == kUILinegrid && boolval != ui->ui_ext[i]) { // There shouldn't be a reason for an UI to do this ever // so explicitly don't support this. - api_set_error(error, kErrorTypeValidation, - "ext_linegrid option cannot be changed"); + api_set_error(err, kErrorTypeValidation, "ext_linegrid option cannot be changed"); } ui->ui_ext[i] = boolval; if (!init) { @@ -403,8 +394,7 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, Error *e } } - api_set_error(error, kErrorTypeValidation, "No such UI option: %s", - name.data); + api_set_error(err, kErrorTypeValidation, "No such UI option: %s", name.data); } /// Tell Nvim to resize a grid. Triggers a grid_resize event with the requested @@ -645,6 +635,8 @@ void remote_ui_grid_resize(UI *ui, Integer grid, Integer width, Integer height) Array args = data->call_buf; if (ui->ui_ext[kUILinegrid]) { ADD_C(args, INTEGER_OBJ(grid)); + } else { + data->client_col = -1; // force cursor update } ADD_C(args, INTEGER_OBJ(width)); ADD_C(args, INTEGER_OBJ(height)); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a53b30dd8a..3a93005841 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -18,6 +18,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/api/vim.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" @@ -86,10 +87,9 @@ Dictionary nvim_get_hl_by_name(String name, Boolean rgb, Arena *arena, Error *er Dictionary result = ARRAY_DICT_INIT; int id = syn_name2id(name.data); - if (id == 0) { - api_set_error(err, kErrorTypeException, "Invalid highlight name: %s", name.data); + VALIDATE_S((id != 0), "highlight name", name.data, { return result; - } + }); return nvim_get_hl_by_id(id, rgb, arena, err); } @@ -103,10 +103,9 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Arena *arena, Error *er FUNC_API_SINCE(3) { Dictionary dic = ARRAY_DICT_INIT; - if (syn_get_final_id((int)hl_id) == 0) { - api_set_error(err, kErrorTypeException, "Invalid highlight id: %" PRId64, hl_id); + VALIDATE_INT((syn_get_final_id((int)hl_id) != 0), "highlight id", hl_id, { return dic; - } + }); int attrcode = syn_id2attr((int)hl_id); return hl_get_attr_by_id(attrcode, rgb, arena, err); } @@ -173,10 +172,9 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err) FUNC_API_SINCE(7) { int hl_id = syn_check_group(name.data, name.size); - if (hl_id == 0) { - api_set_error(err, kErrorTypeException, "Invalid highlight name: %s", name.data); + VALIDATE_S((hl_id != 0), "highlight name", name.data, { return; - } + }); int link_id = -1; HlAttrs attrs = dict2hlattrs(val, true, &link_id, err); @@ -193,10 +191,9 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err) void nvim_set_hl_ns(Integer ns_id, Error *err) FUNC_API_SINCE(10) { - if (ns_id < 0) { - api_set_error(err, kErrorTypeValidation, "no such namespace"); + VALIDATE_INT((ns_id >= 0), "namespace", ns_id, { return; - } + }); ns_hl_global = (NS)ns_id; hl_check_ns(); @@ -403,11 +400,9 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri continue; } int mod = name_to_mod_mask(byte); - if (mod == 0) { - api_set_error(err, kErrorTypeValidation, - "invalid modifier %c", byte); + VALIDATE((mod != 0), "Invalid modifier: %c", byte, { return; - } + }); modmask |= mod; } @@ -500,10 +495,9 @@ Object nvim_notify(String msg, Integer log_level, Dictionary opts, Error *err) Integer nvim_strwidth(String text, Error *err) FUNC_API_SINCE(1) { - if (text.size > INT_MAX) { - api_set_error(err, kErrorTypeValidation, "String is too long"); + VALIDATE_S((text.size <= INT_MAX), "text length", "(too long)", { return 0; - } + }); return (Integer)mb_string2cells(text.data); } @@ -554,7 +548,7 @@ static void find_runtime_cb(char *fname, void *cookie) { Array *rv = (Array *)cookie; if (fname != NULL) { - ADD(*rv, STRING_OBJ(cstr_to_string((char *)fname))); + ADD(*rv, STRING_OBJ(cstr_to_string(fname))); } } @@ -575,10 +569,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E { bool is_lua = api_object_to_bool(opts->is_lua, "is_lua", false, err); bool source = api_object_to_bool(opts->do_source, "do_source", false, err); - if (source && !nlua_is_deferred_safe()) { - api_set_error(err, kErrorTypeValidation, "'do_source' cannot be used in fast callback"); - } - + VALIDATE((!source || nlua_is_deferred_safe()), "%s", "'do_source' used in fast callback", {}); if (ERROR_SET(err)) { return (Array)ARRAY_DICT_INIT; } @@ -602,10 +593,9 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E void nvim_set_current_dir(String dir, Error *err) FUNC_API_SINCE(1) { - if (dir.size >= MAXPATHL) { - api_set_error(err, kErrorTypeValidation, "Directory name is too long"); + VALIDATE_S((dir.size < MAXPATHL), "directory name", "(too long)", { return; - } + }); char string[MAXPATHL]; memcpy(string, dir.data, dir.size); @@ -664,16 +654,15 @@ Object nvim_get_var(String name, Error *err) { dictitem_T *di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); if (di == NULL) { // try to autoload script - if (!script_autoload(name.data, name.size, false) || aborting()) { - api_set_error(err, kErrorTypeValidation, "Key not found: %s", name.data); + bool found = script_autoload(name.data, name.size, false) && !aborting(); + VALIDATE(found, "Key not found: %s", name.data, { return (Object)OBJECT_INIT; - } + }); di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); } - if (di == NULL) { - api_set_error(err, kErrorTypeValidation, "Key not found: %s", name.data); + VALIDATE((di != NULL), "Key not found: %s", name.data, { return (Object)OBJECT_INIT; - } + }); return vim_to_object(&di->di_tv); } @@ -991,16 +980,14 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) String k = opts.items[i].key; Object *v = &opts.items[i].value; if (strequal("on_input", k.data)) { - if (v->type != kObjectTypeLuaRef) { - api_set_error(err, kErrorTypeValidation, - "%s is not a function", "on_input"); + VALIDATE_T("on_input", kObjectTypeLuaRef, v->type, { return 0; - } + }); cb = v->data.luaref; v->data.luaref = LUA_NOREF; break; } else { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); + VALIDATE_S(false, "'opts' key", k.data, {}); } } @@ -1075,9 +1062,7 @@ void nvim_chan_send(Integer chan, String data, Error *err) channel_send((uint64_t)chan, data.data, data.size, false, &error); - if (error) { - api_set_error(err, kErrorTypeValidation, "%s", error); - } + VALIDATE(!error, "%s", error, {}); } /// Gets the current list of tabpage handles. @@ -1164,10 +1149,9 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) static bool draining = false; bool cancel = false; - if (phase < -1 || phase > 3) { - api_set_error(err, kErrorTypeValidation, "Invalid phase: %" PRId64, phase); + VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { return false; - } + }); Array args = ARRAY_DICT_INIT; Object rv = OBJECT_INIT; if (phase == -1 || phase == 1) { // Start of paste-stream. @@ -1234,20 +1218,17 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, FUNC_API_CHECK_TEXTLOCK { yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); - if (!prepare_yankreg_from_object(reg, type, lines.size)) { - api_set_error(err, kErrorTypeValidation, "Invalid type: '%s'", type.data); + VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { goto cleanup; - } + }); if (lines.size == 0) { goto cleanup; // Nothing to do. } for (size_t i = 0; i < lines.size; i++) { - if (lines.items[i].type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "Invalid lines (expected array of strings)"); + VALIDATE_T("line", kObjectTypeString, lines.items[i].type, { goto cleanup; - } + }); String line = lines.items[i].data.string; reg->y_array[i] = xmemdupz(line.data, line.size); memchrsub(reg->y_array[i], NUL, NL, line.size); @@ -1348,11 +1329,11 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) FUNC_API_SINCE(6) { Array types = ARRAY_DICT_INIT; - if (opts->types.type == kObjectTypeArray) { + if (HAS_KEY(opts->types)) { + VALIDATE_T("types", kObjectTypeArray, opts->types.type, { + return (Dictionary)ARRAY_DICT_INIT; + }); types = opts->types.data.array; - } else if (opts->types.type != kObjectTypeNil) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: types"); - return (Dictionary)ARRAY_DICT_INIT; } int int_types = types.size > 0 ? 0 : kCtxAll; @@ -1373,8 +1354,9 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) } else if (strequal(s, "funcs")) { int_types |= kCtxFuncs; } else { - api_set_error(err, kErrorTypeValidation, "unexpected type: %s", s); - return (Dictionary)ARRAY_DICT_INIT; + VALIDATE_S(false, "type", s, { + return (Dictionary)ARRAY_DICT_INIT; + }); } } } @@ -1651,34 +1633,20 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *er size_t i; // also used for freeing the variables for (i = 0; i < calls.size; i++) { - if (calls.items[i].type != kObjectTypeArray) { - api_set_error(err, - kErrorTypeValidation, - "Items in calls array must be arrays"); + VALIDATE_T("'calls' item", kObjectTypeArray, calls.items[i].type, { goto theend; - } + }); Array call = calls.items[i].data.array; - if (call.size != 2) { - api_set_error(err, - kErrorTypeValidation, - "Items in calls array must be arrays of size 2"); + VALIDATE_EXP((call.size == 2), "'calls' item", "2-item Array", NULL, { goto theend; - } - - if (call.items[0].type != kObjectTypeString) { - api_set_error(err, - kErrorTypeValidation, - "Name must be String"); + }); + VALIDATE_T("name", kObjectTypeString, call.items[0].type, { goto theend; - } + }); String name = call.items[0].data.string; - - if (call.items[1].type != kObjectTypeArray) { - api_set_error(err, - kErrorTypeValidation, - "Args must be Array"); + VALIDATE_T("call args", kObjectTypeArray, call.items[1].type, { goto theend; - } + }); Array args = call.items[1].data.array; MsgpackRpcRequestHandler handler = @@ -1850,10 +1818,9 @@ Array nvim_get_proc_children(Integer pid, Error *err) Array rvobj = ARRAY_DICT_INIT; int *proc_list = NULL; - if (pid <= 0 || pid > INT_MAX) { - api_set_error(err, kErrorTypeException, "Invalid pid: %" PRId64, pid); + VALIDATE_INT((pid > 0 && pid <= INT_MAX), "pid", pid, { goto end; - } + }); size_t proc_count; int rv = os_proc_children((int)pid, &proc_list, &proc_count); @@ -1892,10 +1859,10 @@ Object nvim_get_proc(Integer pid, Error *err) rvobj.data.dictionary = (Dictionary)ARRAY_DICT_INIT; rvobj.type = kObjectTypeDictionary; - if (pid <= 0 || pid > INT_MAX) { - api_set_error(err, kErrorTypeException, "Invalid pid: %" PRId64, pid); + VALIDATE_INT((pid > 0 && pid <= INT_MAX), "pid", pid, { return NIL; - } + }); + #ifdef MSWIN rvobj.data.dictionary = os_proc_info((int)pid); if (rvobj.data.dictionary.size == 0) { // Process not found. @@ -1937,10 +1904,9 @@ void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Di Error *err) FUNC_API_SINCE(6) { - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); + VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { return; - } + }); if (finish) { insert = true; @@ -1961,13 +1927,10 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E g = &pum_grid; } else if (grid > 1) { win_T *wp = get_win_by_grid_handle((handle_T)grid); - if (wp != NULL && wp->w_grid_alloc.chars != NULL) { - g = &wp->w_grid_alloc; - } else { - api_set_error(err, kErrorTypeValidation, - "No grid with the given handle"); + VALIDATE_INT((wp != NULL && wp->w_grid_alloc.chars != NULL), "grid handle", grid, { return ret; - } + }); + g = &wp->w_grid_alloc; } if (row < 0 || row >= g->rows @@ -2009,20 +1972,16 @@ Boolean nvim_del_mark(String name, Error *err) FUNC_API_SINCE(8) { bool res = false; - if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, - "Mark name must be a single character"); + VALIDATE_S((name.size == 1), "mark name (must be a single char)", name.data, { return res; - } + }); // Only allow file/uppercase marks // TODO(muniter): Refactor this ASCII_ISUPPER macro to a proper function - if (ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)) { - res = set_mark(NULL, name, 0, 0, err); - } else { - api_set_error(err, kErrorTypeValidation, - "Only file/uppercase marks allowed, invalid mark name: '%c'", - *name.data); - } + VALIDATE_S((ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)), + "mark name (must be file/uppercase)", name.data, { + return res; + }); + res = set_mark(NULL, name, 0, 0, err); return res; } @@ -2043,16 +2002,13 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err) { Array rv = ARRAY_DICT_INIT; - if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, - "Mark name must be a single character"); + VALIDATE_S((name.size == 1), "mark name (must be a single char)", name.data, { return rv; - } else if (!(ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data))) { - api_set_error(err, kErrorTypeValidation, - "Only file/uppercase marks allowed, invalid mark name: '%c'", - *name.data); + }); + VALIDATE_S((ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)), + "mark name (must be file/uppercase)", name.data, { return rv; - } + }); xfmark_T *mark = mark_get_global(false, *name.data); // false avoids loading the mark buffer pos_T pos = mark->fmark.mark; @@ -2137,27 +2093,28 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * if (str.size < 2 || memcmp(str.data, "%!", 2) != 0) { const char *const errmsg = check_stl_option(str.data); - if (errmsg) { - api_set_error(err, kErrorTypeValidation, "%s", errmsg); + VALIDATE(!errmsg, "%s", errmsg, { return result; - } + }); } if (HAS_KEY(opts->winid)) { - if (opts->winid.type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, "winid must be an integer"); + VALIDATE_T("winid", kObjectTypeInteger, opts->winid.type, { return result; - } + }); window = (Window)opts->winid.data.integer; } if (HAS_KEY(opts->fillchar)) { - if (opts->fillchar.type != kObjectTypeString || opts->fillchar.data.string.size == 0 - || ((size_t)utf_ptr2len(opts->fillchar.data.string.data) - != opts->fillchar.data.string.size)) { - api_set_error(err, kErrorTypeValidation, "fillchar must be a single character"); + VALIDATE_T("fillchar", kObjectTypeString, opts->fillchar.type, { return result; - } + }); + VALIDATE_EXP((opts->fillchar.data.string.size != 0 + && ((size_t)utf_ptr2len(opts->fillchar.data.string.data) + == opts->fillchar.data.string.size)), + "fillchar", "single character", NULL, { + return result; + }); fillchar = utf_ptr2char(opts->fillchar.data.string.data); } if (HAS_KEY(opts->highlights)) { @@ -2181,10 +2138,9 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * return result; } } - if (use_winbar && use_tabline) { - api_set_error(err, kErrorTypeValidation, "use_winbar and use_tabline are mutually exclusive"); + VALIDATE(!(use_winbar && use_tabline), "%s", "Cannot use both 'use_winbar' and 'use_tabline'", { return result; - } + }); win_T *wp, *ewp; @@ -2211,10 +2167,9 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (HAS_KEY(opts->maxwidth)) { - if (opts->maxwidth.type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, "maxwidth must be an integer"); + VALIDATE_T("maxwidth", kObjectTypeInteger, opts->maxwidth.type, { return result; - } + }); maxwidth = (int)opts->maxwidth.data.integer; } else { @@ -2266,7 +2221,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * for (stl_hlrec_t *sp = hltab; sp->start != NULL; sp++) { Dictionary hl_info = ARRAY_DICT_INIT; - PUT(hl_info, "start", INTEGER_OBJ((char *)sp->start - buf)); + PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf)); if (sp->userhl == 0) { grpname = get_default_stl_hl(wp, use_winbar); @@ -2281,7 +2236,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } PUT(result, "highlights", ARRAY_OBJ(hl_values)); } - PUT(result, "str", CSTR_TO_OBJ((char *)buf)); + PUT(result, "str", CSTR_TO_OBJ(buf)); return result; } diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index c6a4be7e13..3882b98c2c 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -619,8 +619,6 @@ void ex_argument(exarg_T *eap) /// Edit file "argn" of the argument lists. void do_argfile(exarg_T *eap, int argn) { - int other; - char *p; int old_arg_idx = curwin->w_arg_idx; if (argn < 0 || argn >= ARGCOUNT) { @@ -646,9 +644,9 @@ void do_argfile(exarg_T *eap, int argn) } else { // if 'hidden' set, only check for changed file when re-editing // the same buffer - other = true; + int other = true; if (buf_hide(curbuf)) { - p = fix_fname(alist_name(&ARGLIST[argn])); + char *p = fix_fname(alist_name(&ARGLIST[argn])); other = otherfile(p); xfree(p); } @@ -683,8 +681,6 @@ void do_argfile(exarg_T *eap, int argn) /// ":next", and commands that behave like it. void ex_next(exarg_T *eap) { - int i; - // check for changed buffer now, if this fails the argument list is not // redefined. if (buf_hide(curbuf) @@ -692,6 +688,7 @@ void ex_next(exarg_T *eap) || !check_changed(curbuf, CCGD_AW | (eap->forceit ? CCGD_FORCEIT : 0) | CCGD_EXCMD)) { + int i; if (*eap->arg != NUL) { // redefine file list if (do_arglist(eap->arg, AL_SET, 0, true) == FAIL) { return; diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 4cc75fa9a6..2f1317b05d 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -221,7 +221,7 @@ static void aupat_show(AutoPat *ap, event_T event, int previous_group) char *exec_to_string = aucmd_exec_to_string(ac, ac->exec); if (ac->desc != NULL) { size_t msglen = 100; - char *msg = (char *)xmallocz(msglen); + char *msg = xmallocz(msglen); if (ac->exec.type == CALLABLE_CB) { msg_puts_attr(exec_to_string, HL_ATTR(HLF_8)); snprintf(msg, msglen, " [%s]", ac->desc); @@ -286,7 +286,7 @@ static void au_show_for_event(int group, event_T event, char *pat) if (aupat_is_buflocal(pat, patlen)) { // normalize pat into standard "<buffer>#N" form aupat_normalize_buflocal_pat(buflocal_pat, pat, patlen, aupat_get_buflocal_nr(pat, patlen)); - pat = (char *)buflocal_pat; + pat = buflocal_pat; patlen = (int)strlen(buflocal_pat); } @@ -2119,8 +2119,8 @@ static bool call_autocmd_callback(const AutoCmd *ac, const AutoPatCmd *apc) Dictionary data = ARRAY_DICT_INIT; PUT(data, "id", INTEGER_OBJ(ac->id)); PUT(data, "event", CSTR_TO_OBJ(event_nr2name(apc->event))); - PUT(data, "match", CSTR_TO_OBJ((char *)autocmd_match)); - PUT(data, "file", CSTR_TO_OBJ((char *)autocmd_fname)); + PUT(data, "match", CSTR_TO_OBJ(autocmd_match)); + PUT(data, "file", CSTR_TO_OBJ(autocmd_fname)); PUT(data, "buf", INTEGER_OBJ(autocmd_bufnr)); if (apc->data) { diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5dcb10751f..129a8c6fb2 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3311,7 +3311,7 @@ void maketitle(void) buf_p += MIN(size, SPACE_FOR_FNAME); } else { buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname), - buf_p, SPACE_FOR_FNAME + 1, true); + -1, buf_p, SPACE_FOR_FNAME + 1, true); } switch (bufIsChanged(curbuf) diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 3601dc7062..05901893b9 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -337,36 +337,6 @@ struct mapblock { bool m_replace_keycodes; // replace keycodes in result of expression }; -/// Used for highlighting in the status line. -typedef struct stl_hlrec stl_hlrec_t; -struct stl_hlrec { - char *start; - int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID -}; - -/// Used for building the status line. -typedef struct stl_item stl_item_t; -struct stl_item { - // Where the item starts in the status line output buffer - char *start; - // Function to run for ClickFunc items. - char *cmd; - // The minimum width of the item - int minwid; - // The maximum width of the item - int maxwid; - enum { - Normal, - Empty, - Group, - Separate, - Highlight, - TabPage, - ClickFunc, - Trunc, - } type; -}; - // values for b_syn_spell: what to do with toplevel text #define SYNSPL_DEFAULT 0 // spell check if @Spell not defined #define SYNSPL_TOP 1 // spell check toplevel text @@ -1112,20 +1082,23 @@ struct window_S { win_T *w_prev; ///< link to previous window win_T *w_next; ///< link to next window bool w_closing; ///< window is being closed, don't let - /// autocommands close it too. + ///< autocommands close it too. frame_T *w_frame; ///< frame containing this window pos_T w_cursor; ///< cursor position in buffer colnr_T w_curswant; ///< Column we want to be at. This is - /// used to try to stay in the same column - /// for up/down cursor motions. + ///< 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 // time through cursupdate() to the // current virtual column + linenr_T w_cursorline; ///< Where 'cursorline' should be drawn, + ///< can be different from w_cursor.lnum + ///< for closed folds. linenr_T w_last_cursorline; ///< where last 'cursorline' was drawn pos_T w_last_cursormoved; ///< for CursorMoved event @@ -1417,26 +1390,6 @@ struct window_S { size_t w_statuscol_click_defs_size; }; -/// Struct to hold info for 'statuscolumn' -typedef struct statuscol statuscol_T; - -struct statuscol { - int width; ///< width of the status column - int cur_attr; ///< current attributes in text - int num_attr; ///< attributes used for line number - int fold_attr; ///< attributes used for fold column - int sign_attr[SIGN_SHOW_MAX + 1]; ///< attributes used for signs - int truncate; ///< truncated width - bool draw; ///< draw statuscolumn or not - char fold_text[9 * 4 + 1]; ///< text in fold column (%C) - char *sign_text[SIGN_SHOW_MAX + 1]; ///< text in sign column (%s) - char text[MAXPATHL]; ///< text in status column - char *textp; ///< current position in text - char *text_end; ///< end of text (the NUL byte) - stl_hlrec_t *hlrec; ///< highlight groups - stl_hlrec_t *hlrecp; ///< current highlight group -}; - /// Macros defined in Vim, but not in Neovim // uncrustify:off #define CHANGEDTICK(buf) \ diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 65bb87bc2c..7f8e1c9fd1 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -32,12 +32,14 @@ #include "nvim/msgpack_rpc/server.h" #include "nvim/os/os_defs.h" #include "nvim/os/shell.h" +#include "nvim/path.h" #include "nvim/rbuffer.h" + #ifdef MSWIN +# include "nvim/os/fs.h" # include "nvim/os/os_win_console.h" # include "nvim/os/pty_conpty_win.h" #endif -#include "nvim/path.h" static bool did_stdio = false; diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 5aec9ccf9d..c4c7c5f387 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -354,14 +354,15 @@ size_t transstr_len(const char *const s, bool untab) /// @param[in] untab remove tab characters /// /// @return length of the resulting string, without the NUL byte. -size_t transstr_buf(const char *const s, char *const buf, const size_t len, bool untab) +size_t transstr_buf(const char *const s, const ssize_t slen, char *const buf, const size_t buflen, + bool untab) FUNC_ATTR_NONNULL_ALL { const char *p = s; char *buf_p = buf; - char *const buf_e = buf_p + len - 1; + char *const buf_e = buf_p + buflen - 1; - while (*p != NUL && buf_p < buf_e) { + while ((slen < 0 || (p - s) < slen) && *p != NUL && buf_p < buf_e) { const size_t l = (size_t)utfc_ptr2len(p); if (l > 1) { if (buf_p + l > buf_e) { @@ -416,7 +417,7 @@ char *transstr(const char *const s, bool untab) // multi-byte characters. const size_t len = transstr_len(s, untab) + 1; char *const buf = xmalloc(len); - transstr_buf(s, buf, len, untab); + transstr_buf(s, -1, buf, len, untab); return buf; } @@ -431,7 +432,7 @@ size_t kv_transstr(StringBuilder *str, const char *const s, bool untab) // multi-byte characters. const size_t len = transstr_len(s, untab); kv_ensure_space(*str, len + 1); - transstr_buf(s, str->items + str->size, len + 1, untab); + transstr_buf(s, -1, str->items + str->size, len + 1, untab); str->size += len; // do not include NUL byte return len; } diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 5e4b49db24..97feab2978 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -222,10 +222,8 @@ static void ExpandEscape(expand_T *xp, char *str, int numfiles, char **files, in int nextwild(expand_T *xp, int type, int options, bool escape) { CmdlineInfo *const ccline = get_cmdline_info(); - int i, j; - char *p1; + int i; char *p2; - int difflen; if (xp->xp_numfiles == -1) { set_expand_context(xp); @@ -258,6 +256,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape) // Get next/previous match for a previous expanded pattern. p2 = ExpandOne(xp, NULL, NULL, 0, type); } else { + char *p1; if (cmdline_fuzzy_completion_supported(xp)) { // If fuzzy matching, don't modify the search string p1 = xstrdup(xp->xp_pattern); @@ -282,6 +281,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape) // Longest match: make sure it is not shorter, happens with :help. if (p2 != NULL && type == WILD_LONGEST) { + int j; for (j = 0; (size_t)j < xp->xp_pattern_len; j++) { if (ccline->cmdbuff[i + j] == '*' || ccline->cmdbuff[i + j] == '?') { @@ -295,7 +295,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape) } if (p2 != NULL && !got_int) { - difflen = (int)strlen(p2) - (int)(xp->xp_pattern_len); + int difflen = (int)strlen(p2) - (int)(xp->xp_pattern_len); if (ccline->cmdlen + difflen + 4 > ccline->cmdbufflen) { realloc_cmdbuff(ccline->cmdlen + difflen + 4); xp->xp_pattern = ccline->cmdbuff + i; @@ -454,8 +454,6 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m char *selend = NULL; static int first_match = 0; bool add_left = false; - char *s; - int emenu; int l; if (matches == NULL) { // interrupted completion? @@ -528,10 +526,9 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m selstart_col = clen; } - s = SHOW_MATCH(i); + char *s = SHOW_MATCH(i); // Check for menu separators - replace with '|' - emenu = (xp->xp_context == EXPAND_MENUS - || xp->xp_context == EXPAND_MENUNAMES); + int emenu = (xp->xp_context == EXPAND_MENUS || xp->xp_context == EXPAND_MENUNAMES); if (emenu && menu_is_separator(s)) { STRCPY(buf + len, transchar('|')); l = (int)strlen(buf + len); @@ -847,7 +844,6 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) static int findex; static char *orig_save = NULL; // kept value of orig int orig_saved = false; - int i; // first handle the case of using an old match if (mode == WILD_NEXT || mode == WILD_PREV @@ -900,12 +896,12 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) // TODO(philix): use xstpcpy instead of strcat in a loop (ExpandOne) if (mode == WILD_ALL && xp->xp_numfiles > 0 && !got_int) { size_t len = 0; - for (i = 0; i < xp->xp_numfiles; i++) { + for (int i = 0; i < xp->xp_numfiles; i++) { len += strlen(xp->xp_files[i]) + 1; } ss = xmalloc(len); *ss = NUL; - for (i = 0; i < xp->xp_numfiles; i++) { + for (int i = 0; i < xp->xp_numfiles; i++) { STRCAT(ss, xp->xp_files[i]); if (i != xp->xp_numfiles - 1) { STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " "); @@ -1375,7 +1371,6 @@ void set_expand_context(expand_T *xp) static const char *set_cmd_index(const char *cmd, exarg_T *eap, expand_T *xp, int *complp) { const char *p = NULL; - size_t len = 0; const bool fuzzy = cmdline_fuzzy_complete(cmd); // Isolate the command and search for it in the command table. @@ -1410,7 +1405,7 @@ static const char *set_cmd_index(const char *cmd, exarg_T *eap, expand_T *xp, in if (p == cmd && vim_strchr("@*!=><&~#", (uint8_t)(*p)) != NULL) { p++; } - len = (size_t)(p - cmd); + size_t len = (size_t)(p - cmd); if (len == 0) { xp->xp_context = EXPAND_UNSUCCESSFUL; @@ -2000,8 +1995,8 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa case CMD_snoremap: case CMD_xmap: case CMD_xnoremap: - return (const char *)set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, false, - false, cmdidx); + return set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, false, + false, cmdidx); case CMD_unmap: case CMD_nunmap: case CMD_vunmap: @@ -2011,8 +2006,8 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa case CMD_lunmap: case CMD_sunmap: case CMD_xunmap: - return (const char *)set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, false, - true, cmdidx); + return set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, false, + true, cmdidx); case CMD_mapclear: case CMD_nmapclear: case CMD_vmapclear: @@ -2032,13 +2027,13 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa case CMD_cnoreabbrev: case CMD_iabbrev: case CMD_inoreabbrev: - return (const char *)set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, true, - false, cmdidx); + return set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, true, + false, cmdidx); case CMD_unabbreviate: case CMD_cunabbrev: case CMD_iunabbrev: - return (const char *)set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, true, - true, cmdidx); + return set_context_in_map_cmd(xp, (char *)cmd, (char *)arg, forceit, true, + true, cmdidx); case CMD_menu: case CMD_noremenu: case CMD_unmenu: @@ -2955,7 +2950,6 @@ static void expand_shellcmd(char *filepat, char ***matches, int *numMatches, int char *path = NULL; garray_T ga; char *buf = xmalloc(MAXPATHL); - size_t l; char *s, *e; int flags = flagsarg; bool did_curdir = false; @@ -3013,7 +3007,7 @@ static void expand_shellcmd(char *filepat, char ***matches, int *numMatches, int flags &= ~EW_DIR; } - l = (size_t)(e - s); + size_t l = (size_t)(e - s); if (l > MAXPATHL - 5) { break; } @@ -3238,7 +3232,7 @@ void globpath(char *path, char *file, garray_T *ga, int expand_options, bool dir ga_grow(ga, num_p); // take over the pointers and put them in "ga" for (int i = 0; i < num_p; i++) { - ((char_u **)ga->ga_data)[ga->ga_len] = (char_u *)p[i]; + ((char **)ga->ga_data)[ga->ga_len] = p[i]; ga->ga_len++; } xfree(p); diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c index 2df82d9355..c2928eb9c4 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -368,7 +368,6 @@ static int get_history_idx(int histype) static int calc_hist_idx(int histype, int num) { int i; - int wrapped = false; if (hislen == 0 || histype < 0 || histype >= HIST_COUNT || (i = hisidx[histype]) < 0 || num == 0) { @@ -377,6 +376,7 @@ static int calc_hist_idx(int histype, int num) histentry_T *hist = history[histype]; if (num > 0) { + int wrapped = false; while (hist[i].hisnum > num) { if (--i < 0) { if (wrapped) { @@ -568,14 +568,12 @@ void f_histdel(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) /// "histget()" function void f_histget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - HistoryType type; - int idx; - const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error if (str == NULL) { rettv->vval.v_string = NULL; } else { - type = get_histtype(str, strlen(str), false); + int idx; + HistoryType type = get_histtype(str, strlen(str), false); if (argvars[1].v_type == VAR_UNKNOWN) { idx = get_history_idx(type); } else { @@ -603,13 +601,11 @@ void f_histnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) /// :history command - print a history void ex_history(exarg_T *eap) { - histentry_T *hist; int histype1 = HIST_CMD; int histype2 = HIST_CMD; int hisidx1 = 1; int hisidx2 = -1; - int idx; - int i, j, k; + int i; char *end; char *arg = eap->arg; @@ -649,10 +645,10 @@ void ex_history(exarg_T *eap) assert(history_names[histype1] != NULL); STRCAT(STRCAT(IObuff, history_names[histype1]), " history"); msg_puts_title(IObuff); - idx = hisidx[histype1]; - hist = history[histype1]; - j = hisidx1; - k = hisidx2; + int idx = hisidx[histype1]; + histentry_T *hist = history[histype1]; + int j = hisidx1; + int k = hisidx2; if (j < 0) { j = (-j > hislen) ? 0 : hist[(hislen + j + idx + 1) % hislen].hisnum; } diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index b1dbc68ea3..ceeaa65206 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -494,10 +494,10 @@ int gchar_cursor(void) /// Write a character at the current cursor position. /// It is directly written into the block. -void pchar_cursor(char_u c) +void pchar_cursor(char c) { *(ml_get_buf(curbuf, curwin->w_cursor.lnum, true) - + curwin->w_cursor.col) = (char)c; + + curwin->w_cursor.col) = c; } /// @return pointer to cursor line. diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index f7e70a78ce..3c9a63f5a3 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -75,7 +75,6 @@ void do_debug(char *cmd) tasave_T typeaheadbuf; bool typeahead_saved = false; int save_ignore_script = 0; - int n; char *cmdline = NULL; char *p; char *tail = NULL; @@ -146,7 +145,7 @@ void do_debug(char *cmd) } // don't debug any function call, e.g. from an expression mapping - n = debug_break_level; + int n = debug_break_level; debug_break_level = -1; xfree(cmdline); @@ -727,7 +726,7 @@ void ex_breaklist(exarg_T *eap) for (int i = 0; i < dbg_breakp.ga_len; i++) { struct debuggy *bp = &BREAKP(i); if (bp->dbg_type == DBG_FILE) { - home_replace(NULL, bp->dbg_name, (char *)NameBuff, MAXPATHL, true); + home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true); } if (bp->dbg_type != DBG_EXPR) { smsg(_("%3d %s %s line %" PRId64), diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 032de561b3..c5b28822d0 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -2652,8 +2652,7 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) bool added = true; linenr_T off = lnum - dp->df_lnum[idx]; - int i; - for (i = 0; i < DB_COUNT; i++) { + for (int i = 0; i < DB_COUNT; i++) { if ((curtab->tp_diffbuf[i] != NULL) && (i != idx)) { // Skip lines that are not in the other change (filler lines). if (off >= dp->df_count[i]) { @@ -3409,7 +3408,7 @@ static int parse_diff_ed(char *line, diffhunk_T *hunk) linenr_T f1 = getdigits_int32(&p, true, 0); if (*p == ',') { p++; - l1 = getdigits(&p, true, 0); + l1 = getdigits_long(&p, true, 0); } else { l1 = f1; } @@ -3417,10 +3416,10 @@ static int parse_diff_ed(char *line, diffhunk_T *hunk) return FAIL; // invalid diff format } int difftype = (uint8_t)(*p++); - long f2 = getdigits(&p, true, 0); + long f2 = getdigits_long(&p, true, 0); if (*p == ',') { p++; - l2 = getdigits(&p, true, 0); + l2 = getdigits_long(&p, true, 0); } else { l2 = f2; } @@ -3458,18 +3457,18 @@ static int parse_diff_unified(char *line, diffhunk_T *hunk) long oldcount; long newline; long newcount; - long oldline = getdigits(&p, true, 0); + long oldline = getdigits_long(&p, true, 0); if (*p == ',') { p++; - oldcount = getdigits(&p, true, 0); + oldcount = getdigits_long(&p, true, 0); } else { oldcount = 1; } if (*p++ == ' ' && *p++ == '+') { - newline = getdigits(&p, true, 0); + newline = getdigits_long(&p, true, 0); if (*p == ',') { p++; - newcount = getdigits(&p, true, 0); + newcount = getdigits_long(&p, true, 0); } else { newcount = 1; } diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 01ff207c2b..3cedb04bcb 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -303,7 +303,7 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, static bool use_cursor_line_sign(win_T *wp, linenr_T lnum) { return wp->w_p_cul - && lnum == wp->w_cursor.lnum + && lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR); } @@ -404,37 +404,10 @@ static int get_sign_attrs(buf_T *buf, linenr_T lnum, SignTextAttrs *sattrs, int /// the start of the buffer line "lnum" and once for the wrapped lines. /// /// @param[out] stcp Status column attributes -static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines, - int cul_attr, int sign_num_attr, int sign_cul_attr, statuscol_T *stcp, - foldinfo_T foldinfo, SignTextAttrs *sattrs) +static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T *stcp) { - long relnum = -1; - bool use_cul = use_cursor_line_sign(wp, lnum); - int virtnum = row - startrow - filler_lines; - - // When called the first time for line "lnum" set num_attr - if (stcp->num_attr == 0) { - stcp->num_attr = sign_num_attr ? sign_num_attr - : get_line_number_attr(wp, lnum, row, startrow, filler_lines); - } - // When called for the first non-filler row of line "lnum" set num v:vars and fold column - if (virtnum == 0) { - relnum = labs(get_cursor_rel_lnum(wp, lnum)); - if (compute_foldcolumn(wp, 0)) { - size_t n = fill_foldcolumn(stcp->fold_text, wp, foldinfo, lnum); - stcp->fold_text[n] = NUL; - stcp->fold_attr = win_hl_attr(wp, use_cul ? HLF_CLF : HLF_FC); - } - } - // Make sure to clear->set->clear sign column for filler->first->wrapped lines - int i = 0; - for (; i < wp->w_scwidth; i++) { - SignTextAttrs *sattr = virtnum ? NULL : sign_get_attr(i, sattrs, wp->w_scwidth); - stcp->sign_text[i] = sattr && sattr->text ? sattr->text : " "; - stcp->sign_attr[i] = sattr ? (use_cul && sign_cul_attr ? sign_cul_attr : sattr->hl_attr_id) - : win_hl_attr(wp, use_cul ? HLF_CLS : HLF_SC); - } - stcp->sign_text[i] = NULL; + // When called for the first non-filler row of line "lnum" set num v:vars + long relnum = virtnum == 0 ? labs(get_cursor_rel_lnum(wp, lnum)) : -1; // When a buffer's line count has changed, make a best estimate for the full // width of the status column by building with "w_nrwidth_line_count". Add @@ -442,14 +415,12 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, i if (wp->w_statuscol_line_count != wp->w_nrwidth_line_count) { wp->w_statuscol_line_count = wp->w_nrwidth_line_count; set_vim_var_nr(VV_VIRTNUM, 0); - build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, stcp->width, - ' ', stcp->text, &stcp->hlrec, stcp); + build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, stcp); stcp->width += stcp->truncate; } set_vim_var_nr(VV_VIRTNUM, virtnum); - int width = build_statuscol_str(wp, lnum, relnum, stcp->width, - ' ', stcp->text, &stcp->hlrec, stcp); + int width = build_statuscol_str(wp, lnum, relnum, stcp); // Force a redraw in case of error or when truncated if (*wp->w_p_stc == NUL || (stcp->truncate > 0 && wp->w_nrwidth < MAX_NUMBERWIDTH)) { if (stcp->truncate) { // Avoid truncating 'statuscolumn' @@ -496,8 +467,7 @@ static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_st if (stcp->textp + *n_extrap < stcp->text_end) { int hl = stcp->hlrecp->userhl; stcp->textp = stcp->hlrecp->start; - stcp->cur_attr = hl < 0 ? syn_id2attr(-stcp->hlrecp->userhl) - : hl > 0 ? hl : stcp->num_attr; + stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : hl > 0 ? hl : stcp->num_attr; stcp->hlrecp++; *draw_state = WL_STC - 1; } @@ -517,7 +487,7 @@ static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_st static bool use_cursor_line_nr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines) { return wp->w_p_cul - && lnum == wp->w_cursor.lnum + && lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR) && (row == startrow + filler_lines || (row > startrow + filler_lines @@ -547,6 +517,12 @@ static inline void get_line_number_str(win_T *wp, linenr_T lnum, char *buf, size static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines) { + if (use_cursor_line_nr(wp, lnum, row, startrow, filler_lines)) { + // TODO(vim): Can we use CursorLine instead of CursorLineNr + // when CursorLineNr isn't set? + return win_hl_attr(wp, HLF_CLN); + } + if (wp->w_p_rnu) { if (lnum < wp->w_cursor.lnum) { // Use LineNrAbove @@ -558,12 +534,6 @@ static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow, } } - if (use_cursor_line_nr(wp, lnum, row, startrow, filler_lines)) { - // TODO(vim): Can we use CursorLine instead of CursorLineNr - // when CursorLineNr isn't set? - return win_hl_attr(wp, HLF_CLN); - } - return win_hl_attr(wp, HLF_N); } @@ -615,7 +585,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, foldinfo_T foldinfo, DecorProviders *providers, char **provider_err) { int c = 0; // init for GCC - long vcol = 0; // virtual column (for tabs) + colnr_T vcol = 0; // virtual column (for tabs) long vcol_sbr = -1; // virtual column after showbreak long vcol_prev = -1; // "vcol" of previous character char *line; // current line @@ -657,7 +627,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, bool noinvcur = false; // don't invert the cursor bool lnum_in_visual_area = false; pos_T pos; - long v; + ptrdiff_t v; int char_attr = 0; // attributes for next character bool attr_pri = false; // char_attr has priority @@ -798,7 +768,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, // Check for columns to display for 'colorcolumn'. color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols; if (color_cols != NULL) { - draw_color_col = advance_color_col((int)VCOL_HLC, &color_cols); + draw_color_col = advance_color_col(VCOL_HLC, &color_cols); } if (wp->w_p_spell @@ -960,20 +930,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, filler_todo = filler_lines; // Cursor line highlighting for 'cursorline' in the current window. - if (lnum == wp->w_cursor.lnum) { - // Do not show the cursor line in the text when Visual mode is active, - // because it's not clear what is selected then. - if (wp->w_p_cul && !(wp == curwin && VIsual_active) - && wp->w_p_culopt_flags != CULOPT_NBR) { - cul_screenline = (wp->w_p_wrap - && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); - if (!cul_screenline) { - apply_cursorline_highlight(wp, lnum, &line_attr, &cul_attr, &line_attr_lowprio); - } else { - margin_columns_win(wp, &left_curline_col, &right_curline_col); - } - area_highlighting = true; + if (wp->w_p_cul && wp->w_p_culopt_flags != CULOPT_NBR && lnum == wp->w_cursorline + // Do not show the cursor line in the text when Visual mode is active, + // because it's not clear what is selected then. + && !(wp == curwin && VIsual_active)) { + cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); + if (!cul_screenline) { + apply_cursorline_highlight(wp, lnum, &line_attr, &cul_attr, &line_attr_lowprio); + } else { + margin_columns_win(wp, &left_curline_col, &right_curline_col); } + area_highlighting = true; } SignTextAttrs sattrs[SIGN_SHOW_MAX]; // sign attributes for the sign column @@ -1075,7 +1042,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, chartabsize_T cts; int charsize; - init_chartabsize_arg(&cts, wp, lnum, (colnr_T)vcol, line, ptr); + init_chartabsize_arg(&cts, wp, lnum, vcol, line, ptr); while (cts.cts_vcol < v && *cts.cts_ptr != NUL) { charsize = win_lbr_chartabsize(&cts, NULL); cts.cts_vcol += charsize; @@ -1096,7 +1063,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, || draw_color_col || virtual_active() || (VIsual_active && wp->w_buffer == curwin->w_buffer))) { - vcol = v; + vcol = (colnr_T)v; } // Handle a character that's not completely on the screen: Put ptr at @@ -1116,7 +1083,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, if (tocol <= vcol) { fromcol = 0; } else if (fromcol >= 0 && fromcol < vcol) { - fromcol = (int)vcol; + fromcol = vcol; } // When w_skipcol is non-zero, first line needs 'showbreak' @@ -1211,7 +1178,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, if (*wp->w_p_stc != NUL) { // Draw the 'statuscolumn' if option is set. statuscol.draw = true; + statuscol.sattrs = sattrs; + statuscol.foldinfo = foldinfo; statuscol.width = win_col_off(wp); + statuscol.use_cul = use_cursor_line_sign(wp, lnum); + statuscol.sign_cul_attr = statuscol.use_cul ? sign_cul_attr : 0; + statuscol.num_attr = sign_num_attr ? sign_num_attr + : get_line_number_attr(wp, lnum, row, startrow, filler_lines); } int sign_idx = 0; @@ -1357,8 +1330,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, // Draw the 'statuscolumn' if option is set. if (statuscol.draw) { if (statuscol.textp == NULL) { - get_statuscol_str(wp, lnum, row, startrow, filler_lines, cul_attr, - sign_num_attr, sign_cul_attr, &statuscol, foldinfo, sattrs); + get_statuscol_str(wp, lnum, row - startrow - filler_lines, &statuscol); if (wp->w_redr_statuscol) { break; } @@ -1473,7 +1445,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, if (has_decor && row == startrow + filler_lines) { // hide virt_text on text hidden by 'nowrap' - decor_redraw_col(wp->w_buffer, (int)vcol, off, true, &decor_state); + decor_redraw_col(wp->w_buffer, vcol, off, true, &decor_state); } if (saved_n_extra) { @@ -1570,7 +1542,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, } } else if (area_attr != 0 && (vcol == tocol || (noinvcur - && (colnr_T)vcol == wp->w_virtcol))) { + && vcol == wp->w_virtcol))) { area_attr = 0; // stop highlighting area_active = false; } @@ -1725,9 +1697,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, // At start of the line we can have a composing char. // Draw it as a space with a composing char. if (utf_iscomposing(mb_c)) { - int i; - - for (i = MAX_MCO - 1; i > 0; i--) { + for (int i = MAX_MCO - 1; i > 0; i--) { u8cc[i] = u8cc[i - 1]; } u8cc[0] = mb_c; @@ -1875,7 +1845,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, if (has_decor && v > 0) { bool selected = (area_active || (area_highlighting && noinvcur - && (colnr_T)vcol == wp->w_virtcol)); + && vcol == wp->w_virtcol)); int extmark_attr = decor_redraw_col(wp->w_buffer, (colnr_T)v - 1, off, selected, &decor_state); if (extmark_attr != 0) { @@ -1984,7 +1954,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, char *p = ptr - (mb_off + 1); chartabsize_T cts; - init_chartabsize_arg(&cts, wp, lnum, (colnr_T)vcol, line, p); + init_chartabsize_arg(&cts, wp, lnum, vcol, line, p); n_extra = win_lbr_chartabsize(&cts, NULL) - 1; // We have just drawn the showbreak value, no need to add @@ -2003,7 +1973,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, } if (c == TAB && n_extra + col > grid->cols) { - n_extra = tabstop_padding((colnr_T)vcol, wp->w_buffer->b_p_ts, + n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts, wp->w_buffer->b_p_vts_array) - 1; } c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' '; @@ -2102,7 +2072,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, n_extra = tab_len; } else { char *p; - int i; int saved_nextra = n_extra; if (vcol_off > 0) { @@ -2131,7 +2100,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, p[len] = NUL; xfree(p_extra_free); p_extra_free = p; - for (i = 0; i < tab_len; i++) { + for (int i = 0; i < tab_len; i++) { if (*p == NUL) { tab_len = i; break; @@ -2203,7 +2172,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, && (wp->w_p_rl ? (col >= 0) : (col < grid->cols)) && !(noinvcur && lnum == wp->w_cursor.lnum - && (colnr_T)vcol == wp->w_virtcol))) + && vcol == wp->w_virtcol))) && lcs_eol_one > 0) { // Display a '$' after the line or highlight an extra // character if the line break is included. @@ -2456,7 +2425,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, // check if line ends before left margin if (vcol < v + col - win_col_off(wp)) { - vcol = v + col - win_col_off(wp); + vcol = (colnr_T)v + col - win_col_off(wp); } // Get rid of the boguscols now, we want to draw until the right // edge for 'cursorcolumn'. @@ -2464,7 +2433,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, // boguscols = 0; // Disabled because value never read after this if (draw_color_col) { - draw_color_col = advance_color_col((int)VCOL_HLC, &color_cols); + draw_color_col = advance_color_col(VCOL_HLC, &color_cols); } bool has_virttext = false; @@ -2486,7 +2455,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, || draw_color_col || line_attr_lowprio || line_attr || diff_hlf != (hlf_T)0 || has_virttext)) { int rightmost_vcol = 0; - int i; if (wp->w_p_cuc) { rightmost_vcol = wp->w_virtcol; @@ -2494,7 +2462,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, if (draw_color_col) { // determine rightmost colorcolumn to possibly draw - for (i = 0; color_cols[i] >= 0; i++) { + for (int i = 0; color_cols[i] >= 0; i++) { if (rightmost_vcol < color_cols[i]) { rightmost_vcol = color_cols[i]; } @@ -2523,7 +2491,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, schar_from_ascii(linebuf_char[off], ' '); col += col_stride; if (draw_color_col) { - draw_color_col = advance_color_col((int)VCOL_HLC, &color_cols); + draw_color_col = advance_color_col(VCOL_HLC, &color_cols); } int col_attr = base_attr; @@ -2597,7 +2565,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, // advance to the next 'colorcolumn' if (draw_color_col) { - draw_color_col = advance_color_col((int)VCOL_HLC, &color_cols); + draw_color_col = advance_color_col(VCOL_HLC, &color_cols); } // Highlight the cursor column if 'cursorcolumn' is set. But don't diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 04c342e068..2c0b6ea3b0 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -318,6 +318,10 @@ void screen_resize(int width, int height) resizing_autocmd = false; redraw_all_later(UPD_CLEAR); + if (State != MODE_ASKMORE && State != MODE_EXTERNCMD && State != MODE_CONFIRM) { + screenclear(); + } + if (starting != NO_SCREEN) { maketitle(); @@ -1548,7 +1552,15 @@ static void win_update(win_T *wp, DecorProviders *providers) wp->w_old_visual_col = 0; } - bool cursorline_standout = win_cursorline_standout(wp); + foldinfo_T cursorline_fi; + wp->w_cursorline = win_cursorline_standout(wp) ? wp->w_cursor.lnum : 0; + if (wp->w_p_cul) { + // Make sure that the cursorline on a closed fold is redrawn + cursorline_fi = fold_info(wp, wp->w_cursor.lnum); + if (cursorline_fi.fi_level > 0 && cursorline_fi.fi_lines > 0) { + wp->w_cursorline = cursorline_fi.fi_lnum; + } + } win_check_ns_hl(wp); @@ -1604,7 +1616,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // if lines were inserted or deleted || (wp->w_match_head != NULL && buf->b_mod_xlines != 0))))) - || (cursorline_standout && lnum == wp->w_cursor.lnum) + || lnum == wp->w_cursorline || lnum == wp->w_last_cursorline) { if (lnum == mod_top) { top_to_mod = false; @@ -1620,8 +1632,6 @@ static void win_update(win_T *wp, DecorProviders *providers) && !(dollar_vcol >= 0 && mod_bot == mod_top + 1) && row >= top_end) { int old_rows = 0; - int new_rows = 0; - int xtra_rows; linenr_T l; int i; @@ -1656,6 +1666,7 @@ static void win_update(win_T *wp, DecorProviders *providers) bot_start = 0; bot_scroll_start = 0; } else { + int new_rows = 0; // Able to count old number of rows: Count new window // rows, and may insert/delete lines long j = idx; @@ -1674,7 +1685,7 @@ static void win_update(win_T *wp, DecorProviders *providers) break; } } - xtra_rows = new_rows - old_rows; + int xtra_rows = new_rows - old_rows; if (xtra_rows < 0) { // May scroll text up. If there is not enough // remaining text or scrolling fails, must redraw the @@ -1756,7 +1767,8 @@ static void win_update(win_T *wp, DecorProviders *providers) // When lines are folded, display one line for all of them. // Otherwise, display normally (can be several display lines when // 'wrap' is on). - foldinfo_T foldinfo = fold_info(wp, lnum); + foldinfo_T foldinfo = wp->w_p_cul && lnum == wp->w_cursor.lnum ? + cursorline_fi : fold_info(wp, lnum); if (foldinfo.fi_lines == 0 && idx < wp->w_lines_valid @@ -1815,7 +1827,8 @@ static void win_update(win_T *wp, DecorProviders *providers) if (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum) { // 'relativenumber' set and cursor moved vertically: The // text doesn't need to be drawn, but the number column does. - foldinfo_T info = fold_info(wp, lnum); + foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum ? + cursorline_fi : fold_info(wp, lnum); (void)win_line(wp, lnum, srow, wp->w_grid.rows, true, true, info, &line_providers, &provider_err); } @@ -1850,7 +1863,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // Now that the window has been redrawn with the old and new cursor line, // update w_last_cursorline. - wp->w_last_cursorline = cursorline_standout ? wp->w_cursor.lnum : 0; + wp->w_last_cursorline = wp->w_cursorline; wp->w_last_cursor_lnum_rnu = wp->w_p_rnu ? wp->w_cursor.lnum : 0; diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 96df6a3044..ff7899d0eb 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -558,10 +558,9 @@ static int insert_execute(VimState *state, int key) if (ins_compl_accept_char(s->c)) { // Trigger InsertCharPre. char *str = do_insert_char_pre(s->c); - char *p; if (str != NULL) { - for (p = str; *p != NUL; MB_PTR_ADV(p)) { + for (char *p = str; *p != NUL; MB_PTR_ADV(p)) { ins_compl_addleader(utf_ptr2char(p)); } xfree(str); @@ -1122,12 +1121,11 @@ normalchar: if (!p_paste) { // Trigger InsertCharPre. char *str = do_insert_char_pre(s->c); - char *p; if (str != NULL) { if (*str != NUL && stop_arrow() != FAIL) { // Insert the new value of v:char literally. - for (p = str; *p != NUL; MB_PTR_ADV(p)) { + for (char *p = str; *p != NUL; MB_PTR_ADV(p)) { s->c = utf_ptr2char(p); if (s->c == CAR || s->c == K_KENTER || s->c == NL) { ins_eol(s->c); @@ -1403,16 +1401,15 @@ static int pc_status; #define PC_STATUS_RIGHT 1 // right half of double-wide char #define PC_STATUS_LEFT 2 // left half of double-wide char #define PC_STATUS_SET 3 // pc_bytes was filled -static char_u pc_bytes[MB_MAXBYTES + 1]; // saved bytes +static char pc_bytes[MB_MAXBYTES + 1]; // saved bytes static int pc_attr; static int pc_row; static int pc_col; void edit_putchar(int c, bool highlight) { - int attr; - if (curwin->w_grid_alloc.chars != NULL || default_grid.chars != NULL) { + int attr; update_topline(curwin); // just in case w_topline isn't valid validate_cursor(); if (highlight) { @@ -1441,7 +1438,7 @@ void edit_putchar(int c, bool highlight) // save the character to be able to put it back if (pc_status == PC_STATUS_UNSET) { - grid_getbytes(&curwin->w_grid, pc_row, pc_col, (char *)pc_bytes, &pc_attr); + grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr); pc_status = PC_STATUS_SET; } grid_putchar(&curwin->w_grid, c, pc_row, pc_col, attr); @@ -1524,7 +1521,7 @@ void edit_unputchar(void) if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) { redrawWinline(curwin, curwin->w_cursor.lnum); } else { - grid_puts(&curwin->w_grid, (char *)pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr); + grid_puts(&curwin->w_grid, pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr); } } } @@ -1583,7 +1580,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang int start_col; colnr_T vc; colnr_T orig_col = 0; // init for GCC - char *new_line, *orig_line = NULL; // init for GCC + char *orig_line = NULL; // init for GCC // MODE_VREPLACE state needs to know what the line was like before changing if (State & VREPLACE_FLAG) { @@ -1742,7 +1739,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang // then put it back again the way we wanted it. if (State & VREPLACE_FLAG) { // Save new line - new_line = xstrdup(get_cursor_line_ptr()); + char *new_line = xstrdup(get_cursor_line_ptr()); // We only put back the new line up to the cursor new_line[curwin->w_cursor.col] = NUL; @@ -1949,9 +1946,6 @@ int get_literal(bool no_simplify) /// @param ctrlv `c` was typed after CTRL-V static void insert_special(int c, int allow_modmask, int ctrlv) { - char *p; - int len; - // Special function key, translate into "<Key>". Up to the last '>' is // inserted with ins_str(), so as not to replace characters in replace // mode. @@ -1961,8 +1955,8 @@ static void insert_special(int c, int allow_modmask, int ctrlv) allow_modmask = true; } if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) { - p = (char *)get_special_key_name(c, mod_mask); - len = (int)strlen(p); + char *p = (char *)get_special_key_name(c, mod_mask); + int len = (int)strlen(p); c = (uint8_t)p[len - 1]; if (len > 2) { if (stop_arrow() == FAIL) { @@ -2057,7 +2051,7 @@ void insertchar(int c, int flags, int second_indent) // Check whether this character should end a comment. if (did_ai && c == end_comment_pending) { - char_u lead_end[COM_MAX_LEN]; // end-comment string + char lead_end[COM_MAX_LEN]; // end-comment string // Need to remove existing (middle) comment leader and insert end // comment leader. First, check what comment leader we can find. @@ -2068,7 +2062,7 @@ void insertchar(int c, int flags, int second_indent) while (*p && p[-1] != ':') { // find end of middle flags p++; } - int middle_len = (int)copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ","); + int middle_len = (int)copy_option_part(&p, lead_end, COM_MAX_LEN, ","); // Don't count trailing white space for middle_len while (middle_len > 0 && ascii_iswhite(lead_end[middle_len - 1])) { middle_len--; @@ -2078,7 +2072,7 @@ void insertchar(int c, int flags, int second_indent) while (*p && p[-1] != ':') { // find end of end flags p++; } - int end_len = (int)copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ","); + int end_len = (int)copy_option_part(&p, lead_end, COM_MAX_LEN, ","); // Skip white space before the cursor i = curwin->w_cursor.col; @@ -2089,13 +2083,13 @@ void insertchar(int c, int flags, int second_indent) i -= middle_len; // Check some expected things before we go on - if (i >= 0 && lead_end[end_len - 1] == end_comment_pending) { + if (i >= 0 && (uint8_t)lead_end[end_len - 1] == end_comment_pending) { // Backspace over all the stuff we want to replace backspace_until_column(i); // Insert the end-comment string, except for the last // character, which will get inserted as normal later. - ins_bytes_len((char *)lead_end, (size_t)(end_len - 1)); + ins_bytes_len(lead_end, (size_t)(end_len - 1)); } } } @@ -2294,7 +2288,6 @@ int stop_arrow(void) /// @param nomove <c-\><c-o>, don't move cursor static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) { - int cc; char *ptr; stop_redo_ins(); @@ -2314,6 +2307,7 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) } if (!arrow_used && end_insert_pos != NULL) { + int cc; // Auto-format now. It may seem strange to do this when stopping an // insertion (or moving the cursor), but it's required when appending // a line and having it end in a space. But only do it when something @@ -2422,7 +2416,7 @@ void set_last_insert(int c) if (c < ' ' || c == DEL) { *s++ = Ctrl_V; } - s = (char *)add_char2buf(c, (char_u *)s); + s = add_char2buf(c, s); *s++ = ESC; *s++ = NUL; last_insert_skip = 0; @@ -2449,9 +2443,9 @@ void beginline(int flags) curwin->w_cursor.coladd = 0; if (flags & (BL_WHITE | BL_SOL)) { - char_u *ptr; + char *ptr; - for (ptr = (char_u *)get_cursor_line_ptr(); ascii_iswhite(*ptr) + for (ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr) && !((flags & BL_FIX) && ptr[1] == NUL); ptr++) { curwin->w_cursor.col++; } @@ -2682,7 +2676,7 @@ int stuff_inserted(int c, long count, int no_esc) char *last_ptr; char last = NUL; - ptr = (char *)get_last_insert(); + ptr = get_last_insert(); if (ptr == NULL) { emsg(_(e_noinstext)); return FAIL; @@ -2731,13 +2725,13 @@ int stuff_inserted(int c, long count, int no_esc) return OK; } -char_u *get_last_insert(void) +char *get_last_insert(void) FUNC_ATTR_PURE { if (last_insert == NULL) { return NULL; } - return (char_u *)last_insert + last_insert_skip; + return last_insert + last_insert_skip; } // Get last inserted string, and remove trailing <Esc>. @@ -2883,7 +2877,6 @@ static void mb_replace_pop_ins(int cc) int n; char_u buf[MB_MAXBYTES + 1]; int i; - int c; if ((n = MB_BYTE2LEN(cc)) > 1) { buf[0] = (char_u)cc; @@ -2897,7 +2890,7 @@ static void mb_replace_pop_ins(int cc) // Handle composing chars. for (;;) { - c = replace_pop(); + int c = replace_pop(); if (c == -1) { // stack empty break; } @@ -2943,17 +2936,13 @@ static void replace_flush(void) static void replace_do_bs(int limit_col) { int cc; - int orig_len = 0; - int ins_len; - int orig_vcols = 0; colnr_T start_vcol; - char *p; - int i; - int vcol; const int l_State = State; cc = replace_pop(); if (cc > 0) { + int orig_len = 0; + int orig_vcols = 0; if (l_State & VREPLACE_FLAG) { // Get the number of screen cells used by the character we are // going to delete. @@ -2969,10 +2958,10 @@ static void replace_do_bs(int limit_col) if (l_State & VREPLACE_FLAG) { // Get the number of screen cells used by the inserted characters - p = get_cursor_pos_ptr(); - ins_len = (int)strlen(p) - orig_len; - vcol = start_vcol; - for (i = 0; i < ins_len; i++) { + char *p = get_cursor_pos_ptr(); + int ins_len = (int)strlen(p) - orig_len; + int vcol = start_vcol; + for (int i = 0; i < ins_len; i++) { vcol += win_chartabsize(curwin, p + i, vcol); i += utfc_ptr2len(p) - 1; } @@ -3786,14 +3775,11 @@ static void ins_bs_one(colnr_T *vcolp) static bool ins_bs(int c, int mode, int *inserted_space_p) FUNC_ATTR_NONNULL_ARG(3) { - linenr_T lnum; int cc; int temp = 0; // init for GCC colnr_T save_col; - colnr_T mincol; bool did_backspace = false; int in_indent; - int oldState; int cpc[MAX_MCO]; // composing characters bool call_fix_indent = false; @@ -3844,7 +3830,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // Delete newline! if (curwin->w_cursor.col == 0) { - lnum = Insstart.lnum; + linenr_T lnum = Insstart.lnum; if (curwin->w_cursor.lnum == lnum || revins_on) { if (u_save((linenr_T)(curwin->w_cursor.lnum - 2), (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) { @@ -3900,7 +3886,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // Do the next ins_char() in MODE_NORMAL state, to // prevent ins_char() from replacing characters and // avoiding showmatch(). - oldState = State; + int oldState = State; State = MODE_NORMAL; // restore characters (blanks) deleted after cursor while (cc > 0) { @@ -3920,7 +3906,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) if (revins_on) { // put cursor on last inserted char dec_cursor(); } - mincol = 0; + colnr_T mincol = 0; // keep indent if (mode == BACKSPACE_LINE && (curbuf->b_p_ai || cindent_on()) @@ -3944,7 +3930,6 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) && (*(get_cursor_pos_ptr() - 1) == TAB || (*(get_cursor_pos_ptr() - 1) == ' ' && (!*inserted_space_p || arrow_used)))))) { - int ts; colnr_T vcol; colnr_T want_vcol; colnr_T start_vcol; @@ -3959,7 +3944,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); inc_cursor(); if (p_sta && in_indent) { - ts = get_sw_value(curbuf); + int ts = get_sw_value(curbuf); want_vcol = (want_vcol / ts) * ts; } else { want_vcol = tabstop_start(want_vcol, @@ -3999,7 +3984,6 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) } } else { // Delete up to starting point, start of line or previous word. - int prev_cclass = 0; int cclass = mb_get_class(get_cursor_pos_ptr()); do { @@ -4008,7 +3992,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) } cc = gchar_cursor(); // look multi-byte character class - prev_cclass = cclass; + int prev_cclass = cclass; cclass = mb_get_class(get_cursor_pos_ptr()); if (mode == BACKSPACE_WORD && !ascii_isspace(cc)) { // start of word? mode = BACKSPACE_WORD_NOT_SPACE; @@ -4425,7 +4409,6 @@ static void ins_pagedown(void) static bool ins_tab(void) FUNC_ATTR_WARN_UNUSED_RESULT { - int i; int temp; if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) { @@ -4501,6 +4484,7 @@ static bool ins_tab(void) if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0 || get_sts_value() > 0 || (p_sta && ind))) { + int i; char *ptr; char *saved_line = NULL; // init for GCC pos_T pos; @@ -4597,7 +4581,7 @@ static bool ins_tab(void) // Delete following spaces. i = cursor->col - fpos.col; if (i > 0) { - STRMOVE(ptr, (char *)ptr + i); + STRMOVE(ptr, ptr + i); // correct replace stack. if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG)) { @@ -4690,7 +4674,6 @@ bool ins_eol(int c) static int ins_digraph(void) { int c; - int cc; bool did_putchar = false; pc_status = PC_STATUS_UNSET; @@ -4736,7 +4719,7 @@ static int ins_digraph(void) } no_mapping++; allow_keys++; - cc = plain_vgetc(); + int cc = plain_vgetc(); no_mapping--; allow_keys--; if (did_putchar) { @@ -4835,13 +4818,14 @@ static int ins_ctrl_ey(int tc) // Used when inserting a "normal" character. static void ins_try_si(int c) { - pos_T *pos, old_pos; - char *ptr; - int i; - bool temp; + pos_T *pos; // do some very smart indenting when entering '{' or '}' if (((did_si || can_si_back) && c == '{') || (can_si && c == '}' && inindent(0))) { + pos_T old_pos; + char *ptr; + int i; + bool temp; // for '}' set indent equal to indent of line containing matching '{' if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) { old_pos = curwin->w_cursor; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4de4b7a080..3ab704e250 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1949,7 +1949,6 @@ void set_context_for_expression(expand_T *xp, char *arg, cmdidx_T cmdidx) FUNC_ATTR_NONNULL_ALL { bool got_eq = false; - int c; char *p; if (cmdidx == CMD_let || cmdidx == CMD_const) { @@ -1970,7 +1969,7 @@ void set_context_for_expression(expand_T *xp, char *arg, cmdidx_T cmdidx) : EXPAND_EXPRESSION; } while ((xp->xp_pattern = strpbrk(arg, "\"'+-*/%.=!?~|&$([<>,#")) != NULL) { - c = (uint8_t)(*xp->xp_pattern); + int c = (uint8_t)(*xp->xp_pattern); if (c == '&') { c = (uint8_t)xp->xp_pattern[1]; if (c == '&') { @@ -2310,7 +2309,6 @@ int eval0(char *arg, typval_T *rettv, char **nextcmd, int evaluate) /// @return OK or FAIL. int eval1(char **arg, typval_T *rettv, int evaluate) { - bool result; typval_T var2; // Get the first variable. @@ -2319,7 +2317,7 @@ int eval1(char **arg, typval_T *rettv, int evaluate) } if ((*arg)[0] == '?') { - result = false; + bool result = false; if (evaluate) { bool error = false; @@ -2499,7 +2497,6 @@ static int eval4(char **arg, typval_T *rettv, int evaluate) char *p; exprtype_T type = EXPR_UNKNOWN; int len = 2; - bool ic; // Get the first variable. if (eval5(arg, rettv, evaluate) == FAIL) { @@ -2552,6 +2549,7 @@ static int eval4(char **arg, typval_T *rettv, int evaluate) // If there is a comparative operator, use it. if (type != EXPR_UNKNOWN) { + bool ic; // extra question mark appended: ignore case if (p[len] == '?') { ic = true; @@ -2594,7 +2592,6 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) { typval_T var2; typval_T var3; - int op; varnumber_T n1, n2; float_T f1 = 0, f2 = 0; char *p; @@ -2606,7 +2603,7 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) // Repeat computing, until no '+', '-' or '.' is following. for (;;) { - op = (char_u)(**arg); + int op = (char_u)(**arg); if (op != '+' && op != '-' && op != '.') { break; } @@ -3276,7 +3273,6 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) { bool empty1 = false; bool empty2 = false; - long n1, n2 = 0; ptrdiff_t len = -1; int range = false; char *key = NULL; @@ -3373,16 +3369,17 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) } if (evaluate) { - n1 = 0; + int n2 = 0; + int n1 = 0; if (!empty1 && rettv->v_type != VAR_DICT && !tv_is_luafunc(rettv)) { - n1 = tv_get_number(&var1); + n1 = (int)tv_get_number(&var1); tv_clear(&var1); } if (range) { if (empty2) { n2 = -1; } else { - n2 = tv_get_number(&var2); + n2 = (int)tv_get_number(&var2); tv_clear(&var2); } } @@ -3397,20 +3394,20 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) // The resulting variable is a substring. If the indexes // are out of range the result is empty. if (n1 < 0) { - n1 = len + n1; + n1 = (int)len + n1; if (n1 < 0) { n1 = 0; } } if (n2 < 0) { - n2 = len + n2; + n2 = (int)len + n2; } else if (n2 >= len) { - n2 = len; + n2 = (int)len; } if (n1 >= len || n2 < 0 || n1 > n2) { v = NULL; } else { - v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1)); + v = xmemdupz(s + n1, (size_t)n2 - (size_t)n1 + 1); } } else { // The resulting variable is a string of a single @@ -3433,15 +3430,15 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) // The resulting variable is a sub-blob. If the indexes // are out of range the result is empty. if (n1 < 0) { - n1 = len + n1; + n1 = (int)len + n1; if (n1 < 0) { n1 = 0; } } if (n2 < 0) { - n2 = len + n2; + n2 = (int)len + n2; } else if (n2 >= len) { - n2 = len - 1; + n2 = (int)len - 1; } if (n1 >= len || n2 < 0 || n1 > n2) { tv_clear(rettv); @@ -3449,8 +3446,8 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) rettv->vval.v_blob = NULL; } else { blob_T *const blob = tv_blob_alloc(); - ga_grow(&blob->bv_ga, (int)(n2 - n1 + 1)); - blob->bv_ga.ga_len = (int)(n2 - n1 + 1); + ga_grow(&blob->bv_ga, n2 - n1 + 1); + blob->bv_ga.ga_len = n2 - n1 + 1; for (long i = n1; i <= n2; i++) { tv_blob_set(blob, (int)(i - n1), tv_blob_get(rettv->vval.v_blob, (int)i)); } @@ -3461,10 +3458,10 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) // The resulting variable is a byte value. // If the index is too big or negative that is an error. if (n1 < 0) { - n1 = len + n1; + n1 = (int)len + n1; } if (n1 < len && n1 >= 0) { - const int v = (int)tv_blob_get(rettv->vval.v_blob, (int)n1); + const int v = (int)tv_blob_get(rettv->vval.v_blob, n1); tv_clear(rettv); rettv->v_type = VAR_NUMBER; rettv->vval.v_number = v; @@ -3476,7 +3473,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) case VAR_LIST: len = tv_list_len(rettv->vval.v_list); if (n1 < 0) { - n1 = len + n1; + n1 = (int)len + n1; } if (!empty1 && (n1 < 0 || n1 >= len)) { // For a range we allow invalid values and return an empty @@ -3487,22 +3484,22 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) } return FAIL; } - n1 = len; + n1 = (int)len; } if (range) { list_T *l; listitem_T *item; if (n2 < 0) { - n2 = len + n2; + n2 = (int)len + n2; } else if (n2 >= len) { - n2 = len - 1; + n2 = (int)len - 1; } if (!empty2 && (n2 < 0 || n2 + 1 < n1)) { n2 = -1; } l = tv_list_alloc(n2 - n1 + 1); - item = tv_list_find(rettv->vval.v_list, (int)n1); + item = tv_list_find(rettv->vval.v_list, n1); while (n1++ <= n2) { tv_list_append_tv(l, TV_LIST_ITEM_TV(item)); item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item); @@ -3915,7 +3912,7 @@ char *partial_name(partial_T *pt) if (pt->pt_name != NULL) { return pt->pt_name; } - return (char *)pt->pt_func->uf_name; + return pt->pt_func->uf_name; } static void partial_free(partial_T *pt) @@ -4784,8 +4781,6 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map) const char *const arg_errmsg = (map ? N_("map() argument") : N_("filter() argument")); - int save_did_emsg; - int idx = 0; // Always return the first argument, also on failure. tv_copy(&argvars[0], rettv); @@ -4815,12 +4810,13 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map) // message. Avoid a misleading error message for an empty string that // was not passed as argument. if (expr->v_type != VAR_UNKNOWN) { + int idx = 0; typval_T save_val; prepare_vimvar(VV_VAL, &save_val); // We reset "did_emsg" to be able to detect whether an error // occurred during evaluation of the expression. - save_did_emsg = did_emsg; + int save_did_emsg = did_emsg; did_emsg = false; typval_T save_key; @@ -5052,7 +5048,7 @@ void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref) if (tv_list_len(list) == 0) { arg_idx = 0; } else if (tv_list_len(list) > MAX_FUNC_ARGS) { - emsg_funcname((char *)e_toomanyarg, s); + emsg_funcname(e_toomanyarg, s); xfree(name); goto theend; } @@ -6220,25 +6216,25 @@ int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp, bool c } int i = 0; - long n; + int n; if (fnump != NULL) { - n = tv_list_find_nr(l, i++, NULL); // fnum + n = (int)tv_list_find_nr(l, i++, NULL); // fnum if (n < 0) { return FAIL; } if (n == 0) { n = curbuf->b_fnum; // Current buffer. } - *fnump = (int)n; + *fnump = n; } - n = tv_list_find_nr(l, i++, NULL); // lnum + n = (int)tv_list_find_nr(l, i++, NULL); // lnum if (n < 0) { return FAIL; } - posp->lnum = (linenr_T)n; + posp->lnum = n; - n = tv_list_find_nr(l, i++, NULL); // col + n = (int)tv_list_find_nr(l, i++, NULL); // col if (n < 0) { return FAIL; } @@ -6252,15 +6248,15 @@ int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp, bool c } n = buf_charidx_to_byteidx(buf, posp->lnum == 0 ? curwin->w_cursor.lnum : posp->lnum, - (int)n) + 1; + n) + 1; } - posp->col = (colnr_T)n; + posp->col = n; - n = tv_list_find_nr(l, i, NULL); // off + n = (int)tv_list_find_nr(l, i, NULL); // off if (n < 0) { posp->coladd = 0; } else { - posp->coladd = (colnr_T)n; + posp->coladd = n; } if (curswantp != NULL) { @@ -8064,7 +8060,6 @@ repeat: /// @return an allocated string, NULL for error. char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char *flags) { - int sublen; regmatch_T regmatch; garray_T ga; char *zero_width = NULL; @@ -8080,6 +8075,7 @@ char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char regmatch.rm_ic = p_ic; regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); if (regmatch.regprog != NULL) { + int sublen; char *tail = str; char *end = str + strlen(str); while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) { diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 48f3cd4293..6f983d3208 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -492,7 +492,7 @@ buf_T *get_buf_arg(typval_T *arg) /// "byte2line(byte)" function static void f_byte2line(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - long boff = tv_get_number(&argvars[0]) - 1; + long boff = (long)tv_get_number(&argvars[0]) - 1; if (boff < 0) { rettv->vval.v_number = -1; } else { @@ -978,11 +978,11 @@ static void f_count(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) listitem_T *li = tv_list_first(l); if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[3].v_type != VAR_UNKNOWN) { - long idx = tv_get_number_chk(&argvars[3], &error); + int64_t idx = tv_get_number_chk(&argvars[3], &error); if (!error) { li = tv_list_find(l, (int)idx); if (li == NULL) { - semsg(_(e_listidx), (int64_t)idx); + semsg(_(e_listidx), idx); } } } @@ -3589,7 +3589,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) semsg(_(e_listblobarg), "insert()"); } else if (!value_check_lock(tv_list_locked((l = argvars[0].vval.v_list)), N_("insert() argument"), TV_TRANSLATE)) { - long before = 0; + int64_t before = 0; if (argvars[2].v_type != VAR_UNKNOWN) { before = tv_get_number_chk(&argvars[2], &error); } @@ -3602,7 +3602,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (before != tv_list_len(l)) { item = tv_list_find(l, (int)before); if (item == NULL) { - semsg(_(e_listidx), (int64_t)before); + semsg(_(e_listidx), before); l = NULL; } } @@ -4371,11 +4371,11 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, const SomeMatchType type) { char *str = NULL; - long len = 0; + int64_t len = 0; char *expr = NULL; regmatch_T regmatch; - long start = 0; - long nth = 1; + int64_t start = 0; + int64_t nth = 1; colnr_T startcol = 0; bool match = false; list_T *l = NULL; @@ -5387,7 +5387,7 @@ static void read_file_or_blob(typval_T *argvars, typval_T *rettv, bool always_bl char *prev = NULL; // previously read bytes, if any ptrdiff_t prevlen = 0; // length of data in prev ptrdiff_t prevsize = 0; // size of prev buffer - long maxline = MAXLNUM; + int64_t maxline = MAXLNUM; if (argvars[1].v_type != VAR_UNKNOWN) { if (strcmp(tv_get_string(&argvars[1]), "b") == 0) { @@ -6161,8 +6161,8 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) { bool save_p_ws = p_ws; int retval = 0; // default: FAIL - long lnum_stop = 0; - long time_limit = 0; + linenr_T lnum_stop = 0; + int64_t time_limit = 0; int options = SEARCH_KEEP; bool use_skip = false; @@ -6184,7 +6184,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) // Optional arguments: line number to stop searching, timeout and skip. if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { - lnum_stop = tv_get_number_chk(&argvars[2], NULL); + lnum_stop = (linenr_T)tv_get_number_chk(&argvars[2], NULL); if (lnum_stop < 0) { goto theend; } @@ -6214,7 +6214,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) pos_T pos = save_cursor = curwin->w_cursor; pos_T firstpos = { 0 }; searchit_arg_T sia = { - .sa_stop_lnum = (linenr_T)lnum_stop, + .sa_stop_lnum = lnum_stop, .sa_tm = &tm, }; @@ -6652,8 +6652,8 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) bool save_p_ws = p_ws; int flags = 0; int retval = 0; // default: FAIL - long lnum_stop = 0; - long time_limit = 0; + linenr_T lnum_stop = 0; + int64_t time_limit = 0; // Get the three pattern arguments: start, middle, end. Will result in an // error if not a valid argument. @@ -6695,7 +6695,7 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) skip = &argvars[4]; if (argvars[5].v_type != VAR_UNKNOWN) { - lnum_stop = tv_get_number_chk(&argvars[5], NULL); + lnum_stop = (linenr_T)tv_get_number_chk(&argvars[5], NULL); if (lnum_stop < 0) { semsg(_(e_invarg2), tv_get_string(&argvars[5])); goto theend; @@ -6711,7 +6711,7 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) } retval = (int)do_searchpair(spat, mpat, epat, dir, skip, - flags, match_pos, (linenr_T)lnum_stop, time_limit); + flags, match_pos, lnum_stop, time_limit); theend: p_ws = save_p_ws; @@ -6758,7 +6758,7 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv, EvalFuncData fpt /// @returns 0 or -1 for no match, long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir, const typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, - long time_limit) + int64_t time_limit) FUNC_ATTR_NONNULL_ARG(1, 2, 3) { long retval = 0; @@ -8695,7 +8695,8 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (!callback_from_typval(&callback, &argvars[1])) { return; } - rettv->vval.v_number = (varnumber_T)timer_start(tv_get_number(&argvars[0]), repeat, &callback); + rettv->vval.v_number = (varnumber_T)timer_start((const long)tv_get_number(&argvars[0]), repeat, + &callback); } /// "timer_stop(timerid)" function @@ -8768,7 +8769,7 @@ static void f_tr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) tolen = utfc_ptr2len(p); if (idx-- == 0) { cplen = tolen; - cpstr = (char *)p; + cpstr = p; break; } } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index c298064d86..9a3a1c3c0f 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -751,8 +751,8 @@ int tv_list_concat(list_T *const l1, list_T *const l2, typval_T *const tv) } typedef struct { - char_u *s; - char_u *tofree; + char *s; + char *tofree; } Join; /// Join list into a string, helper function @@ -785,7 +785,7 @@ static int list_join_inner(garray_T *const gap, list_T *const l, const char *con sumlen += len; Join *const p = GA_APPEND_VIA_PTR(Join, join_gap); - p->tofree = p->s = (char_u *)s; + p->tofree = p->s = s; line_breakcheck(); }); @@ -806,7 +806,7 @@ static int list_join_inner(garray_T *const gap, list_T *const l, const char *con const Join *const p = ((const Join *)join_gap->ga_data) + i; if (p->s != NULL) { - ga_concat(gap, (char *)p->s); + ga_concat(gap, p->s); } line_breakcheck(); } @@ -905,14 +905,14 @@ void tv_list_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg) return; } - long idx = tv_get_number_chk(&argvars[1], &error); + int64_t idx = tv_get_number_chk(&argvars[1], &error); listitem_T *item; if (error) { // Type error: do nothing, errmsg already given. } else if ((item = tv_list_find(l, (int)idx)) == NULL) { - semsg(_(e_listidx), (int64_t)idx); + semsg(_(e_listidx), idx); } else { if (argvars[2].v_type == VAR_UNKNOWN) { // Remove one item, return its value. @@ -922,11 +922,11 @@ void tv_list_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg) } else { listitem_T *item2; // Remove range of items, return list with values. - long end = tv_get_number_chk(&argvars[2], &error); + int64_t end = tv_get_number_chk(&argvars[2], &error); if (error) { // Type error: do nothing. } else if ((item2 = tv_list_find(l, (int)end)) == NULL) { - semsg(_(e_listidx), (int64_t)end); + semsg(_(e_listidx), end); } else { int cnt = 0; @@ -1140,7 +1140,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) { ListSortItem *ptrs; long len; - long i; + int i; // Pointer to current info struct used in compare function. Save and restore // the current one for nested calls. @@ -1184,7 +1184,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } else { bool error = false; - i = tv_get_number_chk(&argvars[1], &error); + i = (int)tv_get_number_chk(&argvars[1], &error); if (error) { goto theend; // type error; errmsg already given } @@ -1673,7 +1673,7 @@ char *callback_to_string(Callback *cb) } const size_t msglen = 100; - char *msg = (char *)xmallocz(msglen); + char *msg = xmallocz(msglen); switch (cb->type) { case kCallbackFuncref: @@ -2715,7 +2715,7 @@ void tv_blob_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg) } bool error = false; - long idx = tv_get_number_chk(&argvars[1], &error); + int64_t idx = tv_get_number_chk(&argvars[1], &error); if (!error) { const int len = tv_blob_len(b); @@ -2725,7 +2725,7 @@ void tv_blob_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg) idx = len + idx; } if (idx < 0 || idx >= len) { - semsg(_(e_blobidx), (int64_t)idx); + semsg(_(e_blobidx), idx); return; } if (argvars[2].v_type == VAR_UNKNOWN) { @@ -2736,7 +2736,7 @@ void tv_blob_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg) b->bv_ga.ga_len--; } else { // Remove range of items, return blob with values. - long end = tv_get_number_chk(&argvars[2], &error); + int64_t end = tv_get_number_chk(&argvars[2], &error); if (error) { return; } @@ -2745,7 +2745,7 @@ void tv_blob_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg) end = len + end; } if (end >= len || idx > end) { - semsg(_(e_blobidx), (int64_t)end); + semsg(_(e_blobidx), end); return; } blob_T *const blob = tv_blob_alloc(); diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 957733ecd5..3c4cc34464 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -729,7 +729,6 @@ static void cleanup_function_call(funccall_T *fc) /// @param[in] force When true, we are exiting. static void funccal_unref(funccall_T *fc, ufunc_T *fp, bool force) { - funccall_T **pfc; int i; if (fc == NULL) { @@ -738,7 +737,7 @@ static void funccal_unref(funccall_T *fc, ufunc_T *fp, bool force) fc->fc_refcount--; if (force ? fc->fc_refcount <= 0 : !fc_referenced(fc)) { - for (pfc = &previous_funccal; *pfc != NULL; pfc = &(*pfc)->caller) { + for (funccall_T **pfc = &previous_funccal; *pfc != NULL; pfc = &(*pfc)->caller) { if (fc == *pfc) { *pfc = fc->caller; free_funccal_contents(fc); @@ -880,7 +879,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett fc->rettv = rettv; fc->level = ex_nesting_level; // Check if this function has a breakpoint. - fc->breakpoint = dbg_find_breakpoint(false, (char *)fp->uf_name, (linenr_T)0); + fc->breakpoint = dbg_find_breakpoint(false, fp->uf_name, (linenr_T)0); fc->dbg_tick = debug_tick; // Set up fields for closure. @@ -1075,7 +1074,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett bool func_not_yet_profiling_but_should = do_profiling_yes - && !fp->uf_profiling && has_profiling(false, (char *)fp->uf_name, NULL); + && !fp->uf_profiling && has_profiling(false, fp->uf_name, NULL); if (func_not_yet_profiling_but_should) { started_profiling = true; @@ -1669,7 +1668,7 @@ static void list_func_head(ufunc_T *fp, int indent, bool force) if (fp->uf_name_exp != NULL) { msg_puts((const char *)fp->uf_name_exp); } else { - msg_puts((const char *)fp->uf_name); + msg_puts(fp->uf_name); } msg_putchar('('); int j; @@ -1999,10 +1998,10 @@ static void list_functions(regmatch_T *regmatch) todo--; if ((fp->uf_flags & FC_DEAD) == 0 && (regmatch == NULL - ? (!message_filtered((char *)fp->uf_name) + ? (!message_filtered(fp->uf_name) && !func_name_refcount(fp->uf_name)) : (!isdigit((uint8_t)(*fp->uf_name)) - && vim_regexec(regmatch, (char *)fp->uf_name, 0)))) { + && vim_regexec(regmatch, fp->uf_name, 0)))) { list_func_head(fp, false, false); if (changed != func_hashtab.ht_changed) { emsg(_("E454: function list was modified")); @@ -2194,7 +2193,7 @@ void ex_function(exarg_T *eap) j++; } if (arg[j] != NUL) { - emsg_funcname((char *)e_invarg2, arg); + emsg_funcname(e_invarg2, arg); } } // Disallow using the g: dict. @@ -2748,7 +2747,7 @@ char *get_user_func_name(expand_T *xp, int idx) } if (strlen(fp->uf_name) + 4 >= IOSIZE) { - return (char *)fp->uf_name; // Prevent overflow. + return fp->uf_name; // Prevent overflow. } cat_func_name(IObuff, fp); @@ -3228,7 +3227,7 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat) // If breakpoints have been added/deleted need to check for it. if (fcp->dbg_tick != debug_tick) { - fcp->breakpoint = dbg_find_breakpoint(false, (char *)fp->uf_name, SOURCING_LNUM); + fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name, SOURCING_LNUM); fcp->dbg_tick = debug_tick; } if (do_profiling == PROF_YES) { @@ -3258,9 +3257,9 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat) // Did we encounter a breakpoint? if (fcp->breakpoint != 0 && fcp->breakpoint <= SOURCING_LNUM) { - dbg_breakpoint((char *)fp->uf_name, SOURCING_LNUM); + dbg_breakpoint(fp->uf_name, SOURCING_LNUM); // Find next breakpoint. - fcp->breakpoint = dbg_find_breakpoint(false, (char *)fp->uf_name, SOURCING_LNUM); + fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name, SOURCING_LNUM); fcp->dbg_tick = debug_tick; } @@ -3289,7 +3288,6 @@ int func_has_abort(void *cookie) /// Changes "rettv" in-place. void make_partial(dict_T *const selfdict, typval_T *const rettv) { - char *fname; char *tofree = NULL; ufunc_T *fp; char fname_buf[FLEN_FIXED + 1]; @@ -3298,7 +3296,7 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv) if (rettv->v_type == VAR_PARTIAL && rettv->vval.v_partial->pt_func != NULL) { fp = rettv->vval.v_partial->pt_func; } else { - fname = rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING + char *fname = rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING ? rettv->vval.v_string : rettv->vval.v_partial->pt_name; // Translate "s:func" to the stored function name. @@ -3319,7 +3317,6 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv) pt->pt_name = rettv->vval.v_string; } else { partial_T *ret_pt = rettv->vval.v_partial; - int i; // Partial: copy the function name, use selfdict and copy // args. Can't take over name or args, the partial might @@ -3335,7 +3332,7 @@ void make_partial(dict_T *const selfdict, typval_T *const rettv) size_t arg_size = sizeof(typval_T) * (size_t)ret_pt->pt_argc; pt->pt_argv = (typval_T *)xmalloc(arg_size); pt->pt_argc = ret_pt->pt_argc; - for (i = 0; i < pt->pt_argc; i++) { + for (int i = 0; i < pt->pt_argc; i++) { tv_copy(&ret_pt->pt_argv[i], &pt->pt_argv[i]); } } @@ -3641,14 +3638,13 @@ bool set_ref_in_func(char *name, ufunc_T *fp_in, int copyID) int error = FCERR_NONE; char fname_buf[FLEN_FIXED + 1]; char *tofree = NULL; - char *fname; bool abort = false; if (name == NULL && fp_in == NULL) { return false; } if (fp_in == NULL) { - fname = fname_trans_sid(name, fname_buf, &tofree, &error); + char *fname = fname_trans_sid(name, fname_buf, &tofree, &error); fp = find_func(fname); } if (fp != NULL) { diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 9ed245d6c4..d80bdc70f6 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -369,12 +369,10 @@ int ex_let_vars(char *arg_start, typval_T *tv, int copy, int semicolon, int var_ /// @return NULL for an error. const char *skip_var_list(const char *arg, int *var_count, int *semicolon) { - const char *p; - const char *s; - if (*arg == '[') { + const char *s; // "[var, var]": find the matching ']'. - p = arg; + const char *p = arg; for (;;) { p = skipwhite(p + 1); // skip whites after '[', ';' or ',' s = skip_var_one((char *)p); @@ -575,7 +573,6 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT { char *arg_end = NULL; - int len; // ":let $VAR = expr": Set environment variable. if (*arg == '$') { @@ -586,7 +583,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo // Find the end of the name. arg++; char *name = arg; - len = get_env_len((const char **)&arg); + int len = get_env_len((const char **)&arg); if (len == 0) { semsg(_(e_invarg2), name - 1); } else { @@ -696,7 +693,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo if (!failed) { if (opt_type != gov_string || s != NULL) { - char *err = set_option_value(arg, n, s, scope); + char *err = set_option_value(arg, (long)n, s, scope); arg_end = p; if (err != NULL) { emsg(_(err)); @@ -722,12 +719,10 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo && vim_strchr(endchars, (uint8_t)(*skipwhite(arg + 1))) == NULL) { emsg(_(e_letunexp)); } else { - char *s; - char *ptofree = NULL; const char *p = tv_get_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { - s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); + char *s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); if (s != NULL) { ptofree = concat_str(s, p); p = (const char *)ptofree; @@ -861,10 +856,9 @@ static int do_unlet_var(lval_T *lp, char *name_end, exarg_T *eap, int deep FUNC_ { int forceit = eap->forceit; int ret = OK; - int cc; if (lp->ll_tv == NULL) { - cc = (uint8_t)(*name_end); + int cc = (uint8_t)(*name_end); *name_end = NUL; // Environment variable, normal name or expanded name. diff --git a/src/nvim/eval/window.c b/src/nvim/eval/window.c index f58a0c488a..c1d2e5b38f 100644 --- a/src/nvim/eval/window.c +++ b/src/nvim/eval/window.c @@ -192,9 +192,9 @@ win_T *find_tabwin(typval_T *wvp, typval_T *tvp) if (wvp->v_type != VAR_UNKNOWN) { if (tvp->v_type != VAR_UNKNOWN) { - long n = tv_get_number(tvp); + int n = (int)tv_get_number(tvp); if (n >= 0) { - tp = find_tabpage((int)n); + tp = find_tabpage(n); } } else { tp = curtab; diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 1a524a56ca..1219566e9b 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -422,7 +422,12 @@ static void exit_event(void **argv) } if (!exiting) { - os_exit(status); + if (ui_client_channel_id) { + os_exit(status); + } else { + assert(status == 0); // Called from rpc_close(), which passes 0 as status. + preserve_exit(NULL); + } } } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index ae7abfc5e7..67d1a1e2f7 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -724,7 +724,6 @@ sortend: /// @return FAIL for failure, OK otherwise int do_move(linenr_T line1, linenr_T line2, linenr_T dest) { - char *str; linenr_T l; linenr_T extra; // Num lines added before line1 linenr_T num_lines; // Num lines moved @@ -761,7 +760,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) return FAIL; } for (extra = 0, l = line1; l <= line2; l++) { - str = xstrdup(ml_get(l + extra)); + char *str = xstrdup(ml_get(l + extra)); ml_append(dest + l - line1, str, (colnr_T)0, false); xfree(str); if (dest < line1) { @@ -875,10 +874,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) /// ":copy" void ex_copy(linenr_T line1, linenr_T line2, linenr_T n) { - linenr_T count; - char *p; - - count = line2 - line1 + 1; + linenr_T count = line2 - line1 + 1; if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { curbuf->b_op_start.lnum = n + 1; curbuf->b_op_end.lnum = n + count; @@ -902,7 +898,7 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n) while (line1 <= line2) { // need to use xstrdup() because the line will be unlocked within // ml_append() - p = xstrdup(ml_get(line1)); + char *p = xstrdup(ml_get(line1)); ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, false); xfree(p); @@ -952,7 +948,6 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out char *t; char *p; char *trailarg; - size_t len; int scroll_save = msg_scroll; // @@ -975,7 +970,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out // Skip leading white space to avoid a strange error with some shells. trailarg = skipwhite(arg); do { - len = strlen(trailarg) + 1; + size_t len = strlen(trailarg) + 1; if (newcmd != NULL) { len += strlen(newcmd); } @@ -1823,7 +1818,7 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, int oth if (p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) { char buff[DIALOG_MSG_SIZE]; - dialog_msg((char *)buff, _("Overwrite existing file \"%s\"?"), fname); + dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname); if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES) { return FAIL; } @@ -1859,7 +1854,7 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, int oth if (p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) { char buff[DIALOG_MSG_SIZE]; - dialog_msg((char *)buff, + dialog_msg(buff, _("Swap file \"%s\" exists, overwrite anyway?"), swapname); if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) @@ -1979,11 +1974,11 @@ static int check_readonly(int *forceit, buf_T *buf) char buff[DIALOG_MSG_SIZE]; if (buf->b_p_ro) { - dialog_msg((char *)buff, + dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"), buf->b_fname); } else { - dialog_msg((char *)buff, + dialog_msg(buff, _("File permissions of \"%s\" are read-only.\nIt may still be possible to " "write it.\nDo you wish to try?"), buf->b_fname); @@ -2736,7 +2731,6 @@ void ex_append(exarg_T *eap) linenr_T lnum = eap->line2; int indent = 0; char *p; - int vcol; int empty = (curbuf->b_ml.ml_flags & ML_EMPTY); // the ! flag toggles autoindent @@ -2803,7 +2797,7 @@ void ex_append(exarg_T *eap) } // Look for the "." after automatic indent. - vcol = 0; + int vcol = 0; for (p = theline; indent > vcol; p++) { if (*p == ' ') { vcol++; @@ -2945,7 +2939,7 @@ void ex_z(exarg_T *eap) bigness = 2 * curbuf->b_ml.ml_line_count; } - p_window = bigness; + p_window = (int)bigness; if (*kind == '=') { bigness += 2; } @@ -4339,7 +4333,6 @@ static void global_exe_one(char *const cmd, const linenr_T lnum) void ex_global(exarg_T *eap) { linenr_T lnum; // line number according to old situation - int ndone = 0; int type; // first char of cmd: 'v' or 'g' char *cmd; // command argument @@ -4411,6 +4404,7 @@ void ex_global(exarg_T *eap) global_exe_one(cmd, lnum); } } else { + int ndone = 0; // pass 1: set marks for each (not) matching line for (lnum = eap->line1; lnum <= eap->line2 && !got_int; lnum++) { // a match on this line? @@ -4687,8 +4681,6 @@ int ex_substitute_preview(exarg_T *eap, long cmdpreview_ns, handle_T cmdpreview_ /// @return a pointer to the char just past the pattern plus flags. char *skip_vimgrep_pat(char *p, char **s, int *flags) { - int c; - if (vim_isIDc((uint8_t)(*p))) { // ":vimgrep pattern fname" if (s != NULL) { @@ -4703,7 +4695,7 @@ char *skip_vimgrep_pat(char *p, char **s, int *flags) if (s != NULL) { *s = p + 1; } - c = (uint8_t)(*p); + int c = (uint8_t)(*p); p = skip_regexp(p + 1, c, true); if (*p != c) { return NULL; diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index d08823bc30..c777efb445 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -446,12 +446,9 @@ int buf_write_all(buf_T *buf, int forceit) /// ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo" void ex_listdo(exarg_T *eap) { - int i; win_T *wp; tabpage_T *tp; - int next_fnum = 0; char *save_ei = NULL; - char *p_shm_save; if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo) { // Don't do syntax HL autocommands. Skipping the syntax file is a @@ -469,7 +466,9 @@ void ex_listdo(exarg_T *eap) || !check_changed(curbuf, CCGD_AW | (eap->forceit ? CCGD_FORCEIT : 0) | CCGD_EXCMD)) { - i = 0; + int next_fnum = 0; + char *p_shm_save; + int i = 0; // start at the eap->line1 argument/window/buffer wp = firstwin; tp = first_tabpage; @@ -762,14 +761,13 @@ void ex_compiler(exarg_T *eap) /// ":checktime [buffer]" void ex_checktime(exarg_T *eap) { - buf_T *buf; int save_no_check_timestamps = no_check_timestamps; no_check_timestamps = 0; if (eap->addr_count == 0) { // default is all buffers check_timestamps(false); } else { - buf = buflist_findnr((int)eap->line2); + buf_T *buf = buflist_findnr((int)eap->line2); if (buf != NULL) { // cannot happen? (void)buf_check_timestamp(buf); } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 017787f238..f460b4b93f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1311,16 +1311,16 @@ static void parse_register(exarg_T *eap) } // Change line1 and line2 of Ex command to use count -void set_cmd_count(exarg_T *eap, long count, bool validate) +void set_cmd_count(exarg_T *eap, linenr_T count, bool validate) { if (eap->addr_type != ADDR_LINES) { // e.g. :buffer 2, :sleep 3 - eap->line2 = (linenr_T)count; + eap->line2 = count; if (eap->addr_count == 0) { eap->addr_count = 1; } } else { eap->line1 = eap->line2; - eap->line2 += (linenr_T)count - 1; + eap->line2 += count - 1; eap->addr_count++; // Be vi compatible: no error message for out of range. if (validate && eap->line2 > curbuf->b_ml.ml_line_count) { @@ -1338,7 +1338,7 @@ static int parse_count(exarg_T *eap, char **errormsg, bool validate) if ((eap->argt & EX_COUNT) && ascii_isdigit(*eap->arg) && (!(eap->argt & EX_BUFNAME) || *(p = skipdigits(eap->arg + 1)) == NUL || ascii_iswhite(*p))) { - long n = getdigits_long(&eap->arg, false, -1); + linenr_T n = getdigits_int32(&eap->arg, false, -1); eap->arg = skipwhite(eap->arg); if (eap->args != NULL) { @@ -3200,7 +3200,7 @@ char *skip_range(const char *cmd, int *ctx) } // Skip ":" and white space. - cmd = skip_colon_white((char *)cmd, false); + cmd = skip_colon_white(cmd, false); return (char *)cmd; } @@ -4011,7 +4011,7 @@ static char *getargcmd(char **argp) if (*arg == '+') { // +[command] arg++; if (ascii_isspace(*arg) || *arg == '\0') { - command = (char *)dollar_command; + command = dollar_command; } else { command = arg; arg = skip_cmd_arg(command, true); @@ -4401,7 +4401,7 @@ static int check_more(int message, bool forceit) if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && curbuf->b_fname != NULL) { char buff[DIALOG_MSG_SIZE]; - vim_snprintf((char *)buff, DIALOG_MSG_SIZE, + vim_snprintf(buff, DIALOG_MSG_SIZE, NGETTEXT("%d more file to edit. Quit anyway?", "%d more files to edit. Quit anyway?", n), n); if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES) { @@ -4769,7 +4769,7 @@ void tabpage_close_other(tabpage_T *tp, int forceit) // Limit to 1000 windows, autocommands may add a window while we close // one. OK, so I'm paranoid... while (++done < 1000) { - snprintf((char *)prev_idx, sizeof(prev_idx), "%i", tabpage_index(tp)); + snprintf(prev_idx, sizeof(prev_idx), "%i", tabpage_index(tp)); win_T *wp = tp->tp_lastwin; ex_win_close(forceit, wp, tp); @@ -6748,7 +6748,7 @@ char *eval_vars(char *src, const char *srcstart, size_t *usedlen, linenr_T *lnum // Note: In "\\%" the % is also not recognized! if (src > srcstart && src[-1] == '\\') { *usedlen = 0; - STRMOVE(src - 1, (char *)src); // remove backslash + STRMOVE(src - 1, src); // remove backslash return NULL; } @@ -6925,7 +6925,7 @@ char *eval_vars(char *src, const char *srcstart, size_t *usedlen, linenr_T *lnum *errormsg = _("E961: no line number to use for \"<sflnum>\""); return NULL; } - snprintf((char *)strbuf, sizeof(strbuf), "%" PRIdLINENR, + snprintf(strbuf, sizeof(strbuf), "%" PRIdLINENR, current_sctx.sc_lnum + SOURCING_LNUM); result = strbuf; break; diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index f76e60f6c5..1cef99297a 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -278,9 +278,8 @@ bool cause_errthrow(const char *mesg, bool severe, bool *ignore) /// Free a "msg_list" and the messages it contains. static void free_msglist(msglist_T *l) { - msglist_T *messages, *next; - - messages = l; + msglist_T *next; + msglist_T *messages = l; while (messages != NULL) { next = messages->next; xfree(messages->msg); @@ -379,9 +378,10 @@ int do_intthrow(cstack_T *cstack) char *get_exception_string(void *value, except_type_T type, char *cmdname, int *should_free) { char *ret, *mesg; - char *p, *val; if (type == ET_ERROR) { + char *p; + char *val; *should_free = true; mesg = ((msglist_T *)value)->throw_msg; if (cmdname != NULL && *cmdname != NUL) { @@ -441,9 +441,6 @@ char *get_exception_string(void *value, except_type_T type, char *cmdname, int * /// exception. static int throw_exception(void *value, except_type_T type, char *cmdname) { - except_T *excp; - int should_free; - // Disallow faking Interrupt or error exceptions as user exceptions. They // would be treated differently from real interrupt or error exceptions // when no active try block is found, see do_cmdline(). @@ -456,7 +453,7 @@ static int throw_exception(void *value, except_type_T type, char *cmdname) } } - excp = xmalloc(sizeof(except_T)); + except_T *excp = xmalloc(sizeof(except_T)); if (type == ET_ERROR) { // Store the original message and prefix the exception value with @@ -464,6 +461,7 @@ static int throw_exception(void *value, except_type_T type, char *cmdname) excp->messages = (msglist_T *)value; } + int should_free; excp->value = get_exception_string(value, type, cmdname, &should_free); if (excp->value == NULL && should_free) { goto nomem; @@ -525,8 +523,6 @@ fail: /// caught and the catch clause has been ended normally. static void discard_exception(except_T *excp, bool was_finished) { - char *saved_IObuff; - if (current_exception == excp) { current_exception = NULL; } @@ -538,7 +534,7 @@ static void discard_exception(except_T *excp, bool was_finished) if (p_verbose >= 13 || debug_break_level > 0) { int save_msg_silent = msg_silent; - saved_IObuff = xstrdup(IObuff); + char *saved_IObuff = xstrdup(IObuff); if (debug_break_level > 0) { msg_silent = false; // display messages } else { @@ -677,7 +673,6 @@ static void report_pending(int action, int pending, void *value) { char *mesg; char *s; - int save_msg_silent; assert(value || !(pending & CSTP_THROW)); @@ -727,7 +722,7 @@ static void report_pending(int action, int pending, void *value) } } - save_msg_silent = msg_silent; + int save_msg_silent = msg_silent; if (debug_break_level > 0) { msg_silent = false; // display messages } @@ -806,8 +801,6 @@ void ex_eval(exarg_T *eap) /// Handle ":if". void ex_if(exarg_T *eap) { - int skip; - int result; cstack_T *const cstack = eap->cstack; if (cstack->cs_idx == CSTACK_LEN - 1) { @@ -816,10 +809,10 @@ void ex_if(exarg_T *eap) cstack->cs_idx++; cstack->cs_flags[cstack->cs_idx] = 0; - skip = CHECK_SKIP; + int skip = CHECK_SKIP; bool error; - result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); + int result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); if (!skip && !error) { if (result) { @@ -860,7 +853,6 @@ void ex_endif(exarg_T *eap) /// Handle ":else" and ":elseif". void ex_else(exarg_T *eap) { - bool result = false; cstack_T *const cstack = eap->cstack; bool skip = CHECK_SKIP; @@ -907,6 +899,7 @@ void ex_else(exarg_T *eap) } if (eap->cmdidx == CMD_elseif) { + bool result = false; bool error; // When skipping we ignore most errors, but a missing expression is // wrong, perhaps it should have been "else". @@ -941,13 +934,12 @@ void ex_else(exarg_T *eap) void ex_while(exarg_T *eap) { bool error; - int skip; - int result; cstack_T *const cstack = eap->cstack; if (cstack->cs_idx == CSTACK_LEN - 1) { eap->errmsg = _("E585: :while/:for nesting too deep"); } else { + int result; // The loop flag is set when we have jumped back from the matching // ":endwhile" or ":endfor". When not set, need to initialise this // cstack entry. @@ -959,7 +951,7 @@ void ex_while(exarg_T *eap) cstack->cs_flags[cstack->cs_idx] = eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR; - skip = CHECK_SKIP; + int skip = CHECK_SKIP; if (eap->cmdidx == CMD_while) { // ":while bool-expr" result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); @@ -1013,7 +1005,6 @@ void ex_while(exarg_T *eap) /// Handle ":continue" void ex_continue(exarg_T *eap) { - int idx; cstack_T *const cstack = eap->cstack; if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) { @@ -1023,7 +1014,7 @@ void ex_continue(exarg_T *eap) // conditional not in its finally clause (which is then to be executed // next). Therefore, deactivate all conditionals except the ":while" // itself (if reached). - idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, false); + int idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, false); assert(idx >= 0); if (cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)) { rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel); @@ -1043,7 +1034,6 @@ void ex_continue(exarg_T *eap) /// Handle ":break" void ex_break(exarg_T *eap) { - int idx; cstack_T *const cstack = eap->cstack; if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) { @@ -1053,7 +1043,7 @@ void ex_break(exarg_T *eap) // conditional not in its finally clause (which is then to be // executed next) is found. In the latter case, make the ":break" // pending for execution at the ":endtry". - idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, true); + int idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, true); if (idx >= 0 && !(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) { cstack->cs_pending[idx] = CSTP_BREAK; report_make_pending(CSTP_BREAK, NULL); @@ -1065,10 +1055,8 @@ void ex_break(exarg_T *eap) void ex_endwhile(exarg_T *eap) { cstack_T *const cstack = eap->cstack; - int idx; char *err; int csf; - int fl; if (eap->cmdidx == CMD_endwhile) { err = e_while; @@ -1081,7 +1069,7 @@ void ex_endwhile(exarg_T *eap) if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) { eap->errmsg = _(err); } else { - fl = cstack->cs_flags[cstack->cs_idx]; + int fl = cstack->cs_flags[cstack->cs_idx]; if (!(fl & csf)) { // If we are in a ":while" or ":for" but used the wrong endloop // command, do not rewind to the next enclosing ":for"/":while". @@ -1098,6 +1086,7 @@ void ex_endwhile(exarg_T *eap) eap->errmsg = _(e_endtry); } // Try to find the matching ":while" and report what's missing. + int idx; for (idx = cstack->cs_idx; idx > 0; idx--) { fl = cstack->cs_flags[idx]; if ((fl & CSF_TRY) && !(fl & CSF_FINALLY)) { @@ -1163,10 +1152,8 @@ void ex_throw(exarg_T *eap) /// used for rethrowing an uncaught exception. void do_throw(cstack_T *cstack) { - int idx; int inactivate_try = false; - // // Cleanup and deactivate up to the next surrounding try conditional that // is not in its finally clause. Normally, do not deactivate the try // conditional itself, so that its ACTIVE flag can be tested below. But @@ -1174,7 +1161,7 @@ void do_throw(cstack_T *cstack) // deactivate the try conditional, too, as if the conversion had been done, // and reset the did_emsg or got_int flag, so this won't happen again at // the next surrounding try conditional. - // + #ifndef THROW_ON_ERROR_TRUE if (did_emsg && !THROW_ON_ERROR) { inactivate_try = true; @@ -1187,7 +1174,7 @@ void do_throw(cstack_T *cstack) got_int = false; } #endif - idx = cleanup_conditionals(cstack, 0, inactivate_try); + int idx = cleanup_conditionals(cstack, 0, inactivate_try); if (idx >= 0) { // If this try conditional is active and we are before its first // ":catch", set THROWN so that the ":catch" commands will check @@ -1220,7 +1207,6 @@ void do_throw(cstack_T *cstack) /// Handle ":try" void ex_try(exarg_T *eap) { - int skip; cstack_T *const cstack = eap->cstack; if (cstack->cs_idx == CSTACK_LEN - 1) { @@ -1231,7 +1217,7 @@ void ex_try(exarg_T *eap) cstack->cs_flags[cstack->cs_idx] = CSF_TRY; cstack->cs_pending[cstack->cs_idx] = CSTP_NONE; - skip = CHECK_SKIP; + int skip = CHECK_SKIP; if (!skip) { // Set ACTIVE and TRUE. TRUE means that the corresponding ":catch" @@ -1271,12 +1257,9 @@ void ex_catch(exarg_T *eap) int idx = 0; bool give_up = false; bool skip = false; - bool caught = false; char *end; - char save_char = 0; char *save_cpo; regmatch_T regmatch; - int prev_got_int; cstack_T *const cstack = eap->cstack; char *pat; @@ -1319,6 +1302,7 @@ void ex_catch(exarg_T *eap) } if (!give_up) { + bool caught = false; // Don't do something when no exception has been thrown or when the // corresponding try block never got active (because of an inactive // surrounding conditional or after an error or interrupt or throw). @@ -1344,6 +1328,7 @@ void ex_catch(exarg_T *eap) // the original exception, replace it by an interrupt exception, // and don't catch it in this try block. if (!dbg_check_skipped(eap) || !do_intthrow(cstack)) { + char save_char = 0; // Terminate the pattern and avoid the 'l' flag in 'cpoptions' // while compiling it. if (end != NULL) { @@ -1365,12 +1350,11 @@ void ex_catch(exarg_T *eap) if (regmatch.regprog == NULL) { semsg(_(e_invarg2), pat); } else { - // // Save the value of got_int and reset it. We don't want // a previous interruption cancel matching, only hitting // CTRL-C while matching should abort it. - // - prev_got_int = got_int; + + int prev_got_int = got_int; got_int = false; caught = vim_regexec_nl(®match, current_exception->value, (colnr_T)0); got_int |= prev_got_int; @@ -1415,7 +1399,6 @@ void ex_catch(exarg_T *eap) void ex_finally(exarg_T *eap) { int idx; - int skip = false; int pending = CSTP_NONE; cstack_T *const cstack = eap->cstack; @@ -1451,7 +1434,7 @@ void ex_finally(exarg_T *eap) // ":finally". After every other error (did_emsg or the conditional // errors detected above) or after an interrupt (got_int) or an // exception (did_throw), the finally clause must be executed. - skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE); + int skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE); if (!skip) { // When debugging or a breakpoint was encountered, display the @@ -1985,14 +1968,12 @@ void ex_endfunction(exarg_T *eap) /// @return true if the string "p" looks like a ":while" or ":for" command. int has_loop_cmd(char *p) { - int len; - // skip modifiers, white space and ':' for (;;) { while (*p == ' ' || *p == '\t' || *p == ':') { p++; } - len = modifier_len(p); + int len = modifier_len(p); if (len == 0) { break; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index eadeb839de..af26fe8a1c 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1598,8 +1598,10 @@ static int command_line_insert_reg(CommandLineState *s) } } + bool literally = false; if (s->c != ESC) { // use ESC to cancel inserting register - cmdline_paste(s->c, i == Ctrl_R, false); + literally = i == Ctrl_R; + cmdline_paste(s->c, literally, false); // When there was a serious error abort getting the // command line. @@ -1624,8 +1626,9 @@ static int command_line_insert_reg(CommandLineState *s) ccline.special_char = NUL; redrawcmd(); - // The text has been stuffed, the command line didn't change yet. - return CMDLINE_NOT_CHANGED; + // With "literally": the command line has already changed. + // Else: the text has been stuffed, but the command line didn't change yet. + return literally ? CMDLINE_CHANGED : CMDLINE_NOT_CHANGED; } /// Handle the Left and Right mouse clicks in the command-line mode. @@ -1729,7 +1732,6 @@ static int command_line_browse_history(CommandLineState *s) if (s->hiscnt != s->save_hiscnt) { // jumped to other entry char *p; - int len = 0; int old_firstc; XFREE_CLEAR(ccline.cmdbuff); @@ -1743,6 +1745,7 @@ static int command_line_browse_history(CommandLineState *s) if (s->histype == HIST_SEARCH && p != s->lookfor && (old_firstc = (uint8_t)p[strlen(p) + 1]) != s->firstc) { + int len = 0; // Correct for the separator character used when // adding the history entry vs the one used now. // First loop: count length. @@ -1857,12 +1860,12 @@ static int command_line_handle_key(CommandLineState *s) case Ctrl_R: // insert register switch (command_line_insert_reg(s)) { - case CMDLINE_NOT_CHANGED: - return command_line_not_changed(s); case GOTO_NORMAL_MODE: return 0; // back to cmd mode - default: + case CMDLINE_CHANGED: return command_line_changed(s); + default: + return command_line_not_changed(s); } case Ctrl_D: @@ -3380,14 +3383,14 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) ADD_C(item, INTEGER_OBJ(chunk.attr)); assert(chunk.end >= chunk.start); - ADD_C(item, STRING_OBJ(cbuf_as_string((char *)line->cmdbuff + chunk.start, + ADD_C(item, STRING_OBJ(cbuf_as_string(line->cmdbuff + chunk.start, (size_t)(chunk.end - chunk.start)))); ADD_C(content, ARRAY_OBJ(item)); } } else { Array item = arena_array(&arena, 2); ADD_C(item, INTEGER_OBJ(0)); - ADD_C(item, STRING_OBJ(cstr_as_string((char *)(line->cmdbuff)))); + ADD_C(item, STRING_OBJ(cstr_as_string(line->cmdbuff))); content = arena_array(&arena, 1); ADD_C(content, ARRAY_OBJ(item)); } @@ -3676,7 +3679,6 @@ static void restore_cmdline(CmdlineInfo *ccp) static bool cmdline_paste(int regname, bool literally, bool remcr) { char *arg; - char *p; bool allocated; // check for valid regname; also accept special characters for CTRL-R in @@ -3708,7 +3710,7 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) // When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate // part of the word. - p = arg; + char *p = arg; if (p_is && regname == Ctrl_W) { char *w; int len; @@ -3743,17 +3745,15 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) // line. void cmdline_paste_str(char *s, int literally) { - int c, cv; - if (literally) { put_on_cmdline(s, -1, true); } else { while (*s != NUL) { - cv = (uint8_t)(*s); + int cv = (uint8_t)(*s); if (cv == Ctrl_V && s[1]) { s++; } - c = mb_cptr2char_adv((const char **)&s); + int c = mb_cptr2char_adv((const char **)&s); if (cv == Ctrl_V || c == ESC || c == Ctrl_C || c == CAR || c == NL || c == Ctrl_L || (c == Ctrl_BSL && *s == Ctrl_N)) { @@ -3781,8 +3781,6 @@ void redrawcmdline(void) static void redrawcmdprompt(void) { - int i; - if (cmd_silent) { return; } @@ -3801,7 +3799,7 @@ static void redrawcmdprompt(void) ccline.cmdindent--; } } else { - for (i = ccline.cmdindent; i > 0; i--) { + for (int i = ccline.cmdindent; i > 0; i--) { msg_putchar(' '); } } @@ -4284,12 +4282,10 @@ void cmdline_init(void) /// Returns NULL if value is OK, error message otherwise. char *check_cedit(void) { - int n; - if (*p_cedit == NUL) { cedit_key = -1; } else { - n = string_to_key(p_cedit); + int n = string_to_key(p_cedit); if (vim_isprintc(n)) { return e_invarg; } @@ -4309,9 +4305,7 @@ static int open_cmdwin(void) bufref_T old_curbuf; bufref_T bufref; win_T *old_curwin = curwin; - win_T *wp; int i; - linenr_T lnum; garray_T winsizes; char typestr[2]; int save_restart_edit = restart_edit; @@ -4392,7 +4386,7 @@ static int open_cmdwin(void) if (get_hislen() > 0 && histtype != HIST_INVALID) { i = *get_hisidx(histtype); if (i >= 0) { - lnum = 0; + linenr_T lnum = 0; do { if (++i == get_hislen()) { i = 0; @@ -4463,6 +4457,7 @@ static int open_cmdwin(void) cmdwin_result = Ctrl_C; emsg(_("E199: Active window or buffer deleted")); } else { + win_T *wp; // autocmds may abort script processing if (aborting() && cmdwin_result != K_IGNORE) { cmdwin_result = Ctrl_C; diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 3de5e1db52..8e3e68d9b7 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -65,10 +65,10 @@ static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces) static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) { - int n = 0; win_T *wp; if (restore_size && (ssop_flags & SSOP_WINSIZE)) { + int n = 0; for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (!ses_do_win(wp)) { continue; @@ -218,14 +218,13 @@ static int ses_do_win(win_T *wp) static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp) { char *buf = NULL; - char *s; if (fprintf(fd, "%s\n%s\n", cmd, "%argdel") < 0) { return FAIL; } for (int i = 0; i < gap->ga_len; i++) { // NULL file names are skipped (only happens when out of memory). - s = alist_name(&((aentry_T *)gap->ga_data)[i]); + char *s = alist_name(&((aentry_T *)gap->ga_data)[i]); if (s != NULL) { if (fullname) { buf = xmalloc(MAXPATHL); @@ -551,7 +550,6 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr static int makeopens(FILE *fd, char *dirnow) { int only_save_windows = true; - int nr; int restore_size = true; win_T *wp; char *sname; @@ -753,11 +751,9 @@ static int makeopens(FILE *fd, char *dirnow) PUTLINE_FAIL("let &splitright = s:save_splitright"); } - // // Check if window sizes can be restored (no windows omitted). // Remember the window number of the current window after restoring. - // - nr = 0; + int nr = 0; for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (ses_do_win(wp)) { nr++; @@ -927,11 +923,9 @@ void ex_loadview(exarg_T *eap) void ex_mkrc(exarg_T *eap) { FILE *fd; - int failed = false; int view_session = false; // :mkview, :mksession int using_vdir = false; // using 'viewdir'? char *viewFile = NULL; - unsigned *flagp; if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) { view_session = true; @@ -970,6 +964,8 @@ void ex_mkrc(exarg_T *eap) fd = open_exfile(fname, eap->forceit, WRITEBIN); if (fd != NULL) { + int failed = false; + unsigned *flagp; if (eap->cmdidx == CMD_mkview) { flagp = &vop_flags; } else { diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 42ba0bee97..e27c7c4349 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1026,8 +1026,6 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char *filename, static bool ff_wc_equal(char *s1, char *s2) { int i, j; - int c1 = NUL; - int c2 = NUL; int prev1 = NUL; int prev2 = NUL; @@ -1040,8 +1038,8 @@ static bool ff_wc_equal(char *s1, char *s2) } for (i = 0, j = 0; s1[i] != NUL && s2[j] != NUL;) { - c1 = utf_ptr2char(s1 + i); - c2 = utf_ptr2char(s2 + j); + int c1 = utf_ptr2char(s1 + i); + int c2 = utf_ptr2char(s2 + j); if ((p_fic ? mb_tolower(c1) != mb_tolower(c2) : c1 != c2) && (prev1 != '*' || prev2 != '*')) { diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index fbb5c4f1fa..8c904f0c0a 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -64,6 +64,10 @@ #include "nvim/undo.h" #include "nvim/vim.h" +#ifdef BACKSLASH_IN_FILENAME +# include "nvim/charset.h" +#endif + #if defined(HAVE_FLOCK) && defined(HAVE_DIRFD) # include <dirent.h> # include <sys/file.h> @@ -207,7 +211,7 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip, char *line_start = NULL; // init to shut up gcc int wasempty; // buffer was empty before reading colnr_T len; - long size = 0; + ptrdiff_t size = 0; uint8_t *p = NULL; off_T filesize = 0; bool skip_read = false; @@ -217,7 +221,7 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip, linenr_T linecnt; bool error = false; // errors encountered int ff_error = EOL_UNKNOWN; // file format with errors - long linerest = 0; // remaining chars in line + ptrdiff_t linerest = 0; // remaining chars in line int perm = 0; #ifdef UNIX int swap_mode = -1; // protection bits for swap file @@ -1079,7 +1083,7 @@ retry: if (size < 2 || curbuf->b_p_bin) { ccname = NULL; } else { - ccname = check_for_bom(ptr, size, &blen, + ccname = check_for_bom(ptr, (int)size, &blen, fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc)); } if (ccname != NULL) { @@ -4038,7 +4042,7 @@ static int get_fio_flags(const char *name) /// /// @return the name of the encoding and set "*lenp" to the length or, /// NULL when no BOM found. -static char *check_for_bom(const char *p_in, long size, int *lenp, int flags) +static char *check_for_bom(const char *p_in, int size, int *lenp, int flags) { const uint8_t *p = (const uint8_t *)p_in; char *name = NULL; @@ -5630,7 +5634,7 @@ long read_eintr(int fd, void *buf, size_t bufsize) long ret; for (;;) { - ret = read(fd, buf, bufsize); + ret = read(fd, buf, (unsigned int)bufsize); if (ret >= 0 || errno != EINTR) { break; } @@ -5647,7 +5651,7 @@ long write_eintr(int fd, void *buf, size_t bufsize) // Repeat the write() so long it didn't fail, other than being interrupted // by a signal. while (ret < (long)bufsize) { - long wlen = write(fd, (char *)buf + ret, bufsize - (size_t)ret); + long wlen = write(fd, (char *)buf + ret, (unsigned int)(bufsize - (size_t)ret)); if (wlen < 0) { if (errno != EINTR) { break; diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h index dabcda5bf2..3e51e361ac 100644 --- a/src/nvim/fileio.h +++ b/src/nvim/fileio.h @@ -18,8 +18,6 @@ #define READ_NOWINENTER 0x80 // do not trigger BufWinEnter #define READ_NOFILE 0x100 // do not read a file, do trigger BufReadCmd -#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y)) - typedef varnumber_T (*CheckItem)(void *expr, const char *name); #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/fold.h b/src/nvim/fold.h index ac1e8c9419..cf44cf14c3 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -9,17 +9,6 @@ #include "nvim/pos.h" #include "nvim/types.h" -// Info used to pass info about a fold from the fold-detection code to the -// code that displays the foldcolumn. -typedef struct foldinfo { - linenr_T fi_lnum; // line number where fold starts - int fi_level; // level of the fold; when this is zero the - // other fields are invalid - int fi_low_level; // lowest fold level that starts in the same - // line - linenr_T fi_lines; -} foldinfo_T; - EXTERN int disable_fold_update INIT(= 0); #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/fold_defs.h b/src/nvim/fold_defs.h new file mode 100644 index 0000000000..c528d25348 --- /dev/null +++ b/src/nvim/fold_defs.h @@ -0,0 +1,17 @@ +#ifndef NVIM_FOLD_DEFS_H +#define NVIM_FOLD_DEFS_H + +#include "nvim/pos.h" + +// Info used to pass info about a fold from the fold-detection code to the +// code that displays the foldcolumn. +typedef struct foldinfo { + linenr_T fi_lnum; // line number where fold starts + int fi_level; // level of the fold; when this is zero the + // other fields are invalid + int fi_low_level; // lowest fold level that starts in the same + // line + linenr_T fi_lines; +} foldinfo_T; + +#endif // NVIM_FOLD_DEFS_H diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index f5728d29c1..37840f8875 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -155,7 +155,6 @@ static char *get_buffcont(buffheader_T *buffer, int dozero) { size_t count = 0; char *p = NULL; - char *p2; // compute the total length of the string for (const buffblock_T *bp = buffer->bh_first.b_next; @@ -165,7 +164,7 @@ static char *get_buffcont(buffheader_T *buffer, int dozero) if (count || dozero) { p = xmalloc(count + 1); - p2 = p; + char *p2 = p; for (const buffblock_T *bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) { for (const char *str = bp->b_str; *str;) { @@ -180,7 +179,7 @@ static char *get_buffcont(buffheader_T *buffer, int dozero) /// Return the contents of the record buffer as a single string /// and clear the record buffer. /// K_SPECIAL in the returned string is escaped. -char_u *get_recorded(void) +char *get_recorded(void) { char *p; size_t len; @@ -202,7 +201,7 @@ char_u *get_recorded(void) p[len - 1] = NUL; } - return (char_u *)p; + return p; } /// Return the contents of the redo buffer as a single string. @@ -583,7 +582,7 @@ void stuffRedoReadbuff(const char *s) add_buff(&readbuf2, s, -1L); } -void stuffReadbuffLen(const char *s, long len) +void stuffReadbuffLen(const char *s, ptrdiff_t len) { add_buff(&readbuf1, s, len); } @@ -635,7 +634,7 @@ void stuffescaped(const char *arg, bool literally) arg++; } if (arg > start) { - stuffReadbuffLen(start, (arg - start)); + stuffReadbuffLen(start, arg - start); } // stuff a single special character @@ -662,7 +661,6 @@ static int read_redo(bool init, bool old_redo) int c; int n; char_u buf[MB_MAXBYTES + 1]; - int i; if (init) { bp = old_redo ? old_redobuff.bh_first.b_next : redobuff.bh_first.b_next; @@ -683,7 +681,7 @@ static int read_redo(bool init, bool old_redo) } else { n = 1; } - for (i = 0;; i++) { + for (int i = 0;; i++) { if (c == K_SPECIAL) { // special key or escaped K_SPECIAL c = TO_SPECIAL(p[1], p[2]); p += 2; @@ -858,7 +856,6 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) { char_u *s1, *s2; int addlen; - int i; int val; int nrm; @@ -948,7 +945,7 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) } else { nrm = noremap; } - for (i = 0; i < addlen; i++) { + for (int i = 0; i < addlen; i++) { typebuf.tb_noremap[typebuf.tb_off + i + offset] = (uint8_t)((--nrm >= 0) ? val : RM_YES); } @@ -979,7 +976,7 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) int ins_char_typebuf(int c, int modifiers) { char_u buf[MB_MAXBYTES * 3 + 4]; - unsigned int len = special_to_buf(c, modifiers, true, buf); + unsigned int len = special_to_buf(c, modifiers, true, (char *)buf); assert(len < sizeof(buf)); buf[len] = NUL; (void)ins_typebuf((char *)buf, KeyNoremap, 0, !KeyTyped, cmd_silent); @@ -1020,8 +1017,6 @@ int typebuf_maplen(void) // remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset] void del_typebuf(int len, int offset) { - int i; - if (len == 0) { return; // nothing to do } @@ -1034,7 +1029,7 @@ void del_typebuf(int len, int offset) typebuf.tb_off += len; } else { // Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[] - i = typebuf.tb_off + offset; + int i = typebuf.tb_off + offset; // Leave some extra room at the end to avoid reallocation. if (typebuf.tb_off > MAXMAPLEN) { memmove(typebuf.tb_buf + MAXMAPLEN, @@ -1408,10 +1403,8 @@ int merge_modifiers(int c_arg, int *modifiers) /// Returns the modifiers in the global "mod_mask". int vgetc(void) { - int c, c2; - int n; + int c; char_u buf[MB_MAXBYTES + 1]; - int i; // Do garbage collection when garbagecollect() was called previously and // we are now at the toplevel. @@ -1429,6 +1422,8 @@ int vgetc(void) mouse_row = old_mouse_row; mouse_col = old_mouse_col; } else { + int c2; + int n; // number of characters recorded from the last vgetc() call static size_t last_vgetc_recorded_len = 0; @@ -1554,7 +1549,7 @@ int vgetc(void) if ((n = MB_BYTE2LEN_CHECK(c)) > 1) { no_mapping++; buf[0] = (char_u)c; - for (i = 1; i < n; i++) { + for (int i = 1; i < n; i++) { buf[i] = (char_u)vgetorpeek(true); if (buf[i] == K_SPECIAL) { // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence, @@ -1754,9 +1749,9 @@ static void getchar_common(typval_T *argvars, typval_T *rettv) int grid = mouse_grid; linenr_T lnum; win_T *wp; - int winnr = 1; if (row >= 0 && col >= 0) { + int winnr = 1; // Find the window at the mouse coordinates and compute the // text position. win_T *const win = mouse_find_win(&grid, &row, &col); @@ -1921,9 +1916,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth) int max_mlen = 0; int tb_c1; int mlen; - int nolmaplen; int keylen = *keylenp; - int i; int local_State = get_real_state(); bool is_plug_map = false; @@ -1956,6 +1949,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth) && State != MODE_ASKMORE && State != MODE_CONFIRM && !at_ins_compl_key()) { + int nolmaplen; if (tb_c1 == K_SPECIAL) { nolmaplen = 2; } else { @@ -2168,6 +2162,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth) // complete match if (keylen >= 0 && keylen <= typebuf.tb_len) { + int i; char *map_str = NULL; // Write chars to script file(s). @@ -2199,7 +2194,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth) // mode temporarily. Append K_SELECT to switch back to Select mode. if (VIsual_active && VIsual_select && (mp->m_mode & MODE_VISUAL)) { VIsual_select = false; - (void)ins_typebuf((char *)K_SELECT_STRING, REMAP_NONE, 0, true, false); + (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE, 0, true, false); } // Copy the values from *mp that are used, because evaluating the @@ -2509,9 +2504,6 @@ static int vgetorpeek(bool advance) && (State & MODE_INSERT) && (p_timeout || (keylen == KEYLEN_PART_KEY && p_ttimeout)) && (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, 3, 25L)) == 0) { - colnr_T col = 0; - char_u *ptr; - if (mode_displayed) { unshowmode(true); mode_deleted = true; @@ -2522,6 +2514,8 @@ static int vgetorpeek(bool advance) // move cursor left, if possible if (curwin->w_cursor.col != 0) { + colnr_T col = 0; + char_u *ptr; if (curwin->w_wcol > 0) { // After auto-indenting and no text is following, // we are expecting to truncate the trailing @@ -2890,13 +2884,13 @@ int inchar(char_u *buf, int maxlen, long wait_time) typebuf.tb_change_cnt = 1; } - return fix_input_buffer(buf, len); + return fix_input_buffer((char *)buf, len); } // Fix typed characters for use by vgetc() and check_termcode(). // "buf[]" must have room to triple the number of bytes! // Returns the new length. -int fix_input_buffer(char_u *buf, int len) +int fix_input_buffer(char *buf, int len) FUNC_ATTR_NONNULL_ALL { if (!using_script()) { @@ -2907,13 +2901,12 @@ int fix_input_buffer(char_u *buf, int len) } // Reading from script, need to process special bytes - int i; - char_u *p = buf; + char_u *p = (char_u *)buf; // Two characters are special: NUL and K_SPECIAL. // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER // Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER - for (i = len; --i >= 0; p++) { + for (int i = len; --i >= 0; p++) { if (p[0] == NUL || (p[0] == K_SPECIAL && (i < 2 || p[1] != KS_EXTRA))) { diff --git a/src/nvim/grid.c b/src/nvim/grid.c index 46f8a59710..efbeac4f3f 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -158,9 +158,9 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char *bytes, int *attrp) /// attributes 'attr', and update chars[] and attrs[]. /// Note: only outputs within one row, message is truncated at grid boundary! /// Note: if grid, row and/or col is invalid, nothing is done. -void grid_puts(ScreenGrid *grid, char *text, int row, int col, int attr) +int grid_puts(ScreenGrid *grid, char *text, int row, int col, int attr) { - grid_puts_len(grid, text, -1, row, col, attr); + return grid_puts_len(grid, text, -1, row, col, attr); } static ScreenGrid *put_dirty_grid = NULL; @@ -197,22 +197,18 @@ void grid_put_schar(ScreenGrid *grid, int row, int col, char *schar, int attr) /// like grid_puts(), but output "text[len]". When "len" is -1 output up to /// a NUL. -void grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col, int attr) +int grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col, int attr) { size_t off; char *ptr = text; int len = textlen; int c; size_t max_off; - int mbyte_blen = 1; - int mbyte_cells = 1; - int u8c = 0; int u8cc[MAX_MCO]; bool clear_next_cell = false; int prev_c = 0; // previous Arabic character int pc, nc, nc1; int pcc[MAX_MCO]; - int need_redraw; bool do_flush = false; grid_adjust(&grid, &row, &col); @@ -222,7 +218,7 @@ void grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col, if (grid->chars == NULL || row >= grid->rows || row < 0 || col >= grid->cols || col < 0) { - return; + return 0; } if (put_dirty_row == -1) { @@ -234,6 +230,7 @@ void grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col, } } off = grid->line_offset[row] + (size_t)col; + int start_col = col; // When drawing over the right half of a double-wide char clear out the // left half. Only needed in a terminal. @@ -249,13 +246,19 @@ void grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col, && *ptr != NUL) { c = (unsigned char)(*ptr); // check if this is the first byte of a multibyte - mbyte_blen = len > 0 + int mbyte_blen = len > 0 ? utfc_ptr2len_len(ptr, (int)((text + len) - ptr)) : utfc_ptr2len(ptr); - u8c = len >= 0 + int u8c = len >= 0 ? utfc_ptr2char_len(ptr, u8cc, (int)((text + len) - ptr)) : utfc_ptr2char(ptr, u8cc); - mbyte_cells = utf_char2cells(u8c); + int mbyte_cells = utf_char2cells(u8c); + if (mbyte_cells > 2) { + mbyte_cells = 1; + u8c = 0xFFFD; + u8cc[0] = 0; + } + if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c)) { // Do Arabic shaping. if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) { @@ -287,11 +290,11 @@ void grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col, schar_T buf; schar_from_cc(buf, u8c, u8cc); - need_redraw = schar_cmp(grid->chars[off], buf) - || (mbyte_cells == 2 && grid->chars[off + 1][0] != 0) - || grid->attrs[off] != attr - || exmode_active - || rdb_flags & RDB_NODELTA; + int need_redraw = schar_cmp(grid->chars[off], buf) + || (mbyte_cells == 2 && grid->chars[off + 1][0] != 0) + || grid->attrs[off] != attr + || exmode_active + || rdb_flags & RDB_NODELTA; if (need_redraw) { // When at the end of the text and overwriting a two-cell @@ -340,6 +343,7 @@ void grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col, if (do_flush) { grid_puts_line_flush(true); } + return col - start_col; } /// End a group of grid_puts_len calls and send the screen buffer to the UI @@ -497,7 +501,6 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle size_t max_off_from; size_t max_off_to; int col = 0; - bool redraw_this; // Does character need redraw? bool redraw_next; // redraw_this for next character bool clear_next = false; int char_cells; // 1: normal char @@ -559,7 +562,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle if (col + 1 < endcol) { char_cells = line_off2cells(linebuf_char, off_from, max_off_from); } - redraw_this = redraw_next; + bool redraw_this = redraw_next; // Does character need redraw? redraw_next = grid_char_needs_redraw(grid, off_from + (size_t)char_cells, off_to + (size_t)char_cells, endcol - col - char_cells); @@ -810,7 +813,6 @@ void grid_assign_handle(ScreenGrid *grid) /// 'row', 'col' and 'end' are relative to the start of the region. void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, int width) { - int i; int j; unsigned temp; @@ -825,7 +827,7 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, // Shift line_offset[] line_count down to reflect the inserted lines. // Clear the inserted lines. - for (i = 0; i < line_count; i++) { + for (int i = 0; i < line_count; i++) { if (width != grid->cols) { // need to copy part of a line j = end - 1 - i; @@ -860,7 +862,6 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, int width) { int j; - int i; unsigned temp; int row_off = 0; @@ -874,7 +875,7 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, // Now shift line_offset[] line_count up to reflect the deleted lines. // Clear the inserted lines. - for (i = 0; i < line_count; i++) { + for (int i = 0; i < line_count; i++) { if (width != grid->cols) { // need to copy part of a line j = row + i; diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 851e70caca..8f4c7b1d80 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -457,8 +457,8 @@ hash_T hash_hash_len(const char *key, const size_t len) /// /// Used for testing because luajit ffi does not allow getting addresses of /// globals. -const char_u *_hash_key_removed(void) +const char *_hash_key_removed(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - return (char_u *)HI_KEY_REMOVED; + return HI_KEY_REMOVED; } diff --git a/src/nvim/help.c b/src/nvim/help.c index bbc552fa4c..5fa48e0cee 100644 --- a/src/nvim/help.c +++ b/src/nvim/help.c @@ -47,19 +47,14 @@ void ex_help(exarg_T *eap) { char *arg; - char *tag; FILE *helpfd; // file descriptor of help file - int n; - int i; win_T *wp; int num_matches; char **matches; - char *p; int empty_fnum = 0; int alt_fnum = 0; buf_T *buf; int len; - char *lang; const bool old_KeyTyped = KeyTyped; if (eap != NULL) { @@ -88,13 +83,13 @@ void ex_help(exarg_T *eap) } // remove trailing blanks - p = arg + strlen(arg) - 1; + char *p = arg + strlen(arg) - 1; while (p > arg && ascii_iswhite(*p) && p[-1] != '\\') { *p-- = NUL; } // Check for a specified language - lang = check_help_lang(arg); + char *lang = check_help_lang(arg); // When no argument given go to the index. if (*arg == NUL) { @@ -102,9 +97,9 @@ void ex_help(exarg_T *eap) } // Check if there is a match for the argument. - n = find_help_tags(arg, &num_matches, &matches, eap != NULL && eap->forceit); + int n = find_help_tags(arg, &num_matches, &matches, eap != NULL && eap->forceit); - i = 0; + int i = 0; if (n != FAIL && lang != NULL) { // Find first item with the requested language. for (i = 0; i < num_matches; i++) { @@ -128,7 +123,7 @@ void ex_help(exarg_T *eap) } // The first match (in the requested language) is the best match. - tag = xstrdup(matches[i]); + char *tag = xstrdup(matches[i]); FreeWild(num_matches, matches); // Re-use an existing help window or open a new one. @@ -259,11 +254,8 @@ char *check_help_lang(char *arg) int help_heuristic(char *matched_string, int offset, int wrong_case) FUNC_ATTR_PURE { - int num_letters; - char *p; - - num_letters = 0; - for (p = matched_string; *p; p++) { + int num_letters = 0; + for (char *p = matched_string; *p; p++) { if (ASCII_ISALNUM(*p)) { num_letters++; } @@ -298,11 +290,8 @@ int help_heuristic(char *matched_string, int offset, int wrong_case) /// that has been put after the tagname by find_tags(). static int help_compare(const void *s1, const void *s2) { - char *p1; - char *p2; - - p1 = *(char **)s1 + strlen(*(char **)s1) + 1; - p2 = *(char **)s2 + strlen(*(char **)s2) + 1; + char *p1 = *(char **)s1 + strlen(*(char **)s1) + 1; + char *p2 = *(char **)s2 + strlen(*(char **)s2) + 1; // Compare by help heuristic number first. int cmp = strcmp(p1, p2); @@ -320,8 +309,6 @@ static int help_compare(const void *s1, const void *s2) /// When "keep_lang" is true try keeping the language of the current buffer. int find_help_tags(const char *arg, int *num_matches, char ***matches, bool keep_lang) { - int i; - // Specific tags that either have a specific replacement or won't go // through the generic rules. static char *(except_tbl[][2]) = { @@ -379,7 +366,7 @@ int find_help_tags(const char *arg, int *num_matches, char ***matches, bool keep // When the string starting with "expr-" and containing '?' and matches // the table, it is taken literally (but ~ is escaped). Otherwise '?' // is recognized as a wildcard. - for (i = (int)ARRAY_SIZE(expr_table); --i >= 0;) { + for (int i = (int)ARRAY_SIZE(expr_table); --i >= 0;) { if (strcmp(arg + 5, expr_table[i]) == 0) { for (int si = 0, di = 0;; si++) { if (arg[si] == '~') { @@ -396,7 +383,7 @@ int find_help_tags(const char *arg, int *num_matches, char ***matches, bool keep } else { // Recognize a few exceptions to the rule. Some strings that contain // '*'are changed to "star", otherwise '*' is recognized as a wildcard. - for (i = 0; except_tbl[i][0] != NULL; i++) { + for (int i = 0; except_tbl[i][0] != NULL; i++) { if (strcmp(arg, except_tbl[i][0]) == 0) { STRCPY(d, except_tbl[i][1]); break; @@ -660,7 +647,6 @@ void fix_help_buffer(void) { linenr_T lnum; char *line; - bool in_example = false; // Set filetype to "help". if (strcmp(curbuf->b_p_ft, "help") != 0) { @@ -670,6 +656,7 @@ void fix_help_buffer(void) } if (!syntax_present(curwin)) { + bool in_example = false; for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) { line = ml_get_buf(curbuf, lnum, false); const size_t len = strlen(line); @@ -722,9 +709,7 @@ void fix_help_buffer(void) && path_full_compare(rt, NameBuff, false, true) != kEqualFiles) { int fcount; char **fnames; - char *s; vimconv_T vc; - char *cp; // Find all "doc/ *.txt" files in this directory. if (!add_pathsep(NameBuff) @@ -740,6 +725,8 @@ void fix_help_buffer(void) if (gen_expand_wildcards(1, buff_list, &fcount, &fnames, EW_FILE|EW_SILENT) == OK && fcount > 0) { + char *s; + char *cp; // If foo.abx is found use it instead of foo.txt in // the same directory. for (int i1 = 0; i1 < fcount; i1++) { @@ -1080,7 +1067,6 @@ static void helptags_one(char *dir, const char *ext, const char *tagfname, bool static void do_helptags(char *dirname, bool add_help_tags, bool ignore_writeerr) FUNC_ATTR_NONNULL_ALL { - int len; garray_T ga; char lang[2]; char ext[5]; @@ -1090,7 +1076,7 @@ static void do_helptags(char *dirname, bool add_help_tags, bool ignore_writeerr) // Get a list of all files in the help directory and in subdirectories. xstrlcpy(NameBuff, dirname, sizeof(NameBuff)); - if (!add_pathsep((char *)NameBuff) + if (!add_pathsep(NameBuff) || xstrlcat(NameBuff, "**", sizeof(NameBuff)) >= MAXPATHL) { emsg(_(e_fnametoolong)); return; @@ -1111,7 +1097,7 @@ static void do_helptags(char *dirname, bool add_help_tags, bool ignore_writeerr) int j; ga_init(&ga, 1, 10); for (int i = 0; i < filecount; i++) { - len = (int)strlen(files[i]); + int len = (int)strlen(files[i]); if (len <= 4) { continue; } @@ -1177,7 +1163,6 @@ static void helptags_cb(char *fname, void *cookie) void ex_helptags(exarg_T *eap) { expand_T xpc; - char *dirname; bool add_help_tags = false; // Check for ":helptags ++t {dir}". @@ -1191,7 +1176,8 @@ void ex_helptags(exarg_T *eap) } else { ExpandInit(&xpc); xpc.xp_context = EXPAND_DIRECTORIES; - dirname = ExpandOne(&xpc, eap->arg, NULL, WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); + char *dirname = + ExpandOne(&xpc, eap->arg, NULL, WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); if (dirname == NULL || !os_isdir(dirname)) { semsg(_("E150: Not a directory: %s"), eap->arg); } else { diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index c20eac3c28..cf72102b60 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -12,6 +12,7 @@ #include "lauxlib.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/api/ui.h" #include "nvim/decoration_provider.h" #include "nvim/drawscreen.h" @@ -205,7 +206,7 @@ int ns_get_hl(NS *ns_hl, int hl_id, bool link, bool nodefault) if (!valid_item && p->hl_def != LUA_NOREF && !recursive) { MAXSIZE_TEMP_ARRAY(args, 3); ADD_C(args, INTEGER_OBJ((Integer)ns_id)); - ADD_C(args, STRING_OBJ(cstr_to_string((char *)syn_id2name(hl_id)))); + ADD_C(args, STRING_OBJ(cstr_to_string(syn_id2name(hl_id)))); ADD_C(args, BOOLEAN_OBJ(link)); // TODO(bfredl): preload the "global" attr dict? @@ -971,35 +972,33 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e return hlattrs; } - if (dict->blend.type == kObjectTypeInteger) { + if (HAS_KEY(dict->blend)) { + VALIDATE_T("blend", kObjectTypeInteger, dict->blend.type, { + return hlattrs; + }); + Integer blend0 = dict->blend.data.integer; - if (blend0 < 0 || blend0 > 100) { - api_set_error(err, kErrorTypeValidation, "'blend' is not between 0 to 100"); - } else { - blend = (int)blend0; - } - } else if (HAS_KEY(dict->blend)) { - api_set_error(err, kErrorTypeValidation, "'blend' must be an integer"); - } - if (ERROR_SET(err)) { - return hlattrs; + VALIDATE_RANGE((blend0 >= 0 && blend0 <= 100), "blend", { + return hlattrs; + }); + blend = (int)blend0; } if (HAS_KEY(dict->link) || HAS_KEY(dict->global_link)) { - if (link_id) { - if (HAS_KEY(dict->global_link)) { - *link_id = object_to_hl_id(dict->global_link, "link", err); - mask |= HL_GLOBAL; - } else { - *link_id = object_to_hl_id(dict->link, "link", err); - } - - if (ERROR_SET(err)) { - return hlattrs; - } - } else { + if (!link_id) { api_set_error(err, kErrorTypeValidation, "Invalid Key: '%s'", HAS_KEY(dict->global_link) ? "global_link" : "link"); + return hlattrs; + } + if (HAS_KEY(dict->global_link)) { + *link_id = object_to_hl_id(dict->global_link, "link", err); + mask |= HL_GLOBAL; + } else { + *link_id = object_to_hl_id(dict->link, "link", err); + } + + if (ERROR_SET(err)) { + return hlattrs; } } @@ -1026,7 +1025,9 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e // TODO(clason): handle via gen_api_dispatch cterm_mask_provided = true; } else if (HAS_KEY(dict->cterm)) { - api_set_error(err, kErrorTypeValidation, "'cterm' must be a Dictionary."); + VALIDATE_T("cterm", kObjectTypeDictionary, dict->cterm.type, { + return hlattrs; + }); } #undef CHECK_FLAG @@ -1083,13 +1084,14 @@ int object_to_color(Object val, char *key, bool rgb, Error *err) } else { color = name_to_ctermcolor(str.data); } - if (color < 0) { - api_set_error(err, kErrorTypeValidation, "'%s' is not a valid color", str.data); - } + VALIDATE_S((color >= 0), "highlight color", str.data, { + return color; + }); return color; } else { - api_set_error(err, kErrorTypeValidation, "'%s' must be string or integer", key); - return 0; + VALIDATE_EXP(false, key, "String or Integer", NULL, { + return 0; + }); } } @@ -1115,7 +1117,7 @@ static void hl_inspect_impl(Array *arr, int attr) case kHlSyntax: PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax"))); PUT(item, "hi_name", - STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1)))); + STRING_OBJ(cstr_to_string(syn_id2name(e.id1)))); break; case kHlUI: @@ -1123,7 +1125,7 @@ static void hl_inspect_impl(Array *arr, int attr) const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1]; PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name))); PUT(item, "hi_name", - STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2)))); + STRING_OBJ(cstr_to_string(syn_id2name(e.id2)))); break; case kHlTerminal: diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 3d91335f55..e34c13abc1 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -1522,7 +1522,7 @@ Dictionary get_global_hl_defs(Arena *arena) char *link = hl_table[h->sg_link - 1].sg_name; PUT_C(attrs, "link", STRING_OBJ(cstr_as_string(link))); } - PUT_C(rv, (char *)h->sg_name, DICTIONARY_OBJ(attrs)); + PUT_C(rv, h->sg_name, DICTIONARY_OBJ(attrs)); } return rv; @@ -1547,7 +1547,7 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg char buf[100]; const char *ts = buf; if (type == LIST_INT) { - snprintf((char *)buf, sizeof(buf), "%d", iarg - 1); + snprintf(buf, sizeof(buf), "%d", iarg - 1); } else if (type == LIST_STRING) { ts = sarg; } else { // type == LIST_ATTR diff --git a/src/nvim/indent.c b/src/nvim/indent.c index ec6c72da6d..ee9bc48460 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -460,7 +460,6 @@ int set_indent(int size, int flags) int line_len; int doit = false; int ind_done = 0; // Measured in spaces. - int ind_col = 0; int tab_pad; int retval = false; @@ -479,6 +478,7 @@ int set_indent(int size, int flags) // 'preserveindent' are set count the number of characters at the // beginning of the line to be copied. if (!curbuf->b_p_et || (!(flags & SIN_INSERT) && curbuf->b_p_pi)) { + int ind_col = 0; // If 'preserveindent' is set then reuse as much as possible of // the existing indent structure for the new indent. if (!(flags & SIN_INSERT) && curbuf->b_p_pi) { @@ -936,14 +936,10 @@ void ex_retab(exarg_T *eap) long num_spaces = 0; long num_tabs; long len; - long col; - long vcol; long start_col = 0; // For start of white-space string long start_vcol = 0; // For start of white-space string long old_len; - char *ptr; char *new_line = (char *)1; // init to non-NULL - bool did_undo; // called u_save for current line long *new_vts_array = NULL; char *new_ts_str; // string value of tab argument @@ -972,10 +968,10 @@ void ex_retab(exarg_T *eap) new_ts_str = xstrnsave(new_ts_str, (size_t)(eap->arg - new_ts_str)); } for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) { - ptr = ml_get(lnum); - col = 0; - vcol = 0; - did_undo = false; + char *ptr = ml_get(lnum); + long col = 0; + long vcol = 0; + bool did_undo = false; // called u_save for current line for (;;) { if (ascii_iswhite(ptr[col])) { if (!got_tab && num_spaces == 0) { @@ -1186,10 +1182,6 @@ int get_lisp_indent(void) pos_T *pos, realpos, paren; int amount; char *that; - colnr_T col; - colnr_T firsttry; - int parencount; - int quotecount; int vi_lisp; // Set vi_lisp to use the vi-compatible method. @@ -1213,7 +1205,7 @@ int get_lisp_indent(void) // Extra trick: Take the indent of the first previous non-white // line that is at the same () level. amount = -1; - parencount = 0; + int parencount = 0; while (--curwin->w_cursor.lnum >= pos->lnum) { if (linewhite(curwin->w_cursor.lnum)) { @@ -1268,7 +1260,7 @@ int get_lisp_indent(void) if (amount == -1) { curwin->w_cursor.lnum = pos->lnum; curwin->w_cursor.col = pos->col; - col = pos->col; + colnr_T col = pos->col; that = get_cursor_line_ptr(); @@ -1298,7 +1290,7 @@ int get_lisp_indent(void) that++; amount++; } - firsttry = amount; + colnr_T firsttry = amount; init_chartabsize_arg(&cts, curwin, (colnr_T)(that - line), amount, line, that); @@ -1319,13 +1311,13 @@ int get_lisp_indent(void) } parencount = 0; - quotecount = 0; init_chartabsize_arg(&cts, curwin, (colnr_T)(that - line), amount, line, that); if (vi_lisp || ((*that != '"') && (*that != '\'') && (*that != '#') && (((uint8_t)(*that) < '0') || ((uint8_t)(*that) > '9')))) { + int quotecount = 0; while (*cts.cts_ptr && (!ascii_iswhite(*cts.cts_ptr) || quotecount || parencount) && (!((*cts.cts_ptr == '(' || *cts.cts_ptr == '[') @@ -1373,12 +1365,11 @@ int get_lisp_indent(void) static int lisp_match(char *p) { char buf[LSIZE]; - int len; char *word = *curbuf->b_p_lw != NUL ? curbuf->b_p_lw : p_lispwords; while (*word != NUL) { (void)copy_option_part(&word, buf, LSIZE, ","); - len = (int)strlen(buf); + int len = (int)strlen(buf); if ((strncmp(buf, p, (size_t)len) == 0) && ascii_iswhite_or_nul(p[len])) { return true; diff --git a/src/nvim/input.c b/src/nvim/input.c index 96214d45c2..5b9b866778 100644 --- a/src/nvim/input.c +++ b/src/nvim/input.c @@ -86,9 +86,8 @@ int ask_yesno(const char *const str, const bool direct) /// Translates the interrupt character for unix to ESC. int get_keystroke(MultiQueue *events) { - char_u *buf = NULL; + char *buf = NULL; int buflen = 150; - int maxlen; int len = 0; int n; int save_mapped_ctrl_c = mapped_ctrl_c; @@ -100,7 +99,7 @@ int get_keystroke(MultiQueue *events) // Leave some room for check_termcode() to insert a key code into (max // 5 chars plus NUL). And fix_input_buffer() can triple the number of // bytes. - maxlen = (buflen - 6 - len) / 3; + int maxlen = (buflen - 6 - len) / 3; if (buf == NULL) { buf = xmalloc((size_t)buflen); } else if (maxlen < 10) { @@ -113,7 +112,7 @@ int get_keystroke(MultiQueue *events) // First time: blocking wait. Second time: wait up to 100ms for a // terminal code to complete. - n = os_inchar(buf + len, maxlen, len == 0 ? -1L : 100L, 0, events); + n = os_inchar((uint8_t *)buf + len, maxlen, len == 0 ? -1L : 100L, 0, events); if (n > 0) { // Replace zero and K_SPECIAL by a special key code. n = fix_input_buffer(buf + len, n); @@ -128,14 +127,14 @@ int get_keystroke(MultiQueue *events) } // Handle modifier and/or special key code. - n = buf[0]; + n = (uint8_t)buf[0]; if (n == K_SPECIAL) { - n = TO_SPECIAL(buf[1], buf[2]); - if (buf[1] == KS_MODIFIER + n = TO_SPECIAL((uint8_t)buf[1], (uint8_t)buf[2]); + if ((uint8_t)buf[1] == KS_MODIFIER || n == K_IGNORE || (is_mouse_key(n) && n != K_LEFTMOUSE)) { - if (buf[1] == KS_MODIFIER) { - mod_mask = buf[2]; + if ((uint8_t)buf[1] == KS_MODIFIER) { + mod_mask = (uint8_t)buf[2]; } len -= 3; if (len > 0) { @@ -150,7 +149,7 @@ int get_keystroke(MultiQueue *events) continue; } buf[len >= buflen ? buflen - 1 : len] = NUL; - n = utf_ptr2char((char *)buf); + n = utf_ptr2char(buf); break; } xfree(buf); @@ -166,7 +165,6 @@ int get_keystroke(MultiQueue *events) int get_number(int colon, int *mouse_used) { int n = 0; - int c; int typed = 0; if (mouse_used != NULL) { @@ -183,7 +181,7 @@ int get_number(int colon, int *mouse_used) allow_keys++; // no mapping here, but recognize keys for (;;) { ui_cursor_goto(msg_row, msg_col); - c = safe_vgetc(); + int c = safe_vgetc(); if (ascii_isdigit(c)) { n = n * 10 + c - '0'; msg_putchar(c); diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index e19806e464..8114efc10c 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -582,7 +582,7 @@ unsigned int trans_special(const char **const srcp, const size_t src_len, char * return 0; } - return special_to_buf(key, modifiers, escape_ks, (char_u *)dst); + return special_to_buf(key, modifiers, escape_ks, dst); } /// Put the character sequence for "key" with "modifiers" into "dst" and return @@ -590,27 +590,27 @@ unsigned int trans_special(const char **const srcp, const size_t src_len, char * /// When "escape_ks" is true escape K_SPECIAL bytes in the character. /// The sequence is not NUL terminated. /// This is how characters in a string are encoded. -unsigned int special_to_buf(int key, int modifiers, bool escape_ks, char_u *dst) +unsigned int special_to_buf(int key, int modifiers, bool escape_ks, char *dst) { unsigned int dlen = 0; // Put the appropriate modifier in a string. if (modifiers != 0) { - dst[dlen++] = K_SPECIAL; - dst[dlen++] = KS_MODIFIER; - dst[dlen++] = (char_u)modifiers; + dst[dlen++] = (char)(uint8_t)K_SPECIAL; + dst[dlen++] = (char)(uint8_t)KS_MODIFIER; + dst[dlen++] = (char)(uint8_t)modifiers; } if (IS_SPECIAL(key)) { - dst[dlen++] = K_SPECIAL; - dst[dlen++] = (char_u)KEY2TERMCAP0(key); - dst[dlen++] = KEY2TERMCAP1(key); + dst[dlen++] = (char)(uint8_t)K_SPECIAL; + dst[dlen++] = (char)(uint8_t)KEY2TERMCAP0(key); + dst[dlen++] = (char)(uint8_t)KEY2TERMCAP1(key); } else if (escape_ks) { - char_u *after = add_char2buf(key, dst + dlen); + char *after = add_char2buf(key, dst + dlen); assert(after >= dst && (uintmax_t)(after - dst) <= UINT_MAX); dlen = (unsigned int)(after - dst); } else { - dlen += (unsigned int)utf_char2bytes(key, (char *)dst + dlen); + dlen += (unsigned int)utf_char2bytes(key, dst + dlen); } return dlen; @@ -637,7 +637,6 @@ int find_special_key(const char **const srcp, const size_t src_len, int *const m const bool in_string = flags & FSK_IN_STRING; int modifiers; int bit; - int key; uvarnumber_T n; int l; @@ -685,6 +684,7 @@ int find_special_key(const char **const srcp, const size_t src_len, int *const m } if (bp <= end && *bp == '>') { // found matching '>' + int key; end_of_name = bp + 1; // Which modifiers are given? @@ -1033,20 +1033,20 @@ char *replace_termcodes(const char *const from, const size_t from_len, char **co /// @param[out] s Buffer to add to. Must have at least MB_MAXBYTES + 1 bytes. /// /// @return Pointer to after the added bytes. -char_u *add_char2buf(int c, char_u *s) +char *add_char2buf(int c, char *s) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - char_u temp[MB_MAXBYTES + 1]; - const int len = utf_char2bytes(c, (char *)temp); + char temp[MB_MAXBYTES + 1]; + const int len = utf_char2bytes(c, temp); for (int i = 0; i < len; i++) { c = (uint8_t)temp[i]; // Need to escape K_SPECIAL like in the typeahead buffer. if (c == K_SPECIAL) { - *s++ = K_SPECIAL; - *s++ = KS_SPECIAL; + *s++ = (char)(uint8_t)K_SPECIAL; + *s++ = (char)(uint8_t)KS_SPECIAL; *s++ = KE_FILLER; } else { - *s++ = (char_u)c; + *s++ = (char)(uint8_t)c; } } return s; @@ -1060,9 +1060,9 @@ char *vim_strsave_escape_ks(char *p) // illegal utf-8 byte: // 0xc0 -> 0xc3 - 0x80 -> 0xc3 K_SPECIAL KS_SPECIAL KE_FILLER char *res = xmalloc(strlen(p) * 4 + 1); - char_u *d = (char_u *)res; - for (char_u *s = (char_u *)p; *s != NUL;) { - if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) { + char *d = res; + for (char *s = p; *s != NUL;) { + if ((uint8_t)s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) { // Copy special key unmodified. *d++ = *s++; *d++ = *s++; @@ -1070,8 +1070,8 @@ char *vim_strsave_escape_ks(char *p) } else { // Add character, possibly multi-byte to destination, escaping // K_SPECIAL. Be careful, it can be an illegal byte! - d = add_char2buf(utf_ptr2char((char *)s), d); - s += utf_ptr2len((char *)s); + d = add_char2buf(utf_ptr2char(s), d); + s += utf_ptr2len(s); } } *d = NUL; @@ -1081,9 +1081,9 @@ char *vim_strsave_escape_ks(char *p) /// Remove escaping from K_SPECIAL characters. Reverse of /// vim_strsave_escape_ks(). Works in-place. -void vim_unescape_ks(char_u *p) +void vim_unescape_ks(char *p) { - char_u *s = p, *d = p; + char_u *s = (char_u *)p, *d = (char_u *)p; while (*s != NUL) { if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER) { diff --git a/src/nvim/keycodes.h b/src/nvim/keycodes.h index 7842dee92c..7c143fc99e 100644 --- a/src/nvim/keycodes.h +++ b/src/nvim/keycodes.h @@ -59,7 +59,7 @@ // Used for switching Select mode back on after a mapping or menu. #define KS_SELECT 245 -#define K_SELECT_STRING (char_u *)"\200\365X" +#define K_SELECT_STRING "\200\365X" /// Used a termcap entry that produces a normal character. #define KS_KEY 242 diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 007662fbc9..c8fc76e20d 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1766,13 +1766,12 @@ bool nlua_exec_file(const char *path) StringBuilder sb = KV_INITIAL_VALUE; kv_resize(sb, 64); - ptrdiff_t read_size = -1; // Read all input from stdin, unless interrupted (ctrl-c). while (true) { if (got_int) { // User canceled. return false; } - read_size = file_read(stdin_dup, IObuff, 64); + ptrdiff_t read_size = file_read(stdin_dup, IObuff, 64); if (read_size < 0) { // Error. return false; } @@ -1993,7 +1992,7 @@ char *nlua_register_table_as_callable(const typval_T *const arg) void nlua_execute_on_key(int c) { char buf[NUMBUFLEN]; - size_t buf_len = special_to_buf(c, mod_mask, false, (char_u *)buf); + size_t buf_len = special_to_buf(c, mod_mask, false, buf); lua_State *const lstate = global_lstate; diff --git a/src/nvim/lua/spell.c b/src/nvim/lua/spell.c index d510d25e90..78e023c26d 100644 --- a/src/nvim/lua/spell.c +++ b/src/nvim/lua/spell.c @@ -51,7 +51,6 @@ int nlua_spell_check(lua_State *lstate) } hlf_T attr = HLF_COUNT; - size_t len = 0; size_t pos = 0; int capcol = -1; int no_res = 0; @@ -61,7 +60,7 @@ int nlua_spell_check(lua_State *lstate) while (*str != NUL) { attr = HLF_COUNT; - len = spell_check(curwin, (char *)str, &attr, &capcol, false); + size_t len = spell_check(curwin, (char *)str, &attr, &capcol, false); assert(len <= INT_MAX); if (attr != HLF_COUNT) { diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index 6ebca6d97e..5aeff4de98 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -78,20 +78,20 @@ static int regex_match_line(lua_State *lstate) return luaL_error(lstate, "not enough args"); } - long bufnr = luaL_checkinteger(lstate, 2); + handle_T bufnr = (handle_T)luaL_checkinteger(lstate, 2); linenr_T rownr = (linenr_T)luaL_checkinteger(lstate, 3); - long start = 0, end = -1; + int start = 0, end = -1; if (narg >= 4) { - start = luaL_checkinteger(lstate, 4); + start = (int)luaL_checkinteger(lstate, 4); } if (narg >= 5) { - end = luaL_checkinteger(lstate, 5); + end = (int)luaL_checkinteger(lstate, 5); if (end < 0) { return luaL_error(lstate, "invalid end"); } } - buf_T *buf = bufnr ? handle_get_buffer((int)bufnr) : curbuf; + buf_T *buf = bufnr ? handle_get_buffer(bufnr) : curbuf; if (!buf || buf->b_ml.ml_mfp == NULL) { return luaL_error(lstate, "invalid buffer"); } @@ -218,11 +218,11 @@ static int nlua_str_utf_start(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { size_t s1_len; const char *s1 = luaL_checklstring(lstate, 1, &s1_len); - long offset = luaL_checkinteger(lstate, 2); + ptrdiff_t offset = luaL_checkinteger(lstate, 2); if (offset < 0 || offset > (intptr_t)s1_len) { return luaL_error(lstate, "index out of range"); } - int head_offset = utf_cp_head_off((char_u *)s1, (char_u *)s1 + offset - 1); + int head_offset = utf_cp_head_off(s1, s1 + offset - 1); lua_pushinteger(lstate, head_offset); return 1; } @@ -238,7 +238,7 @@ static int nlua_str_utf_end(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { size_t s1_len; const char *s1 = luaL_checklstring(lstate, 1, &s1_len); - long offset = luaL_checkinteger(lstate, 2); + ptrdiff_t offset = luaL_checkinteger(lstate, 2); if (offset < 0 || offset > (intptr_t)s1_len) { return luaL_error(lstate, "index out of range"); } diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 56f4daed1a..5248ebed14 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -393,7 +393,7 @@ static int parser_parse(lua_State *L) TSTree *new_tree = NULL; size_t len; const char *str; - long bufnr; + handle_T bufnr; buf_T *buf; TSInput input; @@ -406,13 +406,13 @@ static int parser_parse(lua_State *L) break; case LUA_TNUMBER: - bufnr = lua_tointeger(L, 3); - buf = handle_get_buffer((handle_T)bufnr); + bufnr = (handle_T)lua_tointeger(L, 3); + buf = handle_get_buffer(bufnr); if (!buf) { #define BUFSIZE 256 char ebuf[BUFSIZE] = { 0 }; - vim_snprintf(ebuf, BUFSIZE, "invalid buffer handle: %ld", bufnr); + vim_snprintf(ebuf, BUFSIZE, "invalid buffer handle: %d", bufnr); return luaL_argerror(L, 3, ebuf); #undef BUFSIZE } @@ -898,8 +898,8 @@ static int node_child(lua_State *L) if (!node_check(L, 1, &node)) { return 0; } - long num = lua_tointeger(L, 2); - TSNode child = ts_node_child(node, (uint32_t)num); + uint32_t num = (uint32_t)lua_tointeger(L, 2); + TSNode child = ts_node_child(node, num); push_node(L, child, 1); return 1; @@ -911,8 +911,8 @@ static int node_named_child(lua_State *L) if (!node_check(L, 1, &node)) { return 0; } - long num = lua_tointeger(L, 2); - TSNode child = ts_node_named_child(node, (uint32_t)num); + uint32_t num = (uint32_t)lua_tointeger(L, 2); + TSNode child = ts_node_named_child(node, num); push_node(L, child, 1); return 1; diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c index 857b159af5..9a7ae5c146 100644 --- a/src/nvim/lua/xdiff.c +++ b/src/nvim/lua/xdiff.c @@ -257,13 +257,13 @@ static NluaXdiffMode process_xdl_diff_opts(lua_State *lstate, xdemitconf_t *cfg, if (check_xdiff_opt(v->type, kObjectTypeInteger, "ctxlen", err)) { goto exit_1; } - cfg->ctxlen = v->data.integer; + cfg->ctxlen = (long)v->data.integer; } else if (strequal("interhunkctxlen", k.data)) { if (check_xdiff_opt(v->type, kObjectTypeInteger, "interhunkctxlen", err)) { goto exit_1; } - cfg->interhunkctxlen = v->data.integer; + cfg->interhunkctxlen = (long)v->data.integer; } else if (strequal("linematch", k.data)) { *linematch = api_object_to_bool(*v, "linematch", false, err); if (ERROR_SET(err)) { diff --git a/src/nvim/main.c b/src/nvim/main.c index 1f155aa343..52069a6742 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -182,6 +182,9 @@ void early_init(mparm_T *paramp) #ifdef MSWIN OSVERSIONINFO ovi; ovi.dwOSVersionInfoSize = sizeof(ovi); + // Disable warning about GetVersionExA being deprecated. There doesn't seem to be a conventient + // replacement that doesn't add a ton of extra code as of writing this. +# pragma warning(suppress : 4996) GetVersionEx(&ovi); snprintf(windowsVersion, sizeof(windowsVersion), "%d.%d", (int)ovi.dwMajorVersion, (int)ovi.dwMinorVersion); @@ -668,6 +671,7 @@ void os_exit(int r) void getout(int exitval) FUNC_ATTR_NORETURN { + assert(!ui_client_channel_id); exiting = true; // On error during Ex mode, exit with a non-zero code. @@ -788,6 +792,7 @@ void getout(int exitval) } /// Preserve files, print contents of `errmsg`, and exit 1. +/// @param errmsg If NULL, this function will not print anything. /// /// May be called from deadly_signal(). void preserve_exit(const char *errmsg) @@ -813,19 +818,21 @@ void preserve_exit(const char *errmsg) // For TUI: exit alternate screen so that the error messages can be seen. ui_client_stop(); } - os_errmsg(errmsg); - os_errmsg("\n"); + if (errmsg != NULL) { + os_errmsg(errmsg); + os_errmsg("\n"); + } if (ui_client_channel_id) { os_exit(1); } - ui_flush(); ml_close_notmod(); // close all not-modified buffers FOR_ALL_BUFFERS(buf) { if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) { - os_errmsg("Vim: preserving files...\r\n"); - ui_flush(); + if (errmsg != NULL) { + os_errmsg("Vim: preserving files...\r\n"); + } ml_sync_all(false, false, true); // preserve all swap files break; } @@ -833,7 +840,9 @@ void preserve_exit(const char *errmsg) ml_close_all(false); // close all memfiles, without deleting - os_errmsg("Vim: Finished.\r\n"); + if (errmsg != NULL) { + os_errmsg("Vim: Finished.\r\n"); + } getout(1); } @@ -908,9 +917,8 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, } Array args = ARRAY_DICT_INIT; - String arg_s; for (int t_argc = remote_args; t_argc < argc; t_argc++) { - arg_s = cstr_to_string(argv[t_argc]); + String arg_s = cstr_to_string(argv[t_argc]); ADD(args, STRING_OBJ(arg_s)); } @@ -1583,7 +1591,7 @@ static void open_script_files(mparm_T *parmp) scriptin[0] = file_open_new(&error, parmp->scriptin, kFileReadOnly|kFileNonBlocking, 0); if (scriptin[0] == NULL) { - vim_snprintf((char *)IObuff, IOSIZE, + vim_snprintf(IObuff, IOSIZE, _("Cannot open for reading: \"%s\": %s\n"), parmp->scriptin, os_strerror(error)); os_errmsg(IObuff); @@ -1608,9 +1616,6 @@ static void open_script_files(mparm_T *parmp) // Also does recovery if "recoverymode" set. static void create_windows(mparm_T *parmp) { - int dorewind; - int done = 0; - // Create the number of windows that was requested. if (parmp->window_count == -1) { // was not set parmp->window_count = 1; @@ -1646,6 +1651,7 @@ static void create_windows(mparm_T *parmp) } do_modelines(0); // do modelines } else { + int done = 0; // Open a buffer for windows that don't have one yet. // Commands in the vimrc might have loaded a file or split the window. // Watch out for autocommands that delete a window. @@ -1653,7 +1659,7 @@ static void create_windows(mparm_T *parmp) // Don't execute Win/Buf Enter/Leave autocommands here autocmd_no_enter++; autocmd_no_leave++; - dorewind = true; + int dorewind = true; while (done++ < 1000) { if (dorewind) { if (parmp->window_layout == WIN_TABS) { diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 831d1299a8..c740fb41bc 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -1162,7 +1162,7 @@ static bool expand_buffer = false; /// @param cpo_flags Value of various flags present in &cpo /// /// @return NULL when there is a problem. -static char_u *translate_mapping(char_u *str, int cpo_flags) +static char *translate_mapping(char_u *str, int cpo_flags) { garray_T ga; ga_init(&ga, 1, 40); @@ -1203,7 +1203,7 @@ static char_u *translate_mapping(char_u *str, int cpo_flags) } } ga_append(&ga, NUL); - return (char_u *)(ga.ga_data); + return (char *)ga.ga_data; } /// Work out what to complete when doing command line completion of mapping @@ -1212,8 +1212,8 @@ static char_u *translate_mapping(char_u *str, int cpo_flags) /// @param forceit true if '!' given /// @param isabbrev true if abbreviation /// @param isunmap true if unmap/unabbrev command -char_u *set_context_in_map_cmd(expand_T *xp, char *cmd, char *arg, bool forceit, bool isabbrev, - bool isunmap, cmdidx_T cmdidx) +char *set_context_in_map_cmd(expand_T *xp, char *cmd, char *arg, bool forceit, bool isabbrev, + bool isunmap, cmdidx_T cmdidx) { if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap) { xp->xp_context = EXPAND_NOTHING; @@ -1346,7 +1346,7 @@ int ExpandMappings(char *pat, regmatch_T *regmatch, int *numMatches, char ***mat continue; } - char *p = (char *)translate_mapping((char_u *)mp->m_keys, CPO_TO_CPO_FLAGS); + char *p = translate_mapping((char_u *)mp->m_keys, CPO_TO_CPO_FLAGS); if (p == NULL) { continue; } @@ -1434,15 +1434,11 @@ int ExpandMappings(char *pat, regmatch_T *regmatch, int *numMatches, char ***mat // Return true if there is an abbreviation, false if not. bool check_abbr(int c, char *ptr, int col, int mincol) { - int len; int scol; // starting column of the abbr. - int j; - char *s; char_u tb[MB_MAXBYTES + 4]; mapblock_T *mp; mapblock_T *mp2; int clen = 0; // length in characters - bool is_id = true; if (typebuf.tb_no_abbr_cnt) { // abbrev. are not recursive return false; @@ -1462,6 +1458,7 @@ bool check_abbr(int c, char *ptr, int col, int mincol) } { + bool is_id = true; bool vim_abbr; char *p = mb_prevptr(ptr, ptr + col); if (!vim_iswordp(p)) { @@ -1489,7 +1486,7 @@ bool check_abbr(int c, char *ptr, int col, int mincol) } if (scol < col) { // there is a word in front of the cursor ptr += scol; - len = col - scol; + int len = col - scol; mp = curbuf->b_first_abbr; mp2 = first_abbr; if (mp == NULL) { @@ -1506,7 +1503,7 @@ bool check_abbr(int c, char *ptr, int col, int mincol) if (strchr((const char *)mp->m_keys, K_SPECIAL) != NULL) { // Might have K_SPECIAL escaped mp->m_keys. q = xstrdup(mp->m_keys); - vim_unescape_ks((char_u *)q); + vim_unescape_ks(q); qlen = (int)strlen(q); } // find entries with right mode and keys @@ -1532,7 +1529,7 @@ bool check_abbr(int c, char *ptr, int col, int mincol) // // Character CTRL-] is treated specially - it completes the // abbreviation, but is not inserted into the input stream. - j = 0; + int j = 0; if (c != Ctrl_RSB) { // special key code, split up if (IS_SPECIAL(c) || c == K_SPECIAL) { @@ -1568,6 +1565,7 @@ bool check_abbr(int c, char *ptr, int col, int mincol) const bool silent = mp->m_silent; const bool expr = mp->m_expr; + char *s; if (expr) { s = eval_map_expr(mp, c); } else { @@ -1609,7 +1607,7 @@ char *eval_map_expr(mapblock_T *mp, int c) // typeahead. if (mp->m_luaref == LUA_NOREF) { expr = xstrdup(mp->m_str); - vim_unescape_ks((char_u *)expr); + vim_unescape_ks(expr); } const bool replace_keycodes = mp->m_replace_keycodes; diff --git a/src/nvim/mark.c b/src/nvim/mark.c index f1a1f25e6c..855fcb33ae 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -521,11 +521,10 @@ fmark_T *pos_to_mark(buf_T *buf, fmark_T *fmp, pos_T pos) /// @return whether the buffer was switched or not. static MarkMoveRes switch_to_mark_buf(fmark_T *fm, bool pcmark_on_switch) { - bool res; if (fm->fnum != curbuf->b_fnum) { // Switch to another file. int getfile_flag = pcmark_on_switch ? GETF_SETMARK : 0; - res = buflist_getfile(fm->fnum, (linenr_T)1, getfile_flag, false) == OK; + bool res = buflist_getfile(fm->fnum, (linenr_T)1, getfile_flag, false) == OK; return res == true ? kMarkSwitchedBuf : kMarkMoveFailed; } return 0; @@ -617,11 +616,8 @@ fmarkv_T mark_view_make(linenr_T topline, pos_T pos) /// @return next mark or NULL if no mark is found. fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line) { - int i; fmark_T *result = NULL; - pos_T pos; - - pos = *startpos; + pos_T pos = *startpos; if (dir == BACKWARD && begin_line) { pos.col = 0; @@ -629,7 +625,7 @@ fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line) pos.col = MAXCOL; } - for (i = 0; i < NMARKS; i++) { + for (int i = 0; i < NMARKS; i++) { if (curbuf->b_namedm[i].mark.lnum > 0) { if (dir == FORWARD) { if ((result == NULL || lt(curbuf->b_namedm[i].mark, result->mark)) @@ -686,18 +682,17 @@ static void fname2fnum(xfmark_T *fm) void fmarks_check_names(buf_T *buf) { char *name = buf->b_ffname; - int i; if (buf->b_ffname == NULL) { return; } - for (i = 0; i < NGLOBALMARKS; i++) { + for (int i = 0; i < NGLOBALMARKS; i++) { fmarks_check_one(&namedfm[i], name, buf); } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - for (i = 0; i < wp->w_jumplistlen; i++) { + for (int i = 0; i < wp->w_jumplistlen; i++) { fmarks_check_one(&wp->w_jumplist[i], name, buf); } } @@ -821,7 +816,6 @@ static char *mark_line(pos_T *mp, int lead_len) void ex_marks(exarg_T *eap) { char *arg = eap->arg; - int i; char *name; pos_T *posp, *startp, *endp; @@ -830,10 +824,10 @@ void ex_marks(exarg_T *eap) } show_one_mark('\'', arg, &curwin->w_pcmark, NULL, true); - for (i = 0; i < NMARKS; i++) { + for (int i = 0; i < NMARKS; i++) { show_one_mark(i + 'a', arg, &curbuf->b_namedm[i].mark, NULL, true); } - for (i = 0; i < NGLOBALMARKS; i++) { + for (int i = 0; i < NGLOBALMARKS; i++) { if (namedfm[i].fmark.fnum != 0) { name = fm_getname(&namedfm[i].fmark, 15); } else { @@ -919,7 +913,6 @@ void ex_delmarks(exarg_T *eap) { char *p; int from, to; - int i; int lower; int digit; int n; @@ -954,7 +947,7 @@ void ex_delmarks(exarg_T *eap) from = to = (uint8_t)(*p); } - for (i = from; i <= to; i++) { + for (int i = from; i <= to; i++) { if (lower) { curbuf->b_namedm[i - 'a'].mark.lnum = 0; } else { @@ -998,13 +991,12 @@ void ex_delmarks(exarg_T *eap) // print the jumplist void ex_jumps(exarg_T *eap) { - int i; char *name; cleanup_jumplist(curwin, true); // Highlight title msg_puts_title(_("\n jump line col file/text")); - for (i = 0; i < curwin->w_jumplistlen && !got_int; i++) { + for (int i = 0; i < curwin->w_jumplistlen && !got_int; i++) { if (curwin->w_jumplist[i].fmark.mark.lnum != 0) { name = fm_getname(&curwin->w_jumplist[i].fmark, 16); @@ -1051,13 +1043,12 @@ void ex_clearjumps(exarg_T *eap) // print the changelist void ex_changes(exarg_T *eap) { - int i; char *name; // Highlight title msg_puts_title(_("\nchange line col text")); - for (i = 0; i < curbuf->b_changelistlen && !got_int; i++) { + for (int i = 0; i < curbuf->b_changelistlen && !got_int; i++) { if (curbuf->b_changelist[i].mark.lnum != 0) { msg_putchar('\n'); if (got_int) { @@ -1138,7 +1129,6 @@ void mark_adjust_nofold(linenr_T line1, linenr_T line2, linenr_T amount, linenr_ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after, bool adjust_folds, ExtmarkOp op) { - int i; int fnum = curbuf->b_fnum; linenr_T *lp; static pos_T initpos = { 1, 0, 0 }; @@ -1149,13 +1139,13 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // named marks, lower case and upper case - for (i = 0; i < NMARKS; i++) { + for (int i = 0; i < NMARKS; i++) { ONE_ADJUST(&(curbuf->b_namedm[i].mark.lnum)); if (namedfm[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum)); } } - for (i = NMARKS; i < NGLOBALMARKS; i++) { + for (int i = NMARKS; i < NGLOBALMARKS; i++) { if (namedfm[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum)); } @@ -1173,7 +1163,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount } // list of change positions - for (i = 0; i < curbuf->b_changelistlen; i++) { + for (int i = 0; i < curbuf->b_changelistlen; i++) { ONE_ADJUST_NODEL(&(curbuf->b_changelist[i].mark.lnum)); } @@ -1217,7 +1207,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // Marks in the jumplist. When deleting lines, this may create // duplicate marks in the jumplist, they will be removed later. - for (i = 0; i < win->w_jumplistlen; i++) { + for (int i = 0; i < win->w_jumplistlen; i++) { if (win->w_jumplist[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(win->w_jumplist[i].fmark.mark.lnum)); } @@ -1227,7 +1217,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount if (win->w_buffer == curbuf) { if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // marks in the tag stack - for (i = 0; i < win->w_tagstacklen; i++) { + for (int i = 0; i < win->w_tagstacklen; i++) { if (win->w_tagstack[i].fmark.fnum == fnum) { ONE_ADJUST_NODEL(&(win->w_tagstack[i].fmark.mark.lnum)); } @@ -1309,7 +1299,6 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long col_amount, int spaces_removed) { - int i; int fnum = curbuf->b_fnum; pos_T *posp; @@ -1317,13 +1306,13 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c return; // nothing to do } // named marks, lower case and upper case - for (i = 0; i < NMARKS; i++) { + for (int i = 0; i < NMARKS; i++) { COL_ADJUST(&(curbuf->b_namedm[i].mark)); if (namedfm[i].fmark.fnum == fnum) { COL_ADJUST(&(namedfm[i].fmark.mark)); } } - for (i = NMARKS; i < NGLOBALMARKS; i++) { + for (int i = NMARKS; i < NGLOBALMARKS; i++) { if (namedfm[i].fmark.fnum == fnum) { COL_ADJUST(&(namedfm[i].fmark.mark)); } @@ -1336,7 +1325,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c COL_ADJUST(&(curbuf->b_last_change.mark)); // list of change positions - for (i = 0; i < curbuf->b_changelistlen; i++) { + for (int i = 0; i < curbuf->b_changelistlen; i++) { COL_ADJUST(&(curbuf->b_changelist[i].mark)); } @@ -1356,7 +1345,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c // Adjust items in all windows related to the current buffer. FOR_ALL_WINDOWS_IN_TAB(win, curtab) { // marks in the jumplist - for (i = 0; i < win->w_jumplistlen; i++) { + for (int i = 0; i < win->w_jumplistlen; i++) { if (win->w_jumplist[i].fmark.fnum == fnum) { COL_ADJUST(&(win->w_jumplist[i].fmark.mark)); } @@ -1364,7 +1353,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c if (win->w_buffer == curbuf) { // marks in the tag stack - for (i = 0; i < win->w_tagstacklen; i++) { + for (int i = 0; i < win->w_tagstacklen; i++) { if (win->w_tagstack[i].fmark.fnum == fnum) { COL_ADJUST(&(win->w_tagstack[i].fmark.mark)); } @@ -1457,9 +1446,7 @@ void cleanup_jumplist(win_T *wp, bool loadfiles) // Copy the jumplist from window "from" to window "to". void copy_jumplist(win_T *from, win_T *to) { - int i; - - for (i = 0; i < from->w_jumplistlen; i++) { + for (int i = 0; i < from->w_jumplistlen; i++) { to->w_jumplist[i] = from->w_jumplist[i]; if (from->w_jumplist[i].fname != NULL) { to->w_jumplist[i].fname = xstrdup(from->w_jumplist[i].fname); @@ -1671,9 +1658,7 @@ bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const b // Free items in the jumplist of window "wp". void free_jumplist(win_T *wp) { - int i; - - for (i = 0; i < wp->w_jumplistlen; i++) { + for (int i = 0; i < wp->w_jumplistlen; i++) { free_xfmark(wp->w_jumplist[i]); } wp->w_jumplistlen = 0; diff --git a/src/nvim/match.c b/src/nvim/match.c index 6663dfd7ec..93c8a58051 100644 --- a/src/nvim/match.c +++ b/src/nvim/match.c @@ -419,7 +419,6 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_ colnr_T mincol, matchitem_T *cur) FUNC_ATTR_NONNULL_ARG(2) { - linenr_T l; colnr_T matchcol; long nmatched = 0; const int called_emsg_before = called_emsg; @@ -435,7 +434,7 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_ // 1. If the "lnum" is below a previous match, start a new search. // 2. If the previous match includes "mincol", use it. // 3. Continue after the previous match. - l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; + linenr_T l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; if (lnum > l) { shl->lnum = 0; } else if (lnum < l || shl->rm.endpos[0].col > mincol) { diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 8b50ba719a..e27bb003e7 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -449,18 +449,16 @@ int mb_get_class_tab(const char *p, const uint64_t *const chartab) static bool intable(const struct interval *table, size_t n_items, int c) FUNC_ATTR_PURE { - int mid, bot, top; - // first quick check for Latin1 etc. characters if (c < table[0].first) { return false; } // binary search in table - bot = 0; - top = (int)(n_items - 1); + int bot = 0; + int top = (int)(n_items - 1); while (top >= bot) { - mid = (bot + top) / 2; + int mid = (bot + top) / 2; if (table[mid].last < c) { bot = mid + 1; } else if (table[mid].first > c) { @@ -518,11 +516,9 @@ int utf_char2cells(int c) /// This doesn't take care of unprintable characters, use ptr2cells() for that. int utf_ptr2cells(const char *p) { - int c; - // Need to convert to a character number. if ((uint8_t)(*p) >= 0x80) { - c = utf_ptr2char(p); + int c = utf_ptr2char(p); // An illegal byte is displayed as <xx>. if (utf_ptr2len(p) == 1 || c == NUL) { return 4; @@ -540,14 +536,12 @@ int utf_ptr2cells(const char *p) /// For an empty string or truncated character returns 1. int utf_ptr2cells_len(const char *p, int size) { - int c; - // Need to convert to a wide character. if (size > 0 && (uint8_t)(*p) >= 0x80) { if (utf_ptr2len_len(p, size) < utf8len_tab[(uint8_t)(*p)]) { return 1; // truncated } - c = utf_ptr2char((char *)p); + int c = utf_ptr2char((char *)p); // An illegal byte is displayed as <xx>. if (utf_ptr2len((char *)p) == 1 || c == NUL) { return 4; @@ -664,8 +658,6 @@ int utf_ptr2char(const char *const p_in) // "s". static int utf_safe_read_char_adv(const char_u **s, size_t *n) { - int c; - if (*n == 0) { // end of buffer return 0; } @@ -682,7 +674,7 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n) // We have a multibyte sequence and it isn't truncated by buffer // limits so utf_ptr2char() is safe to use. Or the first byte is // illegal (k=0), and it's also safe to use utf_ptr2char(). - c = utf_ptr2char((char *)(*s)); + int c = utf_ptr2char((char *)(*s)); // On failure, utf_ptr2char() returns the first byte, so here we // check equality with the first byte. The only non-ASCII character @@ -855,7 +847,6 @@ int utf_byte2len(int b) int utf_ptr2len_len(const char *p, int size) { int len; - int i; int m; len = utf8len_tab[(uint8_t)(*p)]; @@ -867,7 +858,7 @@ int utf_ptr2len_len(const char *p, int size) } else { m = len; } - for (i = 1; i < m; i++) { + for (int i = 1; i < m; i++) { if ((p[i] & 0xc0) != 0x80) { return 1; } @@ -1141,7 +1132,6 @@ int utf_class_tab(const int c, const uint64_t *const chartab) }; int bot = 0; int top = ARRAY_SIZE(classes) - 1; - int mid; // First quick check for Latin1 characters, use 'iskeyword'. if (c < 0x100) { @@ -1161,7 +1151,7 @@ int utf_class_tab(const int c, const uint64_t *const chartab) // binary search in table while (top >= bot) { - mid = (bot + top) / 2; + int mid = (bot + top) / 2; if (classes[mid].last < (unsigned int)c) { bot = mid + 1; } else if (classes[mid].first > (unsigned int)c) { @@ -1186,13 +1176,12 @@ bool utf_ambiguous_width(int c) // the given conversion "table". Uses binary search on "table". static int utf_convert(int a, const convertStruct *const table, size_t n_items) { - size_t start, mid, end; // indices into table - - start = 0; - end = n_items; + // indices into table + size_t start = 0; + size_t end = n_items; while (start < end) { // need to search further - mid = (end + start) / 2; + size_t mid = (end + start) / 2; if (table[mid].rangeEnd < a) { start = mid + 1; } else { @@ -1540,7 +1529,6 @@ void show_utf8(void) int rlen = 0; char *line; int clen; - int i; // Get the byte length of the char under the cursor, including composing // characters. @@ -1552,7 +1540,7 @@ void show_utf8(void) } clen = 0; - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { if (clen == 0) { // start of (composing) character, get its length if (i > 0) { @@ -1579,9 +1567,6 @@ void show_utf8(void) /// Returns 0 when already at the first byte of a character. int utf_head_off(const char *base_in, const char *p_in) { - int c; - int len; - if ((uint8_t)(*p_in) < 0x80) { // be quick for ASCII return 0; } @@ -1603,7 +1588,7 @@ int utf_head_off(const char *base_in, const char *p_in) } // Check for illegal sequence. Do allow an illegal byte after where we // started. - len = utf8len_tab[*q]; + int len = utf8len_tab[*q]; if (len != (int)(s - q + 1) && len != (int)(p - q + 1)) { return 0; } @@ -1612,7 +1597,7 @@ int utf_head_off(const char *base_in, const char *p_in) break; } - c = utf_ptr2char((char *)q); + int c = utf_ptr2char((char *)q); if (utf_iscomposing(c)) { continue; } @@ -1795,7 +1780,6 @@ int mb_off_next(const char *base, const char *p_in) { const uint8_t *p = (uint8_t *)p_in; int i; - int j; if (*p < 0x80) { // be quick for ASCII return 0; @@ -1804,6 +1788,7 @@ int mb_off_next(const char *base, const char *p_in) // Find the next character that isn't 10xx.xxxx for (i = 0; (p[i] & 0xc0) == 0x80; i++) {} if (i > 0) { + int j; // Check for illegal sequence. for (j = 0; p - j > (uint8_t *)base; j++) { if ((p[-j] & 0xc0) != 0x80) { @@ -1855,7 +1840,7 @@ int utf_cp_tail_off(const char *base, const char *p_in) /// @param[in] p Pointer to byte for which to return the offset to the previous codepoint // /// @return 0 if invalid sequence, else offset to previous codepoint -int utf_cp_head_off(const char_u *base, const char_u *p) +int utf_cp_head_off(const char *base, const char *p) { int i; int j; @@ -1866,16 +1851,16 @@ int utf_cp_head_off(const char_u *base, const char_u *p) // Find the first character that is not 10xx.xxxx for (i = 0; p - i > base; i--) { - if ((p[i] & 0xc0) != 0x80) { + if (((uint8_t)p[i] & 0xc0) != 0x80) { break; } } // Find the last character that is 10xx.xxxx - for (j = 0; (p[j + 1] & 0xc0) == 0x80; j++) {} + for (j = 0; ((uint8_t)p[j + 1] & 0xc0) == 0x80; j++) {} // Check for illegal sequence. - if (utf8len_tab[p[i]] == 1) { + if (utf8len_tab[(uint8_t)p[i]] == 1) { return 0; } return i; @@ -2184,9 +2169,7 @@ char *enc_canonize(char *enc) /// Returns -1 when not found. static int enc_alias_search(const char *name) { - int i; - - for (i = 0; enc_alias_table[i].name != NULL; i++) { + for (int i = 0; enc_alias_table[i].name != NULL; i++) { if (strcmp(name, enc_alias_table[i].name) == 0) { return enc_alias_table[i].canon; } @@ -2479,7 +2462,6 @@ char *string_convert_ext(const vimconv_T *const vcp, char *ptr, size_t *lenp, si { char_u *retval = NULL; char_u *d; - int l; int c; size_t len; @@ -2547,7 +2529,7 @@ char *string_convert_ext(const vimconv_T *const vcp, char *ptr, size_t *lenp, si retval = xmalloc(len + 1); d = retval; for (size_t i = 0; i < len; i++) { - l = utf_ptr2len_len(ptr + i, (int)(len - i)); + int l = utf_ptr2len_len(ptr + i, (int)(len - i)); if (l == 0) { *d++ = NUL; } else if (l == 1) { @@ -2627,8 +2609,8 @@ char *string_convert_ext(const vimconv_T *const vcp, char *ptr, size_t *lenp, si /// Table set by setcellwidths(). typedef struct { - long first; - long last; + int64_t first; + int64_t last; char width; } cw_interval_T; diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 46be9ccea5..118b5d5886 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -603,11 +603,9 @@ static int mf_read(memfile_T *mfp, bhdr_T *hp) static int mf_write(memfile_T *mfp, bhdr_T *hp) { off_T offset; // offset in the file - blocknr_T nr; // block nr which is being written bhdr_T *hp2; unsigned page_size; // number of bytes in a page unsigned page_count; // number of pages written - unsigned size; // number of bytes written if (mfp->mf_fd < 0) { // there is no file, can't write return FAIL; @@ -626,7 +624,7 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp) /// If block 'mf_infile_count' is not in the hash list, it has been /// freed. Fill the space in the file with data from the current block. for (;;) { - nr = hp->bh_bnum; + blocknr_T nr = hp->bh_bnum; // block nr which is being written if (nr > mfp->mf_infile_count) { // beyond end of file nr = mfp->mf_infile_count; hp2 = mf_find_hash(mfp, nr); // NULL caught below @@ -645,7 +643,7 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp) } else { page_count = hp2->bh_page_count; } - size = page_size * page_count; + unsigned size = page_size * page_count; // number of bytes written void *data = (hp2 == NULL) ? hp->bh_data : hp2->bh_data; if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size) { /// Avoid repeating the error message, this mostly happens when the diff --git a/src/nvim/memline.c b/src/nvim/memline.c index dfca19aa96..ff0a6d7627 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -185,8 +185,8 @@ struct block0 { char_u b0_mtime[4]; // last modification time of file char_u b0_ino[4]; // inode of b0_fname char_u b0_pid[4]; // process id of creator (or 0) - char_u b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name) - char_u b0_hname[B0_HNAME_SIZE]; // host name (if it has a name) + char b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name) + char b0_hname[B0_HNAME_SIZE]; // host name (if it has a name) char b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited long b0_magic_long; // check for byte order of long int b0_magic_int; // check for byte order of int @@ -303,11 +303,11 @@ int ml_open(buf_T *buf) b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0; b0p->b0_flags = (char)(get_fileformat(buf) + 1); set_b0_fname(b0p, buf); - (void)os_get_username((char *)b0p->b0_uname, B0_UNAME_SIZE); + (void)os_get_username(b0p->b0_uname, B0_UNAME_SIZE); b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL; - os_get_hostname((char *)b0p->b0_hname, B0_HNAME_SIZE); + os_get_hostname(b0p->b0_hname, B0_HNAME_SIZE); b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL; - long_to_char(os_get_pid(), b0p->b0_pid); + long_to_char((long)os_get_pid(), b0p->b0_pid); } // Always sync block number 0 to disk, so we can check the file name in @@ -632,7 +632,7 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf) // editing the same file on different machines over a network. // First replace home dir path with "~/" with home_replace(). // Then insert the user name to get "~user/". - home_replace(NULL, buf->b_ffname, (char *)b0p->b0_fname, + home_replace(NULL, buf->b_ffname, b0p->b0_fname, B0_FNAME_SIZE_CRYPT, true); if (b0p->b0_fname[0] == '~') { // If there is no user name or it is too long, don't use "~/" @@ -691,7 +691,7 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf) if ((int)strlen(b0p->b0_fname) + n + 1 > size) { b0p->b0_flags = (char)(b0p->b0_flags & ~B0_HAS_FENC); } else { - memmove((char *)b0p->b0_fname + size - n, + memmove(b0p->b0_fname + size - n, buf->b_p_fenc, (size_t)n); *(b0p->b0_fname + size - n - 1) = NUL; b0p->b0_flags |= B0_HAS_FENC; @@ -848,7 +848,7 @@ void ml_recover(bool checkext) msg_puts_attr(_("The file was created on "), attr | MSG_HIST); // avoid going past the end of a corrupted hostname b0p->b0_fname[0] = NUL; - msg_puts_attr((char *)b0p->b0_hname, attr | MSG_HIST); + msg_puts_attr(b0p->b0_hname, attr | MSG_HIST); msg_puts_attr(_(",\nor the file has been damaged."), attr | MSG_HIST); msg_end(); goto theend; @@ -886,7 +886,7 @@ void ml_recover(bool checkext) // If .swp file name given directly, use name from swap file for buffer. if (directly) { - expand_env((char *)b0p->b0_fname, NameBuff, MAXPATHL); + expand_env(b0p->b0_fname, NameBuff, MAXPATHL); if (setfname(curbuf, NameBuff, NULL, true) == FAIL) { goto theend; } @@ -922,7 +922,7 @@ void ml_recover(bool checkext) if (b0p->b0_flags & B0_HAS_FENC) { int fnsize = B0_FNAME_SIZE_NOCRYPT; - for (p = (char *)b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; p--) {} + for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; p--) {} b0_fenc = xstrnsave(p, (size_t)(b0p->b0_fname + fnsize - p)); } @@ -1411,11 +1411,11 @@ void get_b0_dict(const char *fname, dict_T *d) } else { // We have swap information. tv_dict_add_str_len(d, S_LEN("version"), b0.b0_version, 10); - tv_dict_add_str_len(d, S_LEN("user"), (char *)b0.b0_uname, + tv_dict_add_str_len(d, S_LEN("user"), b0.b0_uname, B0_UNAME_SIZE); - tv_dict_add_str_len(d, S_LEN("host"), (char *)b0.b0_hname, + tv_dict_add_str_len(d, S_LEN("host"), b0.b0_hname, B0_HNAME_SIZE); - tv_dict_add_str_len(d, S_LEN("fname"), (char *)b0.b0_fname, + tv_dict_add_str_len(d, S_LEN("fname"), b0.b0_fname, B0_FNAME_SIZE_ORG); tv_dict_add_nr(d, S_LEN("pid"), char_to_long(b0.b0_pid)); @@ -1480,7 +1480,7 @@ static time_t swapfile_info(char *fname) if (b0.b0_fname[0] == NUL) { msg_puts(_("[No Name]")); } else { - msg_outtrans((char *)b0.b0_fname); + msg_outtrans(b0.b0_fname); } msg_puts(_("\n modified: ")); @@ -1488,7 +1488,7 @@ static time_t swapfile_info(char *fname) if (*(b0.b0_uname) != NUL) { msg_puts(_("\n user name: ")); - msg_outtrans((char *)b0.b0_uname); + msg_outtrans(b0.b0_uname); } if (*(b0.b0_hname) != NUL) { @@ -1497,7 +1497,7 @@ static time_t swapfile_info(char *fname) } else { msg_puts(_("\n host name: ")); } - msg_outtrans((char *)b0.b0_hname); + msg_outtrans(b0.b0_hname); } if (char_to_long(b0.b0_pid) != 0L) { @@ -2022,7 +2022,6 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo int lineadd; blocknr_T bnum_left, bnum_right; linenr_T lnum_left, lnum_right; - int pb_idx; PTR_BL *pp_new; // We are going to allocate a new data block. Depending on the @@ -2156,7 +2155,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo // update pointer blocks for the new data block for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; stack_idx--) { infoptr_T *ip = &(buf->b_ml.ml_stack[stack_idx]); - pb_idx = ip->ip_index; + int pb_idx = ip->ip_index; if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) { return FAIL; } @@ -3029,7 +3028,7 @@ char *makeswapname(char *fname, char *ffname, buf_T *buf, char *dir_name) // Expand symlink in the file name, so that we put the swap file with the // actual file instead of with the symlink. - if (resolve_symlink(fname, (char *)fname_buf) == OK) { + if (resolve_symlink(fname, fname_buf) == OK) { fname_res = fname_buf; } #endif @@ -3211,7 +3210,6 @@ static int do_swapexists(buf_T *buf, char *fname) static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_existing_dir) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 2, 4) { - size_t n; char *buf_fname = buf->b_fname; // Isolate a directory name from *dirp and put it in dir_name. @@ -3224,6 +3222,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_ char *fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); for (;;) { + size_t n; if (fname == NULL) { // must be out of memory break; } @@ -3267,12 +3266,12 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_ // have a different mountpoint. if (b0.b0_flags & B0_SAME_DIR) { if (path_fnamecmp(path_tail(buf->b_ffname), - path_tail((char *)b0.b0_fname)) != 0 + path_tail(b0.b0_fname)) != 0 || !same_directory(fname, buf->b_ffname)) { // Symlinks may point to the same file even // when the name differs, need to check the // inode too. - expand_env((char *)b0.b0_fname, NameBuff, MAXPATHL); + expand_env(b0.b0_fname, NameBuff, MAXPATHL); if (fnamecmp_ino(buf->b_ffname, NameBuff, char_to_long(b0.b0_ino))) { differ = true; @@ -3281,7 +3280,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_ } else { // The name in the swap file may be // "~user/path/file". Expand it first. - expand_env((char *)b0.b0_fname, NameBuff, MAXPATHL); + expand_env(b0.b0_fname, NameBuff, MAXPATHL); if (fnamecmp_ino(buf->b_ffname, NameBuff, char_to_long(b0.b0_ino))) { differ = true; @@ -3516,8 +3515,8 @@ static bool fnamecmp_ino(char *fname_c, char *fname_s, long ino_block0) // One of the inode numbers is unknown, try a forced vim_FullName() and // compare the file names. - retval_c = vim_FullName(fname_c, (char *)buf_c, MAXPATHL, true); - retval_s = vim_FullName(fname_s, (char *)buf_s, MAXPATHL, true); + retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, true); + retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, true); if (retval_c == OK && retval_s == OK) { return strcmp(buf_c, buf_s) != 0; } @@ -3605,11 +3604,8 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) linenr_T curline = ml_upd_lastcurline; int curix = ml_upd_lastcurix; - long size; chunksize_T *curchnk; - int rest; bhdr_T *hp; - DATA_BL *dp; if (buf->b_ml.ml_usedchunks == -1 || len == 0) { return; @@ -3655,6 +3651,8 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) } curchnk->mlcs_totalsize += len; if (updtype == ML_CHNK_ADDLINE) { + int rest; + DATA_BL *dp; curchnk->mlcs_numlines++; // May resize here so we don't have to do it in both cases below @@ -3665,17 +3663,14 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) } if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) { - int count; // number of entries in block - int idx; int text_end; - int linecnt; memmove(buf->b_ml.ml_chunksize + curix + 1, buf->b_ml.ml_chunksize + curix, (size_t)(buf->b_ml.ml_usedchunks - curix) * sizeof(chunksize_T)); // Compute length of first half of lines in the split chunk - size = 0; - linecnt = 0; + long size = 0; + int linecnt = 0; while (curline < buf->b_ml.ml_line_count && linecnt < MLCS_MINL) { if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL) { @@ -3683,8 +3678,9 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) return; } dp = hp->bh_data; - count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1; - idx = curline - buf->b_ml.ml_locked_low; + int count + = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1; // number of entries in block + int idx = curline - buf->b_ml.ml_locked_low; curline = buf->b_ml.ml_locked_high + 1; if (idx == 0) { // first line in block, text at the end text_end = (int)dp->db_txt_end; @@ -3793,13 +3789,8 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) int curix; long size; bhdr_T *hp; - DATA_BL *dp; - int count; // number of entries in block - int idx; - int start_idx; int text_end; long offset; - int len; int ffdos = !no_ff && (get_fileformat(buf) == EOL_DOS); int extra = 0; @@ -3859,9 +3850,11 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL) { return -1; } - dp = hp->bh_data; - count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1; - start_idx = idx = curline - buf->b_ml.ml_locked_low; + DATA_BL *dp = hp->bh_data; + int count + = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1; // number of entries in block + int idx; + int start_idx = idx = curline - buf->b_ml.ml_locked_low; if (idx == 0) { // first line in block, text at the end text_end = (int)dp->db_txt_end; } else { @@ -3889,7 +3882,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) idx++; } } - len = text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK); + int len = text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK); size += len; if (offset != 0 && size >= offset) { if (size + ffdos == offset) { diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 2a18b08d8d..4fad926cb0 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -281,7 +281,6 @@ static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const char *next_name; char c; char d; - int i; int pri_idx = 0; int old_modes = 0; int amenu; @@ -411,7 +410,7 @@ static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const p = (call_data == NULL) ? NULL : xstrdup(call_data); // loop over all modes, may add more than one - for (i = 0; i < MENU_MODES; i++) { + for (int i = 0; i < MENU_MODES; i++) { if (modes & (1 << i)) { // free any old menu free_menu_string(menu, i); @@ -617,10 +616,7 @@ static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent) // Free the given menu structure and remove it from the linked list. static void free_menu(vimmenu_T **menup) { - int i; - vimmenu_T *menu; - - menu = *menup; + vimmenu_T *menu = *menup; // Don't change *menup until after calling gui_mch_destroy_menu(). The // MacOS code needs the original structure to properly delete the menu. @@ -630,7 +626,7 @@ static void free_menu(vimmenu_T **menup) xfree(menu->en_name); xfree(menu->en_dname); xfree(menu->actext); - for (i = 0; i < MENU_MODES; i++) { + for (int i = 0; i < MENU_MODES; i++) { free_menu_string(menu, i); } xfree(menu); @@ -640,9 +636,8 @@ static void free_menu(vimmenu_T **menup) static void free_menu_string(vimmenu_T *menu, int idx) { int count = 0; - int i; - for (i = 0; i < MENU_MODES; i++) { + for (int i = 0; i < MENU_MODES; i++) { if (menu->strings[i] == menu->strings[idx]) { count++; } @@ -662,13 +657,11 @@ static void free_menu_string(vimmenu_T *menu, int idx) /// @see menu_get static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes) { - dict_T *dict; - if (!menu || (menu->modes & modes) == 0x0) { return NULL; } - dict = tv_dict_alloc(); + dict_T *dict = tv_dict_alloc(); tv_dict_add_str(dict, S_LEN("name"), menu->dname); tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority); tv_dict_add_nr(dict, S_LEN("hidden"), menu_is_hidden(menu->dname)); @@ -815,7 +808,6 @@ static int show_menus(char *const path_name, int modes) static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) { int i; - int bit; if (menu != NULL && (menu->modes & modes) == 0x0) { return; @@ -838,7 +830,7 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) } if (menu != NULL && menu->children == NULL) { - for (bit = 0; bit < MENU_MODES; bit++) { + for (int bit = 0; bit < MENU_MODES; bit++) { if ((menu->modes & modes & (1 << bit)) != 0) { msg_putchar('\n'); if (got_int) { // "q" hit for "--more--" @@ -902,7 +894,6 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for char *after_dot; char *p; char *path_name = NULL; - char *name; int unmenu; vimmenu_T *menu; int expand_menus; @@ -963,7 +954,7 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for path_name = xmalloc(path_len); xstrlcpy(path_name, arg, path_len); } - name = path_name; + char *name = path_name; while (name != NULL && *name) { p = menu_name_skip(name); while (menu != NULL) { diff --git a/src/nvim/message.c b/src/nvim/message.c index 40453211b4..4904bde095 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -369,14 +369,13 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) char *msg_strtrunc(char *s, int force) { char *buf = NULL; - int len; - int room; // May truncate message to avoid a hit-return prompt if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL) && !exmode_active && msg_silent == 0 && !ui_has(kUIMessages)) || force) { - len = vim_strsize(s); + int room; + int len = vim_strsize(s); if (msg_scrolled != 0) { // Use all the columns. room = (Rows - msg_row) * Columns - 1; @@ -1033,7 +1032,6 @@ void ex_messages(void *const eap_p) { const exarg_T *const eap = (const exarg_T *)eap_p; struct msg_hist *p; - int c = 0; if (strcmp(eap->arg, "clear") == 0) { int keep = eap->addr_count == 0 ? 0 : eap->line2; @@ -1052,6 +1050,7 @@ void ex_messages(void *const eap_p) p = first_msg_hist; if (eap->addr_count != 0) { + int c = 0; // Count total messages for (; p != NULL && !got_int; p = p->next) { c++; @@ -1085,7 +1084,7 @@ void ex_messages(void *const eap_p) } else if (p->msg && p->msg[0]) { Array content_entry = ARRAY_DICT_INIT; ADD(content_entry, INTEGER_OBJ(p->attr)); - ADD(content_entry, STRING_OBJ(cstr_to_string((char *)(p->msg)))); + ADD(content_entry, STRING_OBJ(cstr_to_string(p->msg))); ADD(content, ARRAY_OBJ(content_entry)); } ADD(entry, ARRAY_OBJ(content)); @@ -1470,9 +1469,9 @@ void msg_putchar_attr(int c, int attr) buf[2] = (char)K_THIRD(c); buf[3] = NUL; } else { - buf[utf_char2bytes(c, (char *)buf)] = NUL; + buf[utf_char2bytes(c, buf)] = NUL; } - msg_puts_attr((const char *)buf, attr); + msg_puts_attr(buf, attr); } void msg_outnum(long n) @@ -1542,7 +1541,6 @@ int msg_outtrans_len_attr(const char *msgstr, int len, int attr) const char *str = msgstr; const char *plain_start = msgstr; char *s; - int mb_l; int c; int save_got_int = got_int; @@ -1565,7 +1563,7 @@ int msg_outtrans_len_attr(const char *msgstr, int len, int attr) // Normal characters are printed several at a time. while (--len >= 0 && !got_int) { // Don't include composing chars after the end. - mb_l = utfc_ptr2len_len(str, len + 1); + int mb_l = utfc_ptr2len_len(str, len + 1); if (mb_l > 1) { c = utf_ptr2char(str); if (vim_isprintc(c)) { @@ -2139,7 +2137,7 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) int t_col = 0; // Screen cells todo, 0 when "t_s" not used. int l; int cw; - const char *sb_str = (char *)str; + const char *sb_str = str; int sb_col = msg_col; int wrap; int did_last_char; @@ -2153,7 +2151,7 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) } // Concat pieces with the same highlight size_t len = strnlen(str, (size_t)maxlen); // -V781 - ga_concat_len(&msg_ext_last_chunk, (char *)str, len); + ga_concat_len(&msg_ext_last_chunk, str, len); msg_ext_cur_len += len; return; } @@ -2652,12 +2650,11 @@ void msg_sb_eol(void) static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp) { msgchunk_T *mp = smp; - char *p; for (;;) { msg_row = row; msg_col = mp->sb_msg_col; - p = mp->sb_text; + char *p = mp->sb_text; if (*p == '\n') { // don't display the line break p++; } @@ -2767,7 +2764,6 @@ static int do_more_prompt(int typed_char) int oldState = State; int c; int retval = false; - int toscroll; bool to_redraw = false; msgchunk_T *mp_last = NULL; msgchunk_T *mp; @@ -2809,7 +2805,7 @@ static int do_more_prompt(int typed_char) c = get_keystroke(resize_events); } - toscroll = 0; + int toscroll = 0; switch (c) { case BS: // scroll one line back case K_BS: @@ -3507,7 +3503,6 @@ int do_dialog(int type, char *title, char *message, char *buttons, int dfltbutto { int retval = 0; char *hotkeys; - int c; int i; if (silent_mode // No dialogs in silent mode ("ex -s") @@ -3530,7 +3525,7 @@ int do_dialog(int type, char *title, char *message, char *buttons, int dfltbutto for (;;) { // Get a typed character directly from the user. - c = get_keystroke(NULL); + int c = get_keystroke(NULL); switch (c) { case CAR: // User accepts default option case NL: diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 950b025e53..60efd6a72a 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -86,15 +86,11 @@ static int get_mouse_class(char *p) /// Move "pos" back to the start of the word it's in. static void find_start_of_word(pos_T *pos) { - char *line; - int cclass; - int col; - - line = ml_get(pos->lnum); - cclass = get_mouse_class(line + pos->col); + char *line = ml_get(pos->lnum); + int cclass = get_mouse_class(line + pos->col); while (pos->col > 0) { - col = pos->col - 1; + int col = pos->col - 1; col -= utf_head_off(line, line + col); if (get_mouse_class(line + col) != cclass) { break; @@ -109,7 +105,6 @@ static void find_end_of_word(pos_T *pos) { char *line; int cclass; - int col; line = ml_get(pos->lnum); if (*p_sel == 'e' && pos->col > 0) { @@ -118,7 +113,7 @@ static void find_end_of_word(pos_T *pos) } cclass = get_mouse_class(line + pos->col); while (line[pos->col] != NUL) { - col = pos->col + utfc_ptr2len(line + pos->col); + int col = pos->col + utfc_ptr2len(line + pos->col); if (get_mouse_class(line + col) != cclass) { if (*p_sel == 'e') { pos->col = col; @@ -296,18 +291,16 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) bool in_status_line; // mouse in status line static bool in_tab_line = false; // mouse clicked in tab line bool in_sep_line; // mouse in vertical separator line - int c1, c2; - pos_T save_cursor; + int c1; win_T *old_curwin = curwin; static pos_T orig_cursor; colnr_T leftcol, rightcol; pos_T end_visual; - long diff; int old_active = VIsual_active; int old_mode = VIsual_mode; int regname; - save_cursor = curwin->w_cursor; + pos_T save_cursor = curwin->w_cursor; for (;;) { which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag); @@ -731,6 +724,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) } if (start_visual.lnum) { // right click in visual mode + long diff; // When ALT is pressed make Visual mode blockwise. if (mod_mask & MOD_MASK_ALT) { VIsual_mode = Ctrl_V; @@ -800,6 +794,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) // Middle mouse click: Put text before cursor. if (which_button == MOUSE_MIDDLE) { + int c2; if (regname == 0 && eval_has_provider("clipboard")) { regname = '*'; } @@ -888,13 +883,13 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) // A double click selects a word or a block. if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) { pos_T *pos = NULL; - int gc; if (is_click) { // If the character under the cursor (skipping white space) is // not a word character, try finding a match and select a (), // {}, [], #if/#endif, etc. block. end_visual = curwin->w_cursor; + int gc; while (gc = gchar_pos(&end_visual), ascii_iswhite(gc)) { inc(&end_visual); } @@ -1388,16 +1383,14 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) { int col = *colp; int row = *rowp; - linenr_T lnum; bool retval = false; - int off; int count; if (win->w_p_rl) { col = win->w_width_inner - 1 - col; } - lnum = win->w_topline; + linenr_T lnum = win->w_topline; while (row > 0) { // Don't include filler lines in "count" @@ -1429,7 +1422,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) if (!retval) { // Compute the column without wrapping. - off = win_col_off(win) - win_col_off2(win); + int off = win_col_off(win) - win_col_off2(win); if (col < off) { col = off; } @@ -1467,9 +1460,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) return NULL; } - frame_T *fp; - - fp = topframe; + frame_T *fp = topframe; *rowp -= firstwin->w_winrow; for (;;) { if (fp->fr_layout == FR_LEAF) { @@ -1716,10 +1707,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col) ptr_end += utfc_ptr2len(ptr_end); } - int matchid; int prev_matchid; int nudge = 0; - int cwidth = 0; vcol = offset; @@ -1727,7 +1716,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) #define DECR() nudge--; ptr_end -= utfc_ptr2len((char *)ptr_end) while (ptr < ptr_end && *ptr != NUL) { - cwidth = win_chartabsize(curwin, ptr, vcol); + int cwidth = win_chartabsize(curwin, ptr, vcol); vcol += cwidth; if (cwidth > 1 && *ptr == '\t' && nudge > 0) { // A tab will "absorb" any previous adjustments. @@ -1738,7 +1727,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) } } - matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); + int matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); if (matchid != 0) { if (wp->w_p_cole == 3) { INCR(); @@ -1780,9 +1769,7 @@ int mouse_check_fold(void) int max_col = Columns; int multigrid = ui_has(kUIMultigrid); - win_T *wp; - - wp = mouse_find_win(&click_grid, &click_row, &click_col); + win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col); if (wp && multigrid) { max_row = wp->w_grid_alloc.rows; max_col = wp->w_grid_alloc.cols; diff --git a/src/nvim/move.c b/src/nvim/move.c index 3af26b910e..a946633bf6 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -145,7 +145,6 @@ void update_topline(win_T *wp) { linenr_T old_topline; int old_topfill; - bool check_topline = false; bool check_botline = false; long *so_ptr = wp->w_p_so >= 0 ? &wp->w_p_so : &p_so; long save_so = *so_ptr; @@ -189,6 +188,7 @@ void update_topline(win_T *wp) wp->w_viewport_invalid = true; wp->w_scbind_pos = 1; } else { + bool check_topline = false; // If the cursor is above or near the top of the window, scroll the window // to show the line the cursor is in, with 'scrolloff' context. if (wp->w_topline > 1) { diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 34c8f89e3f..f8be0d4c8d 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -550,6 +550,10 @@ void rpc_close(Channel *channel) if (channel->streamtype == kChannelStreamStdio || (channel->id == ui_client_channel_id && channel->streamtype != kChannelStreamProc)) { + if (channel->streamtype == kChannelStreamStdio) { + // Avoid hanging when there are no other UIs and a prompt is triggered on exit. + remote_ui_disconnect(channel->id); + } exit_from_channel(0); } } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index b88cfb8926..a84d5c73a4 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -401,10 +401,8 @@ void init_normal_cmds(void) /// @return -1 for invalid command. static int find_command(int cmdchar) { - int i; int idx; int top, bot; - int c; // A multi-byte character is never a command. if (cmdchar >= 0x100) { @@ -429,8 +427,8 @@ static int find_command(int cmdchar) top = NV_CMDS_SIZE - 1; idx = -1; while (bot <= top) { - i = (top + bot) / 2; - c = nv_cmds[nv_cmd_idx[i]].cmd_char; + int i = (top + bot) / 2; + int c = nv_cmds[nv_cmd_idx[i]].cmd_char; if (c < 0) { c = -c; } @@ -693,7 +691,6 @@ static void normal_get_additional_char(NormalState *s) int *cp; bool repl = false; // get character for replace mode bool lit = false; // get extra character literally - bool langmap_active = false; // using :lmap mappings int lang; // getting a text character no_mapping++; @@ -729,6 +726,7 @@ static void normal_get_additional_char(NormalState *s) // Get a second or third character. if (cp != NULL) { + bool langmap_active = false; // using :lmap mappings if (repl) { State = MODE_REPLACE; // pretend Replace mode ui_cursor_shape(); // show different cursor shape @@ -1848,7 +1846,6 @@ void clear_showcmd(void) snprintf(showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64, (int64_t)lines); } else { char *s, *e; - int l; int bytes = 0; int chars = 0; @@ -1860,7 +1857,7 @@ void clear_showcmd(void) e = ml_get_pos(&VIsual); } while ((*p_sel != 'e') ? s <= e : s < e) { - l = utfc_ptr2len(s); + int l = utfc_ptr2len(s); if (l == 0) { bytes++; chars++; @@ -2427,7 +2424,6 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist) int linelen = linetabsize(get_cursor_line_ptr()); bool retval = true; bool atend = false; - int n; int col_off1; // margin offset for first screen line int col_off2; // margin offset for wrapped screen line int width1; // text width for first screen line @@ -2446,6 +2442,7 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist) } if (curwin->w_width_inner != 0) { + int n; // Instead of sticking at the last character of the buffer line we // try to stick in the last column of the screen. if (curwin->w_curswant == MAXCOL) { @@ -2793,7 +2790,6 @@ static int nv_zg_zw(cmdarg_T *cap, int nchar) /// Commands that start with "z". static void nv_zet(cmdarg_T *cap) { - int n; colnr_T col; int nchar = cap->nchar; long old_fdl = curwin->w_p_fdl; @@ -2949,7 +2945,7 @@ static void nv_zet(cmdarg_T *cap) } else { getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); } - n = curwin->w_width_inner - curwin_col_off(); + int n = curwin->w_width_inner - curwin_col_off(); if (col + siso < n) { col = 0; } else { @@ -3438,7 +3434,6 @@ static void nv_ident(cmdarg_T *cap) int cmdchar; bool g_cmd; // "g" command bool tag_cmd = false; - char *aux_ptr; if (cap->cmdchar == 'g') { // "g*", "g#", "g]" and "gCTRL-]" cmdchar = cap->nchar; @@ -3542,6 +3537,7 @@ static void nv_ident(cmdarg_T *cap) STRCAT(buf, p); xfree(p); } else { + char *aux_ptr; if (cmdchar == '*') { aux_ptr = (magic_isset() ? "/.*~[^$\\" : "/^$\\"); } else if (cmdchar == '#') { @@ -3653,10 +3649,8 @@ static void nv_tagpop(cmdarg_T *cap) /// Handle scrolling command 'H', 'L' and 'M'. static void nv_scroll(cmdarg_T *cap) { - int used = 0; long n; linenr_T lnum; - int half; cap->oap->motion_type = kMTLineWise; setpcmark(); @@ -3683,11 +3677,12 @@ static void nv_scroll(cmdarg_T *cap) } } else { if (cap->cmdchar == 'M') { + int used = 0; // Don't count filler lines above the window. used -= win_get_fill(curwin, curwin->w_topline) - curwin->w_topfill; validate_botline(curwin); // make sure w_empty_rows is valid - half = (curwin->w_height_inner - curwin->w_empty_rows + 1) / 2; + int half = (curwin->w_height_inner - curwin->w_empty_rows + 1) / 2; for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; n++) { // Count half the number of filler lines to be "below this // line" and half to be "above the next line". @@ -4115,7 +4110,6 @@ static void nv_bracket_block(cmdarg_T *cap, const pos_T *old_pos) pos_T prev_pos; long n; int findc; - int c; if (cap->nchar == '*') { cap->nchar = '/'; @@ -4155,6 +4149,7 @@ static void nv_bracket_block(cmdarg_T *cap, const pos_T *old_pos) // Try finding the '{' or '}' we want to be at. // Also repeat for the given count. if (cap->nchar == 'm' || cap->nchar == 'M') { + int c; // norm is true for "]M" and "[m" int norm = ((findc == '{') == (cap->nchar == 'm')); @@ -4361,7 +4356,6 @@ static void nv_brackets(cmdarg_T *cap) /// Handle Normal mode "%" command. static void nv_percent(cmdarg_T *cap) { - pos_T *pos; linenr_T lnum = curwin->w_cursor.lnum; cap->oap->inclusive = true; @@ -4391,6 +4385,7 @@ static void nv_percent(cmdarg_T *cap) beginline(BL_SOL | BL_FIX); } } else { // "%" : go to matching paren + pos_T *pos; cap->oap->motion_type = kMTCharWise; cap->oap->use_reg_one = true; if ((pos = findmatch(cap->oap, NUL)) == NULL) { @@ -6046,9 +6041,8 @@ static void adjust_for_sel(cmdarg_T *cap) /// @return true when backed up to the previous line. bool unadjust_for_sel(void) { - pos_T *pp; - if (*p_sel == 'e' && !equalpos(VIsual, curwin->w_cursor)) { + pos_T *pp; if (lt(VIsual, curwin->w_cursor)) { pp = &curwin->w_cursor; } else { @@ -6460,7 +6454,6 @@ static void nv_put(cmdarg_T *cap) /// @param fix_indent true for "[p", "[P", "]p" and "]P". static void nv_put_opt(cmdarg_T *cap, bool fix_indent) { - int regname = 0; yankreg_T *savereg = NULL; bool empty = false; bool was_visual = false; @@ -6506,7 +6499,7 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) // Need to save and restore the registers that the delete // overwrites if the old contents is being put. was_visual = true; - regname = cap->oap->regname; + int regname = cap->oap->regname; bool keep_registers = cap->cmdchar == 'P'; // '+' and '*' could be the same selection bool clipoverwrite = (regname == '+' || regname == '*') && (cb_flags & CB_UNNAMEDMASK); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 435ca106ab..e89844098b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -214,7 +214,6 @@ int get_extra_op_char(int optype) void op_shift(oparg_T *oap, int curs_top, int amount) { long i; - int first_char; int block_col = 0; if (u_save((linenr_T)(oap->start.lnum - 1), @@ -227,7 +226,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) } for (i = oap->line_count - 1; i >= 0; i--) { - first_char = (uint8_t)(*get_cursor_line_ptr()); + int first_char = (uint8_t)(*get_cursor_line_ptr()); if (first_char == NUL) { // empty line curwin->w_cursor.col = 0; } else if (oap->motion_type == kMTBlockWise) { @@ -289,15 +288,13 @@ void op_shift(oparg_T *oap, int curs_top, int amount) /// @param call_changed_bytes call changed_bytes() void shift_line(int left, int round, int amount, int call_changed_bytes) { - int count; - int i, j; const int sw_val = (int)get_sw_value_indent(curbuf); - count = get_indent(); // get current indent + int count = get_indent(); // get current indent if (round) { // round off indent - i = count / sw_val; // number of 'shiftwidth' rounded down - j = count % sw_val; // extra spaces + int i = count / sw_val; // number of 'shiftwidth' rounded down + int j = count % sw_val; // extra spaces if (j && left) { // first remove extra spaces amount--; } @@ -636,8 +633,6 @@ static void block_insert(oparg_T *oap, char *s, int b_insert, struct block_def * void op_reindent(oparg_T *oap, Indenter how) { long i = 0; - char *l; - int amount; linenr_T first_changed = 0; linenr_T last_changed = 0; linenr_T start_lnum = curwin->w_cursor.lnum; @@ -652,6 +647,8 @@ void op_reindent(oparg_T *oap, Indenter how) // for each line separately, especially when undoing. if (u_savecommon(curbuf, start_lnum - 1, start_lnum + (linenr_T)oap->line_count, start_lnum + (linenr_T)oap->line_count, false) == OK) { + char *l; + int amount; for (i = oap->line_count - 1; i >= 0 && !got_int; i--) { // it's a slow thing to do, so give feedback so there's no worry // that the computer's just hung. @@ -902,7 +899,6 @@ bool yank_register_mline(int regname) /// @return FAIL for failure, OK otherwise. int do_record(int c) { - char *p; static int regname; yankreg_T *old_y_previous; int retval; @@ -927,10 +923,10 @@ int do_record(int c) dict_T *dict = get_v_event(&save_v_event); // The recorded text contents. - p = (char *)get_recorded(); + char *p = get_recorded(); if (p != NULL) { // Remove escaping for K_SPECIAL in multi-byte chars. - vim_unescape_ks((char_u *)p); + vim_unescape_ks(p); (void)tv_dict_add_str(dict, S_LEN("regcontents"), (const char *)p); } @@ -1149,7 +1145,6 @@ int do_execreg(int regname, int colon, int addcr, int silent) // Insert lines into typeahead buffer, from last one to first one. put_reedit_in_typebuf(silent); - char *escaped; for (size_t i = reg->y_size; i-- > 0;) { // from y_size - 1 to 0 included // insert NL between lines and after last line if type is kMTLineWise if (reg->y_type == kMTLineWise || i < reg->y_size - 1 || addcr) { @@ -1168,7 +1163,7 @@ int do_execreg(int regname, int colon, int addcr, int silent) free_str = true; } } - escaped = vim_strsave_escape_ks(str); + char *escaped = vim_strsave_escape_ks(str); if (free_str) { xfree(str); } @@ -1651,10 +1646,9 @@ int op_delete(oparg_T *oap) } } else { if (virtual_op) { - int endcol = 0; - // For virtualedit: break the tabs that are partly included. if (gchar_pos(&oap->start) == '\t') { + int endcol = 0; if (u_save_cursor() == FAIL) { // save first line for undo return FAIL; } @@ -1820,10 +1814,7 @@ static void replace_character(int c) /// Replace a whole area with one character. static int op_replace(oparg_T *oap, int c) { - int n, numc; - int num_chars; - char *newp, *oldp; - colnr_T oldlen; + int n; struct block_def bd; char *after_p = NULL; int had_ctrl_v_cr = false; @@ -1848,6 +1839,11 @@ static int op_replace(oparg_T *oap, int c) // block mode replace if (oap->motion_type == kMTBlockWise) { + int numc; + int num_chars; + char *newp; + char *oldp; + colnr_T oldlen; bd.is_MAX = (curwin->w_curswant == MAXCOL); for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) { curwin->w_cursor.col = 0; // make sure cursor position is valid @@ -2218,12 +2214,11 @@ bool swapchar(int op_type, pos_T *pos) /// Insert and append operators for Visual mode. void op_insert(oparg_T *oap, long count1) { - long ins_len, pre_textlen = 0; - char *firstline, *ins_text; - colnr_T ind_pre_col = 0, ind_post_col; - int ind_pre_vcol = 0, ind_post_vcol = 0; + long pre_textlen = 0; + char *firstline; + colnr_T ind_pre_col = 0; + int ind_pre_vcol = 0; struct block_def bd; - int i; pos_T t1; // edit() changes this - record it for OP_APPEND @@ -2284,7 +2279,7 @@ void op_insert(oparg_T *oap, long count1) if (u_save_cursor() == FAIL) { return; } - for (i = 0; i < bd.endspaces; i++) { + for (int i = 0; i < bd.endspaces; i++) { ins_char(' '); } bd.textlen += bd.endspaces; @@ -2321,12 +2316,13 @@ void op_insert(oparg_T *oap, long count1) } if (oap->motion_type == kMTBlockWise) { + int ind_post_vcol = 0; struct block_def bd2; bool did_indent = false; // if indent kicked in, the firstline might have changed // but only do that, if the indent actually increased - ind_post_col = (colnr_T)getwhitecols_curline(); + colnr_T ind_post_col = (colnr_T)getwhitecols_curline(); if (curbuf->b_op_start.col > ind_pre_col && ind_post_col > ind_pre_col) { bd.textcol += ind_post_col - ind_pre_col; ind_post_vcol = get_indent(); @@ -2414,9 +2410,9 @@ void op_insert(oparg_T *oap, long count1) } else { firstline += add; } - ins_len = (long)strlen(firstline) - pre_textlen - offset; + long ins_len = (long)strlen(firstline) - pre_textlen - offset; if (pre_textlen >= 0 && ins_len > 0) { - ins_text = xstrnsave(firstline, (size_t)ins_len); + char *ins_text = xstrnsave(firstline, (size_t)ins_len); // block handled here if (u_save(oap->start.lnum, (linenr_T)(oap->end.lnum + 1)) == OK) { block_insert(oap, ins_text, (oap->op_type == OP_INSERT), &bd); @@ -2434,20 +2430,13 @@ void op_insert(oparg_T *oap, long count1) /// @return true if edit() returns because of a CTRL-O command int op_change(oparg_T *oap) { - colnr_T l; int retval; - long offset; - linenr_T linenr; - long ins_len; long pre_textlen = 0; long pre_indent = 0; - char *newp; char *firstline; - char *ins_text; - char *oldp; struct block_def bd; - l = oap->start.col; + colnr_T l = oap->start.col; if (oap->motion_type == kMTLineWise) { l = 0; can_si = may_do_si(); // Like opening a new line, do smart indent @@ -2499,6 +2488,7 @@ int op_change(oparg_T *oap) // Don't repeat the insert when Insert mode ended with CTRL-C. if (oap->motion_type == kMTBlockWise && oap->start.lnum != oap->end.lnum && !got_int) { + long ins_len; // Auto-indenting may have changed the indent. If the cursor was past // the indent, exclude that indent change from the inserted text. firstline = ml_get(oap->start.lnum); @@ -2511,11 +2501,14 @@ int op_change(oparg_T *oap) ins_len = (long)strlen(firstline) - pre_textlen; if (ins_len > 0) { + long offset; + char *newp; + char *oldp; // Subsequent calls to ml_get() flush the firstline data - take a // copy of the inserted text. - ins_text = xmalloc((size_t)(ins_len + 1)); + char *ins_text = xmalloc((size_t)(ins_len + 1)); xstrlcpy(ins_text, firstline + bd.textcol, (size_t)ins_len + 1); - for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum; + for (linenr_T linenr = oap->start.lnum + 1; linenr <= oap->end.lnum; linenr++) { block_prep(oap, &bd, linenr, true); if (!bd.is_short || virtual_op) { @@ -2619,7 +2612,6 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) yankreg_T newreg; // new yank register when appending char **new_ptr; linenr_T lnum; // current line number - size_t j; MotionType yank_type = oap->motion_type; size_t yanklines = (size_t)oap->line_count; linenr_T yankendlnum = oap->end.lnum; @@ -2743,6 +2735,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) } if (curr != reg) { // append the new block to the old block + size_t j; new_ptr = xmalloc(sizeof(char *) * (curr->y_size + reg->y_size)); for (j = 0; j < curr->y_size; j++) { new_ptr[j] = curr->y_array[j]; @@ -3773,7 +3766,6 @@ void ex_display(exarg_T *eap) { char *p; yankreg_T *yb; - int name; char *arg = eap->arg; int clen; int type; @@ -3786,7 +3778,7 @@ void ex_display(exarg_T *eap) // Highlight title msg_puts_title(_("\nType Name Content")); for (int i = -1; i < NUM_REGISTERS && !got_int; i++) { - name = get_register_name(i); + int name = get_register_name(i); switch (get_reg_type(name, NULL)) { case kMTLineWise: type = 'l'; break; @@ -3856,7 +3848,7 @@ void ex_display(exarg_T *eap) } // display last inserted text - if ((p = (char *)get_last_insert()) != NULL + if ((p = get_last_insert()) != NULL && (arg == NULL || vim_strchr(arg, '.') != NULL) && !got_int && !message_filtered(p)) { msg_puts("\n c \". "); @@ -3912,13 +3904,11 @@ void ex_display(exarg_T *eap) static void dis_msg(const char *p, bool skip_esc) FUNC_ATTR_NONNULL_ALL { - int n; - int l; - - n = Columns - 6; + int n = Columns - 6; while (*p != NUL && !(*p == ESC && skip_esc && *(p + 1) == NUL) && (n -= ptr2cells(p)) >= 0) { + int l; if ((l = utfc_ptr2len(p)) > 1) { msg_outtrans_len(p, l); p += l; @@ -4137,7 +4127,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions linenr_T lnum = curwin->w_cursor.lnum + t; colnr_T mincol = (colnr_T)0; linenr_T lnum_amount = -t; - long col_amount = (cend - newp - spaces_removed); + colnr_T col_amount = (colnr_T)(cend - newp - spaces_removed); mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed); @@ -4389,7 +4379,6 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) changed_lines(pos.lnum, 0, pos.lnum + 1, 0L, true); } } else { - int one_change; int length; pos_T startpos; @@ -4429,7 +4418,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) length = oap->end.col - pos.col + 1; } } - one_change = do_addsub(oap->op_type, &pos, length, amount); + int one_change = do_addsub(oap->op_type, &pos, length, amount); if (one_change) { // Remember the start position of the first change. if (change_cnt == 0) { @@ -5323,7 +5312,6 @@ void cursor_pos_info(dict_T *dict) char *p; char buf1[50]; char buf2[40]; - linenr_T lnum; varnumber_T byte_count = 0; varnumber_T bom_count = 0; varnumber_T byte_count_cursor = 0; @@ -5331,9 +5319,6 @@ void cursor_pos_info(dict_T *dict) varnumber_T char_count_cursor = 0; varnumber_T word_count = 0; varnumber_T word_count_cursor = 0; - int eol_size; - varnumber_T last_check = 100000L; - long line_count_selected = 0; pos_T min_pos, max_pos; oparg_T oparg; struct block_def bd; @@ -5347,6 +5332,10 @@ void cursor_pos_info(dict_T *dict) return; } } else { + linenr_T lnum; + int eol_size; + varnumber_T last_check = 100000L; + long line_count_selected = 0; if (get_fileformat(curbuf) == EOL_DOS) { eol_size = 2; } else { @@ -5501,7 +5490,7 @@ void cursor_pos_info(dict_T *dict) validate_virtcol(); col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1); - col_print((char *)buf2, sizeof(buf2), (int)strlen(p), linetabsize(p)); + col_print(buf2, sizeof(buf2), (int)strlen(p), linetabsize(p)); if (char_count_cursor == byte_count_cursor && char_count == byte_count) { @@ -5777,22 +5766,20 @@ typedef struct { void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) { oparg_T *oap = cap->oap; - pos_T old_cursor; - bool empty_region_error; - int restart_edit_save; int lbr_saved = curwin->w_p_lbr; // The visual area is remembered for redo static redo_VIsual_T redo_VIsual = { NUL, 0, 0, 0, 0 }; - bool include_line_break = false; - - old_cursor = curwin->w_cursor; + pos_T old_cursor = curwin->w_cursor; // If an operation is pending, handle it... if ((finish_op || VIsual_active) && oap->op_type != OP_NOP) { + bool empty_region_error; + int restart_edit_save; + bool include_line_break = false; // Yank can be redone when 'y' is in 'cpoptions', but not when yanking // for the clipboard. const bool redo_yank = vim_strchr(p_cpo, CPO_YANK) != NULL && !gui_yank; @@ -5914,8 +5901,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) } else if (VIsual_mode == 'v') { // If 'selection' is "exclusive", backup one character for // charwise selections. - include_line_break = - unadjust_for_sel(); + include_line_break = unadjust_for_sel(); } oap->start = VIsual; diff --git a/src/nvim/option.c b/src/nvim/option.c index 066ca8f003..069304d9e1 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -30,7 +30,10 @@ #include <string.h> #include "auto/config.h" +#include "nvim/api/extmark.h" #include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" @@ -61,6 +64,7 @@ #include "nvim/keycodes.h" #include "nvim/locale.h" #include "nvim/log.h" +#include "nvim/lua/executor.h" #include "nvim/macros.h" #include "nvim/mapping.h" #include "nvim/mbyte.h" @@ -75,6 +79,8 @@ #include "nvim/option.h" #include "nvim/option_defs.h" #include "nvim/optionstr.h" +#include "nvim/os/input.h" +#include "nvim/os/lang.h" #include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/popupmenu.h" @@ -95,14 +101,10 @@ #include "nvim/undo.h" #include "nvim/vim.h" #include "nvim/window.h" -#ifdef MSWIN -# include "nvim/os/pty_conpty_win.h" + +#ifdef BACKSLASH_IN_FILENAME +# include "nvim/arglist.h" #endif -#include "nvim/api/extmark.h" -#include "nvim/api/private/helpers.h" -#include "nvim/lua/executor.h" -#include "nvim/os/input.h" -#include "nvim/os/lang.h" static char e_unknown_option[] = N_("E518: Unknown option"); @@ -165,121 +167,175 @@ void set_init_tablocal(void) p_ch = (long)options[ch_idx].def_val; } -/// Initialize the options, first part. -/// -/// Called only once from main(), just after creating the first buffer. -/// If "clean_arg" is true, Nvim was started with --clean. -/// -/// NOTE: ELOG() etc calls are not allowed here, as log location depends on -/// env var expansion which depends on expression evaluation and other -/// editor state initialized here. Do logging in set_init_2 or later. -void set_init_1(bool clean_arg) +/// Initialize the 'shell' option to a default value. +static void set_init_default_shell(void) { - langmap_init(); - // Find default value for 'shell' option. // Don't use it if it is empty. - { - const char *shell = os_getenv("SHELL"); - if (shell != NULL) { - if (vim_strchr(shell, ' ') != NULL) { - const size_t len = strlen(shell) + 3; // two quotes and a trailing NUL - char *const cmd = xmalloc(len); - snprintf(cmd, len, "\"%s\"", shell); - set_string_default("sh", cmd, true); - } else { - set_string_default("sh", (char *)shell, false); - } + const char *shell = os_getenv("SHELL"); + if (shell != NULL) { + if (vim_strchr(shell, ' ') != NULL) { + const size_t len = strlen(shell) + 3; // two quotes and a trailing NUL + char *const cmd = xmalloc(len); + snprintf(cmd, len, "\"%s\"", shell); + set_string_default("sh", cmd, true); + } else { + set_string_default("sh", (char *)shell, false); } } +} - // Set the default for 'backupskip' to include environment variables for - // temp files. - { +/// Set the default for 'backupskip' to include environment variables for +/// temp files. +static void set_init_default_backupskip(void) +{ #ifdef UNIX - static char *(names[4]) = { "", "TMPDIR", "TEMP", "TMP" }; + static char *(names[4]) = { "", "TMPDIR", "TEMP", "TMP" }; #else - static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" }; + static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" }; #endif - garray_T ga; - int opt_idx = findoption("backupskip"); + garray_T ga; + int opt_idx = findoption("backupskip"); - ga_init(&ga, 1, 100); - for (size_t n = 0; n < ARRAY_SIZE(names); n++) { - bool mustfree = true; - char *p; + ga_init(&ga, 1, 100); + for (size_t n = 0; n < ARRAY_SIZE(names); n++) { + bool mustfree = true; + char *p; #ifdef UNIX - if (*names[n] == NUL) { + if (*names[n] == NUL) { # ifdef __APPLE__ - p = "/private/tmp"; + p = "/private/tmp"; # else - p = "/tmp"; + p = "/tmp"; # endif - mustfree = false; - } else // NOLINT(readability/braces) + mustfree = false; + } else // NOLINT(readability/braces) #endif - { - p = vim_getenv(names[n]); - } - if (p != NULL && *p != NUL) { - // First time count the NUL, otherwise count the ','. - const size_t len = strlen(p) + 3; - char *item = xmalloc(len); - xstrlcpy(item, p, len); - add_pathsep(item); - xstrlcat(item, "*", len); - if (find_dup_item(ga.ga_data, item, options[opt_idx].flags) - == NULL) { - ga_grow(&ga, (int)len); - if (!GA_EMPTY(&ga)) { - STRCAT(ga.ga_data, ","); - } - STRCAT(ga.ga_data, p); - add_pathsep(ga.ga_data); - STRCAT(ga.ga_data, "*"); - ga.ga_len += (int)len; + { + p = vim_getenv(names[n]); + } + if (p != NULL && *p != NUL) { + // First time count the NUL, otherwise count the ','. + const size_t len = strlen(p) + 3; + char *item = xmalloc(len); + xstrlcpy(item, p, len); + add_pathsep(item); + xstrlcat(item, "*", len); + if (find_dup_item(ga.ga_data, item, options[opt_idx].flags) + == NULL) { + ga_grow(&ga, (int)len); + if (!GA_EMPTY(&ga)) { + STRCAT(ga.ga_data, ","); } - xfree(item); - } - if (mustfree) { - xfree(p); + STRCAT(ga.ga_data, p); + add_pathsep(ga.ga_data); + STRCAT(ga.ga_data, "*"); + ga.ga_len += (int)len; } + xfree(item); } - if (ga.ga_data != NULL) { - set_string_default("bsk", ga.ga_data, true); + if (mustfree) { + xfree(p); } } + if (ga.ga_data != NULL) { + set_string_default("bsk", ga.ga_data, true); + } +} - { - // Initialize the 'cdpath' option's default value. - char *cdpath = vim_getenv("CDPATH"); - if (cdpath != NULL) { - char *buf = xmalloc(2 * strlen(cdpath) + 2); - { - buf[0] = ','; // start with ",", current dir first - int j = 1; - for (int i = 0; cdpath[i] != NUL; i++) { - if (vim_ispathlistsep(cdpath[i])) { - buf[j++] = ','; - } else { - if (cdpath[i] == ' ' || cdpath[i] == ',') { - buf[j++] = '\\'; - } - buf[j++] = cdpath[i]; - } - } - buf[j] = NUL; - int opt_idx = findoption("cdpath"); - if (opt_idx >= 0) { - options[opt_idx].def_val = buf; - options[opt_idx].flags |= P_DEF_ALLOCED; - } else { - xfree(buf); // cannot happen - } +/// Initialize the 'cdpath' option to a default value. +static void set_init_default_cdpath(void) +{ + char *cdpath = vim_getenv("CDPATH"); + if (cdpath == NULL) { + return; + } + + char *buf = xmalloc(2 * strlen(cdpath) + 2); + buf[0] = ','; // start with ",", current dir first + int j = 1; + for (int i = 0; cdpath[i] != NUL; i++) { + if (vim_ispathlistsep(cdpath[i])) { + buf[j++] = ','; + } else { + if (cdpath[i] == ' ' || cdpath[i] == ',') { + buf[j++] = '\\'; } - xfree(cdpath); + buf[j++] = cdpath[i]; } } + buf[j] = NUL; + int opt_idx = findoption("cdpath"); + if (opt_idx >= 0) { + options[opt_idx].def_val = buf; + options[opt_idx].flags |= P_DEF_ALLOCED; + } else { + xfree(buf); // cannot happen + } + xfree(cdpath); +} + +/// Expand environment variables and things like "~" for the defaults. +/// If option_expand() returns non-NULL the variable is expanded. This can +/// only happen for non-indirect options. +/// Also set the default to the expanded value, so ":set" does not list +/// them. +/// Don't set the P_ALLOCED flag, because we don't want to free the +/// default. +static void set_init_expand_env(void) +{ + for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + vimoption_T *opt = &options[opt_idx]; + if (opt->flags & P_NO_DEF_EXP) { + continue; + } + char *p; + if ((opt->flags & P_GETTEXT) && opt->var != NULL) { + p = _(*(char **)opt->var); + } else { + p = option_expand(opt_idx, NULL); + } + if (p != NULL) { + p = xstrdup(p); + *(char **)opt->var = p; + if (opt->flags & P_DEF_ALLOCED) { + xfree(opt->def_val); + } + opt->def_val = p; + opt->flags |= P_DEF_ALLOCED; + } + } +} + +/// Initialize the encoding used for "default" in 'fileencodings'. +static void set_init_fenc_default(void) +{ + // enc_locale() will try to find the encoding of the current locale. + // This will be used when "default" is used as encoding specifier + // in 'fileencodings'. + char *p = enc_locale(); + if (p == NULL) { + // Use utf-8 as "default" if locale encoding can't be detected. + p = xmemdupz(S_LEN("utf-8")); + } + fenc_default = p; +} + +/// Initialize the options, first part. +/// +/// Called only once from main(), just after creating the first buffer. +/// If "clean_arg" is true, Nvim was started with --clean. +/// +/// NOTE: ELOG() etc calls are not allowed here, as log location depends on +/// env var expansion which depends on expression evaluation and other +/// editor state initialized here. Do logging in set_init_2 or later. +void set_init_1(bool clean_arg) +{ + langmap_init(); + + set_init_default_shell(); + set_init_default_backupskip(); + set_init_default_cdpath(); char *backupdir = stdpaths_user_state_subpath("backup", 2, true); const size_t backupdir_len = strlen(backupdir); @@ -328,33 +384,7 @@ void set_init_1(bool clean_arg) init_spell_chartab(); // Expand environment variables and things like "~" for the defaults. - // If option_expand() returns non-NULL the variable is expanded. This can - // only happen for non-indirect options. - // Also set the default to the expanded value, so ":set" does not list - // them. - // Don't set the P_ALLOCED flag, because we don't want to free the - // default. - for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) { - vimoption_T *opt = &options[opt_idx]; - if (opt->flags & P_NO_DEF_EXP) { - continue; - } - char *p; - if ((opt->flags & P_GETTEXT) && opt->var != NULL) { - p = _(*(char **)opt->var); - } else { - p = option_expand(opt_idx, NULL); - } - if (p != NULL) { - p = xstrdup(p); - *(char **)opt->var = p; - if (opt->flags & P_DEF_ALLOCED) { - xfree(opt->def_val); - } - opt->def_val = p; - opt->flags |= P_DEF_ALLOCED; - } - } + set_init_expand_env(); save_file_ff(curbuf); // Buffer is unchanged @@ -370,16 +400,7 @@ void set_init_1(bool clean_arg) didset_options2(); lang_init(); - - // enc_locale() will try to find the encoding of the current locale. - // This will be used when 'default' is used as encoding specifier - // in 'fileencodings' - char *p = enc_locale(); - if (p == NULL) { - // use utf-8 as 'default' if locale encoding can't be detected. - p = xmemdupz(S_LEN("utf-8")); - } - fenc_default = p; + set_init_fenc_default(); #ifdef HAVE_WORKING_LIBINTL // GNU gettext 0.10.37 supports this feature: set the codeset used for @@ -753,7 +774,7 @@ static void do_set_bool(int opt_idx, int opt_flags, int prefix, int nextchar, co } } - *errmsg = set_bool_option(opt_idx, (char_u *)varp, (int)value, opt_flags); + *errmsg = set_bool_option(opt_idx, (char *)varp, (int)value, opt_flags); } static void do_set_num(int opt_idx, int opt_flags, char **argp, int nextchar, const set_op_T op, @@ -1108,7 +1129,7 @@ static void do_set_string(int opt_idx, int opt_flags, char **argp, int nextchar, } // Set the new value. - *(char_u **)(varp) = (char_u *)newval; + *(char **)(varp) = newval; // origval may be freed by did_set_string_option(), make a copy. char *saved_origval = (origval != NULL) ? xstrdup(origval) : NULL; @@ -1973,7 +1994,7 @@ static void apply_optionset_autocmd(int opt_idx, long opt_flags, long oldval, lo /// @param[in] opt_flags OPT_LOCAL and/or OPT_GLOBAL. /// /// @return NULL on success, error message on error. -static char *set_bool_option(const int opt_idx, char_u *const varp, const int value, +static char *set_bool_option(const int opt_idx, char *const varp, const int value, const int opt_flags) { int old_value = *(int *)varp; @@ -2009,7 +2030,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va // Ensure that options set to p_force_off cannot be enabled. } else if ((int *)varp == &p_force_off && p_force_off == true) { p_force_off = false; - return (char *)e_unsupportedoption; + return e_unsupportedoption; } else if ((int *)varp == &p_lrm) { // 'langremap' -> !'langnoremap' p_lnr = !p_lrm; @@ -2022,7 +2043,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va // delete the undo file, the option may be set again without making // any changes in between. if (curbuf->b_p_udf || p_udf) { - char_u hash[UNDO_HASH_SIZE]; + uint8_t hash[UNDO_HASH_SIZE]; FOR_ALL_BUFFERS(bp) { // When 'undofile' is set globally: for every buffer, otherwise @@ -2102,7 +2123,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va } } } - } else if (varp == (char_u *)&(curbuf->b_p_lisp)) { + } else if (varp == (char *)&(curbuf->b_p_lisp)) { // When 'lisp' option changes include/exclude '-' in // keyword characters. (void)buf_init_chartab(curbuf, false); // ignore errors @@ -2157,9 +2178,6 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va if (curwin->w_p_spell) { errmsg = did_set_spelllang(curwin); } - } else if (((int *)varp == &curwin->w_p_nu || (int *)varp == &curwin->w_p_rnu) - && *curwin->w_p_stc != NUL) { // '(relative)number' + 'statuscolumn' - curwin->w_nrwidth_line_count = 0; } if ((int *)varp == &curwin->w_p_arab) { @@ -3064,6 +3082,8 @@ char *set_option_value(const char *const name, const long number, const char *co const int opt_flags) FUNC_ATTR_NONNULL_ARG(1) { + static char errbuf[80]; + if (is_tty_option(name)) { return NULL; // Fail silently; many old vimrcs set t_xx options. } @@ -3086,7 +3106,7 @@ char *set_option_value(const char *const name, const long number, const char *co if (s == NULL || opt_flags & OPT_CLEAR) { s = ""; } - return set_string_option(opt_idx, s, opt_flags); + return set_string_option(opt_idx, s, opt_flags, errbuf, sizeof(errbuf)); } char_u *varp = (char_u *)get_varp_scope(&(options[opt_idx]), opt_flags); @@ -3124,9 +3144,9 @@ char *set_option_value(const char *const name, const long number, const char *co } } if (flags & P_NUM) { - return set_num_option(opt_idx, varp, numval, NULL, 0, opt_flags); + return set_num_option(opt_idx, varp, numval, errbuf, sizeof(errbuf), opt_flags); } - return set_bool_option(opt_idx, varp, (int)numval, opt_flags); + return set_bool_option(opt_idx, (char *)varp, (int)numval, opt_flags); } /// Call set_option_value() and when an error is returned report it. @@ -3217,13 +3237,13 @@ static void showoptions(bool all, int opt_flags) continue; } - char_u *varp = NULL; + char *varp = NULL; if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) { if (p->indir != PV_NONE) { - varp = (char_u *)get_varp_scope(p, opt_flags); + varp = get_varp_scope(p, opt_flags); } } else { - varp = get_varp(p); + varp = (char *)get_varp(p); } if (varp != NULL && (all == 1 || (all == 0 && !optval_default(p, varp)))) { @@ -3277,7 +3297,7 @@ static void showoptions(bool all, int opt_flags) } /// Return true if option "p" has its default value. -static int optval_default(vimoption_T *p, const char_u *varp) +static int optval_default(vimoption_T *p, const char *varp) { if (varp == NULL) { return true; // hidden option is always at default @@ -3402,7 +3422,7 @@ int makeset(FILE *fd, int opt_flags, int local_only) continue; } // Global values are only written when not at the default value. - if ((opt_flags & OPT_GLOBAL) && optval_default(p, (char_u *)varp)) { + if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp)) { continue; } @@ -3423,7 +3443,7 @@ int makeset(FILE *fd, int opt_flags, int local_only) // default, need to write it too. if (!(opt_flags & OPT_GLOBAL) && !local_only) { char_u *varp_fresh = (char_u *)get_varp_scope(p, OPT_GLOBAL); // local value - if (!optval_default(p, varp_fresh)) { + if (!optval_default(p, (char *)varp_fresh)) { round = 1; varp_local = (char_u *)varp; varp = (char *)varp_fresh; @@ -4830,10 +4850,9 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char *fuzzystr, int *numM // loop == 0: count the number of matching options // loop == 1: copy the matching options into allocated memory for (int loop = 0; loop <= 1; loop++) { - int match; regmatch->rm_ic = ic; if (xp->xp_context != EXPAND_BOOL_SETTINGS) { - for (match = 0; match < (int)ARRAY_SIZE(names); + for (int match = 0; match < (int)ARRAY_SIZE(names); match++) { if (match_str(names[match], regmatch, *matches, count, (loop == 0), fuzzy, fuzzystr, fuzmatch)) { @@ -4965,7 +4984,7 @@ static void option_value2string(vimoption_T *opp, int scope) if (varp == NULL) { // Just in case. NameBuff[0] = NUL; } else if (opp->flags & P_EXPAND) { - home_replace(NULL, varp, (char *)NameBuff, MAXPATHL, false); + home_replace(NULL, varp, NameBuff, MAXPATHL, false); // Translate 'pastetoggle' into special key names. } else if ((char **)opp->var == &p_pt) { str2specialbuf((const char *)p_pt, NameBuff, MAXPATHL); @@ -5186,8 +5205,8 @@ void fill_breakat_flags(void) } if (p_breakat != NULL) { - for (char_u *p = (char_u *)p_breakat; *p; p++) { - breakat_flags[*p] = true; + for (char *p = p_breakat; *p; p++) { + breakat_flags[(uint8_t)(*p)] = true; } } } @@ -5603,10 +5622,9 @@ long get_sidescrolloff_value(win_T *wp) Dictionary get_vimoption(String name, Error *err) { int opt_idx = findoption_len((const char *)name.data, name.size); - if (opt_idx < 0) { - api_set_error(err, kErrorTypeValidation, "no such option: '%s'", name.data); + VALIDATE_S(opt_idx >= 0, "option (not found)", name.data, { return (Dictionary)ARRAY_DICT_INIT; - } + }); return vimoption2dict(&options[opt_idx]); } diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 7efbeadb2f..f903ad3d09 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -330,7 +330,6 @@ void set_string_option_direct(const char *name, int opt_idx, const char *val, in int set_sid) { char *s; - char **varp; int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; int idx = opt_idx; @@ -353,7 +352,7 @@ void set_string_option_direct(const char *name, int opt_idx, const char *val, in s = xstrdup(val); { - varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags); + char **varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags); if ((opt_flags & OPT_FREE) && (opt->flags & P_ALLOCED)) { free_string_option(*varp); } @@ -411,7 +410,8 @@ void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, c /// #OPT_GLOBAL. /// /// @return NULL on success, an untranslated error message on error. -char *set_string_option(const int opt_idx, const char *const value, const int opt_flags) +char *set_string_option(const int opt_idx, const char *const value, const int opt_flags, + char *const errbuf, const size_t errbuflen) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT { vimoption_T *opt = get_option(opt_idx); @@ -443,7 +443,7 @@ char *set_string_option(const int opt_idx, const char *const value, const int op int value_checked = false; char *const errmsg = did_set_string_option(opt_idx, varp, oldval, - NULL, 0, + errbuf, errbuflen, opt_flags, &value_checked); if (errmsg == NULL) { did_set_option(opt_idx, opt_flags, true, value_checked); diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 0611de14aa..30092b9142 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -34,7 +34,11 @@ #include "nvim/vim.h" #ifdef MSWIN -# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 +# include "nvim/mbyte.h" +#endif + +#ifdef BACKSLASH_IN_FILENAME +# include "nvim/fileio.h" #endif #ifdef HAVE__NSGETENVIRON diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 5af39555c9..846219f720 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -27,6 +27,10 @@ #include "nvim/rbuffer.h" #include "nvim/types.h" +#ifdef MSWIN +# include "nvim/os/os_win_console.h" +#endif + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/fileio.c.generated.h" #endif diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 6157341ec9..85d95960a7 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -12,14 +12,20 @@ #include <stdlib.h> #include <string.h> #include <sys/stat.h> +#include <uv.h> #include "auto/config.h" +#include "nvim/ascii.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/macros.h" +#include "nvim/memory.h" +#include "nvim/message.h" #include "nvim/option_defs.h" #include "nvim/os/fs_defs.h" +#include "nvim/os/os.h" +#include "nvim/path.h" #include "nvim/types.h" #include "nvim/vim.h" @@ -27,24 +33,17 @@ # include <sys/uio.h> #endif -#include <uv.h> - -#include "nvim/ascii.h" -#include "nvim/memory.h" -#include "nvim/message.h" -#include "nvim/os/os.h" -#include "nvim/path.h" - -struct iovec; - #ifdef MSWIN -# include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 +# include "nvim/mbyte.h" +# include "nvim/option.h" #endif #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/fs.c.generated.h" #endif +struct iovec; + #define RUN_UV_FS_FUNC(ret, func, ...) \ do { \ bool did_try_to_free = false; \ diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 44ad0315a5..d472836d0a 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -470,11 +470,6 @@ static InbufPollResult inbuf_poll(int ms, MultiQueue *events) return input_eof ? kInputEof : kInputNone; } -void input_done(void) -{ - input_eof = true; -} - bool input_available(void) { return rbuffer_size(input_buffer) != 0; @@ -483,7 +478,7 @@ bool input_available(void) static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data, bool at_eof) { if (at_eof) { - input_done(); + input_eof = true; } assert(rbuffer_space(input_buffer) >= rbuffer_size(buf)); diff --git a/src/nvim/path.c b/src/nvim/path.c index e4c2253357..9bbf56276e 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -810,7 +810,7 @@ static int find_previous_pathsep(char *path, char **psep) } /// Returns true if "maybe_unique" is unique wrt other_paths in "gap". -/// "maybe_unique" is the end portion of "((char_u **)gap->ga_data)[i]". +/// "maybe_unique" is the end portion of "((char **)gap->ga_data)[i]". static bool is_unique(char *maybe_unique, garray_T *gap, int i) { char **other_paths = gap->ga_data; @@ -879,7 +879,7 @@ static void expand_path_option(char *curdir, garray_T *gap) } STRMOVE(buf + len + 1, buf); STRCPY(buf, curdir); - buf[len] = (char_u)PATHSEP; + buf[len] = PATHSEP; simplify_filename(buf); } @@ -1923,7 +1923,7 @@ void path_fix_case(char *name) xstrlcpy(newname + (tail - name), entry, (size_t)(MAXPATHL - (tail - name) + 1)); FileInfo file_info_new; - if (os_fileinfo_link((char *)newname, &file_info_new) + if (os_fileinfo_link(newname, &file_info_new) && os_fileinfo_id_equal(&file_info, &file_info_new)) { STRCPY(tail, entry); break; @@ -1956,11 +1956,11 @@ bool same_directory(char *f1, char *f2) return false; } - (void)vim_FullName(f1, (char *)ffname, MAXPATHL, false); + (void)vim_FullName(f1, ffname, MAXPATHL, false); t1 = path_tail_with_sep(ffname); t2 = path_tail_with_sep(f2); return t1 - ffname == t2 - f2 - && pathcmp((char *)ffname, f2, (int)(t1 - ffname)) == 0; + && pathcmp(ffname, f2, (int)(t1 - ffname)) == 0; } // Compare path "p[]" to "q[]". diff --git a/src/nvim/plines.c b/src/nvim/plines.c index 5469d94800..a3e5640b18 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -356,14 +356,9 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) char *s = cts->cts_ptr; colnr_T vcol = cts->cts_vcol; - colnr_T col2; colnr_T col_adj = 0; // vcol + screen size of tab - colnr_T colmax; - int added; int mb_added = 0; int numberextra; - char *ps; - int n; cts->cts_cur_text_width = 0; @@ -397,12 +392,12 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) // Count all characters from first non-blank after a blank up to next // non-blank after a blank. numberextra = win_col_off(wp); - col2 = vcol; - colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); + colnr_T col2 = vcol; + colnr_T colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); if (vcol >= colmax) { colmax += col_adj; - n = colmax + win_col_off2(wp); + int n = colmax + win_col_off2(wp); if (n > 0) { colmax += (((vcol - colmax) / n) + 1) * n - col_adj; @@ -410,7 +405,7 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) } for (;;) { - ps = s; + char *ps = s; MB_PTR_ADV(s); c = (uint8_t)(*s); @@ -439,7 +434,7 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) // string at start of line. // Set *headp to the size of what we add. // Do not use 'showbreak' at the NUL after the text. - added = 0; + int added = 0; char *const sbr = c == NUL ? empty_option : get_showbreak_value(wp); if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && vcol != 0) { colnr_T sbrlen = 0; diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 45c1afd70e..cdf8d5720b 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -113,8 +113,6 @@ static void pum_compute_size(void) void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int cmd_startcol) { int context_lines; - int above_row; - int below_row; int redo_count = 0; int pum_win_row; int cursor_col; @@ -134,8 +132,8 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i pum_is_visible = true; pum_is_drawn = true; validate_cursor_col(); - above_row = 0; - below_row = cmdline_row; + int above_row = 0; + int below_row = cmdline_row; // wildoptions=pum if (State == MODE_CMDLINE) { @@ -409,17 +407,15 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i void pum_redraw(void) { int row = 0; - int grid_col; int attr_norm = win_hl_attr(curwin, HLF_PNI); int attr_select = win_hl_attr(curwin, HLF_PSI); int attr_scroll = win_hl_attr(curwin, HLF_PSB); int attr_thumb = win_hl_attr(curwin, HLF_PST); - int attr; int i; - int idx; char *s; char *p = NULL; - int totwidth, width, w; + int width; + int w; int thumb_pos = 0; int thumb_height = 1; int round; @@ -485,8 +481,8 @@ void pum_redraw(void) } for (i = 0; i < pum_height; i++) { - idx = i + pum_first; - attr = (idx == pum_selected) ? attr_select : attr_norm; + int idx = i + pum_first; + int attr = (idx == pum_selected) ? attr_select : attr_norm; grid_puts_line_start(&pum_grid, row); @@ -501,8 +497,8 @@ void pum_redraw(void) // Display each entry, use two spaces for a Tab. // Do this 3 times: For the main text, kind and extra info - grid_col = col_off; - totwidth = 0; + int grid_col = col_off; + int totwidth = 0; for (round = 1; round <= 3; round++) { width = 0; @@ -725,7 +721,6 @@ static bool pum_set_selected(int n, int repeat) && (vim_strchr(p_cot, 'p') != NULL)) { win_T *curwin_save = curwin; tabpage_T *curtab_save = curtab; - int res = OK; // Open a preview window. 3 lines by default. Prefer // 'previewheight' if set and smaller. @@ -744,6 +739,7 @@ static bool pum_set_selected(int n, int repeat) g_do_tagpreview = 0; if (curwin->w_p_pvw) { + int res = OK; if (!resized && (curbuf->b_nwindows == 1) && (curbuf->b_fname == NULL) diff --git a/src/nvim/profile.c b/src/nvim/profile.c index fd024f2d38..173332a428 100644 --- a/src/nvim/profile.c +++ b/src/nvim/profile.c @@ -689,10 +689,8 @@ void profile_init(scriptitem_T *si) /// @param tm place to store wait time void script_prof_save(proftime_T *tm) { - scriptitem_T *si; - if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) { - si = &SCRIPT_ITEM(current_sctx.sc_sid); + scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on && si->sn_pr_nest++ == 0) { si->sn_pr_child = profile_start(); } @@ -720,12 +718,11 @@ void script_prof_restore(const proftime_T *tm) /// Dump the profiling results for all scripts in file "fd". static void script_dump_profile(FILE *fd) { - scriptitem_T *si; FILE *sfd; sn_prl_T *pp; for (int id = 1; id <= script_items.ga_len; id++) { - si = &SCRIPT_ITEM(id); + scriptitem_T *si = &SCRIPT_ITEM(id); if (si->sn_prof_on) { fprintf(fd, "SCRIPT %s\n", si->sn_name); if (si->sn_pr_count == 1) { @@ -808,7 +805,6 @@ void profile_dump(void) void script_line_start(void) { scriptitem_T *si; - sn_prl_T *pp; if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) { return; @@ -822,7 +818,7 @@ void script_line_start(void) while (si->sn_prl_ga.ga_len <= si->sn_prl_idx && si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen) { // Zero counters for a line that was not used before. - pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len); + sn_prl_T *pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len); pp->snp_count = 0; pp->sn_prl_total = profile_zero(); pp->sn_prl_self = profile_zero(); @@ -853,7 +849,6 @@ void script_line_exec(void) void script_line_end(void) { scriptitem_T *si; - sn_prl_T *pp; if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len) { return; @@ -862,7 +857,7 @@ void script_line_end(void) if (si->sn_prof_on && si->sn_prl_idx >= 0 && si->sn_prl_idx < si->sn_prl_ga.ga_len) { if (si->sn_prl_execed) { - pp = &PRL_ITEM(si, si->sn_prl_idx); + sn_prl_T *pp = &PRL_ITEM(si, si->sn_prl_idx); pp->snp_count++; si->sn_prl_start = profile_end(si->sn_prl_start); si->sn_prl_start = profile_sub_wait(si->sn_prl_wait, si->sn_prl_start); diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index b071e10cf9..cff0f886ce 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -276,10 +276,8 @@ static void source_callback(char *fname, void *cookie) /// return FAIL when no file could be sourced, OK otherwise. int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, void *cookie) { - char *tail; int num_files; char **files; - int i; bool did_one = false; // Make a copy of 'runtimepath'. Invoking the callback may change the @@ -287,6 +285,7 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo char *rtp_copy = xstrdup(path); char *buf = xmallocz(MAXPATHL); { + char *tail; if (p_verbose > 10 && name != NULL) { verbose_enter(); smsg(_("Searching for \"%s\" in \"%s\""), name, path); @@ -335,7 +334,7 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo // Expand wildcards, invoke the callback for each match. if (gen_expand_wildcards(1, &buf, &num_files, &files, ew_flags) == OK) { - for (i = 0; i < num_files; i++) { + for (int i = 0; i < num_files; i++) { (*callback)(files[i], cookie); did_one = true; if (!(flags & DIP_ALL)) { @@ -416,7 +415,6 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c char *tail; int num_files; char **files; - int i; bool did_one = false; char buf[MAXPATHL]; @@ -469,7 +467,7 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c // Expand wildcards, invoke the callback for each match. char *(pat[]) = { buf }; if (gen_expand_wildcards(1, pat, &num_files, &files, ew_flags) == OK) { - for (i = 0; i < num_files; i++) { + for (int i = 0; i < num_files; i++) { (*callback)(files[i], cookie); did_one = true; if (!(flags & DIP_ALL)) { @@ -2329,7 +2327,6 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat) { struct source_cookie *sp = (struct source_cookie *)cookie; char *line; - char *p; // If breakpoints have been added/deleted need to check for it. if (sp->dbg_tick < debug_tick) { @@ -2359,6 +2356,7 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat) // Only concatenate lines starting with a \ when 'cpoptions' doesn't // contain the 'C' flag. if (line != NULL && do_concat && (vim_strchr(p_cpo, CPO_CONCAT) == NULL)) { + char *p; // compensate for the one line read-ahead sp->sourcing_lnum--; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 05da6e0ef1..da9178bdff 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -248,11 +248,8 @@ size_t fill_foldcolumn(char *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum) /// Only works for single-byte characters (e.g., numbers). void rl_mirror(char *str) { - char *p1, *p2; - char t; - - for (p1 = str, p2 = str + strlen(str) - 1; p1 < p2; p1++, p2--) { - t = *p1; + for (char *p1 = str, *p2 = str + strlen(str) - 1; p1 < p2; p1++, p2--) { + char t = *p1; *p1 = *p2; *p2 = t; } @@ -264,9 +261,7 @@ void rl_mirror(char *str) /// line of the window right of it. If not, then it's a vertical separator. bool stl_connected(win_T *wp) { - frame_T *fr; - - fr = wp->w_frame; + frame_T *fr = wp->w_frame; while (fr->fr_parent != NULL) { if (fr->fr_parent->fr_layout == FR_COL) { if (fr->fr_next != NULL) { @@ -437,11 +432,7 @@ bool skip_showmode(void) /// @return the length of the message (0 if no message). int showmode(void) { - bool need_clear; int length = 0; - int do_mode; - int attr; - int sub_attr; if (ui_has(kUIMessages) && clear_cmdline) { msg_ext_clear(true); @@ -452,12 +443,13 @@ int showmode(void) msg_grid_validate(); - do_mode = ((p_smd && msg_silent == 0) - && ((State & MODE_TERMINAL) - || (State & MODE_INSERT) - || restart_edit != NUL - || VIsual_active)); + int do_mode = ((p_smd && msg_silent == 0) + && ((State & MODE_TERMINAL) + || (State & MODE_INSERT) + || restart_edit != NUL + || VIsual_active)); if (do_mode || reg_recording != 0) { + int sub_attr; if (skip_showmode()) { return 0; // show mode later } @@ -468,14 +460,14 @@ int showmode(void) check_for_delay(false); // if the cmdline is more than one line high, erase top lines - need_clear = clear_cmdline; + bool need_clear = clear_cmdline; if (clear_cmdline && cmdline_row < Rows - 1) { msg_clr_cmdline(); // will reset clear_cmdline } // Position on the last line in the window, column 0 msg_pos_mode(); - attr = HL_ATTR(HLF_CM); // Highlight mode + int attr = HL_ATTR(HLF_CM); // Highlight mode // When the screen is too narrow to show the entire mode message, // avoid scrolling and truncate instead. diff --git a/src/nvim/search.c b/src/nvim/search.c index eb5cc2e07f..e5a456161f 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -95,7 +95,7 @@ static struct spat spats[2] = { static int last_idx = 0; // index in spats[] for RE_LAST -static char_u lastc[2] = { NUL, NUL }; // last character searched for +static uint8_t lastc[2] = { NUL, NUL }; // last character searched for static Direction lastcdir = FORWARD; // last direction of character search static int last_t_cmd = true; // last search t_cmd static char lastc_bytes[MB_MAXBYTES + 1]; @@ -136,14 +136,12 @@ typedef struct SearchedFile { int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch) { - int magic; - int i; - rc_did_emsg = false; - magic = magic_isset(); + int magic = magic_isset(); // If no pattern given, use a previously defined pattern. if (pat == NULL || *pat == NUL) { + int i; if (pat_use == RE_LAST) { i = last_idx; } else { @@ -439,7 +437,7 @@ int last_csearch_until(void) void set_last_csearch(int c, char *s, int len) { - *lastc = (char_u)c; + *lastc = (uint8_t)c; lastc_bytelen = len; if (len) { memcpy(lastc_bytes, s, (size_t)len); @@ -557,8 +555,6 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, lpos_T endpos; lpos_T matchpos; int loop; - pos_T start_pos; - int at_first_line; int extra_col; int start_char_len; bool match_ok; @@ -611,9 +607,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, extra_col = (options & SEARCH_START) ? start_char_len : 0; } - start_pos = *pos; // remember start pos for detecting no match + pos_T start_pos = *pos; // remember start pos for detecting no match found = 0; // default: not found - at_first_line = true; // default: start in first line + int at_first_line = true; // default: start in first line if (pos->lnum == 0) { // correct lnum for when starting in line 0 pos->lnum = 1; pos->col = 0; @@ -1028,10 +1024,9 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i { pos_T pos; // position of the last match char *searchstr; - struct soffset old_off; int retval; // Return value char *p; - long c; + int64_t c; char *dircp; char *strcopy = NULL; char *ps; @@ -1047,13 +1042,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i // Save the values for when (options & SEARCH_KEEP) is used. // (there is no "if ()" around this because gcc wants them initialized) - old_off = spats[0].off; + struct soffset old_off = spats[0].off; pos = curwin->w_cursor; // start searching at the cursor position // Find out the direction of the search. if (dirc == 0) { - dirc = (char_u)spats[0].off.dir; + dirc = (uint8_t)spats[0].off.dir; } else { spats[0].off.dir = (char)dirc; set_vv_searchforward(); @@ -1434,8 +1429,6 @@ end_do_search: int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char *pat) { linenr_T start = 0; - char *ptr; - char *p; if (buf->b_ml.ml_line_count == 0) { return FAIL; @@ -1469,8 +1462,8 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char *pat) if (start == 0) { start = pos->lnum; } - ptr = ml_get_buf(buf, pos->lnum, false); - p = skipwhite(ptr); + char *ptr = ml_get_buf(buf, pos->lnum, false); + char *p = skipwhite(ptr); pos->col = (colnr_T)(p - ptr); // when adding lines the matching line may be empty but it is not @@ -1503,14 +1496,11 @@ int searchc(cmdarg_T *cap, int t_cmd) int c = cap->nchar; // char to search for int dir = cap->arg; // true for searching forward long count = cap->count1; // repeat count - int col; - char *p; - int len; bool stop = true; if (c != NUL) { // normal search: remember args for repeat if (!KeyStuffed) { // don't remember when redoing - *lastc = (char_u)c; + *lastc = (uint8_t)c; set_csearch_direction(dir); set_csearch_until(t_cmd); lastc_bytelen = utf_char2bytes(c, lastc_bytes); @@ -1550,9 +1540,9 @@ int searchc(cmdarg_T *cap, int t_cmd) cap->oap->inclusive = true; } - p = get_cursor_line_ptr(); - col = curwin->w_cursor.col; - len = (int)strlen(p); + char *p = get_cursor_line_ptr(); + int col = curwin->w_cursor.col; + int len = (int)strlen(p); while (count--) { for (;;) { @@ -2295,15 +2285,10 @@ int check_linecomment(const char *line) /// @param c char to show match for void showmatch(int c) { - pos_T *lpos, save_cursor; - pos_T mpos; + pos_T *lpos; colnr_T vcol; long *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; long *siso = curwin->w_p_siso >= 0 ? &curwin->w_p_siso : &p_siso; - long save_so; - long save_siso; - int save_state; - colnr_T save_dollar_vcol; char *p; // Only show match for chars in the 'matchpairs' option. @@ -2345,10 +2330,10 @@ void showmatch(int c) return; } - mpos = *lpos; // save the pos, update_screen() may change it - save_cursor = curwin->w_cursor; - save_so = *so; - save_siso = *siso; + pos_T mpos = *lpos; // save the pos, update_screen() may change it + pos_T save_cursor = curwin->w_cursor; + long save_so = *so; + long save_siso = *siso; // Handle "$" in 'cpo': If the ')' is typed on top of the "$", // stop displaying the "$". if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol) { @@ -2357,8 +2342,8 @@ void showmatch(int c) curwin->w_virtcol++; // do display ')' just before "$" update_screen(); // show the new char first - save_dollar_vcol = dollar_vcol; - save_state = State; + colnr_T save_dollar_vcol = dollar_vcol; + int save_state = State; State = MODE_SHOWMATCH; ui_cursor_shape(); // may show different cursor shape curwin->w_cursor = mpos; // move to matching char @@ -2531,7 +2516,6 @@ int current_search(long count, bool forward) static int is_zero_width(char *pattern, int move, pos_T *cur, Direction direction) { regmmatch_T regmatch; - int nmatched = 0; int result = -1; pos_T pos; const int called_emsg_before = called_emsg; @@ -2558,6 +2542,7 @@ static int is_zero_width(char *pattern, int move, pos_T *cur, Direction directio } if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1, SEARCH_KEEP + flag, RE_SEARCH, NULL) != FAIL) { + int nmatched = 0; // Zero-width pattern should match somewhere, then we can check if // start and end are in the same position. do { @@ -2587,9 +2572,7 @@ static int is_zero_width(char *pattern, int move, pos_T *cur, Direction directio /// return true if line 'lnum' is empty or has white chars only. int linewhite(linenr_T lnum) { - char *p; - - p = skipwhite(ml_get(lnum)); + char *p = skipwhite(ml_get(lnum)); return *p == NUL; } @@ -2682,7 +2665,6 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst static int chgtick = 0; static char *lastpat = NULL; static buf_T *lbuf = NULL; - proftime_T start; CLEAR_POINTER(stat); @@ -2722,6 +2704,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 0)) { cur += dirc == 0 ? 0 : dirc == '/' ? 1 : -1; } else { + proftime_T start; bool done_search = false; pos_T endpos = { 0, 0, 0 }; p_ws = false; @@ -2788,7 +2771,6 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (argvars[0].v_type != VAR_UNKNOWN) { dict_T *dict; dictitem_T *di; - listitem_T *li; bool error = false; if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) { @@ -2834,7 +2816,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) semsg(_(e_invarg2), "List format should be [lnum, col, off]"); return; } - li = tv_list_find(di->di_tv.vval.v_list, 0L); + listitem_T *li = tv_list_find(di->di_tv.vval.v_list, 0L); if (li != NULL) { pos.lnum = (linenr_T)tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); if (error) { @@ -3125,8 +3107,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s /// normalized and varies with pattern. /// Recursion is limited internally (default=10) to prevent degenerate cases /// (pat_arg="aaaaaa" str="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"). -/// Uses char_u for match indices. Therefore patterns are limited to -/// MAX_FUZZY_MATCHES characters. +/// Patterns are limited to MAX_FUZZY_MATCHES characters. /// /// @return true if "pat_arg" matches "str". Also returns the match score in /// "outScore" and the matching character positions in "matches". @@ -4157,8 +4138,6 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI linenr_T *lnum, long count) FUNC_ATTR_NONNULL_ARG(1, 6) { - char *p; - if (did_show) { msg_putchar('\n'); // cursor below last one } else if (!msg_silent) { @@ -4168,7 +4147,7 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI return; } for (;;) { - p = line + strlen(line) - 1; + char *p = line + strlen(line) - 1; if (fp != NULL) { // We used fgets(), so get rid of newline at end if (p >= line && *p == '\n') { diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c index db647f3ecb..f0a9aecdcc 100644 --- a/src/nvim/sha256.c +++ b/src/nvim/sha256.c @@ -201,14 +201,14 @@ void sha256_update(context_sha256_T *ctx, const uint8_t *input, size_t length) memcpy(ctx->buffer + left, input, fill); sha256_process(ctx, ctx->buffer); length -= fill; - input += fill; + input += fill; left = 0; } while (length >= SHA256_BUFFER_SIZE) { sha256_process(ctx, input); length -= SHA256_BUFFER_SIZE; - input += SHA256_BUFFER_SIZE; + input += SHA256_BUFFER_SIZE; } if (length) { diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 90a01aaf97..98f10c0082 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -2579,7 +2579,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef { STATIC_CSTR_AS_STRING("pid"), INTEGER_OBJ((Integer)os_get_pid()) }, { STATIC_CSTR_AS_STRING("encoding"), - STRING_OBJ(cstr_as_string((char *)p_enc)) }, + STRING_OBJ(cstr_as_string(p_enc)) }, }), } } diff --git a/src/nvim/sign.c b/src/nvim/sign.c index 00e282b76e..d555b8bf4a 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -153,11 +153,10 @@ static int sign_group_get_next_signid(buf_T *buf, const char *groupname) int id = 1; signgroup_T *group = NULL; sign_entry_T *sign; - hashitem_T *hi; int found = false; if (groupname != NULL) { - hi = hash_find(&sg_table, (char *)groupname); + hashitem_T *hi = hash_find(&sg_table, (char *)groupname); if (HASHITEM_EMPTY(hi)) { return id; } @@ -298,8 +297,8 @@ static dict_T *sign_get_info(sign_entry_T *sign) dict_T *d = tv_dict_alloc(); tv_dict_add_nr(d, S_LEN("id"), sign->se_id); tv_dict_add_str(d, S_LEN("group"), ((sign->se_group == NULL) - ? (char *)"" - : (char *)sign->se_group->sg_name)); + ? "" + : sign->se_group->sg_name)); tv_dict_add_nr(d, S_LEN("lnum"), sign->se_lnum); tv_dict_add_str(d, S_LEN("name"), sign_typenr2name(sign->se_typenr)); tv_dict_add_nr(d, S_LEN("priority"), sign->se_priority); @@ -576,7 +575,7 @@ static linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char *group) lnum = sign->se_lnum; buf_signcols_del_check(buf, lnum, lnum); if (sign->se_group != NULL) { - sign_group_unref((char *)sign->se_group->sg_name); + sign_group_unref(sign->se_group->sg_name); } xfree(sign); redraw_buf_line_later(buf, lnum, false); @@ -688,7 +687,7 @@ void buf_delete_signs(buf_T *buf, char *group) next->se_prev = sign->se_prev; } if (sign->se_group != NULL) { - sign_group_unref((char *)sign->se_group->sg_name); + sign_group_unref(sign->se_group->sg_name); } xfree(sign); } else { @@ -1198,7 +1197,6 @@ static linenr_T sign_jump(int sign_id, char *sign_group, buf_T *buf) /// ":sign define {name} ..." command static void sign_define_cmd(char *sign_name, char *cmdline) { - char *arg; char *p = cmdline; char *icon = NULL; char *text = NULL; @@ -1210,7 +1208,7 @@ static void sign_define_cmd(char *sign_name, char *cmdline) // set values for a defined sign. for (;;) { - arg = skipwhite(p); + char *arg = skipwhite(p); if (*arg == NUL) { break; } @@ -1585,7 +1583,6 @@ static void sign_getinfo(sign_T *sp, dict_T *retdict) static void sign_getlist(const char *name, list_T *retlist) { sign_T *sp = first_sign; - dict_T *dict; if (name != NULL) { sp = sign_find((char *)name, NULL); @@ -1595,7 +1592,7 @@ static void sign_getlist(const char *name, list_T *retlist) } for (; sp != NULL && !got_int; sp = sp->sn_next) { - dict = tv_dict_alloc(); + dict_T *dict = tv_dict_alloc(); tv_list_append_dict(retlist, dict); sign_getinfo(sp, dict); @@ -1610,11 +1607,10 @@ list_T *get_buffer_signs(buf_T *buf) FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { sign_entry_T *sign; - dict_T *d; list_T *const l = tv_list_alloc(kListLenMayKnow); FOR_ALL_SIGNS_IN_BUF(buf, sign) { - d = sign_get_info(sign); + dict_T *d = sign_get_info(sign); tv_list_append_dict(l, d); } return l; @@ -1778,7 +1774,7 @@ static char *get_nth_sign_group_name(int idx) todo--; if (current_idx++ == idx) { signgroup_T *const group = HI2SG(hi); - return (char *)group->sg_name; + return group->sg_name; } } } @@ -2055,7 +2051,6 @@ void f_sign_getdefined(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) void f_sign_getplaced(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { buf_T *buf = NULL; - dict_T *dict; dictitem_T *di; linenr_T lnum = 0; int sign_id = 0; @@ -2072,6 +2067,7 @@ void f_sign_getplaced(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } if (argvars[1].v_type != VAR_UNKNOWN) { + dict_T *dict; if (argvars[1].v_type != VAR_DICT || ((dict = argvars[1].vval.v_dict) == NULL)) { emsg(_(e_dictreq)); @@ -2327,8 +2323,6 @@ static void sign_undefine_multiple(list_T *l, list_T *retlist) /// "sign_undefine()" function void f_sign_undefine(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - const char *name; - if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) { // Undefine multiple signs tv_list_alloc_ret(rettv, kListLenMayKnow); @@ -2345,7 +2339,7 @@ void f_sign_undefine(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) rettv->vval.v_number = 0; } else { // Free only the specified sign - name = tv_get_string_chk(&argvars[0]); + const char *name = tv_get_string_chk(&argvars[0]); if (name == NULL) { return; } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 2204cda169..117a770e50 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -380,7 +380,7 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount MB_PTR_ADV(mi.mi_end); } else if (mi.mi_result == SP_BAD && LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) { - char *p, *fp; + char *p; int save_result = mi.mi_result; // First language in 'spelllang' is NOBREAK. Find first position @@ -388,7 +388,7 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, 0); if (mi.mi_lp->lp_slang->sl_fidxs != NULL) { p = mi.mi_word; - fp = mi.mi_fword; + char *fp = mi.mi_fword; for (;;) { MB_PTR_ADV(p); MB_PTR_ADV(fp); @@ -437,14 +437,14 @@ static void find_word(matchinf_T *mip, int mode) int flen; char *ptr; slang_T *slang = mip->mi_lp->lp_slang; - char_u *byts; + uint8_t *byts; idx_T *idxs; if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) { // Check for word with matching case in keep-case tree. ptr = mip->mi_word; flen = 9999; // no case folding, always enough bytes - byts = (char_u *)slang->sl_kbyts; + byts = (uint8_t *)slang->sl_kbyts; idxs = slang->sl_kidxs; if (mode == FIND_KEEPCOMPOUND) { @@ -455,7 +455,7 @@ static void find_word(matchinf_T *mip, int mode) // Check for case-folded in case-folded tree. ptr = mip->mi_fword; flen = mip->mi_fwordlen; // available case-folded bytes - byts = (char_u *)slang->sl_fbyts; + byts = (uint8_t *)slang->sl_fbyts; idxs = slang->sl_fidxs; if (mode == FIND_PREFIX) { @@ -964,7 +964,7 @@ bool can_compound(slang_T *slang, const char *word, const uint8_t *flags) bool match_compoundrule(slang_T *slang, const char_u *compflags) { // loop over all the COMPOUNDRULE entries - for (char_u *p = (char_u *)slang->sl_comprules; *p != NUL; p++) { + for (char *p = (char *)slang->sl_comprules; *p != NUL; p++) { // loop over the flags in the compound word we have made, match // them against the current rule entry for (int i = 0;; i++) { @@ -982,21 +982,21 @@ bool match_compoundrule(slang_T *slang, const char_u *compflags) // compare against all the flags in [] p++; while (*p != ']' && *p != NUL) { - if (*p++ == c) { + if ((uint8_t)(*p++) == c) { match = true; } } if (!match) { break; // none matches } - } else if (*p != c) { + } else if ((uint8_t)(*p) != c) { break; // flag of word doesn't match flag in pattern } p++; } // Skip to the next "/", where the next pattern starts. - p = (char_u *)vim_strchr((char *)p, '/'); + p = vim_strchr(p, '/'); if (p == NULL) { break; } @@ -1062,13 +1062,13 @@ static void find_prefix(matchinf_T *mip, int mode) int wlen = 0; slang_T *slang = mip->mi_lp->lp_slang; - char_u *byts = (char_u *)slang->sl_pbyts; + uint8_t *byts = (uint8_t *)slang->sl_pbyts; if (byts == NULL) { return; // array is empty } // We use the case-folded word here, since prefixes are always // case-folded. - char_u *ptr = (char_u *)mip->mi_fword; + char *ptr = mip->mi_fword; int flen = mip->mi_fwordlen; // available case-folded bytes if (mode == FIND_COMPOUND) { // Skip over the previously found word(s). @@ -1126,7 +1126,7 @@ static void find_prefix(matchinf_T *mip, int mode) } // Perform a binary search in the list of accepted bytes. - int c = ptr[wlen]; + int c = (uint8_t)ptr[wlen]; idx_T lo = arridx; idx_T hi = arridx + len - 1; while (lo < hi) { @@ -1483,9 +1483,9 @@ theend: // to skip those bytes if the word was OK. void spell_cat_line(char *buf, char *line, int maxlen) { - char_u *p = (char_u *)skipwhite(line); + char *p = skipwhite(line); while (vim_strchr("*#/\"\t", (uint8_t)(*p)) != NULL) { - p = (char_u *)skipwhite((char *)p + 1); + p = skipwhite(p + 1); } if (*p == NUL) { @@ -1494,10 +1494,10 @@ void spell_cat_line(char *buf, char *line, int maxlen) // Only worth concatenating if there is something else than spaces to // concatenate. - int n = (int)(p - (char_u *)line) + 1; + int n = (int)(p - line) + 1; if (n < maxlen - 1) { memset(buf, ' ', (size_t)n); - xstrlcpy(buf + n, (char *)p, (size_t)(maxlen - n)); + xstrlcpy(buf + n, p, (size_t)(maxlen - n)); } } @@ -1775,7 +1775,7 @@ bool byte_in_str(uint8_t *str, int n) int init_syl_tab(slang_T *slang) { ga_init(&slang->sl_syl_items, sizeof(syl_item_T), 4); - char *p = vim_strchr((char *)slang->sl_syllable, '/'); + char *p = vim_strchr(slang->sl_syllable, '/'); while (p != NULL) { *p++ = NUL; if (*p == NUL) { // trailing slash @@ -1838,7 +1838,7 @@ static int count_syllables(slang_T *slang, const char *word) // No recognized syllable item, at least a syllable char then? int c = utf_ptr2char(p); len = utfc_ptr2len(p); - if (vim_strchr((char *)slang->sl_syllable, c) == NULL) { + if (vim_strchr(slang->sl_syllable, c) == NULL) { skip = false; // No, search for next syllable } else if (!skip) { cnt++; // Yes, count it @@ -2167,7 +2167,7 @@ static void use_midword(slang_T *lp, win_T *wp) return; } - for (char *p = (char *)lp->sl_midword; *p != NUL;) { + for (char *p = lp->sl_midword; *p != NUL;) { const int c = utf_ptr2char(p); const int l = utfc_ptr2len(p); if (c < 256 && l <= 2) { @@ -2660,24 +2660,24 @@ void onecap_copy(char *word, char *wcopy, bool upper) // "wcopy[MAXWLEN]". The result is NUL terminated. void allcap_copy(char *word, char *wcopy) { - char_u *d = (char_u *)wcopy; + char *d = wcopy; for (char *s = word; *s != NUL;) { int c = mb_cptr2char_adv((const char **)&s); if (c == 0xdf) { c = 'S'; - if (d - (char_u *)wcopy >= MAXWLEN - 1) { + if (d - wcopy >= MAXWLEN - 1) { break; } - *d++ = (char_u)c; + *d++ = (char)c; } else { c = SPELL_TOUPPER(c); } - if (d - (char_u *)wcopy >= MAXWLEN - MB_MAXBYTES) { + if (d - wcopy >= MAXWLEN - MB_MAXBYTES) { break; } - d += utf_char2bytes(c, (char *)d); + d += utf_char2bytes(c, d); } *d = NUL; } @@ -2834,7 +2834,6 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) int j, z; int reslen; int k = 0; - int z0; int k0; int n0; int pri; @@ -2847,7 +2846,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) // But keep white space. int wordlen = 0; for (const char *s = (char *)inword; *s != NUL;) { - const char_u *t = (char_u *)s; + const char *t = s; int c = mb_cptr2char_adv(&s); if (slang->sl_rem_accents) { if (utf_class(c) == 0) { @@ -2858,7 +2857,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) did_white = true; } else { did_white = false; - if (!spell_iswordp_nmw((char *)t, curwin)) { + if (!spell_iswordp_nmw(t, curwin)) { continue; } } @@ -2875,7 +2874,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) while ((c = word[i]) != NUL) { // Start with the first rule that has the character in the word. int n = slang->sl_sal_first[c & 0xff]; - z0 = 0; + int z0 = 0; if (n >= 0) { // Check all rules for the same index byte. @@ -2915,10 +2914,10 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) } k++; } - char_u *s = (char_u *)smp[n].sm_rules; + char *s = smp[n].sm_rules; pri = 5; // default priority - p0 = *s; + p0 = (uint8_t)(*s); k0 = k; while (*s == '-' && k > 1) { k--; @@ -2929,7 +2928,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) } if (ascii_isdigit(*s)) { // determine priority - pri = *s - '0'; + pri = (uint8_t)(*s) - '0'; s++; } if (*s == '^' && *(s + 1) == '^') { @@ -2992,7 +2991,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) } p0 = 5; - s = (char_u *)smp[n0].sm_rules; + s = smp[n0].sm_rules; while (*s == '-') { // "k0" gets NOT reduced because // "if (k0 == k)" @@ -3002,7 +3001,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) s++; } if (ascii_isdigit(*s)) { - p0 = *s - '0'; + p0 = (uint8_t)(*s) - '0'; s++; } @@ -3033,8 +3032,8 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) // replace string ws = smp[n].sm_to_w; - s = (char_u *)smp[n].sm_rules; - p0 = (vim_strchr((char *)s, '<') != NULL) ? 1 : 0; + s = smp[n].sm_rules; + p0 = (vim_strchr(s, '<') != NULL) ? 1 : 0; if (p0 == 1 && z == 0) { // rule with '<' is used if (reslen > 0 && ws != NULL && *ws != NUL @@ -3077,7 +3076,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) } else { c = *ws; } - if (strstr((char *)s, "^^") != NULL) { + if (strstr(s, "^^") != NULL) { if (c != NUL) { wres[reslen++] = c; } @@ -3463,7 +3462,7 @@ static linenr_T dump_prefixes(slang_T *slang, char *word, char *pat, Direction * has_word_up = true; } - char_u *byts = (char_u *)slang->sl_pbyts; + char *byts = slang->sl_pbyts; idx_T *idxs = slang->sl_pidxs; if (byts != NULL) { // array not is empty // Loop over all prefixes, building them byte-by-byte in prefix[]. @@ -3473,7 +3472,7 @@ static linenr_T dump_prefixes(slang_T *slang, char *word, char *pat, Direction * curi[0] = 1; while (depth >= 0 && !got_int) { int n = arridx[depth]; - int len = byts[n]; + int len = (uint8_t)byts[n]; if (curi[depth] > len) { // Done all bytes at this node, go up one level. depth--; @@ -3482,7 +3481,7 @@ static linenr_T dump_prefixes(slang_T *slang, char *word, char *pat, Direction * // Do one more byte at this node. n += curi[depth]; curi[depth]++; - c = byts[n]; + c = (uint8_t)byts[n]; if (c == 0) { // End of prefix, find out how many IDs there are. int i; diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index 4d365deab1..93cf335c3a 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -82,7 +82,7 @@ typedef struct fromto_S { typedef struct salitem_S { char *sm_lead; // leading letters int sm_leadlen; // length of "sm_lead" - char_u *sm_oneof; // letters from () or NULL + char *sm_oneof; // letters from () or NULL char *sm_rules; // rules like ^, $, priority char *sm_to; // replacement. int *sm_lead_w; // wide character copy of "sm_lead" @@ -119,20 +119,20 @@ struct slang_S { char *sl_fname; // name of .spl file bool sl_add; // true if it's a .add file. - char *sl_fbyts; // case-folded word bytes - long sl_fbyts_len; // length of sl_fbyts - idx_T *sl_fidxs; // case-folded word indexes - char *sl_kbyts; // keep-case word bytes - idx_T *sl_kidxs; // keep-case word indexes - char *sl_pbyts; // prefix tree word bytes - idx_T *sl_pidxs; // prefix tree word indexes + char *sl_fbyts; // case-folded word bytes + long sl_fbyts_len; // length of sl_fbyts + idx_T *sl_fidxs; // case-folded word indexes + char *sl_kbyts; // keep-case word bytes + idx_T *sl_kidxs; // keep-case word indexes + char *sl_pbyts; // prefix tree word bytes + idx_T *sl_pidxs; // prefix tree word indexes - char_u *sl_info; // infotext string or NULL + char *sl_info; // infotext string or NULL char sl_regions[MAXREGIONS * 2 + 1]; // table with up to 8 region names plus NUL - char_u *sl_midword; // MIDWORD string or NULL + char *sl_midword; // MIDWORD string or NULL hashtab_T sl_wordcount; // hashtable with word count, wordcount_T @@ -141,13 +141,13 @@ struct slang_S { int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN) int sl_compoptions; // COMP_* flags garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items - regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm - // (NULL when no compounding) + regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm + // (NULL when no compounding) uint8_t *sl_comprules; // all COMPOUNDRULE concatenated (or NULL) uint8_t *sl_compstartflags; // flags for first compound word uint8_t *sl_compallflags; // all flags for compound words bool sl_nobreak; // When true: no spaces between words - char_u *sl_syllable; // SYLLABLE repeatable chars or NULL + char *sl_syllable; // SYLLABLE repeatable chars or NULL garray_T sl_syl_items; // syllable items int sl_prefixcnt; // number of items in "sl_prefprog" diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 5e7ebc4c87..e9dd0a4d5e 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -386,7 +386,7 @@ typedef struct affheader_S { // Flag used in compound items. typedef struct compitem_S { - char_u ci_key[AH_KEY_LEN]; // key for hashtab == name of compound + char ci_key[AH_KEY_LEN]; // key for hashtab == name of compound unsigned ci_flag; // affix name as number, uses "af_flagtype" int ci_newID; // affix ID after renumbering. } compitem_T; @@ -674,7 +674,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent) res = 0; switch (n) { case SN_INFO: - lp->sl_info = READ_STRING(fd, len); // <infotext> + lp->sl_info = read_string(fd, (size_t)len); // <infotext> if (lp->sl_info == NULL) { goto endFAIL; } @@ -689,7 +689,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent) break; case SN_MIDWORD: - lp->sl_midword = READ_STRING(fd, len); // <midword> + lp->sl_midword = read_string(fd, (size_t)len); // <midword> if (lp->sl_midword == NULL) { goto endFAIL; } @@ -716,7 +716,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent) break; case SN_MAP: - p = (char *)READ_STRING(fd, len); // <mapstr> + p = read_string(fd, (size_t)len); // <mapstr> if (p == NULL) { goto endFAIL; } @@ -749,7 +749,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent) break; case SN_SYLLABLE: - lp->sl_syllable = READ_STRING(fd, len); // <syllable> + lp->sl_syllable = read_string(fd, (size_t)len); // <syllable> if (lp->sl_syllable == NULL) { goto endFAIL; } @@ -838,8 +838,9 @@ endOK: // Fill in the wordcount fields for a trie. // Returns the total number of words. -static void tree_count_words(const char_u *byts, idx_T *idxs) +static void tree_count_words(const char *byts_in, idx_T *idxs) { + const uint8_t *byts= (const uint8_t *)byts_in; int depth; idx_T arridx[MAXWLEN]; int curi[MAXWLEN]; @@ -896,7 +897,6 @@ void suggest_load_files(void) char *dotp; FILE *fd; char buf[MAXWLEN]; - int i; time_t timestamp; int wcount; int wordnr; @@ -924,7 +924,7 @@ void suggest_load_files(void) } // <SUGHEADER>: <fileID> <versionnr> <timestamp> - for (i = 0; i < VIMSUGMAGICL; i++) { + for (int i = 0; i < VIMSUGMAGICL; i++) { buf[i] = (char)getc(fd); // <fileID> } if (strncmp(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) { @@ -1000,8 +1000,8 @@ someerror: // Need to put word counts in the word tries, so that we can find // a word by its number. - tree_count_words((char_u *)slang->sl_fbyts, slang->sl_fidxs); - tree_count_words((char_u *)slang->sl_sbyts, slang->sl_sidxs); + tree_count_words(slang->sl_fbyts, slang->sl_fidxs); + tree_count_words(slang->sl_sbyts, slang->sl_sidxs); nextone: if (fd != NULL) { @@ -1017,10 +1017,10 @@ nextone: // Returns NULL when the count is zero. // Sets "*cntp" to SP_*ERROR when there is an error, length of the result // otherwise. -static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp) +static char *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp) { int cnt = 0; - char_u *str; + char *str; // read the length bytes, MSB first for (int i = 0; i < cnt_bytes; i++) { @@ -1036,7 +1036,7 @@ static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp) if (cnt == 0) { return NULL; // nothing to read, return NULL } - str = READ_STRING(fd, cnt); + str = read_string(fd, (size_t)cnt); if (str == NULL) { *cntp = SP_OTHERERROR; } @@ -1065,13 +1065,13 @@ static int read_charflags_section(FILE *fd) int flagslen, follen; // <charflagslen> <charflags> - flags = (char *)read_cnt_string(fd, 1, &flagslen); + flags = read_cnt_string(fd, 1, &flagslen); if (flagslen < 0) { return flagslen; } // <folcharslen> <folchars> - fol = read_cnt_string(fd, 2, &follen); + fol = (char_u *)read_cnt_string(fd, 2, &follen); if (follen < 0) { xfree(flags); return follen; @@ -1143,14 +1143,14 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first) for (; gap->ga_len < cnt; gap->ga_len++) { int c; ftp = &((fromto_T *)gap->ga_data)[gap->ga_len]; - ftp->ft_from = (char *)read_cnt_string(fd, 1, &c); + ftp->ft_from = read_cnt_string(fd, 1, &c); if (c < 0) { return c; } if (c == 0) { return SP_FORMERROR; } - ftp->ft_to = (char *)read_cnt_string(fd, 1, &c); + ftp->ft_to = read_cnt_string(fd, 1, &c); if (c <= 0) { xfree(ftp->ft_from); if (c < 0) { @@ -1181,7 +1181,7 @@ static int read_sal_section(FILE *fd, slang_T *slang) garray_T *gap; salitem_T *smp; int ccnt; - char_u *p; + char *p; slang->sl_sofo = false; @@ -1215,7 +1215,7 @@ static int read_sal_section(FILE *fd, slang_T *slang) return SP_TRUNCERROR; } p = xmalloc((size_t)ccnt + 2); - smp->sm_lead = (char *)p; + smp->sm_lead = p; // Read up to the first special char into sm_lead. int i = 0; @@ -1224,9 +1224,9 @@ static int read_sal_section(FILE *fd, slang_T *slang) if (vim_strchr("0123456789(-<^$", c) != NULL) { break; } - *p++ = (char_u)c; + *p++ = (char)(uint8_t)c; } - smp->sm_leadlen = (int)(p - (char_u *)smp->sm_lead); + smp->sm_leadlen = (int)(p - smp->sm_lead); *p++ = NUL; // Put (abc) chars in sm_oneof, if any. @@ -1237,7 +1237,7 @@ static int read_sal_section(FILE *fd, slang_T *slang) if (c == ')') { break; } - *p++ = (char_u)c; + *p++ = (char)(uint8_t)c; } *p++ = NUL; if (++i < ccnt) { @@ -1248,22 +1248,22 @@ static int read_sal_section(FILE *fd, slang_T *slang) } // Any following chars go in sm_rules. - smp->sm_rules = (char *)p; + smp->sm_rules = p; if (i < ccnt) { // store the char we got while checking for end of sm_lead - *p++ = (char_u)c; + *p++ = (char)(uint8_t)c; } i++; if (i < ccnt) { SPELL_READ_NONNUL_BYTES( // <salfrom> - (char *)p, (size_t)(ccnt - i), fd, + p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead)); p += (ccnt - i); } *p++ = NUL; // <saltolen> <salto> - smp->sm_to = (char *)read_cnt_string(fd, 1, &ccnt); + smp->sm_to = read_cnt_string(fd, 1, &ccnt); if (ccnt < 0) { xfree(smp->sm_lead); return ccnt; @@ -1275,7 +1275,7 @@ static int read_sal_section(FILE *fd, slang_T *slang) if (smp->sm_oneof == NULL) { smp->sm_oneof_w = NULL; } else { - smp->sm_oneof_w = mb_str2wide((char *)smp->sm_oneof); + smp->sm_oneof_w = mb_str2wide(smp->sm_oneof); } if (smp->sm_to == NULL) { smp->sm_to_w = NULL; @@ -1290,12 +1290,12 @@ static int read_sal_section(FILE *fd, slang_T *slang) smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; p = xmalloc(1); p[0] = NUL; - smp->sm_lead = (char *)p; + smp->sm_lead = p; smp->sm_lead_w = mb_str2wide(smp->sm_lead); smp->sm_leadlen = 0; smp->sm_oneof = NULL; smp->sm_oneof_w = NULL; - smp->sm_rules = (char *)p; + smp->sm_rules = p; smp->sm_to = NULL; smp->sm_to_w = NULL; gap->ga_len++; @@ -1350,13 +1350,13 @@ static int read_sofo_section(FILE *fd, slang_T *slang) slang->sl_sofo = true; // <sofofromlen> <sofofrom> - from = (char *)read_cnt_string(fd, 2, &cnt); + from = read_cnt_string(fd, 2, &cnt); if (cnt < 0) { return cnt; } // <sofotolen> <sofoto> - to = (char *)read_cnt_string(fd, 2, &cnt); + to = read_cnt_string(fd, 2, &cnt); if (cnt < 0) { xfree(from); return cnt; @@ -1385,7 +1385,6 @@ static int read_compound(FILE *fd, slang_T *slang, int len) int c; int atstart; int cnt; - garray_T *gap; if (todo < 2) { return SP_FORMERROR; // need at least two bytes @@ -1420,7 +1419,7 @@ static int read_compound(FILE *fd, slang_T *slang, int len) todo--; slang->sl_compoptions = c; - gap = &slang->sl_comppat; + garray_T *gap = &slang->sl_comppat; c = get2c(fd); // <comppatcount> if (c < 0) { return SP_TRUNCERROR; @@ -1429,7 +1428,7 @@ static int read_compound(FILE *fd, slang_T *slang, int len) ga_init(gap, sizeof(char *), c); ga_grow(gap, c); while (--c >= 0) { - ((char **)(gap->ga_data))[gap->ga_len++] = (char *)read_cnt_string(fd, 1, &cnt); + ((char **)(gap->ga_data))[gap->ga_len++] = read_cnt_string(fd, 1, &cnt); // <comppatlen> <comppattext> if (cnt < 0) { return cnt; @@ -1465,7 +1464,7 @@ static int read_compound(FILE *fd, slang_T *slang, int len) uint8_t *crp = xmalloc((size_t)todo + 1); slang->sl_comprules = crp; - char_u *pp = (char_u *)pat; + char *pp = pat; *pp++ = '^'; *pp++ = '\\'; *pp++ = '('; @@ -1521,7 +1520,7 @@ static int read_compound(FILE *fd, slang_T *slang, int len) if (c == '?' || c == '+' || c == '~') { *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+" } - pp += utf_char2bytes(c, (char *)pp); + pp += utf_char2bytes(c, pp); } } @@ -1612,7 +1611,6 @@ static void set_sal_first(slang_T *lp) { salfirst_T *sfirst; salitem_T *smp; - int c; garray_T *gap = &lp->sl_sal; sfirst = lp->sl_sal_first; @@ -1624,7 +1622,7 @@ static void set_sal_first(slang_T *lp) // Use the lowest byte of the first character. For latin1 it's // the character, for other encodings it should differ for most // characters. - c = *smp[i].sm_lead_w & 0xff; + int c = *smp[i].sm_lead_w & 0xff; if (sfirst[c] == -1) { sfirst[c] = i; @@ -1735,10 +1733,8 @@ static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx bool prefixtree, int maxprefcondnr) { int len; - int i; int n; idx_T idx = startidx; - int c; int c2; #define SHARED_MASK 0x8000000 @@ -1753,8 +1749,8 @@ static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx byts[idx++] = (char_u)len; // Read the byte values, flag/region bytes and shared indexes. - for (i = 1; i <= len; i++) { - c = getc(fd); // <byte> + for (int i = 1; i <= len; i++) { + int c = getc(fd); // <byte> if (c < 0) { return SP_TRUNCERROR; } @@ -1816,7 +1812,7 @@ static idx_T read_tree_node(FILE *fd, char_u *byts, idx_T *idxs, int maxidx, idx // Recursively read the children for non-shared siblings. // Skip the end-of-word ones (zero byte value) and the shared ones (and // remove SHARED_MASK) - for (i = 1; i <= len; i++) { + for (int i = 1; i <= len; i++) { if (byts[startidx + i] != 0) { if (idxs[startidx + i] & SHARED_MASK) { idxs[startidx + i] &= ~SHARED_MASK; @@ -1957,9 +1953,9 @@ static void spell_print_node(wordnode_T *node, int depth) PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0); PRINTSOME(line2, depth, " ", 0, 0); PRINTSOME(line3, depth, " ", 0, 0); - msg((char_u *)line1); - msg((char_u *)line2); - msg((char_u *)line3); + msg(line1); + msg(line2); + msg(line3); } else { node->wn_u1.index = true; @@ -1983,9 +1979,9 @@ static void spell_print_node(wordnode_T *node, int depth) } if (node->wn_byte == NUL) { - msg((char_u *)line1); - msg((char_u *)line2); - msg((char_u *)line3); + msg(line1); + msg(line2); + msg(line3); } // do the children @@ -2434,7 +2430,6 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) && strcmp(cur_aff->ah_key, items[1]) == 0 && itemcnt >= 5) { affentry_T *aff_entry; - bool upper = false; int lasti = 5; // Myspell allows extra text after the item, but that might @@ -2493,6 +2488,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) // COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG. if (*items[0] == 'P' && aff->af_pfxpostpone && aff_entry->ae_flags == NULL) { + bool upper = false; // When the chop string is one lower-case letter and // the add string ends in the upper-case letter we set // the "upper" flag, clear "ae_chop" and remove the @@ -2502,10 +2498,8 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) && aff_entry->ae_add != NULL && aff_entry->ae_chop[utfc_ptr2len(aff_entry->ae_chop)] == NUL) { - int c, c_up; - - c = utf_ptr2char(aff_entry->ae_chop); - c_up = SPELL_TOUPPER(c); + int c = utf_ptr2char(aff_entry->ae_chop); + int c_up = SPELL_TOUPPER(c); if (c_up != c && (aff_entry->ae_cond == NULL || utf_ptr2char(aff_entry->ae_cond) == c)) { @@ -2535,8 +2529,6 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) if (aff_entry->ae_chop == NULL) { int idx; - char_u **pp; - int n; // Find a previously used condition. for (idx = spin->si_prefcond.ga_len - 1; idx >= 0; idx--) { @@ -2548,7 +2540,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) if (idx < 0) { // Not found, add a new condition. idx = spin->si_prefcond.ga_len; - pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond); + char_u **pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond); *pp = (aff_entry->ae_cond == NULL) ? NULL : (char_u *)getroom_save(spin, aff_entry->ae_cond); } @@ -2562,7 +2554,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) // PFX_FLAGS is a negative number, so that // tree_add_word() knows this is the prefix tree. - n = PFX_FLAGS; + int n = PFX_FLAGS; if (!cur_aff->ah_combine) { n |= WFP_NC; } @@ -2636,11 +2628,9 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) fname, lnum); } } else if (do_mapline) { - int c; - // Check that every character appears only once. for (p = items[1]; *p != NUL;) { - c = mb_ptr2char_adv((const char **)&p); + int c = mb_ptr2char_adv((const char **)&p); if ((!GA_EMPTY(&spin->si_map) && vim_strchr(spin->si_map.ga_data, c) != NULL) @@ -2681,9 +2671,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) && sofoto == NULL) { sofoto = getroom_save(spin, items[1]); } else if (strcmp(items[0], "COMMON") == 0) { - int i; - - for (i = 1; i < itemcnt; i++) { + for (int i = 1; i < itemcnt; i++) { if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords, (char *)items[i]))) { p = xstrdup(items[i]); hash_add(&spin->si_commonwords, p); @@ -2791,16 +2779,14 @@ static bool is_aff_rule(char **items, int itemcnt, char *rulename, int mincount) static void aff_process_flags(afffile_T *affile, affentry_T *entry) { char *p; - char_u *prevp; - unsigned flag; if (entry->ae_flags != NULL && (affile->af_compforbid != 0 || affile->af_comppermit != 0)) { for (p = entry->ae_flags; *p != NUL;) { - prevp = (char_u *)p; - flag = get_affitem(affile->af_flagtype, &p); + char_u *prevp = (char_u *)p; + unsigned flag = get_affitem(affile->af_flagtype, &p); if (flag == affile->af_comppermit || flag == affile->af_compforbid) { - STRMOVE(prevp, (char *)p); + STRMOVE(prevp, p); p = (char *)prevp; if (flag == affile->af_comppermit) { entry->ae_comppermit = true; @@ -2833,10 +2819,9 @@ static bool spell_info_item(char *s) // returns zero for failure. static unsigned affitem2flag(int flagtype, char *item, char *fname, int lnum) { - unsigned res; char *p = item; - res = get_affitem(flagtype, &p); + unsigned res = get_affitem(flagtype, &p); if (res == 0) { if (flagtype == AFT_NUM) { smsg(_("Flag is not a number in %s line %d: %s"), @@ -2889,30 +2874,27 @@ static unsigned get_affitem(int flagtype, char **pp) /// they fit in one byte. static void process_compflags(spellinfo_T *spin, afffile_T *aff, char *compflags) { - char *p; char *prevp; unsigned flag; compitem_T *ci; int id; - int len; - char_u *tp; char key[AH_KEY_LEN]; hashitem_T *hi; // Make room for the old and the new compflags, concatenated with a / in // between. Processing it makes it shorter, but we don't know by how // much, thus allocate the maximum. - len = (int)strlen(compflags) + 1; + int len = (int)strlen(compflags) + 1; if (spin->si_compflags != NULL) { len += (int)strlen(spin->si_compflags) + 1; } - p = getroom(spin, (size_t)len, false); + char *p = getroom(spin, (size_t)len, false); if (spin->si_compflags != NULL) { STRCPY(p, spin->si_compflags); STRCAT(p, "/"); } spin->si_compflags = p; - tp = (char_u *)p + strlen(p); + char_u *tp = (char_u *)p + strlen(p); for (p = compflags; *p != NUL;) { if (vim_strchr("/?*+[]", (uint8_t)(*p)) != NULL) { @@ -2940,9 +2922,9 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char *compflags id = spin->si_newcompID--; } while (vim_strchr("/?*+[]\\-^", id) != NULL); ci->ci_newID = id; - hash_add(&aff->af_comp, (char *)ci->ci_key); + hash_add(&aff->af_comp, ci->ci_key); } - *tp++ = (char_u)id; + *tp++ = (uint8_t)id; } if (aff->af_flagtype == AFT_NUM && *p == ',') { p++; @@ -3061,7 +3043,6 @@ static void spell_free_aff(afffile_T *aff) { hashtab_T *ht; hashitem_T *hi; - int todo; affheader_T *ah; affentry_T *ae; @@ -3069,7 +3050,7 @@ static void spell_free_aff(afffile_T *aff) // All this trouble to free the "ae_prog" items... for (ht = &aff->af_pref;; ht = &aff->af_suff) { - todo = (int)ht->ht_used; + int todo = (int)ht->ht_used; for (hi = ht->ht_array; todo > 0; hi++) { if (!HASHITEM_EMPTY(hi)) { todo--; @@ -3095,28 +3076,27 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) { hashtab_T ht; char line[MAXLINELEN]; - char_u *p; - char_u *afflist; - char_u store_afflist[MAXWLEN]; + char *p; + char *afflist; + char store_afflist[MAXWLEN]; int pfxlen; bool need_affix; char *dw; - char_u *pc; - char_u *w; + char *pc; + char *w; int l; hash_T hash; hashitem_T *hi; - FILE *fd; int lnum = 1; int non_ascii = 0; int retval = OK; - char_u message[MAXLINELEN + MAXWLEN]; + char message[MAXLINELEN + MAXWLEN]; int flags; int duplicate = 0; Timestamp last_msg_time = 0; // Open the file. - fd = os_fopen(fname, "r"); + FILE *fd = os_fopen(fname, "r"); if (fd == NULL) { semsg(_(e_notopen), fname); return FAIL; @@ -3159,7 +3139,7 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) // Convert from "SET" to 'encoding' when needed. if (spin->si_conv.vc_type != CONV_NONE) { - pc = (char_u *)string_convert(&spin->si_conv, (char *)line, NULL); + pc = string_convert(&spin->si_conv, (char *)line, NULL); if (pc == NULL) { smsg(_("Conversion failure for word in %s line %d: %s"), fname, lnum, line); @@ -3168,7 +3148,7 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) w = pc; } else { pc = NULL; - w = (char_u *)line; + w = line; } // Truncate the word at the "/", set "afflist" to what follows. @@ -3176,7 +3156,7 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) afflist = NULL; for (p = w; *p != NUL; MB_PTR_ADV(p)) { if (*p == '\\' && (p[1] == '\\' || p[1] == '/')) { - STRMOVE(p, (char *)p + 1); + STRMOVE(p, p + 1); } else if (*p == '/') { *p = NUL; afflist = p + 1; @@ -3185,7 +3165,7 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) } // Skip non-ASCII words when "spin->si_ascii" is true. - if (spin->si_ascii && has_non_ascii((char *)w)) { + if (spin->si_ascii && has_non_ascii(w)) { non_ascii++; xfree(pc); continue; @@ -3197,11 +3177,11 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) spin->si_msg_count = 0; if (os_time() > last_msg_time) { last_msg_time = os_time(); - vim_snprintf((char *)message, sizeof(message), + vim_snprintf(message, sizeof(message), _("line %6d, word %6ld - %s"), lnum, spin->si_foldwcount + spin->si_keepwcount, w); msg_start(); - msg_outtrans_long_attr((char *)message, 0); + msg_outtrans_long_attr(message, 0); msg_clr_eos(); msg_didout = false; msg_col = 0; @@ -3210,7 +3190,7 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) } // Store the word in the hashtable to be able to find duplicates. - dw = getroom_save(spin, (char *)w); + dw = getroom_save(spin, w); if (dw == NULL) { retval = FAIL; xfree(pc); @@ -3218,7 +3198,7 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) } hash = hash_hash(dw); - hi = hash_lookup(&ht, (const char *)dw, strlen(dw), hash); + hi = hash_lookup(&ht, dw, strlen(dw), hash); if (!HASHITEM_EMPTY(hi)) { if (p_verbose > 0) { smsg(_("Duplicate word in %s line %d: %s"), @@ -3238,45 +3218,45 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) need_affix = false; if (afflist != NULL) { // Extract flags from the affix list. - flags |= get_affix_flags(affile, (char *)afflist); + flags |= get_affix_flags(affile, afflist); if (affile->af_needaffix != 0 - && flag_in_afflist(affile->af_flagtype, (char *)afflist, + && flag_in_afflist(affile->af_flagtype, afflist, affile->af_needaffix)) { need_affix = true; } if (affile->af_pfxpostpone) { // Need to store the list of prefix IDs with the word. - pfxlen = get_pfxlist(affile, (char *)afflist, store_afflist); + pfxlen = get_pfxlist(affile, afflist, store_afflist); } 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, (char *)afflist, store_afflist + pfxlen); + get_compflags(affile, afflist, (char_u *)store_afflist + pfxlen); } } // Add the word to the word tree(s). if (store_word(spin, dw, flags, spin->si_region, - (char *)store_afflist, need_affix) == FAIL) { + store_afflist, need_affix) == FAIL) { retval = FAIL; } if (afflist != NULL) { // Find all matching suffixes and add the resulting words. // Additionally do matching prefixes that combine. - if (store_aff_word(spin, dw, (char *)afflist, affile, + if (store_aff_word(spin, dw, afflist, affile, &affile->af_suff, &affile->af_pref, - CONDIT_SUF, flags, (char *)store_afflist, pfxlen) == FAIL) { + CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) { retval = FAIL; } // Find all matching prefixes and add the resulting words. - if (store_aff_word(spin, dw, (char *)afflist, affile, + if (store_aff_word(spin, dw, afflist, affile, &affile->af_pref, NULL, - CONDIT_SUF, flags, (char *)store_afflist, pfxlen) == FAIL) { + CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) { retval = FAIL; } } @@ -3338,17 +3318,15 @@ static int get_affix_flags(afffile_T *affile, char *afflist) // Used for PFXPOSTPONE. // Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL // and return the number of affixes. -static int get_pfxlist(afffile_T *affile, char *afflist, char_u *store_afflist) +static int get_pfxlist(afffile_T *affile, char *afflist, char *store_afflist) { - char *p; - char *prevp; int cnt = 0; int id; char key[AH_KEY_LEN]; hashitem_T *hi; - for (p = afflist; *p != NUL;) { - prevp = p; + for (char *p = afflist; *p != NUL;) { + char *prevp = p; if (get_affitem(affile->af_flagtype, &p) != 0) { // A flag is a postponed prefix flag if it appears in "af_pref" // and its ID is not zero. @@ -3357,7 +3335,7 @@ static int get_pfxlist(afffile_T *affile, char *afflist, char_u *store_afflist) if (!HASHITEM_EMPTY(hi)) { id = HI2AH(hi)->ah_newID; if (id != 0) { - store_afflist[cnt++] = (char_u)id; + store_afflist[cnt++] = (char)(uint8_t)id; } } } @@ -3375,14 +3353,12 @@ static int get_pfxlist(afffile_T *affile, char *afflist, char_u *store_afflist) // Puts the flags in "store_afflist[]". static void get_compflags(afffile_T *affile, char *afflist, char_u *store_afflist) { - char *p; - char *prevp; int cnt = 0; char key[AH_KEY_LEN]; hashitem_T *hi; - for (p = afflist; *p != NUL;) { - prevp = p; + for (char *p = afflist; *p != NUL;) { + char *prevp = p; if (get_affitem(affile->af_flagtype, &p) != 0) { // A flag is a compound flag if it appears in "af_comp". xstrlcpy(key, prevp, (size_t)(p - prevp) + 1); @@ -3418,7 +3394,6 @@ static int store_aff_word(spellinfo_T *spin, char *word, char *afflist, afffile_ hashtab_T *ht, hashtab_T *xht, int condit, int flags, char *pfxlist, int pfxlen) { - int todo; hashitem_T *hi; affheader_T *ah; affentry_T *ae; @@ -3430,12 +3405,12 @@ static int store_aff_word(spellinfo_T *spin, char *word, char *afflist, afffile_ char *use_pfxlist; int use_pfxlen; bool need_affix; - char_u store_afflist[MAXWLEN]; + char store_afflist[MAXWLEN]; char pfx_pfxlist[MAXWLEN]; size_t wordlen = strlen(word); int use_condit; - todo = (int)ht->ht_used; + int todo = (int)ht->ht_used; for (hi = ht->ht_array; todo > 0 && retval == OK; hi++) { if (!HASHITEM_EMPTY(hi)) { todo--; @@ -3539,7 +3514,7 @@ static int store_aff_word(spellinfo_T *spin, char *word, char *afflist, afffile_ } else { use_pfxlen = 0; } - use_pfxlist = (char *)store_afflist; + use_pfxlist = store_afflist; // Combine the prefix IDs. Avoid adding the // same ID twice. @@ -3664,7 +3639,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char *fname) long lnum = 0; char rline[MAXLINELEN]; char *line; - char_u *pc = NULL; + char *pc = NULL; char_u *p; int l; int retval = OK; @@ -3706,13 +3681,13 @@ static int spell_read_wordfile(spellinfo_T *spin, char *fname) // Convert from "/encoding={encoding}" to 'encoding' when needed. xfree(pc); if (spin->si_conv.vc_type != CONV_NONE) { - pc = (char_u *)string_convert(&spin->si_conv, rline, NULL); + pc = string_convert(&spin->si_conv, rline, NULL); if (pc == NULL) { smsg(_("Conversion failure for word in %s line %ld: %s"), fname, lnum, rline); continue; } - line = (char *)pc; + line = pc; } else { pc = NULL; line = rline; @@ -3929,7 +3904,7 @@ static int store_word(spellinfo_T *spin, char *word, int flags, int region, cons { int len = (int)strlen(word); int ct = captype(word, word + len); - char_u foldword[MAXWLEN]; + char foldword[MAXWLEN]; int res = OK; // Avoid adding illegal bytes to the word tree. @@ -3937,10 +3912,10 @@ static int store_word(spellinfo_T *spin, char *word, int flags, int region, cons return FAIL; } - (void)spell_casefold(curwin, word, len, (char *)foldword, MAXWLEN); + (void)spell_casefold(curwin, word, len, foldword, MAXWLEN); for (const char_u *p = (char_u *)pfxlist; res == OK; p++) { if (!need_affix || (p != NULL && *p != NUL)) { - res = tree_add_word(spin, foldword, spin->si_foldroot, ct | flags, + res = tree_add_word(spin, (char_u *)foldword, spin->si_foldroot, ct | flags, region, p == NULL ? 0 : *p); } if (p == NULL || *p == NUL) { @@ -3975,10 +3950,9 @@ static int tree_add_word(spellinfo_T *spin, const char_u *word, wordnode_T *root wordnode_T *np; wordnode_T *copyp, **copyprev; wordnode_T **prev = NULL; - int i; // Add each byte of the word to the tree, including the NUL at the end. - for (i = 0;; i++) { + for (int i = 0;; i++) { // When there is more than one reference to this node we need to make // a copy, so that we can modify it. Copy the whole list of siblings // (we don't optimize for a partly shared list of siblings). @@ -4414,7 +4388,6 @@ static int write_vim_spell(spellinfo_T *spin, char *fname) // the table (avoids that it conflicts). File is shorter too. if (!spin->si_ascii && !spin->si_add) { char folchars[128 * 8]; - int flags; putc(SN_CHARFLAGS, fd); // <sectionID> putc(SNF_REQUIRED, fd); // <sectionflags> @@ -4428,7 +4401,7 @@ static int write_vim_spell(spellinfo_T *spin, char *fname) fputc(128, fd); // <charflagslen> for (size_t i = 128; i < 256; i++) { - flags = 0; + int flags = 0; if (spelltab.st_isw[i]) { flags |= CF_WORD; } @@ -5528,8 +5501,6 @@ void spell_add_word(char *word, int len, SpellAddType what, int idx, bool undo) char *fname; char *fnamebuf = NULL; char line[MAXWLEN * 2]; - long fpos, fpos_next = 0; - int i; char *spf; if (!valid_spell_word(word, word + len)) { @@ -5546,6 +5517,7 @@ void spell_add_word(char *word, int len, SpellAddType what, int idx, bool undo) } fname = int_wordlist; } else { + int i; // If 'spellfile' isn't set figure out a good default value. if (*curwin->w_s->b_p_spf == NUL) { init_spellfile(); @@ -5585,6 +5557,8 @@ void spell_add_word(char *word, int len, SpellAddType what, int idx, bool undo) } if (what == SPELL_ADD_BAD || undo) { + long fpos_next = 0; + long fpos = 0; // When the word appears as good word we need to remove that one, // since its flags sort before the one with WF_BANNED. fd = os_fopen(fname, "r"); @@ -5758,13 +5732,12 @@ static void set_spell_charflags(const char_u *flags, int cnt, char *fol) // We build the new tables here first, so that we can compare with the // previous one. spelltab_T new_st; - int i; char *p = fol; int c; clear_spell_chartab(&new_st); - for (i = 0; i < 128; i++) { + for (int i = 0; i < 128; i++) { if (i < cnt) { new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0; new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0; @@ -5784,11 +5757,9 @@ static void set_spell_charflags(const char_u *flags, int cnt, char *fol) static int set_spell_finish(spelltab_T *new_st) { - int i; - if (did_set_spelltab) { // check that it's the same table - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { if (spelltab.st_isw[i] != new_st->st_isw[i] || spelltab.st_isu[i] != new_st->st_isu[i] || spelltab.st_fold[i] != new_st->st_fold[i] @@ -5841,8 +5812,6 @@ static void set_map_str(slang_T *lp, char *map) { char *p; int headc = 0; - int c; - int i; if (*map == NUL) { lp->sl_has_map = false; @@ -5851,7 +5820,7 @@ static void set_map_str(slang_T *lp, char *map) lp->sl_has_map = true; // Init the array and hash tables empty. - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { lp->sl_map_array[i] = 0; } hash_init(&lp->sl_map_hash); @@ -5860,7 +5829,7 @@ static void set_map_str(slang_T *lp, char *map) // "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and // before the same slash. For characters above 255 sl_map_hash is used. for (p = map; *p != NUL;) { - c = mb_cptr2char_adv((const char **)&p); + int c = mb_cptr2char_adv((const char **)&p); if (c == '/') { headc = 0; } else { diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c index 0ddf07e3a6..d176a65228 100644 --- a/src/nvim/spellsuggest.c +++ b/src/nvim/spellsuggest.c @@ -74,9 +74,9 @@ typedef struct suginfo_S { char *su_badptr; ///< start of bad word in line int su_badlen; ///< length of detected bad word in line int su_badflags; ///< caps flags for bad word - char_u su_badword[MAXWLEN]; ///< bad word truncated at su_badlen + char su_badword[MAXWLEN]; ///< bad word truncated at su_badlen char su_fbadword[MAXWLEN]; ///< su_badword case-folded - char_u su_sal_badword[MAXWLEN]; ///< su_badword soundfolded + char su_sal_badword[MAXWLEN]; ///< su_badword soundfolded hashtab_T su_banned; ///< table with banned words slang_T *su_sallang; ///< default language for sound folding } suginfo_T; @@ -269,18 +269,17 @@ static bool can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, i /// Adjust the score of common words. /// /// @param split word was split, less bonus -static int score_wordcount_adj(slang_T *slang, int score, char_u *word, bool split) +static int score_wordcount_adj(slang_T *slang, int score, char *word, bool split) { - wordcount_T *wc; int bonus; int newscore; - hashitem_T *hi = hash_find(&slang->sl_wordcount, (char *)word); + hashitem_T *hi = hash_find(&slang->sl_wordcount, word); if (HASHITEM_EMPTY(hi)) { return score; } - wc = HI2WC(hi); + wordcount_T *wc = HI2WC(hi); if (wc->wc_count < SCORE_THRES2) { bonus = SCORE_COMMON1; } else if (wc->wc_count < SCORE_THRES3) { @@ -302,24 +301,21 @@ static int score_wordcount_adj(slang_T *slang, int score, char_u *word, bool spl /// Like captype() but for a KEEPCAP word add ONECAP if the word starts with a /// capital. So that make_case_word() can turn WOrd into Word. /// Add ALLCAP for "WOrD". -static int badword_captype(char_u *word, char_u *end) +static int badword_captype(char *word, char *end) FUNC_ATTR_NONNULL_ALL { - int flags = captype((char *)word, (char *)end); - int c; - int l, u; - bool first; - char_u *p; + int flags = captype(word, end); if (!(flags & WF_KEEPCAP)) { return flags; } // Count the number of UPPER and lower case letters. - l = u = 0; - first = false; - for (p = word; p < end; MB_PTR_ADV(p)) { - c = utf_ptr2char((char *)p); + int l= 0; + int u= 0; + bool first = false; + for (char *p = word; p < end; MB_PTR_ADV(p)) { + int c = utf_ptr2char(p); if (SPELL_ISUPPER(c)) { u++; if (p == word) { @@ -351,13 +347,12 @@ static int badword_captype(char_u *word, char_u *end) /// "pp" points to the bytes and is advanced over it. /// /// @return the offset. -static int bytes2offset(char_u **pp) +static int bytes2offset(char **pp) { - char_u *p = *pp; + char_u *p = (char_u *)(*pp); int nr; - int c; - c = *p++; + int c = *p++; if ((c & 0x80) == 0x00) { // 1 byte nr = c - 1; } else if ((c & 0xc0) == 0x80) { // 2 bytes @@ -374,7 +369,7 @@ static int bytes2offset(char_u **pp) nr = nr * 255 + (*p++ - 1); } - *pp = p; + *pp = (char *)p; return nr; } @@ -392,20 +387,18 @@ static int sps_limit = 9999; ///< max nr of suggestions given /// Sets "sps_flags" and "sps_limit". int spell_check_sps(void) { - char *p; char *s; char buf[MAXPATHL]; - int f; sps_flags = 0; sps_limit = 9999; - for (p = p_sps; *p != NUL;) { - copy_option_part(&p, (char *)buf, MAXPATHL, ","); + for (char *p = p_sps; *p != NUL;) { + copy_option_part(&p, buf, MAXPATHL, ","); - f = 0; + int f = 0; if (ascii_isdigit(*buf)) { - s = (char *)buf; + s = buf; sps_limit = getdigits_int(&s, true, 0); if (*s != NUL && !ascii_isdigit(*s)) { f = -1; @@ -450,12 +443,10 @@ void spell_suggest(int count) char *line; pos_T prev_cursor = curwin->w_cursor; char wcopy[MAXWLEN + 2]; - char_u *p; - int c; + char *p; suginfo_T sug; suggest_T *stp; int mouse_used; - int need_cap; int limit; int selected = count; int badlen = 0; @@ -499,27 +490,27 @@ void spell_suggest(int count) // cursor. curwin->w_cursor = prev_cursor; line = get_cursor_line_ptr(); - p = (char_u *)line + curwin->w_cursor.col; + p = line + curwin->w_cursor.col; // Backup to before start of word. - while (p > (char_u *)line && spell_iswordp_nmw((char *)p, curwin)) { + while (p > line && spell_iswordp_nmw(p, curwin)) { MB_PTR_BACK(line, p); } // Forward to start of word. - while (*p != NUL && !spell_iswordp_nmw((char *)p, curwin)) { + while (*p != NUL && !spell_iswordp_nmw(p, curwin)) { MB_PTR_ADV(p); } - if (!spell_iswordp_nmw((char *)p, curwin)) { // No word found. + if (!spell_iswordp_nmw(p, curwin)) { // No word found. beep_flush(); return; } - curwin->w_cursor.col = (colnr_T)(p - (char_u *)line); + curwin->w_cursor.col = (colnr_T)(p - line); } // Get the word and its length. // Figure out if the word should be capitalised. - need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col); + int need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col); // Make a copy of current line since autocommands may free the line. line = xstrdup(get_cursor_line_ptr()); @@ -532,7 +523,7 @@ void spell_suggest(int count) } else { limit = sps_limit; } - spell_find_suggest((char_u *)line + curwin->w_cursor.col, badlen, &sug, limit, + spell_find_suggest(line + curwin->w_cursor.col, badlen, &sug, limit, true, need_cap, true); if (GA_EMPTY(&sug.su_ga)) { @@ -651,7 +642,7 @@ void spell_suggest(int count) // Replace the word. p = xmalloc(strlen(line) - (size_t)stp->st_orglen + (size_t)stp->st_wordlen + 1); - c = (int)(sug.su_badptr - line); + int c = (int)(sug.su_badptr - line); memmove(p, line, (size_t)c); STRCPY(p + c, stp->st_word); STRCAT(p, sug.su_badptr + stp->st_orglen); @@ -659,12 +650,12 @@ void spell_suggest(int count) // For redo we use a change-word command. ResetRedobuff(); AppendToRedobuff("ciw"); - AppendToRedobuffLit((char *)p + c, + AppendToRedobuffLit(p + c, stp->st_wordlen + sug.su_badlen - stp->st_orglen); AppendCharToRedobuff(ESC); // "p" may be freed here - ml_replace(curwin->w_cursor.lnum, (char *)p, false); + ml_replace(curwin->w_cursor.lnum, p, false); curwin->w_cursor.col = c; inserted_bytes(curwin->w_cursor.lnum, c, stp->st_orglen, stp->st_wordlen); @@ -685,23 +676,22 @@ void spell_suggest(int count) void spell_suggest_list(garray_T *gap, char *word, int maxcount, bool need_cap, bool interactive) { suginfo_T sug; - suggest_T *stp; - char_u *wcopy; + char *wcopy; - spell_find_suggest((char_u *)word, 0, &sug, maxcount, false, need_cap, interactive); + spell_find_suggest(word, 0, &sug, maxcount, false, need_cap, interactive); // Make room in "gap". - ga_init(gap, sizeof(char_u *), sug.su_ga.ga_len + 1); + ga_init(gap, sizeof(char *), sug.su_ga.ga_len + 1); ga_grow(gap, sug.su_ga.ga_len); for (int i = 0; i < sug.su_ga.ga_len; i++) { - stp = &SUG(sug.su_ga, i); + suggest_T *stp = &SUG(sug.su_ga, i); // The suggested word may replace only part of "word", add the not // replaced part. wcopy = xmalloc((size_t)stp->st_wordlen + strlen(sug.su_badptr + stp->st_orglen) + 1); STRCPY(wcopy, stp->st_word); STRCPY(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen); - ((char_u **)gap->ga_data)[gap->ga_len++] = wcopy; + ((char **)gap->ga_data)[gap->ga_len++] = wcopy; } spell_find_cleanup(&sug); @@ -716,16 +706,13 @@ void spell_suggest_list(garray_T *gap, char *word, int maxcount, bool need_cap, /// @param badlen length of bad word or 0 if unknown /// @param banbadword don't include badword in suggestions /// @param need_cap word should start with capital -static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int maxcount, +static void spell_find_suggest(char *badptr, int badlen, suginfo_T *su, int maxcount, bool banbadword, bool need_cap, bool interactive) { hlf_T attr = HLF_COUNT; char buf[MAXPATHL]; - char *p; bool do_combine = false; - char *sps_copy; static bool expr_busy = false; - int c; langp_T *lp; bool did_intern = false; @@ -738,7 +725,7 @@ static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int ma } hash_init(&su->su_banned); - su->su_badptr = (char *)badptr; + su->su_badptr = badptr; if (badlen != 0) { su->su_badlen = badlen; } else { @@ -752,7 +739,7 @@ static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int ma if (su->su_badlen >= MAXWLEN) { su->su_badlen = MAXWLEN - 1; // just in case } - xstrlcpy((char *)su->su_badword, su->su_badptr, (size_t)su->su_badlen + 1); + xstrlcpy(su->su_badword, su->su_badptr, (size_t)su->su_badlen + 1); (void)spell_casefold(curwin, su->su_badptr, su->su_badlen, su->su_fbadword, MAXWLEN); @@ -762,8 +749,8 @@ static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int ma su->su_fbadword[su->su_badlen] = NUL; // get caps flags for bad word - su->su_badflags = badword_captype((char_u *)su->su_badptr, - (char_u *)su->su_badptr + su->su_badlen); + su->su_badflags = badword_captype(su->su_badptr, + su->su_badptr + su->su_badlen); if (need_cap) { su->su_badflags |= WF_ONECAP; } @@ -783,46 +770,46 @@ static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int ma // Soundfold the bad word with the default sound folding, so that we don't // have to do this many times. if (su->su_sallang != NULL) { - spell_soundfold(su->su_sallang, (char *)su->su_fbadword, true, - (char *)su->su_sal_badword); + spell_soundfold(su->su_sallang, su->su_fbadword, true, + su->su_sal_badword); } // If the word is not capitalised and spell_check() doesn't consider the // word to be bad then it might need to be capitalised. Add a suggestion // for that. - c = utf_ptr2char(su->su_badptr); + int c = utf_ptr2char(su->su_badptr); if (!SPELL_ISUPPER(c) && attr == HLF_COUNT) { - make_case_word((char *)su->su_badword, buf, WF_ONECAP); - add_suggestion(su, &su->su_ga, (char *)buf, su->su_badlen, SCORE_ICASE, + make_case_word(su->su_badword, buf, WF_ONECAP); + add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE, 0, true, su->su_sallang, false); } // Ban the bad word itself. It may appear in another region. if (banbadword) { - add_banned(su, (char *)su->su_badword); + add_banned(su, su->su_badword); } // Make a copy of 'spellsuggest', because the expression may change it. - sps_copy = xstrdup(p_sps); + char *sps_copy = xstrdup(p_sps); // Loop over the items in 'spellsuggest'. - for (p = sps_copy; *p != NUL;) { - copy_option_part(&p, (char *)buf, MAXPATHL, ","); + for (char *p = sps_copy; *p != NUL;) { + copy_option_part(&p, buf, MAXPATHL, ","); if (strncmp(buf, "expr:", 5) == 0) { // Evaluate an expression. Skip this when called recursively, // when using spellsuggest() in the expression. if (!expr_busy) { expr_busy = true; - spell_suggest_expr(su, (char_u *)buf + 5); + spell_suggest_expr(su, buf + 5); expr_busy = false; } } else if (strncmp(buf, "file:", 5) == 0) { // Use list of suggestions in a file. - spell_suggest_file(su, (char_u *)buf + 5); + spell_suggest_file(su, buf + 5); } else if (strncmp(buf, "timeout:", 8) == 0) { // Limit the time searching for suggestions. - spell_suggest_timeout = atol((char *)buf + 8); + spell_suggest_timeout = atol(buf + 8); } else if (!did_intern) { // Use internal method once. spell_suggest_intern(su, interactive); @@ -843,21 +830,20 @@ static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int ma } /// Find suggestions by evaluating expression "expr". -static void spell_suggest_expr(suginfo_T *su, char_u *expr) +static void spell_suggest_expr(suginfo_T *su, char *expr) { - int score; const char *p; // The work is split up in a few parts to avoid having to export // suginfo_T. // First evaluate the expression and get the resulting list. - list_T *const list = eval_spell_expr((char *)su->su_badword, (char *)expr); + list_T *const list = eval_spell_expr(su->su_badword, expr); if (list != NULL) { // Loop over the items in the list. TV_LIST_ITER(list, li, { if (TV_LIST_ITEM_TV(li)->v_type == VAR_LIST) { // Get the word and the score from the items. - score = get_spellword(TV_LIST_ITEM_TV(li)->vval.v_list, &p); + int score = get_spellword(TV_LIST_ITEM_TV(li)->vval.v_list, &p); if (score >= 0 && score <= su->su_maxscore) { add_suggestion(su, &su->su_ga, p, su->su_badlen, score, 0, true, su->su_sallang, false); @@ -873,43 +859,41 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr) } /// Find suggestions in file "fname". Used for "file:" in 'spellsuggest'. -static void spell_suggest_file(suginfo_T *su, char_u *fname) +static void spell_suggest_file(suginfo_T *su, char *fname) { - FILE *fd; - char_u line[MAXWLEN * 2]; - char_u *p; + char line[MAXWLEN * 2]; int len; - char_u cword[MAXWLEN]; + char cword[MAXWLEN]; // Open the file. - fd = os_fopen((char *)fname, "r"); + FILE *fd = os_fopen(fname, "r"); if (fd == NULL) { semsg(_(e_notopen), fname); return; } // Read it line by line. - while (!vim_fgets((char *)line, MAXWLEN * 2, fd) && !got_int) { + while (!vim_fgets(line, MAXWLEN * 2, fd) && !got_int) { line_breakcheck(); - p = (char_u *)vim_strchr((char *)line, '/'); + char *p = vim_strchr(line, '/'); if (p == NULL) { continue; // No Tab found, just skip the line. } *p++ = NUL; if (STRICMP(su->su_badword, line) == 0) { // Match! Isolate the good word, until CR or NL. - for (len = 0; p[len] >= ' '; len++) {} + for (len = 0; (uint8_t)p[len] >= ' '; len++) {} p[len] = NUL; // If the suggestion doesn't have specific case duplicate the case // of the bad word. - if (captype((char *)p, NULL) == 0) { - make_case_word((char *)p, (char *)cword, su->su_badflags); + if (captype(p, NULL) == 0) { + make_case_word(p, cword, su->su_badflags); p = cword; } - add_suggestion(su, &su->su_ga, (char *)p, su->su_badlen, + add_suggestion(su, &su->su_ga, p, su->su_badlen, SCORE_FILE, 0, true, su->su_sallang, false); } } @@ -1013,24 +997,23 @@ static void spell_find_cleanup(suginfo_T *su) /// Try finding suggestions by recognizing specific situations. static void suggest_try_special(suginfo_T *su) { - char c; - char_u word[MAXWLEN]; + char word[MAXWLEN]; // Recognize a word that is repeated: "the the". - char *p = skiptowhite((char *)su->su_fbadword); - size_t len = (size_t)(p - (char *)su->su_fbadword); + char *p = skiptowhite(su->su_fbadword); + size_t len = (size_t)(p - su->su_fbadword); p = skipwhite(p); if (strlen(p) == len && strncmp(su->su_fbadword, p, len) == 0) { // Include badflags: if the badword is onecap or allcap // use that for the goodword too: "The the" -> "The". - c = su->su_fbadword[len]; + char c = su->su_fbadword[len]; su->su_fbadword[len] = NUL; - make_case_word(su->su_fbadword, (char *)word, su->su_badflags); + make_case_word(su->su_fbadword, word, su->su_badflags); su->su_fbadword[len] = c; // Give a soundalike score of 0, compute the score as if deleting one // character. - add_suggestion(su, &su->su_ga, (char *)word, su->su_badlen, + add_suggestion(su, &su->su_ga, word, su->su_badlen, RESCORE(SCORE_REP, 0), 0, true, su->su_sallang, false); } } @@ -1084,16 +1067,14 @@ static void prof_report(char *name) static void suggest_try_change(suginfo_T *su) { char fword[MAXWLEN]; // copy of the bad word, case-folded - int n; - char *p; langp_T *lp; // We make a copy of the case-folded bad word, so that we can modify it // to find matches (esp. REP items). Append some more text, changing // chars after the bad word may help. STRCPY(fword, su->su_fbadword); - n = (int)strlen(fword); - p = su->su_badptr + su->su_badlen; + int n = (int)strlen(fword); + char *p = su->su_badptr + su->su_badlen; (void)spell_casefold(curwin, p, (int)strlen(p), fword + n, MAXWLEN - n); // Make sure the resulting text is not longer than the original text. @@ -1165,12 +1146,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // when going deeper but not when coming // back. char_u compflags[MAXWLEN]; // compound flags, one for each word - trystate_T *sp; int newscore; int score; char_u *byts, *fbyts, *pbyts; idx_T *idxs, *fidxs, *pidxs; - int depth; int c, c2, c3; int n = 0; int flags; @@ -1195,8 +1174,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // "tword[]" contains the word collected from nodes in the tree. // "fword[]" the word we are trying to match with (initially the bad // word). - depth = 0; - sp = &stack[0]; + int depth = 0; + trystate_T *sp = &stack[0]; CLEAR_POINTER(sp); // -V1068 sp->ts_curi = 1; @@ -1268,9 +1247,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // Set su->su_badflags to the caps type at this position. // Use the caps type until here for the prefix itself. n = nofold_len(fword, sp->ts_fidx, su->su_badptr); - flags = badword_captype((char_u *)su->su_badptr, (char_u *)su->su_badptr + n); - su->su_badflags = badword_captype((char_u *)su->su_badptr + n, - (char_u *)su->su_badptr + su->su_badlen); + flags = badword_captype(su->su_badptr, su->su_badptr + n); + su->su_badflags = badword_captype(su->su_badptr + n, + su->su_badptr + su->su_badlen); #ifdef DEBUG_TRIEWALK sprintf(changename[depth], "prefix"); // NOLINT(runtime/printf) #endif @@ -1371,11 +1350,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun (size_t)(sp->ts_fidx - sp->ts_splitfidx)) == 0) { preword[sp->ts_prewordlen] = NUL; newscore = score_wordcount_adj(slang, sp->ts_score, - (char_u *)preword + sp->ts_prewordlen, + preword + sp->ts_prewordlen, sp->ts_prewordlen > 0); // Add the suggestion if the score isn't too bad. if (newscore <= su->su_maxscore) { - add_suggestion(su, &su->su_ga, (char *)preword, + add_suggestion(su, &su->su_ga, preword, sp->ts_splitfidx - repextra, newscore, 0, false, lp->lp_sallang, false); @@ -1437,7 +1416,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun STRCPY(preword + sp->ts_prewordlen, tword + sp->ts_splitoff); } else if (flags & WF_KEEPCAP) { // Must find the word in the keep-case tree. - find_keepcap_word(slang, (char *)tword + sp->ts_splitoff, preword + sp->ts_prewordlen); + find_keepcap_word(slang, tword + sp->ts_splitoff, preword + sp->ts_prewordlen); } else { // Include badflags: If the badword is onecap or allcap // use that for the goodword too. But if the badword is @@ -1465,8 +1444,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun break; } if ((sp->ts_complen == sp->ts_compsplit - && WAS_BANNED(su, (char *)preword + sp->ts_prewordlen)) - || WAS_BANNED(su, (char *)preword)) { + && WAS_BANNED(su, preword + sp->ts_prewordlen)) + || WAS_BANNED(su, preword)) { if (slang->sl_compprog == NULL) { break; } @@ -1528,12 +1507,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // Give a bonus to words seen before. score = score_wordcount_adj(slang, sp->ts_score + newscore, - (char_u *)preword + sp->ts_prewordlen, + preword + sp->ts_prewordlen, sp->ts_prewordlen > 0); // Add the suggestion if the score isn't too bad. if (score <= su->su_maxscore) { - add_suggestion(su, &su->su_ga, (char *)preword, + add_suggestion(su, &su->su_ga, preword, sp->ts_fidx - repextra, score, 0, false, lp->lp_sallang, false); @@ -1546,7 +1525,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun preword + sp->ts_prewordlen, c == 0 ? WF_ALLCAP : 0); - add_suggestion(su, &su->su_ga, (char *)preword, + add_suggestion(su, &su->su_ga, preword, sp->ts_fidx - repextra, score + SCORE_ICASE, 0, false, lp->lp_sallang, false); @@ -1647,7 +1626,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // Give a bonus to words seen before. newscore = score_wordcount_adj(slang, newscore, - (char_u *)preword + sp->ts_prewordlen, true); + preword + sp->ts_prewordlen, true); } if (TRY_DEEPER(su, stack, depth, newscore)) { @@ -1715,8 +1694,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // set su->su_badflags to the caps type at this // position n = nofold_len(fword, sp->ts_fidx, su->su_badptr); - su->su_badflags = badword_captype((char_u *)su->su_badptr + n, - (char_u *)su->su_badptr + su->su_badlen); + su->su_badflags = badword_captype(su->su_badptr + n, + su->su_badptr + su->su_badlen); // Restart at top of the tree. sp->ts_arridx = 0; @@ -1843,7 +1822,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // For changing a composing character adjust // the score from SCORE_SUBST to // SCORE_SUBCOMP. - if (utf_iscomposing(utf_ptr2char((char *)tword + sp->ts_twordlen + if (utf_iscomposing(utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen)) && utf_iscomposing(utf_ptr2char(fword + sp->ts_fcharstart))) { @@ -1851,7 +1830,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun } else if (!soundfold && slang->sl_has_map && similar_chars(slang, - utf_ptr2char((char *)tword + sp->ts_twordlen - + utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen), utf_ptr2char(fword + sp->ts_fcharstart))) { // For a similar character adjust score from @@ -1860,7 +1839,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun } } else if (sp->ts_isdiff == DIFF_INSERT && sp->ts_twordlen > sp->ts_tcharlen) { - p = (char *)tword + sp->ts_twordlen - sp->ts_tcharlen; + p = tword + sp->ts_twordlen - sp->ts_tcharlen; c = utf_ptr2char(p); if (utf_iscomposing(c)) { // Inserting a composing char doesn't @@ -2310,7 +2289,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun fl = (int)strlen(ftp->ft_from); tl = (int)strlen(ftp->ft_to); if (fl != tl) { - STRMOVE(p + tl, (char *)p + fl); + STRMOVE(p + tl, p + fl); repextra += tl - fl; } memmove(p, ftp->ft_to, (size_t)tl); @@ -2340,7 +2319,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun tl = (int)strlen(ftp->ft_to); p = fword + sp->ts_fidx; if (fl != tl) { - STRMOVE(p + fl, (char *)p + tl); + STRMOVE(p + fl, p + tl); repextra -= tl - fl; } memmove(p, ftp->ft_from, (size_t)fl); @@ -2387,7 +2366,6 @@ static void go_deeper(trystate_T *stack, int depth, int score_add) static void find_keepcap_word(slang_T *slang, char *fword, char *kword) { char uword[MAXWLEN]; // "fword" in upper-case - int depth; idx_T tryidx; // The following arrays are used at each depth in the tree. @@ -2402,7 +2380,7 @@ static void find_keepcap_word(slang_T *slang, char *fword, char *kword) int len; int c; idx_T lo, hi, m; - char_u *p; + char *p; char_u *byts = (char_u *)slang->sl_kbyts; // array with bytes of the words idx_T *idxs = slang->sl_kidxs; // array with indexes @@ -2418,7 +2396,7 @@ static void find_keepcap_word(slang_T *slang, char *fword, char *kword) // Each character needs to be tried both case-folded and upper-case. // All this gets very complicated if we keep in mind that changing case // may change the byte length of a multi-byte character... - depth = 0; + int depth = 0; arridx[0] = 0; round[0] = 0; fwordidx[0] = 0; @@ -2443,19 +2421,19 @@ static void find_keepcap_word(slang_T *slang, char *fword, char *kword) // round[depth] == 1: Try using the folded-case character. // round[depth] == 2: Try using the upper-case character. flen = utf_ptr2len(fword + fwordidx[depth]); - ulen = utf_ptr2len((char *)uword + uwordidx[depth]); + ulen = utf_ptr2len(uword + uwordidx[depth]); if (round[depth] == 1) { - p = (char_u *)fword + fwordidx[depth]; + p = fword + fwordidx[depth]; l = flen; } else { - p = (char_u *)uword + uwordidx[depth]; + p = uword + uwordidx[depth]; l = ulen; } for (tryidx = arridx[depth]; l > 0; l--) { // Perform a binary search in the list of accepted bytes. len = byts[tryidx++]; - c = *p++; + c = (uint8_t)(*p++); lo = tryidx; hi = tryidx + len - 1; while (lo < hi) { @@ -2512,8 +2490,7 @@ static void find_keepcap_word(slang_T *slang, char *fword, char *kword) static void score_comp_sal(suginfo_T *su) { langp_T *lp; - char_u badsound[MAXWLEN]; - int i; + char badsound[MAXWLEN]; suggest_T *stp; suggest_T *sstp; int score; @@ -2525,9 +2502,9 @@ static void score_comp_sal(suginfo_T *su) lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); if (!GA_EMPTY(&lp->lp_slang->sl_sal)) { // soundfold the bad word - spell_soundfold(lp->lp_slang, (char *)su->su_fbadword, true, (char *)badsound); + spell_soundfold(lp->lp_slang, su->su_fbadword, true, badsound); - for (i = 0; i < su->su_ga.ga_len; i++) { + for (int i = 0; i < su->su_ga.ga_len; i++) { stp = &SUG(su->su_ga, i); // Case-fold the suggested word, sound-fold it and compute the @@ -2568,11 +2545,11 @@ static void score_combine(suginfo_T *su) if (!GA_EMPTY(&lp->lp_slang->sl_sal)) { // soundfold the bad word slang = lp->lp_slang; - spell_soundfold(slang, (char *)su->su_fbadword, true, badsound); + spell_soundfold(slang, su->su_fbadword, true, badsound); for (int i = 0; i < su->su_ga.ga_len; i++) { stp = &SUG(su->su_ga, i); - stp->st_altscore = stp_sal_score(stp, su, slang, (char_u *)badsound); + stp->st_altscore = stp_sal_score(stp, su, slang, badsound); if (stp->st_altscore == SCORE_MAXMAX) { stp->st_score = (stp->st_score * 3 + SCORE_BIG) / 4; } else { @@ -2593,7 +2570,7 @@ static void score_combine(suginfo_T *su) // Add the alternate score to su_sga. for (int i = 0; i < su->su_sga.ga_len; i++) { stp = &SUG(su->su_sga, i); - stp->st_altscore = spell_edit_score(slang, (char_u *)su->su_badword, (char_u *)stp->st_word); + stp->st_altscore = spell_edit_score(slang, su->su_badword, stp->st_word); if (stp->st_score == SCORE_MAXMAX) { stp->st_score = (SCORE_BIG * 7 + stp->st_altscore) / 8; } else { @@ -2654,23 +2631,21 @@ static void score_combine(suginfo_T *su) /// badword. /// /// @param badsound sound-folded badword -static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *badsound) +static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char *badsound) { - char_u *p; - char_u *pbad; - char_u *pgood; - char_u badsound2[MAXWLEN]; - char_u fword[MAXWLEN]; - char_u goodsound[MAXWLEN]; + char *pbad; + char *pgood; + char badsound2[MAXWLEN]; + char fword[MAXWLEN]; + char goodsound[MAXWLEN]; char goodword[MAXWLEN]; - int lendiff; - lendiff = su->su_badlen - stp->st_orglen; + int lendiff = su->su_badlen - stp->st_orglen; if (lendiff >= 0) { pbad = badsound; } else { // soundfold the bad word with more characters following - (void)spell_casefold(curwin, su->su_badptr, stp->st_orglen, (char *)fword, MAXWLEN); + (void)spell_casefold(curwin, su->su_badptr, stp->st_orglen, fword, MAXWLEN); // When joining two words the sound often changes a lot. E.g., "t he" // sounds like "t h" while "the" sounds like "@". Avoid that by @@ -2678,12 +2653,12 @@ static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u * // space. if (ascii_iswhite(su->su_badptr[su->su_badlen]) && *skiptowhite(stp->st_word) == NUL) { - for (p = fword; *(p = (char_u *)skiptowhite((char *)p)) != NUL;) { - STRMOVE(p, (char *)p + 1); + for (char *p = fword; *(p = skiptowhite(p)) != NUL;) { + STRMOVE(p, p + 1); } } - spell_soundfold(slang, (char *)fword, true, (char *)badsound2); + spell_soundfold(slang, fword, true, badsound2); pbad = badsound2; } @@ -2693,15 +2668,15 @@ static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u * STRCPY(goodword, stp->st_word); xstrlcpy(goodword + stp->st_wordlen, su->su_badptr + su->su_badlen - lendiff, (size_t)lendiff + 1); - pgood = (char_u *)goodword; + pgood = goodword; } else { - pgood = (char_u *)stp->st_word; + pgood = stp->st_word; } // Sound-fold the word and compute the score for the difference. - spell_soundfold(slang, (char *)pgood, false, (char *)goodsound); + spell_soundfold(slang, pgood, false, goodsound); - return soundalike_score((char *)goodsound, (char *)pbad); + return soundalike_score(goodsound, pbad); } /// structure used to store soundfolded words that add_sound_suggest() has @@ -2737,7 +2712,7 @@ static void suggest_try_soundalike_prep(void) /// Note: This doesn't support postponed prefixes. static void suggest_try_soundalike(suginfo_T *su) { - char_u salword[MAXWLEN]; + char salword[MAXWLEN]; langp_T *lp; slang_T *slang; @@ -2748,7 +2723,7 @@ static void suggest_try_soundalike(suginfo_T *su) slang = lp->lp_slang; if (!GA_EMPTY(&slang->sl_sal) && slang->sl_sbyts != NULL) { // soundfold the bad word - spell_soundfold(slang, (char *)su->su_fbadword, true, (char *)salword); + spell_soundfold(slang, su->su_fbadword, true, salword); // try all kinds of inserts/deletes/swaps/etc. // TODO(vim): also soundfold the next words, so that we can try joining @@ -2756,7 +2731,7 @@ static void suggest_try_soundalike(suginfo_T *su) #ifdef SUGGEST_PROFILE prof_init(); #endif - suggest_trie_walk(su, lp, (char *)salword, true); + suggest_trie_walk(su, lp, salword, true); #ifdef SUGGEST_PROFILE prof_report("soundalike"); #endif @@ -2801,10 +2776,7 @@ static void suggest_try_soundalike_finish(void) static void add_sound_suggest(suginfo_T *su, char *goodword, int score, langp_T *lp) { slang_T *slang = lp->lp_slang; // language for sound folding - int sfwordnr; - char_u *nrline; - int orgnr; - char_u theword[MAXWLEN]; + char theword[MAXWLEN]; int i; int wlen; char_u *byts; @@ -2813,8 +2785,6 @@ static void add_sound_suggest(suginfo_T *su, char *goodword, int score, langp_T int wordcount; int wc; int goodscore; - hash_T hash; - hashitem_T *hi; sftword_T *sft; int bc, gc; int limit; @@ -2823,10 +2793,9 @@ static void add_sound_suggest(suginfo_T *su, char *goodword, int score, langp_T // times with different scores. Since the following is quite slow only do // the words that have a better score than before. Use a hashtable to // remember the words that have been done. - hash = hash_hash(goodword); + hash_T hash = hash_hash(goodword); const size_t goodword_len = strlen(goodword); - hi = hash_lookup(&slang->sl_sounddone, (const char *)goodword, goodword_len, - hash); + hashitem_T *hi = hash_lookup(&slang->sl_sounddone, (const char *)goodword, goodword_len, hash); if (HASHITEM_EMPTY(hi)) { sft = xmalloc(offsetof(sftword_T, sft_word) + goodword_len + 1); sft->sft_score = (int16_t)score; @@ -2841,15 +2810,15 @@ static void add_sound_suggest(suginfo_T *su, char *goodword, int score, langp_T } // Find the word nr in the soundfold tree. - sfwordnr = soundfold_find(slang, (char_u *)goodword); + int sfwordnr = soundfold_find(slang, goodword); if (sfwordnr < 0) { internal_error("add_sound_suggest()"); return; } // Go over the list of good words that produce this soundfold word - nrline = (char_u *)ml_get_buf(slang->sl_sugbuf, (linenr_T)sfwordnr + 1, false); - orgnr = 0; + char *nrline = ml_get_buf(slang->sl_sugbuf, (linenr_T)sfwordnr + 1, false); + int orgnr = 0; while (*nrline != NUL) { // The wordnr was stored in a minimal nr of bytes as an offset to the // previous wordnr. @@ -2888,7 +2857,7 @@ static void add_sound_suggest(suginfo_T *su, char *goodword, int score, langp_T wordcount += wc; } - theword[wlen] = byts[n + i]; + theword[wlen] = (char)byts[n + i]; n = idxs[n + i]; } badword: @@ -2896,8 +2865,8 @@ badword: // Go over the possible flags and regions. for (; i <= byts[n] && byts[n + i] == NUL; i++) { - char_u cword[MAXWLEN]; - char_u *p; + char cword[MAXWLEN]; + char *p; int flags = (int)idxs[n + i]; // Skip words with the NOSUGGEST flag @@ -2907,13 +2876,13 @@ badword: if (flags & WF_KEEPCAP) { // Must find the word in the keep-case tree. - find_keepcap_word(slang, (char *)theword, (char *)cword); + find_keepcap_word(slang, theword, cword); p = cword; } else { flags |= su->su_badflags; if ((flags & WF_CAPMASK) != 0) { // Need to fix case according to "flags". - make_case_word((char *)theword, (char *)cword, flags); + make_case_word(theword, cword, flags); p = cword; } else { p = theword; @@ -2924,7 +2893,7 @@ badword: if (sps_flags & SPS_DOUBLE) { // Add the suggestion if the score isn't too bad. if (score <= su->su_maxscore) { - add_suggestion(su, &su->su_sga, (char *)p, su->su_badlen, + add_suggestion(su, &su->su_sga, p, su->su_badlen, score, 0, false, slang, false); } } else { @@ -2940,9 +2909,9 @@ badword: // lower to upper case. Helps for "tath" -> "Kath", which is // less common than "tath" -> "path". Don't do it when the // letter is the same, that has already been counted. - gc = utf_ptr2char((char *)p); + gc = utf_ptr2char(p); if (SPELL_ISUPPER(gc)) { - bc = utf_ptr2char((char *)su->su_badword); + bc = utf_ptr2char(su->su_badword); if (!SPELL_ISUPPER(bc) && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc)) { goodscore += SCORE_ICASE / 2; @@ -2958,10 +2927,9 @@ badword: // inefficient, using an array is quicker. limit = MAXSCORE(su->su_sfmaxscore - goodscore, score); if (limit > SCORE_LIMITMAX) { - goodscore += spell_edit_score(slang, (char_u *)su->su_badword, p); + goodscore += spell_edit_score(slang, su->su_badword, p); } else { - goodscore += spell_edit_score_limit(slang, (char_u *)su->su_badword, - p, limit); + goodscore += spell_edit_score_limit(slang, su->su_badword, p, limit); } // When going over the limit don't bother to do the rest. @@ -2972,7 +2940,7 @@ badword: // Add the suggestion if the score isn't too bad. goodscore = RESCORE(goodscore, score); if (goodscore <= su->su_sfmaxscore) { - add_suggestion(su, &su->su_ga, (char *)p, su->su_badlen, + add_suggestion(su, &su->su_ga, p, su->su_badlen, goodscore, score, true, slang, true); } } @@ -2982,27 +2950,23 @@ badword: } /// Find word "word" in fold-case tree for "slang" and return the word number. -static int soundfold_find(slang_T *slang, char_u *word) +static int soundfold_find(slang_T *slang, char *word) { idx_T arridx = 0; - int len; int wlen = 0; - int c; - char_u *ptr = word; - char_u *byts; - idx_T *idxs; + char_u *ptr = (char_u *)word; int wordnr = 0; - byts = (char_u *)slang->sl_sbyts; - idxs = slang->sl_sidxs; + char_u *byts = (char_u *)slang->sl_sbyts; + idx_T *idxs = slang->sl_sidxs; for (;;) { // First byte is the number of possible bytes. - len = byts[arridx++]; + int len = byts[arridx++]; // If the first possible byte is a zero the word could end here. // If the word ends we found the word. If not skip the NUL bytes. - c = ptr[wlen]; + int c = ptr[wlen]; if (byts[arridx] == NUL) { if (c == NUL) { break; @@ -3065,7 +3029,7 @@ static bool similar_chars(slang_T *slang, int c1, int c2) hashitem_T *hi; if (c1 >= 256) { - buf[utf_char2bytes(c1, (char *)buf)] = 0; + buf[utf_char2bytes(c1, buf)] = 0; hi = hash_find(&slang->sl_map_hash, buf); if (HASHITEM_EMPTY(hi)) { m1 = 0; @@ -3080,7 +3044,7 @@ static bool similar_chars(slang_T *slang, int c1, int c2) } if (c2 >= 256) { - buf[utf_char2bytes(c2, (char *)buf)] = 0; + buf[utf_char2bytes(c2, buf)] = 0; hi = hash_find(&slang->sl_map_hash, buf); if (HASHITEM_EMPTY(hi)) { m2 = 0; @@ -3213,19 +3177,17 @@ static void add_suggestion(suginfo_T *su, garray_T *gap, const char *goodword, i /// @param gap either su_ga or su_sga static void check_suggestions(suginfo_T *su, garray_T *gap) { - suggest_T *stp; char longword[MAXWLEN + 1]; - int len; hlf_T attr; if (gap->ga_len == 0) { return; } - stp = &SUG(*gap, 0); + suggest_T *stp = &SUG(*gap, 0); for (int i = gap->ga_len - 1; i >= 0; i--) { // Need to append what follows to check for "the the". xstrlcpy(longword, stp[i].st_word, MAXWLEN + 1); - len = stp[i].st_wordlen; + int len = stp[i].st_wordlen; xstrlcpy(longword + len, su->su_badptr + stp[i].st_orglen, (size_t)(MAXWLEN - len + 1)); attr = HLF_COUNT; @@ -3244,18 +3206,14 @@ static void check_suggestions(suginfo_T *su, garray_T *gap) /// Add a word to be banned. static void add_banned(suginfo_T *su, char *word) { - char_u *s; - hash_T hash; - hashitem_T *hi; - - hash = hash_hash(word); + hash_T hash = hash_hash(word); const size_t word_len = strlen(word); - hi = hash_lookup(&su->su_banned, word, word_len, hash); + hashitem_T *hi = hash_lookup(&su->su_banned, word, word_len, hash); if (!HASHITEM_EMPTY(hi)) { // already present return; } - s = xmemdupz(word, word_len); - hash_add_item(&su->su_banned, hi, (char *)s, hash); + char *s = xmemdupz(word, word_len); + hash_add_item(&su->su_banned, hi, s, hash); } /// Recompute the score for all suggestions if sound-folding is possible. This @@ -3273,20 +3231,20 @@ static void rescore_suggestions(suginfo_T *su) static void rescore_one(suginfo_T *su, suggest_T *stp) { slang_T *slang = stp->st_slang; - char_u sal_badword[MAXWLEN]; - char_u *p; + char sal_badword[MAXWLEN]; // Only rescore suggestions that have no sal score yet and do have a // language. if (slang != NULL && !GA_EMPTY(&slang->sl_sal) && !stp->st_had_bonus) { + char_u *p; if (slang == su->su_sallang) { - p = su->su_sal_badword; + p = (char_u *)su->su_sal_badword; } else { - spell_soundfold(slang, (char *)su->su_fbadword, true, (char *)sal_badword); - p = sal_badword; + spell_soundfold(slang, su->su_fbadword, true, sal_badword); + p = (char_u *)sal_badword; } - stp->st_altscore = stp_sal_score(stp, su, slang, p); + stp->st_altscore = stp_sal_score(stp, su, slang, (char *)p); if (stp->st_altscore == SCORE_MAXMAX) { stp->st_altscore = SCORE_BIG; } @@ -3355,9 +3313,6 @@ static int soundalike_score(char *goodstart, char *badstart) { char *goodsound = goodstart; char *badsound = badstart; - int goodlen; - int badlen; - int n; char *pl, *ps; char *pl2, *ps2; int score = 0; @@ -3390,12 +3345,12 @@ static int soundalike_score(char *goodstart, char *badstart) } } - goodlen = (int)strlen(goodsound); - badlen = (int)strlen(badsound); + int goodlen = (int)strlen(goodsound); + int badlen = (int)strlen(badsound); // Return quickly if the lengths are too different to be fixed by two // changes. - n = goodlen - badlen; + int n = goodlen - badlen; if (n < -2 || n > 2) { return SCORE_MAXMAX; } @@ -3575,7 +3530,7 @@ static int soundalike_score(char *goodstart, char *badstart) /// The implementation of the algorithm comes from Aspell editdist.cpp, /// edit_distance(). It has been converted from C++ to C and modified to /// support multi-byte characters. -static int spell_edit_score(slang_T *slang, const char_u *badword, const char_u *goodword) +static int spell_edit_score(slang_T *slang, const char *badword, const char *goodword) { int *cnt; int j, i; @@ -3592,12 +3547,12 @@ static int spell_edit_score(slang_T *slang, const char_u *badword, const char_u // Get the characters from the multi-byte strings and put them in an // int array for easy access. badlen = 0; - for (const char *p = (char *)badword; *p != NUL;) { + for (const char *p = badword; *p != NUL;) { wbadword[badlen++] = mb_cptr2char_adv(&p); } wbadword[badlen++] = 0; goodlen = 0; - for (const char *p = (char *)goodword; *p != NUL;) { + for (const char *p = goodword; *p != NUL;) { wgoodword[goodlen++] = mb_cptr2char_adv(&p); } wgoodword[goodlen++] = 0; @@ -3673,37 +3628,33 @@ typedef struct { /// This uses a stack for the edits still to be tried. /// The idea comes from Aspell leditdist.cpp. Rewritten in C and added support /// for multi-byte characters. -static int spell_edit_score_limit(slang_T *slang, char_u *badword, char_u *goodword, int limit) +static int spell_edit_score_limit(slang_T *slang, char *badword, char *goodword, int limit) { return spell_edit_score_limit_w(slang, badword, goodword, limit); } /// Multi-byte version of spell_edit_score_limit(). /// Keep it in sync with the above! -static int spell_edit_score_limit_w(slang_T *slang, const char_u *badword, const char_u *goodword, +static int spell_edit_score_limit_w(slang_T *slang, const char *badword, const char *goodword, int limit) { limitscore_T stack[10]; // allow for over 3 * 2 edits - int stackidx; - int bi, gi; int bi2, gi2; int bc, gc; - int score; int score_off; - int minscore; int round; int wbadword[MAXWLEN]; int wgoodword[MAXWLEN]; // Get the characters from the multi-byte strings and put them in an // int array for easy access. - bi = 0; - for (const char *p = (char *)badword; *p != NUL;) { + int bi = 0; + for (const char *p = badword; *p != NUL;) { wbadword[bi++] = mb_cptr2char_adv(&p); } wbadword[bi++] = 0; - gi = 0; - for (const char *p = (char *)goodword; *p != NUL;) { + int gi = 0; + for (const char *p = goodword; *p != NUL;) { wgoodword[gi++] = mb_cptr2char_adv(&p); } wgoodword[gi++] = 0; @@ -3715,11 +3666,11 @@ static int spell_edit_score_limit_w(slang_T *slang, const char_u *badword, const // pushed unto a stack and tried later, some are tried right away. At the // end of the word the score for one alternative is known. The lowest // possible score is stored in "minscore". - stackidx = 0; + int stackidx = 0; bi = 0; gi = 0; - score = 0; - minscore = limit + 1; + int score = 0; + int minscore = limit + 1; for (;;) { // Skip over an equal part, score remains the same. diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 6ad1f31143..de91bf334c 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -1,6 +1,5 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -// #include <assert.h> #include <inttypes.h> @@ -38,7 +37,7 @@ #include "nvim/path.h" #include "nvim/pos.h" #include "nvim/screen.h" -#include "nvim/sign_defs.h" +#include "nvim/sign.h" #include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/types.h" @@ -153,8 +152,8 @@ void win_redr_status(win_T *wp) row = is_stl_global ? (Rows - (int)p_ch - 1) : W_ENDROW(wp); col = is_stl_global ? 0 : wp->w_wincol; - grid_puts(&default_grid, p, row, col, attr); - grid_fill(&default_grid, row, row + 1, len + col, + int width = grid_puts(&default_grid, p, row, col, attr); + grid_fill(&default_grid, row, row + 1, width + col, this_ru_col + col, fillchar, fillchar, attr); if (get_keymap_str(wp, "<%s>", NameBuff, MAXPATHL) @@ -261,23 +260,18 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) { static bool entered = false; int attr; - int curattr; int row; int col = 0; int maxwidth; - int width; int n; - int len; int fillchar; char buf[MAXPATHL]; + char transbuf[MAXPATHL]; char *stl; - char *p; char *opt_name; int opt_scope = 0; stl_hlrec_t *hltab; StlClickRecord *tabtab; - win_T *ewp; - int p_crb_save; bool is_stl_global = global_stl_height() > 0; ScreenGrid *grid = &default_grid; @@ -370,41 +364,32 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) // Temporarily reset 'cursorbind', we don't want a side effect from moving // the cursor away and back. - ewp = wp == NULL ? curwin : wp; - p_crb_save = ewp->w_p_crb; + win_T *ewp = wp == NULL ? curwin : wp; + int p_crb_save = ewp->w_p_crb; ewp->w_p_crb = false; // Make a copy, because the statusline may include a function call that // might change the option value and free the memory. stl = xstrdup(stl); - width = build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_name, opt_scope, - fillchar, maxwidth, &hltab, &tabtab, NULL); + build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_name, opt_scope, + fillchar, maxwidth, &hltab, &tabtab, NULL); xfree(stl); ewp->w_p_crb = p_crb_save; - // Make all characters printable. - p = transstr(buf, true); - len = (int)xstrlcpy(buf, p, sizeof(buf)); - len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1; - xfree(p); - - // fill up with "fillchar" - while (width < maxwidth && len < (int)sizeof(buf) - 1) { - len += utf_char2bytes(fillchar, buf + len); - width++; - } - buf[len] = NUL; + int len = (int)strlen(buf); + int start_col = col; // Draw each snippet with the specified highlighting. grid_puts_line_start(grid, row); - curattr = attr; - p = buf; + int curattr = attr; + char *p = buf; for (n = 0; hltab[n].start != NULL; n++) { int textlen = (int)(hltab[n].start - p); - grid_puts_len(grid, p, textlen, row, col, curattr); - col += vim_strnsize(p, textlen); + // Make all characters printable. + size_t tsize = transstr_buf(p, textlen, transbuf, sizeof transbuf, true); + col += grid_puts_len(grid, transbuf, (int)tsize, row, col, curattr); p = hltab[n].start; if (hltab[n].userhl == 0) { @@ -418,7 +403,12 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) } } // Make sure to use an empty string instead of p, if p is beyond buf + len. - grid_puts(grid, p >= buf + len ? "" : p, row, col, curattr); + size_t tsize = transstr_buf(p >= buf + len ? "" : p, -1, transbuf, sizeof transbuf, true); + col += grid_puts_len(grid, transbuf, (int)tsize, row, col, curattr); + int maxcol = start_col + maxwidth; + + // fill up with "fillchar" + grid_fill(grid, row, row + 1, col, maxcol, fillchar, fillchar, curattr); grid_puts_line_flush(false); @@ -583,7 +573,7 @@ void win_redr_ruler(win_T *wp, bool always) MAXSIZE_TEMP_ARRAY(content, 1); MAXSIZE_TEMP_ARRAY(chunk, 2); ADD_C(chunk, INTEGER_OBJ(attr)); - ADD_C(chunk, STRING_OBJ(cstr_as_string((char *)buffer))); + ADD_C(chunk, STRING_OBJ(cstr_as_string(buffer))); ADD_C(content, ARRAY_OBJ(chunk)); ui_call_msg_ruler(content); did_show_ext_ruler = true; @@ -710,21 +700,9 @@ static void ui_ext_tabline_update(void) /// Draw the tab pages line at the top of the Vim window. void draw_tabline(void) { - int tabcount = 0; - int tabwidth = 0; - int col = 0; - int scol = 0; - int attr; win_T *wp; - win_T *cwp; - int wincount; - int modified; - int c; - int len; int attr_nosel = HL_ATTR(HLF_TP); int attr_fill = HL_ATTR(HLF_TPF); - char *p; - int room; int use_sep_chars = (t_colors < 8); if (default_grid.chars == NULL) { @@ -749,6 +727,14 @@ void draw_tabline(void) if (*p_tal != NUL) { win_redr_custom(NULL, false, false); } else { + int tabcount = 0; + int tabwidth = 0; + int col = 0; + win_T *cwp; + int wincount; + int c; + int len; + char *p; FOR_ALL_TABS(tp) { tabcount++; } @@ -761,7 +747,7 @@ void draw_tabline(void) tabwidth = 6; } - attr = attr_nosel; + int attr = attr_nosel; tabcount = 0; FOR_ALL_TABS(tp) { @@ -769,7 +755,7 @@ void draw_tabline(void) break; } - scol = col; + int scol = col; if (tp == curtab) { cwp = curwin; @@ -792,7 +778,7 @@ void draw_tabline(void) grid_putchar(&default_grid, ' ', 0, col++, attr); - modified = false; + int modified = false; for (wincount = 0; wp != NULL; wp = wp->w_next, wincount++) { if (bufIsChanged(wp->w_buffer)) { @@ -817,7 +803,7 @@ void draw_tabline(void) grid_putchar(&default_grid, ' ', 0, col++, attr); } - room = scol - col + tabwidth - 1; + int room = scol - col + tabwidth - 1; if (room > 0) { // Get buffer name in NameBuff[] get_trans_bufname(cwp->w_buffer); @@ -885,11 +871,8 @@ void draw_tabline(void) /// Build the 'statuscolumn' string for line "lnum". When "relnum" == -1, /// the v:lnum and v:relnum variables don't have to be updated. /// -/// @param hlrec HL attributes (can be NULL) -/// @param stcp Status column attributes (can be NULL) /// @return The width of the built status column string for line "lnum" -int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, int maxwidth, int fillchar, - char *buf, stl_hlrec_t **hlrec, statuscol_T *stcp) +int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, statuscol_T *stcp) { bool fillclick = relnum >= 0 && lnum == wp->w_topline; @@ -900,8 +883,8 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, int maxwidth, int StlClickRecord *clickrec; char *stc = xstrdup(wp->w_p_stc); - int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, "statuscolumn", OPT_LOCAL, fillchar, - maxwidth, hlrec, fillclick ? &clickrec : NULL, stcp); + int width = build_stl_str_hl(wp, stcp->text, MAXPATHL, stc, "statuscolumn", OPT_LOCAL, ' ', + stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp); xfree(stc); // Only update click definitions once per window per redraw @@ -909,7 +892,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, int maxwidth, int stl_clear_click_defs(wp->w_statuscol_click_defs, wp->w_statuscol_click_defs_size); wp->w_statuscol_click_defs = stl_alloc_click_defs(wp->w_statuscol_click_defs, width, &wp->w_statuscol_click_defs_size); - stl_fill_click_defs(wp->w_statuscol_click_defs, clickrec, buf, width, false); + stl_fill_click_defs(wp->w_statuscol_click_defs, clickrec, stcp->text, width, false); } return width; @@ -1095,7 +1078,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n continue; } - // STL_SEPARATE: Separation place between left and right aligned items. + // STL_SEPARATE: Separation between items, filled with white space. if (*fmt_p == STL_SEPARATE) { fmt_p++; // Ignored when we are inside of a grouping @@ -1390,7 +1373,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n NumberBase base = kNumBaseDecimal; bool itemisflag = false; bool fillable = true; - long num = -1; + int num = -1; char *str = NULL; switch (opt) { case STL_FILEPATH: @@ -1520,10 +1503,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // Overload %l with v:lnum for 'statuscolumn' if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) { if (wp->w_p_nu && !get_vim_var_nr(VV_VIRTNUM)) { - num = get_vim_var_nr(VV_LNUM); + num = (int)get_vim_var_nr(VV_LNUM); } } else { - num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? 0L : (long)(wp->w_cursor.lnum); + num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? 0L : wp->w_cursor.lnum; } break; @@ -1544,7 +1527,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n ? 0 : (int)wp->w_cursor.col + 1))) { break; } - num = (long)virtcol; + num = virtcol; break; } @@ -1604,8 +1587,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL, false); num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ? - 0L : l + 1 + ((State & MODE_INSERT) == 0 && empty_line ? - 0 : (int)wp->w_cursor.col); + 0L : (int)l + 1 + ((State & MODE_INSERT) == 0 && empty_line ? + 0 : (int)wp->w_cursor.col); break; } case STL_BYTEVAL_X: @@ -1625,7 +1608,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // Overload %r with v:relnum for 'statuscolumn' if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) { if (wp->w_p_rnu && !get_vim_var_nr(VV_VIRTNUM)) { - num = get_vim_var_nr(VV_RELNUM); + num = (int)get_vim_var_nr(VV_RELNUM); } } else { itemisflag = true; @@ -1648,20 +1631,40 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n if (stcp == NULL) { break; } - bool fold = opt == STL_FOLDCOL; + int width = fold ? (compute_foldcolumn(wp, 0) > 0) : wp->w_scwidth; + + if (width == 0) { + break; + } + + char *p; + if (fold) { + size_t n = fill_foldcolumn(out_p, wp, stcp->foldinfo, (linenr_T)get_vim_var_nr(VV_LNUM)); + stl_items[curitem].minwid = win_hl_attr(wp, stcp->use_cul ? HLF_CLF : HLF_FC); + p = out_p; + p[n] = NUL; + } + *buf_tmp = NUL; - for (int i = 0; i <= SIGN_SHOW_MAX; i++) { - char *p = fold ? stcp->fold_text : stcp->sign_text[i]; - if ((!p || !*p) && *buf_tmp == NUL) { - break; + varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM); + for (int i = 0; i <= width; i++) { + if (i == width) { + if (*buf_tmp == NUL) { + break; + } + stl_items[curitem].minwid = 0; + } else if (!fold) { + SignTextAttrs *sattr = virtnum ? NULL : sign_get_attr(i, stcp->sattrs, wp->w_scwidth); + p = sattr && sattr->text ? sattr->text : " "; + stl_items[curitem].minwid = sattr ? stcp->sign_cul_attr ? stcp->sign_cul_attr + : sattr->hl_attr_id + : win_hl_attr(wp, stcp->use_cul ? HLF_CLS : HLF_SC); } stl_items[curitem].type = Highlight; stl_items[curitem].start = out_p + strlen(buf_tmp); - stl_items[curitem].minwid = !p || (fold && i) ? 0 : fold ? stcp->fold_attr - : stcp->sign_attr[i]; curitem++; - if (!p || (fold && i)) { + if (i == width) { str = buf_tmp; break; } @@ -1889,7 +1892,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // { Reduce the number by base^n while (num_chars-- > maxwid) { - num /= (long)base; + num /= (int)base; } // } @@ -2067,8 +2070,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n int num_separators = 0; for (int i = 0; i < itemcnt; i++) { if (stl_items[i].type == Separate) { - // Create an array of the start location for each - // separator mark. + // Create an array of the start location for each separator mark. stl_separator_locations[num_separators] = i; num_separators++; } @@ -2080,17 +2082,17 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n int final_spaces = (maxwidth - width) - standard_spaces * (num_separators - 1); - for (int i = 0; i < num_separators; i++) { - int dislocation = (i == (num_separators - 1)) ? final_spaces : standard_spaces; + for (int l = 0; l < num_separators; l++) { + int dislocation = (l == (num_separators - 1)) ? final_spaces : standard_spaces; dislocation *= utf_char2len(fillchar); - char *start = stl_items[stl_separator_locations[i]].start; + char *start = stl_items[stl_separator_locations[l]].start; char *seploc = start + dislocation; STRMOVE(seploc, start); for (char *s = start; s < seploc;) { MB_CHAR2BYTES(fillchar, s); } - for (int item_idx = stl_separator_locations[i] + 1; + for (int item_idx = stl_separator_locations[l] + 1; item_idx < itemcnt; item_idx++) { stl_items[item_idx].start += dislocation; diff --git a/src/nvim/statusline_defs.h b/src/nvim/statusline_defs.h index eac9dfd690..6835d62cdd 100644 --- a/src/nvim/statusline_defs.h +++ b/src/nvim/statusline_defs.h @@ -3,7 +3,10 @@ #include <stddef.h> +#include "nvim/fold_defs.h" #include "nvim/macros.h" +#include "nvim/os/os_defs.h" +#include "nvim/sign_defs.h" /// Status line click definition typedef struct { @@ -23,4 +26,54 @@ typedef struct { const char *start; ///< Location where region starts. } StlClickRecord; +/// Used for highlighting in the status line. +typedef struct stl_hlrec stl_hlrec_t; +struct stl_hlrec { + char *start; + int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID +}; + +/// Used for building the status line. +typedef struct stl_item stl_item_t; +struct stl_item { + // Where the item starts in the status line output buffer + char *start; + // Function to run for ClickFunc items. + char *cmd; + // The minimum width of the item + int minwid; + // The maximum width of the item + int maxwid; + enum { + Normal, + Empty, + Group, + Separate, + Highlight, + TabPage, + ClickFunc, + Trunc, + } type; +}; + +/// Struct to hold info for 'statuscolumn' +typedef struct statuscol statuscol_T; + +struct statuscol { + int width; ///< width of the status column + int cur_attr; ///< current attributes in text + int num_attr; ///< attributes used for line number + int sign_cul_attr; ///< cursorline sign attr + int truncate; ///< truncated width + bool draw; ///< whether to draw the statuscolumn + bool use_cul; ///< whether to use cursorline attrs + char text[MAXPATHL]; ///< text in status column + char *textp; ///< current position in text + char *text_end; ///< end of text (the NUL byte) + stl_hlrec_t *hlrec; ///< highlight groups + stl_hlrec_t *hlrecp; ///< current highlight group + foldinfo_T foldinfo; ///< fold information + SignTextAttrs *sattrs; ///< sign attributes +}; + #endif // NVIM_STATUSLINE_DEFS_H diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 49b63ad324..d4161b9ca2 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -1218,7 +1218,6 @@ static synstate_T *store_current_state(void) // Copy a state stack from "from" in b_sst_array[] to current_state; static void load_current_state(synstate_T *from) { - int i; bufstate_T *bp; clear_current_state(); @@ -1231,7 +1230,7 @@ static void load_current_state(synstate_T *from) } else { bp = from->sst_union.sst_stack; } - for (i = 0; i < from->sst_stacksize; i++) { + for (int i = 0; i < from->sst_stacksize; i++) { CUR_STATE(i).si_idx = bp[i].bs_idx; CUR_STATE(i).si_flags = bp[i].bs_flags; CUR_STATE(i).si_seqnr = bp[i].bs_seqnr; @@ -3441,9 +3440,7 @@ static void syn_list_one(const int id, const bool syncing, const bool link_only) static void syn_list_flags(struct name_list *nlist, int flags, int attr) { - int i; - - for (i = 0; nlist[i].flag != 0; i++) { + for (int i = 0; nlist[i].flag != 0; i++) { if (flags & nlist[i].flag) { msg_puts_attr(nlist[i].name, attr); msg_putchar(' '); @@ -4736,17 +4733,15 @@ static void init_syn_patterns(void) /// @return a pointer to the next argument, or NULL in case of an error. static char *get_syn_pattern(char *arg, synpat_T *ci) { - char *end; int *p; int idx; - char *cpo_save; // need at least three chars if (arg == NULL || arg[0] == NUL || arg[1] == NUL || arg[2] == NUL) { return NULL; } - end = skip_regexp(arg + 1, *arg, true); + char *end = skip_regexp(arg + 1, *arg, true); if (*end != *arg) { // end delimiter not found semsg(_("E401: Pattern delimiter not found: %s"), arg); return NULL; @@ -4755,7 +4750,7 @@ static char *get_syn_pattern(char *arg, synpat_T *ci) ci->sp_pattern = xstrnsave(arg + 1, (size_t)(end - arg) - 1); // Make 'cpoptions' empty, to avoid the 'l' flag - cpo_save = p_cpo; + char *cpo_save = p_cpo; p_cpo = empty_option; ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC); p_cpo = cpo_save; @@ -5145,7 +5140,6 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in { int retval; int16_t *scl_list; - int16_t item; int16_t id = ssp->id; static int depth = 0; int r; @@ -5181,7 +5175,7 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in // If the first item is "ALLBUT", return true if "id" is NOT in the // contains list. We also require that "id" is at the same ":syn include" // level as the list. - item = *list; + int16_t item = *list; if (item >= SYNID_ALLBUT && item < SYNID_CLUSTER) { if (item < SYNID_TOP) { // ALL or ALLBUT: accept all groups in the same file @@ -5291,9 +5285,6 @@ void ex_syntax(exarg_T *eap) void ex_ownsyntax(exarg_T *eap) { - char *old_value; - char *new_value; - if (curwin->w_s == &curwin->w_buffer->b_s) { curwin->w_s = xcalloc(1, sizeof(synblock_T)); hash_init(&curwin->w_s->b_keywtab); @@ -5309,7 +5300,7 @@ void ex_ownsyntax(exarg_T *eap) } // Save value of b:current_syntax. - old_value = get_var_value("b:current_syntax"); + char *old_value = get_var_value("b:current_syntax"); if (old_value != NULL) { old_value = xstrdup(old_value); } @@ -5318,7 +5309,7 @@ void ex_ownsyntax(exarg_T *eap) apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, true, curbuf); // Move value of b:current_syntax to w:current_syntax. - new_value = get_var_value("b:current_syntax"); + char *new_value = get_var_value("b:current_syntax"); if (new_value != NULL) { set_internal_string_var("w:current_syntax", new_value); } @@ -5483,10 +5474,9 @@ int get_syntax_info(int *seqnrp) int syn_get_concealed_id(win_T *wp, linenr_T lnum, colnr_T col) { int seqnr; - int syntax_flags; (void)syn_get_id(wp, lnum, col, false, NULL, false); - syntax_flags = get_syntax_info(&seqnr); + int syntax_flags = get_syntax_info(&seqnr); if (syntax_flags & HL_CONCEAL) { return seqnr; diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 42618e8924..774157831d 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -795,7 +795,6 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char { taggy_T *tagstack = curwin->w_tagstack; int tagstackidx = curwin->w_tagstackidx; - int i; char *p; char *command_end; tagptrs_T tagp; @@ -821,7 +820,7 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char taglen_advance(taglen); msg_puts_attr(_("file\n"), HL_ATTR(HLF_T)); - for (i = 0; i < num_matches && !got_int; i++) { + for (int i = 0; i < num_matches && !got_int; i++) { parse_match(matches[i], &tagp); if (!new_tag && ( (g_do_tagpreview != 0 @@ -979,27 +978,21 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char /// window. static int add_llist_tags(char *tag, int num_matches, char **matches) { - list_T *list; char tag_name[128 + 1]; - char *fname; - char *cmd; - int i; char *p; tagptrs_T tagp; - fname = xmalloc(MAXPATHL + 1); - cmd = xmalloc(CMDBUFFSIZE + 1); - list = tv_list_alloc(0); + char *fname = xmalloc(MAXPATHL + 1); + char *cmd = xmalloc(CMDBUFFSIZE + 1); + list_T *list = tv_list_alloc(0); - for (i = 0; i < num_matches; i++) { - int len, cmd_len; - long lnum; + for (int i = 0; i < num_matches; i++) { dict_T *dict; parse_match(matches[i], &tagp); // Save the tag name - len = (int)(tagp.tagname_end - tagp.tagname); + int len = (int)(tagp.tagname_end - tagp.tagname); if (len > 128) { len = 128; } @@ -1016,7 +1009,7 @@ static int add_llist_tags(char *tag, int num_matches, char **matches) // Get the line number or the search pattern used to locate // the tag. - lnum = 0; + long lnum = 0; if (isdigit((uint8_t)(*tagp.command))) { // Line number is used to locate the tag lnum = atol(tagp.command); @@ -1065,7 +1058,7 @@ static int add_llist_tags(char *tag, int num_matches, char **matches) STRCAT(cmd, "\\V"); len += 2; - cmd_len = (int)(cmd_end - cmd_start + 1); + int cmd_len = (int)(cmd_end - cmd_start + 1); if (cmd_len > (CMDBUFFSIZE - 5)) { cmd_len = CMDBUFFSIZE - 5; } @@ -1124,7 +1117,6 @@ static void taglen_advance(int l) // Print the tag stack void do_tags(exarg_T *eap) { - int i; char *name; taggy_T *tagstack = curwin->w_tagstack; int tagstackidx = curwin->w_tagstackidx; @@ -1132,7 +1124,7 @@ void do_tags(exarg_T *eap) // Highlight title msg_puts_title(_("\n # TO tag FROM line in file/text")); - for (i = 0; i < tagstacklen; i++) { + for (int i = 0; i < tagstacklen; i++) { if (tagstack[i].tagname != NULL) { name = fm_getname(&(tagstack[i].fmark), 30); if (name == NULL) { // file name not available @@ -1162,10 +1154,8 @@ void do_tags(exarg_T *eap) // Make sure case is folded to uppercase in comparison (like for 'sort -f') static int tag_strnicmp(char *s1, char *s2, size_t len) { - int i; - while (len > 0) { - i = TOUPPER_ASC((uint8_t)(*s1)) - TOUPPER_ASC((uint8_t)(*s2)); + int i = TOUPPER_ASC((uint8_t)(*s1)) - TOUPPER_ASC((uint8_t)(*s2)); if (i != 0) { return i; // this character different } @@ -1733,9 +1723,6 @@ static tagmatch_status_T findtags_parse_line(findtags_state_T *st, tagptrs_T *ta tagsearch_info_T *sinfo_p) { int status; - int i; - int cmplen; - int tagcmp; // Figure out where the different strings are in this line. // For "normal" tags: Do a quick check if the tag matches. @@ -1751,7 +1738,7 @@ static tagmatch_status_T findtags_parse_line(findtags_state_T *st, tagptrs_T *ta // Skip this line if the length of the tag is different and // there is no regexp, or the tag is too short. - cmplen = (int)(tagpp->tagname_end - tagpp->tagname); + int cmplen = (int)(tagpp->tagname_end - tagpp->tagname); if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength' cmplen = (int)p_tl; } @@ -1762,8 +1749,9 @@ static tagmatch_status_T findtags_parse_line(findtags_state_T *st, tagptrs_T *ta } if (st->state == TS_BINARY) { + int tagcmp; // Simplistic check for unsorted tags file. - i = (int)tagpp->tagname[0]; + int i = (int)tagpp->tagname[0]; if (margs->sortic) { i = TOUPPER_ASC(tagpp->tagname[0]); } @@ -2253,7 +2241,6 @@ static int findtags_copy_matches(findtags_state_T *st, char ***matchesp) const bool name_only = (st->flags & TAG_NAMES); char **matches; int mtt; - int i; char *mfp; char *p; @@ -2264,7 +2251,7 @@ static int findtags_copy_matches(findtags_state_T *st, char ***matchesp) } st->match_count = 0; for (mtt = 0; mtt < MT_COUNT; mtt++) { - for (i = 0; i < st->ga_match[mtt].ga_len; i++) { + for (int i = 0; i < st->ga_match[mtt].ga_len; i++) { mfp = ((char **)(st->ga_match[mtt].ga_data))[i]; if (matches == NULL) { xfree(mfp); @@ -2719,7 +2706,7 @@ static int parse_match(char *lbuf, tagptrs_T *tagp) { int retval; char *p; - char *pc, *pt; + char *pt; tagp->tag_fname = lbuf + 1; lbuf += strlen(tagp->tag_fname) + 2; @@ -2759,7 +2746,7 @@ static int parse_match(char *lbuf, tagptrs_T *tagp) break; } - pc = vim_strchr(p, ':'); + char *pc = vim_strchr(p, ':'); pt = vim_strchr(p, '\t'); if (pc == NULL || (pt != NULL && pc > pt)) { tagp->tagkind = p; @@ -2995,7 +2982,6 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, int keep_help) retval = OK; } else { int found = 1; - char cc; // try again, ignore case now p_ic = true; @@ -3004,7 +2990,7 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, int keep_help) // Failed to find pattern, take a guess: "^func (" found = 2; (void)test_for_static(&tagp); - cc = *tagp.tagname_end; + char cc = *tagp.tagname_end; *tagp.tagname_end = NUL; snprintf(pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname); if (!do_search(NULL, '/', '/', pbuf, (long)1, search_options, NULL)) { @@ -3155,10 +3141,10 @@ static char *expand_tag_fname(char *fname, char *const tag_fname, const bool exp /// file. static int test_for_current(char *fname, char *fname_end, char *tag_fname, char *buf_ffname) { - char c; int retval = false; if (buf_ffname != NULL) { // if the buffer has a name + char c; { c = *fname_end; *fname_end = NUL; @@ -3225,7 +3211,6 @@ static void tagstack_clear_entry(taggy_T *item) /// @param tagnames expand tag names int expand_tags(int tagnames, char *pat, int *num_file, char ***file) { - int i; int extra_flag; char *name_buf; size_t name_buf_size = 100; @@ -3251,7 +3236,7 @@ int expand_tags(int tagnames, char *pat, int *num_file, char ***file) if (ret == OK && !tagnames) { // Reorganize the tags for display and matching as strings of: // "<tagname>\0<kind>\0<filename>\0" - for (i = 0; i < *num_file; i++) { + for (int i = 0; i < *num_file; i++) { size_t len; parse_match((*file)[i], &t_p); @@ -3327,7 +3312,6 @@ int get_tags(list_T *list, char *pat, char *buf_fname) char *full_fname; dict_T *dict; tagptrs_T tp; - bool is_static; ret = find_tags(pat, &num_matches, &matches, TAG_REGEXP | TAG_NOIC, MAXCOL, buf_fname); @@ -3342,7 +3326,7 @@ int get_tags(list_T *list, char *pat, char *buf_fname) (void)parse_result; assert(parse_result == OK); - is_static = test_for_static(&tp); + bool is_static = test_for_static(&tp); // Skip pseudo-tag lines. if (strncmp(tp.tagname, "!_TAG_", 6) == 0) { @@ -3377,7 +3361,7 @@ int get_tags(list_T *list, char *pat, char *buf_fname) // skip "file:" (static tag) p += 4; } else if (!ascii_iswhite(*p)) { - char *s, *n; + char *n; int len; // Add extra field as a dict entry. Fields are @@ -3388,7 +3372,7 @@ int get_tags(list_T *list, char *pat, char *buf_fname) } len = (int)(p - n); if (*p == ':' && len > 0) { - s = ++p; + char *s = ++p; while (*p != NUL && (uint8_t)(*p) >= ' ') { p++; } @@ -3445,17 +3429,13 @@ static void get_tag_details(taggy_T *tag, dict_T *retdict) // 'retdict'. void get_tagstack(win_T *wp, dict_T *retdict) { - list_T *l; - int i; - dict_T *d; - tv_dict_add_nr(retdict, S_LEN("length"), wp->w_tagstacklen); tv_dict_add_nr(retdict, S_LEN("curidx"), wp->w_tagstackidx + 1); - l = tv_list_alloc(2); + list_T *l = tv_list_alloc(2); tv_dict_add_list(retdict, S_LEN("items"), l); - for (i = 0; i < wp->w_tagstacklen; i++) { - d = tv_dict_alloc(); + for (int i = 0; i < wp->w_tagstacklen; i++) { + dict_T *d = tv_dict_alloc(); tv_list_append_dict(l, d); get_tag_details(&wp->w_tagstack[i], d); } diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index a1a3ba3198..30d30c8b29 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1897,17 +1897,15 @@ func Test_Cmdline() call assert_equal(':', g:entered) au! CmdlineChanged + autocmd CmdlineChanged : let g:log += [getcmdline()] + let g:log = [] cnoremap <F1> <Cmd>call setcmdline('ls')<CR> - autocmd CmdlineChanged : let g:log += [getcmdline()] call feedkeys(":\<F1>", 'xt') call assert_equal(['ls'], g:log) - unlet g:log - au! CmdlineChanged cunmap <F1> let g:log = [] - autocmd CmdlineChanged : let g:log += [getcmdline()] call feedkeys(":sign \<Tab>\<Tab>\<C-N>\<C-P>\<S-Tab>\<S-Tab>\<Esc>", 'xt') call assert_equal([ \ 's', @@ -1938,6 +1936,22 @@ func Test_Cmdline() \ 'sign unplace', \ ], g:log) set wildmenu& wildoptions& + + let g:log = [] + let @r = 'abc' + call feedkeys(":0\<C-R>r1\<C-R>\<C-O>r2\<C-R>\<C-R>r3\<Esc>", 'xt') + call assert_equal([ + \ '0', + \ '0a', + \ '0ab', + \ '0abc', + \ '0abc1', + \ '0abc1abc', + \ '0abc1abc2', + \ '0abc1abc2abc', + \ '0abc1abc2abc3', + \ ], g:log) + unlet g:log au! CmdlineChanged diff --git a/src/nvim/testdir/test_hlsearch.vim b/src/nvim/testdir/test_hlsearch.vim index cf2791113a..043d378a39 100644 --- a/src/nvim/testdir/test_hlsearch.vim +++ b/src/nvim/testdir/test_hlsearch.vim @@ -1,5 +1,8 @@ " Test for v:hlsearch +source check.vim +source screendump.vim + func Test_hlsearch() new call setline(1, repeat(['aaa'], 10)) @@ -63,3 +66,23 @@ func Test_hlsearch_eol_highlight() set nohlsearch bwipe! endfunc + +func Test_hlsearch_Ctrl_R() + CheckRunVimInTerminal + + let lines =<< trim END + set incsearch hlsearch + let @" = "text" + put + END + call writefile(lines, 'XhlsearchCtrlR', 'D') + let buf = RunVimInTerminal('-S XhlsearchCtrlR', #{rows: 6, cols: 60}) + + call term_sendkeys(buf, "/\<C-R>\<C-R>\"") + call VerifyScreenDump(buf, 'Test_hlsearch_ctrlr_1', {}) + + call term_sendkeys(buf, "\<Esc>") + call StopVimInTerminal(buf) +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index f51de94bac..43cc3632e6 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -434,6 +434,8 @@ func Test_set_errors() call assert_fails('set fileencoding=latin1', 'E21:') set modifiable& " call assert_fails('set t_#-&', 'E522:') + call assert_fails('let &formatoptions = "?"', 'E539:') + call assert_fails('call setbufvar("", "&formatoptions", "?")', 'E539:') endfunc func CheckWasSet(name) @@ -1300,5 +1302,44 @@ func Test_endoffile_default() call delete('Xtestout') endfunc +" Test for setting the 'lines' and 'columns' options to a minimum value +func Test_set_min_lines_columns() + let save_lines = &lines + let save_columns = &columns + + let after =<< trim END + set laststatus=1 + set nomore + let msg = [] + let v:errmsg = '' + silent! let &columns=0 + call add(msg, v:errmsg) + silent! set columns=0 + call add(msg, v:errmsg) + silent! call setbufvar('', '&columns', 0) + call add(msg, v:errmsg) + "call writefile(msg, 'XResultsetminlines') + silent! let &lines=0 + call add(msg, v:errmsg) + silent! set lines=0 + call add(msg, v:errmsg) + silent! call setbufvar('', '&lines', 0) + call add(msg, v:errmsg) + call writefile(msg, 'XResultsetminlines') + qall! + END + if RunVim([], after, '') + call assert_equal(['E594: Need at least 12 columns', + \ 'E594: Need at least 12 columns: columns=0', + \ 'E594: Need at least 12 columns', + \ 'E593: Need at least 2 lines', + \ 'E593: Need at least 2 lines: lines=0', + \ 'E593: Need at least 2 lines',], readfile('XResultsetminlines')) + endif + + call delete('XResultsetminlines') + let &lines = save_lines + let &columns = save_columns +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_statusline.vim b/src/nvim/testdir/test_statusline.vim index 990c852ccd..1e06ad1c67 100644 --- a/src/nvim/testdir/test_statusline.vim +++ b/src/nvim/testdir/test_statusline.vim @@ -231,6 +231,10 @@ func Test_statusline() " %=: Separation point between left and right aligned items. set statusline=foo%=bar call assert_match('^foo\s\+bar\s*$', s:get_statusline()) + set statusline=foo%=bar%=baz + call assert_match('^foo\s\+bar\s\+baz\s*$', s:get_statusline()) + set statusline=foo%=bar%=baz%=qux + call assert_match('^foo\s\+bar\s\+baz\s\+qux\s*$', s:get_statusline()) " Test min/max width, leading zeroes, left/right justify. set statusline=%04B diff --git a/src/nvim/testing.c b/src/nvim/testing.c index b5921b3445..3569856f2c 100644 --- a/src/nvim/testing.c +++ b/src/nvim/testing.c @@ -395,12 +395,12 @@ static int assert_equalfile(typval_T *argvars) char line2[200]; ptrdiff_t lineidx = 0; if (fd1 == NULL) { - snprintf(IObuff, IOSIZE, (char *)e_notread, fname1); + snprintf(IObuff, IOSIZE, e_notread, fname1); } else { FILE *const fd2 = os_fopen(fname2, READBIN); if (fd2 == NULL) { fclose(fd1); - snprintf(IObuff, IOSIZE, (char *)e_notread, fname2); + snprintf(IObuff, IOSIZE, e_notread, fname2); } else { int64_t linecount = 1; for (int64_t count = 0;; count++) { diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index e30580a748..05e57e4b8f 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -72,7 +72,7 @@ bool has_format_option(int x) void internal_format(int textwidth, int second_indent, int flags, bool format_only, int c) { int cc; - int save_char = NUL; + char save_char = NUL; bool haveto_redraw = false; const bool fo_ins_blank = has_format_option(FO_INS_BLANK); const bool fo_multibyte = has_format_option(FO_MBYTE_BREAK); @@ -93,7 +93,7 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on && !(State & VREPLACE_FLAG)) { cc = gchar_cursor(); if (ascii_iswhite(cc)) { - save_char = cc; + save_char = (char)cc; pchar_cursor('x'); } } @@ -458,7 +458,7 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on } if (save_char != NUL) { // put back space after cursor - pchar_cursor((char_u)save_char); + pchar_cursor(save_char); } curwin->w_p_lbr = has_lbr; @@ -633,19 +633,16 @@ static bool paragraph_start(linenr_T lnum) /// @param prev_line may start in previous line void auto_format(bool trailblank, bool prev_line) { - pos_T pos; colnr_T len; - char *old; char *new, *pnew; - int wasatend; int cc; if (!has_format_option(FO_AUTO)) { return; } - pos = curwin->w_cursor; - old = get_cursor_line_ptr(); + pos_T pos = curwin->w_cursor; + char *old = get_cursor_line_ptr(); // may remove added space check_auto_format(false); @@ -655,7 +652,7 @@ void auto_format(bool trailblank, bool prev_line) // in 'formatoptions' and there is a single character before the cursor. // Otherwise the line would be broken and when typing another non-white // next they are not joined back together. - wasatend = (pos.col == (colnr_T)strlen(old)); + int wasatend = (pos.col == (colnr_T)strlen(old)); if (*old != NUL && !trailblank && wasatend) { dec_cursor(); cc = gchar_cursor(); @@ -733,18 +730,16 @@ void auto_format(bool trailblank, bool prev_line) /// @param end_insert true when ending Insert mode void check_auto_format(bool end_insert) { - int c = ' '; - int cc; - if (!did_add_space) { return; } - cc = gchar_cursor(); + int cc = gchar_cursor(); if (!WHITECHAR(cc)) { // Somehow the space was removed already. did_add_space = false; } else { + int c = ' '; if (!end_insert) { inc_cursor(); c = gchar_cursor(); @@ -886,7 +881,6 @@ void op_formatexpr(oparg_T *oap) int fex_format(linenr_T lnum, long count, int c) { int use_sandbox = was_set_insecurely(curwin, "formatexpr", OPT_LOCAL); - int r; // Set v:lnum to the first line number and v:count to the number of lines. // Set v:char to the character to be inserted (can be NUL). @@ -900,7 +894,7 @@ int fex_format(linenr_T lnum, long count, int c) if (use_sandbox) { sandbox++; } - r = (int)eval_to_number(fex); + int r = (int)eval_to_number(fex); if (use_sandbox) { sandbox--; } diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c index 8e786c271c..37f893ecec 100644 --- a/src/nvim/textobject.c +++ b/src/nvim/textobject.c @@ -176,7 +176,6 @@ found: bool findpar(bool *pincl, int dir, long count, int what, bool both) { linenr_T curr; - bool did_skip; // true after separating lines have been skipped bool first; // true on first line linenr_T fold_first; // first line of a closed fold linenr_T fold_last; // last line of a closed fold @@ -186,7 +185,7 @@ bool findpar(bool *pincl, int dir, long count, int what, bool both) curr = curwin->w_cursor.lnum; while (count--) { - did_skip = false; + bool did_skip = false; // true after separating lines have been skipped for (first = true;; first = false) { if (*ml_get(curr) != NUL) { did_skip = true; @@ -324,10 +323,6 @@ static int cls(void) /// @param bigword "W", "E" or "B" int fwd_word(long count, bool bigword, bool eol) { - int sclass; // starting class - int i; - int last_line; - curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { @@ -336,12 +331,12 @@ int fwd_word(long count, bool bigword, bool eol) if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) { coladvance(MAXCOL); } - sclass = cls(); + int sclass = cls(); // starting class // We always move at least one character, unless on the last // character in the buffer. - last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count); - i = inc_cursor(); + int last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count); + int i = inc_cursor(); if (i == -1 || (i >= 1 && last_line)) { // started at last char in file return FAIL; } @@ -493,13 +488,11 @@ finished: /// @return FAIL if start of the file was reached. int bckend_word(long count, bool bigword, bool eol) { - int sclass; // starting class - int i; - curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { - sclass = cls(); + int i; + int sclass = cls(); // starting class if ((i = dec_cursor()) == -1) { return FAIL; } @@ -562,10 +555,8 @@ static void back_in_line(void) static void find_first_blank(pos_T *posp) { - int c; - while (decl(posp) != -1) { - c = gchar_pos(posp); + int c = gchar_pos(posp); if (!ascii_iswhite(c)) { incl(posp); break; @@ -598,7 +589,6 @@ static void findsent_forward(long count, bool at_start_sent) int current_word(oparg_T *oap, long count, bool include, bool bigword) { pos_T start_pos; - pos_T pos; bool inclusive = true; int include_white = false; @@ -703,7 +693,7 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword) // word). Also when "2daw" deletes "word." at the end of the line // (cursor is at start of next line). // But don't delete white space at start of line (indent). - pos = curwin->w_cursor; // save cursor position + pos_T pos = curwin->w_cursor; // save cursor position curwin->w_cursor = start_pos; if (oneleft() == OK) { back_in_line(); @@ -1042,7 +1032,6 @@ static bool in_html_tag(bool end_tag) { char *line = get_cursor_line_ptr(); char *p; - int c; int lc = NUL; pos_T pos; @@ -1078,7 +1067,7 @@ static bool in_html_tag(bool end_tag) if (inc(&pos) < 0) { return false; } - c = (uint8_t)(*ml_get_pos(&pos)); + int c = (uint8_t)(*ml_get_pos(&pos)); if (c == '>') { break; } @@ -1443,10 +1432,8 @@ extend: /// @return column number of "quotechar" or -1 when not found. static int find_next_quote(char *line, int col, int quotechar, char *escape) { - int c; - for (;;) { - c = (uint8_t)line[col]; + int c = (uint8_t)line[col]; if (c == NUL) { return -1; } else if (escape != NULL && vim_strchr(escape, c)) { @@ -1471,12 +1458,10 @@ static int find_next_quote(char *line, int col, int quotechar, char *escape) /// @return the found column or zero. static int find_prev_quote(char *line, int col_start, int quotechar, char *escape) { - int n; - while (col_start > 0) { col_start--; col_start -= utf_head_off(line, line + col_start); - n = 0; + int n = 0; if (escape != NULL) { while (col_start - n > 0 && vim_strchr(escape, (uint8_t)line[col_start - n - 1]) != NULL) { diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 733aa25f03..c992253e1f 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -185,8 +185,9 @@ void tinput_stop(TermInput *input) } static void tinput_done_event(void **argv) + FUNC_ATTR_NORETURN { - input_done(); + os_exit(1); } static void tinput_wait_enqueue(void **argv) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index fff5c865bf..8df6e49b77 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -34,15 +34,17 @@ #include "nvim/msgpack_rpc/channel.h" #include "nvim/os/input.h" #include "nvim/os/os.h" -#include "nvim/ui_client.h" -#ifdef MSWIN -# include "nvim/os/os_win_console.h" -#endif #include "nvim/tui/input.h" #include "nvim/tui/terminfo.h" #include "nvim/tui/tui.h" #include "nvim/ugrid.h" #include "nvim/ui.h" +#include "nvim/ui_client.h" + +#ifdef MSWIN +# include "nvim/os/os_win_console.h" +# include "nvim/os/tty.h" +#endif // Space reserved in two output buffers to make the cursor normal or invisible // when flushing. No existing terminal will require 32 bytes to do that. @@ -165,7 +167,7 @@ static bool cursor_style_enabled = false; # include "tui/tui.c.generated.h" #endif -TUIData *tui_start(int *width, int *height, char **term) +void tui_start(TUIData **tui_p, int *width, int *height, char **term) { TUIData *tui = xcalloc(1, sizeof(TUIData)); tui->is_starting = true; @@ -188,11 +190,11 @@ TUIData *tui_start(int *width, int *height, char **term) uv_timer_start(&tui->startup_delay_timer, after_startup_cb, 100, 0); + *tui_p = tui; loop_poll_events(&main_loop, 1); *width = tui->width; *height = tui->height; *term = tui->term; - return tui; } void tui_enable_extkeys(TUIData *tui) @@ -357,12 +359,7 @@ static void terminfo_start(TUIData *tui) if (ret) { ELOG("uv_tty_init failed: %s", uv_strerror(ret)); } -#ifdef MSWIN - ret = uv_tty_set_mode(&tui->output_handle.tty, UV_TTY_MODE_RAW); - if (ret) { - ELOG("uv_tty_set_mode failed: %s", uv_strerror(ret)); - } -#else +#ifndef MSWIN int retry_count = 10; // A signal may cause uv_tty_set_mode() to fail (e.g., SIGCONT). Retry a // few times. #12322 diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 8172a46773..1693595ce8 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -11,6 +11,7 @@ #include "klib/kvec.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/api/ui.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" @@ -608,7 +609,7 @@ Array ui_array(void) return all_uis; } -void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error) +void ui_grid_resize(handle_T grid_handle, int width, int height, Error *err) { if (grid_handle == DEFAULT_GRID_HANDLE) { screen_resize(width, height); @@ -616,11 +617,9 @@ void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error) } win_T *wp = get_win_by_grid_handle(grid_handle); - if (wp == NULL) { - api_set_error(error, kErrorTypeValidation, - "No window with the given handle"); + VALIDATE_INT((wp != NULL), "window handle", (int64_t)grid_handle, { return; - } + }); if (wp->w_floating) { if (width != wp->w_width || height != wp->w_height) { diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index 58edd7aff3..df0a26c6ee 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -22,6 +22,10 @@ #include "nvim/ui.h" #include "nvim/ui_client.h" +#ifdef MSWIN +# include "nvim/os/os_win_console.h" +#endif + static TUIData *tui = NULL; static bool ui_client_is_remote = false; @@ -31,7 +35,6 @@ static bool ui_client_is_remote = false; # include "ui_events_client.generated.h" #endif // uncrustify:on -// uint64_t ui_client_start_server(int argc, char **argv) { @@ -110,7 +113,7 @@ void ui_client_run(bool remote_ui) ui_client_is_remote = remote_ui; int width, height; char *term; - tui = tui_start(&width, &height, &term); + tui_start(&tui, &width, &height, &term); ui_client_attach(width, height, term); diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index ef13f67e49..3a5a4c3e91 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -298,8 +298,8 @@ const char *set_context_in_user_cmdarg(const char *cmd FUNC_ATTR_UNUSED, const c return arg; } if (context == EXPAND_MAPPINGS) { - return (const char *)set_context_in_map_cmd(xp, "map", (char *)arg, forceit, false, false, - CMD_map); + return set_context_in_map_cmd(xp, "map", (char *)arg, forceit, false, false, + CMD_map); } // Find start of last argument. const char *p = arg; @@ -531,15 +531,13 @@ static void uc_list(char *name, size_t name_len) if (a & (EX_RANGE | EX_COUNT)) { if (a & EX_COUNT) { // -count=N - snprintf(IObuff + len, IOSIZE, "%" PRId64 "c", - (int64_t)cmd->uc_def); + snprintf(IObuff + len, IOSIZE, "%" PRId64 "c", cmd->uc_def); len += (int)strlen(IObuff + len); } else if (a & EX_DFLALL) { IObuff[len++] = '%'; } else if (cmd->uc_def >= 0) { // -range=N - snprintf(IObuff + len, IOSIZE, "%" PRId64 "", - (int64_t)cmd->uc_def); + snprintf(IObuff + len, IOSIZE, "%" PRId64 "", cmd->uc_def); len += (int)strlen(IObuff + len); } else { IObuff[len++] = '.'; @@ -862,9 +860,9 @@ char *uc_validate_name(char *name) /// This function takes ownership of compl_arg, compl_luaref, and luaref. /// /// @return OK if the command is created, FAIL otherwise. -int uc_add_command(char *name, size_t name_len, const char *rep, uint32_t argt, long def, int flags, - int compl, char *compl_arg, LuaRef compl_luaref, LuaRef preview_luaref, - cmd_addr_T addr_type, LuaRef luaref, bool force) +int uc_add_command(char *name, size_t name_len, const char *rep, uint32_t argt, int64_t def, + int flags, int compl, char *compl_arg, LuaRef compl_luaref, + LuaRef preview_luaref, cmd_addr_T addr_type, LuaRef luaref, bool force) FUNC_ATTR_NONNULL_ARG(1, 3) { ucmd_T *cmd = NULL; @@ -1540,13 +1538,13 @@ static size_t uc_check_code(char *code, size_t len, char *buf, ucmd_T *cmd, exar case ct_RANGE: case ct_COUNT: { char num_buf[20]; - long num = (type == ct_LINE1) ? eap->line1 : - (type == ct_LINE2) ? eap->line2 : - (type == ct_RANGE) ? eap->addr_count : - (eap->addr_count > 0) ? eap->line2 : cmd->uc_def; + int64_t num = (type == ct_LINE1) ? eap->line1 : + (type == ct_LINE2) ? eap->line2 : + (type == ct_RANGE) ? eap->addr_count : + (eap->addr_count > 0) ? eap->line2 : cmd->uc_def; size_t num_len; - snprintf(num_buf, sizeof(num_buf), "%" PRId64, (int64_t)num); + snprintf(num_buf, sizeof(num_buf), "%" PRId64, num); num_len = strlen(num_buf); result = num_len; @@ -1751,8 +1749,8 @@ Dictionary commands_array(buf_T *buf) Dictionary d = ARRAY_DICT_INIT; ucmd_T *cmd = USER_CMD_GA(gap, i); - PUT(d, "name", STRING_OBJ(cstr_to_string((char *)cmd->uc_name))); - PUT(d, "definition", STRING_OBJ(cstr_to_string((char *)cmd->uc_rep))); + PUT(d, "name", STRING_OBJ(cstr_to_string(cmd->uc_name))); + PUT(d, "definition", STRING_OBJ(cstr_to_string(cmd->uc_rep))); PUT(d, "script_id", INTEGER_OBJ(cmd->uc_script_ctx.sc_sid)); PUT(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_BANG))); PUT(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_TRLBAR))); @@ -1778,12 +1776,12 @@ Dictionary commands_array(buf_T *buf) PUT(d, "complete", (cmd_compl == NULL ? NIL : STRING_OBJ(cstr_to_string(cmd_compl)))); PUT(d, "complete_arg", cmd->uc_compl_arg == NULL - ? NIL : STRING_OBJ(cstr_to_string((char *)cmd->uc_compl_arg))); + ? NIL : STRING_OBJ(cstr_to_string(cmd->uc_compl_arg))); Object obj = NIL; if (cmd->uc_argt & EX_COUNT) { if (cmd->uc_def >= 0) { - snprintf(str, sizeof(str), "%" PRId64, (int64_t)cmd->uc_def); + snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def); obj = STRING_OBJ(cstr_to_string(str)); // -count=N } else { obj = STRING_OBJ(cstr_to_string("0")); // -count @@ -1796,7 +1794,7 @@ Dictionary commands_array(buf_T *buf) if (cmd->uc_argt & EX_DFLALL) { obj = STRING_OBJ(cstr_to_string("%")); // -range=% } else if (cmd->uc_def >= 0) { - snprintf(str, sizeof(str), "%" PRId64, (int64_t)cmd->uc_def); + snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def); obj = STRING_OBJ(cstr_to_string(str)); // -range=N } else { obj = STRING_OBJ(cstr_to_string(".")); // -range @@ -1814,7 +1812,7 @@ Dictionary commands_array(buf_T *buf) } PUT(d, "addr", obj); - PUT(rv, (char *)cmd->uc_name, DICTIONARY_OBJ(d)); + PUT(rv, cmd->uc_name, DICTIONARY_OBJ(d)); } return rv; } diff --git a/src/nvim/usercmd.h b/src/nvim/usercmd.h index b6bf6c1e33..0d9838abf2 100644 --- a/src/nvim/usercmd.h +++ b/src/nvim/usercmd.h @@ -12,7 +12,7 @@ typedef struct ucmd { char *uc_name; // The command name uint32_t uc_argt; // The argument type char *uc_rep; // The command's replacement string - long uc_def; // The default value for a range/count + int64_t uc_def; // The default value for a range/count int uc_compl; // completion type cmd_addr_T uc_addr_type; // The command's address type sctx_T uc_script_ctx; // SCTX where the command was defined diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 3c765f8eb2..00e28e3e68 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -195,7 +195,6 @@ enum { FOLD_TEXT_LEN = 51, }; //!< buffer size for get_foldtext() #define CLEAR_FIELD(field) memset(&(field), 0, sizeof(field)) #define CLEAR_POINTER(ptr) memset((ptr), 0, sizeof(*(ptr))) -// defines to avoid typecasts from (char_u *) to (char *) and back // (vim_strchr() is now in strings.c) #ifndef HAVE_STRNLEN diff --git a/src/nvim/window.c b/src/nvim/window.c index 6b40ccdb84..c6694cd489 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -358,14 +358,13 @@ newwindow: msg(_(m_onlyone)); } else { tabpage_T *oldtab = curtab; - tabpage_T *newtab; // First create a new tab with the window, then go back to // the old tab and close the window there. win_T *wp = curwin; if (win_new_tabpage((int)Prenum, NULL) == OK && valid_tabpage(oldtab)) { - newtab = curtab; + tabpage_T *newtab = curtab; goto_tabpage_tp(oldtab, true, true); if (curwin == wp) { win_close(curwin, false, false); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7b1a082f4d..dc74838760 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,6 +26,7 @@ if(BUSTED_PRG) -D BUILD_DIR=${CMAKE_BINARY_DIR} -D TEST_TYPE=unit -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${UNITTEST_PREREQS} USES_TERMINAL) @@ -50,6 +51,7 @@ if(BUSTED_PRG) -D DEPS_PREFIX=${DEPS_PREFIX} -D TEST_TYPE=functional -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${FUNCTIONALTEST_PREREQS} USES_TERMINAL) @@ -66,6 +68,7 @@ if(BUSTED_PRG) -D BUILD_DIR=${CMAKE_BINARY_DIR} -D TEST_TYPE=benchmark -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${BENCHMARK_PREREQS} USES_TERMINAL) @@ -85,6 +88,7 @@ if(BUSTED_LUA_PRG) -D BUILD_DIR=${CMAKE_BINARY_DIR} -D TEST_TYPE=functional -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${FUNCTIONALTEST_PREREQS} USES_TERMINAL) diff --git a/test/functional/api/autocmd_spec.lua b/test/functional/api/autocmd_spec.lua index af13736aa9..b1e38e77a1 100644 --- a/test/functional/api/autocmd_spec.lua +++ b/test/functional/api/autocmd_spec.lua @@ -14,14 +14,31 @@ before_each(clear) describe('autocmd api', function() describe('nvim_create_autocmd', function() - it('"command" and "callback" are mutually exclusive', function() - local rv = pcall_err(meths.create_autocmd, "BufReadPost", { - pattern = "*.py,*.pyi", + it('validation', function() + eq("Cannot use both 'callback' and 'command'", pcall_err(meths.create_autocmd, 'BufReadPost', { + pattern = '*.py,*.pyi', command = "echo 'Should Have Errored", - callback = "NotAllowed", - }) - - eq("specify either 'callback' or 'command', not both", rv) + callback = 'NotAllowed', + })) + eq("Cannot use both 'pattern' and 'buffer' for the same autocmd", pcall_err(meths.create_autocmd, 'FileType', { + command = 'let g:called = g:called + 1', + buffer = 0, + pattern = '*.py', + })) + eq("Required: 'event'", pcall_err(meths.create_autocmd, {}, { + command = 'ls', + })) + eq("Required: 'command' or 'callback'", pcall_err(meths.create_autocmd, 'FileType', { + })) + eq("Invalid 'desc': expected String, got Integer", pcall_err(meths.create_autocmd, 'FileType', { + command = 'ls', + desc = 42, + })) + eq("Invalid 'callback': expected Lua function or Vim function name, got Integer", pcall_err(meths.create_autocmd, 'FileType', { + callback = 0, + })) + eq("Invalid 'event' item: expected String, got Array", pcall_err(meths.create_autocmd, + {'FileType', {}}, {})) end) it('doesnt leak when you use ++once', function() @@ -59,18 +76,8 @@ describe('autocmd api', function() eq(1, meths.get_var('called')) end) - it('does not allow passing buffer and patterns', function() - local rv = pcall_err(meths.create_autocmd, "Filetype", { - command = "let g:called = g:called + 1", - buffer = 0, - pattern = "*.py", - }) - - eq("cannot pass both: 'pattern' and 'buffer' for the same autocmd", rv) - end) - it('does not allow passing invalid buffers', function() - local ok, msg = pcall(meths.create_autocmd, "Filetype", { + local ok, msg = pcall(meths.create_autocmd, 'FileType', { command = "let g:called = g:called + 1", buffer = -1, }) @@ -294,8 +301,29 @@ describe('autocmd api', function() end) describe('nvim_get_autocmds', function() + it('validation', function() + eq("Invalid 'group': 9997999", pcall_err(meths.get_autocmds, { + group = 9997999, + })) + eq("Invalid 'group': 'bogus'", pcall_err(meths.get_autocmds, { + group = 'bogus', + })) + eq("Invalid 'group': expected String or Integer, got Array", pcall_err(meths.get_autocmds, { + group = {}, + })) + eq("Invalid 'buffer': expected Integer or Array, got Boolean", pcall_err(meths.get_autocmds, { + buffer = true, + })) + eq("Invalid 'event': expected String or Array", pcall_err(meths.get_autocmds, { + event = true, + })) + eq("Invalid 'pattern': expected String or Array, got Boolean", pcall_err(meths.get_autocmds, { + pattern = true, + })) + end) + describe('events', function() - it('should return one autocmd when there is only one for an event', function() + it('returns one autocmd when there is only one for an event', function() command [[au! InsertEnter]] command [[au InsertEnter * :echo "1"]] @@ -303,7 +331,7 @@ describe('autocmd api', function() eq(1, #aus) end) - it('should return two autocmds when there are two for an event', function() + it('returns two autocmds when there are two for an event', function() command [[au! InsertEnter]] command [[au InsertEnter * :echo "1"]] command [[au InsertEnter * :echo "2"]] @@ -312,7 +340,7 @@ describe('autocmd api', function() eq(2, #aus) end) - it('should return the same thing if you use string or list', function() + it('returns the same thing if you use string or list', function() command [[au! InsertEnter]] command [[au InsertEnter * :echo "1"]] command [[au InsertEnter * :echo "2"]] @@ -322,7 +350,7 @@ describe('autocmd api', function() eq(string_aus, array_aus) end) - it('should return two autocmds when there are two for an event', function() + it('returns two autocmds when there are two for an event', function() command [[au! InsertEnter]] command [[au! InsertLeave]] command [[au InsertEnter * :echo "1"]] @@ -332,7 +360,7 @@ describe('autocmd api', function() eq(2, #aus) end) - it('should return different IDs for different autocmds', function() + it('returns different IDs for different autocmds', function() command [[au! InsertEnter]] command [[au! InsertLeave]] command [[au InsertEnter * :echo "1"]] @@ -356,7 +384,7 @@ describe('autocmd api', function() eq(first, new_aus[1]) end) - it('should return event name', function() + it('returns event name', function() command [[au! InsertEnter]] command [[au InsertEnter * :echo "1"]] @@ -364,7 +392,7 @@ describe('autocmd api', function() eq({ { buflocal = false, command = ':echo "1"', event = "InsertEnter", once = false, pattern = "*" } }, aus) end) - it('should work with buffer numbers', function() + it('works with buffer numbers', function() command [[new]] command [[au! InsertEnter]] command [[au InsertEnter <buffer=1> :echo "1"]] @@ -407,8 +435,8 @@ describe('autocmd api', function() pattern = "<buffer=2>", }}, aus) - eq("Invalid value for 'buffer': must be an integer or array of integers", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = "foo" })) - eq("Invalid value for 'buffer': must be an integer", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = { "foo", 42 } })) + eq("Invalid 'buffer': expected Integer or Array, got String", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = "foo" })) + eq("Invalid 'buffer': expected Integer, got String", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = { "foo", 42 } })) eq("Invalid buffer id: 42", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = { 42 } })) local bufs = {} @@ -416,10 +444,10 @@ describe('autocmd api', function() table.insert(bufs, meths.create_buf(true, false)) end - eq("Too many buffers. Please limit yourself to 256 or fewer", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = bufs })) + eq("Too many buffers (maximum of 256)", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = bufs })) end) - it('should return autocmds when group is specified by id', function() + it('returns autocmds when group is specified by id', function() local auid = meths.create_augroup("nvim_test_augroup", { clear = true }) meths.create_autocmd("FileType", { group = auid, command = 'echo "1"' }) meths.create_autocmd("FileType", { group = auid, command = 'echo "2"' }) @@ -431,7 +459,7 @@ describe('autocmd api', function() eq(0, #aus2) end) - it('should return autocmds when group is specified by name', function() + it('returns autocmds when group is specified by name', function() local auname = "nvim_test_augroup" meths.create_augroup(auname, { clear = true }) meths.create_autocmd("FileType", { group = auname, command = 'echo "1"' }) @@ -531,7 +559,7 @@ describe('autocmd api', function() command [[augroup END]] end) - it('should return all groups if no group is specified', function() + it('returns all groups if no group is specified', function() local aus = meths.get_autocmds { event = "InsertEnter" } if #aus ~= 4 then eq({}, aus) @@ -540,7 +568,7 @@ describe('autocmd api', function() eq(4, #aus) end) - it('should return only the group specified', function() + it('returns only the group specified', function() local aus = meths.get_autocmds { event = "InsertEnter", group = "GroupOne", @@ -551,7 +579,7 @@ describe('autocmd api', function() eq("GroupOne", aus[1].group_name) end) - it('should return only the group specified, multiple values', function() + it('returns only the group specified, multiple values', function() local aus = meths.get_autocmds { event = "InsertEnter", group = "GroupTwo", @@ -578,7 +606,7 @@ describe('autocmd api', function() ]], {})) eq(false, success) - matches('invalid augroup: NotDefined', code) + matches("Invalid 'group': 'NotDefined'", code) end) it('raises error for undefined augroup id', function() @@ -596,7 +624,7 @@ describe('autocmd api', function() ]], {})) eq(false, success) - matches('invalid augroup: 1', code) + matches("Invalid 'group': 1", code) end) it('raises error for invalid group type', function() @@ -611,7 +639,7 @@ describe('autocmd api', function() ]], {})) eq(false, success) - matches("'group' must be a string or an integer", code) + matches("Invalid 'group': expected String or Integer, got Boolean", code) end) it('raises error for invalid pattern array', function() @@ -625,7 +653,7 @@ describe('autocmd api', function() ]], {})) eq(false, success) - matches("All entries in 'pattern' must be strings", code) + matches("Invalid 'pattern' item: expected String, got Array", code) end) end) @@ -640,7 +668,7 @@ describe('autocmd api', function() command [[au InsertEnter <buffer> :echo "Buffer"]] end) - it('should should return for literal match', function() + it('returns for literal match', function() local aus = meths.get_autocmds { event = "InsertEnter", pattern = "*" @@ -650,7 +678,7 @@ describe('autocmd api', function() eq([[:echo "No Group"]], aus[1].command) end) - it('should return for multiple matches', function() + it('returns for multiple matches', function() -- vim.api.nvim_get_autocmds local aus = meths.get_autocmds { event = "InsertEnter", @@ -687,6 +715,23 @@ describe('autocmd api', function() end) describe('nvim_exec_autocmds', function() + it('validation', function() + eq("Invalid 'group': 9997999", pcall_err(meths.exec_autocmds, 'FileType', { + group = 9997999, + })) + eq("Invalid 'group': 'bogus'", pcall_err(meths.exec_autocmds, 'FileType', { + group = 'bogus', + })) + eq("Invalid 'group': expected String or Integer, got Array", pcall_err(meths.exec_autocmds, 'FileType', { + group = {}, + })) + eq("Invalid 'buffer': expected Integer, got Array", pcall_err(meths.exec_autocmds, 'FileType', { + buffer = {}, + })) + eq("Invalid 'event' item: expected String, got Array", pcall_err(meths.exec_autocmds, + {'FileType', {}}, {})) + end) + it("can trigger builtin autocmds", function() meths.set_var("autocmd_executed", false) @@ -1036,7 +1081,7 @@ describe('autocmd api', function() local augroup = "WillBeDeleted" meths.create_augroup(augroup, { clear = true }) - meths.create_autocmd({"Filetype"}, { + meths.create_autocmd({"FileType"}, { pattern = "*", command = "echo 'does not matter'", }) @@ -1055,7 +1100,7 @@ describe('autocmd api', function() meths.set_var("value_set", false) meths.create_augroup(augroup, { clear = true }) - meths.create_autocmd("Filetype", { + meths.create_autocmd("FileType", { pattern = "<buffer>", command = "let g:value_set = v:true", }) @@ -1171,6 +1216,16 @@ describe('autocmd api', function() end) describe('nvim_clear_autocmds', function() + it('validation', function() + eq("Cannot use both 'pattern' and 'buffer'", pcall_err(meths.clear_autocmds, { + pattern = '*', + buffer = 42, + })) + eq("Invalid 'event' item: expected String, got Array", pcall_err(meths.clear_autocmds, { + event = {'FileType', {}} + })) + end) + it('should clear based on event + pattern', function() command('autocmd InsertEnter *.py :echo "Python can be cool sometimes"') command('autocmd InsertEnter *.txt :echo "Text Files Are Cool"') diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua index 6b13729994..d454765edb 100644 --- a/test/functional/api/buffer_spec.lua +++ b/test/functional/api/buffer_spec.lua @@ -193,7 +193,7 @@ describe('api/buf', function() it('fails correctly when input is not valid', function() eq(1, api.curbufmeths.get_number()) - eq([[String cannot contain newlines]], + eq([['replacement string' item contains newlines]], pcall_err(bufmeths.set_lines, 1, 1, 2, false, {'b\na'})) end) @@ -553,20 +553,20 @@ describe('api/buf', function() insert([[ hello foo! text]]) - eq('start_row out of bounds', pcall_err(set_text, 2, 0, 3, 0, {})) - eq('start_row out of bounds', pcall_err(set_text, -3, 0, 0, 0, {})) - eq('end_row out of bounds', pcall_err(set_text, 0, 0, 2, 0, {})) - eq('end_row out of bounds', pcall_err(set_text, 0, 0, -3, 0, {})) - eq('start_col out of bounds', pcall_err(set_text, 1, 5, 1, 5, {})) - eq('end_col out of bounds', pcall_err(set_text, 1, 0, 1, 5, {})) + eq("Invalid 'start_row': out of range", pcall_err(set_text, 2, 0, 3, 0, {})) + eq("Invalid 'start_row': out of range", pcall_err(set_text, -3, 0, 0, 0, {})) + eq("Invalid 'end_row': out of range", pcall_err(set_text, 0, 0, 2, 0, {})) + eq("Invalid 'end_row': out of range", pcall_err(set_text, 0, 0, -3, 0, {})) + eq("Invalid 'start_col': out of range", pcall_err(set_text, 1, 5, 1, 5, {})) + eq("Invalid 'end_col': out of range", pcall_err(set_text, 1, 0, 1, 5, {})) end) it('errors when start is greater than end', function() insert([[ hello foo! text]]) - eq('start is higher than end', pcall_err(set_text, 1, 0, 0, 0, {})) - eq('start is higher than end', pcall_err(set_text, 0, 1, 0, 0, {})) + eq("'start' is higher than 'end'", pcall_err(set_text, 1, 0, 0, 0, {})) + eq("'start' is higher than 'end'", pcall_err(set_text, 0, 1, 0, 0, {})) end) it('no heap-use-after-free when called consecutively #19643', function() @@ -611,7 +611,7 @@ describe('api/buf', function() end) it('errors when start is greater than end', function() - eq('start is higher than end', pcall_err(get_text, 1, 0, 0, 0, {})) + eq("'start' is higher than 'end'", pcall_err(get_text, 1, 0, 0, 0, {})) eq('start_col must be less than end_col', pcall_err(get_text, 0, 1, 0, 0, {})) end) end) diff --git a/test/functional/api/buffer_updates_spec.lua b/test/functional/api/buffer_updates_spec.lua index d5f06c8f1f..25b838a4af 100644 --- a/test/functional/api/buffer_updates_spec.lua +++ b/test/functional/api/buffer_updates_spec.lua @@ -762,7 +762,7 @@ describe('API: buffer events:', function() it('returns a proper error on nonempty options dict', function() clear() local b = editoriginal(false) - eq("unexpected key: builtin", pcall_err(buffer, 'attach', b, false, {builtin="asfd"})) + eq("Invalid 'opts' key: 'builtin'", pcall_err(buffer, 'attach', b, false, {builtin="asfd"})) end) it('nvim_buf_attach returns response after delay #8634', function() diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua index d0fb26edc7..9db687cc37 100644 --- a/test/functional/api/command_spec.lua +++ b/test/functional/api/command_spec.lua @@ -543,23 +543,19 @@ describe('nvim_create_user_command', function() end) it('does not allow invalid command names', function() - matches("'name' must begin with an uppercase letter", pcall_err(exec_lua, [[ + eq("Invalid command name (must start with uppercase): 'test'", pcall_err(exec_lua, [[ vim.api.nvim_create_user_command('test', 'echo "hi"', {}) ]])) - - matches('Invalid command name', pcall_err(exec_lua, [[ + eq("Invalid command name: 't@'", pcall_err(exec_lua, [[ vim.api.nvim_create_user_command('t@', 'echo "hi"', {}) ]])) - - matches('Invalid command name', pcall_err(exec_lua, [[ + eq("Invalid command name: 'T@st'", pcall_err(exec_lua, [[ vim.api.nvim_create_user_command('T@st', 'echo "hi"', {}) ]])) - - matches('Invalid command name', pcall_err(exec_lua, [[ + eq("Invalid command name: 'Test!'", pcall_err(exec_lua, [[ vim.api.nvim_create_user_command('Test!', 'echo "hi"', {}) ]])) - - matches('Invalid command name', pcall_err(exec_lua, [[ + eq("Invalid command name: '💩'", pcall_err(exec_lua, [[ vim.api.nvim_create_user_command('💩', 'echo "hi"', {}) ]])) end) diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua index 9902826c72..3f9cb94260 100644 --- a/test/functional/api/extmark_spec.lua +++ b/test/functional/api/extmark_spec.lua @@ -101,12 +101,20 @@ describe('API/extmarks', function() ns2 = request('nvim_create_namespace', "my-fancy-plugin2") end) + it('validation', function() + eq("Invalid 'end_col': expected Integer, got Array", pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = {}, end_row = 1 })) + eq("Invalid 'end_row': expected Integer, got Array", pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_row = {} })) + eq("Invalid 'id': expected positive Integer", pcall_err(set_extmark, ns, {}, 0, 0, { end_col = 1, end_row = 1 })) + eq("Invalid mark position: expected 2 Integer items", pcall_err(get_extmarks, ns, {}, {-1, -1})) + eq("Invalid mark position: expected mark id Integer or 2-item Array", pcall_err(get_extmarks, ns, true, {-1, -1})) + end) + it("can end extranges past final newline using end_col = 0", function() set_extmark(ns, marks[1], 0, 0, { end_col = 0, end_row = 1 }) - eq("end_col value outside range", + eq("Invalid 'end_col': out of range", pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_row = 1 })) end) @@ -1344,10 +1352,10 @@ describe('API/extmarks', function() it('throws consistent error codes', function() local ns_invalid = ns2 + 1 - eq("Invalid ns_id", pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2])) - eq("Invalid ns_id", pcall_err(curbufmeths.del_extmark, ns_invalid, marks[1])) - eq("Invalid ns_id", pcall_err(get_extmarks, ns_invalid, positions[1], positions[2])) - eq("Invalid ns_id", pcall_err(get_extmark_by_id, ns_invalid, marks[1])) + eq("Invalid 'ns_id': 3", pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2])) + eq("Invalid 'ns_id': 3", pcall_err(curbufmeths.del_extmark, ns_invalid, marks[1])) + eq("Invalid 'ns_id': 3", pcall_err(get_extmarks, ns_invalid, positions[1], positions[2])) + eq("Invalid 'ns_id': 3", pcall_err(get_extmark_by_id, ns_invalid, marks[1])) end) it('when col = line-length, set the mark on eol', function() @@ -1362,13 +1370,13 @@ describe('API/extmarks', function() it('when col = line-length, set the mark on eol', function() local invalid_col = init_text:len() + 1 - eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) + eq("Invalid 'col': out of range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) end) it('fails when line > line_count', function() local invalid_col = init_text:len() + 1 local invalid_lnum = 3 - eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) + eq("Invalid 'line': out of range", pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) eq({}, get_extmark_by_id(ns, marks[1])) end) diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index 7f044977cb..e1b3562329 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -57,9 +57,7 @@ describe('API: highlight',function() eq(expected_rgb, nvim("get_hl_by_id", hl_id, true)) -- Test invalid id. - local err, emsg = pcall(meths.get_hl_by_id, 30000, false) - eq(false, err) - eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*')) + eq('Invalid highlight id: 30000', pcall_err(meths.get_hl_by_id, 30000, false)) -- Test all highlight properties. command('hi NewHighlight gui=underline,bold,italic,reverse,strikethrough,altfont,nocombine') @@ -70,22 +68,14 @@ describe('API: highlight',function() eq(expected_undercurl, nvim("get_hl_by_id", hl_id, true)) -- Test nil argument. - err, emsg = pcall(meths.get_hl_by_id, { nil }, false) - eq(false, err) eq('Wrong type for argument 1 when calling nvim_get_hl_by_id, expecting Integer', - string.match(emsg, 'Wrong.*')) + pcall_err(meths.get_hl_by_id, { nil }, false)) -- Test 0 argument. - err, emsg = pcall(meths.get_hl_by_id, 0, false) - eq(false, err) - eq('Invalid highlight id: 0', - string.match(emsg, 'Invalid.*')) + eq('Invalid highlight id: 0', pcall_err(meths.get_hl_by_id, 0, false)) -- Test -1 argument. - err, emsg = pcall(meths.get_hl_by_id, -1, false) - eq(false, err) - eq('Invalid highlight id: -1', - string.match(emsg, 'Invalid.*')) + eq('Invalid highlight id: -1', pcall_err(meths.get_hl_by_id, -1, false)) -- Test highlight group without ctermbg value. command('hi Normal ctermfg=red ctermbg=yellow') @@ -119,22 +109,16 @@ describe('API: highlight',function() eq(expected_normal, nvim("get_hl_by_name", 'Normal', true)) -- Test invalid name. - local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight', false) - eq(false, err) - eq('Invalid highlight name: unknown_highlight', - string.match(emsg, 'Invalid.*')) + eq("Invalid highlight name: 'unknown_highlight'", + pcall_err(meths.get_hl_by_name , 'unknown_highlight', false)) -- Test nil argument. - err, emsg = pcall(meths.get_hl_by_name , { nil }, false) - eq(false, err) eq('Wrong type for argument 1 when calling nvim_get_hl_by_name, expecting String', - string.match(emsg, 'Wrong.*')) + pcall_err(meths.get_hl_by_name , { nil }, false)) -- Test empty string argument. - err, emsg = pcall(meths.get_hl_by_name , '', false) - eq(false, err) - eq('Invalid highlight name: ', - string.match(emsg, 'Invalid.*')) + eq('Invalid highlight name', + pcall_err(meths.get_hl_by_name , '', false)) -- Test "standout" attribute. #8054 eq({ underline = true, }, @@ -155,7 +139,7 @@ describe('API: highlight',function() it('nvim_get_hl_id_by_name', function() -- precondition: use a hl group that does not yet exist - eq('Invalid highlight name: Shrubbery', pcall_err(meths.get_hl_by_name, "Shrubbery", true)) + eq("Invalid highlight name: 'Shrubbery'", pcall_err(meths.get_hl_by_name, "Shrubbery", true)) eq(0, funcs.hlID("Shrubbery")) local hl_id = meths.get_hl_id_by_name("Shrubbery") @@ -253,25 +237,32 @@ describe("API: set highlight", function() before_each(clear) - it ("can set gui highlight", function() + it('validation', function() + eq("Invalid 'blend': out of range", + pcall_err(meths.set_hl, 0, 'Test_hl3', {fg='#FF00FF', blend=999})) + eq("Invalid 'blend': expected Integer, got Array", + pcall_err(meths.set_hl, 0, 'Test_hl3', {fg='#FF00FF', blend={}})) + end) + + it("can set gui highlight", function() local ns = get_ns() meths.set_hl(ns, 'Test_hl', highlight1) eq(highlight1, meths.get_hl_by_name('Test_hl', true)) end) - it ("can set cterm highlight", function() + it("can set cterm highlight", function() local ns = get_ns() meths.set_hl(ns, 'Test_hl', highlight2_config) eq(highlight2_result, meths.get_hl_by_name('Test_hl', false)) end) - it ("can set empty cterm attr", function() + it("can set empty cterm attr", function() local ns = get_ns() meths.set_hl(ns, 'Test_hl', { cterm = {} }) eq({}, meths.get_hl_by_name('Test_hl', false)) end) - it ("cterm attr defaults to gui attr", function() + it("cterm attr defaults to gui attr", function() local ns = get_ns() meths.set_hl(ns, 'Test_hl', highlight1) eq({ @@ -280,14 +271,14 @@ describe("API: set highlight", function() }, meths.get_hl_by_name('Test_hl', false)) end) - it ("can overwrite attr for cterm", function() + it("can overwrite attr for cterm", function() local ns = get_ns() meths.set_hl(ns, 'Test_hl', highlight3_config) eq(highlight3_result_gui, meths.get_hl_by_name('Test_hl', true)) eq(highlight3_result_cterm, meths.get_hl_by_name('Test_hl', false)) end) - it ("can set a highlight in the global namespace", function() + it("can set a highlight in the global namespace", function() meths.set_hl(0, 'Test_hl', highlight2_config) eq('Test_hl xxx cterm=underline,reverse ctermfg=8 ctermbg=15 gui=underline,reverse', exec_capture('highlight Test_hl')) @@ -307,7 +298,7 @@ describe("API: set highlight", function() exec_capture('highlight Test_hl3')) end) - it ("can modify a highlight in the global namespace", function() + it("can modify a highlight in the global namespace", function() meths.set_hl(0, 'Test_hl3', { bg = 'red', fg = 'blue'}) eq('Test_hl3 xxx guifg=Blue guibg=Red', exec_capture('highlight Test_hl3')) @@ -328,17 +319,17 @@ describe("API: set highlight", function() eq('Test_hl3 xxx ctermbg=9', exec_capture('highlight Test_hl3')) - eq("'redd' is not a valid color", + eq("Invalid highlight color: 'redd'", pcall_err(meths.set_hl, 0, 'Test_hl3', {fg='redd'})) - eq("'bleu' is not a valid color", + eq("Invalid highlight color: 'bleu'", pcall_err(meths.set_hl, 0, 'Test_hl3', {ctermfg='bleu'})) meths.set_hl(0, 'Test_hl3', {fg='#FF00FF'}) eq('Test_hl3 xxx guifg=#ff00ff', exec_capture('highlight Test_hl3')) - eq("'#FF00FF' is not a valid color", + eq("Invalid highlight color: '#FF00FF'", pcall_err(meths.set_hl, 0, 'Test_hl3', {ctermfg='#FF00FF'})) for _, fg_val in ipairs{ nil, 'NONE', 'nOnE', '', -1 } do @@ -353,14 +344,14 @@ describe("API: set highlight", function() end) - it ("correctly sets 'Normal' internal properties", function() + it("correctly sets 'Normal' internal properties", function() -- Normal has some special handling internally. #18024 meths.set_hl(0, 'Normal', {fg='#000083', bg='#0000F3'}) eq({foreground = 131, background = 243}, nvim("get_hl_by_name", 'Normal', true)) end) it('does not segfault on invalid group name #20009', function() - eq('Invalid highlight name: foo bar', pcall_err(meths.set_hl, 0, 'foo bar', {bold = true})) + eq("Invalid highlight name: 'foo bar'", pcall_err(meths.set_hl, 0, 'foo bar', {bold = true})) assert_alive() end) end) diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua index 2028a8fba5..20edea3feb 100644 --- a/test/functional/api/proc_spec.lua +++ b/test/functional/api/proc_spec.lua @@ -42,14 +42,14 @@ describe('API', function() end) end) - it('validates input', function() + it('validation', function() local status, rv = pcall(request, "nvim_get_proc_children", -1) eq(false, status) - eq("Invalid pid: -1", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': -1", string.match(rv, "Invalid.*")) status, rv = pcall(request, "nvim_get_proc_children", 0) eq(false, status) - eq("Invalid pid: 0", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': 0", string.match(rv, "Invalid.*")) -- Assume PID 99999 does not exist. status, rv = pcall(request, "nvim_get_proc_children", 99999) @@ -68,14 +68,14 @@ describe('API', function() neq(pid, pinfo.ppid) end) - it('validates input', function() + it('validation', function() local status, rv = pcall(request, "nvim_get_proc", -1) eq(false, status) - eq("Invalid pid: -1", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': -1", string.match(rv, "Invalid.*")) status, rv = pcall(request, "nvim_get_proc", 0) eq(false, status) - eq("Invalid pid: 0", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': 0", string.match(rv, "Invalid.*")) -- Assume PID 99999 does not exist. status, rv = pcall(request, "nvim_get_proc", 99999) diff --git a/test/functional/api/ui_spec.lua b/test/functional/api/ui_spec.lua index 279cd1856d..b616f51d10 100644 --- a/test/functional/api/ui_spec.lua +++ b/test/functional/api/ui_spec.lua @@ -11,17 +11,37 @@ describe('nvim_ui_attach()', function() before_each(function() clear() end) + it('handles very large width/height #2180', function() local screen = Screen.new(999, 999) screen:attach() eq(999, eval('&lines')) eq(999, eval('&columns')) end) - it('invalid option returns error', function() + + it('validation', function() eq('No such UI option: foo', pcall_err(meths.ui_attach, 80, 24, { foo={'foo'} })) - end) - it('validates channel arg', function() + + eq("Invalid 'ext_linegrid': expected Boolean, got Array", + pcall_err(meths.ui_attach, 80, 24, { ext_linegrid={} })) + eq("Invalid 'override': expected Boolean, got Array", + pcall_err(meths.ui_attach, 80, 24, { override={} })) + eq("Invalid 'rgb': expected Boolean, got Array", + pcall_err(meths.ui_attach, 80, 24, { rgb={} })) + eq("Invalid 'term_name': expected String, got Boolean", + pcall_err(meths.ui_attach, 80, 24, { term_name=true })) + eq("Invalid 'term_colors': expected Integer, got Boolean", + pcall_err(meths.ui_attach, 80, 24, { term_colors=true })) + eq("Invalid 'term_background': expected String, got Boolean", + pcall_err(meths.ui_attach, 80, 24, { term_background=true })) + eq("Invalid 'stdin_fd': expected Integer, got String", + pcall_err(meths.ui_attach, 80, 24, { stdin_fd='foo' })) + eq("Invalid 'stdin_tty': expected Boolean, got String", + pcall_err(meths.ui_attach, 80, 24, { stdin_tty='foo' })) + eq("Invalid 'stdout_tty': expected Boolean, got String", + pcall_err(meths.ui_attach, 80, 24, { stdout_tty='foo' })) + eq('UI not attached to channel: 1', pcall_err(request, 'nvim_ui_try_resize', 40, 10)) eq('UI not attached to channel: 1', diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index fc550f5861..981fc19b36 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -490,7 +490,7 @@ describe('API', function() eq('', eval('v:errmsg')) -- v:errmsg was not updated. end) - it('validates args', function() + it('validation', function() local too_many_args = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' } source([[ function! Foo(...) abort @@ -532,7 +532,7 @@ describe('API', function() eq('@it works@', nvim('call_dict_function', { result = 'it works', G = 'G'}, 'G', {})) end) - it('validates args', function() + it('validation', function() command('let g:d={"baz":"zub","meep":[]}') eq('Not found: bogus', pcall_err(request, 'nvim_call_dict_function', 'g:d', 'bogus', {1,2})) @@ -648,10 +648,10 @@ describe('API', function() end) describe('nvim_paste', function() - it('validates args', function() - eq('Invalid phase: -2', + it('validation', function() + eq("Invalid 'phase': -2", pcall_err(request, 'nvim_paste', 'foo', true, -2)) - eq('Invalid phase: 4', + eq("Invalid 'phase': 4", pcall_err(request, 'nvim_paste', 'foo', true, 4)) end) local function run_streamed_paste_tests() @@ -1154,10 +1154,10 @@ describe('API', function() end) describe('nvim_put', function() - it('validates args', function() - eq('Invalid lines (expected array of strings)', + it('validation', function() + eq("Invalid 'line': expected String, got Integer", pcall_err(request, 'nvim_put', {42}, 'l', false, false)) - eq("Invalid type: 'x'", + eq("Invalid 'type': 'x'", pcall_err(request, 'nvim_put', {'foo'}, 'x', false, false)) end) it("fails if 'nomodifiable'", function() @@ -1259,9 +1259,9 @@ describe('API', function() yyybc line 2 line 3 ]]) - eq("Invalid type: 'bx'", + eq("Invalid 'type': 'bx'", pcall_err(meths.put, {'xxx', 'yyy'}, 'bx', false, true)) - eq("Invalid type: 'b3x'", + eq("Invalid 'type': 'b3x'", pcall_err(meths.put, {'xxx', 'yyy'}, 'b3x', false, true)) end) end) @@ -1288,6 +1288,11 @@ describe('API', function() end) describe('set/get/del variables', function() + it('validation', function() + eq('Key not found: bogus', pcall_err(meths.get_var, 'bogus')) + eq('Key not found: bogus', pcall_err(meths.del_var, 'bogus')) + end) + it('nvim_get_var, nvim_set_var, nvim_del_var', function() nvim('set_var', 'lua', {1, 2, {['3'] = 1}}) eq({1, 2, {['3'] = 1}}, nvim('get_var', 'lua')) @@ -1410,6 +1415,17 @@ describe('API', function() ok(not nvim('get_option_value', 'equalalways', {})) end) + it('validation', function() + eq("Invalid 'scope': expected 'local' or 'global'", + pcall_err(nvim, 'get_option_value', 'scrolloff', {scope = 'bogus'})) + eq("Invalid 'scope': expected 'local' or 'global'", + pcall_err(nvim, 'set_option_value', 'scrolloff', 1, {scope = 'bogus'})) + eq("Invalid 'scope': expected String, got Integer", + pcall_err(nvim, 'get_option_value', 'scrolloff', {scope = 42})) + eq("Invalid 'scrolloff': expected Integer/Boolean/String, got Array", + pcall_err(nvim, 'set_option_value', 'scrolloff', {}, {})) + end) + it('can get local values when global value is set', function() eq(0, nvim('get_option_value', 'scrolloff', {})) eq(-1, nvim('get_option_value', 'scrolloff', {scope = 'local'})) @@ -1777,12 +1793,12 @@ describe('API', function() end) describe('nvim_get_context', function() - it('validates args', function() + it('validation', function() eq("Invalid key: 'blah'", pcall_err(nvim, 'get_context', {blah={}})) - eq('invalid value for key: types', + eq("Invalid 'types': expected Array, got Integer", pcall_err(nvim, 'get_context', {types=42})) - eq('unexpected type: zub', + eq("Invalid 'type': 'zub'", pcall_err(nvim, 'get_context', {types={'jumps', 'zub', 'zam',}})) end) it('returns map of current editor state', function() @@ -2223,15 +2239,14 @@ describe('API', function() eq(5, meths.get_var('avar')) end) - it('throws error on malformed arguments', function() + it('validation', function() local req = { {'nvim_set_var', {'avar', 1}}, {'nvim_set_var'}, {'nvim_set_var', {'avar', 2}}, } - local status, err = pcall(meths.call_atomic, req) - eq(false, status) - ok(err:match('Items in calls array must be arrays of size 2') ~= nil) + eq("Invalid 'calls' item: expected 2-item Array", + pcall_err(meths.call_atomic, req)) -- call before was done, but not after eq(1, meths.get_var('avar')) @@ -2239,18 +2254,16 @@ describe('API', function() { 'nvim_set_var', { 'bvar', { 2, 3 } } }, 12, } - status, err = pcall(meths.call_atomic, req) - eq(false, status) - ok(err:match('Items in calls array must be arrays') ~= nil) + eq("Invalid 'calls' item: expected Array, got Integer", + pcall_err(meths.call_atomic, req)) eq({2,3}, meths.get_var('bvar')) req = { {'nvim_set_current_line', 'little line'}, {'nvim_set_var', {'avar', 3}}, } - status, err = pcall(meths.call_atomic, req) - eq(false, status) - ok(err:match('Args must be Array') ~= nil) + eq("Invalid call args: expected Array, got String", + pcall_err(meths.call_atomic, req)) -- call before was done, but not after eq(1, meths.get_var('avar')) eq({''}, meths.buf_get_lines(0, 0, -1, true)) @@ -2750,7 +2763,7 @@ describe('API', function() describe('nvim_get_option_info', function() it('should error for unknown options', function() - eq("no such option: 'bogus'", pcall_err(meths.get_option_info, 'bogus')) + eq("Invalid option (not found): 'bogus'", pcall_err(meths.get_option_info, 'bogus')) end) it('should return the same options for short and long name', function() @@ -3031,10 +3044,10 @@ describe('API', function() eq(true, meths.del_mark('F')) eq({0, 0}, meths.buf_get_mark(buf, 'F')) end) - it('fails when invalid marks are used', function() - eq(false, pcall(meths.del_mark, 'f')) - eq(false, pcall(meths.del_mark, '!')) - eq(false, pcall(meths.del_mark, 'fail')) + it('validation', function() + eq("Invalid mark name (must be file/uppercase): 'f'", pcall_err(meths.del_mark, 'f')) + eq("Invalid mark name (must be file/uppercase): '!'", pcall_err(meths.del_mark, '!')) + eq("Invalid mark name (must be a single char): 'fail'", pcall_err(meths.del_mark, 'fail')) end) end) describe('nvim_get_mark', function() @@ -3048,10 +3061,10 @@ describe('API', function() assert(string.find(mark[4], "mybuf$")) eq({2, 2, buf.id, mark[4]}, mark) end) - it('fails when invalid marks are used', function() - eq(false, pcall(meths.del_mark, 'f')) - eq(false, pcall(meths.del_mark, '!')) - eq(false, pcall(meths.del_mark, 'fail')) + it('validation', function() + eq("Invalid mark name (must be file/uppercase): 'f'", pcall_err(meths.get_mark, 'f', {})) + eq("Invalid mark name (must be file/uppercase): '!'", pcall_err(meths.get_mark, '!', {})) + eq("Invalid mark name (must be a single char): 'fail'", pcall_err(meths.get_mark, 'fail', {})) end) it('returns the expected when mark is not set', function() eq(true, meths.del_mark('A')) @@ -3113,15 +3126,15 @@ describe('API', function() meths.eval_statusline('a%=b', { fillchar = '\031', maxwidth = 5 })) end) it('rejects multiple-character fillchar', function() - eq('fillchar must be a single character', + eq("Invalid 'fillchar': expected single character", pcall_err(meths.eval_statusline, '', { fillchar = 'aa' })) end) it('rejects empty string fillchar', function() - eq('fillchar must be a single character', + eq("Invalid 'fillchar': expected single character", pcall_err(meths.eval_statusline, '', { fillchar = '' })) end) it('rejects non-string fillchar', function() - eq('fillchar must be a single character', + eq("Invalid 'fillchar': expected String, got Integer", pcall_err(meths.eval_statusline, '', { fillchar = 1 })) end) it('rejects invalid string', function() diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua index 5f87c3cdd9..19611429e0 100644 --- a/test/functional/ex_cmds/oldfiles_spec.lua +++ b/test/functional/ex_cmds/oldfiles_spec.lua @@ -2,6 +2,8 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear +local command = helpers.command +local expect_exit = helpers.expect_exit local buf, eq, feed_command = helpers.curbufmeths, helpers.eq, helpers.feed_command local feed, poke_eventloop = helpers.feed, helpers.poke_eventloop local ok = helpers.ok @@ -19,6 +21,7 @@ describe(':oldfiles', function() before_each(_clear) after_each(function() + expect_exit(command, 'qall!') os.remove(shada_file) end) @@ -42,6 +45,7 @@ describe(':oldfiles', function() | Press ENTER or type command to continue^ | ]]) + feed('<CR>') end) it('can be filtered with :filter', function() @@ -107,6 +111,7 @@ describe(':browse oldfiles', function() end) after_each(function() + expect_exit(command, 'qall!') os.remove(shada_file) end) diff --git a/test/functional/ex_cmds/profile_spec.lua b/test/functional/ex_cmds/profile_spec.lua index 2b92f8d0de..bf045a4d1d 100644 --- a/test/functional/ex_cmds/profile_spec.lua +++ b/test/functional/ex_cmds/profile_spec.lua @@ -30,6 +30,7 @@ describe(':profile', function() before_each(helpers.clear) after_each(function() + helpers.expect_exit(command, 'qall!') if lfs.attributes(tempfile, 'uid') ~= nil then os.remove(tempfile) end diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua index 8eed00c973..ad59025d47 100644 --- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua +++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua @@ -13,6 +13,7 @@ local nvim_prog = helpers.nvim_prog local ok = helpers.ok local rmdir = helpers.rmdir local new_argv = helpers.new_argv +local new_pipename = helpers.new_pipename local pesc = helpers.pesc local os_kill = helpers.os_kill local set_session = helpers.set_session @@ -37,10 +38,21 @@ describe(':recover', function() end) -describe(':preserve', function() +describe("preserve and (R)ecover with custom 'directory'", function() local swapdir = lfs.currentdir()..'/Xtest_recover_dir' + local testfile = 'Xtest_recover_file1' + -- Put swapdir at the start of the 'directory' list. #1836 + -- Note: `set swapfile` *must* go after `set directory`: otherwise it may + -- attempt to create a swapfile in different directory. + local init = [[ + set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[// + set swapfile fileformat=unix undolevels=-1 + ]] + + local nvim1 before_each(function() - clear() + nvim1 = spawn(new_argv()) + set_session(nvim1) rmdir(swapdir) lfs.mkdir(swapdir) end) @@ -49,25 +61,15 @@ describe(':preserve', function() rmdir(swapdir) end) - it("saves to custom 'directory' and (R)ecovers #1836", function() - local testfile = 'Xtest_recover_file1' - -- Put swapdir at the start of the 'directory' list. #1836 - -- Note: `set swapfile` *must* go after `set directory`: otherwise it may - -- attempt to create a swapfile in different directory. - local init = [[ - set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[// - set swapfile fileformat=unix undolevels=-1 - ]] - + local function setup_swapname() exec(init) command('edit! '..testfile) feed('isometext<esc>') - command('preserve') exec('redir => g:swapname | silent swapname | redir END') + return eval('g:swapname') + end - local swappath1 = eval('g:swapname') - - os_kill(eval('getpid()')) + local function test_recover(swappath1) -- Start another Nvim instance. local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'}, true) @@ -90,6 +92,35 @@ describe(':preserve', function() -- Verify that :swapname was not truncated (:help 'shortmess'). ok(nil == string.find(swappath1, '%.%.%.')) ok(nil == string.find(swappath2, '%.%.%.')) + end + + it('with :preserve and SIGKILL', function() + local swappath1 = setup_swapname() + command('preserve') + os_kill(eval('getpid()')) + test_recover(swappath1) + end) + + it('closing stdio channel without :preserve #22096', function() + local swappath1 = setup_swapname() + nvim1:close() + test_recover(swappath1) + end) + + it('killing TUI process without :preserve #22096', function() + helpers.skip(helpers.is_os('win')) + local screen = Screen.new() + screen:attach() + local child_server = new_pipename() + funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server}) + screen:expect({any = pesc('[No Name]')}) -- Wait for the child process to start. + local child_session = helpers.connect(child_server) + set_session(child_session) + local swappath1 = setup_swapname() + set_session(nvim1) + command('call chanclose(&channel)') -- Kill the child process. + screen:expect({any = pesc('[Process exited 1]')}) -- Wait for the child process to stop. + test_recover(swappath1) end) end) diff --git a/test/functional/legacy/search_stat_spec.lua b/test/functional/legacy/search_stat_spec.lua index 9fcf798836..06e0b2320a 100644 --- a/test/functional/legacy/search_stat_spec.lua +++ b/test/functional/legacy/search_stat_spec.lua @@ -1,7 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, exec, command = helpers.clear, helpers.feed, helpers.exec, helpers.command -local poke_eventloop = helpers.poke_eventloop describe('search stat', function() local screen @@ -80,12 +79,11 @@ describe('search stat', function() {1:~ }| /foo [1/2] | ]]) + -- Note: there is an intermediate state where the search stat disappears. feed('n') - poke_eventloop() - screen:expect_unchanged() + screen:expect_unchanged(true) feed('n') - poke_eventloop() - screen:expect_unchanged() + screen:expect_unchanged(true) end) -- oldtest: Test_search_stat_then_gd() diff --git a/test/functional/lua/api_spec.lua b/test/functional/lua/api_spec.lua index 03832978a4..dc6452dd62 100644 --- a/test/functional/lua/api_spec.lua +++ b/test/functional/lua/api_spec.lua @@ -33,7 +33,7 @@ describe('luaeval(vim.api.…)', function() describe('with errors', function() it('transforms API error from nvim_buf_set_lines into lua error', function() funcs.setline(1, {"abc", "def", "a\nb", "ttt"}) - eq({false, 'String cannot contain newlines'}, + eq({false, "'replacement string' item contains newlines"}, funcs.luaeval('{pcall(vim.api.nvim_buf_set_lines, 1, 1, 2, false, {"b\\na"})}')) end) diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index 2a7be53164..add69235b6 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -94,6 +94,26 @@ describe('vim.filetype', function() return vim.filetype.match({ buf = 0 }) ]]) end) + + it('works with contents #22180', function() + eq('sh', exec_lua [[ + -- Needs to be set so detect#sh doesn't fail + vim.g.ft_ignore_pat = '\\.\\(Z\\|gz\\|bz2\\|zip\\|tgz\\)$' + return vim.filetype.match({ contents = { '#!/usr/bin/env bash' } }) + ]]) + end) + + it('considers extension mappings when matching from hashbang', function() + eq('fooscript', exec_lua [[ + vim.filetype.add({ + extension = { + foo = 'fooscript', + } + }) + return vim.filetype.match({ contents = { '#!/usr/bin/env foo' } }) + ]]) + end) + end) describe('filetype.lua', function() diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 6481da900e..de436771f9 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -77,13 +77,8 @@ describe('vim.ui_attach', function() } feed '<c-y>' - screen:expect{grid=[[ - foobar^ | - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]], intermediate=true} + -- There is an intermediate state where the 'showmode' message disappears. + screen:expect_unchanged(true) expect_events { { "popupmenu_hide" }; } diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 867f366d06..b43e5b28db 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -1458,7 +1458,7 @@ describe('lua stdlib', function() ]] eq('', funcs.luaeval "vim.bo.filetype") eq(true, funcs.luaeval "vim.bo[BUF].modifiable") - matches("no such option: 'nosuchopt'$", + matches("Invalid option %(not found%): 'nosuchopt'$", pcall_err(exec_lua, 'return vim.bo.nosuchopt')) matches("Expected lua string$", pcall_err(exec_lua, 'return vim.bo[0][0].autoread')) @@ -1479,7 +1479,7 @@ describe('lua stdlib', function() eq(0, funcs.luaeval "vim.wo.cole") eq(0, funcs.luaeval "vim.wo[0].cole") eq(0, funcs.luaeval "vim.wo[1001].cole") - matches("no such option: 'notanopt'$", + matches("Invalid option %(not found%): 'notanopt'$", pcall_err(exec_lua, 'return vim.wo.notanopt')) matches("Expected lua string$", pcall_err(exec_lua, 'return vim.wo[0][0].list')) diff --git a/test/functional/shada/helpers.lua b/test/functional/shada/helpers.lua index fb3ec4a87c..cd99d38345 100644 --- a/test/functional/shada/helpers.lua +++ b/test/functional/shada/helpers.lua @@ -33,6 +33,7 @@ local function reset(o) end local clear = function() + helpers.expect_exit(helpers.command, 'qall!') os.remove(tmpname) end diff --git a/test/functional/shada/history_spec.lua b/test/functional/shada/history_spec.lua index d1daf6c7cc..aa4106ad63 100644 --- a/test/functional/shada/history_spec.lua +++ b/test/functional/shada/history_spec.lua @@ -32,7 +32,6 @@ describe('ShaDa support code', function() nvim_command('rshada') eq('" Test 2', funcs.histget(':', -1)) eq('" Test', funcs.histget(':', -2)) - expect_exit(nvim_command, 'qall') end) it('respects &history when dumping', diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua index 7b1ce5d0ca..24bd363e95 100644 --- a/test/functional/shada/shada_spec.lua +++ b/test/functional/shada/shada_spec.lua @@ -136,24 +136,6 @@ describe('ShaDa support code', function() eq(#msgpack, found) end) - it('does not write NONE file', function() - local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', - '--headless', '--cmd', 'qall'}, true) - session:close() - eq(nil, lfs.attributes('NONE')) - eq(nil, lfs.attributes('NONE.tmp.a')) - end) - - it('does not read NONE file', function() - write_file('NONE', '\005\001\015\131\161na\162rX\194\162rc\145\196\001-') - local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', - '--headless'}, true) - set_session(session) - eq('', funcs.getreg('a')) - session:close() - os.remove('NONE') - end) - local marklike = {[7]=true, [8]=true, [10]=true, [11]=true} local find_file = function(fname) local found = {} @@ -263,3 +245,23 @@ describe('ShaDa support code', function() meths.set_option('shada', '') end) end) + +describe('ShaDa support code', function() + it('does not write NONE file', function() + local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', + '--headless', '--cmd', 'qall'}, true) + session:close() + eq(nil, lfs.attributes('NONE')) + eq(nil, lfs.attributes('NONE.tmp.a')) + end) + + it('does not read NONE file', function() + write_file('NONE', '\005\001\015\131\161na\162rX\194\162rc\145\196\001-') + local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', + '--headless'}, true) + set_session(session) + eq('', funcs.getreg('a')) + session:close() + os.remove('NONE') + end) +end) diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 7294969ac8..4e62354ed8 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -2365,18 +2365,18 @@ describe("TUI as a client", function() set_session(client_super) local screen_client = thelpers.screen_setup(0, - string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "%s", "--remote-ui"]]=], + string.format([=[["%s", "--server", "%s", "--remote-ui"]]=], nvim_prog, server_pipe)) - screen_client:expect{grid=[[ - Hello, Worl{1:d} | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] [+] }| - | - {3:-- TERMINAL --} | - ]]} + screen_client:expect{grid=[[ + Hello, Worl{1:d} | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]} feed_data(":q!\n") @@ -2394,7 +2394,7 @@ describe("TUI as a client", function() set_session(client_super) local screen = thelpers.screen_setup(0, - string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "%s", "--remote-ui"]]=], + string.format([=[["%s", "--server", "%s", "--remote-ui"]]=], nvim_prog, server_pipe)) screen:expect{grid=[[ @@ -2412,15 +2412,19 @@ describe("TUI as a client", function() exec_lua([[vim.loop.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]]) screen:expect({any = '%[Process exited 1%]'}) + eq(0, meths.get_vvar('shell_error')) + -- exits on input eof #22244 + funcs.system({nvim_prog, '--server', server_pipe, '--remote-ui'}) + eq(1, meths.get_vvar('shell_error')) + client_super:close() server:close() end) - it("throws error when no server exists", function() clear() local screen = thelpers.screen_setup(0, - string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "127.0.0.1:2436546", "--remote-ui"]]=], + string.format([=[["%s", "--server", "127.0.0.1:2436546", "--remote-ui"]]=], nvim_prog), 60) screen:expect([[ @@ -2467,7 +2471,7 @@ describe("TUI as a client", function() set_session(client_super) local screen_client = thelpers.screen_setup(0, - string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "%s", "--remote-ui"]]=], + string.format([=[["%s", "--server", "%s", "--remote-ui"]]=], nvim_prog, server_pipe)) screen_client:expect{grid=[[ diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua index df45c9b384..51d8eb62f3 100644 --- a/test/functional/treesitter/language_spec.lua +++ b/test/functional/treesitter/language_spec.lua @@ -82,7 +82,7 @@ describe('treesitter language API', function() command("set filetype=borklang") -- Should throw an error when filetype changes to borklang eq(".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", - pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0)")) + pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')")) end) it('retrieve the tree given a range', function () diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua index 46bfae8de2..418294ac07 100644 --- a/test/functional/ui/bufhl_spec.lua +++ b/test/functional/ui/bufhl_spec.lua @@ -751,8 +751,8 @@ describe('Buffer highlighting', function() it('validates contents', function() -- this used to leak memory - eq('Chunk is not an array', pcall_err(set_virtual_text, id1, 0, {"texty"}, {})) - eq('Chunk is not an array', pcall_err(set_virtual_text, id1, 0, {{"very"}, "texty"}, {})) + eq("Invalid 'chunk': expected Array, got String", pcall_err(set_virtual_text, id1, 0, {"texty"}, {})) + eq("Invalid 'chunk': expected Array, got String", pcall_err(set_virtual_text, id1, 0, {{"very"}, "texty"}, {})) end) it('can be retrieved', function() diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index 46a478c1ea..c8a3397a86 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -29,8 +29,6 @@ describe("folded lines", function() local function with_ext_multigrid(multigrid) local screen before_each(function() - clear() - command('hi VertSplit gui=reverse') screen = Screen.new(45, 8) screen:attach({rgb=true, ext_multigrid=multigrid}) screen:set_default_attr_ids({ @@ -90,10 +88,10 @@ describe("folded lines", function() end) it("highlights with CursorLineFold when 'cursorline' is set", function() - command("set cursorline foldcolumn=2 foldmethod=marker") + command("set number cursorline foldcolumn=2") command("hi link CursorLineFold Search") insert(content1) - feed("zf3j") + feed("ggzf3jj") if multigrid then screen:expect([[ ## grid 1 @@ -106,26 +104,26 @@ describe("folded lines", function() [2:---------------------------------------------]| [3:---------------------------------------------]| ## grid 2 - {7: }This is a | - {7: }valid English | - {7: }sentence composed by | - {7: }an exhausted developer | - {7: }in his cave. | - {6: }{12:^ }| + {7:+ }{8: 1 }{5:+-- 4 lines: This is a················}| + {6: }{9: 5 }{12:^in his cave. }| + {7: }{8: 6 } | + {1:~ }| + {1:~ }| + {1:~ }| {1:~ }| ## grid 3 | ]]) else screen:expect([[ - {7: }This is a | - {7: }valid English | - {7: }sentence composed by | - {7: }an exhausted developer | - {7: }in his cave. | - {6: }{12:^ }| - {1:~ }| - | + {7:+ }{8: 1 }{5:+-- 4 lines: This is a················}| + {6: }{9: 5 }{12:^in his cave. }| + {7: }{8: 6 } | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | ]]) end feed("k") @@ -141,28 +139,34 @@ describe("folded lines", function() [2:---------------------------------------------]| [3:---------------------------------------------]| ## grid 2 - {7: }This is a | - {7: }valid English | - {7: }sentence composed by | - {7: }an exhausted developer | - {6: }{12:^in his cave. }| - {7: } | + {6:+ }{9: 1 }{12:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }| + {1:~ }| + {1:~ }| {1:~ }| ## grid 3 | ]]) else screen:expect([[ - {7: }This is a | - {7: }valid English | - {7: }sentence composed by | - {7: }an exhausted developer | - {6: }{12:^in his cave. }| - {7: } | - {1:~ }| - | + {6:+ }{9: 1 }{12:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | ]]) end + -- CursorLine is applied correctly with screenrow motions #22232 + feed("jgk") + screen:expect_unchanged(true) + -- CursorLine is applied correctly when closing a fold when cursor is not at fold start + feed("zo4Gzc") + screen:expect_unchanged(true) command("set cursorlineopt=line") if multigrid then screen:expect([[ @@ -176,26 +180,61 @@ describe("folded lines", function() [2:---------------------------------------------]| [3:---------------------------------------------]| ## grid 2 - {7: }This is a | - {7: }valid English | - {7: }sentence composed by | - {7: }an exhausted developer | - {7: }{12:^in his cave. }| - {7: } | + {7:+ }{8: 1 }{12:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }| + {1:~ }| + {1:~ }| {1:~ }| ## grid 3 | ]]) else screen:expect([[ - {7: }This is a | - {7: }valid English | - {7: }sentence composed by | - {7: }an exhausted developer | - {7: }{12:^in his cave. }| - {7: } | - {1:~ }| - | + {7:+ }{8: 1 }{12:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + end + command("set relativenumber cursorlineopt=number") + if multigrid then + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]| + [2:---------------------------------------------]| + [2:---------------------------------------------]| + [2:---------------------------------------------]| + [2:---------------------------------------------]| + [2:---------------------------------------------]| + [2:---------------------------------------------]| + [3:---------------------------------------------]| + ## grid 2 + {6:+ }{9:1 }{5:^+-- 4 lines: This is a················}| + {7: }{8: 1 }in his cave. | + {7: }{8: 2 } | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + ]]) + else + screen:expect([[ + {6:+ }{9:1 }{5:^+-- 4 lines: This is a················}| + {7: }{8: 1 }in his cave. | + {7: }{8: 2 } | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | ]]) end end) diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 6fbf9b72c8..96634be327 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -2886,7 +2886,8 @@ it(':substitute with inccommand during :terminal activity', function() feed('gg') feed(':%s/foo/ZZZ') sleep(20) -- Allow some terminal activity. - helpers.poke_eventloop() + poke_eventloop() + screen:sleep(0) screen:expect_unchanged() end) end) diff --git a/test/functional/ui/multibyte_spec.lua b/test/functional/ui/multibyte_spec.lua index d4e237bcb4..9f413f8bff 100644 --- a/test/functional/ui/multibyte_spec.lua +++ b/test/functional/ui/multibyte_spec.lua @@ -158,6 +158,7 @@ describe('multibyte rendering: statusline', function() screen:set_default_attr_ids({ [1] = {bold = true, foreground = Screen.colors.Blue1}, [2] = {bold = true, reverse = true}, + [3] = {background = Screen.colors.Red, foreground = Screen.colors.Gray100}; }) screen:attach() command('set laststatus=2') @@ -220,4 +221,27 @@ describe('multibyte rendering: statusline', function() | ]]} end) + + it('unprintable chars in filename with default stl', function() + command("file 🧑💻") + -- TODO: this is wrong but avoids a crash + screen:expect{grid=[[ + ^ | + {1:~ }| + {2:🧑�💻 }| + | + ]]} + end) + + it('unprintable chars in filename with custom stl', function() + command('set statusline=xx%#ErrorMsg#%f%##yy') + command("file 🧑💻") + -- TODO: this is also wrong but also avoids a crash + screen:expect{grid=[[ + ^ | + {1:~ }| + {2:xx}{3:🧑<200d>💻}{2:yy }| + | + ]]} + end) end) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 3b9cce0e6f..7760f26fca 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -214,7 +214,7 @@ function Screen:attach(options, session) -- simplify test code by doing the same. self._options.rgb = true end - if self._options.ext_multigrid or self._options.ext_float then + if self._options.ext_multigrid then self._options.ext_linegrid = true end end @@ -470,15 +470,19 @@ screen:redraw_debug() to show all intermediate screen states. ]]) end, expected) end -function Screen:expect_unchanged(waittime_ms, ignore_attrs, request_cb) +function Screen:expect_unchanged(intermediate, waittime_ms, ignore_attrs) waittime_ms = waittime_ms and waittime_ms or 100 -- Collect the current screen state. - self:sleep(0, request_cb) local kwargs = self:get_snapshot(nil, ignore_attrs) - -- Check that screen state does not change. - kwargs.unchanged = true + if intermediate then + kwargs.intermediate = true + else + kwargs.unchanged = true + end + kwargs.timeout = waittime_ms + -- Check that screen state does not change. self:expect(kwargs) end diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 3bd2289a73..439021ad87 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -61,6 +61,7 @@ local function screen_tests(linegrid) [5] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Fuchsia}, [6] = {bold = true, foreground = Screen.colors.Fuchsia}, [7] = {bold = true, foreground = Screen.colors.SeaGreen}, + [8] = {foreground = Screen.colors.White, background = Screen.colors.Red}, } ) end) @@ -866,12 +867,9 @@ local function screen_tests(linegrid) end) describe('resize', function() - before_each(function() + it('rebuilds the whole screen', function() screen:try_resize(25, 5) feed('iresize') - end) - - it('rebuilds the whole screen', function() screen:expect([[ resize^ | {0:~ }| @@ -882,6 +880,7 @@ local function screen_tests(linegrid) end) it('has minimum width/height values', function() + feed('iresize') screen:try_resize(1, 1) screen:expect([[ resize^ | @@ -896,7 +895,8 @@ local function screen_tests(linegrid) end) it('VimResized autocommand does not cause invalid UI events #20692 #20759', function() - feed('<Esc>') + screen:try_resize(25, 5) + feed('iresize<Esc>') command([[autocmd VimResized * redrawtabline]]) command([[autocmd VimResized * lua vim.api.nvim_echo({ { 'Hello' } }, false, {})]]) command([[autocmd VimResized * let g:echospace = v:echospace]]) @@ -919,6 +919,77 @@ local function screen_tests(linegrid) ]]) eq(29, meths.get_var('echospace')) end) + + it('messages from the same Ex command as resize are visible #22225', function() + feed(':set columns=20 | call<CR>') + screen:expect([[ + | + | + | + | + | + | + | + | + | + {1: }| + {8:E471: Argument requi}| + {8:red} | + {7:Press ENTER or type }| + {7:command to continue}^ | + ]]) + feed('<CR>') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + feed(':set columns=0<CR>') + screen:expect([[ + | + | + | + | + | + {1: }| + {8:E594: Need a}| + {8:t least 12 c}| + {8:olumns: colu}| + {8:mns=0} | + {7:Press ENTER }| + {7:or type comm}| + {7:and to conti}| + {7:nue}^ | + ]]) + feed('<CR>') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) end) describe('press enter', function() diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 18bbb56a61..916a5eb537 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -10,7 +10,6 @@ local testprg = helpers.testprg describe('search highlighting', function() local screen - local colors = Screen.colors before_each(function() clear() @@ -18,9 +17,9 @@ describe('search highlighting', function() screen:attach() screen:set_default_attr_ids( { [1] = {bold=true, foreground=Screen.colors.Blue}, - [2] = {background = colors.Yellow}, -- Search + [2] = {background = Screen.colors.Yellow}, -- Search [3] = {reverse = true}, - [4] = {foreground = colors.Red}, -- Message + [4] = {foreground = Screen.colors.Red}, -- Message [6] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGrey}, -- Folded }) end) @@ -318,6 +317,7 @@ describe('search highlighting', function() ]]) feed('/foo') helpers.poke_eventloop() + screen:sleep(0) screen:expect_unchanged() end) @@ -498,6 +498,20 @@ describe('search highlighting', function() {1:~ }│{1:~ }| //^ | ]]) + feed('<Esc>') + + -- incsearch works after c_CTRL-R_CTRL-R + command('let @" = "file"') + feed('/<C-R><C-R>"') + screen:expect([[ + the first line │the first line | + in a little {3:file} │in a little {2:file} | + {1:~ }│{1:~ }| + {1:~ }│{1:~ }| + {1:~ }│{1:~ }| + {1:~ }│{1:~ }| + /file^ | + ]]) end) it('works with incsearch and offset', function() @@ -572,12 +586,12 @@ describe('search highlighting', function() it('works with matchadd and syntax', function() screen:set_default_attr_ids { [1] = {bold=true, foreground=Screen.colors.Blue}; - [2] = {background = colors.Yellow}; + [2] = {background = Screen.colors.Yellow}; [3] = {reverse = true}; - [4] = {foreground = colors.Red}; - [5] = {bold = true, background = colors.Green}; - [6] = {italic = true, background = colors.Magenta}; - [7] = {bold = true, background = colors.Yellow}; + [4] = {foreground = Screen.colors.Red}; + [5] = {bold = true, background = Screen.colors.Green}; + [6] = {italic = true, background = Screen.colors.Magenta}; + [7] = {bold = true, background = Screen.colors.Yellow}; [8] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGray}; } feed_command('set hlsearch') diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua index 3233e6cd19..287686cf37 100644 --- a/test/functional/ui/statuscolumn_spec.lua +++ b/test/functional/ui/statuscolumn_spec.lua @@ -456,7 +456,7 @@ describe('statuscolumn', function() 14 aaaaa | | ]]) - command('set stc=') -- also for the default sign column + command('set stc=') -- also for the default fold column screen:expect_unchanged() -- 'statuscolumn' is not too wide with custom (bogus) fold column command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]]) diff --git a/test/functional/vimscript/timer_spec.lua b/test/functional/vimscript/timer_spec.lua index 1818a71ea2..a58cd6ae7f 100644 --- a/test/functional/vimscript/timer_spec.lua +++ b/test/functional/vimscript/timer_spec.lua @@ -251,15 +251,7 @@ describe('timers', function() :good^ | ]]) command('let g:val = 1') - - screen:expect{grid=[[ - | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - :good^ | - ]], intermediate=true, timeout=load_adjust(200)} + screen:expect_unchanged(true, load_adjust(200)) eq(2, eval('g:val')) end) |