aboutsummaryrefslogtreecommitdiff
path: root/modules/user-constants.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-14 17:23:37 -0500
committerCraig Jennings <c@cjennings.net>2026-06-14 17:23:37 -0500
commit7ccc3f5c0d688914eff0f8501f85d3f40ab8601d (patch)
tree96c1669768a87345747a441fa3effd265d5a74b3 /modules/user-constants.el
parentabaf96f1b4b9efc296161e2315549f55377740b4 (diff)
downloaddotemacs-7ccc3f5c0d688914eff0f8501f85d3f40ab8601d.tar.gz
dotemacs-7ccc3f5c0d688914eff0f8501f85d3f40ab8601d.zip
refactor(ui): color the cursor and modeline from theme faces, in sync
The cursor color and the modeline buffer-name indicator both hard-coded hex colors through cj/buffer-status-colors. Replaced that constant with cj/buffer-status-faces, mapping each buffer state to a theme face: read-only to error, overwrite and modified to warning, unmodified to success. A shared classifier (cj/buffer-status-state) and resolver (cj/buffer-status-color) in user-constants now drive both consumers, so the cursor and the modeline resolve their color from the active theme at use time and stay in sync, including the ghostel-terminal case the cursor already special-cased. Tests cover the map, the classifier, the resolver, and both integration paths.
Diffstat (limited to 'modules/user-constants.el')
-rw-r--r--modules/user-constants.el45
1 files changed, 38 insertions, 7 deletions
diff --git a/modules/user-constants.el b/modules/user-constants.el
index 2e64b355e..1ee8ecda3 100644
--- a/modules/user-constants.el
+++ b/modules/user-constants.el
@@ -55,13 +55,44 @@ mail, chime, etc."
;; ---------------------------- Buffer Status Colors ---------------------------
-(defconst cj/buffer-status-colors
- '((read-only . "#f06a3f") ; red – buffer is read-only
- (overwrite . "#c48702") ; gold – overwrite mode
- (modified . "#64aa0f") ; green – modified & writeable
- (unmodified . "#ffffff")) ; white – unmodified & writeable
- "Alist mapping buffer states to their colors.
-Used by cursor color, modeline, and other UI elements.")
+(defconst cj/buffer-status-faces
+ '((read-only . error) ; can't edit
+ (overwrite . warning) ; overwrite mode
+ (modified . warning) ; writeable, with unsaved changes
+ (unmodified . success)) ; clean and writeable
+ "Alist mapping a buffer state to the theme face whose foreground colors it.
+Shared by the cursor color (ui-config.el) and the modeline buffer-status
+indicator (modeline-config.el) so the two stay in sync and follow the active
+theme, rather than hard-coding hex colors.")
+
+(defun cj/buffer-status-state ()
+ "Return the buffer-state symbol for the current buffer.
+One of `read-only', `overwrite', `modified', or `unmodified' -- the keys of
+`cj/buffer-status-faces'.
+
+A live ghostel terminal (in `ghostel-mode' and an input mode that forwards keys
+-- semi-char / char / line) reports `unmodified' even though the buffer is
+read-only: keystrokes go to the terminal process, so from the user's side it is
+writeable and the read-only state would be misleading. ghostel's `copy' and
+`emacs' input modes are the exception -- there the buffer really is a read-only
+Emacs buffer the user navigates, so it falls through to `read-only'."
+ (cond
+ ((and (eq major-mode 'ghostel-mode)
+ (not (memq (bound-and-true-p ghostel--input-mode) '(copy emacs))))
+ 'unmodified)
+ (buffer-read-only 'read-only)
+ (overwrite-mode 'overwrite)
+ ((buffer-modified-p) 'modified)
+ (t 'unmodified)))
+
+(defun cj/buffer-status-color (state)
+ "Return the foreground color of the theme face mapped to buffer STATE.
+Resolves STATE through `cj/buffer-status-faces' against the active theme. Nil
+when the state is unknown or its face has no concrete foreground (face-attribute
+returns the symbol `unspecified' there), so callers can skip cleanly."
+ (when-let* ((face (alist-get state cj/buffer-status-faces))
+ (fg (face-attribute face :foreground nil t)))
+ (and (stringp fg) fg)))
;; --------------------------- Media File Extensions ---------------------------