[Backport release-0.7] introduce $NVIM, unset $NVIM_LISTEN_ADDRESS (#18986)

feat(server): introduce $NVIM

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

(cherry picked from commit b9d97f5951)

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
This commit is contained in:
github-actions[bot]
2022-06-16 18:30:08 -07:00
committed by GitHub
parent ed9e6d19ab
commit fdd5178581
17 changed files with 157 additions and 245 deletions

View File

@@ -1,6 +1,5 @@
local helpers = require('test.functional.helpers')(after_each)
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 iswin = helpers.iswin
local ok = helpers.ok
@@ -16,27 +15,25 @@ end
describe('server', function()
before_each(clear)
it('serverstart() sets $NVIM_LISTEN_ADDRESS on first invocation', function()
-- Unset $NVIM_LISTEN_ADDRESS
command('let $NVIM_LISTEN_ADDRESS = ""')
it('serverstart(), serverstop() does not set $NVIM', function()
local s = eval('serverstart()')
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('', eval('$NVIM_LISTEN_ADDRESS'))
end)
it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function()
clear({env={NVIM_LISTEN_ADDRESS='.'}})
eq('.', eval('$NVIM_LISTEN_ADDRESS'))
-- Cleared on startup.
eq('', eval('$NVIM_LISTEN_ADDRESS'))
local servers = funcs.serverlist()
eq(1, #servers)
ok(string.len(servers[1]) > 4) -- Like /tmp/nvim…/… or \\.\pipe\…
end)
it('sets v:servername at startup or if all servers were stopped',
function()
it('sets v:servername at startup or if all servers were stopped', function()
local initial_server = meths.get_vvar('servername')
assert(initial_server ~= nil and initial_server:len() > 0,
'v:servername was not initialized')
@@ -55,11 +52,13 @@ describe('server', function()
eq(1, funcs.serverstop(funcs.serverlist()[1]))
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]]
or 'Xtest-functional-server-socket')
funcs.serverstart(servername)
eq(servername, meths.get_vvar('servername'))
-- Not set in the current process, only in children.
eq('', eval('$NVIM'))
end)
it('serverstop() returns false for invalid input', function()
@@ -136,7 +135,6 @@ end)
describe('startup --listen', function()
it('validates', function()
clear()
local cmd = { unpack(helpers.nvim_argv) }
table.insert(cmd, '--listen')
matches('nvim.*: Argument missing after: "%-%-listen"', funcs.system(cmd))