Date: Wed, 13 Apr 2022 19:01:50 GMT From: Piotr Pawel Stefaniak <pstef@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: c8f0a1c6d756 - stable/13 - sh: fix autocompletion for commands that share name with a directory Message-ID: <202204131901.23DJ1oQi048306@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by pstef: URL: https://cgit.FreeBSD.org/src/commit/?id=c8f0a1c6d756a0c5cf2fb4deb0234b7863b46fd6 commit c8f0a1c6d756a0c5cf2fb4deb0234b7863b46fd6 Author: Piotr Pawel Stefaniak <pstef@FreeBSD.org> AuthorDate: 2022-03-12 11:08:05 +0000 Commit: Piotr Pawel Stefaniak <pstef@FreeBSD.org> CommitDate: 2022-04-13 19:01:04 +0000 sh: fix autocompletion for commands that share name with a directory (cherry picked from commit 68700941c7ad58d6fa8eda82f3f370d87670fa6a) --- bin/sh/histedit.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c index f3100221d6ad..cf6bebad4c1a 100644 --- a/bin/sh/histedit.c +++ b/bin/sh/histedit.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <dirent.h> #include <limits.h> #include <paths.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -70,12 +71,14 @@ History *hist; /* history cookie */ EditLine *el; /* editline cookie */ int displayhist; static FILE *el_in, *el_out; +static bool in_command_completion; static char *fc_replace(const char *, char *, char *); static int not_fcnumber(const char *); static int str_to_event(const char *, int); static int comparator(const void *, const void *, void *); static char **sh_matches(const char *, int, int); +static const char *append_char_function(const char *); static unsigned char sh_complete(EditLine *, int); /* @@ -540,8 +543,10 @@ static char size_t i = 0, size = 16, uniq; size_t curpos = end - start, lcstring = -1; + in_command_completion = false; if (start > 0 || memchr("/.~", text[0], 3) != NULL) return (NULL); + in_command_completion = true; if ((free_path = path = strdup(pathval())) == NULL) goto out; if ((matches = malloc(size * sizeof(matches[0]))) == NULL) @@ -634,6 +639,32 @@ out: return (matches); } +/* + * If we don't specify this function as app_func in the call to fn_complete2, + * libedit will use the default one, which adds a " " to plain files and + * a "/" to directories regardless of whether it's a command name or a plain + * path (relative or absolute). We never want to add "/" to commands. + * + * For example, after I did "mkdir rmdir", "rmdi" would be autocompleted to + * "rmdir/" instead of "rmdir ". + */ +static const char * +append_char_function(const char *name) +{ + struct stat stbuf; + char *expname = name[0] == '~' ? fn_tilde_expand(name) : NULL; + const char *rs; + + if (!in_command_completion && + stat(expname ? expname : name, &stbuf) == 0 && + S_ISDIR(stbuf.st_mode)) + rs = "/"; + else + rs = " "; + free(expname); + return (rs); +} + /* * This is passed to el_set(el, EL_ADDFN, ...) so that it's possible to * bind a key (tab by default) to execute the function. @@ -642,8 +673,8 @@ unsigned char sh_complete(EditLine *sel, int ch __unused) { return (unsigned char)fn_complete2(sel, NULL, sh_matches, - L" \t\n\"\\'`@$><=;|&{(", NULL, NULL, (size_t)100, - NULL, &((int) {0}), NULL, NULL, FN_QUOTE_MATCH); + L" \t\n\"\\'`@$><=;|&{(", NULL, append_char_function, + (size_t)100, NULL, &((int) {0}), NULL, NULL, FN_QUOTE_MATCH); } #else
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202204131901.23DJ1oQi048306>