0

I've been trying to work out if it's possible to tangle a file if it's not existent on the system. I came across Can Org Babel conditionally tangle code blocks based on system-type? which gave me a starting point, however when I do the following #+begin_src shell :tangle (when (not (file-exists-p "~/bin/eto")) ~/bin/eto) I get Wrong type argument: stringp, nil when I try to tangle the src block.

What am I doing wrong?

3
  • I'm confused. Do you want to tangle that shell block to ~/bin/eto? Then you simply need #+begin_src shell :tangle ~/bin/eto, right? Commented Sep 30, 2021 at 14:47
  • emacs.stackexchange.com/tags/elisp/info Commented Sep 30, 2021 at 16:44
  • @aadcg I only want it tangled when the file doesn't exist, so when I set up on a new system for the first time the src block will get tangled and no other time when I make changes to my config. Commented Oct 4, 2021 at 8:14

2 Answers 2

3

@dalanicolai's answer is correct but you still have a problem: the legal values of the :tangle header are the strings yes, no or a filename, (IOW, the argument always has to be a string), so your elisp snippet has to be more complicated:

#begin_src shell :tangle (if (not file-exists-p "foo") "foo" "bar") ... 

Your original snippet returns nil if the file exists, but nil is not a string. The modified snippet returns the string foo if foo does not exist, but it returns the string bar otherwise, so the :tangle header always gets a string argument and everybody is happy.

EDIT: The OP in a comment to the question mentions that the tangling should only happen the first time (i.e. when the file does not exist) and never again. So the header should read:

#begin_src shell :tangle (if (not file-exists-p "foo") "foo" "no") ... 
2
  • 1
    That would make sense. Thank you both NickD & dalanicolai Commented Oct 4, 2021 at 8:16
  • If this or the other answer has answered your question, please accept one or the other to indicate to others that there is an answer. Don't leave questions orphaned if at all possible. Commented Oct 6, 2021 at 11:48
1

From the org-documentation we find that the filename should be passed as a string (see section FILENAME), so you should place the latter ~/bin/eto between double quotes also.