Add 2011 to FSF/AIST copyright years.
[bpt/emacs.git] / lisp / mail / mailclient.el
CommitLineData
60a97d23
RS
1;;; mailclient.el --- mail sending via system's mail client. -*- byte-compile-dynamic: t -*-
2
5df4f04c 3;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation
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
49
3db4118f 50(defcustom mailclient-place-body-on-clipboard-flag
60a97d23
RS
51 (fboundp 'w32-set-clipboard-data)
52 "If non-nil, put the e-mail body on the clipboard in mailclient.
3db4118f
JB
53This is useful on systems where only short mailto:// URLs are
54supported. Defaults to non-nil on Windows, nil otherwise."
60a97d23
RS
55 :type 'boolean
56 :group 'mail)
57
58(defun mailclient-encode-string-as-url (string)
59 "Convert STRING to a URL, using utf-8 as encoding."
60 (apply (function concat)
61 (mapcar
62 (lambda (char)
63 (cond
64 ((eq char ?\x20) "%20") ;; space
3db4118f 65 ((eq char ?\n) "%0D%0A") ;; newline
60a97d23
RS
66 ((string-match "[-a-zA-Z0-9_:/.@]" (char-to-string char))
67 (char-to-string char)) ;; printable
68 (t ;; everything else
69 (format "%%%02x" char)))) ;; escape
70 ;; Convert string to list of chars
71 (append (encode-coding-string string 'utf-8)))))
72
73(defvar mailclient-delim-static "?")
74(defun mailclient-url-delim ()
75 (let ((current mailclient-delim-static))
3db4118f 76 (setq mailclient-delim-static "&")
60a97d23
RS
77 current))
78
79(defun mailclient-gather-addresses (str &optional drop-first-name)
80 (let ((field (mail-fetch-field str nil t)))
81 (if field
82 (save-excursion
3db4118f 83 (let ((first t)
60a97d23
RS
84 (result ""))
85 (mapc
86 (lambda (recp)
3db4118f
JB
87 (setq result
88 (concat
60a97d23
RS
89 result
90 (if (and drop-first-name
91 first)
92 ""
93 (concat (mailclient-url-delim) str "="))
3db4118f 94 (mailclient-encode-string-as-url
60a97d23
RS
95 recp)))
96 (setq first nil))
3db4118f 97 (split-string
60a97d23
RS
98 (mail-strip-quoted-names field) "\, *"))
99 result)))))
100
ddf6d79f
DR
101(declare-function clipboard-kill-ring-save "menu-bar.el" (beg end))
102
60a97d23 103;;;###autoload
3db4118f 104(defun mailclient-send-it ()
60a97d23
RS
105 "Pass current buffer on to the system's mail client.
106Suitable value for `send-mail-function'.
107The mail client is taken to be the handler of mailto URLs."
108 (require 'mail-utils)
109 (let ((case-fold-search nil)
110 delimline
111 (mailbuf (current-buffer)))
112 (unwind-protect
113 (with-temp-buffer
114 (insert-buffer-substring mailbuf)
115 ;; Move to header delimiter
116 (mail-sendmail-undelimit-header)
117 (setq delimline (point-marker))
118 (if mail-aliases
119 (expand-mail-aliases (point-min) delimline))
120 (goto-char (point-min))
121 ;; ignore any blank lines in the header
122 (while (and (re-search-forward "\n\n\n*" delimline t)
123 (< (point) delimline))
124 (replace-match "\n"))
3db4118f 125 (let ((case-fold-search t))
60a97d23
RS
126 ;; initialize limiter
127 (setq mailclient-delim-static "?")
128 ;; construct and call up mailto URL
3db4118f
JB
129 (browse-url
130 (concat
60a97d23
RS
131 (save-excursion
132 (narrow-to-region (point-min) delimline)
3db4118f 133 (concat
60a97d23
RS
134 "mailto:"
135 ;; some of the headers according to RFC822
3db4118f
JB
136 (mailclient-gather-addresses "To"
137 'drop-first-name)
60a97d23
RS
138 (mailclient-gather-addresses "cc" )
139 (mailclient-gather-addresses "bcc" )
140 (mailclient-gather-addresses "Resent-To" )
141 (mailclient-gather-addresses "Resent-cc" )
142 (mailclient-gather-addresses "Resent-bcc" )
143 (mailclient-gather-addresses "Reply-To" )
144 ;; The From field is not honored for now: it's
145 ;; not necessarily configured. The mail client
146 ;; knows the user's address(es)
147 ;; (mailclient-gather-addresses "From" )
148 ;; subject line
149 (let ((subj (mail-fetch-field "Subject" nil t)))
150 (widen) ;; so we can read the body later on
151 (if subj ;; if non-blank
152 ;; the mail client will deal with
153 ;; warning the user etc.
3db4118f 154 (concat (mailclient-url-delim) "subject="
60a97d23
RS
155 (mailclient-encode-string-as-url subj))
156 ""))))
157 ;; body
3db4118f
JB
158 (concat
159 (mailclient-url-delim) "body="
60a97d23
RS
160 (mailclient-encode-string-as-url
161 (if mailclient-place-body-on-clipboard-flag
162 (progn
3db4118f 163 (clipboard-kill-ring-save
60a97d23
RS
164 (+ 1 delimline) (point-max))
165 (concat
166 "*** E-Mail body has been placed on clipboard, "
0c06a6a6 167 "please paste it here! ***"))
60a97d23
RS
168 ;; else
169 (buffer-substring (+ 1 delimline) (point-max))))))))))))
170
171(provide 'mailclient)
172
aa548632 173;; arch-tag: 35d10fc8-a1bc-4f29-a4e6-c288e53578ef
60a97d23 174;;; mailclient.el ends here