Show More
@@ -3,11 +3,15 b'' | |||||
3 | """ |
|
3 | """ | |
4 | Prefiltering components. |
|
4 | Prefiltering components. | |
5 |
|
5 | |||
|
6 | Prefilters transform user input before it is exec'd by Python. These | |||
|
7 | transforms are used to implement additional syntax such as !ls and %magic. | |||
|
8 | ||||
6 | Authors: |
|
9 | Authors: | |
7 |
|
10 | |||
8 | * Brian Granger |
|
11 | * Brian Granger | |
9 | * Fernando Perez |
|
12 | * Fernando Perez | |
10 | * Dan Milstein |
|
13 | * Dan Milstein | |
|
14 | * Ville Vainio | |||
11 | """ |
|
15 | """ | |
12 |
|
16 | |||
13 | #----------------------------------------------------------------------------- |
|
17 | #----------------------------------------------------------------------------- | |
@@ -34,7 +38,7 b' from IPython.core.component import Component' | |||||
34 | from IPython.core.splitinput import split_user_input |
|
38 | from IPython.core.splitinput import split_user_input | |
35 | from IPython.core.page import page |
|
39 | from IPython.core.page import page | |
36 |
|
40 | |||
37 | from IPython.utils.traitlets import List, Int, Any, Str, CBool |
|
41 | from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool | |
38 | from IPython.utils.genutils import make_quoted_expr |
|
42 | from IPython.utils.genutils import make_quoted_expr | |
39 | from IPython.utils.autoattr import auto_attr |
|
43 | from IPython.utils.autoattr import auto_attr | |
40 |
|
44 | |||
@@ -171,15 +175,46 b' class PrefilterManager(Component):' | |||||
171 |
|
175 | |||
172 | The IPython prefilter is run on all user input before it is run. The |
|
176 | The IPython prefilter is run on all user input before it is run. The | |
173 | prefilter consumes lines of input and produces transformed lines of |
|
177 | prefilter consumes lines of input and produces transformed lines of | |
174 | input. The implementation consists of checkers and handlers. The |
|
178 | input. | |
175 | checkers inspect the input line and select which handler will be used |
|
179 | ||
176 | to transform the input line. |
|
180 | The iplementation consists of two phases: | |
|
181 | ||||
|
182 | 1. Transformers | |||
|
183 | 2. Checkers and handlers | |||
|
184 | ||||
|
185 | Over time, we plan on deprecating the checkers and handlers and doing | |||
|
186 | everything in the transformers. | |||
|
187 | ||||
|
188 | The transformers are instances of :class:`PrefilterTransformer` and have | |||
|
189 | a single method :meth:`transform` that takes a line and returns a | |||
|
190 | transformed line. The transformation can be accomplished using any | |||
|
191 | tool, but our current ones use regular expressions for speed. We also | |||
|
192 | ship :mod:`pyparsing` in :mod:`IPython.external` for use in transformers. | |||
|
193 | ||||
|
194 | After all the transformers have been run, the line is fed to the checkers, | |||
|
195 | which are instances of :class:`PrefilterChecker`. The line is passed to | |||
|
196 | the :meth:`check` method, which either returns `None` or a | |||
|
197 | :class:`PrefilterHandler` instance. If `None` is returned, the other | |||
|
198 | checkers are tried. If an :class:`PrefilterHandler` instance is returned, | |||
|
199 | the line is passed to the :meth:`handle` method of the returned | |||
|
200 | handler and no further checkers are tried. | |||
|
201 | ||||
|
202 | Both transformers and checkers have a `priority` attribute, that determines | |||
|
203 | the order in which they are called. Smaller priorities are tried first. | |||
|
204 | ||||
|
205 | Both transformers and checkers also have `enabled` attribute, which is | |||
|
206 | a boolean that determines if the instance is used. | |||
|
207 | ||||
|
208 | Users or developers can change the priority or enabled attribute of | |||
|
209 | transformers or checkers, but they must call the :meth:`sort_checkers` | |||
|
210 | or :meth`sort_transformers` method after changing the priority. | |||
177 | """ |
|
211 | """ | |
178 |
|
212 | |||
179 | multi_line_specials = CBool(True, config=True) |
|
213 | multi_line_specials = CBool(True, config=True) | |
180 |
|
214 | |||
181 | def __init__(self, parent, config=None): |
|
215 | def __init__(self, parent, config=None): | |
182 | super(PrefilterManager, self).__init__(parent, config=config) |
|
216 | super(PrefilterManager, self).__init__(parent, config=config) | |
|
217 | self.init_transformers() | |||
183 | self.init_handlers() |
|
218 | self.init_handlers() | |
184 | self.init_checkers() |
|
219 | self.init_checkers() | |
185 |
|
220 | |||
@@ -189,21 +224,89 b' class PrefilterManager(Component):' | |||||
189 | root=self.root, |
|
224 | root=self.root, | |
190 | klass='IPython.core.iplib.InteractiveShell')[0] |
|
225 | klass='IPython.core.iplib.InteractiveShell')[0] | |
191 |
|
226 | |||
|
227 | #------------------------------------------------------------------------- | |||
|
228 | # API for managing transformers | |||
|
229 | #------------------------------------------------------------------------- | |||
|
230 | ||||
|
231 | def init_transformers(self): | |||
|
232 | """Create the default transformers.""" | |||
|
233 | self._transformers = [] | |||
|
234 | for transformer_cls in _default_transformers: | |||
|
235 | transformer_cls(self, config=self.config) | |||
|
236 | ||||
|
237 | def sort_transformers(self): | |||
|
238 | """Sort the transformers by priority. | |||
|
239 | ||||
|
240 | This must be called after the priority of a transformer is changed. | |||
|
241 | The :meth:`register_transformer` method calls this automatically. | |||
|
242 | """ | |||
|
243 | self._transformers.sort(cmp=lambda x,y: x.priority-y.priority) | |||
|
244 | ||||
|
245 | @property | |||
|
246 | def transformers(self): | |||
|
247 | """Return a list of checkers, sorted by priority.""" | |||
|
248 | return self._transformers | |||
|
249 | ||||
|
250 | def register_transformer(self, transformer): | |||
|
251 | """Register a transformer instance.""" | |||
|
252 | if transformer not in self._transformers: | |||
|
253 | self._transformers.append(transformer) | |||
|
254 | self.sort_transformers() | |||
|
255 | ||||
|
256 | def unregister_transformer(self, transformer): | |||
|
257 | """Unregister a transformer instance.""" | |||
|
258 | if transformer in self._transformers: | |||
|
259 | self._transformers.remove(transformer) | |||
|
260 | ||||
|
261 | #------------------------------------------------------------------------- | |||
|
262 | # API for managing checkers | |||
|
263 | #------------------------------------------------------------------------- | |||
|
264 | ||||
192 | def init_checkers(self): |
|
265 | def init_checkers(self): | |
|
266 | """Create the default checkers.""" | |||
193 | self._checkers = [] |
|
267 | self._checkers = [] | |
194 | for checker in _default_checkers: |
|
268 | for checker in _default_checkers: | |
195 |
|
|
269 | checker(self, config=self.config) | |
|
270 | ||||
|
271 | def sort_checkers(self): | |||
|
272 | """Sort the checkers by priority. | |||
|
273 | ||||
|
274 | This must be called after the priority of a checker is changed. | |||
|
275 | The :meth:`register_checker` method calls this automatically. | |||
|
276 | """ | |||
|
277 | self._checkers.sort(cmp=lambda x,y: x.priority-y.priority) | |||
|
278 | ||||
|
279 | @property | |||
|
280 | def checkers(self): | |||
|
281 | """Return a list of checkers, sorted by priority.""" | |||
|
282 | return self._checkers | |||
|
283 | ||||
|
284 | def register_checker(self, checker): | |||
|
285 | """Register a checker instance.""" | |||
|
286 | if checker not in self._checkers: | |||
|
287 | self._checkers.append(checker) | |||
|
288 | self.sort_checkers() | |||
|
289 | ||||
|
290 | def unregister_checker(self, checker): | |||
|
291 | """Unregister a checker instance.""" | |||
|
292 | if checker in self._checkers: | |||
|
293 | self._checkers.remove(checker) | |||
|
294 | ||||
|
295 | #------------------------------------------------------------------------- | |||
|
296 | # API for managing checkers | |||
|
297 | #------------------------------------------------------------------------- | |||
196 |
|
298 | |||
197 | def init_handlers(self): |
|
299 | def init_handlers(self): | |
|
300 | """Create the default handlers.""" | |||
198 | self._handlers = {} |
|
301 | self._handlers = {} | |
199 | self._esc_handlers = {} |
|
302 | self._esc_handlers = {} | |
200 | for handler in _default_handlers: |
|
303 | for handler in _default_handlers: | |
201 | handler(self, config=self.config) |
|
304 | handler(self, config=self.config) | |
202 |
|
305 | |||
203 | @property |
|
306 | @property | |
204 |
def |
|
307 | def handlers(self): | |
205 |
"""Return a |
|
308 | """Return a dict of all the handlers.""" | |
206 | return sorted(self._checkers, cmp=lambda x,y: x.priority-y.priority) |
|
309 | return self._handlers | |
207 |
|
310 | |||
208 | def register_handler(self, name, handler, esc_strings): |
|
311 | def register_handler(self, name, handler, esc_strings): | |
209 | """Register a handler instance by name with esc_strings.""" |
|
312 | """Register a handler instance by name with esc_strings.""" | |
@@ -230,24 +333,41 b' class PrefilterManager(Component):' | |||||
230 | """Get a handler by its escape string.""" |
|
333 | """Get a handler by its escape string.""" | |
231 | return self._esc_handlers.get(esc_str) |
|
334 | return self._esc_handlers.get(esc_str) | |
232 |
|
335 | |||
|
336 | #------------------------------------------------------------------------- | |||
|
337 | # Main prefiltering API | |||
|
338 | #------------------------------------------------------------------------- | |||
|
339 | ||||
233 | def prefilter_line_info(self, line_info): |
|
340 | def prefilter_line_info(self, line_info): | |
234 |
"""Prefilter a line that has been converted to a LineInfo object. |
|
341 | """Prefilter a line that has been converted to a LineInfo object. | |
|
342 | ||||
|
343 | This implements the checker/handler part of the prefilter pipe. | |||
|
344 | """ | |||
235 | # print "prefilter_line_info: ", line_info |
|
345 | # print "prefilter_line_info: ", line_info | |
236 | handler = self.find_handler(line_info) |
|
346 | handler = self.find_handler(line_info) | |
237 | return handler.handle(line_info) |
|
347 | return handler.handle(line_info) | |
238 |
|
348 | |||
239 | def find_handler(self, line_info): |
|
349 | def find_handler(self, line_info): | |
240 | """Find a handler for the line_info by trying checkers.""" |
|
350 | """Find a handler for the line_info by trying checkers.""" | |
241 |
for checker in self. |
|
351 | for checker in self.checkers: | |
242 |
|
|
352 | if checker.enabled: | |
243 | if handler: |
|
353 | handler = checker.check(line_info) | |
244 | # print "Used checker: ", checker |
|
354 | if handler: | |
245 |
|
|
355 | return handler | |
246 | return handler |
|
|||
247 | return self.get_handler_by_name('normal') |
|
356 | return self.get_handler_by_name('normal') | |
248 |
|
357 | |||
|
358 | def transform_line(self, line, continue_prompt): | |||
|
359 | """Calls the enabled transformers in order of increasing priority.""" | |||
|
360 | for transformer in self.transformers: | |||
|
361 | if transformer.enabled: | |||
|
362 | line = transformer.transform(line, continue_prompt) | |||
|
363 | return line | |||
|
364 | ||||
249 | def prefilter_line(self, line, continue_prompt): |
|
365 | def prefilter_line(self, line, continue_prompt): | |
250 |
"""Prefilter a single input line as text. |
|
366 | """Prefilter a single input line as text. | |
|
367 | ||||
|
368 | This method prefilters a single line of text by calling the | |||
|
369 | transformers and then the checkers/handlers. | |||
|
370 | """ | |||
251 |
|
371 | |||
252 | # print "prefilter_line: ", line, continue_prompt |
|
372 | # print "prefilter_line: ", line, continue_prompt | |
253 | # All handlers *must* return a value, even if it's blank (''). |
|
373 | # All handlers *must* return a value, even if it's blank (''). | |
@@ -256,8 +376,6 b' class PrefilterManager(Component):' | |||||
256 | # needed, update the cache AND log it (so that the input cache array |
|
376 | # needed, update the cache AND log it (so that the input cache array | |
257 | # stays synced). |
|
377 | # stays synced). | |
258 |
|
378 | |||
259 | # growl.notify("_prefilter: ", "line = %s\ncontinue_prompt = %s" % (line, continue_prompt)) |
|
|||
260 |
|
||||
261 | # save the line away in case we crash, so the post-mortem handler can |
|
379 | # save the line away in case we crash, so the post-mortem handler can | |
262 | # record it |
|
380 | # record it | |
263 | self.shell._last_input_line = line |
|
381 | self.shell._last_input_line = line | |
@@ -272,13 +390,18 b' class PrefilterManager(Component):' | |||||
272 | if ''.join(self.shell.buffer).isspace(): |
|
390 | if ''.join(self.shell.buffer).isspace(): | |
273 | self.shell.buffer[:] = [] |
|
391 | self.shell.buffer[:] = [] | |
274 | return '' |
|
392 | return '' | |
275 |
|
393 | |||
|
394 | # At this point, we invoke our transformers. | |||
|
395 | if not continue_prompt or (continue_prompt and self.multi_line_specials): | |||
|
396 | line = self.transform_line(line, continue_prompt) | |||
|
397 | ||||
|
398 | # Now we compute line_info for the checkers and handlers | |||
276 | line_info = LineInfo(line, continue_prompt) |
|
399 | line_info = LineInfo(line, continue_prompt) | |
277 |
|
400 | |||
278 | # the input history needs to track even empty lines |
|
401 | # the input history needs to track even empty lines | |
279 | stripped = line.strip() |
|
402 | stripped = line.strip() | |
280 |
|
403 | |||
281 |
normal_handler = self.get_handler_by_name('normal') |
|
404 | normal_handler = self.get_handler_by_name('normal') | |
282 | if not stripped: |
|
405 | if not stripped: | |
283 | if not continue_prompt: |
|
406 | if not continue_prompt: | |
284 | self.shell.outputcache.prompt_count -= 1 |
|
407 | self.shell.outputcache.prompt_count -= 1 | |
@@ -296,19 +419,96 b' class PrefilterManager(Component):' | |||||
296 | def prefilter_lines(self, lines, continue_prompt): |
|
419 | def prefilter_lines(self, lines, continue_prompt): | |
297 | """Prefilter multiple input lines of text. |
|
420 | """Prefilter multiple input lines of text. | |
298 |
|
421 | |||
299 | Covers cases where there are multiple lines in the user entry, |
|
422 | This is the main entry point for prefiltering multiple lines of | |
|
423 | input. This simply calls :meth:`prefilter_line` for each line of | |||
|
424 | input. | |||
|
425 | ||||
|
426 | This covers cases where there are multiple lines in the user entry, | |||
300 | which is the case when the user goes back to a multiline history |
|
427 | which is the case when the user goes back to a multiline history | |
301 | entry and presses enter. |
|
428 | entry and presses enter. | |
302 | """ |
|
429 | """ | |
303 | # growl.notify("multiline_prefilter: ", "%s\n%s" % (line, continue_prompt)) |
|
|||
304 | out = [] |
|
430 | out = [] | |
305 | for line in lines.rstrip('\n').split('\n'): |
|
431 | for line in lines.rstrip('\n').split('\n'): | |
306 | out.append(self.prefilter_line(line, continue_prompt)) |
|
432 | out.append(self.prefilter_line(line, continue_prompt)) | |
307 | # growl.notify("multiline_prefilter return: ", '\n'.join(out)) |
|
|||
308 | return '\n'.join(out) |
|
433 | return '\n'.join(out) | |
309 |
|
434 | |||
310 |
|
435 | |||
311 | #----------------------------------------------------------------------------- |
|
436 | #----------------------------------------------------------------------------- | |
|
437 | # Prefilter transformers | |||
|
438 | #----------------------------------------------------------------------------- | |||
|
439 | ||||
|
440 | ||||
|
441 | class PrefilterTransformer(Component): | |||
|
442 | """Transform a line of user input.""" | |||
|
443 | ||||
|
444 | priority = Int(100, config=True) | |||
|
445 | shell = Any | |||
|
446 | prefilter_manager = Any | |||
|
447 | enabled = Bool(True, config=True) | |||
|
448 | ||||
|
449 | def __init__(self, parent, config=None): | |||
|
450 | super(PrefilterTransformer, self).__init__(parent, config=config) | |||
|
451 | self.prefilter_manager.register_transformer(self) | |||
|
452 | ||||
|
453 | @auto_attr | |||
|
454 | def shell(self): | |||
|
455 | return Component.get_instances( | |||
|
456 | root=self.root, | |||
|
457 | klass='IPython.core.iplib.InteractiveShell')[0] | |||
|
458 | ||||
|
459 | @auto_attr | |||
|
460 | def prefilter_manager(self): | |||
|
461 | return PrefilterManager.get_instances(root=self.root)[0] | |||
|
462 | ||||
|
463 | def transform(self, line, continue_prompt): | |||
|
464 | """Transform a line, returning the new one.""" | |||
|
465 | return None | |||
|
466 | ||||
|
467 | def __repr__(self): | |||
|
468 | return "<%s(priority=%r, enabled=%r)>" % ( | |||
|
469 | self.__class__.__name__, self.priority, self.enabled) | |||
|
470 | ||||
|
471 | ||||
|
472 | _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))' | |||
|
473 | r'\s*=\s*!(?P<cmd>.*)') | |||
|
474 | ||||
|
475 | ||||
|
476 | class AssignSystemTransformer(PrefilterTransformer): | |||
|
477 | """Handle the `files = !ls` syntax.""" | |||
|
478 | ||||
|
479 | priority = Int(100, config=True) | |||
|
480 | ||||
|
481 | def transform(self, line, continue_prompt): | |||
|
482 | m = _assign_system_re.match(line) | |||
|
483 | if m is not None: | |||
|
484 | cmd = m.group('cmd') | |||
|
485 | lhs = m.group('lhs') | |||
|
486 | expr = make_quoted_expr("sc -l =%s" % cmd) | |||
|
487 | new_line = '%s = get_ipython().magic(%s)' % (lhs, expr) | |||
|
488 | return new_line | |||
|
489 | return line | |||
|
490 | ||||
|
491 | ||||
|
492 | _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))' | |||
|
493 | r'\s*=\s*%(?P<cmd>.*)') | |||
|
494 | ||||
|
495 | class AssignMagicTransformer(PrefilterTransformer): | |||
|
496 | """Handle the `a = %who` syntax.""" | |||
|
497 | ||||
|
498 | priority = Int(200, config=True) | |||
|
499 | ||||
|
500 | def transform(self, line, continue_prompt): | |||
|
501 | m = _assign_magic_re.match(line) | |||
|
502 | if m is not None: | |||
|
503 | cmd = m.group('cmd') | |||
|
504 | lhs = m.group('lhs') | |||
|
505 | expr = make_quoted_expr(cmd) | |||
|
506 | new_line = '%s = get_ipython().magic(%s)' % (lhs, expr) | |||
|
507 | return new_line | |||
|
508 | return line | |||
|
509 | ||||
|
510 | ||||
|
511 | #----------------------------------------------------------------------------- | |||
312 | # Prefilter checkers |
|
512 | # Prefilter checkers | |
313 | #----------------------------------------------------------------------------- |
|
513 | #----------------------------------------------------------------------------- | |
314 |
|
514 | |||
@@ -319,9 +519,11 b' class PrefilterChecker(Component):' | |||||
319 | priority = Int(100, config=True) |
|
519 | priority = Int(100, config=True) | |
320 | shell = Any |
|
520 | shell = Any | |
321 | prefilter_manager = Any |
|
521 | prefilter_manager = Any | |
|
522 | enabled = Bool(True, config=True) | |||
322 |
|
523 | |||
323 | def __init__(self, parent, config=None): |
|
524 | def __init__(self, parent, config=None): | |
324 | super(PrefilterChecker, self).__init__(parent, config=config) |
|
525 | super(PrefilterChecker, self).__init__(parent, config=config) | |
|
526 | self.prefilter_manager.register_checker(self) | |||
325 |
|
527 | |||
326 | @auto_attr |
|
528 | @auto_attr | |
327 | def shell(self): |
|
529 | def shell(self): | |
@@ -334,15 +536,18 b' class PrefilterChecker(Component):' | |||||
334 | return PrefilterManager.get_instances(root=self.root)[0] |
|
536 | return PrefilterManager.get_instances(root=self.root)[0] | |
335 |
|
537 | |||
336 | def check(self, line_info): |
|
538 | def check(self, line_info): | |
337 | """Inspect line_info and return a handler or None.""" |
|
539 | """Inspect line_info and return a handler instance or None.""" | |
338 | return None |
|
540 | return None | |
339 |
|
541 | |||
340 |
def __ |
|
542 | def __repr__(self): | |
341 | return "<%s(priority=%i)>" % (self.__class__.__name__, self.priority) |
|
543 | return "<%s(priority=%r, enabled=%r)>" % ( | |
|
544 | self.__class__.__name__, self.priority, self.enabled) | |||
|
545 | ||||
342 |
|
546 | |||
343 | class EmacsChecker(PrefilterChecker): |
|
547 | class EmacsChecker(PrefilterChecker): | |
344 |
|
548 | |||
345 | priority = Int(100, config=True) |
|
549 | priority = Int(100, config=True) | |
|
550 | enabled = Bool(False, config=True) | |||
346 |
|
551 | |||
347 | def check(self, line_info): |
|
552 | def check(self, line_info): | |
348 | "Emacs ipython-mode tags certain input lines." |
|
553 | "Emacs ipython-mode tags certain input lines." | |
@@ -410,10 +615,6 b' class EscCharsChecker(PrefilterChecker):' | |||||
410 | return self.prefilter_manager.get_handler_by_esc(line_info.pre_char) |
|
615 | return self.prefilter_manager.get_handler_by_esc(line_info.pre_char) | |
411 |
|
616 | |||
412 |
|
617 | |||
413 | _assign_system_re = re.compile('\s*=\s*!(?P<cmd>.*)') |
|
|||
414 | _assign_magic_re = re.compile('\s*=\s*%(?P<cmd>.*)') |
|
|||
415 |
|
||||
416 |
|
||||
417 | class AssignmentChecker(PrefilterChecker): |
|
618 | class AssignmentChecker(PrefilterChecker): | |
418 |
|
619 | |||
419 | priority = Int(600, config=True) |
|
620 | priority = Int(600, config=True) | |
@@ -427,12 +628,6 b' class AssignmentChecker(PrefilterChecker):' | |||||
427 | python code). E.g. ls='hi', or ls,that=1,2""" |
|
628 | python code). E.g. ls='hi', or ls,that=1,2""" | |
428 | if line_info.the_rest: |
|
629 | if line_info.the_rest: | |
429 | if line_info.the_rest[0] in '=,': |
|
630 | if line_info.the_rest[0] in '=,': | |
430 | # m = _assign_system_re.match(line_info.the_rest) |
|
|||
431 | # if m is not None: |
|
|||
432 | # return self.prefilter_manager.get_handler_by_name('assign_system') |
|
|||
433 | # m = _assign_magic_re.match(line_info.the_rest) |
|
|||
434 | # if m is not None: |
|
|||
435 | # return self.prefilter_manager.get_handler_by_name('assign_magic') |
|
|||
436 | return self.prefilter_manager.get_handler_by_name('normal') |
|
631 | return self.prefilter_manager.get_handler_by_name('normal') | |
437 | else: |
|
632 | else: | |
438 | return None |
|
633 | return None | |
@@ -571,45 +766,6 b' class PrefilterHandler(Component):' | |||||
571 | def __str__(self): |
|
766 | def __str__(self): | |
572 | return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name) |
|
767 | return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name) | |
573 |
|
768 | |||
574 | class AssignSystemHandler(PrefilterHandler): |
|
|||
575 |
|
||||
576 | handler_name = Str('assign_system') |
|
|||
577 |
|
||||
578 | @auto_attr |
|
|||
579 | def normal_handler(self): |
|
|||
580 | return self.prefilter_manager.get_handler_by_name('normal') |
|
|||
581 |
|
||||
582 | def handle(self, line_info): |
|
|||
583 | new_line = line_info.line |
|
|||
584 | m = _assign_system_re.match(line_info.the_rest) |
|
|||
585 | if m is not None: |
|
|||
586 | cmd = m.group('cmd') |
|
|||
587 | expr = make_quoted_expr("sc -l =%s" % cmd) |
|
|||
588 | new_line = '%s%s = get_ipython().magic(%s)' % (line_info.pre_whitespace, |
|
|||
589 | line_info.ifun, expr) |
|
|||
590 | self.shell.log(line_info.line, new_line, line_info.continue_prompt) |
|
|||
591 | return new_line |
|
|||
592 |
|
||||
593 |
|
||||
594 | class AssignMagicHandler(PrefilterHandler): |
|
|||
595 |
|
||||
596 | handler_name = Str('assign_magic') |
|
|||
597 |
|
||||
598 | @auto_attr |
|
|||
599 | def normal_handler(self): |
|
|||
600 | return self.prefilter_manager.get_handler_by_name('normal') |
|
|||
601 |
|
||||
602 | def handle(self, line_info): |
|
|||
603 | new_line = line_info.line |
|
|||
604 | m = _assign_magic_re.match(line_info.the_rest) |
|
|||
605 | if m is not None: |
|
|||
606 | cmd = m.group('cmd') |
|
|||
607 | expr = make_quoted_expr(cmd) |
|
|||
608 | new_line = '%s%s = get_ipython().magic(%s)' % (line_info.pre_whitespace, |
|
|||
609 | line_info.ifun, expr) |
|
|||
610 | self.shell.log(line_info.line, new_line, line_info.continue_prompt) |
|
|||
611 | return new_line |
|
|||
612 |
|
||||
613 |
|
769 | |||
614 | class AliasHandler(PrefilterHandler): |
|
770 | class AliasHandler(PrefilterHandler): | |
615 |
|
771 | |||
@@ -809,6 +965,11 b' class EmacsHandler(PrefilterHandler):' | |||||
809 | #----------------------------------------------------------------------------- |
|
965 | #----------------------------------------------------------------------------- | |
810 |
|
966 | |||
811 |
|
967 | |||
|
968 | _default_transformers = [ | |||
|
969 | AssignSystemTransformer, | |||
|
970 | AssignMagicTransformer | |||
|
971 | ] | |||
|
972 | ||||
812 | _default_checkers = [ |
|
973 | _default_checkers = [ | |
813 | EmacsChecker, |
|
974 | EmacsChecker, | |
814 | ShellEscapeChecker, |
|
975 | ShellEscapeChecker, | |
@@ -830,7 +991,5 b' _default_handlers = [' | |||||
830 | AutoHandler, |
|
991 | AutoHandler, | |
831 | HelpHandler, |
|
992 | HelpHandler, | |
832 | EmacsHandler |
|
993 | EmacsHandler | |
833 | # AssignSystemHandler, |
|
|||
834 | # AssignMagicHandler |
|
|||
835 | ] |
|
994 | ] | |
836 |
|
995 |
General Comments 0
You need to be logged in to leave comments.
Login now