5

I would like a more handy shortcut to basically the system's alt-f4 to close the current emacs window. delete-frame is not far from that, but it refuses to close the last frame: Attempt to delete the sole visible or iconified frame.

How could I get a function that would override that safety? Note that I'm using emacs-client with emacsclient -c "$@" --alternate-editor= & and I would like that the server stays running -- with is the behaviour with alt-f4.

I'm not interested in OS shortcuts because I'm using spacemacs and I can get better shortcuts, like SPC o F for instance.

Emmanuel Touzery
  • 961
  • 1
  • 8
  • 17

3 Answers3

6

I think @harpo answered the question adequately in a comment. Here's some additional info, in case it helps.

You can bind a key to a command that deletes the frame, and if error "Attempt..." is raised then kill Emacs instead. For that, use condition-case to handle the error. That way you can use a single key to either delete a frame or, if it is the last one, kill Emacs.

For example:

(defun delete-frame-or-kill-emacs ()
  "Delete the selected frame.  If the last one, kill Emacs."
  (interactive)
  (condition-case nil (delete-frame) (error (kill-emacs))))

(global-set-key [remap delete-frame] 'delete-frame-or-kill-emacs)

(However, I wouldn't recommend using such a command, as it is too easy to accidentally kill Emacs.)


Update after your comment.

If you are using emacsserver and emacsclient then try (save-buffers-kill-terminal) instead of (kill-emacs). That should delete the frame but keep the server alive. I didn't see that you had specified that you were in such a context. (save-buffers-kill-terminal is bound to C-x C-c in a client frame.) See the Emacs manual, node emacsclient Options.

And in that case, C-x C-c should be all you need - it sounds like it does just what you are asking for. And if you prefer that it be invoked from another key then just bind that key to save-buffers-kill-terminal.

Drew
  • 77,472
  • 10
  • 114
  • 243
  • that's pretty close now! however the problem is that that also kills the emacs server... as i said, I would like that the emacs-server keeps running. – Emmanuel Touzery Jun 27 '15 at 20:46
  • not quite, save-buffers-kill-terminal seems to kill two frames if I have two open. so i probably still want the condition, between delete-frame and save-buffers-kill-terminal. I'll try that now. – Emmanuel Touzery Jun 27 '15 at 22:12
  • that's it, the condition between save-buffers-kill-terminal and delete-frame is exactly what I wanted! – Emmanuel Touzery Jun 27 '15 at 22:15
2

It sounds like what you really want is kill-emacs. In Windows, it's Ctrl+F4 that closes the "frame" (in apps that can have multiple windows), and it wouldn't close the app in any case that I can think of. Whereas Alt+F4 will close all of the child windows regardless (after prompting to save). So actually Emacs is parallel with this.

(Answer moved from comment on question.)

harpo
  • 181
  • 5
  • yes as @Drew pointed out I'd like to kill the whole emacs only if it's the last frame open (and also that emacs-server keeps running) – Emmanuel Touzery Jun 27 '15 at 20:44
1

Since you are using Spacemacs, I suppose you set dotspacemacs-persistent-server to t. Then you should be able to kill the current frame with SPC q z. Note that I don't use that myself and I cannot verify it right now. There is also some documentation about it there: https://github.com/syl20bnr/spacemacs/blob/5baa70057b4b2bfebce3ec8918101a252e00c405/doc/DOCUMENTATION.org#keeping-the-server-alive

syl20bnr
  • 2,095
  • 12
  • 22
  • it works as I want even with dotspacemacs-persistent-server at nil :-) But I'll change it to t just in case. So, great, i'll try to get used to this one then... – Emmanuel Touzery Jun 28 '15 at 17:02