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\"))"
(eval (read s))))
"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."
(let ((name (plist-get (cadr (org-element-at-point)) :name)))
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:
you can execute
(my-org-babel-function-maker "foo.org") and then you should have commands
my-org-babel-good-bye that you can execute with
M-x my-org-babel-hello or
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))
- 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.