branch: elpa/dirvish
commit 8002bb97619fea549d9a74d6a00e1448a1b6b25a
Author: Alex Lu <[email protected]>
Commit: Alex Lu <[email protected]>
fix(core): rewrite mode line composer (#233)
- ensure the mode-line context buffer is alive, closes #233.
- rename dirvish--mode-line-fmt -> dirvish--mode-line-composer
- dirvish-*-ml no longer takes dv as its argument
It's unnecessary for most of the segment and may confuse users who need
define
their own segments.
- compose mode/header line segments at runtime
We may allow changing segments on the fly in the future.
- calculate font scale at runtime
Maybe support text-scale-adjust in the future.
---
dirvish-widgets.el | 1 +
dirvish.el | 84 ++++++++++++++++++++++++----------------------
extensions/dirvish-fd.el | 6 ++--
extensions/dirvish-side.el | 4 +--
4 files changed, 49 insertions(+), 46 deletions(-)
diff --git a/dirvish-widgets.el b/dirvish-widgets.el
index 8672155809..13de8643c5 100644
--- a/dirvish-widgets.el
+++ b/dirvish-widgets.el
@@ -307,6 +307,7 @@ GROUP-TITLES is a list of group titles."
(dirvish-define-mode-line path
"Path of file under the cursor."
(let* ((directory-abbrev-alist nil) ; TODO: support custom
`directory-abbrev-alist'
+ (dv (dirvish-curr))
(index (dired-current-directory))
(face (if (dirvish--window-selected-p dv) 'dired-header 'shadow))
(rmt (dirvish-prop :remote))
diff --git a/dirvish.el b/dirvish.el
index 926074aaa6..b060ff714a 100644
--- a/dirvish.el
+++ b/dirvish.el
@@ -363,7 +363,7 @@ A dirvish preview dispatcher is a function consumed by
"Define a mode line segment NAME with BODY and DOCSTRING."
(declare (indent defun) (doc-string 2))
(let ((ml-name (intern (format "dirvish-%s-ml" name))))
- `(defun ,ml-name (dv) ,docstring (ignore dv) ,@body)))
+ `(defun ,ml-name () ,docstring ,@body)))
;;;; Helpers
@@ -565,8 +565,8 @@ ARGS is a list of keyword arguments for `dirvish' struct."
(when (or m-attr feat-in-lib) (require lib))
(and m-attr (setq attrs (append attrs m-attr))))
finally
- (setf dirvish--mode-line-fmt (dirvish--mode-line-fmt-setter ml-l ml-r))
- (setf dirvish--header-line-fmt (dirvish--mode-line-fmt-setter hl-l hl-r t))
+ (setf dirvish--mode-line-fmt (dirvish--mode-line-composer ml-l ml-r))
+ (setf dirvish--header-line-fmt (dirvish--mode-line-composer hl-l hl-r t))
(setf dirvish--working-preview-dispathchers (dirvish--preview-dps-validate))
(setf dirvish--working-attrs (dirvish--attrs-expand attrs))))
@@ -959,52 +959,54 @@ This attribute is enabled when `dirvish-hide-cursor' is
non-nil."
(let ((ov (make-overlay f-end l-end)))
(overlay-put ov 'invisible t) `(ov . ,ov))))
-(defun dirvish--mode-line-fmt-setter (left right &optional header)
- "Set the `dirvish--mode-line-fmt'.
+(defun dirvish--mode-line-composer (left right &optional header)
+ "Set `dirvish--mode-line-fmt'.
LEFT and RIGHT are segments aligned to left/right respectively.
If HEADER, set the `dirvish--header-line-fmt' instead."
- (cl-labels ((expand (segments)
- (cl-loop for s in segments collect
- (if (stringp s) s
- `(:eval (,(intern (format "dirvish-%s-ml" s))
(dirvish-curr))))))
- (get-font-scale ()
- (let* ((face (if header 'header-line 'mode-line-inactive))
- (default (face-attribute 'default :height))
- (ml-height (face-attribute face :height)))
- (cond ((floatp ml-height) ml-height)
- ((integerp ml-height) (/ (float ml-height) default))
- (t 1)))))
- `((:eval
- (let* ((dv (dirvish-curr))
- (buf (and (car (dv-layout dv)) (cdr (dv-index dv))))
- (scale ,(get-font-scale))
- (win-width (floor (/ (window-width) scale)))
- (str-l (format-mode-line
- ',(or (expand left) mode-line-format) nil nil buf))
- (str-r (format-mode-line ',(expand right) nil nil buf))
- (len-r (string-width str-r)))
- (concat
- (dirvish--bar-image (car (dv-layout dv)) ,header)
- (if (< (+ (string-width str-l) len-r) win-width)
- str-l
- (let ((trim (1- (- win-width len-r))))
- (if (>= trim 0)
- (substring str-l 0 (min trim (1- (length str-l))))
- "")))
- (propertize
- " " 'display
- `((space :align-to (- (+ right right-fringe right-margin)
- ,(ceiling (* scale (string-width str-r)))))))
- str-r))))))
+ `((:eval
+ (let* ((dv (dirvish-curr))
+ (buf (and (car (dv-layout dv)) (cdr (dv-index dv))))
+ (expand
+ (lambda (segs)
+ (cl-loop for s in segs collect
+ (if (stringp s) s
+ `(:eval (,(intern (format "dirvish-%s-ml" s))))))))
+ (face ',(if header 'header-line 'mode-line-inactive))
+ (default (face-attribute 'default :height))
+ (ml-height (face-attribute face :height))
+ (scale (cond ((floatp ml-height) ml-height)
+ ((integerp ml-height) (/ (float ml-height) default))
+ (t 1)))
+ (win-width (floor (/ (window-width) scale)))
+ (str-l "DIRVISH: Context buffer is not a live buffer")
+ (str-r (propertize "WARNING" 'face 'dired-warning))
+ (len-r 7))
+ (when (buffer-live-p buf)
+ (setq str-l (format-mode-line (funcall expand ',left) nil nil buf))
+ (setq str-r (format-mode-line (funcall expand ',right) nil nil buf))
+ (setq len-r (string-width str-r)))
+ (concat
+ (dirvish--bar-image fullframe-p ,header)
+ (if (< (+ (string-width str-l) len-r) win-width)
+ str-l
+ (let ((trim (1- (- win-width len-r))))
+ (if (>= trim 0)
+ (substring str-l 0 (min trim (1- (length str-l))))
+ "")))
+ (propertize
+ " " 'display
+ `((space :align-to (- (+ right right-fringe right-margin)
+ ,(ceiling (* scale (string-width str-r)))))))
+ str-r)))))
;; Thanks to `doom-modeline'.
-(defun dirvish--bar-image (fullscreenp header)
+(defun dirvish--bar-image (fullframe-p header)
"Create a bar image with height of `dirvish-mode-line-height'.
-If FULLSCREENP, use the `cdr' of the value as height, otherwise
+If FULLFRAME-P, use the `cdr' of the value as height, otherwise
use `car'. If HEADER, use `dirvish-header-line-height' instead."
(when (and (display-graphic-p) (image-type-available-p 'pbm))
(let* ((hv (if header dirvish-header-line-height dirvish-mode-line-height))
- (ht (cond ((numberp hv) hv) (fullscreenp (cdr hv)) (t (car hv)))))
+ (ht (cond ((numberp hv) hv) (fullframe-p (cdr hv)) (t (car hv)))))
(propertize
" " 'display
(ignore-errors
diff --git a/extensions/dirvish-fd.el b/extensions/dirvish-fd.el
index 2c5b617efd..933a5a3374 100644
--- a/extensions/dirvish-fd.el
+++ b/extensions/dirvish-fd.el
@@ -75,7 +75,7 @@ should return a list of regular expressions."
(defconst dirvish-fd-bufname "🔍%s📁%s📁%s")
(defconst dirvish-fd-header
- (dirvish--mode-line-fmt-setter '(fd-switches) '(fd-timestamp fd-pwd " ") t))
+ (dirvish--mode-line-composer '(fd-switches) '(fd-timestamp fd-pwd " ") t))
(defvar dirvish-fd-input-history nil "History list of fd input in the
minibuffer.")
(defvar dirvish-fd-debounce-timer nil)
(defvar-local dirvish-fd--output "")
@@ -218,7 +218,7 @@ Raise an error if fd executable is not available."
"Return a formatted string showing the DIRVISH-FD-ACTUAL-SWITCHES."
(pcase-let ((`(,globp ,casep ,ign-range ,types ,exts ,excludes)
(dirvish-prop :fd-arglist))
- (face (if (dirvish--window-selected-p dv)
+ (face (if (dirvish--window-selected-p (dirvish-curr))
'dired-header 'shadow)))
(format " %s | %s"
(propertize "FD" 'face face)
@@ -246,7 +246,7 @@ Raise an error if fd executable is not available."
(dirvish-define-mode-line fd-timestamp
"Timestamp of search finished."
- (when (car (dv-layout dv)) (dirvish-prop :fd-time)))
+ (when (car (dv-layout (dirvish-curr))) (dirvish-prop :fd-time)))
(dirvish-define-mode-line fd-pwd
"Current working directory."
diff --git a/extensions/dirvish-side.el b/extensions/dirvish-side.el
index 024c6f5aa7..96699d9660 100644
--- a/extensions/dirvish-side.el
+++ b/extensions/dirvish-side.el
@@ -56,7 +56,7 @@ If non-nil, expand all the parent directories of current
buffer's
filename until the project root when opening a side session."
:group 'dirvish :type 'boolean)
-(defconst dirvish-side-header (dirvish--mode-line-fmt-setter '(project) nil t))
+(defconst dirvish-side-header (dirvish--mode-line-composer '(project) nil t))
(defun dirvish-side-file-open-fn ()
"Called before opening a file in side sessions."
@@ -145,7 +145,7 @@ filename until the project root when opening a side
session."
(dirvish-define-mode-line project
"Return a string showing current project."
(let ((project (dirvish--get-project-root))
- (face (if (dirvish--window-selected-p dv) 'dired-header 'shadow)))
+ (face (if (dirvish--window-selected-p (dirvish-curr)) 'dired-header
'shadow)))
(if project
(setq project (file-name-base (directory-file-name project)))
(setq project "-"))