[PATCH] Implement a simple read-eval-print loop.

2010-11-22 Thread Michael Hudson
On Sun, 21 Nov 2010 22:51:29 +0100, Michal Sojka  wrote:
> On Sun, 21 Nov 2010, Michal Sojka wrote:
> > This is a great idea. Now I use this script to invoke notmuch remotely
> > and I don't have to create master connection manually.
> > 
> > #!/bin/bash
> > socket="$HOME/.ssh/notmuch-connection"
> > if [[ ! -S $socket ]]; then
> > # Create master connection in background (the connection is closed
> > # after 10 minutes)
> > ssh -f -M -S $socket example.org sleep 600
> 
> The above line must be changed to 
>  ssh -f -M -S $socket example.org sleep 600 >/dev/null 2>&1
> Without the redirections emacs blocks until the command closes stdout,
> which takes 10 minutes in this case.

You can also use ssh -N, although that doesn't disconnect after 10
minutes. 'autossh' can also be handy in this sort of situation.

Cheers,
mwh

> > fi
> > printf -v args "%q " "$@"
> > ssh -S $socket example.org notmuch $args
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Michal Sojka
On Sun, 21 Nov 2010, Michal Sojka wrote:
> This is a great idea. Now I use this script to invoke notmuch remotely
> and I don't have to create master connection manually.
> 
> #!/bin/bash
> socket="$HOME/.ssh/notmuch-connection"
> if [[ ! -S $socket ]]; then
> # Create master connection in background (the connection is closed
> # after 10 minutes)
> ssh -f -M -S $socket example.org sleep 600

The above line must be changed to 
 ssh -f -M -S $socket example.org sleep 600 >/dev/null 2>&1
Without the redirections emacs blocks until the command closes stdout,
which takes 10 minutes in this case.

> fi
> printf -v args "%q " "$@"
> ssh -S $socket example.org notmuch $args


[PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Michal Sojka
On Sun, 21 Nov 2010, Austin Clements wrote:
> Out of curiosity, why not simply use SSH control mastering? 

I use control mastering, but it still takes about five seconds to display
notmuch hello screen.

> You could even make that part of the "standard" remote notmuch script,
> without requiring the user to change anything in their ssh
> configuration. 

This is a great idea. Now I use this script to invoke notmuch remotely
and I don't have to create master connection manually.

#!/bin/bash
socket="$HOME/.ssh/notmuch-connection"
if [[ ! -S $socket ]]; then
# Create master connection in background (the connection is closed
# after 10 minutes)
ssh -f -M -S $socket example.org sleep 600
fi
printf -v args "%q " "$@"
ssh -S $socket example.org notmuch $args

> This should be just as fast as a remote notmuch shell, but retains the
> ability to run multiple simultaneous operations and leverages all of
> the fancy session machinery already built in to ssh. It seems to me
> that ssh already does what you want, and I'm curious what the
> advantage is to reinventing the wheel.

You are probably right that notmuch shell would not help here. The big
delay in displaying notmuch-hello is mostly caused by ping delays which
add for each execution of notmuch count. So better then notmuch shell
might be a possibility to specify several commands at once and get all
the results together. Probably, the simplest thing would be to enhance
count subcommand so that it accepts multiple queries, possibly from
stdin.

Then we could use something like the following to determine the counts
of matched messages for saved searches:

$ (echo $query1; echo $query2; ...) | notmuch count --stdin


...

-Michal


[PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Austin Clements
What about
 notmuch count query1; notmuch count query2; ...
all as a single command issued by notmuch-hello?  That should give exactly
the same output, but eliminates the network round-trips without special
support from count.  It would be interesting to see how this compares with
your modified count and with the current round-trip-per-count approach.

On Sun, Nov 21, 2010 at 4:10 PM, Michal Sojka  wrote:

> Then we could use something like the following to determine the counts
> of matched messages for saved searches:
>
> $ (echo $query1; echo $query2; ...) | notmuch count --stdin
> 
> 
> ...
>
> -Michal
>
-- next part --
An HTML attachment was scrubbed...
URL: 



Re: [PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Austin Clements
What about
 notmuch count query1; notmuch count query2; ...
all as a single command issued by notmuch-hello?  That should give exactly
the same output, but eliminates the network round-trips without special
support from count.  It would be interesting to see how this compares with
your modified count and with the current round-trip-per-count approach.

On Sun, Nov 21, 2010 at 4:10 PM, Michal Sojka  wrote:

> Then we could use something like the following to determine the counts
> of matched messages for saved searches:
>
> $ (echo $query1; echo $query2; ...) | notmuch count --stdin
> 
> 
> ...
>
> -Michal
>
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Michael Hudson
On Sun, 21 Nov 2010 22:51:29 +0100, Michal Sojka  wrote:
> On Sun, 21 Nov 2010, Michal Sojka wrote:
> > This is a great idea. Now I use this script to invoke notmuch remotely
> > and I don't have to create master connection manually.
> > 
> > #!/bin/bash
> > socket="$HOME/.ssh/notmuch-connection"
> > if [[ ! -S $socket ]]; then
> > # Create master connection in background (the connection is closed
> > # after 10 minutes)
> > ssh -f -M -S $socket example.org sleep 600
> 
> The above line must be changed to 
>  ssh -f -M -S $socket example.org sleep 600 >/dev/null 2>&1
> Without the redirections emacs blocks until the command closes stdout,
> which takes 10 minutes in this case.

You can also use ssh -N, although that doesn't disconnect after 10
minutes. 'autossh' can also be handy in this sort of situation.

Cheers,
mwh

> > fi
> > printf -v args "%q " "$@"
> > ssh -S $socket example.org notmuch $args
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Michal Sojka
On Sun, 21 Nov 2010, Michal Sojka wrote:
> This is a great idea. Now I use this script to invoke notmuch remotely
> and I don't have to create master connection manually.
> 
> #!/bin/bash
> socket="$HOME/.ssh/notmuch-connection"
> if [[ ! -S $socket ]]; then
> # Create master connection in background (the connection is closed
> # after 10 minutes)
> ssh -f -M -S $socket example.org sleep 600

The above line must be changed to 
 ssh -f -M -S $socket example.org sleep 600 >/dev/null 2>&1
Without the redirections emacs blocks until the command closes stdout,
which takes 10 minutes in this case.

> fi
> printf -v args "%q " "$@"
> ssh -S $socket example.org notmuch $args
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Michal Sojka
On Sun, 21 Nov 2010, Austin Clements wrote:
> Out of curiosity, why not simply use SSH control mastering? 

I use control mastering, but it still takes about five seconds to display
notmuch hello screen.

> You could even make that part of the "standard" remote notmuch script,
> without requiring the user to change anything in their ssh
> configuration. 

This is a great idea. Now I use this script to invoke notmuch remotely
and I don't have to create master connection manually.

#!/bin/bash
socket="$HOME/.ssh/notmuch-connection"
if [[ ! -S $socket ]]; then
# Create master connection in background (the connection is closed
# after 10 minutes)
ssh -f -M -S $socket example.org sleep 600
fi
printf -v args "%q " "$@"
ssh -S $socket example.org notmuch $args

> This should be just as fast as a remote notmuch shell, but retains the
> ability to run multiple simultaneous operations and leverages all of
> the fancy session machinery already built in to ssh. It seems to me
> that ssh already does what you want, and I'm curious what the
> advantage is to reinventing the wheel.

You are probably right that notmuch shell would not help here. The big
delay in displaying notmuch-hello is mostly caused by ping delays which
add for each execution of notmuch count. So better then notmuch shell
might be a possibility to specify several commands at once and get all
the results together. Probably, the simplest thing would be to enhance
count subcommand so that it accepts multiple queries, possibly from
stdin.

Then we could use something like the following to determine the counts
of matched messages for saved searches:

$ (echo $query1; echo $query2; ...) | notmuch count --stdin


...

-Michal
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Austin Clements
Out of curiosity, why not simply use SSH control mastering?  You could even
make that part of the "standard" remote notmuch script, without requiring
the user to change anything in their ssh configuration.  This should be just
as fast as a remote notmuch shell, but retains the ability to run multiple
simultaneous operations and leverages all of the fancy session machinery
already built in to ssh.  It seems to me that ssh already does what you
want, and I'm curious what the advantage is to reinventing the wheel.

On Sat, Nov 20, 2010 at 6:38 PM, servilio  wrote:

> Hi Michal,
>
> On 20 November 2010 16:15, Michal Sojka  wrote:
> > On Sat, 20 Nov 2010, servilio wrote:
> >> This implementation uses GNU readline for the prompt and command
> >> history, with the default file completion enabled. GLib is used to
> >> split the read line into an arguments list.
> >
> > Hi,
> >
> > I haven't tested it yet, but it seems to be exactly the piece of code I
> > wanted to have to speed up notmuch-hello when notmuch is used remotely
> > over ssh. Spawning new ssh for every saved search to get the count of
> > matched messages has a way too big overhead. Is this the use case you
> > had in mind when implementing this?
>
> Great to see that you find it useful. Yes, the remote usage was in my
> mind, but it should enhance the local usage as well. We could also
> create a quicker test run using the shell.
>
> The disadvantage of using an interactive shell is that you can have
> only one operation running in the UI, and I see no way of
> interrumpting an operation unless you kill the process, but as
> starting a new shell shouldn't be a biggie, this might not be as
> limiting as might seem.
>
> The ideal would be for libnotmuch to be able to connect to a
> xapian-tcpsrv, but haven't had time to look at than, and an
> interactive shell seemed to be less time demanding to implement (and
> had the subjective promise of providing a lot of fun).
>
> > Currently, I have only one comment to the patch. For me, "repl" is a bit
> > unintuitive. I was thinking about "shell" as the name of subcommand for
> > this.
>
> I agree, maybe "shell" or "interactive" would be more intuitive, but
> when I started "repl" was the only one I could think of.
>
> Servilio
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
>
-- next part --
An HTML attachment was scrubbed...
URL: 



Re: [PATCH] Implement a simple read-eval-print loop.

2010-11-21 Thread Austin Clements
Out of curiosity, why not simply use SSH control mastering?  You could even
make that part of the "standard" remote notmuch script, without requiring
the user to change anything in their ssh configuration.  This should be just
as fast as a remote notmuch shell, but retains the ability to run multiple
simultaneous operations and leverages all of the fancy session machinery
already built in to ssh.  It seems to me that ssh already does what you
want, and I'm curious what the advantage is to reinventing the wheel.

On Sat, Nov 20, 2010 at 6:38 PM, servilio  wrote:

> Hi Michal,
>
> On 20 November 2010 16:15, Michal Sojka  wrote:
> > On Sat, 20 Nov 2010, servilio wrote:
> >> This implementation uses GNU readline for the prompt and command
> >> history, with the default file completion enabled. GLib is used to
> >> split the read line into an arguments list.
> >
> > Hi,
> >
> > I haven't tested it yet, but it seems to be exactly the piece of code I
> > wanted to have to speed up notmuch-hello when notmuch is used remotely
> > over ssh. Spawning new ssh for every saved search to get the count of
> > matched messages has a way too big overhead. Is this the use case you
> > had in mind when implementing this?
>
> Great to see that you find it useful. Yes, the remote usage was in my
> mind, but it should enhance the local usage as well. We could also
> create a quicker test run using the shell.
>
> The disadvantage of using an interactive shell is that you can have
> only one operation running in the UI, and I see no way of
> interrumpting an operation unless you kill the process, but as
> starting a new shell shouldn't be a biggie, this might not be as
> limiting as might seem.
>
> The ideal would be for libnotmuch to be able to connect to a
> xapian-tcpsrv, but haven't had time to look at than, and an
> interactive shell seemed to be less time demanding to implement (and
> had the subjective promise of providing a lot of fun).
>
> > Currently, I have only one comment to the patch. For me, "repl" is a bit
> > unintuitive. I was thinking about "shell" as the name of subcommand for
> > this.
>
> I agree, maybe "shell" or "interactive" would be more intuitive, but
> when I started "repl" was the only one I could think of.
>
> Servilio
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch
>
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Implement a simple read-eval-print loop.

2010-11-20 Thread Michal Sojka
On Sat, 20 Nov 2010, servilio wrote:
> This implementation uses GNU readline for the prompt and command
> history, with the default file completion enabled. GLib is used to
> split the read line into an arguments list.

Hi,

I haven't tested it yet, but it seems to be exactly the piece of code I
wanted to have to speed up notmuch-hello when notmuch is used remotely
over ssh. Spawning new ssh for every saved search to get the count of
matched messages has a way too big overhead. Is this the use case you
had in mind when implementing this?

Currently, I have only one comment to the patch. For me, "repl" is a bit
unintuitive. I was thinking about "shell" as the name of subcommand for
this.

-Michal


[PATCH] Implement a simple read-eval-print loop.

2010-11-20 Thread servilio
Hi Michal,

On 20 November 2010 16:15, Michal Sojka  wrote:
> On Sat, 20 Nov 2010, servilio wrote:
>> This implementation uses GNU readline for the prompt and command
>> history, with the default file completion enabled. GLib is used to
>> split the read line into an arguments list.
>
> Hi,
>
> I haven't tested it yet, but it seems to be exactly the piece of code I
> wanted to have to speed up notmuch-hello when notmuch is used remotely
> over ssh. Spawning new ssh for every saved search to get the count of
> matched messages has a way too big overhead. Is this the use case you
> had in mind when implementing this?

Great to see that you find it useful. Yes, the remote usage was in my
mind, but it should enhance the local usage as well. We could also
create a quicker test run using the shell.

The disadvantage of using an interactive shell is that you can have
only one operation running in the UI, and I see no way of
interrumpting an operation unless you kill the process, but as
starting a new shell shouldn't be a biggie, this might not be as
limiting as might seem.

The ideal would be for libnotmuch to be able to connect to a
xapian-tcpsrv, but haven't had time to look at than, and an
interactive shell seemed to be less time demanding to implement (and
had the subjective promise of providing a lot of fun).

> Currently, I have only one comment to the patch. For me, "repl" is a bit
> unintuitive. I was thinking about "shell" as the name of subcommand for
> this.

I agree, maybe "shell" or "interactive" would be more intuitive, but
when I started "repl" was the only one I could think of.

Servilio


Re: [PATCH] Implement a simple read-eval-print loop.

2010-11-20 Thread servilio
Hi Michal,

On 20 November 2010 16:15, Michal Sojka  wrote:
> On Sat, 20 Nov 2010, servilio wrote:
>> This implementation uses GNU readline for the prompt and command
>> history, with the default file completion enabled. GLib is used to
>> split the read line into an arguments list.
>
> Hi,
>
> I haven't tested it yet, but it seems to be exactly the piece of code I
> wanted to have to speed up notmuch-hello when notmuch is used remotely
> over ssh. Spawning new ssh for every saved search to get the count of
> matched messages has a way too big overhead. Is this the use case you
> had in mind when implementing this?

Great to see that you find it useful. Yes, the remote usage was in my
mind, but it should enhance the local usage as well. We could also
create a quicker test run using the shell.

The disadvantage of using an interactive shell is that you can have
only one operation running in the UI, and I see no way of
interrumpting an operation unless you kill the process, but as
starting a new shell shouldn't be a biggie, this might not be as
limiting as might seem.

The ideal would be for libnotmuch to be able to connect to a
xapian-tcpsrv, but haven't had time to look at than, and an
interactive shell seemed to be less time demanding to implement (and
had the subjective promise of providing a lot of fun).

> Currently, I have only one comment to the patch. For me, "repl" is a bit
> unintuitive. I was thinking about "shell" as the name of subcommand for
> this.

I agree, maybe "shell" or "interactive" would be more intuitive, but
when I started "repl" was the only one I could think of.

Servilio
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] Implement a simple read-eval-print loop.

2010-11-20 Thread Michal Sojka
On Sat, 20 Nov 2010, servilio wrote:
> This implementation uses GNU readline for the prompt and command
> history, with the default file completion enabled. GLib is used to
> split the read line into an arguments list.

Hi,

I haven't tested it yet, but it seems to be exactly the piece of code I
wanted to have to speed up notmuch-hello when notmuch is used remotely
over ssh. Spawning new ssh for every saved search to get the count of
matched messages has a way too big overhead. Is this the use case you
had in mind when implementing this?

Currently, I have only one comment to the patch. For me, "repl" is a bit
unintuitive. I was thinking about "shell" as the name of subcommand for
this.

-Michal
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] Implement a simple read-eval-print loop.

2010-11-20 Thread servilio
This implementation uses GNU readline for the prompt and command
history, with the default file completion enabled. GLib is used to
split the read line into an arguments list.
---
 Makefile.local |2 +-
 configure  |   40 ++-
 notmuch.c  |  115 ++--
 3 files changed, 141 insertions(+), 16 deletions(-)

diff --git a/Makefile.local b/Makefile.local
index f9b5a9b..3aff873 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -31,7 +31,7 @@ GPG_FILE=$(SHA1_FILE).asc
 # Smash together user's values with our extra values
 FINAL_CFLAGS = -DNOTMUCH_VERSION=$(VERSION) $(CFLAGS) $(WARN_CFLAGS)
$(CONFIGURE_CFLAGS) $(extra_cflags)
 FINAL_CXXFLAGS = $(CXXFLAGS) $(WARN_CXXFLAGS) $(CONFIGURE_CXXFLAGS)
$(extra_cflags) $(extra_cxxflags)
-FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Llib -lnotmuch
$(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS)
+FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Llib -lnotmuch
$(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS)
$(READLINE_LDFLAGS)
 FINAL_NOTMUCH_LINKER = CC
 ifneq ($(LINKER_RESOLVES_LIBRARY_DEPENDENCIES),1)
 FINAL_NOTMUCH_LDFLAGS += $(CONFIGURE_LDFLAGS)
diff --git a/configure b/configure
index c58dd0f..c9ea920 100755
--- a/configure
+++ b/configure
@@ -259,6 +259,32 @@ else
 errors=$((errors + 1))
 fi

+printf "Checking for readline... "
+
+echo "#include 
+#include 
+#include 
+
+int main(void)
+{
+static char *line = (char *)NULL;
+line = readline(\"\");
+add_history(line);
+return 0;
+}" > have_readline.c
+
+if ${CC} -lreadline -o have_readline have_readline.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_readline=1
+readline_ldflags="-lreadline"
+else
+printf "No.\n"
+have_readline=0
+errors=$((errors + 1))
+fi
+rm -f have_readline have_readline.c
+
 printf "Checking for valgrind development files... "
 if pkg-config --exists valgrind; then
 printf "Yes.\n"
@@ -341,6 +367,10 @@ EOF
echo "  The talloc library (including development files such as 
headers)"
echo "  http://talloc.samba.org/";
 fi
+if [ $have_readline -eq 0 ]; then
+   echo "  The readline library (including development files such as 
headers)"
+   echo "  http://tiswww.case.edu/php/chet/readline/rltop.html";
+fi
 cat <
  * Keith Packard 
