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
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.")))
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)))))
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.