##// END OF EJS Templates
fixed bug in IPython/Extensions/ipy_stock_completer.py that caused shlex_split to ...
jstenar -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,248 +1,248 b''
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 def shlex_split(x):
169 169 """Helper function to split lines into segments."""
170 170 #shlex.split raise exception if syntax error in sh syntax
171 171 #for example if no closing " is found. This function keeps dropping
172 172 #the last character of the line until shlex.split does not raise
173 173 #exception. Adds end of the line to the result of shlex.split
174 174 #example: %run "c:/python -> ['%run','"c:/python']
175 175 endofline=[]
176 176 while x!="":
177 177 try:
178 178 comps=shlex.split(x)
179 if endofline>=1:
179 if len(endofline)>=1:
180 180 comps.append("".join(endofline))
181 181 return comps
182 182 except ValueError:
183 183 endofline=[x[-1:]]+endofline
184 184 x=x[:-1]
185 185 return ["".join(endofline)]
186 186
187 187 def runlistpy(self, event):
188 188 comps = shlex_split(event.line)
189 189 relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"")
190 190
191 191 #print "\nev=",event # dbg
192 192 #print "rp=",relpath # dbg
193 193 #print 'comps=',comps # dbg
194 194
195 195 lglob = glob.glob
196 196 isdir = os.path.isdir
197 197 if relpath.startswith('~'):
198 198 relpath = os.path.expanduser(relpath)
199 199 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*')
200 200 if isdir(f)]
201 201
202 202 # Find if the user has already typed the first filename, after which we
203 203 # should complete on all files, since after the first one other files may
204 204 # be arguments to the input script.
205 205 #filter(
206 206 if filter(lambda f: f.endswith('.py') or f.endswith('.ipy'),comps):
207 207 pys = [f.replace('\\','/') for f in lglob('*')]
208 208 else:
209 209 pys = [f.replace('\\','/')
210 210 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy')]
211 211 return dirs + pys
212 212
213 213 ip.set_hook('complete_command', runlistpy, str_key = '%run')
214 214
215 215 def cd_completer(self, event):
216 216 relpath = event.symbol
217 217 #print event # dbg
218 218 if '-b' in event.line:
219 219 # return only bookmark completions
220 220 bkms = self.db.get('bookmarks',{})
221 221 return bkms.keys()
222 222
223 223
224 224 if event.symbol == '-':
225 225 # jump in directory history by number
226 226 ents = ['-%d [%s]' % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
227 227 if len(ents) > 1:
228 228 return ents
229 229 return []
230 230
231 231 if relpath.startswith('~'):
232 232 relpath = os.path.expanduser(relpath).replace('\\','/')
233 233 found = []
234 234 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
235 235 if os.path.isdir(f)]:
236 236 if ' ' in d:
237 237 # we don't want to deal with any of that, complex code
238 238 # for this is elsewhere
239 239 raise IPython.ipapi.TryNext
240 240 found.append( d )
241 241
242 242 if not found:
243 243 if os.path.isdir(relpath):
244 244 return [relpath]
245 245 raise IPython.ipapi.TryNext
246 246 return found
247 247
248 248 ip.set_hook('complete_command', cd_completer, str_key = '%cd')
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now