Bind RET and TAB on images for better UX.
[gnus] / lisp / gnus-cus.el
index 8f4ae6f..89b8930 100644 (file)
@@ -1,27 +1,25 @@
 ;;; gnus-cus.el --- customization commands for Gnus
-;;
-;; Copyright (C) 1996, 1999, 2000, 2001, 2002, 2003
-;;        Free Software Foundation, Inc.
+
+;; Copyright (C) 1996, 1999, 2000, 2001, 2002, 2003, 2004,
+;;   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
 ;; Keywords: news
 
 ;; 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
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; 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., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -67,7 +65,7 @@ if that value is non-nil."
     (set (make-local-variable 'widget-push-button-suffix) "")
     (set (make-local-variable 'widget-link-prefix) "")
     (set (make-local-variable 'widget-link-suffix) ""))
-  (gnus-run-hooks 'gnus-custom-mode-hook))
+  (gnus-run-mode-hooks 'gnus-custom-mode-hook))
 
 ;;; Group Customization:
 
@@ -227,8 +225,11 @@ See `gnus-emphasis-alist'.")
                              (const signature-file)
                              (const organization)
                              (const address)
+                             (const x-face-file)
                              (const name)
-                             (const body))
+                             (const body)
+                             (symbol)
+                             (string :tag "Header"))
                      (string :format "%v"))))
      "post style.
 See `gnus-posting-styles'."))
@@ -312,15 +313,15 @@ has been stored locally for at least this many days."
               (const :format "Disable " DISABLE))
        "\nEnable, or disable, agent expiration in this group or topic."
        gnus-agent-cat-enable-expiration)
-      (agent-disable-undownloaded-faces
-       (boolean :tag "Disable Agent Faces")
-       "Have the summary buffer ignore the agent's undownloaded faces.
-These faces, when used, act as a warning that an article has not been
-fetched into either the agent nor the cache.  This is of most use to
-users who use the agent as a cache (i.e. they only operate on articles
-that have been downloaded).  Disable to display normal article faces
-even when the article hasn't been downloaded."
-       gnus-agent-cat-disable-undownloaded-faces))
+      (agent-enable-undownloaded-faces
+       (boolean :tag "Enable Agent Faces")
+       "Have the summary buffer use the agent's undownloaded faces.
+These faces, when enabled, act as a warning that an article has not
+been fetched into either the agent nor the cache.  This is of most use
+to users who use the agent as a cache (i.e. they only operate on
+articles that have been downloaded).  Leave disabled to display normal
+article faces even when the article hasn't been downloaded."
+gnus-agent-cat-enable-undownloaded-faces))
     "Alist of group parameters that are not also topic parameters.
 
 Each entry has the form (NAME TYPE DOC ACCESSOR), where NAME is the
@@ -763,6 +764,67 @@ eh?")))
                                       ,group))))
   widget)
 
