Read /dev/tty from within a completion function
Clash Royale CLAN TAG#URR8PPP
up vote
3
down vote
favorite
Why is the following code not working for completion of the foo
command? When I source it then type foo <Tab>
, the shell hangs and doesn't take any input until I press ^C
(which exits the command completion).
My hypothesis is that /dev/tty
is already being read by the shell and it somehow messes with cat
being able to read from it as well, but in that case I still need a workaround.
_foo()
_values 'foo' "$(cat < /dev/tty)"
compdef _foo foo
Note that this example is deliberately simplified: the actual use case is running a terminal interface program (think ncurses) instead of cat
.
zsh autocomplete
add a comment |Â
up vote
3
down vote
favorite
Why is the following code not working for completion of the foo
command? When I source it then type foo <Tab>
, the shell hangs and doesn't take any input until I press ^C
(which exits the command completion).
My hypothesis is that /dev/tty
is already being read by the shell and it somehow messes with cat
being able to read from it as well, but in that case I still need a workaround.
_foo()
_values 'foo' "$(cat < /dev/tty)"
compdef _foo foo
Note that this example is deliberately simplified: the actual use case is running a terminal interface program (think ncurses) instead of cat
.
zsh autocomplete
1
What are you trying to achieve with this particular completion?
â mik
Jan 23 at 21:49
1
I just want to implement my own completion UI. I already have the ncurses GUI binary implemented, it works when I call it from the regular shell (even when its input is a pipe or it's invoked from a subshell, in which case I just open /dev/tty myself), the only issue is when used with completion.
â Nison Maël
Jan 23 at 21:52
Note that zsh has builtin ncurses support in itszsh/curses
module.
â Stéphane Chazelas
Jan 29 at 17:13
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
Why is the following code not working for completion of the foo
command? When I source it then type foo <Tab>
, the shell hangs and doesn't take any input until I press ^C
(which exits the command completion).
My hypothesis is that /dev/tty
is already being read by the shell and it somehow messes with cat
being able to read from it as well, but in that case I still need a workaround.
_foo()
_values 'foo' "$(cat < /dev/tty)"
compdef _foo foo
Note that this example is deliberately simplified: the actual use case is running a terminal interface program (think ncurses) instead of cat
.
zsh autocomplete
Why is the following code not working for completion of the foo
command? When I source it then type foo <Tab>
, the shell hangs and doesn't take any input until I press ^C
(which exits the command completion).
My hypothesis is that /dev/tty
is already being read by the shell and it somehow messes with cat
being able to read from it as well, but in that case I still need a workaround.
_foo()
_values 'foo' "$(cat < /dev/tty)"
compdef _foo foo
Note that this example is deliberately simplified: the actual use case is running a terminal interface program (think ncurses) instead of cat
.
zsh autocomplete
asked Jan 23 at 20:49
Nison Maël
18114
18114
1
What are you trying to achieve with this particular completion?
â mik
Jan 23 at 21:49
1
I just want to implement my own completion UI. I already have the ncurses GUI binary implemented, it works when I call it from the regular shell (even when its input is a pipe or it's invoked from a subshell, in which case I just open /dev/tty myself), the only issue is when used with completion.
â Nison Maël
Jan 23 at 21:52
Note that zsh has builtin ncurses support in itszsh/curses
module.
â Stéphane Chazelas
Jan 29 at 17:13
add a comment |Â
1
What are you trying to achieve with this particular completion?
â mik
Jan 23 at 21:49
1
I just want to implement my own completion UI. I already have the ncurses GUI binary implemented, it works when I call it from the regular shell (even when its input is a pipe or it's invoked from a subshell, in which case I just open /dev/tty myself), the only issue is when used with completion.
â Nison Maël
Jan 23 at 21:52
Note that zsh has builtin ncurses support in itszsh/curses
module.
â Stéphane Chazelas
Jan 29 at 17:13
1
1
What are you trying to achieve with this particular completion?
â mik
Jan 23 at 21:49
What are you trying to achieve with this particular completion?
â mik
Jan 23 at 21:49
1
1
I just want to implement my own completion UI. I already have the ncurses GUI binary implemented, it works when I call it from the regular shell (even when its input is a pipe or it's invoked from a subshell, in which case I just open /dev/tty myself), the only issue is when used with completion.
â Nison Maël
Jan 23 at 21:52
I just want to implement my own completion UI. I already have the ncurses GUI binary implemented, it works when I call it from the regular shell (even when its input is a pipe or it's invoked from a subshell, in which case I just open /dev/tty myself), the only issue is when used with completion.
â Nison Maël
Jan 23 at 21:52
Note that zsh has builtin ncurses support in its
zsh/curses
module.â Stéphane Chazelas
Jan 29 at 17:13
Note that zsh has builtin ncurses support in its
zsh/curses
module.â Stéphane Chazelas
Jan 29 at 17:13
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
0
down vote
This is probably too simplified, cat
will read from /dev/tty
for a good long while. With a _foo
completion of
#compdef foo
_values 'foo' "$(promptfor)"
and a promptfor
of
#!/usr/bin/env expect
set fh [open /dev/tty r+]
stty raw -echo
set key [read $fh 1] ;# read from tty
puts stdout $key ;# to ZSH
flush stdout
stty -raw echo
my ZSH on foo
tab will then complete whatever key is then pressed while promptfor
runs.
If you have a daemon of sorts sitting around, then you'll probably need something fancier like a socket that ZSH and your daemon can use to carry out any necessary communications; read
in ZSH can read from an arbitrary file descriptor or coprocess...
add a comment |Â
up vote
0
down vote
During completion, you're in the zsh line editor, so the terminal line discipline's own line editor is disabled as if you had run:
stty -icanon -echo
In that mode, cat
cannot exit as there's no way you can signify it the end of input (^D
is part of the icanon
line discipline's line editor behaviour) and you won't see the echo of what you type.
You could do:
_foo()
_values 'foo' "$(
s=$(stty -g)
stty sane
cat
stty $s
< /dev/tty)"
zle -I
That is, put the terminal device in the state expected by cat
(where you can press ^D
on an empty line or twice to end the input) before running cat
and restore it afterwards. And we tell zle it has to redraw its prompt and buffer as the echo of what you'd type within the line discipline line editor would mess things up (zle -I
to invalidate).
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
This is probably too simplified, cat
will read from /dev/tty
for a good long while. With a _foo
completion of
#compdef foo
_values 'foo' "$(promptfor)"
and a promptfor
of
#!/usr/bin/env expect
set fh [open /dev/tty r+]
stty raw -echo
set key [read $fh 1] ;# read from tty
puts stdout $key ;# to ZSH
flush stdout
stty -raw echo
my ZSH on foo
tab will then complete whatever key is then pressed while promptfor
runs.
If you have a daemon of sorts sitting around, then you'll probably need something fancier like a socket that ZSH and your daemon can use to carry out any necessary communications; read
in ZSH can read from an arbitrary file descriptor or coprocess...
add a comment |Â
up vote
0
down vote
This is probably too simplified, cat
will read from /dev/tty
for a good long while. With a _foo
completion of
#compdef foo
_values 'foo' "$(promptfor)"
and a promptfor
of
#!/usr/bin/env expect
set fh [open /dev/tty r+]
stty raw -echo
set key [read $fh 1] ;# read from tty
puts stdout $key ;# to ZSH
flush stdout
stty -raw echo
my ZSH on foo
tab will then complete whatever key is then pressed while promptfor
runs.
If you have a daemon of sorts sitting around, then you'll probably need something fancier like a socket that ZSH and your daemon can use to carry out any necessary communications; read
in ZSH can read from an arbitrary file descriptor or coprocess...
add a comment |Â
up vote
0
down vote
up vote
0
down vote
This is probably too simplified, cat
will read from /dev/tty
for a good long while. With a _foo
completion of
#compdef foo
_values 'foo' "$(promptfor)"
and a promptfor
of
#!/usr/bin/env expect
set fh [open /dev/tty r+]
stty raw -echo
set key [read $fh 1] ;# read from tty
puts stdout $key ;# to ZSH
flush stdout
stty -raw echo
my ZSH on foo
tab will then complete whatever key is then pressed while promptfor
runs.
If you have a daemon of sorts sitting around, then you'll probably need something fancier like a socket that ZSH and your daemon can use to carry out any necessary communications; read
in ZSH can read from an arbitrary file descriptor or coprocess...
This is probably too simplified, cat
will read from /dev/tty
for a good long while. With a _foo
completion of
#compdef foo
_values 'foo' "$(promptfor)"
and a promptfor
of
#!/usr/bin/env expect
set fh [open /dev/tty r+]
stty raw -echo
set key [read $fh 1] ;# read from tty
puts stdout $key ;# to ZSH
flush stdout
stty -raw echo
my ZSH on foo
tab will then complete whatever key is then pressed while promptfor
runs.
If you have a daemon of sorts sitting around, then you'll probably need something fancier like a socket that ZSH and your daemon can use to carry out any necessary communications; read
in ZSH can read from an arbitrary file descriptor or coprocess...
answered Jan 24 at 0:14
thrig
22.3k12852
22.3k12852
add a comment |Â
add a comment |Â
up vote
0
down vote
During completion, you're in the zsh line editor, so the terminal line discipline's own line editor is disabled as if you had run:
stty -icanon -echo
In that mode, cat
cannot exit as there's no way you can signify it the end of input (^D
is part of the icanon
line discipline's line editor behaviour) and you won't see the echo of what you type.
You could do:
_foo()
_values 'foo' "$(
s=$(stty -g)
stty sane
cat
stty $s
< /dev/tty)"
zle -I
That is, put the terminal device in the state expected by cat
(where you can press ^D
on an empty line or twice to end the input) before running cat
and restore it afterwards. And we tell zle it has to redraw its prompt and buffer as the echo of what you'd type within the line discipline line editor would mess things up (zle -I
to invalidate).
add a comment |Â
up vote
0
down vote
During completion, you're in the zsh line editor, so the terminal line discipline's own line editor is disabled as if you had run:
stty -icanon -echo
In that mode, cat
cannot exit as there's no way you can signify it the end of input (^D
is part of the icanon
line discipline's line editor behaviour) and you won't see the echo of what you type.
You could do:
_foo()
_values 'foo' "$(
s=$(stty -g)
stty sane
cat
stty $s
< /dev/tty)"
zle -I
That is, put the terminal device in the state expected by cat
(where you can press ^D
on an empty line or twice to end the input) before running cat
and restore it afterwards. And we tell zle it has to redraw its prompt and buffer as the echo of what you'd type within the line discipline line editor would mess things up (zle -I
to invalidate).
add a comment |Â
up vote
0
down vote
up vote
0
down vote
During completion, you're in the zsh line editor, so the terminal line discipline's own line editor is disabled as if you had run:
stty -icanon -echo
In that mode, cat
cannot exit as there's no way you can signify it the end of input (^D
is part of the icanon
line discipline's line editor behaviour) and you won't see the echo of what you type.
You could do:
_foo()
_values 'foo' "$(
s=$(stty -g)
stty sane
cat
stty $s
< /dev/tty)"
zle -I
That is, put the terminal device in the state expected by cat
(where you can press ^D
on an empty line or twice to end the input) before running cat
and restore it afterwards. And we tell zle it has to redraw its prompt and buffer as the echo of what you'd type within the line discipline line editor would mess things up (zle -I
to invalidate).
During completion, you're in the zsh line editor, so the terminal line discipline's own line editor is disabled as if you had run:
stty -icanon -echo
In that mode, cat
cannot exit as there's no way you can signify it the end of input (^D
is part of the icanon
line discipline's line editor behaviour) and you won't see the echo of what you type.
You could do:
_foo()
_values 'foo' "$(
s=$(stty -g)
stty sane
cat
stty $s
< /dev/tty)"
zle -I
That is, put the terminal device in the state expected by cat
(where you can press ^D
on an empty line or twice to end the input) before running cat
and restore it afterwards. And we tell zle it has to redraw its prompt and buffer as the echo of what you'd type within the line discipline line editor would mess things up (zle -I
to invalidate).
answered Jan 29 at 17:10
Stéphane Chazelas
281k53518849
281k53518849
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f419179%2fread-dev-tty-from-within-a-completion-function%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
What are you trying to achieve with this particular completion?
â mik
Jan 23 at 21:49
1
I just want to implement my own completion UI. I already have the ncurses GUI binary implemented, it works when I call it from the regular shell (even when its input is a pipe or it's invoked from a subshell, in which case I just open /dev/tty myself), the only issue is when used with completion.
â Nison Maël
Jan 23 at 21:52
Note that zsh has builtin ncurses support in its
zsh/curses
module.â Stéphane Chazelas
Jan 29 at 17:13