6

I currently I have a couple of org-babel shell snippets to package up a build and push it to a server for later usage. This also handily keeps a reference to the last execution of the snippet so I can remember what was last uploaded and when.

I was thinking I could further automate my process by hooking into compilation-finish-functions to look-up a babel snippet and execute it on successful compilation. What's the best way to organise the babel snippets and call the snippets programmatically? I was wondering if I can use :tags: or if I can just call up the snippet by #+:NAME by searching all my org-agenda-files. I was planning in storing the target babel function in the project's .dir-locals.el.

It would also be nice to mark a snippet as trusted whilst it was unchanged so I didn't need to confirm every execution.

  • Maybe I'm just tired, but I had to read the second paragraph a few times to understand what was being asked. :-) So you want to find a code block by name or tag, across all agenda files? I didn't quite get what .dir-locals has to do with it. – Malabarba Sep 30 '14 at 15:01
  • 1
    @Malabarba I seem to understand that the question is about getting something like (invoke-babel-snippet name) at the end of a compilation. And the .dir-locals.el would help define name in that case. – Sigma Sep 30 '14 at 15:08
  • @Malabarba: what Sigma said, sorry for the confusing wording. I'll see if I can improve the language. – stsquad Sep 30 '14 at 15:34
4

For the first part, the following can move to a specific named snippet and execute it

(defun my/invoke-babel-named (name)
  (interactive)
  (save-excursion
    (org-babel-goto-named-src-block name)
    (org-babel-execute-src-block-maybe)))

You can define snippets as trusted/untrusted based on varying factors, however I don't think there is any built-in mechanism to trust based on content. The following should work based on limited testing (2 code blocks of different languages, making a few changes to ensure it re-prompted).

(defvar my/babel-hashes 'nil)
(defun my/babel-hashed-confirm (lang body)
  (let ((check (list lang (md5 body))))
    ;; If not hashed, prompt
    (if (not (member (list lang (md5 body)) my/babel-hashes))
        ;; Ask if you want to hash
        (if (yes-or-no-p "Store hash for block? ")
            ;; Hash is added, proceed with evaluation
            (progn
              (add-to-list 'my/babel-hashes check)
              'nil)
          ;; Return 't to prompt for evaluation
          't))))

(setq org-confirm-babel-evaluate 'my/babel-hashed-confirm)

org-babel-confirm-evaluate does not provide the code block name so the hash will be added for every change rather than stored on a per-block basis. The downside being frequent changes will lead to a very large hash. The upside being that reverting changes to the code block will still have the hash in memory if already accepted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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