0

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.

Drew
  • 75,699
  • 9
  • 109
  • 225
mle0312
  • 295
  • 1
  • 8

1 Answers1

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 ()
  (interactive)
  (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.

NickD
  • 27,023
  • 3
  • 23
  • 42
  • This works but whenever I am trying to write the letter "q", emacs would quit that frame – mle0312 May 01 '20 at 18:00
  • What does "quit that frame" mean? Is the frame closed? Does a different frame become current? – NickD May 01 '20 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 May 02 '20 at 02:38
  • Added some suggestions to help you debug the problem. – NickD May 02 '20 at 04:43