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