aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAIN.md2
-rw-r--r--runtime/doc/builtin.txt1
-rw-r--r--runtime/doc/ft_rust.txt4
-rw-r--r--runtime/doc/lua.txt2
-rw-r--r--runtime/doc/nvim_terminal_emulator.txt2
-rw-r--r--runtime/lua/nvim/health.lua16
-rw-r--r--runtime/lua/vim/_editor.lua2
-rw-r--r--runtime/lua/vim/_meta/api.lua7
-rw-r--r--runtime/lua/vim/_meta/lpeg.lua328
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua1
-rw-r--r--runtime/lua/vim/_options.lua2
-rw-r--r--runtime/lua/vim/lsp/health.lua9
-rw-r--r--src/nvim/api/deprecated.c7
-rw-r--r--src/nvim/api/vim.c2
-rw-r--r--src/nvim/drawline.c28
-rw-r--r--src/nvim/drawscreen.c2
-rw-r--r--src/nvim/eval.lua2
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/ex_eval.c3
-rw-r--r--src/nvim/ex_eval_defs.h5
-rw-r--r--src/nvim/message.c19
-rw-r--r--test/functional/api/vim_spec.lua50
-rw-r--r--test/functional/ui/cmdline_spec.lua20
-rw-r--r--test/functional/vimscript/eval_spec.lua40
-rw-r--r--test/old/testdir/test_autocmd.vim13
-rw-r--r--test/old/testdir/test_compiler.vim11
-rw-r--r--test/old/testdir/test_listchars.vim203
-rw-r--r--test/old/testdir/test_syntax.vim6
-rw-r--r--test/old/testdir/test_virtualedit.vim20
29 files changed, 644 insertions, 165 deletions
diff --git a/MAINTAIN.md b/MAINTAIN.md
index 3e31fde118..f80f9b92fb 100644
--- a/MAINTAIN.md
+++ b/MAINTAIN.md
@@ -145,6 +145,8 @@ These dependencies are "vendored" (inlined), we must update the sources manually
* Run `scripts/update_terminfo.sh` to update these definitions.
* `runtime/lua/vim/lsp/_meta/protocol.lua`: LSP specification
* Run `scripts/gen_lsp.lua` to update.
+* `runtime/lua/vim/_meta/lpeg.lua`: LPeg definitions.
+ * Refer to [`LuaCATS/lpeg`](https://github.com/LuaCATS/lpeg) for updates.
* `src/bit.c`: only for PUC lua: port of `require'bit'` from luajit https://bitop.luajit.org/
* [treesitter parsers](https://github.com/neovim/neovim/blob/fcc24e43e0b5f9d801a01ff2b8f78ce8c16dd551/cmake.deps/CMakeLists.txt#L197-L210)
* `runtime/lua/coxpcall.lua`: coxpcall (only needed for PUC lua, builtin to luajit)
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 2dd290fef1..207bf817b0 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -7742,6 +7742,7 @@ strutf16len({string} [, {countcc}]) *strutf16len()*
echo strutf16len('😊') " returns 2
echo strutf16len('ą́') " returns 1
echo strutf16len('ą́', v:true) " returns 3
+<
strwidth({string}) *strwidth()*
The result is a Number, which is the number of display cells
diff --git a/runtime/doc/ft_rust.txt b/runtime/doc/ft_rust.txt
index b912f732b6..083b6f579f 100644
--- a/runtime/doc/ft_rust.txt
+++ b/runtime/doc/ft_rust.txt
@@ -467,8 +467,8 @@ rust.vim Debugging ~
register.
:RustInfoToFile [filename] *:RustInfoToFile*
- Saves debugging info of the Vim Rust plugin to the the given
- file, overwritting it.
+ Saves debugging info of the Vim Rust plugin to the given file,
+ overwriting it.
==============================================================================
MAPPINGS *rust-mappings*
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index a77cc3b565..7e888a2375 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -1680,7 +1680,7 @@ vim.print({...}) *vim.print()*
"Pretty prints" the given arguments and returns them unmodified.
Example: >lua
- local hl_normal = vim.print(vim.api.nvim_get_hl_by_name('Normal', true))
+ local hl_normal = vim.print(vim.api.nvim_get_hl(0, { name = 'Normal' }))
<
Return: ~
diff --git a/runtime/doc/nvim_terminal_emulator.txt b/runtime/doc/nvim_terminal_emulator.txt
index d0d535566d..0cfeb3dcb7 100644
--- a/runtime/doc/nvim_terminal_emulator.txt
+++ b/runtime/doc/nvim_terminal_emulator.txt
@@ -482,7 +482,7 @@ The function will be called with the list of arguments so far, and a second
argument that is the name of the pty.
*gdb-version*
Only debuggers fully compatible with gdb will work. Vim uses the GDB/MI
-interface. The "new-ui" command requires gdb version 7.12 or later. if you
+interface. The "new-ui" command requires gdb version 7.12 or later. If you
get this error:
Undefined command: "new-ui". Try "help".~
Then your gdb is too old.
diff --git a/runtime/lua/nvim/health.lua b/runtime/lua/nvim/health.lua
index 7ccb082a40..6b6370fa19 100644
--- a/runtime/lua/nvim/health.lua
+++ b/runtime/lua/nvim/health.lua
@@ -54,15 +54,19 @@ local function check_config()
health.start('Configuration')
local ok = true
- local vimrc = (
- empty(vim.env.MYVIMRC) and vim.fn.stdpath('config') .. '/init.vim' or vim.env.MYVIMRC
- )
- if not filereadable(vimrc) then
+ local init_lua = vim.fn.stdpath('config') .. '/init.lua'
+ local init_vim = vim.fn.stdpath('config') .. '/init.vim'
+ local vimrc = empty(vim.env.MYVIMRC) and init_lua or vim.env.MYVIMRC
+
+ if not filereadable(vimrc) and not filereadable(init_vim) then
ok = false
local has_vim = filereadable(vim.fn.expand('~/.vimrc'))
health.warn(
- (-1 == vim.fn.getfsize(vimrc) and 'Missing' or 'Unreadable') .. ' user config file: ' .. vimrc,
- { has_vim and ':help nvim-from-vim' or ':help init.vim' }
+ ('%s user config file: %s'):format(
+ -1 == vim.fn.getfsize(vimrc) and 'Missing' or 'Unreadable',
+ vimrc
+ ),
+ { has_vim and ':help nvim-from-vim' or ':help config' }
)
end
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index e4a2dadb09..7f09fc8038 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -888,7 +888,7 @@ end
--- Example:
---
--- ```lua
---- local hl_normal = vim.print(vim.api.nvim_get_hl_by_name('Normal', true))
+--- local hl_normal = vim.print(vim.api.nvim_get_hl(0, { name = 'Normal' }))
--- ```
---
--- @see |vim.inspect()|
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
index 81fa7ce7ec..5c51fbd146 100644
--- a/runtime/lua/vim/_meta/api.lua
+++ b/runtime/lua/vim/_meta/api.lua
@@ -425,6 +425,7 @@ function vim.api.nvim_buf_get_number(buffer) end
--- @return integer
function vim.api.nvim_buf_get_offset(buffer, index) end
+--- @deprecated
--- @param buffer integer
--- @param name string
--- @return any
@@ -632,6 +633,7 @@ function vim.api.nvim_buf_set_mark(buffer, name, line, col, opts) end
--- @param name string Buffer name
function vim.api.nvim_buf_set_name(buffer, name) end
+--- @deprecated
--- @param buffer integer
--- @param name string
--- @param value any
@@ -1283,10 +1285,12 @@ function vim.api.nvim_get_mode() end
--- @return table<string,any>
function vim.api.nvim_get_namespaces() end
+--- @deprecated
--- @param name string
--- @return any
function vim.api.nvim_get_option(name) end
+--- @deprecated
--- @param name string
--- @return table<string,any>
function vim.api.nvim_get_option_info(name) end
@@ -1912,6 +1916,7 @@ function vim.api.nvim_set_hl_ns_fast(ns_id) end
--- "callback" is equivalent to returning an empty string.
function vim.api.nvim_set_keymap(mode, lhs, rhs, opts) end
+--- @deprecated
--- @param name string
--- @param value any
function vim.api.nvim_set_option(name, value) end
@@ -2115,6 +2120,7 @@ function vim.api.nvim_win_get_height(window) end
--- @return integer
function vim.api.nvim_win_get_number(window) end
+--- @deprecated
--- @param window integer
--- @param name string
--- @return any
@@ -2197,6 +2203,7 @@ function vim.api.nvim_win_set_height(window, height) end
--- @param ns_id integer the namespace to use
function vim.api.nvim_win_set_hl_ns(window, ns_id) end
+--- @deprecated
--- @param window integer
--- @param name string
--- @param value any
diff --git a/runtime/lua/vim/_meta/lpeg.lua b/runtime/lua/vim/_meta/lpeg.lua
new file mode 100644
index 0000000000..415bffdfdc
--- /dev/null
+++ b/runtime/lua/vim/_meta/lpeg.lua
@@ -0,0 +1,328 @@
+--- @meta
+
+-- These types were taken from https://github.com/LuaCATS/lpeg, with types being renamed to include
+-- the vim namespace and with some descriptions made less verbose.
+
+--- *LPeg* is a new pattern-matching library for Lua, based on [Parsing Expression Grammars](https://bford.info/packrat/) (PEGs).
+vim.lpeg = {}
+
+--- @class vim.lpeg.Pattern
+--- @operator add(vim.lpeg.Pattern): vim.lpeg.Pattern
+--- @operator mul(vim.lpeg.Pattern): vim.lpeg.Pattern
+--- @operator mul(vim.lpeg.Capture): vim.lpeg.Pattern
+--- @operator div(string): vim.lpeg.Capture
+--- @operator div(number): vim.lpeg.Capture
+--- @operator div(table): vim.lpeg.Capture
+--- @operator div(function): vim.lpeg.Capture
+--- @operator pow(number): vim.lpeg.Pattern
+local Pattern = {}
+
+--- @alias vim.lpeg.Capture vim.lpeg.Pattern
+--- @operator add(vim.lpeg.Capture): vim.lpeg.Pattern
+--- @operator mul(vim.lpeg.Capture): vim.lpeg.Pattern
+--- @operator mul(vim.lpeg.Pattern): vim.lpeg.Pattern
+--- @operator div(string): vim.lpeg.Capture
+--- @operator div(number): vim.lpeg.Capture
+--- @operator div(table): vim.lpeg.Capture
+--- @operator div(function): vim.lpeg.Capture
+--- @operator pow(number): vim.lpeg.Pattern
+
+--- Matches the given `pattern` against the `subject` string. If the match succeeds, returns the index in the
+--- subject of the first character after the match, or the captured values (if the pattern captured any value).
+--- An optional numeric argument `init` makes the match start at that position in the subject string. As usual
+--- in Lua libraries, a negative value counts from the end. Unlike typical pattern-matching functions, `match`
+--- works only in anchored mode; that is, it tries to match the pattern with a prefix of the given subject
+--- string (at position `init`), not with an arbitrary substring of the subject. So, if we want to find a
+--- pattern anywhere in a string, we must either write a loop in Lua or write a pattern that
+--- matches anywhere.
+---
+--- Example:
+--- ```lua
+--- local pattern = lpeg.R("az") ^ 1 * -1
+--- assert(pattern:match("hello") == 6)
+--- assert(lpeg.match(pattern, "hello") == 6)
+--- assert(pattern:match("1 hello") == nil)
+--- ```
+---
+--- @param pattern vim.lpeg.Pattern
+--- @param subject string
+--- @param init? integer
+--- @return integer|vim.lpeg.Capture
+function vim.lpeg.match(pattern, subject, init) end
+
+--- Matches the given `pattern` against the `subject` string. If the match succeeds, returns the
+--- index in the subject of the first character after the match, or the captured values (if the
+--- pattern captured any value). An optional numeric argument `init` makes the match start at
+--- that position in the subject string. As usual in Lua libraries, a negative value counts from the end.
+--- Unlike typical pattern-matching functions, `match` works only in anchored mode; that is, it tries
+--- to match the pattern with a prefix of the given subject string (at position `init`), not with
+--- an arbitrary substring of the subject. So, if we want to find a pattern anywhere in a string,
+--- we must either write a loop in Lua or write a pattern that matches anywhere.
+---
+--- Example:
+--- ```lua
+--- local pattern = lpeg.R("az") ^ 1 * -1
+--- assert(pattern:match("hello") == 6)
+--- assert(lpeg.match(pattern, "hello") == 6)
+--- assert(pattern:match("1 hello") == nil)
+--- ```
+---
+--- @param subject string
+--- @param init? integer
+--- @return integer|vim.lpeg.Capture
+function Pattern:match(subject, init) end
+
+--- Returns the string `"pattern"` if the given value is a pattern, otherwise `nil`.
+---
+--- @return 'pattern'|nil
+function vim.lpeg.type(value) end
+
+--- Returns a string with the running version of LPeg.
+--- @return string
+function vim.lpeg.version() end
+
+--- Sets a limit for the size of the backtrack stack used by LPeg to track calls and choices.
+--- The default limit is `400`. Most well-written patterns need little backtrack levels and
+--- therefore you seldom need to change this limit; before changing it you should try to rewrite
+--- your pattern to avoid the need for extra space. Nevertheless, a few useful patterns may overflow.
+--- Also, with recursive grammars, subjects with deep recursion may also need larger limits.
+---
+--- @param max integer
+function vim.lpeg.setmaxstack(max) end
+
+--- Converts the given value into a proper pattern. This following rules are applied:
+--- * If the argument is a pattern, it is returned unmodified.
+--- * If the argument is a string, it is translated to a pattern that matches the string literally.
+--- * If the argument is a non-negative number `n`, the result is a pattern that matches exactly `n` characters.
+--- * If the argument is a negative number `-n`, the result is a pattern that succeeds only if
+--- the input string has less than `n` characters left: `lpeg.P(-n)` is equivalent to `-lpeg.P(n)`
+--- (see the unary minus operation).
+--- * If the argument is a boolean, the result is a pattern that always succeeds or always fails
+--- (according to the boolean value), without consuming any input.
+--- * If the argument is a table, it is interpreted as a grammar (see Grammars).
+--- * If the argument is a function, returns a pattern equivalent to a match-time captureover the empty string.
+---
+--- @param value vim.lpeg.Pattern|string|integer|boolean|table|function
+--- @return vim.lpeg.Pattern
+function vim.lpeg.P(value) end
+
+--- Returns a pattern that matches only if the input string at the current position is preceded by `patt`.
+--- Pattern `patt` must match only strings with some fixed length, and it cannot contain captures.
+--- Like the and predicate, this pattern never consumes any input, independently of success or failure.
+---
+--- @param pattern vim.lpeg.Pattern
+--- @return vim.lpeg.Pattern
+function vim.lpeg.B(pattern) end
+
+--- Returns a pattern that matches any single character belonging to one of the given ranges.
+--- Each `range` is a string `xy` of length 2, representing all characters with code between the codes of
+--- `x` and `y` (both inclusive). As an example, the pattern `lpeg.R("09")` matches any digit, and
+--- `lpeg.R("az", "AZ")` matches any ASCII letter.
+---
+--- Example:
+--- ```lua
+--- local pattern = lpeg.R("az") ^ 1 * -1
+--- assert(pattern:match("hello") == 6)
+--- ```
+---
+--- @param ... string
+--- @return vim.lpeg.Pattern
+function vim.lpeg.R(...) end
+
+--- Returns a pattern that matches any single character that appears in the given string (the `S` stands for Set).
+--- As an example, the pattern `lpeg.S("+-*/")` matches any arithmetic operator. Note that, if `s` is a character
+--- (that is, a string of length 1), then `lpeg.P(s)` is equivalent to `lpeg.S(s)` which is equivalent to
+--- `lpeg.R(s..s)`. Note also that both `lpeg.S("")` and `lpeg.R()` are patterns that always fail.
+---
+--- @param string string
+--- @return vim.lpeg.Pattern
+function vim.lpeg.S(string) end
+
+--- Creates a non-terminal (a variable) for a grammar. This operation creates a non-terminal (a variable)
+--- for a grammar. The created non-terminal refers to the rule indexed by `v` in the enclosing grammar.
+---
+--- Example:
+--- ```lua
+--- local b = lpeg.P({"(" * ((1 - lpeg.S "()") + lpeg.V(1)) ^ 0 * ")"})
+--- assert(b:match('((string))') == 11)
+--- assert(b:match('(') == nil)
+--- ```
+---
+--- @param v string|integer
+--- @return vim.lpeg.Pattern
+function vim.lpeg.V(v) end
+
+--- @class vim.lpeg.Locale
+--- @field alnum userdata
+--- @field alpha userdata
+--- @field cntrl userdata
+--- @field digit userdata
+--- @field graph userdata
+--- @field lower userdata
+--- @field print userdata
+--- @field punct userdata
+--- @field space userdata
+--- @field upper userdata
+--- @field xdigit userdata
+
+--- Returns a table with patterns for matching some character classes according to the current locale.
+--- The table has fields named `alnum`, `alpha`, `cntrl`, `digit`, `graph`, `lower`, `print`, `punct`,
+--- `space`, `upper`, and `xdigit`, each one containing a correspondent pattern. Each pattern matches
+--- any single character that belongs to its class.
+--- If called with an argument `table`, then it creates those fields inside the given table and returns
+--- that table.
+---
+--- Example:
+--- ```lua
+--- lpeg.locale(lpeg)
+--- local space = lpeg.space^0
+--- local name = lpeg.C(lpeg.alpha^1) * space
+--- local sep = lpeg.S(",;") * space
+--- local pair = lpeg.Cg(name * "=" * space * name) * sep^-1
+--- local list = lpeg.Cf(lpeg.Ct("") * pair^0, rawset)
+--- local t = list:match("a=b, c = hi; next = pi")
+--- assert(t.a == 'b')
+--- assert(t.c == 'hi')
+--- assert(t.next == 'pi')
+--- local locale = lpeg.locale()
+--- assert(type(locale.digit) == 'userdata')
+--- ```
+---
+--- @param tab? table
+--- @return vim.lpeg.Locale
+function vim.lpeg.locale(tab) end
+
+--- Creates a simple capture, which captures the substring of the subject that matches `patt`.
+--- The captured value is a string. If `patt` has other captures, their values are returned after this one.
+---
+--- Example:
+--- ```lua
+--- local function split (s, sep)
+--- sep = lpeg.P(sep)
+--- local elem = lpeg.C((1 - sep)^0)
+--- local p = elem * (sep * elem)^0
+--- return lpeg.match(p, s)
+--- end
+--- local a, b, c = split('a,b,c', ',')
+--- assert(a == 'a')
+--- assert(b == 'b')
+--- assert(c == 'c')
+--- ```
+---
+--- @param patt vim.lpeg.Pattern
+--- @return vim.lpeg.Capture
+function vim.lpeg.C(patt) end
+
+--- Creates an argument capture. This pattern matches the empty string and produces the value given as the
+--- nth extra argument given in the call to `lpeg.match`.
+--- @param n integer
+--- @return vim.lpeg.Capture
+function vim.lpeg.Carg(n) end
+
+--- Creates a back capture. This pattern matches the empty string and produces the values produced by the most recent
+--- group capture named `name` (where `name` can be any Lua value). Most recent means the last complete outermost
+--- group capture with the given name. A Complete capture means that the entire pattern corresponding to the capture
+--- has matched. An Outermost capture means that the capture is not inside another complete capture.
+--- In the same way that LPeg does not specify when it evaluates captures, it does not specify whether it reuses
+--- values previously produced by the group or re-evaluates them.
+---
+--- @param name any
+--- @return vim.lpeg.Capture
+function vim.lpeg.Cb(name) end
+
+--- Creates a constant capture. This pattern matches the empty string and produces all given values as its captured values.
+---
+--- @param ... any
+--- @return vim.lpeg.Capture
+function vim.lpeg.Cc(...) end
+
+--- Creates a fold capture. If `patt` produces a list of captures C1 C2 ... Cn, this capture will produce the value
+--- `func(...func(func(C1, C2), C3)...,Cn)`, that is, it will fold (or accumulate, or reduce) the captures from
+--- `patt` using function `func`. This capture assumes that `patt` should produce at least one capture with at
+--- least one value (of any type), which becomes the initial value of an accumulator. (If you need a specific
+--- initial value, you may prefix a constant captureto `patt`.) For each subsequent capture, LPeg calls `func`
+--- with this accumulator as the first argument and all values produced by the capture as extra arguments;
+--- the first result from this call becomes the new value for the accumulator. The final value of the accumulator
+--- becomes the captured value.
+---
+--- Example:
+--- ```lua
+--- local number = lpeg.R("09") ^ 1 / tonumber
+--- local list = number * ("," * number) ^ 0
+--- local function add(acc, newvalue) return acc + newvalue end
+--- local sum = lpeg.Cf(list, add)
+--- assert(sum:match("10,30,43") == 83)
+--- ```
+---
+--- @param patt vim.lpeg.Pattern
+--- @param func fun(acc, newvalue)
+--- @return vim.lpeg.Capture
+function vim.lpeg.Cf(patt, func) end
+
+--- Creates a group capture. It groups all values returned by `patt` into a single capture.
+--- The group may be anonymous (if no name is given) or named with the given name (which
+--- can be any non-nil Lua value).
+---
+--- @param patt vim.lpeg.Pattern
+--- @param name? string
+--- @return vim.lpeg.Capture
+function vim.lpeg.Cg(patt, name) end
+
+--- Creates a position capture. It matches the empty string and captures the position in the
+--- subject where the match occurs. The captured value is a number.
+---
+--- Example:
+--- ```lua
+--- local I = lpeg.Cp()
+--- local function anywhere(p) return lpeg.P({I * p * I + 1 * lpeg.V(1)}) end
+--- local match_start, match_end = anywhere("world"):match("hello world!")
+--- assert(match_start == 7)
+--- assert(match_end == 12)
+--- ```
+---
+--- @return vim.lpeg.Capture
+function vim.lpeg.Cp() end
+
+--- Creates a substitution capture. This function creates a substitution capture, which
+--- captures the substring of the subject that matches `patt`, with substitutions.
+--- For any capture inside `patt` with a value, the substring that matched the capture
+--- is replaced by the capture value (which should be a string). The final captured
+--- value is the string resulting from all replacements.
+---
+--- Example:
+--- ```lua
+--- local function gsub (s, patt, repl)
+--- patt = lpeg.P(patt)
+--- patt = lpeg.Cs((patt / repl + 1)^0)
+--- return lpeg.match(patt, s)
+--- end
+--- assert(gsub('Hello, xxx!', 'xxx', 'World') == 'Hello, World!')
+--- ```
+---
+--- @param patt vim.lpeg.Pattern
+--- @return vim.lpeg.Capture
+function vim.lpeg.Cs(patt) end
+
+--- Creates a table capture. This capture returns a table with all values from all anonymous captures
+--- made by `patt` inside this table in successive integer keys, starting at 1.
+--- Moreover, for each named capture group created by `patt`, the first value of the group is put into
+--- the table with the group name as its key. The captured value is only the table.
+---
+--- @param patt vim.lpeg.Pattern|''
+--- @return vim.lpeg.Capture
+function vim.lpeg.Ct(patt) end
+
+--- Creates a match-time capture. Unlike all other captures, this one is evaluated immediately when a match occurs
+--- (even if it is part of a larger pattern that fails later). It forces the immediate evaluation of all its nested captures
+--- and then calls `function`. The given function gets as arguments the entire subject, the current position
+--- (after the match of `patt`), plus any capture values produced by `patt`. The first value returned by `function`
+--- defines how the match happens. If the call returns a number, the match succeeds and the returned number
+--- becomes the new current position. (Assuming a subject sand current position i, the returned number must be
+--- in the range [i, len(s) + 1].) If the call returns true, the match succeeds without consuming any input
+--- (so, to return true is equivalent to return i). If the call returns false, nil, or no value, the match fails.
+--- Any extra values returned by the function become the values produced by the capture.
+---
+--- @param patt vim.lpeg.Pattern
+--- @param fn function
+--- @return vim.lpeg.Capture
+function vim.lpeg.Cmt(patt, fn) end
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index 4113797759..6686661a27 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -9192,6 +9192,7 @@ function vim.fn.strtrans(string) end
--- echo strutf16len('😊') " returns 2
--- echo strutf16len('ą́') " returns 1
--- echo strutf16len('ą́', v:true) " returns 3
+--- <
---
--- @param string string
--- @param countcc? 0|1
diff --git a/runtime/lua/vim/_options.lua b/runtime/lua/vim/_options.lua
index 6a3413b597..b83a8dd4b1 100644
--- a/runtime/lua/vim/_options.lua
+++ b/runtime/lua/vim/_options.lua
@@ -127,7 +127,7 @@ end
--- @param name string
local function get_options_info(name)
- local info = api.nvim_get_option_info(name)
+ local info = api.nvim_get_option_info2(name, {})
info.metatype = get_option_metatype(name, info)
return info
end
diff --git a/runtime/lua/vim/lsp/health.lua b/runtime/lua/vim/lsp/health.lua
index 023b1c26be..fe06006108 100644
--- a/runtime/lua/vim/lsp/health.lua
+++ b/runtime/lua/vim/lsp/health.lua
@@ -32,8 +32,15 @@ function M.check()
vim.health.start('vim.lsp: Active Clients')
if next(clients) then
for _, client in pairs(clients) do
+ local attached_to = table.concat(vim.tbl_keys(client.attached_buffers or {}), ',')
report_info(
- string.format('%s (id=%s, root_dir=%s)', client.name, client.id, client.config.root_dir)
+ string.format(
+ '%s (id=%s, root_dir=%s, attached_to=[%s])',
+ client.name,
+ client.id,
+ vim.fn.fnamemodify(client.config.root_dir, ':~'),
+ attached_to
+ )
)
end
else
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
index f5a77ece7e..f345edc52c 100644
--- a/src/nvim/api/deprecated.c
+++ b/src/nvim/api/deprecated.c
@@ -518,6 +518,7 @@ static int64_t convert_index(int64_t index)
/// @return Option Information
Dictionary nvim_get_option_info(String name, Error *err)
FUNC_API_SINCE(7)
+ FUNC_API_DEPRECATED_SINCE(11)
{
return get_vimoption(name, OPT_GLOBAL, curbuf, curwin, err);
}
@@ -531,6 +532,7 @@ Dictionary nvim_get_option_info(String name, Error *err)
/// @param[out] err Error details, if any
void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err)
FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(11)
{
set_option_to(channel_id, NULL, SREQ_GLOBAL, name, value, err);
}
@@ -543,6 +545,7 @@ void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err)
/// @return Option value (global)
Object nvim_get_option(String name, Arena *arena, Error *err)
FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(11)
{
return get_option_from(NULL, SREQ_GLOBAL, name, err);
}
@@ -556,6 +559,7 @@ Object nvim_get_option(String name, Arena *arena, Error *err)
/// @return Option value
Object nvim_buf_get_option(Buffer buffer, String name, Arena *arena, Error *err)
FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(11)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -577,6 +581,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Arena *arena, Error *err)
/// @param[out] err Error details, if any
void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object value, Error *err)
FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(11)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -596,6 +601,7 @@ void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object
/// @return Option value
Object nvim_win_get_option(Window window, String name, Arena *arena, Error *err)
FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(11)
{
win_T *win = find_window_by_handle(window, err);
@@ -617,6 +623,7 @@ Object nvim_win_get_option(Window window, String name, Arena *arena, Error *err)
/// @param[out] err Error details, if any
void nvim_win_set_option(uint64_t channel_id, Window window, String name, Object value, Error *err)
FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(11)
{
win_T *win = find_window_by_handle(window, err);
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 7a5c7cc181..78396edef5 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1709,6 +1709,8 @@ static void write_msg(String message, bool to_err, bool writeln)
msg_didout = true; \
kv_drop(line_buf, kv_size(line_buf)); \
kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \
+ } else if (c == NUL) { \
+ kv_push(line_buf, NL); \
} else { \
kv_push(line_buf, c); \
}
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 7d64d9fa3c..1e5798db32 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -1539,6 +1539,25 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
cts.cts_vcol += charsize;
prev_ptr = cts.cts_ptr;
MB_PTR_ADV(cts.cts_ptr);
+ if (wp->w_p_list) {
+ in_multispace = *prev_ptr == ' ' && (*cts.cts_ptr == ' '
+ || (prev_ptr > line && prev_ptr[-1] == ' '));
+ if (!in_multispace) {
+ multispace_pos = 0;
+ } else if (cts.cts_ptr >= line + leadcol
+ && wp->w_p_lcs_chars.multispace != NULL) {
+ multispace_pos++;
+ if (wp->w_p_lcs_chars.multispace[multispace_pos] == NUL) {
+ multispace_pos = 0;
+ }
+ } else if (cts.cts_ptr < line + leadcol
+ && wp->w_p_lcs_chars.leadmultispace != NULL) {
+ multispace_pos++;
+ if (wp->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) {
+ multispace_pos = 0;
+ }
+ }
+ }
}
wlv.vcol = cts.cts_vcol;
ptr = cts.cts_ptr;
@@ -2367,9 +2386,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
}
- in_multispace = c == ' ' && ((ptr > line + 1 && ptr[-2] == ' ') || *ptr == ' ');
- if (!in_multispace) {
- multispace_pos = 0;
+ if (wp->w_p_list) {
+ in_multispace = c == ' ' && (*ptr == ' '
+ || (prev_ptr > line && prev_ptr[-1] == ' '));
+ if (!in_multispace) {
+ multispace_pos = 0;
+ }
}
// 'list': Change char 160 to 'nbsp' and space to 'space'.
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index ee1f03e296..04918e9979 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -471,7 +471,7 @@ int update_screen(void)
// non-displayed part of msg_grid is considered invalid.
for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.rows); i++) {
grid_clear_line(&msg_grid, msg_grid.line_offset[i],
- msg_grid.cols, false);
+ msg_grid.cols, i < p_ch);
}
}
msg_grid.throttled = false;
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index fe816ee8c2..858f7c8afd 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -10973,7 +10973,7 @@ M.funcs = {
echo strutf16len('😊') " returns 2
echo strutf16len('ą́') " returns 1
echo strutf16len('ą́', v:true) " returns 3
-
+ <
]=],
name = 'strutf16len',
params = { { 'string', 'string' }, { 'countcc', '0|1' } },
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 0a0f7c244d..ea93d0fe91 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -906,7 +906,7 @@ void handle_did_throw(void)
if (messages != NULL) {
do {
msglist_T *next = messages->next;
- emsg(messages->msg);
+ emsg_multiline(messages->msg, messages->multiline);
xfree(messages->msg);
xfree(messages->sfile);
xfree(messages);
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 1b150ef75d..0704b47d40 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -157,7 +157,7 @@ int aborted_in_try(void)
/// When several messages appear in the same command, the first is usually the
/// most specific one and used as the exception value. The "severe" flag can be
/// set to true, if a later but severer message should be used instead.
-bool cause_errthrow(const char *mesg, bool severe, bool *ignore)
+bool cause_errthrow(const char *mesg, bool multiline, bool severe, bool *ignore)
FUNC_ATTR_NONNULL_ALL
{
msglist_T *elem;
@@ -249,6 +249,7 @@ bool cause_errthrow(const char *mesg, bool severe, bool *ignore)
elem = xmalloc(sizeof(msglist_T));
elem->msg = xstrdup(mesg);
+ elem->multiline = multiline;
elem->next = NULL;
elem->throw_msg = NULL;
*plist = elem;
diff --git a/src/nvim/ex_eval_defs.h b/src/nvim/ex_eval_defs.h
index 6b3c426722..3ad3368900 100644
--- a/src/nvim/ex_eval_defs.h
+++ b/src/nvim/ex_eval_defs.h
@@ -1,6 +1,8 @@
#ifndef NVIM_EX_EVAL_DEFS_H
#define NVIM_EX_EVAL_DEFS_H
+#include <stdbool.h>
+
#include "nvim/pos.h"
/// There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if"
@@ -41,11 +43,12 @@ enum {
/// message in the list. See cause_errthrow().
typedef struct msglist msglist_T;
struct msglist {
+ msglist_T *next; ///< next of several messages in a row
char *msg; ///< original message, allocated
char *throw_msg; ///< msg to throw: usually original one
char *sfile; ///< value from estack_sfile(), allocated
linenr_T slnum; ///< line number for "sfile"
- msglist_T *next; ///< next of several messages in a row
+ bool multiline; ///< whether this is a multiline message
};
/// The exception types.
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 98e5a231b8..dba4dba600 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -640,7 +640,7 @@ int emsg_not_now(void)
return false;
}
-static bool emsg_multiline(const char *s, bool multiline)
+bool emsg_multiline(const char *s, bool multiline)
{
int attr;
bool ignore = false;
@@ -663,7 +663,7 @@ static bool emsg_multiline(const char *s, bool multiline)
// be found, the message will be displayed later on.) "ignore" is set
// when the message should be ignored completely (used for the
// interrupt message).
- if (cause_errthrow(s, severe, &ignore)) {
+ if (cause_errthrow(s, multiline, severe, &ignore)) {
if (!ignore) {
did_emsg++;
}
@@ -1907,10 +1907,13 @@ void msg_prt_line(const char *s, int list)
continue;
} else {
attr = 0;
- c = (unsigned char)(*s++);
- in_multispace = c == ' ' && ((col > 0 && s[-2] == ' ') || *s == ' ');
- if (!in_multispace) {
- multispace_pos = 0;
+ c = (uint8_t)(*s++);
+ if (list) {
+ in_multispace = c == ' ' && (*s == ' '
+ || (col > 0 && s[-2] == ' '));
+ if (!in_multispace) {
+ multispace_pos = 0;
+ }
}
if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) {
// tab amount depends on current column
@@ -1950,7 +1953,7 @@ void msg_prt_line(const char *s, int list)
// the same in plain text.
attr = HL_ATTR(HLF_0);
} else if (c == ' ') {
- if (list && lead != NULL && s <= lead && in_multispace
+ if (lead != NULL && s <= lead && in_multispace
&& curwin->w_p_lcs_chars.leadmultispace != NULL) {
c = curwin->w_p_lcs_chars.leadmultispace[multispace_pos++];
if (curwin->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) {
@@ -1963,7 +1966,7 @@ void msg_prt_line(const char *s, int list)
} else if (trail != NULL && s > trail) {
c = curwin->w_p_lcs_chars.trail;
attr = HL_ATTR(HLF_0);
- } else if (list && in_multispace
+ } else if (in_multispace
&& curwin->w_p_lcs_chars.multispace != NULL) {
c = curwin->w_p_lcs_chars.multispace[multispace_pos++];
if (curwin->w_p_lcs_chars.multispace[multispace_pos] == NUL) {
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index d82e5f66c9..09495fbaac 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -2053,6 +2053,19 @@ describe('API', function()
end)
describe('nvim_out_write', function()
+ local screen
+
+ before_each(function()
+ screen = Screen.new(40, 8)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue},
+ [1] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [2] = {bold = true, reverse = true},
+ [3] = {foreground = Screen.colors.Blue},
+ })
+ end)
+
it('prints long messages correctly #20534', function()
exec([[
set more
@@ -2073,14 +2086,7 @@ describe('API', function()
eq('\naaa\n' .. ('a'):rep(5002) .. '\naaa', meths.get_var('out'))
end)
- it('blank line in message works', function()
- local screen = Screen.new(40, 8)
- screen:attach()
- screen:set_default_attr_ids({
- [0] = {bold = true, foreground = Screen.colors.Blue},
- [1] = {bold = true, foreground = Screen.colors.SeaGreen},
- [2] = {bold = true, reverse = true},
- })
+ it('blank line in message', function()
feed([[:call nvim_out_write("\na\n")<CR>]])
screen:expect{grid=[[
|
@@ -2105,6 +2111,20 @@ describe('API', function()
{1:Press ENTER or type command to continue}^ |
]]}
end)
+
+ it('NUL bytes in message', function()
+ feed([[:lua vim.api.nvim_out_write('aaa\0bbb\0\0ccc\nddd\0\0\0eee\n')<CR>]])
+ screen:expect{grid=[[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2: }|
+ aaa{3:^@}bbb{3:^@^@}ccc |
+ ddd{3:^@^@^@}eee |
+ {1:Press ENTER or type command to continue}^ |
+ ]]}
+ end)
end)
describe('nvim_err_write', function()
@@ -2193,6 +2213,20 @@ describe('API', function()
]])
feed('<cr>') -- exit the press ENTER screen
end)
+
+ it('NUL bytes in message', function()
+ nvim_async('err_write', 'aaa\0bbb\0\0ccc\nddd\0\0\0eee\n')
+ screen:expect{grid=[[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {3: }|
+ {1:aaa^@bbb^@^@ccc} |
+ {1:ddd^@^@^@eee} |
+ {2:Press ENTER or type command to continue}^ |
+ ]]}
+ end)
end)
describe('nvim_err_writeln', function()
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 6baad28dad..497b2e7f4c 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -1021,6 +1021,26 @@ describe('cmdheight=0', function()
screen:attach()
end)
+ it("with redrawdebug=invalid resize -1", function()
+ command("set redrawdebug=invalid cmdheight=0 noruler laststatus=0")
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]]}
+ feed(":resize -1<CR>")
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ assert_alive()
+ end)
+
it("with cmdheight=1 noruler laststatus=2", function()
command("set cmdheight=1 noruler laststatus=2")
screen:expect{grid=[[
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua
index b3f2c1bfeb..ab0ffccd4d 100644
--- a/test/functional/vimscript/eval_spec.lua
+++ b/test/functional/vimscript/eval_spec.lua
@@ -153,11 +153,6 @@ end)
describe("uncaught exception", function()
before_each(clear)
- after_each(function()
- os.remove('throw1.vim')
- os.remove('throw2.vim')
- os.remove('throw3.vim')
- end)
it('is not forgotten #13490', function()
command('autocmd BufWinEnter * throw "i am error"')
@@ -173,10 +168,45 @@ describe("uncaught exception", function()
let result ..= 'X'
]]):format(i, i))
end
+ finally(function()
+ for i = 1, 3 do
+ os.remove('throw' .. i .. '.vim')
+ end
+ end)
+
command('set runtimepath+=. | let result = ""')
eq('throw1', exc_exec('try | runtime! throw*.vim | endtry'))
eq('123', eval('result'))
end)
+
+ it('multiline exception remains multiline #25350', function()
+ local screen = Screen.new(80, 11)
+ screen:set_default_attr_ids({
+ [1] = {bold = true, reverse = true}; -- MsgSeparator
+ [2] = {foreground = Screen.colors.White, background = Screen.colors.Red}; -- ErrorMsg
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg
+ })
+ screen:attach()
+ exec_lua([[
+ function _G.Oops()
+ error("oops")
+ end
+ ]])
+ feed(':try\rlua _G.Oops()\rendtry\r')
+ screen:expect{grid=[[
+ {1: }|
+ :try |
+ : lua _G.Oops() |
+ : endtry |
+ {2:Error detected while processing :} |
+ {2:E5108: Error executing lua [string "<nvim>"]:2: oops} |
+ {2:stack traceback:} |
+ {2: [C]: in function 'error'} |
+ {2: [string "<nvim>"]:2: in function 'Oops'} |
+ {2: [string ":lua"]:1: in main chunk} |
+ {3:Press ENTER or type command to continue}^ |
+ ]]}
+ end)
end)
describe('listing functions using :function', function()
diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim
index 9da20e662e..453ac10c00 100644
--- a/test/old/testdir/test_autocmd.vim
+++ b/test/old/testdir/test_autocmd.vim
@@ -3442,11 +3442,22 @@ func Test_closing_autocmd_window()
END
call CheckScriptFailure(lines, 'E814:')
au! BufEnter
- only!
bwipe Xa.txt
bwipe Xb.txt
endfunc
+func Test_switch_window_in_autocmd_window()
+ edit Xa.txt
+ tabnew Xb.txt
+ autocmd BufEnter Xa.txt wincmd w
+ doautoall BufEnter
+ au! BufEnter
+ bwipe Xa.txt
+ call assert_false(bufexists('Xa.txt'))
+ bwipe Xb.txt
+ call assert_false(bufexists('Xb.txt'))
+endfunc
+
func Test_bufwipeout_changes_window()
" This should not crash, but we don't have any expectations about what
" happens, changing window in BufWipeout has unpredictable results.
diff --git a/test/old/testdir/test_compiler.vim b/test/old/testdir/test_compiler.vim
index ec7d143030..0b22bafabb 100644
--- a/test/old/testdir/test_compiler.vim
+++ b/test/old/testdir/test_compiler.vim
@@ -7,10 +7,8 @@ func Test_compiler()
CheckExecutable perl
CheckFeature quickfix
- " $LANG changes the output of Perl.
- if $LANG != ''
- unlet $LANG
- endif
+ let save_LC_ALL = $LC_ALL
+ let $LC_ALL= "C"
" %:S does not work properly with 'shellslash' set
let save_shellslash = &shellslash
@@ -40,12 +38,13 @@ func Test_compiler()
let &shellslash = save_shellslash
call delete('Xfoo.pl')
bw!
+ let $LC_ALL = save_LC_ALL
endfunc
func GetCompilerNames()
return glob('$VIMRUNTIME/compiler/*.vim', 0, 1)
- \ ->map({i, v -> substitute(v, '.*[\\/]\([a-zA-Z0-9_\-]*\).vim', '\1', '')})
- \ ->sort()
+ \ ->map({i, v -> substitute(v, '.*[\\/]\([a-zA-Z0-9_\-]*\).vim', '\1', '')})
+ \ ->sort()
endfunc
func Test_compiler_without_arg()
diff --git a/test/old/testdir/test_listchars.vim b/test/old/testdir/test_listchars.vim
index 69f1df3098..5366f503fc 100644
--- a/test/old/testdir/test_listchars.vim
+++ b/test/old/testdir/test_listchars.vim
@@ -4,6 +4,36 @@ source check.vim
source view_util.vim
source screendump.vim
+func Check_listchars(expected, end_lnum, end_scol = -1, leftcol = 0)
+ if a:leftcol > 0
+ let save_wrap = &wrap
+ set nowrap
+ call cursor(1, 1)
+ exe 'normal! ' .. a:leftcol .. 'zl'
+ endif
+
+ redraw!
+ for i in range(1, a:end_lnum)
+ if a:leftcol > 0
+ let col = virtcol2col(0, i, a:leftcol)
+ let col += getline(i)->strpart(col - 1, 1, v:true)->len()
+ call cursor(i, col)
+ redraw
+ call assert_equal(a:leftcol, winsaveview().leftcol)
+ else
+ call cursor(i, 1)
+ end
+
+ let end_scol = a:end_scol < 0 ? '$'->virtcol() - a:leftcol : a:end_scol
+ call assert_equal([a:expected[i - 1]->strcharpart(a:leftcol)],
+ \ ScreenLines(i, end_scol))
+ endfor
+
+ if a:leftcol > 0
+ let &wrap = save_wrap
+ endif
+endfunc
+
func Test_listchars()
enew!
set ff=unix
@@ -24,11 +54,8 @@ func Test_listchars()
\ 'dd........ee<<>-$',
\ '<$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, '$'->virtcol()))
- endfor
+ call Check_listchars(expected, 5)
+ call Check_listchars(expected, 4, -1, 5)
set listchars-=trail:<
let expected = [
@@ -38,11 +65,8 @@ func Test_listchars()
\ 'dd........ee..>-$',
\ '.$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
+ call Check_listchars(expected, 5)
+ call Check_listchars(expected, 4, -1, 5)
" tab with 3rd character.
set listchars-=tab:>-
@@ -54,11 +78,8 @@ func Test_listchars()
\ 'dd........ee--<>$',
\ '-$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
+ call Check_listchars(expected, 5)
+ call Check_listchars(expected, 4, -1, 5)
" tab with 3rd character and linebreak set
set listchars-=tab:<=>
@@ -71,11 +92,7 @@ func Test_listchars()
\ 'dd........ee--<>$',
\ '-$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
+ call Check_listchars(expected, 5)
set nolinebreak
set listchars-=tab:<·>
set listchars+=tab:<=>
@@ -88,11 +105,8 @@ func Test_listchars()
\ 'dd........ee..<>$',
\ '.$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
+ call Check_listchars(expected, 5)
+ call Check_listchars(expected, 4, -1, 5)
set listchars-=tab:<=>
set listchars+=tab:>-
@@ -110,7 +124,8 @@ func Test_listchars()
\ '..fff>--<<$',
\ '>-------gg>-----$',
\ '.....h>-$',
- \ 'iii<<<<><<$', '$'], l)
+ \ 'iii<<<<><<$',
+ \ '$'], l)
" Test lead and trail
normal ggdG
@@ -132,14 +147,10 @@ func Test_listchars()
\ 'h<<<<<<<<<<<$',
\ '<<<<<<<<<<<<$',
\ '>>>>0xx0<<<<$',
- \ '$'
+ \ '$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
-
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
" Test multispace
@@ -162,14 +173,10 @@ func Test_listchars()
\ ' hyYzZyYzZyY$',
\ 'yYzZyYzZyYj $',
\ 'yYzZ0yY0yYzZ$',
- \ '$'
+ \ '$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
-
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
" Test leadmultispace + multispace
@@ -192,15 +199,14 @@ func Test_listchars()
\ ' hyYzZyYzZyY$',
\ '.-+*.-+*.-j $',
\ '.-+*0yY0yYzZ$',
- \ '$'
+ \ '$'
\ ]
- redraw!
call assert_equal('eol:$,multispace:yYzZ,nbsp:S,leadmultispace:.-+*', &listchars)
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
-
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 1)
+ call Check_listchars(expected, 5, -1, 2)
+ call Check_listchars(expected, 5, -1, 3)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
" Test leadmultispace without multispace
@@ -223,16 +229,14 @@ func Test_listchars()
\ '+h>>>>>>>>>>$',
\ '.-+*.-+*.-j>$',
\ '.-+*0++0>>>>$',
- \ '$',
+ \ '$'
\ ]
-
- redraw!
call assert_equal('eol:$,nbsp:S,leadmultispace:.-+*,space:+,trail:>,eol:$', &listchars)
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
-
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 1)
+ call Check_listchars(expected, 5, -1, 2)
+ call Check_listchars(expected, 5, -1, 3)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
" Test leadmultispace only
@@ -255,14 +259,10 @@ func Test_listchars()
\ ' h ',
\ '.-+*.-+*.-j ',
\ '.-+*0 0 ',
- \ ' ',
+ \ ' '
\ ]
- redraw!
call assert_equal('leadmultispace:.-+*', &listchars)
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, 12))
- endfor
+ call Check_listchars(expected, 5, 12)
call assert_equal(expected, split(execute("%list"), "\n"))
" Test leadmultispace and lead and space
@@ -286,14 +286,14 @@ func Test_listchars()
\ '<h----------$',
\ '.-+*.-+*.-j-$',
\ '.-+*0--0----$',
- \ '$',
+ \ '$'
\ ]
- redraw!
call assert_equal('eol:$,lead:<,space:-,leadmultispace:.-+*', &listchars)
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 1)
+ call Check_listchars(expected, 5, -1, 2)
+ call Check_listchars(expected, 5, -1, 3)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
" the last occurrence of 'multispace:' is used
@@ -307,15 +307,11 @@ func Test_listchars()
\ 'xhXyYXyYXyYX$',
\ 'XyYXyYXyYXjx$',
\ 'XyYX0Xy0XyYX$',
- \ '$'
+ \ '$'
\ ]
- redraw!
call assert_equal('eol:$,multispace:yYzZ,space:x,multispace:XyY', &listchars)
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
-
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
set listchars+=lead:>,trail:<
@@ -326,14 +322,10 @@ func Test_listchars()
\ '>h<<<<<<<<<<$',
\ '>>>>>>>>>>j<$',
\ '>>>>0Xy0<<<<$',
- \ '$'
+ \ '$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
-
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
" removing 'multispace:'
@@ -346,14 +338,10 @@ func Test_listchars()
\ '>h<<<<<<<<<<$',
\ '>>>>>>>>>>j<$',
\ '>>>>0xx0<<<<$',
- \ '$'
+ \ '$'
\ ]
- redraw!
- for i in range(1, 5)
- call cursor(i, 1)
- call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
- endfor
-
+ call Check_listchars(expected, 6)
+ call Check_listchars(expected, 5, -1, 6)
call assert_equal(expected, split(execute("%list"), "\n"))
" test nbsp
@@ -365,15 +353,10 @@ func Test_listchars()
call append(0, [ ">" .. nbsp .. "<" ])
let expected = '>X< '
-
- redraw!
- call cursor(1, 1)
- call assert_equal([expected], ScreenLines(1, virtcol('$')))
+ call Check_listchars([expected], 1)
set listchars=nbsp:X
- redraw!
- call cursor(1, 1)
- call assert_equal([expected], ScreenLines(1, virtcol('$')))
+ call Check_listchars([expected], 1)
" test extends
normal ggdG
@@ -383,16 +366,11 @@ func Test_listchars()
call append(0, [ repeat('A', &columns + 1) ])
let expected = repeat('A', &columns)
-
- redraw!
- call cursor(1, 1)
- call assert_equal([expected], ScreenLines(1, &columns))
+ call Check_listchars([expected], 1, &columns)
set list
let expected = expected[:-2] . 'Z'
- redraw!
- call cursor(1, 1)
- call assert_equal([expected], ScreenLines(1, &columns))
+ call Check_listchars([expected], 1, &columns)
enew!
set listchars& ff&
@@ -411,19 +389,20 @@ func Test_listchars_unicode()
let nbsp = nr2char(0xa0)
call append(0, [" a\tb c" .. nbsp .. "d "])
let expected = ['≡≢≣≡≢≣≡≢a←↔↔↔↔↔→b␣c≠d≡≢⇔']
- redraw!
- call cursor(1, 1)
- call assert_equal(expected, ScreenLines(1, virtcol('$')))
+ call Check_listchars(expected, 1)
+ call Check_listchars(expected, 1, -1, 3)
+ call Check_listchars(expected, 1, -1, 13)
set listchars=eol:\\u21d4,space:\\u2423,multispace:≡\\u2262\\U00002263,nbsp:\\U00002260,tab:←↔\\u2192
- redraw!
- call assert_equal(expected, ScreenLines(1, virtcol('$')))
+ call Check_listchars(expected, 1)
+ call Check_listchars(expected, 1, -1, 3)
+ call Check_listchars(expected, 1, -1, 13)
set listchars+=lead:⇨,trail:⇦
let expected = ['⇨⇨⇨⇨⇨⇨⇨⇨a←↔↔↔↔↔→b␣c≠d⇦⇦⇔']
- redraw!
- call cursor(1, 1)
- call assert_equal(expected, ScreenLines(1, virtcol('$')))
+ call Check_listchars(expected, 1)
+ call Check_listchars(expected, 1, -1, 3)
+ call Check_listchars(expected, 1, -1, 13)
let &encoding=oldencoding
enew!
@@ -515,9 +494,7 @@ func Test_listchars_composing()
let expected = [
\ "_ \u3099^I \u309A=" .. nbsp1 .. "\u0302=" .. nbsp2 .. "\u0302$"
\ ]
- redraw!
- call cursor(1, 1)
- call assert_equal(expected, ScreenLines(1, virtcol('$')))
+ call Check_listchars(expected, 1)
let &encoding=oldencoding
enew!
set listchars& ff&
diff --git a/test/old/testdir/test_syntax.vim b/test/old/testdir/test_syntax.vim
index c9ad4bb857..76a21adc57 100644
--- a/test/old/testdir/test_syntax.vim
+++ b/test/old/testdir/test_syntax.vim
@@ -41,9 +41,9 @@ func AssertHighlightGroups(lnum, startcol, expected, trans = 1, msg = "")
for l:i in range(a:startcol, a:startcol + l:expectedGroups->len() - 1)
let l:errors += synID(a:lnum, l:i, a:trans)
- \ ->synIDattr("name")
- \ ->assert_equal(l:expectedGroups[l:i - 1],
- \ l:msg .. l:i)
+ \ ->synIDattr("name")
+ \ ->assert_equal(l:expectedGroups[l:i - 1],
+ \ l:msg .. l:i)
endfor
endfunc
diff --git a/test/old/testdir/test_virtualedit.vim b/test/old/testdir/test_virtualedit.vim
index 4ab69d89fe..4780faa706 100644
--- a/test/old/testdir/test_virtualedit.vim
+++ b/test/old/testdir/test_virtualedit.vim
@@ -598,6 +598,9 @@ func Test_virtualedit_mouse()
call Ntest_setmouse(row, 21 + 15)
call feedkeys("\<LeftMouse>", "xt")
call assert_equal([0, 1, 10, 2, 15], getcurpos())
+ call Ntest_setmouse(row, 21 + 20)
+ call feedkeys("\<LeftMouse>", "xt")
+ call assert_equal([0, 1, 10, 7, 20], getcurpos())
setlocal nowrap
call setline(2, repeat('a', 19))
@@ -654,6 +657,23 @@ func Test_virtualedit_mouse()
sign undefine Sign1
endif
+ wincmd h
+ 4wincmd >
+ normal! gg24I.
+ redraw
+ call Ntest_setmouse(row + 1, 12)
+ call feedkeys("\<LeftMouse>", "xt")
+ call assert_equal([0, 1, 24 + 9, 0, 24 + 12], getcurpos())
+ call Ntest_setmouse(row + 1, 13)
+ call feedkeys("\<LeftMouse>", "xt")
+ call assert_equal([0, 1, 24 + 10, 0, 24 + 13], getcurpos())
+ call Ntest_setmouse(row + 1, 15)
+ call feedkeys("\<LeftMouse>", "xt")
+ call assert_equal([0, 1, 24 + 10, 2, 24 + 15], getcurpos())
+ call Ntest_setmouse(row + 1, 20)
+ call feedkeys("\<LeftMouse>", "xt")
+ call assert_equal([0, 1, 24 + 10, 7, 24 + 20], getcurpos())
+
bwipe!
let &mouse = save_mouse
set virtualedit&