Commit | Line | Data |
---|---|---|
41487370 | 1 | ;;; gnus-edit.el --- Gnus SCORE file editing |
b578f267 | 2 | |
41487370 | 3 | ;; Copyright (C) 1995 Free Software Foundation, Inc. |
b578f267 | 4 | |
41487370 LMI |
5 | ;; Author: Per Abrahamsen <abraham@iesd.auc.dk> |
6 | ;; Keywords: news, help | |
7 | ;; Version: 0.2 | |
8 | ||
b578f267 EN |
9 | ;; This file is part of GNU Emacs. |
10 | ||
11 | ;; GNU Emacs is free software; you can redistribute it and/or modify | |
12 | ;; it under the terms of the GNU General Public License as published by | |
13 | ;; the Free Software Foundation; either version 2, or (at your option) | |
14 | ;; any later version. | |
15 | ||
16 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
22 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
23 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
24 | ;; Boston, MA 02111-1307, USA. | |
25 | ||
41487370 | 26 | ;;; Commentary: |
b578f267 | 27 | |
41487370 LMI |
28 | ;; Type `M-x gnus-score-customize RET' to invoke. |
29 | ||
30 | ;;; Code: | |
31 | ||
32 | (require 'custom) | |
33 | (require 'gnus-score) | |
34 | ||
35 | (defconst gnus-score-custom-data | |
36 | '((tag . "Score") | |
37 | (doc . "Customization of Gnus SCORE files. | |
38 | ||
39 | SCORE files allow you to assign a score to each article when you enter | |
40 | a group, and automatically mark the articles as read or delete them | |
41 | based on the score. In the summary buffer you can use the score to | |
42 | sort the articles by score (`C-c C-s C-s') or to jump to the unread | |
43 | article with the highest score (`,').") | |
44 | (type . group) | |
45 | (data "\n" | |
46 | ((header . nil) | |
47 | (doc . "Name of SCORE file to customize. | |
48 | ||
49 | Enter the name in the `File' field, then push the [Load] button to | |
50 | load it. When done editing, push the [Save] button to save the file. | |
51 | ||
52 | Several score files may apply to each group, and several groups may | |
53 | use the same score file. This is controlled implicitly by the name of | |
54 | the score file and the value of the global variable | |
55 | `gnus-score-find-score-files-function', and explicitly by the the | |
56 | `Files' and `Exclude Files' entries.") | |
57 | (compact . t) | |
58 | (type . group) | |
59 | (data ((tag . "Load") | |
60 | (type . button) | |
61 | (query . gnus-score-custom-load)) | |
62 | ((tag . "Save") | |
63 | (type . button) | |
64 | (query . gnus-score-custom-save)) | |
65 | ((name . file) | |
66 | (tag . "File") | |
67 | (directory . "~/News/") | |
68 | (default-file . "SCORE") | |
69 | (type . file)))) | |
70 | ((name . files) | |
71 | (tag . "Files") | |
72 | (doc . "\ | |
73 | List of score files to load when the the current score file is loaded. | |
74 | You can use this to share score entries between multiple score files. | |
75 | ||
76 | Push the `[INS]' button add a score file to the list, or `[DEL]' to | |
77 | delete a score file from the list.") | |
78 | (type . list) | |
79 | (data ((type . repeat) | |
80 | (header . nil) | |
81 | (data (type . file) | |
82 | (directory . "~/News/"))))) | |
83 | ((name . exclude-files) | |
84 | (tag . "Exclude Files") | |
85 | (doc . "\ | |
86 | List of score files to exclude when the the current score file is loaded. | |
87 | You can use this if you have a score file you want to share between a | |
88 | number of newsgroups, except for the newsgroup this score file | |
89 | matches. [ Did anyone get that? ] | |
90 | ||
91 | Push the `[INS]' button add a score file to the list, or `[DEL]' to | |
92 | delete a score file from the list.") | |
93 | (type . list) | |
94 | (data ((type . repeat) | |
95 | (header . nil) | |
96 | (data (type . file) | |
97 | (directory . "~/News/"))))) | |
98 | ((name . mark) | |
99 | (tag . "Mark") | |
100 | (doc . "\ | |
101 | Articles below this score will be automatically marked as read. | |
102 | ||
103 | This means that when you enter the summary buffer, the articles will | |
104 | be shown but will already be marked as read. You can then press `x' | |
105 | to get rid of them entirely. | |
106 | ||
107 | By default articles with a negative score will be marked as read. To | |
108 | change this, push the `Mark' button, and choose `Integer'. You can | |
109 | then enter a value in the `Mark' field.") | |
110 | (type . gnus-score-custom-maybe-type)) | |
111 | ((name . expunge) | |
112 | (tag . "Expunge") | |
113 | (doc . "\ | |
114 | Articles below this score will not be shown in the summary buffer.") | |
115 | (type . gnus-score-custom-maybe-type)) | |
116 | ((name . mark-and-expunge) | |
117 | (tag . "Mark and Expunge") | |
118 | (doc . "\ | |
119 | Articles below this score will be marked as read, but not shown. | |
120 | ||
121 | Someone should explain me the difference between this and `expunge' | |
122 | alone or combined with `mark'.") | |
123 | (type . gnus-score-custom-maybe-type)) | |
124 | ((name . eval) | |
125 | (tag . "Eval") | |
126 | (doc . "\ | |
127 | Evaluate this lisp expression when the entering summary buffer.") | |
128 | (type . sexp)) | |
129 | ((name . read-only) | |
130 | (tag . "Read Only") | |
131 | (doc . "Read-only score files will not be updated or saved. | |
132 | Except from this buffer, of course!") | |
133 | (type . toggle)) | |
134 | ((type . doc) | |
135 | (doc . "\ | |
136 | Each news header has an associated list of score entries. | |
137 | You can use the [INS] buttons to add new score entries anywhere in the | |
138 | list, or the [DEL] buttons to delete specific score entries. | |
139 | ||
140 | Each score entry should specify a string that should be matched with | |
141 | the content actual header in order to determine whether the entry | |
142 | applies to that header. Enter that string in the `Match' field. | |
143 | ||
144 | If the score entry matches, the articles score will be adjusted with | |
145 | some amount. Enter that amount in the in the `Score' field. You | |
146 | should specify a positive amount for score entries that matches | |
147 | articles you find interesting, and a negative amount for score entries | |
148 | matching articles you would rather avoid. The final score for the | |
149 | article will be the sum of the score of all score entries that match | |
150 | the article. | |
151 | ||
152 | The score entry can be either permanent or expirable. To make the | |
153 | entry permanent, push the `Date' button and choose the `Permanent' | |
154 | entry. To make the entry expirable, choose instead the `Integer' | |
155 | entry. After choosing the you can enter the date the score entry was | |
156 | last matched in the `Date' field. The date will be automatically | |
157 | updated each time the score entry matches an article. When the date | |
158 | become too old, the the score entry will be removed. | |
159 | ||
160 | For your convenience, the date is specified as the number of days | |
161 | elapsed since the (imaginary) Gregorian date Sunday, December 31, 1 | |
162 | BC. | |
163 | ||
164 | Finally, you can choose what kind of match you want to perform by | |
165 | pushing the `Type' button. For most entries you can choose between | |
166 | `Exact' which mean the header content must be exactly identical to the | |
167 | match string, or `Substring' meaning the match string should be | |
168 | somewhere in the header content, or even `Regexp' to use Emacs regular | |
169 | expression matching. The last choice is `Fuzzy' which is like `Exact' | |
170 | except that whitespace derivations, a beginning `Re:' or a terminating | |
171 | parenthetical remark are all ignored. Each of the four types have a | |
172 | variant which will ignore case in the comparison. That variant is | |
173 | indicated with a `(fold)' after its name.")) | |
174 | ((name . from) | |
175 | (tag . "From") | |
176 | (doc . "Scoring based on the authors email address.") | |
177 | (type . gnus-score-custom-string-type)) | |
178 | ((name . subject) | |
179 | (tag . "Subject") | |
180 | (doc . "Scoring based on the articles subject.") | |
181 | (type . gnus-score-custom-string-type)) | |
182 | ((name . followup) | |
183 | (tag . "Followup") | |
184 | (doc . "Scoring based on who the article is a followup to. | |
185 | ||
186 | If you want to see all followups to your own articles, add an entry | |
187 | with a positive score matching your email address here. You can also | |
188 | put an entry with a negative score matching someone who is so annoying | |
189 | that you don't even want to see him quoted in followups.") | |
190 | (type . gnus-score-custom-string-type)) | |
191 | ((name . xref) | |
192 | (tag . "Xref") | |
193 | (doc . "Scoring based on article crossposting. | |
194 | ||
195 | If you want to score based on which newsgroups an article is posted | |
196 | to, this is the header to use. The syntax is a little different from | |
197 | the `Newsgroups' header, but scoring in `Xref' is much faster. As an | |
198 | example, to match all crossposted articles match on `:.*:' using the | |
199 | `Regexp' type.") | |
200 | (type . gnus-score-custom-string-type)) | |
201 | ((name . references) | |
202 | (tag . "References") | |
203 | (doc . "Scoring based on article references. | |
204 | ||
205 | The `References' header gives you an alternative way to score on | |
206 | followups. If you for example want to see follow all discussions | |
207 | where people from `iesd.auc.dk' school participate, you can add a | |
208 | substring match on `iesd.auc.dk>' on this header.") | |
209 | (type . gnus-score-custom-string-type)) | |
210 | ((name . message-id) | |
211 | (tag . "Message-ID") | |
212 | (doc . "Scoring based on the articles message-id. | |
213 | ||
214 | This isn't very useful, but Lars like completeness. You can use it to | |
215 | match all messaged generated by recent Gnus version with a `Substring' | |
216 | match on `.fsf@'.") | |
217 | (type . gnus-score-custom-string-type)) | |
218 | ((type . doc) | |
219 | (doc . "\ | |
220 | WARNING: Scoring on the following three pseudo headers is very slow! | |
221 | Scoring on any of the real headers use a technique that avoids | |
222 | scanning the entire article, only the actual headers you score on are | |
223 | scanned, and this scanning has been heavily optimized. Using just a | |
224 | single entry for one the three pseudo-headers `Head', `Body', and | |
225 | `All' will require GNUS to retrieve and scan the entire article, which | |
226 | can be very slow on large groups. However, if you add one entry for | |
227 | any of these headers, you can just as well add several. Each | |
228 | subsequent entry cost relatively little extra time.")) | |
229 | ((name . head) | |
230 | (tag . "Head") | |
231 | (doc . "Scoring based on the article header. | |
232 | ||
233 | Instead of matching the content of a single header, the entire header | |
234 | section of the article is matched. You can use this to match on | |
235 | arbitrary headers, foe example to single out TIN lusers, use a substring | |
236 | match on `Newsreader: TIN'. That should get 'em!") | |
237 | (type . gnus-score-custom-string-type)) | |
238 | ((name . body) | |
239 | (tag . "Body") | |
240 | (doc . "Scoring based on the article body. | |
241 | ||
242 | If you think any article that mentions `Kibo' is inherently | |
243 | interesting, do a substring match on His name. You Are Allowed.") | |
244 | (type . gnus-score-custom-string-type)) | |
245 | ((name . all) | |
246 | (tag . "All") | |
247 | (doc . "Scoring based on the whole article.") | |
248 | (type . gnus-score-custom-string-type)) | |
249 | ((name . date) | |
250 | (tag . "Date") | |
251 | (doc . "Scoring based on article date. | |
252 | ||
253 | You can change the score of articles that have been posted before, | |
254 | after, or at a specific date. You should add the date in the `Match' | |
255 | field, and then select `before', `after', or `at' by pushing the | |
256 | `Type' button. Imagine you want to lower the score of very old | |
257 | articles, or want to raise the score of articles from the future (such | |
258 | things happen!). Then you can't use date scoring for that. In fact, | |
259 | I can't imagine anything you would want to use this for. | |
260 | ||
261 | For your convenience, the date is specified in Usenet date format.") | |
262 | (type . gnus-score-custom-date-type)) | |
263 | ((type . doc) | |
264 | (doc . "\ | |
265 | The Lines and Chars headers use integer based scoring. | |
266 | ||
267 | This means that you should write an integer in the `Match' field, and | |
268 | the push the `Type' field to if the `Chars' or `Lines' header should | |
269 | be larger, equal, or smaller than the number you wrote in the match | |
270 | field.")) | |
271 | ((name . chars) | |
272 | (tag . "Characters") | |
273 | (doc . "Scoring based on the number of characters in the article.") | |
274 | (type . gnus-score-custom-integer-type)) | |
275 | ((name . lines) | |
276 | (tag . "Lines") | |
277 | (doc . "Scoring based on the number of lines in the article.") | |
278 | (type . gnus-score-custom-integer-type)) | |
279 | ((name . orphan) | |
280 | (tag . "Orphan") | |
281 | (doc . "Score to add to articles with no parents.") | |
282 | (type . gnus-score-custom-maybe-type)) | |
283 | ((name . adapt) | |
284 | (tag . "Adapt") | |
285 | (doc . "Adapting the score files to your newsreading habits. | |
286 | ||
287 | When you have finished reading a group GNUS can automatically create | |
288 | new score entries based on which articles you read and which you | |
abf4db5d | 289 | skipped. This is normally controlled by the two global variables |
41487370 LMI |
290 | `gnus-use-adaptive-scoring' and `gnus-default-adaptive-score-alist', |
291 | The first determines whether adaptive scoring should be enabled or | |
292 | not, while the second determines what score entries should be created. | |
293 | ||
294 | You can overwrite the setting of `gnus-use-adaptive-scoring' by | |
295 | selecting `Enable' or `Disable' by pressing the `Adapt' button. | |
abf4db5d | 296 | Selecting `Custom' will allow you to specify the exact adaptation |
41487370 LMI |
297 | rules (overwriting `gnus-default-adaptive-score-alist').") |
298 | (type . choice) | |
299 | (data ((tag . "Default") | |
300 | (default . nil) | |
301 | (type . const)) | |
302 | ((tag . "Enable") | |
303 | (default . t) | |
304 | (type . const)) | |
305 | ((tag . "Disable") | |
306 | (default . ignore) | |
307 | (type . const)) | |
308 | ((tag . "Custom") | |
309 | (doc . "Customization of adaptive scoring. | |
310 | ||
311 | Each time you read an article it will be marked as read. Likewise, if | |
312 | you delete it it will be marked as deleted, and if you tick it it will | |
313 | be marked as ticked. When you leave a group, GNUS can automatically | |
314 | create score file entries based on these marks, so next time you enter | |
315 | the group articles with subjects that you read last time have higher | |
316 | score and articles with subjects that deleted will have lower score. | |
317 | ||
318 | Below is a list of such marks. You can insert new marks to the list | |
319 | by pushing on one of the `[INS]' buttons in the left margin to create | |
320 | a new entry and then pushing the `Mark' button to select the mark. | |
321 | For each mark there is another list, this time of article headers, | |
322 | which determine how the mark should affect that header. The `[INS]' | |
323 | buttons of this list are indented to indicate that the belong to the | |
324 | mark above. Push the `Header' button to choose a header, and then | |
325 | enter a score value in the `Score' field. | |
326 | ||
327 | For each article that are marked with `Mark' when you leave the | |
328 | group, a temporary score entry for the articles `Header' with the | |
329 | value of `Score' will be added the adapt file. If the score entry | |
330 | already exists, `Score' will be added to its value. If you understood | |
331 | that, you are smart. | |
332 | ||
333 | You can select the special value `Other' when pressing the `Mark' or | |
334 | `Header' buttons. This is because Lars might add more useful values | |
335 | there. If he does, it is up to you to figure out what they are named.") | |
336 | (type . list) | |
337 | (default . ((__uninitialized__))) | |
338 | (data ((type . repeat) | |
339 | (header . nil) | |
340 | (data . ((type . list) | |
341 | (header . nil) | |
342 | (compact . t) | |
343 | (data ((type . choice) | |
344 | (tag . "Mark") | |
345 | (data ((tag . "Unread") | |
346 | (default . gnus-unread-mark) | |
347 | (type . const)) | |
348 | ((tag . "Ticked") | |
349 | (default . gnus-ticked-mark) | |
350 | (type . const)) | |
351 | ((tag . "Dormant") | |
352 | (default . gnus-dormant-mark) | |
353 | (type . const)) | |
354 | ((tag . "Deleted") | |
355 | (default . gnus-del-mark) | |
356 | (type . const)) | |
357 | ((tag . "Read") | |
358 | (default . gnus-read-mark) | |
359 | (type . const)) | |
360 | ((tag . "Expirable") | |
361 | (default . gnus-expirable-mark) | |
362 | (type . const)) | |
363 | ((tag . "Killed") | |
364 | (default . gnus-killed-mark) | |
365 | (type . const)) | |
366 | ((tag . "Kill-file") | |
367 | (default . gnus-kill-file-mark) | |
368 | (type . const)) | |
369 | ((tag . "Low-score") | |
370 | (default . gnus-low-score-mark) | |
371 | (type . const)) | |
372 | ((tag . "Catchup") | |
373 | (default . gnus-catchup-mark) | |
374 | (type . const)) | |
375 | ((tag . "Ancient") | |
376 | (default . gnus-ancient-mark) | |
377 | (type . const)) | |
378 | ((tag . "Canceled") | |
379 | (default . gnus-canceled-mark) | |
380 | (type . const)) | |
381 | ((prompt . "Other") | |
382 | (default . ??) | |
383 | (type . sexp)))) | |
384 | ((type . repeat) | |
385 | (prefix . " ") | |
386 | (data . ((type . list) | |
387 | (compact . t) | |
388 | (data ((tag . "Header") | |
389 | (type . choice) | |
390 | (data ((tag . "Subject") | |
391 | (default . subject) | |
392 | (type . const)) | |
393 | ((prompt . "From") | |
394 | (tag . "From ") | |
395 | (default . from) | |
396 | (type . const)) | |
397 | ((prompt . "Other") | |
398 | (width . 7) | |
399 | (default . nil) | |
400 | (type . symbol)))) | |
401 | ((tag . "Score") | |
402 | (type . integer)))))))))))))) | |
403 | ((name . local) | |
404 | (tag . "Local") | |
405 | (doc . "\ | |
406 | List of local variables to set when this score file is loaded. | |
407 | ||
408 | Using this entry can provide a convenient way to set variables that | |
409 | will affect the summary mode for only some specific groups, i.e. those | |
410 | groups matched by the current score file.") | |
411 | (type . list) | |
412 | (data ((type . repeat) | |
413 | (header . nil) | |
414 | (data . ((type . list) | |
415 | (compact . t) | |
416 | (data ((tag . "Name") | |
417 | (width . 26) | |
418 | (type . symbol)) | |
419 | ((tag . "Value") | |
420 | (width . 26) | |
421 | (type . sexp))))))))))) | |
422 | ||
423 | (defconst gnus-score-custom-type-properties | |
424 | '((gnus-score-custom-maybe-type | |
425 | (type . choice) | |
426 | (data ((type . integer) | |
427 | (default . 0)) | |
428 | ((tag . "Default") | |
429 | (type . const) | |
430 | (default . nil)))) | |
431 | (gnus-score-custom-string-type | |
432 | (type . list) | |
433 | (data ((type . repeat) | |
434 | (header . nil) | |
435 | (data . ((type . list) | |
436 | (compact . t) | |
437 | (data ((tag . "Match") | |
438 | (width . 59) | |
439 | (type . string)) | |
440 | "\n " | |
441 | ((tag . "Score") | |
442 | (type . integer)) | |
443 | ((tag . "Date") | |
444 | (type . choice) | |
445 | (data ((type . integer) | |
446 | (default . 0) | |
447 | (width . 9)) | |
448 | ((tag . "Permanent") | |
449 | (type . const) | |
450 | (default . nil)))) | |
451 | ((tag . "Type") | |
452 | (type . choice) | |
453 | (data ((tag . "Exact") | |
454 | (default . E) | |
455 | (type . const)) | |
456 | ((tag . "Substring") | |
457 | (default . S) | |
458 | (type . const)) | |
459 | ((tag . "Regexp") | |
460 | (default . R) | |
461 | (type . const)) | |
462 | ((tag . "Fuzzy") | |
463 | (default . F) | |
464 | (type . const)) | |
465 | ((tag . "Exact (fold)") | |
466 | (default . e) | |
467 | (type . const)) | |
468 | ((tag . "Substring (fold)") | |
469 | (default . s) | |
470 | (type . const)) | |
471 | ((tag . "Regexp (fold)") | |
472 | (default . r) | |
473 | (type . const)) | |
474 | ((tag . "Fuzzy (fold)") | |
475 | (default . f) | |
476 | (type . const)))))))))) | |
477 | (gnus-score-custom-integer-type | |
478 | (type . list) | |
479 | (data ((type . repeat) | |
480 | (header . nil) | |
481 | (data . ((type . list) | |
482 | (compact . t) | |
483 | (data ((tag . "Match") | |
484 | (type . integer)) | |
485 | ((tag . "Score") | |
486 | (type . integer)) | |
487 | ((tag . "Date") | |
488 | (type . choice) | |
489 | (data ((type . integer) | |
490 | (default . 0) | |
491 | (width . 9)) | |
492 | ((tag . "Permanent") | |
493 | (type . const) | |
494 | (default . nil)))) | |
495 | ((tag . "Type") | |
496 | (type . choice) | |
497 | (data ((tag . "<") | |
498 | (default . <) | |
499 | (type . const)) | |
500 | ((tag . ">") | |
501 | (default . >) | |
502 | (type . const)) | |
503 | ((tag . "=") | |
504 | (default . =) | |
505 | (type . const)) | |
506 | ((tag . ">=") | |
507 | (default . >=) | |
508 | (type . const)) | |
509 | ((tag . "<=") | |
510 | (default . <=) | |
511 | (type . const)))))))))) | |
512 | (gnus-score-custom-date-type | |
513 | (type . list) | |
514 | (data ((type . repeat) | |
515 | (header . nil) | |
516 | (data . ((type . list) | |
517 | (compact . t) | |
518 | (data ((tag . "Match") | |
519 | (width . 59) | |
520 | (type . string)) | |
521 | "\n " | |
522 | ((tag . "Score") | |
523 | (type . integer)) | |
524 | ((tag . "Date") | |
525 | (type . choice) | |
526 | (data ((type . integer) | |
527 | (default . 0) | |
528 | (width . 9)) | |
529 | ((tag . "Permanent") | |
530 | (type . const) | |
531 | (default . nil)))) | |
532 | ((tag . "Type") | |
533 | (type . choice) | |
534 | (data ((tag . "Before") | |
535 | (default . before) | |
536 | (type . const)) | |
537 | ((tag . "After") | |
538 | (default . after) | |
539 | (type . const)) | |
540 | ((tag . "At") | |
541 | (default . at) | |
542 | (type . const)))))))))))) | |
543 | ||
544 | (defvar gnus-score-custom-file nil | |
545 | "Name of SCORE file being customized.") | |
546 | ||
547 | (defun gnus-score-customize () | |
548 | "Create a buffer for editing gnus SCORE files." | |
549 | (interactive) | |
550 | (let (gnus-score-alist) | |
551 | (custom-buffer-create "*Score Edit*" gnus-score-custom-data | |
552 | gnus-score-custom-type-properties | |
553 | 'gnus-score-custom-set | |
554 | 'gnus-score-custom-get | |
555 | 'gnus-score-custom-save)) | |
556 | (make-local-variable 'gnus-score-custom-file) | |
557 | (setq gnus-score-custom-file (expand-file-name "SCORE" "~/News")) | |
558 | (make-local-variable 'gnus-score-alist) | |
559 | (setq gnus-score-alist nil) | |
560 | (custom-reset-all)) | |
561 | ||
562 | (defun gnus-score-custom-get (name) | |
563 | (if (eq name 'file) | |
564 | gnus-score-custom-file | |
565 | (let ((entry (assoc (symbol-name name) gnus-score-alist))) | |
566 | (if entry | |
567 | (mapcar 'gnus-score-custom-sanify (cdr entry)) | |
568 | (setq entry (assoc name gnus-score-alist)) | |
569 | (if (or (memq name '(files exclude-files local)) | |
570 | (and (eq name 'adapt) | |
571 | (not (symbolp (car (cdr entry)))))) | |
572 | (cdr entry) | |
573 | (car (cdr entry))))))) | |
574 | ||
575 | (defun gnus-score-custom-set (name value) | |
576 | (cond ((eq name 'file) | |
577 | (setq gnus-score-custom-file value)) | |
578 | ((assoc (symbol-name name) gnus-score-alist) | |
579 | (if value | |
580 | (setcdr (assoc (symbol-name name) gnus-score-alist) value) | |
581 | (setq gnus-score-alist (delq (assoc (symbol-name name) | |
582 | gnus-score-alist) | |
583 | gnus-score-alist)))) | |
584 | ((assoc (symbol-name name) gnus-header-index) | |
585 | (if value | |
586 | (setq gnus-score-alist | |
587 | (cons (cons (symbol-name name) value) gnus-score-alist)))) | |
588 | ((assoc name gnus-score-alist) | |
589 | (cond ((null value) | |
590 | (setq gnus-score-alist (delq (assoc name gnus-score-alist) | |
591 | gnus-score-alist))) | |
592 | ((and (listp value) (not (eq name 'eval))) | |
593 | (setcdr (assoc name gnus-score-alist) value)) | |
594 | (t | |
595 | (setcdr (assoc name gnus-score-alist) (list value))))) | |
596 | ((null value)) | |
597 | ((and (listp value) (not (eq name 'eval))) | |
598 | (setq gnus-score-alist (cons (cons name value) gnus-score-alist))) | |
599 | (t | |
600 | (setq gnus-score-alist | |
601 | (cons (cons name (list value)) gnus-score-alist))))) | |
602 | ||
603 | (defun gnus-score-custom-sanify (entry) | |
604 | (list (nth 0 entry) | |
605 | (or (nth 1 entry) gnus-score-interactive-default-score) | |
606 | (nth 2 entry) | |
607 | (cond ((null (nth 3 entry)) | |
608 | 's) | |
609 | ((memq (nth 3 entry) '(before after at >= <=)) | |
610 | (nth 3 entry)) | |
611 | (t | |
612 | (intern (substring (symbol-name (nth 3 entry)) 0 1)))))) | |
613 | ||
614 | (defvar gnus-score-cache nil) | |
615 | ||
616 | (defun gnus-score-custom-load () | |
617 | (interactive) | |
618 | (let ((file (custom-name-value 'file))) | |
619 | (if (eq file custom-nil) | |
620 | (error "You must specify a file name")) | |
621 | (setq file (expand-file-name file "~/News")) | |
622 | (gnus-score-load file) | |
623 | (setq gnus-score-custom-file file) | |
624 | (custom-reset-all) | |
625 | (message "Loaded"))) | |
626 | ||
627 | (defun gnus-score-custom-save () | |
628 | (interactive) | |
629 | (custom-apply-all) | |
630 | (gnus-score-remove-from-cache gnus-score-custom-file) | |
631 | (let ((file gnus-score-custom-file) | |
632 | (score gnus-score-alist) | |
633 | emacs-lisp-mode-hook) | |
634 | (save-excursion | |
635 | (set-buffer (get-buffer-create "*Score*")) | |
636 | (buffer-disable-undo (current-buffer)) | |
637 | (erase-buffer) | |
638 | (pp score (current-buffer)) | |
639 | (gnus-make-directory (file-name-directory file)) | |
640 | (write-region (point-min) (point-max) file nil 'silent) | |
641 | (kill-buffer (current-buffer)))) | |
642 | (message "Saved")) | |
643 | ||
644 | (provide 'gnus-edit) | |
645 | ||
646 | ;;; gnus-edit.el end here |