Package: emacs;
Reported by: Tino Calancha <tino.calancha <at> gmail.com>
Date: Thu, 13 Sep 2018 18:20:02 UTC
Severity: wishlist
Found in version 26.1.50
Done: Tino Calancha <tino.calancha <at> gmail.com>
Bug is archived. No further changes may be made.
Message #47 received at 32731 <at> debbugs.gnu.org (full text, mbox):
From: Tino Calancha <tino.calancha <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: npostavs <at> gmail.com, 32731 <at> debbugs.gnu.org Subject: Re: bug#32731: 26.1.50; Ibuffer filter by mode: Handle >1 mode names Date: Fri, 21 Sep 2018 17:37:39 +0900
Eli Zaretskii <eliz <at> gnu.org> writes: >> From: Tino Calancha <tino.calancha <at> gmail.com> >> Date: Wed, 19 Sep 2018 18:23:52 +0900 >> Cc: 32731 <at> debbugs.gnu.org >> >> Following patch adds a key :composable, which also serves as >> documentation. > > Thanks, a few nits to the documentation parts: Thank you. I've amended the patch to address all the nits: --8<-----------------------------cut here---------------start------------->8--- commit 72e332c986304775e91020c88ded1ba9d7226023 Author: Tino Calancha <tino.calancha <at> gmail.com> Date: Fri Sep 21 17:32:57 2018 +0900 Ibuffer filter by modes: Accept several mode names Extend all mode filters so that they handle >1 mode. For instance, if the user wants to filter all buffers in C or C++ mode, then s?he can call the filter interactively with input: 'c-mode,c++-mode' (Bug#32731). * lisp/ibuf-macs.el(define-ibuffer-filter): Add key :accept-list. If the value of this key is non-nil, then the filter accepts either a single qualifier or a list of them; in the latter case, the resultant filter is the `or' composition of the individual ones. * lisp/ibuf-ext.el (ibuffer-filter-by-used-mode) (ibuffer-filter-by-mode, ibuffer-filter-by-derived-mode) Set :accept-list value non-nil. Interactively, accept a comma separated list of mode names. * etc/NEWS(Ibuffer): Announce this change. Co-authored-by: Noam Postavsky <npostavs <at> gmail.com> diff --git a/etc/NEWS b/etc/NEWS index 736955be0c..9f7e0544d5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -62,6 +62,11 @@ to reduce differences between developer and production builds. ** Ibuffer --- +*** All mode filters can now accept a list of symbols. +This means you can now easily filter several major modes, as well +as a single mode. + +--- *** New toggle 'ibuffer-do-toggle-lock', bound to 'L'. ** Gnus diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index d9949d2835..e3e0d0b578 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1228,28 +1228,33 @@ ibuffer-list-buffer-modes ;;;###autoload (autoload 'ibuffer-filter-by-mode "ibuf-ext") (define-ibuffer-filter mode - "Limit current view to buffers with major mode QUALIFIER." + "Limit current view to buffers with major mode(s) specified by QUALIFIER. +QUALIFIER is the mode name as a symbol or a list of symbols. +Called interactively, accept a comma separated list of mode names." (:description "major mode" :reader (let* ((buf (ibuffer-current-buffer)) (default (if (and buf (buffer-live-p buf)) (symbol-name (buffer-local-value 'major-mode buf))))) - (intern - (completing-read + (mapcar #'intern + (completing-read-multiple (if default (format "Filter by major mode (default %s): " default) "Filter by major mode: ") obarray - #'(lambda (e) - (string-match "-mode\\'" (symbol-name e))) - t nil nil default)))) + (lambda (e) + (string-match "-mode\\'" (if (symbolp e) (symbol-name e) e))) + t nil nil default))) + :accept-list t) (eq qualifier (buffer-local-value 'major-mode buf))) ;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext") (define-ibuffer-filter used-mode - "Limit current view to buffers with major mode QUALIFIER. -Called interactively, this function allows selection of modes + "Limit current view to buffers with major mode(s) specified by QUALIFIER. +QUALIFIER is the mode name as a symbol or a list of symbols. + +Called interactively, accept a comma separated list of mode names currently used by buffers." (:description "major mode in use" :reader @@ -1257,23 +1262,29 @@ used-mode (default (if (and buf (buffer-live-p buf)) (symbol-name (buffer-local-value 'major-mode buf))))) - (intern - (completing-read + (mapcar #'intern + (completing-read-multiple (if default (format "Filter by major mode (default %s): " default) "Filter by major mode: ") - (ibuffer-list-buffer-modes) nil t nil nil default)))) + (ibuffer-list-buffer-modes) nil t nil nil default))) + :accept-list t) (eq qualifier (buffer-local-value 'major-mode buf))) ;;;###autoload (autoload 'ibuffer-filter-by-derived-mode "ibuf-ext") (define-ibuffer-filter derived-mode - "Limit current view to buffers whose major mode inherits from QUALIFIER." + "Limit current view to buffers with major mode(s) specified by QUALIFIER. +QUALIFIER is the mode name as a symbol or a list of symbols. + Restrict the view to buffers whose major mode derivates + from modes specified by QUALIFIER. +Called interactively, accept a comma separated list of mode names." (:description "derived mode" :reader - (intern - (completing-read "Filter by derived mode: " - (ibuffer-list-buffer-modes t) - nil t))) + (mapcar #'intern + (completing-read-multiple "Filter by derived mode: " + (ibuffer-list-buffer-modes t) + nil t)) + :accept-list t) (with-current-buffer buf (derived-mode-p qualifier))) ;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext") diff --git a/lisp/ibuf-macs.el b/lisp/ibuf-macs.el index 6a70a8341a..066d9ac2d9 100644 --- a/lisp/ibuf-macs.el +++ b/lisp/ibuf-macs.el @@ -282,12 +282,16 @@ ibuffer-save-marks (cl-defmacro define-ibuffer-filter (name documentation (&key reader - description) + description + accept-list) &rest body) "Define a filter named NAME. DOCUMENTATION is the documentation of the function. READER is a form which should read a qualifier from the user. DESCRIPTION is a short string describing the filter. +ACCEPT-LIST is a boolean; if non-nil, the filter accepts either +a single condition or a list of them; in the latter +case the filter is the `or' composition of the conditions. BODY should contain forms which will be evaluated to test whether or not a particular buffer should be displayed or not. The forms in BODY @@ -296,29 +300,40 @@ ibuffer-save-marks \(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" (declare (indent 2) (doc-string 2)) - (let ((fn-name (intern (concat "ibuffer-filter-by-" (symbol-name name))))) + (let ((fn-name (intern (concat "ibuffer-filter-by-" (symbol-name name)))) + (filter (make-symbol "ibuffer-filter")) + (qualifier-str (make-symbol "ibuffer-qualifier-str"))) `(progn (defun ,fn-name (qualifier) ,(or documentation "This filter is not documented.") (interactive (list ,reader)) - (if (null (ibuffer-push-filter (cons ',name qualifier))) - (message "%s" - (format ,(concat (format "Filter by %s already applied: " description) - " %s") - qualifier)) - (message "%s" - (format ,(concat (format "Filter by %s added: " description) - " %s") - qualifier)) - (ibuffer-update nil t))) + (let ((,filter (cons ',name qualifier)) + (,qualifier-str qualifier)) + ,(when accept-list + `(progn + (unless (listp qualifier) (setq qualifier (list qualifier))) + ;; Reject equivalent filters: (or f1 f2) is same as (or f2 f1). + (setq qualifier (sort (delete-dups qualifier) #'string-lessp)) + (setq ,filter (cons ',name (car qualifier))) + (setq ,qualifier-str + (mapconcat (lambda (m) (if (symbolp m) (symbol-name m) m)) + qualifier ",")) + (when (cdr qualifier) ; Compose individual filters with `or'. + (setq ,filter `(or ,@(mapcar (lambda (m) (cons ',name m)) qualifier)))))) + (if (null (ibuffer-push-filter ,filter)) + (message ,(format "Filter by %s already applied: %%s" description) + ,qualifier-str) + (message ,(format "Filter by %s added: %%s" description) + ,qualifier-str) + (ibuffer-update nil t)))) (push (list ',name ,description (lambda (buf qualifier) - (condition-case nil - (progn ,@body) - (error (ibuffer-pop-filter) - (when (eq ',name 'predicate) - (error "Wrong filter predicate: %S" - qualifier)))))) + (condition-case nil + (progn ,@body) + (error (ibuffer-pop-filter) + (when (eq ',name 'predicate) + (error "Wrong filter predicate: %S" + qualifier)))))) ibuffer-filtering-alist) :autoload-end))) --8<-----------------------------cut here---------------end--------------->8--- In GNU Emacs 27.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11) Repository revision: 7f3877e83405a089b580fe9d0342dc0b6c08cbfc
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.