mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-21 10:19:04 +00:00
sh: improve command completion
When multiple matches are found, we keep the provided string on the input line and print unique matches as suggestions. But the multiple matches might be the same command found in different directories, so we should deduplicate the matches first and then decide whether to autocomplete the command or not, based on the number of unique matches.
This commit is contained in:
parent
e19d93b19d
commit
b8ff849cbd
|
@ -590,7 +590,7 @@ static char
|
|||
char *free_path = NULL, *path;
|
||||
const char *dirname;
|
||||
char **matches = NULL;
|
||||
size_t i = 0, size = 16, j, k;
|
||||
size_t i = 0, size = 16, uniq;
|
||||
size_t curpos = end - start;
|
||||
|
||||
if (start > 0 || memchr("/.~", text[0], 3) != NULL)
|
||||
|
@ -639,6 +639,21 @@ static char
|
|||
}
|
||||
out:
|
||||
free(free_path);
|
||||
if (i == 0) {
|
||||
free(matches);
|
||||
return (NULL);
|
||||
}
|
||||
uniq = 1;
|
||||
if (i > 1) {
|
||||
qsort_s(matches + 1, i, sizeof(matches[0]), comparator,
|
||||
(void *)(intptr_t)curpos);
|
||||
for (size_t k = 2; k <= i; k++)
|
||||
if (strcmp(matches[uniq] + curpos, matches[k] + curpos) == 0)
|
||||
free(matches[k]);
|
||||
else
|
||||
matches[++uniq] = matches[k];
|
||||
}
|
||||
matches[uniq + 1] = NULL;
|
||||
/*
|
||||
* matches[0] is special: it's not a real matching file name but a common
|
||||
* prefix for all matching names. It can't be null, unlike any other
|
||||
|
@ -648,30 +663,13 @@ static char
|
|||
* string in matches[0] which is the reason to copy the full name of the
|
||||
* only match.
|
||||
*/
|
||||
if (i == 0) {
|
||||
free(matches);
|
||||
return (NULL);
|
||||
} else if (i == 1) {
|
||||
matches[0] = strdup(matches[1]);
|
||||
matches[2] = NULL;
|
||||
if (matches[0] != NULL)
|
||||
return (matches);
|
||||
} else
|
||||
matches[0] = strdup(text);
|
||||
matches[0] = strdup(uniq == 1 ? matches[1] : text);
|
||||
if (matches[0] == NULL) {
|
||||
for (j = 1; j <= i; j++)
|
||||
free(matches[j]);
|
||||
for (size_t k = 1; k <= uniq; k++)
|
||||
free(matches[k]);
|
||||
free(matches);
|
||||
return (NULL);
|
||||
}
|
||||
qsort_s(matches + 1, i, sizeof(matches[0]), comparator,
|
||||
(void *)(intptr_t)curpos);
|
||||
for (j = 1, k = 2; k <= i; k++)
|
||||
if (strcmp(matches[j] + curpos, matches[k] + curpos) == 0)
|
||||
free(matches[k]);
|
||||
else
|
||||
matches[++j] = matches[k];
|
||||
matches[j + 1] = NULL;
|
||||
return (matches);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue