mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
feat(server): set $NVIM, unset $NVIM_LISTEN_ADDRESS #11009
PROBLEM ------------------------------------------------------------------------ $NVIM_LISTEN_ADDRESS has conflicting purposes as both a parameter ("the current process should listen on this address") and a descriptor ("the current process is a child of this address"). This contradiction means the presence of NVIM_LISTEN_ADDRESS is ambiguous, so child Nvim always tries to listen on its _parent's_ socket. This is the cause of lots of "Failed to start server" spam in our test/CI logs: WARN 2022-04-30… server_start:154: Failed to start server: address already in use: \\.\pipe\nvim-4480-0 WARN 2022-04-30… server_start:154: Failed to start server: address already in use: \\.\pipe\nvim-2168-0 SOLUTION ------------------------------------------------------------------------ 1. Set $NVIM to the parent v:servername, *only* in child processes. - Now the correct way to detect a "parent" Nvim is to check for $NVIM. 2. Do NOT set $NVIM_LISTEN_ADDRESS in child processes. 3. On startup if $NVIM_LISTEN_ADDRESS exists, unset it immediately after server init. 4. Open a channel to parent automatically, expose it as v:parent. Fixes #3118 Fixes #6764 Fixes #9336 Ref https://github.com/neovim/neovim/pull/8247#issuecomment-380275696 Ref #8696
This commit is contained in:
parent
b5c15ba7e5
commit
4fb48c5654
@ -59,7 +59,7 @@ Nvim instance:
|
|||||||
# trailing '&' which is required since Nvim won't process events while
|
# trailing '&' which is required since Nvim won't process events while
|
||||||
# running a blocking command):
|
# running a blocking command):
|
||||||
#
|
#
|
||||||
# :!./hello.rb &
|
# :!./hello.rb &
|
||||||
#
|
#
|
||||||
# Or from another shell by setting NVIM_LISTEN_ADDRESS:
|
# Or from another shell by setting NVIM_LISTEN_ADDRESS:
|
||||||
# $ NVIM_LISTEN_ADDRESS=[address] ./hello.rb
|
# $ NVIM_LISTEN_ADDRESS=[address] ./hello.rb
|
||||||
|
@ -158,7 +158,6 @@ foldclosedend({lnum}) Number last line of fold at {lnum} if closed
|
|||||||
foldlevel({lnum}) Number fold level at {lnum}
|
foldlevel({lnum}) Number fold level at {lnum}
|
||||||
foldtext() String line displayed for closed fold
|
foldtext() String line displayed for closed fold
|
||||||
foldtextresult({lnum}) String text for closed fold at {lnum}
|
foldtextresult({lnum}) String text for closed fold at {lnum}
|
||||||
foreground() Number bring the Vim window to the foreground
|
|
||||||
fullcommand({name}) String get full command from {name}
|
fullcommand({name}) String get full command from {name}
|
||||||
funcref({name} [, {arglist}] [, {dict}])
|
funcref({name} [, {arglist}] [, {dict}])
|
||||||
Funcref reference to function {name}
|
Funcref reference to function {name}
|
||||||
@ -352,16 +351,6 @@ reg_recording() String get the recording register name
|
|||||||
reltime([{start} [, {end}]]) List get time value
|
reltime([{start} [, {end}]]) List get time value
|
||||||
reltimefloat({time}) Float turn the time value into a Float
|
reltimefloat({time}) Float turn the time value into a Float
|
||||||
reltimestr({time}) String turn time value into a String
|
reltimestr({time}) String turn time value into a String
|
||||||
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
|
|
||||||
String send expression
|
|
||||||
remote_foreground({server}) Number bring Vim server to the foreground
|
|
||||||
remote_peek({serverid} [, {retvar}])
|
|
||||||
Number check for reply string
|
|
||||||
remote_read({serverid} [, {timeout}])
|
|
||||||
String read reply string
|
|
||||||
remote_send({server}, {string} [, {idvar}])
|
|
||||||
String send key sequence
|
|
||||||
remote_startserver({name}) none become server {name}
|
|
||||||
remove({list}, {idx} [, {end}]) any/List
|
remove({list}, {idx} [, {end}]) any/List
|
||||||
remove items {idx}-{end} from {list}
|
remove items {idx}-{end} from {list}
|
||||||
remove({blob}, {idx} [, {end}]) Number/Blob
|
remove({blob}, {idx} [, {end}]) Number/Blob
|
||||||
@ -395,8 +384,6 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [...]]])
|
|||||||
List search for other end of start/end pair
|
List search for other end of start/end pair
|
||||||
searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
|
searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
|
||||||
List search for {pattern}
|
List search for {pattern}
|
||||||
server2client({clientid}, {string})
|
|
||||||
Number send reply string
|
|
||||||
serverlist() String get a list of available servers
|
serverlist() String get a list of available servers
|
||||||
setbufline({expr}, {lnum}, {text})
|
setbufline({expr}, {lnum}, {text})
|
||||||
Number set line {lnum} to {text} in buffer
|
Number set line {lnum} to {text} in buffer
|
||||||
@ -1974,7 +1961,7 @@ expand({string} [, {nosuf} [, {list}]]) *expand()*
|
|||||||
<cword> word under the cursor
|
<cword> word under the cursor
|
||||||
<cWORD> WORD under the cursor
|
<cWORD> WORD under the cursor
|
||||||
<client> the {clientid} of the last received
|
<client> the {clientid} of the last received
|
||||||
message |server2client()|
|
message
|
||||||
Modifiers:
|
Modifiers:
|
||||||
:p expand to full path
|
:p expand to full path
|
||||||
:h head (last path component removed)
|
:h head (last path component removed)
|
||||||
@ -2409,14 +2396,6 @@ foldtextresult({lnum}) *foldtextresult()*
|
|||||||
Can also be used as a |method|: >
|
Can also be used as a |method|: >
|
||||||
GetLnum()->foldtextresult()
|
GetLnum()->foldtextresult()
|
||||||
<
|
<
|
||||||
*foreground()*
|
|
||||||
foreground() Move the Vim window to the foreground. Useful when sent from
|
|
||||||
a client to a Vim server. |remote_send()|
|
|
||||||
On Win32 systems this might not work, the OS does not always
|
|
||||||
allow a window to bring itself to the foreground. Use
|
|
||||||
|remote_foreground()| instead.
|
|
||||||
{only in the Win32 GUI and console version}
|
|
||||||
|
|
||||||
fullcommand({name}) *fullcommand()*
|
fullcommand({name}) *fullcommand()*
|
||||||
Get the full command name from a short abbreviated command
|
Get the full command name from a short abbreviated command
|
||||||
name; see |20.2| for details on command abbreviations.
|
name; see |20.2| for details on command abbreviations.
|
||||||
@ -4280,6 +4259,15 @@ jobstart({cmd} [, {opts}]) *jobstart()*
|
|||||||
by CommandLineToArgvW https://msdn.microsoft.com/bb776391
|
by CommandLineToArgvW https://msdn.microsoft.com/bb776391
|
||||||
unless cmd[0] is some form of "cmd.exe".
|
unless cmd[0] is some form of "cmd.exe".
|
||||||
|
|
||||||
|
*jobstart-env*
|
||||||
|
The job environment is initialized as follows:
|
||||||
|
$NVIM is set to |v:servername| of the parent Nvim
|
||||||
|
$NVIM_LISTEN_ADDRESS is unset
|
||||||
|
$NVIM_LOG_FILE is unset
|
||||||
|
$VIM is unset
|
||||||
|
$VIMRUNTIME is unset
|
||||||
|
You can set these with the `env` option.
|
||||||
|
|
||||||
*jobstart-options*
|
*jobstart-options*
|
||||||
{opts} is a dictionary with these keys:
|
{opts} is a dictionary with these keys:
|
||||||
clear_env: (boolean) `env` defines the job environment
|
clear_env: (boolean) `env` defines the job environment
|
||||||
@ -4290,8 +4278,8 @@ jobstart({cmd} [, {opts}]) *jobstart()*
|
|||||||
killed when Nvim exits. If the process exits
|
killed when Nvim exits. If the process exits
|
||||||
before Nvim, `on_exit` will be invoked.
|
before Nvim, `on_exit` will be invoked.
|
||||||
env: (dict) Map of environment variable name:value
|
env: (dict) Map of environment variable name:value
|
||||||
pairs extending (or replacing if |clear_env|)
|
pairs extending (or replacing with |clear_env|)
|
||||||
the current environment.
|
the current environment. |jobstart-env|
|
||||||
height: (number) Height of the `pty` terminal.
|
height: (number) Height of the `pty` terminal.
|
||||||
|on_exit|: (function) Callback invoked when the job exits.
|
|on_exit|: (function) Callback invoked when the job exits.
|
||||||
|on_stdout|: (function) Callback invoked when the job emits
|
|on_stdout|: (function) Callback invoked when the job emits
|
||||||
@ -4305,8 +4293,8 @@ jobstart({cmd} [, {opts}]) *jobstart()*
|
|||||||
platforms, this option is silently ignored.)
|
platforms, this option is silently ignored.)
|
||||||
pty: (boolean) Connect the job to a new pseudo
|
pty: (boolean) Connect the job to a new pseudo
|
||||||
terminal, and its streams to the master file
|
terminal, and its streams to the master file
|
||||||
descriptor. Then `on_stderr` is ignored,
|
descriptor. `on_stdout` receives all output,
|
||||||
`on_stdout` receives all output.
|
`on_stderr` is ignored. |terminal-start|
|
||||||
rpc: (boolean) Use |msgpack-rpc| to communicate with
|
rpc: (boolean) Use |msgpack-rpc| to communicate with
|
||||||
the job over stdio. Then `on_stdout` is ignored,
|
the job over stdio. Then `on_stdout` is ignored,
|
||||||
but `on_stderr` can still be used.
|
but `on_stderr` can still be used.
|
||||||
@ -5242,9 +5230,8 @@ mode([expr]) Return a string that indicates the current mode.
|
|||||||
! Shell or external command is executing
|
! Shell or external command is executing
|
||||||
t Terminal mode: keys go to the job
|
t Terminal mode: keys go to the job
|
||||||
|
|
||||||
This is useful in the 'statusline' option or when used
|
This is useful in the 'statusline' option or RPC calls. In
|
||||||
with |remote_expr()| In most other places it always returns
|
most other places it always returns "c" or "n".
|
||||||
"c" or "n".
|
|
||||||
Note that in the future more modes and more specific modes may
|
Note that in the future more modes and more specific modes may
|
||||||
be added. It's better not to compare the whole string but only
|
be added. It's better not to compare the whole string but only
|
||||||
the leading character(s).
|
the leading character(s).
|
||||||
@ -5964,107 +5951,6 @@ reltimestr({time}) *reltimestr()*
|
|||||||
Can also be used as a |method|: >
|
Can also be used as a |method|: >
|
||||||
reltime(start)->reltimestr()
|
reltime(start)->reltimestr()
|
||||||
<
|
<
|
||||||
*remote_expr()* *E449*
|
|
||||||
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
|
|
||||||
Send the {string} to {server}. The {server} argument is a
|
|
||||||
string, also see |{server}|.
|
|
||||||
|
|
||||||
The string is sent as an expression and the result is returned
|
|
||||||
after evaluation. The result must be a String or a |List|. A
|
|
||||||
|List| is turned into a String by joining the items with a
|
|
||||||
line break in between (not at the end), like with join(expr,
|
|
||||||
"\n").
|
|
||||||
|
|
||||||
If {idvar} is present and not empty, it is taken as the name
|
|
||||||
of a variable and a {serverid} for later use with
|
|
||||||
|remote_read()| is stored there.
|
|
||||||
|
|
||||||
If {timeout} is given the read times out after this many
|
|
||||||
seconds. Otherwise a timeout of 600 seconds is used.
|
|
||||||
|
|
||||||
See also |clientserver| |RemoteReply|.
|
|
||||||
This function is not available in the |sandbox|.
|
|
||||||
Note: Any errors will cause a local error message to be issued
|
|
||||||
and the result will be the empty string.
|
|
||||||
|
|
||||||
Variables will be evaluated in the global namespace,
|
|
||||||
independent of a function currently being active. Except
|
|
||||||
when in debug mode, then local function variables and
|
|
||||||
arguments can be evaluated.
|
|
||||||
|
|
||||||
Examples: >
|
|
||||||
:echo remote_expr("gvim", "2+2")
|
|
||||||
:echo remote_expr("gvim1", "b:current_syntax")
|
|
||||||
<
|
|
||||||
|
|
||||||
remote_foreground({server}) *remote_foreground()*
|
|
||||||
Move the Vim server with the name {server} to the foreground.
|
|
||||||
The {server} argument is a string, also see |{server}|.
|
|
||||||
This works like: >
|
|
||||||
remote_expr({server}, "foreground()")
|
|
||||||
< Except that on Win32 systems the client does the work, to work
|
|
||||||
around the problem that the OS doesn't always allow the server
|
|
||||||
to bring itself to the foreground.
|
|
||||||
Note: This does not restore the window if it was minimized,
|
|
||||||
like foreground() does.
|
|
||||||
This function is not available in the |sandbox|.
|
|
||||||
{only in the Win32 GUI and the Win32 console version}
|
|
||||||
|
|
||||||
|
|
||||||
remote_peek({serverid} [, {retvar}]) *remote_peek()*
|
|
||||||
Returns a positive number if there are available strings
|
|
||||||
from {serverid}. Copies any reply string into the variable
|
|
||||||
{retvar} if specified. {retvar} must be a string with the
|
|
||||||
name of a variable.
|
|
||||||
Returns zero if none are available.
|
|
||||||
Returns -1 if something is wrong.
|
|
||||||
See also |clientserver|.
|
|
||||||
This function is not available in the |sandbox|.
|
|
||||||
Examples: >
|
|
||||||
:let repl = ""
|
|
||||||
:echo "PEEK: " .. remote_peek(id, "repl") .. ": " .. repl
|
|
||||||
|
|
||||||
remote_read({serverid}, [{timeout}]) *remote_read()*
|
|
||||||
Return the oldest available reply from {serverid} and consume
|
|
||||||
it. Unless a {timeout} in seconds is given, it blocks until a
|
|
||||||
reply is available.
|
|
||||||
See also |clientserver|.
|
|
||||||
This function is not available in the |sandbox|.
|
|
||||||
Example: >
|
|
||||||
:echo remote_read(id)
|
|
||||||
<
|
|
||||||
*remote_send()* *E241*
|
|
||||||
remote_send({server}, {string} [, {idvar}])
|
|
||||||
Send the {string} to {server}. The {server} argument is a
|
|
||||||
string, also see |{server}|.
|
|
||||||
|
|
||||||
The string is sent as input keys and the function returns
|
|
||||||
immediately. At the Vim server the keys are not mapped
|
|
||||||
|:map|.
|
|
||||||
|
|
||||||
If {idvar} is present, it is taken as the name of a variable
|
|
||||||
and a {serverid} for later use with remote_read() is stored
|
|
||||||
there.
|
|
||||||
|
|
||||||
See also |clientserver| |RemoteReply|.
|
|
||||||
This function is not available in the |sandbox|.
|
|
||||||
|
|
||||||
Note: Any errors will be reported in the server and may mess
|
|
||||||
up the display.
|
|
||||||
Examples: >
|
|
||||||
:echo remote_send("gvim", ":DropAndReply " .. file, "serverid") ..
|
|
||||||
\ remote_read(serverid)
|
|
||||||
|
|
||||||
:autocmd NONE RemoteReply *
|
|
||||||
\ echo remote_read(expand("<amatch>"))
|
|
||||||
:echo remote_send("gvim", ":sleep 10 | echo " ..
|
|
||||||
\ 'server2client(expand("<client>"), "HELLO")<CR>')
|
|
||||||
<
|
|
||||||
*remote_startserver()* *E941* *E942*
|
|
||||||
remote_startserver({name})
|
|
||||||
Become the server {name}. This fails if already running as a
|
|
||||||
server, when |v:servername| is not empty.
|
|
||||||
|
|
||||||
remove({list}, {idx} [, {end}]) *remove()*
|
remove({list}, {idx} [, {end}]) *remove()*
|
||||||
Without {end}: Remove the item at {idx} from |List| {list} and
|
Without {end}: Remove the item at {idx} from |List| {list} and
|
||||||
return the item.
|
return the item.
|
||||||
@ -6648,21 +6534,6 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])
|
|||||||
Can also be used as a |method|: >
|
Can also be used as a |method|: >
|
||||||
GetPattern()->searchpos()
|
GetPattern()->searchpos()
|
||||||
|
|
||||||
server2client({clientid}, {string}) *server2client()*
|
|
||||||
Send a reply string to {clientid}. The most recent {clientid}
|
|
||||||
that sent a string can be retrieved with expand("<client>").
|
|
||||||
Note:
|
|
||||||
Returns zero for success, -1 for failure.
|
|
||||||
This id has to be stored before the next command can be
|
|
||||||
received. I.e. before returning from the received command and
|
|
||||||
before calling any commands that waits for input.
|
|
||||||
See also |clientserver|.
|
|
||||||
Example: >
|
|
||||||
:echo server2client(expand("<client>"), "HELLO")
|
|
||||||
|
|
||||||
< Can also be used as a |method|: >
|
|
||||||
GetClientId()->server2client(string)
|
|
||||||
<
|
|
||||||
serverlist() *serverlist()*
|
serverlist() *serverlist()*
|
||||||
Returns a list of server addresses, or empty if all servers
|
Returns a list of server addresses, or empty if all servers
|
||||||
were stopped. |serverstart()| |serverstop()|
|
were stopped. |serverstart()| |serverstop()|
|
||||||
@ -6672,7 +6543,9 @@ serverlist() *serverlist()*
|
|||||||
serverstart([{address}]) *serverstart()*
|
serverstart([{address}]) *serverstart()*
|
||||||
Opens a socket or named pipe at {address} and listens for
|
Opens a socket or named pipe at {address} and listens for
|
||||||
|RPC| messages. Clients can send |API| commands to the address
|
|RPC| messages. Clients can send |API| commands to the address
|
||||||
to control Nvim. Returns the address string.
|
to control Nvim.
|
||||||
|
|
||||||
|
Returns the address string.
|
||||||
|
|
||||||
If {address} does not contain a colon ":" it is interpreted as
|
If {address} does not contain a colon ":" it is interpreted as
|
||||||
a named pipe or Unix domain socket path.
|
a named pipe or Unix domain socket path.
|
||||||
@ -6694,14 +6567,11 @@ serverstart([{address}]) *serverstart()*
|
|||||||
If no address is given, it is equivalent to: >
|
If no address is given, it is equivalent to: >
|
||||||
:call serverstart(tempname())
|
:call serverstart(tempname())
|
||||||
|
|
||||||
< |$NVIM_LISTEN_ADDRESS| is set to {address} if not already set.
|
|
||||||
|
|
||||||
serverstop({address}) *serverstop()*
|
serverstop({address}) *serverstop()*
|
||||||
Closes the pipe or socket at {address}.
|
Closes the pipe or socket at {address}.
|
||||||
Returns TRUE if {address} is valid, else FALSE.
|
Returns TRUE if {address} is valid, else FALSE.
|
||||||
If |$NVIM_LISTEN_ADDRESS| is stopped it is unset.
|
|
||||||
If |v:servername| is stopped it is set to the next available
|
If |v:servername| is stopped it is set to the next available
|
||||||
address returned by |serverlist()|.
|
address in |serverlist()|.
|
||||||
|
|
||||||
setbufline({buf}, {lnum}, {text}) *setbufline()*
|
setbufline({buf}, {lnum}, {text}) *setbufline()*
|
||||||
Set line {lnum} to {text} in buffer {buf}. This works like
|
Set line {lnum} to {text} in buffer {buf}. This works like
|
||||||
@ -8281,19 +8151,15 @@ tempname() *tempname()* *temp-file-name*
|
|||||||
|
|
||||||
termopen({cmd} [, {opts}]) *termopen()*
|
termopen({cmd} [, {opts}]) *termopen()*
|
||||||
Spawns {cmd} in a new pseudo-terminal session connected
|
Spawns {cmd} in a new pseudo-terminal session connected
|
||||||
to the current buffer. {cmd} is the same as the one passed to
|
to the current (unmodified) buffer. Parameters and behavior
|
||||||
|jobstart()|. This function fails if the current buffer is
|
are the same as |jobstart()| except "pty", "width", "height",
|
||||||
modified (all buffer contents are destroyed).
|
and "TERM" are ignored: "height" and "width" are taken from
|
||||||
|
the current window.
|
||||||
The {opts} dict is similar to the one passed to |jobstart()|,
|
|
||||||
but the `pty`, `width`, `height`, and `TERM` fields are
|
|
||||||
ignored: `height`/`width` are taken from the current window
|
|
||||||
and `$TERM` is set to "xterm-256color".
|
|
||||||
Returns the same values as |jobstart()|.
|
Returns the same values as |jobstart()|.
|
||||||
|
|
||||||
See |terminal| for more information.
|
Terminal environment is initialized as in ||jobstart-env|,
|
||||||
|
except $TERM is set to "xterm-256color". Full behavior is
|
||||||
test_ functions are documented here: |test-functions-details|
|
described in |terminal|.
|
||||||
|
|
||||||
tan({expr}) *tan()*
|
tan({expr}) *tan()*
|
||||||
Return the tangent of {expr}, measured in radians, as a |Float|
|
Return the tangent of {expr}, measured in radians, as a |Float|
|
||||||
|
@ -6,9 +6,8 @@
|
|||||||
|
|
||||||
Nvim *deprecated*
|
Nvim *deprecated*
|
||||||
|
|
||||||
The items listed below are "deprecated". This means they will be removed in
|
The items listed below are deprecated: they will be removed in the future.
|
||||||
the future. They should not be used in new scripts, and old scripts should be
|
They should not be used in new scripts, and old scripts should be updated.
|
||||||
updated.
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
@ -25,8 +24,12 @@ Commands ~
|
|||||||
*:wviminfo* Deprecated alias to |:wshada| command.
|
*:wviminfo* Deprecated alias to |:wshada| command.
|
||||||
|
|
||||||
Environment Variables ~
|
Environment Variables ~
|
||||||
*$NVIM_LISTEN_ADDRESS* Deprecated in favor of |--listen|. If both are given,
|
*$NVIM_LISTEN_ADDRESS* $NVIM_LISTEN_ADDRESS is a deprecated way to set the
|
||||||
$NVIM_LISTEN_ADDRESS is ignored.
|
|--listen| address of Nvim, and also had a conflicting
|
||||||
|
purpose as a way to detect a parent Nvim (use |$NVIM|
|
||||||
|
for that). It is unset by |terminal| and |jobstart()|
|
||||||
|
(unless explicitly given by the "env" option).
|
||||||
|
Ignored if --listen is given.
|
||||||
|
|
||||||
Events ~
|
Events ~
|
||||||
*BufCreate* Use |BufAdd| instead.
|
*BufCreate* Use |BufAdd| instead.
|
||||||
|
@ -2138,9 +2138,19 @@ v:scrollstart String describing the script or function that caused the
|
|||||||
*v:servername* *servername-variable*
|
*v:servername* *servername-variable*
|
||||||
v:servername Primary listen-address of the current Nvim instance, the first
|
v:servername Primary listen-address of the current Nvim instance, the first
|
||||||
item returned by |serverlist()|. Can be set by |--listen| or
|
item returned by |serverlist()|. Can be set by |--listen| or
|
||||||
|$NVIM_LISTEN_ADDRESS| at startup. |serverstart()| |serverstop()|
|
|$NVIM_LISTEN_ADDRESS| (deprecated) at startup.
|
||||||
|
See also |serverstart()| |serverstop()|.
|
||||||
Read-only.
|
Read-only.
|
||||||
|
|
||||||
|
*$NVIM*
|
||||||
|
$NVIM is set by |terminal| and |jobstart()|, and is thus
|
||||||
|
a hint that the current environment is a subprocess of Nvim.
|
||||||
|
Example: >
|
||||||
|
if $NVIM
|
||||||
|
echo nvim_get_chan_info(v:parent)
|
||||||
|
endif
|
||||||
|
|
||||||
|
< Note the contents of $NVIM may change in the future.
|
||||||
|
|
||||||
v:searchforward *v:searchforward* *searchforward-variable*
|
v:searchforward *v:searchforward* *searchforward-variable*
|
||||||
Search direction: 1 after a forward search, 0 after a
|
Search direction: 1 after a forward search, 0 after a
|
||||||
|
@ -25,23 +25,23 @@ Start *terminal-start*
|
|||||||
|
|
||||||
There are several ways to create a terminal buffer:
|
There are several ways to create a terminal buffer:
|
||||||
|
|
||||||
- Invoke the |:terminal| command.
|
- Run the |:terminal| command.
|
||||||
- Call the |termopen()| function.
|
- Call the |nvim_open_term()| or |termopen()| function.
|
||||||
- Edit a file with a name matching `term://(.{-}//(\d+:)?)?\zs.*`.
|
- Edit a "term://" buffer. Examples: >
|
||||||
For example:
|
|
||||||
>
|
|
||||||
:edit term://bash
|
:edit term://bash
|
||||||
:vsplit term://top
|
:vsplit term://top
|
||||||
<
|
|
||||||
Note: The "term://" pattern is handled by a BufReadCmd handler, so the
|
< Note: To open a "term://" buffer from an autocmd, the |autocmd-nested|
|
||||||
|autocmd-nested| modifier is required to use it in an autocmd. >
|
modifier is required. >
|
||||||
autocmd VimEnter * ++nested split term://sh
|
autocmd VimEnter * ++nested split term://sh
|
||||||
< This is only mentioned for reference; use |:terminal| instead.
|
< (This is only mentioned for reference; use |:terminal| instead.)
|
||||||
|
|
||||||
When the terminal starts, the buffer contents are updated and the buffer is
|
When the terminal starts, the buffer contents are updated and the buffer is
|
||||||
named in the form of `term://{cwd}//{pid}:{cmd}`. This naming scheme is used
|
named in the form of `term://{cwd}//{pid}:{cmd}`. This naming scheme is used
|
||||||
by |:mksession| to restore a terminal buffer (by restarting the {cmd}).
|
by |:mksession| to restore a terminal buffer (by restarting the {cmd}).
|
||||||
|
|
||||||
|
The terminal environment is initialized as in |jobstart-env|.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Input *terminal-input*
|
Input *terminal-input*
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ typedef enum {
|
|||||||
VV_ARGV,
|
VV_ARGV,
|
||||||
VV_COLLATE,
|
VV_COLLATE,
|
||||||
VV_EXITING,
|
VV_EXITING,
|
||||||
// Neovim
|
// Nvim
|
||||||
VV_STDERR,
|
VV_STDERR,
|
||||||
VV_MSGPACK_TYPES,
|
VV_MSGPACK_TYPES,
|
||||||
VV__NULL_STRING, // String with NULL value. For test purposes only.
|
VV__NULL_STRING, // String with NULL value. For test purposes only.
|
||||||
|
@ -5088,6 +5088,16 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
|
|||||||
tv_dict_add_str(env, S_LEN("TERM"), pty_term_name);
|
tv_dict_add_str(env, S_LEN("TERM"), pty_term_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set $NVIM (in the child process) to v:servername. #3118
|
||||||
|
char *nvim_addr = (char *)get_vim_var_str(VV_SEND_SERVER);
|
||||||
|
if (nvim_addr[0] != '\0') {
|
||||||
|
dictitem_T *dv = tv_dict_find(env, S_LEN("NVIM"));
|
||||||
|
if (dv) {
|
||||||
|
tv_dict_item_remove(env, dv);
|
||||||
|
}
|
||||||
|
tv_dict_add_str(env, S_LEN("NVIM"), nvim_addr);
|
||||||
|
}
|
||||||
|
|
||||||
if (job_env) {
|
if (job_env) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, {
|
TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, {
|
||||||
|
@ -1588,8 +1588,6 @@ varnumber_T tv_dict_get_number(const dict_T *const d, const char *const key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a dict to an environment
|
/// Converts a dict to an environment
|
||||||
///
|
|
||||||
///
|
|
||||||
char **tv_dict_to_env(dict_T *denv)
|
char **tv_dict_to_env(dict_T *denv)
|
||||||
{
|
{
|
||||||
size_t env_size = (size_t)tv_dict_len(denv);
|
size_t env_size = (size_t)tv_dict_len(denv);
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
|
||||||
#define MAX_CONNECTIONS 32
|
#define MAX_CONNECTIONS 32
|
||||||
#define LISTEN_ADDRESS_ENV_VAR "NVIM_LISTEN_ADDRESS"
|
#define ENV_LISTEN "NVIM_LISTEN_ADDRESS" // deprecated
|
||||||
|
#define ENV_NVIM "NVIM"
|
||||||
|
|
||||||
static garray_T watchers = GA_EMPTY_INIT_VALUE;
|
static garray_T watchers = GA_EMPTY_INIT_VALUE;
|
||||||
|
|
||||||
@ -35,20 +36,24 @@ bool server_init(const char *listen_addr)
|
|||||||
{
|
{
|
||||||
ga_init(&watchers, sizeof(SocketWatcher *), 1);
|
ga_init(&watchers, sizeof(SocketWatcher *), 1);
|
||||||
|
|
||||||
// $NVIM_LISTEN_ADDRESS
|
// $NVIM_LISTEN_ADDRESS (deprecated)
|
||||||
const char *env_addr = os_getenv(LISTEN_ADDRESS_ENV_VAR);
|
if (!listen_addr && os_env_exists(ENV_LISTEN)) {
|
||||||
int rv = listen_addr == NULL ? 1 : server_start(listen_addr);
|
listen_addr = os_getenv(ENV_LISTEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rv = listen_addr ? server_start(listen_addr) : 1;
|
||||||
if (0 != rv) {
|
if (0 != rv) {
|
||||||
rv = env_addr == NULL ? 1 : server_start(env_addr);
|
listen_addr = server_address_new();
|
||||||
if (0 != rv) {
|
if (!listen_addr) {
|
||||||
listen_addr = server_address_new();
|
return false;
|
||||||
if (listen_addr == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
rv = server_start(listen_addr);
|
|
||||||
xfree((char *)listen_addr);
|
|
||||||
}
|
}
|
||||||
|
rv = server_start(listen_addr);
|
||||||
|
xfree((char *)listen_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os_env_exists(ENV_LISTEN)) {
|
||||||
|
// Unset $NVIM_LISTEN_ADDRESS, it's a liability hereafter.
|
||||||
|
os_unsetenv(ENV_LISTEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv == 0;
|
return rv == 0;
|
||||||
@ -60,8 +65,8 @@ static void close_socket_watcher(SocketWatcher **watcher)
|
|||||||
socket_watcher_close(*watcher, free_server);
|
socket_watcher_close(*watcher, free_server);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set v:servername to the first server in the server list, or unset it if no
|
/// Sets the "primary address" (v:servername and $NVIM) to the first server in
|
||||||
/// servers are known.
|
/// the server list, or unsets if no servers are known.
|
||||||
static void set_vservername(garray_T *srvs)
|
static void set_vservername(garray_T *srvs)
|
||||||
{
|
{
|
||||||
char *default_server = (srvs->ga_len > 0)
|
char *default_server = (srvs->ga_len > 0)
|
||||||
@ -156,12 +161,6 @@ int server_start(const char *endpoint)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update $NVIM_LISTEN_ADDRESS, if not set.
|
|
||||||
const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
|
|
||||||
if (listen_address == NULL) {
|
|
||||||
os_setenv(LISTEN_ADDRESS_ENV_VAR, watcher->addr, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the watcher to the list.
|
// Add the watcher to the list.
|
||||||
ga_grow(&watchers, 1);
|
ga_grow(&watchers, 1);
|
||||||
((SocketWatcher **)watchers.ga_data)[watchers.ga_len++] = watcher;
|
((SocketWatcher **)watchers.ga_data)[watchers.ga_len++] = watcher;
|
||||||
@ -200,12 +199,6 @@ bool server_stop(char *endpoint)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unset $NVIM_LISTEN_ADDRESS if it is the stopped address.
|
|
||||||
const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
|
|
||||||
if (listen_address && STRCMP(addr, listen_address) == 0) {
|
|
||||||
os_unsetenv(LISTEN_ADDRESS_ENV_VAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_watcher_close(watcher, free_server);
|
socket_watcher_close(watcher, free_server);
|
||||||
|
|
||||||
// Remove this server from the list by swapping it with the last item.
|
// Remove this server from the list by swapping it with the last item.
|
||||||
@ -215,8 +208,8 @@ bool server_stop(char *endpoint)
|
|||||||
}
|
}
|
||||||
watchers.ga_len--;
|
watchers.ga_len--;
|
||||||
|
|
||||||
// If v:servername is the stopped address, re-initialize it.
|
// Bump v:servername to the next available server, if any.
|
||||||
if (STRCMP(addr, get_vim_var_str(VV_SEND_SERVER)) == 0) {
|
if (strequal(addr, (char *)get_vim_var_str(VV_SEND_SERVER))) {
|
||||||
set_vservername(&watchers);
|
set_vservername(&watchers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +179,13 @@ static void term_output_callback(const char *s, size_t len, void *user_data)
|
|||||||
|
|
||||||
// public API {{{
|
// public API {{{
|
||||||
|
|
||||||
|
/// Initializes terminal properties, and triggers TermOpen.
|
||||||
|
///
|
||||||
|
/// The PTY process (TerminalOptions.data) was already started by termopen(),
|
||||||
|
/// via ex_terminal() or the term:// BufReadCmd.
|
||||||
|
///
|
||||||
|
/// @param buf Buffer used for presentation of the terminal.
|
||||||
|
/// @param opts PTY process channel, various terminal properties and callbacks.
|
||||||
Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
|
Terminal *terminal_open(buf_T *buf, TerminalOptions opts)
|
||||||
{
|
{
|
||||||
// Create a new terminal instance and configure it
|
// Create a new terminal instance and configure it
|
||||||
@ -374,6 +381,7 @@ void terminal_check_size(Terminal *term)
|
|||||||
invalidate_terminal(term, -1, -1);
|
invalidate_terminal(term, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements TERM_FOCUS mode. :help Terminal-mode
|
||||||
void terminal_enter(void)
|
void terminal_enter(void)
|
||||||
{
|
{
|
||||||
buf_T *buf = curbuf;
|
buf_T *buf = curbuf;
|
||||||
@ -502,6 +510,7 @@ static int terminal_check(VimState *state)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Processes one char of terminal-mode input.
|
||||||
static int terminal_execute(VimState *state, int key)
|
static int terminal_execute(VimState *state, int key)
|
||||||
{
|
{
|
||||||
TerminalState *s = (TerminalState *)state;
|
TerminalState *s = (TerminalState *)state;
|
||||||
@ -1448,7 +1457,8 @@ static void refresh_terminal(Terminal *term)
|
|||||||
long ml_added = buf->b_ml.ml_line_count - ml_before;
|
long ml_added = buf->b_ml.ml_line_count - ml_before;
|
||||||
adjust_topline(term, buf, ml_added);
|
adjust_topline(term, buf, ml_added);
|
||||||
}
|
}
|
||||||
// Calls refresh_terminal() on all invalidated_terminals.
|
|
||||||
|
/// Calls refresh_terminal() on all invalidated_terminals.
|
||||||
static void refresh_timer_cb(TimeWatcher *watcher, void *data)
|
static void refresh_timer_cb(TimeWatcher *watcher, void *data)
|
||||||
{
|
{
|
||||||
refresh_pending = false;
|
refresh_pending = false;
|
||||||
|
@ -13,7 +13,7 @@ typedef void (*terminal_close_cb)(void *data);
|
|||||||
#include "nvim/buffer_defs.h"
|
#include "nvim/buffer_defs.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *data;
|
void *data; // PTY process channel
|
||||||
uint16_t width, height;
|
uint16_t width, height;
|
||||||
terminal_write_cb write_cb;
|
terminal_write_cb write_cb;
|
||||||
terminal_resize_cb resize_cb;
|
terminal_resize_cb resize_cb;
|
||||||
|
@ -16,6 +16,7 @@ local poke_eventloop = helpers.poke_eventloop
|
|||||||
local iswin = helpers.iswin
|
local iswin = helpers.iswin
|
||||||
local get_pathsep = helpers.get_pathsep
|
local get_pathsep = helpers.get_pathsep
|
||||||
local pathroot = helpers.pathroot
|
local pathroot = helpers.pathroot
|
||||||
|
local exec_lua = helpers.exec_lua
|
||||||
local nvim_set = helpers.nvim_set
|
local nvim_set = helpers.nvim_set
|
||||||
local expect_twostreams = helpers.expect_twostreams
|
local expect_twostreams = helpers.expect_twostreams
|
||||||
local expect_msg_seq = helpers.expect_msg_seq
|
local expect_msg_seq = helpers.expect_msg_seq
|
||||||
@ -208,7 +209,7 @@ describe('jobs', function()
|
|||||||
ok(string.find(err, "E475: Invalid argument: expected valid directory$") ~= nil)
|
ok(string.find(err, "E475: Invalid argument: expected valid directory$") ~= nil)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('produces error when using non-executable `cwd`', function()
|
it('error on non-executable `cwd`', function()
|
||||||
if iswin() then return end -- N/A for Windows
|
if iswin() then return end -- N/A for Windows
|
||||||
|
|
||||||
local dir = 'Xtest_not_executable_dir'
|
local dir = 'Xtest_not_executable_dir'
|
||||||
@ -249,7 +250,7 @@ describe('jobs', function()
|
|||||||
eq({'notification', 'exit', {0, 0}}, next_msg())
|
eq({'notification', 'exit', {0, 0}}, next_msg())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('allows interactive commands', function()
|
it('interactive commands', function()
|
||||||
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
|
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
|
||||||
neq(0, eval('j'))
|
neq(0, eval('j'))
|
||||||
nvim('command', 'call jobsend(j, "abc\\n")')
|
nvim('command', 'call jobsend(j, "abc\\n")')
|
||||||
@ -295,7 +296,7 @@ describe('jobs', function()
|
|||||||
nvim('command', "call jobstop(j)")
|
nvim('command', "call jobstop(j)")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("will not buffer data if it doesn't end in newlines", function()
|
it("emits partial lines (does NOT buffer data lacking newlines)", function()
|
||||||
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
|
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
|
||||||
nvim('command', 'call jobsend(j, "abc\\nxyz")')
|
nvim('command', 'call jobsend(j, "abc\\nxyz")')
|
||||||
eq({'notification', 'stdout', {0, {'abc', 'xyz'}}}, next_msg())
|
eq({'notification', 'stdout', {0, {'abc', 'xyz'}}}, next_msg())
|
||||||
@ -378,7 +379,7 @@ describe('jobs', function()
|
|||||||
eq(NIL, meths.get_proc(pid))
|
eq(NIL, meths.get_proc(pid))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("do not survive the exit of nvim", function()
|
it("disposed on Nvim exit", function()
|
||||||
-- use sleep, which doesn't die on stdin close
|
-- use sleep, which doesn't die on stdin close
|
||||||
nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)")
|
nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)")
|
||||||
local pid = eval('jobpid(g:j)')
|
local pid = eval('jobpid(g:j)')
|
||||||
@ -646,6 +647,43 @@ describe('jobs', function()
|
|||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('jobstart() environment: $NVIM, $NVIM_LISTEN_ADDRESS #11009', function()
|
||||||
|
local function get_env_in_child_job(envname, env)
|
||||||
|
return exec_lua([[
|
||||||
|
local envname, env = ...
|
||||||
|
local join = function(s) return vim.fn.join(s, '') end
|
||||||
|
local stdout = {}
|
||||||
|
local stderr = {}
|
||||||
|
local opt = {
|
||||||
|
env = env,
|
||||||
|
stdout_buffered = true,
|
||||||
|
stderr_buffered = true,
|
||||||
|
on_stderr = function(chan, data, name) stderr = data end,
|
||||||
|
on_stdout = function(chan, data, name) stdout = data end,
|
||||||
|
}
|
||||||
|
local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1',( '+echo "%s="..getenv("%s")'):format(envname, envname), '+qa!' }, opt)
|
||||||
|
vim.fn.jobwait({ j1 }, 10000)
|
||||||
|
return join({ join(stdout), join(stderr) })
|
||||||
|
]],
|
||||||
|
envname,
|
||||||
|
env)
|
||||||
|
end
|
||||||
|
|
||||||
|
local addr = eval('v:servername')
|
||||||
|
ok((addr):len() > 0)
|
||||||
|
-- $NVIM is _not_ defined in the top-level Nvim process.
|
||||||
|
eq('', eval('$NVIM'))
|
||||||
|
-- jobstart() shares its v:servername with the child via $NVIM.
|
||||||
|
eq('NVIM='..addr, get_env_in_child_job('NVIM'))
|
||||||
|
-- $NVIM_LISTEN_ADDRESS is unset by server_init in the child.
|
||||||
|
eq('NVIM_LISTEN_ADDRESS=null', get_env_in_child_job('NVIM_LISTEN_ADDRESS'))
|
||||||
|
eq('NVIM_LISTEN_ADDRESS=null', get_env_in_child_job('NVIM_LISTEN_ADDRESS',
|
||||||
|
{ NVIM_LISTEN_ADDRESS='Xtest_jobstart_env' }))
|
||||||
|
-- User can explicitly set $NVIM_LOG_FILE, $VIM, $VIMRUNTIME.
|
||||||
|
eq('NVIM_LOG_FILE=Xtest_jobstart_env',
|
||||||
|
get_env_in_child_job('NVIM_LOG_FILE', { NVIM_LOG_FILE='Xtest_jobstart_env' }))
|
||||||
|
end)
|
||||||
|
|
||||||
describe('jobwait', function()
|
describe('jobwait', function()
|
||||||
before_each(function()
|
before_each(function()
|
||||||
if iswin() then
|
if iswin() then
|
||||||
|
@ -782,7 +782,7 @@ function module.pathroot()
|
|||||||
return iswin() and (module.nvim_dir:sub(1,2)..pathsep) or '/'
|
return iswin() and (module.nvim_dir:sub(1,2)..pathsep) or '/'
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a valid, platform-independent $NVIM_LISTEN_ADDRESS.
|
-- Returns a valid, platform-independent Nvim listen address.
|
||||||
-- Useful for communicating with child instances.
|
-- Useful for communicating with child instances.
|
||||||
function module.new_pipename()
|
function module.new_pipename()
|
||||||
-- HACK: Start a server temporarily, get the name, then stop it.
|
-- HACK: Start a server temporarily, get the name, then stop it.
|
||||||
|
@ -29,7 +29,7 @@ describe('nodejs host', function()
|
|||||||
local fname = 'Xtest-nodejs-hello.js'
|
local fname = 'Xtest-nodejs-hello.js'
|
||||||
write_file(fname, [[
|
write_file(fname, [[
|
||||||
const neovim = require('neovim');
|
const neovim = require('neovim');
|
||||||
const nvim = neovim.attach({socket: process.env.NVIM_LISTEN_ADDRESS});
|
const nvim = neovim.attach({socket: process.env.NVIM});
|
||||||
nvim.command('let g:job_out = "hello"');
|
nvim.command('let g:job_out = "hello"');
|
||||||
]])
|
]])
|
||||||
command('let g:job_id = jobstart(["node", "'..fname..'"])')
|
command('let g:job_id = jobstart(["node", "'..fname..'"])')
|
||||||
@ -39,7 +39,7 @@ describe('nodejs host', function()
|
|||||||
local fname = 'Xtest-nodejs-hello-plugin.js'
|
local fname = 'Xtest-nodejs-hello-plugin.js'
|
||||||
write_file(fname, [[
|
write_file(fname, [[
|
||||||
const neovim = require('neovim');
|
const neovim = require('neovim');
|
||||||
const nvim = neovim.attach({socket: process.env.NVIM_LISTEN_ADDRESS});
|
const nvim = neovim.attach({socket: process.env.NVIM});
|
||||||
|
|
||||||
class TestPlugin {
|
class TestPlugin {
|
||||||
hello() {
|
hello() {
|
||||||
|
@ -83,7 +83,7 @@ describe('perl provider', function()
|
|||||||
use Neovim::Ext;
|
use Neovim::Ext;
|
||||||
use Neovim::Ext::MsgPack::RPC;
|
use Neovim::Ext::MsgPack::RPC;
|
||||||
|
|
||||||
my $session = Neovim::Ext::MsgPack::RPC::socket_session($ENV{NVIM_LISTEN_ADDRESS});
|
my $session = Neovim::Ext::MsgPack::RPC::socket_session($ENV{NVIM});
|
||||||
my $nvim = Neovim::Ext::from_session($session);
|
my $nvim = Neovim::Ext::from_session($session);
|
||||||
$nvim->command('let g:job_out = "hello"');
|
$nvim->command('let g:job_out = "hello"');
|
||||||
1;
|
1;
|
||||||
@ -116,7 +116,7 @@ describe('perl provider', function()
|
|||||||
use Neovim::Ext;
|
use Neovim::Ext;
|
||||||
use Neovim::Ext::MsgPack::RPC;
|
use Neovim::Ext::MsgPack::RPC;
|
||||||
|
|
||||||
my $session = Neovim::Ext::MsgPack::RPC::socket_session($ENV{NVIM_LISTEN_ADDRESS});
|
my $session = Neovim::Ext::MsgPack::RPC::socket_session($ENV{NVIM});
|
||||||
my $nvim = Neovim::Ext::from_session($session);
|
my $nvim = Neovim::Ext::from_session($session);
|
||||||
my $plugin = TestPlugin->new($nvim);
|
my $plugin = TestPlugin->new($nvim);
|
||||||
$plugin->test_command();
|
$plugin->test_command();
|
||||||
|
@ -75,7 +75,7 @@ local busted = require('busted')
|
|||||||
local deepcopy = helpers.deepcopy
|
local deepcopy = helpers.deepcopy
|
||||||
local shallowcopy = helpers.shallowcopy
|
local shallowcopy = helpers.shallowcopy
|
||||||
local concat_tables = helpers.concat_tables
|
local concat_tables = helpers.concat_tables
|
||||||
local request, run_session = helpers.request, helpers.run_session
|
local run_session = helpers.run_session
|
||||||
local eq = helpers.eq
|
local eq = helpers.eq
|
||||||
local dedent = helpers.dedent
|
local dedent = helpers.dedent
|
||||||
local get_session = helpers.get_session
|
local get_session = helpers.get_session
|
||||||
@ -90,8 +90,6 @@ end
|
|||||||
local Screen = {}
|
local Screen = {}
|
||||||
Screen.__index = Screen
|
Screen.__index = Screen
|
||||||
|
|
||||||
local debug_screen
|
|
||||||
|
|
||||||
local default_timeout_factor = 1
|
local default_timeout_factor = 1
|
||||||
if os.getenv('VALGRIND') then
|
if os.getenv('VALGRIND') then
|
||||||
default_timeout_factor = default_timeout_factor * 3
|
default_timeout_factor = default_timeout_factor * 3
|
||||||
@ -123,18 +121,6 @@ do
|
|||||||
Screen.colornames = colornames
|
Screen.colornames = colornames
|
||||||
end
|
end
|
||||||
|
|
||||||
function Screen.debug(command)
|
|
||||||
if not command then
|
|
||||||
command = 'pynvim -n -c '
|
|
||||||
end
|
|
||||||
command = command .. request('vim_eval', '$NVIM_LISTEN_ADDRESS')
|
|
||||||
if debug_screen then
|
|
||||||
debug_screen:close()
|
|
||||||
end
|
|
||||||
debug_screen = io.popen(command, 'r')
|
|
||||||
debug_screen:read()
|
|
||||||
end
|
|
||||||
|
|
||||||
function Screen.new(width, height)
|
function Screen.new(width, height)
|
||||||
if not width then
|
if not width then
|
||||||
width = 53
|
width = 53
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
local helpers = require('test.functional.helpers')(after_each)
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
|
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
|
||||||
local command = helpers.command
|
|
||||||
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
|
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
|
||||||
local iswin = helpers.iswin
|
local iswin = helpers.iswin
|
||||||
local ok = helpers.ok
|
local ok = helpers.ok
|
||||||
@ -16,27 +15,25 @@ end
|
|||||||
describe('server', function()
|
describe('server', function()
|
||||||
before_each(clear)
|
before_each(clear)
|
||||||
|
|
||||||
it('serverstart() sets $NVIM_LISTEN_ADDRESS on first invocation', function()
|
it('serverstart(), serverstop() does not set $NVIM', function()
|
||||||
-- Unset $NVIM_LISTEN_ADDRESS
|
|
||||||
command('let $NVIM_LISTEN_ADDRESS = ""')
|
|
||||||
|
|
||||||
local s = eval('serverstart()')
|
local s = eval('serverstart()')
|
||||||
assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
|
assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
|
||||||
eq(s, eval('$NVIM_LISTEN_ADDRESS'))
|
eq('', eval('$NVIM'))
|
||||||
|
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
||||||
eq(1, eval("serverstop('"..s.."')"))
|
eq(1, eval("serverstop('"..s.."')"))
|
||||||
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function()
|
it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function()
|
||||||
clear({env={NVIM_LISTEN_ADDRESS='.'}})
|
clear({env={NVIM_LISTEN_ADDRESS='.'}})
|
||||||
eq('.', eval('$NVIM_LISTEN_ADDRESS'))
|
-- Cleared on startup.
|
||||||
|
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
||||||
local servers = funcs.serverlist()
|
local servers = funcs.serverlist()
|
||||||
eq(1, #servers)
|
eq(1, #servers)
|
||||||
ok(string.len(servers[1]) > 4) -- Like /tmp/nvim…/… or \\.\pipe\…
|
ok(string.len(servers[1]) > 4) -- Like /tmp/nvim…/… or \\.\pipe\…
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('sets v:servername at startup or if all servers were stopped',
|
it('sets v:servername at startup or if all servers were stopped', function()
|
||||||
function()
|
|
||||||
local initial_server = meths.get_vvar('servername')
|
local initial_server = meths.get_vvar('servername')
|
||||||
assert(initial_server ~= nil and initial_server:len() > 0,
|
assert(initial_server ~= nil and initial_server:len() > 0,
|
||||||
'v:servername was not initialized')
|
'v:servername was not initialized')
|
||||||
@ -55,11 +52,13 @@ describe('server', function()
|
|||||||
eq(1, funcs.serverstop(funcs.serverlist()[1]))
|
eq(1, funcs.serverstop(funcs.serverlist()[1]))
|
||||||
eq('', meths.get_vvar('servername'))
|
eq('', meths.get_vvar('servername'))
|
||||||
|
|
||||||
-- v:servername will take the next available server.
|
-- v:servername and $NVIM take the next available server.
|
||||||
local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
|
local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
|
||||||
or 'Xtest-functional-server-socket')
|
or 'Xtest-functional-server-socket')
|
||||||
funcs.serverstart(servername)
|
funcs.serverstart(servername)
|
||||||
eq(servername, meths.get_vvar('servername'))
|
eq(servername, meths.get_vvar('servername'))
|
||||||
|
-- Not set in the current process, only in children.
|
||||||
|
eq('', eval('$NVIM'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('serverstop() returns false for invalid input', function()
|
it('serverstop() returns false for invalid input', function()
|
||||||
@ -136,7 +135,6 @@ end)
|
|||||||
describe('startup --listen', function()
|
describe('startup --listen', function()
|
||||||
it('validates', function()
|
it('validates', function()
|
||||||
clear()
|
clear()
|
||||||
|
|
||||||
local cmd = { unpack(helpers.nvim_argv) }
|
local cmd = { unpack(helpers.nvim_argv) }
|
||||||
table.insert(cmd, '--listen')
|
table.insert(cmd, '--listen')
|
||||||
matches('nvim.*: Argument missing after: "%-%-listen"', funcs.system(cmd))
|
matches('nvim.*: Argument missing after: "%-%-listen"', funcs.system(cmd))
|
||||||
|
Loading…
Reference in New Issue
Block a user