On Wed, 2018-05-23 at 09:53 -0400, Chet Ramey wrote: > On 5/23/18 9:34 AM, Luca Boccassi wrote: > > On Wed, 2018-05-23 at 09:15 -0400, Chet Ramey wrote: > > > On 5/23/18 5:44 AM, Luca Boccassi wrote: > > > > > > > So by that, do you mean that it's possible to stop > > > > autocompleting > > > > to > > > > files/dirs/binaries just using a programmable completion > > > > script? Or > > > > did > > > > I misunderstand? Apologies if that's the case. > > > > > > > > Right now we do have completion scripts to implement the help > > > > text > > > > for > > > > the commands (and for the empty set, which displays a general > > > > help > > > > with > > > > a summary), what's missing is stopping files/dirs/binaries > > > > completion > > > > for the first word, so that exclusively the commands are shown. > > > > > > Exactly. What you want, I gather, is a way to restrict > > > completions on > > > the > > > command word to the small set of router commands valid in > > > whichever > > > mode > > > the console happens to be. Programmable completion provides a > > > mechanism to > > > do that, but there is a missing piece of functionality that would > > > allow it > > > to work on the command word. That's the change I would prefer to > > > see. > > > > > > Chet > > > > Ah I see - I am more than happy to work on that instead, but > > (forgive > > my n00bness, first time hacking on Bash) could you please describe > > in a > > couple of lines what the missing piece is and what it should look > > like? > > There is already logic that determines whether the shell is trying to > complete a command word (in_command_position). The existing code does > not attempt programmable completion if in_command_position == 1. The > additional functionality would: > > 1. Add an option to the complete builtin to specify how to complete > command names, and store it in a specially-named compspec, like > completion for empty lines does. > > 2. Add code to invoke that completion, if it exists and programmable > completion is active, before attempting bash's default completion, > if in_command_position == 1. > > Chet
Hi, Thanks for the guidance! Unfortunately I'm still not quite there yet - inlined are the changes based on my understanding of the above. It implements a "usercmd/-U" option similar to the existing -E for empty line. But at the moment all it does is to allow (via "complete -U -F foo") to complete when nothing is typed in, which seemed to be possible already with -E. If some characters are already typed in, it will still do the default completion to commands in the PATH. What have I missed? Thank you for the help! -- Kind regards, Luca Boccassi diff --git a/bashline.c b/bashline.c index ae8fe1cc..9dfe3283 100644 --- a/bashline.c +++ b/bashline.c @@ -1425,6 +1425,7 @@ attempt_shell_completion (text, start, end) int in_command_position, ti, qc, dflags; char **matches, *command_separator_chars; #if defined (PROGRAMMABLE_COMPLETION) + COMPSPEC *cs; int have_progcomps, was_assignment; #endif @@ -1484,6 +1485,9 @@ attempt_shell_completion (text, start, end) that all of the previous words on the line are variable assignments. */ } +#if defined (PROGRAMMABLE_COMPLETION) + cs = progcomp_search(USERCMD); +#endif /* PROGRAMMABLE_COMPLETION */ if (in_command_position && invalid_completion (text, ti)) { @@ -1599,6 +1603,8 @@ attempt_shell_completion (text, start, end) } else foundcs = 0; + if (cs && in_command_position == 1) + prog_complete_matches = programmable_completions (USERCMD, text, s, e, &foundcs); FREE (n); /* XXX - if we found a COMPSPEC for the command, just return whatever the programmable completion code returns, and disable the default diff --git a/builtins/complete.def b/builtins/complete.def index 3ca8c1fa..60f7b17a 100644 --- a/builtins/complete.def +++ b/builtins/complete.def @@ -23,7 +23,7 @@ $PRODUCES complete.c $BUILTIN complete $DEPENDS_ON PROGRAMMABLE_COMPLETION $FUNCTION complete_builtin -$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 ...] +$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DEU] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...] Specify how arguments are to be completed by Readline. For each NAME, specify how arguments are to be completed. If no options @@ -38,10 +38,12 @@ Options: without any specific completion defined -E apply the completions and actions to "empty" commands -- completion attempted on a blank line + -U apply the completions and actions to "user" commands -- + completion attempted on a command name When completion is attempted, the actions are applied in the order the uppercase-letter options are listed above. The -D option takes -precedence over -E. +precedence over -E which takes precedence over -U. Exit Status: Returns success unless an invalid option is supplied or an error occurs. @@ -79,6 +81,7 @@ struct _optflags { int rflag; int Dflag; int Eflag; + int Uflag; }; static int find_compact __P((char *)); @@ -195,7 +198,7 @@ build_actions (list, flagp, actp, optp) opt_given = 0; reset_internal_getopt (); - while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DE")) != -1) + while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DEU")) != -1) { opt_given = 1; switch (opt) @@ -319,6 +322,18 @@ build_actions (list, flagp, actp, optp) case 'S': Sarg = list_optarg; break; + case 'U': + if (flagp) + { + flagp->Uflag = 1; + break; + } + else + { + sh_invalidopt ("-U"); + builtin_usage (); + return (EX_USAGE); + } case 'W': Warg = list_optarg; break; @@ -355,7 +370,7 @@ complete_builtin (list) return (EXECUTION_SUCCESS); } - opt_given = oflags.pflag = oflags.rflag = oflags.Dflag = oflags.Eflag = 0; + opt_given = oflags.pflag = oflags.rflag = oflags.Dflag = oflags.Eflag = oflags.Uflag = 0; acts = copts = (unsigned long)0L; Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL; @@ -371,7 +386,8 @@ complete_builtin (list) list = loptend; 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); + : (oflags.Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) + : (oflags.Uflag ? make_word_list (make_bare_word (USERCMD), (WORD_LIST *)NULL) : 0)); /* -p overrides everything else */ if (oflags.pflag || (list == 0 && opt_given == 0)) @@ -568,6 +584,8 @@ print_one_completion (cmd, cs) printf ("-E\n"); else if (STREQ (cmd, DEFAULTCMD)) printf ("-D\n"); + else if (STREQ (cmd, USERCMD)) + printf ("-U\n"); else printf ("%s\n", cmd); @@ -612,6 +630,8 @@ print_compopts (cmd, cs, full) printf ("-E\n"); else if (STREQ (cmd, DEFAULTCMD)) printf ("-D\n"); + else if (STREQ (cmd, USERCMD)) + printf ("-U\n"); else printf ("%s\n", cmd); } @@ -769,7 +789,7 @@ compgen_builtin (list) $BUILTIN compopt $DEPENDS_ON PROGRAMMABLE_COMPLETION $FUNCTION compopt_builtin -$SHORT_DOC compopt [-o|+o option] [-DE] [name ...] +$SHORT_DOC compopt [-o|+o option] [-DEU] [name ...] Modify or display completion options. Modify the completion options for each NAME, or, if no NAMEs are supplied, @@ -780,6 +800,7 @@ Options: -o option Set completion option OPTION for each NAME -D Change options for the "default" command completion -E Change options for the "empty" command completion + -U Change options for the "user" command completion Using `+o' instead of `-o' turns off the specified option. @@ -800,15 +821,15 @@ int compopt_builtin (list) WORD_LIST *list; { - int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag; + int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag, Uflag; WORD_LIST *l, *wl; COMPSPEC *cs; - opts_on = opts_off = Eflag = Dflag = 0; + opts_on = opts_off = Eflag = Dflag = Uflag = 0; ret = EXECUTION_SUCCESS; reset_internal_getopt (); - while ((opt = internal_getopt (list, "+o:DE")) != -1) + while ((opt = internal_getopt (list, "+o:DEU")) != -1) { opts = (list_opttype == '-') ? &opts_on : &opts_off; @@ -829,6 +850,9 @@ compopt_builtin (list) case 'E': Eflag = 1; break; + case 'U': + Uflag = 1; + break; CASE_HELPOPT; default: builtin_usage (); @@ -838,7 +862,8 @@ compopt_builtin (list) list = loptend; wl = Dflag ? make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL) - : (Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) : 0); + : (Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) + : (Uflag ? make_word_list (make_bare_word (USERCMD), (WORD_LIST *)NULL) : 0)); if (list == 0 && wl == 0) { diff --git a/pcomplete.h b/pcomplete.h index 2ae8224e..005b38e8 100644 --- a/pcomplete.h +++ b/pcomplete.h @@ -107,6 +107,7 @@ typedef struct _list_of_items { #define EMPTYCMD "_EmptycmD_" #define DEFAULTCMD "_DefaultCmD_" +#define USERCMD "_UserCmD_" extern HASH_TABLE *prog_completes; -- 2.14.2
signature.asc
Description: This is a digitally signed message part