Fix return value for `org-get-outline-path'

* lisp/org.el (org--get-outline-path-1): Replace links with their
description, or path, in addition to removing statistics cookies.
(org-get-outline-path): Add an optional argument to include current
headline in path.
(org-refile-get-targets): Make use of new argument.  Remove call to
`org-link-display-format', which is now handled in
`org--get-outline-path-1'.

* testing/lisp/test-org.el (test-org/get-outline-path): Add tests.

Reported-by: Tobias Getzner <tobias.getzner@gmx.de>
<http://permalink.gmane.org/gmane.emacs.orgmode/105425>
This commit is contained in:
Nicolas Goaziou 2016-03-01 01:01:07 +01:00
parent 2971ab6126
commit 105a446697
2 changed files with 74 additions and 39 deletions

View file

@ -11678,7 +11678,6 @@ order.")
(let ((re (format org-complex-heading-regexp-format (let ((re (format org-complex-heading-regexp-format
(regexp-quote heading))) (regexp-quote heading)))
(target (target
(org-link-display-format
(if (not org-refile-use-outline-path) heading (if (not org-refile-use-outline-path) heading
(mapconcat (mapconcat
#'org-protect-slash #'org-protect-slash
@ -11691,8 +11690,8 @@ order.")
(list (buffer-file-name (list (buffer-file-name
(buffer-base-buffer)))) (buffer-base-buffer))))
(t nil)) (t nil))
(org-get-outline-path t)) (org-get-outline-path t t))
"/"))))) "/"))))
(push (list target f re (org-refile-marker (point))) (push (list target f re (org-refile-marker (point)))
tgs))) tgs)))
(when (= (point) begin) (when (= (point) begin)
@ -11716,8 +11715,7 @@ Outline path is a list of strings, in reverse order. When
optional argument USE-CACHE is non-nil, make use of a cache. See optional argument USE-CACHE is non-nil, make use of a cache. See
`org-get-outline-path' for details. `org-get-outline-path' for details.
Assume buffer is widened." Assume buffer is widened and point is on a headline."
(org-back-to-heading t)
(or (and use-cache (cdr (assq (point) org-outline-path-cache))) (or (and use-cache (cdr (assq (point) org-outline-path-cache)))
(let ((p (point)) (let ((p (point))
(heading (progn (heading (progn
@ -11725,9 +11723,10 @@ Assume buffer is widened."
(if (not (match-end 4)) "" (if (not (match-end 4)) ""
;; Remove statistics cookies. ;; Remove statistics cookies.
(org-trim (org-trim
(org-link-display-format
(replace-regexp-in-string (replace-regexp-in-string
"\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" ""
(org-match-string-no-properties 4))))))) (org-match-string-no-properties 4))))))))
(if (org-up-heading-safe) (if (org-up-heading-safe)
(let ((path (cons heading (org--get-outline-path-1 use-cache)))) (let ((path (cons heading (org--get-outline-path-1 use-cache))))
(when use-cache (when use-cache
@ -11740,9 +11739,16 @@ Assume buffer is widened."
(when use-cache (setq org-outline-path-cache (list (cons p path)))) (when use-cache (setq org-outline-path-cache (list (cons p path))))
path))))) path)))))
(defun org-get-outline-path (&optional use-cache) (defun org-get-outline-path (&optional with-self use-cache)
"Return the outline path to the current entry. "Return the outline path to the current entry.
An outline path is a list of ancestors for current headline, as
a list of strings. Statistics cookies are removed and links are
replaced with their description, if any, or their path otherwise.
When optional argument WITH-SELF is non-nil, the path also
includes the current headline.
When optional argument USE-CACHE is non-nil, cache outline paths When optional argument USE-CACHE is non-nil, cache outline paths
between calls to this function so as to avoid backtracking. This between calls to this function so as to avoid backtracking. This
argument is useful when planning to find more than one outline argument is useful when planning to find more than one outline
@ -11750,10 +11756,11 @@ path in the same document. In that case, there are two
conditions to satisfy: conditions to satisfy:
- `org-outline-path-cache' is set to nil before starting the - `org-outline-path-cache' is set to nil before starting the
process; process;
- outline paths are computed by increasing buffer positions. - outline paths are computed by increasing buffer positions."
(org-with-wide-buffer
Return value is a list of strings." (and (or (and with-self (org-back-to-heading t))
(org-with-wide-buffer (reverse (org--get-outline-path-1 use-cache)))) (org-up-heading-safe))
(reverse (org--get-outline-path-1 use-cache)))))
(defun org-format-outline-path (path &optional width prefix separator) (defun org-format-outline-path (path &optional width prefix separator)
"Format the outline path PATH for display. "Format the outline path PATH for display.

View file

@ -1313,39 +1313,67 @@
(ert-deftest test-org/get-outline-path () (ert-deftest test-org/get-outline-path ()
"Test `org-get-outline-path' specifications." "Test `org-get-outline-path' specifications."
;; Top-level headlines have no outline path.
(should-not
(org-test-with-temp-text "* H"
(org-get-outline-path)))
;; Otherwise, outline path is the path leading to the headline.
(should (should
(equal '("H") (equal '("H")
(org-test-with-temp-text "* H"
(org-get-outline-path))))
(should
(equal '("H" "S")
(org-test-with-temp-text "* H\n** S<point>" (org-test-with-temp-text "* H\n** S<point>"
(org-get-outline-path)))) (org-get-outline-path))))
;; Find path even when point is not on a headline. ;; Find path even when point is not on a headline.
(should (should
(equal '("H" "S") (equal '("H")
(org-test-with-temp-text "* H\n** S\nText<point>" (org-test-with-temp-text "* H\n** S\nText<point>"
(org-get-outline-path)))) (org-get-outline-path))))
;; Using cache is transparent to the user. ;; TODO keywords, tags and statistics cookies are ignored.
(should
(equal '("H")
(org-test-with-temp-text "* TODO H [0/1] :tag:\n** S<point>"
(org-get-outline-path))))
;; Links are replaced with their description or their path.
(should
(equal '("Org")
(org-test-with-temp-text
"* [[http://orgmode.org][Org]]\n** S<point>"
(org-get-outline-path))))
(should
(equal '("http://orgmode.org")
(org-test-with-temp-text
"* [[http://orgmode.org]]\n** S<point>"
(org-get-outline-path))))
;; When WITH-SELF is non-nil, include current heading.
(should
(equal '("H")
(org-test-with-temp-text "* H"
(org-get-outline-path t))))
(should (should
(equal '("H" "S") (equal '("H" "S")
(org-test-with-temp-text "* H\n** S\nText<point>"
(org-get-outline-path t))))
;; Using cache is transparent to the user.
(should
(equal '("H")
(org-test-with-temp-text "* H\n** S<point>" (org-test-with-temp-text "* H\n** S<point>"
(setq org-outline-path-cache nil) (setq org-outline-path-cache nil)
(org-get-outline-path t)))) (org-get-outline-path nil t))))
;; Do not corrupt cache when finding outline path in distant part of ;; Do not corrupt cache when finding outline path in distant part of
;; the buffer. ;; the buffer.
(should (should
(equal '("H2" "S2") (equal '("H2")
(org-test-with-temp-text "* H\n** S\n* H2\n** S2" (org-test-with-temp-text "* H\n** S<point>\n* H2\n** S2"
(setq org-outline-path-cache nil) (setq org-outline-path-cache nil)
(org-get-outline-path t) (org-get-outline-path nil t)
(search-forward "S2") (search-forward "S2")
(org-get-outline-path t)))) (org-get-outline-path nil t))))
;; Do not choke on empty headlines. ;; Do not choke on empty headlines.
(should (should
(org-test-with-temp-text "* " (org-test-with-temp-text "* H\n** <point>"
(setq org-outline-path-cache nil) (org-get-outline-path)))
(org-get-outline-path t)))) (should
(org-test-with-temp-text "* \n** H<point>"
(org-get-outline-path))))
(ert-deftest test-org/format-outline-path () (ert-deftest test-org/format-outline-path ()
"Test `org-format-outline-path' specifications." "Test `org-format-outline-path' specifications."