From 9ad5953dd3fdce84e4a1ec27f0334f679b6bd437 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Sat, 20 Dec 2025 20:50:57 +0200 Subject: [PATCH] Handle non-leaf nodes with Eglot text properties in 'M-x imenu' * lisp/imenu.el (imenu--flatten-index-alist): Add special handling of the text property 'breadcrumb-region' added by 'eglot-imenu'. Add non-leaf nodes with these text properties to the flat index alist. (imenu--parentify-index-alist): New function. (imenu-choose-buffer-index): For the case when imenu-flatten is nil, use 'imenu--parentify-index-alist' to add separate ".." to non-leaf nodes when the first node of 'index-alist' has Eglot text properties (bug#79980). --- lisp/imenu.el | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/lisp/imenu.el b/lisp/imenu.el index 41c4b5cee91..a0e6a5cac72 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -864,7 +864,33 @@ Returns t for rescan and otherwise an element or subelement of INDEX-ALIST." (_ new-prefix)) pos))) (t - (imenu--flatten-index-alist pos concat-names new-prefix))))) + (let ((subalist (imenu--flatten-index-alist + pos concat-names new-prefix)) + (region (get-text-property 0 'breadcrumb-region name))) + (if region + ;; Add non-leaf nodes with Eglot text properties. + (append (imenu--flatten-index-alist + (list (cons name (car region))) concat-names prefix) + subalist) + subalist)))))) + index-alist)) + +(defun imenu--parentify-index-alist (index-alist) + ;; Add separate ".." for navigating to non-leaf nodes. + ;; Used only when `index-alist' has Eglot text properties. + (mapcan + (lambda (item) + (let* ((name (car item)) + (pos (cdr item))) + (cond + ((not (imenu--subalist-p item)) + (list item)) + (t + (let ((subalist (imenu--parentify-index-alist pos)) + (region (get-text-property 0 'breadcrumb-region name))) + (when region + (setq subalist (append (list (cons ".." (car region))) subalist))) + (list (cons name subalist))))))) index-alist)) (defun imenu-choose-buffer-index (&optional prompt alist) @@ -896,8 +922,16 @@ The returned value is of the form (INDEX-NAME . INDEX-POSITION)." ;; Create a list for this buffer only when needed. (while (eq result t) (setq index-alist (if alist alist (imenu--make-index-alist))) - (when imenu-flatten + (cond + (imenu-flatten (setq index-alist (imenu--flatten-index-alist index-alist t))) + ((when-let* ((alist (if (eq (car index-alist) imenu--rescan-item) + (cdr index-alist) index-alist)) + (name (caar alist))) + (get-text-property 0 'breadcrumb-region name)) + ;; Change the menu structure by adding ".." to non-leaf nodes + ;; only when the first node has Eglot text properties. + (setq index-alist (imenu--parentify-index-alist index-alist)))) (setq result (if (and imenu-use-popup-menu (or (eq imenu-use-popup-menu t) mouse-triggered))