I have this function:

(defun org-agenda-show-agenda-and-todo (&optional arg)
    (interactive "p")
    (org-agenda arg "n"))

When calls, it will toggle a window with all of my current agenda and todo, like the pic below: enter image description here

As you can see, it defaults to open a new window in a new vertical split. If i want to close this window, I can just press q. The problem comes when I'm already working with 2 windows, like this:

| windows 1 |  windows 2 |
|           |            | 

If I call the same function, the org agenda and todo window would occupy window 2. So, like this:

| windows 1 |  org-agenda list |
|           |                  | 

When I press q, the org-agenda list window would close, and so does my window 2 split. In other words, I am left with a single window with only window 1.

Is there a way or an alternative to show all of my agenda and list without disrupting the current layout of my windows arrangement? I am thinking of something similar to ivy list bookmark, which you can see in the pic below:

enter image description here

Here, I can peek at my bookmark and just choose which one I want. If I want to stop peeking, I press Esc and it goes away and my window arrangement is kept.

1 Answer 1


Define a function similar to the one that you want, but save the current frame configuration in some variable:

(defvar my-pre-agenda-frame-configuration nil)

(defun org-agenda-show-agenda-and-todo (&optional arg)
    (interactive "p")
    (setq my-pre-agenda-frame-configuration (current-frame-configuration))
    (org-agenda arg "n"))

Then define a modified function to quit the agenda that restores the saved frame configuration if it is non-nil:

(defun my-org-agenda-quit ()
  (if my-pre-agenda-frame-configuration
    (set-frame-configuration my-pre-agenda-frame-configuration))
  (setq my-pre-agenda-frame-configuration nil))

Finally, bind the modified agenda-quit function to q in the agenda keymap:

(define-key org-agenda-keymap "q" 'my-org-agenda-quit)

If you use Q to exit the agenda as well, you might want to redefine that function and rebind the key as well.

EDIT: in response to the comment, can you reproduce that behavior starting with emacs -q -l minimal.el with the file minimal.el containing

    (load "org-agenda")

and the code above? If that works, there is something wrong with your init file: you will have to debug that, since I certainly cannot. If that does not work, then I'm not sure what the problem could be: the above works perfectly in my experiments.

The code above only modifies the binding of q in the keymap that org-agenda uses. In all other modes, q is unchanged. So if you open a text file (e.g. in fundamental mode, or some text mode including org-mode), and you do C-h c q it should say that q runs the command self-insert-command (or org-self-insert-command if the mode is org-mode). But if you do the same thing in the agenda buffer, it should say q runs the command my-org-agenda-quit.

  • This works but whenever I am trying to write the letter "q", emacs would quit that frame
    – mle0312
    Commented May 1, 2020 at 18:00
  • What does "quit that frame" mean? Is the frame closed? Does a different frame become current?
    – NickD
    Commented May 1, 2020 at 19:03
  • Yes the frame would close. What i mean is if I split vertical, then open the agenda view, then use "q" to quit agenda view, I would get back the split views. This is fine. However, says I have one window opens, no split and no agenda view. If I try to type "q" in some text file, then emacs would close current frame.
    – mle0312
    Commented May 2, 2020 at 2:38
  • Added some suggestions to help you debug the problem.
    – NickD
    Commented May 2, 2020 at 4:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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