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[4]: bug#57996: 28.2; imenu doesn't differentiate overloaded c++ functions Date: Wed, 05 Oct 2022 13:45:05 +0000 Message-ID: References: <87v8p22wsz.fsf@posteo.net> Reply-To: Chris Hecker Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="------=_MB82838367-B5F7-4DA9-BD2E-734761B5C01C" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="6234"; 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 15:58:18 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 1og4ug-0001Py-6P for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 05 Oct 2022 15:58:18 +0200 Original-Received: from localhost ([::1]:34232 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1og4ue-0008OW-UQ for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 05 Oct 2022 09:58:16 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:33520) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1og4iv-00007g-34 for bug-gnu-emacs@gnu.org; Wed, 05 Oct 2022 09:46:20 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:57262) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1og4io-0008IV-KF for bug-gnu-emacs@gnu.org; Wed, 05 Oct 2022 09:46:05 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1og4io-0000ZV-Eo for bug-gnu-emacs@gnu.org; Wed, 05 Oct 2022 09:46:02 -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:46:02 +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.166497751529041 (code B ref 57996); Wed, 05 Oct 2022 13:46:02 +0000 Original-Received: (at 57996) by debbugs.gnu.org; 5 Oct 2022 13:45:15 +0000 Original-Received: from localhost ([127.0.0.1]:56338 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1og4i2-0007Up-Cu for submit@debbugs.gnu.org; Wed, 05 Oct 2022 09:45:15 -0400 Original-Received: from mail-pl1-f180.google.com ([209.85.214.180]:42982) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1og4hz-00073s-Th for 57996@debbugs.gnu.org; Wed, 05 Oct 2022 09:45:13 -0400 Original-Received: by mail-pl1-f180.google.com with SMTP id c24so5370236pls.9 for <57996@debbugs.gnu.org>; Wed, 05 Oct 2022 06:45:11 -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=rg0RkM2s5oA4umscQGTHW4fJwJrkYC5A9x/vWahj95o=; b=PZcmHx5WtEAENb9W/lOwuGJtfnB8+az73kSut/85VfmvLdRQXrCQSMtDvfjKNKT9yC 43l/y0/95kF7Hq7EyTFK8v+E4lEIIzT5y4BzlSqjIaGFLeBgqKRpF4Mfvg6mDZf00pie ZT29LLWwIdPylPyo9E52xFmHkgndyUNDO0STq9dfz7BLynhrPsF4PdYYL18ex/7e3+7a hQRs+mBn/KAUL7DuOJioKugAVIKFDIFYHgtsWsj8is/8RFrg7Pz25P9uFu0pLRCHjfVS MS4EcnhGfpWWmJO1V8HVTy4ZiAWagGuhu9NH5ZTozl54YTzROENU2rZLweEOI7C9n98V uY+A== 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=rg0RkM2s5oA4umscQGTHW4fJwJrkYC5A9x/vWahj95o=; b=X0ktJFF1OFXbd3CXioggvtnInb0W+DvM61YDFmjBqyUmflhSL+vhY8wbIWVRiSW8i6 RYeerbPjVmzkcsB/b4DPSCSjPbrjcrs/th2VEOq/isGAAjzqPt+VLB0z9FUjvaxKYq5Y icUiwF9YU2EMXw3hAwIyndafeHc6LnzZw+r04q48gTsK9pINuIqaYlmGrpDk0L74UIqG oV0qObkcbHKzM3BMjwwopDqK+foKK5kcAf2pX9iAOnoIQiyUU4pHX+XXi6WRM5BZUySH CQ3TcSKio8XRS2/jJo9tNrpw/EIpp07iN7SRhNycywyKD5iJV38IBWBxGWWC8HlZjxxk ehpQ== X-Gm-Message-State: ACrzQf1RSYRCvtRyiDpAMOz+6ZYkDuN9FLiPSyJkz8fmGSek65UzW8p8 UKkh2XssLmAlnwlPUwwuWTC8dQ== X-Google-Smtp-Source: AMsMyM6c88AMPKBJC7Fi0ucZRQx214hL4FvgEBrSlSiBrw5bzVCXH3Bs110Rtg9KgE9e75aHoxd9MQ== X-Received: by 2002:a17:902:720b:b0:178:83e9:11ec with SMTP id ba11-20020a170902720b00b0017883e911ecmr31452360plb.34.1664977505900; Wed, 05 Oct 2022 06:45:05 -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 bi4-20020a170902bf0400b0017f75654a33sm2722048plb.73.2022.10.05.06.45.05 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 05 Oct 2022 06:45:05 -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:244536 Archived-At: --------=_MB82838367-B5F7-4DA9-BD2E-734761B5C01C Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable 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 the=20 easiest function that was hookable on the pre-cached side of the code=20 (meaning it doesn't get called every imenu, just on *rescan*). It puts=20 the function names in a hash, and if they are dupes, it puts (n) after=20 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 I'd=20 >already hacked my own version of the c++ matching function, so maybe=20 >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 something=20 >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 overloaded=20 >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 simple=20 >>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 probab= ly >>>> > 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 f= rom >>>> > imenu. >>> >>>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 is a function which gets >>>_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 like >>>> clangd. >>> >>>Much more modern! >>> >>>> I've CC'ed Alan to see if he knows how this could be done by c++-mode >>>> 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 be >>>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). --------=_MB82838367-B5F7-4DA9-BD2E-734761B5C01C Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable

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

(defu= n 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).
--------=_MB82838367-B5F7-4DA9-BD2E-734761B5C01C--