##// END OF EJS Templates
Applied Olivier Lauzannes patch for cleaner import completer
vivainio -
Show More
@@ -11,9 +11,84 b" ip.set_hook('complete_command', svn_completer, str_key = 'svn')"
11 11
12 12 import IPython.ipapi
13 13 import glob,os,shlex,sys
14
14 import inspect
15 15 ip = IPython.ipapi.get()
16 16
17 def getRootModules():
18 """
19 Returns a list containing the names of all the modules available in the
20 folders of the pythonpath.
21 """
22 modules = []
23 for path in sys.path:
24 modules += moduleList(path)
25 modules += sys.builtin_module_names
26 modules = list(set(modules))
27 if '__init__' in modules:
28 modules.remove('__init__')
29 return list(set(modules))
30
31 def moduleList(path):
32 """
33 Return the list containing the names of the modules available in the given
34 folder.
35 """
36 folder_list = glob.glob(os.path.join(path,'*'))
37 folder_list = [path for path in folder_list \
38 if (os.path.isdir(path) and os.path.exists(os.path.join(path,'__init__.py')))\
39 or path[-3:] in ('.py','.so')\
40 or path[-4:] in ('.pyc','.pyo')]
41 folder_list += folder_list
42 folder_list = [os.path.basename(path).split('.')[0] for path in folder_list]
43 return folder_list
44
45 def moduleCompletion(line):
46 """
47 Returns a list containing the completion possibilities for an import line.
48 The line looks like this :
49 'import xml.d'
50 'from xml.dom import'
51 """
52 def tryImport(mod, only_modules=False):
53 def isImportable(module, attr):
54 if only_modules:
55 return inspect.ismodule(getattr(module, attr))
56 else:
57 return not(attr[:2] == '__' and attr[-2:] == '__')
58 try:
59 m = __import__(mod)
60 except:
61 return []
62 mods = mod.split('.')
63 for module in mods[1:]:
64 m = getattr(m,module)
65 if (not hasattr(m, '__file__')) or (not only_modules) or\
66 (hasattr(m, '__file__') and '__init__' in m.__file__):
67 completion_list = [attr for attr in dir(m) if isImportable(m, attr)]
68 completion_list.extend(getattr(m,'__all__',[]))
69 if hasattr(m, '__file__') and '__init__' in m.__file__:
70 completion_list.extend(moduleList(os.path.dirname(m.__file__)))
71 completion_list = list(set(completion_list))
72 if '__init__' in completion_list:
73 completion_list.remove('__init__')
74 return completion_list
75
76 words = line.split(' ')
77 if len(words) == 3 and words[0] == 'from':
78 return ['import ']
79 if len(words) < 3 and (words[0] in ['import','from']) :
80 if len(words) == 1:
81 return getRootModules()
82 mod = words[1].split('.')
83 if len(mod) < 2:
84 return getRootModules()
85 completion_list = tryImport('.'.join(mod[:-1]), True)
86 completion_list = ['.'.join(mod[:-1] + [el]) for el in completion_list]
87 return completion_list
88 if len(words) >= 3 and words[0] == 'from':
89 mod = words[1]
90 return tryImport(mod)
91
17 92 def vcs_completer(commands, event):
18 93 """ utility to make writing typical version control app completers easier
19 94
@@ -66,19 +141,15 b' def apt_completers(self, event):'
66 141 pkg_cache = None
67 142
68 143 def module_completer(self,event):
69 """ Give completions after user has typed 'import'.
70
71 Note that only possible completions in the local directory are returned."""
144 """ Give completions after user has typed 'import ...' or 'from ...'"""
72 145
73 146 # This works in all versions of python. While 2.5 has
74 147 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
75 148 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
76 # of possibly problematic side effects. At some point we may implement
77 # something that searches sys.path in a saner/safer way, but for now we'll
78 # restrict ourselves to local completions only.
79 for el in [f[:-3] for f in glob.glob("*.py")]:
80 yield el
81 return
149 # of possibly problematic side effects.
150 # This search the folders in the sys.path for available modules.
151
152 return moduleCompletion(event.line)
82 153
83 154
84 155 svn_commands = """\
General Comments 0
You need to be logged in to leave comments. Login now