improve doc-strings

The first sentence should summarize the variable's or function's
purpose and it should fit on the first line.  Change existing
doc-string by:

* Move first sentence onto first line even if that makes it _a bit_
  long.
* Move additional notes out of first sentence and add them later,
  possibly as complete sentences.
* If I am uncertain whether doing the above would alter the meaning,
  _don't_ do it.
* If fitting the initial sentence on the first line would require a
  complete rewrite of the doc-string _don't_ do so unless it is very
  easy to do.
* Remove indentation from second and later lines if it is there to
  align them with the first in the source code, instead of in
  `describe-*' output.
* Make "pullet point" lists a bit more consistent.

Obviously this does not fix all problems but it's a start.
This commit is contained in:
Jonas Bernoulli 2012-11-10 14:01:17 +01:00
parent b92d826808
commit 8a3d4c27de
13 changed files with 397 additions and 368 deletions

View File

@ -37,8 +37,8 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-action-count-lines (msg) (defun mu4e-action-count-lines (msg)
"Count the number of lines in the e-mail message. Works for "Count the number of lines in the e-mail message.
headers view and message-view." Works for headers view and message-view."
(message "Number of lines: %s" (message "Number of lines: %s"
(shell-command-to-string (shell-command-to-string
(concat "wc -l < " (shell-quote-argument (mu4e-message-field msg :path)))))) (concat "wc -l < " (shell-quote-argument (mu4e-message-field msg :path))))))
@ -53,8 +53,8 @@ headers view and message-view."
"Path to the msg2pdf toy.") "Path to the msg2pdf toy.")
(defun mu4e-action-view-as-pdf (msg) (defun mu4e-action-view-as-pdf (msg)
"Convert the message to pdf, then show it. Works for the message "Convert the message to pdf, then show it.
view." Works for the message view."
(unless (file-executable-p mu4e-msg2pdf) (unless (file-executable-p mu4e-msg2pdf)
(mu4e-error "msg2pdf not found; please set `mu4e-msg2pdf'")) (mu4e-error "msg2pdf not found; please set `mu4e-msg2pdf'"))
(let* ((pdf (let* ((pdf
@ -74,8 +74,9 @@ view."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-action-view-in-browser (msg) (defun mu4e-action-view-in-browser (msg)
"View the body of the message in a web browser. You can influence "View the body of the message in a web browser.
the browser to use with the variable `browse-url-generic-program'." You can influence the browser to use with the variable
`browse-url-generic-program'."
(let* ((html (mu4e-message-field msg :body-html)) (let* ((html (mu4e-message-field msg :body-html))
(txt (mu4e-message-field msg :body-txt)) (txt (mu4e-message-field msg :body-txt))
(tmpfile (format "%s%x.html" temporary-file-directory (random t)))) (tmpfile (format "%s%x.html" temporary-file-directory (random t))))
@ -127,8 +128,8 @@ with `mu4e-compose-attach-captured-message'."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar mu4e-org-contacts-file nil (defvar mu4e-org-contacts-file nil
"File to store contact information for org-contacts. Needed by "File to store contact information for org-contacts.
`mu4e-action-add-org-contact'.") Needed by `mu4e-action-add-org-contact'.")
(eval-when-compile ;; silence compiler warning about free variable (eval-when-compile ;; silence compiler warning about free variable
(unless (require 'org-capture nil 'noerror) (unless (require 'org-capture nil 'noerror)

View File

@ -107,16 +107,16 @@ sent folder."
:group 'mu4e-compose) :group 'mu4e-compose)
(defvar mu4e-compose-pre-hook nil (defvar mu4e-compose-pre-hook nil
"Hook run just *before* message composition starts. If the "Hook run just *before* message composition starts.
compose-type is either /reply/ or /forward/, the variable If the compose-type is either /reply/ or /forward/, the variable
`mu4e-compose-parent-message' points to the message replied to / `mu4e-compose-parent-message' points to the message replied to /
being forwarded / edited.") being forwarded / edited.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-compose-attach-captured-message () (defun mu4e-compose-attach-captured-message ()
"Insert the last captured message (through "Insert the last captured message file as an attachment.
`mu4e-action-capture-message') file as an attachment." Messages are captured with `mu4e-action-capture-message'."
(interactive) (interactive)
(unless mu4e-captured-message (unless mu4e-captured-message
(mu4e-warn "No message has been captured")) (mu4e-warn "No message has been captured"))
@ -145,8 +145,8 @@ being forwarded / edited.")
;; `mu4e-sent-messages-behavior'. ;; `mu4e-sent-messages-behavior'.
(defun mu4e~compose-setup-fcc-maybe () (defun mu4e~compose-setup-fcc-maybe ()
"Maybe setup Fcc, based on `mu4e-sent-messages-behavior'. If "Maybe setup Fcc, based on `mu4e-sent-messages-behavior'.
needed, set the Fcc header, and register the handler function." If needed, set the Fcc header, and register the handler function."
(let* ((mdir (let* ((mdir
(case mu4e-sent-messages-behavior (case mu4e-sent-messages-behavior
(delete nil) (delete nil)
@ -174,8 +174,8 @@ needed, set the Fcc header, and register the handler function."
(defun mu4e~compose-register-message-save-hooks () (defun mu4e~compose-register-message-save-hooks ()
"Just before saving, we remove the mail-header-separator; just "Just before saving, we remove the mail-header-separator; just
after saving we restore it; thus, the separator should never after saving we restore it; thus, the separator should never
appear on disk." appear on disk."
(add-hook 'before-save-hook (add-hook 'before-save-hook
'mu4e~draft-remove-mail-header-separator nil t) 'mu4e~draft-remove-mail-header-separator nil t)
(add-hook 'after-save-hook (add-hook 'after-save-hook
@ -442,9 +442,9 @@ for draft messages."
(mu4e-compose 'forward)) (mu4e-compose 'forward))
(defun mu4e-compose-edit () (defun mu4e-compose-edit ()
"Edit the draft message at point in the headers buffer. This is "Edit the draft message at point in the headers buffer.
only possible if the message at point is, in fact, a draft This is only possible if the message at point is, in fact, a
message." draft message."
(interactive) (interactive)
(mu4e-compose 'edit)) (mu4e-compose 'edit))
@ -457,8 +457,8 @@ message."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; address completion; inspired by org-contacts.el ;; address completion; inspired by org-contacts.el
(defun mu4e~compose-complete-contact (&optional start) (defun mu4e~compose-complete-contact (&optional start)
"Complete the text at START with a contact (ie. either 'name "Complete the text at START with a contact.
<email>' or 'email')." Ie. either 'name <email>' or 'email')."
(interactive) (interactive)
(let ((mail-abbrev-mode-regexp mu4e~compose-address-fields-regexp) (let ((mail-abbrev-mode-regexp mu4e~compose-address-fields-regexp)
(eoh ;; end-of-headers (eoh ;; end-of-headers

View File

@ -38,16 +38,16 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e~draft-user-agent-construct () (defun mu4e~draft-user-agent-construct ()
"Return the User-Agent string for mu4e. This is either the value "Return the User-Agent string for mu4e.
of `mu4e-user-agent', or, if not set, a string based on the versions This is either the value of `mu4e-user-agent', or, if not set, a
of mu4e and emacs." string based on the versions of mu4e and emacs."
(format "mu4e %s; emacs %s" mu4e-mu-version emacs-version)) (format "mu4e %s; emacs %s" mu4e-mu-version emacs-version))
(defun mu4e~draft-cite-original (msg) (defun mu4e~draft-cite-original (msg)
"Return a cited version of the original message MSG (ie., the "Return a cited version of the original message MSG as a plist.
plist). This function use gnus' `message-cite-function', and as This function use gnus' `message-cite-function', and as such all
such all its settings apply." its settings apply."
(with-temp-buffer (with-temp-buffer
(when (fboundp 'mu4e-view-message-text) ;; keep bytecompiler happy (when (fboundp 'mu4e-view-message-text) ;; keep bytecompiler happy
(insert (mu4e-view-message-text msg)) (insert (mu4e-view-message-text msg))
@ -61,8 +61,8 @@ such all its settings apply."
(buffer-string)))) (buffer-string))))
(defun mu4e~draft-header (hdr val) (defun mu4e~draft-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\".
return nil." If VAL is nil, return nil."
(when val (format "%s: %s\n" hdr val))) (when val (format "%s: %s\n" hdr val)))
(defun mu4e~draft-references-construct (msg) (defun mu4e~draft-references-construct (msg)
@ -97,9 +97,10 @@ e-mail addresses. If LST is nil, returns nil."
lst ", "))) lst ", ")))
(defun mu4e~draft-address-cell-equal (cell1 cell2) (defun mu4e~draft-address-cell-equal (cell1 cell2)
"Return t if cell1 and cell2 have the same e-mail "Return t if CELL1 and CELL2 have the same e-mail address.
address (case-insensitively), nil otherwise. cell1 and cell2 are The comparison is done case-insensitively. If the cells done
cons cells (NAME . EMAIL)." match return nil. CELL1 and CELL2 are cons cells of the
form (NAME . EMAIL)."
(string= (string=
(downcase (or (cdr cell1) "")) (downcase (or (cdr cell1) ""))
(downcase (or (cdr cell2) "")))) (downcase (or (cdr cell2) ""))))
@ -174,9 +175,9 @@ nil, function returns nil."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e~draft-insert-mail-header-separator () (defun mu4e~draft-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. message-mode needs this line to know where the headers end `message-mode' needs this line to know where the headers end and
and the body starts. Note, in `mu4e-compose-mode, we use the body starts. Note, in `mu4e-compose-mode', we use
`before-save-hook' and `after-save-hook' to ensure that this `before-save-hook' and `after-save-hook' to ensure that this
separator is never written to the message file. Also see separator is never written to the message file. Also see
`mu4e-remove-mail-header-separator'." `mu4e-remove-mail-header-separator'."
@ -211,8 +212,8 @@ never hits the disk. Also see `mu4e~draft-insert-mail-header-separator."
(replace-match ""))))) (replace-match "")))))
(defun mu4e~draft-user-wants-reply-all (origmsg) (defun mu4e~draft-user-wants-reply-all (origmsg)
"Ask user whether she wants to reply to *all* recipients if there "Ask user whether she wants to reply to *all* recipients.
are more than 1 (based on ORIGMSG)." If there is just one recipient of ORIGMSG do nothing."
(let* ((recipnum (let* ((recipnum
(+ (length (mu4e~draft-create-to-lst origmsg)) (+ (length (mu4e~draft-create-to-lst origmsg))
(length (mu4e~draft-create-cc-lst origmsg t)))) (length (mu4e~draft-create-cc-lst origmsg t))))
@ -226,8 +227,8 @@ are more than 1 (based on ORIGMSG)."
(eq response 'all))) (eq response 'all)))
(defun mu4e~draft-message-filename-construct (&optional flagstr) (defun mu4e~draft-message-filename-construct (&optional flagstr)
"Construct a randomized name for a message file with flags FLAGSTR; it looks "Construct a randomized name for a message file with flags FLAGSTR.
something like It looks something like
<time>-<random>.<hostname>:2, <time>-<random>.<hostname>:2,
You can append flags." You can append flags."
(let* ((hostname (let* ((hostname
@ -307,7 +308,7 @@ You can append flags."
(defvar mu4e~draft-drafts-folder nil (defvar mu4e~draft-drafts-folder nil
"The drafts-folder for this compose buffer, based on "The drafts-folder for this compose buffer, based on
mu4e-drafts-folder', which will be evaluated once.") mu4e-drafts-folder', which will be evaluated once.")
(defun mu4e-draft-open (compose-type &optional msg) (defun mu4e-draft-open (compose-type &optional msg)
"Open a draft file for a new message (when COMPOSE-TYPE is reply, forward or new), "Open a draft file for a new message (when COMPOSE-TYPE is reply, forward or new),

View File

@ -67,14 +67,14 @@ rightmost (last) field."
:group 'mu4e-headers) :group 'mu4e-headers)
(defcustom mu4e-headers-date-format "%x" (defcustom mu4e-headers-date-format "%x"
"Date format to use in the headers view, in the format of "Date format to use in the headers view.
`format-time-string'." In the format of `format-time-string'."
:type 'string :type 'string
:group 'mu4e-headers) :group 'mu4e-headers)
(defcustom mu4e-headers-time-format "%X" (defcustom mu4e-headers-time-format "%X"
"Time format to use in the headers view, in the format of "Time format to use in the headers view.
`format-time-string'." In the format of `format-time-string'."
:type 'string :type 'string
:group 'mu4e-headers) :group 'mu4e-headers)
@ -122,9 +122,8 @@ indexing operation showed changes."
(defvar mu4e-headers-actions (defvar mu4e-headers-actions
'( ("capture message" . mu4e-action-capture-message)) '( ("capture message" . mu4e-action-capture-message))
"List of actions to perform on messages in the headers list. The actions "List of actions to perform on messages in the headers list.
are of the form: The actions are of the form (NAME SHORTCUT FUNC) where:
(NAME SHORTCUT FUNC) where:
* NAME is the name of the action (e.g. \"Count lines\") * NAME is the name of the action (e.g. \"Count lines\")
* SHORTCUT is a one-character shortcut to call this action * SHORTCUT is a one-character shortcut to call this action
* FUNC is a function which receives a message plist as an argument.") * FUNC is a function which receives a message plist as an argument.")
@ -151,20 +150,21 @@ match.
PREDICATE-FUNC as PARAM. This is useful for getting user-input.") PREDICATE-FUNC as PARAM. This is useful for getting user-input.")
(defvar mu4e-headers-sortfield :date (defvar mu4e-headers-sortfield :date
"Field to sort the headers by. Field must be a symbol, one of: "Field to sort the headers by.
:date, :subject, :size, :prio, :from, :to.") Field must be a symbol, one of: :date, :subject, :size, :prio,
:from, :to.")
(defvar mu4e-headers-sort-revert t (defvar mu4e-headers-sort-revert t
"Whether to revert the sort-order, i.e. Z->A instead of A-Z. When "Whether to revert the sort-order.
sorting by date, it's useful to go from biggest to smallest, so i.e. Z>A instead of A>Z. When sorting by date, it's useful to go
newest messages come first.") from biggest to smallest, so newest messages come first.")
(defvar mu4e-headers-show-threads t (defvar mu4e-headers-show-threads t
"Whether to show threads in the headers list.") "Whether to show threads in the headers list.")
(defvar mu4e-headers-full-search nil (defvar mu4e-headers-full-search nil
"Whether to show all results (or just up to "Whether to show all results.
`mu4e-search-results-limit')") If this is nil show results up to `mu4e-search-results-limit')")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -173,10 +173,10 @@ newest messages come first.")
;; docid cookies ;; docid cookies
(defconst mu4e~headers-docid-pre (purecopy "\376") (defconst mu4e~headers-docid-pre (purecopy "\376")
"Each header starts (invisibly) with the `mu4e~headers-docid-pre', "Each header starts (invisibly) with the `mu4e~headers-docid-pre',
followed by the docid, followed by `mu4e~headers-docid-post'.") followed by the docid, followed by `mu4e~headers-docid-post'.")
(defconst mu4e~headers-docid-post (purecopy "\377") (defconst mu4e~headers-docid-post (purecopy "\377")
"Each header starts (invisibly) with the `mu4e~headers-docid-pre', "Each header starts (invisibly) with the `mu4e~headers-docid-pre',
followed by the docid, followed by `mu4e~headers-docid-post'.") followed by the docid, followed by `mu4e~headers-docid-post'.")
(defvar mu4e~headers-view-win nil (defvar mu4e~headers-view-win nil
"The view window connected to this headers view.") "The view window connected to this headers view.")
@ -188,8 +188,8 @@ newest messages come first.")
("zsize" . :size) ("zsize" . :size)
("subject" . :subject) ("subject" . :subject)
("to" . :to)) ("to" . :to))
"List of cells describing the various sort-options (in the format "List of cells describing the various sort-options.
needed for `mu4e-read-option'.") In the format needed for `mu4e-read-option'.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -299,11 +299,11 @@ into a string."
" ")))) " "))))
(defsubst mu4e~headers-flags-str (flags) (defsubst mu4e~headers-flags-str (flags)
"Get a display string for the flags; note, there is "Get a display string for the flags.
`mu4e-flags-to-string' but that is for internal use; this function Note that `mu4e-flags-to-string' is for internal use only; this
is for display. (This difference is significant, since internally, function is for display. (This difference is significant, since
the Maildir spec determines what the flags look like, while our internally, the Maildir spec determines what the flags look like,
display may be different)." while our display may be different)."
(let ((str) (let ((str)
(get-prefix (get-prefix
(lambda (cell) (if mu4e-use-fancy-chars (cdr cell) (car cell))))) (lambda (cell) (if mu4e-use-fancy-chars (cdr cell) (car cell)))))
@ -327,13 +327,13 @@ display may be different)."
(defconst mu4e-headers-from-or-to-prefix '("" . "To ") (defconst mu4e-headers-from-or-to-prefix '("" . "To ")
"Prefix for the :from-or-to field when it is showing, "Prefix for the :from-or-to field.
respectively, From: or To:. It's a cons cell with the car element It's a cons cell with the car element being the From: prefix, the
being the From: prefix, the cdr element the To: prefix.") cdr element the To: prefix.")
(defsubst mu4e~headers-from-or-to (msg) (defsubst mu4e~headers-from-or-to (msg)
"When the from address for message MSG is one of the the user's addresses, "When the from address for message MSG is one of the the user's addresses,
(as per `mu4e-user-mail-address-list'), show the To address; \(as per `mu4e-user-mail-address-list'), show the To address;
otherwise ; show the from address; prefixed with the appropriate otherwise ; show the from address; prefixed with the appropriate
`mu4e-headers-from-or-to-prefix'." `mu4e-headers-from-or-to-prefix'."
(let ((addr (cdr-safe (car-safe (mu4e-message-field msg :from))))) (let ((addr (cdr-safe (car-safe (mu4e-message-field msg :from)))))
@ -344,15 +344,16 @@ otherwise ; show the from address; prefixed with the appropriate
(mu4e~headers-contact-str (mu4e-message-field msg :from)))))) (mu4e~headers-contact-str (mu4e-message-field msg :from))))))
(defsubst mu4e~headers-human-date (msg) (defsubst mu4e~headers-human-date (msg)
"Show a 'human' date -- that is, if the date is today, show the "Show a 'human' date.
date, otherwise, show the time. The formats used for date and time If the date is today, show the time, otherwise, show the
are `mu4e-headers-date-format' and `mu4e-headers-time-format'." date. The formats used for date and time are
`mu4e-headers-date-format' and `mu4e-headers-time-format'."
(let ((date (mu4e-msg-field msg :date))) (let ((date (mu4e-msg-field msg :date)))
(if (= (nth 3 (decode-time date)) (nth 3 (decode-time (current-time)))) (if (= (nth 3 (decode-time date)) (nth 3 (decode-time (current-time))))
(format-time-string mu4e-headers-time-format date) (format-time-string mu4e-headers-time-format date)
(format-time-string mu4e-headers-date-format date)))) (format-time-string mu4e-headers-date-format date))))
;; note: this function is very performance-sensitive ;; note: this function is very performance-sensitive
(defun mu4e~headers-header-handler (msg &optional point) (defun mu4e~headers-header-handler (msg &optional point)
"Create a one line description of MSG in this buffer, at POINT, "Create a one line description of MSG in this buffer, at POINT,
if provided, or at the end of the buffer otherwise." if provided, or at the end of the buffer otherwise."
@ -685,8 +686,8 @@ user-interaction ongoing."
"The highlighted docid") "The highlighted docid")
(defun mu4e~headers-highlight (docid) (defun mu4e~headers-highlight (docid)
"Highlight the header with DOCID, or do nothing if it's not "Highlight the header with DOCID, or do nothing if it's not found.
found. Also, unhighlight any previously highlighted headers." Also, unhighlight any previously highlighted headers."
(with-current-buffer mu4e~headers-buffer (with-current-buffer mu4e~headers-buffer
(save-excursion (save-excursion
;; first, unhighlight the previously highlighted docid, if any ;; first, unhighlight the previously highlighted docid, if any
@ -803,8 +804,9 @@ text-property `msg'."
'docid docid 'msg msg))))))) 'docid docid 'msg msg)))))))
(defun mu4e~headers-remove-header (docid &optional ignore-missing) (defun mu4e~headers-remove-header (docid &optional ignore-missing)
"Remove header with DOCID at POINT; when IGNORE-MISSING is "Remove header with DOCID at point.
non-nill, don't raise an error when the docid is not found." When IGNORE-MISSING is non-nill, don't raise an error when the
docid is not found."
(with-current-buffer mu4e~headers-buffer (with-current-buffer mu4e~headers-buffer
(if (mu4e~headers-goto-docid docid) (if (mu4e~headers-goto-docid docid)
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
@ -866,9 +868,9 @@ of `mu4e-split-view', and return a window for the message view."
;; search-based marking ;; search-based marking
(defun mu4e-headers-for-each (func) (defun mu4e-headers-for-each (func)
"Call FUNC for each header, moving point to the header. FUNC "Call FUNC for each header, moving point to the header.
takes one argument msg, the msg s-expression for the corresponding FUNC takes one argument, the msg s-expression for the
header." corresponding header."
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(while (search-forward mu4e~headers-docid-pre nil t) (while (search-forward mu4e~headers-docid-pre nil t)
@ -942,8 +944,9 @@ matching messages with that mark."
(defun mu4e-headers-mark-thread (&optional subthread) (defun mu4e-headers-mark-thread (&optional subthread)
"Mark the thread at point, if SUBTHREAD is non-nil, marking is "Mark the thread at point.
limited to the message at point and its descendants." If SUBTHREAD is non-nil, marking is limited to the message at
point and its descendants."
;; the tread id is shared by all messages in a thread ;; the tread id is shared by all messages in a thread
(interactive "P") (interactive "P")
(let* ((msg (mu4e-message-at-point)) (let* ((msg (mu4e-message-at-point))
@ -989,9 +992,10 @@ limited to the message at point and its descendants."
"Maximum size for the query stacks.") "Maximum size for the query stacks.")
(defun mu4e~headers-push-query (query where) (defun mu4e~headers-push-query (query where)
"Push QUERY to one of the query stacks; WHERE is a symbol telling "Push QUERY to one of the query stacks.
us where to push; it's a symbol, either 'future or WHERE is a symbol telling us where to push; it's a symbol, either
'past. Functional also removes duplicats, limits the stack size." 'future or 'past. Functional also removes duplicats, limits the
stack size."
(let ((stack (let ((stack
(case where (case where
(past mu4e~headers-query-past) (past mu4e~headers-query-past)
@ -1010,8 +1014,9 @@ us where to push; it's a symbol, either 'future or
(future (setq mu4e~headers-query-future stack)))))) (future (setq mu4e~headers-query-future stack))))))
(defun mu4e~headers-pop-query (whence) (defun mu4e~headers-pop-query (whence)
"Pop a query from the stack. WHENCE is a symbol telling us where "Pop a query from the stack.
to get it from; it's a symbol, either 'future or 'past." WHENCE is a symbol telling us where to get it from; it's a
symbol, either 'future or 'past."
(case whence (case whence
(past (past
(unless mu4e~headers-query-past (unless mu4e~headers-query-past
@ -1085,8 +1090,9 @@ the last search expression."
(defun mu4e-headers-change-sorting (&optional dont-refresh) (defun mu4e-headers-change-sorting (&optional dont-refresh)
"Interactively change the sorting/threading parameters. With prefix-argument, "Interactively change the sorting/threading parameters.
do _not_ refresh the last search with the new parameters." With prefix-argument, do _not_ refresh the last search with the
new parameters."
(interactive "P") (interactive "P")
(let* ((sortfield (let* ((sortfield
(mu4e-read-option "Sortfield: " mu4e~headers-sortfield-choices)) (mu4e-read-option "Sortfield: " mu4e~headers-sortfield-choices))
@ -1105,9 +1111,9 @@ do _not_ refresh the last search with the new parameters."
(mu4e-headers-rerun-search)))) (mu4e-headers-rerun-search))))
(defun mu4e-headers-toggle-threading (&optional dont-refresh) (defun mu4e-headers-toggle-threading (&optional dont-refresh)
"Toggle threading on/off for the search results. With prefix-argument, "Toggle threading on/off for the search results.
do _not_ refresh the last search with the new setting for With prefix-argument, do _not_ refresh the last search with the
threading." new setting for threading."
(interactive "P") (interactive "P")
(setq mu4e-headers-show-threads (not mu4e-headers-show-threads)) (setq mu4e-headers-show-threads (not mu4e-headers-show-threads))
(mu4e-message "Threading turned %s%s" (mu4e-message "Threading turned %s%s"
@ -1118,9 +1124,9 @@ threading."
(mu4e-headers-rerun-search))) (mu4e-headers-rerun-search)))
(defun mu4e-headers-toggle-full-search (&optional dont-refresh) (defun mu4e-headers-toggle-full-search (&optional dont-refresh)
"Toggle full-search on/off for the search results. With prefix-argument, "Toggle full-search on/off for the search results.
do _not_ refresh the last search with the new setting for With prefix-argument, do _not_ refresh the last search with the
threading." new setting for threading."
(interactive "P") (interactive "P")
(setq mu4e-headers-full-search (not mu4e-headers-full-search)) (setq mu4e-headers-full-search (not mu4e-headers-full-search))
(mu4e-message "Full search turned %s%s" (mu4e-message "Full search turned %s%s"
@ -1147,11 +1153,12 @@ threading."
mu4e~headers-loading-buf) mu4e~headers-loading-buf)
(defun mu4e-headers-view-message () (defun mu4e-headers-view-message ()
"View message at point. If there's an existing window for the "View message at point.
view, re-use that one. If not, create a new one, depending on the If there's an existing window for the view, re-use that one. If
value of `mu4e-split-view': if it's a symbol `horizontal' or not, create a new one, depending on the value of
`vertical', split the window accordingly; if it is nil, replace the `mu4e-split-view': if it's a symbol `horizontal' or `vertical',
current window. " split the window accordingly; if it is nil, replace the current
window. "
(interactive) (interactive)
(unless (eq major-mode 'mu4e-headers-mode) (unless (eq major-mode 'mu4e-headers-mode)
(mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode)) (mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))
@ -1177,9 +1184,9 @@ current window. "
(mu4e-headers-search mu4e~headers-last-query)) (mu4e-headers-search mu4e~headers-last-query))
(defun mu4e~headers-query-navigate (whence) (defun mu4e~headers-query-navigate (whence)
"Execute the previous query from the query stacks. WHENCE "Execute the previous query from the query stacks.
determines where the query is taken from and is a symbol, either WHENCE determines where the query is taken from and is a symbol,
`future' or `past'." either `future' or `past'."
(let ((query (mu4e~headers-pop-query whence)) (let ((query (mu4e~headers-pop-query whence))
(where (if (eq whence 'future) 'past 'future))) (where (if (eq whence 'future) 'past 'future)))
(when query (when query
@ -1232,16 +1239,18 @@ docid. Otherwise, return nil."
docid))) docid)))
(defun mu4e-headers-next (&optional n) (defun mu4e-headers-next (&optional n)
"Move point to the next message header. If this succeeds, return "Move point to the next message header.
the new docid. Otherwise, return nil. Optionally, takes an integer If this succeeds, return the new docid. Otherwise, return nil.
N (prefix argument), to the Nth next header." Optionally, takes an integer N (prefix argument), to the Nth next
header."
(interactive "P") (interactive "P")
(mu4e~headers-move (or n 1))) (mu4e~headers-move (or n 1)))
(defun mu4e-headers-prev (&optional n) (defun mu4e-headers-prev (&optional n)
"Move point to the previous message header. If this succeeds, return "Move point to the previous message header.
the new docid. Otherwise, return nil. Optionally, takes an integer If this succeeds, return the new docid. Otherwise, return nil.
N (prefix argument), to the Nth previous header." Optionally, takes an integer N (prefix argument), to the Nth
previous header."
(interactive "P") (interactive "P")
(mu4e~headers-move (- (or n 1)))) (mu4e~headers-move (- (or n 1))))
@ -1274,8 +1283,8 @@ N. Otherwise, don't do anything."
(incf mu4e-headers-visible-columns n))))))) (incf mu4e-headers-visible-columns n)))))))
(defun mu4e-headers-action () (defun mu4e-headers-action ()
"Ask user what to do with message-at-point, then do it. The "Ask user what to do with message-at-point, then do it.
actions are specified in `mu4e-headers-actions'." The actions are specified in `mu4e-headers-actions'."
(interactive) (interactive)
(let ((msg (mu4e-message-at-point)) (let ((msg (mu4e-message-at-point))
(actionfunc (mu4e-read-option "Action: " mu4e-headers-actions))) (actionfunc (mu4e-read-option "Action: " mu4e-headers-actions)))
@ -1289,8 +1298,9 @@ region if there is a region, then move to the next message."
(mu4e-headers-next)) (mu4e-headers-next))
(defun mu4e~headers-quit-buffer () (defun mu4e~headers-quit-buffer ()
"Quit the mu4e-headers buffer. This is a rather complex function, "Quit the mu4e-headers buffer.
to ensure we don't disturb other windows." This is a rather complex function, to ensure we don't disturb
other windows."
(interactive) (interactive)
(unless (eq major-mode 'mu4e-headers-mode) (unless (eq major-mode 'mu4e-headers-mode)
(mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode)) (mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))

View File

@ -69,10 +69,10 @@
(defun mu4e~main-action-str (str &optional func-or-shortcut) (defun mu4e~main-action-str (str &optional func-or-shortcut)
"Highlight the first occurence of [..] in STR. If "Highlight the first occurence of [..] in STR.
FUNC-OR-SHORTCUT is non-nil and if it is a function, call it when If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it
STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is a when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT
string, execute the corresponding keyboard action when it is is a string, execute the corresponding keyboard action when it is
clicked." clicked."
(let ((newstr (let ((newstr
(replace-regexp-in-string (replace-regexp-in-string

View File

@ -83,11 +83,11 @@ where
(clrhash mu4e~mark-map)) (clrhash mu4e~mark-map))
(defun mu4e-mark-at-point (mark &optional target) (defun mu4e-mark-at-point (mark &optional target)
"Mark (or unmark) message at point. MARK specifies the "Mark (or unmark) message at point.
mark-type. For `move'-marks and `trash'-marks there is also the MARK specifies the mark-type. For `move'-marks and `trash'-marks
TARGET argument, which specifies to which maildir the message is to there is also the TARGET argument, which specifies to which
be moved/trashed. The function works in both headers buffers and maildir the message is to be moved/trashed. The function works in
message buffers. both headers buffers and message buffers.
The following marks are available, and the corresponding props: The following marks are available, and the corresponding props:
@ -201,8 +201,9 @@ headers in the region. Optionally, provide TARGET (for moves)."
(mu4e-mark-at-point (car markcell) (cdr markcell))))))) (mu4e-mark-at-point (car markcell) (cdr markcell)))))))
(defun mu4e~mark-get-markpair (prompt &optional allow-something) (defun mu4e~mark-get-markpair (prompt &optional allow-something)
"Ask user for a mark; return (MARK . TARGET). If ALLOW-SOMETHING "Ask user for a mark; return (MARK . TARGET).
is non-nil, allow the 'something' pseudo mark as well." If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark
as well."
(let* ((marks '( ("refile" . refile) (let* ((marks '( ("refile" . refile)
("move" . move) ("move" . move)
("dtrash" . trash) ("dtrash" . trash)
@ -222,8 +223,9 @@ is non-nil, allow the 'something' pseudo mark as well."
(defun mu4e-mark-resolve-deferred-marks () (defun mu4e-mark-resolve-deferred-marks ()
"Check if there are any deferred ('something') marks. If there are such marks, "Check if there are any deferred ('something') marks.
replace them with a _real_ mark (ask the user which one)." If there are such marks, replace them with a _real_ mark (ask the
user which one)."
(interactive) (interactive)
(let ((markpair)) (let ((markpair))
(maphash (maphash
@ -248,11 +250,11 @@ replace them with a _real_ mark (ask the user which one)."
(defun mu4e-mark-execute-all (&optional no-confirmation) (defun mu4e-mark-execute-all (&optional no-confirmation)
"Execute the actions for all marked messages in this "Execute the actions for all marked messages in this buffer.
buffer. After the actions have been executed succesfully, the After the actions have been executed succesfully, the affected
affected messages are *hidden* from the current header list. Since messages are *hidden* from the current header list. Since the
the headers are the result of a search, we cannot be certain that headers are the result of a search, we cannot be certain that the
the messages no longer matches the current one - to get that messages no longer matches the current one - to get that
certainty, we need to rerun the search, but we don't want to do certainty, we need to rerun the search, but we don't want to do
that automatically, as it may be too slow and/or break the users that automatically, as it may be too slow and/or break the users
flow. Therefore, we hide the message, which in practice seems to flow. Therefore, we hide the message, which in practice seems to

View File

@ -35,26 +35,29 @@
(defcustom mu4e-html2text-command nil (defcustom mu4e-html2text-command nil
"Shell command that converts HTML from stdin into plain text on "Shell command that converts from html to plain text.
stdout. If this is not defined, the emacs `html2text' tool will be The command has to read html from stdin and output plain text on
used when faced with html-only message. If you use htmltext, it's stdout. If this is not defined, the emacs `html2text' tool will
recommended you use \"html2text -utf8 -width 72\"." be used when faced with html-only message. If you use htmltext,
it's recommended you use \"html2text -utf8 -width 72\"."
:type 'string :type 'string
:group 'mu4e-view :group 'mu4e-view
:safe 'stringp) :safe 'stringp)
(defcustom mu4e-view-prefer-html nil (defcustom mu4e-view-prefer-html nil
"Whether to base the body display on the HTML-version of the "Whether to base the body display on the html-version.
e-mail message (if there is any." If the e-mail message has no html-version the plain-text version
is always used."
:type 'boolean :type 'boolean
:group 'mu4e-view) :group 'mu4e-view)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defsubst mu4e-message-field-raw (msg field) (defsubst mu4e-message-field-raw (msg field)
"Retrieve FIELD from message plist MSG. FIELD is one "Retrieve FIELD from message plist MSG.
of :from, :to, :cc, :bcc, :subject, :data, :message-id, :path, :maildir, FIELD is one of :from, :to, :cc, :bcc, :subject, :data,
:priority, :attachments, :references, :in-reply-to, :body-txt, :body-html :message-id, :path, :maildir, :priority, :attachments,
:references, :in-reply-to, :body-txt, :body-html
Returns `nil' if the field does not exist. Returns `nil' if the field does not exist.
@ -128,16 +131,18 @@ there is no message at point."
(unless noerror (mu4e-warn "No message at point"))))) (unless noerror (mu4e-warn "No message at point")))))
(defsubst mu4e-message-field-at-point (field) (defsubst mu4e-message-field-at-point (field)
"Get the field FIELD from the message at point; equivalent to "Get the field FIELD from the message at point.
(mu4e-message-field (mu4e-message-at-point FIELD))." This is equivalent to:
(mu4e-message-field (mu4e-message-at-point) FIELD)."
(mu4e-message-field (mu4e-message-at-point) field)) (mu4e-message-field (mu4e-message-at-point) field))
(defun mu4e-message-body-text (msg) (defun mu4e-message-body-text (msg)
"Get the body in text form for this message, which is either :body-txt, "Get the body in text form for this message.
or if not available, :body-html converted to text. By default, it This is either :body-txt, or if not available, :body-html
uses the emacs built-in `html2text'. Alternatively, if converted to text. By default, it uses the emacs built-in
`mu4e-html2text-command' is non-nil, it will use that. Normally, `html2text'. Alternatively, if `mu4e-html2text-command' is
function prefers the text part, but this can be changed by setting non-nil, it will use that. Normally, function prefers the text
part, but this can be changed by setting
`mu4e-view-prefer-html'." `mu4e-view-prefer-html'."
(let* ((txt (mu4e-message-field msg :body-txt)) (let* ((txt (mu4e-message-field msg :body-txt))
(html (mu4e-message-field msg :body-html)) (html (mu4e-message-field msg :body-html))
@ -203,7 +208,7 @@ match."
(defsubst mu4e-message-part-field (msgpart field) (defsubst mu4e-message-part-field (msgpart field)
"Get some field in a message part; a part would look something like: "Get some field in a message part; a part would look something like:
(:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)." (:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)."
(plist-get msgpart field)) (plist-get msgpart field))

View File

@ -32,8 +32,7 @@
;; internal vars ;; internal vars
(defvar mu4e~proc-buf nil (defvar mu4e~proc-buf nil
"Buffer (string) for data received from "Buffer (string) for data received from the backend.")
the backend.")
(defconst mu4e~proc-name " *mu4e-proc*" (defconst mu4e~proc-name " *mu4e-proc*"
"Name of the server process, buffer.") "Name of the server process, buffer.")
(defvar mu4e~proc-process nil (defvar mu4e~proc-process nil
@ -42,16 +41,16 @@ the backend.")
;; dealing with the length cookie that precedes expressions ;; dealing with the length cookie that precedes expressions
(defconst mu4e~cookie-pre "\376" (defconst mu4e~cookie-pre "\376"
"Each expression we get from the backend (mu server) starts with "Each expression we get from the backend (mu server) starts with
a length cookie: a length cookie:
<`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.") <`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.")
(defconst mu4e~cookie-post "\377" (defconst mu4e~cookie-post "\377"
"Each expression we get from the backend (mu server) starts with "Each expression we get from the backend (mu server) starts with
a length cookie: a length cookie:
<`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.") <`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>.")
(defconst mu4e~cookie-matcher-rx (defconst mu4e~cookie-matcher-rx
(purecopy (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)" mu4e~cookie-post)) (purecopy (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)" mu4e~cookie-post))
"Regular expression matching the length cookie. Match 1 will be "Regular expression matching the length cookie.
the length (in hex).") Match 1 will be the length (in hex).")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -98,13 +97,13 @@ the length (in hex).")
t)) t))
(defsubst mu4e~proc-eat-sexp-from-buf () (defsubst mu4e~proc-eat-sexp-from-buf ()
"'Eat' the next s-expression from `mu4e~proc-buf'. Note: this is a string, "'Eat' the next s-expression from `mu4e~proc-buf'.
not an emacs-buffer. `mu4e~proc-buf gets its contents from the Note: this is a string, not an emacs-buffer. `mu4e~proc-buf gets
mu-servers in the following form: its contents from the mu-servers in the following form:
<`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'> <`mu4e~cookie-pre'><length-in-hex><`mu4e~cookie-post'>
Function returns this sexp, or nil if there was Function returns this sexp, or nil if there was none.
none. `mu4e~proc-buf' is updated as well, with all processed sexp `mu4e~proc-buf' is updated as well, with all processed sexp data
data removed." removed."
(ignore-errors ;; the server may die in the middle... (ignore-errors ;; the server may die in the middle...
;; mu4e~cookie-matcher-rx: ;; mu4e~cookie-matcher-rx:
;; (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)]" mu4e~cookie-post) ;; (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)]" mu4e~cookie-post)
@ -129,9 +128,9 @@ data removed."
(defsubst mu4e~proc-filter (proc str) (defsubst mu4e~proc-filter (proc str)
"A process-filter for the 'mu server' output; it accumulates the "A process-filter for the 'mu server' output.
strings into valid sexps by checking of the ';;eox' end-of-sexp It accumulates the strings into valid sexps by checking of the
marker, and then evaluating them. ';;eox' end-of-sexp marker, and then evaluating them.
The server output is as follows: The server output is as follows:
@ -267,8 +266,7 @@ The server output is as follows:
;;(defconst mu4e-xapian-empty 19 "Error code: xapian is empty/non-existent") ;;(defconst mu4e-xapian-empty 19 "Error code: xapian is empty/non-existent")
(defun mu4e~proc-sentinel (proc msg) (defun mu4e~proc-sentinel (proc msg)
"Function that will be called when the mu-server process "Function that will be called when the mu-server process terminates."
terminates."
(let ((status (process-status proc)) (code (process-exit-status proc))) (let ((status (process-status proc)) (code (process-exit-status proc)))
(setq mu4e~proc-process nil) (setq mu4e~proc-process nil)
(setq mu4e~proc-buf "") ;; clear any half-received sexps (setq mu4e~proc-buf "") ;; clear any half-received sexps
@ -291,7 +289,8 @@ terminates."
(error "Something bad happened to the mu server process"))))) (error "Something bad happened to the mu server process")))))
(defsubst mu4e~proc-send-command (frm &rest args) (defsubst mu4e~proc-send-command (frm &rest args)
"Send as command to the mu server process; start the process if needed." "Send as command to the mu server process.
Start the process if needed."
(unless (mu4e~proc-running-p) (unless (mu4e~proc-running-p)
(mu4e~proc-start)) (mu4e~proc-start))
(let ((cmd (apply 'format frm args))) (let ((cmd (apply 'format frm args)))
@ -313,20 +312,21 @@ sexp, which are handled my `mu4e-error-func', respectively."
(mu4e~proc-send-command "remove docid:%d" docid)) (mu4e~proc-send-command "remove docid:%d" docid))
(defun mu4e~proc-escape-query (query) (defun mu4e~proc-escape-query (query)
"Escape the query QUERY for transport, in particular, backslashes "Escape the query QUERY for transport.
and double-quotes." In particular, backslashes and double-quotes."
(let ((esc (replace-regexp-in-string "\\\\" "\\\\\\\\" query))) (let ((esc (replace-regexp-in-string "\\\\" "\\\\\\\\" query)))
(replace-regexp-in-string "\"" "\\\\\"" esc))) (replace-regexp-in-string "\"" "\\\\\"" esc)))
(defun mu4e~proc-find (query threads sortfield revert maxnum) (defun mu4e~proc-find (query threads sortfield revert maxnum)
"Start a database query for QUERY. If THREADS is non-nil, show "Start a database query for QUERY.
results in threaded fasion, SORTFIELD is a symbol describing the If THREADS is non-nil, show results in threaded fasion, SORTFIELD
field to sort by (or nil); see `mu4e~headers-sortfield-choices'. If is a symbol describing the field to sort by (or nil); see
REVERT is non-nil, sort Z->A instead of A->Z. MAXNUM determines the `mu4e~headers-sortfield-choices'. If REVERT is non-nil, sort Z->A
maximum number of results to return, or nil for 'unlimited'. For instead of A->Z. MAXNUM determines the maximum number of results
each result found, a function is called, depending on the kind of to return, or nil for 'unlimited'. For each result found, a
result. The variables `mu4e-error-func' contain the function that function is called, depending on the kind of result. The
will be called for, resp., a message (header row) or an error." variables `mu4e-error-func' contain the function that will be
called for, resp., a message (header row) or an error."
(mu4e~proc-send-command (mu4e~proc-send-command
"find query:\"%s\" threads:%s sortfield:%s reverse:%s maxnum:%d" "find query:\"%s\" threads:%s sortfield:%s reverse:%s maxnum:%d"
(mu4e~proc-escape-query query) (mu4e~proc-escape-query query)
@ -337,10 +337,10 @@ will be called for, resp., a message (header row) or an error."
(if maxnum maxnum -1))) (if maxnum maxnum -1)))
(defun mu4e~proc-move (docid-or-msgid &optional maildir flags) (defun mu4e~proc-move (docid-or-msgid &optional maildir flags)
"Move message identified by DOCID-OR-MSGID. At least one of "Move message identified by DOCID-OR-MSGID.
MAILDIR and FLAGS should be specified. Note, even if MAILDIR is At least one of MAILDIR and FLAGS should be specified. Note, even
nil, this is still a move, since a change in flags still implies if MAILDIR is nil, this is still a move, since a change in flags
a change in message filename. still implies a change in message filename.
MAILDIR (), optionally MAILDIR (), optionally
setting FLAGS (keyword argument :flags). optionally setting FLAGS setting FLAGS (keyword argument :flags). optionally setting FLAGS
@ -393,15 +393,17 @@ of 'my' email addresses (see `mu4e-user-mail-address-list')."
(mu4e~proc-send-command "index path:\"%s\"" path)))) (mu4e~proc-send-command "index path:\"%s\"" path))))
(defun mu4e~proc-add (path maildir) (defun mu4e~proc-add (path maildir)
"Add the message at PATH to the database, with MAILDIR set to the "Add the message at PATH to the database.
maildir this message resides in, e.g. '/drafts'; if this works, we With MAILDIR set to the maildir this message resides in,
will receive (:info add :path <path> :docid <docid>)." e.g. '/drafts'; if this works, we will receive (:info add :path
<path> :docid <docid>)."
(mu4e~proc-send-command "add path:\"%s\" maildir:\"%s\"" (mu4e~proc-send-command "add path:\"%s\" maildir:\"%s\""
path maildir)) path maildir))
(defun mu4e~proc-sent (path maildir) (defun mu4e~proc-sent (path maildir)
"Add the message at PATH to the database, with MAILDIR set to the "Add the message at PATH to the database.
maildir this message resides in, e.g. '/drafts'. With MAILDIR set to the maildir this message resides in,
e.g. '/drafts'.
if this works, we will receive (:info add :path <path> :docid if this works, we will receive (:info add :path <path> :docid
<docid> :fcc <path>)." <docid> :fcc <path>)."
@ -414,7 +416,7 @@ maildir this message resides in, e.g. '/drafts'.
message (ie, replying to, forwarding, editing) with DOCID or nil message (ie, replying to, forwarding, editing) with DOCID or nil
for type `new'. for type `new'.
The result will be delivered to the function registered as The result will be delivered to the function registered as
`mu4e-compose-func'." `mu4e-compose-func'."
(unless (member type '(forward reply edit new)) (unless (member type '(forward reply edit new))
(mu4e-error "Unsupported compose-type %S" type)) (mu4e-error "Unsupported compose-type %S" type))
@ -451,25 +453,24 @@ mean:
(defun mu4e~proc-ping () (defun mu4e~proc-ping ()
"Sends a ping to the mu server, expecting a (:pong ...) in "Sends a ping to the mu server, expecting a (:pong ...) in response."
response."
(mu4e~proc-send-command "ping")) (mu4e~proc-send-command "ping"))
(defun mu4e~proc-contacts (personal after) (defun mu4e~proc-contacts (personal after)
"Sends the contacts command to the mu server, expecting "Sends the contacts command to the mu server.
a (:contacts (<list>)) in response. If PERSONAL is non-nil, only A (:contacts (<list>)) is expected in response. If PERSONAL is
get personal contacts, if AFTER is non-nil, get only contacts non-nil, only get personal contacts, if AFTER is non-nil, get
seen AFTER (the time_t value)." only contacts seen AFTER (the time_t value)."
(mu4e~proc-send-command (mu4e~proc-send-command
"contacts personal:%s after:%d" "contacts personal:%s after:%d"
(if personal "true" "false") (if personal "true" "false")
(or after 0))) (or after 0)))
(defun mu4e~proc-view (docid-or-msgid &optional images decrypt) (defun mu4e~proc-view (docid-or-msgid &optional images decrypt)
"Get one particular message based on its "Get one particular message based on its DOCID-OR-MSGID.
DOCID-OR-MSGID. Optionally, if IMAGES is non-nil, backend will any Optionally, if IMAGES is non-nil, backend will any images
images attached to the message, and return them as temp files. The attached to the message, and return them as temp files.
result will be delivered to the function registered as The result will be delivered to the function registered as
`mu4e-message-func'." `mu4e-message-func'."
(mu4e~proc-send-command (mu4e~proc-send-command
"view %s extract-images:%s extract-encrypted:%s use-agent:true" "view %s extract-images:%s extract-encrypted:%s use-agent:true"
@ -478,9 +479,9 @@ result will be delivered to the function registered as
(if decrypt "true" "false"))) (if decrypt "true" "false")))
(defun mu4e~proc-view-path (path &optional images decrypt) (defun mu4e~proc-view-path (path &optional images decrypt)
"View message at PATH (keyword "View message at PATH (keyword argument).
argument). Optionally, if IMAGES is non-nil, backend will any Optionally, if IMAGES is non-nil, backend will any images
images attached to the message, and return them as temp files. The attached to the message, and return them as temp files. The
result will be delivered to the function registered as result will be delivered to the function registered as
`mu4e-message-func'." `mu4e-message-func'."
(mu4e~proc-send-command (mu4e~proc-send-command

View File

@ -49,8 +49,8 @@ used on a string that terminates immediately after the date.")
(defun mu4e-parse-time-string (s &optional nodefault) (defun mu4e-parse-time-string (s &optional nodefault)
"Parse the standard Org-mode time string. "Parse the standard Org-mode time string.
This should be a lot faster than the normal `parse-time-string'. This should be a lot faster than the normal `parse-time-string'.
If time is not given, defaults to 0:00. However, with optional NODEFAULT, If time is not given, defaults to 0:00. However, with optional
hour and minute fields will be nil if not given." NODEFAULT, hour and minute fields will be nil if not given."
(if (string-match mu4e~ts-regexp0 s) (if (string-match mu4e~ts-regexp0 s)
(list 0 (list 0
(if (or (match-beginning 8) (not nodefault)) (if (or (match-beginning 8) (not nodefault))
@ -65,8 +65,8 @@ hour and minute fields will be nil if not given."
(defun mu4e-user-mail-address-p (addr) (defun mu4e-user-mail-address-p (addr)
"If ADDR is one of user's e-mail addresses (as per "If ADDR is one of user's e-mail addresses return t, nil otherwise.
`mu4e-user-mail-address-list') return t, otherwise return nil." User's addresses are set in `mu4e-user-mail-address-list')."
(when (and addr mu4e-user-mail-address-list (when (and addr mu4e-user-mail-address-list
(find addr mu4e-user-mail-address-list :test 'string=)) (find addr mu4e-user-mail-address-list :test 'string=))
t)) t))
@ -78,9 +78,10 @@ hour and minute fields will be nil if not given."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; the standard folders can be functions too ;; the standard folders can be functions too
(defun mu4e~get-folder (foldervar msg) (defun mu4e~get-folder (foldervar msg)
"Get message folder FOLDER. If FOLDER is a string, return it, if "Get message folder FOLDER.
it is a function, evaluate this function with MSG as If FOLDER is a string, return it, if it is a function, evaluate
parameter (which may be `nil'), and return the result." this function with MSG as parameter (which may be `nil'), and
return the result."
(unless (member foldervar '(mu4e-sent-folder mu4e-drafts-folder (unless (member foldervar '(mu4e-sent-folder mu4e-drafts-folder
mu4e-trash-folder mu4e-refile-folder)) mu4e-trash-folder mu4e-refile-folder))
(mu4e-error "Folder must be either mu4e-sent-folder, (mu4e-error "Folder must be either mu4e-sent-folder,
@ -137,9 +138,9 @@ see its docstring)."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-create-maildir-maybe (dir) (defun mu4e-create-maildir-maybe (dir)
"Offer to create maildir DIR (full filesystem path) if it does "Offer to create maildir DIR if it does not exist yet.
not exist yet. Return t if the dir already existed, or has been Return t if the dir already existed, or has been created, nil
created, nil otherwise." otherwise. DIR has to be an absolute path."
(if (and (file-exists-p dir) (not (file-directory-p dir))) (if (and (file-exists-p dir) (not (file-directory-p dir)))
(mu4e-error "%s exists, but is not a directory." dir)) (mu4e-error "%s exists, but is not a directory." dir))
(cond (cond
@ -155,31 +156,31 @@ created, nil otherwise."
(apply 'format frm args))) (apply 'format frm args)))
(defun mu4e-message (frm &rest args) (defun mu4e-message (frm &rest args)
"Like `message', but prefixed with mu4e. If we're waiting for "Like `message', but prefixed with mu4e.
user-input, don't show anyhting." If we're waiting for user-input, don't show anyhting."
(unless (active-minibuffer-window) (unless (active-minibuffer-window)
(message "%s" (apply 'mu4e-format frm args)) (message "%s" (apply 'mu4e-format frm args))
nil)) nil))
(defun mu4e-error (frm &rest args) (defun mu4e-error (frm &rest args)
"Create [mu4e]-prefixed error based on format FRM and ARGS. Does "Create [mu4e]-prefixed error based on format FRM and ARGS.
a local-exit and does not return, and raises a Does a local-exit and does not return, and raises a
debuggable (backtrace) error." debuggable (backtrace) error."
(mu4e-log 'error (apply 'mu4e-format frm args)) (mu4e-log 'error (apply 'mu4e-format frm args))
(error "%s" (apply 'mu4e-format frm args))) (error "%s" (apply 'mu4e-format frm args)))
(defun mu4e-warn (frm &rest args) (defun mu4e-warn (frm &rest args)
"Create [mu4e]-prefixed warning based on format FRM and "Create [mu4e]-prefixed warning based on format FRM and ARGS.
ARGS. Does a local-exit and does not return. In emacs versions Does a local-exit and does not return. In emacs versions below
below 24.2, the functions is the same as `mu4e-error'." 24.2, the functions is the same as `mu4e-error'."
(mu4e-log 'error (apply 'mu4e-format frm args)) (mu4e-log 'error (apply 'mu4e-format frm args))
(if (fboundp 'user-error) (if (fboundp 'user-error)
(user-error "%s" (apply 'mu4e-format frm args)) ;; only in emacs-trunk (user-error "%s" (apply 'mu4e-format frm args)) ;; only in emacs-trunk
(error "%s" (apply 'mu4e-format frm args)))) (error "%s" (apply 'mu4e-format frm args))))
(defun mu4e~read-char-choice (prompt choices) (defun mu4e~read-char-choice (prompt choices)
"Compatiblity wrapper for `read-char-choice', which is emacs-24 "Compatiblity wrapper for `read-char-choice'.
only." That function is available which emacs-24 only."
(let ((choice) (ok) (inhibit-quit nil)) (let ((choice) (ok) (inhibit-quit nil))
(while (not ok) (while (not ok)
(message nil);; this seems needed... (message nil);; this seems needed...
@ -188,17 +189,17 @@ only."
choice)) choice))
(defun mu4e-read-option (prompt options) (defun mu4e-read-option (prompt options)
"Ask user for an option from a list on the input area. PROMPT "Ask user for an option from a list on the input area.
describes a multiple-choice question to the user, OPTIONS describe PROMPT describes a multiple-choice question to the user.
the options, and is a list of cells describing particular OPTIONS describe the options, and is a list of cells describing
options. Cells have the following structure: particular options. Cells have the following structure:
(OPTIONSTRING . RESULT) (OPTIONSTRING . RESULT)
where OPTIONSTRING is a non-empty string describing the where OPTIONSTRING is a non-empty string describing the
option. The first character of OPTIONSTRING is used as the option. The first character of OPTIONSTRING is used as the
shortcut, and obviously all shortcuts must be different, so you shortcut, and obviously all shortcuts must be different, so you
can prefix the string with an uniquifying character. can prefix the string with an uniquifying character.
The options are provided as a list for the user to choose from; The options are provided as a list for the user to choose from;
user can then choose by typing CHAR. Example: user can then choose by typing CHAR. Example:
@ -240,8 +241,7 @@ Function will return the cdr of the list element."
(defun mu4e~get-maildirs-1 (path mdir) (defun mu4e~get-maildirs-1 (path mdir)
"Get maildirs under path, recursively, as a list of relative "Get maildirs under path, recursively, as a list of relative paths."
paths."
(let ((dirs) (let ((dirs)
(dentries (dentries
(ignore-errors (ignore-errors
@ -397,7 +397,7 @@ Also see `mu4e-flags-to-string'.
(mu4e~string-to-flags-1 (substring str 1)))))) (mu4e~string-to-flags-1 (substring str 1))))))
(defun mu4e-string-to-flags (str) (defun mu4e-string-to-flags (str)
"Convert a string with message flags as seen in Maildir messages "Convert a string with message flags as seen in Maildir messages
into a list of flags in; flags are symbols draft, flagged, new, into a list of flags in; flags are symbols draft, flagged, new,
passed, replied, seen, trashed and the string is the concatenation passed, replied, seen, trashed and the string is the concatenation
of the uppercased first letters of these flags, as per [1]. Other of the uppercased first letters of these flags, as per [1]. Other
@ -420,8 +420,8 @@ http://cr.yp.to/proto/maildir.html "
(defun mu4e-display-manual () (defun mu4e-display-manual ()
"Display the mu4e manual page for the current mode, or go to the "Display the mu4e manual page for the current mode.
top level if there is none." Or go to the top level if there is none."
(interactive) (interactive)
(info (case major-mode (info (case major-mode
('mu4e-main-mode "(mu4e)Main view") ('mu4e-main-mode "(mu4e)Main view")
@ -469,10 +469,10 @@ that has a live window), and vice versa."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar mu4e-index-updated-hook nil (defvar mu4e-index-updated-hook nil
"Hook run when the indexing process had one or more updated "Hook run when the indexing process had one or more updated messages.
messages. This can be used as a simple way to invoke some action This can be used as a simple way to invoke some action when new
when new messages appear, but note that an update in the index does messages appear, but note that an update in the index does not
not necessarily mean a new message.") necessarily mean a new message.")
;; some handler functions for server messages ;; some handler functions for server messages
;; ;;
@ -510,10 +510,10 @@ process."
;; start and stopping ;; start and stopping
(defun mu4e~fill-contacts (contacts) (defun mu4e~fill-contacts (contacts)
"We receive a list of contacts, which each contact of the form "We receive a list of contacts, which each contact of the form
(:name NAME :mail EMAIL) (:name NAME :mail EMAIL)
and fill the list `mu4e~contacts-for-completion' with it, with and fill the list `mu4e~contacts-for-completion' with it, with
each element looking like each element looking like
name <email> name <email>
This is used by the completion function in mu4e-compose." This is used by the completion function in mu4e-compose."
(let ((lst)) (let ((lst))
(dolist (contact contacts) (dolist (contact contacts)
@ -563,13 +563,14 @@ This is used by the completion function in mu4e-compose."
(defun mu4e-running-p () (defun mu4e-running-p ()
"Whether mu4e is running -- that is, the server process is live." "Whether mu4e is running.
Checks whether the server process is live."
(mu4e~proc-running-p)) (mu4e~proc-running-p))
(defun mu4e~start (&optional func) (defun mu4e~start (&optional func)
"If mu4e is already running, execute function FUNC (if non-nil). Otherwise, "If mu4e is already running, execute function FUNC (if non-nil).
check various requirements, then start mu4e. When succesful, call Otherwise, check various requirements, then start mu4e. When
FUNC (if non-nil) afterwards." successful, call FUNC (if non-nil) afterwards."
;; if we're already running, simply go to the main view ;; if we're already running, simply go to the main view
(if (mu4e-running-p) ;; already running? (if (mu4e-running-p) ;; already running?
(when func ;; yes! run func if defined (when func ;; yes! run func if defined

View File

@ -41,8 +41,9 @@
:safe 'stringp) :safe 'stringp)
(defcustom mu4e-mu-binary (executable-find "mu") (defcustom mu4e-mu-binary (executable-find "mu")
"Name of the mu-binary to use; if it cannot be found in your "Name of the mu-binary to use.
PATH, you can specify the full path." If it cannot be found in your PATH, you can specify the full
path."
:type 'file :type 'file
:group 'mu4e :group 'mu4e
:safe 'stringp) :safe 'stringp)
@ -71,17 +72,17 @@ mu4e."
:safe 'integerp) :safe 'integerp)
(defcustom mu4e-attachment-dir (expand-file-name "~/") (defcustom mu4e-attachment-dir (expand-file-name "~/")
"Default directory for saving attachments. This can be either a "Default directory for saving attachments.
string, or a function that takes a filename FNAME and MIMETYPE as This can be either a string, or a function that takes a filename
arguments, and returns the attachment dir. Note, either or both of FNAME and MIMETYPE as arguments, and returns the attachment
the arguments may be `nil'." dir. Note, either or both of the arguments may be `nil'."
:type 'directory :type 'directory
:group 'mu4e :group 'mu4e
:safe 'stringp) :safe 'stringp)
(defcustom mu4e-user-mail-address-list `(,user-mail-address) (defcustom mu4e-user-mail-address-list `(,user-mail-address)
"List of e-mail addresses to consider 'my email addresses', "List of e-mail addresses to consider 'my email addresses'.
ie. addresses whose presence in an email imply that it is a I.e. addresses whose presence in an email imply that it is a
personal message. This is used when indexing messages." personal message. This is used when indexing messages."
:type '(repeat (string :tag "Address")) :type '(repeat (string :tag "Address"))
:group 'mu4e) :group 'mu4e)
@ -122,19 +123,22 @@ search."
("date:today..now" "Today's messages" ?t) ("date:today..now" "Today's messages" ?t)
("date:7d..now" "Last 7 days" ?w) ("date:7d..now" "Last 7 days" ?w)
("mime:image/*" "Messages with images" ?p)) ("mime:image/*" "Messages with images" ?p))
"A list of pre-defined queries; these will show up in the main "A list of pre-defined queries.
screen. Each of the list elements is a three-element list of the These will show up in the main screen. Each of the list elements
form (QUERY DESCRIPTION KEY), where QUERY is a string with a mu is a three-element list of the form (QUERY DESCRIPTION KEY),
query, DESCRIPTION is a short description of the query (this will where QUERY is a string with a mu query, DESCRIPTION is a short
show up in the UI), and KEY is a shortcut key for the query.") description of the query (this will show up in the UI), and KEY
is a shortcut key for the query.")
(defcustom mu4e-split-view 'horizontal (defcustom mu4e-split-view 'horizontal
"How to show messages / headers; a symbol which is either: * a "How to show messages / headers.
symbol 'horizontal: split horizontally (headers on top) * a symbol A symbol which is either:
'vertical: split vertically (headers on the left). * anything * `horizontal': split horizontally (headers on top)
else: don't split (show either headers or messages, not both) Also * `vertical': split vertically (headers on the left).
see `mu4e-headers-visible-lines' and * anything else: don't split (show either headers or messages,
`mu4e-headers-visible-columns'." not both)
Also see `mu4e-headers-visible-lines'
and `mu4e-headers-visible-columns'."
:type '(choice (const :tag "Split horizontally" horizontal) :type '(choice (const :tag "Split horizontally" horizontal)
(const :tag "Split vertically" vertical) (const :tag "Split vertically" vertical)
(const :tag "Don't split" nil))) (const :tag "Don't split" nil)))
@ -161,7 +165,8 @@ view buffer."
:group 'mu4e-crypto) :group 'mu4e-crypto)
(defcustom mu4e-decryption-policy t (defcustom mu4e-decryption-policy t
"Policy for dealing with encrypted parts. The setting is a symbol: "Policy for dealing with encrypted parts.
The setting is a symbol:
* t: try to decrypt automatically * t: try to decrypt automatically
* `ask': ask before decrypting anything * `ask': ask before decrypting anything
* nil: don't try to decrypt anything." * nil: don't try to decrypt anything."
@ -193,16 +198,15 @@ details (in particular, how to define your own e-mail addresses)."
:group 'mu4e-compose) :group 'mu4e-compose)
(defcustom mu4e-compose-complete-only-after "2010-01-01" (defcustom mu4e-compose-complete-only-after "2010-01-01"
"Consider only contacts last seen after this date. Date must be a "Consider only contacts last seen after this date.
string, in a format parseable by `org-parse-time-string'. This Date must be a string, in a format parseable by
excludes really old contacts. Set to nil to not have any `org-parse-time-string'. This excludes really old contacts.
time-based restriction." Set to nil to not have any time-based restriction."
:type 'string :type 'string
:group 'mu4e-compose) :group 'mu4e-compose)
(defcustom mu4e-compose-complete-ignore-address-regexp "no-?reply" (defcustom mu4e-compose-complete-ignore-address-regexp "no-?reply"
"Ignore any e-mail addresses for completion if they match this "Ignore any e-mail addresses for completion if they match this regexp."
regexp."
:type 'string :type 'string
:group 'mu4e-compose) :group 'mu4e-compose)
@ -223,9 +227,9 @@ replying to messages."
:group 'mu4e-compose) :group 'mu4e-compose)
(defvar mu4e-compose-parent-message nil (defvar mu4e-compose-parent-message nil
"The parent message plist -- the message being replied to, "The parent message plist.
forwarded or edited; used in `mu4e-compose-pre-hook. For new This is the message being replied to, forwarded or edited; used
messages, it is nil.") in `mu4e-compose-pre-hook'. For new messages, it is nil.")
;; Folders ;; Folders
(defgroup mu4e-folders nil (defgroup mu4e-folders nil
@ -233,7 +237,7 @@ messages, it is nil.")
:group 'mu4e) :group 'mu4e)
(defcustom mu4e-drafts-folder "/drafts" (defcustom mu4e-drafts-folder "/drafts"
"Your folder for draft messages, relative to `mu4e-maildir', "Your folder for draft messages, relative to `mu4e-maildir'.
e.g. \"/drafts\". Instead of a string, may also be a function that e.g. \"/drafts\". Instead of a string, may also be a function that
takes a message (a msg plist, see `mu4e-message-get-field'), and takes a message (a msg plist, see `mu4e-message-get-field'), and
returns a folder. Note, the message parameter refers to the returns a folder. Note, the message parameter refers to the
@ -285,9 +289,9 @@ re-edited, and is nil otherwise."
(defcustom mu4e-maildir-shortcuts nil (defcustom mu4e-maildir-shortcuts nil
"A list of maildir shortcuts to enable quickly going to the "A list of maildir shortcuts to enable quickly going to the
particular for, or quickly moving messages towards them (i.e., particular for, or quickly moving messages towards them (i.e.,
archiving or refiling). The list contains elements of the form archiving or refiling). The list contains elements of the form
(maildir . shortcut), where MAILDIR is a maildir (such as \(maildir . shortcut), where MAILDIR is a maildir (such as
\"/archive/\"), and shortcut a single shortcut character. With \"/archive/\"), and shortcut a single shortcut character. With
this, in the header buffer and view buffer you can execute this, in the header buffer and view buffer you can execute
`mu4e-mark-for-move-quick' (or 'm', by default) or `mu4e-mark-for-move-quick' (or 'm', by default) or
@ -307,8 +311,8 @@ designated shortcut character for the maildir.")
(defface mu4e-moved-face (defface mu4e-moved-face
'((t :inherit font-lock-comment-face :slant italic)) '((t :inherit font-lock-comment-face :slant italic))
"Face for a message header that has been moved to some "Face for a message header that has been moved to some folder.
folder (it's still visible in the search results, since we cannot \(It's still visible in the search results, since we cannot
be sure it no longer matches)." be sure it no longer matches)."
:group 'mu4e-faces) :group 'mu4e-faces)
@ -319,8 +323,8 @@ be sure it no longer matches)."
(defface mu4e-draft-face (defface mu4e-draft-face
'((t :inherit font-lock-string-face)) '((t :inherit font-lock-string-face))
"Face for a draft message header (i.e., a message with the draft "Face for a draft message header
flag set)." I.e. a message with the draft flag set."
:group 'mu4e-faces) :group 'mu4e-faces)
(defface mu4e-flagged-face (defface mu4e-flagged-face
@ -361,8 +365,7 @@ flag set)."
(defface mu4e-view-header-value-face (defface mu4e-view-header-value-face
'((t :inherit font-lock-doc-face)) '((t :inherit font-lock-doc-face))
"Face for a header value (such as \"Re: Hello!\") in the message "Face for a header value (such as \"Re: Hello!\") in the message view."
view."
:group 'mu4e-faces) :group 'mu4e-faces)
(defface mu4e-view-special-header-value-face (defface mu4e-view-special-header-value-face
@ -444,8 +447,7 @@ flag set)."
(defface mu4e-system-face (defface mu4e-system-face
'((t :inherit font-lock-comment-face :slant italic)) '((t :inherit font-lock-comment-face :slant italic))
"Face for system message (such as the footers for message "Face for system message (such as the footers for message headers)."
headers)."
:group 'mu4e-faces) :group 'mu4e-faces)
(defface mu4e-ok-face (defface mu4e-ok-face
@ -547,10 +549,10 @@ Most fields should be self-explanatory. A special one is
to `:to'.") to `:to'.")
(defvar mu4e-custom-header-info nil (defvar mu4e-custom-header-info nil
"A list like `mu4e-custom-header-info', but for "A list like `mu4e-custom-header-info', but for custom headers.
custom (user-specified) headers. Each of the list items is a I.e. user-specified headers. Each of the list items is a property
property list with :name (the full-name, as displayed in the list with :name (the full-name, as displayed in the message
message view), :shortname (the name as displayed in the headers view), :shortname (the name as displayed in the headers
view), :help (some help information, which shows up in the view), :help (some help information, which shows up in the
tooltip). Furthermore, there are two special fields: tooltip). Furthermore, there are two special fields:
:headers-func and :message-func, and the values should be functions :headers-func and :message-func, and the values should be functions
@ -582,13 +584,13 @@ Note, :sortable does not work for custom header fields.")
(defvar mu4e~view-msg nil "The message being viewed in view mode.") (defvar mu4e~view-msg nil "The message being viewed in view mode.")
(defvar mu4e~contacts-for-completion nil (defvar mu4e~contacts-for-completion nil
"List of contacts (ie. 'name <e-mail>'), "List of contacts (ie. 'name <e-mail>').
used by the completion functions in mu4e-compose, and filled when This is used by the completion functions in mu4e-compose, and
mu4e starts.") filled when mu4e starts.")
(defvar mu4e~server-props nil (defvar mu4e~server-props nil
"Properties we receive from the mu4e server process (in the "Properties we receive from the mu4e server process.
'pong-handler').") \(in the 'pong-handler').")
(defvar mu4e~headers-last-query nil (defvar mu4e~headers-last-query nil
"The present (most recent) query.") "The present (most recent) query.")

View File

@ -68,8 +68,8 @@ contact."
(make-obsolete-variable 'mu4e-view-hide-cited nil "0.9.9-dev7") (make-obsolete-variable 'mu4e-view-hide-cited nil "0.9.9-dev7")
(defcustom mu4e-view-date-format "%c" (defcustom mu4e-view-date-format "%c"
"Date format to use in the message view, in the format of "Date format to use in the message view.
`format-time-string'." In the format of `format-time-string'."
:type 'string :type 'string
:group 'mu4e-view) :group 'mu4e-view)
@ -87,9 +87,9 @@ end of a message. Otherwise, don't move to the next message.")
(defvar mu4e-view-actions (defvar mu4e-view-actions
'( ("capture message" . mu4e-action-capture-message) '( ("capture message" . mu4e-action-capture-message)
("view as pdf" . mu4e-action-view-as-pdf)) ("view as pdf" . mu4e-action-view-as-pdf))
"List of actions to perform on messages in view mode. The actions "List of actions to perform on messages in view mode.
are of the form: The actions are of the form:
(NAME FUNC) (NAME FUNC)
where: where:
* NAME is the name of the action (e.g. \"Count lines\") * NAME is the name of the action (e.g. \"Count lines\")
* FUNC is a function which receives a message plist as an argument. * FUNC is a function which receives a message plist as an argument.
@ -100,13 +100,13 @@ The first letter of NAME is used as a shortcut character.")
'( ("wopen-with" . mu4e-view-open-attachment-with) '( ("wopen-with" . mu4e-view-open-attachment-with)
("ein-emacs" . mu4e-view-open-attachment-emacs) ("ein-emacs" . mu4e-view-open-attachment-emacs)
("|pipe" . mu4e-view-pipe-attachment)) ("|pipe" . mu4e-view-pipe-attachment))
"List of actions to perform on message attachments. The actions "List of actions to perform on message attachments.
are of the form: The actions are of the form:
(NAME FUNC) (NAME FUNC)
where: where:
* NAME is the name of the action (e.g. \"Count lines\") * NAME is the name of the action (e.g. \"Count lines\")
* FUNC is a function which receives two arguments: the message * FUNC is a function which receives two arguments: the message
plist and the attachment number. plist and the attachment number.
The first letter of NAME is used as a shortcut character.") The first letter of NAME is used as a shortcut character.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -121,21 +121,23 @@ The first letter of NAME is used as a shortcut character.")
"A map of some number->url so we can jump to url by number.") "A map of some number->url so we can jump to url by number.")
(defvar mu4e~path-parent-docid-map (make-hash-table :test 'equal) (defvar mu4e~path-parent-docid-map (make-hash-table :test 'equal)
"A map of msg paths --> parent-docids. This is to determine what "A map of msg paths --> parent-docids.
is the parent docid for embedded message extracted at some path.") This is to determine what is the parent docid for embedded
message extracted at some path.")
(defconst mu4e~view-url-regexp (defconst mu4e~view-url-regexp
"\\(\\(https?\\://\\|mailto:\\)[-+a-zA-Z0-9.?_$%/+&#@!*~,:;=/()]+\\)" "\\(\\(https?\\://\\|mailto:\\)[-+a-zA-Z0-9.?_$%/+&#@!*~,:;=/()]+\\)"
"Regexp that matches http:/https:/mailto: URLs; match-string 1 "Regexp that matches http:/https:/mailto: URLs; match-string 1
will contain the matched URL, if any.") will contain the matched URL, if any.")
(defvar mu4e~view-attach-map nil (defvar mu4e~view-attach-map nil
"A mapping of user-visible attachment number to the actual part index.") "A mapping of user-visible attachment number to the actual part index.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-view-message-with-msgid (msgid) (defun mu4e-view-message-with-msgid (msgid)
"View message with MSGID. This is meant for external programs "View message with MSGID.
wanting to show specific messages - for example, `mu4e-org'." This is meant for external programs wanting to show specific
messages - for example, `mu4e-org'."
;; note: hackish; if mu4e-decryption-policy is non-nil (ie., t or 'ask), we ;; note: hackish; if mu4e-decryption-policy is non-nil (ie., t or 'ask), we
;; decrpt the message. Since here we don't know if message is encrypted or ;; decrpt the message. Since here we don't know if message is encrypted or
;; not, when the policy is 'ask'. we simply assume the user said yes... the ;; not, when the policy is 'ask'. we simply assume the user said yes... the
@ -145,8 +147,7 @@ wanting to show specific messages - for example, `mu4e-org'."
(defun mu4e-view-message-text (msg) (defun mu4e-view-message-text (msg)
"Return the message to display (as a string), based on the MSG "Return the message to display (as a string), based on the MSG plist."
plist."
(concat (concat
(mapconcat (mapconcat
(lambda (field) (lambda (field)
@ -463,8 +464,8 @@ at POINT, or if nil, at (point)."
;; decr)))))) ;; decr))))))
(defun mu4e-view-for-each-part (msg func) (defun mu4e-view-for-each-part (msg func)
"Apply FUNC to each part in MSG. FUNC should be a function taking "Apply FUNC to each part in MSG.
two arguments: FUNC should be a function taking two arguments:
1. the message MSG, and 1. the message MSG, and
2. a plist describing the attachment. The plist looks like: 2. a plist describing the attachment. The plist looks like:
(:index 1 :name \"test123.doc\" (:index 1 :name \"test123.doc\"
@ -672,8 +673,8 @@ at POINT, or if nil, at (point)."
(setq autopair-dont-activate t))) (setq autopair-dont-activate t)))
(defun mu4e~view-mark-as-read-maybe () (defun mu4e~view-mark-as-read-maybe ()
"Clear the current message's New/Unread status and set it to "Clear the current message's New/Unread status and set it to Seen.
Seen; if the message is not New/Unread, do nothing." If the message is not New/Unread, do nothing."
(when mu4e~view-msg (when mu4e~view-msg
(let ((flags (mu4e-message-field mu4e~view-msg :flags)) (let ((flags (mu4e-message-field mu4e~view-msg :flags))
(docid (mu4e-message-field mu4e~view-msg :docid))) (docid (mu4e-message-field mu4e~view-msg :docid)))
@ -720,9 +721,9 @@ Seen; if the message is not New/Unread, do nothing."
(add-text-properties p (point-max) '(face mu4e-footer-face))))))) (add-text-properties p (point-max) '(face mu4e-footer-face)))))))
(defun mu4e~view-browse-url-func (url) (defun mu4e~view-browse-url-func (url)
"Return a function that executes `browse-url' with URL. What "Return a function that executes `browse-url' with URL.
browser is called is depending on `browse-url-browser-function' and What browser is called is depending on
`browse-url-mailto-function'." `browse-url-browser-function' and `browse-url-mailto-function'."
(save-match-data (save-match-data
(if (string-match "^mailto:" url) (if (string-match "^mailto:" url)
(lexical-let ((url url)) (lexical-let ((url url))
@ -748,8 +749,8 @@ browser is called is depending on `browse-url-browser-function' and
;; this is fairly simplistic... ;; this is fairly simplistic...
(defun mu4e~view-make-urls-clickable () (defun mu4e~view-make-urls-clickable ()
"Turn things that look like URLs into clickable things, and "Turn things that look like URLs into clickable things.
number them so they can be opened using `mu4e-view-go-to-url'." Also number them so they can be opened using `mu4e-view-go-to-url'."
(let ((num 0)) (let ((num 0))
(save-excursion (save-excursion
(setq mu4e~view-link-map ;; buffer local (setq mu4e~view-link-map ;; buffer local
@ -833,8 +834,9 @@ N (prefix argument), to the Nth previous header."
(setq mu4e~view-cited-hidden nil)) (setq mu4e~view-cited-hidden nil))
(defun mu4e-view-action (&optional msg) (defun mu4e-view-action (&optional msg)
"Ask user for some action to apply on MSG (or message-at-point, "Ask user for some action to apply on MSG, then do it.
if nil), then do it. The actions are specified in If MSG is nil apply action to message returned
bymessage-at-point. The actions are specified in
`mu4e-view-actions'." `mu4e-view-actions'."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point))) (let* ((msg (or msg (mu4e-message-at-point)))
@ -874,11 +876,11 @@ all messages in the subthread at point in the headers view."
;; attachment handling ;; attachment handling
(defun mu4e~view-get-attach-num (prompt msg &optional multi) (defun mu4e~view-get-attach-num (prompt msg &optional multi)
"Ask the user with PROMPT for an attachment number for MSG, and "Ask the user with PROMPT for an attachment number for MSG, and
ensure it is valid. The number is [1..n] for attachments ensure it is valid. The number is [1..n] for attachments
[0..(n-1)] in the message. If MULTI is nil, return the number for \[0..(n-1)] in the message. If MULTI is nil, return the number for
the attachment; otherwise (MULTI is non-nil), accept ranges of the attachment; otherwise (MULTI is non-nil), accept ranges of
attachment numbers, as per `mu4e-split-ranges-to-numbers', and attachment numbers, as per `mu4e-split-ranges-to-numbers', and
return the corresponding string." return the corresponding string."
(let* ((count (hash-table-count mu4e~view-attach-map)) (def)) (let* ((count (hash-table-count mu4e~view-attach-map)) (def))
(when (zerop count) (mu4e-error "No attachments for this message")) (when (zerop count) (mu4e-error "No attachments for this message"))
(if (not multi) (if (not multi)
@ -903,8 +905,9 @@ number ATTNUM."
(defun mu4e-view-save-attachment-single (&optional msg attnum) (defun mu4e-view-save-attachment-single (&optional msg attnum)
"Save attachment number ATTNUM (or ask if nil) from MSG (or "Save attachment number ATTNUM from MSG.
message-at-point if nil) to disk." If MSG is nil use the message returned by `message-at-point'.
If ATTNUM is nil ask for the attachment number."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point))) (let* ((msg (or msg (mu4e-message-at-point)))
(attnum (or attnum (attnum (or attnum
@ -945,17 +948,18 @@ attachments, but as this is the default, you may not need it."
(mu4e-view-save-attachment-single msg num)))) (mu4e-view-save-attachment-single msg num))))
(defun mu4e-view-save-attachment (&optional multi) (defun mu4e-view-save-attachment (&optional multi)
"Offer to save attachment(s). If MULTI (prefix-argument) is nil, "Offer to save attachment(s).
save a single one, otherwise, offer to save a range of If MULTI (prefix-argument) is nil, save a single one, otherwise,
attachments." offer to save a range of attachments."
(interactive "P") (interactive "P")
(if multi (if multi
(mu4e-view-save-attachment-multi) (mu4e-view-save-attachment-multi)
(mu4e-view-save-attachment-single))) (mu4e-view-save-attachment-single)))
(defun mu4e-view-open-attachment (&optional msg attnum) (defun mu4e-view-open-attachment (&optional msg attnum)
"Open attachment number ATTNUM (or ask if nil) from MSG (or "Open attachment number ATTNUM from MSG.
message-at-point if nil)." If MSG is nil use the message returned by `message-at-point'.
If ATTNUM is nil ask for the attachment number."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point))) (let* ((msg (or msg (mu4e-message-at-point)))
(attnum (or attnum (attnum (or attnum
@ -976,16 +980,15 @@ message-at-point if nil)."
(defun mu4e~view-temp-action (docid index what &optional param) (defun mu4e~view-temp-action (docid index what &optional param)
"Open attachment INDEX for message with DOCID, and invoke "Open attachment INDEX for message with DOCID, and invoke ACTION."
ACTION."
(interactive) (interactive)
(mu4e~proc-extract 'temp docid index nil what param)) (mu4e~proc-extract 'temp docid index nil what param))
(defvar mu4e~view-open-with-hist nil "History list for the open-with argument.") (defvar mu4e~view-open-with-hist nil "History list for the open-with argument.")
(defun mu4e-view-open-attachment-with (msg attachnum &optional cmd) (defun mu4e-view-open-attachment-with (msg attachnum &optional cmd)
"Open MSG's attachment ATTACHNUM with CMD; if CMD is nil, ask "Open MSG's attachment ATTACHNUM with CMD.
user for it." If CMD is nil, ask user for it."
(interactive) (interactive)
(let* ((att (mu4e~view-get-attach msg attachnum)) (let* ((att (mu4e~view-get-attach msg attachnum))
(cmd (or cmd (cmd (or cmd
@ -1000,8 +1003,8 @@ user for it."
"History list for the pipe argument.") "History list for the pipe argument.")
(defun mu4e-view-pipe-attachment (msg attachnum &optional pipecmd) (defun mu4e-view-pipe-attachment (msg attachnum &optional pipecmd)
"Feed MSG's attachment ATTACHNUM through pipe PIPECMD; if "Feed MSG's attachment ATTACHNUM through pipe PIPECMD.
PIPECMD is nil, ask user for it." If PIPECMD is nil, ask user for it."
(interactive) (interactive)
(let* ((att (mu4e~view-get-attach msg attachnum)) (let* ((att (mu4e~view-get-attach msg attachnum))
(pipecmd (or pipecmd (pipecmd (or pipecmd
@ -1023,9 +1026,9 @@ PIPECMD is nil, ask user for it."
(defun mu4e-view-attachment-action (&optional msg) (defun mu4e-view-attachment-action (&optional msg)
"Ask user what to do with attachments in MSG (or nil to use "Ask user what to do with attachments in MSG
message-at-point, then do it. The actions are specified in If MSG is nil use the message returned by `message-at-point'.
`mu4e-view-attachment-actions'." The actions are specified in `mu4e-view-attachment-actions'."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point))) (let* ((msg (or msg (mu4e-message-at-point)))
(actionfunc (mu4e-read-option (actionfunc (mu4e-read-option
@ -1072,8 +1075,9 @@ attachments) in response to a (mu4e~proc-extract 'temp ... )."
(member mu4e-split-view '(horizontal vertical))) (member mu4e-split-view '(horizontal vertical)))
(defun mu4e-view-scroll-up-or-next () (defun mu4e-view-scroll-up-or-next ()
"Scroll-up the current message; if mu4e-view-scroll-to-next is "Scroll-up the current message.
non-nil, and we can't scroll-up anymore, go the next message." If `mu4e-view-scroll-to-next' is non-nil, and we can't scroll-up
anymore, go the next message."
(interactive) (interactive)
(condition-case nil (condition-case nil
(scroll-up) (scroll-up)
@ -1082,16 +1086,18 @@ non-nil, and we can't scroll-up anymore, go the next message."
(mu4e-view-headers-next))))) (mu4e-view-headers-next)))))
(defun mu4e-view-unmark-all () (defun mu4e-view-unmark-all ()
"If we're in split-view, unmark all messages. Otherwise, warn "If we're in split-view, unmark all messages.
user that unmarking only works in the header list." Otherwise, warn user that unmarking only works in the header
list."
(interactive) (interactive)
(if (mu4e~view-split-view-p) (if (mu4e~view-split-view-p)
(mu4e~view-in-headers-context (mu4e-mark-unmark-all)) (mu4e~view-in-headers-context (mu4e-mark-unmark-all))
(mu4e-message "Unmarking needs to be done in the header list view"))) (mu4e-message "Unmarking needs to be done in the header list view")))
(defun mu4e-view-unmark () (defun mu4e-view-unmark ()
"If we're in split-view, unmark message at point. Otherwise, warn "If we're in split-view, unmark message at point.
user that unmarking only works in the header list." Otherwise, warn user that unmarking only works in the header
list."
(interactive) (interactive)
(if (mu4e~view-split-view-p) (if (mu4e~view-split-view-p)
(mu4e-view-mark-for-unmark) (mu4e-view-mark-for-unmark)
@ -1188,8 +1194,9 @@ or message-at-point."
(defun mu4e~view-quit-buffer () (defun mu4e~view-quit-buffer ()
"Quit the mu4e-view buffer. This is a rather complex function, to "Quit the mu4e-view buffer.
ensure we don't disturb other windows." This is a rather complex function, to ensure we don't disturb
other windows."
(interactive) (interactive)
(unless (eq major-mode 'mu4e-view-mode) (unless (eq major-mode 'mu4e-view-mode)
(mu4e-error "Must be in mu4e-view-mode (%S)" major-mode)) (mu4e-error "Must be in mu4e-view-mode (%S)" major-mode))

View File

@ -29,7 +29,7 @@
(eval-when-compile (require 'cl)) (eval-when-compile (require 'cl))
(require 'mu4e-meta) ;; autogenerated file with metadata (version etc.) (require 'mu4e-meta) ;; autogenerated file with metadata (version etc.)
(require 'mu4e-headers) ;; headers view (require 'mu4e-headers) ;; headers view
(require 'mu4e-view) ;; message view (require 'mu4e-view) ;; message view
(require 'mu4e-main) ;; main screen (require 'mu4e-main) ;; main screen
(require 'mu4e-compose) ;; message composition / sending (require 'mu4e-compose) ;; message composition / sending

View File

@ -42,18 +42,17 @@
(defcustom org-mu4e-link-desc-func (defcustom org-mu4e-link-desc-func
(lambda (msg) (or (plist-get msg :subject) "No subject")) (lambda (msg) (or (plist-get msg :subject) "No subject"))
"Function that takes a msg and returns a string for the "Function that takes a msg and returns a string for the
description part of an org-mode link. description part of an org-mode link.
Example usage: Example usage:
(defun my-link-descr (msg) (defun my-link-descr (msg)
(let (let ((subject (or (plist-get msg :subject)
((subject (or (plist-get msg :subject) \"No subject\"))
\"No subject\"))
(date (or (format-time-string mu4e-headers-date-format (date (or (format-time-string mu4e-headers-date-format
(mu4e-msg-field msg :date)) (mu4e-msg-field msg :date))
\"No date\"))) \"No date\")))
(concat subject \" \" date))) (concat subject \" \" date)))
(setq org-mu4e-link-desc-func 'my-link-descr)" (setq org-mu4e-link-desc-func 'my-link-descr)"
:type 'function :type 'function
@ -201,8 +200,8 @@ and images in a multipart/related part."
(overlay-put olay 'face 'font-lock-comment-face))))) (overlay-put olay 'face 'font-lock-comment-face)))))
(defun org~mu4e-mime-undecorate-headers () (defun org~mu4e-mime-undecorate-headers ()
"Don't make the headers visually distinctive (well, "Don't make the headers visually distinctive.
mu4e-compose-mode will take care of that)." \(well, mu4e-compose-mode will take care of that)."
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(let* ((eoh (when (search-forward mail-header-separator) (let* ((eoh (when (search-forward mail-header-separator)
@ -210,14 +209,14 @@ mu4e-compose-mode will take care of that)."
(remove-overlays (point-min) eoh)))) (remove-overlays (point-min) eoh))))
(defvar org-mu4e-convert-to-html nil (defvar org-mu4e-convert-to-html nil
"Whether to do automatic org-mode => html conversion when sending "Whether to do automatic org-mode => html conversion when sending messages.")
messages.")
(defun org~mu4e-mime-convert-to-html-maybe () (defun org~mu4e-mime-convert-to-html-maybe ()
"Convert to html if `org-mu4e-convert-to-html' is non-nil. This "Convert to html if `org-mu4e-convert-to-html' is non-nil.
function is called when sending a message (from This function is called when sending a message (from
`message-send-hook') and, if non-nil, will send the message as the `message-send-hook') and, if non-nil, will send the message as
rich-text version of the what is assumed to be an org-mode body." the rich-text version of the what is assumed to be an org-mode
body."
(when org-mu4e-convert-to-html (when org-mu4e-convert-to-html
(mu4e-message "Converting to html") (mu4e-message "Converting to html")
(org~mu4e-mime-convert-to-html))) (org~mu4e-mime-convert-to-html)))
@ -261,7 +260,7 @@ or org-mode (when in the body)."
(defun org-mu4e-compose-org-mode () (defun org-mu4e-compose-org-mode ()
"Pseudo-Minor mode for mu4e-compose-mode, to edit the message "Pseudo-Minor mode for mu4e-compose-mode, to edit the message
body using org-mode." body using org-mode."
(interactive) (interactive)
(unless (member major-mode '(org-mode mu4e-compose-mode)) (unless (member major-mode '(org-mode mu4e-compose-mode))
(mu4e-error "Need org-mode or mu4e-compose-mode")) (mu4e-error "Need org-mode or mu4e-compose-mode"))