[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/taxy fcc780f 27/39: Add: (taxy-take-keyed*)
From: |
ELPA Syncer |
Subject: |
[elpa] externals/taxy fcc780f 27/39: Add: (taxy-take-keyed*) |
Date: |
Fri, 27 Aug 2021 10:57:34 -0400 (EDT) |
branch: externals/taxy
commit fcc780f44a0a354519f190d96d71b57874ad2e00
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>
Add: (taxy-take-keyed*)
---
README.org | 54 ++++++++++++++++++++++++++++++++++++---
taxy.el | 29 +++++++++++++++++++++
taxy.info | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 154 insertions(+), 15 deletions(-)
diff --git a/README.org b/README.org
index e062744..722e0a6 100644
--- a/README.org
+++ b/README.org
@@ -250,6 +250,12 @@ After defining a taxy, call ~taxy-fill~ with it and a list
of objects to fill th
To return a taxy in a more human-readable format (with only relevant fields
included), use ~taxy-plain~. You may also use ~taxy-map~ to replace objects in
a taxy with, e.g. a more useful representation.
** Dynamic taxys
+:PROPERTIES:
+:TOC: :include descendants
+:END:
+:CONTENTS:
+- [[#multi-level-dynamic-taxys][Multi-level dynamic taxys]]
+:END:
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:
@@ -302,9 +308,51 @@ The taxy's ~:take~ function is set to the
~taxy-take-keyed~ function, partially
#<buffer dash.el> #<buffer *Pp Eval Output*> #<buffer
taxy.el> #<buffer scratch.el>))))))
#+END_SRC
-# ** Tips
-#
-# + You can customize settings in the =taxy= group.
+*** Multi-level dynamic taxys
+
+Of course, the point of taxonomies is that they aren't restricted to a single
level of depth, so you may also use the function ~taxy-take-keyed*~ (notice the
~*~) to dynamically make multi-level taxys. Expanding on the previous example,
we use ~cl-labels~ to define functions which are used in the taxy's definition,
which are used in the ~:take~ function, which calls ~taxy-take-keyed*~ (rather
than using ~apply-partially~ like in the previous example, we use a lambda
function, which perf [...]
+
+# MAYBE: A macro to define :take functions more concisely.
+
+#+BEGIN_SRC elisp :exports code
+ (defvar buffery
+ (cl-labels ((buffer-mode (buffer) (buffer-local-value 'major-mode buffer))
+ (buffer-directory (buffer) (buffer-local-value
'default-directory buffer)))
+ (make-taxy
+ :name "Buffers"
+ :taxys (list
+ (make-taxy
+ :name "Directories"
+ :take (lambda (object taxy)
+ (taxy-take-keyed* (list #'buffer-directory
#'buffer-mode) object taxy)))))))
+
+ (taxy-plain
+ (taxy-fill (buffer-list)
+ (taxy-emptied buffery)))
+#+END_SRC
+
+That produces a list like:
+
+#+BEGIN_SRC elisp
+ ("Buffers"
+ (("Directories"
+ (("~/src/emacs/ement.el/"
+ ((dired-mode
+ (#<buffer ement.el<emacs>))
+ (emacs-lisp-mode
+ (#<buffer ement.el<ement.el> #<buffer ement-room-list.el> #<buffer
ement-room.el>))
+ (magit-diff-mode
+ (#<buffer magit-diff: ement.el>))))
+ ("~/src/emacs/taxy.el/"
+ ((dired-mode
+ (#<buffer taxy.el<emacs>))
+ (Info-mode
+ (#<buffer *info*>))
+ (magit-status-mode
+ (#<buffer magit: taxy.el>))
+ (emacs-lisp-mode
+ (#<buffer taxy-magit-section.el> #<buffer taxy.el<taxy.el> #<buffer
scratch.el>))))))))
+#+END_SRC
** Reusable taxys
diff --git a/taxy.el b/taxy.el
index 03e09b9..47bfb8c 100644
--- a/taxy.el
+++ b/taxy.el
@@ -133,6 +133,35 @@ by KEY-NAME-FN called with OBJECT."
(taxy-taxys taxy))))))
(push object (taxy-objects key-taxy))))
+(cl-defun taxy-take-keyed* (key-fns object taxy &key (key-name-fn #'identity))
+ "Take OBJECT into TAXY, adding new taxys dynamically and recursively.
+Places OBJECT into a taxy in TAXY for the value returned by
+KEY-FNS called with OBJECT. The new taxys are added to TAXY
+recursively as necessary. Each new taxy's name is that returned
+by KEY-NAME-FN called with OBJECT."
+ (let ((key-fn (car key-fns)))
+ (if-let ((key (funcall key-fn object)))
+ (let ((key-taxy (or (cl-find-if (lambda (taxy-key)
+ (equal key taxy-key))
+ (taxy-taxys taxy)
+ :key #'taxy-key)
+ (car
+ (push (make-taxy
+ :name (funcall key-name-fn key) :key key
+ :predicate (lambda (object)
+ (equal key (funcall key-fn
object)))
+ :take (when (cdr key-fns)
+ (lambda (object taxy)
+ (taxy-take-keyed* (cdr key-fns)
object taxy))))
+ (taxy-taxys taxy))))))
+ (if (cdr key-fns)
+ (taxy-take-keyed* (cdr key-fns) object key-taxy)
+ (push object (taxy-objects key-taxy))))
+ ;; No key value: push to this taxy.
+ (if (cdr key-fns)
+ (taxy-take-keyed* (cdr key-fns) object taxy)
+ (push object (taxy-objects taxy))))))
+
;;;; Footer
(provide 'taxy)
diff --git a/taxy.info b/taxy.info
index f0d0a8b..ac6b346 100644
--- a/taxy.info
+++ b/taxy.info
@@ -29,7 +29,9 @@ Usage
* Threading macros::
* Magit section::
+Dynamic taxys
+* Multi-level dynamic taxys::
Changelog
@@ -263,8 +265,9 @@ File: README.info, Node: Dynamic taxys, Next: Reusable
taxys, Up: Usage
2.1 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’
+ •
+ 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:
@@ -317,6 +320,64 @@ produces this taxonomy of buffers:
#<buffer ement-room.el> #<buffer init.el> #<buffer
bufler.el>
#<buffer dash.el> #<buffer *Pp Eval Output*> #<buffer
taxy.el> #<buffer scratch.el>))))))
+* Menu:
+
+* Multi-level dynamic taxys::
+
+
+File: README.info, Node: Multi-level dynamic taxys, Up: Dynamic taxys
+
+2.1.1 Multi-level dynamic taxys
+-------------------------------
+
+Of course, the point of taxonomies is that they aren’t restricted to a
+single level of depth, so you may also use the function
+‘taxy-take-keyed*’ (notice the ‘*’) to dynamically make multi-level
+taxys. Expanding on the previous example, we use ‘cl-labels’ to define
+functions which are used in the taxy’s definition, which are used in the
+‘:take’ function, which calls ‘taxy-take-keyed*’ (rather than using
+‘apply-partially’ like in the previous example, we use a lambda
+function, which performs better than partially applied functions). Then
+when the taxy is filled, a multi-level hierarchy is created dynamically,
+organizing buffers first by their directory, and then by mode in each
+directory.
+
+ (defvar buffery
+ (cl-labels ((buffer-mode (buffer) (buffer-local-value 'major-mode
buffer))
+ (buffer-directory (buffer) (buffer-local-value
'default-directory buffer)))
+ (make-taxy
+ :name "Buffers"
+ :taxys (list
+ (make-taxy
+ :name "Directories"
+ :take (lambda (object taxy)
+ (taxy-take-keyed* (list #'buffer-directory
#'buffer-mode) object taxy)))))))
+
+ (taxy-plain
+ (taxy-fill (buffer-list)
+ (taxy-emptied buffery)))
+
+ That produces a list like:
+
+ ("Buffers"
+ (("Directories"
+ (("~/src/emacs/ement.el/"
+ ((dired-mode
+ (#<buffer ement.el<emacs>))
+ (emacs-lisp-mode
+ (#<buffer ement.el<ement.el> #<buffer ement-room-list.el> #<buffer
ement-room.el>))
+ (magit-diff-mode
+ (#<buffer magit-diff: ement.el>))))
+ ("~/src/emacs/taxy.el/"
+ ((dired-mode
+ (#<buffer taxy.el<emacs>))
+ (Info-mode
+ (#<buffer *info*>))
+ (magit-status-mode
+ (#<buffer magit: taxy.el>))
+ (emacs-lisp-mode
+ (#<buffer taxy-magit-section.el> #<buffer taxy.el<taxy.el>
#<buffer scratch.el>))))))))
+
File: README.info, Node: Reusable taxys, Next: Threading macros, Prev:
Dynamic taxys, Up: Usage
@@ -489,16 +550,17 @@ GPLv3
Tag Table:
Node: Top218
-Node: Examples1057
-Node: Usage8957
-Node: Dynamic taxys11040
-Node: Reusable taxys13407
-Node: Threading macros17564
-Node: Magit section18085
-Node: Changelog18680
-Node: 01-pre18818
-Node: Development18912
-Node: License19083
+Node: Examples1101
+Node: Usage9001
+Node: Dynamic taxys11084
+Node: Multi-level dynamic taxys13502
+Node: Reusable taxys15662
+Node: Threading macros19819
+Node: Magit section20340
+Node: Changelog20935
+Node: 01-pre21073
+Node: Development21167
+Node: License21338
End Tag Table
- [elpa] externals/taxy d355d3a 14/39: Docs: Add mascot, (continued)
- [elpa] externals/taxy d355d3a 14/39: Docs: Add mascot, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 3b253a6 21/39: Tidy: (taxy-fill) Argument order in labeled function, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy f5458d0 29/39: Change: taxy-map -> taxy-mapcar, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 35c8f61 33/39: Add: (taxy-magit-section-indent), ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 4686e03 36/39: Add: (taxy-size), ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 34aa94d 23/39: Add: taxy-magit-section, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy a17e540 35/39: Docs: Show examples, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy aa0fe08 20/39: Change: taxy-copy -> taxy-emptied, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy c60a96f 12/39: Change: Rename taxy-simple, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 1699d3a 15/39: Docs: Clarify, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy fcc780f 27/39: Add: (taxy-take-keyed*),
ELPA Syncer <=
- [elpa] externals/taxy 4e132ab 28/39: Docs: Tidy, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 524b151 19/39: Tidy: (taxy-fill), ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 906d387 30/39: Fix: (taxy-magit-section-pp) Use magit-section-mode, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy a7ffe21 37/39: Change: (diredy) Sort taxys, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 2c044ed 39/39: Add: (taxy-take-keyed*) :then, and examples, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 5a1b055 38/39: Docs: Add magit-loggy example, ELPA Syncer, 2021/08/27
- [elpa] externals/taxy 3cf0d46 25/39: Docs: Export Info manual, ELPA Syncer, 2021/08/27