Mercurial > hg > xemacs-beta
comparison lisp/gnus/gnus-cus.el @ 98:0d2f883870bc r20-1b1
Import from CVS: tag r20-1b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:13:56 +0200 |
parents | 131b0175ea99 |
children | 8ff55ebd4be9 |
comparison
equal
deleted
inserted
replaced
97:498bf5da1c90 | 98:0d2f883870bc |
---|---|
1 ;;; gnus-cus.el --- User friendly customization of Gnus | 1 ;;; gnus-cus.el --- customization commands for Gnus |
2 ;; Copyright (C) 1995,96 Free Software Foundation, Inc. | |
3 ;; | 2 ;; |
4 ;; Author: Per Abrahamsen <abraham@iesd.auc.dk> | 3 ;; Copyright (C) 1996 Free Software Foundation, Inc. |
5 ;; Keywords: help, news | 4 |
6 ;; Version: 0.1 | 5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> |
6 ;; Keywords: news | |
7 | 7 |
8 ;; This file is part of GNU Emacs. | 8 ;; This file is part of GNU Emacs. |
9 | 9 |
10 ;; GNU Emacs is free software; you can redistribute it and/or modify | 10 ;; GNU Emacs is free software; you can redistribute it and/or modify |
11 ;; it under the terms of the GNU General Public License as published by | 11 ;; it under the terms of the GNU General Public License as published by |
12 ;; the Free Software Foundation; either version 2, or (at your option) | 12 ;; the Free Software Foundation; either version 2, or (at your option) |
13 ;; any later version. | 13 ;; any later version. |
14 | 14 |
15 ;; GNU Emacs is distributed in the hope that it will be useful, | 15 ;; GNU Emacs is distributed in the hope that it will be useful, |
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 ;; GNU General Public License for more details. | 18 ;; GNU General Public License for more details. |
19 | 19 |
20 ;; You should have received a copy of the GNU General Public License | 20 ;; You should have received a copy of the GNU General Public License |
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the | 21 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
24 | 24 |
25 ;;; Commentary: | 25 ;;; Commentary: |
26 | 26 |
27 ;;; Code: | 27 ;;; Code: |
28 | 28 |
29 (require 'custom) | 29 (require 'widget-edit) |
30 (require 'gnus-ems) | 30 (require 'gnus-score) |
31 (require 'browse-url) | 31 |
32 (eval-when-compile (require 'cl)) | 32 ;;; Widgets: |
33 | 33 |
34 ;; The following is just helper functions and data, not meant to be set | 34 ;; There should be special validation for this. |
35 ;; by the user. | 35 (define-widget 'gnus-email-address 'string |
36 (defun gnus-make-face (color) | 36 "An email address") |
37 ;; Create entry for face with COLOR. | 37 |
38 (custom-face-lookup color nil nil nil nil nil)) | 38 (defun gnus-custom-mode () |
39 | 39 "Major mode for editing Gnus customization buffers. |
40 (defvar gnus-face-light-name-list | 40 |
41 '("light blue" "light cyan" "light yellow" "light pink" | 41 The following commands are available: |
42 "pale green" "beige" "orange" "magenta" "violet" "medium purple" | 42 |
43 "turquoise")) | 43 \\[widget-forward] Move to next button or editable field. |
44 | 44 \\[widget-backward] Move to previous button or editable field. |
45 (defvar gnus-face-dark-name-list | 45 \\[widget-button-click] Activate button under the mouse pointer. |
46 '("dark blue" "firebrick" "dark green" "OrangeRed" | 46 \\[widget-button-press] Activate button under point. |
47 "dark khaki" "dark violet" "SteelBlue4")) | 47 |
48 ; CornflowerBlue SeaGreen OrangeRed SteelBlue4 DeepPink3 | 48 Entry to this mode calls the value of `gnus-custom-mode-hook' |
49 ; DarkOlviveGreen4 | 49 if that value is non-nil." |
50 | 50 (kill-all-local-variables) |
51 (custom-declare '() | 51 (setq major-mode 'gnus-custom-mode |
52 '((tag . "Gnus") | 52 mode-name "Gnus Customize") |
53 (doc . "\ | 53 (use-local-map widget-keymap) |
54 The coffee-brewing, all singing, all dancing, kitchen sink newsreader.") | 54 (run-hooks 'gnus-custom-mode-hook)) |
55 (type . group) | 55 |
56 (data | 56 ;;; Group Customization: |
57 ((tag . "Visual") | 57 |
58 (doc . "\ | 58 (defconst gnus-group-parameters |
59 Gnus can be made colorful and fun or grey and dull as you wish.") | 59 '((to-address (gnus-email-address :tag "To Address") "\ |
60 (type . group) | 60 This will be used when doing followups and posts. |
61 (data | 61 |
62 ((tag . "Visual") | 62 This is primarily useful in mail groups that represent closed |
63 (doc . "Enable visual features. | 63 mailing lists--mailing lists where it's expected that everybody that |
64 If `visual' is disabled, there will be no menus and few faces. Most of | 64 writes to the mailing list is subscribed to it. Since using this |
65 the visual customization options below will be ignored. Gnus will use | 65 parameter ensures that the mail only goes to the mailing list itself, |
66 less space and be faster as a result.") | 66 it means that members won't receive two copies of your followups. |
67 (default . | 67 |
68 (summary-highlight group-highlight | 68 Using `to-address' will actually work whether the group is foreign or |
69 article-highlight | 69 not. Let's say there's a group on the server that is called |
70 mouse-face | 70 `fa.4ad-l'. This is a real newsgroup, but the server has gotten the |
71 summary-menu group-menu article-menu | 71 articles from a mail-to-news gateway. Posting directly to this group |
72 tree-highlight menu highlight | 72 is therefore impossible--you have to send mail to the mailing list |
73 browse-menu server-menu | 73 address instead.") |
74 page-marker tree-menu binary-menu pick-menu | 74 |
75 grouplens-menu)) | 75 (to-list (gnus-email-address :tag "To List") "\ |
76 (name . gnus-visual) | 76 This address will be used when doing a `a' in the group. |
77 (type . sexp)) | 77 |
78 ((tag . "WWW Browser") | 78 It is totally ignored when doing a followup--except that if it is |
79 (doc . "\ | 79 present in a news group, you'll get mail group semantics when doing |
80 WWW Browser to call when clicking on an URL button in the article buffer. | 80 `f'.") |
81 | 81 |
82 You can choose between one of the predefined browsers, or `Other'.") | 82 (broken-reply-to (const :tag "Broken Reply To" t) "\ |
83 (name . browse-url-browser-function) | 83 Ignore `Reply-To' headers in this group. |
84 (calculate . (cond ((boundp 'browse-url-browser-function) | 84 |
85 browse-url-browser-function) | 85 That can be useful if you're reading a mailing list group where the |
86 ((fboundp 'w3-fetch) | 86 listserv has inserted `Reply-To' headers that point back to the |
87 'w3-fetch) | 87 listserv itself. This is broken behavior. So there!") |
88 ((eq window-system 'x) | 88 |
89 'gnus-netscape-open-url))) | 89 (to-group (string :tag "To Group") "\ |
90 (type . choice) | 90 All posts will be send to the specified group.") |
91 (data | 91 |
92 ((tag . "W3") | 92 (gcc-self (choice :tag "GCC" |
93 (type . const) | 93 :value t |
94 (default . w3-fetch)) | 94 (const t) |
95 ((tag . "Netscape") | 95 (const none) |
96 (type . const) | 96 (string :format "%v" :hide-front-space t)) "\ |
97 (default . browse-url-netscape)) | 97 Specify default value for GCC header. |
98 ((prompt . "Other") | 98 |
99 (doc . "\ | 99 If this symbol is present in the group parameter list and set to `t', |
100 You must specify the name of a Lisp function here. The lisp function | 100 new composed messages will be `Gcc''d to the current group. If it is |
101 should open a WWW browser when called with an URL (a string). | 101 present and set to `none', no `Gcc:' header will be generated, if it |
102 is present and a string, this string will be inserted literally as a | |
103 `gcc' header (this symbol takes precedence over any default `Gcc' | |
104 rules as described later).") | |
105 | |
106 (auto-expire (const :tag "Automatic Expire" t) "\ | |
107 All articles that are read will be marked as expirable.") | |
108 | |
109 (total-expire (const :tag "Total Expire" t) "\ | |
110 All read articles will be put through the expiry process | |
111 | |
112 This happens even if they are not marked as expirable. | |
113 Use with caution.") | |
114 | |
115 (expiry-wait (choice :tag "Expire Wait" | |
116 :value never | |
117 (const never) | |
118 (const immediate) | |
119 (number :hide-front-space t | |
120 :format "%v")) "\ | |
121 When to expire. | |
122 | |
123 Overrides any `nnmail-expiry-wait' and `nnmail-expiry-wait-function' | |
124 when expiring expirable messages. The value can either be a number of | |
125 days (not necessarily an integer) or the symbols `never' or | |
126 `immediate'.") | |
127 | |
128 (score-file (file :tag "Score File") "\ | |
129 Make the specified file into the current score file. | |
130 This means that all score commands you issue will end up in this file.") | |
131 | |
132 (adapt-file (file :tag "Adapt File") "\ | |
133 Make the specified file into the current adaptive file. | |
134 All adaptive score entries will be put into this file.") | |
135 | |
136 (admin-address (gnus-email-address :tag "Admin Address") "\ | |
137 Administration address for a mailing list. | |
138 | |
139 When unsubscribing to a mailing list you should never send the | |
140 unsubscription notice to the mailing list itself. Instead, you'd | |
141 send messages to the administrative address. This parameter allows | |
142 you to put the admin address somewhere convenient.") | |
143 | |
144 (display (choice :tag "Display" | |
145 :value default | |
146 (const all) | |
147 (const default)) "\ | |
148 Which articles to display on entering the group. | |
149 | |
150 `all' | |
151 Display all articles, both read and unread. | |
152 | |
153 `default' | |
154 Display the default visible articles, which normally includes | |
155 unread and ticked articles.") | |
156 | |
157 (comment (string :tag "Comment") "\ | |
158 An arbitrary comment on the group.")) | |
159 "Alist of valid group parameters. | |
160 | |
161 Each entry has the form (NAME TYPE DOC), where NAME is the parameter | |
162 itself (a symbol), TYPE is the parameters type (a sexp widget), and | |
163 DOC is a documentation string for the parameter.") | |
164 | |
165 (defvar gnus-custom-params) | |
166 (defvar gnus-custom-method) | |
167 (defvar gnus-custom-group) | |
168 | |
169 (defun gnus-group-customize (group &optional part) | |
170 "Edit the group on the current line." | |
171 (interactive (list (gnus-group-group-name))) | |
172 (let ((part (or part 'info)) | |
173 info | |
174 (types (mapcar (lambda (entry) | |
175 `(cons :format "%v%h\n" | |
176 :doc ,(nth 2 entry) | |
177 (const :format "" ,(nth 0 entry)) | |
178 ,(nth 1 entry))) | |
179 gnus-group-parameters))) | |
180 (unless group | |
181 (error "No group on current line")) | |
182 (unless (setq info (gnus-get-info group)) | |
183 (error "Killed group; can't be edited")) | |
184 ;; Ready. | |
185 (kill-buffer (get-buffer-create "*Gnus Customize*")) | |
186 (switch-to-buffer (get-buffer-create "*Gnus Customize*")) | |
187 (gnus-custom-mode) | |
188 (make-local-variable 'gnus-custom-group) | |
189 (setq gnus-custom-group group) | |
190 (widget-insert "Customize the ") | |
191 (widget-create 'info-link | |
192 :help-echo "Push me to learn more." | |
193 :tag "group parameters" | |
194 "(gnus)Group Parameters") | |
195 (widget-insert " for <") | |
196 (widget-insert group) | |
197 (widget-insert "> and press ") | |
198 (widget-create 'push-button | |
199 :tag "done" | |
200 :help-echo "Push me when done customizing." | |
201 :action 'gnus-group-customize-done) | |
202 (widget-insert ".\n\n") | |
203 (make-local-variable 'gnus-custom-params) | |
204 (setq gnus-custom-params | |
205 (widget-create 'group | |
206 :value (gnus-info-params info) | |
207 `(set :inline t | |
208 :greedy t | |
209 :tag "Parameters" | |
210 :format "%t:\n%h%v" | |
211 :doc "\ | |
212 These special paramerters are recognized by Gnus. | |
213 Check the [ ] for the parameters you want to apply to this group, then | |
214 edit the value to suit your taste." | |
215 ,@types) | |
216 '(repeat :inline t | |
217 :tag "Variables" | |
218 :format "%t:\n%h%v%i\n\n" | |
219 :doc "\ | |
220 Set variables local to the group you are entering. | |
221 | |
222 If you want to turn threading off in `news.answers', you could put | |
223 `(gnus-show-threads nil)' in the group parameters of that group. | |
224 `gnus-show-threads' will be made into a local variable in the summary | |
225 buffer you enter, and the form `nil' will be `eval'ed there. | |
226 | |
227 This can also be used as a group-specific hook function, if you'd | |
228 like. If you want to hear a beep when you enter a group, you could | |
229 put something like `(dummy-variable (ding))' in the parameters of that | |
230 group. `dummy-variable' will be set to the result of the `(ding)' | |
231 form, but who cares?" | |
232 (group :value (nil nil) | |
233 (symbol :tag "Variable") | |
234 (sexp :tag | |
235 "Value"))) | |
236 | |
237 '(repeat :inline t | |
238 :tag "Unknown entries" | |
239 sexp))) | |
240 (widget-insert "\n\nYou can also edit the ") | |
241 (widget-create 'info-link | |
242 :tag "select method" | |
243 :help-echo "Push me to learn more about select methods." | |
244 "(gnus)Select Methods") | |
245 (widget-insert " for the group.\n") | |
246 (setq gnus-custom-method | |
247 (widget-create 'sexp | |
248 :tag "Method" | |
249 :value (gnus-info-method info))) | |
250 (use-local-map widget-keymap) | |
251 (widget-setup))) | |
252 | |
253 (defun gnus-group-customize-done (&rest ignore) | |
254 "Apply changes and bury the buffer." | |
255 (interactive) | |
256 (gnus-group-edit-group-done 'params gnus-custom-group | |
257 (widget-value gnus-custom-params)) | |
258 (gnus-group-edit-group-done 'method gnus-custom-group | |
259 (widget-value gnus-custom-method)) | |
260 (bury-buffer)) | |
261 | |
262 ;;; Score Customization: | |
263 | |
264 (defconst gnus-score-parameters | |
265 '((mark (number :tag "Mark") "\ | |
266 The value of this entry should be a number. | |
267 Any articles with a score lower than this number will be marked as read.") | |
268 | |
269 (expunge (number :tag "Expunge") "\ | |
270 The value of this entry should be a number. | |
271 Any articles with a score lower than this number will be removed from | |
272 the summary buffer.") | |
273 | |
274 (mark-and-expunge (number :tag "Mark-and-expunge") "\ | |
275 The value of this entry should be a number. | |
276 Any articles with a score lower than this number will be marked as | |
277 read and removed from the summary buffer.") | |
278 | |
279 (thread-mark-and-expunge (number :tag "Thread-mark-and-expunge") "\ | |
280 The value of this entry should be a number. | |
281 All articles that belong to a thread that has a total score below this | |
282 number will be marked as read and removed from the summary buffer. | |
283 `gnus-thread-score-function' says how to compute the total score | |
284 for a thread.") | |
285 | |
286 (files (repeat :tag "Files" file) "\ | |
287 The value of this entry should be any number of file names. | |
288 These files are assumed to be score files as well, and will be loaded | |
289 the same way this one was.") | |
290 | |
291 (exclude-files (repeat :tag "Exclude-files" file) "\ | |
292 The clue of this entry should be any number of files. | |
293 These files will not be loaded, even though they would normally be so, | |
294 for some reason or other.") | |
295 | |
296 (eval (sexp :tag "Eval" :value nil) "\ | |
297 The value of this entry will be `eval'el. | |
298 This element will be ignored when handling global score files.") | |
299 | |
300 (read-only (boolean :tag "Read-only" :value t) "\ | |
301 Read-only score files will not be updated or saved. | |
302 Global score files should feature this atom.") | |
303 | |
304 (orphan (number :tag "Orphan") "\ | |
305 The value of this entry should be a number. | |
306 Articles that do not have parents will get this number added to their | |
307 scores. Imagine you follow some high-volume newsgroup, like | |
308 `comp.lang.c'. Most likely you will only follow a few of the threads, | |
309 also want to see any new threads. | |
310 | |
311 You can do this with the following two score file entries: | |
312 | |
313 (orphan -500) | |
314 (mark-and-expunge -100) | |
315 | |
316 When you enter the group the first time, you will only see the new | |
317 threads. You then raise the score of the threads that you find | |
318 interesting (with `I T' or `I S'), and ignore (`C y') the rest. | |
319 Next time you enter the group, you will see new articles in the | |
320 interesting threads, plus any new threads. | |
321 | |
322 I.e.---the orphan score atom is for high-volume groups where there | |
323 exist a few interesting threads which can't be found automatically | |
324 by ordinary scoring rules.") | |
325 | |
326 (adapt (choice :tag "Adapt" | |
327 (const t) | |
328 (const ignore) | |
329 (sexp :format "%v" | |
330 :hide-front-space t)) "\ | |
331 This entry controls the adaptive scoring. | |
332 If it is `t', the default adaptive scoring rules will be used. If it | |
333 is `ignore', no adaptive scoring will be performed on this group. If | |
334 it is a list, this list will be used as the adaptive scoring rules. | |
335 If it isn't present, or is something other than `t' or `ignore', the | |
336 default adaptive scoring rules will be used. If you want to use | |
337 adaptive scoring on most groups, you'd set `gnus-use-adaptive-scoring' | |
338 to `t', and insert an `(adapt ignore)' in the groups where you do not | |
339 want adaptive scoring. If you only want adaptive scoring in a few | |
340 groups, you'd set `gnus-use-adaptive-scoring' to `nil', and insert | |
341 `(adapt t)' in the score files of the groups where you want it.") | |
342 | |
343 (adapt-file (file :tag "Adapt-file") "\ | |
344 All adaptive score entries will go to the file named by this entry. | |
345 It will also be applied when entering the group. This atom might | |
346 be handy if you want to adapt on several groups at once, using the | |
347 same adaptive file for a number of groups.") | |
348 | |
349 (local (repeat :tag "Local" | |
350 (group :value (nil nil) | |
351 (symbol :tag "Variable") | |
352 (sexp :tag "Value"))) "\ | |
353 The value of this entry should be a list of `(VAR VALUE)' pairs. | |
354 Each VAR will be made buffer-local to the current summary buffer, | |
355 and set to the value specified. This is a convenient, if somewhat | |
356 strange, way of setting variables in some groups if you don't like | |
357 hooks much.") | |
358 (touched (sexp :format "Touched\n") "Internal variable.")) | |
359 "Alist of valid symbolic score parameters. | |
360 | |
361 Each entry has the form (NAME TYPE DOC), where NAME is the parameter | |
362 itself (a symbol), TYPE is the parameters type (a sexp widget), and DOC is a | |
363 documentation string for the parameter.") | |
364 | |
365 (define-widget 'gnus-score-string 'group | |
366 "Edit score entries for string-valued headers." | |
367 :convert-widget 'gnus-score-string-convert) | |
368 | |
369 (defun gnus-score-string-convert (widget) | |
370 ;; Set args appropriately. | |
371 (let* ((tag (widget-get widget :tag)) | |
372 (item `(const :format "" :value ,(downcase tag))) | |
373 (match '(string :tag "Match")) | |
374 (score '(choice :tag "Score" | |
375 (const :tag "default" nil) | |
376 (integer :format "%v" | |
377 :hide-front-space t))) | |
378 (expire '(choice :tag "Expire" | |
379 (const :tag "off" nil) | |
380 (integer :format "%v" | |
381 :hide-front-space t))) | |
382 (type '(choice :tag "Type" | |
383 :value s | |
384 ;; I should really create a forgiving :match | |
385 ;; function for each type below, that only | |
386 ;; looked at the first letter. | |
387 (const :tag "Regexp" r) | |
388 (const :tag "Regexp (fixed case)" R) | |
389 (const :tag "Substring" s) | |
390 (const :tag "Substring (fixed case)" S) | |
391 (const :tag "Exact" e) | |
392 (const :tag "Exact (fixed case)" E) | |
393 (const :tag "Word" w) | |
394 (const :tag "Word (fixed case)" W) | |
395 (const :tag "default" nil))) | |
396 (group `(group ,match ,score ,expire ,type)) | |
397 (doc (concat (or (widget-get widget :doc) | |
398 (concat "Change score based on the " tag | |
399 " header.\n")) | |
400 " | |
401 You can have an arbitrary number of score entries for this header, | |
402 each score entry has four elements: | |
403 | |
404 1. The \"match element\". This should be the string to look for in the | |
405 header. | |
406 | |
407 2. The \"score element\". This number should be an integer in the | |
408 neginf to posinf interval. This number is added to the score | |
409 of the article if the match is successful. If this element is | |
410 not present, the `gnus-score-interactive-default-score' number | |
411 will be used instead. This is 1000 by default. | |
412 | |
413 3. The \"date element\". This date says when the last time this score | |
414 entry matched, which provides a mechanism for expiring the | |
415 score entries. It this element is not present, the score | |
416 entry is permanent. The date is represented by the number of | |
417 days since December 31, 1 ce. | |
418 | |
419 4. The \"type element\". This element specifies what function should | |
420 be used to see whether this score entry matches the article. | |
421 | |
422 There are the regexp, as well as substring types, and exact match, | |
423 and word match types. If this element is not present, Gnus will | |
424 assume that substring matching should be used. There is case | |
425 sensitive variants of all match types."))) | |
426 (widget-put widget :args `(,item | |
427 (repeat :inline t | |
428 :indent 0 | |
429 :tag ,tag | |
430 :doc ,doc | |
431 :format "%t:\n%h%v%i\n\n" | |
432 (choice :format "%v" | |
433 :value ("" nil nil s) | |
434 ,group | |
435 sexp))))) | |
436 widget) | |
437 | |
438 (define-widget 'gnus-score-integer 'group | |
439 "Edit score entries for integer-valued headers." | |
440 :convert-widget 'gnus-score-integer-convert) | |
441 | |
442 (defun gnus-score-integer-convert (widget) | |
443 ;; Set args appropriately. | |
444 (let* ((tag (widget-get widget :tag)) | |
445 (item `(const :format "" :value ,(downcase tag))) | |
446 (match '(integer :tag "Match")) | |
447 (score '(choice :tag "Score" | |
448 (const :tag "default" nil) | |
449 (integer :format "%v" | |
450 :hide-front-space t))) | |
451 (expire '(choice :tag "Expire" | |
452 (const :tag "off" nil) | |
453 (integer :format "%v" | |
454 :hide-front-space t))) | |
455 (type '(choice :tag "Type" | |
456 :value < | |
457 (const <) | |
458 (const >) | |
459 (const =) | |
460 (const >=) | |
461 (const <=))) | |
462 (group `(group ,match ,score ,expire ,type)) | |
463 (doc (concat (or (widget-get widget :doc) | |
464 (concat "Change score based on the " tag | |
465 " header."))))) | |
466 (widget-put widget :args `(,item | |
467 (repeat :inline t | |
468 :indent 0 | |
469 :tag ,tag | |
470 :doc ,doc | |
471 :format "%t:\n%h%v%i\n\n" | |
472 ,group)))) | |
473 widget) | |
474 | |
475 (define-widget 'gnus-score-date 'group | |
476 "Edit score entries for date-valued headers." | |
477 :convert-widget 'gnus-score-date-convert) | |
478 | |
479 (defun gnus-score-date-convert (widget) | |
480 ;; Set args appropriately. | |
481 (let* ((tag (widget-get widget :tag)) | |
482 (item `(const :format "" :value ,(downcase tag))) | |
483 (match '(string :tag "Match")) | |
484 (score '(choice :tag "Score" | |
485 (const :tag "default" nil) | |
486 (integer :format "%v" | |
487 :hide-front-space t))) | |
488 (expire '(choice :tag "Expire" | |
489 (const :tag "off" nil) | |
490 (integer :format "%v" | |
491 :hide-front-space t))) | |
492 (type '(choice :tag "Type" | |
493 :value regexp | |
494 (const regexp) | |
495 (const before) | |
496 (const at) | |
497 (const after))) | |
498 (group `(group ,match ,score ,expire ,type)) | |
499 (doc (concat (or (widget-get widget :doc) | |
500 (concat "Change score based on the " tag | |
501 " header.")) | |
502 " | |
503 For the Date header we have three kinda silly match types: `before', | |
504 `at' and `after'. I can't really imagine this ever being useful, but, | |
505 like, it would feel kinda silly not to provide this function. Just in | |
506 case. You never know. Better safe than sorry. Once burnt, twice | |
507 shy. Don't judge a book by its cover. Never not have sex on a first | |
508 date. (I have been told that at least one person, and I quote, | |
509 \"found this function indispensable\", however.) | |
510 | |
511 A more useful match type is `regexp'. With it, you can match the date | |
512 string using a regular expression. The date is normalized to ISO8601 | |
513 compact format first---`YYYYMMDDTHHMMSS'. If you want to match all | |
514 articles that have been posted on April 1st in every year, you could | |
515 use `....0401.........' as a match string, for instance. (Note that | |
516 the date is kept in its original time zone, so this will match | |
517 articles that were posted when it was April 1st where the article was | |
518 posted from. Time zones are such wholesome fun for the whole family, | |
519 eh?"))) | |
520 (widget-put widget :args `(,item | |
521 (repeat :inline t | |
522 :indent 0 | |
523 :tag ,tag | |
524 :doc ,doc | |
525 :format "%t:\n%h%v%i\n\n" | |
526 ,group)))) | |
527 widget) | |
528 | |
529 (defvar gnus-custom-scores) | |
530 (defvar gnus-custom-score-alist) | |
531 | |
532 (defun gnus-score-customize (file) | |
533 "Customize score file FILE." | |
534 (interactive (list gnus-current-score-file)) | |
535 (let ((scores (gnus-score-load file)) | |
536 (types (mapcar (lambda (entry) | |
537 `(group :format "%v%h\n" | |
538 :doc ,(nth 2 entry) | |
539 (const :format "" ,(nth 0 entry)) | |
540 ,(nth 1 entry))) | |
541 gnus-score-parameters))) | |
542 ;; Ready. | |
543 (kill-buffer (get-buffer-create "*Gnus Customize*")) | |
544 (switch-to-buffer (get-buffer-create "*Gnus Customize*")) | |
545 (gnus-custom-mode) | |
546 (make-local-variable 'gnus-custom-score-alist) | |
547 (setq gnus-custom-score-alist scores) | |
548 (widget-insert "Customize the ") | |
549 (widget-create 'info-link | |
550 :help-echo "Push me to learn more." | |
551 :tag "score entries" | |
552 "(gnus)Score File Format") | |
553 (widget-insert " for\n\t") | |
554 (widget-insert file) | |
555 (widget-insert "\nand press ") | |
556 (widget-create 'push-button | |
557 :tag "done" | |
558 :help-echo "Push me when done customizing." | |
559 :action 'gnus-score-customize-done) | |
560 (widget-insert ".\n | |
561 Check the [ ] for the entries you want to apply to this score file, then | |
562 edit the value to suit your taste. Don't forget to mark the checkbox, | |
563 if you do all your changes will be lost. ") | |
564 (widget-create 'push-button | |
565 :action (lambda (&rest ignore) | |
566 (require 'gnus-audio) | |
567 (gnus-audio-play "Evil_Laugh.au")) | |
568 "Bhahahah!") | |
569 (widget-insert "\n\n") | |
570 (make-local-variable 'gnus-custom-scores) | |
571 (setq gnus-custom-scores | |
572 (widget-create 'group | |
573 :value scores | |
574 `(checklist :inline t | |
575 :greedy t | |
576 (gnus-score-string :tag "From") | |
577 (gnus-score-string :tag "Subject") | |
578 (gnus-score-string :tag "References") | |
579 (gnus-score-string :tag "Xref") | |
580 (gnus-score-string :tag "Message-ID") | |
581 (gnus-score-integer :tag "Lines") | |
582 (gnus-score-integer :tag "Chars") | |
583 (gnus-score-date :tag "Date") | |
584 (gnus-score-string :tag "Head" | |
585 :doc "\ | |
586 Match all headers in the article. | |
587 | |
588 Using one of `Head', `Body', `All' will slow down scoring considerable. | |
102 ") | 589 ") |
103 (default . __uninitialized__) | 590 (gnus-score-string :tag "Body" |
104 (type . symbol)))) | 591 :doc "\ |
105 ((tag . "Mouse Face") | 592 Match the body sans header of the article. |
106 (doc . "\ | 593 |
107 Face used for group or summary buffer mouse highlighting. | 594 Using one of `Head', `Body', `All' will slow down scoring considerable. |
108 The line beneath the mouse pointer will be highlighted with this | |
109 face.") | |
110 (name . gnus-mouse-face) | |
111 (calculate . (condition-case () | |
112 (if (gnus-visual-p 'mouse-face 'highlight) | |
113 (if (boundp 'gnus-mouse-face) | |
114 gnus-mouse-face | |
115 'highlight) | |
116 'default) | |
117 (error nil))) | |
118 (type . face)) | |
119 ((tag . "Article Display") | |
120 (doc . "Controls how the article buffer will look. | |
121 | |
122 If you leave the list empty, the article will appear exactly as it is | |
123 stored on the disk. The list entries will hide or highlight various | |
124 parts of the article, making it easier to find the information you | |
125 want.") | |
126 (name . gnus-article-display-hook) | |
127 (type . list) | |
128 (calculate | |
129 . (if (and (string-match "xemacs" emacs-version) | |
130 (featurep 'xface)) | |
131 '(gnus-article-hide-headers-if-wanted | |
132 gnus-article-hide-boring-headers | |
133 gnus-article-treat-overstrike | |
134 gnus-article-maybe-highlight | |
135 gnus-article-display-x-face) | |
136 '(gnus-article-hide-headers-if-wanted | |
137 gnus-article-hide-boring-headers | |
138 gnus-article-treat-overstrike | |
139 gnus-article-maybe-highlight))) | |
140 (data | |
141 ((type . repeat) | |
142 (header . nil) | |
143 (data | |
144 (tag . "Filter") | |
145 (type . choice) | |
146 (data | |
147 ((tag . "Treat Overstrike") | |
148 (doc . "\ | |
149 Convert use of overstrike into bold and underline. | |
150 | |
151 Two identical letters separated by a backspace are displayed as a | |
152 single bold letter, while a letter followed by a backspace and an | |
153 underscore will be displayed as a single underlined letter. This | |
154 technique was developed for old line printers (think about it), and is | |
155 still in use on some newsgroups, in particular the ClariNet | |
156 hierarchy. | |
157 ") | 595 ") |
158 (type . const) | 596 (gnus-score-string :tag "All" |
159 (default . | 597 :doc "\ |
160 gnus-article-treat-overstrike)) | 598 Match the entire article, including both headers and body. |
161 ((tag . "Word Wrap") | 599 |
162 (doc . "\ | 600 Using one of `Head', `Body', `All' will slow down scoring |
163 Format too long lines. | 601 considerable. |
164 ") | 602 ") |
165 (type . const) | 603 (gnus-score-string :tag |
166 (default . gnus-article-word-wrap)) | 604 "Followup" |
167 ((tag . "Remove CR") | 605 :doc "\ |
168 (doc . "\ | 606 Score all followups to the specified authors. |
169 Remove carriage returns from an article. | 607 |
608 This entry is somewhat special, in that it will match the `From:' | |
609 header, and affect the score of not only the matching articles, but | |
610 also all followups to the matching articles. This allows you | |
611 e.g. increase the score of followups to your own articles, or decrease | |
612 the score of followups to the articles of some known trouble-maker. | |
170 ") | 613 ") |
171 (type . const) | 614 (gnus-score-string :tag "Thread" |
172 (default . gnus-article-remove-cr)) | 615 :doc "\ |
173 ((tag . "Display X-Face") | 616 Add a score entry on all articles that are part of a thread. |
174 (doc . "\ | 617 |
175 Look for an X-Face header and display it if present. | 618 This match key works along the same lines as the `Followup' match key. |
176 | 619 If you say that you want to score on a (sub-)thread that is started by |
177 See also `X Face Command' for a definition of the external command | 620 an article with a `Message-ID' X, then you add a `thread' match. This |
178 used for decoding and displaying the face. | 621 will add a new `thread' match for each article that has X in its |
622 `References' header. (These new `thread' matches will use the | |
623 `Message-ID's of these matching articles.) This will ensure that you | |
624 can raise/lower the score of an entire thread, even though some | |
625 articles in the thread may not have complete `References' headers. | |
626 Note that using this may lead to undeterministic scores of the | |
627 articles in the thread. | |
179 ") | 628 ") |
180 (type . const) | 629 ,@types) |
181 (default . gnus-article-display-x-face)) | 630 '(repeat :inline t |
182 ((tag . "Unquote Printable") | 631 :tag "Unknown entries" |
183 (doc . "\ | 632 sexp))) |
184 Transform MIME quoted printable into 8-bit characters. | 633 (use-local-map widget-keymap) |
185 | 634 (widget-setup))) |
186 Quoted printable is often seen by strings like `=EF' where you would | 635 |
187 expect a non-English letter. | 636 (defun gnus-score-customize-done (&rest ignore) |
188 ") | 637 "Reset the score alist with the present value." |
189 (type . const) | 638 (let ((alist gnus-custom-score-alist) |
190 (default . | 639 (value (widget-value gnus-custom-scores))) |
191 gnus-article-de-quoted-unreadable)) | 640 (setcar alist (car value)) |
192 ((tag . "Universal Time") | 641 (setcdr alist (cdr value)) |
193 (doc . "\ | 642 (gnus-score-set 'touched '(t) alist)) |
194 Convert date header to universal time. | 643 (bury-buffer)) |
195 ") | 644 |
196 (type . const) | 645 ;;; The End: |
197 (default . gnus-article-date-ut)) | 646 |
198 ((tag . "Local Time") | |
199 (doc . "\ | |
200 Convert date header to local timezone. | |
201 ") | |
202 (type . const) | |
203 (default . gnus-article-date-local)) | |
204 ((tag . "Lapsed Time") | |
205 (doc . "\ | |
206 Replace date header with a header showing the articles age. | |
207 ") | |
208 (type . const) | |
209 (default . gnus-article-date-lapsed)) | |
210 ((tag . "Highlight") | |
211 (doc . "\ | |
212 Highlight headers, citations, signature, and buttons. | |
213 ") | |
214 (type . const) | |
215 (default . gnus-article-highlight)) | |
216 ((tag . "Maybe Highlight") | |
217 (doc . "\ | |
218 Highlight headers, signature, and buttons if `Visual' is turned on. | |
219 ") | |
220 (type . const) | |
221 (default . | |
222 gnus-article-maybe-highlight)) | |
223 ((tag . "Highlight Some") | |
224 (doc . "\ | |
225 Highlight headers, signature, and buttons. | |
226 ") | |
227 (type . const) | |
228 (default . gnus-article-highlight-some)) | |
229 ((tag . "Highlight Headers") | |
230 (doc . "\ | |
231 Highlight headers as specified by `Article Header Highlighting'. | |
232 ") | |
233 (type . const) | |
234 (default . | |
235 gnus-article-highlight-headers)) | |
236 ((tag . "Highlight Signature") | |
237 (doc . "\ | |
238 Highlight the signature as specified by `Article Signature Face'. | |
239 ") | |
240 (type . const) | |
241 (default . | |
242 gnus-article-highlight-signature)) | |
243 ((tag . "Citation") | |
244 (doc . "\ | |
245 Highlight the citations as specified by `Citation Faces'. | |
246 ") | |
247 (type . const) | |
248 (default . | |
249 gnus-article-highlight-citation)) | |
250 ((tag . "Hide") | |
251 (doc . "\ | |
252 Hide unwanted headers, excess citation, and the signature. | |
253 ") | |
254 (type . const) | |
255 (default . gnus-article-hide)) | |
256 ((tag . "Hide Headers If Wanted") | |
257 (doc . "\ | |
258 Hide headers, but allow user to display them with `t' or `v'. | |
259 ") | |
260 (type . const) | |
261 (default . | |
262 gnus-article-hide-headers-if-wanted)) | |
263 ((tag . "Hide Headers") | |
264 (doc . "\ | |
265 Hide unwanted headers and possibly sort them as well. | |
266 Most likely you want to use `Hide Headers If Wanted' instead. | |
267 ") | |
268 (type . const) | |
269 (default . gnus-article-hide-headers)) | |
270 ((tag . "Hide Signature") | |
271 (doc . "\ | |
272 Hide the signature. | |
273 ") | |
274 (type . const) | |
275 (default . gnus-article-hide-signature)) | |
276 ((tag . "Hide Excess Citations") | |
277 (doc . "\ | |
278 Hide excess citation. | |
279 | |
280 Excess is defined by `Citation Hide Percentage' and `Citation Hide Absolute'. | |
281 ") | |
282 (type . const) | |
283 (default . | |
284 gnus-article-hide-citation-maybe)) | |
285 ((tag . "Hide Citations") | |
286 (doc . "\ | |
287 Hide all cited text. | |
288 ") | |
289 (type . const) | |
290 (default . gnus-article-hide-citation)) | |
291 ((tag . "Add Buttons") | |
292 (doc . "\ | |
293 Make URL's into clickable buttons. | |
294 ") | |
295 (type . const) | |
296 (default . gnus-article-add-buttons)) | |
297 ((prompt . "Other") | |
298 (doc . "\ | |
299 Name of Lisp function to call. | |
300 | |
301 Push the `Filter' button to select one of the predefined filters. | |
302 ") | |
303 (type . symbol))))))) | |
304 ((tag . "Article Button Face") | |
305 (doc . "\ | |
306 Face used for highlighting buttons in the article buffer. | |
307 | |
308 An article button is a piece of text that you can activate by pressing | |
309 `RET' or `mouse-2' above it.") | |
310 (name . gnus-article-button-face) | |
311 (default . bold) | |
312 (type . face)) | |
313 ((tag . "Article Mouse Face") | |
314 (doc . "\ | |
315 Face used for mouse highlighting in the article buffer. | |
316 | |
317 Article buttons will be displayed in this face when the cursor is | |
318 above them.") | |
319 (name . gnus-article-mouse-face) | |
320 (default . highlight) | |
321 (type . face)) | |
322 ((tag . "Article Signature Face") | |
323 (doc . "\ | |
324 Face used for highlighting a signature in the article buffer.") | |
325 (name . gnus-signature-face) | |
326 (default . italic) | |
327 (type . face)) | |
328 ((tag . "Article Header Highlighting") | |
329 (doc . "\ | |
330 Controls highlighting of article header. | |
331 | |
332 Below is a list of article header names, and the faces used for | |
333 displaying the name and content of the header. The `Header' field | |
334 should contain the name of the header. The field actually contains a | |
335 regular expression that should match the beginning of the header line, | |
336 but if you don't know what a regular expression is, just write the | |
337 name of the header. The second field is the `Name' field, which | |
338 determines how the header name (i.e. the part of the header left | |
339 of the `:') is displayed. The third field is the `Content' field, | |
340 which determines how the content (i.e. the part of the header right of | |
341 the `:') is displayed. | |
342 | |
343 If you leave the last `Header' field in the list empty, the `Name' and | |
344 `Content' fields will determine how headers not listed above are | |
345 displayed. | |
346 | |
347 If you only want to change the display of the name part for a specific | |
348 header, specify `None' in the `Content' field. Similarly, specify | |
349 `None' in the `Name' field if you only want to leave the name part | |
350 alone.") | |
351 (name . gnus-header-face-alist) | |
352 (type . list) | |
353 (calculate | |
354 . (cond | |
355 ((not (eq gnus-display-type 'color)) | |
356 '(("" bold italic))) | |
357 ((eq gnus-background-mode 'dark) | |
358 (list | |
359 (list "From" nil | |
360 (custom-face-lookup "light blue" nil nil t t nil)) | |
361 (list "Subject" nil | |
362 (custom-face-lookup "pink" nil nil t t nil)) | |
363 (list "Newsgroups:.*," nil | |
364 (custom-face-lookup "yellow" nil nil t t nil)) | |
365 (list | |
366 "" | |
367 (custom-face-lookup "cyan" nil nil t nil nil) | |
368 (custom-face-lookup "forestgreen" nil nil nil t | |
369 nil)))) | |
370 (t | |
371 (list | |
372 (list "From" nil | |
373 (custom-face-lookup "MidnightBlue" nil nil t t nil)) | |
374 (list "Subject" nil | |
375 (custom-face-lookup "firebrick" nil nil t t nil)) | |
376 (list "Newsgroups:.*," nil | |
377 (custom-face-lookup "indianred" nil nil t t nil)) | |
378 (list "" | |
379 (custom-face-lookup | |
380 "DarkGreen" nil nil t nil nil) | |
381 (custom-face-lookup "DarkGreen" nil nil | |
382 nil t nil)))))) | |
383 (data | |
384 ((type . repeat) | |
385 (header . nil) | |
386 (data | |
387 (type . list) | |
388 (compact . t) | |
389 (data | |
390 ((type . string) | |
391 (prompt . "Header") | |
392 (tag . "Header ")) | |
393 "\n " | |
394 ((type . face) | |
395 (prompt . "Name") | |
396 (tag . "Name ")) | |
397 "\n " | |
398 ((type . face) | |
399 (tag . "Content")) | |
400 "\n"))))) | |
401 ((tag . "Attribution Face") | |
402 (doc . "\ | |
403 Face used for attribution lines. | |
404 It is merged with the face for the cited text belonging to the attribution.") | |
405 (name . gnus-cite-attribution-face) | |
406 (default . underline) | |
407 (type . face)) | |
408 ((tag . "Citation Faces") | |
409 (doc . "\ | |
410 List of faces used for highlighting citations. | |
411 | |
412 When there are citations from multiple articles in the same message, | |
413 Gnus will try to give each citation from each article its own face. | |
414 This should make it easier to see who wrote what.") | |
415 (name . gnus-cite-face-list) | |
416 (import . gnus-custom-import-cite-face-list) | |
417 (type . list) | |
418 (calculate . (cond ((not (eq gnus-display-type 'color)) | |
419 '(italic)) | |
420 ((eq gnus-background-mode 'dark) | |
421 (mapcar 'gnus-make-face | |
422 gnus-face-light-name-list)) | |
423 (t | |
424 (mapcar 'gnus-make-face | |
425 gnus-face-dark-name-list)))) | |
426 (data | |
427 ((type . repeat) | |
428 (header . nil) | |
429 (data (type . face) | |
430 (tag . "Face"))))) | |
431 ((tag . "Citation Hide Percentage") | |
432 (doc . "\ | |
433 Only hide excess citation if above this percentage of the body.") | |
434 (name . gnus-cite-hide-percentage) | |
435 (default . 50) | |
436 (type . integer)) | |
437 ((tag . "Citation Hide Absolute") | |
438 (doc . "\ | |
439 Only hide excess citation if above this number of lines in the body.") | |
440 (name . gnus-cite-hide-absolute) | |
441 (default . 10) | |
442 (type . integer)) | |
443 ((tag . "Summary Selected Face") | |
444 (doc . "\ | |
445 Face used for highlighting the current article in the summary buffer.") | |
446 (name . gnus-summary-selected-face) | |
447 (default . underline) | |
448 (type . face)) | |
449 ((tag . "Summary Line Highlighting") | |
450 (doc . "\ | |
451 Controls the highlighting of summary buffer lines. | |
452 | |
453 Below is a list of `Form'/`Face' pairs. When deciding how a a | |
454 particular summary line should be displayed, each form is | |
455 evaluated. The content of the face field after the first true form is | |
456 used. You can change how those summary lines are displayed, by | |
457 editing the face field. | |
458 | |
459 It is also possible to change and add form fields, but currently that | |
460 requires an understanding of Lisp expressions. Hopefully this will | |
461 change in a future release. For now, you can use the following | |
462 variables in the Lisp expression: | |
463 | |
464 score: The article's score | |
465 default: The default article score. | |
466 below: The score below which articles are automatically marked as read. | |
467 mark: The article's mark.") | |
468 (name . gnus-summary-highlight) | |
469 (type . list) | |
470 (calculate | |
471 . (cond | |
472 ((not (eq gnus-display-type 'color)) | |
473 '(((> score default) . bold) | |
474 ((< score default) . italic))) | |
475 ((eq gnus-background-mode 'dark) | |
476 (list | |
477 (cons | |
478 '(= mark gnus-canceled-mark) | |
479 (custom-face-lookup "yellow" "black" nil | |
480 nil nil nil)) | |
481 (cons '(and (> score default) | |
482 (or (= mark gnus-dormant-mark) | |
483 (= mark gnus-ticked-mark))) | |
484 (custom-face-lookup | |
485 "pink" nil nil t nil nil)) | |
486 (cons '(and (< score default) | |
487 (or (= mark gnus-dormant-mark) | |
488 (= mark gnus-ticked-mark))) | |
489 (custom-face-lookup "pink" nil nil | |
490 nil t nil)) | |
491 (cons '(or (= mark gnus-dormant-mark) | |
492 (= mark gnus-ticked-mark)) | |
493 (custom-face-lookup | |
494 "pink" nil nil nil nil nil)) | |
495 | |
496 (cons | |
497 '(and (> score default) (= mark gnus-ancient-mark)) | |
498 (custom-face-lookup "medium blue" nil nil t | |
499 nil nil)) | |
500 (cons | |
501 '(and (< score default) (= mark gnus-ancient-mark)) | |
502 (custom-face-lookup "SkyBlue" nil nil | |
503 nil t nil)) | |
504 (cons | |
505 '(= mark gnus-ancient-mark) | |
506 (custom-face-lookup "SkyBlue" nil nil | |
507 nil nil nil)) | |
508 (cons '(and (> score default) (= mark gnus-unread-mark)) | |
509 (custom-face-lookup "white" nil nil t | |
510 nil nil)) | |
511 (cons '(and (< score default) (= mark gnus-unread-mark)) | |
512 (custom-face-lookup "white" nil nil | |
513 nil t nil)) | |
514 (cons '(= mark gnus-unread-mark) | |
515 (custom-face-lookup | |
516 "white" nil nil nil nil nil)) | |
517 | |
518 (cons '(> score default) 'bold) | |
519 (cons '(< score default) 'italic))) | |
520 (t | |
521 (list | |
522 (cons | |
523 '(= mark gnus-canceled-mark) | |
524 (custom-face-lookup | |
525 "yellow" "black" nil nil nil nil)) | |
526 (cons '(and (> score default) | |
527 (or (= mark gnus-dormant-mark) | |
528 (= mark gnus-ticked-mark))) | |
529 (custom-face-lookup "firebrick" nil nil | |
530 t nil nil)) | |
531 (cons '(and (< score default) | |
532 (or (= mark gnus-dormant-mark) | |
533 (= mark gnus-ticked-mark))) | |
534 (custom-face-lookup "firebrick" nil nil | |
535 nil t nil)) | |
536 (cons | |
537 '(or (= mark gnus-dormant-mark) | |
538 (= mark gnus-ticked-mark)) | |
539 (custom-face-lookup | |
540 "firebrick" nil nil nil nil nil)) | |
541 | |
542 (cons '(and (> score default) (= mark gnus-ancient-mark)) | |
543 (custom-face-lookup "RoyalBlue" nil nil | |
544 t nil nil)) | |
545 (cons '(and (< score default) (= mark gnus-ancient-mark)) | |
546 (custom-face-lookup "RoyalBlue" nil nil | |
547 nil t nil)) | |
548 (cons | |
549 '(= mark gnus-ancient-mark) | |
550 (custom-face-lookup | |
551 "RoyalBlue" nil nil nil nil nil)) | |
552 | |
553 (cons '(and (> score default) (/= mark gnus-unread-mark)) | |
554 (custom-face-lookup "DarkGreen" nil nil | |
555 t nil nil)) | |
556 (cons '(and (< score default) (/= mark gnus-unread-mark)) | |
557 (custom-face-lookup "DarkGreen" nil nil | |
558 nil t nil)) | |
559 (cons | |
560 '(/= mark gnus-unread-mark) | |
561 (custom-face-lookup "DarkGreen" nil nil | |
562 nil nil nil)) | |
563 | |
564 (cons '(> score default) 'bold) | |
565 (cons '(< score default) 'italic))))) | |
566 (data | |
567 ((type . repeat) | |
568 (header . nil) | |
569 (data (type . pair) | |
570 (compact . t) | |
571 (data ((type . sexp) | |
572 (width . 60) | |
573 (tag . "Form")) | |
574 "\n " | |
575 ((type . face) | |
576 (tag . "Face")) | |
577 "\n"))))) | |
578 | |
579 ((tag . "Group Line Highlighting") | |
580 (doc . "\ | |
581 Controls the highlighting of group buffer lines. | |
582 | |
583 Below is a list of `Form'/`Face' pairs. When deciding how a a | |
584 particular group line should be displayed, each form is | |
585 evaluated. The content of the face field after the first true form is | |
586 used. You can change how those group lines are displayed by | |
587 editing the face field. | |
588 | |
589 It is also possible to change and add form fields, but currently that | |
590 requires an understanding of Lisp expressions. Hopefully this will | |
591 change in a future release. For now, you can use the following | |
592 variables in the Lisp expression: | |
593 | |
594 group: The name of the group. | |
595 unread: The number of unread articles in the group. | |
596 method: The select method used. | |
597 mailp: Whether it's a mail group or not. | |
598 level: The level of the group. | |
599 score: The score of the group. | |
600 ticked: The number of ticked articles.") | |
601 (name . gnus-group-highlight) | |
602 (type . list) | |
603 (calculate | |
604 . (cond | |
605 ((not (eq gnus-display-type 'color)) | |
606 '((mailp . bold) | |
607 ((= unread 0) . italic))) | |
608 ((eq gnus-background-mode 'dark) | |
609 `(((and (not mailp) (eq level 1)) . | |
610 ,(custom-face-lookup "PaleTurquoise" nil nil t)) | |
611 ((and (not mailp) (eq level 2)) . | |
612 ,(custom-face-lookup "turquoise" nil nil t)) | |
613 ((and (not mailp) (eq level 3)) . | |
614 ,(custom-face-lookup "MediumTurquoise" nil nil t)) | |
615 ((and (not mailp) (>= level 4)) . | |
616 ,(custom-face-lookup "DarkTurquoise" nil nil t)) | |
617 ((and mailp (eq level 1)) . | |
618 ,(custom-face-lookup "aquamarine1" nil nil t)) | |
619 ((and mailp (eq level 2)) . | |
620 ,(custom-face-lookup "aquamarine2" nil nil t)) | |
621 ((and mailp (eq level 3)) . | |
622 ,(custom-face-lookup "aquamarine3" nil nil t)) | |
623 ((and mailp (>= level 4)) . | |
624 ,(custom-face-lookup "aquamarine4" nil nil t)) | |
625 )) | |
626 (t | |
627 `(((and (not mailp) (<= level 3)) . | |
628 ,(custom-face-lookup "ForestGreen" nil nil t)) | |
629 ((and (not mailp) (eq level 4)) . | |
630 ,(custom-face-lookup "DarkGreen" nil nil t)) | |
631 ((and (not mailp) (eq level 5)) . | |
632 ,(custom-face-lookup "CadetBlue4" nil nil t)) | |
633 ((and mailp (eq level 1)) . | |
634 ,(custom-face-lookup "DeepPink3" nil nil t)) | |
635 ((and mailp (eq level 2)) . | |
636 ,(custom-face-lookup "HotPink3" nil nil t)) | |
637 ((and mailp (eq level 3)) . | |
638 ,(custom-face-lookup "dark magenta" nil nil t)) | |
639 ((and mailp (eq level 4)) . | |
640 ,(custom-face-lookup "DeepPink4" nil nil t)) | |
641 ((and mailp (> level 4)) . | |
642 ,(custom-face-lookup "DarkOrchid4" nil nil t)) | |
643 )))) | |
644 (data | |
645 ((type . repeat) | |
646 (header . nil) | |
647 (data (type . pair) | |
648 (compact . t) | |
649 (data ((type . sexp) | |
650 (width . 60) | |
651 (tag . "Form")) | |
652 "\n " | |
653 ((type . face) | |
654 (tag . "Face")) | |
655 "\n"))))) | |
656 | |
657 ;; Do not define `gnus-button-alist' before we have | |
658 ;; some `complexity' attribute so we can hide it from | |
659 ;; beginners. | |
660 ))))) | |
661 | |
662 (defun gnus-custom-import-cite-face-list (custom alist) | |
663 ;; Backward compatible grokking of light and dark. | |
664 (cond ((eq alist 'light) | |
665 (setq alist (mapcar 'gnus-make-face gnus-face-light-name-list))) | |
666 ((eq alist 'dark) | |
667 (setq alist (mapcar 'gnus-make-face gnus-face-dark-name-list)))) | |
668 (funcall (custom-super custom 'import) custom alist)) | |
669 | |
670 (provide 'gnus-cus) | 647 (provide 'gnus-cus) |
671 | 648 |
672 ;;; gnus-cus.el ends here | 649 ;;; gnus-cus.el ends here |
650 |