;;; rmail.el --- main code of "RMAIL" mail reader for Emacs
;; Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: mail
(defvar rsf-beep)
(defvar rsf-sleep-after-message)
(defvar total-messages)
+(defvar tool-bar-map)
; These variables now declared in paths.el.
;(defvar rmail-spool-directory "/usr/spool/mail/"
Called with region narrowed to the message, including headers,
before obeying `rmail-ignored-headers'."
:group 'rmail-headers
- :type 'function)
+ :type '(choice (const nil) function))
(defcustom rmail-automatic-folder-directives nil
"List of directives specifying where to put a message.
"String to prepend to Subject line when replying to a message.")
;; Some mailers use "Re(2):" or "Re^2:" or "Re: Re:" or "Re[2]:".
-;; This pattern should catch all the common variants. The pattern
-;; also ignores mailing list identifiers sometimes added in square
-;; brackets at the beginning of subject lines.
-(defvar rmail-reply-regexp "\\`\\(\\[.+?\\] \\)?\\(Re\\(([0-9]+)\\|\\[[0-9]+\\]\\|\\^[0-9]+\\)?: *\\)*"
+;; This pattern should catch all the common variants.
+;; rms: I deleted the change to delete tags in square brackets
+;; because they mess up RT tags.
+(defvar rmail-reply-regexp "\\`\\(Re\\(([0-9]+)\\|\\[[0-9]+\\]\\|\\^[0-9]+\\)?: *\\)*"
"Regexp to delete from Subject line before inserting `rmail-reply-prefix'.")
(defcustom rmail-display-summary nil
;;;###autoload
(defvar rmail-mime-charset-pattern
- "^content-type:[ ]*text/plain;[ \t\n]*charset=\"?\\([^ \t\n\";]+\\)\"?"
+ (concat "^content-type:[ \t]*text/plain;"
+ "\\(?:[ \t\n]*\\(?:format\\|delsp\\)=\"?[-a-z0-9]+\"?;\\)*"
+ "[ \t\n]*charset=\"?\\([^ \t\n\";]+\\)\"?")
"Regexp to match MIME-charset specification in a header of message.
The first parenthesized expression should match the MIME-charset name.")
(unless (and coding-system
(coding-system-p coding-system))
(setq coding-system
- ;; Emacs 21.1 and later writes RMAIL files in emacs-mule, but
- ;; earlier versions did that with the current buffer's encoding.
- ;; So we want to favor detection of emacs-mule (whose normal
- ;; priority is quite low), but still allow detection of other
- ;; encodings if emacs-mule won't fit. The call to
- ;; detect-coding-with-priority below achieves that.
- (car (detect-coding-with-priority
- from to
- '((coding-category-emacs-mule . emacs-mule))))))
- (unless (memq coding-system
- '(undecided undecided-unix))
+ ;; If rmail-file-coding-system is nil, Emacs 21 writes
+ ;; RMAIL files in emacs-mule, Emacs 22 in utf-8, but
+ ;; earlier versions did that with the current buffer's
+ ;; encoding. So we want to favor detection of emacs-mule
+ ;; (whose normal priority is quite low) and utf-8, but
+ ;; still allow detection of other encodings if they won't
+ ;; fit. The call to with-coding-priority below achieves
+ ;; that.
+ (with-coding-priority '(emacs-mule utf-8)
+ (detect-coding-region from to 'highest))))
+ (unless (eq (coding-system-type coding-system) 'undecided)
(set-buffer-modified-p t) ; avoid locking when decoding
(let ((buffer-undo-list t))
(decode-coding-region from to coding-system))
(define-key rmail-mode-map [menu-bar move next]
'("Next" . rmail-next-message))
+
+;; Rmail toolbar
+(defvar rmail-tool-bar-map
+ (if (display-graphic-p)
+ (let ((map (make-sparse-keymap)))
+ (tool-bar-local-item-from-menu 'rmail-get-new-mail "mail/inbox"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-next-undeleted-message "right-arrow"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-previous-undeleted-message "left-arrow"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-search "search"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-input "open"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-mail "mail/compose"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-reply "mail/reply-all"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-forward "mail/forward"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-delete-forward "close"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-output "mail/move"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-output-body-to-file "mail/save"
+ map rmail-mode-map)
+ (tool-bar-local-item-from-menu 'rmail-expunge "delete"
+ map rmail-mode-map)
+ map)))
+
+
\f
;; Rmail mode is suitable only for specially formatted data.
(put 'rmail-mode 'mode-class 'special)
(concat rmail-spool-directory
(user-login-name)))))))
(make-local-variable 'rmail-keywords)
+ (set (make-local-variable 'tool-bar-map) rmail-tool-bar-map)
;; this gets generated as needed
(setq rmail-keywords nil))
(if (and (featurep 'rmail-spam-filter)
rmail-use-spam-filter
(> rsf-number-of-spam 0))
- (if (= 1 new-messages)
- ", and found to be a spam message"
- (if (> rsf-number-of-spam 1)
- (format ", %d of which found to be spam messages"
- rsf-number-of-spam)
- ", one of which found to be a spam message"))
+ (cond ((= 1 new-messages)
+ ", and appears to be spam")
+ ((= rsf-number-of-spam new-messages)
+ ", and all appear to be spam")
+ ((> rsf-number-of-spam 1)
+ (format ", and %d appear to be spam"
+ rsf-number-of-spam))
+ (t
+ ", and 1 appears to be spam"))
""))
(if (and (featurep 'rmail-spam-filter)
rmail-use-spam-filter
(defun rmail-convert-to-babyl-format ()
(let ((count 0) start
(case-fold-search nil)
+ (buffer-undo-list t)
(invalid-input-resync
(function (lambda ()
(message "Invalid Babyl format in inbox!")
;; may still be in use. -- rms, 7 May 1993.
((eolp) (delete-char 1))
(t (error "Cannot convert to babyl format")))))
+ (setq buffer-undo-list nil)
count))
;; Delete the "From ..." line, creating various other headers with
(if blurb
(message blurb))))))
-(defun rmail-redecode-body (coding)
+(defun rmail-redecode-body (coding &optional raw)
"Decode the body of the current message using coding system CODING.
This is useful with mail messages that have malformed or missing
charset= headers.
decode it was incorrect. It then encodes the message back to its
original form, and decodes it again, using the coding system CODING.
+Optional argument RAW, if non-nil, means don't encode the message
+before decoding it with the new CODING. This is useful if the current
+message text was produced by some function which invokes `insert',
+since `insert' leaves unibyte character codes 128 through 255 unconverted
+to multibyte. One example of such a situation is when the text was
+produced by `base64-decode-region'.
+
+Interactively, invoke the function with a prefix argument to set RAW
+non-nil.
+
Note that if Emacs erroneously auto-detected one of the iso-2022
encodings in the message, this function might fail because the escape
sequences that switch between character sets and also single-shift and
(or (eq major-mode 'rmail-mode)
(switch-to-buffer rmail-buffer))
(save-excursion
- (let ((pruned (rmail-msg-is-pruned)))
+ (let ((pruned (rmail-msg-is-pruned))
+ (raw (or raw current-prefix-arg)))
(unwind-protect
(let ((msgbeg (rmail-msgbeg rmail-current-message))
(msgend (rmail-msgend rmail-current-message))
(coding-system-change-eol-conversion
coding
(coding-system-eol-type old-coding)))
+ ;; If old-coding is `undecided', encode-coding-region
+ ;; will not encode the text at all. Find a proper
+ ;; non-trivial encoding to use.
+ (if (memq (coding-system-base old-coding) '(nil undecided))
+ (setq old-coding
+ (car (find-coding-systems-region msgbeg msgend))))
(setq x-coding-header (point-marker))
(narrow-to-region msgbeg msgend)
- (encode-coding-region (point) msgend old-coding)
+ (and (null raw)
+ ;; If old and new encoding are the same, it
+ ;; clearly doesn't make sense to encode.
+ (not (coding-system-equal
+ (coding-system-base old-coding)
+ (coding-system-base coding)))
+ ;; If the body includes only eight-bit-*
+ ;; characters, encoding might fail, e.g. with
+ ;; UTF-8, and isn't needed anyway.
+ (> (length (delq 'ascii
+ (delq 'eight-bit-graphic
+ (delq 'eight-bit-control
+ (find-charset-region
+ msgbeg msgend)))))
+ 0)
+ (encode-coding-region (point) msgend old-coding))
(decode-coding-region (point) msgend coding)
(setq last-coding-system-used coding)
;; Rewrite the coding-system header according