diff options
Diffstat (limited to 'src/nvim/ex_docmd.c')
| -rw-r--r-- | src/nvim/ex_docmd.c | 48 |
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); |
