##// END OF EJS Templates
cd completer fixed to deal (partially) with dir names that have spaces in them (broken on win32)
vivainio -
Show More
@@ -1,208 +1,217
1 1 """ Tab completion support for a couple of linux package managers
2 2
3 3 This is also an example of how to write custom completer plugins
4 4 or hooks.
5 5
6 6 Practical use:
7 7
8 8 [ipython]|1> import ipy_linux_package_managers
9 9 [ipython]|2> apt-get u<<< press tab here >>>
10 10 update upgrade
11 11 [ipython]|2> apt-get up
12 12
13 13 """
14 14 import IPython.ipapi
15 15 import glob,os,shlex,sys
16 16
17 17 ip = IPython.ipapi.get()
18 18
19 19 def vcs_completer(commands, event):
20 20 """ utility to make writing typical version control app completers easier
21 21
22 22 VCS command line apps typically have the format:
23 23
24 24 [sudo ]PROGNAME [help] [command] file file...
25 25
26 26 """
27 27
28 28
29 29 cmd_param = event.line.split()
30 30 if event.line.endswith(' '):
31 31 cmd_param.append('')
32 32
33 33 if cmd_param[0] == 'sudo':
34 34 cmd_param = cmd_param[1:]
35 35
36 36 if len(cmd_param) == 2 or 'help' in cmd_param:
37 37 return commands.split()
38 38
39 39 return ip.IP.Completer.file_matches(event.symbol)
40 40
41 41
42 42
43 43 def apt_completers(self, event):
44 44 """ This should return a list of strings with possible completions.
45 45
46 46 Note that all the included strings that don't start with event.symbol
47 47 are removed, in order to not confuse readline.
48 48
49 49 """
50 50 # print event # dbg
51 51
52 52 # commands are only suggested for the 'command' part of package manager
53 53 # invocation
54 54
55 55 cmd = (event.line + "<placeholder>").rsplit(None,1)[0]
56 56 # print cmd
57 57 if cmd.endswith('apt-get') or cmd.endswith('yum'):
58 58 return ['update', 'upgrade', 'install', 'remove']
59 59
60 60 # later on, add dpkg -l / whatever to get list of possible
61 61 # packages, add switches etc. for the rest of command line
62 62 # filling
63 63
64 64 raise IPython.ipapi.TryNext
65 65
66 66
67 67 # re_key specifies the regexp that triggers the specified completer
68 68
69 69 ip.set_hook('complete_command', apt_completers, re_key = '.*apt-get')
70 70 ip.set_hook('complete_command', apt_completers, re_key = '.*yum')
71 71
72 72 pkg_cache = None
73 73
74 74 def module_completer(self,event):
75 75 """ Give completions after user has typed 'import' """
76 76
77 77 # only a local version for py 2.4, pkgutil has no walk_packages() there
78 78 if sys.version_info < (2,5):
79 79 for el in [f[:-3] for f in glob.glob("*.py")]:
80 80 yield el
81 81 return
82 82
83 83 global pkg_cache
84 84 import pkgutil,imp,time
85 85 #current =
86 86 if pkg_cache is None:
87 87 print "\n\n[Standby while scanning modules, this can take a while]\n\n"
88 88 pkg_cache = list(pkgutil.walk_packages())
89 89
90 90 already = set()
91 91 for ld, name, ispkg in pkg_cache:
92 92 if name.count('.') < event.symbol.count('.') + 1:
93 93 if name not in already:
94 94 already.add(name)
95 95 yield name + (ispkg and '.' or '')
96 96 return
97 97
98 98 ip.set_hook('complete_command', module_completer, str_key = 'import')
99 99 ip.set_hook('complete_command', module_completer, str_key = 'from')
100 100
101 101 svn_commands = """\
102 102 add blame praise annotate ann cat checkout co cleanup commit ci copy
103 103 cp delete del remove rm diff di export help ? h import info list ls
104 104 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
105 105 pe propget pget pg proplist plist pl propset pset ps resolved revert
106 106 status stat st switch sw unlock update
107 107 """
108 108
109 109 def svn_completer(self,event):
110 110 return vcs_completer(svn_commands, event)
111 111
112 112 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
113 113
114 114 hg_commands = """
115 115 add addremove annotate archive backout branch branches bundle cat
116 116 clone commit copy diff export grep heads help identify import incoming
117 117 init locate log manifest merge outgoing parents paths pull push
118 118 qapplied qclone qcommit qdelete qdiff qfold qguard qheader qimport
119 119 qinit qnew qnext qpop qprev qpush qrefresh qrename qrestore qsave
120 120 qselect qseries qtop qunapplied recover remove rename revert rollback
121 121 root serve showconfig status strip tag tags tip unbundle update verify
122 122 version
123 123 """
124 124
125 125 def hg_completer(self,event):
126 126 """ Completer for mercurial commands """
127 127
128 128 return vcs_completer(hg_commands, event)
129 129
130 130 ip.set_hook('complete_command', hg_completer, str_key = 'hg')
131 131
132 132
133 133 bzr_commands = """
134 134 add annotate bind branch break-lock bundle-revisions cat check
135 135 checkout commit conflicts deleted diff export gannotate gbranch
136 136 gcommit gdiff help ignore ignored info init init-repository inventory
137 137 log merge missing mkdir mv nick pull push reconcile register-branch
138 138 remerge remove renames resolve revert revno root serve sign-my-commits
139 139 status testament unbind uncommit unknowns update upgrade version
140 140 version-info visualise whoami
141 141 """
142 142
143 143 def bzr_completer(self,event):
144 144 """ Completer for bazaar commands """
145 145 cmd_param = event.line.split()
146 146 if event.line.endswith(' '):
147 147 cmd_param.append('')
148 148
149 149 if len(cmd_param) > 2:
150 150 cmd = cmd_param[1]
151 151 param = cmd_param[-1]
152 152 output_file = (param == '--output=')
153 153 if cmd == 'help':
154 154 return bzr_commands.split()
155 155 elif cmd in ['bundle-revisions','conflicts',
156 156 'deleted','nick','register-branch',
157 157 'serve','unbind','upgrade','version',
158 158 'whoami'] and not output_file:
159 159 return []
160 160 else:
161 161 # the rest are probably file names
162 162 return ip.IP.Completer.file_matches(event.symbol)
163 163
164 164 return bzr_commands.split()
165 165
166 166 ip.set_hook('complete_command', bzr_completer, str_key = 'bzr')
167 167
168 168
169 169 def runlistpy(self, event):
170 170 comps = shlex.split(event.line)
171 171 relpath = (len(comps) > 1 and comps[-1] or '')
172 172
173 173 #print "rp",relpath # dbg
174 174 lglob = glob.glob
175 175 isdir = os.path.isdir
176 176 if relpath.startswith('~'):
177 177 relpath = os.path.expanduser(relpath)
178 178 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*')
179 179 if isdir(f)]
180 180 pys = [f.replace('\\','/') for f in lglob(relpath+'*.py')]
181 181 return dirs + pys
182 182
183 183 ip.set_hook('complete_command', runlistpy, str_key = '%run')
184 184
185 185 def cd_completer(self, event):
186 186 relpath = event.symbol
187
187 # print event # dbg
188 188 if '-b' in event.line:
189 189 # return only bookmark completions
190 190 bkms = self.db.get('bookmarks',{})
191 191 return bkms.keys()
192 192
193
193 194 if event.symbol == '-':
194 195 # jump in directory history by number
195 196 ents = ['-%d [%s]' % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
196 197 if len(ents) > 1:
197 198 return ents
198 199 return []
199 200
201 if sys.platform != 'win32':
202 protect = lambda n: n
203 else:
204 def protect(n):
205 return n.replace('\\' ,'/').replace(' ', '\\ ')
200 206
201 207 if relpath.startswith('~'):
202 208 relpath = os.path.expanduser(relpath).replace('\\','/')
203 found = [f.replace('\\','/')+'/' for f in glob.glob(relpath+'*') if os.path.isdir(f)]
209 found = [protect(f)+'/' for f in glob.glob(relpath+'*') if os.path.isdir(f)]
210 # print "f",found # dbg
204 211 if not found:
212 if os.path.isdir(relpath):
205 213 return [relpath]
214 raise IPython.ipapi.TryNext
206 215 return found
207 216
208 217 ip.set_hook('complete_command', cd_completer, str_key = '%cd')
General Comments 0
You need to be logged in to leave comments. Login now