branch: externals/modus-themes
commit dc0d606e2a7058485913cbb33f27bad8e66c2d7b
Author: Protesilaos Stavrou <i...@protesilaos.com>
Commit: Protesilaos Stavrou <i...@protesilaos.com>

    Refactor the palette preview commands to use tabulated-list-mode
---
 doc/modus-themes.info | 244 +++++++++++++++++++++++++-------------------------
 doc/modus-themes.org  |  35 ++++----
 modus-themes.el       | 134 +++++++++++++--------------
 3 files changed, 203 insertions(+), 210 deletions(-)

diff --git a/doc/modus-themes.info b/doc/modus-themes.info
index cc1557f87d..0be9226afc 100644
--- a/doc/modus-themes.info
+++ b/doc/modus-themes.info
@@ -1457,36 +1457,36 @@ File: modus-themes.info,  Node: Preview theme colors,  
Next: Use colors from the
 5 Preview theme colors
 **********************
 
-The command ‘modus-themes-list-colors’ uses minibuffer completion to
+[ The preview is revised as part of 4.7.0-dev to use the
+‘tabulated-list-mode’.  This means that the user can now sort by column.
+]
+
+   The command ‘modus-themes-list-colors’ uses minibuffer completion to
 select an item from the Modus themes and then produces a buffer with
-previews of its color palette entries.  The buffer has a naming scheme
-that reflects the given choice, like ‘modus-operandi-list-colors’ for
-the ‘modus-operandi’ theme.
+previews of all of its color palette entries.
 
    The command ‘modus-themes-list-colors-current’ skips the minibuffer
-selection process and just produces a preview for the current Modus
-theme.
+selection process to produce a preview for the current Modus theme.
 
    When called with a prefix argument (‘C-u’ with the default key
 bindings), these commands will show a preview of the palette’s semantic
-color mappings instead of the named colors.  In this context, “named
-colors” are entries that associate a symbol to a string color value,
-such as ‘(blue-warmer "#354fcf")’.  Whereas “semantic color mappings”
-associate a named color to a symbol, like ‘(string blue-warmer)’, thus
-making the theme render all string constructs in the ‘blue-warmer’ color
-value (*note Option for palette overrides: Palette overrides.).
-
-   Aliases for those commands are ‘modus-themes-preview-colors’ and
+color mappings instead of the full palette (*note Option for palette
+overrides: Palette overrides.).
+
+   Aliases for these commands are ‘modus-themes-preview-colors’ and
 ‘modus-themes-preview-colors-current’.
 
-   Each row shows a foreground and background coloration using the
-underlying value it references.  For example a line with ‘#a60000’ (a
-shade of red) will show red text followed by a stripe with that same
-color as a backdrop.
+   Each row includes a foreground and background rendition of the given
+color value.  For example a line with ‘#a60000’ (a shade of red) will
+show a column with a red background combined with a suitable foreground
+followed by another column with a red foreground against the current
+theme’s background.  The intent is to illustrate which values are
+suitable as a background or foreground.
 
    The name of the buffer describes the given Modus theme and what the
-contents are, such as ‘*modus-operandi-list-colors*’ for named colors
-and ‘=*modus-operandi-list-mappings*’ for the semantic color mappings.
+contents are, such as ‘*modus-operandi-list-all*’ for the entirety of
+the palette (named colors as well as semantic color mappings) and
+‘=*modus-operandi-list-mappings*’ for the mappings only.
 
 
 File: modus-themes.info,  Node: Use colors from the Modus themes palette,  
Next: Advanced customization,  Prev: Preview theme colors,  Up: Top
@@ -6486,11 +6486,11 @@ B.1 Function index
                                                                (line  6)
 * modus-themes-get-color-value:          Get a single color from the palette 
with modus-themes-get-color-value.
                                                                (line  6)
-* modus-themes-list-colors:              Preview theme colors. (line  6)
-* modus-themes-list-colors-current:      Preview theme colors. (line 12)
+* modus-themes-list-colors:              Preview theme colors. (line 10)
+* modus-themes-list-colors-current:      Preview theme colors. (line 14)
 * modus-themes-load-theme:               Enable and load.      (line 79)
