Files
2008-08-28 15:38:44 -05:00

109 lines
2.8 KiB
Python

import pydoc
import textwrap
import sys
import cStringIO
# window has to be a global so that the main bpython.py can load it and
# alter its state and share it with the interpreter being used for the
# actual user input, I couldn't think of another way of doing this.
window = None
def _help(obj):
"""Wrapper for the regular help() function but with a ghetto
PAGER since curses + less = :(
As per the vanilla help(), this function special-cases for str,
so you can do help('isinstance') or help(isinstance) and get the
same result.
"""
io = cStringIO.StringIO()
doc = pydoc.TextDoc()
helper = pydoc.Helper(None, io)
rows, columns = window.getmaxyx()
rows -= 3
columns -= 1
output = None
# Copied and pasted from Lib/pydoc.py and fiddled with
# so it works fine with bpython. As far as I can tell
# the bpython help is no compliant with the vanilla help.
# Please let me know if you find this to be untrue.
if type(obj) is type(''):
if obj == 'help':
helper.intro()
elif obj == 'keywords':
helper.listkeywords()
elif obj == 'topics':
helper.listtopics()
elif obj == 'modules':
helper.listmodules()
elif obj[:8] == 'modules ':
helper.listmodules(split(obj)[1])
elif obj in helper.keywords:
helper.showtopic(obj)
elif obj in helper.topics:
helper.showtopic(obj)
elif obj:
output = doc.document(eval(obj))
#######################
else:
output = doc.document(obj)
if not output:
output = "No help found for %s" % obj
return
if output is None:
output = io.getvalue()
io.close()
if not output:
return
output = output.replace('\t', ' ')
if '\n' in output:
output = output.replace('\n\n', '\n')
output = output.split('\n')
else:
output = [output]
paragraphs = []
for o in output:
paragraphs.append(textwrap.wrap(o, columns))
i = 0
for j, paragraph in enumerate(paragraphs):
for line in paragraph:
sys.stdout.write(line + '\n')
i += 1
# This is a little unclear, but it just waits for a
# keypress when the a page worth of text has been
# displayed and returns if 'q' is pressed:
if not i % rows and not wait_for_key():
return
def wait_for_key():
"""Block until a key is pressed for the ghetto paging."""
q = True
window.addstr("Press any key, q to cancel.")
while True:
c = window.getch()
if c and c == ord('q'):
q = False
if c:
break
clear_line()
return q
def clear_line():
y = window.getyx()[0]
window.move(y, 0)
window.clrtoeol()
# vim: sw=4 ts=4 sts=4 ai et