diff options
Diffstat (limited to 'lisp/ibuf-macs.el')
-rw-r--r-- | lisp/ibuf-macs.el | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/lisp/ibuf-macs.el b/lisp/ibuf-macs.el index 6f7b492b821..72a35a53315 100644 --- a/lisp/ibuf-macs.el +++ b/lisp/ibuf-macs.el @@ -280,14 +280,18 @@ buffer object. ;;;###autoload (cl-defmacro define-ibuffer-filter (name documentation - (&key - reader - description) - &rest body) + (&key + reader + 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,26 +300,41 @@ bound to the current value of the filter. \(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)) - (ibuffer-push-filter (cons ',name qualifier)) - (message "%s" - (format ,(concat (format "Filter by %s added: " description) - " %s") - qualifier)) - (ibuffer-update nil t)) + ,(or documentation "This filter is not documented.") + (interactive (list ,reader)) + (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)))))) - ibuffer-filtering-alist) + (lambda (buf 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))) (provide 'ibuf-macs) |