aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/gdb/neovim_gdb.vim6
-rw-r--r--runtime/doc/api.txt4
-rw-r--r--runtime/doc/builtin.txt35
-rw-r--r--runtime/doc/channel.txt4
-rw-r--r--runtime/doc/deprecated.txt305
-rw-r--r--runtime/doc/news.txt1
-rw-r--r--runtime/doc/terminal.txt2
-rw-r--r--runtime/lua/vim/_defaults.lua2
-rw-r--r--runtime/lua/vim/_meta/api.lua4
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua28
-rw-r--r--runtime/pack/dist/opt/termdebug/plugin/termdebug.vim8
-rw-r--r--src/nvim/api/buffer.c4
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/eval.lua28
-rw-r--r--src/nvim/eval/deprecated.c44
-rw-r--r--src/nvim/eval/deprecated.h10
-rw-r--r--src/nvim/eval/funcs.c234
-rw-r--r--src/nvim/ex_docmd.c4
-rw-r--r--src/nvim/generators/gen_eval.lua1
-rw-r--r--src/nvim/terminal.c2
-rw-r--r--test/functional/api/buffer_updates_spec.lua3
-rw-r--r--test/functional/api/vim_spec.lua3
-rw-r--r--test/functional/core/job_spec.lua47
-rw-r--r--test/functional/core/main_spec.lua3
-rw-r--r--test/functional/core/startup_spec.lua29
-rw-r--r--test/functional/editor/mode_normal_spec.lua8
-rw-r--r--test/functional/ex_cmds/swapfile_preserve_recover_spec.lua12
-rw-r--r--test/functional/legacy/window_cmd_spec.lua2
-rw-r--r--test/functional/terminal/buffer_spec.lua10
-rw-r--r--test/functional/terminal/channel_spec.lua14
-rw-r--r--test/functional/terminal/clipboard_spec.lua2
-rw-r--r--test/functional/terminal/cursor_spec.lua2
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua4
-rw-r--r--test/functional/terminal/highlight_spec.lua11
-rw-r--r--test/functional/terminal/scrollback_spec.lua6
-rw-r--r--test/functional/terminal/tui_spec.lua6
-rw-r--r--test/functional/testterm.lua2
-rw-r--r--test/functional/ui/hlstate_spec.lua2
-rw-r--r--test/functional/ui/messages_spec.lua2
-rw-r--r--test/functional/ui/title_spec.lua2
-rw-r--r--test/old/testdir/runnvim.vim3
41 files changed, 466 insertions, 435 deletions
diff --git a/contrib/gdb/neovim_gdb.vim b/contrib/gdb/neovim_gdb.vim
index d61e7bc0cc..e0be6cb803 100644
--- a/contrib/gdb/neovim_gdb.vim
+++ b/contrib/gdb/neovim_gdb.vim
@@ -167,13 +167,15 @@ function! s:Spawn(server_cmd, client_cmd, server_addr, reconnect)
if type(a:server_cmd) == type('')
" spawn gdbserver in a vertical split
let server = s:GdbServer.new(gdb)
- vsp | enew | let gdb._server_id = termopen(a:server_cmd, server)
+ server.term = v:true
+ vsp | enew | let gdb._server_id = jobstart(a:server_cmd, server)
let gdb._jump_window = 2
let gdb._server_buf = bufnr('%')
endif
" go to the bottom window and spawn gdb client
wincmd j
- enew | let gdb._client_id = termopen(a:client_cmd, gdb)
+ gdb.term = v:true
+ enew | let gdb._client_id = jobstart(a:client_cmd, gdb)
let gdb._client_buf = bufnr('%')
tnoremap <silent> <f8> <c-\><c-n>:GdbContinue<cr>i
tnoremap <silent> <f10> <c-\><c-n>:GdbNext<cr>i
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 95c8a6056f..c8e0dcd0c5 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -2170,12 +2170,12 @@ nvim_buf_call({buffer}, {fun}) *nvim_buf_call()*
This temporarily switches current buffer to "buffer". If the current
window already shows "buffer", the window is not switched. If a window
inside the current tabpage (including a float) already shows the buffer,
- then one of these windows will be set as current window temporarily.
+ then one of those windows will be set as current window temporarily.
Otherwise a temporary scratch window (called the "autocmd window" for
historical reasons) will be used.
This is useful e.g. to call Vimscript functions that only work with the
- current buffer/window currently, like |termopen()|.
+ current buffer/window currently, like `jobstart(…, {'term': v:true})`.
Attributes: ~
Lua |vim.api| only
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 5f74080e0c..0e9c1c8512 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -5309,7 +5309,7 @@ jobresize({job}, {width}, {height}) *jobresize()*
(`any`)
jobstart({cmd} [, {opts}]) *jobstart()*
- Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
+ Note: Prefer |vim.system()| in Lua (unless using `rpc`, `pty`, or `term`).
Spawns {cmd} as a job.
If {cmd} is a List it runs directly (no 'shell').
@@ -5317,8 +5317,11 @@ jobstart({cmd} [, {opts}]) *jobstart()*
call jobstart(split(&shell) + split(&shellcmdflag) + ['{cmd}'])
< (See |shell-unquoting| for details.)
- Example: >vim
- call jobstart('nvim -h', {'on_stdout':{j,d,e->append(line('.'),d)}})
+ Example: start a job and handle its output: >vim
+ call jobstart(['nvim', '-h'], {'on_stdout':{j,d,e->append(line('.'),d)}})
+<
+ Example: start a job in a |terminal| connected to the current buffer: >vim
+ call jobstart(['nvim', '-h'], {'term':v:true})
<
Returns |job-id| on success, 0 on invalid arguments (or job
table is full), -1 if {cmd}[0] or 'shell' is not executable.
@@ -5383,6 +5386,10 @@ jobstart({cmd} [, {opts}]) *jobstart()*
stdin: (string) Either "pipe" (default) to connect the
job's stdin to a channel or "null" to disconnect
stdin.
+ term: (boolean) Spawns {cmd} in a new pseudo-terminal session
+ connected to the current (unmodified) buffer. Implies "pty".
+ Default "height" and "width" are set to the current window
+ dimensions. |jobstart()|. Defaults $TERM to "xterm-256color".
width: (number) Width of the `pty` terminal.
{opts} is passed as |self| dictionary to the callback; the
@@ -11168,28 +11175,6 @@ tempname() *tempname()*
Return: ~
(`string`)
-termopen({cmd} [, {opts}]) *termopen()*
- Spawns {cmd} in a new pseudo-terminal session connected
- to the current (unmodified) buffer. Parameters and behavior
- are the same as |jobstart()| except "pty", "width", "height",
- and "TERM" are ignored: "height" and "width" are taken from
- the current window. Note that termopen() implies a "pty" arg
- to jobstart(), and thus has the implications documented at
- |jobstart()|.
-
- Returns the same values as jobstart().
-
- Terminal environment is initialized as in |jobstart-env|,
- except $TERM is set to "xterm-256color". Full behavior is
- described in |terminal|.
-
- Parameters: ~
- • {cmd} (`string|string[]`)
- • {opts} (`table?`)
-
- Return: ~
- (`integer`)
-
test_garbagecollect_now() *test_garbagecollect_now()*
Like |garbagecollect()|, but executed right away. This must
only be called directly to avoid any structure to exist
diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt
index 7184151cda..dc9b0735ea 100644
--- a/runtime/doc/channel.txt
+++ b/runtime/doc/channel.txt
@@ -20,8 +20,8 @@ There are several ways to open a channel:
2. Through stdin, stdout and stderr of a process spawned by |jobstart()|.
- 3. Through the PTY master end of a PTY opened with
- `jobstart(..., {'pty': v:true})` or |termopen()|.
+ 3. Through the PTY master end of a PTY opened with |nvim_open_term()| or
+ `jobstart(…, {'pty': v:true})`.
4. By connecting to a TCP/IP socket or named pipe with |sockconnect()|.
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index 592b6389c4..ec98cc844f 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -16,49 +16,34 @@ Deprecated features
DEPRECATED IN 0.11 *deprecated-0.11*
API
-- nvim_subscribe() Plugins must maintain their own "multicast" channels list.
-- nvim_unsubscribe() Plugins must maintain their own "multicast" channels list.
-
-LUA
-- vim.region() Use |getregionpos()| instead.
-- *vim.highlight* Renamed to |vim.hl|.
-- vim.validate(opts: table) Use form 1. See |vim.validate()|.
+• nvim_subscribe() Plugins must maintain their own "multicast" channels list.
+• nvim_unsubscribe() Plugins must maintain their own "multicast" channels list.
DIAGNOSTICS
-- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
-- *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count=-1, float=true}` instead.
-- *vim.diagnostic.get_next_pos()*
- Use the "lnum" and "col" fields from the return value of
- |vim.diagnostic.get_next()| instead.
-- *vim.diagnostic.get_prev_pos()*
- Use the "lnum" and "col" fields from the return value of
- |vim.diagnostic.get_prev()| instead.
-- The "win_id" parameter used by various functions is deprecated in favor of
+• *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
+• *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count=-1, float=true}` instead.
+• *vim.diagnostic.get_next_pos()* Use the "lnum" and "col" fields from the
+ return value of |vim.diagnostic.get_next()| instead.
+• *vim.diagnostic.get_prev_pos()* Use the "lnum" and "col" fields from the
+ return value of |vim.diagnostic.get_prev()| instead.
+• The "win_id" parameter used by various functions is deprecated in favor of
"winid" |winid|
-- The "cursor_position" parameter of |vim.diagnostic.JumpOpts| is renamed to
- "pos"
+• |vim.diagnostic.JumpOpts| renamed its "cursor_position" field to "pos".
HIGHLIGHTS
-• *TermCursorNC* As of Nvim 0.11, unfocused |terminal| windows no
- longer have any cursor.
-
-TREESITTER
-• *TSNode:child_containing_descendant()* Use
- |TSNode:child_with_descendant()| instead; it is identical except that it can
- return the descendant itself.
+• *TermCursorNC* Unfocused |terminal| windows do not have a cursor.
LSP
• *vim.lsp.util.jump_to_location* Use |vim.lsp.util.show_document()| with
- `{focus=true}` instead.
+ `{focus=true}` instead.
• *vim.lsp.buf.execute_command* Use |Client:exec_cmd()| instead.
• *vim.lsp.buf.completion* Use |vim.lsp.completion.trigger()| instead.
• vim.lsp.buf_request_all The `error` key has been renamed to `err` inside
the result parameter of the handler.
• *vim.lsp.with()* Pass configuration to equivalent
functions in `vim.lsp.buf.*`.
-• |vim.lsp.handlers|
- No longer support client to server response handlers. Only server to
- client requests/notification handlers are supported.
+• |vim.lsp.handlers| Does not support client-to-server response handlers. Only
+ supports server-to-client requests/notification handlers.
• *vim.lsp.handlers.signature_help()* Use |vim.lsp.buf.signature_help()| instead.
• `client.request()` Use |Client:request()| instead.
• `client.request_sync()` Use |Client:request_sync()| instead.
@@ -70,6 +55,18 @@ LSP
• `client.on_attach()` Use |Client:on_attach()| instead.
• `vim.lsp.start_client()` Use |vim.lsp.start()| instead.
+LUA
+• vim.region() Use |getregionpos()| instead.
+• *vim.highlight* Renamed to |vim.hl|.
+• vim.validate(opts: table) Use form 1. See |vim.validate()|.
+
+TREESITTER
+• *TSNode:child_containing_descendant()* Use |TSNode:child_with_descendant()|
+ instead; it is identical except that it can return the descendant itself.
+
+VIMSCRIPT
+• *termopen()* Use |jobstart() with `{term: v:true}`.
+
------------------------------------------------------------------------------
DEPRECATED IN 0.10 *deprecated-0.10*
@@ -130,198 +127,198 @@ TREESITTER
DEPRECATED IN 0.9 *deprecated-0.9*
API
-- *nvim_get_hl_by_name()* Use |nvim_get_hl()| instead.
-- *nvim_get_hl_by_id()* Use |nvim_get_hl()| instead.
+• *nvim_get_hl_by_name()* Use |nvim_get_hl()| instead.
+• *nvim_get_hl_by_id()* Use |nvim_get_hl()| instead.
TREESITTER
-- *vim.treesitter.language.require_language()* Use |vim.treesitter.language.add()| instead.
-- *vim.treesitter.get_node_at_pos()* Use |vim.treesitter.get_node()| instead.
-- *vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()|
+• *vim.treesitter.language.require_language()* Use |vim.treesitter.language.add()| instead.
+• *vim.treesitter.get_node_at_pos()* Use |vim.treesitter.get_node()| instead.
+• *vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()|
and |TSNode:type()| instead.
• The following top level Treesitter functions have been moved:
- - *vim.treesitter.inspect_language()* -> |vim.treesitter.language.inspect()|
- - *vim.treesitter.get_query_files()* -> |vim.treesitter.query.get_files()|
- - *vim.treesitter.set_query()* -> |vim.treesitter.query.set()|
- - *vim.treesitter.query.set_query()* -> |vim.treesitter.query.set()|
- - *vim.treesitter.get_query()* -> |vim.treesitter.query.get()|
- - *vim.treesitter.query.get_query()* -> |vim.treesitter.query.get()|
- - *vim.treesitter.parse_query()* -> |vim.treesitter.query.parse()|
- - *vim.treesitter.query.parse_query()* -> |vim.treesitter.query.parse()|
- - *vim.treesitter.add_predicate()* -> |vim.treesitter.query.add_predicate()|
- - *vim.treesitter.add_directive()* -> |vim.treesitter.query.add_directive()|
- - *vim.treesitter.list_predicates()* -> |vim.treesitter.query.list_predicates()|
- - *vim.treesitter.list_directives()* -> |vim.treesitter.query.list_directives()|
- - *vim.treesitter.query.get_range()* -> |vim.treesitter.get_range()|
- - *vim.treesitter.query.get_node_text()* -> |vim.treesitter.get_node_text()|
+ • *vim.treesitter.inspect_language()* -> |vim.treesitter.language.inspect()|
+ • *vim.treesitter.get_query_files()* -> |vim.treesitter.query.get_files()|
+ • *vim.treesitter.set_query()* -> |vim.treesitter.query.set()|
+ • *vim.treesitter.query.set_query()* -> |vim.treesitter.query.set()|
+ • *vim.treesitter.get_query()* -> |vim.treesitter.query.get()|
+ • *vim.treesitter.query.get_query()* -> |vim.treesitter.query.get()|
+ • *vim.treesitter.parse_query()* -> |vim.treesitter.query.parse()|
+ • *vim.treesitter.query.parse_query()* -> |vim.treesitter.query.parse()|
+ • *vim.treesitter.add_predicate()* -> |vim.treesitter.query.add_predicate()|
+ • *vim.treesitter.add_directive()* -> |vim.treesitter.query.add_directive()|
+ • *vim.treesitter.list_predicates()* -> |vim.treesitter.query.list_predicates()|
+ • *vim.treesitter.list_directives()* -> |vim.treesitter.query.list_directives()|
+ • *vim.treesitter.query.get_range()* -> |vim.treesitter.get_range()|
+ • *vim.treesitter.query.get_node_text()* -> |vim.treesitter.get_node_text()|
LUA
- - *nvim_exec()* Use |nvim_exec2()| instead.
- - *vim.pretty_print()* Use |vim.print()| instead.
+ • *nvim_exec()* Use |nvim_exec2()| instead.
+ • *vim.pretty_print()* Use |vim.print()| instead.
------------------------------------------------------------------------------
DEPRECATED IN 0.8 OR EARLIER
API
-- *nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead.
-- *nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead.
-- *nvim_command_output()* Use |nvim_exec2()| instead.
-- *nvim_execute_lua()* Use |nvim_exec_lua()| instead.
-- *nvim_get_option_info()* Use |nvim_get_option_info2()| instead.
+• *nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead.
+• *nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead.
+• *nvim_command_output()* Use |nvim_exec2()| instead.
+• *nvim_execute_lua()* Use |nvim_exec_lua()| instead.
+• *nvim_get_option_info()* Use |nvim_get_option_info2()| instead.
COMMANDS
-- *:rv* *:rviminfo* Deprecated alias to |:rshada| command.
-- *:wv* *:wviminfo* Deprecated alias to |:wshada| command.
+• *:rv* *:rviminfo* Deprecated alias to |:rshada| command.
+• *:wv* *:wviminfo* Deprecated alias to |:wshada| command.
ENVIRONMENT VARIABLES
-- *$NVIM_LISTEN_ADDRESS*
- - Deprecated way to:
- - set the server name (use |--listen| or |serverstart()| instead)
- - get the server name (use |v:servername| instead)
- - detect a parent Nvim (use |$NVIM| instead)
- - Ignored if --listen is given.
- - Unset by |terminal| and |jobstart()| unless explicitly given by the "env"
+• *$NVIM_LISTEN_ADDRESS*
+ • Deprecated way to:
+ • set the server name (use |--listen| or |serverstart()| instead)
+ • get the server name (use |v:servername| instead)
+ • detect a parent Nvim (use |$NVIM| instead)
+ • Ignored if --listen is given.
+ • Unset by |terminal| and |jobstart()| unless explicitly given by the "env"
option. Example: >vim
call jobstart(['foo'], { 'env': { 'NVIM_LISTEN_ADDRESS': v:servername } })
<
EVENTS
-- *BufCreate* Use |BufAdd| instead.
-- *EncodingChanged* Never fired; 'encoding' is always "utf-8".
-- *FileEncoding* Never fired; equivalent to |EncodingChanged|.
-- *GUIEnter* Never fired; use |UIEnter| instead.
-- *GUIFailed* Never fired.
+• *BufCreate* Use |BufAdd| instead.
+• *EncodingChanged* Never fired; 'encoding' is always "utf-8".
+• *FileEncoding* Never fired; equivalent to |EncodingChanged|.
+• *GUIEnter* Never fired; use |UIEnter| instead.
+• *GUIFailed* Never fired.
KEYCODES
-- *<MouseDown>* Use <ScrollWheelUp> instead.
-- *<MouseUp>* Use <ScrollWheelDown> instead.
-
-FUNCTIONS
-- *buffer_exists()* Obsolete name for |bufexists()|.
-- *buffer_name()* Obsolete name for |bufname()|.
-- *buffer_number()* Obsolete name for |bufnr()|.
-- *file_readable()* Obsolete name for |filereadable()|.
-- *highlight_exists()* Obsolete name for |hlexists()|.
-- *highlightID()* Obsolete name for |hlID()|.
-- *inputdialog()* Use |input()| instead.
-- *jobclose()* Obsolete name for |chanclose()|
-- *jobsend()* Obsolete name for |chansend()|
-- *last_buffer_nr()* Obsolete name for bufnr("$").
-- *rpcstart()* Use |jobstart()| with `{'rpc': v:true}` instead.
-- *rpcstop()* Use |jobstop()| instead to stop any job, or
- `chanclose(id, "rpc")` to close RPC communication
- without stopping the job. Use chanclose(id) to close
- any socket.
+• *<MouseDown>* Use <ScrollWheelUp> instead.
+• *<MouseUp>* Use <ScrollWheelDown> instead.
HIGHLIGHTS
-- *hl-VertSplit* Use |hl-WinSeparator| instead.
+• *hl-VertSplit* Use |hl-WinSeparator| instead.
LSP DIAGNOSTICS
For each of the functions below, use the corresponding function in
|vim.diagnostic| instead (unless otherwise noted). For example, use
|vim.diagnostic.get()| instead of |vim.lsp.diagnostic.get()|.
-- *vim.lsp.diagnostic.clear()* Use |vim.diagnostic.hide()| instead.
-- *vim.lsp.diagnostic.disable()* Use |vim.diagnostic.enable()| instead.
-- *vim.lsp.diagnostic.display()* Use |vim.diagnostic.show()| instead.
-- *vim.lsp.diagnostic.enable()*
-- *vim.lsp.diagnostic.get()*
-- *vim.lsp.diagnostic.get_all()* Use |vim.diagnostic.get()| instead.
-- *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.count()| instead.
-- *vim.lsp.diagnostic.get_line_diagnostics()* Use |vim.diagnostic.get()| instead.
-- *vim.lsp.diagnostic.get_next()*
-- *vim.lsp.diagnostic.get_next_pos()*
-- *vim.lsp.diagnostic.get_prev()*
-- *vim.lsp.diagnostic.get_prev_pos()*
-- *vim.lsp.diagnostic.get_virtual_text_chunks_for_line()* No replacement. Use
+• *vim.lsp.diagnostic.clear()* Use |vim.diagnostic.hide()| instead.
+• *vim.lsp.diagnostic.disable()* Use |vim.diagnostic.enable()| instead.
+• *vim.lsp.diagnostic.display()* Use |vim.diagnostic.show()| instead.
+• *vim.lsp.diagnostic.enable()*
+• *vim.lsp.diagnostic.get()*
+• *vim.lsp.diagnostic.get_all()* Use |vim.diagnostic.get()| instead.
+• *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.count()| instead.
+• *vim.lsp.diagnostic.get_line_diagnostics()* Use |vim.diagnostic.get()| instead.
+• *vim.lsp.diagnostic.get_next()*
+• *vim.lsp.diagnostic.get_next_pos()*
+• *vim.lsp.diagnostic.get_prev()*
+• *vim.lsp.diagnostic.get_prev_pos()*
+• *vim.lsp.diagnostic.get_virtual_text_chunks_for_line()* No replacement. Use
options provided by |vim.diagnostic.config()| to customize virtual text.
-- *vim.lsp.diagnostic.goto_next()*
-- *vim.lsp.diagnostic.goto_prev()*
-- *vim.lsp.diagnostic.redraw()* Use |vim.diagnostic.show()| instead.
-- *vim.lsp.diagnostic.reset()*
-- *vim.lsp.diagnostic.save()* Use |vim.diagnostic.set()| instead.
-- *vim.lsp.diagnostic.set_loclist()* Use |vim.diagnostic.setloclist()| instead.
-- *vim.lsp.diagnostic.set_qflist()* Use |vim.diagnostic.setqflist()| instead.
-- *vim.lsp.diagnostic.show_line_diagnostics()* Use |vim.diagnostic.open_float()| instead.
-- *vim.lsp.diagnostic.show_position_diagnostics()* Use |vim.diagnostic.open_float()| instead.
+• *vim.lsp.diagnostic.goto_next()*
+• *vim.lsp.diagnostic.goto_prev()*
+• *vim.lsp.diagnostic.redraw()* Use |vim.diagnostic.show()| instead.
+• *vim.lsp.diagnostic.reset()*
+• *vim.lsp.diagnostic.save()* Use |vim.diagnostic.set()| instead.
+• *vim.lsp.diagnostic.set_loclist()* Use |vim.diagnostic.setloclist()| instead.
+• *vim.lsp.diagnostic.set_qflist()* Use |vim.diagnostic.setqflist()| instead.
+• *vim.lsp.diagnostic.show_line_diagnostics()* Use |vim.diagnostic.open_float()| instead.
+• *vim.lsp.diagnostic.show_position_diagnostics()* Use |vim.diagnostic.open_float()| instead.
The following are deprecated without replacement. These functions are moved
internally and are no longer exposed as part of the API. Instead, use
|vim.diagnostic.config()| and |vim.diagnostic.show()|.
-- *vim.lsp.diagnostic.set_signs()*
-- *vim.lsp.diagnostic.set_underline()*
-- *vim.lsp.diagnostic.set_virtual_text()*
+• *vim.lsp.diagnostic.set_signs()*
+• *vim.lsp.diagnostic.set_underline()*
+• *vim.lsp.diagnostic.set_virtual_text()*
LSP FUNCTIONS
-- *vim.lsp.buf.server_ready()*
+• *vim.lsp.buf.server_ready()*
Use |LspAttach| instead, depending on your use-case. "Server ready" is not
part of the LSP spec, so the Nvim LSP client cannot meaningfully implement
it. "Ready" is ambiguous because:
- - Language servers may finish analyzing the workspace, but edits can always
+ • Language servers may finish analyzing the workspace, but edits can always
re-trigger analysis/builds.
- - Language servers can serve some requests even while processing changes.
-- *vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with
+ • Language servers can serve some requests even while processing changes.
+• *vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with
the `range` parameter.
-- *vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead.
-- *vim.lsp.util.set_qflist()* Use |setqflist()| instead.
-- *vim.lsp.util.set_loclist()* Use |setloclist()| instead.
-- *vim.lsp.buf_get_clients()* Use |vim.lsp.get_clients()| with
+• *vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead.
+• *vim.lsp.util.set_qflist()* Use |setqflist()| instead.
+• *vim.lsp.util.set_loclist()* Use |setloclist()| instead.
+• *vim.lsp.buf_get_clients()* Use |vim.lsp.get_clients()| with
{buffer=bufnr} instead.
-- *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
+• *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
{async=true} instead.
-- *vim.lsp.buf.formatting_sync()* Use |vim.lsp.buf.format()| with
+• *vim.lsp.buf.formatting_sync()* Use |vim.lsp.buf.format()| with
{async=false} instead.
-- *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
+• *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
or |vim.lsp.buf.format()| instead.
LUA
-- vim.register_keystroke_callback() Use |vim.on_key()| instead.
+• vim.register_keystroke_callback() Use |vim.on_key()| instead.
NORMAL COMMANDS
-- *]f* *[f* Same as "gf".
+• *]f* *[f* Same as "gf".
OPTIONS
-- *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
+• *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
`<>` notation is always enabled.
-- *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
-- *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.
-- *'langnoremap'* Deprecated alias to 'nolangremap'.
-- 'sessionoptions' Flags "unix", "slash" are ignored and always enabled.
-- *'vi'*
-- 'viewoptions' Flags "unix", "slash" are ignored and always enabled.
-- *'viminfo'* Deprecated alias to 'shada' option.
-- *'viminfofile'* Deprecated alias to 'shadafile' option.
-- *'paste'* *'nopaste'* Just Paste It.™ The 'paste' option is obsolete:
+• *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
+• *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.
+• *'langnoremap'* Deprecated alias to 'nolangremap'.
+• 'sessionoptions' Flags "unix", "slash" are ignored and always enabled.
+• *'vi'*
+• 'viewoptions' Flags "unix", "slash" are ignored and always enabled.
+• *'viminfo'* Deprecated alias to 'shada' option.
+• *'viminfofile'* Deprecated alias to 'shadafile' option.
+• *'paste'* *'nopaste'* Just Paste It.™ The 'paste' option is obsolete:
|paste| is handled automatically when you paste text
using your terminal's or GUI's paste feature
(CTRL-SHIFT-v, CMD-v (macOS), middle-click, …).
Enables "paste mode":
- - Disables mappings in Insert, Cmdline mode.
- - Disables abbreviations.
- - Resets 'autoindent' 'expandtab' 'revins' 'ruler'
+ • Disables mappings in Insert, Cmdline mode.
+ • Disables abbreviations.
+ • Resets 'autoindent' 'expandtab' 'revins' 'ruler'
'showmatch' 'smartindent' 'smarttab' 'softtabstop'
'textwidth' 'wrapmargin'.
- - Treats 'formatoptions' as empty.
- - Disables the effect of these options:
- - 'cindent'
- - 'indentexpr'
- - 'lisp'
+ • Treats 'formatoptions' as empty.
+ • Disables the effect of these options:
+ • 'cindent'
+ • 'indentexpr'
+ • 'lisp'
UI EXTENSIONS
-- *ui-wildmenu* Use |ui-cmdline| with |ui-popupmenu| instead. Enabled
+• *ui-wildmenu* Use |ui-cmdline| with |ui-popupmenu| instead. Enabled
by the `ext_wildmenu` |ui-option|. Emits these events:
- - `["wildmenu_show", items]`
- - `["wildmenu_select", selected]`
- - `["wildmenu_hide"]`
-- *term_background* Unused. The terminal background color is now detected
+ • `["wildmenu_show", items]`
+ • `["wildmenu_select", selected]`
+ • `["wildmenu_hide"]`
+• *term_background* Unused. The terminal background color is now detected
by the Nvim core directly instead of the TUI.
VARIABLES
-- *b:terminal_job_pid* Use `jobpid(&channel)` instead.
-- *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
- - Lua: `vim.bo[bufnr].channel`
- - Vimscript: `getbufvar(bufnr, '&channel')`
+• *b:terminal_job_pid* Use `jobpid(&channel)` instead.
+• *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
+ • Lua: `vim.bo[bufnr].channel`
+ • Vimscript: `getbufvar(bufnr, '&channel')`
+
+VIMSCRIPT
+• *buffer_exists()* Obsolete name for |bufexists()|.
+• *buffer_name()* Obsolete name for |bufname()|.
+• *buffer_number()* Obsolete name for |bufnr()|.
+• *file_readable()* Obsolete name for |filereadable()|.
+• *highlight_exists()* Obsolete name for |hlexists()|.
+• *highlightID()* Obsolete name for |hlID()|.
+• *inputdialog()* Use |input()| instead.
+• *jobclose()* Obsolete name for |chanclose()|
+• *jobsend()* Obsolete name for |chansend()|
+• *last_buffer_nr()* Obsolete name for bufnr("$").
+• *rpcstart()* Use |jobstart()| with `{'rpc': v:true}` instead.
+• *rpcstop()* Use |jobstop()| instead to stop any job, or
+ `chanclose(id, "rpc")` to close RPC communication
+ without stopping the job. Use chanclose(id) to close
+ any socket.
vim:noet:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 172fa4625c..011970f5eb 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -294,6 +294,7 @@ TERMINAL
means that the |TermCursorNC| highlight group is no longer supported: an
unfocused terminal window will have no cursor at all (so there is nothing to
highlight).
+• |jobstart()| gained the "term" flag.
TREESITTER
diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt
index f9536c2f0c..ff8e3a976f 100644
--- a/runtime/doc/terminal.txt
+++ b/runtime/doc/terminal.txt
@@ -26,7 +26,7 @@ Start *terminal-start*
There are several ways to create a terminal buffer:
- Run the |:terminal| command.
-- Call the |nvim_open_term()| or |termopen()| function.
+- Call |nvim_open_term()| or `jobstart(…, {'term': v:true})`.
- Edit a "term://" buffer. Examples: >vim
:edit term://bash
:vsplit term://top
diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua
index 0b8a54e957..4216a2acb7 100644
--- a/runtime/lua/vim/_defaults.lua
+++ b/runtime/lua/vim/_defaults.lua
@@ -435,7 +435,7 @@ do
group = nvim_terminal_augroup,
desc = 'Treat term:// buffers as terminal buffers',
nested = true,
- command = "if !exists('b:term_title')|call termopen(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})",
+ command = "if !exists('b:term_title')|call jobstart(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'term': v:true, 'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})",
})
vim.api.nvim_create_autocmd({ 'TermClose' }, {
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
index 8d759278d0..bea6df43bb 100644
--- a/runtime/lua/vim/_meta/api.lua
+++ b/runtime/lua/vim/_meta/api.lua
@@ -272,12 +272,12 @@ function vim.api.nvim_buf_attach(buffer, send_buffer, opts) end
--- This temporarily switches current buffer to "buffer".
--- If the current window already shows "buffer", the window is not switched.
--- If a window inside the current tabpage (including a float) already shows the
---- buffer, then one of these windows will be set as current window temporarily.
+--- buffer, then one of those windows will be set as current window temporarily.
--- Otherwise a temporary scratch window (called the "autocmd window" for
--- historical reasons) will be used.
---
--- This is useful e.g. to call Vimscript functions that only work with the
---- current buffer/window currently, like `termopen()`.
+--- current buffer/window currently, like `jobstart(…, {'term': v:true})`.
---
--- @param buffer integer Buffer handle, or 0 for current buffer
--- @param fun function Function to call inside the buffer (currently Lua callable
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index cf1beda15f..b580357c85 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -4805,7 +4805,7 @@ function vim.fn.jobresize(job, width, height) end
--- @return any
function vim.fn.jobsend(...) end
---- Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
+--- Note: Prefer |vim.system()| in Lua (unless using `rpc`, `pty`, or `term`).
---
--- Spawns {cmd} as a job.
--- If {cmd} is a List it runs directly (no 'shell').
@@ -4813,8 +4813,11 @@ function vim.fn.jobsend(...) end
--- call jobstart(split(&shell) + split(&shellcmdflag) + ['{cmd}'])
--- <(See |shell-unquoting| for details.)
---
---- Example: >vim
---- call jobstart('nvim -h', {'on_stdout':{j,d,e->append(line('.'),d)}})
+--- Example: start a job and handle its output: >vim
+--- call jobstart(['nvim', '-h'], {'on_stdout':{j,d,e->append(line('.'),d)}})
+--- <
+--- Example: start a job in a |terminal| connected to the current buffer: >vim
+--- call jobstart(['nvim', '-h'], {'term':v:true})
--- <
--- Returns |job-id| on success, 0 on invalid arguments (or job
--- table is full), -1 if {cmd}[0] or 'shell' is not executable.
@@ -4879,6 +4882,10 @@ function vim.fn.jobsend(...) end
--- stdin: (string) Either "pipe" (default) to connect the
--- job's stdin to a channel or "null" to disconnect
--- stdin.
+--- term: (boolean) Spawns {cmd} in a new pseudo-terminal session
+--- connected to the current (unmodified) buffer. Implies "pty".
+--- Default "height" and "width" are set to the current window
+--- dimensions. |jobstart()|. Defaults $TERM to "xterm-256color".
--- width: (number) Width of the `pty` terminal.
---
--- {opts} is passed as |self| dictionary to the callback; the
@@ -10168,19 +10175,8 @@ function vim.fn.tanh(expr) end
--- @return string
function vim.fn.tempname() end
---- Spawns {cmd} in a new pseudo-terminal session connected
---- to the current (unmodified) buffer. Parameters and behavior
---- are the same as |jobstart()| except "pty", "width", "height",
---- and "TERM" are ignored: "height" and "width" are taken from
---- the current window. Note that termopen() implies a "pty" arg
---- to jobstart(), and thus has the implications documented at
---- |jobstart()|.
----
---- Returns the same values as jobstart().
----
---- Terminal environment is initialized as in |jobstart-env|,
---- except $TERM is set to "xterm-256color". Full behavior is
---- described in |terminal|.
+--- @deprecated
+--- Use |jobstart()| with `{term: v:true}` instead.
---
--- @param cmd string|string[]
--- @param opts? table
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index fd8c4b8817..b6da91a833 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -38,7 +38,7 @@
" NEOVIM COMPATIBILITY
"
" The vim specific functionalities were replaced with neovim specific calls:
-" - term_start -> termopen
+" - term_start -> `jobstart(…, {'term': v:true})`
" - term_sendkeys -> chansend
" - term_getline -> getbufline
" - job_info && term_getjob -> nvim_get_chan_info
@@ -251,7 +251,7 @@ endfunc
" Open a terminal window without a job, to run the debugged program in.
func s:StartDebug_term(dict)
execute s:vertical ? 'vnew' : 'new'
- let s:pty_job_id = termopen('tail -f /dev/null;#gdb program')
+ let s:pty_job_id = jobstart('tail -f /dev/null;#gdb program', {'term': v:true})
if s:pty_job_id == 0
call s:Echoerr('Invalid argument (or job table is full) while opening terminal window')
return
@@ -323,7 +323,7 @@ func s:StartDebug_term(dict)
execute 'new'
" call ch_log($'executing "{join(gdb_cmd)}"')
- let s:gdb_job_id = termopen(gdb_cmd, {'on_exit': function('s:EndTermDebug')})
+ let s:gdb_job_id = jobstart(gdb_cmd, {'term': v:true, 'on_exit': function('s:EndTermDebug')})
if s:gdb_job_id == 0
call s:Echoerr('Invalid argument (or job table is full) while opening gdb terminal window')
exe 'bwipe! ' . s:ptybufnr
@@ -491,7 +491,7 @@ func s:StartDebug_prompt(dict)
" Unix: Run the debugged program in a terminal window. Open it below the
" gdb window.
belowright new
- let s:pty_job_id = termopen('tail -f /dev/null;#gdb program')
+ let s:pty_job_id = jobstart('tail -f /dev/null;#gdb program', {'term': v:true})
if s:pty_job_id == 0
call s:Echoerr('Invalid argument (or job table is full) while opening terminal window')
return
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 2b6aa8b371..6c40eb9b20 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1181,12 +1181,12 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Arena *arena,
/// This temporarily switches current buffer to "buffer".
/// If the current window already shows "buffer", the window is not switched.
/// If a window inside the current tabpage (including a float) already shows the
-/// buffer, then one of these windows will be set as current window temporarily.
+/// buffer, then one of those windows will be set as current window temporarily.
/// Otherwise a temporary scratch window (called the "autocmd window" for
/// historical reasons) will be used.
///
/// This is useful e.g. to call Vimscript functions that only work with the
-/// current buffer/window currently, like |termopen()|.
+/// current buffer/window currently, like `jobstart(…, {'term': v:true})`.
///
/// @param buffer Buffer handle, or 0 for current buffer
/// @param fun Function to call inside the buffer (currently Lua callable
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 47f0a13b29..8bdd8dad4c 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8493,7 +8493,7 @@ char *do_string_sub(char *str, size_t len, char *pat, char *sub, typval_T *expr,
return ret;
}
-/// common code for getting job callbacks for jobstart, termopen and rpcstart
+/// Common code for getting job callbacks for `jobstart`.
///
/// @return true/false on success/failure.
bool common_job_callbacks(dict_T *vopts, CallbackReader *on_stdout, CallbackReader *on_stderr,
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 9de189cc16..72dabd53e9 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -5945,7 +5945,7 @@ M.funcs = {
jobstart = {
args = { 1, 2 },
desc = [=[
- Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
+ Note: Prefer |vim.system()| in Lua (unless using `rpc`, `pty`, or `term`).
Spawns {cmd} as a job.
If {cmd} is a List it runs directly (no 'shell').
@@ -5953,8 +5953,11 @@ M.funcs = {
call jobstart(split(&shell) + split(&shellcmdflag) + ['{cmd}'])
<(See |shell-unquoting| for details.)
- Example: >vim
- call jobstart('nvim -h', {'on_stdout':{j,d,e->append(line('.'),d)}})
+ Example: start a job and handle its output: >vim
+ call jobstart(['nvim', '-h'], {'on_stdout':{j,d,e->append(line('.'),d)}})
+ <
+ Example: start a job in a |terminal| connected to the current buffer: >vim
+ call jobstart(['nvim', '-h'], {'term':v:true})
<
Returns |job-id| on success, 0 on invalid arguments (or job
table is full), -1 if {cmd}[0] or 'shell' is not executable.
@@ -6019,6 +6022,10 @@ M.funcs = {
stdin: (string) Either "pipe" (default) to connect the
job's stdin to a channel or "null" to disconnect
stdin.
+ term: (boolean) Spawns {cmd} in a new pseudo-terminal session
+ connected to the current (unmodified) buffer. Implies "pty".
+ Default "height" and "width" are set to the current window
+ dimensions. |jobstart()|. Defaults $TERM to "xterm-256color".
width: (number) Width of the `pty` terminal.
{opts} is passed as |self| dictionary to the callback; the
@@ -12271,21 +12278,10 @@ M.funcs = {
signature = 'tempname()',
},
termopen = {
+ deprecated = true,
args = { 1, 2 },
desc = [=[
- Spawns {cmd} in a new pseudo-terminal session connected
- to the current (unmodified) buffer. Parameters and behavior
- are the same as |jobstart()| except "pty", "width", "height",
- and "TERM" are ignored: "height" and "width" are taken from
- the current window. Note that termopen() implies a "pty" arg
- to jobstart(), and thus has the implications documented at
- |jobstart()|.
-
- Returns the same values as jobstart().
-
- Terminal environment is initialized as in |jobstart-env|,
- except $TERM is set to "xterm-256color". Full behavior is
- described in |terminal|.
+ Use |jobstart()| with `{term: v:true}` instead.
]=],
name = 'termopen',
params = { { 'cmd', 'string|string[]' }, { 'opts', 'table' } },
diff --git a/src/nvim/eval/deprecated.c b/src/nvim/eval/deprecated.c
new file mode 100644
index 0000000000..67c254dac9
--- /dev/null
+++ b/src/nvim/eval/deprecated.c
@@ -0,0 +1,44 @@
+#include <stdbool.h> // for true
+
+#include "nvim/errors.h"
+#include "nvim/eval/deprecated.h"
+#include "nvim/eval/funcs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_defs.h"
+#include "nvim/ex_cmds.h"
+#include "nvim/gettext_defs.h" // for _
+#include "nvim/macros_defs.h" // for S_LEN
+#include "nvim/message.h" // for semsg
+#include "nvim/types_defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/deprecated.c.generated.h"
+#endif
+
+/// "termopen(cmd[, cwd])" function
+void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+{
+ if (check_secure()) {
+ return;
+ }
+
+ bool must_free = false;
+
+ if (argvars[1].v_type == VAR_UNKNOWN) {
+ must_free = true;
+ argvars[1].v_type = VAR_DICT;
+ argvars[1].vval.v_dict = tv_dict_alloc();
+ }
+
+ if (argvars[1].v_type != VAR_DICT) {
+ // Wrong argument types
+ semsg(_(e_invarg2), "expected dictionary");
+ return;
+ }
+
+ tv_dict_add_bool(argvars[1].vval.v_dict, S_LEN("term"), true);
+ f_jobstart(argvars, rettv, fptr);
+ if (must_free) {
+ tv_dict_free(argvars[1].vval.v_dict);
+ }
+}
diff --git a/src/nvim/eval/deprecated.h b/src/nvim/eval/deprecated.h
new file mode 100644
index 0000000000..b870403aa4
--- /dev/null
+++ b/src/nvim/eval/deprecated.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <stdbool.h> // for true
+
+#include "nvim/eval/typval_defs.h" // IWYU pragma: keep
+#include "nvim/types_defs.h" // IWYU pragma: keep
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/deprecated.h.generated.h"
+#endif
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 768d7664f7..23bfcff406 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -38,6 +38,7 @@
#include "nvim/eval.h"
#include "nvim/eval/buffer.h"
#include "nvim/eval/decode.h"
+#include "nvim/eval/deprecated.h"
#include "nvim/eval/encode.h"
#include "nvim/eval/executor.h"
#include "nvim/eval/funcs.h"
@@ -3840,8 +3841,8 @@ static const char *required_env_vars[] = {
NULL
};
-static dict_T *create_environment(const dictitem_T *job_env, const bool clear_env, const bool pty,
- const char * const pty_term_name)
+dict_T *create_environment(const dictitem_T *job_env, const bool clear_env, const bool pty,
+ const char * const pty_term_name)
{
dict_T *env = tv_dict_alloc();
@@ -3933,7 +3934,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
}
/// "jobstart()" function
-static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -3942,9 +3943,9 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
return;
}
+ const char *cmd;
bool executable = true;
- char **argv = tv_to_argv(&argvars[0], NULL, &executable);
- dict_T *env = NULL;
+ char **argv = tv_to_argv(&argvars[0], &cmd, &executable);
if (!argv) {
rettv->vval.v_number = executable ? 0 : -1;
return; // Did error message in tv_to_argv.
@@ -3961,6 +3962,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
bool detach = false;
bool rpc = false;
bool pty = false;
+ bool term = false;
bool clear_env = false;
bool overlapped = false;
ChannelStdinMode stdin_mode = kChannelStdinPipe;
@@ -3974,7 +3976,8 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
detach = tv_dict_get_number(job_opts, "detach") != 0;
rpc = tv_dict_get_number(job_opts, "rpc") != 0;
- pty = tv_dict_get_number(job_opts, "pty") != 0;
+ term = tv_dict_get_number(job_opts, "term") != 0;
+ pty = term || tv_dict_get_number(job_opts, "pty") != 0;
clear_env = tv_dict_get_number(job_opts, "clear_env") != 0;
overlapped = tv_dict_get_number(job_opts, "overlapped") != 0;
@@ -3989,6 +3992,14 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
}
}
+ dictitem_T *const job_term = tv_dict_find(job_opts, S_LEN("term"));
+ if (job_term && VAR_BOOL != job_term->di_tv.v_type) {
+ // Restrict "term" field to boolean, in case we want to allow buffer numbers in the future.
+ semsg(_(e_invarg2), "'term' must be Boolean");
+ shell_free_argv(argv);
+ return;
+ }
+
if (pty && rpc) {
semsg(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set");
shell_free_argv(argv);
@@ -4032,24 +4043,87 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
uint16_t height = 0;
char *term_name = NULL;
- if (pty) {
- width = (uint16_t)tv_dict_get_number(job_opts, "width");
- height = (uint16_t)tv_dict_get_number(job_opts, "height");
- // Legacy method, before env option existed, to specify $TERM. No longer
- // documented, but still usable to avoid breaking scripts.
- term_name = tv_dict_get_string(job_opts, "TERM", false);
- if (!term_name) {
- term_name = "ansi";
+ if (term) {
+ if (text_locked()) {
+ text_locked_msg();
+ shell_free_argv(argv);
+ return;
}
+ if (curbuf->b_changed) {
+ emsg(_("jobstart(...,{term=true}) requires unmodified buffer"));
+ shell_free_argv(argv);
+ return;
+ }
+ assert(!rpc);
+ term_name = "xterm-256color";
+ cwd = cwd ? cwd : ".";
+ overlapped = false;
+ detach = false;
+ stdin_mode = kChannelStdinPipe;
+ width = (uint16_t)MAX(0, curwin->w_width_inner - win_col_off(curwin));
+ height = (uint16_t)curwin->w_height_inner;
}
- env = create_environment(job_env, clear_env, pty, term_name);
+ if (pty) {
+ width = width ? width : (uint16_t)tv_dict_get_number(job_opts, "width");
+ height = height ? height : (uint16_t)tv_dict_get_number(job_opts, "height");
+ // Deprecated TERM field is from before `env` option existed.
+ term_name = term_name ? term_name : tv_dict_get_string(job_opts, "TERM", false);
+ term_name = term_name ? term_name : "ansi";
+ }
+ dict_T *env = create_environment(job_env, clear_env, pty, term_name);
Channel *chan = channel_job_start(argv, NULL, on_stdout, on_stderr, on_exit, pty,
rpc, overlapped, detach, stdin_mode, cwd,
width, height, env, &rettv->vval.v_number);
- if (chan) {
+ if (!chan) {
+ return;
+ } else if (!term) {
channel_create_event(chan, NULL);
+ } else {
+ if (rettv->vval.v_number <= 0) {
+ return;
+ }
+
+ int pid = chan->stream.pty.proc.pid;
+
+ // "./…" => "/home/foo/…"
+ vim_FullName(cwd, NameBuff, sizeof(NameBuff), false);
+ // "/home/foo/…" => "~/…"
+ size_t len = home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true);
+ // Trim slash.
+ if (len != 1 && (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/')) {
+ IObuff[len - 1] = NUL;
+ }
+
+ if (len == 1 && IObuff[0] == '/') {
+ // Avoid ambiguity in the URI when CWD is root directory.
+ IObuff[1] = '.';
+ IObuff[2] = NUL;
+ }
+
+ // Terminal URI: "term://$CWD//$PID:$CMD"
+ snprintf(NameBuff, sizeof(NameBuff), "term://%s//%d:%s", IObuff, pid, cmd);
+ // Buffer has no terminal associated yet; unset 'swapfile' to ensure no swapfile is created.
+ curbuf->b_p_swf = false;
+
+ apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf);
+ setfname(curbuf, NameBuff, NULL, true);
+ apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf);
+
+ Error err = ERROR_INIT;
+ // Set (deprecated) buffer-local vars (prefer 'channel' buffer-local option).
+ dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"),
+ INTEGER_OBJ((Integer)chan->id), false, false, NULL, &err);
+ api_clear_error(&err);
+ dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_pid"),
+ INTEGER_OBJ(pid), false, false, NULL, &err);
+ api_clear_error(&err);
+
+ channel_incref(chan);
+ channel_terminal_open(curbuf, chan);
+ channel_create_event(chan, NULL);
+ channel_decref(chan);
}
}
@@ -8133,134 +8207,6 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
(char *)tag_pattern, (char *)fname);
}
-/// "termopen(cmd[, cwd])" function
-static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
-{
- if (check_secure()) {
- return;
- }
- if (text_locked()) {
- text_locked_msg();
- return;
- }
- if (curbuf->b_changed) {
- emsg(_("Can only call this function in an unmodified buffer"));
- return;
- }
-
- const char *cmd;
- bool executable = true;
- char **argv = tv_to_argv(&argvars[0], &cmd, &executable);
- if (!argv) {
- rettv->vval.v_number = executable ? 0 : -1;
- return; // Did error message in tv_to_argv.
- }
-
- if (argvars[1].v_type != VAR_DICT && argvars[1].v_type != VAR_UNKNOWN) {
- // Wrong argument type
- semsg(_(e_invarg2), "expected dictionary");
- shell_free_argv(argv);
- return;
- }
-
- CallbackReader on_stdout = CALLBACK_READER_INIT;
- CallbackReader on_stderr = CALLBACK_READER_INIT;
- Callback on_exit = CALLBACK_NONE;
- dict_T *job_opts = NULL;
- const char *cwd = ".";
- dict_T *env = NULL;
- const bool pty = true;
- bool clear_env = false;
- dictitem_T *job_env = NULL;
-
- if (argvars[1].v_type == VAR_DICT) {
- job_opts = argvars[1].vval.v_dict;
-
- const char *const new_cwd = tv_dict_get_string(job_opts, "cwd", false);
- if (new_cwd && *new_cwd != NUL) {
- cwd = new_cwd;
- // The new cwd must be a directory.
- if (!os_isdir(cwd)) {
- semsg(_(e_invarg2), "expected valid directory");
- shell_free_argv(argv);
- return;
- }
- }
-
- job_env = tv_dict_find(job_opts, S_LEN("env"));
- if (job_env && job_env->di_tv.v_type != VAR_DICT) {
- semsg(_(e_invarg2), "env");
- shell_free_argv(argv);
- return;
- }
-
- clear_env = tv_dict_get_number(job_opts, "clear_env") != 0;
-
- if (!common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit)) {
- shell_free_argv(argv);
- return;
- }
- }
-
- env = create_environment(job_env, clear_env, pty, "xterm-256color");
-
- const bool rpc = false;
- const bool overlapped = false;
- const bool detach = false;
- ChannelStdinMode stdin_mode = kChannelStdinPipe;
- uint16_t term_width = (uint16_t)MAX(0, curwin->w_width_inner - win_col_off(curwin));
- Channel *chan = channel_job_start(argv, NULL, on_stdout, on_stderr, on_exit,
- pty, rpc, overlapped, detach, stdin_mode,
- cwd, term_width, (uint16_t)curwin->w_height_inner,
- env, &rettv->vval.v_number);
- if (rettv->vval.v_number <= 0) {
- return;
- }
-
- int pid = chan->stream.pty.proc.pid;
-
- // "./…" => "/home/foo/…"
- vim_FullName(cwd, NameBuff, sizeof(NameBuff), false);
- // "/home/foo/…" => "~/…"
- size_t len = home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true);
- // Trim slash.
- if (len != 1 && (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/')) {
- IObuff[len - 1] = NUL;
- }
-
- if (len == 1 && IObuff[0] == '/') {
- // Avoid ambiguity in the URI when CWD is root directory.
- IObuff[1] = '.';
- IObuff[2] = NUL;
- }
-
- // Terminal URI: "term://$CWD//$PID:$CMD"
- snprintf(NameBuff, sizeof(NameBuff), "term://%s//%d:%s",
- IObuff, pid, cmd);
- // at this point the buffer has no terminal instance associated yet, so unset
- // the 'swapfile' option to ensure no swap file will be created
- curbuf->b_p_swf = false;
-
- apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf);
- setfname(curbuf, NameBuff, NULL, true);
- apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf);
-
- // Save the job id and pid in b:terminal_job_{id,pid}
- Error err = ERROR_INIT;
- // deprecated: use 'channel' buffer option
- dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"),
- INTEGER_OBJ((Integer)chan->id), false, false, NULL, &err);
- api_clear_error(&err);
- dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_pid"),
- INTEGER_OBJ(pid), false, false, NULL, &err);
- api_clear_error(&err);
-
- channel_incref(chan);
- channel_terminal_open(curbuf, chan);
- channel_create_event(chan, NULL);
- channel_decref(chan);
-}
-
/// "timer_info([timer])" function
static void f_timer_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 052bf3b9f7..bd8623397a 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7775,7 +7775,7 @@ static void ex_terminal(exarg_T *eap)
if (*eap->arg != NUL) { // Run {cmd} in 'shell'.
char *name = vim_strsave_escaped(eap->arg, "\"\\");
snprintf(ex_cmd + len, sizeof(ex_cmd) - len,
- " | call termopen(\"%s\")", name);
+ " | call jobstart(\"%s\",{'term':v:true})", name);
xfree(name);
} else { // No {cmd}: run the job with tokenized 'shell'.
if (*p_sh == NUL) {
@@ -7798,7 +7798,7 @@ static void ex_terminal(exarg_T *eap)
shell_free_argv(argv);
snprintf(ex_cmd + len, sizeof(ex_cmd) - len,
- " | call termopen([%s])", shell_argv + 1);
+ " | call jobstart([%s], {'term':v:true})", shell_argv + 1);
}
do_cmdline_cmd(ex_cmd);
diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua
index 443c68e008..0b6ee6cb24 100644
--- a/src/nvim/generators/gen_eval.lua
+++ b/src/nvim/generators/gen_eval.lua
@@ -19,6 +19,7 @@ hashpipe:write([[
#include "nvim/digraph.h"
#include "nvim/eval.h"
#include "nvim/eval/buffer.h"
+#include "nvim/eval/deprecated.h"
#include "nvim/eval/fs.h"
#include "nvim/eval/funcs.h"
#include "nvim/eval/typval.h"
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 969c539f97..61eede5ae1 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -357,7 +357,7 @@ static void term_output_callback(const char *s, size_t len, void *user_data)
/// Initializes terminal properties, and triggers TermOpen.
///
-/// The PTY process (TerminalOptions.data) was already started by termopen(),
+/// The PTY process (TerminalOptions.data) was already started by jobstart(),
/// via ex_terminal() or the term:// BufReadCmd.
///
/// @param buf Buffer used for presentation of the terminal.
diff --git a/test/functional/api/buffer_updates_spec.lua b/test/functional/api/buffer_updates_spec.lua
index 527394bfd1..489f601d31 100644
--- a/test/functional/api/buffer_updates_spec.lua
+++ b/test/functional/api/buffer_updates_spec.lua
@@ -879,7 +879,8 @@ describe('API: buffer events:', function()
it('when :terminal lines change', function()
local buffer_lines = {}
local expected_lines = {}
- fn.termopen({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '-n', '-c', 'set shortmess+=A' }, {
+ fn.jobstart({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '-n', '-c', 'set shortmess+=A' }, {
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 130be9987f..fbc9490df6 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -2704,7 +2704,8 @@ describe('API', function()
-- :terminal with args + running process.
command('enew')
local progpath_esc = eval('shellescape(v:progpath)')
- fn.termopen(('%s -u NONE -i NONE'):format(progpath_esc), {
+ fn.jobstart(('%s -u NONE -i NONE'):format(progpath_esc), {
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
eq(-1, eval('jobwait([&channel], 0)[0]')) -- Running?
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index b4d80d4ed4..952437d80e 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -65,6 +65,39 @@ describe('jobs', function()
]])
end)
+ it('validation', function()
+ matches(
+ "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set",
+ pcall_err(command, "call jobstart(['cat', '-'], { 'pty': v:true, 'rpc': v:true })")
+ )
+ matches(
+ 'E475: Invalid argument: expected valid directory',
+ pcall_err(command, "call jobstart(['cat', '-'], { 'cwd': 9313843 })")
+ )
+ matches(
+ 'E475: Invalid argument: expected valid directory',
+ pcall_err(command, "call jobstart(['cat', '-'], { 'cwd': 'bogusssssss/bogus' })")
+ )
+ matches(
+ "E475: Invalid argument: 'term' must be Boolean",
+ pcall_err(command, "call jobstart(['cat', '-'], { 'term': 'bogus' })")
+ )
+ matches(
+ "E475: Invalid argument: 'term' must be Boolean",
+ pcall_err(command, "call jobstart(['cat', '-'], { 'term': 1 })")
+ )
+ command('set modified')
+ matches(
+ vim.pesc('jobstart(...,{term=true}) requires unmodified buffer'),
+ pcall_err(command, "call jobstart(['cat', '-'], { 'term': v:true })")
+ )
+
+ -- Non-failure cases:
+ command('set nomodified')
+ command("call jobstart(['cat', '-'], { 'term': v:true })")
+ command("call jobstart(['cat', '-'], { 'term': v:false })")
+ end)
+
it('must specify env option as a dict', function()
command('let g:job_opts.env = v:true')
local _, err = pcall(function()
@@ -969,13 +1002,6 @@ describe('jobs', function()
eq({ 'notification', 'exit', { 0, 143 } }, next_msg())
end)
- it('cannot have both rpc and pty options', function()
- command('let g:job_opts.pty = v:true')
- command('let g:job_opts.rpc = v:true')
- local _, err = pcall(command, "let j = jobstart(['cat', '-'], g:job_opts)")
- matches("E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set", err)
- end)
-
it('does not crash when repeatedly failing to start shell', function()
source([[
set shell=nosuchshell
@@ -1230,7 +1256,7 @@ describe('pty process teardown', function()
it('does not prevent/delay exit. #4798 #4900', function()
skip(fn.executable('sleep') == 0, 'missing "sleep" command')
-- Use a nested nvim (in :term) to test without --headless.
- fn.termopen({
+ fn.jobstart({
n.nvim_prog,
'-u',
'NONE',
@@ -1243,7 +1269,10 @@ describe('pty process teardown', function()
'+terminal',
'+!(sleep 300 &)',
'+qa',
- }, { env = { VIMRUNTIME = os.getenv('VIMRUNTIME') } })
+ }, {
+ term = true,
+ env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
+ })
-- Exiting should terminate all descendants (PTY, its children, ...).
screen:expect([[
diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua
index bfa5a0eb6a..ce4ba1905f 100644
--- a/test/functional/core/main_spec.lua
+++ b/test/functional/core/main_spec.lua
@@ -103,7 +103,8 @@ describe('command-line option', function()
-- Need to explicitly pipe to stdin so that the embedded Nvim instance doesn't try to read
-- data from the terminal #18181
- fn.termopen(string.format([[echo "" | %s]], table.concat(args, ' ')), {
+ fn.jobstart(string.format([[echo "" | %s]], table.concat(args, ' ')), {
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
screen:expect(
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 319a037342..76b0755441 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -55,7 +55,10 @@ describe('startup', function()
clear()
local screen
screen = Screen.new(84, 3)
- fn.termopen({ nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' })
+ fn.jobstart(
+ { nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' },
+ { term = true }
+ )
screen:expect([[
^Cannot attach UI of :terminal child to its parent. (Unset $NVIM to skip this check) |
|*2
@@ -98,7 +101,7 @@ describe('startup', function()
screen = Screen.new(60, 7)
-- not the same colors on windows for some reason
screen._default_attr_ids = nil
- local id = fn.termopen({
+ local id = fn.jobstart({
nvim_prog,
'-u',
'NONE',
@@ -108,6 +111,7 @@ describe('startup', function()
'set noruler',
'-D',
}, {
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -360,7 +364,7 @@ describe('startup', function()
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
- fn.termopen({
+ fn.jobstart({
nvim_prog,
'-u',
'NONE',
@@ -371,6 +375,7 @@ describe('startup', function()
'-c',
'echo has("ttyin") has("ttyout")',
}, {
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -393,13 +398,14 @@ describe('startup', function()
os.remove('Xtest_startup_ttyout')
end)
-- Running in :terminal
- fn.termopen(
+ fn.jobstart(
(
[["%s" -u NONE -i NONE --cmd "%s"]]
.. [[ -c "call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')"]]
.. [[ -c q | cat -v]]
):format(nvim_prog, nvim_set),
{
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -424,7 +430,7 @@ describe('startup', function()
os.remove('Xtest_startup_ttyout')
end)
-- Running in :terminal
- fn.termopen(
+ fn.jobstart(
(
[[echo foo | ]] -- Input from a pipe.
.. [["%s" -u NONE -i NONE --cmd "%s"]]
@@ -432,6 +438,7 @@ describe('startup', function()
.. [[ -c q -- -]]
):format(nvim_prog, nvim_set),
{
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -454,13 +461,14 @@ describe('startup', function()
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
- fn.termopen(
+ fn.jobstart(
(
[[echo foo | ]]
.. [["%s" -u NONE -i NONE --cmd "%s"]]
.. [[ -c "echo has('ttyin') has('ttyout')"]]
):format(nvim_prog, nvim_set),
{
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -614,7 +622,7 @@ describe('startup', function()
local screen
screen = Screen.new(60, 6)
screen._default_attr_ids = nil
- local id = fn.termopen({
+ local id = fn.jobstart({
nvim_prog,
'-u',
'NONE',
@@ -625,6 +633,7 @@ describe('startup', function()
'--cmd',
'let g:foo = g:bar',
}, {
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -1144,7 +1153,8 @@ describe('user config init', function()
local screen = Screen.new(50, 8)
screen._default_attr_ids = nil
- fn.termopen({ nvim_prog }, {
+ fn.jobstart({ nvim_prog }, {
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -1418,7 +1428,7 @@ describe('inccommand on ex mode', function()
clear()
local screen
screen = Screen.new(60, 10)
- local id = fn.termopen({
+ local id = fn.jobstart({
nvim_prog,
'-u',
'NONE',
@@ -1429,6 +1439,7 @@ describe('inccommand on ex mode', function()
'-E',
'test/README.md',
}, {
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
fn.chansend(id, '%s/N')
diff --git a/test/functional/editor/mode_normal_spec.lua b/test/functional/editor/mode_normal_spec.lua
index 5237f51237..353a261edb 100644
--- a/test/functional/editor/mode_normal_spec.lua
+++ b/test/functional/editor/mode_normal_spec.lua
@@ -26,10 +26,10 @@ describe('Normal mode', function()
it('&showcmd does not crash with :startinsert #28419', function()
local screen = Screen.new(60, 17)
- fn.termopen(
- { n.nvim_prog, '--clean', '--cmd', 'startinsert' },
- { env = { VIMRUNTIME = os.getenv('VIMRUNTIME') } }
- )
+ fn.jobstart({ n.nvim_prog, '--clean', '--cmd', 'startinsert' }, {
+ term = true,
+ env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
+ })
screen:expect({
grid = [[
^ |
diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
index 2820cc9663..7234985009 100644
--- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
+++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
@@ -115,7 +115,8 @@ describe("preserve and (R)ecover with custom 'directory'", function()
t.skip(t.is_os('win'))
local screen0 = Screen.new()
local child_server = new_pipename()
- fn.termopen({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server }, {
+ fn.jobstart({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server }, {
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
screen0:expect({ any = pesc('[No Name]') }) -- Wait for the child process to start.
@@ -446,9 +447,10 @@ describe('quitting swapfile dialog on startup stops TUI properly', function()
end)
it('(Q)uit at first file argument', function()
- local chan = fn.termopen(
+ local chan = fn.jobstart(
{ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', init_dir, '--cmd', init_set, testfile },
{
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
}
)
@@ -468,7 +470,7 @@ describe('quitting swapfile dialog on startup stops TUI properly', function()
end)
it('(A)bort at second file argument with -p', function()
- local chan = fn.termopen({
+ local chan = fn.jobstart({
nvim_prog,
'-u',
'NONE',
@@ -482,6 +484,7 @@ describe('quitting swapfile dialog on startup stops TUI properly', function()
otherfile,
testfile,
}, {
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
retry(nil, nil, function()
@@ -508,7 +511,7 @@ describe('quitting swapfile dialog on startup stops TUI properly', function()
second %s /^ \zssecond$/
third %s /^ \zsthird$/]]):format(testfile, testfile, testfile)
)
- local chan = fn.termopen({
+ local chan = fn.jobstart({
nvim_prog,
'-u',
'NONE',
@@ -522,6 +525,7 @@ describe('quitting swapfile dialog on startup stops TUI properly', function()
'set tags=' .. otherfile,
'-tsecond',
}, {
+ term = true,
env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
retry(nil, nil, function()
diff --git a/test/functional/legacy/window_cmd_spec.lua b/test/functional/legacy/window_cmd_spec.lua
index d68c780f49..b58bf0bf43 100644
--- a/test/functional/legacy/window_cmd_spec.lua
+++ b/test/functional/legacy/window_cmd_spec.lua
@@ -120,7 +120,7 @@ describe('splitkeep', function()
row = 0,
col = 0,
}))
- vim.cmd("call termopen([&sh, &shcf, 'true'], { 'on_exit': 'C2' })")
+ vim.cmd("call jobstart([&sh, &shcf, 'true'], { 'term': v:true, 'on_exit': 'C2' })")
end
})]])
feed('j')
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index edb4c928c1..e209ed9025 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -378,7 +378,7 @@ describe(':terminal buffer', function()
}, exec_lua('return _G.input'))
end)
- it('no heap-buffer-overflow when using termopen(echo) #3161', function()
+ it('no heap-buffer-overflow when using jobstart("echo",{term=true}) #3161', function()
local testfilename = 'Xtestfile-functional-terminal-buffers_spec'
write_file(testfilename, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa')
finally(function()
@@ -387,8 +387,8 @@ describe(':terminal buffer', function()
feed_command('edit ' .. testfilename)
-- Move cursor away from the beginning of the line
feed('$')
- -- Let termopen() modify the buffer
- feed_command('call termopen("echo")')
+ -- Let jobstart(…,{term=true}) modify the buffer
+ feed_command([[call jobstart("echo", {'term':v:true})]])
assert_alive()
feed_command('bdelete!')
end)
@@ -411,7 +411,7 @@ describe(':terminal buffer', function()
it('handles split UTF-8 sequences #16245', function()
local screen = Screen.new(50, 7)
- fn.termopen({ testprg('shell-test'), 'UTF-8' })
+ fn.jobstart({ testprg('shell-test'), 'UTF-8' }, { term = true })
screen:expect([[
^å |
ref: å̲ |
@@ -669,7 +669,7 @@ if is_os('win') then
end)
end
-describe('termopen()', function()
+describe('termopen() (deprecated alias to `jobstart(…,{term=true})`)', function()
before_each(clear)
it('disallowed when textlocked and in cmdwin buffer', function()
diff --git a/test/functional/terminal/channel_spec.lua b/test/functional/terminal/channel_spec.lua
index 9912c1ff7b..bb97411f43 100644
--- a/test/functional/terminal/channel_spec.lua
+++ b/test/functional/terminal/channel_spec.lua
@@ -75,8 +75,8 @@ describe('terminal channel is closed and later released if', function()
eq(chans - 1, eval('len(nvim_list_chans())'))
end)
- it('opened by termopen(), exited, and deleted by pressing a key', function()
- command([[let id = termopen('echo')]])
+ it('opened by jobstart(…,{term=true}), exited, and deleted by pressing a key', function()
+ command([[let id = jobstart('echo',{'term':v:true})]])
local chans = eval('len(nvim_list_chans())')
-- wait for process to exit
screen:expect({ any = '%[Process exited 0%]' })
@@ -96,8 +96,8 @@ describe('terminal channel is closed and later released if', function()
end)
-- This indirectly covers #16264
- it('opened by termopen(), exited, and deleted by :bdelete', function()
- command([[let id = termopen('echo')]])
+ it('opened by jobstart(…,{term=true}), exited, and deleted by :bdelete', function()
+ command([[let id = jobstart('echo', {'term':v:true})]])
local chans = eval('len(nvim_list_chans())')
-- wait for process to exit
screen:expect({ any = '%[Process exited 0%]' })
@@ -124,7 +124,7 @@ it('chansend sends lines to terminal channel in proper order', function()
screen._default_attr_ids = nil
local shells = is_os('win') and { 'cmd.exe', 'pwsh.exe -nop', 'powershell.exe -nop' } or { 'sh' }
for _, sh in ipairs(shells) do
- command([[let id = termopen(']] .. sh .. [[')]])
+ command([[let id = jobstart(']] .. sh .. [[', {'term':v:true})]])
command([[call chansend(id, ['echo "hello"', 'echo "world"', ''])]])
screen:expect {
any = [[echo "hello".*echo "world"]],
@@ -149,7 +149,7 @@ describe('no crash when TermOpen autocommand', function()
})
end)
- it('processes job exit event when using termopen()', function()
+ it('processes job exit event when using jobstart(…,{term=true})', function()
command([[autocmd TermOpen * call input('')]])
async_meths.nvim_command('terminal foobar')
screen:expect {
@@ -179,7 +179,7 @@ describe('no crash when TermOpen autocommand', function()
assert_alive()
end)
- it('wipes buffer and processes events when using termopen()', function()
+ it('wipes buffer and processes events when using jobstart(…,{term=true})', function()
command([[autocmd TermOpen * bwipe! | call input('')]])
async_meths.nvim_command('terminal foobar')
screen:expect {
diff --git a/test/functional/terminal/clipboard_spec.lua b/test/functional/terminal/clipboard_spec.lua
index 4a1a0e29fd..f0ce407eaa 100644
--- a/test/functional/terminal/clipboard_spec.lua
+++ b/test/functional/terminal/clipboard_spec.lua
@@ -56,7 +56,7 @@ describe(':terminal', function()
return string.format('\027]52;;%s\027\\', arg)
end
- fn.termopen({ testprg('shell-test'), '-t', osc52(encoded) })
+ fn.jobstart({ testprg('shell-test'), '-t', osc52(encoded) }, { term = true })
retry(nil, 1000, function()
eq(text, exec_lua([[ return vim.g.clipboard_data ]]))
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index 368afd6d36..8594a9ce16 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -239,7 +239,7 @@ describe(':terminal cursor', function()
feed([[<C-\><C-N>]])
command('set statusline=~~~')
command('new')
- call('termopen', { testprg('tty-test') })
+ call('jobstart', { testprg('tty-test') }, { term = true })
feed('i')
screen:expect({
grid = [[
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 5ebe7bd4fc..5224d322d3 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -175,7 +175,7 @@ local function test_terminal_with_fake_shell(backslash)
api.nvim_set_option_value('shellxquote', '', {}) -- win: avoid extra quotes
end)
- it('with no argument, acts like termopen()', function()
+ it('with no argument, acts like jobstart(…,{term=true})', function()
command('autocmd! nvim_terminal TermClose')
feed_command('terminal')
screen:expect([[
@@ -196,7 +196,7 @@ local function test_terminal_with_fake_shell(backslash)
]])
end)
- it("with no argument, but 'shell' has arguments, acts like termopen()", function()
+ it("with no argument, but 'shell' has arguments, acts like jobstart(…,{term=true})", function()
api.nvim_set_option_value('shell', shell_path .. ' INTERACT', {})
feed_command('terminal')
screen:expect([[
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 5ed3c72b72..c43d139f70 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -33,7 +33,7 @@ describe(':terminal highlight', function()
[12] = { bold = true, underdouble = true },
[13] = { italic = true, undercurl = true },
})
- command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
+ command(("enew | call jobstart(['%s'], {'term':v:true})"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
@@ -150,7 +150,7 @@ it(':terminal highlight has lower precedence than editor #9964', function()
},
})
-- Child nvim process in :terminal (with cterm colors).
- fn.termopen({
+ fn.jobstart({
nvim_prog_abs(),
'-n',
'-u',
@@ -163,6 +163,7 @@ it(':terminal highlight has lower precedence than editor #9964', function()
'+norm! ichild nvim',
'+norm! oline 2',
}, {
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -200,7 +201,7 @@ it('CursorLine and CursorColumn work in :terminal buffer in Normal mode', functi
[4] = { background = Screen.colors.Grey90, reverse = true },
[5] = { background = Screen.colors.Red },
})
- command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
+ command(("enew | call jobstart(['%s'], {'term':v:true})"):format(testprg('tty-test')))
screen:expect([[
^tty ready |
|*6
@@ -318,7 +319,7 @@ describe(':terminal highlight forwarding', function()
[2] = { { fg_indexed = true, foreground = tonumber('0xe0e000') }, { foreground = 3 } },
[3] = { { foreground = tonumber('0xff8000') }, {} },
})
- command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
+ command(("enew | call jobstart(['%s'], {'term':v:true})"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
@@ -364,7 +365,7 @@ describe(':terminal highlight with custom palette', function()
[9] = { bold = true },
})
api.nvim_set_var('terminal_color_3', '#123456')
- command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
+ command(("enew | call jobstart(['%s'], {'term':v:true})"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 0de7873200..804c5367eb 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -355,7 +355,9 @@ describe(':terminal prints more lines than the screen height and exits', functio
it('will push extra lines to scrollback', function()
clear()
local screen = Screen.new(30, 7, { rgb = false })
- command(("call termopen(['%s', '10']) | startinsert"):format(testprg('tty-test')))
+ command(
+ ("call jobstart(['%s', '10'], {'term':v:true}) | startinsert"):format(testprg('tty-test'))
+ )
screen:expect([[
line6 |
line7 |
@@ -623,7 +625,7 @@ describe('pending scrollback line handling', function()
local bufnr = vim.api.nvim_create_buf(false, true)
local args = ...
vim.api.nvim_buf_call(bufnr, function()
- vim.fn.termopen(args)
+ vim.fn.jobstart(args, { term = true })
end)
vim.api.nvim_win_set_buf(0, bufnr)
vim.cmd('startinsert')
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 832bacb534..de92aefd5b 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -2114,7 +2114,7 @@ describe('TUI', function()
[5] = { bold = true, reverse = true },
[6] = { foreground = Screen.colors.White, background = Screen.colors.DarkGreen },
})
- fn.termopen({
+ fn.jobstart({
nvim_prog,
'--clean',
'--cmd',
@@ -2124,6 +2124,7 @@ describe('TUI', function()
'--cmd',
'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile',
}, {
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
@@ -2146,7 +2147,7 @@ describe('TUI', function()
for _, guicolors in ipairs({ 'notermguicolors', 'termguicolors' }) do
it('has no black flicker when clearing regions during startup with ' .. guicolors, function()
local screen = Screen.new(50, 10)
- fn.termopen({
+ fn.jobstart({
nvim_prog,
'--clean',
'--cmd',
@@ -2154,6 +2155,7 @@ describe('TUI', function()
'--cmd',
'sleep 10',
}, {
+ term = true,
env = {
VIMRUNTIME = os.getenv('VIMRUNTIME'),
},
diff --git a/test/functional/testterm.lua b/test/functional/testterm.lua
index 7ae28dce69..17209d947e 100644
--- a/test/functional/testterm.lua
+++ b/test/functional/testterm.lua
@@ -141,7 +141,7 @@ function M.setup_screen(extra_rows, cmd, cols, env, screen_opts)
})
api.nvim_command('enew')
- api.nvim_call_function('termopen', { cmd, env and { env = env } or nil })
+ api.nvim_call_function('jobstart', { cmd, { term = true, env = (env and env or nil) } })
api.nvim_input('<CR>')
local vim_errmsg = api.nvim_eval('v:errmsg')
if vim_errmsg and '' ~= vim_errmsg then
diff --git a/test/functional/ui/hlstate_spec.lua b/test/functional/ui/hlstate_spec.lua
index 745ad70efe..e10c79fa48 100644
--- a/test/functional/ui/hlstate_spec.lua
+++ b/test/functional/ui/hlstate_spec.lua
@@ -224,7 +224,7 @@ describe('ext_hlstate detailed highlights', function()
[6] = { { foreground = tonumber('0x40ffff'), fg_indexed = true }, { 5, 1 } },
[7] = { {}, { { hi_name = 'MsgArea', ui_name = 'MsgArea', kind = 'ui' } } },
})
- command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
+ command(("enew | call jobstart(['%s'],{'term':v:true})"):format(testprg('tty-test')))
screen:expect([[
^tty ready |
|
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index 6d8c6609c8..d48d56aeb6 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -2062,7 +2062,7 @@ describe('ui/msg_puts_printf', function()
)
cmd = cmd .. '"' .. nvim_prog .. '" -u NONE -i NONE -Es -V1'
- command([[call termopen(']] .. cmd .. [[')]])
+ command([[call jobstart(']] .. cmd .. [[',{'term':v:true})]])
screen:expect([[
^Exモードに入ります。ノー |
マルモードに戻るには "vis|
diff --git a/test/functional/ui/title_spec.lua b/test/functional/ui/title_spec.lua
index aa9ac3f5b5..2de1e71457 100644
--- a/test/functional/ui/title_spec.lua
+++ b/test/functional/ui/title_spec.lua
@@ -80,7 +80,7 @@ describe('title', function()
it('is updated in Terminal mode', function()
api.nvim_set_option_value('title', true, {})
api.nvim_set_option_value('titlestring', '(%{mode(1)}) | nvim', {})
- fn.termopen({ n.testprg('shell-test'), 'INTERACT' })
+ fn.jobstart({ n.testprg('shell-test'), 'INTERACT' }, { term = true })
screen:expect(function()
eq('(nt) | nvim', screen.title)
end)
diff --git a/test/old/testdir/runnvim.vim b/test/old/testdir/runnvim.vim
index 578614c8a1..f5945aeaee 100644
--- a/test/old/testdir/runnvim.vim
+++ b/test/old/testdir/runnvim.vim
@@ -8,6 +8,7 @@ function s:logger.on_exit(id, data, event)
endfunction
let s:logger.env = #{VIMRUNTIME: $VIMRUNTIME}
+let s:logger.term = v:true
" Replace non-printable chars by special sequence, or "<%x>".
let s:escaped_char = {"\n": '\n', "\r": '\r', "\t": '\t'}
@@ -25,7 +26,7 @@ function Main()
set lines=25
set columns=80
enew
- let job = termopen(args, s:logger)
+ let job = jobstart(args, s:logger)
let results = jobwait([job], 5 * 60 * 1000)
" TODO(ZyX-I): Get colors
let screen = getline(1, '$')