Download raw body.
bin/ksh: add keep-tilde completion option
On Mon, 26 Jan 2026 18:54:46 +0100,
Kirill A. Korinsky <kirill@korins.ky> 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
bin/ksh: add keep-tilde completion option