feat: ":restart +cmd" #34788

Problem:
":restart" always executes ":qall" to exit the server.

Solution:
Support ":restart +cmd" so the user can control the command
used to exit the server.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This commit is contained in:
Sathya Pramodh
2025-07-24 08:15:31 +05:30
committed by GitHub
parent 0dcdd65dcc
commit 54b8c99e51
6 changed files with 77 additions and 35 deletions

View File

@@ -15,6 +15,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/ui.h"
#include "nvim/api/vimscript.h"
#include "nvim/arglist.h"
#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
@@ -4700,6 +4701,13 @@ void not_exiting(void)
exiting = false;
}
/// Call this function if we thought we were going to restart, but we won't
/// (because of an error).
void not_restarting(void)
{
restarting = false;
}
bool before_quit_autocmds(win_T *wp, bool quit_all, bool forceit)
{
apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, wp->w_buffer);
@@ -4829,22 +4837,39 @@ int before_quit_all(exarg_T *eap)
}
/// ":qall": try to quit all windows
/// ":restart": restart the Nvim server
static void ex_quitall_or_restart(exarg_T *eap)
static void ex_quitall(exarg_T *eap)
{
if (before_quit_all(eap) == FAIL) {
return;
}
exiting = true;
Error err = ERROR_INIT;
if ((eap->forceit || !check_changed_any(false, false))
&& (eap->cmdidx != CMD_restart || remote_ui_restart(current_ui, &err))) {
getout(0);
if (!eap->forceit && check_changed_any(false, false)) {
not_exiting();
return;
}
not_exiting();
getout(0);
}
/// ":restart": restart the Nvim server (using ":qall!").
/// ":restart +cmd": restart the Nvim server using ":cmd".
static void ex_restart(exarg_T *eap)
{
char *quit_cmd = (eap->do_ecmd_cmd) ? eap->do_ecmd_cmd : "qall!";
Error err = ERROR_INIT;
if ((cmdmod.cmod_flags & CMOD_CONFIRM) && check_changed_any(false, false)) {
return;
}
restarting = true;
nvim_command(cstr_as_string(quit_cmd), &err);
if (ERROR_SET(&err)) {
emsg(err.msg); // UI disappeared already?
emsg(err.msg); // Could not exit
api_clear_error(&err);
not_restarting();
return;
}
if (!exiting) {
emsg("restart failed: +cmd did not quit the server");
not_restarting();
}
}