summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2024-03-10 23:05:36 +0800
committerJSDurand <mmemmew@gmail.com>2024-03-10 23:05:36 +0800
commitd9795cf25fc383fa06c8e91b4a7859e8cc505a7c (patch)
tree1b2851f10b22713820bfb783e92ea763c53e283e
parent4aaf6977b2785dc2aade1eeb46cc5c72bc76f155 (diff)
modeline: correct alignment
* modeline.el (modeline-format-main, modeline-format-dashboard) (modeline-dashboard-format-left, modeline-dashboard-format-right) (modeline-truncate, modeline-format-buffer-name, modeline-format-vc-mode): Now the mode line catches up with the trend of using string-pixel-width to measure and correctly align strings. Now the mode line will have pixel-level precision of alignment, which is pretty good I guess.
-rw-r--r--modeline.el118
1 files changed, 84 insertions, 34 deletions
diff --git a/modeline.el b/modeline.el
index 52ae9af..49c5f38 100644
--- a/modeline.el
+++ b/modeline.el
@@ -28,16 +28,17 @@
(defun modeline-format-main ()
"The main mode line format."
(let* ((left (modeline-format-left))
- (right (modeline-format-right))
- (left-len (string-width left))
- (right-len (string-width right))
- (middle (propertize " " 'display
- (make-string
- (max (- (window-total-width)
- left-len
- right-len)
- 0)
- 32))))
+ (right (string-trim-right (modeline-format-right)))
+ (left-len (string-pixel-width left))
+ (right-len (string-pixel-width right))
+ (middle (propertize
+ (string 32)
+ 'display
+ (list
+ 'space
+ :width
+ (list
+ (- (window-pixel-width) left-len right-len))))))
(concat left middle right)))
(setq-default mode-line-format '("%e" (:eval (modeline-format-main))))
@@ -46,16 +47,17 @@
(defun modeline-format-dashboard ()
"The mode line format for the dashboard."
(let* ((left (modeline-dashboard-format-left))
- (right (modeline-dashboard-format-right))
- (left-len (length left))
- (right-len (length right))
- (middle (propertize " " 'display
- (make-string
- (max (- (window-total-width)
- left-len
- right-len)
- 0)
- 32))))
+ (right (string-trim-right (modeline-dashboard-format-right)))
+ (left-len (string-pixel-width left))
+ (right-len (string-pixel-width right))
+ (middle (propertize
+ (string 32)
+ 'display
+ (list
+ 'space
+ :width
+ (list
+ (- (window-pixel-width) left-len right-len))))))
(concat left middle right)))
;;;###autoload
@@ -63,7 +65,11 @@
"The left / main part of the mode line for the dashboard."
(concat
(modeline-spc)
- (modeline-format-directory)
+ (modeline-format-buffer-status)
+ (modeline-spc)
+ (modeline-format-buffer-name)
+ (modeline-spc)
+ (modeline-format-keycast)
(modeline-spc)
(modeline-format-minor-modes)))
@@ -76,8 +82,7 @@
('mode-line-inactive))))
(concat
(modeline-propertize
- (format-mode-line global-mode-string face))
- (modeline-spc))))
+ (format-mode-line global-mode-string face)))))
;;;###autoload
(defun modeline-format-left ()
@@ -147,6 +152,54 @@ Characters that take up more than one column will be counted with
str)
(floor len)))
+;;; Correct truncation
+
+(defun modeline-truncate (str limit &optional ellipsis)
+ "Truncate the string STR to no longer than LIMIT columns.
+ELLIPSIS has the same meaning as for `truncate-string-to-width'.
+
+This function calculates widths by `string-pixel-width.'"
+ (setq ellipsis
+ (cond ((or (null ellipsis) (stringp ellipsis)) ellipsis)
+ ((truncate-string-ellipsis))))
+ (let* ((substring-list (string-glyph-split str))
+ (str-len (length str))
+ (str-pixels (string-pixel-width str))
+ (ellipsis-pixels
+ (cond (ellipsis (string-pixel-width ellipsis)) (0)))
+ (column 0)
+ (idx 0)
+ (space-width (string-pixel-width (string #x20)))
+ (limit (* space-width limit))
+ last-column last-idx temp-str)
+ (with-current-buffer (get-buffer-create
+ " *modeline-truncate-to-pixels*")
+ (when (bound-and-true-p display-line-numbers-mode)
+ (display-line-numbers-mode -1))
+ (delete-region (point-min) (point-max))
+ (setq line-prefix nil)
+ (setq wrap-prefix nil)
+ (cond ((and (< limit str-pixels)
+ (< ellipsis-pixels str-pixels))
+ (setq limit (- limit ellipsis-pixels)))
+ ((setq ellipsis (string))))
+ (condition-case nil
+ (while (< column limit)
+ (setq last-column column)
+ (setq last-idx idx)
+ (setq temp-str (nth idx substring-list))
+ (insert (propertize
+ temp-str
+ 'line-prefix nil 'wrap-prefix nil))
+ (setq column (car (buffer-text-pixel-size nil nil t)))
+ (setq idx (+ idx (length temp-str))))
+ (t (setq idx str-len)))
+ (cond
+ ((> column limit)
+ (setq column last-column)
+ (setq idx last-idx)))
+ (concat (substring str 0 idx) ellipsis))))
+
;;; Conveniently add text properties
;;;###autoload
@@ -485,7 +538,7 @@ This will be displayed in the mode line."
(orig (format-mode-line "%b" face)))
(concat
(format-mode-line "%[" face)
- (truncate-string-to-width orig name-max 0 nil ellipsis)
+ (modeline-truncate orig name-max ellipsis)
(format-mode-line "%]" face)))
nil
(concat (buffer-file-name)
@@ -596,16 +649,13 @@ on the mode line."
(cond
((and (stringp modeline-vcs-str)
(not (string= modeline-vcs-str "")))
- (concat
- ;; (modeline-spc)
- (modeline-propertize
- (cond
- ((modeline-active-window-p) modeline-vcs-str)
- (t (propertize modeline-vcs-str 'face 'mode-line-inactive)))
- nil
- (get-text-property 1 'help-echo vc-mode)
- (get-text-property 1 'local-map vc-mode))
- (modeline-spc)))))
+ (modeline-propertize
+ (cond
+ ((modeline-active-window-p) modeline-vcs-str)
+ (t (propertize modeline-vcs-str 'face 'mode-line-inactive)))
+ nil
+ (get-text-property 1 'help-echo vc-mode)
+ (get-text-property 1 'local-map vc-mode)))))
;;;; Input method