X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=elmo%2Felmo-imap4.el;h=2827172f9773cda0f012a3b3d1a7daa0a162f094;hb=fb40159a1fc3d4fb1400f8fe3befb1056bc75b8c;hp=f0d1f7a5d6b5f9666a33632785ed9e648f922bad;hpb=b7bad772865b6dae37ad7a3ea69f49570ea4da8a;p=elisp%2Fwanderlust.git diff --git a/elmo/elmo-imap4.el b/elmo/elmo-imap4.el index f0d1f7a..2827172 100644 --- a/elmo/elmo-imap4.el +++ b/elmo/elmo-imap4.el @@ -53,7 +53,7 @@ (defvar elmo-imap4-disuse-server-flag-mailbox-regexp "^#mh" ; UW imapd "Regexp to match IMAP4 mailbox names whose message flags on server should be ignored. -(Except `\\Deleted' flag).") +\(Except `\\Deleted' flag\).") (defvar elmo-imap4-overview-fetch-chop-length 200 "*Number of overviews to fetch in one request.") @@ -82,7 +82,7 @@ (defvar elmo-imap4-use-select-to-update-status nil "*Some imapd have to send select command to update status. -(ex. UW imapd 4.5-BETA?). For these imapd, you must set this variable t.") +\(ex. UW imapd 4.5-BETA?\). For these imapd, you must set this variable t.") (defvar elmo-imap4-use-modified-utf7 nil "*Use mofidied UTF-7 (rfc2060) encoding for IMAP4 folder name.") @@ -92,7 +92,7 @@ (defvar elmo-imap4-extra-namespace-alist '(("^\\({.*/nntp}\\).*$" . ".")) ; Default is for UW's remote nntp mailbox... - "Extra namespace alist. + "Extra namespace alist. A list of cons cell like: (REGEXP . DELIMITER). REGEXP should have a grouping for namespace prefix.") ;; @@ -245,7 +245,7 @@ Debug information is inserted in the buffer \"*IMAP4 DEBUG*\"") matched)) (defmacro elmo-imap4-response-error-text (response) - "Returns text of NO, BAD, BYE, response." + "Returns text of NO, BAD, BYE response." (` (nth 1 (or (elmo-imap4-response-value (, response) 'no) (elmo-imap4-response-value (, response) 'bad) (elmo-imap4-response-value (, response) 'bye))))) @@ -291,8 +291,11 @@ Returns a TAG string which is assigned to the COMMAND." (when (elmo-imap4-response-bye-p elmo-imap4-current-response) (elmo-imap4-process-bye session)) (setq elmo-imap4-current-response nil) - (if elmo-imap4-parsing - (error "IMAP process is running. Please wait (or plug again)")) + (when elmo-imap4-parsing + (message "Waiting for IMAP response...") + (accept-process-output (elmo-network-session-process-internal + session)) + (message "Waiting for IMAP response...done")) (setq elmo-imap4-parsing t) (elmo-imap4-debug "<-(%s)- %s" tag command) (while (setq token (car command-args)) @@ -354,7 +357,7 @@ TAG is the tag of the command" (elmo-imap4-response-bye-p elmo-imap4-current-response) (when (elmo-imap4-response-garbage-p elmo-imap4-current-response) - (message "Garbage response: %s" + (message "Garbage response: %s" (elmo-imap4-response-value elmo-imap4-current-response 'garbage)) @@ -474,7 +477,7 @@ If response is not `OK' response, causes error with IMAP response text." (with-current-buffer (elmo-network-session-buffer session) (setq elmo-imap4-fetch-callback nil) (setq elmo-imap4-fetch-callback-data nil)) - (elmo-imap4-send-command-wait session "check")) + (elmo-imap4-send-command session "check")) (defun elmo-imap4-atom-p (string) "Return t if STRING is an atom defined in rfc2060." @@ -607,7 +610,7 @@ BUFFER must be a single-byte buffer." (mapcar (lambda (entry) (if (and (eq 'list (car entry)) - (not (member "\\NoSelect" (nth 1 (nth 1 entry))))) + (not (elmo-string-member-ignore-case "\\Noselect" (nth 1 (nth 1 entry))))) (car (nth 1 entry)))) response))) @@ -696,9 +699,9 @@ Returns response value if selecting folder succeed. " (elmo-imap4-response-bye-p response)) (elmo-imap4-process-bye session) (unless no-error - (error (or - (elmo-imap4-response-error-text response) - (format "Select %s failed" mailbox))))))) + (error "%s" + (or (elmo-imap4-response-error-text response) + (format "Select %s failed" mailbox))))))) (and result response)))) (defun elmo-imap4-check-validity (spec validity-file) @@ -770,37 +773,39 @@ If CHOP-LENGTH is not specified, message set is not chopped." ;; ;; app-data: -;; cons of list -;; 0: new-mark 1: already-mark 2: seen-mark 3: important-mark -;; 4: seen-list -;; and result of use-flag-p. +;; cons of flag-table and result of use-flag-p. (defsubst elmo-imap4-fetch-callback-1-subr (entity flags app-data) "A msgdb entity callback function." (let* ((use-flag (cdr app-data)) (app-data (car app-data)) - (seen (member (car entity) (nth 4 app-data))) mark) - (if (member "\\Flagged" flags) - (elmo-msgdb-global-mark-set (car entity) (nth 3 app-data))) + (if (elmo-string-member-ignore-case "\\Flagged" flags) + (elmo-msgdb-global-mark-set (car entity) + elmo-msgdb-important-mark)) (if (setq mark (elmo-msgdb-global-mark-get (car entity))) - (unless (member "\\Seen" flags) + (unless (elmo-string-member-ignore-case "\\Seen" flags) (setq elmo-imap4-seen-messages (cons (elmo-msgdb-overview-entity-get-number entity) elmo-imap4-seen-messages))) (setq mark (or (if (elmo-file-cache-status (elmo-file-cache-get (car entity))) - (if (or seen - (and use-flag - (member "\\Seen" flags))) - nil - (nth 1 app-data)) - (if (or seen - (and use-flag - (member "\\Seen" flags))) - (if elmo-imap4-use-cache - (nth 2 app-data)) - (nth 0 app-data)))))) + ;; cached. + (if (elmo-string-member-ignore-case + "\\Answered" flags) + elmo-msgdb-answered-cached-mark + (if (and use-flag + (member "\\Seen" flags)) + nil + elmo-msgdb-unread-cached-mark)) + (if (elmo-string-member-ignore-case "\\Answered" flags) + elmo-msgdb-answered-uncached-mark + (if (and use-flag + (elmo-string-member-ignore-case + "\\Seen" flags)) + (if elmo-imap4-use-cache + elmo-msgdb-read-uncached-mark) + elmo-msgdb-new-mark)))))) (setq elmo-imap4-current-msgdb (elmo-msgdb-append elmo-imap4-current-msgdb @@ -1804,15 +1809,16 @@ Return nil if no complete line has arrived." (setq mailbox "inbox")) (if (eq (string-to-char mailbox) ?/) (setq mailbox (substring mailbox 1 (length mailbox)))) - (expand-file-name - mailbox + ;; don't use expand-file-name (e.g. %~/something) + (concat (expand-file-name (or (elmo-net-folder-user-internal folder) "nobody") (expand-file-name (or (elmo-net-folder-server-internal folder) "nowhere") (expand-file-name "imap" - elmo-msgdb-directory))))))) + elmo-msgdb-directory))) + "/" mailbox)))) (luna-define-method elmo-folder-status-plugged ((folder elmo-imap4-folder)) @@ -1861,6 +1867,16 @@ Return nil if no complete line has arrived." ((folder elmo-imap4-folder)) (elmo-imap4-list folder "flagged")) +(luna-define-method elmo-folder-list-answereds-plugged + ((folder elmo-imap4-folder)) + (elmo-imap4-list folder "answered")) + +(defun elmo-imap4-folder-list-any-plugged (folder) + (elmo-imap4-list folder "or answered or unseen flagged")) + +(defun elmo-imap4-folder-list-digest-plugged (folder) + (elmo-imap4-list folder "or unseen flagged")) + (luna-define-method elmo-folder-use-flag-p ((folder elmo-imap4-folder)) (not (string-match elmo-imap4-disuse-server-flag-mailbox-regexp (elmo-imap4-folder-mailbox-internal folder)))) @@ -1973,18 +1989,25 @@ Return nil if no complete line has arrived." (luna-define-method elmo-folder-writable-p ((folder elmo-imap4-folder)) t) -(luna-define-method elmo-folder-delete :before ((folder elmo-imap4-folder)) - (let ((session (elmo-imap4-get-session folder)) - msgs) - (when (elmo-imap4-folder-mailbox-internal folder) - (when (setq msgs (elmo-folder-list-messages folder)) - (elmo-folder-delete-messages folder msgs)) - (elmo-imap4-send-command-wait session "close") - (elmo-imap4-send-command-wait - session - (list "delete " - (elmo-imap4-mailbox - (elmo-imap4-folder-mailbox-internal folder))))))) +(luna-define-method elmo-folder-delete ((folder elmo-imap4-folder)) + (let ((msgs (and (elmo-folder-exists-p folder) + (elmo-folder-list-messages folder)))) + (when (yes-or-no-p (format "%sDelete msgdb and substance of \"%s\"? " + (if (> (length msgs) 0) + (format "%d msg(s) exists. " (length msgs)) + "") + (elmo-folder-name-internal folder))) + (let ((session (elmo-imap4-get-session folder))) + (when (elmo-imap4-folder-mailbox-internal folder) + (when msgs (elmo-folder-delete-messages folder msgs)) + (elmo-imap4-send-command-wait session "close") + (elmo-imap4-send-command-wait + session + (list "delete " + (elmo-imap4-mailbox + (elmo-imap4-folder-mailbox-internal folder)))))) + (elmo-msgdb-delete-path folder) + t))) (luna-define-method elmo-folder-rename-internal ((folder elmo-imap4-folder) new-folder) @@ -2064,8 +2087,12 @@ If optional argument REMOVE is non-nil, remove FLAG." (luna-define-method elmo-folder-delete-messages-plugged ((folder elmo-imap4-folder) numbers) (let ((session (elmo-imap4-get-session folder))) - (elmo-imap4-set-flag folder numbers "\\Deleted") - (elmo-imap4-send-command-wait session "expunge"))) + (elmo-imap4-session-select-mailbox + session + (elmo-imap4-folder-mailbox-internal folder)) + (unless (elmo-imap4-set-flag folder numbers "\\Deleted") + (error "Failed to set deleted flag")) + (elmo-imap4-send-command session "expunge"))) (defmacro elmo-imap4-detect-search-charset (string) (` (with-temp-buffer @@ -2075,7 +2102,7 @@ If optional argument REMOVE is non-nil, remove FLAG." (defun elmo-imap4-search-internal-primitive (folder session filter from-msgs) (let ((search-key (elmo-filter-key filter)) (imap-search-keys '("bcc" "body" "cc" "from" "subject" "to" - "larger" "smaller")) + "larger" "smaller" "mark")) (total 0) (length (length from-msgs)) charset set-list end results) @@ -2093,6 +2120,18 @@ If optional argument REMOVE is non-nil, remove FLAG." numbers))) (mapcar '(lambda (x) (delete x numbers)) rest) numbers)) + ((string= "flag" search-key) + (cond + ((string= "unread" (elmo-filter-value filter)) + (elmo-folder-list-unreads folder)) + ((string= "important" (elmo-filter-value filter)) + (elmo-folder-list-importants folder)) + ((string= "answered" (elmo-filter-value filter)) + (elmo-folder-list-answereds folder)) + ((string= "digest" (elmo-filter-value filter)) + (elmo-imap4-folder-list-digest-plugged folder)) + ((string= "any" (elmo-filter-value filter)) + (elmo-imap4-folder-list-any-plugged folder)))) ((or (string= "since" search-key) (string= "before" search-key)) (setq search-key (concat "sent" search-key) @@ -2220,7 +2259,7 @@ If optional argument REMOVE is non-nil, remove FLAG." (luna-call-next-method))) (luna-define-method elmo-folder-msgdb-create-plugged - ((folder elmo-imap4-folder) numbers &rest args) + ((folder elmo-imap4-folder) numbers flag-table) (when numbers (let ((session (elmo-imap4-get-session folder)) (headers @@ -2230,6 +2269,7 @@ If optional argument REMOVE is non-nil, remove FLAG." elmo-msgdb-extra-fields)) (total 0) (length (length numbers)) + print-length print-depth rfc2060 set-list) (setq rfc2060 (memq 'imap4rev1 (elmo-imap4-session-capability-internal @@ -2245,7 +2285,7 @@ If optional argument REMOVE is non-nil, remove FLAG." (setq elmo-imap4-current-msgdb nil elmo-imap4-seen-messages nil elmo-imap4-fetch-callback 'elmo-imap4-fetch-callback-1 - elmo-imap4-fetch-callback-data (cons args + elmo-imap4-fetch-callback-data (cons flag-table (elmo-folder-use-flag-p folder))) (while set-list @@ -2285,6 +2325,14 @@ If optional argument REMOVE is non-nil, remove FLAG." ((folder elmo-imap4-folder) numbers) (elmo-imap4-set-flag folder numbers "\\Seen")) +(luna-define-method elmo-folder-unmark-answered-plugged + ((folder elmo-imap4-folder) numbers) + (elmo-imap4-set-flag folder numbers "\\Answered" 'remove)) + +(luna-define-method elmo-folder-mark-as-answered-plugged + ((folder elmo-imap4-folder) numbers) + (elmo-imap4-set-flag folder numbers "\\Answered")) + (luna-define-method elmo-message-use-cache-p ((folder elmo-imap4-folder) number) elmo-imap4-use-cache) @@ -2377,9 +2425,9 @@ If optional argument REMOVE is non-nil, remove FLAG." (elmo-imap4-session-set-current-mailbox-internal session nil) (if (elmo-imap4-response-bye-p response) (elmo-imap4-process-bye session) - (error (or - (elmo-imap4-response-error-text response) - (format "Select %s failed" mailbox))))) + (error "%s" + (or (elmo-imap4-response-error-text response) + (format "Select %s failed" mailbox))))) (message "Selecting %s...done" (elmo-folder-name-internal folder)) (elmo-folder-set-msgdb-internal @@ -2457,7 +2505,7 @@ If optional argument REMOVE is non-nil, remove FLAG." (elmo-imap4-folder-mailbox-internal folder))))) (luna-define-method elmo-folder-append-buffer - ((folder elmo-imap4-folder) unread &optional number) + ((folder elmo-imap4-folder) &optional flag number) (if (elmo-folder-plugged-p folder) (let ((session (elmo-imap4-get-session folder)) send-buffer result) @@ -2473,13 +2521,16 @@ If optional argument REMOVE is non-nil, remove FLAG." "append " (elmo-imap4-mailbox (elmo-imap4-folder-mailbox-internal folder)) - (if unread " () " " (\\Seen) ") + (cond + ((eq flag 'read) " (\\Seen) ") + ((eq flag 'answered) " (\\Answered)") + (t " () ")) (elmo-imap4-buffer-literal send-buffer)))) (kill-buffer send-buffer)) result) ;; Unplugged (if elmo-enable-disconnected-operation - (elmo-folder-append-buffer-dop folder unread number) + (elmo-folder-append-buffer-dop folder flag number) (error "Unplugged")))) (eval-when-compile @@ -2493,8 +2544,7 @@ If optional argument REMOVE is non-nil, remove FLAG." (elmo-net-folder-user-internal (, folder2))))))) (luna-define-method elmo-folder-append-messages :around - ((folder elmo-imap4-folder) src-folder numbers unread-marks - &optional same-number) + ((folder elmo-imap4-folder) src-folder numbers &optional same-number) (if (and (eq (elmo-folder-type-internal src-folder) 'imap4) (elmo-imap4-identical-system-p folder src-folder) (elmo-folder-plugged-p folder)) @@ -2585,7 +2635,10 @@ If optional argument REMOVE is non-nil, remove FLAG." (goto-char (point-min)) (std11-field-body (symbol-name field))))) - +(luna-define-method elmo-folder-search-requires-msgdb-p ((folder + elmo-imap4-folder) + condition) + nil) (require 'product) (product-provide (provide 'elmo-imap4) (require 'elmo-version))