\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-.tar.gz # use the specific version $ cd mu- $./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 [])} @item @code{(mu:for-each-message [])} @end itemize The first function, @code{mu:message-list} returns a list of all messages matching @t{}; if you leave @t{} 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 = (#< 9040640> #< 9040630> #< 9040570>) @end verbatim So, we get a list with three @t{} 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{} 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{} 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{}), let's see what we can do with such an object. @code{} 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{} 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{} 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{} 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 "")} returns an arbitrary message header (or @t{#f} if not found) -- e.g. @code{(header msg "User-Agent")} @item @code{(contacts 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