xterm improvements/hacks

--HG--
branch : pmacs2
This commit is contained in:
moculus 2009-03-15 02:36:27 +00:00
parent ad8eac608f
commit 399f00b7ee
3 changed files with 107 additions and 17 deletions

View File

@ -16,7 +16,7 @@ class XTermBuffer(Buffer, XTerm):
self.modename = modename self.modename = modename
XTerm.__init__(self) XTerm.__init__(self)
Buffer.__init__(self) Buffer.__init__(self)
#self.debug = True
self.application = app self.application = app
self._name = name or '*XTerm*' self._name = name or '*XTerm*'
self._pid, self._pty = pty.fork() self._pid, self._pty = pty.fork()
@ -47,6 +47,12 @@ class XTermBuffer(Buffer, XTerm):
self.insert_string(p, s, act=ACT_NONE, force=True) self.insert_string(p, s, act=ACT_NONE, force=True)
else: else:
self.overwrite_char(p, s, act=ACT_NONE, force=True) self.overwrite_char(p, s, act=ACT_NONE, force=True)
def term_do_newline(self):
XTerm.term_do_newline(self)
#p = w.logical_cursor()
#self.insert_string(p, "XYZ", act=ACT_NONE, force=True)
def term_do_style(self, s):
pass
def term_do_clear(self): def term_do_clear(self):
self.set_lines([''], force=True) self.set_lines([''], force=True)
def term_do_home(self): def term_do_home(self):

View File

@ -31,18 +31,18 @@ class Exec(Method):
if not os.WIFEXITED(result): if not os.WIFEXITED(result):
err = True err = True
errmsg = "%s: killed by signal %r" % (cmdname, os.WTERMSIG(result)) msg = "%s: killed by signal %r" % (cmdname, os.WTERMSIG(result))
elif status != 0: elif status != 0:
err = True err = True
errmsg = "%s: failed with status %r" % (cmdname, status) msg = "%s: failed with status %r" % (cmdname, status)
else: else:
err = False err = False
errmsg = "%s: ok" % (cmdname,) msg = "%s: ok" % (cmdname,)
if output: if output:
switch_to = err or self.show_success switch_to = err or self.show_success
w.application.data_buffer(bufname, output, switch_to=switch_to) w.application.data_buffer(bufname, output, switch_to=switch_to)
w.set_error(errmsg) w.set_error(msg)
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
if w.buffer.btype == 'dir': if w.buffer.btype == 'dir':
@ -77,10 +77,10 @@ class Man(Exec):
err = False err = False
errmsg = "man: ok" errmsg = "man: ok"
if output: if output:
xterm = term.XTerm() xterm = term.XTerm(cbuf=True)
output = xterm.term_filter(output) output = xterm.term_filter(output)
switch_to = err or self.show_success switch_to = err or self.show_success
w.application.data_buffer('*Manpage*', output, switch_to=switch_to) w.application.color_data_buffer('*Manpage*', output, switch_to=switch_to)
w.set_error(errmsg) w.set_error(errmsg)
class Pipe(Method): class Pipe(Method):

98
term.py
View File

