From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: "Chris Hecker" Newsgroups: gmane.emacs.bugs Subject: bug#57996: Re[5]: bug#57996: 28.2; imenu doesn't differentiate overloaded c++ functions Date: Wed, 05 Oct 2022 13:58:18 +0000 Message-ID: References: <87v8p22wsz.fsf@posteo.net> Reply-To: Chris Hecker Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="------=_MB06998888-894C-417D-A1E9-F40006E2D59F" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="6386"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: eM_Client/8.2.1721.0 Cc: 57996@debbugs.gnu.org To: "Alan Mackenzie" , "Philip Kaludercic" Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Oct 05 16:37:14 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1og5WL-0001S3-47 for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 05 Oct 2022 16:37:13 +0200 Original-Received: from localhost ([::1]:48542 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1og5WK-0003Et-46 for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 05 Oct 2022 10:37:12 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:44238) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1og4vO-00027H-FA for bug-gnu-emacs@gnu.org; Wed, 05 Oct 2022 09:59:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:58672) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1og4vO-0003rG-3V for bug-gnu-emacs@gnu.org; Wed, 05 Oct 2022 09:59:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1og4vN-0001Dr-TK for bug-gnu-emacs@gnu.org; Wed, 05 Oct 2022 09:59:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: "Chris Hecker" Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 05 Oct 2022 13:59:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 57996 X-GNU-PR-Package: emacs Original-Received: via spool by 57996-submit@debbugs.gnu.org id=B57996.16649783104661 (code B ref 57996); Wed, 05 Oct 2022 13:59:01 +0000 Original-Received: (at 57996) by debbugs.gnu.org; 5 Oct 2022 13:58:30 +0000 Original-Received: from localhost ([127.0.0.1]:57750 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1og4ur-0001D5-Js for submit@debbugs.gnu.org; Wed, 05 Oct 2022 09:58:30 -0400 Original-Received: from mail-pf1-f174.google.com ([209.85.210.174]:34467) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1og4un-0001Cq-Te for 57996@debbugs.gnu.org; Wed, 05 Oct 2022 09:58:27 -0400 Original-Received: by mail-pf1-f174.google.com with SMTP id f140so10631792pfa.1 for <57996@debbugs.gnu.org>; Wed, 05 Oct 2022 06:58:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=d6-com.20210112.gappssmtp.com; s=20210112; h=mime-version:user-agent:reply-to:references:in-reply-to:message-id :date:cc:subject:to:from:from:to:cc:subject:date:message-id:reply-to; bh=WGCEzUKdjvAfzlZSFeLaRx8BbW2RS/WgwmfPQjDukE0=; b=Fjf9airwRFpO8u9kGuLnU0KzkbZ7zD8kf6S1wV8cXM9NxQ1y/DNq68bzCJjRZ/3EEY cFc50OPuvfEPL/zO7RO4v/lUIzxeU6qA4UMPzXxWquiLb1REhWghslzK8nt5fjn4IvTi ypKGlACS1QeNRs4tz5jKspql/P4f6kdGJA9BjTyx64XiHx1JyI8g3TmChjUgqYcxkmPq ZbxAQtyzkbgygEfL3OmIF/nBh/xM59siId2M3Ad0BOcLpQBhK+kIDrmCsIn1+iE+XJCF FSleX8/X6PYTRIflNprlZahBHHNa74EBv0TQi3/fnSAagFCGeJsyAr3Fj68dYSZl6Qpu 1/Gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:reply-to:references:in-reply-to:message-id :date:cc:subject:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=WGCEzUKdjvAfzlZSFeLaRx8BbW2RS/WgwmfPQjDukE0=; b=kV7nbKs6wXW2phUqhP9rDnHvN21Oic5CFtHPJ3wjCP8aLD6ViA7/923YZoSzrP7Kmt EgdGy9xyudaHh61uttnEQwNaCp9/raBMyfYWqSJUMri9rj9Hx7+dPp6xQaCOgdCmRPx/ dla4c7vEEoY4gx61/K+CAs3h+hECktWx6ldqe1rYvi9/TzJBBlHgzGxaPeR5HnkfGP4b nBQzMiVRrI/xGkeTy7QA2gqmilMzZaDGg+Vz6c5Xlx5A6s0s986uFWvh6CFuOnJsv/li QIYrjDFZSe7wfbiS44Z02e+HTF132rj50szhukOLJOnyqsthGEYjs/dsOYNqcBVYkCAD EmrQ== X-Gm-Message-State: ACrzQf1EZSWA+vewKoQSKr82U3IEREclPz+c9J6AC5gDchI6jnSRaHiw KKpY3QWfLDCefDCAyqUyB3vpTw== X-Google-Smtp-Source: AMsMyM7+s9GdH8hMWs9fXZoLj+rSEqqV9nVPsP7BOpbNIaJ6oz/g9bpLiI7RdgSW/lrqC3sfy/uw2g== X-Received: by 2002:a63:83c8:0:b0:44c:94b3:6a3a with SMTP id h191-20020a6383c8000000b0044c94b36a3amr4016pge.142.1664978299930; Wed, 05 Oct 2022 06:58:19 -0700 (PDT) Original-Received: from [192.168.1.217] (157-131-207-86.fiber.dynamic.sonic.net. [157.131.207.86]) by smtp.gmail.com with ESMTPSA id v20-20020a170902f0d400b00176cdd7e4c6sm10537214pla.50.2022.10.05.06.58.19 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 05 Oct 2022 06:58:19 -0700 (PDT) In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:244545 Archived-At: --------=_MB06998888-894C-417D-A1E9-F40006E2D59F Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Er, wait, this won't handle nested alists, I'll fix it tomorrow. Chris ------ Original Message ------ From: "Chris Hecker" To: "Alan Mackenzie" ; "Philip Kaludercic"=20 Cc: 57996@debbugs.gnu.org Sent: 2022-10-05 06:45:05 Subject: Re[4]: bug#57996: 28.2; imenu doesn't differentiate overloaded=20 c++ functions > >Okay, I figured out a way to do this that works pretty easily, and the=20 >same idea could be integrated into imenu fairly trivially: > >>(defun checker-imenu-make-unique-alist (index-alist) >> "De-duplicate the imenu alist by adding indices to duplicate names." >> (let ((h (make-hash-table :test #'equal))) >> (mapc (lambda (el) >> (let* ((k (car el)) >> (v (gethash k h))) >> (if v >> (let ((n (car v))) >> (if (=3D n 1) >> (setcar (car (cdr v)) (format "%s(1)" k))) >> (setq n (1+ n)) >> (puthash k '(n nil) h) >> (setcar el (format "%s(%d)" k n))) >> (puthash k (list 1 el) h)))) >> index-alist))) >>(advice-add 'imenu--truncate-items :filter-return=20 >>#'checker-imenu-make-unique-alist) > >So this just hooks the imenu--truncate-items function because it was=20 >the easiest function that was hookable on the pre-cached side of the=20 >code (meaning it doesn't get called every imenu, just on *rescan*). It=20 >puts the function names in a hash, and if they are dupes, it puts (n)=20 >after the name. Works great. > >Chris > > > >------ Original Message ------ >From: "Chris Hecker" >To: "Alan Mackenzie" ; "Philip Kaludercic"=20 > >Cc: 57996@debbugs.gnu.org >Sent: 2022-10-05 04:15:12 >Subject: Re[3]: bug#57996: 28.2; imenu doesn't differentiate overloaded=20 >c++ functions > >> >>Hmm... >> >>item is selected by the user. This function is called with >>arguments consisting of the item name, the buffer position, and >>the ARGUMENTS. >> >>This looks like it might work... I just opened my .emacs and found=20 >>I'd already hacked my own version of the c++ matching function, so=20 >>maybe I'll try this. >> >>A few minutes later... >> >>Okay, so this function does indeed get called, but both Function=20 >>elements in the imenu list pass the marker for the first Function, so=20 >>that's unfortunate... I will look at that... >> >>Another few minutes... >> >>Well, it looks like imenu--generic-function generates the right alist=20 >>with the two functions and the two different markers, so it's=20 >>something about choosing in the buffer... >> >>Here's the alist return, looks good: >> >>(("Function" . #) >> ("Function" . #) >> ("Bar" . #)) >> >>I should sleep, but maybe there's just a bug in the code that selects=20 >>the function, or it searches by name instead of by index. I wish=20 >>there was some way for the regex match to return a mangled name...I'll=20 >>look into imenu next. >> >>Chris >> >>------ Original Message ------ >>From: "Chris Hecker" >>To: "Alan Mackenzie" ; "Philip Kaludercic"=20 >> >>Cc: 57996@debbugs.gnu.org >>Sent: 2022-10-05 03:47:06 >>Subject: Re[2]: bug#57996: 28.2; imenu doesn't differentiate=20 >>overloaded c++ functions >> >>> >>>Yeah, I should probably switch to something a little more modern, but=20 >>>imenu has the advantage of just being there and working most of the=20 >>>time across all machines and shells and stuff. It definitely gets=20 >>>confused occasionally (like it doesn't find inline functions in class=20 >>>declarations) but this overload thing seemed like it might be a=20 >>>simple fix. >>> >>> >>>The scanning interface to imenu allows just function names to be >>>collected. It doesn't allow anything extra (such as a line number) to >>>be included into the alist. >>> >>>I guess you could mangle the name to include the line number or match=20 >>>number...kinda hacky but it'd work...maybe I'll take a look. >>> >>>Chris >>> >>> >>>------ Original Message ------ >>>From: "Alan Mackenzie" >>>To: "Philip Kaludercic" >>>Cc: "Chris Hecker" ; 57996@debbugs.gnu.org >>>Sent: 2022-10-05 03:31:11 >>>Subject: Re: bug#57996: 28.2; imenu doesn't differentiate overloaded=20 >>>c++ functions >>> >>>>Hello, Chris and Philip. >>>> >>>>On Sun, Oct 02, 2022 at 13:13:16 +0000, Philip Kaludercic wrote: >>>>> "Chris Hecker" writes: >>>> >>>>> > With this dumb c++ file: >>>>> > ---- >>>>> > int Function( int n ) { >>>>> > return n; >>>>> > } >>>>> > int Function( float v ) { >>>>> > return (int)(v + 0.5); >>>>> > } >>>>> > ---- >>>> >>>>> > Hitting imenu only gives a single Function entry. It should proba= bly >>>>> > give two, maybe with a line number after them like "Function(123)" = or >>>>> > whatever. Currently there's no way to get to the second Function= from >>>>> > imenu. >>>> >>>>imenu is old and rather simplistic. It parses a buffer, then stores th= e >>>>results in an association list. It then uses the function assoc on tha= t >>>>list to get "the" match. What we could do with is a function which get= s >>>>_all_ the matches from an alist, and I've asked on emacs-devel about >>>>this. >>>> >>>>> Note that this is not the case when using Eglot and a LSP server lik= e >>>>> clangd. >>>> >>>>Much more modern! >>>> >>>>> I've CC'ed Alan to see if he knows how this could be done by c++-mod= e >>>>> itself. >>>> >>>>I'm pretty sure it couldn't be. I think it would involve enhancing >>>>imenu. The scanning interface to imenu allows just function names to b= e >>>>collected. It doesn't allow anything extra (such as a line number) to >>>>be included into the alist. >>>> >>>>I've looked at problems with imenu in C++ Mode before, but got bogged >>>>down without coming up with a workable solution. There the problem was >>>>identically named methods in different classes, or something like that. >>>> >>>>So, maybe we can enhance imenu. But not for Emacs 29. >>>> >>>>-- >>>>Alan Mackenzie (Nuremberg, Germany). --------=_MB06998888-894C-417D-A1E9-F40006E2D59F Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable

