Browse Source

Vim is almost usable using the terminal emulator

pull/161/head
Eugenio Parodi 3 years ago
parent
commit
5f2e5154db
  1. 1
      TermTk/TTkWidgets/TTkTerminal/mode.py
  2. 138
      TermTk/TTkWidgets/TTkTerminal/terminal.py
  3. 70
      TermTk/TTkWidgets/TTkTerminal/terminal_alt.py
  4. 10
      TermTk/TTkWidgets/TTkTerminal/terminal_normal.py
  5. 76
      tests/stupid.ansi.test.sh
  6. 16
      tests/test.input.raw.py
  7. 11
      tests/test.pty.006.terminal.02.py

1
TermTk/TTkWidgets/TTkTerminal/mode.py

@ -21,6 +21,7 @@
# SOFTWARE.
class TTkTerminalModes(int):
DECCKM = 1
# Ps = 1 ⇒ Application Cursor Keys (DECCKM), VT100.
# Ps = 1 ⇒ Normal Cursor Keys (DECCKM), VT100.

138
TermTk/TTkWidgets/TTkTerminal/terminal.py

@ -23,6 +23,8 @@
import os, pty, threading
import struct, fcntl, termios
from dataclasses import dataclass
import re
from select import select
from TermTk.TTkCore.canvas import TTkCanvas
@ -46,6 +48,7 @@ from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.TTkTerminal.terminal_alt import _TTkTerminalAltScreen
from TermTk.TTkWidgets.TTkTerminal.terminal_normal import _TTkTerminalNormalScreen
from TermTk.TTkWidgets.TTkTerminal.mode import TTkTerminalModes
from TermTk.TTkWidgets.TTkTerminal.vt102 import TTkVT102
@ -55,8 +58,13 @@ from TermTk.TTkCore.TTkTerm.colors_ansi_map import ansiMap16, ansiMap256
__all__ = ['TTkTerminal']
class TTkTerminal(TTkWidget):
@dataclass
class _Keyboard():
flags: int = 0
__slots__ = ('_shell', '_fd', '_inout', '_proc', '_quit_pipe', '_mode_normal'
'_buffer_lines', '_buffer_screen',
'_buffer_lines', '_buffer_screen', '_keyboard',
'_screen_current', '_screen_normal', '_screen_alt')
def __init__(self, *args, **kwargs):
self._shell = os.environ.get('SHELL', 'sh')
@ -64,6 +72,7 @@ class TTkTerminal(TTkWidget):
self._proc = None
self._mode_normal = True
self._quit_pipe = None
self._keyboard = TTkTerminal._Keyboard()
self._buffer_lines = [TTkString()]
self._screen_normal = _TTkTerminalNormalScreen()
self._screen_alt = _TTkTerminalAltScreen()
@ -93,6 +102,7 @@ class TTkTerminal(TTkWidget):
# termios.tcsetwinsize(self._fd,(h,w))
self._screen_alt.resize(w,h)
self._screen_normal.resize(w,h)
TTkLog.info(f"Resize Terminal: {w=} {h=}")
return super().resizeEvent(w, h)
def runShell(self, program=None):
@ -118,6 +128,8 @@ class TTkTerminal(TTkWidget):
self._quit_pipe = os.pipe()
threading.Thread(target=self.loop,args=[self]).start()
w,h = self.size()
self.resizeEvent(w,h)
# xterm escape sequences from:
# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
@ -148,12 +160,24 @@ class TTkTerminal(TTkWidget):
if r is not self._inout:
continue
try:
out = self._inout.read(10240)
_fl = fcntl.fcntl(self._inout, fcntl.F_GETFL)
fcntl.fcntl(self._inout, fcntl.F_SETFL, _fl | os.O_NONBLOCK) # Set the input as NONBLOCK to read the full sequence
out = b""
while _out := self._inout.read():
out += _out
fcntl.fcntl(self._inout, fcntl.F_SETFL, _fl)
except Exception as e:
TTkLog.error(f"Error: {e=}")
return
# out = out.decode('utf-8','ignore')
out = out.decode()
try:
out = out.decode()
except Exception as e:
TTkLog.error(f"{e=}")
TTkLog.error(f"Failed to decode {out}")
out = out.decode('utf-8','ignore')
for bi, bout in enumerate(out.split('\a')): # grab the bells
# TTkLog.debug(f'Eugenio->{out}')
# sout = bout.decode('utf-8','ignore')
@ -229,10 +253,11 @@ class TTkTerminal(TTkWidget):
slice = slice[en:]
elif m:
en = m.end()
y = ps = int(y) if (y:=m.group(2)) else 1
sep = m.group(3)
x = int(x) if (x:=m.group(4)) else 1
fn = m.group(5)
defval = self._CSI_Default_MAP.get(fn,(1,1))
y = ps = int(y) if (y:=m.group(2)) else defval[0]
sep = m.group(3)
x = int(x) if (x:=m.group(4)) else defval[1]
TTkLog.debug(f"{mg[0]}{fn} = ps:{y=} {sep=} {x=} {fn=}")
if fn in ['n']:
_ex = self._CSI_MAP.get(
@ -276,6 +301,13 @@ class TTkTerminal(TTkWidget):
# TTkLog.debug(f"Key: {evt.code=}")
TTkLog.debug(f"Key: {str(evt)=}")
if evt.type == TTkK.SpecialKey:
if self._keyboard.flags & TTkTerminalModes.DECCKM:
if code := {TTkK.Key_Up: b"\033OA",
TTkK.Key_Down: b"\033OB",
TTkK.Key_Right: b"\033OC",
TTkK.Key_Left: b"\033OD"}.get(evt.key):
self._inout.write(code)
return True
if evt.key == TTkK.Key_Enter:
TTkLog.debug(f"Key: Enter")
# self._inout.write(b'\n')
@ -290,6 +322,17 @@ class TTkTerminal(TTkWidget):
w,h = self.size()
self._screen_current.paintEvent(canvas,w,h)
# This map include the default values in case Ps or Row/Col are empty
# Since almost all the CSI use 1 as default, I am including here only
# the ones that are different
_CSI_Default_MAP = {
'J' : (0,None),
'K' : (0,None)
}
# CSI Ps n Device Status Report (DSR).
# Ps = 5 ⇒ Status Report.
# Result ("OK") is CSI 0 n
@ -321,20 +364,83 @@ class TTkTerminal(TTkWidget):
'n': _CSI_n_DSR,
}
def _CSI_DEC_SET_RST(self, ps, s):
_dec = self._CSI_DEC_SET_RST_MAP.get(
ps,
lambda a,b: TTkLog.warn(f"Unhandled DEC <ESC>[{ps}{'h' if s else 'l'}"))
_dec(self, s)
# CSI ? Pm h
# DEC Private Mode Set (DECSET).
# Ps = 1 ⇒ Application Cursor Keys (DECCKM), VT100.
# UP = \0330A
# DOWN = \0330B
# LEFT = \0330C
# RIGHT = \0330D
# CSI ? Pm l
# DEC Private Mode Reset (DECRST).
# Ps = 1 ⇒ Normal Cursor Keys (DECCKM), VT100.
# UP = \033[A
# DOWN = \033[B
# LEFT = \033[C
# RIGHT = \033[D
def _CSI_DEC_SR_1_DECCKM(self, s):
if s:
self._keyboard.flags |= TTkTerminalModes.DECCKM
else:
self._keyboard.flags &= ~TTkTerminalModes.DECCKM
# CSI ? Pm h
# DEC Private Mode Set (DECSET).
# Ps = 2 5 ⇒ Show cursor (DECTCEM), VT220.
# CSI ? Pm l
# DEC Private Mode Reset (DECRST).
# Ps = 2 5 ⇒ Hide cursor (DECTCEM), VT220.
def _CSI_DEC_SR_25(self, s):
def _CSI_DEC_SR_25_DECTCEM(self, s):
self.enableWidgetCursor(enable=s)
# CSI ? Pm h
# DEC Private Mode Set (DECSET).
# Ps = 1 0 0 2 ⇒ Use Cell Motion Mouse Tracking, xterm. See
# the section Button-event tracking.
# CSI ? Pm l
# DEC Private Mode Reset (DECRST).
# Ps = 1 0 0 2 ⇒ Don't use Cell Motion Mouse Tracking,
# xterm. See the section Button-event tracking.
def _CSI_DEC_SR_1002(self, s):
pass
# CSI ? Pm h
# DEC Private Mode Set (DECSET).
# Ps = 1 0 4 7 ⇒ Use Alternate Screen Buffer, xterm. This
# may be disabled by the titeInhibit resource.
# CSI ? Pm l
# DEC Private Mode Reset (DECRST).
# Ps = 1 0 4 7 ⇒ Use Normal Screen Buffer, xterm. Clear the
# screen first if in the Alternate Screen Buffer. This may be
# disabled by the titeInhibit resource.
def _CSI_DEC_SR_1047(self, s):
if s:
self._screen_current = self._screen_alt
else:
self._screen_current = self._screen_normal
# CSI ? Pm h
# DEC Private Mode Set (DECSET).
# Ps = 1 0 4 8 ⇒ Save cursor as in DECSC, xterm. This may
# be disabled by the titeInhibit resource.
# CSI ? Pm l
# DEC Private Mode Reset (DECRST).
# Ps = 1 0 4 8 ⇒ Restore cursor as in DECRC, xterm. This
# may be disabled by the titeInhibit resource.
def _CSI_DEC_SR_1048(self, s):
pass
# CSI ? Pm h
# DEC Private Mode Set (DECSET).
# Ps = 1 0 4 9 ⇒ Save cursor as in DECSC, xterm. After
@ -349,13 +455,21 @@ class TTkTerminal(TTkWidget):
# 8 modes. Use this with terminfo-based applications rather
# than the 4 7 mode.
def _CSI_DEC_SR_1049(self, s):
if s:
self._screen_current = self._screen_alt
else:
self._screen_current = self._screen_normal
self._CSI_DEC_SR_1047(s)
self._CSI_DEC_SR_1048(s)
# CSI ? Pm h
# DEC Private Mode Set (DECSET).
# Ps = 2 0 0 4 ⇒ Set bracketed paste mode, xterm.
# CSI ? Pm l
# DEC Private Mode Reset (DECRST).
# Ps = 2 0 0 4 ⇒ Reset bracketed paste mode, xterm.
def _CSI_DEC_SR_2004(self, s):
pass
_CSI_DEC_SET_RST_MAP = {
25 : _CSI_DEC_SR_25,
1 : _CSI_DEC_SR_1_DECCKM,
25 : _CSI_DEC_SR_25_DECTCEM,
1047: _CSI_DEC_SR_1047,
1049: _CSI_DEC_SR_1049
}

