minad / consult

:mag: consult.el - Consulting completing-read
GNU General Public License v3.0
1.12k stars 98 forks source link

Decorating consult-imenu-multi output with the origin #983

Closed DivineDominion closed 1 month ago

DivineDominion commented 1 month ago

consult-imenu-multi (provided the files are being visited) is very good as a general "jump to function" tool.

I was looking into how consult assembles and displays imenu entries with the intent to maybe get marginalia.el to display the buffer origin next to each line, because with generic names like "insert" I always need a bit to parse which function I'm looking for.

Here's an example; please excuse the PHP :)

consult-line-multi consult-imenu-multi
2024-03-23 12-16-15 Emacs -  Minibuf-1@2x 2024-03-23 12-16-31 Emacs -  Minibuf-1@2x

imenu already groups by type, so it can't get consult-line-multi's file headings.

So I was looking to maybe use horizontal space a bit more cleverly and display the file name in another column.

public function insert(string $fullName, string $email): Customer {                BufferA.php
public function insertOrFind(string $fullName, string $email): Customer {          BufferB.php
public function insert(Purchase $purchase): Purchase {                             BufferC.php
private function insertProduct(int $customerId, string $productName): void         BufferD.php
public function testInsert(): void                                                 BufferE.php

(I'm using vertico and marginalia, so maybe marginalia would work? But how I'm not sure.)

I figured out that consult-imenu prefers imenu-markers, and that markers carry some metadata like the origin buffer that can be queried with (marker-buffer MARKER). So with (buffer-name (marker-buffer MARKER)) I can get to the info.

consult-imenu--cache was useful to inspect values; they seem to be cons'es of the consult imenu item and the imenu marker

(#("Functions consult-imenu--select" 0 9
    (face consult-imenu-prefix consult--type 102)
    10 31
    (face font-lock-function-name-face))
  . #<marker at 1 in untitled<2>>)

But how to get to the cdr of each element beats me.

I have trouble parsing how to tweak consult--read invocations, though, so I got stuck there. My interpretation:

Using the :annotate keyword got me to a place where I could do stuff with the candidate, but the candidate at that point in the function is the car of imenu items, so the marker is missing. -- Either way this doesn't play well with marginalia in my experiments, but worked great when marginalia is disabled.

(In the process I discovered the preview functionality, so maybe that's an option for anybody else who stumbled upon this issue.)

Is there a way to get to the imenu marker and use it to annotate multi imenu items with the buffer name or file name of each item?