Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Sep 2021 11:53:39 GMT
From:      Piotr Pawel Stefaniak <pstef@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b8ff849cbddf - main - sh: improve command completion
Message-ID:  <202109191153.18JBrdOc021235@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by pstef:

URL: https://cgit.FreeBSD.org/src/commit/?id=b8ff849cbddfee3404d6550cf98f53d6bb617707

commit b8ff849cbddfee3404d6550cf98f53d6bb617707
Author:     Piotr Pawel Stefaniak <pstef@FreeBSD.org>
AuthorDate: 2021-09-18 11:26:51 +0000
Commit:     Piotr Pawel Stefaniak <pstef@FreeBSD.org>
CommitDate: 2021-09-19 11:51:45 +0000

    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.
---
 bin/sh/histedit.c | 40 +++++++++++++++++++---------------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
index b680a99c4ace..1a1e11e6f885 100644
--- a/bin/sh/histedit.c
+++ b/bin/sh/histedit.c
@@ -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 @@ out:
 	 * 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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109191153.18JBrdOc021235>