mirror of
https://github.com/troglobit/editline.git
synced 2025-05-05 20:11:12 +08:00
Basic support for custom completion handlers with the two "standard"
rl_complete() and rl_list_possib(). Simply leave out complete.o from the default build and in all programs require these two functions to be supplied. A better alternative would be to use function pointers and check those for NULL in the running code. With this code, and no completion handler the editline code will die.
This commit is contained in:
parent
4a3fbd9187
commit
5c9f0047bb
43
configure
vendored
43
configure
vendored
@ -695,6 +695,8 @@ CPP
|
||||
GREP
|
||||
EGREP
|
||||
LIBOBJS
|
||||
COMPLETE_TRUE
|
||||
COMPLETE_FALSE
|
||||
LTLIBOBJS'
|
||||
ac_subst_files=''
|
||||
ac_precious_vars='build_alias
|
||||
@ -1283,6 +1285,7 @@ Optional Features:
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--disable-dependency-tracking speeds up one-time build
|
||||
--enable-dependency-tracking do not reject slow dependency extractors
|
||||
--enable-default-complete Enable default completion handler.
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
@ -4970,6 +4973,35 @@ fi
|
||||
done
|
||||
|
||||
|
||||
# Check whether --enable-complete was given.
|
||||
if test "${enable_complete+set}" = set; then
|
||||
enableval=$enable_complete;
|
||||
case "${enableval}" in
|
||||
yes)
|
||||
complete=true
|
||||
;;
|
||||
no)
|
||||
complete=false
|
||||
;;
|
||||
*)
|
||||
{ { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-default-complete" >&5
|
||||
echo "$as_me: error: bad value ${enableval} for --enable-default-complete" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
;;
|
||||
esac
|
||||
else
|
||||
complete=false
|
||||
fi
|
||||
|
||||
if test x$complete = xtrue; then
|
||||
COMPLETE_TRUE=
|
||||
COMPLETE_FALSE='#'
|
||||
else
|
||||
COMPLETE_TRUE='#'
|
||||
COMPLETE_FALSE=
|
||||
fi
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile src/Makefile include/Makefile man/Makefile examples/Makefile"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
@ -5082,6 +5114,13 @@ echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
if test -z "${COMPLETE_TRUE}" && test -z "${COMPLETE_FALSE}"; then
|
||||
{ { echo "$as_me:$LINENO: error: conditional \"COMPLETE\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&5
|
||||
echo "$as_me: error: conditional \"COMPLETE\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
: ${CONFIG_STATUS=./config.status}
|
||||
ac_clean_files_save=$ac_clean_files
|
||||
@ -5698,10 +5737,12 @@ CPP!$CPP$ac_delim
|
||||
GREP!$GREP$ac_delim
|
||||
EGREP!$EGREP$ac_delim
|
||||
LIBOBJS!$LIBOBJS$ac_delim
|
||||
COMPLETE_TRUE!$COMPLETE_TRUE$ac_delim
|
||||
COMPLETE_FALSE!$COMPLETE_FALSE$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 81; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 83; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
15
configure.ac
15
configure.ac
@ -40,4 +40,19 @@ AC_PROG_GCC_TRADITIONAL
|
||||
AC_FUNC_STAT
|
||||
AC_CHECK_FUNCS([strchr strdup strrchr tcgetattr])
|
||||
|
||||
AC_ARG_ENABLE([complete],
|
||||
[ --enable-default-complete Enable default completion handler.],[
|
||||
case "${enableval}" in
|
||||
yes)
|
||||
complete=true
|
||||
;;
|
||||
no)
|
||||
complete=false
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([bad value ${enableval} for --enable-default-complete])
|
||||
;;
|
||||
esac],[complete=false])
|
||||
AM_CONDITIONAL([COMPLETE], [test x$complete = xtrue])
|
||||
|
||||
AC_OUTPUT(Makefile src/Makefile include/Makefile man/Makefile examples/Makefile)
|
||||
|
@ -1,10 +1,10 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
LDADD = $(top_builddir)/src/libedit.a
|
||||
AM_CFLAGS = -I$(top_srcdir)/src
|
||||
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include
|
||||
|
||||
# TODO: Port "fileman" example from BSD editline
|
||||
noinst_PROGRAMS = testit
|
||||
noinst_PROGRAMS = testit cli
|
||||
|
||||
testit_SOURCES = testit.c
|
||||
#fileman_SOURCES = fileman.c
|
||||
|
@ -30,7 +30,7 @@ POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
noinst_PROGRAMS = testit$(EXEEXT)
|
||||
noinst_PROGRAMS = testit$(EXEEXT) cli$(EXEEXT)
|
||||
subdir = examples
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
@ -41,6 +41,10 @@ mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
cli_SOURCES = cli.c
|
||||
cli_OBJECTS = cli.$(OBJEXT)
|
||||
cli_LDADD = $(LDADD)
|
||||
cli_DEPENDENCIES = $(top_builddir)/src/libedit.a
|
||||
am_testit_OBJECTS = testit.$(OBJEXT)
|
||||
testit_OBJECTS = $(am_testit_OBJECTS)
|
||||
testit_LDADD = $(LDADD)
|
||||
@ -52,8 +56,8 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(testit_SOURCES)
|
||||
DIST_SOURCES = $(testit_SOURCES)
|
||||
SOURCES = cli.c $(testit_SOURCES)
|
||||
DIST_SOURCES = cli.c $(testit_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@ -144,7 +148,7 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
LDADD = $(top_builddir)/src/libedit.a
|
||||
AM_CFLAGS = -I$(top_srcdir)/src
|
||||
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include
|
||||
testit_SOURCES = testit.c
|
||||
all: all-am
|
||||
|
||||
@ -182,6 +186,9 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
|
||||
cli$(EXEEXT): $(cli_OBJECTS) $(cli_DEPENDENCIES)
|
||||
@rm -f cli$(EXEEXT)
|
||||
$(LINK) $(cli_OBJECTS) $(cli_LDADD) $(LIBS)
|
||||
testit$(EXEEXT): $(testit_OBJECTS) $(testit_DEPENDENCIES)
|
||||
@rm -f testit$(EXEEXT)
|
||||
$(LINK) $(testit_OBJECTS) $(testit_LDADD) $(LIBS)
|
||||
@ -192,6 +199,7 @@ mostlyclean-compile:
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cli.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testit.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
|
78
examples/cli.c
Normal file
78
examples/cli.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* The "testit" micro shell, now with command completion.
|
||||
* To be able to run, don't "--enable-default-complete".
|
||||
*/
|
||||
#include "editline.h"
|
||||
#include <string.h>
|
||||
|
||||
char *list[] = {
|
||||
"foo ", "bar ", "bsd ", "cli ", "ls ", "cd ", "malloc ", "tee ", NULL
|
||||
};
|
||||
|
||||
/*
|
||||
** Attempt to complete the pathname, returning an allocated copy.
|
||||
** Fill in *unique if we completed it, or set it to 0 if ambiguous.
|
||||
*/
|
||||
char *rl_complete(char *token, int *match)
|
||||
{
|
||||
int i;
|
||||
int index = -1;
|
||||
int matchlen = 0;
|
||||
int count = 0;
|
||||
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
int partlen = strlen (token); /* Part of token */
|
||||
|
||||
if (!strncmp (list[i], token, partlen))
|
||||
{
|
||||
index = i;
|
||||
matchlen = partlen;
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
*match = 1;
|
||||
return strdup (list[index] + matchlen);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return all possible completions.
|
||||
*/
|
||||
int rl_list_possib(char *token, char ***av)
|
||||
{
|
||||
int i, num, total = 0;
|
||||
char **copy;
|
||||
|
||||
for (num = 0; list[num]; num++)
|
||||
;
|
||||
copy = (char **) malloc (num * sizeof(char *));
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (!strncmp (list[i], token, strlen (token)))
|
||||
{
|
||||
copy[total] = strdup (list[i]);
|
||||
total ++;
|
||||
}
|
||||
}
|
||||
*av = copy;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int main(int ac, char *av[])
|
||||
{
|
||||
char *line;
|
||||
char *prompt = "cli> ";
|
||||
|
||||
while ((line = readline(prompt)) != NULL) {
|
||||
(void)printf("\t\t\t|%s|\n", line);
|
||||
free(line);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -2,5 +2,8 @@ AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
lib_LIBRARIES = libedit.a
|
||||
|
||||
libedit_a_SOURCES = editline.c editline.h complete.c sysunix.c unix.h
|
||||
|
||||
libedit_a_SOURCES = editline.c editline.h sysunix.c unix.h
|
||||
if COMPLETE
|
||||
# Built-in completion handler.
|
||||
libedit_a_SOURCES += complete.c
|
||||
endif
|
||||
|
@ -30,6 +30,8 @@ POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
# Built-in completion handler.
|
||||
@COMPLETE_TRUE@am__append_1 = complete.c
|
||||
subdir = src
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
@ -52,8 +54,11 @@ AR = ar
|
||||
ARFLAGS = cru
|
||||
libedit_a_AR = $(AR) $(ARFLAGS)
|
||||
libedit_a_LIBADD =
|
||||
am_libedit_a_OBJECTS = editline.$(OBJEXT) complete.$(OBJEXT) \
|
||||
sysunix.$(OBJEXT)
|
||||
am__libedit_a_SOURCES_DIST = editline.c editline.h sysunix.c unix.h \
|
||||
complete.c
|
||||
@COMPLETE_TRUE@am__objects_1 = complete.$(OBJEXT)
|
||||
am_libedit_a_OBJECTS = editline.$(OBJEXT) sysunix.$(OBJEXT) \
|
||||
$(am__objects_1)
|
||||
libedit_a_OBJECTS = $(am_libedit_a_OBJECTS)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
@ -63,7 +68,7 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(libedit_a_SOURCES)
|
||||
DIST_SOURCES = $(libedit_a_SOURCES)
|
||||
DIST_SOURCES = $(am__libedit_a_SOURCES_DIST)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@ -154,7 +159,8 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
lib_LIBRARIES = libedit.a
|
||||
libedit_a_SOURCES = editline.c editline.h complete.c sysunix.c unix.h
|
||||
libedit_a_SOURCES = editline.c editline.h sysunix.c unix.h \
|
||||
$(am__append_1)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
Loading…
Reference in New Issue
Block a user