-* modus-themes-preview-colors:           Preview theme colors. (line 25)
-* modus-themes-preview-colors-current:   Preview theme colors. (line 25)
+* modus-themes-preview-colors:           Preview theme colors. (line 22)
+* modus-themes-preview-colors-current:   Preview theme colors. (line 22)
 * modus-themes-rotate:                   Option for which themes to rotate.
                                                                (line  6)
 * modus-themes-select:                   Enable and load.      (line 93)
@@ -6659,104 +6659,104 @@ Node: UI typeface47068
 Node: Palette overrides48041
 Node: Palette extension52431
 Node: Preview theme colors54907
-Node: Use colors from the Modus themes palette56720
-Node: Get a single color from the palette with 
modus-themes-get-color-value57584
-Node: Use theme colors in code with modus-themes-with-colors59946
-Node: Advanced customization62202
-Node: DIY Palette override presets63998
-Node: DIY Add support for engrave-faces66840
-Node: DIY Stylistic variants using palette overrides76823
-Node: DIY Make the mode line borderless78882
-Node: DIY Make the active mode line colorful80257
-Node: DIY Make the tab bar more or less colorful82475
-Node: DIY Make the fringe invisible or another color84412
-Node: DIY Make links use subtle or no underlines85613
-Node: DIY Make prompts more or less colorful86731
-Node: DIY Make completion matches more or less colorful88054
-Node: DIY Make comments yellow and strings green91613
-Node: DIY Make code syntax use the old alt-syntax style93322
-Node: DIY Make use of alternative styles for code syntax96445
-Node: DIY Make matching parenthesis more or less intense99907
-Node: DIY Make box buttons more or less gray101279
-Node: DIY Make TODO and DONE more or less intense102292
-Node: DIY Make headings more or less colorful103793
-Node: DIY Make Org block colors more or less colorful105910
-Node: DIY Make Org agenda more or less colorful110284
-Node: DIY Make inline code in prose use alternative styles113459
-Node: DIY Make mail citations and headers more or less colorful115701
-Node: DIY Make the region preserve text colors plus other styles118101
-Node: DIY Make mouse highlights more or less colorful119657
-Node: DIY Make language underlines less colorful120670
-Node: DIY Make line numbers use alternative styles121822
-Node: DIY Make diffs use only a foreground123465
-Node: DIY Make deuteranopia diffs red and blue instead of yellow and 
blue126356
-Node: DIY More accurate colors in terminal emulators128836
-Node: DIY Range of color with terminal emulators130148
-Node: DIY Per-theme customization settings132941
-Node: DIY Do not extend the region background134374
-Node: DIY Add padding to the mode line135178
-Node: DIY Remap face with local value138112
-Node: DIY Font configurations for Org and others140659
-Ref: DIY Font configurations for Org and others-Footnote-1143644
-Node: DIY Configure bold and italic faces143831
-Node: DIY Custom Org todo keyword and priority faces148453
-Node: DIY Custom Org emphasis faces152196
-Node: DIY Use colored Org source blocks per language157077
-Node: DIY Measure color contrast161717
-Node: DIY Load theme depending on time of day164437
-Node: DIY Backdrop for pdf-tools165467
-Node: DIY Toggle themes without reloading them168636
-Node: DIY Use more spacious margins or padding in Emacs frames169945
-Node: DIY Custom hl-todo colors174202
-Node: DIY Add support for solaire-mode176019
-Node: DIY Add support for meow-mode179125
-Node: DIY Add support for combobulate180905
-Node: DIY Add support for howm184509
-Node: DIY Use a hook at the post-load-theme phase186579
-Node: DIY A theme-agnostic hook for theme loading188695
-Node: Face coverage191326
-Node: Supported packages191778
-Node: Indirectly covered packages197597
-Node: Notes on individual packages198953
-Node: Note on calendarel weekday and weekend colors200053
-Node: Note on git-gutter in Doom Emacs201201
-Node: Note on php-mode multiline comments203701
-Node: Note on underlines in compilation buffers204461
-Node: Note on inline Latex in Org buffers205333
-Node: Note on dimmerel205943
-Node: Note on display-fill-column-indicator-mode207428
-Node: Note on highlight-parenthesesel208881
-Node: Note on mmm-modeel background colors214962
-Node: Note for prism217316
-Node: Note on company-mode overlay pop-up220538
-Ref: Note on company-mode overlay pop-up-Footnote-1221268
-Ref: Note on company-mode overlay pop-up-Footnote-2221335
-Node: Note on ERC escaped color sequences221390
-Ref: Note on ERC escaped color sequences-Footnote-1222818
-Node: Note on powerline or spaceline222928
-Node: Note on SHR colors223342
-Node: Note on SHR fonts223766
-Node: Note on Ement colors and fonts224453
-Node: Note on pdf-tools link hints225963
-Node: Note on the Notmuch logo228423
-Node: Note on goto-address-mode faces228961
-Node: Frequently Asked Questions230079
-Node: Is the contrast ratio about adjacent colors?230712
-Node: What does it mean to avoid exaggerations?232221
-Node: Why are colors mostly variants of blue magenta cyan?234073
-Node: What is the best setup for legibility?238407
-Node: Are these color schemes?241055
-Node: Port the Modus themes to other platforms?244739
-Node: Contributing247585
-Node: Sources of the themes247984
-Node: Issues you can help with248880
-Node: Patches require copyright assignment to the FSF250273
-Node: Acknowledgements252495
-Node: GNU Free Documentation License256796
-Node: Indices282160
-Node: Function index282339
-Node: Variable index283935
-Node: Concept index287435
+Node: Use colors from the Modus themes palette56603
+Node: Get a single color from the palette with 
modus-themes-get-color-value57467
+Node: Use theme colors in code with modus-themes-with-colors59829
+Node: Advanced customization62085
+Node: DIY Palette override presets63881
+Node: DIY Add support for engrave-faces66723
+Node: DIY Stylistic variants using palette overrides76706
+Node: DIY Make the mode line borderless78765
+Node: DIY Make the active mode line colorful80140
+Node: DIY Make the tab bar more or less colorful82358
+Node: DIY Make the fringe invisible or another color84295
+Node: DIY Make links use subtle or no underlines85496
+Node: DIY Make prompts more or less colorful86614
+Node: DIY Make completion matches more or less colorful87937
+Node: DIY Make comments yellow and strings green91496
+Node: DIY Make code syntax use the old alt-syntax style93205
+Node: DIY Make use of alternative styles for code syntax96328
+Node: DIY Make matching parenthesis more or less intense99790
+Node: DIY Make box buttons more or less gray101162
+Node: DIY Make TODO and DONE more or less intense102175
+Node: DIY Make headings more or less colorful103676
+Node: DIY Make Org block colors more or less colorful105793
+Node: DIY Make Org agenda more or less colorful110167
+Node: DIY Make inline code in prose use alternative styles113342
+Node: DIY Make mail citations and headers more or less colorful115584
+Node: DIY Make the region preserve text colors plus other styles117984
+Node: DIY Make mouse highlights more or less colorful119540
+Node: DIY Make language underlines less colorful120553
+Node: DIY Make line numbers use alternative styles121705
+Node: DIY Make diffs use only a foreground123348
+Node: DIY Make deuteranopia diffs red and blue instead of yellow and 
blue126239
+Node: DIY More accurate colors in terminal emulators128719
+Node: DIY Range of color with terminal emulators130031
+Node: DIY Per-theme customization settings132824
+Node: DIY Do not extend the region background134257
+Node: DIY Add padding to the mode line135061
+Node: DIY Remap face with local value137995
+Node: DIY Font configurations for Org and others140542
+Ref: DIY Font configurations for Org and others-Footnote-1143527
+Node: DIY Configure bold and italic faces143714
+Node: DIY Custom Org todo keyword and priority faces148336
+Node: DIY Custom Org emphasis faces152079
+Node: DIY Use colored Org source blocks per language156960
+Node: DIY Measure color contrast161600
+Node: DIY Load theme depending on time of day164320
+Node: DIY Backdrop for pdf-tools165350
+Node: DIY Toggle themes without reloading them168519
+Node: DIY Use more spacious margins or padding in Emacs frames169828
+Node: DIY Custom hl-todo colors174085
+Node: DIY Add support for solaire-mode175902
+Node: DIY Add support for meow-mode179008
+Node: DIY Add support for combobulate180788
+Node: DIY Add support for howm184392
+Node: DIY Use a hook at the post-load-theme phase186462
+Node: DIY A theme-agnostic hook for theme loading188578
+Node: Face coverage191209
+Node: Supported packages191661
+Node: Indirectly covered packages197480
+Node: Notes on individual packages198836
+Node: Note on calendarel weekday and weekend colors199936
+Node: Note on git-gutter in Doom Emacs201084
+Node: Note on php-mode multiline comments203584
+Node: Note on underlines in compilation buffers204344
+Node: Note on inline Latex in Org buffers205216
+Node: Note on dimmerel205826
+Node: Note on display-fill-column-indicator-mode207311
+Node: Note on highlight-parenthesesel208764
+Node: Note on mmm-modeel background colors214845
+Node: Note for prism217199
+Node: Note on company-mode overlay pop-up220421
+Ref: Note on company-mode overlay pop-up-Footnote-1221151
+Ref: Note on company-mode overlay pop-up-Footnote-2221218
+Node: Note on ERC escaped color sequences221273
+Ref: Note on ERC escaped color sequences-Footnote-1222701
+Node: Note on powerline or spaceline222811
+Node: Note on SHR colors223225
+Node: Note on SHR fonts223649
+Node: Note on Ement colors and fonts224336
+Node: Note on pdf-tools link hints225846
+Node: Note on the Notmuch logo228306
+Node: Note on goto-address-mode faces228844
+Node: Frequently Asked Questions229962
+Node: Is the contrast ratio about adjacent colors?230595
+Node: What does it mean to avoid exaggerations?232104
+Node: Why are colors mostly variants of blue magenta cyan?233956
+Node: What is the best setup for legibility?238290
+Node: Are these color schemes?240938
+Node: Port the Modus themes to other platforms?244622
+Node: Contributing247468
+Node: Sources of the themes247867
+Node: Issues you can help with248763
+Node: Patches require copyright assignment to the FSF250156
+Node: Acknowledgements252378
+Node: GNU Free Documentation License256679
+Node: Indices282043
+Node: Function index282222
+Node: Variable index283818
+Node: Concept index287318
 
 End Tag Table
 
