Subject: bug#72210: 31.0.50; Feature request: multi-category support in `icomplete-fido-kill'.

From: Fernando de Morais <[email-masked]>
Date: Mon, 02 Sep 2024 13:23:19 -0300

Hello Stefan,

Stefan Monnier <[email-masked]> writes:

>> `icomplete-fido-kill' works very well, but cannot handle the deletion of
>> files or killing buffers when they are behind a multi-category
>> ``situation''.  Add this would be useful for those of us that combine
>> `icomplete' with, e.g., `consult-buffer'.
>
> Can you provide a recipe?  I'm not sufficiently familiar with that code
> to really understand the problem you're facing.

Sure!

Please, install the `consult' package and, in an emacs -Q session,
evaluate the following:

#+begin_src emacs-lisp
(progn
  (package-initialize)
  (load-library "consult")
  (icomplete-vertical-mode t)
  (keymap-set icomplete-minibuffer-map "C-k" 'icomplete-fido-kill))
#+end_src

- Then, ``M-x consult-buffer'';
- Type *M (this should turn the `*Messages*' buffer the current
  candidate);
- Then ``C-k''

The following message should appear in the minibuffer:

[Sorry, don’t know how to kill things for ‘multi-category’]

The same happens when we try to use `icomplete-fido-kill' in files
listed by `consult-buffer'.

The expected result would be for `icomplete-fido-kill' to work normally,
killing the buffer, even though it is listed by `consult-buffer'.

>> What follows is just the ``hacky'' approach that's currently being used
>> in my init:
>
> Any chance you can make it a patch against `icomplete.el`?

Follows attached!  This is my first patch, so I might have made
mistakes, but I'm here to adjust whatever you deem necessary.

-- 
Regards,
Fernando de Morais.
>From 7fd715580d70d1c7cb7dbbe3035a439c4d06c49d Mon Sep 17 00:00:00 2001
From: Fernando de Morais <[email-masked]>
Date: Mon, 2 Sep 2024 13:14:04 -0300
Subject: [PATCH] Add support for multi-category to icomplete-fido-kill

* etc/NEWS: Announce the multi-category support in 'icomplete-fido-kill'.
* lisp/icomplete.el (icomplete--refine-multi-category): New function.
(icomplete-fido-kill): Apply the helper function to refine
'multi-category' to its actual type.
---
 etc/NEWS          |  7 +++++++
 lisp/icomplete.el | 16 ++++++++++++++--
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 1e66f084117..86c2995cf19 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -65,6 +65,13 @@ different values for completion-affecting variables like
 applies for the styles configuration in 'completion-category-overrides'
 and 'completion-category-defaults'.
 
+** Icomplete
+
+---
+*** 'icomplete-fido-kill' now works within multi-category environments.
+This function can now delete a file or kill a buffer within a
+multi-category environment, such as 'consult-buffer'.
+
 ** Windows
 
 +++
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index 2ea5e36fa88..1ef861ff270 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -317,6 +317,16 @@ Return non-nil if something was stepped."
 
 ;;;_* Helpers for `fido-mode' (or `ido-mode' emulation)
 
+(defun icomplete--refine-multi-category (target)
+  "Refine `multi-category' TARGET to its actual type."
+  (or (let ((mc (get-text-property 0 'multi-category target)))
+        (cond
+         ;; The `cdr' of the `multi-category' property can be a buffer object.
+         ((and (eq (car mc) 'buffer) (buffer-live-p (cdr mc)))
+  	(cons 'buffer (buffer-name (cdr mc))))
+         ((stringp (cdr mc)) mc)))
+      (cons 'general target)))
+
 (defun icomplete-fido-kill ()
   "Kill line or current completion, like `ido-mode'.
 If killing to the end of line make sense, call `kill-line',
@@ -330,8 +340,10 @@ require user confirmation."
     (if (< (point) end)
         (call-interactively 'kill-line)
       (let* ((all (completion-all-sorted-completions))
-             (thing (car all))
-             (cat (icomplete--category))
+             (refined-pair (when (eq 'multi-category (icomplete--category))
+                             (icomplete--refine-multi-category (car all))))
+             (cat (or (car-safe refined-pair) (icomplete--category)))
+             (thing (or (cdr-safe refined-pair) (car all)))
              (action
               (cl-case cat
                 (buffer
-- 
2.46.0