123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- (require 'rmail)
- (defun rmail-sort-by-date (reverse)
- "Sort messages of current Rmail buffer by \"Date\" header.
- If prefix argument REVERSE is non-nil, sorts in reverse order."
- (interactive "P")
- (rmail-sort-messages reverse
- (lambda (msg)
- (rmail-make-date-sortable
- (rmail-get-header "Date" msg)))))
- (defun rmail-sort-by-subject (reverse)
- "Sort messages of current Rmail buffer by \"Subject\" header.
- Ignores any \"Re: \" prefix. If prefix argument REVERSE is
- non-nil, sorts in reverse order."
-
- (interactive "P")
- (rmail-sort-messages reverse
- (lambda (msg)
- (let ((key (or (rmail-get-header "Subject" msg) ""))
- (case-fold-search t))
-
- (if (string-match "^\\(re:[ \t]*\\)*" key)
- (substring key (match-end 0))
- key)))))
- (defun rmail-sort-by-author (reverse)
- "Sort messages of current Rmail buffer by author.
- This uses either the \"From\" or \"Sender\" header, downcased.
- If prefix argument REVERSE is non-nil, sorts in reverse order."
- (interactive "P")
- (rmail-sort-messages reverse
- (lambda (msg)
- (downcase
- (mail-strip-quoted-names
- (or (rmail-get-header "From" msg)
- (rmail-get-header "Sender" msg) ""))))))
- (defun rmail-sort-by-recipient (reverse)
- "Sort messages of current Rmail buffer by recipient.
- This uses either the \"To\" or \"Apparently-To\" header, downcased.
- If prefix argument REVERSE is non-nil, sorts in reverse order."
- (interactive "P")
- (rmail-sort-messages reverse
- (lambda (msg)
- (downcase
- (mail-strip-quoted-names
- (or (rmail-get-header "To" msg)
- (rmail-get-header "Apparently-To" msg) ""))))))
- (defun rmail-sort-by-correspondent (reverse)
- "Sort messages of current Rmail buffer by other correspondent.
- This uses either the \"From\", \"Sender\", \"To\", or
- \"Apparently-To\" header, downcased. Uses the first header not
- excluded by `mail-dont-reply-to-names'. If prefix argument
- REVERSE is non-nil, sorts in reverse order."
- (interactive "P")
- (rmail-sort-messages reverse
- (lambda (msg)
- (downcase
- (rmail-select-correspondent
- msg
- '("From" "Sender" "To" "Apparently-To"))))))
- (defun rmail-select-correspondent (msg fields)
- "Find the first header not excluded by `mail-dont-reply-to-names'.
- MSG is a message number. FIELDS is a list of header names."
- (let ((ans ""))
- (while (and fields (string= ans ""))
- (setq ans
- (mail-dont-reply-to
- (mail-strip-quoted-names
- (or (rmail-get-header (car fields) msg) ""))))
- (setq fields (cdr fields)))
- ans))
- (defun rmail-sort-by-lines (reverse)
- "Sort messages of current Rmail buffer by the number of lines.
- If prefix argument REVERSE is non-nil, sorts in reverse order."
- (interactive "P")
- (rmail-sort-messages reverse
- (lambda (msg)
- (count-lines (rmail-msgbeg msg)
- (rmail-msgend msg)))))
- (defun rmail-sort-by-labels (reverse labels)
- "Sort messages of current Rmail buffer by labels.
- LABELS is a comma-separated list of labels. The order of these
- labels specifies the order of messages: messages with the first
- label come first, messages with the second label come second, and
- so on. Messages that have none of these labels come last.
- If prefix argument REVERSE is non-nil, sorts in reverse order."
- (interactive "P\nsSort by labels: ")
- (or (string-match "[^ \t]" labels)
- (error "No labels specified"))
-
- (setq labels (concat (substring labels (match-beginning 0)) ","))
- (let (labelvec nmax)
-
- (while (string-match "[ \t]*,[ \t]*" labels)
- (setq labelvec (cons
- (concat "\\(, \\|\\`\\)"
- (substring labels 0 (match-beginning 0))
- "\\(,\\|\\'\\)")
- labelvec))
- (setq labels (substring labels (match-end 0))))
- (setq labelvec (apply 'vector (nreverse labelvec))
- nmax (length labelvec))
- (rmail-sort-messages reverse
-
-
-
-
- (lambda (msg)
- (let ((n 0)
- (str (concat (rmail-get-attr-names msg)
- ", "
- (rmail-get-keywords msg))))
-
- (if (string-equal ", " str)
- nmax
- (while (and (< n nmax)
- (not (string-match (aref labelvec n)
- str)))
- (setq n (1+ n)))
- n))))))
- (declare-function rmail-update-summary "rmailsum" (&rest ignore))
- (defun rmail-sort-messages (reverse keyfun)
- "Sort messages of current Rmail buffer.
- If REVERSE is non-nil, sorts in reverse order. Calls the
- function KEYFUN with a message number (it should return a sort key).
- Numeric keys are sorted numerically, all others as strings."
- (with-current-buffer rmail-buffer
- (let ((return-to-point
- (if (rmail-buffers-swapped-p)
- (point)))
- (sort-lists nil))
- (rmail-swap-buffers-maybe)
- (message "Finding sort keys...")
- (widen)
- (let ((msgnum 1))
- (while (>= rmail-total-messages msgnum)
- (setq sort-lists
- (cons (list (funcall keyfun msgnum)
- (eq rmail-current-message msgnum)
- (aref rmail-message-vector msgnum)
- (aref rmail-message-vector (1+ msgnum)))
- sort-lists))
- (if (zerop (% msgnum 10))
- (message "Finding sort keys...%d" msgnum))
- (setq msgnum (1+ msgnum))))
- (or reverse (setq sort-lists (nreverse sort-lists)))
- (setq sort-lists
- (sort sort-lists
-
- (if (numberp (car (car sort-lists)))
- 'car-less-than-car
- (lambda (a b)
- (string-lessp (car a) (car b))))))
- (if reverse (setq sort-lists (nreverse sort-lists)))
-
- (message "Reordering messages...")
- (let ((inhibit-quit t)
- (inhibit-read-only t)
- (current-message nil)
- (msgnum 1)
- (msginfo nil)
- (undo (not (eq buffer-undo-list t))))
-
- (buffer-disable-undo (current-buffer))
- (goto-char (rmail-msgbeg 1))
-
-
- (insert-before-markers ?Z)
- (backward-char 1)
-
- (dolist (msginfo sort-lists)
-
- (insert-buffer-substring
- (current-buffer) (nth 2 msginfo) (nth 3 msginfo))
-
- (rmail-ensure-blank-line)
- (delete-region (nth 2 msginfo) (nth 3 msginfo))
-
- (if (nth 1 msginfo)
- (setq current-message msgnum))
- (if (zerop (% msgnum 10))
- (message "Reordering messages...%d" msgnum))
- (setq msgnum (1+ msgnum)))
-
- (delete-char 1)
- (setq quit-flag nil)
-
-
- (if undo (buffer-enable-undo))
- (rmail-set-message-counters)
- (rmail-show-message-1 current-message)
- (if return-to-point
- (goto-char return-to-point))
- (if (rmail-summary-exists)
- (rmail-select-summary (rmail-update-summary)))))))
- (autoload 'timezone-make-date-sortable "timezone")
- (defun rmail-make-date-sortable (date)
- "Make DATE sortable using the function `string-lessp'."
-
- (timezone-make-date-sortable date "GMT" "GMT"))
- (provide 'rmailsort)
|