1
0
Fork 0
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:
Peter Stephenson 2005-11-07 09:37:34 +00:00
parent 78ace07e16
commit e366ca8dbf
11 changed files with 230 additions and 60 deletions

View file

@ -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:

View file

@ -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.

View file

@ -59,6 +59,8 @@ menu(The Zsh Web Page)
menu(The Zsh Userguide)
menu(See Also)
Roadmap
Invocation
menu(Compatibility)

View file

@ -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)

View file

@ -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()

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -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;
}

View file

@ -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;

View file

@ -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));