X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/1945c7a74c82d7e41af182ffae066642d51baaab..ff4abce949adc72b6a55ee648945542027625573:/lisp/mail/rmailedit.el diff --git a/lisp/mail/rmailedit.el b/lisp/mail/rmailedit.el index 40d5f02489..46c1ab6e03 100644 --- a/lisp/mail/rmailedit.el +++ b/lisp/mail/rmailedit.el @@ -136,9 +136,18 @@ This functions runs the normal hook `rmail-edit-mode-hook'. (insert "\n"))) (let ((old rmail-old-text) (pruned rmail-old-pruned) + ;; 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 @@ -154,6 +163,33 @@ This functions runs the normal hook `rmail-edit-mode-hook'. (string= old (buffer-substring (point-min) (point-max)))) (setq old nil) (goto-char (point-min)) + ;; 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)) + old-coding mime-charset mime-beg mime-end) + (when (re-search-forward rmail-mime-charset-pattern + (1- (save-excursion (search-forward "\n\n"))) + 'move) + (setq mime-beg (match-beginning 1) + mime-end (match-end 1) + old-coding (coding-system-from-name (match-string 1)))) + (setq mime-charset + (symbol-name + (or (coding-system-get new-coding :mime-charset) + (if (coding-system-equal new-coding 'undecided) + 'us-ascii + new-coding)))) + (cond + ((null old-coding) + ;; If there was no charset= spec, insert one. + (insert "Content-type: text/plain; charset=" mime-charset "\n")) + ((not (coding-system-equal (coding-system-base old-coding) + new-coding)) + (delete-region mime-beg mime-end) + (insert mime-charset)))) + (goto-char (point-min)) (search-forward "\n\n") (setq headers-end (point)) (setq new-headers (rmail-edit-headers-alist t)) @@ -171,7 +207,12 @@ This functions runs the normal hook `rmail-edit-mode-hook'. (setq character-coding (mail-fetch-field "content-transfer-encoding") is-text-message (rmail-is-text-p) - coding-system (rmail-get-coding-system))) + 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))) @@ -284,9 +325,9 @@ where OLD is a element of OLD-HEADERS and NEW is an element of NEW-HEADERS." ;; Look at the new headers with no old counterpart. (dolist (new new-headers) (let ((prev (cadr (member new reverse-new)))) - ;; Mark each one as an insertion. Show the previous new header. - (unless old - (push (list prev new) inserted)))) + ;; Mark each one as an insertion. + ;; Record the previous new header, to insert it after that. + (push (list prev new) inserted))) ;; It is crucial to return the insertions in buffer order ;; so that `rmail-edit-update-headers' can insert a field ;; after a new field.