summaryrefslogtreecommitdiff
path: root/tcvt.py
diff options
context:
space:
mode:
Diffstat (limited to 'tcvt.py')
-rwxr-xr-xtcvt.py66
1 files changed, 50 insertions, 16 deletions
diff --git a/tcvt.py b/tcvt.py
index edb102f..3831a83 100755
--- a/tcvt.py
+++ b/tcvt.py
@@ -315,13 +315,14 @@ class Terminal:
self.lastchar = ord(b' ')
self.columns = columns
self.reverse = reverse
+ self.need_refresh = None
def switchmode(self):
if isinstance(self.screen, Columns):
self.screen = Simple(self.realscreen)
else:
self.screen = Columns(self.realscreen, self.columns)
- self.screen.refresh()
+ self.request_refresh()
def resized(self):
# The refresh call causes curses to notice the new dimensions.
@@ -332,15 +333,32 @@ class Terminal:
reverse=self.reverse)
except BadWidth:
self.screen = Simple(self.realscreen)
+ self.request_refresh()
def resizepty(self, ptyfd):
ym, xm = self.screen.getmaxyx()
fcntl.ioctl(ptyfd, termios.TIOCSWINSZ,
struct.pack("HHHH", ym, xm, 0, 0))
+ def refresh_needed(self):
+ return self.need_refresh is not None
+
+ def request_refresh(self):
+ if self.need_refresh is None:
+ self.need_refresh = time.time()
+
+ def refresh(self, minwait=0):
+ if self.need_refresh is None:
+ return
+ if minwait > 0 and self.need_refresh + minwait > time.time():
+ return
+ self.screen.refresh()
+ self.need_refresh = None
+
def addch(self, char):
self.lastchar = char
self.screen.addch(char)
+ self.request_refresh()
def __enter__(self):
self.realscreen = curses.initscr()
@@ -371,27 +389,32 @@ class Terminal:
def do_cr(self):
self.screen.relmove(0, -9999)
+ self.request_refresh()
def do_cub(self, n):
self.screen.relmove(0, -n)
+ self.request_refresh()
def do_cub1(self):
self.do_cub(1)
def do_cud(self, n):
self.screen.relmove(n, 0)
+ self.request_refresh()
def do_cud1(self):
self.do_cud(1)
def do_cuf(self, n):
self.screen.relmove(0, n)
+ self.request_refresh()
def do_cuf1(self):
self.do_cuf(1)
def do_cuu(self, n):
self.screen.relmove(-n, 0)
+ self.request_refresh()
def do_cuu1(self):
self.do_cuu(1)
@@ -399,6 +422,7 @@ class Terminal:
def do_dch(self, n):
for _ in range(n):
self.screen.delch()
+ self.request_refresh()
def do_dch1(self):
self.do_dch(1)
@@ -406,6 +430,7 @@ class Terminal:
def do_dl(self, n):
for _ in range(n):
self.screen.deleteln()
+ self.request_refresh()
def do_dl1(self):
self.do_dl(1)
@@ -413,39 +438,49 @@ class Terminal:
def do_ech(self, n):
for _ in range(n):
self.screen.addch(ord(b' '))
+ self.request_refresh()
def do_ed(self):
self.screen.clrtobot()
+ self.request_refresh()
def do_el(self):
self.screen.clrtoeol()
+ self.request_refresh()
def do_el1(self):
y, x = self.screen.getyx()
- self.screen.move(y, 0)
- for _ in range(x):
- self.screen.addch(ord(b' '))
+ if x > 0:
+ self.screen.move(y, 0)
+ for _ in range(x):
+ self.screen.addch(ord(b' '))
+ self.request_refresh()
def do_home(self):
self.screen.move(0, 0)
+ self.request_refresh()
def do_hpa(self, n):
y, _ = self.screen.getyx()
self.screen.move(y, n)
+ self.request_refresh()
def do_ht(self):
y, x = self.screen.getyx()
_, xm = self.screen.getmaxyx()
x = min(x + 8 - x % 8, xm - 1)
self.screen.move(y, x)
+ self.request_refresh()
def do_ich(self, n):
for _ in range(n):
self.screen.insch(ord(b' '))
+ self.request_refresh()
def do_il(self, n):
for _ in range(n):
self.screen.insertln()
+ self.request_refresh()
def do_il1(self):
self.do_il(1)
@@ -458,6 +493,7 @@ class Terminal:
self.screen.move(y, 0)
else:
self.screen.move(y+1, 0)
+ self.request_refresh()
def do_invis(self):
self.screen.attron(curses.A_INVIS)
@@ -468,6 +504,7 @@ class Terminal:
def do_vpa(self, n):
_, x = self.screen.getyx()
self.screen.move(n, x)
+ self.request_refresh()
def feed_reset(self):
if self.graphics_font:
@@ -595,14 +632,17 @@ class Terminal:
if len(parts) != 2:
raise ValueError("feed esc [ %r H" % parts)
self.screen.move(*map((-1).__add__, map(int, parts)))
+ self.request_refresh()
elif prev == bytearray(b'2') and char == ord(b'J'):
self.screen.move(0, 0)
self.screen.clrtobot()
+ self.request_refresh()
elif char == ord(b'd') and prev.isdigit():
self.do_vpa(int(prev) - 1)
elif char == ord(b'b') and prev.isdigit():
for _ in range(int(prev)):
self.screen.addch(self.lastchar)
+ self.request_refresh()
elif char == ord(b'G') and prev.isdigit():
self.do_hpa(int(prev) - 1)
elif char == ord(b'K') and prev == b'1':
@@ -705,11 +745,10 @@ def main():
with process as masterfd:
with Terminal(acsc, options.columns, reverse=options.reverse) as t:
t.resizepty(masterfd)
- refreshpending = None
while True:
+ timeout = 0 if t.refresh_needed() else None
try:
- res, _, _ = select.select([0, masterfd], [], [],
- refreshpending and 0)
+ res = select.select([0, masterfd], [], [], timeout)[0]
except select.error as err:
if err.args[0] == errno.EINTR:
t.resized()
@@ -731,6 +770,7 @@ def main():
else:
if "TCVT_DEVEL" in os.environ:
raise ValueError("getch returned %d" % key)
+ t.refresh(0.1)
elif masterfd in res:
try:
data = os.read(masterfd, 1024)
@@ -746,15 +786,9 @@ def main():
t.feed(char)
except ValueError:
t.feed_reset()
- if refreshpending is None:
- refreshpending = time.time() + 0.1
- elif refreshpending is not None:
- t.screen.refresh()
- refreshpending = None
- if refreshpending is not None and \
- refreshpending < time.time():
- t.screen.refresh()
- refreshpending = None
+ t.refresh(0.1)
+ else:
+ t.refresh()
except ExecutionError as err:
print(str(err))
sys.exit(255)