2

I would like to have a single shortcut to jump to the next item on the imenu of current buffer. E.g., if the current buffer is in org mode, next-imenu-item = org-next-visible-heading.

Anyone did that before?

  • I grepped the Emacs 25.1 source code for next-imenu-item, and came up with nothing -- i.e., it does not exist. In my setup, imenu creates a menu with all main first level headings, and the subheadings (e.g., second level) are alphabetized (if there are lots, then they are grouped into alphabetized groups). The main ingredient that creates this is (org-set-local 'imenu-create-index-function 'org-imenu-get-tree) within my org-mode setup. Please consider editing your question to provide some additional details regarding your setup and what it is specifically you wish to accomplish. – lawlist Feb 13 '17 at 22:58
  • And, also have this: (eval-after-load "imenu" '(progn (add-hook 'imenu-after-jump-hook (lambda () (when (derived-mode-p 'org-mode) (org-show-context 'org-goto)))))) – lawlist Feb 13 '17 at 23:01
  • I implemented what I wanted and posted as an answer below. Feel free to comment. Thanks. – AhLeung Jun 24 '17 at 7:13
2
(defun my-imenu-goto--closest-dir (direction)
  "Jump to the closest imenu item on the current buffer.
If direction is 1, jump to next imenu item.
If direction is -1, jump to previous imenu item.
See https://emacs.stackexchange.com/questions/30673
Adapted from `which-function' in::
https://github.com/typester/emacs/blob/master/lisp/progmodes/which-func.el"
  ;; Ensure `imenu--index-alist' is populated.
  (imenu--make-index-alist)

  (let ((alist imenu--index-alist)
        (minoffset (point-max))
        offset pair mark imstack destination)
    ;; Elements of alist are either ("name" . marker), or
    ;; ("submenu" ("name" . marker) ... ). The list can be
    ;; Arbitrarily nested.
    (while (or alist imstack)
      (if alist
          (progn
            (setq pair (car-safe alist)
                  alist (cdr-safe alist))
            (cond
             ((atom pair)) ;; Skip anything not a cons.

             ((imenu--subalist-p pair)
              (setq imstack   (cons alist imstack)
                    alist     (cdr pair)))

             ((number-or-marker-p (setq mark (cdr pair)))
              (when (> (setq offset (* (- mark (point)) direction)) 0)
                (when (< offset minoffset) ;; Find the closest item.
                  (setq minoffset offset
                        destination mark))))))

        (setq alist   (car imstack)
              imstack (cdr imstack))))
    (when destination
      (imenu-default-goto-function "" destination ""))))

(defun my-imenu-goto-next ()
  (interactive)
  (unless (my-imenu-goto--closest-dir 1)
    (goto-char (point-max))))

(defun my-imenu-goto-prev ()
  (interactive)
  (unless (my-imenu-goto--closest-dir -1)
    (goto-char (point-min))))
| improve this answer | |
  • You should think about commenting and explaining your answer. – theldoria Jun 24 '17 at 12:13
  • And you should think about submitting it for inclusion in imenu.el. – Stefan Jun 24 '17 at 13:46
  • @theldoria Added some comments to the function. – AhLeung Jul 1 '17 at 6:14
  • 1
    @Stefan I haven't submitted anything to open source project before. Do you have some related pointers / tutorials (on contributing to GNU emac?) for me to follow? Thanks. – AhLeung Jul 1 '17 at 6:16
  • 1
    You can check the file CONTRIBUTE at the top-level of Emacs's source code. Basically, in your case, change imenu.el by adding yur feature to it, then generate a patch for the change and send it via M-x report-emacs-bug (which is used not just for bug-reports but for patch submission and feature requests as well). – Stefan Jul 2 '17 at 2:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.