From 93ad83025b3a17cbf959c0fa3680a565e549785f Mon Sep 17 00:00:00 2001 From: Bob Farrell Date: Tue, 24 Jun 2008 17:33:32 +0100 Subject: [PATCH] Fixed the pager and help so the full help is displayed Also added a 'q' option to the pager to cancel out of huge help pages. --- CHANGELOG | 11 ++++++++ bpython.py | 69 ++++++++++++++++++++++++++++++++------------- bpython/internal.py | 49 -------------------------------- 3 files changed, 61 insertions(+), 68 deletions(-) delete mode 100644 bpython/internal.py diff --git a/CHANGELOG b/CHANGELOG index 6723315..bf4a263 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,14 @@ +v0.5.2 +====== +help() actually displays the full help page, and I fixed up the +ghetto pager a little. + +v0.5.1 +====== +Now you can hit tab to display the autocomplete list, rather than +have it pop up automatically as you type which, apparently, annoys +Brendogg. + v0.5.0 ====== A few people have commented that the help() built-in function diff --git a/bpython.py b/bpython.py index dc76efd..81d2554 100644 --- a/bpython.py +++ b/bpython.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# bpython 0.5.1::fancy curses interface to the Python repl::Bob Farrell 2008 +# bpython 0.5.2::fancy curses interface to the Python repl::Bob Farrell 2008 # # The MIT License # @@ -42,7 +42,7 @@ import struct import termios import fcntl import string -import ConfigParser +import shlex from bpython.formatter import BPythonFormatter class Dummy( object ): @@ -768,10 +768,10 @@ class Repl( object ): # The regular help() function uses PAGER to display the help, which # screws with bpython. - from bpython import internal - internal.window = self.scr - self.push('from bpython import internal\n') - self.push('help = internal._help') + from bpython import _internal + _internal.window = self.scr + self.push('from bpython import _internal\n') + self.push('help = _internal._help') self.iy, self.ix = self.scr.getyx() more = False @@ -788,6 +788,7 @@ class Repl( object ): self.scr.redrawwin() if self.do_exit: return + self.h_i = 0 self.history.append( inp ) self.s_hist[-1] += self.f_string @@ -1385,20 +1386,50 @@ def do_resize( caller ): # The list win resizes itself every time it appears so no need to do it here. def loadrc(): - """Attempt to load the rc file and apply settings.""" + """Use the shlex module to make a simple lexer for the settings, + it also attempts to convert any integers to Python ints, otherwise + leaves them as strings and handles hopefully all the sane ways of + representing a boolean.""" - c = ConfigParser.ConfigParser() - if not( c.read( os.path.expanduser('~/.bpythonrc') ) ): + if not os.path.isfile( os.path.expanduser( '~/.bpythonrc' ) ): return + + f = open( os.path.expanduser( '~/.bpythonrc' ) ) + parser = shlex.shlex( f ) - if not c.has_section('Global'): - return - - if c.has_option('Global', 'requiretab'): - if c.get('Global', 'requiretab') == 'no': - OPTS.requiretab = True - else: - OPTS.requiretab = False + bools = { + 'true': True, + 'yes': True, + 'false': False, + 'no': False + } + + config = {} + while True: + k = parser.get_token() + v = None + + if not k: + break + + if parser.get_token() == '=': + v = parser.get_token() or None + + if v is not None: + try: + v = int(v) + except ValueError: + if v.lower() in bools: + v = bools[v.lower()] + + config[k] = v + + + for k in config: + if hasattr( OPTS, k ): + setattr( OPTS, k, v ) + +stdscr = None def main( scr ): """main function for the curses convenience wrapper @@ -1414,7 +1445,6 @@ def main( scr ): global DO_RESIZE DO_RESIZE = False signal.signal( signal.SIGWINCH, lambda x,y: sigwinch(scr) ) - loadrc() stdscr = scr curses.start_color() @@ -1445,7 +1475,8 @@ except: tb = traceback.format_exc() finally: # I don't know why this is necessary; without it the wrapper doesn't always # do its job. - stdscr.keypad(0) + if stdscr is not None: + stdscr.keypad(0) curses.echo() curses.nocbreak() curses.endwin() diff --git a/bpython/internal.py b/bpython/internal.py deleted file mode 100644 index 9ad138d..0000000 --- a/bpython/internal.py +++ /dev/null @@ -1,49 +0,0 @@ -import pydoc -import textwrap -import sys - -window = None - -def _help( query ): - """Wrapper for the regular help() function but with a ghetto - PAGER since curses + less = :( - query : the actual search thing - window : a curses window instance to use getch() on - and for extrapolating the window size to work it all out""" - - rows, columns = window.getmaxyx() - rows -= 3 - columns -= 1 - output = pydoc.getdoc( query ) - 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 - if not i % rows: - wait_for_key( window ) - if j + 1 < len( paragraphs ): - sys.stdout.write('\n ') - -def wait_for_key( window ): - """Block until a key is pressed for the ghetto paging.""" - - window.addstr("Press any key...") - while True: - c = window.getch() - if c: - break - - y = window.getyx()[0] - window.move(y-1, 0) - window.clrtoeol()