Home GitHub Patreon
Discussions RSS Twitter

Maximize the org-capture buffer

I'm a heavy user of org-capture and one behaviour of it always annoyed me: instead of having the capture popup take the whole screen, it opens a new window. This window is often small and somewhat inconvenient. I like to do one thing at a time and so when I'm filing a note or capturing an idea I want to see only the capture buffer and no other distractions. As we all know distractions kill flow and so we should always find ways to get all the nonsense out of the way.

Recently I've started using this awesome extension to capture web content from firefox (works with chrome too). I've tweaked the protocol handler to not only invoke emacsclient "%u" but also set some frame properties for later.

Here's the bash script I use as the handler

#!/bin/bash
emacsclient -c -F '((name . "org-protocol-capture"))' "$@"

The -F option sets the frame parameters with the specified alist. Here I only set the name to "org-protocol-capture" I make sure to open new frame with -c.

Org capture provides several hooks we can use to tweak the default behaviour.

First, we make sure the capture buffer window takes the whole frame. To do this, we first save the current window configuration and then delete all other windows on entering the org-capture-mode. Unfortunately there is no "before anything happens" hook so we use a before advice instead.

(defvar my-org-capture-before-config nil
  "Window configuration before `org-capture'.")

(defadvice org-capture (before save-config activate)
  "Save the window configuration before `org-capture'."
  (setq my-org-capture-before-config (current-window-configuration)))

(add-hook 'org-capture-mode-hook 'delete-other-windows)

Next, after we finish the capture work flow (either with success or cancellation) we restore the window configuration saved previously.

Finally, let's make sure that after we refile the captured content the frame which was possibly created (if capture was invoked with org-protocol) closes itself automatically. This keeps us in the flow and keeps the distraction of killing the frame manually away. We use the frame name to decide if we wish to kill the frame or not (this is the -F argument from above).

(defun my-org-capture-cleanup ()
  "Clean up the frame created while capturing via org-protocol."
  ;; In case we run capture from emacs itself and not an external app,
  ;; we want to restore the old window config
  (when my-org-capture-before-config
    (set-window-configuration my-org-capture-before-config))
  (-when-let ((&alist 'name name) (frame-parameters))
    (when (equal name "org-protocol-capture")
      (delete-frame))))

(add-hook 'org-capture-after-finalize-hook 'my-org-capture-cleanup)

With these tweaks the whole capture experience is much more streamlined for me. When I invoke capture from anywhere (Emacs or via org-protocol), I get a full screen frame/window where I can quickly jot my thoughts. After I'm finished everything restores itself to the previous state and I can continue with whatever task I was consumed prior to the capture process.


Published at: 2017-09-02 22:02 Last updated at: 2023-02-08 15:59
Found a typo? Edit on GitHub!