0

I am using org-roam to store templates that I use frequently. I got tired of copying the templates manually into my current buffer so I decided to write a helper function to automate the process. I came up with the following code. However, it seems like it stops at the (org-copy-subtree) function since it the kill ring is empty and it does not return to the correct buffer. It works when I type the commands manually though.

    (defun paste-checklist ()
      "Paste entry from org-roam notes into the current buffer."
      (interactive)
      (org-roam-node-find) ;; prompt for node name and visit it
      (beginning-of-buffer) ;; move point to first entry of node
      (org-next-visible-heading)
      (org-copy-subtree) ;; copy subtree to kill ring
      (previous-buffer) ;; go to previous buffer
      ;; (switch-to-buffer (other-buffer))
      (org-paste-subtree))
3
  • Specify what you mean by "it doesn't work".
    – Drew
    Oct 19, 2023 at 14:11
  • thanks for pointing it out. I edited the question to be more descriptive.
    – leonardo
    Oct 19, 2023 at 16:38
  • In order to store and insert templates I would recommend using Skeleton instead of org-roam.
    – crocefisso
    Oct 19, 2023 at 20:25

1 Answer 1

0

org-next-visible-heading needs an argument: the argument is not optional. If I do C-h f org-next-visible-heading, I get the following info:

org-next-visible-heading is an interactive Lisp function in ‘org.el’.

(org-next-visible-heading ARG)

Move to the next visible heading line.
With ARG, repeats or can move backward if negative.

The last sentence is somewhat misleading (see below for details), but the important thing is that the ARG is NOT marked &optional: it is required.

So the solution is to change the call like this:

    ...
    (org-next-visible-heading 1)
    ...

That will make your function behave exactly the same way as doing each step manually.


You can debug it by turning on the debug-on-error flag: just say M-x toggle-debug-on-error and then run the function again: M-x paste-checklist. You will get a backtrace which looks something like this:

Debugger entered--Lisp error: (wrong-number-of-arguments ....)
  org-next-visible-heading()
  paste-checklist()
  ...

where I have elided a long, but ultimately unimportant, mess of information. The important thing is that the backtrace fingers org-next-visible-heading as the function that produces the error (you read the backtrace from the top down).


Now to explain why you need to add that argument.

I presume when you were testing by hand, you called the function interactively with M-x org-next-visible-heading and that worked. But even though you called it without any visible arguments, you cannot assume that when you call the function from Lisp, you can call it without arguments: if you do M-: (org-next-visible-argument) which just evaluates the expression, you will get the error above.

You need to examine the definition of the function in some detail to figure out how to call it from Lisp. In this case, the function is defined as follows (I only show the first few lines and elide the rest):

(defun org-next-visible-heading (arg)
  "Move to the next visible heading line.
With ARG, repeats or can move backward if negative."
  (interactive "p")
  ...

and the (interactive "p") specification says (do C-h f interactive to see the whole doc string):

...
p -- Prefix arg converted to number.  Does not do I/O.
...

and that specification turns out to mean that if you call the function interactively and don't use a prefix argument, then the argument gets a default value of 1. So when you call it from Lisp, you have to use (org-next-visible-heading 1).

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.