+(define-widget 'gnus-score-extra 'group
+  "Edit score entries for extra headers."
+  :convert-widget 'gnus-score-extra-convert)
+
+(defun gnus-score-extra-convert (widget)
+  ;; Set args appropriately.
+  (let* ((tag (widget-get widget :tag))
+        (item `(const :format "" :value ,(downcase tag)))
+        (match '(string :tag "Match"))
+        (score '(choice :tag "Score"
+                        (const :tag "default" nil)
+                        (integer :format "%v"
+                                 :hide-front-space t)))
+        (expire '(choice :tag "Expire"
+                         (const :tag "off" nil)
+                         (integer :format "%v"
+                                  :hide-front-space t)))
+        (type '(choice :tag "Type"
+                       :value s
+                       ;; I should really create a forgiving :match
+                       ;; function for each type below, that only
+                       ;; looked at the first letter.
+                       (const :tag "Regexp" r)
+                       (const :tag "Regexp (fixed case)" R)
+                       (const :tag "Substring" s)
+                       (const :tag "Substring (fixed case)" S)
+                       (const :tag "Exact" e)
+                       (const :tag "Exact (fixed case)" E)
+                       (const :tag "Word" w)
+                       (const :tag "Word (fixed case)" W)
+                       (const :tag "default" nil)))
+        (header (if gnus-extra-headers
+                    (let (name)
+                      `(choice :tag "Header"
+                               ,@(mapcar (lambda (h)
+                                           (setq name (symbol-name h))
+                                           (list 'const :tag name name))
+                                         gnus-extra-headers)
+                               (string :tag "Other" :format "%v")))
+                  '(string :tag "Header")))
+        (group `(group ,match ,score ,expire ,type ,header))
+        (doc (concat (or (widget-get widget :doc)
+                         (concat "Change score based on the " tag
+                                 " header.\n")))))
+    (widget-put
+     widget :args
+     `(,item
+       (repeat :inline t
+              :indent 0
+              :tag ,tag
+              :doc ,doc
+              :format "%t:\n%h%v%i\n\n"
+              (choice :format "%v"
+                      :value ("" nil nil s
+                              ,(if gnus-extra-headers
+                                   (symbol-name (car gnus-extra-headers))
+                                 ""))
+                      ,group
+                      sexp)))))
+  widget)
+
 (defvar gnus-custom-scores)
 (defvar gnus-custom-score-alist)
 
@@ -772,8 +834,8 @@ When called interactively, FILE defaults to the current score file.
 This can be changed using the `\\[gnus-score-change-score-file]' command."
   (interactive (list gnus-current-score-file))
   (unless file
-    (error (format "No score file for %s"
-                  (gnus-group-decoded-name gnus-newsgroup-name))))
+    (error "No score file for %s"
+           (gnus-group-decoded-name gnus-newsgroup-name)))
   (let ((scores (gnus-score-load file))
        (types (mapcar (lambda (entry)
                         `(group :format "%v%h\n"
@@ -819,7 +881,7 @@ if you do all your changes will be lost.  ")
                                     (gnus-score-string :tag "Subject")
                                     (gnus-score-string :tag "References")
                                     (gnus-score-string :tag "Xref")
-                                    (gnus-score-string :tag "Extra")
+                                    (gnus-score-extra :tag "Extra")
                                     (gnus-score-string :tag "Message-ID")
                                     (gnus-score-integer :tag "Lines")
                                     (gnus-score-integer :tag "Chars")
@@ -885,19 +947,18 @@ articles in the thread.
     (gnus-score-set 'touched '(t) alist))
   (bury-buffer))
 
-(eval-when-compile
-  (defvar category-fields nil)
-  (defvar gnus-agent-cat-name)
-  (defvar gnus-agent-cat-score-file)
-  (defvar gnus-agent-cat-length-when-short)
-  (defvar gnus-agent-cat-length-when-long)
-  (defvar gnus-agent-cat-low-score)
-  (defvar gnus-agent-cat-high-score)
-  (defvar gnus-agent-cat-enable-expiration)
-  (defvar gnus-agent-cat-days-until-old)
-  (defvar gnus-agent-cat-predicate)
-  (defvar gnus-agent-cat-groups)
-)
+(defvar category-fields nil)
+(defvar gnus-agent-cat-name)
+(defvar gnus-agent-cat-score-file)
+(defvar gnus-agent-cat-length-when-short)
+(defvar gnus-agent-cat-length-when-long)
+(defvar gnus-agent-cat-low-score)
+(defvar gnus-agent-cat-high-score)
+(defvar gnus-agent-cat-enable-expiration)
+(defvar gnus-agent-cat-days-until-old)
+(defvar gnus-agent-cat-predicate)
+(defvar gnus-agent-cat-groups)
+(defvar gnus-agent-cat-enable-undownloaded-faces)
 
 (defun gnus-trim-whitespace (s)
   (when (string-match "\\`[ \n\t]+" s)
@@ -914,7 +975,8 @@ articles in the thread.
             (val (,field info))
             (deflt (if (,field defaults)
                        (concat " [" (gnus-trim-whitespace
-                                     (pp-to-string (,field defaults))) "]")))
+                                     (gnus-pp-to-string (,field defaults)))
+                               "]")))
             symb)
 
        (if (eq (car type) 'radio)
@@ -928,11 +990,11 @@ articles in the thread.
 
        (if deflt
            (let ((tag (cdr (memq :tag type))))
-             (if (string-match "\n" deflt)
-                 (progn (while (progn (setq deflt (replace-match "\n " t t
-                                                                 deflt))
-                                      (string-match "\n" deflt (match-end 0))))
-                        (setq deflt (concat "\n" deflt))))
+             (when (string-match "\n" deflt)
+              (while (progn (setq deflt (replace-match "\n " t t
+                                                       deflt))
+                            (string-match "\n" deflt (match-end 0))))
+              (setq deflt (concat "\n" deflt)))
 
              (setcar tag (concat (car tag) deflt))))
 
@@ -983,7 +1045,7 @@ articles in the thread.
                    (widgets category-fields))
               (while widgets
                 (let* ((widget (pop widgets))
-                       (value (ignore-errors (widget-value widget))))
+                       (value (condition-case nil (widget-value widget) (error))))
                   (eval `(setf (,(widget-get widget :accessor) ',info)
                                ',value)))))
             (gnus-category-write)
@@ -1012,9 +1074,9 @@ articles in the thread.
       ;; gnus-agent-cat-prepare-category-field as I don't want the
       ;; group list to appear when customizing a topic.
       (widget-insert "\n")
-      
-      (let ((symb 
-             (set 
+
+      (let ((symb
+             (set
               (make-local-variable 'gnus-agent-cat-groups)
               (widget-create
                `(choice
@@ -1044,6 +1106,10 @@ articles in the thread.
       (gnus-agent-cat-prepare-category-field agent-enable-expiration)
       (gnus-agent-cat-prepare-category-field agent-days-until-old)
 
+      (widget-insert "\nVisual Settings ")
+
+      (gnus-agent-cat-prepare-category-field agent-enable-undownloaded-faces)
+
       (use-local-map widget-keymap)
       (widget-setup)
       (buffer-enable-undo))))