view lisp/mail/mailclient.el @ 85536:a23a7c302a2c

Add some support for Fortran 2003 syntax: (f90-type-indent): Now also applies to `enum'. (f90-associate-indent): New user option. (f90-keywords-re, f90-keywords-level-3-re, f90-procedures-re): Add some F2003 keywords. (f90-constants-re): New constant. (f90-font-lock-keywords-1): Add `associate' blocks, and `abstract Interface'. (f90-font-lock-keywords-2): Add `enumerator', `generic', `procedure', `class'. Arguments for `type'/`class' may have spaces. Add a new element for functions with specified types. Add `end enum' and `select type'. Add `implicit enumerator' and `procedure'. Add `class default' and `type is', `class is'. Fix `go to' regexp. (f90-font-lock-keywords-3): Add `asynchronous' attribute. (f90-font-lock-keywords-4): Add `f90-constants-re'. (f90-blocks-re): Add `enum' and `associate'. (f90-else-like-re): Add `class is', `type is', and `class default'. (f90-end-type-re): Add `enum'. (f90-end-associate-re, f90-typeis-re): New constants. (f90-end-block-re): Add `enum' and `associate'. Change from optional whitespace to end-of-word, to avoid `enumerator'. (f90-start-block-re): Add `select type', `abstract interface', and `enum'. Avoid `type is', and `type (sometype)'. (f90-mode-abbrev-table): Add `enumerator', `protected', and `volatile'. (f90-mode): Doc fix. (f90-looking-at-select-case): Doc fix. Add `select type'. (f90-looking-at-associate): New function, (f90-looking-at-type-like): Avoid `type is' and `type (sometype)'. Add `enum' and `abstract interface'. (f90-no-block-limit): Add `select type' and `abstract interface'. (f90-get-correct-indent, f90-calculate-indent) (f90-end-of-block, f90-beginning-of-block, f90-next-block) (f90-indent-region, f90-match-end): : Handle `associate' blocks.
author Glenn Morris <rgm@gnu.org>
date Mon, 22 Oct 2007 08:17:25 +0000
parents 8e27d63c45eb
children de499b20517a
line wrap: on
line source

;;; mailclient.el --- mail sending via system's mail client.  -*- byte-compile-dynamic: t -*-

;; Copyright (C) 2005, 2006, 2007 Free Software Foundation

;; Author: David Reitter <david.reitter@gmail.com>
;; Keywords: mail

;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:

;; This package allows to hand over a buffer to be sent off
;; via the system's designated e-mail client.
;; Note that the e-mail client will display the contents of the buffer
;; again for editing.
;; The e-mail client is taken to be whoever handles a mailto: URL
;; via `browse-url'.
;; Mailto: URLs are composed according to RFC2368.

;; MIME bodies are not supported - we rather expect the mail client
;; to encode the body and add, for example, a digital signature.
;; The mailto URL RFC calls for "short text messages that are
;; actually the content of automatic processing."
;; So mailclient.el is ideal for situations where an e-mail is
;; generated automatically, and the user can edit it in the
;; mail client (e.g. bug-reports).

;; To activate:
;; (setq send-mail-function 'mailclient-send-it) ; if you use `mail'

;;; Code:


