From 4e54737659314a73b2177a9ee789557d08431b10 Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Wed, 20 May 2026 12:34:16 -0400 Subject: [PATCH] add save-theme/load-theme persistence --- org/text-input.org | 11 ++++++----- org/theme.org | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/org/text-input.org b/org/text-input.org index de63dbe..cd03b3d 100644 --- a/org/text-input.org +++ b/org/text-input.org @@ -408,9 +408,10 @@ sequences where modifiers appear in a non-standard position. #+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/input.lisp (defun parse-csi-params (params terminator extended) - (let* ((key (if (find terminator '(#\~ #\u)) + (let* ((terminator-char (code-char terminator)) + (key (if (and terminator-char (find terminator-char '(#\~ #\u))) (cdr (assoc (first params) *csi-tilde-table*)) - (cdr (assoc terminator *csi-key-table*)))) + (cdr (assoc terminator-char *csi-key-table*)))) (modifier (when (and (> (length params) 1) (not (find terminator '(#\~ #\u)))) (second params))) (actual-modifier (when (> (length extended) 1) (second extended))) @@ -642,9 +643,9 @@ to ~parse-csi-params~ for modifier extraction. (setf (fill-pointer extended) (length p)) (replace extended p)) r) - ;; Non-digit branch: b2 is a direct CSI terminator - (progn (vector-push-extend b2 extended) - (multiple-value-list (read-param (lambda () (read-raw-byte)))))))) + ;; Non-digit branch: b2 is a direct CSI terminator + (progn (vector-push-extend b2 extended) + (list nil b2))))) (let ((params (first parsed)) (terminator (or (second parsed) 0))) (parse-csi-params (or params '()) terminator extended))))))) diff --git a/org/theme.org b/org/theme.org index f871f0b..aa48921 100644 --- a/org/theme.org +++ b/org/theme.org @@ -50,7 +50,8 @@ and the backend's ~*theme-colors*~ for SGR resolution. (:use :cl :cl-tty.backend) (:export #:theme #:make-theme #:theme-mode - #:theme-color #:load-preset #:define-preset)) + #:theme-color #:load-preset #:define-preset + #:save-theme #:load-theme)) (in-package :cl-tty.theme) #+END_SRC @@ -395,5 +396,43 @@ contrast than default, designed for reduced eye strain. :markdown-link "#81A1C1" :markdown-quote "#8F9BB3" :syntax-keyword "#81A1C1" :syntax-function "#A3BE8C" :syntax-string "#D08770" :syntax-number "#B48EAD" - :syntax-comment "#8F9BB3" :syntax-type "#88C0D0")) + :syntax-comment "#8F9BB3" :syntax-type "#88C0D0")) +#+END_SRC + +** Persistence + +The theme system provides functions to save and restore a theme's role +map to and from a Lisp data file. The file format is an alist of +~(role . hex)~ pairs, written by ~prin1~ and read with ~read~. + +*** defun save-theme + +Serialises the theme's role hash table to a file. Each ~(role . hex)~ +pair is written as a cons cell in an alist. + +#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/theme.lisp +(defun save-theme (theme path) + "Persist THEME's role map to file at PATH as an alist." + (ensure-directories-exist path) + (with-open-file (out path :direction :output :if-exists :supersede) + (let (alist) + (maphash (lambda (k v) (push (cons k v) alist)) (theme-roles theme)) + (prin1 (nreverse alist) out)) + t)) +#+END_SRC + +*** defun load-theme + +Restores a theme's role map from a file previously written by +~save-theme~. The file is an alist of ~(role . hex)~ pairs. If the +file does not exist, returns nil silently. + +#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/theme.lisp +(defun load-theme (theme path) + "Restore THEME's role map from file at PATH. +Returns T on success, nil if the file does not exist." + (when (probe-file path) + (with-open-file (in path :direction :input) + (dolist (pair (read in) t) + (setf (gethash (car pair) (theme-roles theme)) (cdr pair)))))) #+END_SRC