@ -10,8 +10,27 @@ def show(c):
else: else:
return '\\%03o' % ord(c) return '\\%03o' % ord(c)
cbuffer_map = {
'black': 'B',
'blue': 'b',
'cyan': 'c',
'default': 'd',
'green': 'g',
'magenta': 'm',
'red': 'r',
'white': 'w',
'yellow': 'y',
}
def make_cbuf(fg, bg, xt):
#return '[%r, %r, %r]' % (fg, bg, xt)
if 'bold' in xt:
return '[%s:%s:*]' % (cbuffer_map[fg], cbuffer_map[bg])
else:
return '[%s:%s]' % (cbuffer_map[fg], cbuffer_map[bg])
class Dumb: class Dumb:
name = 'dumb' name = 'dumb'
cbuf = False
def _term_insert(self, s): def _term_insert(self, s):
assert self.i <= len(self.outc) assert self.i <= len(self.outc)
if self.i == len(self.outc): if self.i == len(self.outc):
@ -24,16 +43,20 @@ class Dumb:
self.outs = '' self.outs = ''
self.i = 0 self.i = 0
self.outc = [] self.outc = []
if self.cbuf: self._term_insert(make_cbuf(self._fg, self._bg, self._xt))
def term_do_clear_bol(self): def term_do_clear_bol(self):
pass pass
def term_do_clear_eol(self): def term_do_clear_eol(self):
del self.outc[self.i:] del self.outc[self.i:]
if self.cbuf: self._term_insert(make_cbuf(self._fg, self._bg, self._xt))
def term_do_clear_eos(self): def term_do_clear_eos(self):
pass pass
def term_do_home(self): def term_do_home(self):
self.outs = '' self.outs = ''
self.i = 0 self.i = 0
self.outc = [] self.outc = []
if self.cbuf: self._term_insert(make_cbuf(self._fg, self._bg, self._xt))
def term_do_backspace(self): def term_do_backspace(self):
self.i = max(0, self.i - 1) self.i = max(0, self.i - 1)
@ -43,6 +66,7 @@ class Dumb:
self.outs += ''.join(self.outc) + '\n' self.outs += ''.join(self.outc) + '\n'
self.i = 0 self.i = 0
self.outc = [] self.outc = []
if self.cbuf: self._term_insert(make_cbuf(self._fg, self._bg, self._xt))
def term_do_creturn(self): def term_do_creturn(self):
self.i = 0 self.i = 0
def term_do_esc(self, c): def term_do_esc(self, c):
@ -103,9 +127,10 @@ class XTerm(Dumb):
num_re = re.compile('^([a-zA-Z0-9]+)#(.+)$') num_re = re.compile('^([a-zA-Z0-9]+)#(.+)$')
str_re = re.compile('^([a-zA-Z0-9]+)=(.+)$') str_re = re.compile('^([a-zA-Z0-9]+)=(.+)$')
style_re = re.compile('^\033[[0-9;]+m') style_re = re.compile(r'^\033\[[0-9;]+m')
text_signal_re = re.compile('^\033][0-9]+;.+\007') #style_re = re.compile(r'^\033\[1m')
cup_re = re.compile('^\033\[[0-9]+;[0-9]+H') text_signal_re = re.compile(r'^\033\][0-9]+;.+\007')
cup_re = re.compile(r'^\033\[[0-9]+;[0-9]+H')
callbacks = { callbacks = {
'clear': 'term_do_clear', 'clear': 'term_do_clear',
@ -135,10 +160,16 @@ class XTerm(Dumb):
'ed': 'term_do_clear_eos', 'ed': 'term_do_clear_eos',
'el': 'term_do_clear_eol', 'el': 'term_do_clear_eol',
#'el1': 'term_nop', #'el1': 'term_nop',
} }
def __init__(self): def __init__(self, cbuf=False):
self.debug = False self.debug = False
self.cbuf = cbuf
# style info
self._fg = 'default'
self._bg = 'default'
self._xt = set()
self._meta = [] self._meta = []
f = os.popen('infocmp %s' % self.termtype, 'r') f = os.popen('infocmp %s' % self.termtype, 'r')
self.sequences = {} self.sequences = {}
@ -153,10 +184,58 @@ class XTerm(Dumb):
m = self.str_re.match(field) m = self.str_re.match(field)
assert m, "huh?? %r" % field assert m, "huh?? %r" % field
name, val = m.groups() name, val = m.groups()
if val.startswith('\\E'): if val.startswith('\\E['):
continue
elif val.startswith('\\E'):
self.sequences[val.replace('\\E', '\033')] = name self.sequences[val.replace('\\E', '\033')] = name
f.close() f.close()
def parse_style(self, s):
# starts with '\033[' and ends with 'm'
s2 = s[2:-1]
l = s2.split(';')
#if s2 not in ('0', '22', '1'):
# raise Exception("l = %r" % l)
for n in l:
if n == '0':
self._fg = 'default'
self._bg = 'default'
self._xt = set()
# xtra attributes
elif n == '1': self._xt.add('bold')
elif n == '3': self._xt.add('italic')
elif n == '4': self._xt.add('underline')
elif n == '7': self._xt.add('inverse')
elif n == '9': self._xt.add('strike')
elif n == '22': self._xt.discard('bold')
elif n == '23': self._xt.discard('italic')
elif n == '24': self._xt.discard('underline')
elif n == '27': self._xt.discard('inverse')
elif n == '29': self._xt.discard('strike')
# foreground
elif n == '30': self._fg = 'black'
elif n == '31': self._fg = 'red'
elif n == '32': self._fg = 'green'
elif n == '33': self._fg = 'yellow'
elif n == '34': self._fg = 'blue'
elif n == '35': self._fg = 'magenta'
elif n == '36': self._fg = 'cyan'
elif n == '37': self._fg = 'white'
elif n == '39': self._fg = 'default'
# background
elif n == '40': self._bg = 'black'
elif n == '41': self._bg = 'red'
elif n == '42': self._bg = 'green'
elif n == '43': self._bg = 'yellow'
elif n == '44': self._bg = 'blue'
elif n == '45': self._bg = 'magenta'
elif n == '46': self._bg = 'cyan'
elif n == '47': self._bg = 'white'
elif n == '49': self._bg = 'default'
def term_do_style(self):
if self.cbuf: self._term_insert(make_cbuf(self._fg, self._bg, self._xt))
def term_nop(self, *args): def term_nop(self, *args):
pass pass
def term_filter(self, s): def term_filter(self, s):
@ -174,7 +253,7 @@ class XTerm(Dumb):
self._meta = self._meta[3:] self._meta = self._meta[3:]
if self._meta[0] != '\x1b': if self._meta[0] != '\x1b':
for c2 in self._meta[:-1]: for c2 in self._meta[:-1]:
Dumb.term_handle(self, c) Dumb.term_handle(self, c2)
self._meta = [] self._meta = []
if self._meta: if self._meta:
s = ''.join(self._meta) s = ''.join(self._meta)
@ -191,6 +270,11 @@ class XTerm(Dumb):
if name not in ['home']: if name not in ['home']:
self._meta = [] self._meta = []
elif self.style_re.match(s): elif self.style_re.match(s):
#raise Exception('%r %d' % (s, len(s)))
self.parse_style(s)
self.term_do_style()
#if s == '\x1b[1m': raise("ARGH %r" % self.outc)
#if s == '\x1b[1m': raise("ARGH %r" % [self.outc, self._fg, self._bg, self._xt])
self._meta = [] self._meta = []
elif self.text_signal_re.match(s): elif self.text_signal_re.match(s):
self._meta = [] self._meta = []