Better Code Snippets with org-capture

30. April 2018

A question on /r/emacs inspired me to improve the template I was using for saving code snippets with org-capture. Previously, I’d been using the %^{prompt} expansion to manually enter the language of the snippet; this poster made me realise that could be automated.

They also introuduced me to which-function, which is particularly helpful when you’re only saving a portion of a larger method. Click through for the elisp I wrote.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(defun my/org-capture-get-src-block-string (major-mode)
  "Given a major mode symbol, return the associated org-src block
string that will enable syntax highlighting for that language

E.g. tuareg-mode will return 'ocaml', python-mode 'python', etc..."

  (let ((mm (intern (replace-regexp-in-string "-mode" "" (format "%s" major-mode)))))
    (or (car (rassoc mm org-src-lang-modes)) (format "%s" mm))))

(defun my/org-capture-code-snippet (f)
  (with-current-buffer (find-buffer-visiting f)
    (let ((code-snippet (buffer-substring-no-properties (mark) (- (point) 1)))
          (func-name (which-function))
          (file-name (buffer-file-name))
          (line-number (line-number-at-pos (region-beginning)))
          (org-src-mode (my/org-capture-get-src-block-string major-mode)))
      (format
       "file:%s::%s
In ~%s~:
#+BEGIN_SRC %s
%s
#+END_SRC"
       file-name
       line-number
       func-name
       org-src-mode
       code-snippet))))

;; Capture Template
("s" "code snippet" entry (file ,(my/org-dir-file "snippets.org"))
 "* %?\n%(my/org-capture-code-snippet \"%F\")")

Invoking the template will give you a capture window with the following content and the point located at |, like so:

1
2
3
4
5
6
7
8
* |
file:/Users/Nick/.homesick/repos/dotfiles/home/.spacemacs::305
In ~my/org-dir-file~:
#+BEGIN_SRC elisp
    (defun my/org-dir-file (name)
      "Prepend name with path to the org-directory root"
      (concat org-directory name))
#+END_SRC