##// END OF EJS Templates
cd completer considers bookmarks if no other matches are available
Ville M. Vainio -
Show More
@@ -1,394 +1,400 b''
1
1
2 """ Implementations for various useful completers
2 """ Implementations for various useful completers
3
3
4 See Extensions/ipy_stock_completers.py on examples of how to enable a completer,
4 See Extensions/ipy_stock_completers.py on examples of how to enable a completer,
5 but the basic idea is to do:
5 but the basic idea is to do:
6
6
7 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
7 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
8
8
9 """
9 """
10 import IPython.ipapi
10 import IPython.ipapi
11 import glob,os,shlex,sys
11 import glob,os,shlex,sys
12 import inspect
12 import inspect
13 from time import time
13 from time import time
14 from zipimport import zipimporter
14 from zipimport import zipimporter
15 ip = IPython.ipapi.get()
15 ip = IPython.ipapi.get()
16
16
17 try:
17 try:
18 set
18 set
19 except:
19 except:
20 from sets import Set as set
20 from sets import Set as set
21
21
22 TIMEOUT_STORAGE = 3 #Time in seconds after which the rootmodules will be stored
22 TIMEOUT_STORAGE = 3 #Time in seconds after which the rootmodules will be stored
23 TIMEOUT_GIVEUP = 20 #Time in seconds after which we give up
23 TIMEOUT_GIVEUP = 20 #Time in seconds after which we give up
24
24
25 def quick_completer(cmd, completions):
25 def quick_completer(cmd, completions):
26 """ Easily create a trivial completer for a command.
26 """ Easily create a trivial completer for a command.
27
27
28 Takes either a list of completions, or all completions in string
28 Takes either a list of completions, or all completions in string
29 (that will be split on whitespace)
29 (that will be split on whitespace)
30
30
31 Example::
31 Example::
32
32
33 [d:\ipython]|1> import ipy_completers
33 [d:\ipython]|1> import ipy_completers
34 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
34 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
35 [d:\ipython]|3> foo b<TAB>
35 [d:\ipython]|3> foo b<TAB>
36 bar baz
36 bar baz
37 [d:\ipython]|3> foo ba
37 [d:\ipython]|3> foo ba
38 """
38 """
39 if isinstance(completions, basestring):
39 if isinstance(completions, basestring):
40
40
41 completions = completions.split()
41 completions = completions.split()
42 def do_complete(self,event):
42 def do_complete(self,event):
43 return completions
43 return completions
44
44
45 ip.set_hook('complete_command',do_complete, str_key = cmd)
45 ip.set_hook('complete_command',do_complete, str_key = cmd)
46
46
47 def getRootModules():
47 def getRootModules():
48 """
48 """
49 Returns a list containing the names of all the modules available in the
49 Returns a list containing the names of all the modules available in the
50 folders of the pythonpath.
50 folders of the pythonpath.
51 """
51 """
52 modules = []
52 modules = []
53 if ip.db.has_key('rootmodules'):
53 if ip.db.has_key('rootmodules'):
54 return ip.db['rootmodules']
54 return ip.db['rootmodules']
55 t = time()
55 t = time()
56 store = False
56 store = False
57 for path in sys.path:
57 for path in sys.path:
58 modules += moduleList(path)
58 modules += moduleList(path)
59 if time() - t >= TIMEOUT_STORAGE and not store:
59 if time() - t >= TIMEOUT_STORAGE and not store:
60 store = True
60 store = True
61 print "\nCaching the list of root modules, please wait!"
61 print "\nCaching the list of root modules, please wait!"
62 print "(This will only be done once - type '%rehashx' to " + \
62 print "(This will only be done once - type '%rehashx' to " + \
63 "reset cache!)"
63 "reset cache!)"
64 print
64 print
65 if time() - t > TIMEOUT_GIVEUP:
65 if time() - t > TIMEOUT_GIVEUP:
66 print "This is taking too long, we give up."
66 print "This is taking too long, we give up."
67 print
67 print
68 ip.db['rootmodules'] = []
68 ip.db['rootmodules'] = []
69 return []
69 return []
70
70
71 modules += sys.builtin_module_names
71 modules += sys.builtin_module_names
72
72
73 modules = list(set(modules))
73 modules = list(set(modules))
74 if '__init__' in modules:
74 if '__init__' in modules:
75 modules.remove('__init__')
75 modules.remove('__init__')
76 modules = list(set(modules))
76 modules = list(set(modules))
77 if store:
77 if store:
78 ip.db['rootmodules'] = modules
78 ip.db['rootmodules'] = modules
79 return modules
79 return modules
80
80
81 def moduleList(path):
81 def moduleList(path):
82 """
82 """
83 Return the list containing the names of the modules available in the given
83 Return the list containing the names of the modules available in the given
84 folder.
84 folder.
85 """
85 """
86
86
87 if os.path.isdir(path):
87 if os.path.isdir(path):
88 folder_list = os.listdir(path)
88 folder_list = os.listdir(path)
89 elif path.endswith('.egg'):
89 elif path.endswith('.egg'):
90 try:
90 try:
91 folder_list = [f for f in zipimporter(path)._files]
91 folder_list = [f for f in zipimporter(path)._files]
92 except:
92 except:
93 folder_list = []
93 folder_list = []
94 else:
94 else:
95 folder_list = []
95 folder_list = []
96 #folder_list = glob.glob(os.path.join(path,'*'))
96 #folder_list = glob.glob(os.path.join(path,'*'))
97 folder_list = [p for p in folder_list \
97 folder_list = [p for p in folder_list \
98 if os.path.exists(os.path.join(path, p,'__init__.py'))\
98 if os.path.exists(os.path.join(path, p,'__init__.py'))\
99 or p[-3:] in ('.py','.so')\
99 or p[-3:] in ('.py','.so')\
100 or p[-4:] in ('.pyc','.pyo','.pyd')]
100 or p[-4:] in ('.pyc','.pyo','.pyd')]
101
101
102 folder_list = [os.path.basename(p).split('.')[0] for p in folder_list]
102 folder_list = [os.path.basename(p).split('.')[0] for p in folder_list]
103 return folder_list
103 return folder_list
104
104
105 def moduleCompletion(line):
105 def moduleCompletion(line):
106 """
106 """
107 Returns a list containing the completion possibilities for an import line.
107 Returns a list containing the completion possibilities for an import line.
108 The line looks like this :
108 The line looks like this :
109 'import xml.d'
109 'import xml.d'
110 'from xml.dom import'
110 'from xml.dom import'
111 """
111 """
112 def tryImport(mod, only_modules=False):
112 def tryImport(mod, only_modules=False):
113 def isImportable(module, attr):
113 def isImportable(module, attr):
114 if only_modules:
114 if only_modules:
115 return inspect.ismodule(getattr(module, attr))
115 return inspect.ismodule(getattr(module, attr))
116 else:
116 else:
117 return not(attr[:2] == '__' and attr[-2:] == '__')
117 return not(attr[:2] == '__' and attr[-2:] == '__')
118 try:
118 try:
119 m = __import__(mod)
119 m = __import__(mod)
120 except:
120 except:
121 return []
121 return []
122 mods = mod.split('.')
122 mods = mod.split('.')
123 for module in mods[1:]:
123 for module in mods[1:]:
124 m = getattr(m,module)
124 m = getattr(m,module)
125 if (not hasattr(m, '__file__')) or (not only_modules) or\
125 if (not hasattr(m, '__file__')) or (not only_modules) or\
126 (hasattr(m, '__file__') and '__init__' in m.__file__):
126 (hasattr(m, '__file__') and '__init__' in m.__file__):
127 completion_list = [attr for attr in dir(m) if isImportable(m, attr)]
127 completion_list = [attr for attr in dir(m) if isImportable(m, attr)]
128 completion_list.extend(getattr(m,'__all__',[]))
128 completion_list.extend(getattr(m,'__all__',[]))
129 if hasattr(m, '__file__') and '__init__' in m.__file__:
129 if hasattr(m, '__file__') and '__init__' in m.__file__:
130 completion_list.extend(moduleList(os.path.dirname(m.__file__)))
130 completion_list.extend(moduleList(os.path.dirname(m.__file__)))
131 completion_list = list(set(completion_list))
131 completion_list = list(set(completion_list))
132 if '__init__' in completion_list:
132 if '__init__' in completion_list:
133 completion_list.remove('__init__')
133 completion_list.remove('__init__')
134 return completion_list
134 return completion_list
135
135
136 words = line.split(' ')
136 words = line.split(' ')
137 if len(words) == 3 and words[0] == 'from':
137 if len(words) == 3 and words[0] == 'from':
138 return ['import ']
138 return ['import ']
139 if len(words) < 3 and (words[0] in ['import','from']) :
139 if len(words) < 3 and (words[0] in ['import','from']) :
140 if len(words) == 1:
140 if len(words) == 1:
141 return getRootModules()
141 return getRootModules()
142 mod = words[1].split('.')
142 mod = words[1].split('.')
143 if len(mod) < 2:
143 if len(mod) < 2:
144 return getRootModules()
144 return getRootModules()
145 completion_list = tryImport('.'.join(mod[:-1]), True)
145 completion_list = tryImport('.'.join(mod[:-1]), True)
146 completion_list = ['.'.join(mod[:-1] + [el]) for el in completion_list]
146 completion_list = ['.'.join(mod[:-1] + [el]) for el in completion_list]
147 return completion_list
147 return completion_list
148 if len(words) >= 3 and words[0] == 'from':
148 if len(words) >= 3 and words[0] == 'from':
149 mod = words[1]
149 mod = words[1]
150 return tryImport(mod)
150 return tryImport(mod)
151
151
152 def vcs_completer(commands, event):
152 def vcs_completer(commands, event):
153 """ utility to make writing typical version control app completers easier
153 """ utility to make writing typical version control app completers easier
154
154
155 VCS command line apps typically have the format:
155 VCS command line apps typically have the format:
156
156
157 [sudo ]PROGNAME [help] [command] file file...
157 [sudo ]PROGNAME [help] [command] file file...
158
158
159 """
159 """
160
160
161
161
162 cmd_param = event.line.split()
162 cmd_param = event.line.split()
163 if event.line.endswith(' '):
163 if event.line.endswith(' '):
164 cmd_param.append('')
164 cmd_param.append('')
165
165
166 if cmd_param[0] == 'sudo':
166 if cmd_param[0] == 'sudo':
167 cmd_param = cmd_param[1:]
167 cmd_param = cmd_param[1:]
168
168
169 if len(cmd_param) == 2 or 'help' in cmd_param:
169 if len(cmd_param) == 2 or 'help' in cmd_param:
170 return commands.split()
170 return commands.split()
171
171
172 return ip.IP.Completer.file_matches(event.symbol)
172 return ip.IP.Completer.file_matches(event.symbol)
173
173
174
174
175 pkg_cache = None
175 pkg_cache = None
176
176
177 def module_completer(self,event):
177 def module_completer(self,event):
178 """ Give completions after user has typed 'import ...' or 'from ...'"""
178 """ Give completions after user has typed 'import ...' or 'from ...'"""
179
179
180 # This works in all versions of python. While 2.5 has
180 # This works in all versions of python. While 2.5 has
181 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
181 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
182 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
182 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
183 # of possibly problematic side effects.
183 # of possibly problematic side effects.
184 # This search the folders in the sys.path for available modules.
184 # This search the folders in the sys.path for available modules.
185
185
186 return moduleCompletion(event.line)
186 return moduleCompletion(event.line)
187
187
188
188
189 svn_commands = """\
189 svn_commands = """\
190 add blame praise annotate ann cat checkout co cleanup commit ci copy
190 add blame praise annotate ann cat checkout co cleanup commit ci copy
191 cp delete del remove rm diff di export help ? h import info list ls
191 cp delete del remove rm diff di export help ? h import info list ls
192 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
192 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
193 pe propget pget pg proplist plist pl propset pset ps resolved revert
193 pe propget pget pg proplist plist pl propset pset ps resolved revert
194 status stat st switch sw unlock update
194 status stat st switch sw unlock update
195 """
195 """
196
196
197 def svn_completer(self,event):
197 def svn_completer(self,event):
198 return vcs_completer(svn_commands, event)
198 return vcs_completer(svn_commands, event)
199
199
200
200
201 hg_commands = """
201 hg_commands = """
202 add addremove annotate archive backout branch branches bundle cat
202 add addremove annotate archive backout branch branches bundle cat
203 clone commit copy diff export grep heads help identify import incoming
203 clone commit copy diff export grep heads help identify import incoming
204 init locate log manifest merge outgoing parents paths pull push
204 init locate log manifest merge outgoing parents paths pull push
205 qapplied qclone qcommit qdelete qdiff qfold qguard qheader qimport
205 qapplied qclone qcommit qdelete qdiff qfold qguard qheader qimport
206 qinit qnew qnext qpop qprev qpush qrefresh qrename qrestore qsave
206 qinit qnew qnext qpop qprev qpush qrefresh qrename qrestore qsave
207 qselect qseries qtop qunapplied recover remove rename revert rollback
207 qselect qseries qtop qunapplied recover remove rename revert rollback
208 root serve showconfig status strip tag tags tip unbundle update verify
208 root serve showconfig status strip tag tags tip unbundle update verify
209 version
209 version
210 """
210 """
211
211
212 def hg_completer(self,event):
212 def hg_completer(self,event):
213 """ Completer for mercurial commands """
213 """ Completer for mercurial commands """
214
214
215 return vcs_completer(hg_commands, event)
215 return vcs_completer(hg_commands, event)
216
216
217
217
218
218
219 __bzr_commands = None
219 __bzr_commands = None
220
220
221 def bzr_commands():
221 def bzr_commands():
222 global __bzr_commands
222 global __bzr_commands
223 if __bzr_commands is not None:
223 if __bzr_commands is not None:
224 return __bzr_commands
224 return __bzr_commands
225 out = os.popen('bzr help commands')
225 out = os.popen('bzr help commands')
226 __bzr_commands = [l.split()[0] for l in out]
226 __bzr_commands = [l.split()[0] for l in out]
227 return __bzr_commands
227 return __bzr_commands
228
228
229 def bzr_completer(self,event):
229 def bzr_completer(self,event):
230 """ Completer for bazaar commands """
230 """ Completer for bazaar commands """
231 cmd_param = event.line.split()
231 cmd_param = event.line.split()
232 if event.line.endswith(' '):
232 if event.line.endswith(' '):
233 cmd_param.append('')
233 cmd_param.append('')
234
234
235 if len(cmd_param) > 2:
235 if len(cmd_param) > 2:
236 cmd = cmd_param[1]
236 cmd = cmd_param[1]
237 param = cmd_param[-1]
237 param = cmd_param[-1]
238 output_file = (param == '--output=')
238 output_file = (param == '--output=')
239 if cmd == 'help':
239 if cmd == 'help':
240 return bzr_commands()
240 return bzr_commands()
241 elif cmd in ['bundle-revisions','conflicts',
241 elif cmd in ['bundle-revisions','conflicts',
242 'deleted','nick','register-branch',
242 'deleted','nick','register-branch',
243 'serve','unbind','upgrade','version',
243 'serve','unbind','upgrade','version',
244 'whoami'] and not output_file:
244 'whoami'] and not output_file:
245 return []
245 return []
246 else:
246 else:
247 # the rest are probably file names
247 # the rest are probably file names
248 return ip.IP.Completer.file_matches(event.symbol)
248 return ip.IP.Completer.file_matches(event.symbol)
249
249
250 return bzr_commands()
250 return bzr_commands()
251
251
252
252
253 def shlex_split(x):
253 def shlex_split(x):
254 """Helper function to split lines into segments."""
254 """Helper function to split lines into segments."""
255 #shlex.split raise exception if syntax error in sh syntax
255 #shlex.split raise exception if syntax error in sh syntax
256 #for example if no closing " is found. This function keeps dropping
256 #for example if no closing " is found. This function keeps dropping
257 #the last character of the line until shlex.split does not raise
257 #the last character of the line until shlex.split does not raise
258 #exception. Adds end of the line to the result of shlex.split
258 #exception. Adds end of the line to the result of shlex.split
259 #example: %run "c:/python -> ['%run','"c:/python']
259 #example: %run "c:/python -> ['%run','"c:/python']
260 endofline=[]
260 endofline=[]
261 while x!="":
261 while x!="":
262 try:
262 try:
263 comps=shlex.split(x)
263 comps=shlex.split(x)
264 if len(endofline)>=1:
264 if len(endofline)>=1:
265 comps.append("".join(endofline))
265 comps.append("".join(endofline))
266 return comps
266 return comps
267 except ValueError:
267 except ValueError:
268 endofline=[x[-1:]]+endofline
268 endofline=[x[-1:]]+endofline
269 x=x[:-1]
269 x=x[:-1]
270 return ["".join(endofline)]
270 return ["".join(endofline)]
271
271
272 def runlistpy(self, event):
272 def runlistpy(self, event):
273 comps = shlex_split(event.line)
273 comps = shlex_split(event.line)
274 relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"")
274 relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"")
275
275
276 #print "\nev=",event # dbg
276 #print "\nev=",event # dbg
277 #print "rp=",relpath # dbg
277 #print "rp=",relpath # dbg
278 #print 'comps=',comps # dbg
278 #print 'comps=',comps # dbg
279
279
280 lglob = glob.glob
280 lglob = glob.glob
281 isdir = os.path.isdir
281 isdir = os.path.isdir
282 if relpath.startswith('~'):
282 if relpath.startswith('~'):
283 relpath = os.path.expanduser(relpath)
283 relpath = os.path.expanduser(relpath)
284 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*')
284 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*')
285 if isdir(f)]
285 if isdir(f)]
286
286
287 # Find if the user has already typed the first filename, after which we
287 # Find if the user has already typed the first filename, after which we
288 # should complete on all files, since after the first one other files may
288 # should complete on all files, since after the first one other files may
289 # be arguments to the input script.
289 # be arguments to the input script.
290 #filter(
290 #filter(
291 if filter(lambda f: f.endswith('.py') or f.endswith('.ipy') or
291 if filter(lambda f: f.endswith('.py') or f.endswith('.ipy') or
292 f.endswith('.pyw'),comps):
292 f.endswith('.pyw'),comps):
293 pys = [f.replace('\\','/') for f in lglob('*')]
293 pys = [f.replace('\\','/') for f in lglob('*')]
294 else:
294 else:
295 pys = [f.replace('\\','/')
295 pys = [f.replace('\\','/')
296 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
296 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
297 lglob(relpath + '*.pyw')]
297 lglob(relpath + '*.pyw')]
298 return dirs + pys
298 return dirs + pys
299
299
300
300
301 greedy_cd_completer = False
301 greedy_cd_completer = False
302
302
303 def cd_completer(self, event):
303 def cd_completer(self, event):
304 relpath = event.symbol
304 relpath = event.symbol
305 #print event # dbg
305 #print event # dbg
306 if '-b' in event.line:
306 if '-b' in event.line:
307 # return only bookmark completions
307 # return only bookmark completions
308 bkms = self.db.get('bookmarks',{})
308 bkms = self.db.get('bookmarks',{})
309 return bkms.keys()
309 return bkms.keys()
310
310
311
311
312 if event.symbol == '-':
312 if event.symbol == '-':
313 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
313 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
314 # jump in directory history by number
314 # jump in directory history by number
315 fmt = '-%0' + width_dh +'d [%s]'
315 fmt = '-%0' + width_dh +'d [%s]'
316 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
316 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
317 if len(ents) > 1:
317 if len(ents) > 1:
318 return ents
318 return ents
319 return []
319 return []
320
320
321 if event.symbol.startswith('--'):
321 if event.symbol.startswith('--'):
322 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
322 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
323
323
324 if relpath.startswith('~'):
324 if relpath.startswith('~'):
325 relpath = os.path.expanduser(relpath).replace('\\','/')
325 relpath = os.path.expanduser(relpath).replace('\\','/')
326 found = []
326 found = []
327 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
327 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
328 if os.path.isdir(f)]:
328 if os.path.isdir(f)]:
329 if ' ' in d:
329 if ' ' in d:
330 # we don't want to deal with any of that, complex code
330 # we don't want to deal with any of that, complex code
331 # for this is elsewhere
331 # for this is elsewhere
332 raise IPython.ipapi.TryNext
332 raise IPython.ipapi.TryNext
333 found.append( d )
333 found.append( d )
334
334
335 if not found:
335 if not found:
336 if os.path.isdir(relpath):
336 if os.path.isdir(relpath):
337 return [relpath]
337 return [relpath]
338
339 bks = self.db.get('bookmarks',{}).keys()
340 bkmatches = [s for s in bks if s.startswith(event.symbol)]
341 if bkmatches:
342 return bkmatches
343
338 raise IPython.ipapi.TryNext
344 raise IPython.ipapi.TryNext
339
345
340
346
341 def single_dir_expand(matches):
347 def single_dir_expand(matches):
342 "Recursively expand match lists containing a single dir."
348 "Recursively expand match lists containing a single dir."
343
349
344 if len(matches) == 1 and os.path.isdir(matches[0]):
350 if len(matches) == 1 and os.path.isdir(matches[0]):
345 # Takes care of links to directories also. Use '/'
351 # Takes care of links to directories also. Use '/'
346 # explicitly, even under Windows, so that name completions
352 # explicitly, even under Windows, so that name completions
347 # don't end up escaped.
353 # don't end up escaped.
348 d = matches[0]
354 d = matches[0]
349 if d[-1] in ['/','\\']:
355 if d[-1] in ['/','\\']:
350 d = d[:-1]
356 d = d[:-1]
351
357
352 subdirs = [p for p in os.listdir(d) if os.path.isdir( d + '/' + p) and not p.startswith('.')]
358 subdirs = [p for p in os.listdir(d) if os.path.isdir( d + '/' + p) and not p.startswith('.')]
353 if subdirs:
359 if subdirs:
354 matches = [ (d + '/' + p) for p in subdirs ]
360 matches = [ (d + '/' + p) for p in subdirs ]
355 return single_dir_expand(matches)
361 return single_dir_expand(matches)
356 else:
362 else:
357 return matches
363 return matches
358 else:
364 else:
359 return matches
365 return matches
360
366
361 if greedy_cd_completer:
367 if greedy_cd_completer:
362 return single_dir_expand(found)
368 return single_dir_expand(found)
363 else:
369 else:
364 return found
370 return found
365
371
366 def apt_get_packages(prefix):
372 def apt_get_packages(prefix):
367 out = os.popen('apt-cache pkgnames')
373 out = os.popen('apt-cache pkgnames')
368 for p in out:
374 for p in out:
369 if p.startswith(prefix):
375 if p.startswith(prefix):
370 yield p.rstrip()
376 yield p.rstrip()
371
377
372
378
373 apt_commands = """\
379 apt_commands = """\
374 update upgrade install remove purge source build-dep dist-upgrade
380 update upgrade install remove purge source build-dep dist-upgrade
375 dselect-upgrade clean autoclean check"""
381 dselect-upgrade clean autoclean check"""
376
382
377 def apt_completer(self, event):
383 def apt_completer(self, event):
378 """ Completer for apt-get (uses apt-cache internally)
384 """ Completer for apt-get (uses apt-cache internally)
379
385
380 """
386 """
381
387
382
388
383 cmd_param = event.line.split()
389 cmd_param = event.line.split()
384 if event.line.endswith(' '):
390 if event.line.endswith(' '):
385 cmd_param.append('')
391 cmd_param.append('')
386
392
387 if cmd_param[0] == 'sudo':
393 if cmd_param[0] == 'sudo':
388 cmd_param = cmd_param[1:]
394 cmd_param = cmd_param[1:]
389
395
390 if len(cmd_param) == 2 or 'help' in cmd_param:
396 if len(cmd_param) == 2 or 'help' in cmd_param:
391 return apt_commands.split()
397 return apt_commands.split()
392
398
393 return list(apt_get_packages(event.symbol))
399 return list(apt_get_packages(event.symbol))
394
400
General Comments 0
You need to be logged in to leave comments. Login now