diff options
245 files changed, 4483 insertions, 3621 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index f602a2c1df..a1264ca608 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -14,7 +14,7 @@ freebsd_task: build_deps_script: - gmake deps build_script: - - gmake nvim + - gmake CMAKE_EXTRA_FLAGS="-DCI_BUILD=ON" nvim workaround_script: # Run tests as user "cirrus" instead of root. This is required for the # permission-related tests to work correctly. diff --git a/.github/scripts/build_universal_macos.sh b/.github/scripts/build_universal_macos.sh index 003be75de8..4dfe0d0cf8 100755 --- a/.github/scripts/build_universal_macos.sh +++ b/.github/scripts/build_universal_macos.sh @@ -23,9 +23,17 @@ echo "Build release" cd "$GITHUB_WORKSPACE" MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -f1 -d.)" export MACOSX_DEPLOYMENT_TARGET -cmake -S cmake.deps -B .deps -G Ninja -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64 +cmake -S cmake.deps -B .deps -G Ninja \ + -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} \ + -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} \ + -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64 \ + -D CMAKE_FIND_FRAMEWORK=NEVER cmake --build .deps -cmake -B build -G Ninja -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64 -D CI_BUILD=OFF +cmake -B build -G Ninja \ + -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} \ + -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} \ + -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64 \ + -D CMAKE_FIND_FRAMEWORK=NEVER cmake --build build cmake --install build --prefix build/release/nvim-macos cd build diff --git a/.github/scripts/reviews.js b/.github/scripts/reviews.js index 2aeedd0c81..29b7c4019d 100644 --- a/.github/scripts/reviews.js +++ b/.github/scripts/reviews.js @@ -7,17 +7,17 @@ module.exports = async ({github, context}) => { const labels = pr_data.data.labels.map(e => e.name) const reviewers = new Set() - const team_reviewers = new Array() + const team_reviewers = new Set() if (labels.includes('api')) { reviewers.add("bfredl") } if (labels.includes('build')) { - team_reviewers.push('ci'); + team_reviewers.add('ci'); } if (labels.includes('ci')) { - team_reviewers.push('ci'); + team_reviewers.add('ci'); } if (labels.includes('column')) { @@ -55,7 +55,7 @@ module.exports = async ({github, context}) => { } if (labels.includes('lsp')) { - team_reviewers.push('lsp'); + team_reviewers.add('lsp'); } if (labels.includes('platform:nix')) { @@ -72,7 +72,7 @@ module.exports = async ({github, context}) => { } if (labels.includes('treesitter')) { - team_reviewers.push('treesitter'); + team_reviewers.add('treesitter'); } if (labels.includes('typo')) { @@ -97,6 +97,6 @@ module.exports = async ({github, context}) => { repo: context.repo.repo, pull_number: context.issue.number, reviewers: Array.from(reviewers), - team_reviewers: team_reviewers + team_reviewers: Array.from(team_reviewers) }); } diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 414fe1f1d6..020cbd51bd 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -8,15 +8,9 @@ jobs: contents: write pull-requests: write name: Backport Pull Request - if: > - github.repository_owner == 'neovim' && ( - github.event_name == 'pull_request_target' && - github.event.pull_request.merged - ) + if: github.event.pull_request.merged runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - name: Create backport PRs uses: korthout/backport-action@v1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa1f74e4d1..be0f2f812c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -67,7 +67,7 @@ jobs: run: make deps - name: Build - run: make CMAKE_FLAGS="-D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX" + run: make CMAKE_FLAGS="-D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX" - name: Install run: make install diff --git a/.github/workflows/notes.md b/.github/workflows/notes.md index d752f10609..2b34c72ffa 100644 --- a/.github/workflows/notes.md +++ b/.github/workflows/notes.md @@ -27,18 +27,6 @@ ${NVIM_VERSION} ### Linux (x64) -#### Tarball - -1. Download **nvim-linux64.tar.gz** -2. Extract: `tar xzvf nvim-linux64.tar.gz` -3. Run `./nvim-linux64/bin/nvim` - -#### Debian Package - -1. Download **nvim-linux64.deb** -2. Install the package using `sudo apt install ./nvim-linux64.deb` -3. Run `nvim` - #### AppImage 1. Download **nvim.appimage** 2. Run `chmod u+x nvim.appimage && ./nvim.appimage` @@ -48,6 +36,14 @@ ${NVIM_VERSION} ./squashfs-root/usr/bin/nvim ``` +#### Tarball + +*(deprecated)* + +1. Download **nvim-linux64.tar.gz** +2. Extract: `tar xzvf nvim-linux64.tar.gz` +3. Run `./nvim-linux64/bin/nvim` + ### Other - Install by [package manager](https://github.com/neovim/neovim/wiki/Installing-Neovim) @@ -56,7 +52,6 @@ ${NVIM_VERSION} ``` ${SHA_LINUX_64_TAR} -${SHA_LINUX_64_DEB} ${SHA_APP_IMAGE} ${SHA_APP_IMAGE_ZSYNC} ${SHA_MACOS} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b3a32600dd..c6d0c39402 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: - name: Build release id: build run: | - CC=gcc-10 make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} CMAKE_EXTRA_FLAGS="-DCI_BUILD=OFF -DCMAKE_INSTALL_PREFIX:PATH=" + CC=gcc-10 make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH=" printf 'version<<END\n' >> $GITHUB_OUTPUT ./build/bin/nvim --version | head -n 3 >> $GITHUB_OUTPUT printf 'END\n' >> $GITHUB_OUTPUT @@ -46,7 +46,6 @@ jobs: name: nvim-linux64 path: | build/nvim-linux64.tar.gz - build/nvim-linux64.deb retention-days: 1 appimage: @@ -127,7 +126,7 @@ jobs: cmake --build .deps - name: build package run: | - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE='RelWithDebInfo' -D CI_BUILD=OFF + cmake -B build -G Ninja -DCMAKE_BUILD_TYPE='RelWithDebInfo' cmake --build build --target package - uses: actions/upload-artifact@v3 with: @@ -182,8 +181,6 @@ jobs: cd ./nvim-linux64 sha256sum nvim-linux64.tar.gz > nvim-linux64.tar.gz.sha256sum echo "SHA_LINUX_64_TAR=$(cat nvim-linux64.tar.gz.sha256sum)" >> $GITHUB_ENV - sha256sum nvim-linux64.deb > nvim-linux64.deb.sha256sum - echo "SHA_LINUX_64_DEB=$(cat nvim-linux64.deb.sha256sum)" >> $GITHUB_ENV - name: Generate App Image SHA256 checksums run: | cd ./appimage @@ -228,13 +225,15 @@ jobs: identifier: Neovim.Neovim release-tag: ${{ github.event.inputs.tag_name || github.ref_name }} token: ${{ secrets.WINGET_TOKEN }} + - name: Fetch nightly build msi from previous job + if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly') + uses: actions/download-artifact@v3 - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly') - name: Get nightly version + name: Get version from nightly build msi id: get-version run: | - Invoke-WebRequest https://github.com/neovim/neovim/releases/download/nightly/nvim-win64.msi -OutFile setup.msi Install-Module -Name 'Carbon.Windows.Installer' -Force - $VERSION = (Get-CMsi (Resolve-Path .\setup.msi).Path).ProductVersion + $VERSION = (Get-CMsi (Resolve-Path .\nvim-win64\nvim-win64.msi).Path).ProductVersion "version=$VERSION" >> $env:GITHUB_OUTPUT - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly') name: Publish nightly diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0d18f874c4..8215a79b35 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -76,7 +76,7 @@ jobs: - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: configure - run: cmake -B build -G Ninja -D CI_BUILD=OFF + run: cmake -B build -G Ninja - if: "!cancelled()" name: Determine if run should be aborted @@ -143,6 +143,8 @@ jobs: flags: -D UNSIGNED_CHAR=ON - cc: clang runner: macos-12 + flags: -D CMAKE_FIND_FRAMEWORK=NEVER + deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER # functionaltest-lua is our dumping ground for non-mainline configurations. # 1. Check that the tests pass with PUC Lua instead of LuaJIT. @@ -197,7 +199,7 @@ jobs: - name: Build run: | - cmake -B build -G Ninja -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.flags }} + cmake -B build -G Ninja -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.flags }} -D CI_BUILD=ON cmake --build build - if: "!cancelled()" @@ -276,7 +278,7 @@ jobs: cmake --build .deps - name: Configure - run: cmake -B build -G "Ninja Multi-Config" -D CMAKE_C_COMPILER=gcc + run: cmake -B build -G "Ninja Multi-Config" -D CMAKE_C_COMPILER=gcc -D CI_BUILD=ON - name: Release run: cmake --build build --config Release @@ -313,7 +315,7 @@ jobs: - name: Build run: | - cmake -B build -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' + cmake -B build -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' -D CI_BUILD=ON cmake --build build - name: Install test deps @@ -376,13 +378,13 @@ jobs: libluajit-5.1-dev \ libmsgpack-dev \ libtermkey-dev \ - libtree-sitter-dev \ libunibilium-dev \ libuv1-dev \ lua-filesystem \ lua-lpeg \ lua-mpack \ luajit + # libtree-sitter-dev \ # libvterm-dev \ # lua-luv-dev @@ -397,10 +399,13 @@ jobs: # 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 -G Ninja -D USE_BUNDLED=OFF -D USE_BUNDLED_LUV=ON -D USE_BUNDLED_LIBVTERM=ON + cmake -S cmake.deps -B .deps -G Ninja -D USE_BUNDLED=OFF \ + -D USE_BUNDLED_LUV=ON \ + -D USE_BUNDLED_LIBVTERM=ON \ + -D USE_BUNDLED_TS=ON cmake --build .deps - name: Build run: | - cmake -B build -G Ninja + cmake -B build -G Ninja -D CI_BUILD=ON cmake --build build diff --git a/CMakeLists.txt b/CMakeLists.txt index 262af9ab55..bfc8a2283f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,14 +105,14 @@ set_default_buildtype() # If not in a git repo (e.g., a tarball) these tokens define the complete # version string, else they are combined with the result of `git describe`. set(NVIM_VERSION_MAJOR 0) -set(NVIM_VERSION_MINOR 9) +set(NVIM_VERSION_MINOR 10) set(NVIM_VERSION_PATCH 0) set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers # API level -set(NVIM_API_LEVEL 11) # Bump this after any API change. +set(NVIM_API_LEVEL 11) # Bump this after any API change. set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change. -set(NVIM_API_PRERELEASE true) +set(NVIM_API_PRERELEASE false) # Default to -O2 on release builds. if(CMAKE_C_FLAGS_RELEASE MATCHES "-O3") @@ -131,7 +131,7 @@ functionaltest-lua: | nvim FORMAT=formatc formatlua format LINT=lintlua lintsh lintc clang-tidy lintcommit lint TEST=functionaltest unittest -generated-sources benchmark uninstall $(FORMAT) $(LINT) $(TEST): | build/.ran-cmake +generated-sources benchmark $(FORMAT) $(LINT) $(TEST): | build/.ran-cmake $(CMAKE_PRG) --build build --target $@ test: $(TEST) diff --git a/cmake.deps/CMakeLists.txt b/cmake.deps/CMakeLists.txt index 4659183d19..5ac34cbf26 100644 --- a/cmake.deps/CMakeLists.txt +++ b/cmake.deps/CMakeLists.txt @@ -17,7 +17,8 @@ set(DEPS_CMAKE_ARGS -D CMAKE_C_STANDARD=99 -D CMAKE_GENERATOR=${CMAKE_GENERATOR} -D CMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} - -D CMAKE_POSITION_INDEPENDENT_CODE=ON) + -D CMAKE_POSITION_INDEPENDENT_CODE=ON + -D CMAKE_FIND_FRAMEWORK=${CMAKE_FIND_FRAMEWORK}) set(DEPS_CMAKE_CACHE_ARGS -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}) @@ -187,21 +188,16 @@ set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc891 set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.20.2.tar.gz) set(TREESITTER_C_SHA256 af66fde03feb0df4faf03750102a0d265b007e5d957057b6b293c13116a70af2 ) - set(TREESITTER_LUA_URL https://github.com/MunifTanjim/tree-sitter-lua/archive/v0.0.14.tar.gz) set(TREESITTER_LUA_SHA256 930d0370dc15b66389869355c8e14305b9ba7aafd36edbfdb468c8023395016d) - -set(TREESITTER_VIM_URL https://github.com/vigoux/tree-sitter-viml/archive/e39a7bbcfdcfc7900629962b785c7e14503ae590.tar.gz) -set(TREESITTER_VIM_SHA256 7ca85fa1a5a9e4d057ff3b7ae53d13d31371973e734ada87a83f3f6cbe9c0e32) - -set(TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/b2ec4ec5f7be24cb6f7ccffafd7204477fe5784a.tar.gz) -set(TREESITTER_VIMDOC_SHA256 0689a57d455243de6c6a6c8737a8ce137e225eb8f32676a7037f7dd13dfaec5d) - +set(TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.3.0.tar.gz) +set(TREESITTER_VIM_SHA256 403acec3efb7cdb18ff3d68640fc823502a4ffcdfbb71cec3f98aa786c21cbe2) +set(TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v2.0.0.tar.gz) +set(TREESITTER_VIMDOC_SHA256 1ff8f4afd3a9599dd4c3ce87c155660b078c1229704d1a254433e33794b8f274) set(TREESITTER_QUERY_URL https://github.com/nvim-treesitter/tree-sitter-query/archive/v0.1.0.tar.gz) set(TREESITTER_QUERY_SHA256 e2b806f80e8bf1c4f4e5a96248393fe6622fc1fc6189d6896d269658f67f914c) - -set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/a318b42c8b8594bd5ba1f571ab1d7a929198832c.tar.gz) -set(TREESITTER_SHA256 5f8224431afc36963477e9b69c8c3a31e8e306911185997932fa2cde7d0a2d18) +set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.20.8.tar.gz) +set(TREESITTER_SHA256 6181ede0b7470bfca37e293e7d5dc1d16469b9485d13f13a605baec4a8b1f791) if(USE_EXISTING_SRC_DIR) get_cmake_property(VARS VARIABLES) diff --git a/cmake.deps/cmake/BuildLibtermkey.cmake b/cmake.deps/cmake/BuildLibtermkey.cmake index 0f10c98194..0d2b66a060 100644 --- a/cmake.deps/cmake/BuildLibtermkey.cmake +++ b/cmake.deps/cmake/BuildLibtermkey.cmake @@ -4,7 +4,7 @@ ExternalProject_Add(libtermkey DOWNLOAD_NO_PROGRESS TRUE DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/libtermkey PATCH_COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/libtermkeyCMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibtermkeyCMakeLists.txt ${DEPS_BUILD_DIR}/src/libtermkey/CMakeLists.txt CMAKE_ARGS ${DEPS_CMAKE_ARGS} -D CMAKE_SHARED_LIBRARY_LINK_C_FLAGS="" # Hack to avoid -rdynamic in Mingw diff --git a/cmake.deps/cmake/BuildLuarocks.cmake b/cmake.deps/cmake/BuildLuarocks.cmake index 6e77fd7935..901d1f17da 100644 --- a/cmake.deps/cmake/BuildLuarocks.cmake +++ b/cmake.deps/cmake/BuildLuarocks.cmake @@ -98,22 +98,28 @@ elseif(USE_BUNDLED_LUA) endif() set(ROCKS_DIR ${DEPS_LIB_DIR}/luarocks/rocks-${LUA_VERSION}) +if(MSVC) + # Workaround for luarocks failing to find the md5sum.exe it is shipped with. + list(APPEND LUAROCKS_BUILDARGS MD5SUM=md5sum) + set(PATH PATH=${DEPS_INSTALL_DIR}/luarocks/tools;$ENV{PATH}) +endif() + # mpack add_custom_command(OUTPUT ${ROCKS_DIR}/mpack - COMMAND ${LUAROCKS_BINARY} build mpack 1.0.10-0 ${LUAROCKS_BUILDARGS} + COMMAND ${CMAKE_COMMAND} -E env "${PATH}" ${LUAROCKS_BINARY} build mpack 1.0.10-0 ${LUAROCKS_BUILDARGS} DEPENDS luarocks) add_custom_target(mpack ALL DEPENDS ${ROCKS_DIR}/mpack) # lpeg add_custom_command(OUTPUT ${ROCKS_DIR}/lpeg - COMMAND ${LUAROCKS_BINARY} build lpeg 1.0.2-1 ${LUAROCKS_BUILDARGS} + COMMAND ${CMAKE_COMMAND} -E env "${PATH}" ${LUAROCKS_BINARY} build lpeg 1.0.2-1 ${LUAROCKS_BUILDARGS} DEPENDS mpack) add_custom_target(lpeg ALL DEPENDS ${ROCKS_DIR}/lpeg) if((NOT USE_BUNDLED_LUAJIT) AND USE_BUNDLED_LUA) # luabitop add_custom_command(OUTPUT ${ROCKS_DIR}/luabitop - COMMAND ${LUAROCKS_BINARY} build luabitop 1.0.2-3 ${LUAROCKS_BUILDARGS} + COMMAND ${CMAKE_COMMAND} -E env "${PATH}" ${LUAROCKS_BINARY} build luabitop 1.0.2-3 ${LUAROCKS_BUILDARGS} DEPENDS lpeg) add_custom_target(luabitop ALL DEPENDS ${ROCKS_DIR}/luabitop) endif() @@ -134,20 +140,20 @@ if(USE_BUNDLED_BUSTED) set(LUACHECK_EXE "${DEPS_BIN_DIR}/luacheck") endif() add_custom_command(OUTPUT ${BUSTED_EXE} - COMMAND ${LUAROCKS_BINARY} build busted 2.1.1 ${LUAROCKS_BUILDARGS} + COMMAND ${CMAKE_COMMAND} -E env "${PATH}" ${LUAROCKS_BINARY} build busted 2.1.1 ${LUAROCKS_BUILDARGS} DEPENDS ${BUSTED_DEPENDS}) add_custom_target(busted ALL DEPENDS ${BUSTED_EXE}) # luacheck add_custom_command(OUTPUT ${LUACHECK_EXE} - COMMAND ${LUAROCKS_BINARY} build luacheck 1.1.0-1 ${LUAROCKS_BUILDARGS} + COMMAND ${CMAKE_COMMAND} -E env "${PATH}" ${LUAROCKS_BINARY} build luacheck 1.1.0-1 ${LUAROCKS_BUILDARGS} DEPENDS busted) add_custom_target(luacheck ALL DEPENDS ${LUACHECK_EXE}) if (USE_BUNDLED_LUA OR NOT USE_BUNDLED_LUAJIT) # coxpcall add_custom_command(OUTPUT ${ROCKS_DIR}/coxpcall - COMMAND ${LUAROCKS_BINARY} build coxpcall 1.17.0-1 ${LUAROCKS_BUILDARGS} + COMMAND ${CMAKE_COMMAND} -E env "${PATH}" ${LUAROCKS_BINARY} build coxpcall 1.17.0-1 ${LUAROCKS_BUILDARGS} DEPENDS luarocks) add_custom_target(coxpcall ALL DEPENDS ${ROCKS_DIR}/coxpcall) endif() diff --git a/cmake.deps/cmake/BuildTreesitter.cmake b/cmake.deps/cmake/BuildTreesitter.cmake index 837c1cbcb7..da5d212520 100644 --- a/cmake.deps/cmake/BuildTreesitter.cmake +++ b/cmake.deps/cmake/BuildTreesitter.cmake @@ -1,11 +1,11 @@ -ExternalProject_Add(tree-sitter +ExternalProject_Add(treesitter URL ${TREESITTER_URL} URL_HASH SHA256=${TREESITTER_SHA256} DOWNLOAD_NO_PROGRESS TRUE - DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/tree-sitter + DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/treesitter INSTALL_DIR ${DEPS_INSTALL_DIR} PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/cmake/TreesitterCMakeLists.txt - ${DEPS_BUILD_DIR}/src/tree-sitter/CMakeLists.txt + ${DEPS_BUILD_DIR}/src/treesitter/CMakeLists.txt CMAKE_ARGS ${DEPS_CMAKE_ARGS} CMAKE_CACHE_ARGS ${DEPS_CMAKE_CACHE_ARGS}) diff --git a/cmake.deps/cmake/BuildTreesitterParsers.cmake b/cmake.deps/cmake/BuildTreesitterParsers.cmake index ef7d521249..56c8a5a7c6 100644 --- a/cmake.deps/cmake/BuildTreesitterParsers.cmake +++ b/cmake.deps/cmake/BuildTreesitterParsers.cmake @@ -1,14 +1,29 @@ +# Helper function to download treesitter parsers +# +# Single value arguments: +# LANG - Parser language +# CMAKE_FILE - Cmake file to build the parser with. Defaults to +# TreesitterParserCMakeLists.txt. function(BuildTSParser) cmake_parse_arguments(TS "" - "LANG;URL;SHA256;CMAKE_FILE" + "LANG;CMAKE_FILE" "" ${ARGN}) + if(NOT TS_CMAKE_FILE) + set(TS_CMAKE_FILE TreesitterParserCMakeLists.txt) + endif() + set(NAME treesitter-${TS_LANG}) + string(TOUPPER "TREESITTER_${TS_LANG}_URL" URL_VARNAME) + set(URL ${${URL_VARNAME}}) + string(TOUPPER "TREESITTER_${TS_LANG}_SHA256" HASH_VARNAME) + set(HASH ${${HASH_VARNAME}}) + ExternalProject_Add(${NAME} - URL ${TS_URL} - URL_HASH SHA256=${TS_SHA256} + URL ${URL} + URL_HASH SHA256=${HASH} DOWNLOAD_NO_PROGRESS TRUE DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/${NAME} PATCH_COMMAND ${CMAKE_COMMAND} -E copy @@ -19,32 +34,6 @@ function(BuildTSParser) CMAKE_CACHE_ARGS ${DEPS_CMAKE_CACHE_ARGS}) endfunction() -BuildTSParser( - LANG c - URL ${TREESITTER_C_URL} - SHA256 ${TREESITTER_C_SHA256} - CMAKE_FILE TreesitterParserCMakeLists.txt) - -BuildTSParser( - LANG lua - URL ${TREESITTER_LUA_URL} - SHA256 ${TREESITTER_LUA_SHA256} - CMAKE_FILE TreesitterParserCMakeLists.txt) - -BuildTSParser( - LANG vim - URL ${TREESITTER_VIM_URL} - SHA256 ${TREESITTER_VIM_SHA256} - CMAKE_FILE TreesitterParserCMakeLists.txt) - -BuildTSParser( - LANG vimdoc - URL ${TREESITTER_VIMDOC_URL} - SHA256 ${TREESITTER_VIMDOC_SHA256} - CMAKE_FILE TreesitterParserCMakeLists.txt) - -BuildTSParser( - LANG query - URL ${TREESITTER_QUERY_URL} - SHA256 ${TREESITTER_QUERY_SHA256} - CMAKE_FILE TreesitterParserCMakeLists.txt) +foreach(lang c lua vim vimdoc query) + BuildTSParser(LANG ${lang}) +endforeach() diff --git a/cmake.deps/cmake/libtermkeyCMakeLists.txt b/cmake.deps/cmake/LibtermkeyCMakeLists.txt index cefe14e515..cefe14e515 100644 --- a/cmake.deps/cmake/libtermkeyCMakeLists.txt +++ b/cmake.deps/cmake/LibtermkeyCMakeLists.txt diff --git a/cmake.deps/cmake/TreesitterCMakeLists.txt b/cmake.deps/cmake/TreesitterCMakeLists.txt index 9017436ef5..e9728a4093 100644 --- a/cmake.deps/cmake/TreesitterCMakeLists.txt +++ b/cmake.deps/cmake/TreesitterCMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(tree-sitter C) +project(treesitter C) add_library(tree-sitter lib/src/lib.c) target_include_directories(tree-sitter diff --git a/cmake.packaging/WixPatch.xml b/cmake.packaging/WixPatch.xml index 1179292636..1196f4f335 100644 --- a/cmake.packaging/WixPatch.xml +++ b/cmake.packaging/WixPatch.xml @@ -11,11 +11,4 @@ Value='[INSTALL_ROOT]bin' /> </CPackWiXFragment> - - <!-- Allow installation by non-administrative users --> - <!-- https://learn.microsoft.com/windows/win32/msi/allusers --> - <CPackWiXFragment Id="#PRODUCT"> - <Property Id="ALLUSERS" Value="2" /> - <Property Id="MSIINSTALLPERUSER" Value="1" /> - </CPackWiXFragment> </CPackWiXPatch> diff --git a/cmake/FindLibuv.cmake b/cmake/FindLibuv.cmake index 0f6e80d915..0cf8da3061 100644 --- a/cmake/FindLibuv.cmake +++ b/cmake/FindLibuv.cmake @@ -4,8 +4,6 @@ list(APPEND LIBUV_NAMES uv_a uv) find_library(LIBUV_LIBRARY NAMES ${LIBUV_NAMES}) -mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARY) - set(LIBUV_LIBRARIES ${LIBUV_LIBRARY}) set(LIBUV_INCLUDE_DIRS ${LIBUV_INCLUDE_DIR}) diff --git a/contrib/flake.nix b/contrib/flake.nix index 75c94392e1..d38d1fd2b7 100644 --- a/contrib/flake.nix +++ b/contrib/flake.nix @@ -16,6 +16,9 @@ preConfigure = '' sed -i cmake.config/versiondef.h.in -e 's/@NVIM_VERSION_PRERELEASE@/-dev-${version}/' ''; + nativeBuildInputs = oa.nativeBuildInputs ++ [ + final.libiconv + ]; }); # a development binary to help debug issues diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim deleted file mode 100644 index 59361eb735..0000000000 --- a/runtime/autoload/health/provider.vim +++ /dev/null @@ -1,755 +0,0 @@ -let s:shell_error = 0 - -function! s:is_bad_response(s) abort - return a:s =~? '\v(^unable)|(^error)|(^outdated)' -endfunction - -function! s:trim(s) abort - return substitute(a:s, '^\_s*\|\_s*$', '', 'g') -endfunction - -" Convert '\' to '/'. Collapse '//' and '/./'. -function! s:normalize_path(s) abort - return substitute(substitute(a:s, '\', '/', 'g'), '/\./\|/\+', '/', 'g') -endfunction - -" Returns TRUE if `cmd` exits with success, else FALSE. -function! s:cmd_ok(cmd) abort - call system(a:cmd) - return v:shell_error == 0 -endfunction - -" Handler for s:system() function. -function! s:system_handler(jobid, data, event) dict abort - if a:event ==# 'stderr' - if self.add_stderr_to_output - let self.output .= join(a:data, '') - else - let self.stderr .= join(a:data, '') - endif - elseif a:event ==# 'stdout' - let self.output .= join(a:data, '') - elseif a:event ==# 'exit' - let s:shell_error = a:data - endif -endfunction - -" Attempts to construct a shell command from an args list. -" Only for display, to help users debug a failed command. -function! s:shellify(cmd) abort - if type(a:cmd) != type([]) - return a:cmd - endif - return join(map(copy(a:cmd), - \'v:val =~# ''\m[^\-.a-zA-Z_/]'' ? shellescape(v:val) : v:val'), ' ') -endfunction - -" Run a system command and timeout after 30 seconds. -function! s:system(cmd, ...) abort - let stdin = a:0 ? a:1 : '' - let ignore_error = a:0 > 2 ? a:3 : 0 - let opts = { - \ 'add_stderr_to_output': a:0 > 1 ? a:2 : 0, - \ 'output': '', - \ 'stderr': '', - \ 'on_stdout': function('s:system_handler'), - \ 'on_stderr': function('s:system_handler'), - \ 'on_exit': function('s:system_handler'), - \ } - let jobid = jobstart(a:cmd, opts) - - if jobid < 1 - call health#report_error(printf('Command error (job=%d): `%s` (in %s)', - \ jobid, s:shellify(a:cmd), string(getcwd()))) - let s:shell_error = 1 - return opts.output - endif - - if !empty(stdin) - call jobsend(jobid, stdin) - endif - - let res = jobwait([jobid], 30000) - if res[0] == -1 - call health#report_error(printf('Command timed out: %s', s:shellify(a:cmd))) - call jobstop(jobid) - elseif s:shell_error != 0 && !ignore_error - let emsg = printf("Command error (job=%d, exit code %d): `%s` (in %s)", - \ jobid, s:shell_error, s:shellify(a:cmd), string(getcwd())) - if !empty(opts.output) - let emsg .= "\noutput: " . opts.output - end - if !empty(opts.stderr) - let emsg .= "\nstderr: " . opts.stderr - end - call health#report_error(emsg) - endif - - return opts.output -endfunction - -function! s:systemlist(cmd, ...) abort - let stdout = split(s:system(a:cmd, a:0 ? a:1 : ''), "\n") - if a:0 > 1 && !empty(a:2) - return filter(stdout, '!empty(v:val)') - endif - return stdout -endfunction - -" Fetch the contents of a URL. -function! s:download(url) abort - let has_curl = executable('curl') - if has_curl && system(['curl', '-V']) =~# 'Protocols:.*https' - let rv = s:system(['curl', '-sL', a:url], '', 1, 1) - return s:shell_error ? 'curl error with '.a:url.': '.s:shell_error : rv - elseif executable('python') - let script = " - \try:\n - \ from urllib.request import urlopen\n - \except ImportError:\n - \ from urllib2 import urlopen\n - \\n - \response = urlopen('".a:url."')\n - \print(response.read().decode('utf8'))\n - \" - let rv = s:system(['python', '-c', script]) - return empty(rv) && s:shell_error - \ ? 'python urllib.request error: '.s:shell_error - \ : rv - endif - return 'missing `curl` ' - \ .(has_curl ? '(with HTTPS support) ' : '') - \ .'and `python`, cannot make web request' -endfunction - -" Check for clipboard tools. -function! s:check_clipboard() abort - call health#report_start('Clipboard (optional)') - - if !empty($TMUX) && executable('tmux') && executable('pbpaste') && !s:cmd_ok('pbpaste') - let tmux_version = matchstr(system('tmux -V'), '\d\+\.\d\+') - call health#report_error('pbcopy does not work with tmux version: '.tmux_version, - \ ['Install tmux 2.6+. https://superuser.com/q/231130', - \ 'or use tmux with reattach-to-user-namespace. https://superuser.com/a/413233']) - endif - - let clipboard_tool = provider#clipboard#Executable() - if exists('g:clipboard') && empty(clipboard_tool) - call health#report_error( - \ provider#clipboard#Error(), - \ ["Use the example in :help g:clipboard as a template, or don't set g:clipboard at all."]) - elseif empty(clipboard_tool) - call health#report_warn( - \ 'No clipboard tool found. Clipboard registers (`"+` and `"*`) will not work.', - \ [':help clipboard']) - else - call health#report_ok('Clipboard tool found: '. clipboard_tool) - endif -endfunction - -" Get the latest Nvim Python client (pynvim) version from PyPI. -function! s:latest_pypi_version() abort - let pypi_version = 'unable to get pypi response' - let pypi_response = s:download('https://pypi.python.org/pypi/pynvim/json') - if !empty(pypi_response) - try - let pypi_data = json_decode(pypi_response) - catch /E474/ - return 'error: '.pypi_response - endtry - let pypi_version = get(get(pypi_data, 'info', {}), 'version', 'unable to parse') - endif - return pypi_version -endfunction - -" Get version information using the specified interpreter. The interpreter is -" used directly in case breaking changes were introduced since the last time -" Nvim's Python client was updated. -" -" Returns: [ -" {python executable version}, -" {current nvim version}, -" {current pypi nvim status}, -" {installed version status} -" ] -function! s:version_info(python) abort - let pypi_version = s:latest_pypi_version() - let python_version = s:trim(s:system([ - \ a:python, - \ '-c', - \ 'import sys; print(".".join(str(x) for x in sys.version_info[:3]))', - \ ])) - - if empty(python_version) - let python_version = 'unable to parse '.a:python.' response' - endif - - let nvim_path = s:trim(s:system([ - \ a:python, '-c', - \ 'import sys; ' . - \ 'sys.path = [p for p in sys.path if p != ""]; ' . - \ 'import neovim; print(neovim.__file__)'])) - if s:shell_error || empty(nvim_path) - return [python_version, 'unable to load neovim Python module', pypi_version, - \ nvim_path] - endif - - " Assuming that multiple versions of a package are installed, sort them - " numerically in descending order. - function! s:compare(metapath1, metapath2) abort - let a = matchstr(fnamemodify(a:metapath1, ':p:h:t'), '[0-9.]\+') - let b = matchstr(fnamemodify(a:metapath2, ':p:h:t'), '[0-9.]\+') - return a == b ? 0 : a > b ? 1 : -1 - endfunction - - " Try to get neovim.VERSION (added in 0.1.11dev). - let nvim_version = s:system([a:python, '-c', - \ 'from neovim import VERSION as v; '. - \ 'print("{}.{}.{}{}".format(v.major, v.minor, v.patch, v.prerelease))'], - \ '', 1, 1) - if empty(nvim_version) - let nvim_version = 'unable to find pynvim module version' - let base = fnamemodify(nvim_path, ':h') - let metas = glob(base.'-*/METADATA', 1, 1) - \ + glob(base.'-*/PKG-INFO', 1, 1) - \ + glob(base.'.egg-info/PKG-INFO', 1, 1) - let metas = sort(metas, 's:compare') - - if !empty(metas) - for meta_line in readfile(metas[0]) - if meta_line =~# '^Version:' - let nvim_version = matchstr(meta_line, '^Version: \zs\S\+') - break - endif - endfor - endif - endif - - let nvim_path_base = fnamemodify(nvim_path, ':~:h') - let version_status = 'unknown; '.nvim_path_base - if !s:is_bad_response(nvim_version) && !s:is_bad_response(pypi_version) - if v:lua.vim.version.lt(nvim_version, pypi_version) - let version_status = 'outdated; from '.nvim_path_base - else - let version_status = 'up to date' - endif - endif - - return [python_version, nvim_version, pypi_version, version_status] -endfunction - -" Check the Python interpreter's usability. -function! s:check_bin(bin) abort - if !filereadable(a:bin) && (!has('win32') || !filereadable(a:bin.'.exe')) - call health#report_error(printf('"%s" was not found.', a:bin)) - return 0 - elseif executable(a:bin) != 1 - call health#report_error(printf('"%s" is not executable.', a:bin)) - return 0 - endif - return 1 -endfunction - -" Check "loaded" var for given a:provider. -" Returns 1 if the caller should return (skip checks). -function! s:disabled_via_loaded_var(provider) abort - let loaded_var = 'g:loaded_'.a:provider.'_provider' - if exists(loaded_var) && !exists('*provider#'.a:provider.'#Call') - let v = eval(loaded_var) - if 0 is v - call health#report_info('Disabled ('.loaded_var.'='.v.').') - return 1 - else - call health#report_info('Disabled ('.loaded_var.'='.v.'). This might be due to some previous error.') - endif - endif - return 0 -endfunction - -function! s:check_python() abort - call health#report_start('Python 3 provider (optional)') - - let pyname = 'python3' - let python_exe = '' - let venv = exists('$VIRTUAL_ENV') ? resolve($VIRTUAL_ENV) : '' - let host_prog_var = pyname.'_host_prog' - let python_multiple = [] - - if s:disabled_via_loaded_var(pyname) - return - endif - - let [pyenv, pyenv_root] = s:check_for_pyenv() - - if exists('g:'.host_prog_var) - call health#report_info(printf('Using: g:%s = "%s"', host_prog_var, get(g:, host_prog_var))) - endif - - let [pyname, pythonx_warnings] = provider#pythonx#Detect(3) - - if empty(pyname) - call health#report_warn('No Python executable found that can `import neovim`. ' - \ . 'Using the first available executable for diagnostics.') - elseif exists('g:'.host_prog_var) - let python_exe = pyname - endif - - " No Python executable could `import neovim`, or host_prog_var was used. - if !empty(pythonx_warnings) - call health#report_warn(pythonx_warnings, ['See :help provider-python for more information.', - \ 'You may disable this provider (and warning) by adding `let g:loaded_python3_provider = 0` to your init.vim']) - - elseif !empty(pyname) && empty(python_exe) - if !exists('g:'.host_prog_var) - call health#report_info(printf('`g:%s` is not set. Searching for ' - \ . '%s in the environment.', host_prog_var, pyname)) - endif - - if !empty(pyenv) - let python_exe = s:trim(s:system([pyenv, 'which', pyname], '', 1)) - - if empty(python_exe) - call health#report_warn(printf('pyenv could not find %s.', pyname)) - endif - endif - - if empty(python_exe) - let python_exe = exepath(pyname) - - if exists('$PATH') - for path in split($PATH, has('win32') ? ';' : ':') - let path_bin = s:normalize_path(path.'/'.pyname) - if path_bin != s:normalize_path(python_exe) - \ && index(python_multiple, path_bin) == -1 - \ && executable(path_bin) - call add(python_multiple, path_bin) - endif - endfor - - if len(python_multiple) - " This is worth noting since the user may install something - " that changes $PATH, like homebrew. - call health#report_info(printf('Multiple %s executables found. ' - \ . 'Set `g:%s` to avoid surprises.', pyname, host_prog_var)) - endif - - if python_exe =~# '\<shims\>' - call health#report_warn(printf('`%s` appears to be a pyenv shim.', python_exe), [ - \ '`pyenv` is not in $PATH, your pyenv installation is broken. ' - \ .'Set `g:'.host_prog_var.'` to avoid surprises.', - \ ]) - endif - endif - endif - endif - - if !empty(python_exe) && !exists('g:'.host_prog_var) - if empty(venv) && !empty(pyenv) - \ && !empty(pyenv_root) && resolve(python_exe) !~# '^'.pyenv_root.'/' - call health#report_warn('pyenv is not set up optimally.', [ - \ printf('Create a virtualenv specifically ' - \ . 'for Nvim using pyenv, and set `g:%s`. This will avoid ' - \ . 'the need to install the pynvim module in each ' - \ . 'version/virtualenv.', host_prog_var) - \ ]) - elseif !empty(venv) - if !empty(pyenv_root) - let venv_root = pyenv_root - else - let venv_root = fnamemodify(venv, ':h') - endif - - if resolve(python_exe) !~# '^'.venv_root.'/' - call health#report_warn('Your virtualenv is not set up optimally.', [ - \ printf('Create a virtualenv specifically ' - \ . 'for Nvim and use `g:%s`. This will avoid ' - \ . 'the need to install the pynvim module in each ' - \ . 'virtualenv.', host_prog_var) - \ ]) - endif - endif - endif - - if empty(python_exe) && !empty(pyname) - " An error message should have already printed. - call health#report_error(printf('`%s` was not found.', pyname)) - elseif !empty(python_exe) && !s:check_bin(python_exe) - let python_exe = '' - endif - - " Diagnostic output - call health#report_info('Executable: ' . (empty(python_exe) ? 'Not found' : python_exe)) - if len(python_multiple) - for path_bin in python_multiple - call health#report_info('Other python executable: ' . path_bin) - endfor - endif - - if empty(python_exe) - " No Python executable can import 'neovim'. Check if any Python executable - " can import 'pynvim'. If so, that Python failed to import 'neovim' as - " well, which is most probably due to a failed pip upgrade: - " https://github.com/neovim/neovim/wiki/Following-HEAD#20181118 - let [pynvim_exe, errors] = provider#pythonx#DetectByModule('pynvim', 3) - if !empty(pynvim_exe) - call health#report_error( - \ 'Detected pip upgrade failure: Python executable can import "pynvim" but ' - \ . 'not "neovim": '. pynvim_exe, - \ "Use that Python version to reinstall \"pynvim\" and optionally \"neovim\".\n" - \ . pynvim_exe ." -m pip uninstall pynvim neovim\n" - \ . pynvim_exe ." -m pip install pynvim\n" - \ . pynvim_exe ." -m pip install neovim # only if needed by third-party software") - endif - else - let [majorpyversion, current, latest, status] = s:version_info(python_exe) - - if 3 != str2nr(majorpyversion) - call health#report_warn('Unexpected Python version.' . - \ ' This could lead to confusing error messages.') - endif - - call health#report_info('Python version: ' . majorpyversion) - - if s:is_bad_response(status) - call health#report_info(printf('pynvim version: %s (%s)', current, status)) - else - call health#report_info(printf('pynvim version: %s', current)) - endif - - if s:is_bad_response(current) - call health#report_error( - \ "pynvim is not installed.\nError: ".current, - \ ['Run in shell: '. python_exe .' -m pip install pynvim']) - endif - - if s:is_bad_response(latest) - call health#report_warn('Could not contact PyPI to get latest version.') - call health#report_error('HTTP request failed: '.latest) - elseif s:is_bad_response(status) - call health#report_warn(printf('Latest pynvim is NOT installed: %s', latest)) - elseif !s:is_bad_response(current) - call health#report_ok(printf('Latest pynvim is installed.')) - endif - endif -endfunction - -" Check if pyenv is available and a valid pyenv root can be found, then return -" their respective paths. If either of those is invalid, return two empty -" strings, effectivly ignoring pyenv. -function! s:check_for_pyenv() abort - let pyenv_path = resolve(exepath('pyenv')) - - if empty(pyenv_path) - return ['', ''] - endif - - call health#report_info('pyenv: Path: '. pyenv_path) - - let pyenv_root = exists('$PYENV_ROOT') ? resolve($PYENV_ROOT) : '' - - if empty(pyenv_root) - let pyenv_root = s:trim(s:system([pyenv_path, 'root'])) - call health#report_info('pyenv: $PYENV_ROOT is not set. Infer from `pyenv root`.') - endif - - if !isdirectory(pyenv_root) - call health#report_warn( - \ printf('pyenv: Root does not exist: %s. ' - \ . 'Ignoring pyenv for all following checks.', pyenv_root)) - return ['', ''] - endif - - call health#report_info('pyenv: Root: '.pyenv_root) - - return [pyenv_path, pyenv_root] -endfunction - -" Resolves Python executable path by invoking and checking `sys.executable`. -function! s:python_exepath(invocation) abort - return s:normalize_path(system(fnameescape(a:invocation) - \ . ' -c "import sys; sys.stdout.write(sys.executable)"')) -endfunction - -" Checks that $VIRTUAL_ENV Python executables are found at front of $PATH in -" Nvim and subshells. -function! s:check_virtualenv() abort - call health#report_start('Python virtualenv') - if !exists('$VIRTUAL_ENV') - call health#report_ok('no $VIRTUAL_ENV') - return - endif - let errors = [] - " Keep hints as dict keys in order to discard duplicates. - let hints = {} - " The virtualenv should contain some Python executables, and those - " executables should be first both on Nvim's $PATH and the $PATH of - " subshells launched from Nvim. - let bin_dir = has('win32') ? '/Scripts' : '/bin' - let venv_bins = glob($VIRTUAL_ENV . bin_dir . '/python*', v:true, v:true) - " XXX: Remove irrelevant executables found in bin/. - let venv_bins = filter(venv_bins, 'v:val !~# "python-config"') - if len(venv_bins) - for venv_bin in venv_bins - let venv_bin = s:normalize_path(venv_bin) - let py_bin_basename = fnamemodify(venv_bin, ':t') - let nvim_py_bin = s:python_exepath(exepath(py_bin_basename)) - let subshell_py_bin = s:python_exepath(py_bin_basename) - if venv_bin !=# nvim_py_bin - call add(errors, '$PATH yields this '.py_bin_basename.' executable: '.nvim_py_bin) - let hint = '$PATH ambiguities arise if the virtualenv is not ' - \.'properly activated prior to launching Nvim. Close Nvim, activate the virtualenv, ' - \.'check that invoking Python from the command line launches the correct one, ' - \.'then relaunch Nvim.' - let hints[hint] = v:true - endif - if venv_bin !=# subshell_py_bin - call add(errors, '$PATH in subshells yields this ' - \.py_bin_basename . ' executable: '.subshell_py_bin) - let hint = '$PATH ambiguities in subshells typically are ' - \.'caused by your shell config overriding the $PATH previously set by the ' - \.'virtualenv. Either prevent them from doing so, or use this workaround: ' - \.'https://vi.stackexchange.com/a/34996' - let hints[hint] = v:true - endif - endfor - else - call add(errors, 'no Python executables found in the virtualenv '.bin_dir.' directory.') - endif - - let msg = '$VIRTUAL_ENV is set to: '.$VIRTUAL_ENV - if len(errors) - if len(venv_bins) - let msg .= "\nAnd its ".bin_dir.' directory contains: ' - \.join(map(venv_bins, "fnamemodify(v:val, ':t')"), ', ') - endif - let conj = "\nBut " - for error in errors - let msg .= conj.error - let conj = "\nAnd " - endfor - let msg .= "\nSo invoking Python may lead to unexpected results." - call health#report_warn(msg, keys(hints)) - else - call health#report_info(msg) - call health#report_info('Python version: ' - \.system('python -c "import platform, sys; sys.stdout.write(platform.python_version())"')) - call health#report_ok('$VIRTUAL_ENV provides :!python.') - endif -endfunction - -function! s:check_ruby() abort - call health#report_start('Ruby provider (optional)') - - if s:disabled_via_loaded_var('ruby') - return - endif - - if !executable('ruby') || !executable('gem') - call health#report_warn( - \ '`ruby` and `gem` must be in $PATH.', - \ ['Install Ruby and verify that `ruby` and `gem` commands work.']) - return - endif - call health#report_info('Ruby: '. s:system(['ruby', '-v'])) - - let [host, err] = provider#ruby#Detect() - if empty(host) - call health#report_warn('`neovim-ruby-host` not found.', - \ ['Run `gem install neovim` to ensure the neovim RubyGem is installed.', - \ 'Run `gem environment` to ensure the gem bin directory is in $PATH.', - \ 'If you are using rvm/rbenv/chruby, try "rehashing".', - \ 'See :help g:ruby_host_prog for non-standard gem installations.', - \ 'You may disable this provider (and warning) by adding `let g:loaded_ruby_provider = 0` to your init.vim']) - return - endif - call health#report_info('Host: '. host) - - let latest_gem_cmd = has('win32') ? 'cmd /c gem list -ra "^^neovim$"' : 'gem list -ra ^neovim$' - let latest_gem = s:system(split(latest_gem_cmd)) - if s:shell_error || empty(latest_gem) - call health#report_error('Failed to run: '. latest_gem_cmd, - \ ["Make sure you're connected to the internet.", - \ 'Are you behind a firewall or proxy?']) - return - endif - let latest_gem = get(split(latest_gem, 'neovim (\|, \|)$' ), 0, 'not found') - - let current_gem_cmd = [host, '--version'] - let current_gem = s:system(current_gem_cmd) - if s:shell_error - call health#report_error('Failed to run: '. join(current_gem_cmd), - \ ['Report this issue with the output of: ', join(current_gem_cmd)]) - return - endif - - if v:lua.vim.version.lt(current_gem, latest_gem) - call health#report_warn( - \ printf('Gem "neovim" is out-of-date. Installed: %s, latest: %s', - \ current_gem, latest_gem), - \ ['Run in shell: gem update neovim']) - else - call health#report_ok('Latest "neovim" gem is installed: '. current_gem) - endif -endfunction - -function! s:check_node() abort - call health#report_start('Node.js provider (optional)') - - if s:disabled_via_loaded_var('node') - return - endif - - if !executable('node') || (!executable('npm') && !executable('yarn') && !executable('pnpm')) - call health#report_warn( - \ '`node` and `npm` (or `yarn`, `pnpm`) must be in $PATH.', - \ ['Install Node.js and verify that `node` and `npm` (or `yarn`, `pnpm`) commands work.']) - return - endif - let node_v = get(split(s:system(['node', '-v']), "\n"), 0, '') - call health#report_info('Node.js: '. node_v) - if s:shell_error || v:lua.vim.version.lt(node_v[1:], '6.0.0') - call health#report_warn('Nvim node.js host does not support Node '.node_v) - " Skip further checks, they are nonsense if nodejs is too old. - return - endif - if !provider#node#can_inspect() - call health#report_warn('node.js on this system does not support --inspect-brk so $NVIM_NODE_HOST_DEBUG is ignored.') - endif - - let [host, err] = provider#node#Detect() - if empty(host) - call health#report_warn('Missing "neovim" npm (or yarn, pnpm) package.', - \ ['Run in shell: npm install -g neovim', - \ 'Run in shell (if you use yarn): yarn global add neovim', - \ 'Run in shell (if you use pnpm): pnpm install -g neovim', - \ 'You may disable this provider (and warning) by adding `let g:loaded_node_provider = 0` to your init.vim']) - return - endif - call health#report_info('Nvim node.js host: '. host) - - let manager = 'npm' - if executable('yarn') - let manager = 'yarn' - elseif executable('pnpm') - let manager = 'pnpm' - endif - - let latest_npm_cmd = has('win32') ? - \ 'cmd /c '. manager .' info neovim --json' : - \ manager .' info neovim --json' - let latest_npm = s:system(split(latest_npm_cmd)) - if s:shell_error || empty(latest_npm) - call health#report_error('Failed to run: '. latest_npm_cmd, - \ ["Make sure you're connected to the internet.", - \ 'Are you behind a firewall or proxy?']) - return - endif - try - let pkg_data = json_decode(latest_npm) - catch /E474/ - return 'error: '.latest_npm - endtry - let latest_npm = get(get(pkg_data, 'dist-tags', {}), 'latest', 'unable to parse') - - let current_npm_cmd = ['node', host, '--version'] - let current_npm = s:system(current_npm_cmd) - if s:shell_error - call health#report_error('Failed to run: '. join(current_npm_cmd), - \ ['Report this issue with the output of: ', join(current_npm_cmd)]) - return - endif - - if latest_npm !=# 'unable to parse' && v:lua.vim.version.lt(current_npm, latest_npm) - call health#report_warn( - \ printf('Package "neovim" is out-of-date. Installed: %s, latest: %s', - \ current_npm, latest_npm), - \ ['Run in shell: npm install -g neovim', - \ 'Run in shell (if you use yarn): yarn global add neovim', - \ 'Run in shell (if you use pnpm): pnpm install -g neovim']) - else - call health#report_ok('Latest "neovim" npm/yarn/pnpm package is installed: '. current_npm) - endif -endfunction - -function! s:check_perl() abort - call health#report_start('Perl provider (optional)') - - if s:disabled_via_loaded_var('perl') - return - endif - - let [perl_exec, perl_warnings] = provider#perl#Detect() - if empty(perl_exec) - if !empty(perl_warnings) - call health#report_warn(perl_warnings, ['See :help provider-perl for more information.', - \ 'You may disable this provider (and warning) by adding `let g:loaded_perl_provider = 0` to your init.vim']) - else - call health#report_warn('No usable perl executable found') - endif - return - endif - - call health#report_info('perl executable: '. perl_exec) - - " we cannot use cpanm that is on the path, as it may not be for the perl - " set with g:perl_host_prog - call s:system([perl_exec, '-W', '-MApp::cpanminus', '-e', '']) - if s:shell_error - return [perl_exec, '"App::cpanminus" module is not installed'] - endif - - let latest_cpan_cmd = [perl_exec, - \ '-MApp::cpanminus::fatscript', '-e', - \ 'my $app = App::cpanminus::script->new; - \ $app->parse_options ("--info", "-q", "Neovim::Ext"); - \ exit $app->doit'] - - let latest_cpan = s:system(latest_cpan_cmd) - if s:shell_error || empty(latest_cpan) - call health#report_error('Failed to run: '. join(latest_cpan_cmd, " "), - \ ["Make sure you're connected to the internet.", - \ 'Are you behind a firewall or proxy?']) - return - elseif latest_cpan[0] ==# '!' - let cpanm_errs = split(latest_cpan, '!') - if cpanm_errs[0] =~# "Can't write to " - call health#report_warn(cpanm_errs[0], cpanm_errs[1:-2]) - " Last line is the package info - let latest_cpan = cpanm_errs[-1] - else - call health#report_error('Unknown warning from command: ' . latest_cpan_cmd, cpanm_errs) - return - endif - endif - let latest_cpan = matchstr(latest_cpan, '\(\.\?\d\)\+') - if empty(latest_cpan) - call health#report_error('Cannot parse version number from cpanm output: ' . latest_cpan) - return - endif - - let current_cpan_cmd = [perl_exec, '-W', '-MNeovim::Ext', '-e', 'print $Neovim::Ext::VERSION'] - let current_cpan = s:system(current_cpan_cmd) - if s:shell_error - call health#report_error('Failed to run: '. join(current_cpan_cmd), - \ ['Report this issue with the output of: ', join(current_cpan_cmd)]) - return - endif - - if v:lua.vim.version.lt(current_cpan, latest_cpan) - call health#report_warn( - \ printf('Module "Neovim::Ext" is out-of-date. Installed: %s, latest: %s', - \ current_cpan, latest_cpan), - \ ['Run in shell: cpanm -n Neovim::Ext']) - else - call health#report_ok('Latest "Neovim::Ext" cpan module is installed: '. current_cpan) - endif -endfunction - -function! health#provider#check() abort - call s:check_clipboard() - call s:check_python() - call s:check_virtualenv() - call s:check_ruby() - call s:check_node() - call s:check_perl() -endfunction diff --git a/runtime/autoload/health/provider2.vim b/runtime/autoload/health/provider2.vim new file mode 100644 index 0000000000..edd3baae12 --- /dev/null +++ b/runtime/autoload/health/provider2.vim @@ -0,0 +1,244 @@ +let s:shell_error = 0 + +" Handler for s:system() function. +function! s:system_handler(jobid, data, event) dict abort + if a:event ==# 'stderr' + if self.add_stderr_to_output + let self.output .= join(a:data, '') + else + let self.stderr .= join(a:data, '') + endif + elseif a:event ==# 'stdout' + let self.output .= join(a:data, '') + elseif a:event ==# 'exit' + let s:shell_error = a:data + endif +endfunction + +" Attempts to construct a shell command from an args list. +" Only for display, to help users debug a failed command. +function! s:shellify(cmd) abort + if type(a:cmd) != type([]) + return a:cmd + endif + return join(map(copy(a:cmd), + \'v:val =~# ''\m[^\-.a-zA-Z_/]'' ? shellescape(v:val) : v:val'), ' ') +endfunction + +" Run a system command and timeout after 30 seconds. +function! s:system(cmd, ...) abort + let stdin = a:0 ? a:1 : '' + let ignore_error = a:0 > 2 ? a:3 : 0 + let opts = { + \ 'add_stderr_to_output': a:0 > 1 ? a:2 : 0, + \ 'output': '', + \ 'stderr': '', + \ 'on_stdout': function('s:system_handler'), + \ 'on_stderr': function('s:system_handler'), + \ 'on_exit': function('s:system_handler'), + \ } + let jobid = jobstart(a:cmd, opts) + + if jobid < 1 + call health#report_error(printf('Command error (job=%d): `%s` (in %s)', + \ jobid, s:shellify(a:cmd), string(getcwd()))) + let s:shell_error = 1 + return opts.output + endif + + if !empty(stdin) + call jobsend(jobid, stdin) + endif + + let res = jobwait([jobid], 30000) + if res[0] == -1 + call health#report_error(printf('Command timed out: %s', s:shellify(a:cmd))) + call jobstop(jobid) + elseif s:shell_error != 0 && !ignore_error + let emsg = printf("Command error (job=%d, exit code %d): `%s` (in %s)", + \ jobid, s:shell_error, s:shellify(a:cmd), string(getcwd())) + if !empty(opts.output) + let emsg .= "\noutput: " . opts.output + end + if !empty(opts.stderr) + let emsg .= "\nstderr: " . opts.stderr + end + call health#report_error(emsg) + endif + + return opts.output +endfunction + +" Check "loaded" var for given a:provider. +" Returns 1 if the caller should return (skip checks). +function! s:disabled_via_loaded_var(provider) abort + let loaded_var = 'g:loaded_'.a:provider.'_provider' + if exists(loaded_var) && !exists('*provider#'.a:provider.'#Call') + let v = eval(loaded_var) + if 0 is v + call health#report_info('Disabled ('.loaded_var.'='.v.').') + return 1 + else + call health#report_info('Disabled ('.loaded_var.'='.v.'). This might be due to some previous error.') + endif + endif + return 0 +endfunction + +function! s:check_node() abort + call health#report_start('Node.js provider (optional)') + + if s:disabled_via_loaded_var('node') + return + endif + + if !executable('node') || (!executable('npm') && !executable('yarn') && !executable('pnpm')) + call health#report_warn( + \ '`node` and `npm` (or `yarn`, `pnpm`) must be in $PATH.', + \ ['Install Node.js and verify that `node` and `npm` (or `yarn`, `pnpm`) commands work.']) + return + endif + let node_v = get(split(s:system(['node', '-v']), "\n"), 0, '') + call health#report_info('Node.js: '. node_v) + if s:shell_error || v:lua.vim.version.lt(node_v[1:], '6.0.0') + call health#report_warn('Nvim node.js host does not support Node '.node_v) + " Skip further checks, they are nonsense if nodejs is too old. + return + endif + if !provider#node#can_inspect() + call health#report_warn('node.js on this system does not support --inspect-brk so $NVIM_NODE_HOST_DEBUG is ignored.') + endif + + let [host, err] = provider#node#Detect() + if empty(host) + call health#report_warn('Missing "neovim" npm (or yarn, pnpm) package.', + \ ['Run in shell: npm install -g neovim', + \ 'Run in shell (if you use yarn): yarn global add neovim', + \ 'Run in shell (if you use pnpm): pnpm install -g neovim', + \ 'You may disable this provider (and warning) by adding `let g:loaded_node_provider = 0` to your init.vim']) + return + endif + call health#report_info('Nvim node.js host: '. host) + + let manager = 'npm' + if executable('yarn') + let manager = 'yarn' + elseif executable('pnpm') + let manager = 'pnpm' + endif + + let latest_npm_cmd = has('win32') ? + \ 'cmd /c '. manager .' info neovim --json' : + \ manager .' info neovim --json' + let latest_npm = s:system(split(latest_npm_cmd)) + if s:shell_error || empty(latest_npm) + call health#report_error('Failed to run: '. latest_npm_cmd, + \ ["Make sure you're connected to the internet.", + \ 'Are you behind a firewall or proxy?']) + return + endif + try + let pkg_data = json_decode(latest_npm) + catch /E474/ + return 'error: '.latest_npm + endtry + let latest_npm = get(get(pkg_data, 'dist-tags', {}), 'latest', 'unable to parse') + + let current_npm_cmd = ['node', host, '--version'] + let current_npm = s:system(current_npm_cmd) + if s:shell_error + call health#report_error('Failed to run: '. join(current_npm_cmd), + \ ['Report this issue with the output of: ', join(current_npm_cmd)]) + return + endif + + if latest_npm !=# 'unable to parse' && v:lua.vim.version.lt(current_npm, latest_npm) + call health#report_warn( + \ printf('Package "neovim" is out-of-date. Installed: %s, latest: %s', + \ current_npm, latest_npm), + \ ['Run in shell: npm install -g neovim', + \ 'Run in shell (if you use yarn): yarn global add neovim', + \ 'Run in shell (if you use pnpm): pnpm install -g neovim']) + else + call health#report_ok('Latest "neovim" npm/yarn/pnpm package is installed: '. current_npm) + endif +endfunction + +function! s:check_perl() abort + call health#report_start('Perl provider (optional)') + + if s:disabled_via_loaded_var('perl') + return + endif + + let [perl_exec, perl_warnings] = provider#perl#Detect() + if empty(perl_exec) + if !empty(perl_warnings) + call health#report_warn(perl_warnings, ['See :help provider-perl for more information.', + \ 'You may disable this provider (and warning) by adding `let g:loaded_perl_provider = 0` to your init.vim']) + else + call health#report_warn('No usable perl executable found') + endif + return + endif + + call health#report_info('perl executable: '. perl_exec) + + " we cannot use cpanm that is on the path, as it may not be for the perl + " set with g:perl_host_prog + call s:system([perl_exec, '-W', '-MApp::cpanminus', '-e', '']) + if s:shell_error + return [perl_exec, '"App::cpanminus" module is not installed'] + endif + + let latest_cpan_cmd = [perl_exec, + \ '-MApp::cpanminus::fatscript', '-e', + \ 'my $app = App::cpanminus::script->new; + \ $app->parse_options ("--info", "-q", "Neovim::Ext"); + \ exit $app->doit'] + + let latest_cpan = s:system(latest_cpan_cmd) + if s:shell_error || empty(latest_cpan) + call health#report_error('Failed to run: '. join(latest_cpan_cmd, " "), + \ ["Make sure you're connected to the internet.", + \ 'Are you behind a firewall or proxy?']) + return + elseif latest_cpan[0] ==# '!' + let cpanm_errs = split(latest_cpan, '!') + if cpanm_errs[0] =~# "Can't write to " + call health#report_warn(cpanm_errs[0], cpanm_errs[1:-2]) + " Last line is the package info + let latest_cpan = cpanm_errs[-1] + else + call health#report_error('Unknown warning from command: ' . latest_cpan_cmd, cpanm_errs) + return + endif + endif + let latest_cpan = matchstr(latest_cpan, '\(\.\?\d\)\+') + if empty(latest_cpan) + call health#report_error('Cannot parse version number from cpanm output: ' . latest_cpan) + return + endif + + let current_cpan_cmd = [perl_exec, '-W', '-MNeovim::Ext', '-e', 'print $Neovim::Ext::VERSION'] + let current_cpan = s:system(current_cpan_cmd) + if s:shell_error + call health#report_error('Failed to run: '. join(current_cpan_cmd), + \ ['Report this issue with the output of: ', join(current_cpan_cmd)]) + return + endif + + if v:lua.vim.version.lt(current_cpan, latest_cpan) + call health#report_warn( + \ printf('Module "Neovim::Ext" is out-of-date. Installed: %s, latest: %s', + \ current_cpan, latest_cpan), + \ ['Run in shell: cpanm -n Neovim::Ext']) + else + call health#report_ok('Latest "Neovim::Ext" cpan module is installed: '. current_cpan) + endif +endfunction + +function! health#provider2#check() abort + call s:check_node() + call s:check_perl() +endfunction diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 1adf0a305f..d63563cc05 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -773,6 +773,8 @@ nvim_eval_statusline({str}, {*opts}) *nvim_eval_statusline()* • use_tabline: (boolean) Evaluate tabline instead of statusline. When true, {winid} is ignored. Mutually exclusive with {use_winbar}. + • use_statuscol_lnum: (number) Evaluate statuscolumn for this + line number instead of statusline. Return: ~ Dictionary containing statusline information, with these keys: @@ -2568,17 +2570,17 @@ nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {opts}) `limit`, to get the first marks prior to a given position.) Example: >lua - local a = vim.api - local pos = a.nvim_win_get_cursor(0) - local ns = a.nvim_create_namespace('my-plugin') + local api = vim.api + local pos = api.nvim_win_get_cursor(0) + local ns = api.nvim_create_namespace('my-plugin') -- Create new extmark at line 1, column 1. - local m1 = a.nvim_buf_set_extmark(0, ns, 0, 0, {}) + local m1 = api.nvim_buf_set_extmark(0, ns, 0, 0, {}) -- Create new extmark at line 3, column 1. - local m2 = a.nvim_buf_set_extmark(0, ns, 2, 0, {}) + local m2 = api.nvim_buf_set_extmark(0, ns, 2, 0, {}) -- Get extmarks only from line 3. - local ms = a.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {}) + local ms = api.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {}) -- Get all marks in this buffer + namespace. - local all = a.nvim_buf_get_extmarks(0, ns, 0, -1, {}) + local all = api.nvim_buf_get_extmarks(0, ns, 0, -1, {}) print(vim.inspect(ms)) < diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 3eb2017bed..3735073867 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -130,6 +130,8 @@ TREESITTER FUNCTIONS instead. - *vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()| and |TSNode:type()| instead. +- *vim.treesitter.query.get_query()* Use |vim.treesitter.query.get()| + instead. LUA - vim.register_keystroke_callback() Use |vim.on_key()| instead. diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index f888bb0991..025a7dccfc 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -295,6 +295,14 @@ DiagnosticSignHint DiagnosticSignOk Used for "Ok" signs in sign column. + *hl-DiagnosticDeprecated* +DiagnosticDeprecated + Used for deprecated or obsolete code. + + *hl-DiagnosticUnnecessary* +DiagnosticUnnecessary + Used for unnecessary or unused code. + ============================================================================== SIGNS *diagnostic-signs* diff --git a/runtime/doc/editorconfig.txt b/runtime/doc/editorconfig.txt index 52fd860d2d..7c6e8fb95f 100644 --- a/runtime/doc/editorconfig.txt +++ b/runtime/doc/editorconfig.txt @@ -48,7 +48,7 @@ indent_style One of "tab" or "space". Sets the 'expandtab' option. indent_size A number indicating the size of a single indent. Alternatively, use the value "tab" to use the value of the tab_width property. Sets the 'shiftwidth' and - 'softtabstop'. + 'softtabstop' options. *editorconfig_insert_final_newline* insert_final_newline "true" or "false" to ensure the file always has a diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index f5695669ae..01edbe7cbd 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -517,7 +517,7 @@ groups are derived from the token's type and modifiers: • `@lsp.type.<type>.<ft>` for the type • `@lsp.mod.<mod>.<ft>` for each modifier • `@lsp.typemod.<type>.<mod>.<ft>` for each modifier -Use |:Inspect| to view the higlights for a specific token. Use |:hi| or +Use |:Inspect| to view the highlights for a specific token. Use |:hi| or |nvim_set_hl()| to change the appearance of semantic highlights: >vim hi @lsp.type.function guifg=Yellow " function names are yellow diff --git a/runtime/doc/lua-guide.txt b/runtime/doc/lua-guide.txt index 5e2b753645..3c2e1ac3d1 100644 --- a/runtime/doc/lua-guide.txt +++ b/runtime/doc/lua-guide.txt @@ -539,7 +539,7 @@ about the triggered autocommand. The most useful keys are For example, this allows you to set buffer-local mappings for some filetypes: >lua - vim.api.nvim.create_autocmd("FileType", { + vim.api.nvim_create_autocmd("FileType", { pattern = "lua", callback = function(args) vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = args.buf }) diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index ebbf8bb463..6084a625ba 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -685,9 +685,10 @@ vim.diff({a}, {b}, {opts}) *vim.diff()* • "unified": (default) String in unified format. • "indices": Array of hunk locations. Note: This option is ignored if `on_hunk` is used. - • `linematch` (boolean): Run linematch on the resulting hunks - from xdiff. Requires `result_type = indices`, ignored - otherwise. + • `linematch` (boolean|integer): Run linematch on the resulting hunks + from xdiff. When integer, only hunks upto this size in + lines are run through linematch. Requires `result_type = indices`, + ignored otherwise. • `algorithm` (string): Diff algorithm to use. Values: • "myers" the default algorithm @@ -2001,7 +2002,7 @@ validate({opt}) *vim.validate()* vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}} --> NOP (success) - vim.validate{arg1={1, {'string', table'}}} + vim.validate{arg1={1, {'string', 'table'}}} --> error('arg1: expected string|table, got number') < diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index c65007d1a4..cd374c6f34 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -540,28 +540,10 @@ See |:verbose-cmd| for more information. 1.5 MAPPING SPECIAL KEYS *:map-special-keys* -There are two ways to map a special key: -1. The Vi-compatible method: Map the key code. Often this is a sequence that - starts with <Esc>. To enter a mapping like this you type ":map " and then - you have to type CTRL-V before hitting the function key. Note that when - the key code for the key is in the |terminfo| entry, it will automatically - be translated into the internal code and become the second way of mapping. -2. The second method is to use the internal code for the function key. To - enter such a mapping type CTRL-K and then hit the function key, or use - the form "#1", "#2", .. "#9", "#0", "<Up>", "<S-Down>", "<S-F7>", etc. - (see table of keys |key-notation|, all keys from <Up> can be used). The - first ten function keys can be defined in two ways: Just the number, like - "#2", and with "<F>", like "<F2>". Both stand for function key 2. "#0" - refers to function key 10. - -DETAIL: Vim first checks if a sequence from the keyboard is mapped. If it -isn't the terminal key codes are tried. If a terminal code is found it is -replaced with the internal code. Then the check for a mapping is done again -(so you can map an internal code to something else). What is written into the -script file depends on what is recognized. If the terminal key code was -recognized as a mapping the key code itself is written to the script file. If -it was recognized as a terminal code the internal code is written to the -script file. +To map a function key, use the internal code for it. To enter such a mapping +type CTRL-K and then hit the function key, or use the form "<F2>", "<F10>", +"<Up>", "<S-Down>", "<S-F7>", etc. (see table of keys |key-notation|, all keys +from <Up> can be used). 1.6 SPECIAL CHARACTERS *:map-special-chars* diff --git a/runtime/doc/news-0.9.txt b/runtime/doc/news-0.9.txt new file mode 100644 index 0000000000..c7624119e2 --- /dev/null +++ b/runtime/doc/news-0.9.txt @@ -0,0 +1,323 @@ +*news-0.9.txt* Nvim + + + NVIM REFERENCE MANUAL + + +Notable changes in Nvim 0.9 from 0.8 *news-0.9* + + Type |gO| to see the table of contents. + +============================================================================== +BREAKING CHANGES + +The following changes may require adaptations in user config or plugins. + +• Cscope support is now removed (see |cscope| and |nvim-removed|): + - Commands removed: + - `:cscope` + - `:lcscope` + - `:scscope` + - `:cstag` + - Options removed: + - `cscopepathcomp` + - `cscopeprg` + - `cscopequickfix` + - `cscoperelative` + - `cscopetag` + - `cscopetagorder` + - `cscopeverbose` + - Eval functions removed: + - `cscope_connection()` + + Note: support for |ctags| remains with no plans to remove. + + See https://github.com/neovim/neovim/pull/20545 for more information. + +• `:hardcopy` is now removed (see |hardcopy| and |nvim-removed|): + - Commands removed: + - `:hardcopy` + - Options removed: + - `printdevice` + - `printencoding` + - `printexpr` + - `printfont` + - `printheader` + - `printmbcharset` + +• 'paste' option is now deprecated and 'pastetoggle' is removed. |paste| works + automatically in GUI and terminal (TUI) Nvim. Just Paste It.™ + +• Changes to |vim.treesitter.get_node_text()|: + - It now returns `string`, as opposed to `string|string[]|nil`. + - The `concat` option has been removed as it was not consistently applied. + - Invalid ranges now cause an error instead of returning `nil`. + +• `help` treesitter parser was renamed to `vimdoc`. The only user-visible + change is that language-specific highlight groups need to be renamed from + `@foo.help` to `@foo.vimdoc`. + +• The default value of 'commentstring' is now empty instead of "/*%s*/". + +• libiconv and intl are now required build dependencies. + +============================================================================== +NEW FEATURES + +The following new APIs or features were added. + +• Treesitter syntax highlighting for `help` files now supports highlighted + code examples. To enable, create a `.config/nvim/ftplugin/help.lua` with + the contents >lua + vim.treesitter.start() +< + Note: Highlighted code examples are only available in the Nvim manual, not + in help files taken from Vim. The treesitter `vimdoc` parser is also work in + progress and not guaranteed to correctly highlight every help file in the + wild. + +• Added support for semantic token highlighting to the LSP client. This + functionality is enabled by default when a client that supports this feature + is attached to a buffer. Opt-out can be performed by deleting the + `semanticTokensProvider` from the LSP client's {server_capabilities} in the + `LspAttach` callback. + + See |lsp-semantic-highlight| for more information. + +• |vim.inspect_pos()|, |vim.show_pos()| and |:Inspect| allow a user to get or show items + at a given buffer position. Currently this includes treesitter captures, + LSP semantic tokens, syntax groups and extmarks. + +• |vim.treesitter.inspect_tree()| and |:InspectTree| opens a split window + showing a text representation of the nodes in a language tree for the current + buffer. + +• |'statuscolumn'| option to customize the area to the side of a window, + normally containing the fold, sign and number columns. This new option follows + the 'statusline' syntax and can be used to transform the line numbers, create + mouse click callbacks for |signs|, introduce a custom margin or separator etc. + +• |vim.secure.trust()|, |:trust| allows the user to manage files in trust database. + |vim.secure.read()| reads a file and prompts the user if it should be + trusted and, if so, returns the file's contents. Used by 'exrc' + +• EditorConfig support is now builtin. This is enabled by default and happens + automatically. To disable it, users should add >lua + + vim.g.editorconfig = false +< + (or the Vimscript equivalent) to their |config| file. + +• A new environment variable named NVIM_APPNAME enables configuring the + directories where Neovim should find its configuration and state files. See + `:help $NVIM_APPNAME` . + +• 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 - + +• Added an omnifunc implementation for lua, |vim.lua_omnifunc()| + +• Added a new experimental |lua-loader| that byte-compiles and caches lua files. + To enable the new loader, add the following at the top of your |init.lua|: >lua + vim.loader.enable() + +• Added |lua-version| for parsing and comparing version strings conforming to + the semver specification. + +• When using Nvim inside tmux 3.2 or later, the default clipboard provider + will now copy to the system clipboard. |provider-clipboard| + +• |'showcmdloc'| option to display the 'showcmd' information in the + status line or tab line. A new %S statusline item is available to place + the 'showcmd' text in a custom 'statusline'. Useful for when |'cmdheight'| + is set to 0. + +• |'splitkeep'| option to control the scroll behavior of horizontal splits. + +• |'diffopt'| now includes a `linematch` option to enable a second-stage diff + on individual hunks to provide much more accurate diffs. This option is also + available to |vim.diff()| + + See https://github.com/neovim/neovim/pull/14537. + +• |--remote-ui| option was added to connect to a remote instance and display + in it in a |TUI| in the local terminal. This can be used run a headless nvim + instance in the background and display its UI on demand, which previously + only was possible using an external UI implementation. + +• Added a |vim.lsp.codelens.clear()| function to clear codelenses. + +• Added support for the `willSave` and `willSaveWaitUntil` capabilities to the + LSP client. `willSaveWaitUntil` allows a server to modify a document before it + gets saved. Example use-cases by language servers include removing unused + imports, or formatting the file. + +• Added preliminary support for the `workspace/didChangeWatchedFiles` capability + to the LSP client to notify servers of file changes on disk. The feature is + disabled by default and can be enabled by setting the + `workspace.didChangeWatchedFiles.dynamicRegistration=true` capability. + +• |vim.diagnostic| now supports LSP DiagnosticsTag. + See: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticTag + +• |vim.diagnostic.is_disabled()| checks if diagnostics are disabled in a given + buffer or namespace. + +• Treesitter captures can now be transformed by directives. This will allow + more complicated dynamic language injections. + +• |vim.treesitter.get_node_text()| now accepts a `metadata` option for + writing custom directives using |vim.treesitter.query.add_directive()|. + +• |vim.treesitter.language.add()| replaces `vim.treesitter.language.require_language`. + +• |vim.treesitter.foldexpr()| can be used for 'foldexpr' to use treesitter for folding. + +• Expanded the TSNode API with: + - |TSNode:tree()| + - |TSNode:has_changes()| + - |TSNode:extra()| + - |TSNode:equal()| + + Additionally |TSNode:range()| now takes an optional {include_bytes} argument. + +• Treesitter injection queries now use the format described at + https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection . + Support for the previous format will be removed in a future release. + +• Added |nvim_get_hl()| for getting highlight group definitions in a format + compatible with |nvim_set_hl()|. + +• |vim.filetype.get_option()| to get the default option value for a specific + filetype. This is a wrapper around |nvim_get_option_value()| with caching. + +• `require'bit'` is now always available |lua-bit| + +============================================================================== +CHANGED FEATURES + +The following changes to existing APIs or features add new behavior. + +• 'exrc' now supports `.nvim.lua` file. +• 'exrc' is no longer marked deprecated. + +• The |TUI| is changed to run in a separate process (previously, a separate + thread was used). This is not supposed to be a visible change to the user, + but might be the cause of subtle changes of behavior and bugs. + + Previously, the TUI could be disabled as a build time feature (+tui/-tui), + resulting in a nvim binary which only could be run headless or embedded + in an external process. As of this version, TUI is always available. + +• Vim's `has('gui_running')` is now supported as a way for plugins to check if + a GUI (not the |TUI|) is attached to Nvim. |has()| + +• |msgsep| is now always enabled even if 'display' doesn't contain the "msgsep" + flag. It is no longer possible to scroll the whole screen when showing + messages longer than 'cmdheight'. + +• API calls now show more information about where an exception happened. + +• The `win_viewport` UI event now contains information about virtual lines, + meaning that smooth scrolling can now be implemented more consistently. + +• The `:= {expr}` syntax can be used to evaluate a lua expression, as + a shorter form of `:lua ={expr}`. `:=` and `:[range]=` without argument + are unchanged. However `:=#` and similar variants using |ex-flags| + are no longer supported. + +• Unsaved changes are now preserved rather than discarded when |channel-stdio| + is closed. + +• |nvim_open_win()| now accepts a relative `mouse` option to open a floating win + relative to the mouse. Note that the mouse doesn't update frequently without + setting `vim.o.mousemoveevent = true` + +• |nvim_eval_statusline()| supports evaluating the |'statuscolumn'| through a + new `opts` field: `use_statuscol_lnum`. + +• |nvim_buf_get_extmarks()| now accepts a -1 `ns_id` to request extmarks from + all namespaces and adds the namespace id to the details array. + Other missing properties have been added to the details array and marks can + be filtered by type. + +• |vim.diagnostic.open_float()| (and therefore |vim.diagnostic.config()|) now + accepts a `suffix` option which, by default, renders LSP error codes. + Similarly, the `virtual_text` configuration in |vim.diagnostic.config()| now + has a `suffix` option which does nothing by default. + +• |vim.fs.dir()| now has a `opts` argument with a depth field to allow + recursively searching a directory tree. + +• |vim.gsplit()| supports all features of |vim.split()|. + +• |:highlight| now supports an additional attribute "altfont". + +• |:Man| manpage viewer supports manpage names containing spaces. + +• |nvim_select_popupmenu_item()| now supports |cmdline-completion| popup menu. + +• |nvim_list_uis()| reports all |ui-option| fields. + +• |nvim_get_option_value()| now has a `filetype` option so it can return the + default option for a specific filetype. + +• build: Several improvements were made to make the code generation scripts more + deterministic, and a `LUA_GEN_PRG` build parameter has been introduced to + allow for a workaround for some remaining reproducibility problems. + +============================================================================== +REMOVED FEATURES + +The following deprecated functions or APIs were removed. + +• `filetype.vim` is removed in favor of |lua-filetype| + (Note that filetype logic and tests still align with Vim, so additions or + changes need to be contributed there first.) + See https://github.com/neovim/neovim/pull/20674. + +• 'hkmap', 'hkmapp' and 'aleph' options were removed. Use 'keymap' option instead. + +• |LanguageTree:parse()| no longer returns changed regions. Please use the + `on_changedtree` callbacks instead. + +• `vim.highlight.create()`, `vim.highlight.link()` were removed, use |nvim_set_hl()| instead. + +• `require'health'` was removed. Use |vim.health| instead. + +============================================================================== +DEPRECATIONS + +The following functions are now deprecated and will be removed in the next +release. + +• |vim.treesitter.language.add()| replaces `vim.treesitter.language.require_language()` + +• |vim.treesitter.get_node_at_pos()| and |vim.treesitter.get_node_at_cursor()| + are both deprecated in favor of |vim.treesitter.get_node()|. + +• `vim.api.nvim_get_hl_by_name()`, `vim.api.nvim_get_hl_by_id()` were deprecated, use |nvim_get_hl()| instead. + +• The following top level Treesitter functions have been moved: + `vim.treesitter.inspect_language()` -> `vim.treesitter.language.inspect()` + `vim.treesitter.get_query_files()` -> `vim.treesitter.query.get_files()` + `vim.treesitter.set_query()` -> `vim.treesitter.query.set()` + `vim.treesitter.query.set_query()` -> `vim.treesitter.query.set()` + `vim.treesitter.get_query()` -> `vim.treesitter.query.get()` + `vim.treesitter.query.get_query()` -> `vim.treesitter.query.get()` + `vim.treesitter.parse_query()` -> `vim.treesitter.query.parse()` + `vim.treesitter.query.parse_query()` -> `vim.treesitter.query.parse()` + `vim.treesitter.add_predicate()` -> `vim.treesitter.query.add_predicate()` + `vim.treesitter.add_directive()` -> `vim.treesitter.query.add_directive()` + `vim.treesitter.list_predicates()` -> `vim.treesitter.query.list_predicates()` + `vim.treesitter.list_directives()` -> `vim.treesitter.query.list_directives()` + `vim.treesitter.query.get_range()` -> `vim.treesitter.get_range()` + `vim.treesitter.query.get_node_text()` -> `vim.treesitter.get_node_text()` + +• |nvim_exec()| is now deprecated in favor of |nvim_exec2()|. + +• Renamed |vim.pretty_print()| to |vim.print()|. + + vim:tw=78:ts=8:sw=2:et:ft=help:norl: diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 3ef6451ef9..6e2a1b1d3f 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -1,10 +1,12 @@ *news.txt* Nvim - NVIM REFERENCE MANUAL + NVIM REFERENCE MANUAL -Notable changes in Nvim 0.9 from 0.8 *news* +Notable changes in Nvim 0.10 from 0.9 *news* + +For changes in Nvim 0.9, see |news-0.9|. Type |gO| to see the table of contents. @@ -13,281 +15,29 @@ BREAKING CHANGES *news-breaking* The following changes may require adaptations in user config or plugins. -• Cscope support is now removed (see |cscope| and |nvim-removed|): - - Commands removed: - - `:cscope` - - `:lcscope` - - `:scscope` - - `:cstag` - - Options removed: - - `cscopepathcomp` - - `cscopeprg` - - `cscopequickfix` - - `cscoperelative` - - `cscopetag` - - `cscopetagorder` - - `cscopeverbose` - - Eval functions removed: - - `cscope_connection()` - - Note: support for |ctags| remains with no plans to remove. - - See https://github.com/neovim/neovim/pull/20545 for more information. - -• `:hardcopy` is now removed (see |hardcopy| and |nvim-removed|): - - Commands removed: - - `:hardcopy` - - Options removed: - - `printdevice` - - `printencoding` - - `printexpr` - - `printfont` - - `printheader` - - `printmbcharset` - -• 'paste' option is now deprecated and 'pastetoggle' is removed. |paste| works - automatically in GUI and terminal (TUI) Nvim. Just Paste It.™ - -• libiconv and intl are now required build dependencies. - -• Unsaved changes are now preserved rather than discarded when |channel-stdio| - is closed. - -• Changes to |vim.treesitter.get_node_text()|: - - It now returns `string`, as opposed to `string|string[]|nil`. - - The `concat` option has been removed as it was not consistently applied. - - Invalid ranges now cause an error instead of returning `nil`. - -• Renamed vim.pretty_print to vim.print. |deprecated| - -• |nvim_exec()| is now deprecated in favor of |nvim_exec2()|. - -• `help` treesitter parser was renamed to `vimdoc`. The only user-visible - change is that language-specific highlight groups need to be renamed from - `@foo.help` to `@foo.vimdoc`. - -• The default value of 'commentstring' is now empty instead of "/*%s*/". +• "#" followed by a digit no longer stands for a function key at the start of + the lhs of a mapping. ============================================================================== -NEW FEATURES *news-features* +ADDED FEATURES *news-added* The following new APIs or features were added. -• |nvim_buf_get_extmarks()| now accepts a -1 `ns_id` to request extmarks from - all namespaces and adds the namespace id to the details array. - Other missing properties have been added to the details array and marks can - be filtered by type. - -• Added a new experimental |lua-loader| that byte-compiles and caches lua files. - To enable the new loader, add the following at the top of your |init.lua|: >lua - vim.loader.enable() - -• Added |lua-version| for parsing and comparing version strings conforming to - the semver specification. - -• A new environment variable named NVIM_APPNAME enables configuring the - directories where Neovim should find its configuration and state files. See - `:help $NVIM_APPNAME` . - -• |nvim_open_win()| now accepts a relative `mouse` option to open a floating win - relative to the mouse. Note that the mouse doesn't update frequently without - setting `vim.o.mousemoveevent = true` - -• EditorConfig support is now builtin. This is enabled by default and happens - automatically. To disable it, users should add >lua - - vim.g.editorconfig = false -< - (or the Vimscript equivalent) to their |config| file. - -• 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 - - -• Added a |vim.lsp.codelens.clear()| function to clear codelenses. - -• |vim.inspect_pos()|, |vim.show_pos()| and |:Inspect| allow a user to get or show items - at a given buffer position. Currently this includes treesitter captures, - semantic tokens, syntax groups and extmarks. - -• Added support for semantic token highlighting to the LSP client. This - functionality is enabled by default when a client that supports this feature - is attached to a buffer. Opt-out can be performed by deleting the - `semanticTokensProvider` from the LSP client's {server_capabilities} in the - `LspAttach` callback. - - See |lsp-semantic-highlight| for more information. - -• |vim.treesitter.inspect_tree()| and |:InspectTree| opens a split window - showing a text representation of the nodes in a language tree for the current - buffer. - -• Added support for the `willSave` and `willSaveWaitUntil` capabilities to the - LSP client. `willSaveWaitUntil` allows a server to modify a document before it - gets saved. Example use-cases by language servers include removing unused - imports, or formatting the file. - -• Treesitter syntax highlighting for `help` files now supports highlighted - code examples. To enable, create a `.config/nvim/ftplugin/help.lua` with - the contents >lua - vim.treesitter.start() -< - Note: Highlighted code examples are only available in the Nvim manual, not - in help files taken from Vim. The treesitter `help` parser is also work in - progress and not guaranteed to correctly highlight every help file in the - wild. - -• |vim.secure.trust()|, |:trust| allows the user to manage files in trust - database. - -• |vim.diagnostic.open_float()| (and therefore |vim.diagnostic.config()|) now - accepts a `suffix` option which, by default, renders LSP error codes. - Similarly, the `virtual_text` configuration in |vim.diagnostic.config()| now - has a `suffix` option which does nothing by default. - -• |vim.fs.dir()| now has a `opts` argument with a depth field to allow - recursively searching a directory tree. - -• |vim.gsplit()| supports all features of |vim.split()|. - -• |vim.secure.read()| reads a file and prompts the user if it should be - trusted and, if so, returns the file's contents. - -• When using Nvim inside tmux 3.2 or later, the default clipboard provider - will now copy to the system clipboard. |provider-clipboard| - -• |'showcmdloc'| option to display the 'showcmd' information in the - status line or tab line. A new %S statusline item is available to place - the 'showcmd' text in a custom 'statusline'. Useful for when |'cmdheight'| - is set to 0. - -• |'splitkeep'| option to control the scroll behavior of horizontal splits. - -• |'statuscolumn'| option to customize the area to the side of a window, - normally containing the fold, sign and number columns. This new option follows - the 'statusline' syntax and can be used to transform the line numbers, create - mouse click callbacks for |signs|, introduce a custom margin or separator etc. - -• |nvim_select_popupmenu_item()| now supports |cmdline-completion| popup menu. - -• |'diffopt'| now includes a `linematch` option to enable a second-stage diff - on individual hunks to provide much more accurate diffs. This option is also - available to |vim.diff()| - - See https://github.com/neovim/neovim/pull/14537. - -• |vim.diagnostic.is_disabled()| checks if diagnostics are disabled in a given - buffer or namespace. - -• |--remote-ui| option was added to connect to a remote instance and display - in it in a |TUI| in the local terminal. This can be used run a headless nvim - instance in the background and display its UI on demand, which previously - only was possible using an external UI implementation. - -• Several improvements were made to make the code generation scripts more - deterministic, and a `LUA_GEN_PRG` build parameter has been introduced to - allow for a workaround for some remaining reproducibility problems. - -• |:highlight| now supports an additional attribute "altfont". - -• |:Man| manpage viewer supports manpage names containing spaces. - -• Treesitter captures can now be transformed by directives. This will allow - more complicated dynamic language injections. - -• |vim.treesitter.get_node_text()| now accepts a `metadata` option for - writing custom directives using |vim.treesitter.query.add_directive()|. - -• |vim.treesitter.language.add()| replaces `vim.treesitter.language.require_language`. - -• `require'bit'` is now always available |lua-bit| - -• |vim.treesitter.foldexpr()| can be used for 'foldexpr' to use treesitter for folding. - -• Expanded the TSNode API with: - - |TSNode:tree()| - - |TSNode:has_changes()| - - |TSNode:extra()| - - |TSNode:equal()| - - Additionally |TSNode:range()| now takes an optional {include_bytes} argument. - -• |nvim_list_uis()| reports all |ui-option| fields. - -• Vim's `has('gui_running')` is now supported as a way for plugins to check if - a GUI (not the |TUI|) is attached to Nvim. |has()| - -• Added preliminary support for the `workspace/didChangeWatchedFiles` capability - to the LSP client to notify servers of file changes on disk. The feature is - disabled by default and can be enabled by setting the - `workspace.didChangeWatchedFiles.dynamicRegistration=true` capability. - -• Added an omnifunc implementation for lua, |vim.lua_omnifunc()| - -• Treesitter injection queries now use the format described at - https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection . - Support for the previous format will be removed in a future release. - -• |nvim_get_option_value()| now has a `filetype` option so it can return the - default option for a specific filetype. - -• |vim.filetype.get_option()| to get the default option value for a specific - filetype. This is a wrapper around |nvim_get_option_value()| with caching. - -• Added |nvim_get_hl()| for getting highlight group definitions in a format compatible with |nvim_set_hl()|. - -• |vim.diagnostic| now supports LSP DiagnosticsTag. - See: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticTag +• ... ============================================================================== -CHANGED FEATURES *news-changes* +CHANGED FEATURES *news-changed* The following changes to existing APIs or features add new behavior. -• 'exrc' now supports `.nvim.lua` file. -• 'exrc' is no longer marked deprecated. - -• The |TUI| is changed to run in a separate process (previously, a separate - thread was used). This is not supposed to be a visible change to the user, - but might be the cause of subtle changes of behavior and bugs. - - Previously, the TUI could be disabled as a build time feature (+tui/-tui), - resulting in a nvim binary which only could be run headless or embedded - in an external process. As of this version, TUI is always available. - -• API calls now show more information about where an exception happened. - -• The `win_viewport` UI event now contains information about virtual lines, - meaning that smooth scrolling can now be implemented more consistenlty. - -• The `:= {expr}` syntax can be used to evaluate a lua expression, as - a shorter form of `:lua ={expr}`. `:=` and `:[range]=` without argument - are unchanged. However `:=#` and similar variants using |ex-flags| - are no longer supported. +• ... ============================================================================== REMOVED FEATURES *news-removed* The following deprecated functions or APIs were removed. -• It is no longer possible to scroll the whole screen when showing messages - longer than 'cmdheight'. |msgsep| is now always enabled even if 'display' - doesn't contain the "msgsep" flag. - -• `filetype.vim` is removed in favor of |lua-filetype| - (Note that filetype logic and tests still align with Vim, so additions or - changes need to be contributed there first.) - See https://github.com/neovim/neovim/pull/20674. - -• 'hkmap', 'hkmapp' and 'aleph' options were removed. Use 'keymap' option instead. - -• |LanguageTree:parse()| no longer returns changed regions. Please use the - `on_changedtree` callbacks instead. - -• `vim.highlight.create()`, `vim.highlight.link()` were removed, use |nvim_set_hl()| instead. - -• `require'health'` was removed. Use |vim.health| instead. +• ... ============================================================================== DEPRECATIONS *news-deprecations* @@ -295,27 +45,7 @@ DEPRECATIONS *news-deprecations* The following functions are now deprecated and will be removed in the next release. -• |vim.treesitter.language.add()| replaces `vim.treesitter.language.require_language()` - -• |vim.treesitter.get_node_at_pos()| and |vim.treesitter.get_node_at_cursor()| - are both deprecated in favor of |vim.treesitter.get_node()|. - -• `vim.api.nvim_get_hl_by_name()`, `vim.api.nvim_get_hl_by_id()` were deprecated, use |nvim_get_hl()| instead. +• ... -• The following top level Treesitter functions have been moved: - `vim.treesitter.inspect_language()` -> `vim.treesitter.language.inspect()` - `vim.treesitter.get_query_files()` -> `vim.treesitter.query.get_files()` - `vim.treesitter.set_query()` -> `vim.treesitter.query.set()` - `vim.treesitter.query.set_query()` -> `vim.treesitter.query.set()` - `vim.treesitter.get_query()` -> `vim.treesitter.query.get()` - `vim.treesitter.query.get_query()` -> `vim.treesitter.query.get()` - `vim.treesitter.parse_query()` -> `vim.treesitter.query.parse()` - `vim.treesitter.query.parse_query()` -> `vim.treesitter.query.parse()` - `vim.treesitter.add_predicate()` -> `vim.treesitter.query.add_predicate()` - `vim.treesitter.add_directive()` -> `vim.treesitter.query.add_directive()` - `vim.treesitter.list_predicates()` -> `vim.treesitter.query.list_predicates()` - `vim.treesitter.list_directives()` -> `vim.treesitter.query.list_directives()` - `vim.treesitter.query.get_range()` -> `vim.treesitter.get_range()` - `vim.treesitter.query.get_node_text()` -> `vim.treesitter.get_node_text()` vim:tw=78:ts=8:sw=2:et:ft=help:norl: diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 096b334cda..d22a78700f 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4846,7 +4846,7 @@ A jump table for the options with a short description can be found at |Q_op|. pack/ packages |:packadd| parser/ |treesitter| syntax parsers plugin/ plugin scripts |write-plugin| - query/ |treesitter| queries + queries/ |treesitter| queries rplugin/ |remote-plugin| scripts spell/ spell checking files |spell| syntax/ syntax files |mysyntaxfile| @@ -7256,7 +7256,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'writedelay'* *'wd'* 'writedelay' 'wd' number (default 0) global - Only takes effect toghether with 'redrawdebug'. + Only takes effect together with 'redrawdebug'. The number of milliseconds to wait after each line or each flush vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/runtime/doc/pi_health.txt b/runtime/doc/pi_health.txt index 5ba5d1beef..2ae93b098a 100644 --- a/runtime/doc/pi_health.txt +++ b/runtime/doc/pi_health.txt @@ -105,7 +105,7 @@ with your plugin name: > local M = {} M.check = function() - vim.health.report_start("my_plugin report") + vim.health.report_start("foo report") -- make sure setup function parameters are ok if check_setup() then vim.health.report_ok("Setup is correct") diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 801ea77b7f..b3a30b20e8 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -242,7 +242,7 @@ argument. *-ll* -ll {script} [args] Execute a lua script, similarly to |-l|, but the editor is not - initialized. This gives a lua enviroment similar to a worker + initialized. This gives a lua environment similar to a worker thread. See |lua-loop-threading|. Unlike `-l` no prior arguments are allowed. @@ -1394,7 +1394,7 @@ result in Neovim looking for configuration files in `$XDG_CONFIG_HOME/neovim` instead of `$XDG_CONFIG_HOME/nvim`. Note: Similarly to the $XDG environment variables, when -`$XDG_CONFIG_HOME/nvim` is mentionned, it should be understood as +`$XDG_CONFIG_HOME/nvim` is mentioned, it should be understood as `$XDG_CONFIG_HOME/$NVIM_APPNAME`. LOG FILE *log* *$NVIM_LOG_FILE* *E5430* diff --git a/runtime/doc/support.txt b/runtime/doc/support.txt index e4641751f2..80a035068a 100644 --- a/runtime/doc/support.txt +++ b/runtime/doc/support.txt @@ -14,7 +14,7 @@ Supported platforms *supported-platforms* `System` `Tier` `Versions` `Tested versions` Linux 1 >= 2.6.32, glibc >= 2.12 Ubuntu 22.04 macOS (Intel) 1 >= 10.15 macOS 12 -Windows 64-bit 1 >= 8 (see note below) Windows Server 2019 +Windows 64-bit 1 >= 8 (see note below) Windows Server 2022 FreeBSD 1 >= 10 FreeBSD 13 macOS (M1) 2 >= 10.15 OpenBSD 2 >= 7 diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index 0298f5a9b1..dc1afe89f8 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -1164,4 +1164,12 @@ LanguageTree:trees({self}) *LanguageTree:trees()* Parameters: ~ • {self} + +============================================================================== +Lua module: vim.treesitter.playground *lua-treesitter-playground* + +inspect_tree({opts}) *vim.treesitter.playground.inspect_tree()* + Parameters: ~ + • {opts} InspectTreeOpts + vim:tw=78:ts=8:sw=4:sts=4:et:ft=help:norl: diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index 8244ae4230..7b0e724e31 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -32,7 +32,8 @@ CTRL-L Clears and redraws the screen. The redraw may happen *:redraws* *:redrawstatus* :redraws[tatus][!] Redraws the status line and window bar of the current window, or all status lines and window bars if "!" is - included. Useful if 'statusline' or 'winbar' includes + included. Redraws the commandline instead if it contains + the 'ruler'. Useful if 'statusline' or 'winbar' includes an item that doesn't cause automatic updating. *:redrawt* *:redrawtabline* diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index d6ad9107b3..7228473676 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -255,6 +255,8 @@ Highlight groups: |hl-TermCursorNC| |hl-WinSeparator| highlights window separators |hl-Whitespace| highlights 'listchars' whitespace + |hl-WinBar| highlights 'winbar' + |hl-WinBarNC| highlights non-current window 'winbar' Input/Mappings: ALT (|META|) chords always work (even in the |TUI|). Map |<M-| with any key: @@ -494,8 +496,10 @@ Macro/|recording| behavior the results of keys from 'keymap'. Mappings: - Creating a mapping for a simplifiable key (e.g. <C-I>) doesn't replace an +- Creating a mapping for a simplifiable key (e.g. <C-I>) doesn't replace an existing mapping for its simplified form (e.g. <Tab>). +- "#" followed by a digit doesn't stand for a function key at the start of the + lhs of a mapping. Motion: The |jumplist| avoids useless/phantom jumps. diff --git a/runtime/lua/provider/health.lua b/runtime/lua/provider/health.lua new file mode 100644 index 0000000000..c1e4b8c23a --- /dev/null +++ b/runtime/lua/provider/health.lua @@ -0,0 +1,730 @@ +local M = {} + +local start = vim.health.report_start +local ok = vim.health.report_ok +local info = vim.health.report_info +local warn = vim.health.report_warn +local error = vim.health.report_error +local iswin = vim.loop.os_uname().sysname == 'Windows_NT' + +local shell_error_code = 0 +local function shell_error() + return shell_error_code ~= 0 +end + +-- Returns true if `cmd` exits with success, else false. +local function cmd_ok(cmd) + vim.fn.system(cmd) + return vim.v.shell_error == 0 +end + +local function executable(exe) + return vim.fn.executable(exe) == 1 +end + +local function is_blank(s) + return s:find('^%s*$') ~= nil +end + +local function isdir(path) + if not path then + return false + end + local stat = vim.loop.fs_stat(path) + if not stat then + return false + end + return stat.type == 'directory' +end + +local function isfile(path) + if not path then + return false + end + local stat = vim.loop.fs_stat(path) + if not stat then + return false + end + return stat.type == 'file' +end + +-- Handler for s:system() function. +local function system_handler(self, _, data, event) + if event == 'stderr' then + if self.add_stderr_to_output then + self.output = self.output .. vim.fn.join(data, '') + else + self.stderr = self.stderr .. vim.fn.join(data, '') + end + elseif event == 'stdout' then + self.output = self.output .. vim.fn.join(data, '') + elseif event == 'exit' then + shell_error_code = data + end +end + +-- Attempts to construct a shell command from an args list. +-- Only for display, to help users debug a failed command. +local function shellify(cmd) + if type(cmd) ~= 'table' then + return cmd + end + return vim.fn.join( + vim.fn.map(vim.fn.copy(cmd), [[v:val =~# ''\m[^\-.a-zA-Z_/]'' ? shellescape(v:val) : v:val]]), + ' ' + ) +end + +-- Run a system command and timeout after 30 seconds. +local function system(cmd, ...) + local args = { ... } + local args_count = vim.tbl_count(args) + + local stdin = (args_count > 0 and args[1] or '') + local stderr = (args_count > 1 and args[2] or false) + local ignore_error = (args_count > 2 and args[3] or false) + + local opts = { + add_stderr_to_output = stderr, + output = '', + stderr = '', + on_stdout = system_handler, + on_stderr = system_handler, + on_exit = system_handler, + } + local jobid = vim.fn.jobstart(cmd, opts) + + if jobid < 1 then + local message = 'Command error (job=' + .. jobid + .. '): `' + .. shellify(cmd) + .. '` (in ' + .. vim.fn.string(vim.fn.getcwd()) + .. ')' + + error(message) + shell_error_code = 1 + return opts.output + end + + if not is_blank(stdin) then + vim.cmd([[call jobsend(jobid, stdin)]]) + end + + local res = vim.fn.jobwait({ jobid }, 30000) + if res[1] == -1 then + error('Command timed out: ' .. shellify(cmd)) + vim.cmd([[call jobstop(jobid)]]) + elseif shell_error() and not ignore_error then + local emsg = 'Command error (job=' + .. jobid + .. ', exit code ' + .. shell_error_code + .. '): `' + .. shellify(cmd) + .. '` (in ' + .. vim.fn.string(vim.fn.getcwd()) + .. ')' + if not is_blank(opts.output) then + emsg = emsg .. '\noutput: ' .. opts.output + end + if not is_blank(opts.stderr) then + emsg = emsg .. '\nstderr: ' .. opts.stderr + end + error(emsg) + end + + -- return opts.output + local _ = ... + return vim.trim(vim.fn.system(cmd)) +end + +local function clipboard() + start('Clipboard (optional)') + + if + os.getenv('TMUX') + and executable('tmux') + and executable('pbpaste') + and not cmd_ok('pbpaste') + then + local tmux_version = string.match(vim.fn.system('tmux -V'), '%d+%.%d+') + local advice = { + 'Install tmux 2.6+. https://superuser.com/q/231130', + 'or use tmux with reattach-to-user-namespace. https://superuser.com/a/413233', + } + error('pbcopy does not work with tmux version: ' .. tmux_version, advice) + end + + local clipboard_tool = vim.fn['provider#clipboard#Executable']() + if vim.g.clipboard and is_blank(clipboard_tool) then + local error_message = vim.fn['provider#clipboard#Error']() + error( + error_message, + "Use the example in :help g:clipboard as a template, or don't set g:clipboard at all." + ) + elseif is_blank(clipboard_tool) then + warn( + 'No clipboard tool found. Clipboard registers (`"+` and `"*`) will not work.', + ':help clipboard' + ) + else + ok('Clipboard tool found: ' .. clipboard_tool) + end +end + +local function disabled_via_loaded_var(provider) + local loaded_var = 'loaded_' .. provider .. '_provider' + local v = vim.g[loaded_var] + if v == 0 then + info('Disabled (' .. loaded_var .. '=' .. v .. ').') + return true + end + return false +end + +-- Check if pyenv is available and a valid pyenv root can be found, then return +-- their respective paths. If either of those is invalid, return two empty +-- strings, effectively ignoring pyenv. +local function check_for_pyenv() + local pyenv_path = vim.fn.resolve(vim.fn.exepath('pyenv')) + + if is_blank(pyenv_path) then + return { '', '' } + end + + info('pyenv: Path: ' .. pyenv_path) + + local pyenv_root = os.getenv('PYENV_ROOT') and vim.fn.resolve('$PYENV_ROOT') or '' + + if is_blank(pyenv_root) then + pyenv_root = vim.trim(system({ pyenv_path, 'root' })) + info('pyenv: $PYENV_ROOT is not set. Infer from `pyenv root`.') + end + + if not isdir(pyenv_root) then + local message = 'pyenv: Root does not exist: ' + .. pyenv_root + .. '. Ignoring pyenv for all following checks.' + warn(message) + return { '', '' } + end + + info('pyenv: Root: ' .. pyenv_root) + + return { pyenv_path, pyenv_root } +end + +-- Check the Python interpreter's usability. +local function check_bin(bin) + if not isfile(bin) and (not iswin or not isfile(bin .. '.exe')) then + error('"' .. bin .. '" was not found.') + return false + elseif not executable(bin) then + error('"' .. bin .. '" is not executable.') + return false + end + return true +end + +-- Fetch the contents of a URL. +local function download(url) + local has_curl = executable('curl') + if has_curl and vim.fn.system({ 'curl', '-V' }):find('Protocols:.*https') then + local rv = system({ 'curl', '-sL', url }, '', 1, 1) + if shell_error() then + return 'curl error with ' .. url .. ': ' .. shell_error_code + else + return rv + end + elseif executable('python') then + local script = "try:\n\ + from urllib.request import urlopen\n\ + except ImportError:\n\ + from urllib2 import urlopen\n\ + response = urlopen('" .. url .. "')\n\ + print(response.read().decode('utf8'))\n" + local rv = system({ 'python', '-c', script }) + if is_blank(rv) and shell_error() then + return 'python urllib.request error: ' .. shell_error_code + else + return rv + end + end + + local message = 'missing `curl` ' + + if has_curl then + message = message .. '(with HTTPS support) ' + end + message = message .. 'and `python`, cannot make web request' + + return message +end + +-- Get the latest Nvim Python client (pynvim) version from PyPI. +local function latest_pypi_version() + local pypi_version = 'unable to get pypi response' + local pypi_response = download('https://pypi.python.org/pypi/pynvim/json') + if not is_blank(pypi_response) then + local pcall_ok, output = pcall(vim.fn.json_decode, pypi_response) + local pypi_data + if pcall_ok then + pypi_data = output + else + return 'error: ' .. pypi_response + end + + local pypi_element = pypi_data['info'] or {} + pypi_version = pypi_element['version'] or 'unable to parse' + end + return pypi_version +end + +local function is_bad_response(s) + local lower = s:lower() + return vim.startswith(lower, 'unable') + or vim.startswith(lower, 'error') + or vim.startswith(lower, 'outdated') +end + +-- Get version information using the specified interpreter. The interpreter is +-- used directly in case breaking changes were introduced since the last time +-- Nvim's Python client was updated. +-- +-- Returns: { +-- {python executable version}, +-- {current nvim version}, +-- {current pypi nvim status}, +-- {installed version status} +-- } +local function version_info(python) + local pypi_version = latest_pypi_version() + + local python_version = vim.trim(system({ + python, + '-c', + 'import sys; print(".".join(str(x) for x in sys.version_info[:3]))', + })) + + if is_blank(python_version) then + python_version = 'unable to parse ' .. python .. ' response' + end + + local nvim_path = vim.trim(system({ + python, + '-c', + 'import sys; sys.path = [p for p in sys.path if p != ""]; import neovim; print(neovim.__file__)', + })) + if shell_error() or is_blank(nvim_path) then + return { python_version, 'unable to load neovim Python module', pypi_version, nvim_path } + end + + -- Assuming that multiple versions of a package are installed, sort them + -- numerically in descending order. + local function compare(metapath1, metapath2) + local a = vim.fn.matchstr(vim.fn.fnamemodify(metapath1, ':p:h:t'), [[[0-9.]\+]]) + local b = vim.fn.matchstr(vim.fn.fnamemodify(metapath2, ':p:h:t'), [[[0-9.]\+]]) + if a == b then + return 0 + elseif a > b then + return 1 + else + return -1 + end + end + + -- Try to get neovim.VERSION (added in 0.1.11dev). + local nvim_version = system({ + python, + '-c', + 'from neovim import VERSION as v; print("{}.{}.{}{}".format(v.major, v.minor, v.patch, v.prerelease))', + }, '', 1, 1) + if is_blank(nvim_version) then + nvim_version = 'unable to find pynvim module version' + local base = vim.fs.basename(nvim_path, ':h') + local metas = vim.fn.glob(base .. '-*/METADATA', 1, 1) + vim.list_extend(metas, vim.fn.glob(base .. '-*/PKG-INFO', 1, 1)) + vim.list_extend(metas, vim.fn.glob(base .. '.egg-info/PKG-INFO', 1, 1)) + metas = table.sort(metas, compare) + + if metas and next(metas) ~= nil then + for _, meta_line in ipairs(vim.fn.readfile(metas[1])) do + if vim.startswith(meta_line, 'Version:') then + nvim_version = vim.fn.matchstr(meta_line, [[^Version: \zs\S\+]]) + break + end + end + end + end + + local nvim_path_base = vim.fn.fnamemodify(nvim_path, [[:~:h]]) + local version_status = 'unknown; ' .. nvim_path_base + if is_bad_response(nvim_version) and is_bad_response(pypi_version) then + if vim.version.lt(nvim_version, pypi_version) then + version_status = 'outdated; from ' .. nvim_path_base + else + version_status = 'up to date' + end + end + + return { python_version, nvim_version, pypi_version, version_status } +end + +local function python() + start('Python 3 provider (optional)') + + local pyname = 'python3' + local python_exe = '' + local virtual_env = os.getenv('VIRTUAL_ENV') + local venv = virtual_env and vim.fn.resolve(virtual_env) or '' + local host_prog_var = pyname .. '_host_prog' + local python_multiple = {} + + if disabled_via_loaded_var(pyname) then + return + end + + local pyenv_table = check_for_pyenv() + local pyenv = pyenv_table[1] + local pyenv_root = pyenv_table[2] + + if vim.g['host_prog_var'] then + local message = 'Using: g:' .. host_prog_var .. ' = "' .. vim.g['host_prog_var'] .. '"' + info(message) + end + + local python_table = vim.fn['provider#pythonx#Detect'](3) + pyname = python_table[1] + local pythonx_warnings = python_table[2] + + if is_blank(pyname) then + warn( + 'No Python executable found that can `import neovim`. ' + .. 'Using the first available executable for diagnostics.' + ) + elseif vim.g['host_prog_var'] then + python_exe = pyname + end + + -- No Python executable could `import neovim`, or host_prog_var was used. + if not is_blank(pythonx_warnings) then + warn(pythonx_warnings, { + 'See :help provider-python for more information.', + 'You may disable this provider (and warning) by adding `let g:loaded_python3_provider = 0` to your init.vim', + }) + elseif not is_blank(pyname) and is_blank(python_exe) then + if not vim.g['host_prog_var'] then + local message = '`g:' + .. host_prog_var + .. '` is not set. Searching for ' + .. pyname + .. ' in the environment.' + info(message) + end + + if not is_blank(pyenv) then + python_exe = vim.trim(system({ pyenv, 'which', pyname }, '', 1)) + if is_blank(python_exe) then + warn('pyenv could not find ' .. pyname .. '.') + end + end + + if is_blank(python_exe) then + python_exe = vim.fn.exepath(pyname) + + if os.getenv('PATH') then + local path_sep = iswin and ';' or ':' + local paths = vim.split(os.getenv('PATH') or '', path_sep) + + for _, path in ipairs(paths) do + local path_bin = vim.fs.normalize(path .. '/' .. pyname) + if + path_bin ~= vim.fs.normalize(python_exe) + and vim.tbl_contains(python_multiple, path_bin) + and executable(path_bin) + then + python_multiple[#python_multiple + 1] = path_bin + end + end + + if vim.tbl_count(python_multiple) > 0 then + -- This is worth noting since the user may install something + -- that changes $PATH, like homebrew. + local message = 'Multiple ' + .. pyname + .. ' executables found. ' + .. 'Set `g:' + .. host_prog_var + .. '` to avoid surprises.' + info(message) + end + + if python_exe:find('shims') then + local message = '`' .. python_exe .. '` appears to be a pyenv shim.' + local advice = '`pyenv` is not in $PATH, your pyenv installation is broken. Set `g:' + .. host_prog_var + .. '` to avoid surprises.' + + warn(message, advice) + end + end + end + end + + if not is_blank(python_exe) and not vim.g[host_prog_var] then + if + is_blank(venv) + and not is_blank(pyenv) + and not is_blank(pyenv_root) + and vim.startswith(vim.fn.resolve(python_exe), pyenv_root .. '/') + then + local advice = 'Create a virtualenv specifically for Nvim using pyenv, and set `g:' + .. host_prog_var + .. '`. This will avoid the need to install the pynvim module in each version/virtualenv.' + warn('pyenv is not set up optimally.', advice) + elseif not is_blank(venv) then + local venv_root + if not is_blank(pyenv_root) then + venv_root = pyenv_root + else + venv_root = vim.fs.dirname(venv) + end + + if vim.startswith(vim.fn.resolve(python_exe), venv_root .. '/') then + local advice = 'Create a virtualenv specifically for Nvim and use `g:' + .. host_prog_var + .. '`. This will avoid the need to install the pynvim module in each virtualenv.' + warn('Your virtualenv is not set up optimally.', advice) + end + end + end + + if is_blank(python_exe) and not is_blank(pyname) then + -- An error message should have already printed. + error('`' .. pyname .. '` was not found.') + elseif not is_blank(python_exe) and not check_bin(python_exe) then + python_exe = '' + end + + -- Diagnostic output + info('Executable: ' .. (is_blank(python_exe) and 'Not found' or python_exe)) + if vim.tbl_count(python_multiple) > 0 then + for _, path_bin in ipairs(python_multiple) do + info('Other python executable: ' .. path_bin) + end + end + + if is_blank(python_exe) then + -- No Python executable can import 'neovim'. Check if any Python executable + -- can import 'pynvim'. If so, that Python failed to import 'neovim' as + -- well, which is most probably due to a failed pip upgrade: + -- https://github.com/neovim/neovim/wiki/Following-HEAD#20181118 + local pynvim_table = vim.fn['provider#pythonx#DetectByModule']('pynvim', 3) + local pynvim_exe = pynvim_table[1] + if not is_blank(pynvim_exe) then + local message = 'Detected pip upgrade failure: Python executable can import "pynvim" but not "neovim": ' + .. pynvim_exe + local advice = { + 'Use that Python version to reinstall "pynvim" and optionally "neovim".', + pynvim_exe .. ' -m pip uninstall pynvim neovim', + pynvim_exe .. ' -m pip install pynvim', + pynvim_exe .. ' -m pip install neovim # only if needed by third-party software', + } + error(message, advice) + end + else + local version_info_table = version_info(python_exe) + local majorpyversion = version_info_table[1] + local current = version_info_table[2] + local latest = version_info_table[3] + local status = version_info_table[4] + + if vim.fn.str2nr(majorpyversion) ~= 3 then + warn('Unexpected Python version. This could lead to confusing error messages.') + end + + info('Python version: ' .. majorpyversion) + + if is_bad_response(status) then + info('pynvim version: ' .. current .. ' (' .. status .. ')') + else + info('pynvim version: ' .. current) + end + + if is_bad_response(current) then + error( + 'pynvim is not installed.\nError: ' .. current, + 'Run in shell: ' .. python_exe .. ' -m pip install pynvim' + ) + end + + if is_bad_response(latest) then + warn('Could not contact PyPI to get latest version.') + error('HTTP request failed: ' .. latest) + elseif is_bad_response(status) then + warn('Latest pynvim is NOT installed: ' .. latest) + elseif not is_bad_response(current) then + ok('Latest pynvim is installed.') + end + end +end + +-- Resolves Python executable path by invoking and checking `sys.executable`. +local function python_exepath(invocation) + return vim.fs.normalize( + system(vim.fn.fnameescape(invocation) .. ' -c "import sys; sys.stdout.write(sys.executable)"') + ) +end + +-- Checks that $VIRTUAL_ENV Python executables are found at front of $PATH in +-- Nvim and subshells. +local function virtualenv() + start('Python virtualenv') + if not os.getenv('VIRTUAL_ENV') then + ok('no $VIRTUAL_ENV') + return + end + local errors = {} + -- Keep hints as dict keys in order to discard duplicates. + local hints = {} + -- The virtualenv should contain some Python executables, and those + -- executables should be first both on Nvim's $PATH and the $PATH of + -- subshells launched from Nvim. + local bin_dir = (iswin and '/Scripts' or '/bin') + local venv_bins = vim.fn.glob(os.getenv('VIRTUAL_ENV') .. bin_dir .. '/python*', true, true) + -- XXX: Remove irrelevant executables found in bin/. + venv_bins = vim.fn.filter(venv_bins, 'v:val !~# "python-config"') + if vim.tbl_coun(venv_bins) > 0 then + for _, venv_bin in pairs(venv_bins) do + venv_bin = vim.fs.normalize(venv_bin) + local py_bin_basename = vim.fs.basename(venv_bin) + local nvim_py_bin = python_exepath(vim.fn.exepath(py_bin_basename)) + local subshell_py_bin = python_exepath(py_bin_basename) + if venv_bin ~= nvim_py_bin then + errors[#errors + 1] = '$PATH yields this ' + .. py_bin_basename + .. ' executable: ' + .. nvim_py_bin + local hint = '$PATH ambiguities arise if the virtualenv is not ' + .. 'properly activated prior to launching Nvim. Close Nvim, activate the virtualenv, ' + .. 'check that invoking Python from the command line launches the correct one, ' + .. 'then relaunch Nvim.' + hints[hint] = true + end + if venv_bin ~= subshell_py_bin then + errors[#errors + 1] = '$PATH in subshells yields this ' + .. py_bin_basename + .. ' executable: ' + .. subshell_py_bin + local hint = '$PATH ambiguities in subshells typically are ' + .. 'caused by your shell config overriding the $PATH previously set by the ' + .. 'virtualenv. Either prevent them from doing so, or use this workaround: ' + .. 'https://vi.stackexchange.com/a/34996' + hints[hint] = true + end + end + else + errors[#errors + 1] = 'no Python executables found in the virtualenv ' + .. bin_dir + .. ' directory.' + end + + local msg = '$VIRTUAL_ENV is set to: ' .. os.getenv('VIRTUAL_ENV') + if vim.tbl_count(errors) > 0 then + if vim.tbl_count(venv_bins) > 0 then + msg = msg + .. '\nAnd its ' + .. bin_dir + .. ' directory contains: ' + .. vim.fn.join(vim.fn.map(venv_bins, [[fnamemodify(v:val, ':t')]]), ', ') + end + local conj = '\nBut ' + for _, err in ipairs(errors) do + msg = msg .. conj .. err + conj = '\nAnd ' + end + msg = msg .. '\nSo invoking Python may lead to unexpected results.' + warn(msg, vim.fn.keys(hints)) + else + info(msg) + info( + 'Python version: ' + .. system('python -c "import platform, sys; sys.stdout.write(platform.python_version())"') + ) + ok('$VIRTUAL_ENV provides :!python.') + end +end + +local function ruby() + start('Ruby provider (optional)') + + if disabled_via_loaded_var('ruby') then + return + end + + if not executable('ruby') or not executable('gem') then + warn( + '`ruby` and `gem` must be in $PATH.', + 'Install Ruby and verify that `ruby` and `gem` commands work.' + ) + return + end + info('Ruby: ' .. system({ 'ruby', '-v' })) + + local ruby_detect_table = vim.fn['provider#ruby#Detect']() + local host = ruby_detect_table[1] + if is_blank(host) then + warn('`neovim-ruby-host` not found.', { + 'Run `gem install neovim` to ensure the neovim RubyGem is installed.', + 'Run `gem environment` to ensure the gem bin directory is in $PATH.', + 'If you are using rvm/rbenv/chruby, try "rehashing".', + 'See :help g:ruby_host_prog for non-standard gem installations.', + 'You may disable this provider (and warning) by adding `let g:loaded_ruby_provider = 0` to your init.vim', + }) + return + end + info('Host: ' .. host) + + local latest_gem_cmd = (iswin and 'cmd /c gem list -ra "^^neovim$"' or 'gem list -ra ^neovim$') + local latest_gem = system(vim.fn.split(latest_gem_cmd)) + if shell_error() or is_blank(latest_gem) then + error( + 'Failed to run: ' .. latest_gem_cmd, + { "Make sure you're connected to the internet.", 'Are you behind a firewall or proxy?' } + ) + return + end + local gem_split = vim.split(latest_gem, [[neovim (\|, \|)$]]) + latest_gem = gem_split[1] or 'not found' + + local current_gem_cmd = { host, '--version' } + local current_gem = system(current_gem_cmd) + if shell_error() then + error( + 'Failed to run: ' .. table.concat(current_gem_cmd, ' '), + { 'Report this issue with the output of: ', table.concat(current_gem_cmd, ' ') } + ) + return + end + + if vim.version.lt(current_gem, latest_gem) then + local message = 'Gem "neovim" is out-of-date. Installed: ' + .. current_gem + .. ', latest: ' + .. latest_gem + warn(message, 'Run in shell: gem update neovim') + else + ok('Latest "neovim" gem is installed: ' .. current_gem) + end +end + +function M.check() + clipboard() + python() + virtualenv() + ruby() +end + +return M diff --git a/runtime/lua/vim/F.lua b/runtime/lua/vim/F.lua index 3e370c0a84..16c834b371 100644 --- a/runtime/lua/vim/F.lua +++ b/runtime/lua/vim/F.lua @@ -1,18 +1,29 @@ local F = {} ---- Returns {a} if it is not nil, otherwise returns {b}. +--- Returns the first argument which is not nil. --- ----@generic A ----@generic B +--- If all arguments are nil, returns nil. --- ----@param a A ----@param b B ----@return A | B -function F.if_nil(a, b) - if a == nil then - return b +--- Examples: +--- <pre> +--- local a = nil +--- local b = nil +--- local c = 42 +--- local d = true +--- assert(vim.F.if_nil(a, b, c, d) == 42) +--- </pre> +--- +---@param ... any +---@return any +function F.if_nil(...) + local nargs = select('#', ...) + for i = 1, nargs do + local v = select(i, ...) + if v ~= nil then + return v + end end - return a + return nil end -- Use in combination with pcall diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 0c4b634f6f..fa0980563a 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -36,7 +36,6 @@ for k, v in pairs({ keymap = true, ui = true, health = true, - fs = true, secure = true, _watch = true, }) do diff --git a/runtime/lua/vim/_init_packages.lua b/runtime/lua/vim/_init_packages.lua index 57c0fc9122..2cf2e91a8c 100644 --- a/runtime/lua/vim/_init_packages.lua +++ b/runtime/lua/vim/_init_packages.lua @@ -54,6 +54,7 @@ require('vim.shared') vim._submodules = { inspect = true, version = true, + fs = true, } -- These are for loading runtime modules in the vim namespace lazily. diff --git a/runtime/lua/vim/_inspector.lua b/runtime/lua/vim/_inspector.lua index 92d380b08c..05983d3f0d 100644 --- a/runtime/lua/vim/_inspector.lua +++ b/runtime/lua/vim/_inspector.lua @@ -81,6 +81,12 @@ function vim.inspect_pos(bufnr, row, col, filter) end end + -- namespace id -> name map + local nsmap = {} + for name, id in pairs(vim.api.nvim_get_namespaces()) do + nsmap[id] = name + end + --- Convert an extmark tuple into a map-like table --- @private local function to_map(extmark) @@ -90,6 +96,8 @@ function vim.inspect_pos(bufnr, row, col, filter) col = extmark[3], opts = resolve_hl(extmark[4]), } + extmark.ns_id = extmark.opts.ns_id + extmark.ns = nsmap[extmark.ns_id] or '' extmark.end_row = extmark.opts.end_row or extmark.row -- inclusive extmark.end_col = extmark.opts.end_col or (extmark.col + 1) -- exclusive return extmark @@ -104,17 +112,9 @@ function vim.inspect_pos(bufnr, row, col, filter) end -- all extmarks at this position - local extmarks = {} - for ns, nsid in pairs(vim.api.nvim_get_namespaces()) do - local ns_marks = vim.api.nvim_buf_get_extmarks(bufnr, nsid, 0, -1, { details = true }) - ns_marks = vim.tbl_map(to_map, ns_marks) - ns_marks = vim.tbl_filter(is_here, ns_marks) - for _, mark in ipairs(ns_marks) do - mark.ns_id = nsid - mark.ns = ns - end - vim.list_extend(extmarks, ns_marks) - end + local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, 0, -1, { details = true }) + extmarks = vim.tbl_map(to_map, extmarks) + extmarks = vim.tbl_filter(is_here, extmarks) if filter.semantic_tokens then results.semantic_tokens = vim.tbl_filter(function(extmark) diff --git a/runtime/lua/vim/_meta.lua b/runtime/lua/vim/_meta.lua index 104f29c4c0..e3ad4d76c9 100644 --- a/runtime/lua/vim/_meta.lua +++ b/runtime/lua/vim/_meta.lua @@ -1,4 +1,4 @@ -local a = vim.api +local api = vim.api -- TODO(tjdevries): Improve option metadata so that this doesn't have to be hardcoded. -- Can be done in a separate PR. @@ -30,7 +30,7 @@ end local options_info = setmetatable({}, { __index = function(t, k) - local info = a.nvim_get_option_info(k) + local info = api.nvim_get_option_info(k) info.metatype = get_option_metatype(k, info) rawset(t, k, info) return rawget(t, k) @@ -74,12 +74,12 @@ local function new_opt_accessor(handle, scope) return new_opt_accessor(k, scope) end opt_validate(k, scope) - return a.nvim_get_option_value(k, { [scope] = handle or 0 }) + return api.nvim_get_option_value(k, { [scope] = handle or 0 }) end, __newindex = function(_, k, v) opt_validate(k, scope) - return a.nvim_set_option_value(k, v, { [scope] = handle or 0 }) + return api.nvim_set_option_value(k, v, { [scope] = handle or 0 }) end, }) end @@ -91,10 +91,10 @@ vim.wo = new_opt_accessor(nil, 'win') -- this ONLY sets the global option. like `setglobal` vim.go = setmetatable({}, { __index = function(_, k) - return a.nvim_get_option_value(k, { scope = 'global' }) + return api.nvim_get_option_value(k, { scope = 'global' }) end, __newindex = function(_, k, v) - return a.nvim_set_option_value(k, v, { scope = 'global' }) + return api.nvim_set_option_value(k, v, { scope = 'global' }) end, }) @@ -102,10 +102,10 @@ vim.go = setmetatable({}, { -- it has no additional metamethod magic. vim.o = setmetatable({}, { __index = function(_, k) - return a.nvim_get_option_value(k, {}) + return api.nvim_get_option_value(k, {}) end, __newindex = function(_, k, v) - return a.nvim_set_option_value(k, v, {}) + return api.nvim_set_option_value(k, v, {}) end, }) @@ -488,7 +488,7 @@ local function create_option_accessor(scope) -- opt[my_option] = value _set = function(self) local value = convert_value_to_vim(self._name, self._info, self._value) - a.nvim_set_option_value(self._name, value, { scope = scope }) + api.nvim_set_option_value(self._name, value, { scope = scope }) end, get = function(self) @@ -526,7 +526,7 @@ local function create_option_accessor(scope) return setmetatable({}, { __index = function(_, k) - return make_option(k, a.nvim_get_option_value(k, {})) + return make_option(k, api.nvim_get_option_value(k, {})) end, __newindex = function(_, k, v) diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index b3d9fedeae..d1eabadc4a 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -473,12 +473,12 @@ function M.fs(bufnr) if vim.g.filetype_fs then return vim.g.filetype_fs end - local line = nextnonblank(bufnr, 1) - if findany(line, { '^%s*%.?%( ', '^%s*\\G? ', '^\\$', '^%s*: %S' }) then - return 'forth' - else - return 'fsharp' + for _, line in ipairs(getlines(bufnr, 1, 100)) do + if line:find('^[:(\\] ') then + return 'forth' + end end + return 'fsharp' end function M.git(bufnr) diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 407b334f20..2a51bde263 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -216,7 +216,7 @@ function M.find(names, opts) ---@private local function add(match) - matches[#matches + 1] = match + matches[#matches + 1] = M.normalize(match) if #matches == limit then return true end diff --git a/runtime/lua/vim/loader.lua b/runtime/lua/vim/loader.lua index 201de18497..38b1e9fc0f 100644 --- a/runtime/lua/vim/loader.lua +++ b/runtime/lua/vim/loader.lua @@ -11,7 +11,7 @@ local M = {} ---@class ModuleFindOpts ---@field all? boolean Search for all matches (defaults to `false`) ---@field rtp? boolean Search for modname in the runtime path (defaults to `true`) ----@field patterns? string[] Paterns to use (defaults to `{"/init.lua", ".lua"}`) +---@field patterns? string[] Patterns to use (defaults to `{"/init.lua", ".lua"}`) ---@field paths? string[] Extra paths to search for modname ---@class ModuleInfo @@ -469,7 +469,7 @@ end ---@class ProfileOpts ---@field loaders? boolean Add profiling to the loaders ---- Debug function that wrapps all loaders and tracks stats +--- Debug function that wraps all loaders and tracks stats ---@private ---@param opts ProfileOpts? function M._profile(opts) diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 7e8c73ddb6..2d39f2d45d 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1101,21 +1101,16 @@ function lsp.start_client(config) return true end - local last_set_from = vim.fn.gettext('\n\tLast set from ') - local line = vim.fn.gettext(' line ') - local scriptname - - vim.api.nvim_buf_call(bufnr, function() - scriptname = vim.fn - .execute('verbose set ' .. option .. '?') - :match(last_set_from .. '(.*)' .. line .. '%d+') - end) + local info = vim.api.nvim_get_option_info2(option, { buf = bufnr }) + local scriptinfo = vim.tbl_filter(function(e) + return e.sid == info.last_set_sid + end, vim.fn.getscriptinfo()) - if not scriptname then + if #scriptinfo ~= 1 then return false end - return vim.startswith(vim.fn.expand(scriptname), vim.fn.expand('$VIMRUNTIME')) + return vim.startswith(scriptinfo[1].name, vim.fn.expand('$VIMRUNTIME')) end ---@private diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index 9e337e93e8..eb734fb512 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -655,7 +655,7 @@ end --- vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}} --- --> NOP (success) --- ---- vim.validate{arg1={1, {'string', table'}}} +--- vim.validate{arg1={1, {'string', 'table'}}} --- --> error('arg1: expected string|table, got number') --- --- </pre> diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index 2594c1672d..d1f5996768 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -1,4 +1,4 @@ -local a = vim.api +local api = vim.api local LanguageTree = require('vim.treesitter.languagetree') local Range = require('vim.treesitter._range') @@ -80,7 +80,7 @@ function M._create_parser(bufnr, lang, opts) local source = self:source() --[[@as integer]] - a.nvim_buf_attach( + api.nvim_buf_attach( source, false, { on_bytes = bytes_cb, on_detach = detach_cb, on_reload = reload_cb, preview = true } @@ -109,7 +109,7 @@ function M.get_parser(bufnr, lang, opts) opts = opts or {} if bufnr == nil or bufnr == 0 then - bufnr = a.nvim_get_current_buf() + bufnr = api.nvim_get_current_buf() end if not valid_lang(lang) then @@ -141,7 +141,7 @@ end ---@return boolean function M._has_parser(bufnr) if bufnr == nil or bufnr == 0 then - bufnr = a.nvim_get_current_buf() + bufnr = api.nvim_get_current_buf() end return parsers[bufnr] ~= nil end @@ -229,7 +229,7 @@ local function buf_range_get_text(buf, range) end_col = -1 end_row = end_row - 1 end - local lines = a.nvim_buf_get_text(buf, start_row, start_col, end_row, end_col, {}) + local lines = api.nvim_buf_get_text(buf, start_row, start_col, end_row, end_col, {}) return table.concat(lines, '\n') end @@ -294,7 +294,7 @@ end ---@return table[] List of captures `{ capture = "name", metadata = { ... } }` function M.get_captures_at_pos(bufnr, row, col) if bufnr == 0 then - bufnr = a.nvim_get_current_buf() + bufnr = api.nvim_get_current_buf() end local buf_highlighter = M.highlighter.active[bufnr] @@ -345,8 +345,8 @@ end ---@return string[] List of capture names function M.get_captures_at_cursor(winnr) winnr = winnr or 0 - local bufnr = a.nvim_win_get_buf(winnr) - local cursor = a.nvim_win_get_cursor(winnr) + local bufnr = api.nvim_win_get_buf(winnr) + local cursor = api.nvim_win_get_cursor(winnr) local data = M.get_captures_at_pos(bufnr, cursor[1] - 1, cursor[2]) @@ -374,7 +374,7 @@ function M.get_node(opts) local bufnr = opts.bufnr if not bufnr or bufnr == 0 then - bufnr = a.nvim_get_current_buf() + bufnr = api.nvim_get_current_buf() end local row, col @@ -383,10 +383,10 @@ function M.get_node(opts) row, col = opts.pos[1], opts.pos[2] else assert( - bufnr == a.nvim_get_current_buf(), + bufnr == api.nvim_get_current_buf(), 'Position must be explicitly provided when not using the current buffer' ) - local pos = a.nvim_win_get_cursor(0) + local pos = api.nvim_win_get_cursor(0) -- Subtract one to account for 1-based row indexing in nvim_win_get_cursor row, col = pos[1] - 1, pos[2] end @@ -417,7 +417,7 @@ end function M.get_node_at_pos(bufnr, row, col, opts) vim.deprecate('vim.treesitter.get_node_at_pos()', 'vim.treesitter.get_node()', '0.10') if bufnr == 0 then - bufnr = a.nvim_get_current_buf() + bufnr = api.nvim_get_current_buf() end local ts_range = { row, col, row, col } @@ -440,7 +440,7 @@ end function M.get_node_at_cursor(winnr) vim.deprecate('vim.treesitter.get_node_at_cursor()', 'vim.treesitter.get_node():type()', '0.10') winnr = winnr or 0 - local bufnr = a.nvim_win_get_buf(winnr) + local bufnr = api.nvim_win_get_buf(winnr) return M.get_node({ bufnr = bufnr, ignore_injections = false }):type() end @@ -465,7 +465,7 @@ end ---@param bufnr (integer|nil) Buffer to be highlighted (default: current buffer) ---@param lang (string|nil) Language of the parser (default: buffer filetype) function M.start(bufnr, lang) - bufnr = bufnr or a.nvim_get_current_buf() + bufnr = bufnr or api.nvim_get_current_buf() local parser = M.get_parser(bufnr, lang) M.highlighter.new(parser) end @@ -474,7 +474,7 @@ end --- ---@param bufnr (integer|nil) Buffer to stop highlighting (default: current buffer) function M.stop(bufnr) - bufnr = bufnr or a.nvim_get_current_buf() + bufnr = bufnr or api.nvim_get_current_buf() if M.highlighter.active[bufnr] then M.highlighter.active[bufnr]:destroy() @@ -502,208 +502,8 @@ end --- function, it accepts the buffer number of the source buffer as its only --- argument and should return a string. function M.inspect_tree(opts) - vim.validate({ - opts = { opts, 't', true }, - }) - - opts = opts or {} - - local Playground = require('vim.treesitter.playground') - local buf = a.nvim_get_current_buf() - local win = a.nvim_get_current_win() - local pg = assert(Playground:new(buf, opts.lang)) - - -- Close any existing playground window - if vim.b[buf].playground then - local w = vim.b[buf].playground - if a.nvim_win_is_valid(w) then - a.nvim_win_close(w, true) - end - end - - local w = opts.winid - if not w then - vim.cmd(opts.command or '60vnew') - w = a.nvim_get_current_win() - end - - local b = opts.bufnr - if b then - a.nvim_win_set_buf(w, b) - else - b = a.nvim_win_get_buf(w) - end - - vim.b[buf].playground = w - - vim.wo[w].scrolloff = 5 - vim.wo[w].wrap = false - 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 - local bufname = a.nvim_buf_get_name(buf) - title = string.format('Syntax tree for %s', vim.fn.fnamemodify(bufname, ':.')) - elseif type(title) == 'function' then - title = title(buf) - end - - assert(type(title) == 'string', 'Window title must be a string') - a.nvim_buf_set_name(b, title) - - pg:draw(b) - - 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', - callback = function() - local row = a.nvim_win_get_cursor(w)[1] - local pos = pg:get(row) - a.nvim_set_current_win(win) - a.nvim_win_set_cursor(win, { pos.lnum + 1, pos.col }) - end, - }) - a.nvim_buf_set_keymap(b, 'n', 'a', '', { - desc = 'Toggle anonymous nodes', - callback = function() - local row, col = unpack(a.nvim_win_get_cursor(w)) - local curnode = pg:get(row) - while curnode and not curnode.named do - row = row - 1 - curnode = pg:get(row) - end - - pg.opts.anon = not pg.opts.anon - pg:draw(b) - - if not curnode then - return - end - - local id = curnode.id - for i, node in pg:iter() do - if node.id == id then - a.nvim_win_set_cursor(w, { i, col }) - break - end - end - end, - }) - a.nvim_buf_set_keymap(b, 'n', 'I', '', { - desc = 'Toggle language display', - callback = function() - pg.opts.lang = not pg.opts.lang - pg:draw(b) - end, - }) - - local group = a.nvim_create_augroup('treesitter/playground', {}) - - a.nvim_create_autocmd('CursorMoved', { - group = group, - buffer = b, - callback = function() - a.nvim_buf_clear_namespace(buf, pg.ns, 0, -1) - local row = a.nvim_win_get_cursor(w)[1] - local pos = pg:get(row) - a.nvim_buf_set_extmark(buf, pg.ns, pos.lnum, pos.col, { - end_row = pos.end_lnum, - 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, - }) - - a.nvim_create_autocmd('CursorMoved', { - group = group, - buffer = buf, - callback = function() - if not a.nvim_buf_is_loaded(b) then - return true - end - - a.nvim_buf_clear_namespace(b, pg.ns, 0, -1) - - local cursor_node = M.get_node({ - bufnr = buf, - lang = opts.lang, - ignore_injections = false, - }) - if not cursor_node then - return - end - - local cursor_node_id = cursor_node:id() - for i, v in pg:iter() do - if v.id == cursor_node_id then - local start = v.depth - local end_col = start + #v.text - a.nvim_buf_set_extmark(b, pg.ns, i - 1, start, { - end_col = end_col, - hl_group = 'Visual', - }) - a.nvim_win_set_cursor(w, { i, 0 }) - break - end - end - end, - }) - - a.nvim_create_autocmd({ 'TextChanged', 'InsertLeave' }, { - group = group, - buffer = buf, - callback = function() - if not a.nvim_buf_is_loaded(b) then - return true - end - - pg = assert(Playground:new(buf, opts.lang)) - pg:draw(b) - end, - }) - - a.nvim_create_autocmd('BufLeave', { - group = group, - buffer = b, - callback = function() - a.nvim_buf_clear_namespace(buf, pg.ns, 0, -1) - end, - }) - - a.nvim_create_autocmd('BufLeave', { - group = group, - buffer = buf, - callback = function() - if not a.nvim_buf_is_loaded(b) then - return true - end - - a.nvim_buf_clear_namespace(b, pg.ns, 0, -1) - end, - }) - - a.nvim_create_autocmd('BufHidden', { - group = group, - buffer = buf, - once = true, - callback = function() - if a.nvim_win_is_valid(w) then - a.nvim_win_close(w, true) - end - end, - }) + ---@cast opts InspectTreeOpts + require('vim.treesitter.playground').inspect_tree(opts) end --- Returns the fold level for {lnum} in the current buffer. Can be set directly to 'foldexpr': diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index 6547ab936e..7df93d1b2e 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -68,7 +68,7 @@ function FoldInfo:add_stop(lnum) self.stop_counts[lnum] = (self.stop_counts[lnum] or 0) + 1 end ----@packag +---@package ---@param lnum integer ---@return integer function FoldInfo:get_start(lnum) diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index 729cd34090..ac2a929487 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -1,4 +1,4 @@ -local a = vim.api +local api = vim.api local query = vim.treesitter.query ---@alias TSHlIter fun(): integer, TSNode, TSMetadata @@ -25,7 +25,7 @@ TSHighlighter.active = TSHighlighter.active or {} local TSHighlighterQuery = {} TSHighlighterQuery.__index = TSHighlighterQuery -local ns = a.nvim_create_namespace('treesitter/highlighter') +local ns = api.nvim_create_namespace('treesitter/highlighter') ---@private function TSHighlighterQuery.new(lang, query_string) @@ -36,7 +36,7 @@ function TSHighlighterQuery.new(lang, query_string) local name = self._query.captures[capture] local id = 0 if not vim.startswith(name, '_') then - id = a.nvim_get_hl_id_by_name('@' .. name .. '.' .. lang) + id = api.nvim_get_hl_id_by_name('@' .. name .. '.' .. lang) end rawset(table, capture, id) @@ -121,7 +121,7 @@ function TSHighlighter.new(tree, opts) vim.cmd.runtime({ 'syntax/synload.vim', bang = true }) end - a.nvim_buf_call(self.bufnr, function() + api.nvim_buf_call(self.bufnr, function() vim.opt_local.spelloptions:append('noplainbuffer') end) @@ -140,7 +140,7 @@ function TSHighlighter:destroy() vim.bo[self.bufnr].spelloptions = self.orig_spelloptions vim.b[self.bufnr].ts_highlight = nil if vim.g.syntax_on == 1 then - a.nvim_exec_autocmds('FileType', { group = 'syntaxset', buffer = self.bufnr }) + api.nvim_exec_autocmds('FileType', { group = 'syntaxset', buffer = self.bufnr }) end end end @@ -168,7 +168,7 @@ end ---@param start_row integer ---@param new_end integer function TSHighlighter:on_bytes(_, _, start_row, _, _, _, _, _, new_end) - a.nvim__buf_redraw_range(self.bufnr, start_row, start_row + new_end + 1) + api.nvim__buf_redraw_range(self.bufnr, start_row, start_row + new_end + 1) end ---@package @@ -180,7 +180,7 @@ end ---@param changes integer[][]? function TSHighlighter:on_changedtree(changes) for _, ch in ipairs(changes or {}) do - a.nvim__buf_redraw_range(self.bufnr, ch[1], ch[3] + 1) + api.nvim__buf_redraw_range(self.bufnr, ch[1], ch[3] + 1) end end @@ -236,7 +236,8 @@ local function on_line_impl(self, buf, line, is_spell_nav) break end - local start_row, start_col, end_row, end_col = node:range() + local range = vim.treesitter.get_range(node, buf, metadata[capture]) + local start_row, start_col, _, end_row, end_col, _ = unpack(range) local hl = highlighter_query.hl_cache[capture] local capture_name = highlighter_query:query().captures[capture] @@ -251,7 +252,7 @@ local function on_line_impl(self, buf, line, is_spell_nav) local spell_pri_offset = capture_name == 'nospell' and 1 or 0 if hl and end_row >= line and (not is_spell_nav or spell ~= nil) then - a.nvim_buf_set_extmark(buf, ns, start_row, start_col, { + api.nvim_buf_set_extmark(buf, ns, start_row, start_col, { end_line = end_row, end_col = end_col, hl_group = hl, @@ -322,7 +323,7 @@ function TSHighlighter._on_win(_, _win, buf, _topline) return true end -a.nvim_set_decoration_provider(ns, { +api.nvim_set_decoration_provider(ns, { on_buf = TSHighlighter._on_buf, on_win = TSHighlighter._on_win, on_line = TSHighlighter._on_line, diff --git a/runtime/lua/vim/treesitter/language.lua b/runtime/lua/vim/treesitter/language.lua index 5b74bb6200..b616d4d70b 100644 --- a/runtime/lua/vim/treesitter/language.lua +++ b/runtime/lua/vim/treesitter/language.lua @@ -1,4 +1,4 @@ -local a = vim.api +local api = vim.api ---@class TSLanguageModule local M = {} @@ -89,7 +89,7 @@ function M.add(lang, opts) end local fname = 'parser/' .. lang .. '.*' - local paths = a.nvim_get_runtime_file(fname, false) + local paths = api.nvim_get_runtime_file(fname, false) if #paths == 0 then error("no parser for '" .. lang .. "' language, see :help treesitter-parsers") end diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua index 922e4881ca..4aa07d1b96 100644 --- a/runtime/lua/vim/treesitter/languagetree.lua +++ b/runtime/lua/vim/treesitter/languagetree.lua @@ -32,7 +32,7 @@ --- a plugin that does any kind of analysis on a tree should use a timer to throttle too frequent --- updates. -local a = vim.api +local api = vim.api local query = require('vim.treesitter.query') local language = require('vim.treesitter.language') local Range = require('vim.treesitter._range') @@ -57,7 +57,10 @@ local Range = require('vim.treesitter._range') ---@field private _injection_query Query Queries defining injected languages ---@field private _opts table Options ---@field private _parser TSParser Parser for language ----@field private _regions Range6[][] List of regions this tree should manage and parse +---@field private _has_regions boolean +---@field private _regions Range6[][]? +---List of regions this tree should manage and parse. If nil then regions are +---taken from _trees. This is mostly a short-lived cache for included_regions() ---@field private _lang string Language name ---@field private _source (integer|string) Buffer or string to parse ---@field private _trees TSTree[] Reference to parsed tree (one for each language) @@ -91,7 +94,6 @@ function LanguageTree.new(source, lang, opts) _source = source, _lang = lang, _children = {}, - _regions = {}, _trees = {}, _opts = opts, _injection_query = injections[lang] and query.parse(lang, injections[lang]) @@ -140,16 +142,16 @@ function LanguageTree:_log(...) local prefix = string.format('%s:%d: [%s:%d] ', info.name, info.currentline, self:lang(), nregions) - a.nvim_out_write(prefix) + api.nvim_out_write(prefix) for _, x in ipairs(args) do if type(x) == 'string' then - a.nvim_out_write(x) + api.nvim_out_write(x) else - a.nvim_out_write(vim.inspect(x, { newline = ' ', indent = '' })) + api.nvim_out_write(vim.inspect(x, { newline = ' ', indent = '' })) end - a.nvim_out_write(' ') + api.nvim_out_write(' ') end - a.nvim_out_write('\n') + api.nvim_out_write('\n') end --- Invalidates this parser and all its children @@ -237,27 +239,21 @@ function LanguageTree:parse() --- At least 1 region is invalid if not self:is_valid(true) then - local function _parsetree(index) - local parse_time, tree, tree_changes = - tcall(self._parser.parse, self._parser, self._trees[index], self._source) - - self:_do_callback('changedtree', tree_changes, tree) - self._trees[index] = tree - vim.list_extend(changes, tree_changes) - - total_parse_time = total_parse_time + parse_time - regions_parsed = regions_parsed + 1 - end - - if #self._regions > 0 then - for i, ranges in ipairs(self._regions) do - if not self._valid or not self._valid[i] then - self._parser:set_included_ranges(ranges) - _parsetree(i) - end + -- If there are no ranges, set to an empty list + -- so the included ranges in the parser are cleared. + for i, ranges in ipairs(self:included_regions()) do + if not self._valid or not self._valid[i] then + self._parser:set_included_ranges(ranges) + local parse_time, tree, tree_changes = + tcall(self._parser.parse, self._parser, self._trees[i], self._source) + + self:_do_callback('changedtree', tree_changes, tree) + self._trees[i] = tree + vim.list_extend(changes, tree_changes) + + total_parse_time = total_parse_time + parse_time + regions_parsed = regions_parsed + 1 end - else - _parsetree(1) end end @@ -403,7 +399,7 @@ function LanguageTree:_iter_regions(fn) local all_valid = true - for i, region in ipairs(self._regions) do + for i, region in ipairs(self:included_regions()) do if self._valid[i] == nil then self._valid[i] = true end @@ -445,6 +441,8 @@ end ---@private ---@param new_regions Range6[][] List of regions this tree should manage and parse. function LanguageTree:set_included_regions(new_regions) + self._has_regions = true + -- Transform the tables from 4 element long to 6 element long (with byte offset) for _, region in ipairs(new_regions) do for i, range in ipairs(region) do @@ -454,7 +452,7 @@ function LanguageTree:set_included_regions(new_regions) end end - if #self._regions ~= #new_regions then + if #self:included_regions() ~= #new_regions then self._trees = {} self:invalidate() else @@ -462,13 +460,29 @@ function LanguageTree:set_included_regions(new_regions) return vim.deep_equal(new_regions[i], region) end) end + self._regions = new_regions end ---Gets the set of included regions ---@return integer[][] function LanguageTree:included_regions() - return self._regions + if self._regions then + return self._regions + end + + if not self._has_regions or #self._trees == 0 then + -- treesitter.c will default empty ranges to { -1, -1, -1, -1, -1, -1} + return { {} } + end + + local regions = {} ---@type Range6[][] + for i, _ in ipairs(self._trees) do + regions[i] = self._trees[i]:included_ranges(true) + end + + self._regions = regions + return regions end ---@private @@ -721,6 +735,8 @@ function LanguageTree:_edit( ) end + self._regions = nil + local changed_range = { start_row, start_col, @@ -730,42 +746,16 @@ function LanguageTree:_edit( end_byte_old, } - local new_range = { - start_row, - start_col, - start_byte, - end_row_new, - end_col_new, - end_byte_new, - } - - if #self._regions == 0 then - self._valid = false - end - -- Validate regions after editing the tree self:_iter_regions(function(_, region) - for i, r in ipairs(region) do + if #region == 0 then + -- empty region, use the full source + return false + end + for _, r in ipairs(region) do if Range.intercepts(r, changed_range) then return false end - - -- Range after change. Adjust - if Range.cmp_pos.gt(r[1], r[2], changed_range[4], changed_range[5]) then - local byte_offset = new_range[6] - changed_range[6] - local row_offset = new_range[4] - changed_range[4] - - -- Update the range to avoid invalidation in set_included_regions() - -- which will compare the regions against the parsed injection regions - region[i] = { - r[1] + row_offset, - r[2], - r[3] + byte_offset, - r[4] + row_offset, - r[5], - r[6] + byte_offset, - } - end end return true end) diff --git a/runtime/lua/vim/treesitter/playground.lua b/runtime/lua/vim/treesitter/playground.lua index 35f06f5caf..2c0a0d1aa6 100644 --- a/runtime/lua/vim/treesitter/playground.lua +++ b/runtime/lua/vim/treesitter/playground.lua @@ -1,5 +1,8 @@ local api = vim.api +---@class TSPlaygroundModule +local M = {} + ---@class TSPlayground ---@field ns integer API namespace ---@field opts table Options table with the following keys: @@ -212,4 +215,224 @@ function TSPlayground:iter() return ipairs(self.opts.anon and self.nodes or self.named) end -return TSPlayground +--- @class InspectTreeOpts +--- @field lang string? The language of the source buffer. If omitted, the +--- filetype of the source buffer is used. +--- @field bufnr integer? Buffer to draw the tree into. If omitted, a new +--- buffer is created. +--- @field winid integer? Window id to display the tree buffer in. If omitted, +--- a new window is created with {command}. +--- @field command string? Vimscript command to create the window. Default +--- value is "60vnew". Only used when {winid} is nil. +--- @field title (string|fun(bufnr:integer):string|nil) Title of the window. If a +--- function, it accepts the buffer number of the source +--- buffer as its only argument and should return a string. + +--- @param opts InspectTreeOpts +function M.inspect_tree(opts) + vim.validate({ + opts = { opts, 't', true }, + }) + + opts = opts or {} + + local buf = api.nvim_get_current_buf() + local win = api.nvim_get_current_win() + local pg = assert(TSPlayground:new(buf, opts.lang)) + + -- Close any existing playground window + if vim.b[buf].playground then + local w = vim.b[buf].playground + if api.nvim_win_is_valid(w) then + api.nvim_win_close(w, true) + end + end + + local w = opts.winid + if not w then + vim.cmd(opts.command or '60vnew') + w = api.nvim_get_current_win() + end + + local b = opts.bufnr + if b then + api.nvim_win_set_buf(w, b) + else + b = api.nvim_win_get_buf(w) + end + + vim.b[buf].playground = w + + vim.wo[w].scrolloff = 5 + vim.wo[w].wrap = false + vim.wo[w].foldmethod = 'manual' -- disable folding + vim.bo[b].buflisted = false + vim.bo[b].buftype = 'nofile' + vim.bo[b].bufhidden = 'wipe' + vim.bo[b].filetype = 'query' + + local title --- @type string? + local opts_title = opts.title + if not opts_title then + local bufname = api.nvim_buf_get_name(buf) + title = string.format('Syntax tree for %s', vim.fn.fnamemodify(bufname, ':.')) + elseif type(opts_title) == 'function' then + title = opts_title(buf) + end + + assert(type(title) == 'string', 'Window title must be a string') + api.nvim_buf_set_name(b, title) + + pg:draw(b) + + api.nvim_buf_clear_namespace(buf, pg.ns, 0, -1) + api.nvim_buf_set_keymap(b, 'n', '<CR>', '', { + desc = 'Jump to the node under the cursor in the source buffer', + callback = function() + local row = api.nvim_win_get_cursor(w)[1] + local pos = pg:get(row) + api.nvim_set_current_win(win) + api.nvim_win_set_cursor(win, { pos.lnum + 1, pos.col }) + end, + }) + api.nvim_buf_set_keymap(b, 'n', 'a', '', { + desc = 'Toggle anonymous nodes', + callback = function() + local row, col = unpack(api.nvim_win_get_cursor(w)) + local curnode = pg:get(row) + while curnode and not curnode.named do + row = row - 1 + curnode = pg:get(row) + end + + pg.opts.anon = not pg.opts.anon + pg:draw(b) + + if not curnode then + return + end + + local id = curnode.id + for i, node in pg:iter() do + if node.id == id then + api.nvim_win_set_cursor(w, { i, col }) + break + end + end + end, + }) + api.nvim_buf_set_keymap(b, 'n', 'I', '', { + desc = 'Toggle language display', + callback = function() + pg.opts.lang = not pg.opts.lang + pg:draw(b) + end, + }) + + local group = api.nvim_create_augroup('treesitter/playground', {}) + + api.nvim_create_autocmd('CursorMoved', { + group = group, + buffer = b, + callback = function() + api.nvim_buf_clear_namespace(buf, pg.ns, 0, -1) + local row = api.nvim_win_get_cursor(w)[1] + local pos = pg:get(row) + api.nvim_buf_set_extmark(buf, pg.ns, pos.lnum, pos.col, { + end_row = pos.end_lnum, + 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 + api.nvim_win_set_cursor(win, { pos.end_lnum + 1, 0 }) + elseif pos.lnum > botline and pos.end_lnum > botline then + api.nvim_win_set_cursor(win, { pos.lnum + 1, 0 }) + end + end, + }) + + api.nvim_create_autocmd('CursorMoved', { + group = group, + buffer = buf, + callback = function() + if not api.nvim_buf_is_loaded(b) then + return true + end + + api.nvim_buf_clear_namespace(b, pg.ns, 0, -1) + + local cursor_node = vim.treesitter.get_node({ + bufnr = buf, + lang = opts.lang, + ignore_injections = false, + }) + if not cursor_node then + return + end + + local cursor_node_id = cursor_node:id() + for i, v in pg:iter() do + if v.id == cursor_node_id then + local start = v.depth + local end_col = start + #v.text + api.nvim_buf_set_extmark(b, pg.ns, i - 1, start, { + end_col = end_col, + hl_group = 'Visual', + }) + api.nvim_win_set_cursor(w, { i, 0 }) + break + end + end + end, + }) + + api.nvim_create_autocmd({ 'TextChanged', 'InsertLeave' }, { + group = group, + buffer = buf, + callback = function() + if not api.nvim_buf_is_loaded(b) then + return true + end + + pg = assert(TSPlayground:new(buf, opts.lang)) + pg:draw(b) + end, + }) + + api.nvim_create_autocmd('BufLeave', { + group = group, + buffer = b, + callback = function() + api.nvim_buf_clear_namespace(buf, pg.ns, 0, -1) + end, + }) + + api.nvim_create_autocmd('BufLeave', { + group = group, + buffer = buf, + callback = function() + if not api.nvim_buf_is_loaded(b) then + return true + end + + api.nvim_buf_clear_namespace(b, pg.ns, 0, -1) + end, + }) + + api.nvim_create_autocmd('BufHidden', { + group = group, + buffer = buf, + once = true, + callback = function() + if api.nvim_win_is_valid(w) then + api.nvim_win_close(w, true) + end + end, + }) +end + +return M diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 25623c1498..5b87e6ac31 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -1,4 +1,4 @@ -local a = vim.api +local api = vim.api local language = require('vim.treesitter.language') ---@class Query @@ -74,7 +74,7 @@ end ---@return string[] query_files List of files to load for given query and language function M.get_files(lang, query_name, is_included) local query_path = string.format('queries/%s/%s.scm', lang, query_name) - local lang_files = dedupe_files(a.nvim_get_runtime_file(query_path, true)) + local lang_files = dedupe_files(api.nvim_get_runtime_file(query_path, true)) if #lang_files == 0 then return {} @@ -635,7 +635,7 @@ end ---@return (fun(): integer, TSNode, TSMetadata): capture id, capture node, metadata function Query:iter_captures(node, source, start, stop) if type(source) == 'number' and source == 0 then - source = vim.api.nvim_get_current_buf() + source = api.nvim_get_current_buf() end start, stop = value_or_node_range(start, stop, node) @@ -690,7 +690,7 @@ end ---@return (fun(): integer, table<integer,TSNode>, table): pattern id, match, metadata function Query:iter_matches(node, source, start, stop) if type(source) == 'number' and source == 0 then - source = vim.api.nvim_get_current_buf() + source = api.nvim_get_current_buf() end start, stop = value_or_node_range(start, stop, node) diff --git a/runtime/nvim.appdata.xml b/runtime/nvim.appdata.xml index 1fe672b80b..29db9d5ee4 100644 --- a/runtime/nvim.appdata.xml +++ b/runtime/nvim.appdata.xml @@ -26,6 +26,7 @@ </screenshots> <releases> + <release date="2023-04-07" version="0.9.0"/> <release date="2023-02-02" version="0.8.3"/> <release date="2022-12-29" version="0.8.2"/> <release date="2022-11-14" version="0.8.1"/> diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index 99fd7dba42..d653f71281 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -245,7 +245,7 @@ func s:StartDebug_term(dict) " Create a hidden terminal window to communicate with gdb let s:comm_job_id = jobstart('tail -f /dev/null;#gdb communication', { - \ 'on_stdout': function('s:CommOutput'), + \ 'on_stdout': function('s:JobOutCallback', {'last_line': '', 'real_cb': function('s:CommOutput')}), \ 'pty': v:true, \ }) " hide terminal buffer @@ -430,7 +430,7 @@ func s:StartDebug_prompt(dict) " call ch_log('executing "' . join(gdb_cmd) . '"') let s:gdbjob = jobstart(gdb_cmd, { \ 'on_exit': function('s:EndPromptDebug'), - \ 'on_stdout': function('s:GdbOutCallback'), + \ 'on_stdout': function('s:JobOutCallback', {'last_line': '', 'real_cb': function('s:GdbOutCallback')}), \ }) if s:gdbjob == 0 echoerr 'invalid argument (or job table is full) while starting gdb job' @@ -594,6 +594,23 @@ func s:PromptInterrupt() endif endfunc +" Wrapper around job callback that handles partial lines (:h channel-lines). +" It should be called from a Dictionary with the following keys: +" - last_line: the last (partial) line received +" - real_cb: a callback that assumes full lines +func s:JobOutCallback(jobid, data, event) dict + let eof = (a:data == ['']) + let msgs = a:data + let msgs[0] = self.last_line .. msgs[0] + if eof + let self.last_line = '' + else + let self.last_line = msgs[-1] + unlet msgs[-1] + endif + call self.real_cb(a:jobid, msgs, a:event) +endfunc + " Function called when gdb outputs text. func s:GdbOutCallback(job_id, msgs, event) "call ch_log('received from gdb: ' . a:text) diff --git a/runtime/plugin/editorconfig.lua b/runtime/plugin/editorconfig.lua index 54cd0e828e..a96919e1fe 100644 --- a/runtime/plugin/editorconfig.lua +++ b/runtime/plugin/editorconfig.lua @@ -3,7 +3,7 @@ vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead', 'BufFilePost' }, { group = group, callback = function(args) -- Buffer-local enable has higher priority - local enable = vim.F.if_nil(vim.b.editorconfig, vim.F.if_nil(vim.g.editorconfig, true)) + local enable = vim.F.if_nil(vim.b.editorconfig, vim.g.editorconfig, true) if not enable then return end diff --git a/scripts/genappimage.sh b/scripts/genappimage.sh index dc46f4ce17..9944b5eb31 100755 --- a/scripts/genappimage.sh +++ b/scripts/genappimage.sh @@ -26,7 +26,7 @@ APP_DIR="$APP.AppDir" ######################################################################## # Build and install nvim into the AppImage -make CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_EXTRA_FLAGS="-DCI_BUILD=OFF -DCMAKE_INSTALL_PREFIX=${APP_DIR}/usr -DCMAKE_INSTALL_MANDIR=man" +make CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=${APP_DIR}/usr -DCMAKE_INSTALL_MANDIR=man" make install ######################################################################## diff --git a/src/klib/klist.h b/src/klib/klist.h index a9abbc6dc2..4274c53919 100644 --- a/src/klib/klist.h +++ b/src/klib/klist.h @@ -38,7 +38,7 @@ kmptype_t **buf; \ } kmp_##name##_t; \ static inline kmp_##name##_t *kmp_init_##name(void) { \ - return xcalloc(1, sizeof(kmp_##name##_t)); \ + return (kmp_##name##_t *)xcalloc(1, sizeof(kmp_##name##_t)); \ } \ static inline void kmp_destroy_##name(kmp_##name##_t *mp) \ REAL_FATTR_UNUSED; \ @@ -52,7 +52,7 @@ static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ mp->cnt++; \ if (mp->n == 0) { \ - return xcalloc(1, sizeof(kmptype_t)); \ + return (kmptype_t *)xcalloc(1, sizeof(kmptype_t)); \ } \ return mp->buf[--mp->n]; \ } \ @@ -60,7 +60,7 @@ mp->cnt--; \ if (mp->n == mp->max) { \ mp->max = mp->max ? (mp->max << 1) : 16; \ - mp->buf = xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ + mp->buf = (kmptype_t **)xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ } \ mp->buf[mp->n++] = p; \ } @@ -84,7 +84,7 @@ size_t size; \ } kl_##name##_t; \ static inline kl_##name##_t *kl_init_##name(void) { \ - kl_##name##_t *kl = xcalloc(1, sizeof(kl_##name##_t)); \ + kl_##name##_t *kl = (kl_##name##_t *)xcalloc(1, sizeof(kl_##name##_t)); \ kl->mp = kmp_init(name); \ kl->head = kl->tail = kmp_alloc(name, kl->mp); \ kl->head->next = 0; \ diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index cb688785df..d685e9feed 100755 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -21,7 +21,7 @@ find_package(Iconv REQUIRED) find_package(Libtermkey 0.22 REQUIRED) find_package(Libvterm 0.3 REQUIRED) find_package(Msgpack 1.0.0 REQUIRED) -find_package(Treesitter REQUIRED) +find_package(Treesitter 0.20.8 REQUIRED) find_package(Unibilium 2.0 REQUIRED) target_link_libraries(main_lib INTERFACE @@ -146,11 +146,7 @@ if(HAS_DIAG_COLOR_FLAG) endif() endif() -if($ENV{CI}) - option(CI_BUILD "CI, extra flags will be set" ON) -else() - option(CI_BUILD "CI, extra flags will be set" OFF) -endif() +option(CI_BUILD "CI, extra flags will be set" OFF) if(CI_BUILD) message(STATUS "CI build enabled") if(MSVC) @@ -255,7 +251,6 @@ set(GENERATED_UI_EVENTS_METADATA ${GENERATED_DIR}/api/private/ui_events_metadata set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h) set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h) set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h) -set(GENERATED_KEYSETS ${GENERATED_DIR}/keysets.generated.h) set(GENERATED_KEYSETS_DEFS ${GENERATED_DIR}/keysets_defs.generated.h) set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h) set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h) @@ -263,7 +258,6 @@ set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h) set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua) set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua) set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua) -set(KEYSETS_GENERATOR ${GENERATOR_DIR}/gen_keysets.lua) set(OPTIONS_GENERATOR ${GENERATOR_DIR}/gen_options.lua) set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua) set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/src/unicode) @@ -433,7 +427,6 @@ foreach(sfile ${NVIM_SOURCES} ${GENERATED_API_DISPATCH} "${GENERATED_UI_EVENTS_CALL}" "${GENERATED_UI_EVENTS_REMOTE}" - "${GENERATED_KEYSETS}" "${GENERATED_UI_EVENTS_CLIENT}" ) get_filename_component(full_d ${sfile} DIRECTORY) @@ -485,11 +478,12 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES} add_custom_command( OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA} - ${API_METADATA} ${LUA_API_C_BINDINGS} + ${API_METADATA} ${LUA_API_C_BINDINGS} ${GENERATED_KEYSETS_DEFS} COMMAND ${LUA_GEN_PRG} ${API_DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA} ${API_METADATA} ${LUA_API_C_BINDINGS} + ${GENERATED_KEYSETS_DEFS} ${API_HEADERS} DEPENDS ${API_HEADERS} @@ -560,7 +554,6 @@ list(APPEND NVIM_GENERATED_FOR_SOURCES "${GENERATED_API_DISPATCH}" "${GENERATED_EX_CMDS_DEFS}" "${GENERATED_EVENTS_NAMES_MAP}" - "${GENERATED_KEYSETS}" "${GENERATED_OPTIONS}" "${GENERATED_UNICODE_TABLES}" "${VIM_MODULE_FILE}" @@ -590,12 +583,6 @@ add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} DEPENDS ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua ) -add_custom_command(OUTPUT ${GENERATED_KEYSETS} ${GENERATED_KEYSETS_DEFS} - COMMAND ${LUA_PRG} ${KEYSETS_GENERATOR} - ${CMAKE_CURRENT_LIST_DIR} ${LUA_SHARED_MODULE_SOURCE} ${GENERATED_KEYSETS} ${GENERATED_KEYSETS_DEFS} - DEPENDS ${KEYSETS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/api/keysets.lua ${GENERATOR_HASHY} -) - add_custom_command(OUTPUT ${GENERATED_OPTIONS} COMMAND ${LUA_PRG} ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_OPTIONS} @@ -794,7 +781,7 @@ target_compile_definitions(libnvim PRIVATE MAKE_LIB) target_link_libraries(libnvim PRIVATE main_lib PUBLIC libuv) if(ENABLE_ASAN_UBSAN) - message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.") + message(STATUS "Enabling address sanitizer and undefined behavior sanitizer for nvim.") if(CI_BUILD) # Try to recover from all sanitize issues so we get reports about all failures target_compile_options(nvim PRIVATE -fsanitize-recover=all) @@ -808,7 +795,7 @@ if(ENABLE_ASAN_UBSAN) -fsanitize=undefined) target_link_libraries(nvim PRIVATE -fsanitize=address -fsanitize=undefined) elseif(ENABLE_MSAN) - message(STATUS "Enabling Clang memory sanitizer for nvim.") + message(STATUS "Enabling memory sanitizer for nvim.") target_compile_options(nvim PRIVATE -fsanitize=memory -fsanitize-memory-track-origins @@ -816,7 +803,7 @@ elseif(ENABLE_MSAN) -fno-optimize-sibling-calls) target_link_libraries(nvim PRIVATE -fsanitize=memory -fsanitize-memory-track-origins) elseif(ENABLE_TSAN) - message(STATUS "Enabling Clang thread sanitizer for nvim.") + message(STATUS "Enabling thread sanitizer for nvim.") target_compile_options(nvim PRIVATE -fsanitize=thread -fPIE) target_link_libraries(nvim PRIVATE -fsanitize=thread) endif() diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index 620a295788..6a267103b4 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -608,7 +608,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err) FOR_ALL_AUEVENTS(event) { FOREACH_ITEM(patterns, pat_object, { char *pat = pat_object.data.string.data; - if (!clear_autocmd(event, (char *)pat, au_group, err)) { + if (!clear_autocmd(event, pat, au_group, err)) { goto cleanup; } }); @@ -619,7 +619,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err) FOREACH_ITEM(patterns, pat_object, { char *pat = pat_object.data.string.data; - if (!clear_autocmd(event_nr, (char *)pat, au_group, err)) { + if (!clear_autocmd(event_nr, pat, au_group, err)) { goto cleanup; } }); diff --git a/src/nvim/api/autocmd.h b/src/nvim/api/autocmd.h index f9432830d9..3273ca5759 100644 --- a/src/nvim/api/autocmd.h +++ b/src/nvim/api/autocmd.h @@ -3,6 +3,7 @@ #include <stdint.h> +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/buffer.h b/src/nvim/api/buffer.h index 0814da63cd..db58239af8 100644 --- a/src/nvim/api/buffer.h +++ b/src/nvim/api/buffer.h @@ -3,6 +3,7 @@ #include <lauxlib.h> +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #include "nvim/buffer_defs.h" diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 26ee9205b2..3df80e3fed 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -10,6 +10,7 @@ #include "lauxlib.h" #include "nvim/api/command.h" #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/ascii.h" @@ -1015,7 +1016,7 @@ void create_user_command(uint64_t channel_id, String name, Object command, Dict( uint32_t argt = 0; int64_t def = -1; cmd_addr_T addr_type_arg = ADDR_NONE; - int compl = EXPAND_NOTHING; + int context = EXPAND_NOTHING; char *compl_arg = NULL; const char *rep = NULL; LuaRef luaref = LUA_NOREF; @@ -1161,11 +1162,11 @@ void create_user_command(uint64_t channel_id, String name, Object command, Dict( } if (opts->complete.type == kObjectTypeLuaRef) { - compl = EXPAND_USER_LUA; + context = EXPAND_USER_LUA; compl_luaref = api_new_luaref(opts->complete.data.luaref); } else if (opts->complete.type == kObjectTypeString) { VALIDATE_S(OK == parse_compl_arg(opts->complete.data.string.data, - (int)opts->complete.data.string.size, &compl, &argt, + (int)opts->complete.data.string.size, &context, &argt, &compl_arg), "complete", opts->complete.data.string.data, { goto err; @@ -1204,8 +1205,8 @@ void create_user_command(uint64_t channel_id, String name, Object command, Dict( } WITH_SCRIPT_CONTEXT(channel_id, { - if (uc_add_command(name.data, name.size, rep, argt, def, flags, compl, compl_arg, compl_luaref, - preview_luaref, addr_type_arg, luaref, force) != OK) { + if (uc_add_command(name.data, name.size, rep, argt, def, flags, context, compl_arg, + compl_luaref, preview_luaref, addr_type_arg, luaref, force) != OK) { api_set_error(err, kErrorTypeException, "Failed to create user command"); // Do not goto err, since uc_add_command now owns luaref, compl_luaref, and compl_arg } diff --git a/src/nvim/api/command.h b/src/nvim/api/command.h index b1c9230551..f16bd0acde 100644 --- a/src/nvim/api/command.h +++ b/src/nvim/api/command.h @@ -1,6 +1,7 @@ #ifndef NVIM_API_COMMAND_H #define NVIM_API_COMMAND_H +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #include "nvim/decoration.h" #include "nvim/ex_cmds.h" diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index 4afbdfa487..fc17b9d0cc 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -311,17 +311,17 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, /// /// Example: /// <pre>lua -/// local a = vim.api -/// local pos = a.nvim_win_get_cursor(0) -/// local ns = a.nvim_create_namespace('my-plugin') +/// local api = vim.api +/// local pos = api.nvim_win_get_cursor(0) +/// local ns = api.nvim_create_namespace('my-plugin') /// -- Create new extmark at line 1, column 1. -/// local m1 = a.nvim_buf_set_extmark(0, ns, 0, 0, {}) +/// local m1 = api.nvim_buf_set_extmark(0, ns, 0, 0, {}) /// -- Create new extmark at line 3, column 1. -/// local m2 = a.nvim_buf_set_extmark(0, ns, 2, 0, {}) +/// local m2 = api.nvim_buf_set_extmark(0, ns, 2, 0, {}) /// -- Get extmarks only from line 3. -/// local ms = a.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {}) +/// local ms = api.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {}) /// -- Get all marks in this buffer + namespace. -/// local all = a.nvim_buf_get_extmarks(0, ns, 0, -1, {}) +/// local all = api.nvim_buf_get_extmarks(0, ns, 0, -1, {}) /// print(vim.inspect(ms)) /// </pre> /// diff --git a/src/nvim/api/extmark.h b/src/nvim/api/extmark.h index 0a627a889c..a6586e3031 100644 --- a/src/nvim/api/extmark.h +++ b/src/nvim/api/extmark.h @@ -1,6 +1,7 @@ #ifndef NVIM_API_EXTMARK_H #define NVIM_API_EXTMARK_H +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #include "nvim/decoration.h" #include "nvim/macros.h" diff --git a/src/nvim/api/keysets.h b/src/nvim/api/keysets.h new file mode 100644 index 0000000000..333b90d7fd --- /dev/null +++ b/src/nvim/api/keysets.h @@ -0,0 +1,270 @@ +#ifndef NVIM_API_KEYSETS_H +#define NVIM_API_KEYSETS_H + +#include "nvim/api/private/defs.h" + +typedef struct { + Object types; +} Dict(context); + +typedef struct { + Object on_start; + Object on_buf; + Object on_win; + Object on_line; + Object on_end; + Object _on_hl_def; + Object _on_spell_nav; +} Dict(set_decoration_provider); + +typedef struct { + Object id; + Object end_line; + Object end_row; + Object end_col; + Object hl_group; + Object virt_text; + Object virt_text_pos; + Object virt_text_win_col; + Object virt_text_hide; + Object hl_eol; + Object hl_mode; + Object ephemeral; + Object priority; + Object right_gravity; + Object end_right_gravity; + Object virt_lines; + Object virt_lines_above; + Object virt_lines_leftcol; + Object strict; + Object sign_text; + Object sign_hl_group; + Object number_hl_group; + Object line_hl_group; + Object cursorline_hl_group; + Object conceal; + Object spell; + Object ui_watched; +} Dict(set_extmark); + +typedef struct { + Object noremap; + Object nowait; + Object silent; + Object script; + Object expr; + Object unique; + Object callback; + Object desc; + Object replace_keycodes; +} Dict(keymap); + +typedef struct { + Object builtin; +} Dict(get_commands); + +typedef struct { + Object addr; + Object bang; + Object bar; + Object complete; + Object count; + Object desc; + Object force; + Object keepscript; + Object nargs; + Object preview; + Object range; + Object register_; +} Dict(user_command); + +typedef struct { + Object row; + Object col; + Object width; + Object height; + Object anchor; + Object relative; + Object win; + Object bufpos; + Object external; + Object focusable; + Object zindex; + Object border; + Object title; + Object title_pos; + Object style; + Object noautocmd; +} Dict(float_config); + +typedef struct { + Object is_lua; + Object do_source; +} Dict(runtime); + +typedef struct { + Object winid; + Object maxwidth; + Object fillchar; + Object highlights; + Object use_winbar; + Object use_tabline; + Object use_statuscol_lnum; +} Dict(eval_statusline); + +typedef struct { + Object scope; + Object win; + Object buf; + Object filetype; +} Dict(option); + +typedef struct { + Object bold; + Object standout; + Object strikethrough; + Object underline; + Object undercurl; + Object underdouble; + Object underdotted; + Object underdashed; + Object italic; + Object reverse; + Object altfont; + Object nocombine; + Object default_; + Object cterm; + Object foreground; + Object fg; + Object background; + Object bg; + Object ctermfg; + Object ctermbg; + Object special; + Object sp; + Object link; + Object global_link; + Object fallback; + Object blend; + Object fg_indexed; + Object bg_indexed; +} Dict(highlight); + +typedef struct { + Object bold; + Object standout; + Object strikethrough; + Object underline; + Object undercurl; + Object underdouble; + Object underdotted; + Object underdashed; + Object italic; + Object reverse; + Object altfont; + Object nocombine; +} Dict(highlight_cterm); + +typedef struct { + Object id; + Object name; + Object link; +} Dict(get_highlight); + +typedef struct { + Object buffer; + Object event; + Object group; + Object pattern; +} Dict(clear_autocmds); + +typedef struct { + Object buffer; + Object callback; + Object command; + Object desc; + Object group; + Object nested; + Object once; + Object pattern; +} Dict(create_autocmd); + +typedef struct { + Object buffer; + Object group; + Object modeline; + Object pattern; + Object data; +} Dict(exec_autocmds); + +typedef struct { + Object event; + Object group; + Object pattern; + Object buffer; +} Dict(get_autocmds); + +typedef struct { + Object clear; +} Dict(create_augroup); + +typedef struct { + Object cmd; + Object range; + Object count; + Object reg; + Object bang; + Object args; + Object magic; + Object mods; + Object nargs; + Object addr; + Object nextcmd; +} Dict(cmd); + +typedef struct { + Object file; + Object bar; +} Dict(cmd_magic); + +typedef struct { + Object silent; + Object emsg_silent; + Object unsilent; + Object filter; + Object sandbox; + Object noautocmd; + Object browse; + Object confirm; + Object hide; + Object horizontal; + Object keepalt; + Object keepjumps; + Object keepmarks; + Object keeppatterns; + Object lockmarks; + Object noswapfile; + Object tab; + Object verbose; + Object vertical; + Object split; +} Dict(cmd_mods); + +typedef struct { + Object pattern; + Object force; +} Dict(cmd_mods_filter); + +typedef struct { + Object output; +} Dict(cmd_opts); + +typedef struct { + Object verbose; +} Dict(echo_opts); + +typedef struct { + Object output; +} Dict(exec_opts); + +#endif // NVIM_API_KEYSETS_H diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua deleted file mode 100644 index ce29001787..0000000000 --- a/src/nvim/api/keysets.lua +++ /dev/null @@ -1,238 +0,0 @@ -return { - { 'context', { - "types"; - }}; - { 'set_decoration_provider', { - "on_start"; - "on_buf"; - "on_win"; - "on_line"; - "on_end"; - "_on_hl_def"; - "_on_spell_nav"; - }}; - { 'set_extmark', { - "id"; - "end_line"; - "end_row"; - "end_col"; - "hl_group"; - "virt_text"; - "virt_text_pos"; - "virt_text_win_col"; - "virt_text_hide"; - "hl_eol"; - "hl_mode"; - "ephemeral"; - "priority"; - "right_gravity"; - "end_right_gravity"; - "virt_lines"; - "virt_lines_above"; - "virt_lines_leftcol"; - "strict"; - "sign_text"; - "sign_hl_group"; - "number_hl_group"; - "line_hl_group"; - "cursorline_hl_group"; - "conceal"; - "spell"; - "ui_watched"; - }}; - { 'keymap', { - "noremap"; - "nowait"; - "silent"; - "script"; - "expr"; - "unique"; - "callback"; - "desc"; - "replace_keycodes"; - }}; - { 'get_commands', { - "builtin"; - }}; - { 'user_command', { - "addr"; - "bang"; - "bar"; - "complete"; - "count"; - "desc"; - "force"; - "keepscript"; - "nargs"; - "preview"; - "range"; - "register"; - }}; - { 'float_config', { - "row"; - "col"; - "width"; - "height"; - "anchor"; - "relative"; - "win"; - "bufpos"; - "external"; - "focusable"; - "zindex"; - "border"; - "title"; - "title_pos"; - "style"; - "noautocmd"; - }}; - { 'runtime', { - "is_lua"; - "do_source"; - }}; - { 'eval_statusline', { - "winid"; - "maxwidth"; - "fillchar"; - "highlights"; - "use_winbar"; - "use_tabline"; - }}; - { 'option', { - "scope"; - "win"; - "buf"; - "filetype"; - }}; - { 'highlight', { - "bold"; - "standout"; - "strikethrough"; - "underline"; - "undercurl"; - "underdouble"; - "underdotted"; - "underdashed"; - "italic"; - "reverse"; - "altfont"; - "nocombine"; - "default"; - "cterm"; - "foreground"; "fg"; - "background"; "bg"; - "ctermfg"; - "ctermbg"; - "special"; "sp"; - "link"; - "global_link"; - "fallback"; - "blend"; - "fg_indexed"; - "bg_indexed"; - }}; - { 'highlight_cterm', { - "bold"; - "standout"; - "strikethrough"; - "underline"; - "undercurl"; - "underdouble"; - "underdotted"; - "underdashed"; - "italic"; - "reverse"; - "altfont"; - "nocombine"; - }}; - { 'get_highlight', { - "id"; - "name"; - "link"; - }}; - -- Autocmds - { 'clear_autocmds', { - "buffer"; - "event"; - "group"; - "pattern"; - }}; - { 'create_autocmd', { - "buffer"; - "callback"; - "command"; - "desc"; - "group"; - "nested"; - "once"; - "pattern"; - }}; - { 'exec_autocmds', { - "buffer"; - "group"; - "modeline"; - "pattern"; - "data"; - }}; - { 'get_autocmds', { - "event"; - "group"; - "pattern"; - "buffer"; - }}; - { 'create_augroup', { - "clear"; - }}; - { 'cmd', { - "cmd"; - "range"; - "count"; - "reg"; - "bang"; - "args"; - "magic"; - "mods"; - "nargs"; - "addr"; - "nextcmd"; - }}; - { 'cmd_magic', { - "file"; - "bar"; - }}; - { 'cmd_mods', { - "silent"; - "emsg_silent"; - "unsilent"; - "filter"; - "sandbox"; - "noautocmd"; - "browse"; - "confirm"; - "hide"; - "horizontal"; - "keepalt"; - "keepjumps"; - "keepmarks"; - "keeppatterns"; - "lockmarks"; - "noswapfile"; - "tab"; - "verbose"; - "vertical"; - "split"; - }}; - { 'cmd_mods_filter', { - "pattern"; - "force"; - }}; - { 'cmd_opts', { - "output"; - }}; - { 'echo_opts', { - "verbose"; - }}; - { 'exec_opts', { - "output"; - }}; -} diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index baeb3e88fb..467a4720a6 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -53,7 +53,7 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t } if (HAS_KEY(opts->win)) { - VALIDATE_T("win", kObjectTypeInteger, opts->win.type, { + VALIDATE_T_HANDLE("win", kObjectTypeWindow, opts->win.type, { return FAIL; }); @@ -65,7 +65,7 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t } if (HAS_KEY(opts->buf)) { - VALIDATE_T("buf", kObjectTypeInteger, opts->buf.type, { + VALIDATE_T_HANDLE("buf", kObjectTypeBuffer, opts->buf.type, { return FAIL; }); @@ -559,7 +559,7 @@ static getoption_T access_option_value(char *key, long *numval, char **stringval if (get) { return get_option_value(key, numval, stringval, NULL, opt_flags); } else { - char *errmsg; + const char *errmsg; if ((errmsg = set_option_value(key, *numval, *stringval, opt_flags))) { if (try_end(err)) { return 0; diff --git a/src/nvim/api/options.h b/src/nvim/api/options.h index efbfec3a6c..869826e443 100644 --- a/src/nvim/api/options.h +++ b/src/nvim/api/options.h @@ -1,7 +1,9 @@ #ifndef NVIM_API_OPTIONS_H #define NVIM_API_OPTIONS_H +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/options.h.generated.h" #endif diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c index 58ff552ab7..7d04d883f5 100644 --- a/src/nvim/api/private/converter.c +++ b/src/nvim/api/private/converter.c @@ -49,7 +49,7 @@ typedef struct { #define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \ do { \ const size_t len_ = (size_t)(len); \ - const char *const str_ = (const char *)(str); \ + const char *const str_ = (str); \ assert(len_ == 0 || str_ != NULL); \ kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \ } while (0) diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 8acbf0d9de..7c5559f096 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -130,8 +130,4 @@ typedef struct { size_t ptr_off; } KeySetLink; -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "keysets_defs.generated.h" -#endif - #endif // NVIM_API_PRIVATE_DEFS_H diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h index 4ae61b2bfb..78fcf88d7b 100644 --- a/src/nvim/api/private/dispatch.h +++ b/src/nvim/api/private/dispatch.h @@ -28,6 +28,7 @@ extern const MsgpackRpcRequestHandler method_handlers[]; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/private/dispatch.h.generated.h" # include "api/private/dispatch_wrappers.h.generated.h" +# include "keysets_defs.generated.h" #endif #endif // NVIM_API_PRIVATE_DISPATCH_H diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index c996e19eb9..02060a8950 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -959,12 +959,14 @@ bool set_mark(buf_T *buf, String name, Integer line, Integer col, Error *err) } /// Get default statusline highlight for window -const char *get_default_stl_hl(win_T *wp, bool use_winbar) +const char *get_default_stl_hl(win_T *wp, bool use_winbar, int stc_hl_id) { if (wp == NULL) { return "TabLineFill"; } else if (use_winbar) { return (wp == curwin) ? "WinBar" : "WinBarNC"; + } else if (stc_hl_id > 0) { + return syn_id2name(stc_hl_id); } else { return (wp == curwin) ? "StatusLine" : "StatusLineNC"; } diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index eef97cccb2..2623c97c9d 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -181,7 +181,6 @@ typedef struct { #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/private/helpers.h.generated.h" -# include "keysets.h.generated.h" #endif #define WITH_SCRIPT_CONTEXT(channel_id, code) \ diff --git a/src/nvim/api/private/validate.h b/src/nvim/api/private/validate.h index 91a92c2762..a3e77ea838 100644 --- a/src/nvim/api/private/validate.h +++ b/src/nvim/api/private/validate.h @@ -67,6 +67,15 @@ } \ } while (0) +/// Checks that actual_t is either the correct handle type or a type erased handle (integer) +#define VALIDATE_T_HANDLE(name, expected_t, actual_t, code) \ + do { \ + if (expected_t != actual_t && kObjectTypeInteger != 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)) { \ diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 5dd858a6a9..edf13b073c 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -843,7 +843,7 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int uint32_t csize = (repeat > 1) ? 3 : ((attrs[i] != last_hl) ? 2 : 1); nelem++; mpack_array(buf, csize); - mpack_str(buf, (const char *)chunk[i]); + mpack_str(buf, chunk[i]); if (csize >= 2) { mpack_uint(buf, (uint32_t)attrs[i]); if (csize >= 3) { @@ -873,7 +873,7 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int for (int i = 0; i < endcol - startcol; i++) { remote_ui_cursor_goto(ui, row, startcol + i); remote_ui_highlight_set(ui, attrs[i]); - remote_ui_put(ui, (const char *)chunk[i]); + remote_ui_put(ui, chunk[i]); if (utf_ambiguous_width(utf_ptr2char((char *)chunk[i]))) { data->client_col = -1; // force cursor update } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 9812313b7b..b62521290d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -25,6 +25,7 @@ #include "nvim/buffer.h" #include "nvim/channel.h" #include "nvim/context.h" +#include "nvim/cursor.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" @@ -59,6 +60,7 @@ #include "nvim/popupmenu.h" #include "nvim/pos.h" #include "nvim/runtime.h" +#include "nvim/sign.h" #include "nvim/state.h" #include "nvim/statusline.h" #include "nvim/strings.h" @@ -737,7 +739,7 @@ error: void nvim_out_write(String str) FUNC_API_SINCE(1) { - write_msg(str, false); + write_msg(str, false, false); } /// Writes a message to the Vim error buffer. Does not append "\n", the @@ -747,7 +749,7 @@ void nvim_out_write(String str) void nvim_err_write(String str) FUNC_API_SINCE(1) { - write_msg(str, true); + write_msg(str, true, false); } /// Writes a message to the Vim error buffer. Appends "\n", so the buffer is @@ -758,8 +760,7 @@ void nvim_err_write(String str) void nvim_err_writeln(String str) FUNC_API_SINCE(1) { - nvim_err_write(str); - nvim_err_write((String) { .data = "\n", .size = 1 }); + write_msg(str, true, true); } /// Gets the current list of buffer handles @@ -1672,23 +1673,24 @@ theend: /// /// @param message Message to write /// @param to_err true: message is an error (uses `emsg` instead of `msg`) -static void write_msg(String message, bool to_err) +/// @param writeln Append a trailing newline +static void write_msg(String message, bool to_err, bool writeln) { static StringBuilder out_line_buf = KV_INITIAL_VALUE; static StringBuilder err_line_buf = KV_INITIAL_VALUE; -#define PUSH_CHAR(i, line_buf, msg) \ +#define PUSH_CHAR(c, line_buf, msg) \ if (kv_max(line_buf) == 0) { \ kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ } \ - if (message.data[i] == NL) { \ + if (c == NL) { \ kv_push(line_buf, NUL); \ msg(line_buf.items); \ kv_drop(line_buf, kv_size(line_buf)); \ kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ - continue; \ - } \ - kv_push(line_buf, message.data[i]); + } else { \ + kv_push(line_buf, c); \ + } no_wait_return++; for (uint32_t i = 0; i < message.size; i++) { @@ -1696,9 +1698,16 @@ static void write_msg(String message, bool to_err) break; } if (to_err) { - PUSH_CHAR(i, err_line_buf, emsg); + PUSH_CHAR(message.data[i], err_line_buf, emsg); } else { - PUSH_CHAR(i, out_line_buf, msg); + PUSH_CHAR(message.data[i], out_line_buf, msg); + } + } + if (writeln) { + if (to_err) { + PUSH_CHAR(NL, err_line_buf, emsg); + } else { + PUSH_CHAR(NL, out_line_buf, msg); } } no_wait_return--; @@ -2047,6 +2056,7 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err) /// - use_winbar: (boolean) Evaluate winbar instead of statusline. /// - use_tabline: (boolean) Evaluate tabline instead of statusline. When true, {winid} /// is ignored. Mutually exclusive with {use_winbar}. +/// - use_statuscol_lnum: (number) Evaluate statuscolumn for this line number instead of statusline. /// /// @param[out] err Error details, if any. /// @return Dictionary containing statusline information, with these keys: @@ -2064,6 +2074,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int maxwidth; int fillchar = 0; + int use_bools = 0; + int statuscol_lnum = 0; Window window = 0; bool use_winbar = false; bool use_tabline = false; @@ -2104,36 +2116,48 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (HAS_KEY(opts->use_winbar)) { use_winbar = api_object_to_bool(opts->use_winbar, "use_winbar", false, err); - if (ERROR_SET(err)) { return result; } + use_bools++; } if (HAS_KEY(opts->use_tabline)) { use_tabline = api_object_to_bool(opts->use_tabline, "use_tabline", false, err); - if (ERROR_SET(err)) { return result; } + use_bools++; } - VALIDATE(!(use_winbar && use_tabline), "%s", "Cannot use both 'use_winbar' and 'use_tabline'", { + + win_T *wp = use_tabline ? curwin : find_window_by_handle(window, err); + if (wp == NULL) { + api_set_error(err, kErrorTypeException, "unknown winid %d", window); + return result; + } + + if (HAS_KEY(opts->use_statuscol_lnum)) { + VALIDATE_T("use_statuscol_lnum", kObjectTypeInteger, opts->use_statuscol_lnum.type, { + return result; + }); + statuscol_lnum = (int)opts->use_statuscol_lnum.data.integer; + VALIDATE_RANGE(statuscol_lnum > 0 && statuscol_lnum <= wp->w_buffer->b_ml.ml_line_count, + "use_statuscol_lnum", { + return result; + }); + use_bools++; + } + VALIDATE(use_bools <= 1, "%s", + "Can only use one of 'use_winbar', 'use_tabline' and 'use_statuscol_lnum'", { return result; }); - win_T *wp, *ewp; + int stc_hl_id = 0; + statuscol_T statuscol = { 0 }; + SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 }; if (use_tabline) { - wp = NULL; - ewp = curwin; fillchar = ' '; } else { - wp = find_window_by_handle(window, err); - if (wp == NULL) { - api_set_error(err, kErrorTypeException, "unknown winid %d", window); - return result; - } - ewp = wp; - if (fillchar == 0) { if (use_winbar) { fillchar = wp->w_p_fcs_chars.wbr; @@ -2142,6 +2166,40 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * fillchar = fillchar_status(&attr, wp); } } + if (statuscol_lnum) { + HlPriId line = { 0 }; + HlPriId cul = { 0 }; + HlPriId num = { 0 }; + linenr_T lnum = statuscol_lnum; + int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul); + decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul); + + statuscol.sattrs = sattrs; + statuscol.foldinfo = fold_info(wp, lnum); + wp->w_cursorline = win_cursorline_standout(wp) ? wp->w_cursor.lnum : 0; + + if (wp->w_p_cul) { + if (statuscol.foldinfo.fi_level > 0 && statuscol.foldinfo.fi_lines > 0) { + wp->w_cursorline = statuscol.foldinfo.fi_lnum; + } + statuscol.use_cul = lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR); + } + + statuscol.sign_cul_id = statuscol.use_cul ? cul.hl_id : 0; + if (num.hl_id) { + stc_hl_id = num.hl_id; + } else if (statuscol.use_cul) { + stc_hl_id = HLF_CLN + 1; + } else if (wp->w_p_rnu) { + stc_hl_id = (lnum < wp->w_cursor.lnum ? HLF_LNA : HLF_LNB) + 1; + } else { + stc_hl_id = HLF_N + 1; + } + + set_vim_var_nr(VV_LNUM, lnum); + set_vim_var_nr(VV_RELNUM, labs(get_cursor_rel_lnum(wp, lnum))); + set_vim_var_nr(VV_VIRTNUM, 0); + } } if (HAS_KEY(opts->maxwidth)) { @@ -2151,18 +2209,18 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * maxwidth = (int)opts->maxwidth.data.integer; } else { - maxwidth = (use_tabline || (!use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; + maxwidth = statuscol_lnum ? win_col_off(wp) + : (use_tabline || (!use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; } char buf[MAXPATHL]; stl_hlrec_t *hltab; - stl_hlrec_t **hltab_ptr = highlights ? &hltab : NULL; // Temporarily reset 'cursorbind' to prevent side effects from moving the cursor away and back. - int p_crb_save = ewp->w_p_crb; - ewp->w_p_crb = false; + int p_crb_save = wp->w_p_crb; + wp->w_p_crb = false; - int width = build_stl_str_hl(ewp, + int width = build_stl_str_hl(wp, buf, sizeof(buf), str.data, @@ -2170,14 +2228,14 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * 0, fillchar, maxwidth, - hltab_ptr, + highlights ? &hltab : NULL, NULL, - NULL); + statuscol_lnum ? &statuscol : NULL); PUT(result, "width", INTEGER_OBJ(width)); // Restore original value of 'cursorbind' - ewp->w_p_crb = p_crb_save; + wp->w_p_crb = p_crb_save; if (highlights) { Array hl_values = ARRAY_DICT_INIT; @@ -2188,7 +2246,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * // add the default highlight at the beginning of the highlight list if (hltab->start == NULL || (hltab->start - buf) != 0) { Dictionary hl_info = ARRAY_DICT_INIT; - grpname = get_default_stl_hl(wp, use_winbar); + grpname = get_default_stl_hl(use_tabline ? NULL : wp, use_winbar, stc_hl_id); PUT(hl_info, "start", INTEGER_OBJ(0)); PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); @@ -2202,7 +2260,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf)); if (sp->userhl == 0) { - grpname = get_default_stl_hl(wp, use_winbar); + grpname = get_default_stl_hl(use_tabline ? NULL : wp, use_winbar, stc_hl_id); } else if (sp->userhl < 0) { grpname = syn_id2name(-sp->userhl); } else { diff --git a/src/nvim/api/vim.h b/src/nvim/api/vim.h index de56c67665..c305749ba0 100644 --- a/src/nvim/api/vim.h +++ b/src/nvim/api/vim.h @@ -1,6 +1,7 @@ #ifndef NVIM_API_VIM_H #define NVIM_API_VIM_H +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/vimscript.h b/src/nvim/api/vimscript.h index be808b6b25..99ef43454b 100644 --- a/src/nvim/api/vimscript.h +++ b/src/nvim/api/vimscript.h @@ -1,6 +1,7 @@ #ifndef NVIM_API_VIMSCRIPT_H #define NVIM_API_VIMSCRIPT_H +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index b2b2b51005..c267fee39a 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -277,13 +277,13 @@ Dictionary nvim_win_get_config(Window window, Error *err) for (size_t i = 0; i < 8; i++) { Array tuple = ARRAY_DICT_INIT; - String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T)); + String s = cstrn_to_string(config->border_chars[i], sizeof(schar_T)); int hi_id = config->border_hl_ids[i]; char *hi_name = syn_id2name(hi_id); if (hi_name[0]) { ADD(tuple, STRING_OBJ(s)); - ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name))); + ADD(tuple, STRING_OBJ(cstr_to_string(hi_name))); ADD(border, ARRAY_OBJ(tuple)); } else { ADD(border, STRING_OBJ(s)); @@ -295,10 +295,9 @@ Dictionary nvim_win_get_config(Window window, Error *err) VirtText title_datas = config->title_chunks; for (size_t i = 0; i < title_datas.size; i++) { Array tuple = ARRAY_DICT_INIT; - ADD(tuple, CSTR_TO_OBJ((const char *)title_datas.items[i].text)); + ADD(tuple, CSTR_TO_OBJ(title_datas.items[i].text)); if (title_datas.items[i].hl_id > 0) { - ADD(tuple, - STRING_OBJ(cstr_to_string((const char *)syn_id2name(title_datas.items[i].hl_id)))); + ADD(tuple, STRING_OBJ(cstr_to_string(syn_id2name(title_datas.items[i].hl_id)))); } ADD(titles, ARRAY_OBJ(tuple)); } diff --git a/src/nvim/api/win_config.h b/src/nvim/api/win_config.h index d3e5ede5e9..a4614f02ce 100644 --- a/src/nvim/api/win_config.h +++ b/src/nvim/api/win_config.h @@ -1,6 +1,7 @@ #ifndef NVIM_API_WIN_CONFIG_H #define NVIM_API_WIN_CONFIG_H +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index 3882b98c2c..6735371576 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -63,7 +63,7 @@ typedef struct { # include "arglist.c.generated.h" #endif -static char e_cannot_change_arglist_recursively[] +static const char e_cannot_change_arglist_recursively[] = N_("E1156: Cannot change the argument list recursively"); enum { @@ -1230,8 +1230,7 @@ static void get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rett tv_list_alloc_ret(rettv, argcount); if (arglist != NULL) { for (int idx = 0; idx < argcount; idx++) { - tv_list_append_string(rettv->vval.v_list, - (const char *)alist_name(&arglist[idx]), -1); + tv_list_append_string(rettv->vval.v_list, alist_name(&arglist[idx]), -1); } } } @@ -1267,7 +1266,7 @@ void f_argv(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) rettv->vval.v_string = NULL; int idx = (int)tv_get_number_chk(&argvars[0], NULL); if (arglist != NULL && idx >= 0 && idx < argcount) { - rettv->vval.v_string = xstrdup((const char *)alist_name(&arglist[idx])); + rettv->vval.v_string = xstrdup(alist_name(&arglist[idx])); } else if (idx == -1) { get_arglist_as_rettv(arglist, argcount, rettv); } diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 578542adfe..726344a42b 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -939,10 +939,10 @@ void do_autocmd(exarg_T *eap, char *arg_in, int forceit) xfree(envpat); } -void do_all_autocmd_events(char *pat, bool once, int nested, char *cmd, bool delete, int group) +void do_all_autocmd_events(char *pat, bool once, int nested, char *cmd, bool del, int group) { FOR_ALL_AUEVENTS(event) { - if (do_autocmd_event(event, pat, once, nested, cmd, delete, group) + if (do_autocmd_event(event, pat, once, nested, cmd, del, group) == FAIL) { return; } @@ -956,12 +956,12 @@ void do_all_autocmd_events(char *pat, bool once, int nested, char *cmd, bool del // If *cmd == NUL: show entries. // If forceit == true: delete entries. // If group is not AUGROUP_ALL: only use this group. -int do_autocmd_event(event_T event, char *pat, bool once, int nested, char *cmd, bool delete, +int do_autocmd_event(event_T event, char *pat, bool once, int nested, char *cmd, bool del, int group) FUNC_ATTR_NONNULL_ALL { // Cannot be used to show all patterns. See au_show_for_event or au_show_for_all_events - assert(*pat != NUL || delete); + assert(*pat != NUL || del); AutoPat *ap; AutoPat **prev_ap; @@ -978,7 +978,7 @@ int do_autocmd_event(event_T event, char *pat, bool once, int nested, char *cmd, } // Delete all aupat for an event. - if (*pat == NUL && delete) { + if (*pat == NUL && del) { aupat_del_for_event_and_group(event, findgroup); return OK; } @@ -999,7 +999,7 @@ int do_autocmd_event(event_T event, char *pat, bool once, int nested, char *cmd, patlen = (int)strlen(buflocal_pat); } - if (delete) { + if (del) { assert(*pat != NUL); // Find AutoPat entries with this pattern. @@ -1421,6 +1421,8 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf) aco->save_curwin_handle = curwin->handle; aco->save_curbuf = curbuf; aco->save_prevwin_handle = prevwin == NULL ? 0 : prevwin->handle; + aco->save_State = State; + if (win != NULL) { // There is a window for "buf" in the current tab page, make it the // curwin. This is preferred, it has the least side effects (esp. if @@ -1495,7 +1497,13 @@ void aucmd_restbuf(aco_save_T *aco) } } win_found: - + // May need to stop Insert mode if we were in a prompt buffer. + leaving_window(curwin); + // Do not stop Insert mode when already in Insert mode before. + if (aco->save_State & MODE_INSERT) { + stop_insert_mode = false; + } + // Remove the window. win_remove(curwin, NULL); pmap_del(handle_T)(&window_handles, curwin->handle); if (curwin->w_grid_alloc.chars != NULL) { @@ -2497,7 +2505,7 @@ bool aupat_is_buflocal(char *pat, int patlen) int aupat_get_buflocal_nr(char *pat, int patlen) { - assert(aupat_is_buflocal((char *)pat, patlen)); + assert(aupat_is_buflocal(pat, patlen)); // "<buffer>" if (patlen == 8) { diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h index 791b589167..6dbd18ba7c 100644 --- a/src/nvim/autocmd.h +++ b/src/nvim/autocmd.h @@ -32,6 +32,7 @@ typedef struct { bufref_T new_curbuf; ///< new curbuf char *globaldir; ///< saved value of globaldir bool save_VIsual_active; ///< saved VIsual_active + int save_State; ///< saved State } aco_save_T; typedef struct AutoCmd_S AutoCmd; diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index cedbadbaf3..d1c93733c0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -106,8 +106,8 @@ # include "buffer.c.generated.h" #endif -static char *e_auabort = N_("E855: Autocommands caused command to abort"); -static char e_attempt_to_delete_buffer_that_is_in_use_str[] +static const char *e_auabort = N_("E855: Autocommands caused command to abort"); +static const char e_attempt_to_delete_buffer_that_is_in_use_str[] = N_("E937: Attempt to delete a buffer that is in use: %s"); // Number of times free_buffer() was called. @@ -268,7 +268,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags_arg) int save_bin = curbuf->b_p_bin; int perm; - perm = os_getperm((const char *)curbuf->b_ffname); + perm = os_getperm(curbuf->b_ffname); if (perm >= 0 && (0 || S_ISFIFO(perm) || S_ISSOCK(perm) # ifdef OPEN_CHR_FILES @@ -2231,7 +2231,7 @@ int buflist_findpat(const char *pattern, const char *pattern_end, bool unlisted, // Repeat this for finding an unlisted buffer if there was no matching // listed buffer. - pat = file_pat_to_reg_pat((char *)pattern, (char *)pattern_end, NULL, false); + pat = file_pat_to_reg_pat(pattern, pattern_end, NULL, false); if (pat == NULL) { return -1; } @@ -3309,8 +3309,7 @@ void maketitle(void) SPACE_FOR_FNAME + 1); buf_p += MIN(size, SPACE_FOR_FNAME); } else { - buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname), - -1, buf_p, SPACE_FOR_FNAME + 1, true); + buf_p += transstr_buf(path_tail(curbuf->b_fname), -1, buf_p, SPACE_FOR_FNAME + 1, true); } switch (bufIsChanged(curbuf) @@ -3557,7 +3556,7 @@ void fname_expand(buf_T *buf, char **ffname, char **sfname) #ifdef MSWIN if (!buf->b_p_bin) { // If the file name is a shortcut file, use the file it links to. - char *rfname = os_resolve_shortcut((const char *)(*ffname)); + char *rfname = os_resolve_shortcut(*ffname); if (rfname != NULL) { xfree(*ffname); *ffname = rfname; diff --git a/src/nvim/change.c b/src/nvim/change.c index 1500aded0c..493207d9d5 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -399,13 +399,13 @@ void changed_bytes(linenr_T lnum, colnr_T col) /// insert/delete bytes at column /// /// Like changed_bytes() but also adjust extmark for "new" bytes. -void inserted_bytes(linenr_T lnum, colnr_T col, int old, int new) +void inserted_bytes(linenr_T lnum, colnr_T start_col, int old_col, int new_col) { if (curbuf_splice_pending == 0) { - extmark_splice_cols(curbuf, (int)lnum - 1, col, old, new, kExtmarkUndo); + extmark_splice_cols(curbuf, (int)lnum - 1, start_col, old_col, new_col, kExtmarkUndo); } - changed_bytes(lnum, col); + changed_bytes(lnum, start_col); } /// Appended "count" lines below line "lnum" in the current buffer. @@ -1311,7 +1311,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) } // find start of middle part - (void)copy_option_part(&p, (char *)lead_middle, COM_MAX_LEN, ","); + (void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ","); require_blank = false; } @@ -1322,7 +1322,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) } p++; } - (void)copy_option_part(&p, (char *)lead_middle, COM_MAX_LEN, ","); + (void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ","); while (*p && p[-1] != ':') { // find end of end flags // Check whether we allow automatic ending of comments @@ -1331,7 +1331,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) } p++; } - size_t n = copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ","); + size_t n = copy_option_part(&p, lead_end, COM_MAX_LEN, ","); if (end_comment_pending == -1) { // we can set it now end_comment_pending = (unsigned char)lead_end[n - 1]; @@ -1352,7 +1352,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) // Doing "o" on a start of comment inserts the middle leader. if (lead_len > 0) { if (current_flag == COM_START) { - lead_repl = (char *)lead_middle; + lead_repl = lead_middle; lead_repl_len = (int)strlen(lead_middle); } diff --git a/src/nvim/channel.c b/src/nvim/channel.c index a0fe3cc734..820ce534e1 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -81,7 +81,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) // allow double close, even though we can't say what parts was valid. return true; } - *error = (const char *)e_invchan; + *error = e_invchan; return false; } @@ -91,19 +91,19 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) if (chan->is_rpc) { rpc_close(chan); } else if (part == kChannelPartRpc) { - *error = (const char *)e_invstream; + *error = e_invstream; return false; } } else if ((part == kChannelPartStdin || part == kChannelPartStdout) && chan->is_rpc) { - *error = (const char *)e_invstreamrpc; + *error = e_invstreamrpc; return false; } switch (chan->streamtype) { case kChannelStreamSocket: if (!close_main) { - *error = (const char *)e_invstream; + *error = e_invstream; return false; } stream_may_close(&chan->stream.socket); @@ -134,14 +134,14 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) stream_may_close(&chan->stream.stdio.out); } if (part == kChannelPartStderr) { - *error = (const char *)e_invstream; + *error = e_invstream; return false; } break; case kChannelStreamStderr: if (part != kChannelPartAll && part != kChannelPartStderr) { - *error = (const char *)e_invstream; + *error = e_invstream; return false; } if (!chan->stream.err.closed) { @@ -156,7 +156,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) case kChannelStreamInternal: if (!close_main) { - *error = (const char *)e_invstream; + *error = e_invstream; return false; } if (chan->term) { @@ -831,13 +831,12 @@ static void term_close(void *data) multiqueue_put(chan->events, term_delayed_free, 1, data); } -void channel_info_changed(Channel *chan, bool new) +void channel_info_changed(Channel *chan, bool new_chan) { - event_T event = new ? EVENT_CHANOPEN : EVENT_CHANINFO; + event_T event = new_chan ? EVENT_CHANOPEN : EVENT_CHANINFO; if (has_event(event)) { channel_incref(chan); - multiqueue_put(main_loop.events, set_info_event, - 2, chan, event); + multiqueue_put(main_loop.events, set_info_event, 2, chan, event); } } diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 5743eaead5..ca6c75b411 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -121,7 +121,7 @@ EXTERN Callback on_print INIT(= CALLBACK_INIT); /// @returns Channel with the id or NULL if not found static inline Channel *find_channel(uint64_t id) { - return pmap_get(uint64_t)(&channels, id); + return (Channel *)pmap_get(uint64_t)(&channels, id); } static inline Stream *channel_instream(Channel *chan) diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 2be8ccc456..545002a197 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -389,7 +389,7 @@ size_t transstr_buf(const char *const s, const ssize_t slen, char *const buf, co } else if (*p == TAB && !untab) { *buf_p++ = *p++; } else { - const char *const tb = (const char *)transchar_byte((uint8_t)(*p++)); + const char *const tb = transchar_byte((uint8_t)(*p++)); const size_t tb_len = strlen(tb); if (buf_p + tb_len > buf_e) { break; // Exceeded `buf` size. diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index bce28fa449..774e16f73d 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -959,7 +959,7 @@ static void showmatches_oneline(expand_T *xp, char **matches, int numMatches, in msg_outtrans_attr(matches[j], HL_ATTR(HLF_D)); p = matches[j] + strlen(matches[j]) + 1; msg_advance(maxlen + 1); - msg_puts((const char *)p); + msg_puts(p); msg_advance(maxlen + 3); msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D)); break; @@ -1438,7 +1438,7 @@ static const char *set_cmd_index(const char *cmd, exarg_T *eap, expand_T *xp, in p = cmd + 1; } else if (cmd[0] >= 'A' && cmd[0] <= 'Z') { eap->cmd = (char *)cmd; - p = (const char *)find_ucmd(eap, (char *)p, NULL, xp, complp); + p = find_ucmd(eap, (char *)p, NULL, xp, complp); if (p == NULL) { eap->cmdidx = CMD_SIZE; // Ambiguous user command. } @@ -1464,7 +1464,7 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use // Allow spaces within back-quotes to count as part of the argument // being expanded. xp->xp_pattern = skipwhite(arg); - const char *p = (const char *)xp->xp_pattern; + const char *p = xp->xp_pattern; while (*p != NUL) { int c = utf_ptr2char(p); if (c == '\\' && p[1] != NUL) { @@ -1517,7 +1517,7 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use // Check for environment variable. if (*xp->xp_pattern == '$') { - for (p = (const char *)xp->xp_pattern + 1; *p != NUL; p++) { + for (p = xp->xp_pattern + 1; *p != NUL; p++) { if (!vim_isIDc((uint8_t)(*p))) { break; } @@ -1533,12 +1533,11 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use } // Check for user names. if (*xp->xp_pattern == '~') { - for (p = (const char *)xp->xp_pattern + 1; *p != NUL && *p != '/'; p++) {} + for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; p++) {} // Complete ~user only if it partially matches a user name. // A full match ~user<Tab> will be replaced by user's home // directory i.e. something like ~user<Tab> -> /home/user/ - if (*p == NUL && p > (const char *)xp->xp_pattern + 1 - && match_user(xp->xp_pattern + 1) >= 1) { + if (*p == NUL && p > xp->xp_pattern + 1 && match_user(xp->xp_pattern + 1) >= 1) { xp->xp_context = EXPAND_USER; xp->xp_pattern++; } @@ -1550,13 +1549,13 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use static const char *set_context_in_filter_cmd(expand_T *xp, const char *arg) { if (*arg != NUL) { - arg = (const char *)skip_vimgrep_pat((char *)arg, NULL, NULL); + arg = skip_vimgrep_pat((char *)arg, NULL, NULL); } if (arg == NULL || *arg == NUL) { xp->xp_context = EXPAND_NOTHING; return NULL; } - return (const char *)skipwhite(arg); + return skipwhite(arg); } /// Set the completion context for the :match command. Returns a pointer to the @@ -1566,13 +1565,13 @@ static const char *set_context_in_match_cmd(expand_T *xp, const char *arg) if (*arg == NUL || !ends_excmd(*arg)) { // also complete "None" set_context_in_echohl_cmd(xp, arg); - arg = (const char *)skipwhite(skiptowhite(arg)); + arg = skipwhite(skiptowhite(arg)); if (*arg != NUL) { xp->xp_context = EXPAND_NOTHING; - arg = (const char *)skip_regexp((char *)arg + 1, (uint8_t)(*arg), magic_isset()); + arg = skip_regexp((char *)arg + 1, (uint8_t)(*arg), magic_isset()); } } - return (const char *)find_nextcmd(arg); + return find_nextcmd(arg); } /// Returns a pointer to the next command after a :global or a :v command. @@ -1605,7 +1604,7 @@ static const char *find_cmd_after_substitute_cmd(const char *arg) if (delim) { // Skip "from" part. arg++; - arg = (const char *)skip_regexp((char *)arg, delim, magic_isset()); + arg = skip_regexp((char *)arg, delim, magic_isset()); if (arg[0] != NUL && arg[0] == delim) { // Skip "to" part. @@ -1637,7 +1636,7 @@ static const char *find_cmd_after_substitute_cmd(const char *arg) static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg) { // Skip count. - arg = (const char *)skipwhite(skipdigits(arg)); + arg = skipwhite(skipdigits(arg)); if (*arg != '/') { return NULL; } @@ -1649,7 +1648,7 @@ static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg) } } if (*arg) { - arg = (const char *)skipwhite(arg + 1); + arg = skipwhite(arg + 1); // Check for trailing illegal characters. if (*arg == NUL || strchr("|\"\n", *arg) == NULL) { @@ -1666,7 +1665,7 @@ static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg) static const char *set_context_in_unlet_cmd(expand_T *xp, const char *arg) { while ((xp->xp_pattern = strchr(arg, ' ')) != NULL) { - arg = (const char *)xp->xp_pattern + 1; + arg = xp->xp_pattern + 1; } xp->xp_context = EXPAND_USER_VARS; @@ -1683,7 +1682,7 @@ static const char *set_context_in_unlet_cmd(expand_T *xp, const char *arg) /// Set the completion context for the :language command. Always returns NULL. static const char *set_context_in_lang_cmd(expand_T *xp, const char *arg) { - const char *p = (const char *)skiptowhite(arg); + const char *p = skiptowhite(arg); if (*p == NUL) { xp->xp_context = EXPAND_LANGUAGE; xp->xp_pattern = (char *)arg; @@ -1876,11 +1875,11 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa case CMD_dsplit: return find_cmd_after_isearch_cmd(xp, arg); case CMD_autocmd: - return (const char *)set_context_in_autocmd(xp, (char *)arg, false); + return set_context_in_autocmd(xp, (char *)arg, false); case CMD_doautocmd: case CMD_doautoall: - return (const char *)set_context_in_autocmd(xp, (char *)arg, true); + return set_context_in_autocmd(xp, (char *)arg, true); case CMD_set: set_context_in_set_cmd(xp, (char *)arg, 0); break; @@ -1957,7 +1956,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa case CMD_bwipeout: case CMD_bunload: while ((xp->xp_pattern = strchr(arg, ' ')) != NULL) { - arg = (const char *)xp->xp_pattern + 1; + arg = xp->xp_pattern + 1; } FALLTHROUGH; case CMD_buffer: @@ -2063,7 +2062,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa case CMD_tunmenu: case CMD_popup: case CMD_emenu: - return (const char *)set_context_in_menu_cmd(xp, cmd, (char *)arg, forceit); + return set_context_in_menu_cmd(xp, cmd, (char *)arg, forceit); case CMD_colorscheme: xp->xp_context = EXPAND_COLORS; @@ -2126,7 +2125,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa case CMD_argdelete: while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL) { - arg = (const char *)(xp->xp_pattern + 1); + arg = (xp->xp_pattern + 1); } xp->xp_context = EXPAND_ARGLIST; xp->xp_pattern = (char *)arg; @@ -2186,7 +2185,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff) } // 3. skip over a range specifier of the form: addr [,addr] [;addr] .. - cmd = (const char *)skip_range(cmd, &xp->xp_context); + cmd = skip_range(cmd, &xp->xp_context); xp->xp_pattern = (char *)cmd; if (*cmd == NUL) { return NULL; @@ -2218,7 +2217,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff) ea.argt = excmd_get_argt(ea.cmdidx); } - const char *arg = (const char *)skipwhite(p); + const char *arg = skipwhite(p); // Skip over ++argopt argument if ((ea.argt & EX_ARGOPT) && *arg != NUL && strncmp(arg, "++", 2) == 0) { @@ -2226,7 +2225,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff) while (*p && !ascii_isspace(*p)) { MB_PTR_ADV(p); } - arg = (const char *)skipwhite(p); + arg = skipwhite(p); } if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) { @@ -2234,7 +2233,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff) if (*++arg == '>') { arg++; } - arg = (const char *)skipwhite(arg); + arg = skipwhite(arg); } else if (*arg == '!' && ea.cmdidx == CMD_write) { // :w !filter arg++; usefilter = true; @@ -2253,14 +2252,14 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff) while (*arg == *cmd) { // allow any number of '>' or '<' arg++; } - arg = (const char *)skipwhite(arg); + arg = skipwhite(arg); } // Does command allow "+command"? if ((ea.argt & EX_CMDARG) && !usefilter && *arg == '+') { // Check if we're in the +command p = arg + 1; - arg = (const char *)skip_cmd_arg((char *)arg, false); + arg = skip_cmd_arg((char *)arg, false); // Still touching the command after '+'? if (*arg == NUL) { @@ -2268,7 +2267,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff) } // Skip space(s) after +command to get to the real argument. - arg = (const char *)skipwhite(arg); + arg = skipwhite(arg); } // Check for '|' to separate commands and '"' to start comments. @@ -2344,7 +2343,7 @@ void set_cmd_context(expand_T *xp, char *str, int len, int col, int use_ccline) old_char = str[col]; } str[col] = NUL; - const char *nextcomm = (const char *)str; + const char *nextcomm = str; if (use_ccline && ccline->cmdfirstc == '=') { // pass CMD_SIZE because there is no real command @@ -2922,7 +2921,7 @@ static void expand_shellcmd_onedir(char *buf, char *s, size_t l, char *pat, char // Check if this name was already found. hash_T hash = hash_hash(name + l); hashitem_T *hi = - hash_lookup(ht, (const char *)(name + l), strlen(name + l), hash); + hash_lookup(ht, name + l, strlen(name + l), hash); if (HASHITEM_EMPTY(hi)) { // Remove the path that was prepended. STRMOVE(name, name + l); @@ -3166,7 +3165,7 @@ static int ExpandUserList(expand_T *xp, char ***matches, int *numMatches) continue; // Skip non-string items and empty strings. } - GA_APPEND(char *, &ga, xstrdup((const char *)TV_LIST_ITEM_TV(li)->vval.v_string)); + GA_APPEND(char *, &ga, xstrdup(TV_LIST_ITEM_TV(li)->vval.v_string)); }); tv_list_unref(retlist); @@ -3195,7 +3194,7 @@ static int ExpandUserLua(expand_T *xp, int *num_file, char ***file) continue; // Skip non-string items and empty strings. } - GA_APPEND(char *, &ga, xstrdup((const char *)TV_LIST_ITEM_TV(li)->vval.v_string)); + GA_APPEND(char *, &ga, xstrdup(TV_LIST_ITEM_TV(li)->vval.v_string)); }); tv_list_unref(retlist); @@ -3551,8 +3550,7 @@ theend: tv_list_alloc_ret(rettv, xpc.xp_numfiles); for (int i = 0; i < xpc.xp_numfiles; i++) { - tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i], - -1); + tv_list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); } xfree(pat); ExpandCleanup(&xpc); diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c index c2928eb9c4..81b93e5304 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -622,7 +622,7 @@ void ex_history(exarg_T *eap) } histype1 = get_histtype(arg, (size_t)(end - arg), false); if (histype1 == HIST_INVALID) { - if (STRNICMP(arg, "all", end - (char *)arg) == 0) { + if (STRNICMP(arg, "all", end - arg) == 0) { histype1 = 0; histype2 = HIST_COUNT - 1; } else { diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index f45e13b42a..ea54554c46 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -386,7 +386,7 @@ next_mark: } void decor_redraw_signs(buf_T *buf, int row, int *num_signs, SignTextAttrs sattrs[], - HlPriAttr *num_attrs, HlPriAttr *line_attrs, HlPriAttr *cul_attrs) + HlPriId *num_id, HlPriId *line_id, HlPriId *cul_id) { if (!buf->b_signs) { return; @@ -422,23 +422,23 @@ void decor_redraw_signs(buf_T *buf, int row, int *num_signs, SignTextAttrs sattr if (j < SIGN_SHOW_MAX) { sattrs[j] = (SignTextAttrs) { .text = decor->sign_text, - .hl_attr_id = decor->sign_hl_id == 0 ? 0 : syn_id2attr(decor->sign_hl_id), + .hl_id = decor->sign_hl_id, .priority = decor->priority }; (*num_signs)++; } } - struct { HlPriAttr *dest; int hl; } cattrs[] = { - { line_attrs, decor->line_hl_id }, - { num_attrs, decor->number_hl_id }, - { cul_attrs, decor->cursorline_hl_id }, + struct { HlPriId *dest; int hl; } cattrs[] = { + { line_id, decor->line_hl_id }, + { num_id, decor->number_hl_id }, + { cul_id, decor->cursorline_hl_id }, { NULL, -1 }, }; for (int i = 0; cattrs[i].dest; i++) { if (cattrs[i].hl != 0 && decor->priority >= cattrs[i].dest->priority) { - *cattrs[i].dest = (HlPriAttr) { - .attr_id = syn_id2attr(cattrs[i].hl), + *cattrs[i].dest = (HlPriId) { + .hl_id = cattrs[i].hl, .priority = decor->priority }; } diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 2066151564..7d6349e552 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -47,11 +47,11 @@ typedef struct digraph { result_T result; } digr_T; -static char e_digraph_must_be_just_two_characters_str[] +static const char e_digraph_must_be_just_two_characters_str[] = N_("E1214: Digraph must be just two characters: %s"); -static char e_digraph_argument_must_be_one_character_str[] +static const char e_digraph_argument_must_be_one_character_str[] = N_("E1215: Digraph must be one character: %s"); -static char e_digraph_setlist_argument_must_be_list_of_lists_with_two_items[] +static const char e_digraph_setlist_argument_must_be_list_of_lists_with_two_items[] = N_("E1216: digraph_setlist() argument must be a list of lists with two items"); #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index caad88c212..fcac837993 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -508,31 +508,12 @@ static void get_sign_display_info(bool nrcol, win_T *wp, winlinevars_T *wlv, int if (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr > 0) { wlv->char_attr = sign_cul_attr; } else { - wlv->char_attr = sattr->hl_attr_id; + wlv->char_attr = sattr->hl_id ? syn_id2attr(sattr->hl_id) : 0; } } } } -static int get_sign_attrs(buf_T *buf, winlinevars_T *wlv, int *sign_num_attrp, int *sign_cul_attrp) -{ - HlPriAttr line_attrs = { wlv->line_attr, 0 }; - HlPriAttr num_attrs = { *sign_num_attrp, 0 }; - HlPriAttr cul_attrs = { *sign_cul_attrp, 0 }; - - // TODO(bfredl, vigoux): line_attr should not take priority over decoration! - int num_signs = buf_get_signattrs(buf, wlv->lnum, wlv->sattrs, &num_attrs, &line_attrs, - &cul_attrs); - decor_redraw_signs(buf, wlv->lnum - 1, &num_signs, wlv->sattrs, &num_attrs, &line_attrs, - &cul_attrs); - - wlv->line_attr = line_attrs.attr_id; - *sign_num_attrp = num_attrs.attr_id; - *sign_cul_attrp = cul_attrs.attr_id; - - return num_signs; -} - /// Returns width of the signcolumn that should be used for the whole window /// /// @param wp window we want signcolumn width from @@ -726,7 +707,7 @@ static void get_statuscol_display_info(statuscol_T *stcp, winlinevars_T *wlv) if (stcp->textp + wlv->n_extra < stcp->text_end) { int hl = stcp->hlrecp->userhl; stcp->textp = stcp->hlrecp->start; - stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : hl > 0 ? hl : stcp->num_attr; + stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr; stcp->hlrecp++; wlv->draw_state = WL_STC - 1; } @@ -1288,9 +1269,37 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, area_highlighting = true; } - int sign_num_attr = 0; // sign attribute for the number column - int sign_cul_attr = 0; // sign attribute for cursorline - int num_signs = get_sign_attrs(buf, &wlv, &sign_num_attr, &sign_cul_attr); + HlPriId line_id = { 0 }; + HlPriId sign_cul = { 0 }; + HlPriId sign_num = { 0 }; + // TODO(bfredl, vigoux): line_attr should not take priority over decoration! + int num_signs = buf_get_signattrs(buf, wlv.lnum, wlv.sattrs, &sign_num, &line_id, &sign_cul); + decor_redraw_signs(buf, wlv.lnum - 1, &num_signs, wlv.sattrs, &sign_num, &line_id, &sign_cul); + + int sign_cul_attr = 0; + int sign_num_attr = 0; + statuscol_T statuscol = { 0 }; + if (*wp->w_p_stc != NUL) { + // Draw the 'statuscolumn' if option is set. + statuscol.draw = true; + statuscol.sattrs = wlv.sattrs; + statuscol.foldinfo = foldinfo; + statuscol.width = win_col_off(wp) - (cmdwin_type != 0 && wp == curwin); + statuscol.use_cul = use_cursor_line_highlight(wp, lnum); + statuscol.sign_cul_id = statuscol.use_cul ? sign_cul.hl_id : 0; + statuscol.num_attr = sign_num.hl_id ? syn_id2attr(sign_num.hl_id) + : get_line_number_attr(wp, &wlv); + } else { + if (sign_cul.hl_id > 0) { + sign_cul_attr = syn_id2attr(sign_cul.hl_id); + } + if (sign_num.hl_id > 0) { + sign_num_attr = syn_id2attr(sign_num.hl_id); + } + } + if (line_id.hl_id > 0) { + wlv.line_attr = syn_id2attr(line_id.hl_id); + } // Highlight the current line in the quickfix window. if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) { @@ -1495,18 +1504,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, extra_check = true; } - statuscol_T statuscol = { 0 }; - if (*wp->w_p_stc != NUL) { - // Draw the 'statuscolumn' if option is set. - statuscol.draw = true; - statuscol.sattrs = wlv.sattrs; - statuscol.foldinfo = foldinfo; - statuscol.width = win_col_off(wp) - (cmdwin_type != 0 && wp == curwin); - statuscol.use_cul = use_cursor_line_highlight(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, &wlv); - } - int sign_idx = 0; int virt_line_index; int virt_line_offset = -1; @@ -2970,16 +2967,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, wlv.need_showbreak = true; } if (statuscol.draw) { - if (wlv.row == startrow + wlv.filler_lines + 1 - || wlv.row == startrow + wlv.filler_lines) { - // Re-evaluate 'statuscolumn' for the first wrapped row and non filler line - statuscol.textp = NULL; - } else if (statuscol.textp) { + if (wlv.row == startrow + wlv.filler_lines) { + statuscol.textp = NULL; // re-evaluate for first non-filler line + } else if (vim_strchr(p_cpo, CPO_NUMCOL) && wlv.row > startrow + wlv.filler_lines) { + statuscol.draw = false; // don't draw status column if "n" is in 'cpo' + } else if (wlv.row == startrow + wlv.filler_lines + 1) { + statuscol.textp = NULL; // re-evaluate for first wrapped line + } else { // Draw the already built 'statuscolumn' on the next wrapped or filler line statuscol.textp = statuscol.text; statuscol.hlrecp = statuscol.hlrec; - } // Fall back to default columns if the 'n' flag isn't in 'cpo' - statuscol.draw = vim_strchr(p_cpo, CPO_NUMCOL) == NULL; + } } wlv.filler_todo--; virt_line_offset = -1; diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index f90a41c406..5ced55b2c7 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -2683,6 +2683,11 @@ void status_redraw_buf(buf_T *buf) redraw_later(wp, UPD_VALID); } } + // Redraw the ruler if it is in the command line and was not marked for redraw above + if (p_ru && !curwin->w_status_height && !curwin->w_redr_status) { + redraw_cmdline = true; + redraw_later(curwin, UPD_VALID); + } } /// Redraw all status lines that need to be redrawn. diff --git a/src/nvim/edit.c b/src/nvim/edit.c index c551ec2726..9e4457f793 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2699,7 +2699,7 @@ int stuff_inserted(int c, long count, int no_esc) } do { - stuffReadbuff((const char *)ptr); + stuffReadbuff(ptr); // A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^". if (last) { stuffReadbuff(last == '0' ? "\026\060\064\070" : "\026^"); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index edaa2bb809..ff33fdeccb 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -86,15 +86,15 @@ #define DICT_MAXNEST 100 // maximum nesting of lists and dicts -static char *e_missbrac = N_("E111: Missing ']'"); -static char *e_list_end = N_("E697: Missing end of List ']': %s"); -static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); -static char *e_nowhitespace +static const char *e_missbrac = N_("E111: Missing ']'"); +static const char *e_list_end = N_("E697: Missing end of List ']': %s"); +static const char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); +static const char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); -static char *e_write2 = N_("E80: Error while writing: %s"); -static char *e_string_list_or_blob_required = N_("E1098: String, List or Blob required"); -static char e_expression_too_recursive_str[] = N_("E1169: Expression too recursive: %s"); -static char e_dot_can_only_be_used_on_dictionary_str[] +static const char *e_write2 = N_("E80: Error while writing: %s"); +static const char *e_string_list_or_blob_required = N_("E1098: String, List or Blob required"); +static const char e_expression_too_recursive_str[] = N_("E1169: Expression too recursive: %s"); +static const char e_dot_can_only_be_used_on_dictionary_str[] = N_("E1203: Dot can only be used on a dictionary: %s"); static char * const namespace_char = "abglstvw"; @@ -396,11 +396,11 @@ void eval_init(void) // add to v: scope dict, unless the value is not always available if (p->vv_type != VAR_UNKNOWN) { - hash_add(&vimvarht, (char *)p->vv_di.di_key); + hash_add(&vimvarht, p->vv_di.di_key); } if (p->vv_flags & VV_COMPAT) { // add to compat scope dict - hash_add(&compat_hashtab, (char *)p->vv_di.di_key); + hash_add(&compat_hashtab, p->vv_di.di_key); } } vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; @@ -984,7 +984,7 @@ void prepare_vimvar(int idx, typval_T *save_tv) { *save_tv = vimvars[idx].vv_tv; if (vimvars[idx].vv_type == VAR_UNKNOWN) { - hash_add(&vimvarht, (char *)vimvars[idx].vv_di.di_key); + hash_add(&vimvarht, vimvars[idx].vv_di.di_key); } } @@ -997,7 +997,7 @@ void restore_vimvar(int idx, typval_T *save_tv) return; } - hashitem_T *hi = hash_find(&vimvarht, (char *)vimvars[idx].vv_di.di_key); + hashitem_T *hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); if (HASHITEM_EMPTY(hi)) { internal_error("restore_vimvar()"); } else { @@ -1145,7 +1145,7 @@ void *call_func_retlist(const char *func, int argc, typval_T *argv) typval_T rettv; // All arguments are passed as strings, no conversion to number. - if (call_vim_function((char *)func, argc, argv, &rettv) == FAIL) { + if (call_vim_function(func, argc, argv, &rettv) == FAIL) { return NULL; } @@ -1234,9 +1234,8 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const if (skip) { // When skipping just find the end of the name. - lp->ll_name = (const char *)name; - return (char *)find_name_end(name, NULL, NULL, - FNE_INCL_BR | fne_flags); + lp->ll_name = name; + return (char *)find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); } // Find the end of the name. @@ -1269,8 +1268,8 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const lp->ll_name_len = strlen(lp->ll_name); } } else { - lp->ll_name = (const char *)name; - lp->ll_name_len = (size_t)((const char *)p - lp->ll_name); + lp->ll_name = name; + lp->ll_name_len = (size_t)(p - lp->ll_name); } // Without [idx] or .key we are done. @@ -1417,7 +1416,7 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const } lp->ll_list = NULL; lp->ll_dict = lp->ll_tv->vval.v_dict; - lp->ll_di = tv_dict_find(lp->ll_dict, (const char *)key, len); + lp->ll_di = tv_dict_find(lp->ll_dict, key, len); // When assigning to a scope dictionary check that a function and // variable name is valid (only variable name unless it is l: or @@ -1434,8 +1433,8 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const } wrong = ((lp->ll_dict->dv_scope == VAR_DEF_SCOPE && tv_is_func(*rettv) - && var_wrong_func_name((const char *)key, lp->ll_di == NULL)) - || !valid_varname((const char *)key)); + && var_wrong_func_name(key, lp->ll_di == NULL)) + || !valid_varname(key)); if (len != -1) { key[len] = prevval; } @@ -1728,7 +1727,7 @@ void set_var_lval(lval_T *lp, char *endp, typval_T *rettv, int copy, const bool } // Need to add an item to the Dictionary. - di = tv_dict_item_alloc((const char *)lp->ll_newkey); + di = tv_dict_item_alloc(lp->ll_newkey); if (tv_dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) { xfree(di); return; @@ -1764,7 +1763,7 @@ notify: } else { dictitem_T *di_ = lp->ll_di; assert(di_->di_key != NULL); - tv_dict_watcher_notify(dict, (char *)di_->di_key, lp->ll_tv, &oldtv); + tv_dict_watcher_notify(dict, di_->di_key, lp->ll_tv, &oldtv); tv_clear(&oldtv); } } @@ -1786,7 +1785,7 @@ void *eval_for_line(const char *arg, bool *errp, char **nextcmdp, int skip) *errp = true; // Default: there is an error. - expr = skip_var_list((char *)arg, &fi->fi_varcount, &fi->fi_semicolon); + expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); if (expr == NULL) { return fi; } @@ -2172,13 +2171,13 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ int len = name_len; if (!evaluate) { - check_vars((const char *)s, (size_t)len); + check_vars(s, (size_t)len); } // If "s" is the name of a variable of type VAR_FUNC // use its contents. partial_T *partial; - s = deref_func_name((const char *)s, &len, &partial, !evaluate); + s = deref_func_name(s, &len, &partial, !evaluate); // Need to make a copy, in case evaluating the arguments makes // the name invalid. @@ -3000,9 +2999,9 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) if (**arg == '(') { // recursive! ret = eval_func(arg, s, len, rettv, evaluate, NULL); } else if (evaluate) { - ret = get_var_tv((const char *)s, len, rettv, NULL, true, false); + ret = get_var_tv(s, len, rettv, NULL, true, false); } else { - check_vars((const char *)s, (size_t)len); + check_vars(s, (size_t)len); ret = OK; } } @@ -3036,7 +3035,7 @@ static int eval7_leader(typval_T *const rettv, const bool numeric_only, const char *const start_leader, const char **const end_leaderp) FUNC_ATTR_NONNULL_ALL { - const char *end_leader = (char *)(*end_leaderp); + const char *end_leader = *end_leaderp; int ret = OK; bool error = false; varnumber_T val = 0; @@ -3199,7 +3198,7 @@ static int eval_method(char **const arg, typval_T *const rettv, const bool evalu char *lua_funcname = NULL; if (strncmp(name, "v:lua.", 6) == 0) { lua_funcname = name + 6; - *arg = (char *)skip_luafunc_name((const char *)lua_funcname); + *arg = (char *)skip_luafunc_name(lua_funcname); *arg = skipwhite(*arg); // to detect trailing whitespace later len = (int)(*arg - lua_funcname); } else { @@ -3264,7 +3263,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) bool empty2 = false; ptrdiff_t len = -1; int range = false; - char *key = NULL; + const char *key = NULL; switch (rettv->v_type) { case VAR_FUNC: @@ -3513,15 +3512,14 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) } if (len == -1) { - key = (char *)tv_get_string_chk(&var1); + key = tv_get_string_chk(&var1); if (key == NULL) { tv_clear(&var1); return FAIL; } } - dictitem_T *const item = tv_dict_find(rettv->vval.v_dict, - (const char *)key, len); + dictitem_T *const item = tv_dict_find(rettv->vval.v_dict, key, len); if (item == NULL && verbose) { semsg(_(e_dictkey), key); @@ -4635,14 +4633,14 @@ static int eval_dict(char **arg, typval_T *rettv, int evaluate, bool literal) goto failret; } if (evaluate) { - dictitem_T *item = tv_dict_find(d, (const char *)key, -1); + dictitem_T *item = tv_dict_find(d, key, -1); if (item != NULL) { semsg(_("E721: Duplicate key in Dictionary: \"%s\""), key); tv_clear(&tvkey); tv_clear(&tv); goto failret; } - item = tv_dict_item_alloc((const char *)key); + item = tv_dict_item_alloc(key); item->di_tv = tv; item->di_tv.v_lock = VAR_UNLOCKED; if (tv_dict_add(d, item) == FAIL) { @@ -4755,8 +4753,7 @@ void assert_error(garray_T *gap) // Make sure v:errors is a list. set_vim_var_list(VV_ERRORS, tv_list_alloc(1)); } - tv_list_append_string(vimvars[VV_ERRORS].vv_list, - (const char *)gap->ga_data, (ptrdiff_t)gap->ga_len); + tv_list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, (ptrdiff_t)gap->ga_len); } /// Implementation of map() and filter(). @@ -4831,7 +4828,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map) break; } - vimvars[VV_KEY].vv_str = xstrdup((char *)di->di_key); + vimvars[VV_KEY].vv_str = xstrdup(di->di_key); int r = filter_map_one(&di->di_tv, expr, map, &rem); tv_clear(&vimvars[VV_KEY].vv_tv); if (r == FAIL || did_emsg) { @@ -4983,14 +4980,12 @@ void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref) } if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s)) || (is_funcref && trans_name == NULL)) { - semsg(_(e_invarg2), (use_string - ? tv_get_string(&argvars[0]) - : (const char *)s)); + semsg(_(e_invarg2), (use_string ? tv_get_string(&argvars[0]) : s)); // Don't check an autoload name for existence here. } else if (trans_name != NULL && (is_funcref ? find_func(trans_name) == NULL - : !translated_function_exists((const char *)trans_name))) { + : !translated_function_exists(trans_name))) { semsg(_("E700: Unknown function: %s"), s); } else { int dict_idx = 0; @@ -6338,7 +6333,7 @@ int get_id_len(const char **const arg) } len = (int)(p - *arg); - *arg = (const char *)skipwhite(p); + *arg = skipwhite(p); return len; } @@ -6376,7 +6371,7 @@ int get_name_len(const char **const arg, char **alias, bool evaluate, bool verbo if (expr_start != NULL) { if (!evaluate) { len += (int)(p - *arg); - *arg = (const char *)skipwhite(p); + *arg = skipwhite(p); return len; } @@ -6387,7 +6382,7 @@ int get_name_len(const char **const arg, char **alias, bool evaluate, bool verbo return -1; } *alias = temp_string; - *arg = (const char *)skipwhite(p); + *arg = skipwhite(p); return (int)strlen(temp_string); } @@ -7612,7 +7607,7 @@ const void *var_shada_iter(const void *const iter, const char **const name, typv } else { hi = (const hashitem_T *)iter; } - *name = (char *)TV_DICT_HI2DI(hi)->di_key; + *name = TV_DICT_HI2DI(hi)->di_key; tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv); while ((size_t)(++hi - hifirst) < hinum) { if (!HASHITEM_EMPTY(hi) && (var_flavour(hi->hi_key) & flavour)) { @@ -7636,10 +7631,10 @@ int store_session_globals(FILE *fd) TV_DICT_ITER(&globvardict, this_var, { if ((this_var->di_tv.v_type == VAR_NUMBER || this_var->di_tv.v_type == VAR_STRING) - && var_flavour((char *)this_var->di_key) == VAR_FLAVOUR_SESSION) { + && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) { // Escape special characters with a backslash. Turn a LF and // CR into \n and \r. - char *const p = (char *)vim_strsave_escaped(tv_get_string(&this_var->di_tv), "\\\"\n\r"); + char *const p = vim_strsave_escaped(tv_get_string(&this_var->di_tv), "\\\"\n\r"); for (char *t = p; *t != NUL; t++) { if (*t == '\n') { *t = 'n'; @@ -7658,7 +7653,7 @@ int store_session_globals(FILE *fd) } xfree(p); } else if (this_var->di_tv.v_type == VAR_FLOAT - && var_flavour((char *)this_var->di_key) == VAR_FLAVOUR_SESSION) { + && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) { float_T f = this_var->di_tv.vval.v_float; int sign = ' '; @@ -7949,7 +7944,7 @@ repeat: // "path/to/this.file.ext" :r:r:r // ^ ^------------- tail // +--------------------- *fnamep - if (s > MAX(tail, (char *)(*fnamep))) { + if (s > MAX(tail, *fnamep)) { *fnamelen = (size_t)(s - *fnamep); } } @@ -8165,7 +8160,7 @@ void script_host_eval(char *name, typval_T *argvars, typval_T *rettv) } list_T *args = tv_list_alloc(1); - tv_list_append_string(args, (const char *)argvars[0].vval.v_string, -1); + tv_list_append_string(args, argvars[0].vval.v_string, -1); *rettv = eval_call_provider(name, "eval", args, false); } diff --git a/src/nvim/eval/buffer.c b/src/nvim/eval/buffer.c index 2f37d1ba2e..d9cc18a402 100644 --- a/src/nvim/eval/buffer.c +++ b/src/nvim/eval/buffer.c @@ -487,8 +487,7 @@ static dict_T *get_buffer_info(buf_T *buf) dict_T *const dict = tv_dict_alloc(); tv_dict_add_nr(dict, S_LEN("bufnr"), buf->b_fnum); - tv_dict_add_str(dict, S_LEN("name"), - buf->b_ffname != NULL ? (const char *)buf->b_ffname : ""); + tv_dict_add_str(dict, S_LEN("name"), buf->b_ffname != NULL ? buf->b_ffname : ""); tv_dict_add_nr(dict, S_LEN("lnum"), buf == curbuf ? curwin->w_cursor.lnum : buflist_findlnum(buf)); tv_dict_add_nr(dict, S_LEN("linecount"), buf->b_ml.ml_line_count); @@ -496,8 +495,7 @@ static dict_T *get_buffer_info(buf_T *buf) tv_dict_add_nr(dict, S_LEN("listed"), buf->b_p_bl); tv_dict_add_nr(dict, S_LEN("changed"), bufIsChanged(buf)); tv_dict_add_nr(dict, S_LEN("changedtick"), buf_get_changedtick(buf)); - tv_dict_add_nr(dict, S_LEN("hidden"), - buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0); + tv_dict_add_nr(dict, S_LEN("hidden"), buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0); // Get a reference to buffer variables tv_dict_add_dict(dict, S_LEN("variables"), buf->b_vars); @@ -609,8 +607,7 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli } tv_list_alloc_ret(rettv, end - start + 1); while (start <= end) { - tv_list_append_string(rettv->vval.v_list, - (const char *)ml_get_buf(buf, start++, false), -1); + tv_list_append_string(rettv->vval.v_list, ml_get_buf(buf, start++, false), -1); } } else { rettv->v_type = VAR_STRING; diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 6ce9309677..acef37e0e8 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -148,7 +148,7 @@ static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack assert(!(key.is_special_string || key.val.vval.v_string == NULL || *key.val.vval.v_string == NUL)); - dictitem_T *const obj_di = tv_dict_item_alloc((const char *)key.val.vval.v_string); + dictitem_T *const obj_di = tv_dict_item_alloc(key.val.vval.v_string); tv_clear(&key.val); if (tv_dict_add(last_container.container.vval.v_dict, obj_di) == FAIL) { @@ -179,8 +179,7 @@ static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack && (obj.is_special_string || obj.val.vval.v_string == NULL || *obj.val.vval.v_string == NUL - || tv_dict_find(last_container.container.vval.v_dict, - (const char *)obj.val.vval.v_string, -1))) { + || tv_dict_find(last_container.container.vval.v_dict, obj.val.vval.v_string, -1))) { tv_clear(&obj.val); // Restart diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index c2f1eae8af..b056a1784c 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -298,7 +298,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s #define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \ do { \ - const char *const buf_ = (const char *)(buf); \ + const char *const buf_ = (buf); \ if ((buf) == NULL) { \ ga_concat(gap, "''"); \ } else { \ @@ -376,7 +376,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s #define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \ do { \ - const char *const fun_ = (const char *)(fun); \ + const char *const fun_ = (fun); \ if (fun_ == NULL) { \ internal_error("string(): NULL function name"); \ ga_concat(gap, "function(NULL"); \ @@ -712,7 +712,7 @@ static inline int convert_to_json_string(garray_T *const gap, const char *const #undef TYPVAL_ENCODE_CONV_STRING #define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \ do { \ - if (convert_to_json_string(gap, (const char *)(buf), (len)) != OK) { \ + if (convert_to_json_string(gap, (buf), (len)) != OK) { \ return FAIL; \ } \ } while (0) diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 4286e16eb1..7f224f371c 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -145,10 +145,10 @@ PRAGMA_DIAG_POP PRAGMA_DIAG_POP #endif -static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); -static char *e_invalwindow = N_("E957: Invalid window number"); -static char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value"); -static char e_using_number_as_bool_nr[] +static const char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); +static const char *e_invalwindow = N_("E957: Invalid window number"); +static const char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value"); +static const char e_using_number_as_bool_nr[] = N_("E1023: Using a Number as a Bool: %d"); /// Dummy va_list for passing to vim_snprintf @@ -319,7 +319,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) Object result = handler.fn(VIML_INTERNAL_CALL, args, &res_arena, &err); if (ERROR_SET(&err)) { - semsg_multiline((const char *)e_api_error, err.msg); + semsg_multiline(e_api_error, err.msg); goto end; } @@ -956,7 +956,7 @@ static void f_count(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) const size_t len = strlen(expr); while (*p != NUL) { - if (mb_strnicmp((char *)p, (char *)expr, len) == 0) { + if (mb_strnicmp(p, expr, len) == 0) { n++; p += len; } else { @@ -965,7 +965,7 @@ static void f_count(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } } else { char *next; - while ((next = strstr((char *)p, (char *)expr)) != NULL) { + while ((next = strstr(p, expr)) != NULL) { n++; p = next + strlen(expr); } @@ -1064,17 +1064,17 @@ static void f_ctxpush(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) TV_LIST_ITER(argvars[0].vval.v_list, li, { typval_T *tv_li = TV_LIST_ITEM_TV(li); if (tv_li->v_type == VAR_STRING) { - if (strequal((char *)tv_li->vval.v_string, "regs")) { + if (strequal(tv_li->vval.v_string, "regs")) { types |= kCtxRegs; - } else if (strequal((char *)tv_li->vval.v_string, "jumps")) { + } else if (strequal(tv_li->vval.v_string, "jumps")) { types |= kCtxJumps; - } else if (strequal((char *)tv_li->vval.v_string, "bufs")) { + } else if (strequal(tv_li->vval.v_string, "bufs")) { types |= kCtxBufs; - } else if (strequal((char *)tv_li->vval.v_string, "gvars")) { + } else if (strequal(tv_li->vval.v_string, "gvars")) { types |= kCtxGVars; - } else if (strequal((char *)tv_li->vval.v_string, "sfuncs")) { + } else if (strequal(tv_li->vval.v_string, "sfuncs")) { types |= kCtxSFuncs; - } else if (strequal((char *)tv_li->vval.v_string, "funcs")) { + } else if (strequal(tv_li->vval.v_string, "funcs")) { types |= kCtxFuncs; } } @@ -1546,7 +1546,7 @@ static void f_eval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { const char *s = tv_get_string_chk(&argvars[0]); if (s != NULL) { - s = (const char *)skipwhite(s); + s = skipwhite(s); } const char *const expr_start = s; @@ -1779,7 +1779,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (rettv->v_type == VAR_LIST) { tv_list_alloc_ret(rettv, (result != NULL)); if (result != NULL) { - tv_list_append_string(rettv->vval.v_list, (const char *)result, -1); + tv_list_append_string(rettv->vval.v_list, result, -1); } XFREE_CLEAR(result); } else { @@ -1805,8 +1805,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) ExpandOne(&xpc, (char *)s, NULL, options, WILD_ALL_KEEP); tv_list_alloc_ret(rettv, xpc.xp_numfiles); for (int i = 0; i < xpc.xp_numfiles; i++) { - tv_list_append_string(rettv->vval.v_list, - (const char *)xpc.xp_files[i], -1); + tv_list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); } ExpandCleanup(&xpc); } @@ -2134,7 +2133,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) first = false; if (fresult != NULL && rettv->v_type == VAR_LIST) { - tv_list_append_string(rettv->vval.v_list, (const char *)fresult, -1); + tv_list_append_string(rettv->vval.v_list, fresult, -1); } } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); } @@ -3008,8 +3007,7 @@ static void f_glob(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) WILD_ALL_KEEP); tv_list_alloc_ret(rettv, xpc.xp_numfiles); for (int i = 0; i < xpc.xp_numfiles; i++) { - tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i], - -1); + tv_list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); } ExpandCleanup(&xpc); } @@ -3996,7 +3994,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en if (!clear_env) { typval_T temp_env = TV_INITIAL_VALUE; - f_environ(NULL, &temp_env, (EvalFuncData){ .nullptr = NULL }); + f_environ(NULL, &temp_env, (EvalFuncData){ .null = NULL }); tv_dict_extend(env, temp_env.vval.v_dict, "force"); tv_dict_free(temp_env.vval.v_dict); @@ -4050,7 +4048,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en #ifdef MSWIN TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, { // Always use upper-case keys for Windows so we detect duplicate keys - char *const key = strcase_save((const char *)var->di_key, true); + char *const key = strcase_save(var->di_key, true); size_t len = strlen(key); dictitem_T *dv = tv_dict_find(env, key, len); if (dv) { @@ -4735,8 +4733,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, if (regmatch.endp[i] == NULL) { tv_list_append_string(rettv->vval.v_list, NULL, 0); } else { - tv_list_append_string(rettv->vval.v_list, - (const char *)regmatch.startp[i], + tv_list_append_string(rettv->vval.v_list, regmatch.startp[i], (regmatch.endp[i] - regmatch.startp[i])); } } @@ -4746,7 +4743,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, if (l != NULL) { tv_copy(TV_LIST_ITEM_TV(li), rettv); } else { - rettv->vval.v_string = xmemdupz((const char *)regmatch.startp[0], + rettv->vval.v_string = xmemdupz(regmatch.startp[0], (size_t)(regmatch.endp[0] - regmatch.startp[0])); } @@ -4956,7 +4953,7 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) char msgbuf[sizeof("msgpackdump() argument, index ") * 4 + NUMBUFLEN]; int idx = 0; TV_LIST_ITER(list, li, { - vim_snprintf(msgbuf, sizeof(msgbuf), (char *)msg, idx); + vim_snprintf(msgbuf, sizeof(msgbuf), msg, idx); idx++; if (encode_vim_to_msgpack(packer, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) { break; @@ -6285,7 +6282,7 @@ static void f_reduce(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) argv[0] = *rettv; argv[1] = *TV_LIST_ITEM_TV(li); rettv->v_type = VAR_UNKNOWN; - const int r = call_func((char *)func_name, -1, rettv, 2, argv, &funcexe); + const int r = call_func(func_name, -1, rettv, 2, argv, &funcexe); tv_clear(&argv[0]); if (r == FAIL || called_emsg != called_emsg_start) { break; @@ -6318,7 +6315,7 @@ static void f_reduce(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) argv[0] = *rettv; argv[1].v_type = VAR_NUMBER; argv[1].vval.v_number = tv_blob_get(b, i); - if (call_func((char *)func_name, -1, rettv, 2, argv, &funcexe) == FAIL) { + if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) { return; } } @@ -7557,7 +7554,7 @@ free_lstval: /// "settagstack()" function static void f_settagstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - static char *e_invact2 = N_("E962: Invalid action: '%s'"); + static const char *e_invact2 = N_("E962: Invalid action: '%s'"); char action = 'r'; rettv->vval.v_number = -1; @@ -7910,14 +7907,14 @@ static void f_split(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } const char *end; if (match) { - end = (const char *)regmatch.startp[0]; + end = regmatch.startp[0]; } else { end = str + strlen(str); } if (keepempty || end > str || (tv_list_len(rettv->vval.v_list) > 0 && *str != NUL && match - && end < (const char *)regmatch.endp[0])) { + && end < regmatch.endp[0])) { tv_list_append_string(rettv->vval.v_list, str, end - str); } if (!match) { @@ -7930,7 +7927,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) // Don't get stuck at the same match. col = utfc_ptr2len(regmatch.endp[0]); } - str = (const char *)regmatch.endp[0]; + str = regmatch.endp[0]; } vim_regfree(regmatch.regprog); @@ -8587,7 +8584,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char *)(p == NULL ? p : xstrdup(p)); + rettv->vval.v_string = p == NULL ? NULL : xstrdup(p); } /// "synIDtrans(id)" function @@ -9096,14 +9093,14 @@ static void f_trim(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (dir == 0 || dir == 1) { // Trim leading characters while (*head != NUL) { - c1 = utf_ptr2char((char *)head); + c1 = utf_ptr2char(head); if (mask == NULL) { if (c1 > ' ' && c1 != 0xa0) { break; } } else { for (p = mask; *p != NUL; MB_PTR_ADV(p)) { - if (c1 == utf_ptr2char((char *)p)) { + if (c1 == utf_ptr2char(p)) { break; } } @@ -9121,14 +9118,14 @@ static void f_trim(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) for (; tail > head; tail = prev) { prev = tail; MB_PTR_BACK(head, prev); - c1 = utf_ptr2char((char *)prev); + c1 = utf_ptr2char(prev); if (mask == NULL) { if (c1 > ' ' && c1 != 0xa0) { break; } } else { for (p = mask; *p != NUL; MB_PTR_ADV(p)) { - if (c1 == utf_ptr2char((char *)p)) { + if (c1 == utf_ptr2char(p)) { break; } } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index d077998dae..3e67571053 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -40,25 +40,25 @@ # include "eval/typval.c.generated.h" #endif -static char e_string_required_for_argument_nr[] +static const char e_string_required_for_argument_nr[] = N_("E1174: String required for argument %d"); -static char e_non_empty_string_required_for_argument_nr[] +static const char e_non_empty_string_required_for_argument_nr[] = N_("E1175: Non-empty string required for argument %d"); -static char e_dict_required_for_argument_nr[] +static const char e_dict_required_for_argument_nr[] = N_("E1206: Dictionary required for argument %d"); -static char e_number_required_for_argument_nr[] +static const char e_number_required_for_argument_nr[] = N_("E1210: Number required for argument %d"); -static char e_list_required_for_argument_nr[] +static const char e_list_required_for_argument_nr[] = N_("E1211: List required for argument %d"); -static char e_string_or_list_required_for_argument_nr[] +static const char e_string_or_list_required_for_argument_nr[] = N_("E1222: String or List required for argument %d"); -static char e_list_or_blob_required_for_argument_nr[] +static const char e_list_or_blob_required_for_argument_nr[] = N_("E1226: List or Blob required for argument %d"); -static char e_blob_required_for_argument_nr[] +static const char e_blob_required_for_argument_nr[] = N_("E1238: Blob required for argument %d"); -static char e_invalid_value_for_blob_nr[] +static const char e_invalid_value_for_blob_nr[] = N_("E1239: Invalid value for blob: %d"); -static char e_string_or_function_required_for_argument_nr[] +static const char e_string_or_function_required_for_argument_nr[] = N_("E1256: String or function required for argument %d"); bool tv_in_free_unref_items = false; @@ -897,8 +897,8 @@ void f_list2str(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) char buf[MB_MAXBYTES + 1]; TV_LIST_ITER_CONST(l, li, { - buf[utf_char2bytes((int)tv_get_number(TV_LIST_ITEM_TV(li)), (char *)buf)] = NUL; - ga_concat(&ga, (char *)buf); + buf[utf_char2bytes((int)tv_get_number(TV_LIST_ITEM_TV(li)), buf)] = NUL; + ga_concat(&ga, buf); }); ga_append(&ga, NUL); @@ -1091,7 +1091,7 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) if (partial == NULL) { func_name = sortinfo->item_compare_func; } else { - func_name = (const char *)partial_name(partial); + func_name = partial_name(partial); } // Copy the values. This is needed to be able to set v_lock to VAR_FIXED @@ -1189,7 +1189,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) if (argvars[1].v_type != VAR_UNKNOWN) { // optional second argument: {func} if (argvars[1].v_type == VAR_FUNC) { - info.item_compare_func = (const char *)argvars[1].vval.v_string; + info.item_compare_func = argvars[1].vval.v_string; } else if (argvars[1].v_type == VAR_PARTIAL) { info.item_compare_partial = argvars[1].vval.v_partial; } else { @@ -1894,7 +1894,7 @@ void tv_dict_item_free(dictitem_T *const item) dictitem_T *tv_dict_item_copy(dictitem_T *const di) FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - dictitem_T *const new_di = tv_dict_item_alloc((const char *)di->di_key); + dictitem_T *const new_di = tv_dict_item_alloc(di->di_key); tv_copy(&di->di_tv, &new_di->di_tv); return new_di; } @@ -1906,7 +1906,7 @@ dictitem_T *tv_dict_item_copy(dictitem_T *const di) void tv_dict_item_remove(dict_T *const dict, dictitem_T *const item) FUNC_ATTR_NONNULL_ALL { - hashitem_T *const hi = hash_find(&dict->dv_hashtab, (char *)item->di_key); + hashitem_T *const hi = hash_find(&dict->dv_hashtab, item->di_key); if (HASHITEM_EMPTY(hi)) { semsg(_(e_intern2), "tv_dict_item_remove()"); } else { @@ -2111,9 +2111,9 @@ char **tv_dict_to_env(dict_T *denv) TV_DICT_ITER(denv, var, { const char *str = tv_get_string(&var->di_tv); assert(str); - size_t len = strlen((char *)var->di_key) + strlen(str) + strlen("=") + 1; + size_t len = strlen(var->di_key) + strlen(str) + strlen("=") + 1; env[i] = xmalloc(len); - snprintf(env[i], len, "%s=%s", (char *)var->di_key, str); + snprintf(env[i], len, "%s=%s", var->di_key, str); i++; }); @@ -2240,10 +2240,10 @@ int tv_dict_wrong_func_name(dict_T *d, typval_T *tv, const char *name) int tv_dict_add(dict_T *const d, dictitem_T *const item) FUNC_ATTR_NONNULL_ALL { - if (tv_dict_wrong_func_name(d, &item->di_tv, (const char *)item->di_key)) { + if (tv_dict_wrong_func_name(d, &item->di_tv, item->di_key)) { return FAIL; } - return hash_add(&d->dv_hashtab, (char *)item->di_key); + return hash_add(&d->dv_hashtab, item->di_key); } /// Add a list entry to dictionary @@ -2477,9 +2477,9 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action HASHTAB_ITER(&d2->dv_hashtab, hi2, { dictitem_T *const di2 = TV_DICT_HI2DI(hi2); - dictitem_T *const di1 = tv_dict_find(d1, (const char *)di2->di_key, -1); + dictitem_T *const di1 = tv_dict_find(d1, di2->di_key, -1); // Check the key to be valid when adding to any scope. - if (d1->dv_scope != VAR_NO_SCOPE && !valid_varname((const char *)di2->di_key)) { + if (d1->dv_scope != VAR_NO_SCOPE && !valid_varname(di2->di_key)) { break; } if (di1 == NULL) { @@ -2489,14 +2489,14 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action dictitem_T *const new_di = di2; if (tv_dict_add(d1, new_di) == OK) { hash_remove(&d2->dv_hashtab, hi2); - tv_dict_watcher_notify(d1, (const char *)new_di->di_key, &new_di->di_tv, NULL); + tv_dict_watcher_notify(d1, new_di->di_key, &new_di->di_tv, NULL); } } else { dictitem_T *const new_di = tv_dict_item_copy(di2); if (tv_dict_add(d1, new_di) == FAIL) { tv_dict_item_free(new_di); } else if (watched) { - tv_dict_watcher_notify(d1, (const char *)new_di->di_key, &new_di->di_tv, NULL); + tv_dict_watcher_notify(d1, new_di->di_key, &new_di->di_tv, NULL); } } } else if (*action == 'e') { @@ -2510,7 +2510,7 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action break; } // Disallow replacing a builtin function. - if (tv_dict_wrong_func_name(d1, &di2->di_tv, (const char *)di2->di_key)) { + if (tv_dict_wrong_func_name(d1, &di2->di_tv, di2->di_key)) { break; } @@ -2522,8 +2522,7 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action tv_copy(&di2->di_tv, &di1->di_tv); if (watched) { - tv_dict_watcher_notify(d1, (const char *)di1->di_key, &di1->di_tv, - &oldtv); + tv_dict_watcher_notify(d1, di1->di_key, &di1->di_tv, &oldtv); tv_clear(&oldtv); } } @@ -2558,7 +2557,7 @@ bool tv_dict_equal(dict_T *const d1, dict_T *const d2, const bool ic, const bool } TV_DICT_ITER(d1, di1, { - dictitem_T *const di2 = tv_dict_find(d2, (const char *)di1->di_key, -1); + dictitem_T *const di2 = tv_dict_find(d2, di1->di_key, -1); if (di2 == NULL) { return false; } @@ -2597,12 +2596,12 @@ dict_T *tv_dict_copy(const vimconv_T *const conv, dict_T *const orig, const bool } dictitem_T *new_di; if (conv == NULL || conv->vc_type == CONV_NONE) { - new_di = tv_dict_item_alloc((const char *)di->di_key); + new_di = tv_dict_item_alloc(di->di_key); } else { - size_t len = strlen((char *)di->di_key); - char *const key = (char *)string_convert(conv, (char *)di->di_key, &len); + size_t len = strlen(di->di_key); + char *const key = string_convert(conv, di->di_key, &len); if (key == NULL) { - new_di = tv_dict_item_alloc_len((const char *)di->di_key, len); + new_di = tv_dict_item_alloc_len(di->di_key, len); } else { new_di = tv_dict_item_alloc_len(key, len); xfree(key); @@ -2868,7 +2867,7 @@ void f_list2blob(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) varnumber_T n = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); if (error || n < 0 || n > 255) { if (!error) { - semsg(_(e_invalid_value_for_blob_nr), n); + semsg(_(e_invalid_value_for_blob_nr), (int)n); } ga_clear(&blob->bv_ga); return; @@ -2945,7 +2944,7 @@ static void tv_dict_list(typval_T *const tv, typval_T *const rettv, const DictLi switch (what) { case kDictListKeys: tv_item.v_type = VAR_STRING; - tv_item.vval.v_string = xstrdup((char *)di->di_key); + tv_item.vval.v_string = xstrdup(di->di_key); break; case kDictListValues: tv_copy(&di->di_tv, &tv_item); @@ -2960,7 +2959,7 @@ static void tv_dict_list(typval_T *const tv, typval_T *const rettv, const DictLi tv_list_append_owned_tv(sub_l, (typval_T) { .v_type = VAR_STRING, .v_lock = VAR_UNLOCKED, - .vval.v_string = xstrdup((const char *)di->di_key), + .vval.v_string = xstrdup(di->di_key), }); tv_list_append_tv(sub_l, &di->di_tv); @@ -3132,7 +3131,7 @@ static inline int _nothing_conv_func_start(typval_T *const tv, char *const fun) } } else { func_unref(fun); - if ((const char *)fun != tv_empty_string) { + if (fun != tv_empty_string) { xfree(fun); } tv->vval.v_string = NULL; @@ -3805,7 +3804,7 @@ static const char *const str_errors[] = { [VAR_FUNC]= N_(FUNC_ERROR), [VAR_LIST]= N_("E730: using List as a String"), [VAR_DICT]= N_("E731: using Dictionary as a String"), - [VAR_FLOAT]= ((const char *)e_float_as_string), + [VAR_FLOAT]= e_float_as_string, [VAR_BLOB]= N_("E976: using Blob as a String"), [VAR_UNKNOWN]= N_("E908: using an invalid value as a String"), }; @@ -4116,7 +4115,7 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf) return buf; case VAR_STRING: if (tv->vval.v_string != NULL) { - return (const char *)tv->vval.v_string; + return tv->vval.v_string; } return ""; case VAR_BOOL: diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 40bca9acc1..f09da6b79b 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -65,11 +65,11 @@ static funccall_T *current_funccal = NULL; // item in it is still being used. static funccall_T *previous_funccal = NULL; -static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); -static char *e_funcdict = N_("E717: Dictionary entry already exists"); -static char *e_funcref = N_("E718: Funcref required"); -static char *e_nofunc = N_("E130: Unknown function: %s"); -static char e_no_white_space_allowed_before_str_str[] +static const char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); +static const char *e_funcdict = N_("E717: Dictionary entry already exists"); +static const char *e_funcref = N_("E718: Funcref required"); +static const char *e_nofunc = N_("E130: Unknown function: %s"); +static const char e_no_white_space_allowed_before_str_str[] = N_("E1068: No white space allowed before '%s': %s"); void func_init(void) @@ -421,9 +421,9 @@ char *deref_func_name(const char *name, int *lenp, partial_T **const partialp, b /// Give an error message with a function name. Handle <SNR> things. /// -/// @param ermsg must be passed without translation (use N_() instead of _()). +/// @param errmsg must be passed without translation (use N_() instead of _()). /// @param name function name -void emsg_funcname(char *ermsg, const char *name) +void emsg_funcname(const char *errmsg, const char *name) { char *p; @@ -433,7 +433,7 @@ void emsg_funcname(char *ermsg, const char *name) p = (char *)name; } - semsg(_(ermsg), p); + semsg(_(errmsg), p); if (p != name) { xfree(p); @@ -611,7 +611,7 @@ static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr) STRCPY(v->di_key, name); #endif v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; - hash_add(&dp->dv_hashtab, (char *)v->di_key); + hash_add(&dp->dv_hashtab, v->di_key); v->di_tv.v_type = VAR_NUMBER; v->di_tv.v_lock = VAR_FIXED; v->di_tv.vval.v_number = nr; @@ -758,7 +758,7 @@ static void funccal_unref(funccall_T *fc, ufunc_T *fp, bool force) /// @return true if the entry was deleted, false if it wasn't found. static bool func_remove(ufunc_T *fp) { - hashitem_T *hi = hash_find(&func_hashtab, (char *)UF2HIKEY(fp)); + hashitem_T *hi = hash_find(&func_hashtab, UF2HIKEY(fp)); if (HASHITEM_EMPTY(hi)) { return false; } @@ -905,7 +905,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett STRCPY(name, "self"); #endif v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; - hash_add(&fc->l_vars.dv_hashtab, (char *)v->di_key); + hash_add(&fc->l_vars.dv_hashtab, v->di_key); v->di_tv.v_type = VAR_DICT; v->di_tv.v_lock = VAR_UNLOCKED; v->di_tv.vval.v_dict = selfdict; @@ -931,7 +931,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett STRCPY(name, "000"); #endif v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; - hash_add(&fc->l_avars.dv_hashtab, (char *)v->di_key); + hash_add(&fc->l_avars.dv_hashtab, v->di_key); v->di_tv.v_type = VAR_LIST; v->di_tv.v_lock = VAR_FIXED; v->di_tv.vval.v_list = &fc->l_varlist; @@ -1009,9 +1009,9 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // Named arguments can be accessed without the "a:" prefix in lambda // expressions. Add to the l: dict. tv_copy(&v->di_tv, &v->di_tv); - hash_add(&fc->l_vars.dv_hashtab, (char *)v->di_key); + hash_add(&fc->l_vars.dv_hashtab, v->di_key); } else { - hash_add(&fc->l_avars.dv_hashtab, (char *)v->di_key); + hash_add(&fc->l_avars.dv_hashtab, v->di_key); } if (ai >= 0 && ai < MAX_FUNC_ARGS) { @@ -1575,7 +1575,7 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t XFREE_CLEAR(name); funcname = "v:lua"; } - } else if (fp != NULL || !builtin_function((const char *)rfname, -1)) { + } else if (fp != NULL || !builtin_function(rfname, -1)) { // User defined function. if (fp == NULL) { fp = find_func(rfname); @@ -1589,8 +1589,7 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t fp = find_func(rfname); } // Try loading a package. - if (fp == NULL && script_autoload((const char *)rfname, strlen(rfname), - true) && !aborting()) { + if (fp == NULL && script_autoload(rfname, strlen(rfname), true) && !aborting()) { // Loaded a package, search for the function again. fp = find_func(rfname); } @@ -1666,7 +1665,7 @@ static void list_func_head(ufunc_T *fp, int indent, bool force) } msg_puts(force ? "function! " : "function "); if (fp->uf_name_exp != NULL) { - msg_puts((const char *)fp->uf_name_exp); + msg_puts(fp->uf_name_exp); } else { msg_puts(fp->uf_name); } @@ -1676,7 +1675,7 @@ static void list_func_head(ufunc_T *fp, int indent, bool force) if (j) { msg_puts(", "); } - msg_puts((const char *)FUNCARG(fp, j)); + msg_puts(FUNCARG(fp, j)); if (j >= fp->uf_args.ga_len - fp->uf_def_args.ga_len) { msg_puts(" = "); msg_puts(((char **)(fp->uf_def_args.ga_data)) @@ -1771,7 +1770,7 @@ char *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, part semsg(_(e_invarg2), start); } } else { - *pp = (char *)find_name_end((char *)start, NULL, NULL, FNE_INCL_BR); + *pp = (char *)find_name_end(start, NULL, NULL, FNE_INCL_BR); } goto theend; } @@ -1828,7 +1827,7 @@ char *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, part len = (int)strlen(lv.ll_exp_name); name = deref_func_name(lv.ll_exp_name, &len, partial, flags & TFN_NO_AUTOLOAD); - if ((const char *)name == lv.ll_exp_name) { + if (name == lv.ll_exp_name) { name = NULL; } } else if (!(flags & TFN_NO_DEREF)) { @@ -1881,8 +1880,7 @@ char *trans_function_name(char **pp, bool skip, int flags, funcdict_T *fdp, part lead = 0; // do nothing } else if (lead > 0) { lead = 3; - if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) - || eval_fname_sid((const char *)(*pp))) { + if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) || eval_fname_sid(*pp)) { // It's "s:" or "<SID>". if (current_sctx.sc_sid <= 0) { emsg(_(e_usingsid)); @@ -2209,7 +2207,7 @@ void ex_function(exarg_T *eap) if (KeyTyped && ui_has(kUICmdline)) { show_block = true; - ui_ext_cmdline_block_append(0, (const char *)eap->cmd); + ui_ext_cmdline_block_append(0, eap->cmd); } // find extra arguments "range", "dict", "abort" and "closure" @@ -2308,7 +2306,7 @@ void ex_function(exarg_T *eap) } if (show_block) { assert(indent >= 0); - ui_ext_cmdline_block_append((size_t)indent, (const char *)theline); + ui_ext_cmdline_block_append((size_t)indent, theline); } // Detect line continuation: SOURCING_LNUM increased more than one. @@ -2390,7 +2388,7 @@ void ex_function(exarg_T *eap) if (*p == '!') { p = skipwhite(p + 1); } - p += eval_fname_script((const char *)p); + p += eval_fname_script(p); xfree(trans_function_name(&p, true, 0, NULL, NULL)); if (*skipwhite(p) == '(') { if (nesting == MAX_FUNC_NESTING - 1) { @@ -2501,7 +2499,7 @@ void ex_function(exarg_T *eap) // If there are no errors, add the function if (fudi.fd_dict == NULL) { - v = find_var((const char *)name, strlen(name), &ht, false); + v = find_var(name, strlen(name), &ht, false); if (v != NULL && v->di_tv.v_type == VAR_FUNC) { emsg_funcname(N_("E707: Function name conflicts with variable: %s"), name); goto erret; @@ -2548,13 +2546,11 @@ void ex_function(exarg_T *eap) goto erret; } if (fudi.fd_di == NULL) { - if (value_check_lock(fudi.fd_dict->dv_lock, (const char *)eap->arg, - TV_CSTRING)) { + if (value_check_lock(fudi.fd_dict->dv_lock, eap->arg, TV_CSTRING)) { // Can't add a function to a locked dictionary goto erret; } - } else if (value_check_lock(fudi.fd_di->di_tv.v_lock, (const char *)eap->arg, - TV_CSTRING)) { + } else if (value_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, TV_CSTRING)) { // Can't change an existing function if it is locked goto erret; } @@ -2595,7 +2591,7 @@ void ex_function(exarg_T *eap) if (fudi.fd_dict != NULL) { if (fudi.fd_di == NULL) { // Add new dict entry - fudi.fd_di = tv_dict_item_alloc((const char *)fudi.fd_newkey); + fudi.fd_di = tv_dict_item_alloc(fudi.fd_newkey); if (tv_dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) { xfree(fudi.fd_di); xfree(fp); @@ -2616,7 +2612,7 @@ void ex_function(exarg_T *eap) set_ufunc_name(fp, name); if (overwrite) { hi = hash_find(&func_hashtab, name); - hi->hi_key = (char *)UF2HIKEY(fp); + hi->hi_key = UF2HIKEY(fp); } else if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) { xfree(fp); goto erret; @@ -2685,7 +2681,7 @@ int eval_fname_script(const char *const p) bool translated_function_exists(const char *name) { if (builtin_function(name, -1)) { - return find_internal_func((char *)name) != NULL; + return find_internal_func(name) != NULL; } return find_func(name) != NULL; } diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index ed2453bd59..9120cc4471 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -50,8 +50,8 @@ #define DICT_MAXNEST 100 // maximum nesting of lists and dicts -static char *e_letunexp = N_("E18: Unexpected characters in :let"); -static char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s"); +static const char *e_letunexp = N_("E18: Unexpected characters in :let"); +static const char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s"); /// Get a list of lines from a HERE document. The here document is a list of /// lines surrounded by a marker. @@ -197,10 +197,10 @@ static void ex_let_const(exarg_T *eap, const bool is_const) int var_count = 0; int semicolon = 0; char op[2]; - char *argend; + const char *argend; int first = true; - argend = (char *)skip_var_list(arg, &var_count, &semicolon); + argend = skip_var_list(arg, &var_count, &semicolon); if (argend == NULL) { return; } @@ -215,7 +215,7 @@ static void ex_let_const(exarg_T *eap, const bool is_const) emsg(_(e_invarg)); } else if (!ends_excmd(*arg)) { // ":let var1 var2" - arg = (char *)list_arg_vars(eap, (const char *)arg, &first); + arg = (char *)list_arg_vars(eap, arg, &first); } else if (!eap->skip) { // ":let" list_glob_vars(&first); @@ -235,8 +235,7 @@ static void ex_let_const(exarg_T *eap, const bool is_const) if (!eap->skip) { op[0] = '='; op[1] = NUL; - (void)ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, - is_const, (char *)op); + (void)ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, is_const, op); } tv_clear(&rettv); } @@ -267,8 +266,7 @@ static void ex_let_const(exarg_T *eap, const bool is_const) } emsg_skip--; } else if (i != FAIL) { - (void)ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, - is_const, (char *)op); + (void)ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, is_const, op); tv_clear(&rettv); } } @@ -375,7 +373,7 @@ const char *skip_var_list(const char *arg, int *var_count, int *semicolon) const char *p = arg; for (;;) { p = skipwhite(p + 1); // skip whites after '[', ';' or ',' - s = skip_var_one((char *)p); + s = skip_var_one(p); if (s == p) { semsg(_(e_invarg2), p); return NULL; @@ -398,7 +396,7 @@ const char *skip_var_list(const char *arg, int *var_count, int *semicolon) } return p + 1; } - return skip_var_one((char *)arg); + return skip_var_one(arg); } /// Skip one (assignable) variable name, including @r, $VAR, &option, d.key, @@ -408,8 +406,8 @@ static const char *skip_var_one(const char *arg) if (*arg == '@' && arg[1] != NUL) { return arg + 2; } - return (char *)find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, - NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); + return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, + NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); } /// List variables for hashtab "ht" with prefix "prefix". @@ -430,7 +428,7 @@ void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, int *firs // apply :filter /pat/ to variable name xstrlcpy(buf, prefix, IOSIZE); - xstrlcat(buf, (char *)di->di_key, IOSIZE); + xstrlcat(buf, di->di_key, IOSIZE); if (message_filtered(buf)) { continue; } @@ -551,7 +549,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) xfree(tofree); } - arg = (const char *)skipwhite(arg); + arg = skipwhite(arg); } return arg; @@ -601,7 +599,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo char *s = vim_getenv(name); if (s != NULL) { tofree = concat_str(s, p); - p = (const char *)tofree; + p = tofree; xfree(s); } } @@ -693,7 +691,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, (long)n, s, scope); + const char *err = set_option_value(arg, (long)n, s, scope); arg_end = p; if (err != NULL) { emsg(_(err)); @@ -725,7 +723,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo char *s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); if (s != NULL) { ptofree = concat_str(s, p); - p = (const char *)ptofree; + p = ptofree; xfree(s); } } @@ -798,7 +796,7 @@ static void ex_unletlock(exarg_T *eap, char *argstart, int deep, ex_unletlock_ca do { if (*arg == '$') { - lv.ll_name = (const char *)arg; + lv.ll_name = arg; lv.ll_tv = NULL; arg++; if (get_env_len((const char **)&arg) == 0) { @@ -915,7 +913,7 @@ static int do_unlet_var(lval_T *lp, char *name_end, exarg_T *eap, int deep FUNC_ if (watched) { tv_copy(&di->di_tv, &oldtv); // need to save key because dictitem_remove will free it - key = xstrdup((char *)di->di_key); + key = xstrdup(di->di_key); } tv_dict_item_remove(d, di); @@ -1151,7 +1149,7 @@ void vars_clear_ext(hashtab_T *ht, int free_val) } } hash_clear(ht); - ht->ht_used = 0; + hash_init(ht); } /// Delete a variable from hashtab "ht" at item "hi". @@ -1169,7 +1167,7 @@ void delete_var(hashtab_T *ht, hashitem_T *hi) static void list_one_var(dictitem_T *v, const char *prefix, int *first) { char *const s = encode_tv2echo(&v->di_tv, NULL); - list_one_var_a(prefix, (const char *)v->di_key, (ptrdiff_t)strlen((char *)v->di_key), + list_one_var_a(prefix, v->di_key, (ptrdiff_t)strlen(v->di_key), v->di_tv.v_type, (s == NULL ? "" : s), first); xfree(s); } @@ -1206,7 +1204,7 @@ static void list_one_var_a(const char *prefix, const char *name, const ptrdiff_t msg_putchar(' '); } - msg_outtrans((char *)string); + msg_outtrans(string); if (type == VAR_FUNC || type == VAR_PARTIAL) { msg_puts("()"); @@ -1343,7 +1341,7 @@ void set_var_const(const char *name, const size_t name_len, typval_T *const tv, v = xmalloc(offsetof(dictitem_T, di_key) + strlen(varname) + 1); STRCPY(v->di_key, varname); - if (hash_add(ht, (char *)v->di_key) == FAIL) { + if (hash_add(ht, v->di_key) == FAIL) { xfree(v); return; } @@ -1362,7 +1360,7 @@ void set_var_const(const char *name, const size_t name_len, typval_T *const tv, } if (watched) { - tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv); + tv_dict_watcher_notify(dict, v->di_key, &v->di_tv, &oldtv); tv_clear(&oldtv); } diff --git a/src/nvim/eval/window.c b/src/nvim/eval/window.c index c1d2e5b38f..25de236d90 100644 --- a/src/nvim/eval/window.c +++ b/src/nvim/eval/window.c @@ -36,8 +36,8 @@ # include "eval/window.c.generated.h" #endif -static char *e_invalwindow = N_("E957: Invalid window number"); -static char e_cannot_resize_window_in_another_tab_page[] +static const char *e_invalwindow = N_("E957: Invalid window number"); +static const char e_cannot_resize_window_in_another_tab_page[] = N_("E1308: Cannot resize a window in another tab page"); static int win_getid(typval_T *argvars) @@ -265,7 +265,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar) } else { // Extract the window count (if specified). e.g. winnr('3j') char *endp; - long count = strtol((char *)arg, &endp, 10); + long count = strtol(arg, &endp, 10); if (count <= 0) { // if count is not specified, default to 1 count = 1; diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 8f8a36eff9..0096d0e11e 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -112,13 +112,13 @@ static MultiQueue *multiqueue_new(MultiQueue *parent, PutCallback put_cb, void * return rv; } -void multiqueue_free(MultiQueue *this) +void multiqueue_free(MultiQueue *self) { - assert(this); + assert(self); QUEUE *q; - QUEUE_FOREACH(q, &this->headtail, { + QUEUE_FOREACH(q, &self->headtail, { MultiQueueItem *item = multiqueue_node_data(q); - if (this->parent) { + if (self->parent) { QUEUE_REMOVE(&item->data.item.parent_item->node); xfree(item->data.item.parent_item); } @@ -126,29 +126,29 @@ void multiqueue_free(MultiQueue *this) xfree(item); }) - xfree(this); + xfree(self); } /// Removes the next item and returns its Event. -Event multiqueue_get(MultiQueue *this) +Event multiqueue_get(MultiQueue *self) { - return multiqueue_empty(this) ? NILEVENT : multiqueue_remove(this); + return multiqueue_empty(self) ? NILEVENT : multiqueue_remove(self); } -void multiqueue_put_event(MultiQueue *this, Event event) +void multiqueue_put_event(MultiQueue *self, Event event) { - assert(this); - multiqueue_push(this, event); - if (this->parent && this->parent->put_cb) { - this->parent->put_cb(this->parent, this->parent->data); + assert(self); + multiqueue_push(self, event); + if (self->parent && self->parent->put_cb) { + self->parent->put_cb(self->parent, self->parent->data); } } -void multiqueue_process_events(MultiQueue *this) +void multiqueue_process_events(MultiQueue *self) { - assert(this); - while (!multiqueue_empty(this)) { - Event event = multiqueue_remove(this); + assert(self); + while (!multiqueue_empty(self)) { + Event event = multiqueue_remove(self); if (event.handler) { event.handler(event.argv); } @@ -156,30 +156,30 @@ void multiqueue_process_events(MultiQueue *this) } /// Removes all events without processing them. -void multiqueue_purge_events(MultiQueue *this) +void multiqueue_purge_events(MultiQueue *self) { - assert(this); - while (!multiqueue_empty(this)) { - (void)multiqueue_remove(this); + assert(self); + while (!multiqueue_empty(self)) { + (void)multiqueue_remove(self); } } -bool multiqueue_empty(MultiQueue *this) +bool multiqueue_empty(MultiQueue *self) { - assert(this); - return QUEUE_EMPTY(&this->headtail); + assert(self); + return QUEUE_EMPTY(&self->headtail); } -void multiqueue_replace_parent(MultiQueue *this, MultiQueue *new_parent) +void multiqueue_replace_parent(MultiQueue *self, MultiQueue *new_parent) { - assert(multiqueue_empty(this)); - this->parent = new_parent; + assert(multiqueue_empty(self)); + self->parent = new_parent; } /// Gets the count of all events currently in the queue. -size_t multiqueue_size(MultiQueue *this) +size_t multiqueue_size(MultiQueue *self) { - return this->size; + return self->size; } /// Gets an Event from an item. @@ -213,35 +213,35 @@ static Event multiqueueitem_get_event(MultiQueueItem *item, bool remove) return ev; } -static Event multiqueue_remove(MultiQueue *this) +static Event multiqueue_remove(MultiQueue *self) { - assert(!multiqueue_empty(this)); - QUEUE *h = QUEUE_HEAD(&this->headtail); + assert(!multiqueue_empty(self)); + QUEUE *h = QUEUE_HEAD(&self->headtail); QUEUE_REMOVE(h); MultiQueueItem *item = multiqueue_node_data(h); - assert(!item->link || !this->parent); // Only a parent queue has link-nodes + assert(!item->link || !self->parent); // Only a parent queue has link-nodes Event ev = multiqueueitem_get_event(item, true); - this->size--; + self->size--; xfree(item); return ev; } -static void multiqueue_push(MultiQueue *this, Event event) +static void multiqueue_push(MultiQueue *self, Event event) { MultiQueueItem *item = xmalloc(sizeof(MultiQueueItem)); item->link = false; item->data.item.event = event; item->data.item.parent_item = NULL; - QUEUE_INSERT_TAIL(&this->headtail, &item->node); - if (this->parent) { + QUEUE_INSERT_TAIL(&self->headtail, &item->node); + if (self->parent) { // push link node to the parent queue item->data.item.parent_item = xmalloc(sizeof(MultiQueueItem)); item->data.item.parent_item->link = true; - item->data.item.parent_item->data.queue = this; - QUEUE_INSERT_TAIL(&this->parent->headtail, + item->data.item.parent_item->data.queue = self; + QUEUE_INSERT_TAIL(&self->parent->headtail, &item->data.item.parent_item->node); } - this->size++; + self->size++; } static MultiQueueItem *multiqueue_node_data(QUEUE *q) diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 705f0fe83d..a1b43113a6 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -150,7 +150,7 @@ void do_ascii(const exarg_T *const eap) if (vim_isprintc_strict(c) && (c < ' ' || c > '~')) { char buf3[7]; transchar_nonprint(curbuf, buf3, c); - vim_snprintf(buf1, sizeof(buf1), " <%s>", (char *)buf3); + vim_snprintf(buf1, sizeof(buf1), " <%s>", buf3); } else { buf1[0] = NUL; } @@ -1361,12 +1361,12 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) { bool is_fish_shell = #if defined(UNIX) - strncmp((char *)invocation_path_tail(p_sh, NULL), "fish", 4) == 0; + strncmp(invocation_path_tail(p_sh, NULL), "fish", 4) == 0; #else false; #endif - bool is_pwsh = strncmp((char *)invocation_path_tail(p_sh, NULL), "pwsh", 4) == 0 - || strncmp((char *)invocation_path_tail(p_sh, NULL), "powershell", + bool is_pwsh = strncmp(invocation_path_tail(p_sh, NULL), "pwsh", 4) == 0 + || strncmp(invocation_path_tail(p_sh, NULL), "powershell", 10) == 0; size_t len = strlen(cmd) + 1; // At least enough space for cmd + NULL. @@ -1388,7 +1388,7 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) if (is_pwsh) { if (itmp != NULL) { xstrlcpy(buf, "& { Get-Content ", len - 1); // FIXME: should we add "-Encoding utf8"? - xstrlcat(buf, (const char *)itmp, len - 1); + xstrlcat(buf, itmp, len - 1); xstrlcat(buf, " | & ", len - 1); // FIXME: add `&` ourself or leave to user? xstrlcat(buf, cmd, len - 1); xstrlcat(buf, " }", len - 1); @@ -1409,7 +1409,7 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) if (itmp != NULL) { xstrlcat(buf, " < ", len - 1); - xstrlcat(buf, (const char *)itmp, len - 1); + xstrlcat(buf, itmp, len - 1); } #else // For shells that don't understand braces around commands, at least allow @@ -1426,9 +1426,9 @@ char *make_filter_cmd(char *cmd, char *itmp, char *otmp) } } xstrlcat(buf, " < ", len); - xstrlcat(buf, (const char *)itmp, len); + xstrlcat(buf, itmp, len); if (*p_shq == NUL) { - const char *const p = find_pipe((const char *)cmd); + const char *const p = find_pipe(cmd); if (p != NULL) { xstrlcat(buf, " ", len - 1); // Insert a space before the '|' for DOS xstrlcat(buf, p, len - 1); @@ -4288,7 +4288,7 @@ bool do_sub_msg(bool count_only) "%" PRId64 " matches on %" PRId64 " lines", sub_nsubs) : NGETTEXT("%" PRId64 " substitution on %" PRId64 " lines", "%" PRId64 " substitutions on %" PRId64 " lines", sub_nsubs); - vim_snprintf_add((char *)msg_buf, sizeof(msg_buf), + vim_snprintf_add(msg_buf, sizeof(msg_buf), NGETTEXT(msg_single, msg_plural, sub_nlines), (int64_t)sub_nsubs, (int64_t)sub_nlines); if (msg(msg_buf)) { @@ -4745,7 +4745,7 @@ void ex_oldfiles(exarg_T *eap) if (!message_filtered(fname)) { msg_outnum(nr); msg_puts(": "); - msg_outtrans((char *)tv_get_string(TV_LIST_ITEM_TV(li))); + msg_outtrans(tv_get_string(TV_LIST_ITEM_TV(li))); msg_clr_eos(); msg_putchar('\n'); os_breakcheck(); diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index a86676733f..6d190df939 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -814,7 +814,7 @@ static void script_host_do_range(char *name, exarg_T *eap) list_T *args = tv_list_alloc(3); tv_list_append_number(args, (int)eap->line1); tv_list_append_number(args, (int)eap->line2); - tv_list_append_string(args, (const char *)eap->arg, -1); + tv_list_append_string(args, eap->arg, -1); (void)eval_call_provider(name, "do_range", args, true); } } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 6a259b75fb..699c1da3a7 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -85,15 +85,15 @@ #include "nvim/vim.h" #include "nvim/window.h" -static char e_ambiguous_use_of_user_defined_command[] +static const char e_ambiguous_use_of_user_defined_command[] = N_("E464: Ambiguous use of user-defined command"); -static char e_not_an_editor_command[] +static const char e_not_an_editor_command[] = N_("E492: Not an editor command"); -static char e_no_source_file_name_to_substitute_for_sfile[] +static const char e_no_source_file_name_to_substitute_for_sfile[] = N_("E498: no :source file name to substitute for \"<sfile>\""); -static char e_no_call_stack_to_substitute_for_stack[] +static const char e_no_call_stack_to_substitute_for_stack[] = N_("E489: no call stack to substitute for \"<stack>\""); -static char e_no_script_file_name_to_substitute_for_script[] +static const char e_no_script_file_name_to_substitute_for_script[] = N_("E1274: No script file name to substitute for \"<script>\""); static int quitmore = 0; @@ -4452,7 +4452,7 @@ static void ex_highlight(exarg_T *eap) if (*eap->arg == NUL && eap->cmd[2] == '!') { msg(_("Greetings, Vim user!")); } - do_highlight((const char *)eap->arg, eap->forceit, false); + do_highlight(eap->arg, eap->forceit, false); } /// Call this function if we thought we were going to exit, but we won't @@ -5211,7 +5211,7 @@ void do_exedit(exarg_T *eap, win_T *old_curwin) int ms = msg_scroll; if (eap->nextcmd != NULL) { - stuffReadbuff((const char *)eap->nextcmd); + stuffReadbuff(eap->nextcmd); eap->nextcmd = NULL; } diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 1cef99297a..fed8f549e6 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -1055,7 +1055,7 @@ void ex_break(exarg_T *eap) void ex_endwhile(exarg_T *eap) { cstack_T *const cstack = eap->cstack; - char *err; + const char *err; int csf; if (eap->cmdidx == CMD_endwhile) { @@ -1125,7 +1125,7 @@ void ex_endwhile(exarg_T *eap) /// Handle ":throw expr" void ex_throw(exarg_T *eap) { - const char *arg = (const char *)eap->arg; + const char *arg = eap->arg; char *value; if (*arg != NUL && *arg != '|' && *arg != '\n') { diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index bd7ddbf567..ba403e3dd9 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -295,7 +295,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s if (*p == '!') { p = skipwhite(p + 1); } - while (ASCII_ISALPHA(*(p = skipwhite((char *)p)))) { + while (ASCII_ISALPHA(*(p = skipwhite(p)))) { p++; } if (*p == NUL) { @@ -2753,7 +2753,7 @@ void text_locked_msg(void) emsg(_(get_text_locked_msg())); } -char *get_text_locked_msg(void) +const char *get_text_locked_msg(void) { if (cmdwin_type != 0) { return e_cmdwin; @@ -2947,7 +2947,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, { ParserLine parser_lines[] = { { - .data = (const char *)colored_ccline->cmdbuff, + .data = colored_ccline->cmdbuff, .size = strlen(colored_ccline->cmdbuff), .allocated = false, }, @@ -3051,7 +3051,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) bool can_free_cb = false; TryState tstate; Error err = ERROR_INIT; - const char *err_errmsg = (const char *)e_intern2; + const char *err_errmsg = e_intern2; bool dgc_ret = true; bool tl_ret = true; @@ -3084,8 +3084,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) } if (colored_ccline->cmdbuff[colored_ccline->cmdlen] != NUL) { arg_allocated = true; - arg.vval.v_string = xmemdupz((const char *)colored_ccline->cmdbuff, - (size_t)colored_ccline->cmdlen); + arg.vval.v_string = xmemdupz(colored_ccline->cmdbuff, (size_t)colored_ccline->cmdlen); } // msg_start() called by e.g. :echo may shift command-line to the first column // even though msg_silent is here. Two ways to workaround this problem without @@ -3204,8 +3203,7 @@ color_cmdline_end: if (arg_allocated) { ccline_colors->cmdbuff = arg.vval.v_string; } else { - ccline_colors->cmdbuff = xmemdupz((const char *)colored_ccline->cmdbuff, - (size_t)colored_ccline->cmdlen); + ccline_colors->cmdbuff = xmemdupz(colored_ccline->cmdbuff, (size_t)colored_ccline->cmdlen); } tv_clear(&tv); return ret; @@ -4274,7 +4272,7 @@ void cmdline_init(void) /// Check value of 'cedit' and set cedit_key. /// Returns NULL if value is OK, error message otherwise. -char *check_cedit(void) +const char *check_cedit(void) { if (*p_cedit == NUL) { cedit_key = -1; @@ -4558,7 +4556,7 @@ bool is_in_cmdwin(void) char *script_get(exarg_T *const eap, size_t *const lenp) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC { - const char *const cmd = (const char *)eap->arg; + const char *const cmd = eap->arg; if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) { *lenp = strlen(eap->arg); @@ -4570,7 +4568,7 @@ char *script_get(exarg_T *const eap, size_t *const lenp) ga_init(&ga, 1, 0x400); } - const char *const end_pattern = (cmd[2] != NUL ? (const char *)skipwhite(cmd + 2) : "."); + const char *const end_pattern = (cmd[2] != NUL ? skipwhite(cmd + 2) : "."); for (;;) { char *const theline = eap->getline(eap->cstack->cs_looplevel > 0 ? -1 : NUL, eap->cookie, 0, true); diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index d91e2dfeeb..6782c0211b 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -182,7 +182,7 @@ typedef struct ff_search_ctx_T { # include "file_search.c.generated.h" #endif -static char e_pathtoolong[] = N_("E854: path too long for completion"); +static const char e_pathtoolong[] = N_("E854: path too long for completion"); /// Initialization routine for vim_findfile(). /// @@ -1117,28 +1117,28 @@ static int ff_check_visited(ff_visited_T **visited_list, char *fname, char *wc_p static ff_stack_T *ff_create_stack_element(char *fix_part, char *wc_part, int level, int star_star_empty) { - ff_stack_T *new = xmalloc(sizeof(ff_stack_T)); + ff_stack_T *stack = xmalloc(sizeof(ff_stack_T)); - new->ffs_prev = NULL; - new->ffs_filearray = NULL; - new->ffs_filearray_size = 0; - new->ffs_filearray_cur = 0; - new->ffs_stage = 0; - new->ffs_level = level; - new->ffs_star_star_empty = star_star_empty; + stack->ffs_prev = NULL; + stack->ffs_filearray = NULL; + stack->ffs_filearray_size = 0; + stack->ffs_filearray_cur = 0; + stack->ffs_stage = 0; + stack->ffs_level = level; + stack->ffs_star_star_empty = star_star_empty; // the following saves NULL pointer checks in vim_findfile if (fix_part == NULL) { fix_part = ""; } - new->ffs_fix_path = xstrdup(fix_part); + stack->ffs_fix_path = xstrdup(fix_part); if (wc_part == NULL) { wc_part = ""; } - new->ffs_wc_path = xstrdup(wc_part); + stack->ffs_wc_path = xstrdup(wc_part); - return new; + return stack; } /// Push a dir on the directory stack. @@ -1341,7 +1341,7 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch char *buf = NULL; int rel_to_curdir; - if (rel_fname != NULL && path_with_url((const char *)rel_fname)) { + if (rel_fname != NULL && path_with_url(rel_fname)) { // Do not attempt to search "relative" to a URL. #6009 rel_fname = NULL; } diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 684658b4e3..d4725ccd86 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -134,8 +134,8 @@ static char *err_readonly = "is read-only (cannot override: \"W\" in 'cpoptions' # include "fileio.c.generated.h" #endif -static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name"); -static char e_no_matching_autocommands_for_buftype_str_buffer[] +static const char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name"); +static const char e_no_matching_autocommands_for_buftype_str_buffer[] = N_("E676: No matching autocommands for buftype=%s buffer"); void filemess(buf_T *buf, char *name, char *s, int attr) @@ -145,7 +145,7 @@ void filemess(buf_T *buf, char *name, char *s, int attr) if (msg_silent != 0) { return; } - add_quoted_fname(IObuff, IOSIZE - 100, buf, (const char *)name); + add_quoted_fname(IObuff, IOSIZE - 100, buf, name); // Avoid an over-long translation to cause trouble. xstrlcat(IObuff, s, IOSIZE); // For the first message may have to start a new line. @@ -576,7 +576,7 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip, // Set swap file protection bits after creating it. if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL && curbuf->b_ml.ml_mfp->mf_fname != NULL) { - const char *swap_fname = (const char *)curbuf->b_ml.ml_mfp->mf_fname; + const char *swap_fname = curbuf->b_ml.ml_mfp->mf_fname; // If the group-read bit is set but not the world-read bit, then // the group must be equal to the group of the original file. If @@ -1732,7 +1732,7 @@ failed: } if (!filtering && !(flags & READ_DUMMY) && !silent) { - add_quoted_fname(IObuff, IOSIZE, curbuf, (const char *)sfname); + add_quoted_fname(IObuff, IOSIZE, curbuf, sfname); c = false; #ifdef UNIX @@ -2372,7 +2372,7 @@ static int get_fileinfo_os(char *fname, FileInfo *file_info_old, bool overwritin *newfile = true; *perm = -1; } else { - *perm = os_getperm((const char *)fname); + *perm = os_getperm(fname); if (*perm < 0) { *newfile = true; } else if (os_isdir(fname)) { @@ -2611,7 +2611,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o // set file protection same as original file, but // strip s-bit. - (void)os_setperm((const char *)(*backupp), perm & 0777); + (void)os_setperm(*backupp, perm & 0777); #ifdef UNIX // @@ -2621,8 +2621,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o // if (file_info_new.stat.st_gid != file_info_old->stat.st_gid && os_chown(*backupp, (uv_uid_t)-1, (uv_gid_t)file_info_old->stat.st_gid) != 0) { - os_setperm((const char *)(*backupp), - ((int)perm & 0707) | (((int)perm & 07) << 3)); + os_setperm(*backupp, ((int)perm & 0707) | (((int)perm & 07) << 3)); } #endif @@ -2960,7 +2959,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en && file_info_old.stat.st_uid == getuid() && vim_strchr(p_cpo, CPO_FWRITE) == NULL) { perm |= 0200; - (void)os_setperm((const char *)fname, (int)perm); + (void)os_setperm(fname, (int)perm); made_writable = true; } #endif @@ -3378,7 +3377,7 @@ restore_backup: } #endif if (perm >= 0) { // Set perm. of new file same as old file. - (void)os_setperm((const char *)wfname, (int)perm); + (void)os_setperm(wfname, (int)perm); } // Probably need to set the ACL before changing the user (can't set the // ACL on a file the user doesn't own). @@ -3459,7 +3458,7 @@ restore_backup: fname = sfname; // use shortname now, for the messages #endif if (!filtering) { - add_quoted_fname(IObuff, IOSIZE, buf, (const char *)fname); + add_quoted_fname(IObuff, IOSIZE, buf, fname); bool insert_space = false; if (write_info.bw_conv_error) { STRCAT(IObuff, _(" CONVERSION ERROR")); @@ -3563,7 +3562,7 @@ restore_backup: } } if (org != NULL) { - os_setperm(org, os_getperm((const char *)fname) & 0777); + os_setperm(org, os_getperm(fname) & 0777); xfree(org); } } @@ -3600,9 +3599,9 @@ nofail: if (err.msg != NULL) { // - 100 to save some space for further error message #ifndef UNIX - add_quoted_fname(IObuff, IOSIZE - 100, buf, (const char *)sfname); + add_quoted_fname(IObuff, IOSIZE - 100, buf, sfname); #else - add_quoted_fname(IObuff, IOSIZE - 100, buf, (const char *)fname); + add_quoted_fname(IObuff, IOSIZE - 100, buf, fname); #endif emit_err(&err); @@ -4229,7 +4228,7 @@ void shorten_fnames(int force) os_dirname(dirname, MAXPATHL); FOR_ALL_BUFFERS(buf) { - shorten_buf_fname(buf, (char *)dirname, force); + shorten_buf_fname(buf, dirname, force); // Always make the swap file name a full path, a "nofile" buffer may // also have a swap file. @@ -4363,7 +4362,7 @@ bool vim_fgets(char *buf, int size, FILE *fp) do { tbuf[sizeof(tbuf) - 2] = NUL; errno = 0; - retval = fgets((char *)tbuf, sizeof(tbuf), fp); + retval = fgets(tbuf, sizeof(tbuf), fp); if (retval == NULL && (feof(fp) || errno != EINTR)) { break; } @@ -4545,8 +4544,7 @@ int vim_rename(const char *from, const char *to) // to the same file (ignoring case and slash/backslash differences) but // the file name differs we need to go through a temp file. if (path_fnamecmp(from, to) == 0) { - if (p_fic && (strcmp(path_tail((char *)from), path_tail((char *)to)) - != 0)) { + if (p_fic && (strcmp(path_tail(from), path_tail(to)) != 0)) { use_tmp_file = true; } else { return 0; @@ -4555,7 +4553,7 @@ int vim_rename(const char *from, const char *to) // Fail if the "from" file doesn't exist. Avoids that "to" is deleted. FileInfo from_info; - if (!os_fileinfo((char *)from, &from_info)) { + if (!os_fileinfo(from, &from_info)) { return -1; } @@ -4563,8 +4561,7 @@ int vim_rename(const char *from, const char *to) // This happens when "from" and "to" differ in case and are on a FAT32 // filesystem. In that case go through a temp file name. FileInfo to_info; - if (os_fileinfo((char *)to, &to_info) - && os_fileinfo_id_equal(&from_info, &to_info)) { + if (os_fileinfo(to, &to_info) && os_fileinfo_id_equal(&from_info, &to_info)) { use_tmp_file = true; } @@ -4576,7 +4573,7 @@ int vim_rename(const char *from, const char *to) // os_rename() work, on other systems it makes sure that we don't have // two files when the os_rename() fails. - os_remove((char *)to); + os_remove(to); // First try a normal rename, return if it works. if (os_rename(from, to) == OK) { @@ -4587,14 +4584,14 @@ int vim_rename(const char *from, const char *to) long perm = os_getperm(from); // For systems that support ACL: get the ACL from the original file. vim_acl_T acl = os_get_acl(from); - int fd_in = os_open((char *)from, O_RDONLY, 0); + int fd_in = os_open(from, O_RDONLY, 0); if (fd_in < 0) { os_free_acl(acl); return -1; } // Create the new file with same permissions as the original. - int fd_out = os_open((char *)to, O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)perm); + int fd_out = os_open(to, O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)perm); if (fd_out < 0) { close(fd_in); os_free_acl(acl); @@ -4637,7 +4634,7 @@ int vim_rename(const char *from, const char *to) semsg(errmsg, to); return -1; } - os_remove((char *)from); + os_remove(from); return 0; } @@ -5295,7 +5292,7 @@ int delete_recursive(const char *name) if (readdir_core(&ga, exp, NULL, NULL) == OK) { for (int i = 0; i < ga.ga_len; i++) { vim_snprintf(NameBuff, MAXPATHL, "%s/%s", exp, ((char **)ga.ga_data)[i]); - if (delete_recursive((const char *)NameBuff) != 0) { + if (delete_recursive(NameBuff) != 0) { // Remember the failure but continue deleting any further // entries. result = -1; @@ -5428,10 +5425,9 @@ char *vim_tempname(void) // There is no need to check if the file exists, because we own the directory // and nobody else creates a file in it. - char template[TEMP_FILE_PATH_MAXLEN]; - snprintf(template, TEMP_FILE_PATH_MAXLEN, - "%s%" PRIu64, tempdir, temp_count++); - return xstrdup(template); + char templ[TEMP_FILE_PATH_MAXLEN]; + snprintf(templ, TEMP_FILE_PATH_MAXLEN, "%s%" PRIu64, tempdir, temp_count++); + return xstrdup(templ); } /// Tries matching a filename with a "pattern" ("prog" is NULL), or use the diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 7306131574..71984e806d 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -101,7 +101,7 @@ typedef void (*LevelGetter)(fline_T *); #ifdef INCLUDE_GENERATED_DECLARATIONS # include "fold.c.generated.h" #endif -static char *e_nofold = N_("E490: No fold found"); +static const char *e_nofold = N_("E490: No fold found"); // While updating the folds lines between invalid_top and invalid_bot have an // undefined fold level. Only used for the window currently being updated. @@ -1786,7 +1786,7 @@ char *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldinfo } } if (*p != NUL) { - p = transstr((const char *)text, true); + p = transstr(text, true); xfree(text); text = p; } diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua index 3e89b60b4a..17a224fd22 100644 --- a/src/nvim/generators/c_grammar.lua +++ b/src/nvim/generators/c_grammar.lua @@ -55,5 +55,11 @@ local c_proto = Ct( fill * P(';') ) -local grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1) +local c_field = Ct(Cg(c_id, 'type') * ws * Cg(c_id, 'name') * fill * P(';') * fill) +local c_keyset = Ct( + P('typedef') * ws * P('struct') * fill * P('{') * fill * + Cg(Ct(c_field ^ 1), 'fields') * + P('}') * fill * P('Dict') * fill * P('(') * Cg(c_id, 'keyset_name') * fill * P(')') * P(';')) + +local grammar = Ct((c_proto + c_comment + c_preproc + ws + c_keyset) ^ 1) return {grammar=grammar, typed_container=typed_container} diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 8aa1829364..f292c265ec 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -8,6 +8,7 @@ if arg[1] == '--help' then print(' 3: functions metadata output file (funcs_metadata.generated.h)') print(' 4: API metadata output file (api_metadata.mpack)') print(' 5: lua C bindings output file (lua_api_c_bindings.generated.c)') + print(' 6: keyset definitions output file (keysets_defs.generated.h)') print(' rest: C files where API functions are defined') end assert(#arg >= 4) @@ -32,6 +33,7 @@ local funcs_metadata_outputf = arg[3] -- output metadata mpack file, for use by other build scripts local mpack_outputf = arg[4] local lua_c_bindings_outputf = arg[5] +local keysets_outputf = arg[6] -- set of function names, used to detect duplicates local function_names = {} @@ -42,8 +44,57 @@ local function startswith(String,Start) return string.sub(String,1,string.len(Start))==Start end +local function add_function(fn) + local public = startswith(fn.name, "nvim_") or fn.deprecated_since + if public and not fn.noexport then + functions[#functions + 1] = fn + function_names[fn.name] = true + if #fn.parameters >= 2 and fn.parameters[2][1] == 'Array' and fn.parameters[2][2] == 'uidata' then + -- function receives the "args" as a parameter + fn.receives_array_args = true + -- remove the args parameter + table.remove(fn.parameters, 2) + end + if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then + -- this function should receive the channel id + fn.receives_channel_id = true + -- remove the parameter since it won't be passed by the api client + table.remove(fn.parameters, 1) + end + if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'error' then + -- function can fail if the last parameter type is 'Error' + fn.can_fail = true + -- remove the error parameter, msgpack has it's own special field + -- for specifying errors + fn.parameters[#fn.parameters] = nil + end + if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then + -- return value is allocated in an arena + fn.arena_return = true + fn.parameters[#fn.parameters] = nil + end + if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then + fn.has_lua_imp = true + fn.parameters[#fn.parameters] = nil + end + end +end + +local keysets = {} + +local function add_keyset(val) + local keys = {} + for _,field in ipairs(val.fields) do + if field.type ~= 'Object' then + error 'not yet implemented: types other than Object' + end + table.insert(keys, field.name) + end + table.insert(keysets, {val.keyset_name, keys}) +end + -- read each input file, parse and append to the api metadata -for i = 6, #arg do +for i = 7, #arg do local full_path = arg[i] local parts = {} for part in string.gmatch(full_path, '[^/]+') do @@ -55,39 +106,11 @@ for i = 6, #arg do local tmp = c_grammar.grammar:match(input:read('*all')) for j = 1, #tmp do - local fn = tmp[j] - local public = startswith(fn.name, "nvim_") or fn.deprecated_since - if public and not fn.noexport then - functions[#functions + 1] = tmp[j] - function_names[fn.name] = true - if #fn.parameters >= 2 and fn.parameters[2][1] == 'Array' and fn.parameters[2][2] == 'uidata' then - -- function receives the "args" as a parameter - fn.receives_array_args = true - -- remove the args parameter - table.remove(fn.parameters, 2) - end - if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then - -- this function should receive the channel id - fn.receives_channel_id = true - -- remove the parameter since it won't be passed by the api client - table.remove(fn.parameters, 1) - end - if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'error' then - -- function can fail if the last parameter type is 'Error' - fn.can_fail = true - -- remove the error parameter, msgpack has it's own special field - -- for specifying errors - fn.parameters[#fn.parameters] = nil - end - if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then - -- return value is allocated in an arena - fn.arena_return = true - fn.parameters[#fn.parameters] = nil - end - if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then - fn.has_lua_imp = true - fn.parameters[#fn.parameters] = nil - end + local val = tmp[j] + if val.keyset_name then + add_keyset(val) + else + add_function(val) end end input:close() @@ -195,6 +218,7 @@ funcs_metadata_output:close() -- start building the dispatch wrapper output local output = io.open(dispatch_outputf, 'wb') +local keysets_defs = io.open(keysets_outputf, 'wb') -- =========================================================================== -- NEW API FILES MUST GO HERE. @@ -224,6 +248,52 @@ output:write([[ ]]) +for _,keyset in ipairs(keysets) do + local name, keys = unpack(keyset) + local special = {} + local function sanitize(key) + if special[key] then + return key .. "_" + end + return key + end + + for i = 1,#keys do + if vim.endswith(keys[i], "_") then + keys[i] = string.sub(keys[i],1, #(keys[i]) - 1) + special[keys[i]] = true + end + end + local neworder, hashfun = hashy.hashy_hash(name, keys, function (idx) + return name.."_table["..idx.."].str" + end) + + keysets_defs:write("extern KeySetLink "..name.."_table[];\n") + + output:write("KeySetLink "..name.."_table[] = {\n") + for _, key in ipairs(neworder) do + output:write(' {"'..key..'", offsetof(KeyDict_'..name..", "..sanitize(key)..")},\n") + end + output:write(' {NULL, 0},\n') + output:write("};\n\n") + + output:write(hashfun) + + output:write([[ +Object *KeyDict_]]..name..[[_get_field(void *retval, const char *str, size_t len) +{ + int hash = ]]..name..[[_hash(str, len); + if (hash == -1) { + return NULL; + } + + return (Object *)((char *)retval + ]]..name..[[_table[hash].ptr_off); +} + +]]) + keysets_defs:write("#define api_free_keydict_"..name.."(x) api_free_keydict(x, "..name.."_table)\n") +end + local function real_type(type) local rv = type local rmatch = string.match(type, "Dict%(([_%w]+)%)") @@ -475,6 +545,7 @@ output:write([[ #include "nvim/func_attr.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/dispatch.h" #include "nvim/lua/converter.h" #include "nvim/lua/executor.h" #include "nvim/memory.h" @@ -670,3 +741,4 @@ output:write([[ ]]) output:close() +keysets_defs:close() diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua index fb1dd82a26..a86dc4233e 100644 --- a/src/nvim/generators/gen_eval.lua +++ b/src/nvim/generators/gen_eval.lua @@ -94,12 +94,12 @@ for _, name in ipairs(neworder) do end local base = def.base or "BASE_NONE" local func = def.func or ('f_' .. name) - local data = def.data or "{ .nullptr = NULL }" + local data = def.data or "{ .null = NULL }" local fast = def.fast and 'true' or 'false' hashpipe:write((' { "%s", %s, %s, %s, %s, &%s, %s },\n') :format(name, args[1], args[2], base, fast, func, data)) end -hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, { .nullptr = NULL } },\n') +hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, { .null = NULL } },\n') hashpipe:write("};\n\n") hashpipe:write(hashfun) hashpipe:close() diff --git a/src/nvim/generators/gen_keysets.lua b/src/nvim/generators/gen_keysets.lua deleted file mode 100644 index b1c1f3e2d8..0000000000 --- a/src/nvim/generators/gen_keysets.lua +++ /dev/null @@ -1,80 +0,0 @@ -local nvimsrcdir = arg[1] -local shared_file = arg[2] -local funcs_file = arg[3] -local defs_file = arg[4] - -_G.vim = loadfile(shared_file)() - -if nvimsrcdir == '--help' then - print([[ -Usage: - lua gen_keyset.lua TODOFIXUPDATETHIS - -Will generate build/src/nvim/auto/keyset.generated.h with definition of functions -static const array. -]]) - os.exit(0) -end - - -package.path = nvimsrcdir .. '/?.lua;' .. package.path -local hashy = require'generators.hashy' - -local funcspipe = io.open(funcs_file, 'wb') -local defspipe = io.open(defs_file, 'wb') - -local keysets = require'api.keysets' - -local keywords = { - register = true; - default = true; -} - -local function sanitize(key) - if keywords[key] then - return key .. "_" - end - return key -end - -for _, v in ipairs(keysets) do - local name = v[1] - local keys = v[2] - local neworder, hashfun = hashy.hashy_hash(name, keys, function (idx) - return name.."_table["..idx.."].str" - end) - - defspipe:write("typedef struct {\n") - for _, key in ipairs(neworder) do - defspipe:write(" Object "..sanitize(key)..";\n") - end - defspipe:write("} KeyDict_"..name..";\n\n") - - defspipe:write("extern KeySetLink "..name.."_table[];\n") - - funcspipe:write("KeySetLink "..name.."_table[] = {\n") - for _, key in ipairs(neworder) do - funcspipe:write(' {"'..key..'", offsetof(KeyDict_'..name..", "..sanitize(key)..")},\n") - end - funcspipe:write(' {NULL, 0},\n') - funcspipe:write("};\n\n") - - funcspipe:write(hashfun) - - funcspipe:write([[ -Object *KeyDict_]]..name..[[_get_field(void *retval, const char *str, size_t len) -{ - int hash = ]]..name..[[_hash(str, len); - if (hash == -1) { - return NULL; - } - - return (Object *)((char *)retval + ]]..name..[[_table[hash].ptr_off); -} - -]]) - defspipe:write("#define api_free_keydict_"..name.."(x) api_free_keydict(x, "..name.."_table)\n") -end - -funcspipe:close() -defspipe:close() diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 745e9d27e2..69a371ccf9 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1788,7 +1788,7 @@ void f_getcharstr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) int i = 0; if (n != 0) { - i += utf_char2bytes((int)n, (char *)temp); + i += utf_char2bytes((int)n, temp); } assert(i < 7); temp[i++] = NUL; @@ -2007,8 +2007,8 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth) // Don't allow mapping the first byte(s) of a multi-byte char. // Happens when mapping <M-a> and then changing 'encoding'. // Beware that 0x80 is escaped. - char *p1 = mp->m_keys; - char *p2 = (char *)mb_unescape((const char **)&p1); + const char *p1 = mp->m_keys; + const char *p2 = mb_unescape(&p1); if (p2 != NULL && MB_BYTE2LEN(tb_c1) > utfc_ptr2len(p2)) { mlen = 0; diff --git a/src/nvim/gettext.h b/src/nvim/gettext.h index 6d2a55124e..9d7b2aec32 100644 --- a/src/nvim/gettext.h +++ b/src/nvim/gettext.h @@ -3,7 +3,7 @@ #ifdef HAVE_WORKING_LIBINTL # include <libintl.h> -# define _(x) gettext((char *)(x)) +# define _(x) gettext(x) // XXX do we actually need this? # ifdef gettext_noop # define N_(x) gettext_noop(x) @@ -17,7 +17,7 @@ # undef setlocale # endif #else -# define _(x) ((char *)(x)) +# define _(x) (x) # define N_(x) x # define NGETTEXT(x, xs, n) ((n) == 1 ? (x) : (xs)) # define bindtextdomain(x, y) // empty diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 571df45e89..7653076e39 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -866,172 +866,172 @@ EXTERN linenr_T spell_redraw_lnum INIT(= 0); // The error messages that can be shared are included here. // Excluded are errors that are only used once and debugging messages. -EXTERN char e_abort[] INIT(= N_("E470: Command aborted")); -EXTERN char e_afterinit[] INIT(= N_("E905: Cannot set this option after startup")); -EXTERN char e_api_spawn_failed[] INIT(= N_("E903: Could not spawn API job")); -EXTERN char e_argreq[] INIT(= N_("E471: Argument required")); -EXTERN char e_backslash[] INIT(= N_("E10: \\ should be followed by /, ? or &")); -EXTERN char e_cmdwin[] INIT(= N_("E11: Invalid in command-line window; <CR> executes, CTRL-C quits")); -EXTERN char e_curdir[] INIT(= N_("E12: Command not allowed in secure mode in current dir or tag search")); -EXTERN char e_command_too_recursive[] INIT(= N_("E169: Command too recursive")); -EXTERN char e_endif[] INIT(= N_("E171: Missing :endif")); -EXTERN char e_endtry[] INIT(= N_("E600: Missing :endtry")); -EXTERN char e_endwhile[] INIT(= N_("E170: Missing :endwhile")); -EXTERN char e_endfor[] INIT(= N_("E170: Missing :endfor")); -EXTERN char e_while[] INIT(= N_("E588: :endwhile without :while")); -EXTERN char e_for[] INIT(= N_("E588: :endfor without :for")); -EXTERN char e_exists[] INIT(= N_("E13: File exists (add ! to override)")); -EXTERN char e_failed[] INIT(= N_("E472: Command failed")); -EXTERN char e_internal[] INIT(= N_("E473: Internal error")); -EXTERN char e_intern2[] INIT(= N_("E685: Internal error: %s")); -EXTERN char e_interr[] INIT(= N_("Interrupted")); -EXTERN char e_invarg[] INIT(= N_("E474: Invalid argument")); -EXTERN char e_invarg2[] INIT(= N_("E475: Invalid argument: %s")); -EXTERN char e_invargval[] INIT(= N_("E475: Invalid value for argument %s")); -EXTERN char e_invargNval[] INIT(= N_("E475: Invalid value for argument %s: %s")); -EXTERN char e_duparg2[] INIT(= N_("E983: Duplicate argument: %s")); -EXTERN char e_invexpr2[] INIT(= N_("E15: Invalid expression: %s")); -EXTERN char e_invrange[] INIT(= N_("E16: Invalid range")); -EXTERN char e_invcmd[] INIT(= N_("E476: Invalid command")); -EXTERN char e_isadir2[] INIT(= N_("E17: \"%s\" is a directory")); -EXTERN char e_no_spell[] INIT(= N_("E756: Spell checking is not possible")); -EXTERN char e_invchan[] INIT(= N_("E900: Invalid channel id")); -EXTERN char e_invchanjob[] INIT(= N_("E900: Invalid channel id: not a job")); -EXTERN char e_jobtblfull[] INIT(= N_("E901: Job table is full")); -EXTERN char e_jobspawn[] INIT(= N_("E903: Process failed to start: %s: \"%s\"")); -EXTERN char e_channotpty[] INIT(= N_("E904: channel is not a pty")); -EXTERN char e_stdiochan2[] INIT(= N_("E905: Couldn't open stdio channel: %s")); -EXTERN char e_invstream[] INIT(= N_("E906: invalid stream for channel")); -EXTERN char e_invstreamrpc[] INIT(= N_("E906: invalid stream for rpc channel, use 'rpc'")); -EXTERN char e_streamkey[] INIT(= N_("E5210: dict key '%s' already set for buffered stream in channel %" PRIu64)); -EXTERN char e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\"")); -EXTERN char e_fsync[] INIT(= N_("E667: Fsync failed: %s")); -EXTERN char e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s")); -EXTERN char e_markinval[] INIT(= N_("E19: Mark has invalid line number")); -EXTERN char e_marknotset[] INIT(= N_("E20: Mark not set")); -EXTERN char e_modifiable[] INIT(= N_("E21: Cannot make changes, 'modifiable' is off")); -EXTERN char e_nesting[] INIT(= N_("E22: Scripts nested too deep")); -EXTERN char e_noalt[] INIT(= N_("E23: No alternate file")); -EXTERN char e_noabbr[] INIT(= N_("E24: No such abbreviation")); -EXTERN char e_nobang[] INIT(= N_("E477: No ! allowed")); -EXTERN char e_nogroup[] INIT(= N_("E28: No such highlight group name: %s")); -EXTERN char e_noinstext[] INIT(= N_("E29: No inserted text yet")); -EXTERN char e_nolastcmd[] INIT(= N_("E30: No previous command line")); -EXTERN char e_nomap[] INIT(= N_("E31: No such mapping")); -EXTERN char e_nomatch[] INIT(= N_("E479: No match")); -EXTERN char e_nomatch2[] INIT(= N_("E480: No match: %s")); -EXTERN char e_noname[] INIT(= N_("E32: No file name")); -EXTERN char e_nopresub[] INIT(= N_("E33: No previous substitute regular expression")); -EXTERN char e_noprev[] INIT(= N_("E34: No previous command")); -EXTERN char e_noprevre[] INIT(= N_("E35: No previous regular expression")); -EXTERN char e_norange[] INIT(= N_("E481: No range allowed")); -EXTERN char e_noroom[] INIT(= N_("E36: Not enough room")); -EXTERN char e_notmp[] INIT(= N_("E483: Can't get temp file name")); -EXTERN char e_notopen[] INIT(= N_("E484: Can't open file %s")); -EXTERN char e_notopen_2[] INIT(= N_("E484: Can't open file %s: %s")); -EXTERN char e_notread[] INIT(= N_("E485: Can't read file %s")); -EXTERN char e_null[] INIT(= N_("E38: Null argument")); -EXTERN char e_number_exp[] INIT(= N_("E39: Number expected")); -EXTERN char e_openerrf[] INIT(= N_("E40: Can't open errorfile %s")); -EXTERN char e_outofmem[] INIT(= N_("E41: Out of memory!")); -EXTERN char e_patnotf[] INIT(= N_("Pattern not found")); -EXTERN char e_patnotf2[] INIT(= N_("E486: Pattern not found: %s")); -EXTERN char e_positive[] INIT(= N_("E487: Argument must be positive")); -EXTERN char e_prev_dir[] INIT(= N_("E459: Cannot go back to previous directory")); - -EXTERN char e_no_errors[] INIT(= N_("E42: No Errors")); -EXTERN char e_loclist[] INIT(= N_("E776: No location list")); -EXTERN char e_re_damg[] INIT(= N_("E43: Damaged match string")); -EXTERN char e_re_corr[] INIT(= N_("E44: Corrupted regexp program")); -EXTERN char e_readonly[] INIT(= N_("E45: 'readonly' option is set (add ! to override)")); -EXTERN char e_letwrong[] INIT(= N_("E734: Wrong variable type for %s=")); -EXTERN char e_illvar[] INIT(= N_("E461: Illegal variable name: %s")); -EXTERN char e_cannot_mod[] INIT(= N_("E995: Cannot modify existing variable")); -EXTERN char e_readonlyvar[] INIT(= N_("E46: Cannot change read-only variable \"%.*s\"")); -EXTERN char e_stringreq[] INIT(= N_("E928: String required")); -EXTERN char e_dictreq[] INIT(= N_("E715: Dictionary required")); -EXTERN char e_blobidx[] INIT(= N_("E979: Blob index out of range: %" PRId64)); -EXTERN char e_invalblob[] INIT(= N_("E978: Invalid operation for Blob")); -EXTERN char e_toomanyarg[] INIT(= N_("E118: Too many arguments for function: %s")); -EXTERN char e_dictkey[] INIT(= N_("E716: Key not present in Dictionary: \"%s\"")); -EXTERN char e_listreq[] INIT(= N_("E714: List required")); -EXTERN char e_listblobreq[] INIT(= N_("E897: List or Blob required")); -EXTERN char e_listdictarg[] INIT(= N_("E712: Argument of %s must be a List or Dictionary")); -EXTERN char e_listdictblobarg[] INIT(= N_("E896: Argument of %s must be a List, Dictionary or Blob")); -EXTERN char e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); -EXTERN char e_sandbox[] INIT(= N_("E48: Not allowed in sandbox")); -EXTERN char e_secure[] INIT(= N_("E523: Not allowed here")); -EXTERN char e_textlock[] INIT(= N_("E565: Not allowed to change text or change window")); -EXTERN char e_screenmode[] INIT(= N_("E359: Screen mode setting not supported")); -EXTERN char e_scroll[] INIT(= N_("E49: Invalid scroll size")); -EXTERN char e_shellempty[] INIT(= N_("E91: 'shell' option is empty")); -EXTERN char e_signdata[] INIT(= N_("E255: Couldn't read in sign data!")); -EXTERN char e_swapclose[] INIT(= N_("E72: Close error on swap file")); -EXTERN char e_tagstack[] INIT(= N_("E73: tag stack empty")); -EXTERN char e_toocompl[] INIT(= N_("E74: Command too complex")); -EXTERN char e_longname[] INIT(= N_("E75: Name too long")); -EXTERN char e_toomsbra[] INIT(= N_("E76: Too many [")); -EXTERN char e_toomany[] INIT(= N_("E77: Too many file names")); -EXTERN char e_trailing[] INIT(= N_("E488: Trailing characters")); -EXTERN char e_trailing_arg[] INIT(= N_("E488: Trailing characters: %s")); -EXTERN char e_umark[] INIT(= N_("E78: Unknown mark")); -EXTERN char e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards")); -EXTERN char e_winheight[] INIT(= N_("E591: 'winheight' cannot be smaller than 'winminheight'")); -EXTERN char e_winwidth[] INIT(= N_("E592: 'winwidth' cannot be smaller than 'winminwidth'")); -EXTERN char e_write[] INIT(= N_("E80: Error while writing")); -EXTERN char e_zerocount[] INIT(= N_("E939: Positive count required")); -EXTERN char e_usingsid[] INIT(= N_("E81: Using <SID> not in a script context")); -EXTERN char e_missingparen[] INIT(= N_("E107: Missing parentheses: %s")); -EXTERN char e_maxmempat[] INIT(= N_("E363: pattern uses more memory than 'maxmempattern'")); -EXTERN char e_emptybuf[] INIT(= N_("E749: empty buffer")); -EXTERN char e_nobufnr[] INIT(= N_("E86: Buffer %" PRId64 " does not exist")); - -EXTERN char e_invalpat[] INIT(= N_("E682: Invalid search pattern or delimiter")); -EXTERN char e_bufloaded[] INIT(= N_("E139: File is loaded in another buffer")); -EXTERN char e_notset[] INIT(= N_("E764: Option '%s' is not set")); -EXTERN char e_invalidreg[] INIT(= N_("E850: Invalid register name")); -EXTERN char e_dirnotf[] INIT(= N_("E919: Directory not found in '%s': \"%s\"")); -EXTERN char e_au_recursive[] INIT(= N_("E952: Autocommand caused recursive behavior")); -EXTERN char e_menuothermode[] INIT(= N_("E328: Menu only exists in another mode")); -EXTERN char e_autocmd_close[] INIT(= N_("E813: Cannot close autocmd window")); -EXTERN char e_listarg[] INIT(= N_("E686: Argument of %s must be a List")); -EXTERN char e_unsupportedoption[] INIT(= N_("E519: Option not supported")); -EXTERN char e_fnametoolong[] INIT(= N_("E856: Filename too long")); -EXTERN char e_float_as_string[] INIT(= N_("E806: using Float as a String")); -EXTERN char e_cannot_edit_other_buf[] INIT(= N_("E788: Not allowed to edit another buffer now")); - -EXTERN char e_cmdmap_err[] INIT(= N_("E5520: <Cmd> mapping must end with <CR>")); -EXTERN char e_cmdmap_repeated[] +EXTERN const char e_abort[] INIT(= N_("E470: Command aborted")); +EXTERN const char e_afterinit[] INIT(= N_("E905: Cannot set this option after startup")); +EXTERN const char e_api_spawn_failed[] INIT(= N_("E903: Could not spawn API job")); +EXTERN const char e_argreq[] INIT(= N_("E471: Argument required")); +EXTERN const char e_backslash[] INIT(= N_("E10: \\ should be followed by /, ? or &")); +EXTERN const char e_cmdwin[] INIT(= N_("E11: Invalid in command-line window; <CR> executes, CTRL-C quits")); +EXTERN const char e_curdir[] INIT(= N_("E12: Command not allowed in secure mode in current dir or tag search")); +EXTERN const char e_command_too_recursive[] INIT(= N_("E169: Command too recursive")); +EXTERN const char e_endif[] INIT(= N_("E171: Missing :endif")); +EXTERN const char e_endtry[] INIT(= N_("E600: Missing :endtry")); +EXTERN const char e_endwhile[] INIT(= N_("E170: Missing :endwhile")); +EXTERN const char e_endfor[] INIT(= N_("E170: Missing :endfor")); +EXTERN const char e_while[] INIT(= N_("E588: :endwhile without :while")); +EXTERN const char e_for[] INIT(= N_("E588: :endfor without :for")); +EXTERN const char e_exists[] INIT(= N_("E13: File exists (add ! to override)")); +EXTERN const char e_failed[] INIT(= N_("E472: Command failed")); +EXTERN const char e_internal[] INIT(= N_("E473: Internal error")); +EXTERN const char e_intern2[] INIT(= N_("E685: Internal error: %s")); +EXTERN const char e_interr[] INIT(= N_("Interrupted")); +EXTERN const char e_invarg[] INIT(= N_("E474: Invalid argument")); +EXTERN const char e_invarg2[] INIT(= N_("E475: Invalid argument: %s")); +EXTERN const char e_invargval[] INIT(= N_("E475: Invalid value for argument %s")); +EXTERN const char e_invargNval[] INIT(= N_("E475: Invalid value for argument %s: %s")); +EXTERN const char e_duparg2[] INIT(= N_("E983: Duplicate argument: %s")); +EXTERN const char e_invexpr2[] INIT(= N_("E15: Invalid expression: %s")); +EXTERN const char e_invrange[] INIT(= N_("E16: Invalid range")); +EXTERN const char e_invcmd[] INIT(= N_("E476: Invalid command")); +EXTERN const char e_isadir2[] INIT(= N_("E17: \"%s\" is a directory")); +EXTERN const char e_no_spell[] INIT(= N_("E756: Spell checking is not possible")); +EXTERN const char e_invchan[] INIT(= N_("E900: Invalid channel id")); +EXTERN const char e_invchanjob[] INIT(= N_("E900: Invalid channel id: not a job")); +EXTERN const char e_jobtblfull[] INIT(= N_("E901: Job table is full")); +EXTERN const char e_jobspawn[] INIT(= N_("E903: Process failed to start: %s: \"%s\"")); +EXTERN const char e_channotpty[] INIT(= N_("E904: channel is not a pty")); +EXTERN const char e_stdiochan2[] INIT(= N_("E905: Couldn't open stdio channel: %s")); +EXTERN const char e_invstream[] INIT(= N_("E906: invalid stream for channel")); +EXTERN const char e_invstreamrpc[] INIT(= N_("E906: invalid stream for rpc channel, use 'rpc'")); +EXTERN const char e_streamkey[] INIT(= N_("E5210: dict key '%s' already set for buffered stream in channel %" PRIu64)); +EXTERN const char e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\"")); +EXTERN const char e_fsync[] INIT(= N_("E667: Fsync failed: %s")); +EXTERN const char e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s")); +EXTERN const char e_markinval[] INIT(= N_("E19: Mark has invalid line number")); +EXTERN const char e_marknotset[] INIT(= N_("E20: Mark not set")); +EXTERN const char e_modifiable[] INIT(= N_("E21: Cannot make changes, 'modifiable' is off")); +EXTERN const char e_nesting[] INIT(= N_("E22: Scripts nested too deep")); +EXTERN const char e_noalt[] INIT(= N_("E23: No alternate file")); +EXTERN const char e_noabbr[] INIT(= N_("E24: No such abbreviation")); +EXTERN const char e_nobang[] INIT(= N_("E477: No ! allowed")); +EXTERN const char e_nogroup[] INIT(= N_("E28: No such highlight group name: %s")); +EXTERN const char e_noinstext[] INIT(= N_("E29: No inserted text yet")); +EXTERN const char e_nolastcmd[] INIT(= N_("E30: No previous command line")); +EXTERN const char e_nomap[] INIT(= N_("E31: No such mapping")); +EXTERN const char e_nomatch[] INIT(= N_("E479: No match")); +EXTERN const char e_nomatch2[] INIT(= N_("E480: No match: %s")); +EXTERN const char e_noname[] INIT(= N_("E32: No file name")); +EXTERN const char e_nopresub[] INIT(= N_("E33: No previous substitute regular expression")); +EXTERN const char e_noprev[] INIT(= N_("E34: No previous command")); +EXTERN const char e_noprevre[] INIT(= N_("E35: No previous regular expression")); +EXTERN const char e_norange[] INIT(= N_("E481: No range allowed")); +EXTERN const char e_noroom[] INIT(= N_("E36: Not enough room")); +EXTERN const char e_notmp[] INIT(= N_("E483: Can't get temp file name")); +EXTERN const char e_notopen[] INIT(= N_("E484: Can't open file %s")); +EXTERN const char e_notopen_2[] INIT(= N_("E484: Can't open file %s: %s")); +EXTERN const char e_notread[] INIT(= N_("E485: Can't read file %s")); +EXTERN const char e_null[] INIT(= N_("E38: Null argument")); +EXTERN const char e_number_exp[] INIT(= N_("E39: Number expected")); +EXTERN const char e_openerrf[] INIT(= N_("E40: Can't open errorfile %s")); +EXTERN const char e_outofmem[] INIT(= N_("E41: Out of memory!")); +EXTERN const char e_patnotf[] INIT(= N_("Pattern not found")); +EXTERN const char e_patnotf2[] INIT(= N_("E486: Pattern not found: %s")); +EXTERN const char e_positive[] INIT(= N_("E487: Argument must be positive")); +EXTERN const char e_prev_dir[] INIT(= N_("E459: Cannot go back to previous directory")); + +EXTERN const char e_no_errors[] INIT(= N_("E42: No Errors")); +EXTERN const char e_loclist[] INIT(= N_("E776: No location list")); +EXTERN const char e_re_damg[] INIT(= N_("E43: Damaged match string")); +EXTERN const char e_re_corr[] INIT(= N_("E44: Corrupted regexp program")); +EXTERN const char e_readonly[] INIT(= N_("E45: 'readonly' option is set (add ! to override)")); +EXTERN const char e_letwrong[] INIT(= N_("E734: Wrong variable type for %s=")); +EXTERN const char e_illvar[] INIT(= N_("E461: Illegal variable name: %s")); +EXTERN const char e_cannot_mod[] INIT(= N_("E995: Cannot modify existing variable")); +EXTERN const char e_readonlyvar[] INIT(= N_("E46: Cannot change read-only variable \"%.*s\"")); +EXTERN const char e_stringreq[] INIT(= N_("E928: String required")); +EXTERN const char e_dictreq[] INIT(= N_("E715: Dictionary required")); +EXTERN const char e_blobidx[] INIT(= N_("E979: Blob index out of range: %" PRId64)); +EXTERN const char e_invalblob[] INIT(= N_("E978: Invalid operation for Blob")); +EXTERN const char e_toomanyarg[] INIT(= N_("E118: Too many arguments for function: %s")); +EXTERN const char e_dictkey[] INIT(= N_("E716: Key not present in Dictionary: \"%s\"")); +EXTERN const char e_listreq[] INIT(= N_("E714: List required")); +EXTERN const char e_listblobreq[] INIT(= N_("E897: List or Blob required")); +EXTERN const char e_listdictarg[] INIT(= N_("E712: Argument of %s must be a List or Dictionary")); +EXTERN const char e_listdictblobarg[] INIT(= N_("E896: Argument of %s must be a List, Dictionary or Blob")); +EXTERN const char e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); +EXTERN const char e_sandbox[] INIT(= N_("E48: Not allowed in sandbox")); +EXTERN const char e_secure[] INIT(= N_("E523: Not allowed here")); +EXTERN const char e_textlock[] INIT(= N_("E565: Not allowed to change text or change window")); +EXTERN const char e_screenmode[] INIT(= N_("E359: Screen mode setting not supported")); +EXTERN const char e_scroll[] INIT(= N_("E49: Invalid scroll size")); +EXTERN const char e_shellempty[] INIT(= N_("E91: 'shell' option is empty")); +EXTERN const char e_signdata[] INIT(= N_("E255: Couldn't read in sign data!")); +EXTERN const char e_swapclose[] INIT(= N_("E72: Close error on swap file")); +EXTERN const char e_tagstack[] INIT(= N_("E73: tag stack empty")); +EXTERN const char e_toocompl[] INIT(= N_("E74: Command too complex")); +EXTERN const char e_longname[] INIT(= N_("E75: Name too long")); +EXTERN const char e_toomsbra[] INIT(= N_("E76: Too many [")); +EXTERN const char e_toomany[] INIT(= N_("E77: Too many file names")); +EXTERN const char e_trailing[] INIT(= N_("E488: Trailing characters")); +EXTERN const char e_trailing_arg[] INIT(= N_("E488: Trailing characters: %s")); +EXTERN const char e_umark[] INIT(= N_("E78: Unknown mark")); +EXTERN const char e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards")); +EXTERN const char e_winheight[] INIT(= N_("E591: 'winheight' cannot be smaller than 'winminheight'")); +EXTERN const char e_winwidth[] INIT(= N_("E592: 'winwidth' cannot be smaller than 'winminwidth'")); +EXTERN const char e_write[] INIT(= N_("E80: Error while writing")); +EXTERN const char e_zerocount[] INIT(= N_("E939: Positive count required")); +EXTERN const char e_usingsid[] INIT(= N_("E81: Using <SID> not in a script context")); +EXTERN const char e_missingparen[] INIT(= N_("E107: Missing parentheses: %s")); +EXTERN const char e_maxmempat[] INIT(= N_("E363: pattern uses more memory than 'maxmempattern'")); +EXTERN const char e_emptybuf[] INIT(= N_("E749: empty buffer")); +EXTERN const char e_nobufnr[] INIT(= N_("E86: Buffer %" PRId64 " does not exist")); + +EXTERN const char e_invalpat[] INIT(= N_("E682: Invalid search pattern or delimiter")); +EXTERN const char e_bufloaded[] INIT(= N_("E139: File is loaded in another buffer")); +EXTERN const char e_notset[] INIT(= N_("E764: Option '%s' is not set")); +EXTERN const char e_invalidreg[] INIT(= N_("E850: Invalid register name")); +EXTERN const char e_dirnotf[] INIT(= N_("E919: Directory not found in '%s': \"%s\"")); +EXTERN const char e_au_recursive[] INIT(= N_("E952: Autocommand caused recursive behavior")); +EXTERN const char e_menuothermode[] INIT(= N_("E328: Menu only exists in another mode")); +EXTERN const char e_autocmd_close[] INIT(= N_("E813: Cannot close autocmd window")); +EXTERN const char e_listarg[] INIT(= N_("E686: Argument of %s must be a List")); +EXTERN const char e_unsupportedoption[] INIT(= N_("E519: Option not supported")); +EXTERN const char e_fnametoolong[] INIT(= N_("E856: Filename too long")); +EXTERN const char e_float_as_string[] INIT(= N_("E806: using Float as a String")); +EXTERN const char e_cannot_edit_other_buf[] INIT(= N_("E788: Not allowed to edit another buffer now")); + +EXTERN const char e_cmdmap_err[] INIT(= N_("E5520: <Cmd> mapping must end with <CR>")); +EXTERN const char e_cmdmap_repeated[] INIT(= N_("E5521: <Cmd> mapping must end with <CR> before second <Cmd>")); -EXTERN char e_api_error[] INIT(= N_("E5555: API call: %s")); +EXTERN const char e_api_error[] INIT(= N_("E5555: API call: %s")); -EXTERN char e_luv_api_disabled[] INIT(= N_("E5560: %s must not be called in a lua loop callback")); +EXTERN const char e_luv_api_disabled[] INIT(= N_("E5560: %s must not be called in a lua loop callback")); -EXTERN char e_floatonly[] INIT(= N_("E5601: Cannot close window, only floating window would remain")); -EXTERN char e_floatexchange[] INIT(= N_("E5602: Cannot exchange or rotate float")); +EXTERN const char e_floatonly[] INIT(= N_("E5601: Cannot close window, only floating window would remain")); +EXTERN const char e_floatexchange[] INIT(= N_("E5602: Cannot exchange or rotate float")); -EXTERN char e_cannot_define_autocommands_for_all_events[] INIT(= N_("E1155: Cannot define autocommands for ALL events")); +EXTERN const char e_cannot_define_autocommands_for_all_events[] INIT(= N_("E1155: Cannot define autocommands for ALL events")); -EXTERN char e_resulting_text_too_long[] INIT(= N_("E1240: Resulting text too long")); +EXTERN const char e_resulting_text_too_long[] INIT(= N_("E1240: Resulting text too long")); -EXTERN char e_line_number_out_of_range[] INIT(= N_("E1247: Line number out of range")); +EXTERN const char e_line_number_out_of_range[] INIT(= N_("E1247: Line number out of range")); -EXTERN char e_highlight_group_name_invalid_char[] INIT(= N_("E5248: Invalid character in group name")); +EXTERN const char e_highlight_group_name_invalid_char[] INIT(= N_("E5248: Invalid character in group name")); -EXTERN char e_highlight_group_name_too_long[] INIT(= N_("E1249: Highlight group name too long")); +EXTERN const char e_highlight_group_name_too_long[] INIT(= N_("E1249: Highlight group name too long")); -EXTERN char e_invalid_line_number_nr[] INIT(= N_("E966: Invalid line number: %ld")); +EXTERN const char e_invalid_line_number_nr[] INIT(= N_("E966: Invalid line number: %ld")); -EXTERN char e_undobang_cannot_redo_or_move_branch[] +EXTERN const char e_undobang_cannot_redo_or_move_branch[] INIT(= N_("E5767: Cannot use :undo! to redo or move to a different undo branch")); -EXTERN char e_trustfile[] INIT(= N_("E5570: Cannot update trust file: %s")); +EXTERN const char e_trustfile[] INIT(= N_("E5570: Cannot update trust file: %s")); -EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM")); -EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP")); +EXTERN const char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM")); +EXTERN const char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP")); -EXTERN char line_msg[] INIT(= N_(" line ")); +EXTERN const char line_msg[] INIT(= N_(" line ")); EXTERN FILE *time_fd INIT(= NULL); // where to write startup timing diff --git a/src/nvim/grid.c b/src/nvim/grid.c index 3c4b1e9d70..7745daf69a 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -657,22 +657,22 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy, bool valid) { int new_row; - ScreenGrid new = *grid; + ScreenGrid ngrid = *grid; assert(rows >= 0 && columns >= 0); size_t ncells = (size_t)rows * (size_t)columns; - new.chars = xmalloc(ncells * sizeof(schar_T)); - new.attrs = xmalloc(ncells * sizeof(sattr_T)); - new.line_offset = xmalloc((size_t)rows * sizeof(*new.line_offset)); - new.line_wraps = xmalloc((size_t)rows * sizeof(*new.line_wraps)); + ngrid.chars = xmalloc(ncells * sizeof(schar_T)); + ngrid.attrs = xmalloc(ncells * sizeof(sattr_T)); + ngrid.line_offset = xmalloc((size_t)rows * sizeof(*ngrid.line_offset)); + ngrid.line_wraps = xmalloc((size_t)rows * sizeof(*ngrid.line_wraps)); - new.rows = rows; - new.cols = columns; + ngrid.rows = rows; + ngrid.cols = columns; - for (new_row = 0; new_row < new.rows; new_row++) { - new.line_offset[new_row] = (size_t)new_row * (size_t)new.cols; - new.line_wraps[new_row] = false; + for (new_row = 0; new_row < ngrid.rows; new_row++) { + ngrid.line_offset[new_row] = (size_t)new_row * (size_t)ngrid.cols; + ngrid.line_wraps[new_row] = false; - grid_clear_line(&new, new.line_offset[new_row], columns, valid); + grid_clear_line(&ngrid, ngrid.line_offset[new_row], columns, valid); if (copy) { // If the screen is not going to be cleared, copy as much as @@ -680,18 +680,18 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy, bool valid) // (used when resizing the window at the "--more--" prompt or when // executing an external command, for the GUI). if (new_row < grid->rows && grid->chars != NULL) { - int len = MIN(grid->cols, new.cols); - memmove(new.chars + new.line_offset[new_row], + int len = MIN(grid->cols, ngrid.cols); + memmove(ngrid.chars + ngrid.line_offset[new_row], grid->chars + grid->line_offset[new_row], (size_t)len * sizeof(schar_T)); - memmove(new.attrs + new.line_offset[new_row], + memmove(ngrid.attrs + ngrid.line_offset[new_row], grid->attrs + grid->line_offset[new_row], (size_t)len * sizeof(sattr_T)); } } } grid_free(grid); - *grid = new; + *grid = ngrid; // Share a single scratch buffer for all grids, by // ensuring it is as wide as the widest grid. diff --git a/src/nvim/help.c b/src/nvim/help.c index 728c890da4..633e9df244 100644 --- a/src/nvim/help.c +++ b/src/nvim/help.c @@ -976,7 +976,7 @@ static void helptags_one(char *dir, const char *ext, const char *tagfname, bool } p1 = vim_strchr(IObuff, '*'); // find first '*' while (p1 != NULL) { - p2 = strchr((const char *)p1 + 1, '*'); // Find second '*'. + p2 = strchr(p1 + 1, '*'); // Find second '*'. if (p2 != NULL && p2 > p1 + 1) { // Skip "*" and "**". for (s = p1 + 1; s < p2; s++) { if (*s == ' ' || *s == '\t' || *s == '|') { @@ -1154,7 +1154,7 @@ static void do_helptags(char *dirname, bool add_help_tags, bool ignore_writeerr) ext[1] = fname[5]; ext[2] = fname[6]; } - helptags_one(dirname, (char *)ext, (char *)fname, add_help_tags, ignore_writeerr); + helptags_one(dirname, ext, fname, add_help_tags, ignore_writeerr); } ga_clear(&ga); diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 36da057ddc..e2f3e2aafa 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -11,6 +11,7 @@ #include "klib/kvec.h" #include "lauxlib.h" #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/ui.h" @@ -303,7 +304,7 @@ int hl_get_ui_attr(int ns_id, int idx, int final_id, bool optional) bool available = false; if (final_id > 0) { - int syn_attr = syn_ns_id2attr(ns_id, final_id, optional); + int syn_attr = syn_ns_id2attr(ns_id, final_id, &optional); if (syn_attr > 0) { attrs = syn_attr2entry(syn_attr); available = true; diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h index 4da7dd65bb..5a4a90035c 100644 --- a/src/nvim/highlight.h +++ b/src/nvim/highlight.h @@ -3,6 +3,7 @@ #include <stdbool.h> +#include "nvim/api/keysets.h" #include "nvim/api/private/defs.h" #include "nvim/buffer_defs.h" #include "nvim/highlight_defs.h" diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h index a5586659c7..f690b57148 100644 --- a/src/nvim/highlight_defs.h +++ b/src/nvim/highlight_defs.h @@ -247,8 +247,8 @@ typedef struct { /// highlight attributes with associated priorities typedef struct { - int attr_id; + int hl_id; int priority; -} HlPriAttr; +} HlPriId; #endif // NVIM_HIGHLIGHT_DEFS_H diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index cce124de77..6493408a58 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -278,6 +278,7 @@ static const char *highlight_init_both[] = { // LSP semantic tokens "default link @lsp.type.class Structure", + "default link @lsp.type.comment Comment", "default link @lsp.type.decorator Function", "default link @lsp.type.enum Structure", "default link @lsp.type.enumMember Constant", @@ -894,15 +895,15 @@ void do_highlight(const char *line, const bool forceit, const bool init) bool dodefault = false; // Isolate the name. - const char *name_end = (const char *)skiptowhite(line); - const char *linep = (const char *)skipwhite(name_end); + const char *name_end = skiptowhite(line); + const char *linep = skipwhite(name_end); // Check for "default" argument. if (strncmp(line, "default", (size_t)(name_end - line)) == 0) { dodefault = true; line = linep; - name_end = (const char *)skiptowhite(line); - linep = (const char *)skipwhite(name_end); + name_end = skiptowhite(line); + linep = skipwhite(name_end); } bool doclear = false; @@ -936,9 +937,9 @@ void do_highlight(const char *line, const bool forceit, const bool init) int to_id; HlGroup *hlgroup = NULL; - from_end = (const char *)skiptowhite(from_start); - to_start = (const char *)skipwhite(from_end); - to_end = (const char *)skiptowhite(to_start); + from_end = skiptowhite(from_start); + to_start = skipwhite(from_end); + to_end = skiptowhite(to_start); if (ends_excmd((uint8_t)(*from_start)) || ends_excmd((uint8_t)(*to_start))) { @@ -1002,7 +1003,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) // ":highlight clear [group]" command. line = linep; if (ends_excmd((uint8_t)(*line))) { - do_unlet(S_LEN("colors_name"), true); + do_unlet(S_LEN("g:colors_name"), true); restore_cterm_colors(); // Clear all default highlight groups and load the defaults. @@ -1014,8 +1015,8 @@ void do_highlight(const char *line, const bool forceit, const bool init) redraw_all_later(UPD_NOT_VALID); return; } - name_end = (const char *)skiptowhite(line); - linep = (const char *)skipwhite(name_end); + name_end = skiptowhite(line); + linep = skipwhite(name_end); } // Find the group name in the table. If it does not exist yet, add it. @@ -1072,7 +1073,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) memcpy(key, key_start, key_len); key[key_len] = NUL; vim_strup(key); - linep = (const char *)skipwhite(linep); + linep = skipwhite(linep); if (strcmp(key, "NONE") == 0) { if (!init || hl_table[idx].sg_set == 0) { @@ -1093,7 +1094,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) linep++; // Isolate the argument. - linep = (const char *)skipwhite(linep); + linep = skipwhite(linep); if (*linep == '\'') { // guifg='color name' arg_start = ++linep; linep = strchr(linep, '\''); @@ -1104,7 +1105,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) } } else { arg_start = linep; - linep = (const char *)skiptowhite(linep); + linep = skiptowhite(linep); } if (linep == arg_start) { semsg(_("E417: missing argument: %s"), key_start); @@ -1360,7 +1361,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) } // Continue with next argument. - linep = (const char *)skipwhite(linep); + linep = skipwhite(linep); } } @@ -1638,7 +1639,7 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg msg_puts_attr(name, HL_ATTR(HLF_D)); msg_puts_attr("=", HL_ATTR(HLF_D)); } - msg_outtrans((char *)ts); + msg_outtrans(ts); } return didh; } @@ -1987,18 +1988,23 @@ static int syn_add_group(const char *name, size_t len) /// @see syn_attr2entry int syn_id2attr(int hl_id) { - return syn_ns_id2attr(-1, hl_id, false); + bool optional = false; + return syn_ns_id2attr(-1, hl_id, &optional); } -int syn_ns_id2attr(int ns_id, int hl_id, bool optional) +int syn_ns_id2attr(int ns_id, int hl_id, bool *optional) + FUNC_ATTR_NONNULL_ALL { - hl_id = syn_ns_get_final_id(&ns_id, hl_id); + if (syn_ns_get_final_id(&ns_id, &hl_id)) { + // If the namespace explicitly defines a group to be empty, it is not optional + *optional = false; + } HlGroup *sgp = &hl_table[hl_id - 1]; // index is ID minus one int attr = ns_get_hl(&ns_id, hl_id, false, sgp->sg_set); // if a highlight group is optional, don't use the global value - if (attr >= 0 || (optional && ns_id > 0)) { + if (attr >= 0 || (*optional && ns_id > 0)) { return attr; } return sgp->sg_attr; @@ -2007,16 +2013,20 @@ int syn_ns_id2attr(int ns_id, int hl_id, bool optional) /// Translate a group ID to the final group ID (following links). int syn_get_final_id(int hl_id) { - int id = curwin->w_ns_hl_active; - return syn_ns_get_final_id(&id, hl_id); + int ns_id = curwin->w_ns_hl_active; + syn_ns_get_final_id(&ns_id, &hl_id); + return hl_id; } -int syn_ns_get_final_id(int *ns_id, int hl_id) +bool syn_ns_get_final_id(int *ns_id, int *hl_idp) { int count; + int hl_id = *hl_idp; + bool used = false; if (hl_id > highlight_ga.ga_len || hl_id < 1) { - return 0; // Can be called from eval!! + *hl_idp = 0; + return false; // Can be called from eval!! } // Follow links until there is no more. @@ -2029,8 +2039,10 @@ int syn_ns_get_final_id(int *ns_id, int hl_id) // syn_id2attr time int check = ns_get_hl(ns_id, hl_id, true, sgp->sg_set); if (check == 0) { - return hl_id; // how dare! it broke the link! + *hl_idp = hl_id; + return true; // how dare! it broke the link! } else if (check > 0) { + used = true; hl_id = check; continue; } @@ -2044,7 +2056,8 @@ int syn_ns_get_final_id(int *ns_id, int hl_id) } } - return hl_id; + *hl_idp = hl_id; + return used; } /// Refresh the color attributes of all highlight groups. @@ -2127,7 +2140,8 @@ void highlight_changed(void) abort(); } int ns_id = -1; - int final_id = syn_ns_get_final_id(&ns_id, id); + int final_id = id; + syn_ns_get_final_id(&ns_id, &final_id); if (hlf == HLF_SNC) { id_SNC = final_id; } else if (hlf == HLF_S) { @@ -2197,7 +2211,7 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg) } // (part of) subcommand already typed - const char *p = (const char *)skiptowhite(arg); + const char *p = skiptowhite(arg); if (*p == NUL) { return; } @@ -2205,9 +2219,9 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg) // past "default" or group name include_default = 0; if (strncmp("default", arg, (unsigned)(p - arg)) == 0) { - arg = (const char *)skipwhite(p); + arg = skipwhite(p); xp->xp_pattern = (char *)arg; - p = (const char *)skiptowhite(arg); + p = skiptowhite(arg); } if (*p == NUL) { return; @@ -2221,10 +2235,10 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg) if (strncmp("link", arg, (unsigned)(p - arg)) == 0 || strncmp("clear", arg, (unsigned)(p - arg)) == 0) { xp->xp_pattern = skipwhite(p); - p = (const char *)skiptowhite(xp->xp_pattern); + p = skiptowhite(xp->xp_pattern); if (*p != NUL) { // past first group name xp->xp_pattern = skipwhite(p); - p = (const char *)skiptowhite(xp->xp_pattern); + p = skiptowhite(xp->xp_pattern); } } if (*p != NUL) { // past group name(s) @@ -2287,7 +2301,7 @@ const char *get_highlight_name_ext(expand_T *xp, int idx, bool skip_cleared) } else if (idx >= highlight_ga.ga_len) { return NULL; } - return (const char *)hl_table[idx].sg_name; + return hl_table[idx].sg_name; } color_name_table_T color_name_table[] = { @@ -2988,7 +3002,7 @@ RgbValue name_to_color(const char *name, int *idx) && isxdigit((uint8_t)name[6]) && name[7] == NUL) { // rgb hex string *idx = kColorIdxHex; - return (RgbValue)strtol((char *)(name + 1), NULL, 16); + return (RgbValue)strtol(name + 1, NULL, 16); } else if (!STRICMP(name, "bg") || !STRICMP(name, "background")) { *idx = kColorIdxBg; return normal_bg; diff --git a/src/nvim/highlight_group.h b/src/nvim/highlight_group.h index bf6bad1a86..77a3684067 100644 --- a/src/nvim/highlight_group.h +++ b/src/nvim/highlight_group.h @@ -1,6 +1,7 @@ #ifndef NVIM_HIGHLIGHT_GROUP_H #define NVIM_HIGHLIGHT_GROUP_H +#include "nvim/api/keysets.h" #include "nvim/api/private/helpers.h" #include "nvim/highlight_defs.h" #include "nvim/types.h" diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 6ad19c6f96..8a65e88545 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -427,7 +427,7 @@ int get_indent_str_vtab(const char *ptr, long ts, long *vts, bool list) } else { // In list mode, when tab is not set, count screen char width // for Tab, displays: ^I - count += ptr2cells((char *)ptr); + count += ptr2cells(ptr); } } else if (*ptr == ' ') { count++; // count a space for one diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 7100146245..800d7e29ca 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -187,8 +187,8 @@ typedef enum { CP_FAST = 32, ///< use fast_breakcheck instead of os_breakcheck } cp_flags_T; -static char e_hitend[] = N_("Hit end of paragraph"); -static char e_compldel[] = N_("E840: Completion function deleted text"); +static const char e_hitend[] = N_("Hit end of paragraph"); +static const char e_compldel[] = N_("E840: Completion function deleted text"); // All the current matches are stored in a list. // "compl_first_match" points to the start of the list. @@ -1067,14 +1067,14 @@ static bool pum_enough_matches(void) { // Don't display the popup menu if there are no matches or there is only // one (ignoring the original text). - compl_T *compl = compl_first_match; + compl_T *comp = compl_first_match; int i = 0; do { - if (compl == NULL || (!match_at_original_text(compl) && ++i == 2)) { + if (comp == NULL || (!match_at_original_text(comp) && ++i == 2)) { break; } - compl = compl->cp_next; - } while (!is_first_match(compl)); + comp = comp->cp_next; + } while (!is_first_match(comp)); if (strstr(p_cot, "menuone") != NULL) { return i >= 1; @@ -1138,7 +1138,7 @@ static int ins_compl_build_pum(void) { // Need to build the popup menu list. compl_match_arraysize = 0; - compl_T *compl = compl_first_match; + compl_T *comp = compl_first_match; // If it's user complete function and refresh_always, // do not use "compl_leader" as prefix filter. @@ -1149,13 +1149,13 @@ static int ins_compl_build_pum(void) const int lead_len = compl_leader != NULL ? (int)strlen(compl_leader) : 0; do { - if (!match_at_original_text(compl) + if (!match_at_original_text(comp) && (compl_leader == NULL - || ins_compl_equal(compl, compl_leader, (size_t)lead_len))) { + || ins_compl_equal(comp, compl_leader, (size_t)lead_len))) { compl_match_arraysize++; } - compl = compl->cp_next; - } while (compl != NULL && !is_first_match(compl)); + comp = comp->cp_next; + } while (comp != NULL && !is_first_match(comp)); if (compl_match_arraysize == 0) { return -1; @@ -1172,46 +1172,46 @@ static int ins_compl_build_pum(void) bool did_find_shown_match = false; int cur = -1; int i = 0; - compl = compl_first_match; + comp = compl_first_match; do { - if (!match_at_original_text(compl) + if (!match_at_original_text(comp) && (compl_leader == NULL - || ins_compl_equal(compl, compl_leader, (size_t)lead_len))) { + || ins_compl_equal(comp, compl_leader, (size_t)lead_len))) { if (!shown_match_ok) { - if (compl == compl_shown_match || did_find_shown_match) { + if (comp == compl_shown_match || did_find_shown_match) { // This item is the shown match or this is the // first displayed item after the shown match. - compl_shown_match = compl; + compl_shown_match = comp; did_find_shown_match = true; shown_match_ok = true; } else { // Remember this displayed match for when the // shown match is just below it. - shown_compl = compl; + shown_compl = comp; } cur = i; } - if (compl->cp_text[CPT_ABBR] != NULL) { - compl_match_array[i].pum_text = compl->cp_text[CPT_ABBR]; + if (comp->cp_text[CPT_ABBR] != NULL) { + compl_match_array[i].pum_text = comp->cp_text[CPT_ABBR]; } else { - compl_match_array[i].pum_text = compl->cp_str; + compl_match_array[i].pum_text = comp->cp_str; } - compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND]; - compl_match_array[i].pum_info = compl->cp_text[CPT_INFO]; - if (compl->cp_text[CPT_MENU] != NULL) { - compl_match_array[i++].pum_extra = compl->cp_text[CPT_MENU]; + compl_match_array[i].pum_kind = comp->cp_text[CPT_KIND]; + compl_match_array[i].pum_info = comp->cp_text[CPT_INFO]; + if (comp->cp_text[CPT_MENU] != NULL) { + compl_match_array[i++].pum_extra = comp->cp_text[CPT_MENU]; } else { - compl_match_array[i++].pum_extra = compl->cp_fname; + compl_match_array[i++].pum_extra = comp->cp_fname; } } - if (compl == compl_shown_match) { + if (comp == compl_shown_match) { did_find_shown_match = true; // When the original text is the shown match don't set // compl_shown_match. - if (match_at_original_text(compl)) { + if (match_at_original_text(comp)) { shown_match_ok = true; } @@ -1222,8 +1222,8 @@ static int ins_compl_build_pum(void) shown_match_ok = true; } } - compl = compl->cp_next; - } while (compl != NULL && !is_first_match(compl)); + comp = comp->cp_next; + } while (comp != NULL && !is_first_match(comp)); if (!shown_match_ok) { // no displayed match at all cur = -1; @@ -1414,7 +1414,7 @@ static int thesaurus_add_words_in_line(char *fname, char **buf_arg, int dir, con // different classes, only separate words // with single-byte non-word characters. while (*ptr != NUL) { - const int l = utfc_ptr2len((const char *)ptr); + const int l = utfc_ptr2len(ptr); if (l < 2 && !vim_iswordc((uint8_t)(*ptr))) { break; @@ -1750,7 +1750,7 @@ void ins_compl_addleader(int c) if ((cc = utf_char2len(c)) > 1) { char buf[MB_MAXBYTES + 1]; - utf_char2bytes(c, (char *)buf); + utf_char2bytes(c, buf); buf[cc] = NUL; ins_char_bytes(buf, (size_t)cc); } else { @@ -2257,7 +2257,7 @@ static void copy_global_to_buflocal_cb(Callback *globcb, Callback *bufcb) /// Invoked when the 'completefunc' option is set. The option value can be a /// name of a function (string), or function(<name>) or funcref(<name>) or a /// lambda expression. -void set_completefunc_option(char **errmsg) +void set_completefunc_option(const char **errmsg) { if (option_set_callback_func(curbuf->b_p_cfu, &cfu_cb) == FAIL) { *errmsg = e_invarg; @@ -2278,7 +2278,7 @@ void set_buflocal_cfu_callback(buf_T *buf) /// Invoked when the 'omnifunc' option is set. The option value can be a /// name of a function (string), or function(<name>) or funcref(<name>) or a /// lambda expression. -void set_omnifunc_option(buf_T *buf, char **errmsg) +void set_omnifunc_option(buf_T *buf, const char **errmsg) { if (option_set_callback_func(buf->b_p_ofu, &ofu_cb) == FAIL) { *errmsg = e_invarg; @@ -2298,7 +2298,7 @@ void set_buflocal_ofu_callback(buf_T *buf) /// Invoked when the 'thesaurusfunc' option is set. The option value can be a /// name of a function (string), or function(<name>) or funcref(<name>) or a /// lambda expression. -void set_thesaurusfunc_option(char **errmsg) +void set_thesaurusfunc_option(const char **errmsg) { int retval; @@ -2515,7 +2515,7 @@ static void ins_compl_add_dict(dict_T *dict) compl_opt_refresh_always = false; di_refresh = tv_dict_find(dict, S_LEN("refresh")); if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING) { - const char *v = (const char *)di_refresh->di_tv.vval.v_string; + const char *v = di_refresh->di_tv.vval.v_string; if (v != NULL && strcmp(v, "always") == 0) { compl_opt_refresh_always = true; @@ -4301,7 +4301,7 @@ static void ins_compl_show_statusmsg(void) if (edit_submode_extra != NULL) { if (!p_smd) { msg_hist_off = true; - msg_attr((const char *)edit_submode_extra, + msg_attr(edit_submode_extra, (edit_submode_highl < HLF_COUNT ? HL_ATTR(edit_submode_highl) : 0)); msg_hist_off = false; diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index 8eec9014f7..abf31ae344 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -905,19 +905,6 @@ char *replace_termcodes(const char *const from, const size_t from_len, char **co src = from; - // Check for #n at start only: function key n - if ((flags & REPTERM_FROM_PART) && from_len > 1 && src[0] == '#' - && ascii_isdigit(src[1])) { // function key - result[dlen++] = (char)K_SPECIAL; - result[dlen++] = 'k'; - if (src[1] == '0') { - result[dlen++] = ';'; // #0 is F10 is "k;" - } else { - result[dlen++] = src[1]; // #3 is F3 is "k3" - } - src += 2; - } - // Copy each byte from *from to result[dlen] while (src <= end) { if (!allocated && dlen + 64 > buf_len) { @@ -1002,7 +989,7 @@ char *replace_termcodes(const char *const from, const size_t from_len, char **co } // skip multibyte char correctly - for (i = utfc_ptr2len_len((char *)src, (int)(end - src) + 1); i > 0; i--) { + for (i = utfc_ptr2len_len(src, (int)(end - src) + 1); i > 0; i--) { // If the character is K_SPECIAL, replace it with K_SPECIAL // KS_SPECIAL KE_FILLER. if (*src == (char)K_SPECIAL) { diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 6160b84485..9ff03bc67d 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -459,7 +459,7 @@ static bool typval_conv_special = false; TYPVAL_ENCODE_CONV_NUMBER(tv, flt) #define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \ - lua_pushlstring(lstate, (const char *)(str), (len)) + lua_pushlstring(lstate, (str), (len)) #define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING @@ -469,9 +469,7 @@ static bool typval_conv_special = false; #define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ do { \ const blob_T *const blob_ = (blob); \ - lua_pushlstring(lstate, \ - blob_ != NULL ? (const char *)blob_->bv_ga.ga_data : "", \ - (size_t)(len)); \ + lua_pushlstring(lstate, blob_ != NULL ? blob_->bv_ga.ga_data : "", (size_t)(len)); \ } while (0) #define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \ diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index b5dd7a3e78..3646fd876b 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1105,7 +1105,7 @@ static int nlua_debug(lua_State *lstate) tv_clear(&input); return 0; } - if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string, + if (luaL_loadbuffer(lstate, input.vval.v_string, strlen(input.vval.v_string), "=(debug command)")) { nlua_error(lstate, _("E5115: Error while loading debug string: %.*s")); } else if (nlua_pcall(lstate, 0, 0)) { @@ -1172,7 +1172,7 @@ int nlua_call(lua_State *lstate) TRY_WRAP(&err, { // call_func() retval is deceptive, ignore it. Instead we set `msg_list` // (TRY_WRAP) to capture abort-causing non-exception errors. - (void)call_func((char *)name, (int)name_len, &rettv, nargs, vim_args, &funcexe); + (void)call_func(name, (int)name_len, &rettv, nargs, vim_args, &funcexe); }); if (!ERROR_SET(&err)) { @@ -1652,7 +1652,7 @@ void ex_luado(exarg_T *const eap) emsg(_("cannot save undo information")); return; } - const char *const cmd = (const char *)eap->arg; + const char *const cmd = eap->arg; const size_t cmd_len = strlen(cmd); lua_State *const lstate = global_lstate; @@ -1693,7 +1693,7 @@ void ex_luado(exarg_T *const eap) break; } lua_pushvalue(lstate, -1); - const char *const old_line = (const char *)ml_get_buf(curbuf, l, false); + const char *const old_line = ml_get_buf(curbuf, l, false); // Get length of old_line here as calling Lua code may free it. const size_t old_line_len = strlen(old_line); lua_pushstring(lstate, old_line); @@ -1729,7 +1729,7 @@ void ex_luado(exarg_T *const eap) void ex_luafile(exarg_T *const eap) FUNC_ATTR_NONNULL_ALL { - nlua_exec_file((const char *)eap->arg); + nlua_exec_file(eap->arg); } /// Executes Lua code from a file or "-" (stdin). @@ -1860,7 +1860,7 @@ int nlua_expand_pat(expand_T *xp, char *pat, int *num_results, char ***results) luaL_checktype(lstate, -1, LUA_TFUNCTION); // [ vim, vim._expand_pat, buf ] - lua_pushlstring(lstate, (const char *)pat, strlen(pat)); + lua_pushlstring(lstate, pat, strlen(pat)); if (nlua_pcall(lstate, 1, 2) != 0) { nlua_error(lstate, @@ -2092,7 +2092,7 @@ int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview) lua_setfield(lstate, -2, "line2"); lua_newtable(lstate); // f-args table - lua_pushstring(lstate, (const char *)eap->arg); + lua_pushstring(lstate, eap->arg); lua_pushvalue(lstate, -1); // Reference for potential use on f-args lua_setfield(lstate, -4, "args"); diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 289a0cb9b4..ae3a7b6d75 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -64,6 +64,7 @@ static struct luaL_Reg tree_meta[] = { { "__tostring", tree_tostring }, { "root", tree_root }, { "edit", tree_edit }, + { "included_ranges", tree_get_ranges }, { "copy", tree_copy }, { NULL, NULL } }; @@ -512,6 +513,24 @@ static int tree_edit(lua_State *L) return 0; } +static int tree_get_ranges(lua_State *L) +{ + TSTree **tree = tree_check(L, 1); + if (!(*tree)) { + return 0; + } + + bool include_bytes = (lua_gettop(L) >= 2) && lua_toboolean(L, 2); + + uint32_t len; + TSRange *ranges = ts_tree_included_ranges(*tree, &len); + + push_ranges(L, ranges, len, include_bytes); + + xfree(ranges); + return 1; +} + // Use the top of the stack (without popping it) to create a TSRange, it can be // either a lua table or a TSNode static void range_from_lua(lua_State *L, TSRange *range) diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c index 9a7ae5c146..e0bbdb8942 100644 --- a/src/nvim/lua/xdiff.c +++ b/src/nvim/lua/xdiff.c @@ -32,7 +32,7 @@ typedef struct { Error *err; mmfile_t *ma; mmfile_t *mb; - bool linematch; + int64_t linematch; bool iwhite; } hunkpriv_t; @@ -128,7 +128,7 @@ static int hunk_locations_cb(long start_a, long count_a, long start_b, long coun { hunkpriv_t *priv = (hunkpriv_t *)cb_data; lua_State *lstate = priv->lstate; - if (priv->linematch) { + if (priv->linematch > 0 && count_a + count_b <= priv->linematch) { get_linematch_results(lstate, priv->ma, priv->mb, start_a, count_a, start_b, count_b, priv->iwhite); } else { @@ -208,7 +208,7 @@ static bool check_xdiff_opt(ObjectType actType, ObjectType expType, const char * } static NluaXdiffMode process_xdl_diff_opts(lua_State *lstate, xdemitconf_t *cfg, xpparam_t *params, - bool *linematch, Error *err) + int64_t *linematch, Error *err) { const DictionaryOf(LuaRef) opts = nlua_pop_Dictionary(lstate, true, err); @@ -265,8 +265,12 @@ static NluaXdiffMode process_xdl_diff_opts(lua_State *lstate, xdemitconf_t *cfg, } 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)) { + if (v->type == kObjectTypeBoolean) { + *linematch = v->data.boolean ? INT64_MAX : 0; + } else if (v->type == kObjectTypeInteger) { + *linematch = v->data.integer; + } else { + api_set_error(err, kErrorTypeValidation, "linematch must be a boolean or integer"); goto exit_1; } } else { @@ -330,7 +334,7 @@ int nlua_xdl_diff(lua_State *lstate) xdemitconf_t cfg; xpparam_t params; xdemitcb_t ecb; - bool linematch = false; + int64_t linematch = 0; CLEAR_FIELD(cfg); CLEAR_FIELD(params); diff --git a/src/nvim/main.c b/src/nvim/main.c index 1f16ecff76..0ef1fc9391 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -2122,7 +2122,7 @@ static int execute_env(char *env) current_sctx.sc_sid = SID_ENV; current_sctx.sc_seq = 0; current_sctx.sc_lnum = 0; - do_cmdline_cmd((char *)initstr); + do_cmdline_cmd(initstr); estack_pop(); current_sctx = save_current_sctx; diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 2941d5965b..19a2aca75e 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -422,7 +422,7 @@ static int str_to_mapargs(const char *strargs, bool is_unmap, MapArguments *mapa // {lhs_end} is a pointer to the "terminating whitespace" after {lhs}. // Use that to initialize {rhs_start}. - const char *rhs_start = skipwhite((char *)lhs_end); + const char *rhs_start = skipwhite(lhs_end); // Given {lhs} might be larger than MAXMAPLEN before replace_termcodes // (e.g. "<Space>" is longer than ' '), so first copy into a buffer. @@ -449,7 +449,7 @@ static int str_to_mapargs(const char *strargs, bool is_unmap, MapArguments *mapa /// @param args "rhs", "rhs_lua", "orig_rhs", "expr", "silent", "nowait", "replace_keycodes" and /// and "desc" fields are used. /// "rhs", "rhs_lua", "orig_rhs" fields are cleared if "simplified" is false. -/// @param sid -1 to use current_sctx +/// @param sid 0 to use current_sctx static void map_add(buf_T *buf, mapblock_T **map_table, mapblock_T **abbr_table, const char *keys, MapArguments *args, int noremap, int mode, bool is_abbr, scid_T sid, linenr_T lnum, bool simplified) @@ -482,7 +482,7 @@ static void map_add(buf_T *buf, mapblock_T **map_table, mapblock_T **abbr_table, mp->m_simplified = simplified; mp->m_expr = args->expr; mp->m_replace_keycodes = args->replace_keycodes; - if (sid >= 0) { + if (sid != 0) { mp->m_script_ctx.sc_sid = sid; mp->m_script_ctx.sc_lnum = lnum; } else { @@ -594,15 +594,15 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, const int first = vim_iswordp(lhs); int last = first; - p = (char *)lhs + utfc_ptr2len((char *)lhs); + p = lhs + utfc_ptr2len(lhs); n = 1; - while (p < (char *)lhs + len) { + while (p < lhs + len) { n++; // nr of (multi-byte) chars last = vim_iswordp(p); // type of last char if (same == -1 && last != first) { same = n - 1; // count of same char type } - p += utfc_ptr2len((char *)p); + p += utfc_ptr2len(p); } if (last && n > 2 && same >= 0 && same < n - 1) { retval = 1; @@ -733,8 +733,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, // we ignore trailing space when matching with // the "lhs", since an abbreviation can't have // trailing space. - if (n != len && (!is_abbrev || round || n > len - || *skipwhite((char *)lhs + n) != NUL)) { + if (n != len && (!is_abbrev || round || n > len || *skipwhite(lhs + n) != NUL)) { mpp = &(mp->m_next); continue; } @@ -857,9 +856,9 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, } // Get here when adding a new entry to the maphash[] list or abbrlist. - map_add(buf, map_table, abbr_table, (char *)lhs, args, noremap, mode, is_abbrev, - -1, // sid - 0, // lnum + map_add(buf, map_table, abbr_table, lhs, args, noremap, mode, is_abbrev, + 0, // sid + 0, // lnum keyround1_simplified); } @@ -1501,7 +1500,7 @@ bool check_abbr(int c, char *ptr, int col, int mincol) char *q = mp->m_keys; int match; - if (strchr((const char *)mp->m_keys, K_SPECIAL) != NULL) { + if (strchr(mp->m_keys, K_SPECIAL) != NULL) { // Might have K_SPECIAL escaped mp->m_keys. q = xstrdup(mp->m_keys); vim_unescape_ks(q); @@ -1811,8 +1810,7 @@ int makemap(FILE *fd, buf_T *buf) did_cpo = true; } else { const char specials[] = { (char)(uint8_t)K_SPECIAL, NL, NUL }; - if (strpbrk((const char *)mp->m_str, specials) != NULL - || strpbrk((const char *)mp->m_keys, specials) != NULL) { + if (strpbrk(mp->m_str, specials) != NULL || strpbrk(mp->m_keys, specials) != NULL) { did_cpo = true; } } @@ -2091,7 +2089,7 @@ static Dictionary mapblock_fill_dict(const mapblock_T *const mp, const char *lhs PUT(dict, "desc", STRING_OBJ(cstr_to_string(mp->m_desc))); } PUT(dict, "lhs", STRING_OBJ(cstr_as_string(lhs))); - PUT(dict, "lhsraw", STRING_OBJ(cstr_to_string((const char *)mp->m_keys))); + PUT(dict, "lhsraw", STRING_OBJ(cstr_to_string(mp->m_keys))); if (lhsrawalt != NULL) { // Also add the value for the simplified entry. PUT(dict, "lhsrawalt", STRING_OBJ(cstr_to_string(lhsrawalt))); @@ -2646,10 +2644,10 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod case 0: break; case 1: - api_set_error(err, kErrorTypeException, (char *)e_invarg, 0); + api_set_error(err, kErrorTypeException, e_invarg, 0); goto fail_and_free; case 2: - api_set_error(err, kErrorTypeException, (char *)e_nomap, 0); + api_set_error(err, kErrorTypeException, e_nomap, 0); goto fail_and_free; case 5: api_set_error(err, kErrorTypeException, diff --git a/src/nvim/mapping.h b/src/nvim/mapping.h index 58e28810bc..ff6c30c4c9 100644 --- a/src/nvim/mapping.h +++ b/src/nvim/mapping.h @@ -5,6 +5,7 @@ #include <stddef.h> #include "lauxlib.h" +#include "nvim/api/keysets.h" #include "nvim/buffer_defs.h" #include "nvim/ex_cmds_defs.h" #include "nvim/types.h" diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index 7e900bafa2..f1285b39e7 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -1216,7 +1216,7 @@ void mt_inspect_node(MarkTree *b, garray_T *ga, mtnode_t *n, mtpos_t off) for (int i = 0; i < n->n; i++) { mtpos_t p = n->key[i].pos; unrelative(off, &p); - snprintf((char *)buf, sizeof(buf), "%d/%d", p.row, p.col); + snprintf(buf, sizeof(buf), "%d/%d", p.row, p.col); ga_concat(ga, buf); if (n->level) { mt_inspect_node(b, ga, n->ptr[i + 1], p); diff --git a/src/nvim/match.c b/src/nvim/match.c index 29d4b7c225..31a628bbff 100644 --- a/src/nvim/match.c +++ b/src/nvim/match.c @@ -42,7 +42,7 @@ # include "match.c.generated.h" #endif -static char *e_invalwindow = N_("E957: Invalid window number"); +static const char *e_invalwindow = N_("E957: Invalid window number"); #define SEARCH_HL_PRIORITY 0 @@ -938,10 +938,9 @@ void f_getmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) tv_dict_add_list(dict, buf, (size_t)len, l); } } else { - tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cur->mit_pattern); + tv_dict_add_str(dict, S_LEN("pattern"), cur->mit_pattern); } - tv_dict_add_str(dict, S_LEN("group"), - (const char *)syn_id2name(cur->mit_hlg_id)); + tv_dict_add_str(dict, S_LEN("group"), syn_id2name(cur->mit_hlg_id)); tv_dict_add_nr(dict, S_LEN("priority"), (varnumber_T)cur->mit_priority); tv_dict_add_nr(dict, S_LEN("id"), (varnumber_T)cur->mit_id); @@ -1166,9 +1165,8 @@ void f_matcharg(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) matchitem_T *const m = get_match(curwin, id); if (m != NULL) { - tv_list_append_string(rettv->vval.v_list, - (const char *)syn_id2name(m->mit_hlg_id), -1); - tv_list_append_string(rettv->vval.v_list, (const char *)m->mit_pattern, -1); + tv_list_append_string(rettv->vval.v_list, syn_id2name(m->mit_hlg_id), -1); + tv_list_append_string(rettv->vval.v_list, m->mit_pattern, -1); } else { tv_list_append_string(rettv->vval.v_list, NULL, 0); tv_list_append_string(rettv->vval.v_list, NULL, 0); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index c580dc29e6..ab787524a9 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -87,17 +87,17 @@ struct interval { #endif // uncrustify:on -static char e_list_item_nr_is_not_list[] +static const char e_list_item_nr_is_not_list[] = N_("E1109: List item %d is not a List"); -static char e_list_item_nr_does_not_contain_3_numbers[] +static const char e_list_item_nr_does_not_contain_3_numbers[] = N_("E1110: List item %d does not contain 3 numbers"); -static char e_list_item_nr_range_invalid[] +static const char e_list_item_nr_range_invalid[] = N_("E1111: List item %d range invalid"); -static char e_list_item_nr_cell_width_invalid[] +static const char e_list_item_nr_cell_width_invalid[] = N_("E1112: List item %d cell width invalid"); -static char e_overlapping_ranges_for_nr[] +static const char e_overlapping_ranges_for_nr[] = N_("E1113: Overlapping ranges for 0x%lx"); -static char e_only_values_of_0x80_and_higher_supported[] +static const char e_only_values_of_0x80_and_higher_supported[] = N_("E1114: Only values of 0x80 and higher supported"); // To speed up BYTELEN(); keep a lookup table to quickly get the length in @@ -367,7 +367,7 @@ static int enc_canon_search(const char *name) int enc_canon_props(const char *name) FUNC_ATTR_PURE { - int i = enc_canon_search((char *)name); + int i = enc_canon_search(name); if (i >= 0) { return enc_canon_table[i].prop; } else if (strncmp(name, "2byte-", 6) == 0) { @@ -538,9 +538,9 @@ int utf_ptr2cells_len(const char *p, int size) if (utf_ptr2len_len(p, size) < utf8len_tab[(uint8_t)(*p)]) { return 1; // truncated } - int c = utf_ptr2char((char *)p); + int c = utf_ptr2char(p); // An illegal byte is displayed as <xx>. - if (utf_ptr2len((char *)p) == 1 || c == NUL) { + if (utf_ptr2len(p) == 1 || c == NUL) { return 4; } // If the char is ASCII it must be an overlong sequence. @@ -719,14 +719,14 @@ bool utf_composinglike(const char *p1, const char *p2) { int c2; - c2 = utf_ptr2char((char *)p2); + c2 = utf_ptr2char(p2); if (utf_iscomposing(c2)) { return true; } if (!arabic_maycombine(c2)) { return false; } - return arabic_combine(utf_ptr2char((char *)p1), c2); + return arabic_combine(utf_ptr2char(p1), c2); } /// Convert a UTF-8 string to a wide character @@ -1053,7 +1053,7 @@ int utf_class_tab(const int c, const uint64_t *const chartab) static struct clinterval { unsigned int first; unsigned int last; - unsigned int class; + unsigned int cls; } classes[] = { { 0x037e, 0x037e, 1 }, // Greek question mark { 0x0387, 0x0387, 1 }, // Greek ano teleia @@ -1154,7 +1154,7 @@ int utf_class_tab(const int c, const uint64_t *const chartab) } else if (classes[mid].first > (unsigned int)c) { top = mid - 1; } else { - return (int)classes[mid].class; + return (int)classes[mid].cls; } } @@ -1312,10 +1312,10 @@ static int utf_strnicmp(const char *s1, const char *s2, size_t n1, size_t n2) // to fold just one character to determine the result of comparison. if (c1 != -1 && c2 == -1) { - n1 = (size_t)utf_char2bytes(utf_fold(c1), (char *)buffer); + n1 = (size_t)utf_char2bytes(utf_fold(c1), buffer); s1 = buffer; } else if (c2 != -1 && c1 == -1) { - n2 = (size_t)utf_char2bytes(utf_fold(c2), (char *)buffer); + n2 = (size_t)utf_char2bytes(utf_fold(c2), buffer); s2 = buffer; } diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 118b5d5886..51fa17384c 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -800,7 +800,7 @@ static bool mf_do_open(memfile_T *mfp, char *fname, int flags) emsg(_("E300: Swap file already exists (symlink attack?)")); } else { // try to open the file - mfp->mf_fd = MCH_OPEN_RW((char *)mfp->mf_fname, flags | O_NOFOLLOW); + mfp->mf_fd = MCH_OPEN_RW(mfp->mf_fname, flags | O_NOFOLLOW); } // If the file cannot be opened, use memory only diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 51a4186775..18d5e75a53 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1351,7 +1351,7 @@ int recover_names(char *fname, int list, int nr, char **fname_out) // print the swap file name msg_outnum((long)++file_count); msg_puts(". "); - msg_puts((const char *)path_tail(files[i])); + msg_puts(path_tail(files[i])); msg_putchar('\n'); (void)swapfile_info(files[i]); } @@ -1508,7 +1508,7 @@ static time_t swapfile_info(char *fname) if (char_to_long(b0.b0_pid) != 0L) { msg_puts(_("\n process ID: ")); msg_outnum(char_to_long(b0.b0_pid)); - if (swapfile_process_running(&b0, (const char *)fname)) { + if (swapfile_process_running(&b0, fname)) { msg_puts(_(" (STILL RUNNING)")); process_still_running = true; } @@ -3988,7 +3988,7 @@ int inc(pos_T *lp) if (lp->col != MAXCOL) { const char *const p = ml_get_pos(lp); if (*p != NUL) { // still within line, move to next char (may be NUL) - const int l = utfc_ptr2len((char *)p); + const int l = utfc_ptr2len(p); lp->col += l; return ((p[l] != NUL) ? 0 : 2); diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 4fad926cb0..b9afa2e7a4 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -50,8 +50,8 @@ /// The character for each menu mode static char *menu_mode_chars[] = { "n", "v", "s", "o", "i", "c", "tl", "t" }; -static char e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu"); -static char e_nomenu[] = N_("E329: No menu \"%s\""); +static const char e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu"); +static const char e_nomenu[] = N_("E329: No menu \"%s\""); // Return true if "name" is a window toolbar menu name. static bool menu_is_winbar(const char *const name) @@ -1343,7 +1343,7 @@ static char *menu_text(const char *str, int *mnemonic, char **actext) bool menu_is_menubar(const char *const name) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return !menu_is_popup((char *)name) + return !menu_is_popup(name) && !menu_is_toolbar(name) && !menu_is_winbar(name) && *name != MNU_HIDDEN_CHAR; diff --git a/src/nvim/message.c b/src/nvim/message.c index b43bc6ce9b..f78980c859 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1488,17 +1488,17 @@ void msg_outnum(long n) msg_puts(buf); } -void msg_home_replace(char *fname) +void msg_home_replace(const char *fname) { msg_home_replace_attr(fname, 0); } -void msg_home_replace_hl(char *fname) +void msg_home_replace_hl(const char *fname) { msg_home_replace_attr(fname, HL_ATTR(HLF_D)); } -static void msg_home_replace_attr(char *fname, int attr) +static void msg_home_replace_attr(const char *fname, int attr) { char *name = home_replace_save(NULL, fname); msg_outtrans_attr(name, attr); @@ -1510,7 +1510,7 @@ static void msg_home_replace_attr(char *fname, int attr) /// Use attributes 'attr'. /// /// @return the number of characters it takes on the screen. -int msg_outtrans(char *str) +int msg_outtrans(const char *str) { return msg_outtrans_attr(str, 0); } @@ -1529,7 +1529,7 @@ int msg_outtrans_len(const char *str, int len) /// Handles multi-byte characters. /// /// @return pointer to the next character. -char *msg_outtrans_one(char *p, int attr) +const char *msg_outtrans_one(const char *p, int attr) { int l; @@ -1537,7 +1537,7 @@ char *msg_outtrans_one(char *p, int attr) msg_outtrans_len_attr(p, l, attr); return p + l; } - msg_puts_attr((const char *)transchar_byte_buf(NULL, (uint8_t)(*p)), attr); + msg_puts_attr(transchar_byte_buf(NULL, (uint8_t)(*p)), attr); return p + 1; } @@ -1582,8 +1582,7 @@ int msg_outtrans_len_attr(const char *msgstr, int len, int attr) msg_puts_attr_len(plain_start, str - plain_start, attr); } plain_start = str + mb_l; - msg_puts_attr((const char *)transchar_buf(NULL, c), - (attr == 0 ? HL_ATTR(HLF_8) : attr)); + msg_puts_attr(transchar_buf(NULL, c), attr == 0 ? HL_ATTR(HLF_8) : attr); retval += char2cells(c); } len -= mb_l - 1; @@ -1616,11 +1615,11 @@ int msg_outtrans_len_attr(const char *msgstr, int len, int attr) return retval; } -void msg_make(char *arg) +void msg_make(const char *arg) { int i; - static char *str = "eeffoc"; - static char *rs = "Plon#dqg#vxjduB"; + static const char *str = "eeffoc"; + static const char *rs = "Plon#dqg#vxjduB"; arg = skipwhite(arg); for (i = 5; *arg && i >= 0; i--) { @@ -1777,7 +1776,7 @@ const char *str2special(const char **const sp, const bool replace_spaces, const || c < ' ' || (replace_spaces && c == ' ') || (replace_lt && c == '<')) { - return (const char *)get_special_key_name(c, modifiers); + return get_special_key_name(c, modifiers); } buf[0] = (char)c; buf[1] = NUL; @@ -1806,20 +1805,20 @@ void str2specialbuf(const char *sp, char *buf, size_t len) } /// print line for :print or :list command -void msg_prt_line(char *s, int list) +void msg_prt_line(const char *s, int list) { int c; int col = 0; int n_extra = 0; int c_extra = 0; int c_final = 0; - char *p_extra = NULL; // init to make SASC shut up + const char *p_extra = NULL; // init to make SASC shut up int n; int attr = 0; - char *lead = NULL; + const char *lead = NULL; bool in_multispace = false; int multispace_pos = 0; - char *trail = NULL; + const char *trail = NULL; int l; if (curwin->w_p_list) { @@ -2011,12 +2010,12 @@ void msg_puts_title(const char *s) /// Show a message in such a way that it always fits in the line. Cut out a /// part in the middle and replace it with "..." when necessary. /// Does not handle multi-byte characters! -void msg_outtrans_long_attr(char *longstr, int attr) +void msg_outtrans_long_attr(const char *longstr, int attr) { msg_outtrans_long_len_attr(longstr, (int)strlen(longstr), attr); } -void msg_outtrans_long_len_attr(char *longstr, int len, int attr) +void msg_outtrans_long_len_attr(const char *longstr, int len, int attr) { int slen = len; int room; diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index d1fd28f882..9afa3ea02a 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -11,6 +11,7 @@ #include "klib/kvec.h" #include "msgpack/pack.h" +#include "nvim/api/keysets.h" #include "nvim/api/private/helpers.h" #include "nvim/assert.h" #include "nvim/event/wstream.h" @@ -19,7 +20,6 @@ #include "nvim/types.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "keysets.generated.h" // IWYU pragma: export # include "msgpack_rpc/helpers.c.generated.h" #endif diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 6ad1cbd987..b11d5a3c32 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -117,7 +117,7 @@ static inline void normal_state_init(NormalState *s) // n_*(): functions called to handle Normal mode commands. // v_*(): functions called to handle Visual mode commands. -static char *e_noident = N_("E349: No identifier under cursor"); +static const char *e_noident = N_("E349: No identifier under cursor"); /// Function to be called for a Normal or Visual mode command. /// The argument is a cmdarg_T. @@ -668,7 +668,7 @@ static void normal_redraw_mode_message(NormalState *s) keep_msg = kmsg; kmsg = xstrdup(keep_msg); - msg_attr((const char *)kmsg, keep_msg_attr); + msg_attr(kmsg, keep_msg_attr); xfree(kmsg); } setcursor(); @@ -1336,7 +1336,7 @@ static void normal_redraw(NormalState *s) // check for duplicates. Never put this message in // history. msg_hist_off = true; - msg_attr((const char *)p, keep_msg_attr); + msg_attr(p, keep_msg_attr); msg_hist_off = false; xfree(p); } @@ -3512,7 +3512,7 @@ static void nv_ident(cmdarg_T *cap) ptr = xstrnsave(ptr, n); if (kp_ex) { // Escape the argument properly for an Ex command - p = vim_strsave_fnameescape((const char *)ptr, VSE_NONE); + p = vim_strsave_fnameescape(ptr, VSE_NONE); } else { // Escape the argument properly for a shell command p = vim_strsave_shellescape(ptr, true, true); @@ -5334,7 +5334,7 @@ static void nv_g_dollar_cmd(cmdarg_T *cap) coladvance((colnr_T)i); // if the character doesn't fit move one back - if (curwin->w_cursor.col > 0 && utf_ptr2cells((const char *)get_cursor_pos_ptr()) > 1) { + if (curwin->w_cursor.col > 0 && utf_ptr2cells(get_cursor_pos_ptr()) > 1) { colnr_T vcol; getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index d66ed9abff..9aacfcad30 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -623,9 +623,9 @@ static void block_insert(oparg_T *oap, char *s, int b_insert, struct block_def * } } // for all lnum - changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true); - State = oldstate; + + changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true); } /// Handle reindenting a block of lines. @@ -926,7 +926,7 @@ int do_record(int c) if (p != NULL) { // Remove escaping for K_SPECIAL in multi-byte chars. vim_unescape_ks(p); - (void)tv_dict_add_str(dict, S_LEN("regcontents"), (const char *)p); + (void)tv_dict_add_str(dict, S_LEN("regcontents"), p); } // Name of requested register, or empty string for unnamed operation. @@ -1273,7 +1273,7 @@ int insert_reg(int regname, bool literally_arg) if (arg == NULL) { return FAIL; } - stuffescaped((const char *)arg, literally); + stuffescaped(arg, literally); if (allocated) { xfree(arg); } @@ -1288,7 +1288,7 @@ int insert_reg(int regname, bool literally_arg) AppendCharToRedobuff(regname); do_put(regname, NULL, BACKWARD, 1L, PUT_CURSEND); } else { - stuffescaped((const char *)reg->y_array[i], literally); + stuffescaped(reg->y_array[i], literally); } // Insert a newline between lines and after last line if // y_type is kMTLineWise. @@ -2867,7 +2867,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) // The yanked text contents. list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size); for (size_t i = 0; i < reg->y_size; i++) { - tv_list_append_string(list, (const char *)reg->y_array[i], -1); + tv_list_append_string(list, reg->y_array[i], -1); } tv_list_set_lock(list, VAR_FIXED); (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); @@ -4963,7 +4963,7 @@ void *get_reg_contents(int regname, int flags) if (flags & kGRegList) { list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size); for (size_t i = 0; i < reg->y_size; i++) { - tv_list_append_string(list, (const char *)reg->y_array[i], -1); + tv_list_append_string(list, reg->y_array[i], -1); } return list; @@ -5608,13 +5608,13 @@ static void op_colon(oparg_T *oap) stuffReadbuff("!"); } if (oap->op_type == OP_INDENT) { - stuffReadbuff((const char *)get_equalprg()); + stuffReadbuff(get_equalprg()); stuffReadbuff("\n"); } else if (oap->op_type == OP_FORMAT) { if (*curbuf->b_p_fp != NUL) { - stuffReadbuff((const char *)curbuf->b_p_fp); + stuffReadbuff(curbuf->b_p_fp); } else if (*p_fp != NUL) { - stuffReadbuff((const char *)p_fp); + stuffReadbuff(p_fp); } else { stuffReadbuff("fmt"); } @@ -5628,7 +5628,7 @@ static void op_colon(oparg_T *oap) static Callback opfunc_cb; /// Process the 'operatorfunc' option value. -void set_operatorfunc_option(char **errmsg) +void set_operatorfunc_option(const char **errmsg) { if (option_set_callback_func(p_opfunc, &opfunc_cb) == FAIL) { *errmsg = e_invarg; @@ -6639,7 +6639,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet) if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) { goto err; } - reg->y_array[tv_idx++] = xstrdupnul((const char *)TV_LIST_ITEM_TV(li)->vval.v_string); + reg->y_array[tv_idx++] = xstrdupnul(TV_LIST_ITEM_TV(li)->vval.v_string); }); if (reg->y_size > 0 && strlen(reg->y_array[reg->y_size - 1]) == 0) { @@ -6700,7 +6700,7 @@ static void set_clipboard(int name, yankreg_T *reg) list_T *const lines = tv_list_alloc((ptrdiff_t)reg->y_size + (reg->y_type != kMTCharWise)); for (size_t i = 0; i < reg->y_size; i++) { - tv_list_append_string(lines, (const char *)reg->y_array[i], -1); + tv_list_append_string(lines, reg->y_array[i], -1); } char regtype; @@ -6910,7 +6910,7 @@ bcount_t get_region_bytecount(buf_T *buf, linenr_T start_lnum, linenr_T end_lnum if (start_lnum == end_lnum) { return end_col - start_col; } - const char *first = (const char *)ml_get_buf(buf, start_lnum, false); + const char *first = ml_get_buf(buf, start_lnum, false); bcount_t deleted_bytes = (bcount_t)strlen(first) - start_col + 1; for (linenr_T i = 1; i <= end_lnum - start_lnum - 1; i++) { diff --git a/src/nvim/option.c b/src/nvim/option.c index 8fa719c3a9..386c6d88d9 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -105,17 +105,17 @@ # include "nvim/arglist.h" #endif -static char e_unknown_option[] +static const char e_unknown_option[] = N_("E518: Unknown option"); -static char e_not_allowed_in_modeline[] +static const char e_not_allowed_in_modeline[] = N_("E520: Not allowed in a modeline"); -static char e_not_allowed_in_modeline_when_modelineexpr_is_off[] +static const char e_not_allowed_in_modeline_when_modelineexpr_is_off[] = N_("E992: Not allowed in a modeline when 'modelineexpr' is off"); -static char e_key_code_not_set[] +static const char e_key_code_not_set[] = N_("E846: Key code not set"); -static char e_number_required_after_equal[] +static const char e_number_required_after_equal[] = N_("E521: Number required after ="); -static char e_preview_window_already_exists[] +static const char e_preview_window_already_exists[] = N_("E590: A preview window already exists"); static char *p_term = NULL; @@ -747,7 +747,7 @@ void ex_set(exarg_T *eap) } static void do_set_bool(int opt_idx, int opt_flags, int prefix, int nextchar, const char *varp, - char **errmsg) + const char **errmsg) { varnumber_T value; @@ -777,7 +777,7 @@ static void do_set_bool(int opt_idx, int opt_flags, int prefix, int nextchar, co } static void do_set_num(int opt_idx, int opt_flags, char **argp, int nextchar, const set_op_T op, - const char *varp, char *errbuf, size_t errbuflen, char **errmsg) + const char *varp, char *errbuf, size_t errbuflen, const char **errmsg) { varnumber_T value; char *arg = *argp; @@ -911,7 +911,7 @@ static void munge_string_opt_val(char **varp, char **oldval, char **const origva /// Part of do_set() for string options. static void do_set_string(int opt_idx, int opt_flags, char **argp, int nextchar, set_op_T op_arg, uint32_t flags, char *varp_arg, char *errbuf, size_t errbuflen, - int *value_checked, char **errmsg) + int *value_checked, const char **errmsg) { char *arg = *argp; set_op_T op = op_arg; @@ -1235,7 +1235,7 @@ static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp) return FAIL; } if (arg[1] == 't' && arg[2] == '_') { // could be term code - opt_idx = findoption_len((const char *)arg + 1, (size_t)(len - 1)); + opt_idx = findoption_len(arg + 1, (size_t)(len - 1)); } len++; if (opt_idx == -1) { @@ -1251,7 +1251,7 @@ static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp) len++; } } - opt_idx = findoption_len((const char *)arg, (size_t)len); + opt_idx = findoption_len(arg, (size_t)len); if (opt_idx == -1) { key = find_key_option(arg, false); } @@ -1265,7 +1265,7 @@ static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp) } static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t flags, int prefix, - char **errmsg) + const char **errmsg) { // Only bools can have a prefix of 'inv' or 'no' if (!(flags & P_BOOL) && prefix != 1) { @@ -1318,7 +1318,7 @@ static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t fla static void do_set_option_value(int opt_idx, int opt_flags, char **argp, int prefix, int nextchar, set_op_T op, uint32_t flags, char *varp, char *errbuf, - size_t errbuflen, char **errmsg) + size_t errbuflen, const char **errmsg) { int value_checked = false; if (flags & P_BOOL) { // boolean @@ -1343,7 +1343,7 @@ static void do_set_option_value(int opt_idx, int opt_flags, char **argp, int pre } static void do_set_option(int opt_flags, char **argp, bool *did_show, char *errbuf, - size_t errbuflen, char **errmsg) + size_t errbuflen, const char **errmsg) { // 1: nothing, 0: "no", 2: "inv" in front of name int prefix = get_option_prefix(argp); @@ -1521,7 +1521,7 @@ int do_set(char *arg, int opt_flags) } } else { char *startarg = arg; // remember for error message - char *errmsg = NULL; + const char *errmsg = NULL; char errbuf[80]; do_set_option(opt_flags, &arg, &did_show, errbuf, sizeof(errbuf), &errmsg); @@ -1869,7 +1869,7 @@ void check_blending(win_T *wp) /// Handle setting `winhighlight' in window "wp" bool parse_winhl_opt(win_T *wp) { - const char *p = (const char *)wp->w_p_winhl; + const char *p = wp->w_p_winhl; if (!*p) { if (wp->w_ns_hl_winhl && wp->w_ns_hl == wp->w_ns_hl_winhl) { @@ -1992,17 +1992,17 @@ 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 *const varp, const int value, - const int opt_flags) +static const char *set_bool_option(const int opt_idx, char *const varp, const int value, + const int opt_flags) { int old_value = *(int *)varp; int old_global_value = 0; - char *errmsg = NULL; + const char *errmsg = NULL; // Disallow changing some options from secure mode if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) { - return (char *)e_secure; + return e_secure; } // Save the global value before changing anything. This is needed as for @@ -2274,10 +2274,10 @@ static char *set_bool_option(const int opt_idx, char *const varp, const int valu /// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE. /// /// @return NULL on success, error message on error. -static char *set_num_option(int opt_idx, char *varp, long value, char *errbuf, size_t errbuflen, - int opt_flags) +static const char *set_num_option(int opt_idx, char *varp, long value, char *errbuf, + size_t errbuflen, int opt_flags) { - char *errmsg = NULL; + const char *errmsg = NULL; long old_value = *(long *)varp; long old_global_value = 0; // only used when setting a local and global option long old_Rows = Rows; // remember old Rows @@ -3078,8 +3078,8 @@ vimoption_T *get_option(int opt_idx) /// on the option). /// /// @return NULL on success, an untranslated error message on error. -char *set_option_value(const char *const name, const long number, const char *const string, - const int opt_flags) +const char *set_option_value(const char *const name, const long number, const char *const string, + const int opt_flags) FUNC_ATTR_NONNULL_ARG(1) { static char errbuf[80]; @@ -3154,7 +3154,7 @@ char *set_option_value(const char *const name, const long number, const char *co /// @param opt_flags OPT_LOCAL or 0 (both) void set_option_value_give_err(const char *name, long number, const char *string, int opt_flags) { - char *errmsg = set_option_value(name, number, string, opt_flags); + const char *errmsg = set_option_value(name, number, string, opt_flags); if (errmsg != NULL) { emsg(_(errmsg)); @@ -4694,7 +4694,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) return; } nextchar = *p; - opt_idx = findoption_len((const char *)arg, (size_t)(p - arg)); + opt_idx = findoption_len(arg, (size_t)(p - arg)); if (opt_idx == -1 || options[opt_idx].var == NULL) { xp->xp_context = EXPAND_NOTHING; return; @@ -5509,7 +5509,7 @@ int win_signcol_count(win_T *wp) /// Return the number of requested sign columns, based on user / configuration. int win_signcol_configured(win_T *wp, int *is_fixed) { - const char *scl = (const char *)wp->w_p_scl; + const char *scl = wp->w_p_scl; if (is_fixed) { *is_fixed = 1; @@ -5607,7 +5607,7 @@ long get_sidescrolloff_value(win_T *wp) Dictionary get_vimoption(String name, int scope, buf_T *buf, win_T *win, Error *err) { - int opt_idx = findoption_len((const char *)name.data, name.size); + int opt_idx = findoption_len(name.data, name.size); VALIDATE_S(opt_idx >= 0, "option (not found)", name.data, { return (Dictionary)ARRAY_DICT_INIT; }); @@ -5676,7 +5676,7 @@ static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, wi char *def_val = opt->def_val; if (opt->flags & P_STRING) { type = "string"; - def = CSTR_TO_OBJ(def_val ? (char *)def_val : ""); + def = CSTR_TO_OBJ(def_val ? def_val : ""); } else if (opt->flags & P_NUM) { type = "number"; def = INTEGER_OBJ((Integer)(intptr_t)def_val); diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index bf4ebbb3e2..3372c7b6c6 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -59,13 +59,13 @@ # include "optionstr.c.generated.h" #endif -static char e_unclosed_expression_sequence[] +static const char e_unclosed_expression_sequence[] = N_("E540: Unclosed expression sequence"); -static char e_unbalanced_groups[] +static const char e_unbalanced_groups[] = N_("E542: unbalanced groups"); -static char e_backupext_and_patchmode_are_equal[] +static const char e_backupext_and_patchmode_are_equal[] = N_("E589: 'backupext' and 'patchmode' are equal"); -static char e_showbreak_contains_unprintable_or_wide_character[] +static const char e_showbreak_contains_unprintable_or_wide_character[] = N_("E595: 'showbreak' contains unprintable or wide character"); static char *(p_ambw_values[]) = { "single", "double", NULL }; @@ -410,8 +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 *const errbuf, const size_t errbuflen) +const 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); @@ -442,9 +442,8 @@ char *set_string_option(const int opt_idx, const char *const value, const int op char *const saved_newval = xstrdup(s); int value_checked = false; - char *const errmsg = did_set_string_option(opt_idx, varp, oldval, - errbuf, errbuflen, - opt_flags, &value_checked); + const char *const errmsg = did_set_string_option(opt_idx, varp, oldval, errbuf, errbuflen, + opt_flags, &value_checked); if (errmsg == NULL) { did_set_option(opt_idx, opt_flags, true, value_checked); } @@ -478,7 +477,7 @@ static bool valid_filetype(const char *val) /// Handle setting 'mousescroll'. /// @return error message, NULL if it's OK. -static char *check_mousescroll(char *string) +static const char *check_mousescroll(char *string) { long vertical = -1; long horizontal = -1; @@ -571,7 +570,7 @@ static int check_signcolumn(char *val) /// Check validity of options with the 'statusline' format. /// Return an untranslated error message or NULL. -char *check_stl_option(char *s) +const char *check_stl_option(char *s) { int groupdepth = 0; static char errbuf[80]; @@ -650,7 +649,7 @@ static bool check_illegal_path_names(char *val, uint32_t flags) && strpbrk(val, "*?[|;&<>\r\n") != NULL)); } -static void did_set_backupcopy(buf_T *buf, char *oldval, int opt_flags, char **errmsg) +static void did_set_backupcopy(buf_T *buf, char *oldval, int opt_flags, const char **errmsg) { char *bkc = p_bkc; unsigned int *flags = &bkc_flags; @@ -678,7 +677,7 @@ static void did_set_backupcopy(buf_T *buf, char *oldval, int opt_flags, char **e } } -static void did_set_backupext_or_patchmode(char **errmsg) +static void did_set_backupext_or_patchmode(const char **errmsg) { if (strcmp(*p_bex == '.' ? p_bex + 1 : p_bex, *p_pm == '.' ? p_pm + 1 : p_pm) == 0) { @@ -686,7 +685,7 @@ static void did_set_backupext_or_patchmode(char **errmsg) } } -static void did_set_breakindentopt(win_T *win, char **errmsg) +static void did_set_breakindentopt(win_T *win, const char **errmsg) { if (briopt_check(win) == FAIL) { *errmsg = e_invarg; @@ -697,7 +696,7 @@ static void did_set_breakindentopt(win_T *win, char **errmsg) } } -static void did_set_isopt(buf_T *buf, bool *did_chartab, char **errmsg) +static void did_set_isopt(buf_T *buf, bool *did_chartab, const char **errmsg) { // 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[] // If the new option is invalid, use old value. @@ -719,14 +718,14 @@ static void did_set_helpfile(void) } } -static void did_set_cursorlineopt(win_T *win, char **varp, char **errmsg) +static void did_set_cursorlineopt(win_T *win, char **varp, const char **errmsg) { if (**varp == NUL || fill_culopt_flags(*varp, win) != OK) { *errmsg = e_invarg; } } -static void did_set_helplang(char **errmsg) +static void did_set_helplang(const char **errmsg) { // Check for "", "ab", "ab,cd", etc. for (char *s = p_hlg; *s != NUL; s += 3) { @@ -740,26 +739,27 @@ static void did_set_helplang(char **errmsg) } } -static void did_set_highlight(char **varp, char **errmsg) +static void did_set_highlight(char **varp, const char **errmsg) { if (strcmp(*varp, HIGHLIGHT_INIT) != 0) { *errmsg = e_unsupportedoption; } } -static void did_set_opt_flags(char *val, char **values, unsigned *flagp, bool list, char **errmsg) +static void did_set_opt_flags(char *val, char **values, unsigned *flagp, bool list, + const char **errmsg) { if (opt_strings_flags(val, values, flagp, list) != OK) { *errmsg = e_invarg; } } -static void did_set_opt_strings(char *val, char **values, bool list, char **errmsg) +static void did_set_opt_strings(char *val, char **values, bool list, const char **errmsg) { did_set_opt_flags(val, values, NULL, list, errmsg); } -static void did_set_sessionoptions(char *oldval, char **errmsg) +static void did_set_sessionoptions(char *oldval, const char **errmsg) { if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, true) != OK) { *errmsg = e_invarg; @@ -771,7 +771,7 @@ static void did_set_sessionoptions(char *oldval, char **errmsg) } } -static void did_set_ambiwidth(char **errmsg) +static void did_set_ambiwidth(const char **errmsg) { if (check_opt_strings(p_ambw, p_ambw_values, false) != OK) { *errmsg = e_invarg; @@ -780,7 +780,7 @@ static void did_set_ambiwidth(char **errmsg) } } -static void did_set_background(char **errmsg) +static void did_set_background(const char **errmsg) { if (check_opt_strings(p_bg, p_bg_values, false) != OK) { *errmsg = e_invarg; @@ -803,21 +803,21 @@ static void did_set_background(char **errmsg) } } -static void did_set_wildmode(char **errmsg) +static void did_set_wildmode(const char **errmsg) { if (check_opt_wim() == FAIL) { *errmsg = e_invarg; } } -static void did_set_winaltkeys(char **errmsg) +static void did_set_winaltkeys(const char **errmsg) { if (*p_wak == NUL || check_opt_strings(p_wak, p_wak_values, false) != OK) { *errmsg = e_invarg; } } -static void did_set_eventignore(char **errmsg) +static void did_set_eventignore(const char **errmsg) { if (check_ei() == FAIL) { *errmsg = e_invarg; @@ -825,7 +825,8 @@ static void did_set_eventignore(char **errmsg) } // 'encoding', 'fileencoding' and 'makeencoding' -static void did_set_encoding(buf_T *buf, char **varp, char **gvarp, int opt_flags, char **errmsg) +static void did_set_encoding(buf_T *buf, char **varp, char **gvarp, int opt_flags, + const char **errmsg) { if (gvarp == &p_fenc) { if (!MODIFIABLE(buf) && opt_flags != OPT_GLOBAL) { @@ -861,7 +862,7 @@ static void did_set_encoding(buf_T *buf, char **varp, char **gvarp, int opt_flag } static void did_set_keymap(buf_T *buf, char **varp, int opt_flags, int *value_checked, - char **errmsg) + const char **errmsg) { if (!valid_filetype(*varp)) { *errmsg = e_invarg; @@ -908,7 +909,7 @@ static void did_set_keymap(buf_T *buf, char **varp, int opt_flags, int *value_ch } static void did_set_fileformat(buf_T *buf, char **varp, const char *oldval, int opt_flags, - char **errmsg) + const char **errmsg) { if (!MODIFIABLE(buf) && !(opt_flags & OPT_GLOBAL)) { *errmsg = e_modifiable; @@ -926,7 +927,7 @@ static void did_set_fileformat(buf_T *buf, char **varp, const char *oldval, int } } -static void did_set_matchpairs(char **varp, char **errmsg) +static void did_set_matchpairs(char **varp, const char **errmsg) { for (char *p = *varp; *p != NUL; p++) { int x2 = -1; @@ -950,7 +951,7 @@ static void did_set_matchpairs(char **varp, char **errmsg) } } -static void did_set_comments(char **varp, char *errbuf, size_t errbuflen, char **errmsg) +static void did_set_comments(char **varp, char *errbuf, size_t errbuflen, const char **errmsg) { for (char *s = *varp; *s;) { while (*s && *s != ':') { @@ -979,7 +980,8 @@ static void did_set_comments(char **varp, char *errbuf, size_t errbuflen, char * } } -static void did_set_global_listfillchars(win_T *win, char **varp, int opt_flags, char **errmsg) +static void did_set_global_listfillchars(win_T *win, char **varp, int opt_flags, + const char **errmsg) { char **local_ptr = varp == &p_lcs ? &win->w_p_lcs : &win->w_p_fcs; // only apply the global value to "win" when it does not have a local value @@ -1004,7 +1006,7 @@ static void did_set_global_listfillchars(win_T *win, char **varp, int opt_flags, } } -static void did_set_verbosefile(char **errmsg) +static void did_set_verbosefile(const char **errmsg) { verbose_stop(); if (*p_vfile != NUL && verbose_open() == FAIL) { @@ -1015,7 +1017,7 @@ static void did_set_verbosefile(char **errmsg) static int shada_idx = -1; static void did_set_shada(vimoption_T **opt, int *opt_idx, bool *free_oldval, char *errbuf, - size_t errbuflen, char **errmsg) + size_t errbuflen, const char **errmsg) { // TODO(ZyX-I): Remove this code in the future, alongside with &viminfo // option. @@ -1073,7 +1075,7 @@ static void did_set_shada(vimoption_T **opt, int *opt_idx, bool *free_oldval, ch } } -static void did_set_showbreak(char **varp, char **errmsg) +static void did_set_showbreak(char **varp, const char **errmsg) { for (char *s = *varp; *s;) { if (ptr2cells(s) != 1) { @@ -1097,14 +1099,14 @@ static void did_set_titleiconstring(char **varp) did_set_title(); } -static void did_set_selection(char **errmsg) +static void did_set_selection(const char **errmsg) { if (*p_sel == NUL || check_opt_strings(p_sel, p_sel_values, false) != OK) { *errmsg = e_invarg; } } -static void did_set_keymodel(char **errmsg) +static void did_set_keymodel(const char **errmsg) { if (check_opt_strings(p_km, p_km_values, true) != OK) { *errmsg = e_invarg; @@ -1114,7 +1116,7 @@ static void did_set_keymodel(char **errmsg) km_startsel = (vim_strchr(p_km, 'a') != NULL); } -static void did_set_display(char **errmsg) +static void did_set_display(const char **errmsg) { if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, true) != OK) { *errmsg = e_invarg; @@ -1124,7 +1126,7 @@ static void did_set_display(char **errmsg) msg_grid_validate(); } -static void did_set_spellfile(char **varp, char **errmsg) +static void did_set_spellfile(char **varp, const char **errmsg) { // When there is a window for this buffer in which 'spell' // is set load the wordlists. @@ -1136,7 +1138,7 @@ static void did_set_spellfile(char **varp, char **errmsg) } } -static void did_set_spell(char **varp, char **errmsg) +static void did_set_spell(char **varp, const char **errmsg) { // When there is a window for this buffer in which 'spell' // is set load the wordlists. @@ -1147,13 +1149,13 @@ static void did_set_spell(char **varp, char **errmsg) } } -static void did_set_spellcapcheck(win_T *win, char **errmsg) +static void did_set_spellcapcheck(win_T *win, const char **errmsg) { // When 'spellcapcheck' is set compile the regexp program. *errmsg = compile_cap_prog(win->w_s); } -static void did_set_spelloptions(win_T *win, char **errmsg) +static void did_set_spelloptions(win_T *win, const char **errmsg) { if (opt_strings_flags(win->w_s->b_p_spo, p_spo_values, &(win->w_s->b_p_spo_flags), true) != OK) { @@ -1161,21 +1163,21 @@ static void did_set_spelloptions(win_T *win, char **errmsg) } } -static void did_set_spellsuggest(char **errmsg) +static void did_set_spellsuggest(const char **errmsg) { if (spell_check_sps() != OK) { *errmsg = e_invarg; } } -static void did_set_mkspellmem(char **errmsg) +static void did_set_mkspellmem(const char **errmsg) { if (spell_check_msm() != OK) { *errmsg = e_invarg; } } -static void did_set_buftype(buf_T *buf, win_T *win, char **errmsg) +static void did_set_buftype(buf_T *buf, win_T *win, const char **errmsg) { // When 'buftype' is set, check for valid value. if ((buf->terminal && buf->b_p_bt[0] != 't') @@ -1193,7 +1195,7 @@ static void did_set_buftype(buf_T *buf, win_T *win, char **errmsg) } // 'statusline', 'winbar', 'tabline', 'rulerformat' or 'statuscolumn' -static void did_set_statusline(win_T *win, char **varp, char **gvarp, char **errmsg) +static void did_set_statusline(win_T *win, char **varp, char **gvarp, const char **errmsg) { if (varp == &p_ruf) { // reset ru_wid first ru_wid = 0; @@ -1227,7 +1229,7 @@ static void did_set_statusline(win_T *win, char **varp, char **gvarp, char **err } } -static void did_set_complete(char **varp, char *errbuf, size_t errbuflen, char **errmsg) +static void did_set_complete(char **varp, char *errbuf, size_t errbuflen, const char **errmsg) { // check if it is a valid value for 'complete' -- Acevedo for (char *s = *varp; *s;) { @@ -1265,7 +1267,7 @@ static void did_set_complete(char **varp, char *errbuf, size_t errbuflen, char * } } -static void did_set_completeopt(char **errmsg) +static void did_set_completeopt(const char **errmsg) { if (check_opt_strings(p_cot, p_cot_values, true) != OK) { *errmsg = e_invarg; @@ -1275,7 +1277,7 @@ static void did_set_completeopt(char **errmsg) } #ifdef BACKSLASH_IN_FILENAME -static void did_set_completeslash(buf_T *buf, char **errmsg) +static void did_set_completeslash(buf_T *buf, const char **errmsg) { if (check_opt_strings(p_csl, p_csl_values, false) != OK || check_opt_strings(buf->b_p_csl, p_csl_values, false) != OK) { @@ -1284,7 +1286,7 @@ static void did_set_completeslash(buf_T *buf, char **errmsg) } #endif -static void did_set_signcolumn(win_T *win, char **varp, const char *oldval, char **errmsg) +static void did_set_signcolumn(win_T *win, char **varp, const char *oldval, const char **errmsg) { if (check_signcolumn(*varp) != OK) { *errmsg = e_invarg; @@ -1298,14 +1300,14 @@ static void did_set_signcolumn(win_T *win, char **varp, const char *oldval, char } } -static void did_set_foldcolumn(char **varp, char **errmsg) +static void did_set_foldcolumn(char **varp, const char **errmsg) { if (**varp == NUL || check_opt_strings(*varp, p_fdc_values, false) != OK) { *errmsg = e_invarg; } } -static void did_set_backspace(char **errmsg) +static void did_set_backspace(const char **errmsg) { if (ascii_isdigit(*p_bs)) { if (*p_bs > '3' || p_bs[1] != NUL) { @@ -1316,7 +1318,7 @@ static void did_set_backspace(char **errmsg) } } -static void did_set_tagcase(buf_T *buf, int opt_flags, char **errmsg) +static void did_set_tagcase(buf_T *buf, int opt_flags, const char **errmsg) { unsigned int *flags; char *p; @@ -1338,14 +1340,14 @@ static void did_set_tagcase(buf_T *buf, int opt_flags, char **errmsg) } } -static void did_set_diffopt(char **errmsg) +static void did_set_diffopt(const char **errmsg) { if (diffopt_changed() == FAIL) { *errmsg = e_invarg; } } -static void did_set_foldmethod(win_T *win, char **varp, char **errmsg) +static void did_set_foldmethod(win_T *win, char **varp, const char **errmsg) { if (check_opt_strings(*varp, p_fdm_values, false) != OK || *win->w_p_fdm == NUL) { @@ -1358,7 +1360,7 @@ static void did_set_foldmethod(win_T *win, char **varp, char **errmsg) } } -static void did_set_foldmarker(win_T *win, char **varp, char **errmsg) +static void did_set_foldmarker(win_T *win, char **varp, const char **errmsg) { char *p = vim_strchr(*varp, ','); if (p == NULL) { @@ -1370,7 +1372,7 @@ static void did_set_foldmarker(win_T *win, char **varp, char **errmsg) } } -static void did_set_commentstring(char **varp, char **errmsg) +static void did_set_commentstring(char **varp, const char **errmsg) { if (**varp != NUL && strstr(*varp, "%s") == NULL) { *errmsg = N_("E537: 'commentstring' must be empty or contain %s"); @@ -1384,7 +1386,7 @@ static void did_set_foldignore(win_T *win) } } -static void did_set_virtualedit(win_T *win, int opt_flags, char *oldval, char **errmsg) +static void did_set_virtualedit(win_T *win, int opt_flags, char *oldval, const char **errmsg) { char *ve = p_ve; unsigned int *flags = &ve_flags; @@ -1410,7 +1412,7 @@ static void did_set_virtualedit(win_T *win, int opt_flags, char *oldval, char ** } } -static void did_set_lispoptions(char **varp, char **errmsg) +static void did_set_lispoptions(char **varp, const char **errmsg) { if (**varp != NUL && strcmp(*varp, "expr:0") != 0 && strcmp(*varp, "expr:1") != 0) { *errmsg = e_invarg; @@ -1418,7 +1420,7 @@ static void did_set_lispoptions(char **varp, char **errmsg) } static void did_set_filetype_or_syntax(char **varp, char *oldval, int *value_checked, - bool *value_changed, char **errmsg) + bool *value_changed, const char **errmsg) { if (!valid_filetype(*varp)) { *errmsg = e_invarg; @@ -1432,14 +1434,14 @@ static void did_set_filetype_or_syntax(char **varp, char *oldval, int *value_che *value_checked = true; } -static void did_set_winhl(win_T *win, char **errmsg) +static void did_set_winhl(win_T *win, const char **errmsg) { if (!parse_winhl_opt(win)) { *errmsg = e_invarg; } } -static void did_set_varsoftabstop(buf_T *buf, char **varp, char **errmsg) +static void did_set_varsoftabstop(buf_T *buf, char **varp, const char **errmsg) { if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) { XFREE_CLEAR(buf->b_p_vsts_array); @@ -1465,7 +1467,7 @@ static void did_set_varsoftabstop(buf_T *buf, char **varp, char **errmsg) } } -static void did_set_vartabstop(buf_T *buf, win_T *win, char **varp, char **errmsg) +static void did_set_vartabstop(buf_T *buf, win_T *win, char **varp, const char **errmsg) { if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) { XFREE_CLEAR(buf->b_p_vts_array); @@ -1505,7 +1507,7 @@ static void did_set_optexpr(char **varp) // handle option that is a list of flags. static void did_set_option_listflag(char **varp, char *flags, char *errbuf, size_t errbuflen, - char **errmsg) + const char **errmsg) { for (char *s = *varp; *s; s++) { if (vim_strchr(flags, (uint8_t)(*s)) == NULL) { @@ -1569,11 +1571,11 @@ static void do_spelllang_source(win_T *win) /// @param value_checked value was checked to be safe, no need to set P_INSECURE /// /// @return NULL for success, or an untranslated error message for an error -static char *did_set_string_option_for(buf_T *buf, win_T *win, int opt_idx, char **varp, - char *oldval, char *errbuf, size_t errbuflen, int opt_flags, - int *value_checked) +static const char *did_set_string_option_for(buf_T *buf, win_T *win, int opt_idx, char **varp, + char *oldval, char *errbuf, size_t errbuflen, + int opt_flags, int *value_checked) { - char *errmsg = NULL; + const char *errmsg = NULL; bool did_chartab = false; vimoption_T *opt = get_option(opt_idx); bool free_oldval = (opt->flags & P_ALLOCED); @@ -1881,8 +1883,8 @@ static char *did_set_string_option_for(buf_T *buf, win_T *win, int opt_idx, char return errmsg; } -char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf, size_t errbuflen, - int opt_flags, int *value_checked) +const char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf, + size_t errbuflen, int opt_flags, int *value_checked) { return did_set_string_option_for(curbuf, curwin, opt_idx, varp, oldval, errbuf, errbuflen, opt_flags, value_checked); @@ -1939,8 +1941,10 @@ int check_ff_value(char *p) return check_opt_strings(p, p_ff_values, false); } -static char e_conflicts_with_value_of_listchars[] = N_("E834: Conflicts with value of 'listchars'"); -static char e_conflicts_with_value_of_fillchars[] = N_("E835: Conflicts with value of 'fillchars'"); +static const char e_conflicts_with_value_of_listchars[] + = N_("E834: Conflicts with value of 'listchars'"); +static const char e_conflicts_with_value_of_fillchars[] + = N_("E835: Conflicts with value of 'fillchars'"); /// Calls mb_cptr2char_adv(p) and returns the character. /// If "p" starts with "\x", "\u" or "\U" the hex or unicode value is used. @@ -1978,7 +1982,7 @@ static int get_encoded_char_adv(const char **p) /// @param varp either the global or the window-local value. /// @param apply if false, do not store the flags, only check for errors. /// @return error message, NULL if it's OK. -char *set_chars_option(win_T *wp, char **varp, bool apply) +const char *set_chars_option(win_T *wp, char **varp, bool apply) { const char *last_multispace = NULL; // Last occurrence of "multispace:" const char *last_lmultispace = NULL; // Last occurrence of "leadmultispace:" @@ -2202,7 +2206,7 @@ char *set_chars_option(win_T *wp, char **varp, bool apply) /// May set different defaults in case character widths change. /// /// @return an untranslated error message if any of them is invalid, NULL otherwise. -char *check_chars_options(void) +const char *check_chars_options(void) { if (set_chars_option(curwin, &p_lcs, false) != NULL) { return e_conflicts_with_value_of_listchars; diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 5b8c060e7a..0b06877f3c 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -845,7 +845,7 @@ const void *vim_env_iter(const char delim, const char *const val, const void *co const char **const dir, size_t *const len) FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT { - const char *varval = (const char *)iter; + const char *varval = iter; if (varval == NULL) { varval = val; } @@ -876,7 +876,7 @@ const void *vim_env_iter_rev(const char delim, const char *const val, const void const char **const dir, size_t *const len) FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT { - const char *varend = (const char *)iter; + const char *varend = iter; if (varend == NULL) { varend = val + strlen(val) - 1; } @@ -1060,7 +1060,7 @@ size_t home_replace(const buf_T *const buf, const char *src, char *const dst, si } if (buf != NULL && buf->b_help) { - const size_t dlen = xstrlcpy(dst, path_tail((char *)src), dstlen); + const size_t dlen = xstrlcpy(dst, path_tail(src), dstlen); return MIN(dlen, dstlen - 1); } @@ -1098,7 +1098,7 @@ size_t home_replace(const buf_T *const buf, const char *src, char *const dst, si } if (!one) { - src = skipwhite((char *)src); + src = skipwhite(src); } char *dst_p = dst; while (*src && dstlen > 0) { diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 7eba5ca54c..cb51e81005 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -1014,17 +1014,17 @@ int os_file_mkdir(char *fname, int32_t mode) /// Create a unique temporary directory. /// -/// @param[in] template Template of the path to the directory with XXXXXX -/// which would be replaced by random chars. +/// @param[in] templ Template of the path to the directory with XXXXXX +/// which would be replaced by random chars. /// @param[out] path Path to created directory for success, undefined for /// failure. /// @return `0` for success, non-zero for failure. -int os_mkdtemp(const char *template, char *path) +int os_mkdtemp(const char *templ, char *path) FUNC_ATTR_NONNULL_ALL { uv_fs_t request; fs_loop_lock(); - int result = uv_fs_mkdtemp(&fs_loop, &request, template, NULL); + int result = uv_fs_mkdtemp(&fs_loop, &request, templ, NULL); fs_loop_unlock(); if (result == kLibuvSuccess) { xstrlcpy(path, request.path, TEMP_FILE_PATH_MAXLEN); diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index f7d1154169..52cab63989 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -144,7 +144,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in bool is_fish_shell = #if defined(UNIX) - strncmp((char *)invocation_path_tail(p_sh, NULL), "fish", 4) == 0; + strncmp(invocation_path_tail(p_sh, NULL), "fish", 4) == 0; #else false; #endif @@ -876,7 +876,7 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu // Failed, probably 'shell' is not executable. if (!silent) { msg_puts(_("\nshell failed to start: ")); - msg_outtrans((char *)os_strerror(status)); + msg_outtrans(os_strerror(status)); msg_puts(": "); msg_outtrans(prog); msg_putchar('\n'); @@ -1180,7 +1180,7 @@ static size_t tokenize(const char *const str, char **const argv) } argc++; - p = (const char *)skipwhite((p + len)); + p = skipwhite((p + len)); } return argc; diff --git a/src/nvim/path.c b/src/nvim/path.c index 973e5eaec4..368f3feb27 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -641,7 +641,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in while (*path_end != NUL) { // May ignore a wildcard that has a backslash before it; it will // be removed by rem_backslash() or file_pat_to_reg_pat() below. - if (path_end >= path + wildoff && rem_backslash((char *)path_end)) { + if (path_end >= path + wildoff && rem_backslash(path_end)) { *p++ = *path_end++; } else if (vim_ispathsep_nocolon(*path_end)) { if (e != NULL) { @@ -651,12 +651,12 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in } else if (path_end >= path + wildoff && (vim_strchr("*?[{~$", (uint8_t)(*path_end)) != NULL #ifndef MSWIN - || (!p_fic && (flags & EW_ICASE) && mb_isalpha(utf_ptr2char((char *)path_end))) + || (!p_fic && (flags & EW_ICASE) && mb_isalpha(utf_ptr2char(path_end))) #endif )) { // NOLINT(whitespace/parens) e = p; } - len = (size_t)(utfc_ptr2len((char *)path_end)); + len = (size_t)(utfc_ptr2len(path_end)); memcpy(p, path_end, len); p += len; path_end += len; @@ -727,9 +727,9 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in char *dirpath = (*buf == NUL ? "." : buf); if (os_file_is_readable(dirpath) && os_scandir(&dir, dirpath)) { // Find all matching entries. - char *name; + const char *name; scandir_next_with_dots(NULL); // initialize - while (!got_int && (name = (char *)scandir_next_with_dots(&dir)) != NULL) { + while (!got_int && (name = scandir_next_with_dots(&dir)) != NULL) { if ((name[0] != '.' || starts_with_dot || ((flags & EW_DODOT) @@ -973,7 +973,7 @@ static void uniquefy_paths(garray_T *gap, char *pattern) for (int i = 0; i < gap->ga_len && !got_int; i++) { char *path = fnames[i]; int is_in_curdir; - char *dir_end = (char *)gettail_dir((const char *)path); + const char *dir_end = gettail_dir(path); char *pathsep_p; char *path_cutoff; @@ -1911,8 +1911,8 @@ void path_fix_case(char *name) return; } - char *entry; - while ((entry = (char *)os_scandir_next(&dir))) { + const char *entry; + while ((entry = os_scandir_next(&dir))) { // Only accept names that differ in case and are the same byte // length. TODO: accept different length name. if (STRICMP(tail, entry) == 0 && strlen(tail) == strlen(entry)) { @@ -2021,7 +2021,7 @@ int pathcmp(const char *p, const char *q, int maxlen) // ignore a trailing slash, but not "//" or ":/" if (c2 == NUL && i > 0 - && !after_pathsep((char *)s, (char *)s + i) + && !after_pathsep(s, s + i) #ifdef BACKSLASH_IN_FILENAME && (c1 == '/' || c1 == '\\') #else @@ -2354,11 +2354,11 @@ int append_path(char *path, const char *to_append, size_t max_len) /// @return FAIL for failure, OK for success. static int path_to_absolute(const char *fname, char *buf, size_t len, int force) { - char *p; + const char *p; *buf = NUL; char *relative_directory = xmalloc(len); - char *end_of_path = (char *)fname; + const char *end_of_path = fname; // expand it if forced or not an absolute path if (force || !path_is_absolute(fname)) { diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 9f6181f986..262d87ba61 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -244,10 +244,10 @@ typedef struct vgr_args_S { # include "quickfix.c.generated.h" #endif -static char *e_no_more_items = N_("E553: No more items"); -static char *e_current_quickfix_list_was_changed = +static const char *e_no_more_items = N_("E553: No more items"); +static const char *e_current_quickfix_list_was_changed = N_("E925: Current quickfix list was changed"); -static char *e_current_location_list_was_changed = +static const char *e_current_location_list_was_changed = N_("E926: Current location list was changed"); // Quickfix window check helper macro @@ -374,8 +374,8 @@ int qf_init(win_T *wp, const char *restrict efile, char *restrict errorformat, i qi = ll_get_or_alloc_list(wp); } - return qf_init_ext(qi, qi->qf_curlist, (char *)efile, curbuf, NULL, errorformat, - newlist, (linenr_T)0, (linenr_T)0, (char *)qf_title, enc); + return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat, + newlist, (linenr_T)0, (linenr_T)0, qf_title, enc); } // Maximum number of bytes allowed per line while reading an errorfile. @@ -531,7 +531,7 @@ static int efm_to_regpat(const char *efm, int len, efm_T *fmt_ptr, char *regpat) } } if (idx < FMT_PATTERNS) { - ptr = efmpat_to_regpat((char *)efmp, ptr, fmt_ptr, idx, round); + ptr = efmpat_to_regpat(efmp, ptr, fmt_ptr, idx, round); if (ptr == NULL) { return FAIL; } @@ -1241,7 +1241,7 @@ static char *qf_cmdtitle(char *cmd) { static char qftitle_str[IOSIZE]; - snprintf((char *)qftitle_str, IOSIZE, ":%s", cmd); + snprintf(qftitle_str, IOSIZE, ":%s", cmd); return qftitle_str; } @@ -2385,7 +2385,7 @@ static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr, int dir, int * { qfline_T *qf_ptr = qfl->qf_ptr; int qf_idx = qfl->qf_index; - char *err = e_no_more_items; + const char *err = e_no_more_items; while (errornr--) { qfline_T *prev_qf_ptr = qf_ptr; @@ -3228,7 +3228,7 @@ void qf_list(exarg_T *eap) static void qf_fmt_text(garray_T *gap, const char *restrict text) FUNC_ATTR_NONNULL_ALL { - const char *p = (char *)text; + const char *p = text; while (*p != NUL) { if (*p == '\n') { @@ -3281,7 +3281,7 @@ static void qf_msg(qf_info_T *qi, int which, char *lead) int count = qi->qf_lists[which].qf_count; char buf[IOSIZE]; - vim_snprintf((char *)buf, IOSIZE, _("%serror list %d of %d; %d errors "), + vim_snprintf(buf, IOSIZE, _("%serror list %d of %d; %d errors "), lead, which + 1, qi->qf_listcount, @@ -3506,7 +3506,7 @@ static char *qf_types(int c, int nr) } static char buf[20]; - snprintf((char *)buf, sizeof(buf), "%s %3d", p, nr); + snprintf(buf, sizeof(buf), "%s %3d", p, nr); return buf; } @@ -3885,7 +3885,7 @@ static buf_T *qf_find_buf(qf_info_T *qi) } /// Process the 'quickfixtextfunc' option value. -void qf_process_qftf_option(char **errmsg) +void qf_process_qftf_option(const char **errmsg) { if (option_set_callback_func(p_qftf, &qftf_cb) == FAIL) { *errmsg = e_invarg; @@ -4286,11 +4286,11 @@ static char *make_get_fullcmd(const char *makecmd, const char *fname) len += strlen(p_sp) + strlen(fname) + 3; } char *const cmd = xmalloc(len); - snprintf(cmd, len, "%s%s%s", p_shq, (char *)makecmd, p_shq); + snprintf(cmd, len, "%s%s%s", p_shq, makecmd, p_shq); // If 'shellpipe' empty: don't redirect to 'errorfile'. if (*p_sp != NUL) { - append_redir(cmd, len, p_sp, (char *)fname); + append_redir(cmd, len, p_sp, fname); } // Display the fully formed command. Output a newline if there's something @@ -5795,28 +5795,19 @@ static int get_qfline_items(qfline_T *qfp, list_T *list) buf[0] = qfp->qf_type; buf[1] = NUL; if (tv_dict_add_nr(dict, S_LEN("bufnr"), (varnumber_T)bufnum) == FAIL - || (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum) - == FAIL) - || (tv_dict_add_nr(dict, S_LEN("end_lnum"), (varnumber_T)qfp->qf_end_lnum) - == FAIL) + || (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("end_lnum"), (varnumber_T)qfp->qf_end_lnum) == FAIL) || (tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)qfp->qf_col) == FAIL) - || (tv_dict_add_nr(dict, S_LEN("end_col"), (varnumber_T)qfp->qf_end_col) - == FAIL) - || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol) - == FAIL) + || (tv_dict_add_nr(dict, S_LEN("end_col"), (varnumber_T)qfp->qf_end_col) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol) == FAIL) || (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL) - || (tv_dict_add_str(dict, S_LEN("module"), - (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module)) - == FAIL) - || (tv_dict_add_str(dict, S_LEN("pattern"), - (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern)) + || (tv_dict_add_str(dict, S_LEN("module"), (qfp->qf_module == NULL ? "" : qfp->qf_module)) == FAIL) - || (tv_dict_add_str(dict, S_LEN("text"), - (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text)) + || (tv_dict_add_str(dict, S_LEN("pattern"), (qfp->qf_pattern == NULL ? "" : qfp->qf_pattern)) == FAIL) - || (tv_dict_add_str(dict, S_LEN("type"), (const char *)buf) == FAIL) - || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid) - == FAIL)) { + || (tv_dict_add_str(dict, S_LEN("text"), (qfp->qf_text == NULL ? "" : qfp->qf_text)) == FAIL) + || (tv_dict_add_str(dict, S_LEN("type"), buf) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid) == FAIL)) { // tv_dict_add* fail only if key already exist, but this is a newly // allocated dictionary which is thus guaranteed to have no existing keys. abort(); @@ -6039,8 +6030,7 @@ static int qf_getprop_qfidx(qf_info_T *qi, dict_T *what) qf_idx = INVALID_QFIDX; } } - } else if (di->di_tv.v_type == VAR_STRING - && strequal((const char *)di->di_tv.vval.v_string, "$")) { + } else if (di->di_tv.v_type == VAR_STRING && strequal(di->di_tv.vval.v_string, "$")) { // Get the last quickfix list number qf_idx = qi->qf_listcount - 1; } else { @@ -6069,7 +6059,7 @@ static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *r int status = OK; if (flags & QF_GETLIST_TITLE) { - status = tv_dict_add_str(retdict, S_LEN("title"), (const char *)""); + status = tv_dict_add_str(retdict, S_LEN("title"), ""); } if ((status == OK) && (flags & QF_GETLIST_ITEMS)) { list_T *l = tv_list_alloc(kListLenMayKnow); @@ -6082,7 +6072,7 @@ static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *r status = tv_dict_add_nr(retdict, S_LEN("winid"), qf_winid(qi)); } if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) { - status = tv_dict_add_str(retdict, S_LEN("context"), (const char *)""); + status = tv_dict_add_str(retdict, S_LEN("context"), ""); } if ((status == OK) && (flags & QF_GETLIST_ID)) { status = tv_dict_add_nr(retdict, S_LEN("id"), 0); @@ -6112,8 +6102,7 @@ static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *r /// Return the quickfix list title as 'title' in retdict static int qf_getprop_title(qf_list_T *qfl, dict_T *retdict) { - return tv_dict_add_str(retdict, S_LEN("title"), - (const char *)qfl->qf_title); + return tv_dict_add_str(retdict, S_LEN("title"), qfl->qf_title); } // Returns the identifier of the window used to display files from a location @@ -6462,8 +6451,7 @@ static int qf_setprop_get_qfidx(const qf_info_T *qi, const dict_T *what, int act } else if (action != ' ') { *newlist = false; // use the specified list } - } else if (di->di_tv.v_type == VAR_STRING - && strequal((const char *)di->di_tv.vval.v_string, "$")) { + } else if (di->di_tv.v_type == VAR_STRING && strequal(di->di_tv.vval.v_string, "$")) { if (!qf_stack_empty(qi)) { qf_idx = qi->qf_listcount - 1; } else if (*newlist) { @@ -7124,7 +7112,7 @@ static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char while (*p != NUL && !got_int) { copy_option_part(&p, NameBuff, MAXPATHL, ","); - hgr_search_files_in_dir(qfl, NameBuff, p_regmatch, (char *)lang); + hgr_search_files_in_dir(qfl, NameBuff, p_regmatch, lang); } } @@ -7304,7 +7292,7 @@ void f_getqflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) FUNC_ATTR_NONNULL_ARG(2, 3) { - static char *e_invact = N_("E927: Invalid action: '%s'"); + static const char *e_invact = N_("E927: Invalid action: '%s'"); const char *title = NULL; char action = ' '; static int recursive = 0; diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 0b9a9bbdec..94796f0ed3 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -97,31 +97,31 @@ static int toggle_Magic(int x) #define EMSG2_RET_NULL(m, c) \ return (semsg((m), (c) ? "" : "\\"), rc_did_emsg = true, (void *)NULL) #define EMSG3_RET_NULL(m, c, a) \ - return (semsg((const char *)(m), (c) ? "" : "\\", (a)), rc_did_emsg = true, (void *)NULL) + return (semsg((m), (c) ? "" : "\\", (a)), rc_did_emsg = true, (void *)NULL) #define EMSG2_RET_FAIL(m, c) \ return (semsg((m), (c) ? "" : "\\"), rc_did_emsg = true, FAIL) #define EMSG_ONE_RET_NULL EMSG2_RET_NULL(_("E369: invalid item in %s%%[]"), reg_magic == MAGIC_ALL) #define MAX_LIMIT (32767L << 16L) -static char e_missingbracket[] = N_("E769: Missing ] after %s["); -static char e_reverse_range[] = N_("E944: Reverse range in character class"); -static char e_large_class[] = N_("E945: Range too large in character class"); -static char e_unmatchedpp[] = N_("E53: Unmatched %s%%("); -static char e_unmatchedp[] = N_("E54: Unmatched %s("); -static char e_unmatchedpar[] = N_("E55: Unmatched %s)"); -static char e_z_not_allowed[] = N_("E66: \\z( not allowed here"); -static char e_z1_not_allowed[] = N_("E67: \\z1 - \\z9 not allowed here"); -static char e_missing_sb[] = N_("E69: Missing ] after %s%%["); -static char e_empty_sb[] = N_("E70: Empty %s%%[]"); -static char e_recursive[] = N_("E956: Cannot use pattern recursively"); -static char e_regexp_number_after_dot_pos_search_chr[] +static const char e_missingbracket[] = N_("E769: Missing ] after %s["); +static const char e_reverse_range[] = N_("E944: Reverse range in character class"); +static const char e_large_class[] = N_("E945: Range too large in character class"); +static const char e_unmatchedpp[] = N_("E53: Unmatched %s%%("); +static const char e_unmatchedp[] = N_("E54: Unmatched %s("); +static const char e_unmatchedpar[] = N_("E55: Unmatched %s)"); +static const char e_z_not_allowed[] = N_("E66: \\z( not allowed here"); +static const char e_z1_not_allowed[] = N_("E67: \\z1 - \\z9 not allowed here"); +static const char e_missing_sb[] = N_("E69: Missing ] after %s%%["); +static const char e_empty_sb[] = N_("E70: Empty %s%%[]"); +static const char e_recursive[] = N_("E956: Cannot use pattern recursively"); +static const char e_regexp_number_after_dot_pos_search_chr[] = N_("E1204: No Number allowed after .: '\\%%%c'"); -static char e_nfa_regexp_missing_value_in_chr[] +static const char e_nfa_regexp_missing_value_in_chr[] = N_("E1273: (NFA regexp) missing value in '\\%%%c'"); -static char e_atom_engine_must_be_at_start_of_pattern[] +static const char e_atom_engine_must_be_at_start_of_pattern[] = N_("E1281: Atom '\\%%#=%c' must be at the start of the pattern"); -static char e_substitute_nesting_too_deep[] = N_("E1290: substitute nesting too deep"); +static const char e_substitute_nesting_too_deep[] = N_("E1290: substitute nesting too deep"); #define NOT_MULTI 0 #define MULTI_ONE 1 @@ -2237,12 +2237,12 @@ list_T *reg_submatch_list(int no) tv_list_append_string(list, s, ecol); } } else { - s = (const char *)rsm.sm_match->startp[no]; + s = rsm.sm_match->startp[no]; if (s == NULL || rsm.sm_match->endp[no] == NULL) { return NULL; } list = tv_list_alloc(1); - tv_list_append_string(list, s, (const char *)rsm.sm_match->endp[no] - s); + tv_list_append_string(list, s, rsm.sm_match->endp[no] - s); } tv_list_ref(list); diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 950814880b..260d40a202 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -244,10 +244,10 @@ static int nfa_classcodes[] = { NFA_UPPER, NFA_NUPPER }; -static char e_nul_found[] = N_("E865: (NFA) Regexp end encountered prematurely"); -static char e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c"); -static char e_ill_char_class[] = N_("E877: (NFA regexp) Invalid character class: %" PRId64); -static char e_value_too_large[] = N_("E951: \\% value too large"); +static const char e_nul_found[] = N_("E865: (NFA) Regexp end encountered prematurely"); +static const char e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c"); +static const char e_ill_char_class[] = N_("E877: (NFA regexp) Invalid character class: %" PRId64); +static const char e_value_too_large[] = N_("E951: \\% value too large"); // Since the out pointers in the list are always // uninitialized, we use the pointers themselves @@ -1918,7 +1918,7 @@ static int nfa_regatom(void) case Magic('|'): case Magic('&'): case Magic(')'): - semsg(_(e_misplaced), (int64_t)no_Magic(c)); // -V1037 + semsg(_(e_misplaced), (char)no_Magic(c)); // -V1037 return FAIL; case Magic('='): @@ -1928,7 +1928,7 @@ static int nfa_regatom(void) case Magic('*'): case Magic('{'): // these should follow an atom, not form an atom - semsg(_(e_misplaced), (int64_t)no_Magic(c)); + semsg(_(e_misplaced), (char)no_Magic(c)); return FAIL; case Magic('~'): { @@ -3274,7 +3274,7 @@ static void nfa_set_code(int c) } static FILE *log_fd; -static uint8_t e_log_open_failed[] = +static const uint8_t e_log_open_failed[] = N_("Could not open temporary log file for writing, displaying on stderr... "); // Print the postfix notation of the current regexp. @@ -5252,9 +5252,9 @@ static regsubs_T *addstate_here(nfa_list_T *l, nfa_state_T *state, regsubs_T *su } // Check character class "class" against current character c. -static int check_char_class(int class, int c) +static int check_char_class(int cls, int c) { - switch (class) { + switch (cls) { case NFA_CLASS_ALNUM: if (c >= 1 && c < 128 && isalnum(c)) { return OK; @@ -5353,7 +5353,7 @@ static int check_char_class(int class, int c) default: // should not be here :P - siemsg(_(e_ill_char_class), (int64_t)class); + siemsg(_(e_ill_char_class), (int64_t)cls); return FAIL; } return FAIL; diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 5d1c104dc5..1e39b58543 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -910,7 +910,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) } const char *insp = NULL; const char *after_insp = NULL; - for (const char *entry = (const char *)p_rtp; *entry != NUL;) { + for (const char *entry = p_rtp; *entry != NUL;) { const char *cur_entry = entry; copy_option_part((char **)&entry, buf, MAXPATHL, ","); @@ -945,7 +945,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) if (insp == NULL) { // Both "fname" and "after" not found, append at the end. - insp = (const char *)p_rtp + strlen(p_rtp); + insp = p_rtp + strlen(p_rtp); } // check if rtp/pack/name/start/name/after exists @@ -966,7 +966,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) // We now have 'rtp' parts: {keep}{keep_after}{rest}. // Create new_rtp, first: {keep},{fname} - size_t keep = (size_t)(insp - (const char *)p_rtp); + size_t keep = (size_t)(insp - p_rtp); memmove(new_rtp, p_rtp, keep); size_t new_rtp_len = keep; if (*insp == NUL) { @@ -979,7 +979,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) } if (afterlen > 0 && after_insp != NULL) { - size_t keep_after = (size_t)(after_insp - (const char *)p_rtp); + size_t keep_after = (size_t)(after_insp - p_rtp); // Add to new_rtp: {keep},{fname}{keep_after},{afterdir} memmove(new_rtp + new_rtp_len, p_rtp + keep, keep_after - keep); @@ -1039,7 +1039,7 @@ static int load_pack_plugin(bool opt, char *fname) do_cmdline_cmd("augroup filetypedetect"); vim_snprintf(pat, len, ftpat, ffname); source_all_matches(pat); - vim_snprintf((char *)pat, len, "%s/ftdetect/*.lua", ffname); // NOLINT + vim_snprintf(pat, len, "%s/ftdetect/*.lua", ffname); // NOLINT source_all_matches(pat); do_cmdline_cmd("augroup END"); } @@ -1061,7 +1061,7 @@ static void add_pack_plugin(bool opt, char *fname, void *cookie) char *buf = xmalloc(MAXPATHL); bool found = false; - const char *p = (const char *)p_rtp; + const char *p = p_rtp; while (*p != NUL) { copy_option_part((char **)&p, buf, MAXPATHL, ","); if (path_fnamecmp(buf, fname) == 0) { @@ -1784,7 +1784,7 @@ static bool concat_continued_line(garray_T *const ga, const int init_growsize, c size_t len) FUNC_ATTR_NONNULL_ALL { - const char *const line = skipwhite_len((char *)p, len); + const char *const line = skipwhite_len(p, len); len -= (size_t)(line - p); // Skip lines starting with '\" ', concat lines starting with '\' if (len >= 3 && strncmp(line, "\"\\ ", 3) == 0) { @@ -1832,7 +1832,7 @@ static char *get_str_line(int c, void *cookie, int indent, bool do_concat) if (!concat_continued_line(&ga, 400, line, (size_t)(next_eol - line))) { break; } - eol = (char *)next_eol; + eol = next_eol; } } ga_append(&ga, NUL); @@ -1878,7 +1878,7 @@ static int source_using_linegetter(void *cookie, LineGetter fgetline, const char if (save_sourcing_name == NULL) { sname = (char *)traceback_name; } else { - snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf), + snprintf(sourcing_name_buf, sizeof(sourcing_name_buf), "%s called at %s:%" PRIdLINENR, traceback_name, save_sourcing_name, save_sourcing_lnum); sname = sourcing_name_buf; @@ -1925,12 +1925,10 @@ static void cmd_source_buffer(const exarg_T *const eap) .offset = 0, }; if (curbuf->b_fname - && path_with_extension((const char *)curbuf->b_fname, "lua")) { - nlua_source_using_linegetter(get_str_line, (void *)&cookie, - ":source (no file)"); + && path_with_extension(curbuf->b_fname, "lua")) { + nlua_source_using_linegetter(get_str_line, (void *)&cookie, ":source (no file)"); } else { - source_using_linegetter((void *)&cookie, get_str_line, - ":source (no file)"); + source_using_linegetter((void *)&cookie, get_str_line, ":source (no file)"); } ga_clear(&ga); } @@ -2134,12 +2132,12 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) cookie.conv.vc_type = CONV_NONE; // no conversion - if (path_with_extension((const char *)fname_exp, "lua")) { + if (path_with_extension(fname_exp, "lua")) { const sctx_T current_sctx_backup = current_sctx; current_sctx.sc_sid = SID_LUA; current_sctx.sc_lnum = 0; // Source the file as lua - nlua_exec_file((const char *)fname_exp); + nlua_exec_file(fname_exp); current_sctx = current_sctx_backup; } else { // Read the first line so we can check for a UTF-8 BOM. diff --git a/src/nvim/search.c b/src/nvim/search.c index 525cec8b02..694c4cad52 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1468,7 +1468,7 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char *pat) // when adding lines the matching line may be empty but it is not // ignored because we are interested in the next line -- Acevedo if (compl_status_adding() && !compl_status_sol()) { - if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) { + if (mb_strcmp_ic((bool)p_ic, p, pat) == 0) { return OK; } } else if (*p != NUL) { // Ignore empty lines. @@ -2233,10 +2233,10 @@ int check_linecomment(const char *line) const char *p = line; // scan from start // skip Lispish one-line comments if (curbuf->b_p_lisp) { - if (vim_strchr((char *)p, ';') != NULL) { // there may be comments + if (vim_strchr(p, ';') != NULL) { // there may be comments bool in_str = false; // inside of string - while ((p = strpbrk((char *)p, "\";")) != NULL) { + while ((p = strpbrk(p, "\";")) != NULL) { if (*p == '"') { if (in_str) { if (*(p - 1) != '\\') { // skip escaped quote @@ -2258,7 +2258,7 @@ int check_linecomment(const char *line) p = NULL; } } else { - while ((p = vim_strchr((char *)p, '/')) != NULL) { + while ((p = vim_strchr(p, '/')) != NULL) { // Accept a double /, unless it's preceded with * and followed by *, // because * / / * is an end and start of a C comment. Only // accept the position if it is not inside a string. @@ -2777,21 +2777,21 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } dict = argvars[0].vval.v_dict; - di = tv_dict_find(dict, (const char *)"timeout", -1); + di = tv_dict_find(dict, "timeout", -1); if (di != NULL) { timeout = (long)tv_get_number_chk(&di->di_tv, &error); if (error) { return; } } - di = tv_dict_find(dict, (const char *)"maxcount", -1); + di = tv_dict_find(dict, "maxcount", -1); if (di != NULL) { maxcount = (int)tv_get_number_chk(&di->di_tv, &error); if (error) { return; } } - di = tv_dict_find(dict, (const char *)"recompute", -1); + di = tv_dict_find(dict, "recompute", -1); if (di != NULL) { recompute = tv_get_number_chk(&di->di_tv, &error); if (error) { @@ -2805,7 +2805,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } } - di = tv_dict_find(dict, (const char *)"pos", -1); + di = tv_dict_find(dict, "pos", -1); if (di != NULL) { if (di->di_tv.v_type != VAR_LIST) { semsg(_(e_invarg2), "pos"); @@ -3036,8 +3036,8 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s // Loop through fuzpat and str looking for a match bool first_match = true; while (*fuzpat != NUL && *str != NUL) { - const int c1 = utf_ptr2char((char *)fuzpat); - const int c2 = utf_ptr2char((char *)str); + const int c1 = utf_ptr2char(fuzpat); + const int c2 = utf_ptr2char(str); // Found match if (mb_tolower(c1) == mb_tolower(c2)) { @@ -3055,7 +3055,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s // Recursive call that "skips" this match uint32_t recursiveMatches[MAX_FUZZY_MATCHES]; int recursiveScore = 0; - const char *const next_char = (char *)str + utfc_ptr2len((char *)str); + const char *const next_char = str + utfc_ptr2len(str); if (fuzzy_match_recursive(fuzpat, next_char, strIdx + 1, &recursiveScore, strBegin, strLen, matches, recursiveMatches, sizeof(recursiveMatches) / sizeof(recursiveMatches[0]), nextMatch, @@ -3227,7 +3227,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat // For a dict, either use the specified key to lookup the string or // use the specified callback function to get the string. if (key != NULL) { - itemstr = tv_dict_get_string(tv->vval.v_dict, (const char *)key, false); + itemstr = tv_dict_get_string(tv->vval.v_dict, key, false); } else { typval_T argv[2]; @@ -3257,7 +3257,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat if (retmatchpos) { items[match_count].lmatchpos = tv_list_alloc(kListLenMayKnow); int j = 0; - const char *p = (char *)str; + const char *p = str; while (*p != NUL) { if (!ascii_iswhite(utf_ptr2char(p)) || matchseq) { tv_list_append_number(items[match_count].lmatchpos, matches[j]); @@ -4015,7 +4015,7 @@ search_line: curwin->w_cursor.lnum = lnum; check_cursor(); } else { - if (!GETFILE_SUCCESS(getfile(0, (char *)files[depth].name, NULL, true, + if (!GETFILE_SUCCESS(getfile(0, files[depth].name, NULL, true, files[depth].lnum, false))) { break; // failed to jump to file } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 3f816d0172..2d5eee7eec 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1491,7 +1491,7 @@ static char *shada_filename(const char *file) // If shell is not performing them then they should be done in main.c // where arguments are parsed, *not here*. expand_env((char *)file, &(NameBuff[0]), MAXPATHL); - file = (const char *)&(NameBuff[0]); + file = &(NameBuff[0]); } } return xstrdup(file); @@ -1548,9 +1548,9 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntr if (!HASHITEM_EMPTY(hi)) { \ todo--; \ dictitem_T *const di = TV_DICT_HI2DI(hi); \ - const size_t key_len = strlen((const char *)hi->hi_key); \ + const size_t key_len = strlen(hi->hi_key); \ msgpack_pack_str(spacker, key_len); \ - msgpack_pack_str_body(spacker, (const char *)hi->hi_key, key_len); \ + msgpack_pack_str_body(spacker, hi->hi_key, key_len); \ if (encode_vim_to_msgpack(spacker, &di->di_tv, \ _("additional data of ShaDa " what)) \ == FAIL) { \ @@ -2208,7 +2208,7 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re shada_free_shada_entry(&entry); break; } - const char *const fname = (const char *)entry.data.filemark.fname; + const char *const fname = entry.data.filemark.fname; khiter_t k; int kh_ret; k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret); @@ -2714,17 +2714,17 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef const char *fname; if (fm.fmark.fnum == 0) { assert(fm.fname != NULL); - if (shada_removable((const char *)fm.fname)) { + if (shada_removable(fm.fname)) { continue; } - fname = (const char *)fm.fname; + fname = fm.fname; } else { const buf_T *const buf = buflist_findnr(fm.fmark.fnum); if (buf == NULL || buf->b_ffname == NULL || in_bufset(&removable_bufs, buf)) { continue; } - fname = (const char *)buf->b_ffname; + fname = buf->b_ffname; } const PossiblyFreedShadaEntry pf_entry = { .can_free_entry = false, @@ -2761,7 +2761,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef continue; } const void *local_marks_iter = NULL; - const char *const fname = (const char *)buf->b_ffname; + const char *const fname = buf->b_ffname; khiter_t k; int kh_ret; k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret); @@ -4009,7 +4009,7 @@ static bool shada_removable(const char *name) char part[MAXPATHL + 1]; bool retval = false; - char *new_name = home_replace_save(NULL, (char *)name); + char *new_name = home_replace_save(NULL, name); for (p = p_shada; *p;) { (void)copy_option_part(&p, part, ARRAY_SIZE(part), ", "); if (part[0] == 'r') { diff --git a/src/nvim/sign.c b/src/nvim/sign.c index d555b8bf4a..50a55ddd5c 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -100,7 +100,7 @@ static signgroup_T *sign_group_ref(const char *groupname) signgroup_T *group; hash = hash_hash(groupname); - hi = hash_lookup(&sg_table, (char *)groupname, strlen(groupname), hash); + hi = hash_lookup(&sg_table, groupname, strlen(groupname), hash); if (HASHITEM_EMPTY(hi)) { // new group group = xmalloc(offsetof(signgroup_T, sg_name) + strlen(groupname) + 1); @@ -156,7 +156,7 @@ static int sign_group_get_next_signid(buf_T *buf, const char *groupname) int found = false; if (groupname != NULL) { - hashitem_T *hi = hash_find(&sg_table, (char *)groupname); + hashitem_T *hi = hash_find(&sg_table, groupname); if (HASHITEM_EMPTY(hi)) { return id; } @@ -174,7 +174,7 @@ static int sign_group_get_next_signid(buf_T *buf, const char *groupname) // Check whether this sign is already placed in the buffer found = true; FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (id == sign->se_id && sign_in_group(sign, (char *)groupname)) { + if (id == sign->se_id && sign_in_group(sign, groupname)) { found = false; // sign identifier is in use break; } @@ -442,7 +442,7 @@ static linenr_T buf_change_sign_type(buf_T *buf, int markId, const char *group, sign_entry_T *sign; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->se_id == markId && sign_in_group(sign, (char *)group)) { + if (sign->se_id == markId && sign_in_group(sign, group)) { sign->se_typenr = typenr; sign->se_priority = prio; sign_sort_by_prio_on_line(buf, sign); @@ -491,8 +491,8 @@ SignTextAttrs *sign_get_attr(int idx, SignTextAttrs sattrs[], int max_signs) /// @param lnum Line in which to search /// @param sattrs Output array for attrs /// @return Number of signs of which attrs were found -int buf_get_signattrs(buf_T *buf, linenr_T lnum, SignTextAttrs sattrs[], HlPriAttr *num_attrs, - HlPriAttr *line_attrs, HlPriAttr *cul_attrs) +int buf_get_signattrs(buf_T *buf, linenr_T lnum, SignTextAttrs sattrs[], HlPriId *num_id, + HlPriId *line_id, HlPriId *cul_id) { sign_entry_T *sign; @@ -517,21 +517,21 @@ int buf_get_signattrs(buf_T *buf, linenr_T lnum, SignTextAttrs sattrs[], HlPriAt if (sp->sn_text != NULL && sattr_matches < SIGN_SHOW_MAX) { sattrs[sattr_matches++] = (SignTextAttrs) { .text = sp->sn_text, - .hl_attr_id = sp->sn_text_hl == 0 ? 0 : syn_id2attr(sp->sn_text_hl), + .hl_id = sp->sn_text_hl, .priority = sign->se_priority }; } - struct { HlPriAttr *dest; int hl; } cattrs[] = { - { line_attrs, sp->sn_line_hl }, - { num_attrs, sp->sn_num_hl }, - { cul_attrs, sp->sn_cul_hl }, + struct { HlPriId *dest; int hl; } cattrs[] = { + { line_id, sp->sn_line_hl }, + { num_id, sp->sn_num_hl }, + { cul_id, sp->sn_cul_hl }, { NULL, -1 }, }; for (int i = 0; cattrs[i].dest; i++) { if (cattrs[i].hl != 0 && sign->se_priority >= cattrs[i].dest->priority) { - *cattrs[i].dest = (HlPriAttr) { - .attr_id = syn_id2attr(cattrs[i].hl), + *cattrs[i].dest = (HlPriId) { + .hl_id = cattrs[i].hl, .priority = sign->se_priority }; } @@ -1085,23 +1085,17 @@ static int sign_place(int *sign_id, const char *sign_group, const char *sign_nam return FAIL; } if (*sign_id == 0) { - *sign_id = sign_group_get_next_signid(buf, (char *)sign_group); + *sign_id = sign_group_get_next_signid(buf, sign_group); } if (lnum > 0) { // ":sign place {id} line={lnum} name={name} file={fname}": // place a sign bool has_text_or_icon = sp->sn_text != NULL || sp->sn_icon != NULL; - buf_addsign(buf, - *sign_id, - (char *)sign_group, - prio, - lnum, - sp->sn_typenr, - has_text_or_icon); + buf_addsign(buf, *sign_id, sign_group, prio, lnum, sp->sn_typenr, has_text_or_icon); } else { // ":sign place {id} file={fname}": change sign type and/or priority - lnum = buf_change_sign_type(buf, *sign_id, (char *)sign_group, sp->sn_typenr, prio); + lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr, prio); } if (lnum > 0) { redraw_buf_line_later(buf, lnum, false); @@ -1585,7 +1579,7 @@ static void sign_getlist(const char *name, list_T *retlist) sign_T *sp = first_sign; if (name != NULL) { - sp = sign_find((char *)name, NULL); + sp = sign_find(name, NULL); if (sp == NULL) { return; } @@ -1633,7 +1627,7 @@ static void sign_get_placed_in_buf(buf_T *buf, linenr_T lnum, int sign_id, const tv_dict_add_list(d, S_LEN("signs"), l); FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (!sign_in_group(sign, (char *)sign_group)) { + if (!sign_in_group(sign, sign_group)) { continue; } if ((lnum == 0 && sign_id == 0) @@ -2154,7 +2148,7 @@ static int sign_place_from_dict(typval_T *id_tv, typval_T *group_tv, typval_T *n { int sign_id = 0; char *group = NULL; - char *sign_name = NULL; + const char *sign_name = NULL; buf_T *buf = NULL; dictitem_T *di; linenr_T lnum = 0; @@ -2213,7 +2207,7 @@ static int sign_place_from_dict(typval_T *id_tv, typval_T *group_tv, typval_T *n if (name_tv == NULL) { goto cleanup; } - sign_name = (char *)tv_get_string_chk(name_tv); + sign_name = tv_get_string_chk(name_tv); if (sign_name == NULL) { goto cleanup; } @@ -2313,7 +2307,7 @@ static void sign_undefine_multiple(list_T *l, list_T *retlist) TV_LIST_ITER_CONST(l, li, { retval = -1; name = (char *)tv_get_string_chk(TV_LIST_ITEM_TV(li)); - if (name != NULL && (sign_undefine_by_name((char *)name) == OK)) { + if (name != NULL && (sign_undefine_by_name(name) == OK)) { retval = 0; } tv_list_append_number(retlist, retval); diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index bae5344588..274158faad 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -35,7 +35,7 @@ struct sign_entry { /// Sign attributes. Used by the screen refresh routines. typedef struct { char *text; - int hl_attr_id; + int hl_id; int priority; } SignTextAttrs; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 9108059b4d..a14a02b9f7 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -1316,7 +1316,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att // Copy the line into "buf" and append the start of the next line if // possible. Note: this ml_get_buf() may make "line" invalid, check // for empty line first. - bool empty_line = *skipwhite((const char *)line) == NUL; + bool empty_line = *skipwhite(line) == NUL; STRCPY(buf, line); if (lnum < wp->w_buffer->b_ml.ml_line_count) { spell_cat_line(buf + strlen(buf), @@ -1743,7 +1743,7 @@ void count_common_word(slang_T *lp, char *word, int len, uint8_t count) wordcount_T *wc; hash_T hash = hash_hash(p); const size_t p_len = strlen(p); - hashitem_T *hi = hash_lookup(&lp->sl_wordcount, (const char *)p, p_len, hash); + hashitem_T *hi = hash_lookup(&lp->sl_wordcount, p, p_len, hash); if (HASHITEM_EMPTY(hi)) { wc = xmalloc(offsetof(wordcount_T, wc_word) + p_len + 1); memcpy(wc->wc_word, p, p_len + 1); @@ -2845,7 +2845,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) // Remove accents, if wanted. We actually remove all non-word characters. // But keep white space. int wordlen = 0; - for (const char *s = (char *)inword; *s != NUL;) { + for (const char *s = inword; *s != NUL;) { const char *t = s; int c = mb_cptr2char_adv(&s); if (slang->sl_rem_accents) { @@ -3129,9 +3129,9 @@ void ex_spellinfo(exarg_T *eap) for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; lpi++) { langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); msg_puts("file: "); - msg_puts((const char *)lp->lp_slang->sl_fname); + msg_puts(lp->lp_slang->sl_fname); msg_putchar('\n'); - const char *const p = (const char *)lp->lp_slang->sl_info; + const char *const p = lp->lp_slang->sl_info; if (p != NULL) { msg_puts(p); msg_putchar('\n'); @@ -3619,9 +3619,9 @@ bool valid_spellfile(const char *val) return true; } -char *did_set_spell_option(bool is_spellfile) +const char *did_set_spell_option(bool is_spellfile) { - char *errmsg = NULL; + const char *errmsg = NULL; if (is_spellfile) { int l = (int)strlen(curwin->w_s->b_p_spf); @@ -3646,7 +3646,7 @@ char *did_set_spell_option(bool is_spellfile) /// Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'. /// Return error message when failed, NULL when OK. -char *compile_cap_prog(synblock_T *synblock) +const char *compile_cap_prog(synblock_T *synblock) FUNC_ATTR_NONNULL_ALL { regprog_T *rp = synblock->b_cap_prog; diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index aa76dcbd32..d553910ece 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -322,11 +322,11 @@ enum { CF_UPPER = 0x02, }; -static char *e_spell_trunc = N_("E758: Truncated spell file"); -static char *e_illegal_character_in_word = N_("E1280: Illegal character in word"); -static char *e_afftrailing = N_("Trailing text in %s line %d: %s"); -static char *e_affname = N_("Affix name too long in %s line %d: %s"); -static char *msg_compressing = N_("Compressing word tree..."); +static const char *e_spell_trunc = N_("E758: Truncated spell file"); +static const char *e_illegal_character_in_word = N_("E1280: Illegal character in word"); +static const char *e_afftrailing = N_("Trailing text in %s line %d: %s"); +static const char *e_affname = N_("Affix name too long in %s line %d: %s"); +static const char *msg_compressing = N_("Compressing word tree..."); #define MAXLINELEN 500 // Maximum length in bytes of a line in a .aff // and .dic file. @@ -2137,7 +2137,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) if (itemcnt > 0) { if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) { // Setup for conversion from "ENC" to 'encoding'. - aff->af_enc = enc_canonize((char *)items[1]); + aff->af_enc = enc_canonize(items[1]); if (!spin->si_ascii && convert_setup(&spin->si_conv, aff->af_enc, p_enc) == FAIL) { smsg(_("Conversion in %s not supported: from %s to %s"), @@ -2240,13 +2240,13 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) { // We don't use the count, but do check that it's a number and // not COMPOUNDRULE mistyped. - if (atoi((char *)items[1]) == 0) { + if (atoi(items[1]) == 0) { smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"), fname, lnum, items[1]); } } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) { // Don't use the first rule if it is a number. - if (compflags != NULL || *skipdigits((char *)items[1]) != NUL) { + if (compflags != NULL || *skipdigits(items[1]) != NUL) { // Concatenate this string to previously defined ones, // using a slash to separate them. l = (int)strlen(items[1]) + 1; @@ -2263,21 +2263,21 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) } } else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2) && compmax == 0) { - compmax = atoi((char *)items[1]); + compmax = atoi(items[1]); if (compmax == 0) { smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"), fname, lnum, items[1]); } } else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2) && compminlen == 0) { - compminlen = atoi((char *)items[1]); + compminlen = atoi(items[1]); if (compminlen == 0) { smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"), fname, lnum, items[1]); } } else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2) && compsylmax == 0) { - compsylmax = atoi((char *)items[1]); + compsylmax = atoi(items[1]); if (compsylmax == 0) { smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"), fname, lnum, items[1]); @@ -2291,7 +2291,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) { compoptions |= COMP_CHECKTRIPLE; } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) { - if (atoi((char *)items[1]) == 0) { + if (atoi(items[1]) == 0) { smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"), fname, lnum, items[1]); } @@ -2344,7 +2344,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) // "S" flag on all but the last block, thus we check for that // and store it in ah_follows. xstrlcpy(key, items[1], AH_KEY_LEN); - hi = hash_find(tp, (char *)key); + hi = hash_find(tp, key); if (!HASHITEM_EMPTY(hi)) { cur_aff = HI2AH(hi); if (cur_aff->ah_combine != (*items[2] == 'Y')) { @@ -2421,7 +2421,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) } } - aff_todo = atoi((char *)items[3]); + aff_todo = atoi(items[3]); } else if ((strcmp(items[0], "PFX") == 0 || strcmp(items[0], "SFX") == 0) && aff_todo > 0 @@ -2640,7 +2640,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) // We simply concatenate all the MAP strings, separated by // slashes. - ga_concat(&spin->si_map, (char *)items[1]); + ga_concat(&spin->si_map, items[1]); ga_append(&spin->si_map, '/'); } } @@ -2670,7 +2670,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char *fname) sofoto = getroom_save(spin, items[1]); } else if (strcmp(items[0], "COMMON") == 0) { for (int i = 1; i < itemcnt; i++) { - if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords, (char *)items[i]))) { + if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords, items[i]))) { p = xstrdup(items[i]); hash_add(&spin->si_commonwords, p); } @@ -2906,7 +2906,7 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char *compflags // Find the flag in the hashtable. If it was used before, use // the existing ID. Otherwise add a new entry. xstrlcpy(key, prevp, (size_t)(p - prevp) + 1); - hi = hash_find(&aff->af_comp, (char *)key); + hi = hash_find(&aff->af_comp, key); if (!HASHITEM_EMPTY(hi)) { id = HI2CI(hi)->ci_newID; } else { @@ -3111,14 +3111,14 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile) spin->si_msg_count = 999999; // Read and ignore the first line: word count. - if (vim_fgets((char *)line, MAXLINELEN, fd) || !ascii_isdigit(*skipwhite((char *)line))) { + if (vim_fgets(line, MAXLINELEN, fd) || !ascii_isdigit(*skipwhite(line))) { semsg(_("E760: No word count in %s"), fname); } // Read all the lines in the file one by one. // The words are converted to 'encoding' here, before being added to // the hashtable. - while (!vim_fgets((char *)line, MAXLINELEN, fd) && !got_int) { + while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) { line_breakcheck(); lnum++; if (line[0] == '#' || line[0] == '/') { @@ -3137,7 +3137,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 = string_convert(&spin->si_conv, (char *)line, NULL); + pc = string_convert(&spin->si_conv, line, NULL); if (pc == NULL) { smsg(_("Conversion failure for word in %s line %d: %s"), fname, lnum, line); @@ -3329,7 +3329,7 @@ static int get_pfxlist(afffile_T *affile, char *afflist, char *store_afflist) // A flag is a postponed prefix flag if it appears in "af_pref" // and its ID is not zero. xstrlcpy(key, prevp, (size_t)(p - prevp) + 1); - hi = hash_find(&affile->af_pref, (char *)key); + hi = hash_find(&affile->af_pref, key); if (!HASHITEM_EMPTY(hi)) { id = HI2AH(hi)->ah_newID; if (id != 0) { @@ -3360,7 +3360,7 @@ static void get_compflags(afffile_T *affile, char *afflist, char *store_afflist) 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); - hi = hash_find(&affile->af_comp, (char *)key); + hi = hash_find(&affile->af_comp, key); if (!HASHITEM_EMPTY(hi)) { store_afflist[cnt++] = (char)(uint8_t)HI2CI(hi)->ci_newID; } @@ -4393,7 +4393,7 @@ static int write_vim_spell(spellinfo_T *spin, char *fname) // Form the <folchars> string first, we need to know its length. size_t l = 0; for (size_t i = 128; i < 256; i++) { - l += (size_t)utf_char2bytes(spelltab.st_fold[i], (char *)folchars + l); + l += (size_t)utf_char2bytes(spelltab.st_fold[i], folchars + l); } put_bytes(fd, 1 + 128 + 2 + l, 4); // <sectionlen> @@ -5561,7 +5561,7 @@ void spell_add_word(char *word, int len, SpellAddType what, int idx, bool undo) // since its flags sort before the one with WF_BANNED. fd = os_fopen(fname, "r"); if (fd != NULL) { - while (!vim_fgets((char *)line, MAXWLEN * 2, fd)) { + while (!vim_fgets(line, MAXWLEN * 2, fd)) { fpos = fpos_next; fpos_next = ftell(fd); if (fpos_next < 0) { @@ -5712,7 +5712,7 @@ static void init_spellfile(void) ((fname != NULL && strstr(path_tail(fname), ".ascii.") != NULL) ? "ascii" - : (const char *)spell_enc())); + : spell_enc())); set_option_value_give_err("spellfile", 0L, buf, OPT_LOCAL); break; } @@ -5851,7 +5851,7 @@ static void set_map_str(slang_T *lp, char *map) utf_char2bytes(headc, b + cl + 1); b[cl + 1 + headcl] = NUL; hash = hash_hash(b); - hi = hash_lookup(&lp->sl_map_hash, (const char *)b, strlen(b), hash); + hi = hash_lookup(&lp->sl_map_hash, b, strlen(b), hash); if (HASHITEM_EMPTY(hi)) { hash_add_item(&lp->sl_map_hash, hi, b, hash); } else { diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c index d28460a63d..e029d949fd 100644 --- a/src/nvim/spellsuggest.c +++ b/src/nvim/spellsuggest.c @@ -2794,7 +2794,7 @@ static void add_sound_suggest(suginfo_T *su, char *goodword, int score, langp_T // remember the words that have been done. hash_T hash = hash_hash(goodword); const size_t goodword_len = strlen(goodword); - hashitem_T *hi = hash_lookup(&slang->sl_sounddone, (const char *)goodword, goodword_len, hash); + hashitem_T *hi = hash_lookup(&slang->sl_sounddone, goodword, goodword_len, hash); if (HASHITEM_EMPTY(hi)) { sft = xmalloc(offsetof(sftword_T, sft_word) + goodword_len + 1); sft->sft_score = (int16_t)score; diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index ca92953b05..6c698f45be 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -1443,8 +1443,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // Store the current buffer number as a string variable vim_snprintf(buf_tmp, sizeof(buf_tmp), "%d", curbuf->b_fnum); set_internal_string_var("g:actual_curbuf", buf_tmp); - vim_snprintf((char *)win_tmp, sizeof(win_tmp), "%d", curwin->handle); - set_internal_string_var("g:actual_curwin", (char *)win_tmp); + vim_snprintf(win_tmp, sizeof(win_tmp), "%d", curwin->handle); + set_internal_string_var("g:actual_curwin", win_tmp); buf_T *const save_curbuf = curbuf; win_T *const save_curwin = curwin; @@ -1482,7 +1482,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // If the output of the expression needs to be evaluated // replace the %{} block with the result of evaluation if (reevaluate && str != NULL && *str != 0 - && strchr((const char *)str, '%') != NULL + && strchr(str, '%') != NULL && evaldepth < MAX_STL_EVAL_DEPTH) { size_t parsed_usefmt = (size_t)(block_start - usefmt); size_t str_length = strlen(str); @@ -1512,7 +1512,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n case STL_LINE: // Overload %l with v:lnum for 'statuscolumn' - if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) { + if (stcp != NULL) { if (wp->w_p_nu && !get_vim_var_nr(VV_VIRTNUM)) { num = (int)get_vim_var_nr(VV_LNUM); } @@ -1617,7 +1617,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n case STL_ROFLAG: case STL_ROFLAG_ALT: // Overload %r with v:relnum for 'statuscolumn' - if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) { + if (stcp != NULL) { if (wp->w_p_rnu && !get_vim_var_nr(VV_VIRTNUM)) { num = (int)get_vim_var_nr(VV_RELNUM); } @@ -1652,7 +1652,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n 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); + stl_items[curitem].minwid = -((stcp->use_cul ? HLF_CLF : HLF_FC) + 1); p = out_p; p[n] = NUL; } @@ -1668,9 +1668,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n } 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].minwid = -(sattr ? stcp->sign_cul_id ? stcp->sign_cul_id + : sattr->hl_id : (stcp->use_cul ? HLF_CLS : HLF_SC) + 1); } stl_items[curitem].type = Highlight; stl_items[curitem].start = out_p + strlen(buf_tmp); diff --git a/src/nvim/statusline_defs.h b/src/nvim/statusline_defs.h index 6835d62cdd..a9483216de 100644 --- a/src/nvim/statusline_defs.h +++ b/src/nvim/statusline_defs.h @@ -62,8 +62,8 @@ 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 num_attr; ///< default highlight attr + int sign_cul_id; ///< cursorline sign highlight id int truncate; ///< truncated width bool draw; ///< whether to draw the statuscolumn bool use_cul; ///< whether to use cursorline attrs diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 34b3c38103..14aa4ddc1a 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -946,10 +946,10 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap, t - str_arg); } if (fmt_spec == 'S') { - char *p1; + const char *p1; size_t i; - for (i = 0, p1 = (char *)str_arg; *p1; p1 += utfc_ptr2len(p1)) { + for (i = 0, p1 = str_arg; *p1; p1 += utfc_ptr2len(p1)) { size_t cell = (size_t)utf_ptr2cells(p1); if (precision_specified && i + cell > precision) { break; @@ -1468,7 +1468,7 @@ char *reverse_text(char *s) /// @return [allocated] Copy of the string. char *strrep(const char *src, const char *what, const char *rep) { - char *pos = (char *)src; + const char *pos = src; size_t whatlen = strlen(what); // Count occurrences diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 14fef19399..5094f0cd6f 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -58,7 +58,7 @@ static bool did_syntax_onoff = false; #define SPO_LC_OFF 6 // leading context offset #define SPO_COUNT 7 -static char e_illegal_arg[] = N_("E390: Illegal argument: %s"); +static const char e_illegal_arg[] = N_("E390: Illegal argument: %s"); // The patterns that are being searched for are stored in a syn_pattern. // A match item consists of one pattern. @@ -3643,7 +3643,7 @@ static bool syn_list_keywords(const int id, const hashtab_T *const ht, bool did_ prev_skipempty = (kp->flags & HL_SKIPEMPTY); } } - msg_outtrans((char *)kp->keyword); + msg_outtrans(kp->keyword); } } } @@ -3674,7 +3674,7 @@ static void syn_clear_keyword(int id, hashtab_T *ht) if (kp_next == NULL) { hash_remove(ht, hi); } else { - hi->hi_key = (char *)KE2HIKEY(kp_next); + hi->hi_key = KE2HIKEY(kp_next); } } else { kp_prev->ke_next = kp_next; @@ -3749,7 +3749,7 @@ static void add_keyword(char *const name, const int id, const int flags, hashtab_T *const ht = (curwin->w_s->b_syn_ic) ? &curwin->w_s->b_keywtab_ic : &curwin->w_s->b_keywtab; - hashitem_T *const hi = hash_lookup(ht, (const char *)kp->keyword, + hashitem_T *const hi = hash_lookup(ht, kp->keyword, strlen(kp->keyword), hash); // even though it looks like only the kp->keyword member is @@ -3763,7 +3763,7 @@ static void add_keyword(char *const name, const int id, const int flags, } else { // keyword already exists, prepend to list kp->ke_next = HI2KE(hi); - hi->hi_key = (char *)KE2HIKEY(kp); + hi->hi_key = KE2HIKEY(kp); } } @@ -5370,7 +5370,7 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg) } // (part of) subcommand already typed - const char *p = (const char *)skiptowhite(arg); + const char *p = skiptowhite(arg); if (*p == NUL) { return; } diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 2d9d0de951..401b43204e 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -188,11 +188,11 @@ typedef struct { # include "tag.c.generated.h" #endif -static char *bottommsg = N_("E555: at bottom of tag stack"); -static char *topmsg = N_("E556: at top of tag stack"); -static char *recurmsg = N_("E986: cannot modify the tag stack within tagfunc"); -static char *tfu_inv_ret_msg = N_("E987: invalid return value from tagfunc"); -static char e_window_unexpectedly_close_while_searching_for_tags[] +static const char *bottommsg = N_("E555: at bottom of tag stack"); +static const char *topmsg = N_("E556: at top of tag stack"); +static const char *recurmsg = N_("E986: cannot modify the tag stack within tagfunc"); +static const char *tfu_inv_ret_msg = N_("E987: invalid return value from tagfunc"); +static const char e_window_unexpectedly_close_while_searching_for_tags[] = N_("E1299: Window unexpectedly closed while searching for tags"); static char *tagmatchname = NULL; // name of last used tag @@ -210,7 +210,7 @@ static Callback tfu_cb; // 'tagfunc' callback function /// Reads the 'tagfunc' option value and convert that to a callback value. /// Invoked when the 'tagfunc' option is set. The option value can be a name of /// a function (string), or function(<name>) or funcref(<name>) or a lambda. -void set_tagfunc_option(char **errmsg) +void set_tagfunc_option(const char **errmsg) { callback_free(&tfu_cb); callback_free(&curbuf->b_tfu_cb); @@ -795,8 +795,8 @@ 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; - char *p; - char *command_end; + const char *p; + const char *command_end; tagptrs_T tagp; int taglen; int attr; @@ -1081,7 +1081,7 @@ static int add_llist_tags(char *tag, int num_matches, char **matches) tv_list_append_dict(list, dict); tv_dict_add_str(dict, S_LEN("text"), tag_name); - tv_dict_add_str(dict, S_LEN("filename"), (const char *)fname); + tv_dict_add_str(dict, S_LEN("filename"), fname); tv_dict_add_nr(dict, S_LEN("lnum"), lnum); if (lnum == 0) { tv_dict_add_str(dict, S_LEN("pattern"), cmd); @@ -1246,10 +1246,10 @@ static int find_tagfunc_tags(char *pat, garray_T *ga, int *match_count, int flag // create 'info' dict argument dict_T *const d = tv_dict_alloc_lock(VAR_FIXED); if (tag != NULL && tag->user_data != NULL) { - tv_dict_add_str(d, S_LEN("user_data"), (const char *)tag->user_data); + tv_dict_add_str(d, S_LEN("user_data"), tag->user_data); } if (buf_ffname != NULL) { - tv_dict_add_str(d, S_LEN("buf_ffname"), (const char *)buf_ffname); + tv_dict_add_str(d, S_LEN("buf_ffname"), buf_ffname); } d->dv_refcount++; @@ -1303,7 +1303,7 @@ static int find_tagfunc_tags(char *pat, garray_T *ga, int *match_count, int flag res_kind = NULL; TV_DICT_ITER(TV_LIST_ITEM_TV(li)->vval.v_dict, di, { - const char *dict_key = (char *)di->di_key; + const char *dict_key = di->di_key; typval_T *tv = &di->di_tv; if (tv->v_type != VAR_STRING || tv->vval.v_string == NULL) { @@ -1372,7 +1372,7 @@ static int find_tagfunc_tags(char *pat, garray_T *ga, int *match_count, int flag } TV_DICT_ITER(TV_LIST_ITEM_TV(li)->vval.v_dict, di, { - const char *dict_key = (char *)di->di_key; + const char *dict_key = di->di_key; typval_T *tv = &di->di_tv; if (tv->v_type != VAR_STRING || tv->vval.v_string == NULL) { continue; @@ -2067,7 +2067,7 @@ static void findtags_add_match(findtags_state_T *st, tagptrs_T *tagpp, findtags_ // follow after it. E.g. help tags store the priority // after the NUL. *hash = hash_hash(mfp); - hi = hash_lookup(&st->ht_match[mtt], (const char *)mfp, strlen(mfp), *hash); + hi = hash_lookup(&st->ht_match[mtt], mfp, strlen(mfp), *hash); if (HASHITEM_EMPTY(hi)) { hash_add_item(&st->ht_match[mtt], hi, mfp, *hash); GA_APPEND(char *, &st->ga_match[mtt], mfp); @@ -2530,7 +2530,7 @@ int get_tagfname(tagname_T *tnp, int first, char *buf) } tnp->tn_hf_idx++; STRCPY(buf, p_hf); - STRCPY(path_tail((char *)buf), "tags"); + STRCPY(path_tail(buf), "tags"); #ifdef BACKSLASH_IN_FILENAME slash_adjust(buf); #endif @@ -3408,11 +3408,11 @@ static void get_tag_details(taggy_T *tag, dict_T *retdict) list_T *pos; fmark_T *fmark; - tv_dict_add_str(retdict, S_LEN("tagname"), (const char *)tag->tagname); + tv_dict_add_str(retdict, S_LEN("tagname"), tag->tagname); tv_dict_add_nr(retdict, S_LEN("matchnr"), tag->cur_match + 1); tv_dict_add_nr(retdict, S_LEN("bufnr"), tag->cur_fnum); if (tag->user_data) { - tv_dict_add_str(retdict, S_LEN("user_data"), (const char *)tag->user_data); + tv_dict_add_str(retdict, S_LEN("user_data"), tag->user_data); } pos = tv_list_alloc(4); diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 76fa3049f6..c774dbe384 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -896,13 +896,13 @@ static int term_moverect(VTermRect dest, VTermRect src, void *data) return 1; } -static int term_movecursor(VTermPos new, VTermPos old, int visible, void *data) +static int term_movecursor(VTermPos new_pos, VTermPos old_pos, int visible, void *data) { Terminal *term = data; - term->cursor.row = new.row; - term->cursor.col = new.col; - invalidate_terminal(term, old.row, old.row + 1); - invalidate_terminal(term, new.row, new.row + 1); + term->cursor.row = new_pos.row; + term->cursor.col = new_pos.col; + invalidate_terminal(term, old_pos.row, old_pos.row + 1); + invalidate_terminal(term, new_pos.row, new_pos.row + 1); return 1; } diff --git a/src/nvim/testing.c b/src/nvim/testing.c index 3569856f2c..907940f64a 100644 --- a/src/nvim/testing.c +++ b/src/nvim/testing.c @@ -34,13 +34,13 @@ # include "testing.c.generated.h" #endif -static char e_assert_fails_second_arg[] +static const char e_assert_fails_second_arg[] = N_("E856: assert_fails() second argument must be a string or a list with one or two strings"); -static char e_assert_fails_fourth_argument[] +static const char e_assert_fails_fourth_argument[] = N_("E1115: assert_fails() fourth argument must be a number"); -static char e_assert_fails_fifth_argument[] +static const char e_assert_fails_fifth_argument[] = N_("E1116: assert_fails() fifth argument must be a string"); -static char e_calling_test_garbagecollect_now_while_v_testing_is_not_set[] +static const char e_calling_test_garbagecollect_now_while_v_testing_is_not_set[] = N_("E1142: Calling test_garbagecollect_now() while v:testing is not set"); /// Prepare "gap" for an assert error and add the sourcing position. @@ -185,16 +185,14 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char *exp_str int todo = (int)exp_d->dv_hashtab.ht_used; for (const hashitem_T *hi = exp_d->dv_hashtab.ht_array; todo > 0; hi++) { if (!HASHITEM_EMPTY(hi)) { - dictitem_T *item2 = tv_dict_find(got_d, (const char *)hi->hi_key, -1); + dictitem_T *item2 = tv_dict_find(got_d, hi->hi_key, -1); if (item2 == NULL || !tv_equal(&TV_DICT_HI2DI(hi)->di_tv, &item2->di_tv, false, false)) { // item of exp_d not present in got_d or values differ. const size_t key_len = strlen(hi->hi_key); - tv_dict_add_tv(exp_tv->vval.v_dict, (const char *)hi->hi_key, key_len, - &TV_DICT_HI2DI(hi)->di_tv); + tv_dict_add_tv(exp_tv->vval.v_dict, hi->hi_key, key_len, &TV_DICT_HI2DI(hi)->di_tv); if (item2 != NULL) { - tv_dict_add_tv(got_tv->vval.v_dict, (const char *)hi->hi_key, key_len, - &item2->di_tv); + tv_dict_add_tv(got_tv->vval.v_dict, hi->hi_key, key_len, &item2->di_tv); } } else { omitted++; @@ -207,12 +205,11 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char *exp_str todo = (int)got_d->dv_hashtab.ht_used; for (const hashitem_T *hi = got_d->dv_hashtab.ht_array; todo > 0; hi++) { if (!HASHITEM_EMPTY(hi)) { - dictitem_T *item2 = tv_dict_find(exp_d, (const char *)hi->hi_key, -1); + dictitem_T *item2 = tv_dict_find(exp_d, hi->hi_key, -1); if (item2 == NULL) { // item of got_d not present in exp_d const size_t key_len = strlen(hi->hi_key); - tv_dict_add_tv(got_tv->vval.v_dict, (const char *)hi->hi_key, key_len, - &TV_DICT_HI2DI(hi)->di_tv); + tv_dict_add_tv(got_tv->vval.v_dict, hi->hi_key, key_len, &TV_DICT_HI2DI(hi)->di_tv); } todo--; } @@ -507,7 +504,7 @@ void f_assert_fails(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) garray_T ga; int save_trylevel = trylevel; const int called_emsg_before = called_emsg; - char *wrong_arg_msg = NULL; + const char *wrong_arg_msg = NULL; // trylevel must be zero for a ":throw" command to be considered failed trylevel = 0; diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 05e57e4b8f..c406f0c302 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -634,7 +634,7 @@ static bool paragraph_start(linenr_T lnum) void auto_format(bool trailblank, bool prev_line) { colnr_T len; - char *new, *pnew; + char *linep, *plinep; int cc; if (!has_format_option(FO_AUTO)) { @@ -705,13 +705,13 @@ void auto_format(bool trailblank, bool prev_line) // need to add a space when 'w' is in 'formatoptions' to keep a paragraph // formatted. if (!wasatend && has_format_option(FO_WHITE_PAR)) { - new = get_cursor_line_ptr(); - len = (colnr_T)strlen(new); + linep = get_cursor_line_ptr(); + len = (colnr_T)strlen(linep); if (curwin->w_cursor.col == len) { - pnew = xstrnsave(new, (size_t)len + 2); - pnew[len] = ' '; - pnew[len + 1] = NUL; - ml_replace(curwin->w_cursor.lnum, pnew, false); + plinep = xstrnsave(linep, (size_t)len + 2); + plinep[len] = ' '; + plinep[len + 1] = NUL; + ml_replace(curwin->w_cursor.lnum, plinep, false); // remove the space later did_add_space = true; } else { diff --git a/src/nvim/types.h b/src/nvim/types.h index 0bc2f76078..ca0ae16a66 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -26,7 +26,7 @@ typedef struct MsgpackRpcRequestHandler MsgpackRpcRequestHandler; typedef union { float_T (*float_func)(float_T); const MsgpackRpcRequestHandler *api_handler; - void *nullptr; + void *null; } EvalFuncData; typedef handle_T NS; diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index 25ff63ea2d..b93b31f7dc 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -43,7 +43,7 @@ uint64_t ui_client_start_server(int argc, char **argv) varnumber_T exit_status; char **args = xmalloc(((size_t)(2 + argc)) * sizeof(char *)); int args_idx = 0; - args[args_idx++] = xstrdup((const char *)get_vim_var_str(VV_PROGPATH)); + args[args_idx++] = xstrdup(get_vim_var_str(VV_PROGPATH)); args[args_idx++] = xstrdup("--embed"); for (int i = 1; i < argc; i++) { args[args_idx++] = xstrdup(argv[i]); diff --git a/src/nvim/undo.c b/src/nvim/undo.c index ad33ba4667..132c84231f 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -624,7 +624,7 @@ int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, int re // extra fields for uhp #define UHP_SAVE_NR 1 -static char e_not_open[] = N_("E828: Cannot open undo file for writing: %s"); +static const char e_not_open[] = N_("E828: Cannot open undo file for writing: %s"); /// Compute the hash for a buffer text into hash[UNDO_HASH_SIZE]. /// @@ -1179,7 +1179,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, // allow the user to access the undo file. int perm = 0600; if (buf->b_ffname != NULL) { - perm = os_getperm((const char *)buf->b_ffname); + perm = os_getperm(buf->b_ffname); if (perm < 0) { perm = 0600; } diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index 6869f7eaf9..4cd58bb91b 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -44,11 +44,11 @@ garray_T ucmds = { 0, 0, sizeof(ucmd_T), 4, NULL }; -static char e_complete_used_without_allowing_arguments[] +static const char e_complete_used_without_allowing_arguments[] = N_("E1208: -complete used without allowing arguments"); -static char e_no_such_user_defined_command_str[] +static const char e_no_such_user_defined_command_str[] = N_("E184: No such user-defined command: %s"); -static char e_no_such_user_defined_command_in_current_buffer_str[] +static const char e_no_such_user_defined_command_in_current_buffer_str[] = N_("E1237: No such user-defined command in current buffer: %s"); /// List of names for completion for ":command" with the EXPAND_ flag. @@ -234,7 +234,7 @@ const char *set_context_in_user_cmd(expand_T *xp, const char *arg_in) // Check for attributes while (*arg == '-') { arg++; // Skip "-". - p = (const char *)skiptowhite(arg); + p = skiptowhite(arg); if (*p == NUL) { // Cursor is still in the attribute. p = strchr(arg, '='); @@ -262,11 +262,11 @@ const char *set_context_in_user_cmd(expand_T *xp, const char *arg_in) } return NULL; } - arg = (const char *)skipwhite(p); + arg = skipwhite(p); } // After the attributes comes the new command name. - p = (const char *)skiptowhite(arg); + p = skiptowhite(arg); if (*p == NUL) { xp->xp_context = EXPAND_USER_COMMANDS; xp->xp_pattern = (char *)arg; @@ -274,7 +274,7 @@ const char *set_context_in_user_cmd(expand_T *xp, const char *arg_in) } // And finally comes a normal command. - return (const char *)skipwhite(p); + return skipwhite(p); } /// Set the completion context for the argument of a user defined command. @@ -292,7 +292,7 @@ const char *set_context_in_user_cmdarg(const char *cmd FUNC_ATTR_UNUSED, const c } if (context == EXPAND_MENUS) { - return (const char *)set_context_in_menu_cmd(xp, cmd, (char *)arg, forceit); + return set_context_in_menu_cmd(xp, cmd, (char *)arg, forceit); } if (context == EXPAND_COMMANDS) { return arg; @@ -861,7 +861,7 @@ char *uc_validate_name(char *name) /// /// @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, int64_t def, - int flags, int compl, char *compl_arg, LuaRef compl_luaref, + int flags, int context, char *compl_arg, LuaRef compl_luaref, LuaRef preview_luaref, cmd_addr_T addr_type, LuaRef luaref, bool force) FUNC_ATTR_NONNULL_ARG(1, 3) { @@ -944,7 +944,7 @@ int uc_add_command(char *name, size_t name_len, const char *rep, uint32_t argt, cmd->uc_rep = rep_buf; cmd->uc_argt = argt; cmd->uc_def = def; - cmd->uc_compl = compl; + cmd->uc_compl = context; cmd->uc_script_ctx = current_sctx; cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM; nlua_set_sctx(&cmd->uc_script_ctx); @@ -974,7 +974,7 @@ void ex_command(exarg_T *eap) uint32_t argt = 0; long def = -1; int flags = 0; - int compl = EXPAND_NOTHING; + int context = EXPAND_NOTHING; char *compl_arg = NULL; cmd_addr_T addr_type_arg = ADDR_NONE; int has_attr = (eap->arg[0] == '-'); @@ -986,7 +986,7 @@ void ex_command(exarg_T *eap) while (*p == '-') { p++; end = skiptowhite(p); - if (uc_scan_attr(p, (size_t)(end - p), &argt, &def, &flags, &compl, &compl_arg, + if (uc_scan_attr(p, (size_t)(end - p), &argt, &def, &flags, &context, &compl_arg, &addr_type_arg) == FAIL) { goto theend; } @@ -1011,10 +1011,10 @@ void ex_command(exarg_T *eap) emsg(_("E183: User defined commands must start with an uppercase letter")); } else if (name_len <= 4 && strncmp(name, "Next", name_len) == 0) { emsg(_("E841: Reserved name, cannot be used for user defined command")); - } else if (compl > 0 && (argt & EX_EXTRA) == 0) { + } else if (context > 0 && (argt & EX_EXTRA) == 0) { emsg(_(e_complete_used_without_allowing_arguments)); } else { - uc_add_command(name, name_len, p, argt, def, flags, compl, compl_arg, LUA_NOREF, LUA_NOREF, + uc_add_command(name, name_len, p, argt, def, flags, context, compl_arg, LUA_NOREF, LUA_NOREF, addr_type_arg, LUA_NOREF, eap->forceit); return; // success diff --git a/src/nvim/window.c b/src/nvim/window.c index 762ad13ba3..75fa61fb1e 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -96,7 +96,7 @@ typedef enum { WEE_TRIGGER_LEAVE_AUTOCMDS = 0x10, } wee_flags_T; -static char e_cannot_split_window_when_closing_buffer[] +static const char e_cannot_split_window_when_closing_buffer[] = N_("E1159: Cannot split a window when closing the buffer"); static char *m_onlyone = N_("Already only one window"); @@ -899,7 +899,7 @@ void win_check_anchored_floats(win_T *win) /// Return the number of fold columns to display int win_fdccol_count(win_T *wp) { - const char *fdc = (const char *)wp->w_p_fdc; + const char *fdc = wp->w_p_fdc; // auto:<NUM> if (strncmp(fdc, "auto", 4) == 0) { @@ -2417,7 +2417,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } } -static void leaving_window(win_T *const win) +void leaving_window(win_T *const win) FUNC_ATTR_NONNULL_ALL { // Only matters for a prompt window. @@ -7422,7 +7422,7 @@ static int int_cmp(const void *a, const void *b) /// Handle setting 'colorcolumn' or 'textwidth' in window "wp". /// /// @return error message, NULL if it's OK. -char *check_colorcolumn(win_T *wp) +const char *check_colorcolumn(win_T *wp) { if (wp->w_buffer == NULL) { return NULL; // buffer was closed diff --git a/test/busted/outputHandlers/nvim.lua b/test/busted/outputHandlers/nvim.lua index 2ce32c3b7a..e17536e0f8 100644 --- a/test/busted/outputHandlers/nvim.lua +++ b/test/busted/outputHandlers/nvim.lua @@ -204,7 +204,7 @@ return function(options) handler.fileStart = function(file) fileTestCount = 0 - io.write(fileStartString:format(file.name)) + io.write(fileStartString:format(vim.fs.normalize(file.name))) io.flush() return nil, true end @@ -213,7 +213,7 @@ return function(options) local elapsedTime_ms = getElapsedTime(file) local tests = (fileTestCount == 1 and 'test' or 'tests') fileCount = fileCount + 1 - io.write(fileEndString:format(fileTestCount, tests, file.name, elapsedTime_ms)) + io.write(fileEndString:format(fileTestCount, tests, vim.fs.normalize(file.name), elapsedTime_ms)) io.flush() return nil, true end diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 9d5a0c4b4e..af6fbf092a 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1,6 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local lfs = require('lfs') local luv = require('luv') local fmt = string.format @@ -2080,6 +2079,46 @@ describe('API', function() end) end) + describe('nvim_err_writeln', function() + local screen + + before_each(function() + screen = Screen.new(40, 8) + screen:attach() + screen:set_default_attr_ids({ + [0] = {bold=true, foreground=Screen.colors.Blue}, + [1] = {foreground = Screen.colors.White, background = Screen.colors.Red}, + [2] = {bold = true, foreground = Screen.colors.SeaGreen}, + [3] = {bold = true, reverse = true}, + }) + end) + + it('shows only one return prompt after all lines are shown', function() + nvim_async('err_writeln', 'FAILURE\nERROR\nEXCEPTION\nTRACEBACK') + screen:expect([[ + | + {0:~ }| + {3: }| + {1:FAILURE} | + {1:ERROR} | + {1:EXCEPTION} | + {1:TRACEBACK} | + {2:Press ENTER or type command to continue}^ | + ]]) + feed('<CR>') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + end) + describe('nvim_list_chans, nvim_get_chan_info', function() before_each(function() command('autocmd ChanOpen * let g:opened_event = deepcopy(v:event)') @@ -3382,6 +3421,38 @@ describe('API', function() 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight', { use_winbar = true, highlights = true })) end) + it('works with statuscolumn', function() + exec([[ + let &stc='%C%s%=%l ' + set cul nu nuw=3 scl=yes:2 fdc=2 + call setline(1, repeat(['aaaaa'], 5)) + let g:ns = nvim_create_namespace('') + call sign_define('a', {'text':'aa', 'texthl':'IncSearch', 'numhl':'Normal'}) + call sign_place(2, 1, 'a', bufnr(), {'lnum':4}) + call nvim_buf_set_extmark(0, g:ns, 3, 1, { 'sign_text':'bb', 'sign_hl_group':'ErrorMsg' }) + 1,5fold | 1,5 fold | foldopen! + norm 4G + ]]) + eq({ + str = '││aabb 4 ', + width = 9, + highlights = { + { group = 'CursorLineFold', start = 0 }, + { group = 'Normal', start = 6 }, + { group = 'IncSearch', start = 6 }, + { group = 'ErrorMsg', start = 8 }, + { group = 'Normal', start = 10 } + } + }, meths.eval_statusline('%C%s%=%l ', { use_statuscol_lnum = 4, highlights = true })) + eq({ + str = '3 ' , + width = 2, + highlights = { + { group = 'LineNr', start = 0 }, + { group = 'ErrorMsg', start = 1 } + } + }, meths.eval_statusline('%l%#ErrorMsg# ', { use_statuscol_lnum = 3, highlights = true })) + end) it('no memory leak with click functions', function() meths.eval_statusline('%@ClickFunc@StatusLineStringWithClickFunc%T', {}) eq({ @@ -4140,7 +4211,7 @@ describe('API', function() meths.cmd({ cmd = "buffers", mods = { filter = { pattern = "foo", force = true } } }, { output = true })) - -- with emsg_silent = true error is suppresed + -- with emsg_silent = true error is suppressed feed([[:lua vim.api.nvim_cmd({ cmd = 'call', mods = { emsg_silent = true } }, {})<CR>]]) eq('', meths.cmd({ cmd = 'messages' }, { output = true })) -- error from the next command typed is not suppressed #21420 @@ -4153,7 +4224,7 @@ describe('API', function() vim.api.nvim_echo({{ opts.fargs[1] }}, false, {}) end, { nargs = 1 }) ]]) - eq(lfs.currentdir(), + eq(luv.cwd(), meths.cmd({ cmd = "Foo", args = { '%:p:h' }, magic = { file = true } }, { output = true })) end) diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua index 828cffa460..20aa07d058 100644 --- a/test/functional/autocmd/dirchanged_spec.lua +++ b/test/functional/autocmd/dirchanged_spec.lua @@ -1,4 +1,4 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear @@ -9,7 +9,7 @@ local request = helpers.request local is_os = helpers.is_os describe('autocmd DirChanged and DirChangedPre', function() - local curdir = string.gsub(lfs.currentdir(), '\\', '/') + local curdir = string.gsub(luv.cwd(), '\\', '/') local dirs = { curdir .. '/Xtest-functional-autocmd-dirchanged.dir1', curdir .. '/Xtest-functional-autocmd-dirchanged.dir2', diff --git a/test/functional/autocmd/focus_spec.lua b/test/functional/autocmd/focus_spec.lua index d7a87e17ed..33e4d88c7b 100644 --- a/test/functional/autocmd/focus_spec.lua +++ b/test/functional/autocmd/focus_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') -local lfs = require('lfs') +local luv = require('luv') local clear = helpers.clear local nvim_prog = helpers.nvim_prog local feed_command = helpers.feed_command @@ -32,7 +32,8 @@ describe('autoread TUI FocusGained/FocusLost', function() ]] helpers.write_file(path, '') - lfs.touch(path, os.time() - 10) + local atime = os.time() - 10 + luv.fs_utime(path, atime, atime) screen:expect{grid=[[ {1: } | diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua index 153b53dce2..4236a4ff47 100644 --- a/test/functional/core/fileio_spec.lua +++ b/test/functional/core/fileio_spec.lua @@ -1,4 +1,4 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local assert_log = helpers.assert_log @@ -142,7 +142,7 @@ describe('fileio', function() local backup_file_name = link_file_name .. '~' write_file('Xtest_startup_file1', initial_content, false) - lfs.link('Xtest_startup_file1', link_file_name, true) + luv.fs_symlink('Xtest_startup_file1', link_file_name) command('set backup') command('set backupcopy=yes') command('edit ' .. link_file_name) @@ -166,7 +166,7 @@ describe('fileio', function() local backup_file_name = backup_dir .. sep .. link_file_name .. '~' write_file('Xtest_startup_file1', initial_content, false) - lfs.link('Xtest_startup_file1', link_file_name, true) + luv.fs_symlink('Xtest_startup_file1', link_file_name) mkdir(backup_dir) command('set backup') command('set backupcopy=yes') diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua index ab11e14a67..efab40dd11 100644 --- a/test/functional/core/main_spec.lua +++ b/test/functional/core/main_spec.lua @@ -1,4 +1,4 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') @@ -28,18 +28,18 @@ describe('Command-line option', function() os.remove(dollar_fname) end) it('treats - as stdin', function() - eq(nil, lfs.attributes(fname)) + eq(nil, luv.fs_stat(fname)) funcs.system( {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', '-s', '-', fname}, {':call setline(1, "42")', ':wqall!', ''}) eq(0, eval('v:shell_error')) - local attrs = lfs.attributes(fname) + local attrs = luv.fs_stat(fname) eq(#('42\n'), attrs.size) end) it('does not expand $VAR', function() - eq(nil, lfs.attributes(fname)) + eq(nil, luv.fs_stat(fname)) eq(true, not not dollar_fname:find('%$%w+')) write_file(dollar_fname, ':call setline(1, "100500")\n:wqall!\n') funcs.system( @@ -47,7 +47,7 @@ describe('Command-line option', function() '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', '-s', dollar_fname, fname}) eq(0, eval('v:shell_error')) - local attrs = lfs.attributes(fname) + local attrs = luv.fs_stat(fname) eq(#('100500\n'), attrs.size) end) it('does not crash after reading from stdin in non-headless mode', function() @@ -121,7 +121,7 @@ describe('Command-line option', function() '--cmd', 'language C', '-s', fname, '-s', dollar_fname, fname_2})) eq(2, eval('v:shell_error')) - eq(nil, lfs.attributes(fname_2)) + eq(nil, luv.fs_stat(fname_2)) end) end) end) diff --git a/test/functional/core/spellfile_spec.lua b/test/functional/core/spellfile_spec.lua index afd2c1bce4..378899eece 100644 --- a/test/functional/core/spellfile_spec.lua +++ b/test/functional/core/spellfile_spec.lua @@ -1,5 +1,4 @@ local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') local eq = helpers.eq local clear = helpers.clear @@ -7,6 +6,7 @@ local meths = helpers.meths local exc_exec = helpers.exc_exec local rmdir = helpers.rmdir local write_file = helpers.write_file +local mkdir = helpers.mkdir local testdir = 'Xtest-functional-spell-spellfile.d' @@ -14,8 +14,8 @@ describe('spellfile', function() before_each(function() clear() rmdir(testdir) - lfs.mkdir(testdir) - lfs.mkdir(testdir .. '/spell') + mkdir(testdir) + mkdir(testdir .. '/spell') end) after_each(function() rmdir(testdir) diff --git a/test/functional/editor/fold_spec.lua b/test/functional/editor/fold_spec.lua index 00e83bedc8..3115c20410 100644 --- a/test/functional/editor/fold_spec.lua +++ b/test/functional/editor/fold_spec.lua @@ -4,17 +4,17 @@ local clear = helpers.clear local insert = helpers.insert local feed = helpers.feed local expect = helpers.expect -local feed_command = helpers.feed_command +local command = helpers.command local funcs = helpers.funcs -local foldlevel = funcs.foldlevel -local foldclosedend = funcs.foldclosedend local eq = helpers.eq describe('Folds', function() local tempfname = 'Xtest-fold.txt' - clear() - before_each(function() feed_command('enew!') end) + + setup(clear) + before_each(function() command('bwipe! | new') end) after_each(function() os.remove(tempfname) end) + it('manual folding adjusts with filter', function() insert([[ 1 @@ -37,8 +37,11 @@ describe('Folds', function() 18 19 20]]) - feed_command('4,$fold', '%foldopen', '10,$fold', '%foldopen') - feed_command('1,8! cat') + command('4,$fold') + command('%foldopen') + command('10,$fold') + command('%foldopen') + command('1,8! cat') feed('5ggzdzMGdd') expect([[ 1 @@ -51,22 +54,24 @@ describe('Folds', function() 8 9]]) end) + describe('adjusting folds after :move', function() local function manually_fold_indent() -- setting foldmethod twice is a trick to get vim to set the folds for me - feed_command('set foldmethod=indent', 'set foldmethod=manual') + command('set foldmethod=indent') + command('set foldmethod=manual') -- Ensure that all folds will get closed (makes it easier to test the -- length of folds). - feed_command('set foldminlines=0') + command('set foldminlines=0') -- Start with all folds open (so :move ranges aren't affected by closed -- folds). - feed_command('%foldopen!') + command('%foldopen!') end local function get_folds() local rettab = {} for i = 1, funcs.line('$') do - table.insert(rettab, foldlevel(i)) + table.insert(rettab, funcs.foldlevel(i)) end return rettab end @@ -75,16 +80,16 @@ describe('Folds', function() -- This test is easy because we just need to ensure that the resulting -- fold is the same as calculated when creating folds from scratch. insert(insert_string) - feed_command(move_command) + command(move_command) local after_move_folds = get_folds() -- Doesn't change anything, but does call foldUpdateAll() - feed_command('set foldminlines=0') + command('set foldminlines=0') eq(after_move_folds, get_folds()) -- Set up the buffer with insert_string for the manual fold testing. - feed_command('enew!') + command('enew!') insert(insert_string) manually_fold_indent() - feed_command(move_command) + command(move_command) end it('neither closes nor corrupts folds', function() @@ -130,19 +135,20 @@ a for i = 1,funcs.line('$') do eq(-1, funcs.foldclosed(i)) if i == 1 or i == 7 or i == 13 then - eq(0, foldlevel(i)) + eq(0, funcs.foldlevel(i)) elseif i == 4 then - eq(2, foldlevel(i)) + eq(2, funcs.foldlevel(i)) else - eq(1, foldlevel(i)) + eq(1, funcs.foldlevel(i)) end end -- folds are not corrupted feed('zM') - eq(6, foldclosedend(2)) - eq(12, foldclosedend(8)) - eq(18, foldclosedend(14)) + eq(6, funcs.foldclosedend(2)) + eq(12, funcs.foldclosedend(8)) + eq(18, funcs.foldclosedend(14)) end) + it("doesn't split a fold when the move is within it", function() test_move_indent([[ a @@ -157,6 +163,7 @@ a a]], '5m6') eq({0, 1, 1, 2, 2, 2, 2, 1, 1, 0}, get_folds()) end) + it('truncates folds that end in the moved range', function() test_move_indent([[ a @@ -168,6 +175,7 @@ a a]], '4,5m6') eq({0, 1, 2, 0, 0, 0, 0}, get_folds()) end) + it('moves folds that start between moved range and destination', function() test_move_indent([[ a @@ -185,6 +193,7 @@ a a]], '3,4m$') eq({0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0}, get_folds()) end) + it('does not affect folds outside changed lines', function() test_move_indent([[ a @@ -198,6 +207,7 @@ a a]], '4m5') eq({1, 1, 1, 0, 0, 0, 1, 1, 1}, get_folds()) end) + it('moves and truncates folds that start in moved range', function() test_move_indent([[ a @@ -212,6 +222,7 @@ a a]], '1,3m7') eq({0, 0, 0, 0, 0, 1, 2, 0, 0, 0}, get_folds()) end) + it('breaks a fold when moving text into it', function() test_move_indent([[ a @@ -223,6 +234,7 @@ a a]], '$m4') eq({0, 1, 2, 2, 0, 0, 0}, get_folds()) end) + it('adjusts correctly when moving a range backwards', function() test_move_indent([[ a @@ -232,6 +244,7 @@ a a]], '2,3m0') eq({1, 2, 0, 0, 0}, get_folds()) end) + it('handles shifting all remaining folds', function() test_move_indent([[ a @@ -252,6 +265,7 @@ a]], '13m7') eq({1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0}, get_folds()) end) end) + it('updates correctly on :read', function() -- luacheck: ignore 621 helpers.write_file(tempfname, [[ @@ -265,8 +279,10 @@ a]], '13m7') a a ]]) - feed_command('set foldmethod=indent', '2', '%foldopen') - feed_command('read ' .. tempfname) + command('set foldmethod=indent') + command('2') + command('%foldopen') + command('read ' .. tempfname) -- Just to check we have the correct file text. expect([[ a @@ -288,6 +304,7 @@ a]], '13m7') eq(1, funcs.foldlevel(i)) end end) + it('combines folds when removing separating space', function() -- luacheck: ignore 621 insert([[ @@ -300,9 +317,11 @@ a]], '13m7') a a ]]) - feed_command('set foldmethod=indent', '3,5d') + command('set foldmethod=indent') + command('3,5d') eq(5, funcs.foldclosedend(1)) end) + it("doesn't combine folds that have a specified end", function() insert([[ {{{ @@ -314,9 +333,12 @@ a]], '13m7') }}} ]]) - feed_command('set foldmethod=marker', '3,5d', '%foldclose') + command('set foldmethod=marker') + command('3,5d') + command('%foldclose') eq(2, funcs.foldclosedend(1)) end) + it('splits folds according to >N and <N with foldexpr', function() helpers.source([[ function TestFoldExpr(lnum) @@ -350,8 +372,11 @@ a]], '13m7') a a ]]) - feed_command('set foldmethod=expr', 'set foldexpr=TestFoldExpr(v:lnum)', '2', 'foldopen') - feed_command('read ' .. tempfname, '%foldclose') + command('set foldmethod=expr foldexpr=TestFoldExpr(v:lnum)') + command('2') + command('foldopen') + command('read ' .. tempfname) + command('%foldclose') eq(2, funcs.foldclosedend(1)) eq(0, funcs.foldlevel(3)) eq(0, funcs.foldlevel(4)) @@ -359,4 +384,37 @@ a]], '13m7') eq(10, funcs.foldclosedend(7)) eq(14, funcs.foldclosedend(11)) end) + + it('no folds remain if :delete makes buffer empty #19671', function() + command('set foldmethod=manual') + funcs.setline(1, {'foo', 'bar', 'baz'}) + command('2,3fold') + command('%delete') + eq(0, funcs.foldlevel(1)) + end) + + it('multibyte fold markers work #20438', function() + command('set foldmethod=marker foldmarker=«,» commentstring=/*%s*/') + insert([[ + bbbbb + bbbbb + bbbbb]]) + feed('zfgg') + expect([[ + bbbbb/*«*/ + bbbbb + bbbbb/*»*/]]) + eq(1, funcs.foldlevel(1)) + end) + + it('updates correctly with indent method and visual blockwise insertion #22898', function() + insert([[ + a + b + ]]) + command('set foldmethod=indent shiftwidth=2') + feed('gg0<C-v>jI <Esc>') -- indent both lines using visual blockwise mode + eq(1, funcs.foldlevel(1)) + eq(1, funcs.foldlevel(2)) + end) end) diff --git a/test/functional/editor/put_spec.lua b/test/functional/editor/put_spec.lua index 5050edff5c..fb55b71e43 100644 --- a/test/functional/editor/put_spec.lua +++ b/test/functional/editor/put_spec.lua @@ -9,22 +9,21 @@ local eq = helpers.eq local map = helpers.tbl_map local filter = helpers.tbl_filter local feed_command = helpers.feed_command +local command = helpers.command local curbuf_contents = helpers.curbuf_contents local funcs = helpers.funcs local dedent = helpers.dedent -local getreg = funcs.getreg local function reset() - feed_command('enew!') + command('bwipe! | new') insert([[ Line of words 1 Line of words 2]]) - feed_command('goto 1') + command('goto 1') feed('itest_string.<esc>u') funcs.setreg('a', 'test_stringa', 'V') funcs.setreg('b', 'test_stringb\ntest_stringb\ntest_stringb', 'b') funcs.setreg('"', 'test_string"', 'v') - feed_command('set virtualedit=') end -- We check the last inserted register ". in each of these tests because it is @@ -508,10 +507,10 @@ describe('put command', function() test_expect(exception_table, after_redo) if selection_string then if not conversion_table.put_backwards then - eq(selection_string, getreg('"')) + eq(selection_string, funcs.getreg('"')) end else - eq('test_string"', getreg('"')) + eq('test_string"', funcs.getreg('"')) end end end @@ -644,7 +643,7 @@ describe('put command', function() -- Set curswant to '8' to be at the end of the tab character -- This is where the cursor is put back after the 'u' command. funcs.setpos('.', {0, 2, 1, 0, 8}) - feed_command('set autoindent') + command('set autoindent') end ) end) @@ -655,7 +654,7 @@ describe('put command', function() test_stringx" Line of words 2]] run_normal_mode_tests(test_string, 'p', function() funcs.setline('$', ' Line of words 2') - feed_command('set virtualedit=all') + command('setlocal virtualedit=all') funcs.setpos('.', {0, 2, 1, 2, 3}) end) end) @@ -667,7 +666,7 @@ describe('put command', function() Line of words 2]] run_normal_mode_tests(test_string, 'p', function() funcs.setline('$', ' Line of words 2') - feed_command('set virtualedit=all') + command('setlocal virtualedit=all') funcs.setpos('.', {0, 1, 16, 1, 17}) end, true) end) @@ -717,7 +716,7 @@ describe('put command', function() return function(exception_table, after_redo) test_expect(exception_table, after_redo) if not conversion_table.put_backwards then - eq('Line of words 1\n', getreg('"')) + eq('Line of words 1\n', funcs.getreg('"')) end end end @@ -753,7 +752,7 @@ describe('put command', function() return function(e,c) test_expect(e,c) if not conversion_table.put_backwards then - eq('Lin\nLin', getreg('"')) + eq('Lin\nLin', funcs.getreg('"')) end end end @@ -836,7 +835,7 @@ describe('put command', function() 'vp', function() funcs.setline('$', ' Line of words 2') - feed_command('set virtualedit=all') + command('setlocal virtualedit=all') funcs.setpos('.', {0, 2, 1, 2, 3}) end, nil, @@ -851,7 +850,7 @@ describe('put command', function() base_expect_string, 'vp', function() - feed_command('set virtualedit=all') + command('setlocal virtualedit=all') funcs.setpos('.', {0, 1, 16, 2, 18}) end, true, @@ -920,12 +919,12 @@ describe('put command', function() end) it('should ring the bell when deleting if not appropriate', function() - feed_command('goto 2') - feed('i<bs><esc>') - expect([[ - ine of words 1 - Line of words 2]]) - bell_test(function() feed('".P') end, true) + command('goto 2') + feed('i<bs><esc>') + expect([[ + ine of words 1 + Line of words 2]]) + bell_test(function() feed('".P') end, true) end) it('should restore cursor position after undo of ".p', function() @@ -935,7 +934,7 @@ describe('put command', function() end) it("should be unaffected by 'autoindent' with V\".2p", function() - feed_command('set autoindent') + command('set autoindent') feed('i test_string.<esc>u') feed('V".2p') expect([[ diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua index 5ed71651c7..b6a3713158 100644 --- a/test/functional/ex_cmds/cd_spec.lua +++ b/test/functional/ex_cmds/cd_spec.lua @@ -1,6 +1,6 @@ -- Specs for :cd, :tcd, :lcd and getcwd() -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq @@ -11,6 +11,7 @@ local exc_exec = helpers.exc_exec local pathsep = helpers.get_pathsep() local skip = helpers.skip local is_os = helpers.is_os +local mkdir = helpers.mkdir -- These directories will be created for testing local directories = { @@ -36,14 +37,14 @@ for _, cmd in ipairs {'cd', 'chdir'} do before_each(function() clear() for _, d in pairs(directories) do - lfs.mkdir(d) + mkdir(d) end directories.start = cwd() end) after_each(function() for _, d in pairs(directories) do - lfs.rmdir(d) + luv.fs_rmdir(d) end end) @@ -273,7 +274,7 @@ end describe("getcwd()", function () before_each(function() clear() - lfs.mkdir(directories.global) + mkdir(directories.global) end) after_each(function() diff --git a/test/functional/ex_cmds/file_spec.lua b/test/functional/ex_cmds/file_spec.lua index 771c283134..131661828e 100644 --- a/test/functional/ex_cmds/file_spec.lua +++ b/test/functional/ex_cmds/file_spec.lua @@ -1,17 +1,18 @@ local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local clear = helpers.clear local command = helpers.command local eq = helpers.eq local funcs = helpers.funcs local rmdir = helpers.rmdir +local mkdir = helpers.mkdir describe(':file', function() - local swapdir = lfs.currentdir()..'/Xtest-file_spec' + local swapdir = luv.cwd()..'/Xtest-file_spec' before_each(function() clear() rmdir(swapdir) - lfs.mkdir(swapdir) + mkdir(swapdir) end) after_each(function() command('%bwipeout!') diff --git a/test/functional/ex_cmds/highlight_spec.lua b/test/functional/ex_cmds/highlight_spec.lua index 18f215cf75..45764e6719 100644 --- a/test/functional/ex_cmds/highlight_spec.lua +++ b/test/functional/ex_cmds/highlight_spec.lua @@ -3,6 +3,9 @@ local helpers = require("test.functional.helpers")(after_each) local eq, command = helpers.eq, helpers.command local clear = helpers.clear local eval, exc_exec = helpers.eval, helpers.exc_exec +local exec = helpers.exec +local funcs = helpers.funcs +local meths = helpers.meths describe(':highlight', function() local screen @@ -45,4 +48,20 @@ describe(':highlight', function() eq('', eval('synIDattr(hlID("NonText"), "undercurl", "gui")')) eq('1', eval('synIDattr(hlID("NonText"), "underline", "gui")')) end) + + it('clear', function() + meths.set_var('colors_name', 'foo') + eq(1, funcs.exists('g:colors_name')) + command('hi clear') + eq(0, funcs.exists('g:colors_name')) + meths.set_var('colors_name', 'foo') + eq(1, funcs.exists('g:colors_name')) + exec([[ + func HiClear() + hi clear + endfunc + ]]) + funcs.HiClear() + eq(0, funcs.exists('g:colors_name')) + end) end) diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua index 0a1cdd93aa..d70ccb5b39 100644 --- a/test/functional/ex_cmds/mksession_spec.lua +++ b/test/functional/ex_cmds/mksession_spec.lua @@ -1,4 +1,3 @@ -local lfs = require('lfs') local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') @@ -15,6 +14,7 @@ local sleep = helpers.sleep local meths = helpers.meths local skip = helpers.skip local is_os = helpers.is_os +local mkdir = helpers.mkdir local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec' @@ -26,7 +26,7 @@ describe(':mksession', function() before_each(function() clear() - lfs.mkdir(tab_dir) + mkdir(tab_dir) end) after_each(function() diff --git a/test/functional/ex_cmds/mkview_spec.lua b/test/functional/ex_cmds/mkview_spec.lua index fef8065b2e..f71b826210 100644 --- a/test/functional/ex_cmds/mkview_spec.lua +++ b/test/functional/ex_cmds/mkview_spec.lua @@ -1,4 +1,3 @@ -local lfs = require('lfs') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear @@ -7,6 +6,7 @@ local get_pathsep = helpers.get_pathsep local eq = helpers.eq local funcs = helpers.funcs local rmdir = helpers.rmdir +local mkdir = helpers.mkdir local file_prefix = 'Xtest-functional-ex_cmds-mkview_spec' @@ -17,8 +17,8 @@ describe(':mkview', function() before_each(function() clear() - lfs.mkdir(view_dir) - lfs.mkdir(local_dir) + mkdir(view_dir) + mkdir(local_dir) end) after_each(function() diff --git a/test/functional/ex_cmds/profile_spec.lua b/test/functional/ex_cmds/profile_spec.lua index bf045a4d1d..249373a9c4 100644 --- a/test/functional/ex_cmds/profile_spec.lua +++ b/test/functional/ex_cmds/profile_spec.lua @@ -1,5 +1,5 @@ require('os') -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local eval = helpers.eval @@ -12,18 +12,16 @@ local read_file = helpers.read_file -- tmpname() also creates the file on POSIX systems. Remove it again. -- We just need the name, ignoring any race conditions. -if lfs.attributes(tempfile, 'uid') then +if luv.fs_stat(tempfile).uid then os.remove(tempfile) end local function assert_file_exists(filepath) - -- Use 2-argument lfs.attributes() so no extra table gets created. - -- We don't really care for the uid. - neq(nil, lfs.attributes(filepath, 'uid')) + neq(nil, luv.fs_stat(filepath).uid) end local function assert_file_exists_not(filepath) - eq(nil, lfs.attributes(filepath, 'uid')) + eq(nil, luv.fs_stat(filepath)) end describe(':profile', function() @@ -31,7 +29,7 @@ describe(':profile', function() after_each(function() helpers.expect_exit(command, 'qall!') - if lfs.attributes(tempfile, 'uid') ~= nil then + if luv.fs_stat(tempfile).uid ~= nil then os.remove(tempfile) end end) diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua index ad59025d47..639bc6c94e 100644 --- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua +++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua @@ -1,6 +1,5 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') local luv = require('luv') local eq, eval, expect, exec = helpers.eq, helpers.eval, helpers.expect, helpers.exec @@ -21,6 +20,7 @@ local spawn = helpers.spawn local nvim_async = helpers.nvim_async local expect_msg_seq = helpers.expect_msg_seq local pcall_err = helpers.pcall_err +local mkdir = helpers.mkdir describe(':recover', function() before_each(clear) @@ -39,7 +39,7 @@ describe(':recover', function() end) describe("preserve and (R)ecover with custom 'directory'", function() - local swapdir = lfs.currentdir()..'/Xtest_recover_dir' + local swapdir = luv.cwd()..'/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 @@ -54,7 +54,7 @@ describe("preserve and (R)ecover with custom 'directory'", function() nvim1 = spawn(new_argv()) set_session(nvim1) rmdir(swapdir) - lfs.mkdir(swapdir) + mkdir(swapdir) end) after_each(function() command('%bwipeout!') @@ -126,7 +126,7 @@ describe("preserve and (R)ecover with custom 'directory'", function() end) describe('swapfile detection', function() - local swapdir = lfs.currentdir()..'/Xtest_swapdialog_dir' + local swapdir = luv.cwd()..'/Xtest_swapdialog_dir' local nvim0 -- Put swapdir at the start of the 'directory' list. #1836 -- Note: `set swapfile` *must* go after `set directory`: otherwise it may @@ -139,7 +139,7 @@ describe('swapfile detection', function() nvim0 = spawn(new_argv()) set_session(nvim0) rmdir(swapdir) - lfs.mkdir(swapdir) + mkdir(swapdir) end) after_each(function() set_session(nvim0) @@ -361,7 +361,8 @@ describe('swapfile detection', function() ]]) -- pretend that the swapfile was created before boot - lfs.touch(swname, os.time() - luv.uptime() - 10) + local atime = os.time() - luv.uptime() - 10 + luv.fs_utime(swname, atime, atime) feed(':edit Xswaptest<CR>') screen:expect({any = table.concat({ diff --git a/test/functional/ex_cmds/write_spec.lua b/test/functional/ex_cmds/write_spec.lua index 1ccd27875e..126646f21a 100644 --- a/test/functional/ex_cmds/write_spec.lua +++ b/test/functional/ex_cmds/write_spec.lua @@ -1,5 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local eq, eval, clear, write_file, source, insert = helpers.eq, helpers.eval, helpers.clear, helpers.write_file, helpers.source, helpers.insert @@ -153,7 +153,7 @@ describe(':write', function() end write_file(fname_bak, 'TTYX') skip(is_os('win'), [[FIXME: exc_exec('write!') outputs 0 in Windows]]) - lfs.link(fname_bak .. ('/xxxxx'):rep(20), fname, true) + luv.fs_symlink(fname_bak .. ('/xxxxx'):rep(20), fname) eq('Vim(write):E166: Can\'t open linked file for writing', pcall_err(command, 'write!')) end) diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua index 861a977ea6..7525343891 100644 --- a/test/functional/ex_cmds/wviminfo_spec.lua +++ b/test/functional/ex_cmds/wviminfo_spec.lua @@ -1,5 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local clear = helpers.clear local command, eq, neq, write_file = helpers.command, helpers.eq, helpers.neq, helpers.write_file @@ -21,10 +21,10 @@ describe(':wshada', function() it('creates a shada file', function() -- file should _not_ exist - eq(nil, lfs.attributes(shada_file)) + eq(nil, luv.fs_stat(shada_file)) command('wsh! '..shada_file) -- file _should_ exist - neq(nil, lfs.attributes(shada_file)) + neq(nil, luv.fs_stat(shada_file)) end) it('overwrites existing files', function() @@ -35,7 +35,7 @@ describe(':wshada', function() -- sanity check eq(text, read_file(shada_file)) - neq(nil, lfs.attributes(shada_file)) + neq(nil, luv.fs_stat(shada_file)) command('wsh! '..shada_file) diff --git a/test/functional/fixtures/api_level_11.mpack b/test/functional/fixtures/api_level_11.mpack Binary files differnew file mode 100644 index 0000000000..2399854c42 --- /dev/null +++ b/test/functional/fixtures/api_level_11.mpack diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 188c196eb3..2e373467d0 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -1,5 +1,4 @@ local luv = require('luv') -local lfs = require('lfs') local global_helpers = require('test.helpers') local Session = require('test.client.session') @@ -20,10 +19,9 @@ local tbl_contains = global_helpers.tbl_contains local fail = global_helpers.fail local module = { - mkdir = lfs.mkdir, } -local start_dir = lfs.currentdir() +local start_dir = luv.cwd() local runtime_set = 'set runtimepath^=./build/lib/nvim/' module.nvim_prog = ( os.getenv('NVIM_PRG') @@ -730,21 +728,17 @@ function module.assert_visible(bufnr, visible) end local function do_rmdir(path) - local mode, errmsg, errcode = lfs.attributes(path, 'mode') - if mode == nil then - if errcode == 2 then - -- "No such file or directory", don't complain. - return - end - error(string.format('rmdir: %s (%d)', errmsg, errcode)) + local stat = luv.fs_stat(path) + if stat == nil then + return end - if mode ~= 'directory' then + if stat.type ~= 'directory' then error(string.format('rmdir: not a directory: %s', path)) end - for file in lfs.dir(path) do + for file in vim.fs.dir(path) do if file ~= '.' and file ~= '..' then local abspath = path..'/'..file - if lfs.attributes(abspath, 'mode') == 'directory' then + if global_helpers.isdir(abspath) then do_rmdir(abspath) -- recurse else local ret, err = os.remove(abspath) @@ -764,9 +758,9 @@ local function do_rmdir(path) end end end - local ret, err = lfs.rmdir(path) + local ret, err = luv.fs_rmdir(path) if not ret then - error('lfs.rmdir('..path..'): '..err) + error('luv.fs_rmdir('..path..'): '..err) end end diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua index 7ae851467f..5b6d030567 100644 --- a/test/functional/legacy/011_autocommands_spec.lua +++ b/test/functional/legacy/011_autocommands_spec.lua @@ -13,7 +13,7 @@ -- being modified outside of Vim (noticed on Solaris). local helpers= require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local clear, feed_command, expect, eq, neq, dedent, write_file, feed = helpers.clear, helpers.feed_command, helpers.expect, helpers.eq, helpers.neq, helpers.dedent, helpers.write_file, helpers.feed @@ -31,8 +31,8 @@ local function prepare_gz_file(name, text) -- Compress the file with gzip. command([[call system(['gzip', '--force', ']]..name..[['])]]) -- This should create the .gz file and delete the original. - neq(nil, lfs.attributes(name..'.gz')) - eq(nil, lfs.attributes(name)) + neq(nil, luv.fs_stat(name..'.gz')) + eq(nil, luv.fs_stat(name)) end describe('file reading, writing and bufnew and filter autocommands', function() diff --git a/test/functional/legacy/012_directory_spec.lua b/test/functional/legacy/012_directory_spec.lua index dd207ca0b4..050e3855fe 100644 --- a/test/functional/legacy/012_directory_spec.lua +++ b/test/functional/legacy/012_directory_spec.lua @@ -4,7 +4,7 @@ -- - "dir", in directory relative to current dir local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local eq = helpers.eq local neq = helpers.neq @@ -17,10 +17,11 @@ local command = helpers.command local write_file = helpers.write_file local curbufmeths = helpers.curbufmeths local expect_exit = helpers.expect_exit +local mkdir = helpers.mkdir local function ls_dir_sorted(dirname) local files = {} - for f in lfs.dir(dirname) do + for f in vim.fs.dir(dirname) do if f ~= "." and f~= ".." then table.insert(files, f) end @@ -38,8 +39,8 @@ describe("'directory' option", function() end of testfile ]] write_file('Xtest1', text) - lfs.mkdir('Xtest.je') - lfs.mkdir('Xtest2') + mkdir('Xtest.je') + mkdir('Xtest2') write_file('Xtest2/Xtest3', text) clear() end) @@ -62,21 +63,21 @@ describe("'directory' option", function() meths.set_option('directory', '.') -- sanity check: files should not exist yet. - eq(nil, lfs.attributes('.Xtest1.swp')) + eq(nil, luv.fs_stat('.Xtest1.swp')) command('edit! Xtest1') poke_eventloop() eq('Xtest1', funcs.buffer_name('%')) -- Verify that the swapfile exists. In the legacy test this was done by -- reading the output from :!ls. - neq(nil, lfs.attributes('.Xtest1.swp')) + neq(nil, luv.fs_stat('.Xtest1.swp')) meths.set_option('directory', './Xtest2,.') command('edit Xtest1') poke_eventloop() -- swapfile should no longer exist in CWD. - eq(nil, lfs.attributes('.Xtest1.swp')) + eq(nil, luv.fs_stat('.Xtest1.swp')) eq({ "Xtest1.swp", "Xtest3" }, ls_dir_sorted("Xtest2")) diff --git a/test/functional/legacy/074_global_var_in_viminfo_spec.lua b/test/functional/legacy/074_global_var_in_viminfo_spec.lua index 445d742c1f..06d8b276d7 100644 --- a/test/functional/legacy/074_global_var_in_viminfo_spec.lua +++ b/test/functional/legacy/074_global_var_in_viminfo_spec.lua @@ -1,7 +1,7 @@ -- Tests for storing global variables in the .shada file local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local clear, command, eq, neq, eval, poke_eventloop = helpers.clear, helpers.command, helpers.eq, helpers.neq, helpers.eval, helpers.poke_eventloop @@ -39,7 +39,7 @@ describe('storing global variables in ShaDa files', function() poke_eventloop() -- Assert that the shada file exists. - neq(nil, lfs.attributes(tempname)) + neq(nil, luv.fs_stat(tempname)) command('unlet MY_GLOBAL_DICT') command('unlet MY_GLOBAL_LIST') -- Assert that the variables where deleted. diff --git a/test/functional/legacy/autochdir_spec.lua b/test/functional/legacy/autochdir_spec.lua index 13cb6cd287..5da54b4850 100644 --- a/test/functional/legacy/autochdir_spec.lua +++ b/test/functional/legacy/autochdir_spec.lua @@ -1,8 +1,8 @@ -local lfs = require('lfs') local helpers = require('test.functional.helpers')(after_each) local clear, eq, matches = helpers.clear, helpers.eq, helpers.matches local eval, command, call, meths = helpers.eval, helpers.command, helpers.call, helpers.meths local source, exec_capture = helpers.source, helpers.exec_capture +local mkdir = helpers.mkdir local function expected_empty() eq({}, meths.get_vvar('errors')) @@ -12,7 +12,7 @@ describe('autochdir behavior', function() local dir = 'Xtest_functional_legacy_autochdir' before_each(function() - lfs.mkdir(dir) + mkdir(dir) clear() command('set shellslash') end) diff --git a/test/functional/legacy/prompt_buffer_spec.lua b/test/functional/legacy/prompt_buffer_spec.lua index 602593d632..5c3f8a6f8c 100644 --- a/test/functional/legacy/prompt_buffer_spec.lua +++ b/test/functional/legacy/prompt_buffer_spec.lua @@ -3,9 +3,11 @@ local Screen = require('test.functional.ui.screen') local feed = helpers.feed local source = helpers.source local clear = helpers.clear +local command = helpers.command local poke_eventloop = helpers.poke_eventloop local meths = helpers.meths local eq = helpers.eq +local neq = helpers.neq describe('prompt buffer', function() local screen @@ -14,9 +16,11 @@ describe('prompt buffer', function() clear() screen = Screen.new(25, 10) screen:attach() - source([[ - set laststatus=0 nohidden + command('set laststatus=0 nohidden') + end) + local function source_script() + source([[ func TextEntered(text) if a:text == "exit" " Reset &modified to allow the buffer to be closed. @@ -63,7 +67,7 @@ describe('prompt buffer', function() ~ | -- INSERT -- | ]]) - end) + end after_each(function() screen:detach() @@ -71,6 +75,7 @@ describe('prompt buffer', function() -- oldtest: Test_prompt_basic() it('works', function() + source_script() feed("hello\n") screen:expect([[ cmd: hello | @@ -101,6 +106,7 @@ describe('prompt buffer', function() -- oldtest: Test_prompt_editing() it('editing', function() + source_script() feed("hello<BS><BS>") screen:expect([[ cmd: hel^ | @@ -170,6 +176,7 @@ describe('prompt buffer', function() -- oldtest: Test_prompt_switch_windows() it('switch windows', function() + source_script() feed("<C-O>:call SwitchWindows()<CR>") screen:expect{grid=[[ cmd: | @@ -213,11 +220,47 @@ describe('prompt buffer', function() -- oldtest: Test_prompt_while_writing_to_hidden_buffer() it('keeps insert mode after aucmd_restbuf in callback', function() + source_script() source [[ let s:buf = nvim_create_buf(1, 1) call timer_start(0, {-> nvim_buf_set_lines(s:buf, -1, -1, 0, ['walrus'])}) ]] poke_eventloop() - eq({ mode = "i", blocking = false }, meths.get_mode()) + eq({ mode = 'i', blocking = false }, meths.get_mode()) + end) + + -- oldtest: Test_prompt_appending_while_hidden() + it('accessing hidden prompt buffer does not start insert mode', function() + local prev_win = meths.get_current_win() + source([[ + new prompt + set buftype=prompt + set bufhidden=hide + + func s:TextEntered(text) + if a:text == 'exit' + close + endif + let g:entered = a:text + endfunc + call prompt_setcallback(bufnr(), function('s:TextEntered')) + + func DoAppend() + call appendbufline('prompt', '$', 'Test') + return '' + endfunc + ]]) + feed('asomething<CR>') + eq('something', meths.get_var('entered')) + neq(prev_win, meths.get_current_win()) + feed('exit<CR>') + eq(prev_win, meths.get_current_win()) + eq({ mode = 'n', blocking = false }, meths.get_mode()) + command('call DoAppend()') + eq({ mode = 'n', blocking = false }, meths.get_mode()) + feed('i') + eq({ mode = 'i', blocking = false }, meths.get_mode()) + command('call DoAppend()') + eq({ mode = 'i', blocking = false }, meths.get_mode()) end) end) diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 2cd3123dcd..04f4f89472 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -1,6 +1,6 @@ -- Test suite for testing interactions with API bindings local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local command = helpers.command local meths = helpers.meths @@ -754,7 +754,8 @@ describe('lua: nvim_buf_attach on_bytes', function() write_file("Xtest-reload", dedent [[ old line 1 old line 2]]) - lfs.touch("Xtest-reload", os.time() - 10) + local atime = os.time() - 10 + luv.fs_utime("Xtest-reload", atime, atime) command "e Xtest-reload" command "set autoread" diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 7b4d68c9cd..6b4ca5ac73 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -79,10 +79,6 @@ describe('vim.diagnostic', function() ]]) end) - after_each(function() - clear() - end) - it('creates highlight groups', function() command('runtime plugin/diagnostic.vim') eq({ diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index da60b5c13b..2fcbc9450f 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -1,5 +1,4 @@ local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') local clear = helpers.clear local exec_lua = helpers.exec_lua @@ -11,6 +10,7 @@ local test_build_dir = helpers.test_build_dir local test_source_path = helpers.test_source_path local nvim_prog = helpers.nvim_prog local is_os = helpers.is_os +local mkdir = helpers.mkdir local nvim_prog_basename = is_os('win') and 'nvim.exe' or 'nvim' @@ -133,10 +133,10 @@ describe('vim.fs', function() describe('dir()', function() before_each(function() - lfs.mkdir('testd') - lfs.mkdir('testd/a') - lfs.mkdir('testd/a/b') - lfs.mkdir('testd/a/b/c') + mkdir('testd') + mkdir('testd/a') + mkdir('testd/a/b') + mkdir('testd/a/b/c') end) after_each(function() @@ -271,10 +271,11 @@ describe('vim.fs', function() eq('C:/Users/jdoe', exec_lua [[ return vim.fs.normalize('C:\\Users\\jdoe') ]]) end) it('works with ~', function() - if is_os('win') then - pending([[$HOME does not exist on Windows ¯\_(ツ)_/¯]]) - end - eq(os.getenv('HOME') .. '/src/foo', exec_lua [[ return vim.fs.normalize('~/src/foo') ]]) + eq( exec_lua([[ + local home = ... + return home .. '/src/foo' + ]], is_os('win') and vim.fs.normalize(os.getenv('USERPROFILE')) or os.getenv('HOME') + ) , exec_lua [[ return vim.fs.normalize('~/src/foo') ]]) end) it('works with environment variables', function() local xdg_config_home = test_build_dir .. '/.config' diff --git a/test/functional/lua/inspector_spec.lua b/test/functional/lua/inspector_spec.lua index 5e488bb082..edc0519471 100644 --- a/test/functional/lua/inspector_spec.lua +++ b/test/functional/lua/inspector_spec.lua @@ -12,9 +12,13 @@ describe('vim.inspect_pos', function() it('it returns items', function() local ret = exec_lua([[ local buf = vim.api.nvim_create_buf(true, false) + local ns1 = vim.api.nvim_create_namespace("ns1") + local ns2 = vim.api.nvim_create_namespace("") vim.api.nvim_set_current_buf(buf) vim.api.nvim_buf_set_lines(0, 0, -1, false, {"local a = 123"}) vim.api.nvim_buf_set_option(buf, "filetype", "lua") + vim.api.nvim_buf_set_extmark(buf, ns1, 0, 10, { hl_group = "Normal" }) + vim.api.nvim_buf_set_extmark(buf, ns2, 0, 10, { hl_group = "Normal" }) vim.cmd("syntax on") return {buf, vim.inspect_pos(0, 0, 10)} ]]) @@ -24,7 +28,42 @@ describe('vim.inspect_pos', function() buffer = buf, col = 10, row = 0, - extmarks = {}, + extmarks = { + { + col = 10, + end_col = 11, + end_row = 0, + id = 1, + ns = 'ns1', + ns_id = 1, + opts = { + hl_eol = false, + hl_group = 'Normal', + hl_group_link = 'Normal', + ns_id = 1, + priority = 4096, + right_gravity = true + }, + row = 0 + }, + { + col = 10, + end_col = 11, + end_row = 0, + id = 1, + ns = '', + ns_id = 2, + opts = { + hl_eol = false, + hl_group = 'Normal', + hl_group_link = 'Normal', + ns_id = 2, + priority = 4096, + right_gravity = true + }, + row = 0 + } + }, treesitter = {}, semantic_tokens = {}, syntax = { diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 4f401eed8f..45d9263c0c 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -2721,11 +2721,11 @@ describe('lua stdlib', function() it('does not cause ml_get errors with invalid visual selection', function() -- Should be fixed by vim-patch:8.2.4028. exec_lua [[ - local a = vim.api - local t = function(s) return a.nvim_replace_termcodes(s, true, true, true) end - a.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) - a.nvim_feedkeys(t "G<C-V>", "txn", false) - a.nvim_buf_call(a.nvim_create_buf(false, true), function() vim.cmd "redraw" end) + local api = vim.api + local t = function(s) return api.nvim_replace_termcodes(s, true, true, true) end + api.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) + api.nvim_feedkeys(t "G<C-V>", "txn", false) + api.nvim_buf_call(api.nvim_create_buf(false, true), function() vim.cmd "redraw" end) ]] end) @@ -2800,29 +2800,29 @@ describe('lua stdlib', function() it('does not cause ml_get errors with invalid visual selection', function() -- Add lines to the current buffer and make another window looking into an empty buffer. exec_lua [[ - _G.a = vim.api - _G.t = function(s) return a.nvim_replace_termcodes(s, true, true, true) end - _G.win_lines = a.nvim_get_current_win() + _G.api = vim.api + _G.t = function(s) return api.nvim_replace_termcodes(s, true, true, true) end + _G.win_lines = api.nvim_get_current_win() vim.cmd "new" - _G.win_empty = a.nvim_get_current_win() - a.nvim_set_current_win(win_lines) - a.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) + _G.win_empty = api.nvim_get_current_win() + api.nvim_set_current_win(win_lines) + api.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) ]] -- Start Visual in current window, redraw in other window with fewer lines. -- Should be fixed by vim-patch:8.2.4018. exec_lua [[ - a.nvim_feedkeys(t "G<C-V>", "txn", false) - a.nvim_win_call(win_empty, function() vim.cmd "redraw" end) + api.nvim_feedkeys(t "G<C-V>", "txn", false) + api.nvim_win_call(win_empty, function() vim.cmd "redraw" end) ]] -- Start Visual in current window, extend it in other window with more lines. -- Fixed for win_execute by vim-patch:8.2.4026, but nvim_win_call should also not be affected. exec_lua [[ - a.nvim_feedkeys(t "<Esc>gg", "txn", false) - a.nvim_set_current_win(win_empty) - a.nvim_feedkeys(t "gg<C-V>", "txn", false) - a.nvim_win_call(win_lines, function() a.nvim_feedkeys(t "G<C-V>", "txn", false) end) + api.nvim_feedkeys(t "<Esc>gg", "txn", false) + api.nvim_set_current_win(win_empty) + api.nvim_feedkeys(t "gg<C-V>", "txn", false) + api.nvim_win_call(win_lines, function() api.nvim_feedkeys(t "G<C-V>", "txn", false) end) vim.cmd "redraw" ]] end) @@ -2836,14 +2836,14 @@ describe('lua stdlib', function() } screen:attach() exec_lua [[ - _G.a = vim.api + _G.api = vim.api vim.opt.ruler = true local lines = {} for i = 0, 499 do lines[#lines + 1] = tostring(i) end - a.nvim_buf_set_lines(0, 0, -1, true, lines) - a.nvim_win_set_cursor(0, {20, 0}) + api.nvim_buf_set_lines(0, 0, -1, true, lines) + api.nvim_win_set_cursor(0, {20, 0}) vim.cmd "split" - _G.win = a.nvim_get_current_win() + _G.win = api.nvim_get_current_win() vim.cmd "wincmd w | redraw" ]] screen:expect [[ @@ -2854,7 +2854,7 @@ describe('lua stdlib', function() | ]] exec_lua [[ - a.nvim_win_call(win, function() a.nvim_win_set_cursor(0, {100, 0}) end) + api.nvim_win_call(win, function() api.nvim_win_set_cursor(0, {100, 0}) end) vim.cmd "redraw" ]] screen:expect [[ @@ -2967,6 +2967,32 @@ describe('lua stdlib', function() }]], eval[[execute('lua vim.print(42, "abc", { a = { b = 77 }})')]]) end) + + it('vim.F.if_nil', function() + local function if_nil(...) + return exec_lua([[ + local args = {...} + local nargs = select('#', ...) + for i = 1, nargs do + if args[i] == vim.NIL then + args[i] = nil + end + end + return vim.F.if_nil(unpack(args, 1, nargs)) + ]], ...) + end + + local a = NIL + local b = NIL + local c = 42 + local d = false + eq(42, if_nil(a, c)) + eq(false, if_nil(d, b)) + eq(42, if_nil(a, b, c, d)) + eq(false, if_nil(d)) + eq(false, if_nil(d, c)) + eq(NIL, if_nil(a)) + end) end) describe('lua: builtin modules', function() diff --git a/test/functional/lua/watch_spec.lua b/test/functional/lua/watch_spec.lua index 554480c2b3..bbcfd27cde 100644 --- a/test/functional/lua/watch_spec.lua +++ b/test/functional/lua/watch_spec.lua @@ -3,7 +3,7 @@ local eq = helpers.eq local exec_lua = helpers.exec_lua local clear = helpers.clear local is_os = helpers.is_os -local lfs = require('lfs') +local mkdir = helpers.mkdir describe('vim._watch', function() before_each(function() @@ -14,7 +14,7 @@ describe('vim._watch', function() it('detects file changes', function() local root_dir = helpers.tmpname() os.remove(root_dir) - lfs.mkdir(root_dir) + mkdir(root_dir) local result = exec_lua( [[ @@ -102,7 +102,7 @@ describe('vim._watch', function() it('detects file changes', function() local root_dir = helpers.tmpname() os.remove(root_dir) - lfs.mkdir(root_dir) + mkdir(root_dir) local result = exec_lua( [[ diff --git a/test/functional/options/autochdir_spec.lua b/test/functional/options/autochdir_spec.lua index 0b6fe9533c..c75a98f35b 100644 --- a/test/functional/options/autochdir_spec.lua +++ b/test/functional/options/autochdir_spec.lua @@ -1,9 +1,10 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq local funcs = helpers.funcs local command = helpers.command +local mkdir = helpers.mkdir describe("'autochdir'", function() it('given on the shell gets processed properly', function() @@ -20,11 +21,11 @@ describe("'autochdir'", function() end) it('is not overwritten by getwinvar() call #17609',function() - local curdir = string.gsub(lfs.currentdir(), '\\', '/') + local curdir = string.gsub(luv.cwd(), '\\', '/') local dir_a = curdir..'/Xtest-functional-options-autochdir.dir_a' local dir_b = curdir..'/Xtest-functional-options-autochdir.dir_b' - lfs.mkdir(dir_a) - lfs.mkdir(dir_b) + mkdir(dir_a) + mkdir(dir_b) clear() command('set shellslash') command('set autochdir') diff --git a/test/functional/plugin/lsp/semantic_tokens_spec.lua b/test/functional/plugin/lsp/semantic_tokens_spec.lua index 780d18fce9..ec4d20974d 100644 --- a/test/functional/plugin/lsp/semantic_tokens_spec.lua +++ b/test/functional/plugin/lsp/semantic_tokens_spec.lua @@ -1367,7 +1367,7 @@ int main() exec_lua([[ local text = ... vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.fn.split(text, "\n")) - vim.wait(15) -- wait fot debounce + vim.wait(15) -- wait for debounce ]], test.text2) end diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 3de4c6275e..da05b09593 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -1,6 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) local lsp_helpers = require('test.functional.plugin.lsp.helpers') -local lfs = require('lfs') local assert_log = helpers.assert_log local buf_lines = helpers.buf_lines @@ -24,6 +23,7 @@ local is_ci = helpers.is_ci local meths = helpers.meths local is_os = helpers.is_os local skip = helpers.skip +local mkdir = helpers.mkdir local clear_notrace = lsp_helpers.clear_notrace local create_server_definition = lsp_helpers.create_server_definition @@ -3768,7 +3768,7 @@ describe('LSP', function() it('sends notifications when files change', function() local root_dir = helpers.tmpname() os.remove(root_dir) - lfs.mkdir(root_dir) + mkdir(root_dir) exec_lua(create_server_definition) local result = exec_lua([[ @@ -3877,14 +3877,14 @@ describe('LSP', function() local send_event require('vim.lsp._watchfiles')._watchfunc = function(_, _, callback) - local stoppped = false + local stopped = false send_event = function(...) - if not stoppped then + if not stopped then callback(...) end end return function() - stoppped = true + stopped = true end end diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua index 24bd363e95..cc21d08620 100644 --- a/test/functional/shada/shada_spec.lua +++ b/test/functional/shada/shada_spec.lua @@ -8,7 +8,7 @@ local write_file, spawn, set_session, nvim_prog, exc_exec = local is_os = helpers.is_os local skip = helpers.skip -local lfs = require('lfs') +local luv = require('luv') local paths = require('test.cmakeconfig.paths') local mpack = require('mpack') @@ -29,7 +29,7 @@ describe('ShaDa support code', function() after_each(function() clear() clean() - lfs.rmdir(dirname) + luv.fs_rmdir(dirname) end) it('preserves `s` item size limit with unknown entries', function() @@ -81,7 +81,7 @@ describe('ShaDa support code', function() wshada('Some text file') eq(0, exc_exec('wshada! ' .. shada_fname)) eq(1, read_shada_file(shada_fname)[1].type) - eq(nil, lfs.attributes(shada_fname .. '.tmp.a')) + eq(nil, luv.fs_stat(shada_fname .. '.tmp.a')) end) it('leaves .tmp.b in-place when there is error in original ShaDa and it has .tmp.a', function() @@ -251,8 +251,8 @@ describe('ShaDa support code', 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')) + eq(nil, luv.fs_stat('NONE')) + eq(nil, luv.fs_stat('NONE.tmp.a')) end) it('does not read NONE file', function() diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua index 00a35a5c6c..5d967e0340 100644 --- a/test/functional/terminal/scrollback_spec.lua +++ b/test/functional/terminal/scrollback_spec.lua @@ -575,12 +575,12 @@ describe("pending scrollback line handling", function() it("does not crash after setting 'number' #14891", function() exec_lua [[ - local a = vim.api - local buf = a.nvim_create_buf(true, true) - local chan = a.nvim_open_term(buf, {}) - a.nvim_win_set_option(0, "number", true) - a.nvim_chan_send(chan, ("a\n"):rep(11) .. "a") - a.nvim_win_set_buf(0, buf) + local api = vim.api + local buf = api.nvim_create_buf(true, true) + local chan = api.nvim_open_term(buf, {}) + api.nvim_win_set_option(0, "number", true) + api.nvim_chan_send(chan, ("a\n"):rep(11) .. "a") + api.nvim_win_set_buf(0, buf) ]] screen:expect [[ {1: 1 }^a | @@ -607,12 +607,11 @@ describe("pending scrollback line handling", function() it("does not crash after nvim_buf_call #14891", function() skip(is_os('win')) exec_lua [[ - local a = vim.api - local bufnr = a.nvim_create_buf(false, true) - a.nvim_buf_call(bufnr, function() + local bufnr = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_call(bufnr, function() vim.fn.termopen({"echo", ("hi\n"):rep(11)}) end) - a.nvim_win_set_buf(0, bufnr) + vim.api.nvim_win_set_buf(0, bufnr) vim.cmd("startinsert") ]] screen:expect [[ diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index ea9958b12a..9afce0b3a0 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -948,4 +948,48 @@ int x = INT_MAX; [16] = '1', [17] = '0' }, get_fold_levels()) end) + + it('tracks the root range properly (#22911)', function() + insert([[ + int main() { + int x = 3; + }]]) + + local query0 = [[ + (declaration) @declaration + (function_definition) @function + ]] + + exec_lua([[ + vim.treesitter.start(0, 'c') + ]]) + + local function run_query() + return exec_lua([[ + local query = vim.treesitter.query.parse("c", ...) + parser = vim.treesitter.get_parser() + tree = parser:parse()[1] + res = {} + for id, node in query:iter_captures(tree:root()) do + table.insert(res, {query.captures[id], node:range()}) + end + return res + ]], query0) + end + + eq({ + { 'function', 0, 0, 2, 1 }, + { 'declaration', 1, 2, 1, 12 } + }, run_query()) + + helpers.command'normal ggO' + insert('int a;') + + eq({ + { 'declaration', 0, 0, 0, 6 }, + { 'function', 1, 0, 3, 1 }, + { 'declaration', 2, 2, 2, 12 } + }, run_query()) + + end) end) diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index d03d2f1374..80e5b6230e 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -47,15 +47,15 @@ describe('decorations providers', function() local function setup_provider(code) return exec_lua ([[ - local a = vim.api - _G.ns1 = a.nvim_create_namespace "ns1" + local api = vim.api + _G.ns1 = api.nvim_create_namespace "ns1" ]] .. (code or [[ beamtrace = {} local function on_do(kind, ...) table.insert(beamtrace, {kind, ...}) end ]]) .. [[ - a.nvim_set_decoration_provider(_G.ns1, { + api.nvim_set_decoration_provider(_G.ns1, { on_start = on_do; on_buf = on_do; on_win = on_do; on_line = on_do; on_end = on_do; _on_spell_nav = on_do; @@ -75,8 +75,8 @@ describe('decorations providers', function() -- rather than append, which used to spin in an infinite loop allocating -- memory until nvim crashed/was killed. setup_provider([[ - local ns2 = a.nvim_create_namespace "ns2" - a.nvim_set_decoration_provider(ns2, {}) + local ns2 = api.nvim_create_namespace "ns2" + api.nvim_set_decoration_provider(ns2, {}) ]]) helpers.assert_alive() end) @@ -132,12 +132,12 @@ describe('decorations providers', function() it('can have single provider', function() insert(mulholland) setup_provider [[ - local hl = a.nvim_get_hl_id_by_name "ErrorMsg" - local test_ns = a.nvim_create_namespace "mulholland" + local hl = api.nvim_get_hl_id_by_name "ErrorMsg" + local test_ns = api.nvim_create_namespace "mulholland" function on_do(event, ...) if event == "line" then local win, buf, line = ... - a.nvim_buf_set_extmark(buf, test_ns, line, line, + api.nvim_buf_set_extmark(buf, test_ns, line, line, { end_line = line, end_col = line+1, hl_group = hl, ephemeral = true @@ -172,11 +172,11 @@ describe('decorations providers', function() ]] setup_provider [[ - local ns = a.nvim_create_namespace "spell" + local ns = api.nvim_create_namespace "spell" beamtrace = {} local function on_do(kind, ...) if kind == 'win' or kind == 'spell' then - a.nvim_buf_set_extmark(0, ns, 0, 0, { + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row = 2, end_col = 23, spell = true, @@ -330,12 +330,12 @@ describe('decorations providers', function() ]]} exec_lua [[ - local a = vim.api - local thewin = a.nvim_get_current_win() - local ns2 = a.nvim_create_namespace 'ns2' - a.nvim_set_decoration_provider (ns2, { + local api = vim.api + local thewin = api.nvim_get_current_win() + local ns2 = api.nvim_create_namespace 'ns2' + api.nvim_set_decoration_provider (ns2, { on_win = function (_, win, buf) - a.nvim_set_hl_ns_fast(win == thewin and _G.ns1 or ns2) + api.nvim_set_hl_ns_fast(win == thewin and _G.ns1 or ns2) end; }) ]] @@ -436,12 +436,12 @@ describe('decorations providers', function() it('can have virtual text', function() insert(mulholland) setup_provider [[ - local hl = a.nvim_get_hl_id_by_name "ErrorMsg" - local test_ns = a.nvim_create_namespace "mulholland" + local hl = api.nvim_get_hl_id_by_name "ErrorMsg" + local test_ns = api.nvim_create_namespace "mulholland" function on_do(event, ...) if event == "line" then local win, buf, line = ... - a.nvim_buf_set_extmark(buf, test_ns, line, 0, { + api.nvim_buf_set_extmark(buf, test_ns, line, 0, { virt_text = {{'+', 'ErrorMsg'}}; virt_text_pos='overlay'; ephemeral = true; @@ -465,12 +465,12 @@ describe('decorations providers', function() it('can have virtual text of the style: right_align', function() insert(mulholland) setup_provider [[ - local hl = a.nvim_get_hl_id_by_name "ErrorMsg" - local test_ns = a.nvim_create_namespace "mulholland" + local hl = api.nvim_get_hl_id_by_name "ErrorMsg" + local test_ns = api.nvim_create_namespace "mulholland" function on_do(event, ...) if event == "line" then local win, buf, line = ... - a.nvim_buf_set_extmark(buf, test_ns, line, 0, { + api.nvim_buf_set_extmark(buf, test_ns, line, 0, { virt_text = {{'+'}, {string.rep(' ', line+1), 'ErrorMsg'}}; virt_text_pos='right_align'; ephemeral = true; @@ -494,12 +494,12 @@ describe('decorations providers', function() it('can highlight beyond EOL', function() insert(mulholland) setup_provider [[ - local test_ns = a.nvim_create_namespace "veberod" + local test_ns = api.nvim_create_namespace "veberod" function on_do(event, ...) if event == "line" then local win, buf, line = ... - if string.find(a.nvim_buf_get_lines(buf, line, line+1, true)[1], "buf") then - a.nvim_buf_set_extmark(buf, test_ns, line, 0, { + if string.find(api.nvim_buf_get_lines(buf, line, line+1, true)[1], "buf") then + api.nvim_buf_set_extmark(buf, test_ns, line, 0, { end_line = line+1; hl_group = 'DiffAdd'; hl_eol = true; @@ -534,9 +534,9 @@ describe('decorations providers', function() local function on_do(kind, winid, bufnr, topline, botline_guess) if kind == 'win' then if topline < 100 and botline_guess > 100 then - vim.api.nvim_buf_set_extmark(bufnr, ns1, 99, -1, { sign_text = 'X' }) + api.nvim_buf_set_extmark(bufnr, ns1, 99, -1, { sign_text = 'X' }) else - vim.api.nvim_buf_clear_namespace(bufnr, ns1, 0, -1) + api.nvim_buf_clear_namespace(bufnr, ns1, 0, -1) end end end diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 6d9197e1df..3203b187cc 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -65,20 +65,20 @@ describe('float window', function() it('closed immediately by autocmd #11383', function() eq('Window was closed immediately', pcall_err(exec_lua, [[ - local a = vim.api + local api = vim.api local function crashes(contents) - local buf = a.nvim_create_buf(false, true) - local floatwin = a.nvim_open_win(buf, true, { + local buf = api.nvim_create_buf(false, true) + local floatwin = api.nvim_open_win(buf, true, { relative = 'cursor'; style = 'minimal'; row = 0; col = 0; height = #contents; width = 10; }) - a.nvim_buf_set_lines(buf, 0, -1, true, contents) + api.nvim_buf_set_lines(buf, 0, -1, true, contents) local winnr = vim.fn.win_id2win(floatwin) - a.nvim_command('wincmd p') - a.nvim_command('autocmd CursorMoved * ++once '..winnr..'wincmd c') + api.nvim_command('wincmd p') + api.nvim_command('autocmd CursorMoved * ++once '..winnr..'wincmd c') return buf, floatwin end crashes{'foo'} @@ -4954,6 +4954,53 @@ describe('float window', function() end) end) + it("can use Normal as background", function() + local buf = meths.create_buf(false,false) + meths.buf_set_lines(buf,0,-1,true,{"here", "float"}) + local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + meths.set_option_value('winhl', 'Normal:Normal', {win=win}) + + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 5 + here | + float | + ]], float_pos={ + [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + }} + else + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }here {0: }| + {0:~ }float {0: }| + {0:~ }| + {0:~ }| + | + ]]} + end + end) + describe("handles :wincmd", function() local win local expected_pos diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index 96e28c1978..a99b77f707 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -4,7 +4,6 @@ local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq local command = helpers.command local feed_command = helpers.feed_command local insert = helpers.insert -local expect = helpers.expect local funcs = helpers.funcs local meths = helpers.meths local exec = helpers.exec @@ -2023,29 +2022,4 @@ describe("folded lines", function() describe('without ext_multigrid', function() with_ext_multigrid(false) end) - - it('no folds remains if :delete makes buffer empty #19671', function() - funcs.setline(1, {'foo', 'bar', 'baz'}) - command('2,3fold') - command('%delete') - eq(0, funcs.foldlevel(1)) - end) - - it('multibyte fold markers work #20438', function() - exec([[ - setlocal foldmethod=marker - setlocal foldmarker=«,» - setlocal commentstring=/*%s*/ - ]]) - insert([[ - bbbbb - bbbbb - bbbbb]]) - feed('zfgg') - expect([[ - bbbbb/*«*/ - bbbbb - bbbbb/*»*/]]) - eq(1, funcs.foldlevel(1)) - end) end) diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index dce886ac91..fedfaca7ba 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -2432,6 +2432,23 @@ describe("'winhighlight' highlight", function() | ]]} end) + + it('can link to empty highlight group', function() + command 'hi NormalNC guibg=Red' -- czerwone time + command 'set winhl=NormalNC:Normal' + command 'split' + + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }| + {3:[No Name] }| + | + {0:~ }| + {4:[No Name] }| + | + ]]} + end) end) describe('highlight namespaces', function() diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua index 0a253455ad..83c49e56a0 100644 --- a/test/functional/ui/statuscolumn_spec.lua +++ b/test/functional/ui/statuscolumn_spec.lua @@ -397,6 +397,29 @@ describe('statuscolumn', function() {0:~ }| | ]]) + -- Also test virt_lines when 'cpoptions' includes "n" + exec_lua([[ + vim.opt.cpoptions:append("n") + local ns = vim.api.nvim_create_namespace("ns") + vim.api.nvim_buf_set_extmark(0, ns, 14, 0, { virt_lines = {{{"virt_line1", ""}}} }) + vim.api.nvim_buf_set_extmark(0, ns, 14, 0, { virt_lines = {{{"virt_line2", ""}}} }) + ]]) + screen:expect([[ + {1:buffer 0 13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaa | + {1:buffer 0 14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaa | + {1:buffer 0 15}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaa | + {1:virtual-2 15}virt_line1 | + {1:virtual-2 15}virt_line2 | + {1:buffer 0 16}{5:^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| + {5:aaaaaaaaa }| + {1:virtual-1 16}END | + {0:~ }| + {0:~ }| + | + ]]) end) it("works with 'statuscolumn' clicks", function() diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua index ffd45a59a3..8e301dc70c 100644 --- a/test/functional/ui/statusline_spec.lua +++ b/test/functional/ui/statusline_spec.lua @@ -636,3 +636,20 @@ it('statusline is redrawn on recording state change #22683', function() recording @Q | ]]) end) + +it('ruler is redrawn in cmdline with redrawstatus #22804', function() + clear() + local screen = Screen.new(40, 2) + screen:attach() + command([[ + let g:n = 'initial value' + set ls=1 ru ruf=%{g:n} + redraw + let g:n = 'other value' + redrawstatus + ]]) + screen:expect([[ + ^ | + other value | + ]]) +end) diff --git a/test/functional/vimscript/api_functions_spec.lua b/test/functional/vimscript/api_functions_spec.lua index c032ac3030..dc591c3e0d 100644 --- a/test/functional/vimscript/api_functions_spec.lua +++ b/test/functional/vimscript/api_functions_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local lfs = require('lfs') +local luv = require('luv') local neq, eq, command = helpers.neq, helpers.eq, helpers.command local clear, curbufmeths = helpers.clear, helpers.curbufmeths local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval @@ -118,7 +118,7 @@ describe('eval-API', function() end) it('are highlighted by vim.vim syntax file', function() - if lfs.attributes("build/runtime/syntax/vim/generated.vim",'uid') == nil then + if luv.fs_stat("build/runtime/syntax/vim/generated.vim").uid == nil then pending("runtime was not built, skipping test") return end diff --git a/test/functional/vimscript/buf_functions_spec.lua b/test/functional/vimscript/buf_functions_spec.lua index b521620320..7a54f479e0 100644 --- a/test/functional/vimscript/buf_functions_spec.lua +++ b/test/functional/vimscript/buf_functions_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local eq = helpers.eq local clear = helpers.clear @@ -16,6 +16,7 @@ local curtabmeths = helpers.curtabmeths local get_pathsep = helpers.get_pathsep local rmdir = helpers.rmdir local pcall_err = helpers.pcall_err +local mkdir = helpers.mkdir local fname = 'Xtest-functional-eval-buf_functions' local fname2 = fname .. '.2' @@ -62,7 +63,7 @@ describe('bufname() function', function() eq('', funcs.bufname('X')) end) before_each(function() - lfs.mkdir(dirname) + mkdir(dirname) end) after_each(function() rmdir(dirname) @@ -70,7 +71,7 @@ describe('bufname() function', function() it('returns expected buffer name', function() eq('', funcs.bufname('%')) -- Buffer has no name yet command('file ' .. fname) - local wd = lfs.currentdir() + local wd = luv.cwd() local sep = get_pathsep() local curdirname = funcs.fnamemodify(wd, ':t') for _, arg in ipairs({'%', 1, 'X', wd}) do @@ -103,7 +104,7 @@ describe('bufnr() function', function() it('returns expected buffer number', function() eq(1, funcs.bufnr('%')) command('file ' .. fname) - local wd = lfs.currentdir() + local wd = luv.cwd() local curdirname = funcs.fnamemodify(wd, ':t') eq(1, funcs.bufnr(fname)) eq(1, funcs.bufnr(wd)) @@ -144,7 +145,7 @@ describe('bufwinnr() function', function() eq(-1, funcs.bufwinnr('X')) end) before_each(function() - lfs.mkdir(dirname) + mkdir(dirname) end) after_each(function() rmdir(dirname) diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index a8a901042b..b411b1e379 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -12,7 +12,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local lfs = require('lfs') +local mkdir = helpers.mkdir local clear = helpers.clear local eq = helpers.eq local exc_exec = helpers.exc_exec @@ -56,11 +56,11 @@ end) describe("backtick expansion", function() setup(function() clear() - lfs.mkdir("test-backticks") + mkdir("test-backticks") write_file("test-backticks/file1", "test file 1") write_file("test-backticks/file2", "test file 2") write_file("test-backticks/file3", "test file 3") - lfs.mkdir("test-backticks/subdir") + mkdir("test-backticks/subdir") write_file("test-backticks/subdir/file4", "test file 4") -- Long path might cause "Press ENTER" prompt; use :silent to avoid it. command('silent cd test-backticks') @@ -220,3 +220,38 @@ describe('listing functions using :function', function() assert_alive() end) end) + +it('no double-free in garbage collection #16287', function() + clear() + -- Don't use exec() here as using a named script reproduces the issue better. + write_file('Xgarbagecollect.vim', [[ + func Foo() abort + let s:args = [a:000] + let foo0 = "" + let foo1 = "" + let foo2 = "" + let foo3 = "" + let foo4 = "" + let foo5 = "" + let foo6 = "" + let foo7 = "" + let foo8 = "" + let foo9 = "" + let foo10 = "" + let foo11 = "" + let foo12 = "" + let foo13 = "" + let foo14 = "" + endfunc + + set updatetime=1 + call Foo() + call Foo() + ]]) + finally(function() + os.remove('Xgarbagecollect.vim') + end) + command('source Xgarbagecollect.vim') + sleep(10) + assert_alive() +end) diff --git a/test/functional/vimscript/glob_spec.lua b/test/functional/vimscript/glob_spec.lua index b8807ecfcc..948a63f050 100644 --- a/test/functional/vimscript/glob_spec.lua +++ b/test/functional/vimscript/glob_spec.lua @@ -1,17 +1,18 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local clear, command, eval, eq = helpers.clear, helpers.command, helpers.eval, helpers.eq +local mkdir = helpers.mkdir before_each(function() clear() - lfs.mkdir('test-glob') + mkdir('test-glob') -- Long path might cause "Press ENTER" prompt; use :silent to avoid it. command('silent cd test-glob') end) after_each(function() - lfs.rmdir('test-glob') + luv.fs_rmdir('test-glob') end) describe('glob()', function() diff --git a/test/functional/vimscript/writefile_spec.lua b/test/functional/vimscript/writefile_spec.lua index 8c8da9dc88..c816efd37b 100644 --- a/test/functional/vimscript/writefile_spec.lua +++ b/test/functional/vimscript/writefile_spec.lua @@ -1,6 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') +local mkdir = helpers.mkdir local clear = helpers.clear local eq = helpers.eq local funcs = helpers.funcs @@ -19,16 +20,16 @@ local ddname_tail = '2' local ddname = dname .. '/' .. ddname_tail before_each(function() - lfs.mkdir(dname) - lfs.mkdir(ddname) + mkdir(dname) + mkdir(ddname) clear() end) after_each(function() os.remove(fname) os.remove(dfname) - lfs.rmdir(ddname) - lfs.rmdir(dname) + luv.fs_rmdir(ddname) + luv.fs_rmdir(dname) end) describe('writefile()', function() diff --git a/test/helpers.lua b/test/helpers.lua index b01e966464..94dcf86c4d 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -3,7 +3,6 @@ local shared = vim local assert = require('luassert') local busted = require('busted') local luv = require('luv') -local lfs = require('lfs') local relpath = require('pl.path').relpath local Paths = require('test.cmakeconfig.paths') @@ -22,6 +21,28 @@ local module = { REMOVE_THIS = {}, } +function module.isdir(path) + if not path then + return false + end + local stat = luv.fs_stat(path) + if not stat then + return false + end + return stat.type == 'directory' +end + +function module.isfile(path) + if not path then + return false + end + local stat = luv.fs_stat(path) + if not stat then + return false + end + return stat.type == 'file' +end + function module.argss_to_cmd(...) local cmd = '' for i = 1, select('#', ...) do @@ -228,16 +249,16 @@ function module.glob(initial_path, re, exc_re) while #paths_to_check > 0 do local cur_path = paths_to_check[#paths_to_check] paths_to_check[#paths_to_check] = nil - for e in lfs.dir(cur_path) do + for e in vim.fs.dir(cur_path) do local full_path = cur_path .. '/' .. e local checked_path = full_path:sub(#initial_path + 1) if (not is_excluded(checked_path)) and e:sub(1, 1) ~= '.' then - local attrs = lfs.attributes(full_path) - if attrs then - local check_key = attrs.dev .. ':' .. tostring(attrs.ino) + local stat = luv.fs_stat(full_path) + if stat then + local check_key = stat.dev .. ':' .. tostring(stat.ino) if not checked_files[check_key] then checked_files[check_key] = true - if attrs.mode == 'directory' then + if stat.type == 'directory' then paths_to_check[#paths_to_check + 1] = full_path elseif not re or checked_path:match(re) then ret[#ret + 1] = full_path @@ -253,8 +274,8 @@ end function module.check_logs() local log_dir = os.getenv('LOG_DIR') local runtime_errors = {} - if log_dir and lfs.attributes(log_dir, 'mode') == 'directory' then - for tail in lfs.dir(log_dir) do + if log_dir and module.isdir(log_dir) then + for tail in vim.fs.dir(log_dir) do if tail:sub(1, 30) == 'valgrind-' or tail:find('san%.') then local file = log_dir .. '/' .. tail local fd = io.open(file) @@ -843,6 +864,11 @@ function module.read_nvim_log(logfile, ci_rename) return log end +function module.mkdir(path) + -- 493 is 0755 in decimal + return luv.fs_mkdir(path, 493) +end + module = shared.tbl_extend('error', module, Paths, shared, require('test.deprecated')) return module diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index 23adff3d3d..776aaae4ac 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -1227,27 +1227,11 @@ func Test_fs_file() call assert_equal('forth', &filetype) bwipe! - call writefile(['.( Forth displayed inline comment )'], 'Xfile.fs') - split Xfile.fs - call assert_equal('forth', &filetype) - bwipe! - call writefile(['\ Forth line comment'], 'Xfile.fs') split Xfile.fs call assert_equal('forth', &filetype) bwipe! - " empty line comment - no space required - call writefile(['\'], 'Xfile.fs') - split Xfile.fs - call assert_equal('forth', &filetype) - bwipe! - - call writefile(['\G Forth documentation comment '], 'Xfile.fs') - split Xfile.fs - call assert_equal('forth', &filetype) - bwipe! - call writefile([': squared ( n -- n^2 )', 'dup * ;'], 'Xfile.fs') split Xfile.fs call assert_equal('forth', &filetype) diff --git a/test/old/testdir/test_maparg.vim b/test/old/testdir/test_maparg.vim index f903f5b934..19130c1569 100644 --- a/test/old/testdir/test_maparg.vim +++ b/test/old/testdir/test_maparg.vim @@ -1,8 +1,9 @@ " Tests for maparg(), mapcheck() and mapset(). " Also test utf8 map with a 0x80 byte. -" Also test mapcheck() -func s:SID() +source shared.vim + +func s:SID() return str2nr(matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')) endfunc @@ -319,7 +320,28 @@ func Test_map_restore() call Check_ctrlb_map(dsimp, 0) nunmap <C-B> +endfunc +" Test restoring the script context of a mapping +func Test_map_restore_sid() + let after =<< trim [CODE] + call assert_equal("\tLast set from --cmd argument", + \ execute('verbose nmap ,n')->trim()->split("\n")[-1]) + let d = maparg(',n', 'n', 0, 1) + nunmap ,n + call assert_equal('No mapping found', + \ execute('verbose nmap ,n')->trim()->split("\n")[-1]) + call mapset('n', 0, d) + call assert_equal("\tLast set from --cmd argument", + \ execute('verbose nmap ,n')->trim()->split("\n")[-1]) + call writefile(v:errors, 'Xresult') + qall! + [CODE] + + if RunVim([], after, '--clean --cmd "nmap ,n <Nop>"') + call assert_equal([], readfile('Xresult')) + endif + call delete('Xresult') endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_prompt_buffer.vim b/test/old/testdir/test_prompt_buffer.vim index b1288b4892..2cc3f19b59 100644 --- a/test/old/testdir/test_prompt_buffer.vim +++ b/test/old/testdir/test_prompt_buffer.vim @@ -238,7 +238,7 @@ func Test_prompt_while_writing_to_hidden_buffer() \ done'], #{out_io: 'buffer', out_name: ''}) startinsert END - eval script->writefile(scriptName) + eval script->writefile(scriptName, 'D') let buf = RunVimInTerminal('-S ' .. scriptName, {}) call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))}) @@ -251,7 +251,55 @@ func Test_prompt_while_writing_to_hidden_buffer() call WaitForAssert({-> assert_equal('cmd:testtesttest', term_getline(buf, 1))}) call StopVimInTerminal(buf) - call delete(scriptName) +endfunc + +func Test_prompt_appending_while_hidden() + call CanTestPromptBuffer() + + let script =<< trim END + new prompt + set buftype=prompt + set bufhidden=hide + + func s:TextEntered(text) + if a:text == 'exit' + close + endif + echowin 'Entered:' a:text + endfunc + call prompt_setcallback(bufnr(), function('s:TextEntered')) + + func DoAppend() + call appendbufline('prompt', '$', 'Test') + return '' + endfunc + END + call writefile(script, 'XpromptBuffer', 'D') + + let buf = RunVimInTerminal('-S XpromptBuffer', {'rows': 10}) + call TermWait(buf) + + call term_sendkeys(buf, "asomething\<CR>") + call TermWait(buf) + + call term_sendkeys(buf, "exit\<CR>") + call TermWait(buf) + call assert_notmatch('-- INSERT --', term_getline(buf, 10)) + + call term_sendkeys(buf, ":call DoAppend()\<CR>") + call TermWait(buf) + call assert_notmatch('-- INSERT --', term_getline(buf, 10)) + + call term_sendkeys(buf, "i") + call TermWait(buf) + call assert_match('-- INSERT --', term_getline(buf, 10)) + + call term_sendkeys(buf, "\<C-R>=DoAppend()\<CR>") + call TermWait(buf) + call assert_match('-- INSERT --', term_getline(buf, 10)) + + call term_sendkeys(buf, "\<Esc>") + call StopVimInTerminal(buf) endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/unit/fixtures/multiqueue.c b/test/unit/fixtures/multiqueue.c index a8dca0a844..4f4f5989d9 100644 --- a/test/unit/fixtures/multiqueue.c +++ b/test/unit/fixtures/multiqueue.c @@ -7,13 +7,13 @@ #include "multiqueue.h" -void ut_multiqueue_put(MultiQueue *this, const char *str) +void ut_multiqueue_put(MultiQueue *self, const char *str) { - multiqueue_put(this, NULL, 1, str); + multiqueue_put(self, NULL, 1, str); } -const char *ut_multiqueue_get(MultiQueue *this) +const char *ut_multiqueue_get(MultiQueue *self) { - Event event = multiqueue_get(this); + Event event = multiqueue_get(self); return event.argv[0]; } diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua index 686af3b461..708929ad9f 100644 --- a/test/unit/helpers.lua +++ b/test/unit/helpers.lua @@ -148,7 +148,11 @@ local cdef = ffi.cdef local cimportstr -local previous_defines_init = '' +local previous_defines_init = [[ +typedef struct { char bytes[16]; } __attribute__((aligned(16))) __uint128_t; +typedef struct { char bytes[16]; } __attribute__((aligned(16))) __float128; +]] + local preprocess_cache_init = {} local previous_defines_mod = '' local preprocess_cache_mod = nil diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua index 71177f4c65..24b92edee5 100644 --- a/test/unit/os/env_spec.lua +++ b/test/unit/os/env_spec.lua @@ -10,8 +10,6 @@ local to_cstr = helpers.to_cstr local NULL = helpers.NULL local OK = 0 -require('lfs') - local cimp = cimport('./src/nvim/os/os.h') describe('env.c', function() diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua index 4d58a8934e..fd30ca70da 100644 --- a/test/unit/os/fileio_spec.lua +++ b/test/unit/os/fileio_spec.lua @@ -1,4 +1,4 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.unit.helpers')(after_each) local itp = helpers.gen_itp(it) @@ -7,6 +7,7 @@ local eq = helpers.eq local ffi = helpers.ffi local cimport = helpers.cimport local cppimport = helpers.cppimport +local mkdir = helpers.mkdir local m = cimport('./src/nvim/os/os.h', './src/nvim/os/fileio.h') cppimport('fcntl.h') @@ -25,7 +26,7 @@ local linkb = dir .. '/broken.lnk' local filec = dir .. '/created-file.dat' before_each(function() - lfs.mkdir(dir); + mkdir(dir); local f1 = io.open(file1, 'w') f1:write(fcontents) @@ -35,8 +36,8 @@ before_each(function() f2:write(fcontents) f2:close() - lfs.link('file1.dat', linkf, true) - lfs.link('broken.dat', linkb, true) + luv.fs_symlink('file1.dat', linkf) + luv.fs_symlink('broken.dat', linkb) end) after_each(function() @@ -45,7 +46,7 @@ after_each(function() os.remove(linkf) os.remove(linkb) os.remove(filec) - lfs.rmdir(dir) + luv.fs_rmdir(dir) end) local function file_open(fname, flags, mode) @@ -119,13 +120,13 @@ describe('file_open_fd', function() eq(0, m.file_close(fp, false)) end) itp('can use file descriptor returned by os_open for writing', function() - eq(nil, lfs.attributes(filec)) + eq(nil, luv.fs_stat(filec)) local fd = m.os_open(filec, m.kO_WRONLY + m.kO_CREAT, 384) local err, fp = file_open_fd(fd, m.kFileWriteOnly) eq(0, err) eq(4, file_write(fp, 'test')) eq(0, m.file_close(fp, false)) - eq(4, lfs.attributes(filec).size) + eq(4, luv.fs_stat(filec).size) eq('test', io.open(filec):read('*a')) end) end) @@ -139,13 +140,13 @@ describe('file_open_fd_new', function() eq(0, m.file_free(fp, false)) end) itp('can use file descriptor returned by os_open for writing', function() - eq(nil, lfs.attributes(filec)) + eq(nil, luv.fs_stat(filec)) local fd = m.os_open(filec, m.kO_WRONLY + m.kO_CREAT, 384) local err, fp = file_open_fd_new(fd, m.kFileWriteOnly) eq(0, err) eq(4, file_write(fp, 'test')) eq(0, m.file_free(fp, false)) - eq(4, lfs.attributes(filec).size) + eq(4, luv.fs_stat(filec).size) eq('test', io.open(filec):read('*a')) end) end) @@ -154,32 +155,32 @@ describe('file_open', function() itp('can create a rwx------ file with kFileCreate', function() local err, fp = file_open(filec, m.kFileCreate, 448) eq(0, err) - local attrs = lfs.attributes(filec) - eq('rwx------', attrs.permissions) + local attrs = luv.fs_stat(filec) + eq(33216, attrs.mode) eq(0, m.file_close(fp, false)) end) itp('can create a rw------- file with kFileCreate', function() local err, fp = file_open(filec, m.kFileCreate, 384) eq(0, err) - local attrs = lfs.attributes(filec) - eq('rw-------', attrs.permissions) + local attrs = luv.fs_stat(filec) + eq(33152, attrs.mode) eq(0, m.file_close(fp, false)) end) itp('can create a rwx------ file with kFileCreateOnly', function() local err, fp = file_open(filec, m.kFileCreateOnly, 448) eq(0, err) - local attrs = lfs.attributes(filec) - eq('rwx------', attrs.permissions) + local attrs = luv.fs_stat(filec) + eq(33216, attrs.mode) eq(0, m.file_close(fp, false)) end) itp('can create a rw------- file with kFileCreateOnly', function() local err, fp = file_open(filec, m.kFileCreateOnly, 384) eq(0, err) - local attrs = lfs.attributes(filec) - eq('rw-------', attrs.permissions) + local attrs = luv.fs_stat(filec) + eq(33152, attrs.mode) eq(0, m.file_close(fp, false)) end) @@ -228,7 +229,7 @@ describe('file_open', function() eq(0, err) eq(true, fp.wr) eq(0, m.file_close(fp, false)) - local attrs = lfs.attributes(file1) + local attrs = luv.fs_stat(file1) eq(0, attrs.size) end) @@ -237,14 +238,14 @@ describe('file_open', function() eq(0, err) eq(true, fp.wr) eq(0, m.file_close(fp, false)) - local attrs = lfs.attributes(file1) + local attrs = luv.fs_stat(file1) eq(4096, attrs.size) end) itp('fails to create a file with just kFileWriteOnly', function() local err, _ = file_open(filec, m.kFileWriteOnly, 384) eq(m.UV_ENOENT, err) - local attrs = lfs.attributes(filec) + local attrs = luv.fs_stat(filec) eq(nil, attrs) end) @@ -254,7 +255,7 @@ describe('file_open', function() eq(0, err) eq(true, fp.wr) eq(0, m.file_close(fp, false)) - local attrs = lfs.attributes(file1) + local attrs = luv.fs_stat(file1) eq(0, attrs.size) end) @@ -295,9 +296,9 @@ describe('file_close', function() eq(0, err) local wsize = file_write(fp, 'test') eq(4, wsize) - eq(0, lfs.attributes(filec).size) + eq(0, luv.fs_stat(filec).size) eq(0, m.file_close(fp, true)) - eq(wsize, lfs.attributes(filec).size) + eq(wsize, luv.fs_stat(filec).size) end) end) @@ -307,9 +308,9 @@ describe('file_free', function() eq(0, err) local wsize = file_write(fp, 'test') eq(4, wsize) - eq(0, lfs.attributes(filec).size) + eq(0, luv.fs_stat(filec).size) eq(0, m.file_free(fp, true)) - eq(wsize, lfs.attributes(filec).size) + eq(wsize, luv.fs_stat(filec).size) end) end) @@ -318,12 +319,12 @@ describe('file_fsync', function() local err, fp = file_open(filec, m.kFileCreateOnly, 384) eq(0, file_fsync(fp)) eq(0, err) - eq(0, lfs.attributes(filec).size) + eq(0, luv.fs_stat(filec).size) local wsize = file_write(fp, 'test') eq(4, wsize) - eq(0, lfs.attributes(filec).size) + eq(0, luv.fs_stat(filec).size) eq(0, file_fsync(fp)) - eq(wsize, lfs.attributes(filec).size) + eq(wsize, luv.fs_stat(filec).size) eq(0, m.file_close(fp, false)) end) end) @@ -333,12 +334,12 @@ describe('file_flush', function() local err, fp = file_open(filec, m.kFileCreateOnly, 384) eq(0, file_flush(fp)) eq(0, err) - eq(0, lfs.attributes(filec).size) + eq(0, luv.fs_stat(filec).size) local wsize = file_write(fp, 'test') eq(4, wsize) - eq(0, lfs.attributes(filec).size) + eq(0, luv.fs_stat(filec).size) eq(0, file_flush(fp)) - eq(wsize, lfs.attributes(filec).size) + eq(wsize, luv.fs_stat(filec).size) eq(0, m.file_close(fp, false)) end) end) @@ -412,7 +413,7 @@ describe('file_write', function() local wr = file_write(fp, fcontents) eq(#fcontents, wr) eq(0, m.file_close(fp, false)) - eq(wr, lfs.attributes(filec).size) + eq(wr, luv.fs_stat(filec).size) eq(fcontents, io.open(filec):read('*a')) end) @@ -429,7 +430,7 @@ describe('file_write', function() shift = shift + size end eq(0, m.file_close(fp, false)) - eq(#fcontents, lfs.attributes(filec).size) + eq(#fcontents, luv.fs_stat(filec).size) eq(fcontents, io.open(filec):read('*a')) end) @@ -446,7 +447,7 @@ describe('file_write', function() shift = shift + size end eq(0, m.file_close(fp, false)) - eq(#fcontents, lfs.attributes(filec).size) + eq(#fcontents, luv.fs_stat(filec).size) eq(fcontents, io.open(filec):read('*a')) end) end) diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua index c718244ea4..95a12f5b17 100644 --- a/test/unit/os/fs_spec.lua +++ b/test/unit/os/fs_spec.lua @@ -1,4 +1,4 @@ -local lfs = require('lfs') +local luv = require('luv') local bit = require('bit') local helpers = require('test.unit.helpers')(after_each) @@ -16,6 +16,7 @@ local to_cstr = helpers.to_cstr local OK = helpers.OK local FAIL = helpers.FAIL local NULL = helpers.NULL +local mkdir = helpers.mkdir local NODE_NORMAL = 0 local NODE_WRITABLE = 1 @@ -48,11 +49,11 @@ local function unset_bit(number, to_unset) end local function assert_file_exists(filepath) - neq(nil, lfs.attributes(filepath)) + neq(nil, luv.fs_stat(filepath)) end local function assert_file_does_not_exist(filepath) - eq(nil, lfs.attributes(filepath)) + eq(nil, luv.fs_stat(filepath)) end local function os_setperm(filename, perm) @@ -70,14 +71,14 @@ describe('fs.c', function() end before_each(function() - lfs.mkdir('unit-test-directory'); + mkdir('unit-test-directory'); io.open('unit-test-directory/test.file', 'w'):close() io.open('unit-test-directory/test_2.file', 'w'):close() - lfs.link('test.file', 'unit-test-directory/test_link.file', true) + luv.fs_symlink('test.file', 'unit-test-directory/test_link.file') - lfs.link('non_existing_file.file', 'unit-test-directory/test_broken_link.file', true) + luv.fs_symlink('non_existing_file.file', 'unit-test-directory/test_broken_link.file') -- The tests are invoked with an absolute path to `busted` executable. absolute_executable = arg[0] -- Split the absolute_executable path into a directory and filename. @@ -90,19 +91,19 @@ describe('fs.c', function() os.remove('unit-test-directory/test_link.file') os.remove('unit-test-directory/test_hlink.file') os.remove('unit-test-directory/test_broken_link.file') - lfs.rmdir('unit-test-directory') + luv.fs_rmdir('unit-test-directory') end) describe('os_dirname', function() itp('returns OK and writes current directory to the buffer', function() - local length = string.len(lfs.currentdir()) + 1 + local length = string.len(luv.cwd()) + 1 local buf = cstr(length, '') eq(OK, fs.os_dirname(buf, length)) - eq(lfs.currentdir(), ffi.string(buf)) + eq(luv.cwd(), ffi.string(buf)) end) itp('returns FAIL if the buffer is too small', function() - local length = string.len(lfs.currentdir()) + 1 + local length = string.len(luv.cwd()) + 1 local buf = cstr(length - 1, '') eq(FAIL, fs.os_dirname(buf, length - 1)) end) @@ -203,20 +204,20 @@ describe('fs.c', function() end) itp('returns the absolute path when given an executable relative to the current dir', function() - local old_dir = lfs.currentdir() + local old_dir = luv.cwd() - lfs.chdir(directory) + luv.chdir(directory) -- Rely on currentdir to resolve symlinks, if any. Testing against -- the absolute path taken from arg[0] may result in failure where -- the path has a symlink in it. - local canonical = lfs.currentdir() .. '/' .. executable_name + local canonical = luv.cwd() .. '/' .. executable_name local expected = exe(canonical) local relative_executable = './' .. executable_name local res = exe(relative_executable) -- Don't test yet; we need to chdir back first. - lfs.chdir(old_dir) + luv.chdir(old_dir) eq(expected, res) end) end) @@ -278,11 +279,11 @@ describe('fs.c', function() describe('os_fchown', function() local filename = 'unit-test-directory/test.file' itp('does not change owner and group if respective IDs are equal to -1', function() - local uid = lfs.attributes(filename, 'uid') - local gid = lfs.attributes(filename, 'gid') + local uid = luv.fs_stat(filename).uid + local gid = luv.fs_stat(filename).gid eq(0, os_fchown(filename, -1, -1)) - eq(uid, lfs.attributes(filename, 'uid')) - return eq(gid, lfs.attributes(filename, 'gid')) + eq(uid, luv.fs_stat(filename).uid) + return eq(gid, luv.fs_stat(filename).gid) end) -- Some systems may not have `id` utility. @@ -290,7 +291,7 @@ describe('fs.c', function() pending('skipped (missing `id` utility)', function() end) else itp('owner of a file may change the group of the file to any group of which that owner is a member', function() - local file_gid = lfs.attributes(filename, 'gid') + local file_gid = luv.fs_stat(filename).gid -- Gets ID of any group of which current user is a member except the -- group that owns the file. @@ -305,7 +306,7 @@ describe('fs.c', function() -- In that case we can not perform this test. if new_gid then eq(0, (os_fchown(filename, -1, new_gid))) - eq(new_gid, (lfs.attributes(filename, 'gid'))) + eq(new_gid, luv.fs_stat(filename).gid) end end) end @@ -548,7 +549,7 @@ describe('fs.c', function() --create the file local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("700", 8)) --verify permissions - eq('rwx------', lfs.attributes(new_file)['permissions']) + eq(33216, luv.fs_stat(new_file).mode) eq(0, os_close(fd)) end) @@ -557,7 +558,7 @@ describe('fs.c', function() --create the file local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("600", 8)) --verify permissions - eq('rw-------', lfs.attributes(new_file)['permissions']) + eq(33152, luv.fs_stat(new_file).mode) eq(0, os_close(fd)) end) @@ -766,7 +767,7 @@ describe('fs.c', function() eq(false, (os_isdir('unit-test-directory/new-dir'))) eq(0, (os_mkdir('unit-test-directory/new-dir', mode))) eq(true, (os_isdir('unit-test-directory/new-dir'))) - lfs.rmdir('unit-test-directory/new-dir') + luv.fs_rmdir('unit-test-directory/new-dir') end) end) @@ -801,7 +802,7 @@ describe('fs.c', function() eq(0, ret) eq(nil, failed_str) eq(true, os_isdir('unit-test-directory/new-dir-recurse')) - lfs.rmdir('unit-test-directory/new-dir-recurse') + luv.fs_rmdir('unit-test-directory/new-dir-recurse') eq(false, os_isdir('unit-test-directory/new-dir-recurse')) end) @@ -812,7 +813,7 @@ describe('fs.c', function() eq(0, ret) eq(nil, failed_str) eq(true, os_isdir('unit-test-directory/new-dir-recurse')) - lfs.rmdir('unit-test-directory/new-dir-recurse') + luv.fs_rmdir('unit-test-directory/new-dir-recurse') eq(false, os_isdir('unit-test-directory/new-dir-recurse')) end) @@ -823,7 +824,7 @@ describe('fs.c', function() eq(0, ret) eq(nil, failed_str) eq(true, os_isdir('unit-test-directory/new-dir-recurse')) - lfs.rmdir('unit-test-directory/new-dir-recurse') + luv.fs_rmdir('unit-test-directory/new-dir-recurse') eq(false, os_isdir('unit-test-directory/new-dir-recurse')) end) @@ -837,10 +838,10 @@ describe('fs.c', function() eq(true, os_isdir('unit-test-directory/new-dir-recurse/1')) eq(true, os_isdir('unit-test-directory/new-dir-recurse/1/2')) eq(true, os_isdir('unit-test-directory/new-dir-recurse/1/2/3')) - lfs.rmdir('unit-test-directory/new-dir-recurse/1/2/3') - lfs.rmdir('unit-test-directory/new-dir-recurse/1/2') - lfs.rmdir('unit-test-directory/new-dir-recurse/1') - lfs.rmdir('unit-test-directory/new-dir-recurse') + luv.fs_rmdir('unit-test-directory/new-dir-recurse/1/2/3') + luv.fs_rmdir('unit-test-directory/new-dir-recurse/1/2') + luv.fs_rmdir('unit-test-directory/new-dir-recurse/1') + luv.fs_rmdir('unit-test-directory/new-dir-recurse') eq(false, os_isdir('unit-test-directory/new-dir-recurse')) end) end) @@ -851,7 +852,7 @@ describe('fs.c', function() end) itp('removes the given directory and returns 0', function() - lfs.mkdir('unit-test-directory/new-dir') + mkdir('unit-test-directory/new-dir') eq(0, os_rmdir('unit-test-directory/new-dir')) eq(false, (os_isdir('unit-test-directory/new-dir'))) end) @@ -1005,7 +1006,7 @@ describe('fs.c', function() file:write('some bytes to get filesize != 0') file:flush() file:close() - local size = lfs.attributes(path, 'size') + local size = luv.fs_stat(path).size local info = file_info_new() assert.is_true(fs.os_fileinfo(path, info)) eq(size, fs.os_fileinfo_size(info)) @@ -1019,7 +1020,7 @@ describe('fs.c', function() local info = file_info_new() assert.is_true(fs.os_fileinfo(path, info)) eq(1, fs.os_fileinfo_hardlinks(info)) - lfs.link(path, path_link) + luv.fs_link(path, path_link) assert.is_true(fs.os_fileinfo(path, info)) eq(2, fs.os_fileinfo_hardlinks(info)) end) @@ -1028,11 +1029,7 @@ describe('fs.c', function() describe('os_fileinfo_blocksize', function() itp('returns the correct blocksize of a file', function() local path = 'unit-test-directory/test.file' - -- there is a bug in luafilesystem where - -- `lfs.attributes path, 'blksize'` returns the wrong value: - -- https://github.com/keplerproject/luafilesystem/pull/44 - -- using this workaround for now: - local blksize = lfs.attributes(path).blksize + local blksize = luv.fs_stat(path).blksize local info = file_info_new() assert.is_true(fs.os_fileinfo(path, info)) if blksize then diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index 1fc4e2496e..5808e2013a 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -1,4 +1,4 @@ -local lfs = require('lfs') +local luv = require('luv') local helpers = require('test.unit.helpers')(after_each) local itp = helpers.gen_itp(it) @@ -11,6 +11,7 @@ local to_cstr = helpers.to_cstr local NULL = helpers.NULL local OK = helpers.OK local FAIL = helpers.FAIL +local mkdir = helpers.mkdir cimport('string.h') local cimp = cimport('./src/nvim/os/os.h', './src/nvim/path.h') @@ -21,11 +22,11 @@ local buffer = nil describe('path.c', function() describe('path_full_dir_name', function() setup(function() - lfs.mkdir('unit-test-directory') + mkdir('unit-test-directory') end) teardown(function() - lfs.rmdir('unit-test-directory') + luv.fs_rmdir('unit-test-directory') end) local function path_full_dir_name(directory, buf, len) @@ -35,34 +36,34 @@ describe('path.c', function() before_each(function() -- Create empty string buffer which will contain the resulting path. - length = string.len(lfs.currentdir()) + 22 + length = string.len(luv.cwd()) + 22 buffer = cstr(length, '') end) itp('returns the absolute directory name of a given relative one', function() local result = path_full_dir_name('..', buffer, length) eq(OK, result) - local old_dir = lfs.currentdir() - lfs.chdir('..') - local expected = lfs.currentdir() - lfs.chdir(old_dir) + local old_dir = luv.cwd() + luv.chdir('..') + local expected = luv.cwd() + luv.chdir(old_dir) eq(expected, (ffi.string(buffer))) end) itp('returns the current directory name if the given string is empty', function() eq(OK, (path_full_dir_name('', buffer, length))) - eq(lfs.currentdir(), (ffi.string(buffer))) + eq(luv.cwd(), (ffi.string(buffer))) end) itp('works with a normal relative dir', function() local result = path_full_dir_name('unit-test-directory', buffer, length) - eq(lfs.currentdir() .. '/unit-test-directory', (ffi.string(buffer))) + eq(luv.cwd() .. '/unit-test-directory', (ffi.string(buffer))) eq(OK, result) end) itp('works with a non-existing relative dir', function() local result = path_full_dir_name('does-not-exist', buffer, length) - eq(lfs.currentdir() .. '/does-not-exist', (ffi.string(buffer))) + eq(luv.cwd() .. '/does-not-exist', (ffi.string(buffer))) eq(OK, result) end) @@ -268,27 +269,27 @@ describe('path.c', function() end) describe('path_try_shorten_fname', function() - local cwd = lfs.currentdir() + local cwd = luv.cwd() before_each(function() - lfs.mkdir('ut_directory') + mkdir('ut_directory') end) after_each(function() - lfs.chdir(cwd) - lfs.rmdir('ut_directory') + luv.chdir(cwd) + luv.fs_rmdir('ut_directory') end) describe('path_try_shorten_fname', function() itp('returns shortened path if possible', function() - lfs.chdir('ut_directory') - local full = to_cstr(lfs.currentdir() .. '/subdir/file.txt') + luv.chdir('ut_directory') + local full = to_cstr(luv.cwd() .. '/subdir/file.txt') eq('subdir/file.txt', (ffi.string(cimp.path_try_shorten_fname(full)))) end) itp('returns `full_path` if a shorter version is not possible', function() - local old = lfs.currentdir() - lfs.chdir('ut_directory') + local old = luv.cwd() + luv.chdir('ut_directory') local full = old .. '/subdir/file.txt' eq(full, (ffi.string(cimp.path_try_shorten_fname(to_cstr(full))))) end) @@ -300,7 +301,7 @@ describe('path_try_shorten_fname', function() end) describe('path.c path_guess_exepath', function() - local cwd = lfs.currentdir() + local cwd = luv.cwd() for _,name in ipairs({'./nvim', '.nvim', 'foo/nvim'}) do itp('"'..name..'" returns name catenated with CWD', function() @@ -354,7 +355,7 @@ end) describe('path.c', function() setup(function() - lfs.mkdir('unit-test-directory'); + mkdir('unit-test-directory'); io.open('unit-test-directory/test.file', 'w'):close() -- Since the tests are executed, they are called by an executable. We use @@ -368,7 +369,7 @@ describe('path.c', function() teardown(function() os.remove('unit-test-directory/test.file') - lfs.rmdir('unit-test-directory') + luv.fs_rmdir('unit-test-directory') end) describe('vim_FullName', function() @@ -420,7 +421,7 @@ describe('path.c', function() end) itp('concatenates filename if it does not contain a slash', function() - local expected = lfs.currentdir() .. '/test.file' + local expected = luv.cwd() .. '/test.file' local filename = 'test.file' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -430,7 +431,7 @@ describe('path.c', function() end) itp('concatenates directory name if it does not contain a slash', function() - local expected = lfs.currentdir() .. '/..' + local expected = luv.cwd() .. '/..' local filename = '..' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -440,10 +441,10 @@ describe('path.c', function() end) itp('enters given directory (instead of just concatenating the strings) if possible and if path contains a slash', function() - local old_dir = lfs.currentdir() - lfs.chdir('..') - local expected = lfs.currentdir() .. '/test.file' - lfs.chdir(old_dir) + local old_dir = luv.cwd() + luv.chdir('..') + local expected = luv.cwd() .. '/test.file' + luv.chdir(old_dir) local filename = '../test.file' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -472,7 +473,7 @@ describe('path.c', function() end) itp('works with some "normal" relative path with directories', function() - local expected = lfs.currentdir() .. '/unit-test-directory/test.file' + local expected = luv.cwd() .. '/unit-test-directory/test.file' local filename = 'unit-test-directory/test.file' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -482,7 +483,7 @@ describe('path.c', function() end) itp('does not modify the given filename', function() - local expected = lfs.currentdir() .. '/unit-test-directory/test.file' + local expected = luv.cwd() .. '/unit-test-directory/test.file' local filename = to_cstr('unit-test-directory/test.file') local buflen = string.len(expected) + 1 local buf = cstr(buflen, '') @@ -505,7 +506,7 @@ describe('path.c', function() end) itp('does not remove trailing slash from non-existing relative directory #20847', function() - local expected = lfs.currentdir() .. '/non_existing_dir/' + local expected = luv.cwd() .. '/non_existing_dir/' local filename = 'non_existing_dir/' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -515,7 +516,7 @@ describe('path.c', function() end) itp('expands "./" to the current directory #7117', function() - local expected = lfs.currentdir() .. '/unit-test-directory/test.file' + local expected = luv.cwd() .. '/unit-test-directory/test.file' local filename = './unit-test-directory/test.file' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -525,7 +526,7 @@ describe('path.c', function() end) itp('collapses "foo/../foo" to "foo" #7117', function() - local expected = lfs.currentdir() .. '/unit-test-directory/test.file' + local expected = luv.cwd() .. '/unit-test-directory/test.file' local filename = 'unit-test-directory/../unit-test-directory/test.file' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -542,8 +543,8 @@ describe('path.c', function() return ffi.string(c_file) end - before_each(function() lfs.mkdir('CamelCase') end) - after_each(function() lfs.rmdir('CamelCase') end) + before_each(function() mkdir('CamelCase') end) + after_each(function() luv.fs_rmdir('CamelCase') end) if ffi.os == 'Windows' or ffi.os == 'OSX' then itp('Corrects the case of file names in Mac and Windows', function() diff --git a/test/unit/preload.lua b/test/unit/preload.lua index 841e19b878..c2d051d98a 100644 --- a/test/unit/preload.lua +++ b/test/unit/preload.lua @@ -3,5 +3,4 @@ -- for more information about this. local ffi = require('ffi') local helpers = require('test.unit.helpers')(nil) -local lfs = require('lfs') local preprocess = require('test.unit.preprocess') diff --git a/test/unit/preprocess.lua b/test/unit/preprocess.lua index 1073855a7d..88f7a14d1f 100644 --- a/test/unit/preprocess.lua +++ b/test/unit/preprocess.lua @@ -199,12 +199,6 @@ function Gcc:preprocess(previous_defines, ...) {pseudoheader_fname}) defines = self:filter_standard_defines(defines) - -- lfs = require("lfs") - -- print("CWD: #{lfs.currentdir!}") - -- print("CMD: #{cmd}") - -- io.stderr\write("CWD: #{lfs.currentdir!}\n") - -- io.stderr\write("CMD: #{cmd}\n") - local declarations = repeated_read_cmd(self.path, self.preprocessor_extra_flags, self.get_declarations_extra_flags, diff --git a/test/unit/tempfile_spec.lua b/test/unit/tempfile_spec.lua index 44bd19c1d2..e35490a561 100644 --- a/test/unit/tempfile_spec.lua +++ b/test/unit/tempfile_spec.lua @@ -1,4 +1,3 @@ -local lfs = require('lfs') local helpers = require('test.unit.helpers')(after_each) local itp = helpers.gen_itp(it) @@ -30,7 +29,7 @@ describe('tempfile related functions', function() -- os_file_is_writable returns 2 for a directory which we have rights -- to write into. eq(lib.os_file_is_writable(helpers.to_cstr(dir)), 2) - for entry in lfs.dir(dir) do + for entry in vim.fs.dir(dir) do assert.True(entry == '.' or entry == '..') end end) diff --git a/test/unit/undo_spec.lua b/test/unit/undo_spec.lua index cdc5d3a99e..9261eca19d 100644 --- a/test/unit/undo_spec.lua +++ b/test/unit/undo_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.unit.helpers')(after_each) local itp = helpers.gen_itp(it) -local lfs = require('lfs') +local luv = require('luv') local child_call_once = helpers.child_call_once local sleep = helpers.sleep @@ -9,6 +9,7 @@ local cimport = helpers.cimport local to_cstr = helpers.to_cstr local neq = helpers.neq local eq = helpers.eq +local mkdir = helpers.mkdir cimport('./src/nvim/ex_cmds_defs.h') cimport('./src/nvim/buffer_defs.h') @@ -44,14 +45,14 @@ end) describe('u_write_undo', function() setup(function() - lfs.mkdir('unit-test-directory') - lfs.chdir('unit-test-directory') - options.p_udir = to_cstr(lfs.currentdir()) -- set p_udir to be the test dir + mkdir('unit-test-directory') + luv.chdir('unit-test-directory') + options.p_udir = to_cstr(luv.cwd()) -- set p_udir to be the test dir end) teardown(function() - lfs.chdir('..') - local success, err = lfs.rmdir('unit-test-directory') + luv.chdir('..') + local success, err = luv.fs_rmdir('unit-test-directory') if not success then print(err) -- inform tester if directory fails to delete end @@ -102,7 +103,7 @@ describe('u_write_undo', function() local test_permission_file = io.open(test_file_name, "w") test_permission_file:write("testing permissions") test_permission_file:close() - local test_permissions = lfs.attributes(test_file_name).permissions + local test_permissions = luv.fs_stat(test_file_name).mode -- Create vim buffer local c_file = to_cstr(test_file_name) @@ -115,7 +116,7 @@ describe('u_write_undo', function() local undo_file_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false)) -- Find out the permissions of the new file - local permissions = lfs.attributes(undo_file_name).permissions + local permissions = luv.fs_stat(undo_file_name).mode eq(test_permissions, permissions) -- delete the file now that we're done with it. @@ -130,7 +131,7 @@ describe('u_write_undo', function() end) itp('writes an undofile only readable by the user if the buffer is unnamed', function() - local correct_permissions = "rw-------" + local correct_permissions = 33152 local undo_file_name = "test.undo" -- Create vim buffer @@ -140,7 +141,7 @@ describe('u_write_undo', function() u_write_undo(undo_file_name, false, file_buffer, buffer_hash) -- Find out the permissions of the new file - local permissions = lfs.attributes(undo_file_name).permissions + local permissions = luv.fs_stat(undo_file_name).mode eq(correct_permissions, permissions) -- delete the file now that we're done with it. @@ -172,13 +173,13 @@ describe('u_write_undo', function() u_write_undo(nil, false, file_buffer, buffer_hash) local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false)) - local file_last_modified = lfs.attributes(correct_name).modification + local file_last_modified = luv.fs_stat(correct_name).mtime.sec sleep(1000) -- Ensure difference in timestamps. file_buffer.b_u_numhead = 1 -- Mark it as if there are changes u_write_undo(nil, false, file_buffer, buffer_hash) - local file_last_modified_2 = lfs.attributes(correct_name).modification + local file_last_modified_2 = luv.fs_stat(correct_name).mtime.sec -- print(file_last_modified, file_last_modified_2) neq(file_last_modified, file_last_modified_2) |