Emacs tidal babel

Hi all, this code makes me happy to run tidal code within org babel blocks, just add it to your init.el, and make a block look like this:

#+src_begin tidal 
d1 $ ...
#+src_end

here is the elisp code for making it work:

(defun org-babel-execute:tidal (body params)
  "Execute a block of TidalCycles code with org-babel."
  (with-temp-buffer
    (insert body)
    (set-mark (point-min))
    (goto-char (point-max))
    (tidal-mode)
    (tidal-run-multiple-lines)
    nil))

(add-to-list 'org-babel-tangle-lang-exts '("tidal" . "tidal"))

;; Set default header arguments for Tidal blocks
(setq org-babel-default-header-args:tidal '((:results . "none")))

enjoy

2 Likes

oh wait this opens up so many possibilities, thank you!

been waiting for an excuse to get started with org-roam and I think this is it... so many possibilities...

1 Like

here is a updated version. Now you can have more separate tidal commands in a src block, and run them individually when cursor on in and C-c C-c

EDIT: it is still a little bit messy. consider it as WIP.

(defun org-babel-execute:tidal (body params)
  "Execute a block of TidalCycles code with org-babel. Execute only the command under the cursor."
  (let ((element (org-element-context)))
    (if (and (eq (org-element-type element) 'src-block)
             (string= (org-element-property :language element) "tidal"))
        (let* ((block-start (save-excursion
                              (goto-char (org-element-property :begin element))
                              (forward-line 1)
                              (point)))
               (block-end (save-excursion
                            (goto-char (org-element-property :end element))
                            (forward-line -2)
                            (point)))
               (p (point)))
          (if (and (>= p block-start) (<= p block-end))
              (let ((command-start (save-excursion
                                     (goto-char p)
                                     (beginning-of-line)
                                     (while (and (not (bobp))
                                                 (not (looking-at "^[[:space:]]*$"))
                                                 (> (point) block-start))
                                       (forward-line -1))
                                     (if (bobp) block-start (point))))
                    (command-end (save-excursion
                                   (goto-char p)
                                   (end-of-line)
                                   (while (and (not (eobp))
                                               (not (looking-at "^[[:space:]]*$"))
                                               (< (point) block-end))
                                     (forward-line 1))
                                   (forward-line -1)
                                   (end-of-line)
                                   (if (= (point) (- block-end 1)) ;; get rid of #+src_end
                                        (progn
                                        (forward-line -1)
                                        (end-of-line)))
                                   (point))))

                (let ((eval-body (buffer-substring-no-properties command-start command-end)))
                    (with-temp-buffer
                    (insert eval-body)
                    (set-mark (point-min))
                    (goto-char (point-max))
                    (tidal-mode)
                    (tidal-run-multiple-lines)
                  nil)))
            (message "Cursor is not within the source block boundaries")))
      (message "Not in a Tidal source block"))))