X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=wl%2Fwl-summary.el;h=afedf62fcbc318d63886f951ca9f274526d28a45;hb=298179ef92e7400bdab05f509725ebfb9672b038;hp=fafdea7c89e278b082af470a11d2a5ade00a15c3;hpb=bfabaf322d3a50fa9867c68b8869107ce8680c69;p=elisp%2Fwanderlust.git diff --git a/wl/wl-summary.el b/wl/wl-summary.el index fafdea7..afedf62 100644 --- a/wl/wl-summary.el +++ b/wl/wl-summary.el @@ -60,7 +60,7 @@ (defvar dragdrop-drop-functions) (defvar scrollbar-height) (defvar mail-reply-buffer) -(defvar elmo-global-flag-list) +(defvar elmo-global-flags) (defvar wl-summary-buffer-name "Summary") (defvar wl-summary-mode-map nil) @@ -109,6 +109,9 @@ (defvar wl-summary-buffer-line-format nil) (defvar wl-summary-buffer-mode-line-formatter nil) (defvar wl-summary-buffer-mode-line nil) +(defvar wl-summary-buffer-display-mime-mode 'mime) +(defvar wl-summary-buffer-display-all-header nil) +(defvar wl-summary-buffer-event-handler nil) (defvar wl-thread-indent-level-internal nil) (defvar wl-thread-have-younger-brother-str-internal nil) @@ -182,6 +185,9 @@ (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) +(make-variable-buffer-local 'wl-summary-buffer-display-mime-mode) +(make-variable-buffer-local 'wl-summary-buffer-display-all-header) +(make-variable-buffer-local 'wl-summary-buffer-event-handler) (defvar wl-datevec) (defvar wl-thr-indent-string) @@ -398,8 +404,8 @@ See also variable `wl-use-petname'." (define-key wl-summary-mode-map ">" 'wl-summary-display-bottom) (define-key wl-summary-mode-map "\177" 'wl-summary-prev-page) (define-key wl-summary-mode-map [backspace] 'wl-summary-prev-page) - (define-key wl-summary-mode-map "\r" 'wl-summary-next-line-content) - (define-key wl-summary-mode-map "\C-m" 'wl-summary-next-line-content) + (define-key wl-summary-mode-map "\r" 'wl-summary-enter-handler) + (define-key wl-summary-mode-map "\C-m" 'wl-summary-enter-handler) (define-key wl-summary-mode-map "/" 'wl-thread-open-close) (define-key wl-summary-mode-map "[" 'wl-thread-open-all) (define-key wl-summary-mode-map "]" 'wl-thread-close-all) @@ -417,6 +423,7 @@ See also variable `wl-use-petname'." (define-key wl-summary-mode-map "f" 'wl-summary-forward) (define-key wl-summary-mode-map "$" 'wl-summary-mark-as-important) (define-key wl-summary-mode-map "F" 'wl-summary-set-flags) + (define-key wl-summary-mode-map "\M-k" 'wl-summary-toggle-persistent-mark) (define-key wl-summary-mode-map "&" 'wl-summary-mark-as-answered) (define-key wl-summary-mode-map "@" 'wl-summary-edit-addresses) @@ -432,8 +439,8 @@ See also variable `wl-use-petname'." (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 "H" 'wl-summary-toggle-all-header) + (define-key wl-summary-mode-map "M" 'wl-summary-toggle-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) @@ -592,9 +599,10 @@ See also variable `wl-use-petname'." (goto-char beg) (while (and (< (point) end) (not (eobp))) (when (null (get-text-property (point) 'face)) - (setq number (wl-summary-message-number) - flags (elmo-message-flags wl-summary-buffer-elmo-folder - number)) + (setq number (wl-summary-message-number)) + (when number + (setq flags (elmo-message-flags wl-summary-buffer-elmo-folder + number))) (let (wl-summary-highlight) (wl-summary-update-persistent-mark number flags)) (wl-highlight-summary-current-line number flags)) @@ -612,6 +620,22 @@ See also variable `wl-use-petname'." (wl-summary-lazy-update-mark (list 'wl-summary-update-mark-window)))) +;; Handler of event from elmo-folder +(eval-and-compile + (luna-define-class wl-summary-event-handler (elmo-event-handler) + (buffer)) + (luna-define-internal-accessors 'wl-summary-event-handler)) + +(luna-define-method elmo-event-handler-flag-changed ((handler + wl-summary-event-handler) + numbers) + (with-current-buffer (wl-summary-event-handler-buffer-internal handler) + (save-excursion + (dolist (number numbers) + (when (and (wl-summary-message-visible-p number) + (wl-summary-jump-to-msg number)) + (wl-summary-update-persistent-mark number)))))) + (defun wl-status-update () (interactive) (wl-address-init)) @@ -795,6 +819,11 @@ you." (setq wl-summary-buffer-persistent (wl-folder-persistent-p (elmo-folder-name-internal folder))) (elmo-folder-set-persistent-internal folder wl-summary-buffer-persistent) + (elmo-folder-add-handler folder + (setq wl-summary-buffer-event-handler + (luna-make-entity + 'wl-summary-event-handler + :buffer (current-buffer)))) ;; process duplicates. (elmo-folder-set-process-duplicates-internal folder (cdr (elmo-string-matched-assoc @@ -837,6 +866,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." ;;;(setq default-directory (or wl-tmp-dir (expand-file-name "~/"))) (setq buffer-read-only t) (setq truncate-lines t) + (setq show-trailing-whitespace nil) ;;;(make-local-variable 'tab-width) ;;;(setq tab-width 1) (buffer-disable-undo (current-buffer)) @@ -881,12 +911,10 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (defun wl-summary-overview-entity-compare-by-from (x y) "Compare entity X and Y by from." (string< - (wl-address-header-extract-address - (or (elmo-message-entity-field x 'from t) - wl-summary-no-from-message)) - (wl-address-header-extract-address - (or (elmo-message-entity-field y 'from t) - wl-summary-no-from-message)))) + (or (elmo-message-entity-field x 'from t) + wl-summary-no-from-message) + (or (elmo-message-entity-field y 'from t) + wl-summary-no-from-message))) (defun wl-summary-overview-entity-compare-by-subject (x y) "Compare entity X and Y by subject." @@ -940,26 +968,32 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (string< (or (car list-info-x) "") (or (car list-info-y) ""))))) -(defun wl-summary-sort-by-date () - (interactive) - (wl-summary-rescan "date")) -(defun wl-summary-sort-by-number () - (interactive) - (wl-summary-rescan "number")) -(defun wl-summary-sort-by-subject () - (interactive) - (wl-summary-rescan "subject")) -(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-sort-by-size () - (interactive) - (wl-summary-rescan "size")) +(defun wl-summary-sort-by-date (reverse) + "Sort summary lines into the order by message date; argument means descending order." + (interactive "P") + (wl-summary-rescan "date" reverse)) +(defun wl-summary-sort-by-number (reverse) + "Sort summary lines into the order by message number; argument means descending order." + (interactive "P") + (wl-summary-rescan "number" reverse)) +(defun wl-summary-sort-by-subject (reverse) + "Sort summary lines into the order by subject; argument means descending order." + (interactive "P") + (wl-summary-rescan "subject" reverse)) +(defun wl-summary-sort-by-from (reverse) + "Sort summary lines into the order by from; argument means descending order." + (interactive "P") + (wl-summary-rescan "from" reverse)) +(defun wl-summary-sort-by-list-info (reverse) + "Sort summary lines into the order by mailing list info; argument means descending order." + (interactive "P") + (wl-summary-rescan "list-info" reverse)) +(defun wl-summary-sort-by-size (reverse) + "Sort summary lines into the order by message size; argument means descending order." + (interactive "P") + (wl-summary-rescan "size" reverse)) -(defun wl-summary-rescan (&optional sort-by disable-killed disable-thread) +(defun wl-summary-rescan (&optional sort-by reverse disable-killed disable-thread) "Rescan current folder without updating." (interactive) (let ((elmo-mime-charset wl-summary-buffer-mime-charset) @@ -977,13 +1011,14 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (predicate (and sort-by (intern (format "wl-summary-overview-entity-compare-by-%s" sort-by)))) + (sort-label (if reverse "Reverse sorting" "Sorting")) (i 0) num expunged) (erase-buffer) (message "Re-scanning...") (when sort-by - (message "Sorting by %s..." sort-by) + (message "%s by %s..." sort-label sort-by) (setq numbers (sort numbers (lambda (x y) @@ -991,7 +1026,8 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." predicate (elmo-message-entity wl-summary-buffer-elmo-folder x) (elmo-message-entity wl-summary-buffer-elmo-folder y))))) - (message "Sorting by %s...done" sort-by)) + (if reverse (setq numbers (nreverse numbers))) + (message "%s by %s...done" sort-label sort-by)) (setq num (length numbers)) (setq wl-thread-entity-hashtb (elmo-make-hash (* num 2)) wl-thread-entity-list nil @@ -1160,7 +1196,10 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." (progn (wl-summary-save-view) (if (or force-exit (not sticky)) - (elmo-folder-close wl-summary-buffer-elmo-folder) + (progn + (elmo-folder-close wl-summary-buffer-elmo-folder) + (elmo-folder-remove-handler wl-summary-buffer-elmo-folder + wl-summary-buffer-event-handler)) (elmo-folder-commit wl-summary-buffer-elmo-folder) (elmo-folder-check wl-summary-buffer-elmo-folder)) (if wl-use-scoring (wl-score-save))) @@ -1248,6 +1287,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'." nil wl-use-scoring))) (wl-summary-rescan nil + nil (string-match "noscore" range) (string-match "thread" range)) (and msg (wl-summary-jump-to-msg msg)))) @@ -1617,7 +1657,8 @@ If ARG is non-nil, checking is omitted." (if (null number-list) (message "No message.") (wl-summary-set-persistent-mark-internal remove 'answered - number-list) + number-list + nil nil (interactive-p)) (wl-summary-count-unread) (wl-summary-update-modeline)))) @@ -1632,7 +1673,8 @@ If ARG is non-nil, checking is omitted." 'important)))) (if (null number-list) (message "No message.") - (wl-summary-mark-as-important-internal remove number-list) + (wl-summary-set-persistent-mark-internal remove 'important number-list + nil nil (interactive-p)) (wl-summary-count-unread) (wl-summary-update-modeline)))) @@ -1643,15 +1685,10 @@ If ARG is non-nil, checking is omitted." (let ((folder wl-summary-buffer-elmo-folder) (cur-buf (current-buffer))) (message "Setting all msgs as read...") - (elmo-folder-set-flag + (elmo-folder-unset-flag folder (elmo-folder-list-flagged folder 'unread 'in-msgdb) - 'read) - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (wl-summary-update-persistent-mark) - (forward-line 1))) + 'unread) (wl-folder-update-unread (wl-summary-buffer-folder-name) 0) (setq wl-summary-buffer-unread-count 0) (setq wl-summary-buffer-new-count 0) @@ -1765,67 +1802,51 @@ This function is defined for `window-scroll-functions'" (apply 'wl-summary-insert-thread args) (apply 'wl-summary-insert-sequential args))) -(defun wl-summary-sort () - (interactive) +(defun wl-summary-sort (reverse) + "Sort summary lines into the selected order; argument means descending order." + (interactive "P") (wl-summary-rescan (completing-read - (format "Sort by (%s): " (symbol-name wl-summary-default-sort-spec)) + (format "%s by (%s): " + (if reverse "Reverse sort" "Sort") + (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)))) + nil t nil nil (symbol-name wl-summary-default-sort-spec)) + reverse)) + +(defun wl-summary-get-available-flags (&optional include-specials) + (let ((flags (elmo-uniq-list + (append elmo-global-flags + (copy-sequence elmo-preserved-flags)) + #'delq))) + (if include-specials + flags + (delq 'new (delq 'cached flags))))) (defun wl-summary-sync-marks () "Update persistent marks in summary." (interactive) (let ((mes "Updated ") diff diffs) - ;; synchronize marks. - (when (not (eq (elmo-folder-type-internal - wl-summary-buffer-elmo-folder) - 'internal)) - - (message "Updating marks...") - (dolist (flag elmo-global-flag-list) - (unless (memq flag elmo-preserved-flags) - (setq diff (elmo-list-diff (elmo-folder-list-flagged - wl-summary-buffer-elmo-folder - flag) - (elmo-folder-list-flagged - wl-summary-buffer-elmo-folder - flag 'in-msgdb))) - (setq diffs (cadr diff)) ; deletes - (setq mes (concat mes (format "-%d" (length diffs)))) - (while diffs - (wl-summary-remove-flags-internal (car diffs) - (list flag) 'no-server) - (setq diffs (cdr diffs))) - (setq diffs (car diff)) ; appends - (setq mes (concat mes (format "/+%d %s," (length diffs) flag))) - (while diffs - (wl-summary-add-flags-internal (car diffs) - (list flag) 'no-server) - (setq diffs (cdr diffs))))) - - (dolist (flag (delete 'new (delete 'cached - (copy-sequence elmo-preserved-flags)))) - (setq diff (elmo-list-diff (elmo-folder-list-flagged - wl-summary-buffer-elmo-folder - flag) - (elmo-folder-list-flagged - wl-summary-buffer-elmo-folder - flag 'in-msgdb))) - (setq diffs (cadr diff)) - (setq mes (concat mes (format "-%d" (length diffs)))) - (while diffs - (wl-summary-unset-persistent-mark flag (car diffs) 'no-modeline) - (setq diffs (cdr diffs))) - (setq diffs (car diff) - mes (concat mes (format "/+%d %s " (length diffs) flag))) - (while diffs - (wl-summary-set-persistent-mark flag (car diffs) 'no-modeline) - (setq diffs (cdr diffs)))) - (if (interactive-p) (message "%s" mes))))) + (message "Updating marks...") + (dolist (flag (wl-summary-get-available-flags)) + (setq diff (elmo-list-diff (elmo-folder-list-flagged + wl-summary-buffer-elmo-folder + flag) + (elmo-folder-list-flagged + wl-summary-buffer-elmo-folder + flag 'in-msgdb))) + (setq diffs (cadr diff)) + (setq mes (concat mes (format "-%d" (length diffs)))) + (when diffs + (wl-summary-unset-persistent-mark flag diffs 'no-modeline 'no-server)) + (setq diffs (car diff) + mes (concat mes (format "/+%d %s " (length diffs) flag))) + (when diffs + (wl-summary-set-persistent-mark flag diffs 'no-modeline 'no-server))) + (if (interactive-p) (message "%s" mes)))) (defun wl-summary-sync-update (&optional unset-cursor disable-killed @@ -2017,7 +2038,7 @@ This function is defined for `window-scroll-functions'" (funcall wl-summary-buffer-mode-line-formatter))) (defun wl-summary-jump-to-msg (&optional number) - (interactive) + (interactive "NJump to Number:") (let ((num (or number (string-to-int (read-from-minibuffer "Jump to Message(No.): "))))) @@ -2029,10 +2050,6 @@ This function is defined for `window-scroll-functions'" (progn (beginning-of-line) t) nil))) -(defun wl-summary-digit-jump (number) - (interactive "NJump to Number: ") - (wl-summary-jump-to-msg number)) - (defun wl-summary-highlight-msgs (msgs) (save-excursion (let ((len (length msgs)) @@ -2103,7 +2120,7 @@ If ARG, without confirm." (setq wl-summary-buffer-view 'thread)) (wl-summary-update-modeline) (force-mode-line-update) - (wl-summary-rescan nil nil t))) + (wl-summary-rescan nil nil nil t))) (defun wl-summary-load-file-object (filename) "Load lisp object from dir." @@ -2303,9 +2320,16 @@ If ARG, without confirm." (if other-window (delete-other-windows)) (set-buffer buf) + (when wl-summary-buffer-event-handler + (elmo-folder-remove-handler wl-summary-buffer-elmo-folder + wl-summary-buffer-event-handler)) (unless (eq major-mode 'wl-summary-mode) (wl-summary-mode)) (wl-summary-buffer-set-folder folder) + (setq wl-summary-buffer-display-mime-mode + (if (wl-summary-no-mime-p wl-summary-buffer-elmo-folder) + 'as-is + 'mime)) (setq wl-summary-buffer-disp-msg nil) (setq wl-summary-buffer-last-displayed-msg nil) (setq wl-summary-buffer-current-msg nil) @@ -2444,6 +2468,11 @@ If ARG, without confirm." (when (and wl-summary-buffer-window-scroll-functions wl-on-xemacs) (sit-for 0)) + (when (or (eq t wl-summary-force-prefetch-folder-list) + (wl-string-match-member + (elmo-folder-name-internal wl-summary-buffer-elmo-folder) + wl-summary-force-prefetch-folder-list)) + (wl-summary-force-prefetch)) (unwind-protect (run-hooks 'wl-summary-prepared-hook) (set-buffer-modified-p nil)) @@ -2727,14 +2756,20 @@ If ARG, without confirm." i)) (defun wl-summary-pick (&optional from-list delete-marks) - (interactive) + (interactive "i\nP") (save-excursion - (let* ((condition (car (elmo-parse-search-condition + (let* ((messages (or from-list + (elmo-folder-list-messages + wl-summary-buffer-elmo-folder + 'visible + 'in-msgdb) + (error "No messages"))) + (condition (car (elmo-parse-search-condition (elmo-read-search-condition wl-summary-pick-field-default)))) (result (elmo-folder-search wl-summary-buffer-elmo-folder condition - from-list)) + messages)) num) (if delete-marks (let ((mlist wl-summary-buffer-target-mark-list)) @@ -2833,7 +2868,8 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." "wl-summary-%s-cached-mark" (car priorities)) (format "wl-summary-%s-uncached-mark" (car priorities)))))) - (if (boundp var) + (if (and (boundp var) + (symbol-value var)) (symbol-value var) (if cached (downcase (substring (symbol-name (car priorities)) @@ -2844,7 +2880,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." (or mark (if (or cached (elmo-folder-local-p folder)) nil - wl-summary-read-uncached-mark)))) + wl-summary-uncached-mark)))) (defsubst wl-summary-message-mark (folder number &optional flags) "Return mark of the message." @@ -2895,8 +2931,13 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." (or (cadr (memq (current-buffer) buffers)) (car buffers))))) +(defun wl-summary-check-target-mark () + (when (null wl-summary-buffer-target-mark-list) + (error "No marked message"))) + (defun wl-summary-target-mark-mark-as-read () (interactive) + (wl-summary-check-target-mark) (save-excursion (goto-char (point-min)) (let ((inhibit-read-only t) @@ -2908,6 +2949,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." (defun wl-summary-target-mark-mark-as-unread () (interactive) + (wl-summary-check-target-mark) (save-excursion (goto-char (point-min)) (let ((inhibit-read-only t) @@ -2918,6 +2960,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." (wl-summary-unset-mark number))))) (defun wl-summary-target-mark-operation (flag &optional inverse) + (wl-summary-check-target-mark) (save-excursion (let ((inhibit-read-only t) (buffer-read-only nil) @@ -2938,6 +2981,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." (defun wl-summary-target-mark-set-flags (&optional remove) (interactive "P") + (wl-summary-check-target-mark) (save-excursion (let ((inhibit-read-only t) (buffer-read-only nil) @@ -2950,6 +2994,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." (defun wl-summary-target-mark-save () (interactive) + (wl-summary-check-target-mark) (let ((wl-save-dir (wl-read-directory-name "Save to directory: " wl-temporary-file-directory)) @@ -2963,6 +3008,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED." (defun wl-summary-target-mark-pick () (interactive) + (wl-summary-check-target-mark) (wl-summary-pick wl-summary-buffer-target-mark-list 'delete)) (defun wl-summary-update-persistent-mark (&optional number flags) @@ -2993,7 +3039,7 @@ Return non-nil if the mark is updated" (save-excursion (let ((folder wl-summary-buffer-elmo-folder) unread-message number - number-list visible) + number-list) (setq number-list (cond ((numberp number-or-numbers) (setq unread-message (elmo-message-flagged-p @@ -3015,16 +3061,13 @@ Return non-nil if the mark is updated" (if (null number-list) (message "No message.") (if inverse - (elmo-folder-unset-flag folder number-list 'read no-folder-mark) - (elmo-folder-set-flag folder number-list 'read no-folder-mark)) - (dolist (number number-list) - (setq visible (wl-summary-jump-to-msg number)) - (unless inverse - (when unread-message - (run-hooks 'wl-summary-unread-message-hook))) - ;; set mark on buffer - (when visible - (wl-summary-update-persistent-mark))) + (elmo-folder-set-flag folder number-list 'unread no-folder-mark) + (elmo-folder-unset-flag folder number-list 'unread no-folder-mark)) + (when (and unread-message + (not inverse)) + (dolist (number number-list) + (wl-summary-jump-to-msg number) + (run-hooks 'wl-summary-unread-message-hook))) (unless no-modeline-update ;; Update unread numbers. (wl-summary-count-unread) @@ -3052,13 +3095,15 @@ Return non-nil if the mark is updated" no-modeline-update)) (defsubst wl-summary-set-persistent-mark-internal (inverse - &optional flag - number-or-numbers - no-modeline-update) + flag + &optional number-or-numbers + no-modeline-update + no-server + interactive) "Set persistent mark." (save-excursion (let ((folder wl-summary-buffer-elmo-folder) - number number-list visible) + number number-list) (setq number-list (cond ((numberp number-or-numbers) (list number-or-numbers)) ((and (not (null number-or-numbers)) @@ -3069,61 +3114,88 @@ Return non-nil if the mark is updated" (list number)))) (if (null number-list) (message "No message.") - (if inverse - (elmo-folder-unset-flag folder number-list flag) - (elmo-folder-set-flag folder number-list flag)) - (dolist (number number-list) - (setq visible (wl-summary-jump-to-msg number)) - ;; set mark on buffer - (when visible - (wl-summary-update-persistent-mark))) - (unless no-modeline-update - ;; Update unread numbers. - ;; should elmo-flag-mark-as-read return unread numbers? - (wl-summary-count-unread) - (wl-summary-update-modeline) - (wl-folder-update-unread - (wl-summary-buffer-folder-name) - wl-summary-buffer-unread-count)))))) + ;; XXX Only the first element of the list is checked. + (if (elmo-message-flag-available-p folder (car number-list) flag) + (progn + (if inverse + (elmo-folder-unset-flag folder number-list flag no-server) + (elmo-folder-set-flag folder number-list flag no-server)) + (unless no-modeline-update + ;; Update unread numbers. + ;; should elmo-flag-mark-as-read return unread numbers? + (wl-summary-count-unread) + (wl-summary-update-modeline) + (wl-folder-update-unread + (wl-summary-buffer-folder-name) + wl-summary-buffer-unread-count))) + (if interactive + (error "Flag `%s' is not available in this folder" flag))))))) (defun wl-summary-unset-persistent-mark (&optional flag number-or-numbers - no-modeline-update) + no-modeline-update + no-server) "Unset persistent mark." (interactive) (when (interactive-p) - (setq flag (intern (downcase - (completing-read - "Flag: " - (mapcar (lambda (flag) - (list (capitalize (symbol-name flag)))) - elmo-preserved-flags) - nil - 'require-match))))) + (let ((completion-ignore-case t)) + (setq flag (intern (downcase + (completing-read + "Mark name: " + (mapcar (lambda (flag) + (list (capitalize (symbol-name flag)))) + (wl-summary-get-available-flags)) + nil + 'require-match)))))) (wl-summary-set-persistent-mark-internal 'inverse flag number-or-numbers - no-modeline-update)) + no-modeline-update + no-server + (interactive-p))) (defun wl-summary-set-persistent-mark (&optional flag number-or-numbers - no-modeline-update) + no-modeline-update + no-server) "Set persistent mark." (interactive) (when (interactive-p) + (let ((completion-ignore-case t)) + (setq flag (intern (downcase + (completing-read + "Mark name: " + (mapcar (lambda (flag) + (list (capitalize (symbol-name flag)))) + (wl-summary-get-available-flags)) + nil + 'require-match)))))) + (wl-summary-set-persistent-mark-internal nil + flag + number-or-numbers + no-modeline-update + no-server + (interactive-p))) + +(defun wl-summary-toggle-persistent-mark (&optional force) + "Toggle persistent mark." + (interactive "P") + (let ((completion-ignore-case t) + flag) (setq flag (intern (downcase (completing-read - "Flag: " + "Mark name: " (mapcar (lambda (flag) (list (capitalize (symbol-name flag)))) - elmo-preserved-flags) + (wl-summary-get-available-flags)) nil - 'require-match))))) - (wl-summary-set-persistent-mark-internal - nil - flag - number-or-numbers - no-modeline-update)) + 'require-match)))) + (if (and (elmo-message-flagged-p wl-summary-buffer-elmo-folder + (wl-summary-message-number) + flag) + (not force)) + (wl-summary-unset-persistent-mark flag) + (wl-summary-set-persistent-mark flag)))) (defun wl-summary-mark-as-answered (&optional number-or-numbers no-modeline-update) @@ -3135,7 +3207,9 @@ Return non-nil if the mark is updated" 'answered)) 'answered number-or-numbers - no-modeline-update)) + no-modeline-update + nil + (interactive-p))) (defun wl-summary-mark-as-unanswered (&optional number-or-numbers no-modeline-update) @@ -3160,18 +3234,20 @@ Return non-nil if the mark is updated" "Flags: " (mapcar (lambda (flag) (list (capitalize (symbol-name flag)))) - elmo-global-flag-list) + elmo-global-flags) nil nil (mapconcat (lambda (flag) (capitalize (symbol-name flag))) flags ","))))) (dolist (flag new-flags) - (unless (memq flag elmo-global-flag-list) - (if (y-or-n-p (format "Flag `%s' does not exist yet. Create?" + (unless (memq flag elmo-global-flags) + (when (elmo-local-flag-p flag) + (error "Cannot treat `%s'." flag)) + (if (y-or-n-p (format "Flag `%s' is not registered yet. Register?" (capitalize (symbol-name flag)))) - (setq elmo-global-flag-list (append - elmo-global-flag-list - (list flag))) + (setq elmo-global-flags (append + elmo-global-flags + (list flag))) (error "Stopped")))) new-flags)) @@ -3182,7 +3258,7 @@ Return non-nil if the mark is updated" remove-all) (save-excursion (let ((folder wl-summary-buffer-elmo-folder) - number number-list visible) + number number-list) (setq number-list (cond ((numberp number-or-numbers) (list number-or-numbers)) ((and (not (null number-or-numbers)) @@ -3198,92 +3274,24 @@ Return non-nil if the mark is updated" (if (null number-list) (message "No message.") (dolist (number number-list) - (elmo-message-set-global-flags folder number flags local) - (setq visible (wl-summary-jump-to-msg number)) - ;; set mark on buffer - (when visible - (wl-summary-update-persistent-mark)))) + (elmo-message-set-global-flags folder number flags local))) flags))) -(defsubst wl-summary-add-flags-internal (&optional - number-or-numbers - flags - local) - (save-excursion - (let ((folder wl-summary-buffer-elmo-folder) - set-flags msg number-list visible) - (setq number-list (cond ((numberp number-or-numbers) - (list number-or-numbers)) - ((and (not (null number-or-numbers)) - (listp number-or-numbers)) - number-or-numbers) - ((setq msg (wl-summary-message-number)) - ;; interactive - (list msg)))) - (if (null number-list) - (message "No message.") - (dolist (number number-list) - (setq set-flags - (elmo-get-global-flags - (elmo-message-flags folder number))) - (setq set-flags (nconc flags set-flags)) - (elmo-message-set-global-flags folder number set-flags local) - (setq visible (wl-summary-jump-to-msg number)) - ;; set mark on buffer - (when visible - (wl-summary-update-persistent-mark))))))) - -(defsubst wl-summary-remove-flags-internal (&optional - number-or-numbers - flags - local) - (save-excursion - (let ((folder wl-summary-buffer-elmo-folder) - set-flags msg number-list visible) - (setq number-list (cond ((numberp number-or-numbers) - (list number-or-numbers)) - ((and (not (null number-or-numbers)) - (listp number-or-numbers)) - number-or-numbers) - ((setq msg (wl-summary-message-number)) - ;; interactive - (list msg)))) - (if (null number-list) - (message "No message.") - (dolist (number number-list) - (setq set-flags (elmo-get-global-flags - (elmo-message-flags folder number))) - (dolist (flag flags) - (setq set-flags (delq flag set-flags))) - (elmo-message-set-global-flags folder number set-flags local) - (setq visible (wl-summary-jump-to-msg number)) - ;; set mark on buffer - (when visible - (wl-summary-update-persistent-mark))))))) - (defun wl-summary-set-flags (&optional remove) (interactive "P") - (if (eq 'flag (elmo-folder-type-internal wl-summary-buffer-elmo-folder)) - (error "Cannot process flags in this folder")) (wl-summary-set-flags-internal nil nil nil remove)) -(defun wl-summary-mark-as-important-internal (inverse - &optional number-or-numbers) - (if inverse - (wl-summary-remove-flags-internal number-or-numbers '(important)) - (wl-summary-add-flags-internal number-or-numbers '(important)))) - (defun wl-summary-mark-as-important (&optional prompt) (interactive "P") - (if (eq 'flag (elmo-folder-type-internal wl-summary-buffer-elmo-folder)) - (error "Cannot process flags in this folder")) (if prompt (wl-summary-set-flags-internal) - (wl-summary-mark-as-important-internal + (wl-summary-set-persistent-mark-internal (and (interactive-p) (elmo-message-flagged-p wl-summary-buffer-elmo-folder (wl-summary-message-number) - 'important))))) + 'important)) + 'important + nil nil nil (interactive-p)))) ;;; Summary line. (defvar wl-summary-line-formatter nil) @@ -3759,6 +3767,21 @@ Return non-nil if the mark is updated" ))) (run-hooks 'wl-summary-buffer-window-scroll-functions))) +(defun wl-summary-enter-handler (&optional arg) + "A command for `enter' key in the summary. +Basically, it shows next line of the message. +If optional argument ARG is specified, behave as followed. +If ARG is number, jump to the message. +Otherwise it shows previous line of the message." + (interactive "P") + (cond ((numberp arg) + (unless (wl-thread-jump-to-msg arg) + (message "Message (#%d) was not found." arg))) + (arg + (wl-summary-prev-line-content)) + (t + (wl-summary-next-line-content)))) + (defun wl-summary-next-line-content () "Show next line of the message." (interactive) @@ -3814,15 +3837,14 @@ Return t if message exists." (progn (set-buffer wl-message-buffer) t) - (if (wl-summary-no-mime-p folder) - (wl-summary-redisplay-no-mime-internal folder number) - (wl-summary-redisplay-internal folder number)) + (wl-summary-redisplay-internal folder number) (when (buffer-live-p wl-message-buffer) (set-buffer wl-message-buffer)) nil))) (defun wl-summary-target-mark-forward (&optional arg) (interactive "P") + (wl-summary-check-target-mark) (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list))) (summary-buf (current-buffer)) (wl-draft-forward t) @@ -3853,6 +3875,7 @@ Return t if message exists." (defun wl-summary-target-mark-reply-with-citation (&optional arg) (interactive "P") + (wl-summary-check-target-mark) (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list))) (summary-buf (current-buffer)) change-major-mode-hook @@ -4347,15 +4370,69 @@ Use function list is `wl-summary-write-current-folder-functions'." (wl-summary-redisplay))) (message "No last message."))) +(defun wl-summary-toggle-mime (&optional arg) + "Toggle MIME decoding. +If ARG is non-nil, ask coding-system to display the message in the current +MIME analysis mode. + +If ARG is numeric number, decode message as following: +1: Enable MIME analysis. +2: Enable MIME analysis only for headers. +3: Disable MIME analysis." + (interactive "P") + (let ((rest (memq wl-summary-buffer-display-mime-mode + wl-summary-display-mime-mode-list)) + (elmo-mime-display-as-is-coding-system + elmo-mime-display-as-is-coding-system)) + (if (numberp arg) + (setq wl-summary-buffer-display-mime-mode + (case arg + (1 'mime) + (2 'header-only) + (3 'as-is))) + (if arg + ;; Specify coding-system (doesn't change the MIME mode). + (setq elmo-mime-display-as-is-coding-system + (if (and arg (not (eq wl-summary-buffer-display-mime-mode + 'mime))) + (or (read-coding-system "Coding system: ") + elmo-mime-display-as-is-coding-system) + elmo-mime-display-as-is-coding-system)) + ;; Change the MIME mode. + (if (cadr rest) + (setq wl-summary-buffer-display-mime-mode (cadr rest)) + (setq wl-summary-buffer-display-mime-mode + (car wl-summary-display-mime-mode-list))))) + (wl-summary-redisplay arg) + (wl-summary-update-modeline) + (message "MIME decoding: %s%s" + (upcase (symbol-name wl-summary-buffer-display-mime-mode)) + (if (and arg + (not (numberp arg)) + (not (eq wl-summary-buffer-display-mime-mode + 'mime))) + (concat " (" + (symbol-name elmo-mime-display-as-is-coding-system) + ")") + "")))) + (defun wl-summary-redisplay (&optional arg) + "Redisplay message." + (interactive "P") + (wl-summary-redisplay-internal nil nil arg)) + +(defun wl-summary-toggle-all-header (&optional arg) + "Toggle displaying message with all header." (interactive "P") - (if (and (not arg) - (wl-summary-no-mime-p wl-summary-buffer-elmo-folder)) - (wl-summary-redisplay-no-mime) - (wl-summary-redisplay-internal nil nil arg))) + (setq wl-summary-buffer-display-all-header + (not wl-summary-buffer-display-all-header)) + (wl-summary-redisplay-internal nil nil arg)) -(defun wl-summary-redisplay-internal (&optional folder number force-reload) +(defun wl-summary-redisplay-internal (&optional folder number force-reload + mode all-header) (let* ((folder (or folder wl-summary-buffer-elmo-folder)) + (mode (or mode wl-summary-buffer-display-mime-mode)) + (all-header (or all-header wl-summary-buffer-display-all-header)) (num (or number (wl-summary-message-number))) (wl-mime-charset wl-summary-buffer-mime-charset) (default-mime-charset wl-summary-buffer-mime-charset) @@ -4384,7 +4461,7 @@ Use function list is `wl-summary-write-current-folder-functions'." (setq no-folder-mark ;; If cache is used, change folder-mark. (if (wl-message-redisplay folder num - 'mime + mode all-header (or force-reload (string= (elmo-folder-name-internal @@ -4418,74 +4495,6 @@ Use function list is `wl-summary-write-current-folder-functions'." (run-hooks 'wl-summary-redisplay-hook)) (message "No message to display.")))) -(defun wl-summary-redisplay-no-mime (&optional ask-coding) - "Display message without MIME decoding. -If ASK-CODING is non-nil, coding-system for the message is asked." - (interactive "P") - (let ((elmo-mime-display-as-is-coding-system - (if ask-coding - (or (read-coding-system "Coding system: ") - elmo-mime-display-as-is-coding-system) - elmo-mime-display-as-is-coding-system))) - (wl-summary-redisplay-no-mime-internal))) - -(defun wl-summary-redisplay-no-mime-internal (&optional folder number) - (let* ((fld (or folder wl-summary-buffer-elmo-folder)) - (num (or number (wl-summary-message-number))) - wl-break-pages) - (if num - (progn - (setq wl-summary-buffer-disp-msg t) - (setq wl-summary-buffer-last-displayed-msg - wl-summary-buffer-current-msg) - (setq wl-current-summary-buffer (current-buffer)) - (wl-message-redisplay fld num 'as-is - (string= (elmo-folder-name-internal fld) - wl-draft-folder)) - (when (elmo-message-use-cache-p fld num) - (elmo-message-set-cached fld num t)) - (ignore-errors - (if (elmo-message-flagged-p fld num 'unread) - (wl-summary-mark-as-read num); no-folder-mark) - (wl-summary-update-persistent-mark))) - (setq wl-summary-buffer-current-msg num) - (when wl-summary-recenter - (recenter (/ (- (window-height) 2) 2)) - (if (not wl-summary-indent-length-limit) - (wl-horizontal-recenter))) - (wl-highlight-summary-displaying) - (run-hooks 'wl-summary-redisplay-hook)) - (message "No message to display.") - (wl-ask-folder 'wl-summary-exit - "No more messages. Type SPC to go to folder mode.")))) - -(defun wl-summary-redisplay-all-header (&optional folder number) - (interactive) - (let* ((fld (or folder wl-summary-buffer-elmo-folder)) - (num (or number (wl-summary-message-number))) - (wl-mime-charset wl-summary-buffer-mime-charset) - (default-mime-charset wl-summary-buffer-mime-charset)) - (if num - (progn - (setq wl-summary-buffer-disp-msg t) - (setq wl-summary-buffer-last-displayed-msg - wl-summary-buffer-current-msg) - (setq wl-current-summary-buffer (current-buffer)) - (when (elmo-message-use-cache-p fld num) - (elmo-message-set-cached fld num t)) - (if (wl-message-redisplay fld num 'all-header - (string= (elmo-folder-name-internal fld) - wl-draft-folder)) - (wl-summary-mark-as-read num)) - (setq wl-summary-buffer-current-msg num) - (when wl-summary-recenter - (recenter (/ (- (window-height) 2) 2)) - (if (not wl-summary-indent-length-limit) - (wl-horizontal-recenter))) - (wl-highlight-summary-displaying) - (run-hooks 'wl-summary-redisplay-hook)) - (message "No message to display.")))) - (defun wl-summary-jump-to-current-message () "Jump into Message buffer." (interactive) @@ -4699,7 +4708,6 @@ If ASK-CODING is non-nil, coding-system for the message is asked." wl-break-pages) (save-excursion (wl-summary-set-message-buffer-or-redisplay) - ;; (wl-summary-redisplay-internal) (let* ((buffer (generate-new-buffer " *print*")) (entity (progn (set-buffer summary-buffer) @@ -4737,14 +4745,13 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (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)))))) + (wl-summary-check-target-mark) + (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))))) (defun wl-summary-folder-info-update () (wl-folder-set-folder-updated @@ -4764,10 +4771,11 @@ If ASK-CODING is non-nil, coding-system for the message is asked." (interactive "P") (elmo-folder-pack-numbers wl-summary-buffer-elmo-folder) (let (wl-use-scoring) - (wl-summary-rescan nil nil t))) + (wl-summary-rescan nil nil nil t))) (defun wl-summary-target-mark-uudecode () (interactive) + (wl-summary-check-target-mark) (let ((mlist (reverse wl-summary-buffer-target-mark-list)) (summary-buf (current-buffer)) (tmp-buf (get-buffer-create "*WL UUENCODE*"))