summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--Doc/Zsh/builtins.yo4
-rw-r--r--Doc/Zsh/manual.yo2
-rw-r--r--Doc/Zsh/params.yo4
-rw-r--r--Doc/Zsh/roadmap.yo5
-rw-r--r--Src/Zle/compresult.c30
-rw-r--r--Src/Zle/iwidgets.list2
-rw-r--r--Src/Zle/zle.h16
-rw-r--r--Src/Zle/zle_misc.c209
-rw-r--r--Src/builtin.c2
-rw-r--r--Src/params.c1
11 files changed, 229 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index d033848e0..3e77961e2 100644
--- a/ChangeLog
+++ b/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:
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 0ae467c42..affe5b610 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -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.
diff --git a/Doc/Zsh/manual.yo b/Doc/Zsh/manual.yo
index 9820f1f23..4bf9f6bcd 100644
--- a/Doc/Zsh/manual.yo
+++ b/Doc/Zsh/manual.yo
@@ -59,6 +59,8 @@ menu(The Zsh Web Page)
menu(The Zsh Userguide)
menu(See Also)
+Roadmap
+
Invocation
menu(Compatibility)
diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index d48723756..7999d297b 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -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)
diff --git a/Doc/Zsh/roadmap.yo b/Doc/Zsh/roadmap.yo
index 5c5bb5ea5..547f7e20b 100644
--- a/Doc/Zsh/roadmap.yo
+++ b/Doc/Zsh/roadmap.yo
@@ -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()
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index 4018c5488..84e276747 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -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;
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index bf8b7c0ce..bf1abdadc 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -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
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index 6c960e595..59e790542 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -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)
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 8605c4624..4caf0b915 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -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];
+ suffixnoinslen = inv ? 0 : n;
+ else if (inv) {
+ /*
+ * negative match, \- wasn't present, so it *should*
+ * have this suffix length
+ */
+ suffixnoinslen = n;
+ }
- while (b <= e)
- 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
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;
}
diff --git a/Src/builtin.c b/Src/builtin.c
index 063baa687..1b7e1935e 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1461,6 +1461,8 @@ bin_fc(char *nam, char **argv, Options ops, int func)
else
editor = getsparam("FCEDIT");
if (!editor)
+ editor = getsparam("EDITOR");
+ if (!editor)
editor = DEFAULT_FCEDIT;
unqueue_signals();
diff --git a/Src/params.c b/Src/params.c
index 1468c014a..0d3b6a25b 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -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));