mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-28 06:30:57 +02:00
users/9638: tweaks for FCEDIT etc.
21986: rewrite completion suffixes for wide characters
This commit is contained in:
parent
78ace07e16
commit
e366ca8dbf
11 changed files with 230 additions and 60 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2005-11-07 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 21986: Src/Zle/compresult.c, Src/Zle/iwidgets.list,
|
||||
Src/Zle/zle.h, Src/Zle/zle_misc.c: make completion suffix
|
||||
system work with wide characters; also make magic-space
|
||||
behave like a normal space when it follows a suffix.
|
||||
|
||||
* users/9638: Src/builtin.c, Doc/Zsh/builtins.yo,
|
||||
Doc/Zsh/roadmap.yo: allow FCEDIT to default to EDITOR before
|
||||
defaulting to the builtin default; mention edit-command-line in
|
||||
menu in roadmap. Also (unposted) indicate roadmap in detailed
|
||||
texinfo node listing even though it doesn't have subentries.
|
||||
|
||||
2005-11-06 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* Scott Murray <semurray@ntlworld.com>: users/9648:
|
||||
|
|
|
@ -410,7 +410,9 @@ pattern (should be quoted) and only the history events matching this
|
|||
pattern will be shown.
|
||||
Otherwise the editor program var(ename) is invoked on a file containing
|
||||
these history events. If var(ename) is not given, the value
|
||||
of the parameter tt(FCEDIT) is used. If var(ename) is `tt(-)',
|
||||
of the parameter tt(FCEDIT) is used; if that is not set the value of the
|
||||
parameter tt(EDITOR) is used; if that is not set a builtin default, usually
|
||||
`tt(vi)' is used. If var(ename) is `tt(-)',
|
||||
no editor is invoked. When editing is complete, the edited
|
||||
command is executed.
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ menu(The Zsh Web Page)
|
|||
menu(The Zsh Userguide)
|
||||
menu(See Also)
|
||||
|
||||
Roadmap
|
||||
|
||||
Invocation
|
||||
|
||||
menu(Compatibility)
|
||||
|
|
|
@ -758,7 +758,9 @@ tt(ENV) is em(not) used unless zsh is emulating bf(sh) or bf(ksh).
|
|||
)
|
||||
vindex(FCEDIT)
|
||||
item(tt(FCEDIT))(
|
||||
The default editor for the tt(fc) builtin.
|
||||
The default editor for the tt(fc) builtin. If tt(FCEDIT) is not set,
|
||||
the parameter tt(EDITOR) is used; if that is not set either, a builtin
|
||||
default, usually tt(vi), is used.
|
||||
)
|
||||
vindex(fignore)
|
||||
vindex(FIGNORE)
|
||||
|
|
|
@ -58,7 +58,10 @@ item(tt(history-beginning-search-backward-end), etc.)(
|
|||
alternative ways of searching the shell history
|
||||
)
|
||||
item(tt(replace-string), tt(replace-pattern))(
|
||||
functions for replacing strings or patterns globally in the command line.
|
||||
functions for replacing strings or patterns globally in the command line
|
||||
)
|
||||
item(tt(edit-command-line))(
|
||||
edit the command line with an external editor.
|
||||
)
|
||||
enditem()
|
||||
|
||||
|
|
|
@ -991,9 +991,17 @@ do_single(Cmatch m)
|
|||
if (minfo.we) {
|
||||
minfo.end += minfo.insc;
|
||||
if (m->flags & CMF_REMOVE) {
|
||||
makesuffixstr(m->remf, m->rems, minfo.insc);
|
||||
if (minfo.insc == 1)
|
||||
suffixlen[STOUC(m->suf[0])] = 1;
|
||||
/*
|
||||
* Here we need the number of characters, not
|
||||
* bytes in the string.
|
||||
*/
|
||||
int len;
|
||||
ZLE_STRING_T wsuf =
|
||||
stringaszleline(m->suf, 0, &len, NULL, NULL);
|
||||
makesuffixstr(m->remf, m->rems, len);
|
||||
if (len == 1)
|
||||
addsuffix(SUFTYP_POSSTR, wsuf, 1, 1);
|
||||
free(wsuf);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1085,7 +1093,7 @@ do_single(Cmatch m)
|
|||
makesuffixstr(m->remf, m->rems, 1);
|
||||
else if (isset(AUTOREMOVESLASH)) {
|
||||
makesuffix(1);
|
||||
suffixlen['/'] = 1;
|
||||
addsuffix(SUFTYP_POSSTR, ZWS("/"), 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1100,7 +1108,7 @@ do_single(Cmatch m)
|
|||
/* If a suffix was added, and is removable, let *
|
||||
* `,' and `}' remove it. */
|
||||
if (isset(AUTOPARAMKEYS))
|
||||
suffixlen[','] = suffixlen['}'] = suffixlen[256];
|
||||
addsuffix(SUFTYP_POSSTR, ZWS(",}"), 2, suffixnoinslen);
|
||||
} else if (!menucmp) {
|
||||
/*{{*/
|
||||
/* Otherwise, add a `,' suffix, and let `}' remove it. */
|
||||
|
@ -1110,7 +1118,7 @@ do_single(Cmatch m)
|
|||
minfo.insc++;
|
||||
makesuffix(1);
|
||||
if ((!menucmp || minfo.we) && isset(AUTOPARAMKEYS))
|
||||
suffixlen[','] = suffixlen['}'] = 1;
|
||||
addsuffix(SUFTYP_POSSTR, ZWS(",}"), 2, 1);
|
||||
}
|
||||
} else if (!havesuff && (!(m->flags & CMF_FILE) || !sr)) {
|
||||
/* If we didn't add a suffix, add a space, unless we are *
|
||||
|
@ -1129,8 +1137,14 @@ do_single(Cmatch m)
|
|||
makesuffixstr(m->remf, m->rems, 1);
|
||||
}
|
||||
}
|
||||
if (minfo.we && partest && isset(AUTOPARAMKEYS))
|
||||
makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq);
|
||||
if (minfo.we && partest && isset(AUTOPARAMKEYS)) {
|
||||
/* the suffix code needs numbers of characters, not octets */
|
||||
int outlen;
|
||||
char *tmpstr = dupstrpfx(zlemetaline + parq, minfo.insc - parq);
|
||||
ZLE_STRING_T subline = stringaszleline(tmpstr, 0, &outlen, NULL, NULL);
|
||||
makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), outlen);
|
||||
free(subline);
|
||||
}
|
||||
|
||||
if ((menucmp && !minfo.we) || !movetoend) {
|
||||
zlemetacs = minfo.end;
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
"kill-word", killword, ZLE_KILL | ZLE_KEEPSUFFIX
|
||||
"list-choices", listchoices, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_ISCOMP
|
||||
"list-expand", listexpand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"magic-space", magicspace, 0
|
||||
"magic-space", magicspace, ZLE_KEEPSUFFIX | ZLE_MENUCMP
|
||||
"menu-complete", menucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||
"menu-expand-or-complete", menuexpandorcomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
|
||||
"neg-argument", negargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||
|
|
|
@ -248,7 +248,12 @@ typedef void (*KeyScanFunc) _((char *, Thingy, char *, void *));
|
|||
|
||||
/* Standard type of suffix removal. */
|
||||
|
||||
#define removesuffix() iremovesuffix(256, 0)
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
#define NO_INSERT_CHAR WEOF
|
||||
#else
|
||||
#define NO_INSERT_CHAR 256
|
||||
#endif
|
||||
#define removesuffix() iremovesuffix(NO_INSERT_CHAR, 0)
|
||||
|
||||
/*
|
||||
* Cut/kill buffer type. The buffer itself is purely binary data, not
|
||||
|
@ -326,6 +331,15 @@ enum {
|
|||
ZSL_TOEND = 2, /* Go to the end of the new line */
|
||||
};
|
||||
|
||||
|
||||
/* Type arguments to addsuffix() */
|
||||
enum suffixtype {
|
||||
SUFTYP_POSSTR, /* String of characters to match */
|
||||
SUFTYP_NEGSTR, /* String of characters not to match */
|
||||
SUFTYP_POSRNG, /* Range of characters to match */
|
||||
SUFTYP_NEGRNG /* Range of characters not to match */
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
#define STRINGIFY_LITERAL(x) # x
|
||||
#define STRINGIFY(x) STRINGIFY_LITERAL(x)
|
||||
|
|
|
@ -1012,20 +1012,51 @@ executenamedcommand(char *prmt)
|
|||
* indicate that it is being permanently fixed.
|
||||
*/
|
||||
|
||||
/* Length of suffix to remove when inserting each possible character value. *
|
||||
* suffixlen[256] is the length to remove for non-insertion editing actions. */
|
||||
struct suffixset;
|
||||
|
||||
/*
|
||||
* TODO: Aargh, this is completely broken with wide characters.
|
||||
*/
|
||||
/**/
|
||||
mod_export int suffixlen[257];
|
||||
/* An element of a suffix specification */
|
||||
struct suffixset {
|
||||
struct suffixset *next; /* Next in the list */
|
||||
int tp; /* The SUFTYP_* from enum suffixtype */
|
||||
ZLE_STRING_T chars; /* Set of characters to match (or not) */
|
||||
int lenstr; /* Length of chars */
|
||||
int lensuf; /* Length of suffix */
|
||||
};
|
||||
|
||||
/* The list of suffix structures */
|
||||
struct suffixset *suffixlist;
|
||||
|
||||
/* Shell function to call to remove the suffix. */
|
||||
|
||||
/**/
|
||||
static char *suffixfunc;
|
||||
|
||||
/* Length associated with the suffix function */
|
||||
static int suffixfunclen;
|
||||
|
||||
/* Length associated with uninsertable characters */
|
||||
/**/
|
||||
mod_export int
|
||||
suffixnoinslen;
|
||||
|
||||
/**/
|
||||
mod_export void
|
||||
addsuffix(int tp, ZLE_STRING_T chars, int lenstr, int lensuf)
|
||||
{
|
||||
struct suffixset *newsuf = zalloc(sizeof(struct suffixset));
|
||||
newsuf->next = suffixlist;
|
||||
suffixlist = newsuf;
|
||||
|
||||
newsuf->tp = tp;
|
||||
if (lenstr) {
|
||||
newsuf->chars = zalloc(lenstr*sizeof(ZLE_CHAR_T));
|
||||
ZS_memcpy(newsuf->chars, chars, lenstr);
|
||||
} else
|
||||
newsuf->chars = NULL;
|
||||
newsuf->lenstr = lenstr;
|
||||
newsuf->lensuf = lensuf;
|
||||
}
|
||||
|
||||
/* Set up suffix: the last n characters are a suffix that should be *
|
||||
* removed in the usual word end conditions. */
|
||||
|
||||
|
@ -1033,8 +1064,8 @@ static char *suffixfunc;
|
|||
mod_export void
|
||||
makesuffix(int n)
|
||||
{
|
||||
suffixlen[256] = suffixlen[' '] = suffixlen['\t'] = suffixlen['\n'] =
|
||||
suffixlen[';'] = suffixlen['&'] = suffixlen['|'] = n;
|
||||
addsuffix(SUFTYP_POSSTR, ZWS(" \t\n;&|"), 6, n);
|
||||
suffixnoinslen = n;
|
||||
}
|
||||
|
||||
/* Set up suffix for parameter names: the last n characters are a suffix *
|
||||
|
@ -1047,13 +1078,16 @@ makesuffix(int n)
|
|||
mod_export void
|
||||
makeparamsuffix(int br, int n)
|
||||
{
|
||||
if(br || unset(KSHARRAYS))
|
||||
suffixlen[':'] = suffixlen['['] = n;
|
||||
if(br) {
|
||||
suffixlen['#'] = suffixlen['%'] = suffixlen['?'] = n;
|
||||
suffixlen['-'] = suffixlen['+'] = suffixlen['='] = n;
|
||||
/*{*/ suffixlen['}'] = suffixlen['/'] = n;
|
||||
ZLE_STRING_T charstr = ZWS(":[#%?-+=");
|
||||
int lenstr = 0;
|
||||
|
||||
if (br || unset(KSHARRAYS)) {
|
||||
lenstr = 2;
|
||||
if (br)
|
||||
lenstr += 6;
|
||||
}
|
||||
if (lenstr)
|
||||
addsuffix(SUFTYP_POSSTR, charstr, lenstr, n);
|
||||
}
|
||||
|
||||
/* Set up suffix given a string containing the characters on which to *
|
||||
|
@ -1066,9 +1100,10 @@ makesuffixstr(char *f, char *s, int n)
|
|||
if (f) {
|
||||
zsfree(suffixfunc);
|
||||
suffixfunc = ztrdup(f);
|
||||
suffixlen[0] = n;
|
||||
suffixfunclen = n;
|
||||
} else if (s) {
|
||||
int inv, i, v, z = 0;
|
||||
int inv, i, z = 0;
|
||||
ZLE_STRING_T ws, lasts, wptr;
|
||||
|
||||
if (*s == '^' || *s == '!') {
|
||||
inv = 1;
|
||||
|
@ -1077,28 +1112,43 @@ makesuffixstr(char *f, char *s, int n)
|
|||
inv = 0;
|
||||
s = getkeystring(s, &i, 5, &z);
|
||||
s = metafy(s, i, META_USEHEAP);
|
||||
|
||||
if (inv) {
|
||||
v = 0;
|
||||
for (i = 0; i < 257; i++)
|
||||
suffixlen[i] = n;
|
||||
} else
|
||||
v = n;
|
||||
ws = stringaszleline(s, 0, &i, NULL, NULL);
|
||||
|
||||
if (z)
|
||||
suffixlen[256] = v;
|
||||
|
||||
while (*s) {
|
||||
if (s[1] == '-' && s[2]) {
|
||||
int b = (int) *s, e = (int) s[2];
|
||||
|
||||
while (b <= e)
|
||||
suffixlen[b++] = v;
|
||||
s += 2;
|
||||
} else
|
||||
suffixlen[STOUC(*s)] = v;
|
||||
s++;
|
||||
suffixnoinslen = inv ? 0 : n;
|
||||
else if (inv) {
|
||||
/*
|
||||
* negative match, \- wasn't present, so it *should*
|
||||
* have this suffix length
|
||||
*/
|
||||
suffixnoinslen = n;
|
||||
}
|
||||
|
||||
lasts = wptr = ws;
|
||||
while (i) {
|
||||
if (i >= 3 && wptr[1] == ZWC('-')) {
|
||||
ZLE_CHAR_T str[2];
|
||||
|
||||
if (wptr > lasts)
|
||||
addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR,
|
||||
lasts, wptr - lasts, n);
|
||||
str[0] = *wptr;
|
||||
str[1] = wptr[2];
|
||||
addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG,
|
||||
str, 2, n);
|
||||
|
||||
wptr += 3;
|
||||
i -= 3;
|
||||
lasts = wptr;
|
||||
} else {
|
||||
wptr++;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (wptr > lasts)
|
||||
addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR,
|
||||
lasts, wptr - lasts, n);
|
||||
free(ws);
|
||||
} else
|
||||
makesuffix(n);
|
||||
}
|
||||
|
@ -1129,7 +1179,7 @@ iremovesuffix(ZLE_INT_T c, int keep)
|
|||
unmetafy_line();
|
||||
}
|
||||
|
||||
sprintf(buf, "%d", suffixlen[0]);
|
||||
sprintf(buf, "%d", suffixfunclen);
|
||||
addlinknode(args, suffixfunc);
|
||||
addlinknode(args, buf);
|
||||
|
||||
|
@ -1146,14 +1196,73 @@ iremovesuffix(ZLE_INT_T c, int keep)
|
|||
zsfree(suffixfunc);
|
||||
suffixfunc = NULL;
|
||||
} else {
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
/* TODO: best I can think of for now... */
|
||||
int sl = (unsigned int)c <= 256 ? suffixlen[c] : 0;
|
||||
#else
|
||||
int sl = suffixlen[c];
|
||||
#endif
|
||||
if(sl) {
|
||||
backdel(sl);
|
||||
int sl = 0;
|
||||
struct suffixset *ss;
|
||||
|
||||
if (c == NO_INSERT_CHAR) {
|
||||
sl = suffixnoinslen;
|
||||
} else {
|
||||
/*
|
||||
* Search for a match for c in the suffix list.
|
||||
* We stop if we encounter a match in a positive or negative
|
||||
* list, using the suffix length specified or zero respectively.
|
||||
* If we reached the end and passed through a negative
|
||||
* list, we use the suffix length for that, else zero.
|
||||
* This would break if it were possible to have negative
|
||||
* sets with different suffix length: that's not supposed
|
||||
* to happen.
|
||||
*/
|
||||
int negsuflen = 0, found = 0;
|
||||
|
||||
for (ss = suffixlist; ss; ss = ss->next) {
|
||||
switch (ss->tp) {
|
||||
case SUFTYP_POSSTR:
|
||||
if (memchr(ss->chars, c, ss->lenstr)) {
|
||||
sl = ss->lensuf;
|
||||
found = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SUFTYP_NEGSTR:
|
||||
if (memchr(ss->chars, c, ss->lenstr)) {
|
||||
sl = 0;
|
||||
found = 1;
|
||||
} else {
|
||||
negsuflen = ss->lensuf;
|
||||
}
|
||||
break;
|
||||
|
||||
case SUFTYP_POSRNG:
|
||||
if (ss->chars[0] <= c && c <= ss->chars[1]) {
|
||||
sl = ss->lensuf;
|
||||
found = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SUFTYP_NEGRNG:
|
||||
if (ss->chars[0] <= c && c <= ss->chars[1]) {
|
||||
sl = 0;
|
||||
found = 1;
|
||||
} else {
|
||||
negsuflen = ss->lensuf;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
sl = negsuflen;
|
||||
}
|
||||
if (sl) {
|
||||
/* must be shifting wide character lengths */
|
||||
if (zlemetaline != NULL) {
|
||||
unmetafy_line();
|
||||
backdel(sl);
|
||||
metafy_line();
|
||||
} else
|
||||
backdel(sl);
|
||||
if (!keep)
|
||||
invalidatelist();
|
||||
}
|
||||
|
@ -1167,5 +1276,15 @@ iremovesuffix(ZLE_INT_T c, int keep)
|
|||
mod_export void
|
||||
fixsuffix(void)
|
||||
{
|
||||
memset(suffixlen, 0, sizeof(suffixlen));
|
||||
while (suffixlist) {
|
||||
struct suffixset *next = suffixlist->next;
|
||||
|
||||
if (suffixlist->lenstr)
|
||||
zfree(suffixlist->chars, suffixlist->lenstr * sizeof(ZLE_CHAR_T));
|
||||
zfree(suffixlist, sizeof(struct suffixset));
|
||||
|
||||
suffixlist = next;
|
||||
}
|
||||
|
||||
suffixfunclen = suffixnoinslen = 0;
|
||||
}
|
||||
|
|
|
@ -1460,6 +1460,8 @@ bin_fc(char *nam, char **argv, Options ops, int func)
|
|||
editor = OPT_ARG(ops, 'e');
|
||||
else
|
||||
editor = getsparam("FCEDIT");
|
||||
if (!editor)
|
||||
editor = getsparam("EDITOR");
|
||||
if (!editor)
|
||||
editor = DEFAULT_FCEDIT;
|
||||
|
||||
|
|
|
@ -643,7 +643,6 @@ createparamtable(void)
|
|||
#ifdef HAVE_SELECT
|
||||
setiparam("BAUD", getbaudrate(&shttyinfo)); /* get the output baudrate */
|
||||
#endif
|
||||
setsparam("FCEDIT", ztrdup(DEFAULT_FCEDIT));
|
||||
setsparam("TMPPREFIX", ztrdup(DEFAULT_TMPPREFIX));
|
||||
setsparam("TIMEFMT", ztrdup(DEFAULT_TIMEFMT));
|
||||
setsparam("WATCHFMT", ztrdup(default_watchfmt));
|
||||
|
|
Loading…
Reference in a new issue