7373import bdb
7474import dis
7575import code
76+ import glob
7677import pprint
7778import signal
7879import inspect
@@ -155,6 +156,8 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
155156 # Try to load readline if it exists
156157 try :
157158 import readline
159+ # remove some common file name delimiters
160+ readline .set_completer_delims (' \t \n `@#$%^&*()=+[{]}\\ |;:\' ",<>?' )
158161 except ImportError :
159162 pass
160163 self .allow_kbdint = False
@@ -445,6 +448,61 @@ def message(self, msg):
445448 def error (self , msg ):
446449 print ('***' , msg , file = self .stdout )
447450
451+ # Generic completion functions. Individual complete_foo methods can be
452+ # assigned below to one of these functions.
453+
454+ def _complete_location (self , text , line , begidx , endidx ):
455+ # Complete a file/module/function location for break/tbreak/clear.
456+ if line .strip ().endswith ((':' , ',' )):
457+ # Here comes a line number or a condition which we can't complete.
458+ return []
459+ # First, try to find matching functions (i.e. expressions).
460+ try :
461+ ret = self ._complete_expression (text , line , begidx , endidx )
462+ except Exception :
463+ ret = []
464+ # Then, try to complete file names as well.
465+ globs = glob .glob (text + '*' )
466+ for fn in globs :
467+ if os .path .isdir (fn ):
468+ ret .append (fn + '/' )
469+ elif os .path .isfile (fn ) and fn .lower ().endswith (('.py' , '.pyw' )):
470+ ret .append (fn + ':' )
471+ return ret
472+
473+ def _complete_bpnumber (self , text , line , begidx , endidx ):
474+ # Complete a breakpoint number. (This would be more helpful if we could
475+ # display additional info along with the completions, such as file/line
476+ # of the breakpoint.)
477+ return [str (i ) for i , bp in enumerate (bdb .Breakpoint .bpbynumber )
478+ if bp is not None and str (i ).startswith (text )]
479+
480+ def _complete_expression (self , text , line , begidx , endidx ):
481+ # Complete an arbitrary expression.
482+ if not self .curframe :
483+ return []
484+ # Collect globals and locals. It is usually not really sensible to also
485+ # complete builtins, and they clutter the namespace quite heavily, so we
486+ # leave them out.
487+ ns = self .curframe .f_globals .copy ()
488+ ns .update (self .curframe_locals )
489+ if '.' in text :
490+ # Walk an attribute chain up to the last part, similar to what
491+ # rlcompleter does. This will bail if any of the parts are not
492+ # simple attribute access, which is what we want.
493+ dotted = text .split ('.' )
494+ try :
495+ obj = ns [dotted [0 ]]
496+ for part in dotted [1 :- 1 ]:
497+ obj = getattr (obj , part )
498+ except (KeyError , AttributeError ):
499+ return []
500+ prefix = '.' .join (dotted [:- 1 ]) + '.'
501+ return [prefix + n for n in dir (obj ) if n .startswith (dotted [- 1 ])]
502+ else :
503+ # Complete a simple name.
504+ return [n for n in ns .keys () if n .startswith (text )]
505+
448506 # Command definitions, called by cmdloop()
449507 # The argument is the remaining string on the command line
450508 # Return true to exit from the command loop
@@ -526,6 +584,8 @@ def do_commands(self, arg):
526584 self .commands_defining = False
527585 self .prompt = prompt_back
528586
587+ complete_commands = _complete_bpnumber
588+
529589 def do_break (self , arg , temporary = 0 ):
530590 """b(reak) [ ([filename:]lineno | function) [, condition] ]
531591 Without argument, list all breaks.
@@ -628,13 +688,18 @@ def defaultFile(self):
628688
629689 do_b = do_break
630690
691+ complete_break = _complete_location
692+ complete_b = _complete_location
693+
631694 def do_tbreak (self , arg ):
632695 """tbreak [ ([filename:]lineno | function) [, condition] ]
633696 Same arguments as break, but sets a temporary breakpoint: it
634697 is automatically deleted when first hit.
635698 """
636699 self .do_break (arg , 1 )
637700
701+ complete_tbreak = _complete_location
702+
638703 def lineinfo (self , identifier ):
639704 failed = (None , None , None )
640705 # Input is identifier, may be in single quotes
@@ -704,6 +769,8 @@ def do_enable(self, arg):
704769 bp .enable ()
705770 self .message ('Enabled %s' % bp )
706771
772+ complete_enable = _complete_bpnumber
773+
707774 def do_disable (self , arg ):
708775 """disable bpnumber [bpnumber ...]
709776 Disables the breakpoints given as a space separated list of
@@ -722,6 +789,8 @@ def do_disable(self, arg):
722789 bp .disable ()
723790 self .message ('Disabled %s' % bp )
724791
792+ complete_disable = _complete_bpnumber
793+
725794 def do_condition (self , arg ):
726795 """condition bpnumber [condition]
727796 Set a new condition for the breakpoint, an expression which
@@ -745,6 +814,8 @@ def do_condition(self, arg):
745814 else :
746815 self .message ('New condition set for breakpoint %d.' % bp .number )
747816
817+ complete_condition = _complete_bpnumber
818+
748819 def do_ignore (self , arg ):
749820 """ignore bpnumber [count]
750821 Set the ignore count for the given breakpoint number. If
@@ -776,6 +847,8 @@ def do_ignore(self, arg):
776847 self .message ('Will stop next time breakpoint %d is reached.'
777848 % bp .number )
778849
850+ complete_ignore = _complete_bpnumber
851+
779852 def do_clear (self , arg ):
780853 """cl(ear) filename:lineno\n cl(ear) [bpnumber [bpnumber...]]
781854 With a space separated list of breakpoint numbers, clear
@@ -824,6 +897,9 @@ def do_clear(self, arg):
824897 self .message ('Deleted %s' % bp )
825898 do_cl = do_clear # 'c' is already an abbreviation for 'continue'
826899
900+ complete_clear = _complete_location
901+ complete_cl = _complete_location
902+
827903 def do_where (self , arg ):
828904 """w(here)
829905 Print a stack trace, with the most recent frame at the bottom.
@@ -1007,6 +1083,8 @@ def do_debug(self, arg):
10071083 sys .settrace (self .trace_dispatch )
10081084 self .lastcmd = p .lastcmd
10091085
1086+ complete_debug = _complete_expression
1087+
10101088 def do_quit (self , arg ):
10111089 """q(uit)\n exit
10121090 Quit from the debugger. The program being executed is aborted.
@@ -1093,6 +1171,10 @@ def do_pp(self, arg):
10931171 except :
10941172 pass
10951173
1174+ complete_print = _complete_expression
1175+ complete_p = _complete_expression
1176+ complete_pp = _complete_expression
1177+
10961178 def do_list (self , arg ):
10971179 """l(ist) [first [,last] | .]
10981180
@@ -1173,6 +1255,8 @@ def do_source(self, arg):
11731255 return
11741256 self ._print_lines (lines , lineno )
11751257
1258+ complete_source = _complete_expression
1259+
11761260 def _print_lines (self , lines , start , breaks = (), frame = None ):
11771261 """Print a range of lines."""
11781262 if frame :
@@ -1227,6 +1311,8 @@ def do_whatis(self, arg):
12271311 # None of the above...
12281312 self .message (type (value ))
12291313
1314+ complete_whatis = _complete_expression
1315+
12301316 def do_display (self , arg ):
12311317 """display [expression]
12321318
@@ -1244,6 +1330,8 @@ def do_display(self, arg):
12441330 self .displaying .setdefault (self .curframe , {})[arg ] = val
12451331 self .message ('display %s: %r' % (arg , val ))
12461332
1333+ complete_display = _complete_expression
1334+
12471335 def do_undisplay (self , arg ):
12481336 """undisplay [expression]
12491337
@@ -1259,6 +1347,10 @@ def do_undisplay(self, arg):
12591347 else :
12601348 self .displaying .pop (self .curframe , None )
12611349
1350+ def complete_undisplay (self , text , line , begidx , endidx ):
1351+ return [e for e in self .displaying .get (self .curframe , {})
1352+ if e .startswith (text )]
1353+
12621354 def do_interact (self , arg ):
12631355 """interact
12641356
@@ -1313,6 +1405,9 @@ def do_unalias(self, arg):
13131405 if args [0 ] in self .aliases :
13141406 del self .aliases [args [0 ]]
13151407
1408+ def complete_unalias (self , text , line , begidx , endidx ):
1409+ return [a for a in self .aliases if a .startswith (text )]
1410+
13161411 # List of all the commands making the program resume execution.
13171412 commands_resuming = ['do_continue' , 'do_step' , 'do_next' , 'do_return' ,
13181413 'do_quit' , 'do_jump' ]
0 commit comments