Skip to content

Commit

Permalink
Add another hook to "live encode" format=flow
Browse files Browse the repository at this point in the history
  • Loading branch information
wberrier committed Oct 19, 2018
1 parent ef87972 commit 335a14d
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,23 @@ then add the following to your =.emacs= file:
(add-hook 'message-mode-hook 'messages-are-flowing-use-and-mark-hard-newlines)
#+END_SRC

This package also supports inserting spaces for soft newlines via the
following:

#+BEGIN_SRC emacs-lisp
(add-hook 'message-mode-hook 'messages-are-flowing-enhance-fill-newline)
#+END_SRC

NOTE: the modes need to be specified when to use the enhanced
fill-newline:

#+BEGIN_SRC emacs-lisp
(use-package messages-are-flowing
:custom (messages-are-flowing-enhance-fill-newline-modes 'message-mode)
)
#+END_SRC

This can be useful if using a mailer that does not post-encode the
text (ie: mutt).

#+STARTUP: showall
74 changes: 74 additions & 0 deletions messages-are-flowing.el
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@
;;
;; (with-eval-after-load "message"
;; (add-hook 'message-mode-hook 'messages-are-flowing-use-and-mark-hard-newlines))
;;
;; If your mail program does not encode the flowed format, the following
;; can be used to convert soft newlines to spaces:
;;
;; (add-hook 'message-mode-hook 'messages-are-flowing-enhance-fill-newline)
;;
;; Also note that messages-are-flowing-enhance-fill-newline-modes will need to
;; be set with the modes the enhanced fill-newline should be used in

;;; Code:

Expand All @@ -55,6 +63,23 @@ device, such that messages remain readable on narrow displays."
(use-hard-newlines)
(add-hook 'after-change-functions 'messages-are-flowing--mark-hard-newlines nil t))

;;;###autoload
(defun messages-are-flowing-enhance-fill-newline ()
"Function to enhance fill-newline, only for certain modes"
(advice-add 'fill-newline :around #'messages-are-flowing--fill-newline-wrapper)
(turn-off-auto-fill)
)

(defgroup messages-are-flowing nil
"Utilities for working with format=flowed messages"
)

(defcustom messages-are-flowing-enhance-fill-newline-modes nil
"Modes to apply to when messages-are-flowing-enhance-fille-newline is in use"
:type 'function
:group 'messages-are-flowing)


(defun messages-are-flowing--mark-hard-newlines (beg end &rest _ignore)
"Visibly mark hard newlines between BEG and END.
For each hard newline, add a display property that makes it visible.
Expand All @@ -70,5 +95,54 @@ For each soft newline, remove any display property."
(add-text-properties pos (1+ pos) (list 'display (copy-sequence "\n")))
(remove-text-properties pos (1+ pos) '(display nil)))))))


;; fill-newline that puts a space for soft newlines
;; Based on https://emacs.stackexchange.com/questions/19296/retooling-fill-paragraph-to-append-trailing-spaces
(defun messages-are-flowing--fill-newline ()
"Custom version of fill-newline to behave 3676ishly"

;; Replace whitespace here with one newline, then
;; indent to left margin.
(skip-chars-backward " \t")
(insert ?\s)
(insert ?\n)
;; Give newline the properties of the space(s) it replaces
(set-text-properties (1- (point)) (point)
(fill-text-properties-at (point)))
(and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
(or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
(match-end 2))
;; When refilling later on, this newline would normally not be replaced
;; by a space, so we need to mark it specially to re-install the space
;; when we unfill.
(put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
;; If we don't want breaks in invisible text, don't insert
;; an invisible newline.
(if fill-nobreak-invisible
(remove-text-properties (1- (point)) (point)
'(invisible t)))
(if (or fill-prefix
(not fill-indent-according-to-mode))
(fill-indent-to-left-margin)
(indent-according-to-mode))
;; Insert the fill prefix after indentation.
(and fill-prefix (not (equal fill-prefix ""))
;; Markers that were after the whitespace are now at point: insert
;; before them so they don't get stuck before the prefix.
(insert-before-markers-and-inherit fill-prefix)))

(defun messages-are-flowing--fill-newline-wrapper (orig-fun &rest args)
"Call [messages-are-flowing--]fill-newline depending on mode"

;; NOTE: this is done so that it doesn't affect other modes
(if (equal major-mode messages-are-flowing-enhance-fill-newline-modes)
(progn ;; allow multiple statements
;; Alter fill-newline
(messages-are-flowing--fill-newline)
)
(apply orig-fun args)
)
)

(provide 'messages-are-flowing)
;;; messages-are-flowing.el ends here

0 comments on commit 335a14d

Please sign in to comment.