;;; gnus-msg.el --- mail and post interface for Gnus
-;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc.
;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
;; Lars Magne Ingebrigtsen <larsi@gnus.org>
(defvar gnus-posting-styles nil
"*Alist of styles to use when posting.")
-(defvar gnus-posting-style-alist
- '((organization . message-user-organization)
- (signature . message-signature)
- (signature-file . message-signature-file)
- (address . user-mail-address)
- (name . user-full-name))
- "*Mapping from style parameters to variables.")
+(defcustom gnus-group-posting-charset-alist
+ '(("^no\\." iso-8859-1)
+ (message-this-is-mail nil)
+ (".*" iso-8859-1)
+ (message-this-is-news iso-8859-1))
+ "Alist of regexps (to match group names) and default charsets to be unencoded when posting."
+ :type '(repeat (list (regexp :tag "Group")
+ (symbol :tag "Charset")))
+ :group 'gnus-charset)
;;; Internal variables.
The buffer below is a mail buffer. When you press `C-c C-c', it will
be sent to the Gnus Bug Exterminators.
-At the bottom of the buffer you'll see lots of variable settings.
-Please do not delete those. They will tell the Bug People what your
-environment is, so that it will be easier to locate the bugs.
+The thing near the bottom of the buffer is how the environment
+settings will be included in the mail. Please do not delete that.
+They will tell the Bug People what your environment is, so that it
+will be easier to locate the bugs.
If you have found a bug that makes Emacs go \"beep\", set
debug-on-error to t (`M-x set-variable RET debug-on-error RET t RET')
(setq gnus-message-buffer (current-buffer))
(set (make-local-variable 'gnus-message-group-art)
(cons ,group ,article))
- (make-local-variable 'gnus-newsgroup-name)
+ (set (make-local-variable 'gnus-newsgroup-name) ,group)
+ (set (make-local-variable 'message-posting-charset)
+ (gnus-setup-posting-charset ,group))
(gnus-run-hooks 'gnus-message-setup-hook))
(gnus-add-buffer)
(gnus-configure-windows ,config t)
(set-buffer-modified-p nil))))
+(defun gnus-setup-posting-charset (group)
+ (let ((alist gnus-group-posting-charset-alist)
+ (group (or group ""))
+ elem)
+ (when group
+ (catch 'found
+ (while (setq elem (pop alist))
+ (when (or (and (stringp (car elem))
+ (string-match (car elem) group))
+ (and (gnus-functionp (car elem))
+ (funcall (car elem) group))
+ (and (symbolp (car elem))
+ (symbol-value (car elem))))
+ (throw 'found (cadr elem))))))))
+
(defun gnus-inews-add-send-actions (winconf buffer article)
(make-local-hook 'message-sent-hook)
(add-hook 'message-sent-hook 'gnus-inews-do-gcc nil t)
If ARG, use the group under the point to find a posting style.
If ARG is 1, prompt for a group name to find the posting style."
(interactive "P")
- (let ((gnus-newsgroup-name
- (if arg
- (if (= 1 (prefix-numeric-value arg))
- (completing-read "Use posting style of group: "
- gnus-active-hashtb nil
- (gnus-read-active-file-p))
- (gnus-group-group-name))
- "")))
- (gnus-setup-message 'message (message-mail))))
+ ;; We can't `let' gnus-newsgroup-name here, since that leads
+ ;; to local variables leaking.
+ (let ((group gnus-newsgroup-name)
+ (buffer (current-buffer)))
+ (unwind-protect
+ (progn
+ (setq gnus-newsgroup-name
+ (if arg
+ (if (= 1 (prefix-numeric-value arg))
+ (completing-read "Use posting style of group: "
+ gnus-active-hashtb nil
+ (gnus-read-active-file-p))
+ (gnus-group-group-name))
+ ""))
+ (gnus-setup-message 'message (message-mail)))
+ (save-excursion
+ (set-buffer buffer)
+ (setq gnus-newsgroup-name group)))))
(defun gnus-group-post-news (&optional arg)
"Start composing a news message.
;; Delete the headers from the displayed articles.
(set-buffer gnus-article-copy)
(delete-region (goto-char (point-min))
- (or (search-forward "\n\n" nil t) (point)))
+ (or (search-forward "\n\n" nil t) (point-max)))
;; Insert the original article headers.
(insert-buffer-substring gnus-original-article-buffer beg end)
(article-decode-encoded-words)))
" (" gnus-version ")"
" "
(cond
- ((string-match "^\\([0-9]+\\.[0-9]+\\)\\.[.0-9]+$" emacs-version)
+ ((string-match "^\\(\\([.0-9]+\\)*\\)\\.[0-9]+$" emacs-version)
(concat "Emacs/" (match-string 1 emacs-version)))
((string-match "\\([A-Z]*[Mm][Aa][Cc][Ss]\\)[^(]*\\(\\((beta.*)\\|'\\)\\)?"
emacs-version)
(interactive "P")
(gnus-summary-reply-with-original n t))
-(defun gnus-summary-mail-forward (&optional full-headers post)
+(defun gnus-summary-mail-forward (&optional not-used post)
"Forward the current message to another user.
-If FULL-HEADERS (the prefix), include full headers when forwarding."
+If POST, post instead of mail."
(interactive "P")
(gnus-setup-message 'forward
(gnus-summary-select-article)
- (set-buffer gnus-original-article-buffer)
- (let ((message-included-forward-headers
- (if full-headers "" message-included-forward-headers)))
+ (let (text)
+ (save-excursion
+ (set-buffer gnus-original-article-buffer)
+ (setq text (buffer-string)))
+ (set-buffer (gnus-get-buffer-create
+ (generate-new-buffer-name " *Gnus forward*")))
+ (erase-buffer)
+ (insert text)
+ (goto-char (point-min))
+ (when (looking-at "From ")
+ (replace-match "X-From-Line: ") )
+ (run-hooks 'gnus-article-decode-hook)
(message-forward post))))
(defun gnus-summary-resend-message (address n)
(stringp nntp-server-type))
(insert nntp-server-type))
(insert "\n\n\n\n\n")
- (gnus-debug)
+ (save-excursion
+ (set-buffer (gnus-get-buffer-create " *gnus environment info*"))
+ (gnus-debug))
+ (insert "<#part type=application/x-emacs-lisp buffer=\" *gnus environment info*\" disposition=inline description=\"User settings\"><#/part>")
(goto-char (point-min))
(search-forward "Subject: " nil t)
(message "")))
(save-excursion
(nnheader-set-temp-buffer " *acc*")
(insert-buffer-substring cur)
+ (message-encode-message-body)
+ (save-restriction
+ (message-narrow-to-headers)
+ (mail-encode-encoded-word-buffer))
(goto-char (point-min))
(when (re-search-forward
(concat "^" (regexp-quote mail-header-separator) "$")
;;; Posting styles.
-(defvar gnus-message-style-insertions nil)
-
(defun gnus-configure-posting-styles ()
"Configure posting styles according to `gnus-posting-styles'."
(unless gnus-inhibit-posting-styles
- (let ((styles gnus-posting-styles)
- (gnus-newsgroup-name (or gnus-newsgroup-name ""))
- style match variable attribute value value-value)
- (make-local-variable 'gnus-message-style-insertions)
+ (let ((group (or gnus-newsgroup-name ""))
+ (styles gnus-posting-styles)
+ style match variable attribute value v styles results
+ filep name address element)
+ ;; If the group has a posting-style parameter, add it at the end with a
+ ;; regexp matching everything, to be sure it takes precedence over all
+ ;; the others.
+ (when gnus-newsgroup-name
+ (let ((tmp-style (gnus-group-find-parameter group 'posting-style t)))
+ (when tmp-style
+ (setq styles (append styles (list (cons ".*" tmp-style)))))))
;; Go through all styles and look for matches.
- (while styles
- (setq style (pop styles)
- match (pop style))
- (when (cond ((stringp match)
- ;; Regexp string match on the group name.
- (string-match match gnus-newsgroup-name))
- ((or (symbolp match)
- (gnus-functionp match))
- (cond ((gnus-functionp match)
- ;; Function to be called.
- (funcall match))
- ((boundp match)
- ;; Variable to be checked.
- (symbol-value match))))
- ((listp match)
- ;; This is a form to be evaled.
- (eval match)))
+ (dolist (style styles)
+ (setq match (pop style))
+ (when (cond
+ ((stringp match)
+ ;; Regexp string match on the group name.
+ (string-match match group))
+ ((or (symbolp match)
+ (gnus-functionp match))
+ (cond
+ ((gnus-functionp match)
+ ;; Function to be called.
+ (funcall match))
+ ((boundp match)
+ ;; Variable to be checked.
+ (symbol-value match))))
+ ((listp match)
+ ;; This is a form to be evaled.
+ (eval match)))
;; We have a match, so we set the variables.
- (while style
- (setq attribute (pop style)
- value (cadr attribute)
- variable nil)
- ;; We find the variable that is to be modified.
- (if (and (not (stringp (car attribute)))
- (not (eq 'body (car attribute)))
- (not (setq variable
- (cdr (assq (car attribute)
- gnus-posting-style-alist)))))
- (message "Couldn't find attribute %s" (car attribute))
- ;; We get the value.
- (setq value-value
- (cond ((stringp value)
- value)
- ((or (symbolp value)
- (gnus-functionp value))
- (cond ((gnus-functionp value)
- (funcall value))
- ((boundp value)
- (symbol-value value))))
- ((listp value)
- (eval value))))
- (if variable
- ;; This is an ordinary variable.
- (set (make-local-variable variable) value-value)
- ;; This is either a body or a header to be inserted in the
- ;; message.
- (when value-value
- (let ((attr (car attribute)))
- (make-local-variable 'message-setup-hook)
- (if (eq 'body attr)
- (add-hook 'message-setup-hook
- `(lambda ()
- (save-excursion
- (message-goto-body)
- (insert ,value-value))))
- (add-hook 'message-setup-hook
- 'gnus-message-insert-stylings)
- (push (cons (if (stringp attr) attr
- (symbol-name attr))
- value-value)
- gnus-message-style-insertions))))))))))))
-
-(defun gnus-message-insert-stylings ()
- (let (val)
- (save-excursion
- (message-goto-eoh)
- (while (setq val (pop gnus-message-style-insertions))
- (when (cdr val)
- (insert (car val) ": " (cdr val) "\n"))
- (gnus-pull (car val) gnus-message-style-insertions)))))
+ (dolist (attribute style)
+ (setq element (pop attribute)
+ variable nil
+ filep nil)
+ (setq value
+ (cond
+ ((eq (car attribute) :file)
+ (setq filep t)
+ (cadr attribute))
+ ((eq (car attribute) :value)
+ (cadr attribute))
+ (t
+ (car attribute))))
+ ;; We get the value.
+ (setq v
+ (cond
+ ((stringp value)
+ value)
+ ((or (symbolp value)
+ (gnus-functionp value))
+ (cond ((gnus-functionp value)
+ (funcall value))
+ ((boundp value)
+ (symbol-value value))))
+ ((listp value)
+ (eval value))))
+ ;; Translate obsolescent value.
+ (when (eq element 'signature-file)
+ (setq element 'signature
+ filep t))
+ ;; Get the contents of file elems.
+ (when filep
+ (setq v (with-temp-buffer
+ (insert-file-contents v)
+ (buffer-string))))
+ (setq results (delq (assoc element results) results))
+ (push (cons element v) results))))
+ ;; Now we have all the styles, so we insert them.
+ (setq name (assq 'name results)
+ address (assq 'address results))
+ (setq results (delq name (delq address results)))
+ (make-local-variable 'message-setup-hook)
+ (dolist (result results)
+ (when (cdr result)
+ (add-hook 'message-setup-hook
+ (cond
+ ((eq 'body (car result))
+ `(lambda ()
+ (save-excursion
+ (message-goto-body)
+ (insert ,(cdr result)))))
+ ((eq 'signature (car result))
+ (set (make-local-variable 'message-signature) nil)
+ (set (make-local-variable 'message-signature-file) nil)
+ `(lambda ()
+ (save-excursion
+ (let ((message-signature ,(cdr result)))
+ (message-insert-signature)))))
+ (t
+ (let ((header
+ (if (symbolp (car result))
+ (capitalize (symbol-name (car result)))
+ (car result))))
+ `(lambda ()
+ (save-excursion
+ (message-remove-header ,header)
+ (message-goto-eoh)
+ (insert ,header ": " ,(cdr result) "\n")))))))))
+ (when (or name address)
+ (add-hook 'message-setup-hook
+ `(lambda ()
+ (let ((user-full-name ,(or (cdr name) user-full-name))
+ (user-mail-address
+ ,(or (cdr address) user-mail-address)))
+ (save-excursion
+ (message-remove-header "From")
+ (message-goto-eoh)
+ (insert "From: " (message-make-from) "\n")))))))))
;;; Allow redefinition of functions.