X-Git-Url: http://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fmessage.el;h=d7973c5f7c3a8e87df7296e772f29d1bd939d812;hb=b4bc300f0dcddc2b17bb50a3501ed6e6db1ef12c;hp=f32981fbaa2a08821ce99ee5ec3e4c5f5603fba4;hpb=dbe766e74ab0e0764730d3560b372e3d14b6393c;p=gnus diff --git a/lisp/message.el b/lisp/message.el index f32981fba..d7973c5f7 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -1,6 +1,6 @@ ;;; message.el --- composing mail and news messages -;; Copyright (C) 1996-2012 Free Software Foundation, Inc. +;; Copyright (C) 1996-2014 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: mail, news @@ -268,7 +268,7 @@ This is a list of regexps and regexp matches." :type 'sexp) (defcustom message-ignored-news-headers - "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:" + "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:\\|^X-Message-SMTP-Method:\\|^X-Gnus-Delayed:" "*Regexp of headers to be removed unconditionally before posting." :group 'message-news :group 'message-headers @@ -535,7 +535,7 @@ If t, use `message-user-organization-file'." (setq orgfile f))) orgfile) "*Local news organization file." - :type 'file + :type '(choice (const nil) file) :link '(custom-manual "(message)News Headers") :group 'message-headers) @@ -600,8 +600,10 @@ Done before generating the new subject of a forward." ;; comes back to you (e.g. a mailing-list to which you subscribe, in which ;; case you may be removed from the list on the grounds that mail to you ;; bounced with a "mailing loop" error). - "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:\\|^>?From \\|^Delivered-To:" + "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:\\|^>?From \\|^Delivered-To:\ +\\|^X-Content-Length:\\|^X-UIDL:" "*All headers that match this regexp will be deleted when resending a message." + :version "24.4" :group 'message-interface :link '(custom-manual "(message)Resending") :type '(repeat :value-to-internal (lambda (widget value) @@ -970,6 +972,8 @@ the signature is inserted." (set-keymap-parent map minibuffer-local-map) map) "Keymap for `message-read-from-minibuffer'." + ;; FIXME improve type. + :type '(restricted-sexp :match-alternatives (symbolp keymapp)) :version "22.1" :group 'message-various) @@ -1140,9 +1144,9 @@ e.g. using `gnus-posting-styles': (eval (set (make-local-variable 'message-cite-reply-position) 'above))" :version "24.1" - :type '(choice (const :tag "Reply inline" 'traditional) - (const :tag "Reply above" 'above) - (const :tag "Reply below" 'below)) + :type '(choice (const :tag "Reply inline" traditional) + (const :tag "Reply above" above) + (const :tag "Reply below" below)) :group 'message-insertion) (defcustom message-cite-style nil @@ -1376,11 +1380,11 @@ If nil, you might be asked to input the charset." :type 'symbol) (defcustom message-dont-reply-to-names - (and (boundp 'rmail-dont-reply-to-names) rmail-dont-reply-to-names) + (and (boundp 'mail-dont-reply-to-names) mail-dont-reply-to-names) "*Addresses to prune when doing wide replies. This can be a regexp or a list of regexps. Also, a value of nil means exclude your own user name only." - :version "21.1" + :version "24.3" :group 'message :link '(custom-manual "(message)Wide Reply") :type '(choice (const :tag "Yourself" nil) @@ -1785,7 +1789,7 @@ no, only reply back to the author." (file-error)) (mm-coding-system-p 'utf-8) (executable-find idna-program) - (string= (idna-to-ascii "räksmörgås") + (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. @@ -1977,10 +1981,13 @@ You must have the \"hashcash\" binary installed, see `hashcash-path'." (autoload 'nndraft-request-associate-buffer "nndraft") (autoload 'nndraft-request-expire-articles "nndraft") (autoload 'nnvirtual-find-group-art "nnvirtual") -(autoload 'rmail-dont-reply-to "mail-utils") (autoload 'rmail-msg-is-pruned "rmail") (autoload 'rmail-output "rmailout") +;; Emacs < 24.1 do not have mail-dont-reply-to +(unless (fboundp 'mail-dont-reply-to) + (defalias 'mail-dont-reply-to 'rmail-dont-reply-to)) + ;;; @@ -2647,7 +2654,7 @@ Point is left at the beginning of the narrowed-to region." (interactive) (let ((start (point))) (message-skip-to-next-address) - (kill-region start (point)))) + (kill-region start (if (bolp) (1- (point)) (point))))) (autoload 'Info-goto-node "info") @@ -2978,7 +2985,6 @@ C-c M-n `message-insert-disposition-notification-to' (request receipt). C-c M-m `message-mark-inserted-region' (mark region with enclosing tags). C-c M-f `message-mark-insert-file' (insert file marked with enclosing tags). M-RET `message-newline-and-reformat' (break the line and reformat)." - (setq local-abbrev-table text-mode-abbrev-table) (set (make-local-variable 'message-reply-buffer) nil) (set (make-local-variable 'message-inserted-headers) nil) (set (make-local-variable 'message-send-actions) nil) @@ -3176,22 +3182,10 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." (push-mark) (message-position-on-field "Summary" "Subject")) -(eval-when-compile - (defmacro message-called-interactively-p (kind) - (condition-case nil - (progn - (eval '(called-interactively-p 'any)) - ;; Emacs >=23.2 - `(called-interactively-p ,kind)) - ;; Emacs <23.2 - (wrong-number-of-arguments '(called-interactively-p)) - ;; XEmacs - (void-function '(interactive-p))))) - (defun message-goto-body () "Move point to the beginning of the message body." (interactive) - (when (and (message-called-interactively-p 'any) + (when (and (gmm-called-interactively-p 'any) (looking-at "[ \t]*\n")) (expand-abbrev)) (push-mark) @@ -3201,8 +3195,12 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." (defun message-in-body-p () "Return t if point is in the message body." - (let ((body (save-excursion (message-goto-body)))) - (>= (point) body))) + (>= (point) + (save-excursion + (goto-char (point-min)) + (or (search-forward (concat "\n" mail-header-separator "\n") nil t) + (search-forward-regexp "[^:]+:\\([^\n]\\|\n[ \t]\\)+\n\n" nil t)) + (point)))) (defun message-goto-eoh () "Move point to the end of the headers." @@ -3333,11 +3331,33 @@ or in the synonym headers, defined by `message-header-synonyms'." (defun message-insert-newsgroups () "Insert the Newsgroups header from the article being replied to." (interactive) - (when (and (message-position-on-field "Newsgroups") - (mail-fetch-field "newsgroups") - (not (string-match "\\` *\\'" (mail-fetch-field "newsgroups")))) - (insert ",")) - (insert (or (message-fetch-reply-field "newsgroups") ""))) + (let ((old-newsgroups (mail-fetch-field "newsgroups")) + (new-newsgroups (message-fetch-reply-field "newsgroups")) + (first t) + insert-newsgroups) + (message-position-on-field "Newsgroups") + (cond + ((not new-newsgroups) + (error "No Newsgroups to insert")) + ((not old-newsgroups) + (insert new-newsgroups)) + (t + (setq new-newsgroups (split-string new-newsgroups "[, ]+") + old-newsgroups (split-string old-newsgroups "[, ]+")) + (dolist (group new-newsgroups) + (unless (member group old-newsgroups) + (push group insert-newsgroups))) + (if (null insert-newsgroups) + (error "Newgroup%s already in the header" + (if (> (length new-newsgroups) 1) + "s" "")) + (when old-newsgroups + (setq first nil)) + (dolist (group insert-newsgroups) + (unless first + (insert ",")) + (setq first nil) + (insert group))))))) @@ -3839,7 +3859,9 @@ prefix, and don't delete any headers." (interactive "P") ;; eval the let forms contained in message-cite-style (eval - `(let ,message-cite-style + `(let ,(if (symbolp message-cite-style) + (symbol-value message-cite-style) + message-cite-style) (message--yank-original-internal ',arg)))) (defun message-yank-buffer (buffer) @@ -3855,7 +3877,7 @@ prefix, and don't delete any headers." (save-current-buffer (dolist (buffer (buffer-list t)) (set-buffer buffer) - (when (and (eq major-mode 'message-mode) + (when (and (derived-mode-p 'message-mode) (null message-sent-message-via)) (push (buffer-name buffer) buffers)))) (nreverse buffers))) @@ -3968,18 +3990,19 @@ See `message-citation-line-format'." (let ((i ?A) lst) (when (stringp name) ;; Guess first name and last name: - (cond ((string-match - "\\`\\(\\w\\|[-.]\\)+ \\(\\w\\|[-.]\\)+\\'" name) - (setq fname (nth 0 (split-string name "[ \t]+")) - lname (nth 1 (split-string name "[ \t]+")))) - ((string-match - "\\`\\(\\w\\|[-.]\\)+, \\(\\w\\|[-.]\\)+\\'" name) - (setq fname (nth 1 (split-string name "[ \t,]+")) - lname (nth 0 (split-string name "[ \t,]+")))) - ((string-match - "\\`\\(\\w\\|[-.]\\)+\\'" name) - (setq fname name - lname "")))) + (let* ((names (delq nil (mapcar (lambda (x) + (if (string-match "\\`\\(\\w\\|[-.]\\)+\\'" x) x nil)) + (split-string name "[ \t]+")))) + (count (length names))) + (cond ((= count 1) (setq fname (car names) + lname "")) + ((or (= count 2) (= count 3)) (setq fname (car names) + lname (mapconcat 'identity (cdr names) " "))) + ((> count 3) (setq fname (mapconcat 'identity (butlast names (- count 2)) " ") + lname (mapconcat 'identity (nthcdr 2 names) " "))) ) + (when (string-match "\\(.*\\),\\'" fname) + (let ((newlname (match-string 1 fname))) + (setq fname lname lname newlname))))) ;; The following letters are not used in `format-time-string': (push ?E lst) (push "" lst) (push ?F lst) (push fname lst) @@ -4055,28 +4078,6 @@ This function strips off the signature from the original message." (forward-char -1) nil)))) -(defun message-remove-signature () - "Remove the signature from the text between point and mark. -The text will also be indented the normal way." - (save-excursion - (let ((start (point)) - mark) - (if (not (re-search-forward message-signature-separator (mark t) t)) - ;; No signature here, so we just indent the cited text. - (message-indent-citation) - ;; Find the last non-empty line. - (forward-line -1) - (while (looking-at "[ \t]*$") - (forward-line -1)) - (forward-line 1) - (setq mark (set-marker (make-marker) (point))) - (goto-char start) - (message-indent-citation) - ;; Enable undoing the deletion. - (undo-boundary) - (delete-region mark (mark t)) - (set-marker mark nil))))) - ;;; @@ -4784,7 +4785,9 @@ that instead." (list resend-to-addresses) '("-t")))))) (unless (or (null cpr) (and (numberp cpr) (zerop cpr))) - (if errbuf (pop-to-buffer errbuf)) + (when errbuf + (pop-to-buffer errbuf) + (setq errbuf nil)) (error "Sending...failed with exit value %d" cpr))) (when message-interactive (with-current-buffer errbuf @@ -4883,9 +4886,7 @@ Do not use this for anything important, it is cryptographically weak." (require 'sha1) (let (sha1-maximum-internal-length) (sha1 (concat (message-unique-id) - (format "%x%x%x" (random) - (progn (random t) (random)) - (random)) + (format "%x%x%x" (random) (random) (random)) (prin1-to-string (recent-keys)) (prin1-to-string (garbage-collect)))))) @@ -5588,7 +5589,6 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'." ;; You might for example insert a "." somewhere (not next to another dot ;; or string boundary), or modify the "fsf" string. (defun message-unique-id () - (random t) ;; Don't use microseconds from (current-time), they may be unsupported. ;; Instead we use this randomly inited counter. (setq message-unique-id-char @@ -5849,12 +5849,6 @@ give as trustworthy answer as possible." (concat system-name ".i-did-not-set--mail-host-address--so-tickle-me"))))) -(defun message-make-host-name () - "Return the name of the host." - (let ((fqdn (message-make-fqdn))) - (string-match "^[^.]+\\." fqdn) - (substring fqdn 0 (1- (match-end 0))))) - (defun message-make-domain () "Return the domain name." (or mail-host-address @@ -6171,20 +6165,13 @@ Headers already prepared in the buffer are not modified." (while (and (not (= (point) end)) (or (not (eq char ?,)) quoted)) - (skip-chars-forward "^,\"" (point-max)) + (skip-chars-forward "^,\"" end) (when (eq (setq char (following-char)) ?\") (setq quoted (not quoted))) (unless (= (point) end) (forward-char 1))) (skip-chars-forward " \t\n"))) -(defun message-fill-address (header value) - (insert (capitalize (symbol-name header)) - ": " - (if (consp value) (car value) value) - "\n") - (message-fill-field-address)) - (defun message-split-line () "Split current line, moving portion beyond point vertically down. If the current line has `message-yank-prefix', insert it on the new line." @@ -6215,17 +6202,22 @@ If the current line has `message-yank-prefix', insert it on the new line." (point-max)))) (defun message-fill-field-address () - (while (not (eobp)) - (message-skip-to-next-address) - (let (last) - (if (and (> (current-column) 78) - last) - (progn - (save-excursion - (goto-char last) - (insert "\n\t")) - (setq last (1+ (point)))) - (setq last (1+ (point))))))) + (let (end last) + (while (not end) + (message-skip-to-next-address) + (cond ((bolp) + (end-of-line 0) + (setq end 1)) + ((eobp) + (setq end 0))) + (when (and (> (current-column) 78) + last) + (save-excursion + (goto-char last) + (delete-char (- (skip-chars-backward " \t"))) + (insert "\n\t"))) + (setq last (point))) + (forward-line end))) (defun message-fill-field-general () (let ((begin (point)) @@ -6327,6 +6319,9 @@ they are." :link '(custom-manual "(message)Movement") :type 'boolean) +(defvar visual-line-mode) +(declare-function beginning-of-visual-line "simple" (&optional n)) + (defun message-beginning-of-line (&optional n) "Move point to beginning of header value or to beginning of line. The prefix argument N is passed directly to `beginning-of-line'. @@ -6353,7 +6348,9 @@ between beginning of field and beginning of line." (goto-char (if (and eoh (or (< eoh here) (= bol here))) eoh bol))) - (beginning-of-line n))) + (if (and (boundp 'visual-line-mode) visual-line-mode) + (beginning-of-visual-line n) + (beginning-of-line n)))) (defun message-buffer-name (type &optional to group) "Return a new (unique) buffer name based on TYPE and TO." @@ -6776,11 +6773,16 @@ The function is called with one parameter, a cons cell ..." ", ")) mct (message-fetch-field "mail-copies-to") author (or (message-fetch-field "mail-reply-to") - (message-fetch-field "reply-to") - (message-fetch-field "from") - "") + (message-fetch-field "reply-to")) mft (and message-use-mail-followup-to - (message-fetch-field "mail-followup-to")))) + (message-fetch-field "mail-followup-to"))) + ;; Make sure this message goes to the author if this is a wide + ;; reply, since Reply-To address may be a list address a mailing + ;; list server added. + (when (and wide author) + (setq cc (concat author ", " cc))) + (when (or wide (not author)) + (setq author (or (message-fetch-field "from") "")))) ;; Handle special values of Mail-Copies-To. (when mct @@ -6846,9 +6848,9 @@ want to get rid of this query permanently."))) ;; Squeeze whitespace. (while (string-match "[ \t][ \t]+" recipients) (setq recipients (replace-match " " t t recipients))) - ;; Remove addresses that match `rmail-dont-reply-to-names'. - (let ((rmail-dont-reply-to-names (message-dont-reply-to-names))) - (setq recipients (rmail-dont-reply-to recipients))) + ;; Remove addresses that match `mail-dont-reply-to-names'. + (let ((mail-dont-reply-to-names (message-dont-reply-to-names))) + (setq recipients (mail-dont-reply-to recipients))) ;; Perhaps "Mail-Copies-To: never" removed the only address? (if (string-equal recipients "") (setq recipients author)) @@ -7196,7 +7198,7 @@ If ARG, allow editing of the cancellation message." (erase-buffer) (insert "Newsgroups: " newsgroups "\n" "From: " from "\n" - "Subject: cmsg cancel " message-id "\n" + "Subject: cancel " message-id "\n" "Control: cancel " message-id "\n" (if distribution (concat "Distribution: " distribution "\n") @@ -7427,12 +7429,13 @@ Optional DIGEST will use digest to forward." (dolist (elem ignored) (message-remove-header elem t)))))) -(defun message-forward-make-body-mime (forward-buffer) +(defun message-forward-make-body-mime (forward-buffer &optional beg end) (let ((b (point))) (insert "\n\n<#part type=message/rfc822 disposition=inline raw=t>\n") (save-restriction (narrow-to-region (point) (point)) - (mml-insert-buffer forward-buffer) + (insert-buffer-substring forward-buffer beg end) + (mml-quote-region (point-min) (point-max)) (goto-char (point-min)) (when (looking-at "From ") (replace-match "X-From-Line: ")) @@ -7997,37 +8000,36 @@ those headers." ;; falling back to message-tab-body-function. (lambda () (funcall fun) 'completion-attempted))))) -(eval-and-compile - (condition-case nil - (with-temp-buffer - (let ((standard-output (current-buffer))) - (eval '(display-completion-list nil ""))) - (defalias 'message-display-completion-list 'display-completion-list)) - (error ;; Don't use `wrong-number-of-arguments' here because of XEmacs. - (defun message-display-completion-list (completions &optional ignore) - "Display the list of completions, COMPLETIONS, using `standard-output'." - (display-completion-list completions))))) - (defun message-expand-group () "Expand the group name under point." - (let* ((b (save-excursion - (save-restriction - (narrow-to-region - (save-excursion - (beginning-of-line) - (skip-chars-forward "^:") - (1+ (point))) - (point)) - (skip-chars-backward "^, \t\n") (point)))) - (completion-ignore-case t) - (e (progn (skip-chars-forward "^,\t\n ") (point))) - (hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb))) - (message-completion-in-region e b hashtb))) + (let ((b (save-excursion + (save-restriction + (narrow-to-region + (save-excursion + (beginning-of-line) + (skip-chars-forward "^:") + (1+ (point))) + (point)) + (skip-chars-backward "^, \t\n") (point)))) + (completion-ignore-case t) + (e (progn (skip-chars-forward "^,\t\n ") (point))) + group collection) + (when (and (boundp 'gnus-active-hashtb) + gnus-active-hashtb) + (mapatoms + (lambda (symbol) + (setq group (symbol-name symbol)) + (push (if (string-match "[^\000-\177]" group) + (gnus-group-decoded-name group) + group) + collection)) + gnus-active-hashtb)) + (message-completion-in-region b e collection))) (defalias 'message-completion-in-region (if (fboundp 'completion-in-region) 'completion-in-region - (lambda (e b hashtb) + (lambda (b e hashtb) (let* ((string (buffer-substring b e)) (completions (all-completions string hashtb)) comp) @@ -8052,8 +8054,7 @@ those headers." (let ((buffer-read-only nil)) (erase-buffer) (let ((standard-output (current-buffer))) - (message-display-completion-list (sort completions 'string<) - string)) + (display-completion-list (sort completions 'string<))) (setq buffer-read-only nil) (goto-char (point-min)) (delete-region (point) @@ -8182,7 +8183,7 @@ regexp VARSTR." (if (fboundp 'mail-abbrevs-setup) (let ((minibuffer-setup-hook 'mail-abbrevs-setup) (minibuffer-local-map message-minibuffer-local-map)) - (flet ((mail-abbrev-in-expansion-header-p nil t)) + (gmm-flet ((mail-abbrev-in-expansion-header-p nil t)) (read-from-minibuffer prompt initial-contents))) (let ((minibuffer-setup-hook 'mail-abbrev-minibuffer-setup-hook) (minibuffer-local-map message-minibuffer-local-map)) @@ -8472,7 +8473,7 @@ Used in `message-simplify-recipients'." (run-hooks 'message-load-hook) ;; Local Variables: -;; coding: iso-8859-1 +;; coding: utf-8 ;; End: ;;; message.el ends here