summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2018-06-24 11:10:06 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2018-06-24 11:25:15 +0200
commit627cb7f578e07547f3a3ea73ef1670ed39084a82 (patch)
tree124140edff2215556c7bc3164558ca7d0de3d9bb
parent9553896b1171dc0ad0a7b1960144039de37583c5 (diff)
downloadorg-mode-627cb7f578e07547f3a3ea73ef1670ed39084a82.tar.gz
org-footnote: Fix `org-footnote-goto-previous-reference'
* lisp/org-footnote.el (org-footnote-goto-previous-reference): Only add to mark ring on a successful match. Improve error message when reference is outside visible part of buffer. (org-footnote-get-next-reference): Avoid using `org-footnote-at-reference-p', which is inaccurate, due to `org-footnote-in-valid-context-p'. * testing/lisp/test-org-footnote.el (test-org-footnote/goto-previous-reference): New test.
-rw-r--r--lisp/org-footnote.el61
-rw-r--r--testing/lisp/test-org-footnote.el22
2 files changed, 59 insertions, 24 deletions
diff --git a/lisp/org-footnote.el b/lisp/org-footnote.el
index 119a53a..d57ffcd 100644
--- a/lisp/org-footnote.el
+++ b/lisp/org-footnote.el
@@ -467,16 +467,27 @@ the buffer position bounding the search.
Return value is a list like those provided by `org-footnote-at-reference-p'.
If no footnote is found, return nil."
- (save-excursion
- (let* ((label-fmt (if label (format "\\[fn:%s[]:]" label) org-footnote-re)))
- (catch 'exit
- (while t
- (unless (funcall (if backward #'re-search-backward #'re-search-forward)
- label-fmt limit t)
- (throw 'exit nil))
+ (let ((label-fmt (if label (format "\\[fn:%s[]:]" label) org-footnote-re)))
+ (catch :exit
+ (save-excursion
+ (while (funcall (if backward #'re-search-backward #'re-search-forward)
+ label-fmt limit t)
(unless backward (backward-char))
- (let ((ref (org-footnote-at-reference-p)))
- (when ref (throw 'exit ref))))))))
+ (let ((reference (org-element-context)))
+ (when (eq 'footnote-reference (org-element-type reference))
+ (throw :exit
+ (list
+ (org-element-property :label reference)
+ (org-element-property :begin reference)
+ (save-excursion
+ (goto-char (org-element-property :end reference))
+ (skip-chars-backward " \t")
+ (point))
+ (and (eq 'inline (org-element-property :type reference))
+ (buffer-substring-no-properties
+ (org-element-property :contents-begin reference)
+ (org-element-property :contents-end
+ reference))))))))))))
(defun org-footnote-next-reference-or-definition (limit)
"Move point to next footnote reference or definition.
@@ -537,21 +548,23 @@ value if point was successfully moved."
(defun org-footnote-goto-previous-reference (label)
"Find the first closest (to point) reference of footnote with label LABEL."
(interactive "sLabel: ")
- (org-mark-ring-push)
- (let ((label (org-footnote-normalize-label label))
- ref)
- (save-excursion
- (setq ref (or (org-footnote-get-next-reference label t)
- (org-footnote-get-next-reference label)
- (save-restriction
- (widen)
- (or
- (org-footnote-get-next-reference label t)
- (org-footnote-get-next-reference label))))))
- (if (not ref)
- (error "Cannot find reference of footnote %s" label)
- (goto-char (nth 1 ref))
- (org-show-context 'link-search))))
+ (let* ((label (org-footnote-normalize-label label))
+ (reference
+ (save-excursion
+ (or (org-footnote-get-next-reference label t)
+ (org-footnote-get-next-reference label)
+ (and (buffer-narrowed-p)
+ (org-with-wide-buffer
+ (or (org-footnote-get-next-reference label t)
+ (org-footnote-get-next-reference label)))))))
+ (start (nth 1 reference)))
+ (cond ((not reference)
+ (user-error "Cannot find reference of footnote %S" label))
+ ((or (> start (point-max)) (< start (point-min)))
+ (user-error "Reference is outside narrowed part of buffer")))
+ (org-mark-ring-push)
+ (goto-char start)
+ (org-show-context 'link-search)))
;;;; Getters
diff --git a/testing/lisp/test-org-footnote.el b/testing/lisp/test-org-footnote.el
index f5877a8..6ff8fea 100644
--- a/testing/lisp/test-org-footnote.el
+++ b/testing/lisp/test-org-footnote.el
@@ -242,6 +242,28 @@
(org-footnote-goto-definition "label")
(buffer-substring (point) (point-max))))))
+(ert-deftest test-org-footnote/goto-previous-reference ()
+ "Test `org-footnote-goto-previous-reference' specifications."
+ ;; Error on unknown reference.
+ (should-error
+ (org-test-with-temp-text "No footnote reference"
+ (org-footnote-goto-previous-reference "1")))
+ ;; Error when trying to reach a reference outside narrowed part of
+ ;; buffer.
+ (should-error
+ (org-test-with-temp-text "Some text<point>\nReference[fn:1]."
+ (narrow-to-region (point-min) (point))
+ (org-footnote-goto-previous-reference "1")))
+ ;; Otherwise, move to closest reference from point.
+ (should
+ (org-test-with-temp-text "First reference[fn:1]\nReference[fn:1].<point>"
+ (org-footnote-goto-previous-reference "1")
+ (= (line-end-position) (point-max))))
+ (should
+ (org-test-with-temp-text "First reference[fn:1]\nReference[fn:1]."
+ (org-footnote-goto-previous-reference "1")
+ (= (line-beginning-position) (point-min)))))
+
(ert-deftest test-org-footnote/sort ()
"Test `org-footnote-sort' specifications."
;; Reorder definitions with a nil `org-footnote-section'. In this