diff --git a/doc/modus-themes.org b/doc/modus-themes.org
index c5ca963a58..64c432bb03 100644
--- a/doc/modus-themes.org
+++ b/doc/modus-themes.org
@@ -1306,40 +1306,39 @@ Examples demonstrating how to use the aforementioned:
 :end:
 #+cindex: Preview named colors or semantic color mappings
 
+[ The preview is revised as part of {{{development-version}}} to use
+  the ~tabulated-list-mode~. This means that the user can now sort by
+  column. ]
+
 #+findex: modus-themes-list-colors
 The command ~modus-themes-list-colors~ uses minibuffer completion to
 select an item from the Modus themes and then produces a buffer with
-previews of its color palette entries.  The buffer has a naming scheme
-that reflects the given choice, like =modus-operandi-list-colors= for
-the ~modus-operandi~ theme.
+previews of all of its color palette entries.
 
 #+findex: modus-themes-list-colors-current
 The command ~modus-themes-list-colors-current~ skips the minibuffer
-selection process and just produces a preview for the current Modus
-theme.
+selection process to produce a preview for the current Modus theme.
 
 When called with a prefix argument (=C-u= with the default key
 bindings), these commands will show a preview of the palette's
-semantic color mappings instead of the named colors.  In this context,
-"named colors" are entries that associate a symbol to a string color
-value, such as =(blue-warmer "#354fcf")=.  Whereas "semantic color
-mappings" associate a named color to a symbol, like =(string
-blue-warmer)=, thus making the theme render all string constructs in
-the =blue-warmer= color value 
([[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]]).
+semantic color mappings instead of the full palette 
([[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]]).
 
 #+findex: modus-themes-preview-colors
 #+findex: modus-themes-preview-colors-current
