Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Ramblings about read -c / read -l



Just something I stumbled on while looking at something else:

torch% thingy() { typeset -g theline; read -l theline; return 1 }
torch% zle -C thingy complete-word thingy
torch% ls 
thingy:read: option valid only in functions called from completion

That error message is a bit misleading -- it hasn't changed since compctl
was the one and only way to perform completion.

Curious, I looked through the related code in compctl.c and compcore.c
and noticed that compctl.c seems to prevent "read -c" during a call from
a compcore.c completion widget *unless* a compctl action is implicitly
invoked via "zle complete-word" or similar.  I don't suppose anyone
remembers why this is?  ("git blame" is useless for code this old; there
seeems to have been some squashing of commits when importing from CVS.)

I tried fiddling with allowing "read -c" to be called directly from a
"zle -C" widget and it seems to work OK, though obviously it's not really
needed given access to the various special variables.  However, I didn't
test its interaction with "compset" state-frobbing, so perhaps that's
where potential problems lie.

I have some other half-formed concerns about the way compctl.c manages
global variables given that widgets can call other widgets (or make
recursive calls) with the "zle" builtin, but obviously it's been years
without anyone running into such a thing, so ...

One other observation: Nothing would prevent a module other than compctl
from assigning to compcltreadptr and thereby providing entirely new
semantics for "read -[cln]".  For that matter, a module other than zle
could set the zle_entry_ptr global and plug in a whole new line editor.

Suggested patch for the error message follows, but I don't plan to
commit it before PWS releases 5.0.3.


diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index ab1857c..2563095 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -193,7 +193,7 @@ compctlread(char *name, char **args, Options ops, char *reply)
 
     /* only allowed to be called for completion */
     if (!incompctlfunc) {
-	zwarnnam(name, "option valid only in functions called for completion");
+	zwarnnam(name, "option valid only in functions called via compctl");
 	return 1;
     }
 
diff --git a/Src/init.c b/Src/init.c
index 53c4fbd..fa074ea 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1522,7 +1522,7 @@ mod_export CompctlReadFn compctlreadptr = fallback_compctlread;
 mod_export int
 fallback_compctlread(char *name, UNUSED(char **args), UNUSED(Options ops), UNUSED(char *reply))
 {
-    zwarnnam(name, "option valid only in functions called from completion");
+    zwarnnam(name, "no loaded module provides read for completion context");
     return 1;
 }
 



Messages sorted by: Reverse Date, Date, Thread, Author