;;; gnus-registry.el --- article registry for Gnus
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;; 2005 Free Software Foundation, Inc.
+;; 2005, 2006, 2007 Free Software Foundation, Inc.
;; Author: Ted Zlatanov <tzz@lifelogs.com>
;; Keywords: news
(require 'gnus)
(require 'gnus-int)
(require 'gnus-sum)
+(require 'gnus-util)
(require 'nnmail)
(defvar gnus-registry-dirty t
"*The article registry by Message ID.")
(defcustom gnus-registry-unfollowed-groups '("delayed" "drafts" "queue")
- "List of groups that gnus-registry-split-fancy-with-parent won't follow.
-The group names are matched, they don't have to be fully qualified."
+ "List of groups that gnus-registry-split-fancy-with-parent won't return.
+The group names are matched, they don't have to be fully
+qualified. This parameter tells the Registry 'never split a
+message into a group that matches one of these, regardless of
+references.'"
:group 'gnus-registry
:type '(repeat string))
;; remove empty entries
(when gnus-registry-clean-empty
(gnus-registry-clean-empty-function))
- ;; now trim the registry appropriately
- (setq gnus-registry-alist (gnus-registry-trim
- (hashtable-to-alist gnus-registry-hashtb)))
+ ;; now trim and clean text properties from the registry appropriately
+ (setq gnus-registry-alist
+ (gnus-registry-remove-alist-text-properties
+ (gnus-registry-trim
+ (gnus-hashtable-to-alist
+ gnus-registry-hashtb))))
;; really save
(gnus-registry-cache-save)
(setq gnus-registry-entry-caching caching)
(when (stringp key)
(dolist (group (gnus-registry-fetch-groups key))
(when (gnus-parameter-registry-ignore group)
- (gnus-message
+ (gnus-message
10
"gnus-registry: deleted ignored group %s from key %s"
group key)
(gnus-registry-fetch-group key)
;; TODO: look for specific extra data here!
;; in this example, we look for 'label
- (gnus-registry-fetch-extra key 'label)
- (stringp key))
+ (gnus-registry-fetch-extra key 'label))
(incf count)
(gnus-registry-delete-id key))
(defun gnus-registry-read ()
(gnus-registry-cache-read)
- (setq gnus-registry-hashtb (alist-to-hashtable gnus-registry-alist))
+ (setq gnus-registry-hashtb (gnus-alist-to-hashtable gnus-registry-alist))
(setq gnus-registry-dirty nil))
+(defun gnus-registry-remove-alist-text-properties (v)
+ "Remove text properties from all strings in alist."
+ (if (stringp v)
+ (gnus-string-remove-all-properties v)
+ (if (and (listp v) (listp (cdr v)))
+ (mapcar 'gnus-registry-remove-alist-text-properties v)
+ (if (and (listp v) (stringp (cdr v)))
+ (cons (gnus-registry-remove-alist-text-properties (car v))
+ (gnus-registry-remove-alist-text-properties (cdr v)))
+ v))))
+
(defun gnus-registry-trim (alist)
"Trim alist to size, using gnus-registry-max-entries.
Also, drop all gnus-registry-ignored-groups matches."
(setq alist
(nthcdr
trim-length
- (sort alist
+ (sort alist
(lambda (a b)
(time-less-p
(or (cdr (gethash (car a) timehash)) '(0 0 0))
(or (cdr (gethash (car b) timehash)) '(0 0 0))))))))))
-(defun alist-to-hashtable (alist)
- "Build a hashtable from the values in ALIST."
- (let ((ht (make-hash-table
- :size 4096
- :test 'equal)))
- (mapc
- (lambda (kv-pair)
- (puthash (car kv-pair) (cdr kv-pair) ht))
- alist)
- ht))
-
-(defun hashtable-to-alist (hash)
- "Build an alist from the values in HASH."
- (let ((list nil))
- (maphash
- (lambda (key value)
- (setq list (cons (cons key value) list)))
- hash)
- list))
-
(defun gnus-registry-action (action data-header from &optional to method)
(let* ((id (mail-header-id data-header))
- (subject (gnus-registry-simplify-subject
- (mail-header-subject data-header)))
- (sender (mail-header-from data-header))
+ (subject (gnus-string-remove-all-properties
+ (gnus-registry-simplify-subject
+ (mail-header-subject data-header))))
+ (sender (gnus-string-remove-all-properties (mail-header-from data-header)))
(from (gnus-group-guess-full-name-from-command-method from))
(to (if to (gnus-group-guess-full-name-from-command-method to) nil))
(to-name (if to to "the Bit Bucket"))
messages.
For a message to be split, it looks for the parent message in the
-References or In-Reply-To header and then looks in the registry to
-see which group that message was put in. This group is returned.
+References or In-Reply-To header and then looks in the registry
+to see which group that message was put in. This group is
+returned, unless it matches one of the entries in
+gnus-registry-unfollowed-groups or
+nnmail-split-fancy-with-parent-ignore-groups.
See the Info node `(gnus)Fancy Mail Splitting' for more details."
(let* ((refstr (or (message-fetch-field "references") "")) ; guarantee string
references))
;; else: there were no references, now try the extra tracking
- (let ((sender (message-fetch-field "from"))
- (subject (gnus-registry-simplify-subject
- (message-fetch-field "subject")))
+ (let ((sender (gnus-string-remove-all-properties(message-fetch-field "from")))
+ (subject (gnus-string-remove-all-properties
+ (gnus-registry-simplify-subject
+ (message-fetch-field "subject"))))
(single-match t))
(when (and single-match
(gnus-registry-track-sender-p)
(setq res nil))))
res))
+(defun gnus-registry-wash-for-keywords (&optional force)
+ (interactive)
+ (let ((id (gnus-registry-fetch-message-id-fast gnus-current-article))
+ word words)
+ (if (or (not (gnus-registry-fetch-extra id 'keywords))
+ force)
+ (save-excursion
+ (set-buffer gnus-article-buffer)
+ (article-goto-body)
+ (save-window-excursion
+ (save-restriction
+ (narrow-to-region (point) (point-max))
+ (with-syntax-table gnus-adaptive-word-syntax-table
+ (while (re-search-forward "\\b\\w+\\b" nil t)
+ (setq word (gnus-registry-remove-alist-text-properties
+ (downcase (buffer-substring
+ (match-beginning 0) (match-end 0)))))
+ (if (> (length word) 3)
+ (push word words))))))
+ (gnus-registry-store-extra-entry id 'keywords words)))))
+
+(defun gnus-registry-find-keywords (keyword)
+ (interactive "skeyword: ")
+ (let (articles)
+ (maphash
+ (lambda (key value)
+ (when (gnus-registry-grep-in-list
+ keyword
+ (cdr (gnus-registry-fetch-extra key 'keywords)))
+ (push key articles)))
+ gnus-registry-hashtb)
+ articles))
+
(defun gnus-registry-register-message-ids ()
"Register the Message-ID of every article in the group"
(unless (gnus-parameter-registry-ignore gnus-newsgroup-name)
"Fetch the Subject quickly, using the internal gnus-data-list function"
(if (and (numberp article)
(assoc article (gnus-data-list nil)))
- (gnus-registry-simplify-subject
- (mail-header-subject (gnus-data-header
- (assoc article (gnus-data-list nil)))))
+ (gnus-string-remove-all-properties
+ (gnus-registry-simplify-subject
+ (mail-header-subject (gnus-data-header
+ (assoc article (gnus-data-list nil))))))
nil))
(defun gnus-registry-fetch-sender-fast (article)
"Fetch the Sender quickly, using the internal gnus-data-list function"
(if (and (numberp article)
(assoc article (gnus-data-list nil)))
- (mail-header-from (gnus-data-header
- (assoc article (gnus-data-list nil))))
+ (gnus-string-remove-all-properties
+ (mail-header-from (gnus-data-header
+ (assoc article (gnus-data-list nil)))))
nil))
(defun gnus-registry-grep-in-list (word list)
(defun gnus-registry-store-extra-entry (id key value)
"Put a specific entry in the extras field of the registry entry for id."
(let* ((extra (gnus-registry-fetch-extra id))
- (alist (cons (cons key value)
- (gnus-assq-delete-all key (gnus-registry-fetch-extra id)))))
+ (alist (gnus-registry-remove-alist-text-properties
+ (cons (cons key value)
+ (gnus-assq-delete-all key (gnus-registry-fetch-extra id))))))
(gnus-registry-store-extra id alist)))
(defun gnus-registry-fetch-group (id)
"Clear the Gnus registry."
(interactive)
(setq gnus-registry-alist nil)
- (setq gnus-registry-hashtb (alist-to-hashtable gnus-registry-alist))
+ (setq gnus-registry-hashtb (gnus-alist-to-hashtable gnus-registry-alist))
(setq gnus-registry-dirty t))
;;;###autoload