Show More
@@ -119,6 +119,52 b' def mark_dirs(matches):' | |||||
119 | return out |
|
119 | return out | |
120 |
|
120 | |||
121 |
|
121 | |||
|
122 | def expand_user(path): | |||
|
123 | """Expand '~'-style usernames in strings. | |||
|
124 | ||||
|
125 | This is similar to :func:`os.path.expanduser`, but it computes and returns | |||
|
126 | extra information that will be useful if the input was being used in | |||
|
127 | computing completions, and you wish to return the completions with the | |||
|
128 | original '~' instead of its expanded value. | |||
|
129 | ||||
|
130 | Parameters | |||
|
131 | ---------- | |||
|
132 | path : str | |||
|
133 | String to be expanded. If no ~ is present, the output is the same as the | |||
|
134 | input. | |||
|
135 | ||||
|
136 | Returns | |||
|
137 | ------- | |||
|
138 | newpath : str | |||
|
139 | Result of ~ expansion in the input path. | |||
|
140 | tilde_expand : bool | |||
|
141 | Whether any expansion was performed or not. | |||
|
142 | tilde_val : str | |||
|
143 | The value that ~ was replaced with. | |||
|
144 | """ | |||
|
145 | # Default values | |||
|
146 | tilde_expand = False | |||
|
147 | tilde_val = '' | |||
|
148 | newpath = path | |||
|
149 | ||||
|
150 | if path.startswith('~'): | |||
|
151 | tilde_expand = True | |||
|
152 | rest = path[1:] | |||
|
153 | newpath = os.path.expanduser(path) | |||
|
154 | tilde_val = newpath.replace(rest, '') | |||
|
155 | ||||
|
156 | return newpath, tilde_expand, tilde_val | |||
|
157 | ||||
|
158 | ||||
|
159 | def compress_user(path, tilde_expand, tilde_val): | |||
|
160 | """Does the opposite of expand_user, with its outputs. | |||
|
161 | """ | |||
|
162 | if tilde_expand: | |||
|
163 | return path.replace(tilde_val, '~') | |||
|
164 | else: | |||
|
165 | return path | |||
|
166 | ||||
|
167 | ||||
122 | def single_dir_expand(matches): |
|
168 | def single_dir_expand(matches): | |
123 | "Recursively expand match lists containing a single dir." |
|
169 | "Recursively expand match lists containing a single dir." | |
124 |
|
170 |
@@ -28,6 +28,7 b' from time import time' | |||||
28 | from zipimport import zipimporter |
|
28 | from zipimport import zipimporter | |
29 |
|
29 | |||
30 | # Our own imports |
|
30 | # Our own imports | |
|
31 | from IPython.core.completer import expand_user, compress_user | |||
31 | from IPython.core.error import TryNext |
|
32 | from IPython.core.error import TryNext | |
32 |
|
33 | |||
33 | # FIXME: this should be pulled in with the right call via the component system |
|
34 | # FIXME: this should be pulled in with the right call via the component system | |
@@ -65,6 +66,10 b' def shlex_split(x):' | |||||
65 | # Example: |
|
66 | # Example: | |
66 | # %run "c:/python -> ['%run','"c:/python'] |
|
67 | # %run "c:/python -> ['%run','"c:/python'] | |
67 |
|
68 | |||
|
69 | # shlex.split has unicode bugs, so encode first to str | |||
|
70 | if isinstance(x, unicode): | |||
|
71 | x = x.encode(sys.stdin.encoding) | |||
|
72 | ||||
68 | endofline = [] |
|
73 | endofline = [] | |
69 | while x != '': |
|
74 | while x != '': | |
70 | try: |
|
75 | try: | |
@@ -253,6 +258,8 b' def module_completer(self,event):' | |||||
253 |
|
258 | |||
254 | return module_completion(event.line) |
|
259 | return module_completion(event.line) | |
255 |
|
260 | |||
|
261 | # FIXME: there's a lot of logic common to the run, cd and builtin file | |||
|
262 | # completers, that is currently reimplemented in each. | |||
256 |
|
263 | |||
257 | def magic_run_completer(self, event): |
|
264 | def magic_run_completer(self, event): | |
258 | """Complete files that end in .py or .ipy for the %run command. |
|
265 | """Complete files that end in .py or .ipy for the %run command. | |
@@ -260,14 +267,14 b' def magic_run_completer(self, event):' | |||||
260 | comps = shlex_split(event.line) |
|
267 | comps = shlex_split(event.line) | |
261 | relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"") |
|
268 | relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"") | |
262 |
|
269 | |||
263 |
#print |
|
270 | #print("\nev=", event) # dbg | |
264 |
#print |
|
271 | #print("rp=", relpath) # dbg | |
265 |
#print |
|
272 | #print('comps=', comps) # dbg | |
266 |
|
273 | |||
267 | lglob = glob.glob |
|
274 | lglob = glob.glob | |
268 | isdir = os.path.isdir |
|
275 | isdir = os.path.isdir | |
269 | if relpath.startswith('~'): |
|
276 | relpath, tilde_expand, tilde_val = expand_user(relpath) | |
270 | relpath = os.path.expanduser(relpath) |
|
277 | ||
271 | dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)] |
|
278 | dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)] | |
272 |
|
279 | |||
273 | # Find if the user has already typed the first filename, after which we |
|
280 | # Find if the user has already typed the first filename, after which we | |
@@ -280,7 +287,8 b' def magic_run_completer(self, event):' | |||||
280 | pys = [f.replace('\\','/') |
|
287 | pys = [f.replace('\\','/') | |
281 | for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') + |
|
288 | for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') + | |
282 | lglob(relpath + '*.pyw')] |
|
289 | lglob(relpath + '*.pyw')] | |
283 | return dirs + pys |
|
290 | #print('run comp:', dirs+pys) # dbg | |
|
291 | return [compress_user(p, tilde_expand, tilde_val) for p in dirs+pys] | |||
284 |
|
292 | |||
285 |
|
293 | |||
286 | def cd_completer(self, event): |
|
294 | def cd_completer(self, event): | |
@@ -309,8 +317,9 b' def cd_completer(self, event):' | |||||
309 | if event.symbol.startswith('--'): |
|
317 | if event.symbol.startswith('--'): | |
310 | return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']] |
|
318 | return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']] | |
311 |
|
319 | |||
312 | if relpath.startswith('~'): |
|
320 | # Expand ~ in path and normalize directory separators. | |
313 | relpath = os.path.expanduser(relpath).replace('\\','/') |
|
321 | relpath, tilde_expand, tilde_val = expand_user(relpath) | |
|
322 | relpath = relpath.replace('\\','/') | |||
314 |
|
323 | |||
315 | found = [] |
|
324 | found = [] | |
316 | for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*') |
|
325 | for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*') | |
@@ -324,7 +333,7 b' def cd_completer(self, event):' | |||||
324 |
|
333 | |||
325 | if not found: |
|
334 | if not found: | |
326 | if os.path.isdir(relpath): |
|
335 | if os.path.isdir(relpath): | |
327 | return [relpath] |
|
336 | return [compress_user(relpath, tilde_expand, tilde_val)] | |
328 |
|
337 | |||
329 | # if no completions so far, try bookmarks |
|
338 | # if no completions so far, try bookmarks | |
330 | bks = self.db.get('bookmarks',{}).keys() |
|
339 | bks = self.db.get('bookmarks',{}).keys() | |
@@ -334,4 +343,4 b' def cd_completer(self, event):' | |||||
334 |
|
343 | |||
335 | raise TryNext |
|
344 | raise TryNext | |
336 |
|
345 | |||
337 | return found |
|
346 | return [compress_user(p, tilde_expand, tilde_val) for p in found] |
General Comments 0
You need to be logged in to leave comments.
Login now