]> git.eshelyaron.com Git - emacs.git/commitdiff
Add a new command `restart-emacs'
authorLars Ingebrigtsen <larsi@gnus.org>
Sun, 17 Apr 2022 11:37:51 +0000 (13:37 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Sun, 17 Apr 2022 11:37:51 +0000 (13:37 +0200)
* doc/lispref/os.texi (Killing Emacs): Document it.

* lisp/files.el (save-buffers-kill-emacs): Add new RESTART parameter.
(restart-emacs): New function.

* src/emacs.c (terminate_due_to_signal, Fkill_emacs): Take an
optional RESTART parameter.

* test/lisp/files-tests.el
(files-tests-save-buffers-kill-emacs--confirm-kill-processes):
* src/xterm.c (x_connection_closed):
* src/xsmfns.c (Fhandle_save_session):
* src/keyboard.c (Fcommand_error_default_function, command_loop)
(command_loop_1, read_menu_command, read_event_from_main_queue)
(read_key_sequence, quit_throw_to_read_char):
* src/eval.c (process_quit_flag): Adjust Fkill_emacs callers.

doc/lispref/os.texi
etc/NEWS
lisp/files.el
src/emacs.c
src/eval.c
src/keyboard.c
src/xdisp.c
src/xsmfns.c
src/xterm.c
test/lisp/files-tests.el

index 8366689640f2c5bf6fed187a6cf6f56479e6313b..eea0ab8f6bc02593598cf25d66b219b611e1924e 100644 (file)
@@ -699,7 +699,7 @@ If you started Emacs from a terminal, the parent process normally
 resumes control.  The low-level primitive for killing Emacs is
 @code{kill-emacs}.
 
-@deffn Command kill-emacs &optional exit-data
+@deffn Command kill-emacs &optional exit-data restart
 This command calls the hook @code{kill-emacs-hook}, then exits the
 Emacs process and kills it.
 
@@ -714,6 +714,10 @@ input) can read them.
 If @var{exit-data} is neither an integer nor a string, or is omitted,
 that means to use the (system-specific) exit status which indicates
 successful program termination.
+
+If @var{restart} is non-@code{nil}, instead of just exiting at the
+end, start a new Emacs process, using the same command line arguments
+as the currently running Emacs process.
 @end deffn
 
 @cindex SIGTERM
@@ -756,6 +760,13 @@ the remaining functions in this hook.  Calling @code{kill-emacs}
 directly does not run this hook.
 @end defopt
 
+@deffn Command restart-emacs
+This command does the same as @code{save-buffers-kill-emacs}, but
+instead of just killing the current Emacs process at the end, it'll
+restart a new Emacs process, using the same command line arguments as
+the currently running Emacs process.
+@end deffn
+
 @node Suspending Emacs
 @subsection Suspending Emacs
 @cindex suspending Emacs
index 71d1e90d83383a52fcd670b3a666c3c8b567f212..0245ec8c6894b57983593a7ff4886984cfcb830e 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -194,6 +194,15 @@ methods instead.
 \f
 * Changes in Emacs 29.1
 
++++
+** New command 'restart-emacs'.
+This is like 'save-buffers-kill-emacs', but instead of just killing
+the current Emacs process at the end, it starts a new Emacs process
+(using the same command line arguments as the running Emacs process).
+'kill-emacs' and 'save-buffers-kill-emacs' have also gained new
+optional parameters to restart instead of just killing the current
+process.
+
 +++
 ** New user option 'mouse-drag-and-drop-region-cross-program'.
 If non-nil, this option allows dragging text in the region from Emacs
@@ -1451,7 +1460,8 @@ compliant.
 +++
 ** New macro 'setopt'.
 This is like 'setq', but is meant to be used for user options instead
-of plain variables, and uses 'custom-set'/'set-default' to set them.
+of plain variables, and
+uses 'custom-set'/'set-default' to set them.
 
 +++
 ** New utility predicate 'mode-line-window-selected-p'.
index b5ec7d450057a234da752d74fc06f7d29288a92a..80180276a99ac5a80ad6badac206d138dd066bb5 100644 (file)
@@ -7762,14 +7762,17 @@ prompt the user before killing them."
   :group 'convenience
   :version "26.1")
 
-(defun save-buffers-kill-emacs (&optional arg)
+(defun save-buffers-kill-emacs (&optional arg restart)
   "Offer to save each buffer, then kill this Emacs process.
 With prefix ARG, silently save all file-visiting buffers without asking.
 If there are active processes where `process-query-on-exit-flag'
 returns non-nil and `confirm-kill-processes' is non-nil,
 asks whether processes should be killed.
+
 Runs the members of `kill-emacs-query-functions' in turn and stops
