Conversation
|
I'm now thinking twice about the
This means the shell is perfectly willing to call readline for non-TTY input if you give it This is not obviously the correct behavior: bash, rc, and dash do the same thing, but fish doesn't use its interactive input logic here, zsh seems to just ignore the redirection entirely, and elvish's With this PR and #263, the behavior would be:
The last bit is the distinction; instead of checking for stdin, we check for Technically I think it would work to turn the Another alternative would be to just have
Technically, both of these could be added simultaneously; the former is (IMO) the best way to get a So, I guess after all this rambling, here's what I want: |
Also do a better job at handling errors setting up the fds for readline.
This PR creates a new primitive
$&readlinewhich performs the same readline logic as the shell. It takes one argument which it uses as the prompt, and it reads exactly one line of input, with the same basic return semantics as$&read-- a single string containing a single line of input, or the empty list on an immediate EOF.$&readlinealways calls the readline library. Logic around "if we're reading from a TTY, then$&readline; otherwise,$&read" is out of scope for this PR, but something like$&isattycan be added to make that check later.$&readlinerespects redirections, settingrl_instreamandrl_outstreamtofdmap(0)andfdmap(2). Something interesting to note is that apparently readline prints everything to its stdout by default. This PR changes that to stderr for the$&readlineprimitive, for better consistency with existing shells and es' own non-readline behavior. As a side note: it is, I think, a good sign that moving this behavior to a primitive makes these kinds of behaviors more explicit. It's also possible to change back to stdout with a simple>[2=1]!The obvious deficiency with
$&readlineas it is now is that it is really only designed to work as shell input. Somebody trying to read some random text is probably not going to be helped by variable or primitive completion, for example. Improving$&readline's ability to act as non-shell-input is something I'd like to take a stab at in a follow-up.One question is: why a new
$&readlineprimitive, rather than, say, extending$&read? That comes down to how we model optional behaviors. I think the ideal way to model libraries in es is for them to add additional primitives, which can be tied into the system using normal scripting behavior. This is already how$&limit,$&time,$&readfromand$&writeto,$&execfailure, and the readline-related primitives work now. Actually, if someone wanted a combined read/readline%readwith this PR, I think the best way to do that would be viafn-%read = $&readline.