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

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

[elpa] externals/taxy fe190c2 09/42: Add: (taxy-magit-section-define-col


From: ELPA Syncer
Subject: [elpa] externals/taxy fe190c2 09/42: Add: (taxy-magit-section-define-column-definer)
Date: Wed, 15 Sep 2021 12:57:27 -0400 (EDT)

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

    Add: (taxy-magit-section-define-column-definer)
---
 taxy-magit-section.el | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/taxy-magit-section.el b/taxy-magit-section.el
index 5a8e48c..85af4d3 100644
--- a/taxy-magit-section.el
+++ b/taxy-magit-section.el
@@ -168,6 +168,82 @@ Default visibility function for
        (_ 'show)))
     (_ nil)))
 
+;;;; Column-based formatting
+
+;; Column-based, or "table"?
+
+;; TODO: Probably, this belongs in a separate library, since it's not
+;; directly related to using taxy or magit-section.  Maybe it could be
+;; called something like `flextab' (or, keeping with the theme,
+;; `tabley').
+
+;;;;; Macros
+
+(cl-defmacro taxy-magit-section-define-column-definer (prefix &key 
columns-variable-docstring)
+  "FIXME: Docstring."
+  (let* ((definer-name (intern (format "%s-define-column" prefix)))
+        (definer-docstring (format "Define a column formatting function with 
NAME.
+NAME should be a string.  BODY should return a string or nil.  In
+the BODY, `item' is bound to the item being formatted, and `depth' is
+bound to the item's depth in the hierarchy.
+
+PLIST may be a plist setting the following options:
+
+  `:face' is a face applied to the string.
+
+  `:max-width' defines a customization option for the column's
+  maximum width with the specified value as its default: an
+  integer limits the width, while nil does not."))
+        (columns-variable-name (intern (format "%s-columns" prefix)))
+        (columns-variable-docstring (or columns-variable-docstring
+                                        (format "Columns defined by `%s'."
+                                                definer-name)))
+        (column-formatters-variable-name (intern (format 
"%s-column-formatters" prefix)))
+        (column-formatters-variable-docstring (format "Column formatters 
defined by `%s'."
+                                                      definer-name)))
+    ;; TODO: Add defined columns to customization type for the 
columns-variable.
+    `(let ((columns-variable ',columns-variable-name)
+          (column-formatters-variable ',column-formatters-variable-name))
+       (defvar ,columns-variable-name nil
+        ,columns-variable-docstring)
+       (defvar ,column-formatters-variable-name nil
+        ,column-formatters-variable-docstring)
+       (defmacro ,definer-name (name plist &rest body)
+        ,definer-docstring
+        (declare (indent defun))
+        (cl-check-type name string)
+        (pcase-let* ((fn-name (intern (concat ,prefix "-column-format-" 
(downcase name))))
+                     ((map (:face face) (:max-width max-width)) plist)
+                     (max-width-variable (intern (concat ,prefix "-" name 
"-max-width")))
+                     (max-width-docstring (format "Maximum width of the %s 
column." name)))
+          `(progn
+             ,(when (plist-member plist :max-width)
+                `(defcustom ,max-width-variable
+                   ,max-width
+                   ,max-width-docstring
+                   :type '(choice (integer :tag "Maximum width")
+                                  (const :tag "Unlimited width" nil))))
+             (defun ,fn-name (item depth)
+               (if-let ((string (progn ,@body)))
+                   (progn
+                     ,(when max-width
+                        `(when ,max-width-variable
+                           (setf string (truncate-string-to-width string 
,max-width-variable nil nil "…"))))
+                     ,(when face
+                        ;; Faces are not defined until load time, while this 
checks type at expansion
+                        ;; time, so we can only test that the argument is a 
symbol, not a face.
+                        (cl-check-type face symbol ":face must be a face 
symbol")
+                        `(setf string (propertize string 'face ',face)))
+                     string)
+                 ""))
+             (setf (map-elt ,column-formatters-variable ,name) #',fn-name)
+             (unless (member ,name (get ',columns-variable 'standard-value))
+               (setf (get ',columns-variable 'standard-value)
+                     (append (get ',columns-variable 'standard-value)
+                             (list ,name))))))))))
+
+;;;;; Functions
+
 ;; MAYBE: Consider using spaces with `:align-to', rather than formatting 
strings with indentation, as used by `epkg'
 ;; (see 
<https://github.com/emacscollective/epkg/blob/edf8c009066360af61caedf67a2482eaa19481b0/epkg-desc.el#L363>).
 ;; I'm not sure which would perform better; I guess that with many lines, 
redisplay might take longer to use the



reply via email to

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