aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/release.yml4
-rw-r--r--contrib/flake.nix95
-rw-r--r--runtime/doc/lsp.txt69
-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/language.lua16
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua31
-rw-r--r--src/nvim/main.c5
-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--test/functional/lua/treesitter_spec.lua4
17 files changed, 268 insertions, 50 deletions
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2acd615da1..d7f9556028 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,9 +12,10 @@ on:
tags:
- v[0-9]+.[0-9]+.[0-9]+
+# Build on the oldest supported images, so we have broader compatibility
jobs:
linux:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-16.04
outputs:
version: ${{ steps.build.outputs.version }}
release: ${{ steps.build.outputs.release }}
@@ -42,7 +43,6 @@ jobs:
retention-days: 1
appimage:
- # Build on the oldest supported image, so we have broader compatibility
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v2
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/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/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/language.lua b/runtime/lua/vim/treesitter/language.lua
index a7e36a0b89..d60cd2d0c7 100644
--- a/runtime/lua/vim/treesitter/language.lua
+++ b/runtime/lua/vim/treesitter/language.lua
@@ -8,7 +8,8 @@ local M = {}
--
-- @param lang The language the parser should parse
-- @param path Optionnal path the parser is located at
-function M.require_language(lang, path)
+-- @param silent Don't throw an error if language not found
+function M.require_language(lang, path, silent)
if vim._ts_has_language(lang) then
return true
end
@@ -16,12 +17,23 @@ function M.require_language(lang, path)
local fname = 'parser/' .. lang .. '.*'
local paths = a.nvim_get_runtime_file(fname, false)
if #paths == 0 then
+ if silent then
+ return false
+ end
+
-- TODO(bfredl): help tag?
error("no parser for '"..lang.."' language, see :help treesitter-parsers")
end
path = paths[1]
end
- vim._ts_add_language(path, lang)
+
+ if silent then
+ return pcall(function() vim._ts_add_language(path, lang) end)
+ else
+ vim._ts_add_language(path, lang)
+ end
+
+ return true
end
--- Inspects the provided language.
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 885460c9fd..04b5fee256 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -121,23 +121,30 @@ function LanguageTree:parse()
local seen_langs = {}
for lang, injection_ranges in pairs(injections_by_lang) do
- local child = self._children[lang]
+ local has_lang = language.require_language(lang, nil, true)
- if not child then
- child = self:add_child(lang)
- end
+ -- Child language trees should just be ignored if not found, since
+ -- they can depend on the text of a node. Intermediate strings
+ -- would cause errors for unknown parsers.
+ if has_lang then
+ local child = self._children[lang]
- child:set_included_regions(injection_ranges)
+ if not child then
+ child = self:add_child(lang)
+ end
- local _, child_changes = child:parse()
+ child:set_included_regions(injection_ranges)
- -- Propagate any child changes so they are included in the
- -- the change list for the callback.
- if child_changes then
- vim.list_extend(changes, child_changes)
- end
+ local _, child_changes = child:parse()
- seen_langs[lang] = true
+ -- Propagate any child changes so they are included in the
+ -- the change list for the callback.
+ if child_changes then
+ vim.list_extend(changes, child_changes)
+ end
+
+ seen_langs[lang] = true
+ end
end
for lang, _ in pairs(self._children) do
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/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/test/functional/lua/treesitter_spec.lua b/test/functional/lua/treesitter_spec.lua
index 0e823426ae..f34cbbb65b 100644
--- a/test/functional/lua/treesitter_spec.lua
+++ b/test/functional/lua/treesitter_spec.lua
@@ -22,6 +22,10 @@ describe('treesitter API', function()
matches("Error executing lua: Failed to load parser: uv_dlopen: .+",
pcall_err(exec_lua, "parser = vim.treesitter.require_language('borklang', 'borkbork.so')"))
+ -- Should not throw an error when silent
+ eq(false, exec_lua("return vim.treesitter.require_language('borklang', nil, true)"))
+ eq(false, exec_lua("return vim.treesitter.require_language('borklang', 'borkbork.so', true)"))
+
eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "parser = vim.treesitter.inspect_language('borklang')"))
end)