Fix imenu compatibility with non-contiguous structure

* lisp/org.el (org-mode): Move imenu compatibility to "org-compat.el".
* lisp/org-compat.el (org-imenu-new-marker): Remove function.
(org-imenu-get-tree): Handle non-contiguous structure.

Reported-by: Thibault Polge <thibault@thb.lt>
<http://lists.gnu.org/r/emacs-orgmode/2018-06/msg00088.html>
This commit is contained in:
Nicolas Goaziou 2018-06-13 01:13:16 +02:00
parent 3745c0af9f
commit f440ff0a6a
2 changed files with 25 additions and 32 deletions

View File

@ -613,46 +613,42 @@ This also applied for speedbar access."
(defvar-local org-imenu-markers nil
"All markers currently used by Imenu.")
(defun org-imenu-new-marker (&optional pos)
"Return a new marker for use by Imenu, and remember the marker."
(let ((m (make-marker)))
(move-marker m (or pos (point)))
(push m org-imenu-markers)
m))
(defun org-imenu-get-tree ()
"Produce the index for Imenu."
(dolist (x org-imenu-markers) (move-marker x nil))
(setq org-imenu-markers nil)
(let* ((case-fold-search nil)
(n org-imenu-depth)
(re (concat "^" (org-get-limited-outline-regexp)))
(subs (make-vector (1+ n) nil))
(last-level 0)
m level head0 head)
(org-with-wide-buffer
(goto-char (point-max))
(org-with-wide-buffer
(goto-char (point-max))
(let* ((re (concat "^" (org-get-limited-outline-regexp)))
(subs (make-vector (1+ org-imenu-depth) nil))
(last-level 0))
(while (re-search-backward re nil t)
(setq level (org-reduced-level (funcall outline-level)))
(when (and (<= level n)
(looking-at org-complex-heading-regexp)
(setq head0 (match-string-no-properties 4)))
(setq head (org-link-display-format head0)
m (org-imenu-new-marker))
(org-add-props head nil 'org-imenu-marker m 'org-imenu t)
(if (>= level last-level)
(push (cons head m) (aref subs level))
(push (cons head (aref subs (1+ level))) (aref subs level))
(cl-loop for i from (1+ level) to n do (aset subs i nil)))
(setq last-level level))))
(aref subs 1)))
(let ((level (org-reduced-level (funcall outline-level)))
(headline (org-no-properties
(org-link-display-format (org-get-heading t t t t)))))
(when (and (<= level org-imenu-depth) (org-string-nw-p headline))
(let* ((m (point-marker))
(item (propertize headline 'org-imenu-marker m 'org-imenu t)))
(push m org-imenu-markers)
(if (>= level last-level)
(push (cons item m) (aref subs level))
(push (cons item
(cl-mapcan #'identity (cl-subseq subs (1+ level))))
(aref subs level))
(cl-loop for i from (1+ level) to org-imenu-depth
do (aset subs i nil)))
(setq last-level level)))))
(aref subs 1))))
(eval-after-load "imenu"
'(progn
(add-hook 'imenu-after-jump-hook
(lambda ()
(when (derived-mode-p 'org-mode)
(org-show-context 'org-goto))))))
(org-show-context 'org-goto))))
(add-hook 'org-mode-hook
(lambda ()
(setq imenu-create-index-function 'org-imenu-get-tree)))))
;;;; Speedbar

View File

@ -5529,9 +5529,6 @@ The following commands are available:
(regexp . "^[ \t]*#\\+[A-Z_]+:\\(\\s-*\\)\\S-+")
(modes . '(org-mode)))))
;; Imenu
(setq-local imenu-create-index-function 'org-imenu-get-tree)
;; Make isearch reveal context
(setq-local outline-isearch-open-invisible-function
(lambda (&rest _) (org-show-context 'isearch)))