Mercurial > emacs
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) |