;;; imenu-conf.el --- Flatten imenu -*- lexical-binding: t; -*- ;; Copyright (C) 2023 Jean Sévère Durand ;; Author: Jean Sévère Durand ;; Keywords: convenience, maint, outlines ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Flatten the imenu list if needed. ;;; Code: (require 'imenu) (defvar imenu-flatten-p t "Whether or not to flatten the indices in imenu.") (defun imenu-flatten-prefix (parent-prefix child-prefix) "A helper function to concatenate prefixes." (cond ((and (stringp parent-prefix) (not (string-empty-p parent-prefix))) ;; We can experiment with different styles, perhaps. (format "%s/%s" parent-prefix child-prefix)) (child-prefix))) (defun imenu-flatten (alist) "Flatten the ALIST. See the documentation of the variable `imenu--index-alist' to know what the flattening does." (let* ((prefix "") ;; Perform a depth-first walk on the tree. (stack (mapcar (lambda (item) (cons prefix item)) alist)) temp result) (while (consp stack) ; `consp' excludes empty lists ;; pop the stack from the front (setq temp (car stack)) (setq stack (cdr stack)) (cond ((not (imenu--subalist-p (cdr temp))) (setq result (cons (cons (imenu-flatten-prefix (car temp) (cadr temp)) (cddr temp)) result))) ((let ((prefix (imenu-flatten-prefix (car temp) (cadr temp)))) (mapc (lambda (sub-item) (setq stack (cons (cons prefix sub-item) stack))) (cddr temp)))))) (nreverse result))) (defun imenu-flatten-advice (alist) "An advice for `imenu--make-index-alist' that flattens its result. The variable `imenu-flatten-p' controls whether the flattening actually happens." (cond (imenu-flatten-p (imenu-flatten alist)) (alist))) (advice-add #'imenu--make-index-alist :filter-return #'imenu-flatten-advice) (provide 'imenu-conf) ;;; imenu-conf.el ends here