3

Is there a keybinding (or way to define one) to call a source block by its name in the current org-mode buffer?

Currently, I move mouse pointer inside the code block and then press C-c C-c. But this jumping is becoming distracting as the document gets larger and larger.

2 Answers 2

3

Yes, you can write a function that calls org-sbe with the source block name and its arguments and bind it to your favorite key:

#+name: call-me
#+begin_src emacs-lisp :var x="foo"
(message x)
#+end_src

#+begin_src emacs-lisp
  (defun call-sb ()
     (interactive)
     (org-sbe call-me (x $"bar")))

  (define-key org-mode-map (kbd "C-c z") #'call-sb)

#+end_src

Here C-c z is bound to the command call-sb which executess the source block call-me with argument x bound to the value "bar" as a string (without the $ sign, it is interpreted as a reference to the name bar in the Org mode buffer). org-sbe is a macro, so its arguments are passed to it unevaluated (in contrast to a function) and it can play games with them (like the $ interpretation).

See the doc string for org-sbe:


(org-sbe SOURCE-BLOCK &rest VARIABLES)

Return the results of calling SOURCE-BLOCK with VARIABLES.

Each element of VARIABLES should be a list of two elements: the
first element is the name of the variable and second element is a
string of its value.

So this ‘org-sbe’ construct

 (org-sbe "source-block" (n $2) (m 3))

is the equivalent of the following source code block:

 #+begin_src emacs-lisp :var results=source-block(n=val_at_col_2, m=3) :results silent
 results
 #+end_src

NOTE: The quotation marks around the function name,
’source-block’, are optional.

NOTE: By default, string variable names are interpreted as
references to source-code blocks, to force interpretation of a
cell’s value as a string, prefix the identifier a "$" (e.g.,
"$$2" instead of "$2" or "$@2$2" instead of "@2$2").

NOTE: It is also possible to pass header arguments to the code
block.  In this case a table cell should hold the string value of
the header argument which can then be passed before all variables
as shown in the example below.

| 1 | 2 | :file nothing.png | nothing.png |
#+TBLFM: @1$4='(org-sbe test-sbe $3 (x $1) (y $2))
4

Are you sure you need new key-bindings? Did you know that you can call code blocks from other code blocks? See https://orgmode.org/manual/Evaluating-Code-Blocks.html

You can bind code block by name in the header (e.g. :var x=random) to a variable, and call it by using the variable within the block.

Also, especially if this is for debugging purposes, you can get rid of scrolling by adding #+CALL: lines before the block you are working with.

Using your example, place line #+CALL: call-me() somewhere in the same document and execute it with C-c C-c. To pass an argument, try #+CALL: call-me(x="bar").

3
  • Could you explain with an example how #+CALL works? I tried reading the documentation and found it hard to figure out. Commented Mar 18, 2021 at 14:06
  • 1
    The idea is that instead of moving somewhere else in the document to execute the code block, you have a call-line somewhere closer to where you work. Using your example, place line #+CALL: call-me() somewhere and execute it with C-c C-c. To pass an argument, try #+CALL: call-me(x="bar").
    – Heikki
    Commented Mar 20, 2021 at 10:04
  • 2
    Added the example code paragraph to the answer itself which is the correct place for it.
    – Heikki
    Commented Mar 20, 2021 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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