(put 'message-mode 'font-lock-defaults '(message-font-lock-keywords t))
(defvar message-face-alist
- '((bold . bold-region)
+ '((bold . message-bold-region)
(underline . underline-region)
(default . (lambda (b e)
- (unbold-region b e)
+ (message-unbold-region b e)
(ununderline-region b e))))
"Alist of mail and news faces for facemenu.
The cdr of each entry is a function for applying the face to a region.")
(integer 1000000)))
(defcustom message-alternative-emails nil
- "A regexp to match the alternative email addresses.
-The first matched address (not primary one) is used in the From field."
+ "*Regexp matching alternative email addresses.
+The first address in the To, Cc or From headers of the original
+article matching this variable is used as the From field of
+outgoing messages.
+
+This variable has precedence over posting styles and anything that runs
+off `message-setup-hook'."
:group 'message-headers
:link '(custom-manual "(message)Message Headers")
:type '(choice (const :tag "Always use primary" nil)
(file-error))
(mm-coding-system-p 'utf-8)
(executable-find idna-program)
- 'ask)
- "Whether to encode non-ASCII in domain names into ASCII according to IDNA."
+ (string= (idna-to-ascii "räksmörgås")
+ "xn--rksmrgs-5wao1o")
+ t)
+ "Whether to encode non-ASCII in domain names into ASCII according to IDNA.
+GNU Libidn, and in particular the elisp package \"idna.el\" and
+the external program \"idn\", must be installed for this
+functionality to work."
:version "22.1"
:group 'message-headers
:link '(custom-manual "(message)IDNA")
;;; Suggested by Jonas Steverud @ www.dtek.chalmers.se/~d4jonas/
-;;;###autoload
(defun message-change-subject (new-subject)
"Ask for NEW-SUBJECT header, append (was: <Old Subject>)."
;; <URL:http://www.landfield.com/usefor/drafts/draft-ietf-usefor-useage--1.02.unpaged>
" (was: "
old-subject ")\n")))))))))
-;;;###autoload
-(defun message-mark-inserted-region (beg end)
+(defun message-mark-inserted-region (beg end &optional verbatim)
"Mark some region in the current article with enclosing tags.
-See `message-mark-insert-begin' and `message-mark-insert-end'."
- (interactive "r")
+See `message-mark-insert-begin' and `message-mark-insert-end'.
+If VERBATIM, use slrn style verbatim marks (\"#v+\" and \"#v-\")."
+ (interactive "r\nP")
(save-excursion
;; add to the end of the region first, otherwise end would be invalid
(goto-char end)
- (insert message-mark-insert-end)
+ (insert (if verbatim "#v-\n" message-mark-insert-end))
(goto-char beg)
- (insert message-mark-insert-begin)))
+ (insert (if verbatim "#v+\n" message-mark-insert-begin))))
-;;;###autoload
-(defun message-mark-insert-file (file)
+(defun message-mark-insert-file (file &optional verbatim)
"Insert FILE at point, marking it with enclosing tags.
-See `message-mark-insert-begin' and `message-mark-insert-end'."
- (interactive "fFile to insert: ")
+See `message-mark-insert-begin' and `message-mark-insert-end'.
+If VERBATIM, use slrn style verbatim marks (\"#v+\" and \"#v-\")."
+ (interactive "fFile to insert: \nP")
;; reverse insertion to get correct result.
(let ((p (point)))
- (insert message-mark-insert-end)
+ (insert (if verbatim "#v-\n" message-mark-insert-end))
(goto-char p)
(insert-file-contents file)
(goto-char p)
- (insert message-mark-insert-begin)))
+ (insert (if verbatim "#v+\n" message-mark-insert-begin))))
-;;;###autoload
(defun message-add-archive-header ()
"Insert \"X-No-Archive: Yes\" in the header and a note in the body.
The note can be customized using `message-archive-note'. When called with a
(message-add-header message-archive-header)
(message-sort-headers)))
-;;;###autoload
(defun message-cross-post-followup-to-header (target-group)
"Mangles FollowUp-To and Newsgroups header to point to TARGET-GROUP.
With prefix-argument just set Follow-Up, don't cross-post."
(insert (concat "\nFollowup-To: " target-group)))
(setq message-cross-post-old-target target-group))
-;;;###autoload
(defun message-cross-post-insert-note (target-group cross-post in-old
old-groups)
"Insert a in message body note about a set Followup or Crosspost.
(insert (concat message-followup-to-note target-group "\n"))
(insert (concat message-cross-post-note target-group "\n")))))
-;;;###autoload
(defun message-cross-post-followup-to (target-group)
"Crossposts message and set Followup-To to TARGET-GROUP.
With prefix-argument just set Follow-Up, don't cross-post."
;;; Reduce To: to Cc: or Bcc: header
-;;;###autoload
(defun message-reduce-to-to-cc ()
"Replace contents of To: header with contents of Cc: or Bcc: header."
(interactive)
(define-key message-mode-map "\C-c\C-fw" 'message-insert-wide-reply)
(define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups)
(define-key message-mode-map "\C-c\C-l" 'message-to-list-only)
+ (define-key message-mode-map "\C-c\C-f\C-e" 'message-insert-expires)
(define-key message-mode-map "\C-c\C-u" 'message-insert-or-toggle-importance)
(define-key message-mode-map "\C-c\M-n"
;; ["Followup-To (with note in body)" message-cross-post-followup-to t]
["Crosspost / Followup-To..." message-cross-post-followup-to t]
["Distribution" message-goto-distribution t]
- ["X-No-Archive:" message-add-archive-header t ]
+ ["Expires" message-insert-expires t ]
+ ["X-No-Archive" message-add-archive-header t ]
"----"
;; (typical) mailing-lists stuff
["Fetch To" message-insert-to
C-c C-f C-f move to Followup-To
C-c C-f C-m move to Mail-Followup-To
C-c C-f c move to Mail-Copies-To
+ C-c C-f C-e move to Expires
C-c C-f C-i cycle through Importance values
C-c C-f s change subject and append \"(was: <Old Subject>)\"
C-c C-f x crossposting with FollowUp-To header and note in body
(if point (goto-char point)))))
(defun message-fill-paragraph (&optional arg)
- "Like `fill-paragraph'."
+ "Message specific function to fill a paragraph.
+This function is used as the value of `fill-paragraph-function' in
+Message buffers and is not meant to be called directly."
(interactive (list (if current-prefix-arg 'full)))
(if (if (boundp 'filladapt-mode) filladapt-mode)
nil
(zerop
(length
(setq to (completing-read
- "Followups to (default: no Followup-To header) "
+ "Followups to (default no Followup-To header): "
(mapcar #'list
(cons "poster"
(message-tokenize-header
(concat "Re: " (message-strip-subject-re subject)))
(t subject)))
+(defun message-insert-expires (days)
+ "Insert the Expires header. Expiry in DAYS days."
+ (interactive "NExpire article in how many days? ")
+ (save-excursion
+ (message-position-on-field "Expires" "X-Draft-From")
+ (insert (message-make-expires-date days))))
+
+(defun message-make-expires-date (days)
+ "Make date string for the Expires header. Expiry in DAYS days.
+
+In posting styles use `(\"Expires\" (make-expires-date 30))'."
+ (let* ((cur (decode-time (current-time)))
+ (nday (+ days (nth 3 cur))))
+ (setf (nth 3 cur) nday)
+ (message-make-date (apply 'encode-time cur))))
+
(defun message-make-message-id ()
"Make a unique Message-ID."
(concat "<" (message-unique-id)
(let ((field (message-fetch-field header))
rhs ace address)
(when field
- (dolist (address (mail-header-parse-addresses field))
- (setq address (car address)
- rhs (downcase (or (cadr (split-string address "@")) ""))
- ace (downcase (idna-to-ascii rhs)))
+ (dolist (rhs
+ (mm-delete-duplicates
+ (mapcar (lambda (rhs) (or (cadr (split-string rhs "@")) ""))
+ (mapcar 'downcase
+ (mapcar
+ 'car (mail-header-parse-addresses field))))))
+ (setq ace (downcase (idna-to-ascii rhs)))
(when (and (not (equal rhs ace))
(or (not (eq message-use-idna 'ask))
- (y-or-n-p (format "Replace %s with %s? " rhs ace))))
+ (y-or-n-p (format "Replace %s with %s in %s:? "
+ rhs ace header))))
(goto-char (point-min))
(while (re-search-forward (concat "^" header ":") nil t)
(message-narrow-to-field)
(message-idna-to-ascii-rhs-1 "From")
(message-idna-to-ascii-rhs-1 "To")
(message-idna-to-ascii-rhs-1 "Reply-To")
+ (message-idna-to-ascii-rhs-1 "Mail-Reply-To")
+ (message-idna-to-ascii-rhs-1 "Mail-Followup-To")
(message-idna-to-ascii-rhs-1 "Cc")))))
(defun message-generate-headers (headers)
(when message-default-mail-headers
(insert message-default-mail-headers)
(or (bolp) (insert ?\n)))
- (save-restriction
- (message-narrow-to-headers)
- (if (and replybuffer
- message-alternative-emails)
- (message-use-alternative-email-as-from)))
(when message-generate-headers-first
(message-generate-headers
(message-headers-to-generate
;; Generate hashcash headers for recipients already known
(mail-add-payment-async))
(run-hooks 'message-setup-hook)
+ ;; Do this last to give it precedence over posting styles, etc.
+ (when (message-mail-p)
+ (save-restriction
+ (message-narrow-to-headers)
+ (if message-alternative-emails
+ (message-use-alternative-email-as-from))))
(message-position-point)
(undo-boundary))
;; This code should be moved to underline.el (from which it is stolen).
;;;###autoload
-(defun bold-region (start end)
+(defun message-bold-region (start end)
"Bold all nonblank characters in the region.
Works by overstriking characters.
Called from program, takes two arguments START and END
(forward-char 1)))))
;;;###autoload
-(defun unbold-region (start end)
+(defun message-unbold-region (start end)
"Remove all boldness (overstruck characters) in the region.
Called from program, takes two arguments START and END
which specify the range to operate on."
(read-string prompt initial-contents))))
(defun message-use-alternative-email-as-from ()
+ "Set From field of the outgoing message to the first matching
+address in `message-alternative-emails', looking at To, Cc and
+From headers in the original article."
(require 'mail-utils)
(let* ((fields '("To" "Cc" "From"))
(emails
emails nil))
(pop emails))
(unless (or (not email) (equal email user-mail-address))
+ (message-remove-header "From")
(goto-char (point-max))
(insert "From: " (let ((user-mail-address email)) (message-make-from))
"\n"))))