;;; message.el --- composing mail and news messages
;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; MORIOKA Tomohiko <morioka@jaist.ac.jp>
;; Keywords: mail, news, MIME
:type 'integer)
(defcustom message-send-rename-function nil
- "*Function called to rename the buffer after sending it."
+ "Function called to rename the buffer after sending it."
:group 'message-buffers
:type 'function)
(const default))
:group 'message-headers)
-(defcustom message-references-generator
- (if (fboundp 'std11-fill-msg-id-list-string)
- (function message-generate-filled-references)
- (function message-generate-folded-references))
- "*Function to generate \"References\" field."
- :type '(radio (function-item message-generate-filled-references)
- (function-item message-generate-folded-references)
- (function-item message-generate-unfolded-references)
- (function :tag "Other"))
- :group 'message-headers)
-
(defcustom message-syntax-checks nil
- ;; Guess this one shouldn't be easy to customize...
+ ; Guess this one shouldn't be easy to customize...
"*Controls what syntax checks should not be performed on outgoing posts.
To disable checking of long signatures, for instance, add
`(signature . disabled)' to this list.
:type '(repeat sexp))
(defcustom message-deletable-headers '(Message-ID Date Lines)
- "*Headers to be deleted if they already exist and were generated by message previously."
+ "Headers to be deleted if they already exist and were generated by message previously."
:group 'message-headers
:type 'sexp)
:group 'message-headers
:type 'regexp)
-(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|X-Trace:\\|X-Complaints-To:\\|Return-Path:\\|^Supersedes:"
+(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:"
"*Header lines matching this regexp will be deleted before posting.
It's best to delete old Path and Date headers before posting to avoid
any confusion."
:group 'message-interface
:type 'regexp)
+(defcustom message-subject-re-regexp "^[ \t]*\\([Rr][Ee]:[ \t]*\\)*[ \t]*"
+ "*Regexp matching \"Re: \" in the subject line."
+ :group 'message-various
+ :type 'regexp)
+
;;;###autoload
(defcustom message-signature-separator "^-- *$"
- "*Regexp matching the signature separator."
+ "Regexp matching the signature separator."
:type 'regexp
:group 'message-various)
(defcustom message-elide-elipsis "\n[...]\n\n"
- "*The string which is inserted for elided text.")
+ "*The string which is inserted for elided text."
+ :type 'string
+ :group 'message-various)
(defcustom message-interactive nil
- "*Non-nil means when sending a message wait for and display errors.
+ "Non-nil means when sending a message wait for and display errors.
nil means let mailer mail back a message to report errors."
:group 'message-sending
:group 'message-mail
:type 'boolean)
(defcustom message-generate-new-buffers t
- "*Non-nil means that a new message buffer will be created whenever `mail-setup' is called.
+ "*Non-nil means that a new message buffer will be created whenever `message-setup' is called.
If this is a function, call that function with three parameters: The type,
the to address and the group name. (Any of these may be nil.) The function
should return the new buffer name."
:type 'file
:group 'message-headers)
-(defcustom message-autosave-directory
- (nnheader-concat message-directory "drafts/")
- "*Directory where Message autosaves buffers.
-If nil, Message won't autosave."
- :group 'message-buffers
- :type 'directory)
-
(defcustom message-forward-start-separator
(concat (mime-make-tag "message" "rfc822") "\n")
"*Delimiter inserted before forwarded messages."
:type 'regexp)
(defcustom message-cancel-message "I am canceling my own article."
- "*Message to be inserted in the cancel message."
+ "Message to be inserted in the cancel message."
:group 'message-interface
:type 'string)
;; Useful to set in site-init.el
;;;###autoload
(defcustom message-send-mail-function 'message-send-mail-with-sendmail
- "*Function to call to send the current buffer as mail.
+ "Function to call to send the current buffer as mail.
The headers should be delimited by a line whose contents match the
variable `mail-header-separator'.
;; 1997-09-29 by MORIOKA Tomohiko
(defcustom message-send-news-function 'message-send-news-with-gnus
- "*Function to call to send the current buffer as news.
+ "Function to call to send the current buffer as news.
The headers should be delimited by a line whose contents match the
variable `mail-header-separator'."
:group 'message-sending
:type 'function)
(defcustom message-reply-to-function nil
- "*Function that should return a list of headers.
+ "Function that should return a list of headers.
This function should pick out addresses from the To, Cc, and From headers
and respond with new To and Cc headers."
:group 'message-interface
:type 'function)
(defcustom message-wide-reply-to-function nil
- "*Function that should return a list of headers.
+ "Function that should return a list of headers.
This function should pick out addresses from the To, Cc, and From headers
and respond with new To and Cc headers."
:group 'message-interface
:type 'function)
(defcustom message-followup-to-function nil
- "*Function that should return a list of headers.
+ "Function that should return a list of headers.
This function should pick out addresses from the To, Cc, and From headers
and respond with new To and Cc headers."
:group 'message-interface
;; qmail-related stuff
(defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject"
- "*Location of the qmail-inject program."
+ "Location of the qmail-inject program."
:group 'message-sending
:type 'file)
(defcustom message-qmail-inject-args nil
- "*Arguments passed to qmail-inject programs.
+ "Arguments passed to qmail-inject programs.
This should be a list of strings, one string for each argument.
For e.g., if you wish to set the envelope sender address so that bounces
((boundp 'gnus-select-method)
gnus-select-method)
(t '(nnspool "")))
- "*Method used to post news."
+ "*Method used to post news.
+Note that when posting from inside Gnus, for instance, this
+variable isn't used."
:group 'message-news
:group 'message-sending
;; This should be the `gnus-select-method' widget, but that might
(defcustom message-setup-hook
'(message-maybe-setup-default-charset turn-on-mime-edit)
- "*Normal hook, run each time a new outgoing message is initialized.
+ "Normal hook, run each time a new outgoing message is initialized.
The function `message-setup' runs this hook."
:group 'message-various
:type 'hook)
(defcustom message-signature-setup-hook nil
- "*Normal hook, run each time a new outgoing message is initialized.
+ "Normal hook, run each time a new outgoing message is initialized.
It is run after the headers have been inserted and before
the signature is inserted."
:group 'message-various
:type 'hook)
(defcustom message-mode-hook nil
- "*Hook run in message mode buffers."
+ "Hook run in message mode buffers."
:group 'message-various
:type 'hook)
(defcustom message-header-hook '(eword-encode-header)
- "*Hook run in a message mode buffer narrowed to the headers."
+ "Hook run in a message mode buffer narrowed to the headers."
:group 'message-various
:type 'hook)
(defcustom message-header-setup-hook nil
- "*Hook called narrowed to the headers when setting up a message
-buffer."
+ "Hook called narrowed to the headers when setting up a message buffer."
:group 'message-various
:type 'hook)
:type 'function)
(defcustom message-expires 14
- "*Number of days before your article expires."
+ "Number of days before your article expires."
:group 'message-news
:group 'message-headers
:link '(custom-manual "(message)News Headers")
:type 'integer)
(defcustom message-user-path nil
- "*If nil, use the NNTP server name in the Path header.
+ "If nil, use the NNTP server name in the Path header.
If stringp, use this; if non-nil, use no host name (user name only)."
:group 'message-news
:group 'message-headers
(define-widget 'message-header-lines 'text
"All header lines must be LFD terminated."
+ :format "%t:%n%v"
:valid-regexp "^\\'"
:error "All header lines must be newline terminated")
The default is `abbrev', which uses mailabbrev. nil switches
mail aliases off.")
+(defcustom message-autosave-directory
+ (nnheader-concat message-directory "drafts/")
+ "*Directory where Message autosaves buffers if Gnus isn't running.
+If nil, Message won't autosave."
+ :group 'message-buffers
+ :type 'directory)
+
;;; Internal variables.
;;; Well, not really internal.
(,(concat "^\\(X-[A-Za-z0-9-]+\\|In-Reply-To\\):" content)
(1 'message-header-name-face)
(2 'message-header-name-face))
- (,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
- 1 'message-separator-face)
+ ,@(if (and mail-header-separator
+ (not (equal mail-header-separator "")))
+ `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
+ 1 'message-separator-face))
+ nil)
(,(concat "^[ \t]*"
"\\([" cite-prefix "]+[" cite-suffix "]*\\)?"
"[:>|}].*")
The cdr of ech entry is a function for applying the face to a region.")
(defcustom message-send-hook nil
- "*Hook run before sending messages."
+ "Hook run before sending messages."
:group 'message-various
:options '(ispell-message)
:type 'hook)
(defcustom message-send-mail-hook nil
- "*Hook run before sending mail messages."
+ "Hook run before sending mail messages."
:group 'message-various
:type 'hook)
(defcustom message-send-news-hook nil
- "*Hook run before sending news messages."
+ "Hook run before sending news messages."
:group 'message-various
:type 'hook)
(defcustom message-sent-hook nil
- "*Hook run after sending messages."
+ "Hook run after sending messages."
:group 'message-various
:type 'hook)
(Lines)
(Expires)
(Message-ID)
- (References . message-fill-header)
+ (References . message-shorten-references)
(X-Mailer)
(X-Newsreader))
"Alist used for formatting headers.")
(autoload 'gnus-output-to-rmail "gnus-util")
(autoload 'mail-abbrev-in-expansion-header-p "mailabbrev")
(autoload 'nndraft-request-associate-buffer "nndraft")
- (autoload 'nndraft-request-expire-articles "nndraft"))
+ (autoload 'nndraft-request-expire-articles "nndraft")
+ (autoload 'gnus-open-server "gnus-int")
+ (autoload 'gnus-request-post "gnus-int")
+ (autoload 'gnus-alive-p "gnus-util")
+ (autoload 'rmail-output "rmail"))
\f
(defun message-fetch-field (header &optional not-all)
"The same as `mail-fetch-field', only remove all newlines."
- (let ((value (mail-fetch-field header nil (not not-all))))
+ (let* ((inhibit-point-motion-hooks t)
+ (value (mail-fetch-field header nil (not not-all))))
(when value
(nnheader-replace-chars-in-string value ?\n ? ))))
(defun message-strip-subject-re (subject)
"Remove \"Re:\" from subject lines."
- (if (string-match "^[Rr][Ee]: *" subject)
+ (if (string-match message-subject-re-regexp subject)
(substring subject (match-end 0))
subject))
If FIRST, only remove the first instance of the header.
Return the number of headers removed."
(goto-char (point-min))
- (let ((regexp (if is-regexp header (concat "^" header ":")))
+ (let ((regexp (if is-regexp header (concat "^" (regexp-quote header) ":")))
(number 0)
(case-fold-search t)
last)
(defun message-news-p ()
"Say whether the current buffer contains a news message."
- (or message-this-is-news
- (save-excursion
- (save-restriction
- (message-narrow-to-headers)
- (and (message-fetch-field "newsgroups")
- (not (message-fetch-field "posted-to")))))))
+ (and (not message-this-is-mail)
+ (or message-this-is-news
+ (save-excursion
+ (save-restriction
+ (message-narrow-to-headers)
+ (and (message-fetch-field "newsgroups")
+ (not (message-fetch-field "posted-to"))))))))
(defun message-mail-p ()
"Say whether the current buffer contains a mail message."
- (or message-this-is-mail
- (save-excursion
- (save-restriction
- (message-narrow-to-headers)
- (or (message-fetch-field "to")
- (message-fetch-field "cc")
- (message-fetch-field "bcc"))))))
+ (and (not message-this-is-news)
+ (or message-this-is-mail
+ (save-excursion
+ (save-restriction
+ (message-narrow-to-headers)
+ (or (message-fetch-field "to")
+ (message-fetch-field "cc")
+ (message-fetch-field "bcc")))))))
(defun message-next-header ()
"Go to the beginning of the next header."
["Spellcheck" ispell-message t]
"----"
["Send Message" message-send-and-exit t]
- ["Abort Message" message-dont-send t]))
+ ["Abort Message" message-dont-send t]
+ ["Kill Message" message-kill-buffer t]))
(easy-menu-define
message-mode-field-menu message-mode-map ""
C-c C-y message-yank-original (insert current message, if any).
C-c C-q message-fill-yanked-message (fill what was yanked).
C-c C-e message-elide-region (elide the text between point and mark).
+C-c C-z message-kill-to-signature (kill the text up to the signature).
C-c C-r message-caesar-buffer-body (rot13 the message body)."
(interactive)
(kill-all-local-variables)
facemenu-remove-face-function t)
(make-local-variable 'paragraph-separate)
(make-local-variable 'paragraph-start)
+ ;; `-- ' precedes the signature. `-----' appears at the start of the
+ ;; lines that delimit forwarded messages.
+ ;; Lines containing just >= 3 dashes, perhaps after whitespace,
+ ;; are also sometimes used and should be separators.
(setq paragraph-start
(concat (regexp-quote mail-header-separator)
- "$\\|[ \t]*[-_][-_][-_]+$\\|"
- "-- $\\|"
- ;;!!! Uhm... shurely this can't be right.
- "[> " (regexp-quote message-yank-prefix) "]+$\\|"
- paragraph-start))
- (setq paragraph-separate
- (concat (regexp-quote mail-header-separator)
- "$\\|[ \t]*[-_][-_][-_]+$\\|"
- "-- $\\|"
- "[> " (regexp-quote message-yank-prefix) "]+$\\|"
- paragraph-separate))
+ "$\\|[ \t]*[a-z0-9A-Z]*>+[ \t]*$\\|[ \t]*$\\|"
+ "-- $\\|---+$\\|"
+ page-delimiter
+ ;;!!! Uhm... shurely this can't be right?
+ "[> " (regexp-quote message-yank-prefix) "]+$"))
+ (setq paragraph-separate paragraph-start)
(make-local-variable 'message-reply-headers)
(setq message-reply-headers nil)
(make-local-variable 'message-newsreader)
(when (eq message-mail-alias-type 'abbrev)
(if (fboundp 'mail-abbrevs-setup)
(mail-abbrevs-setup)
- (funcall (intern "mail-aliases-setup"))))
+ (mail-aliases-setup)))
(message-set-auto-save-file-name)
- (gnus-run-hooks 'text-mode-hook 'message-mode-hook)
(unless (string-match "XEmacs" emacs-version)
(set (make-local-variable 'font-lock-defaults)
- '(message-font-lock-keywords t))))
+ '(message-font-lock-keywords t)))
+ (make-local-variable 'adaptive-fill-regexp)
+ (setq adaptive-fill-regexp
+ (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|" adaptive-fill-regexp))
+ (unless (boundp 'adaptive-fill-first-line-regexp)
+ (setq adaptive-fill-first-line-regexp nil))
+ (make-local-variable 'adaptive-fill-first-line-regexp)
+ (setq adaptive-fill-first-line-regexp
+ (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|"
+ adaptive-fill-first-line-regexp))
+ (run-hooks 'text-mode-hook 'message-mode-hook))
\f
(interactive)
(let ((point (point)))
(message-goto-signature)
- (forward-line -2)
+ (unless (eobp)
+ (forward-line -2))
(kill-region point (point))
(unless (bolp)
(insert "\n"))))
(or (bolp) (insert "\n")))))
(defun message-elide-region (b e)
- "Elide the text between point and mark. An ellipsis (from
-message-elide-elipsis) will be inserted where the text was killed."
+ "Elide the text between point and mark.
+An ellipsis (from `message-elide-elipsis') will be inserted where the
+text was killed."
(interactive "r")
(kill-region b e)
(unless (bolp)
(name-default (concat "*message* " mail-trimmed-to))
(name (if enter-string
(read-string "New buffer name: " name-default)
- name-default))
- (default-directory
- (if message-autosave-directory
- (file-name-as-directory message-autosave-directory)
- default-directory)))
+ name-default)))
(rename-buffer name t)))))
(defun message-fill-yanked-message (&optional justifyp)
(unless (bolp)
(insert ?\n))
(unless modified
- (setq message-checksum (cons (message-checksum) (buffer-size)))))))
+ (setq message-checksum (message-checksum))))))
(defun message-cite-original-without-signature ()
"Cite function in the standard Message manner."
(defun message-dont-send ()
"Don't send the message you have been editing."
(interactive)
+ (set-buffer-modified-p t)
(save-buffer)
(let ((actions message-postpone-actions))
(message-bury (current-buffer))
(let ((inhibit-read-only t))
(put-text-property (point-min) (point-max) 'read-only nil))
(message-fix-before-sending)
- (gnus-run-hooks 'message-send-hook)
+ (run-hooks 'message-send-hook)
(message "Sending...")
(let ((message-encoding-buffer
(message-generate-new-buffer-clone-locals " message encoding"))
(message-do-fcc)
;;(when (fboundp 'mail-hist-put-headers-into-history)
;; (mail-hist-put-headers-into-history))
- (gnus-run-hooks 'message-sent-hook)
+ (run-hooks 'message-sent-hook)
(message "Sending...done")
;; Mark the buffer as unmodified and delete autosave.
(set-buffer-modified-p nil)
t))))
(defun message-send-via-mail (arg)
- "Send the current message via mail."
+ "Send the current message via mail."
(message-send-mail arg))
(defun message-send-via-news (arg)
(if news nil message-deletable-headers)))
(message-generate-headers message-required-mail-headers))
;; Let the user do all of the above.
- (gnus-run-hooks 'message-header-hook))
+ (run-hooks 'message-header-hook))
(unwind-protect
(save-excursion
(set-buffer tembuf)
(replace-match "\n")
(backward-char 1)
(setq delimline (point-marker))
- (gnus-run-hooks 'message-send-mail-hook)
+ (run-hooks 'message-send-mail-hook)
;; Insert an extra newline if we need it to work around
;; Sun's bug that swallows newlines.
(goto-char (1+ delimline))
(re-search-forward
(concat "^" (regexp-quote mail-header-separator) "\n"))
(replace-match "\n")
- (gnus-run-hooks 'message-send-mail-hook)
+ (run-hooks 'message-send-mail-hook)
;; send the message
(case
(let ((coding-system-for-write 'binary))
(concat "^" (symbol-name (car headers)) ": *") nil t)
(message-delete-line))
(pop headers))))
- (gnus-run-hooks 'message-send-mail-hook)
+ (run-hooks 'message-send-mail-hook)
;; Pass it on to mh.
(mh-send-letter)))
;; Insert some headers.
(message-generate-headers message-required-news-headers)
;; Let the user do all of the above.
- (gnus-run-hooks 'message-header-hook))
+ (run-hooks 'message-header-hook))
(message-cleanup-headers)
(if (not (message-check-news-syntax))
(progn
(let* ((case-fold-search t)
(message-id (message-fetch-field "message-id" t)))
(or (not message-id)
+ ;; Is there an @ in the ID?
(and (string-match "@" message-id)
- (string-match "@[^\\.]*\\." message-id))
+ ;; Is there a dot in the ID?
+ (string-match "@[^.]*\\." message-id)
+ ;; Does the ID end with a dot?
+ (not (string-match "\\.>" message-id)))
(y-or-n-p
(format "The Message-ID looks strange: \"%s\". Really post? "
message-id)))))
(message-check 'new-text
(or
(not message-checksum)
- (not (and (eq (message-checksum) (car message-checksum))
- (eq (buffer-size) (cdr message-checksum))))
+ (not (eq (message-checksum) message-checksum))
(y-or-n-p
"It looks like no new text has been added. Really post? ")))
;; Check the length of the signature.
(while (setq file (message-fetch-field "fcc"))
(push file list)
(message-remove-header "fcc" nil t)))
- (gnus-run-hooks 'message-header-hook 'message-before-do-fcc-hook)
+ (run-hooks 'message-header-hook 'message-before-do-fcc-hook)
(goto-char (point-min))
(re-search-forward (concat "^" (regexp-quote mail-header-separator) "$"))
(replace-match "" t t)
(when from
(let ((stop-pos
(string-match " *at \\| *@ \\| *(\\| *<" from)))
- (concat (if stop-pos (substring from 0 stop-pos) from)
+ (concat (if (and stop-pos
+ (not (zerop stop-pos)))
+ (substring from 0 stop-pos) from)
"'s message of \""
(if (or (not date) (string= date ""))
"(unknown date)" date)
(or mail-host-address
(message-make-fqdn)))
-(defun message-generate-filled-references (references message-id)
- "Return filled References field from REFERENCES and MESSAGE-ID."
- (std11-fill-msg-id-list-string (concat references message-id)))
-
-(defun message-generate-folded-references (references message-id)
- "Return folded References field from REFERENCES and MESSAGE-ID."
- (if references
- (let (quote)
- (setq references
- (mapconcat (function
- (lambda (char)
- (cond ((eq char ?\\)
- (setq quote t)
- "\\")
- ((memq char '(?\ ?\t))
- (prog1
- (if quote
- (char-to-string char)
- (concat "\n" (char-to-string char)))
- (setq quote nil)))
- (t
- (setq quote nil)
- (char-to-string char)
- ))))
- references ""))
- (if message-id
- (concat references "\n " message-id)
- references))
- message-id))
-
-(defun message-generate-unfolded-references (references message-id)
- "Return folded References field from REFERENCES and MESSAGE-ID."
- (if references
- (if message-id
- (concat references " " message-id)
- references)
- message-id))
-
(defun message-generate-headers (headers)
"Prepare article HEADERS.
Headers already prepared in the buffer are not modified."
(insert "Original-")
(beginning-of-line))
(when (or (message-news-p)
- (string-match "^[^@]@.+\\..+" secure-sender))
+ (string-match "@.+\\.." secure-sender))
(insert "Sender: " secure-sender "\n")))))))
(defun message-insert-courtesy-copy ()
(widen)
(forward-line 1)))
+(defun message-fill-references (header value)
+ (insert (capitalize (symbol-name header))
+ ": "
+ (std11-fill-msg-id-list-string
+ (if (consp value) (car value) value))
+ "\n"))
+
(defun message-fill-header (header value)
(let ((begin (point))
(fill-column 990)
(replace-match " " t t))
(goto-char (point-max)))))
+(defun message-shorten-references (header references)
+ "Limit REFERENCES to be shorter than 988 characters."
+ (let ((max 988)
+ (cut 4)
+ refs)
+ (nnheader-temp-write nil
+ (insert references)
+ (goto-char (point-min))
+ (while (re-search-forward "<[^>]+>" nil t)
+ (push (match-string 0) refs))
+ (setq refs (nreverse refs))
+ (while (> (length (mapconcat 'identity refs " ")) max)
+ (when (< (length refs) (1+ cut))
+ (decf cut))
+ (setcdr (nthcdr cut refs) (cddr (nthcdr cut refs)))))
+ (insert (capitalize (symbol-name header)) ": "
+ (mapconcat 'identity refs " ") "\n")))
+
(defun message-position-point ()
"Move point to where the user probably wants to find it."
(message-narrow-to-headers)
(delq 'Lines
(delq 'Subject
(copy-sequence message-required-mail-headers))))))
- (gnus-run-hooks 'message-signature-setup-hook)
+ (run-hooks 'message-signature-setup-hook)
(message-insert-signature)
(save-restriction
(message-narrow-to-headers)
- (gnus-run-hooks 'message-header-setup-hook))
+ (run-hooks 'message-header-setup-hook))
(set-buffer-modified-p nil)
(setq buffer-undo-list nil)
- (gnus-run-hooks 'message-setup-hook)
+ (run-hooks 'message-setup-hook)
(message-position-point)
(undo-boundary))
(defun message-set-auto-save-file-name ()
"Associate the message buffer with a file in the drafts directory."
(when message-autosave-directory
- (setq message-draft-article (nndraft-request-associate-buffer "drafts"))
+ (if (gnus-alive-p)
+ (setq message-draft-article
+ (nndraft-request-associate-buffer "drafts"))
+ (setq buffer-file-name (expand-file-name "*message*"
+ message-autosave-directory))
+ (setq buffer-auto-save-file-name (make-auto-save-file-name)))
(clear-visited-file-modtime)))
(defun message-disassociate-draft ()
(Subject . ,(or subject ""))))))
;;;###autoload
-(defun message-reply (&optional to-address wide ignore-reply-to)
+(defun message-reply (&optional to-address wide)
"Start editing a reply to the article in the current buffer."
(interactive)
(let ((cur (current-buffer))
to (message-fetch-field "to")
cc (message-fetch-field "cc")
mct (message-fetch-field "mail-copies-to")
- reply-to (unless ignore-reply-to (message-fetch-field "reply-to"))
+ reply-to (message-fetch-field "reply-to")
references (message-fetch-field "references")
message-id (message-fetch-field "message-id" t))
;; Remove any (buggy) Re:'s that are present and make a
;; proper one.
- (when (string-match "^[ \t]*[Rr][Ee]:[ \t]*" subject)
+ (when (string-match message-subject-re-regexp subject)
(setq subject (substring subject (match-end 0))))
(setq subject (concat "Re: " subject))
`((Subject . ,subject)
,@follow-to
,@(if (or references message-id)
- `((References . ,(funcall message-references-generator
- references message-id))))
- )
+ `((References . ,(concat (or references "") (and references " ")
+ (or message-id ""))))
+ nil))
cur)))
;;;###autoload
-(defun message-wide-reply (&optional to-address ignore-reply-to)
+(defun message-wide-reply (&optional to-address)
"Make a \"wide\" reply to the message in the current buffer."
(interactive)
- (message-reply to-address t ignore-reply-to))
+ (message-reply to-address t))
;;;###autoload
(defun message-followup (&optional to-newsgroups)
(setq distribution nil))
;; Remove any (buggy) Re:'s that are present and make a
;; proper one.
- (when (string-match "^[ \t]*[Rr][Ee]:[ \t]*" subject)
+ (when (string-match message-subject-re-regexp subject)
(setq subject (substring subject (match-end 0))))
(setq subject (concat "Re: " subject))
(widen))
`((Newsgroups . ,newsgroups))))
,@(and distribution (list (cons 'Distribution distribution)))
,@(if (or references message-id)
- `((References . ,(funcall message-references-generator
- references message-id))))
+ `((References . ,(concat (or references "") (and references " ")
+ (or message-id "")))))
,@(when (and mct
(not (equal (downcase mct) "never")))
(list (cons 'Cc (if (equal (downcase mct) "always")
(unless (message-news-p)
(error "This is not a news article; canceling is impossible"))
(when (yes-or-no-p "Do you really want to cancel this article? ")
- (let (from newsgroups message-id distribution buf)
+ (let (from newsgroups message-id distribution buf sender)
(save-excursion
;; Get header info. from original article.
(save-restriction
(message-narrow-to-head)
(setq from (message-fetch-field "from")
+ sender (message-fetch-field "sender")
newsgroups (message-fetch-field "newsgroups")
message-id (message-fetch-field "message-id" t)
distribution (message-fetch-field "distribution")))
;; Make sure that this article was written by the user.
- (unless (string-equal
- (downcase (cadr (std11-extract-address-components from)))
- (downcase (message-make-address)))
+ (unless (or (and sender
+ (string-equal
+ (downcase sender)
+ (downcase (message-make-sender))))
+ (string-equal
+ (downcase (cadr (mail-extract-address-components from)))
+ (downcase (cadr (mail-extract-address-components
+ (message-make-from))))))
(error "This article is not yours"))
;; Make control message.
(setq buf (set-buffer (get-buffer-create " *message cancel*")))
(let ((cur (current-buffer)))
;; Check whether the user owns the article that is to be superseded.
(unless (string-equal
- (downcase (cadr (mail-extract-address-components
- (message-fetch-field "from"))))
- (downcase (message-make-address)))
+ (downcase (or (message-fetch-field "sender")
+ (cadr (mail-extract-address-components
+ (message-fetch-field "from")))))
+ (downcase (message-make-sender)))
(error "This article is not yours"))
;; Get a normal message buffer.
(message-pop-to-buffer (message-buffer-name "supersede"))
(concat "[" (or (message-fetch-field
(if (message-news-p) "newsgroups" "from"))
"(nowhere)")
- "] " (or (message-fetch-field "Subject") "")))))
+ "] " (or (eword-decode-unstructured-field-body
+ (message-fetch-field "Subject") ""))))))
;;;###autoload
(defun message-forward (&optional news)
(goto-char (point-max)))
(insert mail-header-separator)
;; Rename all old ("Also-")Resent headers.
- (while (re-search-backward "^\\(Also-\\)?Resent-" beg t)
+ (while (re-search-backward "^\\(Also-\\)*Resent-" beg t)
(beginning-of-line)
(insert "Also-"))
;; Quote any "From " lines at the beginning.
(same-window-buffer-names nil)
(same-window-regexps nil))
(message-pop-to-buffer (message-buffer-name "mail" to)))
- (message-setup `((To . ,(or to "")) (Subject . ,(or subject "")))))
+ (let ((message-this-is-mail t))
+ (message-setup `((To . ,(or to "")) (Subject . ,(or subject ""))))))
;;;###autoload
(defun message-mail-other-frame (&optional to subject)
(same-window-buffer-names nil)
(same-window-regexps nil))
(message-pop-to-buffer (message-buffer-name "mail" to)))
- (message-setup `((To . ,(or to "")) (Subject . ,(or subject "")))))
+ (let ((message-this-is-mail t))
+ (message-setup `((To . ,(or to "")) (Subject . ,(or subject ""))))))
;;;###autoload
(defun message-news-other-window (&optional newsgroups subject)
(same-window-buffer-names nil)
(same-window-regexps nil))
(message-pop-to-buffer (message-buffer-name "news" nil newsgroups)))
- (message-setup `((Newsgroups . ,(or newsgroups ""))
- (Subject . ,(or subject "")))))
+ (let ((message-this-is-news t))
+ (message-setup `((Newsgroups . ,(or newsgroups ""))
+ (Subject . ,(or subject ""))))))
;;;###autoload
(defun message-news-other-frame (&optional newsgroups subject)
(same-window-buffer-names nil)
(same-window-regexps nil))
(message-pop-to-buffer (message-buffer-name "news" nil newsgroups)))
- (message-setup `((Newsgroups . ,(or newsgroups ""))
- (Subject . ,(or subject "")))))
+ (let ((message-this-is-news t))
+ (message-setup `((Newsgroups . ,(or newsgroups ""))
+ (Subject . ,(or subject ""))))))
;;; underline.el
(point))
(skip-chars-backward "^, \t\n") (point))))
(completion-ignore-case t)
- (string (buffer-substring b (point)))
+ (string (buffer-substring b (progn (skip-chars-forward "^,\t\n ")
+ (point))))
(hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb))
(completions (all-completions string hashtb))
(cur (current-buffer))