##// END OF EJS Templates
Merge pull request #2124 from bfroehle/use_alias_magic...
Fernando Perez -
r8023:a5beb59f merge
parent child Browse files
Show More
@@ -2053,6 +2053,12 b' class InteractiveShell(SingletonConfigurable):'
2053 2053 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2054 2054 )
2055 2055
2056 # Register Magic Aliases
2057 mman = self.magics_manager
2058 mman.register_alias('ed', 'edit')
2059 mman.register_alias('hist', 'history')
2060 mman.register_alias('rep', 'recall')
2061
2056 2062 # FIXME: Move the color initialization to the DisplayHook, which
2057 2063 # should be split into a prompt manager and displayhook. We probably
2058 2064 # even need a centralize colors management object.
@@ -452,6 +452,36 b' class MagicsManager(Configurable):'
452 452 setattr(self.user_magics, name, meth)
453 453 record_magic(self.magics, 'line', name, meth)
454 454
455 def register_alias(self, alias_name, magic_name, magic_kind='line'):
456 """Register an alias to a magic function.
457
458 The alias is an instance of :class:`MagicAlias`, which holds the
459 name and kind of the magic it should call. Binding is done at
460 call time, so if the underlying magic function is changed the alias
461 will call the new function.
462
463 Parameters
464 ----------
465 alias_name : str
466 The name of the magic to be registered.
467
468 magic_name : str
469 The name of an existing magic.
470
471 magic_kind : str
472 Kind of magic, one of 'line' or 'cell'
473 """
474
475 # `validate_type` is too permissive, as it allows 'line_cell'
476 # which we do not handle.
477 if magic_kind not in magic_kinds:
478 raise ValueError('magic_kind must be one of %s, %s given' %
479 magic_kinds, magic_kind)
480
481 alias = MagicAlias(self.shell, magic_name, magic_kind)
482 setattr(self.user_magics, alias_name, alias)
483 record_magic(self.magics, magic_kind, alias_name, alias)
484
455 485 # Key base class that provides the central functionality for magics.
456 486
457 487 class Magics(object):
@@ -615,3 +645,45 b' class Magics(object):'
615 645 if fn not in self.lsmagic():
616 646 error("%s is not a magic function" % fn)
617 647 self.options_table[fn] = optstr
648
649 class MagicAlias(object):
650 """Store a magic alias.
651
652 An alias is determined by its magic name and magic kind. Lookup
653 is done at call time, so if the underlying magic changes the alias
654 will call the new function.
655
656 Use the :meth:`MagicsManager.register_alias` method or the
657 `%alias_magic` magic function to create and register a new alias.
658 """
659 def __init__(self, shell, magic_name, magic_kind):
660 self.shell = shell
661 self.magic_name = magic_name
662 self.magic_kind = magic_kind
663
664 self._in_call = False
665
666 @property
667 def pretty_target(self):
668 """A formatted version of the target of the alias."""
669 return '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
670
671 @property
672 def __doc__(self):
673 return "Alias for `%s`." % self.pretty_target
674
675 def __call__(self, *args, **kwargs):
676 """Call the magic alias."""
677 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
678 if fn is None:
679 raise UsageError("Magic `%s` not found." % self.pretty_target)
680
681 # Protect against infinite recursion.
682 if self._in_call:
683 raise UsageError("Infinite recursion detected; "
684 "magic aliases cannot call themselves.")
685 self._in_call = True
686 try:
687 return fn(*args, **kwargs)
688 finally:
689 self._in_call = False
@@ -65,6 +65,8 b' class BasicMagics(Magics):'
65 65 --------
66 66 ::
67 67 In [1]: %alias_magic t timeit
68 Created `%t` as an alias for `%timeit`.
69 Created `%%t` as an alias for `%%timeit`.
68 70
69 71 In [2]: %t -n1 pass
70 72 1 loops, best of 3: 954 ns per loop
@@ -77,12 +79,14 b' class BasicMagics(Magics):'
77 79 In [4]: %alias_magic --cell whereami pwd
78 80 UsageError: Cell magic function `%%pwd` not found.
79 81 In [5]: %alias_magic --line whereami pwd
82 Created `%whereami` as an alias for `%pwd`.
80 83
81 84 In [6]: %whereami
82 85 Out[6]: u'/home/testuser'
83 86 """
84 87 args = magic_arguments.parse_argstring(self.alias_magic, line)
85 88 shell = self.shell
89 mman = self.shell.magics_manager
86 90 escs = ''.join(magic_escapes.values())
87 91
88 92 target = args.target.lstrip(escs)
@@ -109,18 +113,16 b' class BasicMagics(Magics):'
109 113 args.cell = bool(m_cell)
110 114
111 115 if args.line:
112 def wrapper(line): return m_line(line)
113 wrapper.__name__ = str(name)
114 wrapper.__doc__ = "Alias for `%s%s`." % \
115 (magic_escapes['line'], target)
116 shell.register_magic_function(wrapper, 'line', name)
116 mman.register_alias(name, target, 'line')
117 print('Created `%s%s` as an alias for `%s%s`.' % (
118 magic_escapes['line'], name,
119 magic_escapes['line'], target))
117 120
118 121 if args.cell:
119 def wrapper(line, cell): return m_cell(line, cell)
120 wrapper.__name__ = str(name)
121 wrapper.__doc__ = "Alias for `%s%s`." % \
122 (magic_escapes['cell'], target)
123 shell.register_magic_function(wrapper, 'cell', name)
122 mman.register_alias(name, target, 'cell')
123 print('Created `%s%s` as an alias for `%s%s`.' % (
124 magic_escapes['cell'], name,
125 magic_escapes['cell'], target))
124 126
125 127 def _lsmagic(self):
126 128 mesc = magic_escapes['line']
@@ -333,11 +333,6 b' class CodeMagics(Magics):'
333 333 mfile.close()
334 334 self.shell.user_ns[mname] = Macro(mvalue)
335 335
336 @line_magic
337 def ed(self, parameter_s=''):
338 """Alias to %edit."""
339 return self.edit(parameter_s)
340
341 336 @skip_doctest
342 337 @line_magic
343 338 def edit(self, parameter_s='',last_call=['','']):
@@ -431,7 +426,7 b' class CodeMagics(Magics):'
431 426 This is an example of creating a simple function inside the editor and
432 427 then modifying it. First, start up the editor::
433 428
434 In [1]: ed
429 In [1]: edit
435 430 Editing... done. Executing edited code...
436 431 Out[1]: 'def foo():\\n print "foo() was defined in an editing
437 432 session"\\n'
@@ -444,7 +439,7 b' class CodeMagics(Magics):'
444 439 Now we edit foo. IPython automatically loads the editor with the
445 440 (temporary) file where foo() was previously defined::
446 441
447 In [3]: ed foo
442 In [3]: edit foo
448 443 Editing... done. Executing edited code...
449 444
450 445 And if we call foo() again we get the modified version::
@@ -455,21 +450,21 b' class CodeMagics(Magics):'
455 450 Here is an example of how to edit a code snippet successive
456 451 times. First we call the editor::
457 452
458 In [5]: ed
453 In [5]: edit
459 454 Editing... done. Executing edited code...
460 455 hello
461 456 Out[5]: "print 'hello'\\n"
462 457
463 458 Now we call it again with the previous output (stored in _)::
464 459
465 In [6]: ed _
460 In [6]: edit _
466 461 Editing... done. Executing edited code...
467 462 hello world
468 463 Out[6]: "print 'hello world'\\n"
469 464
470 465 Now we call it with the output #8 (stored in _8, also as Out[8])::
471 466
472 In [7]: ed _8
467 In [7]: edit _8
473 468 Editing... done. Executing edited code...
474 469 hello again
475 470 Out[7]: "print 'hello again'\\n"
@@ -91,10 +91,10 b' class HistoryMagics(Magics):'
91 91 --------
92 92 ::
93 93
94 In [6]: %hist -n 4-6
94 In [6]: %history -n 4-6
95 95 4:a = 12
96 96 5:print a**2
97 6:%hist -n 4-6
97 6:%history -n 4-6
98 98
99 99 """
100 100
@@ -187,15 +187,8 b' class HistoryMagics(Magics):'
187 187 if close_at_end:
188 188 outfile.close()
189 189
190 # For a long time we've had %hist as well as %history
191 190 @line_magic
192 def hist(self, arg):
193 return self.history(arg)
194
195 hist.__doc__ = history.__doc__
196
197 @line_magic
198 def rep(self, arg):
191 def recall(self, arg):
199 192 r"""Repeat a command, or get command to input line for editing.
200 193
201 194 %recall and %rep are equivalent.
@@ -209,7 +202,7 b' class HistoryMagics(Magics):'
209 202 In[1]: l = ["hei", "vaan"]
210 203 In[2]: "".join(l)
211 204 Out[2]: heivaan
212 In[3]: %rep
205 In[3]: %recall
213 206 In[4]: heivaan_ <== cursor blinking
214 207
215 208 %recall 45
@@ -244,7 +237,7 b' class HistoryMagics(Magics):'
244 237 except Exception: # Search for term in history
245 238 histlines = self.shell.history_manager.search("*"+arg+"*")
246 239 for h in reversed([x[2] for x in histlines]):
247 if 'rep' in h:
240 if 'recall' in h or 'rep' in h:
248 241 continue
249 242 self.shell.set_next_input(h.rstrip())
250 243 return
@@ -292,10 +285,3 b' class HistoryMagics(Magics):'
292 285 print(histlines)
293 286 print("=== Output: ===")
294 287 self.shell.run_cell("\n".join(hist), store_history=False)
295
296 @line_magic
297 def recall(self,arg):
298 self.rep(arg)
299
300 recall.__doc__ = rep.__doc__
301
@@ -575,7 +575,7 b' class ZMQInteractiveShell(InteractiveShell):'
575 575 def init_magics(self):
576 576 super(ZMQInteractiveShell, self).init_magics()
577 577 self.register_magics(KernelMagics)
578 self.run_line_magic('alias_magic', 'ed edit')
578 self.magics_manager.register_alias('ed', 'edit')
579 579
580 580
581 581
General Comments 0
You need to be logged in to leave comments. Login now