aboutsummaryrefslogtreecommitdiff
path: root/modules/modeline-config.el
diff options
context:
space:
mode:
Diffstat (limited to 'modules/modeline-config.el')
-rw-r--r--modules/modeline-config.el80
1 files changed, 40 insertions, 40 deletions
diff --git a/modules/modeline-config.el b/modules/modeline-config.el
index 0e6e5d0fb..61dcb69c6 100644
--- a/modules/modeline-config.el
+++ b/modules/modeline-config.el
@@ -15,7 +15,6 @@
;; No external packages = no buffer issues, no native-comp errors.
;; Features:
-;; - Buffer status (modified, read-only)
;; - Buffer name
;; - Major mode
;; - Version control status
@@ -72,30 +71,29 @@ Example: `my-very-long-name.el' → `my-ver...me.el'"
(concat (substring str 0 half) "..." (substring str (- half))))
str))
+(defun cj/--modeline-click-map (mouse-1 &optional mouse-3)
+ "Return a mode-line `local-map' binding mouse clicks to commands.
+\[mode-line mouse-1] runs MOUSE-1; when MOUSE-3 is non-nil, [mode-line mouse-3]
+runs it too. Shared builder for the clickable modeline segments."
+ (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1] mouse-1)
+ (when mouse-3
+ (define-key map [mode-line mouse-3] mouse-3))
+ map))
+
;; -------------------------- 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))
- (name (buffer-name))
+ '(:eval (let* ((name (buffer-name))
(truncated-name (cj/modeline-string-cut-middle name)))
(propertize truncated-name
- 'face `(:foreground ,color)
'mouse-face 'mode-line-highlight
'help-echo (concat
name "\n"
(or (buffer-file-name)
(format "No file. Directory: %s" default-directory)))
- 'local-map (let ((map (make-sparse-keymap)))
- (define-key map [mode-line mouse-1] 'previous-buffer)
- (define-key map [mode-line mouse-3] 'next-buffer)
- map))))
- "Buffer name colored by modification and read-only status.
-White = unmodified, Green = modified, Red = read-only, Gold = overwrite.
+ 'local-map (cj/--modeline-click-map 'previous-buffer 'next-buffer))))
+ "Buffer name in the mode line.
Truncates in narrow windows. Click to switch buffers.")
(defvar-local cj/modeline-position
@@ -137,12 +135,12 @@ Uses built-in cached values for performance.")
cj/modeline-vc-cache-set-p nil))
(defun cj/modeline-vc-cache-key (file)
- "Return the cache key for FILE.
-Includes the resolved `file-truename' so that if FILE is a symlink whose
-target moves to a different VC tree, the key changes and the cache is not
-served a stale backend. The extra `file-truename' is one stat per refresh,
-cheap next to the VC calls the cache avoids."
- (list file (file-truename file) cj/modeline-vc-show-remote))
+ "Return the cache key for FILE: the file path and `cj/modeline-vc-show-remote'.
+`file-truename' is deliberately omitted -- the mode-line rebuilds this key on
+every render to check cache validity, so a stat here would run per redisplay.
+A symlink whose target moves to a different VC tree is picked up at the next
+TTL refresh, when `vc-backend' resolves the link fresh."
+ (list file cj/modeline-vc-show-remote))
(defun cj/modeline-vc-cache-valid-p (key now)
"Return non-nil when cached VC data is valid for KEY at NOW."
@@ -157,18 +155,25 @@ Return a plist with `:branch' and `:state', or nil when FILE has no VC data.
Uses `vc-git--symbolic-ref' for branch names when available (it returns the
symbolic ref like \"main\" instead of a SHA when HEAD is on a branch), but
falls back to `vc-working-revision' if the internal accessor is missing --
-the symbol is internal and can be renamed or removed between Emacs versions."
- (unless (and (file-remote-p file) (not cj/modeline-vc-show-remote))
- (when-let* ((backend (vc-backend file))
- (branch (vc-working-revision file backend)))
- (when (eq backend 'Git)
- (unless (fboundp 'vc-git--symbolic-ref)
- (require 'vc-git nil 'noerror))
- (when (fboundp 'vc-git--symbolic-ref)
- (when-let* ((symbolic (ignore-errors (vc-git--symbolic-ref file))))
- (setq branch symbolic))))
- (list :branch branch
- :state (vc-state file backend)))))
+the symbol is internal and can be renamed or removed between Emacs versions.
+
+The whole VC probe is wrapped in `condition-case' returning nil. These are
+synchronous git calls that, on TTL expiry, run while the mode-line is built;
+on a slow or unmounted filesystem a signal here would land in redisplay and
+break it. Caching nil degrades to \"no VC info\" instead."
+ (condition-case nil
+ (unless (and (file-remote-p file) (not cj/modeline-vc-show-remote))
+ (when-let* ((backend (vc-backend file))
+ (branch (vc-working-revision file backend)))
+ (when (eq backend 'Git)
+ (unless (fboundp 'vc-git--symbolic-ref)
+ (require 'vc-git nil 'noerror))
+ (when (fboundp 'vc-git--symbolic-ref)
+ (when-let* ((symbolic (ignore-errors (vc-git--symbolic-ref file))))
+ (setq branch symbolic))))
+ (list :branch branch
+ :state (vc-state file backend))))
+ (error nil)))
(defun cj/modeline-vc-info ()
"Return cached modeline VC data for the current buffer."
@@ -197,10 +202,7 @@ the symbol is internal and can be renamed or removed between Emacs versions."
'face face
'mouse-face 'mode-line-highlight
'help-echo (format "Branch: %s\nState: %s\nmouse-1: vc-diff\nmouse-3: vc-root-diff" branch state)
- 'local-map (let ((map (make-sparse-keymap)))
- (define-key map [mode-line mouse-1] 'vc-diff)
- (define-key map [mode-line mouse-3] 'vc-root-diff)
- map))))))
+ 'local-map (cj/--modeline-click-map 'vc-diff 'vc-root-diff))))))
(defvar-local cj/modeline-vc-branch
'(:eval (when (mode-line-window-selected-p) ; Only show in active window
@@ -217,9 +219,7 @@ Click to show diffs with `vc-diff' or `vc-root-diff'.")
'help-echo (if-let* ((parent (get mode-sym 'derived-mode-parent)))
(format "Major mode: %s\nDerived from: %s\nmouse-1: describe-mode" mode-sym parent)
(format "Major mode: %s\nmouse-1: describe-mode" mode-sym))
- 'local-map (let ((map (make-sparse-keymap)))
- (define-key map [mode-line mouse-1] 'describe-mode)
- map))))
+ 'local-map (cj/--modeline-click-map 'describe-mode))))
"Major mode name only (no minor modes).
Click to show help with `describe-mode'.")