Subject: bug#32731: 26.1.50; Ibuffer filter by mode: Handle >1 mode names

From: Tino Calancha <[email-masked]>
Date: Fri, 14 Sep 2018 05:04:33 +0900 (JST)

On Thu, 13 Sep 2018, Noam Postavsky wrote:

> On 13 September 2018 at 14:19, Tino Calancha <[email-masked]> wrote:
>
>> +;;;###autoload
>> +(defun ibuffer-filter-by-used-modes(modes)
>> +  "Limit current view to buffers with major mode in MODES.
>> +MODES is a list of mode names (symbols).
>> +When called interactively, accept the mode names separated by commas."
>> +  (interactive
>> +   (let* ((buf (ibuffer-current-buffer))
>> +          (default (if (and buf (buffer-live-p buf))
>> +                       (symbol-name (buffer-local-value
>> +                                     'major-mode buf)))))
>> +     (list
>> +      (mapcar #'intern
>> +              (split-string
>> +               (completing-read
>> +                (if default
>> +                    (format "Filter by major mode (default %s): " default)
>> +                  "Filter by major mode: ")
>> +                (ibuffer-list-buffer-modes)
>> +                nil nil nil nil default)
>> +               "\\s-*,\\s-*" t)))))
>
> This will use completion only for the first mode, right?
Yeah, that's right.
> Perhaps completing-read-multiple would make more sense here.
Hummmm, it sounds like a good idea.  I will look on it.

>> +  (setq modes (delete-dups modes))
>> +  (mapc #'ibuffer-filter-by-used-mode modes)
>> +  (let ((nb_modes (length modes)))
>> +    (when (>= nb_modes 2)
>> +      (cl-loop repeat (- nb_modes 2) do (ibuffer-or-filter))
>> +      (message nil)
>
> What's this `message' call for?
To clean the minibuffer after the second filter fails;
before you do the composition, you have an implicit AND, so
you are requiring:
(and (eq major-mode mode1-mode) (eq major-mode mode2-mode))
;; This fails
;; after  `ibuffer-or-filter' previous line is changed to:
(or (eq major-mode mode1-mode) (eq major-mode mode2-mode))

>> +      (ibuffer-or-filter))))
>
> Maybe it's simpler to construct the filter directly? As in:
>
>  (push `(or ,@(mapcar (lambda (m) `(used-mode . ,m)) modes))
>        ibuffer-filtering-qualifiers)
>  (ibuffer-update nil t)
Right, much more elegant.  Thank you!
I will update the patch accordingly