From: aditya siram <aditya.siram@gmail.com>
To: emacs-orgmode@gnu.org
Subject: Jumping from source block to Org block ...
Date: Fri, 13 Sep 2013 22:04:34 -0500 [thread overview]
Message-ID: <CAJrReyhBrq-ESgQRX=FR3WQmfYxfW5s7Z6n4_=GaOkt3hi1RJQ@mail.gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 251 bytes --]
Attached is a patch that fixes a bug with jumping from source block back to
the Org file. The problem is that the current detangling behavior does not
take the :padlline flag into account. This stopped.
Hopefully this is helpful to others ...
-deech
[-- Attachment #1.2: Type: text/html, Size: 311 bytes --]
[-- Attachment #2: src_block_jump_fix.patch --]
[-- Type: application/octet-stream, Size: 6245 bytes --]
From 1bff94700991197d236af89bcfe5fa246941c7b7 Mon Sep 17 00:00:00 2001
From: Aditya Siram <aditya siram at gmail dot com>
Date: Fri, 13 Sep 2013 18:29:14 -0500
Subject: [PATCH 3/3] org-babel-detangle and org-babel-tangle-jump-to-org now
correctly compensate for padded source chunks
---
lisp/ob-tangle.el | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 86 insertions(+), 6 deletions(-)
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index 8141943..d8cede2 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -502,12 +502,12 @@ which enable the original code blocks to be found."
(goto-char end))
(prog1 counter (message "Detangled %d code blocks" counter)))))
-(defun org-babel-tangle-jump-to-org ()
+(defun org-babel-tangle-jump-to-org (&optional maintain-point)
"Jump from a tangled code file to the related Org-mode file."
(interactive)
(let ((mid (point))
- start body-start end done
- target-buffer target-char link path block-name body)
+ start body-start end done depadded-body
+ target-buffer offset target-char link path block-name body)
(save-window-excursion
(save-excursion
(while (and (re-search-backward org-bracket-link-analytic-regexp nil t)
@@ -526,7 +526,7 @@ which enable the original code blocks to be found."
(setq end (point-at-bol))))))))
(unless (and start (< start mid) (< mid end))
(error "Not in tangled code"))
- (setq body (org-babel-trim (buffer-substring start end))))
+ (setq body (buffer-substring start end)))
(when (string-match "::" path)
(setq path (substring path 0 (match-beginning 0))))
(find-file path) (setq target-buffer (current-buffer))
@@ -537,12 +537,17 @@ which enable the original code blocks to be found."
(org-babel-goto-named-src-block block-name))
;; position at the beginning of the code block body
(goto-char (org-babel-where-is-src-block-head))
+ (let* ((pad-adjusted-values (org-babel-detangle-adjust-for-padlines start mid body))
+ (depadded-body (car pad-adjusted-values))
+ (depadded-point (cdr pad-adjusted-values)))
+ (progn
+ (setq offset depadded-point)
+ (setq body depadded-body)))
(forward-line 1)
- ;; Use org-edit-special to isolate the code.
(org-edit-special)
;; Then move forward the correct number of characters in the
;; code buffer.
- (forward-char (- mid body-start))
+ (forward-char offset)
;; And return to the Org-mode buffer with the point in the right
;; place.
(org-edit-src-exit)
@@ -550,6 +555,81 @@ which enable the original code blocks to be found."
(org-src-switch-to-buffer target-buffer t)
(prog1 body (goto-char target-char))))
+(defun org-babel-detangle-adjust-for-padlines (chunk-start desired-point chunk-body)
+ "Check if :padline was enabled for this chunk and then
+adjust point and body accordingly. Also account for the user
+editing the tangled file and removing the padded lines.
+
+Returns a tuple (body . offset) where body is an adjusted source chunk
+with padded newlines possibly removed and offset is how far into
+that chunk point is. If point was on either of the padlines, point
+is set to the first or last character of the chunk depending on what's
+closer."
+ (save-excursion
+ (let* ((org-block (org-babel-get-src-block-info))
+ (params (nth 2 org-block))
+ (org-body (nth 1 org-block))
+ (should-be-padded (not (string= "no" (cdr (assoc :padline params)))))
+ (minimal-padded-chunk-length (+ 1 ;; end of first delimiter
+ 1 ;; newline from first padline
+ 1 ;; newline from second padline
+ 1 ;; start of second delimiter
+ ))
+ (possibly-padded (>= (length chunk-body) minimal-padded-chunk-length))
+ (char-at (lambda (pos str) (substring str pos (+ pos 1))))
+ (actually-padded (and (not (= (length chunk-body) 0))
+ (string= "\n" (funcall char-at 1 chunk-body))
+ (string= "\n" (funcall char-at (- (length chunk-body)
+ 1 ;; start of second delimiter
+ 1 ;; newline from second padline
+ )
+ chunk-body)))))
+ (if should-be-padded
+ (if possibly-padded
+ (if actually-padded
+ (let* ((start-offset (+ 1 ;; end of first delimiter
+ 1 ;; newline from first padline
+ 1 ;; first character of body
+ ))
+ (end-offset (+ 1 ;; newline from second padline
+ 1 ;; eol character after last character of body
+ ))
+ (start-index (- start-offset 1))
+ (end-index (- (length chunk-body) end-offset))
+ (end-inclusive-substring (lambda (str start end) (substring str start (+ 1 end))))
+ (depadded-body (substring chunk-body start-index end-index))
+ (distance-from-start (- desired-point chunk-start))
+ (on-first-padline (= distance-from-start 1))
+ (on-last-padline (= distance-from-start (- (length chunk-body) 1)))
+ (adjusted-distance(cond (on-first-padline 0)
+ (on-last-padline (length depadded-body))
+ (t (- distance-from-start (- start-offset
+ 1 ;; compensate for the
+ ;; fact that start-offset
+ ;; includes the first
+ ;; character
+ )))))
+ (distance-within-org-body (< adjusted-distance (- (length org-body) 1))))
+ ;; If this chunk and the org source chunk match
+ ;; send this chunk back and preserve the desired point
+ (if (string= org-body depadded-body)
+ `(,depadded-body . ,adjusted-distance)
+ ;; if the chunks match before the desired point
+ ;; we can still preserve the point
+ (if (and distance-within-org-body
+ (string= (substring org-body 0 adjusted-distance)
+ (substring depadded-body 0 adjusted-distance)))
+ `(,depadded-body . ,adjusted-distance)
+ ;; otherwise we can't preserve the point
+ `(,depadded-body . 0))
+ `(,depadded-body . 0)))
+ ;; The user didn't respect the padlines
+ ;; so the whole body goes back unchanged
+ `(,chunk-body . 0))
+ `(,chunk-body . 0))
+ ;; No adjustment needed
+ `(,chunk-body . ,desired-point)))))
+
(provide 'ob-tangle)
;; Local variables:
--
1.8.1.2
next reply other threads:[~2013-09-14 3:05 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-14 3:04 aditya siram [this message]
2013-09-14 15:44 ` Jumping from source block to Org block Eric Schulte
2013-09-14 15:53 ` aditya siram
2013-09-14 16:56 ` aditya siram
2013-09-15 11:51 ` Eric Schulte
2013-09-15 11:52 ` Eric Schulte
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAJrReyhBrq-ESgQRX=FR3WQmfYxfW5s7Z6n4_=GaOkt3hi1RJQ@mail.gmail.com' \
--to=aditya.siram@gmail.com \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).