Er,= wait, this won't handle nested alists, I'll fix it tomorrow.
Chris


------ Original Message ------
From: "Chris Hecker" <checker@d6.= com>
To: "Alan Mackenzie" <acm@muc.de&= gt;; "Philip Kaludercic" <philipk@= posteo.net>
Sent: 2022-10-05 06:45:05
Subject: Re[4]: bug#57996: 28.2; imenu doesn't differentiate overloade= d c++ functions


Okay, I figured out a way to do this that works prett= y easily, and the same idea could be integrated into imenu fairly trivially= :

(defun checker-imenu-make-unique-alist (index-alist= )
=C2=A0 "De-duplicate the imenu alist by adding indices to duplic= ate names."
=C2=A0 (let ((h (make-hash-table :test #'equal)))
=C2=A0 =C2=A0 (mapc (lambda (el)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((k (car el))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0(v (gethash k h)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if v
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= let ((n (car v)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (if (=3D n 1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 (setcar (car (cdr v)) (format "%s(1)" k)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (setq n (1+ n))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (puthash k '(n nil) h)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (setcar el (format "%s(%d)" k n)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (puthash = k (list 1 el) h))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 index-alist)))
(advice-add 'imenu--truncate-items :filter-return #'checker-imen= u-make-unique-alist)

So this just hooks the imenu--trun= cate-items function because it was the easiest function that was hookable o= n the pre-cached side of the code (meaning it doesn't get called every imen= u, just on *rescan*).=C2=A0 It puts the function names in a hash, and if th= ey are dupes, it puts (n) after the name.=C2=A0 Works great.
Chris



------ Original Message ------
From: "Chris Hecker" <checker@d6.= com>
To: "Alan Mackenzie" <acm@muc.de&= gt;; "Philip Kaludercic" <philipk@= posteo.net>
Sent: 2022-10-05 04:15:12
Subject: Re[3]: bug#57996: 28.2; imenu doesn't differentiate overloade= d c++ functions


Hmm...

item is= selected by the user.=C2=A0 This function is called with
arguments consisting of the item name, the buffer position, and
the ARGUMENTS.

This looks = like it might work...=C2=A0 I just opened my .emacs and found I'd already= hacked my own version of the c++ matching function, so maybe I'll try this.=

A few minutes later...

Okay, so this function does indeed get called, but both Function element= s in the imenu list pass the marker for the first Function, so that's unfor= tunate...=C2=A0 I will look at that...

Another f= ew minutes...

Well, it looks like imenu--generic= -function generates the right alist with the two functions and the two diff= erent markers, so it's something about choosing in the buffer...
=
Here's the alist return, looks good:
=
(("Function"= . #<marker at 2 in c.cpp>)
=C2=A0("Function" . #<marker at 41 in c.cpp>)
=C2=A0("Bar" . #<marker at 95 in c.cpp>))

I should sleep, bu= t maybe there's just a bug in the code that selects the function, or it sea= rches by name instead of by index.=C2=A0 =C2=A0I wish there was some way fo= r the regex match to return a mangled name...I'll look into imenu next.

Chris

------ Original Message ------
From: "Chris Hecker" <checker@d6.= com>
To: "Alan Mackenzie" <acm@muc.de&= gt;; "Philip Kaludercic" <philipk@= posteo.net>
Sent: 2022-10-05 03:47:06
Subject: Re[2]: bug#57996: 28.2; imenu doesn't differentiate overloade= d c++ functions


Yeah, I should probably switch to something a little= more modern, but imenu has the advantage of just being there and working mo= st of the time across all machines and shells and stuff.=C2=A0 It definitel= y gets confused occasionally (like it doesn't find inline functions in clas= s declarations) but this overload thing seemed like it might be a simple fi= x.


The scanning interface to imenu allow= s just function names to be
collected. It doesn't allow anything extra (such = as a line number) to
be included into the alist.

I guess you could mangle the name to include the li= ne number or match number...kinda hacky but it'd work...maybe I'll take a l= ook.

Chris


------ Original Message ------
From: "Alan Mackenzie" <acm@muc.de>
Sent: 2022-10-05 03:31:11
Subject: Re: bug#57996: 28.2; imenu doesn't differentiate overloaded c= ++ functions

Hello, Chris and Philip.
=C2=A0
On Sun, Oct 02, 2022 at 13:13:16 +0000, Philip Ka= ludercic wrote:
=C2=A0
> With this dumb c++ file:
> ----
> int Function( int n ) {
> return n;
> }
> int Function( float v ) {
> return (int)(v + 0.5);
> }
> ----
=C2=A0
> Hitting imenu only gives a single Function= entry. It should probably
> give two, maybe with a line number after th= em like "Function(123)" or
> whatever. Currently there's no way to get= to the second Function from
> imenu.
=C2=A0
imenu is old and rather simplistic. It parses a= buffer, then stores the
results in an association list. It then uses the = function assoc on that
list to get "the" match. What we could do with i= s a function which gets
_all_ the matches from an alist, and I've asked o= n emacs-devel about
this.
=C2=A0
Note that this is not the case when using Eglot= and a LSP server like
clangd.
=C2=A0
Much more modern!
=C2=A0
I've CC'ed Alan to see if he knows how this coul= d be done by c++-mode
itself.
=C2=A0
I'm pretty sure it couldn't be. I think it would = involve enhancing
imenu. The scanning interface to imenu allows ju= st function names to be
collected. It doesn't allow anything extra (such = as a line number) to
be included into the alist.
=C2=A0
I've looked at problems with imenu in C++ Mode be= fore, but got bogged
down without coming up with a workable solution. = There the problem was
identically named methods in different classes, o= r something like that.
=C2=A0
So, maybe we can enhance imenu. But not for Emac= s 29.
=C2=A0
--
Alan Mackenzie (Nuremberg, Germany).
--------=_MB06998888-894C-417D-A1E9-F40006E2D59F--