emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/taxy 8797141 02/39: Dynamic, consuming, and non-consumi


From: ELPA Syncer
Subject: [elpa] externals/taxy 8797141 02/39: Dynamic, consuming, and non-consuming
Date: Fri, 27 Aug 2021 10:57:29 -0400 (EDT)

branch: externals/taxy
commit 8797141334f03dd02dc5d9fe1f7f679491da3d8d
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>

    Dynamic, consuming, and non-consuming
    
    Squashed commit of the following:
    
    commit 3f2d7ee535a74518ebc04fa7da751d72698c6c13
    Author: Adam Porter <adam@alphapapa.net>
    Date:   Wed Aug 25 06:17:31 2021 -0500
    
        WIP: Dynamic, consuming, and non-consuming
    
    commit 41209b371ee98e12a0939264f293cd1a8652c401
    Author: Adam Porter <adam@alphapapa.net>
    Date:   Wed Aug 25 05:18:25 2021 -0500
    
        WIP: Dynamic taxys
---
 README.org | 145 ++++++++++++++++++++++++++++++++++++++++++++-----------------
 taxy.el    |  30 ++++++++-----
 2 files changed, 125 insertions(+), 50 deletions(-)

diff --git a/README.org b/README.org
index 279e27e..ea7d72f 100644
--- a/README.org
+++ b/README.org
@@ -15,22 +15,24 @@ This is a silly taxonomy of numbers below 100:
 #+BEGIN_SRC elisp
   ("Numbery" "A silly taxonomy of numbers."
    (("< 10" "Numbers below 10"
-     (("Odd"
+     (0 2 4 6 8)
+     (("Odd (consuming)"
        (1 3 5 7 9))
-      ("Even"
+      ("Even (non-consuming)"
        (0 2 4 6 8))))
-    ("> 10" "Numbers above 9"
-     (("Divisible by 3"
+    (">= 10" "Numbers above 9"
+     (10 11 13 14 17 19 22 23 25 26 29 31 34 35 37 38 41 43 46 47 49 50 53 55 
58
+         59 61 62 65 67 70 71 73 74 77 79 82 83 85 86 89 91 94 95 97 98)
+     (("Divisible by 3 (non-consuming)"
        (12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 
81 84
            87 90 93 96 99))
-      ("Divisible by 4"
+      ("Divisible by 4 (non-consuming)"
        (12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96))
-      ("Divisible by 3 or 4"
+      ("Divisible by 3 or 4 (consuming)"
        (12 15 16 18 20 21 24 27 28 30 32 33 36 39 40 42 44 45 48 51 52 54 56 
57 60
            63 64 66 68 69 72 75 76 78 80 81 84 87 88 90 92 93 96 99))
-      ("Not divisible by 3 or 4"
-       (10 11 13 14 17 19 22 23 25 26 29 31 34 35 37 38 41 43 46 47 49 50 53 
55 58
-           59 61 62 65 67 70 71 73 74 77 79 82 83 85 86 89 91 94 95 97 98))))))
+      ("Divisible by 5 (non-consuming)"
+       (10 25 35 50 55 65 70 85 95))))))
 #+END_SRC
 
 You might think about how to produce that by writing some imperative code, but 
=taxy= allows you to do so in a more declarative and functional manner:
@@ -39,37 +41,39 @@ You might think about how to produce that by writing some 
imperative code, but =
   (require 'taxy)
 
   (let ((numbery
-         (make-taxy :name "Numbery"
-                    :description "A silly taxonomy of numbers."
-                    :predicate #'numberp
-                    :then #'ignore
-                    :taxys (list (make-taxy :name "< 10"
-                                            :description "Numbers below 10"
-                                            :predicate (lambda (n) (< n 10))
-                                            :then #'ignore
-                                            :taxys (list (make-taxy :name "Odd"
-                                                                    :predicate 
#'oddp
-                                                                    :then 
#'ignore)
-                                                         (make-taxy :name 
"Even"
-                                                                    :predicate 
#'evenp
-                                                                    :then 
#'ignore)))
-                                 (make-taxy :name "> 10"
-                                            :description "Numbers above 9"
-                                            :predicate (lambda (n) (>= n 10))
-                                            :then #'ignore
-                                            :taxys (list (make-taxy :name 
"Divisible by 3"
-                                                                    :predicate 
(lambda (n) (zerop (mod n 3)))
-                                                                    :then 
#'identity)
-                                                         (make-taxy :name 
"Divisible by 4"
-                                                                    :predicate 
(lambda (n) (zerop (mod n 4)))
-                                                                    :then 
#'identity)
-                                                         (make-taxy :name 
"Divisible by 3 or 4"
-                                                                    :predicate 
(lambda (n) (or (zerop (mod n 3))
-                                                                               
                (zerop (mod n 4))))
-                                                                    :then 
#'ignore)
-                                                         (make-taxy :name "Not 
divisible by 3 or 4"
-                                                                    :predicate 
#'identity
-                                                                    :then 
#'ignore))))))
+         (make-taxy
+          :name "Numbery"
+          :description "A silly taxonomy of numbers."
+          :predicate #'numberp
+          :then #'ignore
+          :taxys (list (make-taxy
+                        :name "< 10"
+                        :description "Numbers below 10"
+                        :predicate (lambda (n) (< n 10))
+                        :then #'ignore
+                        :taxys (list (make-taxy :name "Odd (consuming)"
+                                                :predicate #'oddp
+                                                :then #'ignore)
+                                     (make-taxy :name "Even (non-consuming)"
+                                                :predicate #'evenp
+                                                :then #'identity)))
+                       (make-taxy
+                        :name ">= 10"
+                        :description "Numbers above 9"
+                        :predicate (lambda (n) (>= n 10))
+                        :then #'ignore
+                        :taxys (list (make-taxy :name "Divisible by 3 
(non-consuming)"
+                                                :predicate (lambda (n) (zerop 
(mod n 3)))
+                                                :then #'identity)
+                                     (make-taxy :name "Divisible by 4 
(non-consuming)"
+                                                :predicate (lambda (n) (zerop 
(mod n 4)))
+                                                :then #'identity)
+                                     (make-taxy :name "Divisible by 3 or 4 
(consuming)"
+                                                :predicate (lambda (n) (or 
(zerop (mod n 3))
+                                                                           
(zerop (mod n 4)))))
+                                     (make-taxy :name "Divisible by 5 
(non-consuming)"
+                                                :predicate (lambda (n) (zerop 
(mod n 5)))
+                                                :then #'identity))))))
         (numbers (cl-loop for i below 100 collect i)))
     (taxy-simple (taxy-apply numbery (reverse numbers))))
 #+END_SRC
@@ -134,6 +138,67 @@ After defining a taxy, call ~taxy-apply~ with it and a 
list of objects to fill t
 
 To return a taxy in a more human-readable format (with only relevant fields 
included), use ~taxy-simple~.
 
+** Dynamic taxys
+
+You may not always know in advance what taxonomy a set of objects fits into, 
so =taxy= lets you add taxys dynamically by using the ~:take~ function to add a 
taxy when an object is "taken into" a parent taxy.  For example, you could 
dynamically classify buffers by their major mode like so:
+
+#+BEGIN_SRC elisp :exports code
+  (let* ((key-fn (lambda (buffer)
+                   (buffer-local-value 'major-mode buffer)))
+         (buffery
+          (make-taxy
+           :name "Buffers"
+           :taxys (list
+                   (make-taxy
+                    :name "Modes"
+                    :take (lambda (buffer taxy)
+                            (let* ((key (funcall key-fn buffer))
+                                   (key-taxy
+                                    (or (cl-find-if (lambda (taxy-key)
+                                                      (equal key taxy-key))
+                                                    (taxy-taxys taxy)
+                                                    :key #'taxy-key)
+                                        (car
+                                         (push (make-taxy
+                                                :name key :key key
+                                                :predicate (lambda (buffer)
+                                                             (equal key 
(funcall key-fn buffer))))
+                                               (taxy-taxys taxy))))))
+                              (push buffer (taxy-objects key-taxy)))))))))
+    (taxy-simple (taxy-apply buffery (buffer-list))))
+#+END_SRC
+
+Which produces this taxonomy of buffers:
+
+#+BEGIN_SRC elisp
+  ("Buffers"
+   (("Modes"
+     ((magit-process-mode
+       (#<buffer magit-process: taxy.el> #<buffer magit-process: > #<buffer 
magit-process: notes>))
+      (messages-buffer-mode
+       (#<buffer *Messages*>))
+      (special-mode
+       (#<buffer *Warnings*> #<buffer *elfeed-log*>))
+      (dired-mode
+       (#<buffer ement.el<emacs>>))
+      (Custom-mode
+       (#<buffer *Customize Apropos*>))
+      (fundamental-mode
+       (#<buffer  *helm candidates:Bookmarks*> #<buffer *Backtrace*>))
+      (magit-diff-mode
+       (#<buffer magit-diff: taxy.el> #<buffer magit-diff: notes> #<buffer 
magit-diff: ement.el>))
+      (compilation-mode
+       (#<buffer *compilation*> #<buffer *Compile-Log*>))
+      (Info-mode
+       (#<buffer  *helm info temp buffer*> #<buffer *info*>))
+      (help-mode
+       (#<buffer *Help*>))
+      (emacs-lisp-mode
+       (#<buffer ement.el<ement.el>> #<buffer ement-room-list.el> #<buffer 
*scratch*>
+                 #<buffer ement-room.el> #<buffer init.el> #<buffer bufler.el>
+                 #<buffer dash.el> #<buffer *Pp Eval Output*> #<buffer 
taxy.el> #<buffer scratch.el>))))))
+#+END_SRC
+
 # ** Tips
 # 
 # + You can customize settings in the =taxy= group.
diff --git a/taxy.el b/taxy.el
index ddbe311..0070f27 100644
--- a/taxy.el
+++ b/taxy.el
@@ -31,8 +31,9 @@
 ;;;; Structs
 
 (cl-defstruct taxy
-  name description objects
-  predicate then taxys)
+  name description key objects taxys dynamic
+  (predicate #'identity) (then #'ignore)
+  take)
 
 ;;;; Variables
 
@@ -47,14 +48,23 @@
 
 (defun taxy-apply (taxy objects)
   (cl-labels ((apply-object (taxy object)
-                            (cl-loop for taxy in (taxy-taxys taxy)
-                                     while object
+                            (cl-loop with taken
+                                     for taxy in (taxy-taxys taxy)
                                      when (funcall (taxy-predicate taxy) 
object)
-                                     do (setf object
-                                              (if-let* ((taxys (taxy-taxys 
taxy)))
-                                                  (apply-object taxy object)
-                                                (push object (taxy-objects 
taxy))
-                                                (funcall (taxy-then taxy) 
object))))))
+                                     do (setf taken t
+                                              object (if (taxy-take taxy)
+                                                         (progn
+                                                           (funcall (taxy-take 
taxy) object taxy)
+                                                           (funcall (taxy-then 
taxy) object))
+                                                       (if (taxy-taxys taxy)
+                                                           (progn
+                                                             (or (apply-object 
taxy object)
+                                                                 (push object 
(taxy-objects taxy)))
+                                                             (funcall 
(taxy-then taxy) object))
+                                                         (push object 
(taxy-objects taxy))
+                                                         (funcall (taxy-then 
taxy) object))))
+                                     unless object return t
+                                     finally return nil)))
     (dolist (object objects taxy)
       (apply-object taxy object))))
 
@@ -63,7 +73,7 @@
         (list (taxy-name taxy)
               (taxy-description taxy)
               (taxy-objects taxy)
-              (mapcar #'taxy-print (taxy-taxys taxy)))))
+              (mapcar #'taxy-simple (taxy-taxys taxy)))))
 
 ;;;; Footer
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]