;; 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 'custom-file "cus-edit")
-
-;;;###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* ((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))))))
- (if (ignore-errors (custom-file))
- (customize-save-variable 'sendmail-query-once-function function)
- (setq 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 [menu-bar mail]
(cons "Mail" (make-sparse-keymap "Mail")))
+ (define-key map [menu-bar mail attachment]
+ '("Attach File" . mail-add-attachment))
+
(define-key map [menu-bar mail fill]
'("Fill Citation" . mail-fill-yanked-message))
"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)
+ (let* ((options `(("Mail client" . mailclient-send-it)
+ ,@(when (and sendmail-program
+ (executable-find sendmail-program))
+ '(("Mail transport agent" . sendmail-send-it)))
+ ("SMTP server" . 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. However, it was not configured
+ for sending email. You can instruct Emacs to send email in one of the
+ following ways:
+
+ - Start your default mail client and pass to it the message text.
+ Type \"Mail client\" at the prompt below to select this option.\n\n")
+ (if (and sendmail-program
+ (executable-find sendmail-program))
+ (insert "\
+ - Invoke the system's mail transport agent (\"sendmail\").
+ Type \"Mail transport agent\" at the prompt below to select this option.\n\n"))
+ (insert "\
+ - Send mail directly by communicating with your mail server
+ (this requires setting up SMTP parameters).
+ Type \"SMTP server\" at the prompt below to select this option.
+
+ Emacs will record your selection and will use it thereafter. To change
+ your selection 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)))))
+ (funcall send-mail-function))
+\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))))
:options '(footnote-mode))
(defvar mail-mode-abbrev-table text-mode-abbrev-table)
+(defvar mail-encode-mml)
;;;###autoload
(define-derived-mode mail-mode text-mode "Mail"
"Major mode for editing mail to be sent.
\\[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-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)
(make-local-variable 'mail-send-actions)
(make-local-variable 'mail-return-action)
+ (make-local-variable 'mail-encode-mml)
+ (setq mail-encode-mml nil)
(setq buffer-offer-save t)
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults '(mail-font-lock-keywords t t))
:type '(repeat string)
:group 'sendmail)
+(declare-function mml-to-mime "mml" ())
(defun mail-send ()
"Send the message in the current buffer.
(error "Invalid header line (maybe a continuation line lacks initial whitespace)"))
(forward-line 1)))
(goto-char opoint)
+ (when mail-encode-mml
+ (mml-to-mime)
+ (setq mail-encode-mml nil))
(run-hooks 'mail-send-hook)
(message "Sending...")
(funcall send-mail-function)
(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
(insert-file-contents file)
(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 mail message being composed."
+ (interactive "fAttach file: ")
+ (mml-attach-file file
+ (or (mm-default-file-encoding file)
+ "application/octet-stream") nil)
+ (setq mail-encode-mml t))
+
\f
;; 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.