Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > gnu.bash.bug > #14144

Re: [PATCH] Add nofirstword completion option

From Luca Boccassi <bluca@debian.org>
Newsgroups gnu.bash.bug
Subject Re: [PATCH] Add nofirstword completion option
Date 2018-05-25 18:42 +0100
Message-ID <mailman.488.1527270180.1292.bug-bash@gnu.org> (permalink)
References (1 earlier) <96bcb197-40d1-aac8-c214-c513a6db805d@case.edu> <1527068652.6997.5.camel@debian.org> <76b1d3fa-4cb1-3e70-d93c-ada07c04dfa2@case.edu> <1527082457.6997.14.camel@debian.org> <4ccfc554-15a9-2ec1-55e1-b2df687f0bee@case.edu>

Show all headers | View raw


[Multipart message — attachments visible in raw view] - view raw

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

Back to gnu.bash.bug | Previous | Next | Find similar | Unroll thread


Thread

Re: [PATCH] Add nofirstword completion option Luca Boccassi <bluca@debian.org> - 2018-05-25 18:42 +0100

csiph-web