mirror of
https://github.com/neovim/neovim.git
synced 2026-04-14 03:26:10 +00:00
fix(:restart): only pass --headless when there is no UI (#38580)
Change --embed so that the first UI can be on non-stdio channel even if
neither --headless nor --listen is passed.
(cherry picked from commit a3a48392c5)
This commit is contained in:
committed by
github-actions[bot]
parent
d83141c0f2
commit
8b3f3113c4
@@ -120,23 +120,9 @@ void remote_ui_free_all_mem(void)
|
||||
#endif
|
||||
|
||||
/// Wait until UI has connected.
|
||||
///
|
||||
/// @param only_stdio UI is expected to connect on stdio.
|
||||
void remote_ui_wait_for_attach(bool only_stdio)
|
||||
void remote_ui_wait_for_attach(void)
|
||||
{
|
||||
if (only_stdio) {
|
||||
Channel *channel = find_channel(CHAN_STDIO);
|
||||
if (!channel) {
|
||||
// `only_stdio` implies --embed mode, thus stdio channel can be assumed.
|
||||
abort();
|
||||
}
|
||||
|
||||
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1,
|
||||
map_has(uint64_t, &connected_uis, CHAN_STDIO));
|
||||
} else {
|
||||
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, -1,
|
||||
ui_active());
|
||||
}
|
||||
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, -1, ui_active());
|
||||
}
|
||||
|
||||
/// Activates UI events on the channel.
|
||||
|
||||
@@ -4963,6 +4963,7 @@ static void ex_quitall(exarg_T *eap)
|
||||
static void ex_restart(exarg_T *eap)
|
||||
{
|
||||
Error err = ERROR_INIT;
|
||||
const bool no_ui = !ui_active();
|
||||
const char *exepath = get_vim_var_str(VV_PROGPATH);
|
||||
const list_T *l = get_vim_var_list(VV_ARGV);
|
||||
int argc = tv_list_len(l);
|
||||
@@ -4996,14 +4997,18 @@ static void ex_restart(exarg_T *eap)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Replace `--embed` OR `--headless` with `--embed --headless` once.
|
||||
// Replace `--embed` OR `--headless` with `--embed` or `--embed --headless` once.
|
||||
// Drop stdin ("-") argument.
|
||||
if (i == 0
|
||||
|| (!strequal(arg, "--embed") && !strequal(arg, "--headless") && !strequal(arg, "-"))) {
|
||||
argv[i++] = xstrdup(arg);
|
||||
if (i == 1) {
|
||||
argv[i++] = xstrdup("--embed");
|
||||
argv[i++] = xstrdup("--headless");
|
||||
// Without --headless, embed waits for UI to attach.
|
||||
// Only add --headless when there is no UI.
|
||||
if (no_ui) {
|
||||
argv[i++] = xstrdup("--headless");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -5075,7 +5080,7 @@ static void ex_restart(exarg_T *eap)
|
||||
result_mem = NULL;
|
||||
|
||||
// Send restart event with new listen address to current UI.
|
||||
if (!remote_ui_restart(current_ui, listen_addr, &err)) {
|
||||
if (!no_ui && !remote_ui_restart(current_ui, listen_addr, &err)) {
|
||||
if (ERROR_SET(&err)) {
|
||||
ELOG("%s", err.msg); // UI disappeared already?
|
||||
api_clear_error(&err);
|
||||
|
||||
@@ -436,10 +436,9 @@ int main(int argc, char **argv)
|
||||
// Wait for UIs to set up Nvim or show early messages
|
||||
// and prompts (--cmd, swapfile dialog, …).
|
||||
bool use_remote_ui = (embedded_mode && !headless_mode);
|
||||
bool listen_and_embed = params.listen_addr != NULL;
|
||||
if (use_remote_ui) {
|
||||
TIME_MSG("waiting for UI");
|
||||
remote_ui_wait_for_attach(!listen_and_embed);
|
||||
remote_ui_wait_for_attach();
|
||||
TIME_MSG("done waiting for UI");
|
||||
firstwin->w_prev_height = firstwin->w_height; // may have changed
|
||||
}
|
||||
|
||||
@@ -351,3 +351,31 @@ describe('startup --listen', function()
|
||||
matches([[[/\\]test%-name[^/\\]*]], api.nvim_get_vvar('servername'))
|
||||
end)
|
||||
end)
|
||||
|
||||
it(':restart works in headless server (no UI)', function()
|
||||
t.skip(is_os('win'), 'FIXME: --listen not preserved by :restart on Windows')
|
||||
|
||||
local nvim0 = clear()
|
||||
local server_pipe = n.new_pipename()
|
||||
|
||||
finally(function()
|
||||
n.expect_exit(n.command, 'qall!')
|
||||
nvim0:close()
|
||||
n.set_session(nil)
|
||||
end)
|
||||
|
||||
fn.jobstart({ n.nvim_prog, '--clean', '--headless', '--listen', server_pipe })
|
||||
t.retry(nil, nil, function()
|
||||
neq(nil, vim.uv.fs_stat(server_pipe))
|
||||
end)
|
||||
n.set_session(n.connect(server_pipe))
|
||||
|
||||
n.expect_exit(n.command, 'restart')
|
||||
n.set_session(n.connect(server_pipe))
|
||||
eq(1, api.nvim_get_vvar('vim_did_enter'))
|
||||
|
||||
-- TODO: [command] is currently not executed without UI
|
||||
-- n.expect_exit(n.command, 'restart lua _G.new_server = 1')
|
||||
-- n.set_session(n.connect(server_pipe))
|
||||
-- eq(1, n.exec_lua('return _G.new_server'))
|
||||
end)
|
||||
|
||||
@@ -466,7 +466,7 @@ describe('TUI :restart', function()
|
||||
screen:expect({ any = vim.pesc('[Process exited 0]') })
|
||||
end)
|
||||
|
||||
it('autocommands are triggered by [command] properly #38549', function()
|
||||
it('[command] triggers autocommands properly #38549', function()
|
||||
local screen = tt.setup_child_nvim({
|
||||
'--clean',
|
||||
'--cmd',
|
||||
@@ -497,6 +497,80 @@ describe('TUI :restart', function()
|
||||
feed_data(':qall!\r')
|
||||
screen:expect({ any = vim.pesc('[Process exited 0]') })
|
||||
end)
|
||||
|
||||
it('new server loads user config after old server exits #38569', function()
|
||||
local config_file = 'Xrestart_session_config.lua'
|
||||
local session_file = 'Xrestart_session.vim'
|
||||
write_file(
|
||||
config_file,
|
||||
([[
|
||||
vim.api.nvim_create_autocmd("VimLeavePre", {
|
||||
callback = function()
|
||||
vim.cmd('mksession! %s')
|
||||
end,
|
||||
})
|
||||
|
||||
if vim.v.vim_did_enter and vim.uv.fs_stat('%s') then
|
||||
vim.cmd('source %s')
|
||||
end
|
||||
]]):format(session_file, session_file, session_file)
|
||||
)
|
||||
finally(function()
|
||||
os.remove(config_file)
|
||||
os.remove(session_file)
|
||||
end)
|
||||
|
||||
local screen = tt.setup_child_nvim({
|
||||
'--clean',
|
||||
'-u',
|
||||
config_file,
|
||||
'--cmd',
|
||||
'set notermguicolors noswapfile laststatus=0 nowrap noruler',
|
||||
}, { env = env_notermguicolors })
|
||||
screen:expect([[
|
||||
^ |
|
||||
~ |*4
|
||||
|
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed_data(':rightbelow 28vsplit test/functional/fixtures/bigfile.txt\r')
|
||||
screen:expect([[
|
||||
│^0000;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0001;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0002;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0003;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0004;<control>;Cc;0;BN;;;;;N|
|
||||
|
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed_data(':restart echo "restarted"\r')
|
||||
screen:expect([[
|
||||
^ │0000;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0001;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0002;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0003;<control>;Cc;0;BN;;;;;N|
|
||||
~ │0004;<control>;Cc;0;BN;;;;;N|
|
||||
restarted |
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
feed_data(':set sessionoptions-=winsize | restart\r')
|
||||
screen:expect([[
|
||||
^ │0000;<control>;Cc;0;BN;;|
|
||||
~ │0001;<control>;Cc;0;BN;;|
|
||||
~ │0002;<control>;Cc;0;BN;;|
|
||||
~ │0003;<control>;Cc;0;BN;;|
|
||||
~ │0004;<control>;Cc;0;BN;;|
|
||||
|
|
||||
{5:-- TERMINAL --} |
|
||||
]])
|
||||
|
||||
-- The server is now detached and needs to be quit explicitly.
|
||||
feed_data(':qall!\r')
|
||||
screen:expect({ any = vim.pesc('[Process exited 0]') })
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('TUI :connect', function()
|
||||
|
||||
Reference in New Issue
Block a user