second attempt at getting '$FOO/b*r/baz' tab-completed right,
plus the beginning of the tilde fix… do not use, this is fucking impossible to get right, but I’d like an archival commit
This commit is contained in:
parent
2ed6e8998c
commit
42ac0dc08e
65
edit.c
65
edit.c
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.248 2012/08/24 20:05:11 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.249 2012/08/24 20:57:44 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in later versions we might use libtermcap for this, but since external
|
* in later versions we might use libtermcap for this, but since external
|
||||||
@ -61,8 +61,7 @@ static X_chars edchars;
|
|||||||
#define XCF_FULLPATH BIT(2) /* command completion: store full path */
|
#define XCF_FULLPATH BIT(2) /* command completion: store full path */
|
||||||
#define XCF_COMMAND_FILE (XCF_COMMAND | XCF_FILE)
|
#define XCF_COMMAND_FILE (XCF_COMMAND | XCF_FILE)
|
||||||
#define XCF_IS_COMMAND BIT(3) /* return flag: is command */
|
#define XCF_IS_COMMAND BIT(3) /* return flag: is command */
|
||||||
#define XCF_IS_SUBST BIT(4) /* return flag: is $FOO substitution */
|
#define XCF_IS_NOSPACE BIT(4) /* return flag: do not append a space */
|
||||||
#define XCF_IS_NOSPACE BIT(5) /* return flag: do not append a space */
|
|
||||||
|
|
||||||
static char editmode;
|
static char editmode;
|
||||||
static int xx_cols; /* for Emacs mode */
|
static int xx_cols; /* for Emacs mode */
|
||||||
@ -378,8 +377,9 @@ x_file_glob(int *flagsp, char *toglob, char ***wordsp)
|
|||||||
nwords = DOGLOB | DOTILDE | DOMARKDIRS;
|
nwords = DOGLOB | DOTILDE | DOMARKDIRS;
|
||||||
if (*cp != EOS) {
|
if (*cp != EOS) {
|
||||||
/* probably a $FOO expansion */
|
/* probably a $FOO expansion */
|
||||||
nwords = DOKEEPQUOTE;
|
*flagsp |= XCF_IS_NOSPACE;
|
||||||
*flagsp |= XCF_IS_SUBST | XCF_IS_NOSPACE;
|
/* this always results in at most one match */
|
||||||
|
nwords = DOKEEPQCHAR;
|
||||||
}
|
}
|
||||||
expand(yylval.cp, &w, nwords);
|
expand(yylval.cp, &w, nwords);
|
||||||
XPput(w, NULL);
|
XPput(w, NULL);
|
||||||
@ -601,18 +601,23 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp,
|
|||||||
/*
|
/*
|
||||||
* If the pathname contains a wildcard (an unquoted '*',
|
* If the pathname contains a wildcard (an unquoted '*',
|
||||||
* '?', or '[') or an extglob, then it is globbed based
|
* '?', or '[') or an extglob, then it is globbed based
|
||||||
* on that value (i.e., without the appended '*').
|
* on that value (i.e., without the appended '*'). Same
|
||||||
|
* for parameter substitutions (as in “cat $HOME/.ss↹”)
|
||||||
|
* without appending a trailing space (LP: #710539), as
|
||||||
|
* well as for “~foo” (but not “~foo/”).
|
||||||
*/
|
*/
|
||||||
for (s = toglob; *s; s++) {
|
for (s = toglob; *s; s++) {
|
||||||
if (*s == '\\' && s[1])
|
if (*s == '\\' && s[1])
|
||||||
s++;
|
s++;
|
||||||
else if (*s == '?' || *s == '*' || *s == '[' ||
|
else if (*s == '?' || *s == '*' || *s == '[' ||
|
||||||
/* also skip this for variable expansion */
|
|
||||||
*s == '$' ||
|
*s == '$' ||
|
||||||
/* ?() *() +() @() !() but two already checked */
|
/* ?() *() +() @() !() but two already checked */
|
||||||
(s[1] == '(' /*)*/ &&
|
(s[1] == '(' /*)*/ &&
|
||||||
(*s == '+' || *s == '@' || *s == '!'))) {
|
(*s == '+' || *s == '@' || *s == '!'))) {
|
||||||
/* just expand based on the extglob */
|
/*
|
||||||
|
* just expand based on the extglob
|
||||||
|
* or parameter
|
||||||
|
*/
|
||||||
goto dont_add_glob;
|
goto dont_add_glob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -807,20 +812,24 @@ glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
|
|||||||
static int
|
static int
|
||||||
x_escape(const char *s, size_t len, int (*putbuf_func)(const char *, size_t))
|
x_escape(const char *s, size_t len, int (*putbuf_func)(const char *, size_t))
|
||||||
{
|
{
|
||||||
|
char ch;
|
||||||
size_t add = 0, wlen = len;
|
size_t add = 0, wlen = len;
|
||||||
const char *ifs = str_val(local("IFS", 0));
|
const char *ifs = str_val(local("IFS", 0));
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
while (wlen - add > 0)
|
while (wlen - add > 0) {
|
||||||
if (vstrchr("\"#$&'()*:;<=>?[\\`{|}", s[add]) ||
|
ch = s[add];
|
||||||
vstrchr(ifs, s[add])) {
|
if (vstrchr("\"#$&'()*:;<=>?[\\`{|}", ch) ||
|
||||||
|
ch == QCHAR || vstrchr(ifs, ch)) {
|
||||||
if (putbuf_func(s, add) != 0) {
|
if (putbuf_func(s, add) != 0) {
|
||||||
rval = -1;
|
rval = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
putbuf_func(s[add] == '\n' ? "'" : "\\", 1);
|
putbuf_func(ch == '\n' ? "'" : "\\", 1);
|
||||||
|
if (ch == QCHAR)
|
||||||
|
++add;
|
||||||
putbuf_func(&s[add], 1);
|
putbuf_func(&s[add], 1);
|
||||||
if (s[add] == '\n')
|
if (ch == '\n')
|
||||||
putbuf_func("'", 1);
|
putbuf_func("'", 1);
|
||||||
|
|
||||||
add++;
|
add++;
|
||||||
@ -829,6 +838,7 @@ x_escape(const char *s, size_t len, int (*putbuf_func)(const char *, size_t))
|
|||||||
add = 0;
|
add = 0;
|
||||||
} else
|
} else
|
||||||
++add;
|
++add;
|
||||||
|
}
|
||||||
if (wlen > 0 && rval == 0)
|
if (wlen > 0 && rval == 0)
|
||||||
rval = putbuf_func(s, wlen);
|
rval = putbuf_func(s, wlen);
|
||||||
|
|
||||||
@ -2748,17 +2758,33 @@ do_complete(
|
|||||||
}
|
}
|
||||||
olen = end - start;
|
olen = end - start;
|
||||||
nlen = x_longest_prefix(nwords, words);
|
nlen = x_longest_prefix(nwords, words);
|
||||||
if (nwords == 1 || (flags & XCF_IS_SUBST)) {
|
if (nwords == 1) {
|
||||||
/*
|
/*
|
||||||
* always complete the expansion of parameter and
|
* always complete single matches;
|
||||||
* homedir substitution as well as single matches
|
* any expansion of parameter substitution
|
||||||
|
* is always at most one result, too
|
||||||
*/
|
*/
|
||||||
completed = true;
|
completed = true;
|
||||||
} else {
|
} else {
|
||||||
char *unescaped;
|
char *unescaped;
|
||||||
|
|
||||||
/* make a copy of the original string part and... */
|
/* make a copy of the original string part */
|
||||||
strndupx(unescaped, xbuf + start, olen, ATEMP);
|
strndupx(unescaped, xbuf + start, olen, ATEMP);
|
||||||
|
if (*unescaped == '~') {
|
||||||
|
/*
|
||||||
|
* do some tilde expansion; we know at this
|
||||||
|
* point (by means of having nwords > 1) that
|
||||||
|
* the string looke like "~foo/bar"
|
||||||
|
*/
|
||||||
|
char *cp, *dp;
|
||||||
|
|
||||||
|
cp = ucstrchr(unescaped + 1, '/');
|
||||||
|
*cp++ = 0;
|
||||||
|
if ((dp = tilde(unescaped + 1))) {
|
||||||
|
/* got a match */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ... convert it from backslash-escaped via QCHAR-escaped... */
|
/* ... convert it from backslash-escaped via QCHAR-escaped... */
|
||||||
x_glob_hlp_add_qchar(unescaped);
|
x_glob_hlp_add_qchar(unescaped);
|
||||||
/* ... to unescaped, for comparison with the matches */
|
/* ... to unescaped, for comparison with the matches */
|
||||||
@ -2786,10 +2812,7 @@ do_complete(
|
|||||||
xcp = xbuf + start;
|
xcp = xbuf + start;
|
||||||
xep -= olen;
|
xep -= olen;
|
||||||
memmove(xcp, xcp + olen, xep - xcp + 1);
|
memmove(xcp, xcp + olen, xep - xcp + 1);
|
||||||
if (flags & XCF_IS_SUBST)
|
x_escape(words[0], nlen, x_do_ins);
|
||||||
x_do_ins(words[0], nlen);
|
|
||||||
else
|
|
||||||
x_escape(words[0], nlen, x_do_ins);
|
|
||||||
}
|
}
|
||||||
x_adjust();
|
x_adjust();
|
||||||
/*
|
/*
|
||||||
|
9
eval.c
9
eval.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.126 2012/08/24 20:05:13 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.127 2012/08/24 20:57:45 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
@ -63,7 +63,6 @@ static char *trimsub(char *, char *, int);
|
|||||||
static void glob(char *, XPtrV *, bool);
|
static void glob(char *, XPtrV *, bool);
|
||||||
static void globit(XString *, char **, char *, XPtrV *, int);
|
static void globit(XString *, char **, char *, XPtrV *, int);
|
||||||
static const char *maybe_expand_tilde(const char *, XString *, char **, int);
|
static const char *maybe_expand_tilde(const char *, XString *, char **, int);
|
||||||
static char *tilde(char *);
|
|
||||||
#ifndef MKSH_NOPWNAM
|
#ifndef MKSH_NOPWNAM
|
||||||
static char *homedir(char *);
|
static char *homedir(char *);
|
||||||
#endif
|
#endif
|
||||||
@ -1012,8 +1011,8 @@ expand(const char *cp, /* input word */
|
|||||||
else {
|
else {
|
||||||
/* undo temporary */
|
/* undo temporary */
|
||||||
quote &= ~2;
|
quote &= ~2;
|
||||||
if (f & DOKEEPQUOTE)
|
if (f & DOKEEPQCHAR)
|
||||||
*dp++ = '\\';
|
*dp++ = QCHAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (make_magic) {
|
if (make_magic) {
|
||||||
@ -1642,7 +1641,7 @@ maybe_expand_tilde(const char *p, XString *dsp, char **dpp, int isassign)
|
|||||||
* based on a version by Arnold Robbins
|
* based on a version by Arnold Robbins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *
|
char *
|
||||||
tilde(char *cp)
|
tilde(char *cp)
|
||||||
{
|
{
|
||||||
char *dp = null;
|
char *dp = null;
|
||||||
|
5
sh.h
5
sh.h
@ -157,7 +157,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.581 2012/08/24 20:05:13 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.582 2012/08/24 20:57:46 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R40 2012/08/17"
|
#define MKSH_VERSION "R40 2012/08/17"
|
||||||
|
|
||||||
@ -1343,7 +1343,7 @@ struct ioword {
|
|||||||
#define DOTEMP BIT(8) /* dito: in word part of ${..[%#=?]..} */
|
#define DOTEMP BIT(8) /* dito: in word part of ${..[%#=?]..} */
|
||||||
#define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */
|
#define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */
|
||||||
#define DOMARKDIRS BIT(10) /* force markdirs behaviour */
|
#define DOMARKDIRS BIT(10) /* force markdirs behaviour */
|
||||||
#define DOKEEPQUOTE BIT(11) /* internal use by globbing code */
|
#define DOKEEPQCHAR BIT(11) /* internal use by globbing code */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The arguments of [[ .. ]] expressions are kept in t->args[] and flags
|
* The arguments of [[ .. ]] expressions are kept in t->args[] and flags
|
||||||
@ -1635,6 +1635,7 @@ char *evalonestr(const char *cp, int);
|
|||||||
char *debunk(char *, const char *, size_t);
|
char *debunk(char *, const char *, size_t);
|
||||||
void expand(const char *, XPtrV *, int);
|
void expand(const char *, XPtrV *, int);
|
||||||
int glob_str(char *, XPtrV *, bool);
|
int glob_str(char *, XPtrV *, bool);
|
||||||
|
char *tilde(char *);
|
||||||
/* exec.c */
|
/* exec.c */
|
||||||
int execute(struct op * volatile, volatile int, volatile int * volatile);
|
int execute(struct op * volatile, volatile int, volatile int * volatile);
|
||||||
int shcomexec(const char **);
|
int shcomexec(const char **);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user