Rewrite Eshell tests using ERT
[bpt/emacs.git] / lisp / mail / mailclient.el
CommitLineData
4902e827 1;;; mailclient.el --- mail sending via system's mail client.
60a97d23 2
ab422c4d 3;; Copyright (C) 2005-2013 Free Software Foundation, Inc.
60a97d23
RS
4
5;; Author: David Reitter <david.reitter@gmail.com>
6;; Keywords: mail
7
8;; This file is part of GNU Emacs.
9
b1fc2b50 10;; GNU Emacs is free software: you can redistribute it and/or modify
60a97d23 11;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
60a97d23
RS
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b1fc2b50 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
60a97d23
RS
22
23;;; Commentary:
24
3db4118f
JB
25;; This package allows to hand over a buffer to be sent off
26;; via the system's designated e-mail client.
60a97d23
RS
27;; Note that the e-mail client will display the contents of the buffer
28;; again for editing.
29;; The e-mail client is taken to be whoever handles a mailto: URL
3db4118f 30;; via `browse-url'.
60a97d23
RS
31;; Mailto: URLs are composed according to RFC2368.
32
33;; MIME bodies are not supported - we rather expect the mail client
34;; to encode the body and add, for example, a digital signature.
35;; The mailto URL RFC calls for "short text messages that are
3db4118f 36;; actually the content of automatic processing."
60a97d23 37;; So mailclient.el is ideal for situations where an e-mail is
3db4118f
JB
38;; generated automatically, and the user can edit it in the
39;; mail client (e.g. bug-reports).
60a97d23
RS
40
41;; To activate:
42;; (setq send-mail-function 'mailclient-send-it) ; if you use `mail'
43
44;;; Code:
45
46
47(require 'sendmail) ;; for mail-sendmail-undelimit-header
48(require 'mail-utils) ;; for mail-fetch-field
7bd9b9d8 49(require 'browse-url)
60a97d23 50
3db4118f 51(defcustom mailclient-place-body-on-clipboard-flag
60a97d23
RS
52 (fboundp 'w32-set-clipboard-data)
53 "If non-nil, put the e-mail body on the clipboard in mailclient.
3db4118f
JB
54This is useful on systems where only short mailto:// URLs are
55supported. Defaults to non-nil on Windows, nil otherwise."
60a97d23
RS
56 :type 'boolean
57 :group 'mail)
58
59(defun mailclient-encode-string-as-url (string)
60 "Convert STRING to a URL, using utf-8 as encoding."
61 (apply (function concat)
62 (mapcar
63 (lambda (char)
64 (cond
65 ((eq char ?\x20) "%20") ;; space
3db4118f 66 ((eq char ?\n) "%0D%0A") ;; newline
60a97d23
RS
67 ((string-match "[-a-zA-Z0-9_:/.@]" (char-to-string char))
68 (char-to-string char)) ;; printable
69 (t ;; everything else
70 (format "%%%02x" char)))) ;; escape
71 ;; Convert string to list of chars
72 (append (encode-coding-string string 'utf-8)))))
73
74(defvar mailclient-delim-static "?")
75(defun mailclient-url-delim ()
76 (let ((current mailclient-delim-static))
3db4118f 77 (setq mailclient-delim-static "&")
60a97d23
RS
78 current))
79
80(defun mailclient-gather-addresses (str &optional drop-first-name)
81 (let ((field (mail-fetch-field str nil t)))
82 (if field
83 (save-excursion
3db4118f 84 (let ((first t)
60a97d23
RS
85 (result ""))
86 (mapc
87 (lambda (recp)
3db4118f
JB
88 (setq result
89 (concat
60a97d23
RS
90 result
91 (if (and drop-first-name
92 first)
93 ""
94 (concat (mailclient-url-delim) str "="))
3db4118f 95 (mailclient-encode-string-as-url
60a97d23
RS
96 recp)))
97 (setq first nil))
3db4118f 98 (split-string
60a97d23
RS
99 (mail-strip-quoted-names field) "\, *"))
100 result)))))
101
ddf6d79f
DR
102(declare-function clipboard-kill-ring-save "menu-bar.el" (beg end))
103
60a97d23 104;;;###autoload
3db4118f 105(defun mailclient-send-it ()
60a97d23
RS
106 "Pass current buffer on to the system's mail client.
107Suitable value for `send-mail-function'.
108The mail client is taken to be the handler of mailto URLs."
109 (require 'mail-utils)
110 (let ((case-fold-search nil)
111 delimline
112 (mailbuf (current-buffer)))
113 (unwind-protect
114 (with-temp-buffer
115 (insert-buffer-substring mailbuf)
116 ;; Move to header delimiter
117 (mail-sendmail-undelimit-header)
118 (setq delimline (point-marker))
119 (if mail-aliases
120 (expand-mail-aliases (point-min) delimline))
121 (goto-char (point-min))
122 ;; ignore any blank lines in the header
123 (while (and (re-search-forward "\n\n\n*" delimline t)
124 (< (point) delimline))
125 (replace-match "\n"))
7bd9b9d8
LMI
126 (let ((case-fold-search t)
127 ;; Use the external browser function to send the
128 ;; message.
129 (browse-url-mailto-function nil))
60a97d23
RS
130 ;; initialize limiter
131 (setq mailclient-delim-static "?")
132 ;; construct and call up mailto URL
3db4118f
JB
133 (browse-url
134 (concat
60a97d23
RS
135 (save-excursion
136 (narrow-to-region (point-min) delimline)
3db4118f 137 (concat
60a97d23
RS
138 "mailto:"
139 ;; some of the headers according to RFC822
3db4118f
JB
140 (mailclient-gather-addresses "To"
141 'drop-first-name)
60a97d23
RS
142 (mailclient-gather-addresses "cc" )
143 (mailclient-gather-addresses "bcc" )
144 (mailclient-gather-addresses "Resent-To" )
145 (mailclient-gather-addresses "Resent-cc" )
146 (mailclient-gather-addresses "Resent-bcc" )
147 (mailclient-gather-addresses "Reply-To" )
148 ;; The From field is not honored for now: it's
149 ;; not necessarily configured. The mail client
150 ;; knows the user's address(es)
151 ;; (mailclient-gather-addresses "From" )
152 ;; subject line
153 (let ((subj (mail-fetch-field "Subject" nil t)))
154 (widen) ;; so we can read the body later on
155 (if subj ;; if non-blank
156 ;; the mail client will deal with
157 ;; warning the user etc.
3db4118f 158 (concat (mailclient-url-delim) "subject="
60a97d23
RS
159 (mailclient-encode-string-as-url subj))
160 ""))))
161 ;; body
3db4118f
JB
162 (concat
163 (mailclient-url-delim) "body="
60a97d23
RS
164 (mailclient-encode-string-as-url
165 (if mailclient-place-body-on-clipboard-flag
166 (progn
3db4118f 167 (clipboard-kill-ring-save
60a97d23
RS
168 (+ 1 delimline) (point-max))
169 (concat
170 "*** E-Mail body has been placed on clipboard, "
0c06a6a6 171 "please paste it here! ***"))
60a97d23
RS
172 ;; else
173 (buffer-substring (+ 1 delimline) (point-max))))))))))))
174
175(provide 'mailclient)
176
177;;; mailclient.el ends here