* imap.el: Add compiler directives.
[gnus] / lisp / nnmail.el
index fb0b506..2e19009 100644 (file)
@@ -31,7 +31,6 @@
 (require 'gnus)                                ; for macro gnus-kill-buffer, at least
 (require 'nnheader)
 (require 'message)
-(require 'custom)
 (require 'gnus-util)
 (require 'mail-source)
 (require 'mm-util)
@@ -363,6 +362,70 @@ messages will be shown to indicate the current status."
   :type '(choice (const :tag "infinite" nil)
                  (number :tag "count")))
 
+(define-widget 'nnmail-lazy 'default
+  "Base widget for recursive datastructures.
+
+This is copy of the `lazy' widget in Emacs 21.4 provided for compatibility."
+  :format "%{%t%}: %v"
+  :convert-widget 'widget-value-convert-widget
+  :value-create (lambda (widget)
+                  (let ((value (widget-get widget :value))
+                        (type (widget-get widget :type)))
+                    (widget-put widget :children 
+                                (list (widget-create-child-value 
+                                       widget (widget-convert type) value)))))
+  :value-delete 'widget-children-value-delete
+  :value-get (lambda (widget)
+               (widget-value (car (widget-get widget :children))))
+  :value-inline (lambda (widget)
+                  (widget-apply (car (widget-get widget :children))
+                                :value-inline))
+  :default-get (lambda (widget)
+                 (widget-default-get
+                  (widget-convert (widget-get widget :type))))
+  :match (lambda (widget value)
+           (widget-apply (widget-convert (widget-get widget :type))
+                         :match value))
+  :validate (lambda (widget)
+              (widget-apply (car (widget-get widget :children)) :validate)))
+
+(define-widget 'nnmail-split-fancy 'nnmail-lazy
+  "Widget for customizing splits in the variable of the same name."
+  :tag "Split"
+  :type '(menu-choice :value (any ".*value.*" "misc")
+                      :tag "Type"
+                      (string :tag "Destination")
+                      (list :tag "Use first match (|)" :value (|)
+                            (const :format "" |)
+                            (editable-list :inline t nnmail-split-fancy))
+                      (list :tag "Use all matches (&)" :value (&)
+                            (const :format "" &)
+                            (editable-list :inline t nnmail-split-fancy))
+                      (list :tag "Function with fixed arguments (:)"
+                            :value (:)
+                            (const :format "" :value :)
+                            function 
+                            (editable-list :inline t (sexp :tag "Arg"))
+                            )
+                      (list :tag "Function with split arguments (!)"
+                            :value (!)
+                            (const :format "" !)
+                            function
+                            (editable-list :inline t nnmail-split-fancy))
+                      (list :tag "Field match" 
+                            (choice :tag "Field" 
+                                    regexp symbol)
+                            (choice :tag "Match"
+                                    regexp 
+                                    (symbol :value mail))
+                            (repeat :inline t
+                                    :tag "Restrictions"
+                                    (group :inline t
+                                           (const :format "" -)
+                                           regexp))
+                            nnmail-split-fancy)
+                      (const :tag "Junk (delete mail)" junk)))
+
 (defcustom nnmail-split-fancy "mail.misc"
   "Incoming mail can be split according to this fancy variable.
 To enable this, set `nnmail-split-methods' to `nnmail-split-fancy'.
@@ -403,7 +466,7 @@ FIELD must match a complete field name.  VALUE must match a complete
 word according to the `nnmail-split-fancy-syntax-table' syntax table.
 You can use \".*\" in the regexps to match partial field names or words.
 
-FIELD and VALUE can also be lisp symbols, in that case they are expanded
+FIELD and VALUE can also be Lisp symbols, in that case they are expanded
 as specified in `nnmail-split-abbrev-alist'.
 
 GROUP can contain \\& and \\N which will substitute from matching
@@ -438,8 +501,7 @@ Example:
          ;; Unmatched mail goes to the catch all group.
          \"misc.misc\"))"
   :group 'nnmail-split
-  ;; Sigh!
-  :type 'sexp)
+  :type 'nnmail-split-fancy)
 
 (defcustom nnmail-split-abbrev-alist
   '((any . "from\\|to\\|cc\\|sender\\|apparently-to\\|resent-from\\|resent-to\\|resent-cc")
@@ -604,7 +666,7 @@ nn*-request-list should have been called before calling this function."
     (while (not (eobp))
       (condition-case err
          (progn
-           (narrow-to-region (point) (gnus-point-at-eol))
+           (narrow-to-region (point) (point-at-eol))
            (setq group (read buffer))
            (unless (stringp group)
              (setq group (symbol-name group)))
@@ -1042,7 +1104,7 @@ FUNC will be called with the group name to determine the article number."
        (while (not (eobp))
          (unless (< (move-to-column nnmail-split-header-length-limit)
                     nnmail-split-header-length-limit)
-           (delete-region (point) (gnus-point-at-eol)))
+           (delete-region (point) (point-at-eol)))
          (forward-line 1))
        ;; Allow washing.
        (goto-char (point-min))
@@ -1105,7 +1167,10 @@ FUNC will be called with the group name to determine the article number."
              (unless group-art
                (setq group-art
                      (list (cons (car method)
-                                 (funcall func (car method)))))))))
+                                 (funcall func (car method))))))))
+         ;; Fall back on "bogus" if all else fails.
+         (unless group-art
+           (setq group-art (list (cons "bogus" (funcall func "bogus"))))))
        ;; Produce a trace if non-empty.
        (when (and trace nnmail-split-trace)
          (let ((restore (current-buffer)))
@@ -1241,12 +1306,8 @@ to actually put the message in the right group."
 (defun nnmail-split-fancy ()
   "Fancy splitting method.
 See the documentation for the variable `nnmail-split-fancy' for details."
-  (let ((syntab (syntax-table)))
-    (unwind-protect
-       (progn
-         (set-syntax-table nnmail-split-fancy-syntax-table)
-         (nnmail-split-it nnmail-split-fancy))
-      (set-syntax-table syntab))))
+  (with-syntax-table nnmail-split-fancy-syntax-table
+    (nnmail-split-it nnmail-split-fancy)))
 
 (defvar nnmail-split-cache nil)
 ;; Alist of split expressions their equivalent regexps.
@@ -1492,31 +1553,34 @@ See the documentation for the variable `nnmail-split-fancy' for details."
 (defvar group)
 (defvar group-art-list)
 (defvar group-art)
-(defun nnmail-cache-insert (id grp)
-  (run-hook-with-args 'nnmail-spool-hook 
-                     id grp)
-  (when nnmail-treat-duplicates
-    ;; Store some information about the group this message is written
-    ;; to.  This is passed in as the grp argument -- all locations this
-    ;; has been called from have been checked and the group is available.
-    ;; The only ambiguous case is nnmail-check-duplication which will only
-    ;; pass the first (of possibly >1) group which matches. -Josh
-    (unless (gnus-buffer-live-p nnmail-cache-buffer)
-      (nnmail-cache-open))
-    (save-excursion
-      (set-buffer nnmail-cache-buffer)
-      (goto-char (point-max))
-      (if (and grp (not (string= "" grp))
-              (gnus-methods-equal-p gnus-command-method
-                                    (nnmail-cache-primary-mail-backend)))
-         (let ((regexp (if (consp nnmail-cache-ignore-groups)
-                           (mapconcat 'identity nnmail-cache-ignore-groups
-                                      "\\|")
-                         nnmail-cache-ignore-groups)))
-           (unless (and regexp (string-match regexp grp))
-             (insert id "\t" grp "\n")))
-       (insert id "\n")))))
-
+(defun nnmail-cache-insert (id grp &optional subject sender)
+  (when (stringp id)
+    ;; this will handle cases like `B r' where the group is nil
+    (let ((grp (or grp gnus-newsgroup-name "UNKNOWN")))
+      (run-hook-with-args 'nnmail-spool-hook 
+                         id grp subject sender))
+    (when nnmail-treat-duplicates
+      ;; Store some information about the group this message is written
+      ;; to.  This is passed in as the grp argument -- all locations this
+      ;; has been called from have been checked and the group is available.
+      ;; The only ambiguous case is nnmail-check-duplication which will only
+      ;; pass the first (of possibly >1) group which matches. -Josh
+      (unless (gnus-buffer-live-p nnmail-cache-buffer)
+       (nnmail-cache-open))
+      (save-excursion
+       (set-buffer nnmail-cache-buffer)
+       (goto-char (point-max))
+       (if (and grp (not (string= "" grp))
+                (gnus-methods-equal-p gnus-command-method
+                                      (nnmail-cache-primary-mail-backend)))
+           (let ((regexp (if (consp nnmail-cache-ignore-groups)
+                             (mapconcat 'identity nnmail-cache-ignore-groups
+                                        "\\|")
+                           nnmail-cache-ignore-groups)))
+             (unless (and regexp (string-match regexp grp))
+               (insert id "\t" grp "\n")))
+         (insert id "\n"))))))
+  
 (defun nnmail-cache-primary-mail-backend ()
   (let ((be-list (cons gnus-select-method gnus-secondary-select-methods))
        (be nil)
@@ -1545,7 +1609,7 @@ See the documentation for the variable `nnmail-split-fancy' for details."
        (skip-chars-forward "^\n\r\t")
        (unless (looking-at "[\r\n]")
          (forward-char 1)
-         (buffer-substring (point) (gnus-point-at-eol)))))))
+         (buffer-substring (point) (point-at-eol)))))))
 
 ;; Function for nnmail-split-fancy: look up all references in the
 ;; cache and if a match is found, return that group.