aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml45
-rwxr-xr-x.github/workflows/env.sh2
-rw-r--r--.github/workflows/notes.md42
-rw-r--r--.github/workflows/release.yml32
-rw-r--r--CMakeLists.txt16
-rw-r--r--LICENSE.txt (renamed from LICENSE)0
-rwxr-xr-xci/before_cache.sh4
-rw-r--r--ci/build.ps15
-rw-r--r--packaging/CMakeLists.txt78
-rw-r--r--packaging/logo.icnsbin0 -> 637562 bytes
-rw-r--r--packaging/logo.icobin0 -> 3518 bytes
-rw-r--r--packaging/logo.svg1
-rw-r--r--runtime/doc/api.txt23
-rw-r--r--runtime/doc/builtin.txt30
-rw-r--r--runtime/doc/editing.txt6
-rw-r--r--runtime/doc/lua.txt32
-rw-r--r--runtime/doc/options.txt8
-rw-r--r--runtime/doc/repeat.txt17
-rw-r--r--runtime/filetype.lua7
-rw-r--r--runtime/lua/vim/diagnostic.lua6
-rw-r--r--runtime/lua/vim/highlight.lua105
-rw-r--r--runtime/lua/vim/lsp/handlers.lua4
-rw-r--r--runtime/lua/vim/lsp/util.lua4
-rw-r--r--runtime/syntax/structurizr.vim9
-rw-r--r--src/nvim/api/buffer.c119
-rw-r--r--src/nvim/api/keysets.lua1
-rw-r--r--src/nvim/api/private/helpers.c47
-rw-r--r--src/nvim/api/vim.c4
-rw-r--r--src/nvim/buffer.c3
-rw-r--r--src/nvim/charset.c4
-rw-r--r--src/nvim/eval/funcs.c2
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/getchar.c2
-rw-r--r--src/nvim/highlight.c23
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/testdir/test_autocmd.vim6
-rw-r--r--src/nvim/testdir/test_breakindent.vim2
-rw-r--r--src/nvim/testdir/test_cindent.vim9
-rw-r--r--src/nvim/testdir/test_digraph.vim4
-rw-r--r--src/nvim/testdir/test_edit.vim2
-rw-r--r--src/nvim/testdir/test_functions.vim4
-rw-r--r--src/nvim/testdir/test_normal.vim8
-rw-r--r--src/nvim/testdir/test_profile.vim31
-rw-r--r--src/nvim/testdir/test_quickfix.vim2
-rw-r--r--src/nvim/testdir/test_registers.vim2
-rw-r--r--src/nvim/testdir/test_stat.vim2
-rw-r--r--src/nvim/testdir/test_suspend.vim4
-rw-r--r--src/nvim/testdir/test_system.vim26
-rw-r--r--src/nvim/testdir/test_vimscript.vim5
-rw-r--r--test/functional/api/buffer_spec.lua35
-rw-r--r--test/functional/api/highlight_spec.lua15
51 files changed, 656 insertions, 186 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c94729182c..94da9ec6f0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,6 +9,8 @@ on:
branches:
- 'master'
- 'release-[0-9]+.[0-9]+'
+ paths-ignore:
+ - 'runtime/doc/*'
# Cancel any in-progress CI runs for a PR if it is updated
concurrency:
@@ -29,19 +31,46 @@ jobs:
- name: Install apt packages
run: |
+ sudo add-apt-repository ppa:neovim-ppa/stable
sudo apt-get update
- sudo apt-get install -y autoconf automake build-essential ccache cmake gettext gperf libtool-bin locales ninja-build pkg-config flake8
-
- - name: Cache dependencies
+ sudo apt-get install -y \
+ autoconf \
+ automake \
+ build-essential \
+ ccache \
+ cmake \
+ flake8 \
+ gettext \
+ gperf \
+ libluajit-5.1-dev \
+ libmsgpack-dev \
+ libtermkey-dev \
+ libtool-bin \
+ libtree-sitter-dev \
+ libunibilium-dev \
+ libuv1-dev \
+ libvterm-dev \
+ locales \
+ lua-busted \
+ lua-check \
+ lua-filesystem \
+ lua-inspect \
+ lua-lpeg \
+ lua-luv-dev \
+ lua-nvim \
+ luajit \
+ ninja-build \
+ pkg-config
+
+ - name: Cache artifacts
uses: actions/cache@v2
with:
path: |
- ${{ env.CACHE_NVIM_DEPS_DIR }}
~/.ccache
- key: lint-${{ hashFiles('cmake/*', 'third-party/**', '**/CMakeLists.txt') }}-${{ github.base_ref }}
+ key: lint-${{ hashFiles('cmake/*', '**/CMakeLists.txt', '!third-party/**CMakeLists.txt') }}-${{ github.base_ref }}
- - name: Build third-party
- run: ./ci/before_script.sh
+ - name: Build nvim
+ run: ./ci/run_tests.sh build
- if: "!cancelled()"
name: clint
@@ -64,7 +93,6 @@ jobs:
run: ./ci/run_lint.sh single-includes
- name: Cache dependencies
- if: ${{ success() }}
run: ./ci/before_cache.sh
unixish:
@@ -176,7 +204,6 @@ jobs:
run: ./ci/run_tests.sh install_nvim
- name: Cache dependencies
- if: ${{ success() }}
run: ./ci/before_cache.sh
windows:
diff --git a/.github/workflows/env.sh b/.github/workflows/env.sh
index 0964995605..d424924c27 100755
--- a/.github/workflows/env.sh
+++ b/.github/workflows/env.sh
@@ -46,7 +46,9 @@ CLANG_SANITIZER=TSAN
EOF
;;
lint)
+ BUILD_FLAGS="$BUILD_FLAGS -DLIBLUV_LIBRARY:FILEPATH=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/lua/5.1/luv.so -DLIBLUV_INCLUDE_DIR:PATH=/usr/include/lua5.1"
cat <<EOF >> "$GITHUB_ENV"
+USE_BUNDLED=OFF
CI_TARGET=lint
EOF
;;
diff --git a/.github/workflows/notes.md b/.github/workflows/notes.md
index 9928d472b3..7181972696 100644
--- a/.github/workflows/notes.md
+++ b/.github/workflows/notes.md
@@ -6,8 +6,26 @@ ${NVIM_VERSION}
### Windows
-1. Extract **nvim-win64.zip**
-2. Run `nvim-qt.exe`
+#### Zip
+
+1. Download **nvim-win64.zip**
+2. Extract the zip.
+3. Run `nvim-qt.exe`
+
+#### MSI
+
+1. Download **nvim-win64.msi**
+2. Run the MSI
+3. Add the Neovim location to your path.
+ - Default location is `C:\Program Files\Neovim`
+4. Search and run `nvim-qt.exe` or run `nvim.exe` on your CLI of choice.
+
+#### NSIS
+
+1. Download **nvim-win64.exe**
+2. Run the installer.
+ - Ensure that the option to add the installation location to your path is checked if it's your first installation.
+3. Search and run `nvim-qt.exe` or run `nvim.exe` on your CLI of choice.
### macOS
@@ -17,6 +35,19 @@ ${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`
- If your system does not have FUSE you can [extract the appimage](https://github.com/AppImage/AppImageKit/wiki/FUSE#type-2-appimage):
@@ -32,9 +63,12 @@ ${NVIM_VERSION}
## SHA256 Checksums
```
-${SHA_LINUX_64}
+${SHA_LINUX_64_TAR}
+${SHA_LINUX_64_DEB}
${SHA_APP_IMAGE}
${SHA_APP_IMAGE_ZSYNC}
${SHA_MACOS}
-${SHA_WIN_64}
+${SHA_WIN_64_ZIP}
+${SHA_WIN_64_MSI}
+${SHA_WIN_64_EXE}
```
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 0e04bd8fa3..e954b57175 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -39,12 +39,17 @@ jobs:
printf '::set-output name=version::%s\n' "$(./build/bin/nvim --version | head -n 3 | sed -z 's/\n/%0A/g')"
printf '::set-output name=release::%s\n' "$(./build/bin/nvim --version | head -n 1)"
make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-linux64" install
- cd "$GITHUB_WORKSPACE/build/release"
- tar cfz nvim-linux64.tar.gz nvim-linux64
+ cd "$GITHUB_WORKSPACE/build/"
+ cpack -C $NVIM_BUILD_TYPE
- uses: actions/upload-artifact@v2
with:
name: nvim-linux64
- path: build/release/nvim-linux64.tar.gz
+ path: build/nvim-linux64.tar.gz
+ retention-days: 1
+ - uses: actions/upload-artifact@v2
+ with:
+ name: nvim-linux64
+ path: build/nvim-linux64.deb
retention-days: 1
appimage:
@@ -131,12 +136,21 @@ jobs:
- run: powershell ci\build.ps1 -NoTests
env:
CONFIGURATION: ${{ matrix.config }}
- - run: move build\Neovim.zip build\${{ matrix.archive }}.zip
- uses: actions/upload-artifact@v2
with:
name: ${{ matrix.archive }}
path: build/${{ matrix.archive }}.zip
retention-days: 1
+ - uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.archive }}
+ path: build/${{ matrix.archive }}.msi
+ retention-days: 1
+ - uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.archive }}
+ path: build/${{ matrix.archive }}.exe
+ retention-days: 1
publish:
needs: [linux, appimage, macOS, windows]
@@ -187,7 +201,9 @@ jobs:
run: |
cd ./nvim-linux64
sha256sum nvim-linux64.tar.gz > nvim-linux64.tar.gz.sha256sum
- echo "SHA_LINUX_64=$(cat nvim-linux64.tar.gz.sha256sum)" >> $GITHUB_ENV
+ 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
@@ -207,7 +223,11 @@ jobs:
run: |
cd ./nvim-win64
sha256sum nvim-win64.zip > nvim-win64.zip.sha256sum
- echo "SHA_WIN_64=$(cat nvim-win64.zip.sha256sum)" >> $GITHUB_ENV
+ echo "SHA_WIN_64_ZIP=$(cat nvim-win64.zip.sha256sum)" >> $GITHUB_ENV
+ sha256sum nvim-win64.msi > nvim-win64.msi.sha256sum
+ echo "SHA_WIN_64_MSI=$(cat nvim-win64.msi.sha256sum)" >> $GITHUB_ENV
+ sha256sum nvim-win64.exe > nvim-win64.exe.sha256sum
+ echo "SHA_WIN_64_EXE=$(cat nvim-win64.exe.sha256sum)" >> $GITHUB_ENV
- name: Publish release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0f05e1205..08d52eb071 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -736,17 +736,6 @@ else()
COMMENT "lualint: LUACHECK_PRG not defined")
endif()
-set(CPACK_PACKAGE_NAME "Neovim")
-set(CPACK_PACKAGE_VENDOR "neovim.io")
-set(CPACK_PACKAGE_VERSION ${NVIM_VERSION_MEDIUM})
-set(CPACK_PACKAGE_INSTALL_DIRECTORY "Neovim")
-# Set toplevel directory/installer name as Neovim
-set(CPACK_PACKAGE_FILE_NAME "Neovim")
-set(CPACK_TOPLEVEL_TAG "Neovim")
-set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
-set(CPACK_NSIS_MODIFY_PATH ON)
-set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
-include(CPack)
#add uninstall target
if(NOT TARGET uninstall)
@@ -758,3 +747,8 @@ if(NOT TARGET uninstall)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/UninstallHelper.cmake)
endif()
+
+
+if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
+ add_subdirectory(packaging)
+endif()
diff --git a/LICENSE b/LICENSE.txt
index c1b8286c4b..c1b8286c4b 100644
--- a/LICENSE
+++ b/LICENSE.txt
diff --git a/ci/before_cache.sh b/ci/before_cache.sh
index c86109168e..bec6c37bbe 100755
--- a/ci/before_cache.sh
+++ b/ci/before_cache.sh
@@ -7,6 +7,8 @@ CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CI_DIR}/common/build.sh"
source "${CI_DIR}/common/suite.sh"
+mkdir -p "${HOME}/.cache"
+
echo "before_cache.sh: cache size"
du -chd 1 "${HOME}/.cache" | sort -rh | head -20
@@ -16,7 +18,7 @@ ccache -s 2>/dev/null || true
find "${HOME}/.ccache" -name stats -delete
# Update the third-party dependency cache only if the build was successful.
-if ended_successfully; then
+if ended_successfully && [ -d "${DEPS_BUILD_DIR}" ]; then
# Do not cache downloads. They should not be needed with up-to-date deps.
rm -rf "${DEPS_BUILD_DIR}/build/downloads"
rm -rf "${CACHE_NVIM_DEPS_DIR}"
diff --git a/ci/build.ps1 b/ci/build.ps1
index 0953a708c8..c7c3b3d470 100644
--- a/ci/build.ps1
+++ b/ci/build.ps1
@@ -183,7 +183,4 @@ if (Test-Path -Path $env:ChocolateyInstall\bin\cpack.exe) {
}
# Build artifacts
-cpack -G ZIP -C RelWithDebInfo
-if ($env:APPVEYOR_REPO_TAG_NAME -ne $null) {
- cpack -G NSIS -C RelWithDebInfo
-}
+cpack -C $cmakeBuildType
diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt
new file mode 100644
index 0000000000..6ae744c2cd
--- /dev/null
+++ b/packaging/CMakeLists.txt
@@ -0,0 +1,78 @@
+set(CPACK_PACKAGE_NAME "Neovim")
+set(CPACK_PACKAGE_VENDOR "neovim.io")
+set(CPACK_PACKAGE_FILE_NAME "nvim")
+
+# From the GitHub About section
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Vim-fork focused on extensibility and usability.")
+
+set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
+
+# Pull the versions defined with the top level CMakeLists.txt
+set(CPACK_PACKAGE_VERSION_MAJOR ${NVIM_VERSION_MAJOR})
+set(CPACK_PACKAGE_VERSION_MINOR ${NVIM_VERSION_MINOR})
+set(CPACK_PACKAGE_VERSION_PATCH ${NVIM_VERSION_PATCH})
+
+# CPACK_VERBATIM_VARIABLES ensures that the variables prefixed with *CPACK_*
+# are correctly passed to the cpack program.
+# This should always be set to true.
+set(CPACK_VERBATIM_VARIABLES TRUE)
+
+set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt")
+set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md)
+
+
+if(WIN32)
+ set(CPACK_PACKAGE_FILE_NAME "nvim-win64")
+ set(CPACK_GENERATOR ZIP WIX NSIS)
+
+ # WIX
+ # CPACK_WIX_UPGRADE_GUID should be set, but should never change.
+ # CPACK_WIX_PRODUCT_GUID should not be set (leave as default to auto-generate).
+
+ # The following guid is just a randomly generated guid that's been pasted here.
+ # It has no special meaning other than to supply it to WIX.
+ set(CPACK_WIX_UPGRADE_GUID "207A1A70-7B0C-418A-A153-CA6883E38F4D")
+ set(CPACK_WIX_PRODUCT_ICON ${CMAKE_CURRENT_LIST_DIR}/logo.ico)
+
+ # NSIS
+ # install icon
+ set(CPACK_NSIS_MUI_ICON ${CMAKE_CURRENT_LIST_DIR}/logo.ico)
+
+ # uninstall icon
+ set(CPACK_NSIS_MUI_UNIICON ${CMAKE_CURRENT_LIST_DIR}/logo.ico)
+
+ # icon that appears when you search in Add/Remove programs
+ set(CPACK_NSIS_INSTALLED_ICON_NAME ${CMAKE_CURRENT_LIST_DIR}/logo.ico)
+
+ # name that appears in the list in Add/Remove programs
+ set(CPACK_NSIS_DISPLAY_NAME "Neovim")
+
+ # name used in various installer UI locations, such as the title
+ set(CPACK_NSIS_PACKAGE_NAME "Neovim")
+
+ # Allow the user to modify their path to include neovim during
+ # the installation process.
+ set(CPACK_NSIS_MODIFY_PATH TRUE)
+elseif(APPLE)
+ set(CPACK_PACKAGE_FILE_NAME "nvim-macos")
+ set(CPACK_GENERATOR TGZ)
+ set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_LIST_DIR}/logo.icns)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(CPACK_PACKAGE_FILE_NAME "nvim-linux64")
+ set(CPACK_GENERATOR TGZ DEB)
+ set(CPACK_DEBIAN_PACKAGE_NAME "Neovim") # required
+ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Neovim.io") # required
+
+ # Automatically compute required shared lib dependencies.
+ # Unfortunately, you "just need to know" that this has a hidden
+ # dependency on dpkg-shlibdeps whilst using a debian based host.
+ set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS TRUE)
+else()
+ set(CPACK_GENERATOR TGZ)
+endif()
+
+# CPack variables are loaded in on the call to include(CPack). If you set
+# variables *after* the inclusion, they don't get updated within the CPack
+# config. Note that some CPack commands should still be run after it, such
+# as cpack_add_component().
+include(CPack)
diff --git a/packaging/logo.icns b/packaging/logo.icns
new file mode 100644
index 0000000000..a6377d9cdb
--- /dev/null
+++ b/packaging/logo.icns
Binary files differ
diff --git a/packaging/logo.ico b/packaging/logo.ico
new file mode 100644
index 0000000000..a4523501b9
--- /dev/null
+++ b/packaging/logo.ico
Binary files differ
diff --git a/packaging/logo.svg b/packaging/logo.svg
new file mode 100644
index 0000000000..e8aa8bd33e
--- /dev/null
+++ b/packaging/logo.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 54 65" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#D" x=".5" y=".5"/><defs><linearGradient x1="50.00%" y1="0.00%" x2="50.00%" y2="100.00%" id="A"><stop stop-color="#16b0ed" stop-opacity=".8" offset="0%"/><stop stop-color="#0f59b2" stop-opacity=".837" offset="100%"/></linearGradient><linearGradient x1="50.00%" y1="0.00%" x2="50.00%" y2="100.00%" id="B"><stop stop-color="#7db643" offset="0%"/><stop stop-color="#367533" offset="100%"/></linearGradient><linearGradient x1="50.00%" y1="-0.00%" x2="50.00%" y2="100.01%" id="C"><stop stop-color="#88c649" stop-opacity=".8" offset="0%"/><stop stop-color="#439240" stop-opacity=".84" offset="100%"/></linearGradient></defs><symbol id="D" overflow="visible"><g stroke="none"><path d="M0 13.761L13.63 0v63.983L0 50.381z" fill="url(#A)"/><path d="M52.664 13.894L38.848.008l.281 63.976 13.63-13.602z" fill="url(#B)"/><path d="M13.621.011l35.435 54.07-9.916 9.915L3.686 10.046z" fill="url(#C)"/><path d="M13.633 25.092l-.019 2.13L2.676 11.069l1.013-1.032z" fill="#000" fill-opacity=".13"/></g></symbol></svg> \ No newline at end of file
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 1e1534c31f..de7db3b0b7 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -2152,6 +2152,29 @@ nvim_buf_get_option({buffer}, {name}) *nvim_buf_get_option()*
Return: ~
Option value
+ *nvim_buf_get_text()*
+nvim_buf_get_text({buffer}, {start_row}, {start_col}, {end_row}, {end_col},
+ {opts})
+ Gets a range from the buffer.
+
+ This differs from |nvim_buf_get_lines()| in that it allows
+ retrieving only portions of a line.
+
+ Indexing is zero-based. Column indices are end-exclusive.
+
+ Prefer |nvim_buf_get_lines()| when retrieving entire lines.
+
+ Parameters: ~
+ {buffer} Buffer handle, or 0 for current buffer
+ {start_row} First line index
+ {start_col} Starting byte offset of first line
+ {end_row} Last line index
+ {end_col} Ending byte offset of last line (exclusive)
+ {opts} Optional parameters. Currently unused.
+
+ Return: ~
+ Array of lines, or empty array for unloaded buffer.
+
nvim_buf_get_var({buffer}, {name}) *nvim_buf_get_var()*
Gets a buffer-scoped (b:) variable.
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 35a232c0c2..833da2622c 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1807,6 +1807,7 @@ exists({expr}) The result is a Number, which is |TRUE| if {expr} is
exists("$HOSTNAME")
exists("*strftime")
exists("*s:MyFunc")
+ exists("*MyFunc")
exists("bufcount")
exists(":Make")
exists("#CursorHold")
@@ -5863,16 +5864,22 @@ reltimestr({time}) *reltimestr()*
<
*remote_expr()* *E449*
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
- Send the {string} to {server}. The string is sent as an
- expression and the result is returned after evaluation.
- The result must be a String or a |List|. A |List| is turned
- into a String by joining the items with a line break in
- between (not at the end), like with join(expr, "\n").
+ Send the {string} to {server}. The {server} argument is a
+ string, also see |{server}|.
+
+ The string is sent as an expression and the result is returned
+ after evaluation. The result must be a String or a |List|. A
+ |List| is turned into a String by joining the items with a
+ line break in between (not at the end), like with join(expr,
+ "\n").
+
If {idvar} is present and not empty, it is taken as the name
of a variable and a {serverid} for later use with
|remote_read()| is stored there.
+
If {timeout} is given the read times out after this many
seconds. Otherwise a timeout of 600 seconds is used.
+
See also |clientserver| |RemoteReply|.
This function is not available in the |sandbox|.
Note: Any errors will cause a local error message to be issued
@@ -5890,7 +5897,7 @@ remote_expr({server}, {string} [, {idvar} [, {timeout}]])
remote_foreground({server}) *remote_foreground()*
Move the Vim server with the name {server} to the foreground.
- The {server} argument is a string.
+ The {server} argument is a string, also see |{server}|.
This works like: >
remote_expr({server}, "foreground()")
< Except that on Win32 systems the client does the work, to work
@@ -5926,12 +5933,17 @@ remote_read({serverid}, [{timeout}]) *remote_read()*
<
*remote_send()* *E241*
remote_send({server}, {string} [, {idvar}])
- Send the {string} to {server}. The string is sent as input
- keys and the function returns immediately. At the Vim server
- the keys are not mapped |:map|.
+ Send the {string} to {server}. The {server} argument is a
+ string, also see |{server}|.
+
+ The string is sent as input keys and the function returns
+ immediately. At the Vim server the keys are not mapped
+ |:map|.
+
If {idvar} is present, it is taken as the name of a variable
and a {serverid} for later use with remote_read() is stored
there.
+
See also |clientserver| |RemoteReply|.
This function is not available in the |sandbox|.
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index 8ddc661c0e..4ccf3f145c 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -196,7 +196,7 @@ If you want to keep the changed buffer without saving it, switch on the
Edit {file} always. Discard any changes to the
current buffer.
Also see |++opt| and |+cmd|.
-
+ *:edit_#* *:e#*
:e[dit] [++opt] [+cmd] #[count]
Edit the [count]th buffer (as shown by |:files|).
This command does the same as [count] CTRL-^. But ":e
@@ -356,7 +356,7 @@ as a wildcard when "[" is in the 'isfname' option. A simple way to avoid this
is to use "path\[[]abc]", this matches the file "path\[abc]".
*starstar-wildcard*
-Expanding "**" is possible on Unix, Win32, Mac OS/X and a few other systems.
+Expanding "**" is possible on Unix, Win32, macOS and a few other systems.
This allows searching a directory tree. This goes up to 100 directories deep.
Note there are some commands where this works slightly differently, see
|file-searching|.
@@ -1495,7 +1495,7 @@ which version of the file you want to keep.
The accuracy of the time check depends on the filesystem. On Unix it is
usually sub-second. With old file sytems and on MS-Windows it is normally one
-second. Use has('nanotime') check if sub-second time stamp checks are
+second. Use `has('nanotime')` to check if sub-second time stamp checks are
available.
There is one situation where you get the message while there is nothing wrong:
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 1a2d845281..355c31090e 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -595,13 +595,33 @@ vim.highlight.on_yank({opts}) *vim.highlight.on_yank()*
- {on_visual} highlight when yanking visual selection (default `true`)
- {event} event structure (default |v:event|)
-vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {rtype}, {inclusive})
+vim.highlight.range({bufnr}, {ns}, {hlgroup}, {start}, {finish}, {opts})
*vim.highlight.range()*
- Highlights the range between {start} and {finish} (tuples of {line,col})
- in buffer {bufnr} with the highlight group {higroup} using the namespace
- {ns}. Optional arguments are the type of range (characterwise, linewise,
- or blockwise, see |setreg|; default to characterwise) and whether the
- range is inclusive (default false).
+
+ Apply highlight group to range of text.
+
+ Parameters: ~
+ {bufnr} buffer number
+ {ns} namespace for highlights
+ {hlgroup} highlight group name
+ {start} starting position (tuple {line,col})
+ {finish} finish position (tuple {line,col})
+ {opts} optional parameters:
+ • `regtype`: type of range (characterwise, linewise,
+ or blockwise, see |setreg|), default `'v'`
+ • `inclusive`: range includes end position, default
+ `false`
+ • `priority`: priority of highlight, default
+ `vim.highlight.user` (see below)
+
+vim.highlight.priorities *vim.highlight.priorities*
+
+ Table with default priorities used for highlighting:
+ • `syntax`: `50`, used for standard syntax highlighting
+ • `treesitter`: `100`, used for tree-sitter-based highlighting
+ • `diagnostics`: `150`, used for code analysis such as diagnostics
+ • `user`: `200`, used for user-triggered highlights such as LSP
+ document symbols or `on_yank` autocommands
------------------------------------------------------------------------------
VIM.REGEX *lua-regex*
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 6e2bc228d0..2f76cc018c 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3040,7 +3040,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'guitablabel'* *'gtl'*
'guitablabel' 'gtl' string (default empty)
global
- When nonempty describes the text to use in a label of the GUI tab
+ When non-empty describes the text to use in a label of the GUI tab
pages line. When empty and when the result is empty Vim will use a
default label. See |setting-guitablabel| for more info.
@@ -3057,7 +3057,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'guitabtooltip'* *'gtt'*
'guitabtooltip' 'gtt' string (default empty)
global
- When nonempty describes the text to use in a tooltip for the GUI tab
+ When non-empty describes the text to use in a tooltip for the GUI tab
pages line. When empty Vim will use a default tooltip.
This option is otherwise just like 'guitablabel' above.
You can include a line break. Simplest method is to use |:let|: >
@@ -5906,7 +5906,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'statusline'* *'stl'* *E540* *E542*
'statusline' 'stl' string (default empty)
global or local to window |global-local|
- When nonempty, this option determines the content of the status line.
+ When non-empty, this option determines the content of the status line.
Also see |status-line|.
The option consists of printf style '%' items interspersed with
@@ -6222,7 +6222,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'tabline'* *'tal'*
'tabline' 'tal' string (default empty)
global
- When nonempty, this option determines the content of the tab pages
+ When non-empty, this option determines the content of the tab pages
line at the top of the Vim window. When empty Vim will use a default
tab pages line. See |setting-tabline| for more info.
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index a022049766..05529dc90a 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -253,21 +253,22 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
below "plugin", just like with plugins in
'runtimepath'.
- If the filetype detection was not enabled yet (this
+ If the filetype detection was already enabled (this
is usually done with a "syntax enable" or "filetype
- on" command in your .vimrc file), this will also look
+ on" command in your |init.vim|, or automatically during
+ |initialization|), and the package was found in
+ "pack/*/opt/{name}", this command will also look
for "{name}/ftdetect/*.vim" files.
When the optional ! is added no plugin files or
ftdetect scripts are loaded, only the matching
directories are added to 'runtimepath'. This is
- useful in your .vimrc. The plugins will then be
- loaded during initialization, see |load-plugins| (note
+ useful in your |init.vim|. The plugins will then be
+ loaded during |initialization|, see |load-plugins| (note
that the loading order will be reversed, because each
- directory is inserted before others).
- Note that for ftdetect scripts to be loaded
- you will need to write `filetype plugin indent on`
- AFTER all `packadd!` commands.
+ directory is inserted before others). In this case, the
+ ftdetect scripts will be loaded during |initialization|,
+ before the |load-plugins| step.
Also see |pack-add|.
diff --git a/runtime/filetype.lua b/runtime/filetype.lua
index fcfc5701f0..74e427c358 100644
--- a/runtime/filetype.lua
+++ b/runtime/filetype.lua
@@ -7,6 +7,7 @@ if vim.g.do_filetype_lua ~= 1 then
return
end
+-- TODO: Remove vim.cmd once Lua autocommands land
vim.cmd [[
augroup filetypedetect
au BufRead,BufNewFile * call v:lua.vim.filetype.match(expand('<afile>'))
@@ -18,6 +19,12 @@ runtime! ftdetect/*.lua
" Set a marker so that the ftdetect scripts are not sourced a second time by filetype.vim
let g:did_load_ftdetect = 1
+" If filetype.vim is disabled, set up the autocmd to use scripts.vim
+if exists('did_load_filetypes')
+ au BufRead,BufNewFile * if !did_filetype() && expand('<amatch>') !~ g:ft_ignore_pat | runtime! scripts.vim | endif
+ au StdinReadPost * if !did_filetype() | runtime! scripts.vim | endif
+endif
+
augroup END
]]
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index fda70b4e95..fcb1e61764 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -447,7 +447,7 @@ local function set_list(loclist, opts)
vim.fn.setqflist({}, ' ', { title = title, items = items })
end
if open then
- vim.api.nvim_command(loclist and "lopen" or "copen")
+ vim.api.nvim_command(loclist and "lopen" or "botright copen")
end
end
@@ -921,9 +921,7 @@ M.handlers.underline = {
higroup,
{ diagnostic.lnum, diagnostic.col },
{ diagnostic.end_lnum, diagnostic.end_col },
- 'v',
- false,
- 150
+ { priority = vim.highlight.priorities.diagnostics }
)
end
save_extmarks(underline_ns, bufnr)
diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua
index 12faa0a6e1..4105ef0675 100644
--- a/runtime/lua/vim/highlight.lua
+++ b/runtime/lua/vim/highlight.lua
@@ -1,9 +1,16 @@
local api = vim.api
-local highlight = {}
+local M = {}
+
+M.priorities = {
+ syntax = 50,
+ treesitter = 100,
+ diagnostics = 150,
+ user = 200,
+}
---@private
-function highlight.create(higroup, hi_info, default)
+function M.create(higroup, hi_info, default)
local options = {}
-- TODO: Add validation
for k, v in pairs(hi_info) do
@@ -13,28 +20,33 @@ function highlight.create(higroup, hi_info, default)
end
---@private
-function highlight.link(higroup, link_to, force)
+function M.link(higroup, link_to, force)
vim.cmd(string.format([[highlight%s link %s %s]], force and "!" or " default", higroup, link_to))
end
-
--- Highlight range between two positions
---
---@param bufnr number of buffer to apply highlighting to
---@param ns namespace to add highlight to
---@param higroup highlight group to use for highlighting
----@param rtype type of range (:help setreg, default charwise)
----@param inclusive boolean indicating whether the range is end-inclusive (default false)
----@param priority number indicating priority of highlight (default 50)
-function highlight.range(bufnr, ns, higroup, start, finish, rtype, inclusive, priority)
- rtype = rtype or 'v'
- inclusive = inclusive or false
- priority = priority or 50
+---@param start first position (tuple {line,col})
+---@param finish second position (tuple {line,col})
+---@param opts table with options:
+-- - regtype type of range (:help setreg, default charwise)
+-- - inclusive boolean indicating whether the range is end-inclusive (default false)
+-- - priority number indicating priority of highlight (default priorities.user)
+function M.range(bufnr, ns, higroup, start, finish, opts)
+ opts = opts or {}
+ local regtype = opts.regtype or "v"
+ local inclusive = opts.inclusive or false
+ local priority = opts.priority or M.priorities.user
-- sanity check
- if start[2] < 0 or finish[1] < start[1] then return end
+ if start[2] < 0 or finish[1] < start[1] then
+ return
+ end
- local region = vim.region(bufnr, start, finish, rtype, inclusive)
+ local region = vim.region(bufnr, start, finish, regtype, inclusive)
for linenr, cols in pairs(region) do
local end_row
if cols[2] == -1 then
@@ -46,13 +58,12 @@ function highlight.range(bufnr, ns, higroup, start, finish, rtype, inclusive, pr
end_row = end_row,
end_col = cols[2],
priority = priority,
- strict = false
+ strict = false,
})
end
-
end
-local yank_ns = api.nvim_create_namespace('hlyank')
+local yank_ns = api.nvim_create_namespace("hlyank")
--- Highlight the yanked region
---
--- use from init.vim via
@@ -62,26 +73,40 @@ local yank_ns = api.nvim_create_namespace('hlyank')
--- customize conditions (here: do not highlight a visual selection) via
--- au TextYankPost * lua vim.highlight.on_yank {on_visual=false}
---
--- @param opts dictionary with options controlling the highlight:
+-- @param opts table with options controlling the highlight:
-- - higroup highlight group for yanked region (default "IncSearch")
-- - timeout time in ms before highlight is cleared (default 150)
-- - on_macro highlight when executing macro (default false)
-- - on_visual highlight when yanking visual selection (default true)
-- - event event structure (default vim.v.event)
-function highlight.on_yank(opts)
- vim.validate {
- opts = { opts,
- function(t) if t == nil then return true else return type(t) == 'table' end end,
- 'a table or nil to configure options (see `:h highlight.on_yank`)',
- }}
+function M.on_yank(opts)
+ vim.validate({
+ opts = {
+ opts,
+ function(t)
+ if t == nil then
+ return true
+ else
+ return type(t) == "table"
+ end
+ end,
+ "a table or nil to configure options (see `:h highlight.on_yank`)",
+ },
+ })
opts = opts or {}
local event = opts.event or vim.v.event
local on_macro = opts.on_macro or false
local on_visual = (opts.on_visual ~= false)
- if (not on_macro) and vim.fn.reg_executing() ~= '' then return end
- if event.operator ~= 'y' or event.regtype == '' then return end
- if (not on_visual) and event.visual then return end
+ if not on_macro and vim.fn.reg_executing() ~= "" then
+ return
+ end
+ if event.operator ~= "y" or event.regtype == "" then
+ return
+ end
+ if not on_visual and event.visual then
+ return
+ end
local higroup = opts.higroup or "IncSearch"
local timeout = opts.timeout or 150
@@ -92,19 +117,23 @@ function highlight.on_yank(opts)
local pos1 = vim.fn.getpos("'[")
local pos2 = vim.fn.getpos("']")
- pos1 = {pos1[2] - 1, pos1[3] - 1 + pos1[4]}
- pos2 = {pos2[2] - 1, pos2[3] - 1 + pos2[4]}
-
- highlight.range(bufnr, yank_ns, higroup, pos1, pos2, event.regtype, event.inclusive, 200)
+ pos1 = { pos1[2] - 1, pos1[3] - 1 + pos1[4] }
+ pos2 = { pos2[2] - 1, pos2[3] - 1 + pos2[4] }
- vim.defer_fn(
- function()
- if api.nvim_buf_is_valid(bufnr) then
- api.nvim_buf_clear_namespace(bufnr, yank_ns, 0, -1)
- end
- end,
- timeout
+ M.range(
+ bufnr,
+ yank_ns,
+ higroup,
+ pos1,
+ pos2,
+ { regtype = event.regtype, inclusive = event.inclusive, priority = M.priorities.user }
)
+
+ vim.defer_fn(function()
+ if api.nvim_buf_is_valid(bufnr) then
+ api.nvim_buf_clear_namespace(bufnr, yank_ns, 0, -1)
+ end
+ end, timeout)
end
-return highlight
+return M
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index a997b887d9..f5aefd4402 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -336,7 +336,7 @@ local function location_handler(_, result, ctx, _)
title = 'LSP locations',
items = util.locations_to_items(result, client.offset_encoding)
})
- api.nvim_command("copen")
+ api.nvim_command("botright copen")
end
else
util.jump_to_location(result, client.offset_encoding)
@@ -430,7 +430,7 @@ local make_call_hierarchy_handler = function(direction)
end
end
vim.fn.setqflist({}, ' ', {title = 'LSP call hierarchy', items = items})
- api.nvim_command("copen")
+ api.nvim_command("botright copen")
end
end
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index d93331c12f..655c3a4679 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1551,9 +1551,7 @@ do --[[ References ]]
document_highlight_kind[kind],
{ start_line, start_idx },
{ end_line, end_idx },
- 'v',
- false,
- 200)
+ { priority = vim.highlight.priorities.user })
end
end
end
diff --git a/runtime/syntax/structurizr.vim b/runtime/syntax/structurizr.vim
index 73629b1495..ab9e4ee609 100644
--- a/runtime/syntax/structurizr.vim
+++ b/runtime/syntax/structurizr.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: Structurizr DSL
" Maintainer: Bastian Venthur <venthur@debian.org>
-" Last Change: 2021-08-16
+" Last Change: 2022-02-15
" Remark: For a language reference, see
" https://github.com/structurizr/dsl
@@ -30,6 +30,7 @@ syn keyword skeyword deployment
syn keyword skeyword deploymentenvironment
syn keyword skeyword deploymentgroup
syn keyword skeyword deploymentnode
+syn keyword skeyword description
syn keyword skeyword dynamic
syn keyword skeyword element
syn keyword skeyword enterprise
@@ -37,7 +38,6 @@ syn keyword skeyword exclude
syn keyword skeyword filtered
syn keyword skeyword group
syn keyword skeyword healthcheck
-syn keyword skeyword impliedrelationships
syn keyword skeyword include
syn keyword skeyword infrastructurenode
syn keyword skeyword model
@@ -51,6 +51,7 @@ syn keyword skeyword styles
syn keyword skeyword systemcontext
syn keyword skeyword systemlandscape
syn keyword skeyword tags
+syn keyword skeyword technology
syn keyword skeyword terminology
syn keyword skeyword theme
syn keyword skeyword title
@@ -63,7 +64,11 @@ syn match skeyword "\!adrs\s\+"
syn match skeyword "\!constant\s\+"
syn match skeyword "\!docs\s\+"
syn match skeyword "\!identifiers\s\+"
+syn match skeyword "\!impliedrelationships\s\+"
syn match skeyword "\!include\s\+"
+syn match skeyword "\!plugin\s\+"
+syn match skeyword "\!ref\s\+"
+syn match skeyword "\!script\s\+"
syn region sstring oneline start='"' end='"'
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 2d5403d4b8..922d288da1 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -287,8 +287,8 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
}
bool oob = false;
- start = normalize_index(buf, start, &oob);
- end = normalize_index(buf, end, &oob);
+ start = normalize_index(buf, start, true, &oob);
+ end = normalize_index(buf, end, true, &oob);
if (strict_indexing && oob) {
api_set_error(err, kErrorTypeValidation, "Index out of bounds");
@@ -374,15 +374,14 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ
}
bool oob = false;
- start = normalize_index(buf, start, &oob);
- end = normalize_index(buf, end, &oob);
+ start = normalize_index(buf, start, true, &oob);
+ end = normalize_index(buf, end, true, &oob);
if (strict_indexing && oob) {
api_set_error(err, kErrorTypeValidation, "Index out of bounds");
return;
}
-
if (start > end) {
api_set_error(err,
kErrorTypeValidation,
@@ -554,13 +553,13 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
// check range is ordered and everything!
// start_row, end_row within buffer len (except add text past the end?)
- start_row = normalize_index(buf, start_row, &oob);
+ start_row = normalize_index(buf, start_row, false, &oob);
if (oob || start_row == buf->b_ml.ml_line_count + 1) {
api_set_error(err, kErrorTypeValidation, "start_row out of bounds");
return;
}
- end_row = normalize_index(buf, end_row, &oob);
+ end_row = normalize_index(buf, end_row, false, &oob);
if (oob || end_row == buf->b_ml.ml_line_count + 1) {
api_set_error(err, kErrorTypeValidation, "end_row out of bounds");
return;
@@ -757,6 +756,108 @@ end:
try_end(err);
}
+/// Gets a range from the buffer.
+///
+/// This differs from |nvim_buf_get_lines()| in that it allows retrieving only
+/// portions of a line.
+///
+/// Indexing is zero-based. Column indices are end-exclusive.
+///
+/// Prefer |nvim_buf_get_lines()| when retrieving entire lines.
+///
+/// @param channel_id
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param start_row First line index
+/// @param start_col Starting byte offset of first line
+/// @param end_row Last line index
+/// @param end_col Ending byte offset of last line (exclusive)
+/// @param opts Optional parameters. Currently unused.
+/// @param[out] err Error details, if any
+/// @return Array of lines, or empty array for unloaded buffer.
+ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer,
+ Integer start_row, Integer start_col,
+ Integer end_row, Integer end_col,
+ Dictionary opts, Error *err)
+ FUNC_API_SINCE(9)
+{
+ Array rv = ARRAY_DICT_INIT;
+
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
+ return rv;
+ }
+
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return rv;
+ }
+
+ // return sentinel value if the buffer isn't loaded
+ if (buf->b_ml.ml_mfp == NULL) {
+ return rv;
+ }
+
+ bool oob = false;
+ start_row = normalize_index(buf, start_row, false, &oob);
+ end_row = normalize_index(buf, end_row, false, &oob);
+
+ if (oob) {
+ api_set_error(err, kErrorTypeValidation, "Index out of bounds");
+ return rv;
+ }
+
+ // nvim_buf_get_lines doesn't care if the start row is greater than the end
+ // row (it will just return an empty array), but nvim_buf_get_text does in
+ // order to maintain symmetry with nvim_buf_set_text.
+ if (start_row > end_row) {
+ api_set_error(err, kErrorTypeValidation, "start is higher than end");
+ return rv;
+ }
+
+ bool replace_nl = (channel_id != VIML_INTERNAL_CALL);
+
+ if (start_row == end_row) {
+ String line = buf_get_text(buf, start_row, start_col, end_col, replace_nl, err);
+ if (ERROR_SET(err)) {
+ return rv;
+ }
+
+ ADD(rv, STRING_OBJ(line));
+ return rv;
+ }
+
+ rv.size = (size_t)(end_row - start_row) + 1;
+ rv.items = xcalloc(rv.size, sizeof(Object));
+
+ rv.items[0] = STRING_OBJ(buf_get_text(buf, start_row, start_col, MAXCOL-1, replace_nl, err));
+ if (ERROR_SET(err)) {
+ goto end;
+ }
+
+ if (rv.size > 2) {
+ Array tmp = ARRAY_DICT_INIT;
+ tmp.items = &rv.items[1];
+ if (!buf_collect_lines(buf, rv.size - 2, start_row + 1, replace_nl, &tmp, err)) {
+ goto end;
+ }
+ }
+
+ rv.items[rv.size-1] = STRING_OBJ(buf_get_text(buf, end_row, 0, end_col, replace_nl, err));
+ if (ERROR_SET(err)) {
+ goto end;
+ }
+
+end:
+ if (ERROR_SET(err)) {
+ api_free_array(rv);
+ rv.size = 0;
+ rv.items = NULL;
+ }
+
+ return rv;
+}
+
/// Returns the byte offset of a line (0-indexed). |api-indexing|
///
/// Line 1 (index=0) has offset 0. UTF-8 bytes are counted. EOL is one byte.
@@ -1386,11 +1487,11 @@ static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
}
// Normalizes 0-based indexes to buffer line numbers
-static int64_t normalize_index(buf_T *buf, int64_t index, bool *oob)
+static int64_t normalize_index(buf_T *buf, int64_t index, bool end_exclusive, bool *oob)
{
int64_t line_count = buf->b_ml.ml_line_count;
// Fix if < 0
- index = index < 0 ? line_count + index +1 : index;
+ index = index < 0 ? line_count + index + (int)end_exclusive : index;
// Check for oob
if (index > line_count) {
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
index f6dce1905e..45a57b9257 100644
--- a/src/nvim/api/keysets.lua
+++ b/src/nvim/api/keysets.lua
@@ -97,6 +97,7 @@ return {
"special"; "sp";
"link";
"fallback";
+ "blend";
"temp";
};
highlight_cterm = {
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 2b107a3f27..971fa1cb0f 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -411,7 +411,6 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object
current_sctx = save_current_sctx;
}
-
buf_T *find_buffer_by_handle(Buffer buffer, Error *err)
{
if (buffer == 0) {
@@ -758,6 +757,52 @@ bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl, Arr
return true;
}
+/// Returns a substring of a buffer line
+///
+/// @param buf Buffer handle
+/// @param lnum Line number (1-based)
+/// @param start_col Starting byte offset into line (0-based)
+/// @param end_col Ending byte offset into line (0-based, exclusive)
+/// @param replace_nl Replace newlines ('\n') with null ('\0')
+/// @param err Error object
+/// @return The text between start_col and end_col on line lnum of buffer buf
+String buf_get_text(buf_T *buf, int64_t lnum, int64_t start_col, int64_t end_col, bool replace_nl,
+ Error *err)
+{
+ String rv = STRING_INIT;
+
+ if (lnum >= MAXLNUM) {
+ api_set_error(err, kErrorTypeValidation, "Line index is too high");
+ return rv;
+ }
+
+ const char *bufstr = (char *)ml_get_buf(buf, (linenr_T)lnum, false);
+ size_t line_length = strlen(bufstr);
+
+ start_col = start_col < 0 ? (int64_t)line_length + start_col + 1 : start_col;
+ end_col = end_col < 0 ? (int64_t)line_length + end_col + 1 : end_col;
+
+ if (start_col >= MAXCOL || end_col >= MAXCOL) {
+ api_set_error(err, kErrorTypeValidation, "Column index is too high");
+ return rv;
+ }
+
+ if (start_col > end_col) {
+ api_set_error(err, kErrorTypeValidation, "start_col must be less than end_col");
+ return rv;
+ }
+
+ if ((size_t)start_col >= line_length) {
+ return rv;
+ }
+
+ rv = cstrn_to_string(&bufstr[start_col], (size_t)(end_col - start_col));
+ if (replace_nl) {
+ strchrsub(rv.data, '\n', '\0');
+ }
+
+ return rv;
+}
void api_free_string(String value)
{
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 11bb1750e4..4dc599564f 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -124,6 +124,10 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err)
/// Set a highlight group.
///
+/// Note: unlike the `:highlight` command which can update a highlight group,
+/// this function completely replaces the definition. For example:
+/// `nvim_set_hl(0, 'Visual', {})` will clear the highlight group 'Visual'.
+///
/// @param ns_id number of namespace for this highlight. Use value 0
/// to set a highlight group in the global (`:highlight`)
/// namespace.
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index aada11bc9e..dd40623af2 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1441,7 +1441,7 @@ void set_curbuf(buf_T *buf, int action)
set_bufref(&prevbufref, prevbuf);
set_bufref(&newbufref, buf);
- // Autocommands may delete the curren buffer and/or the buffer we want to go
+ // Autocommands may delete the current buffer and/or the buffer we want to go
// to. In those cases don't close the buffer.
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
|| (bufref_valid(&prevbufref) && bufref_valid(&newbufref)
@@ -1454,6 +1454,7 @@ void set_curbuf(buf_T *buf, int action)
}
if (bufref_valid(&prevbufref) && !aborting()) {
win_T *previouswin = curwin;
+
// Do not sync when in Insert mode and the buffer is open in
// another window, might be a timer doing something in another
// window.
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 583a040ed1..f4882e57e1 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1439,7 +1439,7 @@ bool vim_isblankline(char_u *lbuf)
/// @param unptr Returns the unsigned result.
/// @param maxlen Max length of string to check.
/// @param strict If true, fail if the number has unexpected trailing
-/// alpha-numeric chars: *len is set to 0 and nothing else is
+/// alphanumeric chars: *len is set to 0 and nothing else is
/// returned.
void vim_str2nr(const char_u *const start, int *const prep, int *const len, const int what,
varnumber_T *const nptr, uvarnumber_T *const unptr, const int maxlen,
@@ -1585,7 +1585,7 @@ vim_str2nr_hex:
#undef PARSE_NUMBER
vim_str2nr_proceed:
- // Check for an alpha-numeric character immediately following, that is
+ // Check for an alphanumeric character immediately following, that is
// most likely a typo.
if (strict && ptr - (const char *)start != maxlen && ASCII_ISALNUM(*ptr)) {
return;
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index c6baa105b0..3763390c22 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -3225,7 +3225,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
set_vim_var_nr(VV_MOUSE_COL, 0);
rettv->vval.v_number = n;
- if (IS_SPECIAL(n) || mod_mask != 0) {
+ if (n != 0 && (IS_SPECIAL(n) || mod_mask != 0)) {
char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1
int i = 0;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index e8b8dc799c..48749afcb3 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7506,7 +7506,7 @@ static void ex_edit(exarg_T *eap)
do_exedit(eap, NULL);
}
-/// ":edit <file>" command and alikes.
+/// ":edit <file>" command and alike.
///
/// @param old_curwin curwin before doing a split or NULL
void do_exedit(exarg_T *eap, win_T *old_curwin)
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 741fc6d803..34cde9a7c4 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -2455,7 +2455,7 @@ static int vgetorpeek(bool advance)
/// 1. a scriptfile
/// 2. the keyboard
///
-/// As much characters as we can get (up to 'maxlen') are put in "buf" and
+/// As many characters as we can get (up to 'maxlen') are put in "buf" and
/// NUL terminated (buffer length must be 'maxlen' + 1).
/// Minimum for "maxlen" is 3!!!!
///
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 8b998ff62e..e43a56086f 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -800,6 +800,7 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
{
HlAttrs hlattrs = HLATTRS_INIT;
int32_t fg = -1, bg = -1, ctermfg = -1, ctermbg = -1, sp = -1;
+ int blend = -1;
int16_t mask = 0;
int16_t cterm_mask = 0;
bool cterm_mask_provided = false;
@@ -847,6 +848,20 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
return hlattrs;
}
+ if (dict->blend.type == kObjectTypeInteger) {
+ Integer blend0 = dict->blend.data.integer;
+ if (blend0 < 0 || blend0 > 100) {
+ api_set_error(err, kErrorTypeValidation, "'blend' is not between 0 to 100");
+ } else {
+ blend = (int)blend0;
+ }
+ } else if (HAS_KEY(dict->blend)) {
+ api_set_error(err, kErrorTypeValidation, "'blend' must be an integer");
+ }
+ if (ERROR_SET(err)) {
+ return hlattrs;
+ }
+
if (HAS_KEY(dict->link)) {
if (link_id) {
*link_id = object_to_hl_id(dict->link, "link", err);
@@ -908,6 +923,7 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
hlattrs.rgb_bg_color = bg;
hlattrs.rgb_fg_color = fg;
hlattrs.rgb_sp_color = sp;
+ hlattrs.hl_blend = blend;
hlattrs.cterm_bg_color = ctermbg == -1 ? 0 : ctermbg + 1;
hlattrs.cterm_fg_color = ctermfg == -1 ? 0 : ctermfg + 1;
hlattrs.cterm_ae_attr = cterm_mask;
@@ -927,10 +943,11 @@ int object_to_color(Object val, char *key, bool rgb, Error *err)
} else if (val.type == kObjectTypeString) {
String str = val.data.string;
// TODO(bfredl): be more fancy with "bg", "fg" etc
+ if (!str.size || STRICMP(str.data, "NONE") == 0) {
+ return -1;
+ }
int color;
- if (!str.size) {
- color = 0;
- } else if (rgb) {
+ if (rgb) {
color = name_to_color(str.data);
} else {
color = name_to_ctermcolor(str.data);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index c8e50d4494..d97a22c342 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -4277,7 +4277,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf,
}
// Save the global value before changing anything. This is needed as for
- // a global-only option setting the "local value" infact sets the global
+ // a global-only option setting the "local value" in fact sets the global
// value (since there is only one value).
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
old_global_value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 0146c06109..c39546b9ea 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -502,7 +502,7 @@ func Test_autocmd_bufwipe_in_SessLoadPost()
[CODE]
call writefile(content, 'Xvimrc')
- call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq')
+ call system(GetVimCommand('Xvimrc') .. ' --headless --noplugins -S Session.vim -c cq')
let errors = join(readfile('Xerrors'))
call assert_match('E814', errors)
@@ -562,7 +562,7 @@ func Test_autocmd_bufwipe_in_SessLoadPost2()
[CODE]
call writefile(content, 'Xvimrc')
- call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq')
+ call system(GetVimCommand('Xvimrc') .. ' --headless --noplugins -S Session.vim -c cq')
let errors = join(readfile('Xerrors'))
" This probably only ever matches on unix.
call assert_notmatch('Caught deadly signal SEGV', errors)
@@ -1506,7 +1506,7 @@ func Test_bufunload_all()
call writefile(content, 'Xtest')
call delete('Xout')
- call system(v:progpath. ' -u NORC -i NONE -N -S Xtest')
+ call system(GetVimCommandClean() .. ' -N --headless -S Xtest')
call assert_true(filereadable('Xout'))
call delete('Xxx1')
diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim
index b619f2adb6..438edb0257 100644
--- a/src/nvim/testdir/test_breakindent.vim
+++ b/src/nvim/testdir/test_breakindent.vim
@@ -1,7 +1,7 @@
" Test for breakindent
"
" Note: if you get strange failures when adding new tests, it might be that
-" while the test is run, the breakindent cacheing gets in its way.
+" while the test is run, the breakindent caching gets in its way.
" It helps to change the tabstop setting and force a redraw (e.g. see
" Test_breakindent08())
if !exists('+breakindent')
diff --git a/src/nvim/testdir/test_cindent.vim b/src/nvim/testdir/test_cindent.vim
index 5dc54111e7..4b702bf2b8 100644
--- a/src/nvim/testdir/test_cindent.vim
+++ b/src/nvim/testdir/test_cindent.vim
@@ -815,7 +815,7 @@ func Test_cindent_1()
}
}
- public: // <-- this was incoreectly indented before!!
+ public: // <-- this was incorrectly indented before!!
void testfall();
protected:
void testfall();
@@ -1792,7 +1792,7 @@ func Test_cindent_1()
}
}
- public: // <-- this was incoreectly indented before!!
+ public: // <-- this was incorrectly indented before!!
void testfall();
protected:
void testfall();
@@ -5302,9 +5302,12 @@ endfunc
" this was going beyond the end of the line.
func Test_cindent_case()
new
- call setline(1, "case x: // x")
+ call setline(1, 'case x: // x')
set cindent
norm! f:a:
+ call assert_equal('case x:: // x', getline(1))
+
+ set cindent&
bwipe!
endfunc
diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim
index d23748a3e3..5965ee48ef 100644
--- a/src/nvim/testdir/test_digraph.vim
+++ b/src/nvim/testdir/test_digraph.vim
@@ -81,7 +81,7 @@ func Test_digraphs()
call Put_Dig(".e")
call Put_Dig("a.") " not defined
call assert_equal(['ḃ', 'ė', '.'], getline(line('.')-2,line('.')))
- " Diaresis
+ " Diaeresis
call Put_Dig("a:")
call Put_Dig(":u")
call Put_Dig("b:") " not defined
@@ -288,7 +288,7 @@ func Test_digraphs_option()
call Put_Dig_BS(".","e")
call Put_Dig_BS("a",".") " not defined
call assert_equal(['ḃ', 'ė', '.'], getline(line('.')-2,line('.')))
- " Diaresis
+ " Diaeresis
call Put_Dig_BS("a",":")
call Put_Dig_BS(":","u")
call Put_Dig_BS("b",":") " not defined
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index a1f6a84a99..360b3aaaa0 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -590,7 +590,7 @@ func Test_edit_CTRL_K()
call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
call assert_equal(['AA'], getline(1, '$'))
- " press an unexecpted key after dictionary completion
+ " press an unexpected key after dictionary completion
%d
call setline(1, 'A')
call cursor(1, 1)
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 6e36f4e3d2..994d74601a 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -1451,6 +1451,10 @@ func Test_getchar()
call assert_equal('', getcharstr(0))
call assert_equal('', getcharstr(1))
+ call feedkeys("\<M-F2>", '')
+ call assert_equal("\<M-F2>", getchar(0))
+ call assert_equal(0, getchar(0))
+
call setline(1, 'xxxx')
" call test_setmouse(1, 3)
" let v:mouse_win = 9
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index e8eebb3fdd..f45cd96733 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -1118,7 +1118,7 @@ func Test_normal20_exmode()
endif
call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
call writefile(['1', '2'], 'Xfile')
- call system(v:progpath .' -e -s < Xscript Xfile')
+ call system(GetVimCommand() .. ' -e -s < Xscript Xfile')
let a=readfile('Xfile2')
call assert_equal(['1', 'foo', 'bar', '2'], a)
@@ -1171,13 +1171,13 @@ func Test_normal22_zet()
endfor
call writefile(['1', '2'], 'Xfile_Test_normal22_zet')
- let args = ' --headless -u NONE -N -U NONE -i NONE --noplugins'
- call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile_Test_normal22_zet')
+ let args = ' -N -i NONE --noplugins -X --headless'
+ call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xfile_Test_normal22_zet')
let a = readfile('Xfile_Test_normal22_zet')
call assert_equal([], a)
" Test for ZQ
call writefile(['1', '2'], 'Xfile_Test_normal22_zet')
- call system(v:progpath . args . ' -c "%d" -c ":norm! ZQ" Xfile_Test_normal22_zet')
+ call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xfile_Test_normal22_zet')
let a = readfile('Xfile_Test_normal22_zet')
call assert_equal(['1', '2'], a)
diff --git a/src/nvim/testdir/test_profile.vim b/src/nvim/testdir/test_profile.vim
index 4b0097617e..fdb6f13e2b 100644
--- a/src/nvim/testdir/test_profile.vim
+++ b/src/nvim/testdir/test_profile.vim
@@ -1,8 +1,9 @@
" Test Vim profiler
-if !has('profile')
- finish
-endif
+source check.vim
+CheckFeature profile
+
+source shared.vim
source screendump.vim
func Test_profile_func()
@@ -37,7 +38,7 @@ func Test_profile_func()
[CODE]
call writefile(lines, 'Xprofile_func.vim')
- call system(v:progpath
+ call system(GetVimCommand()
\ . ' -es --clean'
\ . ' -c "so Xprofile_func.vim"'
\ . ' -c "qall!"')
@@ -124,8 +125,8 @@ func Test_profile_func_with_ifelse()
[CODE]
call writefile(lines, 'Xprofile_func.vim')
- call system(v:progpath
- \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ call system(GetVimCommand()
+ \ . ' -es -i NONE --noplugin'
\ . ' -c "profile start Xprofile_func.log"'
\ . ' -c "profile func Foo*"'
\ . ' -c "so Xprofile_func.vim"'
@@ -237,8 +238,8 @@ func Test_profile_func_with_trycatch()
[CODE]
call writefile(lines, 'Xprofile_func.vim')
- call system(v:progpath
- \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ call system(GetVimCommand()
+ \ . ' -es -i NONE --noplugin'
\ . ' -c "profile start Xprofile_func.log"'
\ . ' -c "profile func Foo*"'
\ . ' -c "so Xprofile_func.vim"'
@@ -324,8 +325,8 @@ func Test_profile_file()
[CODE]
call writefile(lines, 'Xprofile_file.vim')
- call system(v:progpath
- \ . ' -es --clean'
+ call system(GetVimCommandClean()
+ \ . ' -es'
\ . ' -c "profile start Xprofile_file.log"'
\ . ' -c "profile file Xprofile_file.vim"'
\ . ' -c "so Xprofile_file.vim"'
@@ -369,8 +370,8 @@ func Test_profile_file_with_cont()
\ ]
call writefile(lines, 'Xprofile_file.vim')
- call system(v:progpath
- \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ call system(GetVimCommandClean()
+ \ . ' -es'
\ . ' -c "profile start Xprofile_file.log"'
\ . ' -c "profile file Xprofile_file.vim"'
\ . ' -c "so Xprofile_file.vim"'
@@ -427,7 +428,7 @@ func Test_profile_truncate_mbyte()
\ ]
call writefile(lines, 'Xprofile_file.vim')
- call system(v:progpath
+ call system(GetVimCommandClean()
\ . ' -es --cmd "set enc=utf-8"'
\ . ' -c "profile start Xprofile_file.log"'
\ . ' -c "profile file Xprofile_file.vim"'
@@ -474,7 +475,7 @@ func Test_profdel_func()
call Foo3()
[CODE]
call writefile(lines, 'Xprofile_file.vim')
- call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q')
+ call system(GetVimCommandClean() . ' -es -c "so Xprofile_file.vim" -c q')
call assert_equal(0, v:shell_error)
let lines = readfile('Xprofile_file.log')
@@ -509,7 +510,7 @@ func Test_profdel_star()
call Foo()
[CODE]
call writefile(lines, 'Xprofile_file.vim')
- call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q')
+ call system(GetVimCommandClean() . ' -es -c "so Xprofile_file.vim" -c q')
call assert_equal(0, v:shell_error)
let lines = readfile('Xprofile_file.log')
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index c4d70fb1de..6852f53ea8 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -2739,7 +2739,7 @@ func Test_cwindow_jump()
call assert_true(winnr('$') == 2)
call assert_true(winnr() == 1)
- " Jumping to a file from the location list window should find a usuable
+ " Jumping to a file from the location list window should find a usable
" window by wrapping around the window list.
enew | only
call setloclist(0, [], 'f')
diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim
index 2e92d9aa2f..23e39eba35 100644
--- a/src/nvim/testdir/test_registers.vim
+++ b/src/nvim/testdir/test_registers.vim
@@ -219,7 +219,7 @@ func Test_set_register()
call setreg('=', 'b', 'a')
call assert_equal('regwrite', getreg('='))
- " Test for settting a list of lines to special registers
+ " Test for setting a list of lines to special registers
call setreg('/', [])
call assert_equal('', @/)
call setreg('=', [])
diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim
index b44f3e9b94..d3059664e9 100644
--- a/src/nvim/testdir/test_stat.vim
+++ b/src/nvim/testdir/test_stat.vim
@@ -7,7 +7,7 @@ func CheckFileTime(doSleep)
let times = []
let result = 0
- " Use three files istead of localtim(), with a network filesystem the file
+ " Use three files instead of localtim(), with a network filesystem the file
" times may differ at bit
let fl = ['Hello World!']
for fname in fnames
diff --git a/src/nvim/testdir/test_suspend.vim b/src/nvim/testdir/test_suspend.vim
index 4b3bd5eadf..bf88bd4453 100644
--- a/src/nvim/testdir/test_suspend.vim
+++ b/src/nvim/testdir/test_suspend.vim
@@ -26,8 +26,8 @@ func Test_suspend()
" Wait for shell prompt.
call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
- call term_sendkeys(buf, v:progpath
- \ . " --clean -X"
+ call term_sendkeys(buf, GetVimCommandClean()
+ \ . " -X"
\ . " -c 'set nu'"
\ . " -c 'call setline(1, \"foo\")'"
\ . " Xfoo\<CR>")
diff --git a/src/nvim/testdir/test_system.vim b/src/nvim/testdir/test_system.vim
index 5b8079d7b6..18692f42c9 100644
--- a/src/nvim/testdir/test_system.vim
+++ b/src/nvim/testdir/test_system.vim
@@ -50,11 +50,11 @@ endfunc
func Test_system_exmode()
if has('unix') " echo $? only works on Unix
- let cmd = ' -es --headless -u NONE -c "source Xscript" +q; echo "result=$?"'
+ let cmd = ' -es -c "source Xscript" +q; echo "result=$?"'
" Need to put this in a script, "catch" isn't found after an unknown
" function.
call writefile(['try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript')
- let a = system(v:progpath . cmd)
+ let a = system(GetVimCommand() . cmd)
call assert_match('result=0', a)
call assert_equal(0, v:shell_error)
endif
@@ -62,33 +62,33 @@ func Test_system_exmode()
" Error before try does set error flag.
call writefile(['call nosuchfunction()', 'try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript')
if has('unix') " echo $? only works on Unix
- let a = system(v:progpath . cmd)
+ let a = system(GetVimCommand() . cmd)
call assert_notequal('0', a[0])
endif
- let cmd = ' -es --headless -u NONE -c "source Xscript" +q'
- let a = system(v:progpath . cmd)
+ let cmd = ' -es -c "source Xscript" +q'
+ let a = system(GetVimCommand() . cmd)
call assert_notequal(0, v:shell_error)
call delete('Xscript')
if has('unix') " echo $? only works on Unix
- let cmd = ' -es --headless -u NONE -c "call doesnotexist()" +q; echo $?'
- let a = system(v:progpath. cmd)
+ let cmd = ' -es -c "call doesnotexist()" +q; echo $?'
+ let a = system(GetVimCommand() . cmd)
call assert_notequal(0, a[0])
endif
- let cmd = ' -es --headless -u NONE -c "call doesnotexist()" +q'
- let a = system(v:progpath. cmd)
+ let cmd = ' -es -c "call doesnotexist()" +q'
+ let a = system(GetVimCommand(). cmd)
call assert_notequal(0, v:shell_error)
if has('unix') " echo $? only works on Unix
- let cmd = ' -es --headless -u NONE -c "call doesnotexist()|let a=1" +q; echo $?'
- let a = system(v:progpath. cmd)
+ let cmd = ' -es -c "call doesnotexist()|let a=1" +q; echo $?'
+ let a = system(GetVimCommand() . cmd)
call assert_notequal(0, a[0])
endif
- let cmd = ' -es --headless -u NONE -c "call doesnotexist()|let a=1" +q'
- let a = system(v:progpath. cmd)
+ let cmd = ' -es -c "call doesnotexist()|let a=1" +q'
+ let a = system(GetVimCommand() . cmd)
call assert_notequal(0, v:shell_error)
endfunc
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
index 75a965f16d..f93eb6e274 100644
--- a/src/nvim/testdir/test_vimscript.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -1,6 +1,9 @@
" Test various aspects of the Vim script language.
" Most of this was formerly in test49.
+source check.vim
+source shared.vim
+
"-------------------------------------------------------------------------------
" Test environment {{{1
"-------------------------------------------------------------------------------
@@ -1744,7 +1747,7 @@ func Test_function_defined_line()
[CODE]
call writefile(lines, 'Xtest.vim')
- let res = system(v:progpath .. ' --clean -es -X -S Xtest.vim')
+ let res = system(GetVimCommandClean() .. ' -es -X -S Xtest.vim')
call assert_equal(0, v:shell_error)
let m = matchstr(res, 'function F1()[^[:print:]]*[[:print:]]*')
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua
index 688f3abba5..dd3af8c28f 100644
--- a/test/functional/api/buffer_spec.lua
+++ b/test/functional/api/buffer_spec.lua
@@ -423,6 +423,13 @@ describe('api/buf', function()
-- will join multiple lines if needed
set_text(0, 6, 3, 4, {'bar'})
eq({'hello bar'}, get_lines(0, 1, true))
+
+ -- can use negative line numbers
+ set_text(-2, 0, -2, 5, {'goodbye'})
+ eq({'goodbye bar', ''}, get_lines(0, -1, true))
+
+ set_text(-1, 0, -1, 0, {'text'})
+ eq({'goodbye bar', 'text'}, get_lines(0, 2, true))
end)
it('works with undo', function()
@@ -537,6 +544,34 @@ describe('api/buf', function()
end)
end)
+ describe('nvim_buf_get_text', function()
+ local get_text = curbufmeths.get_text
+
+ it('works', function()
+ insert([[
+ hello foo!
+ text]])
+
+ eq({'hello'}, get_text(0, 0, 0, 5, {}))
+ eq({'hello foo!'}, get_text(0, 0, 0, 42, {}))
+ eq({'foo!'}, get_text(0, 6, 0, 10, {}))
+ eq({'foo!', 'tex'}, get_text(0, 6, 1, 3, {}))
+ eq({'foo!', 'tex'}, get_text(-2, 6, -1, 3, {}))
+ eq({''}, get_text(0, 18, 0, 20, {}))
+ eq({'ext'}, get_text(-1, 1, -1, 4, {}))
+ end)
+
+ it('errors on out-of-range', function()
+ eq(false, pcall(get_text, 2, 0, 3, 0, {}))
+ eq(false, pcall(get_text, 0, 0, 4, 0, {}))
+ end)
+
+ it('errors when start is greater than end', function()
+ eq(false, pcall(get_text, 1, 0, 0, 0, {}))
+ eq(false, pcall(get_text, 0, 1, 0, 0, {}))
+ end)
+ end)
+
describe('nvim_buf_get_offset', function()
local get_offset = curbufmeths.get_offset
it('works', function()
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index 03b407f4e0..443689754c 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -304,10 +304,6 @@ describe("API: set highlight", function()
eq('Test_hl3 xxx ctermbg=9',
exec_capture('highlight Test_hl3'))
- meths.set_hl(0, 'Test_hl3', {})
- eq('Test_hl3 xxx cleared',
- exec_capture('highlight Test_hl3'))
-
eq("'redd' is not a valid color",
pcall_err(meths.set_hl, 0, 'Test_hl3', {fg='redd'}))
@@ -320,5 +316,16 @@ describe("API: set highlight", function()
eq("'#FF00FF' is not a valid color",
pcall_err(meths.set_hl, 0, 'Test_hl3', {ctermfg='#FF00FF'}))
+
+ for _, fg_val in ipairs{ nil, 'NONE', 'nOnE', '', -1 } do
+ meths.set_hl(0, 'Test_hl3', {fg = fg_val})
+ eq('Test_hl3 xxx cleared',
+ exec_capture('highlight Test_hl3'))
+ end
+
+ meths.set_hl(0, 'Test_hl3', {fg='#FF00FF', blend=50})
+ eq('Test_hl3 xxx guifg=#FF00FF blend=50',
+ exec_capture('highlight Test_hl3'))
+
end)
end)