##// 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 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
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 # FIXME: Move the color initialization to the DisplayHook, which
2062 # FIXME: Move the color initialization to the DisplayHook, which
2057 # should be split into a prompt manager and displayhook. We probably
2063 # should be split into a prompt manager and displayhook. We probably
2058 # even need a centralize colors management object.
2064 # even need a centralize colors management object.
@@ -452,6 +452,36 b' class MagicsManager(Configurable):'
452 setattr(self.user_magics, name, meth)
452 setattr(self.user_magics, name, meth)
453 record_magic(self.magics, 'line', name, meth)
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 # Key base class that provides the central functionality for magics.
485 # Key base class that provides the central functionality for magics.
456
486
457 class Magics(object):
487 class Magics(object):
@@ -615,3 +645,45 b' class Magics(object):'
615 if fn not in self.lsmagic():
645 if fn not in self.lsmagic():
616 error("%s is not a magic function" % fn)
646 error("%s is not a magic function" % fn)
617 self.options_table[fn] = optstr
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 In [1]: %alias_magic t timeit
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 In [2]: %t -n1 pass
71 In [2]: %t -n1 pass
70 1 loops, best of 3: 954 ns per loop
72 1 loops, best of 3: 954 ns per loop
@@ -77,12 +79,14 b' class BasicMagics(Magics):'
77 In [4]: %alias_magic --cell whereami pwd
79 In [4]: %alias_magic --cell whereami pwd
78 UsageError: Cell magic function `%%pwd` not found.
80 UsageError: Cell magic function `%%pwd` not found.
79 In [5]: %alias_magic --line whereami pwd
81 In [5]: %alias_magic --line whereami pwd
82 Created `%whereami` as an alias for `%pwd`.
80
83
81 In [6]: %whereami
84 In [6]: %whereami
82 Out[6]: u'/home/testuser'
85 Out[6]: u'/home/testuser'
83 """
86 """
84 args = magic_arguments.parse_argstring(self.alias_magic, line)
87 args = magic_arguments.parse_argstring(self.alias_magic, line)
85 shell = self.shell
88 shell = self.shell
89 mman = self.shell.magics_manager
86 escs = ''.join(magic_escapes.values())
90 escs = ''.join(magic_escapes.values())
87
91
88 target = args.target.lstrip(escs)
92 target = args.target.lstrip(escs)
@@ -109,18 +113,16 b' class BasicMagics(Magics):'
109 args.cell = bool(m_cell)
113 args.cell = bool(m_cell)
110
114
111 if args.line:
115 if args.line:
112 def wrapper(line): return m_line(line)
116 mman.register_alias(name, target, 'line')
113 wrapper.__name__ = str(name)
117 print('Created `%s%s` as an alias for `%s%s`.' % (
114 wrapper.__doc__ = "Alias for `%s%s`." % \
118 magic_escapes['line'], name,
115 (magic_escapes['line'], target)
119 magic_escapes['line'], target))
116 shell.register_magic_function(wrapper, 'line', name)
117
120
118 if args.cell:
121 if args.cell:
119 def wrapper(line, cell): return m_cell(line, cell)
122 mman.register_alias(name, target, 'cell')
120 wrapper.__name__ = str(name)
123 print('Created `%s%s` as an alias for `%s%s`.' % (
121 wrapper.__doc__ = "Alias for `%s%s`." % \
124 magic_escapes['cell'], name,
122 (magic_escapes['cell'], target)
125 magic_escapes['cell'], target))
123 shell.register_magic_function(wrapper, 'cell', name)
124
126
125 def _lsmagic(self):
127 def _lsmagic(self):
126 mesc = magic_escapes['line']
128 mesc = magic_escapes['line']
@@ -333,11 +333,6 b' class CodeMagics(Magics):'
333 mfile.close()
333 mfile.close()
334 self.shell.user_ns[mname] = Macro(mvalue)
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 @skip_doctest
336 @skip_doctest
342 @line_magic
337 @line_magic
343 def edit(self, parameter_s='',last_call=['','']):
338 def edit(self, parameter_s='',last_call=['','']):
@@ -431,7 +426,7 b' class CodeMagics(Magics):'
431 This is an example of creating a simple function inside the editor and
426 This is an example of creating a simple function inside the editor and
432 then modifying it. First, start up the editor::
427 then modifying it. First, start up the editor::
433
428
434 In [1]: ed
429 In [1]: edit
435 Editing... done. Executing edited code...
430 Editing... done. Executing edited code...
436 Out[1]: 'def foo():\\n print "foo() was defined in an editing
431 Out[1]: 'def foo():\\n print "foo() was defined in an editing
437 session"\\n'
432 session"\\n'
@@ -444,7 +439,7 b' class CodeMagics(Magics):'
444 Now we edit foo. IPython automatically loads the editor with the
439 Now we edit foo. IPython automatically loads the editor with the
445 (temporary) file where foo() was previously defined::
440 (temporary) file where foo() was previously defined::
446
441
447 In [3]: ed foo
442 In [3]: edit foo
448 Editing... done. Executing edited code...
443 Editing... done. Executing edited code...
449
444
450 And if we call foo() again we get the modified version::
445 And if we call foo() again we get the modified version::
@@ -455,21 +450,21 b' class CodeMagics(Magics):'
455 Here is an example of how to edit a code snippet successive
450 Here is an example of how to edit a code snippet successive
456 times. First we call the editor::
451 times. First we call the editor::
457
452
458 In [5]: ed
453 In [5]: edit
459 Editing... done. Executing edited code...
454 Editing... done. Executing edited code...
460 hello
455 hello
461 Out[5]: "print 'hello'\\n"
456 Out[5]: "print 'hello'\\n"
462
457
463 Now we call it again with the previous output (stored in _)::
458 Now we call it again with the previous output (stored in _)::
464
459
465 In [6]: ed _
460 In [6]: edit _
466 Editing... done. Executing edited code...
461 Editing... done. Executing edited code...
467 hello world
462 hello world
468 Out[6]: "print 'hello world'\\n"
463 Out[6]: "print 'hello world'\\n"
469
464
470 Now we call it with the output #8 (stored in _8, also as Out[8])::
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 Editing... done. Executing edited code...
468 Editing... done. Executing edited code...
474 hello again
469 hello again
475 Out[7]: "print 'hello again'\\n"
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 4:a = 12
95 4:a = 12
96 5:print a**2
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 if close_at_end:
187 if close_at_end:
188 outfile.close()
188 outfile.close()
189
189
190 # For a long time we've had %hist as well as %history
191 @line_magic
190 @line_magic
192 def hist(self, arg):
191 def recall(self, arg):
193 return self.history(arg)
194
195 hist.__doc__ = history.__doc__
196
197 @line_magic
198 def rep(self, arg):
199 r"""Repeat a command, or get command to input line for editing.
192 r"""Repeat a command, or get command to input line for editing.
200
193
201 %recall and %rep are equivalent.
194 %recall and %rep are equivalent.
@@ -209,7 +202,7 b' class HistoryMagics(Magics):'
209 In[1]: l = ["hei", "vaan"]
202 In[1]: l = ["hei", "vaan"]
210 In[2]: "".join(l)
203 In[2]: "".join(l)
211 Out[2]: heivaan
204 Out[2]: heivaan
212 In[3]: %rep
205 In[3]: %recall
213 In[4]: heivaan_ <== cursor blinking
206 In[4]: heivaan_ <== cursor blinking
214
207
215 %recall 45
208 %recall 45
@@ -244,7 +237,7 b' class HistoryMagics(Magics):'
244 except Exception: # Search for term in history
237 except Exception: # Search for term in history
245 histlines = self.shell.history_manager.search("*"+arg+"*")
238 histlines = self.shell.history_manager.search("*"+arg+"*")
246 for h in reversed([x[2] for x in histlines]):
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 continue
241 continue
249 self.shell.set_next_input(h.rstrip())
242 self.shell.set_next_input(h.rstrip())
250 return
243 return
@@ -292,10 +285,3 b' class HistoryMagics(Magics):'
292 print(histlines)
285 print(histlines)
293 print("=== Output: ===")
286 print("=== Output: ===")
294 self.shell.run_cell("\n".join(hist), store_history=False)
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 def init_magics(self):
575 def init_magics(self):
576 super(ZMQInteractiveShell, self).init_magics()
576 super(ZMQInteractiveShell, self).init_magics()
577 self.register_magics(KernelMagics)
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