Files
bpython-gist/bpython/_internal.py
T
2008-06-25 17:49:47 +01:00

97 lines
2.7 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()