Org Mode: Inserting a function definition

While nudging jcs to add a definition of jcs-insert-url to the blog post about Making Things Easier, I realized it might be handy to have a quick function for inserting a function definition without thinking about where it’s defined. This tries to use the definition from the source, and it can fall back to using the stored function definition if necessary. There’s probably a better way to do this, but this was small and fun to write. =)

Naturally, I used it to insert itself:

(defun my/org-insert-defun (function)
  "Inserts an Org source block with the definition for FUNCTION."
  (interactive (find-function-read))
  (let* ((buffer-point (condition-case nil (find-definition-noselect function nil) (error nil)))
         (new-buf (car buffer-point))
         (new-point (cdr buffer-point))
    (if buffer-point        
      (with-current-buffer new-buf ;; Try to get original definition
          (goto-char new-point)
          (setq definition (buffer-substring-no-properties (point) (save-excursion (end-of-defun) (point))))))
      ;; Fallback: Print function definition
      (setq definition (concat (prin1-to-string (symbol-function function)) "\n")))
    (insert "#+begin_src emacs-lisp\n" definition "#+end_src\n")))

One Pingback/Trackback

  • jcs

    That’s very nice and definitely worth stealing. It nicely illustrates the point I was trying to make in the original post: look for ways to make things easier. I always just bring up my init.el and copy the definition into the new buffer. This is much easier.

  • Tomas Zellerin

    Very nice indeed. Another option – not more complicated – is to create a named Babel block that takes function name as a parameter and expands to the source elisp block. Then it can be used with #+CALL and one can control updates to definition (unless historical version is what you want). But maybe one would still want to add a function to select the function to expand and write the CALL :)

  • Pingback: More Making Things Easier | Irreal()