Section 1
Section 1.1
Section 1.1.1
Section 1.1.2
Section 1.2
Section 1.2.1
Section 1.2.2
Section 2
Section 2.1
Section 2.1.1
Section 2.1.2
Section 2.2
Section 2.2.1
Section 2.2.2
Code
(setq org-imenu-depth 3)
(setq imenu-list-position 'left)
;; See https://orgmode.org/worg/org-tutorials/advanced-searching.html
(defvar org-imenu-filter-history
'(
"SECTION=1" ; Match property SECTION=1
"SECTION=2" ; Match property SECTION=2
"SECTION={1\\|2}" ; Match property SECTION=1 or 2
"TEXT" ; Match tag TEXT
"CODE" ; Match tag CODE
"CODE|TEXT" ; Match tag CODE or tag EXT
"CODE+SECTION=1" ; Match tag CODE and property SECTION=1
"CODE+SECTION=2") ; Match tag CODE and property SECTION=2
"org imenu filter history list.")
(defvar org-imenu-filter-function
(cdr (org-make-tags-matcher "*"))
"Filter function to decide if a headline is kept")
(defun org-imenu-filter ()
(interactive)
(let* ((match (completing-read-multiple "FILTER: "
org-imenu-filter-history
nil nil nil
'org-imenu-filter-history))
(match (mapconcat #'identity match " ")))
(org-imenu-filter-apply match)))
(defun org-imenu-filter-apply (match)
(when (string= "" match)
(setq match "*"))
(setq org-imenu-filter-function
(cdr (org-make-tags-matcher match)))
(imenu-list-refresh))
(defun org-imenu-filter-tree (&optional bound parent-match)
(let* ((headlines '()))
(save-excursion
(org-with-wide-buffer
(unless bound
(setq bound (point-max))
(goto-char (point-min)))
(while (re-search-forward org-heading-regexp bound t)
(let* ((element (org-element-at-point))
(begin (org-element-property :begin element))
(end (org-element-property :end element))
(marker (copy-marker begin))
(level (org-element-property :level element))
(match (save-excursion
(goto-char begin)
(funcall org-imenu-filter-function
nil (org-get-tags) level)))
(title (org-element-property :raw-value element))
(title (org-link-display-format
(substring-no-properties title)))
(title (propertize title 'org-imenu-marker marker
'org-imenu t))
(children (org-imenu-filter-tree end match)))
(goto-char end)
(cond ((and (< level org-imenu-depth) (> (length children) 0))
(add-to-list 'headlines (append (list title) children) t))
((or match parent-match)
(add-to-list 'headlines (cons title marker) t)))))))
headlines))
(advice-add #'org-imenu-get-tree :override #'org-imenu-filter-tree)
Call first
imenu-list
then callorg-imenu-filter
to filter the list.