Skip to content

Commit

Permalink
redis-cli: fix bugs in hints of commands with subcommands. (redis#8914)
Browse files Browse the repository at this point in the history
There are two bugs in redis-cli hints:
* The hints of commands with subcommands lack first params.
* When search matching command of currently input, we should find the
command with longest matching prefix. If not COMMAND INFO will always
match COMMAND and display no hints.
  • Loading branch information
huangzhw authored May 17, 2021
1 parent 46d9f31 commit 8827aae
Showing 1 changed file with 40 additions and 26 deletions.
66 changes: 40 additions & 26 deletions src/redis-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,48 +707,62 @@ static void completionCallback(const char *buf, linenoiseCompletions *lc) {
static char *hintsCallback(const char *buf, int *color, int *bold) {
if (!pref.hints) return NULL;

int i, argc, buflen = strlen(buf);
sds *argv = sdssplitargs(buf,&argc);
int i, rawargc, argc, buflen = strlen(buf), matchlen = 0;
sds *rawargv, *argv = sdssplitargs(buf,&argc);
int endspace = buflen && isspace(buf[buflen-1]);
helpEntry *entry = NULL;

/* Check if the argument list is empty and return ASAP. */
if (argc == 0) {
sdsfreesplitres(argv,argc);
return NULL;
}

/* Search longest matching prefix command */
for (i = 0; i < helpEntriesLen; i++) {
if (!(helpEntries[i].type & CLI_HELP_COMMAND)) continue;

if (strcasecmp(argv[0],helpEntries[i].full) == 0 ||
strcasecmp(buf,helpEntries[i].full) == 0)
{
*color = 90;
*bold = 0;
sds hint = sdsnew(helpEntries[i].org->params);

/* Remove arguments from the returned hint to show only the
* ones the user did not yet typed. */
int toremove = argc-1;
while(toremove > 0 && sdslen(hint)) {
if (hint[0] == '[') break;
if (hint[0] == ' ') toremove--;
sdsrange(hint,1,-1);
rawargv = sdssplitargs(helpEntries[i].full,&rawargc);
if (rawargc <= argc) {
int j;
for (j = 0; j < rawargc; j++) {
if (strcasecmp(rawargv[j],argv[j])) {
break;
}
}

/* Add an initial space if needed. */
if (!endspace) {
sds newhint = sdsnewlen(" ",1);
newhint = sdscatsds(newhint,hint);
sdsfree(hint);
hint = newhint;
if (j == rawargc && rawargc > matchlen) {
matchlen = rawargc;
entry = &helpEntries[i];
}

sdsfreesplitres(argv,argc);
return hint;
}
sdsfreesplitres(rawargv,rawargc);
}
sdsfreesplitres(argv,argc);

if (entry) {
*color = 90;
*bold = 0;
sds hint = sdsnew(entry->org->params);

/* Remove arguments from the returned hint to show only the
* ones the user did not yet type. */
int toremove = argc-matchlen;
while(toremove > 0 && sdslen(hint)) {
if (hint[0] == '[') break;
if (hint[0] == ' ') toremove--;
sdsrange(hint,1,-1);
}

/* Add an initial space if needed. */
if (!endspace) {
sds newhint = sdsnewlen(" ",1);
newhint = sdscatsds(newhint,hint);
sdsfree(hint);
hint = newhint;
}

return hint;
}
return NULL;
}

Expand Down

0 comments on commit 8827aae

Please sign in to comment.