From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: Zsh Hackers' List <zsh-workers@zsh.org>
Subject: Re: Fish-like autosuggestions
Date: Wed, 6 Nov 2013 21:33:44 +0000 [thread overview]
Message-ID: <20131106213344.3e9bea64@pws-pc.ntlworld.com> (raw)
In-Reply-To: <20131106200715.6e549a6e@pws-pc.ntlworld.com>
(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/
next parent reply other threads:[~2013-11-06 21:59 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[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 ` Peter Stephenson [this message]
2013-11-07 0:11 ` Bart Schaefer
2013-11-12 19:46 ` Peter Stephenson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131106213344.3e9bea64@pws-pc.ntlworld.com \
--to=p.w.stephenson@ntlworld.com \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).