mu/guile/mu-guile.texi

399 lines
13 KiB
Plaintext
Raw Normal View History

\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
2012-01-01 21:46:11 +01:00
* 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::
2012-01-06 15:18:18 +01:00
* 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
2012-01-01 21:46:11 +01:00
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
2012-01-06 15:18:18 +01:00
@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!
2012-01-06 15:18:18 +01:00
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