-;;; sendmail.el --- mail sending commands for Emacs. -*- byte-compile-dynamic: t -*-
+;;; sendmail.el --- mail sending commands for Emacs
-;; Copyright (C) 1985-1986, 1992-1996, 1998, 2000-2011
+;; Copyright (C) 1985-1986, 1992-1996, 1998, 2000-2012
;; Free Software Foundation, Inc.
;; Maintainer: FSF
(require 'rfc2047)
-(autoload 'mml-to-mime "mml"
- "Translate the current buffer from MML to MIME.")
-
-(autoload 'mml-attach-file "mml"
- "Attach a file to the outgoing MIME message.
-The file is not inserted or encoded until you send the message.")
-
-(autoload 'mm-default-file-encoding "mm-encode"
- "Return the default encoding for FILE.")
-
(defgroup sendmail nil
"Mail sending commands for Emacs."
:prefix "mail-"
;; Useful to set in site-init.el
;;;###autoload
-(defcustom send-mail-function 'sendmail-query-once
+(defcustom send-mail-function
+ ;; Assume smtpmail is the preferred choice if it's already configured.
+ (if (and (boundp 'smtpmail-smtp-server)
+ smtpmail-smtp-server)
+ 'smtpmail-send-it 'sendmail-query-once)
"Function to call to send the current buffer as mail.
The headers should be delimited by a line which is
not a valid RFC822 header or continuation line,
:version "24.1"
:group 'sendmail)
-(defvar sendmail-query-once-function 'query
- "Either a function to send email, or the symbol `query'.")
-
-;;;###autoload
-(defun sendmail-query-once ()
- "Send an email via `sendmail-query-once-function'.
-If `sendmail-query-once-function' is `query', ask the user what
-function to use, and then save that choice."
- (when (equal sendmail-query-once-function 'query)
- (let* ((mail-buffer (current-buffer))
- (default
- (cond
- ((or (and window-system (eq system-type 'darwin))
- (eq system-type 'windows-nt))
- 'mailclient-send-it)
- ((and sendmail-program
- (executable-find sendmail-program))
- 'sendmail-send-it)))
- (function
- (if (or (not default)
- ;; We have detected no OS-level mail senders, or we
- ;; have already configured smtpmail, so we use the
- ;; internal SMTP service.
- (and (boundp 'smtpmail-smtp-server)
- smtpmail-smtp-server))
- 'smtpmail-send-it
- ;; Query the user.
- (unwind-protect
- (progn
- (pop-to-buffer "*Mail Help*")
- (erase-buffer)
- (insert "Sending mail from Emacs hasn't been set up yet.\n\n"
- "Type `y' to configure outgoing SMTP, or `n' to use\n"
- "the default mail sender on your system.\n\n"
- "To change this again at a later date, customize the\n"
- "`send-mail-function' variable.\n")
- (goto-char (point-min))
- (if (y-or-n-p "Configure outgoing SMTP in Emacs? ")
- 'smtpmail-send-it
- default))
- (kill-buffer (current-buffer))
- (set-buffer mail-buffer)))))
- (customize-save-variable 'sendmail-query-once-function function)))
- (funcall sendmail-query-once-function))
-
;;;###autoload
(defcustom mail-header-separator (purecopy "--text follows this line--")
"Line used to separate headers from text in messages being composed."
(define-key map "\C-c\C-w" 'mail-signature)
(define-key map "\C-c\C-c" 'mail-send-and-exit)
(define-key map "\C-c\C-s" 'mail-send)
- (define-key map "\C-c\C-i" 'mail-attach-file)
+ (define-key map "\C-c\C-i" 'mail-insert-file)
;; FIXME add this? "b" = bury buffer. It's in the menu-bar.
;;; (define-key map "\C-c\C-b" 'mail-dont-send)
"Additional expressions to highlight in Mail mode.")
\f
+;;;###autoload
+(defun sendmail-query-once ()
+ "Query for `send-mail-function' and send mail with it.
+This also saves the value of `send-mail-function' via Customize."
+ ;; If send-mail-function is already setup, we're incorrectly called
+ ;; a second time, probably because someone's using an old value
+ ;; of send-mail-function.
+ (when (eq send-mail-function 'sendmail-query-once)
+ (sendmail-query-user-about-smtp))
+ (funcall send-mail-function))
+
+(defun sendmail-query-user-about-smtp ()
+ (let* ((options `(("mail client" . mailclient-send-it)
+ ,@(when (and sendmail-program
+ (executable-find sendmail-program))
+ '(("transport" . sendmail-send-it)))
+ ("smtp" . smtpmail-send-it)))
+ (choice
+ ;; Query the user.
+ (with-temp-buffer
+ (rename-buffer "*Emacs Mail Setup Help*" t)
+ (insert "\
+ Emacs is about to send an email message, but it has not been
+ configured for sending email. To tell Emacs how to send email:
+
+ - Type `"
+ (propertize "mail client" 'face 'bold)
+ "' to start your default email client and
+ pass it the message text.\n\n")
+ (and sendmail-program
+ (executable-find sendmail-program)
+ (insert "\
+ - Type `"
+ (propertize "transport" 'face 'bold)
+ "' to invoke the system's mail transport agent
+ (the `"
+ sendmail-program
+ "' program).\n\n"))
+ (insert "\
+ - Type `"
+ (propertize "smtp" 'face 'bold)
+ "' to send mail directly to an \"outgoing mail\" server.
+ (Emacs may prompt you for SMTP settings).
+
+ Emacs will record your selection and will use it thereafter.
+ To change it later, customize the option `send-mail-function'.\n")
+ (goto-char (point-min))
+ (display-buffer (current-buffer))
+ (let ((completion-ignore-case t))
+ (completing-read "Send mail via: "
+ options nil 'require-match)))))
+ (customize-save-variable 'send-mail-function
+ (cdr (assoc-string choice options t)))))
+\f
(defun sendmail-sync-aliases ()
(when mail-personal-alias-file
(let ((modtime (nth 5 (file-attributes mail-personal-alias-file))))
send-actions return-action
&rest ignored)
(if switch-function
- (let ((special-display-buffer-names nil)
- (special-display-regexps nil)
- (same-window-buffer-names nil)
- (same-window-regexps nil))
- (funcall switch-function "*mail*")))
+ (funcall switch-function "*mail*"))
(let ((cc (cdr (assoc-string "cc" other-headers t)))
(in-reply-to (cdr (assoc-string "in-reply-to" other-headers t)))
(body (cdr (assoc-string "body" other-headers t))))
;; (kill-local-variable 'enable-multibyte-characters)
(set-buffer-multibyte (default-value 'enable-multibyte-characters))
(if current-input-method
- (inactivate-input-method))
+ (deactivate-input-method))
;; Local variables for Mail mode.
(setq mail-send-actions actions)
\\[mail-signature] mail-signature (insert `mail-signature-file' file).
\\[mail-yank-original] mail-yank-original (insert current message, in Rmail).
\\[mail-fill-yanked-message] mail-fill-yanked-message (fill what was yanked).
-\\[mail-attach-file] insert a text file into the message.
-\\[mail-add-attachment] add to the message a file as binary attachment.
+\\[mail-insert-file] insert a text file into the message.
+\\[mail-add-attachment] attach to the message a file as binary attachment.
Turning on Mail mode runs the normal hooks `text-mode-hook' and
`mail-mode-hook' (in that order)."
(make-local-variable 'mail-reply-action)
(set (make-local-variable 'comment-start-skip)
(concat "^" (regexp-quote mail-yank-prefix) "[ \t]*")))
(make-local-variable 'adaptive-fill-regexp)
+ ;; Also update the paragraph-separate entry if you change this.
(setq adaptive-fill-regexp
(concat "[ \t]*[-[:alnum:]]+>+[ \t]*\\|"
adaptive-fill-regexp))
;; lines that delimit forwarded messages.
;; Lines containing just >= 3 dashes, perhaps after whitespace,
;; are also sometimes used and should be separators.
- (setq paragraph-separate (concat (regexp-quote mail-header-separator)
- "$\\|\t*\\([-|#;>* ]\\|(?[0-9]+[.)]\\)+$"
- "\\|[ \t]*[[:alnum:]]*>+[ \t]*$\\|[ \t]*$\\|"
- "--\\( \\|-+\\)$\\|"
- page-delimiter)))
+ (setq paragraph-separate
+ (concat (regexp-quote mail-header-separator)
+ ;; This is based on adaptive-fill-regexp (presumably
+ ;; the idea is to allow navigation etc of cited paragraphs).
+ "$\\|\t*[-–!|#%;>*·•‣⁃◦ ]+$"
+ "\\|[ \t]*[-[:alnum:]]*>+[ \t]*$\\|[ \t]*$\\|"
+ "--\\( \\|-+\\)$\\|"
+ page-delimiter)))
(defun mail-header-end ()
(defun mail-bury (&optional arg)
"Bury this mail buffer."
(let ((newbuf (other-buffer (current-buffer)))
- (return-action mail-return-action)
- some-rmail)
+ (return-action mail-return-action))
(bury-buffer (current-buffer))
;; If there is an Rmail buffer, return to it nicely
;; even if this message was not started by an Rmail command.
(unless return-action
(dolist (buffer (buffer-list))
- (if (eq (buffer-local-value 'major-mode buffer) 'rmail-mode)
- (setq return-action `(rmail-mail-return ,newbuf)))))
+ (if (and (eq (buffer-local-value 'major-mode buffer) 'rmail-mode)
+ (null return-action)
+ ;; Don't match message-viewer buffer.
+ (not (string-match "\\` " (buffer-name buffer))))
+ (setq return-action `(rmail-mail-return ,buffer)))))
(if (and (null arg) return-action)
(apply (car return-action) (cdr return-action))
(switch-to-buffer newbuf))))
:type '(repeat string)
:group 'sendmail)
+(declare-function mml-to-mime "mml" ())
(defun mail-send ()
"Send the message in the current buffer.
;;;###autoload
(defvar sendmail-coding-system nil
- "*Coding system for encoding the outgoing mail.
+ "Coding system for encoding the outgoing mail.
This has higher priority than the default `buffer-file-coding-system'
and `default-sendmail-coding-system',
but lower priority than the local value of `buffer-file-coding-system'.
(cons selected mm-coding-system-priorities)
mm-coding-system-priorities))
(tick (buffer-chars-modified-tick))
+ ;; Many mailers, including Gnus, passes a message of which
+ ;; the header is already encoded, so this is necessary to
+ ;; prevent it from being encoded again.
(rfc2047-encode-encoded-words nil))
(rfc2047-encode-message-header)
(= tick (buffer-chars-modified-tick)))))
and don't delete any header fields."
(interactive "P")
(and (consp mail-reply-action)
- (eq (car mail-reply-action) 'insert-buffer)
+ (memq (car mail-reply-action)
+ '(rmail-yank-current-message insert-buffer))
(with-current-buffer (nth 1 mail-reply-action)
(or (mark t)
(error "No mark set: %S" (current-buffer))))
(split-line mail-yank-prefix))
\f
-(defun mail-attach-file (&optional file)
+(defun mail-insert-file (&optional file)
"Insert a file at the end of the buffer, with separator lines around it."
(interactive "fAttach file: ")
(save-excursion
(or (bolp) (newline))
(goto-char start))))
+(define-obsolete-function-alias 'mail-attach-file 'mail-insert-file "24.1")
+
+(declare-function mml-attach-file "mml"
+ (file &optional type description disposition))
+(declare-function mm-default-file-encoding "mm-encode" (file))
+
(defun mail-add-attachment (file)
- "Add FILE as a MIME attachment to the end of the message."
+ "Add FILE as a MIME attachment to the end of the mail message being composed."
(interactive "fAttach file: ")
(mml-attach-file file
(or (mm-default-file-encoding file)
;; Put these commands last, to reduce chance of lossage from quitting
;; in middle of loading the file.
-;;;###autoload (add-hook 'same-window-buffer-names (purecopy "*mail*"))
-;;;###autoload (add-hook 'same-window-buffer-names (purecopy "*unsent mail*"))
-
;;;###autoload
(defun mail (&optional noerase to subject in-reply-to cc replybuffer
actions return-action)
This is how Rmail arranges to mark messages `answered'."
(interactive "P")
(if (eq noerase 'new)
- (pop-to-buffer (generate-new-buffer "*mail*"))
+ (pop-to-buffer-same-window (generate-new-buffer "*mail*"))
(and noerase
(not (get-buffer "*mail*"))
(setq noerase nil))
- (pop-to-buffer "*mail*"))
+ (pop-to-buffer-same-window "*mail*"))
;; Avoid danger that the auto-save file can't be written.
(let ((dir (expand-file-name
(dired-noselect file-name
(concat dired-listing-switches " -t"))))
(save-selected-window
- (select-window (display-buffer dispbuf t))
+ (switch-to-buffer-other-window dispbuf)
(goto-char (point-min))
(forward-line 2)
(dired-move-to-filename)
(defun mail-other-window (&optional noerase to subject in-reply-to cc replybuffer sendactions)
"Like `mail' command, but display mail buffer in another window."
(interactive "P")
- (let ((pop-up-windows t)
- (special-display-buffer-names nil)
- (special-display-regexps nil)
- (same-window-buffer-names nil)
- (same-window-regexps nil))
- (pop-to-buffer "*mail*"))
+ (switch-to-buffer-other-window "*mail*")
(mail noerase to subject in-reply-to cc replybuffer sendactions))
;;;###autoload
(defun mail-other-frame (&optional noerase to subject in-reply-to cc replybuffer sendactions)
"Like `mail' command, but display mail buffer in another frame."
(interactive "P")
- (let ((pop-up-frames t)
- (special-display-buffer-names nil)
- (special-display-regexps nil)
- (same-window-buffer-names nil)
- (same-window-regexps nil))
- (pop-to-buffer "*mail*"))
+ (switch-to-buffer-other-frame "*mail*")
(mail noerase to subject in-reply-to cc replybuffer sendactions))
;; Do not add anything but external entries on this page.
(provide 'sendmail)
+;; Local Variables:
+;; byte-compile-dynamic: t
+;; coding: utf-8
+;; End:
+
;;; sendmail.el ends here