2 * Copyright notice from original mutt:
3 * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
5 * This file is part of mutt-ng, see http://www.muttng.org/.
6 * It's licensed under the GNU General Public License,
7 * please see the file GPL in the top level source directory.
10 #include <lib-lib/lib-lib.h>
16 @import "lib-lua/base.cpkg"
18 typedef struct score_t {
22 int exact; /* if this rule matches, don't evaluate any more */
25 DO_INIT(score_t, score);
26 static void score_wipe(score_t *sc)
28 pattern_list_wipe(&sc->pat);
31 DO_NEW(score_t, score);
32 DO_DELETE(score_t, score);
33 DO_SLIST(score_t, score, score_delete);
35 static score_t *Score = NULL;
41 ** When this variable is \fIunset\fP, scoring is turned off. This can
42 ** be useful to selectively disable scoring for certain folders when the
43 ** ``$$score_threshold_delete'' variable and friends are used.
46 int threshold_flag = 9999;
49 ** Messages which have been assigned a score greater than or equal to this
50 ** variable's value are automatically marked ``flagged''.
52 int threshold_delete = -1;
55 ** Messages which have been assigned a score equal to or lower than the value
56 ** of this variable are automatically marked for deletion by Madmutt. Since
57 ** Madmutt scores are always greater than or equal to zero, the default setting
58 ** of this variable will never mark a message for deletion.
60 int threshold_read = -1;
63 ** Messages which have been assigned a score equal to or lower than the value
64 ** of this variable are automatically marked as read by Madmutt. Since
65 ** Madmutt scores are always greater than or equal to zero, the default setting
66 ** of this variable will never mark a message read.
69 void score(string_t pattern, int value) {
73 for (last = &Score; *last; last = &(*last)->next) {
74 if (!m_strcmp(pattern, (*last)->str))
78 /* FIXME need a buffer for error */
79 struct pattern_t *pat = mutt_pattern_comp(pattern, 0, NULL);
87 (*last)->str = pattern;
90 pc += (*last)->exact = (*pc == '=');
92 set_option(OPTNEEDRESCORE);
96 void unscore(const string_t pattern) {
97 if (!m_strcmp(pattern, "*")) {
98 score_list_wipe(&Score);
99 set_option(OPTNEEDRESCORE);
102 for (score_t **last = &Score; *last; last = &(*last)->next) {
103 if (!m_strcmp(pattern, (*last)->str)) {
104 score_t *tmp = score_list_pop(last);
106 set_option(OPTNEEDRESCORE);
114 void mutt_score_message (CONTEXT * ctx, HEADER * hdr, int upd_ctx)
116 hdr->score = 0; /* in case of re-scoring */
117 for (score_t *tmp = Score; tmp; tmp = tmp->next) {
118 if (mutt_pattern_exec (tmp->pat, M_MATCH_FULL_ADDRESS, NULL, hdr) > 0) {
119 if (tmp->exact || tmp->val == 9999 || tmp->val == -9999) {
120 hdr->score = tmp->val;
123 hdr->score += tmp->val;
129 if (hdr->score <= mod_score.threshold_delete)
130 _mutt_set_flag(ctx, hdr, M_DELETE, 1, upd_ctx);
131 if (hdr->score <= mod_score.threshold_read)
132 _mutt_set_flag(ctx, hdr, M_READ, 1, upd_ctx);
133 if (hdr->score >= mod_score.threshold_flag)
134 _mutt_set_flag(ctx, hdr, M_FLAG, 1, upd_ctx);
137 void mutt_check_rescore (CONTEXT * ctx)
139 if (option(OPTNEEDRESCORE) && mod_score.enable) {
140 if (((Sort | SortAux) & SORT_MASK) == SORT_SCORE) {
141 set_option(OPTNEEDRESORT);
142 if ((Sort & SORT_MASK) == SORT_THREADS)
143 set_option(OPTSORTSUBTHREADS);
146 /* must redraw the index since the user might have %N in it */
147 set_option(OPTFORCEREDRAWINDEX);
148 set_option(OPTFORCEREDRAWPAGER);
150 for (int i = 0; ctx && i < ctx->msgcount; i++) {
151 mutt_score_message(ctx, ctx->hdrs[i], 1);
152 ctx->hdrs[i]->pair = 0;
155 unset_option(OPTNEEDRESCORE);