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