From 767b43cc04f42f36db20fa1ef9b32aab2c37b497 Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Sun, 24 Oct 2021 12:11:37 -0700 Subject: [PATCH 3/3] When killing the last client attached to a lazy daemon, kill the daemon too lisp/server.el (server-save-buffers-kill-terminal): Kill Emacs when connected to a lazy daemon and there are no other clients. (server-kill-emacs-query-function): Don't warn about killing Emacs when not necessary. lisp/frame.el (handle-delete-frame): Exclude the initial frame of a lazily-created daemon as a "valid" other frame. --- lisp/frame.el | 7 ++++-- lisp/server.el | 61 +++++++++++++++++++++++++++++--------------------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/lisp/frame.el b/lisp/frame.el index dfbd751201..fd38c4b623 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -119,11 +119,14 @@ handle-delete-frame (if (catch 'other-frame (dolist (frame-1 (frame-list)) ;; A valid "other" frame is visible, has its `delete-before' - ;; parameter unset and is not a child frame. + ;; parameter unset and is not a child frame or the initial frame + ;; of a lazily-created daemon. (when (and (not (eq frame-1 frame)) (frame-visible-p frame-1) (not (frame-parent frame-1)) - (not (frame-parameter frame-1 'delete-before))) + (not (frame-parameter frame-1 'delete-before)) + (or (not (eq (daemon-type) 'lazy)) + (frame-parameter frame-1 'client))) (throw 'other-frame t)))) (delete-frame frame t) ;; Gildea@x.org says it is ok to ask questions before terminating. diff --git a/lisp/server.el b/lisp/server.el index 5988560c83..0cbabba621 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1580,12 +1580,17 @@ server-done (server-buffer-done (current-buffer)))) (defun server-kill-emacs-query-function () - "Ask before exiting Emacs if it has live clients." - (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? "))) + "Ask before exiting Emacs if it has live clients. +If Emacs was started as a lazy daemon and the only live client is the +current frame's client, don't bother asking." + (let ((ignored-proc (and (eq (daemon-type) 'lazy) + (frame-parameter nil 'client)))) + (or (not (seq-some (lambda (proc) + (unless (eq ignored-proc proc) + (seq-some #'buffer-live-p + (process-get proc 'buffers)))) + server-clients)) + (yes-or-no-p "This Emacs session has clients; exit anyway? ")))) (defun server-kill-buffer () "Remove the current buffer from its clients' buffer list. @@ -1721,28 +1726,32 @@ server-save-buffers-kill-terminal With ARG non-nil, silently save all file-visiting buffers, then kill. If emacsclient was started with a list of filenames to edit, then -only these files will be asked to be saved." +only these files will be asked to be saved. + +If Emacs was started as a lazy daemon and this is the last client +connected to it, this will call `save-buffers-kill-emacs'." (let ((proc (frame-parameter nil 'client))) - (cond ((eq proc 'nowait) + (unless (or (eq proc 'nowait) (processp proc)) + (error "Invalid client frame")) + (if (and (eq (daemon-type) 'lazy) + (equal server-clients (unless (eq proc 'nowait) (list proc)))) + ;; If we're the last client connected to a lazy daemon, kill Emacs. + (save-buffers-kill-emacs arg) + (if (eq proc 'nowait) ;; Nowait frames have no client buffer list. - (if (cdr (frame-list)) - (progn (save-some-buffers arg) - (delete-frame)) - ;; 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))) - (t (error "Invalid client frame"))))) + (progn (save-some-buffers arg) + (delete-frame)) + (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)))))) (define-key ctl-x-map "#" 'server-edit) -- 2.25.1