(require 'sendmail)   ;; for mail-sendmail-undelimit-header
(require 'mail-utils) ;; for mail-fetch-field

(defcustom mailclient-place-body-on-clipboard-flag
  (fboundp 'w32-set-clipboard-data)
  "If non-nil, put the e-mail body on the clipboard in mailclient.
This is useful on systems where only short mailto:// URLs are
supported.  Defaults to non-nil on Windows, nil otherwise."
  :type 'boolean
  :group 'mail)

(defun mailclient-encode-string-as-url (string)
  "Convert STRING to a URL, using utf-8 as encoding."
  (apply (function concat)
	 (mapcar
	  (lambda (char)
	    (cond
	     ((eq char ?\x20) "%20")   ;; space
	     ((eq char ?\n) "%0D%0A")  ;; newline
	     ((string-match "[-a-zA-Z0-9_:/.@]" (char-to-string char))
	      (char-to-string char))   ;; printable
	     (t                        ;; everything else
	      (format "%%%02x" char))))	;; escape
	  ;; Convert string to list of chars
	  (append (encode-coding-string string 'utf-8)))))

(defvar mailclient-delim-static "?")
(defun mailclient-url-delim ()
  (let ((current mailclient-delim-static))
    (setq mailclient-delim-static "&")
    current))

(defun mailclient-gather-addresses (str &optional drop-first-name)
  (let ((field (mail-fetch-field str nil t)))
    (if field
	(save-excursion
	  (let ((first t)
		(result ""))
	    (mapc
	     (lambda (recp)
	       (setq result
		     (concat
		      result
		      (if (and drop-first-name
			       first)
			  ""
			(concat (mailclient-url-delim) str "="))
		      (mailclient-encode-string-as-url
		       recp)))
	       (setq first nil))
	     (split-string
	      (mail-strip-quoted-names field) "\, *"))
	    result)))))

;;;###autoload
(defun mailclient-send-it ()
  "Pass current buffer on to the system's mail client.
Suitable value for `send-mail-function'.
The mail client is taken to be the handler of mailto URLs."
  (require 'mail-utils)
  (let ((case-fold-search nil)
	delimline
	(mailbuf (current-buffer)))
    (unwind-protect
	(with-temp-buffer
	  (insert-buffer-substring mailbuf)
	  ;; Move to header delimiter
	  (mail-sendmail-undelimit-header)
	  (setq delimline (point-marker))
	  (if mail-aliases
	      (expand-mail-aliases (point-min) delimline))
	  (goto-char (point-min))
	  ;; ignore any blank lines in the header
	  (while (and (re-search-forward "\n\n\n*" delimline t)
		      (< (point) delimline))
	    (replace-match "\n"))
	  (let ((case-fold-search t))
	    ;; initialize limiter
	    (setq mailclient-delim-static "?")
	    ;; construct and call up mailto URL
	    (browse-url
	     (concat
	      (save-excursion
		(narrow-to-region (point-min) delimline)
		(concat
		 "mailto:"
		 ;; some of the headers according to RFC822
		 (mailclient-gather-addresses "To"
					      'drop-first-name)
		 (mailclient-gather-addresses "cc"  )
		 (mailclient-gather-addresses "bcc"  )
		 (mailclient-gather-addresses "Resent-To"  )
		 (mailclient-gather-addresses "Resent-cc"  )
		 (mailclient-gather-addresses "Resent-bcc"  )
		 (mailclient-gather-addresses "Reply-To"  )
		 ;; The From field is not honored for now: it's
		 ;; not necessarily configured. The mail client
		 ;; knows the user's address(es)
		 ;; (mailclient-gather-addresses "From"  )
		 ;; subject line
		 (let ((subj (mail-fetch-field "Subject" nil t)))
		   (widen) ;; so we can read the body later on
		   (if subj ;; if non-blank
		       ;; the mail client will deal with
		       ;; warning the user etc.
		       (concat (mailclient-url-delim) "subject="
			       (mailclient-encode-string-as-url subj))
		     ""))))
	      ;; body
	      (concat
	       (mailclient-url-delim) "body="
	       (mailclient-encode-string-as-url
		(if mailclient-place-body-on-clipboard-flag
		    (progn
		      (clipboard-kill-ring-save
		       (+ 1 delimline) (point-max))
		      (concat
		       "*** E-Mail body has been placed on clipboard, "
		       "please paste them here! ***"))
		  ;; else
		  (buffer-substring (+ 1 delimline) (point-max))))))))))))

(provide 'mailclient)

;; arch-tag: 35d10fc8-a1bc-4f29-a4e6-c288e53578ef
;;; mailclient.el ends here