Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

399 lines (310 sloc) 13.091 kb
\input texinfo.tex @c -*-texinfo-*-
@c %**start of header
@setfilename mu-guile.info
@settitle mu-guile user manual
@documentencoding utf-8
@c %**end of header
@dircategory The Algorithmic Language Scheme
@direntry
* mu-guile manual: (mu-guile). Guile bindings for the @t{mu} e-mail indexer/searcher.
@end direntry
@copying
Copyright @copyright{} 2012 Dirk-Jan C. Binnema
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license is included in the section entitled ``GNU Free
Documentation License.''
@end quotation
@end copying
@node Top
@top mu4e Manual
Welcome to @t{mu-guile}!
@t{mu-guile} is a binding of the @t{mu} email search engine and the @t{guile}
programming language.
@menu
* Introduction::
* Getting started::
* Initializing mu-guile::
* Messages::
* Contacts::
Appendices
* GNU Free Documentation License:: The license of this manual.
@end menu
@node Introduction
@chapter Introduction
@t{mu4e} is an e-mail program for @emph{GNU/Emacs}; it uses the @t{mu} maildir
search engine as its backend, making @t{mu} fully search-based.
@t{mu} is a program for indexing / searching e-mails, as well as an
@t{emacs}-based email-client (@t{mu4e}.
@t{guile} is the @emph{GNU Ubiquitous Intelligent Language for Extensions} - a
version of the @emph{Scheme} programming language and the official GNU
extension language.
@t{mu-guile} connects @t{mu} and @t{guile}, and allows you to easily write
programs to do things with your e-mails.
@node Getting started
@chapter Getting started
@menu
* Installation::
* First steps::
@end menu
This chapter walks you through the installation and some basic steps to ensure
things work correctly.
@node Installation
@section Installation
@t{mu-guile} is part of @t{mu} - by installing the latter, the former will be
installed as well. Note, however, that @t{mu-guile} requires you to have
@t{guile} version 2.0 installed, otherwise @t{mu-guile} will not be
built/installed.
At the time of writing, there are no distribution packages for @t{mu-guile}
yet, so we are assuming installation from source packages.
Installation follows the normal sequence of:
@example
$ tar xvfz mu-<version>.tar.gz # use the specific version
$ cd mu-<version>
$./configure
@end example
The output of @t{./configure} should end with a little text describing the
detected versions of various libraries @t{mu} depends on. In particular, it
should mention the @t{guile} version, e.g.
@example
Guile version : 2.0.3.82-a2c66
@end example
If you don't see any line referring to @t{guile}, please install it, and run
@t{configure} again. Note once more, @t{mu-guile} requires @t{guile} version
2.0.
After a succesfull @t{./configure}, we can make and install the package:
@example
$ make && sudo make install
@end example
After this, @t{mu} and @t{mu-guile} should be installed. Note that the above
instructions will normally install things under @t{/usr/local}; you may need
to update @t{guile}'s @t{%load-path} to find it there.
You can check the current load-path with the following:
@example
guile -c '(display %load-path)(newline)'
@end example
If necessary, you can add the @t{%load-path} by adding something like the
following to your @file{~/.guile}:
@lisp
(set! %load-path (cons "/usr/local/share/guile/site/2.0" %load-path))
@end lisp
After this, you should be ready to go.
@node First steps
@section First steps
Assuming @t{mu-guile} has been installed correctly (@ref{Installation}), and
also assuming that you have already indexed your e-mail messages (if
necessary, see the @t{mu-index} man-page), we are ready to start @t{mu-guile};
a session may look something like this:
@verbatim
$ guile
GNU Guile 2.0.3.82-a2c66
Copyright (C) 1995-2011 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
scheme@(guile-user)>
@end verbatim
Now, we need to load the @t{mu-guile} module:
@verbatim
scheme@(guile-user)> (use-modules (mu) (mu message))
@end verbatim
This will load the basic modules for dealing with messages. After we have
loaded the modules, we need to initialize the @t{mu-guile} system:
@verbatim
scheme@(guile-user)> (mu:initialize)
@end verbatim
When this is done, we can start querying the database. We'll go into various
functions later in this manual, but just to give an example, let's get a list
of the subjects of all messages that mention @emph{hello}:
@verbatim
scheme@(guile-user)> (for-each
(lambda(msg)
(format #t "Subject: ~a\n" (subject msg)))
(mu:message-list "hello"))
@end verbatim
@node Initializing mu-guile
@chapter Initializing mu-guile
It is of course possible to write separate programs with @t{mu-guile}, but for
now we'll do things @emph{interactively}, i.e., from the Guile-prompt
(``@abbr{REPL}'').
We start our @t{mu-guile} session by starting @t{guile}:
@verbatim
$ guile
GNU Guile 2.0.3.82-a2c66
Copyright (C) 1995-2011 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
scheme@(guile-user)>
@end verbatim
Now, the first thing we need to do is load the @t{mu-guile} modules;
currently, there are three available:
@itemize
@item @code{mu} - initialization, functions to get messages, contacts
@item @code{mu message} - functions to deal with messages
@item @code{mu contact} - functions to deal with contacts
@end itemize
Let's simply load all of them:
@verbatim
scheme@(guile-user)> (use-modules (mu) (mu message) (mu contact))
@end verbatim
Assuming you have installed everything correctly, the first time you do this,
@t{guile} will probably respond by showing some message about compiling the
modules, and then end with another prompt.
Before we can do anything with @t{mu guile}, we need to initialize the
system. The reason as to not do this automatically is to enable people to use
non-default places to keep there @t{mu} data files.
We can initialize the system with:
@verbatim
scheme@(guile-user)> (mu:initialize)
@end verbatim
Which will use the default location of @file{~/.mu}. Or, instead, if you keep
your @t{mu} data in a non-standard place:
@verbatim
scheme@(guile-user)> (mu:initialize #t "/path/to/my/mu/")
@end verbatim
Note, the second parameter, @t{#t} is for future use; simply set it to @t{#t}
for now.
If all worked up until here, we're ready to go with @t{mu-guile}.
@node Messages
@chapter Messages
In this chapter, we discuss how to find messages, and then how to do various
things with them.
@menu
* Finding messages::
* Message functions::
@end menu
@node Finding messages
@section Finding messages
Now we are ready to retrieve some messages from the system. There are two
principle functions to do this:
@itemize
@item @code{(mu:message-list [<search-expression>])}
@item @code{(mu:for-each-message <function> [<search-expression>])}
@end itemize
The first function, @code{mu:message-list} returns a list of all messages
matching @t{<search-expression>}; if you leave @t{<search-expression>} out, it
returns @emph{all} messages.
For example, to get all messages with @emph{coffee} in the subject line, you
could do:
@verbatim
scheme@(guile-user)> (mu:message-list "subject:coffee")
$1 = (#<<mu-message> 9040640> #<<mu-message> 9040630>
#<<mu-message> 9040570>)
@end verbatim
So, we get a list with three @t{<mu-message>} objects. We'll discuss them in a
bit more detail in the next section, but let's just use the @code{subject}
function ('method') provided by @t{<mu-message>} objects to retrieve the
subject-field.
For your convenience, @t{guile} has saved the result in @t{$1}, so to get the
subject of the first message in the list, we can do:
@verbatim
scheme@(guile-user)> (subject (car $1))
$2 = "Re: best coffee ever!"
@end verbatim
The second function we mentioned, @code{mu:for-each-message}, executes some
function for each message matched by the search expression (or @emph{all}
message if the search expression is omitted).
@verbatim
scheme@(guile-user)> (mu:for-each-message
(lambda(msg)
(display (subject msg))
(newline))
"subject:coffee")
Re: best coffee ever!
best coffee ever!
Coffee beans
scheme@(guile-user)>
@end verbatim
Using @code{mu:message-list} and/or
@code{mu:for-each-message}@footnote{Implementation node:
@code{mu:message-list} is implemented in terms of @code{mu:for-each-message},
not the other way around. Due to the way @t{mu} works,
@code{mu:for-each-message} is rather more efficient than a combination for
@code{for-each} and @code{mu:message-list}} and a couple of @t{<mu-message>}
methods, together with that Guile/Scheme provides should allow for many
interesting programs.
@node Message functions
@section Message functions
Now that we've seen how to retrieve lists of message objects
(@code{<mu-message>}), let's see what we can do with such an object.
@code{<mu-message>} defines the following methods
@footnote{A note on naming: functions we have seen before --
@code{mu:initialize}, @code{mu:message-list} and @code{mu:for-each-message}
are prefixed with @t{mu:}. This is not the case for the @code{<mu-message>}
methods to be discussed next, such as the methods @code{subject} and
@code{from}. Reason for this is that it is not @emph{needed}, since these
methods only recognized for @code{<mu-message>} objects, and do not affect
anything else, while the @code{mu:}-prefixed are 'globally visible' and thus
we need to be careful about naming conflicts}
that all only take a single
@code{<mu-message>} object as a parameter. We won't go into the exact meanings
for all of these functions here - for the details about various flags /
properties, please refer to the @t{mu-find} man-page.
@itemize
@item @code{bcc}: the @t{Bcc} field of the message, or @t{#f} if there is none
@item @code{body-html}: : the html body of the message, or @t{#f} if there is none
@item @code{body-txt}: the plain-text body of the message, or @t{#f} if there is none
@item @code{cc}: the @t{Bcc} field of the message, or @t{#f} if there is none
@item @code{date}: the @t{Date} field of the message, or 0 if there is none
@item @code{flags}: list of message-flags for this message
@item @code{from}: the @t{From} field of the message, or @t{#f} if there is none
@item @code{maildir}: the maildir this message lives in, or @t{#f} if there is none
@item @code{message-id}: the @t{Message-Id} field of the message, or @t{#f} if there is none
@item @code{path}: the file system path for this message
@item @code{priority}: the priority of this message (either @t{mu:low}, @t{mu:normal}
or @t{mu:high}
@item @code{references}: the list of messages (message-ids) this message
refers to in the @t{References:} header
@item @code{size}: size of the message in bytes
@item @code{subject}: the @t{Subject} field of the message, or @t{#f} if there is none.
@item @code{tags}: list of tags for this message
@item @code{to}: the sender of the message, or @t{#f} if there is none.
@end itemize
With these functions, we can query messages for their properties; for example:
@verbatim
scheme@(guile-user)> (define msg (car (mu:message-list "snow")))
scheme@(guile-user)> (subject msg)
$1 = "Re: Running in the snow is beautiful"
scheme@(guile-user)> (flags msg)
$2 = (mu:replied mu:seen)
scheme@(guile-user)> (strftime "%F" (localtime (date msg)))
$3 = "2011-01-15"
@end verbatim
There are a couple more functions:
@itemize
@item @code{(header <mu-message> "<header-name>")} returns an arbitrary message
header (or @t{#f} if not found) -- e.g. @code{(header msg "User-Agent")}
@item @code{(contacts <mu-message> contact-type)} which returns a list
of contacts (names/e-mail addresses in the To/From/Cc/Bcc-fields).
@xref{Contacts}.
@end itemize
Now, let's write a little example -- let's find out what is the @emph{longest
subject} of any of your e-mail messages; you can put in a separate file, make
it executable, and run it like any program.
@verbatim
#!/bin/sh
exec guile -e main -s $0 $@
!#
(use-modules (mu) (mu message))
(let* ((longest-subj ""))
(mu:initialize)
(mu:for-each-message
(lambda(msg)
(let ((subj (subject msg)))
(if (and subj (> (string-length subj) (string-length longest-subj)))
(set! longest-subj subj))))
query)
(format #t "Longest subject: ~a" longest-subj))
@end verbatim
@node Contacts
@chapter Contacts
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texi
@bye
Jump to Line
Something went wrong with that request. Please try again.