Mercurial > emacs
comparison lisp/mh-e/mh-seq.el @ 56673:e9a6cbc8ca5e
Upgraded to MH-E version 7.4.80.
See etc/MH-E-NEWS and lisp/mh-e/ChangeLog for details.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Sun, 15 Aug 2004 22:00:06 +0000 |
parents | d36b00b98db0 |
children | 4f4f410e6fe8 d8411455de48 |
comparison
equal
deleted
inserted
replaced
56672:83ab2b01744a | 56673:e9a6cbc8ca5e |
---|---|
68 | 68 |
69 ;;; Change Log: | 69 ;;; Change Log: |
70 | 70 |
71 ;;; Code: | 71 ;;; Code: |
72 | 72 |
73 (require 'mh-utils) | 73 (eval-when-compile (require 'mh-acros)) |
74 (mh-require-cl) | 74 (mh-require-cl) |
75 (require 'mh-e) | 75 (require 'mh-e) |
76 | 76 |
77 ;; Shush the byte-compiler | 77 ;; Shush the byte-compiler |
78 (defvar tool-bar-mode) | 78 (defvar tool-bar-mode) |
79 | 79 |
80 ;;; Data structures (used in message threading)... | 80 ;;; Data structures (used in message threading)... |
81 (defstruct (mh-thread-message (:conc-name mh-message-) | 81 (mh-defstruct (mh-thread-message (:conc-name mh-message-) |
82 (:constructor mh-thread-make-message)) | 82 (:constructor mh-thread-make-message)) |
83 (id nil) | 83 (id nil) |
84 (references ()) | 84 (references ()) |
85 (subject "") | 85 (subject "") |
86 (subject-re-p nil)) | 86 (subject-re-p nil)) |
87 | 87 |
88 (defstruct (mh-thread-container (:conc-name mh-container-) | 88 (mh-defstruct (mh-thread-container (:conc-name mh-container-) |
89 (:constructor mh-thread-make-container)) | 89 (:constructor mh-thread-make-container)) |
90 message parent children | 90 message parent children |
91 (real-child-p t)) | 91 (real-child-p t)) |
92 | 92 |
93 | 93 |
94 ;;; Internal variables: | 94 ;;; Internal variables: |
199 (setq view-exit-action 'kill-buffer) | 199 (setq view-exit-action 'kill-buffer) |
200 (message "Listing sequences...done"))))) | 200 (message "Listing sequences...done"))))) |
201 | 201 |
202 ;;;###mh-autoload | 202 ;;;###mh-autoload |
203 (defun mh-msg-is-in-seq (message) | 203 (defun mh-msg-is-in-seq (message) |
204 "Display the sequences that contain MESSAGE. | 204 "Display the sequences in which the current message appears. |
205 Default is the displayed message." | 205 Use a prefix argument to display the sequences in which another MESSAGE |
206 (interactive (list (mh-get-msg-num t))) | 206 appears." |
207 (interactive "P") | |
208 (if (not message) | |
209 (setq message (mh-get-msg-num t))) | |
207 (let* ((dest-folder (loop for seq in mh-refile-list | 210 (let* ((dest-folder (loop for seq in mh-refile-list |
208 until (member message (cdr seq)) | 211 when (member message (cdr seq)) return (car seq) |
209 finally return (car seq))) | 212 finally return nil)) |
210 (deleted-flag (unless dest-folder (member message mh-delete-list)))) | 213 (deleted-flag (unless dest-folder (member message mh-delete-list)))) |
211 (message "Message %d%s is in sequences: %s" | 214 (message "Message %d%s is in sequences: %s" |
212 message | 215 message |
213 (cond (dest-folder (format " (to be refiled to %s)" dest-folder)) | 216 (cond (dest-folder (format " (to be refiled to %s)" dest-folder)) |
214 (deleted-flag (format " (to be deleted)")) | 217 (deleted-flag (format " (to be deleted)")) |
267 (unless (mh-valid-seq-p sequence) | 270 (unless (mh-valid-seq-p sequence) |
268 (error "Can't put message in invalid sequence `%s'" sequence)) | 271 (error "Can't put message in invalid sequence `%s'" sequence)) |
269 (let* ((internal-seq-flag (mh-internal-seq sequence)) | 272 (let* ((internal-seq-flag (mh-internal-seq sequence)) |
270 (original-msgs (mh-seq-msgs (mh-find-seq sequence))) | 273 (original-msgs (mh-seq-msgs (mh-find-seq sequence))) |
271 (folders (list mh-current-folder)) | 274 (folders (list mh-current-folder)) |
272 (msg-list ())) | 275 (msg-list (mh-range-to-msg-list range))) |
276 (mh-add-msgs-to-seq msg-list sequence nil t) | |
273 (mh-iterate-on-range m range | 277 (mh-iterate-on-range m range |
274 (push m msg-list) | |
275 (unless (memq m original-msgs) | 278 (unless (memq m original-msgs) |
276 (mh-add-sequence-notation m internal-seq-flag))) | 279 (mh-add-sequence-notation m internal-seq-flag))) |
277 (mh-add-msgs-to-seq msg-list sequence nil t) | |
278 (if (not internal-seq-flag) | 280 (if (not internal-seq-flag) |
279 (setq mh-last-seq-used sequence)) | 281 (setq mh-last-seq-used sequence)) |
280 (when mh-index-data | 282 (when mh-index-data |
281 (setq folders | 283 (setq folders |
282 (append folders (mh-index-add-to-sequence sequence msg-list)))) | 284 (append folders (mh-index-add-to-sequence sequence msg-list)))) |
290 (pop mh-view-ops)) | 292 (pop mh-view-ops)) |
291 (t nil))) | 293 (t nil))) |
292 | 294 |
293 ;;;###mh-autoload | 295 ;;;###mh-autoload |
294 (defun mh-widen (&optional all-flag) | 296 (defun mh-widen (&optional all-flag) |
295 "Remove last restriction from current folder. | 297 "Restore the previous limit. |
296 If optional prefix argument ALL-FLAG is non-nil, then unwind to the beginning | 298 If optional prefix argument ALL-FLAG is non-nil, remove all limits." |
297 of the view stack thereby showing all messages that the buffer originally | |
298 contained." | |
299 (interactive "P") | 299 (interactive "P") |
300 (let ((msg (mh-get-msg-num nil))) | 300 (let ((msg (mh-get-msg-num nil))) |
301 (when mh-folder-view-stack | 301 (when mh-folder-view-stack |
302 (cond (all-flag | 302 (cond (all-flag |
303 (while (cdr mh-view-ops) | 303 (while (cdr mh-view-ops) |
531 (mh-define-sequence new-name (mh-seq-msgs old-seq)) | 531 (mh-define-sequence new-name (mh-seq-msgs old-seq)) |
532 (mh-undefine-sequence sequence (mh-seq-msgs old-seq)) | 532 (mh-undefine-sequence sequence (mh-seq-msgs old-seq)) |
533 (rplaca old-seq new-name))) | 533 (rplaca old-seq new-name))) |
534 | 534 |
535 ;;;###mh-autoload | 535 ;;;###mh-autoload |
536 (defun mh-map-to-seq-msgs (func seq &rest args) | |
537 "Invoke the FUNC at each message in the SEQ. | |
538 SEQ can either be a list of messages or a MH sequence. The remaining ARGS are | |
539 passed as arguments to FUNC." | |
540 (save-excursion | |
541 (let ((msgs (if (listp seq) seq (mh-seq-to-msgs seq)))) | |
542 (while msgs | |
543 (if (mh-goto-msg (car msgs) t t) | |
544 (apply func (car msgs) args)) | |
545 (setq msgs (cdr msgs)))))) | |
546 | |
547 ;;;###mh-autoload | |
548 (defun mh-notate-seq (seq notation offset) | |
549 "Mark the scan listing. | |
550 All messages in SEQ are marked with NOTATION at OFFSET from the beginning of | |
551 the line." | |
552 (let ((msg-list (mh-seq-to-msgs seq))) | |
553 (mh-iterate-on-messages-in-region msg (point-min) (point-max) | |
554 (when (member msg msg-list) | |
555 (mh-notate nil notation offset))))) | |
556 | |
557 ;;;###mh-autoload | |
558 (defun mh-notate-cur () | 536 (defun mh-notate-cur () |
559 "Mark the MH sequence cur. | 537 "Mark the MH sequence cur. |
560 In addition to notating the current message with `mh-note-cur' the function | 538 In addition to notating the current message with `mh-note-cur' the function |
561 uses `overlay-arrow-position' to put a marker in the fringe." | 539 uses `overlay-arrow-position' to put a marker in the fringe." |
562 (let ((cur (car (mh-seq-to-msgs 'cur)))) | 540 (let ((cur (car (mh-seq-to-msgs 'cur)))) |
574 (if (and (mh-valid-seq-p seq) (not (mh-folder-name-p seq))) | 552 (if (and (mh-valid-seq-p seq) (not (mh-folder-name-p seq))) |
575 (if msgs | 553 (if msgs |
576 (apply 'mh-exec-cmd "mark" mh-current-folder "-add" | 554 (apply 'mh-exec-cmd "mark" mh-current-folder "-add" |
577 "-sequence" (symbol-name seq) | 555 "-sequence" (symbol-name seq) |
578 (mh-coalesce-msg-list msgs))))) | 556 (mh-coalesce-msg-list msgs))))) |
579 | |
580 ;; This has a tricky bug. mh-map-to-seq-msgs uses mh-goto-msg, which assumes | |
581 ;; that the folder buffer is sorted. However in this case that assumption | |
582 ;; doesn't hold. So we will do this the dumb way. | |
583 ;(defun mh-copy-seq-to-point (seq location) | |
584 ; ;; Copy the scan listing of the messages in SEQUENCE to after the point | |
585 ; ;; LOCATION in the current buffer. | |
586 ; (mh-map-to-seq-msgs 'mh-copy-line-to-point seq location)) | |
587 | 557 |
588 (defvar mh-thread-last-ancestor) | 558 (defvar mh-thread-last-ancestor) |
589 | 559 |
590 (defun mh-copy-seq-to-eob (seq) | 560 (defun mh-copy-seq-to-eob (seq) |
591 "Copy SEQ to the end of the buffer." | 561 "Copy SEQ to the end of the buffer." |
611 (mh-thread-print-scan-lines | 581 (mh-thread-print-scan-lines |
612 (mh-thread-generate mh-current-folder ())) | 582 (mh-thread-generate mh-current-folder ())) |
613 (mh-notate-user-sequences)) | 583 (mh-notate-user-sequences)) |
614 (mh-index-data | 584 (mh-index-data |
615 (mh-index-insert-folder-headers))))))) | 585 (mh-index-insert-folder-headers))))))) |
616 | |
617 (defun mh-copy-line-to-point (msg location) | |
618 "Copy current message line to a specific location. | |
619 The argument MSG is not used. The message in the current line is copied to | |
620 LOCATION." | |
621 ;; msg is not used? | |
622 ;; Copy the current line to the LOCATION in the current buffer. | |
623 (beginning-of-line) | |
624 (save-excursion | |
625 (let ((beginning-of-line (point)) | |
626 end) | |
627 (forward-line 1) | |
628 (setq end (point)) | |
629 (goto-char location) | |
630 (insert-buffer-substring (current-buffer) beginning-of-line end)))) | |
631 | 586 |
632 ;;;###mh-autoload | 587 ;;;###mh-autoload |
633 (defmacro mh-iterate-on-messages-in-region (var begin end &rest body) | 588 (defmacro mh-iterate-on-messages-in-region (var begin end &rest body) |
634 "Iterate over region. | 589 "Iterate over region. |
635 VAR is bound to the message on the current line as we loop starting from BEGIN | 590 VAR is bound to the message on the current line as we loop starting from BEGIN |
700 (mh-iterate-on-range msg range | 655 (mh-iterate-on-range msg range |
701 (push msg msg-list)) | 656 (push msg msg-list)) |
702 (nreverse msg-list))) | 657 (nreverse msg-list))) |
703 | 658 |
704 ;;;###mh-autoload | 659 ;;;###mh-autoload |
705 (defun mh-interactive-range (range-prompt) | 660 (defun mh-interactive-range (range-prompt &optional default) |
706 "Return interactive specification for message, sequence, range or region. | 661 "Return interactive specification for message, sequence, range or region. |
707 By convention, the name of this argument is RANGE. | 662 By convention, the name of this argument is RANGE. |
708 | 663 |
709 If variable `transient-mark-mode' is non-nil and the mark is active, then this | 664 If variable `transient-mark-mode' is non-nil and the mark is active, then this |
710 function returns a cons-cell of the region. | 665 function returns a cons-cell of the region. |
712 If optional prefix argument is provided, then prompt for message range with | 667 If optional prefix argument is provided, then prompt for message range with |
713 RANGE-PROMPT. A list of messages in that range is returned. | 668 RANGE-PROMPT. A list of messages in that range is returned. |
714 | 669 |
715 If a MH range is given, say something like last:20, then a list containing | 670 If a MH range is given, say something like last:20, then a list containing |
716 the messages in that range is returned. | 671 the messages in that range is returned. |
672 | |
673 If DEFAULT non-nil then it is returned. | |
717 | 674 |
718 Otherwise, the message number at point is returned. | 675 Otherwise, the message number at point is returned. |
719 | 676 |
720 This function is usually used with `mh-iterate-on-range' in order to provide | 677 This function is usually used with `mh-iterate-on-range' in order to provide |
721 a uniform interface to MH-E functions." | 678 a uniform interface to MH-E functions." |
722 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end))) | 679 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end))) |
723 (current-prefix-arg (mh-read-range range-prompt nil nil t t)) | 680 (current-prefix-arg (mh-read-range range-prompt nil nil t t)) |
681 (default default) | |
724 (t (mh-get-msg-num t)))) | 682 (t (mh-get-msg-num t)))) |
725 | |
726 ;;;###mh-autoload | |
727 (defun mh-region-to-msg-list (begin end) | |
728 "Return a list of messages within the region between BEGIN and END." | |
729 ;; If end is end of buffer back up one position | |
730 (setq end (if (equal end (point-max)) (1- end) end)) | |
731 (let ((result)) | |
732 (mh-iterate-on-messages-in-region index begin end | |
733 (when (numberp index) (push index result))) | |
734 result)) | |
735 | 683 |
736 | 684 |
737 | 685 |
738 ;;; Commands to handle new 'subject sequence. | 686 ;;; Commands to handle new 'subject sequence. |
739 ;;; Or "Poor man's threading" by psg. | 687 ;;; Or "Poor man's threading" by psg. |
770 (save-excursion | 718 (save-excursion |
771 (beginning-of-line) | 719 (beginning-of-line) |
772 (if (or (not (looking-at mh-scan-subject-regexp)) | 720 (if (or (not (looking-at mh-scan-subject-regexp)) |
773 (not (match-string 3)) | 721 (not (match-string 3)) |
774 (string-equal "" (match-string 3))) | 722 (string-equal "" (match-string 3))) |
775 (progn (message "No subject line.") | 723 (progn (message "No subject line") |
776 nil) | 724 nil) |
777 (let ((subject (match-string-no-properties 3)) | 725 (let ((subject (match-string-no-properties 3)) |
778 (list)) | 726 (list)) |
779 (if (> (length subject) 41) | 727 (if (> (length subject) 41) |
780 (setq subject (substring subject 0 41))) | 728 (setq subject (substring subject 0 41))) |
833 (ignore-errors | 781 (ignore-errors |
834 (mh-message-subject | 782 (mh-message-subject |
835 (mh-container-message (gethash (gethash msg mh-thread-index-id-map) | 783 (mh-container-message (gethash (gethash msg mh-thread-index-id-map) |
836 mh-thread-id-table))))) | 784 mh-thread-id-table))))) |
837 | 785 |
838 ;;;###mh-autoload | 786 (defun mh-edit-pick-expr (default) |
839 (defun mh-narrow-to-subject () | 787 "With prefix arg edit a pick expression. |
840 "Narrow to a sequence containing all following messages with same subject." | |
841 (interactive) | |
842 (let ((num (mh-get-msg-num nil)) | |
843 (count (mh-subject-to-sequence t))) | |
844 (cond | |
845 ((not count) ; No subject line, delete msg anyway | |
846 nil) | |
847 ((= 0 count) ; No other msgs, delete msg anyway. | |
848 (message "No other messages with same Subject following this one.") | |
849 nil) | |
850 (t ; We have a subject sequence. | |
851 (message "Found %d messages for subject sequence." count) | |
852 (mh-narrow-to-seq 'subject) | |
853 (if (numberp num) | |
854 (mh-goto-msg num t t)))))) | |
855 | |
856 (defun mh-read-pick-regexp (default) | |
857 "With prefix arg read a pick regexp. | |
858 If no prefix arg is given, then return DEFAULT." | 788 If no prefix arg is given, then return DEFAULT." |
859 (let ((default-string (loop for x in default concat (format " %s" x)))) | 789 (let ((default-string (loop for x in default concat (format " %s" x)))) |
860 (if (or current-prefix-arg (equal default-string "")) | 790 (if (or current-prefix-arg (equal default-string "")) |
861 (delete "" (split-string (read-string "Pick regexp: " default-string))) | 791 (delete "" (split-string (read-string "Pick expression: " |
792 default-string))) | |
862 default))) | 793 default))) |
863 | 794 |
864 ;;;###mh-autoload | 795 ;;;###mh-autoload |
865 (defun mh-narrow-to-from (&optional regexp) | 796 (defun mh-narrow-to-subject (&optional pick-expr) |
866 "Limit to messages with the same From header field as the message at point. | 797 "Limit to messages with same subject. |
867 With a prefix argument, prompt for the regular expression, REGEXP given to | 798 With a prefix argument, edit PICK-EXPR. |
868 pick." | 799 |
800 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." | |
869 (interactive | 801 (interactive |
870 (list (mh-read-pick-regexp (mh-current-message-header-field 'from)))) | 802 (list (mh-edit-pick-expr (mh-current-message-header-field 'subject)))) |
871 (mh-narrow-to-header-field 'from regexp)) | 803 (mh-narrow-to-header-field 'subject pick-expr)) |
872 | 804 |
873 ;;;###mh-autoload | 805 ;;;###mh-autoload |
874 (defun mh-narrow-to-cc (&optional regexp) | 806 (defun mh-narrow-to-from (&optional pick-expr) |
875 "Limit to messages with the same Cc header field as the message at point. | 807 "Limit to messages with the same `From:' field. |
876 With a prefix argument, prompt for the regular expression, REGEXP given to | 808 With a prefix argument, edit PICK-EXPR. |
877 pick." | 809 |
810 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." | |
878 (interactive | 811 (interactive |
879 (list (mh-read-pick-regexp (mh-current-message-header-field 'cc)))) | 812 (list (mh-edit-pick-expr (mh-current-message-header-field 'from)))) |
880 (mh-narrow-to-header-field 'cc regexp)) | 813 (mh-narrow-to-header-field 'from pick-expr)) |
881 | 814 |
882 ;;;###mh-autoload | 815 ;;;###mh-autoload |
883 (defun mh-narrow-to-to (&optional regexp) | 816 (defun mh-narrow-to-cc (&optional pick-expr) |
884 "Limit to messages with the same To header field as the message at point. | 817 "Limit to messages with the same `Cc:' field. |
885 With a prefix argument, prompt for the regular expression, REGEXP given to | 818 With a prefix argument, edit PICK-EXPR. |
886 pick." | 819 |
820 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." | |
887 (interactive | 821 (interactive |
888 (list (mh-read-pick-regexp (mh-current-message-header-field 'to)))) | 822 (list (mh-edit-pick-expr (mh-current-message-header-field 'cc)))) |
889 (mh-narrow-to-header-field 'to regexp)) | 823 (mh-narrow-to-header-field 'cc pick-expr)) |
890 | 824 |
891 (defun mh-narrow-to-header-field (header-field regexp) | 825 ;;;###mh-autoload |
892 "Limit to messages whose HEADER-FIELD match REGEXP. | 826 (defun mh-narrow-to-to (&optional pick-expr) |
827 "Limit to messages with the same `To:' field. | |
828 With a prefix argument, edit PICK-EXPR. | |
829 | |
830 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." | |
831 (interactive | |
832 (list (mh-edit-pick-expr (mh-current-message-header-field 'to)))) | |
833 (mh-narrow-to-header-field 'to pick-expr)) | |
834 | |
835 (defun mh-narrow-to-header-field (header-field pick-expr) | |
836 "Limit to messages whose HEADER-FIELD match PICK-EXPR. | |
893 The MH command pick is used to do the match." | 837 The MH command pick is used to do the match." |
894 (let ((folder mh-current-folder) | 838 (let ((folder mh-current-folder) |
895 (original (mh-coalesce-msg-list | 839 (original (mh-coalesce-msg-list |
896 (mh-range-to-msg-list (cons (point-min) (point-max))))) | 840 (mh-range-to-msg-list (cons (point-min) (point-max))))) |
897 (msg-list ())) | 841 (msg-list ())) |
898 (with-temp-buffer | 842 (with-temp-buffer |
899 (apply #'mh-exec-cmd-output "pick" nil folder | 843 (apply #'mh-exec-cmd-output "pick" nil folder |
900 (append original (list "-list") regexp)) | 844 (append original (list "-list") pick-expr)) |
901 (goto-char (point-min)) | 845 (goto-char (point-min)) |
902 (while (not (eobp)) | 846 (while (not (eobp)) |
903 (let ((num (read-from-string | 847 (let ((num (read-from-string |
904 (buffer-substring (point) (line-end-position))))) | 848 (buffer-substring (point) (line-end-position))))) |
905 (when (numberp (car num)) (push (car num) msg-list)) | 849 (when (numberp (car num)) (push (car num) msg-list)) |
937 ;;;###mh-autoload | 881 ;;;###mh-autoload |
938 (defun mh-narrow-to-range (range) | 882 (defun mh-narrow-to-range (range) |
939 "Limit to messages in RANGE. | 883 "Limit to messages in RANGE. |
940 | 884 |
941 Check the documentation of `mh-interactive-range' to see how RANGE is read in | 885 Check the documentation of `mh-interactive-range' to see how RANGE is read in |
942 interactive use." | 886 interactive use. |
887 | |
888 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." | |
943 (interactive (list (mh-interactive-range "Narrow to"))) | 889 (interactive (list (mh-interactive-range "Narrow to"))) |
944 (when (assoc 'range mh-seq-list) (mh-delete-seq 'range)) | 890 (when (assoc 'range mh-seq-list) (mh-delete-seq 'range)) |
945 (mh-add-msgs-to-seq (mh-range-to-msg-list range) 'range) | 891 (mh-add-msgs-to-seq (mh-range-to-msg-list range) 'range) |
946 (mh-narrow-to-seq 'range)) | 892 (mh-narrow-to-seq 'range)) |
947 | 893 |
956 (let ((count (mh-subject-to-sequence nil))) | 902 (let ((count (mh-subject-to-sequence nil))) |
957 (cond | 903 (cond |
958 ((not count) ; No subject line, delete msg anyway | 904 ((not count) ; No subject line, delete msg anyway |
959 (mh-delete-msg (mh-get-msg-num t))) | 905 (mh-delete-msg (mh-get-msg-num t))) |
960 ((= 0 count) ; No other msgs, delete msg anyway. | 906 ((= 0 count) ; No other msgs, delete msg anyway. |
961 (message "No other messages with same Subject following this one.") | 907 (message "No other messages with same Subject following this one") |
962 (mh-delete-msg (mh-get-msg-num t))) | 908 (mh-delete-msg (mh-get-msg-num t))) |
963 (t ; We have a subject sequence. | 909 (t ; We have a subject sequence. |
964 (message "Marked %d messages for deletion" count) | 910 (message "Marked %d messages for deletion" count) |
965 (mh-delete-msg 'subject))))) | 911 (mh-delete-msg 'subject))))) |
966 | 912 |
1076 (setf (mh-message-id message) id) | 1022 (setf (mh-message-id message) id) |
1077 (setf (mh-message-references message) refs) | 1023 (setf (mh-message-references message) refs) |
1078 message) | 1024 message) |
1079 (container | 1025 (container |
1080 (setf (mh-container-message container) | 1026 (setf (mh-container-message container) |
1081 (mh-thread-make-message :subject subject | 1027 (mh-thread-make-message :id id :references refs |
1082 :subject-re-p subject-re-p | 1028 :subject subject |
1083 :id id :references refs))) | 1029 :subject-re-p subject-re-p))) |
1084 (t (let ((message (mh-thread-make-message | 1030 (t (let ((message (mh-thread-make-message :id id :references refs |
1085 :subject subject | 1031 :subject-re-p subject-re-p |
1086 :subject-re-p subject-re-p | 1032 :subject subject))) |
1087 :id id :references refs))) | |
1088 (prog1 message | 1033 (prog1 message |
1089 (mh-thread-get-message-container message))))))) | 1034 (mh-thread-get-message-container message))))))) |
1090 | 1035 |
1091 (defsubst mh-thread-canonicalize-id (id) | 1036 (defsubst mh-thread-canonicalize-id (id) |
1092 "Produce canonical string representation for ID. | 1037 "Produce canonical string representation for ID. |
1448 MSG is the message being notated with NOTATION at OFFSET." | 1393 MSG is the message being notated with NOTATION at OFFSET." |
1449 (let* ((msg (or msg (mh-get-msg-num nil))) | 1394 (let* ((msg (or msg (mh-get-msg-num nil))) |
1450 (cur-scan-line (and mh-thread-scan-line-map | 1395 (cur-scan-line (and mh-thread-scan-line-map |
1451 (gethash msg mh-thread-scan-line-map))) | 1396 (gethash msg mh-thread-scan-line-map))) |
1452 (old-scan-lines (loop for map in mh-thread-scan-line-map-stack | 1397 (old-scan-lines (loop for map in mh-thread-scan-line-map-stack |
1453 collect (and map (gethash msg map)))) | 1398 collect (and map (gethash msg map))))) |
1454 (notation (if (stringp notation) (aref notation 0) notation))) | |
1455 (when cur-scan-line | 1399 (when cur-scan-line |
1456 (setf (aref (car cur-scan-line) offset) notation)) | 1400 (setf (aref (car cur-scan-line) offset) notation)) |
1457 (dolist (line old-scan-lines) | 1401 (dolist (line old-scan-lines) |
1458 (when line (setf (aref (car line) offset) notation))))) | 1402 (when line (setf (aref (car line) offset) notation))))) |
1459 | 1403 |
1484 do (let ((v (gethash msg old-map))) | 1428 do (let ((v (gethash msg old-map))) |
1485 (when v | 1429 (when v |
1486 (setf (gethash msg mh-thread-scan-line-map) v)))) | 1430 (setf (gethash msg mh-thread-scan-line-map) v)))) |
1487 (when (> (hash-table-count mh-thread-scan-line-map) 0) | 1431 (when (> (hash-table-count mh-thread-scan-line-map) 0) |
1488 (insert (if (bobp) "" "\n") (car x) "\n") | 1432 (insert (if (bobp) "" "\n") (car x) "\n") |
1489 (mh-thread-generate-scan-lines thread-tree -2))))))) | 1433 (mh-thread-generate-scan-lines thread-tree -2)))) |
1434 (mh-index-create-imenu-index)))) | |
1490 | 1435 |
1491 (defun mh-thread-folder () | 1436 (defun mh-thread-folder () |
1492 "Generate thread view of folder." | 1437 "Generate thread view of folder." |
1493 (message "Threading %s..." (buffer-name)) | 1438 (message "Threading %s..." (buffer-name)) |
1494 (mh-thread-initialize) | 1439 (mh-thread-initialize) |
1709 (mh-iterate-on-range msg range | 1654 (mh-iterate-on-range msg range |
1710 (cond ((member msg tick-seq-msgs) | 1655 (cond ((member msg tick-seq-msgs) |
1711 (push msg unticked) | 1656 (push msg unticked) |
1712 (setcdr tick-seq (delq msg (cdr tick-seq))) | 1657 (setcdr tick-seq (delq msg (cdr tick-seq))) |
1713 (when (null (cdr tick-seq)) (setq mh-last-seq-used nil)) | 1658 (when (null (cdr tick-seq)) (setq mh-last-seq-used nil)) |
1714 (mh-remove-sequence-notation msg t)) | 1659 (mh-remove-sequence-notation msg (mh-colors-in-use-p))) |
1715 (t | 1660 (t |
1716 (push msg ticked) | 1661 (push msg ticked) |
1717 (setq mh-last-seq-used mh-tick-seq) | 1662 (setq mh-last-seq-used mh-tick-seq) |
1718 (mh-add-sequence-notation msg t)))) | 1663 (let ((mh-seq-list (cons `(,mh-tick-seq ,msg) mh-seq-list))) |
1664 (mh-add-sequence-notation msg (mh-colors-in-use-p)))))) | |
1719 (mh-add-msgs-to-seq ticked mh-tick-seq nil t) | 1665 (mh-add-msgs-to-seq ticked mh-tick-seq nil t) |
1720 (mh-undefine-sequence mh-tick-seq unticked) | 1666 (mh-undefine-sequence mh-tick-seq unticked) |
1721 (when mh-index-data | 1667 (when mh-index-data |
1722 (mh-index-add-to-sequence mh-tick-seq ticked) | 1668 (mh-index-add-to-sequence mh-tick-seq ticked) |
1723 (mh-index-delete-from-sequence mh-tick-seq unticked)))) | 1669 (mh-index-delete-from-sequence mh-tick-seq unticked)))) |
1724 | 1670 |
1725 ;;;###mh-autoload | 1671 ;;;###mh-autoload |
1726 (defun mh-narrow-to-tick () | 1672 (defun mh-narrow-to-tick () |
1727 "Restrict display of this folder to just messages in `mh-tick-seq'. | 1673 "Limit to messages in `mh-tick-seq'. |
1674 | |
1728 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." | 1675 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." |
1729 (interactive) | 1676 (interactive) |
1730 (cond ((not mh-tick-seq) | 1677 (cond ((not mh-tick-seq) |
1731 (error "Enable ticking by customizing `mh-tick-seq'")) | 1678 (error "Enable ticking by customizing `mh-tick-seq'")) |
1732 ((null (mh-seq-msgs (mh-find-seq mh-tick-seq))) | 1679 ((null (mh-seq-msgs (mh-find-seq mh-tick-seq))) |
1733 (message "No messages in tick sequence")) | 1680 (message "No messages in %s sequence" mh-tick-seq)) |
1734 (t (mh-narrow-to-seq mh-tick-seq)))) | 1681 (t (mh-narrow-to-seq mh-tick-seq)))) |
1735 | |
1736 | 1682 |
1737 (provide 'mh-seq) | 1683 (provide 'mh-seq) |
1738 | 1684 |
1739 ;;; Local Variables: | 1685 ;;; Local Variables: |
1740 ;;; indent-tabs-mode: nil | 1686 ;;; indent-tabs-mode: nil |