i-bash/builtins/complete.def

878 lines
21 KiB
Modula-2
Raw Normal View History

2000-03-17 21:46:59 +00:00
This file is complete.def, from which is created complete.c.
2009-01-12 13:36:28 +00:00
It implements the builtins "complete", "compgen", and "compopt" in Bash.
2000-03-17 21:46:59 +00:00
Copyright (C) 1999-2015 Free Software Foundation, Inc.
2000-03-17 21:46:59 +00:00
This file is part of GNU Bash, the Bourne Again SHell.
2009-01-12 13:36:28 +00:00
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
2000-03-17 21:46:59 +00:00
2009-01-12 13:36:28 +00:00
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
2000-03-17 21:46:59 +00:00
2009-01-12 13:36:28 +00:00
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
2000-03-17 21:46:59 +00:00
$PRODUCES complete.c
$BUILTIN complete
$DEPENDS_ON PROGRAMMABLE_COMPLETION
$FUNCTION complete_builtin
2011-11-21 20:51:19 -05:00
$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
2009-01-12 13:36:28 +00:00
Specify how arguments are to be completed by Readline.
For each NAME, specify how arguments are to be completed. If no options
are supplied, existing completion specifications are printed in a way that
allows them to be reused as input.
Options:
-p print existing completion specifications in a reusable format
-r remove a completion specification for each NAME, or, if no
NAMEs are supplied, all completion specifications
2011-11-21 20:51:19 -05:00
-D apply the completions and actions as the default for commands
without any specific completion defined
2011-11-21 20:51:19 -05:00
-E apply the completions and actions to "empty" commands --
completion attempted on a blank line
2009-01-12 13:36:28 +00:00
When completion is attempted, the actions are applied in the order the
2011-11-21 20:51:19 -05:00
uppercase-letter options are listed above. The -D option takes
precedence over -E.
2009-01-12 13:36:28 +00:00
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
2000-03-17 21:46:59 +00:00
$END
#include <config.h>
#include <stdio.h>
#include "../bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
2004-07-27 13:29:18 +00:00
#include "../bashintl.h"
2000-03-17 21:46:59 +00:00
#include "../shell.h"
#include "../builtins.h"
#include "../pcomplete.h"
2004-07-27 13:29:18 +00:00
#include "../bashline.h"
2000-03-17 21:46:59 +00:00
#include "common.h"
#include "bashgetopt.h"
2001-11-13 17:56:06 +00:00
#include <readline/readline.h>
2000-03-17 21:46:59 +00:00
#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
2009-01-12 13:36:28 +00:00
/* Structure containing all the non-action (binary) options; filled in by
build_actions(). */
struct _optflags {
int pflag;
int rflag;
2011-11-21 20:51:19 -05:00
int Dflag;
2009-01-12 13:36:28 +00:00
int Eflag;
};
2001-11-13 17:56:06 +00:00
static int find_compact __P((char *));
static int find_compopt __P((char *));
2009-01-12 13:36:28 +00:00
static int build_actions __P((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *));
2001-11-13 17:56:06 +00:00
static int remove_cmd_completions __P((WORD_LIST *));
2000-03-17 21:46:59 +00:00
2002-07-17 14:10:11 +00:00
static int print_one_completion __P((char *, COMPSPEC *));
static int print_compitem __P((BUCKET_CONTENTS *));
2009-01-12 13:36:28 +00:00
static void print_compopts __P((const char *, COMPSPEC *, int));
2001-11-13 17:56:06 +00:00
static void print_all_completions __P((void));
static int print_cmd_completions __P((WORD_LIST *));
2000-03-17 21:46:59 +00:00
2002-07-17 14:10:11 +00:00
static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
2000-03-17 21:46:59 +00:00
2009-01-12 13:36:28 +00:00
static const struct _compacts {
const char * const actname;
2000-03-17 21:46:59 +00:00
int actflag;
int actopt;
} compacts[] = {
{ "alias", CA_ALIAS, 'a' },
{ "arrayvar", CA_ARRAYVAR, 0 },
{ "binding", CA_BINDING, 0 },
{ "builtin", CA_BUILTIN, 'b' },
{ "command", CA_COMMAND, 'c' },
{ "directory", CA_DIRECTORY, 'd' },
{ "disabled", CA_DISABLED, 0 },
{ "enabled", CA_ENABLED, 0 },
{ "export", CA_EXPORT, 'e' },
{ "file", CA_FILE, 'f' },
{ "function", CA_FUNCTION, 0 },
{ "helptopic", CA_HELPTOPIC, 0 },
2000-03-17 21:46:59 +00:00
{ "hostname", CA_HOSTNAME, 0 },
2001-11-13 17:56:06 +00:00
{ "group", CA_GROUP, 'g' },
2000-03-17 21:46:59 +00:00
{ "job", CA_JOB, 'j' },
{ "keyword", CA_KEYWORD, 'k' },
{ "running", CA_RUNNING, 0 },
2002-07-17 14:10:11 +00:00
{ "service", CA_SERVICE, 's' },
2000-03-17 21:46:59 +00:00
{ "setopt", CA_SETOPT, 0 },
{ "shopt", CA_SHOPT, 0 },
{ "signal", CA_SIGNAL, 0 },
{ "stopped", CA_STOPPED, 0 },
{ "user", CA_USER, 'u' },
{ "variable", CA_VARIABLE, 'v' },
{ (char *)NULL, 0, 0 },
};
2002-07-17 14:10:11 +00:00
/* This should be a STRING_INT_ALIST */
static const struct _compopt {
2009-01-12 13:36:28 +00:00
const char * const optname;
2001-04-06 19:14:31 +00:00
int optflag;
} compopts[] = {
2004-07-27 13:29:18 +00:00
{ "bashdefault", COPT_BASHDEFAULT },
2001-04-06 19:14:31 +00:00
{ "default", COPT_DEFAULT },
{ "dirnames", COPT_DIRNAMES },
{ "filenames",COPT_FILENAMES},
{ "noquote", COPT_NOQUOTE },
{ "nosort", COPT_NOSORT },
2002-07-17 14:10:11 +00:00
{ "nospace", COPT_NOSPACE },
2004-07-27 13:29:18 +00:00
{ "plusdirs", COPT_PLUSDIRS },
2001-04-06 19:14:31 +00:00
{ (char *)NULL, 0 },
};
2000-03-17 21:46:59 +00:00
static int
find_compact (name)
char *name;
{
register int i;
for (i = 0; compacts[i].actname; i++)
if (STREQ (name, compacts[i].actname))
return i;
return -1;
}
2001-04-06 19:14:31 +00:00
static int
find_compopt (name)
char *name;
{
register int i;
for (i = 0; compopts[i].optname; i++)
if (STREQ (name, compopts[i].optname))
return i;
return -1;
}
/* Build the actions and compspec options from the options specified in LIST.
ACTP is a pointer to an unsigned long in which to place the bitmap of
actions. OPTP is a pointer to an unsigned long in which to place the
bitmap of compspec options (arguments to `-o'). PP, if non-null, gets 1
2001-04-06 19:14:31 +00:00
if -p is supplied; RP, if non-null, gets 1 if -r is supplied.
If either is null, the corresponding option generates an error.
This also sets variables corresponding to options that take arguments as
a side effect; the caller should ensure that those variables are set to
NULL before calling build_actions. Return value:
2000-03-17 21:46:59 +00:00
EX_USAGE = bad option
EXECUTION_SUCCESS = some options supplied
EXECUTION_FAILURE = no options supplied
*/
static int
2009-01-12 13:36:28 +00:00
build_actions (list, flagp, actp, optp)
2000-03-17 21:46:59 +00:00
WORD_LIST *list;
2009-01-12 13:36:28 +00:00
struct _optflags *flagp;
2001-04-06 19:14:31 +00:00
unsigned long *actp, *optp;
2000-03-17 21:46:59 +00:00
{
2001-11-13 17:56:06 +00:00
int opt, ind, opt_given;
2001-04-06 19:14:31 +00:00
unsigned long acts, copts;
2000-03-17 21:46:59 +00:00
2001-04-06 19:14:31 +00:00
acts = copts = (unsigned long)0L;
2000-03-17 21:46:59 +00:00
opt_given = 0;
reset_internal_getopt ();
2011-11-21 20:51:19 -05:00
while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DE")) != -1)
2000-03-17 21:46:59 +00:00
{
opt_given = 1;
switch (opt)
{
case 'r':
2009-01-12 13:36:28 +00:00
if (flagp)
2000-03-17 21:46:59 +00:00
{
2009-01-12 13:36:28 +00:00
flagp->rflag = 1;
2000-03-17 21:46:59 +00:00
break;
}
else
{
2002-07-17 14:10:11 +00:00
sh_invalidopt ("-r");
2000-03-17 21:46:59 +00:00
builtin_usage ();
return (EX_USAGE);
}
case 'p':
2009-01-12 13:36:28 +00:00
if (flagp)
2000-03-17 21:46:59 +00:00
{
2009-01-12 13:36:28 +00:00
flagp->pflag = 1;
2000-03-17 21:46:59 +00:00
break;
}
else
{
2002-07-17 14:10:11 +00:00
sh_invalidopt ("-p");
2000-03-17 21:46:59 +00:00
builtin_usage ();
return (EX_USAGE);
}
case 'a':
acts |= CA_ALIAS;
break;
case 'b':
acts |= CA_BUILTIN;
break;
case 'c':
acts |= CA_COMMAND;
break;
case 'd':
acts |= CA_DIRECTORY;
break;
case 'e':
acts |= CA_EXPORT;
break;
case 'f':
acts |= CA_FILE;
break;
2001-11-13 17:56:06 +00:00
case 'g':
acts |= CA_GROUP;
break;
2000-03-17 21:46:59 +00:00
case 'j':
acts |= CA_JOB;
break;
case 'k':
acts |= CA_KEYWORD;
break;
2002-07-17 14:10:11 +00:00
case 's':
acts |= CA_SERVICE;
break;
2000-03-17 21:46:59 +00:00
case 'u':
acts |= CA_USER;
break;
case 'v':
acts |= CA_VARIABLE;
break;
2001-04-06 19:14:31 +00:00
case 'o':
ind = find_compopt (list_optarg);
if (ind < 0)
{
2002-07-17 14:10:11 +00:00
sh_invalidoptname (list_optarg);
2001-04-06 19:14:31 +00:00
return (EX_USAGE);
}
copts |= compopts[ind].optflag;
break;
2000-03-17 21:46:59 +00:00
case 'A':
ind = find_compact (list_optarg);
if (ind < 0)
{
2004-07-27 13:29:18 +00:00
builtin_error (_("%s: invalid action name"), list_optarg);
2000-03-17 21:46:59 +00:00
return (EX_USAGE);
}
acts |= compacts[ind].actflag;
break;
case 'C':
Carg = list_optarg;
break;
2011-11-21 20:51:19 -05:00
case 'D':
if (flagp)
{
flagp->Dflag = 1;
break;
}
else
{
sh_invalidopt ("-D");
builtin_usage ();
return (EX_USAGE);
}
2009-01-12 13:36:28 +00:00
case 'E':
if (flagp)
{
flagp->Eflag = 1;
break;
}
else
{
sh_invalidopt ("-E");
builtin_usage ();
return (EX_USAGE);
}
2000-03-17 21:46:59 +00:00
case 'F':
Farg = list_optarg;
break;
case 'G':
Garg = list_optarg;
break;
case 'P':
Parg = list_optarg;
break;
case 'S':
Sarg = list_optarg;
break;
case 'W':
Warg = list_optarg;
break;
case 'X':
Xarg = list_optarg;
break;
CASE_HELPOPT;
2000-03-17 21:46:59 +00:00
default:
builtin_usage ();
return (EX_USAGE);
}
}
*actp = acts;
2001-04-06 19:14:31 +00:00
*optp = copts;
2000-03-17 21:46:59 +00:00
return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
/* Add, remove, and display completion specifiers. */
int
complete_builtin (list)
WORD_LIST *list;
{
2009-01-12 13:36:28 +00:00
int opt_given, rval;
2001-04-06 19:14:31 +00:00
unsigned long acts, copts;
2000-03-17 21:46:59 +00:00
COMPSPEC *cs;
2009-01-12 13:36:28 +00:00
struct _optflags oflags;
WORD_LIST *l, *wl;
2000-03-17 21:46:59 +00:00
if (list == 0)
{
print_all_completions ();
return (EXECUTION_SUCCESS);
}
2011-11-21 20:51:19 -05:00
opt_given = oflags.pflag = oflags.rflag = oflags.Dflag = oflags.Eflag = 0;
2009-01-12 13:36:28 +00:00
2001-04-06 19:14:31 +00:00
acts = copts = (unsigned long)0L;
2002-07-17 14:10:11 +00:00
Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
2000-03-17 21:46:59 +00:00
cs = (COMPSPEC *)NULL;
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
as a side effect if they are supplied as options. */
2009-01-12 13:36:28 +00:00
rval = build_actions (list, &oflags, &acts, &copts);
2000-03-17 21:46:59 +00:00
if (rval == EX_USAGE)
return (rval);
opt_given = rval != EXECUTION_FAILURE;
list = loptend;
2011-11-21 20:51:19 -05:00
wl = oflags.Dflag ? make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL)
: (oflags.Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) : 0);
2009-01-12 13:36:28 +00:00
2000-03-17 21:46:59 +00:00
/* -p overrides everything else */
2009-01-12 13:36:28 +00:00
if (oflags.pflag || (list == 0 && opt_given == 0))
2000-03-17 21:46:59 +00:00
{
2009-01-12 13:36:28 +00:00
if (wl)
{
rval = print_cmd_completions (wl);
dispose_words (wl);
return rval;
}
else if (list == 0)
2000-03-17 21:46:59 +00:00
{
print_all_completions ();
return (EXECUTION_SUCCESS);
}
return (print_cmd_completions (list));
}
/* next, -r overrides everything else. */
2009-01-12 13:36:28 +00:00
if (oflags.rflag)
2000-03-17 21:46:59 +00:00
{
2009-01-12 13:36:28 +00:00
if (wl)
{
rval = remove_cmd_completions (wl);
dispose_words (wl);
return rval;
}
else if (list == 0)
2000-03-17 21:46:59 +00:00
{
2002-07-17 14:10:11 +00:00
progcomp_flush ();
2000-03-17 21:46:59 +00:00
return (EXECUTION_SUCCESS);
}
return (remove_cmd_completions (list));
}
2009-01-12 13:36:28 +00:00
if (wl == 0 && list == 0 && opt_given)
2000-03-17 21:46:59 +00:00
{
builtin_usage ();
return (EX_USAGE);
}
/* If we get here, we need to build a compspec and add it for each
remaining argument. */
2002-07-17 14:10:11 +00:00
cs = compspec_create ();
2000-03-17 21:46:59 +00:00
cs->actions = acts;
2001-04-06 19:14:31 +00:00
cs->options = copts;
2000-03-17 21:46:59 +00:00
cs->globpat = STRDUP (Garg);
cs->words = STRDUP (Warg);
cs->prefix = STRDUP (Parg);
cs->suffix = STRDUP (Sarg);
cs->funcname = STRDUP (Farg);
cs->command = STRDUP (Carg);
cs->filterpat = STRDUP (Xarg);
2009-01-12 13:36:28 +00:00
for (rval = EXECUTION_SUCCESS, l = wl ? wl : list ; l; l = l->next)
2000-03-17 21:46:59 +00:00
{
/* Add CS as the compspec for the specified commands. */
2009-01-12 13:36:28 +00:00
if (progcomp_insert (l->word->word, cs) == 0)
2001-04-06 19:14:31 +00:00
rval = EXECUTION_FAILURE;
2000-03-17 21:46:59 +00:00
}
2009-01-12 13:36:28 +00:00
dispose_words (wl);
2000-03-17 21:46:59 +00:00
return (rval);
}
static int
remove_cmd_completions (list)
WORD_LIST *list;
{
WORD_LIST *l;
int ret;
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
{
2002-07-17 14:10:11 +00:00
if (progcomp_remove (l->word->word) == 0)
2000-03-17 21:46:59 +00:00
{
2004-07-27 13:29:18 +00:00
builtin_error (_("%s: no completion specification"), l->word->word);
2000-03-17 21:46:59 +00:00
ret = EXECUTION_FAILURE;
}
}
return ret;
}
#define SQPRINTARG(a, f) \
do { \
if (a) \
{ \
2001-04-06 19:14:31 +00:00
x = sh_single_quote (a); \
2000-03-17 21:46:59 +00:00
printf ("%s %s ", f, x); \
free (x); \
} \
} while (0)
#define PRINTARG(a, f) \
do { \
if (a) \
printf ("%s %s ", f, a); \
} while (0)
#define PRINTOPT(a, f) \
do { \
if (acts & a) \
printf ("%s ", f); \
} while (0)
#define PRINTACT(a, f) \
do { \
if (acts & a) \
printf ("-A %s ", f); \
} while (0)
2001-04-06 19:14:31 +00:00
#define PRINTCOMPOPT(a, f) \
do { \
if (copts & a) \
printf ("-o %s ", f); \
} while (0)
2009-01-12 13:36:28 +00:00
#define XPRINTCOMPOPT(a, f) \
do { \
if (copts & a) \
printf ("-o %s ", f); \
else \
printf ("+o %s ", f); \
} while (0)
2002-07-17 14:10:11 +00:00
static int
2000-03-17 21:46:59 +00:00
print_one_completion (cmd, cs)
char *cmd;
COMPSPEC *cs;
{
2001-04-06 19:14:31 +00:00
unsigned long acts, copts;
2000-03-17 21:46:59 +00:00
char *x;
printf ("complete ");
2001-04-06 19:14:31 +00:00
copts = cs->options;
/* First, print the -o options. */
2004-07-27 13:29:18 +00:00
PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
2001-04-06 19:14:31 +00:00
PRINTCOMPOPT (COPT_DEFAULT, "default");
PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
PRINTCOMPOPT (COPT_FILENAMES, "filenames");
2002-07-17 14:10:11 +00:00
PRINTCOMPOPT (COPT_NOSPACE, "nospace");
2004-07-27 13:29:18 +00:00
PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
2001-04-06 19:14:31 +00:00
2000-03-17 21:46:59 +00:00
acts = cs->actions;
2001-04-06 19:14:31 +00:00
/* simple flags next */
2000-03-17 21:46:59 +00:00
PRINTOPT (CA_ALIAS, "-a");
PRINTOPT (CA_BUILTIN, "-b");
PRINTOPT (CA_COMMAND, "-c");
PRINTOPT (CA_DIRECTORY, "-d");
PRINTOPT (CA_EXPORT, "-e");
PRINTOPT (CA_FILE, "-f");
2001-11-13 17:56:06 +00:00
PRINTOPT (CA_GROUP, "-g");
2000-03-17 21:46:59 +00:00
PRINTOPT (CA_JOB, "-j");
2002-07-17 14:10:11 +00:00
PRINTOPT (CA_KEYWORD, "-k");
PRINTOPT (CA_SERVICE, "-s");
2000-03-17 21:46:59 +00:00
PRINTOPT (CA_USER, "-u");
PRINTOPT (CA_VARIABLE, "-v");
/* now the rest of the actions */
PRINTACT (CA_ARRAYVAR, "arrayvar");
PRINTACT (CA_BINDING, "binding");
PRINTACT (CA_DISABLED, "disabled");
PRINTACT (CA_ENABLED, "enabled");
PRINTACT (CA_FUNCTION, "function");
PRINTACT (CA_HELPTOPIC, "helptopic");
PRINTACT (CA_HOSTNAME, "hostname");
PRINTACT (CA_RUNNING, "running");
PRINTACT (CA_SETOPT, "setopt");
PRINTACT (CA_SHOPT, "shopt");
PRINTACT (CA_SIGNAL, "signal");
PRINTACT (CA_STOPPED, "stopped");
/* now the rest of the arguments */
/* arguments that require quoting */
SQPRINTARG (cs->globpat, "-G");
SQPRINTARG (cs->words, "-W");
SQPRINTARG (cs->prefix, "-P");
SQPRINTARG (cs->suffix, "-S");
SQPRINTARG (cs->filterpat, "-X");
2009-01-12 13:36:28 +00:00
SQPRINTARG (cs->command, "-C");
2000-03-17 21:46:59 +00:00
/* simple arguments that don't require quoting */
PRINTARG (cs->funcname, "-F");
2011-11-21 20:51:19 -05:00
if (STREQ (cmd, EMPTYCMD))
printf ("-E\n");
else if (STREQ (cmd, DEFAULTCMD))
printf ("-D\n");
else
printf ("%s\n", cmd);
2002-07-17 14:10:11 +00:00
return (0);
}
2009-01-12 13:36:28 +00:00
static void
print_compopts (cmd, cs, full)
const char *cmd;
COMPSPEC *cs;
int full;
{
int copts;
printf ("compopt ");
copts = cs->options;
if (full)
{
XPRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
XPRINTCOMPOPT (COPT_DEFAULT, "default");
XPRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
XPRINTCOMPOPT (COPT_FILENAMES, "filenames");
XPRINTCOMPOPT (COPT_NOSPACE, "nospace");
XPRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
}
else
{
PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
PRINTCOMPOPT (COPT_DEFAULT, "default");
PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
PRINTCOMPOPT (COPT_FILENAMES, "filenames");
PRINTCOMPOPT (COPT_NOSPACE, "nospace");
PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
}
2011-11-21 20:51:19 -05:00
if (STREQ (cmd, EMPTYCMD))
printf ("-E\n");
else if (STREQ (cmd, DEFAULTCMD))
printf ("-D\n");
else
printf ("%s\n", cmd);
2009-01-12 13:36:28 +00:00
}
2002-07-17 14:10:11 +00:00
static int
print_compitem (item)
BUCKET_CONTENTS *item;
{
COMPSPEC *cs;
char *cmd;
cmd = item->key;
cs = (COMPSPEC *)item->data;
return (print_one_completion (cmd, cs));
2000-03-17 21:46:59 +00:00
}
static void
print_all_completions ()
{
2002-07-17 14:10:11 +00:00
progcomp_walk (print_compitem);
2000-03-17 21:46:59 +00:00
}
static int
print_cmd_completions (list)
WORD_LIST *list;
{
WORD_LIST *l;
COMPSPEC *cs;
int ret;
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
{
2002-07-17 14:10:11 +00:00
cs = progcomp_search (l->word->word);
2000-03-17 21:46:59 +00:00
if (cs)
2001-04-06 19:14:31 +00:00
print_one_completion (l->word->word, cs);
2000-03-17 21:46:59 +00:00
else
{
2004-07-27 13:29:18 +00:00
builtin_error (_("%s: no completion specification"), l->word->word);
2000-03-17 21:46:59 +00:00
ret = EXECUTION_FAILURE;
}
}
2009-01-12 13:36:28 +00:00
return (sh_chkwrite (ret));
2000-03-17 21:46:59 +00:00
}
$BUILTIN compgen
$DEPENDS_ON PROGRAMMABLE_COMPLETION
$FUNCTION compgen_builtin
$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
2009-01-12 13:36:28 +00:00
Display possible completions depending on the options.
Intended to be used from within a shell function generating possible
completions. If the optional WORD argument is supplied, matches against
WORD are generated.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
2000-03-17 21:46:59 +00:00
$END
int
compgen_builtin (list)
WORD_LIST *list;
{
int rval;
2001-04-06 19:14:31 +00:00
unsigned long acts, copts;
2000-03-17 21:46:59 +00:00
COMPSPEC *cs;
STRINGLIST *sl;
2004-07-27 13:29:18 +00:00
char *word, **matches;
2000-03-17 21:46:59 +00:00
if (list == 0)
return (EXECUTION_SUCCESS);
2001-04-06 19:14:31 +00:00
acts = copts = (unsigned long)0L;
2002-07-17 14:10:11 +00:00
Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
2000-03-17 21:46:59 +00:00
cs = (COMPSPEC *)NULL;
/* Build the actions from the arguments. Also sets the [A-Z]arg variables
as a side effect if they are supplied as options. */
2009-01-12 13:36:28 +00:00
rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts);
2000-03-17 21:46:59 +00:00
if (rval == EX_USAGE)
return (rval);
if (rval == EXECUTION_FAILURE)
return (EXECUTION_SUCCESS);
list = loptend;
word = (list && list->word) ? list->word->word : "";
if (Farg)
2004-07-27 13:29:18 +00:00
builtin_error (_("warning: -F option may not work as you expect"));
2000-03-17 21:46:59 +00:00
if (Carg)
2004-07-27 13:29:18 +00:00
builtin_error (_("warning: -C option may not work as you expect"));
2000-03-17 21:46:59 +00:00
/* If we get here, we need to build a compspec and evaluate it. */
2002-07-17 14:10:11 +00:00
cs = compspec_create ();
2000-03-17 21:46:59 +00:00
cs->actions = acts;
2001-04-06 19:14:31 +00:00
cs->options = copts;
2000-03-17 21:46:59 +00:00
cs->refcount = 1;
cs->globpat = STRDUP (Garg);
cs->words = STRDUP (Warg);
cs->prefix = STRDUP (Parg);
cs->suffix = STRDUP (Sarg);
cs->funcname = STRDUP (Farg);
cs->command = STRDUP (Carg);
cs->filterpat = STRDUP (Xarg);
rval = EXECUTION_FAILURE;
2011-11-21 20:51:19 -05:00
sl = gen_compspec_completions (cs, "compgen", word, 0, 0, 0);
2001-11-13 17:56:06 +00:00
2004-07-27 13:29:18 +00:00
/* If the compspec wants the bash default completions, temporarily
turn off programmable completion and call the bash completion code. */
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_BASHDEFAULT))
{
matches = bash_default_completion (word, 0, 0, 0, 0);
sl = completions_to_stringlist (matches);
strvec_dispose (matches);
}
2001-11-13 17:56:06 +00:00
/* This isn't perfect, but it's the best we can do, given what readline
exports from its set of completion utility functions. */
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT))
{
matches = rl_completion_matches (word, rl_filename_completion_function);
strlist_dispose (sl);
2001-11-13 17:56:06 +00:00
sl = completions_to_stringlist (matches);
2002-07-17 14:10:11 +00:00
strvec_dispose (matches);
2001-11-13 17:56:06 +00:00
}
2000-03-17 21:46:59 +00:00
if (sl)
{
2001-11-13 17:56:06 +00:00
if (sl->list && sl->list_len)
2000-03-17 21:46:59 +00:00
{
rval = EXECUTION_SUCCESS;
2002-07-17 14:10:11 +00:00
strlist_print (sl, (char *)NULL);
2000-03-17 21:46:59 +00:00
}
2002-07-17 14:10:11 +00:00
strlist_dispose (sl);
2000-03-17 21:46:59 +00:00
}
2002-07-17 14:10:11 +00:00
compspec_dispose (cs);
2000-03-17 21:46:59 +00:00
return (rval);
}
2009-01-12 13:36:28 +00:00
$BUILTIN compopt
$DEPENDS_ON PROGRAMMABLE_COMPLETION
$FUNCTION compopt_builtin
2011-11-21 20:51:19 -05:00
$SHORT_DOC compopt [-o|+o option] [-DE] [name ...]
2009-01-12 13:36:28 +00:00
Modify or display completion options.
Modify the completion options for each NAME, or, if no NAMEs are supplied,
the completion currently being executed. If no OPTIONs are given, print
2009-01-12 13:36:28 +00:00
the completion options for each NAME or the current completion specification.
Options:
-o option Set completion option OPTION for each NAME
2011-11-21 20:51:19 -05:00
-D Change options for the "default" command completion
-E Change options for the "empty" command completion
2009-01-12 13:36:28 +00:00
Using `+o' instead of `-o' turns off the specified option.
Arguments:
Each NAME refers to a command for which a completion specification must
have previously been defined using the `complete' builtin. If no NAMEs
are supplied, compopt must be called by a function currently generating
completions, and the options for that currently-executing completion
generator are modified.
Exit Status:
Returns success unless an invalid option is supplied or NAME does not
have a completion specification defined.
$END
int
compopt_builtin (list)
WORD_LIST *list;
{
2011-11-21 20:51:19 -05:00
int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag;
WORD_LIST *l, *wl;
2009-01-12 13:36:28 +00:00
COMPSPEC *cs;
2011-11-21 20:51:19 -05:00
opts_on = opts_off = Eflag = Dflag = 0;
2009-01-12 13:36:28 +00:00
ret = EXECUTION_SUCCESS;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "+o:DE")) != -1)
2009-01-12 13:36:28 +00:00
{
opts = (list_opttype == '-') ? &opts_on : &opts_off;
switch (opt)
{
case 'o':
oind = find_compopt (list_optarg);
if (oind < 0)
{
sh_invalidoptname (list_optarg);
return (EX_USAGE);
}
*opts |= compopts[oind].optflag;
break;
2011-11-21 20:51:19 -05:00
case 'D':
Dflag = 1;
break;
case 'E':
Eflag = 1;
break;
CASE_HELPOPT;
2009-01-12 13:36:28 +00:00
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
2011-11-21 20:51:19 -05:00
wl = Dflag ? make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL)
: (Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) : 0);
if (list == 0 && wl == 0)
2009-01-12 13:36:28 +00:00
{
if (RL_ISSTATE (RL_STATE_COMPLETING) == 0 || pcomp_curcs == 0)
{
builtin_error (_("not currently executing completion function"));
return (EXECUTION_FAILURE);
}
cs = pcomp_curcs;
if (opts_on == 0 && opts_off == 0)
{
print_compopts (pcomp_curcmd, cs, 1);
return (sh_chkwrite (ret));
}
/* Set the compspec options */
pcomp_set_compspec_options (cs, opts_on, 1);
pcomp_set_compspec_options (cs, opts_off, 0);
/* And change the readline variables the options control */
pcomp_set_readline_variables (opts_on, 1);
pcomp_set_readline_variables (opts_off, 0);
return (ret);
}
2011-11-21 20:51:19 -05:00
for (l = wl ? wl : list; l; l = l->next)
2009-01-12 13:36:28 +00:00
{
cs = progcomp_search (l->word->word);
if (cs == 0)
{
builtin_error (_("%s: no completion specification"), l->word->word);
ret = EXECUTION_FAILURE;
continue;
}
if (opts_on == 0 && opts_off == 0)
{
print_compopts (l->word->word, cs, 1);
continue; /* XXX -- fill in later */
}
/* Set the compspec options */
pcomp_set_compspec_options (cs, opts_on, 1);
pcomp_set_compspec_options (cs, opts_off, 0);
}
if (wl)
dispose_words (wl);
2009-01-12 13:36:28 +00:00
return (ret);
}