From e0f6495d155e9f7ee291c28d40273aa503f564cd Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 25 May 2018 18:29:27 +0100 Subject: [PATCH] Add -U option to compopt and complete for custom cmd completion User-supplied programmable completion with the -U option can be used to customise command completion. --- bashline.c | 11 +++++++++-- builtins/complete.def | 45 +++++++++++++++++++++++++++++++++---------- doc/bash.1 | 10 +++++++--- doc/bash.html | 8 ++++++-- doc/bash.info | 17 +++++++++++----- doc/bashref.html | 15 +++++++++++---- doc/bashref.info | 17 +++++++++++----- pcomplete.h | 1 + 8 files changed, 93 insertions(+), 31 deletions(-) diff --git a/bashline.c b/bashline.c index b4647951..27586366 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 *uc; 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) + uc = progcomp_search(USERCMD); +#endif /* PROGRAMMABLE_COMPLETION */ if (in_command_position && invalid_completion (text, ti)) { @@ -1510,7 +1514,7 @@ attempt_shell_completion (text, start, end) #if defined (PROGRAMMABLE_COMPLETION) /* Attempt programmable completion. */ have_progcomps = prog_completion_enabled && (progcomp_size () > 0); - if (matches == 0 && (in_command_position == 0 || text[0] == '\0') && + if (matches == 0 && (in_command_position == 0 || text[0] == '\0' || uc) && current_prompt_string == ps1_prompt) { int s, e, s1, e1, os, foundcs; @@ -1559,7 +1563,10 @@ attempt_shell_completion (text, start, end) end == index of where word to be completed ends if (s == start) we are doing command word completion for sure if (e1 == end) we are at the end of the command name and completing it */ - if (start == 0 && end == 0 && e != 0 && text[0] == '\0') /* beginning of non-empty line */ + /* If the user has defined a custom command substitution, try that first.*/ + if (uc && in_command_position == 1) + prog_complete_matches = programmable_completions (USERCMD, text, s, e, &foundcs); + else if (start == 0 && end == 0 && e != 0 && text[0] == '\0') /* beginning of non-empty line */ foundcs = 0; else if (start == end && start == s1 && e != 0 && e1 > end) /* beginning of command name, leading whitespace */ foundcs = 0; 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/doc/bash.1 b/doc/bash.1 index 7909a4d1..00c5059f 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -7647,12 +7647,12 @@ will be displayed. The return value is true unless an invalid option is supplied, or no matches were generated. .TP -\fBcomplete\fP [\fB\-abcdefgjksuv\fP] [\fB\-o\fP \fIcomp-option\fP] [\fB\-DE\fP] [\fB\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP] +\fBcomplete\fP [\fB\-abcdefgjksuv\fP] [\fB\-o\fP \fIcomp-option\fP] [\fB\-DEU\fP] [\fB\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP] .br [\fB\-X\fP \fIfilterpat\fP] [\fB\-P\fP \fIprefix\fP] [\fB\-S\fP \fIsuffix\fP] \fIname\fP [\fIname ...\fP] .PD 0 .TP -\fBcomplete\fP \fB\-pr\fP [\fB\-DE\fP] [\fIname\fP ...] +\fBcomplete\fP \fB\-pr\fP [\fB\-DEU\fP] [\fIname\fP ...] .PD Specify how arguments to each \fIname\fP should be completed. If the \fB\-p\fP option is supplied, or if no options are supplied, @@ -7667,6 +7667,8 @@ on a command for which no completion has previously been defined. The \fB\-E\fP option indicates that the remaining options and actions should apply to ``empty'' command completion; that is, completion attempted on a blank line. +The \fB\-U\fP option indicates that the remaining options should apply to +command name completion; that is, completion is attempted on the first word. .sp 1 The process of applying these completion specifications when word completion is attempted is described above under \fBProgrammable Completion\fP. @@ -7862,7 +7864,7 @@ a \fIname\fP for which no specification exists, or an error occurs adding a completion specification. .RE .TP -\fBcompopt\fP [\fB\-o\fP \fIoption\fP] [\fB\-DE\fP] [\fB+o\fP \fIoption\fP] [\fIname\fP] +\fBcompopt\fP [\fB\-o\fP \fIoption\fP] [\fB\-DEU\fP] [\fB+o\fP \fIoption\fP] [\fIname\fP] Modify completion options for each \fIname\fP according to the \fIoption\fPs, or for the currently-executing completion if no \fIname\fPs are supplied. @@ -7876,6 +7878,8 @@ on a command for which no completion has previously been defined. The \fB\-E\fP option indicates that the remaining options should apply to ``empty'' command completion; that is, completion attempted on a blank line. +The \fB\-U\fP option indicates that the remaining options should apply to +command name completion; that is, completion is attempted on the first word. .sp 1 The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a \fIname\fP for which no completion diff --git a/doc/bash.html b/doc/bash.html index 54b42fec..c98a1de1 100644 --- a/doc/bash.html +++ b/doc/bash.html @@ -9745,7 +9745,7 @@ will be displayed.

