more advanced line edition

This commit is contained in:
Mattias Andrée 2012-10-30 19:14:21 +01:00
parent 51858104cd
commit 98f584257b

View file

@ -82,12 +82,12 @@ class PonysayTool():
print('\033[?1049h', end='') # initialise terminal print('\033[?1049h', end='') # initialise terminal
if linuxvt: print('\033[?8c', end='') # use full block for cursor (_ is used by default in linux vt) if linuxvt: print('\033[?8c', end='') # use full block for cursor (_ is used by default in linux vt)
cmd = 'stty %s < %s > /dev/null 2> /dev/null' cmd = 'stty %s < %s > /dev/null 2> /dev/null'
cmd %= ('-echo -icanon -isig', os.path.realpath('/dev/stdout')) cmd %= ('-echo -icanon -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait() Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
self.editmeta(pony) self.editmeta(pony)
finally: finally:
cmd = 'stty %s < %s > /dev/null 2> /dev/null' cmd = 'stty %s < %s > /dev/null 2> /dev/null'
cmd %= ('echo icanon isig', os.path.realpath('/dev/stdout')) cmd %= ('echo icanon isig ixoff ixon', os.path.realpath('/dev/stdout'))
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait() Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
if linuxvt: print('\033[?0c', end='') # restore cursor if linuxvt: print('\033[?0c', end='') # restore cursor
print('\033[?1049l', end='') # terminate terminal print('\033[?1049l', end='') # terminate terminal
@ -211,9 +211,9 @@ class PonysayTool():
data['comment'] = '\n'.join(comment) data['comment'] = '\n'.join(comment)
fields = [key for key in data] fields = [key for key in data]
fields.sort() fields.sort()
standardfields = ['GROUP NAME', 'NAME', 'OTHER NAMES', 'APPEARANCE', 'KIND', standardfields = ['GROUP NAME', 'NAME', 'OTHER NAMES', 'APPEARANCE', 'KIND', 'GROUP',
'GROUP', 'BALLOON', 'LINK', 'LINK ON', 'COAT', 'MANE', 'EYE', 'BALLOON', 'LINK', 'LINK ON', 'COAT', 'MANE', 'EYE', 'AURA', 'DISPLAY',
'AURA', 'DISPLAY', 'MASTER', 'SOURCE', 'MEDIA', 'comment'] 'MASTER', 'SOURCE', 'MEDIA', 'FREE', 'comment']
for standard in standardfields: for standard in standardfields:
if standard in fields: if standard in fields:
del fields[fields.index(standard)] del fields[fields.index(standard)]
@ -298,36 +298,123 @@ class TextArea:
y += 1 y += 1
(termh, termw) = self.termsize (termh, termw) = self.termsize
(y, x) = (0, 0)
mark = None
def status(text): def status(text):
print('\033[%i;%iH\033[7m%s\033[0m' % (termh - 1, 1, ' (' + text + ') ' + '-' * (termw - len(' (' + text + ') '))), end='') print('\033[%i;%iH\033[7m%s\033[27m\033[%i;%iH' % (termh - 1, 1, ' (' + text + ') ' + '-' * (termw - len(' (' + text + ') ')), self.top + y, innerleft + x), end='')
status('unmodified') status('unmodified')
print('\033[%i;%iH' % (self.top, innerleft), end='') print('\033[%i;%iH' % (self.top, innerleft), end='')
(y, x) = (0, 0)
def alert(text): def alert(text):
print('\033[%i;%iH\033[2K%s\033[%i;%iH' % (termh, 1, text, self.top + y, innerleft + x), end='') if text is None:
alert('')
else:
print('\033[%i;%iH\033[2K%s\033[%i;%iH' % (termh, 1, text, self.top + y, innerleft + x), end='')
modified = False
override = False
(oldy, oldx, oldmark) = (y, x, mark)
stored = None
alerted = False alerted = False
edited = False
while True: while True:
if (oldmark is not None) and (oldmark >= 0):
if oldmark < oldx:
print('\033[%i;%iH\033[49m%s\033[%i;%iH' % (self.top + oldy, innerleft + oldmark, datalines[y][oldmark : oldx], self.top + y, innerleft + x), end='')
elif oldmark > oldx:
print('\033[%i;%iH\033[49m%s\033[%i;%iH' % (self.top + oldy, innerleft + oldx, datalines[y][oldx : oldmark], self.top + y, innerleft + x), end='')
if (mark is not None) and (mark >= 0):
if mark < x:
print('\033[%i;%iH\033[44m%s\033[49m\033[%i;%iH' % (self.top + y, innerleft + mark, datalines[y][mark : x], self.top + y, innerleft + x), end='')
elif mark > x:
print('\033[%i;%iH\033[44m%s\033[49m\033[%i;%iH' % (self.top + y, innerleft + x, datalines[y][x : mark], self.top + y, innerleft + x), end='')
(oldy, oldx, oldmark) = (y, x, mark)
if edited:
edited = False
if not modified:
modified = True
status('modified' + (' override' if override else ''))
sys.stdout.flush() sys.stdout.flush()
d = sys.stdin.read(1) if stored is None:
d = sys.stdin.read(1)
else:
d = stored
stored = None
if alerted: if alerted:
alerted = False alerted = False
alert('') alert(None)
if (ord(d) == 127) or (ord(d) == 8): if ord(d) == ord('@') - ord('@'):
if mark is None:
mark = x
alert('Mark set')
elif mark == ~x:
mark = x
alert('Mark activated')
elif mark == x:
mark = ~x
alert('Mark deactivated')
else:
mark = x
alert('Mark set')
elif ord(d) == ord('X') - ord('@'):
alert('C-x')
alerted = True
sys.stdout.flush()
d = sys.stdin.read(1)
alert(str(ord(d)))
sys.stdout.flush()
if ord(d) == ord('X') - ord('@'):
if (mark is not None) and (mark >= 0):
x ^= mark; mark ^= x; x ^= mark
alert('Mark swapped')
else:
alert('No mark is activated')
elif ord(d) == ord('S') - ord('@'):
# TODO saver()
status('unmodified' + (' override' if override else ''))
alert('Saved')
elif ord(d) == ord('C') - ord('@'):
break
else:
stored = d
alerted = False
alert(None)
elif (ord(d) == 127) or (ord(d) == 8):
removed = 1
if (mark is not None) and (mark >= 0) and (mark != x):
if mark > x:
x ^= mark; mark ^= x; x ^= mark
removed = x - mark
if x == 0: if x == 0:
alert('At beginning') alert('At beginning')
alerted = True alerted = True
continue continue
dataline = datalines[y] dataline = datalines[y]
datalines[y] = dataline = dataline[:x - 1] + dataline[x:] datalines[y] = dataline = dataline[:x - removed] + dataline[x:]
x -= 1 x -= removed
print('\033[%i;%iH%s \033[%i;%iH' % (self.top + y, innerleft, dataline, self.top + y, innerleft + x), end='') mark = None
print('\033[%i;%iH%s%s\033[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * removed, self.top + y, innerleft + x), end='')
edited = True
elif ord(d) < ord(' '): elif ord(d) < ord(' '):
if d == '\033': if ord(d) == ord('F') - ord('@'):
if x < len(datalines[y]):
x += 1
print('\033[C', end='')
else:
alert('At end')
alerted = True
elif ord(d) == ord('B') - ord('@'):
if x > 0:
x -= 1
print('\033[D', end='')
else:
alert('At beginning')
alerted = True
elif d == '\033':
d = sys.stdin.read(1) d = sys.stdin.read(1)
if d == '[': if d == '[':
d = sys.stdin.read(1) d = sys.stdin.read(1)
@ -336,25 +423,43 @@ class TextArea:
x += 1 x += 1
print('\033[C', end='') print('\033[C', end='')
else: else:
alert('At beginning') alert('At end')
alerted = True alerted = True
elif d == 'D': elif d == 'D':
if x > 0: if x > 0:
x -= 1 x -= 1
print('\033[D', end='') print('\033[D', end='')
else: else:
alert('At end') alert('At beginning')
alerted = True alerted = True
elif d == '2':
d = sys.stdin.read(1)
if d == '~':
override = not override
status(('modified' if modified else 'unmodified') + (' override' if override else ''))
elif d == '3': elif d == '3':
d = sys.stdin.read(1) d = sys.stdin.read(1)
if d == '~': if d == '~':
removed = 1
if (mark is not None) and (mark >= 0) and (mark != x):
if mark < x:
x ^= mark; mark ^= x; x ^= mark
removed = mark - x
dataline = datalines[y] dataline = datalines[y]
if x == len(dataline): if x == len(dataline):
alert('At end') alert('At end')
alerted = True alerted = True
continue continue
datalines[y] = dataline = dataline[:x] + dataline[x + 1:] datalines[y] = dataline = dataline[:x] + dataline[x + removed:]
print('\033[%i;%iH%s \033[%i;%iH' % (self.top + y, innerleft, dataline, self.top + y, innerleft + x), end='') print('\033[%i;%iH%s%s\033[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * removed, self.top + y, innerleft + x), end='')
mark = None
edited = True
else:
while True:
d = sys.stdin.read(1)
if (ord('a') <= ord(d)) and (ord(d) <= ord('z')): break
if (ord('A') <= ord(d)) and (ord(d) <= ord('Z')): break
if d == '~': break
elif d == 'O': elif d == 'O':
d = sys.stdin.read(1) d = sys.stdin.read(1)
if d == 'H': if d == 'H':
@ -365,12 +470,23 @@ class TextArea:
elif d == '\n': elif d == '\n':
break break
else: else:
dataline = datalines[y]; insert = d
print(d + dataline[x:], end='') if len(insert) == 0:
if len(dataline) - x > 0: continue
print('\033[%iD' % (len(dataline) - x), end='') dataline = datalines[y]
datalines[y] = dataline[:x] + d + dataline[x:] if (not override) or (x == len(dataline)):
x += 1 print(insert + dataline[x:], end='')
if len(dataline) - x > 0:
print('\033[%iD' % (len(dataline) - x), end='')
datalines[y] = dataline[:x] + insert + dataline[x:]
if (mark is not None) and (mark >= 0):
if mark >= x:
mark += len(insert)
else:
print(insert, end='')
datalines[y] = dataline[:x] + insert + dataline[x + 1:]
x += len(insert)
edited = True