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
.