From 105a44669716abd50377fdcfd03a9a11dc388b16 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Tue, 1 Mar 2016 01:01:07 +0100 Subject: [PATCH] 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 --- lisp/org.el | 57 ++++++++++++++++++++++------------------ testing/lisp/test-org.el | 56 +++++++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index ea75d2ee6..04cce7bfb 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -11678,21 +11678,20 @@ order.") (let ((re (format org-complex-heading-regexp-format (regexp-quote heading))) (target - (org-link-display-format - (if (not org-refile-use-outline-path) heading - (mapconcat - #'org-protect-slash - (append - (case org-refile-use-outline-path - (file (list (file-name-nondirectory - (buffer-file-name - (buffer-base-buffer))))) - (full-file-path - (list (buffer-file-name - (buffer-base-buffer)))) - (t nil)) - (org-get-outline-path t)) - "/"))))) + (if (not org-refile-use-outline-path) heading + (mapconcat + #'org-protect-slash + (append + (case org-refile-use-outline-path + (file (list (file-name-nondirectory + (buffer-file-name + (buffer-base-buffer))))) + (full-file-path + (list (buffer-file-name + (buffer-base-buffer)))) + (t nil)) + (org-get-outline-path t t)) + "/")))) (push (list target f re (org-refile-marker (point))) tgs))) (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 `org-get-outline-path' for details. -Assume buffer is widened." - (org-back-to-heading t) +Assume buffer is widened and point is on a headline." (or (and use-cache (cdr (assq (point) org-outline-path-cache))) (let ((p (point)) (heading (progn @@ -11725,9 +11723,10 @@ Assume buffer is widened." (if (not (match-end 4)) "" ;; Remove statistics cookies. (org-trim - (replace-regexp-in-string - "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" - (org-match-string-no-properties 4))))))) + (org-link-display-format + (replace-regexp-in-string + "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" + (org-match-string-no-properties 4)))))))) (if (org-up-heading-safe) (let ((path (cons heading (org--get-outline-path-1 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)))) 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. +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 between calls to this function so as to avoid backtracking. This 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: - `org-outline-path-cache' is set to nil before starting the process; - - outline paths are computed by increasing buffer positions. - -Return value is a list of strings." - (org-with-wide-buffer (reverse (org--get-outline-path-1 use-cache)))) + - outline paths are computed by increasing buffer positions." + (org-with-wide-buffer + (and (or (and with-self (org-back-to-heading t)) + (org-up-heading-safe)) + (reverse (org--get-outline-path-1 use-cache))))) (defun org-format-outline-path (path &optional width prefix separator) "Format the outline path PATH for display. diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index e64bdf4cf..ffdd1b359 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -1313,39 +1313,67 @@ (ert-deftest test-org/get-outline-path () "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 (equal '("H") - (org-test-with-temp-text "* H" - (org-get-outline-path)))) - (should - (equal '("H" "S") (org-test-with-temp-text "* H\n** S" (org-get-outline-path)))) ;; Find path even when point is not on a headline. (should - (equal '("H" "S") + (equal '("H") (org-test-with-temp-text "* H\n** S\nText" (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" + (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" + (org-get-outline-path)))) + (should + (equal '("http://orgmode.org") + (org-test-with-temp-text + "* [[http://orgmode.org]]\n** S" + (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 (equal '("H" "S") + (org-test-with-temp-text "* H\n** S\nText" + (org-get-outline-path t)))) + ;; Using cache is transparent to the user. + (should + (equal '("H") (org-test-with-temp-text "* H\n** S" (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 ;; the buffer. (should - (equal '("H2" "S2") - (org-test-with-temp-text "* H\n** S\n* H2\n** S2" + (equal '("H2") + (org-test-with-temp-text "* H\n** S\n* H2\n** S2" (setq org-outline-path-cache nil) - (org-get-outline-path t) + (org-get-outline-path nil t) (search-forward "S2") - (org-get-outline-path t)))) + (org-get-outline-path nil t)))) ;; Do not choke on empty headlines. (should - (org-test-with-temp-text "* " - (setq org-outline-path-cache nil) - (org-get-outline-path t)))) + (org-test-with-temp-text "* H\n** " + (org-get-outline-path))) + (should + (org-test-with-temp-text "* \n** H" + (org-get-outline-path)))) (ert-deftest test-org/format-outline-path () "Test `org-format-outline-path' specifications."