Capturing into org-mode from Chromium

org-protocol provides a way to capture information into org-mode from external sources, such as your browser. I like to be able to add TODO items related to webpages (e.g., something I want read at a later date).

Following the org-protocol guide I added the following bookmark in Chromium.

javascript:location.href='org-protocol://capture://W/'+
    encodeURIComponent(location.href)+'/'+
    encodeURIComponent(document.title)+'/'+
    encodeURIComponent(window.getSelection())

The ‘W’ indicates which template in org-capture-templates should be used and the other parts harvest the URL, page title, and any text I may have selected. In this case, my capture template is

("W" "Web TODO" entry (file org-default-notes-file)
 "* TODO %?\n%U\n%a\n")

I registered emacsclient to handle org-protocol links by creating a file at

~/.local/share/applications/emacsclient.desktop

with the following content.

[Desktop Entry]
Name=Emacs Client
Exec=emacsclient -c -n %u
Icon=emacs-icon
Type=Application
Terminal=false
MimeType=x-scheme-handler/org-protocol;

The -c tells emacsclient to make a new frame for me. But I want to make sure that I get a frame with one window (just the capture buffer) and that once I finish the capture the frame will vanish. To achieve that, I added the following to my org-mode configuration.

(defun jws/org-protocol-capture-p ()
  "Return true if this capture was initiated via org-protocol."
  (equal (buffer-name (org-capture-get :original-buffer)) " *server*"))

(defun jws/org-capture-after-finalize ()
  "Delete frame if capture was initiated via org-protocol"
  (if (jws/org-protocol-capture-p) (delete-frame)))

(defun jws/org-capture-initialize ()
  "Make sure frame has only one window if capture was initiated via org-protocol"
  (if (jws/org-protocol-capture-p) (delete-other-windows)))

(add-hook 'org-capture-mode-hook 'jws/org-capture-initialize)
(add-hook 'org-capture-after-finalize-hook 'jws/org-capture-after-finalize)