11#!/usr/bin/env python
2- # bpython 0.5.0 ::fancy curses interface to the Python repl::Bob Farrell 2008
2+ # bpython 0.5.1 ::fancy curses interface to the Python repl::Bob Farrell 2008
33#
44# The MIT License
55#
@@ -49,6 +49,8 @@ class Dummy( object ):
4949 pass
5050OPTS = Dummy ()
5151
52+ OPTS .auto_display_list = True
53+
5254try :
5355 from pygments import highlight
5456 from pygments .lexers import PythonLexer
@@ -70,6 +72,10 @@ class Dummy( object ):
7072
7173# TODO:
7274#
75+ # Keyboard interrupt needs to tidy up the screen afterwards.
76+ #
77+ # Ability to require a keypress (e.g. tab) to display autocomplete
78+ # list.
7379#
7480# No config file yet. This will allow things like "indent depth" for requiring
7581# the user to hit return n times to signify the end of a code block.
@@ -210,6 +216,7 @@ def __init__( self, scr, interp, statusbar=None, idle=None):
210216 self .argspec = None
211217 self .tablen = None
212218 self .s = ''
219+ self .list_win_visible = False
213220
214221
215222 if not OPTS .argspec :
@@ -334,10 +341,25 @@ def walk( seq ):
334341
335342 return getargspec ( func )
336343
337- def complete ( self ):
344+ def complete ( self , tab = False ):
345+ """Wrap the _complete method to determine the visibility of list_win
346+ since there can be several reasons why it won't be displayed; this
347+ makes it more manageable."""
348+
349+ if self .list_win_visible and not OPTS .auto_display_list :
350+ self .scr .touchwin ()
351+ self .list_win_visible = False
352+ return
353+
354+ if OPTS .auto_display_list or tab :
355+ self .list_win_visible = self ._complete ( tab )
356+ return
357+
358+ def _complete ( self , tab = False ):
338359 """Construct a full list of possible completions and construct and
339360 display them in a window. Also check if there's an available argspec
340- (via the inspect module) and bang that on top of the completions too."""
361+ (via the inspect module) and bang that on top of the completions too.
362+ The return value is whether the list_win is visible or not."""
341363
342364 words = []
343365 i = 0
@@ -349,7 +371,7 @@ def complete( self ):
349371 if not (cw or self .argspec ):
350372 self .scr .redrawwin ()
351373 self .scr .refresh ()
352- return None
374+ return False
353375
354376 if not cw :
355377 self .matches = []
@@ -365,12 +387,19 @@ def complete( self ):
365387
366388 if (e or not self .completer .matches ) and not self .argspec :
367389 self .scr .redrawwin ()
368- return
390+ return False
369391
370392 if not e and self .completer .matches :
371393 self .matches = sorted ( set ( self .completer .matches ) ) # remove duplicates and
372394# restore order
395+
396+ if len ( self .matches ) == 1 and not OPTS .auto_display_list :
397+ self .list_win_visible = True
398+ self .tab ()
399+ return False
400+
373401 self .show_list ( self .matches , self .argspec )
402+ return True
374403
375404 def show_list ( self , items , topline = None ):
376405 shared = Dummy ()
@@ -419,6 +448,7 @@ def lsize():
419448 v_items .append ( i [:max_w - 3 ] )
420449 if not lsize ():
421450 del v_items [- 1 ]
451+ v_items [- 1 ] = '...'
422452 break
423453
424454 rows = shared .rows
@@ -454,14 +484,22 @@ def lsize():
454484 for ix , i in enumerate (v_items ):
455485 padding = (wl - len (i )) * ' '
456486 self .list_win .addstr ( i + padding , curses .color_pair ( self ._C ["c" ]+ 1 ) )
457- if (cols == 1 ) or (ix and not ix % cols and ix < len (v_items ) ):
487+ if (( cols == 1 ) or (ix and not ix % cols )) and ix + 1 < len (v_items ):
458488 self .list_win .addstr ( '\n ' )
489+
490+ # XXX: After all the trouble I had with sizing the list box (I'm not very good
491+ # at that type of thing) I decided to do this bit of tidying up here just to make
492+ # sure there's no unnececessary blank lines, it makes things look nicer. :)
493+ y = self .list_win .getyx ()[0 ]
494+ self .list_win .resize (y + 2 , w )
459495
460496 self .statusbar .win .touchwin ()
461497 self .statusbar .win .noutrefresh ()
462498 self .list_win .border ()
463499 self .scr .touchwin ()
500+ self .scr .cursyncup ()
464501 self .scr .noutrefresh ()
502+ self .scr .move ( * self .scr .getyx () )
465503 self .list_win .refresh ()
466504
467505
@@ -996,12 +1034,20 @@ def tab( self ):
9961034 self .tablen = self .scr .getyx ()[1 ] - x
9971035 return True
9981036
1037+ if not OPTS .auto_display_list and not self .list_win_visible :
1038+ self .complete ( tab = True )
1039+ return True
1040+
9991041 cw = self .cw ()
1000- if cw :
1001- b = self .strbase ( self .matches )
1002- if b :
1003- self .s += b [ len ( cw ) : ]
1004- self .print_line ( self .s )
1042+ if not cw :
1043+ return True
1044+
1045+ b = self .strbase ( self .matches )
1046+ if b :
1047+ self .s += b [ len ( cw ) : ]
1048+ self .print_line ( self .s )
1049+ if len ( self .matches ) == 1 and OPTS .auto_display_list :
1050+ self .scr .touchwin ()
10051051 return True
10061052
10071053 def strbase ( self , l ):
0 commit comments