Mercurial > emacs
comparison lisp/gnus/gnus-topic.el @ 31716:9968f55ad26e
Update to emacs-21-branch of the Gnus CVS repository.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Tue, 19 Sep 2000 13:37:09 +0000 |
parents | 15fc6acbae7a |
children | 51cea22fd2aa |
comparison
equal
deleted
inserted
replaced
31715:7c896543d225 | 31716:9968f55ad26e |
---|---|
1 ;;; gnus-topic.el --- a folding minor mode for Gnus group buffers | 1 ;;; gnus-topic.el --- a folding minor mode for Gnus group buffers |
2 ;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 |
3 ;; Free Software Foundation, Inc. | |
3 | 4 |
4 ;; Author: Ilja Weis <kult@uni-paderborn.de> | 5 ;; Author: Ilja Weis <kult@uni-paderborn.de> |
5 ;; Lars Magne Ingebrigtsen <larsi@gnus.org> | 6 ;; Lars Magne Ingebrigtsen <larsi@gnus.org> |
6 ;; Keywords: news | 7 ;; Keywords: news |
7 | 8 |
23 ;; Boston, MA 02111-1307, USA. | 24 ;; Boston, MA 02111-1307, USA. |
24 | 25 |
25 ;;; Commentary: | 26 ;;; Commentary: |
26 | 27 |
27 ;;; Code: | 28 ;;; Code: |
28 | |
29 (eval-when-compile (require 'cl)) | |
30 | 29 |
31 (eval-when-compile (require 'cl)) | 30 (eval-when-compile (require 'cl)) |
32 | 31 |
33 (require 'gnus) | 32 (require 'gnus) |
34 (require 'gnus-group) | 33 (require 'gnus-group) |
149 (if (gnus-group-goto-group group) | 148 (if (gnus-group-goto-group group) |
150 (gnus-current-topic) | 149 (gnus-current-topic) |
151 (gnus-group-topic group)))) | 150 (gnus-group-topic group)))) |
152 | 151 |
153 (defun gnus-topic-goto-topic (topic) | 152 (defun gnus-topic-goto-topic (topic) |
154 "Go to TOPIC." | |
155 (when topic | 153 (when topic |
156 (gnus-goto-char (text-property-any (point-min) (point-max) | 154 (gnus-goto-char (text-property-any (point-min) (point-max) |
157 'gnus-topic (intern topic))))) | 155 'gnus-topic (intern topic))))) |
158 | 156 |
157 (defun gnus-topic-jump-to-topic (topic) | |
158 "Go to TOPIC." | |
159 (interactive | |
160 (list (completing-read "Go to topic: " | |
161 (mapcar 'list (gnus-topic-list)) | |
162 nil t))) | |
163 (dolist (topic (gnus-current-topics topic)) | |
164 (gnus-topic-fold t)) | |
165 (gnus-topic-goto-topic topic)) | |
166 | |
159 (defun gnus-current-topic () | 167 (defun gnus-current-topic () |
160 "Return the name of the current topic." | 168 "Return the name of the current topic." |
161 (let ((result | 169 (let ((result |
162 (or (get-text-property (point) 'gnus-topic) | 170 (or (get-text-property (point) 'gnus-topic) |
163 (save-excursion | 171 (save-excursion |
203 (- (1+ (cdr active)) (car active)))) | 211 (- (1+ (cdr active)) (car active)))) |
204 clevel (or (gnus-info-level info) | 212 clevel (or (gnus-info-level info) |
205 (if (member group gnus-zombie-list) | 213 (if (member group gnus-zombie-list) |
206 gnus-level-zombie gnus-level-killed)))) | 214 gnus-level-zombie gnus-level-killed)))) |
207 (and | 215 (and |
208 unread ; nil means that the group is dead. | 216 info ; nil means that the group is dead. |
209 (<= clevel level) | 217 (<= clevel level) |
210 (>= clevel lowest) ; Is inside the level we want. | 218 (>= clevel lowest) ; Is inside the level we want. |
211 (or all | 219 (or all |
212 (if (eq unread t) | 220 (if (or (eq unread t) |
221 (eq unread nil)) | |
213 gnus-group-list-inactive-groups | 222 gnus-group-list-inactive-groups |
214 (> unread 0)) | 223 (> unread 0)) |
215 (and gnus-list-groups-with-ticked-articles | 224 (and gnus-list-groups-with-ticked-articles |
216 (cdr (assq 'tick (gnus-info-marks info)))) | 225 (cdr (assq 'tick (gnus-info-marks info)))) |
217 ; Has right readedness. | 226 ;; Has right readedness. |
218 ;; Check for permanent visibility. | 227 ;; Check for permanent visibility. |
219 (and gnus-permanently-visible-groups | 228 (and gnus-permanently-visible-groups |
220 (string-match gnus-permanently-visible-groups group)) | 229 (string-match gnus-permanently-visible-groups group)) |
221 (memq 'visible params) | 230 (memq 'visible params) |
222 (cdr (assq 'visible params))) | 231 (cdr (assq 'visible params))) |
361 (gnus-dribble-enter | 370 (gnus-dribble-enter |
362 (format "(setq gnus-topic-topology '%S)" gnus-topic-topology))) | 371 (format "(setq gnus-topic-topology '%S)" gnus-topic-topology))) |
363 | 372 |
364 ;;; Generating group buffers | 373 ;;; Generating group buffers |
365 | 374 |
366 (defun gnus-group-prepare-topics (level &optional all lowest regexp list-topic topic-level) | 375 (defun gnus-group-prepare-topics (level &optional all lowest |
376 regexp list-topic topic-level) | |
367 "List all newsgroups with unread articles of level LEVEL or lower. | 377 "List all newsgroups with unread articles of level LEVEL or lower. |
368 Use the `gnus-group-topics' to sort the groups. | 378 Use the `gnus-group-topics' to sort the groups. |
369 If ALL is non-nil, list groups that have no unread articles. | 379 If ALL is non-nil, list groups that have no unread articles. |
370 If LOWEST is non-nil, list all newsgroups of level LOWEST or higher." | 380 If LOWEST is non-nil, list all newsgroups of level LOWEST or higher." |
371 (set-buffer gnus-group-buffer) | 381 (set-buffer gnus-group-buffer) |
416 articles in the topic and its subtopics." | 426 articles in the topic and its subtopics." |
417 (let* ((type (pop topicl)) | 427 (let* ((type (pop topicl)) |
418 (entries (gnus-topic-find-groups | 428 (entries (gnus-topic-find-groups |
419 (car type) list-level | 429 (car type) list-level |
420 (or all | 430 (or all |
421 (cdr (assq 'visible | 431 (cdr (assq 'visible |
422 (gnus-topic-hierarchical-parameters | 432 (gnus-topic-hierarchical-parameters |
423 (car type))))) | 433 (car type))))) |
424 lowest)) | 434 lowest)) |
425 (visiblep (and (eq (nth 1 type) 'visible) (not silent))) | 435 (visiblep (and (eq (nth 1 type) 'visible) (not silent))) |
426 (gnus-group-indentation | 436 (gnus-group-indentation |
444 (while (setq entry (pop entries)) | 454 (while (setq entry (pop entries)) |
445 (when visiblep | 455 (when visiblep |
446 (if (stringp entry) | 456 (if (stringp entry) |
447 ;; Dead groups. | 457 ;; Dead groups. |
448 (gnus-group-insert-group-line | 458 (gnus-group-insert-group-line |
449 entry (if (member entry gnus-zombie-list) gnus-level-zombie gnus-level-killed) | 459 entry (if (member entry gnus-zombie-list) |
460 gnus-level-zombie gnus-level-killed) | |
450 nil (- (1+ (cdr (setq active (gnus-active entry)))) | 461 nil (- (1+ (cdr (setq active (gnus-active entry)))) |
451 (car active)) | 462 (car active)) |
452 nil) | 463 nil) |
453 ;; Living groups. | 464 ;; Living groups. |
454 (when (setq info (nth 2 entry)) | 465 (when (setq info (nth 2 entry)) |
492 ;; reason. I have been unable to determine why this is the | 503 ;; reason. I have been unable to determine why this is the |
493 ;; case, but this hack seems to take care of things. | 504 ;; case, but this hack seems to take care of things. |
494 (let ((data (cadr (gnus-topic-find-topology topic)))) | 505 (let ((data (cadr (gnus-topic-find-topology topic)))) |
495 (setcdr data | 506 (setcdr data |
496 (list (if insert 'visible 'invisible) | 507 (list (if insert 'visible 'invisible) |
497 (if hide 'hide nil) | 508 (caddr data) |
498 (cadddr data)))) | 509 (cadddr data)))) |
499 (if total-remove | 510 (if total-remove |
500 (setq gnus-topic-alist | 511 (setq gnus-topic-alist |
501 (delq (assoc topic gnus-topic-alist) gnus-topic-alist)) | 512 (delq (assoc topic gnus-topic-alist) gnus-topic-alist)) |
502 (gnus-topic-insert-topic topic in-level))))) | 513 (gnus-topic-insert-topic topic in-level))))) |
505 "Insert TOPIC." | 516 "Insert TOPIC." |
506 (gnus-group-prepare-topics | 517 (gnus-group-prepare-topics |
507 (car gnus-group-list-mode) (cdr gnus-group-list-mode) | 518 (car gnus-group-list-mode) (cdr gnus-group-list-mode) |
508 nil nil topic level)) | 519 nil nil topic level)) |
509 | 520 |
510 (defun gnus-topic-fold (&optional insert) | 521 (defun gnus-topic-fold (&optional insert topic) |
511 "Remove/insert the current topic." | 522 "Remove/insert the current topic." |
512 (let ((topic (gnus-group-topic-name))) | 523 (let ((topic (or topic (gnus-group-topic-name)))) |
513 (when topic | 524 (when topic |
514 (save-excursion | 525 (save-excursion |
515 (if (not (gnus-group-active-topic-p)) | 526 (if (not (gnus-group-active-topic-p)) |
516 (gnus-topic-remove-topic | 527 (gnus-topic-remove-topic |
517 (or insert (not (gnus-topic-visible-p)))) | 528 (or insert (not (gnus-topic-visible-p)))) |
531 (active-topic (eq gnus-topic-alist gnus-topic-active-alist)) | 542 (active-topic (eq gnus-topic-alist gnus-topic-active-alist)) |
532 gnus-tmp-header) | 543 gnus-tmp-header) |
533 (gnus-topic-update-unreads name unread) | 544 (gnus-topic-update-unreads name unread) |
534 (beginning-of-line) | 545 (beginning-of-line) |
535 ;; Insert the text. | 546 ;; Insert the text. |
536 (gnus-add-text-properties | 547 (if shownp |
537 (point) | 548 (gnus-add-text-properties |
538 (prog1 (1+ (point)) | 549 (point) |
539 (eval gnus-topic-line-format-spec)) | 550 (prog1 (1+ (point)) |
540 (list 'gnus-topic (intern name) | 551 (eval gnus-topic-line-format-spec)) |
541 'gnus-topic-level level | 552 (list 'gnus-topic (intern name) |
542 'gnus-topic-unread unread | 553 'gnus-topic-level level |
543 'gnus-active active-topic | 554 'gnus-topic-unread unread |
544 'gnus-topic-visible visiblep)))) | 555 'gnus-active active-topic |
556 'gnus-topic-visible visiblep))))) | |
545 | 557 |
546 (defun gnus-topic-update-unreads (topic unreads) | 558 (defun gnus-topic-update-unreads (topic unreads) |
547 (setq gnus-topic-unreads (delq (assoc topic gnus-topic-unreads) | 559 (setq gnus-topic-unreads (delq (assoc topic gnus-topic-unreads) |
548 gnus-topic-unreads)) | 560 gnus-topic-unreads)) |
549 (push (cons topic unreads) gnus-topic-unreads)) | 561 (push (cons topic unreads) gnus-topic-unreads)) |
582 (defun gnus-topic-goto-missing-group (group) | 594 (defun gnus-topic-goto-missing-group (group) |
583 "Place point where GROUP is supposed to be inserted." | 595 "Place point where GROUP is supposed to be inserted." |
584 (let* ((topic (gnus-group-topic group)) | 596 (let* ((topic (gnus-group-topic group)) |
585 (groups (cdr (assoc topic gnus-topic-alist))) | 597 (groups (cdr (assoc topic gnus-topic-alist))) |
586 (g (cdr (member group groups))) | 598 (g (cdr (member group groups))) |
587 (unfound t)) | 599 (unfound t) |
600 entry) | |
588 ;; Try to jump to a visible group. | 601 ;; Try to jump to a visible group. |
589 (while (and g (not (gnus-group-goto-group (car g) t))) | 602 (while (and g (not (gnus-group-goto-group (car g) t))) |
590 (pop g)) | 603 (pop g)) |
591 ;; It wasn't visible, so we try to see where to insert it. | 604 ;; It wasn't visible, so we try to see where to insert it. |
592 (when (not g) | 605 (when (not g) |
596 (forward-line 1) | 609 (forward-line 1) |
597 (setq unfound nil))) | 610 (setq unfound nil))) |
598 (when (and unfound | 611 (when (and unfound |
599 topic | 612 topic |
600 (not (gnus-topic-goto-missing-topic topic))) | 613 (not (gnus-topic-goto-missing-topic topic))) |
601 (gnus-topic-insert-topic-line | 614 (let* ((top (gnus-topic-find-topology topic)) |
602 topic t t (car (gnus-topic-find-topology topic)) nil 0))))) | 615 (children (cddr top)) |
616 (type (cadr top)) | |
617 (unread 0) | |
618 (entries (gnus-topic-find-groups | |
619 (car type) (car gnus-group-list-mode) | |
620 (cdr gnus-group-list-mode)))) | |
621 (while children | |
622 (incf unread (gnus-topic-unread (caar (pop children))))) | |
623 (while (setq entry (pop entries)) | |
624 (when (numberp (car entry)) | |
625 (incf unread (car entry)))) | |
626 (gnus-topic-insert-topic-line | |
627 topic t t (car (gnus-topic-find-topology topic)) nil unread)))))) | |
603 | 628 |
604 (defun gnus-topic-goto-missing-topic (topic) | 629 (defun gnus-topic-goto-missing-topic (topic) |
605 (if (gnus-topic-goto-topic topic) | 630 (if (gnus-topic-goto-topic topic) |
606 (forward-line 1) | 631 (forward-line 1) |
607 ;; Topic not displayed. | 632 ;; Topic not displayed. |
608 (let* ((top (gnus-topic-find-topology | 633 (let* ((top (gnus-topic-find-topology |
609 (gnus-topic-parent-topic topic))) | 634 (gnus-topic-parent-topic topic))) |
610 (tp (reverse (cddr top)))) | 635 (tp (reverse (cddr top)))) |
611 (while (not (equal (caaar tp) topic)) | 636 (if (not top) |
612 (setq tp (cdr tp))) | 637 (gnus-topic-insert-topic-line |
613 (pop tp) | 638 topic t t (car (gnus-topic-find-topology topic)) nil 0) |
614 (while (and tp | 639 (while (not (equal (caaar tp) topic)) |
615 (not (gnus-topic-goto-topic (caaar tp)))) | 640 (setq tp (cdr tp))) |
616 (pop tp)) | 641 (pop tp) |
617 (if tp | 642 (while (and tp |
618 (gnus-topic-forward-topic 1) | 643 (not (gnus-topic-goto-topic (caaar tp)))) |
619 (gnus-topic-goto-missing-topic (caadr top)))) | 644 (pop tp)) |
645 (if tp | |
646 (gnus-topic-forward-topic 1) | |
647 (gnus-topic-goto-missing-topic (caadr top))))) | |
620 nil)) | 648 nil)) |
621 | 649 |
622 (defun gnus-topic-update-topic-line (topic-name &optional reads) | 650 (defun gnus-topic-update-topic-line (topic-name &optional reads) |
623 (let* ((top (gnus-topic-find-topology topic-name)) | 651 (let* ((top (gnus-topic-find-topology topic-name)) |
624 (type (cadr top)) | 652 (type (cadr top)) |
906 ;; Override certain group mode keys. | 934 ;; Override certain group mode keys. |
907 (gnus-define-keys gnus-topic-mode-map | 935 (gnus-define-keys gnus-topic-mode-map |
908 "=" gnus-topic-select-group | 936 "=" gnus-topic-select-group |
909 "\r" gnus-topic-select-group | 937 "\r" gnus-topic-select-group |
910 " " gnus-topic-read-group | 938 " " gnus-topic-read-group |
939 "\C-c\C-x" gnus-topic-expire-articles | |
911 "\C-k" gnus-topic-kill-group | 940 "\C-k" gnus-topic-kill-group |
912 "\C-y" gnus-topic-yank-group | 941 "\C-y" gnus-topic-yank-group |
913 "\M-g" gnus-topic-get-new-news-this-topic | 942 "\M-g" gnus-topic-get-new-news-this-topic |
914 "AT" gnus-topic-list-active | 943 "AT" gnus-topic-list-active |
915 "Gp" gnus-topic-edit-parameters | 944 "Gp" gnus-topic-edit-parameters |
929 "m" gnus-topic-move-group | 958 "m" gnus-topic-move-group |
930 "D" gnus-topic-remove-group | 959 "D" gnus-topic-remove-group |
931 "c" gnus-topic-copy-group | 960 "c" gnus-topic-copy-group |
932 "h" gnus-topic-hide-topic | 961 "h" gnus-topic-hide-topic |
933 "s" gnus-topic-show-topic | 962 "s" gnus-topic-show-topic |
963 "j" gnus-topic-jump-to-topic | |
934 "M" gnus-topic-move-matching | 964 "M" gnus-topic-move-matching |
935 "C" gnus-topic-copy-matching | 965 "C" gnus-topic-copy-matching |
936 "\C-i" gnus-topic-indent | 966 "\C-i" gnus-topic-indent |
937 [tab] gnus-topic-indent | 967 [tab] gnus-topic-indent |
938 "r" gnus-topic-rename | 968 "r" gnus-topic-rename |
960 ["Move" gnus-topic-move-group t] | 990 ["Move" gnus-topic-move-group t] |
961 ["Remove" gnus-topic-remove-group t] | 991 ["Remove" gnus-topic-remove-group t] |
962 ["Copy matching" gnus-topic-copy-matching t] | 992 ["Copy matching" gnus-topic-copy-matching t] |
963 ["Move matching" gnus-topic-move-matching t]) | 993 ["Move matching" gnus-topic-move-matching t]) |
964 ("Topics" | 994 ("Topics" |
995 ["Goto" gnus-topic-jump-to-topic t] | |
965 ["Show" gnus-topic-show-topic t] | 996 ["Show" gnus-topic-show-topic t] |
966 ["Hide" gnus-topic-hide-topic t] | 997 ["Hide" gnus-topic-hide-topic t] |
967 ["Delete" gnus-topic-delete t] | 998 ["Delete" gnus-topic-delete t] |
968 ["Rename" gnus-topic-rename t] | 999 ["Rename" gnus-topic-rename t] |
969 ["Create" gnus-topic-create-topic t] | 1000 ["Create" gnus-topic-create-topic t] |
970 ["Mark" gnus-topic-mark-topic t] | 1001 ["Mark" gnus-topic-mark-topic t] |
971 ["Indent" gnus-topic-indent t] | 1002 ["Indent" gnus-topic-indent t] |
1003 ["Sort" gnus-topic-sort-topics t] | |
972 ["Toggle hide empty" gnus-topic-toggle-display-empty-topics t] | 1004 ["Toggle hide empty" gnus-topic-toggle-display-empty-topics t] |
973 ["Edit parameters" gnus-topic-edit-parameters t]) | 1005 ["Edit parameters" gnus-topic-edit-parameters t]) |
974 ["List active" gnus-topic-list-active t])))) | 1006 ["List active" gnus-topic-list-active t])))) |
975 | 1007 |
976 (defun gnus-topic-mode (&optional arg redisplay) | 1008 (defun gnus-topic-mode (&optional arg redisplay) |
980 (make-local-variable 'gnus-topic-mode) | 1012 (make-local-variable 'gnus-topic-mode) |
981 (setq gnus-topic-mode | 1013 (setq gnus-topic-mode |
982 (if (null arg) (not gnus-topic-mode) | 1014 (if (null arg) (not gnus-topic-mode) |
983 (> (prefix-numeric-value arg) 0))) | 1015 (> (prefix-numeric-value arg) 0))) |
984 ;; Infest Gnus with topics. | 1016 ;; Infest Gnus with topics. |
985 (if (not gnus-topic-mode) | 1017 (if (not gnus-topic-mode) |
986 (setq gnus-goto-missing-group-function nil) | 1018 (setq gnus-goto-missing-group-function nil) |
987 (when (gnus-visual-p 'topic-menu 'menu) | 1019 (when (gnus-visual-p 'topic-menu 'menu) |
988 (gnus-topic-make-menu-bar)) | 1020 (gnus-topic-make-menu-bar)) |
989 (gnus-set-format 'topic t) | 1021 (gnus-set-format 'topic t) |
990 (gnus-add-minor-mode 'gnus-topic-mode " Topic" gnus-topic-mode-map) | 1022 (gnus-add-minor-mode 'gnus-topic-mode " Topic" |
1023 gnus-topic-mode-map nil (lambda (&rest junk) | |
1024 (interactive) | |
1025 (gnus-topic-mode nil t))) | |
991 (add-hook 'gnus-group-catchup-group-hook 'gnus-topic-update-topic) | 1026 (add-hook 'gnus-group-catchup-group-hook 'gnus-topic-update-topic) |
992 (set (make-local-variable 'gnus-group-prepare-function) | 1027 (set (make-local-variable 'gnus-group-prepare-function) |
993 'gnus-group-prepare-topics) | 1028 'gnus-group-prepare-topics) |
994 (set (make-local-variable 'gnus-group-get-parameter-function) | 1029 (set (make-local-variable 'gnus-group-get-parameter-function) |
995 'gnus-group-topic-parameters) | 1030 'gnus-group-topic-parameters) |
1030 If performed over a topic line, toggle folding the topic." | 1065 If performed over a topic line, toggle folding the topic." |
1031 (interactive "P") | 1066 (interactive "P") |
1032 (if (gnus-group-topic-p) | 1067 (if (gnus-group-topic-p) |
1033 (let ((gnus-group-list-mode | 1068 (let ((gnus-group-list-mode |
1034 (if all (cons (if (numberp all) all 7) t) gnus-group-list-mode))) | 1069 (if all (cons (if (numberp all) all 7) t) gnus-group-list-mode))) |
1035 (gnus-topic-fold all)) | 1070 (gnus-topic-fold all) |
1071 (gnus-dribble-touch)) | |
1036 (gnus-group-select-group all))) | 1072 (gnus-group-select-group all))) |
1037 | 1073 |
1038 (defun gnus-mouse-pick-topic (e) | 1074 (defun gnus-mouse-pick-topic (e) |
1039 "Select the group or topic under the mouse pointer." | 1075 "Select the group or topic under the mouse pointer." |
1040 (interactive "e") | 1076 (interactive "e") |
1041 (mouse-set-point e) | 1077 (mouse-set-point e) |
1042 (gnus-topic-read-group nil)) | 1078 (gnus-topic-read-group nil)) |
1079 | |
1080 (defun gnus-topic-expire-articles (topic) | |
1081 "Expire articles in this topic or group." | |
1082 (interactive (list (gnus-group-topic-name))) | |
1083 (if (not topic) | |
1084 (call-interactively 'gnus-group-expire-articles) | |
1085 (save-excursion | |
1086 (gnus-message 5 "Expiring groups in %s..." topic) | |
1087 (let ((gnus-group-marked | |
1088 (mapcar (lambda (entry) (car (nth 2 entry))) | |
1089 (gnus-topic-find-groups topic gnus-level-killed t)))) | |
1090 (gnus-group-expire-articles nil)) | |
1091 (gnus-message 5 "Expiring groups in %s...done" topic)))) | |
1043 | 1092 |
1044 (defun gnus-topic-read-group (&optional all no-article group) | 1093 (defun gnus-topic-read-group (&optional all no-article group) |
1045 "Read news in this newsgroup. | 1094 "Read news in this newsgroup. |
1046 If the prefix argument ALL is non-nil, already read articles become | 1095 If the prefix argument ALL is non-nil, already read articles become |
1047 readable. IF ALL is a number, fetch this number of articles. If the | 1096 readable. IF ALL is a number, fetch this number of articles. If the |
1084 (push (list topic) gnus-topic-alist))) | 1133 (push (list topic) gnus-topic-alist))) |
1085 (gnus-topic-enter-dribble) | 1134 (gnus-topic-enter-dribble) |
1086 (gnus-group-list-groups) | 1135 (gnus-group-list-groups) |
1087 (gnus-topic-goto-topic topic)) | 1136 (gnus-topic-goto-topic topic)) |
1088 | 1137 |
1138 ;; FIXME: | |
1139 ;; 1. When the marked groups are overlapped with the process | |
1140 ;; region, the behavior of move or remove is not right. | |
1141 ;; 2. Can't process on several marked groups with a same name, | |
1142 ;; because gnus-group-marked only keeps one copy. | |
1143 | |
1089 (defun gnus-topic-move-group (n topic &optional copyp) | 1144 (defun gnus-topic-move-group (n topic &optional copyp) |
1090 "Move the next N groups to TOPIC. | 1145 "Move the next N groups to TOPIC. |
1091 If COPYP, copy the groups instead." | 1146 If COPYP, copy the groups instead." |
1092 (interactive | 1147 (interactive |
1093 (list current-prefix-arg | 1148 (list current-prefix-arg |
1094 (completing-read "Move to topic: " gnus-topic-alist nil t))) | 1149 (completing-read "Move to topic: " gnus-topic-alist nil t))) |
1095 (let ((groups (gnus-group-process-prefix n)) | 1150 (let ((use-marked (and (not n) (not (gnus-region-active-p)) |
1151 gnus-group-marked t)) | |
1152 (groups (gnus-group-process-prefix n)) | |
1096 (topicl (assoc topic gnus-topic-alist)) | 1153 (topicl (assoc topic gnus-topic-alist)) |
1154 (start-topic (gnus-group-topic-name)) | |
1097 (start-group (progn (forward-line 1) (gnus-group-group-name))) | 1155 (start-group (progn (forward-line 1) (gnus-group-group-name))) |
1098 (start-topic (gnus-group-topic-name)) | |
1099 entry) | 1156 entry) |
1157 (if (and (not groups) (not copyp) start-topic) | |
1158 (gnus-topic-move start-topic topic) | |
1159 (mapcar | |
1160 (lambda (g) | |
1161 (gnus-group-remove-mark g use-marked) | |
1162 (when (and | |
1163 (setq entry (assoc (gnus-current-topic) gnus-topic-alist)) | |
1164 (not copyp)) | |
1165 (setcdr entry (gnus-delete-first g (cdr entry)))) | |
1166 (nconc topicl (list g))) | |
1167 groups) | |
1168 (gnus-topic-enter-dribble) | |
1169 (if start-group | |
1170 (gnus-group-goto-group start-group) | |
1171 (gnus-topic-goto-topic start-topic)) | |
1172 (gnus-group-list-groups)))) | |
1173 | |
1174 (defun gnus-topic-remove-group (&optional n) | |
1175 "Remove the current group from the topic." | |
1176 (interactive "P") | |
1177 (let ((use-marked (and (not n) (not (gnus-region-active-p)) | |
1178 gnus-group-marked t)) | |
1179 (groups (gnus-group-process-prefix n))) | |
1100 (mapcar | 1180 (mapcar |
1101 (lambda (g) | 1181 (lambda (group) |
1102 (gnus-group-remove-mark g) | 1182 (gnus-group-remove-mark group use-marked) |
1103 (when (and | 1183 (let ((topicl (assoc (gnus-current-topic) gnus-topic-alist)) |
1104 (setq entry (assoc (gnus-current-topic) gnus-topic-alist)) | 1184 (buffer-read-only nil)) |
1105 (not copyp)) | 1185 (when (and topicl group) |
1106 (setcdr entry (gnus-delete-first g (cdr entry)))) | 1186 (gnus-delete-line) |
1107 (nconc topicl (list g))) | 1187 (gnus-delete-first group topicl)) |
1188 (gnus-topic-update-topic))) | |
1108 groups) | 1189 groups) |
1109 (gnus-topic-enter-dribble) | 1190 (gnus-topic-enter-dribble) |
1110 (if start-group | 1191 (gnus-group-position-point))) |
1111 (gnus-group-goto-group start-group) | |
1112 (gnus-topic-goto-topic start-topic)) | |
1113 (gnus-group-list-groups))) | |
1114 | |
1115 (defun gnus-topic-remove-group (&optional arg) | |
1116 "Remove the current group from the topic." | |
1117 (interactive "P") | |
1118 (gnus-group-iterate arg | |
1119 (lambda (group) | |
1120 (let ((topicl (assoc (gnus-current-topic) gnus-topic-alist)) | |
1121 (buffer-read-only nil)) | |
1122 (when (and topicl group) | |
1123 (gnus-delete-line) | |
1124 (gnus-delete-first group topicl)) | |
1125 (gnus-topic-update-topic) | |
1126 (gnus-group-position-point))))) | |
1127 | 1192 |
1128 (defun gnus-topic-copy-group (n topic) | 1193 (defun gnus-topic-copy-group (n topic) |
1129 "Copy the current group to a topic." | 1194 "Copy the current group to a topic." |
1130 (interactive | 1195 (interactive |
1131 (list current-prefix-arg | 1196 (list current-prefix-arg |
1143 gnus-topic-killed-topics) | 1208 gnus-topic-killed-topics) |
1144 (gnus-topic-remove-topic nil t) | 1209 (gnus-topic-remove-topic nil t) |
1145 (gnus-topic-find-topology topic nil nil gnus-topic-topology) | 1210 (gnus-topic-find-topology topic nil nil gnus-topic-topology) |
1146 (gnus-topic-enter-dribble)) | 1211 (gnus-topic-enter-dribble)) |
1147 (gnus-group-kill-group n discard) | 1212 (gnus-group-kill-group n discard) |
1148 (gnus-topic-update-topic))) | 1213 (if (not (gnus-group-topic-p)) |
1214 (gnus-topic-update-topic) | |
1215 ;; Move up one line so that we update the right topic. | |
1216 (forward-line -1) | |
1217 (gnus-topic-update-topic) | |
1218 (forward-line 1)))) | |
1149 | 1219 |
1150 (defun gnus-topic-yank-group (&optional arg) | 1220 (defun gnus-topic-yank-group (&optional arg) |
1151 "Yank the last topic." | 1221 "Yank the last topic." |
1152 (interactive "p") | 1222 (interactive "p") |
1153 (if gnus-topic-killed-topics | 1223 (if gnus-topic-killed-topics |
1193 (setcdr alist (nconc yanked (cdr alist))) | 1263 (setcdr alist (nconc yanked (cdr alist))) |
1194 (setq alist nil)) | 1264 (setq alist nil)) |
1195 (setq alist (cdr alist)))))) | 1265 (setq alist (cdr alist)))))) |
1196 (gnus-topic-update-topic))) | 1266 (gnus-topic-update-topic))) |
1197 | 1267 |
1198 (defun gnus-topic-hide-topic () | 1268 (defun gnus-topic-hide-topic (&optional permanent) |
1199 "Hide the current topic." | 1269 "Hide the current topic. |
1200 (interactive) | 1270 If PERMANENT, make it stay hidden in subsequent sessions as well." |
1271 (interactive "P") | |
1201 (when (gnus-current-topic) | 1272 (when (gnus-current-topic) |
1202 (gnus-topic-goto-topic (gnus-current-topic)) | 1273 (gnus-topic-goto-topic (gnus-current-topic)) |
1203 (gnus-topic-remove-topic nil nil 'hidden))) | 1274 (if permanent |
1204 | 1275 (setcar (cddr |
1205 (defun gnus-topic-show-topic () | 1276 (cadr |
1206 "Show the hidden topic." | 1277 (gnus-topic-find-topology (gnus-current-topic)))) |
1207 (interactive) | 1278 'hidden)) |
1279 (gnus-topic-remove-topic nil nil))) | |
1280 | |
1281 (defun gnus-topic-show-topic (&optional permanent) | |
1282 "Show the hidden topic. | |
1283 If PERMANENT, make it stay shown in subsequent sessions as well." | |
1284 (interactive "P") | |
1208 (when (gnus-group-topic-p) | 1285 (when (gnus-group-topic-p) |
1209 (gnus-topic-remove-topic t nil 'shown))) | 1286 (if (not permanent) |
1287 (gnus-topic-remove-topic t nil) | |
1288 (let ((topic | |
1289 (gnus-topic-find-topology | |
1290 (completing-read "Show topic: " gnus-topic-alist nil t)))) | |
1291 (setcar (cddr (cadr topic)) nil) | |
1292 (setcar (cdr (cadr topic)) 'visible) | |
1293 (gnus-group-list-groups))))) | |
1210 | 1294 |
1211 (defun gnus-topic-mark-topic (topic &optional unmark) | 1295 (defun gnus-topic-mark-topic (topic &optional unmark) |
1212 "Mark all groups in the topic with the process mark." | 1296 "Mark all groups in the topic with the process mark." |
1213 (interactive (list (gnus-group-topic-name))) | 1297 (interactive (list (gnus-group-topic-name))) |
1214 (if (not topic) | 1298 (if (not topic) |
1448 "Sort the current topic alphabetically by backend name. | 1532 "Sort the current topic alphabetically by backend name. |
1449 If REVERSE, sort in reverse order." | 1533 If REVERSE, sort in reverse order." |
1450 (interactive "P") | 1534 (interactive "P") |
1451 (gnus-topic-sort-groups 'gnus-group-sort-by-method reverse)) | 1535 (gnus-topic-sort-groups 'gnus-group-sort-by-method reverse)) |
1452 | 1536 |
1537 (defun gnus-topic-sort-topics-1 (top reverse) | |
1538 (if (cdr top) | |
1539 (let ((subtop | |
1540 (mapcar `(lambda (top) | |
1541 (gnus-topic-sort-topics-1 top ,reverse)) | |
1542 (sort (cdr top) | |
1543 '(lambda (t1 t2) | |
1544 (string-lessp (caar t1) (caar t2))))))) | |
1545 (setcdr top (if reverse (reverse subtop) subtop)))) | |
1546 top) | |
1547 | |
1548 (defun gnus-topic-sort-topics (&optional topic reverse) | |
1549 "Sort topics in TOPIC alphabeticaly by topic name. | |
1550 If REVERSE, reverse the sorting order." | |
1551 (interactive | |
1552 (list (completing-read "Sort topics in : " gnus-topic-alist nil t | |
1553 (gnus-current-topic)) | |
1554 current-prefix-arg)) | |
1555 (let ((topic-topology (or (and topic (cdr (gnus-topic-find-topology topic))) | |
1556 gnus-topic-topology))) | |
1557 (gnus-topic-sort-topics-1 topic-topology reverse) | |
1558 (gnus-topic-enter-dribble) | |
1559 (gnus-group-list-groups) | |
1560 (gnus-topic-goto-topic topic))) | |
1561 | |
1562 (defun gnus-topic-move (current to) | |
1563 "Move the CURRENT topic to TO." | |
1564 (interactive | |
1565 (list | |
1566 (gnus-group-topic-name) | |
1567 (completing-read "Move to topic: " gnus-topic-alist nil t))) | |
1568 (unless (and current to) | |
1569 (error "Can't find topic")) | |
1570 (let ((current-top (cdr (gnus-topic-find-topology current))) | |
1571 (to-top (cdr (gnus-topic-find-topology to)))) | |
1572 (unless current-top | |
1573 (error "Can't find topic `%s'" current)) | |
1574 (unless to-top | |
1575 (error "Can't find topic `%s'" to)) | |
1576 (if (gnus-topic-find-topology to current-top 0);; Don't care the level | |
1577 (error "Can't move `%s' to its sub-level" current)) | |
1578 (gnus-topic-find-topology current nil nil 'delete) | |
1579 (while (cdr to-top) | |
1580 (setq to-top (cdr to-top))) | |
1581 (setcdr to-top (list current-top)) | |
1582 (gnus-topic-enter-dribble) | |
1583 (gnus-group-list-groups) | |
1584 (gnus-topic-goto-topic current))) | |
1585 | |
1586 (defun gnus-subscribe-topics (newsgroup) | |
1587 (catch 'end | |
1588 (let (match gnus-group-change-level-function) | |
1589 (dolist (topic (gnus-topic-list)) | |
1590 (when (and (setq match (cdr (assq 'subscribe | |
1591 (gnus-topic-parameters topic)))) | |
1592 (string-match match newsgroup)) | |
1593 ;; Just subscribe the group. | |
1594 (gnus-subscribe-alphabetically newsgroup) | |
1595 ;; Add the group to the topic. | |
1596 (nconc (assoc topic gnus-topic-alist) (list newsgroup)) | |
1597 (throw 'end t)))))) | |
1598 | |
1453 (provide 'gnus-topic) | 1599 (provide 'gnus-topic) |
1454 | 1600 |
1455 ;;; gnus-topic.el ends here | 1601 ;;; gnus-topic.el ends here |