summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gnus74
1 files changed, 46 insertions, 28 deletions
diff --git a/.gnus b/.gnus
index 056a1c6..c24734e 100644
--- a/.gnus
+++ b/.gnus
@@ -128,6 +128,27 @@
;;; Article tweaks.
+(defun my/gnus-article-center ()
+ (setq fill-column 80
+ my/centered-set-right-margin t)
+ (my/centered-mode))
+
+(defun my/gnus-article-eschew-tables ()
+ ;; I set shr-fill-text to nil because I prefer letting
+ ;; visual-line-mode manage wrapping. Unfortunately, many HTML
+ ;; emails rely on <table>s for layouts, and rendering can get ugly.
+ ;; Work around this by treating <table> & children as any other
+ ;; <div>.
+ (make-local-variable 'shr-external-rendering-functions)
+ (pcase-dolist (`(,tag . ,shr-function)
+ '((table . shr-tag-div)
+ (thead . shr-tag-div)
+ (tbody . shr-tag-div)
+ (tr . shr-tag-ul)
+ (th . shr-tag-li)
+ (td . shr-tag-li)))
+ (setf (alist-get tag shr-external-rendering-functions) shr-function)))
+
(defun my/gnus-article-has-html ()
(seq-some
(lambda (handle)
@@ -159,40 +180,37 @@
(forward-line))
should-wrap)))
-;; Keep article buffer centered; enable visual-line-mode when it helps
-;; (long lines that are not part of citations nor patches).
-;;
-;; Use article-prepare hook instead of article-mode hook to ensure
-;; visual-line-mode will be set and effectively clear truncate-lines.
+(defun my/gnus-article-wrap-maybe ()
+ ;; Enable visual-line-mode when it helps, i.e. when the message has
+ ;; long lines that are not part of citations nor patches.
+ (visual-line-mode
+ (unless (my/gnus-article-should-wrap) -1)))
+
+;; Article setup is tricky. In order, `gnus-article-prepare'
;;
-;; The sequence goes like this: gnus-article-prepare first calls
-;; gnus-article-setup-buffer, which
+;; (1) calls `gnus-article-setup-buffer', which
+;; (a) calls `gnus-article-mode', which runs
+;; gnus-article-mode-hook,
+;; (b) sets truncate-lines from gnus-article-truncate-lines,
;;
-;; (1) sets truncate-lines from gnus-article-truncate-lines,
-;; (2) calls gnus-article-mode, which runs gnus-article-mode-hook.
+;; (2) calls `gnus-display-mime', which may end up calling `mm-shr';
+;; this can call `shr-tag-table', which turns truncate-lines on
+;; unconditionally.
;;
-;; But then gnus-article-prepare calls gnus-display-mime, which may
-;; end up calling mm-shr, which *might* end up calling shr-tag-table,
-;; which unconditionally turns truncate-lines back on.
+;; (3) runs gnus-article-prepare-hook.
;;
-;; Then gnus-article-prepare runs gnus-article-prepare-hook: that's
-;; our cue to run visual-line-mode, which will set truncate-lines back
-;; *off*.
+;; Gnus will only run (1a) once, and skip that step when it re-uses
+;; the same *Article* buffer for subsequent articles. So for our
+;; purposes, we need to
;;
-;; eww does not have this problem because it checks shr-fill-text &
-;; turns visual-line-mode "late enough"; though the display of tables
-;; remains less than ideal since rows are wrapped. Ideally
-;; shr-tag-table should switch to an alternative layout when
-;; shr-fill-text is nil.
-
-(defun my/gnus-article-setup ()
- (setq fill-column 80
- my/centered-set-right-margin t)
- (my/centered-mode)
- (visual-line-mode
- (unless (my/gnus-article-should-wrap) -1)))
+;; (Ⅰ) hack the shr rendering functions in mode-hook, before `mm-shr'
+;; gets to work.
+;; (Ⅱ) call `visual-line-mode' (if needed) in prepare-hook, after
+;; truncate-lines has been set.
-(add-hook 'gnus-article-prepare-hook 'my/gnus-article-setup)
+(add-hook 'gnus-article-mode-hook 'my/gnus-article-center)
+(add-hook 'gnus-article-mode-hook 'my/gnus-article-eschew-tables)
+(add-hook 'gnus-article-prepare-hook 'my/gnus-article-wrap-maybe)
;;; Key bindings.
;;