##// END OF EJS Templates
use package cache in import completer, for performance
vivainio -
Show More
@@ -1,115 +1,120 b''
1 """ Tab completion support for a couple of linux package managers
1 """ Tab completion support for a couple of linux package managers
2
2
3 This is also an example of how to write custom completer plugins
3 This is also an example of how to write custom completer plugins
4 or hooks.
4 or hooks.
5
5
6 Practical use:
6 Practical use:
7
7
8 [ipython]|1> import ipy_linux_package_managers
8 [ipython]|1> import ipy_linux_package_managers
9 [ipython]|2> apt-get u<<< press tab here >>>
9 [ipython]|2> apt-get u<<< press tab here >>>
10 update upgrade
10 update upgrade
11 [ipython]|2> apt-get up
11 [ipython]|2> apt-get up
12
12
13 """
13 """
14 import IPython.ipapi
14 import IPython.ipapi
15 import glob,os,shlex
15 import glob,os,shlex
16
16
17 ip = IPython.ipapi.get()
17 ip = IPython.ipapi.get()
18
18
19 def apt_completers(self, event):
19 def apt_completers(self, event):
20 """ This should return a list of strings with possible completions.
20 """ This should return a list of strings with possible completions.
21
21
22 Note that all the included strings that don't start with event.symbol
22 Note that all the included strings that don't start with event.symbol
23 are removed, in order to not confuse readline.
23 are removed, in order to not confuse readline.
24
24
25 """
25 """
26 # print event # dbg
26 # print event # dbg
27
27
28 # commands are only suggested for the 'command' part of package manager
28 # commands are only suggested for the 'command' part of package manager
29 # invocation
29 # invocation
30
30
31 cmd = (event.line + "<placeholder>").rsplit(None,1)[0]
31 cmd = (event.line + "<placeholder>").rsplit(None,1)[0]
32 # print cmd
32 # print cmd
33 if cmd.endswith('apt-get') or cmd.endswith('yum'):
33 if cmd.endswith('apt-get') or cmd.endswith('yum'):
34 return ['update', 'upgrade', 'install', 'remove']
34 return ['update', 'upgrade', 'install', 'remove']
35
35
36 # later on, add dpkg -l / whatever to get list of possible
36 # later on, add dpkg -l / whatever to get list of possible
37 # packages, add switches etc. for the rest of command line
37 # packages, add switches etc. for the rest of command line
38 # filling
38 # filling
39
39
40 raise IPython.ipapi.TryNext
40 raise IPython.ipapi.TryNext
41
41
42
42
43 # re_key specifies the regexp that triggers the specified completer
43 # re_key specifies the regexp that triggers the specified completer
44
44
45 ip.set_hook('complete_command', apt_completers, re_key = '.*apt-get')
45 ip.set_hook('complete_command', apt_completers, re_key = '.*apt-get')
46 ip.set_hook('complete_command', apt_completers, re_key = '.*yum')
46 ip.set_hook('complete_command', apt_completers, re_key = '.*yum')
47
47
48 pkg_cache = None
49
48 def module_completer(self,event):
50 def module_completer(self,event):
49 """ Give completions after user has typed 'import' """
51 """ Give completions after user has typed 'import' """
50
52
53 global pkg_cache
51 import pkgutil,imp,time
54 import pkgutil,imp,time
52 for ld, name, ispkg in pkgutil.walk_packages():
55 #current =
53 if ispkg:
56 if pkg_cache is None:
54 yield name + '.'
57 print "\n\n[Standby while scanning modules, this can take a while]\n\n"
55 else:
58 pkg_cache = list(pkgutil.walk_packages())
56 yield name
59
60 for ld, name, ispkg in pkg_cache:
61 yield name
57 return
62 return
58
63
59 ip.set_hook('complete_command', module_completer, str_key = 'import')
64 ip.set_hook('complete_command', module_completer, str_key = 'import')
60 ip.set_hook('complete_command', module_completer, str_key = 'from')
65 ip.set_hook('complete_command', module_completer, str_key = 'from')
61
66
62 svn_commands = """\
67 svn_commands = """\
63 add blame praise annotate ann cat checkout co cleanup commit ci copy
68 add blame praise annotate ann cat checkout co cleanup commit ci copy
64 cp delete del remove rm diff di export help ? h import info list ls
69 cp delete del remove rm diff di export help ? h import info list ls
65 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
70 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
66 pe propget pget pg proplist plist pl propset pset ps resolved revert
71 pe propget pget pg proplist plist pl propset pset ps resolved revert
67 status stat st switch sw unlock update
72 status stat st switch sw unlock update
68 """
73 """
69
74
70 def svn_completer(self,event):
75 def svn_completer(self,event):
71 if len((event.line + 'placeholder').split()) > 2:
76 if len((event.line + 'placeholder').split()) > 2:
72 # the rest are probably file names
77 # the rest are probably file names
73 return ip.IP.Completer.file_matches(event.symbol)
78 return ip.IP.Completer.file_matches(event.symbol)
74
79
75 return svn_commands.split()
80 return svn_commands.split()
76
81
77 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
82 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
78
83
79 def runlistpy(self, event):
84 def runlistpy(self, event):
80 comps = shlex.split(event.line)
85 comps = shlex.split(event.line)
81 relpath = (len(comps) > 1 and comps[-1] or '')
86 relpath = (len(comps) > 1 and comps[-1] or '')
82
87
83 print "rp",relpath
88 print "rp",relpath
84 if relpath.startswith('~'):
89 if relpath.startswith('~'):
85 relpath = os.path.expanduser(relpath)
90 relpath = os.path.expanduser(relpath)
86 dirs = [f.replace('\\','/') + "/" for f in glob.glob(relpath+'*') if os.path.isdir(f)]
91 dirs = [f.replace('\\','/') + "/" for f in glob.glob(relpath+'*') if os.path.isdir(f)]
87 pys = [f.replace('\\','/') for f in glob.glob(relpath+'*.py')]
92 pys = [f.replace('\\','/') for f in glob.glob(relpath+'*.py')]
88 return dirs + pys
93 return dirs + pys
89
94
90 ip.set_hook('complete_command', runlistpy, str_key = '%run')
95 ip.set_hook('complete_command', runlistpy, str_key = '%run')
91
96
92 def listdirs(self, event):
97 def cd_completer(self, event):
93 relpath = event.symbol
98 relpath = event.symbol
94
99
95 if '-b' in event.line:
100 if '-b' in event.line:
96 # return only bookmark completions
101 # return only bookmark completions
97 bkms = self.db.get('bookmarks',{})
102 bkms = self.db.get('bookmarks',{})
98 return bkms.keys()
103 return bkms.keys()
99
104
100 if event.symbol == '-':
105 if event.symbol == '-':
101 # jump in directory history by number
106 # jump in directory history by number
102 ents = ['-%d [%s]' % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
107 ents = ['-%d [%s]' % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
103 if len(ents) > 1:
108 if len(ents) > 1:
104 return ents
109 return ents
105 return []
110 return []
106
111
107
112
108 if relpath.startswith('~'):
113 if relpath.startswith('~'):
109 relpath = os.path.expanduser(relpath).replace('\\','/')
114 relpath = os.path.expanduser(relpath).replace('\\','/')
110 found = [f.replace('\\','/')+'/' for f in glob.glob(relpath+'*') if os.path.isdir(f)]
115 found = [f.replace('\\','/')+'/' for f in glob.glob(relpath+'*') if os.path.isdir(f)]
111 if not found:
116 if not found:
112 return [relpath]
117 return [relpath]
113 return found
118 return found
114
119
115 ip.set_hook('complete_command', listdirs, str_key = '%cd') No newline at end of file
120 ip.set_hook('complete_command', cd_completer, str_key = '%cd') No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now