mirror of
https://github.com/neovim/neovim.git
synced 2025-10-25 20:07:09 +00:00
feat: ":restart [cmd]" can run commands #35045
Problem: Not easy for a user to tell ":restart" to "run this command(s) after restarting". Solution: All ":restart" args following the optional +cmd arg are treated as a big cmdline that is passed as a "-c" CLI arg when restarting nvim.
This commit is contained in:
@@ -70,7 +70,7 @@ Stop or detach the current UI
|
|||||||
Restart Nvim
|
Restart Nvim
|
||||||
|
|
||||||
*:restart*
|
*:restart*
|
||||||
:restart [+cmd]
|
:restart [+cmd] [command]
|
||||||
Restarts the Nvim server with the same startup arguments
|
Restarts the Nvim server with the same startup arguments
|
||||||
|v:argv| and reattaches the current UI to the new server.
|
|v:argv| and reattaches the current UI to the new server.
|
||||||
All other UIs will detach.
|
All other UIs will detach.
|
||||||
@@ -78,6 +78,9 @@ Restart Nvim
|
|||||||
Use with `:confirm` to prompt if changes have been made.
|
Use with `:confirm` to prompt if changes have been made.
|
||||||
|
|
||||||
Example: `:restart +qall!` stops the server using `:qall!`.
|
Example: `:restart +qall!` stops the server using `:qall!`.
|
||||||
|
Example: `:restart +qall! lua vim.pack.update()` stops the
|
||||||
|
server using `:qall!` and starts the new server with the
|
||||||
|
argument `-c lua vim.pack.update()`. See also |-c|.
|
||||||
|
|
||||||
Note: |+cmd| defaults to `qall!` if not specified.
|
Note: |+cmd| defaults to `qall!` if not specified.
|
||||||
Note: If the current UI hasn't implemented the "restart" UI
|
Note: If the current UI hasn't implemented the "restart" UI
|
||||||
|
|||||||
@@ -286,15 +286,31 @@ bool remote_ui_restart(uint64_t channel_id, Error *err)
|
|||||||
assert(argc > 0);
|
assert(argc > 0);
|
||||||
Array argv = arena_array(&arena, (size_t)argc + 1);
|
Array argv = arena_array(&arena, (size_t)argc + 1);
|
||||||
bool had_minmin = false;
|
bool had_minmin = false;
|
||||||
|
bool skipping_minc = false; // Skip -c <cmd> from argv.
|
||||||
|
bool first_minc = true; // Avoid skipping the first -c <cmd> from argv.
|
||||||
TV_LIST_ITER_CONST(l, li, {
|
TV_LIST_ITER_CONST(l, li, {
|
||||||
const char *arg = tv_get_string(TV_LIST_ITEM_TV(li));
|
const char *arg = tv_get_string(TV_LIST_ITEM_TV(li));
|
||||||
if (argv.size > 0 && !had_minmin && strequal(arg, "--")) {
|
if (argv.size > 0 && !had_minmin && strequal(arg, "--")) {
|
||||||
had_minmin = true;
|
had_minmin = true;
|
||||||
|
skipping_minc = false;
|
||||||
}
|
}
|
||||||
// Exclude --embed/--headless from `argv`, as the client may start the server in a
|
bool startswith_min = strlen(arg) > 0 && arg[0] == '-';
|
||||||
|
bool startswith_minmin = strlen(arg) > 1 && arg[0] == '-' && arg[1] == '-';
|
||||||
|
if (skipping_minc && (startswith_min || startswith_minmin)) {
|
||||||
|
skipping_minc = false;
|
||||||
|
}
|
||||||
|
if (!had_minmin && !skipping_minc && strequal(arg, "-c")) {
|
||||||
|
if (!first_minc) {
|
||||||
|
skipping_minc = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
first_minc = false;
|
||||||
|
}
|
||||||
|
// Exclude --embed/--headless/-c <cmd> from `argv`, as the client may start the server in a
|
||||||
// different way than how the server was originally started.
|
// different way than how the server was originally started.
|
||||||
|
// Eg: 'nvim -c foo -c bar --embed --headless -- example.txt' would be parsed as { 'nvim', '-c', 'foo', '--', 'example.txt' }.
|
||||||
if (argv.size == 0 || had_minmin
|
if (argv.size == 0 || had_minmin
|
||||||
|| (!strequal(arg, "--embed") && !strequal(arg, "--headless"))) {
|
|| (!strequal(arg, "--embed") && !strequal(arg, "--headless") && !skipping_minc)) {
|
||||||
ADD_C(argv, CSTR_AS_OBJ(arg));
|
ADD_C(argv, CSTR_AS_OBJ(arg));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2248,7 +2248,7 @@ M.cmds = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
command = 'restart',
|
command = 'restart',
|
||||||
flags = bit.bor(CMDARG, TRLBAR),
|
flags = bit.bor(CMDARG, EXTRA, NOTRLCOM),
|
||||||
addr_type = 'ADDR_NONE',
|
addr_type = 'ADDR_NONE',
|
||||||
func = 'ex_restart',
|
func = 'ex_restart',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4852,8 +4852,30 @@ static void ex_quitall(exarg_T *eap)
|
|||||||
|
|
||||||
/// ":restart": restart the Nvim server (using ":qall!").
|
/// ":restart": restart the Nvim server (using ":qall!").
|
||||||
/// ":restart +cmd": restart the Nvim server using ":cmd".
|
/// ":restart +cmd": restart the Nvim server using ":cmd".
|
||||||
|
/// ":restart +cmd <command>": restart the Nvim server using ":cmd" and add -c <command> to the new server.
|
||||||
static void ex_restart(exarg_T *eap)
|
static void ex_restart(exarg_T *eap)
|
||||||
{
|
{
|
||||||
|
// Patch v:argv to include "-c <arg>" when it restarts.
|
||||||
|
if (eap->arg != NULL) {
|
||||||
|
const list_T *l = get_vim_var_list(VV_ARGV);
|
||||||
|
int argc = tv_list_len(l);
|
||||||
|
list_T *argv_cpy = tv_list_alloc(argc + 2);
|
||||||
|
bool added_startup_arg = false;
|
||||||
|
TV_LIST_ITER_CONST(l, li, {
|
||||||
|
const char *arg = tv_get_string(TV_LIST_ITEM_TV(li));
|
||||||
|
size_t arg_size = strlen(arg);
|
||||||
|
assert(arg_size <= (size_t)SSIZE_MAX);
|
||||||
|
tv_list_append_string(argv_cpy, arg, (ssize_t)arg_size);
|
||||||
|
if (!added_startup_arg) {
|
||||||
|
tv_list_append_string(argv_cpy, "-c", 2);
|
||||||
|
size_t cmd_size = strlen(eap->arg);
|
||||||
|
assert(cmd_size <= (size_t)SSIZE_MAX);
|
||||||
|
tv_list_append_string(argv_cpy, eap->arg, (ssize_t)cmd_size);
|
||||||
|
added_startup_arg = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
set_vim_var_list(VV_ARGV, argv_cpy);
|
||||||
|
}
|
||||||
char *quit_cmd = (eap->do_ecmd_cmd) ? eap->do_ecmd_cmd : "qall!";
|
char *quit_cmd = (eap->do_ecmd_cmd) ? eap->do_ecmd_cmd : "qall!";
|
||||||
Error err = ERROR_INIT;
|
Error err = ERROR_INIT;
|
||||||
if ((cmdmod.cmod_flags & CMOD_CONFIRM) && check_changed_any(false, false)) {
|
if ((cmdmod.cmod_flags & CMOD_CONFIRM) && check_changed_any(false, false)) {
|
||||||
|
|||||||
@@ -255,8 +255,37 @@ describe('TUI :restart', function()
|
|||||||
tt.feed_data(':1restart\013')
|
tt.feed_data(':1restart\013')
|
||||||
screen:expect({ any = vim.pesc('{101:E481: No range allowed}') })
|
screen:expect({ any = vim.pesc('{101:E481: No range allowed}') })
|
||||||
|
|
||||||
tt.feed_data(':restart foo\013')
|
local s1 = [[
|
||||||
screen:expect({ any = vim.pesc('{101:E488: Trailing characters: foo}') })
|
|
|
||||||
|
|
|
||||||
|
{2: }|
|
||||||
|
{MATCH:%d+ +}|
|
||||||
|
Hello |
|
||||||
|
{102:Press ENTER or type command to continue}^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]]
|
||||||
|
|
||||||
|
-- Check trailing characters are considered in -c
|
||||||
|
tt.feed_data(':restart echo "Hello"\013')
|
||||||
|
screen_expect(s1)
|
||||||
|
tt.feed_data('\013')
|
||||||
|
restart_pid_check()
|
||||||
|
gui_running_check()
|
||||||
|
|
||||||
|
-- Check trailing characters after +cmd are considered in -c
|
||||||
|
tt.feed_data(':restart +qall echo "Hello" | echo "World"\013')
|
||||||
|
screen_expect([[
|
||||||
|
|
|
||||||
|
{2: }|
|
||||||
|
{MATCH:%d+ +}|
|
||||||
|
Hello |
|
||||||
|
World |
|
||||||
|
{102:Press ENTER or type command to continue}^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
tt.feed_data('\013')
|
||||||
|
restart_pid_check()
|
||||||
|
gui_running_check()
|
||||||
|
|
||||||
-- Check ":restart" on an unmodified buffer.
|
-- Check ":restart" on an unmodified buffer.
|
||||||
tt.feed_data(':restart\013')
|
tt.feed_data(':restart\013')
|
||||||
@@ -290,6 +319,17 @@ describe('TUI :restart', function()
|
|||||||
-- Cancel the operation (abandons restart).
|
-- Cancel the operation (abandons restart).
|
||||||
tt.feed_data('C\013')
|
tt.feed_data('C\013')
|
||||||
|
|
||||||
|
-- Check ":confirm restart <cmd>" on a modified buffer.
|
||||||
|
tt.feed_data(':confirm restart echo "Hello"\013')
|
||||||
|
screen:expect({ any = vim.pesc('Save changes to "Untitled"?') })
|
||||||
|
tt.feed_data('N\013')
|
||||||
|
|
||||||
|
-- Check if the -c <cmd> runs after restart.
|
||||||
|
screen_expect(s1)
|
||||||
|
tt.feed_data('\013')
|
||||||
|
restart_pid_check()
|
||||||
|
gui_running_check()
|
||||||
|
|
||||||
-- Check ":restart" on the modified buffer.
|
-- Check ":restart" on the modified buffer.
|
||||||
tt.feed_data(':restart\013')
|
tt.feed_data(':restart\013')
|
||||||
screen_expect(s0)
|
screen_expect(s0)
|
||||||
|
|||||||
Reference in New Issue
Block a user