* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients @ 2022-10-09 23:32 Jim Porter 2022-10-10 6:11 ` Eli Zaretskii 0 siblings, 1 reply; 9+ messages in thread From: Jim Porter @ 2022-10-09 23:32 UTC (permalink / raw) To: 58404 [-- Attachment #1: Type: text/plain, Size: 988 bytes --] To reproduce: $ emacs -Q --daemon $ emacsclient foo.txt M-x save-buffers-kill-emacs => This Emacs session has clients; exit anyway? I think that's unnecessary. Since we're in the last (only) client, we can't accidentally kill other clients that we don't see right now (e.g. ones in an SSH connection); they don't exist! Couldn't we just proceed ahead without the prompt? On the other hand, I think it *would* be useful to prompt if you're in the last client, but there are other non-client frames. This can happen if you start the main Emacs process without --daemon or if you use --no-wait. For example: $ emacs -Q --daemon $ emacsclient foo.txt $ emacsclient --no-wait -c bar.txt ;; From the first client: M-x save-buffers-kill-emacs => This Emacs session has clients; exit anyway? This is ok, except the prompt could be clearer. The real issue is that the session has non-client frames that would get killed. Attached is a patch to do this. [-- Attachment #2: 0001-Don-t-prompt-when-killing-an-Emacs-client-if-it-s-th.patch --] [-- Type: text/plain, Size: 2215 bytes --] From 2fb6c6da99b84c250e59409d4dc0adbdbe704fed Mon Sep 17 00:00:00 2001 From: Jim Porter <jporterbugs@gmail.com> Date: Sun, 9 Oct 2022 15:53:27 -0700 Subject: [PATCH] Don't prompt when killing an Emacs client if it's the last client * lisp/server.el (server-kill-emacs-query-function): Ignore the current client, if any. Prompt if there are non-client frames. --- lisp/server.el | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/lisp/server.el b/lisp/server.el index 3caa335c4e..9ebdabbf87 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1589,14 +1589,28 @@ server-done (server-buffer-done (current-buffer)))) (defun server-kill-emacs-query-function () - "Ask before exiting Emacs if it has live clients. + "Ask before exiting Emacs if it has other live clients or non-client frames. A \"live client\" is a client with at least one live buffer associated with it." - (or (not (seq-some (lambda (proc) - (seq-some #'buffer-live-p - (process-get proc 'buffers))) - server-clients)) - (yes-or-no-p "This Emacs session has clients; exit anyway? "))) + (let ((this-client (frame-parameter nil 'client))) + (if (seq-some (lambda (proc) + ;; Ignore the current client when checking for + ;; live clients. + (unless (eq proc this-client) + (seq-some #'buffer-live-p + (process-get proc 'buffers)))) + server-clients) + (yes-or-no-p "This Emacs session has other clients; exit anyway? ") + (or (not (processp this-client)) + ;; Check if there are any non-client frames, ignoring the + ;; initial frame when in daemon mode. + (>= (if (daemonp) 1 0) + (seq-count + (lambda (frame) + (not (processp (frame-parameter frame 'client)))) + (frame-list))) + (yes-or-no-p + "This Emacs session has non-client frames; exit anyway? "))))) (defun server-kill-buffer () "Remove the current buffer from its clients' buffer list. -- 2.25.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-09 23:32 bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients Jim Porter @ 2022-10-10 6:11 ` Eli Zaretskii 2022-10-10 8:08 ` Jim Porter 0 siblings, 1 reply; 9+ messages in thread From: Eli Zaretskii @ 2022-10-10 6:11 UTC (permalink / raw) To: Jim Porter; +Cc: 58404 > Date: Sun, 9 Oct 2022 16:32:28 -0700 > From: Jim Porter <jporterbugs@gmail.com> > > On the other hand, I think it *would* be useful to prompt if you're in > the last client, but there are other non-client frames. This can happen > if you start the main Emacs process without --daemon or if you use > --no-wait. For example: > > $ emacs -Q --daemon > $ emacsclient foo.txt > $ emacsclient --no-wait -c bar.txt > > ;; From the first client: > M-x save-buffers-kill-emacs > => This Emacs session has clients; exit anyway? > > This is ok, except the prompt could be clearer. The real issue is that > the session has non-client frames that would get killed. > > Attached is a patch to do this. IMO, this is an unnecessary annoyance. We don't by default ask the user any questions today, when they want to kill an Emacs session. Why should we change that in this case? What is the use case where this command could be invoked by mistake and will risk losing edits or other valuable work? ^ permalink raw reply [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-10 6:11 ` Eli Zaretskii @ 2022-10-10 8:08 ` Jim Porter 2022-10-10 8:53 ` Eli Zaretskii 0 siblings, 1 reply; 9+ messages in thread From: Jim Porter @ 2022-10-10 8:08 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 58404 On 10/9/2022 11:11 PM, Eli Zaretskii wrote: > IMO, this is an unnecessary annoyance. We don't by default ask the > user any questions today, when they want to kill an Emacs session. But Emacs *does* prompt the user today. If you call 'save-buffers-kill-emacs' from an emacsclient frame, it will (almost) always ask you, "This Emacs session has clients; exit anyway?" My patch just gets rid of that annoyance when we can be sure it's unnecessary (i.e. it won't ask if there are no other emacsclients and no other frames not owned by a client). The patch does also change the prompt to be more-precise when there is an open frame not owned by a client[1]. However, it doesn't add any new prompts where there were none before; it only removes a prompt in one case. > What is the use case where this command could be invoked by mistake > and will risk losing edits or other valuable work? I didn't write this code initially, but here's my understanding of why the prompt is useful. If you use "emacs --daemon", 'C-x C-c' ('save-buffers-kill-terminal') will only close the current emacsclient, not shut down the daemon entirely. If you'd like to shut down the daemon too, you can call 'save-buffers-kill-emacs' instead. Maybe you'd even bind that to a key combo or do it automatically in some cases. So given the above, imagine you're at the office. You start the Emacs daemon and connect a GUI emacsclient instance[2]. Then you do a bunch of work until it's time to go home, but you leave your emacsclient running to pick up where you left off the next day. When you get home, you remember that you wanted to edit something quickly, so you SSH into you work computer and start a second emacsclient instance. By now, you forgot about your first emacsclient instance you made while at work. If you call 'save-buffers-kill-emacs' from your SSH emacsclient, it's nice that it can remind you that you have another emacsclient instance still running: since you don't see the GUI frames for the other client, it would be easy to forget about them and kill the session entirely. Then when you go into work the next day, the buffers you had open yesterday would be gone. In this case, you likely haven't lost changes to any files, since you saved before killing the session, but you'd lose non-file buffers, window configuration, etc. (Of course, this assumes you're not using desktop.el.) As for the code I added to check for non-client frames, the story is pretty much the same, although that code is there to handle situations where users start Emacs normally (i.e. by running "emacs") and then start the Emacs server via '(server-start)'. When connecting to that Emacs session remotely, it would be useful to get a prompt for the same reasons above. The only difference is that the GUI frames on your work system are "non-client" frames, so the code checks for them in a different way. [1] Excluding the initial frame for "emacs --daemon", that is. [2] This could be as simple as clicking the "Emacs (client)" icon on your desktop. ^ permalink raw reply [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-10 8:08 ` Jim Porter @ 2022-10-10 8:53 ` Eli Zaretskii 2022-10-10 16:43 ` Jim Porter 0 siblings, 1 reply; 9+ messages in thread From: Eli Zaretskii @ 2022-10-10 8:53 UTC (permalink / raw) To: Jim Porter; +Cc: 58404 > Date: Mon, 10 Oct 2022 01:08:17 -0700 > Cc: 58404@debbugs.gnu.org > From: Jim Porter <jporterbugs@gmail.com> > > On 10/9/2022 11:11 PM, Eli Zaretskii wrote: > > IMO, this is an unnecessary annoyance. We don't by default ask the > > user any questions today, when they want to kill an Emacs session. > > But Emacs *does* prompt the user today. If you call > 'save-buffers-kill-emacs' from an emacsclient frame, it will (almost) > always ask you, "This Emacs session has clients; exit anyway?" My patch > just gets rid of that annoyance when we can be sure it's unnecessary > (i.e. it won't ask if there are no other emacsclients and no other > frames not owned by a client). It is okay not to prompt when there's no need. That wasn't the part on which I commented, AFAIU. You said: > On the other hand, I think it *would* be useful to prompt if you're in > the last client, but there are other non-client frames. I'm saying that no, it will not be useful to prompt in that case: if the only frames left are non-client frames, we should not prompt, because we don't prompt when there are no client frames to begin with. Apologies if I misunderstood the use case. ^ permalink raw reply [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-10 8:53 ` Eli Zaretskii @ 2022-10-10 16:43 ` Jim Porter 2022-10-10 16:59 ` Eli Zaretskii 0 siblings, 1 reply; 9+ messages in thread From: Jim Porter @ 2022-10-10 16:43 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 58404 [-- Attachment #1: Type: text/plain, Size: 2168 bytes --] On 10/10/2022 1:53 AM, Eli Zaretskii wrote: > It is okay not to prompt when there's no need. That wasn't the part > on which I commented, AFAIU. > > You said: > >> On the other hand, I think it *would* be useful to prompt if you're in >> the last client, but there are other non-client frames. > > I'm saying that no, it will not be useful to prompt in that case: if > the only frames left are non-client frames, we should not prompt, > because we don't prompt when there are no client frames to begin with. > Apologies if I misunderstood the use case. Ah, I see. In that part of my original message, I wanted to say that this was a case where I thought the old code made sense, since it prompts the user then. However, I also thought that the prompt message could be more informative. Here's why I think prompting then makes sense: when you're in an emacsclient frame and there are other non-client frames (i.e. ones "owned" by the main Emacs process), that looks very similar to the user as when you have a second emacsclient running. In other words, I think it would be good for this function to prompt when doing this: $ emacs -Q --daemon $ emacsclient foo.txt $ emacsclient -c bar.txt ;; From either frame: M-x save-buffers-kill-emacs Or this: $ emacs -Q --daemon $ emacsclient foo.txt $ emacsclient --no-wait -c bar.txt ;; From either frame: M-x save-buffers-kill-emacs Or this: $ emacs foo.txt M-x server-start $ emacsclient -c bar.txt ;; From either frame: M-x save-buffers-kill-emacs In all of those cases, the user would have 2 (visible) frames, possibly on different displays/terminals. Since they're visually similar, I think it makes sense to have similar prompts. Next, if the user ran 'save-buffers-kill-emacs' a second time in any of those examples, it *wouldn't* prompt, since then all the remaining frames are associated with a single emacsclient (or no client at all). Since the use case for this is non-obvious (it actually took me several iterations to identify all the possible cases), I updated my patch with clearer (to me) code, plus comments explaining the reasoning. [-- Attachment #2: 0001-Don-t-prompt-when-killing-an-Emacs-client-if-it-s-th.patch --] [-- Type: text/plain, Size: 2846 bytes --] From 3f08b120a83b3c06a777823acee604f94fd41210 Mon Sep 17 00:00:00 2001 From: Jim Porter <jporterbugs@gmail.com> Date: Sun, 9 Oct 2022 15:53:27 -0700 Subject: [PATCH] Don't prompt when killing an Emacs client if it's the last client Previously, this function prompted whenever there was a live client, including the current one. Now, only prompt in one of: 1. There are live Emacs clients other than the current one, or 2. The current frame is a client frame and there are also non-client frames open. * lisp/server.el (server-kill-emacs-query-function): Rewrite to avoid prompting as above (bug#58404). --- lisp/server.el | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/lisp/server.el b/lisp/server.el index 3caa335c4e..f74f26210a 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1589,14 +1589,34 @@ server-done (server-buffer-done (current-buffer)))) (defun server-kill-emacs-query-function () - "Ask before exiting Emacs if it has live clients. + "Ask before exiting Emacs if it has other live clients or non-client frames. A \"live client\" is a client with at least one live buffer associated with it." - (or (not (seq-some (lambda (proc) - (seq-some #'buffer-live-p - (process-get proc 'buffers))) - server-clients)) - (yes-or-no-p "This Emacs session has clients; exit anyway? "))) + (let ((this-client (frame-parameter nil 'client))) + (cond + ;; Check for Emacs clients, excluding the current one (if any). + ;; If there are any other clients, prompt the user before killing + ;; Emacs. Other clients might be on different (possibly remote) + ;; displays, so it can be hard for users to tell on their own. + ((seq-some (lambda (proc) + (unless (eq proc this-client) + (seq-some #'buffer-live-p + (process-get proc 'buffers)))) + server-clients) + (yes-or-no-p "This Emacs session has other clients; exit anyway? ")) + ;; If the user is in a client frame, prompt if there are any + ;; frames created by the main Emacs process. Like in the case + ;; above, those frames might be on different displays. + ((and (processp this-client) + ;; Don't count the initial frame when in daemon mode. + (< (if (daemonp) 1 0) + (seq-count + (lambda (frame) + (not (processp (frame-parameter frame 'client)))) + (frame-list)))) + (yes-or-no-p "This Emacs session has non-client frames; exit anyway? ")) + ;; Otherwise, we can kill Emacs without prompting. + (t t)))) (defun server-kill-buffer () "Remove the current buffer from its clients' buffer list. -- 2.25.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-10 16:43 ` Jim Porter @ 2022-10-10 16:59 ` Eli Zaretskii 2022-10-10 17:49 ` Jim Porter 0 siblings, 1 reply; 9+ messages in thread From: Eli Zaretskii @ 2022-10-10 16:59 UTC (permalink / raw) To: Jim Porter; +Cc: 58404 > Date: Mon, 10 Oct 2022 09:43:55 -0700 > Cc: 58404@debbugs.gnu.org > From: Jim Porter <jporterbugs@gmail.com> > > Here's why I think prompting then makes sense: when you're in an > emacsclient frame and there are other non-client frames (i.e. ones > "owned" by the main Emacs process), that looks very similar to the user > as when you have a second emacsclient running. No, there's a very fundamental difference between the two. When there are client frames showing buffers, for each client buffer there's a process waiting, the process which requested the buffer to be edited. That's why we prompt: we don't want to fail those waiting processes. Non-client frames don't have this problem. ^ permalink raw reply [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-10 16:59 ` Eli Zaretskii @ 2022-10-10 17:49 ` Jim Porter 2022-10-10 17:57 ` Eli Zaretskii 0 siblings, 1 reply; 9+ messages in thread From: Jim Porter @ 2022-10-10 17:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 58404 [-- Attachment #1: Type: text/plain, Size: 1409 bytes --] On 10/10/2022 9:59 AM, Eli Zaretskii wrote: >> Date: Mon, 10 Oct 2022 09:43:55 -0700 >> Cc: 58404@debbugs.gnu.org >> From: Jim Porter <jporterbugs@gmail.com> >> >> Here's why I think prompting then makes sense: when you're in an >> emacsclient frame and there are other non-client frames (i.e. ones >> "owned" by the main Emacs process), that looks very similar to the user >> as when you have a second emacsclient running. > > No, there's a very fundamental difference between the two. When there > are client frames showing buffers, for each client buffer there's a > process waiting, the process which requested the buffer to be edited. > That's why we prompt: we don't want to fail those waiting processes. > > Non-client frames don't have this problem. Ok, I think that makes sense. I was hesitant about removing prompts too aggressively, since I didn't want to open users up to losing some Emacs state without prompting when they would have gotten a prompt before. However, you've convinced me that we don't need to worry about non-client frames since they don't have processes waiting on them. (Maybe some users would want more prompts in case they accidentally kill Emacs, but they can always add to 'kill-emacs-query-functions'.) Attached is a new patch that removes the prompt when called from the last remaining client. I also expanded the docstring to explain why the prompt is there. [-- Attachment #2: 0001-Don-t-prompt-when-killing-an-Emacs-client-if-it-s-th.patch --] [-- Type: text/plain, Size: 1910 bytes --] From ea95b409e89c1d87016a36a92070a592b8b2e4d0 Mon Sep 17 00:00:00 2001 From: Jim Porter <jporterbugs@gmail.com> Date: Sun, 9 Oct 2022 15:53:27 -0700 Subject: [PATCH] Don't prompt when killing an Emacs client if it's the last client * lisp/server.el (server-kill-emacs-query-function): Ignore the current client (if any) when checking for live clients (bug#58404). --- lisp/server.el | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lisp/server.el b/lisp/server.el index 3caa335c4e..15118067e5 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1589,14 +1589,19 @@ server-done (server-buffer-done (current-buffer)))) (defun server-kill-emacs-query-function () - "Ask before exiting Emacs if it has live clients. + "Ask before exiting Emacs if it has other live clients. A \"live client\" is a client with at least one live buffer -associated with it." - (or (not (seq-some (lambda (proc) - (seq-some #'buffer-live-p - (process-get proc 'buffers))) - server-clients)) - (yes-or-no-p "This Emacs session has clients; exit anyway? "))) +associated with it. These clients were (probably) started by +external processes that are waiting for some buffers to be +edited. If there are any other clients, we don't want to fail +their waiting processes, so ask the user to be sure." + (let ((this-client (frame-parameter nil 'client))) + (or (not (seq-some (lambda (proc) + (unless (eq proc this-client) + (seq-some #'buffer-live-p + (process-get proc 'buffers)))) + server-clients)) + (yes-or-no-p "This Emacs session has other clients; exit anyway? ")))) (defun server-kill-buffer () "Remove the current buffer from its clients' buffer list. -- 2.25.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-10 17:49 ` Jim Porter @ 2022-10-10 17:57 ` Eli Zaretskii 2022-10-10 23:09 ` Jim Porter 0 siblings, 1 reply; 9+ messages in thread From: Eli Zaretskii @ 2022-10-10 17:57 UTC (permalink / raw) To: Jim Porter; +Cc: 58404 > Date: Mon, 10 Oct 2022 10:49:05 -0700 > Cc: 58404@debbugs.gnu.org > From: Jim Porter <jporterbugs@gmail.com> > > Attached is a new patch that removes the prompt when called from the > last remaining client. I also expanded the docstring to explain why the > prompt is there. LGTM, thanks. ^ permalink raw reply [flat|nested] 9+ messages in thread
* bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients 2022-10-10 17:57 ` Eli Zaretskii @ 2022-10-10 23:09 ` Jim Porter 0 siblings, 0 replies; 9+ messages in thread From: Jim Porter @ 2022-10-10 23:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 58404-done On 10/10/2022 10:57 AM, Eli Zaretskii wrote: >> Date: Mon, 10 Oct 2022 10:49:05 -0700 >> Cc: 58404@debbugs.gnu.org >> From: Jim Porter <jporterbugs@gmail.com> >> >> Attached is a new patch that removes the prompt when called from the >> last remaining client. I also expanded the docstring to explain why the >> prompt is there. > > LGTM, thanks. Thanks, merged as ebc19f56aaeb98b834eea1ce8768ca13bed8578c. Closing this bug. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-10-10 23:09 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-10-09 23:32 bug#58404: 29.0.50; [PATCH] When killing Emacs from the last client, don't warn about the session having clients Jim Porter 2022-10-10 6:11 ` Eli Zaretskii 2022-10-10 8:08 ` Jim Porter 2022-10-10 8:53 ` Eli Zaretskii 2022-10-10 16:43 ` Jim Porter 2022-10-10 16:59 ` Eli Zaretskii 2022-10-10 17:49 ` Jim Porter 2022-10-10 17:57 ` Eli Zaretskii 2022-10-10 23:09 ` Jim Porter
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.