aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml10
-rw-r--r--cmake.deps/CMakeLists.txt4
-rw-r--r--runtime/doc/news.txt6
-rw-r--r--runtime/doc/treesitter.txt17
-rw-r--r--runtime/lua/nvim/health.lua470
-rw-r--r--runtime/lua/vim/health.lua15
-rw-r--r--runtime/lua/vim/treesitter/query.lua10
-rw-r--r--scripts/gen_help_html.lua23
-rw-r--r--src/nvim/api/private/helpers.c13
-rw-r--r--src/nvim/ex_getln.c8
-rw-r--r--src/nvim/globals.h4
-rw-r--r--src/nvim/main.c36
-rw-r--r--src/nvim/main.h3
-rw-r--r--src/nvim/os/fs.c4
-rw-r--r--src/nvim/os/input.c18
-rw-r--r--src/nvim/os/input.h2
-rw-r--r--src/nvim/os/os_win_console.c4
-rw-r--r--src/nvim/testdir/test_shell.vim209
-rw-r--r--src/nvim/testdir/test_startup.vim35
-rw-r--r--src/nvim/testdir/test_system.vim36
-rw-r--r--src/nvim/tui/input.c16
-rw-r--r--src/nvim/tui/tui.c11
-rw-r--r--src/nvim/ui_client.c9
-rw-r--r--test/functional/api/vim_spec.lua8
-rw-r--r--test/functional/autocmd/autocmd_spec.lua8
-rw-r--r--test/functional/autocmd/cmdline_spec.lua26
-rw-r--r--test/functional/autocmd/termxx_spec.lua2
-rw-r--r--test/functional/core/exit_spec.lua6
-rw-r--r--test/functional/editor/mark_spec.lua24
-rw-r--r--test/functional/legacy/gf_spec.lua3
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua8
-rw-r--r--test/functional/vimscript/api_functions_spec.lua3
-rw-r--r--test/functional/vimscript/ctx_functions_spec.lua4
33 files changed, 629 insertions, 426 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7699233ea3..399ac24ecc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -83,8 +83,10 @@ jobs:
args: --check runtime/
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
- name: lintlua
- run: make lintlua
+ name: luacheck
+ run: |
+ cmake -B $BUILD_DIR -G Ninja
+ cmake --build $BUILD_DIR --target lintlua-luacheck
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
name: lintsh
@@ -162,8 +164,8 @@ jobs:
run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
- name: lintc
- run: make lintc
+ name: clint.py
+ run: cmake --build build --target lintc-clint
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
name: check-single-includes
diff --git a/cmake.deps/CMakeLists.txt b/cmake.deps/CMakeLists.txt
index 72268141ca..8844613655 100644
--- a/cmake.deps/CMakeLists.txt
+++ b/cmake.deps/CMakeLists.txt
@@ -153,8 +153,8 @@ set(MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/c-4.0.0/m
set(MSGPACK_SHA256 420fe35e7572f2a168d17e660ef981a589c9cbe77faa25eb34a520e1fcc032c8)
# https://github.com/LuaJIT/LuaJIT/tree/v2.1
-set(LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/a04480e311f93d3ceb2f92549cad3fffa38250ef.tar.gz)
-set(LUAJIT_SHA256 297e9c06d934753f9553fa7d1c1e43381e20094ed3289e0e145dd5f3c203a27e)
+set(LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/d0e88930ddde28ff662503f9f20facf34f7265aa.tar.gz)
+set(LUAJIT_SHA256 aa354d1265814db5a1ee9dfff6049e19b148e1fd818f1ecfa4fcf2b19f6e4dd9)
set(LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz)
set(LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333)
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index ce07c3035c..8a9736e1c2 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -159,11 +159,17 @@ The following changes to existing APIs or features add new behavior.
resulting in a nvim binary which only could be run headless or embedded
in an external process. As of this version, TUI is always available.
+• API calls now show more information about where an exception happened.
+
==============================================================================
REMOVED FEATURES *news-removed*
The following deprecated functions or APIs were removed.
+• It is no longer possible to scroll the whole screen when showing messages
+ longer than 'cmdheight'. |msgsep| is now always enabled even if 'display'
+ doesn't contain the "msgsep" flag.
+
• `filetype.vim` is removed in favor of |lua-filetype|
(Note that filetype logic and tests still align with Vim, so additions or
changes need to be contributed there first.)
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index 096cec6678..917863eef8 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -708,8 +708,15 @@ add_directive({name}, {handler}, {force})
Parameters: ~
• {name} (string) Name of the directive, without leading #
- • {handler} function(match:string, pattern:string, bufnr:number,
- predicate:function, metadata:table)
+ • {handler} function(match:table, pattern:string, bufnr:number,
+ predicate:string[], metadata:table)
+ • match: see |treesitter-query|
+ • node-level data are accessible via `match[capture_id]`
+
+ • pattern: see |treesitter-query|
+ • predicate: list of strings containing the full directive
+ being called, e.g. `(node (#set! conceal "-"))` would get
+ the predicate `{ "#set!", "conceal", "-" }`
*vim.treesitter.query.add_predicate()*
add_predicate({name}, {handler}, {force})
@@ -717,8 +724,10 @@ add_predicate({name}, {handler}, {force})
Parameters: ~
• {name} (string) Name of the predicate, without leading #
- • {handler} function(match:string, pattern:string, bufnr:number,
- predicate:function)
+ • {handler} function(match:table, pattern:string, bufnr:number,
+ predicate:string[])
+ • see |vim.treesitter.query.add_directive()| for argument
+ meanings
*vim.treesitter.query.get_node_text()*
get_node_text({node}, {source}, {opts})
diff --git a/runtime/lua/nvim/health.lua b/runtime/lua/nvim/health.lua
index c00b921d5c..e11574ee97 100644
--- a/runtime/lua/nvim/health.lua
+++ b/runtime/lua/nvim/health.lua
@@ -1,6 +1,22 @@
local M = {}
local health = require('vim.health')
+local fn_bool = function(key)
+ return function(...)
+ return vim.fn[key](...) == 1
+ end
+end
+
+local has = fn_bool('has')
+local executable = fn_bool('executable')
+local empty = fn_bool('empty')
+local filereadable = fn_bool('filereadable')
+local filewritable = fn_bool('filewritable')
+
+local shell_error = function()
+ return vim.v.shell_error ~= 0
+end
+
local suggest_faq = 'https://github.com/neovim/neovim/wiki/Building-Neovim#optimized-builds'
local function check_runtime()
@@ -37,15 +53,6 @@ end
local function check_config()
health.report_start('Configuration')
local ok = true
- local empty = function(o)
- return 0 ~= vim.fn.empty(o)
- end
- local filereadable = function(o)
- return 0 ~= vim.fn.filereadable(o)
- end
- local filewritable = function(o)
- return 0 ~= vim.fn.filewritable(o)
- end
local vimrc = (
empty(vim.env.MYVIMRC) and vim.fn.stdpath('config') .. '/init.vim' or vim.env.MYVIMRC
@@ -65,7 +72,7 @@ local function check_config()
health.report_error('$VIM is invalid: ' .. vim.env.VIM)
end
- if 1 == vim.fn.exists('$NVIM_TUI_ENABLE_CURSOR_SHAPE') then
+ if vim.env.NVIM_TUI_ENABLE_CURSOR_SHAPE then
ok = false
health.report_warn('$NVIM_TUI_ENABLE_CURSOR_SHAPE is ignored in Nvim 0.2+', {
"Use the 'guicursor' option to configure cursor shape. :help 'guicursor'",
@@ -139,240 +146,245 @@ local function check_config()
end
local function check_performance()
- vim.api.nvim_exec([=[
- func! s:check_performance() abort
- let s:suggest_faq = ']=] .. suggest_faq .. [=['
-
- call health#report_start('Performance')
-
- " check buildtype
- let s:buildtype = matchstr(execute('version'), '\v\cbuild type:?\s*[^\n\r\t ]+')
- if empty(s:buildtype)
- call health#report_error('failed to get build type from :version')
- elseif s:buildtype =~# '\v(MinSizeRel|Release|RelWithDebInfo)'
- call health#report_ok(s:buildtype)
- else
- call health#report_info(s:buildtype)
- call health#report_warn(
- \ 'Non-optimized '.(has('debug')?'(DEBUG) ':'').'build. Nvim will be slower.',
- \ ['Install a different Nvim package, or rebuild with `CMAKE_BUILD_TYPE=RelWithDebInfo`.',
- \ s:suggest_faq])
- endif
-
- " check for slow shell invocation
- let s:slow_cmd_time = 1.5
- let s:start_time = reltime()
- call system('echo')
- let s:elapsed_time = reltimefloat(reltime(s:start_time))
- if s:elapsed_time > s:slow_cmd_time
- call health#report_warn(
- \ 'Slow shell invocation (took '.printf('%.2f', s:elapsed_time).' seconds).')
- endif
- endf
-
- call s:check_performance()
- ]=], false)
+ health.report_start('Performance')
+
+ -- Check buildtype
+ local buildtype = vim.fn.matchstr(vim.fn.execute('version'), [[\v\cbuild type:?\s*[^\n\r\t ]+]])
+ if empty(buildtype) then
+ health.report_error('failed to get build type from :version')
+ elseif vim.regex([[\v(MinSizeRel|Release|RelWithDebInfo)]]):match_str(buildtype) then
+ health.report_ok(buildtype)
+ else
+ health.report_info(buildtype)
+ health.report_warn(
+ 'Non-optimized ' .. (has('debug') and '(DEBUG) ' or '') .. 'build. Nvim will be slower.',
+ {
+ 'Install a different Nvim package, or rebuild with `CMAKE_BUILD_TYPE=RelWithDebInfo`.',
+ suggest_faq,
+ }
+ )
+ end
+
+ -- check for slow shell invocation
+ local slow_cmd_time = 1.5
+ local start_time = vim.fn.reltime()
+ vim.fn.system('echo')
+ local elapsed_time = vim.fn.reltimefloat(vim.fn.reltime(start_time))
+ if elapsed_time > slow_cmd_time then
+ health.report_warn(
+ 'Slow shell invocation (took ' .. vim.fn.printf('%.2f', elapsed_time) .. ' seconds).'
+ )
+ end
end
-- Load the remote plugin manifest file and check for unregistered plugins
local function check_rplugin_manifest()
- vim.api.nvim_exec(
- [=[
- func! s:check_rplugin_manifest() abort
- call health#report_start('Remote Plugins')
- let existing_rplugins = {}
-
- for item in remote#host#PluginsForHost('python')
- let existing_rplugins[item.path] = 'python'
- endfor
-
- for item in remote#host#PluginsForHost('python3')
- let existing_rplugins[item.path] = 'python3'
- endfor
-
- let require_update = 0
-
- for path in map(split(&runtimepath, ','), 'resolve(v:val)')
- let python_glob = glob(path.'/rplugin/python*', 1, 1)
- if empty(python_glob)
- continue
- endif
-
- let python_dir = python_glob[0]
- let python_version = fnamemodify(python_dir, ':t')
-
- for script in glob(python_dir.'/*.py', 1, 1)
- \ + glob(python_dir.'/*/__init__.py', 1, 1)
- let contents = join(readfile(script))
- if contents =~# '\<\%(from\|import\)\s\+neovim\>'
- if script =~# '[\/]__init__\.py$'
- let script = tr(fnamemodify(script, ':h'), '\', '/')
- endif
-
- if !has_key(existing_rplugins, script)
- let msg = printf('"%s" is not registered.', fnamemodify(path, ':t'))
- if python_version ==# 'pythonx'
- if !has('python3')
- let msg .= ' (python3 not available)'
- endif
- elseif !has(python_version)
- let msg .= printf(' (%s not available)', python_version)
- else
- let require_update = 1
- endif
-
- call health#report_warn(msg)
- endif
-
- break
- endif
- endfor
- endfor
-
- if require_update
- call health#report_warn('Out of date', ['Run `:UpdateRemotePlugins`'])
- else
- call health#report_ok('Up to date')
- endif
- endf
+ health.report_start('Remote Plugins')
- call s:check_rplugin_manifest()
- ]=],
- false
- )
+ local existing_rplugins = {}
+ for _, item in ipairs(vim.fn['remote#host#PluginsForHost']('python')) do
+ existing_rplugins[item.path] = 'python'
+ end
+
+ for item in ipairs(vim.fn['remote#host#PluginsForHost']('python3')) do
+ existing_rplugins[item.path] = 'python3'
+ end
+
+ local require_update = false
+ local handle_path = function(path)
+ local python_glob = vim.fn.glob(path .. '/rplugin/python*', true, true)
+ if empty(python_glob) then
+ return
+ end
+
+ local python_dir = python_glob[1]
+ local python_version = vim.fn.fnamemodify(python_dir, ':t')
+
+ local scripts = vim.fn.glob(python_dir .. '/*.py', true, true)
+ vim.list_extend(scripts, vim.fn.glob(python_dir .. '/*/__init__.py', true, true))
+
+ for script in ipairs(scripts) do
+ local contents = vim.fn.join(vim.fn.readfile(script))
+ if vim.regex([[\<\%(from\|import\)\s\+neovim\>]]):match_str(contents) then
+ if vim.regex([[[\/]__init__\.py$]]):match_str(script) then
+ script = vim.fn.tr(vim.fn.fnamemodify(script, ':h'), '\\', '/')
+ end
+ if not existing_rplugins[script] then
+ local msg = vim.fn.printf('"%s" is not registered.', vim.fn.fnamemodify(path, ':t'))
+ if python_version == 'pythonx' then
+ if not has('python3') then
+ msg = msg .. ' (python3 not available)'
+ end
+ elseif not has(python_version) then
+ msg = msg .. vim.fn.printf(' (%s not available)', python_version)
+ else
+ require_update = true
+ end
+
+ health.report_warn(msg)
+ end
+
+ break
+ end
+ end
+ end
+
+ for _, path in ipairs(vim.fn.map(vim.fn.split(vim.o.runtimepath, ','), 'resolve(v:val)')) do
+ handle_path(path)
+ end
+
+ if require_update then
+ health.report_warn('Out of date', { 'Run `:UpdateRemotePlugins`' })
+ else
+ health.report_ok('Up to date')
+ end
end
local function check_tmux()
- vim.api.nvim_exec([=[
- let s:suggest_faq = ']=] .. suggest_faq .. [=['
-
- func! s:get_tmux_option(option) abort
- let cmd = 'tmux show-option -qvg '.a:option " try global scope
- let out = system(split(cmd))
- let val = substitute(out, '\v(\s|\r|\n)', '', 'g')
- if v:shell_error
- call health#report_error('command failed: '.cmd."\n".out)
+ if empty(vim.env.TMUX) or not executable('tmux') then
+ return
+ end
+
+ local get_tmux_option = function(option)
+ local cmd = 'tmux show-option -qvg ' .. option -- try global scope
+ local out = vim.fn.system(vim.fn.split(cmd))
+ local val = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ if shell_error() then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
return 'error'
- elseif empty(val)
- let cmd = 'tmux show-option -qvgs '.a:option " try session scope
- let out = system(split(cmd))
- let val = substitute(out, '\v(\s|\r|\n)', '', 'g')
- if v:shell_error
- call health#report_error('command failed: '.cmd."\n".out)
+ elseif empty(val) then
+ cmd = 'tmux show-option -qvgs ' .. option -- try session scope
+ out = vim.fn.system(vim.fn.split(cmd))
+ val = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ if shell_error() then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
return 'error'
- endif
- endif
+ end
+ end
return val
- endf
+ end
- func! s:check_tmux() abort
- if empty($TMUX) || !executable('tmux')
- return
- endif
- call health#report_start('tmux')
-
- " check escape-time
- let suggestions = ["set escape-time in ~/.tmux.conf:\nset-option -sg escape-time 10",
- \ s:suggest_faq]
- let tmux_esc_time = s:get_tmux_option('escape-time')
- if tmux_esc_time !=# 'error'
- if empty(tmux_esc_time)
- call health#report_error('`escape-time` is not set', suggestions)
- elseif tmux_esc_time > 300
- call health#report_error(
- \ '`escape-time` ('.tmux_esc_time.') is higher than 300ms', suggestions)
- else
- call health#report_ok('escape-time: '.tmux_esc_time)
- endif
- endif
-
- " check focus-events
- let suggestions = ["(tmux 1.9+ only) Set `focus-events` in ~/.tmux.conf:\nset-option -g focus-events on"]
- let tmux_focus_events = s:get_tmux_option('focus-events')
- if tmux_focus_events !=# 'error'
- if empty(tmux_focus_events) || tmux_focus_events !=# 'on'
- call health#report_warn(
- \ "`focus-events` is not enabled. |'autoread'| may not work.", suggestions)
- else
- call health#report_ok('focus-events: '.tmux_focus_events)
- endif
- endif
-
- " check default-terminal and $TERM
- call health#report_info('$TERM: '.$TERM)
- let cmd = 'tmux show-option -qvg default-terminal'
- let out = system(split(cmd))
- let tmux_default_term = substitute(out, '\v(\s|\r|\n)', '', 'g')
- if empty(tmux_default_term)
- let cmd = 'tmux show-option -qvgs default-terminal'
- let out = system(split(cmd))
- let tmux_default_term = substitute(out, '\v(\s|\r|\n)', '', 'g')
- endif
-
- if v:shell_error
- call health#report_error('command failed: '.cmd."\n".out)
- elseif tmux_default_term !=# $TERM
- call health#report_info('default-terminal: '.tmux_default_term)
- call health#report_error(
- \ '$TERM differs from the tmux `default-terminal` setting. Colors might look wrong.',
- \ ['$TERM may have been set by some rc (.bashrc, .zshrc, ...).'])
- elseif $TERM !~# '\v(tmux-256color|screen-256color)'
- call health#report_error(
- \ '$TERM should be "screen-256color" or "tmux-256color" in tmux. Colors might look wrong.',
- \ ["Set default-terminal in ~/.tmux.conf:\nset-option -g default-terminal \"screen-256color\"",
- \ s:suggest_faq])
- endif
-
- " check for RGB capabilities
- let info = system(['tmux', 'show-messages', '-JT'])
- let has_tc = stridx(info, " Tc: (flag) true") != -1
- let has_rgb = stridx(info, " RGB: (flag) true") != -1
- if !has_tc && !has_rgb
- call health#report_warn(
- \ "Neither Tc nor RGB capability set. True colors are disabled. |'termguicolors'| won't work properly.",
- \ ["Put this in your ~/.tmux.conf and replace XXX by your $TERM outside of tmux:\nset-option -sa terminal-overrides ',XXX:RGB'",
- \ "For older tmux versions use this instead:\nset-option -ga terminal-overrides ',XXX:Tc'"])
- endif
- endf
-
- call s:check_tmux()
- ]=], false)
+ health.report_start('tmux')
+
+ -- check escape-time
+ local suggestions =
+ { 'set escape-time in ~/.tmux.conf:\nset-option -sg escape-time 10', suggest_faq }
+ local tmux_esc_time = get_tmux_option('escape-time')
+ if tmux_esc_time ~= 'error' then
+ if empty(tmux_esc_time) then
+ health.report_error('`escape-time` is not set', suggestions)
+ elseif tmux_esc_time > 300 then
+ health.report_error(
+ '`escape-time` (' .. tmux_esc_time .. ') is higher than 300ms',
+ suggestions
+ )
+ else
+ health.report_ok('escape-time: ' .. tmux_esc_time)
+ end
+ end
+
+ -- check focus-events
+ local tmux_focus_events = get_tmux_option('focus-events')
+ if tmux_focus_events ~= 'error' then
+ if empty(tmux_focus_events) or tmux_focus_events ~= 'on' then
+ health.report_warn(
+ "`focus-events` is not enabled. |'autoread'| may not work.",
+ { '(tmux 1.9+ only) Set `focus-events` in ~/.tmux.conf:\nset-option -g focus-events on' }
+ )
+ else
+ health.report_ok('focus-events: ' .. tmux_focus_events)
+ end
+ end
+
+ -- check default-terminal and $TERM
+ health.report_info('$TERM: ' .. vim.env.TERM)
+ local cmd = 'tmux show-option -qvg default-terminal'
+ local out = vim.fn.system(vim.fn.split(cmd))
+ local tmux_default_term = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ if empty(tmux_default_term) then
+ cmd = 'tmux show-option -qvgs default-terminal'
+ out = vim.fn.system(vim.fn.split(cmd))
+ tmux_default_term = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ end
+
+ if shell_error() then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
+ elseif tmux_default_term ~= vim.env.TERM then
+ health.report_info('default-terminal: ' .. tmux_default_term)
+ health.report_error(
+ '$TERM differs from the tmux `default-terminal` setting. Colors might look wrong.',
+ { '$TERM may have been set by some rc (.bashrc, .zshrc, ...).' }
+ )
+ elseif not vim.regex([[\v(tmux-256color|screen-256color)]]):match_str(vim.env.TERM) then
+ health.report_error(
+ '$TERM should be "screen-256color" or "tmux-256color" in tmux. Colors might look wrong.',
+ {
+ 'Set default-terminal in ~/.tmux.conf:\nset-option -g default-terminal "screen-256color"',
+ suggest_faq,
+ }
+ )
+ end
+
+ -- check for RGB capabilities
+ local info = vim.fn.system({ 'tmux', 'show-messages', '-JT' })
+ local has_tc = vim.fn.stridx(info, ' Tc: (flag) true') ~= -1
+ local has_rgb = vim.fn.stridx(info, ' RGB: (flag) true') ~= -1
+ if not has_tc and not has_rgb then
+ health.report_warn(
+ "Neither Tc nor RGB capability set. True colors are disabled. |'termguicolors'| won't work properly.",
+ {
+ "Put this in your ~/.tmux.conf and replace XXX by your $TERM outside of tmux:\nset-option -sa terminal-overrides ',XXX:RGB'",
+ "For older tmux versions use this instead:\nset-option -ga terminal-overrides ',XXX:Tc'",
+ }
+ )
+ end
end
local function check_terminal()
- vim.api.nvim_exec(
- [=[
- func! s:check_terminal() abort
- if !executable('infocmp')
- return
- endif
- call health#report_start('terminal')
- let cmd = 'infocmp -L'
- let out = system(split(cmd))
- let kbs_entry = matchstr(out, 'key_backspace=[^,[:space:]]*')
- let kdch1_entry = matchstr(out, 'key_dc=[^,[:space:]]*')
-
- if v:shell_error
- \ && (!has('win32')
- \ || empty(matchstr(out,
- \ 'infocmp: couldn''t open terminfo file .\+'
- \ ..'\%(conemu\|vtpcon\|win32con\)')))
- call health#report_error('command failed: '.cmd."\n".out)
- else
- call health#report_info(printf('key_backspace (kbs) terminfo entry: `%s`', (empty(kbs_entry) ? '? (not found)' : kbs_entry)))
- call health#report_info(printf('key_dc (kdch1) terminfo entry: `%s`', (empty(kbs_entry) ? '? (not found)' : kdch1_entry)))
- endif
- for env_var in ['XTERM_VERSION', 'VTE_VERSION', 'TERM_PROGRAM', 'COLORTERM', 'SSH_TTY']
- if exists('$'.env_var)
- call health#report_info(printf('$%s="%s"', env_var, eval('$'.env_var)))
- endif
- endfor
- endf
-
- call s:check_terminal()
- ]=],
- false
- )
+ if not executable('infocmp') then
+ return
+ end
+
+ health.report_start('terminal')
+ local cmd = 'infocmp -L'
+ local out = vim.fn.system(vim.fn.split(cmd))
+ local kbs_entry = vim.fn.matchstr(out, 'key_backspace=[^,[:space:]]*')
+ local kdch1_entry = vim.fn.matchstr(out, 'key_dc=[^,[:space:]]*')
+
+ if
+ shell_error()
+ and (
+ not has('win32')
+ or empty(
+ vim.fn.matchstr(
+ out,
+ [[infocmp: couldn't open terminfo file .\+\%(conemu\|vtpcon\|win32con\)]]
+ )
+ )
+ )
+ then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
+ else
+ health.report_info(
+ vim.fn.printf(
+ 'key_backspace (kbs) terminfo entry: `%s`',
+ (empty(kbs_entry) and '? (not found)' or kbs_entry)
+ )
+ )
+
+ health.report_info(
+ vim.fn.printf(
+ 'key_dc (kdch1) terminfo entry: `%s`',
+ (empty(kbs_entry) and '? (not found)' or kdch1_entry)
+ )
+ )
+ end
+
+ for env_var in ipairs({ 'XTERM_VERSION', 'VTE_VERSION', 'TERM_PROGRAM', 'COLORTERM', 'SSH_TTY' }) do
+ if vim.env[env_var] then
+ health.report_info(vim.fn.printf('$%s="%s"', env_var, vim.env[env_var]))
+ end
+ end
end
function M.check()
diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua
index b875da0abc..044880e076 100644
--- a/runtime/lua/vim/health.lua
+++ b/runtime/lua/vim/health.lua
@@ -23,7 +23,20 @@ end
local path2name = function(path)
if path:match('%.lua$') then
-- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp"
- return path:gsub('.-lua[%\\%/]', '', 1):gsub('[%\\%/]', '.'):gsub('%.health.-$', '')
+
+ -- Get full path, make sure all slashes are '/'
+ path = vim.fs.normalize(path)
+
+ -- Remove everything up to the last /lua/ folder
+ path = path:gsub('^.*/lua/', '')
+
+ -- Remove the filename (health.lua)
+ path = vim.fn.fnamemodify(path, ':h')
+
+ -- Change slashes to dots
+ path = path:gsub('/', '.')
+
+ return path
else
-- Vim: transform "../autoload/health/provider.vim" into "provider"
return vim.fn.fnamemodify(path, ':t:r')
diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua
index 4bec5db527..dbf134573d 100644
--- a/runtime/lua/vim/treesitter/query.lua
+++ b/runtime/lua/vim/treesitter/query.lua
@@ -419,7 +419,8 @@ local directive_handlers = {
--- Adds a new predicate to be used in queries
---
---@param name string Name of the predicate, without leading #
----@param handler function(match:string, pattern:string, bufnr:number, predicate:function)
+---@param handler function(match:table, pattern:string, bufnr:number, predicate:string[])
+--- - see |vim.treesitter.query.add_directive()| for argument meanings
function M.add_predicate(name, handler, force)
if predicate_handlers[name] and not force then
error(string.format('Overriding %s', name))
@@ -436,7 +437,12 @@ end
--- metadata table `metadata[capture_id].key = value`
---
---@param name string Name of the directive, without leading #
----@param handler function(match:string, pattern:string, bufnr:number, predicate:function, metadata:table)
+---@param handler function(match:table, pattern:string, bufnr:number, predicate:string[], metadata:table)
+--- - match: see |treesitter-query|
+--- - node-level data are accessible via `match[capture_id]`
+--- - pattern: see |treesitter-query|
+--- - predicate: list of strings containing the full directive being called, e.g.
+--- `(node (#set! conceal "-"))` would get the predicate `{ "#set!", "conceal", "-" }`
function M.add_directive(name, handler, force)
if directive_handlers[name] and not force then
error(string.format('Overriding %s', name))
diff --git a/scripts/gen_help_html.lua b/scripts/gen_help_html.lua
index fa7c14eaa3..2563f2f410 100644
--- a/scripts/gen_help_html.lua
+++ b/scripts/gen_help_html.lua
@@ -60,19 +60,18 @@ local exclude_invalid = {
["'previewpopup'"] = "quickref.txt",
["'pvp'"] = "quickref.txt",
["'string'"] = "eval.txt",
- Query = "treesitter.txt",
- ["eq?"] = "treesitter.txt",
- ["lsp-request"] = "lsp.txt",
- matchit = "vim_diff.txt",
- ["matchit.txt"] = "help.txt",
+ Query = 'treesitter.txt',
+ ['eq?'] = 'treesitter.txt',
+ ['lsp-request'] = 'lsp.txt',
+ matchit = 'vim_diff.txt',
+ ['matchit.txt'] = 'help.txt',
["set!"] = "treesitter.txt",
- ["v:_null_blob"] = "builtin.txt",
- ["v:_null_dict"] = "builtin.txt",
- ["v:_null_list"] = "builtin.txt",
- ["v:_null_string"] = "builtin.txt",
- ["vim.lsp.buf_request()"] = "lsp.txt",
- ["vim.lsp.util.get_progress_messages()"] = "lsp.txt",
- ["vim.treesitter.start()"] = "treesitter.txt",
+ ['v:_null_blob'] = 'builtin.txt',
+ ['v:_null_dict'] = 'builtin.txt',
+ ['v:_null_list'] = 'builtin.txt',
+ ['v:_null_string'] = 'builtin.txt',
+ ['vim.lsp.buf_request()'] = 'lsp.txt',
+ ['vim.lsp.util.get_progress_messages()'] = 'lsp.txt',
}
-- False-positive "invalid URLs".
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index bf19c8c395..519f2cc5bf 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -150,7 +150,18 @@ bool try_end(Error *err)
xfree(msg);
}
} else if (did_throw) {
- api_set_error(err, kErrorTypeException, "%s", current_exception->value);
+ if (*current_exception->throw_name != NUL) {
+ if (current_exception->throw_lnum != 0) {
+ api_set_error(err, kErrorTypeException, "%s, line %" PRIdLINENR ": %s",
+ current_exception->throw_name, current_exception->throw_lnum,
+ current_exception->value);
+ } else {
+ api_set_error(err, kErrorTypeException, "%s: %s",
+ current_exception->throw_name, current_exception->value);
+ }
+ } else {
+ api_set_error(err, kErrorTypeException, "%s", current_exception->value);
+ }
discard_current_exception();
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 62586598bf..47ee1c00ce 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -773,7 +773,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool clea
tl_ret = try_leave(&tstate, &err);
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
- msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
+ msg_scroll = true;
+ msg_puts_attr(err.msg, HL_ATTR(HLF_E)|MSG_HIST);
api_clear_error(&err);
redrawcmd();
}
@@ -881,7 +882,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool clea
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
- semsg(e_autocmd_err, err.msg);
+ emsg(err.msg);
did_emsg = false;
api_clear_error(&err);
}
@@ -2544,7 +2545,8 @@ static void do_autocmd_cmdlinechanged(int firstc)
bool tl_ret = try_leave(&tstate, &err);
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
- msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
+ msg_scroll = true;
+ msg_puts_attr(err.msg, HL_ATTR(HLF_E)|MSG_HIST);
api_clear_error(&err);
redrawcmd();
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index aa8dbf6331..43b1d780be 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -494,6 +494,9 @@ EXTERN int v_dying INIT(= 0);
EXTERN bool stdin_isatty INIT(= true);
// is stdout a terminal?
EXTERN bool stdout_isatty INIT(= true);
+// is stderr a terminal?
+EXTERN bool stderr_isatty INIT(= true);
+
/// filedesc set by embedder for reading first buffer like `cmd | nvim -`
EXTERN int stdin_fd INIT(= -1);
@@ -999,7 +1002,6 @@ EXTERN char e_fnametoolong[] INIT(= N_("E856: Filename too long"));
EXTERN char e_float_as_string[] INIT(= N_("E806: using Float as a String"));
EXTERN char e_cannot_edit_other_buf[] INIT(= N_("E788: Not allowed to edit another buffer now"));
-EXTERN char e_autocmd_err[] INIT(= N_("E5500: autocmd has thrown an exception: %s"));
EXTERN char e_cmdmap_err[] INIT(= N_("E5520: <Cmd> mapping must end with <CR>"));
EXTERN char e_cmdmap_repeated[]
INIT(= N_("E5521: <Cmd> mapping must end with <CR> before second <Cmd>"));
diff --git a/src/nvim/main.c b/src/nvim/main.c
index cc78f7d36f..4dfb00f2db 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -286,7 +286,13 @@ int main(int argc, char **argv)
}
}
- bool use_builtin_ui = (!headless_mode && !embedded_mode && !silent_mode);
+#ifdef MSWIN
+ // on windows we use CONIN special file, thus we don't know this yet.
+ bool has_term = true;
+#else
+ bool has_term = (stdin_isatty || stdout_isatty || stderr_isatty);
+#endif
+ bool use_builtin_ui = (has_term && !headless_mode && !embedded_mode && !silent_mode);
// don't bind the server yet, if we are using builtin ui.
// This will be done when nvim server has been forked from the ui process
@@ -302,7 +308,7 @@ int main(int argc, char **argv)
bool remote_ui = (ui_client_channel_id != 0);
if (use_builtin_ui && !remote_ui) {
- ui_client_forward_stdin = !params.input_isatty;
+ ui_client_forward_stdin = !stdin_isatty;
uint64_t rv = ui_client_start_server(params.argc, params.argv);
if (!rv) {
os_errmsg("Failed to start Nvim server!\n");
@@ -359,8 +365,8 @@ int main(int argc, char **argv)
debug_break_level = params.use_debug_break_level;
// Read ex-commands if invoked with "-es".
- if (!params.input_isatty && !params.input_istext && silent_mode && exmode_active) {
- input_start(STDIN_FILENO);
+ if (!stdin_isatty && !params.input_istext && silent_mode && exmode_active) {
+ input_start();
}
if (ui_client_channel_id) {
@@ -539,7 +545,9 @@ int main(int argc, char **argv)
if (params.diff_mode) {
// set options in each window for "nvim -d".
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- diff_win_options(wp, true);
+ if (!wp->w_arg_idx_invalid) {
+ diff_win_options(wp, true);
+ }
}
}
@@ -637,8 +645,8 @@ void os_exit(int r)
if (!event_teardown() && r == 0) {
r = 1; // Exit with error if main_loop did not teardown gracefully.
}
- if (input_global_fd() >= 0) {
- stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
+ if (used_stdin) {
+ stream_set_blocking(STDIN_FILENO, true); // normalize stream (#2598)
}
ILOG("Nvim exit: %d", r);
@@ -783,9 +791,9 @@ void preserve_exit(void)
// Prevent repeated calls into this method.
if (really_exiting) {
- if (input_global_fd() >= 0) {
+ if (used_stdin) {
// normalize stream (#2598)
- stream_set_blocking(input_global_fd(), true);
+ stream_set_blocking(STDIN_FILENO, true);
}
exit(2);
}
@@ -961,7 +969,7 @@ static bool edit_stdin(mparm_T *parmp)
bool implicit = !headless_mode
&& !(embedded_mode && stdin_fd <= 0)
&& (!exmode_active || parmp->input_istext)
- && !parmp->input_isatty
+ && !stdin_isatty
&& parmp->scriptin == NULL; // `-s -` was not given.
return parmp->had_stdin_file || implicit;
}
@@ -1447,11 +1455,9 @@ static void init_startuptime(mparm_T *paramp)
static void check_and_set_isatty(mparm_T *paramp)
{
- stdin_isatty
- = paramp->input_isatty = os_isatty(STDIN_FILENO);
- stdout_isatty
- = paramp->output_isatty = os_isatty(STDOUT_FILENO);
- paramp->err_isatty = os_isatty(STDERR_FILENO);
+ stdin_isatty = os_isatty(STDIN_FILENO);
+ stdout_isatty = os_isatty(STDOUT_FILENO);
+ stderr_isatty = os_isatty(STDERR_FILENO);
TIME_MSG("window checked");
}
diff --git a/src/nvim/main.h b/src/nvim/main.h
index 46d7217364..2d54837872 100644
--- a/src/nvim/main.h
+++ b/src/nvim/main.h
@@ -30,10 +30,7 @@ typedef struct {
char *tagname; // tag from -t argument
char *use_ef; // 'errorfile' from -q argument
- bool input_isatty; // stdin is a terminal
bool input_istext; // stdin is text, not executable (-E/-Es)
- bool output_isatty; // stdout is a terminal
- bool err_isatty; // stderr is a terminal
int no_swap_file; // "-n" argument used
int use_debug_break_level;
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index e0449d468a..98ec9aa826 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -302,7 +302,9 @@ static bool is_executable(const char *name, char **abspath)
static bool is_executable_ext(const char *name, char **abspath)
FUNC_ATTR_NONNULL_ARG(1)
{
- const bool is_unix_shell = strstr((char *)path_tail(p_sh), "sh") != NULL;
+ const bool is_unix_shell = strstr(path_tail(p_sh), "powershell") == NULL
+ && strstr(path_tail(p_sh), "pwsh") == NULL
+ && strstr(path_tail(p_sh), "sh") != NULL;
char *nameext = strrchr(name, '.');
size_t nameext_len = nameext ? strlen(nameext) : 0;
xstrlcpy(os_buf, name, sizeof(os_buf));
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 5d2ac1e102..51cabfbcbf 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -44,7 +44,6 @@ typedef enum {
static Stream read_stream = { .closed = true }; // Input before UI starts.
static RBuffer *input_buffer = NULL;
static bool input_eof = false;
-static int global_fd = -1;
static bool blocking = false;
static int cursorhold_time = 0; ///< time waiting for CursorHold event
static int cursorhold_tb_change_cnt = 0; ///< tb_change_cnt when waiting started
@@ -58,25 +57,14 @@ void input_init(void)
input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN);
}
-void input_global_fd_init(int fd)
-{
- global_fd = fd;
-}
-
-/// Global TTY (or pipe for "-es") input stream, before UI starts.
-int input_global_fd(void)
-{
- return global_fd;
-}
-
-void input_start(int fd)
+void input_start(void)
{
if (!read_stream.closed) {
return;
}
- input_global_fd_init(fd);
- rstream_init_fd(&main_loop, &read_stream, fd, READ_BUFFER_SIZE);
+ used_stdin = true;
+ rstream_init_fd(&main_loop, &read_stream, STDIN_FILENO, READ_BUFFER_SIZE);
rstream_start(&read_stream, input_read_cb, NULL);
}
diff --git a/src/nvim/os/input.h b/src/nvim/os/input.h
index 7026781407..6f25efdc7b 100644
--- a/src/nvim/os/input.h
+++ b/src/nvim/os/input.h
@@ -7,6 +7,8 @@
#include "nvim/api/private/defs.h"
#include "nvim/event/multiqueue.h"
+EXTERN bool used_stdin INIT(= false);
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/input.h.generated.h"
#endif
diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c
index ec0f03a1dc..18f6e8b37b 100644
--- a/src/nvim/os/os_win_console.c
+++ b/src/nvim/os/os_win_console.c
@@ -14,7 +14,7 @@ static HWND hWnd = NULL;
static HICON hOrigIconSmall = NULL;
static HICON hOrigIcon = NULL;
-int os_get_conin_fd(void)
+int os_open_conin_fd(void)
{
const HANDLE conin_handle = CreateFile("CONIN$",
GENERIC_READ | GENERIC_WRITE,
@@ -30,7 +30,7 @@ int os_get_conin_fd(void)
void os_replace_stdin_to_conin(void)
{
close(STDIN_FILENO);
- const int conin_fd = os_get_conin_fd();
+ const int conin_fd = os_open_conin_fd();
assert(conin_fd == STDIN_FILENO);
}
diff --git a/src/nvim/testdir/test_shell.vim b/src/nvim/testdir/test_shell.vim
new file mode 100644
index 0000000000..8b9c7a5b12
--- /dev/null
+++ b/src/nvim/testdir/test_shell.vim
@@ -0,0 +1,209 @@
+" Test for the shell related options ('shell', 'shellcmdflag', 'shellpipe',
+" 'shellquote', 'shellredir', 'shellxescape', and 'shellxquote')
+
+source check.vim
+source shared.vim
+
+func Test_shell_options()
+ " The expected value of 'shellcmdflag', 'shellpipe', 'shellquote',
+ " 'shellredir', 'shellxescape', 'shellxquote' for the supported shells.
+ let shells = []
+ if has('unix')
+ let shells += [['sh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['ksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['mksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['zsh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['zsh-beta', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['bash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['fish', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['ash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['dash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
+ \ ['csh', '-c', '|& tee', '', '>&', '', ''],
+ \ ['tcsh', '-c', '|& tee', '', '>&', '', '']]
+ endif
+ if has('win32')
+ let shells += [['cmd', '/s /c', '>%s 2>&1', '', '>%s 2>&1', '', '"']]
+ endif
+
+ " start a new Vim instance with 'shell' set to each of the supported shells
+ " and check the default shell option settings
+ let after =<< trim END
+ let l = [&shell, &shellcmdflag, &shellpipe, &shellquote]
+ let l += [&shellredir, &shellxescape, &shellxquote]
+ call writefile([json_encode(l)], 'Xtestout')
+ qall!
+ END
+ for e in shells
+ if RunVim([], after, '--cmd "set shell=' .. e[0] .. '"')
+ call assert_equal(e, json_decode(readfile('Xtestout')[0]))
+ endif
+ endfor
+
+ " Test shellescape() for each of the shells.
+ for e in shells
+ exe 'set shell=' .. e[0]
+ if e[0] =~# '.*csh$' || e[0] =~# '.*csh.exe$'
+ let str1 = "'cmd \"arg1\" '\\''arg2'\\'' \\!%#'"
+ let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\\\!\\%\\#'"
+ elseif e[0] =~# '.*powershell$' || e[0] =~# '.*powershell.exe$'
+ let str1 = "'cmd \"arg1\" ''arg2'' !%#'"
+ let str2 = "'cmd \"arg1\" ''arg2'' \\!\\%\\#'"
+ else
+ let str1 = "'cmd \"arg1\" '\\''arg2'\\'' !%#'"
+ let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\!\\%\\#'"
+ endif
+ call assert_equal(str1, shellescape("cmd \"arg1\" 'arg2' !%#"), e[0])
+ call assert_equal(str2, shellescape("cmd \"arg1\" 'arg2' !%#", 1), e[0])
+
+ " Try running an external command with the shell.
+ if executable(e[0])
+ " set the shell options for the current 'shell'
+ let [&shellcmdflag, &shellpipe, &shellquote, &shellredir,
+ \ &shellxescape, &shellxquote] = e[1:6]
+ new
+ r !echo hello
+ call assert_equal('hello', substitute(getline(2), '\W', '', 'g'), e[0])
+ bwipe!
+ endif
+ endfor
+ set shell& shellcmdflag& shellpipe& shellquote&
+ set shellredir& shellxescape& shellxquote&
+ call delete('Xtestout')
+endfunc
+
+" Test for the 'shell' option
+func Test_shell()
+ throw 'Skipped: Nvim missing :shell currently'
+ CheckUnix
+ let save_shell = &shell
+ set shell=
+ let caught_e91 = 0
+ try
+ shell
+ catch /E91:/
+ let caught_e91 = 1
+ endtry
+ call assert_equal(1, caught_e91)
+ let &shell = save_shell
+endfunc
+
+" Test for the 'shellquote' option
+func Test_shellquote()
+ CheckUnix
+ set shellquote=#
+ set verbose=20
+ redir => v
+ silent! !echo Hello
+ redir END
+ set verbose&
+ set shellquote&
+ call assert_match(': "#echo Hello#"', v)
+endfunc
+
+" Test for the 'shellescape' option
+func Test_shellescape()
+ let save_shell = &shell
+ set shell=bash
+ call assert_equal("'text'", shellescape('text'))
+ call assert_equal("'te\"xt'", 'te"xt'->shellescape())
+ call assert_equal("'te'\\''xt'", shellescape("te'xt"))
+
+ call assert_equal("'te%xt'", shellescape("te%xt"))
+ call assert_equal("'te\\%xt'", shellescape("te%xt", 1))
+ call assert_equal("'te#xt'", shellescape("te#xt"))
+ call assert_equal("'te\\#xt'", shellescape("te#xt", 1))
+ call assert_equal("'te!xt'", shellescape("te!xt"))
+ call assert_equal("'te\\!xt'", shellescape("te!xt", 1))
+
+ call assert_equal("'te\nxt'", shellescape("te\nxt"))
+ call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1))
+ set shell=tcsh
+ call assert_equal("'te\\!xt'", shellescape("te!xt"))
+ call assert_equal("'te\\\\!xt'", shellescape("te!xt", 1))
+ call assert_equal("'te\\\nxt'", shellescape("te\nxt"))
+ call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1))
+
+ let &shell = save_shell
+endfunc
+
+" Test for 'shellslash'
+func Test_shellslash()
+ CheckOption shellslash
+ let save_shellslash = &shellslash
+ " The shell and cmdflag, and expected slash in tempname with shellslash set or
+ " unset. The assert checks the file separator before the leafname.
+ " ".*\\\\[^\\\\]*$"
+ let shells = [['cmd', '/c', '/', '/'],
+ \ ['powershell', '-Command', '/', '/'],
+ \ ['sh', '-c', '/', '/']]
+ for e in shells
+ exe 'set shell=' .. e[0] .. ' | set shellcmdflag=' .. e[1]
+ set noshellslash
+ let file = tempname()
+ call assert_match('^.\+' .. e[2] .. '[^' .. e[2] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' nossl')
+ set shellslash
+ let file = tempname()
+ call assert_match('^.\+' .. e[3] .. '[^' .. e[3] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' ssl')
+ endfor
+ let &shellslash = save_shellslash
+endfunc
+
+" Test for 'shellxquote'
+func Test_shellxquote()
+ CheckUnix
+
+ let save_shell = &shell
+ let save_sxq = &shellxquote
+ let save_sxe = &shellxescape
+
+ call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell')
+ call setfperm('Xtestshell', "r-x------")
+ set shell=./Xtestshell
+
+ set shellxquote=\\"
+ call feedkeys(":!pwd\<CR>\<CR>", 'xt')
+ call assert_equal(['Cmd: [-c "pwd"]'], readfile('Xlog'))
+
+ set shellxquote=(
+ call feedkeys(":!pwd\<CR>\<CR>", 'xt')
+ call assert_equal(['Cmd: [-c (pwd)]'], readfile('Xlog'))
+
+ set shellxquote=\\"(
+ call feedkeys(":!pwd\<CR>\<CR>", 'xt')
+ call assert_equal(['Cmd: [-c "(pwd)"]'], readfile('Xlog'))
+
+ set shellxescape=\"&<<()@^
+ set shellxquote=(
+ call feedkeys(":!pwd\"&<<{}@^\<CR>\<CR>", 'xt')
+ call assert_equal(['Cmd: [-c (pwd^"^&^<^<{}^@^^)]'], readfile('Xlog'))
+
+ let &shell = save_shell
+ let &shellxquote = save_sxq
+ let &shellxescape = save_sxe
+ call delete('Xtestshell')
+ call delete('Xlog')
+endfunc
+
+" Test for using the shell set in the $SHELL environment variable
+func Test_set_shell()
+ let after =<< trim [CODE]
+ call writefile([&shell], "Xtestout")
+ quit!
+ [CODE]
+
+ if has('win32')
+ let $SHELL = 'C:\with space\cmd.exe'
+ let expected = '"C:\with space\cmd.exe"'
+ else
+ let $SHELL = '/bin/with space/sh'
+ let expected = '"/bin/with space/sh"'
+ endif
+
+ if RunVimPiped([], after, '', '')
+ let lines = readfile('Xtestout')
+ call assert_equal(expected, lines[0])
+ endif
+ call delete('Xtestout')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
index 54b7636f69..1ee1d0dfe3 100644
--- a/src/nvim/testdir/test_startup.vim
+++ b/src/nvim/testdir/test_startup.vim
@@ -725,27 +725,6 @@ func Test_read_stdin()
call delete('Xtestout')
endfunc
-func Test_set_shell()
- let after =<< trim [CODE]
- call writefile([&shell], "Xtestout")
- quit!
- [CODE]
-
- if has('win32')
- let $SHELL = 'C:\with space\cmd.exe'
- let expected = '"C:\with space\cmd.exe"'
- else
- let $SHELL = '/bin/with space/sh'
- let expected = '"/bin/with space/sh"'
- endif
-
- if RunVimPiped([], after, '', '')
- let lines = readfile('Xtestout')
- call assert_equal(expected, lines[0])
- endif
- call delete('Xtestout')
-endfunc
-
func Test_progpath()
" Tests normally run with "./vim" or "../vim", these must have been expanded
" to a full path.
@@ -1064,7 +1043,7 @@ func Test_io_not_a_terminal()
\ 'Vim: Warning: Input is not from a terminal'], l)
endfunc
-" Test for --not-a-term avoiding escape codes.
+" Test for not being a term avoiding escape codes.
func Test_not_a_term()
CheckUnix
CheckNotGui
@@ -1075,18 +1054,14 @@ func Test_not_a_term()
let redir = &shellredir .. ' Xvimout'
endif
- " Without --not-a-term there are a few escape sequences.
- " This will take 2 seconds because of the missing --not-a-term
+ " As nvim checks the environment by itself there will be no escape sequences
+ " This will also happen to take two (2) seconds.
let cmd = GetVimProg() .. ' --cmd quit ' .. redir
exe "silent !" . cmd
- call assert_match("\<Esc>", readfile('Xvimout')->join())
+ call assert_notmatch("\e", readfile('Xvimout')->join())
call delete('Xvimout')
- " With --not-a-term there are no escape sequences.
- let cmd = GetVimProg() .. ' --not-a-term --cmd quit ' .. redir
- exe "silent !" . cmd
- call assert_notmatch("\<Esc>", readfile('Xvimout')->join())
- call delete('Xvimout')
+ " --not-a-term flag has thus been deleted
endfunc
diff --git a/src/nvim/testdir/test_system.vim b/src/nvim/testdir/test_system.vim
index bfa8a277bd..6c8373b335 100644
--- a/src/nvim/testdir/test_system.vim
+++ b/src/nvim/testdir/test_system.vim
@@ -142,40 +142,4 @@ func Test_system_with_shell_quote()
endtry
endfunc
-" Test for 'shellxquote'
-func Test_Shellxquote()
- CheckUnix
-
- let save_shell = &shell
- let save_sxq = &shellxquote
- let save_sxe = &shellxescape
-
- call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell')
- call setfperm('Xtestshell', "r-x------")
- set shell=./Xtestshell
-
- set shellxquote=\\"
- call feedkeys(":!pwd\<CR>\<CR>", 'xt')
- call assert_equal(['Cmd: [-c "pwd"]'], readfile('Xlog'))
-
- set shellxquote=(
- call feedkeys(":!pwd\<CR>\<CR>", 'xt')
- call assert_equal(['Cmd: [-c (pwd)]'], readfile('Xlog'))
-
- set shellxquote=\\"(
- call feedkeys(":!pwd\<CR>\<CR>", 'xt')
- call assert_equal(['Cmd: [-c "(pwd)"]'], readfile('Xlog'))
-
- set shellxescape=\"&<<()@^
- set shellxquote=(
- call feedkeys(":!pwd\"&<<{}@^\<CR>\<CR>", 'xt')
- call assert_equal(['Cmd: [-c (pwd^"^&^<^<{}^@^^)]'], readfile('Xlog'))
-
- let &shell = save_shell
- let &shellxquote = save_sxq
- let &shellxescape = save_sxe
- call delete('Xtestshell')
- call delete('Xlog')
-endfunc
-
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 55a8b3666e..5325ae3e4d 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -149,19 +149,7 @@ void tinput_init(TermInput *input, Loop *loop)
kitty_key_map_entry[i].name);
}
- // If stdin is not a pty, switch to stderr. For cases like:
- // echo q | nvim -es
- // ls *.md | xargs nvim
-#ifdef MSWIN
- if (!os_isatty(input->in_fd)) {
- input->in_fd = os_get_conin_fd();
- }
-#else
- if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) {
- input->in_fd = STDERR_FILENO;
- }
-#endif
- input_global_fd_init(input->in_fd);
+ input->in_fd = STDIN_FILENO;
const char *term = os_getenv("TERM");
if (!term) {
@@ -170,7 +158,7 @@ void tinput_init(TermInput *input, Loop *loop)
input->tk = termkey_new_abstract(term,
TERMKEY_FLAG_UTF8 | TERMKEY_FLAG_NOSTART);
- termkey_hook_terminfo_getstr(input->tk, input->tk_ti_hook_fn, NULL);
+ termkey_hook_terminfo_getstr(input->tk, input->tk_ti_hook_fn, input);
termkey_start(input->tk);
int curflags = termkey_get_canonflags(input->tk);
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 5232bcad19..44b99f6c84 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1338,7 +1338,7 @@ static void suspend_event(void **argv)
TUIData *tui = argv[0];
bool enable_mouse = tui->mouse_enabled;
tui_terminal_stop(tui);
- stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
+ stream_set_blocking(tui->input.in_fd, true); // normalize stream (#2598)
kill(0, SIGTSTP);
@@ -1347,7 +1347,7 @@ static void suspend_event(void **argv)
if (enable_mouse) {
tui_mouse_on(tui);
}
- stream_set_blocking(input_global_fd(), false); // libuv expects this
+ stream_set_blocking(tui->input.in_fd, false); // libuv expects this
}
#endif
@@ -2234,12 +2234,12 @@ static void flush_buf(TUIData *tui)
///
/// @see tmux/tty-keys.c fe4e9470bb504357d073320f5d305b22663ee3fd
/// @see https://bugzilla.redhat.com/show_bug.cgi?id=142659
-static const char *tui_get_stty_erase(void)
+static const char *tui_get_stty_erase(int fd)
{
static char stty_erase[2] = { 0 };
#if defined(HAVE_TERMIOS_H)
struct termios t;
- if (tcgetattr(input_global_fd(), &t) != -1) {
+ if (tcgetattr(fd, &t) != -1) {
stty_erase[0] = (char)t.c_cc[VERASE];
stty_erase[1] = '\0';
DLOG("stty/termios:erase=%s", stty_erase);
@@ -2252,9 +2252,10 @@ static const char *tui_get_stty_erase(void)
/// @see TermInput.tk_ti_hook_fn
static const char *tui_tk_ti_getstr(const char *name, const char *value, void *data)
{
+ TermInput *input = data;
static const char *stty_erase = NULL;
if (stty_erase == NULL) {
- stty_erase = tui_get_stty_erase();
+ stty_erase = tui_get_stty_erase(input->in_fd);
}
if (strequal(name, "key_backspace")) {
diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c
index b80b250cec..222ba3d5dd 100644
--- a/src/nvim/ui_client.c
+++ b/src/nvim/ui_client.c
@@ -51,9 +51,16 @@ uint64_t ui_client_start_server(int argc, char **argv)
on_err, CALLBACK_NONE,
false, true, true, false, kChannelStdinPipe,
NULL, 0, 0, NULL, &exit_status);
+
+ // If stdin is not a pty, it is forwarded to the client.
+ // Replace stdin in the TUI process with the tty fd.
if (ui_client_forward_stdin) {
close(0);
- dup(2);
+#ifdef MSWIN
+ os_open_conin_fd();
+#else
+ dup(stderr_isatty ? STDERR_FILENO : STDOUT_FILENO);
+#endif
}
return channel->id;
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index aa2f46bb59..68003e918b 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -166,7 +166,7 @@ describe('API', function()
echo nvim_exec('echo Avast_ye_hades(''ahoy!'')', 1)
]], true))
- eq('Vim(call):E5555: API call: Vim(echo):E121: Undefined variable: s:pirate',
+ matches('Vim%(echo%):E121: Undefined variable: s:pirate$',
pcall_err(request, 'nvim_exec', [[
let s:pirate = 'script-scoped varrrrr'
call nvim_exec('echo s:pirate', 1)
@@ -208,12 +208,12 @@ describe('API', function()
end)
it('execution error', function()
- eq('Vim:E492: Not an editor command: bogus_command',
+ eq('nvim_exec(): Vim:E492: Not an editor command: bogus_command',
pcall_err(request, 'nvim_exec', 'bogus_command', false))
eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
- eq('Vim(buffer):E86: Buffer 23487 does not exist',
+ eq('nvim_exec(): Vim(buffer):E86: Buffer 23487 does not exist',
pcall_err(request, 'nvim_exec', 'buffer 23487', false))
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
@@ -485,7 +485,7 @@ describe('API', function()
throw 'wtf'
endfunction
]])
- eq('wtf', pcall_err(request, 'nvim_call_function', 'Foo', {}))
+ eq('function Foo, line 1: wtf', pcall_err(request, 'nvim_call_function', 'Foo', {}))
eq('', eval('v:exception'))
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
end)
diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua
index 90254b7415..60ee9fa3a4 100644
--- a/test/functional/autocmd/autocmd_spec.lua
+++ b/test/functional/autocmd/autocmd_spec.lua
@@ -424,13 +424,13 @@ describe('autocmd', function()
end)
it('gives E814 when there are no other floating windows', function()
- eq('Vim(close):E814: Cannot close window, only autocmd window would remain',
+ eq('BufAdd Autocommands for "Xa.txt": Vim(close):E814: Cannot close window, only autocmd window would remain',
pcall_err(command, 'doautoall BufAdd'))
end)
it('gives E814 when there are other floating windows', function()
meths.open_win(0, true, {width = 10, height = 10, relative = 'editor', row = 10, col = 10})
- eq('Vim(close):E814: Cannot close window, only autocmd window would remain',
+ eq('BufAdd Autocommands for "Xa.txt": Vim(close):E814: Cannot close window, only autocmd window would remain',
pcall_err(command, 'doautoall BufAdd'))
end)
end)
@@ -476,14 +476,14 @@ describe('autocmd', function()
it('during RecordingLeave event', function()
command([[autocmd RecordingLeave * let v:event.regname = '']])
- eq('Vim(let):E46: Cannot change read-only variable "v:event.regname"',
+ eq('RecordingLeave Autocommands for "*": Vim(let):E46: Cannot change read-only variable "v:event.regname"',
pcall_err(command, 'normal! qqq'))
end)
it('during TermClose event', function()
command('autocmd TermClose * let v:event.status = 0')
command('terminal')
- eq('Vim(let):E46: Cannot change read-only variable "v:event.status"',
+ eq('TermClose Autocommands for "*": Vim(let):E46: Cannot change read-only variable "v:event.status"',
pcall_err(command, 'bdelete!'))
end)
end)
diff --git a/test/functional/autocmd/cmdline_spec.lua b/test/functional/autocmd/cmdline_spec.lua
index 60c29170e2..82fb9b9444 100644
--- a/test/functional/autocmd/cmdline_spec.lua
+++ b/test/functional/autocmd/cmdline_spec.lua
@@ -73,7 +73,7 @@ describe('cmdline autocommands', function()
{1:~ }|
{4: }|
: |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
+ {2:CmdlineEnter Autocommands for "*": Vim(echoerr):FAIL} |
:^ |
]])
@@ -82,9 +82,9 @@ describe('cmdline autocommands', function()
|
{4: }|
: |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
+ {2:CmdlineEnter Autocommands for "*": Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):very error} |
+ {2:CmdlineLeave Autocommands for "*": Vim(echoerr):very error} |
|
{3:Press ENTER or type command to continue}^ |
]])
@@ -111,9 +111,9 @@ describe('cmdline autocommands', function()
lorem ipsum |
{4: }|
: |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
+ {2:CmdlineEnter Autocommands for "*": Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
+ {2:CmdlineChanged Autocommands for "*": Vim(echoerr):change erreor} |
:put ='lorem ipsum'^ |
]])
@@ -123,9 +123,9 @@ describe('cmdline autocommands', function()
lorem ipsum |
{4: }|
: |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
+ {2:CmdlineEnter Autocommands for "*": Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
+ {2:CmdlineChanged Autocommands for "*": Vim(echoerr):change erreor} |
:put ='lorem ipsum^' |
]])
@@ -134,22 +134,22 @@ describe('cmdline autocommands', function()
screen:expect([[
{4: }|
: |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
+ {2:CmdlineEnter Autocommands for "*": Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
+ {2:CmdlineChanged Autocommands for "*": Vim(echoerr):change erreor} |
:put ='lorem ipsum.' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
+ {2:CmdlineChanged Autocommands for "*": Vim(echoerr):change erreor} |
:put ='lorem ipsum.^' |
]])
feed('<cr>')
screen:expect([[
:put ='lorem ipsum' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
+ {2:CmdlineChanged Autocommands for "*": Vim(echoerr):change erreor} |
:put ='lorem ipsum.' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
+ {2:CmdlineChanged Autocommands for "*": Vim(echoerr):change erreor} |
:put ='lorem ipsum.' |
- {2:E5500: autocmd has thrown an exception: Vim(echoerr):very error} |
+ {2:CmdlineLeave Autocommands for "*": Vim(echoerr):very error} |
|
{3:Press ENTER or type command to continue}^ |
]])
diff --git a/test/functional/autocmd/termxx_spec.lua b/test/functional/autocmd/termxx_spec.lua
index 4717b1fa2e..0a33f1b2ac 100644
--- a/test/functional/autocmd/termxx_spec.lua
+++ b/test/functional/autocmd/termxx_spec.lua
@@ -24,7 +24,7 @@ describe('autocmd TermClose', function()
local function test_termclose_delete_own_buf()
command('autocmd TermClose * bdelete!')
command('terminal')
- matches('^Vim%(bdelete%):E937: Attempt to delete a buffer that is in use: term://',
+ matches('^TermClose Autocommands for "%*": Vim%(bdelete%):E937: Attempt to delete a buffer that is in use: term://',
pcall_err(command, 'bdelete!'))
assert_alive()
end
diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua
index 8cad7adfa6..05a69e1992 100644
--- a/test/functional/core/exit_spec.lua
+++ b/test/functional/core/exit_spec.lua
@@ -89,14 +89,14 @@ describe(':cquit', function()
end)
it('exits with redir msg for multiple exit codes after :cquit 1 2', function()
- test_cq('cquit 1 2', nil, 'Vim(cquit):E488: Trailing characters: 2: cquit 1 2')
+ test_cq('cquit 1 2', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: 2: cquit 1 2')
end)
it('exits with redir msg for non-number exit code after :cquit X', function()
- test_cq('cquit X', nil, 'Vim(cquit):E488: Trailing characters: X: cquit X')
+ test_cq('cquit X', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: X: cquit X')
end)
it('exits with redir msg for negative exit code after :cquit -1', function()
- test_cq('cquit -1', nil, 'Vim(cquit):E488: Trailing characters: -1: cquit -1')
+ test_cq('cquit -1', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: -1: cquit -1')
end)
end)
diff --git a/test/functional/editor/mark_spec.lua b/test/functional/editor/mark_spec.lua
index f300fea3a0..b3b190ef79 100644
--- a/test/functional/editor/mark_spec.lua
+++ b/test/functional/editor/mark_spec.lua
@@ -40,59 +40,59 @@ describe('named marks', function()
it("errors when set out of range with :mark", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "1000mark x")
- eq("Vim(mark):E16: Invalid range: 1000mark x", err)
+ eq("nvim_exec(): Vim(mark):E16: Invalid range: 1000mark x", err)
end)
it("errors when set out of range with :k", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "1000kx")
- eq("Vim(k):E16: Invalid range: 1000kx", err)
+ eq("nvim_exec(): Vim(k):E16: Invalid range: 1000kx", err)
end)
it("errors on unknown mark name with :mark", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "mark #")
- eq("Vim(mark):E191: Argument must be a letter or forward/backward quote", err)
+ eq("nvim_exec(): Vim(mark):E191: Argument must be a letter or forward/backward quote", err)
end)
it("errors on unknown mark name with '", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "normal! '#")
- eq("Vim(normal):E78: Unknown mark", err)
+ eq("nvim_exec(): Vim(normal):E78: Unknown mark", err)
end)
it("errors on unknown mark name with `", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "normal! `#")
- eq("Vim(normal):E78: Unknown mark", err)
+ eq("nvim_exec(): Vim(normal):E78: Unknown mark", err)
end)
it("errors when moving to a mark that is not set with '", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "normal! 'z")
- eq("Vim(normal):E20: Mark not set", err)
+ eq("nvim_exec(): Vim(normal):E20: Mark not set", err)
err = pcall_err(helpers.exec_capture, "normal! '.")
- eq("Vim(normal):E20: Mark not set", err)
+ eq("nvim_exec(): Vim(normal):E20: Mark not set", err)
end)
it("errors when moving to a mark that is not set with `", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "normal! `z")
- eq("Vim(normal):E20: Mark not set", err)
+ eq("nvim_exec(): Vim(normal):E20: Mark not set", err)
err = pcall_err(helpers.exec_capture, "normal! `>")
- eq("Vim(normal):E20: Mark not set", err)
+ eq("nvim_exec(): Vim(normal):E20: Mark not set", err)
end)
it("errors when moving to a global mark that is not set with '", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "normal! 'Z")
- eq("Vim(normal):E20: Mark not set", err)
+ eq("nvim_exec(): Vim(normal):E20: Mark not set", err)
end)
it("errors when moving to a global mark that is not set with `", function()
command("edit " .. file1)
local err = pcall_err(helpers.exec_capture, "normal! `Z")
- eq("Vim(normal):E20: Mark not set", err)
+ eq("nvim_exec(): Vim(normal):E20: Mark not set", err)
end)
it("can move to them using '", function()
@@ -153,7 +153,7 @@ describe('named marks', function()
command("next")
command("bw! " .. file1 )
local err = pcall_err(helpers.exec_capture, "normal! 'A")
- eq("Vim(normal):E92: Buffer 1 not found", err)
+ eq("nvim_exec(): Vim(normal):E92: Buffer 1 not found", err)
os.remove(file1)
end)
diff --git a/test/functional/legacy/gf_spec.lua b/test/functional/legacy/gf_spec.lua
index f1b1790ba1..9f725446be 100644
--- a/test/functional/legacy/gf_spec.lua
+++ b/test/functional/legacy/gf_spec.lua
@@ -10,6 +10,7 @@ describe('gf', function()
it('is not allowed when buffer is locked', function()
command('au OptionSet diff norm! gf')
command([[call setline(1, ['Xfile1', 'line2', 'line3', 'line4'])]])
- eq('Vim(normal):E788: Not allowed to edit another buffer now', pcall_err(command, 'diffthis'))
+ eq('OptionSet Autocommands for "diff": Vim(normal):E788: Not allowed to edit another buffer now',
+ pcall_err(command, 'diffthis'))
end)
end)
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index 33e375760e..eb5de693bd 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -335,17 +335,17 @@ describe('Command-line coloring', function()
:echo "«^ |
]])
end)
- it('does the right thing when errorring', function()
+ it('does the right thing when erroring', function()
set_color_cb('Echoerring')
start_prompt('e')
screen:expect([[
|
{EOB:~ }|
- {EOB:~ }|
{MSEP: }|
: |
{ERR:E5407: Callback has thrown an exception:}|
- {ERR: Vim(echoerr):HERE} |
+ {ERR: function DoPrompt[3]..Echoerring, line }|
+ {ERR:1: Vim(echoerr):HERE} |
:e^ |
]])
end)
@@ -400,10 +400,10 @@ describe('Command-line coloring', function()
screen:expect([[
|
{EOB:~ }|
- {EOB:~ }|
{MSEP: }|
: |
{ERR:E5407: Callback has thrown an exception:}|
+ {ERR: function DoPrompt[3]..Throwing, line 1:}|
{ERR: ABC} |
:e^ |
]])
diff --git a/test/functional/vimscript/api_functions_spec.lua b/test/functional/vimscript/api_functions_spec.lua
index 8ca245f61a..c032ac3030 100644
--- a/test/functional/vimscript/api_functions_spec.lua
+++ b/test/functional/vimscript/api_functions_spec.lua
@@ -5,6 +5,7 @@ local neq, eq, command = helpers.neq, helpers.eq, helpers.command
local clear, curbufmeths = helpers.clear, helpers.curbufmeths
local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval
local insert, pcall_err = helpers.insert, helpers.pcall_err
+local matches = helpers.matches
local meths = helpers.meths
describe('eval-API', function()
@@ -49,7 +50,7 @@ describe('eval-API', function()
it('cannot change texts if textlocked', function()
command("autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])")
- eq('Vim(call):E5555: API call: E565: Not allowed to change text or change window',
+ matches('Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$',
pcall_err(command, "normal! yy"))
end)
diff --git a/test/functional/vimscript/ctx_functions_spec.lua b/test/functional/vimscript/ctx_functions_spec.lua
index d92a81c55b..773ec8d0f7 100644
--- a/test/functional/vimscript/ctx_functions_spec.lua
+++ b/test/functional/vimscript/ctx_functions_spec.lua
@@ -173,9 +173,9 @@ describe('context functions', function()
call('SaveSFuncs')
call('DeleteSFuncs')
- eq('Vim(call):E117: Unknown function: s:greet',
+ eq('function Greet, line 1: Vim(call):E117: Unknown function: s:greet',
pcall_err(command, [[call Greet('World')]]))
- eq('Vim(call):E117: Unknown function: s:greet_all',
+ eq('function GreetAll, line 1: Vim(call):E117: Unknown function: s:greet_all',
pcall_err(command, [[call GreetAll('World', 'One', 'Two', 'Three')]]))
call('RestoreFuncs')