all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 58909@debbugs.gnu.org
Subject: bug#58909: 29.0.50; [WIP PATCH] Deleting the last frame of an emacsclient doesn't ask to save
Date: Mon, 31 Oct 2022 12:28:23 -0700	[thread overview]
Message-ID: <53238b5b-3e0a-3dfe-eeba-f37cafa81f50@gmail.com> (raw)
In-Reply-To: <83zgdcduxm.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 1757 bytes --]

On 10/31/2022 5:44 AM, Eli Zaretskii wrote:
>> Date: Sun, 30 Oct 2022 15:29:30 -0700
>> From: Jim Porter <jporterbugs@gmail.com>
>>
>> However, if you use 'C-x 5 0' instead, that terminates the Emacs client,
>> but *doesn't* prompt to save foo.txt. I think it should prompt in this
>> case too: all three of 'C-x #', 'C-x C-c', and 'C-x 5 0' have the effect
>> (in this simple case) of deleting the Emacs client and returning to the
>> calling process. (A user who wanted to bail out of an Emacs client
>> without saving should use 'sever-edit-abort' instead.)
> 
> I'm uneasy with this incompatible behavior change.  I can think of
> some legitimate use cases where "C-x 5 0" should not prompt, e.g., if
> the user intends to keep editing the file, and no application is
> waiting for the client to finish.  Why break such flows?

After thinking about this some more, I realized that I didn't properly 
address this part of your message. If no application is waiting for the 
client to finish, then the user hopefully used "--no-wait" when starting 
emacsclient. We could avoid prompting in that case.[1]

If an application *is* waiting for the client to finish, then 
"--no-wait" would be unset. In that case, prompting the user has some 
value. See the attached patch. (I changed the code to only prompt when 
deleting the last frame of a *non-nowait* client.)

[1] Currently, 'C-x C-c' from a nowait frame prompts via 
'save-some-buffers' (so long as there's another frame; see 
'server-save-buffers-kill-terminal'). Maybe we could avoid prompting 
then too? After prompting, it just calls 'delete-frame', so it's very 
similar to 'C-x 5 0' in this scenario... Still, as you say, it's 
probably good to be careful about making incompatible changes here.

[-- Attachment #2: 0001-When-deleting-the-last-frame-of-an-Emacs-client-ask-.patch --]
[-- Type: text/plain, Size: 3898 bytes --]

From 68b9f41685256870f3409ea468971ee0b64cf136 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Sat, 29 Oct 2022 20:40:49 -0700
Subject: [PATCH] When deleting the last frame of an Emacs client, ask to save

* src/frame.c (delete_frame): Call 'delete-frame-functions' with
'call2' instead of 'safe_call2' to allow hooks to quit, cancelling the
frame's deletion.

* lisp/server.el (server-save-some-buffers): New function...
(server-handle-delete-frame, server-save-buffers-kill-terminal):
... use it.
---
 lisp/server.el | 33 ++++++++++++++++++++-------------
 src/frame.c    |  2 +-
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/lisp/server.el b/lisp/server.el
index 90d97c1538..f04f993426 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -479,12 +479,26 @@ server-unselect-display
       (when (buffer-live-p buffer)
 	(kill-buffer buffer)))))
 
