summaryrefslogtreecommitdiff
path: root/imenu-conf.el
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2023-01-01 02:25:08 +0800
committerJSDurand <mmemmew@gmail.com>2023-01-01 02:25:08 +0800
commitf3c383b7906235e3b50dbc196194f311bf949174 (patch)
tree0f12da5263f9ed29f39b5e8ba1774cba9e49b528 /imenu-conf.el
parentb6a8d5d653c15437c7c3e8a580e00c4770e4124b (diff)
imenu: flatten imenu
* imenu-conf.el (imenu-flatten-p): A variable to control whether or not we want to flatten imenu. (imenu-flatten-prefix): A helper function to deal with prefixes. (imenu-flatten): The function that actually flattens the lists. (imenu-flatten-advice, imenu--make-index-alist): Advice the producer of indices of imenu to plug our flattening logic in. * init.el ("imenu-conf.el"): Load this configuration automatically.
Diffstat (limited to 'imenu-conf.el')
-rw-r--r--imenu-conf.el83
1 files changed, 83 insertions, 0 deletions
diff --git a/imenu-conf.el b/imenu-conf.el
new file mode 100644
index 0000000..af85559
--- /dev/null
+++ b/imenu-conf.el
@@ -0,0 +1,83 @@
+;;; imenu-conf.el --- Flatten imenu -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2023 Jean Sévère Durand
+
+;; Author: Jean Sévère Durand <durand@jsdurand.xyz>
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; 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