-Aliases for those commands are ~modus-themes-preview-colors~ and
+Aliases for these commands are ~modus-themes-preview-colors~ and
 ~modus-themes-preview-colors-current~.
 
-Each row shows a foreground and background coloration using the
-underlying value it references.  For example a line with =#a60000= (a
-shade of red) will show red text followed by a stripe with that same
-color as a backdrop.
+Each row includes a foreground and background rendition of the given
+color value. For example a line with =#a60000= (a shade of red) will
+show a column with a red background combined with a suitable
+foreground followed by another column with a red foreground against
+the current theme's background. The intent is to illustrate which
+values are suitable as a background or foreground.
 
 The name of the buffer describes the given Modus theme and what the
-contents are, such as =*modus-operandi-list-colors*= for named colors
-and ==*modus-operandi-list-mappings*= for the semantic color mappings.
+contents are, such as =*modus-operandi-list-all*= for the entirety of
+the palette (named colors as well as semantic color mappings) and
+==*modus-operandi-list-mappings*= for the mappings only.
 
 * Use colors from the Modus themes palette
 :PROPERTIES:
diff --git a/modus-themes.el b/modus-themes.el
index b418a9c903..31419bf04d 100644
--- a/modus-themes.el
+++ b/modus-themes.el
@@ -6,7 +6,7 @@
 ;; Maintainer: Protesilaos Stavrou <i...@protesilaos.com>
 ;; URL: https://github.com/protesilaos/modus-themes
 ;; Version: 4.6.0
