diff options
author | JSDurand <mmemmew@gmail.com> | 2024-03-10 23:05:36 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2024-03-10 23:05:36 +0800 |
commit | d9795cf25fc383fa06c8e91b4a7859e8cc505a7c (patch) | |
tree | 1b2851f10b22713820bfb783e92ea763c53e283e | |
parent | 4aaf6977b2785dc2aade1eeb46cc5c72bc76f155 (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.el | 118 |
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 |