Function: rmail-cease-edit
rmail-cease-edit is an interactive and byte-compiled function defined
in rmailedit.el.gz.
Signature
(rmail-cease-edit &optional ABORT)
Documentation
This function has :override advice: hrmail--rmail-cease-edit.
This is an :override advice, which means that rmail-cease-edit isn't
run at all, and the documentation below may be irrelevant.
Finish editing message; switch back to Rmail proper. If ABORT, this is the result of aborting an edit.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/mail/rmailedit.el.gz
(defun rmail-cease-edit (&optional abort)
"Finish editing message; switch back to Rmail proper.
If ABORT, this is the result of aborting an edit."
(interactive)
(if (rmail-summary-exists)
(with-current-buffer rmail-summary-buffer
(rmail-summary-enable)))
(widen)
(goto-char (point-min))
;; This is far from ideal. The edit may have inadvertently
;; removed the blank line at the end of the headers, but there
;; are almost certainly other blank lines.
(or (search-forward "\n\n" nil t)
(error "There must be a blank line at the end of the headers"))
;; Disguise any "From " lines so they don't start a new message.
(goto-char (point-min))
;; This tries to skip the mbox From. FIXME less fragile to go to EOH?
(if (or rmail-old-mime-state
(not rmail-old-pruned))
(forward-line 1))
;; When editing a non-MIME message, rmail-show-message-1 has unescaped
;; ^>*From lines according to rmail-mbox-format. We are editing
;; the message as it was displayed, and need to put the escapes when done.
;; When editing a MIME message, we are editing the "raw" message.
;; ^>*From lines have not been escaped, but we still need to ensure
;; a "^From " line is escaped so as not to break later parsing (?).
;; With ^>+From lines, we have no way of knowing whether the person
;; doing the editing escaped them or not, so it seems best to leave
;; them alone. (This all assumes you are using rmailmm rather than
;; something else that behaves differently.)
(let ((fromline (if (or (eq 'mboxo rmail-mbox-format)
rmail-mime-decoded)
"^From "
"^>*From "))
case-fold-search)
(while (re-search-forward fromline nil t)
(beginning-of-line)
(insert ">")
(forward-line)))
(let ((old rmail-old-text)
(pruned rmail-old-pruned)
(mime-state rmail-old-mime-state)
;; People who know what they are doing might have modified the
;; buffer's encoding if editing the message included inserting
;; characters that were unencodable by the original message's
;; encoding. Make note of the new encoding and use it for
;; encoding the edited message.
(edited-coding buffer-file-coding-system)
new-headers
character-coding is-text-message coding-system
headers-end limit)
;; Make sure `edited-coding' can safely encode the edited message.
(setq edited-coding
(select-safe-coding-system (point-min) (point-max) edited-coding))
;; Go back to Rmail mode, but carefully.
(force-mode-line-update)
(let ((rmail-buffer-swapped nil)) ; Prevent change-major-mode-hook
; from unswapping the buffers.
(kill-all-local-variables)
(rmail-mode-1)
(if (boundp 'tool-bar-map)
(setq-local tool-bar-map rmail-tool-bar-map))
(setq buffer-undo-list t)
(rmail-variables))
;; If text has really changed, mark message as edited.
;; FIXME we should do the comparison before escaping From lines.
(unless (and (= (length old) (- (point-max) (point-min)))
(string= old (buffer-substring (point-min) (point-max))))
(setq old nil)
(goto-char (point-min))
(search-forward "\n\n")
(setq headers-end (point-marker)) ; first character of body
(save-restriction
(narrow-to-region (point-min) headers-end)
;; If they changed the message's encoding, rewrite the charset=
;; header for them, so that subsequent rmail-show-message
;; decodes it correctly.
(let* ((buffer-read-only nil)
(new-coding (coding-system-base edited-coding))
(mime-charset (symbol-name
(or (coding-system-get new-coding :mime-charset)
(if (coding-system-equal new-coding
'undecided)
'us-ascii
new-coding))))
old-coding mime-beg mime-end content-type)
;; If there's no content-type in the edited headers, look for one
;; in the original headers and add it to the edited headers
;; (Bug #26918)
(unless (mail-fetch-field "Content-Type")
(let (old-content-type
(msgbeg (rmail-msgbeg rmail-current-message))
(msgend (rmail-msgend rmail-current-message)))
(with-current-buffer rmail-view-buffer ; really the mbox buffer
(save-restriction
(narrow-to-region msgbeg msgend)
(goto-char (point-min))
(setq limit (search-forward "\n\n"))
(narrow-to-region (point-min) limit)
(goto-char (point-min))
(when (re-search-forward "^content-type:" limit t)
(forward-line)
(setq old-content-type (buffer-substring
(match-beginning 0) (point))))))
(when old-content-type
(save-excursion
(goto-char headers-end) ; first char of body
(backward-char) ; add header before second newline
(insert old-content-type)
;;Add it to rmail-old-headers as though it had been
;;there originally, to avoid rmail-edit-update-headers
;;an extra copy
(let ((header (substring old-content-type 0
(length "content-type"))))
(unless (assoc header rmail-old-headers)
(push (cons header old-content-type) rmail-old-headers)))
))))
(goto-char (point-min))
(if (re-search-forward rmail-mime-charset-pattern nil 'move)
(setq mime-beg (match-beginning 1)
mime-end (match-end 1)
old-coding (coding-system-from-name (match-string 1)))
(setq content-type (mail-fetch-field "Content-Type")))
(cond
;; No match for rmail-mime-charset-pattern, but there was some
;; other Content-Type. We should not insert another. (Bug#4624)
(content-type)
;; Don't insert anything if aborting.
(abort)
((null old-coding)
;; If there was no charset= spec, insert one.
(backward-char 1)
(insert "Content-type: text/plain; charset=" mime-charset "\n"))
((not (coding-system-equal (coding-system-base old-coding)
new-coding))
(goto-char mime-end)
(delete-region mime-beg mime-end)
(insert mime-charset)))))
(setq new-headers (rmail-edit-headers-alist t))
(rmail-swap-buffers-maybe)
(narrow-to-region (rmail-msgbeg rmail-current-message)
(rmail-msgend rmail-current-message))
(goto-char (point-min))
(setq limit (search-forward "\n\n"))
(save-restriction
;; All 3 of the functions we call below assume the buffer was
;; narrowed to just the headers of the message.
(narrow-to-region (point-min) limit)
(setq character-coding
(mail-fetch-field "content-transfer-encoding")
is-text-message (rmail-is-text-p)
coding-system (if (and edited-coding
(not (coding-system-equal
(coding-system-base edited-coding)
'undecided)))
edited-coding
(rmail-get-coding-system))))
(if character-coding
(setq character-coding (downcase character-coding)))
(goto-char limit)
(let ((inhibit-read-only t)
(data-buffer (current-buffer))
(start (copy-marker (point) nil)) ; new body will be between
(end (copy-marker (point) t))) ; these two markers
(if mime-state
;; Message is already in encoded state
(insert-buffer-substring rmail-view-buffer headers-end
(with-current-buffer rmail-view-buffer
(point-max)))
(with-current-buffer rmail-view-buffer
(encode-coding-region headers-end (point-max) coding-system
data-buffer)))
;; Apply to the mbox buffer any changes in header fields
;; that the user made while editing in the view buffer.
(rmail-edit-update-headers (rmail-edit-diff-headers
rmail-old-headers new-headers))
;; Re-apply content-transfer-encoding, if any, on the message body.
(cond
(mime-state) ; if set, already transfer-encoded
((string= character-coding "quoted-printable")
(mail-quote-printable-region start end))
((and (string= character-coding "base64") is-text-message)
(base64-encode-region start end))
((and (eq character-coding 'uuencode) is-text-message)
(error "uuencoded messages are not supported")))
;; After encoding, make sure buffer ends with a blank line so as not to
;; run this message together with the following one.
(goto-char end)
(rmail-ensure-blank-line)
;; Delete previous body. This must be after all insertions at the end,
;; so the marker for the beginning of the next message isn't messed up.
(delete-region end (point-max)))
(rmail-set-attribute rmail-edited-attr-index t)
(if (rmail-summary-exists)
(let ((msgnum rmail-current-message))
(with-current-buffer rmail-summary-buffer
(rmail-summary-update-line msgnum)))))
(rmail-show-message)
(rmail-toggle-header (if pruned 1 0))
;; Restore mime display state.
(and mime-state (rmail-mime nil mime-state)))
(run-hooks 'rmail-mode-hook))