-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvs #2
Improvs #2
Conversation
@trappedinspacetime this is some work i had pending but didn't push because i was busy with other stuff. |
Hmmm it may be possible to not use bash, apparently modification of stty settings can be used to read answer sequences, but i'm too smooth brained to understand well what is going on. |
@eylles I'm not a |
It's possible that not understanding stty is actually a sign that your brain is healthy.Back in the olden days, before we had To get a flavour of what we had to do, here's an implementation I wrote in Python: ## See man termios(3) for details on tcgetattr
from termios import *
def terminal_query(seq, delimiter=None, timeout=0.2):
"""
Given an escape SEQuence, and optionally a DELIMITER and a TIMEOUT,
print SEQ to stderr and read a response from stdin until the
character DELIMITER is read or TIMEOUT seconds is reached.
Input that is read is returned to the calling function.
If TIMEOUT is not specified, it default to 0.2.
If DELIMITER is not specified, it defaults to the last character of SEQ.
If neither DELIMITER nor SEQ are specified, then "" is returned.
"""
import sys, copy, posix
if not delimiter and not seq:
return ""
if not seq: seq="" # Allow simply reading from terminal.
# Responses usually end with the same character as the request.
if not delimiter and len(seq)>0:
delimiter=seq[-1]
oldmode = tcgetattr(sys.stdin.fileno())
# tcgetattr returns [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]
[ iflag, oflag, cflag, lflag, ispeed, ospeed, cc ] = oldmode
## CBREAK MODE: Read byte by byte.
## Cbreak is like Raw but allow ^C interrupt signal and does
## not clear OPOST (print newlines as carriage return + newline)
# Do not transmogrify input in any way...
iflag = iflag & ~(INPCK | ISTRIP | IXON | ICRNL | INLCR | IGNCR)
# ... except do allow BREAK (^C) to flush queues and send SIGINT
iflag = (iflag & ~IGNBRK) | BRKINT
lflag = lflag & ~ICANON # Noncanonical: read by bytes, not lines
lflag = lflag & ~ECHO # Do not echo characters received
# Clear character size and disable parity checking
cflag = cflag & ~(CSIZE | PARENB)
cflag = cflag | CS8 # Set 8-bit character size
## Polling read (MIN == 0, TIME == 0) See termios(3).
cc[VMIN] = 0
cc[VTIME] = 0
pollingread = copy.deepcopy([ iflag, oflag, cflag, lflag, ispeed, ospeed, cc ])
## Read with timeout (MIN == 0, TIME > 0) See termios(3).
cc[VMIN] = 0
cc[VTIME] = int(timeout*10+0.5) # Timeout is in tenths of a second
readwithtimeout = copy.deepcopy([ iflag, oflag, cflag, lflag, ispeed, ospeed, cc ])
# Drain stdin in case there's junk from a prev req in there already.
tcsetattr(sys.stdin.fileno(), TCSANOW, pollingread)
while posix.read(sys.stdin.fileno(), 1024):
debugprint(".", end='')
output="" # String of output so far.
c = None # Currently read character.
try:
# Next read() should timeout if no byte becomes available.
tcsetattr(sys.stdin.fileno(), TCSANOW, readwithtimeout)
print(seq, file=stderr, end='', flush=True) # Send Esc seq to terminal
# Accumulate response in 'output' until delimiter or timeout
while c != delimiter:
c = posix.read(sys.stdin.fileno(), 1).decode()
if c:
output=output+c
# debugprint("got", repr(c), "waiting for", repr(delimiter))
else:
debugprint("read() returned 0 characters after", repr(seq))
# Timeout
break
finally:
tcsetattr(sys.stdin.fileno(), TCSANOW, oldmode)
if (debug):
if output:
debugprint("Terminal query received: ", repr(output))
if (c == delimiter):
debugprint("Exited on delimiter", repr(c))
else:
debugprint("Exited after timeout", repr(c))
return(output) While it works, I am thankful that |
this is a branch i was working on trying to add stuff from lsix to have detection of terminal size in cols and pixels, from looking at how it gets the terminal properties.
the change to bash is since i have not found any way to properly query the properties and parse them in pure posix shell, another important this is the need to check the terminal cells and rows against the X and Y pixels to calculate the X and Y pixel density of each cell for proper sixel sizing, also getting the background to properly display the images with montage on a properly colored background.
the commands to detect the properties along some echos to show them:
a lot of this was taken directly from lsix
ideally some of these could be cached to not have the need for constantly queriying the properties on every image.