* mu4e: code refactoring / cleanup
This commit is contained in:
@ -29,7 +29,7 @@ dist_lisp_LISP= \
|
|||||||
mu4e-main.el \
|
mu4e-main.el \
|
||||||
mu4e-proc.el \
|
mu4e-proc.el \
|
||||||
mu4e-raw-view.el \
|
mu4e-raw-view.el \
|
||||||
mu4e-send.el \
|
mu4e-compose.el \
|
||||||
mu4e-speedbar.el \
|
mu4e-speedbar.el \
|
||||||
mu4e-vars.el \
|
mu4e-vars.el \
|
||||||
mu4e-version.el \
|
mu4e-version.el \
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
;; mu4e-send.el -- part of mu4e, the mu mail user agent for emacs
|
;; mu4e-compose.el -- part of mu4e, the mu mail user agent for emacs
|
||||||
;;
|
;;
|
||||||
;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema
|
;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema
|
||||||
|
|
||||||
@ -28,27 +28,16 @@
|
|||||||
;;; Code:
|
;;; Code:
|
||||||
;; we use some stuff from gnus..
|
;; we use some stuff from gnus..
|
||||||
(require 'cl)
|
(require 'cl)
|
||||||
|
|
||||||
(require 'mu4e-utils)
|
|
||||||
(require 'mu4e-vars)
|
|
||||||
(require 'message)
|
(require 'message)
|
||||||
(require 'mail-parse)
|
(require 'mail-parse)
|
||||||
(require 'smtpmail)
|
(require 'smtpmail)
|
||||||
|
|
||||||
|
(require 'mu4e-utils)
|
||||||
;; internal variables / constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
(require 'mu4e-vars)
|
||||||
(defconst mu4e-send-draft-name "*mu4e-draft*" "Name for draft messages.")
|
(require 'mu4e-proc)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
(defun mu4e--cite-original (msg)
|
||||||
(defun mu4e-send-user-agent ()
|
|
||||||
"Return the User-Agent string for mu4e. This is either the value
|
|
||||||
of `mu4e-user-agent', or, if not set, a string based on the versions
|
|
||||||
of mu4e and emacs."
|
|
||||||
(or mu4e-user-agent
|
|
||||||
(format "mu4e %s; emacs %s" mu4e-mu-version emacs-version)))
|
|
||||||
|
|
||||||
(defun mu4e-send-cite-original (msg)
|
|
||||||
"Cite the body text of MSG, with a \"On %s, %s wrote:\"
|
"Cite the body text of MSG, with a \"On %s, %s wrote:\"
|
||||||
line (with the %s's replaced with the date of MSG and the name
|
line (with the %s's replaced with the date of MSG and the name
|
||||||
or e-mail address of its sender (or 'someone' if nothing
|
or e-mail address of its sender (or 'someone' if nothing
|
||||||
@ -68,14 +57,13 @@ of mu4e and emacs."
|
|||||||
(replace-regexp-in-string "^"
|
(replace-regexp-in-string "^"
|
||||||
mu4e-citation-prefix body)))))
|
mu4e-citation-prefix body)))))
|
||||||
|
|
||||||
(defun mu4e-send-header (hdr val)
|
(defun mu4e--header (hdr val)
|
||||||
"Return a header line of the form HDR: VAL\n. If VAL is nil,
|
"Return a header line of the form HDR: VAL\n. If VAL is nil,
|
||||||
return nil."
|
return nil."
|
||||||
(when val
|
(when val (format "%s: %s\n" hdr val)))
|
||||||
(format "%s: %s\n" hdr val)))
|
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-send-references-create (msg)
|
(defun mu4e--refererences-construct (msg)
|
||||||
"Construct the value of the References: header based on MSG as a
|
"Construct the value of the References: header based on MSG as a
|
||||||
comma-separated string. Normally, this the concatenation of the
|
comma-separated string. Normally, this the concatenation of the
|
||||||
existing References (which may be empty) and the message-id. If the
|
existing References (which may be empty) and the message-id. If the
|
||||||
@ -90,7 +78,6 @@ return nil."
|
|||||||
refs ","))))
|
refs ","))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; determine the recipient fields for new messages
|
;; determine the recipient fields for new messages
|
||||||
@ -116,6 +103,8 @@ e-mail addresses. If LST is nil, returns nil."
|
|||||||
(downcase (or (cdr cell1) ""))
|
(downcase (or (cdr cell1) ""))
|
||||||
(downcase (or (cdr cell2) ""))))
|
(downcase (or (cdr cell2) ""))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e--create-to-lst (origmsg)
|
(defun mu4e--create-to-lst (origmsg)
|
||||||
"Create a list of address for the To: in a new message, based on
|
"Create a list of address for the To: in a new message, based on
|
||||||
the original message ORIGMSG. If the Reply-To address is set, use
|
the original message ORIGMSG. If the Reply-To address is set, use
|
||||||
@ -160,7 +149,7 @@ the original message ORIGMSG, and whether it's a reply-all."
|
|||||||
cc-lst))))
|
cc-lst))))
|
||||||
cc-lst)))
|
cc-lst)))
|
||||||
|
|
||||||
(defun mu4e--create-recipient-field (field origmsg &optional reply-all)
|
(defun mu4e--recipients-construct (field origmsg &optional reply-all)
|
||||||
"Create value (a string) for the recipient field FIELD (a
|
"Create value (a string) for the recipient field FIELD (a
|
||||||
symbol, :to or :cc), based on the original message ORIGMSG,
|
symbol, :to or :cc), based on the original message ORIGMSG,
|
||||||
and (optionally) REPLY-ALL which indicates this is a reply-to-all
|
and (optionally) REPLY-ALL which indicates this is a reply-to-all
|
||||||
@ -174,7 +163,8 @@ message. Return nil if there are no recipients for the particular field."
|
|||||||
(otherwise
|
(otherwise
|
||||||
(error "Unsupported field")))))
|
(error "Unsupported field")))))
|
||||||
|
|
||||||
(defun mu4e-send-from-create ()
|
|
||||||
|
(defun mu4e--from-construct ()
|
||||||
"Construct a value for the From:-field of the reply to MSG,
|
"Construct a value for the From:-field of the reply to MSG,
|
||||||
based on `user-full-name' and `user-mail-address'; if the latter is
|
based on `user-full-name' and `user-mail-address'; if the latter is
|
||||||
nil, function returns nil."
|
nil, function returns nil."
|
||||||
@ -185,9 +175,7 @@ nil, function returns nil."
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
|
(defun mu4e--insert-mail-header-separator ()
|
||||||
|
|
||||||
(defun mu4e-insert-mail-header-separator ()
|
|
||||||
"Insert `mail-header-separator' in the first empty line of the
|
"Insert `mail-header-separator' in the first empty line of the
|
||||||
message. message-mode needs this line to know where the headers end
|
message. message-mode needs this line to know where the headers end
|
||||||
and the body starts. Note, in `mu4e-edit-mode, we use
|
and the body starts. Note, in `mu4e-edit-mode, we use
|
||||||
@ -205,10 +193,10 @@ separator is never written to file. Also see
|
|||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(insert (concat "\n" mail-header-separator "\n"))))))
|
(insert (concat "\n" mail-header-separator "\n"))))))
|
||||||
|
|
||||||
(defun mu4e-remove-mail-header-separator ()
|
(defun mu4e--remove-mail-header-separator ()
|
||||||
"Remove `mail-header-separator; we do this before saving a
|
"Remove `mail-header-separator; we do this before saving a
|
||||||
file (and restore it afterwardds), to ensure that the separator
|
file (and restore it afterwardds), to ensure that the separator
|
||||||
never hits the disk. Also see `mu4e-insert-mail-header-separator."
|
never hits the disk. Also see `mu4e--insert-mail-header-separator."
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
;; remove the --text follows this line-- separator
|
;; remove the --text follows this line-- separator
|
||||||
@ -220,10 +208,10 @@ never hits the disk. Also see `mu4e-insert-mail-header-separator."
|
|||||||
are more than 1 (based on ORIGMSG)."
|
are more than 1 (based on ORIGMSG)."
|
||||||
(let* ((recipnum
|
(let* ((recipnum
|
||||||
(+ (length (mu4e--create-to-lst origmsg))
|
(+ (length (mu4e--create-to-lst origmsg))
|
||||||
(length (mu4e--create-cc-lst origmsg t))))
|
(length (mu4e--create-cc-lst origmsg t))))
|
||||||
(response
|
(response
|
||||||
(if (= recipnum 1)
|
(if (= recipnum 1)
|
||||||
?a ;; with one recipient, we can reply to 'all'....
|
?a ;; with one recipient, we can reply to 'all'....
|
||||||
(mu4e-read-option
|
(mu4e-read-option
|
||||||
"Reply to "
|
"Reply to "
|
||||||
`( (,(format "all %d recipients" recipnum))
|
`( (,(format "all %d recipients" recipnum))
|
||||||
@ -231,7 +219,7 @@ are more than 1 (based on ORIGMSG)."
|
|||||||
(= response ?a)))
|
(= response ?a)))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-send-create-reply (origmsg)
|
(defun mu4e--reply-construct (origmsg)
|
||||||
"Create a draft message as a reply to original message ORIGMSG."
|
"Create a draft message as a reply to original message ORIGMSG."
|
||||||
(let* ((recipnum
|
(let* ((recipnum
|
||||||
(+ (length (mu4e--create-to-lst origmsg))
|
(+ (length (mu4e--create-to-lst origmsg))
|
||||||
@ -241,58 +229,60 @@ are more than 1 (based on ORIGMSG)."
|
|||||||
(subject (or (plist-get origmsg :subject) "")))
|
(subject (or (plist-get origmsg :subject) "")))
|
||||||
(concat
|
(concat
|
||||||
|
|
||||||
(mu4e-send-header "From" (or (mu4e-send-from-create) ""))
|
(mu4e--header "From" (or (mu4e--from-construct) ""))
|
||||||
(mu4e-send-header "Reply-To" mu4e-reply-to-address)
|
(mu4e--header "Reply-To" mu4e-reply-to-address)
|
||||||
(mu4e-send-header "To" (mu4e--create-recipient-field :to origmsg))
|
(mu4e--header "To" (mu4e--recipients-construct :to origmsg))
|
||||||
(mu4e-send-header "Cc" (mu4e--create-recipient-field :cc origmsg
|
(mu4e--header "Cc" (mu4e--recipients-construct :cc origmsg
|
||||||
reply-all))
|
reply-all))
|
||||||
(mu4e-send-header "User-agent" (mu4e-send-user-agent))
|
(mu4e--header "User-agent" (mu4e-user-agent))
|
||||||
(mu4e-send-header "References" (mu4e-send-references-create origmsg))
|
(mu4e--header "References" (mu4e--refererences-construct origmsg))
|
||||||
|
|
||||||
(when old-msgid
|
(when old-msgid
|
||||||
(mu4e-send-header "In-reply-to" (format "<%s>" old-msgid)))
|
(mu4e--header "In-reply-to" (format "<%s>" old-msgid)))
|
||||||
|
|
||||||
(mu4e-send-header "Subject"
|
(mu4e--header "Subject"
|
||||||
(concat
|
(concat
|
||||||
;; if there's no Re: yet, prepend it
|
;; if there's no Re: yet, prepend it
|
||||||
(if (string-match (concat "^" mu4e-reply-prefix) subject)
|
(if (string-match (concat "^" mu4e-reply-prefix) subject)
|
||||||
"" mu4e-reply-prefix)
|
"" mu4e-reply-prefix)
|
||||||
subject))
|
subject))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
(mu4e-send-cite-original origmsg))))
|
(mu4e--cite-original origmsg))))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-send-create-forward (origmsg)
|
(defun mu4e--forward-construct (origmsg)
|
||||||
"Create a draft forward message for original message ORIGMSG."
|
"Create a draft forward message for original message ORIGMSG."
|
||||||
|
|
||||||
(let ((subject
|
(let ((subject
|
||||||
(or (plist-get origmsg :subject) "")))
|
(or (plist-get origmsg :subject) "")))
|
||||||
(concat
|
(concat
|
||||||
(mu4e-send-header "From" (or (mu4e-send-from-create) ""))
|
(mu4e--header "From" (or (mu4e--from-construct) ""))
|
||||||
(mu4e-send-header "Reply-To" mu4e-reply-to-address)
|
(mu4e--header "Reply-To" mu4e-reply-to-address)
|
||||||
(mu4e-send-header "To" "")
|
(mu4e--header "To" "")
|
||||||
(mu4e-send-header "User-agent" (mu4e-send-user-agent))
|
(mu4e--header "User-agent" (mu4e-user-agent))
|
||||||
(mu4e-send-header "References" (mu4e-send-references-create origmsg))
|
(mu4e--header "References" (mu4e--refererences-construct origmsg))
|
||||||
(mu4e-send-header "Subject"
|
(mu4e--header "Subject"
|
||||||
(concat
|
(concat
|
||||||
;; if there's no Re: yet, prepend it
|
;; if there's no Re: yet, prepend it
|
||||||
(if (string-match (concat "^" mu4e-forward-prefix) subject)
|
(if (string-match (concat "^" mu4e-forward-prefix) subject)
|
||||||
"" mu4e-forward-prefix)
|
"" mu4e-forward-prefix)
|
||||||
subject))
|
subject))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
(mu4e-send-cite-original origmsg))))
|
(mu4e--cite-original origmsg))))
|
||||||
|
|
||||||
(defun mu4e-send-create-new ()
|
|
||||||
"Create a new message.."
|
(defun mu4e--newmsg-construct ()
|
||||||
|
"Create a new message."
|
||||||
(concat
|
(concat
|
||||||
(mu4e-send-header "From" (or (mu4e-send-from-create) ""))
|
(mu4e--header "From" (or (mu4e--from-construct) ""))
|
||||||
(mu4e-send-header "Reply-To" mu4e-reply-to-address)
|
(mu4e--header "Reply-To" mu4e-reply-to-address)
|
||||||
(mu4e-send-header "To" "")
|
(mu4e--header "To" "")
|
||||||
(mu4e-send-header "User-agent" (mu4e-send-user-agent))
|
(mu4e--header "User-agent" (mu4e-user-agent))
|
||||||
(mu4e-send-header "Subject" "")
|
(mu4e--header "Subject" "")
|
||||||
"\n"))
|
"\n"))
|
||||||
|
|
||||||
(defun mu4e-send-open-draft (compose-type &optional msg)
|
|
||||||
|
(defun mu4e--open-new-draft-file (compose-type &optional msg)
|
||||||
"Open a draft file for a new message, creating it if it does not
|
"Open a draft file for a new message, creating it if it does not
|
||||||
already exist, and optionally fill it with STR. Function also adds
|
already exist, and optionally fill it with STR. Function also adds
|
||||||
the new message to the database. When the draft message is added to
|
the new message to the database. When the draft message is added to
|
||||||
@ -311,9 +301,9 @@ use the new docid. Returns the full path to the new message."
|
|||||||
(format-time-string "%Y%m%d" (current-time))
|
(format-time-string "%Y%m%d" (current-time))
|
||||||
(emacs-pid) (random t) hostname)))
|
(emacs-pid) (random t) hostname)))
|
||||||
(str (case compose-type
|
(str (case compose-type
|
||||||
(reply (mu4e-send-create-reply msg))
|
(reply (mu4e--reply-construct msg))
|
||||||
(forward (mu4e-send-create-forward msg))
|
(forward (mu4e--forward-construct msg))
|
||||||
(new (mu4e-send-create-new))
|
(new (mu4e--newmsg-construct))
|
||||||
(t (error "unsupported compose-type %S" compose-type)))))
|
(t (error "unsupported compose-type %S" compose-type)))))
|
||||||
(when str
|
(when str
|
||||||
(with-current-buffer (find-file-noselect draft)
|
(with-current-buffer (find-file-noselect draft)
|
||||||
@ -322,7 +312,7 @@ use the new docid. Returns the full path to the new message."
|
|||||||
|
|
||||||
|
|
||||||
(define-derived-mode mu4e-edit-mode message-mode "mu4e:edit"
|
(define-derived-mode mu4e-edit-mode message-mode "mu4e:edit"
|
||||||
"Major mode for the mu4e main screen.
|
"Major mode for the mu4e message composition, derived from `message-mode'.
|
||||||
\\{message-mode-map}."
|
\\{message-mode-map}."
|
||||||
(let ((message-hidden-headers
|
(let ((message-hidden-headers
|
||||||
`("^References:" "^Face:" "^X-Face:" "^X-Draft-From:"
|
`("^References:" "^Face:" "^X-Face:" "^X-Draft-From:"
|
||||||
@ -344,11 +334,11 @@ use the new docid. Returns the full path to the new message."
|
|||||||
;; hack-hack-hack... just before saving, we remove the
|
;; hack-hack-hack... just before saving, we remove the
|
||||||
;; mail-header-separator; just after saving we restore it; thus, the
|
;; mail-header-separator; just after saving we restore it; thus, the
|
||||||
;; separator should never appear on disk
|
;; separator should never appear on disk
|
||||||
(add-hook 'before-save-hook 'mu4e-remove-mail-header-separator)
|
(add-hook 'before-save-hook 'mu4e--remove-mail-header-separator)
|
||||||
(add-hook 'after-save-hook
|
(add-hook 'after-save-hook
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(mu4e-set-buffer-name)
|
(mu4e--set-friendly-buffer-name)
|
||||||
(mu4e-insert-mail-header-separator)
|
(mu4e--insert-mail-header-separator)
|
||||||
(set-buffer-modified-p nil)))
|
(set-buffer-modified-p nil)))
|
||||||
|
|
||||||
;; update the db when the file is saved...]
|
;; update the db when the file is saved...]
|
||||||
@ -357,27 +347,27 @@ use the new docid. Returns the full path to the new message."
|
|||||||
(mu4e-proc-add (buffer-file-name) mu4e-drafts-folder))))
|
(mu4e-proc-add (buffer-file-name) mu4e-drafts-folder))))
|
||||||
|
|
||||||
;; notify the backend that a message has been sent. The backend will respond
|
;; notify the backend that a message has been sent. The backend will respond
|
||||||
;; with (:sent ...) sexp, which is handled in `mu4e-send-compose-handler'.
|
;; with (:sent ...) sexp, which is handled in `mu4e-compose-handler'.
|
||||||
(add-hook 'message-sent-hook
|
(add-hook 'message-sent-hook
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(set-buffer-modified-p t)
|
(set-buffer-modified-p t)
|
||||||
(basic-save-buffer)
|
(basic-save-buffer)
|
||||||
(mu4e-proc-sent (buffer-file-name) mu4e-drafts-folder)))
|
(mu4e-proc-sent (buffer-file-name) mu4e-drafts-folder)))
|
||||||
|
|
||||||
;; register the function; this function will be called when the '(:sent...)'
|
;; register the function; this function will be called when the '(:sent...)'
|
||||||
;; message is received (see mu4e-proc.el) with parameters docid and path
|
;; message is received (see mu4e-proc.el) with parameters docid and path
|
||||||
(setq mu4e-proc-sent-func 'mu4e-sent-handler)
|
(setq mu4e-sent-func 'mu4e-sent-handler)
|
||||||
|
|
||||||
;; set the default directory to the user's home dir; this is probably more
|
;; set the default directory to the user's home dir; this is probably more
|
||||||
;; useful e.g. when finding an attachment file the directory the current
|
;; useful e.g. when finding an attachment file the directory the current
|
||||||
;; mail files lives in...
|
;; mail files lives in...
|
||||||
(setq default-directory (expand-file-name "~/")))
|
(setq default-directory (expand-file-name "~/")))
|
||||||
|
|
||||||
|
|
||||||
(defconst mu4e-send-buffer-max-name-length 20
|
(defconst mu4e--buffer-max-name-length 30
|
||||||
"Maximum length of the mu4e-send-buffer-name.")
|
"Maximum length of the mu4e-send-buffer-name.")
|
||||||
|
|
||||||
(defun mu4e-set-buffer-name (&optional compose-type)
|
(defun mu4e--set-friendly-buffer-name (&optional compose-type)
|
||||||
"Set some user-friendly buffer name based on the compose type."
|
"Set some user-friendly buffer name based on the compose type."
|
||||||
(let* ((subj (message-field-value "subject"))
|
(let* ((subj (message-field-value "subject"))
|
||||||
(subj (unless (and subj (string-match "^[:blank:]*$" subj)) subj))
|
(subj (unless (and subj (string-match "^[:blank:]*$" subj)) subj))
|
||||||
@ -388,11 +378,11 @@ use the new docid. Returns the full path to the new message."
|
|||||||
(otherwise "*draft*")))))
|
(otherwise "*draft*")))))
|
||||||
(rename-buffer (generate-new-buffer-name
|
(rename-buffer (generate-new-buffer-name
|
||||||
(truncate-string-to-width str
|
(truncate-string-to-width str
|
||||||
mu4e-send-buffer-max-name-length
|
mu4e--buffer-max-name-length
|
||||||
nil nil t)))))
|
nil nil t)))))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-send-compose-handler (compose-type &optional original-msg includes)
|
(defun mu4e-compose-handler (compose-type &optional original-msg includes)
|
||||||
"Create a new draft message, or open an existing one.
|
"Create a new draft message, or open an existing one.
|
||||||
|
|
||||||
COMPOSE-TYPE determines the kind of message to compose and is a
|
COMPOSE-TYPE determines the kind of message to compose and is a
|
||||||
@ -418,14 +408,14 @@ The name of the draft folder is constructed from the concatenation
|
|||||||
The message file name is a unique name determined by
|
The message file name is a unique name determined by
|
||||||
`mu4e-send-draft-file-name'.
|
`mu4e-send-draft-file-name'.
|
||||||
|
|
||||||
The initial STR would be created from either `mu4e-send-create-reply',
|
The initial STR would be created from either `mu4e--reply-construct',
|
||||||
ar`mu4e-send-create-forward' or `mu4e-send-create-new'. The editing buffer is
|
ar`mu4e--forward-construct' or `mu4e--newmsg-construct'. The editing buffer is
|
||||||
using Gnus' `message-mode'."
|
using Gnus' `message-mode'."
|
||||||
(unless mu4e-maildir (error "mu4e-maildir not set"))
|
(unless mu4e-maildir (error "mu4e-maildir not set"))
|
||||||
(unless mu4e-drafts-folder (error "mu4e-drafts-folder not set"))
|
(unless mu4e-drafts-folder (error "mu4e-drafts-folder not set"))
|
||||||
(let ((draft
|
(let ((draft
|
||||||
(if (member compose-type '(reply forward new))
|
(if (member compose-type '(reply forward new))
|
||||||
(mu4e-send-open-draft compose-type original-msg)
|
(mu4e--open-new-draft-file compose-type original-msg)
|
||||||
(if (eq compose-type 'edit)
|
(if (eq compose-type 'edit)
|
||||||
(plist-get original-msg :path)
|
(plist-get original-msg :path)
|
||||||
(error "unsupported compose-type %S" compose-type)))))
|
(error "unsupported compose-type %S" compose-type)))))
|
||||||
@ -435,7 +425,7 @@ using Gnus' `message-mode'."
|
|||||||
|
|
||||||
;; insert mail-header-separator, which is needed by message mode to separate
|
;; insert mail-header-separator, which is needed by message mode to separate
|
||||||
;; headers and body. will be removed before saving to disk
|
;; headers and body. will be removed before saving to disk
|
||||||
(mu4e-insert-mail-header-separator)
|
(mu4e--insert-mail-header-separator)
|
||||||
|
|
||||||
;; include files -- e.g. when forwarding a message with attachments,
|
;; include files -- e.g. when forwarding a message with attachments,
|
||||||
;; we take those from the original.
|
;; we take those from the original.
|
||||||
@ -455,11 +445,11 @@ using Gnus' `message-mode'."
|
|||||||
(message-goto-to)
|
(message-goto-to)
|
||||||
(message-goto-body))
|
(message-goto-body))
|
||||||
|
|
||||||
(mu4e-set-buffer-name compose-type)
|
(mu4e--set-friendly-buffer-name compose-type)
|
||||||
|
|
||||||
;; buffer is not user-modified yet
|
;; buffer is not user-modified yet
|
||||||
(set-buffer-modified-p nil)))
|
(set-buffer-modified-p nil)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-sent-handler (docid path)
|
(defun mu4e-sent-handler (docid path)
|
||||||
@ -468,14 +458,14 @@ message."
|
|||||||
(with-current-buffer (find-file-noselect path)
|
(with-current-buffer (find-file-noselect path)
|
||||||
;; for Forward ('Passed') and Replied messages, try to set the appropriate
|
;; for Forward ('Passed') and Replied messages, try to set the appropriate
|
||||||
;; flag at the message forwarded or replied-to
|
;; flag at the message forwarded or replied-to
|
||||||
(mu4e-send-set-parent-flag docid path)
|
(mu4e--set-parent-flag docid path)
|
||||||
;; handle the draft -- should it be moved to the send folder, or elsewhere?
|
;; handle the draft -- should it be moved to the send folder, or elsewhere?
|
||||||
(mu4e-send-save-copy-maybe docid path)
|
(mu4e--save-copy-maybe docid path)
|
||||||
;; now, get rid of the buffer
|
;; now, get rid of the buffer
|
||||||
(kill-buffer)))
|
(kill-buffer)))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-send-save-copy-maybe (docid path)
|
(defun mu4e--save-copy-maybe (docid path)
|
||||||
"Handler function, called with DOCID and PATH for the just-sent
|
"Handler function, called with DOCID and PATH for the just-sent
|
||||||
message, which will move it to the sent-folder or elsewhere,
|
message, which will move it to the sent-folder or elsewhere,
|
||||||
depending on the value of `mu4e-sent-messages-behavior'.
|
depending on the value of `mu4e-sent-messages-behavior'.
|
||||||
@ -493,7 +483,7 @@ buffer."
|
|||||||
(mu4e-proc-move-msg docid mu4e-trash-folder "+T-D+S")
|
(mu4e-proc-move-msg docid mu4e-trash-folder "+T-D+S")
|
||||||
(mu4e-proc-move-msg docid mu4e-sent-folder "-T-D+S")))))
|
(mu4e-proc-move-msg docid mu4e-sent-folder "-T-D+S")))))
|
||||||
|
|
||||||
(defun mu4e-send-set-parent-flag (docid path)
|
(defun mu4e--set-parent-flag (docid path)
|
||||||
"Set the 'replied' \"R\" flag on messages we replied to, and the
|
"Set the 'replied' \"R\" flag on messages we replied to, and the
|
||||||
'passed' \"F\" flag on message we have forwarded.
|
'passed' \"F\" flag on message we have forwarded.
|
||||||
|
|
||||||
@ -530,4 +520,4 @@ buffer.
|
|||||||
(when (and forwarded-from (string-match "<\\(.*\\)>" forwarded-from))
|
(when (and forwarded-from (string-match "<\\(.*\\)>" forwarded-from))
|
||||||
(mu4e-proc-flag (match-string 1 forwarded-from) "+P"))))
|
(mu4e-proc-flag (match-string 1 forwarded-from) "+P"))))
|
||||||
|
|
||||||
(provide 'mu4e-send)
|
(provide 'mu4e-compose)
|
||||||
@ -81,14 +81,6 @@ results, otherwise, limit number of results to
|
|||||||
"Handler function for displaying a message."
|
"Handler function for displaying a message."
|
||||||
(mu4e-view msg mu4e-hdrs-buffer))
|
(mu4e-view msg mu4e-hdrs-buffer))
|
||||||
|
|
||||||
(defun mu4e-hdrs-error-handler (err)
|
|
||||||
"Handler function for showing an error."
|
|
||||||
(let ((errcode (plist-get err :error))
|
|
||||||
(errmsg (plist-get err :error-message)))
|
|
||||||
(case errcode
|
|
||||||
(4 (message "No matches for this search query."))
|
|
||||||
(t (message (format "Error %d: %s" errcode errmsg))))))
|
|
||||||
|
|
||||||
(defun mu4e-hdrs-update-handler (msg is-move)
|
(defun mu4e-hdrs-update-handler (msg is-move)
|
||||||
"Update handler, will be called when a message has been updated
|
"Update handler, will be called when a message has been updated
|
||||||
in the database. This function will update the current list of
|
in the database. This function will update the current list of
|
||||||
@ -343,17 +335,6 @@ after the end of the search results."
|
|||||||
|
|
||||||
(fset 'mu4e-hdrs-mode-map mu4e-hdrs-mode-map)
|
(fset 'mu4e-hdrs-mode-map mu4e-hdrs-mode-map)
|
||||||
|
|
||||||
;; we register our handler functions for the mu4e-proc (mu server) output
|
|
||||||
(setq mu4e-proc-error-func 'mu4e-hdrs-error-handler)
|
|
||||||
(setq mu4e-proc-update-func 'mu4e-hdrs-update-handler)
|
|
||||||
(setq mu4e-proc-header-func 'mu4e-hdrs-header-handler)
|
|
||||||
(setq mu4e-proc-found-func 'mu4e-hdrs-found-handler)
|
|
||||||
(setq mu4e-proc-view-func 'mu4e-hdrs-view-handler)
|
|
||||||
(setq mu4e-proc-remove-func 'mu4e-hdrs-remove-handler)
|
|
||||||
(setq mu4e-proc-erase-func 'mu4e-hdrs-clear)
|
|
||||||
|
|
||||||
;; this last one is defined in mu4e-send.el
|
|
||||||
(setq mu4e-proc-compose-func 'mu4e-send-compose-handler)
|
|
||||||
|
|
||||||
(define-derived-mode mu4e-hdrs-mode special-mode
|
(define-derived-mode mu4e-hdrs-mode special-mode
|
||||||
"mu4e:headers"
|
"mu4e:headers"
|
||||||
@ -471,7 +452,7 @@ docid DOCID, or nil if it cannot be found."
|
|||||||
with DOCID which must be present in the headers buffer."
|
with DOCID which must be present in the headers buffer."
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(when (mu4e--goto-docid docid)
|
(when (mu4e--goto-docid docid)
|
||||||
(mu4e-field-at-point field))))
|
(mu4e-field-at-point field))))
|
||||||
|
|
||||||
;;;; markers mark headers for
|
;;;; markers mark headers for
|
||||||
(defun mu4e--mark-header (docid mark)
|
(defun mu4e--mark-header (docid mark)
|
||||||
@ -897,7 +878,7 @@ for draft messages."
|
|||||||
;; 'new is special, since it takes no existing message as arg therefore,
|
;; 'new is special, since it takes no existing message as arg therefore,
|
||||||
;; we don't need to call thec backend, and call the handler *directly*
|
;; we don't need to call thec backend, and call the handler *directly*
|
||||||
(if (eq compose-type 'new)
|
(if (eq compose-type 'new)
|
||||||
(mu4e-send-compose-handler 'new)
|
(mu4e-compose-handler 'new)
|
||||||
;; otherwise, we need the doc-id
|
;; otherwise, we need the doc-id
|
||||||
(let ((docid (mu4e--docid-at-point)))
|
(let ((docid (mu4e--docid-at-point)))
|
||||||
(unless docid (error "No message at point."))
|
(unless docid (error "No message at point."))
|
||||||
|
|||||||
@ -29,68 +29,8 @@
|
|||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; internal vars
|
;; internal vars
|
||||||
|
(defvar mu4e-mu-proc nil "*internal* The mu-server process")
|
||||||
(defvar mu4e-mu-proc nil
|
(defvar mu4e-buf nil "*internal* Buffer for results data.")
|
||||||
"*internal* The mu-server process")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-error-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each error returned from the
|
|
||||||
server process; the function is passed an error plist as
|
|
||||||
argument. See `mu4e-proc-filter' for the format.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-update-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each :update sexp returned from
|
|
||||||
the server process; the function is passed a msg sexp as
|
|
||||||
argument. See `mu4e-proc-filter' for the format.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-remove-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each :remove sexp returned from
|
|
||||||
the server process, when some message has been deleted. The
|
|
||||||
function is passed the docid of the removed message.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-sent-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each :sent sexp returned from
|
|
||||||
the server process, when some message has been sent. The
|
|
||||||
function is passed the docid and the draft-path of the sent message.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-view-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each single message sexp
|
|
||||||
returned from the server process. The function is passed a message
|
|
||||||
sexp as argument. See `mu4e-proc-filter' for the
|
|
||||||
format.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-header-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each message returned from the
|
|
||||||
server process; the function is passed a msg plist as argument. See
|
|
||||||
`mu4e-proc-filter' for the format.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-found-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for when we received a :found sexp
|
|
||||||
after the headers have returns, to report on the number of
|
|
||||||
matches. See `mu4e-proc-filter' for the format.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-erase-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for when we received an :erase sexp
|
|
||||||
after the headers have returns, to clear the current headers
|
|
||||||
buffer. See `mu4e-proc-filter' for the format.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-compose-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each message returned from the
|
|
||||||
server process that is used as basis for composing a new
|
|
||||||
message (ie., either a reply or a forward); the function is passed
|
|
||||||
msg and a symbol (either reply or forward). See `mu4e-proc-filter'
|
|
||||||
for the format of <msg-plist>.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-info-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each (:info type ....) sexp
|
|
||||||
received from the server process.")
|
|
||||||
|
|
||||||
(defvar mu4e-proc-pong-func 'mu4e-default-handler
|
|
||||||
"*internal* A function called for each (:pong type ....) sexp
|
|
||||||
received from the server process.")
|
|
||||||
|
|
||||||
(defvar mu4e-buf nil
|
|
||||||
"*internal* Buffer for results data.")
|
|
||||||
|
|
||||||
(defvar mu4e-path-docid-map
|
(defvar mu4e-path-docid-map
|
||||||
(make-hash-table :size 32 :rehash-size 2 :test 'equal :weakness nil)
|
(make-hash-table :size 32 :rehash-size 2 :test 'equal :weakness nil)
|
||||||
@ -98,31 +38,6 @@ received from the server process.")
|
|||||||
we added ourselves (ie., draft messages), so we can e.g. move them
|
we added ourselves (ie., draft messages), so we can e.g. move them
|
||||||
to the sent folder using their docid")
|
to the sent folder using their docid")
|
||||||
|
|
||||||
(defun mu4e-proc-info-handler (info)
|
|
||||||
"Handler function for (:info ...) sexps received from the server
|
|
||||||
process."
|
|
||||||
(let ((type (plist-get info :info)))
|
|
||||||
(cond
|
|
||||||
((eq type 'add)
|
|
||||||
;; update our path=>docid map; we use this when composing messages to
|
|
||||||
;; add draft messages to the db, so when we're sending them, we can move
|
|
||||||
;; to the sent folder using the `mu4e-proc-move'.
|
|
||||||
(puthash (plist-get info :path) (plist-get info :docid) mu4e-path-docid-map))
|
|
||||||
((eq type 'index)
|
|
||||||
(if (eq (plist-get info :status) 'running)
|
|
||||||
(message (format "Indexing... processed %d, updated %d"
|
|
||||||
(plist-get info :processed) (plist-get info :updated)))
|
|
||||||
(message
|
|
||||||
(format "Indexing completed; processed %d, updated %d, cleaned-up %d"
|
|
||||||
(plist-get info :processed) (plist-get info :updated)
|
|
||||||
(plist-get info :cleaned-up)))))
|
|
||||||
((plist-get info :message) (message "%s" (plist-get info :message))))))
|
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-default-handler (&rest args)
|
|
||||||
"Dummy handler function."
|
|
||||||
(error "Not handled: %S" args))
|
|
||||||
|
|
||||||
(defconst mu4e-server-name "*mu4e-server*"
|
(defconst mu4e-server-name "*mu4e-server*"
|
||||||
"*internal* Name of the server process, buffer.")
|
"*internal* Name of the server process, buffer.")
|
||||||
|
|
||||||
@ -140,7 +55,6 @@ process."
|
|||||||
mu4e-server-name mu4e-server-name
|
mu4e-server-name mu4e-server-name
|
||||||
mu4e-mu-binary args))
|
mu4e-mu-binary args))
|
||||||
;; register a function for (:info ...) sexps
|
;; register a function for (:info ...) sexps
|
||||||
(setq mu4e-proc-info-func 'mu4e-proc-info-handler)
|
|
||||||
(when mu4e-mu-proc
|
(when mu4e-mu-proc
|
||||||
(set-process-query-on-exit-flag mu4e-mu-proc nil)
|
(set-process-query-on-exit-flag mu4e-mu-proc nil)
|
||||||
(set-process-coding-system mu4e-mu-proc 'binary 'utf-8-unix)
|
(set-process-coding-system mu4e-mu-proc 'binary 'utf-8-unix)
|
||||||
@ -202,7 +116,7 @@ updated as well, with all processed sexp data removed."
|
|||||||
1. an error
|
1. an error
|
||||||
(:error 2 :error-message \"unknown command\")
|
(:error 2 :error-message \"unknown command\")
|
||||||
;; eox
|
;; eox
|
||||||
=> this will be passed to `mu4e-proc-error-func'.
|
=> this will be passed to `mu4e-error-func'.
|
||||||
|
|
||||||
2a. a message sexp looks something like:
|
2a. a message sexp looks something like:
|
||||||
\(
|
\(
|
||||||
@ -223,32 +137,32 @@ updated as well, with all processed sexp data removed."
|
|||||||
:body-txt \" <message body>\"
|
:body-txt \" <message body>\"
|
||||||
\)
|
\)
|
||||||
;; eox
|
;; eox
|
||||||
=> this will be passed to `mu4e-proc-header-func'.
|
=> this will be passed to `mu4e-header-func'.
|
||||||
|
|
||||||
2b. After the list of message sexps has been returned (see 2a.),
|
2b. After the list of message sexps has been returned (see 2a.),
|
||||||
we'll receive a sexp that looks like
|
we'll receive a sexp that looks like
|
||||||
(:found <n>) with n the number of messages found. The <n> will be
|
(:found <n>) with n the number of messages found. The <n> will be
|
||||||
passed to `mu4e-proc-found-func'.
|
passed to `mu4e-found-func'.
|
||||||
|
|
||||||
3. a view looks like:
|
3. a view looks like:
|
||||||
(:view <msg-sexp>)
|
(:view <msg-sexp>)
|
||||||
=> the <msg-sexp> (see 2.) will be passed to `mu4e-proc-view-func'.
|
=> the <msg-sexp> (see 2.) will be passed to `mu4e-view-func'.
|
||||||
|
|
||||||
4. a database update looks like:
|
4. a database update looks like:
|
||||||
(:update <msg-sexp> :move <nil-or-t>)
|
(:update <msg-sexp> :move <nil-or-t>)
|
||||||
|
|
||||||
=> the <msg-sexp> (see 2.) will be passed to
|
=> the <msg-sexp> (see 2.) will be passed to
|
||||||
`mu4e-proc-update-func', :move tells us whether this is a move to
|
`mu4e-update-func', :move tells us whether this is a move to
|
||||||
another maildir, or merely a flag change.
|
another maildir, or merely a flag change.
|
||||||
|
|
||||||
5. a remove looks like:
|
5. a remove looks like:
|
||||||
(:remove <docid>)
|
(:remove <docid>)
|
||||||
=> the docid will be passed to `mu4e-proc-remove-func'
|
=> the docid will be passed to `mu4e-remove-func'
|
||||||
|
|
||||||
6. a compose looks like:
|
6. a compose looks like:
|
||||||
(:compose <msg-sexp> :action <reply|forward>) => the <msg-sexp>
|
(:compose <msg-sexp> :action <reply|forward>) => the <msg-sexp>
|
||||||
and either 'reply or 'forward will be passed
|
and either 'reply or 'forward will be passed
|
||||||
`mu4e-proc-compose-func'."
|
`mu4e-compose-func'."
|
||||||
(mu4e-proc-log "* Received %d byte(s)" (length str))
|
(mu4e-proc-log "* Received %d byte(s)" (length str))
|
||||||
(setq mu4e-buf (concat mu4e-buf str)) ;; update our buffer
|
(setq mu4e-buf (concat mu4e-buf str)) ;; update our buffer
|
||||||
(let ((sexp (mu4e-proc-eat-sexp-from-buf)))
|
(let ((sexp (mu4e-proc-eat-sexp-from-buf)))
|
||||||
@ -257,54 +171,54 @@ updated as well, with all processed sexp data removed."
|
|||||||
(cond
|
(cond
|
||||||
;; a header plist can be recognized by the existence of a :date field
|
;; a header plist can be recognized by the existence of a :date field
|
||||||
((plist-get sexp :date)
|
((plist-get sexp :date)
|
||||||
(funcall mu4e-proc-header-func sexp))
|
(funcall mu4e-header-func sexp))
|
||||||
|
|
||||||
;; the found sexp, we receive after getting all the headers
|
;; the found sexp, we receive after getting all the headers
|
||||||
((plist-get sexp :found)
|
((plist-get sexp :found)
|
||||||
(funcall mu4e-proc-found-func (plist-get sexp :found)))
|
(funcall mu4e-found-func (plist-get sexp :found)))
|
||||||
|
|
||||||
;; viewing a specific message
|
;; viewing a specific message
|
||||||
((plist-get sexp :view)
|
((plist-get sexp :view)
|
||||||
(funcall mu4e-proc-view-func (plist-get sexp :view)))
|
(funcall mu4e-view-func (plist-get sexp :view)))
|
||||||
|
|
||||||
;; receive an erase message
|
;; receive an erase message
|
||||||
((plist-get sexp :erase)
|
((plist-get sexp :erase)
|
||||||
(funcall mu4e-proc-erase-func))
|
(funcall mu4e-erase-func))
|
||||||
|
|
||||||
;; receive a :sent message
|
;; receive a :sent message
|
||||||
((plist-get sexp :sent)
|
((plist-get sexp :sent)
|
||||||
(funcall mu4e-proc-sent-func
|
(funcall mu4e-sent-func
|
||||||
(plist-get sexp :docid)
|
(plist-get sexp :docid)
|
||||||
(plist-get sexp :path)))
|
(plist-get sexp :path)))
|
||||||
|
|
||||||
;; receive a pong message
|
;; receive a pong message
|
||||||
((plist-get sexp :pong)
|
((plist-get sexp :pong)
|
||||||
(funcall mu4e-proc-pong-func
|
(funcall mu4e-pong-func
|
||||||
(plist-get sexp :version) (plist-get sexp :doccount)))
|
(plist-get sexp :version) (plist-get sexp :doccount)))
|
||||||
|
|
||||||
;; something got moved/flags changed
|
;; something got moved/flags changed
|
||||||
((plist-get sexp :update)
|
((plist-get sexp :update)
|
||||||
(funcall mu4e-proc-update-func
|
(funcall mu4e-update-func
|
||||||
(plist-get sexp :update) (plist-get sexp :move)))
|
(plist-get sexp :update) (plist-get sexp :move)))
|
||||||
|
|
||||||
;; a message got removed
|
;; a message got removed
|
||||||
((plist-get sexp :remove)
|
((plist-get sexp :remove)
|
||||||
(funcall mu4e-proc-remove-func (plist-get sexp :remove)))
|
(funcall mu4e-remove-func (plist-get sexp :remove)))
|
||||||
|
|
||||||
;; start composing a new message
|
;; start composing a new message
|
||||||
((plist-get sexp :compose-type)
|
((plist-get sexp :compose-type)
|
||||||
(funcall mu4e-proc-compose-func
|
(funcall mu4e-compose-func
|
||||||
(plist-get sexp :compose-type)
|
(plist-get sexp :compose-type)
|
||||||
(plist-get sexp :original)
|
(plist-get sexp :original)
|
||||||
(plist-get sexp :include)))
|
(plist-get sexp :include)))
|
||||||
|
|
||||||
;; get some info
|
;; get some info
|
||||||
((plist-get sexp :info)
|
((plist-get sexp :info)
|
||||||
(funcall mu4e-proc-info-func sexp))
|
(funcall mu4e-info-func sexp))
|
||||||
|
|
||||||
;; receive an error
|
;; receive an error
|
||||||
((plist-get sexp :error)
|
((plist-get sexp :error)
|
||||||
(funcall mu4e-proc-error-func sexp))
|
(funcall mu4e-error-func sexp))
|
||||||
(t (message "Unexpected data from server [%S]" sexp)))
|
(t (message "Unexpected data from server [%S]" sexp)))
|
||||||
(setq sexp (mu4e-proc-eat-sexp-from-buf)))))
|
(setq sexp (mu4e-proc-eat-sexp-from-buf)))))
|
||||||
|
|
||||||
@ -359,7 +273,7 @@ terminates."
|
|||||||
(defun mu4e-proc-remove-msg (docid)
|
(defun mu4e-proc-remove-msg (docid)
|
||||||
"Remove message identified by DOCID. The results are reporter
|
"Remove message identified by DOCID. The results are reporter
|
||||||
through either (:update ... ) or (:error ) sexp, which are handled
|
through either (:update ... ) or (:error ) sexp, which are handled
|
||||||
my `mu4e-proc-update-func' and `mu4e-proc-error-func', respectively."
|
my `mu4e-error-func', respectively."
|
||||||
(mu4e-proc-send-command "remove %d" docid))
|
(mu4e-proc-send-command "remove %d" docid))
|
||||||
|
|
||||||
|
|
||||||
@ -367,7 +281,7 @@ my `mu4e-proc-update-func' and `mu4e-proc-error-func', respectively."
|
|||||||
"Start a database query for EXPR, getting up to MAXNUM
|
"Start a database query for EXPR, getting up to MAXNUM
|
||||||
results (or -1 for unlimited). For each result found, a function is
|
results (or -1 for unlimited). For each result found, a function is
|
||||||
called, depending on the kind of result. The variables
|
called, depending on the kind of result. The variables
|
||||||
`mu4e-proc-header-func' and `mu4e-proc-error-func' contain the function
|
`mu4e-error-func' contain the function
|
||||||
that will be called for, resp., a message (header row) or an
|
that will be called for, resp., a message (header row) or an
|
||||||
error."
|
error."
|
||||||
(mu4e-proc-send-command "find \"%s\" %d"
|
(mu4e-proc-send-command "find \"%s\" %d"
|
||||||
@ -392,10 +306,10 @@ The flags are any of `deleted', `flagged', `new', `passed', `replied' `seen' or
|
|||||||
`trashed', or the corresponding \"DFNPRST\" as defined in [1]. See
|
`trashed', or the corresponding \"DFNPRST\" as defined in [1]. See
|
||||||
`mu4e-string-to-flags' and `mu4e-flags-to-string'.
|
`mu4e-string-to-flags' and `mu4e-flags-to-string'.
|
||||||
The server reports the results for the operation through
|
The server reports the results for the operation through
|
||||||
`mu4e-proc-update-func'.
|
`mu4e-update-func'.
|
||||||
The results are reported through either (:update ... )
|
The results are reported through either (:update ... )
|
||||||
or (:error ) sexp, which are handled my `mu4e-proc-update-func' and
|
or (:error ) sexp, which are handled my `mu4e-update-func' and
|
||||||
`mu4e-proc-error-func', respectively."
|
`mu4e-error-func', respectively."
|
||||||
(let
|
(let
|
||||||
((flagstr (if (stringp flags) flags (mu4e-flags-to-string flags)))
|
((flagstr (if (stringp flags) flags (mu4e-flags-to-string flags)))
|
||||||
(fullpath (concat mu4e-maildir targetmdir)))
|
(fullpath (concat mu4e-maildir targetmdir)))
|
||||||
@ -446,7 +360,7 @@ expecting a (:sent <docid> :path <draftpath>) in response."
|
|||||||
|
|
||||||
(defun mu4e-proc-view-msg (docid-or-msgid)
|
(defun mu4e-proc-view-msg (docid-or-msgid)
|
||||||
"Get one particular message based on its DOCID-OR-MSGID. The result will
|
"Get one particular message based on its DOCID-OR-MSGID. The result will
|
||||||
be delivered to the function registered as `mu4e-proc-message-func'."
|
be delivered to the function registered as `mu4e-message-func'."
|
||||||
(if (stringp docid-or-msgid)
|
(if (stringp docid-or-msgid)
|
||||||
(mu4e-proc-send-command "view %s" docid-or-msgid)
|
(mu4e-proc-send-command "view %s" docid-or-msgid)
|
||||||
(mu4e-proc-send-command "view %d" docid-or-msgid)))
|
(mu4e-proc-send-command "view %d" docid-or-msgid)))
|
||||||
@ -455,7 +369,7 @@ be delivered to the function registered as `mu4e-proc-message-func'."
|
|||||||
"Start composing a message with DOCID and COMPOSE-TYPE (a symbol,
|
"Start composing a message with DOCID and COMPOSE-TYPE (a symbol,
|
||||||
either `forward', `reply' or `edit'.
|
either `forward', `reply' or `edit'.
|
||||||
The result will be delivered to the function registered as
|
The result will be delivered to the function registered as
|
||||||
`mu4e-proc-compose-func'."
|
`mu4e-compose-func'."
|
||||||
(unless (member compose-type '(forward reply edit))
|
(unless (member compose-type '(forward reply edit))
|
||||||
(error "Unsupported compose-type %S" compose-type))
|
(error "Unsupported compose-type %S" compose-type))
|
||||||
(mu4e-proc-send-command "compose %s %d" (symbol-name compose-type) docid))
|
(mu4e-proc-send-command "compose %s %d" (symbol-name compose-type) docid))
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'cl)
|
(require 'cl)
|
||||||
(require 'html2text)
|
(require 'html2text)
|
||||||
|
(require 'mu4e-vars)
|
||||||
|
|
||||||
(defun mu4e-create-maildir-maybe (dir)
|
(defun mu4e-create-maildir-maybe (dir)
|
||||||
"Offer to create DIR if it does not exist yet. Return t if the
|
"Offer to create DIR if it does not exist yet. Return t if the
|
||||||
@ -91,7 +92,7 @@ Function returns the CHAR typed."
|
|||||||
(setq ;; eat first kar from descr; use it as kar
|
(setq ;; eat first kar from descr; use it as kar
|
||||||
kar (string-to-char descr)
|
kar (string-to-char descr)
|
||||||
descr (substring descr 1)))
|
descr (substring descr 1)))
|
||||||
(add-to-list 'optionkars kar)
|
(add-to-list 'optionkars kar)
|
||||||
(concat
|
(concat
|
||||||
"[" (propertize (make-string 1 kar) 'face 'mu4e-view-link-face) "]"
|
"[" (propertize (make-string 1 kar) 'face 'mu4e-view-link-face) "]"
|
||||||
descr))) options ", "))
|
descr))) options ", "))
|
||||||
@ -106,7 +107,7 @@ Function returns the CHAR typed."
|
|||||||
(mu4e-read-option prompt options))
|
(mu4e-read-option prompt options))
|
||||||
;; otherwise, return the response char
|
;; otherwise, return the response char
|
||||||
response))
|
response))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-get-maildirs (parentdir)
|
(defun mu4e-get-maildirs (parentdir)
|
||||||
"List the maildirs under PARENTDIR." ;; TODO: recursive?
|
"List the maildirs under PARENTDIR." ;; TODO: recursive?
|
||||||
@ -335,6 +336,12 @@ top level if there is none."
|
|||||||
('mu4e-hdrs-mode "(mu4e)Headers view")
|
('mu4e-hdrs-mode "(mu4e)Headers view")
|
||||||
('mu4e-view-mode "(mu4e)Message view")
|
('mu4e-view-mode "(mu4e)Message view")
|
||||||
(t "mu4e"))))
|
(t "mu4e"))))
|
||||||
|
|
||||||
|
(defun mu4e-user-agent ()
|
||||||
|
"Return the User-Agent string for mu4e. This is either the value
|
||||||
|
of `mu4e-user-agent', or, if not set, a string based on the versions
|
||||||
|
of mu4e and emacs."
|
||||||
|
(or mu4e-user-agent
|
||||||
(format "mu4e %s; emacs %s" mu4e-mu-version emacs-version)))
|
(format "mu4e %s; emacs %s" mu4e-mu-version emacs-version)))
|
||||||
|
|
||||||
(defun mu4e-field-at-point (field)
|
(defun mu4e-field-at-point (field)
|
||||||
@ -373,6 +380,46 @@ that has a live window), and vice versa."
|
|||||||
(if (window-live-p other-win)
|
(if (window-live-p other-win)
|
||||||
(select-window other-win)
|
(select-window other-win)
|
||||||
(message "No window to switch to"))))
|
(message "No window to switch to"))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; some handler functions for server messages
|
||||||
|
;;
|
||||||
|
(defun mu4e-info-handler (info)
|
||||||
|
"Handler function for (:info ...) sexps received from the server
|
||||||
|
process."
|
||||||
|
(let ((type (plist-get info :info)))
|
||||||
|
(cond
|
||||||
|
((eq type 'add)
|
||||||
|
;; update our path=>docid map; we use this when composing messages to
|
||||||
|
;; add draft messages to the db, so when we're sending them, we can move
|
||||||
|
;; to the sent folder using the `mu4e-proc-move'.
|
||||||
|
(puthash (plist-get info :path) (plist-get info :docid) mu4e-path-docid-map))
|
||||||
|
((eq type 'index)
|
||||||
|
(if (eq (plist-get info :status) 'running)
|
||||||
|
(message (format "Indexing... processed %d, updated %d"
|
||||||
|
(plist-get info :processed) (plist-get info :updated)))
|
||||||
|
(message
|
||||||
|
(format "Indexing completed; processed %d, updated %d, cleaned-up %d"
|
||||||
|
(plist-get info :processed) (plist-get info :updated)
|
||||||
|
(plist-get info :cleaned-up)))))
|
||||||
|
((plist-get info :message) (message "%s" (plist-get info :message))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun mu4e-error-handler (err)
|
||||||
|
"Handler function for showing an error."
|
||||||
|
(let ((errcode (plist-get err :error))
|
||||||
|
(errmsg (plist-get err :error-message)))
|
||||||
|
(case errcode
|
||||||
|
(4 (message "No matches for this search query."))
|
||||||
|
(t (message (format "Error %d: %s" errcode errmsg))))))
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
(defvar mu4e-update-timer nil
|
(defvar mu4e-update-timer nil
|
||||||
@ -390,7 +437,7 @@ server has the expected values."
|
|||||||
;; better to check for specific features
|
;; better to check for specific features
|
||||||
(if (< emacs-major-version 23)
|
(if (< emacs-major-version 23)
|
||||||
(error "Emacs >= 23.x is required for mu4e")
|
(error "Emacs >= 23.x is required for mu4e")
|
||||||
(progn
|
(progn
|
||||||
(setq mu4e-pong-func
|
(setq mu4e-pong-func
|
||||||
(lambda (version doccount)
|
(lambda (version doccount)
|
||||||
(unless (string= version mu4e-mu-version)
|
(unless (string= version mu4e-mu-version)
|
||||||
|
|||||||
@ -475,4 +475,72 @@ in which case it will be equal to `:to'.)")
|
|||||||
(defvar mu4e-current-msg nil
|
(defvar mu4e-current-msg nil
|
||||||
"*internal* The plist describing the currently viewed message.")
|
"*internal* The plist describing the currently viewed message.")
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; our handlers funcs
|
||||||
|
;; these handler funcs define what happens when we receive a certain message
|
||||||
|
;; from the server
|
||||||
|
(defun mu4e--default-handler (&rest args)
|
||||||
|
"*internal* Dummy handler function."
|
||||||
|
(error "Not handled: %S" args))
|
||||||
|
|
||||||
|
(defvar mu4e-error-func 'mu4e--default-handler
|
||||||
|
"A function called for each error returned from the server
|
||||||
|
process; the function is passed an error plist as argument. See
|
||||||
|
`mu4e-proc-filter' for the format.")
|
||||||
|
|
||||||
|
(defvar mu4e-update-func 'mu4e--default-handler
|
||||||
|
"A function called for each :update sexp returned from the server
|
||||||
|
process; the function is passed a msg sexp as argument. See
|
||||||
|
`mu4e-proc-filter' for the format.")
|
||||||
|
|
||||||
|
(defvar mu4e-remove-func 'mu4e--default-handler
|
||||||
|
"A function called for each :remove sexp returned from the server
|
||||||
|
process, when some message has been deleted. The function is passed
|
||||||
|
the docid of the removed message.")
|
||||||
|
|
||||||
|
(defvar mu4e-sent-func 'mu4e--default-handler
|
||||||
|
"A function called for each :sent sexp returned from the server
|
||||||
|
process, when some message has been sent. The function is passed
|
||||||
|
the docid and the draft-path of the sent message.")
|
||||||
|
|
||||||
|
(defvar mu4e-view-func 'mu4e--default-handler
|
||||||
|
"A function called for each single message sexp returned from the
|
||||||
|
server process. The function is passed a message sexp as
|
||||||
|
argument. See `mu4e-proc-filter' for the format.")
|
||||||
|
|
||||||
|
(defvar mu4e-header-func 'mu4e--default-handler
|
||||||
|
"A function called for each message returned from the server
|
||||||
|
process; the function is passed a msg plist as argument. See
|
||||||
|
`mu4e-proc-filter' for the format.")
|
||||||
|
|
||||||
|
(defvar mu4e-found-func 'mu4e--default-handler
|
||||||
|
"A function called for when we received a :found sexp after the
|
||||||
|
headers have returns, to report on the number of matches. See
|
||||||
|
`mu4e-proc-filter' for the format.")
|
||||||
|
|
||||||
|
(defvar mu4e-erase-func 'mu4e--default-handler
|
||||||
|
"A function called for when we received an :erase sexp after the
|
||||||
|
headers have returns, to clear the current headers buffer. See
|
||||||
|
`mu4e-proc-filter' for the format.")
|
||||||
|
|
||||||
|
(defvar mu4e-compose-func 'mu4e--default-handler
|
||||||
|
"A function called for each message returned from the server
|
||||||
|
process that is used as basis for composing a new message (ie.,
|
||||||
|
either a reply or a forward); the function is passed msg and a
|
||||||
|
symbol (either reply or forward). See `mu4e-proc-filter' for the
|
||||||
|
format of <msg-plist>.")
|
||||||
|
|
||||||
|
(defvar mu4e-info-func 'mu4e--default-handler
|
||||||
|
"A function called for each (:info type ....) sexp received from
|
||||||
|
the server process.")
|
||||||
|
|
||||||
|
(defvar mu4e-pong-func 'mu4e--default-handler
|
||||||
|
"A function called for each (:pong type ....) sexp received from
|
||||||
|
the server process.")
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
(provide 'mu4e-vars)
|
(provide 'mu4e-vars)
|
||||||
|
;;; End of mu4e-vars.el
|
||||||
|
|||||||
@ -28,17 +28,45 @@
|
|||||||
|
|
||||||
(eval-when-compile (require 'cl))
|
(eval-when-compile (require 'cl))
|
||||||
|
|
||||||
|
(require 'mu4e-version) ;; autogenerated file with the version
|
||||||
(require 'mu4e-hdrs) ;; headers view
|
(require 'mu4e-hdrs) ;; headers view
|
||||||
(require 'mu4e-view) ;; message view
|
(require 'mu4e-view) ;; message view
|
||||||
(require 'mu4e-main) ;; main screen
|
(require 'mu4e-main) ;; main screen
|
||||||
(require 'mu4e-send) ;; editing / sending
|
(require 'mu4e-compose) ;; message composition / sending
|
||||||
(require 'mu4e-proc) ;; communication with backend
|
(require 'mu4e-proc) ;; communication with backend
|
||||||
(require 'mu4e-utils) ;; utility functions
|
(require 'mu4e-utils) ;; utility functions
|
||||||
|
|
||||||
(require 'mu4e-speedbar) ;; support for speedbar
|
(require 'mu4e-speedbar) ;; support for speedbar
|
||||||
|
|
||||||
;; mu4e-version.el is autogenerated, and defines mu4e-mu-version
|
|
||||||
(require 'mu4e-version)
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; register our handler functions; these connect server messages to functions
|
||||||
|
;; to handle them.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;; these are all defined in mu4e-hdrs
|
||||||
|
(setq mu4e-update-func 'mu4e-hdrs-update-handler)
|
||||||
|
(setq mu4e-header-func 'mu4e-hdrs-header-handler)
|
||||||
|
(setq mu4e-found-func 'mu4e-hdrs-found-handler)
|
||||||
|
(setq mu4e-view-func 'mu4e-hdrs-view-handler)
|
||||||
|
(setq mu4e-remove-func 'mu4e-hdrs-remove-handler)
|
||||||
|
(setq mu4e-erase-func 'mu4e-hdrs-clear)
|
||||||
|
|
||||||
|
;; these ones are define in mu4e-utils
|
||||||
|
(setq mu4e-info-func 'mu4e-info-handler)
|
||||||
|
(setq mu4e-error-func 'mu4e-error-handler)
|
||||||
|
;; note: mu4e-utils also dynamically (temporarily)
|
||||||
|
;; registers mu4e-pong func
|
||||||
|
|
||||||
|
;; this one is defined in mu4e-compose
|
||||||
|
(setq mu4e-compose-func 'mu4e-compose-handler)
|
||||||
|
;; note: mu4e-compose.el dynamically registers mu4e-sent-func
|
||||||
|
;; we don't do that here, because it's only a local (temporary)
|
||||||
|
;; handler
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
(provide 'mu4e)
|
(provide 'mu4e)
|
||||||
|
|||||||
Reference in New Issue
Block a user