4 Коммиты 28a9b0a36c ... f3a137628e

Автор SHA1 Сообщение Дата
  Alex Kost f3a137628e examples/buffers: Use default filters 4 лет назад
  Joe Bloggs ab62fcefc3 core: Add interactive filters 4 лет назад
  Alex Kost ed3f2c8b26 core: Add 'bui-current-params' 4 лет назад
  Jonas Bernoulli 9a2321b322 Fix typo 4 лет назад
3 измененных файлов с 94 добавлено и 9 удалено
  1. 39 2
      bui-core.el
  2. 48 1
      bui-utils.el
  3. 7 6
      examples/buffers.el

+ 39 - 2
bui-core.el

@@ -1,6 +1,7 @@
 ;;; bui-core.el --- Core functionality for BUI  -*- lexical-binding: t -*-
 
-;; Copyright © 2014–2017 Alex Kost <alezost@gmail.com>
+;; Copyright © 2014–2017, 2021 Alex Kost <alezost@gmail.com>
+;; Copyright © 2020 Joe Bloggs <vapniks@yahoo.com>
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -181,7 +182,8 @@ See `bui-define-current-args-accessor' for details."
   "Hint with the default keys for filtering.
 See `bui-hint' for details.")
 
-(defcustom bui-filter-predicates nil
+(defcustom bui-filter-predicates
+  '(bui-filter-by-regexp bui-filter-by-sexp)
   "List of available filter predicates.
 These predicates are used as completions for
 '\\[bui-enable-filter]' command to hide entries. See
@@ -214,6 +216,33 @@ If PREDICATES are not specified, display all entries."
                     (bui-current-entry-type)
                     (bui-current-buffer-type)))
 
