aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2022-04-14 01:00:44 +0200
committerLars Ingebrigtsen2022-04-14 01:00:44 +0200
commit800998808a1ebf83263ffbdea833c155fcbae7a6 (patch)
tree681525e5aa9743eaef1369b34e896888cec79f71
parent864c8013fdd0a548d98d81dd21af2f88f207858a (diff)
downloademacs-800998808a1ebf83263ffbdea833c155fcbae7a6.tar.gz
emacs-800998808a1ebf83263ffbdea833c155fcbae7a6.zip
Allow putting alternating colors on vtable rows
* doc/misc/vtable.texi (Making A Table): Document it. * lisp/emacs-lisp/vtable.el (vtable): Add :row-colors. (make-vtable): Ditto. (vtable--compute-colors, vtable--color-blend): New functions. (vtable--insert-line): Take a line number argument and adjust callers.
-rw-r--r--doc/misc/vtable.texi12
-rw-r--r--lisp/emacs-lisp/vtable.el61
2 files changed, 61 insertions, 12 deletions
diff --git a/doc/misc/vtable.texi b/doc/misc/vtable.texi
index 4f7b722a289..77cb8663af4 100644
--- a/doc/misc/vtable.texi
+++ b/doc/misc/vtable.texi
@@ -387,11 +387,21 @@ The face to be used. This defaults to @code{vtable}. This face
387doesn't override the faces in the data, or the faces supplied by the 387doesn't override the faces in the data, or the faces supplied by the
388getter and formatter functions. 388getter and formatter functions.
389 389
390@item :row-colors
391If present, this should be a list of color names to be used as the
392background color on the rows. If there are fewer colors here than
393there are rows, the rows will be repeated. The most common use
394case here is to have alternating background colors on the rows, so
395this would usually be a list of two colors.
396
390@item :column-colors 397@item :column-colors
391If present, this should be a list of color names to be used as the 398If present, this should be a list of color names to be used as the
392background color on the columns. If there are fewer colors here than 399background color on the columns. If there are fewer colors here than
393there are columns, the colors will be repeated. The most common use 400there are columns, the colors will be repeated. The most common use
394case here is to have alternating background colors on the columns. 401case here is to have alternating background colors on the columns, so
402this would usually be a list of two colors. If both
403@code{:row-colors} and @code{:column-colors} is present, the colors
404will be ``blended'' to produce the final colors in the table.
395 405
396@item :actions 406@item :actions
397This uses the same syntax as @code{define-keymap}, but doesn't refer 407This uses the same syntax as @code{define-keymap}, but doesn't refer
diff --git a/lisp/emacs-lisp/vtable.el b/lisp/emacs-lisp/vtable.el
index 3e521c94a5c..e0010434447 100644
--- a/lisp/emacs-lisp/vtable.el
+++ b/lisp/emacs-lisp/vtable.el
@@ -64,6 +64,8 @@
64 (sort-by :initarg :sort-by :accessor vtable-sort-by) 64 (sort-by :initarg :sort-by :accessor vtable-sort-by)
65 (ellipsis :initarg :ellipsis :accessor vtable-ellipsis) 65 (ellipsis :initarg :ellipsis :accessor vtable-ellipsis)
66 (column-colors :initarg :column-colors :accessor vtable-column-colors) 66 (column-colors :initarg :column-colors :accessor vtable-column-colors)
67 (row-colors :initarg :row-colors :accessor vtable-row-colors)
68 (-cached-colors :initform nil :accessor vtable--cached-colors)
67 (-cache :initform (make-hash-table :test #'equal))) 69 (-cache :initform (make-hash-table :test #'equal)))
68 "A object to hold the data for a table.") 70 "A object to hold the data for a table.")
69 71
@@ -91,6 +93,7 @@
91 sort-by 93 sort-by
92 (ellipsis t) 94 (ellipsis t)
93 (insert t) 95 (insert t)
96 row-colors
94 column-colors) 97 column-colors)
95 "Create and insert a vtable at point. 98 "Create and insert a vtable at point.
96The vtable object is returned. If INSERT is nil, the table won't 99The vtable object is returned. If INSERT is nil, the table won't
@@ -130,10 +133,15 @@ be inserted."
130 :keymap keymap 133 :keymap keymap
131 :separator-width separator-width 134 :separator-width separator-width
132 :sort-by sort-by 135 :sort-by sort-by
136 :row-colors row-colors
133 :column-colors column-colors 137 :column-colors column-colors
134 :ellipsis ellipsis))) 138 :ellipsis ellipsis)))
135 ;; Compute missing column data. 139 ;; Compute missing column data.
136 (setf (vtable-columns table) (vtable--compute-columns table)) 140 (setf (vtable-columns table) (vtable--compute-columns table))
141 ;; Compute colors if we have to mix them.
142 (when (and row-colors column-colors)
143 (setf (vtable--cached-colors table)
144 (vtable--compute-colors row-colors column-colors)))
137 (unless sort-by 145 (unless sort-by
138 (seq-do-indexed (lambda (column index) 146 (seq-do-indexed (lambda (column index)
139 (when (vtable-column-primary column) 147 (when (vtable-column-primary column)
@@ -144,6 +152,20 @@ be inserted."
144 (vtable-insert table)) 152 (vtable-insert table))
145 table)) 153 table))
146 154
155(defun vtable--compute-colors (row-colors column-colors)
156 (cl-loop for row in row-colors
157 collect (cl-loop for column in column-colors
158 collect (vtable--color-blend row column))))
159
160;;; FIXME: This is probably not the right way to blend two colors, is
161;;; it?
162(defun vtable--color-blend (color1 color2)
163 (cl-destructuring-bind (r g b)
164 (mapcar (lambda (n) (* (/ n 2) 255.0))
165 (cl-mapcar #'+ (color-name-to-rgb color1)
166 (color-name-to-rgb color2)))
167 (format "#%02X%02X%02X" r g b)))
168
147;;; Interface utility functions. 169;;; Interface utility functions.
148 170
149(defun vtable-current-table () 171(defun vtable-current-table ()
@@ -219,7 +241,8 @@ If it can't be found, return nil and don't move point."
219 (error "Can't find the old object")) 241 (error "Can't find the old object"))
220 (setcar (cdr objects) object)) 242 (setcar (cdr objects) object))
221 ;; Then update the cache... 243 ;; Then update the cache...
222 (let ((line (assq old-object (car (vtable--cache table))))) 244 (let* ((line-number (seq-position old-object (car (vtable--cache table))))
245 (line (elt (car (vtable--cache table)) line-number)))
223 (unless line 246 (unless line
224 (error "Can't find cached object")) 247 (error "Can't find cached object"))
225 (setcar line object) 248 (setcar line object)
@@ -230,7 +253,8 @@ If it can't be found, return nil and don't move point."
230 (let ((keymap (get-text-property (point) 'keymap)) 253 (let ((keymap (get-text-property (point) 'keymap))
231 (start (point))) 254 (start (point)))
232 (delete-line) 255 (delete-line)
233 (vtable--insert-line table line (nth 1 (vtable--cache table)) 256 (vtable--insert-line table line line-number
257 (nth 1 (vtable--cache table))
234 (vtable--spacer table)) 258 (vtable--spacer table))
235 (add-text-properties start (point) (list 'keymap keymap 259 (add-text-properties start (point) (list 'keymap keymap
236 'vtable table)))) 260 'vtable table))))
@@ -285,7 +309,10 @@ This also updates the displayed table."
285 (unless (vtable-goto-object after-object) 309 (unless (vtable-goto-object after-object)
286 (vtable-end-of-table)))) 310 (vtable-end-of-table))))
287 (let ((start (point))) 311 (let ((start (point)))
288 (vtable--insert-line table line (nth 1 cache) (vtable--spacer table)) 312 ;; FIXME: We have to adjust colors in lines below this if we
313 ;; have :row-colors.
314 (vtable--insert-line table line 0
315 (nth 1 cache) (vtable--spacer table))
289 (add-text-properties start (point) (list 'keymap keymap 316 (add-text-properties start (point) (list 'keymap keymap
290 'vtable table))) 317 'vtable table)))
291 ;; We may have inserted a non-numerical value into a previously 318 ;; We may have inserted a non-numerical value into a previously
@@ -374,20 +401,26 @@ This also updates the displayed table."
374 (setq start (point))) 401 (setq start (point)))
375 (vtable--sort table) 402 (vtable--sort table)
376 ;; Insert the data. 403 ;; Insert the data.
377 (dolist (line (car (vtable--cache table))) 404 (let ((line-number 0))
378 (vtable--insert-line table line widths spacer 405 (dolist (line (car (vtable--cache table)))
379 ellipsis ellipsis-width)) 406 (vtable--insert-line table line line-number widths spacer
407 ellipsis ellipsis-width)
408 (setq line-number (1+ line-number))))
380 (add-text-properties start (point) 409 (add-text-properties start (point)
381 (list 'keymap (vtable--make-keymap table) 410 (list 'keymap (vtable--make-keymap table)
382 'rear-nonsticky t 411 'rear-nonsticky t
383 'vtable table)) 412 'vtable table))
384 (goto-char start))) 413 (goto-char start)))
385 414
386(defun vtable--insert-line (table line widths spacer 415(defun vtable--insert-line (table line line-number widths spacer
387 &optional ellipsis ellipsis-width) 416 &optional ellipsis ellipsis-width)
388 (let ((start (point)) 417 (let ((start (point))
389 (columns (vtable-columns table)) 418 (columns (vtable-columns table))
390 (colors (vtable-column-colors table))) 419 (column-colors
420 (if (vtable-row-colors table)
421 (elt (vtable--cached-colors table)
422 (mod line-number (length (vtable-row-colors table))))
423 (vtable-column-colors table))))
391 (seq-do-indexed 424 (seq-do-indexed
392 (lambda (elem index) 425 (lambda (elem index)
393 (let ((value (nth 0 elem)) 426 (let ((value (nth 0 elem))
@@ -449,14 +482,20 @@ This also updates the displayed table."
449 (list 'space 482 (list 'space
450 :width (list spacer))))) 483 :width (list spacer)))))
451 (put-text-property start (point) 'vtable-column index) 484 (put-text-property start (point) 'vtable-column index)
452 (when colors 485 (when column-colors
453 (add-face-text-property 486 (add-face-text-property
454 start (point) 487 start (point)
455 (list :background 488 (list :background
456 (elt colors (mod index (length colors))))))))) 489 (elt column-colors (mod index (length column-colors)))))))))
457 (cdr line)) 490 (cdr line))
458 (insert "\n") 491 (insert "\n")
459 (put-text-property start (point) 'vtable-object (car line)))) 492 (put-text-property start (point) 'vtable-object (car line))
493 (unless column-colors
494 (when-let ((row-colors (vtable-row-colors table)))
495 (add-face-text-property
496 start (point)
497 (list :background
498 (elt row-colors (mod line-number (length row-colors)))))))))
460 499
461(defun vtable--cache-key () 500(defun vtable--cache-key ()
462 (cons (frame-terminal) (window-width))) 501 (cons (frame-terminal) (window-width)))