diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/modeline-config.el | 7 | ||||
| -rw-r--r-- | modules/ui-config.el | 57 | ||||
| -rw-r--r-- | modules/user-constants.el | 45 |
3 files changed, 57 insertions, 52 deletions
diff --git a/modules/modeline-config.el b/modules/modeline-config.el index 21ecd7e47..f6b8ef4eb 100644 --- a/modules/modeline-config.el +++ b/modules/modeline-config.el @@ -75,12 +75,7 @@ Example: `my-very-long-name.el' → `my-ver...me.el'" ;; -------------------------- Modeline Segments -------------------------------- (defvar-local cj/modeline-buffer-name - '(:eval (let* ((state (cond - (buffer-read-only 'read-only) - (overwrite-mode 'overwrite) - ((buffer-modified-p) 'modified) - (t 'unmodified))) - (color (alist-get state cj/buffer-status-colors)) + '(:eval (let* ((color (cj/buffer-status-color (cj/buffer-status-state))) (name (buffer-name)) (truncated-name (cj/modeline-string-cut-middle name))) (propertize truncated-name diff --git a/modules/ui-config.el b/modules/ui-config.el index 7afe528b2..86670b29d 100644 --- a/modules/ui-config.el +++ b/modules/ui-config.el @@ -94,53 +94,32 @@ When `cj/enable-transparency' is nil, reset alpha to fully opaque." (if cj/enable-transparency "enabled" "disabled"))) ;; ----------------------------------- Cursor ---------------------------------- -;; set cursor color according to mode -;; -;; #f06a3f indicates a read-only document -;; #c48702 indicates overwrite mode -;; #64aa0f indicates insert and read/write mode +;; Set the cursor color from the active theme's faces according to buffer state. +;; The state classifier and the state->face map live in user-constants.el +;; (cj/buffer-status-state / cj/buffer-status-faces, colored via the theme's +;; error / warning / success faces) and are shared with the modeline buffer-name +;; indicator, so the cursor and the modeline stay in sync. (defvar cj/-cursor-last-color nil "Last color applied by `cj/set-cursor-color-according-to-mode'.") (defvar cj/-cursor-last-buffer nil "Last buffer name where cursor color was applied.") -(defun cj/--buffer-cursor-state () - "Return the buffer-state symbol used to choose the cursor color. - -One of `read-only', `overwrite', `modified', or `unmodified' — keys -of `cj/buffer-status-colors'. - -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 the buffer is writeable and the read-only -(orange) cursor 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' -and keeps the orange cursor." - (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/set-cursor-color-according-to-mode () - "Change cursor color according to buffer state (modified, read-only, overwrite). -Only updates for real user buffers, not internal/temporary buffers. -A no-op on non-graphical frames -- TTY/batch sessions have no cursor color -to set." + "Set the cursor color from the active theme according to buffer state. +The state and its theme face come from `cj/buffer-status-state' and +`cj/buffer-status-color' (shared with the modeline), so the color follows the +loaded theme. Only updates real user buffers, not internal/temporary ones; a +no-op on non-graphical frames -- TTY/batch sessions have no cursor color to set." (when (display-graphic-p) - ;; Only update cursor for real buffers (not internal ones like *temp*, *Echo Area*, etc.) - (unless (string-prefix-p " " (buffer-name)) ; Internal buffers start with space - (let ((color (alist-get (cj/--buffer-cursor-state) cj/buffer-status-colors))) - ;; Only skip if BOTH color AND buffer are the same (optimization) - ;; This allows color to update when buffer state changes - (unless (and (string= color cj/-cursor-last-color) - (string= (buffer-name) cj/-cursor-last-buffer)) + ;; Only update cursor for real buffers (not internal ones like *temp*, *Echo Area*). + (unless (string-prefix-p " " (buffer-name)) ; internal buffers start with a space + (let ((color (cj/buffer-status-color (cj/buffer-status-state)))) + ;; Skip only when BOTH color and buffer are unchanged (so the color still + ;; updates when the buffer state changes). + (when (and color + (not (and (equal color cj/-cursor-last-color) + (equal (buffer-name) cj/-cursor-last-buffer)))) (set-cursor-color color) (setq cj/-cursor-last-color color cj/-cursor-last-buffer (buffer-name))))))) 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 --------------------------- |
