]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve SHR/EWW support for 'visual-wrap-prefix-mode'
authorJim Porter <jporterbugs@gmail.com>
Mon, 5 Aug 2024 02:37:00 +0000 (19:37 -0700)
committerEshel Yaron <me@eshelyaron.com>
Tue, 20 Aug 2024 14:12:00 +0000 (16:12 +0200)
* lisp/visual-wrap.el (visual-wrap--apply-to-line): Use
'add-display-text-property' so we don't clobber other display
properties.
(visual-wrap--content-prefix): Remove special-case for spaces-only
indent prefix; this was an attempt to be helpful for variable-pitch
fonts, but in practice just interferes with matters.  This case now
falls back to the one immediately following it (return the string of
spaces).  Use 'string-pixel-width' instead of 'string-width'.

* lisp/net/shr.el (shr-indent): Set 'shr-prefix-length' here to help
keep track of the prefixes of nestedly-indented elements.  Set the
specified space width in terms of the default width of the current face.
* lisp/net/shr.el (shr-adaptive-fill-function): Use 'shr-prefix-length'
as set above to return a fill prefix.

* lisp/net/eww.el (eww-render): Enable 'visual-wrap-prefix-mode'
alongside of 'visual-line-mode'.
(eww-mode): Set 'adaptive-fill-function' to
'shr-adaptive-fill-function'.

* etc/NEWS: Announce this change (bug#72485).

(cherry picked from commit a876c4d7a17df152e3e78800c76ddf158f632ee5)

etc/NEWS
lisp/net/eww.el
lisp/net/shr.el
lisp/visual-wrap.el

index 926f8e2086c416a57389b1f0f7a1d160df59e0c6..82b150e2ebccce53989d5b1398b3815f4932eeab 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -138,6 +138,17 @@ Advanced" node in the EWW manual.
 By customizing 'shr-image-zoom-levels', you can change the list of zoom
 levels that SHR cycles through when calling 'shr-zoom-image'.
 
+** EWW
+
+---
+*** EWW now enables 'visual-wrap-prefix-mode' when 'shr-fill-text' is nil.
+By default, 'shr-fill-text' is t, and EWW fills the text according to
+the width of the window.  If you customize 'shr-fill-text' to nil, EWW
+will now automatically turn on 'visual-wrap-prefix-mode' in addition to
+'visual-line-mode', so that long lines are wrapped at word boundaries
+near window edge and the continuation lines are indented using prefixes
+computed from surrounding context.
+
 ** Go-ts mode
 
 +++
index b2e1c5a72e5ec475f151ea460513faf924f00368..b5d2f20781a7c2efd2ed27cad681c895895be6b1 100644 (file)
@@ -709,7 +709,8 @@ The renaming scheme is performed in accordance with
              (and last-coding-system-used
                   (set-buffer-file-coding-system last-coding-system-used))
               (unless shr-fill-text
-                (visual-line-mode))
+                (visual-line-mode)
+                (visual-wrap-prefix-mode))
              (run-hooks 'eww-after-render-hook)
               ;; Enable undo again so that undo works in text input
               ;; boxes.
@@ -1336,6 +1337,8 @@ within text input fields."
   ;; desktop support
   (setq-local desktop-save-buffer #'eww-desktop-misc-data)
   (setq truncate-lines t)
+  ;; visual-wrap-prefix-mode support
+  (setq-local adaptive-fill-function #'shr-adaptive-fill-function)
   ;; thingatpt support
   (setq-local thing-at-point-provider-alist
               (cons '(url . eww--url-at-point)
index d3c48b344286b190530799c026a8e3c8c98cb97b..b9ac9f0c8c0354989d8359b2e61573107bdd2c2e 100644 (file)
@@ -938,6 +938,11 @@ When `shr-fill-text' is nil, only indent."
         (when (looking-at " $")
          (delete-region (point) (line-end-position)))))))
 
+(defun shr-adaptive-fill-function ()
+  "Return a fill prefix for the paragraph at point."
+  (when-let ((prefix (get-text-property (point) 'shr-prefix-length)))
+    (buffer-substring (point) (+ (point) prefix))))
+
 (defun shr-parse-base (url)
   ;; Always chop off anchors.
   (when (string-match "#.*" url)
@@ -1041,11 +1046,24 @@ When `shr-fill-text' is nil, only indent."
 
 (defun shr-indent ()
   (when (> shr-indentation 0)
-    (if (not shr-use-fonts)
-        (insert-char ?\s shr-indentation)
-      (insert ?\s)
-      (put-text-property (1- (point)) (point)
-                         'display `(space :width (,shr-indentation))))))
+    (let ((start (point))
+          (prefix (or (get-text-property (point) 'shr-prefix-length) 0)))
+      (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))))
+      (put-text-property start (+ (point) prefix)
+                         'shr-prefix-length (+ prefix (- (point) start))))))
 
 (defun shr-fontize-dom (dom &rest types)
   (let ((start (point)))
index 16d330c2a9350cd737788ce240058a8724b3881b..902a9e41c5ee07d0d2343462ddddfbf9e01cbaaf 100644 (file)
@@ -126,10 +126,10 @@ extra indent = 2
         ;; of the line though!  (`fill-match-adaptive-prefix' could
         ;; potentially return a prefix longer than the current line in
         ;; the buffer.)
-        (put-text-property
+        (add-display-text-property
          position (min (+ position (length first-line-prefix))
                        (line-end-position))
-         'display `(min-width ((,next-line-prefix . width)))))
+         'min-width `((,next-line-prefix . width))))
       (setq next-line-prefix (visual-wrap--adjust-prefix next-line-prefix))
       (put-text-property
        position (line-end-position) 'wrap-prefix
@@ -147,12 +147,6 @@ PREFIX was empty."
   (cond
    ((string= prefix "")
     nil)
-   ((string-match (rx bos (+ blank) eos) prefix)
-    ;; If the first-line prefix is all spaces, return its width in
-    ;; characters.  This way, we can set the prefix for all lines to use
-    ;; the canonical-width of the font, which helps for variable-pitch
-    ;; fonts where space characters are usually quite narrow.
-    (string-width prefix))
    ((or (and adaptive-fill-first-line-regexp
              (string-match adaptive-fill-first-line-regexp prefix))
         (and comment-start-skip
@@ -175,7 +169,11 @@ PREFIX was empty."
         (max (string-width prefix)
              (ceiling (string-pixel-width prefix (current-buffer))
                       (aref info 7)))
-      (string-width prefix)))))
+      ;; 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)))))
 
 (defun visual-wrap-fill-context-prefix (beg end)
   "Compute visual wrap prefix from text between BEG and END.