7

Is there an inverse of org-babel-tangle-jump-to-org allowing one to jump from a source block to the corresponding place in the tangled file?

3 Answers 3

3

Here is a solution if you use :comments link in your code blocks header and if tangle multiple blocks into a single file. With cursor at code block it will jump to a point where this block was tangled using these comment links.

;; this is optional but might look better than defaults
(setq org-babel-tangle-comment-format-beg "-------->>  [[%link][%source-name]]")
(setq org-babel-tangle-comment-format-end "--------<<  %source-name ends here\n\n")

(defun sv-org-babel-tangle-jump-to-src ()
  "The opposite of `org-babel-tangle-jump-to-org'. Jumps at tangled code from org src block."
  (interactive)
  (if (org-in-src-block-p)
      (let* ((header (car (org-babel-tangle-single-block 1 'only-this-block)))
             (tangle (car header))
             (lang (caadr header))
             (buffer (nth 2 (cadr header)))
             (org-id (nth 3 (cadr header)))
             (source-name (nth 4 (cadr header)))
             (search-comment (org-fill-template
                              org-babel-tangle-comment-format-beg
                              `(("link" . ,org-id) ("source-name" . ,source-name))))
             (file (expand-file-name
                    (org-babel-effective-tangled-filename buffer lang tangle))))
        (if (not (file-exists-p file))
            (message "File does not exist. 'org-babel-tangle' first to create file.")
          (find-file file)
          (beginning-of-buffer)
          (search-forward search-comment)))
    (message "Cannot jump to tangled file because point is not at org src block.")))
1

I am not aware of a function shipped with org that jumps to the tangled file. Furthermore, there is no separate function that generates the file name(s) for the tangled file(s) in org-babel-tangle. That makes the job a bit cumbersome.

The function org-babel-tangle-jump calls org-babel-tangle with write-region temporarily modified such that it does not write the region contents to a file but just delivers the file name that is passed to it in a variable file locally bound in org-babel-tangle-jump. Finally, org-babel-tangle-jump opens the file with that name if it already exists.

(defun org-babel-tangle-jump ()
  "Jump to tangle file for the source block at point."
  (interactive)
  (let (file org-babel-pre-tangle-hook org-babel-post-tangle-hook)
    (cl-letf (((symbol-function 'write-region) (lambda (start end filename &rest _ignore)
                         (setq file filename)))
          ((symbol-function 'delete-file) #'ignore))
      (org-babel-tangle '(4)))
    (when file
      (setq file (expand-file-name file))
      (if (file-readable-p file)
      (find-file file)
    (error "Cannot open tangle file %S" file)))))
1

A little add up to Stas' fantastic function:

as org-babel-tangle-single-block is used with counter 1, the function only work if your source block is the first in the subtree, or if it have #+name: some name before the block.

explanation:

if the src block have no #+name:, the link in tangle file would be

  • [[file:babel.org::+begin_src python][No heading:2]] (if it is before first heading) or
  • [[file:babel.org::*a heading][a heading:1]] ("a heading" is the heading it belongs to)

and the counter in [No heading:2] and [a heading:1]may not be 1.

With #+name: the link would look like [[file:babel.org::this block][this block]], where the counter wouldn't matter.

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.