* Re: Fish-like autosuggestions
[not found] ` <20131106200715.6e549a6e@pws-pc.ntlworld.com>
@ 2013-11-06 21:33 ` Peter Stephenson
2013-11-07 0:11 ` Bart Schaefer
2013-11-12 19:46 ` Peter Stephenson
0 siblings, 2 replies; 3+ messages in thread
From: Peter Stephenson @ 2013-11-06 21:33 UTC (permalink / raw)
To: Zsh Hackers' List
(Moved to zsh-workers.)
This seems to work.
In one session I did
ztcp -l 3519
port=$REPLY
ztcp -a $port
out=$REPLY
and on the other
ztcp localhost 3519
in=$REPLY
read-from-fd() {
local REPLY
read -u$1 REPLY
LBUFFER+=$REPLY
zle -R
}
zle -N read-from-fd
zle -Fw $in read-from-fd
and then doing "print stuff >&$out" in the first session causes it to be
added to the command line on the other.
Note the point about "zle -R". We are down in the loop that processes
input to the line editor; we don't get back to redisplaying until after
we've read a key. This doesn't seem unreasonable, although we could
force a redisplay internally if that seemed sensible. (Returning from
the input reading without reading anything from the main input file
descriptor doesn't seem the right thing to do.)
I should really rewrite those three separate arrays to use an array of
structures.
I've fixed a bug here --- zlecallhook() prepended the thingy name to the
argument list, but execzlefunc() prepended the function name, too.
I don't think both can be right --- that gives $0 as the function name,
$1 as the thingy name, and normal arguments starting at $2. I can't
believe that's intentional and it doesn't appear to be suggested by the
doc. I think $WIDGET does the expected thing of returning the name
of the widget if different from the function name.
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 614924b..2d77568 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -373,7 +373,7 @@ xitem(tt(zle) tt(-R) [ tt(-c) ] [ var(display-string) ] [ var(string) ... ])
xitem(tt(zle) tt(-M) var(string))
xitem(tt(zle) tt(-U) var(string))
xitem(tt(zle) tt(-K) var(keymap))
-xitem(tt(zle) tt(-F) [ tt(-L) ] [ var(fd) [ var(handler) ] ])
+xitem(tt(zle) tt(-F) [ tt(-L) | tt(-w) ] [ var(fd) [ var(handler) ] ])
xitem(tt(zle) tt(-I))
xitem(tt(zle) tt(-T) [ tt(tc) var(function) | tt(-r) tt(tc) | tt(-L) ] )
item(tt(zle) var(widget) tt([ -n) var(num) tt(]) tt([ -Nw ] [ -K) var(keymap) tt(]) var(args) ...)(
@@ -487,7 +487,7 @@ This keymap selection affects the interpretation of following keystrokes
within this invocation of ZLE. Any following invocation (e.g., the next
command line) will start as usual with the `tt(main)' keymap selected.
)
-item(tt(-F) [ tt(-L) ] [ var(fd) [ var(handler) ] ])(
+item(tt(-F) [ tt(-L) | tt(-w) ] [ var(fd) [ var(handler) ] ])(
Only available if your system supports one of the `poll' or `select' system
calls; most modern systems do.
@@ -502,6 +502,13 @@ Note that zle makes no attempt to check whether this fd is actually
readable when installing the handler. The user must make their own
arrangements for handling the file descriptor when zle is not active.
+If the option tt(-w) is also given, the var(handler) is instead a
+line editor widget, typically a shell function made into a widget using
+tt(zle -N). In that case var(handler) can use all the facilities of
+zle to update the current editing line. Note, however, that as handling
+var(fd) takes place at a low level changes to the display will not
+automatically appear; the widget should call tt(zle -R) to force redisplay.
+
Any number of handlers for any number of readable file descriptors may be
installed. Installing a handler for an var(fd) which is already handled
causes the existing handler to be replaced.
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 5798e74..6822230 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -201,6 +201,8 @@ int nwatch; /* Number of fd's we are watching */
int *watch_fds; /* The list of fds, not terminated! */
/**/
char **watch_funcs; /* The corresponding functions to call, normal array */
+/**/
+int *watch_widgets; /* 1 if corresponding function is called as widget */
/* set up terminal */
@@ -725,7 +727,9 @@ raw_getbyte(long do_keytmout, char *cptr)
int lnwatch = nwatch;
int *lwatch_fds = zalloc(lnwatch*sizeof(int));
char **lwatch_funcs = zarrdup(watch_funcs);
+ int *lwatch_widgets = zalloc(lnwatch*sizeof(int));
memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(int));
+ memcpy(lwatch_widgets, watch_widgets, lnwatch*sizeof(int));
for (i = 0; i < lnwatch; i++) {
if (
# ifdef HAVE_POLL
@@ -735,30 +739,37 @@ raw_getbyte(long do_keytmout, char *cptr)
# endif
) {
/* Handle the fd. */
- LinkList funcargs = znewlinklist();
- zaddlinknode(funcargs, ztrdup(lwatch_funcs[i]));
+ char *fdbuf;
{
char buf[BDIGBUFSIZE];
convbase(buf, lwatch_fds[i], 10);
- zaddlinknode(funcargs, ztrdup(buf));
+ fdbuf = ztrdup(buf);
}
+
+ if (lwatch_widgets[i]) {
+ zlecallhook(lwatch_funcs[i], fdbuf);
+ zsfree(fdbuf);
+ } else {
+ LinkList funcargs = znewlinklist();
+ zaddlinknode(funcargs, ztrdup(lwatch_funcs[i]));
+ zaddlinknode(funcargs, fdbuf);
# ifdef HAVE_POLL
# ifdef POLLERR
- if (fds[i+1].revents & POLLERR)
- zaddlinknode(funcargs, ztrdup("err"));
+ if (fds[i+1].revents & POLLERR)
+ zaddlinknode(funcargs, ztrdup("err"));
# endif
# ifdef POLLHUP
- if (fds[i+1].revents & POLLHUP)
- zaddlinknode(funcargs, ztrdup("hup"));
+ if (fds[i+1].revents & POLLHUP)
+ zaddlinknode(funcargs, ztrdup("hup"));
# endif
# ifdef POLLNVAL
- if (fds[i+1].revents & POLLNVAL)
- zaddlinknode(funcargs, ztrdup("nval"));
+ if (fds[i+1].revents & POLLNVAL)
+ zaddlinknode(funcargs, ztrdup("nval"));
# endif
# endif
-
-
- callhookfunc(lwatch_funcs[i], funcargs, 0, NULL);
+ callhookfunc(lwatch_funcs[i], funcargs, 0, NULL);
+ freelinklist(funcargs, freestr);
+ }
if (errflag) {
/* No sensible way of handling errors here */
errflag = 0;
@@ -768,7 +779,6 @@ raw_getbyte(long do_keytmout, char *cptr)
*/
errtry = 1;
}
- freelinklist(funcargs, freestr);
}
}
/* Function may have invalidated the display. */
@@ -1960,7 +1970,7 @@ zle_main_entry(int cmd, va_list ap)
static struct builtin bintab[] = {
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL),
BUILTIN("vared", 0, bin_vared, 1, 1, 0, "aAcef:hi:M:m:p:r:t:", NULL),
- BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNrRTU", NULL),
+ BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNrRTUw", NULL),
};
/* The order of the entries in this table has to match the *HOOK
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 49d715e..78c7918 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -781,7 +781,8 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
if (*args && watch_fds[i] != fd)
continue;
found = 1;
- printf("%s -F %d %s\n", name, watch_fds[i], watch_funcs[i]);
+ printf("%s -F %s%d %s\n", name, watch_widgets[i] ? "-w " : "",
+ watch_fds[i], watch_funcs[i]);
}
/* only return status 1 if fd given and not found */
return *args && !found;
@@ -795,6 +796,7 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
if (watch_fds[i] == fd) {
zsfree(watch_funcs[i]);
watch_funcs[i] = funcnam;
+ watch_widgets[i] = OPT_ISSET(ops,'w') ? 1 : 0;
found = 1;
break;
}
@@ -807,9 +809,12 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
newnwatch * sizeof(int));
watch_funcs = (char **)zrealloc(watch_funcs,
(newnwatch+1) * sizeof(char *));
+ watch_widgets = (int *)zrealloc(watch_widgets,
+ newnwatch * sizeof(int));
watch_fds[nwatch] = fd;
watch_funcs[nwatch] = funcnam;
watch_funcs[newnwatch] = NULL;
+ watch_widgets[nwatch] = OPT_ISSET(ops,'w') ? 1 : 0;
nwatch = newnwatch;
}
} else {
@@ -817,32 +822,39 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
for (i = 0; i < nwatch; i++) {
if (watch_fds[i] == fd) {
int newnwatch = nwatch-1;
- int *new_fds;
+ int *new_fds, *new_widgets;
char **new_funcs;
zsfree(watch_funcs[i]);
if (newnwatch) {
new_fds = zalloc(newnwatch*sizeof(int));
new_funcs = zalloc((newnwatch+1)*sizeof(char*));
+ new_widgets = zalloc(newnwatch*sizeof(int));
if (i) {
memcpy(new_fds, watch_fds, i*sizeof(int));
memcpy(new_funcs, watch_funcs, i*sizeof(char *));
+ memcpy(new_widgets, watch_widgets, i*sizeof(int));
}
if (i < newnwatch) {
memcpy(new_fds+i, watch_fds+i+1,
(newnwatch-i)*sizeof(int));
memcpy(new_funcs+i, watch_funcs+i+1,
(newnwatch-i)*sizeof(char *));
+ memcpy(new_widgets+i, watch_widgets+i+1,
+ (newnwatch-i)*sizeof(int));
}
new_funcs[newnwatch] = NULL;
} else {
new_fds = NULL;
new_funcs = NULL;
+ new_widgets = NULL;
}
zfree(watch_fds, nwatch*sizeof(int));
zfree(watch_funcs, (nwatch+1)*sizeof(char *));
+ zfree(watch_widgets, nwatch*sizeof(int));
watch_fds = new_fds;
watch_funcs = new_funcs;
+ watch_widgets = new_widgets;
nwatch = newnwatch;
found = 1;
break;
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index b84d253..b82e54c 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -1643,7 +1643,7 @@ zlecallhook(char *name, char *arg)
{
Thingy thingy = rthingy_nocreate(name);
int saverrflag, savretflag;
- char *args[3];
+ char *args[2];
if (!thingy)
return;
@@ -1651,9 +1651,8 @@ zlecallhook(char *name, char *arg)
saverrflag = errflag;
savretflag = retflag;
- args[0] = thingy->nam;
- args[1] = arg;
- args[2] = NULL;
+ args[0] = arg;
+ args[1] = NULL;
execzlefunc(thingy, args, 1);
unrefthingy(thingy);
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Fish-like autosuggestions
2013-11-06 21:33 ` Fish-like autosuggestions Peter Stephenson
@ 2013-11-07 0:11 ` Bart Schaefer
2013-11-12 19:46 ` Peter Stephenson
1 sibling, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2013-11-07 0:11 UTC (permalink / raw)
To: Zsh Hackers' List
On Wed, Nov 6, 2013 at 1:33 PM, Peter Stephenson
<p.w.stephenson@ntlworld.com> wrote:
> I've fixed a bug here --- zlecallhook() prepended the thingy name to the
> argument list, but execzlefunc() prepended the function name, too.
> I don't think both can be right --- that gives $0 as the function name,
> $1 as the thingy name, and normal arguments starting at $2.
I've always considered it a bug that we used the name "Thingy" in the
first place.
Nevertheless, I agree with this change. It's pretty unusual for
widgets to examine their argument list anyway.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Fish-like autosuggestions
2013-11-06 21:33 ` Fish-like autosuggestions Peter Stephenson
2013-11-07 0:11 ` Bart Schaefer
@ 2013-11-12 19:46 ` Peter Stephenson
1 sibling, 0 replies; 3+ messages in thread
From: Peter Stephenson @ 2013-11-12 19:46 UTC (permalink / raw)
To: Zsh Hackers' List
On Wed, 6 Nov 2013 21:33:44 +0000
Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> I should really rewrite those three separate arrays to use an array of
> structures.
I hope this doesn't break anything. It does appear to fix one leak.
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index cf44b47..870e214 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -497,3 +497,15 @@ typedef REFRESH_ELEMENT *REFRESH_STRING;
#define METACHECK()
#define UNMETACHECK()
#endif
+
+
+typedef struct watch_fd *Watch_fd;
+
+struct watch_fd {
+ /* Function to call */
+ char *func;
+ /* Watched fd */
+ int fd;
+ /* 1 if func is called as a widget */
+ int widget;
+};
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 6822230..040b7cb 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -197,12 +197,11 @@ static int delayzsetterm;
*/
/**/
int nwatch; /* Number of fd's we are watching */
+/*
+ * Array of nwatch structures.
+ */
/**/
-int *watch_fds; /* The list of fds, not terminated! */
-/**/
-char **watch_funcs; /* The corresponding functions to call, normal array */
-/**/
-int *watch_widgets; /* 1 if corresponding function is called as widget */
+Watch_fd watch_fds;
/* set up terminal */
@@ -588,7 +587,7 @@ raw_getbyte(long do_keytmout, char *cptr)
*/
fds[0].events = POLLIN;
for (i = 0; i < nwatch; i++) {
- fds[i+1].fd = watch_fds[i];
+ fds[i+1].fd = watch_fds[i].fd;
fds[i+1].events = POLLIN;
}
# endif
@@ -613,7 +612,7 @@ raw_getbyte(long do_keytmout, char *cptr)
FD_SET(SHTTY, &foofd);
if (!errtry) {
for (i = 0; i < nwatch; i++) {
- int fd = watch_fds[i];
+ int fd = watch_fds[i].fd;
FD_SET(fd, &foofd);
if (fd > fdmax)
fdmax = fd;
@@ -725,33 +724,33 @@ raw_getbyte(long do_keytmout, char *cptr)
* handler function.
*/
int lnwatch = nwatch;
- int *lwatch_fds = zalloc(lnwatch*sizeof(int));
- char **lwatch_funcs = zarrdup(watch_funcs);
- int *lwatch_widgets = zalloc(lnwatch*sizeof(int));
- memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(int));
- memcpy(lwatch_widgets, watch_widgets, lnwatch*sizeof(int));
+ Watch_fd lwatch_fds = zalloc(lnwatch*sizeof(struct watch_fd));
+ memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(struct watch_fd));
+ for (i = 0; i < lnwatch; i++)
+ lwatch_fds[i].func = ztrdup(lwatch_fds[i].func);
for (i = 0; i < lnwatch; i++) {
+ Watch_fd lwatch_fd = lwatch_fds + i;
if (
# ifdef HAVE_POLL
(fds[i+1].revents & POLLIN)
# else
- FD_ISSET(lwatch_fds[i], &foofd)
+ FD_ISSET(lwatch_fd->fd, &foofd)
# endif
) {
/* Handle the fd. */
char *fdbuf;
{
char buf[BDIGBUFSIZE];
- convbase(buf, lwatch_fds[i], 10);
+ convbase(buf, lwatch_fd->fd, 10);
fdbuf = ztrdup(buf);
}
- if (lwatch_widgets[i]) {
- zlecallhook(lwatch_funcs[i], fdbuf);
+ if (lwatch_fd->widget) {
+ zlecallhook(lwatch_fd->func, fdbuf);
zsfree(fdbuf);
} else {
LinkList funcargs = znewlinklist();
- zaddlinknode(funcargs, ztrdup(lwatch_funcs[i]));
+ zaddlinknode(funcargs, ztrdup(lwatch_fd->func));
zaddlinknode(funcargs, fdbuf);
# ifdef HAVE_POLL
# ifdef POLLERR
@@ -767,7 +766,7 @@ raw_getbyte(long do_keytmout, char *cptr)
zaddlinknode(funcargs, ztrdup("nval"));
# endif
# endif
- callhookfunc(lwatch_funcs[i], funcargs, 0, NULL);
+ callhookfunc(lwatch_fd->func, funcargs, 0, NULL);
freelinklist(funcargs, freestr);
}
if (errflag) {
@@ -784,8 +783,9 @@ raw_getbyte(long do_keytmout, char *cptr)
/* Function may have invalidated the display. */
if (resetneeded)
zrefresh();
- zfree(lwatch_fds, lnwatch*sizeof(int));
- freearray(lwatch_funcs);
+ for (i = 0; i < lnwatch; i++)
+ zsfree(lwatch_fds[i].func);
+ zfree(lwatch_fds, lnwatch*sizeof(struct watch_fd));
}
}
# ifdef HAVE_POLL
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 78c7918..7fd3a59 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -778,11 +778,12 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
return 1;
}
for (i = 0; i < nwatch; i++) {
- if (*args && watch_fds[i] != fd)
+ Watch_fd watch_fd = watch_fds + i;
+ if (*args && watch_fd->fd != fd)
continue;
found = 1;
- printf("%s -F %s%d %s\n", name, watch_widgets[i] ? "-w " : "",
- watch_fds[i], watch_funcs[i]);
+ printf("%s -F %s%d %s\n", name, watch_fd->widget ? "-w " : "",
+ watch_fd->fd, watch_fd->func);
}
/* only return status 1 if fd given and not found */
return *args && !found;
@@ -793,10 +794,11 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
char *funcnam = ztrdup(args[1]);
if (nwatch) {
for (i = 0; i < nwatch; i++) {
- if (watch_fds[i] == fd) {
- zsfree(watch_funcs[i]);
- watch_funcs[i] = funcnam;
- watch_widgets[i] = OPT_ISSET(ops,'w') ? 1 : 0;
+ Watch_fd watch_fd = watch_fds + i;
+ if (watch_fd->fd == fd) {
+ zsfree(watch_fd->func);
+ watch_fd->func = funcnam;
+ watch_fd->widget = OPT_ISSET(ops,'w') ? 1 : 0;
found = 1;
break;
}
@@ -805,56 +807,38 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func))
if (!found) {
/* zrealloc handles NULL pointers, so OK for first time through */
int newnwatch = nwatch+1;
- watch_fds = (int *)zrealloc(watch_fds,
- newnwatch * sizeof(int));
- watch_funcs = (char **)zrealloc(watch_funcs,
- (newnwatch+1) * sizeof(char *));
- watch_widgets = (int *)zrealloc(watch_widgets,
- newnwatch * sizeof(int));
- watch_fds[nwatch] = fd;
- watch_funcs[nwatch] = funcnam;
- watch_funcs[newnwatch] = NULL;
- watch_widgets[nwatch] = OPT_ISSET(ops,'w') ? 1 : 0;
+ Watch_fd new_fd;
+ watch_fds = (Watch_fd)zrealloc(watch_fds,
+ newnwatch * sizeof(struct watch_fd));
+ new_fd = watch_fds + nwatch;
+ new_fd->fd = fd;
+ new_fd->func = funcnam;
+ new_fd->widget = OPT_ISSET(ops,'w') ? 1 : 0;
nwatch = newnwatch;
}
} else {
/* Deleting a handler */
for (i = 0; i < nwatch; i++) {
- if (watch_fds[i] == fd) {
+ Watch_fd watch_fd = watch_fds + i;
+ if (watch_fd->fd == fd) {
int newnwatch = nwatch-1;
- int *new_fds, *new_widgets;
- char **new_funcs;
+ Watch_fd new_fds;
- zsfree(watch_funcs[i]);
+ zsfree(watch_fd->func);
if (newnwatch) {
- new_fds = zalloc(newnwatch*sizeof(int));
- new_funcs = zalloc((newnwatch+1)*sizeof(char*));
- new_widgets = zalloc(newnwatch*sizeof(int));
+ new_fds = zalloc(newnwatch*sizeof(struct watch_fd));
if (i) {
- memcpy(new_fds, watch_fds, i*sizeof(int));
- memcpy(new_funcs, watch_funcs, i*sizeof(char *));
- memcpy(new_widgets, watch_widgets, i*sizeof(int));
+ memcpy(new_fds, watch_fds, i*sizeof(struct watch_fd));
}
if (i < newnwatch) {
memcpy(new_fds+i, watch_fds+i+1,
- (newnwatch-i)*sizeof(int));
- memcpy(new_funcs+i, watch_funcs+i+1,
- (newnwatch-i)*sizeof(char *));
- memcpy(new_widgets+i, watch_widgets+i+1,
- (newnwatch-i)*sizeof(int));
+ (newnwatch-i)*sizeof(struct watch_fd));
}
- new_funcs[newnwatch] = NULL;
} else {
new_fds = NULL;
- new_funcs = NULL;
- new_widgets = NULL;
}
- zfree(watch_fds, nwatch*sizeof(int));
- zfree(watch_funcs, (nwatch+1)*sizeof(char *));
- zfree(watch_widgets, nwatch*sizeof(int));
+ zfree(watch_fds, nwatch*sizeof(struct watch_fd));
watch_fds = new_fds;
- watch_funcs = new_funcs;
- watch_widgets = new_widgets;
nwatch = newnwatch;
found = 1;
break;
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-11-12 20:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <CAAq2XdpaRKOnDe1LBafsq+Ln6wU0_9RL71exrOEyboi1PWcx3w@mail.gmail.com>
[not found] ` <131030092555.ZM8077@torch.brasslantern.com>
[not found] ` <CAAq2Xdos6Xdt-XunRuWToDkoaubwztRP8tesPyByU8CWc3FR=Q@mail.gmail.com>
[not found] ` <131105075700.ZM18043@torch.brasslantern.com>
[not found] ` <20131105161858.543037da@pwslap01u.europe.root.pri>
[not found] ` <131105114640.ZM18224@torch.brasslantern.com>
[not found] ` <131105124000.ZM18277@torch.brasslantern.com>
[not found] ` <20131106200715.6e549a6e@pws-pc.ntlworld.com>
2013-11-06 21:33 ` Fish-like autosuggestions Peter Stephenson
2013-11-07 0:11 ` Bart Schaefer
2013-11-12 19:46 ` Peter Stephenson
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).