diff --git a/configure.in b/configure.in index e93e173..476397b 100644 --- a/configure.in +++ b/configure.in @@ -201,6 +201,22 @@ else fi AC_SUBST(smtpservers)dnl +dnl Do you want whatnow to use readline()? +dnl (e.g. enable tab completion and editor support) +AC_ARG_WITH([readline], + [AS_HELP_STRING([--with-readline], + [enable line-editing when using whatnow])], + [], + [with_readline=yes]) +if test x"$with_readline" = x"yes"; then + AC_DEFINE(HAVE_LIBREADLINE, 1, + [Define if you have libreadline.])dnl + LIBREADLINE="-lreadline -lncurses" +else + LIBREADLINE= +fi +AC_SUBST(LIBREADLINE)dnl + dnl ---------------------------------------------------- dnl Default location is /usr/local/nmh/{bin,etc,lib,man} dnl ---------------------------------------------------- diff --git a/sbr/getans.c b/sbr/getans.c index 3229eb5..b8c4df1 100644 --- a/sbr/getans.c +++ b/sbr/getans.c @@ -12,6 +12,18 @@ #include #include +#if HAVE_LIBREADLINE + +#include +#include + +static struct swit *rl_cmds; + +char *nmh_command_generator PARAMS((const char *, int)); +char **nmh_completion PARAMS((const char *, int, int)); + +#endif + static char ansbuf[BUFSIZ]; static jmp_buf sigenv; @@ -20,7 +32,6 @@ static jmp_buf sigenv; */ static RETSIGTYPE intrser (int); - char ** getans (char *prompt, struct swit *ansp) { @@ -66,6 +77,97 @@ getans (char *prompt, struct swit *ansp) } } +#if HAVE_LIBREADLINE + +char ** +getans_via_readline (char *prompt, struct swit *ansp) +{ + char *ans, **cpp; + + initialize_readline (); + rl_cmds = ansp; + + for (;;) { + ans = readline (prompt); + if (ans == NULL || ans[0] == '?' || ans[0] == 0 ) { + printf ("Options are:\n"); + print_sw (ALL, ansp, "", stdout); + free(ans); + continue; + } + strcpy (ansbuf,ans); + cpp = brkstring (ansbuf, " ", NULL); + switch (smatch (*cpp, ansp)) { + case AMBIGSW: + ambigsw (*cpp, ansp); + continue; + case UNKWNSW: + printf (" -%s unknown. Hit for help.\n", *cpp); + continue; + default: + free(ans); + return cpp; + } + free(ans); + } +} + +// HERE use the mh equiv... +char * +dupstr (char *s) +{ + char *r; + r = xmalloc (strlen (s) + 1); + strcpy (r, s); + return (r); +} +// ...HERE + +void +initialize_readline () +{ + rl_readline_name = "Nmh"; + rl_attempted_completion_function = nmh_completion; +} + +char ** +nmh_completion (const char *text, int start, int end) +{ + char **matches; + + matches = (char **)NULL; + + if (start == 0) + matches = rl_completion_matches (text, nmh_command_generator); + + return (matches); +} + +char * +nmh_command_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + char buf[256]; + char *p; + + if (!state) { + list_index = 0; + len = strlen (text); + } + while (name = rl_cmds[list_index].sw) { + list_index++; + strncpy(buf, name, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + p = *brkstring (buf, " ", NULL); + if (strncmp (p, text, len) == 0) + return (dupstr(p)); + } + + return ((char *)NULL); +} + +#endif static RETSIGTYPE intrser (int i) diff --git a/uip/Makefile.in b/uip/Makefile.in index 370fc15..91a320d 100644 --- a/uip/Makefile.in +++ b/uip/Makefile.in @@ -23,8 +23,9 @@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ MTSLIB = ../mts/libmts.a NDBM_LIBS = @NDBM_LIBS@ +READLINE_LIBS = @LIBREADLINE@ LOCALLIBS = ../config/version.o ../config/config.o $(MTSLIB) ../sbr/libmh.a -LINKLIBS = $(LOCALLIBS) $(LIBS) +LINKLIBS = $(READLINE_LIBS) $(LOCALLIBS) $(LIBS) LINT = @LINT@ LINTFLAGS = @LINTFLAGS@ diff --git a/uip/whatnowsbr.c b/uip/whatnowsbr.c index 6541b42..3aff4b8 100644 --- a/uip/whatnowsbr.c +++ b/uip/whatnowsbr.c @@ -245,7 +245,11 @@ WhatNow (int argc, char **argv) snprintf (prompt, sizeof(prompt), myprompt, invo_name); for (;;) { +#ifndef HAVE_LIBREADLINE if (!(argp = getans (prompt, aleqs))) { +#else + if (!(argp = getans_via_readline (prompt, aleqs))) { +#endif unlink (LINK); done (1); }