-
Notifications
You must be signed in to change notification settings - Fork 71
Open
Labels
Description
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
Reactions are currently unavailable