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