-if any returns nil.  If `confirm-kill-emacs' is non-nil, calls it."
+if any returns nil.  If `confirm-kill-emacs' is non-nil, calls it.
+
+If RESTART, restart Emacs after killing the current Emacs process."
   (interactive "P")
   ;; Don't use save-some-buffers-default-predicate, because we want
   ;; to ask about all the buffers before killing Emacs.
@@ -7823,7 +7826,7 @@ if any returns nil.  If `confirm-kill-emacs' is non-nil, calls it."
      (run-hook-with-args-until-failure 'kill-emacs-query-functions)
      (or (null confirm)
          (funcall confirm "Really exit Emacs? "))
-     (kill-emacs))))
+     (kill-emacs nil restart))))
 
 (defun save-buffers-kill-terminal (&optional arg)
   "Offer to save each buffer, then kill the current connection.
@@ -7838,6 +7841,16 @@ only these files will be asked to be saved."
   (if (frame-parameter nil 'client)
       (server-save-buffers-kill-terminal arg)
     (save-buffers-kill-emacs arg)))
+
+(defun restart-emacs ()
+  "Kill the current Emacs process and start a new one.
+This goes through the same shutdown procedure as
+`save-buffers-kill-emacs', but instead of killing Emacs and
+exiting, it re-executes Emacs (using the same command line
+arguments as the running Emacs)."
+  (interactive)
+  (save-buffers-kill-emacs nil t))
+
 \f
 ;; We use /: as a prefix to "quote" a file name
 ;; so that magic file name handlers will not apply to it.
index a35996c07aa1c176e33ae2294b0d51c997002bc6..50b1628d207d3fdcfbd7186d146ea5fc57775294 100644 (file)
@@ -427,7 +427,7 @@ terminate_due_to_signal (int sig, int backtrace_limit)
                 don't care about the message stack.  */
              if (sig == SIGINT && noninteractive)
                clear_message_stack ();
-             Fkill_emacs (make_fixnum (sig));
+             Fkill_emacs (make_fixnum (sig), Qnil);
            }
 
           shut_down_emacs (sig, Qnil);
@@ -2740,21 +2740,25 @@ sort_args (int argc, char **argv)
   xfree (priority);
 }
 \f
-DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
+DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 2, "P",
        doc: /* Exit the Emacs job and kill it.
 If ARG is an integer, return ARG as the exit program code.
 If ARG is a string, stuff it as keyboard input.
 Any other value of ARG, or ARG omitted, means return an
 exit code that indicates successful program termination.
 
+If RESTART is non-nil, instead of just exiting at the end, start a new
+Emacs process, using the same command line arguments as the currently
+running Emacs process.
+
 This function is called upon receipt of the signals SIGTERM
 or SIGHUP, and upon SIGINT in batch mode.
 
-The value of `kill-emacs-hook', if not void,
-is a list of functions (of no args),
-all of which are called before Emacs is actually killed.  */
+The value of `kill-emacs-hook', if not void, is a list of functions
+(of no args), all of which are called before Emacs is actually
+killed.  */
        attributes: noreturn)
-  (Lisp_Object arg)
+  (Lisp_Object arg, Lisp_Object restart)
 {
   int exit_code;
 
@@ -2801,6 +2805,11 @@ all of which are called before Emacs is actually killed.  */
   eln_load_path_final_clean_up ();
 #endif
 
+  if (!NILP (restart))
+    {
+      execvp (*initial_argv, initial_argv);
+    }
+
   if (FIXNUMP (arg))
     exit_code = (XFIXNUM (arg) < 0
                 ? XFIXNUM (arg) | INT_MIN
index a1cebcd0257c48e454e3b0e1c12a84b1797a3228..6b1e12b823291f180f07b425b16880d647bbe28b 100644 (file)
@@ -1613,7 +1613,7 @@ process_quit_flag (void)
   Lisp_Object flag = Vquit_flag;
   Vquit_flag = Qnil;
   if (EQ (flag, Qkill_emacs))
-    Fkill_emacs (Qnil);
+    Fkill_emacs (Qnil, Qnil);
   if (EQ (Vthrow_on_input, flag))
     Fthrow (Vthrow_on_input, Qt);
   quit ();
index e569f8f34c915818d72136eae4625f2f2260ce79..19c8fdf1dc0ce3f713286fa615d3a190b7e818ac 100644 (file)
@@ -1059,7 +1059,7 @@ Default value of `command-error-function'.  */)
       print_error_message (data, Qexternal_debugging_output,
                           SSDATA (context), signal);
       Fterpri (Qexternal_debugging_output, Qnil);
-      Fkill_emacs (make_fixnum (-1));
+      Fkill_emacs (make_fixnum (-1), Qnil);
     }
   else
     {
@@ -1122,7 +1122,7 @@ command_loop (void)
 
        /* End of file in -batch run causes exit here.  */
        if (noninteractive)
-         Fkill_emacs (Qt);
+         Fkill_emacs (Qt, Qnil);
       }
 }
 