The return value is true unless an invalid option is supplied, or no matches were generated. -

complete [-abcdefgjksuv] [-o comp-option] [-DE] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command]
+
complete [-abcdefgjksuv] [-o comp-option] [-DEU] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command]

[-X filterpat] [-P prefix] [-S suffix] name [name ...] @@ -9765,6 +9765,8 @@ on a command for which no completion has previously been defined. The -E option indicates that the remaining options and actions should apply to ``empty'' command completion; that is, completion attempted on a blank line. +The -U option indicates that the remaining options should apply to +command name completion; that is, completion is attempted on the first word.

The process of applying these completion specifications when word completion is attempted is described above under Programmable Completion. @@ -9995,7 +9997,7 @@ a name for which no specification exists, or an error occurs adding a completion specification. -

compopt [-o option] [-DE] [+o option] [name]
+
compopt [-o option] [-DEU] [+o option] [name]
Modify completion options for each name according to the options, or for the currently-executing completion if no names are supplied. @@ -10009,6 +10011,8 @@ on a command for which no completion has previously been defined. The -E option indicates that the remaining options should apply to ``empty'' command completion; that is, completion attempted on a blank line. +The -U option indicates that the remaining options should apply to +command name completion; that is, completion is attempted on the first word.

The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a name for which no completion diff --git a/doc/bash.info b/doc/bash.info index 9a4edb08..10c71ccc 100644 --- a/doc/bash.info +++ b/doc/bash.info @@ -8737,7 +8737,7 @@ happening. no matches were generated. 'complete' - complete [-abcdefgjksuv] [-o COMP-OPTION] [-DE] [-A ACTION] [-G GLOBPAT] [-W WORDLIST] + complete [-abcdefgjksuv] [-o COMP-OPTION] [-DEU] [-A ACTION] [-G GLOBPAT] [-W WORDLIST] [-F FUNCTION] [-C COMMAND] [-X FILTERPAT] [-P PREFIX] [-S SUFFIX] NAME [NAME ...] complete -pr [-DE] [NAME ...] @@ -8753,10 +8753,14 @@ happening. completion has previously been defined. The '-E' option indicates that the remaining options and actions should apply to "empty" command completion; that is, completion attempted on a blank line. + The '-U' option indicates that the remaining options should apply + to command name completion; that is, completion is attempted on the + first word. The process of applying these completion specifications when word completion is attempted is described above (*note Programmable - Completion::). The '-D' option takes precedence over '-E'. + Completion::). The '-D' option takes precedence over '-E' which + takes precedence over '-U'. Other options, if specified, have the following meanings. The arguments to the '-G', '-W', and '-X' options (and, if necessary, @@ -8936,7 +8940,7 @@ happening. completion specification. 'compopt' - compopt [-o OPTION] [-DE] [+o OPTION] [NAME] + compopt [-o OPTION] [-DEU] [+o OPTION] [NAME] Modify completion options for each NAME according to the OPTIONs, or for the currently-executing completion if no NAMEs are supplied. If no OPTIONs are given, display the completion options for each @@ -8947,9 +8951,12 @@ happening. command for which no completion has previously been defined. The '-E' option indicates that the remaining options should apply to "empty" command completion; that is, completion attempted on a - blank line. + blank line. The '-U' option indicates that the remaining options + should apply to command name completion; that is, completion is + attempted on the first word. - The '-D' option takes precedence over '-E'. + The '-D' option takes precedence over '-E' which takes precedence + over '-U'. The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a NAME for which no diff --git a/doc/bashref.html b/doc/bashref.html index f494f344..8fd41e95 100644 --- a/doc/bashref.html +++ b/doc/bashref.html @@ -11973,7 +11973,7 @@ matches were generated.

complete
-
complete [-abcdefgjksuv] [-o comp-option] [-DE] [-A action] [-G globpat] [-W wordlist]
+
complete [-abcdefgjksuv] [-o comp-option] [-DEU] [-A action] [-G globpat] [-W wordlist]
 [-F function] [-C command] [-X filterpat]
 [-P prefix] [-S suffix] name [name …]
 complete -pr [-DE] [name …]
@@ -11992,10 +11992,14 @@ on a command for which no completion has previously been defined.
 The -E option indicates that the remaining options and actions should
 apply to “empty” command completion; that is, completion attempted on a 
 blank line.
+The -U option indicates that the remaining options should
+apply to command name completion; that is, completion is attempted on the first word.
+

The process of applying these completion specifications when word completion is attempted is described above (see Programmable Completion). The --D option takes precedence over -E. +-D option takes precedence over -E which takes precedence +over '-U'.

Other options, if specified, have the following meanings. The arguments to the -G, -W, and -X options @@ -12221,7 +12225,7 @@ an error occurs adding a completion specification.

compopt
-
compopt [-o option] [-DE] [+o option] [name]
+
compopt [-o option] [-DEU] [+o option] [name]
 

Modify completion options for each name according to the options, or for the currently-executing completion if no names @@ -12236,8 +12240,11 @@ on a command for which no completion has previously been defined. The -E option indicates that the remaining options should apply to “empty” command completion; that is, completion attempted on a blank line. +The -U option indicates that the remaining options should +apply to command name completion; that is, completion is attempted on the first word.

-

The -D option takes precedence over -E. +

The -D option takes precedence over -E which takes +precedence over '-U'.

The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a name for which no completion diff --git a/doc/bashref.info b/doc/bashref.info index 29dd0eff..395a60ec 100644 --- a/doc/bashref.info +++ b/doc/bashref.info @@ -8740,7 +8740,7 @@ happening. complete [-abcdefgjksuv] [-o COMP-OPTION] [-DE] [-A ACTION] [-G GLOBPAT] [-W WORDLIST] [-F FUNCTION] [-C COMMAND] [-X FILTERPAT] [-P PREFIX] [-S SUFFIX] NAME [NAME ...] - complete -pr [-DE] [NAME ...] + complete -pr [-DEU] [NAME ...] Specify how arguments to each NAME should be completed. If the '-p' option is supplied, or if no options are supplied, existing @@ -8753,10 +8753,14 @@ happening. completion has previously been defined. The '-E' option indicates that the remaining options and actions should apply to "empty" command completion; that is, completion attempted on a blank line. + The '-U' option indicates that the remaining options and actions + should apply to command name completion; that is, completion is + attempted on the first word. The process of applying these completion specifications when word completion is attempted is described above (*note Programmable - Completion::). The '-D' option takes precedence over '-E'. + Completion::). The '-D' option takes precedence over '-E' which + takes precedence over '-U'. Other options, if specified, have the following meanings. The arguments to the '-G', '-W', and '-X' options (and, if necessary, @@ -8936,7 +8940,7 @@ happening. completion specification. 'compopt' - compopt [-o OPTION] [-DE] [+o OPTION] [NAME] + compopt [-o OPTION] [-DEU] [+o OPTION] [NAME] Modify completion options for each NAME according to the OPTIONs, or for the currently-executing completion if no NAMEs are supplied. If no OPTIONs are given, display the completion options for each @@ -8947,9 +8951,12 @@ happening. command for which no completion has previously been defined. The '-E' option indicates that the remaining options should apply to "empty" command completion; that is, completion attempted on a - blank line. + blank line. The '-U' option indicates that the remaining options + should apply to command name completion; that is, completion is + attempted on the first word. - The '-D' option takes precedence over '-E'. + The '-D' option takes precedence over '-E' which takes precedence + over '-U'. The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a NAME for which no diff --git a/pcomplete.h b/pcomplete.h index 2ae8224e..61e8545c 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.17.0