Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Gracefully save buffers and stop emacs daemon.

563 views
Skip to first unread message

amicitas

unread,
Aug 21, 2009, 5:21:41 PM8/21/09
to
I am looking for a way to stop the emacs daemon, however, before
stopping I want the following things to happen:
1. Check if any frames are open, if so ask if I still want to stop
emacs
2. Check if there are any modified buffers, if so ask if I want to
save

The closest solution I have found so far is to run:

emacsclient -c -e '(save-buffers-kill-emacs)'

The problem with this is that it always displays the following two
prompts, even if no clients were active before:
This Emacs session has clients; exit anyway? (yes or no)
The current server still has clients; delete them? (yes or no)

I can remove (or modify) the first prompt by modifying the 'kill-emacs-
query-functions hooks, however I cannot figure out how to remove the
second prompt.


Does anyone already have a solution for this?
If not would anyone be willing to help me write a function that will
provide what I want?


-- Novi

Joost Kremers

unread,
Aug 21, 2009, 6:48:58 PM8/21/09
to
amicitas wrote:
> The closest solution I have found so far is to run:
>
> emacsclient -c -e '(save-buffers-kill-emacs)'
>
> The problem with this is that it always displays the following two
> prompts, even if no clients were active before:
> This Emacs session has clients; exit anyway? (yes or no)
> The current server still has clients; delete them? (yes or no)

well, the call to emacsclient creates a client... ;-)

presumably the prompts will go away if you call emacsclient with the -n switch,
which instructs it not to wait but exit immediately.

> I can remove (or modify) the first prompt by modifying the 'kill-emacs-
> query-functions hooks,

there shouldn't be any need for that once you pass -n.


--
Joost Kremers joostk...@yahoo.com
Selbst in die Unterwelt dringt durch Spalten Licht
EN:SiS(9)

A.Politz

unread,
Aug 21, 2009, 7:08:32 PM8/21/09
to
On Aug 22, 12:48 am, Joost Kremers <joostkrem...@yahoo.com> wrote:
> amicitas wrote:
> > The closest solution I have found so far is to run:
>
> > emacsclient -c -e '(save-buffers-kill-emacs)'
>
> > The problem with this is that it always displays the following two
> > prompts, even if no clients were active before:
> > This Emacs session has clients; exit anyway? (yes or no)
> > The current server still has clients; delete them? (yes or no)
>
> well, the call to emacsclient creates a client... ;-)
>
> presumably the prompts will go away if you call emacsclient with the -n switch,
> which instructs it not to wait but exit immediately.

That does not appear to work for eval arguments. Maybe a timer can
help.

$ ec -e "(run-with-timer 0 0 'save-buffers-kill-emacs)"

-ap

amicitas

unread,
Aug 21, 2009, 9:17:43 PM8/21/09
to
Unfortunately using -n does not have any effect if -e is used.
I am not sure if this is the intended behavior or a bug.

I have created a function that will almost do what I want,
the only problem is that I can't figure out how to create a frame if
one does not already exist.

The problem is if I use
emacsclient -e '(my-shutdown-function)'
and no frames currently exist, then make-frame has no effect.

If I instead use
emacsclient -c -e '(my-shutdown-function)'
Then a new frame is always created even if I do not not need any
prompts.

(Note: I don't want to use the -t option since on computer (an old
mac) terminal scrolling is very slow.)

Any ideas?

-Novi

> Joost Kremers                                      joostkrem...@yahoo.com

amicitas

unread,
Aug 21, 2009, 11:26:37 PM8/21/09
to
Ok I finally came up with a solution (and now I know more lisp as
well).

To gracefully shut down the emacs daemon I used the following command:

emacsclient -e '(client-save-kill-emacs)'

The function client-save-kill-emacs is defined at the bottom of this
message. I placed it into my .emacs file.

This function will do the following:
1. Check if any frames are open.
2. Check if any clients are active
3. Check if any buffers are modified.

If any of the above are true a new frame is opened (as an x window).
The user is prompted if clients or frames are present, then prompted
to save any modified buffers.

If you have any questions let me know.


-- Novi

(defun client-save-kill-emacs()
" This is a function that can bu used to shutdown save buffers and
shutdown the emacs daemon. It should be called using
emacsclient -e '(client-save-kill-emacs)'. This function will
check to see if there are any modified buffers or active clients
or frame. If so an x window will be opened and the user will
be prompted."

(let (new-frame modified-buffers active-clients-or-frames)

; Check if there are modified buffers or active clients or frames.
(setq modified-buffers (modified-buffers-exist))
(setq active-clients-or-frames ( or (> (length server-clients) 1)
(> (length (frame-list)) 1)
))

; Create a new frame if prompts are needed.
(when (or modified-buffers active-clients-or-frames)
(progn
(message "window-system: %s" (window-system))
(when (not (eq (window-system) "x"))
(x-initialize-window-system))
(select-frame (make-frame '((window-system . x))))))


; Save the current frame.
(setq new-frame (selected-frame))


; When displaying the number of clients and frames:
; subtract 1 from the clients for this client.
; subtract 2 from the frames this frame (that we just created) and
the default frame.
(when ( or (not active-clients-or-frames)
(yes-or-no-p (format "There are currently %d clients and %d
frames. Exit anyway?" (- (length server-clients) 1) (- (length (frame-
list)) 2))))

; If the user quits during the save dialog then don't exit
emacs.
; Still close the terminal though.
(let((inhibit-quit t))
; Save buffers
(with-local-quit
(save-some-buffers))

(if quit-flag
(setq quit-flag nil)
; Kill all remaining clients
(progn
(dolist (client server-clients)
(server-delete-client client))
; Exit emacs
(kill-emacs)))
))

; If we made a frame then kill it.
(when (or modified-buffers active-clients-or-frames) (delete-frame
new-frame))
)
)


(defun modified-buffers-exist()
"This function will check to see if there are any buffers
that have been modified. It will return true if there are
and nil otherwise. Buffers that have buffer-offer-save set to
nil are ignored."
(let (modified-found)
(dolist (buffer (buffer-list))
(when (and (buffer-live-p buffer)
(buffer-modified-p buffer)
(not (buffer-base-buffer buffer))
(or
(buffer-file-name buffer)
(progn
(set-buffer buffer)
(and buffer-offer-save (> (buffer-size) 0))))
)
(setq modified-found t)
)
)
modified-found
)
)

0 new messages