+(defun bui-filter-by-regexp (entry param regexp)
+  "Filter the current entries by regexp.
+Return non-nil, if ENTRY's parameter PARAM matches REGEXP.
+Interactively, prompt for PARAM and REGEXP."
+  (interactive
+   (list '<>
+         (intern
+          (completing-read "Parameter: "
+		           (mapcar #'symbol-name (bui-current-params))))
+	 (read-regexp "Regexp: ")))
+  (string-match-p regexp
+                  (bui-get-string (bui-assq-value entry param))))
+
+(defun bui-filter-by-sexp (entry sexp)
+  "Filter the current entries using sexp.
+Evaluate SEXP and return its value.
+SEXP can use the ENTRY's parameters as symbols, e.g.:
+
+  '(or (string-match-p \"foo\" name)
+       (string-match-p \"bar\" synopsis))
+"
+  (interactive (list '<> (read--expression "sexp: ")))
+  (dolist (param (bui-current-params))
+    (setq sexp (cl-subst (bui-assq-value entry param)
+                         param sexp)))
+  (eval sexp))
+
 (defun bui-enable-filter (predicate &optional single?)
   "Apply filter PREDICATE to the current entries.
 Interactively, prompt for PREDICATE, choosing candidates from the
@@ -235,6 +264,7 @@ only active one (remove the other active predicates)."
              current-prefix-arg))))
   (or (functionp predicate)
       (error "Wrong filter predicate: %S" predicate))
+  (setq predicate (bui-apply-interactive predicate))
   (if (if single?
           (equal (list predicate) bui-active-filter-predicates)
         (memq predicate bui-active-filter-predicates))
@@ -586,6 +616,13 @@ Use '\\[bui-disable-filters]' to remove filters")))))
   "Return non-nil if PARAM for ENTRY-TYPE/BUFFER-TYPE is boolean."
   (memq param (bui-symbol-value entry-type buffer-type 'boolean-params)))
 
+(defun bui-current-params ()
+  "Return parameter names of the current buffer."
+  (mapcar #'car
+          (bui-symbol-value (bui-current-entry-type)
+                            (bui-current-buffer-type)
+                            'format)))
+
 
 ;;; Displaying entries
 

+ 48 - 1
bui-utils.el

@@ -1,6 +1,7 @@
 ;;; bui-utils.el --- General utility functions  -*- lexical-binding: t -*-
 
-;; Copyright © 2014–2017 Alex Kost <alezost@gmail.com>
+;; Copyright © 2014–2017, 2021 Alex Kost <alezost@gmail.com>
+;; Copyright © 2020 Joe Bloggs <vapniks@yahoo.com>
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -431,6 +432,52 @@ return `defcustom' clause instead."
            :group ',group)
       `(defvar ,symbol ,val ,doc))))
 
+(defun bui-apply-interactive (function)
+  "Call the interactive form of FUNCTION to (partially) apply arguments.
+Return FUNCTION, if it has no `interactive' form.  Otherwise,
+return a new function that does the same as FUNCTION, except its
+arguments are fixed to the values obtained interactively during
+this FUNCTION call.
+
+Any `<>' symbols returned by the `interactive' form of FUNCTION will be
+used as the place holders for arguments of the returned function.
+Also, if the `interactive' form returns a '&rest symbol, this will
+be used in the arglist of the returned function.
+
+For example, the following call:
+
+ (bui-apply-interactive
+  (lambda (x y &rest z)
+    (interactive (list (read-number \"Factor: \")
+		       '<> '&rest '<>))
+    (* x (apply '+ y z))))
+
+will prompt for a number, x, and return a function that takes any
+number of arguments, adds them together and multiplies the result
+by x."
+  (let ((interact (interactive-form function)))
+    (if interact
+	(let* ((args  (eval `(call-interactively
+			      (lambda (&rest args) ,interact args))))
+	       (args2 (mapcar (lambda (x) (if (eq x '<>) (gensym) x))
+			      (cl-remove-if-not
+                               (lambda (y) (memq y '(<> &rest)))
+			       args)))
+	       (args3 (remove '&rest args))
+	       (args4 (remove '&rest args2))
+	       (restp (memq '&rest args2)))
+	  ;; Use `eval' rather than `macroexpand' so that the function
+	  ;; can be called with `funcall'.
+	  (eval `(lambda ,args2
+		   (,@(if restp `(apply ,function) `(,function))
+		    ,@(mapcar
+		       (lambda (x) (if (eq x '<>) (pop args4)
+				     (if (or (symbolp x) (listp x))
+					 (list 'quote x)
+				       x)))
+		       args3)))))
+      function)))
+
 (provide 'bui-utils)
 
 ;;; bui-utils.el ends here

+ 7 - 6
examples/buffers.el

@@ -1,6 +1,6 @@
 ;;; buffers.el --- List of buffers and buffer info
 
-;; Copyright © 2016–2017 Alex Kost <alezost@gmail.com>
+;; Copyright © 2016–2017, 2021 Alex Kost <alezost@gmail.com>
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 ;; To try it, load this file (for example, with "M-x load-file"), and
 ;; run "M-x buffers" command.  There you can mark several buffers (with
 ;; "m") and press "i" to display the info buffer; press "f f" to enable
-;; fiters, etc.  Press "h" to look at the "hint" (available keys).
+;; filters, etc.  Press "h" to look at the "hint" (available keys).
 
 ;;; Code:
 
@@ -75,10 +75,11 @@
   :titles '((mod-time . "Modification Time"))
   :get-entries-function #'buffers-get-entries
   :filter-predicates
-  '(buffers-buffer-ephemeral?
-    buffers-buffer-non-ephemeral?
-    buffers-buffer-visiting-file?
-    buffers-buffer-not-visiting-file?))
+  (append bui-filter-predicates
+          '(buffers-buffer-ephemeral?
+            buffers-buffer-non-ephemeral?
+            buffers-buffer-visiting-file?
+            buffers-buffer-not-visiting-file?)))
 
 (defun buffers-describe-mode-function (button)
   (describe-function (intern (button-label button))))