1

This answer shows how to define a command that executes a named org-babel source block. If you want to do this for all named source blocks in a file, you could define one command per block. That's cumbersome.

I'm looking for a function that defines commands for all named blocks in a given set of files.

  • the function should be placed in init.el to define commands for all named source blocks in a set of files
  • the command names should prefix something like 'my-org-babel-' to all block names
  • in case of duplicate block names, the latest one encountered can be retained
1
2

Here is some code to do almost (but not quite) everything you want. The following two functions are to be added to your init file:

(defun my-org-babel-make-func (name)
   "Construct a string defining the function, then parse the
   string into a Lisp s-expression and eval that to actually
   define the function."
   (let ((s (format "(defun my-org-babel-%s () (interactive) (org-sbe \"%s\"))"
             name name)))
      (eval (read s))))

(defun my-org-babel-function-maker(filename)
   "Map the form over all the code blocks in the file. The form
   gets the name of the block and if non-nil, calls the make-func function
   to define the function for that name."
   (org-babel-map-src-blocks filename
     (let ((name (plist-get (cadr (org-element-at-point)) :name)))
        (when name
           (my-org-babel-make-func name))))
      nil)

I hope the comments are enough to convey what the functions are doing.

Then if you have an Org mode file foo.org with named code blocks like this:

* foo

  #+name: hello
  #+begin_src emacs-lisp
  "Hello"
  #+end_src

  #+name: good-bye
  #+begin_src emacs-lisp
  "Good Bye"
  #+end_src

you can execute (my-org-babel-function-maker "foo.org") and then you should have commands my-org-babel-hello and my-org-babel-good-bye that you can execute with M-x my-org-babel-hello or M-x my-org-babel-good-bye.

If you want this to be done when you open the file you can use a file local variables block to execute the function maker when the file is opened:

... named code blocks as above ...

* COMMENT Local variables

  # Local variables:
  # eval: (my-org-babel-function-maker (buffer-file-name))
  # End:

Caveats:

  • no error checking
  • blocks with duplicate names are not handled the way you want: org-sbe will execute the named code block - if there is more than one code block with that name, it will run whichever one it wants: which one that is depends on the implementation of org-sbe and is outside the scope of this answer. I would suggest you avoid blocks with the same name in the file.
  • it would be nice if these functions were defined locally for this file only, but that's not the way it works: functions are global in scope in Emacs Lisp, so my-org-babel-hello will exist everywhere. If you execute it in a different file that has a code block named hello, it will happily run that code block; and if there is no such code block, it will complain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.