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