Improve computation of indent depth in SHR and 'visual-wrap-prefix-mode'

Now, we get the average-width of the current font using
'string-pixel-width' and a specified space display spec, which doesn't
require the buffer to be displayed in a window (bug#72771).

* lisp/net/shr.el (shr-indent):
* lisp/visual-wrap.el (visual-wrap--content-prefix): Fix getting the
font when the buffer isn't displayed in a window.
(visual-wrap-fill-context-prefix): Fix indentation.
This commit is contained in:
Jim Porter 2024-08-23 15:11:24 -07:00
parent 3a8222e700
commit 55aad592e1
2 changed files with 18 additions and 24 deletions

View file

@ -1051,17 +1051,17 @@ When `shr-fill-text' is nil, only indent."
(if (not shr-use-fonts)
(insert-char ?\s shr-indentation)
(insert ?\s)
(put-text-property
(1- (point)) (point) 'display
;; Set the specified space width in terms of the default width
;; of the current face, like (N . width). That way, the
;; indentation is calculated correctly when using
;; `text-scale-adjust'.
`(space :width (,(if-let ((font (font-at (1- (point))))
(info (query-font font)))
(/ (float shr-indentation) (aref info 7))
shr-indentation)
. width))))
;; Set the specified space width in units of the average-width
;; of the current font, like (N . width). That way, the
;; indentation is calculated correctly when using
;; `text-scale-adjust'.
(let ((avg-space (propertize (buffer-substring (1- (point)) (point))
'display '(space :width 1))))
(put-text-property
(1- (point)) (point) 'display
`(space :width (,(/ (float shr-indentation)
(string-pixel-width avg-space (current-buffer)))
. width)))))
(put-text-property start (+ (point) prefix)
'shr-prefix-length (+ prefix (- (point) start))))))

View file

@ -160,20 +160,14 @@ PREFIX was empty."
prefix)
(t
;; Otherwise, we want the prefix to be whitespace of the same width
;; as the first-line prefix. If possible, compute the real pixel
;; width of the first-line prefix in canonical-width characters.
;; This is useful if the first-line prefix uses some very-wide
;; characters.
(if-let ((font (font-at position))
(info (query-font font)))
;; as the first-line prefix. We want to return an integer width (in
;; units of the font's average-width) large enough to fit the
;; first-line prefix.
(let ((avg-space (propertize (buffer-substring position (1+ position))
'display '(space :width 1))))
(max (string-width prefix)
(ceiling (string-pixel-width prefix (current-buffer))
(aref info 7)))
;; We couldn't get the font, so we're in a terminal and
;; `string-pixel-width' is really returning the number of columns.
;; (This is different from `string-width', since that doesn't
;; respect specified spaces.)
(string-pixel-width prefix)))))
(string-pixel-width avg-space (current-buffer))))))))
(defun visual-wrap-fill-context-prefix (beg end)
"Compute visual wrap prefix from text between BEG and END.
@ -189,7 +183,7 @@ by `visual-wrap-extra-indent'."
;; make much sense (and is positively harmful in
;; taskpaper-mode where paragraph-start matches everything).
(or (let ((paragraph-start regexp-unmatchable))
(fill-context-prefix beg end))
(fill-context-prefix beg end))
;; Note: fill-context-prefix may return nil; See:
;; http://article.gmane.org/gmane.emacs.devel/156285
""))