Mercurial > hg > xemacs-beta
comparison lisp/gnus/gnus-kill.el @ 16:0293115a14e9 r19-15b91
Import from CVS: tag r19-15b91
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:49:20 +0200 |
parents | 376386a54a3c |
children | 4103f0995bd7 |
comparison
equal
deleted
inserted
replaced
15:ad457d5f7d04 | 16:0293115a14e9 |
---|---|
1 ;;; gnus-kill.el --- kill commands for Gnus | 1 ;;; gnus-kill.el --- kill commands for Gnus |
2 ;; Copyright (C) 1995,96 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1995,96,97 Free Software Foundation, Inc. |
3 | 3 |
4 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet> | 4 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet> |
5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no> | 5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no> |
6 ;; Keywords: news | 6 ;; Keywords: news |
7 | 7 |
25 ;;; Commentary: | 25 ;;; Commentary: |
26 | 26 |
27 ;;; Code: | 27 ;;; Code: |
28 | 28 |
29 (require 'gnus) | 29 (require 'gnus) |
30 (eval-when-compile (require 'cl)) | 30 (require 'gnus-art) |
31 | 31 (require 'gnus-range) |
32 (defvar gnus-kill-file-mode-hook nil | 32 |
33 "*A hook for Gnus kill file mode.") | 33 (defcustom gnus-kill-file-mode-hook nil |
34 | 34 "Hook for Gnus kill file mode." |
35 (defvar gnus-kill-expiry-days 7 | 35 :group 'gnus-score |
36 "*Number of days before expiring unused kill file entries.") | 36 :type 'hook) |
37 | 37 |
38 (defvar gnus-kill-save-kill-file nil | 38 (defcustom gnus-kill-expiry-days 7 |
39 "*If non-nil, will save kill files after processing them.") | 39 "*Number of days before expiring unused kill file entries." |
40 | 40 :group 'gnus-score |
41 (defvar gnus-winconf-kill-file nil) | 41 :type 'integer) |
42 | |
43 (defcustom gnus-kill-save-kill-file nil | |
44 "*If non-nil, will save kill files after processing them." | |
45 :group 'gnus-score | |
46 :type 'boolean) | |
47 | |
48 (defcustom gnus-winconf-kill-file nil | |
49 "What does this do, Lars?" | |
50 :group 'gnus-score | |
51 :type 'sexp) | |
52 | |
53 (defcustom gnus-kill-killed t | |
54 "*If non-nil, Gnus will apply kill files to already killed articles. | |
55 If it is nil, Gnus will never apply kill files to articles that have | |
56 already been through the scoring process, which might very well save lots | |
57 of time." | |
58 :group 'gnus-score | |
59 :type 'boolean) | |
42 | 60 |
43 | 61 |
44 | 62 |
45 (defmacro gnus-raise (field expression level) | 63 (defmacro gnus-raise (field expression level) |
46 `(gnus-kill ,field ,expression | 64 `(gnus-kill ,field ,expression |
55 ;;; | 73 ;;; |
56 | 74 |
57 (defvar gnus-kill-file-mode-map nil) | 75 (defvar gnus-kill-file-mode-map nil) |
58 | 76 |
59 (unless gnus-kill-file-mode-map | 77 (unless gnus-kill-file-mode-map |
60 (gnus-define-keymap | 78 (gnus-define-keymap (setq gnus-kill-file-mode-map |
61 (setq gnus-kill-file-mode-map (copy-keymap emacs-lisp-mode-map)) | 79 (copy-keymap emacs-lisp-mode-map)) |
62 "\C-c\C-k\C-s" gnus-kill-file-kill-by-subject | 80 "\C-c\C-k\C-s" gnus-kill-file-kill-by-subject |
63 "\C-c\C-k\C-a" gnus-kill-file-kill-by-author | 81 "\C-c\C-k\C-a" gnus-kill-file-kill-by-author |
64 "\C-c\C-k\C-t" gnus-kill-file-kill-by-thread | 82 "\C-c\C-k\C-t" gnus-kill-file-kill-by-thread |
65 "\C-c\C-k\C-x" gnus-kill-file-kill-by-xref | 83 "\C-c\C-k\C-x" gnus-kill-file-kill-by-xref |
66 "\C-c\C-a" gnus-kill-file-apply-buffer | 84 "\C-c\C-a" gnus-kill-file-apply-buffer |
67 "\C-c\C-e" gnus-kill-file-apply-last-sexp | 85 "\C-c\C-e" gnus-kill-file-apply-last-sexp |
68 "\C-c\C-c" gnus-kill-file-exit)) | 86 "\C-c\C-c" gnus-kill-file-exit)) |
69 | 87 |
70 (defun gnus-kill-file-mode () | 88 (defun gnus-kill-file-mode () |
71 "Major mode for editing kill files. | 89 "Major mode for editing kill files. |
72 | 90 |
73 If you are using this mode - you probably shouldn't. Kill files | 91 If you are using this mode - you probably shouldn't. Kill files |
91 purpose is not so easy because the internal working of Gnus must be | 109 purpose is not so easy because the internal working of Gnus must be |
92 well-known. For this reason, Gnus provides a general function which | 110 well-known. For this reason, Gnus provides a general function which |
93 does this easily for non-Lisp programmers. | 111 does this easily for non-Lisp programmers. |
94 | 112 |
95 The `gnus-kill' function executes commands available in Summary Mode | 113 The `gnus-kill' function executes commands available in Summary Mode |
96 by their key sequences. `gnus-kill' should be called with FIELD, | 114 by their key sequences. `gnus-kill' should be called with FIELD, |
97 REGEXP and optional COMMAND and ALL. FIELD is a string representing | 115 REGEXP and optional COMMAND and ALL. FIELD is a string representing |
98 the header field or an empty string. If FIELD is an empty string, the | 116 the header field or an empty string. If FIELD is an empty string, the |
99 entire article body is searched for. REGEXP is a string which is | 117 entire article body is searched for. REGEXP is a string which is |
100 compared with FIELD value. COMMAND is a string representing a valid | 118 compared with FIELD value. COMMAND is a string representing a valid |
101 key sequence in Summary mode or Lisp expression. COMMAND defaults to | 119 key sequence in Summary mode or Lisp expression. COMMAND defaults to |
102 '(gnus-summary-mark-as-read nil \"X\"). Make sure that COMMAND is | 120 '(gnus-summary-mark-as-read nil \"X\"). Make sure that COMMAND is |
103 executed in the Summary buffer. If the second optional argument ALL | 121 executed in the Summary buffer. If the second optional argument ALL |
104 is non-nil, the COMMAND is applied to articles which are already | 122 is non-nil, the COMMAND is applied to articles which are already |
105 marked as read or unread. Articles which are marked are skipped over | 123 marked as read or unread. Articles which are marked are skipped over |
106 by default. | 124 by default. |
178 ;; Enter kill file entry. | 196 ;; Enter kill file entry. |
179 ;; FIELD: String containing the name of the header field to kill. | 197 ;; FIELD: String containing the name of the header field to kill. |
180 ;; REGEXP: The string to kill. | 198 ;; REGEXP: The string to kill. |
181 (save-excursion | 199 (save-excursion |
182 (let (string) | 200 (let (string) |
183 (or (eq major-mode 'gnus-kill-file-mode) | 201 (unless (eq major-mode 'gnus-kill-file-mode) |
184 (gnus-kill-set-kill-buffer)) | 202 (gnus-kill-set-kill-buffer)) |
185 (unless dont-move | 203 (unless dont-move |
186 (goto-char (point-max))) | 204 (goto-char (point-max))) |
187 (insert (setq string (format "(gnus-kill %S %S)\n" field regexp))) | 205 (insert (setq string (format "(gnus-kill %S %S)\n" field regexp))) |
188 (gnus-kill-file-apply-string string)))) | 206 (gnus-kill-file-apply-string string)))) |
189 | 207 |
193 (gnus-kill-file-enter-kill | 211 (gnus-kill-file-enter-kill |
194 "Subject" | 212 "Subject" |
195 (if (vectorp gnus-current-headers) | 213 (if (vectorp gnus-current-headers) |
196 (regexp-quote | 214 (regexp-quote |
197 (gnus-simplify-subject (mail-header-subject gnus-current-headers))) | 215 (gnus-simplify-subject (mail-header-subject gnus-current-headers))) |
198 "") t)) | 216 "") |
217 t)) | |
199 | 218 |
200 (defun gnus-kill-file-kill-by-author () | 219 (defun gnus-kill-file-kill-by-author () |
201 "Kill by author." | 220 "Kill by author." |
202 (interactive) | 221 (interactive) |
203 (gnus-kill-file-enter-kill | 222 (gnus-kill-file-enter-kill |
216 ""))) | 235 ""))) |
217 | 236 |
218 (defun gnus-kill-file-kill-by-xref () | 237 (defun gnus-kill-file-kill-by-xref () |
219 "Kill by Xref." | 238 "Kill by Xref." |
220 (interactive) | 239 (interactive) |
221 (let ((xref (and (vectorp gnus-current-headers) | 240 (let ((xref (and (vectorp gnus-current-headers) |
222 (mail-header-xref gnus-current-headers))) | 241 (mail-header-xref gnus-current-headers))) |
223 (start 0) | 242 (start 0) |
224 group) | 243 group) |
225 (if xref | 244 (if xref |
226 (while (string-match " \\([^ \t]+\\):" xref start) | 245 (while (string-match " \\([^ \t]+\\):" xref start) |
227 (setq start (match-end 0)) | 246 (setq start (match-end 0)) |
228 (if (not (string= | 247 (when (not (string= |
229 (setq group | 248 (setq group |
230 (substring xref (match-beginning 1) (match-end 1))) | 249 (substring xref (match-beginning 1) (match-end 1))) |
231 gnus-newsgroup-name)) | 250 gnus-newsgroup-name)) |
232 (gnus-kill-file-enter-kill | 251 (gnus-kill-file-enter-kill |
233 "Xref" (concat " " (regexp-quote group) ":") t))) | 252 "Xref" (concat " " (regexp-quote group) ":") t))) |
234 (gnus-kill-file-enter-kill "Xref" "" t)))) | 253 (gnus-kill-file-enter-kill "Xref" "" t)))) |
235 | 254 |
236 (defun gnus-kill-file-raise-followups-to-author (level) | 255 (defun gnus-kill-file-raise-followups-to-author (level) |
237 "Raise score for all followups to the current author." | 256 "Raise score for all followups to the current author." |
238 (interactive "p") | 257 (interactive "p") |
291 "Save a kill file, then return to the previous buffer." | 310 "Save a kill file, then return to the previous buffer." |
292 (interactive) | 311 (interactive) |
293 (save-buffer) | 312 (save-buffer) |
294 (let ((killbuf (current-buffer))) | 313 (let ((killbuf (current-buffer))) |
295 ;; We don't want to return to article buffer. | 314 ;; We don't want to return to article buffer. |
296 (and (get-buffer gnus-article-buffer) | 315 (when (get-buffer gnus-article-buffer) |
297 (bury-buffer gnus-article-buffer)) | 316 (bury-buffer gnus-article-buffer)) |
298 ;; Delete the KILL file windows. | 317 ;; Delete the KILL file windows. |
299 (delete-windows-on killbuf) | 318 (delete-windows-on killbuf) |
300 ;; Restore last window configuration if available. | 319 ;; Restore last window configuration if available. |
301 (and gnus-winconf-kill-file | 320 (when gnus-winconf-kill-file |
302 (set-window-configuration gnus-winconf-kill-file)) | 321 (set-window-configuration gnus-winconf-kill-file)) |
303 (setq gnus-winconf-kill-file nil) | 322 (setq gnus-winconf-kill-file nil) |
304 ;; Kill the KILL file buffer. Suggested by tale@pawl.rpi.edu. | 323 ;; Kill the KILL file buffer. Suggested by tale@pawl.rpi.edu. |
305 (kill-buffer killbuf))) | 324 (kill-buffer killbuf))) |
306 | 325 |
307 ;; For kill files | 326 ;; For kill files |
332 | 351 |
333 (defun gnus-apply-kill-file-unless-scored () | 352 (defun gnus-apply-kill-file-unless-scored () |
334 "Apply .KILL file, unless a .SCORE file for the same newsgroup exists." | 353 "Apply .KILL file, unless a .SCORE file for the same newsgroup exists." |
335 (cond ((file-exists-p (gnus-score-file-name gnus-newsgroup-name)) | 354 (cond ((file-exists-p (gnus-score-file-name gnus-newsgroup-name)) |
336 ;; Ignores global KILL. | 355 ;; Ignores global KILL. |
337 (if (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name)) | 356 (when (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name)) |
338 (gnus-message 3 "Note: Ignoring %s.KILL; preferring .SCORE" | 357 (gnus-message 3 "Note: Ignoring %s.KILL; preferring .SCORE" |
339 gnus-newsgroup-name)) | 358 gnus-newsgroup-name)) |
340 0) | 359 0) |
341 ((or (file-exists-p (gnus-newsgroup-kill-file nil)) | 360 ((or (file-exists-p (gnus-newsgroup-kill-file nil)) |
342 (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name))) | 361 (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name))) |
343 (gnus-apply-kill-file-internal)) | 362 (gnus-apply-kill-file-internal)) |
344 (t | 363 (t |
353 (gnus-summary-inhibit-highlight t) | 372 (gnus-summary-inhibit-highlight t) |
354 beg) | 373 beg) |
355 (setq gnus-newsgroup-kill-headers nil) | 374 (setq gnus-newsgroup-kill-headers nil) |
356 ;; If there are any previously scored articles, we remove these | 375 ;; If there are any previously scored articles, we remove these |
357 ;; from the `gnus-newsgroup-headers' list that the score functions | 376 ;; from the `gnus-newsgroup-headers' list that the score functions |
358 ;; will see. This is probably pretty wasteful when it comes to | 377 ;; will see. This is probably pretty wasteful when it comes to |
359 ;; conses, but is, I think, faster than having to assq in every | 378 ;; conses, but is, I think, faster than having to assq in every |
360 ;; single score function. | 379 ;; single score function. |
361 (let ((files kill-files)) | 380 (let ((files kill-files)) |
362 (while files | 381 (while files |
363 (if (file-exists-p (car files)) | 382 (if (file-exists-p (car files)) |
365 (if gnus-kill-killed | 384 (if gnus-kill-killed |
366 (setq gnus-newsgroup-kill-headers | 385 (setq gnus-newsgroup-kill-headers |
367 (mapcar (lambda (header) (mail-header-number header)) | 386 (mapcar (lambda (header) (mail-header-number header)) |
368 headers)) | 387 headers)) |
369 (while headers | 388 (while headers |
370 (or (gnus-member-of-range | 389 (unless (gnus-member-of-range |
371 (mail-header-number (car headers)) | 390 (mail-header-number (car headers)) |
372 gnus-newsgroup-killed) | 391 gnus-newsgroup-killed) |
373 (setq gnus-newsgroup-kill-headers | 392 (push (mail-header-number (car headers)) |
374 (cons (mail-header-number (car headers)) | 393 gnus-newsgroup-kill-headers)) |
375 gnus-newsgroup-kill-headers))) | |
376 (setq headers (cdr headers)))) | 394 (setq headers (cdr headers)))) |
377 (setq files nil)) | 395 (setq files nil)) |
378 (setq files (cdr files))))) | 396 (setq files (cdr files))))) |
379 (if (not gnus-newsgroup-kill-headers) | 397 (if (not gnus-newsgroup-kill-headers) |
380 () | 398 () |
386 (gnus-message 6 "Processing kill file %s..." (car kill-files)) | 404 (gnus-message 6 "Processing kill file %s..." (car kill-files)) |
387 (find-file (car kill-files)) | 405 (find-file (car kill-files)) |
388 (gnus-add-current-to-buffer-list) | 406 (gnus-add-current-to-buffer-list) |
389 (goto-char (point-min)) | 407 (goto-char (point-min)) |
390 | 408 |
391 (if (consp (condition-case nil (read (current-buffer)) | 409 (if (consp (ignore-errors (read (current-buffer)))) |
392 (error nil))) | |
393 (gnus-kill-parse-gnus-kill-file) | 410 (gnus-kill-parse-gnus-kill-file) |
394 (gnus-kill-parse-rn-kill-file)) | 411 (gnus-kill-parse-rn-kill-file)) |
395 | 412 |
396 (gnus-message | 413 (gnus-message |
397 6 "Processing kill file %s...done" (car kill-files))) | 414 6 "Processing kill file %s...done" (car kill-files))) |
421 (goto-char (point-min)) | 438 (goto-char (point-min)) |
422 (gnus-kill-file-mode) | 439 (gnus-kill-file-mode) |
423 (let (beg form) | 440 (let (beg form) |
424 (while (progn | 441 (while (progn |
425 (setq beg (point)) | 442 (setq beg (point)) |
426 (setq form (condition-case () (read (current-buffer)) | 443 (setq form (ignore-errors (read (current-buffer))))) |
427 (error nil)))) | 444 (unless (listp form) |
428 (or (listp form) | 445 (error "Illegal kill entry (possibly rn kill file?): %s" form)) |
429 (error "Illegal kill entry (possibly rn kill file?): %s" form)) | |
430 (if (or (eq (car form) 'gnus-kill) | 446 (if (or (eq (car form) 'gnus-kill) |
431 (eq (car form) 'gnus-raise) | 447 (eq (car form) 'gnus-raise) |
432 (eq (car form) 'gnus-lower)) | 448 (eq (car form) 'gnus-lower)) |
433 (progn | 449 (progn |
434 (delete-region beg (point)) | 450 (delete-region beg (point)) |
435 (insert (or (eval form) ""))) | 451 (insert (or (eval form) ""))) |
436 (save-excursion | 452 (save-excursion |
437 (set-buffer gnus-summary-buffer) | 453 (set-buffer gnus-summary-buffer) |
438 (condition-case () (eval form) (error nil))))) | 454 (ignore-errors (eval form))))) |
439 (and (buffer-modified-p) | 455 (and (buffer-modified-p) |
440 gnus-kill-save-kill-file | 456 gnus-kill-save-kill-file |
441 (save-buffer)) | 457 (save-buffer)) |
442 (set-buffer-modified-p nil))) | 458 (set-buffer-modified-p nil))) |
443 | 459 |
444 ;; Parse an rn killfile. | 460 ;; Parse an rn killfile. |
463 (setq commands (buffer-substring (match-beginning 3) (match-end 3))) | 479 (setq commands (buffer-substring (match-beginning 3) (match-end 3))) |
464 | 480 |
465 ;; The "f:+" command marks everything *but* the matches as read, | 481 ;; The "f:+" command marks everything *but* the matches as read, |
466 ;; so we simply first match everything as read, and then unmark | 482 ;; so we simply first match everything as read, and then unmark |
467 ;; PATTERN later. | 483 ;; PATTERN later. |
468 (and (string-match "\\+" commands) | 484 (when (string-match "\\+" commands) |
469 (progn | 485 (gnus-kill "from" ".") |
470 (gnus-kill "from" ".") | 486 (setq commands "m")) |
471 (setq commands "m"))) | |
472 | 487 |
473 (gnus-kill | 488 (gnus-kill |
474 (or (cdr (assq modifier mod-to-header)) "subject") | 489 (or (cdr (assq modifier mod-to-header)) "subject") |
475 pattern | 490 pattern |
476 (if (string-match "m" commands) | 491 (if (string-match "m" commands) |
477 '(gnus-summary-mark-as-unread nil " ") | 492 '(gnus-summary-mark-as-unread nil " ") |
478 '(gnus-summary-mark-as-read nil "X")) | 493 '(gnus-summary-mark-as-read nil "X")) |
479 nil t)) | 494 nil t)) |
480 (forward-line 1)))) | 495 (forward-line 1)))) |
481 | 496 |
482 ;; Kill changes and new format by suggested by JWZ and Sudish Joseph | 497 ;; Kill changes and new format by suggested by JWZ and Sudish Joseph |
483 ;; <joseph@cis.ohio-state.edu>. | 498 ;; <joseph@cis.ohio-state.edu>. |
491 ;; We don't want to change current point nor window configuration. | 506 ;; We don't want to change current point nor window configuration. |
492 (let ((old-buffer (current-buffer))) | 507 (let ((old-buffer (current-buffer))) |
493 (save-excursion | 508 (save-excursion |
494 (save-window-excursion | 509 (save-window-excursion |
495 ;; Selected window must be summary buffer to execute keyboard | 510 ;; Selected window must be summary buffer to execute keyboard |
496 ;; macros correctly. See command_loop_1. | 511 ;; macros correctly. See command_loop_1. |
497 (switch-to-buffer gnus-summary-buffer 'norecord) | 512 (switch-to-buffer gnus-summary-buffer 'norecord) |
498 (goto-char (point-min)) ;From the beginning. | 513 (goto-char (point-min)) ;From the beginning. |
499 (let ((kill-list regexp) | 514 (let ((kill-list regexp) |
500 (date (current-time-string)) | 515 (date (current-time-string)) |
501 (command (or exe-command '(gnus-summary-mark-as-read | 516 (command (or exe-command '(gnus-summary-mark-as-read |
503 kill kdate prev) | 518 kill kdate prev) |
504 (if (listp kill-list) | 519 (if (listp kill-list) |
505 ;; It is a list. | 520 ;; It is a list. |
506 (if (not (consp (cdr kill-list))) | 521 (if (not (consp (cdr kill-list))) |
507 ;; It's on the form (regexp . date). | 522 ;; It's on the form (regexp . date). |
508 (if (zerop (gnus-execute field (car kill-list) | 523 (if (zerop (gnus-execute field (car kill-list) |
509 command nil (not all))) | 524 command nil (not all))) |
510 (if (> (gnus-days-between date (cdr kill-list)) | 525 (when (> (gnus-days-between date (cdr kill-list)) |
511 gnus-kill-expiry-days) | 526 gnus-kill-expiry-days) |
512 (setq regexp nil)) | 527 (setq regexp nil)) |
513 (setcdr kill-list date)) | 528 (setcdr kill-list date)) |
514 (while (setq kill (car kill-list)) | 529 (while (setq kill (car kill-list)) |
515 (if (consp kill) | 530 (if (consp kill) |
516 ;; It's a temporary kill. | 531 ;; It's a temporary kill. |
517 (progn | 532 (progn |
518 (setq kdate (cdr kill)) | 533 (setq kdate (cdr kill)) |
519 (if (zerop (gnus-execute | 534 (if (zerop (gnus-execute |
520 field (car kill) command nil (not all))) | 535 field (car kill) command nil (not all))) |
521 (if (> (gnus-days-between date kdate) | 536 (when (> (gnus-days-between date kdate) |
522 gnus-kill-expiry-days) | 537 gnus-kill-expiry-days) |
523 ;; Time limit has been exceeded, so we | 538 ;; Time limit has been exceeded, so we |
524 ;; remove the match. | 539 ;; remove the match. |
525 (if prev | 540 (if prev |
526 (setcdr prev (cdr kill-list)) | 541 (setcdr prev (cdr kill-list)) |
527 (setq regexp (cdr regexp)))) | 542 (setq regexp (cdr regexp)))) |
528 ;; Successful kill. Set the date to today. | 543 ;; Successful kill. Set the date to today. |
529 (setcdr kill date))) | 544 (setcdr kill date))) |
530 ;; It's a permanent kill. | 545 ;; It's a permanent kill. |
531 (gnus-execute field kill command nil (not all))) | 546 (gnus-execute field kill command nil (not all))) |
532 (setq prev kill-list) | 547 (setq prev kill-list) |
533 (setq kill-list (cdr kill-list)))) | 548 (setq kill-list (cdr kill-list)))) |
534 (gnus-execute field kill-list command nil (not all)))))) | 549 (gnus-execute field kill-list command nil (not all)))))) |
535 (switch-to-buffer old-buffer) | 550 (switch-to-buffer old-buffer) |
536 (if (and (eq major-mode 'gnus-kill-file-mode) regexp (not silent)) | 551 (when (and (eq major-mode 'gnus-kill-file-mode) regexp (not silent)) |
537 (gnus-pp-gnus-kill | 552 (gnus-pp-gnus-kill |
538 (nconc (list 'gnus-kill field | 553 (nconc (list 'gnus-kill field |
539 (if (consp regexp) (list 'quote regexp) regexp)) | 554 (if (consp regexp) (list 'quote regexp) regexp)) |
540 (if (or exe-command all) (list (list 'quote exe-command))) | 555 (when (or exe-command all) |
541 (if all (list t) nil)))))) | 556 (list (list 'quote exe-command))) |
557 (if all (list t) nil)))))) | |
542 | 558 |
543 (defun gnus-pp-gnus-kill (object) | 559 (defun gnus-pp-gnus-kill (object) |
544 (if (or (not (consp (nth 2 object))) | 560 (if (or (not (consp (nth 2 object))) |
545 (not (consp (cdr (nth 2 object)))) | 561 (not (consp (cdr (nth 2 object)))) |
546 (and (eq 'quote (car (nth 2 object))) | 562 (and (eq 'quote (car (nth 2 object))) |
547 (not (consp (cdadr (nth 2 object)))))) | 563 (not (consp (cdadr (nth 2 object)))))) |
548 (concat "\n" (prin1-to-string object)) | 564 (concat "\n" (gnus-prin1-to-string object)) |
549 (save-excursion | 565 (save-excursion |
550 (set-buffer (get-buffer-create "*Gnus PP*")) | 566 (set-buffer (get-buffer-create "*Gnus PP*")) |
551 (buffer-disable-undo (current-buffer)) | 567 (buffer-disable-undo (current-buffer)) |
552 (erase-buffer) | 568 (erase-buffer) |
553 (insert (format "\n(%S %S\n '(" (nth 0 object) (nth 1 object))) | 569 (insert (format "\n(%S %S\n '(" (nth 0 object) (nth 1 object))) |
554 (let ((klist (cadr (nth 2 object))) | 570 (let ((klist (cadr (nth 2 object))) |
555 (first t)) | 571 (first t)) |
556 (while klist | 572 (while klist |
557 (insert (if first (progn (setq first nil) "") "\n ") | 573 (insert (if first (progn (setq first nil) "") "\n ") |
558 (prin1-to-string (car klist))) | 574 (gnus-prin1-to-string (car klist))) |
559 (setq klist (cdr klist)))) | 575 (setq klist (cdr klist)))) |
560 (insert ")") | 576 (insert ")") |
561 (and (nth 3 object) | 577 (and (nth 3 object) |
562 (insert "\n " | 578 (insert "\n " |
563 (if (and (consp (nth 3 object)) | 579 (if (and (consp (nth 3 object)) |
564 (not (eq 'quote (car (nth 3 object))))) | 580 (not (eq 'quote (car (nth 3 object))))) |
565 "'" "") | 581 "'" "") |
566 (prin1-to-string (nth 3 object)))) | 582 (gnus-prin1-to-string (nth 3 object)))) |
567 (and (nth 4 object) | 583 (when (nth 4 object) |
568 (insert "\n t")) | 584 (insert "\n t")) |
569 (insert ")") | 585 (insert ")") |
570 (prog1 | 586 (prog1 |
571 (buffer-substring (point-min) (point-max)) | 587 (buffer-substring (point-min) (point-max)) |
572 (kill-buffer (current-buffer)))))) | 588 (kill-buffer (current-buffer)))))) |
573 | 589 |
581 (let (value) | 597 (let (value) |
582 (and header | 598 (and header |
583 (progn | 599 (progn |
584 (setq value (funcall function header)) | 600 (setq value (funcall function header)) |
585 ;; Number (Lines:) or symbol must be converted to string. | 601 ;; Number (Lines:) or symbol must be converted to string. |
586 (or (stringp value) | 602 (unless (stringp value) |
587 (setq value (prin1-to-string value))) | 603 (setq value (gnus-prin1-to-string value))) |
588 (setq did-kill (string-match regexp value))) | 604 (setq did-kill (string-match regexp value))) |
589 (cond ((stringp form) ;Keyboard macro. | 605 (cond ((stringp form) ;Keyboard macro. |
590 (execute-kbd-macro form)) | 606 (execute-kbd-macro form)) |
591 ((gnus-functionp form) | 607 ((gnus-functionp form) |
592 (funcall form)) | 608 (funcall form)) |
593 (t | 609 (t |
594 (eval form))))) | 610 (eval form))))) |
599 (gnus-mark-article-hook nil)) ;Inhibit marking as read. | 615 (gnus-mark-article-hook nil)) ;Inhibit marking as read. |
600 (gnus-message | 616 (gnus-message |
601 6 "Searching for article: %d..." (mail-header-number header)) | 617 6 "Searching for article: %d..." (mail-header-number header)) |
602 (gnus-article-setup-buffer) | 618 (gnus-article-setup-buffer) |
603 (gnus-article-prepare (mail-header-number header) t) | 619 (gnus-article-prepare (mail-header-number header) t) |
604 (if (save-excursion | 620 (when (save-excursion |
605 (set-buffer gnus-article-buffer) | 621 (set-buffer gnus-article-buffer) |
606 (goto-char (point-min)) | 622 (goto-char (point-min)) |
607 (setq did-kill (re-search-forward regexp nil t))) | 623 (setq did-kill (re-search-forward regexp nil t))) |
608 (if (stringp form) ;Keyboard macro. | 624 (cond ((stringp form) ;Keyboard macro. |
609 (execute-kbd-macro form) | 625 (execute-kbd-macro form)) |
610 (eval form)))))) | 626 ((gnus-functionp form) |
627 (funcall form)) | |
628 (t | |
629 (eval form))))))) | |
611 did-kill))) | 630 did-kill))) |
612 | 631 |
613 (defun gnus-execute (field regexp form &optional backward ignore-marked) | 632 (defun gnus-execute (field regexp form &optional backward unread) |
614 "If FIELD of article header matches REGEXP, execute lisp FORM (or a string). | 633 "If FIELD of article header matches REGEXP, execute lisp FORM (or a string). |
615 If FIELD is an empty string (or nil), entire article body is searched for. | 634 If FIELD is an empty string (or nil), entire article body is searched for. |
616 If optional 1st argument BACKWARD is non-nil, do backward instead. | 635 If optional 1st argument BACKWARD is non-nil, do backward instead. |
617 If optional 2nd argument IGNORE-MARKED is non-nil, articles which are | 636 If optional 2nd argument UNREAD is non-nil, articles which are |
618 marked as read or ticked are ignored." | 637 marked as read or ticked are ignored." |
619 (save-excursion | 638 (save-excursion |
620 (let ((killed-no 0) | 639 (let ((killed-no 0) |
621 function article header) | 640 function article header) |
622 (cond | 641 (cond |
623 ;; Search body. | 642 ;; Search body. |
624 ((or (null field) | 643 ((or (null field) |
625 (string-equal field "")) | 644 (string-equal field "")) |
626 (setq function nil)) | 645 (setq function nil)) |
627 ;; Get access function of header field. | 646 ;; Get access function of header field. |
628 ((fboundp | 647 ((fboundp |
629 (setq function | 648 (setq function |
638 ;; First article. | 657 ;; First article. |
639 (and (not article) | 658 (and (not article) |
640 (setq article (gnus-summary-article-number))) | 659 (setq article (gnus-summary-article-number))) |
641 ;; Find later articles. | 660 ;; Find later articles. |
642 (setq article | 661 (setq article |
643 (gnus-summary-search-forward | 662 (gnus-summary-search-forward unread nil backward))) |
644 (not ignore-marked) nil backward))) | |
645 (and (or (null gnus-newsgroup-kill-headers) | 663 (and (or (null gnus-newsgroup-kill-headers) |
646 (memq article gnus-newsgroup-kill-headers)) | 664 (memq article gnus-newsgroup-kill-headers)) |
647 (vectorp (setq header (gnus-summary-article-header article))) | 665 (vectorp (setq header (gnus-summary-article-header article))) |
648 (gnus-execute-1 function regexp form header) | 666 (gnus-execute-1 function regexp form header) |
649 (setq killed-no (1+ killed-no)))) | 667 (setq killed-no (1+ killed-no)))) |
650 ;; Return the number of killed articles. | 668 ;; Return the number of killed articles. |
651 killed-no))) | 669 killed-no))) |
652 | 670 |
671 ;;;###autoload | |
672 (defalias 'gnus-batch-kill 'gnus-batch-score) | |
673 ;;;###autoload | |
674 (defun gnus-batch-score () | |
675 "Run batched scoring. | |
676 Usage: emacs -batch -l gnus -f gnus-batch-score <newsgroups> ... | |
677 Newsgroups is a list of strings in Bnews format. If you want to score | |
678 the comp hierarchy, you'd say \"comp.all\". If you would not like to | |
679 score the alt hierarchy, you'd say \"!alt.all\"." | |
680 (interactive) | |
681 (let* ((gnus-newsrc-options-n | |
682 (gnus-newsrc-parse-options | |
683 (concat "options -n " | |
684 (mapconcat 'identity command-line-args-left " ")))) | |
685 (gnus-expert-user t) | |
686 (nnmail-spool-file nil) | |
687 (gnus-use-dribble-file nil) | |
688 (gnus-batch-mode t) | |
689 group newsrc entry | |
690 ;; Disable verbose message. | |
691 gnus-novice-user gnus-large-newsgroup | |
692 gnus-options-subscribe gnus-auto-subscribed-groups | |
693 gnus-options-not-subscribe) | |
694 ;; Eat all arguments. | |
695 (setq command-line-args-left nil) | |
696 (gnus-slave) | |
697 ;; Apply kills to specified newsgroups in command line arguments. | |
698 (setq newsrc (cdr gnus-newsrc-alist)) | |
699 (while (setq group (car (pop newsrc))) | |
700 (setq entry (gnus-gethash group gnus-newsrc-hashtb)) | |
701 (when (and (<= (gnus-info-level (car newsrc)) gnus-level-subscribed) | |
702 (and (car entry) | |
703 (or (eq (car entry) t) | |
704 (not (zerop (car entry))))) | |
705 ;;(eq (gnus-matches-options-n group) 'subscribe) | |
706 ) | |
707 (gnus-summary-read-group group nil t nil t) | |
708 (when (eq (current-buffer) (get-buffer gnus-summary-buffer)) | |
709 (gnus-summary-exit)))) | |
710 ;; Exit Emacs. | |
711 (switch-to-buffer gnus-group-buffer) | |
712 (gnus-group-save-newsrc))) | |
713 | |
653 (provide 'gnus-kill) | 714 (provide 'gnus-kill) |
654 | 715 |
655 ;;; gnus-kill.el ends here | 716 ;;; gnus-kill.el ends here |