diff options
-rw-r--r-- | INSTALL.md | 25 | ||||
-rw-r--r-- | runtime/doc/lsp.txt | 1 | ||||
-rw-r--r-- | runtime/doc/treesitter.txt | 31 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/diagnostic.lua | 52 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/_meta.lua | 23 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/highlighter.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/query.lua | 91 | ||||
-rw-r--r-- | src/nvim/change.c | 19 | ||||
-rw-r--r-- | src/nvim/drawscreen.c | 15 | ||||
-rw-r--r-- | src/nvim/lua/treesitter.c | 8 | ||||
-rw-r--r-- | test/functional/legacy/number_spec.lua | 306 | ||||
-rw-r--r-- | test/functional/plugin/lsp/diagnostic_spec.lua | 8 | ||||
-rw-r--r-- | test/functional/ui/highlight_spec.lua | 249 | ||||
-rw-r--r-- | test/old/testdir/test_highlight.vim | 20 | ||||
-rw-r--r-- | test/old/testdir/test_number.vim | 33 |
15 files changed, 517 insertions, 366 deletions
diff --git a/INSTALL.md b/INSTALL.md index 8ca3ab7a13..9bba1f0a8c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -93,6 +93,20 @@ The [Releases](https://github.com/neovim/neovim/releases) page provides pre-buil ## Linux +### Pre-built archives + +The [Releases](https://github.com/neovim/neovim/releases) page provides pre-built binaries for Linux systems. + +```sh +curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz +sudo rm -rf /opt/nvim +sudo tar -C /opt -xzf nvim-linux64.tar.gz +``` + +After this step add this to `~/.bashrc`: + + export PATH="$PATH:/opt/nvim-linux64/bin" + ### AppImage ("universal" Linux package) The [Releases](https://github.com/neovim/neovim/releases) page provides an [AppImage](https://appimage.org) that runs on most Linux systems. No installation is needed, just download `nvim.appimage` and run it. (It might not work if your Linux distribution is more than 4 years old.) @@ -101,6 +115,15 @@ The [Releases](https://github.com/neovim/neovim/releases) page provides an [AppI chmod u+x nvim.appimage ./nvim.appimage +To expose nvim globally: + + mkdir -p /opt/nvim + mv nvim.appimage /opt/nvim/nvim + +And the following line to `~/.bashrc`: + + export PATH="$PATH:/opt/nvim/" + If the `./nvim.appimage` command fails, try: ```sh ./nvim.appimage --appimage-extract @@ -111,7 +134,7 @@ sudo mv squashfs-root / sudo ln -s /squashfs-root/AppRun /usr/bin/nvim nvim ``` - + ### Arch Linux Neovim can be installed from the community repository: diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index ad1b838578..dd3ef9cbc8 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1384,6 +1384,7 @@ on_diagnostic({_}, {result}, {ctx}, {config}) < Parameters: ~ + • {result} (`lsp.DocumentDiagnosticReport`) • {ctx} (`lsp.HandlerContext`) • {config} (`table`) Configuration table (see |vim.diagnostic.config()|). diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index 2755cd421b..f6ee2ef425 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -976,7 +976,8 @@ get({lang}, {query_name}) *vim.treesitter.query.get()* • {query_name} (`string`) Name of the query (e.g. "highlights") Return: ~ - (`Query?`) Parsed query + (`vim.treesitter.Query?`) Parsed query. `nil` if no query files are + found. *vim.treesitter.query.get_files()* get_files({lang}, {query_name}, {is_included}) @@ -1040,12 +1041,12 @@ parse({lang}, {query}) *vim.treesitter.query.parse()* read the contents into a string before calling). Returns a `Query` (see |lua-treesitter-query|) object which can be used to - search nodes in the syntax tree for the patterns defined in {query} using `iter_*` methods - below. + search nodes in the syntax tree for the patterns defined in {query} using + the `iter_captures` and `iter_matches` methods. Exposes `info` and `captures` with additional context about {query}. • `captures` contains the list of unique capture names defined in {query}. - -`info.captures` also points to `captures`. + • `info.captures` also points to `captures`. • `info.patterns` contains information about predicates. Parameters: ~ @@ -1053,7 +1054,10 @@ parse({lang}, {query}) *vim.treesitter.query.parse()* • {query} (`string`) Query in s-expr syntax Return: ~ - (`Query`) Parsed query + (`vim.treesitter.Query`) Parsed query + + See also: ~ + • |vim.treesitter.query.get()| *Query:iter_captures()* Query:iter_captures({node}, {source}, {start}, {stop}) @@ -1082,8 +1086,10 @@ Query:iter_captures({node}, {source}, {start}, {stop}) • {node} (`TSNode`) under which the search will occur • {source} (`integer|string`) Source buffer or string to extract text from - • {start} (`integer`) Starting line for the search - • {stop} (`integer`) Stopping line for the search (end-exclusive) + • {start} (`integer?`) Starting line for the search. Defaults to + `node:start()`. + • {stop} (`integer?`) Stopping line for the search (end-exclusive). + Defaults to `node:end_()`. Return: ~ (`fun(end_line: integer?): integer, TSNode, TSMetadata`) capture id, @@ -1115,13 +1121,14 @@ Query:iter_matches({node}, {source}, {start}, {stop}, {opts}) Parameters: ~ • {node} (`TSNode`) under which the search will occur • {source} (`integer|string`) Source buffer or string to search - • {start} (`integer`) Starting line for the search - • {stop} (`integer`) Stopping line for the search (end-exclusive) - • {opts} (`table?`) Options: + • {start} (`integer?`) Starting line for the search. Defaults to + `node:start()`. + • {stop} (`integer?`) Stopping line for the search (end-exclusive). + Defaults to `node:end_()`. + • {opts} (`table?`) Optional keyword arguments: • max_start_depth (integer) if non-zero, sets the maximum start depth for each match. This is used to prevent - traversing too deep into a tree. Requires treesitter >= - 0.20.9. + traversing too deep into a tree. Return: ~ (`fun(): integer, table<integer,TSNode>, table`) pattern id, match, diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index aa812fa78c..3a4064a1e4 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -221,6 +221,13 @@ function M.get_namespace(client_id, is_pull) end end +local function convert_severity(opt) + if type(opt) == 'table' and not opt.severity and opt.severity_limit then + vim.deprecate('severity_limit', '{min = severity} See vim.diagnostic.severity', '0.11') + opt.severity = { min = severity_lsp_to_vim(opt.severity_limit) } + end +end + --- |lsp-handler| for the method "textDocument/publishDiagnostics" --- --- See |vim.diagnostic.config()| for configuration options. Handler-specific @@ -267,13 +274,8 @@ function M.on_publish_diagnostics(_, result, ctx, config) if config then for _, opt in pairs(config) do - if type(opt) == 'table' then - if not opt.severity and opt.severity_limit then - opt.severity = { min = severity_lsp_to_vim(opt.severity_limit) } - end - end + convert_severity(opt) end - -- Persist configuration to ensure buffer reloads use the same -- configuration. To make lsp.with configuration work (See :help -- lsp-handler-configuration) @@ -308,11 +310,14 @@ end --- ) --- ``` --- +---@param result lsp.DocumentDiagnosticReport ---@param ctx lsp.HandlerContext ---@param config table Configuration table (see |vim.diagnostic.config()|). function M.on_diagnostic(_, result, ctx, config) local client_id = ctx.client_id - local uri = ctx.params.textDocument.uri + --- @type lsp.DocumentDiagnosticParams + local params = ctx.params + local uri = params.textDocument.uri local fname = vim.uri_to_fname(uri) if result == nil then @@ -339,11 +344,8 @@ function M.on_diagnostic(_, result, ctx, config) if config then for _, opt in pairs(config) do - if type(opt) == 'table' and not opt.severity and opt.severity_limit then - opt.severity = { min = severity_lsp_to_vim(opt.severity_limit) } - end + convert_severity(opt) end - -- Persist configuration to ensure buffer reloads use the same -- configuration. To make lsp.with configuration work (See :help -- lsp-handler-configuration) @@ -381,34 +383,28 @@ end --- ---@param bufnr integer|nil The buffer number ---@param line_nr integer|nil The line number ----@param opts table|nil Configuration keys ---- - severity: (DiagnosticSeverity, default nil) ---- - Only return diagnostics with this severity. Overrides severity_limit ---- - severity_limit: (DiagnosticSeverity, default nil) ---- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid. +---@param opts {severity?:lsp.DiagnosticSeverity}? +--- - severity: (lsp.DiagnosticSeverity) +--- - Only return diagnostics with this severity. ---@param client_id integer|nil the client id ---@return table Table with map of line number to list of diagnostics. --- Structured: { [1] = {...}, [5] = {.... } } ---@private function M.get_line_diagnostics(bufnr, line_nr, opts, client_id) - opts = opts or {} - if opts.severity then - opts.severity = severity_lsp_to_vim(opts.severity) - elseif opts.severity_limit then - opts.severity = { min = severity_lsp_to_vim(opts.severity_limit) } - end + convert_severity(opts) + local diag_opts = {} --- @type vim.diagnostic.GetOpts - if client_id then - opts.namespace = M.get_namespace(client_id, false) + if opts and opts.severity then + diag_opts.severity = severity_lsp_to_vim(opts.severity) end - if not line_nr then - line_nr = vim.api.nvim_win_get_cursor(0)[1] - 1 + if client_id then + diag_opts.namespace = M.get_namespace(client_id, false) end - opts.lnum = line_nr + diag_opts.lnum = line_nr or (api.nvim_win_get_cursor(0)[1] - 1) - return diagnostic_vim_to_lsp(vim.diagnostic.get(bufnr, opts)) + return diagnostic_vim_to_lsp(vim.diagnostic.get(bufnr, diag_opts)) end --- Clear diagnostics from pull based clients diff --git a/runtime/lua/vim/treesitter/_meta.lua b/runtime/lua/vim/treesitter/_meta.lua index 80c998b555..6a714de052 100644 --- a/runtime/lua/vim/treesitter/_meta.lua +++ b/runtime/lua/vim/treesitter/_meta.lua @@ -1,4 +1,5 @@ ---@meta +error('Cannot require a meta file') ---@class TSNode: userdata ---@field id fun(self: TSNode): string @@ -33,7 +34,7 @@ ---@field byte_length fun(self: TSNode): integer local TSNode = {} ----@param query userdata +---@param query TSQuery ---@param captures true ---@param start? integer ---@param end_? integer @@ -41,17 +42,17 @@ local TSNode = {} ---@return fun(): integer, TSNode, any function TSNode:_rawquery(query, captures, start, end_, opts) end ----@param query userdata +---@param query TSQuery ---@param captures false ---@param start? integer ---@param end_? integer ---@param opts? table ----@return fun(): string, any +---@return fun(): integer, any function TSNode:_rawquery(query, captures, start, end_, opts) end ---@alias TSLoggerCallback fun(logtype: 'parse'|'lex', msg: string) ----@class TSParser +---@class TSParser: userdata ---@field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: true): TSTree, Range6[] ---@field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: false|nil): TSTree, Range4[] ---@field reset fun(self: TSParser) @@ -62,19 +63,31 @@ function TSNode:_rawquery(query, captures, start, end_, opts) end ---@field _set_logger fun(self: TSParser, lex: boolean, parse: boolean, cb: TSLoggerCallback) ---@field _logger fun(self: TSParser): TSLoggerCallback ----@class TSTree +---@class TSTree: userdata ---@field root fun(self: TSTree): TSNode ---@field edit fun(self: TSTree, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _:integer) ---@field copy fun(self: TSTree): TSTree ---@field included_ranges fun(self: TSTree, include_bytes: true): Range6[] ---@field included_ranges fun(self: TSTree, include_bytes: false): Range4[] +---@class TSQuery: userdata +---@field inspect fun(self: TSQuery): TSQueryInfo + +---@class (exact) TSQueryInfo +---@field captures string[] +---@field patterns table<integer, (integer|string)[][]> + ---@return integer vim._ts_get_language_version = function() end ---@return integer vim._ts_get_minimum_language_version = function() end +---@param lang string Language to use for the query +---@param query string Query string in s-expr syntax +---@return TSQuery +vim._ts_parse_query = function(lang, query) end + ---@param lang string ---@return TSParser vim._create_ts_parser = function(lang) end diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index 84d40322fe..08c4c2a832 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -7,7 +7,7 @@ local ns = api.nvim_create_namespace('treesitter/highlighter') ---@alias vim.treesitter.highlighter.Iter fun(end_line: integer|nil): integer, TSNode, TSMetadata ---@class vim.treesitter.highlighter.Query ----@field private _query Query? +---@field private _query vim.treesitter.query.Query? ---@field private lang string ---@field private hl_cache table<integer,integer> local TSHighlighterQuery = {} diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 63d4a9382a..cd65c0d7f6 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -1,18 +1,48 @@ local api = vim.api local language = require('vim.treesitter.language') ----@class Query ----@field captures string[] List of captures used in query ----@field info TSQueryInfo Contains used queries, predicates, directives ----@field query userdata Parsed query +local M = {} + +---Parsed query, see |vim.treesitter.query.parse()| +--- +---@class vim.treesitter.Query +---@field lang string name of the language for this parser +---@field captures string[] list of (unique) capture names defined in query +---@field info vim.treesitter.QueryInfo contains information used in the query (e.g. captures, predicates, directives) +---@field query TSQuery userdata query object local Query = {} Query.__index = Query ----@class TSQueryInfo ----@field captures table ----@field patterns table<string,any[][]> +---@package +---@see vim.treesitter.query.parse +---@param lang string +---@param ts_query TSQuery +---@return vim.treesitter.Query +function Query.new(lang, ts_query) + local self = setmetatable({}, Query) + local query_info = ts_query:inspect() ---@type TSQueryInfo + self.query = ts_query + self.lang = lang + self.info = { + captures = query_info.captures, + patterns = query_info.patterns, + } + self.captures = self.info.captures + return self +end -local M = {} +---Information for Query, see |vim.treesitter.query.parse()| +---@class vim.treesitter.QueryInfo +--- +---List of (unique) capture names defined in query. +---@field captures string[] +--- +---Contains information about predicates and directives. +---Key is pattern id, and value is list of predicates or directives defined in the pattern. +---A predicate or directive is a list of (integer|string); integer represents `capture_id`, and +---string represents (literal) arguments to predicate/directive. See |treesitter-predicates| +---and |treesitter-directives| for more details. +---@field patterns table<integer, (integer|string)[][]> ---@param files string[] ---@return string[] @@ -162,7 +192,7 @@ local function read_query_files(filenames) end -- The explicitly set queries from |vim.treesitter.query.set()| ----@type table<string,table<string,Query>> +---@type table<string,table<string,vim.treesitter.Query>> local explicit_queries = setmetatable({}, { __index = function(t, k) local lang_queries = {} @@ -201,7 +231,7 @@ end ---@param lang string Language to use for the query ---@param query_name string Name of the query (e.g. "highlights") --- ----@return Query|nil Parsed query +---@return vim.treesitter.Query|nil -- Parsed query. `nil` if no query files are found. M.get = vim.func._memoize('concat-2', function(lang, query_name) if explicit_queries[lang][query_name] then return explicit_queries[lang][query_name] @@ -228,26 +258,24 @@ end --- --- Returns a `Query` (see |lua-treesitter-query|) object which can be used to --- search nodes in the syntax tree for the patterns defined in {query} ---- using `iter_*` methods below. +--- using the `iter_captures` and `iter_matches` methods. --- --- Exposes `info` and `captures` with additional context about {query}. ---- - `captures` contains the list of unique capture names defined in ---- {query}. ---- -` info.captures` also points to `captures`. +--- - `captures` contains the list of unique capture names defined in {query}. +--- - `info.captures` also points to `captures`. --- - `info.patterns` contains information about predicates. --- ---@param lang string Language to use for the query ---@param query string Query in s-expr syntax --- ----@return Query Parsed query +---@return vim.treesitter.Query Parsed query +--- +---@see |vim.treesitter.query.get()| M.parse = vim.func._memoize('concat-2', function(lang, query) language.add(lang) - local self = setmetatable({}, Query) - self.query = vim._ts_parse_query(lang, query) - self.info = self.query:inspect() - self.captures = self.info.captures - return self + local ts_query = vim._ts_parse_query(lang, query) + return Query.new(lang, ts_query) end) ---@deprecated @@ -644,14 +672,16 @@ end --- Returns the start and stop value if set else the node's range. -- When the node's range is used, the stop is incremented by 1 -- to make the search inclusive. ----@param start integer ----@param stop integer +---@param start integer|nil +---@param stop integer|nil ---@param node TSNode ---@return integer, integer local function value_or_node_range(start, stop, node) - if start == nil and stop == nil then - local node_start, _, node_stop, _ = node:range() - return node_start, node_stop + 1 -- Make stop inclusive + if start == nil then + start = node:start() + end + if stop == nil then + stop = node:end_() + 1 -- Make stop inclusive end return start, stop @@ -682,8 +712,8 @@ end --- ---@param node TSNode under which the search will occur ---@param source (integer|string) Source buffer or string to extract text from ----@param start integer Starting line for the search ----@param stop integer Stopping line for the search (end-exclusive) +---@param start? integer Starting line for the search. Defaults to `node:start()`. +---@param stop? integer Stopping line for the search (end-exclusive). Defaults to `node:end_()`. --- ---@return (fun(end_line: integer|nil): integer, TSNode, TSMetadata): --- capture id, capture node, metadata @@ -741,12 +771,11 @@ end --- ---@param node TSNode under which the search will occur ---@param source (integer|string) Source buffer or string to search ----@param start integer Starting line for the search ----@param stop integer Stopping line for the search (end-exclusive) ----@param opts table|nil Options: +---@param start? integer Starting line for the search. Defaults to `node:start()`. +---@param stop? integer Stopping line for the search (end-exclusive). Defaults to `node:end_()`. +---@param opts? table Optional keyword arguments: --- - max_start_depth (integer) if non-zero, sets the maximum start depth --- for each match. This is used to prevent traversing too deep into a tree. ---- Requires treesitter >= 0.20.9. --- ---@return (fun(): integer, table<integer,TSNode>, table): pattern id, match, metadata function Query:iter_matches(node, source, start, stop, opts) diff --git a/src/nvim/change.c b/src/nvim/change.c index fa098a3220..e0b5822233 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -353,20 +353,19 @@ static void changed_common(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnum } // If lines have been added or removed, relative numbering always - // requires a redraw. + // requires an update even if cursor didn't move. if (wp->w_p_rnu && xtra != 0) { wp->w_last_cursor_lnum_rnu = 0; - redraw_later(wp, UPD_VALID); } - // Cursor line highlighting probably need to be updated with - // "UPD_VALID" if it's below the change. - // If the cursor line is inside the change we need to redraw more. - if (wp->w_p_cul) { - if (xtra == 0) { - redraw_later(wp, UPD_VALID); - } else if (lnum <= wp->w_last_cursorline) { - redraw_later(wp, UPD_SOME_VALID); + if (wp->w_p_cul && wp->w_last_cursorline >= lnum) { + if (wp->w_last_cursorline < lnume) { + // If 'cursorline' was inside the change, it has already + // been invalidated in w_lines[] by the loop above. + wp->w_last_cursorline = 0; + } else { + // If 'cursorline' was below the change, adjust its lnum. + wp->w_last_cursorline += xtra; } } } diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index f23c0a0fd3..3d048d178e 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1643,12 +1643,6 @@ static void win_update(win_T *wp) top_end = 1; } } - - // When line numbers are displayed need to redraw all lines below - // inserted/deleted lines. - if (mod_top != 0 && buf->b_mod_xlines != 0 && wp->w_p_nu) { - mod_bot = MAXLNUM; - } } wp->w_redraw_top = 0; // reset for next time @@ -2326,9 +2320,12 @@ static void win_update(win_T *wp) idx++; lnum += foldinfo.fi_lines + 1; } else { - if (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum) { - // 'relativenumber' set and cursor moved vertically: The - // text doesn't need to be drawn, but the number column does. + // If: + // - 'number' is set and below inserted/deleted lines, or + // - 'relativenumber' is set and cursor moved vertically, + // the text doesn't need to be redrawn, but the number column does. + if ((wp->w_p_nu && mod_top != 0 && lnum >= mod_bot && buf->b_mod_xlines != 0) + || (wp->w_p_rnu && wp->w_last_cursor_lnum_rnu != wp->w_cursor.lnum)) { foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum ? cursorline_fi : fold_info(wp, lnum); win_line(wp, lnum, srow, wp->w_grid.rows, wp->w_lines[idx].wl_size, &spv, info); diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index de17aabca2..c1816a8860 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -56,6 +56,7 @@ typedef struct { # include "lua/treesitter.c.generated.h" #endif +// TSParser static struct luaL_Reg parser_meta[] = { { "__gc", parser_gc }, { "__tostring", parser_tostring }, @@ -70,6 +71,7 @@ static struct luaL_Reg parser_meta[] = { { NULL, NULL } }; +// TSTree static struct luaL_Reg tree_meta[] = { { "__gc", tree_gc }, { "__tostring", tree_tostring }, @@ -80,6 +82,7 @@ static struct luaL_Reg tree_meta[] = { { NULL, NULL } }; +// TSNode static struct luaL_Reg node_meta[] = { { "__tostring", node_tostring }, { "__eq", node_eq }, @@ -119,6 +122,7 @@ static struct luaL_Reg node_meta[] = { { NULL, NULL } }; +// TSQuery static struct luaL_Reg query_meta[] = { { "__gc", query_gc }, { "__tostring", query_tostring }, @@ -1649,8 +1653,10 @@ static int query_inspect(lua_State *L) return 0; } - uint32_t n_pat = ts_query_pattern_count(query); + // TSQueryInfo lua_createtable(L, 0, 2); // [retval] + + uint32_t n_pat = ts_query_pattern_count(query); lua_createtable(L, (int)n_pat, 1); // [retval, patterns] for (size_t i = 0; i < n_pat; i++) { uint32_t len; diff --git a/test/functional/legacy/number_spec.lua b/test/functional/legacy/number_spec.lua new file mode 100644 index 0000000000..c112532eed --- /dev/null +++ b/test/functional/legacy/number_spec.lua @@ -0,0 +1,306 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') +local clear = helpers.clear +local command = helpers.command +local exec = helpers.exec +local feed = helpers.feed + +describe("'number' and 'relativenumber'", function() + before_each(clear) + + -- oldtest: Test_relativenumber_colors() + it('LineNr, LineNrAbove and LineNrBelow', function() + local screen = Screen.new(50, 10) + screen:set_default_attr_ids({ + [1] = { foreground = Screen.colors.Red }, + [2] = { foreground = Screen.colors.Blue }, + [3] = { foreground = Screen.colors.Green }, + }) + screen:attach() + exec([[ + call setline(1, range(200)) + 111 + set number relativenumber + hi LineNr guifg=red + ]]) + screen:expect([[ + {1: 4 }106 | + {1: 3 }107 | + {1: 2 }108 | + {1: 1 }109 | + {1:111 }^110 | + {1: 1 }111 | + {1: 2 }112 | + {1: 3 }113 | + {1: 4 }114 | + | + ]]) + command('hi LineNrAbove guifg=blue') + screen:expect([[ + {2: 4 }106 | + {2: 3 }107 | + {2: 2 }108 | + {2: 1 }109 | + {1:111 }^110 | + {1: 1 }111 | + {1: 2 }112 | + {1: 3 }113 | + {1: 4 }114 | + | + ]]) + command('hi LineNrBelow guifg=green') + screen:expect([[ + {2: 4 }106 | + {2: 3 }107 | + {2: 2 }108 | + {2: 1 }109 | + {1:111 }^110 | + {3: 1 }111 | + {3: 2 }112 | + {3: 3 }113 | + {3: 4 }114 | + | + ]]) + command('hi clear LineNrAbove') + screen:expect([[ + {1: 4 }106 | + {1: 3 }107 | + {1: 2 }108 | + {1: 1 }109 | + {1:111 }^110 | + {3: 1 }111 | + {3: 2 }112 | + {3: 3 }113 | + {3: 4 }114 | + | + ]]) + end) + + -- oldtest: Test_relativenumber_colors_wrapped() + it('LineNr, LineNrAbove and LineNrBelow with wrapped lines', function() + local screen = Screen.new(50, 20) + screen:set_default_attr_ids({ + [1] = { background = Screen.colors.Red, foreground = Screen.colors.Black }, + [2] = { background = Screen.colors.Blue, foreground = Screen.colors.Black }, + [3] = { background = Screen.colors.Green, foreground = Screen.colors.Black }, + [4] = { bold = true, foreground = Screen.colors.Blue }, + }) + screen:attach() + exec([[ + set display=lastline scrolloff=0 + call setline(1, range(200)->map('v:val->string()->repeat(40)')) + 111 + set number relativenumber + hi LineNr guibg=red guifg=black + hi LineNrAbove guibg=blue guifg=black + hi LineNrBelow guibg=green guifg=black + ]]) + screen:expect([[ + {2: 2 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 1 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {1:111 }^1101101101101101101101101101101101101101101101| + {1: }1011011011011011011011011011011011011011011011| + {1: }0110110110110110110110110110 | + {3: 1 }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111 | + {3: 2 }1121121121121121121121121121121121121121121121| + {3: }1211211211211211211211211211211211211211211211| + {3: }2112112112112112112112112112 | + {3: 3 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 4 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('k') + screen:expect([[ + {2: 1 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {1:110 }^1091091091091091091091091091091091091091091091| + {1: }0910910910910910910910910910910910910910910910| + {1: }9109109109109109109109109109 | + {3: 1 }1101101101101101101101101101101101101101101101| + {3: }1011011011011011011011011011011011011011011011| + {3: }0110110110110110110110110110 | + {3: 2 }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111 | + {3: 3 }1121121121121121121121121121121121121121121121| + {3: }1211211211211211211211211211211211211211211211| + {3: }2112112112112112112112112112 | + {3: 4 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 5 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('2j') + screen:expect([[ + {2: 3 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 2 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {2: 1 }1101101101101101101101101101101101101101101101| + {2: }1011011011011011011011011011011011011011011011| + {2: }0110110110110110110110110110 | + {1:112 }^1111111111111111111111111111111111111111111111| + {1: }1111111111111111111111111111111111111111111111| + {1: }1111111111111111111111111111 | + {3: 1 }1121121121121121121121121121121121121121121121| + {3: }1211211211211211211211211211211211211211211211| + {3: }2112112112112112112112112112 | + {3: 2 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 3 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('2j') + screen:expect([[ + {2: 5 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 4 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {2: 3 }1101101101101101101101101101101101101101101101| + {2: }1011011011011011011011011011011011011011011011| + {2: }0110110110110110110110110110 | + {2: 2 }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111 | + {2: 1 }1121121121121121121121121121121121121121121121| + {2: }1211211211211211211211211211211211211211211211| + {2: }2112112112112112112112112112 | + {1:114 }^1131131131131131131131131131131131131131131131| + {1: }1311311311311311311311311311311311311311311311| + {1: }3113113113113113113113113113 | + {3: 1 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('k') + screen:expect([[ + {2: 4 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 3 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {2: 2 }1101101101101101101101101101101101101101101101| + {2: }1011011011011011011011011011011011011011011011| + {2: }0110110110110110110110110110 | + {2: 1 }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111 | + {1:113 }^1121121121121121121121121121121121121121121121| + {1: }1211211211211211211211211211211211211211211211| + {1: }2112112112112112112112112112 | + {3: 1 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 2 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + end) + + -- oldtest: Test_relativenumber_callback() + it('relative line numbers are updated if cursor is moved from timer', function() + local screen = Screen.new(50, 8) + screen:set_default_attr_ids({ + [1] = { foreground = Screen.colors.Brown }, -- LineNr + [2] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText + }) + screen:attach() + exec([[ + call setline(1, ['aaaaa', 'bbbbb', 'ccccc', 'ddddd']) + set relativenumber + call cursor(4, 1) + + func Func(timer) + call cursor(1, 1) + endfunc + + call timer_start(300, 'Func') + ]]) + screen:expect({ + grid = [[ + {1: 3 }aaaaa | + {1: 2 }bbbbb | + {1: 1 }ccccc | + {1: 0 }^ddddd | + {2:~ }|*3 + | + ]], + timeout = 100, + }) + screen:expect({ + grid = [[ + {1: 0 }^aaaaa | + {1: 1 }bbbbb | + {1: 2 }ccccc | + {1: 3 }ddddd | + {2:~ }|*3 + | + ]], + }) + end) + + -- oldtest: Test_number_insert_delete_lines() + it('line numbers are updated when deleting/inserting lines', function() + local screen = Screen.new(50, 8) + screen:set_default_attr_ids({ + [1] = { foreground = Screen.colors.Brown }, -- LineNr + [2] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText + }) + screen:attach() + exec([[ + call setline(1, range(1, 7)) + set number + call cursor(2, 1) + ]]) + local snapshot1 = [[ + {1: 1 }1 | + {1: 2 }^2 | + {1: 3 }3 | + {1: 4 }4 | + {1: 5 }5 | + {1: 6 }6 | + {1: 7 }7 | + | + ]] + screen:expect(snapshot1) + feed('dd') + screen:expect([[ + {1: 1 }1 | + {1: 2 }^3 | + {1: 3 }4 | + {1: 4 }5 | + {1: 5 }6 | + {1: 6 }7 | + {2:~ }| + | + ]]) + feed('P') + screen:expect(snapshot1) + feed('2dd') + screen:expect([[ + {1: 1 }1 | + {1: 2 }^4 | + {1: 3 }5 | + {1: 4 }6 | + {1: 5 }7 | + {2:~ }|*2 + | + ]]) + feed('P') + screen:expect(snapshot1) + end) +end) diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua index ee8dfc7a60..705c182df7 100644 --- a/test/functional/plugin/lsp/diagnostic_spec.lua +++ b/test/functional/plugin/lsp/diagnostic_spec.lua @@ -193,7 +193,7 @@ describe('vim.lsp.diagnostic', function() PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { underline = false, virtual_text = { - severity_limit = ... + severity = { min = ... } }, }) @@ -212,11 +212,11 @@ describe('vim.lsp.diagnostic', function() end -- No messages with Error or higher - eq(0, get_extmark_count_with_severity('Error')) + eq(0, get_extmark_count_with_severity('ERROR')) -- But now we don't filter it - eq(1, get_extmark_count_with_severity('Warning')) - eq(1, get_extmark_count_with_severity('Hint')) + eq(1, get_extmark_count_with_severity('WARN')) + eq(1, get_extmark_count_with_severity('HINT')) end) it('correctly handles UTF-16 offsets', function() diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index d9bb4d3a98..d2320db2a1 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -1705,255 +1705,6 @@ describe('MsgSeparator highlight and msgsep fillchar', function() end) end) -describe("'number' and 'relativenumber' highlight", function() - before_each(clear) - - -- oldtest: Test_relativenumber_colors() - it('LineNr, LineNrAbove and LineNrBelow', function() - local screen = Screen.new(50, 10) - screen:set_default_attr_ids({ - [1] = { foreground = Screen.colors.Red }, - [2] = { foreground = Screen.colors.Blue }, - [3] = { foreground = Screen.colors.Green }, - }) - screen:attach() - exec([[ - call setline(1, range(200)) - 111 - set number relativenumber - hi LineNr guifg=red - ]]) - screen:expect([[ - {1: 4 }106 | - {1: 3 }107 | - {1: 2 }108 | - {1: 1 }109 | - {1:111 }^110 | - {1: 1 }111 | - {1: 2 }112 | - {1: 3 }113 | - {1: 4 }114 | - | - ]]) - command('hi LineNrAbove guifg=blue') - screen:expect([[ - {2: 4 }106 | - {2: 3 }107 | - {2: 2 }108 | - {2: 1 }109 | - {1:111 }^110 | - {1: 1 }111 | - {1: 2 }112 | - {1: 3 }113 | - {1: 4 }114 | - | - ]]) - command('hi LineNrBelow guifg=green') - screen:expect([[ - {2: 4 }106 | - {2: 3 }107 | - {2: 2 }108 | - {2: 1 }109 | - {1:111 }^110 | - {3: 1 }111 | - {3: 2 }112 | - {3: 3 }113 | - {3: 4 }114 | - | - ]]) - command('hi clear LineNrAbove') - screen:expect([[ - {1: 4 }106 | - {1: 3 }107 | - {1: 2 }108 | - {1: 1 }109 | - {1:111 }^110 | - {3: 1 }111 | - {3: 2 }112 | - {3: 3 }113 | - {3: 4 }114 | - | - ]]) - end) - - -- oldtest: Test_relativenumber_colors_wrapped() - it('LineNr, LineNrAbove and LineNrBelow with wrapped lines', function() - local screen = Screen.new(50, 20) - screen:set_default_attr_ids({ - [1] = { background = Screen.colors.Red, foreground = Screen.colors.Black }, - [2] = { background = Screen.colors.Blue, foreground = Screen.colors.Black }, - [3] = { background = Screen.colors.Green, foreground = Screen.colors.Black }, - [4] = { bold = true, foreground = Screen.colors.Blue }, - }) - screen:attach() - exec([[ - set display=lastline scrolloff=0 - call setline(1, range(200)->map('v:val->string()->repeat(40)')) - 111 - set number relativenumber - hi LineNr guibg=red guifg=black - hi LineNrAbove guibg=blue guifg=black - hi LineNrBelow guibg=green guifg=black - ]]) - screen:expect([[ - {2: 2 }1081081081081081081081081081081081081081081081| - {2: }0810810810810810810810810810810810810810810810| - {2: }8108108108108108108108108108 | - {2: 1 }1091091091091091091091091091091091091091091091| - {2: }0910910910910910910910910910910910910910910910| - {2: }9109109109109109109109109109 | - {1:111 }^1101101101101101101101101101101101101101101101| - {1: }1011011011011011011011011011011011011011011011| - {1: }0110110110110110110110110110 | - {3: 1 }1111111111111111111111111111111111111111111111| - {3: }1111111111111111111111111111111111111111111111| - {3: }1111111111111111111111111111 | - {3: 2 }1121121121121121121121121121121121121121121121| - {3: }1211211211211211211211211211211211211211211211| - {3: }2112112112112112112112112112 | - {3: 3 }1131131131131131131131131131131131131131131131| - {3: }1311311311311311311311311311311311311311311311| - {3: }3113113113113113113113113113 | - {3: 4 }1141141141141141141141141141141141141141141{4:@@@}| - | - ]]) - feed('k') - screen:expect([[ - {2: 1 }1081081081081081081081081081081081081081081081| - {2: }0810810810810810810810810810810810810810810810| - {2: }8108108108108108108108108108 | - {1:110 }^1091091091091091091091091091091091091091091091| - {1: }0910910910910910910910910910910910910910910910| - {1: }9109109109109109109109109109 | - {3: 1 }1101101101101101101101101101101101101101101101| - {3: }1011011011011011011011011011011011011011011011| - {3: }0110110110110110110110110110 | - {3: 2 }1111111111111111111111111111111111111111111111| - {3: }1111111111111111111111111111111111111111111111| - {3: }1111111111111111111111111111 | - {3: 3 }1121121121121121121121121121121121121121121121| - {3: }1211211211211211211211211211211211211211211211| - {3: }2112112112112112112112112112 | - {3: 4 }1131131131131131131131131131131131131131131131| - {3: }1311311311311311311311311311311311311311311311| - {3: }3113113113113113113113113113 | - {3: 5 }1141141141141141141141141141141141141141141{4:@@@}| - | - ]]) - feed('2j') - screen:expect([[ - {2: 3 }1081081081081081081081081081081081081081081081| - {2: }0810810810810810810810810810810810810810810810| - {2: }8108108108108108108108108108 | - {2: 2 }1091091091091091091091091091091091091091091091| - {2: }0910910910910910910910910910910910910910910910| - {2: }9109109109109109109109109109 | - {2: 1 }1101101101101101101101101101101101101101101101| - {2: }1011011011011011011011011011011011011011011011| - {2: }0110110110110110110110110110 | - {1:112 }^1111111111111111111111111111111111111111111111| - {1: }1111111111111111111111111111111111111111111111| - {1: }1111111111111111111111111111 | - {3: 1 }1121121121121121121121121121121121121121121121| - {3: }1211211211211211211211211211211211211211211211| - {3: }2112112112112112112112112112 | - {3: 2 }1131131131131131131131131131131131131131131131| - {3: }1311311311311311311311311311311311311311311311| - {3: }3113113113113113113113113113 | - {3: 3 }1141141141141141141141141141141141141141141{4:@@@}| - | - ]]) - feed('2j') - screen:expect([[ - {2: 5 }1081081081081081081081081081081081081081081081| - {2: }0810810810810810810810810810810810810810810810| - {2: }8108108108108108108108108108 | - {2: 4 }1091091091091091091091091091091091091091091091| - {2: }0910910910910910910910910910910910910910910910| - {2: }9109109109109109109109109109 | - {2: 3 }1101101101101101101101101101101101101101101101| - {2: }1011011011011011011011011011011011011011011011| - {2: }0110110110110110110110110110 | - {2: 2 }1111111111111111111111111111111111111111111111| - {2: }1111111111111111111111111111111111111111111111| - {2: }1111111111111111111111111111 | - {2: 1 }1121121121121121121121121121121121121121121121| - {2: }1211211211211211211211211211211211211211211211| - {2: }2112112112112112112112112112 | - {1:114 }^1131131131131131131131131131131131131131131131| - {1: }1311311311311311311311311311311311311311311311| - {1: }3113113113113113113113113113 | - {3: 1 }1141141141141141141141141141141141141141141{4:@@@}| - | - ]]) - feed('k') - screen:expect([[ - {2: 4 }1081081081081081081081081081081081081081081081| - {2: }0810810810810810810810810810810810810810810810| - {2: }8108108108108108108108108108 | - {2: 3 }1091091091091091091091091091091091091091091091| - {2: }0910910910910910910910910910910910910910910910| - {2: }9109109109109109109109109109 | - {2: 2 }1101101101101101101101101101101101101101101101| - {2: }1011011011011011011011011011011011011011011011| - {2: }0110110110110110110110110110 | - {2: 1 }1111111111111111111111111111111111111111111111| - {2: }1111111111111111111111111111111111111111111111| - {2: }1111111111111111111111111111 | - {1:113 }^1121121121121121121121121121121121121121121121| - {1: }1211211211211211211211211211211211211211211211| - {1: }2112112112112112112112112112 | - {3: 1 }1131131131131131131131131131131131131131131131| - {3: }1311311311311311311311311311311311311311311311| - {3: }3113113113113113113113113113 | - {3: 2 }1141141141141141141141141141141141141141141{4:@@@}| - | - ]]) - end) - - -- oldtest: Test_relativenumber_callback() - it('relative number highlight is updated if cursor is moved from timer', function() - local screen = Screen.new(50, 8) - screen:set_default_attr_ids({ - [1] = { foreground = Screen.colors.Brown }, -- LineNr - [2] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText - }) - screen:attach() - exec([[ - call setline(1, ['aaaaa', 'bbbbb', 'ccccc', 'ddddd']) - set relativenumber - call cursor(4, 1) - - func Func(timer) - call cursor(1, 1) - endfunc - - call timer_start(300, 'Func') - ]]) - screen:expect({ - grid = [[ - {1: 3 }aaaaa | - {1: 2 }bbbbb | - {1: 1 }ccccc | - {1: 0 }^ddddd | - {2:~ }|*3 - | - ]], - timeout = 100, - }) - screen:expect({ - grid = [[ - {1: 0 }^aaaaa | - {1: 1 }bbbbb | - {1: 2 }ccccc | - {1: 3 }ddddd | - {2:~ }|*3 - | - ]], - }) - end) -end) - describe("'winhighlight' highlight", function() local screen diff --git a/test/old/testdir/test_highlight.vim b/test/old/testdir/test_highlight.vim index f7f4d9832b..bcaa1dac5d 100644 --- a/test/old/testdir/test_highlight.vim +++ b/test/old/testdir/test_highlight.vim @@ -541,7 +541,7 @@ func Test_cursorline_after_yank() call writefile([ \ 'set cul rnu', \ 'call setline(1, ["","1","2","3",""])', - \ ], 'Xtest_cursorline_yank') + \ ], 'Xtest_cursorline_yank', 'D') let buf = RunVimInTerminal('-S Xtest_cursorline_yank', {'rows': 8}) call TermWait(buf) call term_sendkeys(buf, "Gy3k") @@ -552,25 +552,25 @@ func Test_cursorline_after_yank() " clean up call StopVimInTerminal(buf) - call delete('Xtest_cursorline_yank') endfunc -" test for issue https://github.com/vim/vim/issues/4862 +" Test for issue #4862: pasting above 'cursorline' redraws properly. func Test_put_before_cursorline() new only! - call setline(1, 'A') + call setline(1, ['A', 'B', 'C']) + call cursor(2, 1) redraw - let std_attr = screenattr(1, 1) + let std_attr = screenattr(2, 1) set cursorline redraw - let cul_attr = screenattr(1, 1) + let cul_attr = screenattr(2, 1) normal yyP redraw - " Line 1 has cursor so it should be highlighted with CursorLine. - call assert_equal(cul_attr, screenattr(1, 1)) - " And CursorLine highlighting from the second line should be gone. - call assert_equal(std_attr, screenattr(2, 1)) + " Line 2 has cursor so it should be highlighted with CursorLine. + call assert_equal(cul_attr, screenattr(2, 1)) + " And CursorLine highlighting from line 3 should be gone. + call assert_equal(std_attr, screenattr(3, 1)) set nocursorline bwipe! endfunc diff --git a/test/old/testdir/test_number.vim b/test/old/testdir/test_number.vim index 6ac3c4cfe4..b57c1ed2c5 100644 --- a/test/old/testdir/test_number.vim +++ b/test/old/testdir/test_number.vim @@ -146,8 +146,7 @@ func Test_number_with_linewrap1() call s:close_windows() endfunc -" Pending: https://groups.google.com/forum/#!topic/vim_dev/tzNKP7EDWYI -func XTest_number_with_linewrap2() +func Test_number_with_linewrap2() call s:test_windows(3, 20) normal! 61ia setl number wrap @@ -164,8 +163,7 @@ func XTest_number_with_linewrap2() call s:close_windows() endfunc -" Pending: https://groups.google.com/forum/#!topic/vim_dev/tzNKP7EDWYI -func XTest_number_with_linewrap3() +func Test_number_with_linewrap3() call s:test_windows(4, 20) normal! 81ia setl number wrap @@ -174,7 +172,7 @@ func XTest_number_with_linewrap3() call s:validate_cursor() let lines = s:screen_lines(1, 4) let expect = [ -\ "aaaaaaaa", +\ "<<<aaaaa", \ "aaaaaaaa", \ "aaaaaaaa", \ "a ", @@ -349,6 +347,31 @@ func Test_relativenumber_callback() call StopVimInTerminal(buf) endfunc +" Test that line numbers below inserted/deleted lines are updated. +func Test_number_insert_delete_lines() + CheckScreendump + + let lines =<< trim END + call setline(1, range(1, 7)) + set number + call cursor(2, 1) + END + call writefile(lines, 'Xnumber_insert_delete_lines', 'D') + + let buf = RunVimInTerminal('-S Xnumber_insert_delete_lines', #{rows: 8}) + call VerifyScreenDump(buf, 'Test_number_insert_delete_lines_1', {}) + call term_sendkeys(buf, "dd") + call VerifyScreenDump(buf, 'Test_number_insert_delete_lines_2', {}) + call term_sendkeys(buf, "P") + call VerifyScreenDump(buf, 'Test_number_insert_delete_lines_1', {}) + call term_sendkeys(buf, "2dd") + call VerifyScreenDump(buf, 'Test_number_insert_delete_lines_3', {}) + call term_sendkeys(buf, "P") + call VerifyScreenDump(buf, 'Test_number_insert_delete_lines_1', {}) + + call StopVimInTerminal(buf) +endfunc + " Test for displaying line numbers with 'rightleft' func Test_number_rightleft() CheckFeature rightleft |