summaryrefslogtreecommitdiffstatshomepage
path: root/src/nvim/ex_docmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r--src/nvim/ex_docmd.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 1a29a61d22..0737e31642 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4818,10 +4818,15 @@ static void ex_highlight(exarg_T *eap)
void not_exiting(bool save_exiting)
{
exiting = save_exiting;
+ set_vim_var_string(VV_EXITREASON, NULL, -1);
}
bool before_quit_autocmds(win_T *wp, bool quit_all, bool forceit)
{
+ // Set v:exitreason if not already set (e.g. by :restart).
+ if (*get_vim_var_str(VV_EXITREASON) == NUL) {
+ set_vim_var_string(VV_EXITREASON, S_LEN("quit"));
+ }
apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, wp->w_buffer);
// Bail out when autocommands closed the window.
@@ -4830,6 +4835,7 @@ bool before_quit_autocmds(win_T *wp, bool quit_all, bool forceit)
if (!win_valid(wp)
|| curbuf_locked()
|| (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) {
+ set_vim_var_string(VV_EXITREASON, NULL, -1);
return true;
}
@@ -4842,6 +4848,7 @@ bool before_quit_autocmds(win_T *wp, bool quit_all, bool forceit)
if (!win_valid(wp)
|| curbuf_locked()
|| (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) {
+ set_vim_var_string(VV_EXITREASON, NULL, -1);
return true;
}
}
@@ -4976,15 +4983,10 @@ static void ex_restart(exarg_T *eap)
char **argv = xcalloc((size_t)argc + 3, sizeof(char *));
size_t i = 0;
- const char *listen_arg = NULL;
-#ifdef MSWIN
- // On Windows, don't pass --listen to new server (named pipe can't be reused immediately).
- // Instead pass the address via RPC, and new server will rebind to it after startup.
-# define HANDLE_LISTEN_ADDR listen_arg = addr; li = next_li; continue
-#else
-# define HANDLE_LISTEN_ADDR listen_arg = addr
-#endif
- TV_LIST_ITER_CONST(l, li, {
+ const char *listen_arg = NULL; // --listen arg given by user, if any.
+
+ // Build args to start the new Nvim, based on the current v:argv.
+ for (const listitem_T *li = l->lv_first; li != NULL; li = li->li_next) {
const char *arg = tv_get_string(TV_LIST_ITEM_TV(li));
// Drop "-- [files…]". Usually isn't wanted. User can :mksession instead.
if (i > 0 && strequal(arg, "--")) {
@@ -4992,16 +4994,22 @@ static void ex_restart(exarg_T *eap)
}
// Drop "-s <scriptfile>": skip the scriptfile arg too.
if (i > 0 && strequal(arg, "-s")) {
- li = TV_LIST_ITEM_NEXT(l, li);
+ li = li->li_next;
continue;
}
// The address after --listen may be in use by the current server.
if (i > 0 && strequal(arg, "--listen")) {
- listitem_T *next_li = TV_LIST_ITEM_NEXT(l, li);
+ const listitem_T *next_li = li->li_next;
if (next_li != NULL) {
const char *addr = tv_get_string(TV_LIST_ITEM_TV(next_li));
if (strstr(addr, ":") || strstr(addr, "/") || strstr(addr, "\\")) {
- HANDLE_LISTEN_ADDR;
+ listen_arg = addr;
+#ifdef MSWIN
+ // On Windows, don't pass --listen to new server (named pipe can't be reused immediately).
+ // Instead pass the address via RPC; new server rebinds after startup.
+ li = next_li;
+ continue;
+#endif
}
}
}
@@ -5019,12 +5027,11 @@ static void ex_restart(exarg_T *eap)
}
}
}
- });
-#undef HANDLE_LISTEN_ADDR
+ }
#ifdef MSWIN
// On Windows, --listen is omitted from child argv because the named pipe can't be reused immediately.
- // Recover the canonical address from the Lua module state (set by the previous rebind_old_addr_after_restart() call),
+ // Recover the canonical address from the Lua module state (set by the previous rebind_after_restart() call),
// and keep the current listener alive (new server reclaims it).
char *listen_arg_alloc = NULL;
if (listen_arg == NULL) {
@@ -5104,8 +5111,7 @@ static void ex_restart(exarg_T *eap)
result_mem = NULL;
}
- // Get the new server's initial listen address. On Windows this is the
- // temporary bootstrap address that UIs should reconnect to first.
+ // Get the new server's initial address. On Windows this is the temporary self-generated address.
MAXSIZE_TEMP_ARRAY(servername_args, 1);
ADD_C(servername_args, CSTR_AS_OBJ("servername"));
Object result = rpc_send_call(channel->id, "nvim_get_vvar", servername_args, &result_mem, &err);
@@ -5116,6 +5122,7 @@ static void ex_restart(exarg_T *eap)
emsg("restart failed: could not get listen address from new server");
goto fail_2;
}
+ // New server's self-generated address.
char *listen_addr = xmemdupz(result.data.string.data, result.data.string.size);
arena_mem_free(result_mem);
result_mem = NULL;
@@ -5126,10 +5133,9 @@ static void ex_restart(exarg_T *eap)
// then retire the bootstrap address after all UIs have reattached (or timeout).
MAXSIZE_TEMP_ARRAY(lua_args, 2);
ADD_C(lua_args,
- CSTR_AS_OBJ("return require('vim._core.server').rebind_old_addr_after_restart(...)"));
+ CSTR_AS_OBJ("return require('vim._core.server').rebind_after_restart(...)"));
MAXSIZE_TEMP_ARRAY(handoff_params, 3);
ADD_C(handoff_params, CSTR_AS_OBJ(listen_arg));
- ADD_C(handoff_params, CSTR_AS_OBJ(listen_addr));
ADD_C(handoff_params, INTEGER_OBJ((Integer)ui_active()));
ADD_C(lua_args, ARRAY_OBJ(handoff_params));
rpc_send_call(channel->id, "nvim_exec_lua", lua_args, &result_mem, &err);
@@ -5146,6 +5152,8 @@ static void ex_restart(exarg_T *eap)
ui_flush();
xfree(listen_addr);
+ set_vim_var_string(VV_EXITREASON, S_LEN("restart"));
+
char *quit_cmd = (eap->do_ecmd_cmd) ? eap->do_ecmd_cmd : "qall";
char *quit_cmd_copy = NULL;
@@ -5154,6 +5162,7 @@ static void ex_restart(exarg_T *eap)
quit_cmd_copy = concat_str("confirm ", quit_cmd);
quit_cmd = quit_cmd_copy;
}
+ // Try to quit.
nvim_command(cstr_as_string(quit_cmd), &err);
xfree(quit_cmd_copy);
@@ -5165,6 +5174,7 @@ static void ex_restart(exarg_T *eap)
}
fail_2:
+ set_vim_var_string(VV_EXITREASON, NULL, -1);
if (ERROR_SET(&err)) {
emsg(err.msg);
api_clear_error(&err);