1 ;;; gnus-score.el --- scoring code for Gnus
2 ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;; Free Software Foundation, Inc.
5 ;; Author: Per Abrahamsen <amanda@iesd.auc.dk>
6 ;; Lars Magne Ingebrigtsen <larsi@gnus.org>
9 ;; This file is part of GNU Emacs.
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)
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.
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.
30 (eval-when-compile (require 'cl))
39 (autoload 'ffap-string-at-point "ffap")
41 (defcustom gnus-global-score-files nil
42 "List of global score files and directories.
43 Set this variable if you want to use people's score files. One entry
44 for each score file or each score file directory. Gnus will decide
45 by itself what score files are applicable to which group.
47 Say you want to use the single score file
48 \"/ftp.gnus.org@ftp:/pub/larsi/ding/score/soc.motss.SCORE\" and all
49 score files in the \"/ftp.some-where:/pub/score\" directory.
51 (setq gnus-global-score-files
52 '(\"/ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE\"
53 \"/ftp.some-where:/pub/score\"))"
54 :group 'gnus-score-files
57 (defcustom gnus-score-file-single-match-alist nil
58 "Alist mapping regexps to lists of score files.
59 Each element of this alist should be of the form
60 (\"REGEXP\" [ \"SCORE-FILE-1\" ] [ \"SCORE-FILE-2\" ] ... )
62 If the name of a group is matched by REGEXP, the corresponding scorefiles
63 will be used for that group.
64 The first match found is used, subsequent matching entries are ignored (to
65 use multiple matches, see `gnus-score-file-multiple-match-alist').
67 These score files are loaded in addition to any files returned by
68 `gnus-score-find-score-files-function'."
69 :group 'gnus-score-files
70 :type '(repeat (cons regexp (repeat file))))
72 (defcustom gnus-score-file-multiple-match-alist nil
73 "Alist mapping regexps to lists of score files.
74 Each element of this alist should be of the form
75 (\"REGEXP\" [ \"SCORE-FILE-1\" ] [ \"SCORE-FILE-2\" ] ... )
77 If the name of a group is matched by REGEXP, the corresponding scorefiles
78 will be used for that group.
79 If multiple REGEXPs match a group, the score files corresponding to each
80 match will be used (for only one match to be used, see
81 `gnus-score-file-single-match-alist').
83 These score files are loaded in addition to any files returned by
84 `gnus-score-find-score-files-function'."
85 :group 'gnus-score-files
86 :type '(repeat (cons regexp (repeat file))))
88 (defcustom gnus-score-file-suffix "SCORE"
89 "Suffix of the score files."
90 :group 'gnus-score-files
93 (defcustom gnus-adaptive-file-suffix "ADAPT"
94 "Suffix of the adaptive score files."
95 :group 'gnus-score-files
96 :group 'gnus-score-adapt
99 (defcustom gnus-score-find-score-files-function 'gnus-score-find-bnews
100 "Function used to find score files.
101 The function will be called with the group name as the argument, and
102 should return a list of score files to apply to that group. The score
103 files do not actually have to exist.
105 Predefined values are:
107 `gnus-score-find-single': Only apply the group's own score file.
108 `gnus-score-find-hierarchical': Also apply score files from parent groups.
109 `gnus-score-find-bnews': Apply score files whose names matches.
111 See the documentation to these functions for more information.
113 This variable can also be a list of functions to be called. Each
114 function is given the group name as argument and should either return
115 a list of score files, or a list of score alists.
117 If functions other than these pre-defined functions are used,
118 the `a' symbolic prefix to the score commands will always use
120 :group 'gnus-score-files
121 :type '(radio (function-item gnus-score-find-single)
122 (function-item gnus-score-find-hierarchical)
123 (function-item gnus-score-find-bnews)
124 (repeat :tag "List of functions"
125 (choice (function :tag "Other" :value 'ignore)
126 (function-item gnus-score-find-single)
127 (function-item gnus-score-find-hierarchical)
128 (function-item gnus-score-find-bnews)))
129 (function :tag "Other" :value 'ignore)))
131 (defcustom gnus-score-interactive-default-score 1000
132 "*Scoring commands will raise/lower the score with this number as the default."
133 :group 'gnus-score-default
136 (defcustom gnus-score-expiry-days 7
137 "*Number of days before unused score file entries are expired.
138 If this variable is nil, no score file entries will be expired."
139 :group 'gnus-score-expire
140 :type '(choice (const :tag "never" nil)
143 (defcustom gnus-update-score-entry-dates t
144 "*In non-nil, update matching score entry dates.
145 If this variable is nil, then score entries that provide matches
146 will be expired along with non-matching score entries."
147 :group 'gnus-score-expire
150 (defcustom gnus-decay-scores nil
151 "*If non-nil, decay non-permanent scores."
152 :group 'gnus-score-decay
155 (defcustom gnus-decay-score-function 'gnus-decay-score
156 "*Function called to decay a score.
157 It is called with one parameter -- the score to be decayed."
158 :group 'gnus-score-decay
159 :type '(radio (function-item gnus-decay-score)
160 (function :tag "Other")))
162 (defcustom gnus-score-decay-constant 3
163 "*Decay all \"small\" scores with this amount."
164 :group 'gnus-score-decay
167 (defcustom gnus-score-decay-scale .05
168 "*Decay all \"big\" scores with this factor."
169 :group 'gnus-score-decay
172 (defcustom gnus-home-score-file nil
173 "Variable to control where interactive score entries are to go.
177 This file file will be used as the home score file.
180 The result of this function will be used as the home score file.
181 The function will be passed the name of the group as its
185 The elements in this list can be:
187 * `(regexp file-name ...)'
188 If the `regexp' matches the group name, the first `file-name' will
189 will be used as the home score file. (Multiple filenames are
190 allowed so that one may use gnus-score-file-single-match-alist to
194 If the function returns non-nil, the result will be used
195 as the home score file. The function will be passed the
196 name of the group as its parameter.
198 * A string. Use the string as the home score file.
200 The list will be traversed from the beginning towards the end looking
202 :group 'gnus-score-files
203 :type '(choice string
204 (repeat (choice string
205 (cons regexp (repeat file))
206 (function :value fun)))
207 (function-item gnus-hierarchial-home-score-file)
208 (function-item gnus-current-home-score-file)
209 (function :value fun)))
211 (defcustom gnus-home-adapt-file nil
212 "Variable to control where new adaptive score entries are to go.
213 This variable allows the same syntax as `gnus-home-score-file'."
214 :group 'gnus-score-adapt
215 :group 'gnus-score-files
216 :type '(choice string
217 (repeat (choice string
218 (cons regexp (repeat file))
219 (function :value fun)))
220 (function :value fun)))
222 (defcustom gnus-default-adaptive-score-alist
223 '((gnus-kill-file-mark)
225 (gnus-read-mark (from 3) (subject 30))
226 (gnus-catchup-mark (subject -10))
227 (gnus-killed-mark (from -1) (subject -20))
228 (gnus-del-mark (from -2) (subject -15)))
229 "*Alist of marks and scores."
230 :group 'gnus-score-adapt
231 :type '(repeat (cons (symbol :tag "Mark")
232 (repeat (list (choice :tag "Header"
235 (symbol :tag "other"))
236 (integer :tag "Score"))))))
238 (defcustom gnus-adaptive-word-length-limit nil
239 "*Words of a length lesser than this limit will be ignored when doing adaptive scoring."
240 :group 'gnus-score-adapt
243 (defcustom gnus-ignored-adaptive-words nil
244 "List of words to be ignored when doing adaptive word scoring."
245 :group 'gnus-score-adapt
246 :type '(repeat string))
248 (defcustom gnus-default-ignored-adaptive-words
249 '("a" "i" "the" "to" "of" "and" "in" "is" "it" "for" "that" "if" "you"
250 "this" "be" "on" "with" "not" "have" "are" "or" "as" "from" "can"
251 "but" "by" "at" "an" "will" "no" "all" "was" "do" "there" "my" "one"
252 "so" "we" "they" "what" "would" "any" "which" "about" "get" "your"
253 "use" "some" "me" "then" "name" "like" "out" "when" "up" "time"
254 "other" "more" "only" "just" "end" "also" "know" "how" "new" "should"
255 "been" "than" "them" "he" "who" "make" "may" "people" "these" "now"
256 "their" "here" "into" "first" "could" "way" "had" "see" "work" "well"
257 "were" "two" "very" "where" "while" "us" "because" "good" "same"
258 "even" "much" "most" "many" "such" "long" "his" "over" "last" "since"
259 "right" "before" "our" "without" "too" "those" "why" "must" "part"
260 "being" "current" "back" "still" "go" "point" "value" "each" "did"
261 "both" "true" "off" "say" "another" "state" "might" "under" "start"
263 "*Default list of words to be ignored when doing adaptive word scoring."
264 :group 'gnus-score-adapt
265 :type '(repeat string))
267 (defcustom gnus-default-adaptive-word-score-alist
268 `((,gnus-read-mark . 30)
269 (,gnus-catchup-mark . -10)
270 (,gnus-killed-mark . -20)
271 (,gnus-del-mark . -15))
272 "*Alist of marks and scores."
273 :group 'gnus-score-adapt
274 :type '(repeat (cons (character :tag "Mark")
275 (integer :tag "Score"))))
277 (defcustom gnus-adaptive-word-minimum nil
278 "If a number, this is the minimum score value that can be assigned to a word."
279 :group 'gnus-score-adapt
280 :type '(choice (const nil) integer))
282 (defcustom gnus-adaptive-word-no-group-words nil
283 "If t, don't adaptively score words included in the group name."
284 :group 'gnus-score-adapt
287 (defcustom gnus-score-mimic-keymap nil
288 "*Have the score entry functions pretend that they are a keymap."
289 :group 'gnus-score-default
292 (defcustom gnus-score-exact-adapt-limit 10
293 "*Number that says how long a match has to be before using substring matching.
294 When doing adaptive scoring, one normally uses fuzzy or substring
295 matching. However, if the header one matches is short, the possibility
296 for false positives is great, so if the length of the match is less
297 than this variable, exact matching will be used.
299 If this variable is nil, exact matching will always be used."
300 :group 'gnus-score-adapt
301 :type '(choice (const nil) integer))
303 (defcustom gnus-score-uncacheable-files "ADAPT$"
304 "All score files that match this regexp will not be cached."
305 :group 'gnus-score-adapt
306 :group 'gnus-score-files
309 (defcustom gnus-score-default-header nil
310 "Default header when entering new scores.
312 Should be one of the following symbols.
321 e: `extra' (non-standard overview)
326 If nil, the user will be asked for a header."
327 :group 'gnus-score-default
328 :type '(choice (const :tag "from" a)
329 (const :tag "subject" s)
330 (const :tag "body" b)
331 (const :tag "head" h)
332 (const :tag "message-id" i)
333 (const :tag "references" t)
334 (const :tag "xref" x)
335 (const :tag "extra" e)
336 (const :tag "lines" l)
337 (const :tag "date" d)
338 (const :tag "followup" f)
339 (const :tag "ask" nil)))
341 (defcustom gnus-score-default-type nil
342 "Default match type when entering new scores.
344 Should be one of the following symbols.
354 >: greater than number
357 If nil, the user will be asked for a match type."
358 :group 'gnus-score-default
359 :type '(choice (const :tag "substring" s)
360 (const :tag "exact string" e)
361 (const :tag "fuzzy string" f)
362 (const :tag "regexp string" r)
363 (const :tag "before date" b)
364 (const :tag "after date" a)
365 (const :tag "this date" n)
366 (const :tag "less than number" <)
367 (const :tag "greater than number" >)
368 (const :tag "equal than number" =)
369 (const :tag "ask" nil)))
371 (defcustom gnus-score-default-fold nil
372 "Use case folding for new score file entries iff not nil."
373 :group 'gnus-score-default
376 (defcustom gnus-score-default-duration nil
377 "Default duration of effect when entering new scores.
379 Should be one of the following symbols.