GNU bug report logs - #70846
Imenu flatten

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> linkov.net>

Date: Thu, 9 May 2024 16:37:01 UTC

Severity: normal

Fixed in version 30.0.50

Done: Juri Linkov <juri <at> linkov.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 70846 in the body.
You can then email your comments to 70846 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Thu, 09 May 2024 16:37:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Juri Linkov <juri <at> linkov.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 09 May 2024 16:37:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: bug-gnu-emacs <at> gnu.org
Subject: Imenu flatten
Date: Thu, 09 May 2024 19:29:15 +0300
[Message part 1 (text/plain, inline)]
This patch revives the feature existed in the initial version of imenu.el,
but that was unfortunately removed later.

When comparing it with the version in breadcrumb-jump that was discussed in
https://lists.gnu.org/archive/html/emacs-devel/2023-12/msg00278.html
the advantage of this version is that it doesn't use 'cl-loop':

[imenu-flatten.patch (text/x-diff, inline)]
diff --git a/lisp/imenu.el b/lisp/imenu.el
index f628936cedc..ccc73fe42d2 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -66,6 +66,13 @@ imenu
   :group 'convenience
   :link '(custom-manual "(elisp)Imenu"))
 
+(defcustom imenu-flatten nil
+  "If non-nil, popup the completion buffer with a flattened menu.
+The string from `imenu-level-separator' is used to separate names of
+nested levels while flattening nested indexes with name concatenation."
+  :type 'boolean
+  :version "30.1")
+
 (defcustom imenu-use-markers t
   "Non-nil means use markers instead of integers for Imenu buffer positions.
 
@@ -142,8 +149,7 @@ imenu-space-replacement
 
 (defcustom imenu-level-separator ":"
   "The separator between index names of different levels.
-Used for making mouse-menu titles and for flattening nested indexes
-with name concatenation."
+Used for flattening nested indexes with name concatenation."
   :type 'string)
 
 (defcustom imenu-generic-skip-comments-and-strings t
@@ -763,6 +770,26 @@ imenu--mouse-menu
                                            menu)))))
     (popup-menu map event)))
 
+(defun imenu--flatten-index-alist (index-alist &optional concat-names prefix)
+  ;; Takes a nested INDEX-ALIST and returns a flat index alist.
+  ;; If optional CONCAT-NAMES is non-nil, then a nested index has its
+  ;; name and a space concatenated to the names of the children.
+  ;; Third argument PREFIX is for internal use only.
+  (mapcan
+   (lambda (item)
+     (let* ((name (car item))
+	    (pos (cdr item))
+	    (new-prefix (and concat-names
+			     (if prefix
+				 (concat prefix imenu-level-separator name)
+			       name))))
+       (cond
+	((or (markerp pos) (numberp pos))
+	 (list (cons new-prefix pos)))
+	(t
+	 (imenu--flatten-index-alist pos concat-names new-prefix)))))
+   index-alist))
+
 (defun imenu-choose-buffer-index (&optional prompt alist)
   "Let the user select from a buffer index and return the chosen index.
 
@@ -792,6 +819,8 @@ imenu-choose-buffer-index
     ;; 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
+        (setq index-alist (imenu--flatten-index-alist index-alist t)))
       (setq result
 	    (if (and imenu-use-popup-menu
 		     (or (eq imenu-use-popup-menu t) mouse-triggered))

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Thu, 09 May 2024 16:47:02 GMT) Full text and rfc822 format available.

Message #8 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Thu, 09 May 2024 19:45:50 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Date: Thu, 09 May 2024 19:29:15 +0300
> 
> This patch revives the feature existed in the initial version of imenu.el,
> but that was unfortunately removed later.
> 
> When comparing it with the version in breadcrumb-jump that was discussed in
> https://lists.gnu.org/archive/html/emacs-devel/2023-12/msg00278.html
> the advantage of this version is that it doesn't use 'cl-loop':

Thanks.  If this is installed, I think it needs a NEWS entry.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Fri, 10 May 2024 06:57:02 GMT) Full text and rfc822 format available.

Message #11 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Fri, 10 May 2024 09:52:25 +0300
>> This patch revives the feature existed in the initial version of imenu.el,
>> but that was unfortunately removed later.
>>
>> When comparing it with the version in breadcrumb-jump that was discussed in
>> https://lists.gnu.org/archive/html/emacs-devel/2023-12/msg00278.html
>> the advantage of this version is that it doesn't use 'cl-loop':
>
> Thanks.  If this is installed, I think it needs a NEWS entry.

So now pushed with a NEWS entry, and also with changes in the manual.

BTW, the manual says in (info "(emacs) Imenu"):

     You can customize the way the menus are sorted by setting the
  variable ‘imenu-sort-function’.  By default, names are ordered as they
  occur in the buffer; if you want alphabetic sorting, use the symbol
  ‘imenu--sort-by-name’ as the value.  You can also define your own
  comparison function by writing Lisp code.

But imenu-sort-function affects only the mouse popup menu.

To be able to customize sorting of imenu completion candidates
in the minibuffer, another patch is needed that sets a category
for sorting customization:

diff --git a/lisp/imenu.el b/lisp/imenu.el
index f628936cedc..5671b49cdf4 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -733,10 +740,12 @@ imenu--completion-buffer
                          (imenu--in-alist name prepared-index-alist)
                          ;; Default to `name' if it's in the alist.
                          name))))
