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