3

I like to start Emacs as part of a login script and leave it running for the duration of my login session (which is typically weeks).

I have scripts to call emacs-client which will allow me to use a file-manager or Windows Explorer to locate files and right-click to edit them in Emacs.

I often end up with a lot of emacs windows (frames) open and I like to just be able to close them by clicking on the MS-Windows or KDE X button at the top-right.

The trouble is, if the window is the last one, this will shut down emacs which will lose all kinds of interesting history information.

As a work-around I use C-x 5 0 which won't let me close the last frame but this is often not as convenient as using the mouse

Does anyone know how to configure Emacs so that it can intercept the Window-Close button of the last frame to either request confirmation or simply disallow it?

On MS-Windows, disallowing closing of the last window may cause logoff to hang if emacs is still running but I'm not too worried about that.

4

Two ways I can think of, but I'm sure there are more. The function that is called when you click the delete-frame button (upper-right corner [X] on Windows) is handle-delete-frame. You can advise that command or you can replace it as the function that handles that click by some other command.

To advise it:

    (defadvice handle-delete-frame (around my-handle-delete-frame-advice activate)
      "Ask for confirmation before deleting the last frame"
      (let ((frame   (posn-window (event-start event)))
            (numfrs  (length (visible-frame-list))))
        (when (or (> numfrs 1) (y-or-n-p "Really exit Emacs? "))
          ad-do-it)))

To replace it:

    (defun my-handle-delete-frame (event)
      "Ask for confirmation before deleting the last frame"
      (interactive "e")
      (let ((frame   (posn-window (event-start event)))
            (numfrs  (length (visible-frame-list))))
        (cond ((> numfrs 1) (delete-frame frame t))
              ((y-or-n-p "Really exit Emacs? ") (save-buffers-kill-emacs)))))

    (define-key special-event-map [delete-frame] 'my-handle-delete-frame)

Don't do both of these; just do one of them.

  • This seems to work well on Windows. I'll try it out for a few days and also in KDE before I accept your answer. – Adrian Pronk Aug 28 '11 at 22:40
  • Option 1 prompts when I close the last visible frame. I think I should use frame-list rather than visible-frame-list to prompt at the last frame. Or is there some tricky problem with using frame-list? – Adrian Pronk Aug 29 '11 at 9:58
  • Yes, you can use frame-list -- that makes more sense, actually. – Drew Sep 5 '11 at 23:15
3

You should use the emacs daemon: launch Emacs as

       emacs -d

Then Emacs will be launch in background, waiting for emacsclient to open a new windows. The Emacs daemon won't close when its last windows will be closed.

  • 1
    It looks like I'll be able to use emacs --daemon on Linux but NTEmacs doesn't seem to support that option. I'll keep at it... – Adrian Pronk Jul 11 '11 at 10:04
0

And, here's an update which uses Drew's 'my-handle-delete-frame' function, in order to remove the 'Really kill emacs' pop-up necessary in the original version, and enable one to simply exit when the 'X button' is now clicked.

;; The function that is called when you click the delete-frame button
;; (upper-right corner [X] on Windows) is handle-delete-frame. You can advise
;; that command or you can replace it with a function that handles that click
;; via some other command. Therefore, whenever the 'X button' is now clicked
;; the event now is handled here, and invokes kill-emacs, which replaced
;; previous code. The user no longer has to deal w/'Really exit emacs' pop-up.
  (defun exit-emacs-via-del-frm (event)
      "No longer ask for confirmation before deleting the last frame; simply exit"
      (interactive "e")
      (let ((frame   (posn-window (event-start event)))
            (numfrs  (length (visible-frame-list))))
            (kill-emacs) ) )

    (define-key special-event-map [delete-frame] 'exit-emacs-via-del-frm)
  • 1
    It's not clear to me what you are doing here, or even what you are trying to accomplish.  It seems like you are just restoring the default behavior; i.e., cancelling out Drew's answer. Please do not respond in comments; edit your answer to make it clearer and more complete. – Scott Dec 3 '18 at 3:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.