aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTino Calancha2018-09-29 18:40:46 +0900
committerTino Calancha2018-09-29 18:40:46 +0900
commit2296bf188fc99d66306e71e6decd3d2e176b7ae6 (patch)
treebfc6c4d8afad29ee0204ce56801583ea7d97e403
parent3bbe9e609138ae88a4c98bcee0da8fcf8b4a3e80 (diff)
downloademacs-2296bf188fc99d66306e71e6decd3d2e176b7ae6.tar.gz
emacs-2296bf188fc99d66306e71e6decd3d2e176b7ae6.zip
Ibuffer filter by modes: Accept several mode names
Extend all mode filters so that they handle >1 mode. For instance, if the users want to filter all buffers in C or C++ mode, then they 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@gmail.com>
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/ibuf-ext.el45
-rw-r--r--lisp/ibuf-macs.el65
3 files changed, 73 insertions, 42 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 474af167e83..7e7de165ec1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -62,6 +62,11 @@ to reduce differences between developer and production builds.
62** Ibuffer 62** Ibuffer
63 63
64--- 64---
65*** All mode filters can now accept a list of symbols.
66This means you can now easily filter several major modes, as well
67as a single mode.
68
69---
65*** New toggle 'ibuffer-do-toggle-lock', bound to 'L'. 70*** New toggle 'ibuffer-do-toggle-lock', bound to 'L'.
66 71
67** Gnus 72** Gnus
diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el
index d9949d28352..32ec91db970 100644
--- a/lisp/ibuf-ext.el
+++ b/lisp/ibuf-ext.el
@@ -1228,28 +1228,33 @@ If INCLUDE-PARENTS is non-nil then include parent modes."
1228 1228
1229;;;###autoload (autoload 'ibuffer-filter-by-mode "ibuf-ext") 1229;;;###autoload (autoload 'ibuffer-filter-by-mode "ibuf-ext")
1230(define-ibuffer-filter mode 1230(define-ibuffer-filter mode
1231 "Limit current view to buffers with major mode QUALIFIER." 1231 "Limit current view to buffers with major mode(s) specified by QUALIFIER.
1232QUALIFIER is the mode name as a symbol or a list of symbols.
1233Called interactively, accept a comma separated list of mode names."
1232 (:description "major mode" 1234 (:description "major mode"
1233 :reader 1235 :reader
1234 (let* ((buf (ibuffer-current-buffer)) 1236 (let* ((buf (ibuffer-current-buffer))
1235 (default (if (and buf (buffer-live-p buf)) 1237 (default (if (and buf (buffer-live-p buf))
1236 (symbol-name (buffer-local-value 1238 (symbol-name (buffer-local-value
1237 'major-mode buf))))) 1239 'major-mode buf)))))
1238 (intern 1240 (mapcar #'intern
1239 (completing-read 1241 (completing-read-multiple
1240 (if default 1242 (if default
1241 (format "Filter by major mode (default %s): " default) 1243 (format "Filter by major mode (default %s): " default)
1242 "Filter by major mode: ") 1244 "Filter by major mode: ")
1243 obarray 1245 obarray
1244 #'(lambda (e) 1246 (lambda (e)
1245 (string-match "-mode\\'" (symbol-name e))) 1247 (string-match "-mode\\'" (if (symbolp e) (symbol-name e) e)))
1246 t nil nil default)))) 1248 t nil nil default)))
1249 :accept-list t)
1247 (eq qualifier (buffer-local-value 'major-mode buf))) 1250 (eq qualifier (buffer-local-value 'major-mode buf)))
1248 1251
1249;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext") 1252;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext")
1250(define-ibuffer-filter used-mode 1253(define-ibuffer-filter used-mode
1251 "Limit current view to buffers with major mode QUALIFIER. 1254 "Limit current view to buffers with major mode(s) specified by QUALIFIER.
1252Called interactively, this function allows selection of modes 1255QUALIFIER is the mode name as a symbol or a list of symbols.
1256
1257Called interactively, accept a comma separated list of mode names
1253currently used by buffers." 1258currently used by buffers."
1254 (:description "major mode in use" 1259 (:description "major mode in use"
1255 :reader 1260 :reader
@@ -1257,23 +1262,29 @@ currently used by buffers."
1257 (default (if (and buf (buffer-live-p buf)) 1262 (default (if (and buf (buffer-live-p buf))
1258 (symbol-name (buffer-local-value 1263 (symbol-name (buffer-local-value
1259 'major-mode buf))))) 1264 'major-mode buf)))))
1260 (intern 1265 (mapcar #'intern
1261 (completing-read 1266 (completing-read-multiple
1262 (if default 1267 (if default
1263 (format "Filter by major mode (default %s): " default) 1268 (format "Filter by major mode (default %s): " default)
1264 "Filter by major mode: ") 1269 "Filter by major mode: ")
1265 (ibuffer-list-buffer-modes) nil t nil nil default)))) 1270 (ibuffer-list-buffer-modes) nil t nil nil default)))
1271 :accept-list t)
1266 (eq qualifier (buffer-local-value 'major-mode buf))) 1272 (eq qualifier (buffer-local-value 'major-mode buf)))
1267 1273
1268;;;###autoload (autoload 'ibuffer-filter-by-derived-mode "ibuf-ext") 1274;;;###autoload (autoload 'ibuffer-filter-by-derived-mode "ibuf-ext")
1269(define-ibuffer-filter derived-mode 1275(define-ibuffer-filter derived-mode
1270 "Limit current view to buffers whose major mode inherits from QUALIFIER." 1276 "Limit current view to buffers with major mode(s) specified by QUALIFIER.
1277QUALIFIER is the mode name as a symbol or a list of symbols.
1278 Restrict the view to buffers whose major mode derivates
1279 from modes specified by QUALIFIER.
1280Called interactively, accept a comma separated list of mode names."
1271 (:description "derived mode" 1281 (:description "derived mode"
1272 :reader 1282 :reader
1273 (intern 1283 (mapcar #'intern
1274 (completing-read "Filter by derived mode: " 1284 (completing-read-multiple "Filter by derived mode: "
1275 (ibuffer-list-buffer-modes t) 1285 (ibuffer-list-buffer-modes t)
1276 nil t))) 1286 nil t))
1287 :accept-list t)
1277 (with-current-buffer buf (derived-mode-p qualifier))) 1288 (with-current-buffer buf (derived-mode-p qualifier)))
1278 1289
1279;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext") 1290;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext")
diff --git a/lisp/ibuf-macs.el b/lisp/ibuf-macs.el
index 6a70a8341a2..72a35a53315 100644
--- a/lisp/ibuf-macs.el
+++ b/lisp/ibuf-macs.el
@@ -280,14 +280,18 @@ buffer object.
280 280
281;;;###autoload 281;;;###autoload
282(cl-defmacro define-ibuffer-filter (name documentation 282(cl-defmacro define-ibuffer-filter (name documentation
283 (&key 283 (&key
284 reader 284 reader
285 description) 285 description
286 &rest body) 286 accept-list)
287 &rest body)
287 "Define a filter named NAME. 288 "Define a filter named NAME.
288DOCUMENTATION is the documentation of the function. 289DOCUMENTATION is the documentation of the function.
289READER is a form which should read a qualifier from the user. 290READER is a form which should read a qualifier from the user.
290DESCRIPTION is a short string describing the filter. 291DESCRIPTION is a short string describing the filter.
292ACCEPT-LIST is a boolean; if non-nil, the filter accepts either
293a single condition or a list of them; in the latter
294case the filter is the `or' composition of the conditions.
291 295
292BODY should contain forms which will be evaluated to test whether or 296BODY should contain forms which will be evaluated to test whether or
293not a particular buffer should be displayed or not. The forms in BODY 297not a particular buffer should be displayed or not. The forms in BODY
@@ -296,30 +300,41 @@ bound to the current value of the filter.
296 300
297\(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)" 301\(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)"
298 (declare (indent 2) (doc-string 2)) 302 (declare (indent 2) (doc-string 2))
299 (let ((fn-name (intern (concat "ibuffer-filter-by-" (symbol-name name))))) 303 (let ((fn-name (intern (concat "ibuffer-filter-by-" (symbol-name name))))
304 (filter (make-symbol "ibuffer-filter"))
305 (qualifier-str (make-symbol "ibuffer-qualifier-str")))
300 `(progn 306 `(progn
301 (defun ,fn-name (qualifier) 307 (defun ,fn-name (qualifier)
302 ,(or documentation "This filter is not documented.") 308 ,(or documentation "This filter is not documented.")
303 (interactive (list ,reader)) 309 (interactive (list ,reader))
304 (if (null (ibuffer-push-filter (cons ',name qualifier))) 310 (let ((,filter (cons ',name qualifier))
305 (message "%s" 311 (,qualifier-str qualifier))
306 (format ,(concat (format "Filter by %s already applied: " description) 312 ,(when accept-list
307 " %s") 313 `(progn
308 qualifier)) 314 (unless (listp qualifier) (setq qualifier (list qualifier)))
309 (message "%s" 315 ;; Reject equivalent filters: (or f1 f2) is same as (or f2 f1).
310 (format ,(concat (format "Filter by %s added: " description) 316 (setq qualifier (sort (delete-dups qualifier) #'string-lessp))
311 " %s") 317 (setq ,filter (cons ',name (car qualifier)))
312 qualifier)) 318 (setq ,qualifier-str
313 (ibuffer-update nil t))) 319 (mapconcat (lambda (m) (if (symbolp m) (symbol-name m) m))
320 qualifier ","))
321 (when (cdr qualifier) ; Compose individual filters with `or'.
322 (setq ,filter `(or ,@(mapcar (lambda (m) (cons ',name m)) qualifier))))))
323 (if (null (ibuffer-push-filter ,filter))
324 (message ,(format "Filter by %s already applied: %%s" description)
325 ,qualifier-str)
326 (message ,(format "Filter by %s added: %%s" description)
327 ,qualifier-str)
328 (ibuffer-update nil t))))
314 (push (list ',name ,description 329 (push (list ',name ,description
315 (lambda (buf qualifier) 330 (lambda (buf qualifier)
316 (condition-case nil 331 (condition-case nil
317 (progn ,@body) 332 (progn ,@body)
318 (error (ibuffer-pop-filter) 333 (error (ibuffer-pop-filter)
319 (when (eq ',name 'predicate) 334 (when (eq ',name 'predicate)
320 (error "Wrong filter predicate: %S" 335 (error "Wrong filter predicate: %S"
321 qualifier)))))) 336 qualifier))))))
322 ibuffer-filtering-alist) 337 ibuffer-filtering-alist)
323 :autoload-end))) 338 :autoload-end)))
324 339
325(provide 'ibuf-macs) 340(provide 'ibuf-macs)