;;; gnus-msg.el --- mail and post interface for Semi-gnus
-;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
+;; Free Software Foundation, Inc.
;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
;; Lars Magne Ingebrigtsen <larsi@gnus.org>
;;; Code:
-(eval-when-compile
- (require 'cl)
- (require 'static))
+(eval-when-compile (require 'cl))
+(eval-when-compile (require 'static))
(require 'gnus)
(require 'gnus-ems)
(require 'message)
(require 'gnus-art)
-(defcustom gnus-post-method nil
+(defcustom gnus-post-method 'current
"*Preferred method for posting USENET news.
If this variable is `current', Gnus will use the \"current\" select
method when posting. If it is nil (which is the default), Gnus will
-use the native posting method of the server.
+use the native select method when posting.
This method will not be used in mail groups and the like, only in
\"real\" newsgroups.
If not nil nor `native', the value must be a valid method as discussed
-in the documentation of `gnus-select-method'. It can also be a list of
-methods. If that is the case, the user will be queried for what select
+in the documentation of `gnus-select-method'. It can also be a list of
+methods. If that is the case, the user will be queried for what select
method to use when posting."
:group 'gnus-group-foreign
:type `(choice (const nil)
"*Alist of styles to use when posting.")
(defcustom gnus-group-posting-charset-alist
- '(("^no\\." iso-8859-1)
- (message-this-is-mail nil)
- ("^de\\." 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")))
+ '(("^\\(no\\|fr\\|dk\\)\\.[^,]*\\(,[ \t\n]*\\(no\\|fr\\|dk\\)\\.[^,]*\\)*$" iso-8859-1 (iso-8859-1))
+ ("^\\(fido7\\|relcom\\)\\.[^,]*\\(,[ \t\n]*\\(fido7\\|relcom\\)\\.[^,]*\\)*$" koi8-r (koi8-r))
+ (message-this-is-mail nil nil)
+ (message-this-is-news nil t))
+ "Alist of regexps and permitted unencoded charsets for posting.
+Each element of the alist has the form (TEST HEADER BODY-LIST), where
+TEST is either a regular expression matching the newsgroup header or a
+variable to query,
+HEADER is the charset which may be left unencoded in the header (nil
+means encode all charsets),
+BODY-LIST is a list of charsets which may be encoded using 8bit
+content-transfer encoding in the body, or one of the special values
+nil (always encode using quoted-printable) or t (always use 8bit).
+
+Note that any value other than nil for HEADER infringes some RFCs, so
+use this option with care."
+ :type '(repeat (list :tag "Permitted unencoded charsets"
+ (choice :tag "Where"
+ (regexp :tag "Group")
+ (const :tag "Mail message" :value message-this-is-mail)
+ (const :tag "News article" :value message-this-is-news))
+ (choice :tag "Header"
+ (const :tag "None" nil)
+ (symbol :tag "Charset"))
+ (choice :tag "Body"
+ (const :tag "Any" :value t)
+ (const :tag "None" :value nil)
+ (repeat :tag "Charsets"
+ (symbol :tag "Charset")))))
:group 'gnus-charset)
;;; Internal variables.
"c" gnus-summary-cancel-article
"s" gnus-summary-supersede-article
"r" gnus-summary-reply
+ "y" gnus-summary-yank-message
"R" gnus-summary-reply-with-original
"w" gnus-summary-wide-reply
"W" gnus-summary-wide-reply-with-original
"\M-c" gnus-summary-mail-crosspost-complaint
"om" gnus-summary-mail-forward
"op" gnus-summary-post-forward
- "Om" gnus-summary-mail-digest
- "Op" gnus-summary-post-digest)
+ "Om" gnus-uu-digest-mail-forward
+ "Op" gnus-uu-digest-post-forward)
(gnus-define-keys (gnus-send-bounce-map "D" gnus-summary-send-map)
"b" gnus-summary-resend-bounced-mail
;; "c" gnus-summary-send-draft
"r" gnus-summary-resend-message)
+;;;###autoload
+(defun gnus-msg-mail (&rest args)
+ "Start editing a mail message to be sent.
+Like `message-mail', but with Gnus paraphernalia, particularly the
+the Gcc: header for archiving purposes."
+ (interactive)
+ (gnus-setup-message 'message
+ (apply 'message-mail args)))
+
+;;;###autoload
+(define-mail-user-agent 'gnus-user-agent
+ 'gnus-msg-mail 'message-send-and-exit
+ 'message-kill-buffer 'message-send-hook)
+
;;; Internal functions.
(defvar gnus-article-reply nil)
(set (make-local-variable 'gnus-message-group-art)
(cons ,group ,article))
(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)
(funcall (car elem) group))
(and (symbolp (car elem))
(symbol-value (car elem))))
- (throw 'found (cadr elem))))))))
+ (throw 'found (cons (cadr elem) (caddr elem)))))))))
(defun gnus-inews-add-send-actions (winconf buffer article)
(make-local-hook 'message-sent-hook)
(gnus-remove-text-with-property 'x-face-mule-bitmap-image)
(insert
(prog1
- (format "%s" (buffer-string))
- (erase-buffer)))
- )
+ (buffer-substring-no-properties (point-min) (point-max))
+ (erase-buffer))))
;; Find the original headers.
(set-buffer gnus-original-article-buffer)
(goto-char (point-min))
(article-buffer 'reply)
(t 'message))
(let* ((group (or group gnus-newsgroup-name))
+ (charset (gnus-group-name-charset nil group))
(pgroup group)
to-address to-group mailing-list to-list
newsgroup-p)
newsgroup-p (gnus-group-find-parameter group 'newsgroup)
mailing-list (when gnus-mailing-list-groups
(string-match gnus-mailing-list-groups group))
- group (gnus-group-real-name group)))
+ group (gnus-group-name-decode (gnus-group-real-name group)
+ charset)))
(if (or (and to-group
(gnus-news-group-p to-group))
newsgroup-p
;; the default method.
((null group-method)
(or (and (null (eq gnus-post-method 'active)) gnus-post-method)
- gnus-select-method message-post-method))
+ gnus-select-method message-post-method))
;; We want the inverse of the default
((and arg (not (eq arg 0)))
(if (eq gnus-post-method 'active)
\f
-(defun gnus-extended-version ()
- "Stringified gnus version."
- (concat gnus-product-name "/" gnus-version-number
- " (based on "
- gnus-original-product-name " v" gnus-original-version-number ")"
- (if (zerop (string-to-number gnus-revision-number))
- ""
- (concat " (revision " gnus-revision-number ")"))
- ))
-
(defun gnus-message-make-user-agent (&optional include-mime-info max-column)
"Return user-agent info.
INCLUDE-MIME-INFO the optional first argument if it is non-nil and the variable
(if full-headers "" message-included-forward-headers)))
(message-forward post))))
-;;; XXX: generate Subject and ``Topics''?
-(defun gnus-summary-mail-digest (&optional n post)
- "Digests and forwards all articles in this series."
- (interactive "P")
- (let ((subject "Digested Articles")
- (articles (gnus-summary-work-articles n))
- article frame)
- (gnus-setup-message 'forward
- (gnus-summary-select-article)
- (if post (message-news nil subject) (message-mail nil subject))
- (when (and message-use-multi-frames (cdr articles))
- (setq frame (window-frame (get-buffer-window (current-buffer)))))
- (message-goto-body)
- (while (setq article (pop articles))
- (save-window-excursion
- (set-buffer gnus-summary-buffer)
- (gnus-summary-select-article nil nil nil article)
- (gnus-summary-remove-process-mark article))
- (when frame
- (select-frame frame))
- (insert (mime-make-tag "message" "rfc822") "\n")
- (insert-buffer-substring gnus-original-article-buffer))
- (push-mark)
- (message-goto-body)
- (mime-edit-enclose-digest-region (point)(mark t)))))
-
-(defun gnus-summary-post-digest (&optional n)
- "Digest and forwards all articles in this series to a newsgroup."
- (interactive "P")
- (gnus-summary-mail-digest n t))
+;;;;; XXX: generate Subject and ``Topics''?
+;;(defun gnus-summary-mail-digest (&optional n post)
+;; "Digests and forwards all articles in this series."
+;; (interactive "P")
+;; (let ((subject "Digested Articles")
+;; (articles (gnus-summary-work-articles n))
+;; article frame)
+;; (gnus-setup-message 'forward
+;; (gnus-summary-select-article)
+;; (if post (message-news nil subject) (message-mail nil subject))
+;; (when (and message-use-multi-frames (cdr articles))
+;; (setq frame (window-frame (get-buffer-window (current-buffer)))))
+;; (message-goto-body)
+;; (while (setq article (pop articles))
+;; (save-window-excursion
+;; (set-buffer gnus-summary-buffer)
+;; (gnus-summary-select-article nil nil nil article)
+;; (gnus-summary-remove-process-mark article))
+;; (when frame
+;; (select-frame frame))
+;; (insert (mime-make-tag "message" "rfc822") "\n")
+;; (insert-buffer-substring gnus-original-article-buffer))
+;; (push-mark)
+;; (message-goto-body)
+;; (mime-edit-enclose-digest-region (point)(mark t)))))
+;;
+;;(defun gnus-summary-post-digest (&optional n)
+;; "Digest and forwards all articles in this series to a newsgroup."
+;; (interactive "P")
+;; (gnus-summary-mail-digest n t))
(defun gnus-summary-resend-message (address n)
"Resend the current article to ADDRESS."
(insert (with-temp-buffer
(gnus-debug)
(buffer-string)))
+ (let (mime-content-types)
+ (mime-edit-insert-tag "text" "plain"))
(goto-char (point-min))
(search-forward "Subject: " nil t)
(message "")))
(when (get-buffer "*Gnus Help Bug*")
(kill-buffer "*Gnus Help Bug*")))
+(defun gnus-summary-yank-message (buffer n)
+ "Yank the current article into a composed message."
+ (interactive
+ (list (completing-read "Buffer: " (mapcar 'list (message-buffers)) nil t)
+ current-prefix-arg))
+ (when (gnus-buffer-live-p buffer)
+ (let ((summary-frame (selected-frame))
+ (message-frame (when (static-if (featurep 'xemacs)
+ (device-on-window-system-p)
+ window-system)
+ (let ((window (get-buffer-window buffer t)))
+ (when window
+ (window-frame window)))))
+ (separator (concat "^" (regexp-quote mail-header-separator)
+ "\n")))
+ (gnus-summary-iterate n
+ (gnus-summary-select-article)
+ (gnus-copy-article-buffer)
+ (when (frame-live-p message-frame)
+ (raise-frame message-frame)
+ (select-frame message-frame))
+ (with-current-buffer buffer
+ (when (save-excursion
+ (beginning-of-line)
+ (let (case-fold-search)
+ (and (not (re-search-backward separator nil t))
+ (re-search-forward separator nil t))))
+ (goto-char (match-end 0)))
+ (message-yank-buffer gnus-article-copy))
+ (select-frame summary-frame))
+ (when (frame-live-p message-frame)
+ (select-frame message-frame)))))
+
(defun gnus-debug ()
"Attempts to go through the Gnus source file and report what variables have been changed.
The source file has to be in the Emacs load path."
(let ((files '("gnus.el" "gnus-sum.el" "gnus-group.el"
"gnus-art.el" "gnus-start.el" "gnus-async.el"
"gnus-msg.el" "gnus-score.el" "gnus-win.el" "gnus-topic.el"
- "nnmail.el" "message.el"))
+ "nnmail.el" "nntp.el" "message.el"))
(point (point))
file expr olist sym)
(gnus-message 4 "Please wait while we snoop your variables...")
(goto-char (point-min))
(while (setq expr (ignore-errors (read (current-buffer))))
(ignore-errors
- (and (or (eq (car expr) 'defvar)
- (eq (car expr) 'defcustom))
+ (and (memq (car expr) '(defvar defcustom defvoo))
(stringp (nth 3 expr))
(or (not (boundp (nth 1 expr)))
(not (equal (eval (nth 2 expr))
(push (nth 1 expr) olist)))))))
(kill-buffer (current-buffer)))
(when (setq olist (nreverse olist))
- (insert "------------------ Environment follows ------------------\n\n"))
+ (insert ";----------------- Environment follows ------------------\n\n"))
(while olist
(if (boundp (car olist))
(condition-case ()
(format "(setq %s 'whatever)\n" (car olist))))
(insert ";; (makeunbound '" (symbol-name (car olist)) ")\n"))
(setq olist (cdr olist)))
- (insert "\n\n")
;; Remove any control chars - they seem to cause trouble for some
;; mailers. (Byte-compiled output from the stuff above.)
(goto-char point)
(while (re-search-forward "[\000-\010\013-\037\200-\237]" nil t)
(replace-match (format "\\%03o" (string-to-char (match-string 0)))
- t t))))
+ t t))
+ ;; Break MIME tags purposely.
+ (goto-char point)
+ (while (re-search-forward mime-edit-tag-regexp nil t)
+ (goto-char (1+ (match-beginning 0)))
+ (insert "X"))))
;;; Treatment of rejected articles.
;;; Bounced mail.
(when gcc
(message-remove-header "gcc")
(widen)
- (setq groups (message-tokenize-header gcc " ,"))
+ (setq groups (message-unquote-tokens
+ (message-tokenize-header gcc " ,")))
;; Copy the article over to some group(s).
(while (setq group (pop groups))
(gnus-check-server
(group (or group gnus-newsgroup-name ""))
(gcc-self-val
(and gnus-newsgroup-name
+ (not (equal gnus-newsgroup-name ""))
(gnus-group-find-parameter
gnus-newsgroup-name 'gcc-self)))
result
;; Go through all styles and look for matches.
(dolist (style styles)
(setq match (pop style))
+ (goto-char (point-min))
(when (cond
((stringp match)
;; Regexp string match on the group name.
(string-match match group))
+ ((eq match 'header)
+ (let ((header (message-fetch-field (pop style))))
+ (and header
+ (string-match (pop style) header))))
((or (symbolp match)
(gnus-functionp match))
(cond
(setq element 'signature
filep t))
;; Get the contents of file elems.
- (when filep
+ (when (and filep v)
(setq v (with-temp-buffer
(insert-file-contents v)
(buffer-string))))
(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 'eval (car result))
- 'ignore)
- ((eq 'body (car result))
+ (add-hook 'message-setup-hook
+ (cond
+ ((eq 'eval (car result))
+ 'ignore)
+ ((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)
+ (if (not (cdr result))
+ 'ignore
`(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)
+ (let ((message-signature ,(cdr result)))
+ (when message-signature
+ (message-insert-signature)))))))
+ (t
+ (let ((header
+ (if (symbolp (car result))
+ (capitalize (symbol-name (car result)))
+ (car result))))
`(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")))))))))
+ (message-remove-header ,header)
+ (let ((value ,(cdr result)))
+ (when value
+ (message-goto-eoh)
+ (insert ,header ": " value "\n"))))))))))
(when (or name address)
(add-hook 'message-setup-hook
`(lambda ()
- (let ((user-full-name ,(or (cdr name) user-full-name))
+ (set (make-local-variable 'user-mail-address)
+ ,(or (cdr address) user-mail-address))
+ (let ((user-full-name ,(or (cdr name) (user-full-name)))
(user-mail-address
,(or (cdr address) user-mail-address)))
(save-excursion