Mercurial > emacs
comparison lisp/mh-e/mh-seq.el @ 67758:6b063593fdad
Follow Emacs coding conventions. Use default setting of
emacs-lisp-docstring-fill-column which is 65.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Fri, 23 Dec 2005 07:40:40 +0000 |
parents | 3a8785724cca |
children | 9c3504ae6060 |
comparison
equal
deleted
inserted
replaced
67757:488b4dbc7482 | 67758:6b063593fdad |
---|---|
120 "Table to look up message identifier from message index.") | 120 "Table to look up message identifier from message index.") |
121 (defvar mh-thread-scan-line-map nil | 121 (defvar mh-thread-scan-line-map nil |
122 "Map of message index to various parts of the scan line.") | 122 "Map of message index to various parts of the scan line.") |
123 (defvar mh-thread-scan-line-map-stack nil | 123 (defvar mh-thread-scan-line-map-stack nil |
124 "Old map of message index to various parts of the scan line. | 124 "Old map of message index to various parts of the scan line. |
125 This is the original map that is stored when the folder is narrowed.") | 125 This is the original map that is stored when the folder is |
126 narrowed.") | |
126 (defvar mh-thread-subject-container-hash nil | 127 (defvar mh-thread-subject-container-hash nil |
127 "Hashtable used to group messages by subject.") | 128 "Hashtable used to group messages by subject.") |
128 (defvar mh-thread-duplicates nil | 129 (defvar mh-thread-duplicates nil |
129 "Hashtable used to associate messages with the same message identifier.") | 130 "Hashtable used to associate messages with the same message identifier.") |
130 (defvar mh-thread-history () | 131 (defvar mh-thread-history () |
131 "Variable to remember the transformations to the thread tree. | 132 "Variable to remember the transformations to the thread tree. |
132 When new messages are added, these transformations are rewound, then the | 133 When new messages are added, these transformations are rewound, |
133 links are added from the newly seen messages. Finally the transformations are | 134 then the links are added from the newly seen messages. Finally |
134 redone to get the new thread tree. This makes incremental threading easier.") | 135 the transformations are redone to get the new thread tree. This |
136 makes incremental threading easier.") | |
135 (defvar mh-thread-body-width nil | 137 (defvar mh-thread-body-width nil |
136 "Width of scan substring that contains subject and body of message.") | 138 "Width of scan substring that contains subject and body of message.") |
137 | 139 |
138 (make-variable-buffer-local 'mh-thread-id-hash) | 140 (make-variable-buffer-local 'mh-thread-id-hash) |
139 (make-variable-buffer-local 'mh-thread-subject-hash) | 141 (make-variable-buffer-local 'mh-thread-subject-hash) |
148 | 150 |
149 ;;;###mh-autoload | 151 ;;;###mh-autoload |
150 (defun mh-delete-seq (sequence) | 152 (defun mh-delete-seq (sequence) |
151 "Delete SEQUENCE. | 153 "Delete SEQUENCE. |
152 | 154 |
153 You are prompted for the sequence to delete. Note that this deletes only the | 155 You are prompted for the sequence to delete. Note that this |
154 sequence, not the messages in the sequence. If you want to delete the | 156 deletes only the sequence, not the messages in the sequence. If |
155 messages, use \"\\[universal-argument] \\[mh-delete-msg]\"." | 157 you want to delete the messages, use \"\\[universal-argument] |
158 \\[mh-delete-msg]\"." | |
156 (interactive (list (mh-read-seq-default "Delete" t))) | 159 (interactive (list (mh-read-seq-default "Delete" t))) |
157 (let ((msg-list (mh-seq-to-msgs sequence)) | 160 (let ((msg-list (mh-seq-to-msgs sequence)) |
158 (internal-flag (mh-internal-seq sequence)) | 161 (internal-flag (mh-internal-seq sequence)) |
159 (folders-changed (list mh-current-folder))) | 162 (folders-changed (list mh-current-folder))) |
160 (mh-iterate-on-range msg sequence | 163 (mh-iterate-on-range msg sequence |
214 (message "Listing sequences...done"))))) | 217 (message "Listing sequences...done"))))) |
215 | 218 |
216 ;;;###mh-autoload | 219 ;;;###mh-autoload |
217 (defun mh-msg-is-in-seq (message) | 220 (defun mh-msg-is-in-seq (message) |
218 "Display the sequences in which the current message appears. | 221 "Display the sequences in which the current message appears. |
219 Use a prefix argument to display the sequences in which another MESSAGE | 222 Use a prefix argument to display the sequences in which another |
220 appears." | 223 MESSAGE appears." |
221 (interactive "P") | 224 (interactive "P") |
222 (if (not message) | 225 (if (not message) |
223 (setq message (mh-get-msg-num t))) | 226 (setq message (mh-get-msg-num t))) |
224 (let* ((dest-folder (loop for seq in mh-refile-list | 227 (let* ((dest-folder (loop for seq in mh-refile-list |
225 when (member message (cdr seq)) return (car seq) | 228 when (member message (cdr seq)) return (car seq) |
241 | 244 |
242 ;;;###mh-autoload | 245 ;;;###mh-autoload |
243 (defun mh-narrow-to-seq (sequence) | 246 (defun mh-narrow-to-seq (sequence) |
244 "Restrict display to messages in SEQUENCE. | 247 "Restrict display to messages in SEQUENCE. |
245 | 248 |
246 You are prompted for the name of the sequence. What this command does is show | 249 You are prompted for the name of the sequence. What this command |
247 only those messages that are in the selected sequence in the MH-Folder buffer. | 250 does is show only those messages that are in the selected |
248 In addition, it limits further MH-E searches to just those messages. | 251 sequence in the MH-Folder buffer. In addition, it limits further |
249 | 252 MH-E searches to just those messages. |
250 When you want to widen the view to all your messages again, use \\[mh-widen]." | 253 |
254 When you want to widen the view to all your messages again, use | |
255 \\[mh-widen]." | |
251 (interactive (list (mh-read-seq "Narrow to" t))) | 256 (interactive (list (mh-read-seq "Narrow to" t))) |
252 (with-mh-folder-updating (t) | 257 (with-mh-folder-updating (t) |
253 (cond ((mh-seq-to-msgs sequence) | 258 (cond ((mh-seq-to-msgs sequence) |
254 (mh-remove-all-notation) | 259 (mh-remove-all-notation) |
255 (let ((eob (point-max)) | 260 (let ((eob (point-max)) |
281 | 286 |
282 ;;;###mh-autoload | 287 ;;;###mh-autoload |
283 (defun mh-put-msg-in-seq (range sequence) | 288 (defun mh-put-msg-in-seq (range sequence) |
284 "Add RANGE to SEQUENCE\\<mh-folder-mode-map>. | 289 "Add RANGE to SEQUENCE\\<mh-folder-mode-map>. |
285 | 290 |
286 To place a message in a sequence, use this command to do it manually, or use | 291 To place a message in a sequence, use this command to do it |
287 the MH command \"pick\" or the MH-E version of \"pick\", \\[mh-search-folder], | 292 manually, or use the MH command \"pick\" or the MH-E version of |
288 which create a sequence automatically. | 293 \"pick\", \\[mh-search-folder], which create a sequence |
289 | 294 automatically. |
290 Give this command a RANGE and you can add all the messages in a sequence to | 295 |
291 another sequence (for example, \"\\[universal-argument] \\[mh-put-msg-in-seq] | 296 Give this command a RANGE and you can add all the messages in a |
292 SourceSequence RET DestSequence RET\"). Check the documentation of | 297 sequence to another sequence (for example, |
293 `mh-interactive-range' to see how RANGE is read in interactive use." | 298 \"\\[universal-argument] \\[mh-put-msg-in-seq] SourceSequence RET |
299 DestSequence RET\"). Check the documentation of | |
300 `mh-interactive-range' to see how RANGE is read in interactive | |
301 use." | |
294 (interactive (list (mh-interactive-range "Add messages from") | 302 (interactive (list (mh-interactive-range "Add messages from") |
295 (mh-read-seq-default "Add to" nil))) | 303 (mh-read-seq-default "Add to" nil))) |
296 (unless (mh-valid-seq-p sequence) | 304 (unless (mh-valid-seq-p sequence) |
297 (error "Can't put message in invalid sequence `%s'" sequence)) | 305 (error "Can't put message in invalid sequence `%s'" sequence)) |
298 (let* ((internal-seq-flag (mh-internal-seq sequence)) | 306 (let* ((internal-seq-flag (mh-internal-seq sequence)) |
319 (t nil))) | 327 (t nil))) |
320 | 328 |
321 ;;;###mh-autoload | 329 ;;;###mh-autoload |
322 (defun mh-widen (&optional all-flag) | 330 (defun mh-widen (&optional all-flag) |
323 "Remove last restriction. | 331 "Remove last restriction. |
324 If optional prefix argument ALL-FLAG is non-nil, remove all limits." | 332 If optional prefix argument ALL-FLAG is non-nil, remove all |
333 limits." | |
325 (interactive "P") | 334 (interactive "P") |
326 (let ((msg (mh-get-msg-num nil))) | 335 (let ((msg (mh-get-msg-num nil))) |
327 (when mh-folder-view-stack | 336 (when mh-folder-view-stack |
328 (cond (all-flag | 337 (cond (all-flag |
329 (while (cdr mh-view-ops) | 338 (while (cdr mh-view-ops) |
366 ;; FIXME? We may want to clear all notations and add one for current-message | 375 ;; FIXME? We may want to clear all notations and add one for current-message |
367 ;; and process user sequences. | 376 ;; and process user sequences. |
368 ;;;###mh-autoload | 377 ;;;###mh-autoload |
369 (defun mh-notate-deleted-and-refiled () | 378 (defun mh-notate-deleted-and-refiled () |
370 "Notate messages marked for deletion or refiling. | 379 "Notate messages marked for deletion or refiling. |
371 Messages to be deleted are given by `mh-delete-list' while messages to be | 380 Messages to be deleted are given by `mh-delete-list' while |
372 refiled are present in `mh-refile-list'." | 381 messages to be refiled are present in `mh-refile-list'." |
373 (let ((refiled-hash (make-hash-table)) | 382 (let ((refiled-hash (make-hash-table)) |
374 (deleted-hash (make-hash-table))) | 383 (deleted-hash (make-hash-table))) |
375 (dolist (msg mh-delete-list) | 384 (dolist (msg mh-delete-list) |
376 (setf (gethash msg deleted-hash) t)) | 385 (setf (gethash msg deleted-hash) t)) |
377 (dolist (dest-msg-list mh-refile-list) | 386 (dolist (dest-msg-list mh-refile-list) |
393 (defvar mh-sequence-history ()) | 402 (defvar mh-sequence-history ()) |
394 | 403 |
395 ;;;###mh-autoload | 404 ;;;###mh-autoload |
396 (defun mh-read-seq-default (prompt not-empty) | 405 (defun mh-read-seq-default (prompt not-empty) |
397 "Read and return sequence name with default narrowed or previous sequence. | 406 "Read and return sequence name with default narrowed or previous sequence. |
398 PROMPT is the prompt to use when reading. If NOT-EMPTY is non-nil then a | 407 PROMPT is the prompt to use when reading. If NOT-EMPTY is non-nil |
399 non-empty sequence is read." | 408 then a non-empty sequence is read." |
400 (mh-read-seq prompt not-empty | 409 (mh-read-seq prompt not-empty |
401 (or mh-last-seq-used | 410 (or mh-last-seq-used |
402 (car (mh-seq-containing-msg (mh-get-msg-num nil) nil))))) | 411 (car (mh-seq-containing-msg (mh-get-msg-num nil) nil))))) |
403 | 412 |
404 (defun mh-read-seq (prompt not-empty &optional default) | 413 (defun mh-read-seq (prompt not-empty &optional default) |
405 "Read and return a sequence name. | 414 "Read and return a sequence name. |
406 Prompt with PROMPT, raise an error if the sequence is empty and the NOT-EMPTY | 415 Prompt with PROMPT, raise an error if the sequence is empty and |
407 flag is non-nil, and supply an optional DEFAULT sequence. A reply of '%' | 416 the NOT-EMPTY flag is non-nil, and supply an optional DEFAULT |
408 defaults to the first sequence containing the current message." | 417 sequence. A reply of '%' defaults to the first sequence |
418 containing the current message." | |
409 (let* ((input (completing-read (format "%s %s %s" prompt "sequence:" | 419 (let* ((input (completing-read (format "%s %s %s" prompt "sequence:" |
410 (if default | 420 (if default |
411 (format "[%s] " default) | 421 (format "[%s] " default) |
412 "")) | 422 "")) |
413 (mh-seq-names mh-seq-list) | 423 (mh-seq-names mh-seq-list) |
457 ;;;###mh-autoload | 467 ;;;###mh-autoload |
458 (defun mh-read-range (prompt &optional folder default | 468 (defun mh-read-range (prompt &optional folder default |
459 expand-flag ask-flag number-as-range-flag) | 469 expand-flag ask-flag number-as-range-flag) |
460 "Read a message range with PROMPT. | 470 "Read a message range with PROMPT. |
461 | 471 |
462 If FOLDER is non-nil then a range is read from that folder, otherwise use | 472 If FOLDER is non-nil then a range is read from that folder, otherwise |
463 `mh-current-folder'. | 473 use `mh-current-folder'. |
464 | 474 |
465 If DEFAULT is a string then use that as default range to return. If DEFAULT is | 475 If DEFAULT is a string then use that as default range to return. If |
466 nil then ask user with default answer a range based on the sequences that seem | 476 DEFAULT is nil then ask user with default answer a range based on the |
467 relevant. Finally if DEFAULT is t, try to avoid prompting the user. Unseen | 477 sequences that seem relevant. Finally if DEFAULT is t, try to avoid |
468 messages, if present, are returned. If the folder has fewer than | 478 prompting the user. Unseen messages, if present, are returned. If the |
469 `mh-large-folder' messages then \"all\" messages are returned. Finally as a | 479 folder has fewer than `mh-large-folder' messages then \"all\" messages |
470 last resort prompt the user. | 480 are returned. Finally as a last resort prompt the user. |
471 | 481 |
472 If EXPAND-FLAG is non-nil then a list of message numbers corresponding to the | 482 If EXPAND-FLAG is non-nil then a list of message numbers corresponding |
473 input is returned. If this list is empty then an error is raised. If | 483 to the input is returned. If this list is empty then an error is |
474 EXPAND-FLAG is nil just return the input string. In this case we don't check | 484 raised. If EXPAND-FLAG is nil just return the input string. In this |
475 if the range is empty. | 485 case we don't check if the range is empty. |
476 | 486 |
477 If ASK-FLAG is non-nil, then the user is always queried for a range of | 487 If ASK-FLAG is non-nil, then the user is always queried for a range of |
478 messages. If ASK-FLAG is nil, then the function checks if the unseen sequence | 488 messages. If ASK-FLAG is nil, then the function checks if the unseen |
479 is non-empty. If that is the case, `mh-unseen-seq', or the list of messages in | 489 sequence is non-empty. If that is the case, `mh-unseen-seq', or the |
480 it depending on the value of EXPAND, is returned. Otherwise if the folder has | 490 list of messages in it depending on the value of EXPAND, is returned. |
481 fewer than `mh-large-folder' messages then the list of messages corresponding | 491 Otherwise if the folder has fewer than `mh-large-folder' messages then |
482 to \"all\" is returned. If neither of the above holds then as a last resort | 492 the list of messages corresponding to \"all\" is returned. If neither |
483 the user is queried for a range of messages. | 493 of the above holds then as a last resort the user is queried for a |
484 | 494 range of messages. |
485 If NUMBER-AS-RANGE-FLAG is non-nil, then if a number, N is read as input, it | 495 |
486 is interpreted as the range \"last:N\". | 496 If NUMBER-AS-RANGE-FLAG is non-nil, then if a number, N is read as |
487 | 497 input, it is interpreted as the range \"last:N\". |
488 This function replaces the existing function `mh-read-msg-range'. Calls to: | 498 |
499 This function replaces the existing function `mh-read-msg-range'. | |
500 Calls to: | |
501 | |
489 (mh-read-msg-range folder flag) | 502 (mh-read-msg-range folder flag) |
503 | |
490 should be replaced with: | 504 should be replaced with: |
505 | |
491 (mh-read-range \"Suitable prompt\" folder t nil flag | 506 (mh-read-range \"Suitable prompt\" folder t nil flag |
492 mh-interpret-number-as-range-flag)" | 507 mh-interpret-number-as-range-flag)" |
493 (setq default (or default mh-last-seq-used | 508 (setq default (or default mh-last-seq-used |
494 (car (mh-seq-containing-msg (mh-get-msg-num nil) t))) | 509 (car (mh-seq-containing-msg (mh-get-msg-num nil) t))) |
495 prompt (format "%s range" prompt)) | 510 prompt (format "%s range" prompt)) |
563 (rplaca old-seq new-name))) | 578 (rplaca old-seq new-name))) |
564 | 579 |
565 ;;;###mh-autoload | 580 ;;;###mh-autoload |
566 (defun mh-notate-cur () | 581 (defun mh-notate-cur () |
567 "Mark the MH sequence cur. | 582 "Mark the MH sequence cur. |
568 In addition to notating the current message with `mh-note-cur' the function | 583 In addition to notating the current message with `mh-note-cur' |
569 uses `overlay-arrow-position' to put a marker in the fringe." | 584 the function uses `overlay-arrow-position' to put a marker in the |
585 fringe." | |
570 (let ((cur (car (mh-seq-to-msgs 'cur)))) | 586 (let ((cur (car (mh-seq-to-msgs 'cur)))) |
571 (when (and cur (mh-goto-msg cur t t)) | 587 (when (and cur (mh-goto-msg cur t t)) |
572 (beginning-of-line) | 588 (beginning-of-line) |
573 (when (looking-at mh-scan-good-msg-regexp) | 589 (when (looking-at mh-scan-good-msg-regexp) |
574 (mh-notate nil mh-note-cur mh-cmd-note)) | 590 (mh-notate nil mh-note-cur mh-cmd-note)) |
615 (mh-index-insert-folder-headers))))))) | 631 (mh-index-insert-folder-headers))))))) |
616 | 632 |
617 ;;;###mh-autoload | 633 ;;;###mh-autoload |
618 (defmacro mh-iterate-on-messages-in-region (var begin end &rest body) | 634 (defmacro mh-iterate-on-messages-in-region (var begin end &rest body) |
619 "Iterate over region. | 635 "Iterate over region. |
620 VAR is bound to the message on the current line as we loop starting from BEGIN | 636 |
621 till END. In each step BODY is executed. | 637 VAR is bound to the message on the current line as we loop |
638 starting from BEGIN till END. In each step BODY is executed. | |
622 | 639 |
623 If VAR is nil then the loop is executed without any binding." | 640 If VAR is nil then the loop is executed without any binding." |
624 (unless (symbolp var) | 641 (unless (symbolp var) |
625 (error "Can not bind the non-symbol %s" var)) | 642 (error "Can not bind the non-symbol %s" var)) |
626 (let ((binding-needed-flag var)) | 643 (let ((binding-needed-flag var)) |
637 | 654 |
638 ;;;###mh-autoload | 655 ;;;###mh-autoload |
639 (defmacro mh-iterate-on-range (var range &rest body) | 656 (defmacro mh-iterate-on-range (var range &rest body) |
640 "Iterate an operation over a region or sequence. | 657 "Iterate an operation over a region or sequence. |
641 | 658 |
642 VAR is bound to each message in turn in a loop over RANGE, which can be a | 659 VAR is bound to each message in turn in a loop over RANGE, which |
643 message number, a list of message numbers, a sequence, a region in a cons | 660 can be a message number, a list of message numbers, a sequence, a |
644 cell, or a MH range (something like last:20) in a string. In each iteration, | 661 region in a cons cell, or a MH range (something like last:20) in |
645 BODY is executed. | 662 a string. In each iteration, BODY is executed. |
646 | 663 |
647 The parameter RANGE is usually created with `mh-interactive-range' | 664 The parameter RANGE is usually created with |
648 in order to provide a uniform interface to MH-E functions." | 665 `mh-interactive-range' in order to provide a uniform interface to |
666 MH-E functions." | |
649 (unless (symbolp var) | 667 (unless (symbolp var) |
650 (error "Can not bind the non-symbol %s" var)) | 668 (error "Can not bind the non-symbol %s" var)) |
651 (let ((binding-needed-flag var) | 669 (let ((binding-needed-flag var) |
652 (msgs (make-symbol "msgs")) | 670 (msgs (make-symbol "msgs")) |
653 (seq-hash-table (make-symbol "seq-hash-table"))) | 671 (seq-hash-table (make-symbol "seq-hash-table"))) |
678 | 696 |
679 ;;;###mh-autoload | 697 ;;;###mh-autoload |
680 (defun mh-range-to-msg-list (range) | 698 (defun mh-range-to-msg-list (range) |
681 "Return a list of messages for RANGE. | 699 "Return a list of messages for RANGE. |
682 | 700 |
683 Check the documentation of `mh-interactive-range' to see how RANGE is read in | 701 Check the documentation of `mh-interactive-range' to see how |
684 interactive use." | 702 RANGE is read in interactive use." |
685 (let (msg-list) | 703 (let (msg-list) |
686 (mh-iterate-on-range msg range | 704 (mh-iterate-on-range msg range |
687 (push msg msg-list)) | 705 (push msg msg-list)) |
688 (nreverse msg-list))) | 706 (nreverse msg-list))) |
689 | 707 |
690 ;;;###mh-autoload | 708 ;;;###mh-autoload |
691 (defun mh-interactive-range (range-prompt &optional default) | 709 (defun mh-interactive-range (range-prompt &optional default) |
692 "Return interactive specification for message, sequence, range or region. | 710 "Return interactive specification for message, sequence, range or region. |
693 By convention, the name of this argument is RANGE. | 711 By convention, the name of this argument is RANGE. |
694 | 712 |
695 If variable `transient-mark-mode' is non-nil and the mark is active, then this | 713 If variable `transient-mark-mode' is non-nil and the mark is active, |
696 function returns a cons-cell of the region. | 714 then this function returns a cons-cell of the region. |
697 | 715 |
698 If optional prefix argument is provided, then prompt for message range with | 716 If optional prefix argument is provided, then prompt for message range |
699 RANGE-PROMPT. A list of messages in that range is returned. | 717 with RANGE-PROMPT. A list of messages in that range is returned. |
700 | 718 |
701 If a MH range is given, say something like last:20, then a list containing | 719 If a MH range is given, say something like last:20, then a list |
702 the messages in that range is returned. | 720 containing the messages in that range is returned. |
703 | 721 |
704 If DEFAULT non-nil then it is returned. | 722 If DEFAULT non-nil then it is returned. |
705 | 723 |
706 Otherwise, the message number at point is returned. | 724 Otherwise, the message number at point is returned. |
707 | 725 |
708 This function is usually used with `mh-iterate-on-range' in order to provide | 726 This function is usually used with `mh-iterate-on-range' in order to |
709 a uniform interface to MH-E functions." | 727 provide a uniform interface to MH-E functions." |
710 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end))) | 728 (cond ((mh-mark-active-p t) (cons (region-beginning) (region-end))) |
711 (current-prefix-arg (mh-read-range range-prompt nil nil t t)) | 729 (current-prefix-arg (mh-read-range range-prompt nil nil t t)) |
712 (default default) | 730 (default default) |
713 (t (mh-get-msg-num t)))) | 731 (t (mh-get-msg-num t)))) |
714 | 732 |
718 | 736 |
719 ;; XXX: The function mh-subject-to-sequence-unthreaded uses the magic number | 737 ;; XXX: The function mh-subject-to-sequence-unthreaded uses the magic number |
720 ;; 41 for the max size of the subject part. Avoiding this would be desirable. | 738 ;; 41 for the max size of the subject part. Avoiding this would be desirable. |
721 (defun mh-subject-to-sequence (all) | 739 (defun mh-subject-to-sequence (all) |
722 "Put all following messages with same subject in sequence 'subject. | 740 "Put all following messages with same subject in sequence 'subject. |
723 If arg ALL is t, move to beginning of folder buffer to collect all messages. | 741 If arg ALL is t, move to beginning of folder buffer to collect all |
742 messages. | |
724 If arg ALL is nil, collect only messages fron current one on forward. | 743 If arg ALL is nil, collect only messages fron current one on forward. |
725 | 744 |
726 Return number of messages put in the sequence: | 745 Return number of messages put in the sequence: |
727 | 746 |
728 nil -> there was no subject line. | 747 nil -> there was no subject line. |
729 0 -> there were no later messages with the same subject (sequence not made) | 748 |
749 0 -> there were no later messages with the same | |
750 subject (sequence not made) | |
751 | |
730 >1 -> the total number of messages including current one." | 752 >1 -> the total number of messages including current one." |
731 (if (memq 'unthread mh-view-ops) | 753 (if (memq 'unthread mh-view-ops) |
732 (mh-subject-to-sequence-threaded all) | 754 (mh-subject-to-sequence-threaded all) |
733 (mh-subject-to-sequence-unthreaded all))) | 755 (mh-subject-to-sequence-unthreaded all))) |
734 | 756 |
735 (defun mh-subject-to-sequence-unthreaded (all) | 757 (defun mh-subject-to-sequence-unthreaded (all) |
736 "Put all following messages with same subject in sequence 'subject. | 758 "Put all following messages with same subject in sequence 'subject. |
737 This function only works with an unthreaded folder. If arg ALL is t, move to | 759 |
738 beginning of folder buffer to collect all messages. If arg ALL is nil, collect | 760 This function only works with an unthreaded folder. If arg ALL is |
739 only messages fron current one on forward. | 761 t, move to beginning of folder buffer to collect all messages. If |
762 arg ALL is nil, collect only messages fron current one on | |
763 forward. | |
740 | 764 |
741 Return number of messages put in the sequence: | 765 Return number of messages put in the sequence: |
742 | 766 |
743 nil -> there was no subject line. | 767 nil -> there was no subject line. |
744 0 -> there were no later messages with the same subject (sequence not made) | 768 0 -> there were no later messages with the same |
769 subject (sequence not made) | |
745 >1 -> the total number of messages including current one." | 770 >1 -> the total number of messages including current one." |
746 (if (not (eq major-mode 'mh-folder-mode)) | 771 (if (not (eq major-mode 'mh-folder-mode)) |
747 (error "Not in a folder buffer")) | 772 (error "Not in a folder buffer")) |
748 (save-excursion | 773 (save-excursion |
749 (beginning-of-line) | 774 (beginning-of-line) |
780 (t | 805 (t |
781 0)))))) | 806 0)))))) |
782 | 807 |
783 (defun mh-subject-to-sequence-threaded (all) | 808 (defun mh-subject-to-sequence-threaded (all) |
784 "Put all messages with the same subject in the 'subject sequence. | 809 "Put all messages with the same subject in the 'subject sequence. |
785 This function works when the folder is threaded. In this situation the subject | 810 |
786 could get truncated and so the normal matching doesn't work. | 811 This function works when the folder is threaded. In this |
787 | 812 situation the subject could get truncated and so the normal |
788 The parameter ALL is non-nil then all the messages in the buffer are | 813 matching doesn't work. |
789 considered, otherwise only the messages after the current one are taken into | 814 |
790 account." | 815 The parameter ALL is non-nil then all the messages in the buffer |
816 are considered, otherwise only the messages after the current one | |
817 are taken into account." | |
791 (let* ((cur (mh-get-msg-num nil)) | 818 (let* ((cur (mh-get-msg-num nil)) |
792 (subject (mh-thread-find-msg-subject cur)) | 819 (subject (mh-thread-find-msg-subject cur)) |
793 region msgs) | 820 region msgs) |
794 (if (null subject) | 821 (if (null subject) |
795 (and (message "No subject line") nil) | 822 (and (message "No subject line") nil) |
822 default-string)) | 849 default-string)) |
823 default))) | 850 default))) |
824 | 851 |
825 (defun mh-pick-args-list (s) | 852 (defun mh-pick-args-list (s) |
826 "Form list by grouping elements in string S suitable for pick arguments. | 853 "Form list by grouping elements in string S suitable for pick arguments. |
827 For example, the string \"-subject a b c -from Joe User <user@domain.com>\" | 854 For example, the string \"-subject a b c -from Joe User |
828 is converted to (\"-subject\" \"a b c\" \"-from\" | 855 <user@domain.com>\" is converted to (\"-subject\" \"a b c\" |
829 \"Joe User <user@domain.com>\"" | 856 \"-from\" \"Joe User <user@domain.com>\"" |
830 (let ((full-list (split-string s)) | 857 (let ((full-list (split-string s)) |
831 current-arg collection arg-list) | 858 current-arg collection arg-list) |
832 (while full-list | 859 (while full-list |
833 (setq current-arg (car full-list)) | 860 (setq current-arg (car full-list)) |
834 (if (null (string-match "^-" current-arg)) | 861 (if (null (string-match "^-" current-arg)) |
933 | 960 |
934 ;;;###mh-autoload | 961 ;;;###mh-autoload |
935 (defun mh-narrow-to-range (range) | 962 (defun mh-narrow-to-range (range) |
936 "Limit to RANGE. | 963 "Limit to RANGE. |
937 | 964 |
938 Check the documentation of `mh-interactive-range' to see how RANGE is read in | 965 Check the documentation of `mh-interactive-range' to see how |
939 interactive use. | 966 RANGE is read in interactive use. |
940 | 967 |
941 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." | 968 Use \\<mh-folder-mode-map>\\[mh-widen] to undo this command." |
942 (interactive (list (mh-interactive-range "Narrow to"))) | 969 (interactive (list (mh-interactive-range "Narrow to"))) |
943 (when (assoc 'range mh-seq-list) (mh-delete-seq 'range)) | 970 (when (assoc 'range mh-seq-list) (mh-delete-seq 'range)) |
944 (mh-add-msgs-to-seq (mh-range-to-msg-list range) 'range) | 971 (mh-add-msgs-to-seq (mh-range-to-msg-list range) 'range) |
947 | 974 |
948 ;;;###mh-autoload | 975 ;;;###mh-autoload |
949 (defun mh-delete-subject () | 976 (defun mh-delete-subject () |
950 "Delete messages with same subject\\<mh-folder-mode-map>. | 977 "Delete messages with same subject\\<mh-folder-mode-map>. |
951 | 978 |
952 To delete messages faster, you can use this command to delete all the messages | 979 To delete messages faster, you can use this command to delete all |
953 with the same subject as the current message. This command puts these messages | 980 the messages with the same subject as the current message. This |
954 in a sequence named \"subject\". You can undo this action by using \\[mh-undo] | 981 command puts these messages in a sequence named \"subject\". You |
955 with a prefix argument and then specifying the \"subject\" sequence." | 982 can undo this action by using \\[mh-undo] with a prefix argument |
983 and then specifying the \"subject\" sequence." | |
956 (interactive) | 984 (interactive) |
957 (let ((count (mh-subject-to-sequence nil))) | 985 (let ((count (mh-subject-to-sequence nil))) |
958 (cond | 986 (cond |
959 ((not count) ; No subject line, delete msg anyway | 987 ((not count) ; No subject line, delete msg anyway |
960 (mh-delete-msg (mh-get-msg-num t))) | 988 (mh-delete-msg (mh-get-msg-num t))) |
967 | 995 |
968 ;;;###mh-autoload | 996 ;;;###mh-autoload |
969 (defun mh-delete-subject-or-thread () | 997 (defun mh-delete-subject-or-thread () |
970 "Delete messages with same subject or thread\\<mh-folder-mode-map>. | 998 "Delete messages with same subject or thread\\<mh-folder-mode-map>. |
971 | 999 |
972 To delete messages faster, you can use this command to delete all the messages | 1000 To delete messages faster, you can use this command to delete all |
973 with the same subject as the current message. This command puts these messages | 1001 the messages with the same subject as the current message. This |
974 in a sequence named \"subject\". You can undo this action by using \\[mh-undo] | 1002 command puts these messages in a sequence named \"subject\". You |
975 with a prefix argument and then specifying the \"subject\" sequence. | 1003 can undo this action by using \\[mh-undo] with a prefix argument |
976 | 1004 and then specifying the \"subject\" sequence. |
977 However, if the buffer is displaying a threaded view of the folder then this | 1005 |
978 command behaves like \\[mh-thread-delete]." | 1006 However, if the buffer is displaying a threaded view of the |
1007 folder then this command behaves like \\[mh-thread-delete]." | |
979 (interactive) | 1008 (interactive) |
980 (if (memq 'unthread mh-view-ops) | 1009 (if (memq 'unthread mh-view-ops) |
981 (mh-thread-delete) | 1010 (mh-thread-delete) |
982 (mh-delete-subject))) | 1011 (mh-delete-subject))) |
983 | 1012 |
1003 (mh-thread-initialize-hash mh-thread-duplicates #'eq) | 1032 (mh-thread-initialize-hash mh-thread-duplicates #'eq) |
1004 (setq mh-thread-history ())) | 1033 (setq mh-thread-history ())) |
1005 | 1034 |
1006 (defsubst mh-thread-id-container (id) | 1035 (defsubst mh-thread-id-container (id) |
1007 "Given ID, return the corresponding container in `mh-thread-id-table'. | 1036 "Given ID, return the corresponding container in `mh-thread-id-table'. |
1008 If no container exists then a suitable container is created and the id-table | 1037 If no container exists then a suitable container is created and |
1009 is updated." | 1038 the id-table is updated." |
1010 (when (not id) | 1039 (when (not id) |
1011 (error "1")) | 1040 (error "1")) |
1012 (or (gethash id mh-thread-id-table) | 1041 (or (gethash id mh-thread-id-table) |
1013 (setf (gethash id mh-thread-id-table) | 1042 (setf (gethash id mh-thread-id-table) |
1014 (let ((message (mh-thread-make-message :id id))) | 1043 (let ((message (mh-thread-make-message :id id))) |
1025 unless (eq child-container elem) collect elem)) | 1054 unless (eq child-container elem) collect elem)) |
1026 (setf (mh-container-parent child-container) nil)))) | 1055 (setf (mh-container-parent child-container) nil)))) |
1027 | 1056 |
1028 (defsubst mh-thread-add-link (parent child &optional at-end-p) | 1057 (defsubst mh-thread-add-link (parent child &optional at-end-p) |
1029 "Add links so that PARENT becomes a parent of CHILD. | 1058 "Add links so that PARENT becomes a parent of CHILD. |
1030 Doesn't make any changes if CHILD is already an ancestor of PARENT. If | 1059 Doesn't make any changes if CHILD is already an ancestor of |
1031 optional argument AT-END-P is non-nil, the CHILD is added to the end of the | 1060 PARENT. If optional argument AT-END-P is non-nil, the CHILD is |
1032 children list of PARENT." | 1061 added to the end of the children list of PARENT." |
1033 (let ((parent-container (cond ((null parent) nil) | 1062 (let ((parent-container (cond ((null parent) nil) |
1034 ((mh-thread-container-p parent) parent) | 1063 ((mh-thread-container-p parent) parent) |
1035 (t (mh-thread-id-container parent)))) | 1064 (t (mh-thread-id-container parent)))) |
1036 (child-container (if (mh-thread-container-p child) | 1065 (child-container (if (mh-thread-container-p child) |
1037 child (mh-thread-id-container child)))) | 1066 child (mh-thread-id-container child)))) |
1051 (unless parent-container | 1080 (unless parent-container |
1052 (mh-thread-remove-parent-link child-container)))) | 1081 (mh-thread-remove-parent-link child-container)))) |
1053 | 1082 |
1054 (defun mh-thread-ancestor-p (ancestor successor) | 1083 (defun mh-thread-ancestor-p (ancestor successor) |
1055 "Return t if ANCESTOR is really an ancestor of SUCCESSOR and nil otherwise. | 1084 "Return t if ANCESTOR is really an ancestor of SUCCESSOR and nil otherwise. |
1056 In the limit, the function returns t if ANCESTOR and SUCCESSOR are the same | 1085 In the limit, the function returns t if ANCESTOR and SUCCESSOR |
1057 containers." | 1086 are the same containers." |
1058 (block nil | 1087 (block nil |
1059 (while successor | 1088 (while successor |
1060 (when (eq ancestor successor) (return t)) | 1089 (when (eq ancestor successor) (return t)) |
1061 (setq successor (mh-container-parent successor))) | 1090 (setq successor (mh-container-parent successor))) |
1062 nil)) | 1091 nil)) |
1063 | 1092 |
1064 (defsubst mh-thread-get-message-container (message) | 1093 (defsubst mh-thread-get-message-container (message) |
1065 "Return container which has MESSAGE in it. | 1094 "Return container which has MESSAGE in it. |
1066 If there is no container present then a new container is allocated." | 1095 If there is no container present then a new container is |
1096 allocated." | |
1067 (let* ((id (mh-message-id message)) | 1097 (let* ((id (mh-message-id message)) |
1068 (container (gethash id mh-thread-id-table))) | 1098 (container (gethash id mh-thread-id-table))) |
1069 (cond (container (setf (mh-container-message container) message) | 1099 (cond (container (setf (mh-container-message container) message) |
1070 container) | 1100 container) |
1071 (t (setf (gethash id mh-thread-id-table) | 1101 (t (setf (gethash id mh-thread-id-table) |
1072 (mh-thread-make-container :message message)))))) | 1102 (mh-thread-make-container :message message)))))) |
1073 | 1103 |
1074 (defsubst mh-thread-get-message (id subject-re-p subject refs) | 1104 (defsubst mh-thread-get-message (id subject-re-p subject refs) |
1075 "Return appropriate message. | 1105 "Return appropriate message. |
1076 Otherwise update message already present to have the proper ID, SUBJECT-RE-P, | 1106 Otherwise update message already present to have the proper ID, |
1077 SUBJECT and REFS fields." | 1107 SUBJECT-RE-P, SUBJECT and REFS fields." |
1078 (let* ((container (gethash id mh-thread-id-table)) | 1108 (let* ((container (gethash id mh-thread-id-table)) |
1079 (message (if container (mh-container-message container) nil))) | 1109 (message (if container (mh-container-message container) nil))) |
1080 (cond (message | 1110 (cond (message |
1081 (setf (mh-message-subject-re-p message) subject-re-p) | 1111 (setf (mh-message-subject-re-p message) subject-re-p) |
1082 (setf (mh-message-subject message) subject) | 1112 (setf (mh-message-subject message) subject) |
1101 (gethash id mh-thread-id-hash) | 1131 (gethash id mh-thread-id-hash) |
1102 (setf (gethash id mh-thread-id-hash) id))) | 1132 (setf (gethash id mh-thread-id-hash) id))) |
1103 | 1133 |
1104 (defsubst mh-thread-prune-subject (subject) | 1134 (defsubst mh-thread-prune-subject (subject) |
1105 "Prune leading Re:'s, Fwd:'s etc. and trailing (fwd)'s from SUBJECT. | 1135 "Prune leading Re:'s, Fwd:'s etc. and trailing (fwd)'s from SUBJECT. |
1106 If the result after pruning is not the empty string then it is canonicalized | 1136 If the result after pruning is not the empty string then it is |
1107 so that subjects can be tested for equality with eq. This is done so that all | 1137 canonicalized so that subjects can be tested for equality with |
1108 the messages without a subject are not put into a single thread." | 1138 eq. This is done so that all the messages without a subject are |
1139 not put into a single thread." | |
1109 (let ((case-fold-search t) | 1140 (let ((case-fold-search t) |
1110 (subject-pruned-flag nil)) | 1141 (subject-pruned-flag nil)) |
1111 ;; Prune subject leader | 1142 ;; Prune subject leader |
1112 (while (or (string-match "^[ \t]*\\(re\\|fwd?\\)\\(\\[[0-9]*\\]\\)?:[ \t]*" | 1143 (while (or (string-match "^[ \t]*\\(re\\|fwd?\\)\\(\\[[0-9]*\\]\\)?:[ \t]*" |
1113 subject) | 1144 subject) |
1126 (setf (gethash subject mh-thread-subject-hash) subject)) | 1157 (setf (gethash subject mh-thread-subject-hash) subject)) |
1127 subject-pruned-flag))))) | 1158 subject-pruned-flag))))) |
1128 | 1159 |
1129 (defun mh-thread-container-subject (container) | 1160 (defun mh-thread-container-subject (container) |
1130 "Return the subject of CONTAINER. | 1161 "Return the subject of CONTAINER. |
1131 If CONTAINER is empty return the subject info of one of its children." | 1162 If CONTAINER is empty return the subject info of one of its |
1163 children." | |
1132 (cond ((and (mh-container-message container) | 1164 (cond ((and (mh-container-message container) |
1133 (mh-message-id (mh-container-message container))) | 1165 (mh-message-id (mh-container-message container))) |
1134 (mh-message-subject (mh-container-message container))) | 1166 (mh-message-subject (mh-container-message container))) |
1135 (t (block nil | 1167 (t (block nil |
1136 (dolist (kid (mh-container-children container)) | 1168 (dolist (kid (mh-container-children container)) |
1231 (and (integerp index-x) (integerp index-y) | 1263 (and (integerp index-x) (integerp index-y) |
1232 (< index-x index-y))))))) | 1264 (< index-x index-y))))))) |
1233 | 1265 |
1234 (defsubst mh-thread-group-by-subject (roots) | 1266 (defsubst mh-thread-group-by-subject (roots) |
1235 "Group the set of message containers, ROOTS based on subject. | 1267 "Group the set of message containers, ROOTS based on subject. |
1236 Bug: Check for and make sure that something without Re: is made the parent in | 1268 Bug: Check for and make sure that something without Re: is made |
1237 preference to something that has it." | 1269 the parent in preference to something that has it." |
1238 (clrhash mh-thread-subject-container-hash) | 1270 (clrhash mh-thread-subject-container-hash) |
1239 (let ((results ())) | 1271 (let ((results ())) |
1240 (dolist (root roots) | 1272 (dolist (root roots) |
1241 (let* ((subject (mh-thread-container-subject root)) | 1273 (let* ((subject (mh-thread-container-subject root)) |
1242 (parent (gethash subject mh-thread-subject-container-hash))) | 1274 (parent (gethash subject mh-thread-subject-container-hash))) |
1249 (push root results))))) | 1281 (push root results))))) |
1250 (nreverse results))) | 1282 (nreverse results))) |
1251 | 1283 |
1252 (defun mh-thread-process-in-reply-to (reply-to-header) | 1284 (defun mh-thread-process-in-reply-to (reply-to-header) |
1253 "Extract message id's from REPLY-TO-HEADER. | 1285 "Extract message id's from REPLY-TO-HEADER. |
1254 Ideally this should have some regexp which will try to guess if a string | 1286 Ideally this should have some regexp which will try to guess if a |
1255 between < and > is a message id and not an email address. For now it will | 1287 string between < and > is a message id and not an email address. |
1256 take the last string inside angles." | 1288 For now it will take the last string inside angles." |
1257 (let ((end (mh-search-from-end ?> reply-to-header))) | 1289 (let ((end (mh-search-from-end ?> reply-to-header))) |
1258 (when (numberp end) | 1290 (when (numberp end) |
1259 (let ((begin (mh-search-from-end ?< (substring reply-to-header 0 end)))) | 1291 (let ((begin (mh-search-from-end ?< (substring reply-to-header 0 end)))) |
1260 (when (numberp begin) | 1292 (when (numberp begin) |
1261 (list (substring reply-to-header begin (1+ end)))))))) | 1293 (list (substring reply-to-header begin (1+ end)))))))) |
1277 (setq mh-thread-duplicates (mh-get-table 'mh-thread-duplicates)) | 1309 (setq mh-thread-duplicates (mh-get-table 'mh-thread-duplicates)) |
1278 (setq mh-thread-history (mh-get-table 'mh-thread-history)))) | 1310 (setq mh-thread-history (mh-get-table 'mh-thread-history)))) |
1279 | 1311 |
1280 (defsubst mh-thread-update-id-index-maps (id index) | 1312 (defsubst mh-thread-update-id-index-maps (id index) |
1281 "Message with id, ID is the message in INDEX. | 1313 "Message with id, ID is the message in INDEX. |
1282 The function also checks for duplicate messages (that is multiple messages | 1314 The function also checks for duplicate messages (that is multiple |
1283 with the same ID). These messages are put in the `mh-thread-duplicates' hash | 1315 messages with the same ID). These messages are put in the |
1284 table." | 1316 `mh-thread-duplicates' hash table." |
1285 (let ((old-index (gethash id mh-thread-id-index-map))) | 1317 (let ((old-index (gethash id mh-thread-id-index-map))) |
1286 (when old-index (push old-index (gethash id mh-thread-duplicates))) | 1318 (when old-index (push old-index (gethash id mh-thread-duplicates))) |
1287 (setf (gethash id mh-thread-id-index-map) index) | 1319 (setf (gethash id mh-thread-id-index-map) index) |
1288 (setf (gethash index mh-thread-index-id-map) id))) | 1320 (setf (gethash index mh-thread-index-id-map) id))) |
1289 | 1321 |
1381 (mh-notate-cur) | 1413 (mh-notate-cur) |
1382 (set-buffer-modified-p old-buffer-modified-flag)))) | 1414 (set-buffer-modified-p old-buffer-modified-flag)))) |
1383 | 1415 |
1384 (defun mh-thread-generate-scan-lines (tree level) | 1416 (defun mh-thread-generate-scan-lines (tree level) |
1385 "Generate scan lines. | 1417 "Generate scan lines. |
1386 TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps message indices | 1418 TREE is the hierarchical tree of messages, SCAN-LINE-MAP maps |
1387 to the corresponding scan lines and LEVEL used to determine indentation of | 1419 message indices to the corresponding scan lines and LEVEL used to |
1388 the message." | 1420 determine indentation of the message." |
1389 (cond ((null tree) nil) | 1421 (cond ((null tree) nil) |
1390 ((mh-thread-container-p tree) | 1422 ((mh-thread-container-p tree) |
1391 (let* ((message (mh-container-message tree)) | 1423 (let* ((message (mh-container-message tree)) |
1392 (id (mh-message-id message)) | 1424 (id (mh-message-id message)) |
1393 (index (gethash id mh-thread-id-index-map)) | 1425 (index (gethash id mh-thread-id-index-map)) |
1434 | 1466 |
1435 ;; Another and may be better approach would be to generate all the info from | 1467 ;; Another and may be better approach would be to generate all the info from |
1436 ;; the scan which generates the threading info. For now this will have to do. | 1468 ;; the scan which generates the threading info. For now this will have to do. |
1437 (defun mh-thread-parse-scan-line (&optional string) | 1469 (defun mh-thread-parse-scan-line (&optional string) |
1438 "Parse a scan line. | 1470 "Parse a scan line. |
1439 If optional argument STRING is given then that is assumed to be the scan line. | 1471 If optional argument STRING is given then that is assumed to be |
1440 Otherwise uses the line at point as the scan line to parse." | 1472 the scan line. Otherwise uses the line at point as the scan line |
1473 to parse." | |
1441 (let* ((string (or string | 1474 (let* ((string (or string |
1442 (buffer-substring-no-properties (line-beginning-position) | 1475 (buffer-substring-no-properties (line-beginning-position) |
1443 (line-end-position)))) | 1476 (line-end-position)))) |
1444 (address-start (+ mh-cmd-note mh-scan-field-from-start-offset)) | 1477 (address-start (+ mh-cmd-note mh-scan-field-from-start-offset)) |
1445 (body-start (+ mh-cmd-note mh-scan-field-from-end-offset)) | 1478 (body-start (+ mh-cmd-note mh-scan-field-from-end-offset)) |
1581 | 1614 |
1582 ;;;###mh-autoload | 1615 ;;;###mh-autoload |
1583 (defun mh-thread-next-sibling (&optional previous-flag) | 1616 (defun mh-thread-next-sibling (&optional previous-flag) |
1584 "Display next sibling. | 1617 "Display next sibling. |
1585 | 1618 |
1586 With non-nil optional argument PREVIOUS-FLAG jump to the previous sibling." | 1619 With non-nil optional argument PREVIOUS-FLAG jump to the previous |
1620 sibling." | |
1587 (interactive) | 1621 (interactive) |
1588 (cond ((not (memq 'unthread mh-view-ops)) | 1622 (cond ((not (memq 'unthread mh-view-ops)) |
1589 (error "Folder isn't threaded")) | 1623 (error "Folder isn't threaded")) |
1590 ((eobp) | 1624 ((eobp) |
1591 (error "No message at point"))) | 1625 (error "No message at point"))) |
1630 | 1664 |
1631 ;;;###mh-autoload | 1665 ;;;###mh-autoload |
1632 (defun mh-thread-ancestor (&optional thread-root-flag) | 1666 (defun mh-thread-ancestor (&optional thread-root-flag) |
1633 "Display ancestor of current message. | 1667 "Display ancestor of current message. |
1634 | 1668 |
1635 If you do not care for the way a particular thread has turned, you can move up | 1669 If you do not care for the way a particular thread has turned, |
1636 the chain of messages with this command. This command can also take a prefix | 1670 you can move up the chain of messages with this command. This |
1637 argument THREAD-ROOT-FLAG to jump to the message that started everything." | 1671 command can also take a prefix argument THREAD-ROOT-FLAG to jump |
1672 to the message that started everything." | |
1638 (interactive "P") | 1673 (interactive "P") |
1639 (beginning-of-line) | 1674 (beginning-of-line) |
1640 (cond ((not (memq 'unthread mh-view-ops)) | 1675 (cond ((not (memq 'unthread mh-view-ops)) |
1641 (error "Folder isn't threaded")) | 1676 (error "Folder isn't threaded")) |
1642 ((eobp) | 1677 ((eobp) |
1650 (t (mh-thread-immediate-ancestor) | 1685 (t (mh-thread-immediate-ancestor) |
1651 (mh-maybe-show))))) | 1686 (mh-maybe-show))))) |
1652 | 1687 |
1653 (defun mh-thread-find-children () | 1688 (defun mh-thread-find-children () |
1654 "Return a region containing the current message and its children. | 1689 "Return a region containing the current message and its children. |
1655 The result is returned as a list of two elements. The first is the point at the | 1690 The result is returned as a list of two elements. The first is |
1656 start of the region and the second is the point at the end." | 1691 the point at the start of the region and the second is the point |
1692 at the end." | |
1657 (beginning-of-line) | 1693 (beginning-of-line) |
1658 (if (eobp) | 1694 (if (eobp) |
1659 nil | 1695 nil |
1660 (let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width | 1696 (let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width |
1661 mh-scan-date-width 1)) | 1697 mh-scan-date-width 1)) |
1742 | 1778 |
1743 ;;;###mh-autoload | 1779 ;;;###mh-autoload |
1744 (defun mh-narrow-to-tick () | 1780 (defun mh-narrow-to-tick () |
1745 "Limit to ticked messages. | 1781 "Limit to ticked messages. |
1746 | 1782 |
1747 What this command does is show only those messages that are in the \"tick\" | 1783 What this command does is show only those messages that are in |
1748 sequence (which you can customize via the `mh-tick-seq' option) in the | 1784 the \"tick\" sequence (which you can customize via the |
1749 MH-Folder buffer. In addition, it limits further MH-E searches to just those | 1785 `mh-tick-seq' option) in the MH-Folder buffer. In addition, it |
1750 messages. When you want to widen the view to all your messages again, use | 1786 limits further MH-E searches to just those messages. When you |
1787 want to widen the view to all your messages again, use | |
1751 \\[mh-widen]." | 1788 \\[mh-widen]." |
1752 (interactive) | 1789 (interactive) |
1753 (cond ((not mh-tick-seq) | 1790 (cond ((not mh-tick-seq) |
1754 (error "Enable ticking by customizing `mh-tick-seq'")) | 1791 (error "Enable ticking by customizing `mh-tick-seq'")) |
1755 ((null (mh-seq-msgs (mh-find-seq mh-tick-seq))) | 1792 ((null (mh-seq-msgs (mh-find-seq mh-tick-seq))) |