* mm-decode.el (mm-dissect-singlepart): Check that the decoder exists.
[gnus] / lisp / message.el
index 0183b87..5569363 100644 (file)
@@ -1,6 +1,6 @@
 ;;; message.el --- composing mail and news messages
 
-;; Copyright (C) 1996-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2012 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: mail, news
@@ -934,7 +934,7 @@ The function `message-setup' runs this hook."
   :type 'hook)
 
 (defcustom message-cancel-hook nil
-  "Hook run when cancelling articles."
+  "Hook run when canceling articles."
   :group 'message-various
   :link '(custom-manual "(message)Various Message Variables")
   :type 'hook)
@@ -1937,14 +1937,14 @@ You must have the \"hashcash\" binary installed, see `hashcash-path'."
   (concat "[a-z0-9][-.a-z0-9]+\\." ;; [hostname.subdomain.]domain.
          ;; valid TLDs:
          "\\([a-z][a-z]\\|" ;; two letter country TDLs
-         "aero\\|arpa\\|bitnet\\|biz\\|bofh\\|"
+         "aero\\|arpa\\|asia\\|bitnet\\|biz\\|bofh\\|"
          "cat\\|com\\|coop\\|edu\\|gov\\|"
          "info\\|int\\|jobs\\|"
          "mil\\|mobi\\|museum\\|name\\|net\\|"
-         "org\\|pro\\|travel\\|uucp\\)")
+         "org\\|pro\\|tel\\|travel\\|uucp\\)")
   ;; http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
   ;; http://en.wikipedia.org/wiki/GTLD
-  ;; `in the process of being approved': .asia .post .tel .sex
+  ;; `approved, but not yet in operation': .xxx
   ;; "dead" nato bitnet uucp
   "Regular expression that matches a valid FQDN."
   ;; see also: gnus-button-valid-fqdn-regexp
@@ -2547,7 +2547,7 @@ Return the number of headers removed."
      (point-max)))
   (goto-char (point-min)))
 
-;; FIXME: clarify diffference: message-narrow-to-head,
+;; FIXME: clarify difference: message-narrow-to-head,
 ;; message-narrow-to-headers-or-head, message-narrow-to-headers
 (defun message-narrow-to-head ()
   "Narrow the buffer to the head of the message.
@@ -3098,66 +3098,79 @@ M-RET    `message-newline-and-reformat' (break the line and reformat)."
 (defun message-goto-to ()
   "Move point to the To header."
   (interactive)
+  (push-mark)
   (message-position-on-field "To"))
 
 (defun message-goto-from ()
   "Move point to the From header."
   (interactive)
+  (push-mark)
   (message-position-on-field "From"))
 
 (defun message-goto-subject ()
   "Move point to the Subject header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Subject"))
 
 (defun message-goto-cc ()
   "Move point to the Cc header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Cc" "To"))
 
 (defun message-goto-bcc ()
   "Move point to the Bcc  header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Bcc" "Cc" "To"))
 
 (defun message-goto-fcc ()
   "Move point to the Fcc header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Fcc" "To" "Newsgroups"))
 
 (defun message-goto-reply-to ()
   "Move point to the Reply-To header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Reply-To" "Subject"))
 
 (defun message-goto-newsgroups ()
   "Move point to the Newsgroups header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Newsgroups"))
 
 (defun message-goto-distribution ()
   "Move point to the Distribution header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Distribution"))
 
 (defun message-goto-followup-to ()
   "Move point to the Followup-To header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Followup-To" "Newsgroups"))
 
 (defun message-goto-mail-followup-to ()
   "Move point to the Mail-Followup-To header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Mail-Followup-To" "To"))
 
 (defun message-goto-keywords ()
   "Move point to the Keywords header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Keywords" "Subject"))
 
 (defun message-goto-summary ()
   "Move point to the Summary header."
   (interactive)
+  (push-mark)
   (message-position-on-field "Summary" "Subject"))
 
 (eval-when-compile
@@ -3178,6 +3191,7 @@ M-RET    `message-newline-and-reformat' (break the line and reformat)."
   (when (and (message-called-interactively-p 'any)
             (looking-at "[ \t]*\n"))
     (expand-abbrev))
+  (push-mark)
   (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)))
@@ -3198,6 +3212,7 @@ M-RET    `message-newline-and-reformat' (break the line and reformat)."
 If there is no signature in the article, go to the end and
 return nil."
   (interactive)
+  (push-mark)
   (goto-char (point-min))
   (if (re-search-forward message-signature-separator nil t)
       (forward-line 1)
@@ -3723,7 +3738,7 @@ However, if `message-yank-prefix' is non-nil, insert that prefix on each line."
       (message-delete-line))
     ;; Delete blank lines at the end of the buffer.
     (goto-char (point-max))
