* automatic mail retrieval (WIP-2):
- mu4e-main.el: mu4e-update-mail-show-window retrieves mail / updates
database, show output in split window (actual work is done by...:)
- mu4e.el: mu4e-update-mail retrieves mail, updates database,
asynchronously. Optionally, show output in a buffer
when `mu4e-update-interval' is non-nil and some integer, it calls
mu4e-update-mail every so many seconds.
- mu4e.texi: document this
- TODO: updated
This commit is contained in:
@ -4,19 +4,15 @@
|
||||
** Bugs
|
||||
|
||||
*** database locks (solved?)
|
||||
*** sometimes +S-u-n does not seem to work?
|
||||
|
||||
** Features i
|
||||
|
||||
*** documentation
|
||||
*** mu4e-get-sub-maildirs
|
||||
*** auto-mail check
|
||||
*** extract mailing list name
|
||||
*** mark thread
|
||||
*** bounce support
|
||||
*** sorting
|
||||
*** tool bars
|
||||
*** colorize cited parts in view
|
||||
*** refiling-by-pattern
|
||||
*** window management
|
||||
*** inspect message (muile)
|
||||
@ -62,6 +58,10 @@
|
||||
** make links clickable
|
||||
** integrate with org-contacts
|
||||
** forward should take the attachments from the original
|
||||
** auto-mail check
|
||||
** colorize cited parts in view
|
||||
** documentation
|
||||
** sometimes +S-u-n does not seem to work?
|
||||
|
||||
# Local Variables:
|
||||
# mode: org; org-startup-folded: nil
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
(defconst mu4e-main-buffer-name "*mu4e-main*"
|
||||
"*internal* Name of the mm main buffer.")
|
||||
|
||||
|
||||
(defvar mu4e-main-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
|
||||
@ -42,7 +43,7 @@
|
||||
|
||||
(define-key map "m" 'mu4e-toggle-mail-sending-mode)
|
||||
(define-key map "f" 'smtpmail-send-queued-mail)
|
||||
(define-key map "U" 'mu4e-retrieve-mail-update-db)
|
||||
(define-key map "U" 'mu4e-update-mail-show-window)
|
||||
|
||||
(define-key map "H" 'mu4e-display-manual)
|
||||
map)
|
||||
@ -124,7 +125,7 @@ clicked."
|
||||
(propertize " Misc\n\n" 'face 'mu4e-title-face)
|
||||
|
||||
(mu4e-action-str "\t* [U]pdate email & database\n"
|
||||
'mu4e-retrieve-mail-update-db)
|
||||
'mu4e-update-mail-show-window)
|
||||
|
||||
;; show the queue functions if `smtpmail-queue-dir' is defined
|
||||
(if (file-directory-p smtpmail-queue-dir)
|
||||
@ -148,10 +149,28 @@ clicked."
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Interactive functions
|
||||
|
||||
(defun mu4e-retrieve-mail-update-db ()
|
||||
"Get new mail and update the database."
|
||||
(defconst mu4e-update-buffer-name "*mu4e-update*"
|
||||
"*internal* Name of the buffer for message retrieval / database
|
||||
updating.")
|
||||
|
||||
(defun mu4e-update-mail-show-window ()
|
||||
"Try to retrieve mail (using the user-provided shell command),
|
||||
and update the database afterwards, and show the progress in a
|
||||
split-window."
|
||||
(interactive)
|
||||
(mu4e-proc-retrieve-mail-update-db))
|
||||
(unless mu4e-get-mail-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(let ((buf (get-buffer-create mu4e-update-buffer-name))
|
||||
(win
|
||||
(split-window (selected-window)
|
||||
(- (window-height (selected-window)) 8))))
|
||||
(with-selected-window win
|
||||
(switch-to-buffer buf)
|
||||
(set-window-dedicated-p win t)
|
||||
(erase-buffer)
|
||||
(insert "\n") ;; FIXME -- needed so output starts
|
||||
(mu4e-update-mail buf))))
|
||||
|
||||
|
||||
(defun mu4e-toggle-mail-sending-mode ()
|
||||
"Toggle sending mail mode, either queued or direct."
|
||||
@ -160,9 +179,8 @@ clicked."
|
||||
(error "`smtp-queue-dir' does not exist"))
|
||||
(setq smtpmail-queue-mail (not smtpmail-queue-mail))
|
||||
(message
|
||||
(if smtpmail-queue-mail
|
||||
"Outgoing mail will now be queued"
|
||||
"Outgoing mail will now be sent directly"))
|
||||
(concat "Outgoing mail will now be "
|
||||
(if smtpmail-queue-mail "queued" "sent directly")))
|
||||
(mu4e-main-view))
|
||||
|
||||
(provide 'mu4e-main)
|
||||
|
||||
111
emacs/mu4e.el
111
emacs/mu4e.el
@ -69,6 +69,15 @@ PATH, you can specify the full path."
|
||||
:group 'mu4e
|
||||
:safe 'stringp)
|
||||
|
||||
(defcustom mu4e-update-interval nil
|
||||
"Number of seconds between automatic calls to retrieve mail and
|
||||
update the database. If nil, don't update automatically. Note,
|
||||
changes in `mu4e-update-interval' only take effect after restarting
|
||||
mu4d."
|
||||
:type 'integer
|
||||
:group 'mu4e
|
||||
:safe 'integerp)
|
||||
|
||||
(defcustom mu4e-attachment-dir (expand-file-name "~/")
|
||||
"Default directory for saving attachments."
|
||||
:type 'string
|
||||
@ -90,7 +99,6 @@ limiting search results speeds up searches significantly, it's
|
||||
useful to limit this. Note, to ignore the limit, use a prefix
|
||||
argument (C-u) before invoking the search.")
|
||||
|
||||
|
||||
(defvar mu4e-debug nil
|
||||
"When set to non-nil, log debug information to the *mu4e-log* buffer.")
|
||||
|
||||
@ -152,16 +160,17 @@ designated shortcut character for the maildir.")
|
||||
|
||||
|
||||
(defcustom mu4e-headers-fields
|
||||
'( (:date . 25)
|
||||
(:flags . 6)
|
||||
(:from . 22)
|
||||
(:subject . nil))
|
||||
'( (:date . 25)
|
||||
(:flags . 6)
|
||||
(:from . 22)
|
||||
(:subject . nil))
|
||||
"A list of header fields to show in the headers buffer, and their
|
||||
respective widths in characters. A width of `nil' means
|
||||
'unrestricted', and this is best reserved fo the rightmost (last)
|
||||
field. For the complete list of available headers, see `mu4e-header-names'"
|
||||
:type (list 'symbol)
|
||||
:group 'mu4e-headers)
|
||||
field. For the complete list of available headers, see
|
||||
`mu4e-header-names'"
|
||||
:type (list 'symbol)
|
||||
:group 'mu4e-headers)
|
||||
|
||||
(defcustom mu4e-headers-date-format "%x %X"
|
||||
"Date format to use in the headers view, in the format of
|
||||
@ -170,11 +179,12 @@ designated shortcut character for the maildir.")
|
||||
:group 'mu4e-headers)
|
||||
|
||||
(defcustom mu4e-headers-leave-behavior 'ask
|
||||
"What do to when user leaves the headers view (e.g. quit or doing
|
||||
a new search). Value is one of the following symbols:
|
||||
- ask (ask the user whether to ignore the marks)
|
||||
- apply (automatically apply the marks before doing anything else)
|
||||
- ignore (automatically ignore the marks without asking)."
|
||||
"What to do when user leaves the headers view (e.g. quits,
|
||||
refreshes or does a new search). Value is one of the following
|
||||
symbols:
|
||||
- ask (ask the user whether to ignore the marks)
|
||||
- apply (automatically apply the marks before doing anything else)
|
||||
- ignore (automatically ignore the marks without asking)."
|
||||
:type 'symbol
|
||||
:group 'mu4e-headers)
|
||||
|
||||
@ -394,6 +404,9 @@ dir already existed, or has been created, nil otherwise."
|
||||
(unless (mu4e-create-maildir-maybe path)
|
||||
(error "%s (%S) does not exist" path var)))))
|
||||
|
||||
(defvar mu4e-update-timer nil
|
||||
"*internal* The mu4e update timer.")
|
||||
|
||||
(defun mu4e ()
|
||||
"Start mm. We do this by sending a 'ping' to the mu server
|
||||
process, and start the main view if the 'pong' we receive from the
|
||||
@ -413,10 +426,26 @@ server has the expected values."
|
||||
(error "mu server has version %s, but we need %s"
|
||||
version mu4e-mu-version))
|
||||
(mu4e-main-view)
|
||||
(when mu4e-update-interval
|
||||
(setq mu4e-update-timer
|
||||
(run-at-time
|
||||
0 mu4e-update-interval
|
||||
'mu4e-update-mail)))
|
||||
(message "Started mu4e with %d message%s in store"
|
||||
doccount (if (= doccount 1) "" "s"))))
|
||||
(mu4e-proc-ping)))))
|
||||
|
||||
(defun mu4e-quit()
|
||||
"Quit the mm session."
|
||||
(interactive)
|
||||
(when (y-or-n-p "Are you sure you want to quit? ")
|
||||
(message nil)
|
||||
(when mu4e-update-timer
|
||||
(cancel-timer mu4e-update-timer))
|
||||
(mu4e-kill-proc)
|
||||
(kill-buffer)))
|
||||
|
||||
|
||||
(defun mu4e-get-maildirs (parentdir)
|
||||
"List the maildirs under PARENTDIR." ;; TODO: recursive?
|
||||
(let* ((files (directory-files parentdir))
|
||||
@ -521,9 +550,7 @@ message files; flags are symbols draft, flagged, new, passed,
|
||||
replied, seen, trashed and the string is the concatenation of the
|
||||
uppercased first letters of these flags, as per [1]. Other flags
|
||||
than the ones listed here are ignored.
|
||||
|
||||
Also see `mu4e-flags-to-string'.
|
||||
|
||||
\[1\]: http://cr.yp.to/proto/maildir.html"
|
||||
(when flags
|
||||
(let ((kar (case (car flags)
|
||||
@ -612,40 +639,29 @@ function prefers the text part, but this can be changed by setting
|
||||
;; and finally, remove some crap from the remaining string.
|
||||
(replace-regexp-in-string "[
|
||||
]" " " body nil nil nil)))
|
||||
|
||||
(defconst mu4e-get-mail-name "*mu4e-get-mail*"
|
||||
|
||||
(defconst mu4e-update-mail-name "*mu4e-update-mail*"
|
||||
"*internal* Name of the process to update mail")
|
||||
|
||||
(defun mu4e-retrieve-mail-update-db-proc (buf)
|
||||
"Try to retrieve mail (using `mu4e-get-mail-command'), with
|
||||
output going to BUF if not nil, or discarded if nil. After
|
||||
|
||||
(defun mu4e-update-mail (&optional buf)
|
||||
"Update mail (retrieve using `mu4e-get-mail-command' and update
|
||||
the database afterwards), with output going to BUF if not nil, or
|
||||
discarded if nil. After retrieving mail, update the database. Note,
|
||||
function is asynchronous, returns (almost) immediately, and all the
|
||||
processing takes part in the background, unless buf is non-nil."
|
||||
(unless mu4e-get-mail-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(message "Retrieving mail...")
|
||||
(let* ((proc (start-process-shell-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(let* ((process-connection-type t)
|
||||
(proc (start-process-shell-command
|
||||
mu4e-update-mail-name buf mu4e-get-mail-command)))
|
||||
(message "Retrieving mail...")
|
||||
(set-process-sentinel proc
|
||||
(lambda (proc msg)
|
||||
(message nil)
|
||||
(mu4e-proc-index mu4e-maildir)
|
||||
(let ((buf (process-buffer proc)))
|
||||
(when (buffer-live-p buf)
|
||||
(mu4e-proc-index mu4e-maildir)
|
||||
(kill-buffer buf)))))))
|
||||
|
||||
(defun mu4e-retrieve-mail-update-db ()
|
||||
"Try to retrieve mail (using the user-provided shell command),
|
||||
and update the database afterwards"
|
||||
(interactive)
|
||||
(unless mu4e-get-mail-command
|
||||
(error "`mu4e-get-mail-command' is not defined"))
|
||||
(let ((buf (get-buffer-create mu4e-update-buffer-name))
|
||||
(win
|
||||
(split-window (selected-window)
|
||||
(- (window-height (selected-window)) 8))))
|
||||
(with-selected-window win
|
||||
(switch-to-buffer buf)
|
||||
(set-window-dedicated-p win t)
|
||||
(erase-buffer)
|
||||
(let ((buf (process-buffer proc)))
|
||||
(when (buffer-live-p buf)
|
||||
(kill-buffer buf)))))
|
||||
(set-process-query-on-exit-flag proc t)))
|
||||
|
||||
|
||||
@ -658,15 +674,6 @@ top level if there is none."
|
||||
('mu4e-hdrs-mode "(mu4e)Headers view")
|
||||
('mu4e-view-mode "(mu4e)Message view")
|
||||
(t "mu4e"))))
|
||||
|
||||
(defun mu4e-quit()
|
||||
"Quit the mm session."
|
||||
(interactive)
|
||||
(when (y-or-n-p "Are you sure you want to quit? ")
|
||||
(message nil)
|
||||
(mu4e-kill-proc)
|
||||
(kill-buffer)))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ tested on Debian GNU/Linux.
|
||||
* Getting started::
|
||||
* Running mu4e::
|
||||
* Searching mail::
|
||||
* Org-mode support::
|
||||
* Interaction with other tools::
|
||||
* Example configuration::
|
||||
* FAQ - Frequently Anticipated Questions::
|
||||
* Known issues / missing features::
|
||||
@ -180,6 +180,17 @@ of googling should be able to provide you with the details; also there is full
|
||||
example of setting @t{mu4e} up with @t{offlineimap} and Gmail; @pxref{Gmail
|
||||
configuration}.
|
||||
|
||||
You can do all of the mail retrieval @emph{outside} of @t{emacs}/@t{mu4e}, but
|
||||
you can also do it from the @t{mu4e}. For that, set the variable
|
||||
@code{mu4e-get-mail-command} to the command you want to use for retrieving
|
||||
mail, which you can then access from the @ref{Main view}.
|
||||
|
||||
You can also have this command run periodically (in the background), by
|
||||
setting the variable @code{mu4e-update-interval} to the number of seconds
|
||||
between such updates. If set to @code{nil}, it will not update at all. Note
|
||||
that if you make changes to @code{mu4e-update-interval}, @code{mu4e} must be
|
||||
restarted before the change will take effect.
|
||||
|
||||
@node Indexing your messages
|
||||
@section Indexing your messages
|
||||
|
||||
@ -405,8 +416,7 @@ Finally, there are some @emph{Misc} actions:
|
||||
@itemize
|
||||
@item @t{[U]pdate email & database} will execute whatever is in
|
||||
the variable @code{mu4e-get-mail-command}, and afterwards update the @t{mu}
|
||||
database; @pxref{Indexing your messages}. This is a synchronous command - you
|
||||
have to wait for it to finish.
|
||||
database; @pxref{Indexing your messages}. See @ref{Getting mail} for details.
|
||||
@item @t{toggle [m]ail sending mode (direct)} will toggle between sending
|
||||
mail directly, and queuing it first (for example, when you are offline), and
|
||||
@t{[f]lush queued mail} will flush any queued mail. This item is visible only
|
||||
@ -487,6 +497,12 @@ The two-step mark-execute sequence is similar to what for example @t{dired}
|
||||
does; @inforef{(emacs) Dired} - it tries to be as fast as possible while still
|
||||
trying to protect the user from accidents.
|
||||
|
||||
When you try to do a new search, or refresh the headers buffer while you still
|
||||
have marked messages, by default you will be asked what to do with those marks
|
||||
-- whether to @emph{apply} them before leaving, @emph{ignore} them or to
|
||||
@emph{cancel} the operation. This behavior can be influenced with the variable
|
||||
@code{mu4e-headers-leave-behavior} -- see its documentation.
|
||||
|
||||
@node Message view
|
||||
@section Message view
|
||||
|
||||
@ -794,22 +810,20 @@ The same shortcuts are used by the function @code{mu4e-mark-for-move}; so for
|
||||
example, if you want to move a message the @t{/archive} folder, you can do so
|
||||
by typing @key{ma}.
|
||||
|
||||
@node Org-mode support
|
||||
@chapter Org-mode support
|
||||
@node Interaction with other tools
|
||||
@chapter Interaction with other tools
|
||||
|
||||
Many emacs-users use @t{org-mode} for their note-taking, agenda, to-do list
|
||||
and many other things, so it is useful to integrate e-mail with this as well.
|
||||
|
||||
@t{mu4e} support @t{org-mode}-links, and the @t{org-mode}-address book,
|
||||
@t{org-contact}.
|
||||
In this chapter we discuss some ways in ways in which @t{mu4e} can cooperate
|
||||
with other tools.
|
||||
|
||||
@menu
|
||||
* Org-mode links::
|
||||
* Org-contacts::
|
||||
* Creating org-mode links::
|
||||
* Maintaining an address-book with org-contacts::
|
||||
* Getting new mail notifications with Sauron::
|
||||
@end menu
|
||||
|
||||
@node Org-mode links
|
||||
@section Org-mode links
|
||||
@node Creating org-mode links
|
||||
@section Creating org-mode links
|
||||
It can be useful to include links to e-mail messages or even search queries in
|
||||
your org-mode files. @t{mu4e} supports this with the @t{org-mu4e} module; you
|
||||
can set it up by adding it to your configuration:
|
||||
@ -826,8 +840,8 @@ org-insert-link}. Then, you can go to the query or message the link points to
|
||||
with either @t{M-x org-agenda-open-link} in agenda buffers, or @t{M-x
|
||||
org-open-at-point} elsewhere - both are typically bound to @kbd{C-c C-o}.
|
||||
|
||||
@node Org-contacts
|
||||
@section Org-contacts
|
||||
@node Maintaining an address-book with org-contacts
|
||||
@section Maintaining an address-book with org-contacts
|
||||
|
||||
To manage your addresses using @t{org-mode}, there is
|
||||
@t{org-contacts}@footnote{@url{http://julien.danjou.info/software/org-contacts.el}}.
|
||||
@ -844,7 +858,55 @@ You can use it with a @t{capture}-template:
|
||||
@end verbatim
|
||||
|
||||
After setting this up, you can use @t{M-x org-capture RET c} to get a template
|
||||
for a new contact based on the 'From:' address.
|
||||
for a new contact based on` the 'From:' address.
|
||||
|
||||
|
||||
@node Getting new mail notifications with Sauron
|
||||
@section Getting new mail notifications with Sauron
|
||||
|
||||
The emacs-package Sauron@footnote{Sauron can be found at
|
||||
@url{https://github.com/djcb/sauron}, or in the Marmalade package-repository
|
||||
at @url{http://http://marmalade-repo.org/}.} (by the same author) can be used
|
||||
to get notifications about new mails.
|
||||
|
||||
If you put something like the below script in your @t{crontab} (or have some
|
||||
other way of having it execute every @emph{n} minutes, you will receive
|
||||
notifications in the sauron-buffer when new messages arrive.
|
||||
|
||||
@verbatim
|
||||
#!/bin/sh
|
||||
# put the path to your Inbox folder here
|
||||
|
||||
CHECKDIR="/home/$LOGNAME/Maildir/Inbox"
|
||||
sauron-msg () {
|
||||
DBUS_COOKIE="/home/$LOGNAME/.sauron-dbus"
|
||||
if test "x$DBUS_SESSION_BUS_ADDRESS" = "x"; then
|
||||
if test -e $DBUS_COOKIE; then
|
||||
export DBUS_SESSION_BUS_ADDRESS="`cat $DBUS_COOKIE`"
|
||||
fi
|
||||
fi
|
||||
if test -n "x$DBUS_SESSION_BUS_ADDRESS"; then
|
||||
dbus-send --session \
|
||||
--dest="org.gnu.Emacs" \
|
||||
"/org/gnu/Emacs/Sauron" \
|
||||
"org.gnu.Emacs.Sauron.AddMsgEvent" \
|
||||
string:shell uint32:3 string:"$1"
|
||||
fi
|
||||
}
|
||||
|
||||
for f in `find $CHECKDIR -mmin -2 -a -type f`; do
|
||||
subject=`$MU view $f | grep '^Subject:' | sed 's/^Subject://'`
|
||||
sauron-msg "mail: $subject"
|
||||
done
|
||||
@end verbatim
|
||||
|
||||
Note, you should put something like:
|
||||
@lisp
|
||||
(setq sauron-dbus-cookie t)
|
||||
@end lisp
|
||||
in your setup, which allows the script to find the D-Bus session bus.
|
||||
|
||||
|
||||
|
||||
@node Example configuration
|
||||
@chapter Example configuration
|
||||
@ -1105,7 +1167,8 @@ select ('mark' in emacs-speak) the messages; the actions you then take (e.g.,
|
||||
@key{DEL} for delete, @key{m} for move and @key{t} for trash) will apply to
|
||||
@emph{all} selected messages
|
||||
@item @emph{How can I use @t{BBDB}?} Currently, there is no built-in for
|
||||
address management with @t{BBDB}; we recommend using @ref{Org-contacts} for now.
|
||||
address management with @t{BBDB}; instead, we recommend @ref{Maintaining an
|
||||
address-book with org-contacts} for now.
|
||||
@item @emph{mu4e only seems to return a subset of all matches - how can I get
|
||||
all?}. Yes, for speed reasons (and because, if you are like the author, you
|
||||
usually don't need thousands of matches), @t{mu4e} returns only up to the
|
||||
|
||||
Reference in New Issue
Block a user