Repository: neovim/neovim
File: src/nvim/ex_docmd.c (C)

Code before:
  not_exiting(save_exiting);
}

/// ":restart": restart the Nvim server (using ":qall!").
/// ":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)
{
  const list_T *l = get_vim_var_list(VV_ARGV);
  int argc = tv_list_len(l);
  list_T *argv_cpy = tv_list_alloc(eap->arg ? argc + 2 : argc);

  // Copy v:argv, skipping unwanted items.
  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);
    if (strequal(arg, "-")) {
      continue;  // Skip stdin ("-") argument.
    }

    tv_list_append_string(argv_cpy, arg, (ssize_t)arg_size);
  });
  // Patch v:argv to include "-c <command>".
  if (eap->arg) {
    tv_list_append_string(argv_cpy, "-c", 2);
    tv_list_append_string(argv_cpy, eap->arg, (ssize_t)strlen(eap->arg));
  }
  set_vim_var_list(VV_ARGV, argv_cpy);

  char *quit_cmd = (eap->do_ecmd_cmd) ? eap->do_ecmd_cmd : "qall";
  char *quit_cmd_copy = NULL;

  // Prepend "confirm " to cmd if :confirm is used
  if (cmdmod.cmod_flags & CMOD_CONFIRM) {
    quit_cmd_copy = concat_str("confirm ", quit_cmd);
    quit_cmd = quit_cmd_copy;
  }

  Error err = ERROR_INIT;
  restarting = true;
  nvim_command(cstr_as_string(quit_cmd), &err);
  xfree(quit_cmd_copy);
  if (ERROR_SET(&err)) {
    emsg(err.msg);  // Could not exit
    api_clear_error(&err);
    not_restarting();
    return;
  }
  if (!exiting) {
    emsg("restart failed: +cmd did not quit the server");

Review comment (suggestion):


the arg should go last, and just before any `--` arg:

```c
  for (listitem_T *li = l != NULL ? l->lv_first : NULL; li != NULL; li = li->li_next) {
    ...

    // Patch v:argv to include "-c <command>".
    if (eap->arg && (li->li_next == NULL || strequal(tv_get_string(TV_LIST_ITEM_TV(li->li_next)), "--"))) {
      tv_list_append_string(argv_cpy, "-c", 2);
      tv_list_append_string(argv_cpy, eap->arg, (ssize_t)strlen(eap->arg));
    }
  }
```

but actually that's an antifeature. if user wants to restart with `-- files...` they can use a session.

Code after:
  not_exiting(save_exiting);
}

/// ":restart": restart the Nvim server (using ":qall!").
/// ":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)
{
  const list_T *l = get_vim_var_list(VV_ARGV);
  int argc = tv_list_len(l);
  list_T *argv_cpy = tv_list_alloc(eap->arg ? argc + 2 : argc);

  // Copy v:argv, skipping unwanted items.
  for (listitem_T *li = l != NULL ? l->lv_first : NULL; li != NULL; li = li->li_next) {
    const char *arg = tv_get_string(TV_LIST_ITEM_TV(li));
    size_t arg_size = strlen(arg);
    assert(arg_size <= (size_t)SSIZE_MAX);

    if (strequal(arg, "--embed") || strequal(arg, "--headless")) {
      continue;  // Drop --embed/--headless: the client decides how to start+attach the server.
    } else if (strequal(arg, "-")) {
      continue;  // Drop stdin ("-") argument.
    } else if (strequal(arg, "+:::")) {
      // The special placeholder "+:::" marks a previous :restart command.
      // Drop the `"+:::", "-c", "…"` triplet, to avoid "stacking" commands from previous :restart(s).
      listitem_T *next1 = li->li_next;
      if (next1 != NULL && strequal(tv_get_string(TV_LIST_ITEM_TV(next1)), "-c")) {
        listitem_T *next2 = next1->li_next;
        if (next2 != NULL) {
          li = next2;
          continue;
        }
      }
      continue;  // If the triplet is incomplete, just skip "+:::"
    } else if (strequal(arg, "--")) {
      break;  // Drop "-- [files…]". Usually isn't wanted. User can :mksession instead.
    }

    tv_list_append_string(argv_cpy, arg, (ssize_t)arg_size);
  }
  // Append `"+:::", "-c", "<command>"` to end of v:argv.
  // The "+:::" item is a no-op placeholder to mark the :restart "<command>".
  if (eap->arg && eap->arg[0] != '\0') {
    tv_list_append_string(argv_cpy, S_LEN("+:::"));
    tv_list_append_string(argv_cpy, S_LEN("-c"));
    tv_list_append_string(argv_cpy, eap->arg, (ssize_t)strlen(eap->arg));
  }
  set_vim_var_list(VV_ARGV, argv_cpy);

  char *quit_cmd = (eap->do_ecmd_cmd) ? eap->do_ecmd_cmd : "qall";
  char *quit_cmd_copy = NULL;