-;; Package-Requires: ((emacs "27.1"))
+;; Package-Requires: ((emacs "28.1"))
 ;; Keywords: faces, theme, accessibility
 
 ;; This file is part of GNU Emacs.
@@ -1294,87 +1294,81 @@ the list becomes the last.  Do not modify THEMES in the 
process."
 
 ;;;;; Preview a theme palette
 
-(defun modus-themes--list-colors-render (buffer theme &optional mappings &rest 
_)
-  "Render colors in BUFFER from THEME for `modus-themes-list-colors'.
-Optional MAPPINGS changes the output to only list the semantic
-color mappings of the palette, instead of its named colors."
+(defun modus-themes--list-colors-get-mappings (palette)
+  "Get the semantic palette entries in PALETTE.
+PALETTE is the value of a variable like `modus-operandi-palette'."
+  (seq-remove
+   (lambda (cell)
+     (stringp (cadr cell)))
+   palette))
+
+(defun modus-themes--list-colors-tabulated (theme &optional mappings)
+  "Return a data structure of THEME palette or MAPPINGS for tabulated list."
   (let* ((current-palette (modus-themes--palette-value theme mappings))
          (palette (if mappings
-                      (seq-remove (lambda (cell)
-                                    (stringp (cadr cell)))
-                                  current-palette)
-                    current-palette))
-         (current-buffer buffer)
-         (current-theme theme))
-    (with-help-window buffer
-      (with-current-buffer standard-output
-        (erase-buffer)
-        (when (<= (display-color-cells) 256)
-          (insert (concat "Your display terminal may not render all color 
previews!\n"
-                          "It seems to only support <= 256 colors.\n\n"))
-          (put-text-property (point-min) (point) 'face 'warning))
-        ;; We need this to properly render the first line.
-        (insert " ")
-        (dolist (cell palette)
-          (let* ((name (car cell))
-                 (color (modus-themes-get-color-value name mappings theme))
-                 (pad (make-string 10 ?\s))
-                 (fg (if (eq color 'unspecified)
-                         (progn
-                           (readable-foreground-color 
(modus-themes-get-color-value 'bg-main nil theme))
-                           (setq pad (make-string 6 ?\s)))
-                       (readable-foreground-color color))))
-            (let ((old-point (point)))
-              (insert (format "%s %s" color pad))
-              (put-text-property old-point (point) 'face `( :foreground 
,color)))
-            (let ((old-point (point)))
-              (insert (format " %s %s %s\n" color pad name))
-              (put-text-property old-point (point)
-                                 'face `( :background ,color
-                                          :foreground ,fg
-                                          :extend t)))
-            ;; We need this to properly render the last line.
-            (insert " ")))
-        (setq-local revert-buffer-function
-                    (lambda (_ignore-auto _noconfirm)
-                      (modus-themes--list-colors-render current-buffer 
current-theme mappings)))))))
-
-(defvar modus-themes--list-colors-prompt-history '()
-  "Minibuffer history for `modus-themes--list-colors-prompt'.")
-
-(defun modus-themes--list-colors-prompt ()
-  "Prompt for Modus theme.
-Helper function for `modus-themes-list-colors'."
-  (let ((def (format "%s" (modus-themes--current-theme)))
-        (completion-extra-properties `(:annotation-function 
,#'modus-themes--annotate-theme)))
-    (completing-read
-     (format "Use palette from theme [%s]: " def)
-     (modus-themes--completion-table-candidates)
-     nil t nil
-     'modus-themes--list-colors-prompt-history def)))
+                      (modus-themes--list-colors-get-mappings current-palette)
+                    current-palette)))
+    (mapcar (lambda (cell)
+              (pcase-let* ((`(,name ,value) cell)
+                           (name-string (format "%s" name))
+                           (value-string (format "%s" value))
+                           (value-string-padded (string-pad value-string 30))
+                           (color (modus-themes-get-color-value name mappings 
theme))) ; resolve a semantic mapping
+                (list name
+                      (vector
+                       (if (symbolp value)
+                           "Yes"
+                         "")
+                       name-string
+                       (propertize value-string 'face `( :foreground ,color))
+                       (propertize value-string-padded 'face (list :background 
color
+                                                                   :foreground 
(if (string= color "unspecified")
+                                                                               
    (readable-foreground-color (modus-themes-get-color-value 'bg-main nil 
theme))
+                                                                               
  (readable-foreground-color color))))))))
