##// END OF EJS Templates
Change to `Creates` as function is now singular.
Matthias Bussonnier -
Show More
@@ -1,796 +1,796 b''
1 1 """Implementation of magic functions for interaction with the OS.
2 2
3 3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 4 builtin.
5 5 """
6 6 from __future__ import print_function
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (c) 2012 The IPython Development Team.
9 9 #
10 10 # Distributed under the terms of the Modified BSD License.
11 11 #
12 12 # The full license is in the file COPYING.txt, distributed with this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 # Stdlib
20 20 import io
21 21 import os
22 22 import re
23 23 import sys
24 24 from pprint import pformat
25 25
26 26 # Our own packages
27 27 from IPython.core import magic_arguments
28 28 from IPython.core import oinspect
29 29 from IPython.core import page
30 30 from IPython.core.alias import AliasError, Alias
31 31 from IPython.core.error import UsageError
32 32 from IPython.core.magic import (
33 33 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
34 34 )
35 35 from IPython.testing.skipdoctest import skip_doctest
36 36 from IPython.utils.openpy import source_to_unicode
37 37 from IPython.utils.path import unquote_filename
38 38 from IPython.utils.process import abbrev_cwd
39 39 from IPython.utils import py3compat
40 40 from IPython.utils.py3compat import unicode_type
41 41 from IPython.utils.terminal import set_term_title
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Magic implementation classes
45 45 #-----------------------------------------------------------------------------
46 46 @magics_class
47 47 class OSMagics(Magics):
48 48 """Magics to interact with the underlying OS (shell-type functionality).
49 49 """
50 50
51 51 @skip_doctest
52 52 @line_magic
53 53 def alias(self, parameter_s=''):
54 54 """Define an alias for a system command.
55 55
56 56 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
57 57
58 58 Then, typing 'alias_name params' will execute the system command 'cmd
59 59 params' (from your underlying operating system).
60 60
61 61 Aliases have lower precedence than magic functions and Python normal
62 62 variables, so if 'foo' is both a Python variable and an alias, the
63 63 alias can not be executed until 'del foo' removes the Python variable.
64 64
65 65 You can use the %l specifier in an alias definition to represent the
66 66 whole line when the alias is called. For example::
67 67
68 68 In [2]: alias bracket echo "Input in brackets: <%l>"
69 69 In [3]: bracket hello world
70 70 Input in brackets: <hello world>
71 71
72 72 You can also define aliases with parameters using %s specifiers (one
73 73 per parameter)::
74 74
75 75 In [1]: alias parts echo first %s second %s
76 76 In [2]: %parts A B
77 77 first A second B
78 78 In [3]: %parts A
79 79 Incorrect number of arguments: 2 expected.
80 80 parts is an alias to: 'echo first %s second %s'
81 81
82 82 Note that %l and %s are mutually exclusive. You can only use one or
83 83 the other in your aliases.
84 84
85 85 Aliases expand Python variables just like system calls using ! or !!
86 86 do: all expressions prefixed with '$' get expanded. For details of
87 87 the semantic rules, see PEP-215:
88 88 http://www.python.org/peps/pep-0215.html. This is the library used by
89 89 IPython for variable expansion. If you want to access a true shell
90 90 variable, an extra $ is necessary to prevent its expansion by
91 91 IPython::
92 92
93 93 In [6]: alias show echo
94 94 In [7]: PATH='A Python string'
95 95 In [8]: show $PATH
96 96 A Python string
97 97 In [9]: show $$PATH
98 98 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
99 99
100 100 You can use the alias facility to acess all of $PATH. See the %rehashx
101 function, which automatically create aliases for the contents of your
101 function, which automatically creates aliases for the contents of your
102 102 $PATH.
103 103
104 104 If called with no parameters, %alias prints the current alias table."""
105 105
106 106 par = parameter_s.strip()
107 107 if not par:
108 108 aliases = sorted(self.shell.alias_manager.aliases)
109 109 # stored = self.shell.db.get('stored_aliases', {} )
110 110 # for k, v in stored:
111 111 # atab.append(k, v[0])
112 112
113 113 print("Total number of aliases:", len(aliases))
114 114 sys.stdout.flush()
115 115 return aliases
116 116
117 117 # Now try to define a new one
118 118 try:
119 119 alias,cmd = par.split(None, 1)
120 120 except TypeError:
121 121 print(oinspect.getdoc(self.alias))
122 122 return
123 123
124 124 try:
125 125 self.shell.alias_manager.define_alias(alias, cmd)
126 126 except AliasError as e:
127 127 print(e)
128 128 # end magic_alias
129 129
130 130 @line_magic
131 131 def unalias(self, parameter_s=''):
132 132 """Remove an alias"""
133 133
134 134 aname = parameter_s.strip()
135 135 try:
136 136 self.shell.alias_manager.undefine_alias(aname)
137 137 except ValueError as e:
138 138 print(e)
139 139 return
140 140
141 141 stored = self.shell.db.get('stored_aliases', {} )
142 142 if aname in stored:
143 143 print("Removing %stored alias",aname)
144 144 del stored[aname]
145 145 self.shell.db['stored_aliases'] = stored
146 146
147 147 @line_magic
148 148 def rehashx(self, parameter_s=''):
149 149 """Update the alias table with all executable files in $PATH.
150 150
151 151 rehashx explicitly checks that every entry in $PATH is a file
152 152 with execute access (os.X_OK).
153 153
154 154 Under Windows, it checks executability as a match against a
155 155 '|'-separated string of extensions, stored in the IPython config
156 156 variable win_exec_ext. This defaults to 'exe|com|bat'.
157 157
158 158 This function also resets the root module cache of module completer,
159 159 used on slow filesystems.
160 160 """
161 161 from IPython.core.alias import InvalidAliasError
162 162
163 163 # for the benefit of module completer in ipy_completers.py
164 164 del self.shell.db['rootmodules_cache']
165 165
166 166 path = [os.path.abspath(os.path.expanduser(p)) for p in
167 167 os.environ.get('PATH','').split(os.pathsep)]
168 168
169 169 syscmdlist = []
170 170 # Now define isexec in a cross platform manner.
171 171 if os.name == 'posix':
172 172 isexec = lambda fname:os.path.isfile(fname) and \
173 173 os.access(fname,os.X_OK)
174 174 else:
175 175 try:
176 176 winext = os.environ['pathext'].replace(';','|').replace('.','')
177 177 except KeyError:
178 178 winext = 'exe|com|bat|py'
179 179 if 'py' not in winext:
180 180 winext += '|py'
181 181 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
182 182 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
183 183 savedir = py3compat.getcwd()
184 184
185 185 # Now walk the paths looking for executables to alias.
186 186 try:
187 187 # write the whole loop for posix/Windows so we don't have an if in
188 188 # the innermost part
189 189 if os.name == 'posix':
190 190 for pdir in path:
191 191 try:
192 192 os.chdir(pdir)
193 193 dirlist = os.listdir(pdir)
194 194 except OSError:
195 195 continue
196 196 for ff in dirlist:
197 197 if isexec(ff):
198 198 try:
199 199 # Removes dots from the name since ipython
200 200 # will assume names with dots to be python.
201 201 if not self.shell.alias_manager.is_alias(ff):
202 202 self.shell.alias_manager.define_alias(
203 203 ff.replace('.',''), ff)
204 204 except InvalidAliasError:
205 205 pass
206 206 else:
207 207 syscmdlist.append(ff)
208 208 else:
209 209 no_alias = Alias.blacklist
210 210 for pdir in path:
211 211 try:
212 212 os.chdir(pdir)
213 213 dirlist = os.listdir(pdir)
214 214 except OSError:
215 215 continue
216 216 for ff in dirlist:
217 217 base, ext = os.path.splitext(ff)
218 218 if isexec(ff) and base.lower() not in no_alias:
219 219 if ext.lower() == '.exe':
220 220 ff = base
221 221 try:
222 222 # Removes dots from the name since ipython
223 223 # will assume names with dots to be python.
224 224 self.shell.alias_manager.define_alias(
225 225 base.lower().replace('.',''), ff)
226 226 except InvalidAliasError:
227 227 pass
228 228 syscmdlist.append(ff)
229 229 self.shell.db['syscmdlist'] = syscmdlist
230 230 finally:
231 231 os.chdir(savedir)
232 232
233 233 @skip_doctest
234 234 @line_magic
235 235 def pwd(self, parameter_s=''):
236 236 """Return the current working directory path.
237 237
238 238 Examples
239 239 --------
240 240 ::
241 241
242 242 In [9]: pwd
243 243 Out[9]: '/home/tsuser/sprint/ipython'
244 244 """
245 245 return py3compat.getcwd()
246 246
247 247 @skip_doctest
248 248 @line_magic
249 249 def cd(self, parameter_s=''):
250 250 """Change the current working directory.
251 251
252 252 This command automatically maintains an internal list of directories
253 253 you visit during your IPython session, in the variable _dh. The
254 254 command %dhist shows this history nicely formatted. You can also
255 255 do 'cd -<tab>' to see directory history conveniently.
256 256
257 257 Usage:
258 258
259 259 cd 'dir': changes to directory 'dir'.
260 260
261 261 cd -: changes to the last visited directory.
262 262
263 263 cd -<n>: changes to the n-th directory in the directory history.
264 264
265 265 cd --foo: change to directory that matches 'foo' in history
266 266
267 267 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
268 268 (note: cd <bookmark_name> is enough if there is no
269 269 directory <bookmark_name>, but a bookmark with the name exists.)
270 270 'cd -b <tab>' allows you to tab-complete bookmark names.
271 271
272 272 Options:
273 273
274 274 -q: quiet. Do not print the working directory after the cd command is
275 275 executed. By default IPython's cd command does print this directory,
276 276 since the default prompts do not display path information.
277 277
278 278 Note that !cd doesn't work for this purpose because the shell where
279 279 !command runs is immediately discarded after executing 'command'.
280 280
281 281 Examples
282 282 --------
283 283 ::
284 284
285 285 In [10]: cd parent/child
286 286 /home/tsuser/parent/child
287 287 """
288 288
289 289 oldcwd = py3compat.getcwd()
290 290 numcd = re.match(r'(-)(\d+)$',parameter_s)
291 291 # jump in directory history by number
292 292 if numcd:
293 293 nn = int(numcd.group(2))
294 294 try:
295 295 ps = self.shell.user_ns['_dh'][nn]
296 296 except IndexError:
297 297 print('The requested directory does not exist in history.')
298 298 return
299 299 else:
300 300 opts = {}
301 301 elif parameter_s.startswith('--'):
302 302 ps = None
303 303 fallback = None
304 304 pat = parameter_s[2:]
305 305 dh = self.shell.user_ns['_dh']
306 306 # first search only by basename (last component)
307 307 for ent in reversed(dh):
308 308 if pat in os.path.basename(ent) and os.path.isdir(ent):
309 309 ps = ent
310 310 break
311 311
312 312 if fallback is None and pat in ent and os.path.isdir(ent):
313 313 fallback = ent
314 314
315 315 # if we have no last part match, pick the first full path match
316 316 if ps is None:
317 317 ps = fallback
318 318
319 319 if ps is None:
320 320 print("No matching entry in directory history")
321 321 return
322 322 else:
323 323 opts = {}
324 324
325 325
326 326 else:
327 327 #turn all non-space-escaping backslashes to slashes,
328 328 # for c:\windows\directory\names\
329 329 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
330 330 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
331 331 # jump to previous
332 332 if ps == '-':
333 333 try:
334 334 ps = self.shell.user_ns['_dh'][-2]
335 335 except IndexError:
336 336 raise UsageError('%cd -: No previous directory to change to.')
337 337 # jump to bookmark if needed
338 338 else:
339 339 if not os.path.isdir(ps) or 'b' in opts:
340 340 bkms = self.shell.db.get('bookmarks', {})
341 341
342 342 if ps in bkms:
343 343 target = bkms[ps]
344 344 print('(bookmark:%s) -> %s' % (ps, target))
345 345 ps = target
346 346 else:
347 347 if 'b' in opts:
348 348 raise UsageError("Bookmark '%s' not found. "
349 349 "Use '%%bookmark -l' to see your bookmarks." % ps)
350 350
351 351 # strip extra quotes on Windows, because os.chdir doesn't like them
352 352 ps = unquote_filename(ps)
353 353 # at this point ps should point to the target dir
354 354 if ps:
355 355 try:
356 356 os.chdir(os.path.expanduser(ps))
357 357 if hasattr(self.shell, 'term_title') and self.shell.term_title:
358 358 set_term_title('IPython: ' + abbrev_cwd())
359 359 except OSError:
360 360 print(sys.exc_info()[1])
361 361 else:
362 362 cwd = py3compat.getcwd()
363 363 dhist = self.shell.user_ns['_dh']
364 364 if oldcwd != cwd:
365 365 dhist.append(cwd)
366 366 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
367 367
368 368 else:
369 369 os.chdir(self.shell.home_dir)
370 370 if hasattr(self.shell, 'term_title') and self.shell.term_title:
371 371 set_term_title('IPython: ' + '~')
372 372 cwd = py3compat.getcwd()
373 373 dhist = self.shell.user_ns['_dh']
374 374
375 375 if oldcwd != cwd:
376 376 dhist.append(cwd)
377 377 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
378 378 if not 'q' in opts and self.shell.user_ns['_dh']:
379 379 print(self.shell.user_ns['_dh'][-1])
380 380
381 381 @line_magic
382 382 def env(self, parameter_s=''):
383 383 """Get, set, or list environment variables.
384 384
385 385 Usage:\\
386 386
387 387 %env: lists all environment variables/values
388 388 %env var: get value for var
389 389 %env var val: set value for var
390 390 %env var=val: set value for var
391 391 %env var=$val: set value for var, using python expansion if possible
392 392 """
393 393 if parameter_s.strip():
394 394 split = '=' if '=' in parameter_s else ' '
395 395 bits = parameter_s.split(split)
396 396 if len(bits) == 1:
397 397 key = parameter_s.strip()
398 398 if key in os.environ:
399 399 return os.environ[key]
400 400 else:
401 401 err = "Environment does not have key: {0}".format(key)
402 402 raise UsageError(err)
403 403 if len(bits) > 1:
404 404 return self.set_env(parameter_s)
405 405 return dict(os.environ)
406 406
407 407 @line_magic
408 408 def set_env(self, parameter_s):
409 409 """Set environment variables. Assumptions are that either "val" is a
410 410 name in the user namespace, or val is something that evaluates to a
411 411 string.
412 412
413 413 Usage:\\
414 414 %set_env var val: set value for var
415 415 %set_env var=val: set value for var
416 416 %set_env var=$val: set value for var, using python expansion if possible
417 417 """
418 418 split = '=' if '=' in parameter_s else ' '
419 419 bits = parameter_s.split(split, 1)
420 420 if not parameter_s.strip() or len(bits)<2:
421 421 raise UsageError("usage is 'set_env var=val'")
422 422 var = bits[0].strip()
423 423 val = bits[1].strip()
424 424 if re.match(r'.*\s.*', var):
425 425 # an environment variable with whitespace is almost certainly
426 426 # not what the user intended. what's more likely is the wrong
427 427 # split was chosen, ie for "set_env cmd_args A=B", we chose
428 428 # '=' for the split and should have chosen ' '. to get around
429 429 # this, users should just assign directly to os.environ or use
430 430 # standard magic {var} expansion.
431 431 err = "refusing to set env var with whitespace: '{0}'"
432 432 err = err.format(val)
433 433 raise UsageError(err)
434 434 os.environ[py3compat.cast_bytes_py2(var)] = py3compat.cast_bytes_py2(val)
435 435 print('env: {0}={1}'.format(var,val))
436 436
437 437 @line_magic
438 438 def pushd(self, parameter_s=''):
439 439 """Place the current dir on stack and change directory.
440 440
441 441 Usage:\\
442 442 %pushd ['dirname']
443 443 """
444 444
445 445 dir_s = self.shell.dir_stack
446 446 tgt = os.path.expanduser(unquote_filename(parameter_s))
447 447 cwd = py3compat.getcwd().replace(self.shell.home_dir,'~')
448 448 if tgt:
449 449 self.cd(parameter_s)
450 450 dir_s.insert(0,cwd)
451 451 return self.shell.magic('dirs')
452 452
453 453 @line_magic
454 454 def popd(self, parameter_s=''):
455 455 """Change to directory popped off the top of the stack.
456 456 """
457 457 if not self.shell.dir_stack:
458 458 raise UsageError("%popd on empty stack")
459 459 top = self.shell.dir_stack.pop(0)
460 460 self.cd(top)
461 461 print("popd ->",top)
462 462
463 463 @line_magic
464 464 def dirs(self, parameter_s=''):
465 465 """Return the current directory stack."""
466 466
467 467 return self.shell.dir_stack
468 468
469 469 @line_magic
470 470 def dhist(self, parameter_s=''):
471 471 """Print your history of visited directories.
472 472
473 473 %dhist -> print full history\\
474 474 %dhist n -> print last n entries only\\
475 475 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
476 476
477 477 This history is automatically maintained by the %cd command, and
478 478 always available as the global list variable _dh. You can use %cd -<n>
479 479 to go to directory number <n>.
480 480
481 481 Note that most of time, you should view directory history by entering
482 482 cd -<TAB>.
483 483
484 484 """
485 485
486 486 dh = self.shell.user_ns['_dh']
487 487 if parameter_s:
488 488 try:
489 489 args = map(int,parameter_s.split())
490 490 except:
491 491 self.arg_err(self.dhist)
492 492 return
493 493 if len(args) == 1:
494 494 ini,fin = max(len(dh)-(args[0]),0),len(dh)
495 495 elif len(args) == 2:
496 496 ini,fin = args
497 497 fin = min(fin, len(dh))
498 498 else:
499 499 self.arg_err(self.dhist)
500 500 return
501 501 else:
502 502 ini,fin = 0,len(dh)
503 503 print('Directory history (kept in _dh)')
504 504 for i in range(ini, fin):
505 505 print("%d: %s" % (i, dh[i]))
506 506
507 507 @skip_doctest
508 508 @line_magic
509 509 def sc(self, parameter_s=''):
510 510 """Shell capture - run shell command and capture output (DEPRECATED use !).
511 511
512 512 DEPRECATED. Suboptimal, retained for backwards compatibility.
513 513
514 514 You should use the form 'var = !command' instead. Example:
515 515
516 516 "%sc -l myfiles = ls ~" should now be written as
517 517
518 518 "myfiles = !ls ~"
519 519
520 520 myfiles.s, myfiles.l and myfiles.n still apply as documented
521 521 below.
522 522
523 523 --
524 524 %sc [options] varname=command
525 525
526 526 IPython will run the given command using commands.getoutput(), and
527 527 will then update the user's interactive namespace with a variable
528 528 called varname, containing the value of the call. Your command can
529 529 contain shell wildcards, pipes, etc.
530 530
531 531 The '=' sign in the syntax is mandatory, and the variable name you
532 532 supply must follow Python's standard conventions for valid names.
533 533
534 534 (A special format without variable name exists for internal use)
535 535
536 536 Options:
537 537
538 538 -l: list output. Split the output on newlines into a list before
539 539 assigning it to the given variable. By default the output is stored
540 540 as a single string.
541 541
542 542 -v: verbose. Print the contents of the variable.
543 543
544 544 In most cases you should not need to split as a list, because the
545 545 returned value is a special type of string which can automatically
546 546 provide its contents either as a list (split on newlines) or as a
547 547 space-separated string. These are convenient, respectively, either
548 548 for sequential processing or to be passed to a shell command.
549 549
550 550 For example::
551 551
552 552 # Capture into variable a
553 553 In [1]: sc a=ls *py
554 554
555 555 # a is a string with embedded newlines
556 556 In [2]: a
557 557 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
558 558
559 559 # which can be seen as a list:
560 560 In [3]: a.l
561 561 Out[3]: ['setup.py', 'win32_manual_post_install.py']
562 562
563 563 # or as a whitespace-separated string:
564 564 In [4]: a.s
565 565 Out[4]: 'setup.py win32_manual_post_install.py'
566 566
567 567 # a.s is useful to pass as a single command line:
568 568 In [5]: !wc -l $a.s
569 569 146 setup.py
570 570 130 win32_manual_post_install.py
571 571 276 total
572 572
573 573 # while the list form is useful to loop over:
574 574 In [6]: for f in a.l:
575 575 ...: !wc -l $f
576 576 ...:
577 577 146 setup.py
578 578 130 win32_manual_post_install.py
579 579
580 580 Similarly, the lists returned by the -l option are also special, in
581 581 the sense that you can equally invoke the .s attribute on them to
582 582 automatically get a whitespace-separated string from their contents::
583 583
584 584 In [7]: sc -l b=ls *py
585 585
586 586 In [8]: b
587 587 Out[8]: ['setup.py', 'win32_manual_post_install.py']
588 588
589 589 In [9]: b.s
590 590 Out[9]: 'setup.py win32_manual_post_install.py'
591 591
592 592 In summary, both the lists and strings used for output capture have
593 593 the following special attributes::
594 594
595 595 .l (or .list) : value as list.
596 596 .n (or .nlstr): value as newline-separated string.
597 597 .s (or .spstr): value as space-separated string.
598 598 """
599 599
600 600 opts,args = self.parse_options(parameter_s, 'lv')
601 601 # Try to get a variable name and command to run
602 602 try:
603 603 # the variable name must be obtained from the parse_options
604 604 # output, which uses shlex.split to strip options out.
605 605 var,_ = args.split('=', 1)
606 606 var = var.strip()
607 607 # But the command has to be extracted from the original input
608 608 # parameter_s, not on what parse_options returns, to avoid the
609 609 # quote stripping which shlex.split performs on it.
610 610 _,cmd = parameter_s.split('=', 1)
611 611 except ValueError:
612 612 var,cmd = '',''
613 613 # If all looks ok, proceed
614 614 split = 'l' in opts
615 615 out = self.shell.getoutput(cmd, split=split)
616 616 if 'v' in opts:
617 617 print('%s ==\n%s' % (var, pformat(out)))
618 618 if var:
619 619 self.shell.user_ns.update({var:out})
620 620 else:
621 621 return out
622 622
623 623 @line_cell_magic
624 624 def sx(self, line='', cell=None):
625 625 """Shell execute - run shell command and capture output (!! is short-hand).
626 626
627 627 %sx command
628 628
629 629 IPython will run the given command using commands.getoutput(), and
630 630 return the result formatted as a list (split on '\\n'). Since the
631 631 output is _returned_, it will be stored in ipython's regular output
632 632 cache Out[N] and in the '_N' automatic variables.
633 633
634 634 Notes:
635 635
636 636 1) If an input line begins with '!!', then %sx is automatically
637 637 invoked. That is, while::
638 638
639 639 !ls
640 640
641 641 causes ipython to simply issue system('ls'), typing::
642 642
643 643 !!ls
644 644
645 645 is a shorthand equivalent to::
646 646
647 647 %sx ls
648 648
649 649 2) %sx differs from %sc in that %sx automatically splits into a list,
650 650 like '%sc -l'. The reason for this is to make it as easy as possible
651 651 to process line-oriented shell output via further python commands.
652 652 %sc is meant to provide much finer control, but requires more
653 653 typing.
654 654
655 655 3) Just like %sc -l, this is a list with special attributes:
656 656 ::
657 657
658 658 .l (or .list) : value as list.
659 659 .n (or .nlstr): value as newline-separated string.
660 660 .s (or .spstr): value as whitespace-separated string.
661 661
662 662 This is very useful when trying to use such lists as arguments to
663 663 system commands."""
664 664
665 665 if cell is None:
666 666 # line magic
667 667 return self.shell.getoutput(line)
668 668 else:
669 669 opts,args = self.parse_options(line, '', 'out=')
670 670 output = self.shell.getoutput(cell)
671 671 out_name = opts.get('out', opts.get('o'))
672 672 if out_name:
673 673 self.shell.user_ns[out_name] = output
674 674 else:
675 675 return output
676 676
677 677 system = line_cell_magic('system')(sx)
678 678 bang = cell_magic('!')(sx)
679 679
680 680 @line_magic
681 681 def bookmark(self, parameter_s=''):
682 682 """Manage IPython's bookmark system.
683 683
684 684 %bookmark <name> - set bookmark to current dir
685 685 %bookmark <name> <dir> - set bookmark to <dir>
686 686 %bookmark -l - list all bookmarks
687 687 %bookmark -d <name> - remove bookmark
688 688 %bookmark -r - remove all bookmarks
689 689
690 690 You can later on access a bookmarked folder with::
691 691
692 692 %cd -b <name>
693 693
694 694 or simply '%cd <name>' if there is no directory called <name> AND
695 695 there is such a bookmark defined.
696 696
697 697 Your bookmarks persist through IPython sessions, but they are
698 698 associated with each profile."""
699 699
700 700 opts,args = self.parse_options(parameter_s,'drl',mode='list')
701 701 if len(args) > 2:
702 702 raise UsageError("%bookmark: too many arguments")
703 703
704 704 bkms = self.shell.db.get('bookmarks',{})
705 705
706 706 if 'd' in opts:
707 707 try:
708 708 todel = args[0]
709 709 except IndexError:
710 710 raise UsageError(
711 711 "%bookmark -d: must provide a bookmark to delete")
712 712 else:
713 713 try:
714 714 del bkms[todel]
715 715 except KeyError:
716 716 raise UsageError(
717 717 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
718 718
719 719 elif 'r' in opts:
720 720 bkms = {}
721 721 elif 'l' in opts:
722 722 bks = sorted(bkms)
723 723 if bks:
724 724 size = max(map(len, bks))
725 725 else:
726 726 size = 0
727 727 fmt = '%-'+str(size)+'s -> %s'
728 728 print('Current bookmarks:')
729 729 for bk in bks:
730 730 print(fmt % (bk, bkms[bk]))
731 731 else:
732 732 if not args:
733 733 raise UsageError("%bookmark: You must specify the bookmark name")
734 734 elif len(args)==1:
735 735 bkms[args[0]] = py3compat.getcwd()
736 736 elif len(args)==2:
737 737 bkms[args[0]] = args[1]
738 738 self.shell.db['bookmarks'] = bkms
739 739
740 740 @line_magic
741 741 def pycat(self, parameter_s=''):
742 742 """Show a syntax-highlighted file through a pager.
743 743
744 744 This magic is similar to the cat utility, but it will assume the file
745 745 to be Python source and will show it with syntax highlighting.
746 746
747 747 This magic command can either take a local filename, an url,
748 748 an history range (see %history) or a macro as argument ::
749 749
750 750 %pycat myscript.py
751 751 %pycat 7-27
752 752 %pycat myMacro
753 753 %pycat http://www.example.com/myscript.py
754 754 """
755 755 if not parameter_s:
756 756 raise UsageError('Missing filename, URL, input history range, '
757 757 'or macro.')
758 758
759 759 try :
760 760 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
761 761 except (ValueError, IOError):
762 762 print("Error: no such file, variable, URL, history range or macro")
763 763 return
764 764
765 765 page.page(self.shell.pycolorize(source_to_unicode(cont)))
766 766
767 767 @magic_arguments.magic_arguments()
768 768 @magic_arguments.argument(
769 769 '-a', '--append', action='store_true', default=False,
770 770 help='Append contents of the cell to an existing file. '
771 771 'The file will be created if it does not exist.'
772 772 )
773 773 @magic_arguments.argument(
774 774 'filename', type=unicode_type,
775 775 help='file to write'
776 776 )
777 777 @cell_magic
778 778 def writefile(self, line, cell):
779 779 """Write the contents of the cell to a file.
780 780
781 781 The file will be overwritten unless the -a (--append) flag is specified.
782 782 """
783 783 args = magic_arguments.parse_argstring(self.writefile, line)
784 784 filename = os.path.expanduser(unquote_filename(args.filename))
785 785
786 786 if os.path.exists(filename):
787 787 if args.append:
788 788 print("Appending to %s" % filename)
789 789 else:
790 790 print("Overwriting %s" % filename)
791 791 else:
792 792 print("Writing %s" % filename)
793 793
794 794 mode = 'a' if args.append else 'w'
795 795 with io.open(filename, mode, encoding='utf-8') as f:
796 796 f.write(cell)
General Comments 0
You need to be logged in to leave comments. Login now