X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=wl%2Fwl-summary.el;h=5853eb0e88973b1971f2c8df4d944fbd7a808d6d;hb=2a6b1705041ddafbf36593de88bafd01e7c545fb;hp=79fa995861435e93f9f02508a682f523d590e4f8;hpb=1d7ac1983cc07568560c6a302cc5f6fc500e5ca5;p=elisp%2Fwanderlust.git diff --git a/wl/wl-summary.el b/wl/wl-summary.el index 79fa995..5853eb0 100644 --- a/wl/wl-summary.el +++ b/wl/wl-summary.el @@ -75,14 +75,12 @@ (` (and wl-summary-buffer-elmo-folder (elmo-folder-msgdb wl-summary-buffer-elmo-folder)))) -(defvar wl-summary-buffer-folder-indicator nil) (defvar wl-summary-buffer-disp-msg nil) (defvar wl-summary-buffer-disp-folder nil) (defvar wl-summary-buffer-refile-list nil) (defvar wl-summary-buffer-delete-list nil) (defvar wl-summary-buffer-last-displayed-msg nil) (defvar wl-summary-buffer-current-msg nil) -(defvar wl-summary-buffer-unread-status " (0 new/0 unread)") (defvar wl-summary-buffer-unread-count 0) (defvar wl-summary-buffer-new-count 0) (defvar wl-summary-buffer-mime-charset nil) @@ -92,8 +90,11 @@ (defvar wl-summary-buffer-message-modified nil) (defvar wl-summary-buffer-mark-modified nil) (defvar wl-summary-buffer-thread-modified nil) + (defvar wl-summary-buffer-number-column nil) -(defvar wl-summary-buffer-number-regexp nil) +(defvar wl-summary-buffer-temp-mark-column nil) +(defvar wl-summary-buffer-persistent-mark-column nil) + (defvar wl-summary-buffer-persistent nil) (defvar wl-summary-buffer-thread-nodes nil) (defvar wl-summary-buffer-target-mark-list nil) @@ -108,6 +109,10 @@ (defvar wl-summary-buffer-number-list nil) (defvar wl-summary-buffer-msgdb nil) (defvar wl-summary-buffer-folder-name nil) +(defvar wl-summary-buffer-line-formatter nil) +(defvar wl-summary-buffer-line-format nil) +(defvar wl-summary-buffer-mode-line-formatter nil) +(defvar wl-summary-buffer-mode-line nil) (defvar wl-thread-indent-level-internal nil) (defvar wl-thread-have-younger-brother-str-internal nil) @@ -126,8 +131,6 @@ (defvar wl-summary-get-petname-function 'wl-address-get-petname-1) -(defvar wl-summary-message-regexp "^ *\\(-?[0-9]+\\)") - (defvar wl-summary-shell-command-last "") (defvar wl-ps-preprint-hook nil) @@ -141,9 +144,7 @@ (make-variable-buffer-local 'wl-summary-buffer-copy-list) (make-variable-buffer-local 'wl-summary-buffer-target-mark-list) (make-variable-buffer-local 'wl-summary-buffer-delete-list) -(make-variable-buffer-local 'wl-summary-buffer-folder-indicator) (make-variable-buffer-local 'wl-summary-buffer-last-displayed-msg) -(make-variable-buffer-local 'wl-summary-buffer-unread-status) (make-variable-buffer-local 'wl-summary-buffer-unread-count) (make-variable-buffer-local 'wl-summary-buffer-new-count) (make-variable-buffer-local 'wl-summary-buffer-mime-charset) @@ -154,7 +155,8 @@ (make-variable-buffer-local 'wl-summary-buffer-mark-modified) (make-variable-buffer-local 'wl-summary-buffer-thread-modified) (make-variable-buffer-local 'wl-summary-buffer-number-column) -(make-variable-buffer-local 'wl-summary-buffer-number-regexp) +(make-variable-buffer-local 'wl-summary-buffer-temp-mark-column) +(make-variable-buffer-local 'wl-summary-buffer-persistent-mark-column) (make-variable-buffer-local 'wl-summary-buffer-persistent) (make-variable-buffer-local 'wl-summary-buffer-thread-nodes) (make-variable-buffer-local 'wl-summary-buffer-prev-refile-destination) @@ -179,21 +181,24 @@ (make-variable-buffer-local 'wl-summary-buffer-number-list) (make-variable-buffer-local 'wl-summary-buffer-msgdb) (make-variable-buffer-local 'wl-summary-buffer-folder-name) +(make-variable-buffer-local 'wl-summary-buffer-line-formatter) +(make-variable-buffer-local 'wl-summary-buffer-line-format) +(make-variable-buffer-local 'wl-summary-buffer-mode-line-formatter) +(make-variable-buffer-local 'wl-summary-buffer-mode-line) + +(defvar wl-datevec) +(defvar wl-thr-indent-string) +(defvar wl-thr-children-number) +(defvar wl-thr-linked) +(defvar wl-message-entity) +(defvar wl-parent-message-entity) +(defvar wl-temp-mark) +(defvar wl-persistent-mark) ;; internal functions (dummy) (unless (fboundp 'wl-summary-append-message-func-internal) - (defun wl-summary-append-message-func-internal (entity overview - mark-alist update + (defun wl-summary-append-message-func-internal (entity msgdb update &optional force-insert))) -(unless (fboundp 'wl-summary-from-func-internal) - (defun wl-summary-from-func-internal (from) - from)) -(unless (fboundp 'wl-summary-subject-func-internal) - (defun wl-summary-subject-func-internal (subject) - subject)) -(unless (fboundp 'wl-summary-subject-filter-func-internal) - (defun wl-summary-subject-filter-func-internal (subject) - subject)) (defmacro wl-summary-sticky-buffer-name (name) (` (concat wl-summary-buffer-name ":" (, name)))) @@ -203,7 +208,6 @@ (substring subject-string (match-end 0)) subject-string)) -(eval-when-compile (defvar-maybe entity nil)) ; silence byte compiler. (defun wl-summary-default-from (from) (let (retval tos ng) (unless @@ -213,7 +217,8 @@ (wl-summary-buffer-folder-name)) (wl-address-user-mail-address-p from) (cond - ((and (setq tos (elmo-msgdb-overview-entity-get-to entity)) + ((and (setq tos (elmo-msgdb-overview-entity-get-to + wl-message-entity)) (not (string= "" tos))) (setq retval (concat "To:" @@ -223,7 +228,8 @@ (eword-decode-string (if wl-use-petname (or - (funcall wl-summary-get-petname-function to) + (funcall + wl-summary-get-petname-function to) (car (std11-extract-address-components to)) to) @@ -231,7 +237,7 @@ (wl-parse-addresses tos) ",")))) ((setq ng (elmo-msgdb-overview-entity-get-extra-field - entity "newsgroups")) + wl-message-entity "newsgroups")) (setq retval (concat "Ng:" ng))))) (if wl-use-petname (setq retval (or (funcall wl-summary-get-petname-function from) @@ -247,6 +253,9 @@ string) string)) +(defvar wl-summary-sort-specs '(number date subject from list-info)) +(defvar wl-summary-default-sort-spec 'date) + (defvar wl-summary-mode-menu-spec '("Summary" ["Read" wl-summary-read t] @@ -274,7 +283,8 @@ ["By Number" wl-summary-sort-by-number t] ["By Date" wl-summary-sort-by-date t] ["By From" wl-summary-sort-by-from t] - ["By Subject" wl-summary-sort-by-subject t]) + ["By Subject" wl-summary-sort-by-subject t] + ["By List Info" wl-summary-sort-by-list-info t]) "----" ("Message Operation" ["Mark as read" wl-summary-mark-as-read t] @@ -345,6 +355,7 @@ "----" ("Writing Messages" ["Write a message" wl-summary-write t] + ["Write for current folder" wl-summary-write-current-folder t] ["Reply" wl-summary-reply t] ["Reply with citation" wl-summary-reply-with-citation t] ["Forward" wl-summary-forward t]) @@ -412,12 +423,15 @@ (define-key wl-summary-mode-map "e" 'wl-summary-save) (define-key wl-summary-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer) (define-key wl-summary-mode-map "\C-c\C-a" 'wl-addrmgr) + (define-key wl-summary-mode-map "\C-c\C-p" 'wl-summary-previous-buffer) + (define-key wl-summary-mode-map "\C-c\C-n" 'wl-summary-next-buffer) (define-key wl-summary-mode-map "H" 'wl-summary-redisplay-all-header) (define-key wl-summary-mode-map "M" 'wl-summary-redisplay-no-mime) (define-key wl-summary-mode-map "B" 'wl-summary-burst) (define-key wl-summary-mode-map "Z" 'wl-status-update) (define-key wl-summary-mode-map "#" 'wl-summary-print-message) (define-key wl-summary-mode-map "|" 'wl-summary-pipe-message) + (define-key wl-summary-mode-map "z" 'wl-summary-suspend) (define-key wl-summary-mode-map "q" 'wl-summary-exit) (define-key wl-summary-mode-map "Q" 'wl-summary-force-exit) @@ -491,6 +505,8 @@ (define-key wl-summary-mode-map "mA" 'wl-summary-target-mark-reply-with-citation) (define-key wl-summary-mode-map "mf" 'wl-summary-target-mark-forward) (define-key wl-summary-mode-map "m?" 'wl-summary-target-mark-pick) + (define-key wl-summary-mode-map "m#" 'wl-summary-target-mark-print) + (define-key wl-summary-mode-map "m|" 'wl-summary-target-mark-pipe) ;; region commands (define-key wl-summary-mode-map "r" (make-sparse-keymap)) @@ -537,6 +553,8 @@ (defun wl-summary-display-top () (interactive) (goto-char (point-min)) + (when wl-summary-lazy-highlight + (wl-highlight-summary-window)) (if wl-summary-buffer-disp-msg (wl-summary-redisplay))) @@ -544,27 +562,21 @@ (interactive) (goto-char (point-max)) (forward-line -1) + (when wl-summary-lazy-highlight + (wl-highlight-summary-window)) (if wl-summary-buffer-disp-msg (wl-summary-redisplay))) -(defun wl-summary-count-unread (mark-alist) - (let ((new 0) - (unread 0) - mark) - (while mark-alist - (setq mark (cadr (car mark-alist))) - (and mark - (cond - ((string= mark wl-summary-new-mark) - (setq new (+ 1 new))) - ((or (string= mark wl-summary-unread-uncached-mark) - (string= mark wl-summary-unread-cached-mark)) - (setq unread (+ 1 unread))))) - (setq mark-alist (cdr mark-alist))) +(defun wl-summary-count-unread () + (let ((pair + (elmo-msgdb-count-marks (wl-summary-buffer-msgdb) + wl-summary-new-mark + (list wl-summary-unread-uncached-mark + wl-summary-unread-cached-mark)))) (if (eq major-mode 'wl-summary-mode) - (setq wl-summary-buffer-new-count new - wl-summary-buffer-unread-count unread)) - (cons new unread))) + (setq wl-summary-buffer-new-count (car pair) + wl-summary-buffer-unread-count (cdr pair))) + pair)) (defun wl-summary-message-string (&optional use-cache) "Return full body string of current message. @@ -629,7 +641,7 @@ you." (concat "^--" boundary "\n" "\\([Cc]ontent-[Dd]escription:.*\n\\)?" "[Cc]ontent-[Tt]ype:[ \t]+" - "\\(message/rfc822\\|text/rfc822-headers\\)\n" + "\\(message/rfc822\\|text/rfc822-headers\\).*\n" "\\(.+\n\\)*\n") nil t)) (re-search-forward (concat "\n\\(--" boundary "\\)--\n") nil t)) @@ -692,14 +704,39 @@ you." (kill-buffer (current-buffer))) (message "Resending message to %s...done" address)))) +(defun wl-summary-detect-mark-position () + (let ((column wl-summary-buffer-number-column) + (formatter wl-summary-buffer-line-formatter) + (dummy-temp (char-to-string 200)) + (dummy-persistent (char-to-string 201)) + temp persistent) + (with-temp-buffer + (setq wl-summary-buffer-number-column column + wl-summary-buffer-line-formatter formatter) + (insert + (wl-summary-create-line + (elmo-msgdb-make-entity + :number 10000 + :from "foo" + :subject "bar" + :size 100) + nil + dummy-temp + dummy-persistent)) + (goto-char (point-min)) + (setq temp (save-excursion + (search-forward dummy-temp nil t) + (current-column)) + persistent (save-excursion + (search-forward dummy-persistent nil t) + (current-column)))) + (setq wl-summary-buffer-temp-mark-column temp + wl-summary-buffer-persistent-mark-column persistent))) + (defun wl-summary-buffer-set-folder (folder) (if (stringp folder) (setq folder (wl-folder-get-elmo-folder folder))) (setq wl-summary-buffer-elmo-folder folder) - (setq wl-summary-buffer-folder-indicator - (if (memq 'modeline wl-use-folder-petname) - (wl-folder-get-petname (elmo-folder-name-internal folder)) - (elmo-folder-name-internal folder))) (make-local-variable 'wl-message-buffer) (setq wl-summary-buffer-mime-charset (or (wl-get-assoc-list-value wl-folder-mime-charset-alist @@ -714,6 +751,23 @@ you." (wl-get-assoc-list-value wl-folder-thread-indent-set-alist (elmo-folder-name-internal folder))) + (setq wl-summary-buffer-number-column + (or (wl-get-assoc-list-value wl-summary-number-column-alist + (wl-summary-buffer-folder-name)) + wl-summary-default-number-column)) + (wl-line-formatter-setup + wl-summary-buffer-line-formatter + (setq wl-summary-buffer-line-format + (or (wl-get-assoc-list-value + wl-folder-summary-line-format-alist + (elmo-folder-name-internal folder)) + wl-summary-line-format)) + wl-summary-line-format-spec-alist) + (wl-line-formatter-setup + wl-summary-buffer-mode-line-formatter + wl-summary-mode-line-format + wl-summary-mode-line-format-spec-alist) + (wl-summary-detect-mark-position) (setq wl-summary-buffer-persistent (wl-folder-persistent-p (elmo-folder-name-internal folder))) (elmo-folder-set-persistent-internal folder wl-summary-buffer-persistent) @@ -741,13 +795,6 @@ you." wl-thread-space-str-internal (or (nth 5 wl-summary-buffer-thread-indent-set) wl-thread-space-str)) - (setq wl-thread-indent-regexp - (concat - (regexp-quote wl-thread-have-younger-brother-str-internal) "\\|" - (regexp-quote wl-thread-youngest-child-str-internal) "\\|" - (regexp-quote wl-thread-vertical-str-internal) "\\|" - (regexp-quote wl-thread-horizontal-str-internal) "\\|" - (regexp-quote wl-thread-space-str-internal))) (run-hooks 'wl-summary-buffer-set-folder-hook)) (defun wl-summary-mode () @@ -769,13 +816,17 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." ;;;(make-local-variable 'tab-width) ;;;(setq tab-width 1) (buffer-disable-undo (current-buffer)) - (wl-mode-line-buffer-identification '("Wanderlust: " - wl-summary-buffer-folder-indicator - wl-summary-buffer-unread-status)) + (setq selective-display t + selective-display-ellipses nil) + (wl-mode-line-buffer-identification '(wl-summary-buffer-mode-line)) (easy-menu-add wl-summary-mode-menu) (when wl-summary-lazy-highlight - (make-local-variable 'window-scroll-functions) - (add-hook 'window-scroll-functions 'wl-highlight-summary-window)) + (if wl-on-xemacs + (progn + (make-local-variable 'pre-idle-hook) + (add-hook 'pre-idle-hook 'wl-highlight-summary-window)) + (make-local-variable 'window-scroll-functions) + (add-hook 'window-scroll-functions 'wl-highlight-summary-window))) ;; This hook may contain the function `wl-setup-summary' for reasons ;; of system internal to accord facilities for the Emacs variants. (run-hooks 'wl-summary-mode-hook)) @@ -811,6 +862,49 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (string< (elmo-msgdb-overview-entity-get-subject-no-decode x) (elmo-msgdb-overview-entity-get-subject-no-decode y))) +(defun wl-summary-get-list-info (entity) + "Returns (\"ML-name\" . ML-count) of ENTITY." + (let (sequence ml-name ml-count subject return-path) + (setq sequence (elmo-msgdb-overview-entity-get-extra-field + entity "x-sequence") + ml-name (or (elmo-msgdb-overview-entity-get-extra-field + entity "x-ml-name") + (and sequence + (car (split-string sequence " ")))) + ml-count (or (elmo-msgdb-overview-entity-get-extra-field + entity "x-mail-count") + (elmo-msgdb-overview-entity-get-extra-field + entity "x-ml-count") + (and sequence + (cadr (split-string sequence " "))))) + (and (setq subject (elmo-msgdb-overview-entity-get-subject + entity)) + (setq subject (elmo-delete-char ?\n subject)) + (string-match "^\\s(\\(\\S)+\\)[ :]\\([0-9]+\\)\\s)[ \t]*" subject) + (progn + (or ml-name (setq ml-name (match-string 1 subject))) + (or ml-count (setq ml-count (match-string 2 subject))))) + (and (setq return-path + (elmo-msgdb-overview-entity-get-extra-field + entity "return-path")) + (string-match "^<\\([^@>]+\\)-return-\\([0-9]+\\)-" return-path) + (progn + (or ml-name (setq ml-name (match-string 1 return-path))) + (or ml-count (setq ml-count (match-string 2 return-path))))) + (cons (and ml-name (car (split-string ml-name " "))) + (and ml-count (string-to-int ml-count))))) + +(defun wl-summary-overview-entity-compare-by-list-info (x y) + "Compare entity X and Y by mailing-list info." + (let* ((list-info-x (wl-summary-get-list-info x)) + (list-info-y (wl-summary-get-list-info y))) + (if (equal list-info-x list-info-y) + (wl-summary-overview-entity-compare-by-date x y) + (if (string= (car list-info-x) (car list-info-y)) + (< (or (cdr list-info-x) 0) + (or (cdr list-info-y) 0)) + (string< (car list-info-x) (car list-info-y)))))) + (defun wl-summary-sort-by-date () (interactive) (wl-summary-rescan "date")) @@ -823,6 +917,9 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (defun wl-summary-sort-by-from () (interactive) (wl-summary-rescan "from")) +(defun wl-summary-sort-by-list-info () + (interactive) + (wl-summary-rescan "list-info")) (defun wl-summary-rescan (&optional sort-by) "Rescan current folder without updating." @@ -831,7 +928,6 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (msgdb (wl-summary-buffer-msgdb)) (overview (elmo-msgdb-get-overview msgdb)) (number-alist (elmo-msgdb-get-number-alist msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) (elmo-mime-charset wl-summary-buffer-mime-charset) i percent num gc-message entity @@ -841,7 +937,6 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." expunged) (fset 'wl-summary-append-message-func-internal (wl-summary-get-append-message-func)) - (wl-summary-buffer-number-column-detect nil) (erase-buffer) (message "Re-scanning...") (setq i 0) @@ -866,11 +961,9 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (setq wl-summary-buffer-delete-list nil) (setq wl-summary-delayed-update nil) (elmo-kill-buffer wl-summary-search-buf-name) - (message "Constructing summary structure...") (while curp (setq entity (car curp)) - (wl-summary-append-message-func-internal entity overview mark-alist - nil) + (wl-summary-append-message-func-internal entity msgdb nil) (setq curp (cdr curp)) (when (> num elmo-display-progress-threshold) (setq i (+ i 1)) @@ -885,8 +978,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (elmo-msgdb-overview-entity-get-number (cdar wl-summary-delayed-update))) (wl-summary-append-message-func-internal - (cdar wl-summary-delayed-update) - overview mark-alist nil t) + (cdar wl-summary-delayed-update) msgdb nil t) (setq wl-summary-delayed-update (cdr wl-summary-delayed-update)))) (message "Constructing summary structure...done") (set-buffer cur-buf) @@ -905,9 +997,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (setq expunged (wl-summary-score-update-all-lines))) (message "%d message(s) are expunged by scoring." (length expunged)))) (wl-summary-set-message-modified) - (wl-summary-count-unread - (elmo-msgdb-get-mark-alist - (elmo-folder-msgdb wl-summary-buffer-elmo-folder))) + (wl-summary-count-unread) (wl-summary-update-modeline) (goto-char (point-max)) (forward-line -1) @@ -1091,6 +1181,11 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (kill-buffer summary-buf))) (run-hooks 'wl-summary-exit-hook))))) +(defun wl-summary-suspend () + (interactive) + (wl-summary-exit) + (wl-folder-suspend)) + (defun wl-summary-sync-force-update (&optional unset-cursor no-check) (interactive) (wl-summary-sync-update unset-cursor nil no-check)) @@ -1109,8 +1204,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (setq wl-summary-buffer-target-mark-list nil) (setq wl-summary-buffer-refile-list nil) (setq wl-summary-buffer-copy-list nil) - (setq wl-summary-buffer-delete-list nil) - (wl-summary-buffer-number-column-detect nil)) + (setq wl-summary-buffer-delete-list nil)) (defun wl-summary-sync (&optional unset-cursor force-range) (interactive) @@ -1276,17 +1370,18 @@ If ARG is non-nil, checking is omitted." ;; prefetching procedure. (save-excursion (let* ((msgdb (wl-summary-buffer-msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) (number-alist (elmo-msgdb-get-number-alist msgdb)) (message-id (cdr (assq number number-alist))) (ov (elmo-msgdb-overview-get-entity message-id msgdb)) - (entity ov) + (wl-message-entity ov) + (entity ov) ; backward compatibility. (size (elmo-msgdb-overview-entity-get-size ov)) (inhibit-read-only t) (buffer-read-only nil) (file-cached (elmo-file-cache-exists-p message-id)) (force-read (and size - (or (null wl-prefetch-threshold) + (or (and (null wl-prefetch-confirm) arg) + (null wl-prefetch-threshold) (< size wl-prefetch-threshold)))) mark new-mark) (unwind-protect @@ -1303,8 +1398,8 @@ If ARG is non-nil, checking is omitted." "[ " (save-match-data (wl-set-string-width - wl-summary-from-width - (wl-summary-from-func-internal + 17 + (funcall wl-summary-from-function (eword-decode-string (elmo-delete-char ?\" @@ -1313,7 +1408,7 @@ If ARG is non-nil, checking is omitted." "??")))))) " ]") size)))) (message "")) ; flush. - (setq mark (cadr (assq number mark-alist))) + (setq mark (elmo-msgdb-get-mark msgdb number)) (if force-read (save-excursion (save-match-data @@ -1336,10 +1431,8 @@ If ARG is non-nil, checking is omitted." ((string= mark wl-summary-read-uncached-mark) nil) (t mark))) - (setq mark-alist (elmo-msgdb-mark-set - mark-alist number new-mark)) + (elmo-msgdb-set-mark msgdb number new-mark) (or new-mark (setq new-mark " ")) - (elmo-msgdb-set-mark-alist msgdb mark-alist) (wl-summary-set-mark-modified) (wl-summary-update-modeline) (wl-folder-update-unread @@ -1368,27 +1461,25 @@ If ARG is non-nil, checking is omitted." (message "Collecting marks...") (goto-char (point-min)) (while (not (eobp)) - (beginning-of-line) - (when (looking-at "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)") - (setq mark (wl-match-buffer 2)) - (setq msg (string-to-int (wl-match-buffer 1))) - (if (or (and (null prefetch-marks) - msg - (null (elmo-file-cache-exists-p - (cdr (assq msg - (elmo-msgdb-get-number-alist - (wl-summary-buffer-msgdb))))))) - (member mark prefetch-marks)) - (setq targets (nconc targets (list msg)))) - (setq entity (wl-thread-get-entity msg)) - (if (or (not (eq wl-summary-buffer-view 'thread)) - (wl-thread-entity-get-opened entity)) - (); opened. no hidden children. - ;; hidden children!! - (setq targets (nconc - targets - (wl-thread-get-children-msgs-uncached - msg prefetch-marks))))) + (setq mark (wl-summary-persistent-mark) + msg (wl-summary-message-number)) + (if (or (and (null prefetch-marks) + msg + (null (elmo-file-cache-exists-p + (elmo-message-field + wl-summary-buffer-elmo-folder + msg + 'message-id)))) + (member mark prefetch-marks)) + (setq targets (nconc targets (list msg)))) + (setq entity (wl-thread-get-entity msg)) + (if (or (not (eq wl-summary-buffer-view 'thread)) + (wl-thread-entity-get-opened entity)) + (); opened. no hidden children. + (setq targets (nconc + targets + (wl-thread-get-children-msgs-uncached + msg prefetch-marks)))) (forward-line 1)) (setq length (length targets)) (message "Prefetching...") @@ -1421,36 +1512,17 @@ If ARG is non-nil, checking is omitted." "Prefetch current message." (interactive "P") (save-excursion - (save-match-data - (beginning-of-line) - (when (looking-at "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)") - (goto-char (match-beginning 2)) - (let ((inhibit-read-only t) - (buffer-read-only nil) - (beg (match-beginning 2)) - (end (match-end 2)) - mark) - (setq mark (wl-summary-prefetch-msg - (string-to-int (wl-match-buffer 1)) arg)) - (when mark - (delete-region beg end) - (insert mark) - (if wl-summary-highlight - (wl-highlight-summary-current-line))) - (set-buffer-modified-p nil) - mark))))) - -(defun wl-summary-delete-all-status-marks-on-buffer () - (interactive) - (save-excursion - (goto-char (point-min)) (let ((inhibit-read-only t) (buffer-read-only nil) - (case-fold-search nil)) - (while (re-search-forward - (concat "^" wl-summary-buffer-number-regexp ".\\(.\\)") nil t) - (delete-region (match-beginning 1) (match-end 1)) - (insert " "))))) + (mark (wl-summary-persistent-mark))) + (setq mark (wl-summary-prefetch-msg (wl-summary-message-number) arg)) + (when mark + (delete-backward-char 1) + (insert mark) + (if wl-summary-highlight + (wl-highlight-summary-current-line))) + (set-buffer-modified-p nil) + mark))) (defun wl-summary-delete-marks-on-buffer (marks) (while marks @@ -1477,41 +1549,21 @@ If ARG is non-nil, checking is omitted." (defun wl-summary-delete-all-temp-marks-on-buffer (&optional sticky) ;; for summary view cache saving. - (interactive) (save-excursion (goto-char (point-min)) (let ((inhibit-read-only t) - (buffer-read-only nil) - (case-fold-search nil) - (regexp (concat "^" wl-summary-buffer-number-regexp "\\([^ ]\\)" ))) - (while (re-search-forward regexp nil t) - (delete-region (match-beginning 1) (match-end 1)) - (insert " ") - (if (and sticky wl-summary-highlight) - (wl-highlight-summary-current-line)))))) - -(defun wl-summary-delete-all-marks (mark-alist mark) - "Delete all MARKs in MARK-ALIST." - (let ((malist mark-alist) - (ret-val mark-alist) - entity) - (while malist - (setq entity (car malist)) - (if (string= (cadr entity) mark) - ;; delete this entity - (setq ret-val (delete entity ret-val))) - (setq malist (cdr malist))) - ret-val)) - -;; Does not work correctly... + (buffer-read-only nil)) + (while (not (eobp)) + (unless (string= (wl-summary-temp-mark) " ") + (delete-backward-char 1) + (insert " ")) + (forward-line 1))))) + (defun wl-summary-mark-as-read-region (beg end) (interactive "r") (save-excursion (save-restriction (narrow-to-region beg end) -;;; use narrowing. -;;; (save-excursion (goto-char end) -;;; (end-of-line) (point))) (goto-char (point-min)) (if (eq wl-summary-buffer-view 'thread) (progn @@ -1521,19 +1573,18 @@ If ARG is non-nil, checking is omitted." children) (if (wl-thread-entity-get-opened entity) ;; opened...mark line. - ;; Crossposts are not processed - (wl-summary-mark-as-read t) + (wl-summary-mark-as-read number) ;; closed - (wl-summary-mark-as-read t) ; mark itself. + (wl-summary-mark-as-read number) ; mark itself. (setq children (wl-thread-get-children-msgs number)) (while children - (wl-summary-mark-as-read t nil nil (car children)) + (wl-summary-mark-as-read (car children)) (setq children (cdr children)))) (forward-line 1)))) (while (not (eobp)) - (wl-summary-mark-as-read t) + (wl-summary-mark-as-read (wl-summary-message-number)) (forward-line 1))))) - (wl-summary-count-unread (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline)) (defun wl-summary-mark-as-unread-region (beg end) @@ -1566,7 +1617,7 @@ If ARG is non-nil, checking is omitted." (while (not (eobp)) (wl-summary-mark-as-unread) (forward-line 1))))) - (wl-summary-count-unread (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline)) (defun wl-summary-mark-as-important-region (beg end) @@ -1597,7 +1648,7 @@ If ARG is non-nil, checking is omitted." (while (not (eobp)) (wl-summary-mark-as-important) (forward-line 1))))) - (wl-summary-count-unread (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline)) (defun wl-summary-mark-as-read-all () @@ -1607,9 +1658,6 @@ If ARG is non-nil, checking is omitted." (let* ((folder wl-summary-buffer-elmo-folder) (cur-buf (current-buffer)) (msgdb (wl-summary-buffer-msgdb)) -;;; (number-alist (elmo-msgdb-get-number-alist msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) - (malist mark-alist) (inhibit-read-only t) (buffer-read-only nil) (case-fold-search nil) @@ -1623,36 +1671,34 @@ If ARG is non-nil, checking is omitted." wl-summary-new-mark))) (save-excursion (goto-char (point-min)) - (while (re-search-forward "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9 ]\\)" nil t) - (setq msg (string-to-int (wl-match-buffer 1))) - (setq mark (wl-match-buffer 2)) - (when (and (not (string= mark wl-summary-important-mark)) + (while (not (eobp)) + (setq msg (wl-summary-message-number)) + (setq mark (wl-summary-persistent-mark)) + (when (and (not (string= mark " ")) + (not (string= mark wl-summary-important-mark)) (not (string= mark wl-summary-read-uncached-mark))) - (delete-region (match-beginning 2) (match-end 2)) + (delete-backward-char 1) (if (or (not (elmo-message-use-cache-p folder msg)) (string= mark wl-summary-unread-cached-mark)) (progn (insert " ") - (setq mark-alist - (elmo-msgdb-mark-set - mark-alist - msg -;;; Use msg instead of (cdr (assq msg number-alist)). -;;; (cdr (assq msg number-alist)) - nil))) + (elmo-msgdb-set-mark msgdb msg nil)) ;; New mark and unread-uncached mark (insert wl-summary-read-uncached-mark) - (setq mark-alist - (elmo-msgdb-mark-set mark-alist - msg -;;; (cdr (assq msg number-alist)) - wl-summary-read-uncached-mark))) + (elmo-msgdb-set-mark + msgdb msg wl-summary-read-uncached-mark)) (if wl-summary-highlight - (wl-highlight-summary-current-line nil nil t))))) - (setq mark-alist (wl-summary-set-as-read-mark-alist mark-alist)) + (wl-highlight-summary-current-line nil nil t))) + (forward-line 1))) + (elmo-folder-replace-marks + folder + (list (cons wl-summary-unread-cached-mark + nil) + (cons wl-summary-unread-uncached-mark + wl-summary-read-uncached-mark) + (cons wl-summary-new-mark + wl-summary-read-uncached-mark))) (wl-summary-set-mark-modified) - (set-buffer cur-buf); why is this needed??? - (elmo-msgdb-set-mark-alist msgdb mark-alist) (wl-folder-update-unread (wl-summary-buffer-folder-name) 0) (setq wl-summary-buffer-unread-count 0) (setq wl-summary-buffer-new-count 0) @@ -1668,42 +1714,34 @@ If ARG is non-nil, checking is omitted." (buffer-read-only nil) (folder wl-summary-buffer-elmo-folder) (msgdb (wl-summary-buffer-msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) (number-alist (elmo-msgdb-get-number-alist msgdb)) (case-fold-search nil) mark number unread new-mark) -;;; (re-search-backward "^ *[0-9]+..[0-9]+/[0-9]+" nil t) ; set cursor line - (beginning-of-line) - (when (looking-at "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)") - (progn - (setq mark (wl-match-buffer 2)) - (cond - ((or (string= mark wl-summary-new-mark) - (string= mark wl-summary-unread-uncached-mark) - (string= mark wl-summary-important-mark)) - ;; noop - ) - ((string= mark wl-summary-unread-cached-mark) - (setq new-mark wl-summary-unread-uncached-mark)) - (t - (setq new-mark wl-summary-read-uncached-mark))) - (when new-mark - (setq number (string-to-int (wl-match-buffer 1))) - (delete-region (match-beginning 2) (match-end 2)) - (goto-char (match-beginning 2)) - (insert new-mark) - (elmo-file-cache-delete - (elmo-file-cache-get-path - (elmo-message-field wl-summary-buffer-elmo-folder - number - 'message-id))) - (setq mark-alist - (elmo-msgdb-mark-set mark-alist number new-mark)) - (elmo-msgdb-set-mark-alist msgdb mark-alist) - (wl-summary-set-mark-modified) - (if wl-summary-highlight - (wl-highlight-summary-current-line nil nil t)) - (set-buffer-modified-p nil))))))) + (setq mark (wl-summary-persistent-mark)) + (cond + ((or (string= mark wl-summary-new-mark) + (string= mark wl-summary-unread-uncached-mark) + (string= mark wl-summary-important-mark)) + ;; noop + ) + ((string= mark wl-summary-unread-cached-mark) + (setq new-mark wl-summary-unread-uncached-mark)) + (t + (setq new-mark wl-summary-read-uncached-mark))) + (when new-mark + (setq number (wl-summary-message-number)) + (delete-backward-char 1) + (insert new-mark) + (elmo-file-cache-delete + (elmo-file-cache-get-path + (elmo-message-field wl-summary-buffer-elmo-folder + number + 'message-id))) + (elmo-msgdb-set-mark msgdb number new-mark) + (wl-summary-set-mark-modified) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil t)) + (set-buffer-modified-p nil))))) (defun wl-summary-resume-cache-status () "Resume the cache status of all messages in the current folder." @@ -1712,7 +1750,6 @@ If ARG is non-nil, checking is omitted." (cur-buf (current-buffer)) (msgdb (wl-summary-buffer-msgdb)) (number-alist (elmo-msgdb-get-number-alist msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) (inhibit-read-only t) (buffer-read-only nil) (case-fold-search nil) @@ -1720,11 +1757,10 @@ If ARG is non-nil, checking is omitted." (message "Resuming cache status...") (save-excursion (goto-char (point-min)) - (while (re-search-forward "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)" nil t) - (setq msg (string-to-int - (wl-match-buffer 1))) - (setq mark (wl-match-buffer 2)) - (setq msgid (cdr (assq msg number-alist))) + (while (not (eobp)) + (setq msg (wl-summary-message-number)) + (setq mark (wl-summary-persistent-mark)) + (setq msgid (elmo-msgdb-get-field msgdb msg 'message-id)) (setq set-mark nil) (if (elmo-file-cache-exists-p msgid) (if (or @@ -1740,84 +1776,19 @@ If ARG is non-nil, checking is omitted." (setq set-mark wl-summary-unread-uncached-mark) ; ! -> U ))) (when set-mark - (delete-region (match-beginning 2) (match-end 2)) + (delete-backward-char 1) (insert set-mark) - (setq mark-alist - (elmo-msgdb-mark-set - mark-alist msg ; msgid - (if (string= set-mark " ") nil set-mark))) + (elmo-msgdb-set-mark msgdb msg + (if (string= set-mark " ") nil set-mark)) (if wl-summary-highlight - (wl-highlight-summary-current-line)))) + (wl-highlight-summary-current-line))) + (forward-line 1)) (wl-summary-set-mark-modified) - (set-buffer cur-buf); why is this needed??? - (elmo-msgdb-set-mark-alist msgdb mark-alist) - (wl-summary-count-unread mark-alist) + (wl-summary-count-unread) (wl-summary-update-modeline) (message "Resuming cache status...done") (set-buffer-modified-p nil)))) -(defun wl-summary-resume-marks-and-highlight () - (let* ((msgdb (wl-summary-buffer-msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) -;;; (number-alist (elmo-msgdb-get-number-alist msgdb)) - (count (count-lines (point-min)(point-max))) - (i 0) - msg-num percent smark) - (save-excursion - (goto-char (point-min)) - (message "Resuming all marks...") - (while (not (eobp)) - (setq msg-num (wl-summary-message-number)) - (setq smark (car (cdr (assq msg-num mark-alist)))) - (if (looking-at (format "^ *%s \\( \\)" msg-num)) - (progn - (goto-char (match-end 1)) - (delete-region (match-beginning 1) (match-end 1)) - (insert (or smark " ")))) - (wl-highlight-summary-current-line smark) - (when (> count elmo-display-progress-threshold) - (setq i (+ i 1)) - (setq percent (/ (* i 100) count)) - (elmo-display-progress - 'wl-summary-resume-marks-and-highlight "Resuming all marks..." - percent)) - (forward-line 1))) - (message "Resuming all marks...done"))) - -(defun wl-summary-resume-marks () - (let* ((msgdb (wl-summary-buffer-msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) - (number-alist (elmo-msgdb-get-number-alist msgdb)) - (count (length mark-alist)) - (i 0) - entity msg-num percent) - (save-excursion - (message "Resuming all marks...") - (while mark-alist - (setq entity (car mark-alist)) - (if (setq msg-num (car (rassoc (car entity) number-alist))) - (progn -;;; (goto-char (point-min)) - (if (re-search-forward (format "^ *%s \\( \\)" msg-num) nil t) - (progn - (delete-region (match-beginning 1) (match-end 1)) - (insert (or (cadr entity) - " "))) - (if (re-search-backward (format "^ *%s \\( \\)" msg-num) nil t) - (progn - (goto-char (match-end 1)) - (delete-region (match-beginning 1) (match-end 1)) - (insert (or (cadr entity) - " "))))))) - (when (> count elmo-display-progress-threshold) - (setq i (+ i 1)) - (setq percent (/ (* i 100) count)) - (elmo-display-progress - 'wl-summary-resume-marks "Resuming all marks..." - percent)) - (setq mark-alist (cdr mark-alist))) - (message "Resuming all marks...done")))) - (defun wl-summary-delete-messages-on-buffer (msgs &optional deleting-info) (interactive) (save-excursion @@ -1837,10 +1808,9 @@ If ARG is non-nil, checking is omitted." (wl-thread-delete-message (car msgs)))) (setq update-list (delq (car msgs) update-list))) (goto-char (point-min)) - (if (re-search-forward (format "^ *%d[^0-9]\\([^0-9]\\).*$" - (car msgs)) nil t) + (if (wl-summary-jump-to-msg (car msgs)) (progn - (delete-region (match-beginning 0) (match-end 0)) + (delete-region (point-at-bol) (point-at-eol)) (delete-char 1) ; delete '\n' (setq wl-summary-buffer-number-list (delq (car msgs) wl-summary-buffer-number-list))))) @@ -1856,61 +1826,26 @@ If ARG is non-nil, checking is omitted." (wl-thread-update-line-msgs (elmo-uniq-list update-list) (unless deleting-info 'no-msg)) (wl-thread-cleanup-symbols msgs2)) - (wl-summary-count-unread - (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline) (wl-folder-update-unread (wl-summary-buffer-folder-name) (+ wl-summary-buffer-unread-count wl-summary-buffer-new-count))))) -(defun wl-summary-set-as-read-mark-alist (mark-alist) - (let ((marks (list (cons wl-summary-unread-cached-mark - nil) - (cons wl-summary-unread-uncached-mark - wl-summary-read-uncached-mark) - (cons wl-summary-new-mark - wl-summary-read-uncached-mark))) - (ret-val mark-alist) - entity pair) - (while mark-alist - (setq entity (car mark-alist)) - (when (setq pair (assoc (cadr entity) marks)) - (if (elmo-message-use-cache-p wl-summary-buffer-elmo-folder - (caar mark-alist)) - (if (cdr pair) - (setcar (cdr entity) (cdr pair)) - (setq ret-val (delete entity ret-val))) - (setq ret-val (delete entity ret-val)))) - (setq mark-alist (cdr mark-alist))) - ret-val)) - -(defun wl-summary-set-status-marks (mark-alist before after) - "Set the BEFORE marks to AFTER." - (let ((ret-val mark-alist) - entity) - (while mark-alist - (setq entity (car mark-alist)) - (when (string= (cadr entity) before) - (if after - (setcar (cdr entity) after) - (setq ret-val (delete entity ret-val)))) - (setq mark-alist (cdr mark-alist))) - ret-val)) - -(defun wl-summary-set-status-marks-on-buffer (before after) - "Set the MARKS marks on buffer." +(defun wl-summary-replace-status-marks (before after) + "Replace the status marks on buffer." (interactive) (save-excursion (goto-char (point-min)) (let ((inhibit-read-only t) - (buffer-read-only nil) - (regexp (concat "^" wl-summary-buffer-number-regexp ".\\(\\%s\\)"))) - (while (re-search-forward - (format regexp (regexp-quote before)) nil t) - (delete-region (match-beginning 1) (match-end 1)) - (insert after) - (if wl-summary-highlight - (wl-highlight-summary-current-line)))))) + (buffer-read-only nil)) + (while (not (eobp)) + (when (string= (wl-summary-persistent-mark) before) + (delete-backward-char 1) + (insert after) + (if wl-summary-highlight + (wl-highlight-summary-current-line))) + (forward-line 1))))) (defun wl-summary-get-delete-folder (folder) (if (string= folder wl-trash-folder) @@ -1922,58 +1857,38 @@ If ARG is non-nil, checking is omitted." ((or (equal type 'remove) (equal type 'null)) 'null) (t;; (equal type 'trash) - wl-trash-folder))))) - -(defun wl-summary-delete-important-msgs-from-list (delete-list - mark-alist) - (let ((dlist delete-list)) - (while dlist - (if (string= wl-summary-important-mark - (car (cdr (assq (car dlist) mark-alist)))) - (setq delete-list (delete (car dlist) delete-list))) - (setq dlist (cdr dlist))) - delete-list)) - -(defun wl-summary-delete-canceled-msgs-from-list (delete-list msgdb) - (let ((dlist delete-list)) - (while dlist - (if (null (cdr (assq (car dlist) (cadr msgdb)))) - (setq delete-list (delete (car dlist) delete-list))) - (setq dlist (cdr dlist))) - delete-list)) + (let ((trash-folder (wl-folder-get-elmo-folder wl-trash-folder))) + (unless (elmo-folder-exists-p trash-folder) + (if (y-or-n-p + (format "Trash Folder %s does not exist, create it? " + wl-trash-folder)) + (elmo-folder-create trash-folder) + (error "Trash Folder is not created")))) + wl-trash-folder))))) (defun wl-summary-get-append-message-func () (if (eq wl-summary-buffer-view 'thread) 'wl-summary-insert-thread-entity -;;; 'wl-summary-insert-thread - 'wl-summary-insert-summary)) + 'wl-summary-insert-sequential)) (defun wl-summary-sort () (interactive) - (let ((sort-by (let ((input-range-list '("number" "date" "subject" "from")) - (default "date") - in) - (setq in - (completing-read - (format "Sort by (%s): " default) - (mapcar - (function (lambda (x) (cons x x))) - input-range-list))) - (if (string= in "") - default - in)))) - (if (not (member sort-by '("number" "date" "subject" "from"))) - (error "Sort by %s is not implemented" sort-by)) - (wl-summary-rescan sort-by))) + (wl-summary-rescan + (completing-read + (format "Sort by (%s): " (symbol-name wl-summary-default-sort-spec)) + (mapcar (lambda (spec) + (list (symbol-name spec))) + wl-summary-sort-specs) + nil t nil nil (symbol-name wl-summary-default-sort-spec)))) (defun wl-summary-sync-marks () "Update marks in summary." (interactive) (let ((last-progress 0) (i 0) - mark-alist unread-marks importants unreads + unread-marks importants unreads importants-in-db unreads-in-db diff diffs - mes num-ma progress) + mes progress) ;; synchronize marks. (when (not (eq (elmo-folder-type-internal wl-summary-buffer-elmo-folder) @@ -1982,31 +1897,18 @@ If ARG is non-nil, checking is omitted." (setq unread-marks (list wl-summary-unread-cached-mark wl-summary-unread-uncached-mark wl-summary-new-mark) - mark-alist (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb)) - num-ma (length mark-alist) + importants-in-db (elmo-folder-list-messages-mark-match + wl-summary-buffer-elmo-folder + (regexp-quote wl-summary-important-mark)) + unreads-in-db (elmo-folder-list-messages-mark-match + wl-summary-buffer-elmo-folder + (wl-regexp-opt unread-marks)) importants (elmo-folder-list-importants wl-summary-buffer-elmo-folder wl-summary-important-mark) unreads (elmo-folder-list-unreads wl-summary-buffer-elmo-folder unread-marks)) - (while mark-alist - (if (string= (cadr (car mark-alist)) - wl-summary-important-mark) - (setq importants-in-db (cons (car (car mark-alist)) - importants-in-db)) - (if (member (cadr (car mark-alist)) unread-marks) - (setq unreads-in-db (cons (car (car mark-alist)) - unreads-in-db)))) - (setq mark-alist (cdr mark-alist)) - (when (> num-ma elmo-display-progress-threshold) - (setq i (1+ i) - progress (/ (* i 100) num-ma)) - (if (not (eq progress last-progress)) - (elmo-display-progress 'wl-summary-sync-marks - "Updating marks..." - progress)) - (setq last-progress progress))) (setq diff (elmo-list-diff importants importants-in-db)) (setq diffs (cadr diff)) ; important-deletes (setq mes (format "Updated (-%d" (length diffs))) @@ -2024,7 +1926,7 @@ If ARG is non-nil, checking is omitted." (setq diffs (cadr diff)) (setq mes (concat mes (format "(-%d" (length diffs)))) (while diffs - (wl-summary-mark-as-read t 'no-server nil (car diffs)) + (wl-summary-mark-as-read (car diffs) 'no-folder) (setq diffs (cdr diffs))) (setq diffs (car diff)) ; unread-appends (setq mes (concat mes (format "/+%d) unread mark(s)." (length diffs)))) @@ -2042,11 +1944,11 @@ If ARG is non-nil, checking is omitted." (inhibit-read-only t) (buffer-read-only nil) gc-message - overview number-alist mark-alist + overview number-alist curp num i new-msgdb append-list delete-list crossed update-thread update-top-list - expunged mes sync-result) + expunged mes sync-result entity) (unwind-protect (progn (unless wl-summary-buffer-elmo-folder @@ -2058,7 +1960,7 @@ If ARG is non-nil, checking is omitted." ;;(setq seen-list ;;(wl-summary-flush-pending-append-operations seen-list)) (goto-char (point-max)) - (wl-folder-confirm-existence folder 'force) + (wl-folder-confirm-existence folder (elmo-folder-plugged-p folder)) (setq sync-result (elmo-folder-synchronize folder wl-summary-new-mark @@ -2085,7 +1987,7 @@ If ARG is non-nil, checking is omitted." (wl-summary-delete-messages-on-buffer delete-list "Deleting...") (message "Deleting...done")) (when new-msgdb - (wl-summary-set-status-marks-on-buffer + (wl-summary-replace-status-marks wl-summary-new-mark wl-summary-unread-uncached-mark)) (setq append-list (elmo-msgdb-get-overview new-msgdb)) @@ -2093,20 +1995,20 @@ If ARG is non-nil, checking is omitted." (setq num (length curp)) (when append-list (setq i 0) + ;; set these value for append-message-func (setq overview (elmo-msgdb-get-overview (elmo-folder-msgdb folder))) (setq number-alist (elmo-msgdb-get-number-alist (elmo-folder-msgdb folder))) - (setq mark-alist (elmo-msgdb-get-mark-alist - (elmo-folder-msgdb folder))) + (setq wl-summary-delayed-update nil) (elmo-kill-buffer wl-summary-search-buf-name) (while curp (setq entity (car curp)) (when (setq update-thread (wl-summary-append-message-func-internal - entity overview mark-alist + entity (elmo-folder-msgdb folder) (not sync-all))) (wl-append update-top-list update-thread)) (if elmo-use-database @@ -2129,7 +2031,8 @@ If ARG is non-nil, checking is omitted." (when (setq update-thread (wl-summary-append-message-func-internal (cdar wl-summary-delayed-update) - overview mark-alist (not sync-all) t)) + (elmo-folder-msgdb folder) + (not sync-all) t)) (wl-append update-top-list update-thread)) (setq wl-summary-delayed-update (cdr wl-summary-delayed-update)))) @@ -2145,7 +2048,6 @@ If ARG is non-nil, checking is omitted." (when (and sync-all (eq wl-summary-buffer-view 'thread)) (elmo-kill-buffer wl-summary-search-buf-name) (message "Inserting thread...") - (setq wl-thread-entity-cur 0) (wl-thread-insert-top) (message "Inserting thread...done")) (if elmo-use-database @@ -2186,13 +2088,10 @@ If ARG is non-nil, checking is omitted." (wl-folder-set-folder-updated (elmo-folder-name-internal folder) (list 0 - (let ((pair (wl-summary-count-unread - (elmo-msgdb-get-mark-alist - (elmo-folder-msgdb folder))))) + (let ((pair (wl-summary-count-unread))) (+ (car pair) (cdr pair))) (elmo-folder-messages folder))) (wl-summary-update-modeline) - (wl-summary-buffer-number-column-detect t) ;; (unless unset-cursor (goto-char (point-min)) @@ -2220,18 +2119,16 @@ If ARG is non-nil, checking is omitted." (buffer-read-only nil) msg-num cur-mark) - (when (looking-at "^ *\\(-?[0-9]+\\)\\([^0-9]\\)") - (setq msg-num (string-to-int (wl-match-buffer 1))) - (setq cur-mark (wl-match-buffer 2)) - (when (member cur-mark (list " " - wl-summary-score-below-mark - wl-summary-score-over-mark)) - (goto-char (match-end 1)) - (delete-region (match-beginning 2) (match-end 2)) - (insert mark) - (if wl-summary-highlight - (wl-highlight-summary-current-line nil nil t)) - (set-buffer-modified-p nil)))))) + (setq msg-num (wl-summary-message-number)) + (setq cur-mark (wl-summary-temp-mark)) + (when (member cur-mark (list " " + wl-summary-score-below-mark + wl-summary-score-over-mark)) + (delete-backward-char 1) + (insert mark) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil t)) + (set-buffer-modified-p nil))))) (defun wl-summary-get-score-mark (msg-num) (let ((score (cdr (assq msg-num wl-summary-scored)))) @@ -2242,23 +2139,19 @@ If ARG is non-nil, checking is omitted." "+"))))) (defun wl-summary-update-modeline () - (setq wl-summary-buffer-unread-status - (format " {%s}(%d new/%d unread)" - (if (eq wl-summary-buffer-view 'thread) - "T" "S") - wl-summary-buffer-new-count - (+ wl-summary-buffer-new-count - wl-summary-buffer-unread-count)))) - -(defsubst wl-summary-jump-to-msg (&optional number) + (setq wl-summary-buffer-mode-line + (funcall wl-summary-buffer-mode-line-formatter))) + +(defun wl-summary-jump-to-msg (&optional number) (interactive) (let ((num (or number (string-to-int (read-from-minibuffer "Jump to Message(No.): "))))) (setq num (int-to-string num)) (beginning-of-line) - (if (or (re-search-forward (concat "^[ \t]*" num "[^0-9]") nil t) - (re-search-backward (concat "^[ \t]*" num "[^0-9]") nil t)) + (if (or (and (re-search-forward (concat "\r" num "[^0-9]") nil t) + (progn (backward-char 1) t)) + (re-search-backward (concat "\r" num "[^0-9]") nil t)) (progn (beginning-of-line) t) nil))) @@ -2283,19 +2176,11 @@ If ARG is non-nil, checking is omitted." (defun wl-summary-message-number () (save-excursion (beginning-of-line) - (if (looking-at "^ *\\(-?[0-9]+\\)") + (if (or (re-search-forward "\r\\(-?[0-9]+\\)" (point-at-eol) t) + (re-search-forward "^ *\\(-?[0-9]+\\)" (point-at-eol) t)) (string-to-int (wl-match-buffer 1)) nil))) -(defun wl-summary-move (src dsts-msgs) - (let* ((dsts (car dsts-msgs)) ; (+foo +bar) -;;; (msgs (cdr dsts-msgs)) ; (1 2 3) -;;; (msgdb (wl-summary-buffer-msgdb)) -;;; result) - ) - (while dsts - (setq dsts (cdr dsts))))) - (defun wl-summary-delete-all-msgs () (interactive) (let ((cur-buf (current-buffer)) @@ -2422,13 +2307,15 @@ If ARG, without confirm." wl-summary-buffer-target-mark-list wl-summary-buffer-elmo-folder wl-summary-buffer-number-column - wl-summary-buffer-number-regexp + wl-summary-buffer-temp-mark-column + wl-summary-buffer-persistent-mark-column wl-summary-buffer-message-modified wl-summary-buffer-mark-modified wl-summary-buffer-thread-modified wl-summary-buffer-number-list wl-summary-buffer-msgdb - wl-summary-buffer-folder-name) + wl-summary-buffer-folder-name + wl-summary-buffer-line-formatter) (and (eq wl-summary-buffer-view 'thread) '(wl-thread-entity-hashtb wl-thread-entities @@ -2457,8 +2344,7 @@ If ARG, without confirm." (setq copy-variables (cdr copy-variables))) (switch-to-buffer buf) (kill-buffer cur-buf) - (wl-summary-count-unread - (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline) (if msg (if (eq wl-summary-buffer-view 'thread) @@ -2488,9 +2374,9 @@ If ARG, without confirm." (defun wl-summary-auto-select-msg-p (unread-msg) (and unread-msg (not (string= - (cadr (assoc unread-msg - (elmo-msgdb-get-mark-alist - (wl-summary-buffer-msgdb)))) + (elmo-msgdb-get-mark + (wl-summary-buffer-msgdb) + unread-msg) wl-summary-important-mark)))) (defsubst wl-summary-open-folder (folder) @@ -2565,7 +2451,7 @@ If ARG, without confirm." default-enable-multibyte-characters) (decode-mime-charset-region (point-min)(point-max) - wl-summary-buffer-mime-charset)) + wl-summary-buffer-mime-charset 'LF)) (when (file-exists-p view) (setq wl-summary-buffer-view (wl-summary-load-file-object view))) @@ -2577,12 +2463,15 @@ If ARG, without confirm." (elmo-folder-msgdb-path folder)))) (wl-summary-open-folder folder) (wl-summary-rescan)) - (wl-summary-count-unread - (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline))) (unless (eq wl-summary-buffer-view 'thread) (wl-summary-make-number-list)) - (wl-summary-buffer-number-column-detect t) + (when (and wl-summary-cache-use + (or (and wl-summary-check-line-format + (wl-summary-line-format-changed-p)) + (wl-summary-view-old-p))) + (wl-summary-rescan)) (wl-summary-toggle-disp-msg (if wl-summary-buffer-disp-msg 'on 'off)) (unless (and reuse-buf keep-cursor) ;(setq hilit wl-summary-highlight) @@ -2672,31 +2561,18 @@ If ARG, without confirm." ;; entity-id is unknown. (wl-folder-set-current-entity-id (wl-folder-get-entity-id entity))) + (when (and wl-summary-lazy-highlight + wl-on-xemacs) + (sit-for 0)) (unwind-protect (run-hooks 'wl-summary-prepared-hook) (set-buffer-modified-p nil)) retval)) -(defun wl-summary-summary-line-already-exists-p (parent-number buffer) - "Return the depth." - (set-buffer buffer) - (goto-char (point-max)) - (let ((depth 0)) - (when (re-search-backward (format "^ *%s..../..\(.*\)..:.. " - parent-number) nil t) - (goto-char (match-end 0)) - (while (string-match wl-thread-indent-regexp - (char-to-string - (char-after (point)))) - (setq depth (+ 1 depth)) - (forward-char)) - (/ depth wl-thread-indent-level-internal)))) - -(defun wl-summary-goto-bottom-of-current-thread () - (if (re-search-forward (concat "^" wl-summary-buffer-number-regexp - "..../..\(.*\)..:.. [[<]") nil t) - () - (goto-char (point-max)))) +(defun wl-summary-goto-previous-message-beginning () + (end-of-line) + (re-search-backward "\r\\(-?[0-9]+\\)" nil t) + (beginning-of-line)) (defun wl-summary-goto-top-of-current-thread () (wl-summary-jump-to-msg @@ -2730,22 +2606,19 @@ If ARG, without confirm." (save-excursion (beginning-of-line)(point)) (save-excursion (end-of-line)(point)) 'mouse-face nil)) - (condition-case nil ; it's dangerous, so ignore error. - (run-hooks 'wl-summary-line-inserted-hook) - (error (ding) - (message "Error in wl-summary-line-inserted-hook")))) - -(defun wl-summary-insert-summary (entity database mark-alist dummy &optional dumm) - (let ((overview-entity entity) - summary-line msg) - (setq msg (elmo-msgdb-overview-entity-get-number entity)) - (when (setq summary-line - (wl-summary-overview-create-summary-line - msg entity nil 0 mark-alist)) - (let ((inhibit-read-only t) - buffer-read-only) - (goto-char (point-max)) - (wl-summary-insert-line summary-line))))) + (ignore-errors + (run-hooks 'wl-summary-line-inserted-hook))) + +(defun wl-summary-insert-sequential (entity msgdb &rest args) + (let ((inhibit-read-only t) + buffer-read-only) + (goto-char (point-max)) + (wl-summary-insert-line + (wl-summary-create-line entity nil nil + (elmo-msgdb-get-mark + msgdb + (elmo-msgdb-overview-entity-get-number + entity)))))) (defun wl-summary-default-subject-filter (subject) (let ((case-fold-search t)) @@ -2754,8 +2627,8 @@ If ARG, without confirm." (elmo-replace-in-string subject "^\\[.*\\]" ""))) (defun wl-summary-subject-equal (subject1 subject2) - (string= (wl-summary-subject-filter-func-internal subject1) - (wl-summary-subject-filter-func-internal subject2))) + (string= (funcall wl-summary-subject-filter-function subject1) + (funcall wl-summary-subject-filter-function subject2))) (defmacro wl-summary-put-alike (alike) (` (elmo-set-hash-val (format "#%d" (wl-count-lines)) @@ -2767,6 +2640,7 @@ If ARG, without confirm." wl-summary-alike-hashtb))) (defun wl-summary-insert-headers (overview func mime-decode) + (message "Creating subject cache...") (let (ov this last alike) (buffer-disable-undo (current-buffer)) (make-local-variable 'wl-summary-alike-hashtb) @@ -2791,6 +2665,7 @@ If ARG, without confirm." elmo-mime-charset) (when (eq mime-decode 'mime) (eword-decode-region (point-min) (point-max)))) + (message "Creating subject cache...done") (run-hooks 'wl-summary-insert-headers-hook))) (defun wl-summary-search-by-subject (entity overview) @@ -2807,11 +2682,11 @@ If ARG, without confirm." overview (function (lambda (x) - (wl-summary-subject-filter-func-internal + (funcall wl-summary-subject-filter-function (elmo-msgdb-overview-entity-get-subject-no-decode x)))) t)) - (setq match (wl-summary-subject-filter-func-internal - (elmo-msgdb-overview-entity-get-subject entity))) + (setq match (funcall wl-summary-subject-filter-function + (elmo-msgdb-overview-entity-get-subject entity))) (if (string= match "") (setq match "\n")) (goto-char (point-min)) @@ -2839,95 +2714,103 @@ If ARG, without confirm." (if founds (car founds)))))) -(defun wl-summary-insert-thread-entity (entity overview mark-alist update +(defun wl-summary-insert-thread-entity (entity msgdb update &optional force-insert) - (let (update-list entity-stack) + (let* ((overview (elmo-msgdb-get-overview msgdb)) + this-id + parent-entity + parent-number + (case-fold-search t) + cur number overview2 cur-entity linked retval delayed-entity + update-list entity-stack) (while entity - (let* ((this-id (elmo-msgdb-overview-entity-get-id entity)) - (parent-entity - (elmo-msgdb-overview-get-parent-entity entity overview));; temp -;;; (parent-id (elmo-msgdb-overview-entity-get-id parent-entity)) - (parent-number (elmo-msgdb-overview-entity-get-number parent-entity)) - (case-fold-search t) - msg overview2 cur-entity linked retval delayed-entity) - (setq msg (elmo-msgdb-overview-entity-get-number entity)) + (setq this-id (elmo-msgdb-overview-entity-get-id entity) + parent-entity + (elmo-msgdb-get-parent-entity entity msgdb) + parent-number (elmo-msgdb-overview-entity-get-number + parent-entity)) + (setq number (elmo-msgdb-overview-entity-get-number entity)) + ;; If thread loop detected, set parent as nil. + (setq cur entity) + (while cur + (if (eq number (elmo-msgdb-overview-entity-get-number + (setq cur + (elmo-msgdb-get-parent-entity cur msgdb)))) + (setq parent-number nil + cur nil))) + (if (and parent-number + (not (wl-thread-get-entity parent-number)) + (not force-insert)) + ;; parent exists in overview, but not in wl-thread-entities + (progn + (wl-append wl-summary-delayed-update + (list (cons parent-number entity))) + (setq entity nil)) ;; exit loop + ;; Search parent by subject. + (when (and (null parent-number) + wl-summary-search-parent-by-subject-regexp + (string-match + wl-summary-search-parent-by-subject-regexp + (elmo-msgdb-overview-entity-get-subject entity))) + (let ((found (wl-summary-search-by-subject entity overview))) + (when (and found + (not (member found wl-summary-delayed-update))) + (setq parent-entity found) + (setq parent-number + (elmo-msgdb-overview-entity-get-number parent-entity)) + (setq linked t)))) + ;; If subject is change, divide thread. (if (and parent-number - (not (wl-thread-get-entity parent-number)) - (not force-insert)) - ;; parent is exists in overview, but not exists in wl-thread-entities - (progn - (wl-append wl-summary-delayed-update - (list (cons parent-number entity))) - (setq entity nil)) ;; exit loop - ;; Search parent by subject. - (when (and (null parent-number) - wl-summary-search-parent-by-subject-regexp - (string-match - wl-summary-search-parent-by-subject-regexp - (elmo-msgdb-overview-entity-get-subject entity))) - (let ((found (wl-summary-search-by-subject entity overview))) - (when (and found - (not (member found wl-summary-delayed-update))) - (setq parent-entity found) - (setq parent-number - (elmo-msgdb-overview-entity-get-number parent-entity)) - (setq linked t)))) - ;; If subject is change, divide thread. - (if (and parent-number - wl-summary-divide-thread-when-subject-changed - (not (wl-summary-subject-equal - (or (elmo-msgdb-overview-entity-get-subject - entity) "") - (or (elmo-msgdb-overview-entity-get-subject - parent-entity) "")))) - (setq parent-number nil)) - ;; - (setq retval - (wl-thread-insert-message entity overview mark-alist - msg parent-number update linked)) - (and retval - (wl-append update-list (list retval))) - (setq entity nil) ; exit loop - (while (setq delayed-entity (assq msg wl-summary-delayed-update)) - (setq wl-summary-delayed-update - (delete delayed-entity wl-summary-delayed-update)) - ;; update delayed message - (wl-append entity-stack (list (cdr delayed-entity))))) - (if (and (not entity) - entity-stack) - (setq entity (pop entity-stack))))) + wl-summary-divide-thread-when-subject-changed + (not (wl-summary-subject-equal + (or (elmo-msgdb-overview-entity-get-subject + entity) "") + (or (elmo-msgdb-overview-entity-get-subject + parent-entity) "")))) + (setq parent-number nil)) + (setq retval + (wl-thread-insert-message entity + number parent-number update linked)) + (and retval + (wl-append update-list (list retval))) + (setq entity nil) ; exit loop + (while (setq delayed-entity (assq number wl-summary-delayed-update)) + (setq wl-summary-delayed-update + (delq delayed-entity wl-summary-delayed-update)) + ;; update delayed message + (wl-append entity-stack (list (cdr delayed-entity))))) + (if (and (not entity) + entity-stack) + (setq entity (pop entity-stack)))) update-list)) (defun wl-summary-update-thread (entity - overview - mark-alist thr-entity parent-entity) - (let* ((depth 0) - (this-id (elmo-msgdb-overview-entity-get-id entity)) + (let* ((this-id (elmo-msgdb-overview-entity-get-id entity)) (overview-entity entity) (parent-id (elmo-msgdb-overview-entity-get-id parent-entity)) - (parent-number (elmo-msgdb-overview-entity-get-number parent-entity)) - summary-line msg subject-differ) + (number (elmo-msgdb-overview-entity-get-number entity)) + (parent-number (elmo-msgdb-overview-entity-get-number parent-entity))) (cond ((or (not parent-id) (string= this-id parent-id)) (goto-char (point-max)) (beginning-of-line)) ;; parent already exists in buffer. - ((setq depth (or (wl-summary-summary-line-already-exists-p - parent-number (current-buffer)) -1)) - (setq depth (+ 1 depth)) + ((wl-summary-jump-to-msg parent-number) (wl-thread-goto-bottom-of-sub-thread))) - (if (and (setq msg (elmo-msgdb-overview-entity-get-number entity))) - (if (setq summary-line - (wl-summary-overview-create-summary-line - msg entity parent-entity depth mark-alist - (wl-thread-maybe-get-children-num msg) - nil thr-entity)) - (let ((inhibit-read-only t) - (buffer-read-only nil)) - (wl-summary-insert-line summary-line)))))) + (let ((inhibit-read-only t) + (buffer-read-only nil)) + (wl-summary-insert-line + (wl-summary-create-line + entity + parent-entity + nil + (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) number) + (wl-thread-maybe-get-children-num number) + (wl-thread-make-indent-string thr-entity) + (wl-thread-entity-get-linked thr-entity)))))) (defun wl-summary-mark-as-unread (&optional number no-server-update @@ -2939,13 +2822,12 @@ If ARG, without confirm." (buffer-read-only nil) (folder wl-summary-buffer-elmo-folder) (msgdb (wl-summary-buffer-msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) ;;; (number-alist (elmo-msgdb-get-number-alist msgdb)) - new-mark visible mark) + new-mark visible mark cur-mark) (if number (progn (setq visible (wl-summary-jump-to-msg number)) - (unless (setq mark (cadr (assq number mark-alist))) + (unless (setq mark (elmo-msgdb-get-mark msgdb number)) (setq mark " "))) ;; interactive (setq visible t)) @@ -2954,22 +2836,18 @@ If ARG, without confirm." (message "No message.") (end-of-line) (setq eol (point)) - (re-search-backward (concat "^" wl-summary-buffer-number-regexp - "..../..")) ; set cursor line - (beginning-of-line))) + (wl-summary-goto-previous-message-beginning))) (if (or (and (not visible) ;; already exists in msgdb. - (assq number (elmo-msgdb-get-number-alist msgdb))) - (re-search-forward - (format (concat "^ *\\(" - (if number (int-to-string number) - "-?[0-9]+") - "\\)[^0-9]\\(%s\\|%s\\)") - wl-summary-read-uncached-mark - " ") eol t)) + (elmo-msgdb-overview-get-entity number msgdb)) + (progn + ;; visible. + (setq cur-mark (wl-summary-persistent-mark)) + (or (string= cur-mark " ") + (string= cur-mark wl-summary-read-uncached-mark)))) (progn - (setq number (or number (string-to-int (wl-match-buffer 1)))) - (setq mark (or mark (elmo-match-buffer 2))) + (setq number (or number (wl-summary-message-number))) + (setq mark (or mark cur-mark)) (save-match-data (setq new-mark (if (string= mark wl-summary-read-uncached-mark) @@ -2983,13 +2861,9 @@ If ARG, without confirm." (unless (elmo-folder-unmark-read folder (list number)) (error "Setting mark failed")))) (when visible - (delete-region (match-beginning 2) (match-end 2)) + (delete-backward-char 1) (insert new-mark)) - (setq mark-alist - (elmo-msgdb-mark-set mark-alist - number - new-mark)) - (elmo-msgdb-set-mark-alist msgdb mark-alist) + (elmo-msgdb-set-mark msgdb number new-mark) (unless no-modeline-update (setq wl-summary-buffer-unread-count (+ 1 wl-summary-buffer-unread-count)) @@ -3004,7 +2878,7 @@ If ARG, without confirm." (set-buffer-modified-p nil)) (defun wl-summary-delete (&optional number) - "Mark Delete mark 'D'. + "Mark a delete mark 'D'. If optional argument NUMBER is specified, mark message specified by NUMBER." (interactive) (let* ((buffer-num (wl-summary-message-number)) @@ -3040,7 +2914,8 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." sol eol rs re) (beginning-of-line) (setq sol (point)) - (end-of-line) + (search-forward "\r") + (forward-char -1) (setq eol (point)) (setq rs (next-single-property-change sol 'wl-summary-destination buf eol)) @@ -3088,12 +2963,10 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." (wl-append msglist result))) (forward-line 1))) (elmo-uniq-list msglist)) - (let* ((case-fold-search nil) - (re (format (concat wl-summary-message-regexp "%s") - (regexp-quote mark)))) - (while (re-search-forward re nil t) + (while (not (eobp)) + (when (string= (wl-summary-temp-mark) mark) (setq msglist (cons (wl-summary-message-number) msglist))) - (nreverse msglist))))))) + (forward-line 1))))))) (defun wl-summary-exec () (interactive) @@ -3240,7 +3113,14 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." (or wl-folder-completion-function (if (memq 'read-folder wl-use-folder-petname) (wl-folder-get-entity-with-petname) - wl-folder-entity-hashtb)) + (let (alist) + (mapatoms + (lambda (atom) + (setq alist + (cons (list (elmo-string + (symbol-name atom))) alist))) + wl-folder-entity-hashtb) + alist))) nil nil (or init wl-default-spec) 'wl-read-folder-hist))) (if (or (string= fld wl-default-spec) @@ -3269,7 +3149,10 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." len rs re c) (setq len (string-width folder)) (if (< len 1) () - (end-of-line) + ;;(end-of-line) + (beginning-of-line) + (search-forward "\r") + (forward-char -1) (setq re (point)) (setq c 0) (while (< c len) @@ -3366,7 +3249,8 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." (message "Force refile to %s." folder))) (if (string= folder (wl-summary-buffer-folder-name)) (error "Same folder")) - (if (or (string= folder wl-queue-folder) + (if (or (not (elmo-folder-writable-p (wl-folder-get-elmo-folder folder))) + (string= folder wl-queue-folder) (string= folder wl-draft-folder)) (error "Don't %s messages to %s" copy-or-refile folder)) ;; learn for refile. @@ -3408,8 +3292,9 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." (wl-summary-prev) (wl-summary-next))) -(defsubst wl-summary-no-auto-refile-message-p (msg mark-alist) - (member (cadr (assq msg mark-alist)) wl-summary-auto-refile-skip-marks)) +(defsubst wl-summary-no-auto-refile-message-p (msg) + (member (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) msg) + wl-summary-auto-refile-skip-marks)) (defun wl-summary-auto-refile (&optional open-all) "Set refile mark automatically according to 'wl-refile-guess-by-rule'." @@ -3420,51 +3305,44 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." open-all) (wl-thread-open-all)) (let* ((spec (wl-summary-buffer-folder-name)) - (overview (elmo-msgdb-get-overview - (wl-summary-buffer-msgdb))) - (mark-alist (elmo-msgdb-get-mark-alist - (wl-summary-buffer-msgdb))) checked-dsts (count 0) number dst thr-entity) (goto-line 1) (while (not (eobp)) (setq number (wl-summary-message-number)) - (when (and (not (wl-summary-no-auto-refile-message-p number - mark-alist)) - (setq dst - (wl-folder-get-realname - (wl-refile-guess-by-rule - (elmo-msgdb-overview-get-entity - number (wl-summary-buffer-msgdb))))) - (not (equal dst spec))) - (when (not (member dst checked-dsts)) - (wl-folder-confirm-existence (wl-folder-get-elmo-folder dst)) - (setq checked-dsts (cons dst checked-dsts))) - (if (wl-summary-refile dst number) - (incf count)) - (message "Marking...%d message(s)." count)) - (if (eq wl-summary-buffer-view 'thread) - ;; process invisible children. - (unless (wl-thread-entity-get-opened - (setq thr-entity (wl-thread-get-entity number))) - (let ((messages - (elmo-delete-if - (function - (lambda (x) - (wl-summary-no-auto-refile-message-p - x mark-alist))) - (wl-thread-entity-get-descendant thr-entity)))) - (while messages - (when (and (setq dst - (wl-refile-guess-by-rule - (elmo-msgdb-overview-get-entity - (car messages) (wl-summary-buffer-msgdb)))) - (not (equal dst spec))) - (if (wl-summary-refile dst (car messages)) - (incf count)) - (message "Marking...%d message(s)." count)) - (setq messages (cdr messages)))))) + (dolist (number (cons number + (and (eq wl-summary-buffer-view 'thread) + ;; process invisible children. + (not (wl-thread-entity-get-opened + (setq thr-entity + (wl-thread-get-entity number)))) + (wl-thread-entity-get-descendant + thr-entity)))) + (when (and (not (wl-summary-no-auto-refile-message-p + number)) + (setq dst + (wl-folder-get-realname + (wl-refile-guess-by-rule + (elmo-msgdb-overview-get-entity + number (wl-summary-buffer-msgdb))))) + (not (equal dst spec)) + (let ((pair (assoc dst checked-dsts)) + ret) + (if pair + (cdr pair) + (setq ret + (condition-case nil + (progn + (wl-folder-confirm-existence + (wl-folder-get-elmo-folder dst)) + t) + (error))) + (setq checked-dsts (cons (cons dst ret) checked-dsts)) + ret))) + (if (wl-summary-refile dst number) + (incf count)) + (message "Marking...%d message(s)." count))) (forward-line)) (if (eq count 0) (message "No message was marked.") @@ -3486,15 +3364,13 @@ If optional argument NUMBER is specified, unmark message specified by NUMBER." (setq visible (wl-summary-jump-to-msg number)) (setq visible t)) ;; Delete mark on buffer. - (when (and visible - (looking-at "^ *\\(-?[0-9]+\\)\\([^0-9]\\)")) - (goto-char (match-end 2)) - (or number - (setq number (string-to-int (wl-match-buffer 1)))) - (setq cur-mark (wl-match-buffer 2)) + (when visible + (setq cur-mark (wl-summary-temp-mark)) (if (string= cur-mark " ") () - (delete-region (match-beginning 2) (match-end 2)) + (delete-backward-char 1) + (or number + (setq number (wl-summary-message-number))) (if (setq score-mark (wl-summary-get-score-mark number)) (insert score-mark) (insert " "))) @@ -3504,7 +3380,7 @@ If optional argument NUMBER is specified, unmark message specified by NUMBER." (if wl-summary-highlight (wl-highlight-summary-current-line nil nil score-mark)) (set-buffer-modified-p nil)) - ;; Remove from temporary mark structure. + ;; Remove from temporal mark structure. (and number (wl-summary-delete-mark number))))) @@ -3553,7 +3429,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." (defun wl-summary-refile-region (beg end) - "Put copy mark on messages in the region specified by BEG and END." + "Put refile mark on messages in the region specified by BEG and END." (interactive "r") (wl-summary-refile-region-subr "refile" beg end)) @@ -3660,18 +3536,18 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." (defun wl-summary-delete-all-mark (mark) (goto-char (point-min)) - (let ((case-fold-search nil)) - (while (re-search-forward (format "^ *-?[0-9]+%s" - (regexp-quote mark)) nil t) + (while (not (eobp)) + (when (string= (wl-summary-temp-mark) mark) (wl-summary-unmark)) - (cond ((string= mark "*") - (setq wl-summary-buffer-target-mark-list nil)) - ((string= mark "D") - (setq wl-summary-buffer-delete-list nil)) - ((string= mark "O") - (setq wl-summary-buffer-copy-list nil)) - ((string= mark "o") - (setq wl-summary-buffer-refile-list nil))))) + (forward-line 1)) + (cond ((string= mark "*") + (setq wl-summary-buffer-target-mark-list nil)) + ((string= mark "D") + (setq wl-summary-buffer-delete-list nil)) + ((string= mark "O") + (setq wl-summary-buffer-copy-list nil)) + ((string= mark "o") + (setq wl-summary-buffer-refile-list nil)))) (defun wl-summary-unmark-all () "Unmark all according to what you input." @@ -3686,17 +3562,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER." (defun wl-summary-target-mark-thread () (interactive) - (let (beg end) - (end-of-line) - (wl-summary-goto-top-of-current-thread) - (wl-thread-force-open) - (setq beg (point)) - (end-of-line) - (wl-summary-goto-bottom-of-current-thread) -;;; (forward-line -1) - (beginning-of-line) - (setq end (point)) - (wl-summary-target-mark-region beg end))) + (wl-thread-call-region-func 'wl-summary-target-mark-region t)) (defun wl-summary-target-mark-msgs (msgs) "Return the number of marked messages." @@ -3776,7 +3642,7 @@ If ARG, exit virtual folder." (message "Unmarking...")) (while (not (eobp)) (wl-summary-unmark) - (forward-line)) + (forward-line 1)) (unless no-msg (message "Unmarking...done")) (setq wl-summary-buffer-target-mark-list nil) @@ -3803,38 +3669,42 @@ If ARG, exit virtual folder." (setq wl-summary-buffer-refile-list (delq pair wl-summary-buffer-refile-list)))))))) +(defsubst wl-summary-temp-mark () + "Move to the temp-mark column and return mark string." + (move-to-column wl-summary-buffer-temp-mark-column) + (buffer-substring (- (point) 1) (point))) + +(defsubst wl-summary-persistent-mark () + "Move to the persistent-mark column and return mark string." + (move-to-column wl-summary-buffer-persistent-mark-column) + (buffer-substring (- (point) 1) (point))) + (defun wl-summary-mark-line (mark) "Put MARK on current line. Return message number." (save-excursion (beginning-of-line) (let ((inhibit-read-only t) - (buffer-read-only nil) - msg-num - cur-mark) - (when (looking-at "^ *\\(-?[0-9]+\\)\\([^0-9]\\)") - (setq msg-num (string-to-int (wl-match-buffer 1))) - (setq cur-mark (wl-match-buffer 2)) - (goto-char (match-end 1)) - (delete-region (match-beginning 2) (match-end 2)) -;;; (wl-summary-delete-mark msg-num) - (insert mark) - (if wl-summary-highlight - (wl-highlight-summary-current-line nil nil t)) - (set-buffer-modified-p nil) - msg-num)))) + (buffer-read-only nil)) + (wl-summary-temp-mark) ; mark + (delete-backward-char 1) + (insert mark) + (if wl-summary-highlight + (wl-highlight-summary-current-line nil nil t)) + (set-buffer-modified-p nil)))) (defun wl-summary-target-mark-delete () (interactive) (save-excursion (goto-char (point-min)) - (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) - number mlist) - (while (re-search-forward regexp nil t) - (let (wl-summary-buffer-disp-msg) - (when (setq number (wl-summary-message-number)) - (wl-summary-delete number) - (setq wl-summary-buffer-target-mark-list - (delq number wl-summary-buffer-target-mark-list))))) + (let (number mlist) + (while (not (eobp)) + (when (string= (wl-summary-temp-mark) "*") + (let (wl-summary-buffer-disp-msg) + (when (setq number (wl-summary-message-number)) + (wl-summary-delete number) + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))))) + (forward-line 1)) (setq mlist wl-summary-buffer-target-mark-list) (while mlist (wl-append wl-summary-buffer-delete-list (list (car mlist))) @@ -3862,9 +3732,8 @@ If ARG, exit virtual folder." (when (wl-summary-jump-to-msg (car mlist)) (wl-summary-unmark) (when new-mark - (when (looking-at "^ *-?[0-9]+[^0-9]\\([^0-9]\\)") - (delete-region (match-beginning 1) (match-end 1))) - (goto-char (match-beginning 1)) + (wl-summary-persistent-mark) ; move + (delete-backward-char 1) (insert new-mark) (if wl-summary-highlight (wl-highlight-summary-current-line)) @@ -3882,34 +3751,34 @@ If ARG, exit virtual folder." (intern (format "wl-summary-buffer-%s-list" copy-or-refile))) (function (intern (format "wl-summary-%s" copy-or-refile))) + (numlist wl-summary-buffer-number-list) regexp number msgid entity folder mlist) (save-excursion - (goto-char (point-min)) - (setq regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) ;; guess by first mark - (when (re-search-forward regexp nil t) - (setq msgid (cdr (assq (setq number (wl-summary-message-number)) - (elmo-msgdb-get-number-alist - (wl-summary-buffer-msgdb)))) - entity (assoc msgid - (elmo-msgdb-get-overview - (wl-summary-buffer-msgdb)))) + (while numlist + (if (memq (car numlist) wl-summary-buffer-target-mark-list) + (setq number (car numlist) + numlist nil)) + (setq numlist (cdr numlist))) + (when number + (setq msgid (elmo-message-field wl-summary-buffer-elmo-folder + number 'message-id) + entity (elmo-msgdb-overview-get-entity + number (wl-summary-buffer-msgdb))) (if (null entity) (error "Cannot %s" copy-or-refile)) - (funcall function - (setq folder (wl-summary-read-folder - (wl-refile-guess entity) - (format "for %s" copy-or-refile))) - number) - (if number - (setq wl-summary-buffer-target-mark-list - (delq number wl-summary-buffer-target-mark-list))) - (while (re-search-forward regexp nil t) - (let (wl-summary-buffer-disp-msg) - (when (setq number (wl-summary-message-number)) - (funcall function folder number) - (setq wl-summary-buffer-target-mark-list - (delq number wl-summary-buffer-target-mark-list))))) + (setq folder (wl-summary-read-folder + (wl-refile-guess entity) + (format "for %s" copy-or-refile))) + (goto-char (point-min)) + (while (not (eobp)) + (when (string= (wl-summary-temp-mark) "*") + (let (wl-summary-buffer-disp-msg) + (when (setq number (wl-summary-message-number)) + (funcall function folder number) + (setq wl-summary-buffer-target-mark-list + (delq number wl-summary-buffer-target-mark-list))))) + (forward-line 1)) ;; process invisible messages. (setq mlist wl-summary-buffer-target-mark-list) (while mlist @@ -3920,6 +3789,28 @@ If ARG, exit virtual folder." (delq (car mlist) wl-summary-buffer-target-mark-list)) (setq mlist (cdr mlist))))))) +(defun wl-summary-next-buffer () + "Switch to next summary buffer." + (interactive) + (let ((buffers (sort (wl-collect-summary) + (lambda (buffer1 buffer2) + (string-lessp (buffer-name buffer1) + (buffer-name buffer2)))))) + (switch-to-buffer + (or (cadr (memq (current-buffer) buffers)) + (car buffers))))) + +(defun wl-summary-previous-buffer () + "Switch to previous summary buffer." + (interactive) + (let ((buffers (sort (wl-collect-summary) + (lambda (buffer1 buffer2) + (not (string-lessp (buffer-name buffer1) + (buffer-name buffer2))))))) + (switch-to-buffer + (or (cadr (memq (current-buffer) buffers)) + (car buffers))))) + (defun wl-summary-target-mark-copy () (interactive) (wl-summary-target-mark-refile-subr "copy")) @@ -3932,50 +3823,51 @@ If ARG, exit virtual folder." (interactive) (save-excursion (goto-char (point-min)) - (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) - (inhibit-read-only t) + (let ((inhibit-read-only t) (buffer-read-only nil) + wl-summary-buffer-disp-msg number mlist) - (while (re-search-forward regexp nil t) - (let (wl-summary-buffer-disp-msg) + (while (not (eobp)) + (when (string= (wl-summary-temp-mark) "*") ;; delete target-mark from buffer. - (delete-region (match-beginning 1) (match-end 1)) + (delete-backward-char 1) (insert " ") - (setq number (wl-summary-mark-as-read t)) + (setq number (wl-summary-message-number)) + (wl-summary-mark-as-read number) (if wl-summary-highlight (wl-highlight-summary-current-line)) (if number (setq wl-summary-buffer-target-mark-list - (delq number wl-summary-buffer-target-mark-list))))) + (delq number wl-summary-buffer-target-mark-list)))) + (forward-line 1)) (setq mlist wl-summary-buffer-target-mark-list) (while mlist - (wl-summary-mark-as-read t nil nil (car mlist)) + (wl-summary-mark-as-read (car mlist)) (setq wl-summary-buffer-target-mark-list (delq (car mlist) wl-summary-buffer-target-mark-list)) (setq mlist (cdr mlist))) - (wl-summary-count-unread - (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline)))) (defun wl-summary-target-mark-mark-as-unread () (interactive) (save-excursion (goto-char (point-min)) - (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) - (inhibit-read-only t) + (let ((inhibit-read-only t) (buffer-read-only nil) + wl-summary-buffer-disp-msg number mlist) - (while (re-search-forward regexp nil t) - (let (wl-summary-buffer-disp-msg) - ;; delete target-mark from buffer. - (delete-region (match-beginning 1) (match-end 1)) + (while (not (eobp)) + (when (string= (wl-summary-temp-mark) "*") + (delete-backward-char 1) (insert " ") (setq number (wl-summary-mark-as-unread)) (if wl-summary-highlight (wl-highlight-summary-current-line)) (if number (setq wl-summary-buffer-target-mark-list - (delq number wl-summary-buffer-target-mark-list))))) + (delq number wl-summary-buffer-target-mark-list)))) + (forward-line 1)) (setq mlist wl-summary-buffer-target-mark-list) (while mlist (wl-summary-mark-as-unread (car mlist)) @@ -3983,29 +3875,29 @@ If ARG, exit virtual folder." (setq wl-summary-buffer-target-mark-list (delq (car mlist) wl-summary-buffer-target-mark-list)) (setq mlist (cdr mlist))) - (wl-summary-count-unread - (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline)))) (defun wl-summary-target-mark-mark-as-important () (interactive) (save-excursion (goto-char (point-min)) - (let ((regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) - (inhibit-read-only t) + (let ((inhibit-read-only t) (buffer-read-only nil) + wl-summary-buffer-disp-msg number mlist) - (while (re-search-forward regexp nil t) - (let (wl-summary-buffer-disp-msg) + (while (not (eobp)) + (when (string= (wl-summary-temp-mark) "*") ;; delete target-mark from buffer. - (delete-region (match-beginning 1) (match-end 1)) + (delete-backward-char 1) (insert " ") (setq number (wl-summary-mark-as-important)) (if wl-summary-highlight (wl-highlight-summary-current-line)) (if number (setq wl-summary-buffer-target-mark-list - (delq number wl-summary-buffer-target-mark-list))))) + (delq number wl-summary-buffer-target-mark-list)))) + (forward-line 1)) (setq mlist wl-summary-buffer-target-mark-list) (while mlist (wl-summary-mark-as-important (car mlist)) @@ -4013,117 +3905,87 @@ If ARG, exit virtual folder." (setq wl-summary-buffer-target-mark-list (delq (car mlist) wl-summary-buffer-target-mark-list)) (setq mlist (cdr mlist))) - (wl-summary-count-unread - (elmo-msgdb-get-mark-alist (wl-summary-buffer-msgdb))) + (wl-summary-count-unread) (wl-summary-update-modeline)))) (defun wl-summary-target-mark-save () (interactive) - (save-excursion - (goto-char (point-min)) - (let ((wl-save-dir - (wl-read-directory-name "Save to directory: " - wl-temporary-file-directory)) - (regexp (concat "^" wl-summary-buffer-number-regexp "\\(\\*\\)")) - number mlist) - (if (null (file-exists-p wl-save-dir)) - (make-directory wl-save-dir)) - (while (re-search-forward regexp nil t) - (let (wl-summary-buffer-disp-msg) - (setq number (wl-summary-save t wl-save-dir)) - (wl-summary-unmark) - (if number - (setq wl-summary-buffer-target-mark-list - (delq number wl-summary-buffer-target-mark-list)))))))) + (let ((wl-save-dir + (wl-read-directory-name "Save to directory: " + wl-temporary-file-directory)) + number) + (if (null (file-exists-p wl-save-dir)) + (make-directory wl-save-dir)) + (while (setq number (car wl-summary-buffer-target-mark-list)) + (wl-thread-jump-to-msg number) + (wl-summary-save t wl-save-dir) + (wl-summary-unmark number)))) (defun wl-summary-target-mark-pick () (interactive) (wl-summary-pick wl-summary-buffer-target-mark-list 'delete)) -(defun wl-summary-mark-as-read (&optional notcrosses - leave-server-side-mark-untouched - displayed - number - cached) +(defun wl-summary-mark-as-read (&optional number no-folder-mark) (interactive) (save-excursion - (let* (eol - (inhibit-read-only t) - (buffer-read-only nil) - (folder wl-summary-buffer-elmo-folder) - (msgdb (wl-summary-buffer-msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) -;;; (number-alist (elmo-msgdb-get-number-alist msgdb)) - (case-fold-search nil) - mark stat visible uncached new-mark marked) - (if number - (progn - (setq visible (wl-summary-jump-to-msg number)) - (setq mark (cadr (assq number mark-alist)))) - ;; interactive - (setq visible t)) - (beginning-of-line) - (if (or (not visible) - (looking-at - (format "^ *\\(-?[0-9]+\\)[^0-9]\\(%s\\|%s\\|%s\\|%s\\).*$" - (regexp-quote wl-summary-read-uncached-mark) - (regexp-quote wl-summary-unread-uncached-mark) - (regexp-quote wl-summary-unread-cached-mark) - (regexp-quote wl-summary-new-mark)))) - (progn - (setq mark (or mark (wl-match-buffer 2))) - (when mark - (cond - ((string= mark wl-summary-new-mark) ; N - (setq stat 'new) - (setq uncached t)) - ((string= mark wl-summary-unread-uncached-mark) ; U - (setq stat 'unread) - (setq uncached t)) - ((string= mark wl-summary-unread-cached-mark) ; ! - (setq stat 'unread)) - (t - ;; no need to mark server. - (setq leave-server-side-mark-untouched t)))) - (setq number (or number (string-to-int (wl-match-buffer 1)))) - ;; set server side mark... - (setq new-mark (if (and uncached - (if (elmo-message-use-cache-p folder number) - (not (elmo-folder-local-p folder))) - (not cached)) - wl-summary-read-uncached-mark - nil)) - (if (not leave-server-side-mark-untouched) - (save-match-data - (setq marked (elmo-folder-mark-as-read - folder - (list number))))) - (if (or leave-server-side-mark-untouched - marked) - (progn - (cond ((eq stat 'unread) - (setq wl-summary-buffer-unread-count - (1- wl-summary-buffer-unread-count))) - ((eq stat 'new) - (setq wl-summary-buffer-new-count - (1- wl-summary-buffer-new-count)))) - (wl-summary-update-modeline) - (wl-folder-update-unread - (wl-summary-buffer-folder-name) - (+ wl-summary-buffer-unread-count - wl-summary-buffer-new-count)) - (when (or stat cached) - (when visible - (goto-char (match-end 2)) - (delete-region (match-beginning 2) (match-end 2)) - (insert (or new-mark " "))) - (setq mark-alist - (elmo-msgdb-mark-set mark-alist number new-mark)) - (elmo-msgdb-set-mark-alist msgdb mark-alist) - (wl-summary-set-mark-modified)) - (if (and visible wl-summary-highlight) - (wl-highlight-summary-current-line nil nil t))) - (if mark (message "Warning: Changing mark failed."))))) + (let ((buffer-read-only nil) + (folder wl-summary-buffer-elmo-folder) + (msgdb (wl-summary-buffer-msgdb)) + (case-fold-search nil) + cur-mark mark stat visible uncached new-mark marked) + (setq number (or number (wl-summary-message-number)) + visible (if number + (wl-summary-jump-to-msg number) + ;; interactive + t) + mark (elmo-msgdb-get-mark msgdb number)) + (cond + ((string= mark wl-summary-new-mark) ; N + (setq stat 'new)) + ((string= mark wl-summary-unread-uncached-mark) ; U + (setq stat 'unread)) + ((string= mark wl-summary-unread-cached-mark) ; ! + (setq stat 'unread)) + ((string= mark wl-summary-read-uncached-mark) ; u + (setq stat 'read)) + (t + ;; no need to mark server. + (setq no-folder-mark t))) + (setq new-mark + (if (and (if (elmo-message-use-cache-p folder number) + (not (elmo-folder-local-p folder))) + (not (elmo-file-cache-exists-p + (elmo-message-field wl-summary-buffer-elmo-folder + number 'message-id)))) + wl-summary-read-uncached-mark + nil)) + ;; folder mark. + (unless no-folder-mark + (setq marked (elmo-folder-mark-as-read folder (list number)))) + (when (or no-folder-mark marked) + (cond ((eq stat 'unread) + (setq wl-summary-buffer-unread-count + (1- wl-summary-buffer-unread-count))) + ((eq stat 'new) + (setq wl-summary-buffer-new-count + (1- wl-summary-buffer-new-count)))) + (wl-summary-update-modeline) + (wl-folder-update-unread + (wl-summary-buffer-folder-name) + (+ wl-summary-buffer-unread-count + wl-summary-buffer-new-count)) + (when stat + ;; set mark on buffer + (when visible + (unless (string= (wl-summary-persistent-mark) new-mark) + (delete-backward-char 1) + (insert (or new-mark " ")))) + ;; set msgdb mark. + (unless (string= mark new-mark) + (elmo-msgdb-set-mark msgdb number new-mark)) + (wl-summary-set-mark-modified)) + (if (and visible wl-summary-highlight) + (wl-highlight-summary-current-line nil nil t))) (set-buffer-modified-p nil) (if stat (run-hooks 'wl-summary-unread-message-hook)) @@ -4143,13 +4005,12 @@ If ARG, exit virtual folder." (buffer-read-only nil) (folder wl-summary-buffer-elmo-folder) (msgdb (wl-summary-buffer-msgdb)) - (mark-alist (elmo-msgdb-get-mark-alist msgdb)) (number-alist (elmo-msgdb-get-number-alist msgdb)) - message-id visible) + message-id visible cur-mark) (if number (progn (setq visible (wl-summary-jump-to-msg number)) - (setq mark (or mark (cadr (assq number mark-alist))))) + (setq mark (or mark (elmo-msgdb-get-mark msgdb number)))) (setq visible t)) (when visible (if (null (setq number (wl-summary-message-number))) @@ -4158,15 +4019,14 @@ If ARG, exit virtual folder." (setq visible nil)) (end-of-line) (setq eol (point)) - (re-search-backward (concat "^" wl-summary-buffer-number-regexp - "..../..") nil t)) ; set cursor line - (beginning-of-line)) + (wl-summary-goto-previous-message-beginning))) (if (or (and (not visible) - (assq number (elmo-msgdb-get-number-alist msgdb))) - (re-search-forward "^ *\\(-?[0-9]+\\)[^0-9]\\([^0-9]\\)" eol t)) + ;; already exists in msgdb. + (elmo-msgdb-overview-get-entity number msgdb)) + (setq cur-mark (wl-summary-persistent-mark))) (progn - (setq number (or number (string-to-int (wl-match-buffer 1)))) - (setq mark (or mark (wl-match-buffer 2))) + (setq number (or number (wl-summary-message-number))) + (setq mark (or mark cur-mark)) (setq message-id (elmo-message-field wl-summary-buffer-elmo-folder number @@ -4185,23 +4045,18 @@ If ARG, exit virtual folder." (elmo-file-cache-delete (elmo-file-cache-get-path message-id)))) (when visible - (delete-region (match-beginning 2) (match-end 2)) + (delete-backward-char 1) (insert " ")) - (setq mark-alist - (elmo-msgdb-mark-set mark-alist - number - nil))) + (elmo-msgdb-set-mark msgdb number nil)) ;; server side mark (save-match-data (unless no-server-update (elmo-folder-mark-as-important folder (list number)))) (when visible - (delete-region (match-beginning 2) (match-end 2)) + (delete-backward-char 1) (insert wl-summary-important-mark)) - (setq mark-alist - (elmo-msgdb-mark-set mark-alist - number - wl-summary-important-mark)) + (elmo-msgdb-set-mark msgdb number + wl-summary-important-mark) (if (eq (elmo-file-cache-exists-p message-id) 'entire) (elmo-folder-mark-as-read folder (list number)) ;; Force cache message. @@ -4209,132 +4064,180 @@ If ARG, exit virtual folder." (unless no-server-update (elmo-msgdb-global-mark-set message-id wl-summary-important-mark))) - (elmo-msgdb-set-mark-alist msgdb mark-alist) (wl-summary-set-mark-modified))) (if (and visible wl-summary-highlight) (wl-highlight-summary-current-line nil nil t)))) (set-buffer-modified-p nil) number) -(defsubst wl-summary-format-date (date-string) +;;; Summary line. +(defvar wl-summary-line-formatter nil) + +(defun wl-summary-view-old-p () + "Return non-nil when summary view cache has old format." + (save-excursion + (goto-char (point-min)) + (and wl-summary-buffer-number-list + (not (re-search-forward "\r-?[0-9]+" (point-at-eol) t))))) + +(defun wl-summary-line-format-changed-p () + "Return non-nil when summary line format is changed." + (not (string= + wl-summary-buffer-line-format + (or (elmo-object-load (expand-file-name + wl-summary-line-format-file + (elmo-folder-msgdb-path + wl-summary-buffer-elmo-folder)) + wl-summary-buffer-mime-charset) + wl-summary-buffer-line-format)))) + +(defun wl-summary-line-format-save () + "Save current summary line format." + (elmo-object-save + (expand-file-name wl-summary-line-format-file + (elmo-folder-msgdb-path + wl-summary-buffer-elmo-folder)) + wl-summary-buffer-line-format + wl-summary-buffer-mime-charset)) + +(defun wl-summary-line-number () + (wl-set-string-width + (- wl-summary-buffer-number-column) + (number-to-string + (elmo-msgdb-overview-entity-get-number wl-message-entity)))) + +(defun wl-summary-line-year () + (aref wl-datevec 0)) +(defun wl-summary-line-month () + (format "%02d" (aref wl-datevec 1))) +(defun wl-summary-line-day () + (format "%02d" (aref wl-datevec 2))) +(defun wl-summary-line-day-of-week () (condition-case nil - (let ((datevec (timezone-fix-time date-string nil - wl-summary-fix-timezone))) - (format "%02d/%02d(%s)%02d:%02d" - (aref datevec 1) - (aref datevec 2) - (elmo-date-get-week (aref datevec 0) - (aref datevec 1) - (aref datevec 2)) - (aref datevec 3) - (aref datevec 4))) - (error "??/??(??)??:??"))) - -(defun wl-summary-overview-create-summary-line (msg - entity - parent-entity - depth - mark-alist - &optional - children-num - temp-mark thr-entity - subject-differ) - (let ((wl-mime-charset wl-summary-buffer-mime-charset) - (elmo-mime-charset wl-summary-buffer-mime-charset) - no-parent before-indent - from subject parent-raw-subject parent-subject - mark line - (elmo-lang wl-summary-buffer-weekday-name-lang) - (children-num (if children-num (int-to-string children-num))) - (thr-str "") - linked) - (when thr-entity - (setq thr-str (wl-thread-make-indent-string thr-entity)) - (setq linked (wl-thread-entity-get-linked thr-entity))) - (if (string= thr-str "") + (elmo-date-get-week (aref wl-datevec 0) + (aref wl-datevec 1) + (aref wl-datevec 2)) + (error "??"))) +(defun wl-summary-line-hour () + (format "%02d" (aref wl-datevec 3))) +(defun wl-summary-line-minute () + (format "%02d" (aref wl-datevec 4))) + +(defun wl-summary-line-size () + (let ((size (elmo-msgdb-overview-entity-get-size wl-message-entity))) + (if size + (cond + ((<= 1 (/ size 1048576)) + (format "%.0fM" (/ size 1048576.0))) + ((<= 1 (/ size 1024)) + (format "%.0fK" (/ size 1024.0))) + (t (format "%dB" size))) + ""))) + +(defvar wl-summary-line-subject-minimum-length nil) +(defun wl-summary-line-subject () + (let (no-parent subject parent-raw-subject parent-subject) + (if (string= wl-thr-indent-string "") (setq no-parent t)) ; no parent - (if (and wl-summary-indent-length-limit - (< wl-summary-indent-length-limit - (string-width thr-str))) - (setq thr-str (wl-set-string-width - wl-summary-indent-length-limit - thr-str))) - (setq from - (wl-set-string-width - (if children-num - (- wl-summary-from-width (length children-num) 2) - wl-summary-from-width) - (elmo-delete-char ?\n - (wl-summary-from-func-internal - (elmo-msgdb-overview-entity-get-from entity))))) (setq subject (elmo-delete-char ?\n (or (elmo-msgdb-overview-entity-get-subject - entity) + wl-message-entity) wl-summary-no-subject-message))) (setq parent-raw-subject - (elmo-msgdb-overview-entity-get-subject parent-entity)) + (elmo-msgdb-overview-entity-get-subject wl-parent-message-entity)) (setq parent-subject (if parent-raw-subject (elmo-delete-char ?\n parent-raw-subject))) - (setq mark (or (cadr (assq msg mark-alist)) " ")) - (setq line - (concat - (setq before-indent - (format (concat "%" - (int-to-string - wl-summary-buffer-number-column) - "s%s%s%s %s") - msg - (or temp-mark " ") - mark - (wl-summary-format-date - (elmo-msgdb-overview-entity-get-date entity)) - (if thr-str thr-str ""))) - (format (if linked - "<%s > %s" - "[%s ] %s") - (if children-num - (concat "+" children-num ": " from) - (concat " " from)) - (progn - (setq subject - (if (or no-parent - (null parent-subject) - (not (wl-summary-subject-equal - subject parent-subject))) - (wl-summary-subject-func-internal subject) "")) - (if (and (not wl-summary-width) - wl-summary-subject-length-limit) - (truncate-string subject wl-summary-subject-length-limit) - subject))))) + (setq subject + (if (or no-parent + (null parent-subject) + (not (wl-summary-subject-equal + subject parent-subject))) + (funcall wl-summary-subject-function subject) + "")) + (when (and wl-summary-line-subject-minimum-length + (< (string-width subject) + wl-summary-line-subject-minimum-length)) + (while (< (string-width subject) + wl-summary-line-subject-minimum-length) + (setq subject (concat subject " ")))) + (if (and (not wl-summary-width) + wl-summary-subject-length-limit) + (truncate-string subject + wl-summary-subject-length-limit) + subject))) + +(defun wl-summary-line-from () + (elmo-delete-char ?\n + (funcall wl-summary-from-function + (elmo-msgdb-overview-entity-get-from + wl-message-entity)))) + +(defun wl-summary-line-list-info () + (let ((list-info (wl-summary-get-list-info wl-message-entity))) + (if (and (car list-info) (cdr list-info)) + (format "(%s %05d)" (car list-info) (cdr list-info)) + ""))) + +(defun wl-summary-line-list-count () + (let ((ml-count (cdr (wl-summary-get-list-info wl-message-entity)))) + (if ml-count + (format "%.0f" ml-count) + ""))) + +(defun wl-summary-line-attached () + (let ((content-type (elmo-msgdb-overview-entity-get-extra-field + wl-message-entity "content-type"))) + (if (and content-type + (string-match "multipart/mixed" content-type)) + "@" + ""))) + +(defun wl-summary-create-line (wl-message-entity + wl-parent-message-entity + wl-temp-mark + wl-persistent-mark + &optional + wl-thr-children-number + wl-thr-indent-string + wl-thr-linked) + "Create a summary line." + (let ((wl-mime-charset wl-summary-buffer-mime-charset) + (elmo-mime-charset wl-summary-buffer-mime-charset) + (elmo-lang wl-summary-buffer-weekday-name-lang) + (wl-datevec (or (ignore-errors (timezone-fix-time + (elmo-msgdb-overview-entity-get-date + wl-message-entity) + nil + wl-summary-fix-timezone)) + (make-vector 5 0))) + (entity wl-message-entity) ; backward compatibility. + line mark) + (if (and wl-thr-indent-string + wl-summary-indent-length-limit + (< wl-summary-indent-length-limit + (string-width wl-thr-indent-string))) + (setq wl-thr-indent-string (wl-set-string-width + wl-summary-indent-length-limit + wl-thr-indent-string))) + (setq line (funcall wl-summary-buffer-line-formatter)) (if wl-summary-width (setq line (wl-set-string-width - (- wl-summary-width 1) line))) + (- wl-summary-width 1) line nil + 'ignore-invalid))) + (setq line (concat line + "\r" + (number-to-string + (elmo-msgdb-overview-entity-get-number + wl-message-entity)))) (if wl-summary-highlight (wl-highlight-summary-line-string line - mark - temp-mark - thr-str)) + wl-persistent-mark + wl-temp-mark + wl-thr-indent-string)) line)) -(defsubst wl-summary-buffer-number-column-detect (update) - (let (end) - (save-excursion - (goto-char (point-min)) - (setq wl-summary-buffer-number-column - (or - (if (and update - (setq end (if (re-search-forward - "^ *-?[0-9]+[^0-9]" nil t) - (point)))) - (- end (progn (beginning-of-line) (point)) 1)) - (wl-get-assoc-list-value wl-summary-number-column-alist - (wl-summary-buffer-folder-name)) - wl-summary-default-number-column)) - (setq wl-summary-buffer-number-regexp - (wl-repeat-string "." wl-summary-buffer-number-column))))) - (defsubst wl-summary-proc-wday (wday-str year month mday) (save-match-data (if (string-match "\\([A-Z][a-z][a-z]\\).*" wday-str) @@ -4428,11 +4331,12 @@ If ARG, exit virtual folder." (cache (expand-file-name wl-summary-cache-file dir)) (view (expand-file-name wl-summary-view-file dir)) (save-view wl-summary-buffer-view) - (mark-list wl-summary-buffer-target-mark-list) - (refile-list wl-summary-buffer-refile-list) - (copy-list wl-summary-buffer-copy-list) - (delete-list wl-summary-buffer-delete-list) + (mark-list (copy-sequence wl-summary-buffer-target-mark-list)) + (refile-list (copy-sequence wl-summary-buffer-refile-list)) + (copy-list (copy-sequence wl-summary-buffer-copy-list)) + (delete-list (copy-sequence wl-summary-buffer-delete-list)) (tmp-buffer (get-buffer-create " *wl-summary-save-view-cache*")) + (temp-column wl-summary-buffer-temp-mark-column) (charset wl-summary-buffer-mime-charset)) (if (file-directory-p dir) (); ok. @@ -4441,19 +4345,27 @@ If ARG, exit virtual folder." (elmo-make-directory dir))) (if (eq save-view 'thread) (wl-thread-save-entity dir)) + (when wl-summary-check-line-format + (wl-summary-line-format-save)) (unwind-protect (progn (when (file-writable-p cache) (copy-to-buffer tmp-buffer (point-min) (point-max)) (with-current-buffer tmp-buffer (widen) - (setq wl-summary-buffer-target-mark-list mark-list + (make-local-variable 'wl-summary-highlight) + (setq wl-summary-highlight nil + wl-summary-buffer-target-mark-list mark-list wl-summary-buffer-refile-list refile-list wl-summary-buffer-copy-list copy-list - wl-summary-buffer-delete-list delete-list) - (wl-summary-delete-all-temp-marks 'no-msg) - (encode-mime-charset-region - (point-min) (point-max) charset) + wl-summary-buffer-delete-list delete-list + wl-summary-buffer-temp-mark-column temp-column) + (wl-summary-delete-all-temp-marks) + (encode-coding-region + (point-min) (point-max) + (or (mime-charset-to-coding-system charset 'LF) + ;; Mule 2 doesn't have `*ctext*unix'. + (mime-charset-to-coding-system charset))) (write-region-as-binary (point-min)(point-max) cache nil 'no-msg))) (when (file-writable-p view) ; 'thread or 'sequence @@ -4645,11 +4557,19 @@ If ARG, exit virtual folder." (defun wl-summary-next-page () (interactive) - (wl-message-next-page)) + (let ((cur-buf (current-buffer))) + (wl-summary-toggle-disp-msg 'on) + (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original) + (set-buffer cur-buf) + (wl-message-next-page)))) (defun wl-summary-prev-page () (interactive) - (wl-message-prev-page)) + (let ((cur-buf (current-buffer))) + (wl-summary-toggle-disp-msg 'on) + (when (wl-summary-set-message-buffer-or-redisplay 'ignore-original) + (set-buffer cur-buf) + (wl-message-prev-page)))) (defsubst wl-summary-no-mime-p (folder) (wl-string-match-member (elmo-folder-name-internal folder) @@ -4954,9 +4874,8 @@ Reply to author if invoked with ARG." (defun wl-summary-write () "Write a new draft from Summary." (interactive) - (wl-draft nil nil nil nil nil - nil nil nil nil nil nil (current-buffer) - nil (wl-summary-buffer-folder-name)) + (wl-draft (list (cons 'To "")) + nil nil nil nil (wl-summary-buffer-folder-name)) (run-hooks 'wl-mail-setup-hook) (mail-position-on-field "To")) @@ -4982,20 +4901,19 @@ Use function list is `wl-summary-write-current-folder-functions'." (setq func-list (cdr func-list)) (setq guess-func (car func-list)) (setq func-list nil))) - (when (null guess-func) - (error "Can't guess by folder %s" folder)) - (unless (or (stringp (nth 0 guess-list)) - (stringp (nth 1 guess-list)) - (stringp (nth 2 guess-list))) - (error "Invalid value return guess function `%s'" - (symbol-name guess-func))) - (wl-draft (nth 0 guess-list) nil nil ; To: - (nth 1 guess-list) nil ; Cc: - (nth 2 guess-list) ; Newsgroups: - nil nil nil nil nil nil nil - folder) - (run-hooks 'wl-mail-setup-hook) - (mail-position-on-field "Subject"))) + (if (null guess-func) + (wl-summary-write) + (unless (or (stringp (nth 0 guess-list)) + (stringp (nth 1 guess-list)) + (stringp (nth 2 guess-list))) + (error "Invalid value return guess function `%s'" + (symbol-name guess-func))) + (wl-draft (list (cons 'To (nth 0 guess-list)) + (cons 'Cc (nth 1 guess-list)) + (cons 'Newsgroups (nth 2 guess-list))) + nil nil nil nil folder) + (run-hooks 'wl-mail-setup-hook) + (mail-position-on-field "Subject")))) (defun wl-summary-forward (&optional without-setup-hook) "" @@ -5047,76 +4965,50 @@ Use function list is `wl-summary-write-current-folder-functions'." (if (wl-message-next-page) (wl-summary-down t))))) -(defun wl-summary-prev (&optional interactive) - "" - (interactive) +(defsubst wl-summary-cursor-move-surface (downward interactive) (if wl-summary-move-direction-toggle - (setq wl-summary-move-direction-downward nil)) - (let ((skip-mark-regexp (mapconcat - 'regexp-quote - wl-summary-skip-mark-list "")) - goto-next regex-list regex next-entity finfo) - (beginning-of-line) + (setq wl-summary-move-direction-downward downward)) + (let ((start (point)) + (skip-tmark-regexp (wl-regexp-opt wl-summary-skip-mark-list)) + (skip t) + skip-pmark-regexp goto-next next-entity finfo) (if (elmo-folder-plugged-p wl-summary-buffer-elmo-folder) - (setq regex (format "^%s[^%s]" - wl-summary-buffer-number-regexp - skip-mark-regexp)) - (setq regex (format "^%s[^%s]\\(%s\\|%s\\| \\)" - wl-summary-buffer-number-regexp - skip-mark-regexp - (regexp-quote wl-summary-unread-cached-mark) - (regexp-quote wl-summary-important-mark)))) - (unless (re-search-backward regex nil t) - (setq goto-next t)) - (beginning-of-line) - (if (not goto-next) - (progn - (if wl-summary-buffer-disp-msg - (wl-summary-redisplay))) - (if (or interactive (interactive-p)) - (if wl-summary-buffer-prev-folder-function - (funcall wl-summary-buffer-prev-folder-function) - (when wl-auto-select-next - (setq next-entity (wl-summary-get-prev-folder)) - (if next-entity - (setq finfo (wl-folder-get-entity-info next-entity)))) - (wl-ask-folder - '(lambda () (wl-summary-next-folder-or-exit next-entity)) - (format - "No more messages. Type SPC to go to %s." - (wl-summary-entity-info-msg next-entity finfo)))))))) + () + (setq skip-pmark-regexp + (wl-regexp-opt (list " " + wl-summary-unread-cached-mark + wl-summary-important-mark)))) + (while (and skip + (not (if downward (eobp) (bobp)))) + (if downward + (forward-line 1) + (forward-line -1)) + (setq skip (or (string-match skip-tmark-regexp + (save-excursion + (wl-summary-temp-mark))) + (and skip-pmark-regexp + (not (string-match + skip-pmark-regexp + (save-excursion + (wl-summary-persistent-mark)))))))) + + (if (if downward (eobp) (and (bobp) skip)) (setq goto-next t)) + (if (or (eobp) (and (bobp) skip)) + (goto-char start)) -(defun wl-summary-next (&optional interactive) - "" - (interactive) - (if wl-summary-move-direction-toggle - (setq wl-summary-move-direction-downward t)) - (let ((skip-mark-regexp (mapconcat - 'regexp-quote - wl-summary-skip-mark-list "")) - goto-next regex regex-list next-entity finfo) - (end-of-line) - (if (elmo-folder-plugged-p wl-summary-buffer-elmo-folder) - (setq regex (format "^%s[^%s]" - wl-summary-buffer-number-regexp - skip-mark-regexp)) - (setq regex (format "^%s[^%s]\\(%s\\|%s\\| \\)" - wl-summary-buffer-number-regexp - skip-mark-regexp - (regexp-quote wl-summary-unread-cached-mark) - (regexp-quote wl-summary-important-mark)))) - (unless (re-search-forward regex nil t) - (forward-line 1) - (setq goto-next t)) (beginning-of-line) + (if (not goto-next) (if wl-summary-buffer-disp-msg (wl-summary-redisplay)) - (if (or interactive (interactive-p)) + (if interactive (if wl-summary-buffer-next-folder-function (funcall wl-summary-buffer-next-folder-function) (when wl-auto-select-next - (setq next-entity (wl-summary-get-next-folder)) + (setq next-entity + (if downward + (wl-summary-get-next-folder) + (wl-summary-get-prev-folder))) (if next-entity (setq finfo (wl-folder-get-entity-info next-entity)))) (wl-ask-folder @@ -5125,6 +5017,14 @@ Use function list is `wl-summary-write-current-folder-functions'." "No more messages. Type SPC to go to %s." (wl-summary-entity-info-msg next-entity finfo)))))))) +(defun wl-summary-prev (&optional interactive) + (interactive) + (wl-summary-cursor-move-surface nil (or interactive (interactive-p)))) + +(defun wl-summary-next (&optional interactive) + (interactive) + (wl-summary-cursor-move-surface t (or interactive (interactive-p)))) + (defun wl-summary-up (&optional interactive skip-no-unread) "" (interactive) @@ -5255,7 +5155,7 @@ Use function list is `wl-summary-write-current-folder-functions'." (delete-window fld-win))) (setq wl-current-summary-buffer (current-buffer)) (wl-summary-mark-as-read - nil + num ;; not fetched, then change server-mark. (if (wl-message-redisplay folder num 'mime (or force-reload @@ -5270,11 +5170,7 @@ Use function list is `wl-summary-write-current-folder-functions'." wl-summary-buffer-elmo-folder)) (elmo-folder-plugged-p wl-summary-buffer-elmo-folder)) - 'leave)) - t ; displayed - nil - 'cached ; cached by reading. - ) + 'leave))) (setq wl-summary-buffer-current-msg num) (when wl-summary-recenter (recenter (/ (- (window-height) 2) 2)) @@ -5312,7 +5208,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (wl-message-redisplay fld num 'as-is (string= (elmo-folder-name-internal fld) wl-draft-folder)) - (wl-summary-mark-as-read nil nil t) + (wl-summary-mark-as-read num) (setq wl-summary-buffer-current-msg num) (when wl-summary-recenter (recenter (/ (- (window-height) 2) 2)) @@ -5339,7 +5235,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (if (wl-message-redisplay fld num 'all-header (string= (elmo-folder-name-internal fld) wl-draft-folder)) - (wl-summary-mark-as-read nil nil t)) + (wl-summary-mark-as-read num)) (setq wl-summary-buffer-current-msg num) (when wl-summary-recenter (recenter (/ (- (window-height) 2) 2)) @@ -5350,6 +5246,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (message "No message to display.")))) (defun wl-summary-jump-to-current-message () + "Jump into Message buffer." (interactive) (let (message-buf message-win) (if (setq message-buf wl-message-buffer) @@ -5444,6 +5341,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (wl-draft-edit-string (buffer-substring (point-min) (point-max))))))) (defun wl-summary-save (&optional arg wl-save-dir) + "Save current message to disk." (interactive) (let ((filename) (num (wl-summary-message-number))) @@ -5502,16 +5400,33 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (setq command (read-string "Shell command on message: " wl-summary-shell-command-last)) (if (y-or-n-p "Send this message to pipe? ") - (save-excursion - (wl-summary-set-message-buffer-or-redisplay) - (set-buffer (wl-message-get-original-buffer)) - (if (string= command "") - (setq command wl-summary-shell-command-last)) - (goto-char (point-min)) ; perhaps this line won't be necessary - (if prefix - (search-forward "\n\n")) - (shell-command-on-region (point) (point-max) command nil) - (setq wl-summary-shell-command-last command))))) + (wl-summary-pipe-message-subr prefix command)))) + +(defun wl-summary-target-mark-pipe (prefix command) + "Send each marked messages via pipe." + (interactive (list current-prefix-arg nil)) + (if (null wl-summary-buffer-target-mark-list) + (message "No marked message.") + (setq command (read-string "Shell command on each marked message: " + wl-summary-shell-command-last)) + (when (y-or-n-p "Send each marked message to pipe? ") + (while (car wl-summary-buffer-target-mark-list) + (let ((num (car wl-summary-buffer-target-mark-list))) + (wl-thread-jump-to-msg num) + (wl-summary-pipe-message-subr prefix command) + (wl-summary-unmark num)))))) + +(defun wl-summary-pipe-message-subr (prefix command) + (save-excursion + (wl-summary-set-message-buffer-or-redisplay) + (set-buffer (wl-message-get-original-buffer)) + (if (string= command "") + (setq command wl-summary-shell-command-last)) + (goto-char (point-min)) ; perhaps this line won't be necessary + (if prefix + (search-forward "\n\n")) + (shell-command-on-region (point) (point-max) command nil) + (setq wl-summary-shell-command-last command))) (defun wl-summary-print-message (&optional arg) (interactive "P") @@ -5530,6 +5445,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (message ""))))) (defun wl-summary-print-message-with-ps-print (&optional filename) + "Print message via ps-print." (interactive) (if (null (wl-summary-message-number)) (message "No message.") @@ -5579,6 +5495,17 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (if (featurep 'ps-print) ; ps-print is available. (fset 'wl-summary-print-message 'wl-summary-print-message-with-ps-print)) +(defun wl-summary-target-mark-print () + (interactive) + (if (null wl-summary-buffer-target-mark-list) + (message "No marked message.") + (when (y-or-n-p "Print all marked messages. OK? ") + (while (car wl-summary-buffer-target-mark-list) + (let ((num (car wl-summary-buffer-target-mark-list))) + (wl-thread-jump-to-msg num) + (wl-summary-print-message) + (wl-summary-unmark num)))))) + (defun wl-summary-folder-info-update () (let ((folder (elmo-string (wl-summary-buffer-folder-name))) (num-db (elmo-msgdb-get-number-alist