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