From 0d939f685215232066e8d2af002ef25470e3fc66 Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Fri, 6 May 2016 11:12:23 +0200 Subject: [PATCH 1/6] By default, compose messages as format=flowed Fixes https://github.com/djcb/mu/issues/836 --- mu4e/mu4e-compose.el | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index 96fdb897..7169fe8b 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -143,6 +143,15 @@ Also see `mu4e-context-policy'." :safe 'symbolp :group 'mu4e-compose)) +(defcustom mu4e-compose-format-flowed t + "Whether to compose messages to be sent as format=flowed (or + with long lines if `use-hard-newlines' is set to nil). The + variable `fill-flowed-encode-column' lets you customize the + width beyond which format=flowed lines are wrapped." + :type 'boolean + :safe 'booleanp + :group 'mu4e-compose) + (defcustom mu4e-compose-pre-hook nil "Hook run just *before* message composition starts. If the compose-type is either 'reply' or 'forward', the variable @@ -346,12 +355,24 @@ message-thread by removing the In-Reply-To header." (when mu4e-compose-complete-addresses (mu4e~compose-setup-completion)) + (when mu4e-compose-format-flowed + (turn-off-auto-fill) + (setq truncate-lines nil + word-wrap t + use-hard-newlines t) + ;; Set the marks in the fringes before activating visual-line-mode + (set (make-local-variable 'visual-line-fringe-indicators) + '(left-curly-arrow right-curly-arrow)) + (visual-line-mode t)) + ;; setup the fcc-stuff, if needed (add-hook 'message-send-hook (lambda () ;; mu4e~compose-save-before-sending ;; when in-reply-to was removed, remove references as well. (when (eq mu4e~compose-type 'reply) (mu4e~remove-refs-maybe)) + (when use-hard-newlines + (mu4e-send-harden-newlines)) ;; for safety, always save the draft before sending (set-buffer-modified-p t) (save-buffer) @@ -366,6 +387,13 @@ message-thread by removing the In-Reply-To header." ;; (put 'mu4e~compose-save-before-sending 'permanent-local-hook t) (put 'mu4e~compose-mark-after-sending 'permanent-local-hook t)) +(defun mu4e-send-harden-newlines () + "Set the hard property to all newlines." + (save-excursion + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (put-text-property (1- (point)) (point) 'hard t)))) + (defconst mu4e~compose-buffer-max-name-length 30 "Maximum length of the mu4e-send-buffer-name.") From b6a1e1cef841c01ab287dfc42375b11a399fafbd Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Fri, 6 May 2016 15:53:34 +0200 Subject: [PATCH 2/6] Add a menu entry to toggle format=flowed --- mu4e/mu4e-compose.el | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index 7169fe8b..83e27614 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -326,6 +326,23 @@ message-thread by removing the In-Reply-To header." (define-key map (kbd "C-c C-k") 'mu4e-message-kill-buffer) map))) +(define-key-after + (lookup-key text-mode-map [menu-bar text]) + [mu4e-hard-newlines] + '(menu-item "Format=flowed" mu4e-toggle-use-hard-newlines + :button (:toggle . use-hard-newlines) + :help "Toggle format=flowed" + :visible (eq major-mode 'mu4e-compose-mode)) + 'sep) + +(defun mu4e-toggle-use-hard-newlines () + (interactive) + (setq use-hard-newlines (not use-hard-newlines)) + (if use-hard-newlines + (turn-off-auto-fill) + (turn-on-auto-fill))) + + (defvar mu4e-compose-mode-abbrev-table nil) (define-derived-mode mu4e-compose-mode message-mode "mu4e:compose" "Major mode for the mu4e message composition, derived from `message-mode'. From d2ae534ad823a44ff0b82e926baf815f200dcaa9 Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Sat, 7 May 2016 02:41:04 +0200 Subject: [PATCH 3/6] With use-hard-newlines, M-q reformat the paragraph as a single line --- mu4e/mu4e-compose.el | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index 83e27614..cd032d5d 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -324,8 +324,22 @@ message-thread by removing the In-Reply-To header." (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index) (define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index) (define-key map (kbd "C-c C-k") 'mu4e-message-kill-buffer) + (define-key map (kbd "M-q") 'mu4e-fill-paragraph) map))) +(defun mu4e-fill-paragraph (&optional region) + "If `use-hard-newlines', takes a multi-line paragraph and makes +it into a single line of text. Assume paragraphs are separated +by blank lines. If `use-hard-newlines' is not enabled, this +simply executes `fill-paragraph'." + ;; Inspired by https://www.emacswiki.org/emacs/UnfillParagraph + (interactive (progn (barf-if-buffer-read-only) '(t))) + (if use-hard-newlines + (let ((fill-column (point-max)) + (use-hard-newlines nil)); rfill "across" hard newlines + (fill-paragraph nil region)) + (fill-paragraph nil region))) + (define-key-after (lookup-key text-mode-map [menu-bar text]) [mu4e-hard-newlines] From 55a95db3f0f7794cb747c8f48d51e2dd4c24fbb9 Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Sat, 7 May 2016 02:47:13 +0200 Subject: [PATCH 4/6] Update the manual about composing format=flowed messages --- mu4e/mu4e.texi | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index e5727d52..cd26ab25 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -3840,21 +3840,19 @@ don't have it, your mails mostly look quite bad especially on mobile devices) and here's the RFC with all the details: @url{http://www.ietf.org/rfc/rfc2646.txt}. -To add this to outgoing mu4e emails, activate @t{use-hard-newlines} and -use only @t{M-q} or @t{fill-paragraph} for your paragraphs, Emacs -indicates intra-paragraph breaks with soft newlines and inter-paragraph -breaks with hard newlines. When the Gnus code sees these on outgoing -emails, it automatically sets @t{format=flowed}. +Since version 0.9.17, @t{mu4e} send emails with @t{format=flowed} by +default. The transformation of your message into the proper format is +done at the time of sending. In order to happen properly, you should +write each paragraph of your message of as a long line (i.e. without +carriage return). If you introduce unwanted newlines in your paragraph, +use @kbd{M-q} to reformat it as a single line. -To enable this, you can use something like this in your init.el: +If you want to send the message with long lines but without +@t{format=flowed} (because, say, the receiver does not understand it as +it is the case for Google or Github), use @kbd{M-x use-hard-newlines} or +uncheck the box @t{format=flowed} in the @t{Text} menu when composing a +message. -@lisp -;; tip submitted by mu4e user cpbotha -(add-hook 'mu4e-compose-mode-hook - (defun cpb-compose-setup () - "Outgoing mails get format=flowed." - (use-hard-newlines t 'guess))) -@end lisp @end enumerate @node Known issues From af523cd05a0527564943618992965eae676c82c5 Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Sat, 7 May 2016 03:16:38 +0200 Subject: [PATCH 5/6] Add the menu entry in the function defining the mode This ensures that `(lookup-key message-mode-map [menu-bar text])' returns a valid keymap. --- mu4e/mu4e-compose.el | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index cd032d5d..3998b3f3 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -340,15 +340,6 @@ simply executes `fill-paragraph'." (fill-paragraph nil region)) (fill-paragraph nil region))) -(define-key-after - (lookup-key text-mode-map [menu-bar text]) - [mu4e-hard-newlines] - '(menu-item "Format=flowed" mu4e-toggle-use-hard-newlines - :button (:toggle . use-hard-newlines) - :help "Toggle format=flowed" - :visible (eq major-mode 'mu4e-compose-mode)) - 'sep) - (defun mu4e-toggle-use-hard-newlines () (interactive) (setq use-hard-newlines (not use-hard-newlines)) @@ -396,6 +387,15 @@ simply executes `fill-paragraph'." '(left-curly-arrow right-curly-arrow)) (visual-line-mode t)) + (define-key-after + (lookup-key message-mode-map [menu-bar text]) + [mu4e-hard-newlines] + '(menu-item "Format=flowed" mu4e-toggle-use-hard-newlines + :button (:toggle . use-hard-newlines) + :help "Toggle format=flowed" + :visible (eq major-mode 'mu4e-compose-mode)) + 'sep) + ;; setup the fcc-stuff, if needed (add-hook 'message-send-hook (lambda () ;; mu4e~compose-save-before-sending From d063889e4c4d5d3caa891d88fad25a660c54d2f1 Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Sat, 7 May 2016 13:12:11 +0200 Subject: [PATCH 6/6] Set mu4e-compose-format-flowed to nil by default Requested by Dirk-Jan C. Binnema not to disturb existing users. --- mu4e/mu4e-compose.el | 7 ++++--- mu4e/mu4e.texi | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index 3998b3f3..963aef69 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -143,7 +143,7 @@ Also see `mu4e-context-policy'." :safe 'symbolp :group 'mu4e-compose)) -(defcustom mu4e-compose-format-flowed t +(defcustom mu4e-compose-format-flowed nil "Whether to compose messages to be sent as format=flowed (or with long lines if `use-hard-newlines' is set to nil). The variable `fill-flowed-encode-column' lets you customize the @@ -334,7 +334,7 @@ by blank lines. If `use-hard-newlines' is not enabled, this simply executes `fill-paragraph'." ;; Inspired by https://www.emacswiki.org/emacs/UnfillParagraph (interactive (progn (barf-if-buffer-read-only) '(t))) - (if use-hard-newlines + (if mu4e-compose-format-flowed (let ((fill-column (point-max)) (use-hard-newlines nil)); rfill "across" hard newlines (fill-paragraph nil region)) @@ -393,7 +393,8 @@ simply executes `fill-paragraph'." '(menu-item "Format=flowed" mu4e-toggle-use-hard-newlines :button (:toggle . use-hard-newlines) :help "Toggle format=flowed" - :visible (eq major-mode 'mu4e-compose-mode)) + :visible (eq major-mode 'mu4e-compose-mode) + :enable mu4e-compose-format-flowed) 'sep) ;; setup the fcc-stuff, if needed diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index cd26ab25..4ce797fd 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -3841,15 +3841,23 @@ devices) and here's the RFC with all the details: @url{http://www.ietf.org/rfc/rfc2646.txt}. Since version 0.9.17, @t{mu4e} send emails with @t{format=flowed} by -default. The transformation of your message into the proper format is +setting + +@lisp +(setq mu4e-compose-format-flowed t) +@end lisp + +in your Emacs init file (@file{~/.emacs} or @file{~/.emacs.d/init.el}). +The transformation of your message into the proper format is done at the time of sending. In order to happen properly, you should write each paragraph of your message of as a long line (i.e. without carriage return). If you introduce unwanted newlines in your paragraph, use @kbd{M-q} to reformat it as a single line. -If you want to send the message with long lines but without -@t{format=flowed} (because, say, the receiver does not understand it as -it is the case for Google or Github), use @kbd{M-x use-hard-newlines} or +If you want to send the message with paragraphs on single lines but +without @t{format=flowed} (because, say, the receiver does not +understand the latter as it is the case for Google or Github), use +@kbd{M-x use-hard-newlines} (to turn @code{use-hard-newlines} off) or uncheck the box @t{format=flowed} in the @t{Text} menu when composing a message.