-    (let ((minibuffer-setup-hook minibuffer-setup-hook))
-      ;; Display the completion buffer.
-      (if (not imenu-eager-completion-buffer)
-	  (add-hook 'minibuffer-setup-hook 'minibuffer-completion-help))
+    ;; Display the completion buffer.
+    (minibuffer-with-setup-hook
+        (lambda ()
+          (setq-local completion-extra-properties '(:category imenu))
+          (unless imenu-eager-completion-buffer
+            (minibuffer-completion-help)))
       (setq name (completing-read prompt
 				  prepared-index-alist
 				  nil t nil 'imenu--history-list name)))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Fri, 10 May 2024 07:31:02 GMT) Full text and rfc822 format available.

Message #14 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Fri, 10 May 2024 10:29:52 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: 70846 <at> debbugs.gnu.org
> Date: Fri, 10 May 2024 09:52:25 +0300
> 
> BTW, the manual says in (info "(emacs) Imenu"):
> 
>      You can customize the way the menus are sorted by setting the
>   variable ‘imenu-sort-function’.  By default, names are ordered as they
>   occur in the buffer; if you want alphabetic sorting, use the symbol
>   ‘imenu--sort-by-name’ as the value.  You can also define your own
>   comparison function by writing Lisp code.
> 
> But imenu-sort-function affects only the mouse popup menu.
> 
> To be able to customize sorting of imenu completion candidates
> in the minibuffer, another patch is needed that sets a category
> for sorting customization:

I agree that it is better to sort the same way in both cases, so
changes to do that are welcome.  But please also amend the text in the
manual to say so, because currently it only talks about "menus", which
could arguably be interpreted as pertaining only to popup menus.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Fri, 10 May 2024 16:50:02 GMT) Full text and rfc822 format available.

Message #17 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Fri, 10 May 2024 19:45:37 +0300
>> BTW, the manual says in (info "(emacs) Imenu"):
>>
>>      You can customize the way the menus are sorted by setting the
>>   variable ‘imenu-sort-function’.  By default, names are ordered as they
>>   occur in the buffer; if you want alphabetic sorting, use the symbol
>>   ‘imenu--sort-by-name’ as the value.  You can also define your own
>>   comparison function by writing Lisp code.
>>
>> But imenu-sort-function affects only the mouse popup menu.
>>
>> To be able to customize sorting of imenu completion candidates
>> in the minibuffer, another patch is needed that sets a category
>> for sorting customization:
>
> I agree that it is better to sort the same way in both cases, so
> changes to do that are welcome.

So now pushed.

> But please also amend the text in the manual to say so, because
> currently it only talks about "menus", which could arguably be
> interpreted as pertaining only to popup menus.

The "menus" above are pertaining only to popup menus,
and the variable ‘imenu-sort-function’ can't be used
to change the sorting order of Imenu completion candidates.
Only the following customization changes this order:

  (add-to-list 'completion-category-overrides
               '(imenu (display-sort-function . identity)))

Using this setting is especially essential for Imenu
on a PDF document with doc-view.el to keep the order
of chapters for the table of contents.

But I have no idea how to document this customization.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Fri, 10 May 2024 17:08:02 GMT) Full text and rfc822 format available.

Message #20 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Fri, 10 May 2024 20:06:07 +0300
[Message part 1 (text/plain, inline)]
> +(defcustom imenu-flatten nil
> +  "If non-nil, popup the completion buffer with a flattened menu.
> +The string from `imenu-level-separator' is used to separate names of
> +nested levels while flattening nested indexes with name concatenation."
> +  :type 'boolean

Here is another useful value for `imenu-flatten' that
will show section names as a suffix instead of a prefix:

[imenu-flatten-annotation.patch (text/x-diff, inline)]
diff --git a/lisp/imenu.el b/lisp/imenu.el
index 9c0c1ae144e..ccf5a0dc576 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -147,10 +147,16 @@ imenu-level-separator
 
 (defcustom imenu-flatten nil
   "Whether to flatten the list of sections in an imenu or show it nested.
-If non-nil, popup the completion buffer with a flattened menu.
+If nil, use nested indexes.
+If t, popup the completion buffer with a flattened menu.
+If `annotation', use completion annotation as a suffix
+to append section names after the index names.
+
 The string from `imenu-level-separator' is used to separate names of
 nested levels while flattening nested indexes with name concatenation."
-  :type 'boolean
+  :type '(choice (const :tag "Nested" nil)
+                 (const :tag "By prefix" t)
+                 (const :tag "By suffix" annotation))
   :version "30.1")
 
 (defcustom imenu-generic-skip-comments-and-strings t
@@ -743,7 +749,10 @@ imenu--completion-buffer
     ;; Display the completion buffer.
     (minibuffer-with-setup-hook
         (lambda ()
-          (setq-local completion-extra-properties '(:category imenu))
+          (setq-local completion-extra-properties
+                      `( :category imenu
+                         :annotation-function
+                         ,(lambda (s) (get-text-property 0 'imenu-section s))))
           (unless imenu-eager-completion-buffer
             (minibuffer-completion-help)))
       (setq name (completing-read prompt
@@ -787,7 +796,11 @@ imenu--flatten-index-alist
 			       name))))
        (cond
 	((not (imenu--subalist-p item))
-	 (list (cons new-prefix pos)))
+	 (list (cons (if (and (eq imenu-flatten 'annotation) prefix)
+			 (propertize name 'imenu-section
+				     (format " (%s)" prefix))
+		       name)
+		     pos)))
 	(t
 	 (imenu--flatten-index-alist pos concat-names new-prefix)))))
    index-alist))

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Sat, 11 May 2024 10:34:02 GMT) Full text and rfc822 format available.

Message #23 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Sat, 11 May 2024 13:33:03 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: 70846 <at> debbugs.gnu.org
> Date: Fri, 10 May 2024 19:45:37 +0300
> 
> >> BTW, the manual says in (info "(emacs) Imenu"):
> >>
> >>      You can customize the way the menus are sorted by setting the
> >>   variable ‘imenu-sort-function’.  By default, names are ordered as they
> >>   occur in the buffer; if you want alphabetic sorting, use the symbol
> >>   ‘imenu--sort-by-name’ as the value.  You can also define your own
> >>   comparison function by writing Lisp code.
> >>
> >> But imenu-sort-function affects only the mouse popup menu.
> >>
> >> To be able to customize sorting of imenu completion candidates
> >> in the minibuffer, another patch is needed that sets a category
> >> for sorting customization:
> >
> > I agree that it is better to sort the same way in both cases, so
> > changes to do that are welcome.
> 
> So now pushed.
> 
> > But please also amend the text in the manual to say so, because
> > currently it only talks about "menus", which could arguably be
> > interpreted as pertaining only to popup menus.
> 
> The "menus" above are pertaining only to popup menus,
> and the variable ‘imenu-sort-function’ can't be used
> to change the sorting order of Imenu completion candidates.
> Only the following customization changes this order:
> 
>   (add-to-list 'completion-category-overrides
>                '(imenu (display-sort-function . identity)))
> 
> Using this setting is especially essential for Imenu
> on a PDF document with doc-view.el to keep the order
> of chapters for the table of contents.
> 
> But I have no idea how to document this customization.

Now I'm confused: I thought the change you installed was supposed to
make sure the completion candidates are sorted using the same sort
order as determined by imenu-sort-function.  If not, then what did
your change do in this matter?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Sun, 12 May 2024 07:07:02 GMT) Full text and rfc822 format available.

Message #26 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Sun, 12 May 2024 09:55:38 +0300
>> >> BTW, the manual says in (info "(emacs) Imenu"):
>> >>
>> >>      You can customize the way the menus are sorted by setting the
>> >>   variable ‘imenu-sort-function’.  By default, names are ordered as they
>> >>   occur in the buffer; if you want alphabetic sorting, use the symbol
>> >>   ‘imenu--sort-by-name’ as the value.  You can also define your own
>> >>   comparison function by writing Lisp code.
>>
>> The "menus" above are pertaining only to popup menus,
>> and the variable ‘imenu-sort-function’ can't be used
>> to change the sorting order of Imenu completion candidates.
>> Only the following customization changes this order:
>>
>>   (add-to-list 'completion-category-overrides
>>                '(imenu (display-sort-function . identity)))
>>
>> Using this setting is especially essential for Imenu
>> on a PDF document with doc-view.el to keep the order
>> of chapters for the table of contents.
>>
>> But I have no idea how to document this customization.
>
> Now I'm confused: I thought the change you installed was supposed to
> make sure the completion candidates are sorted using the same sort
> order as determined by imenu-sort-function.  If not, then what did
> your change do in this matter?

Completions can be sorted only by 'display-sort-function'.
There is no other way to sort completions.
So the question remains: whether to document and how
the customization with 'completion-category-overrides' above?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Sun, 12 May 2024 07:12:02 GMT) Full text and rfc822 format available.

Message #29 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Sun, 12 May 2024 10:10:45 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: 70846 <at> debbugs.gnu.org
> Date: Sun, 12 May 2024 09:55:38 +0300
> 
> >> >> BTW, the manual says in (info "(emacs) Imenu"):
> >> >>
> >> >>      You can customize the way the menus are sorted by setting the
> >> >>   variable ‘imenu-sort-function’.  By default, names are ordered as they
> >> >>   occur in the buffer; if you want alphabetic sorting, use the symbol
> >> >>   ‘imenu--sort-by-name’ as the value.  You can also define your own
> >> >>   comparison function by writing Lisp code.
> >>
> >> The "menus" above are pertaining only to popup menus,
> >> and the variable ‘imenu-sort-function’ can't be used
> >> to change the sorting order of Imenu completion candidates.
> >> Only the following customization changes this order:
> >>
> >>   (add-to-list 'completion-category-overrides
> >>                '(imenu (display-sort-function . identity)))
> >>
> >> Using this setting is especially essential for Imenu
> >> on a PDF document with doc-view.el to keep the order
> >> of chapters for the table of contents.
> >>
> >> But I have no idea how to document this customization.
> >
> > Now I'm confused: I thought the change you installed was supposed to
> > make sure the completion candidates are sorted using the same sort
> > order as determined by imenu-sort-function.  If not, then what did
> > your change do in this matter?
> 
> Completions can be sorted only by 'display-sort-function'.
> There is no other way to sort completions.

Then what did the change you installed do wrt sorting of candidates?

> So the question remains: whether to document and how
> the customization with 'completion-category-overrides' above?

I cannot answer that unless I understand what we just installed and
why.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Sun, 12 May 2024 16:40:02 GMT) Full text and rfc822 format available.

Message #32 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Sun, 12 May 2024 19:37:14 +0300
>> >> >> BTW, the manual says in (info "(emacs) Imenu"):
>> >> >>
>> >> >>      You can customize the way the menus are sorted by setting the
>> >> >>   variable ‘imenu-sort-function’.  By default, names are ordered as they
>> >> >>   occur in the buffer; if you want alphabetic sorting, use the symbol
>> >> >>   ‘imenu--sort-by-name’ as the value.  You can also define your own
>> >> >>   comparison function by writing Lisp code.
>> >>
>> >> The "menus" above are pertaining only to popup menus,
>> >> and the variable ‘imenu-sort-function’ can't be used
>> >> to change the sorting order of Imenu completion candidates.
>> >> Only the following customization changes this order:
>> >>
>> >>   (add-to-list 'completion-category-overrides
>> >>                '(imenu (display-sort-function . identity)))
>> >>
>> >> Using this setting is especially essential for Imenu
>> >> on a PDF document with doc-view.el to keep the order
>> >> of chapters for the table of contents.
>> >>
>> >> But I have no idea how to document this customization.
>> >
>> > Now I'm confused: I thought the change you installed was supposed to
>> > make sure the completion candidates are sorted using the same sort
>> > order as determined by imenu-sort-function.  If not, then what did
>> > your change do in this matter?
>>
>> Completions can be sorted only by 'display-sort-function'.
>> There is no other way to sort completions.
>
> Then what did the change you installed do wrt sorting of candidates?

It allows the users to customize the sorting order of
completion candidates displayed by 'imenu'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Sun, 12 May 2024 17:18:01 GMT) Full text and rfc822 format available.

Message #35 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Sun, 12 May 2024 20:17:36 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: 70846 <at> debbugs.gnu.org
> Date: Sun, 12 May 2024 19:37:14 +0300
> 
> >> >> >> BTW, the manual says in (info "(emacs) Imenu"):
> >> >> >>
> >> >> >>      You can customize the way the menus are sorted by setting the
> >> >> >>   variable ‘imenu-sort-function’.  By default, names are ordered as they
> >> >> >>   occur in the buffer; if you want alphabetic sorting, use the symbol
> >> >> >>   ‘imenu--sort-by-name’ as the value.  You can also define your own
> >> >> >>   comparison function by writing Lisp code.
> >> >>
> >> >> The "menus" above are pertaining only to popup menus,
> >> >> and the variable ‘imenu-sort-function’ can't be used
> >> >> to change the sorting order of Imenu completion candidates.
> >> >> Only the following customization changes this order:
> >> >>
> >> >>   (add-to-list 'completion-category-overrides
> >> >>                '(imenu (display-sort-function . identity)))
> >> >>
> >> >> Using this setting is especially essential for Imenu
> >> >> on a PDF document with doc-view.el to keep the order
> >> >> of chapters for the table of contents.
> >> >>
> >> >> But I have no idea how to document this customization.
> >> >
> >> > Now I'm confused: I thought the change you installed was supposed to
> >> > make sure the completion candidates are sorted using the same sort
> >> > order as determined by imenu-sort-function.  If not, then what did
> >> > your change do in this matter?
> >>
> >> Completions can be sorted only by 'display-sort-function'.
> >> There is no other way to sort completions.
> >
> > Then what did the change you installed do wrt sorting of candidates?
> 
> It allows the users to customize the sorting order of
> completion candidates displayed by 'imenu'.

And the only way to customize that is via add-to-list as above?  IOW,
without the change you installed, even the add-to-list method would
not have worked?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Mon, 13 May 2024 07:00:02 GMT) Full text and rfc822 format available.

Message #38 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Mon, 13 May 2024 09:57:43 +0300
>> >> >> >> BTW, the manual says in (info "(emacs) Imenu"):
>> >> >> >>
>> >> >> >>      You can customize the way the menus are sorted by setting the
>> >> >> >>   variable ‘imenu-sort-function’.  By default, names are ordered as they
>> >> >> >>   occur in the buffer; if you want alphabetic sorting, use the symbol
>> >> >> >>   ‘imenu--sort-by-name’ as the value.  You can also define your own
>> >> >> >>   comparison function by writing Lisp code.
>> >> >>
>> >> >> The "menus" above are pertaining only to popup menus,
>> >> >> and the variable ‘imenu-sort-function’ can't be used
>> >> >> to change the sorting order of Imenu completion candidates.
>> >> >> Only the following customization changes this order:
>> >> >>
>> >> >>   (add-to-list 'completion-category-overrides
>> >> >>                '(imenu (display-sort-function . identity)))
>> >> >>
>> >> >> Using this setting is especially essential for Imenu
>> >> >> on a PDF document with doc-view.el to keep the order
>> >> >> of chapters for the table of contents.
>> >> >>
>> >> >> But I have no idea how to document this customization.
>> >> >
>> >> > Now I'm confused: I thought the change you installed was supposed to
>> >> > make sure the completion candidates are sorted using the same sort
>> >> > order as determined by imenu-sort-function.  If not, then what did
>> >> > your change do in this matter?
>> >>
>> >> Completions can be sorted only by 'display-sort-function'.
>> >> There is no other way to sort completions.
>> >
>> > Then what did the change you installed do wrt sorting of candidates?
>>
>> It allows the users to customize the sorting order of
>> completion candidates displayed by 'imenu'.
>
> And the only way to customize that is via add-to-list as above?  IOW,
> without the change you installed, even the add-to-list method would
> not have worked?

Yes, there was no way to customize sorting of Imenu completion candidates.

Ok, I could add display-sort-function directly to the imenu completing-read
that will depend on the value of display-sort-function.  Then there will be
no need to change the manual.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Mon, 13 May 2024 07:48:01 GMT) Full text and rfc822 format available.

Message #41 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Mon, 13 May 2024 10:46:32 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: 70846 <at> debbugs.gnu.org
> Date: Mon, 13 May 2024 09:57:43 +0300
> 
> >> >> >> >> BTW, the manual says in (info "(emacs) Imenu"):
> >> >> >> >>
> >> >> >> >>      You can customize the way the menus are sorted by setting the
> >> >> >> >>   variable ‘imenu-sort-function’.  By default, names are ordered as they
> >> >> >> >>   occur in the buffer; if you want alphabetic sorting, use the symbol
> >> >> >> >>   ‘imenu--sort-by-name’ as the value.  You can also define your own
> >> >> >> >>   comparison function by writing Lisp code.
> >> >> >>
> >> >> >> The "menus" above are pertaining only to popup menus,
> >> >> >> and the variable ‘imenu-sort-function’ can't be used
> >> >> >> to change the sorting order of Imenu completion candidates.
> >> >> >> Only the following customization changes this order:
> >> >> >>
> >> >> >>   (add-to-list 'completion-category-overrides
> >> >> >>                '(imenu (display-sort-function . identity)))
> >> >> >>
> >> >> >> Using this setting is especially essential for Imenu
> >> >> >> on a PDF document with doc-view.el to keep the order
> >> >> >> of chapters for the table of contents.
> >> >> >>
> >> >> >> But I have no idea how to document this customization.
> >> >> >
> >> >> > Now I'm confused: I thought the change you installed was supposed to
> >> >> > make sure the completion candidates are sorted using the same sort
> >> >> > order as determined by imenu-sort-function.  If not, then what did
> >> >> > your change do in this matter?
> >> >>
> >> >> Completions can be sorted only by 'display-sort-function'.
> >> >> There is no other way to sort completions.
> >> >
> >> > Then what did the change you installed do wrt sorting of candidates?
> >>
> >> It allows the users to customize the sorting order of
> >> completion candidates displayed by 'imenu'.
> >
> > And the only way to customize that is via add-to-list as above?  IOW,
> > without the change you installed, even the add-to-list method would
> > not have worked?
> 
> Yes, there was no way to customize sorting of Imenu completion candidates.
> 
> Ok, I could add display-sort-function directly to the imenu completing-read
> that will depend on the value of display-sort-function.  Then there will be
> no need to change the manual.

Except we should then remove the reference to "menus", right?  Because
if you do that, the customization of sorting order will affect both
the menus and the completion, right?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Tue, 14 May 2024 06:09:02 GMT) Full text and rfc822 format available.

Message #44 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Tue, 14 May 2024 09:05:09 +0300
[Message part 1 (text/plain, inline)]
>> Ok, I could add display-sort-function directly to the imenu completing-read
>> that will depend on the value of display-sort-function.  Then there will be
>> no need to change the manual.
>
> Except we should then remove the reference to "menus", right?  Because
> if you do that, the customization of sorting order will affect both
> the menus and the completion, right?

Indeed, this will require removing the reference to the mouse menus.

But when I tried to use imenu-sort-function for sorting the completions,
I found a problem that makes such change impossible.

The problem is that the default value of imenu-sort-function is nil.
This means that by default the items on the mouse menu are unsorted.
But the completions are sorted, and we can't change this default
behavior.  Therefore, imenu-sort-function can't define how the
completions are sorted.  So this is just a documentation task
that is done in this patch:

[imenu-completion-sort.patch (text/x-diff, inline)]
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 01a1462044c..8ab5033795d 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -378,6 +378,10 @@ Imenu
 symbol @code{imenu--sort-by-name} as the value.  You can also
 define your own comparison function by writing Lisp code.
 
+  You can also customize how Imenu completions are sorted by changing
+the variable @code{completion-category-overrides} and setting its
+@code{display-sort-function} for the category @code{imenu}.
+
   If Eglot is activated for the current buffer's project
 (@pxref{Projects}) and the current buffer's major mode, Eglot provides
 its own facility for producing the buffer's index based on the
diff --git a/etc/NEWS b/etc/NEWS
index 8a2c8950fd8..19564062d9f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1046,6 +1046,11 @@ point is not in a comment or a string.  It is by default bound to
 It defines whether to flatten the list of sections in an imenu
 or show it nested.
 
++++
+*** Imenu completions now can be sorted.
+You can customize the option 'completion-category-overrides'
+and set 'display-sort-function' for the category 'imenu'.
+
 ** Which Function mode
 
 +++
diff --git a/lisp/imenu.el b/lisp/imenu.el
index 93a544ff550..f255dcc7148 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -115,7 +115,10 @@ imenu-after-jump-hook
 (defcustom imenu-sort-function nil
   "The function to use for sorting the index mouse-menu.
 
-Affects only the mouse index menu.
+Affects only the mouse index menu.  If you want to change
+the sorting order of completions, you can customize
+the option `completion-category-overrides' and set
+`display-sort-function' for the category `imenu'.
 
 Set this to nil if you don't want any sorting (faster).
 The items in the menu are then presented in the order they were found

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Tue, 14 May 2024 06:35:01 GMT) Full text and rfc822 format available.

Message #47 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Tue, 14 May 2024 09:34:11 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: 70846 <at> debbugs.gnu.org
> Date: Tue, 14 May 2024 09:05:09 +0300
> 
> >> Ok, I could add display-sort-function directly to the imenu completing-read
> >> that will depend on the value of display-sort-function.  Then there will be
> >> no need to change the manual.
> >
> > Except we should then remove the reference to "menus", right?  Because
> > if you do that, the customization of sorting order will affect both
> > the menus and the completion, right?
> 
> Indeed, this will require removing the reference to the mouse menus.
> 
> But when I tried to use imenu-sort-function for sorting the completions,
> I found a problem that makes such change impossible.
> 
> The problem is that the default value of imenu-sort-function is nil.
> This means that by default the items on the mouse menu are unsorted.
> But the completions are sorted, and we can't change this default
> behavior.  Therefore, imenu-sort-function can't define how the
> completions are sorted.  So this is just a documentation task
> that is done in this patch:

Thanks, SGTM.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Tue, 28 May 2024 18:00:02 GMT) Full text and rfc822 format available.

Message #50 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Tue, 28 May 2024 20:53:18 +0300
[Message part 1 (text/plain, inline)]
>> +(defcustom imenu-flatten nil
>> +  "If non-nil, popup the completion buffer with a flattened menu.
>> +The string from `imenu-level-separator' is used to separate names of
>> +nested levels while flattening nested indexes with name concatenation."
>> +  :type 'boolean
>
> Here is another useful value for `imenu-flatten' that
> will show section names as a suffix instead of a prefix:

Here is the final patch that adds an option to group Imenu completions.

[imenu-flatten-group.patch (text/x-diff, inline)]
diff --git a/lisp/imenu.el b/lisp/imenu.el
index 93d84106ec1..3aec32fa708 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -151,15 +151,18 @@ imenu-level-separator
 (defcustom imenu-flatten nil
   "Whether to flatten the list of sections in an imenu or show it nested.
 If nil, use nested indexes.
-If t, pop up the completion buffer with a flattened menu.
+If `prefix', pop up the completion buffer with a flattened menu
+where section names are used as a prefix.
 If `annotation', use completion annotation as a suffix
 to append section names after the index names.
+If `group', split completions into groups.
 
 The string from `imenu-level-separator' is used to separate names of
 nested levels while flattening nested indexes with name concatenation."
   :type '(choice (const :tag "Nested" nil)
-                 (const :tag "By prefix" t)
-                 (const :tag "By suffix" annotation))
+                 (const :tag "By prefix" prefix)
+                 (const :tag "By annotation" annotation)
+                 (const :tag "By group" group))
   :version "30.1")
 
 (defcustom imenu-generic-skip-comments-and-strings t
@@ -758,7 +761,13 @@ imenu--completion-buffer
                          ,@(when (eq imenu-flatten 'annotation)
                              `(:annotation-function
                                ,(lambda (s) (get-text-property
-                                             0 'imenu-section s))))))
+                                             0 'imenu-section s))))
+                         ,@(when (eq imenu-flatten 'group)
+                             `(:group-function
+                               ,(lambda (s transform)
+                                  (if transform s
+                                    (get-text-property
+                                     0 'imenu-section s)))))))
           (unless imenu-eager-completion-buffer
             (minibuffer-completion-help)))
       (setq name (completing-read prompt
@@ -801,15 +810,20 @@ imenu--flatten-index-alist
 	    (new-prefix (and concat-names
 			     (if prefix
 				 (concat prefix imenu-level-separator name)
-			       (if (eq imenu-flatten 'annotation)
-                                   (propertize name 'imenu-choice item)
-                                 name)))))
+			       name))))
        (cond
 	((not (imenu--subalist-p item))
-	 (list (cons (if (and (eq imenu-flatten 'annotation) prefix)
-			 (propertize name 'imenu-section
-				     (format " (%s)" prefix))
-		       new-prefix)
+	 (list (cons (pcase imenu-flatten
+                       ('annotation
+                        (if prefix
+                            (propertize name
+                                        'imenu-section (format " (%s)" prefix)
+                                        'imenu-choice item)
+                          (propertize new-prefix 'imenu-choice item)))
+                       ('group (propertize name
+                                           'imenu-section (or prefix "*")
+                                           'imenu-choice item))
+                       (_ new-prefix))
 		     pos)))
 	(t
 	 (imenu--flatten-index-alist pos concat-names new-prefix)))))

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Wed, 29 May 2024 18:08:02 GMT) Full text and rfc822 format available.

Message #53 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Wed, 29 May 2024 21:05:32 +0300
close 70846 30.0.50
thanks

>>> +(defcustom imenu-flatten nil
>>> +  "If non-nil, popup the completion buffer with a flattened menu.
>>> +The string from `imenu-level-separator' is used to separate names of
>>> +nested levels while flattening nested indexes with name concatenation."
>>> +  :type 'boolean
>>
>> Here is another useful value for `imenu-flatten' that
>> will show section names as a suffix instead of a prefix:
>
> Here is the final patch that adds an option to group Imenu completions.

So now pushed and closed.




bug marked as fixed in version 30.0.50, send any further explanations to 70846 <at> debbugs.gnu.org and Juri Linkov <juri <at> linkov.net> Request was from Juri Linkov <juri <at> linkov.net> to control <at> debbugs.gnu.org. (Wed, 29 May 2024 18:08:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70846; Package emacs. (Thu, 06 Jun 2024 05:44:02 GMT) Full text and rfc822 format available.

Message #58 received at 70846 <at> debbugs.gnu.org (full text, mbox):

From: Yuan Fu <casouri <at> gmail.com>
To: Juri Linkov <juri <at> linkov.net>
Cc: 70846 <at> debbugs.gnu.org
Subject: Re: bug#70846: Imenu flatten
Date: Wed, 5 Jun 2024 22:35:35 -0700

> On May 29, 2024, at 11:05 AM, Juri Linkov <juri <at> linkov.net> wrote:
> 
> close 70846 30.0.50
> thanks
> 
>>>> +(defcustom imenu-flatten nil
>>>> +  "If non-nil, popup the completion buffer with a flattened menu.
>>>> +The string from `imenu-level-separator' is used to separate names of
>>>> +nested levels while flattening nested indexes with name concatenation."
>>>> +  :type 'boolean
>>> 
>>> Here is another useful value for `imenu-flatten' that
>>> will show section names as a suffix instead of a prefix:
>> 
>> Here is the final patch that adds an option to group Imenu completions.
> 
> So now pushed and closed.
> 

This is a great feature, thanks for working on it, Juri!

Yuan



bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Thu, 04 Jul 2024 11:24:07 GMT) Full text and rfc822 format available.

This bug report was last modified 22 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.