From f9226f2dd0cf05fe7ff69bfe1b2cefa516c8c4f5 Mon Sep 17 00:00:00 2001 From: Kévin Le Gouguec Date: Sun, 7 Jan 2024 23:37:00 +0100 Subject: Make Gnus leverage visual-line-mode Set shr-fill-text to nil; this automatically causes eww to enable visual-line-mode. For Gnus, the dance is a bit more involved. Not 100% happy with where I landed, but at least I gave myself an escape hatch by rebinding C-c d v in summary buffers. Also, * lift size restriction when fontifying citations: it mostly only ever causes fontification failures when people review big patches, * tweak header order slightly, * align shr heading faces with eighters-title-* faces. --- .emacs | 6 +++ .emacs.d/eighters-theme.el | 6 +++ .gnus | 95 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 97 insertions(+), 10 deletions(-) diff --git a/.emacs b/.emacs index 18f4de5..b126177 100644 --- a/.emacs +++ b/.emacs @@ -874,6 +874,12 @@ (setq shell-font-lock-keywords nil) (add-hook 'shell-mode-hook 'my/shell-hook)) +(use-package shr + :custom + ;; Prefer visual-line-mode, which refills text automatically when + ;; the window width changes. + (shr-fill-text nil)) + (use-package which-key :custom (which-key-idle-delay 0.5) diff --git a/.emacs.d/eighters-theme.el b/.emacs.d/eighters-theme.el index fbd66e7..6d7c95d 100644 --- a/.emacs.d/eighters-theme.el +++ b/.emacs.d/eighters-theme.el @@ -430,6 +430,12 @@ `(shortdoc-heading ((t (:inherit eighters-title-1)))) `(show-paren-match ((t (:foreground ,fg-cyan :inverse-video t)))) `(show-paren-mismatch ((t (:foreground ,fg-red :inverse-video t)))) + `(shr-h1 ((t (:inherit eighters-title-1)))) + `(shr-h2 ((t (:inherit eighters-title-2)))) + `(shr-h3 ((t (:inherit eighters-title-3)))) + `(shr-h4 ((t (:inherit eighters-title-4)))) + `(shr-h5 ((t (:inherit eighters-title-5)))) + `(shr-h6 ((t (:inherit eighters-title-6)))) `(success ((t (:foreground ,fg-blue :weight bold)))) `(tab-bar ((t (:background ,bg-hl-dimmer :inherit eighters-ui)))) `(tab-bar-tab ((t (:weight bold :box (:style released-button) :inherit tab-bar)))) diff --git a/.gnus b/.gnus index 8472771..37a17af 100644 --- a/.gnus +++ b/.gnus @@ -56,6 +56,7 @@ (t . "%F")) ;; Articles. + gnus-cite-parse-max-size nil gnus-header-face-alist '(("From" nil gnus-header-from) ("Subject" nil gnus-header-subject) @@ -67,20 +68,26 @@ ;; What, when. "^Subject:" "^Summary:" "^Keywords:" "^Date:" ;; Who. - "^From:" "^Followup-To:" "^To:" "^Cc:" "^Newsgroups:" "^Organization:") - gnus-treat-display-smileys nil) + "^From:" "^Organization:" "^Followup-To:" "^To:" "^Cc:" "^Newsgroups:") + gnus-treat-display-smileys nil + ;; Do not fill anything; let visual-line-mode wrap text. + gnus-article-unfold-long-headers t + gnus-treat-fill-article nil + gnus-treat-fill-long-lines nil + gnus-treat-fold-headers nil) + +;;; Summary tweaks. + +(defun my/gnus-toggle-article-wrap () + (interactive) + (with-current-buffer gnus-article-buffer + (visual-line-mode 'toggle))) (add-hook 'gnus-summary-mode-hook (lambda () (setq fill-column 120) - (my/centered-mode))) -(add-hook 'gnus-article-mode-hook - (lambda () - (setq fill-column 80 - my/centered-set-right-margin t) - (my/centered-mode))) - -;;; Summary tweaks. + (my/centered-mode) + (keymap-local-set "C-c d v" 'my/gnus-toggle-article-wrap))) ;; message-subject-re-regexp is used both in Gnus summary buffers to ;; detect and elide similar subjects in a thread, and by message mode @@ -119,6 +126,74 @@ (setq gnus-summary-to-prefix sent-prefix gnus-summary-newsgroup-prefix sent-prefix)) +;;; Article tweaks. + +(defun my/gnus-article-has-html () + (seq-some + (lambda (handle) + (and (listp handle) + (string= (mm-handle-media-type handle) "text/html"))) + gnus-article-mime-handles)) + +(defun my/gnus-article-should-wrap () + (save-excursion + (message-goto-body) + (let ((should-wrap nil) + (has-html (my/gnus-article-has-html))) + (while-let (((not should-wrap)) + ((not (eobp))) + (current-line (thing-at-point 'line))) + (setq should-wrap + (and + ;; The line is bigger than the target width. + (> (length current-line) fill-column) + ;; The line is not boring (citation, diff addition/removal). + (not (string-match-p "\\`[>+-]" current-line)) + ;; Lines that start with spaces are boring, unless this + ;; is an HTML part: those are choked with tags + ;; that shr left-pads with spaces. + ;; NB: HAS-HTML is a naive heuristic: we are assuming + ;; that "any text/html part is present" means "we are + ;; looking at this text/html part". + (or (not (string-match-p "\\` " current-line)) has-html))) + (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. +;; +;; The sequence goes like this: gnus-article-prepare first calls +;; gnus-article-setup-buffer, which +;; +;; (1) sets truncate-lines from gnus-article-truncate-lines, +;; (2) calls gnus-article-mode, which runs gnus-article-mode-hook. +;; +;; 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. +;; +;; 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*. +;; +;; 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) + (when (my/gnus-article-should-wrap) + (visual-line-mode))) + +(add-hook 'gnus-article-prepare-hook 'my/gnus-article-setup) + ;;; Key bindings. ;; ;; m compose -- cgit v1.2.3