From 563036eaf0924f4777f25e74e9f611419fc031cf Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Fri, 19 Nov 2021 19:49:38 -0800 Subject: [PATCH 1/2] Ensure killing an emacsclient terminal prompts to save files Previously, when using 'server-stop-automatically', killing an emacsclient terminal wouldn't prompt the user to save the files initially passed to emacsclient (unless it was the last client). * lisp/server.el (server-save-buffers-kill-terminal): Check 'server-stop-automatically' and handle killing Emas as needed. (server-stop-automatically--handle-delete-frame): Remove logic specific to 'save-buffers-kill-terminal'. --- lisp/server.el | 94 +++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/lisp/server.el b/lisp/server.el index 2f003a380a..e2d20b1b02 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1727,52 +1727,60 @@ server-save-buffers-kill-terminal If emacsclient was started with a list of filenames to edit, then only these files will be asked to be saved." - (if server-stop-automatically - (server-stop-automatically--handle-delete-frame (selected-frame)) - (let ((proc (frame-parameter nil 'client))) - (cond ((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")))))) + (let ((proc (frame-parameter nil 'client))) + (cond ((eq proc 'nowait) + ;; Nowait frames have no client buffer list. + (if (if server-stop-automatically + (cddr (frame-list)) + (cdr (frame-list))) + ;; If there are any other frames (excluding the daemon + ;; frame when `server-stop-automatically' is non-nil), + ;; only delete this frame. FIXME: It would be nice to + ;; delete any other frames created by this frame (as + ;; when killing the terminal of an ordinary client + ;; below), but we can't distinguish separate groups of + ;; nowait frames currently. + (progn (save-some-buffers arg) + (delete-frame)) + ;; If we're the last frame standing, kill Emacs. + (save-buffers-kill-emacs arg))) + ((processp proc) + (if (seq-some + (lambda (frame) + (let ((p (frame-parameter frame 'client))) + (unless (and server-stop-automatically (null p)) + (not (equal proc p))))) + (frame-list)) + ;; If there are any frames from other clients, only + ;; delete this client. If `server-stop-automatically' + ;; is nil, check for frames from the server process as + ;; well. + (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)) + ;; If all frames are from this client, kill Emacs. + (save-buffers-kill-emacs arg))) + (t (error "Invalid client frame"))))) (defun server-stop-automatically--handle-delete-frame (frame) "Handle deletion of FRAME when `server-stop-automatically' is used." - (when server-stop-automatically - (if (if (and (processp (frame-parameter frame 'client)) - (eq this-command 'save-buffers-kill-terminal)) - (progn - (dolist (f (frame-list)) - (when (and (eq (frame-parameter frame 'client) - (frame-parameter f 'client)) - (not (eq frame f))) - (set-frame-parameter f 'client nil) - (let ((server-stop-automatically nil)) - (delete-frame f)))) - (if (cddr (frame-list)) - (let ((server-stop-automatically nil)) - (delete-frame frame) - nil) - t)) - (null (cddr (frame-list)))) - (let ((server-stop-automatically nil)) - (save-buffers-kill-emacs) - (delete-frame frame))))) + (when (and ;; Check that the frame is a client frame. + ;; Note: `server-delete-client' sets `client' to nil + ;; before calling `delete-frame'. That's good, since we + ;; don't want to call `save-buffers-kill-emacs' in that + ;; case anyway. + (frame-parameter frame 'client) + (null (cddr (frame-list)))) + (save-buffers-kill-emacs))) (defun server-stop-automatically--maybe-kill-emacs () "Handle closing of Emacs daemon when `server-stop-automatically' is used." -- 2.25.1