aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--.github/workflows/nightly.yml128
-rw-r--r--.github/workflows/release.yml175
-rw-r--r--contrib/flake.nix95
-rw-r--r--runtime/autoload/man.vim6
-rw-r--r--runtime/doc/eval.txt2
-rw-r--r--runtime/doc/lsp.txt69
-rw-r--r--runtime/doc/treesitter.txt2
-rw-r--r--runtime/filetype.vim3
-rw-r--r--runtime/lua/vim/lsp.lua21
-rw-r--r--runtime/lua/vim/lsp/buf.lua10
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua14
-rw-r--r--runtime/lua/vim/lsp/util.lua5
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua2
-rw-r--r--runtime/plugin/man.vim4
-rwxr-xr-xscripts/update_version_stamp.lua9
-rw-r--r--src/nvim/CMakeLists.txt2
-rw-r--r--src/nvim/api/buffer.c230
-rw-r--r--src/nvim/api/deprecated.c367
-rw-r--r--src/nvim/api/deprecated.h11
-rw-r--r--src/nvim/api/private/dispatch.c1
-rw-r--r--src/nvim/api/tabpage.c42
-rw-r--r--src/nvim/api/vim.c37
-rw-r--r--src/nvim/api/window.c42
-rw-r--r--src/nvim/ex_getln.c3
-rw-r--r--src/nvim/log.c9
-rw-r--r--src/nvim/main.c5
-rw-r--r--src/nvim/message.c2
-rw-r--r--src/nvim/popupmnu.c1
-rw-r--r--src/nvim/regexp.c16
-rw-r--r--src/nvim/regexp_nfa.c16
-rw-r--r--src/nvim/testdir/test_filetype.vim1
-rw-r--r--src/nvim/testdir/test_regexp_latin.vim7
-rw-r--r--src/nvim/testdir/test_ruby.vim24
-rw-r--r--src/nvim/testdir/test_search.vim23
-rw-r--r--src/nvim/undo.c5
-rw-r--r--src/nvim/window.c31
-rw-r--r--test/functional/lua/treesitter_spec.lua21
-rw-r--r--test/functional/ui/multigrid_spec.lua71
39 files changed, 964 insertions, 554 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 70cdc3b4a2..dcc3c2c45f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,5 +1,9 @@
name: CI
-on: [push, pull_request]
+on:
+ push:
+ branches: '**'
+ pull_request:
+ branches: 'master'
jobs:
build:
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
deleted file mode 100644
index d4187d9dad..0000000000
--- a/.github/workflows/nightly.yml
+++ /dev/null
@@ -1,128 +0,0 @@
-name: Nightly release
-on:
- schedule:
- - cron: '5 5 * * *'
-
-jobs:
- linux:
- runs-on: ubuntu-20.04
- outputs:
- version: ${{ steps.build.outputs.version }}
- release: ${{ steps.build.outputs.release }}
- steps:
- - uses: actions/checkout@v2
- - name: Install dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y autoconf automake build-essential ccache cmake cpanminus cscope gcc-multilib gdb gettext gperf language-pack-tr libtool-bin locales ninja-build pkg-config python3 python3-pip python3-setuptools unzip valgrind xclip
- - name: Build nightly
- id: build
- run: |
- make CMAKE_BUILD_TYPE=RelWithDebinfo CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH="
- 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 | sed 's/-.*//')"
- make DESTDIR="$GITHUB_WORKSPACE/build/nightly/nvim-linux64" install
- cd "$GITHUB_WORKSPACE/build/nightly"
- tar cfz nvim-linux64.tar.gz nvim-linux64
- - uses: actions/upload-artifact@v2
- with:
- name: nvim-linux64.tar.gz
- path: build/nightly/nvim-linux64.tar.gz
- retention-days: 1
-
- macOS:
- runs-on: macos-10.15
- steps:
- - uses: actions/checkout@v2
- - name: Install brew packages
- run: |
- brew update >/dev/null
- brew install automake ninja
- - name: Build nightly
- run: |
- make CMAKE_BUILD_TYPE=Release CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11"
- make DESTDIR="$GITHUB_WORKSPACE/build/nightly/nvim-osx64" install
- - name: Create package
- run: |
- cd "$GITHUB_WORKSPACE/build/nightly"
- mkdir -p bundle/nvim/libs
- mkdir -p bundle/nvim/bin
- cp nvim-osx64/bin/nvim bundle/nvim/bin/
- libs=($(otool -L nvim-osx64/bin/nvim | sed 1d | sed -E -e 's|^[[:space:]]*||' -e 's| .*||'))
- echo "libs:"
- for lib in "${libs[@]}"; do
- if echo "$lib" | grep -q -E 'libSystem|CoreFoundation' 2>/dev/null; then
- echo " [skipped] $lib"
- else
- echo " $lib"
- relname="libs/${lib##*/}"
- cp -L "$lib" "bundle/nvim/$relname"
- install_name_tool -change "$lib" "@executable_path/../$relname" bundle/nvim/bin/nvim
- fi
- done
- tar cjSf nvim-macos.tar.bz2 -C bundle nvim
- - uses: actions/upload-artifact@v2
- with:
- name: nvim-macos.tar.bz2
- path: build/nightly/nvim-macos.tar.bz2
- retention-days: 1
-
- publish:
- needs: [linux, macOS]
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/download-artifact@v2
- - uses: actions/create-release@v1
- id: create_release
- with:
- tag_name: nightly
- release_name: NVIM ${{ needs.linux.outputs.release }}
- body: |
- Nvim development (prerelease) build.
- ```
- ${{ needs.linux.outputs.version }}
- ```
-
- ## Install
-
- ### Windows
-
- 1. Extract **nvim-win64.zip** (or **nvim-win32.zip**)
- 2. Run `nvim-qt.exe`
-
- ### macOS
-
- 1. Download **nvim-macos.tar.gz**
- 2. Extract: `tar xzvf nvim-macos.tar.gz`
- 3. Run `./nvim-osx64/bin/nvim`
-
- ### Linux (x64)
-
- 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):
- ```
- ./nvim.appimage --appimage-extract
- ./squashfs-root/usr/bin/nvim
- ```
-
- ### Other
-
- - Install by [package manager](https://github.com/neovim/neovim/wiki/Installing-Neovim)
- prerelease: true
- - uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./nvim-macos.tar.bz2
- asset_name: nvim-macos.tar.bz2
- asset_content_type: application/x-bzip2
- - uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./nvim-linux64.tar.gz
- asset_name: nvim-linux64.tar.gz
- asset_content_type: application/gzip
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..d7f9556028
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,175 @@
+name: Release
+on:
+ schedule:
+ - cron: '5 5 * * *'
+ workflow_dispatch:
+ inputs:
+ tag_name:
+ description: 'Tag name for release'
+ required: false
+ default: nightly
+ push:
+ tags:
+ - v[0-9]+.[0-9]+.[0-9]+
+
+# Build on the oldest supported images, so we have broader compatibility
+jobs:
+ linux:
+ runs-on: ubuntu-16.04
+ outputs:
+ version: ${{ steps.build.outputs.version }}
+ release: ${{ steps.build.outputs.release }}
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y autoconf automake build-essential cmake gcc-multilib gettext gperf libtool-bin locales ninja-build pkg-config unzip
+ - name: Build release
+ id: build
+ run: |
+ make CMAKE_BUILD_TYPE=RelWithDebinfo CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH="
+ 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
+ - uses: actions/upload-artifact@v2
+ with:
+ name: nvim-linux64
+ path: build/release/nvim-linux64.tar.gz
+ retention-days: 1
+
+ appimage:
+ runs-on: ubuntu-16.04
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y autoconf automake build-essential cmake gcc-multilib gettext gperf libtool-bin locales ninja-build pkg-config unzip
+ - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name != 'nightly')
+ run: make appimage-latest
+ - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly')
+ run: make appimage-nightly
+ - uses: actions/upload-artifact@v2
+ with:
+ name: appimage
+ path: build/bin/nvim.appimage
+ retention-days: 1
+ - uses: actions/upload-artifact@v2
+ with:
+ name: appimage
+ path: build/bin/nvim.appimage.zsync
+ retention-days: 1
+
+ macOS:
+ runs-on: macos-10.15
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Install brew packages
+ run: |
+ brew update >/dev/null
+ brew install automake ninja
+ - name: Build release
+ run: |
+ make CMAKE_BUILD_TYPE=Release CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11"
+ make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-osx64" install
+ - name: Create package
+ run: |
+ cd "$GITHUB_WORKSPACE/build/release"
+ mkdir -p nvim-osx64/libs
+ libs=($(otool -L nvim-osx64/bin/nvim | sed 1d | sed -E -e 's|^[[:space:]]*||' -e 's| .*||'))
+ echo "libs:"
+ for lib in "${libs[@]}"; do
+ if echo "$lib" | grep -q -E 'libSystem|CoreFoundation' 2>/dev/null; then
+ echo " [skipped] $lib"
+ else
+ echo " $lib"
+ relname="libs/${lib##*/}"
+ cp -L "$lib" "nvim-osx64/$relname"
+ install_name_tool -change "$lib" "@executable_path/../$relname" nvim-osx64/bin/nvim
+ fi
+ done
+ tar cfz nvim-macos.tar.gz nvim-osx64
+ - uses: actions/upload-artifact@v2
+ with:
+ name: nvim-macos
+ path: build/release/nvim-macos.tar.gz
+ retention-days: 1
+
+ publish:
+ needs: [linux, appimage, macOS]
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/download-artifact@v2
+ - if: github.event_name == 'workflow_dispatch'
+ run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV
+ - if: github.event_name == 'schedule'
+ run: echo 'TAG_NAME=nightly' >> $GITHUB_ENV
+ - if: github.event_name == 'push'
+ run: |
+ TAG_NAME=${{ github.ref }}
+ echo "TAG_NAME=${TAG_NAME#refs/tags/}" >> $GITHUB_ENV
+ - if: env.TAG_NAME == 'nightly'
+ run: echo 'SUBJECT=Nvim development (prerelease) build' >> $GITHUB_ENV
+ - if: env.TAG_NAME != 'nightly'
+ run: echo 'SUBJECT=Nvim release build' >> $GITHUB_ENV
+ - if: env.TAG_NAME == 'nightly'
+ uses: dev-drprasad/delete-tag-and-release@v0.1.2
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ delete_release: false
+ tag_name: nightly
+ - uses: meeDamian/github-release@2.0
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ tag: ${{ env.TAG_NAME }}
+ name: ${{ needs.linux.outputs.release }}
+ prerelease: ${{ env.TAG_NAME == 'nightly' }}
+ commitish: ${{ github.sha }}
+ gzip: false
+ allow_override: ${{ env.TAG_NAME == 'nightly' }}
+ files: |
+ nvim-macos.tar.gz:./nvim-macos/nvim-macos.tar.gz
+ nvim-linux64.tar.gz:./nvim-linux64/nvim-linux64.tar.gz
+ nvim.appimage:./appimage/nvim.appimage
+ nvim.appimage.zsync:./appimage/nvim.appimage.zsync
+ body: |
+ ${{ env.SUBJECT }}
+ ```
+ ${{ needs.linux.outputs.version }}```
+
+ ## Install
+
+ ### Windows
+
+ 1. Extract **nvim-win64.zip** (or **nvim-win32.zip**)
+ 2. Run `nvim-qt.exe`
+
+ ### macOS
+
+ 1. Download **nvim-macos.tar.gz**
+ 2. Extract: `tar xzvf nvim-macos.tar.gz`
+ 3. Run `./nvim-osx64/bin/nvim`
+
+ ### Linux (x64)
+
+ 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):
+ ```
+ ./nvim.appimage --appimage-extract
+ ./squashfs-root/usr/bin/nvim
+ ```
+
+ ### Other
+
+ - Install by [package manager](https://github.com/neovim/neovim/wiki/Installing-Neovim)
diff --git a/contrib/flake.nix b/contrib/flake.nix
new file mode 100644
index 0000000000..a75e584075
--- /dev/null
+++ b/contrib/flake.nix
@@ -0,0 +1,95 @@
+{
+ description = "Neovim flake";
+
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+ };
+
+ outputs = { self, nixpkgs }: let
+ system = "x86_64-linux";
+ legacyPkgs = nixpkgs.legacyPackages."${system}".pkgs;
+ pkgs = legacyPkgs;
+ in {
+
+ packages."${system}" = rec {
+
+ neovim = legacyPkgs.neovim-unwrapped.overrideAttrs(oa: {
+ version = "master";
+ src = ../.;
+
+ buildInputs = oa.buildInputs ++ ([
+ pkgs.tree-sitter
+ ]);
+
+ cmakeFlags = oa.cmakeFlags ++ [
+ "-DUSE_BUNDLED=OFF"
+ ];
+ });
+
+ # a development binary to help debug issues
+ neovim-debug = (neovim.override {
+ stdenv = pkgs.llvmPackages_latest.stdenv;
+ lua = pkgs.enableDebugging legacyPkgs.luajit;
+ }).overrideAttrs(oa:{
+ cmakeBuildType="Debug";
+ cmakeFlags = oa.cmakeFlags ++ [
+ "-DMIN_LOG_LEVEL=0"
+ ];
+ });
+
+ # for neovim developers, very slow
+ # brings development tools as well
+ neovim-developer = let
+ lib = nixpkgs.lib;
+ pythonEnv = legacyPkgs.python3;
+ luacheck = legacyPkgs.luaPackages.luacheck;
+ in
+ neovim-debug.overrideAttrs(oa: {
+ cmakeFlags = oa.cmakeFlags ++ [
+ "-DLUACHECK_PRG=${luacheck}/bin/luacheck"
+ "-DMIN_LOG_LEVEL=0"
+ "-DENABLE_LTO=OFF"
+ "-DUSE_BUNDLED=OFF"
+ # https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
+ # https://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports
+ "-DCLANG_ASAN_UBSAN=ON"
+ ];
+
+ nativeBuildInputs = oa.nativeBuildInputs ++ (with pkgs; [
+ pythonEnv
+ include-what-you-use # for scripts/check-includes.py
+ jq # jq for scripts/vim-patch.sh -r
+ doxygen
+ ]);
+
+ shellHook = oa.shellHook + ''
+ export NVIM_PYTHON_LOG_LEVEL=DEBUG
+ export NVIM_LOG_FILE=/tmp/nvim.log
+
+ export ASAN_OPTIONS="log_path=./test.log:abort_on_error=1"
+ export UBSAN_OPTIONS=print_stacktrace=1
+ '';
+ });
+ };
+
+ defaultPackage."${system}" = self.packages."${system}".neovim;
+
+ overlay = final: prev: {
+ inherit (self.packages."${system}") neovim neovim-debug;
+ };
+
+ apps."${system}" = let
+ mkApp = pkg: {
+ type = "app";
+ program = pkg + "/bin/nvim";
+ };
+ in {
+ nvim = mkApp self.packages."${system}".neovim;
+ nvim-debug = mkApp self.packages."${system}".neovim-debug;
+ };
+
+ defaultApp."${system}" = self.apps."${system}".nvim;
+
+ devShell."${system}" = self.packages."${system}".neovim-developer;
+ };
+}
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim
index 486ed99e3f..99d8c41dba 100644
--- a/runtime/autoload/man.vim
+++ b/runtime/autoload/man.vim
@@ -18,7 +18,7 @@ function! man#init() abort
endtry
endfunction
-function! man#open_page(count, count1, mods, ...) abort
+function! man#open_page(count, mods, ...) abort
if a:0 > 2
call s:error('too many arguments')
return
@@ -39,9 +39,7 @@ function! man#open_page(count, count1, mods, ...) abort
endif
try
let [sect, name] = s:extract_sect_and_name_ref(ref)
- if a:count ==# a:count1
- " v:count defaults to 0 which is a valid section, and v:count1 defaults to
- " 1, also a valid section. If they are equal, count explicitly set.
+ if a:count >= 0
let sect = string(a:count)
endif
let path = s:verify_exists(sect, name)
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 343e35bf66..f306806c96 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -8441,8 +8441,6 @@ strftime({format} [, {time}]) *strftime()*
:echo strftime("%H:%M") 11:55
:echo strftime("%c", getftime("file.c"))
Show mod time of file.c.
-< Not available on all systems. To check use: >
- :if exists("*strftime")
strgetchar({str}, {index}) *strgetchar()*
Get character {index} from {str}. This uses a character
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index c8a44dfb75..ea9072841c 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -247,7 +247,7 @@ For |lsp-notification|, each |lsp-handler| has this signature: >
of a particular handler.
For an example, see:
- |vim.lsp.diagnostics.on_publish_diagnostics()|
+ |vim.lsp.diagnostic.on_publish_diagnostics()|
To configure a particular |lsp-handler|, see:
|lsp-handler-configuration|
@@ -715,6 +715,15 @@ start_client({config}) *vim.lsp.start_client()*
The following parameters describe fields in the {config}
table.
+>
+
+ -- In attach function for the client, you can do:
+ local custom_attach = function(client)
+ if client.config.flags then
+ client.config.flags.allow_incremental_sync = true
+ end
+ end
+<
Parameters: ~
{root_dir} (required, string) Directory where the
@@ -796,6 +805,11 @@ start_client({config}) *vim.lsp.start_client()*
in the initialize request.
Invalid/empty values will default to
"off"
+ {flags} A table with flags for the client. The
+ current (experimental) flags are:
+ • allow_incremental_sync (bool, default
+ false): Allow using on_line callbacks
+ for lsp
Return: ~
Client id. |vim.lsp.get_client_by_id()| Note: client may
@@ -833,6 +847,12 @@ with({handler}, {override_config}) *vim.lsp.with()*
==============================================================================
Lua module: vim.lsp.buf *lsp-buf*
+ *vim.lsp.buf.add_workspace_folder()*
+add_workspace_folder({workspace_folder})
+ Add the folder at path to the workspace folders. If {path} is
+ not provided, the user will be prompted for a path using
+ |input()|.
+
clear_references() *vim.lsp.buf.clear_references()*
Removes document highlights from current buffer.
@@ -935,6 +955,9 @@ incoming_calls() *vim.lsp.buf.incoming_calls()*
|quickfix| window. If the symbol can resolve to multiple
items, the user can pick one in the |inputlist|.
+list_workspace_folders() *vim.lsp.buf.list_workspace_folders()*
+ List workspace folders.
+
outgoing_calls() *vim.lsp.buf.outgoing_calls()*
Lists all the items that are called by the symbol under the
cursor in the |quickfix| window. If the symbol can resolve to
@@ -961,6 +984,9 @@ range_formatting({options}, {start_pos}, {end_pos})
Parameters: ~
{options} Table with valid `FormattingOptions` entries.
{start_pos} ({number, number}, optional) mark-indexed
+ position. Defaults to the start of the last
+ visual selection.
+ {end_pos} ({number, number}, optional) mark-indexed
position. Defaults to the end of the last
visual selection.
@@ -974,6 +1000,12 @@ references({context}) *vim.lsp.buf.references()*
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
+ *vim.lsp.buf.remove_workspace_folder()*
+remove_workspace_folder({workspace_folder})
+ Remove the folder at path from the workspace folders. If
+ {path} is not provided, the user will be prompted for a path
+ using |input()|.
+
rename({new_name}) *vim.lsp.buf.rename()*
Renames all references to the symbol under the cursor.
@@ -996,19 +1028,6 @@ type_definition() *vim.lsp.buf.type_definition()*
Jumps to the definition of the type of the symbol under the
cursor.
-add_workspace_folder({path}) *vim.lsp.buf.add_workspace_folder()*
- Add the folder at path to the workspace folders. If {path} is
- not provided, the user will be prompted for a path using
- |input()|.
-
-remove_workspace_folder({path}) *vim.lsp.buf.remove_workspace_folder()*
- Remove the folder at path from the workspace folders. If
- {path} is not provided, the user will be prompted for
- a path using |input()|.
-
-list_workspace_folders() *vim.lsp.buf.list_workspace_folders()*
- List all folders in the workspace.
-
workspace_symbol({query}) *vim.lsp.buf.workspace_symbol()*
Lists all symbols in the current workspace in the quickfix
window.
@@ -1062,9 +1081,9 @@ get_count({bufnr}, {severity}, {client_id})
let sl = ''
if luaeval('not vim.tbl_isempty(vim.lsp.buf_get_clients(0))')
let sl.='%#MyStatuslineLSP#E:'
- let sl.='%#MyStatuslineLSPErrors#%{luaeval("vim.lsp.diagnostic.get_count(vim.fn.bufnr('%'), [[Error]])")}'
+ let sl.='%#MyStatuslineLSPErrors#%{luaeval("vim.lsp.diagnostic.get_count(0, [[Error]])")}'
let sl.='%#MyStatuslineLSP# W:'
- let sl.='%#MyStatuslineLSPWarnings#%{luaeval("vim.lsp.diagnostic.get_count(vim.fn.bufnr('%'), [[Warning]])")}'
+ let sl.='%#MyStatuslineLSPWarnings#%{luaeval("vim.lsp.diagnostic.get_count(0, [[Warning]])")}'
else
let sl.='%#MyStatuslineLSPErrors#off'
endif
@@ -1104,7 +1123,7 @@ get_next({opts}) *vim.lsp.diagnostic.get_next()*
Get the previous diagnostic closest to the cursor_position
Parameters: ~
- {opts} table See |vim.lsp.diagnostics.goto_next()|
+ {opts} table See |vim.lsp.diagnostic.goto_next()|
Return: ~
table Next diagnostic
@@ -1114,7 +1133,7 @@ get_next_pos({opts}) *vim.lsp.diagnostic.get_next_pos()*
current buffer.
Parameters: ~
- {opts} table See |vim.lsp.diagnostics.goto_next()|
+ {opts} table See |vim.lsp.diagnostic.goto_next()|
Return: ~
table Next diagnostic position
@@ -1123,7 +1142,7 @@ get_prev({opts}) *vim.lsp.diagnostic.get_prev()*
Get the previous diagnostic closest to the cursor_position
Parameters: ~
- {opts} table See |vim.lsp.diagnostics.goto_next()|
+ {opts} table See |vim.lsp.diagnostic.goto_next()|
Return: ~
table Previous diagnostic
@@ -1133,7 +1152,7 @@ get_prev_pos({opts}) *vim.lsp.diagnostic.get_prev_pos()*
current buffer.
Parameters: ~
- {opts} table See |vim.lsp.diagnostics.goto_next()|
+ {opts} table See |vim.lsp.diagnostic.goto_next()|
Return: ~
table Previous diagnostic position
@@ -1196,7 +1215,7 @@ goto_prev({opts}) *vim.lsp.diagnostic.goto_prev()*
Move to the previous diagnostic
Parameters: ~
- {opts} table See |vim.lsp.diagnostics.goto_next()|
+ {opts} table See |vim.lsp.diagnostic.goto_next()|
*vim.lsp.diagnostic.on_publish_diagnostics()*
on_publish_diagnostics({_}, {_}, {params}, {client_id}, {_}, {config})
@@ -1654,6 +1673,14 @@ make_text_document_params() *vim.lsp.util.make_text_document_params()*
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentIdentifier
+ *vim.lsp.util.make_workspace_params()*
+make_workspace_params({added}, {removed})
+ Create the workspace params
+
+ Parameters: ~
+ {added}
+ {removed}
+
*vim.lsp.util.open_floating_preview()*
open_floating_preview({contents}, {filetype}, {opts})
Shows contents in a floating window.
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index ae77b0a35a..cd6186834d 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -280,7 +280,7 @@ This lists the currently available predicates to use in queries.
Treesitter syntax highlighting (WIP) *lua-treesitter-highlight*
NOTE: This is a partially implemented feature, and not usable as a default
-solution yet. What is documented here is a temporary interface indented
+solution yet. What is documented here is a temporary interface intended
for those who want to experiment with this feature and contribute to
its development.
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index ed19fa1a43..ed3204c537 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1744,6 +1744,9 @@ au BufNewFile,BufRead *.tf,.tfrc,tfrc setf tf
" tmux configuration
au BufNewFile,BufRead {.,}tmux*.conf setf tmux
+" TOML
+au BufNewFile,BufRead *.toml setf toml
+
" TPP - Text Presentation Program
au BufNewFile,BufReadPost *.tpp setf tpp
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index f082fe29f2..ed31572abb 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1,3 +1,5 @@
+local if_nil = vim.F.if_nil
+
local default_handlers = require 'vim.lsp.handlers'
local log = require 'vim.lsp.log'
local lsp_rpc = require 'vim.lsp.rpc'
@@ -226,6 +228,7 @@ local function validate_client_config(config)
on_init = { config.on_init, "f", true };
before_init = { config.before_init, "f", true };
offset_encoding = { config.offset_encoding, "s", true };
+ flags = { config.flags, "t", true };
}
-- TODO(remove-callbacks)
@@ -434,6 +437,17 @@ end
---
--@param trace: "off" | "messages" | "verbose" | nil passed directly to the language
--- server in the initialize request. Invalid/empty values will default to "off"
+--@param flags: A table with flags for the client. The current (experimental) flags are:
+--- - allow_incremental_sync (bool, default false): Allow using on_line callbacks for lsp
+---
+--- <pre>
+--- -- In attach function for the client, you can do:
+--- local custom_attach = function(client)
+--- if client.config.flags then
+--- client.config.flags.allow_incremental_sync = true
+--- end
+--- end
+--- </pre>
---
--@returns Client id. |vim.lsp.get_client_by_id()| Note: client may not be
--- fully initialized. Use `on_init` to do any actions once
@@ -442,6 +456,8 @@ function lsp.start_client(config)
local cleaned_config = validate_client_config(config)
local cmd, cmd_args, offset_encoding = cleaned_config.cmd, cleaned_config.cmd_args, cleaned_config.offset_encoding
+ config.flags = config.flags or {}
+
local client_id = next_client_id()
-- TODO(remove-callbacks)
@@ -799,6 +815,7 @@ do
local size_index = encoding_index[client.offset_encoding]
local length = select(size_index, old_byte_size, old_utf16_size, old_utf32_size)
local lines = nvim_buf_get_lines(bufnr, firstline, new_lastline, true)
+
-- This is necessary because we are specifying the full line including the
-- newline in range. Therefore, we must replace the newline as well.
if #lines > 0 then
@@ -820,6 +837,8 @@ do
end)
local uri = vim.uri_from_bufnr(bufnr)
for_each_buffer_client(bufnr, function(client, _client_id)
+ local allow_incremental_sync = if_nil(client.config.flags.allow_incremental_sync, false)
+
local text_document_did_change = client.resolved_capabilities.text_document_did_change
local changes
if text_document_did_change == protocol.TextDocumentSyncKind.None then
@@ -830,7 +849,7 @@ do
-- is no way to specify the sync capability by the client.
-- See https://github.com/palantir/python-language-server/commit/cfd6675bc10d5e8dbc50fc50f90e4a37b7178821#diff-f68667852a14e9f761f6ebf07ba02fc8 for an example of pyls handling both.
--]=]
- elseif true or text_document_did_change == protocol.TextDocumentSyncKind.Full then
+ elseif not allow_incremental_sync or text_document_did_change == protocol.TextDocumentSyncKind.Full then
changes = full_changes(client)
elseif text_document_did_change == protocol.TextDocumentSyncKind.Incremental then
changes = incremental_changes(client)
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index a70581478b..00219b6d98 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -149,7 +149,7 @@ end
--@param options Table with valid `FormattingOptions` entries.
--@param start_pos ({number, number}, optional) mark-indexed position.
---Defaults to the start of the last visual selection.
---@param start_pos ({number, number}, optional) mark-indexed position.
+--@param end_pos ({number, number}, optional) mark-indexed position.
---Defaults to the end of the last visual selection.
function M.range_formatting(options, start_pos, end_pos)
validate { options = {options, 't', true} }
@@ -239,6 +239,7 @@ function M.outgoing_calls()
end
--- List workspace folders.
+---
function M.list_workspace_folders()
local workspace_folders = {}
for _, client in ipairs(vim.lsp.buf_get_clients()) do
@@ -249,7 +250,8 @@ function M.list_workspace_folders()
return workspace_folders
end
---- Add a workspace folder.
+--- Add the folder at path to the workspace folders. If {path} is
+--- not provided, the user will be prompted for a path using |input()|.
function M.add_workspace_folder(workspace_folder)
workspace_folder = workspace_folder or npcall(vfn.input, "Workspace Folder: ", vfn.expand('%:p:h'))
vim.api.nvim_command("redraw")
@@ -275,7 +277,9 @@ function M.add_workspace_folder(workspace_folder)
end
end
---- Remove a workspace folder.
+--- Remove the folder at path from the workspace folders. If
+--- {path} is not provided, the user will be prompted for
+--- a path using |input()|.
function M.remove_workspace_folder(workspace_folder)
workspace_folder = workspace_folder or npcall(vfn.input, "Workspace Folder: ", vfn.expand('%:p:h'))
vim.api.nvim_command("redraw")
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 27a1f53f89..efca5b53af 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -400,9 +400,9 @@ end
--- let sl = ''
--- if luaeval('not vim.tbl_isempty(vim.lsp.buf_get_clients(0))')
--- let sl.='%#MyStatuslineLSP#E:'
---- let sl.='%#MyStatuslineLSPErrors#%{luaeval("vim.lsp.diagnostic.get_count([[Error]])")}'
+--- let sl.='%#MyStatuslineLSPErrors#%{luaeval("vim.lsp.diagnostic.get_count(0, [[Error]])")}'
--- let sl.='%#MyStatuslineLSP# W:'
---- let sl.='%#MyStatuslineLSPWarnings#%{luaeval("vim.lsp.diagnostic.get_count([[Warning]])")}'
+--- let sl.='%#MyStatuslineLSPWarnings#%{luaeval("vim.lsp.diagnostic.get_count(0, [[Warning]])")}'
--- else
--- let sl.='%#MyStatuslineLSPErrors#off'
--- endif
@@ -510,7 +510,7 @@ end
--- Get the previous diagnostic closest to the cursor_position
---
----@param opts table See |vim.lsp.diagnostics.goto_next()|
+---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Previous diagnostic
function M.get_prev(opts)
opts = opts or {}
@@ -523,7 +523,7 @@ function M.get_prev(opts)
end
--- Return the pos, {row, col}, for the prev diagnostic in the current buffer.
----@param opts table See |vim.lsp.diagnostics.goto_next()|
+---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Previous diagnostic position
function M.get_prev_pos(opts)
return _iter_diagnostic_lines_pos(
@@ -533,7 +533,7 @@ function M.get_prev_pos(opts)
end
--- Move to the previous diagnostic
----@param opts table See |vim.lsp.diagnostics.goto_next()|
+---@param opts table See |vim.lsp.diagnostic.goto_next()|
function M.goto_prev(opts)
return _iter_diagnostic_move_pos(
"DiagnosticPrevious",
@@ -543,7 +543,7 @@ function M.goto_prev(opts)
end
--- Get the previous diagnostic closest to the cursor_position
----@param opts table See |vim.lsp.diagnostics.goto_next()|
+---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Next diagnostic
function M.get_next(opts)
opts = opts or {}
@@ -556,7 +556,7 @@ function M.get_next(opts)
end
--- Return the pos, {row, col}, for the next diagnostic in the current buffer.
----@param opts table See |vim.lsp.diagnostics.goto_next()|
+---@param opts table See |vim.lsp.diagnostic.goto_next()|
---@return table Next diagnostic position
function M.get_next_pos(opts)
return _iter_diagnostic_lines_pos(
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 5804ac6656..3da4dd6219 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1022,7 +1022,7 @@ do
--@deprecated
function M.buf_diagnostics_signs(bufnr, diagnostics, client_id)
- warn_once("buf_diagnostics_signs is deprecated. Use 'vim.lsp.diagnostics.set_signs'")
+ warn_once("buf_diagnostics_signs is deprecated. Use 'vim.lsp.diagnostic.set_signs'")
return vim.lsp.diagnostic.set_signs(diagnostics, bufnr, client_id)
end
@@ -1315,6 +1315,9 @@ function M.make_text_document_params()
return { uri = vim.uri_from_bufnr(0) }
end
+--- Create the workspace params
+--@param added
+--@param removed
function M.make_workspace_params(added, removed)
return { event = { added = added; removed = removed; } }
end
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 0a28891814..04b5fee256 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -452,7 +452,7 @@ end
function LanguageTree:language_for_range(range)
for _, child in pairs(self._children) do
if child:contains(range) then
- return child:node_for_range(range)
+ return child:language_for_range(range)
end
end
diff --git a/runtime/plugin/man.vim b/runtime/plugin/man.vim
index e762eb3664..689aa32ef3 100644
--- a/runtime/plugin/man.vim
+++ b/runtime/plugin/man.vim
@@ -5,9 +5,9 @@ if exists('g:loaded_man')
endif
let g:loaded_man = 1
-command! -bang -bar -range=0 -complete=customlist,man#complete -nargs=* Man
+command! -bang -bar -range=-1 -complete=customlist,man#complete -nargs=* Man
\ if <bang>0 | set ft=man |
- \ else | call man#open_page(v:count, v:count1, <q-mods>, <f-args>) | endif
+ \ else | call man#open_page(<count>, <q-mods>, <f-args>) | endif
augroup man
autocmd!
diff --git a/scripts/update_version_stamp.lua b/scripts/update_version_stamp.lua
index 11b521fab6..0342e08f31 100755
--- a/scripts/update_version_stamp.lua
+++ b/scripts/update_version_stamp.lua
@@ -35,11 +35,10 @@ if not described then
end
-- `git describe` annotates the most recent tagged release; for pre-release
--- builds we must replace that with the unreleased version.
-local with_prefix = described:gsub("^v%d+%.%d+%.%d+", prefix)
-if described == with_prefix then
- -- Prepend the prefix always, e.g. with "nightly-12208-g4041b62b9".
- with_prefix = prefix .. "-" .. described
+-- builds we append that to the dev version
+local with_prefix = prefix
+if prefix:match('-dev$') ~= nil then
+ with_prefix = prefix .. '+' .. described:gsub('^v%d+%.%d+%.%d+-', '')
end
-- Read existing include file.
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 8ec087c626..db77931c16 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -242,7 +242,7 @@ if(use_git_version)
add_custom_target(update_version_stamp ALL
COMMAND ${LUA_PRG} scripts/update_version_stamp.lua
${relbuild}/config/auto/versiondef_git.h
- "v${NVIM_VERSION_MAJOR}.${NVIM_VERSION_MINOR}.${NVIM_VERSION_PATCH}"
+ "v${NVIM_VERSION_MAJOR}.${NVIM_VERSION_MINOR}.${NVIM_VERSION_PATCH}${NVIM_VERSION_PRERELEASE}"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
BYPRODUCTS ${CMAKE_BINARY_DIR}/config/auto/versiondef_git.h)
else()
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 1011f050fd..db37e2100d 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1,7 +1,7 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-// Much of this code was adapted from 'if_py_both.h' from the original
+// Some of this code was adapted from 'if_py_both.h' from the original
// vim source
#include <stdbool.h>
#include <stdint.h>
@@ -80,34 +80,6 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err)
return buf->b_ml.ml_line_count;
}
-/// Gets a buffer line
-///
-/// @deprecated use nvim_buf_get_lines instead.
-/// for positive indices (including 0) use
-/// "nvim_buf_get_lines(buffer, index, index+1, true)"
-/// for negative indices use
-/// "nvim_buf_get_lines(buffer, index-1, index, true)"
-///
-/// @param buffer Buffer handle
-/// @param index Line index
-/// @param[out] err Error details, if any
-/// @return Line string
-String buffer_get_line(Buffer buffer, Integer index, Error *err)
-{
- String rv = { .size = 0 };
-
- index = convert_index(index);
- Array slice = nvim_buf_get_lines(0, buffer, index, index+1, true, err);
-
- if (!ERROR_SET(err) && slice.size) {
- rv = slice.items[0].data.string;
- }
-
- xfree(slice.items);
-
- return rv;
-}
-
/// Activates buffer-update events on a channel, or as Lua callbacks.
///
/// Example (Lua): capture buffer updates in a global `events` variable
@@ -258,68 +230,6 @@ void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last,
redraw_buf_range_later(buf, (linenr_T)first+1, (linenr_T)last);
}
-/// Sets a buffer line
-///
-/// @deprecated use nvim_buf_set_lines instead.
-/// for positive indices use
-/// "nvim_buf_set_lines(buffer, index, index+1, true, [line])"
-/// for negative indices use
-/// "nvim_buf_set_lines(buffer, index-1, index, true, [line])"
-///
-/// @param buffer Buffer handle
-/// @param index Line index
-/// @param line Contents of the new line
-/// @param[out] err Error details, if any
-void buffer_set_line(Buffer buffer, Integer index, String line, Error *err)
-{
- Object l = STRING_OBJ(line);
- Array array = { .items = &l, .size = 1 };
- index = convert_index(index);
- nvim_buf_set_lines(0, buffer, index, index+1, true, array, err);
-}
-
-/// Deletes a buffer line
-///
-/// @deprecated use nvim_buf_set_lines instead.
-/// for positive indices use
-/// "nvim_buf_set_lines(buffer, index, index+1, true, [])"
-/// for negative indices use
-/// "nvim_buf_set_lines(buffer, index-1, index, true, [])"
-/// @param buffer buffer handle
-/// @param index line index
-/// @param[out] err Error details, if any
-void buffer_del_line(Buffer buffer, Integer index, Error *err)
-{
- Array array = ARRAY_DICT_INIT;
- index = convert_index(index);
- nvim_buf_set_lines(0, buffer, index, index+1, true, array, err);
-}
-
-/// Retrieves a line range from the buffer
-///
-/// @deprecated use nvim_buf_get_lines(buffer, newstart, newend, false)
-/// where newstart = start + int(not include_start) - int(start < 0)
-/// newend = end + int(include_end) - int(end < 0)
-/// int(bool) = 1 if bool is true else 0
-/// @param buffer Buffer handle
-/// @param start First line index
-/// @param end Last line index
-/// @param include_start True if the slice includes the `start` parameter
-/// @param include_end True if the slice includes the `end` parameter
-/// @param[out] err Error details, if any
-/// @return Array of lines
-ArrayOf(String) buffer_get_line_slice(Buffer buffer,
- Integer start,
- Integer end,
- Boolean include_start,
- Boolean include_end,
- Error *err)
-{
- start = convert_index(start) + !include_start;
- end = convert_index(end) + include_end;
- return nvim_buf_get_lines(0, buffer, start , end, false, err);
-}
-
/// Gets a line-range from the buffer.
///
/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
@@ -392,35 +302,6 @@ end:
}
-/// Replaces a line range on the buffer
-///
-/// @deprecated use nvim_buf_set_lines(buffer, newstart, newend, false, lines)
-/// where newstart = start + int(not include_start) + int(start < 0)
-/// newend = end + int(include_end) + int(end < 0)
-/// int(bool) = 1 if bool is true else 0
-///
-/// @param buffer Buffer handle, or 0 for current buffer
-/// @param start First line index
-/// @param end Last line index
-/// @param include_start True if the slice includes the `start` parameter
-/// @param include_end True if the slice includes the `end` parameter
-/// @param replacement Array of lines to use as replacement (0-length
-// array will delete the line range)
-/// @param[out] err Error details, if any
-void buffer_set_line_slice(Buffer buffer,
- Integer start,
- Integer end,
- Boolean include_start,
- Boolean include_end,
- ArrayOf(String) replacement,
- Error *err)
-{
- start = convert_index(start) + !include_start;
- end = convert_index(end) + include_end;
- nvim_buf_set_lines(0, buffer, start, end, false, replacement, err);
-}
-
-
/// Sets (replaces) a line-range in the buffer.
///
/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
@@ -787,48 +668,6 @@ void nvim_buf_del_var(Buffer buffer, String name, Error *err)
dict_set_var(buf->b_vars, name, NIL, true, false, err);
}
-/// Sets a buffer-scoped (b:) variable
-///
-/// @deprecated
-///
-/// @param buffer Buffer handle, or 0 for current buffer
-/// @param name Variable name
-/// @param value Variable value
-/// @param[out] err Error details, if any
-/// @return Old value or nil if there was no previous value.
-///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
-Object buffer_set_var(Buffer buffer, String name, Object value, Error *err)
-{
- buf_T *buf = find_buffer_by_handle(buffer, err);
-
- if (!buf) {
- return (Object) OBJECT_INIT;
- }
-
- return dict_set_var(buf->b_vars, name, value, false, true, err);
-}
-
-/// Removes a buffer-scoped (b:) variable
-///
-/// @deprecated
-///
-/// @param buffer Buffer handle, or 0 for current buffer
-/// @param name Variable name
-/// @param[out] err Error details, if any
-/// @return Old value
-Object buffer_del_var(Buffer buffer, String name, Error *err)
-{
- buf_T *buf = find_buffer_by_handle(buffer, err);
-
- if (!buf) {
- return (Object) OBJECT_INIT;
- }
-
- return dict_set_var(buf->b_vars, name, NIL, true, true, err);
-}
-
/// Gets a buffer option value
///
@@ -869,28 +708,6 @@ void nvim_buf_set_option(uint64_t channel_id, Buffer buffer,
set_option_to(channel_id, buf, SREQ_BUF, name, value, err);
}
-/// Gets the buffer number
-///
-/// @deprecated The buffer number now is equal to the object id,
-/// so there is no need to use this function.
-///
-/// @param buffer Buffer handle, or 0 for current buffer
-/// @param[out] err Error details, if any
-/// @return Buffer number
-Integer nvim_buf_get_number(Buffer buffer, Error *err)
- FUNC_API_SINCE(1)
- FUNC_API_DEPRECATED_SINCE(2)
-{
- Integer rv = 0;
- buf_T *buf = find_buffer_by_handle(buffer, err);
-
- if (!buf) {
- return rv;
- }
-
- return buf->b_fnum;
-}
-
/// Gets the full file name for the buffer
///
/// @param buffer Buffer handle, or 0 for current buffer
@@ -1017,25 +834,6 @@ Boolean nvim_buf_is_valid(Buffer buffer)
return ret;
}
-/// Inserts a sequence of lines to a buffer at a certain index
-///
-/// @deprecated use nvim_buf_set_lines(buffer, lnum, lnum, true, lines)
-///
-/// @param buffer Buffer handle
-/// @param lnum Insert the lines after `lnum`. If negative, appends to
-/// the end of the buffer.
-/// @param lines Array of lines
-/// @param[out] err Error details, if any
-void buffer_insert(Buffer buffer,
- Integer lnum,
- ArrayOf(String) lines,
- Error *err)
-{
- // "lnum" will be the index of the line after inserting,
- // no matter if it is negative or not
- nvim_buf_set_lines(0, buffer, lnum, lnum, true, lines, err);
-}
-
/// Return a tuple (row,col) representing the position of the named mark.
///
/// Marks are (1,0)-indexed. |api-indexing|
@@ -1667,27 +1465,6 @@ void nvim_buf_clear_namespace(Buffer buffer,
(int)line_end-1, MAXCOL);
}
-/// Clears highlights and virtual text from namespace and range of lines
-///
-/// @deprecated use |nvim_buf_clear_namespace()|.
-///
-/// @param buffer Buffer handle, or 0 for current buffer
-/// @param ns_id Namespace to clear, or -1 to clear all.
-/// @param line_start Start of range of lines to clear
-/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
-/// to end of file.
-/// @param[out] err Error details, if any
-void nvim_buf_clear_highlight(Buffer buffer,
- Integer ns_id,
- Integer line_start,
- Integer line_end,
- Error *err)
- FUNC_API_SINCE(1)
-{
- nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end, err);
-}
-
-
/// Set the virtual text (annotation) for a buffer line.
///
/// By default (and currently the only option) the text will be placed after
@@ -1873,8 +1650,3 @@ static int64_t normalize_index(buf_T *buf, int64_t index, bool *oob)
index++;
return index;
}
-
-static int64_t convert_index(int64_t index)
-{
- return index < 0 ? index - 1 : index;
-}
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
new file mode 100644
index 0000000000..3989386bb9
--- /dev/null
+++ b/src/nvim/api/deprecated.c
@@ -0,0 +1,367 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "nvim/api/deprecated.h"
+#include "nvim/api/buffer.h"
+#include "nvim/api/vim.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/lua/executor.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "api/deprecated.c.generated.h"
+#endif
+
+/// @deprecated
+/// @see nvim_exec
+String nvim_command_output(String command, Error *err)
+ FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(7)
+{
+ return nvim_exec(command, true, err);
+}
+
+/// @deprecated Use nvim_exec_lua() instead.
+/// @see nvim_exec_lua
+Object nvim_execute_lua(String code, Array args, Error *err)
+ FUNC_API_SINCE(3)
+ FUNC_API_DEPRECATED_SINCE(7)
+ FUNC_API_REMOTE_ONLY
+{
+ return nlua_exec(code, args, err);
+}
+
+/// Gets the buffer number
+///
+/// @deprecated The buffer number now is equal to the object id,
+/// so there is no need to use this function.
+///
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param[out] err Error details, if any
+/// @return Buffer number
+Integer nvim_buf_get_number(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(2)
+{
+ Integer rv = 0;
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return rv;
+ }
+
+ return buf->b_fnum;
+}
+
+/// Clears highlights and virtual text from namespace and range of lines
+///
+/// @deprecated use |nvim_buf_clear_namespace()|.
+///
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param ns_id Namespace to clear, or -1 to clear all.
+/// @param line_start Start of range of lines to clear
+/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
+/// to end of file.
+/// @param[out] err Error details, if any
+void nvim_buf_clear_highlight(Buffer buffer,
+ Integer ns_id,
+ Integer line_start,
+ Integer line_end,
+ Error *err)
+ FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(7)
+{
+ nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end, err);
+}
+
+
+/// Inserts a sequence of lines to a buffer at a certain index
+///
+/// @deprecated use nvim_buf_set_lines(buffer, lnum, lnum, true, lines)
+///
+/// @param buffer Buffer handle
+/// @param lnum Insert the lines after `lnum`. If negative, appends to
+/// the end of the buffer.
+/// @param lines Array of lines
+/// @param[out] err Error details, if any
+void buffer_insert(Buffer buffer,
+ Integer lnum,
+ ArrayOf(String) lines,
+ Error *err)
+{
+ // "lnum" will be the index of the line after inserting,
+ // no matter if it is negative or not
+ nvim_buf_set_lines(0, buffer, lnum, lnum, true, lines, err);
+}
+
+/// Gets a buffer line
+///
+/// @deprecated use nvim_buf_get_lines instead.
+/// for positive indices (including 0) use
+/// "nvim_buf_get_lines(buffer, index, index+1, true)"
+/// for negative indices use
+/// "nvim_buf_get_lines(buffer, index-1, index, true)"
+///
+/// @param buffer Buffer handle
+/// @param index Line index
+/// @param[out] err Error details, if any
+/// @return Line string
+String buffer_get_line(Buffer buffer, Integer index, Error *err)
+{
+ String rv = { .size = 0 };
+
+ index = convert_index(index);
+ Array slice = nvim_buf_get_lines(0, buffer, index, index+1, true, err);
+
+ if (!ERROR_SET(err) && slice.size) {
+ rv = slice.items[0].data.string;
+ }
+
+ xfree(slice.items);
+
+ return rv;
+}
+
+/// Sets a buffer line
+///
+/// @deprecated use nvim_buf_set_lines instead.
+/// for positive indices use
+/// "nvim_buf_set_lines(buffer, index, index+1, true, [line])"
+/// for negative indices use
+/// "nvim_buf_set_lines(buffer, index-1, index, true, [line])"
+///
+/// @param buffer Buffer handle
+/// @param index Line index
+/// @param line Contents of the new line
+/// @param[out] err Error details, if any
+void buffer_set_line(Buffer buffer, Integer index, String line, Error *err)
+{
+ Object l = STRING_OBJ(line);
+ Array array = { .items = &l, .size = 1 };
+ index = convert_index(index);
+ nvim_buf_set_lines(0, buffer, index, index+1, true, array, err);
+}
+
+/// Deletes a buffer line
+///
+/// @deprecated use nvim_buf_set_lines instead.
+/// for positive indices use
+/// "nvim_buf_set_lines(buffer, index, index+1, true, [])"
+/// for negative indices use
+/// "nvim_buf_set_lines(buffer, index-1, index, true, [])"
+/// @param buffer buffer handle
+/// @param index line index
+/// @param[out] err Error details, if any
+void buffer_del_line(Buffer buffer, Integer index, Error *err)
+{
+ Array array = ARRAY_DICT_INIT;
+ index = convert_index(index);
+ nvim_buf_set_lines(0, buffer, index, index+1, true, array, err);
+}
+
+/// Retrieves a line range from the buffer
+///
+/// @deprecated use nvim_buf_get_lines(buffer, newstart, newend, false)
+/// where newstart = start + int(not include_start) - int(start < 0)
+/// newend = end + int(include_end) - int(end < 0)
+/// int(bool) = 1 if bool is true else 0
+/// @param buffer Buffer handle
+/// @param start First line index
+/// @param end Last line index
+/// @param include_start True if the slice includes the `start` parameter
+/// @param include_end True if the slice includes the `end` parameter
+/// @param[out] err Error details, if any
+/// @return Array of lines
+ArrayOf(String) buffer_get_line_slice(Buffer buffer,
+ Integer start,
+ Integer end,
+ Boolean include_start,
+ Boolean include_end,
+ Error *err)
+{
+ start = convert_index(start) + !include_start;
+ end = convert_index(end) + include_end;
+ return nvim_buf_get_lines(0, buffer, start , end, false, err);
+}
+
+/// Replaces a line range on the buffer
+///
+/// @deprecated use nvim_buf_set_lines(buffer, newstart, newend, false, lines)
+/// where newstart = start + int(not include_start) + int(start < 0)
+/// newend = end + int(include_end) + int(end < 0)
+/// int(bool) = 1 if bool is true else 0
+///
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param start First line index
+/// @param end Last line index
+/// @param include_start True if the slice includes the `start` parameter
+/// @param include_end True if the slice includes the `end` parameter
+/// @param replacement Array of lines to use as replacement (0-length
+// array will delete the line range)
+/// @param[out] err Error details, if any
+void buffer_set_line_slice(Buffer buffer,
+ Integer start,
+ Integer end,
+ Boolean include_start,
+ Boolean include_end,
+ ArrayOf(String) replacement,
+ Error *err)
+{
+ start = convert_index(start) + !include_start;
+ end = convert_index(end) + include_end;
+ nvim_buf_set_lines(0, buffer, start, end, false, replacement, err);
+}
+
+
+/// Sets a buffer-scoped (b:) variable
+///
+/// @deprecated
+///
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+/// @return Old value or nil if there was no previous value.
+///
+/// @warning It may return nil if there was no previous value
+/// or if previous value was `v:null`.
+Object buffer_set_var(Buffer buffer, String name, Object value, Error *err)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return NIL;
+ }
+
+ return dict_set_var(buf->b_vars, name, value, false, true, err);
+}
+
+/// Removes a buffer-scoped (b:) variable
+///
+/// @deprecated
+///
+/// @param buffer Buffer handle, or 0 for current buffer
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Old value
+Object buffer_del_var(Buffer buffer, String name, Error *err)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return NIL;
+ }
+
+ return dict_set_var(buf->b_vars, name, NIL, true, true, err);
+}
+
+/// Sets a window-scoped (w:) variable
+///
+/// @deprecated
+///
+/// @param window Window handle, or 0 for current window
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+/// @return Old value or nil if there was no previous value.
+///
+/// @warning It may return nil if there was no previous value
+/// or if previous value was `v:null`.
+Object window_set_var(Window window, String name, Object value, Error *err)
+{
+ win_T *win = find_window_by_handle(window, err);
+
+ if (!win) {
+ return NIL;
+ }
+
+ return dict_set_var(win->w_vars, name, value, false, true, err);
+}
+
+/// Removes a window-scoped (w:) variable
+///
+/// @deprecated
+///
+/// @param window Window handle, or 0 for current window
+/// @param name variable name
+/// @param[out] err Error details, if any
+/// @return Old value
+Object window_del_var(Window window, String name, Error *err)
+{
+ win_T *win = find_window_by_handle(window, err);
+
+ if (!win) {
+ return NIL;
+ }
+
+ return dict_set_var(win->w_vars, name, NIL, true, true, err);
+}
+
+/// Sets a tab-scoped (t:) variable
+///
+/// @deprecated
+///
+/// @param tabpage Tabpage handle, or 0 for current tabpage
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+/// @return Old value or nil if there was no previous value.
+///
+/// @warning It may return nil if there was no previous value
+/// or if previous value was `v:null`.
+Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
+{
+ tabpage_T *tab = find_tab_by_handle(tabpage, err);
+
+ if (!tab) {
+ return NIL;
+ }
+
+ return dict_set_var(tab->tp_vars, name, value, false, true, err);
+}
+
+/// Removes a tab-scoped (t:) variable
+///
+/// @deprecated
+///
+/// @param tabpage Tabpage handle, or 0 for current tabpage
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Old value
+Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
+{
+ tabpage_T *tab = find_tab_by_handle(tabpage, err);
+
+ if (!tab) {
+ return NIL;
+ }
+
+ return dict_set_var(tab->tp_vars, name, NIL, true, true, err);
+}
+
+/// @deprecated
+/// @see nvim_set_var
+/// @warning May return nil if there was no previous value
+/// OR if previous value was `v:null`.
+/// @return Old value or nil if there was no previous value.
+Object vim_set_var(String name, Object value, Error *err)
+{
+ return dict_set_var(&globvardict, name, value, false, true, err);
+}
+
+/// @deprecated
+/// @see nvim_del_var
+Object vim_del_var(String name, Error *err)
+{
+ return dict_set_var(&globvardict, name, NIL, true, true, err);
+}
+
+static int64_t convert_index(int64_t index)
+{
+ return index < 0 ? index - 1 : index;
+}
diff --git a/src/nvim/api/deprecated.h b/src/nvim/api/deprecated.h
new file mode 100644
index 0000000000..79095167e1
--- /dev/null
+++ b/src/nvim/api/deprecated.h
@@ -0,0 +1,11 @@
+#ifndef NVIM_API_DEPRECATED_H
+#define NVIM_API_DEPRECATED_H
+
+#include <stdint.h>
+
+#include "nvim/api/private/defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "api/deprecated.h.generated.h"
+#endif
+#endif // NVIM_API_DEPRECATED_H
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
index 2975df3c68..eae4581f42 100644
--- a/src/nvim/api/private/dispatch.c
+++ b/src/nvim/api/private/dispatch.c
@@ -19,6 +19,7 @@
#include "nvim/api/ui.h"
#include "nvim/api/vim.h"
#include "nvim/api/window.h"
+#include "nvim/api/deprecated.h"
static Map(String, MsgpackRpcRequestHandler) *methods = NULL;
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c
index dd17bc03e5..5f727dbc38 100644
--- a/src/nvim/api/tabpage.c
+++ b/src/nvim/api/tabpage.c
@@ -97,48 +97,6 @@ void nvim_tabpage_del_var(Tabpage tabpage, String name, Error *err)
dict_set_var(tab->tp_vars, name, NIL, true, false, err);
}
-/// Sets a tab-scoped (t:) variable
-///
-/// @deprecated
-///
-/// @param tabpage Tabpage handle, or 0 for current tabpage
-/// @param name Variable name
-/// @param value Variable value
-/// @param[out] err Error details, if any
-/// @return Old value or nil if there was no previous value.
-///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
-Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
-{
- tabpage_T *tab = find_tab_by_handle(tabpage, err);
-
- if (!tab) {
- return (Object) OBJECT_INIT;
- }
-
- return dict_set_var(tab->tp_vars, name, value, false, true, err);
-}
-
-/// Removes a tab-scoped (t:) variable
-///
-/// @deprecated
-///
-/// @param tabpage Tabpage handle, or 0 for current tabpage
-/// @param name Variable name
-/// @param[out] err Error details, if any
-/// @return Old value
-Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
-{
- tabpage_T *tab = find_tab_by_handle(tabpage, err);
-
- if (!tab) {
- return (Object) OBJECT_INIT;
- }
-
- return dict_set_var(tab->tp_vars, name, NIL, true, true, err);
-}
-
/// Gets the current window in a tabpage
///
/// @param tabpage Tabpage handle, or 0 for current tabpage
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 8ac820abd9..8b80d4aad9 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -15,6 +15,7 @@
#include "nvim/api/private/dispatch.h"
#include "nvim/api/buffer.h"
#include "nvim/api/window.h"
+#include "nvim/api/deprecated.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/lua/executor.h"
@@ -479,15 +480,6 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
return cstr_as_string(ptr);
}
-/// @deprecated
-/// @see nvim_exec
-String nvim_command_output(String command, Error *err)
- FUNC_API_SINCE(1)
- FUNC_API_DEPRECATED_SINCE(7)
-{
- return nvim_exec(command, true, err);
-}
-
/// Evaluates a VimL |expression|.
/// Dictionaries and Lists are recursively expanded.
///
@@ -534,16 +526,6 @@ Object nvim_eval(String expr, Error *err)
return rv;
}
-/// @deprecated Use nvim_exec_lua() instead.
-/// @see nvim_exec_lua
-Object nvim_execute_lua(String code, Array args, Error *err)
- FUNC_API_SINCE(3)
- FUNC_API_DEPRECATED_SINCE(7)
- FUNC_API_REMOTE_ONLY
-{
- return nlua_exec(code, args, err);
-}
-
/// Execute Lua code. Parameters (if any) are available as `...` inside the
/// chunk. The chunk can return a value.
///
@@ -920,23 +902,6 @@ void nvim_del_var(String name, Error *err)
dict_set_var(&globvardict, name, NIL, true, false, err);
}
-/// @deprecated
-/// @see nvim_set_var
-/// @warning May return nil if there was no previous value
-/// OR if previous value was `v:null`.
-/// @return Old value or nil if there was no previous value.
-Object vim_set_var(String name, Object value, Error *err)
-{
- return dict_set_var(&globvardict, name, value, false, true, err);
-}
-
-/// @deprecated
-/// @see nvim_del_var
-Object vim_del_var(String name, Error *err)
-{
- return dict_set_var(&globvardict, name, NIL, true, true, err);
-}
-
/// Gets a v: variable.
///
/// @param name Variable name
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index f09a03f592..a3ec1c8e53 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -288,48 +288,6 @@ void nvim_win_del_var(Window window, String name, Error *err)
dict_set_var(win->w_vars, name, NIL, true, false, err);
}
-/// Sets a window-scoped (w:) variable
-///
-/// @deprecated
-///
-/// @param window Window handle, or 0 for current window
-/// @param name Variable name
-/// @param value Variable value
-/// @param[out] err Error details, if any
-/// @return Old value or nil if there was no previous value.
-///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
-Object window_set_var(Window window, String name, Object value, Error *err)
-{
- win_T *win = find_window_by_handle(window, err);
-
- if (!win) {
- return (Object) OBJECT_INIT;
- }
-
- return dict_set_var(win->w_vars, name, value, false, true, err);
-}
-
-/// Removes a window-scoped (w:) variable
-///
-/// @deprecated
-///
-/// @param window Window handle, or 0 for current window
-/// @param name variable name
-/// @param[out] err Error details, if any
-/// @return Old value
-Object window_del_var(Window window, String name, Error *err)
-{
- win_T *win = find_window_by_handle(window, err);
-
- if (!win) {
- return (Object) OBJECT_INIT;
- }
-
- return dict_set_var(win->w_vars, name, NIL, true, true, err);
-}
-
/// Gets a window option value
///
/// @param window Window handle, or 0 for current window
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index ed408c28e5..a0910f1394 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -4327,7 +4327,8 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
/// if true then it escapes for a shell command.
///
/// @return [allocated] escaped file name.
-char *vim_strsave_fnameescape(const char *const fname, const bool shell)
+char *vim_strsave_fnameescape(const char *const fname,
+ const bool shell FUNC_ATTR_UNUSED)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
#ifdef BACKSLASH_IN_FILENAME
diff --git a/src/nvim/log.c b/src/nvim/log.c
index 225e40cdb4..19203a3c2a 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -13,9 +13,6 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
-#if !defined(WIN32)
-# include <sys/time.h> // for gettimeofday()
-#endif
#include <uv.h>
#include "auto/config.h"
@@ -296,12 +293,10 @@ static bool v_do_log_to_file(FILE *log_file, int log_level,
}
int millis = 0;
-#if !defined(WIN32)
- struct timeval curtime;
- if (gettimeofday(&curtime, NULL) == 0) {
+ uv_timeval64_t curtime;
+ if (uv_gettimeofday(&curtime) == 0) {
millis = (int)curtime.tv_usec / 1000;
}
-#endif
// Print the log message.
int64_t pid = os_get_pid();
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 79c165419e..025312a6e1 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1414,7 +1414,10 @@ static void read_stdin(void)
no_wait_return = true;
int save_msg_didany = msg_didany;
set_buflisted(true);
- (void)open_buffer(true, NULL, 0); // create memfile and read file
+
+ // Create memfile and read from stdin.
+ (void)open_buffer(true, NULL, 0);
+
if (BUFEMPTY() && curbuf->b_next != NULL) {
// stdin was empty, go to buffer 2 (e.g. "echo file1 | xargs nvim"). #8561
do_cmdline_cmd("silent! bnext");
diff --git a/src/nvim/message.c b/src/nvim/message.c
index ad38e6d060..02a7732f5c 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1712,7 +1712,7 @@ void msg_prt_line(char_u *s, int list)
col += utf_ptr2cells(s);
char buf[MB_MAXBYTES + 1];
if (l >= MB_MAXBYTES) {
- xstrlcpy(buf, "¿", sizeof(buf));
+ xstrlcpy(buf, "?", sizeof(buf));
} else if (curwin->w_p_lcs_chars.nbsp != NUL && list
&& (utf_ptr2char(s) == 160
|| utf_ptr2char(s) == 0x202f)) {
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index f242b7d71a..551a650045 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -742,6 +742,7 @@ static int pum_set_selected(int n, int repeat)
// Edit a new, empty buffer. Set options for a "wipeout"
// buffer.
set_option_value("swf", 0L, NULL, OPT_LOCAL);
+ set_option_value("bl", 0L, NULL, OPT_LOCAL);
set_option_value("bt", 0L, "nofile", OPT_LOCAL);
set_option_value("bh", 0L, "wipe", OPT_LOCAL);
set_option_value("diff", 0L, NULL, OPT_LOCAL);
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 1c88bd4ba4..2878e73573 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -3605,6 +3605,22 @@ theend:
if (backpos.ga_maxlen > BACKPOS_INITIAL)
ga_clear(&backpos);
+ // Make sure the end is never before the start. Can happen when \zs and
+ // \ze are used.
+ if (REG_MULTI) {
+ const lpos_T *const start = &rex.reg_mmatch->startpos[0];
+ const lpos_T *const end = &rex.reg_mmatch->endpos[0];
+
+ if (end->lnum < start->lnum
+ || (end->lnum == start->lnum && end->col < start->col)) {
+ rex.reg_mmatch->endpos[0] = rex.reg_mmatch->startpos[0];
+ }
+ } else {
+ if (rex.reg_match->endp[0] < rex.reg_match->startp[0]) {
+ rex.reg_match->endp[0] = rex.reg_match->startp[0];
+ }
+ }
+
return retval;
}
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 7dfd16fb4f..137b2304c0 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -6591,6 +6591,22 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol,
#endif
theend:
+ // Make sure the end is never before the start. Can happen when \zs and
+ // \ze are used.
+ if (REG_MULTI) {
+ const lpos_T *const start = &rex.reg_mmatch->startpos[0];
+ const lpos_T *const end = &rex.reg_mmatch->endpos[0];
+
+ if (end->lnum < start->lnum
+ || (end->lnum == start->lnum && end->col < start->col)) {
+ rex.reg_mmatch->endpos[0] = rex.reg_mmatch->startpos[0];
+ }
+ } else {
+ if (rex.reg_match->endp[0] < rex.reg_match->startp[0]) {
+ rex.reg_match->endp[0] = rex.reg_match->startp[0];
+ }
+ }
+
return retval;
}
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index f3c3e085f6..356a7ce135 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -463,6 +463,7 @@ let s:filename_checks = {
\ 'tilde': ['file.t.html'],
\ 'tli': ['file.tli'],
\ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf'],
+ \ 'toml': ['file.toml'],
\ 'tpp': ['file.tpp'],
\ 'treetop': ['file.treetop'],
\ 'trustees': ['trustees.conf'],
diff --git a/src/nvim/testdir/test_regexp_latin.vim b/src/nvim/testdir/test_regexp_latin.vim
index 2ee0ee1c0c..1bb2ee53de 100644
--- a/src/nvim/testdir/test_regexp_latin.vim
+++ b/src/nvim/testdir/test_regexp_latin.vim
@@ -755,6 +755,13 @@ func Test_start_end_of_buffer_match()
bwipe!
endfunc
+func Test_ze_before_zs()
+ call assert_equal('', matchstr(' ', '\%#=1\ze \zs'))
+ call assert_equal('', matchstr(' ', '\%#=2\ze \zs'))
+ call assert_equal(repeat([''], 10), matchlist(' ', '\%#=1\ze \zs'))
+ call assert_equal(repeat([''], 10), matchlist(' ', '\%#=2\ze \zs'))
+endfunc
+
" Check for detecting error
func Test_regexp_error()
set regexpengine=2
diff --git a/src/nvim/testdir/test_ruby.vim b/src/nvim/testdir/test_ruby.vim
index 9c74c35049..1a274d1fec 100644
--- a/src/nvim/testdir/test_ruby.vim
+++ b/src/nvim/testdir/test_ruby.vim
@@ -27,6 +27,19 @@ func Test_rubydo()
%bwipe!
endfunc
+func Test_rubydo_dollar_underscore()
+ throw 'skipped: TODO: '
+ new
+ call setline(1, ['one', 'two', 'three', 'four'])
+ 2,3rubydo $_ = '[' + $_ + ']'
+ call assert_equal(['one', '[two]', '[three]', 'four'], getline(1, '$'))
+ bwipe!
+
+ call assert_fails('rubydo $_ = 0', 'E265:')
+ call assert_fails('rubydo (')
+ bwipe!
+endfunc
+
func Test_rubyfile()
" Check :rubyfile does not SEGV with Ruby level exception but just fails
let tempfile = tempname() . '.rb'
@@ -391,3 +404,14 @@ func Test_ruby_p()
let messages = GetMessages()
call assert_equal(0, len(messages))
endfunc
+
+func Test_rubyeval_error()
+ " On Linux or Windows the error matches:
+ " "syntax error, unexpected end-of-input"
+ " whereas on macOS in CI, the error message makes less sense:
+ " "SyntaxError: array length must be 2"
+ " Unclear why. The test does not check the error message.
+ call assert_fails('call rubyeval("(")')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
index 6824c50112..8d71ada551 100644
--- a/src/nvim/testdir/test_search.vim
+++ b/src/nvim/testdir/test_search.vim
@@ -508,7 +508,7 @@ endfunc
func Test_search_cmdline7()
throw 'skipped: Nvim does not support test_override()'
- " Test that an pressing <c-g> in an empty command line
+ " Test that pressing <c-g> in an empty command line
" does not move the cursor
if !exists('+incsearch')
return
@@ -1172,3 +1172,24 @@ func Test_search_special()
set t_PE=
exe "norm /\x80PS"
endfunc
+
+" Test 'smartcase' with utf-8.
+func Test_search_smartcase_utf8()
+ new
+ let save_enc = &encoding
+ set encoding=utf8 ignorecase smartcase
+
+ call setline(1, 'Café cafÉ')
+ 1s/café/x/g
+ call assert_equal('x x', getline(1))
+
+ call setline(1, 'Café cafÉ')
+ 1s/cafÉ/x/g
+ call assert_equal('Café x', getline(1))
+
+ set ignorecase& smartcase&
+ let &encoding = save_enc
+ close!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index a8b8f7aa50..636d00bbbf 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -1255,7 +1255,8 @@ theend:
/// a bit more verbose.
/// Otherwise use curbuf->b_ffname to generate the undo file name.
/// "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
-void u_read_undo(char *name, char_u *hash, char_u *orig_name)
+void u_read_undo(char *name, const char_u *hash,
+ const char_u *orig_name FUNC_ATTR_UNUSED)
FUNC_ATTR_NONNULL_ARG(2)
{
u_header_T **uhp_table = NULL;
@@ -1273,7 +1274,7 @@ void u_read_undo(char *name, char_u *hash, char_u *orig_name)
// owner of the text file or equal to the current user.
FileInfo file_info_orig;
FileInfo file_info_undo;
- if (os_fileinfo((char *)orig_name, &file_info_orig)
+ if (os_fileinfo((const char *)orig_name, &file_info_orig)
&& os_fileinfo((char *)file_name, &file_info_undo)
&& file_info_orig.stat.st_uid != file_info_undo.stat.st_uid
&& file_info_undo.stat.st_uid != getuid()) {
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 72ee400e40..9eb16e67ec 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3787,32 +3787,35 @@ void free_tabpage(tabpage_T *tp)
/// @return Was the new tabpage created successfully? FAIL or OK.
int win_new_tabpage(int after, char_u *filename)
{
- tabpage_T *tp = curtab;
+ tabpage_T *old_curtab = curtab;
tabpage_T *newtp;
int n;
newtp = alloc_tabpage();
- /* Remember the current windows in this Tab page. */
- if (leave_tabpage(curbuf, TRUE) == FAIL) {
+ // Remember the current windows in this Tab page.
+ if (leave_tabpage(curbuf, true) == FAIL) {
xfree(newtp);
return FAIL;
}
- newtp->tp_localdir = tp->tp_localdir ? vim_strsave(tp->tp_localdir) : NULL;
+ newtp->tp_localdir = old_curtab->tp_localdir
+ ? vim_strsave(old_curtab->tp_localdir) : NULL;
curtab = newtp;
- /* Create a new empty window. */
- if (win_alloc_firstwin(tp->tp_curwin) == OK) {
- /* Make the new Tab page the new topframe. */
+ // Create a new empty window.
+ if (win_alloc_firstwin(old_curtab->tp_curwin) == OK) {
+ // Make the new Tab page the new topframe.
if (after == 1) {
- /* New tab page becomes the first one. */
+ // New tab page becomes the first one.
newtp->tp_next = first_tabpage;
first_tabpage = newtp;
} else {
+ tabpage_T *tp = old_curtab;
+
if (after > 0) {
- /* Put new tab page before tab page "after". */
+ // Put new tab page before tab page "after".
n = 2;
for (tp = first_tabpage; tp->tp_next != NULL
&& n < after; tp = tp->tp_next)
@@ -3826,13 +3829,13 @@ int win_new_tabpage(int after, char_u *filename)
win_comp_scroll(curwin);
newtp->tp_topframe = topframe;
- last_status(FALSE);
+ last_status(false);
redraw_all_later(NOT_VALID);
- tabpage_check_windows(tp);
+ tabpage_check_windows(old_curtab);
- lastused_tabpage = tp;
+ lastused_tabpage = old_curtab;
apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf);
@@ -3842,8 +3845,8 @@ int win_new_tabpage(int after, char_u *filename)
return OK;
}
- /* Failed, get back the previous Tab page */
- enter_tabpage(curtab, curbuf, TRUE, TRUE);
+ // Failed, get back the previous Tab page
+ enter_tabpage(curtab, curbuf, true, true);
return FAIL;
}
diff --git a/test/functional/lua/treesitter_spec.lua b/test/functional/lua/treesitter_spec.lua
index fc4928eb71..f34cbbb65b 100644
--- a/test/functional/lua/treesitter_spec.lua
+++ b/test/functional/lua/treesitter_spec.lua
@@ -923,4 +923,25 @@ local hl_query = [[
end)
end)
+ describe("when getting the language for a range", function()
+ before_each(function()
+ insert([[
+int x = INT_MAX;
+#define VALUE 123456789
+ ]])
+ end)
+
+ it("should return the correct language tree", function()
+ local result = exec_lua([[
+ parser = vim.treesitter.get_parser(0, "c", {
+ queries = { c = "(preproc_def (preproc_arg) @c)"}})
+
+ local sub_tree = parser:language_for_range({1, 18, 1, 19})
+
+ return sub_tree == parser:children().c
+ ]])
+
+ eq(result, true)
+ end)
+ end)
end)
diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua
index 6601c2d68e..719e2ee82a 100644
--- a/test/functional/ui/multigrid_spec.lua
+++ b/test/functional/ui/multigrid_spec.lua
@@ -1562,6 +1562,77 @@ describe('ext_multigrid', function()
{1:~ }|
]]}
+ command('tabnext')
+ command('$tabnew')
+ screen:expect{grid=[[
+ ## grid 1
+ {16: }{17:2}{16: [No Name] }{17:2}{16: [No Name] }{7: [No Name] }{12: }{16:X}|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ [7:-----------------------------------------------------]|
+ {11:[No Name] }|
+ [3:-----------------------------------------------------]|
+ ## grid 2 (hidden)
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ## grid 3
+ |
+ ## grid 4 (hidden)
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ## grid 5 (hidden)
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ## grid 6 (hidden)
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ## grid 7
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]]}
+
+ command('tabclose')
command('tabclose')
screen:expect{grid=[[
## grid 1