@@ -1331,7 +1331,7 @@ command_loop_1 (void)
       Lisp_Object cmd;
 
       if (! FRAME_LIVE_P (XFRAME (selected_frame)))
-       Fkill_emacs (Qnil);
+       Fkill_emacs (Qnil, Qnil);
 
       /* Make sure the current window's buffer is selected.  */
       set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
@@ -1402,7 +1402,7 @@ command_loop_1 (void)
 
       /* A filter may have run while we were reading the input.  */
       if (! FRAME_LIVE_P (XFRAME (selected_frame)))
-       Fkill_emacs (Qnil);
+       Fkill_emacs (Qnil, Qnil);
       set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
 
       ++num_input_keys;
@@ -1660,7 +1660,7 @@ read_menu_command (void)
   unbind_to (count, Qnil);
 
   if (! FRAME_LIVE_P (XFRAME (selected_frame)))
-    Fkill_emacs (Qnil);
+    Fkill_emacs (Qnil, Qnil);
   if (i == 0 || i == -1)
     return Qt;
 
@@ -2259,7 +2259,7 @@ read_event_from_main_queue (struct timespec *end_time,
 
   /* Terminate Emacs in batch mode if at eof.  */
   if (noninteractive && FIXNUMP (c) && XFIXNUM (c) < 0)
-    Fkill_emacs (make_fixnum (1));
+    Fkill_emacs (make_fixnum (1), Qnil);
 
   if (FIXNUMP (c))
     {
@@ -10039,7 +10039,7 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
              if (fix_current_buffer)
                {
                  if (! FRAME_LIVE_P (XFRAME (selected_frame)))
-                   Fkill_emacs (Qnil);
+                   Fkill_emacs (Qnil, Qnil);
                  if (XBUFFER (XWINDOW (selected_window)->contents)
                      != current_buffer)
                    Fset_buffer (XWINDOW (selected_window)->contents);
@@ -10163,7 +10163,7 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
                      record_unwind_current_buffer ();
 
                      if (! FRAME_LIVE_P (XFRAME (selected_frame)))
-                       Fkill_emacs (Qnil);
+                       Fkill_emacs (Qnil, Qnil);
                      set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
                      goto replay_sequence;
                    }
@@ -11393,7 +11393,7 @@ quit_throw_to_read_char (bool from_signal)
   /* When not called from a signal handler it is safe to call
      Lisp.  */
   if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
-    Fkill_emacs (Qnil);
+    Fkill_emacs (Qnil, Qnil);
 
   /* Prevent another signal from doing this before we finish.  */
   clear_waiting_for_input ();
index 2dbc68f657c2c64763c164d7ac994f3c995b880a..a3a4338eb4f3ca5aa670900f8e46fdf1865bef57 100644 (file)
@@ -12143,7 +12143,7 @@ setup_echo_area_for_printing (bool multibyte_p)
 {
   /* If we can't find an echo area any more, exit.  */
   if (! FRAME_LIVE_P (XFRAME (selected_frame)))
-    Fkill_emacs (Qnil);
+    Fkill_emacs (Qnil, Qnil);
 
   ensure_echo_area_buffers ();
 
index 199e3ded3dd9a5265177c54e5a9ea20f3045643f..7015a8eb633eea6711f7ee86774e5bb9e89c4eec 100644 (file)
@@ -522,7 +522,7 @@ Do not call this function yourself. */)
     {
       /* We should not do user interaction here, but it is not easy to
          prevent.  Fix this in next version.  */
-      Fkill_emacs (Qnil);
+      Fkill_emacs (Qnil, Qnil);
 
 #if false
       /* This will not be reached, but we want kill-emacs-hook to be run.  */
index 89dd28c0d5802e6f9e0bdc85f263e3316f6e179a..ab4dcc3841aa2865d386b6f2bd81c86ae877fe83 100644 (file)
@@ -19773,7 +19773,7 @@ For details, see etc/PROBLEMS.\n",
   if (terminal_list == 0)
     {
       fprintf (stderr, "%s\n", error_msg);
-      Fkill_emacs (make_fixnum (70));
+      Fkill_emacs (make_fixnum (70), Qnil);
     }
 
   totally_unblock_input ();
index 42b09201de832c92d2c7d3b152995bbdb010fb8a..e4424f3cbedc356a7ebc194b58bb146cd4625760 100644 (file)
@@ -263,7 +263,7 @@ form.")
                 nil))
              (kill-emacs-args nil)
              ((symbol-function #'kill-emacs)
-              (lambda (&optional arg) (push arg kill-emacs-args)))
+              (lambda (&optional arg arg) (push arg kill-emacs-args)))
              (process
               (make-process
                :name "sleep"