2525import __builtin__
2626import __main__
2727import rlcompleter
28- import line
28+ import line as lineparts
2929import re
3030import os
3131from glob import glob
@@ -210,6 +210,10 @@ def get_completer(cursor_offset, current_line, locals_, argspec, config, magic_m
210210 if matches is not None :
211211 return sorted (set (matches )), FilenameCompletion
212212
213+ matches = DictKeyCompletion .matches (cursor_offset , current_line , locals_ = locals_ , config = config )
214+ if matches is not None :
215+ return sorted (set (matches )), DictKeyCompletion
216+
213217 matches = AttrCompletion .matches (cursor_offset , current_line , locals_ = locals_ , config = config )
214218 if matches is not None :
215219 cw = AttrCompletion .locate (cursor_offset , current_line )[2 ]
@@ -264,18 +268,18 @@ def substitute(cls, cursor_offset, line, match):
264268
265269class ImportCompletion (BaseCompletionType ):
266270 matches = staticmethod (importcompletion .complete )
267- locate = staticmethod (line .current_word )
271+ locate = staticmethod (lineparts .current_word )
268272 format = staticmethod (after_last_dot )
269273
270274class FilenameCompletion (BaseCompletionType ):
271275 shown_before_tab = False
272276 @classmethod
273277 def matches (cls , cursor_offset , current_line ):
274- cs = line .current_string (cursor_offset , current_line )
278+ cs = lineparts .current_string (cursor_offset , current_line )
275279 if cs is None :
276280 return None
277281 return filename_matches (cs [2 ])
278- locate = staticmethod (line .current_string )
282+ locate = staticmethod (lineparts .current_string )
279283 format = staticmethod (last_part_of_filename )
280284
281285class AttrCompletion (BaseCompletionType ):
@@ -292,9 +296,25 @@ def matches(cls, cursor_offset, line, locals_, config):
292296 # possibly be raised here, so if anyone wants to do that, feel free to send me
293297 # a patch. XXX: Make sure you raise here if you're debugging the completion
294298 # stuff !
295- e = True
296- raise
297- else :
298- e = False
299- locate = staticmethod (line .current_word )
299+ pass
300+ return None
301+ locate = staticmethod (lineparts .current_word )
300302 format = staticmethod (after_last_dot )
303+
304+ class DictKeyCompletion (BaseCompletionType ):
305+ locate = staticmethod (lineparts .current_dict_key )
306+ @classmethod
307+ def matches (cls , cursor_offset , line , locals_ , config ):
308+ r = cls .locate (cursor_offset , line )
309+ if r is None :
310+ return None
311+ start , end , orig = r
312+ _ , _ , dexpr = lineparts .current_dict (cursor_offset , line )
313+ obj = eval (dexpr , locals_ )
314+ if obj and isinstance (obj , type ({})) and obj .keys ():
315+ return ["{!r}]" .format (k ) for k in obj .keys () if repr (k ).startswith (orig )]
316+ else :
317+ return []
318+ @classmethod
319+ def format (cls , match ):
320+ return match [:- 1 ]
0 commit comments