1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-29 19:00: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> 2005-11-06 Peter Stephenson <p.w.stephenson@ntlworld.com>
* Scott Murray <semurray@ntlworld.com>: users/9648: * 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. pattern will be shown.
Otherwise the editor program var(ename) is invoked on a file containing Otherwise the editor program var(ename) is invoked on a file containing
these history events. If var(ename) is not given, the value 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 no editor is invoked. When editing is complete, the edited
command is executed. command is executed.

View file

@ -59,6 +59,8 @@ menu(The Zsh Web Page)
menu(The Zsh Userguide) menu(The Zsh Userguide)
menu(See Also) menu(See Also)
Roadmap
Invocation Invocation
menu(Compatibility) 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) vindex(FCEDIT)
item(tt(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)
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 alternative ways of searching the shell history
) )
item(tt(replace-string), tt(replace-pattern))( 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() enditem()

View file

@ -991,9 +991,17 @@ do_single(Cmatch m)
if (minfo.we) { if (minfo.we) {
minfo.end += minfo.insc; minfo.end += minfo.insc;
if (m->flags & CMF_REMOVE) { if (m->flags & CMF_REMOVE) {
makesuffixstr(m->remf, m->rems, minfo.insc); /*
if (minfo.insc == 1) * Here we need the number of characters, not
suffixlen[STOUC(m->suf[0])] = 1; * 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 { } else {
@ -1085,7 +1093,7 @@ do_single(Cmatch m)
makesuffixstr(m->remf, m->rems, 1); makesuffixstr(m->remf, m->rems, 1);
else if (isset(AUTOREMOVESLASH)) { else if (isset(AUTOREMOVESLASH)) {
makesuffix(1); 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 * /* If a suffix was added, and is removable, let *
* `,' and `}' remove it. */ * `,' and `}' remove it. */
if (isset(AUTOPARAMKEYS)) if (isset(AUTOPARAMKEYS))
suffixlen[','] = suffixlen['}'] = suffixlen[256]; addsuffix(SUFTYP_POSSTR, ZWS(",}"), 2, suffixnoinslen);
} else if (!menucmp) { } else if (!menucmp) {
/*{{*/ /*{{*/
/* Otherwise, add a `,' suffix, and let `}' remove it. */ /* Otherwise, add a `,' suffix, and let `}' remove it. */
@ -1110,7 +1118,7 @@ do_single(Cmatch m)
minfo.insc++; minfo.insc++;
makesuffix(1); makesuffix(1);
if ((!menucmp || minfo.we) && isset(AUTOPARAMKEYS)) if ((!menucmp || minfo.we) && isset(AUTOPARAMKEYS))
suffixlen[','] = suffixlen['}'] = 1; addsuffix(SUFTYP_POSSTR, ZWS(",}"), 2, 1);
} }
} else if (!havesuff && (!(m->flags & CMF_FILE) || !sr)) { } else if (!havesuff && (!(m->flags & CMF_FILE) || !sr)) {
/* If we didn't add a suffix, add a space, unless we are * /* 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); makesuffixstr(m->remf, m->rems, 1);
} }
} }
if (minfo.we && partest && isset(AUTOPARAMKEYS)) if (minfo.we && partest && isset(AUTOPARAMKEYS)) {
makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq); /* 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) { if ((menucmp && !minfo.we) || !movetoend) {
zlemetacs = minfo.end; zlemetacs = minfo.end;

View file

@ -73,7 +73,7 @@
"kill-word", killword, ZLE_KILL | ZLE_KEEPSUFFIX "kill-word", killword, ZLE_KILL | ZLE_KEEPSUFFIX
"list-choices", listchoices, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_ISCOMP "list-choices", listchoices, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_ISCOMP
"list-expand", listexpand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL "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-complete", menucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
"menu-expand-or-complete", menuexpandorcomplete, 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 "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. */ /* 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 * 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 */ 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 #ifdef DEBUG
#define STRINGIFY_LITERAL(x) # x #define STRINGIFY_LITERAL(x) # x
#define STRINGIFY(x) STRINGIFY_LITERAL(x) #define STRINGIFY(x) STRINGIFY_LITERAL(x)

View file

@ -1012,20 +1012,51 @@ executenamedcommand(char *prmt)
* indicate that it is being permanently fixed. * indicate that it is being permanently fixed.
*/ */
/* Length of suffix to remove when inserting each possible character value. * struct suffixset;
* suffixlen[256] is the length to remove for non-insertion editing actions. */
/* /* An element of a suffix specification */
* TODO: Aargh, this is completely broken with wide characters. struct suffixset {
*/ struct suffixset *next; /* Next in the list */
/**/ int tp; /* The SUFTYP_* from enum suffixtype */
mod_export int suffixlen[257]; 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. */ /* Shell function to call to remove the suffix. */
/**/ /**/
static char *suffixfunc; 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 * /* Set up suffix: the last n characters are a suffix that should be *
* removed in the usual word end conditions. */ * removed in the usual word end conditions. */
@ -1033,8 +1064,8 @@ static char *suffixfunc;
mod_export void mod_export void
makesuffix(int n) makesuffix(int n)
{ {
suffixlen[256] = suffixlen[' '] = suffixlen['\t'] = suffixlen['\n'] = addsuffix(SUFTYP_POSSTR, ZWS(" \t\n;&|"), 6, n);
suffixlen[';'] = suffixlen['&'] = suffixlen['|'] = n; suffixnoinslen = n;
} }
/* Set up suffix for parameter names: the last n characters are a suffix * /* Set up suffix for parameter names: the last n characters are a suffix *
@ -1047,13 +1078,16 @@ makesuffix(int n)
mod_export void mod_export void
makeparamsuffix(int br, int n) makeparamsuffix(int br, int n)
{ {
if(br || unset(KSHARRAYS)) ZLE_STRING_T charstr = ZWS(":[#%?-+=");
suffixlen[':'] = suffixlen['['] = n; int lenstr = 0;
if(br) {
suffixlen['#'] = suffixlen['%'] = suffixlen['?'] = n; if (br || unset(KSHARRAYS)) {
suffixlen['-'] = suffixlen['+'] = suffixlen['='] = n; lenstr = 2;
/*{*/ suffixlen['}'] = suffixlen['/'] = n; if (br)
lenstr += 6;
} }
if (lenstr)
addsuffix(SUFTYP_POSSTR, charstr, lenstr, n);
} }
/* Set up suffix given a string containing the characters on which to * /* 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) { if (f) {
zsfree(suffixfunc); zsfree(suffixfunc);
suffixfunc = ztrdup(f); suffixfunc = ztrdup(f);
suffixlen[0] = n; suffixfunclen = n;
} else if (s) { } else if (s) {
int inv, i, v, z = 0; int inv, i, z = 0;
ZLE_STRING_T ws, lasts, wptr;
if (*s == '^' || *s == '!') { if (*s == '^' || *s == '!') {
inv = 1; inv = 1;
@ -1077,28 +1112,43 @@ makesuffixstr(char *f, char *s, int n)
inv = 0; inv = 0;
s = getkeystring(s, &i, 5, &z); s = getkeystring(s, &i, 5, &z);
s = metafy(s, i, META_USEHEAP); s = metafy(s, i, META_USEHEAP);
ws = stringaszleline(s, 0, &i, NULL, NULL);
if (inv) {
v = 0;
for (i = 0; i < 257; i++)
suffixlen[i] = n;
} else
v = n;
if (z) if (z)
suffixlen[256] = v; suffixnoinslen = inv ? 0 : n;
else if (inv) {
while (*s) { /*
if (s[1] == '-' && s[2]) { * negative match, \- wasn't present, so it *should*
int b = (int) *s, e = (int) s[2]; * have this suffix length
*/
while (b <= e) suffixnoinslen = n;
suffixlen[b++] = v;
s += 2;
} else
suffixlen[STOUC(*s)] = v;
s++;
} }
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 } else
makesuffix(n); makesuffix(n);
} }
@ -1129,7 +1179,7 @@ iremovesuffix(ZLE_INT_T c, int keep)
unmetafy_line(); unmetafy_line();
} }
sprintf(buf, "%d", suffixlen[0]); sprintf(buf, "%d", suffixfunclen);
addlinknode(args, suffixfunc); addlinknode(args, suffixfunc);
addlinknode(args, buf); addlinknode(args, buf);
@ -1146,14 +1196,73 @@ iremovesuffix(ZLE_INT_T c, int keep)
zsfree(suffixfunc); zsfree(suffixfunc);
suffixfunc = NULL; suffixfunc = NULL;
} else { } else {
#ifdef MULTIBYTE_SUPPORT int sl = 0;
/* TODO: best I can think of for now... */ struct suffixset *ss;
int sl = (unsigned int)c <= 256 ? suffixlen[c] : 0;
#else if (c == NO_INSERT_CHAR) {
int sl = suffixlen[c]; sl = suffixnoinslen;
#endif } else {
if(sl) { /*
backdel(sl); * 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) if (!keep)
invalidatelist(); invalidatelist();
} }
@ -1167,5 +1276,15 @@ iremovesuffix(ZLE_INT_T c, int keep)
mod_export void mod_export void
fixsuffix(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'); editor = OPT_ARG(ops, 'e');
else else
editor = getsparam("FCEDIT"); editor = getsparam("FCEDIT");
if (!editor)
editor = getsparam("EDITOR");
if (!editor) if (!editor)
editor = DEFAULT_FCEDIT; editor = DEFAULT_FCEDIT;

View file

@ -643,7 +643,6 @@ createparamtable(void)
#ifdef HAVE_SELECT #ifdef HAVE_SELECT
setiparam("BAUD", getbaudrate(&shttyinfo)); /* get the output baudrate */ setiparam("BAUD", getbaudrate(&shttyinfo)); /* get the output baudrate */
#endif #endif
setsparam("FCEDIT", ztrdup(DEFAULT_FCEDIT));
setsparam("TMPPREFIX", ztrdup(DEFAULT_TMPPREFIX)); setsparam("TMPPREFIX", ztrdup(DEFAULT_TMPPREFIX));
setsparam("TIMEFMT", ztrdup(DEFAULT_TIMEFMT)); setsparam("TIMEFMT", ztrdup(DEFAULT_TIMEFMT));
setsparam("WATCHFMT", ztrdup(default_watchfmt)); setsparam("WATCHFMT", ztrdup(default_watchfmt));