+ *  Servilio Afre Puentes 
  */

+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
 #include "notmuch-client.h"

 typedef int (*command_function_t) (void *ctx, int argc, char *argv[]);
@@ -35,6 +44,9 @@ typedef struct command {
 static int
 notmuch_help_command (void *ctx, int argc, char *argv[]);

+static int
+notmuch_repl_command (void *ctx, int argc, char *argv[]);
+
 static const char search_terms_help[] =
 "\tSeveral notmuch commands accept a comman syntax for search\n"
 "\tterms.\n"
@@ -361,6 +373,10 @@ command_t commands[] = {
   "\tby the \"--format=json\" option of \"notmuch show\". If the\n"
   "\tmessage specified by the search terms does not include a\n"
   "\tpart with the specified \"id\" there will be no output." },
+{ "repl", notmuch_repl_command,
+  NULL,
+  "Execute an interactive interpreter of notmuch commands.",
+  "\tAlso known as a read-eval-print loop.\n" },
 { "config", notmuch_config_command,
   "[get|set] . [value ...]",
   "Get or set settings in the notmuch configuration file.",
@@ -471,6 +487,90 @@ notmuch_help_command (unused (void *ctx), int
argc, char *argv[])
 return 1;
 }

+static int
+notmuch_command_dispatch (void *ctx, int argc, char *argv[])
+{
+command_t *command;
+unsigned int i;
+
+for (i = 0; i < ARRAY_SIZE (commands); i++) {
+   command = &commands[i];
+
+   if (strcmp (argv[0], command->name) == 0)
+   return (command->function) (ctx, argc - 1, &argv[1]);
+}
+
+fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n",
+argv[0]);
+
+return 1;
+}
+
+/*
+ * A notmuch REPL (Read-eval-print loop) with readline support.
+ */
+static int
+notmuch_repl_command (void *ctx, unused (int argc), unused (char *argv[]))
+{
+const char *prompt = "notmuch> ";
+static char *line = (char *)NULL;
+int ret = 0;
+gint read_argc = 0;
+gchar **read_argv;
+GError *parse_error;
+
+/* Initialize readline. */
+/* Allow conditional parsing of the ~/.inputrc file. */
+rl_readline_name = "notmuch";
+
+do
+{
+read_argv = NULL;
+parse_error = NULL;
+line = readline(prompt);
+   if (line && *line)
+   {
+   g_shell_parse_argv((gchar *)line,
+  &read_argc,
+  &read_argv,
+  &parse_error);
+
+   if (parse_error == NULL)
+   {
+   add_history(line);
+   }
+   free (line);
+   line = (char *)NULL;
+
+   if (parse_error != NULL)
+   {
+ 

[PATCH] Implement a simple read-eval-print loop.

2010-11-20 Thread servilio
This implementation uses GNU readline for the prompt and command
history, with the default file completion enabled. GLib is used to
split the read line into an arguments list.
---
 Makefile.local |2 +-
 configure  |   40 ++-
 notmuch.c  |  115 ++--
 3 files changed, 141 insertions(+), 16 deletions(-)

diff --git a/Makefile.local b/Makefile.local
index f9b5a9b..3aff873 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -31,7 +31,7 @@ GPG_FILE=$(SHA1_FILE).asc
 # Smash together user's values with our extra values
 FINAL_CFLAGS = -DNOTMUCH_VERSION=$(VERSION) $(CFLAGS) $(WARN_CFLAGS)
$(CONFIGURE_CFLAGS) $(extra_cflags)
 FINAL_CXXFLAGS = $(CXXFLAGS) $(WARN_CXXFLAGS) $(CONFIGURE_CXXFLAGS)
$(extra_cflags) $(extra_cxxflags)
-FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Llib -lnotmuch
$(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS)
+FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Llib -lnotmuch
$(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS)
$(READLINE_LDFLAGS)
 FINAL_NOTMUCH_LINKER = CC
 ifneq ($(LINKER_RESOLVES_LIBRARY_DEPENDENCIES),1)
 FINAL_NOTMUCH_LDFLAGS += $(CONFIGURE_LDFLAGS)
diff --git a/configure b/configure
index c58dd0f..c9ea920 100755
--- a/configure
+++ b/configure
@@ -259,6 +259,32 @@ else
 errors=$((errors + 1))
 fi

+printf "Checking for readline... "
+
+echo "#include 
+#include 
+#include 
+
+int main(void)
+{
+static char *line = (char *)NULL;
+line = readline(\"\");
+add_history(line);
+return 0;
+}" > have_readline.c
+
+if ${CC} -lreadline -o have_readline have_readline.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_readline=1
+readline_ldflags="-lreadline"
+else
+printf "No.\n"
+have_readline=0
+errors=$((errors + 1))
+fi
+rm -f have_readline have_readline.c
+
 printf "Checking for valgrind development files... "
 if pkg-config --exists valgrind; then
 printf "Yes.\n"
@@ -341,6 +367,10 @@ EOF
echo "  The talloc library (including development files such as 
headers)"
echo "  http://talloc.samba.org/";
 fi
+if [ $have_readline -eq 0 ]; then
+   echo "  The readline library (including development files such as 
headers)"
+   echo "  http://tiswww.case.edu/php/chet/readline/rltop.html";
+fi
 cat <
  * Keith Packard 
+ *  Servilio Afre Puentes 
  */

+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
 #include "notmuch-client.h"

 typedef int (*command_function_t) (void *ctx, int argc, char *argv[]);
@@ -35,6 +44,9 @@ typedef struct command {
 static int
 notmuch_help_command (void *ctx, int argc, char *argv[]);

+static int
+notmuch_repl_command (void *ctx, int argc, char *argv[]);
+
 static const char search_terms_help[] =
 "\tSeveral notmuch commands accept a comman syntax for search\n"
 "\tterms.\n"
@@ -361,6 +373,10 @@ command_t commands[] = {
   "\tby the \"--format=json\" option of \"notmuch show\". If the\n"
   "\tmessage specified by the search terms does not include a\n"
   "\tpart with the specified \"id\" there will be no output." },
+{ "repl", notmuch_repl_command,
+  NULL,
+  "Execute an interactive interpreter of notmuch commands.",
+  "\tAlso known as a read-eval-print loop.\n" },
 { "config", notmuch_config_command,
   "[get|set] . [value ...]",
   "Get or set settings in the notmuch configuration file.",
@@ -471,6 +487,90 @@ notmuch_help_command (unused (void *ctx), int
argc, char *argv[])
 return 1;
 }

+static int
+notmuch_command_dispatch (void *ctx, int argc, char *argv[])
+{
+command_t *command;
+unsigned int i;
+
+for (i = 0; i < ARRAY_SIZE (commands); i++) {
+   command = &commands[i];
+
+   if (strcmp (argv[0], command->name) == 0)
+   return (command->function) (ctx, argc - 1, &argv[1]);
+}
+
+fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n",
+argv[0]);
+
+return 1;
+}
+
+/*
+ * A notmuch REPL (Read-eval-print loop) with readline support.
+ */
+static int
+notmuch_repl_command (void *ctx, unused (int argc), unused (char *argv[]))
+{
+const char *prompt = "notmuch> ";
+static char *line = (char *)NULL;
+int ret = 0;
+gint read_argc = 0;
+gchar **read_argv;
+GError *parse_error;
+
+/* Initialize readline. */
+/* Allow conditional parsing of the ~/.inputrc file. */
+rl_readline_name = "notmuch";
+
+do
+{
+read_argv = NULL;
+parse_error = NULL;
+line = readline(prompt);
+   if (line && *line)
+   {
+   g_shell_parse_argv((gchar *)line,
+  &read_argc,
+  &read_argv,
+  &parse_error);
+
+   if (parse_error == NULL)
+   {
+   add_history(line);
+   }
+   free (line);
+   line = (char *)NULL;
+
+   if (parse_error != NULL)
+   {
+