summaryrefslogtreecommitdiff
path: root/lisp/gnus-kill.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/gnus-kill.el')
-rw-r--r--lisp/gnus-kill.el154
1 files changed, 87 insertions, 67 deletions
diff --git a/lisp/gnus-kill.el b/lisp/gnus-kill.el
index 628fff43e2e..ac76cd201d0 100644
--- a/lisp/gnus-kill.el
+++ b/lisp/gnus-kill.el
@@ -1,6 +1,5 @@
;;; gnus-kill.el --- kill commands for Gnus
-
-;; Copyright (C) 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96 Free Software Foundation, Inc.
;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
@@ -28,6 +27,7 @@
;;; Code:
(require 'gnus)
+(eval-when-compile (require 'cl))
(defvar gnus-kill-file-mode-hook nil
"*A hook for Gnus kill file mode.")
@@ -43,12 +43,12 @@
(defmacro gnus-raise (field expression level)
- (` (gnus-kill (, field) (, expression)
- (function (gnus-summary-raise-score (, level))) t)))
+ `(gnus-kill ,field ,expression
+ (function (gnus-summary-raise-score ,level)) t))
(defmacro gnus-lower (field expression level)
- (` (gnus-kill (, field) (, expression)
- (function (gnus-summary-raise-score (- (, level)))) t)))
+ `(gnus-kill ,field ,expression
+ (function (gnus-summary-raise-score (- ,level))) t))
;;;
;;; Gnus Kill File Mode
@@ -56,23 +56,16 @@
(defvar gnus-kill-file-mode-map nil)
-(if gnus-kill-file-mode-map
- nil
- (setq gnus-kill-file-mode-map (copy-keymap emacs-lisp-mode-map))
- (define-key gnus-kill-file-mode-map
- "\C-c\C-k\C-s" 'gnus-kill-file-kill-by-subject)
- (define-key gnus-kill-file-mode-map
- "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-author)
- (define-key gnus-kill-file-mode-map
- "\C-c\C-k\C-t" 'gnus-kill-file-kill-by-thread)
- (define-key gnus-kill-file-mode-map
- "\C-c\C-k\C-x" 'gnus-kill-file-kill-by-xref)
- (define-key gnus-kill-file-mode-map
- "\C-c\C-a" 'gnus-kill-file-apply-buffer)
- (define-key gnus-kill-file-mode-map
- "\C-c\C-e" 'gnus-kill-file-apply-last-sexp)
- (define-key gnus-kill-file-mode-map
- "\C-c\C-c" 'gnus-kill-file-exit))
+(unless gnus-kill-file-mode-map
+ (gnus-define-keymap
+ (setq gnus-kill-file-mode-map (copy-keymap emacs-lisp-mode-map))
+ "\C-c\C-k\C-s" gnus-kill-file-kill-by-subject
+ "\C-c\C-k\C-a" gnus-kill-file-kill-by-author
+ "\C-c\C-k\C-t" gnus-kill-file-kill-by-thread
+ "\C-c\C-k\C-x" gnus-kill-file-kill-by-xref
+ "\C-c\C-a" gnus-kill-file-apply-buffer
+ "\C-c\C-e" gnus-kill-file-apply-last-sexp
+ "\C-c\C-c" gnus-kill-file-exit))
(defun gnus-kill-file-mode ()
"Major mode for editing kill files.
@@ -181,7 +174,7 @@ If NEWSGROUP is nil, the global kill file is selected."
(gnus-kill-file-mode)
(bury-buffer buffer)))
-(defun gnus-kill-file-enter-kill (field regexp)
+(defun gnus-kill-file-enter-kill (field regexp &optional dont-move)
;; Enter kill file entry.
;; FIELD: String containing the name of the header field to kill.
;; REGEXP: The string to kill.
@@ -189,8 +182,8 @@ If NEWSGROUP is nil, the global kill file is selected."
(let (string)
(or (eq major-mode 'gnus-kill-file-mode)
(gnus-kill-set-kill-buffer))
- (current-buffer)
- (goto-char (point-max))
+ (unless dont-move
+ (goto-char (point-max)))
(insert (setq string (format "(gnus-kill %S %S)\n" field regexp)))
(gnus-kill-file-apply-string string))))
@@ -202,7 +195,7 @@ If NEWSGROUP is nil, the global kill file is selected."
(if (vectorp gnus-current-headers)
(regexp-quote
(gnus-simplify-subject (mail-header-subject gnus-current-headers)))
- "")))
+ "") t))
(defun gnus-kill-file-kill-by-author ()
"Kill by author."
@@ -211,7 +204,7 @@ If NEWSGROUP is nil, the global kill file is selected."
"From"
(if (vectorp gnus-current-headers)
(regexp-quote (mail-header-from gnus-current-headers))
- "")))
+ "") t))
(defun gnus-kill-file-kill-by-thread ()
"Kill by author."
@@ -237,8 +230,8 @@ If NEWSGROUP is nil, the global kill file is selected."
(substring xref (match-beginning 1) (match-end 1)))
gnus-newsgroup-name))
(gnus-kill-file-enter-kill
- "Xref" (concat " " (regexp-quote group) ":"))))
- (gnus-kill-file-enter-kill "Xref" ""))))
+ "Xref" (concat " " (regexp-quote group) ":") t)))
+ (gnus-kill-file-enter-kill "Xref" "" t))))
(defun gnus-kill-file-raise-followups-to-author (level)
"Raise score for all followups to the current author."
@@ -258,7 +251,8 @@ If NEWSGROUP is nil, the global kill file is selected."
"From" name level))
(insert string)
(gnus-kill-file-apply-string string))
- (message "Added temporary score file entry for followups to %s." name)))
+ (gnus-message
+ 6 "Added temporary score file entry for followups to %s." name)))
(defun gnus-kill-file-apply-buffer ()
"Apply current buffer to current newsgroup."
@@ -267,7 +261,7 @@ If NEWSGROUP is nil, the global kill file is selected."
(get-buffer gnus-summary-buffer))
;; Assume newsgroup is selected.
(gnus-kill-file-apply-string (buffer-string))
- (ding) (message "No newsgroup is selected.")))
+ (ding) (gnus-message 2 "No newsgroup is selected.")))
(defun gnus-kill-file-apply-string (string)
"Apply STRING to current newsgroup."
@@ -291,7 +285,7 @@ If NEWSGROUP is nil, the global kill file is selected."
(save-window-excursion
(pop-to-buffer gnus-summary-buffer)
(eval (car (read-from-string string))))))
- (ding) (message "No newsgroup is selected.")))
+ (ding) (gnus-message 2 "No newsgroup is selected.")))
(defun gnus-kill-file-exit ()
"Save a kill file, then return to the previous buffer."
@@ -318,24 +312,37 @@ If NEWSGROUP is nil, return the global kill file instead."
(cond ((or (null newsgroup)
(string-equal newsgroup ""))
;; The global kill file is placed at top of the directory.
- (expand-file-name gnus-kill-file-name
- (or gnus-kill-files-directory "~/News")))
+ (expand-file-name gnus-kill-file-name gnus-kill-files-directory))
(gnus-use-long-file-name
;; Append ".KILL" to capitalized newsgroup name.
(expand-file-name (concat (gnus-capitalize-newsgroup newsgroup)
"." gnus-kill-file-name)
- (or gnus-kill-files-directory "~/News")))
+ gnus-kill-files-directory))
(t
;; Place "KILL" under the hierarchical directory.
(expand-file-name (concat (gnus-newsgroup-directory-form newsgroup)
"/" gnus-kill-file-name)
- (or gnus-kill-files-directory "~/News")))))
+ gnus-kill-files-directory))))
(defun gnus-expunge (marks)
"Remove lines marked with MARKS."
(save-excursion
(set-buffer gnus-summary-buffer)
- (gnus-summary-remove-lines-marked-with marks)))
+ (gnus-summary-limit-to-marks marks 'reverse)))
+
+(defun gnus-apply-kill-file-unless-scored ()
+ "Apply .KILL file, unless a .SCORE file for the same newsgroup exists."
+ (cond ((file-exists-p (gnus-score-file-name gnus-newsgroup-name))
+ ;; Ignores global KILL.
+ (if (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name))
+ (gnus-message 3 "Note: Ignoring %s.KILL; preferring .SCORE"
+ gnus-newsgroup-name))
+ 0)
+ ((or (file-exists-p (gnus-newsgroup-kill-file nil))
+ (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name)))
+ (gnus-apply-kill-file-internal))
+ (t
+ 0)))
(defun gnus-apply-kill-file-internal ()
"Apply a kill file to the current newsgroup.
@@ -346,8 +353,6 @@ Returns the number of articles marked as read."
(gnus-summary-inhibit-highlight t)
beg)
(setq gnus-newsgroup-kill-headers nil)
- (or gnus-newsgroup-headers-hashtb-by-number
- (gnus-make-headers-hashtable-by-number))
;; If there are any previously scored articles, we remove these
;; from the `gnus-newsgroup-headers' list that the score functions
;; will see. This is probably pretty wasteful when it comes to
@@ -378,7 +383,7 @@ Returns the number of articles marked as read."
(while kill-files
(if (not (file-exists-p (car kill-files)))
()
- (message "Processing kill file %s..." (car kill-files))
+ (gnus-message 6 "Processing kill file %s..." (car kill-files))
(find-file (car kill-files))
(gnus-add-current-to-buffer-list)
(goto-char (point-min))
@@ -388,7 +393,8 @@ Returns the number of articles marked as read."
(gnus-kill-parse-gnus-kill-file)
(gnus-kill-parse-rn-kill-file))
- (message "Processing kill file %s...done" (car kill-files)))
+ (gnus-message
+ 6 "Processing kill file %s...done" (car kill-files)))
(setq kill-files (cdr kill-files)))))
(gnus-set-mode-line 'summary)
@@ -396,7 +402,7 @@ Returns the number of articles marked as read."
(if beg
(let ((nunreads (- unreads (length gnus-newsgroup-unreads))))
(or (eq nunreads 0)
- (message "Marked %d articles as read" nunreads))
+ (gnus-message 6 "Marked %d articles as read" nunreads))
nunreads)
0))))
@@ -408,7 +414,7 @@ Returns the number of articles marked as read."
(erase-buffer)
(insert string ":\n\n")
(while alist
- (insert (format " %c: %s\n" (car (car alist)) (nth idx (car alist))))
+ (insert (format " %c: %s\n" (caar alist) (nth idx (car alist))))
(setq alist (cdr alist)))))
(defun gnus-kill-parse-gnus-kill-file ()
@@ -538,14 +544,14 @@ COMMAND must be a lisp expression or a string representing a key sequence."
(if (or (not (consp (nth 2 object)))
(not (consp (cdr (nth 2 object))))
(and (eq 'quote (car (nth 2 object)))
- (not (consp (cdr (car (cdr (nth 2 object))))))))
+ (not (consp (cdadr (nth 2 object))))))
(concat "\n" (prin1-to-string object))
(save-excursion
(set-buffer (get-buffer-create "*Gnus PP*"))
(buffer-disable-undo (current-buffer))
(erase-buffer)
(insert (format "\n(%S %S\n '(" (nth 0 object) (nth 1 object)))
- (let ((klist (car (cdr (nth 2 object))))
+ (let ((klist (cadr (nth 2 object)))
(first t))
(while klist
(insert (if first (progn (setq first nil) "") "\n ")
@@ -580,15 +586,19 @@ COMMAND must be a lisp expression or a string representing a key sequence."
(or (stringp value)
(setq value (prin1-to-string value)))
(setq did-kill (string-match regexp value)))
- (if (stringp form) ;Keyboard macro.
- (execute-kbd-macro form)
- (funcall form))))
+ (cond ((stringp form) ;Keyboard macro.
+ (execute-kbd-macro form))
+ ((gnus-functionp form)
+ (funcall form))
+ (t
+ (eval form)))))
;; Search article body.
(let ((gnus-current-article nil) ;Save article pointer.
(gnus-last-article nil)
(gnus-break-pages nil) ;No need to break pages.
(gnus-mark-article-hook nil)) ;Inhibit marking as read.
- (message "Searching for article: %d..." (mail-header-number header))
+ (gnus-message
+ 6 "Searching for article: %d..." (mail-header-number header))
(gnus-article-setup-buffer)
(gnus-article-prepare (mail-header-number header) t)
(if (save-excursion
@@ -609,27 +619,37 @@ marked as read or ticked are ignored."
(save-excursion
(let ((killed-no 0)
function article header)
- (if (or (null field) (string-equal field ""))
- (setq function nil)
- ;; Get access function of header filed.
- (setq function (intern-soft (concat "gnus-header-" (downcase field))))
- (if (and function (fboundp function))
- (setq function (symbol-function function))
- (error "Unknown header field: \"%s\"" field))
- ;; Make FORM funcallable.
- (if (and (listp form) (not (eq (car form) 'lambda)))
- (setq form (list 'lambda nil form))))
+ (cond
+ ;; Search body.
+ ((or (null field)
+ (string-equal field ""))
+ (setq function nil))
+ ;; Get access function of header field.
+ ((fboundp
+ (setq function
+ (intern-soft
+ (concat "mail-header-" (downcase field)))))
+ (setq function `(lambda (h) (,function h))))
+ ;; Signal error.
+ (t
+ (error "Unknown header field: \"%s\"" field)))
;; Starting from the current article.
- (while (or (and (not article)
- (setq article (gnus-summary-article-number))
- t)
- (setq article
- (gnus-summary-search-subject
- backward (not ignore-marked))))
+ (while (or
+ ;; First article.
+ (and (not article)
+ (setq article (gnus-summary-article-number)))
+ ;; Find later articles.
+ (setq article
+ (gnus-summary-search-forward
+ (not ignore-marked) nil backward)))
(and (or (null gnus-newsgroup-kill-headers)
(memq article gnus-newsgroup-kill-headers))
- (vectorp (setq header (gnus-get-header-by-number article)))
+ (vectorp (setq header (gnus-summary-article-header article)))
(gnus-execute-1 function regexp form header)
(setq killed-no (1+ killed-no))))
+ ;; Return the number of killed articles.
killed-no)))
+(provide 'gnus-kill)
+
+;;; gnus-kill.el ends here