70
TermTk/TTkWidgets/TTkTerminal/terminal_alt.py

@ -39,12 +39,15 @@ from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView, TTkAbst
from TermTk.TTkWidgets.widget import TTkWidget
class _TTkTerminalAltScreen():
__slots__ = ('_lines', '_terminalCursor', '_w', '_h', '_color', '_canvas')
__slots__ = ('_lines', '_terminalCursor',
'_scrollingRegion',
'_w', '_h', '_color', '_canvas')
def __init__(self, w=80, h=24, color=TTkColor.RST) -> None:
self._lines = [TTkString()]
self._terminalCursor = (0,0)
self._w = w
self._h = h
self._scrollingRegion = (0,h)
self._color = color
self._canvas = TTkCanvas(width=w, height=h)
@ -55,8 +58,15 @@ class _TTkTerminalAltScreen():
return self._terminalCursor
def resize(self, w, h):
self._w = w
self._h = h
ow, oh = self._w, self._h
self._w, self._h = w, h
st,sb = self._scrollingRegion
# if oh <= h: # Terminal height decreasing
# sb = min(h,oh)
# else:# Terminal height increasing
# sb = h-oh+sb
self._scrollingRegion = (st,sb)
self._scrollingRegion = (1,h)
newCanvas = TTkCanvas(width=w, height=h)
s = (0,0,w,h)
newCanvas.paintCanvas(self._canvas,s,s,s)
@ -195,9 +205,9 @@ class _TTkTerminalAltScreen():
x,y = self._terminalCursor
w,h = self._w,self._h
if ps == 0:
self._canvas.fill(char=' ', pos=(0,y),size=(x,1))
elif ps == 1:
self._canvas.fill(char=' ', pos=(x,y),size=(w,1))
elif ps == 1:
self._canvas.fill(char=' ', pos=(0,y),size=(x,1))
elif ps == 2:
self._canvas.fill(char=' ', pos=(0,y),size=(w,1))
@ -208,7 +218,22 @@ class _TTkTerminalAltScreen():
# Ps = 2 ⇒ Selective Erase All.
# CSI Ps L Insert Ps Line(s) (default = 1) (IL).
# def _CSI_L_IL(self, ps, _): pass
def _CSI_L_IL(self, ps, _):
x,y = self._terminalCursor
t,b = self._scrollingRegion
w,h = self._w, self._h
bkl = h-b
l = len(self._canvas._data)
#TODO: Avoid this HACK
baseData = [' ']*w
baseColors = [TTkColor.RST]*w
bkData = self._canvas._data[-bkl:]
bkColors = self._canvas._colors[-bkl:]
self._canvas._data[y:y] = [baseData.copy() for _ in range(ps)]
self._canvas._colors[y:y] = [baseColors.copy() for _ in range(ps)]
self._canvas._data = self._canvas._data[:h-bkl] + bkData
self._canvas._colors = self._canvas._colors[:h-bkl] + bkColors
# CSI Ps M Delete Ps Line(s) (default = 1) (DL).
# def _CSI_M_DL(self, ps, _): pass
@ -1084,6 +1109,8 @@ class _TTkTerminalAltScreen():
# CSI Ps ; Ps r
# Set Scrolling Region [top;bottom] (default = full size of
# window) (DECSTBM), VT100.
def _CSI_r_DECSTBM(self, top, bottom):
self._scrollingRegion = (top-1, bottom-1)
# CSI ? Pm r
# Restore DEC Private Mode Values (XTRESTORE), xterm. The value
@ -1448,21 +1475,21 @@ class _TTkTerminalAltScreen():
# Ps = 2 ⇒ host-writable.
_CSI_MAP = {
'@': _CSI___ICH,
# '@': _CSI___SL,
'A': _CSI_A_CUU,
# 'A': _CSI_A_SR,
'B': _CSI_B_CUD,
'C': _CSI_C_CUF,
'D': _CSI_D_CUB,
'E': _CSI_E_CNL,
'F': _CSI_F_CPL,
'G': _CSI_G_CHA,
'H': _CSI_H_CUP,
'@': _CSI___ICH, # CSI Ps @ Insert Ps (Blank) Character(s) (default = 1) (ICH).
# '@': _CSI___SL, #
'A': _CSI_A_CUU, # CSI Ps A Cursor Up Ps Times (default = 1) (CUU).
# 'A': _CSI_A_SR, #
'B': _CSI_B_CUD, # CSI Ps B Cursor Down Ps Times (default = 1) (CUD).
'C': _CSI_C_CUF, # CSI Ps C Cursor Forward Ps Times (default = 1) (CUF).
'D': _CSI_D_CUB, # CSI Ps D Cursor Backward Ps Times (default = 1) (CUB).
'E': _CSI_E_CNL, # CSI Ps E Cursor Next Line Ps Times (default = 1) (CNL).
'F': _CSI_F_CPL, # CSI Ps F Cursor Preceding Line Ps Times (default = 1) (CPL).
'G': _CSI_G_CHA, # CSI Ps G Cursor Character Absolute [column] (default = [row,1]) (CHA).
'H': _CSI_H_CUP, # CSI Ps ; Ps H Cursor Position [row;column] (default = [1,1]) (CUP).
# 'I': _CSI_I_CHT,
'J': _CSI_J_ED,
'K': _CSI_K_EL,
# 'L': _CSI_L_IL,
'J': _CSI_J_ED, # CSI Ps J Erase in Display (ED), VT100. [0:Below, 1:Above, 2:All, 3:SavedLines]
'K': _CSI_K_EL, # CSI Ps K Erase in Line (EL), VT100. [0:Right, 1:Left, 2:All]
'L': _CSI_L_IL, # CSI Ps L Insert Ps Line(s) (default = 1) (IL).
# 'M': _CSI_M_DL,
# 'P': _CSI_P_DCH,
# 'S': _CSI_S_SU,
@ -1476,7 +1503,7 @@ class _TTkTerminalAltScreen():
# 'c': _CSI_c_Pri_DA,
# 'd': _CSI_d_VPA,
# 'e': _CSI_e_VPR,
'f': _CSI_f_HVP,
'f': _CSI_f_HVP, # CSI Ps ; Ps f Horizontal and Vertical Position [row;column] (default = [1,1]) (HVP).
# 'g': _CSI_g_TBC,
# 'h': _CSI_h_SM,
# 'i': _CSI_i_MC,
@ -1484,6 +1511,7 @@ class _TTkTerminalAltScreen():
# 'm': _CSI_m_SGR,
# 'n': _CSI_n_DSR,
# 'q': _CSI_q_DECLL,
'r': _CSI_r_DECSTBM, # CSI Ps ; Ps r Set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM), VT100.
# 's': _CSI_s_SCOSC,
# 'u': _CSI_u_SCORC,
# 'x': _CSI_x_DECREQTPARM

10
TermTk/TTkWidgets/TTkTerminal/terminal_normal.py

@ -197,11 +197,11 @@ class _TTkTerminalNormalScreen():
l = len(self._lines)
# y = max(0,y-l-h)
if ps == 0:
self._lines[y+1:] = [TTkString()]*(l-y-1)
self._lines[y] = self._lines[y].substring(to=x)
elif ps == 1:
self._lines[-h:y-1] = [TTkString()]*(y-1-l+h)
self._lines[y] = TTkString(' '*x) + self._lines[y].substring(fr=x)
elif ps == 1:
self._lines[y+1:] = [TTkString()]*(l-y-1)
self._lines[y] = self._lines[y].substring(to=x)
elif ps == 2:
self._lines[-h:] = [TTkString()]*(h)
@ -220,9 +220,9 @@ class _TTkTerminalNormalScreen():
x,y = self._terminalCursor
line = self._lines[y]
if ps == 0:
self._lines[y] = TTkString(' '*x) + self._lines[y].substring(fr=x)
elif ps == 1:
self._lines[y] = line.substring(to=x)
elif ps == 1:
self._lines[y] = TTkString(' '*x) + self._lines[y].substring(fr=x)
elif ps == 2:
self._lines[y] = TTkString()

76
tests/stupid.ansi.test.sh

@ -2,39 +2,45 @@
echo -n -e "\033[2J\033[0;0H"
echo "(0, 0) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 0) n o p q r s t u v w x y z A B C D E F G H (100, 0) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 1) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 1) n o p q r s t u v w x y z A B C D E F G H (100, 1) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 2) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 2) n o p q r s t u v w x y z A B C D E F G H (100, 2) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 3) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 3) n o p q r s t u v w x y z A B C D E F G H (100, 3) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 4) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 4) n o p q r s t u v w x y z A B C D E F G H (100, 4) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 5) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 5) n o p q r s t u v w x y z A B C D E F G H (100, 5) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 6) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 6) n o p q r s t u v w x y z A B C D E F G H (100, 6) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 7) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 7) n o p q r s t u v w x y z A B C D E F G H (100, 7) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 8) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 8) n o p q r s t u v w x y z A B C D E F G H (100, 8) I J K L M N O P Q R S T U V W X Y Z"
echo "(0, 9) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 9) n o p q r s t u v w x y z A B C D E F G H (100, 9) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,10) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,10) n o p q r s t u v w x y z A B C D E F G H (100,10) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,11) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,11) n o p q r s t u v w x y z A B C D E F G H (100,11) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,12) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,12) n o p q r s t u v w x y z A B C D E F G H (100,12) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,13) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,13) n o p q r s t u v w x y z A B C D E F G H (100,13) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,14) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,14) n o p q r s t u v w x y z A B C D E F G H (100,14) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,15) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,15) n o p q r s t u v w x y z A B C D E F G H (100,15) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,16) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,16) n o p q r s t u v w x y z A B C D E F G H (100,16) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,17) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,17) n o p q r s t u v w x y z A B C D E F G H (100,17) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,18) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,18) n o p q r s t u v w x y z A B C D E F G H (100,18) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,19) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,19) n o p q r s t u v w x y z A B C D E F G H (100,19) I J K L M N O P Q R S T U V W X Y Z"
echo "(0,20) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,20) n o p q r s t u v w x y z A B C D E F G H (100,20) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,21) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,21) n o p q r s t u v w x y z A B C D E F G H (100,21) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,22) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,22) n o p q r s t u v w x y z A B C D E F G H (100,22) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,23) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,23) n o p q r s t u v w x y z A B C D E F G H (100,23) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,24) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,24) n o p q r s t u v w x y z A B C D E F G H (100,24) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,25) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,25) n o p q r s t u v w x y z A B C D E F G H (100,25) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,26) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,26) n o p q r s t u v w x y z A B C D E F G H (100,26) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,27) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,27) n o p q r s t u v w x y z A B C D E F G H (100,27) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,28) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,28) n o p q r s t u v w x y z A B C D E F G H (100,28) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,29) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,29) n o p q r s t u v w x y z A B C D E F G H (100,29) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,30) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,30) n o p q r s t u v w x y z A B C D E F G H (100,30) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,31) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,31) n o p q r s t u v w x y z A B C D E F G H (100,31) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,32) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,32) n o p q r s t u v w x y z A B C D E F G H (100,32) I J K L M N O P Q R S T U V W X Y Z"
# echo "(0,33) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,33) n o p q r s t u v w x y z A B C D E F G H (100,33) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[1;1H" "(0, 0) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 0) n o p q r s t u v w x y z A B C D E F G H (100, 0) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[2;1H" "(0, 1) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 1) n o p q r s t u v w x y z A B C D E F G H (100, 1) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[3;1H" "(0, 2) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 2) n o p q r s t u v w x y z A B C D E F G H (100, 2) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[4;1H" "(0, 3) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 3) n o p q r s t u v w x y z A B C D E F G H (100, 3) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[5;1H" "(0, 4) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 4) n o p q r s t u v w x y z A B C D E F G H (100, 4) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[6;1H" "(0, 5) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 5) n o p q r s t u v w x y z A B C D E F G H (100, 5) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[7;1H" "(0, 6) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 6) n o p q r s t u v w x y z A B C D E F G H (100, 6) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[8;1H" "(0, 7) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 7) n o p q r s t u v w x y z A B C D E F G H (100, 7) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[9;1H" "(0, 8) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 8) n o p q r s t u v w x y z A B C D E F G H (100, 8) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[10;1H" "(0, 9) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50, 9) n o p q r s t u v w x y z A B C D E F G H (100, 9) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[11;1H" "(0,10) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,10) n o p q r s t u v w x y z A B C D E F G H (100,10) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[12;1H" "(0,11) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,11) n o p q r s t u v w x y z A B C D E F G H (100,11) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[13;1H" "(0,12) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,12) n o p q r s t u v w x y z A B C D E F G H (100,12) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[14;1H" "(0,13) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,13) n o p q r s t u v w x y z A B C D E F G H (100,13) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[15;1H" "(0,14) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,14) n o p q r s t u v w x y z A B C D E F G H (100,14) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[16;1H" "(0,15) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,15) n o p q r s t u v w x y z A B C D E F G H (100,15) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[17;1H" "(0,16) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,16) n o p q r s t u v w x y z A B C D E F G H (100,16) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[18;1H" "(0,17) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,17) n o p q r s t u v w x y z A B C D E F G H (100,17) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[19;1H" "(0,18) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,18) n o p q r s t u v w x y z A B C D E F G H (100,18) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[20;1H" "(0,19) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,19) n o p q r s t u v w x y z A B C D E F G H (100,19) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[21;1H" "(0,20) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,20) n o p q r s t u v w x y z A B C D E F G H (100,20) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[22;1H" "(0,21) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,21) n o p q r s t u v w x y z A B C D E F G H (100,21) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[23;1H" "(0,22) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,22) n o p q r s t u v w x y z A B C D E F G H (100,22) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[24;1H" "(0,23) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,23) n o p q r s t u v w x y z A B C D E F G H (100,23) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[25;1H" "(0,24) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,24) n o p q r s t u v w x y z A B C D E F G H (100,24) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[26;1H" "(0,25) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,25) n o p q r s t u v w x y z A B C D E F G H (100,25) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[27;1H" "(0,26) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,26) n o p q r s t u v w x y z A B C D E F G H (100,26) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[28;1H" "(0,27) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,27) n o p q r s t u v w x y z A B C D E F G H (100,27) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[29;1H" "(0,28) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,28) n o p q r s t u v w x y z A B C D E F G H (100,28) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[30;1H" "(0,29) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,29) n o p q r s t u v w x y z A B C D E F G H (100,29) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[31;1H" "(0,30) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,30) n o p q r s t u v w x y z A B C D E F G H (100,30) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[32;1H" "(0,31) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,31) n o p q r s t u v w x y z A B C D E F G H (100,31) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[33;1H" "(0,32) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,32) n o p q r s t u v w x y z A B C D E F G H (100,32) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[34;1H" "(0,33) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,33) n o p q r s t u v w x y z A B C D E F G H (100,33) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[35;1H" "(0,34) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,34) n o p q r s t u v w x y z A B C D E F G H (100,34) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[36;1H" "(0,35) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,35) n o p q r s t u v w x y z A B C D E F G H (100,35) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[37;1H" "(0,36) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,36) n o p q r s t u v w x y z A B C D E F G H (100,36) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[38;1H" "(0,37) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,37) n o p q r s t u v w x y z A B C D E F G H (100,37) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[39;1H" "(0,38) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,38) n o p q r s t u v w x y z A B C D E F G H (100,38) I J K L M N O P Q R S T U V W X Y Z"
echo -n -e "\033[40;1H" "(0,39) 1 2 3 4 5 6 7 8 9 0 a b c d e f g j k l m (50,39) n o p q r s t u v w x y z A B C D E F G H (100,39) I J K L M N O P Q R S T U V W X Y Z"
echo -e "abcdefg--->\033[10;50H<-Eugenio->\033[${1}${2}${3}${4}${5}${6}${7}<----hijklm\n\n\n\n"
echo -n -e "abcdefg--->\033[10;50H<-Eugenio->\033[${1}${2}${3}${4}${5}${6}${7}<----hijklm"

16
tests/test.input.raw.py

@ -22,7 +22,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import sys, os, select
import sys, os, select, signal
import logging
try: import fcntl, termios, tty
@ -31,10 +31,10 @@ except Exception as e:
exit(1)
sys.path.append(os.path.join(sys.path[0],'..'))
from TermTk import TTkLog, TTkK, TTkInput, TTkTerm
from TermTk import TTkTerm
TTkLog.info("Retrieve Keyboard, Mouse press/drag/wheel Events")
TTkLog.info("Press q or <ESC> to exit")
print("Retrieve Keyboard, Mouse press/drag/wheel Events")
print("Press q or <ESC> to exit")
TTkTerm.push(TTkTerm.Mouse.ON)
# TTkTerm.push(TTkTerm.Mouse.DIRECT_ON)
@ -44,6 +44,12 @@ TTkTerm.setEcho(False)
_attr = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin)
# Capture Terminal Resize:
def _sigwinch(a,b):
print(f"SIGWINCH: {os.get_terminal_size()=} {a=} {b=}")
signal.signal(signal.SIGWINCH, _sigwinch)
def read():
rlist, _, _ = select.select( [sys.stdin], [], [] )
@ -74,7 +80,7 @@ def read_new():
else:
for ch in stdinRead:
yield ch
# print("--->\033[?1h<---")
try:
for stdinRead in read_new():
print(f"{stdinRead=}")

11
tests/test.pty.006.terminal.02.py

@ -41,20 +41,25 @@ import os
import pty
import sys
import threading
import argparse
from select import select
sys.path.append(os.path.join(sys.path[0],'..'))
import TermTk as ttk
ttk.TTkLog.use_default_file_logging()
parser = argparse.ArgumentParser()
parser.add_argument('-d', help='Debug (Add LogViewer Panel)', action='store_true')
args = parser.parse_args()
# ttk.TTkLog.use_default_file_logging()
root = ttk.TTk(layout=ttk.TTkGridLayout())
split = ttk.TTkSplitter(parent=root, orientation=ttk.TTkK.VERTICAL)
split.addItem(top := ttk.TTkLayout())
split.addWidget(ttk.TTkLogViewer(follow=False ), title='Log', size=20)
if args.d:
split.addWidget(ttk.TTkLogViewer(follow=False ), title='Log', size=20)
quitBtn = ttk.TTkButton(text="QUIT", border=True)
quitBtn.clicked.connect(ttk.TTkHelper.quit)

Loading…
Cancel
Save