From d618bb4620d5d651027e772b8ccc490e1bab6d80 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 16 May 2026 02:56:25 -0500 Subject: refactor(ui): four UI/navigation hygiene fixes from module-by-module re-review - popper-config.el: move `(popper-mode +1)` and `(popper-echo-mode +1)` from the use-package `:init` block into `:config`. `:disabled t' on use-package skips `:config' but still runs `:init', so the previous shape enabled popper-mode on every load, including batch / test runs, despite the disabled marker. - modeline-config.el: make `cj/modeline-vc-fetch' fall back when the internal `vc-git--symbolic-ref' is missing. `require' uses `nil 'noerror', the call sits inside an `fboundp' guard, and `ignore-errors' wraps the call itself so an Emacs version that renames or removes the accessor leaves `branch' at `vc-working-revision''s output instead of crashing the modeline. - ui-config.el: guard the cursor-color `post-command-hook' behind `(display-graphic-p)' both at install time and inside the function body. Batch / TTY runs short-circuit cleanly with no per-command overhead. A `server-after-make-frame-hook' catches the daemon case where the first GUI frame is created after ui-config loads and installs the hook lazily. Updates test-ui-config--buffer-cursor-state and test-ui-cursor-color-integration to stub `display-graphic-p' so the work body still runs under batch. - nerd-icons-config.el: drop `:demand t' (`:defer t' now), keeping the `:config' advice install as the natural lazy-on-load path. Add a `with-eval-after-load 'nerd-icons' block as a safety net for the already-loaded case on re-eval; the block uses `advice-member-p' so the advice never stacks. --- modules/ui-config.el | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'modules/ui-config.el') diff --git a/modules/ui-config.el b/modules/ui-config.el index 5d3a6643..39b86182 100644 --- a/modules/ui-config.el +++ b/modules/ui-config.el @@ -120,21 +120,36 @@ through to `read-only' and keeps the orange cursor." (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." - ;; 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)) - (set-cursor-color color) - (setq cj/-cursor-last-color color - cj/-cursor-last-buffer (buffer-name)))))) +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." + (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)) + (set-cursor-color color) + (setq cj/-cursor-last-color color + cj/-cursor-last-buffer (buffer-name))))))) ;; Use post-command-hook to update cursor color after every command -;; This ensures cursor color always matches the current buffer's state -(add-hook 'post-command-hook #'cj/set-cursor-color-according-to-mode) +;; This ensures cursor color always matches the current buffer's state. +;; The hook only registers under a graphical session so batch / TTY runs +;; don't pay per-command overhead for a no-op. +(when (display-graphic-p) + (add-hook 'post-command-hook #'cj/set-cursor-color-according-to-mode)) +;; Daemon mode: the first frame may be created after this module loads. +;; Re-attempt the hook install once a GUI frame appears. +(add-hook 'server-after-make-frame-hook + (lambda () + (when (and (display-graphic-p) + (not (memq #'cj/set-cursor-color-according-to-mode + post-command-hook))) + (add-hook 'post-command-hook + #'cj/set-cursor-color-according-to-mode)))) ;; Don’t show a cursor in non-selected windows: (setq cursor-in-non-selected-windows nil) -- cgit v1.2.3