+(defun server-save-some-buffers (proc &optional arg)
+  "Save modified file-visiting buffers from the emacsclient file list.
+PROC is the emacsclient process.  If ARG is non-nil, save all
+with no questions."
+  (let ((buffers (process-get proc 'buffers)))
+    (save-some-buffers
+     arg (if buffers
+             ;; Only files from emacsclient file list.
+             (lambda () (memq (current-buffer) buffers))
+           ;; If there's no emacsclient file list: don't override
+           ;; `save-some-buffers-default-predicate' (unless ARG is
+           ;; non-nil).
+           (and arg t)))))
+
 (defun server-handle-delete-frame (frame)
   "Delete the client connection when the emacsclient frame is deleted.
 \(To be used from `delete-frame-functions'.)"
   (let ((proc (frame-parameter frame 'client)))
     (when (and (frame-live-p frame)
-	       proc
+	       (processp proc)
 	       ;; See if this is the last frame for this client.
                (not (seq-some
                      (lambda (f)
@@ -492,7 +506,9 @@ server-handle-delete-frame
                             (eq proc (frame-parameter f 'client))))
                      (frame-list))))
       (server-log (format "server-handle-delete-frame, frame %s" frame) proc)
-      (server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later.
+      (server-save-some-buffers proc))
+      ;; Let delete-frame delete the frame later.
+      (server-delete-client proc 'noframe)))
 
 (defun server-handle-suspend-tty (terminal)
   "Notify the client process that its tty device is suspended."
@@ -1752,17 +1768,8 @@ server-save-buffers-kill-terminal
 	       ;; If we're the last frame standing, kill Emacs.
 	       (save-buffers-kill-emacs arg)))
 	    ((processp proc)
-	     (let ((buffers (process-get proc 'buffers)))
-	       (save-some-buffers
-	        arg (if buffers
-                        ;; Only files from emacsclient file list.
-		        (lambda () (memq (current-buffer) buffers))
-                      ;; No emacsclient file list: don't override
-                      ;; `save-some-buffers-default-predicate' (unless
-                      ;; ARG is non-nil), since we're not killing
-                      ;; Emacs (unlike `save-buffers-kill-emacs').
-		      (and arg t)))
-	       (server-delete-client proc)))
+             (server-save-some-buffers proc arg)
+	     (server-delete-client proc))
 	    (t (error "Invalid client frame"))))))
 
 (defun server-stop-automatically--handle-delete-frame (frame)
diff --git a/src/frame.c b/src/frame.c
index f076a5ba54..8a85d5a400 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2037,7 +2037,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
       x_clipboard_manager_save_frame (frame);
 #endif
 
-      safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
+      call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
     }
 
   /* delete_frame_functions may have deleted any frame, including this
-- 
2.25.1


  parent reply	other threads:[~2022-10-31 19:28 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-30 22:29 bug#58909: 29.0.50; [WIP PATCH] Deleting the last frame of an emacsclient doesn't ask to save Jim Porter
2022-10-31 12:44 ` Eli Zaretskii
2022-10-31 17:36   ` Jim Porter
2022-10-31 18:25     ` Eli Zaretskii
2022-10-31 19:38       ` Jim Porter
2022-10-31 19:52         ` Eli Zaretskii
2022-10-31 20:28           ` Jim Porter
2022-11-01  6:17             ` Eli Zaretskii
2022-10-31 19:28   ` Jim Porter [this message]
2022-10-31 19:43     ` Eli Zaretskii
2022-10-31 20:01       ` Jim Porter
2022-10-31 20:21         ` Eli Zaretskii
2022-10-31 21:06           ` Jim Porter
2022-11-01  6:39             ` Eli Zaretskii
2022-11-01 16:11               ` Jim Porter
2022-11-01 22:39                 ` Jim Porter
2022-11-02 12:16                   ` Eli Zaretskii
2022-11-02 16:36                     ` Jim Porter
2022-11-02 17:11                       ` Eli Zaretskii
2022-11-02 18:17                         ` Jim Porter
2022-11-02 18:42                           ` Eli Zaretskii
2022-11-02 19:16                             ` Jim Porter
2022-11-02 19:23                               ` Eli Zaretskii
2022-11-02 19:57                                 ` Jim Porter
2022-11-02 20:09                                   ` Eli Zaretskii
2022-11-02 22:09                                     ` bug#58909: 29.0.50; [PATCH] " Jim Porter
2022-11-03  6:25                                       ` Eli Zaretskii
2022-11-06 20:23                                         ` Jim Porter
2022-11-08 14:47                                           ` Eli Zaretskii
2022-11-08 15:08                                             ` Robert Pluim
2022-11-08 15:13                                               ` Eli Zaretskii
2022-11-08 15:29                                                 ` Robert Pluim
2022-11-08 16:52                                                   ` Jim Porter
2022-11-09 10:06                                                     ` Robert Pluim
2022-11-17  5:17                                                       ` Jim Porter
2023-09-07 21:03                                                         ` bug#58909: 29.0.50; [WIP PATCH] " Stefan Kangas
2023-09-08  1:21                                                           ` Jim Porter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53238b5b-3e0a-3dfe-eeba-f37cafa81f50@gmail.com \
    --to=jporterbugs@gmail.com \
    --cc=58909@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.