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