Re: ksh(1): custom completion for command containing hyphens

2017-06-12 Thread Klemens Nanni

On Fri, Jun 02, 2017 at 05:07:42PM +0200, Anton Lindqvist wrote:

Custom completions in ksh is currently limited to commands that does not
contain hyphens since such a character cannot be part of an identifier.
We could cheat and replace hyphens with underscores upon performing
completions.
The motivation behind this is that I want to add completions for
ssh-add(1). With the attached diff, I can achieve the following:

 $ set -A complete_ssh_add -- $(find ~/.ssh -name '*_rsa')

Comments? OK?

While this works and we (obviously) don't have any binaries in base that
would run into this problem, keep in mind that this workaround munges
the real names: complete_ssh_add can now stand for and would in
fact complete for both ssh_add and ssh-add.



ksh(1): custom completion for command containing hyphens

2017-06-02 Thread Anton Lindqvist
Hi,
Custom completions in ksh is currently limited to commands that does not
contain hyphens since such a character cannot be part of an identifier.
We could cheat and replace hyphens with underscores upon performing
completions.
The motivation behind this is that I want to add completions for
ssh-add(1). With the attached diff, I can achieve the following:

  $ set -A complete_ssh_add -- $(find ~/.ssh -name '*_rsa')

Comments? OK?

Index: edit.c
===
RCS file: /cvs/src/bin/ksh/edit.c,v
retrieving revision 1.57
diff -u -p -r1.57 edit.c
--- edit.c  8 Sep 2016 12:12:40 -   1.57
+++ edit.c  2 Jun 2017 15:00:02 -
@@ -585,7 +585,7 @@ x_try_array(const char *buf, int buflen,
 {
const char *cmd, *cp;
int cmdlen, n, i, slen;
-   char *name, *s;
+   char *ncmd, *name, *s;
struct tbl *v, *vp;
 
*nwords = 0;
@@ -604,10 +604,19 @@ x_try_array(const char *buf, int buflen,
while (cmd + cmdlen < want && !isspace((u_char)cmd[cmdlen]))
cmdlen++;
for (i = 0; i < cmdlen; i++) {
-   if (!isalnum((u_char)cmd[i]) && cmd[i] != '_')
+   if (!isalnum((u_char)cmd[i]) && cmd[i] != '_' && cmd[i] != '-')
return 0;
}
 
+   /* Normalize the command by replacing hyphens with underscores. */
+   if ((ncmd = malloc(cmdlen)) == NULL)
+   internal_errorf(1, "unable to allocate memory");
+   for (i = 0; i < cmdlen; i++)
+   if (cmd[i] == '-')
+   ncmd[i] = '_';
+   else
+   ncmd[i] = cmd[i];
+
/* Take a stab at argument count from here. */
n = 1;
for (cp = cmd + cmdlen + 1; cp < want; cp++) {
@@ -616,18 +625,21 @@ x_try_array(const char *buf, int buflen,
}
 
/* Try to find the array. */
-   if (asprintf(, "complete_%.*s_%d", cmdlen, cmd, n) < 0)
+   if (asprintf(, "complete_%.*s_%d", cmdlen, ncmd, n) < 0)
internal_errorf(1, "unable to allocate memory");
v = global(name);
free(name);
if (~v->flag & (ISSET|ARRAY)) {
-   if (asprintf(, "complete_%.*s", cmdlen, cmd) < 0)
+   if (asprintf(, "complete_%.*s", cmdlen, ncmd) < 0)
internal_errorf(1, "unable to allocate memory");
v = global(name);
free(name);
-   if (~v->flag & (ISSET|ARRAY))
+   if (~v->flag & (ISSET|ARRAY)) {
+   free(ncmd);
return 0;
+   }
}
+   free(ncmd);
 
/* Walk the array and build words list. */
for (vp = v; vp; vp = vp->u.array) {
Index: ksh.1
===
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.187
diff -u -p -r1.187 ksh.1
--- ksh.1   19 Feb 2017 22:09:18 -  1.187
+++ ksh.1   2 Jun 2017 15:00:02 -
@@ -4719,6 +4719,14 @@ offer a selection of signal names for th
 .Xr kill 1 :
 .Pp
 .Dl set -A complete_kill_1 -- -9 -HUP -INFO -KILL -TERM
+.Pp
+If the command contain hyphens,
+replace them with underscores.
+For example,
+offer selection of arguments to
+.Xr ssh-add 1 :
+.Pp
+.Dl set -A complete_ssh_add -- $(find ~/.ssh -name '*_rsa')
 .It complete-command: ^X^[
 Automatically completes as much as is unique of the command name having the
 partial word up to the cursor as its prefix, as in the