0

There's an answer here for appending the current code block to an existing file.

I want to do the opposite, which is to prepend the current code block to an existing file. Could you please help?

1 Answer 1

1

I don't see a clever way to do what you want: you would have to change the org-babel-tangle function itself, or rather write your own function which would be almost the same as the org-babel-tangle function, but not quite. @Tobias's answer in the linked question locally redefines the delete-file function to ignore, so when org-babel-tangle is called, the file is not deleted and the block is just written to the existing file (it just so happens that it is written at the end of the file, so everything works out).

In your case you would, in addition, have to rewrite a portion of the org-babel-tangle function itself. So you would have to write a new function org-babel-tangle-prepend which is an almost exact copy of the org-babel-tangle function with two changes:

  • Delete the code that deletes the file. This is effectively what @Tobias does in a clever way in the linked answer, so he can reuse the existing org-babel-tangle function without changing it, but since you have to change the function anyway, you might as well physically delete the relevant lines. So the following code (around line 258 in the file ob-tangle.el in the current upstream version - you may have to look around that line to find the code in your version) should be deleted in the new function:
              ;; delete any old versions of file
              (and (file-exists-p file-name)
               (not (member file-name (mapcar #'car path-collector)))
               (delete-file file-name))
  • The code in lines 269-280 of ob-tangle.el (again that is in the current upstream version and you may have to look around to find it in your version) has to be changed.

The latter code looks like this in the original:

            ;; We avoid append-to-file as it does not work with tramp.
            (let ((content (buffer-string)))
              (with-temp-buffer
                (when (file-exists-p file-name)
                  (insert-file-contents file-name))
                (goto-char (point-max))
                ;; Handle :padlines unless first line in file
                (unless (or (string= "no" (cdr (assq :padline (nth 4 spec))))
                    (= (point) (point-min)))
                  (insert "\n"))
                (insert content)
                (write-region nil nil file-name))))

It needs to be changed to look like this in the new org-babel-tangle-prepend function:

            ;; We avoid append-to-file as it does not work with tramp.
            (let ((content (buffer-string)))
              (with-temp-buffer
                (insert content)
                ;; Handle :padlines unless first line in file
                (unless (or (string= "no" (cdr (assq :padline (nth 4 spec))))
                    (= (point) (point-min)))
                  (insert "\n"))

                (when (file-exists-p file-name)
                  (insert-file-contents file-name))

                (write-region nil nil file-name))))

This is just a slightly reordered version of the original code:

  • We first write the new code.
  • Add padlines if necessary.
  • Add the contents of the old file.
  • Write the whole thing back into the file.

Minimally tested.

Your Answer

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

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