emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 5be9a9cacf: Add a new command `restart-emacs'


From: Lars Ingebrigtsen
Subject: master 5be9a9cacf: Add a new command `restart-emacs'
Date: Sun, 17 Apr 2022 07:38:12 -0400 (EDT)

branch: master
commit 5be9a9cacfaae1959c4b95c45c146044a181ad20
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Add a new command `restart-emacs'
    
    * 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      | 13 ++++++++++++-
 etc/NEWS                 | 12 +++++++++++-
 lisp/files.el            | 19 ++++++++++++++++---
 src/emacs.c              | 21 +++++++++++++++------
 src/eval.c               |  2 +-
 src/keyboard.c           | 18 +++++++++---------
 src/xdisp.c              |  2 +-
 src/xsmfns.c             |  2 +-
 src/xterm.c              |  2 +-
 test/lisp/files-tests.el |  2 +-
 10 files changed, 68 insertions(+), 25 deletions(-)

diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 8366689640..eea0ab8f6b 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -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
diff --git a/etc/NEWS b/etc/NEWS
index 71d1e90d83..0245ec8c68 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -194,6 +194,15 @@ methods instead.
 
 * 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'.
diff --git a/lisp/files.el b/lisp/files.el
index b5ec7d4500..80180276a9 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -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))
+
 
 ;; We use /: as a prefix to "quote" a file name
 ;; so that magic file name handlers will not apply to it.
diff --git a/src/emacs.c b/src/emacs.c
index a35996c07a..50b1628d20 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -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);
 }
 
-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
diff --git a/src/eval.c b/src/eval.c
index a1cebcd025..6b1e12b823 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -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 ();
diff --git a/src/keyboard.c b/src/keyboard.c
index e569f8f34c..19c8fdf1dc 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -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 ();
diff --git a/src/xdisp.c b/src/xdisp.c
index 2dbc68f657..a3a4338eb4 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -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 ();
 
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 199e3ded3d..7015a8eb63 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -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.  */
diff --git a/src/xterm.c b/src/xterm.c
index 89dd28c0d5..ab4dcc3841 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -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 ();
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index 42b09201de..e4424f3cbe 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -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"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]