Merge branch 'next' of github.com:erkin/ponysay into next

This commit is contained in:
Mattias Andrée 2012-11-05 13:55:22 +01:00
commit e3b461343a
3 changed files with 143 additions and 14 deletions

View file

@ -261,9 +261,9 @@ If the argument is not a number, but starts instead with @code{n} (for none
of the terminal is used. of the terminal is used.
@code{n} and @code{i} is case insensitive, so you may use @code{N} and @code{I} @code{n} and @code{i} is case insensitive, so you may use @code{N} and @code{I}
instead. Additionally, typo correction is for QWERTY and Dvorak is built in to instead. Additionally, typo correction is for QWERTY (and QWERTZ) and Dvorak is
@command{ponysay}; the nearest key, either to the left or to the right, depending built in to @command{ponysay}; the nearest key, either to the left or to the
on which hand is used to press the key, is also allowed. right, depending on which hand is used to press the key, is also allowed.
@item -c @item -c
@itemx --compress @itemx --compress
@ -1339,7 +1339,25 @@ without the balloon, respectively, for each pony the the directory.
@opindex @option{-r} @opindex @option{-r}
@opindex @option{--restrict} @opindex @option{--restrict}
TODO... Running @command{ponysay-tool --browse PONY-DIR}, or @command{ponysay-tool -b PONY-DIR}
will display all ponies in @file{PONY-DIR} for you. You can limit the listed ponies by
using the option @option{--restrict}, or @option{-r}, that works the same was in with
the commands @command{ponysay} and @command{ponythink}. See @ref{Invoking ponysay} for
more infomation about the @option{--restrict} option.
In this browser you will on the right side have all pony files, in your selected
directory, listed except those that does not match your @option{--restrict} settings.
In the rest of the free space, the pony select in the list is centered. You can move
the pony, in case it is too big, by using the arrows keys with @kbd{control} held down,
or using the @kbd{W}, @kbd{A}, @kbd{S}, @kbd{D} keys (for QWERTY and QWERTZ layout,)
or with the @kbd{<} (or @kbd{Ä}), @kbd{A}, @kbd{O}, @kbd{E} keys (for Dvorak and Svorak
layout.) To recenter the pony press @kbd{C-l} (@kb{dl} with @kbd{control} held down.)
Browse between ponies using the arrow keys or with @kbd{C-n} and @kbd{C-p}, for next
pony and previous pony, respectivily. Additionally, @kbd{Q} can be used list quotes
for pony, and @kbd{I} for metadata; press the key again to return the pony browsing.
The tool can be exited using the key combinations @kbd{C-q} or @kbd{C-x C-c}.

View file

@ -81,6 +81,23 @@ class PonysayTool():
elif (opts['--metadata'] is not None) and (len(opts['--metadata']) == 1): elif (opts['--metadata'] is not None) and (len(opts['--metadata']) == 1):
self.generateMetadata(opts['--metadata'][0]) self.generateMetadata(opts['--metadata'][0])
elif (opts['-b'] is not None) and (len(opts['-b']) == 1):
try:
if opts['--no-term-init'] is None:
print('\033[?1049h', end='') # initialise terminal
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
cmd %= ('-echo -icanon -echo -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
print('\033[?25l', end='') # hide cursor
self.browse(opts['-b'][0], opts['-r'])
finally:
print('\033[?25h', end='') # show cursor
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
cmd %= ('echo icanon echo isig ixoff ixon', os.path.realpath('/dev/stdout'))
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
if opts['--no-term-init'] is None:
print('\033[?1049l', end='') # terminate terminal
elif (opts['--edit'] is not None) and (len(opts['--edit']) == 1): elif (opts['--edit'] is not None) and (len(opts['--edit']) == 1):
pony = opts['--edit'][0] pony = opts['--edit'][0]
if not os.path.isfile(pony): if not os.path.isfile(pony):
@ -88,17 +105,19 @@ class PonysayTool():
exit(252) exit(252)
linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux') linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
try: try:
if opts['--no-term-init'] is None:
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 -ixoff -ixon', os.path.realpath('/dev/stdout')) cmd %= ('-echo -icanon -echo -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 ixoff ixon', os.path.realpath('/dev/stdout')) cmd %= ('echo icanon echo 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
if opts['--no-term-init'] is None:
print('\033[?1049l', end='') # terminate terminal print('\033[?1049l', end='') # terminate terminal
elif (opts['--edit-rm'] is not None) and (len(opts['--edit-rm']) == 1): elif (opts['--edit-rm'] is not None) and (len(opts['--edit-rm']) == 1):
@ -152,6 +171,95 @@ class PonysayTool():
exit(253) exit(253)
'''
Browse ponies
@param ponydir:str The pony directory to browse
@param restriction:list<str> Restrictions on listed ponies, may be None
'''
def browse(self, ponydir, restriction):
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
termsize = None
for channel in (sys.stdout, sys.stdin, sys.stderr):
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
if len(termsize) > 0:
termsize = termsize.decode('utf8', 'replace')[:-1].split(' ') # [:-1] removes a \n
termsize = [int(item) for item in termsize]
break
print('\033[H\033[2J', end='')
(x, y) = (0, 0)
(oldx, oldy) = (None, None)
(quotes, info) = (False, False)
(ponyindex, oldpony) = (0, None)
stored = None
while True:
if (ponyindex != oldpony):
oldpony = ponyindex
# TODO load new pony
if (oldx != x) or (oldy != y):
(oldx, oldy) = (x, y)
# TODO redraw
sys.stdout.buffer.flush()
if stored is None:
d = sys.stdin.read(1)
else:
d = stored
stored = None
recenter = False
if (d == 'w') or (d == 'W') or (d == '<') or (d == 'ä') or (d == 'Ä'): # pad ↑
y -= 1
elif (d == 's') or (d == 'S') or (d == 'o') or (d == 'O'): # pad ↓
y += 1
elif (d == 'd') or (d == 'D') or (d == 'e') or (d == 'E'): # pad →
x += 1
elif (d == 'a') or (d == 'A'): # pad ←
x -= 1
elif (d == 'q') or (d == 'Q'): # toggle quotes
quotes = False if info else not quotes
recenter = True
elif (d == 'i') or (d == 'I'): # toggle metadata
info = False if quotes else not info
recenter = True
elif ord(d) == ord('L') - ord('@'): # recenter
recenter = True
elif ord(d) == ord('P') - ord('@'): # previous
ponyindex -= 1
recenter = True
elif ord(d) == ord('N') - ord('@'): # next
ponyindex += 1
recenter = True
elif ord(d) == ord('Q') - ord('@'):
break
elif ord(d) == ord('X') - ord('@'):
if ord(sys.stdin.read(1)) == ord('C') - ord('@'):
break
elif d == '\033':
d = sys.stdin.read(1)
if d == '[':
d = sys.stdin.read(1)
if d == 'A': stored = chr(ord('P') - ord('@')) if (not quotes) and (not info) else 'W'
elif d == 'B': stored = chr(ord('N') - ord('@')) if (not quotes) and (not info) else 'S'
elif d == 'C': stored = chr(ord('N') - ord('@')) if (not quotes) and (not info) else 'D'
elif d == 'D': stored = chr(ord('P') - ord('@')) if (not quotes) and (not info) else 'A'
elif d == '1':
if sys.stdin.read(1) == ';':
if sys.stdin.read(1) == '5':
d = sys.stdin.read(1)
if d == 'A': stored = 'W'
elif d == 'B': stored = 'S'
elif d == 'C': stored = 'D'
elif d == 'D': stored = 'A'
if recenter:
(oldx, oldy) = (None, None)
(x, y) = (0, 0)
''' '''
Generate all kmsponies for the current TTY palette Generate all kmsponies for the current TTY palette
''' '''
@ -268,7 +376,7 @@ class PonysayTool():
sort(items, key = lambda item : item[0]) sort(items, key = lambda item : item[0])
for pair in ((widths, 'widths'), (heights, 'heights'), (onlyheights, 'onlyheights')): for pair in ((widths, 'widths'), (heights, 'heights'), (onlyheights, 'onlyheights')):
(items, dimfile) = pair (items, dimfile) = pair
dimfile = (ponydir + '/' + dimfile).replace('//'. '/') dimfile = (ponydir + '/' + dimfile).replace('//', '/')
ponies = [item[1] for item in items] ponies = [item[1] for item in items]
dims = [] dims = []
last = -1 last = -1
@ -305,7 +413,7 @@ class PonysayTool():
for c in value: for c in value:
if esc: if esc:
if bracket == 0: if bracket == 0:
if c not in (',', '\\', '('. ')'): if c not in (',', '\\', '(', ')'):
buf += '\\' buf += '\\'
buf += c buf += c
esc = False esc = False
@ -449,7 +557,7 @@ class PonysayTool():
ponyheight = len(printpony) - len(ponyfile.split('\n')) + 1 - 2 # using fallback balloon ponyheight = len(printpony) - len(ponyfile.split('\n')) + 1 - 2 # using fallback balloon
ponywidth = Backend.len(max(printpony, key = Backend.len)) ponywidth = Backend.len(max(printpony, key = Backend.len))
## Call `stty` to determine the size of the terminal, this way is better then using python's ncurses ## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
termsize = None termsize = None
for channel in (sys.stdout, sys.stdin, sys.stderr): for channel in (sys.stdout, sys.stdin, sys.stderr):
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0] termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
@ -917,6 +1025,8 @@ if __name__ == '__main__':
usage = usage, usage = usage,
longdescription = None) longdescription = None)
opts.add_argumentless(['--no-term-init']) # for debugging
opts.add_argumentless(['-h', '--help'], help = 'Print this help message.') opts.add_argumentless(['-h', '--help'], help = 'Print this help message.')
opts.add_argumentless(['-v', '--version'], help = 'Print the version of the program.') opts.add_argumentless(['-v', '--version'], help = 'Print the version of the program.')
opts.add_argumentless(['--kms'], help = 'Generate all kmsponies for the current TTY palette') opts.add_argumentless(['--kms'], help = 'Generate all kmsponies for the current TTY palette')

View file

@ -747,7 +747,7 @@ class Ponysay():
@return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area @return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area
''' '''
def __gettermsize(self): def __gettermsize(self):
## Call `stty` to determine the size of the terminal, this way is better then using python's ncurses ## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
for channel in (sys.stderr, sys.stdout, sys.stdin): for channel in (sys.stderr, sys.stdout, sys.stdin):
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0] termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
if len(termsize) > 0: if len(termsize) > 0:
@ -2217,6 +2217,7 @@ class Backend():
extraleft -= (msgwidth - width) >> 1 extraleft -= (msgwidth - width) >> 1
if extraleft < 0: if extraleft < 0:
extraleft = 0 extraleft = 0
if wrap is not None:
if extraleft + msgwidth > wrap: if extraleft + msgwidth > wrap:
extraleft -= msgwidth - wrap extraleft -= msgwidth - wrap