Skip to content

Instantly share code, notes, and snippets.

@salewski
Created January 15, 2021 17:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save salewski/b518e644daee18522f2820fad9a66162 to your computer and use it in GitHub Desktop.
Save salewski/b518e644daee18522f2820fad9a66162 to your computer and use it in GitHub Desktop.
emacs: fill.el tweaks to support format=flowed in fill-paragraph
;;; This Gist by Alan D. Salewski <ads@salewski.email>, based on
;;; the 'fill.el' file from GNU Emacs 26.1 as shipped by Debian in
;;; the 'emacs25-lucid' package, version 1:26.1+1-3.2+deb10u1. The
;;; copyright statement from the original file has been preserved below.
;;;
;;; The intent is that this Gist could serve as the starting point
;;; for a proper patch, once I have more time to put such a thing
;;; together.
;;;
;;; Changes here include:
;;;
;;; 1. Introduce a new 'fill-paragraph-flowed-enabled' buffer-local
;;; variable. It defaults to nil, which means the other changes
;;; introduced here have no effect unless specifically requested
;;; in a given buffer.
;;;
;;; 2. Adjust `fill-newline' to honor the above var, and insert a
;;; space character prior to the newline when filling a para.
;;;
;;; To manually enable this in an existing buffer:
;;;
;;; (with-current-buffer "YOUR-BUFFER-NAME"
;;; (setq fill-paragraph-flowed-enabled t))
;;;
;;; To enable this automatically when editing email messages (assuming
;;; you use `message-mode' for such editing):
;;;
;;; (add-hook 'message-mode-hook
;;; (lambda ()
;;; (setq fill-paragraph-flowed-enabled t)))
;;;
;;; fill.el --- fill commands for Emacs
;; Copyright (C) 1985-1986, 1992, 1994-1997, 1999, 2001-2018 Free
;; Software Foundation, Inc.
;; Maintainer: emacs-devel@gnu.org
;; Keywords: wp
;; Package: emacs
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; All the commands for filling text. These are documented in the Emacs
;; manual.
;;; Code:
;;; ...
(defvar fill-paragraph-flowed-enabled nil
"When non-nil, `fill-paragraph' will use \"soft line breaks\"
when filling paragraph text. The definition of this format comes
from RFC 3676, \"The Text/Plain Format and DelSp Parameters\",
and is often referred to as \"format=flowed\" (sometimes
abbreviated to just \"f=f\"), after the MIME parameter and value
used to declare it in the \"Text/Plain\" Media Type.
A \"soft\" line break consists of an ASCII space character
followed by a newline on all lines of a paragraph except for the
last. Such text is called \"flowed\".
The primary use of such text is in modes that involved with
editing email and Usenet messages, but may be useful anywhere
Text/Plain messages are used. The intent is to help avoid what
RFC 3676 (section 3.2) calls \"embarrassing line wrap\" when text
is displayed on different size displays.
Software that supports flowed text may interpret the soft line
breaks as places where the running paragraph text can be
re-flowed (or re-wrapped) to adjust it for a particular size
display. Software that does not support flowed text
will (presumably) simply display it \"as is\". This allows, for
example, messages to be composed for display on a desktop or
laptop computer screen, but also display nicely on a (typically
much smaller) mobile device screen.
Note that encoding paragraphs with flowed is only one part of
implmenting \"format=flowed\", and the only part handled by
`fill-paragraph' when this variable is non-nil. Users wishing to
send \"format=flowed\" email messages will need to take
additional action to configure their mailer to perform
\"space-stuffing\" and set the \"Content-Type:\" header
correctly. See your mailer manual for details.")
(make-variable-buffer-local 'fill-paragraph-flowed-enabled)
(defun fill-newline ()
;; Replace whitespace here with one newline, then
;; indent to left margin.
(skip-chars-backward " \t")
;; ALJUNK new go
(when fill-paragraph-flowed-enabled
(insert ?\s)
;; Give our newly inserted SPC the properties of the existing space(s) that will be replaced
(set-text-properties (1- (point)) (point)
(fill-text-properties-at (point))))
;; ALJUNK new end
(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)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment