* mh-e/mh-comp.el (mh-send-letter):
[bpt/emacs.git] / lisp / mh-e / mh-letter.el
index b9fa528..dcb8d85 100644 (file)
@@ -1,7 +1,8 @@
 ;;; mh-letter.el --- MH-Letter mode
 
 ;; Copyright (C) 1993, 1995, 1997,
-;;  2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+;;   Free Software Foundation, Inc.
 
 ;; Author: Bill Wohler <wohler@newt.com>
 ;; Maintainer: Bill Wohler <wohler@newt.com>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -21,9 +22,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -42,8 +41,9 @@
 
 (require 'gnus-util)
 
-;; Dynamically-created function not found in mh-loaddefs.el.
+;; Dynamically-created functions not found in mh-loaddefs.el.
 (autoload 'mh-tool-bar-letter-buttons-init "mh-tool-bar")
+(autoload 'mh-tool-bar-init "mh-tool-bar")
 
 (autoload 'mml-insert-tag "mml")
 
     (to . mh-alias-letter-expand-alias))
   "Alist of header fields and completion functions to use.")
 
-(defvar mh-hidden-header-keymap
-  (let ((map (make-sparse-keymap)))
-    (mh-do-in-gnu-emacs
-      (define-key map [mouse-2] 'mh-letter-toggle-header-field-display-button))
-    (mh-do-in-xemacs
-      (define-key map '(button2)
-        'mh-letter-toggle-header-field-display-button))
-    map))
-
 (defvar mh-yank-hooks nil
   "Obsolete hook for modifying a citation just inserted in the mail buffer.
 
@@ -276,17 +267,15 @@ searching for `mh-mail-header-separator' in the buffer."
     (goto-char (point-min))
     (cond ((equal mh-mail-header-separator "") (point-min))
           ((search-forward (format "\n%s\n" mh-mail-header-separator) nil t)
-           (line-beginning-position 0))
+           (mh-line-beginning-position 0))
           (t (point-min)))))
 
 \f
 
 ;;; MH-Letter Mode
 
-(defvar mh-letter-buttons-init-flag nil)
-
 ;; Shush compiler.
-(eval-when-compile (mh-do-in-xemacs (defvar font-lock-defaults)))
+(defvar font-lock-defaults)             ; XEmacs
 
 ;; Ensure new buffers won't get this mode if default-major-mode is nil.
 (put 'mh-letter-mode 'mode-class 'special)
@@ -320,15 +309,18 @@ order).
   (make-local-variable 'mh-sent-from-folder)
   (make-local-variable 'mh-sent-from-msg)
   (mh-do-in-gnu-emacs
-   (unless mh-letter-buttons-init-flag
-     (mh-tool-bar-letter-buttons-init)
-     (setq mh-letter-buttons-init-flag t)))
+    (unless mh-letter-tool-bar-map
+      (mh-tool-bar-letter-buttons-init))
+    (if (boundp 'tool-bar-map)
+        (set (make-local-variable 'tool-bar-map) mh-letter-tool-bar-map)))
+  (mh-do-in-xemacs
+    (mh-tool-bar-init :letter))
   ;; Set the local value of mh-mail-header-separator according to what is
   ;; present in the buffer...
   (set (make-local-variable 'mh-mail-header-separator)
        (save-excursion
          (goto-char (mh-mail-header-end))
-         (buffer-substring-no-properties (point) (line-end-position))))
+         (buffer-substring-no-properties (point) (mh-line-end-position))))
   (make-local-variable 'mail-header-separator)
   (setq mail-header-separator mh-mail-header-separator) ;override sendmail.el
   (mh-set-help mh-letter-mode-help-messages)
@@ -337,8 +329,6 @@ order).
 
   ;; Enable undo since a show-mode buffer might have been reused.
   (buffer-enable-undo)
-  (set (make-local-variable 'tool-bar-map) mh-letter-tool-bar-map)
-  (mh-funcall-if-exists mh-tool-bar-init :letter)
   (make-local-variable 'font-lock-defaults)
   (cond
    ((or (equal mh-highlight-citation-style 'font-lock)
@@ -403,24 +393,26 @@ message is not indented, and \"> \" is not inserted before each line.
 This command leaves the mark before the letter and point after it."
   (interactive
    (let* ((folder
-           (mh-prompt-for-folder "Message from"
-                                 mh-sent-from-folder nil))
+           (mh-prompt-for-folder "Message from" mh-sent-from-folder nil))
           (default
-            (if (and (equal folder mh-sent-from-folder)
-                     (numberp mh-sent-from-msg))
-                mh-sent-from-msg
+            (if (equal folder mh-sent-from-folder)
+                (or mh-sent-from-msg (nth 0 (mh-translate-range folder "cur")))
               (nth 0 (mh-translate-range folder "cur"))))
           (message
            (read-string (concat "Message number"
                                 (or (and default
                                          (format " (default %d): " default))
-                                    ": ")))))
+                                    ": "))
+                        nil nil
+                        (if (numberp default)
+                            (int-to-string default)
+                          default))))
      (list folder message current-prefix-arg)))
+  (if (equal message "")
+      (error "No message number given"))
   (save-restriction
     (narrow-to-region (point) (point))
     (let ((start (point-min)))
-      (if (and (equal message "") (numberp mh-sent-from-msg))
-          (setq message (int-to-string mh-sent-from-msg)))
       (insert-file-contents
        (expand-file-name message (mh-expand-file-name folder)))
       (when (not verbatim)
@@ -593,50 +585,6 @@ point to the last field from anywhere in the body."
           (t (goto-char header-end)
              (forward-line)))))
 
-;;;###mh-autoload
-(defun mh-letter-toggle-header-field-display (arg)
-  "Toggle display of header field at point.
-
-Use this command to display truncated header fields. This command
-is a toggle so entering it again will hide the field. This
-command takes a prefix argument ARG: if negative then the field
-is hidden, if positive then the field is displayed."
-  (interactive (list nil))
-  (when (and (mh-in-header-p)
-             (progn
-               (end-of-line)
-               (re-search-backward mh-letter-header-field-regexp nil t)))
-    (let ((buffer-read-only nil)
-          (modified-flag (buffer-modified-p))
-          (begin (point))
-          end)
-      (end-of-line)
-      (setq end (1- (if (re-search-forward "^[^ \t]" nil t)
-                        (match-beginning 0)
-                      (point-max))))
-      (goto-char begin)
-      ;; Make it clickable...
-      (add-text-properties begin end `(keymap ,mh-hidden-header-keymap
-                                       mouse-face highlight))
-      (unwind-protect
-          (cond ((or (and (not arg)
-                          (text-property-any begin end 'invisible 'vanish))
-                     (and (numberp arg) (>= arg 0))
-                     (and (eq arg 'long) (> (line-beginning-position 5) end)))
-                 (remove-text-properties begin end '(invisible nil))
-                 (search-forward ":" (line-end-position) t)
-                 (mh-letter-skip-leading-whitespace-in-header-field))
-                ;; XXX Redesign to make usable by user. Perhaps use a positive
-                ;; numeric prefix to make that many lines visible.
-                ((eq arg 'long)
-                 (end-of-line 4)
-                 (mh-letter-truncate-header-field end)
-                 (beginning-of-line))
-                (t (end-of-line)
-                   (mh-letter-truncate-header-field end)
-                   (beginning-of-line)))
-        (set-buffer-modified-p modified-flag)))))
-
 (defun mh-open-line ()
   "Insert a newline and leave point before it.
 
@@ -670,7 +618,7 @@ a copy of the draft."
                                   mh-default-folder-for-message-function)))
                           "")
                       t)))
-  (let ((last-input-char ?\C-f))
+  (let ((last-input-event ?\C-f))
     (expand-abbrev)
     (save-excursion
       (mh-to-field)
@@ -700,10 +648,10 @@ Create the field if it does not exist.
 Set the mark to point before moving."
   (interactive)
   (expand-abbrev)
-  (let ((target (cdr (or (assoc (char-to-string (logior last-input-char ?`))
+  (let ((target (cdr (or (assoc (char-to-string (logior last-input-event ?`))
                                 mh-to-field-choices)
                          ;; also look for a char for version 4 compat
-                         (assoc (logior last-input-char ?`)
+                         (assoc (logior last-input-event ?`)
                                 mh-to-field-choices))))
         (case-fold-search t))
     (push-mark)
@@ -711,7 +659,7 @@ Set the mark to point before moving."
            (let ((eol (point)))
              (skip-chars-backward " \t")
              (delete-region (point) eol))
-           (if (and (not (eq (logior last-input-char ?`) ?s))
+           (if (and (not (eq (logior last-input-event ?`) ?s))
                     (save-excursion
                       (backward-char 1)
                       (not (looking-at "[:,]"))))
@@ -881,7 +829,7 @@ body."
           ((< (point) (progn
                         (beginning-of-line)
                         (re-search-forward mh-letter-header-field-regexp
-                                           (line-end-position) t)
+                                           (mh-line-end-position) t)
                         (point)))
            (beginning-of-line))
           (t (end-of-line)))
@@ -892,29 +840,11 @@ body."
           (t (goto-char header-end)
              (forward-line)))))
 
-;;;###mh-autoload
-(defun mh-letter-skipped-header-field-p (field)
-  "Check if FIELD is to be skipped."
-  (let ((field (downcase field)))
-    (loop for x in mh-compose-skipped-header-fields
-          when (equal (downcase x) field) return t
-          finally return nil)))
-
-(defun mh-letter-skip-leading-whitespace-in-header-field ()
-  "Skip leading whitespace in a header field.
-If the header field doesn't have at least one space after the
-colon then a space character is added."
-  (let ((need-space t))
-    (while (memq (char-after) '(?\t ?\ ))
-      (forward-char)
-      (setq need-space nil))
-    (when need-space (insert " "))))
-
 ;;;###mh-autoload
 (defun mh-position-on-field (field &optional ignored)
   "Move to the end of the FIELD in the header.
 Move to end of entire header if FIELD not found.
-Returns non-nil iff FIELD was found.
+Returns non-nil if FIELD was found.
 The optional second arg is for pre-version 4 compatibility and is
 IGNORED."
   (cond ((mh-goto-header-field field)
@@ -936,20 +866,17 @@ downcasing the field name."
   "Do folder name completion in Fcc header field."
   (let* ((end (point))
          (beg (mh-beginning-of-word))
-         (folder (buffer-substring beg end))
+         (folder (buffer-substring-no-properties beg end))
          (leading-plus (and (> (length folder) 0) (equal (aref folder 0) ?+)))
-         (last-slash (mh-search-from-end ?/ folder))
-         (prefix (and last-slash (substring folder 0 last-slash)))
-         (choices (mapcar #'(lambda (x)
-                              (list (cond (prefix (format "%s/%s" prefix x))
-                                          (leading-plus (format "+%s" x))
-                                          (t x))))
+         (choices (mapcar (lambda (x) (list x))
                           (mh-folder-completion-function folder nil t))))
+    (unless leading-plus
+      (setq folder (concat "+" folder)))
     (mh-complete-word folder choices beg end)))
 
 ;;;###mh-autoload
 (defun mh-complete-word (word choices begin end)
-  "Complete WORD at from CHOICES.
+  "Complete WORD from CHOICES.
 Any match found replaces the text from BEGIN to END."
   (let ((completion (try-completion word choices))
         (completions-buffer "*Completions*"))
@@ -965,7 +892,7 @@ Any match found replaces the text from BEGIN to END."
            (if (equal word completion)
                (with-output-to-temp-buffer completions-buffer
                  (mh-display-completion-list (all-completions word choices)
-                                             choices))
+                                             word))
              (ignore-errors
                (kill-buffer completions-buffer))
              (delete-region begin end)
@@ -980,6 +907,7 @@ Any match found replaces the text from BEGIN to END."
                   (not (null (string-match "\.vcf$" file))))
              (string-equal "text/x-vcard" (mh-file-mime-type file))))))
 
+;;;###mh-autoload
 (defun mh-letter-toggle-header-field-display-button (event)
   "Toggle header field display at location of EVENT.
 This function does the same thing as
@@ -989,15 +917,6 @@ callable from a mouse button."
   (mh-do-at-event-location event
     (mh-letter-toggle-header-field-display nil)))
 
-(defun mh-letter-truncate-header-field (end)
-  "Replace text from current line till END with an ellipsis.
-If the current line is too long truncate a part of it as well."
-  (let ((max-len (min (window-width) 62)))
-    (when (> (+ (current-column) 4) max-len)
-      (backward-char (- (+ (current-column) 5) max-len)))
-    (when (> end (point))
-      (add-text-properties (point) end '(invisible vanish)))))
-
 (defun mh-extract-from-attribution ()
   "Extract phrase or comment from From header field."
   (save-excursion