You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello, here is a suggestion: it would be nice if picotui used stderr for I/O, and not stdin+stdout.
Why? that would free stdio and stdout for other application-specific things: the app can get its input from stdin and write result to stdout, unix-way, and it would allow to use picotui-base app in unix pipes: echo "input-data" | picotui-app | consumer
I'm doing exactly that in my picotui-based app, and it works great.
Here's the code I had to add to make it work (thanks to python, no need to modify picotui code, can just patch it):
from picotui.screen import Screen
#################################################################################
# Start patching picotui to use STDERR (FD 2)
#################################################################################
FD_IN = 2
FD_OUT = 2
import os
def wr(*args):
s = args[-1]
# TODO: When Python is 3.5, update this to use only bytes
if isinstance(s, str):
s = bytes(s, "utf-8")
os.write(FD_OUT, s)
from picotui.basewidget import Widget
from picotui.defs import KEYMAP as _KEYMAP
def get_input(self):
if self.kbuf:
key = self.kbuf[0:1]
self.kbuf = self.kbuf[1:]
else:
key = os.read(FD_IN, 32)
if key[0] != 0x1b:
key = key.decode()
self.kbuf = key[1:].encode()
key = key[0:1].encode()
key = _KEYMAP.get(key, key)
if isinstance(key, bytes) and key.startswith(b"\x1b[M") and len(key) == 6:
row = key[5] - 33
col = key[4] - 33
return [col, row]
return key
def screen_size(*args):
import select
wr(b"\x1b[18t")
res = select.select([FD_IN], [], [], 0.2)[0]
if not res:
return (80, 24)
resp = os.read(FD_IN, 32)
assert resp.startswith(b"\x1b[8;") and resp[-1:] == b"t"
vals = resp[:-1].split(b";")
return (int(vals[2]), int(vals[1]))
def init_tty(*args):
import tty, termios
global ttyattr
ttyattr = termios.tcgetattr(FD_IN)
tty.setraw(FD_IN)
def deinit_tty(*args):
import termios
termios.tcsetattr(FD_IN, termios.TCSANOW, ttyattr)
def patch_picotui():
Screen.wr = wr
Screen.init_tty = init_tty
Screen.deinit_tty = deinit_tty
Screen.screen_size = screen_size
Widget.get_input = get_input
#################################################################################
# End patching picotui
#################################################################################
.. that's it, just introduced constants instead of hard-coded FD 0 and 1
The text was updated successfully, but these errors were encountered:
Thanks for the feedback and suggestion. I'll keep it in mind, but arguments for doing it like that would be that it's customary to do it at all. Do other TUI applications do it like that? Does curses lib do it like that by default?
As a random quick test, I tried Midnight Commander with:
mc >/dev/null
That doesn't produce any output, so it clearly does TUI operations on stdout.
I agree, by very nature TUI must interact with console. Most likely, there are no conventions on FD usage for TUI.
In shell, FD 0 and 1 can participate in pipe, and 2 cannot be piped, and supposed to be attached to "debug console".
Anyway, if you would just introduce constants FD_IN=0 and FD_OUT=1, so that it behaves the same way and give the possibility to modify them and attach to different FD - that would be really nice
Anyway, if you would just introduce constants FD_IN=0 and FD_OUT=1
I'll keep that in mind. I have a queue of things I'd like to do, including to that part of the code, so it may need to wait some time, but I'm not against it in principle.
pfalcon
changed the title
Suggestion: use stderr for I/O, or meake it configurable
Suggestion: use stderr for I/O, or make it configurable
Jan 31, 2021
Hello, here is a suggestion: it would be nice if picotui used stderr for I/O, and not stdin+stdout.
Why? that would free stdio and stdout for other application-specific things: the app can get its input from stdin and write result to stdout, unix-way, and it would allow to use picotui-base app in unix pipes:
echo "input-data" | picotui-app | consumer
I'm doing exactly that in my picotui-based app, and it works great.
Here's the code I had to add to make it work (thanks to python, no need to modify picotui code, can just patch it):
.. that's it, just introduced constants instead of hard-coded FD 0 and 1
The text was updated successfully, but these errors were encountered: