comparison lisp/gnus/gnus-topic.el @ 85712:a3c27999decb

Update Gnus to No Gnus 0.7 from the Gnus CVS trunk Revision: emacs@sv.gnu.org/emacs--devo--0--patch-911
author Miles Bader <miles@gnu.org>
date Sun, 28 Oct 2007 09:18:39 +0000
parents 24202b793a08
children 107ccd98fa12 880960b70474
comparison
equal deleted inserted replaced
85711:b6f5dc84b2e1 85712:a3c27999decb
103 103
104 ;;; Utility functions 104 ;;; Utility functions
105 105
106 (defun gnus-group-topic-name () 106 (defun gnus-group-topic-name ()
107 "The name of the topic on the current line." 107 "The name of the topic on the current line."
108 (let ((topic (get-text-property (gnus-point-at-bol) 'gnus-topic))) 108 (let ((topic (get-text-property (point-at-bol) 'gnus-topic)))
109 (and topic (symbol-name topic)))) 109 (and topic (symbol-name topic))))
110 110
111 (defun gnus-group-topic-level () 111 (defun gnus-group-topic-level ()
112 "The level of the topic on the current line." 112 "The level of the topic on the current line."
113 (get-text-property (gnus-point-at-bol) 'gnus-topic-level)) 113 (get-text-property (point-at-bol) 'gnus-topic-level))
114 114
115 (defun gnus-group-topic-unread () 115 (defun gnus-group-topic-unread ()
116 "The number of unread articles in topic on the current line." 116 "The number of unread articles in topic on the current line."
117 (get-text-property (gnus-point-at-bol) 'gnus-topic-unread)) 117 (get-text-property (point-at-bol) 'gnus-topic-unread))
118 118
119 (defun gnus-topic-unread (topic) 119 (defun gnus-topic-unread (topic)
120 "Return the number of unread articles in TOPIC." 120 "Return the number of unread articles in TOPIC."
121 (or (cdr (assoc topic gnus-topic-unreads)) 121 (or (cdr (assoc topic gnus-topic-unreads))
122 0)) 122 0))
125 "Return non-nil if the current line is a topic." 125 "Return non-nil if the current line is a topic."
126 (gnus-group-topic-name)) 126 (gnus-group-topic-name))
127 127
128 (defun gnus-topic-visible-p () 128 (defun gnus-topic-visible-p ()
129 "Return non-nil if the current topic is visible." 129 "Return non-nil if the current topic is visible."
130 (get-text-property (gnus-point-at-bol) 'gnus-topic-visible)) 130 (get-text-property (point-at-bol) 'gnus-topic-visible))
131 131
132 (defun gnus-topic-articles-in-topic (entries) 132 (defun gnus-topic-articles-in-topic (entries)
133 (let ((total 0) 133 (let ((total 0)
134 number) 134 number)
135 (while entries 135 (while entries
165 "Go to TOPIC." 165 "Go to TOPIC."
166 (interactive 166 (interactive
167 (list (completing-read "Go to topic: " 167 (list (completing-read "Go to topic: "
168 (mapcar 'list (gnus-topic-list)) 168 (mapcar 'list (gnus-topic-list))
169 nil t))) 169 nil t)))
170 (dolist (topic (gnus-current-topics topic)) 170 (let ((buffer-read-only nil))
171 (gnus-topic-goto-topic topic) 171 (dolist (topic (gnus-current-topics topic))
172 (gnus-topic-fold t)) 172 (unless (gnus-topic-goto-topic topic)
173 (gnus-topic-goto-missing-topic topic)
174 (gnus-topic-display-missing-topic topic))))
173 (gnus-topic-goto-topic topic)) 175 (gnus-topic-goto-topic topic))
174 176
175 (defun gnus-current-topic () 177 (defun gnus-current-topic ()
176 "Return the name of the current topic." 178 "Return the name of the current topic."
177 (let ((result 179 (let ((result
194 (setq topic (gnus-topic-parent-topic topic))) 196 (setq topic (gnus-topic-parent-topic topic)))
195 (nreverse topics))) 197 (nreverse topics)))
196 198
197 (defun gnus-group-active-topic-p () 199 (defun gnus-group-active-topic-p ()
198 "Say whether the current topic comes from the active topics." 200 "Say whether the current topic comes from the active topics."
199 (save-excursion 201 (get-text-property (point-at-bol) 'gnus-active))
200 (beginning-of-line)
201 (get-text-property (point) 'gnus-active)))
202 202
203 (defun gnus-topic-find-groups (topic &optional level all lowest recursive) 203 (defun gnus-topic-find-groups (topic &optional level all lowest recursive)
204 "Return entries for all visible groups in TOPIC. 204 "Return entries for all visible groups in TOPIC.
205 If RECURSIVE is t, return groups in its subtopics too." 205 If RECURSIVE is t, return groups in its subtopics too."
206 (let ((groups (cdr (assoc topic gnus-topic-alist))) 206 (let ((groups (cdr (assoc topic gnus-topic-alist)))
208 (setq lowest (or lowest 1)) 208 (setq lowest (or lowest 1))
209 (setq level (or level gnus-level-unsubscribed)) 209 (setq level (or level gnus-level-unsubscribed))
210 ;; We go through the newsrc to look for matches. 210 ;; We go through the newsrc to look for matches.
211 (while groups 211 (while groups
212 (when (setq group (pop groups)) 212 (when (setq group (pop groups))
213 (setq entry (gnus-gethash group gnus-newsrc-hashtb) 213 (setq entry (gnus-group-entry group)
214 info (nth 2 entry) 214 info (nth 2 entry)
215 params (gnus-info-params info) 215 params (gnus-info-params info)
216 active (gnus-active group) 216 active (gnus-active group)
217 unread (or (car entry) 217 unread (or (car entry)
218 (and (not (equal group "dummy.group")) 218 (and (not (equal group "dummy.group"))
242 (push (or entry group) visible-groups))) 242 (push (or entry group) visible-groups)))
243 (setq visible-groups (nreverse visible-groups)) 243 (setq visible-groups (nreverse visible-groups))
244 (when recursive 244 (when recursive
245 (if (eq recursive t) 245 (if (eq recursive t)
246 (setq recursive (cdr (gnus-topic-find-topology topic)))) 246 (setq recursive (cdr (gnus-topic-find-topology topic))))
247 (mapcar (lambda (topic-topology) 247 (dolist (topic-topology (cdr recursive))
248 (setq visible-groups 248 (setq visible-groups
249 (nconc visible-groups 249 (nconc visible-groups
250 (gnus-topic-find-groups 250 (gnus-topic-find-groups
251 (caar topic-topology) 251 (caar topic-topology)
252 level all lowest topic-topology)))) 252 level all lowest topic-topology)))))
253 (cdr recursive)))
254 visible-groups)) 253 visible-groups))
255 254
256 (defun gnus-topic-goto-previous-topic (n) 255 (defun gnus-topic-goto-previous-topic (n)
257 "Go to the N'th previous topic." 256 "Go to the N'th previous topic."
258 (interactive "p") 257 (interactive "p")
349 "Return a list of all topics in the topology." 348 "Return a list of all topics in the topology."
350 (unless topology 349 (unless topology
351 (setq topology gnus-topic-topology 350 (setq topology gnus-topic-topology
352 gnus-tmp-topics nil)) 351 gnus-tmp-topics nil))
353 (push (caar topology) gnus-tmp-topics) 352 (push (caar topology) gnus-tmp-topics)
354 (mapcar 'gnus-topic-list (cdr topology)) 353 (mapc 'gnus-topic-list (cdr topology))
355 gnus-tmp-topics) 354 gnus-tmp-topics)
356 355
357 ;;; Topic parameter jazz 356 ;;; Topic parameter jazz
358 357
359 (defun gnus-topic-parameters (topic) 358 (defun gnus-topic-parameters (topic)
376 (setcar (nthcdr 3 (cadr top)) parameters) 375 (setcar (nthcdr 3 (cadr top)) parameters)
377 (gnus-dribble-enter 376 (gnus-dribble-enter
378 (format "(gnus-topic-set-parameters %S '%S)" topic parameters)))) 377 (format "(gnus-topic-set-parameters %S '%S)" topic parameters))))
379 378
380 (defun gnus-group-topic-parameters (group) 379 (defun gnus-group-topic-parameters (group)
381 "Compute the group parameters for GROUP taking into account inheritance from topics." 380 "Compute the group parameters for GROUP in topic mode.
381 Possibly inherit parameters from topics above GROUP."
382 (let ((params-list (copy-sequence (gnus-group-get-parameter group)))) 382 (let ((params-list (copy-sequence (gnus-group-get-parameter group))))
383 (save-excursion 383 (save-excursion
384 (nconc params-list 384 (gnus-topic-hierarchical-parameters
385 (gnus-topic-hierarchical-parameters 385 ;; First we try to go to the group within the group buffer and find the
386 ;; First we try to go to the group within the group 386 ;; topic for the group that way. This hopefully copes well with groups
387 ;; buffer and find the topic for the group that way. 387 ;; that are in more than one topic. Failing that (i.e. when the group
388 ;; This hopefully copes well with groups that are in 388 ;; isn't visible in the group buffer) we find a topic for the group via
389 ;; more than one topic. Failing that (i.e. when the 389 ;; gnus-group-topic.
390 ;; group isn't visible in the group buffer) we find a 390 (or (and (gnus-group-goto-group group)
391 ;; topic for the group via gnus-group-topic. 391 (gnus-current-topic))
392 (or (and (gnus-group-goto-group group) 392 (gnus-group-topic group))
393 (gnus-current-topic)) 393 params-list))))
394 (gnus-group-topic group))))))) 394
395 395 (defun gnus-topic-hierarchical-parameters (topic &optional group-params-list)
396 (defun gnus-topic-hierarchical-parameters (topic) 396 "Compute the topic parameters for TOPIC.
397 "Return a topic list computed for TOPIC." 397 Possibly inherit parameters from topics above TOPIC.
398 (let ((topics (gnus-current-topics topic)) 398 If optional argument GROUP-PARAMS-LIST is non-nil, use it as the basis for
399 params-list param out params) 399 inheritance."
400 (while topics 400 (let ((params-list
401 (push (gnus-topic-parameters (pop topics)) params-list)) 401 ;; We probably have lots of nil elements here, so we remove them.
402 ;; We probably have lots of nil elements here, so 402 ;; Probably faster than doing this "properly".
403 ;; we remove them. Probably faster than doing this "properly". 403 (delq nil (cons group-params-list
404 (setq params-list (delq nil params-list)) 404 (mapcar 'gnus-topic-parameters
405 (gnus-current-topics topic)))))
406 param out params)
405 ;; Now we have all the parameters, so we go through them 407 ;; Now we have all the parameters, so we go through them
406 ;; and do inheritance in the obvious way. 408 ;; and do inheritance in the obvious way.
407 (while (setq params (pop params-list)) 409 (let (posting-style)
408 (while (setq param (pop params)) 410 (while (setq params (pop params-list))
409 (when (atom param) 411 (while (setq param (pop params))
410 (setq param (cons param t))) 412 (when (atom param)
411 ;; Override any old versions of this param. 413 (setq param (cons param t)))
412 (gnus-pull (car param) out) 414 (cond ((eq (car param) 'posting-style)
413 (push param out))) 415 (let ((param (cdr param))
416 elt)
417 (while (setq elt (pop param))
418 (unless (assoc (car elt) posting-style)
419 (push elt posting-style)))))
420 (t
421 (unless (assq (car param) out)
422 (push param out))))))
423 (and posting-style (push (cons 'posting-style posting-style) out)))
414 ;; Return the resulting parameter list. 424 ;; Return the resulting parameter list.
415 out)) 425 out))
416 426
417 ;;; General utility functions 427 ;;; General utility functions
418 428
463 (when not-in-list 473 (when not-in-list
464 (unless gnus-killed-hashtb 474 (unless gnus-killed-hashtb
465 (gnus-make-hashtable-from-killed)) 475 (gnus-make-hashtable-from-killed))
466 (gnus-group-prepare-flat-list-dead 476 (gnus-group-prepare-flat-list-dead
467 (gnus-remove-if (lambda (group) 477 (gnus-remove-if (lambda (group)
468 (or (gnus-gethash group gnus-newsrc-hashtb) 478 (or (gnus-group-entry group)
469 (gnus-gethash group gnus-killed-hashtb))) 479 (gnus-gethash group gnus-killed-hashtb)))
470 not-in-list) 480 not-in-list)
471 gnus-level-killed ?K regexp))) 481 gnus-level-killed ?K regexp)))
472 482
473 ;; Use topics. 483 ;; Use topics.
725 (gnus-topic-parent-topic topic)))) 735 (gnus-topic-parent-topic topic))))
726 (when (and parent 736 (when (and parent
727 (not (gnus-topic-goto-missing-topic (caadr parent)))) 737 (not (gnus-topic-goto-missing-topic (caadr parent))))
728 (gnus-topic-display-missing-topic (caadr parent)))) 738 (gnus-topic-display-missing-topic (caadr parent))))
729 (gnus-topic-goto-missing-topic topic) 739 (gnus-topic-goto-missing-topic topic)
740 ;; Skip past all groups in the topic we're in.
741 (while (gnus-group-group-name)
742 (forward-line 1))
730 (let* ((top (gnus-topic-find-topology topic)) 743 (let* ((top (gnus-topic-find-topology topic))
731 (children (cddr top)) 744 (children (cddr top))
732 (type (cadr top)) 745 (type (cadr top))
733 (unread 0) 746 (unread 0)
734 (entries (gnus-topic-find-groups 747 (entries (gnus-topic-find-groups
846 (unless (assoc (car topics) gnus-topic-alist) 859 (unless (assoc (car topics) gnus-topic-alist)
847 (push (list (car topics)) gnus-topic-alist)) 860 (push (list (car topics)) gnus-topic-alist))
848 (pop topics))) 861 (pop topics)))
849 ;; Go through all living groups and make sure that 862 ;; Go through all living groups and make sure that
850 ;; they belong to some topic. 863 ;; they belong to some topic.
851 (let* ((tgroups (apply 'append (mapcar (lambda (entry) (cdr entry)) 864 (let* ((tgroups (apply 'append (mapcar 'cdr gnus-topic-alist)))
852 gnus-topic-alist)))
853 (entry (last (assoc (caar gnus-topic-topology) gnus-topic-alist))) 865 (entry (last (assoc (caar gnus-topic-topology) gnus-topic-alist)))
854 (newsrc (cdr gnus-newsrc-alist)) 866 (newsrc (cdr gnus-newsrc-alist))
855 group) 867 group)
856 (while newsrc 868 (while newsrc
857 (unless (member (setq group (gnus-info-group (pop newsrc))) tgroups) 869 (unless (member (setq group (gnus-info-group (pop newsrc))) tgroups)
861 (let ((alist gnus-topic-alist) 873 (let ((alist gnus-topic-alist)
862 topic) 874 topic)
863 (while (setq topic (pop alist)) 875 (while (setq topic (pop alist))
864 (while (cdr topic) 876 (while (cdr topic)
865 (if (and (cadr topic) 877 (if (and (cadr topic)
866 (gnus-gethash (cadr topic) gnus-newsrc-hashtb)) 878 (gnus-group-entry (cadr topic)))
867 (setq topic (cdr topic)) 879 (setq topic (cdr topic))
868 (setcdr topic (cddr topic))))))) 880 (setcdr topic (cddr topic)))))))
869 881
870 (defun gnus-topic-init-alist () 882 (defun gnus-topic-init-alist ()
871 "Initialize the topic structures." 883 "Initialize the topic structures."
891 (gnus-make-hashtable-from-killed)) 903 (gnus-make-hashtable-from-killed))
892 (while (setq topic (pop topic-alist)) 904 (while (setq topic (pop topic-alist))
893 (let ((topic-name (pop topic)) 905 (let ((topic-name (pop topic))
894 group filtered-topic) 906 group filtered-topic)
895 (while (setq group (pop topic)) 907 (while (setq group (pop topic))
896 (when (and (or (gnus-gethash group gnus-active-hashtb) 908 (when (and (or (gnus-active group)
897 (gnus-info-method (gnus-get-info group))) 909 (gnus-info-method (gnus-get-info group)))
898 (not (gnus-gethash group gnus-killed-hashtb))) 910 (not (gnus-gethash group gnus-killed-hashtb)))
899 (push group filtered-topic))) 911 (push group filtered-topic)))
900 (push (cons topic-name (nreverse filtered-topic)) result))) 912 (push (cons topic-name (nreverse filtered-topic)) result)))
901 (setq gnus-topic-alist (nreverse result)))) 913 (setq gnus-topic-alist (nreverse result))))
1140 (if (not gnus-topic-mode) 1152 (if (not gnus-topic-mode)
1141 (setq gnus-goto-missing-group-function nil) 1153 (setq gnus-goto-missing-group-function nil)
1142 (when (gnus-visual-p 'topic-menu 'menu) 1154 (when (gnus-visual-p 'topic-menu 'menu)
1143 (gnus-topic-make-menu-bar)) 1155 (gnus-topic-make-menu-bar))
1144 (gnus-set-format 'topic t) 1156 (gnus-set-format 'topic t)
1145 (gnus-add-minor-mode 'gnus-topic-mode " Topic" gnus-topic-mode-map) 1157 (add-minor-mode 'gnus-topic-mode " Topic" gnus-topic-mode-map)
1146 (add-hook 'gnus-group-catchup-group-hook 'gnus-topic-update-topic) 1158 (add-hook 'gnus-group-catchup-group-hook 'gnus-topic-update-topic)
1147 (set (make-local-variable 'gnus-group-prepare-function) 1159 (set (make-local-variable 'gnus-group-prepare-function)
1148 'gnus-group-prepare-topics) 1160 'gnus-group-prepare-topics)
1149 (set (make-local-variable 'gnus-group-get-parameter-function) 1161 (set (make-local-variable 'gnus-group-get-parameter-function)
1150 'gnus-group-topic-parameters) 1162 'gnus-group-topic-parameters)
1295 (start-topic (gnus-group-topic-name)) 1307 (start-topic (gnus-group-topic-name))
1296 (start-group (progn (forward-line 1) (gnus-group-group-name))) 1308 (start-group (progn (forward-line 1) (gnus-group-group-name)))
1297 entry) 1309 entry)
1298 (if (and (not groups) (not copyp) start-topic) 1310 (if (and (not groups) (not copyp) start-topic)
1299 (gnus-topic-move start-topic topic) 1311 (gnus-topic-move start-topic topic)
1300 (mapcar 1312 (dolist (g groups)
1301 (lambda (g) 1313 (gnus-group-remove-mark g use-marked)
1302 (gnus-group-remove-mark g use-marked) 1314 (when (and
1303 (when (and 1315 (setq entry (assoc (gnus-current-topic) gnus-topic-alist))
1304 (setq entry (assoc (gnus-current-topic) gnus-topic-alist)) 1316 (not copyp))
1305 (not copyp)) 1317 (setcdr entry (gnus-delete-first g (cdr entry))))
1306 (setcdr entry (gnus-delete-first g (cdr entry)))) 1318 (nconc topicl (list g)))
1307 (nconc topicl (list g)))
1308 groups)
1309 (gnus-topic-enter-dribble) 1319 (gnus-topic-enter-dribble)
1310 (if start-group 1320 (if start-group
1311 (gnus-group-goto-group start-group) 1321 (gnus-group-goto-group start-group)
1312 (gnus-topic-goto-topic start-topic)) 1322 (gnus-topic-goto-topic start-topic))
1313 (gnus-group-list-groups)))) 1323 (gnus-group-list-groups))))
1316 "Remove the current group from the topic." 1326 "Remove the current group from the topic."
1317 (interactive "P") 1327 (interactive "P")
1318 (let ((use-marked (and (not n) (not (gnus-region-active-p)) 1328 (let ((use-marked (and (not n) (not (gnus-region-active-p))
1319 gnus-group-marked t)) 1329 gnus-group-marked t))
1320 (groups (gnus-group-process-prefix n))) 1330 (groups (gnus-group-process-prefix n)))
1321 (mapcar 1331 (mapc
1322 (lambda (group) 1332 (lambda (group)
1323 (gnus-group-remove-mark group use-marked) 1333 (gnus-group-remove-mark group use-marked)
1324 (let ((topicl (assoc (gnus-current-topic) gnus-topic-alist)) 1334 (let ((topicl (assoc (gnus-current-topic) gnus-topic-alist))
1325 (buffer-read-only nil)) 1335 (buffer-read-only nil))
1326 (when (and topicl group) 1336 (when (and topicl group)
1733 (unless to-top 1743 (unless to-top
1734 (error "Can't find topic `%s'" to)) 1744 (error "Can't find topic `%s'" to))
1735 (if (gnus-topic-find-topology to current-top 0);; Don't care the level 1745 (if (gnus-topic-find-topology to current-top 0);; Don't care the level
1736 (error "Can't move `%s' to its sub-level" current)) 1746 (error "Can't move `%s' to its sub-level" current))
1737 (gnus-topic-find-topology current nil nil 'delete) 1747 (gnus-topic-find-topology current nil nil 'delete)
1738 (while (cdr to-top) 1748 (setcdr (last to-top) (list current-top))
1739 (setq to-top (cdr to-top)))
1740 (setcdr to-top (list current-top))
1741 (gnus-topic-enter-dribble) 1749 (gnus-topic-enter-dribble)
1742 (gnus-group-list-groups) 1750 (gnus-group-list-groups)
1743 (gnus-topic-goto-topic current))) 1751 (gnus-topic-goto-topic current)))
1744 1752
1745 (defun gnus-subscribe-topics (newsgroup) 1753 (defun gnus-subscribe-topics (newsgroup)