-    (unless (eolp)
+    (unless (eq (preceding-char) ?\n)
       (insert "\n"))
     (while (and (zerop (forward-line -1))
                (looking-at "$"))
@@ -4066,7 +4081,9 @@ The text will also be indented the normal way."
 ;;;
 
 (defun message-send-and-exit (&optional arg)
-  "Send message like `message-send', then, if no errors, exit from mail buffer."
+  "Send message like `message-send', then, if no errors, exit from mail buffer.
+The usage of ARG is defined by the instance that called Message.
+It should typically alter the sending method in some way or other."
   (interactive "P")
   (let ((buf (current-buffer))
        (actions message-exit-actions))
@@ -4451,7 +4468,7 @@ This function could be useful in `message-setup-hook'."
        ;; A simple function.
        ((functionp action)
        (funcall action))
-       ;; Something to be evaled.
+       ;; Something to be evalled.
        (t
        (eval action))))))
 
@@ -4549,7 +4566,8 @@ This function could be useful in `message-setup-hook'."
                   (boundp 'gnus-group-posting-charset-alist))
              (gnus-setup-posting-charset nil)
            message-posting-charset))
-        (headers message-required-mail-headers))
+        (headers message-required-mail-headers)
+        options)
     (when (and message-generate-hashcash
               (not (eq message-generate-hashcash 'opportunistic)))
       (message "Generating hashcash...")
@@ -4588,9 +4606,11 @@ This function could be useful in `message-setup-hook'."
              (error "Failed to send the message")))))
       ;; Let the user do all of the above.
       (run-hooks 'message-header-hook))
+    (setq options message-options)
     (unwind-protect
        (with-current-buffer tembuf
          (erase-buffer)
+         (setq message-options options)
          ;; Avoid copying text props (except hard newlines).
          (insert (with-current-buffer mailbuf
                    (mml-buffer-substring-no-properties-except-hard-newlines
@@ -4672,9 +4692,11 @@ If you always want Gnus to send messages in one piece, set
                (message "Sending via mail...")
                (funcall (or message-send-mail-real-function
                             message-send-mail-function)))
-           (message-send-mail-partially)))
+           (message-send-mail-partially))
+         (setq options message-options))
       (kill-buffer tembuf))
     (set-buffer mailbuf)
+    (setq message-options options)
     (push 'mail message-sent-message-via)))
 
 (defvar sendmail-program)
@@ -4877,7 +4899,7 @@ Otherwise, generate and save a value for `canlock-password' first."
                           (message-fetch-field "Followup-To")))
         ;; BUG: We really need to get the charset for each name in the
         ;; Newsgroups and Followup-To lines to allow crossposting
-        ;; between group namess with incompatible character sets.
+        ;; between group names with incompatible character sets.
         ;; -- Per Abrahamsen <abraham@dina.kvl.dk> 2001-10-08.
         (group-field-charset
          (gnus-group-name-charset method newsgroups-field))
@@ -6206,7 +6228,7 @@ If the current line has `message-yank-prefix', insert it on the new line."
 When sending via news, also check that the REFERENCES are less
 than 988 characters long, and if they are not, trim them until
 they are."
-  ;; 21 is the number suggested by USEAGE.
+  ;; 21 is the number suggested by USAGE.
   (let ((maxcount 21)
        (count 0)
        (cut 2)
@@ -6373,7 +6395,7 @@ between beginning of field and beginning of line."
              (progn
                (gnus-select-frame-set-input-focus (window-frame window))
                (select-window window))
-           (funcall (or switch-function 'switch-to-buffer) buffer)
+           (funcall (or switch-function #'pop-to-buffer) buffer)
            (set-buffer buffer))
          (when (and (buffer-modified-p)
                     (not (prog1
@@ -6381,7 +6403,11 @@ between beginning of field and beginning of line."
                               "Message already being composed; erase? ")
                            (message nil))))
            (error "Message being composed")))
-      (funcall (or switch-function 'switch-to-buffer) name)
+      (funcall (or switch-function
+                  (if (fboundp #'pop-to-buffer-same-window)
+                      #'pop-to-buffer-same-window
+                    #'pop-to-buffer))
+              name)
       (set-buffer name))
     (erase-buffer)
     (message-mode)))
@@ -6402,35 +6428,38 @@ between beginning of field and beginning of line."
   ;; Rename the buffer.
   (if message-send-rename-function
       (funcall message-send-rename-function)
-    ;; Note: mail-abbrevs of XEmacs renames buffer name behind Gnus.
-    (when (string-match
-          "\\`\\*\\(sent \\|unsent \\)?\\(.+\\)\\*[^\\*]*\\|\\`mail to "
-          (buffer-name))
-      (let ((name (match-string 2 (buffer-name)))
-           to group)
-       (if (not (or (null name)
-                    (string-equal name "mail")
-                    (string-equal name "posting")))
-           (setq name (concat "*sent " name "*"))
-         (message-narrow-to-headers)
-         (setq to (message-fetch-field "to"))
-         (setq group (message-fetch-field "newsgroups"))
-         (widen)
-         (setq name
-               (cond
-                (to (concat "*sent mail to "
-                            (or (car (mail-extract-address-components to))
-                                to) "*"))
-                ((and group (not (string= group "")))
-                 (concat "*sent posting on " group "*"))
-                (t "*sent mail*"))))
-       (unless (string-equal name (buffer-name))
-         (rename-buffer name t)))))
+    (message-default-send-rename-function))
   ;; Push the current buffer onto the list.
   (when message-max-buffers
     (setq message-buffer-list
          (nconc message-buffer-list (list (current-buffer))))))
 
+(defun message-default-send-rename-function ()
+  ;; Note: mail-abbrevs of XEmacs renames buffer name behind Gnus.
+  (when (string-match
+        "\\`\\*\\(sent \\|unsent \\)?\\(.+\\)\\*[^\\*]*\\|\\`mail to "
+        (buffer-name))
+    (let ((name (match-string 2 (buffer-name)))
+         to group)
+      (if (not (or (null name)
+                  (string-equal name "mail")
+                  (string-equal name "posting")))
+         (setq name (concat "*sent " name "*"))
+       (message-narrow-to-headers)
+       (setq to (message-fetch-field "to"))
+       (setq group (message-fetch-field "newsgroups"))
+       (widen)
+       (setq name
+             (cond
+              (to (concat "*sent mail to "
+                          (or (car (mail-extract-address-components to))
+                              to) "*"))
+              ((and group (not (string= group "")))
+               (concat "*sent posting on " group "*"))
+              (t "*sent mail*"))))
+      (unless (string-equal name (buffer-name))
+       (rename-buffer name t)))))
+
 (defun message-mail-user-agent ()
   (let ((mua (cond
              ((not message-mail-user-agent) nil)
@@ -7206,7 +7235,7 @@ header line with the old Message-ID."
 
 (defun message-wash-subject (subject)
   "Remove junk like \"Re:\", \"(fwd)\", etc. added to subject string SUBJECT.
-Previous forwarders, replyers, etc. may add it."
+Previous forwarders, repliers, etc. may add it."
   (with-temp-buffer
     (insert subject)
     (goto-char (point-min))
@@ -7470,14 +7499,16 @@ is for the internal use."
       (with-temp-buffer
        (insert-buffer-substring cur)
        (when (setq handles (mm-dissect-buffer t t))
-         (if (and (prog1
-                      (bufferp (car handles))
-                    (mm-destroy-parts handles))
+         (if (and (bufferp (car handles))
                   (equal (mm-handle-media-type handles) "text/plain"))
              (progn
+               (erase-buffer)
+               (insert-buffer-substring (car handles))
                (mm-decode-content-transfer-encoding
                 (mm-handle-encoding handles))
+               (mm-destroy-parts handles)
                (setq handles (mm-uu-dissect)))
+           (mm-destroy-parts handles)
            (setq handles nil))))))
   (when handles
     (prog1
@@ -7766,7 +7797,7 @@ Setter function for custom variables."
                              'message-tool-bar-retro)
   "Specifies the message mode tool bar.
 
-It can be either a list or a symbol refering to a list.  See
+It can be either a list or a symbol referring to a list.  See
 `gmm-tool-bar-from-list' for the format of the list.  The
 default key map is `message-mode-map'.
 
@@ -7927,7 +7958,11 @@ those headers."
                (let ((mail-abbrev-mode-regexp (caar alist)))
                  (not (mail-abbrev-in-expansion-header-p))))
       (setq alist (cdr alist)))
-    (cdar alist)))
+    (when (cdar alist)
+      (lexical-let ((fun (cdar alist)))
+        ;; Even if completion fails, return a non-nil value, so as to avoid
+        ;; falling back to message-tab-body-function.
+        (lambda () (funcall fun) 'completion-attempted)))))
 
 (eval-and-compile
   (condition-case nil