+            palette)))
+
+(defvar modus-themes-current-preview nil)
+(defvar modus-themes-current-preview-show-mappings nil)
+
+(defun modus-themes--set-tabulated-entries ()
+  "Set the value of `tabulated-list-entries' with palette entries."
+  (setq-local tabulated-list-entries
+              (modus-themes--list-colors-tabulated 
modus-themes-current-preview modus-themes-current-preview-show-mappings)))
 
 (defun modus-themes-list-colors (theme &optional mappings)
-  "Preview named colors of the Modus THEME of choice.
-With optional prefix argument for MAPPINGS preview the semantic
-color mappings instead of the named colors."
-  (interactive (list (intern (modus-themes--list-colors-prompt)) 
current-prefix-arg))
-  (modus-themes--list-colors-render
-   (format (if mappings "*%s-list-mappings*" "*%s-list-colors*") theme)
-   theme
-   mappings))
+  "Preview the palette of the Modus THEME of choice.
+With optional prefix argument for MAPPINGS preview only the semantic
+color mappings instead of the complete palette."
+  (interactive (list (modus-themes--select-prompt) current-prefix-arg))
+  (let ((buffer (get-buffer-create (format (if mappings "*%s-list-mappings*" 
"*%s-list-all*") theme))))
+    (with-current-buffer buffer
+      (let ((modus-themes-current-preview theme)
+            (modus-themes-current-preview-show-mappings mappings))
+        (modus-themes-preview-mode)))
+    (pop-to-buffer buffer)))
 
 (defalias 'modus-themes-preview-colors 'modus-themes-list-colors
-  "Alias of `modus-themes-list-colors'.")
+  "Alias for `modus-themes-list-colors'.")
 
 (defun modus-themes-list-colors-current (&optional mappings)
-  "Call `modus-themes-list-colors' for the current Modus theme.
-Optional prefix argument MAPPINGS has the same meaning as for
-`modus-themes-list-colors'."
+  "Like `modus-themes-list-colors' with optional MAPPINGS for the current 
theme."
   (interactive "P")
   (modus-themes-list-colors (modus-themes--current-theme) mappings))
 
 (defalias 'modus-themes-preview-colors-current 
'modus-themes-list-colors-current
-  "Alias of `modus-themes-list-colors-current'.")
+  "Alias for `modus-themes-list-colors-current'.")
+
+(define-derived-mode modus-themes-preview-mode tabulated-list-mode "Modus 
palette"
+  "Major mode to display a Modus themes palette."
+  :interactive nil
+  (setq-local tabulated-list-format
+              [("Mapping?" 10 t)
+               ("Symbol name" 30 t)
+               ("As foreground" 30 t)
+               ("As background" 0 t)])
+  (modus-themes--set-tabulated-entries)
+  (tabulated-list-init-header)
+  (tabulated-list-print))
 
 
 

Reply via email to