22

Is it possible to use zsh's built-in line editor (zle) to feed input to a subprocess? That is, I would like to run zlewrap mycommand where zlewrap is a zsh function and mycommand is any program that just reads lines from stdin; zlewrap would effectively provide zle's line-editing capabilities to mycommand. This is on the model of rlwrap which does just this, but with readline and not zle for line editing.

6
  • 2
    This looks helpful: zsh.org/mla/users/2004/msg00917.html . It's not as easy as a single command, but you can adapt this script to your program (read the follow-ups for corrections).
    – imgx64
    Jan 7, 2011 at 7:58
  • One problem I have when I think of solutions is how do you indicate when you want to be 'editing' in the ZLE and when you want to be waiting for the 'mycommand' to return? Does it only ever return one line?
    – polynomial
    Aug 27, 2011 at 2:42
  • 2
    @polynomial wrappers like this return one line at a time to the process behind them. Use of rlwrap is quite widespread and you've probably used it. Think about the little pseudo shell things you get in things like mysql, sqlite, lftp, etc. They all have some implementation of a line editor that returns on line or block of lines at a time to the actual processor behind them. rlwrap does hits quite neatly for any program that accepts STDIN, but it would be nice to have zle style bindings and abilities rather than readlines which are someone less extensive.
    – Caleb
    Jan 7, 2012 at 23:26
  • Have you looked at the manual for zsh - cs.elte.hu/zsh-manual/zsh_14.html? - I don't quite understand your question, but Googled the title, and found that page. It might help, but I don't know.
    – Kevdog777
    Aug 22, 2012 at 8:33
  • 1
    Ok, I was just trying to help, as I see your question hasn't been answered in over a year. Sorry my comment wasn't good enough.
    – Kevdog777
    Aug 22, 2012 at 12:04

1 Answer 1

4

Here is how you can do it if using GNU screen:

Put a file called zf in your $PATH with:

#! /usr/bin/env zsh
zmodload -i zsh/zle
trap 'printf "\03"; exit' INT
HISTSIZE=100
while a=; vared -p "${2:-zle> }" -eh a; do
{
  s=$(stty -g)
  stty -echo -iexten -isig lnext '' werase '' eof '' rprnt '' kill ''
  printf "%s\r" "$a"
  print -rs -- "$a"
  stty "$s"
} < $1
done
printf "\04"

And then, run the filter in screen as

<Ctrl-A>:exec .!. zf /dev/pts/x "> "

Replace /dev/pts/x with the actual Windows pty (output of tty command in the window), and "> " with the prompt to display.

There will be occasional display glitches as both zsh and the application will write to the terminal in an unconcerted way.

Original at http://www.zsh.org/mla/users/2005/msg00186.html

1
  • Any chance of some explanation of how this works? What does ".!." mean? Why does it need to be run in screen?
    – Ben
    Aug 31, 2020 at 20:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .