From: Kirill A. Korinsky Subject: Re: bin/ksh: add keep-tilde completion option To: tech@openbsd.org Date: Mon, 06 Apr 2026 17:04:38 +0200 On Mon, 26 Jan 2026 18:54:46 +0100, Kirill A. Korinsky wrote: > > tech@, > > this is a new optional feature for ksh: keep ~ as unexpanded for completion. > > Not sure does I only one who prefer to keep short path with ~ isntead expand > to /home/user/ > > Feedbacks? Ok? > Anyone? Index: bin/ksh/edit.c =================================================================== RCS file: /home/cvs/src/bin/ksh/edit.c,v diff -u -p -r1.71 edit.c --- bin/ksh/edit.c 23 Apr 2024 13:34:50 -0000 1.71 +++ bin/ksh/edit.c 6 Apr 2026 15:01:50 -0000 @@ -30,6 +30,7 @@ static void check_sigwinch(void); static int x_file_glob(int, const char *, int, char ***); static int x_command_glob(int, const char *, int, char ***); static int x_locate_word(const char *, int, int, int *, int *); +static void x_keep_tilde(char **, int, const char *, const char *); /* Called from main */ @@ -417,10 +418,24 @@ x_file_glob(int flags, const char *str, int nwords; XPtrV w; struct source *s, *sold; + char *tilde = NULL; + char *tilde_expanded = NULL; + int keep_tilde = 0; + int tlen = 0; if (slen < 0) return 0; + if (Flag(FKEEPTILDE) && slen > 0 && str[0] == '~') { + for (tlen = 1; tlen < slen; tlen++) + if (str[tlen] == '/') + break; + tilde = str_nsave(str, tlen, ATEMP); + tilde_expanded = evalstr(tilde, DOTILDE); + if (tilde_expanded != null && tilde_expanded[0] != '~') + keep_tilde = 1; + } + toglob = add_glob(str, slen); /* @@ -433,7 +448,8 @@ x_file_glob(int flags, const char *str, if (yylex(ONEWORD|UNESCAPE) != LWORD) { source = sold; internal_warningf("%s: substitute error", __func__); - return 0; + nwords = 0; + goto done; } source = sold; XPinit(w, 32); @@ -461,13 +477,52 @@ x_file_glob(int flags, const char *str, afree(toglob, ATEMP); if (nwords) { + if (keep_tilde) + x_keep_tilde(words, nwords, tilde, tilde_expanded); *wordsp = words; } else if (words) { x_free_words(nwords, words); *wordsp = NULL; } +done: + if (tilde) + afree(tilde, ATEMP); + if (tilde_expanded && tilde_expanded != null) + afree(tilde_expanded, ATEMP); return nwords; +} + +static void +x_keep_tilde(char **words, int nwords, const char *tilde, + const char *tilde_expanded) +{ + size_t tilde_len, exp_len; + int i; + + tilde_len = strlen(tilde); + exp_len = strlen(tilde_expanded); + if (exp_len == 0) + return; + + for (i = 0; i < nwords; i++) { + char *w = words[i]; + size_t rest_len; + char *nw; + + if (strncmp(w, tilde_expanded, exp_len) != 0) + continue; + if (w[exp_len] != '\0' && w[exp_len] != '/') + continue; + + rest_len = strlen(w + exp_len); + nw = areallocarray(NULL, tilde_len + rest_len + 1, + sizeof(char), ATEMP); + memcpy(nw, tilde, tilde_len); + memcpy(nw + tilde_len, w + exp_len, rest_len + 1); + afree(w, ATEMP); + words[i] = nw; + } } /* Data structure used in x_command_glob() */ Index: bin/ksh/ksh.1 =================================================================== RCS file: /home/cvs/src/bin/ksh/ksh.1,v diff -u -p -r1.223 ksh.1 --- bin/ksh/ksh.1 31 Dec 2025 22:12:25 -0000 1.223 +++ bin/ksh/ksh.1 6 Apr 2026 15:01:50 -0000 @@ -3630,6 +3630,8 @@ is read 13 times in a row. The shell is an interactive shell. This option can only be used when the shell is invoked. See above for a description of what this means. +.It Ic keep-tilde +Keep leading tilde expressions in file name completion results. .It Ic login The shell is a login shell. This option can only be used when the shell is invoked. Index: bin/ksh/misc.c =================================================================== RCS file: /home/cvs/src/bin/ksh/misc.c,v diff -u -p -r1.78 misc.c --- bin/ksh/misc.c 24 Dec 2021 22:08:37 -0000 1.78 +++ bin/ksh/misc.c 6 Apr 2026 15:01:50 -0000 @@ -135,6 +135,7 @@ const struct option sh_options[] = { #endif { "ignoreeof", 0, OF_ANY }, { "interactive",'i', OF_CMDLINE }, + { "keep-tilde", 0, OF_ANY }, /* non-standard */ { "keyword", 'k', OF_ANY }, { "login", 'l', OF_CMDLINE }, { "markdirs", 'X', OF_ANY }, Index: bin/ksh/sh.h =================================================================== RCS file: /home/cvs/src/bin/ksh/sh.h,v diff -u -p -r1.78 sh.h --- bin/ksh/sh.h 5 Mar 2026 05:38:58 -0000 1.78 +++ bin/ksh/sh.h 6 Apr 2026 15:01:50 -0000 @@ -146,6 +146,7 @@ enum sh_flag { #endif FIGNOREEOF, /* eof does not exit */ FTALKING, /* -i: interactive */ + FKEEPTILDE, /* keep ~ in completion */ FKEYWORD, /* -k: name=value anywhere */ FLOGIN, /* -l: a login shell */ FMARKDIRS, /* mark dirs with / in file name completion */ -- wbr, Kirill