diff options
104 files changed, 930 insertions, 557 deletions
diff --git a/.editorconfig b/.editorconfig index 2aa956b1fc..07993e25b9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,6 +10,9 @@ insert_final_newline = true [*.{c,h,in,lua}] max_line_length = 100 +[*.py] +indent_size = 4 + [{Makefile,**/Makefile,runtime/doc/*.txt}] indent_style = tab indent_size = 8 diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index c30c190301..b6c9253a41 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -1096,22 +1096,35 @@ WinNew When a new window was created. Not done for *WinScrolled* WinScrolled After scrolling the content of a window or - resizing a window. - The pattern is matched against the - |window-ID|. Both <amatch> and <afile> are - set to the |window-ID|. - Non-recursive (the event cannot trigger - itself). However, if the command causes the - window to scroll or change size another + resizing a window in the current tab page. + + When more than one window scrolled or resized + only one WinScrolled event is triggered. You + can use the `winlayout()` and `getwininfo()` + functions to see what changed. + + The pattern is matched against the |window-ID| + of the first window that scrolled or resized. + Both <amatch> and <afile> are set to the + |window-ID|. + + Only starts triggering after startup finished + and the first screen redraw was done. + + Non-recursive: the event will not trigger + while executing commands for the WinScrolled + event. However, if the command causes a + window to scroll or change size, then another WinScrolled event will be triggered later. + Does not trigger when the command is added, only after the first scroll or resize. ============================================================================== 6. Patterns *autocmd-pattern* *{aupat}* -The {aupat} argument of `:autocmd` can be a comma-separated list. This works -as if the command was given with each pattern separately. Thus this command: > +The {aupat} argument of `:autocmd` can be a comma-separated list. This works as +if the command was given with each pattern separately. Thus this command: > :autocmd BufRead *.txt,*.info set et Is equivalent to: > :autocmd BufRead *.txt set et diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index fa9fb286ae..fdee409639 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -170,6 +170,7 @@ get({func}, {what}) any get property of funcref/partial {func} getbufinfo([{buf}]) List information about buffers getbufline({buf}, {lnum} [, {end}]) List lines {lnum} to {end} of buffer {buf} +getbufoneline({buf}, {lnum}) String line {lnum} of buffer {buf} getbufvar({buf}, {varname} [, {def}]) any variable {varname} in buffer {buf} getchangelist([{buf}]) List list of change list items @@ -638,6 +639,7 @@ append({lnum}, {text}) *append()* text line below line {lnum} in the current buffer. Otherwise append {text} as one text line below line {lnum} in the current buffer. + Any type of item is accepted and converted to a String. {lnum} can be zero to insert a line before the first one. {lnum} is used like with |getline()|. Returns 1 for failure ({lnum} out of range or out of memory), @@ -2684,11 +2686,13 @@ getbufinfo([{dict}]) Can also be used as a |method|: > GetBufnr()->getbufinfo() < + *getbufline()* getbufline({buf}, {lnum} [, {end}]) Return a |List| with the lines starting from {lnum} to {end} (inclusive) in the buffer {buf}. If {end} is omitted, a - |List| with only the line {lnum} is returned. + |List| with only the line {lnum} is returned. See + `getbufoneline()` for only getting the line. For the use of {buf}, see |bufname()| above. @@ -2711,6 +2715,11 @@ getbufline({buf}, {lnum} [, {end}]) < Can also be used as a |method|: > GetBufnr()->getbufline(lnum) +< + *getbufoneline()* +getbufoneline({buf}, {lnum}) + Just like `getbufline()` but only get one line and return it + as a string. getbufvar({buf}, {varname} [, {def}]) *getbufvar()* The result is the value of option or local buffer variable @@ -3198,7 +3207,8 @@ getline({lnum} [, {end}]) < Can also be used as a |method|: > ComputeLnum()->getline() -< To get lines from another buffer see |getbufline()| +< To get lines from another buffer see |getbufline()| and + |getbufoneline()| getloclist({nr} [, {what}]) *getloclist()* Returns a |List| with all the entries in the location list for @@ -7054,6 +7064,8 @@ setline({lnum}, {text}) *setline()* {lnum} is used like with |getline()|. When {lnum} is just below the last line the {text} will be added below the last line. + {text} can be any type or a List of any type, each item is + converted to a String. If this succeeds, FALSE is returned. If this fails (most likely because {lnum} is invalid) TRUE is returned. diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index d30d6c28a0..07a7d5190f 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -365,6 +365,11 @@ config({opts}, {namespace}) *vim.diagnostic.config()* the beginning of the virtual text. • prefix: (string) Prepend diagnostic message with prefix. + • suffix: (string or function) Append diagnostic + message with suffix. If a function, it must have the + signature (diagnostic) -> string, where {diagnostic} + is of type |diagnostic-structure|. This can be used + to render an LSP diagnostic error code. • format: (function) A function that takes a diagnostic as input and returns a string. The return value is the text used to display the diagnostic. Example: > @@ -426,7 +431,7 @@ fromqflist({list}) *vim.diagnostic.fromqflist()* |getloclist()|. Return: ~ - array of diagnostics |diagnostic-structure| + Diagnostic [] array of |diagnostic-structure| get({bufnr}, {opts}) *vim.diagnostic.get()* Get current diagnostics. @@ -441,7 +446,7 @@ get({bufnr}, {opts}) *vim.diagnostic.get()* • severity: See |diagnostic-severity|. Return: ~ - (table) A list of diagnostic items |diagnostic-structure|. + Diagnostic [] table A list of diagnostic items |diagnostic-structure|. get_namespace({namespace}) *vim.diagnostic.get_namespace()* Get namespace metadata. @@ -462,37 +467,39 @@ get_next({opts}) *vim.diagnostic.get_next()* Get the next diagnostic closest to the cursor position. Parameters: ~ - • {opts} (table) See |vim.diagnostic.goto_next()| + • {opts} (table|nil) See |vim.diagnostic.goto_next()| Return: ~ - (table) Next diagnostic + Diagnostic|nil Next diagnostic get_next_pos({opts}) *vim.diagnostic.get_next_pos()* Return the position of the next diagnostic in the current buffer. Parameters: ~ - • {opts} (table) See |vim.diagnostic.goto_next()| + • {opts} (table|nil) See |vim.diagnostic.goto_next()| Return: ~ - (table) Next diagnostic position as a (row, col) tuple. + table|false Next diagnostic position as a (row, col) tuple or false if + no next diagnostic. get_prev({opts}) *vim.diagnostic.get_prev()* Get the previous diagnostic closest to the cursor position. Parameters: ~ - • {opts} (table) See |vim.diagnostic.goto_next()| + • {opts} nil|table See |vim.diagnostic.goto_next()| Return: ~ - (table) Previous diagnostic + Diagnostic|nil Previous diagnostic get_prev_pos({opts}) *vim.diagnostic.get_prev_pos()* Return the position of the previous diagnostic in the current buffer. Parameters: ~ - • {opts} (table) See |vim.diagnostic.goto_next()| + • {opts} (table|nil) See |vim.diagnostic.goto_next()| Return: ~ - (table) Previous diagnostic position as a (row, col) tuple. + table|false Previous diagnostic position as a (row, col) tuple or + false if there is no prior diagnostic goto_next({opts}) *vim.diagnostic.goto_next()* Move to the next diagnostic. @@ -532,8 +539,8 @@ hide({namespace}, {bufnr}) *vim.diagnostic.hide()* |vim.diagnostic.disable()|. Parameters: ~ - • {namespace} (number|nil) Diagnostic namespace. When omitted, hide - diagnostics from all namespaces. + • {namespace} (number|nil) Diagnostic namespace. When omitted, hide diagnostics from all + namespaces. • {bufnr} (number|nil) Buffer number, or 0 for current buffer. When omitted, hide diagnostics in all buffers. @@ -566,8 +573,8 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults}) default to 0 and "severity" defaults to ERROR. Return: ~ - diagnostic |diagnostic-structure| or `nil` if {pat} fails to match - {str}. + Diagnostic|nil: |diagnostic-structure| or `nil` if {pat} fails to + match {str}. open_float({opts}, {...}) *vim.diagnostic.open_float()* Show diagnostics in a floating window. @@ -618,9 +625,12 @@ open_float({opts}, {...}) *vim.diagnostic.open_float()* {prefix} is a string, it is prepended to each diagnostic in the window with no highlight. Overrides the setting from |vim.diagnostic.config()|. + • suffix: Same as {prefix}, but appends the text to the + diagnostic instead of prepending it. Overrides the setting + from |vim.diagnostic.config()|. Return: ~ - tuple ({float_bufnr}, {win_id}) + number|nil, number|nil: ({float_bufnr}, {win_id}) reset({namespace}, {bufnr}) *vim.diagnostic.reset()* Remove all diagnostics from the given namespace. @@ -631,8 +641,8 @@ reset({namespace}, {bufnr}) *vim.diagnostic.reset()* re-displayed, use |vim.diagnostic.hide()|. Parameters: ~ - • {namespace} (number|nil) Diagnostic namespace. When omitted, remove - diagnostics from all namespaces. + • {namespace} (number|nil) Diagnostic namespace. When omitted, remove diagnostics from all + namespaces. • {bufnr} (number|nil) Remove diagnostics for the given buffer. When omitted, diagnostics are removed for all buffers. @@ -680,8 +690,8 @@ show({namespace}, {bufnr}, {diagnostics}, {opts}) Display diagnostics for the given namespace and buffer. Parameters: ~ - • {namespace} (number|nil) Diagnostic namespace. When omitted, show - diagnostics from all namespaces. + • {namespace} (number|nil) Diagnostic namespace. When omitted, show diagnostics from all + namespaces. • {bufnr} (number|nil) Buffer number, or 0 for current buffer. When omitted, show diagnostics in all buffers. • {diagnostics} (table|nil) The diagnostics to display. When omitted, @@ -701,6 +711,6 @@ toqflist({diagnostics}) *vim.diagnostic.toqflist()* • {diagnostics} (table) List of diagnostics |diagnostic-structure|. Return: ~ - array of quickfix list items |setqflist-what| + table[] of quickfix list items |setqflist-what| vim:tw=78:ts=8:sw=4:sts=4:et:ft=help:norl: diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index e4f8030f16..eb42e10338 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -229,13 +229,13 @@ is not available it returns zero or the default value you specify: > List concatenation ~ - + *list-concatenation* Two lists can be concatenated with the "+" operator: > :let longlist = mylist + [5, 6] :let mylist += [7, 8] -To prepend or append an item turn the item into a list by putting [] around -it. To change a list in-place see |list-modification| below. +To prepend or append an item, turn the item into a list by putting [] around +it. To change a list in-place, refer to |list-modification| below. Sublist ~ diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 036b0bbc6f..0255d78c4c 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1330,7 +1330,9 @@ hover({_}, {result}, {ctx}, {config}) *vim.lsp.handlers.hover()* vim.lsp.handlers["textDocument/hover"] = vim.lsp.with( vim.lsp.handlers.hover, { -- Use a sharp border with `FloatBorder` highlights - border = "single" + border = "single", + -- add the title in hover float window + title = "hover" } ) < diff --git a/runtime/doc/support.txt b/runtime/doc/support.txt index a0fc6e9f2c..481959d8f1 100644 --- a/runtime/doc/support.txt +++ b/runtime/doc/support.txt @@ -12,8 +12,8 @@ Support *support* Supported platforms *supported-platforms* `System` `Tier` `Versions` `Tested versions` -Linux 1 >= 2.6.32, glibc >= 2.12 Ubuntu 20.04 -macOS (Intel) 1 >= 10.15 macOS 11 +Linux 1 >= 2.6.32, glibc >= 2.12 Ubuntu 22.04 +macOS (Intel) 1 >= 10.15 macOS 12 Windows 64-bit 1 >= 8 Windows Server 2019 FreeBSD 1 >= 10 FreeBSD 13 macOS (M1) 2 >= 10.15 diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 067ad6648c..226bd029a3 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -785,6 +785,13 @@ Working with text in the current buffer: *text-functions* getcharsearch() return character search information setcharsearch() set character search information +Working with text in another buffer: + getbufline() get a list of lines from the specified buffer + getbufoneline() get a one line from the specified buffer + setbufline() replace a line in the specified buffer + appendbufline() append a list of lines in the specified buffer + deletebufline() delete lines from a specified buffer + *system-functions* *file-functions* System functions and manipulation of files: glob() expand wildcards @@ -838,8 +845,10 @@ Buffers, windows and the argument list: argidx() current position in the argument list arglistid() get id of the argument list argv() get one entry from the argument list + bufadd() add a file to the list of buffers bufexists() check if a buffer exists buflisted() check if a buffer exists and is listed + bufload() ensure a buffer is loaded bufloaded() check if a buffer exists and is loaded bufname() get the name of a specific buffer bufnr() get the buffer number of a specific buffer @@ -850,10 +859,6 @@ Buffers, windows and the argument list: bufwinid() get the window ID of a specific buffer bufwinnr() get the window number of a specific buffer winbufnr() get the buffer number of a specific window - getbufline() get a list of lines from the specified buffer - setbufline() replace a line in the specified buffer - appendbufline() append a list of lines in the specified buffer - deletebufline() delete lines from a specified buffer win_findbuf() find windows containing a buffer win_getid() get window ID of a window win_gettype() get type of window diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 09eeb617f5..18df1f1586 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -2,6 +2,7 @@ local api, if_nil = vim.api, vim.F.if_nil local M = {} +---@enum DiagnosticSeverity M.severity = { ERROR = 1, WARN = 2, @@ -613,6 +614,10 @@ end --- * spacing: (number) Amount of empty spaces inserted at the beginning --- of the virtual text. --- * prefix: (string) Prepend diagnostic message with prefix. +--- * suffix: (string or function) Append diagnostic message with suffix. +--- If a function, it must have the signature (diagnostic) -> +--- string, where {diagnostic} is of type |diagnostic-structure|. +--- This can be used to render an LSP diagnostic error code. --- * format: (function) A function that takes a diagnostic as input and --- returns a string. The return value is the text used to display --- the diagnostic. Example: @@ -751,6 +756,18 @@ function M.get_namespaces() return vim.deepcopy(all_namespaces) end +---@class Diagnostic +---@field buffer number +---@field lnum number 0-indexed +---@field end_lnum nil|number 0-indexed +---@field col number 0-indexed +---@field end_col nil|number 0-indexed +---@field severity DiagnosticSeverity +---@field message string +---@field source nil|string +---@field code nil|string +---@field user_data nil|any arbitrary data plugins can add + --- Get current diagnostics. --- ---@param bufnr number|nil Buffer number to get diagnostics from. Use 0 for @@ -759,7 +776,7 @@ end --- - namespace: (number) Limit diagnostics to the given namespace. --- - lnum: (number) Limit diagnostics to the given line number. --- - severity: See |diagnostic-severity|. ----@return table A list of diagnostic items |diagnostic-structure|. +---@return Diagnostic[] table A list of diagnostic items |diagnostic-structure|. function M.get(bufnr, opts) vim.validate({ bufnr = { bufnr, 'n', true }, @@ -771,8 +788,8 @@ end --- Get the previous diagnostic closest to the cursor position. --- ----@param opts table See |vim.diagnostic.goto_next()| ----@return table Previous diagnostic +---@param opts nil|table See |vim.diagnostic.goto_next()| +---@return Diagnostic|nil Previous diagnostic function M.get_prev(opts) opts = opts or {} @@ -785,8 +802,9 @@ end --- Return the position of the previous diagnostic in the current buffer. --- ----@param opts table See |vim.diagnostic.goto_next()| ----@return table Previous diagnostic position as a (row, col) tuple. +---@param opts table|nil See |vim.diagnostic.goto_next()| +---@return table|false Previous diagnostic position as a (row, col) tuple or false if there is no +--- prior diagnostic function M.get_prev_pos(opts) local prev = M.get_prev(opts) if not prev then @@ -804,8 +822,8 @@ end --- Get the next diagnostic closest to the cursor position. --- ----@param opts table See |vim.diagnostic.goto_next()| ----@return table Next diagnostic +---@param opts table|nil See |vim.diagnostic.goto_next()| +---@return Diagnostic|nil Next diagnostic function M.get_next(opts) opts = opts or {} @@ -818,8 +836,9 @@ end --- Return the position of the next diagnostic in the current buffer. --- ----@param opts table See |vim.diagnostic.goto_next()| ----@return table Next diagnostic position as a (row, col) tuple. +---@param opts table|nil See |vim.diagnostic.goto_next()| +---@return table|false Next diagnostic position as a (row, col) tuple or false if no next +--- diagnostic. function M.get_next_pos(opts) local next = M.get_next(opts) if not next then @@ -1039,6 +1058,7 @@ function M._get_virt_text_chunks(line_diags, opts) opts = opts or {} local prefix = opts.prefix or '■' + local suffix = opts.suffix or '' local spacing = opts.spacing or 4 -- Create a little more space between virtual text and contents @@ -1052,8 +1072,11 @@ function M._get_virt_text_chunks(line_diags, opts) -- TODO(tjdevries): Allow different servers to be shown first somehow? -- TODO(tjdevries): Display server name associated with these? if last.message then + if type(suffix) == 'function' then + suffix = suffix(last) or '' + end table.insert(virt_texts, { - string.format('%s %s', prefix, last.message:gsub('\r', ''):gsub('\n', ' ')), + string.format('%s %s%s', prefix, last.message:gsub('\r', ''):gsub('\n', ' '), suffix), virtual_text_highlight_map[last.severity], }) @@ -1220,7 +1243,9 @@ end --- string, it is prepended to each diagnostic in the window with no --- highlight. --- Overrides the setting from |vim.diagnostic.config()|. ----@return tuple ({float_bufnr}, {win_id}) +--- - suffix: Same as {prefix}, but appends the text to the diagnostic instead of +--- prepending it. Overrides the setting from |vim.diagnostic.config()|. +---@return number|nil, number|nil: ({float_bufnr}, {win_id}) function M.open_float(opts, ...) -- Support old (bufnr, opts) signature local bufnr @@ -1313,11 +1338,11 @@ function M.open_float(opts, ...) -- Don't insert any lines for an empty string if string.len(if_nil(header[1], '')) > 0 then table.insert(lines, header[1]) - table.insert(highlights, { 0, header[2] or 'Bold' }) + table.insert(highlights, { hlname = header[2] or 'Bold' }) end elseif #header > 0 then table.insert(lines, header) - table.insert(highlights, { 0, 'Bold' }) + table.insert(highlights, { hlname = 'Bold' }) end end @@ -1350,18 +1375,52 @@ function M.open_float(opts, ...) end end + local suffix_opt = if_nil(opts.suffix, function(diagnostic) + return diagnostic.code and string.format(' [%s]', diagnostic.code) or '' + end) + + local suffix, suffix_hl_group + if suffix_opt then + vim.validate({ + suffix = { + suffix_opt, + { 'string', 'table', 'function' }, + "'string' or 'table' or 'function'", + }, + }) + if type(suffix_opt) == 'string' then + suffix, suffix_hl_group = suffix_opt, 'NormalFloat' + elseif type(suffix_opt) == 'table' then + suffix, suffix_hl_group = suffix_opt[1] or '', suffix_opt[2] or 'NormalFloat' + end + end + for i, diagnostic in ipairs(diagnostics) do if prefix_opt and type(prefix_opt) == 'function' then prefix, prefix_hl_group = prefix_opt(diagnostic, i, #diagnostics) prefix, prefix_hl_group = prefix or '', prefix_hl_group or 'NormalFloat' end + if suffix_opt and type(suffix_opt) == 'function' then + suffix, suffix_hl_group = suffix_opt(diagnostic, i, #diagnostics) + suffix, suffix_hl_group = suffix or '', suffix_hl_group or 'NormalFloat' + end local hiname = floating_highlight_map[diagnostic.severity] local message_lines = vim.split(diagnostic.message, '\n') - table.insert(lines, prefix .. message_lines[1]) - table.insert(highlights, { #prefix, hiname, prefix_hl_group }) - for j = 2, #message_lines do - table.insert(lines, string.rep(' ', #prefix) .. message_lines[j]) - table.insert(highlights, { 0, hiname }) + for j = 1, #message_lines do + local pre = j == 1 and prefix or string.rep(' ', #prefix) + local suf = j == #message_lines and suffix or '' + table.insert(lines, pre .. message_lines[j] .. suf) + table.insert(highlights, { + hlname = hiname, + prefix = { + length = j == 1 and #prefix or 0, + hlname = prefix_hl_group, + }, + suffix = { + length = j == #message_lines and #suffix or 0, + hlname = suffix_hl_group, + }, + }) end end @@ -1370,12 +1429,17 @@ function M.open_float(opts, ...) opts.focus_id = scope end local float_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts) - for i, hi in ipairs(highlights) do - local prefixlen, hiname, prefix_hiname = unpack(hi) - if prefix_hiname then - api.nvim_buf_add_highlight(float_bufnr, -1, prefix_hiname, i - 1, 0, prefixlen) + for i, hl in ipairs(highlights) do + local line = lines[i] + local prefix_len = hl.prefix and hl.prefix.length or 0 + local suffix_len = hl.suffix and hl.suffix.length or 0 + if prefix_len > 0 then + api.nvim_buf_add_highlight(float_bufnr, -1, hl.prefix.hlname, i - 1, 0, prefix_len) + end + api.nvim_buf_add_highlight(float_bufnr, -1, hl.hlname, i - 1, prefix_len, #line - suffix_len) + if suffix_len > 0 then + api.nvim_buf_add_highlight(float_bufnr, -1, hl.suffix.hlname, i - 1, #line - suffix_len, -1) end - api.nvim_buf_add_highlight(float_bufnr, -1, hiname, i - 1, prefixlen, -1) end return float_bufnr, winnr @@ -1529,7 +1593,7 @@ end ---@param defaults table|nil Table of default values for any fields not listed in {groups}. --- When omitted, numeric values default to 0 and "severity" defaults to --- ERROR. ----@return diagnostic |diagnostic-structure| or `nil` if {pat} fails to match {str}. +---@return Diagnostic|nil: |diagnostic-structure| or `nil` if {pat} fails to match {str}. function M.match(str, pat, groups, severity_map, defaults) vim.validate({ str = { str, 's' }, @@ -1576,7 +1640,7 @@ local errlist_type_map = { --- passed to |setqflist()| or |setloclist()|. --- ---@param diagnostics table List of diagnostics |diagnostic-structure|. ----@return array of quickfix list items |setqflist-what| +---@return table[] of quickfix list items |setqflist-what| function M.toqflist(diagnostics) vim.validate({ diagnostics = { @@ -1613,7 +1677,7 @@ end --- ---@param list table A list of quickfix items from |getqflist()| or --- |getloclist()|. ----@return array of diagnostics |diagnostic-structure| +---@return Diagnostic[] array of |diagnostic-structure| function M.fromqflist(list) vim.validate({ list = { diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 8e5e75232f..39e2577294 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -317,7 +317,9 @@ end --- vim.lsp.handlers["textDocument/hover"] = vim.lsp.with( --- vim.lsp.handlers.hover, { --- -- Use a sharp border with `FloatBorder` highlights ---- border = "single" +--- border = "single", +--- -- add the title in hover float window +--- title = "hover" --- } --- ) --- </pre> diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index b0f9c1660e..d89757ef0c 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1050,6 +1050,13 @@ function M.make_floating_popup_options(width, height, opts) col = 1 end + local title = (opts.border and opts.title) and opts.title or nil + local title_pos + + if title then + title_pos = opts.title_pos or 'center' + end + return { anchor = anchor, col = col + (opts.offset_x or 0), @@ -1061,6 +1068,8 @@ function M.make_floating_popup_options(width, height, opts) width = width, border = opts.border or default_border, zindex = opts.zindex or 50, + title = title, + title_pos = title_pos, } end diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 532052f9b0..cfe887d762 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -382,7 +382,7 @@ static void parse_border_title(Object title, Object title_pos, FloatConfig *fcon return; } - if (title.type == kObjectTypeArray && title.data.array.size == 0) { + if (title.data.array.size == 0) { api_set_error(err, kErrorTypeValidation, "title cannot be an empty array"); return; } @@ -391,7 +391,6 @@ static void parse_border_title(Object title, Object title_pos, FloatConfig *fcon fconfig->title_chunks = parse_virt_text(title.data.array, err, &fconfig->title_width); fconfig->title = true; - return; } static bool parse_title_pos(Object title_pos, FloatConfig *fconfig, Error *err) diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 4df14411c5..54fa57c7a0 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -1142,13 +1142,17 @@ int autocmd_register(int64_t id, event_T event, char *pat, int patlen, int group } // Initialize the fields checked by the WinScrolled trigger to - // stop it from firing right after the first autocmd is defined. + // prevent it from firing right after the first autocmd is + // defined. if (event == EVENT_WINSCROLLED && !has_event(EVENT_WINSCROLLED)) { - curwin->w_last_topline = curwin->w_topline; - curwin->w_last_leftcol = curwin->w_leftcol; - curwin->w_last_skipcol = curwin->w_skipcol; - curwin->w_last_width = curwin->w_width; - curwin->w_last_height = curwin->w_height; + tabpage_T *save_curtab = curtab; + FOR_ALL_TABS(tp) { + unuse_tabpage(curtab); + use_tabpage(tp); + snapshot_windows_scroll_size(); + } + unuse_tabpage(curtab); + use_tabpage(save_curtab); } ap->cmds = NULL; diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index 71959cfa29..6f7d6a27ef 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -808,26 +808,26 @@ static linenr_T debuggy_find(bool file, char_u *fname, linenr_T after, garray_T typval_T *const tv = eval_expr_no_emsg(bp); if (tv != NULL) { if (bp->dbg_val == NULL) { - debug_oldval = typval_tostring(NULL); + debug_oldval = typval_tostring(NULL, true); bp->dbg_val = tv; - debug_newval = typval_tostring(bp->dbg_val); + debug_newval = typval_tostring(bp->dbg_val, true); line = true; } else { if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK && tv->vval.v_number == false) { line = true; - debug_oldval = typval_tostring(bp->dbg_val); + debug_oldval = typval_tostring(bp->dbg_val, true); // Need to evaluate again, typval_compare() overwrites "tv". typval_T *const v = eval_expr_no_emsg(bp); - debug_newval = typval_tostring(v); + debug_newval = typval_tostring(v, true); tv_free(bp->dbg_val); bp->dbg_val = v; } tv_free(tv); } } else if (bp->dbg_val != NULL) { - debug_oldval = typval_tostring(bp->dbg_val); - debug_newval = typval_tostring(NULL); + debug_oldval = typval_tostring(bp->dbg_val, true); + debug_newval = typval_tostring(NULL, true); tv_free(bp->dbg_val); bp->dbg_val = NULL; line = true; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8e7eead62c..a41a559fd9 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1236,8 +1236,6 @@ int eval_foldexpr(char *arg, int *cp) return (int)retval; } -// TODO(ZyX-I): move to eval/executor - /// Get an lvalue /// /// Lvalue may be @@ -1622,8 +1620,6 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const return p; } -// TODO(ZyX-I): move to eval/executor - /// Clear lval "lp" that was filled by get_lval(). void clear_lval(lval_T *lp) { @@ -1631,8 +1627,6 @@ void clear_lval(lval_T *lp) xfree(lp->ll_newkey); } -// TODO(ZyX-I): move to eval/executor - /// Set a variable that was parsed by get_lval() to "rettv". /// /// @param endp points to just after the parsed name. @@ -1840,8 +1834,6 @@ notify: } } -// TODO(ZyX-I): move to eval/ex_cmds - /// Evaluate the expression used in a ":for var in expr" command. /// "arg" points to "var". /// @@ -1917,8 +1909,6 @@ void *eval_for_line(const char *arg, bool *errp, char **nextcmdp, int skip) return fi; } -// TODO(ZyX-I): move to eval/ex_cmds - /// Use the first item in a ":for" list. Advance to the next. /// Assign the values to the variable (list). "arg" points to the first one. /// @@ -1965,8 +1955,6 @@ bool next_for_item(void *fi_void, char *arg) fi->fi_semicolon, fi->fi_varcount, false, NULL) == OK); } -// TODO(ZyX-I): move to eval/ex_cmds - /// Free the structure used to store info used by ":for". void free_for_info(void *fi_void) { @@ -2212,8 +2200,6 @@ char *get_user_var_name(expand_T *xp, int idx) return NULL; } -// TODO(ZyX-I): move to eval/expressions - /// Does not use 'cpo' and always uses 'magic'. /// /// @return true if "pat" matches "text". @@ -2293,8 +2279,6 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ return ret; } -// TODO(ZyX-I): move to eval/expressions - /// The "evaluate" argument: When false, the argument is only parsed but not /// executed. The function may return OK, but the rettv will be of type /// VAR_UNKNOWN. The function still returns FAIL for a syntax error. @@ -2344,8 +2328,6 @@ int eval0(char *arg, typval_T *rettv, char **nextcmd, int evaluate) return ret; } -// TODO(ZyX-I): move to eval/expressions - /// Handle top level expression: /// expr2 ? expr1 : expr1 /// @@ -2410,8 +2392,6 @@ int eval1(char **arg, typval_T *rettv, int evaluate) return OK; } -// TODO(ZyX-I): move to eval/expressions - /// Handle first level expression: /// expr2 || expr2 || expr2 logical OR /// @@ -2469,8 +2449,6 @@ static int eval2(char **arg, typval_T *rettv, int evaluate) return OK; } -// TODO(ZyX-I): move to eval/expressions - /// Handle second level expression: /// expr3 && expr3 && expr3 logical AND /// @@ -2528,8 +2506,6 @@ static int eval3(char **arg, typval_T *rettv, int evaluate) return OK; } -// TODO(ZyX-I): move to eval/expressions - /// Handle third level expression: /// var1 == var2 /// var1 =~ var2 @@ -2633,8 +2609,6 @@ static int eval4(char **arg, typval_T *rettv, int evaluate) return OK; } -// TODO(ZyX-I): move to eval/expressions - /// Handle fourth level expression: /// + number addition /// - number subtraction @@ -2796,8 +2770,6 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) return OK; } -// TODO(ZyX-I): move to eval/expressions - /// Handle fifth level expression: /// - * number multiplication /// - / number division @@ -2913,8 +2885,6 @@ static int eval6(char **arg, typval_T *rettv, int evaluate, int want_string) return OK; } -// TODO(ZyX-I): move to eval/expressions - /// Handle sixth level expression: /// number number constant /// 0zFFFFFFFF Blob constant @@ -3408,8 +3378,6 @@ static int eval_method(char **const arg, typval_T *const rettv, const bool evalu return ret; } -// TODO(ZyX-I): move to eval/expressions - /// Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". /// "*arg" points to the '[' or '.'. /// @@ -3709,8 +3677,6 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) return OK; } -// TODO(ZyX-I): move to eval/executor - /// Get an option value /// /// @param[in,out] arg Points to the '&' or '+' before the option name. Is @@ -3974,8 +3940,6 @@ char *partial_name(partial_T *pt) return (char *)pt->pt_func->uf_name; } -// TODO(ZyX-I): Move to eval/typval.h - static void partial_free(partial_T *pt) { for (int i = 0; i < pt->pt_argc; i++) { @@ -3992,8 +3956,6 @@ static void partial_free(partial_T *pt) xfree(pt); } -// TODO(ZyX-I): Move to eval/typval.h - /// Unreference a closure: decrement the reference count and free it when it /// becomes zero. void partial_unref(partial_T *pt) @@ -5592,9 +5554,9 @@ void screenchar_adjust(ScreenGrid **grid, int *row, int *col) *col -= (*grid)->comp_col; } -/// Set line or list of lines in buffer "buf". -void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T *lines, - typval_T *rettv) +/// Set line or list of lines in buffer "buf" to "lines". +/// Any type is allowed and converted to a string. +void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, typval_T *lines, typval_T *rettv) FUNC_ATTR_NONNULL_ARG(4, 5) { linenr_T lnum = lnum_arg + (append ? 1 : 0); @@ -5632,7 +5594,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T list_T *l = NULL; listitem_T *li = NULL; - const char *line = NULL; + char *line = NULL; if (lines->v_type == VAR_LIST) { l = lines->vval.v_list; if (l == NULL || tv_list_len(l) == 0) { @@ -5644,7 +5606,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T } li = tv_list_first(l); } else { - line = tv_get_string_chk(lines); + line = typval_tostring(lines, false); } // Default result is zero == OK. @@ -5654,7 +5616,8 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T if (li == NULL) { break; } - line = tv_get_string_chk(TV_LIST_ITEM_TV(li)); + xfree(line); + line = typval_tostring(TV_LIST_ITEM_TV(li), false); li = TV_LIST_ITEM_NEXT(l, li); } @@ -5674,7 +5637,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T // Existing line, replace it. int old_len = (int)strlen(ml_get(lnum)); if (u_savesub(lnum) == OK - && ml_replace(lnum, (char *)line, true) == OK) { + && ml_replace(lnum, line, true) == OK) { inserted_bytes(lnum, 0, old_len, (int)strlen(line)); if (is_curbuf && lnum == curwin->w_cursor.lnum) { check_cursor_col(); @@ -5684,7 +5647,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T } else if (added > 0 || u_save(lnum - 1, lnum) == OK) { // append the line. added++; - if (ml_append(lnum - 1, (char *)line, 0, false) == OK) { + if (ml_append(lnum - 1, line, 0, false) == OK) { rettv->vval.v_number = 0; // OK } } @@ -5694,6 +5657,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T } lnum++; } + xfree(line); if (added > 0) { appended_lines_mark(append_lnum, added); @@ -8965,10 +8929,16 @@ int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, bool ic) return OK; } -char *typval_tostring(typval_T *arg) +/// Convert any type to a string, never give an error. +/// When "quotes" is true add quotes to a string. +/// Returns an allocated string. +char *typval_tostring(typval_T *arg, bool quotes) { if (arg == NULL) { return xstrdup("(does not exist)"); } + if (!quotes && arg->v_type == VAR_STRING) { + return xstrdup(arg->vval.v_string == NULL ? "" : arg->vval.v_string); + } return encode_tv2string(arg, NULL); } diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index dd30f51eb4..14be6aba73 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -146,6 +146,7 @@ return { get={args={2, 3}, base=1}, getbufinfo={args={0, 1}, base=1}, getbufline={args={2, 3}, base=1}, + getbufoneline={args=2, base=1}, getbufvar={args={2, 3}, base=1}, getchangelist={args={0, 1}, base=1}, getchar={args={0, 1}}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index e49b0fd14c..8ab1178b17 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2671,8 +2671,9 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli } } -/// "getbufline()" function -static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +/// @param retlist true: "getbufline()" function +/// false: "getbufoneline()" function +static void getbufline(typval_T *argvars, typval_T *rettv, bool retlist) { const int did_emsg_before = did_emsg; buf_T *const buf = tv_get_buf_from_arg(&argvars[0]); @@ -2684,7 +2685,19 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) ? lnum : tv_get_lnum_buf(&argvars[2], buf)); - get_buffer_lines(buf, lnum, end, true, rettv); + get_buffer_lines(buf, lnum, end, retlist, rettv); +} + +/// "getbufline()" function +static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + getbufline(argvars, rettv, true); +} + +/// "getbufoneline()" function +static void f_getbufoneline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + getbufline(argvars, rettv, false); } /// "getchangelist()" function diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index ae867cb716..42f78422cb 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -2960,8 +2960,6 @@ void ex_return(exarg_T *eap) } } -// TODO(ZyX-I): move to eval/ex_cmds - /// ":1,25call func(arg1, arg2)" function call. void ex_call(exarg_T *eap) { diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 54ff0a53d3..733bc3ac2d 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -558,8 +558,6 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) return arg; } -// TODO(ZyX-I): move to eval/ex_cmds - /// Set one item of `:let var = expr` or `:let [v1, v2] = list` to its value /// /// @param[in] arg Start of the variable name. @@ -769,8 +767,6 @@ void ex_unlet(exarg_T *eap) ex_unletlock(eap, eap->arg, 0, do_unlet_var); } -// TODO(ZyX-I): move to eval/ex_cmds - /// ":lockvar" and ":unlockvar" commands void ex_lockvar(exarg_T *eap) { @@ -787,8 +783,6 @@ void ex_lockvar(exarg_T *eap) ex_unletlock(eap, arg, deep, do_lock_var); } -// TODO(ZyX-I): move to eval/ex_cmds - /// Common parsing logic for :unlet, :lockvar and :unlockvar. /// /// Invokes `callback` afterwards if successful and `eap->skip == false`. @@ -853,8 +847,6 @@ static void ex_unletlock(exarg_T *eap, char *argstart, int deep, ex_unletlock_ca eap->nextcmd = check_nextcmd(arg); } -// TODO(ZyX-I): move to eval/ex_cmds - /// Unlet a variable indicated by `lp`. /// /// @param[in] lp The lvalue. @@ -944,8 +936,6 @@ static int do_unlet_var(lval_T *lp, char *name_end, exarg_T *eap, int deep FUNC_ return ret; } -// TODO(ZyX-I): move to eval/ex_cmds - /// unlet a variable /// /// @param[in] name Variable name to unlet. @@ -1016,8 +1006,6 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit) return FAIL; } -// TODO(ZyX-I): move to eval/ex_cmds - /// Lock or unlock variable indicated by `lp`. /// /// Locks if `eap->cmdidx == CMD_lockvar`, unlocks otherwise. @@ -1463,8 +1451,6 @@ bool var_check_fixed(const int flags, const char *name, size_t name_len) return false; } -// TODO(ZyX-I): move to eval/expressions - /// Check if name is a valid name to assign funcref to /// /// @param[in] name Possible function/funcref name. @@ -1493,8 +1479,6 @@ bool var_wrong_func_name(const char *const name, const bool new_var) return false; } -// TODO(ZyX-I): move to eval/expressions - /// Check if a variable name is valid /// /// @param[in] varname Variable name to check. diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index cd80da729b..db0b20036f 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -1,8 +1,6 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -// TODO(ZyX-I): move to eval/executor - /// @file ex_eval.c /// /// Functions for Ex command line for the +eval feature. @@ -862,7 +860,7 @@ void ex_endif(exarg_T *eap) /// Handle ":else" and ":elseif". void ex_else(exarg_T *eap) { - int result; + bool result = false; cstack_T *const cstack = eap->cstack; bool skip = CHECK_SKIP; diff --git a/src/nvim/linematch.c b/src/nvim/linematch.c index 9897c92ac5..f8b286fcd8 100644 --- a/src/nvim/linematch.c +++ b/src/nvim/linematch.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include <assert.h> #include <stdbool.h> #include <stddef.h> diff --git a/src/nvim/msgpack_rpc/unpacker.c b/src/nvim/msgpack_rpc/unpacker.c index e5583cf91b..c082bba660 100644 --- a/src/nvim/msgpack_rpc/unpacker.c +++ b/src/nvim/msgpack_rpc/unpacker.c @@ -380,6 +380,7 @@ bool unpacker_parse_redraw(Unpacker *p) size_t size = p->read_size; GridLineEvent *g = p->grid_line_event; +// -V:NEXT_TYPE:501 #define NEXT_TYPE(tok, typ) \ result = mpack_rtoken(&data, &size, &tok); \ if (result == MPACK_EOF) { \ diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 5536b7ba08..f9b32a9bd6 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1397,6 +1397,9 @@ static int normal_check(VimState *state) fclose(time_fd); time_fd = NULL; } + // After the first screen update may start triggering WinScrolled + // autocmd events. Store all the scroll positions and sizes now. + may_make_initial_scroll_size_snapshot(); } // May perform garbage collection when waiting for a character, but diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 2ae0a81e3d..d694025bc2 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -974,7 +974,7 @@ int os_file_mkdir(char *fname, int32_t mode) *tail = NUL; int r; char *failed_dir; - if ((r = os_mkdir_recurse(fname, mode, &failed_dir) < 0)) { + if (((r = os_mkdir_recurse(fname, mode, &failed_dir)) < 0)) { semsg(_(e_mkdir), failed_dir, os_strerror(r)); xfree(failed_dir); } diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index f0a983b80f..ef168d1d45 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -6711,7 +6711,7 @@ static bool mark_quickfix_ctx(qf_info_T *qi, int copyID) typval_T *ctx = qi->qf_lists[i].qf_ctx; if (ctx != NULL && ctx->v_type != VAR_NUMBER && ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT) { - abort = abort || set_ref_in_item(ctx, copyID, NULL, NULL); + abort = set_ref_in_item(ctx, copyID, NULL, NULL); } Callback *cb = &qi->qf_lists[i].qf_qftf_cb; diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 70da0a9ba2..3030ecdfa9 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -311,7 +311,7 @@ func Test_WinScrolled() au WinScrolled * let g:amatch = str2nr(expand('<amatch>')) au WinScrolled * let g:afile = str2nr(expand('<afile>')) END - call writefile(lines, 'Xtest_winscrolled') + call writefile(lines, 'Xtest_winscrolled', 'D') let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6}) call term_sendkeys(buf, ":echo g:scrolled\<CR>") @@ -346,7 +346,36 @@ func Test_WinScrolled() call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000) call StopVimInTerminal(buf) - call delete('Xtest_winscrolled') +endfunc + +func Test_WinScrolled_mouse() + CheckRunVimInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + set mouse=a term=xterm ttymouse=sgr mousetime=200 clipboard= + call setline(1, ['foo']->repeat(32)) + split + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + END + call writefile(lines, 'Xtest_winscrolled_mouse', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10}) + + " With the upper split focused, send a scroll-down event to the unfocused one. + call test_setmouse(7, 1) + call term_sendkeys(buf, "\<ScrollWheelDown>") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^1', term_getline(buf, 10))}, 1000) + + " Again, but this time while we're in insert mode. + call term_sendkeys(buf, "i\<ScrollWheelDown>\<Esc>") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^2', term_getline(buf, 10))}, 1000) + + call StopVimInTerminal(buf) endfunc func Test_WinScrolled_close_curwin() @@ -359,7 +388,7 @@ func Test_WinScrolled_close_curwin() au WinScrolled * close au VimLeave * call writefile(['123456'], 'Xtestout') END - call writefile(lines, 'Xtest_winscrolled_close_curwin') + call writefile(lines, 'Xtest_winscrolled_close_curwin', 'D') let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6}) " This was using freed memory @@ -367,12 +396,64 @@ func Test_WinScrolled_close_curwin() call TermWait(buf) call StopVimInTerminal(buf) + " check the startup script finished to the end call assert_equal(['123456'], readfile('Xtestout')) - - call delete('Xtest_winscrolled_close_curwin') call delete('Xtestout') endfunc +func Test_WinScrolled_once_only() + CheckRunVimInTerminal + + let lines =<< trim END + set cmdheight=2 + call setline(1, ['aaa', 'bbb']) + let trigger_count = 0 + func ShowInfo(id) + echo g:trigger_count g:winid winlayout() + endfunc + + vsplit + split + " use a timer to show the info after a redraw + au WinScrolled * let trigger_count += 1 | let winid = expand('<amatch>') | call timer_start(100, 'ShowInfo') + wincmd j + wincmd l + END + call writefile(lines, 'Xtest_winscrolled_once', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 60, statusoff: 2}) + + call term_sendkeys(buf, "\<C-E>") + call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {}) + + call StopVimInTerminal(buf) +endfunc + +" Check that WinScrolled is not triggered immediately when defined and there +" are split windows. +func Test_WinScrolled_not_when_defined() + CheckRunVimInTerminal + + let lines =<< trim END + call setline(1, ['aaa', 'bbb']) + echo 'nothing happened' + func ShowTriggered(id) + echo 'triggered' + endfunc + END + call writefile(lines, 'Xtest_winscrolled_not', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2}) + call term_sendkeys(buf, ":split\<CR>") + call TermWait(buf) + " use a timer to show the message after redrawing + call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>") + call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {}) + + call term_sendkeys(buf, "\<C-E>") + call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_WinScrolled_long_wrapped() CheckRunVimInTerminal @@ -385,7 +466,7 @@ func Test_WinScrolled_long_wrapped() call setline(1, repeat('foo', height * width)) call cursor(1, height * width) END - call writefile(lines, 'Xtest_winscrolled_long_wrapped') + call writefile(lines, 'Xtest_winscrolled_long_wrapped', 'D') let buf = RunVimInTerminal('-S Xtest_winscrolled_long_wrapped', {'rows': 6}) call term_sendkeys(buf, ":echo g:scrolled\<CR>") @@ -402,8 +483,6 @@ func Test_WinScrolled_long_wrapped() call term_sendkeys(buf, '$') call term_sendkeys(buf, ":echo g:scrolled\<CR>") call WaitForAssert({-> assert_match('^3 ', term_getline(buf, 6))}, 1000) - - call delete('Xtest_winscrolled_long_wrapped') endfunc func Test_WinClosed() @@ -2788,6 +2867,7 @@ func Test_SpellFileMissing_bwipe() call assert_fails('set spell spelllang=0', 'E937:') au! SpellFileMissing + set nospell spelllang=en bwipe endfunc diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim index fae6b1dab7..d4dee38620 100644 --- a/src/nvim/testdir/test_bufline.vim +++ b/src/nvim/testdir/test_bufline.vim @@ -5,12 +5,15 @@ source screendump.vim source check.vim func Test_setbufline_getbufline() + " similar to Test_set_get_bufline() new let b = bufnr('%') hide call assert_equal(0, setbufline(b, 1, ['foo', 'bar'])) call assert_equal(['foo'], getbufline(b, 1)) + call assert_equal('foo', getbufoneline(b, 1)) call assert_equal(['bar'], getbufline(b, '$')) + call assert_equal('bar', getbufoneline(b, '$')) call assert_equal(['foo', 'bar'], getbufline(b, 1, 2)) exe "bd!" b call assert_equal([], getbufline(b, 1, 2)) @@ -34,10 +37,21 @@ func Test_setbufline_getbufline() call assert_equal(0, setbufline(b, 4, ['d', 'e'])) call assert_equal(['c'], b->getbufline(3)) + call assert_equal('c', b->getbufoneline(3)) call assert_equal(['d'], getbufline(b, 4)) + call assert_equal('d', getbufoneline(b, 4)) call assert_equal(['e'], getbufline(b, 5)) + call assert_equal('e', getbufoneline(b, 5)) call assert_equal([], getbufline(b, 6)) call assert_equal([], getbufline(b, 2, 1)) + + if has('job') + call setbufline(b, 2, [function('eval'), #{key: 123}, test_null_job()]) + call assert_equal(["function('eval')", + \ "{'key': 123}", + \ "no process"], + \ getbufline(b, 2, 4)) + endif exe "bwipe! " . b endfunc diff --git a/src/nvim/window.c b/src/nvim/window.c index 54ab9a0471..f25e25e905 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3868,6 +3868,27 @@ void close_others(int message, int forceit) } } +/// Store the relevant window pointers for tab page "tp". To be used before +/// use_tabpage(). +void unuse_tabpage(tabpage_T *tp) +{ + tp->tp_topframe = topframe; + tp->tp_firstwin = firstwin; + tp->tp_lastwin = lastwin; + tp->tp_curwin = curwin; +} + +/// Set the relevant pointers to use tab page "tp". May want to call +/// unuse_tabpage() first. +void use_tabpage(tabpage_T *tp) +{ + curtab = tp; + topframe = curtab->tp_topframe; + firstwin = curtab->tp_firstwin; + lastwin = curtab->tp_lastwin; + curwin = curtab->tp_curwin; +} + // Allocate the first window and put an empty buffer in it. // Only called from main(). void win_alloc_first(void) @@ -3878,11 +3899,8 @@ void win_alloc_first(void) } first_tabpage = alloc_tabpage(); - first_tabpage->tp_topframe = topframe; curtab = first_tabpage; - curtab->tp_firstwin = firstwin; - curtab->tp_lastwin = lastwin; - curtab->tp_curwin = curwin; + unuse_tabpage(first_tabpage); } // Init `aucmd_win`. This can only be done after the first window @@ -4253,10 +4271,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a win_T *next_prevwin = tp->tp_prevwin; tabpage_T *old_curtab = curtab; - curtab = tp; - firstwin = tp->tp_firstwin; - lastwin = tp->tp_lastwin; - topframe = tp->tp_topframe; + use_tabpage(tp); if (old_curtab != curtab) { tabpage_check_windows(old_curtab); @@ -5263,35 +5278,60 @@ void win_new_screen_cols(void) win_reconfig_floats(); // The size of floats might change } -/// Trigger WinScrolled for "curwin" if needed. +/// Make a snapshot of all the window scroll positions and sizes of the current +/// tab page. +void snapshot_windows_scroll_size(void) +{ + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + wp->w_last_topline = wp->w_topline; + wp->w_last_leftcol = wp->w_leftcol; + wp->w_last_skipcol = wp->w_skipcol; + wp->w_last_width = wp->w_width; + wp->w_last_height = wp->w_height; + } +} + +static bool did_initial_scroll_size_snapshot = false; + +void may_make_initial_scroll_size_snapshot(void) +{ + if (!did_initial_scroll_size_snapshot) { + did_initial_scroll_size_snapshot = true; + snapshot_windows_scroll_size(); + } +} + +/// Trigger WinScrolled if any window scrolled or changed size. void may_trigger_winscrolled(void) { static bool recursive = false; - if (recursive || !has_event(EVENT_WINSCROLLED)) { + if (recursive + || !has_event(EVENT_WINSCROLLED) + || !did_initial_scroll_size_snapshot) { return; } - win_T *wp = curwin; - if (wp->w_last_topline != wp->w_topline - || wp->w_last_leftcol != wp->w_leftcol - || wp->w_last_skipcol != wp->w_skipcol - || wp->w_last_width != wp->w_width - || wp->w_last_height != wp->w_height) { - char winid[NUMBUFLEN]; - vim_snprintf(winid, sizeof(winid), "%d", wp->handle); - - recursive = true; - apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer); - recursive = false; - - // an autocmd may close the window, "wp" may be invalid now - if (win_valid_any_tab(wp)) { - wp->w_last_topline = wp->w_topline; - wp->w_last_leftcol = wp->w_leftcol; - wp->w_last_skipcol = wp->w_skipcol; - wp->w_last_width = wp->w_width; - wp->w_last_height = wp->w_height; + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_last_topline != wp->w_topline + || wp->w_last_leftcol != wp->w_leftcol + || wp->w_last_skipcol != wp->w_skipcol + || wp->w_last_width != wp->w_width + || wp->w_last_height != wp->w_height) { + // WinScrolled is triggered only once, even when multiple windows + // scrolled or changed size. Store the current values before + // triggering the event, if a scroll or resize happens as a side + // effect then WinScrolled is triggered again later. + snapshot_windows_scroll_size(); + + char winid[NUMBUFLEN]; + vim_snprintf(winid, sizeof(winid), "%d", wp->handle); + + recursive = true; + apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer); + recursive = false; + + break; } } } diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua index 0fbf58a8e7..3af1791e43 100644 --- a/test/functional/api/proc_spec.lua +++ b/test/functional/api/proc_spec.lua @@ -3,12 +3,12 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq local funcs = helpers.funcs -local iswin = helpers.iswin local neq = helpers.neq local nvim_argv = helpers.nvim_argv local request = helpers.request local retry = helpers.retry local NIL = helpers.NIL +local is_os = helpers.is_os describe('API', function() before_each(clear) @@ -62,7 +62,7 @@ describe('API', function() it('returns process info', function() local pid = funcs.getpid() local pinfo = request('nvim_get_proc', pid) - eq((iswin() and 'nvim.exe' or 'nvim'), pinfo.name) + eq((is_os('win') and 'nvim.exe' or 'nvim'), pinfo.name) eq(pid, pinfo.pid) eq('number', type(pinfo.ppid)) neq(pid, pinfo.ppid) diff --git a/test/functional/api/server_notifications_spec.lua b/test/functional/api/server_notifications_spec.lua index 77a80ac7f3..833d54396b 100644 --- a/test/functional/api/server_notifications_spec.lua +++ b/test/functional/api/server_notifications_spec.lua @@ -5,7 +5,7 @@ local eq, clear, eval, command, nvim, next_msg = local meths = helpers.meths local exec_lua = helpers.exec_lua local retry = helpers.retry -local isCI = helpers.isCI +local is_ci = helpers.is_ci local assert_alive = helpers.assert_alive local skip = helpers.skip @@ -79,7 +79,7 @@ describe('notify', function() end) it('cancels stale events on channel close', function() - skip(isCI(), 'hangs on CI #14083 #15251') + skip(is_ci(), 'hangs on CI #14083 #15251') local catchan = eval("jobstart(['cat'], {'rpc': v:true})") local catpath = eval('exepath("cat")') eq({id=catchan, argv={catpath}, stream='job', mode='rpc', client = {}}, exec_lua ([[ diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 045de94de2..ceff390dc5 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -250,7 +250,7 @@ describe('server -> client', function() pcall(funcs.jobstop, jobid) end) - if helpers.skip(helpers.iswin()) then return end + if helpers.skip(helpers.is_os('win')) then return end it('rpc and text stderr can be combined', function() local status, rv = pcall(funcs.rpcrequest, jobid, 'poll') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 9df73c8d69..3e1aab28ce 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -12,7 +12,6 @@ local exec = helpers.exec local eval = helpers.eval local expect = helpers.expect local funcs = helpers.funcs -local iswin = helpers.iswin local meths = helpers.meths local matches = helpers.matches local pesc = helpers.pesc @@ -400,7 +399,7 @@ describe('API', function() end) it('returns shell |:!| output', function() - local win_lf = iswin() and '\r' or '' + local win_lf = is_os('win') and '\r' or '' eq(':!echo foo\r\n\nfoo'..win_lf..'\n', nvim('command_output', [[!echo foo]])) end) @@ -2125,7 +2124,7 @@ describe('API', function() pty='?', } local event = meths.get_var("opened_event") - if not iswin() then + if not is_os('win') then info.pty = event.info.pty neq(nil, string.match(info.pty, "^/dev/")) end @@ -2141,7 +2140,7 @@ describe('API', function() stream = 'job', id = 4, argv = ( - iswin() and { + is_os('win') and { eval('&shell'), '/s', '/c', @@ -2163,7 +2162,7 @@ describe('API', function() -- :terminal with args + stopped process. eq(1, eval('jobstop(&channel)')) eval('jobwait([&channel], 1000)') -- Wait. - expected2.pty = (iswin() and '?' or '') -- pty stream was closed. + expected2.pty = (is_os('win') and '?' or '') -- pty stream was closed. eq(expected2, eval('nvim_get_chan_info(&channel)')) end) end) @@ -2724,7 +2723,7 @@ describe('API', function() eq({}, meths.get_runtime_file("foobarlang/", true)) end) it('can handle bad patterns', function() - skip(iswin()) + skip(is_os('win')) eq("Vim:E220: Missing }.", pcall_err(meths.get_runtime_file, "{", false)) diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua index 45dc06b39b..828cffa460 100644 --- a/test/functional/autocmd/dirchanged_spec.lua +++ b/test/functional/autocmd/dirchanged_spec.lua @@ -1,12 +1,12 @@ local lfs = require('lfs') -local h = require('test.functional.helpers')(after_each) +local helpers = require('test.functional.helpers')(after_each) -local clear = h.clear -local command = h.command -local eq = h.eq -local eval = h.eval -local request = h.request -local iswin = h.iswin +local clear = helpers.clear +local command = helpers.command +local eq = helpers.eq +local eval = helpers.eval +local request = helpers.request +local is_os = helpers.is_os describe('autocmd DirChanged and DirChangedPre', function() local curdir = string.gsub(lfs.currentdir(), '\\', '/') @@ -21,8 +21,8 @@ describe('autocmd DirChanged and DirChangedPre', function() curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR3', } - setup(function() for _, dir in pairs(dirs) do h.mkdir(dir) end end) - teardown(function() for _, dir in pairs(dirs) do h.rmdir(dir) end end) + setup(function() for _, dir in pairs(dirs) do helpers.mkdir(dir) end end) + teardown(function() for _, dir in pairs(dirs) do helpers.rmdir(dir) end end) before_each(function() clear() @@ -159,7 +159,7 @@ describe('autocmd DirChanged and DirChangedPre', function() eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) - if iswin() then + if is_os('win') then command('lcd '..win_dirs[1]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) @@ -182,7 +182,7 @@ describe('autocmd DirChanged and DirChangedPre', function() eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) - if iswin() then + if is_os('win') then command('tcd '..win_dirs[2]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) @@ -204,7 +204,7 @@ describe('autocmd DirChanged and DirChangedPre', function() eq(3, eval('g:cdprecount')) eq(3, eval('g:cdcount')) - if iswin() then + if is_os('win') then command('cd '..win_dirs[3]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) @@ -229,7 +229,7 @@ describe('autocmd DirChanged and DirChangedPre', function() eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) - if iswin() then + if is_os('win') then command('split '..win_dirs[1]..'/baz') eq({}, eval('g:evpre')) eq({}, eval('g:ev')) @@ -278,7 +278,7 @@ describe('autocmd DirChanged and DirChangedPre', function() eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - if iswin() then + if is_os('win') then command('tabnew') -- tab 3 eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event diff --git a/test/functional/autocmd/focus_spec.lua b/test/functional/autocmd/focus_spec.lua index b5fc6b7600..024dccbe8e 100644 --- a/test/functional/autocmd/focus_spec.lua +++ b/test/functional/autocmd/focus_spec.lua @@ -6,7 +6,7 @@ local nvim_prog = helpers.nvim_prog local feed_command = helpers.feed_command local feed_data = thelpers.feed_data -if helpers.skip(helpers.iswin()) then return end +if helpers.skip(helpers.is_os('win')) then return end describe('autoread TUI FocusGained/FocusLost', function() local f1 = 'xtest-foo' diff --git a/test/functional/autocmd/signal_spec.lua b/test/functional/autocmd/signal_spec.lua index bbe1c186b2..738064090a 100644 --- a/test/functional/autocmd/signal_spec.lua +++ b/test/functional/autocmd/signal_spec.lua @@ -5,10 +5,10 @@ local command = helpers.command local eq = helpers.eq local funcs = helpers.funcs local next_msg = helpers.next_msg -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip -if skip(iswin(), 'Only applies to POSIX systems') then return end +if skip(is_os('win'), 'Only applies to POSIX systems') then return end local function posix_kill(signame, pid) os.execute('kill -s '..signame..' -- '..pid..' >/dev/null') diff --git a/test/functional/autocmd/termxx_spec.lua b/test/functional/autocmd/termxx_spec.lua index 5601965bd9..4717b1fa2e 100644 --- a/test/functional/autocmd/termxx_spec.lua +++ b/test/functional/autocmd/termxx_spec.lua @@ -10,8 +10,8 @@ local ok = helpers.ok local feed = helpers.feed local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive -local iswin = helpers.iswin local skip = helpers.skip +local is_os = helpers.is_os describe('autocmd TermClose', function() before_each(function() @@ -48,7 +48,7 @@ describe('autocmd TermClose', function() end) it('triggers when long-running terminal job gets stopped', function() - nvim('set_option', 'shell', iswin() and 'cmd.exe' or 'sh') + nvim('set_option', 'shell', is_os('win') and 'cmd.exe' or 'sh') command('autocmd TermClose * let g:test_termclose = 23') command('terminal') command('call jobstop(b:terminal_job_id)') @@ -56,7 +56,7 @@ describe('autocmd TermClose', function() end) it('kills job trapping SIGTERM', function() - skip(iswin()) + skip(is_os('win')) nvim('set_option', 'shell', 'sh') nvim('set_option', 'shellcmdflag', '-c') command([[ let g:test_job = jobstart('trap "" TERM && echo 1 && sleep 60', { ]] @@ -76,7 +76,7 @@ describe('autocmd TermClose', function() end) it('kills PTY job trapping SIGHUP and SIGTERM', function() - skip(iswin()) + skip(is_os('win')) nvim('set_option', 'shell', 'sh') nvim('set_option', 'shellcmdflag', '-c') command([[ let g:test_job = jobstart('trap "" HUP TERM && echo 1 && sleep 60', { ]] diff --git a/test/functional/autocmd/winscrolled_spec.lua b/test/functional/autocmd/winscrolled_spec.lua index 12b8e7c42d..5a426fcfa1 100644 --- a/test/functional/autocmd/winscrolled_spec.lua +++ b/test/functional/autocmd/winscrolled_spec.lua @@ -1,8 +1,10 @@ local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') local clear = helpers.clear local eq = helpers.eq local eval = helpers.eval +local exec = helpers.exec local command = helpers.command local feed = helpers.feed local meths = helpers.meths @@ -89,11 +91,72 @@ describe('WinScrolled', function() end) end) -it('closing window in WinScrolled does not cause use-after-free #13265', function() - local lines = {'aaa', 'bbb'} - meths.buf_set_lines(0, 0, -1, true, lines) - command('vsplit') - command('autocmd WinScrolled * close') - feed('<C-E>') - assert_alive() +describe('WinScrolled', function() + -- oldtest: Test_WinScrolled_mouse() + it('is triggered by mouse scrolling in another window', function() + local screen = Screen.new(75, 10) + screen:attach() + exec([[ + set nowrap scrolloff=0 + set mouse=a + call setline(1, ['foo']->repeat(32)) + split + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + ]]) + eq(0, eval('g:scrolled')) + + -- With the upper split focused, send a scroll-down event to the unfocused one. + meths.input_mouse('wheel', 'down', '', 0, 6, 0) + eq(1, eval('g:scrolled')) + + -- Again, but this time while we're in insert mode. + feed('i') + meths.input_mouse('wheel', 'down', '', 0, 6, 0) + feed('<Esc>') + eq(2, eval('g:scrolled')) + end) + + -- oldtest: Test_WinScrolled_close_curwin() + it('closing window does not cause use-after-free #13265', function() + exec([[ + set nowrap scrolloff=0 + call setline(1, ['aaa', 'bbb']) + vsplit + au WinScrolled * close + ]]) + + -- This was using freed memory + feed('<C-E>') + assert_alive() + end) + + it('is triggered by mouse scrolling in unfocused floating window #18222', function() + local screen = Screen.new(80, 24) + screen:attach() + local buf = meths.create_buf(true, true) + meths.buf_set_lines(buf, 0, -1, false, {'a', 'b', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}) + local win = meths.open_win(buf, false, { + height = 5, + width = 10, + col = 0, + row = 1, + relative = 'editor', + style = 'minimal' + }) + exec([[ + let g:scrolled = 0 + autocmd WinScrolled * let g:scrolled += 1 + autocmd WinScrolled * let g:amatch = expand('<amatch>') + ]]) + eq(0, eval('g:scrolled')) + + meths.input_mouse('wheel', 'down', '', 0, 3, 3) + eq(1, eval('g:scrolled')) + eq(tostring(win.id), eval('g:amatch')) + + meths.input_mouse('wheel', 'down', '', 0, 3, 3) + eq(2, eval('g:scrolled')) + eq(tostring(win.id), eval('g:amatch')) + end) end) diff --git a/test/functional/core/channels_spec.lua b/test/functional/core/channels_spec.lua index 63bd85ff43..8275575c24 100644 --- a/test/functional/core/channels_spec.lua +++ b/test/functional/core/channels_spec.lua @@ -1,5 +1,4 @@ local helpers = require('test.functional.helpers')(after_each) -local uname = helpers.uname local clear, eq, eval, next_msg, ok, source = helpers.clear, helpers.eq, helpers.eval, helpers.next_msg, helpers.ok, helpers.source local command, funcs, meths = helpers.command, helpers.funcs, helpers.meths @@ -12,7 +11,6 @@ local retry = helpers.retry local expect_twostreams = helpers.expect_twostreams local assert_alive = helpers.assert_alive local pcall_err = helpers.pcall_err -local iswin = helpers.iswin local skip = helpers.skip describe('channels', function() @@ -147,7 +145,7 @@ describe('channels', function() end it('can use stdio channel with pty', function() - skip(iswin()) + skip(is_os('win')) source([[ let g:job_opts = { \ 'on_stdout': function('OnEvent'), @@ -180,8 +178,7 @@ describe('channels', function() command("call chansend(id, 'incomplet\004')") - local is_bsd = not not string.find(uname(), 'bsd') - local bsdlike = is_bsd or is_os('mac') + local bsdlike = is_os('bsd') or is_os('mac') local extra = bsdlike and "^D\008\008" or "" expect_twoline(id, "stdout", "incomplet"..extra, "[1, ['incomplet'], 'stdin']", true) @@ -201,7 +198,7 @@ describe('channels', function() it('stdio channel can use rpc and stderr simultaneously', function() - skip(iswin()) + skip(is_os('win')) source([[ let g:job_opts = { \ 'on_stderr': function('OnEvent'), diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua index 00b9074e29..51189b7c32 100644 --- a/test/functional/core/fileio_spec.lua +++ b/test/functional/core/fileio_spec.lua @@ -21,14 +21,14 @@ local read_file = helpers.read_file local tmpname = helpers.tmpname local trim = helpers.trim local currentdir = helpers.funcs.getcwd -local iswin = helpers.iswin local assert_alive = helpers.assert_alive local expect_exit = helpers.expect_exit local write_file = helpers.write_file local Screen = require('test.functional.ui.screen') local feed_command = helpers.feed_command -local isCI = helpers.isCI local skip = helpers.skip +local is_os = helpers.is_os +local is_ci = helpers.is_ci describe('fileio', function() before_each(function() @@ -90,7 +90,7 @@ describe('fileio', function() end) it('backup #9709', function() - skip(isCI('cirrus')) + skip(is_ci('cirrus')) clear({ args={ '-i', 'Xtest_startup_shada', '--cmd', 'set directory=Xtest_startup_swapdir' } }) @@ -110,7 +110,7 @@ describe('fileio', function() end) it('backup with full path #11214', function() - skip(isCI('cirrus')) + skip(is_ci('cirrus')) clear() mkdir('Xtest_backupdir') command('set backup') @@ -123,7 +123,7 @@ describe('fileio', function() -- Backup filename = fullpath, separators replaced with "%". local backup_file_name = string.gsub(currentdir()..'/Xtest_startup_file1', - iswin() and '[:/\\]' or '/', '%%') .. '~' + is_os('win') and '[:/\\]' or '/', '%%') .. '~' local foo_contents = trim(read_file('Xtest_backupdir/'..backup_file_name)) local foobar_contents = trim(read_file('Xtest_startup_file1')) @@ -132,7 +132,7 @@ describe('fileio', function() end) it('backup symlinked files #11349', function() - skip(isCI('cirrus')) + skip(is_ci('cirrus')) clear() local initial_content = 'foo' @@ -154,7 +154,7 @@ describe('fileio', function() it('backup symlinked files in first avialable backupdir #11349', function() - skip(isCI('cirrus')) + skip(is_ci('cirrus')) clear() local initial_content = 'foo' @@ -299,7 +299,7 @@ describe('tmpdir', function() end) -- "…/nvim.<user>/" has wrong permissions: - skip(iswin(), 'TODO(justinmk): need setfperm/getfperm on Windows. #8244') + skip(is_os('win'), 'TODO(justinmk): need setfperm/getfperm on Windows. #8244') os.remove(testlog) os.remove(tmproot) mkdir(tmproot) diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 4e5c4ca351..1bae626b98 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -13,7 +13,6 @@ local retry = helpers.retry local meths = helpers.meths local NIL = helpers.NIL local poke_eventloop = helpers.poke_eventloop -local iswin = helpers.iswin local get_pathsep = helpers.get_pathsep local pathroot = helpers.pathroot local exec_lua = helpers.exec_lua @@ -24,6 +23,7 @@ local pcall_err = helpers.pcall_err local matches = helpers.matches local Screen = require('test.functional.ui.screen') local skip = helpers.skip +local is_os = helpers.is_os describe('jobs', function() local channel @@ -56,7 +56,7 @@ describe('jobs', function() it('must specify env option as a dict', function() command("let g:job_opts.env = v:true") local _, err = pcall(function() - if iswin() then + if is_os('win') then nvim('command', "let j = jobstart('set', g:job_opts)") else nvim('command', "let j = jobstart('env', g:job_opts)") @@ -69,7 +69,7 @@ describe('jobs', function() nvim('command', "let $VAR = 'abc'") nvim('command', "let $TOTO = 'goodbye world'") nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}") - if iswin() then + if is_os('win') then nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) else nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]]) @@ -88,12 +88,12 @@ describe('jobs', function() end) it('append environment with pty #env', function() - skip(iswin()) + skip(is_os('win')) nvim('command', "let $VAR = 'abc'") nvim('command', "let $TOTO = 'goodbye world'") nvim('command', "let g:job_opts.pty = v:true") nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}") - if iswin() then + if is_os('win') then nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) else nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]]) @@ -123,7 +123,7 @@ describe('jobs', function() -- -- Rather than expecting a completely empty environment, ensure that $VAR -- is *not* in the environment but $TOTO is. - if iswin() then + if is_os('win') then nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) expect_msg_seq({ {'notification', 'stdout', {0, {'hello world %VAR%', ''}}} @@ -142,7 +142,7 @@ describe('jobs', function() -- Since $Toto is being set in the job, it should take precedence over the -- global $TOTO on Windows nvim('command', "let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}") - if iswin() then + if is_os('win') then nvim('command', [[let j = jobstart('set | find /I "toto="', g:job_opts)]]) else nvim('command', [[let j = jobstart('env | grep -i toto=', g:job_opts)]]) @@ -151,7 +151,7 @@ describe('jobs', function() nvim('command', "let g:output = Normalize(g:job_opts.stdout)") local actual = eval('g:output') local expected - if iswin() then + if is_os('win') then -- Toto is normalized to TOTO so we can detect duplicates, and because -- Windows doesn't care about case expected = {'TOTO=def', ''} @@ -165,7 +165,7 @@ describe('jobs', function() it('uses &shell and &shellcmdflag if passed a string', function() nvim('command', "let $VAR = 'abc'") - if iswin() then + if is_os('win') then nvim('command', "let j = jobstart('echo %VAR%', g:job_opts)") else nvim('command', "let j = jobstart('echo $VAR', g:job_opts)") @@ -177,7 +177,7 @@ describe('jobs', function() it('changes to given / directory', function() nvim('command', "let g:job_opts.cwd = '/'") - if iswin() then + if is_os('win') then nvim('command', "let j = jobstart('cd', g:job_opts)") else nvim('command', "let j = jobstart('pwd', g:job_opts)") @@ -192,7 +192,7 @@ describe('jobs', function() local dir = eval("resolve(tempname())"):gsub("/", get_pathsep()) mkdir(dir) nvim('command', "let g:job_opts.cwd = '" .. dir .. "'") - if iswin() then + if is_os('win') then nvim('command', "let j = jobstart('cd', g:job_opts)") else nvim('command', "let j = jobstart('pwd', g:job_opts)") @@ -216,7 +216,7 @@ describe('jobs', function() local dir = eval('resolve(tempname())."-bogus"') local _, err = pcall(function() nvim('command', "let g:job_opts.cwd = '" .. dir .. "'") - if iswin() then + if is_os('win') then nvim('command', "let j = jobstart('cd', g:job_opts)") else nvim('command', "let j = jobstart('pwd', g:job_opts)") @@ -226,7 +226,7 @@ describe('jobs', function() end) it('error on non-executable `cwd`', function() - skip(iswin(), 'Not applicable for Windows') + skip(is_os('win'), 'Not applicable for Windows') local dir = 'Xtest_not_executable_dir' mkdir(dir) @@ -249,7 +249,7 @@ describe('jobs', function() end local executable_jobid = new_job() - local exe = iswin() and './test/functional/fixtures' or './test/functional/fixtures/non_executable.txt' + local exe = is_os('win') and './test/functional/fixtures' or './test/functional/fixtures/non_executable.txt' eq("Vim:E475: Invalid value for argument cmd: '"..exe.."' is not executable", pcall_err(eval, "jobstart(['"..exe.."'])")) eq("", eval("v:errmsg")) @@ -703,7 +703,7 @@ describe('jobs', function() describe('jobwait', function() before_each(function() - if iswin() then + if is_os('win') then helpers.set_shell_powershell() end end) @@ -787,7 +787,7 @@ describe('jobs', function() feed_command('call rpcnotify(g:channel, "ready") | '.. 'call rpcnotify(g:channel, "wait", '.. 'jobwait([jobstart("'.. - (iswin() and 'Start-Sleep 10' or 'sleep 10').. + (is_os('win') and 'Start-Sleep 10' or 'sleep 10').. '; exit 55")]))') eq({'notification', 'ready', {}}, next_msg()) feed('<c-c>') @@ -798,7 +798,7 @@ describe('jobs', function() feed_command('call rpcnotify(g:channel, "ready") | '.. 'call rpcnotify(g:channel, "wait", '.. 'jobwait([jobstart("'.. - (iswin() and 'Start-Sleep 10' or 'sleep 10').. + (is_os('win') and 'Start-Sleep 10' or 'sleep 10').. '; exit 55")], 10000))') eq({'notification', 'ready', {}}, next_msg()) feed('<c-c>') @@ -806,7 +806,7 @@ describe('jobs', function() end) it('can be called recursively', function() - skip(iswin(), "TODO: Need `cat`") + skip(is_os('win'), "TODO: Need `cat`") source([[ let g:opts = {} let g:counter = 0 @@ -931,7 +931,7 @@ describe('jobs', function() -- ..c.."', '-c', '"..c.."'])") -- Create child with several descendants. - if iswin() then + if is_os('win') then source([[ function! s:formatprocs(pid, prefix) let result = '' @@ -980,13 +980,13 @@ describe('jobs', function() endfunction ]]) end - local sleep_cmd = (iswin() + local sleep_cmd = (is_os('win') and 'ping -n 31 127.0.0.1' or 'sleep 30') local j = eval("jobstart('"..sleep_cmd..' | '..sleep_cmd..' | '..sleep_cmd.."')") local ppid = funcs.jobpid(j) local children - if iswin() then + if is_os('win') then local status, result = pcall(retry, nil, nil, function() children = meths.get_proc_children(ppid) -- On Windows conhost.exe may exist, and @@ -1007,7 +1007,7 @@ describe('jobs', function() -- Assert that nvim_get_proc() sees the children. for _, child_pid in ipairs(children) do local info = meths.get_proc(child_pid) - -- eq((iswin() and 'nvim.exe' or 'nvim'), info.name) + -- eq((is_os('win') and 'nvim.exe' or 'nvim'), info.name) eq(ppid, info.ppid) end -- Kill the root of the tree. @@ -1028,7 +1028,7 @@ describe('jobs', function() end) describe('running tty-test program', function() - if skip(iswin()) then return end + if skip(is_os('win')) then return end local function next_chunk() local rv while true do @@ -1125,7 +1125,7 @@ describe("pty process teardown", function() end) it("does not prevent/delay exit. #4798 #4900", function() - skip(iswin()) + skip(is_os('win')) -- Use a nested nvim (in :term) to test without --headless. feed_command(":terminal '"..helpers.nvim_prog .."' -u NONE -i NONE --cmd '"..nvim_set.."' " diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua index 782a03bfed..53461f505a 100644 --- a/test/functional/core/main_spec.lua +++ b/test/functional/core/main_spec.lua @@ -9,7 +9,7 @@ local clear = helpers.clear local funcs = helpers.funcs local nvim_prog_abs = helpers.nvim_prog_abs local write_file = helpers.write_file -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip describe('Command-line option', function() @@ -51,7 +51,7 @@ describe('Command-line option', function() eq(#('100500\n'), attrs.size) end) it('does not crash after reading from stdin in non-headless mode', function() - skip(iswin()) + skip(is_os('win')) local screen = Screen.new(40, 8) screen:attach() local args = { diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua index 61fae7622c..a786887bbd 100644 --- a/test/functional/core/path_spec.lua +++ b/test/functional/core/path_spec.lua @@ -3,16 +3,16 @@ local clear = helpers.clear local eq = helpers.eq local eval = helpers.eval local command = helpers.command -local iswin = helpers.iswin local insert = helpers.insert local feed = helpers.feed +local is_os = helpers.is_os describe('path collapse', function() local targetdir local expected_path local function join_path(...) - local pathsep = (iswin() and '\\' or '/') + local pathsep = (is_os('win') and '\\' or '/') return table.concat({...}, pathsep) end diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 2084d365a5..bab339e253 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -20,11 +20,11 @@ local read_file = helpers.read_file local retry = helpers.retry local rmdir = helpers.rmdir local sleep = helpers.sleep -local iswin = helpers.iswin local startswith = helpers.startswith local write_file = helpers.write_file local meths = helpers.meths local alter_slashes = helpers.alter_slashes +local is_os = helpers.is_os local testfile = 'Xtest_startuptime' after_each(function() @@ -79,7 +79,7 @@ describe('startup', function() it('in a TTY: has("ttyin")==1 has("ttyout")==1', function() local screen = Screen.new(25, 4) screen:attach() - if iswin() then + if is_os('win') then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal @@ -95,7 +95,7 @@ describe('startup', function() ]]) end) it('output to pipe: has("ttyin")==1 has("ttyout")==0', function() - if iswin() then + if is_os('win') then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal @@ -111,7 +111,7 @@ describe('startup', function() end) end) it('input from pipe: has("ttyin")==0 has("ttyout")==1', function() - if iswin() then + if is_os('win') then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal @@ -130,7 +130,7 @@ describe('startup', function() it('input from pipe (implicit) #7679', function() local screen = Screen.new(25, 4) screen:attach() - if iswin() then + if is_os('win') then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal @@ -665,7 +665,7 @@ describe('runtime:', function() end) it('loads plugin/*.lua from site packages', function() - local nvimdata = iswin() and "nvim-data" or "nvim" + local nvimdata = is_os('win') and "nvim-data" or "nvim" local plugin_path = table.concat({xdata, nvimdata, 'site', 'pack', 'xa', 'start', 'yb'}, pathsep) local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep) local plugin_after_path = table.concat({plugin_path, 'after', 'plugin'}, pathsep) diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua index d2135d0613..5ed71651c7 100644 --- a/test/functional/ex_cmds/cd_spec.lua +++ b/test/functional/ex_cmds/cd_spec.lua @@ -9,8 +9,8 @@ local clear = helpers.clear local command = helpers.command local exc_exec = helpers.exc_exec local pathsep = helpers.get_pathsep() -local iswin = helpers.iswin local skip = helpers.skip +local is_os = helpers.is_os -- These directories will be created for testing local directories = { @@ -281,7 +281,7 @@ describe("getcwd()", function () end) it("returns empty string if working directory does not exist", function() - skip(iswin()) + skip(is_os('win')) command("cd "..directories.global) command("call delete('../"..directories.global.."', 'd')") eq("", helpers.eval("getcwd()")) diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua index b7ff6a7bf7..0a0c7ca410 100644 --- a/test/functional/ex_cmds/mksession_spec.lua +++ b/test/functional/ex_cmds/mksession_spec.lua @@ -5,7 +5,6 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command local get_pathsep = helpers.get_pathsep -local iswin = helpers.iswin local eq = helpers.eq local neq = helpers.neq local funcs = helpers.funcs @@ -15,6 +14,7 @@ local rmdir = helpers.rmdir local sleep = helpers.sleep local meths = helpers.meths local skip = helpers.skip +local is_os = helpers.is_os local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec' @@ -178,7 +178,7 @@ describe(':mksession', function() command('cd ' .. cwd_dir) command('mksession ' .. session_path) command('%bwipeout!') - if iswin() then + if is_os('win') then sleep(100) -- Make sure all child processes have exited. end @@ -189,13 +189,13 @@ describe(':mksession', function() local expected_cwd = cwd_dir .. '/' .. tab_dir matches('^term://' .. pesc(expected_cwd) .. '//%d+:', funcs.expand('%')) command('%bwipeout!') - if iswin() then + if is_os('win') then sleep(100) -- Make sure all child processes have exited. end end) it('restores CWD for :terminal buffer at root directory #16988', function() - skip(iswin(), 'N/A for Windows') + skip(is_os('win'), 'N/A for Windows') local screen local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '') diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua index 10ebefd8cd..64c3464be7 100644 --- a/test/functional/ex_cmds/source_spec.lua +++ b/test/functional/ex_cmds/source_spec.lua @@ -14,9 +14,9 @@ local eval = helpers.eval local exec_capture = helpers.exec_capture local neq = helpers.neq local matches = helpers.matches -local iswin = helpers.iswin local mkdir = helpers.mkdir local rmdir = helpers.rmdir +local is_os = helpers.is_os describe(':source', function() before_each(function() @@ -44,7 +44,7 @@ describe(':source', function() end) it("changing 'shellslash' changes the result of expand()", function() - if not iswin() then + if not is_os('win') then pending("'shellslash' only works on Windows") return end diff --git a/test/functional/ex_cmds/write_spec.lua b/test/functional/ex_cmds/write_spec.lua index e2a6b6460d..1ccd27875e 100644 --- a/test/functional/ex_cmds/write_spec.lua +++ b/test/functional/ex_cmds/write_spec.lua @@ -8,9 +8,9 @@ local command = helpers.command local feed_command = helpers.feed_command local funcs = helpers.funcs local meths = helpers.meths -local iswin = helpers.iswin -local isCI = helpers.isCI local skip = helpers.skip +local is_os = helpers.is_os +local is_ci = helpers.is_ci local fname = 'Xtest-functional-ex_cmds-write' local fname_bak = fname .. '~' @@ -39,7 +39,7 @@ describe(':write', function() it('&backupcopy=auto preserves symlinks', function() command('set backupcopy=auto') write_file('test_bkc_file.txt', 'content0') - if iswin() then + if is_os('win') then command("silent !mklink test_bkc_link.txt test_bkc_file.txt") else command("silent !ln -s test_bkc_file.txt test_bkc_link.txt") @@ -57,10 +57,10 @@ describe(':write', function() end) it('&backupcopy=no replaces symlink with new file', function() - skip(isCI('cirrus')) + skip(is_ci('cirrus')) command('set backupcopy=no') write_file('test_bkc_file.txt', 'content0') - if iswin() then + if is_os('win') then command("silent !mklink test_bkc_link.txt test_bkc_file.txt") else command("silent !ln -s test_bkc_file.txt test_bkc_link.txt") @@ -79,7 +79,7 @@ describe(':write', function() it("appends FIFO file", function() -- mkfifo creates read-only .lnk files on Windows - if iswin() or eval("executable('mkfifo')") == 0 then + if is_os('win') or eval("executable('mkfifo')") == 0 then pending('missing "mkfifo" command') end @@ -112,7 +112,7 @@ describe(':write', function() eq(1, eval("filereadable('test/write/p_opt.txt')")) eq(('Vim(write):E32: No file name'), pcall_err(command, 'write ++p test_write/')) - if not iswin() then + if not is_os('win') then eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'), pcall_err(command, 'write ++p .')) eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'), @@ -121,11 +121,11 @@ describe(':write', function() end) it('errors out correctly', function() - skip(isCI('cirrus')) + skip(is_ci('cirrus')) command('let $HOME=""') eq(funcs.fnamemodify('.', ':p:h'), funcs.fnamemodify('.', ':p:h:~')) -- Message from check_overwrite - if not iswin() then + if not is_os('win') then eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'), pcall_err(command, 'write .')) end @@ -144,7 +144,7 @@ describe(':write', function() funcs.setfperm(fname, 'r--------') eq('Vim(write):E505: "Xtest-functional-ex_cmds-write" is read-only (add ! to override)', pcall_err(command, 'write')) - if iswin() then + if is_os('win') then eq(0, os.execute('del /q/f ' .. fname)) eq(0, os.execute('rd /q/s ' .. fname_bak)) else @@ -152,7 +152,7 @@ describe(':write', function() eq(true, os.remove(fname_bak)) end write_file(fname_bak, 'TTYX') - skip(iswin(), [[FIXME: exc_exec('write!') outputs 0 in Windows]]) + skip(is_os('win'), [[FIXME: exc_exec('write!') outputs 0 in Windows]]) lfs.link(fname_bak .. ('/xxxxx'):rep(20), fname, true) eq('Vim(write):E166: Can\'t open linked file for writing', pcall_err(command, 'write!')) diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua index 7c00daf1d7..861a977ea6 100644 --- a/test/functional/ex_cmds/wviminfo_spec.lua +++ b/test/functional/ex_cmds/wviminfo_spec.lua @@ -3,14 +3,14 @@ local lfs = require('lfs') local clear = helpers.clear local command, eq, neq, write_file = helpers.command, helpers.eq, helpers.neq, helpers.write_file -local iswin = helpers.iswin local read_file = helpers.read_file +local is_os = helpers.is_os describe(':wshada', function() local shada_file = 'wshada_test' before_each(function() - clear{args={'-i', iswin() and 'nul' or '/dev/null', + clear{args={'-i', is_os('win') and 'nul' or '/dev/null', -- Need 'swapfile' for these tests. '--cmd', 'set swapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'}, args_rm={'-n', '-i', '--cmd'}} diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 1cd632f00b..ca59eb3182 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -54,7 +54,6 @@ if module.nvim_dir == module.nvim_prog then module.nvim_dir = "." end -local iswin = global_helpers.iswin local prepend_argv if os.getenv('VALGRIND') then @@ -557,7 +556,7 @@ function module.source(code) end function module.has_powershell() - return module.eval('executable("'..(iswin() and 'powershell' or 'pwsh')..'")') == 1 + return module.eval('executable("'..(is_os('win') and 'powershell' or 'pwsh')..'")') == 1 end --- Sets Nvim shell to powershell. @@ -570,9 +569,9 @@ function module.set_shell_powershell(fake) if not fake then assert(found) end - local shell = found and (iswin() and 'powershell' or 'pwsh') or module.testprg('pwsh-test') + local shell = found and (is_os('win') and 'powershell' or 'pwsh') or module.testprg('pwsh-test') local set_encoding = '[Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new();' - local cmd = set_encoding..'Remove-Item -Force '..table.concat(iswin() + local cmd = set_encoding..'Remove-Item -Force '..table.concat(is_os('win') and {'alias:cat', 'alias:echo', 'alias:sleep', 'alias:sort'} or {'alias:echo'}, ',')..';' module.exec([[ @@ -854,13 +853,13 @@ function module.exec_lua(code, ...) end function module.get_pathsep() - return iswin() and '\\' or '/' + return is_os('win') and '\\' or '/' end --- Gets the filesystem root dir, namely "/" or "C:/". function module.pathroot() local pathsep = package.config:sub(1,1) - return iswin() and (module.nvim_dir:sub(1,2)..pathsep) or '/' + return is_os('win') and (module.nvim_dir:sub(1,2)..pathsep) or '/' end --- Gets the full `…/build/bin/{name}` path of a test program produced by @@ -868,7 +867,7 @@ end --- --- @param name (string) Name of the test program. function module.testprg(name) - local ext = module.iswin() and '.exe' or '' + local ext = module.is_os('win') and '.exe' or '' return ('%s/%s%s'):format(module.nvim_dir, name, ext) end @@ -895,7 +894,7 @@ function module.missing_provider(provider) end function module.alter_slashes(obj) - if not iswin() then + if not is_os('win') then return obj end if type(obj) == 'string' then @@ -913,7 +912,7 @@ function module.alter_slashes(obj) end local load_factor = 1 -if global_helpers.isCI() then +if global_helpers.is_ci() then -- Compute load factor only once (but outside of any tests). module.clear() module.request('nvim_command', 'source src/nvim/testdir/load.vim') @@ -946,14 +945,14 @@ end -- Kill process with given pid function module.os_kill(pid) - return os.execute((iswin() + return os.execute((is_os('win') and 'taskkill /f /t /pid '..pid..' > nul' or 'kill -9 '..pid..' > /dev/null')) end -- Create folder with non existing parents function module.mkdir_p(path) - return os.execute((iswin() + return os.execute((is_os('win') and 'mkdir '..path or 'mkdir -p '..path)) end diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua index 0fa9290f3c..7ae851467f 100644 --- a/test/functional/legacy/011_autocommands_spec.lua +++ b/test/functional/legacy/011_autocommands_spec.lua @@ -18,11 +18,11 @@ local clear, feed_command, expect, eq, neq, dedent, write_file, feed = helpers.clear, helpers.feed_command, helpers.expect, helpers.eq, helpers.neq, helpers.dedent, helpers.write_file, helpers.feed local command = helpers.command -local iswin = helpers.iswin local read_file = helpers.read_file +local is_os = helpers.is_os local function has_gzip() - local null = iswin() and 'nul' or '/dev/null' + local null = is_os('win') and 'nul' or '/dev/null' return os.execute('gzip --help >' .. null .. ' 2>&1') == 0 end diff --git a/test/functional/legacy/025_jump_tag_hidden_spec.lua b/test/functional/legacy/025_jump_tag_hidden_spec.lua index dd89a3680e..15bd56a601 100644 --- a/test/functional/legacy/025_jump_tag_hidden_spec.lua +++ b/test/functional/legacy/025_jump_tag_hidden_spec.lua @@ -23,7 +23,7 @@ describe('jump to a tag with hidden set', function() feed_command('set hidden') -- Create a link from test25.dir to the current directory. - if helpers.iswin() then + if helpers.is_os('win') then feed_command('!rd /q/s test25.dir') feed_command('!mklink /j test25.dir .') else @@ -33,7 +33,7 @@ describe('jump to a tag with hidden set', function() -- Create tags.text, with the current directory name inserted. feed_command('/tags line') - feed_command('r !' .. (helpers.iswin() and 'cd' or 'pwd')) + feed_command('r !' .. (helpers.is_os('win') and 'cd' or 'pwd')) feed('d$/test<cr>') feed('hP:.w! tags.test<cr>') @@ -44,7 +44,7 @@ describe('jump to a tag with hidden set', function() feed('G<C-]> x:yank a<cr>') feed_command("call delete('tags.test')") feed_command("call delete('Xxx')") - if helpers.iswin() then + if helpers.is_os('win') then feed_command('!rd /q test25.dir') else feed_command('!rm -f test25.dir') diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua index dd5a26ad3b..a62dc4d4c8 100644 --- a/test/functional/legacy/097_glob_path_spec.lua +++ b/test/functional/legacy/097_glob_path_spec.lua @@ -10,7 +10,7 @@ describe('glob() and globpath()', function() setup(clear) setup(function() - if helpers.iswin() then + if helpers.is_os('win') then os.execute("md sautest\\autoload") os.execute(".>sautest\\autoload\\Test104.vim 2>nul") os.execute(".>sautest\\autoload\\footest.vim 2>nul") @@ -28,7 +28,7 @@ describe('glob() and globpath()', function() -- Consistent sorting of file names command('set nofileignorecase') - if helpers.iswin() then + if helpers.is_os('win') then command([[$put =glob('Xxx{')]]) command([[$put =glob('Xxx$')]]) @@ -72,7 +72,7 @@ describe('glob() and globpath()', function() end) teardown(function() - if helpers.iswin() then + if helpers.is_os('win') then os.execute('del /q/f Xxx{ Xxx$') os.execute('rd /q /s sautest') else diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua index 4ba4c8d356..cefcd6c6c4 100644 --- a/test/functional/legacy/delete_spec.lua +++ b/test/functional/legacy/delete_spec.lua @@ -48,7 +48,7 @@ describe('Test for delete()', function() it('symlink directory delete', function() command("call mkdir('Xdir1')") - if helpers.iswin() then + if helpers.is_os('win') then command("silent !mklink /j Xlink Xdir1") else command("silent !ln -s Xdir1 Xlink") diff --git a/test/functional/legacy/excmd_spec.lua b/test/functional/legacy/excmd_spec.lua index ece88d26bd..eb480a6689 100644 --- a/test/functional/legacy/excmd_spec.lua +++ b/test/functional/legacy/excmd_spec.lua @@ -7,12 +7,12 @@ local exec_lua = helpers.exec_lua local expect_exit = helpers.expect_exit local feed = helpers.feed local funcs = helpers.funcs -local iswin = helpers.iswin local meths = helpers.meths local read_file = helpers.read_file local source = helpers.source local eq = helpers.eq local write_file = helpers.write_file +local is_os = helpers.is_os local function sizeoflong() if not exec_lua('return pcall(require, "ffi")') then @@ -376,7 +376,7 @@ describe(':confirm command dialog', function() {3:(Y)es, [N]o: }^ | ]]) feed('Y') - if iswin() then + if is_os('win') then screen:expect([[ foobar | {0:~ }| @@ -416,7 +416,7 @@ describe(':confirm command dialog', function() {3:(Y)es, [N]o: }^ | ]]) feed('Y') - if iswin() then + if is_os('win') then screen:expect([[ foobar | {1: }| @@ -493,7 +493,7 @@ describe(':confirm command dialog', function() {3:(Y)es, [N]o: }^ | ]]) feed('Y') - if iswin() then + if is_os('win') then screen:expect([[ a | b | diff --git a/test/functional/legacy/filechanged_spec.lua b/test/functional/legacy/filechanged_spec.lua index 747eca1c45..cea1d6ac30 100644 --- a/test/functional/legacy/filechanged_spec.lua +++ b/test/functional/legacy/filechanged_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear, source = helpers.clear, helpers.source local call, eq, meths = helpers.call, helpers.eq, helpers.meths -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip local function expected_empty() @@ -17,7 +17,7 @@ describe('file changed dialog', function() end) it('works', function() - skip(iswin()) + skip(is_os('win')) source([[ func Test_file_changed_dialog() au! FileChangedShell diff --git a/test/functional/legacy/memory_usage_spec.lua b/test/functional/legacy/memory_usage_spec.lua index eec89aa919..8d9b28e1fc 100644 --- a/test/functional/legacy/memory_usage_spec.lua +++ b/test/functional/legacy/memory_usage_spec.lua @@ -3,15 +3,14 @@ local clear = helpers.clear local eval = helpers.eval local eq = helpers.eq local feed_command = helpers.feed_command -local iswin = helpers.iswin local retry = helpers.retry local ok = helpers.ok local source = helpers.source local poke_eventloop = helpers.poke_eventloop -local uname = helpers.uname local load_adjust = helpers.load_adjust local write_file = helpers.write_file -local isCI = helpers.isCI +local is_os = helpers.is_os +local is_ci = helpers.is_ci local function isasan() local version = eval('execute("version")') @@ -22,8 +21,8 @@ clear() if isasan() then pending('ASAN build is difficult to estimate memory usage', function() end) return -elseif iswin() then - if isCI('github') then +elseif is_os('win') then + if is_ci('github') then pending('Windows runners in Github Actions do not have a stable environment to estimate memory usage', function() end) return elseif eval("executable('wmic')") == 0 then @@ -38,7 +37,7 @@ end local monitor_memory_usage = { memory_usage = function(self) local handle - if iswin() then + if is_os('win') then handle = io.popen('wmic process where processid=' ..self.pid..' get WorkingSetSize') else handle = io.popen('ps -o rss= -p '..self.pid) @@ -169,7 +168,7 @@ describe('memory usage', function() -- Allow for 20% tolerance at the upper limit. That's very permissive, but -- otherwise the test fails sometimes. On Sourcehut CI with FreeBSD we need to -- be even much more permissive. - local upper_multiplier = uname() == 'freebsd' and 19 or 12 + local upper_multiplier = is_os('freebsd') and 19 or 12 local lower = before.last * 8 / 10 local upper = load_adjust((after.max + (after.last - before.last)) * upper_multiplier / 10) check_result({before=before, after=after, last=last}, @@ -179,7 +178,7 @@ describe('memory usage', function() end) it('releases memory when closing windows when folds exist', function() - if helpers.is_os('mac') then + if is_os('mac') then pending('macOS memory compression causes flakiness') end local pid = eval('getpid()') diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 116a541358..b7fe39cc91 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -16,7 +16,7 @@ describe('vim.diagnostic', function() exec_lua [[ require('vim.diagnostic') - function make_diagnostic(msg, x1, y1, x2, y2, severity, source) + function make_diagnostic(msg, x1, y1, x2, y2, severity, source, code) return { lnum = x1, col = y1, @@ -25,23 +25,24 @@ describe('vim.diagnostic', function() message = msg, severity = severity, source = source, + code = code, } end - function make_error(msg, x1, y1, x2, y2, source) - return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.ERROR, source) + function make_error(msg, x1, y1, x2, y2, source, code) + return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.ERROR, source, code) end - function make_warning(msg, x1, y1, x2, y2, source) - return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.WARN, source) + function make_warning(msg, x1, y1, x2, y2, source, code) + return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.WARN, source, code) end - function make_info(msg, x1, y1, x2, y2, source) - return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.INFO, source) + function make_info(msg, x1, y1, x2, y2, source, code) + return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.INFO, source, code) end - function make_hint(msg, x1, y1, x2, y2, source) - return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.HINT, source) + function make_hint(msg, x1, y1, x2, y2, source, code) + return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.HINT, source, code) end function count_diagnostics(bufnr, severity, namespace) @@ -1160,6 +1161,44 @@ end) eq(" some_linter: 👀 Warning", result[1][2][1]) eq(" another_linter: 🔥 Error", result[2][2][1]) end) + + it('can add a suffix to virtual text', function() + eq(' Some error ✘', exec_lua [[ + local diagnostics = { + make_error('Some error', 0, 0, 0, 0), + } + + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics, { + underline = false, + virtual_text = { + prefix = '', + suffix = ' ✘', + } + }) + + local extmarks = get_virt_text_extmarks(diagnostic_ns) + local virt_text = extmarks[1][4].virt_text[2][1] + return virt_text + ]]) + + eq(' Some error [err-code]', exec_lua [[ + local diagnostics = { + make_error('Some error', 0, 0, 0, 0, nil, 'err-code'), + } + + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics, { + underline = false, + virtual_text = { + prefix = '', + suffix = function(diag) return string.format(' [%s]', diag.code) end, + } + }) + + local extmarks = get_virt_text_extmarks(diagnostic_ns) + local virt_text = extmarks[1][4].virt_text[2][1] + return virt_text + ]]) + end) end) describe('set()', function() @@ -1780,6 +1819,51 @@ end) pcall_err(exec_lua, [[ vim.diagnostic.open_float({ prefix = 42 }) ]])) end) + it('can add a suffix to diagnostics', function() + -- Default is to render the diagnostic error code + eq({'1. Syntax error [code-x]', '2. Some warning [code-y]'}, exec_lua [[ + local diagnostics = { + make_error("Syntax error", 0, 1, 0, 3, nil, "code-x"), + make_warning("Some warning", 1, 1, 1, 3, nil, "code-y"), + } + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) + local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer"}) + local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) + vim.api.nvim_win_close(winnr, true) + return lines + ]]) + + eq({'1. Syntax error', '2. Some warning'}, exec_lua [[ + local diagnostics = { + make_error("Syntax error", 0, 1, 0, 3, nil, "code-x"), + make_warning("Some warning", 1, 1, 1, 3, nil, "code-y"), + } + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) + local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer", suffix = ""}) + local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) + vim.api.nvim_win_close(winnr, true) + return lines + ]]) + + -- Suffix is rendered on the last line of a multiline diagnostic + eq({'1. Syntax error', ' More context [code-x]'}, exec_lua [[ + local diagnostics = { + make_error("Syntax error\nMore context", 0, 1, 0, 3, nil, "code-x"), + } + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) + local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer"}) + local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) + vim.api.nvim_win_close(winnr, true) + return lines + ]]) + + eq(".../diagnostic.lua:0: suffix: expected string|table|function, got number", + pcall_err(exec_lua, [[ vim.diagnostic.open_float({ suffix = 42 }) ]])) + end) + it('works with the old signature', function() eq({'1. Syntax error'}, exec_lua [[ local diagnostics = { diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 3123ec324c..fc228e54bc 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -7,10 +7,10 @@ local mkdir_p = helpers.mkdir_p local rmdir = helpers.rmdir local nvim_dir = helpers.nvim_dir local test_build_dir = helpers.test_build_dir -local iswin = helpers.iswin local nvim_prog = helpers.nvim_prog +local is_os = helpers.is_os -local nvim_prog_basename = iswin() and 'nvim.exe' or 'nvim' +local nvim_prog_basename = is_os('win') and 'nvim.exe' or 'nvim' before_each(clear) @@ -102,7 +102,7 @@ describe('vim.fs', function() eq('C:/Users/jdoe', exec_lua [[ return vim.fs.normalize('C:\\Users\\jdoe') ]]) end) it('works with ~', function() - if iswin() then + if is_os('win') then pending([[$HOME does not exist on Windows ¯\_(ツ)_/¯]]) end eq(os.getenv('HOME') .. '/src/foo', exec_lua [[ return vim.fs.normalize('~/src/foo') ]]) diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua index 32c1615a45..3f107811ae 100644 --- a/test/functional/lua/overrides_spec.lua +++ b/test/functional/lua/overrides_spec.lua @@ -8,12 +8,12 @@ local feed = helpers.feed local clear = helpers.clear local funcs = helpers.funcs local meths = helpers.meths -local iswin = helpers.iswin local command = helpers.command local write_file = helpers.write_file local exec_capture = helpers.exec_capture local exec_lua = helpers.exec_lua local pcall_err = helpers.pcall_err +local is_os = helpers.is_os local screen @@ -135,7 +135,7 @@ describe('print', function() print("very slow") vim.api.nvim_command("sleep 1m") -- force deferred event processing end - ]], (iswin() and "timeout 1") or "sleep 0.1") + ]], (is_os('win') and "timeout 1") or "sleep 0.1") eq('very slow\nvery fast', exec_capture('lua test()')) end) end) diff --git a/test/functional/lua/secure_spec.lua b/test/functional/lua/secure_spec.lua index c348526d65..a5eeee8494 100644 --- a/test/functional/lua/secure_spec.lua +++ b/test/functional/lua/secure_spec.lua @@ -5,7 +5,7 @@ local eq = helpers.eq local clear = helpers.clear local command = helpers.command local pathsep = helpers.get_pathsep() -local iswin = helpers.iswin() +local is_os = helpers.is_os local curbufmeths = helpers.curbufmeths local exec_lua = helpers.exec_lua local feed_command = helpers.feed_command @@ -18,7 +18,7 @@ describe('vim.secure', function() local xstate = 'Xstate' setup(function() - helpers.mkdir_p(xstate .. pathsep .. (iswin and 'nvim-data' or 'nvim')) + helpers.mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim')) end) teardown(function() diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua index 38c7801d55..416e9e1f02 100644 --- a/test/functional/lua/uri_spec.lua +++ b/test/functional/lua/uri_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local exec_lua = helpers.exec_lua local eq = helpers.eq -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip local write_file = require('test.helpers').write_file @@ -169,7 +169,7 @@ describe('URI methods', function() describe('uri from bufnr', function() it('Windows paths should not be treated as uris', function() - skip(not iswin(), "Not applicable on non-Windows") + skip(not is_os('win'), "Not applicable on non-Windows") local file = helpers.tmpname() write_file(file, 'Test content') diff --git a/test/functional/options/autochdir_spec.lua b/test/functional/options/autochdir_spec.lua index 74959a8e76..0b6fe9533c 100644 --- a/test/functional/options/autochdir_spec.lua +++ b/test/functional/options/autochdir_spec.lua @@ -16,7 +16,7 @@ describe("'autochdir'", function() -- With 'autochdir' on, we should get the directory of tty-test.c. clear('--cmd', 'set autochdir', targetdir..'/tty-test.c') - eq(helpers.iswin() and expected:gsub('/', '\\') or expected, funcs.getcwd()) + eq(helpers.is_os('win') and expected:gsub('/', '\\') or expected, funcs.getcwd()) end) it('is not overwritten by getwinvar() call #17609',function() diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 130ed73c34..c0d820f40e 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -12,13 +12,13 @@ local eq = helpers.eq local ok = helpers.ok local funcs = helpers.funcs local insert = helpers.insert -local iswin = helpers.iswin local neq = helpers.neq local mkdir = helpers.mkdir local rmdir = helpers.rmdir local alter_slashes = helpers.alter_slashes local tbl_contains = helpers.tbl_contains local expect_exit = helpers.expect_exit +local is_os = helpers.is_os describe('startup defaults', function() describe(':filetype', function() @@ -240,7 +240,7 @@ describe('startup defaults', function() describe('$NVIM_LOG_FILE', function() local xdgdir = 'Xtest-startup-xdg-logpath' - local xdgstatedir = iswin() and xdgdir..'/nvim-data' or xdgdir..'/nvim' + local xdgstatedir = is_os('win') and xdgdir..'/nvim-data' or xdgdir..'/nvim' after_each(function() os.remove('Xtest-logpath') rmdir(xdgdir) @@ -279,7 +279,7 @@ describe('XDG defaults', function() clear() local rtp = eval('split(&runtimepath, ",")') local rv = {} - local expected = (iswin() + local expected = (is_os('win') and { [[\nvim-data\site]], [[\nvim-data\site\after]], } or { '/nvim/site', '/nvim/site/after', }) @@ -327,10 +327,10 @@ describe('XDG defaults', function() return vimruntime, libdir end - local env_sep = iswin() and ';' or ':' - local data_dir = iswin() and 'nvim-data' or 'nvim' - local state_dir = iswin() and 'nvim-data' or 'nvim' - local root_path = iswin() and 'C:' or '' + local env_sep = is_os('win') and ';' or ':' + local data_dir = is_os('win') and 'nvim-data' or 'nvim' + local state_dir = is_os('win') and 'nvim-data' or 'nvim' + local root_path = is_os('win') and 'C:' or '' describe('with too long XDG variables', function() before_each(function() @@ -497,7 +497,7 @@ describe('XDG defaults', function() it('are escaped properly', function() local vimruntime, libdir = vimruntime_and_libdir() - local path_sep = iswin() and '\\' or '/' + local path_sep = is_os('win') and '\\' or '/' eq(('\\, \\, \\,' .. path_sep .. 'nvim' .. ',\\,-\\,-\\,' .. path_sep .. 'nvim' .. ',-\\,-\\,-' .. path_sep .. 'nvim' @@ -549,9 +549,9 @@ end) describe('stdpath()', function() -- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions -- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same. - local datadir = iswin() and 'nvim-data' or 'nvim' - local statedir = iswin() and 'nvim-data' or 'nvim' - local env_sep = iswin() and ';' or ':' + local datadir = is_os('win') and 'nvim-data' or 'nvim' + local statedir = is_os('win') and 'nvim-data' or 'nvim' + local env_sep = is_os('win') and ';' or ':' it('acceptance', function() clear() -- Do not explicitly set any env vars. @@ -704,7 +704,7 @@ describe('stdpath()', function() context('returns a List', function() -- Some OS specific variables the system would have set. local function base_env() - if iswin() then + if is_os('win') then return { HOME='C:\\Users\\docwhat', -- technically, is not a usual PATH HOMEDRIVE='C:', diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 2ab1e34de4..071791e702 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -17,9 +17,9 @@ local retry = helpers.retry local NIL = helpers.NIL local read_file = require('test.helpers').read_file local write_file = require('test.helpers').write_file -local isCI = helpers.isCI +local is_ci = helpers.is_ci local meths = helpers.meths -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip -- Use these to get access to a coroutine so that I can run async tests and use @@ -27,7 +27,7 @@ local skip = helpers.skip local run, stop = helpers.run, helpers.stop -- TODO(justinmk): hangs on Windows https://github.com/neovim/neovim/pull/11837 -if skip(iswin()) then return end +if skip(is_os('win')) then return end -- Fake LSP server. local fake_lsp_code = 'test/functional/fixtures/fake-lsp-server.lua' @@ -318,7 +318,7 @@ describe('LSP', function() end) it('should succeed with manual shutdown', function() - if isCI() then + if is_ci() then pending('hangs the build on CI #14028, re-enable with freeze timeout #14204') return elseif helpers.skip_fragile(pending) then diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua index c57f43c632..c6c7d2b03d 100644 --- a/test/functional/plugin/man_spec.lua +++ b/test/functional/plugin/man_spec.lua @@ -8,8 +8,8 @@ local nvim_prog = helpers.nvim_prog local matches = helpers.matches local write_file = helpers.write_file local tmpname = helpers.tmpname -local isCI = helpers.isCI local skip = helpers.skip +local is_ci = helpers.is_ci clear() if funcs.executable('man') == 0 then @@ -162,7 +162,7 @@ describe(':Man', function() end) it('reports non-existent man pages for absolute paths', function() - skip(isCI('cirrus')) + skip(is_ci('cirrus')) local actual_file = tmpname() -- actual_file must be an absolute path to an existent file for us to test against it matches('^/.+', actual_file) diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua index dda8077f05..93cf6d2b77 100644 --- a/test/functional/plugin/shada_spec.lua +++ b/test/functional/plugin/shada_spec.lua @@ -2140,7 +2140,7 @@ end) describe('plugin/shada.vim', function() local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0) - local eol = helpers.iswin() and '\r\n' or '\n' + local eol = helpers.is_os('win') and '\r\n' or '\n' before_each(function() -- Note: reset() is called explicitly in each test. os.remove(fname) diff --git a/test/functional/preload.lua b/test/functional/preload.lua index 74f03eaecf..43e2151f84 100644 --- a/test/functional/preload.lua +++ b/test/functional/preload.lua @@ -2,10 +2,10 @@ -- Busted started doing this to help provide more isolation. See issue #62 -- for more information about this. local helpers = require('test.functional.helpers')(nil) -local iswin = helpers.iswin local busted = require("busted") +local is_os = helpers.is_os -if iswin() then +if is_os('win') then local ffi = require('ffi') ffi.cdef[[ typedef int errno_t; diff --git a/test/functional/provider/perl_spec.lua b/test/functional/provider/perl_spec.lua index 4c5c3ece15..ce92831f4c 100644 --- a/test/functional/provider/perl_spec.lua +++ b/test/functional/provider/perl_spec.lua @@ -9,7 +9,7 @@ local curbufmeths = helpers.curbufmeths local insert = helpers.insert local expect = helpers.expect local feed = helpers.feed -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip do @@ -26,7 +26,7 @@ before_each(function() end) describe('legacy perl provider', function() - skip(iswin()) + skip(is_os('win')) it('feature test', function() eq(1, eval('has("perl")')) @@ -70,7 +70,7 @@ describe('legacy perl provider', function() end) describe('perl provider', function() - skip(iswin()) + skip(is_os('win')) teardown(function () os.remove('Xtest-perl-hello.pl') os.remove('Xtest-perl-hello-plugin.pl') diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua index a5ef60d91f..fb656735dd 100644 --- a/test/functional/shada/compatibility_spec.lua +++ b/test/functional/shada/compatibility_spec.lua @@ -12,7 +12,7 @@ local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compati local mock_file_path = '/a/b/' local mock_file_path2 = '/d/e/' -if helpers.iswin() then +if helpers.is_os('win') then mock_file_path = 'C:/a/' mock_file_path2 = 'C:/d/' end diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua index 2d44b0a950..da2fbbe029 100644 --- a/test/functional/shada/merging_spec.lua +++ b/test/functional/shada/merging_spec.lua @@ -14,7 +14,7 @@ local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-merging.shada') local mock_file_path = '/a/b/' -if helpers.iswin() then +if helpers.is_os('win') then mock_file_path = 'C:/a/' end diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua index 210c09e187..88a99d9b55 100644 --- a/test/functional/shada/shada_spec.lua +++ b/test/functional/shada/shada_spec.lua @@ -5,7 +5,7 @@ local meths, nvim_command, funcs, eq = local write_file, spawn, set_session, nvim_prog, exc_exec = helpers.write_file, helpers.spawn, helpers.set_session, helpers.nvim_prog, helpers.exc_exec -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip local lfs = require('lfs') @@ -250,7 +250,7 @@ describe('ShaDa support code', function() end) it('does not crash when ShaDa file directory is not writable', function() - skip(iswin()) + skip(is_os('win')) funcs.mkdir(dirname, '', 0) eq(0, funcs.filewritable(dirname)) diff --git a/test/functional/terminal/altscreen_spec.lua b/test/functional/terminal/altscreen_spec.lua index 457a5aa18f..cbe5e06005 100644 --- a/test/functional/terminal/altscreen_spec.lua +++ b/test/functional/terminal/altscreen_spec.lua @@ -6,7 +6,7 @@ local feed_data = thelpers.feed_data local enter_altscreen = thelpers.enter_altscreen local exit_altscreen = thelpers.exit_altscreen -if helpers.skip(helpers.iswin()) then return end +if helpers.skip(helpers.is_os('win')) then return end describe(':terminal altscreen', function() local screen diff --git a/test/functional/terminal/api_spec.lua b/test/functional/terminal/api_spec.lua index b5697c4c6b..38ef7c2a61 100644 --- a/test/functional/terminal/api_spec.lua +++ b/test/functional/terminal/api_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local child_session = require('test.functional.terminal.helpers') local ok = helpers.ok -if helpers.skip(helpers.iswin()) then return end +if helpers.skip(helpers.is_os('win')) then return end describe('api', function() local screen diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 5a75af69c0..9c8b983ff7 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -15,7 +15,7 @@ local matches = helpers.matches local exec_lua = helpers.exec_lua local sleep = helpers.sleep local funcs = helpers.funcs -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip describe(':terminal buffer', function() @@ -202,7 +202,7 @@ describe(':terminal buffer', function() -- Save the buffer number of the terminal for later testing. local tbuf = eval('bufnr("%")') - local exitcmd = helpers.iswin() + local exitcmd = helpers.is_os('win') and "['cmd', '/c', 'exit']" or "['sh', '-c', 'exit']" source([[ @@ -264,7 +264,7 @@ describe(':terminal buffer', function() end) it('it works with set rightleft #11438', function() - skip(iswin()) + skip(is_os('win')) local columns = eval('&columns') feed(string.rep('a', columns)) command('set rightleft') diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua index fdd7b9407b..98ac03211a 100644 --- a/test/functional/terminal/cursor_spec.lua +++ b/test/functional/terminal/cursor_spec.lua @@ -9,7 +9,7 @@ local matches = helpers.matches local feed_command = helpers.feed_command local hide_cursor = thelpers.hide_cursor local show_cursor = thelpers.show_cursor -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip describe(':terminal cursor', function() @@ -90,7 +90,7 @@ describe(':terminal cursor', function() describe('when invisible', function() it('is not highlighted and is detached from screen cursor', function() - skip(iswin()) + skip(is_os('win')) hide_cursor() screen:expect([[ tty ready | @@ -363,7 +363,7 @@ describe('buffer cursor position is correct in terminal without number column', end) describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function() - if skip(iswin(), "Encoding problem?") then return end + if skip(is_os('win'), "Encoding problem?") then return end before_each(function() setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') @@ -446,7 +446,7 @@ describe('buffer cursor position is correct in terminal without number column', end) describe('in a line with double-cell multibyte characters and no trailing spaces,', function() - skip(iswin(), "Encoding problem?") + skip(is_os('win'), "Encoding problem?") before_each(function() setup_ex_register('哦哦哦哦哦哦哦哦') @@ -743,7 +743,7 @@ describe('buffer cursor position is correct in terminal with number column', fun end) describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function() - if skip(iswin(), "Encoding problem?") then return end + if skip(is_os('win'), "Encoding problem?") then return end before_each(function() setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') @@ -826,7 +826,7 @@ describe('buffer cursor position is correct in terminal with number column', fun end) describe('in a line with double-cell multibyte characters and no trailing spaces,', function() - skip(iswin(), "Encoding problem?") + skip(is_os('win'), "Encoding problem?") before_each(function() setup_ex_register('哦哦哦哦哦哦哦哦') diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua index 95ee561d2b..80287bb3d0 100644 --- a/test/functional/terminal/edit_spec.lua +++ b/test/functional/terminal/edit_spec.lua @@ -36,7 +36,7 @@ describe(':edit term://*', function() end) it("runs TermOpen early enough to set buffer-local 'scrollback'", function() - if helpers.skip(helpers.iswin()) then return end + if helpers.skip(helpers.is_os('win')) then return end local columns, lines = 20, 4 local scr = get_screen(columns, lines) local rep = 97 diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index 48254faa31..6b7e93a864 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -8,10 +8,10 @@ local feed_command, eval = helpers.feed_command, helpers.eval local funcs = helpers.funcs local retry = helpers.retry local ok = helpers.ok -local iswin = helpers.iswin local command = helpers.command -local isCI = helpers.isCI local skip = helpers.skip +local is_os = helpers.is_os +local is_ci = helpers.is_ci describe(':terminal', function() local screen @@ -47,8 +47,8 @@ describe(':terminal', function() end) it("reads output buffer on terminal reporting #4151", function() - skip(isCI('cirrus') or iswin()) - if iswin() then + skip(is_ci('cirrus') or is_os('win')) + if is_os('win') then feed_command([[terminal powershell -NoProfile -NoLogo -Command Write-Host -NoNewline "\"$([char]27)[6n\""; Start-Sleep -Milliseconds 500 ]]) else feed_command([[terminal printf '\e[6n'; sleep 0.5 ]]) @@ -57,7 +57,7 @@ describe(':terminal', function() end) it("in normal-mode :split does not move cursor", function() - if iswin() then + if is_os('win') then feed_command([[terminal for /L \\%I in (1,0,2) do ( echo foo & ping -w 100 -n 1 127.0.0.1 > nul )]]) else feed_command([[terminal while true; do echo foo; sleep .1; done]]) @@ -144,7 +144,7 @@ describe(':terminal (with fake shell)', function() end it('with no argument, acts like termopen()', function() - skip(iswin()) + skip(is_os('win')) terminal_with_fake_shell() retry(nil, 4 * screen.timeout, function() screen:expect([[ @@ -168,7 +168,7 @@ describe(':terminal (with fake shell)', function() end) it("with no argument, but 'shell' has arguments, acts like termopen()", function() - skip(iswin()) + skip(is_os('win')) nvim('set_option', 'shell', testprg('shell-test')..' -t jeff') terminal_with_fake_shell() screen:expect([[ @@ -180,7 +180,7 @@ describe(':terminal (with fake shell)', function() end) it('executes a given command through the shell', function() - skip(iswin()) + skip(is_os('win')) command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell('echo hi') screen:expect([[ @@ -192,7 +192,7 @@ describe(':terminal (with fake shell)', function() end) it("executes a given command through the shell, when 'shell' has arguments", function() - skip(iswin()) + skip(is_os('win')) nvim('set_option', 'shell', testprg('shell-test')..' -t jeff') command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell('echo hi') @@ -205,7 +205,7 @@ describe(':terminal (with fake shell)', function() end) it('allows quotes and slashes', function() - skip(iswin()) + skip(is_os('win')) command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell([[echo 'hello' \ "world"]]) screen:expect([[ @@ -242,7 +242,7 @@ describe(':terminal (with fake shell)', function() end) it('works with :find', function() - skip(iswin()) + skip(is_os('win')) terminal_with_fake_shell() screen:expect([[ ^ready $ | @@ -253,7 +253,7 @@ describe(':terminal (with fake shell)', function() eq('term://', string.match(eval('bufname("%")'), "^term://")) feed([[<C-\><C-N>]]) feed_command([[find */shadacat.py]]) - if iswin() then + if is_os('win') then eq('scripts\\shadacat.py', eval('bufname("%")')) else eq('scripts/shadacat.py', eval('bufname("%")')) @@ -261,7 +261,7 @@ describe(':terminal (with fake shell)', function() end) it('works with gf', function() - skip(iswin()) + skip(is_os('win')) command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell([[echo "scripts/shadacat.py"]]) retry(nil, 4 * screen.timeout, function() diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index 3e121405d8..2ac45771d4 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -7,7 +7,7 @@ local nvim_prog_abs = helpers.nvim_prog_abs local eq, eval = helpers.eq, helpers.eval local funcs = helpers.funcs local nvim_set = helpers.nvim_set -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip describe(':terminal highlight', function() @@ -60,7 +60,7 @@ describe(':terminal highlight', function() end) local function pass_attrs() - skip(iswin()) + skip(is_os('win')) screen:expect(sub([[ tty ready | {NUM:text}text{10: } | @@ -75,7 +75,7 @@ describe(':terminal highlight', function() it('will pass the corresponding attributes', pass_attrs) it('will pass the corresponding attributes on scrollback', function() - skip(iswin()) + skip(is_os('win')) pass_attrs() local lines = {} for i = 1, 8 do @@ -199,7 +199,7 @@ describe(':terminal highlight forwarding', function() end) it('will handle cterm and rgb attributes', function() - skip(iswin()) + skip(is_os('win')) thelpers.set_fg(3) thelpers.feed_data('text') thelpers.feed_termcode('[38:2:255:128:0m') @@ -251,7 +251,7 @@ describe(':terminal highlight with custom palette', function() end) it('will use the custom color', function() - skip(iswin()) + skip(is_os('win')) thelpers.set_fg(3) thelpers.feed_data('text') thelpers.clear_attrs() diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index a062a77a14..899df0ac54 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -3,7 +3,7 @@ local thelpers = require('test.functional.terminal.helpers') local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval local feed, nvim, command = helpers.feed, helpers.nvim, helpers.command local feed_data = thelpers.feed_data -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip describe(':terminal mouse', function() @@ -68,7 +68,7 @@ describe(':terminal mouse', function() end) it('does not leave terminal mode on left-release', function() - skip(iswin()) + skip(is_os('win')) feed('<LeftRelease>') eq('t', eval('mode(1)')) end) @@ -89,7 +89,7 @@ describe(':terminal mouse', function() end) it('will forward mouse press, drag and release to the program', function() - skip(iswin()) + skip(is_os('win')) feed('<LeftMouse><1,2>') screen:expect([[ line27 | @@ -133,7 +133,7 @@ describe(':terminal mouse', function() end) it('will forward mouse scroll to the program', function() - skip(iswin()) + skip(is_os('win')) feed('<ScrollWheelUp><0,0>') screen:expect([[ line27 | @@ -147,7 +147,7 @@ describe(':terminal mouse', function() end) it('dragging and scrolling do not interfere with each other', function() - skip(iswin()) + skip(is_os('win')) feed('<LeftMouse><1,2>') screen:expect([[ line27 | @@ -201,7 +201,7 @@ describe(':terminal mouse', function() end) it('will forward mouse clicks to the program with the correct even if set nu', function() - skip(iswin()) + skip(is_os('win')) command('set number') -- When the display area such as a number is clicked, it returns to the -- normal mode. @@ -232,7 +232,7 @@ describe(':terminal mouse', function() end) describe('with a split window and other buffer', function() - skip(iswin()) + skip(is_os('win')) before_each(function() feed('<c-\\><c-n>:vsp<cr>') screen:expect([[ diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua index 873445f281..a4899c8219 100644 --- a/test/functional/terminal/scrollback_spec.lua +++ b/test/functional/terminal/scrollback_spec.lua @@ -3,7 +3,6 @@ local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf local feed, testprg, feed_command = helpers.feed, helpers.testprg, helpers.feed_command -local iswin = helpers.iswin local eval = helpers.eval local command = helpers.command local matches = helpers.matches @@ -16,6 +15,7 @@ local pcall_err = helpers.pcall_err local exec_lua = helpers.exec_lua local assert_alive = helpers.assert_alive local skip = helpers.skip +local is_os = helpers.is_os describe(':terminal scrollback', function() local screen @@ -140,7 +140,7 @@ describe(':terminal scrollback', function() describe('and height decreased by 1', function() - if skip(iswin()) then return end + if skip(is_os('win')) then return end local function will_hide_top_line() feed([[<C-\><C-N>]]) screen:try_resize(screen._width - 2, screen._height - 1) @@ -186,7 +186,7 @@ describe(':terminal scrollback', function() -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html -- See also: https://github.com/rprichard/winpty/issues/110 - if skip(iswin()) then return end + if skip(is_os('win')) then return end describe('and the height is decreased by 2', function() before_each(function() @@ -265,7 +265,7 @@ describe(':terminal scrollback', function() -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html -- See also: https://github.com/rprichard/winpty/issues/110 - if skip(iswin()) then return end + if skip(is_os('win')) then return end local function pop_then_push() screen:try_resize(screen._width, screen._height + 1) screen:expect([[ @@ -347,7 +347,7 @@ end) describe(':terminal prints more lines than the screen height and exits', function() it('will push extra lines to scrollback', function() - skip(iswin()) + skip(is_os('win')) clear() local screen = Screen.new(30, 7) screen:attach({rgb=false}) @@ -397,21 +397,21 @@ describe("'scrollback' option", function() it('set to 0 behaves as 1', function() local screen - if iswin() then + if is_os('win') then screen = thelpers.screen_setup(nil, "['cmd.exe']", 30) else screen = thelpers.screen_setup(nil, "['sh']", 30) end curbufmeths.set_option('scrollback', 0) - feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) + feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) screen:expect{any='30: line '} retry(nil, nil, function() expect_lines(7) end) end) it('deletes lines (only) if necessary', function() local screen - if iswin() then + if is_os('win') then command([[let $PROMPT='$$']]) screen = thelpers.screen_setup(nil, "['cmd.exe']", 30) else @@ -424,7 +424,7 @@ describe("'scrollback' option", function() -- Wait for prompt. screen:expect{any='%$'} - feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) + feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) screen:expect{any='30: line '} retry(nil, nil, function() expect_lines(33, 2) end) @@ -437,8 +437,8 @@ describe("'scrollback' option", function() -- 'scrollback' option is synchronized with the internal sb_buffer. command('sleep 100m') - feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) - if iswin() then + feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) + if is_os('win') then screen:expect{grid=[[ 37: line | 38: line | @@ -462,8 +462,8 @@ describe("'scrollback' option", function() expect_lines(58) -- Verify off-screen state - matches((iswin() and '^36: line[ ]*$' or '^35: line[ ]*$'), eval("getline(line('w0') - 1)")) - matches((iswin() and '^27: line[ ]*$' or '^26: line[ ]*$'), eval("getline(line('w0') - 10)")) + matches((is_os('win') and '^36: line[ ]*$' or '^35: line[ ]*$'), eval("getline(line('w0') - 1)")) + matches((is_os('win') and '^27: line[ ]*$' or '^26: line[ ]*$'), eval("getline(line('w0') - 10)")) end) it('deletes extra lines immediately', function() @@ -607,7 +607,7 @@ describe("pending scrollback line handling", function() end) it("does not crash after nvim_buf_call #14891", function() - skip(iswin()) + skip(is_os('win')) exec_lua [[ local a = vim.api local bufnr = a.nvim_create_buf(false, true) diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 4cfdd90187..b3d2625d78 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -5,7 +5,6 @@ -- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode local helpers = require('test.functional.helpers')(after_each) -local uname = helpers.uname local thelpers = require('test.functional.terminal.helpers') local Screen = require('test.functional.ui.screen') local assert_alive = helpers.assert_alive @@ -22,8 +21,10 @@ local ok = helpers.ok local read_file = helpers.read_file local funcs = helpers.funcs local meths = helpers.meths +local is_ci = helpers.is_ci +local is_os = helpers.is_os -if helpers.skip(helpers.iswin()) then return end +if helpers.skip(helpers.is_os('win')) then return end describe('TUI', function() local screen @@ -821,9 +822,8 @@ describe('TUI', function() end) it('paste: terminal mode', function() - if os.getenv('GITHUB_ACTIONS') ~= nil then + if is_ci('github') then pending("tty-test complains about not owning the terminal -- actions/runner#241") - return end child_exec_lua('vim.o.statusline="^^^^^^^"') child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test')) @@ -1089,7 +1089,7 @@ describe('TUI', function() -- "bracketed paste" feed_data('\027[200~'..expected..'\027[201~') -- FIXME: Data race between the two feeds - if uname() == 'freebsd' then screen:sleep(1) end + if is_os('freebsd') then screen:sleep(1) end feed_data(' end') expected = expected..' end' screen:expect([[ @@ -1329,9 +1329,8 @@ describe('TUI', function() end) it('forwards :term palette colors with termguicolors', function() - if os.getenv('GITHUB_ACTIONS') ~= nil then + if is_ci('github') then pending("tty-test complains about not owning the terminal -- actions/runner#241") - return end screen:set_rgb_cterm(true) screen:set_default_attr_ids({ @@ -1669,7 +1668,6 @@ end) -- does not initialize the TUI. describe("TUI 't_Co' (terminal colors)", function() local screen - local is_freebsd = (uname() == 'freebsd') local function assert_term_colors(term, colorterm, maxcolors) helpers.clear({env={TERM=term}, args={}}) @@ -1772,7 +1770,7 @@ describe("TUI 't_Co' (terminal colors)", function() -- which is raised to 16 by COLORTERM. it("TERM=screen no COLORTERM uses 8/256 colors", function() - if is_freebsd then + if is_os('freebsd') then assert_term_colors("screen", nil, 256) else assert_term_colors("screen", nil, 8) @@ -1780,7 +1778,7 @@ describe("TUI 't_Co' (terminal colors)", function() end) it("TERM=screen COLORTERM=screen uses 16/256 colors", function() - if is_freebsd then + if is_os('freebsd') then assert_term_colors("screen", "screen", 256) else assert_term_colors("screen", "screen", 16) @@ -1943,8 +1941,6 @@ end) -- does not initialize the TUI. describe("TUI 'term' option", function() local screen - local is_bsd = not not string.find(uname(), 'bsd') - local is_macos = not not string.find(uname(), 'darwin') local function assert_term(term_envvar, term_expected) clear() @@ -1970,11 +1966,11 @@ describe("TUI 'term' option", function() end) it('gets system-provided term if $TERM is valid', function() - if uname() == "openbsd" then + if is_os('openbsd') then assert_term("xterm", "xterm") - elseif is_bsd then -- BSD lacks terminfo, builtin is always used. + elseif is_os('bsd') then -- BSD lacks terminfo, builtin is always used. assert_term("xterm", "builtin_xterm") - elseif is_macos then + elseif is_os('mac') then local status, _ = pcall(assert_term, "xterm", "xterm") if not status then pending("macOS: unibilium could not find terminfo") diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index 81cd1017db..80e9d78400 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -3,12 +3,12 @@ local thelpers = require('test.functional.terminal.helpers') local feed_data = thelpers.feed_data local feed, clear = helpers.feed, helpers.clear local poke_eventloop = helpers.poke_eventloop -local iswin = helpers.iswin local command = helpers.command local retry = helpers.retry local eq = helpers.eq local eval = helpers.eval local skip = helpers.skip +local is_os = helpers.is_os describe(':terminal window', function() local screen @@ -19,7 +19,7 @@ describe(':terminal window', function() end) it('sets topline correctly #8556', function() - skip(iswin()) + skip(is_os('win')) -- Test has hardcoded assumptions of dimensions. eq(7, eval('&lines')) feed_data('\n\n\n') -- Add blank lines. @@ -55,7 +55,7 @@ describe(':terminal window', function() {3:-- TERMINAL --} | ]]) - skip(iswin(), 'win: :terminal resize is unreliable #7007') + skip(is_os('win'), 'win: :terminal resize is unreliable #7007') -- numberwidth=9 feed([[<C-\><C-N>]]) @@ -171,7 +171,7 @@ describe(':terminal with multigrid', function() ]]) screen:try_resize_grid(2, 20, 10) - if iswin() then + if is_os('win') then screen:expect{any="rows: 10, cols: 20"} else screen:expect([[ @@ -200,7 +200,7 @@ describe(':terminal with multigrid', function() end screen:try_resize_grid(2, 70, 3) - if iswin() then + if is_os('win') then screen:expect{any="rows: 3, cols: 70"} else screen:expect([[ @@ -222,7 +222,7 @@ describe(':terminal with multigrid', function() end screen:try_resize_grid(2, 0, 0) - if iswin() then + if is_os('win') then screen:expect{any="rows: 6, cols: 50"} else screen:expect([[ diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua index b62d173cea..1d77e1e92e 100644 --- a/test/functional/terminal/window_split_tab_spec.lua +++ b/test/functional/terminal/window_split_tab_spec.lua @@ -8,9 +8,9 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval local meths = helpers.meths -local iswin = helpers.iswin local sleep = helpers.sleep local retry = helpers.retry +local is_os = helpers.is_os describe(':terminal', function() local screen @@ -96,7 +96,7 @@ describe(':terminal', function() local w1, h1 = screen._width - 3, screen._height - 2 local w2, h2 = w1 - 6, h1 - 3 - if iswin() then + if is_os('win') then -- win: SIGWINCH is unreliable, use a weaker test. #7506 retry(3, 30000, function() screen:try_resize(w1, h1) diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index c6ddf812be..f006ad4539 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -5,7 +5,7 @@ local eq = helpers.eq local insert = helpers.insert local exec_lua = helpers.exec_lua local feed = helpers.feed -local iswin = helpers.iswin +local is_os = helpers.is_os local skip = helpers.skip before_each(clear) @@ -684,7 +684,7 @@ int x = INT_MAX; end) it("should not inject bad languages", function() - skip(iswin()) + skip(is_os('win')) exec_lua([=[ vim.treesitter.add_directive("inject-bad!", function(match, _, _, pred, metadata) metadata.language = "{" diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index 8003947078..c73c2d9f8a 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -4,10 +4,10 @@ local clear, feed = helpers.clear, helpers.feed local source = helpers.source local command = helpers.command local assert_alive = helpers.assert_alive -local uname = helpers.uname local exec = helpers.exec local eval = helpers.eval local eq = helpers.eq +local is_os = helpers.is_os local function new_screen(opt) local screen = Screen.new(25, 5) @@ -717,7 +717,7 @@ describe('cmdline redraw', function() end) it('with <Cmd>', function() - if string.find(uname(), 'bsd') then + if is_os('bsd') then pending('FIXME #10804') end command('cmap a <Cmd>call sin(0)<CR>') -- no-op diff --git a/test/functional/ui/embed_spec.lua b/test/functional/ui/embed_spec.lua index e7addd1b85..cd2b48213d 100644 --- a/test/functional/ui/embed_spec.lua +++ b/test/functional/ui/embed_spec.lua @@ -51,7 +51,7 @@ local function test_embed(ext_linegrid) end) it("doesn't erase output when setting color scheme", function() - if 'openbsd' == helpers.uname() then + if helpers.is_os('openbsd') then pending('FIXME #10804') end startup('--cmd', 'echoerr "foo"', '--cmd', 'color default', '--cmd', 'echoerr "bar"') diff --git a/test/functional/ui/hlstate_spec.lua b/test/functional/ui/hlstate_spec.lua index a8b4c05747..55f873e827 100644 --- a/test/functional/ui/hlstate_spec.lua +++ b/test/functional/ui/hlstate_spec.lua @@ -4,10 +4,10 @@ local Screen = require('test.functional.ui.screen') local clear, insert = helpers.clear, helpers.insert local command = helpers.command local meths = helpers.meths -local iswin = helpers.iswin local testprg = helpers.testprg local thelpers = require('test.functional.terminal.helpers') local skip = helpers.skip +local is_os = helpers.is_os describe('ext_hlstate detailed highlights', function() local screen @@ -183,7 +183,7 @@ describe('ext_hlstate detailed highlights', function() end) it("work with :terminal", function() - skip(iswin()) + skip(is_os('win')) screen:set_default_attr_ids({ [1] = {{}, {{hi_name = "TermCursorNC", ui_name = "TermCursorNC", kind = "ui"}}}, @@ -212,7 +212,7 @@ describe('ext_hlstate detailed highlights', function() thelpers.set_bold() thelpers.feed_data('z\n') -- TODO(bfredl): check if this distinction makes sense - if iswin() then + if is_os('win') then screen:expect([[ ^tty ready | x {5:y z} | @@ -238,7 +238,7 @@ describe('ext_hlstate detailed highlights', function() thelpers.feed_termcode("[A") thelpers.feed_termcode("[2C") - if iswin() then + if is_os('win') then screen:expect([[ ^tty ready | x {6:y}{5: z} | diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 60b538eee5..f7ffe16bd6 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -9,12 +9,13 @@ local meths = helpers.meths local async_meths = helpers.async_meths local test_build_dir = helpers.test_build_dir local nvim_prog = helpers.nvim_prog -local iswin = helpers.iswin local exec = helpers.exec local exc_exec = helpers.exc_exec local exec_lua = helpers.exec_lua local poke_eventloop = helpers.poke_eventloop local assert_alive = helpers.assert_alive +local is_os = helpers.is_os +local is_ci = helpers.is_ci describe('ui/ext_messages', function() local screen @@ -1496,7 +1497,7 @@ describe('ui/msg_puts_printf', function() screen = Screen.new(25, 5) screen:attach() - if iswin() then + if is_os('win') then if os.execute('chcp 932 > NUL 2>&1') ~= 0 then pending('missing japanese language features', function() end) return @@ -1507,7 +1508,7 @@ describe('ui/msg_puts_printf', function() if (exc_exec('lang ja_JP.UTF-8') ~= 0) then pending('Locale ja_JP.UTF-8 not supported', function() end) return - elseif helpers.isCI() then + elseif is_ci() then -- Fails non--Windows CI. Message catalog directory issue? pending('fails on unix CI', function() end) return diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua index 0825772d57..223844405e 100644 --- a/test/functional/ui/output_spec.lua +++ b/test/functional/ui/output_spec.lua @@ -6,7 +6,6 @@ local mkdir, write_file, rmdir = helpers.mkdir, helpers.write_file, helpers.rmdi local eq = helpers.eq local feed = helpers.feed local feed_command = helpers.feed_command -local iswin = helpers.iswin local clear = helpers.clear local command = helpers.command local testprg = helpers.testprg @@ -14,6 +13,7 @@ local nvim_dir = helpers.nvim_dir local has_powershell = helpers.has_powershell local set_shell_powershell = helpers.set_shell_powershell local skip = helpers.skip +local is_os = helpers.is_os describe("shell command :!", function() local screen @@ -37,7 +37,7 @@ describe("shell command :!", function() end) it("displays output without LF/EOF. #4646 #4569 #3772", function() - skip(iswin()) + skip(is_os('win')) -- NOTE: We use a child nvim (within a :term buffer) -- to avoid triggering a UI flush. child_session.feed_data(":!printf foo; sleep 200\n") @@ -53,7 +53,7 @@ describe("shell command :!", function() end) it("throttles shell-command output greater than ~10KB", function() - skip('openbsd' == helpers.uname(), 'FIXME #10804') + skip(is_os('openbsd'), 'FIXME #10804') child_session.feed_data((":!%s REP 30001 foo\n"):format(testprg('shell-test'))) -- If we observe any line starting with a dot, then throttling occurred. @@ -95,7 +95,7 @@ describe("shell command :!", function() end) it('handles control codes', function() - skip(iswin(), 'missing printf') + skip(is_os('win'), 'missing printf') local screen = Screen.new(50, 4) screen:set_default_attr_ids { [1] = {bold = true, reverse = true}; @@ -170,10 +170,10 @@ describe("shell command :!", function() end) it("doesn't truncate Last line of shell output #3269", function() - command(helpers.iswin() + command(is_os('win') and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]] or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]]) - local result = (helpers.iswin() + local result = (is_os('win') and [[:!dir /b bang_filter_spec]] or [[:!ls bang_filter_spec ]]) feed([[\l]]) @@ -212,7 +212,7 @@ describe("shell command :!", function() it('handles multibyte sequences split over buffer boundaries', function() command('cd '..nvim_dir) - local cmd = iswin() and '!shell-test UTF-8 ' or '!./shell-test UTF-8' + local cmd = is_os('win') and '!shell-test UTF-8 ' or '!./shell-test UTF-8' feed_command(cmd) -- Note: only the first example of split composed char works screen:expect([[ @@ -262,7 +262,7 @@ describe("shell command :!", function() | Press ENTER or type command to continue^ | ]]) - if iswin() then + if is_os('win') then feed_command([[!& 'cmd.exe' /c 'echo $a']]) screen:expect([[ :!& 'cmd.exe' /c 'echo $a' | diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 5aacdc95e2..3bd2289a73 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -5,8 +5,8 @@ local feed, command = helpers.feed, helpers.command local insert = helpers.insert local eq = helpers.eq local eval = helpers.eval -local iswin = helpers.iswin local funcs, meths, exec_lua = helpers.funcs, helpers.meths, helpers.exec_lua +local is_os = helpers.is_os describe('screen', function() local screen @@ -128,18 +128,18 @@ local function screen_tests(linegrid) end) it('has correct default title with named file', function() - local expected = (iswin() and 'myfile (C:\\mydir) - NVIM' or 'myfile (/mydir) - NVIM') + local expected = (is_os('win') and 'myfile (C:\\mydir) - NVIM' or 'myfile (/mydir) - NVIM') command('set title') - command(iswin() and 'file C:\\mydir\\myfile' or 'file /mydir/myfile') + command(is_os('win') and 'file C:\\mydir\\myfile' or 'file /mydir/myfile') screen:expect(function() eq(expected, screen.title) end) end) describe('is not changed by', function() - local file1 = iswin() and 'C:\\mydir\\myfile1' or '/mydir/myfile1' - local file2 = iswin() and 'C:\\mydir\\myfile2' or '/mydir/myfile2' - local expected = (iswin() and 'myfile1 (C:\\mydir) - NVIM' or 'myfile1 (/mydir) - NVIM') + local file1 = is_os('win') and 'C:\\mydir\\myfile1' or '/mydir/myfile1' + local file2 = is_os('win') and 'C:\\mydir\\myfile2' or '/mydir/myfile2' + local expected = (is_os('win') and 'myfile1 (C:\\mydir) - NVIM' or 'myfile1 (/mydir) - NVIM') local buf2 before_each(function() diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua index 1aa73e7b13..425790dbf9 100644 --- a/test/functional/ui/spell_spec.lua +++ b/test/functional/ui/spell_spec.lua @@ -5,8 +5,8 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local feed = helpers.feed local insert = helpers.insert -local uname = helpers.uname local command = helpers.command +local is_os = helpers.is_os describe("'spell'", function() local screen @@ -27,7 +27,7 @@ describe("'spell'", function() end) it('joins long lines #7937', function() - if uname() == 'openbsd' then pending('FIXME #12104', function() end) return end + if is_os('openbsd') then pending('FIXME #12104', function() end) return end command('set spell') insert([[ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua index f1e818119e..50466c9473 100644 --- a/test/functional/ui/wildmode_spec.lua +++ b/test/functional/ui/wildmode_spec.lua @@ -1,13 +1,13 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, command = helpers.clear, helpers.feed, helpers.command -local iswin = helpers.iswin local funcs = helpers.funcs local meths = helpers.meths local eq = helpers.eq local eval = helpers.eval local retry = helpers.retry local testprg = helpers.testprg +local is_os = helpers.is_os describe("'wildmenu'", function() local screen @@ -159,7 +159,7 @@ describe("'wildmenu'", function() -- must wait the full timeout. So make it reasonable. screen.timeout = 1000 - if not iswin() then + if not is_os('win') then command('set shell=sh') -- Need a predictable "$" prompt. command('let $PS1 = "$"') end @@ -169,7 +169,7 @@ describe("'wildmenu'", function() -- Check for a shell prompt to verify that the terminal loaded. retry(nil, nil, function() - if iswin() then + if is_os('win') then eq('Microsoft', eval("matchstr(join(getline(1, '$')), 'Microsoft')")) else eq('$', eval([[matchstr(getline(1), '\$')]])) diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index d50c252569..a8a901042b 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -71,13 +71,13 @@ describe("backtick expansion", function() end) it("with default 'shell'", function() - if helpers.iswin() then + if helpers.is_os('win') then command(":silent args `dir /b *2`") else command(":silent args `echo ***2`") end eq({ "file2", }, eval("argv()")) - if helpers.iswin() then + if helpers.is_os('win') then command(":silent args `dir /s/b *4`") eq({ "subdir\\file4", }, eval("map(argv(), 'fnamemodify(v:val, \":.\")')")) else diff --git a/test/functional/vimscript/executable_spec.lua b/test/functional/vimscript/executable_spec.lua index b49eb09512..43e4a29e1a 100644 --- a/test/functional/vimscript/executable_spec.lua +++ b/test/functional/vimscript/executable_spec.lua @@ -1,15 +1,16 @@ local helpers = require('test.functional.helpers')(after_each) -local eq, clear, call, iswin, write_file, command = - helpers.eq, helpers.clear, helpers.call, helpers.iswin, helpers.write_file, +local eq, clear, call, write_file, command = + helpers.eq, helpers.clear, helpers.call, helpers.write_file, helpers.command local exc_exec = helpers.exc_exec local eval = helpers.eval +local is_os = helpers.is_os describe('executable()', function() before_each(clear) it('returns 1 for commands in $PATH', function() - local exe = iswin() and 'ping' or 'ls' + local exe = is_os('win') and 'ping' or 'ls' eq(1, call('executable', exe)) command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') eq(1, call('executable', 'null')) @@ -17,7 +18,7 @@ describe('executable()', function() eq(1, call('executable', 'false')) end) - if iswin() then + if is_os('win') then it('exepath respects shellslash', function() command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') eq([[test\functional\fixtures\bin\null.CMD]], call('fnamemodify', call('exepath', 'null'), ':.')) @@ -56,8 +57,8 @@ describe('executable()', function() -- Some executable in build/bin/, *not* in $PATH nor CWD. local sibling_exe = 'printargs-test' -- Windows: siblings are in Nvim's "pseudo-$PATH". - local expected = iswin() and 1 or 0 - if iswin() then + local expected = is_os('win') and 1 or 0 + if is_os('win') then eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', sibling_exe..' lemon sky tree')) end @@ -69,7 +70,7 @@ describe('executable()', function() clear() write_file('Xtest_not_executable', 'non-executable file') write_file('Xtest_executable', 'executable file (exec-bit set)') - if not iswin() then -- N/A for Windows. + if not is_os('win') then -- N/A for Windows. call('system', {'chmod', '-x', 'Xtest_not_executable'}) call('system', {'chmod', '+x', 'Xtest_executable'}) end @@ -90,14 +91,17 @@ describe('executable()', function() end) it('set, qualified as a path', function() - local expected = iswin() and 0 or 1 + local expected = is_os('win') and 0 or 1 eq(expected, call('executable', './Xtest_executable')) end) end) end) describe('executable() (Windows)', function() - if not iswin() then return end -- N/A for Unix. + if not is_os('win') then + pending('N/A for non-windows') + return + end local exts = {'bat', 'exe', 'com', 'cmd'} setup(function() diff --git a/test/functional/vimscript/execute_spec.lua b/test/functional/vimscript/execute_spec.lua index a733b098f5..5fe3d787cb 100644 --- a/test/functional/vimscript/execute_spec.lua +++ b/test/functional/vimscript/execute_spec.lua @@ -8,7 +8,7 @@ local funcs = helpers.funcs local Screen = require('test.functional.ui.screen') local command = helpers.command local feed = helpers.feed -local iswin = helpers.iswin +local is_os = helpers.is_os describe('execute()', function() before_each(clear) @@ -265,7 +265,7 @@ describe('execute()', function() -- This deviates from vim behavior, but is consistent -- with how nvim currently displays the output. it('captures shell-command output', function() - local win_lf = iswin() and '\13' or '' + local win_lf = is_os('win') and '\13' or '' eq('\n:!echo foo\r\n\nfoo'..win_lf..'\n', funcs.execute('!echo foo')) end) diff --git a/test/functional/vimscript/exepath_spec.lua b/test/functional/vimscript/exepath_spec.lua index db96b79743..056f67e0ad 100644 --- a/test/functional/vimscript/exepath_spec.lua +++ b/test/functional/vimscript/exepath_spec.lua @@ -1,19 +1,20 @@ local helpers = require('test.functional.helpers')(after_each) -local eq, clear, call, iswin = - helpers.eq, helpers.clear, helpers.call, helpers.iswin +local eq, clear, call = + helpers.eq, helpers.clear, helpers.call local command = helpers.command local exc_exec = helpers.exc_exec local matches = helpers.matches +local is_os = helpers.is_os describe('exepath()', function() before_each(clear) it('returns 1 for commands in $PATH', function() - local exe = iswin() and 'ping' or 'ls' - local ext_pat = iswin() and '%.EXE$' or '$' + local exe = is_os('win') and 'ping' or 'ls' + local ext_pat = is_os('win') and '%.EXE$' or '$' matches(exe .. ext_pat, call('exepath', exe)) command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') - ext_pat = iswin() and '%.CMD$' or '$' + ext_pat = is_os('win') and '%.CMD$' or '$' matches('null' .. ext_pat, call('exepath', 'null')) matches('true' .. ext_pat, call('exepath', 'true')) matches('false' .. ext_pat, call('exepath', 'false')) @@ -30,7 +31,7 @@ describe('exepath()', function() end end) - if iswin() then + if is_os('win') then it('append extension if omitted', function() local filename = 'cmd' local pathext = '.exe' diff --git a/test/functional/vimscript/fnamemodify_spec.lua b/test/functional/vimscript/fnamemodify_spec.lua index d54a6db417..c3ecdd853c 100644 --- a/test/functional/vimscript/fnamemodify_spec.lua +++ b/test/functional/vimscript/fnamemodify_spec.lua @@ -1,12 +1,12 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq -local iswin = helpers.iswin local fnamemodify = helpers.funcs.fnamemodify local getcwd = helpers.funcs.getcwd local command = helpers.command local write_file = helpers.write_file local alter_slashes = helpers.alter_slashes +local is_os = helpers.is_os local function eq_slashconvert(expected, got) eq(alter_slashes(expected), alter_slashes(got)) @@ -27,7 +27,7 @@ describe('fnamemodify()', function() local root = helpers.pathroot() eq(root, fnamemodify([[/]], ':p:h')) eq(root, fnamemodify([[/]], ':p')) - if iswin() then + if is_os('win') then eq(root, fnamemodify([[\]], ':p:h')) eq(root, fnamemodify([[\]], ':p')) command('set shellslash') @@ -114,7 +114,7 @@ describe('fnamemodify()', function() it('handles shell escape', function() local expected - if iswin() then + if is_os('win') then -- we expand with double-quotes on Windows expected = [["hello there! quote ' newline]] .. '\n' .. [["]] else diff --git a/test/functional/vimscript/functions_spec.lua b/test/functional/vimscript/functions_spec.lua index 20c1400030..09b3334989 100644 --- a/test/functional/vimscript/functions_spec.lua +++ b/test/functional/vimscript/functions_spec.lua @@ -9,12 +9,12 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eval = helpers.eval -local iswin = helpers.iswin local matches = helpers.matches +local is_os = helpers.is_os before_each(clear) it('windowsversion()', function() clear() - matches(iswin() and '^%d+%.%d+$' or '^$', eval('windowsversion()')) + matches(is_os('win') and '^%d+%.%d+$' or '^$', eval('windowsversion()')) end) diff --git a/test/functional/vimscript/has_spec.lua b/test/functional/vimscript/has_spec.lua index 4d9b226434..2e26d603b3 100644 --- a/test/functional/vimscript/has_spec.lua +++ b/test/functional/vimscript/has_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local clear = helpers.clear local funcs = helpers.funcs -local iswin = helpers.iswin +local is_os = helpers.is_os describe('has()', function() before_each(clear) @@ -51,7 +51,7 @@ describe('has()', function() end) it('"unnamedplus"', function() - if (not iswin()) and funcs.has("clipboard") == 1 then + if (not is_os('win')) and funcs.has("clipboard") == 1 then eq(1, funcs.has("unnamedplus")) else eq(0, funcs.has("unnamedplus")) diff --git a/test/functional/vimscript/hostname_spec.lua b/test/functional/vimscript/hostname_spec.lua index 6112cf64e3..7d4baa7213 100644 --- a/test/functional/vimscript/hostname_spec.lua +++ b/test/functional/vimscript/hostname_spec.lua @@ -3,7 +3,7 @@ local eq = helpers.eq local ok = helpers.ok local call = helpers.call local clear = helpers.clear -local iswin = helpers.iswin +local is_os = helpers.is_os describe('hostname()', function() before_each(clear) @@ -13,8 +13,8 @@ describe('hostname()', function() ok(string.len(actual) > 0) if call('executable', 'hostname') == 1 then local expected = string.gsub(call('system', 'hostname'), '[\n\r]', '') - eq((iswin() and expected:upper() or expected), - (iswin() and actual:upper() or actual)) + eq((is_os('win') and expected:upper() or expected), + (is_os('win') and actual:upper() or actual)) end end) end) diff --git a/test/functional/vimscript/msgpack_functions_spec.lua b/test/functional/vimscript/msgpack_functions_spec.lua index cab67d77e4..de5a721efe 100644 --- a/test/functional/vimscript/msgpack_functions_spec.lua +++ b/test/functional/vimscript/msgpack_functions_spec.lua @@ -5,7 +5,7 @@ local eval, eq = helpers.eval, helpers.eq local command = helpers.command local nvim = helpers.nvim local exc_exec = helpers.exc_exec -local iswin = helpers.iswin +local is_os = helpers.is_os describe('msgpack*() functions', function() before_each(clear) @@ -467,7 +467,7 @@ describe('msgpackparse() function', function() eval(cmd) eval(cmd) -- do it again (try to force segfault) local api_info = eval(cmd) -- do it again - if iswin() then + if is_os('win') then helpers.assert_alive() pending('msgpackparse() has a bug on windows') return diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua index 6e95459630..14c87d9d93 100644 --- a/test/functional/vimscript/server_spec.lua +++ b/test/functional/vimscript/server_spec.lua @@ -1,11 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths -local iswin = helpers.iswin local ok = helpers.ok local matches = helpers.matches local pcall_err = helpers.pcall_err local mkdir = helpers.mkdir +local is_os = helpers.is_os local function clear_serverlist() for _, server in pairs(funcs.serverlist()) do @@ -19,7 +19,7 @@ describe('server', function() mkdir(dir) clear({ env={ XDG_RUNTIME_DIR=dir } }) matches(dir, funcs.stdpath('run')) - if not iswin() then + if not is_os('win') then matches(dir, funcs.serverstart()) end end) @@ -65,7 +65,7 @@ describe('server', function() eq('', meths.get_vvar('servername')) -- v:servername and $NVIM take the next available server. - local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]] + local servername = (is_os('win') and [[\\.\pipe\Xtest-functional-server-pipe]] or './Xtest-functional-server-socket') funcs.serverstart(servername) eq(servername, meths.get_vvar('servername')) @@ -130,7 +130,7 @@ describe('server', function() local n = eval('len(serverlist())') -- Add some servers. - local servs = (iswin() + local servs = (is_os('win') and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] } or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] }) for _, s in ipairs(servs) do @@ -164,7 +164,7 @@ describe('startup --listen', function() end) it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function() - local addr = (iswin() and [[\\.\pipe\Xtest-listen-pipe]] + local addr = (is_os('win') and [[\\.\pipe\Xtest-listen-pipe]] or './Xtest-listen-pipe') clear({ env={ NVIM_LISTEN_ADDRESS='./Xtest-env-pipe' }, args={ '--listen', addr } }) diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua index ed822add72..dbf734b51a 100644 --- a/test/functional/vimscript/system_spec.lua +++ b/test/functional/vimscript/system_spec.lua @@ -9,9 +9,9 @@ local command = helpers.command local insert = helpers.insert local expect = helpers.expect local exc_exec = helpers.exc_exec -local iswin = helpers.iswin local os_kill = helpers.os_kill local pcall_err = helpers.pcall_err +local is_os = helpers.is_os local Screen = require('test.functional.ui.screen') @@ -85,7 +85,7 @@ describe('system()', function() end) it('does NOT run in shell', function() - if iswin() then + if is_os('win') then eq("%PATH%\n", eval("system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])")) else eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])")) @@ -94,7 +94,7 @@ describe('system()', function() end) it('sets v:shell_error', function() - if iswin() then + if is_os('win') then eval([[system("cmd.exe /c exit")]]) eq(0, eval('v:shell_error')) eval([[system("cmd.exe /c exit 1")]]) @@ -123,7 +123,7 @@ describe('system()', function() screen:attach() end) - if iswin() then + if is_os('win') then local function test_more() eq('root = true', eval([[get(split(system('"more" ".editorconfig"'), "\n"), 0, '')]])) end @@ -184,7 +184,7 @@ describe('system()', function() -- * on Windows, expected to default to Western European enc -- * on Linux, expected to default to UTF8 command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']]) - eq(iswin() and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]])) + eq(is_os('win') and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]])) end) it('`echo` and waits for its return', function() @@ -213,7 +213,7 @@ describe('system()', function() screen:try_resize(72, 14) feed(':4verbose echo system("echo hi")<cr>') - if iswin() then + if is_os('win') then screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]]} else screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]]} @@ -243,7 +243,7 @@ describe('system()', function() end) it('`yes` interrupted with CTRL-C', function() - feed(':call system("' .. (iswin() + feed(':call system("' .. (is_os('win') and 'for /L %I in (1,0,2) do @echo y' or 'yes') .. '")<cr>') screen:expect([[ @@ -260,7 +260,7 @@ describe('system()', function() ~ | ~ | ~ | -]] .. (iswin() +]] .. (is_os('win') and [[ :call system("for /L %I in (1,0,2) do @echo y") |]] or [[ @@ -286,7 +286,7 @@ describe('system()', function() it('`yes` interrupted with mapped CTRL-C', function() command('nnoremap <C-C> i') - feed(':call system("' .. (iswin() + feed(':call system("' .. (is_os('win') and 'for /L %I in (1,0,2) do @echo y' or 'yes') .. '")<cr>') screen:expect([[ @@ -303,7 +303,7 @@ describe('system()', function() ~ | ~ | ~ | -]] .. (iswin() +]] .. (is_os('win') and [[ :call system("for /L %I in (1,0,2) do @echo y") |]] or [[ @@ -330,7 +330,7 @@ describe('system()', function() describe('passing no input', function() it('returns the program output', function() - if iswin() then + if is_os('win') then eq("echoed\n", eval('system("echo echoed")')) else eq("echoed", eval('system("echo -n echoed")')) @@ -438,7 +438,7 @@ describe('systemlist()', function() before_each(clear) it('sets v:shell_error', function() - if iswin() then + if is_os('win') then eval([[systemlist("cmd.exe /c exit")]]) eq(0, eval('v:shell_error')) eval([[systemlist("cmd.exe /c exit 1")]]) @@ -617,12 +617,12 @@ describe('systemlist()', function() return end helpers.set_shell_powershell() - eq({iswin() and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]])) + eq({is_os('win') and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]])) -- Sanity test w/ default encoding -- * on Windows, expected to default to Western European enc -- * on Linux, expected to default to UTF8 command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']]) - eq({iswin() and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]])) + eq({is_os('win') and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]])) end) end) @@ -639,7 +639,7 @@ describe('shell :!', function() 1 4 2]]) - if iswin() then + if is_os('win') then feed(':4verbose %!sort /R<cr>') screen:expect{ any=[[Executing command: .?& { Get%-Content .* | & sort /R } 2>&1 | Out%-File %-Encoding UTF8 .*; exit $LastExitCode"]] diff --git a/test/helpers.lua b/test/helpers.lua index 68c1b17dbc..eef47563a0 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -269,14 +269,10 @@ function module.check_logs() table.concat(runtime_errors, ', '))) end -function module.iswin() - return package.config:sub(1,1) == '\\' -end - --- Gets (lowercase) OS name from CMake, uname, or "win" if iswin(). -module.uname = (function() +-- Gets (lowercase) OS name from CMake, uname, or manually check if on Windows +do local platform = nil - return (function() + function module.uname() if platform then return platform end @@ -290,22 +286,28 @@ module.uname = (function() if status then platform = string.lower(f:read("*l")) f:close() - elseif module.iswin() then + elseif package.config:sub(1,1) == '\\' then platform = 'windows' else error('unknown platform') end return platform - end) -end)() + end +end function module.is_os(s) - if not (s == 'win' or s == 'mac' or s == 'unix') then + if not (s == 'win' + or s == 'mac' + or s == 'freebsd' + or s == 'openbsd' + or s == 'bsd') then error('unknown platform: '..tostring(s)) end - return ((s == 'win' and module.iswin()) + return ((s == 'win' and module.uname() == 'windows') or (s == 'mac' and module.uname() == 'darwin') - or (s == 'unix')) + or (s == 'freebsd' and module.uname() == 'freebsd') + or (s == 'openbsd' and module.uname() == 'openbsd') + or (s == 'bsd' and string.find(module.uname(), 'bsd'))) end local function tmpdir_get() @@ -331,11 +333,11 @@ module.tmpname = (function() return fname else local fname = os.tmpname() - if module.uname() == 'windows' and fname:sub(1, 2) == '\\s' then + if module.is_os('win') and fname:sub(1, 2) == '\\s' then -- In Windows tmpname() returns a filename starting with -- special sequence \s, prepend $TEMP path return tmpdir..fname - elseif fname:match('^/tmp') and module.uname() == 'darwin' then + elseif fname:match('^/tmp') and module.is_os('mac') then -- In OS X /tmp links to /private/tmp return '/private'..fname else @@ -378,14 +380,14 @@ function module.check_cores(app, force) exc_re = { os.getenv('NVIM_TEST_CORE_EXC_RE'), local_tmpdir } db_cmd = os.getenv('NVIM_TEST_CORE_DB_CMD') or gdb_db_cmd random_skip = os.getenv('NVIM_TEST_CORE_RANDOM_SKIP') - elseif 'darwin' == module.uname() then + elseif module.is_os('mac') then initial_path = '/cores' re = nil exc_re = { local_tmpdir } db_cmd = lldb_db_cmd else initial_path = '.' - if 'freebsd' == module.uname() then + if module.is_os('freebsd') then re = '/nvim.core$' else re = '/core[^/]*$' @@ -800,7 +802,7 @@ function module.write_file(name, text, no_dedent, append) file:close() end -function module.isCI(name) +function module.is_ci(name) local any = (name == nil) assert(any or name == 'github' or name == 'cirrus') local gh = ((any or name == 'github') and nil ~= os.getenv('GITHUB_ACTIONS')) @@ -812,7 +814,7 @@ end -- Also moves the file to "${NVIM_LOG_FILE}.displayed" on CI environments. function module.read_nvim_log(logfile, ci_rename) logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog' - local is_ci = module.isCI() + local is_ci = module.is_ci() local keep = is_ci and 100 or 10 local lines = module.read_file_list(logfile, -keep) or {} local log = (('-'):rep(78)..'\n' |