Fix some aspects of globbing - in emacs mode at least.
echo ~<ESC><ESC> and $HOME<ESC><ESC> as well as ~/b<ESC><ESC> all now expand correctly.
This commit is contained in:
parent
bab1dc1428
commit
84412e9292
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: edit.c,v 1.6 1999/11/02 22:06:45 jdolecek Exp $ */
|
||||
/* $NetBSD: edit.c,v 1.7 2002/01/25 23:40:51 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Command line editing - common code
|
||||
@ -840,6 +840,40 @@ x_cf_glob(flags, buf, buflen, pos, startp, endp, wordsp, is_commandp)
|
||||
return nwords;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
find_match(const char *s, int have)
|
||||
{
|
||||
int want = 0;
|
||||
int nest = 1;
|
||||
int c;
|
||||
|
||||
switch (have) {
|
||||
case '(': want = ')'; break;
|
||||
case '{': want = '}'; break;
|
||||
case '[': want = ']'; break;
|
||||
case '\'':
|
||||
case '"': want = have; break;
|
||||
}
|
||||
if (want == 0 || s == NULL)
|
||||
return NULL;
|
||||
|
||||
while (nest > 0 && (c = *s)) {
|
||||
if (c == '\\') {
|
||||
s++;
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if (c == want)
|
||||
nest--;
|
||||
else if (c == have)
|
||||
nest++;
|
||||
if (nest > 0)
|
||||
s++;
|
||||
}
|
||||
return (nest == 0) ? (char *) s : NULL;
|
||||
}
|
||||
|
||||
/* Given a string, copy it and possibly add a '*' to the end. The
|
||||
* new string is returned.
|
||||
*/
|
||||
@ -859,19 +893,33 @@ add_glob(str, slen)
|
||||
toglob[slen] = '\0';
|
||||
|
||||
/*
|
||||
* If the pathname contains a wildcard (an unquoted '*',
|
||||
* '?', or '[') or parameter expansion ('$'), or a ~username
|
||||
* with no trailing slash, then it is globbed based on that
|
||||
* value (i.e., without the appended '*').
|
||||
* If the pathname contains a wildcard (an unquoted '*', '?',
|
||||
* or '[') or parameter expansion ('$') with nothing following
|
||||
* it, or a ~username with no trailing slash, then it is
|
||||
* globbed based on that value (i.e., without the appended
|
||||
* '*').
|
||||
*/
|
||||
for (s = toglob; *s; s++) {
|
||||
if (*s == '\\' && s[1])
|
||||
s++;
|
||||
else if (*s == '*' || *s == '[' || *s == '?' || *s == '$'
|
||||
else if (*s == '*' || *s == '[' || *s == '?'
|
||||
|| (s[1] == '(' /*)*/ && strchr("*+?@!", *s)))
|
||||
break;
|
||||
else if (ISDIRSEP(*s))
|
||||
saw_slash = TRUE;
|
||||
else if (*s == '$') {
|
||||
if (*++s == '{') {
|
||||
char *cp;
|
||||
|
||||
if ((cp = find_match(&s[1], '{')))
|
||||
s = ++cp;
|
||||
}
|
||||
if (*s)
|
||||
s += strcspn(s,
|
||||
".,/?-<>[]{}()'\";:\\|=+*&^%$#@!`~");
|
||||
if (!*s)
|
||||
return toglob;
|
||||
}
|
||||
}
|
||||
if (!*s && (*toglob != '~' || saw_slash)) {
|
||||
toglob[slen] = '*';
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: emacs.c,v 1.10 1999/11/09 00:01:49 jdolecek Exp $ */
|
||||
/* $NetBSD: emacs.c,v 1.11 2002/01/25 23:40:51 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Emacs-like command line editing and history
|
||||
@ -1768,6 +1768,17 @@ x_expand(c)
|
||||
return KSTD;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
is_dir(const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(path, &st) == 0)
|
||||
return S_ISDIR(st.st_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* type == 0 for list, 1 for complete and 2 for complete-list */
|
||||
static void
|
||||
do_complete(flags, type)
|
||||
@ -1854,8 +1865,15 @@ do_complete(flags, type)
|
||||
* space to the end...
|
||||
*/
|
||||
if (nwords == 1
|
||||
&& !ISDIRSEP(words[0][nlen - 1]))
|
||||
x_ins(space);
|
||||
&& !ISDIRSEP(words[0][nlen - 1])) {
|
||||
/*
|
||||
* we may be here because we
|
||||
* just expanded $HOME in
|
||||
* which case adding '/' is
|
||||
* correct.
|
||||
*/
|
||||
x_ins(is_dir(words[0]) ? slash : space);
|
||||
}
|
||||
} else
|
||||
x_e_putc(BEL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user