##// END OF EJS Templates
First go an implementing a=!ls and a=%who syntax....
Brian Granger -
Show More
@@ -1,772 +1,836 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 Prefiltering components.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez
10 10 * Dan Milstein
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2009 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import __builtin__
25 25 import codeop
26 26 import keyword
27 27 import os
28 28 import re
29 29 import sys
30 30
31 31 from IPython.core.alias import AliasManager
32 32 from IPython.core.autocall import IPyAutocall
33 33 from IPython.core.component import Component
34 34 from IPython.core.splitinput import split_user_input
35 35 from IPython.core.page import page
36 36
37 37 from IPython.utils.traitlets import List, Int, Any, Str, CBool
38 38 from IPython.utils.genutils import make_quoted_expr
39 39 from IPython.utils.autoattr import auto_attr
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Global utilities, errors and constants
43 43 #-----------------------------------------------------------------------------
44 44
45
45 # Warning, these cannot be changed unless various regular expressions
46 # are updated in a number of places. Not great, but at least we told you.
46 47 ESC_SHELL = '!'
47 48 ESC_SH_CAP = '!!'
48 49 ESC_HELP = '?'
49 50 ESC_MAGIC = '%'
50 51 ESC_QUOTE = ','
51 52 ESC_QUOTE2 = ';'
52 53 ESC_PAREN = '/'
53 54
54 55
55 56 class PrefilterError(Exception):
56 57 pass
57 58
58 59
59 60 # RegExp to identify potential function names
60 61 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
61 62
62 63 # RegExp to exclude strings with this start from autocalling. In
63 64 # particular, all binary operators should be excluded, so that if foo is
64 65 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
65 66 # characters '!=()' don't need to be checked for, as the checkPythonChars
66 67 # routine explicitely does so, to catch direct calls and rebindings of
67 68 # existing names.
68 69
69 70 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
70 71 # it affects the rest of the group in square brackets.
71 72 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
72 73 r'|^is |^not |^in |^and |^or ')
73 74
74 75 # try to catch also methods for stuff in lists/tuples/dicts: off
75 76 # (experimental). For this to work, the line_split regexp would need
76 77 # to be modified so it wouldn't break things at '['. That line is
77 78 # nasty enough that I shouldn't change it until I can test it _well_.
78 79 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
79 80
80 81
81 82 # Handler Check Utilities
82 83 def is_shadowed(identifier, ip):
83 84 """Is the given identifier defined in one of the namespaces which shadow
84 85 the alias and magic namespaces? Note that an identifier is different
85 86 than ifun, because it can not contain a '.' character."""
86 87 # This is much safer than calling ofind, which can change state
87 88 return (identifier in ip.user_ns \
88 89 or identifier in ip.internal_ns \
89 90 or identifier in ip.ns_table['builtin'])
90 91
91 92
92 93 #-----------------------------------------------------------------------------
93 94 # The LineInfo class used throughout
94 95 #-----------------------------------------------------------------------------
95 96
96 97
97 98 class LineInfo(object):
98 99 """A single line of input and associated info.
99 100
100 101 Includes the following as properties:
101 102
102 103 line
103 104 The original, raw line
104 105
105 106 continue_prompt
106 107 Is this line a continuation in a sequence of multiline input?
107 108
108 109 pre
109 110 The initial esc character or whitespace.
110 111
111 112 pre_char
112 113 The escape character(s) in pre or the empty string if there isn't one.
113 114 Note that '!!' is a possible value for pre_char. Otherwise it will
114 115 always be a single character.
115 116
116 117 pre_whitespace
117 118 The leading whitespace from pre if it exists. If there is a pre_char,
118 119 this is just ''.
119 120
120 121 ifun
121 122 The 'function part', which is basically the maximal initial sequence
122 123 of valid python identifiers and the '.' character. This is what is
123 124 checked for alias and magic transformations, used for auto-calling,
124 125 etc.
125 126
126 127 the_rest
127 128 Everything else on the line.
128 129 """
129 130 def __init__(self, line, continue_prompt):
130 131 self.line = line
131 132 self.continue_prompt = continue_prompt
132 133 self.pre, self.ifun, self.the_rest = split_user_input(line)
133 134
134 135 self.pre_char = self.pre.strip()
135 136 if self.pre_char:
136 137 self.pre_whitespace = '' # No whitespace allowd before esc chars
137 138 else:
138 139 self.pre_whitespace = self.pre
139 140
140 141 self._oinfo = None
141 142
142 143 def ofind(self, ip):
143 144 """Do a full, attribute-walking lookup of the ifun in the various
144 145 namespaces for the given IPython InteractiveShell instance.
145 146
146 147 Return a dict with keys: found,obj,ospace,ismagic
147 148
148 149 Note: can cause state changes because of calling getattr, but should
149 150 only be run if autocall is on and if the line hasn't matched any
150 151 other, less dangerous handlers.
151 152
152 153 Does cache the results of the call, so can be called multiple times
153 154 without worrying about *further* damaging state.
154 155 """
155 156 if not self._oinfo:
156 157 self._oinfo = ip._ofind(self.ifun)
157 158 return self._oinfo
158 159
159 160 def __str__(self):
160 161 return "Lineinfo [%s|%s|%s]" %(self.pre,self.ifun,self.the_rest)
161 162
162 163
163 164 #-----------------------------------------------------------------------------
164 165 # Main Prefilter manager
165 166 #-----------------------------------------------------------------------------
166 167
167 168
168 169 class PrefilterManager(Component):
169 170 """Main prefilter component.
170 171
171 172 The IPython prefilter is run on all user input before it is run. The
172 173 prefilter consumes lines of input and produces transformed lines of
173 174 input. The implementation consists of checkers and handlers. The
174 175 checkers inspect the input line and select which handler will be used
175 176 to transform the input line.
176 177 """
177 178
178 179 multi_line_specials = CBool(True, config=True)
179 180
180 181 def __init__(self, parent, config=None):
181 182 super(PrefilterManager, self).__init__(parent, config=config)
182 183 self.init_handlers()
183 184 self.init_checkers()
184 185
185 186 @auto_attr
186 187 def shell(self):
187 188 return Component.get_instances(
188 189 root=self.root,
189 190 klass='IPython.core.iplib.InteractiveShell')[0]
190 191
191 192 def init_checkers(self):
192 193 self._checkers = []
193 194 for checker in _default_checkers:
194 195 self._checkers.append(checker(self, config=self.config))
195 196
196 197 def init_handlers(self):
197 198 self._handlers = {}
198 199 self._esc_handlers = {}
199 200 for handler in _default_handlers:
200 201 handler(self, config=self.config)
201 202
202 203 @property
203 204 def sorted_checkers(self):
204 205 """Return a list of checkers, sorted by priority."""
205 206 return sorted(self._checkers, cmp=lambda x,y: x.priority-y.priority)
206 207
207 208 def register_handler(self, name, handler, esc_strings):
208 209 """Register a handler instance by name with esc_strings."""
209 210 self._handlers[name] = handler
210 211 for esc_str in esc_strings:
211 212 self._esc_handlers[esc_str] = handler
212 213
213 214 def unregister_handler(self, name, handler, esc_strings):
214 215 """Unregister a handler instance by name with esc_strings."""
215 216 try:
216 217 del self._handlers[name]
217 218 except KeyError:
218 219 pass
219 220 for esc_str in esc_strings:
220 221 h = self._esc_handlers.get(esc_str)
221 222 if h is handler:
222 223 del self._esc_handlers[esc_str]
223 224
224 225 def get_handler_by_name(self, name):
225 226 """Get a handler by its name."""
226 227 return self._handlers.get(name)
227 228
228 229 def get_handler_by_esc(self, esc_str):
229 230 """Get a handler by its escape string."""
230 231 return self._esc_handlers.get(esc_str)
231 232
232 233 def prefilter_line_info(self, line_info):
233 234 """Prefilter a line that has been converted to a LineInfo object."""
235 # print "prefilter_line_info: ", line_info
234 236 handler = self.find_handler(line_info)
235 237 return handler.handle(line_info)
236 238
237 239 def find_handler(self, line_info):
238 240 """Find a handler for the line_info by trying checkers."""
239 241 for checker in self.sorted_checkers:
240 242 handler = checker.check(line_info)
241 243 if handler:
244 # print "Used checker: ", checker
245 # print "Using handler: ", handler
242 246 return handler
243 247 return self.get_handler_by_name('normal')
244 248
245 249 def prefilter_line(self, line, continue_prompt):
246 250 """Prefilter a single input line as text."""
247 251
252 # print "prefilter_line: ", line, continue_prompt
248 253 # All handlers *must* return a value, even if it's blank ('').
249 254
250 255 # Lines are NOT logged here. Handlers should process the line as
251 256 # needed, update the cache AND log it (so that the input cache array
252 257 # stays synced).
253 258
254 259 # growl.notify("_prefilter: ", "line = %s\ncontinue_prompt = %s" % (line, continue_prompt))
255 260
256 261 # save the line away in case we crash, so the post-mortem handler can
257 # record it
262 # record it
258 263 self.shell._last_input_line = line
259 264
260 265 if not line:
261 266 # Return immediately on purely empty lines, so that if the user
262 267 # previously typed some whitespace that started a continuation
263 268 # prompt, he can break out of that loop with just an empty line.
264 269 # This is how the default python prompt works.
265 270
266 271 # Only return if the accumulated input buffer was just whitespace!
267 272 if ''.join(self.shell.buffer).isspace():
268 273 self.shell.buffer[:] = []
269 274 return ''
270 275
271 276 line_info = LineInfo(line, continue_prompt)
272 277
273 278 # the input history needs to track even empty lines
274 279 stripped = line.strip()
275 280
276 281 normal_handler = self.get_handler_by_name('normal')
277 282 if not stripped:
278 283 if not continue_prompt:
279 284 self.shell.outputcache.prompt_count -= 1
280 285
281 286 return normal_handler.handle(line_info)
282 287
283 288 # special handlers are only allowed for single line statements
284 289 if continue_prompt and not self.multi_line_specials:
285 290 return normal_handler.handle(line_info)
286 291
287 return self.prefilter_line_info(line_info)
292 prefiltered = self.prefilter_line_info(line_info)
293 # print "prefiltered line: %r" % prefiltered
294 return prefiltered
288 295
289 296 def prefilter_lines(self, lines, continue_prompt):
290 297 """Prefilter multiple input lines of text.
291 298
292 299 Covers cases where there are multiple lines in the user entry,
293 300 which is the case when the user goes back to a multiline history
294 301 entry and presses enter.
295 302 """
296 303 # growl.notify("multiline_prefilter: ", "%s\n%s" % (line, continue_prompt))
297 304 out = []
298 305 for line in lines.rstrip('\n').split('\n'):
299 306 out.append(self.prefilter_line(line, continue_prompt))
300 307 # growl.notify("multiline_prefilter return: ", '\n'.join(out))
301 308 return '\n'.join(out)
302 309
303 310
304 311 #-----------------------------------------------------------------------------
305 312 # Prefilter checkers
306 313 #-----------------------------------------------------------------------------
307 314
308 315
309 316 class PrefilterChecker(Component):
310 317 """Inspect an input line and return a handler for that line."""
311 318
312 319 priority = Int(100, config=True)
313 320 shell = Any
314 321 prefilter_manager = Any
315 322
316 323 def __init__(self, parent, config=None):
317 324 super(PrefilterChecker, self).__init__(parent, config=config)
318 325
319 326 @auto_attr
320 327 def shell(self):
321 328 return Component.get_instances(
322 329 root=self.root,
323 330 klass='IPython.core.iplib.InteractiveShell')[0]
324 331
325 332 @auto_attr
326 333 def prefilter_manager(self):
327 334 return PrefilterManager.get_instances(root=self.root)[0]
328 335
329 336 def check(self, line_info):
330 337 """Inspect line_info and return a handler or None."""
331 338 return None
332 339
340 def __str__(self):
341 return "<%s(priority=%i)>" % (self.__class__.__name__, self.priority)
333 342
334 343 class EmacsChecker(PrefilterChecker):
335 344
336 345 priority = Int(100, config=True)
337 346
338 347 def check(self, line_info):
339 348 "Emacs ipython-mode tags certain input lines."
340 349 if line_info.line.endswith('# PYTHON-MODE'):
341 350 return self.prefilter_manager.get_handler_by_name('emacs')
342 351 else:
343 352 return None
344 353
345 354
346 355 class ShellEscapeChecker(PrefilterChecker):
347 356
348 357 priority = Int(200, config=True)
349 358
350 359 def check(self, line_info):
351 360 if line_info.line.lstrip().startswith(ESC_SHELL):
352 361 return self.prefilter_manager.get_handler_by_name('shell')
353 362
354 363
355 364 class IPyAutocallChecker(PrefilterChecker):
356 365
357 366 priority = Int(300, config=True)
358 367
359 368 def check(self, line_info):
360 369 "Instances of IPyAutocall in user_ns get autocalled immediately"
361 370 obj = self.shell.user_ns.get(line_info.ifun, None)
362 371 if isinstance(obj, IPyAutocall):
363 372 obj.set_ip(self.shell)
364 373 return self.prefilter_manager.get_handler_by_name('auto')
365 374 else:
366 375 return None
367 376
368 377
369 378 class MultiLineMagicChecker(PrefilterChecker):
370 379
371 380 priority = Int(400, config=True)
372 381
373 382 def check(self, line_info):
374 383 "Allow ! and !! in multi-line statements if multi_line_specials is on"
375 384 # Note that this one of the only places we check the first character of
376 385 # ifun and *not* the pre_char. Also note that the below test matches
377 386 # both ! and !!.
378 387 if line_info.continue_prompt \
379 388 and self.prefilter_manager.multi_line_specials:
380 389 if line_info.ifun.startswith(ESC_MAGIC):
381 390 return self.prefilter_manager.get_handler_by_name('magic')
382 391 else:
383 392 return None
384 393
385 394
386 395 class EscCharsChecker(PrefilterChecker):
387 396
388 397 priority = Int(500, config=True)
389 398
390 399 def check(self, line_info):
391 400 """Check for escape character and return either a handler to handle it,
392 401 or None if there is no escape char."""
393 402 if line_info.line[-1] == ESC_HELP \
394 403 and line_info.pre_char != ESC_SHELL \
395 404 and line_info.pre_char != ESC_SH_CAP:
396 405 # the ? can be at the end, but *not* for either kind of shell escape,
397 406 # because a ? can be a vaild final char in a shell cmd
398 407 return self.prefilter_manager.get_handler_by_name('help')
399 408 else:
400 409 # This returns None like it should if no handler exists
401 410 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
402 411
403 412
413 _assign_system_re = re.compile('\s*=\s*!(?P<cmd>.*)')
414 _assign_magic_re = re.compile('\s*=\s*%(?P<cmd>.*)')
415
416
404 417 class AssignmentChecker(PrefilterChecker):
405 418
406 419 priority = Int(600, config=True)
407 420
408 421 def check(self, line_info):
409 422 """Check to see if user is assigning to a var for the first time, in
410 423 which case we want to avoid any sort of automagic / autocall games.
411 424
412 425 This allows users to assign to either alias or magic names true python
413 426 variables (the magic/alias systems always take second seat to true
414 427 python code). E.g. ls='hi', or ls,that=1,2"""
415 if line_info.the_rest and line_info.the_rest[0] in '=,':
416 return self.prefilter_manager.get_handler_by_name('normal')
428 if line_info.the_rest:
429 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')
417 437 else:
418 438 return None
419 439
420 440
421 441 class AutoMagicChecker(PrefilterChecker):
422 442
423 443 priority = Int(700, config=True)
424 444
425 445 def check(self, line_info):
426 446 """If the ifun is magic, and automagic is on, run it. Note: normal,
427 447 non-auto magic would already have been triggered via '%' in
428 448 check_esc_chars. This just checks for automagic. Also, before
429 449 triggering the magic handler, make sure that there is nothing in the
430 450 user namespace which could shadow it."""
431 451 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
432 452 return None
433 453
434 454 # We have a likely magic method. Make sure we should actually call it.
435 455 if line_info.continue_prompt and not self.shell.multi_line_specials:
436 456 return None
437 457
438 458 head = line_info.ifun.split('.',1)[0]
439 459 if is_shadowed(head, self.shell):
440 460 return None
441 461
442 462 return self.prefilter_manager.get_handler_by_name('magic')
443 463
444 464
445 465 class AliasChecker(PrefilterChecker):
446 466
447 467 priority = Int(800, config=True)
448 468
449 469 @auto_attr
450 470 def alias_manager(self):
451 471 return AliasManager.get_instances(root=self.root)[0]
452 472
453 473 def check(self, line_info):
454 474 "Check if the initital identifier on the line is an alias."
455 475 # Note: aliases can not contain '.'
456 476 head = line_info.ifun.split('.',1)[0]
457 477 if line_info.ifun not in self.alias_manager \
458 478 or head not in self.alias_manager \
459 479 or is_shadowed(head, self.shell):
460 480 return None
461 481
462 482 return self.prefilter_manager.get_handler_by_name('alias')
463 483
464 484
465 485 class PythonOpsChecker(PrefilterChecker):
466 486
467 487 priority = Int(900, config=True)
468 488
469 489 def check(self, line_info):
470 490 """If the 'rest' of the line begins with a function call or pretty much
471 491 any python operator, we should simply execute the line (regardless of
472 492 whether or not there's a possible autocall expansion). This avoids
473 493 spurious (and very confusing) geattr() accesses."""
474 494 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
475 495 return self.prefilter_manager.get_handler_by_name('normal')
476 496 else:
477 497 return None
478 498
479 499
480 500 class AutocallChecker(PrefilterChecker):
481 501
482 502 priority = Int(1000, config=True)
483 503
484 504 def check(self, line_info):
485 505 "Check if the initial word/function is callable and autocall is on."
486 506 if not self.shell.autocall:
487 507 return None
488 508
489 509 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
490 510 if not oinfo['found']:
491 511 return None
492 512
493 513 if callable(oinfo['obj']) \
494 514 and (not re_exclude_auto.match(line_info.the_rest)) \
495 515 and re_fun_name.match(line_info.ifun):
496 516 return self.prefilter_manager.get_handler_by_name('auto')
497 517 else:
498 518 return None
499 519
500 520
501 521 #-----------------------------------------------------------------------------
502 522 # Prefilter handlers
503 523 #-----------------------------------------------------------------------------
504 524
505 525
506 526 class PrefilterHandler(Component):
507 527
508 528 handler_name = Str('normal')
509 529 esc_strings = List([])
510 530 shell = Any
511 531 prefilter_manager = Any
512 532
513 533 def __init__(self, parent, config=None):
514 534 super(PrefilterHandler, self).__init__(parent, config=config)
515 535 self.prefilter_manager.register_handler(
516 536 self.handler_name,
517 537 self,
518 538 self.esc_strings
519 539 )
520 540
521 541 @auto_attr
522 542 def shell(self):
523 543 return Component.get_instances(
524 544 root=self.root,
525 545 klass='IPython.core.iplib.InteractiveShell')[0]
526 546
527 547 @auto_attr
528 548 def prefilter_manager(self):
529 549 return PrefilterManager.get_instances(root=self.root)[0]
530 550
531 551 def handle(self, line_info):
552 # print "normal: ", line_info
532 553 """Handle normal input lines. Use as a template for handlers."""
533 554
534 555 # With autoindent on, we need some way to exit the input loop, and I
535 556 # don't want to force the user to have to backspace all the way to
536 557 # clear the line. The rule will be in this case, that either two
537 558 # lines of pure whitespace in a row, or a line of pure whitespace but
538 559 # of a size different to the indent level, will exit the input loop.
539 560 line = line_info.line
540 561 continue_prompt = line_info.continue_prompt
541 562
542 563 if (continue_prompt and self.shell.autoindent and line.isspace() and
543 564 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2 or
544 565 (self.shell.buffer[-1]).isspace() )):
545 566 line = ''
546 567
547 568 self.shell.log(line, line, continue_prompt)
548 569 return line
549 570
571 def __str__(self):
572 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
573
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
550 613
551 614 class AliasHandler(PrefilterHandler):
552 615
553 616 handler_name = Str('alias')
554 esc_strings = List([])
555 617
556 618 @auto_attr
557 619 def alias_manager(self):
558 620 return AliasManager.get_instances(root=self.root)[0]
559 621
560 622 def handle(self, line_info):
561 623 """Handle alias input lines. """
562 624 transformed = self.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
563 625 # pre is needed, because it carries the leading whitespace. Otherwise
564 626 # aliases won't work in indented sections.
565 627 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
566 628 make_quoted_expr(transformed))
567 629
568 630 self.shell.log(line_info.line, line_out, line_info.continue_prompt)
569 631 return line_out
570 632
571 633
572 634 class ShellEscapeHandler(PrefilterHandler):
573 635
574 636 handler_name = Str('shell')
575 637 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
576 638
577 639 def handle(self, line_info):
578 640 """Execute the line in a shell, empty return value"""
579 641 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
580 642
581 643 line = line_info.line
582 644 if line.lstrip().startswith(ESC_SH_CAP):
583 645 # rewrite LineInfo's line, ifun and the_rest to properly hold the
584 646 # call to %sx and the actual command to be executed, so
585 647 # handle_magic can work correctly. Note that this works even if
586 648 # the line is indented, so it handles multi_line_specials
587 649 # properly.
588 650 new_rest = line.lstrip()[2:]
589 651 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
590 652 line_info.ifun = 'sx'
591 653 line_info.the_rest = new_rest
592 654 return magic_handler.handle(line_info)
593 655 else:
594 656 cmd = line.lstrip().lstrip(ESC_SHELL)
595 657 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
596 658 make_quoted_expr(cmd))
597 659 # update cache/log and return
598 660 self.shell.log(line, line_out, line_info.continue_prompt)
599 661 return line_out
600 662
601 663
602 664 class MagicHandler(PrefilterHandler):
603 665
604 666 handler_name = Str('magic')
605 667 esc_strings = List([ESC_MAGIC])
606 668
607 669 def handle(self, line_info):
608 670 """Execute magic functions."""
609 671 ifun = line_info.ifun
610 672 the_rest = line_info.the_rest
611 673 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
612 674 make_quoted_expr(ifun + " " + the_rest))
613 675 self.shell.log(line_info.line, cmd, line_info.continue_prompt)
614 676 return cmd
615 677
616 678
617 679 class AutoHandler(PrefilterHandler):
618 680
619 681 handler_name = Str('auto')
620 682 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
621 683
622 684 def handle(self, line_info):
623 685 """Hande lines which can be auto-executed, quoting if requested."""
624 686 line = line_info.line
625 687 ifun = line_info.ifun
626 688 the_rest = line_info.the_rest
627 689 pre = line_info.pre
628 690 continue_prompt = line_info.continue_prompt
629 691 obj = line_info.ofind(self)['obj']
630 692
631 693 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
632 694
633 695 # This should only be active for single-line input!
634 696 if continue_prompt:
635 697 self.log(line,line,continue_prompt)
636 698 return line
637 699
638 700 force_auto = isinstance(obj, IPyAutocall)
639 701 auto_rewrite = True
640 702
641 703 if pre == ESC_QUOTE:
642 704 # Auto-quote splitting on whitespace
643 705 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
644 706 elif pre == ESC_QUOTE2:
645 707 # Auto-quote whole string
646 708 newcmd = '%s("%s")' % (ifun,the_rest)
647 709 elif pre == ESC_PAREN:
648 710 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
649 711 else:
650 712 # Auto-paren.
651 713 # We only apply it to argument-less calls if the autocall
652 714 # parameter is set to 2. We only need to check that autocall is <
653 715 # 2, since this function isn't called unless it's at least 1.
654 716 if not the_rest and (self.shell.autocall < 2) and not force_auto:
655 717 newcmd = '%s %s' % (ifun,the_rest)
656 718 auto_rewrite = False
657 719 else:
658 720 if not force_auto and the_rest.startswith('['):
659 721 if hasattr(obj,'__getitem__'):
660 722 # Don't autocall in this case: item access for an object
661 723 # which is BOTH callable and implements __getitem__.
662 724 newcmd = '%s %s' % (ifun,the_rest)
663 725 auto_rewrite = False
664 726 else:
665 727 # if the object doesn't support [] access, go ahead and
666 728 # autocall
667 729 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
668 730 elif the_rest.endswith(';'):
669 731 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
670 732 else:
671 733 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
672 734
673 735 if auto_rewrite:
674 736 rw = self.shell.outputcache.prompt1.auto_rewrite() + newcmd
675 737
676 738 try:
677 739 # plain ascii works better w/ pyreadline, on some machines, so
678 740 # we use it and only print uncolored rewrite if we have unicode
679 741 rw = str(rw)
680 742 print >>Term.cout, rw
681 743 except UnicodeEncodeError:
682 744 print "-------------->" + newcmd
683 745
684 746 # log what is now valid Python, not the actual user input (without the
685 747 # final newline)
686 748 self.shell.log(line,newcmd,continue_prompt)
687 749 return newcmd
688 750
689 751
690 752 class HelpHandler(PrefilterHandler):
691 753
692 754 handler_name = Str('help')
693 755 esc_strings = List([ESC_HELP])
694 756
695 757 def handle(self, line_info):
696 758 """Try to get some help for the object.
697 759
698 760 obj? or ?obj -> basic information.
699 761 obj?? or ??obj -> more details.
700 762 """
701 763 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
702 764 line = line_info.line
703 765 # We need to make sure that we don't process lines which would be
704 766 # otherwise valid python, such as "x=1 # what?"
705 767 try:
706 768 codeop.compile_command(line)
707 769 except SyntaxError:
708 770 # We should only handle as help stuff which is NOT valid syntax
709 771 if line[0]==ESC_HELP:
710 772 line = line[1:]
711 773 elif line[-1]==ESC_HELP:
712 774 line = line[:-1]
713 775 self.shell.log(line, '#?'+line, line_info.continue_prompt)
714 776 if line:
715 777 #print 'line:<%r>' % line # dbg
716 778 self.shell.magic_pinfo(line)
717 779 else:
718 780 page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
719 781 return '' # Empty string is needed here!
720 782 except:
721 783 raise
722 784 # Pass any other exceptions through to the normal handler
723 785 return normal_handler.handle(line_info)
724 786 else:
725 787 raise
726 788 # If the code compiles ok, we should handle it normally
727 789 return normal_handler.handle(line_info)
728 790
729 791
730 792 class EmacsHandler(PrefilterHandler):
731 793
732 794 handler_name = Str('emacs')
733 795 esc_strings = List([])
734 796
735 797 def handle(self, line_info):
736 798 """Handle input lines marked by python-mode."""
737 799
738 800 # Currently, nothing is done. Later more functionality can be added
739 801 # here if needed.
740 802
741 803 # The input cache shouldn't be updated
742 804 return line_info.line
743 805
744 806
745 807 #-----------------------------------------------------------------------------
746 808 # Defaults
747 809 #-----------------------------------------------------------------------------
748 810
749 811
750 812 _default_checkers = [
751 813 EmacsChecker,
752 814 ShellEscapeChecker,
753 815 IPyAutocallChecker,
754 816 MultiLineMagicChecker,
755 817 EscCharsChecker,
756 818 AssignmentChecker,
757 819 AutoMagicChecker,
758 820 AliasChecker,
759 821 PythonOpsChecker,
760 822 AutocallChecker
761 823 ]
762 824
763 825 _default_handlers = [
764 826 PrefilterHandler,
765 827 AliasHandler,
766 828 ShellEscapeHandler,
767 829 MagicHandler,
768 830 AutoHandler,
769 831 HelpHandler,
770 832 EmacsHandler
833 # AssignSystemHandler,
834 # AssignMagicHandler
771 835 ]
772 836
@@ -1,77 +1,83 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 Simple utility for splitting user input.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2009 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import re
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Main function
27 27 #-----------------------------------------------------------------------------
28 28
29 29
30 30 # RegExp for splitting line contents into pre-char//first word-method//rest.
31 31 # For clarity, each group in on one line.
32 32
33 33 # WARNING: update the regexp if the escapes in iplib are changed, as they
34 34 # are hardwired in.
35 35
36 36 # Although it's not solely driven by the regex, note that:
37 37 # ,;/% only trigger if they are the first character on the line
38 38 # ! and !! trigger if they are first char(s) *or* follow an indent
39 39 # ? triggers as first or last char.
40 40
41 41 # The three parts of the regex are:
42 42 # 1) pre: pre_char *or* initial whitespace
43 43 # 2) ifun: first word/method (mix of \w and '.')
44 44 # 3) the_rest: rest of line (separated from ifun by space if non-empty)
45 45 line_split = re.compile(r'^([,;/%?]|!!?|\s*)'
46 46 r'\s*([\w\.]+)'
47 47 r'(\s+.*$|$)')
48 48
49 # r'[\w\.]+'
50 # r'\s*=\s*%.*'
49 51
50 52 def split_user_input(line, pattern=None):
51 """Split user input into pre-char/whitespace, function part and rest."""
53 """Split user input into pre-char/whitespace, function part and rest.
54
55 This is currently handles lines with '=' in them in a very inconsistent
56 manner.
57 """
52 58
53 59 if pattern is None:
54 60 pattern = line_split
55 61 match = pattern.match(line)
56 62 if not match:
57 #print "match failed for line '%s'" % line
63 # print "match failed for line '%s'" % line
58 64 try:
59 65 ifun, the_rest = line.split(None,1)
60 66 except ValueError:
61 #print "split failed for line '%s'" % line
67 # print "split failed for line '%s'" % line
62 68 ifun, the_rest = line,''
63 69 pre = re.match('^(\s*)(.*)',line).groups()[0]
64 70 else:
65 71 pre,ifun,the_rest = match.groups()
66 72
67 73 # ifun has to be a valid python identifier, so it better be only pure
68 74 # ascii, no unicode:
69 75 try:
70 76 ifun = ifun.encode('ascii')
71 77 except UnicodeEncodeError:
72 78 the_rest = ifun + u' ' + the_rest
73 79 ifun = u''
74 80
75 81 #print 'line:<%s>' % line # dbg
76 82 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
77 83 return pre, ifun.strip(), the_rest.lstrip()
@@ -1,58 +1,58 b''
1 1 # -*- coding: utf-8 -*-
2 2 """ IPython extension: new prefilters for output grabbing
3 3
4 4 Provides
5 5
6 6 var = %magic blah blah
7 7
8 8 var = !ls
9 9 """
10 10
11 11 from IPython.core import ipapi
12 12 from IPython.core.error import TryNext
13 13 from IPython.utils.genutils import *
14 14
15 15 ip = ipapi.get()
16 16
17 17 import re
18 18
19 19 def hnd_magic(line,mo):
20 20 """ Handle a = %mymagic blah blah """
21 21 var = mo.group('varname')
22 22 cmd = mo.group('cmd')
23 23 expr = make_quoted_expr(cmd)
24 24 return itpl('$var = get_ipython().magic($expr)')
25 25
26 26 def hnd_syscmd(line,mo):
27 27 """ Handle a = !ls """
28 28 var = mo.group('varname')
29 29 cmd = mo.group('cmd')
30 30 expr = make_quoted_expr(itpl("sc -l =$cmd"))
31 31 return itpl('$var = get_ipython().magic($expr)')
32 32
33 33 def install_re_handler(pat, hnd):
34 34 ip.meta.re_prefilters.append((re.compile(pat), hnd))
35 35
36 36 def init_handlers():
37 37
38 38 ip.meta.re_prefilters = []
39 39
40 40 install_re_handler('(?P<varname>[\w\.]+)\s*=\s*%(?P<cmd>.*)',
41 41 hnd_magic
42 42 )
43 43
44 44 install_re_handler('(?P<varname>[\w\.]+)\s*=\s*!(?P<cmd>.*)',
45 45 hnd_syscmd
46 46 )
47 47
48 48 init_handlers()
49 49
50 def regex_prefilter_f(self,line):
50 def regex_prefilter_f(self,line):
51 51 for pat, handler in ip.meta.re_prefilters:
52 52 mo = pat.match(line)
53 53 if mo:
54 54 return handler(line,mo)
55 55
56 56 raise TryNext
57 57
58 58 ip.set_hook('input_prefilter', regex_prefilter_f)
General Comments 0
You need to be logged in to leave comments. Login now