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 -0000 1.57 +++ edit.c 2 Jun 2017 15:00:02 -0000 @@ -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(&name, "complete_%.*s_%d", cmdlen, cmd, n) < 0) + if (asprintf(&name, "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(&name, "complete_%.*s", cmdlen, cmd) < 0) + if (asprintf(&name, "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 -0000 1.187 +++ ksh.1 2 Jun 2017 15:00:02 -0000 @@ -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