##// END OF EJS Templates
Merge pull request #1839 from juliantaylor/external-cleanup...
Thomas Kluyver -
r7317:e9dcd18c merge
parent child Browse files
Show More
@@ -1,957 +1,956 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Prefiltering components.
3 Prefiltering components.
4
4
5 Prefilters transform user input before it is exec'd by Python. These
5 Prefilters transform user input before it is exec'd by Python. These
6 transforms are used to implement additional syntax such as !ls and %magic.
6 transforms are used to implement additional syntax such as !ls and %magic.
7
7
8 Authors:
8 Authors:
9
9
10 * Brian Granger
10 * Brian Granger
11 * Fernando Perez
11 * Fernando Perez
12 * Dan Milstein
12 * Dan Milstein
13 * Ville Vainio
13 * Ville Vainio
14 """
14 """
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Copyright (C) 2008-2011 The IPython Development Team
17 # Copyright (C) 2008-2011 The IPython Development Team
18 #
18 #
19 # Distributed under the terms of the BSD License. The full license is in
19 # Distributed under the terms of the BSD License. The full license is in
20 # the file COPYING, distributed as part of this software.
20 # the file COPYING, distributed as part of this software.
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Imports
24 # Imports
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 import __builtin__
27 import __builtin__
28 import codeop
28 import codeop
29 import re
29 import re
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.config.configurable import Configurable
33 from IPython.config.configurable import Configurable
34 from IPython.core.macro import Macro
34 from IPython.core.macro import Macro
35 from IPython.core.splitinput import split_user_input, LineInfo
35 from IPython.core.splitinput import split_user_input, LineInfo
36 from IPython.core import page
36 from IPython.core import page
37
37
38 from IPython.utils.traitlets import (
38 from IPython.utils.traitlets import (
39 List, Integer, Any, Unicode, CBool, Bool, Instance, CRegExp
39 List, Integer, Any, Unicode, CBool, Bool, Instance, CRegExp
40 )
40 )
41 from IPython.utils.autoattr import auto_attr
41 from IPython.utils.autoattr import auto_attr
42
42
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44 # Global utilities, errors and constants
44 # Global utilities, errors and constants
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 # Warning, these cannot be changed unless various regular expressions
47 # Warning, these cannot be changed unless various regular expressions
48 # are updated in a number of places. Not great, but at least we told you.
48 # are updated in a number of places. Not great, but at least we told you.
49 ESC_SHELL = '!'
49 ESC_SHELL = '!'
50 ESC_SH_CAP = '!!'
50 ESC_SH_CAP = '!!'
51 ESC_HELP = '?'
51 ESC_HELP = '?'
52 ESC_MAGIC = '%'
52 ESC_MAGIC = '%'
53 ESC_QUOTE = ','
53 ESC_QUOTE = ','
54 ESC_QUOTE2 = ';'
54 ESC_QUOTE2 = ';'
55 ESC_PAREN = '/'
55 ESC_PAREN = '/'
56
56
57
57
58 class PrefilterError(Exception):
58 class PrefilterError(Exception):
59 pass
59 pass
60
60
61
61
62 # RegExp to identify potential function names
62 # RegExp to identify potential function names
63 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
63 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
64
64
65 # RegExp to exclude strings with this start from autocalling. In
65 # RegExp to exclude strings with this start from autocalling. In
66 # particular, all binary operators should be excluded, so that if foo is
66 # particular, all binary operators should be excluded, so that if foo is
67 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
67 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
68 # characters '!=()' don't need to be checked for, as the checkPythonChars
68 # characters '!=()' don't need to be checked for, as the checkPythonChars
69 # routine explicitely does so, to catch direct calls and rebindings of
69 # routine explicitely does so, to catch direct calls and rebindings of
70 # existing names.
70 # existing names.
71
71
72 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
72 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
73 # it affects the rest of the group in square brackets.
73 # it affects the rest of the group in square brackets.
74 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
74 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
75 r'|^is |^not |^in |^and |^or ')
75 r'|^is |^not |^in |^and |^or ')
76
76
77 # try to catch also methods for stuff in lists/tuples/dicts: off
77 # try to catch also methods for stuff in lists/tuples/dicts: off
78 # (experimental). For this to work, the line_split regexp would need
78 # (experimental). For this to work, the line_split regexp would need
79 # to be modified so it wouldn't break things at '['. That line is
79 # to be modified so it wouldn't break things at '['. That line is
80 # nasty enough that I shouldn't change it until I can test it _well_.
80 # nasty enough that I shouldn't change it until I can test it _well_.
81 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
81 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
82
82
83
83
84 # Handler Check Utilities
84 # Handler Check Utilities
85 def is_shadowed(identifier, ip):
85 def is_shadowed(identifier, ip):
86 """Is the given identifier defined in one of the namespaces which shadow
86 """Is the given identifier defined in one of the namespaces which shadow
87 the alias and magic namespaces? Note that an identifier is different
87 the alias and magic namespaces? Note that an identifier is different
88 than ifun, because it can not contain a '.' character."""
88 than ifun, because it can not contain a '.' character."""
89 # This is much safer than calling ofind, which can change state
89 # This is much safer than calling ofind, which can change state
90 return (identifier in ip.user_ns \
90 return (identifier in ip.user_ns \
91 or identifier in ip.user_global_ns \
91 or identifier in ip.user_global_ns \
92 or identifier in ip.ns_table['builtin'])
92 or identifier in ip.ns_table['builtin'])
93
93
94
94
95 #-----------------------------------------------------------------------------
95 #-----------------------------------------------------------------------------
96 # Main Prefilter manager
96 # Main Prefilter manager
97 #-----------------------------------------------------------------------------
97 #-----------------------------------------------------------------------------
98
98
99
99
100 class PrefilterManager(Configurable):
100 class PrefilterManager(Configurable):
101 """Main prefilter component.
101 """Main prefilter component.
102
102
103 The IPython prefilter is run on all user input before it is run. The
103 The IPython prefilter is run on all user input before it is run. The
104 prefilter consumes lines of input and produces transformed lines of
104 prefilter consumes lines of input and produces transformed lines of
105 input.
105 input.
106
106
107 The iplementation consists of two phases:
107 The iplementation consists of two phases:
108
108
109 1. Transformers
109 1. Transformers
110 2. Checkers and handlers
110 2. Checkers and handlers
111
111
112 Over time, we plan on deprecating the checkers and handlers and doing
112 Over time, we plan on deprecating the checkers and handlers and doing
113 everything in the transformers.
113 everything in the transformers.
114
114
115 The transformers are instances of :class:`PrefilterTransformer` and have
115 The transformers are instances of :class:`PrefilterTransformer` and have
116 a single method :meth:`transform` that takes a line and returns a
116 a single method :meth:`transform` that takes a line and returns a
117 transformed line. The transformation can be accomplished using any
117 transformed line. The transformation can be accomplished using any
118 tool, but our current ones use regular expressions for speed. We also
118 tool, but our current ones use regular expressions for speed.
119 ship :mod:`pyparsing` in :mod:`IPython.external` for use in transformers.
120
119
121 After all the transformers have been run, the line is fed to the checkers,
120 After all the transformers have been run, the line is fed to the checkers,
122 which are instances of :class:`PrefilterChecker`. The line is passed to
121 which are instances of :class:`PrefilterChecker`. The line is passed to
123 the :meth:`check` method, which either returns `None` or a
122 the :meth:`check` method, which either returns `None` or a
124 :class:`PrefilterHandler` instance. If `None` is returned, the other
123 :class:`PrefilterHandler` instance. If `None` is returned, the other
125 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
124 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
126 the line is passed to the :meth:`handle` method of the returned
125 the line is passed to the :meth:`handle` method of the returned
127 handler and no further checkers are tried.
126 handler and no further checkers are tried.
128
127
129 Both transformers and checkers have a `priority` attribute, that determines
128 Both transformers and checkers have a `priority` attribute, that determines
130 the order in which they are called. Smaller priorities are tried first.
129 the order in which they are called. Smaller priorities are tried first.
131
130
132 Both transformers and checkers also have `enabled` attribute, which is
131 Both transformers and checkers also have `enabled` attribute, which is
133 a boolean that determines if the instance is used.
132 a boolean that determines if the instance is used.
134
133
135 Users or developers can change the priority or enabled attribute of
134 Users or developers can change the priority or enabled attribute of
136 transformers or checkers, but they must call the :meth:`sort_checkers`
135 transformers or checkers, but they must call the :meth:`sort_checkers`
137 or :meth:`sort_transformers` method after changing the priority.
136 or :meth:`sort_transformers` method after changing the priority.
138 """
137 """
139
138
140 multi_line_specials = CBool(True, config=True)
139 multi_line_specials = CBool(True, config=True)
141 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
140 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
142
141
143 def __init__(self, shell=None, config=None):
142 def __init__(self, shell=None, config=None):
144 super(PrefilterManager, self).__init__(shell=shell, config=config)
143 super(PrefilterManager, self).__init__(shell=shell, config=config)
145 self.shell = shell
144 self.shell = shell
146 self.init_transformers()
145 self.init_transformers()
147 self.init_handlers()
146 self.init_handlers()
148 self.init_checkers()
147 self.init_checkers()
149
148
150 #-------------------------------------------------------------------------
149 #-------------------------------------------------------------------------
151 # API for managing transformers
150 # API for managing transformers
152 #-------------------------------------------------------------------------
151 #-------------------------------------------------------------------------
153
152
154 def init_transformers(self):
153 def init_transformers(self):
155 """Create the default transformers."""
154 """Create the default transformers."""
156 self._transformers = []
155 self._transformers = []
157 for transformer_cls in _default_transformers:
156 for transformer_cls in _default_transformers:
158 transformer_cls(
157 transformer_cls(
159 shell=self.shell, prefilter_manager=self, config=self.config
158 shell=self.shell, prefilter_manager=self, config=self.config
160 )
159 )
161
160
162 def sort_transformers(self):
161 def sort_transformers(self):
163 """Sort the transformers by priority.
162 """Sort the transformers by priority.
164
163
165 This must be called after the priority of a transformer is changed.
164 This must be called after the priority of a transformer is changed.
166 The :meth:`register_transformer` method calls this automatically.
165 The :meth:`register_transformer` method calls this automatically.
167 """
166 """
168 self._transformers.sort(key=lambda x: x.priority)
167 self._transformers.sort(key=lambda x: x.priority)
169
168
170 @property
169 @property
171 def transformers(self):
170 def transformers(self):
172 """Return a list of checkers, sorted by priority."""
171 """Return a list of checkers, sorted by priority."""
173 return self._transformers
172 return self._transformers
174
173
175 def register_transformer(self, transformer):
174 def register_transformer(self, transformer):
176 """Register a transformer instance."""
175 """Register a transformer instance."""
177 if transformer not in self._transformers:
176 if transformer not in self._transformers:
178 self._transformers.append(transformer)
177 self._transformers.append(transformer)
179 self.sort_transformers()
178 self.sort_transformers()
180
179
181 def unregister_transformer(self, transformer):
180 def unregister_transformer(self, transformer):
182 """Unregister a transformer instance."""
181 """Unregister a transformer instance."""
183 if transformer in self._transformers:
182 if transformer in self._transformers:
184 self._transformers.remove(transformer)
183 self._transformers.remove(transformer)
185
184
186 #-------------------------------------------------------------------------
185 #-------------------------------------------------------------------------
187 # API for managing checkers
186 # API for managing checkers
188 #-------------------------------------------------------------------------
187 #-------------------------------------------------------------------------
189
188
190 def init_checkers(self):
189 def init_checkers(self):
191 """Create the default checkers."""
190 """Create the default checkers."""
192 self._checkers = []
191 self._checkers = []
193 for checker in _default_checkers:
192 for checker in _default_checkers:
194 checker(
193 checker(
195 shell=self.shell, prefilter_manager=self, config=self.config
194 shell=self.shell, prefilter_manager=self, config=self.config
196 )
195 )
197
196
198 def sort_checkers(self):
197 def sort_checkers(self):
199 """Sort the checkers by priority.
198 """Sort the checkers by priority.
200
199
201 This must be called after the priority of a checker is changed.
200 This must be called after the priority of a checker is changed.
202 The :meth:`register_checker` method calls this automatically.
201 The :meth:`register_checker` method calls this automatically.
203 """
202 """
204 self._checkers.sort(key=lambda x: x.priority)
203 self._checkers.sort(key=lambda x: x.priority)
205
204
206 @property
205 @property
207 def checkers(self):
206 def checkers(self):
208 """Return a list of checkers, sorted by priority."""
207 """Return a list of checkers, sorted by priority."""
209 return self._checkers
208 return self._checkers
210
209
211 def register_checker(self, checker):
210 def register_checker(self, checker):
212 """Register a checker instance."""
211 """Register a checker instance."""
213 if checker not in self._checkers:
212 if checker not in self._checkers:
214 self._checkers.append(checker)
213 self._checkers.append(checker)
215 self.sort_checkers()
214 self.sort_checkers()
216
215
217 def unregister_checker(self, checker):
216 def unregister_checker(self, checker):
218 """Unregister a checker instance."""
217 """Unregister a checker instance."""
219 if checker in self._checkers:
218 if checker in self._checkers:
220 self._checkers.remove(checker)
219 self._checkers.remove(checker)
221
220
222 #-------------------------------------------------------------------------
221 #-------------------------------------------------------------------------
223 # API for managing checkers
222 # API for managing checkers
224 #-------------------------------------------------------------------------
223 #-------------------------------------------------------------------------
225
224
226 def init_handlers(self):
225 def init_handlers(self):
227 """Create the default handlers."""
226 """Create the default handlers."""
228 self._handlers = {}
227 self._handlers = {}
229 self._esc_handlers = {}
228 self._esc_handlers = {}
230 for handler in _default_handlers:
229 for handler in _default_handlers:
231 handler(
230 handler(
232 shell=self.shell, prefilter_manager=self, config=self.config
231 shell=self.shell, prefilter_manager=self, config=self.config
233 )
232 )
234
233
235 @property
234 @property
236 def handlers(self):
235 def handlers(self):
237 """Return a dict of all the handlers."""
236 """Return a dict of all the handlers."""
238 return self._handlers
237 return self._handlers
239
238
240 def register_handler(self, name, handler, esc_strings):
239 def register_handler(self, name, handler, esc_strings):
241 """Register a handler instance by name with esc_strings."""
240 """Register a handler instance by name with esc_strings."""
242 self._handlers[name] = handler
241 self._handlers[name] = handler
243 for esc_str in esc_strings:
242 for esc_str in esc_strings:
244 self._esc_handlers[esc_str] = handler
243 self._esc_handlers[esc_str] = handler
245
244
246 def unregister_handler(self, name, handler, esc_strings):
245 def unregister_handler(self, name, handler, esc_strings):
247 """Unregister a handler instance by name with esc_strings."""
246 """Unregister a handler instance by name with esc_strings."""
248 try:
247 try:
249 del self._handlers[name]
248 del self._handlers[name]
250 except KeyError:
249 except KeyError:
251 pass
250 pass
252 for esc_str in esc_strings:
251 for esc_str in esc_strings:
253 h = self._esc_handlers.get(esc_str)
252 h = self._esc_handlers.get(esc_str)
254 if h is handler:
253 if h is handler:
255 del self._esc_handlers[esc_str]
254 del self._esc_handlers[esc_str]
256
255
257 def get_handler_by_name(self, name):
256 def get_handler_by_name(self, name):
258 """Get a handler by its name."""
257 """Get a handler by its name."""
259 return self._handlers.get(name)
258 return self._handlers.get(name)
260
259
261 def get_handler_by_esc(self, esc_str):
260 def get_handler_by_esc(self, esc_str):
262 """Get a handler by its escape string."""
261 """Get a handler by its escape string."""
263 return self._esc_handlers.get(esc_str)
262 return self._esc_handlers.get(esc_str)
264
263
265 #-------------------------------------------------------------------------
264 #-------------------------------------------------------------------------
266 # Main prefiltering API
265 # Main prefiltering API
267 #-------------------------------------------------------------------------
266 #-------------------------------------------------------------------------
268
267
269 def prefilter_line_info(self, line_info):
268 def prefilter_line_info(self, line_info):
270 """Prefilter a line that has been converted to a LineInfo object.
269 """Prefilter a line that has been converted to a LineInfo object.
271
270
272 This implements the checker/handler part of the prefilter pipe.
271 This implements the checker/handler part of the prefilter pipe.
273 """
272 """
274 # print "prefilter_line_info: ", line_info
273 # print "prefilter_line_info: ", line_info
275 handler = self.find_handler(line_info)
274 handler = self.find_handler(line_info)
276 return handler.handle(line_info)
275 return handler.handle(line_info)
277
276
278 def find_handler(self, line_info):
277 def find_handler(self, line_info):
279 """Find a handler for the line_info by trying checkers."""
278 """Find a handler for the line_info by trying checkers."""
280 for checker in self.checkers:
279 for checker in self.checkers:
281 if checker.enabled:
280 if checker.enabled:
282 handler = checker.check(line_info)
281 handler = checker.check(line_info)
283 if handler:
282 if handler:
284 return handler
283 return handler
285 return self.get_handler_by_name('normal')
284 return self.get_handler_by_name('normal')
286
285
287 def transform_line(self, line, continue_prompt):
286 def transform_line(self, line, continue_prompt):
288 """Calls the enabled transformers in order of increasing priority."""
287 """Calls the enabled transformers in order of increasing priority."""
289 for transformer in self.transformers:
288 for transformer in self.transformers:
290 if transformer.enabled:
289 if transformer.enabled:
291 line = transformer.transform(line, continue_prompt)
290 line = transformer.transform(line, continue_prompt)
292 return line
291 return line
293
292
294 def prefilter_line(self, line, continue_prompt=False):
293 def prefilter_line(self, line, continue_prompt=False):
295 """Prefilter a single input line as text.
294 """Prefilter a single input line as text.
296
295
297 This method prefilters a single line of text by calling the
296 This method prefilters a single line of text by calling the
298 transformers and then the checkers/handlers.
297 transformers and then the checkers/handlers.
299 """
298 """
300
299
301 # print "prefilter_line: ", line, continue_prompt
300 # print "prefilter_line: ", line, continue_prompt
302 # All handlers *must* return a value, even if it's blank ('').
301 # All handlers *must* return a value, even if it's blank ('').
303
302
304 # save the line away in case we crash, so the post-mortem handler can
303 # save the line away in case we crash, so the post-mortem handler can
305 # record it
304 # record it
306 self.shell._last_input_line = line
305 self.shell._last_input_line = line
307
306
308 if not line:
307 if not line:
309 # Return immediately on purely empty lines, so that if the user
308 # Return immediately on purely empty lines, so that if the user
310 # previously typed some whitespace that started a continuation
309 # previously typed some whitespace that started a continuation
311 # prompt, he can break out of that loop with just an empty line.
310 # prompt, he can break out of that loop with just an empty line.
312 # This is how the default python prompt works.
311 # This is how the default python prompt works.
313 return ''
312 return ''
314
313
315 # At this point, we invoke our transformers.
314 # At this point, we invoke our transformers.
316 if not continue_prompt or (continue_prompt and self.multi_line_specials):
315 if not continue_prompt or (continue_prompt and self.multi_line_specials):
317 line = self.transform_line(line, continue_prompt)
316 line = self.transform_line(line, continue_prompt)
318
317
319 # Now we compute line_info for the checkers and handlers
318 # Now we compute line_info for the checkers and handlers
320 line_info = LineInfo(line, continue_prompt)
319 line_info = LineInfo(line, continue_prompt)
321
320
322 # the input history needs to track even empty lines
321 # the input history needs to track even empty lines
323 stripped = line.strip()
322 stripped = line.strip()
324
323
325 normal_handler = self.get_handler_by_name('normal')
324 normal_handler = self.get_handler_by_name('normal')
326 if not stripped:
325 if not stripped:
327 if not continue_prompt:
326 if not continue_prompt:
328 self.shell.displayhook.prompt_count -= 1
327 self.shell.displayhook.prompt_count -= 1
329
328
330 return normal_handler.handle(line_info)
329 return normal_handler.handle(line_info)
331
330
332 # special handlers are only allowed for single line statements
331 # special handlers are only allowed for single line statements
333 if continue_prompt and not self.multi_line_specials:
332 if continue_prompt and not self.multi_line_specials:
334 return normal_handler.handle(line_info)
333 return normal_handler.handle(line_info)
335
334
336 prefiltered = self.prefilter_line_info(line_info)
335 prefiltered = self.prefilter_line_info(line_info)
337 # print "prefiltered line: %r" % prefiltered
336 # print "prefiltered line: %r" % prefiltered
338 return prefiltered
337 return prefiltered
339
338
340 def prefilter_lines(self, lines, continue_prompt=False):
339 def prefilter_lines(self, lines, continue_prompt=False):
341 """Prefilter multiple input lines of text.
340 """Prefilter multiple input lines of text.
342
341
343 This is the main entry point for prefiltering multiple lines of
342 This is the main entry point for prefiltering multiple lines of
344 input. This simply calls :meth:`prefilter_line` for each line of
343 input. This simply calls :meth:`prefilter_line` for each line of
345 input.
344 input.
346
345
347 This covers cases where there are multiple lines in the user entry,
346 This covers cases where there are multiple lines in the user entry,
348 which is the case when the user goes back to a multiline history
347 which is the case when the user goes back to a multiline history
349 entry and presses enter.
348 entry and presses enter.
350 """
349 """
351 llines = lines.rstrip('\n').split('\n')
350 llines = lines.rstrip('\n').split('\n')
352 # We can get multiple lines in one shot, where multiline input 'blends'
351 # We can get multiple lines in one shot, where multiline input 'blends'
353 # into one line, in cases like recalling from the readline history
352 # into one line, in cases like recalling from the readline history
354 # buffer. We need to make sure that in such cases, we correctly
353 # buffer. We need to make sure that in such cases, we correctly
355 # communicate downstream which line is first and which are continuation
354 # communicate downstream which line is first and which are continuation
356 # ones.
355 # ones.
357 if len(llines) > 1:
356 if len(llines) > 1:
358 out = '\n'.join([self.prefilter_line(line, lnum>0)
357 out = '\n'.join([self.prefilter_line(line, lnum>0)
359 for lnum, line in enumerate(llines) ])
358 for lnum, line in enumerate(llines) ])
360 else:
359 else:
361 out = self.prefilter_line(llines[0], continue_prompt)
360 out = self.prefilter_line(llines[0], continue_prompt)
362
361
363 return out
362 return out
364
363
365 #-----------------------------------------------------------------------------
364 #-----------------------------------------------------------------------------
366 # Prefilter transformers
365 # Prefilter transformers
367 #-----------------------------------------------------------------------------
366 #-----------------------------------------------------------------------------
368
367
369
368
370 class PrefilterTransformer(Configurable):
369 class PrefilterTransformer(Configurable):
371 """Transform a line of user input."""
370 """Transform a line of user input."""
372
371
373 priority = Integer(100, config=True)
372 priority = Integer(100, config=True)
374 # Transformers don't currently use shell or prefilter_manager, but as we
373 # Transformers don't currently use shell or prefilter_manager, but as we
375 # move away from checkers and handlers, they will need them.
374 # move away from checkers and handlers, they will need them.
376 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
375 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
377 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
376 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
378 enabled = Bool(True, config=True)
377 enabled = Bool(True, config=True)
379
378
380 def __init__(self, shell=None, prefilter_manager=None, config=None):
379 def __init__(self, shell=None, prefilter_manager=None, config=None):
381 super(PrefilterTransformer, self).__init__(
380 super(PrefilterTransformer, self).__init__(
382 shell=shell, prefilter_manager=prefilter_manager, config=config
381 shell=shell, prefilter_manager=prefilter_manager, config=config
383 )
382 )
384 self.prefilter_manager.register_transformer(self)
383 self.prefilter_manager.register_transformer(self)
385
384
386 def transform(self, line, continue_prompt):
385 def transform(self, line, continue_prompt):
387 """Transform a line, returning the new one."""
386 """Transform a line, returning the new one."""
388 return None
387 return None
389
388
390 def __repr__(self):
389 def __repr__(self):
391 return "<%s(priority=%r, enabled=%r)>" % (
390 return "<%s(priority=%r, enabled=%r)>" % (
392 self.__class__.__name__, self.priority, self.enabled)
391 self.__class__.__name__, self.priority, self.enabled)
393
392
394
393
395 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
394 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
396 r'\s*=\s*!(?P<cmd>.*)')
395 r'\s*=\s*!(?P<cmd>.*)')
397
396
398
397
399 class AssignSystemTransformer(PrefilterTransformer):
398 class AssignSystemTransformer(PrefilterTransformer):
400 """Handle the `files = !ls` syntax."""
399 """Handle the `files = !ls` syntax."""
401
400
402 priority = Integer(100, config=True)
401 priority = Integer(100, config=True)
403
402
404 def transform(self, line, continue_prompt):
403 def transform(self, line, continue_prompt):
405 m = _assign_system_re.match(line)
404 m = _assign_system_re.match(line)
406 if m is not None:
405 if m is not None:
407 cmd = m.group('cmd')
406 cmd = m.group('cmd')
408 lhs = m.group('lhs')
407 lhs = m.group('lhs')
409 expr = "sc =%s" % cmd
408 expr = "sc =%s" % cmd
410 new_line = '%s = get_ipython().magic(%r)' % (lhs, expr)
409 new_line = '%s = get_ipython().magic(%r)' % (lhs, expr)
411 return new_line
410 return new_line
412 return line
411 return line
413
412
414
413
415 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
414 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
416 r'\s*=\s*%(?P<cmd>.*)')
415 r'\s*=\s*%(?P<cmd>.*)')
417
416
418 class AssignMagicTransformer(PrefilterTransformer):
417 class AssignMagicTransformer(PrefilterTransformer):
419 """Handle the `a = %who` syntax."""
418 """Handle the `a = %who` syntax."""
420
419
421 priority = Integer(200, config=True)
420 priority = Integer(200, config=True)
422
421
423 def transform(self, line, continue_prompt):
422 def transform(self, line, continue_prompt):
424 m = _assign_magic_re.match(line)
423 m = _assign_magic_re.match(line)
425 if m is not None:
424 if m is not None:
426 cmd = m.group('cmd')
425 cmd = m.group('cmd')
427 lhs = m.group('lhs')
426 lhs = m.group('lhs')
428 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
427 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
429 return new_line
428 return new_line
430 return line
429 return line
431
430
432
431
433 _classic_prompt_re = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )')
432 _classic_prompt_re = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )')
434
433
435 class PyPromptTransformer(PrefilterTransformer):
434 class PyPromptTransformer(PrefilterTransformer):
436 """Handle inputs that start with '>>> ' syntax."""
435 """Handle inputs that start with '>>> ' syntax."""
437
436
438 priority = Integer(50, config=True)
437 priority = Integer(50, config=True)
439
438
440 def transform(self, line, continue_prompt):
439 def transform(self, line, continue_prompt):
441
440
442 if not line or line.isspace() or line.strip() == '...':
441 if not line or line.isspace() or line.strip() == '...':
443 # This allows us to recognize multiple input prompts separated by
442 # This allows us to recognize multiple input prompts separated by
444 # blank lines and pasted in a single chunk, very common when
443 # blank lines and pasted in a single chunk, very common when
445 # pasting doctests or long tutorial passages.
444 # pasting doctests or long tutorial passages.
446 return ''
445 return ''
447 m = _classic_prompt_re.match(line)
446 m = _classic_prompt_re.match(line)
448 if m:
447 if m:
449 return line[len(m.group(0)):]
448 return line[len(m.group(0)):]
450 else:
449 else:
451 return line
450 return line
452
451
453
452
454 _ipy_prompt_re = re.compile(r'(^[ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
453 _ipy_prompt_re = re.compile(r'(^[ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
455
454
456 class IPyPromptTransformer(PrefilterTransformer):
455 class IPyPromptTransformer(PrefilterTransformer):
457 """Handle inputs that start classic IPython prompt syntax."""
456 """Handle inputs that start classic IPython prompt syntax."""
458
457
459 priority = Integer(50, config=True)
458 priority = Integer(50, config=True)
460
459
461 def transform(self, line, continue_prompt):
460 def transform(self, line, continue_prompt):
462
461
463 if not line or line.isspace() or line.strip() == '...':
462 if not line or line.isspace() or line.strip() == '...':
464 # This allows us to recognize multiple input prompts separated by
463 # This allows us to recognize multiple input prompts separated by
465 # blank lines and pasted in a single chunk, very common when
464 # blank lines and pasted in a single chunk, very common when
466 # pasting doctests or long tutorial passages.
465 # pasting doctests or long tutorial passages.
467 return ''
466 return ''
468 m = _ipy_prompt_re.match(line)
467 m = _ipy_prompt_re.match(line)
469 if m:
468 if m:
470 return line[len(m.group(0)):]
469 return line[len(m.group(0)):]
471 else:
470 else:
472 return line
471 return line
473
472
474 #-----------------------------------------------------------------------------
473 #-----------------------------------------------------------------------------
475 # Prefilter checkers
474 # Prefilter checkers
476 #-----------------------------------------------------------------------------
475 #-----------------------------------------------------------------------------
477
476
478
477
479 class PrefilterChecker(Configurable):
478 class PrefilterChecker(Configurable):
480 """Inspect an input line and return a handler for that line."""
479 """Inspect an input line and return a handler for that line."""
481
480
482 priority = Integer(100, config=True)
481 priority = Integer(100, config=True)
483 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
482 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
484 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
483 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
485 enabled = Bool(True, config=True)
484 enabled = Bool(True, config=True)
486
485
487 def __init__(self, shell=None, prefilter_manager=None, config=None):
486 def __init__(self, shell=None, prefilter_manager=None, config=None):
488 super(PrefilterChecker, self).__init__(
487 super(PrefilterChecker, self).__init__(
489 shell=shell, prefilter_manager=prefilter_manager, config=config
488 shell=shell, prefilter_manager=prefilter_manager, config=config
490 )
489 )
491 self.prefilter_manager.register_checker(self)
490 self.prefilter_manager.register_checker(self)
492
491
493 def check(self, line_info):
492 def check(self, line_info):
494 """Inspect line_info and return a handler instance or None."""
493 """Inspect line_info and return a handler instance or None."""
495 return None
494 return None
496
495
497 def __repr__(self):
496 def __repr__(self):
498 return "<%s(priority=%r, enabled=%r)>" % (
497 return "<%s(priority=%r, enabled=%r)>" % (
499 self.__class__.__name__, self.priority, self.enabled)
498 self.__class__.__name__, self.priority, self.enabled)
500
499
501
500
502 class EmacsChecker(PrefilterChecker):
501 class EmacsChecker(PrefilterChecker):
503
502
504 priority = Integer(100, config=True)
503 priority = Integer(100, config=True)
505 enabled = Bool(False, config=True)
504 enabled = Bool(False, config=True)
506
505
507 def check(self, line_info):
506 def check(self, line_info):
508 "Emacs ipython-mode tags certain input lines."
507 "Emacs ipython-mode tags certain input lines."
509 if line_info.line.endswith('# PYTHON-MODE'):
508 if line_info.line.endswith('# PYTHON-MODE'):
510 return self.prefilter_manager.get_handler_by_name('emacs')
509 return self.prefilter_manager.get_handler_by_name('emacs')
511 else:
510 else:
512 return None
511 return None
513
512
514
513
515 class ShellEscapeChecker(PrefilterChecker):
514 class ShellEscapeChecker(PrefilterChecker):
516
515
517 priority = Integer(200, config=True)
516 priority = Integer(200, config=True)
518
517
519 def check(self, line_info):
518 def check(self, line_info):
520 if line_info.line.lstrip().startswith(ESC_SHELL):
519 if line_info.line.lstrip().startswith(ESC_SHELL):
521 return self.prefilter_manager.get_handler_by_name('shell')
520 return self.prefilter_manager.get_handler_by_name('shell')
522
521
523
522
524 class MacroChecker(PrefilterChecker):
523 class MacroChecker(PrefilterChecker):
525
524
526 priority = Integer(250, config=True)
525 priority = Integer(250, config=True)
527
526
528 def check(self, line_info):
527 def check(self, line_info):
529 obj = self.shell.user_ns.get(line_info.ifun)
528 obj = self.shell.user_ns.get(line_info.ifun)
530 if isinstance(obj, Macro):
529 if isinstance(obj, Macro):
531 return self.prefilter_manager.get_handler_by_name('macro')
530 return self.prefilter_manager.get_handler_by_name('macro')
532 else:
531 else:
533 return None
532 return None
534
533
535
534
536 class IPyAutocallChecker(PrefilterChecker):
535 class IPyAutocallChecker(PrefilterChecker):
537
536
538 priority = Integer(300, config=True)
537 priority = Integer(300, config=True)
539
538
540 def check(self, line_info):
539 def check(self, line_info):
541 "Instances of IPyAutocall in user_ns get autocalled immediately"
540 "Instances of IPyAutocall in user_ns get autocalled immediately"
542 obj = self.shell.user_ns.get(line_info.ifun, None)
541 obj = self.shell.user_ns.get(line_info.ifun, None)
543 if isinstance(obj, IPyAutocall):
542 if isinstance(obj, IPyAutocall):
544 obj.set_ip(self.shell)
543 obj.set_ip(self.shell)
545 return self.prefilter_manager.get_handler_by_name('auto')
544 return self.prefilter_manager.get_handler_by_name('auto')
546 else:
545 else:
547 return None
546 return None
548
547
549
548
550 class MultiLineMagicChecker(PrefilterChecker):
549 class MultiLineMagicChecker(PrefilterChecker):
551
550
552 priority = Integer(400, config=True)
551 priority = Integer(400, config=True)
553
552
554 def check(self, line_info):
553 def check(self, line_info):
555 "Allow ! and !! in multi-line statements if multi_line_specials is on"
554 "Allow ! and !! in multi-line statements if multi_line_specials is on"
556 # Note that this one of the only places we check the first character of
555 # Note that this one of the only places we check the first character of
557 # ifun and *not* the pre_char. Also note that the below test matches
556 # ifun and *not* the pre_char. Also note that the below test matches
558 # both ! and !!.
557 # both ! and !!.
559 if line_info.continue_prompt \
558 if line_info.continue_prompt \
560 and self.prefilter_manager.multi_line_specials:
559 and self.prefilter_manager.multi_line_specials:
561 if line_info.esc == ESC_MAGIC:
560 if line_info.esc == ESC_MAGIC:
562 return self.prefilter_manager.get_handler_by_name('magic')
561 return self.prefilter_manager.get_handler_by_name('magic')
563 else:
562 else:
564 return None
563 return None
565
564
566
565
567 class EscCharsChecker(PrefilterChecker):
566 class EscCharsChecker(PrefilterChecker):
568
567
569 priority = Integer(500, config=True)
568 priority = Integer(500, config=True)
570
569
571 def check(self, line_info):
570 def check(self, line_info):
572 """Check for escape character and return either a handler to handle it,
571 """Check for escape character and return either a handler to handle it,
573 or None if there is no escape char."""
572 or None if there is no escape char."""
574 if line_info.line[-1] == ESC_HELP \
573 if line_info.line[-1] == ESC_HELP \
575 and line_info.esc != ESC_SHELL \
574 and line_info.esc != ESC_SHELL \
576 and line_info.esc != ESC_SH_CAP:
575 and line_info.esc != ESC_SH_CAP:
577 # the ? can be at the end, but *not* for either kind of shell escape,
576 # the ? can be at the end, but *not* for either kind of shell escape,
578 # because a ? can be a vaild final char in a shell cmd
577 # because a ? can be a vaild final char in a shell cmd
579 return self.prefilter_manager.get_handler_by_name('help')
578 return self.prefilter_manager.get_handler_by_name('help')
580 else:
579 else:
581 if line_info.pre:
580 if line_info.pre:
582 return None
581 return None
583 # This returns None like it should if no handler exists
582 # This returns None like it should if no handler exists
584 return self.prefilter_manager.get_handler_by_esc(line_info.esc)
583 return self.prefilter_manager.get_handler_by_esc(line_info.esc)
585
584
586
585
587 class AssignmentChecker(PrefilterChecker):
586 class AssignmentChecker(PrefilterChecker):
588
587
589 priority = Integer(600, config=True)
588 priority = Integer(600, config=True)
590
589
591 def check(self, line_info):
590 def check(self, line_info):
592 """Check to see if user is assigning to a var for the first time, in
591 """Check to see if user is assigning to a var for the first time, in
593 which case we want to avoid any sort of automagic / autocall games.
592 which case we want to avoid any sort of automagic / autocall games.
594
593
595 This allows users to assign to either alias or magic names true python
594 This allows users to assign to either alias or magic names true python
596 variables (the magic/alias systems always take second seat to true
595 variables (the magic/alias systems always take second seat to true
597 python code). E.g. ls='hi', or ls,that=1,2"""
596 python code). E.g. ls='hi', or ls,that=1,2"""
598 if line_info.the_rest:
597 if line_info.the_rest:
599 if line_info.the_rest[0] in '=,':
598 if line_info.the_rest[0] in '=,':
600 return self.prefilter_manager.get_handler_by_name('normal')
599 return self.prefilter_manager.get_handler_by_name('normal')
601 else:
600 else:
602 return None
601 return None
603
602
604
603
605 class AutoMagicChecker(PrefilterChecker):
604 class AutoMagicChecker(PrefilterChecker):
606
605
607 priority = Integer(700, config=True)
606 priority = Integer(700, config=True)
608
607
609 def check(self, line_info):
608 def check(self, line_info):
610 """If the ifun is magic, and automagic is on, run it. Note: normal,
609 """If the ifun is magic, and automagic is on, run it. Note: normal,
611 non-auto magic would already have been triggered via '%' in
610 non-auto magic would already have been triggered via '%' in
612 check_esc_chars. This just checks for automagic. Also, before
611 check_esc_chars. This just checks for automagic. Also, before
613 triggering the magic handler, make sure that there is nothing in the
612 triggering the magic handler, make sure that there is nothing in the
614 user namespace which could shadow it."""
613 user namespace which could shadow it."""
615 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
614 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
616 return None
615 return None
617
616
618 # We have a likely magic method. Make sure we should actually call it.
617 # We have a likely magic method. Make sure we should actually call it.
619 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
618 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
620 return None
619 return None
621
620
622 head = line_info.ifun.split('.',1)[0]
621 head = line_info.ifun.split('.',1)[0]
623 if is_shadowed(head, self.shell):
622 if is_shadowed(head, self.shell):
624 return None
623 return None
625
624
626 return self.prefilter_manager.get_handler_by_name('magic')
625 return self.prefilter_manager.get_handler_by_name('magic')
627
626
628
627
629 class AliasChecker(PrefilterChecker):
628 class AliasChecker(PrefilterChecker):
630
629
631 priority = Integer(800, config=True)
630 priority = Integer(800, config=True)
632
631
633 def check(self, line_info):
632 def check(self, line_info):
634 "Check if the initital identifier on the line is an alias."
633 "Check if the initital identifier on the line is an alias."
635 # Note: aliases can not contain '.'
634 # Note: aliases can not contain '.'
636 head = line_info.ifun.split('.',1)[0]
635 head = line_info.ifun.split('.',1)[0]
637 if line_info.ifun not in self.shell.alias_manager \
636 if line_info.ifun not in self.shell.alias_manager \
638 or head not in self.shell.alias_manager \
637 or head not in self.shell.alias_manager \
639 or is_shadowed(head, self.shell):
638 or is_shadowed(head, self.shell):
640 return None
639 return None
641
640
642 return self.prefilter_manager.get_handler_by_name('alias')
641 return self.prefilter_manager.get_handler_by_name('alias')
643
642
644
643
645 class PythonOpsChecker(PrefilterChecker):
644 class PythonOpsChecker(PrefilterChecker):
646
645
647 priority = Integer(900, config=True)
646 priority = Integer(900, config=True)
648
647
649 def check(self, line_info):
648 def check(self, line_info):
650 """If the 'rest' of the line begins with a function call or pretty much
649 """If the 'rest' of the line begins with a function call or pretty much
651 any python operator, we should simply execute the line (regardless of
650 any python operator, we should simply execute the line (regardless of
652 whether or not there's a possible autocall expansion). This avoids
651 whether or not there's a possible autocall expansion). This avoids
653 spurious (and very confusing) geattr() accesses."""
652 spurious (and very confusing) geattr() accesses."""
654 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
653 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
655 return self.prefilter_manager.get_handler_by_name('normal')
654 return self.prefilter_manager.get_handler_by_name('normal')
656 else:
655 else:
657 return None
656 return None
658
657
659
658
660 class AutocallChecker(PrefilterChecker):
659 class AutocallChecker(PrefilterChecker):
661
660
662 priority = Integer(1000, config=True)
661 priority = Integer(1000, config=True)
663
662
664 function_name_regexp = CRegExp(re_fun_name, config=True,
663 function_name_regexp = CRegExp(re_fun_name, config=True,
665 help="RegExp to identify potential function names.")
664 help="RegExp to identify potential function names.")
666 exclude_regexp = CRegExp(re_exclude_auto, config=True,
665 exclude_regexp = CRegExp(re_exclude_auto, config=True,
667 help="RegExp to exclude strings with this start from autocalling.")
666 help="RegExp to exclude strings with this start from autocalling.")
668
667
669 def check(self, line_info):
668 def check(self, line_info):
670 "Check if the initial word/function is callable and autocall is on."
669 "Check if the initial word/function is callable and autocall is on."
671 if not self.shell.autocall:
670 if not self.shell.autocall:
672 return None
671 return None
673
672
674 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
673 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
675 if not oinfo['found']:
674 if not oinfo['found']:
676 return None
675 return None
677
676
678 if callable(oinfo['obj']) \
677 if callable(oinfo['obj']) \
679 and (not self.exclude_regexp.match(line_info.the_rest)) \
678 and (not self.exclude_regexp.match(line_info.the_rest)) \
680 and self.function_name_regexp.match(line_info.ifun):
679 and self.function_name_regexp.match(line_info.ifun):
681 return self.prefilter_manager.get_handler_by_name('auto')
680 return self.prefilter_manager.get_handler_by_name('auto')
682 else:
681 else:
683 return None
682 return None
684
683
685
684
686 #-----------------------------------------------------------------------------
685 #-----------------------------------------------------------------------------
687 # Prefilter handlers
686 # Prefilter handlers
688 #-----------------------------------------------------------------------------
687 #-----------------------------------------------------------------------------
689
688
690
689
691 class PrefilterHandler(Configurable):
690 class PrefilterHandler(Configurable):
692
691
693 handler_name = Unicode('normal')
692 handler_name = Unicode('normal')
694 esc_strings = List([])
693 esc_strings = List([])
695 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
694 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
696 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
695 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
697
696
698 def __init__(self, shell=None, prefilter_manager=None, config=None):
697 def __init__(self, shell=None, prefilter_manager=None, config=None):
699 super(PrefilterHandler, self).__init__(
698 super(PrefilterHandler, self).__init__(
700 shell=shell, prefilter_manager=prefilter_manager, config=config
699 shell=shell, prefilter_manager=prefilter_manager, config=config
701 )
700 )
702 self.prefilter_manager.register_handler(
701 self.prefilter_manager.register_handler(
703 self.handler_name,
702 self.handler_name,
704 self,
703 self,
705 self.esc_strings
704 self.esc_strings
706 )
705 )
707
706
708 def handle(self, line_info):
707 def handle(self, line_info):
709 # print "normal: ", line_info
708 # print "normal: ", line_info
710 """Handle normal input lines. Use as a template for handlers."""
709 """Handle normal input lines. Use as a template for handlers."""
711
710
712 # With autoindent on, we need some way to exit the input loop, and I
711 # With autoindent on, we need some way to exit the input loop, and I
713 # don't want to force the user to have to backspace all the way to
712 # don't want to force the user to have to backspace all the way to
714 # clear the line. The rule will be in this case, that either two
713 # clear the line. The rule will be in this case, that either two
715 # lines of pure whitespace in a row, or a line of pure whitespace but
714 # lines of pure whitespace in a row, or a line of pure whitespace but
716 # of a size different to the indent level, will exit the input loop.
715 # of a size different to the indent level, will exit the input loop.
717 line = line_info.line
716 line = line_info.line
718 continue_prompt = line_info.continue_prompt
717 continue_prompt = line_info.continue_prompt
719
718
720 if (continue_prompt and
719 if (continue_prompt and
721 self.shell.autoindent and
720 self.shell.autoindent and
722 line.isspace() and
721 line.isspace() and
723 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
722 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
724 line = ''
723 line = ''
725
724
726 return line
725 return line
727
726
728 def __str__(self):
727 def __str__(self):
729 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
728 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
730
729
731
730
732 class AliasHandler(PrefilterHandler):
731 class AliasHandler(PrefilterHandler):
733
732
734 handler_name = Unicode('alias')
733 handler_name = Unicode('alias')
735
734
736 def handle(self, line_info):
735 def handle(self, line_info):
737 """Handle alias input lines. """
736 """Handle alias input lines. """
738 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
737 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
739 # pre is needed, because it carries the leading whitespace. Otherwise
738 # pre is needed, because it carries the leading whitespace. Otherwise
740 # aliases won't work in indented sections.
739 # aliases won't work in indented sections.
741 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, transformed)
740 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, transformed)
742
741
743 return line_out
742 return line_out
744
743
745
744
746 class ShellEscapeHandler(PrefilterHandler):
745 class ShellEscapeHandler(PrefilterHandler):
747
746
748 handler_name = Unicode('shell')
747 handler_name = Unicode('shell')
749 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
748 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
750
749
751 def handle(self, line_info):
750 def handle(self, line_info):
752 """Execute the line in a shell, empty return value"""
751 """Execute the line in a shell, empty return value"""
753 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
752 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
754
753
755 line = line_info.line
754 line = line_info.line
756 if line.lstrip().startswith(ESC_SH_CAP):
755 if line.lstrip().startswith(ESC_SH_CAP):
757 # rewrite LineInfo's line, ifun and the_rest to properly hold the
756 # rewrite LineInfo's line, ifun and the_rest to properly hold the
758 # call to %sx and the actual command to be executed, so
757 # call to %sx and the actual command to be executed, so
759 # handle_magic can work correctly. Note that this works even if
758 # handle_magic can work correctly. Note that this works even if
760 # the line is indented, so it handles multi_line_specials
759 # the line is indented, so it handles multi_line_specials
761 # properly.
760 # properly.
762 new_rest = line.lstrip()[2:]
761 new_rest = line.lstrip()[2:]
763 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
762 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
764 line_info.ifun = 'sx'
763 line_info.ifun = 'sx'
765 line_info.the_rest = new_rest
764 line_info.the_rest = new_rest
766 return magic_handler.handle(line_info)
765 return magic_handler.handle(line_info)
767 else:
766 else:
768 cmd = line.lstrip().lstrip(ESC_SHELL)
767 cmd = line.lstrip().lstrip(ESC_SHELL)
769 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, cmd)
768 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, cmd)
770 return line_out
769 return line_out
771
770
772
771
773 class MacroHandler(PrefilterHandler):
772 class MacroHandler(PrefilterHandler):
774 handler_name = Unicode("macro")
773 handler_name = Unicode("macro")
775
774
776 def handle(self, line_info):
775 def handle(self, line_info):
777 obj = self.shell.user_ns.get(line_info.ifun)
776 obj = self.shell.user_ns.get(line_info.ifun)
778 pre_space = line_info.pre_whitespace
777 pre_space = line_info.pre_whitespace
779 line_sep = "\n" + pre_space
778 line_sep = "\n" + pre_space
780 return pre_space + line_sep.join(obj.value.splitlines())
779 return pre_space + line_sep.join(obj.value.splitlines())
781
780
782
781
783 class MagicHandler(PrefilterHandler):
782 class MagicHandler(PrefilterHandler):
784
783
785 handler_name = Unicode('magic')
784 handler_name = Unicode('magic')
786 esc_strings = List([ESC_MAGIC])
785 esc_strings = List([ESC_MAGIC])
787
786
788 def handle(self, line_info):
787 def handle(self, line_info):
789 """Execute magic functions."""
788 """Execute magic functions."""
790 ifun = line_info.ifun
789 ifun = line_info.ifun
791 the_rest = line_info.the_rest
790 the_rest = line_info.the_rest
792 cmd = '%sget_ipython().magic(%r)' % (line_info.pre_whitespace,
791 cmd = '%sget_ipython().magic(%r)' % (line_info.pre_whitespace,
793 (ifun + " " + the_rest))
792 (ifun + " " + the_rest))
794 return cmd
793 return cmd
795
794
796
795
797 class AutoHandler(PrefilterHandler):
796 class AutoHandler(PrefilterHandler):
798
797
799 handler_name = Unicode('auto')
798 handler_name = Unicode('auto')
800 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
799 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
801
800
802 def handle(self, line_info):
801 def handle(self, line_info):
803 """Handle lines which can be auto-executed, quoting if requested."""
802 """Handle lines which can be auto-executed, quoting if requested."""
804 line = line_info.line
803 line = line_info.line
805 ifun = line_info.ifun
804 ifun = line_info.ifun
806 the_rest = line_info.the_rest
805 the_rest = line_info.the_rest
807 pre = line_info.pre
806 pre = line_info.pre
808 esc = line_info.esc
807 esc = line_info.esc
809 continue_prompt = line_info.continue_prompt
808 continue_prompt = line_info.continue_prompt
810 obj = line_info.ofind(self.shell)['obj']
809 obj = line_info.ofind(self.shell)['obj']
811 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
810 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
812
811
813 # This should only be active for single-line input!
812 # This should only be active for single-line input!
814 if continue_prompt:
813 if continue_prompt:
815 return line
814 return line
816
815
817 force_auto = isinstance(obj, IPyAutocall)
816 force_auto = isinstance(obj, IPyAutocall)
818
817
819 # User objects sometimes raise exceptions on attribute access other
818 # User objects sometimes raise exceptions on attribute access other
820 # than AttributeError (we've seen it in the past), so it's safest to be
819 # than AttributeError (we've seen it in the past), so it's safest to be
821 # ultra-conservative here and catch all.
820 # ultra-conservative here and catch all.
822 try:
821 try:
823 auto_rewrite = obj.rewrite
822 auto_rewrite = obj.rewrite
824 except Exception:
823 except Exception:
825 auto_rewrite = True
824 auto_rewrite = True
826
825
827 if esc == ESC_QUOTE:
826 if esc == ESC_QUOTE:
828 # Auto-quote splitting on whitespace
827 # Auto-quote splitting on whitespace
829 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
828 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
830 elif esc == ESC_QUOTE2:
829 elif esc == ESC_QUOTE2:
831 # Auto-quote whole string
830 # Auto-quote whole string
832 newcmd = '%s("%s")' % (ifun,the_rest)
831 newcmd = '%s("%s")' % (ifun,the_rest)
833 elif esc == ESC_PAREN:
832 elif esc == ESC_PAREN:
834 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
833 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
835 else:
834 else:
836 # Auto-paren.
835 # Auto-paren.
837 if force_auto:
836 if force_auto:
838 # Don't rewrite if it is already a call.
837 # Don't rewrite if it is already a call.
839 do_rewrite = not the_rest.startswith('(')
838 do_rewrite = not the_rest.startswith('(')
840 else:
839 else:
841 if not the_rest:
840 if not the_rest:
842 # We only apply it to argument-less calls if the autocall
841 # We only apply it to argument-less calls if the autocall
843 # parameter is set to 2.
842 # parameter is set to 2.
844 do_rewrite = (self.shell.autocall >= 2)
843 do_rewrite = (self.shell.autocall >= 2)
845 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
844 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
846 # Don't autocall in this case: item access for an object
845 # Don't autocall in this case: item access for an object
847 # which is BOTH callable and implements __getitem__.
846 # which is BOTH callable and implements __getitem__.
848 do_rewrite = False
847 do_rewrite = False
849 else:
848 else:
850 do_rewrite = True
849 do_rewrite = True
851
850
852 # Figure out the rewritten command
851 # Figure out the rewritten command
853 if do_rewrite:
852 if do_rewrite:
854 if the_rest.endswith(';'):
853 if the_rest.endswith(';'):
855 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
854 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
856 else:
855 else:
857 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
856 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
858 else:
857 else:
859 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
858 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
860 return normal_handler.handle(line_info)
859 return normal_handler.handle(line_info)
861
860
862 # Display the rewritten call
861 # Display the rewritten call
863 if auto_rewrite:
862 if auto_rewrite:
864 self.shell.auto_rewrite_input(newcmd)
863 self.shell.auto_rewrite_input(newcmd)
865
864
866 return newcmd
865 return newcmd
867
866
868
867
869 class HelpHandler(PrefilterHandler):
868 class HelpHandler(PrefilterHandler):
870
869
871 handler_name = Unicode('help')
870 handler_name = Unicode('help')
872 esc_strings = List([ESC_HELP])
871 esc_strings = List([ESC_HELP])
873
872
874 def handle(self, line_info):
873 def handle(self, line_info):
875 """Try to get some help for the object.
874 """Try to get some help for the object.
876
875
877 obj? or ?obj -> basic information.
876 obj? or ?obj -> basic information.
878 obj?? or ??obj -> more details.
877 obj?? or ??obj -> more details.
879 """
878 """
880 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
879 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
881 line = line_info.line
880 line = line_info.line
882 # We need to make sure that we don't process lines which would be
881 # We need to make sure that we don't process lines which would be
883 # otherwise valid python, such as "x=1 # what?"
882 # otherwise valid python, such as "x=1 # what?"
884 try:
883 try:
885 codeop.compile_command(line)
884 codeop.compile_command(line)
886 except SyntaxError:
885 except SyntaxError:
887 # We should only handle as help stuff which is NOT valid syntax
886 # We should only handle as help stuff which is NOT valid syntax
888 if line[0]==ESC_HELP:
887 if line[0]==ESC_HELP:
889 line = line[1:]
888 line = line[1:]
890 elif line[-1]==ESC_HELP:
889 elif line[-1]==ESC_HELP:
891 line = line[:-1]
890 line = line[:-1]
892 if line:
891 if line:
893 #print 'line:<%r>' % line # dbg
892 #print 'line:<%r>' % line # dbg
894 self.shell.magic('pinfo %s' % line_info.ifun)
893 self.shell.magic('pinfo %s' % line_info.ifun)
895 else:
894 else:
896 self.shell.show_usage()
895 self.shell.show_usage()
897 return '' # Empty string is needed here!
896 return '' # Empty string is needed here!
898 except:
897 except:
899 raise
898 raise
900 # Pass any other exceptions through to the normal handler
899 # Pass any other exceptions through to the normal handler
901 return normal_handler.handle(line_info)
900 return normal_handler.handle(line_info)
902 else:
901 else:
903 # If the code compiles ok, we should handle it normally
902 # If the code compiles ok, we should handle it normally
904 return normal_handler.handle(line_info)
903 return normal_handler.handle(line_info)
905
904
906
905
907 class EmacsHandler(PrefilterHandler):
906 class EmacsHandler(PrefilterHandler):
908
907
909 handler_name = Unicode('emacs')
908 handler_name = Unicode('emacs')
910 esc_strings = List([])
909 esc_strings = List([])
911
910
912 def handle(self, line_info):
911 def handle(self, line_info):
913 """Handle input lines marked by python-mode."""
912 """Handle input lines marked by python-mode."""
914
913
915 # Currently, nothing is done. Later more functionality can be added
914 # Currently, nothing is done. Later more functionality can be added
916 # here if needed.
915 # here if needed.
917
916
918 # The input cache shouldn't be updated
917 # The input cache shouldn't be updated
919 return line_info.line
918 return line_info.line
920
919
921
920
922 #-----------------------------------------------------------------------------
921 #-----------------------------------------------------------------------------
923 # Defaults
922 # Defaults
924 #-----------------------------------------------------------------------------
923 #-----------------------------------------------------------------------------
925
924
926
925
927 _default_transformers = [
926 _default_transformers = [
928 AssignSystemTransformer,
927 AssignSystemTransformer,
929 AssignMagicTransformer,
928 AssignMagicTransformer,
930 PyPromptTransformer,
929 PyPromptTransformer,
931 IPyPromptTransformer,
930 IPyPromptTransformer,
932 ]
931 ]
933
932
934 _default_checkers = [
933 _default_checkers = [
935 EmacsChecker,
934 EmacsChecker,
936 ShellEscapeChecker,
935 ShellEscapeChecker,
937 MacroChecker,
936 MacroChecker,
938 IPyAutocallChecker,
937 IPyAutocallChecker,
939 MultiLineMagicChecker,
938 MultiLineMagicChecker,
940 EscCharsChecker,
939 EscCharsChecker,
941 AssignmentChecker,
940 AssignmentChecker,
942 AutoMagicChecker,
941 AutoMagicChecker,
943 AliasChecker,
942 AliasChecker,
944 PythonOpsChecker,
943 PythonOpsChecker,
945 AutocallChecker
944 AutocallChecker
946 ]
945 ]
947
946
948 _default_handlers = [
947 _default_handlers = [
949 PrefilterHandler,
948 PrefilterHandler,
950 AliasHandler,
949 AliasHandler,
951 ShellEscapeHandler,
950 ShellEscapeHandler,
952 MacroHandler,
951 MacroHandler,
953 MagicHandler,
952 MagicHandler,
954 AutoHandler,
953 AutoHandler,
955 HelpHandler,
954 HelpHandler,
956 EmacsHandler
955 EmacsHandler
957 ]
956 ]
@@ -1,271 +1,268 b''
1 """Shell mode for IPython.
1 """Shell mode for IPython.
2
2
3 Start ipython in shell mode by invoking "ipython -p sh"
3 Start ipython in shell mode by invoking "ipython -p sh"
4
4
5 (the old version, "ipython -p pysh" still works but this is the more "modern"
5 (the old version, "ipython -p pysh" still works but this is the more "modern"
6 shell mode and is recommended for users who don't care about pysh-mode
6 shell mode and is recommended for users who don't care about pysh-mode
7 compatibility)
7 compatibility)
8 """
8 """
9
9
10 from IPython.core import ipapi
10 from IPython.core import ipapi
11 from IPython.core.error import TryNext
11 from IPython.core.error import TryNext
12 import os,re,textwrap
12 import os,re,textwrap
13
13
14 # The import below effectively obsoletes your old-style ipythonrc[.ini],
14 # The import below effectively obsoletes your old-style ipythonrc[.ini],
15 # so consider yourself warned!
15 # so consider yourself warned!
16
16
17 import ipy_defaults
17 import ipy_defaults
18
18
19 def main():
19 def main():
20 ip = ipapi.get()
20 ip = ipapi.get()
21 o = ip.options
21 o = ip.options
22 # autocall to "full" mode (smart mode is default, I like full mode)
22 # autocall to "full" mode (smart mode is default, I like full mode)
23
23
24 o.autocall = 2
24 o.autocall = 2
25
25
26 # Jason Orendorff's path class is handy to have in user namespace
26 # Jason Orendorff's path class is handy to have in user namespace
27 # if you are doing shell-like stuff
27 # if you are doing shell-like stuff
28 try:
28 try:
29 ip.ex("from IPython.external.path import path" )
29 ip.ex("from IPython.external.path import path" )
30 except ImportError:
30 except ImportError:
31 pass
31 pass
32
32
33 # beefed up %env is handy in shell mode
33 # beefed up %env is handy in shell mode
34 import envpersist
34 import envpersist
35
35
36 # To see where mycmd resides (in path/aliases), do %which mycmd
36 # To see where mycmd resides (in path/aliases), do %which mycmd
37 import ipy_which
37 import ipy_which
38
38
39 # tab completers for hg, svn, ...
39 # tab completers for hg, svn, ...
40 import ipy_app_completers
40 import ipy_app_completers
41
41
42 # To make executables foo and bar in mybin usable without PATH change, do:
42 # To make executables foo and bar in mybin usable without PATH change, do:
43 # %rehashdir c:/mybin
43 # %rehashdir c:/mybin
44 # %store foo
44 # %store foo
45 # %store bar
45 # %store bar
46 import ipy_rehashdir
46 import ipy_rehashdir
47
47
48 # does not work without subprocess module!
48 # does not work without subprocess module!
49 #import ipy_signals
49 #import ipy_signals
50
50
51 ip.ex('import os')
51 ip.ex('import os')
52 ip.ex("def up(): os.chdir('..')")
52 ip.ex("def up(): os.chdir('..')")
53 ip.user_ns['LA'] = LastArgFinder()
53 ip.user_ns['LA'] = LastArgFinder()
54
54
55 # You can assign to _prompt_title variable
55 # You can assign to _prompt_title variable
56 # to provide some extra information for prompt
56 # to provide some extra information for prompt
57 # (e.g. the current mode, host/username...)
57 # (e.g. the current mode, host/username...)
58
58
59 ip.user_ns['_prompt_title'] = ''
59 ip.user_ns['_prompt_title'] = ''
60
60
61 # Nice prompt
61 # Nice prompt
62 o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
62 o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
63 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
63 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
64 o.prompt_out= '<\#> '
64 o.prompt_out= '<\#> '
65
65
66 from IPython.core import release
66 from IPython.core import release
67
67
68 import sys
68 import sys
69 # Non-chatty banner
69 # Non-chatty banner
70 o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0])
70 o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0])
71
71
72
72
73 ip.default_option('cd','-q')
73 ip.default_option('cd','-q')
74 ip.default_option('macro', '-r')
74 ip.default_option('macro', '-r')
75 # If you only rarely want to execute the things you %edit...
75 # If you only rarely want to execute the things you %edit...
76 #ip.default_option('edit','-x')
76 #ip.default_option('edit','-x')
77
77
78
78
79 o.prompts_pad_left="1"
79 o.prompts_pad_left="1"
80 # Remove all blank lines in between prompts, like a normal shell.
80 # Remove all blank lines in between prompts, like a normal shell.
81 o.separate_in="0"
81 o.separate_in="0"
82 o.separate_out="0"
82 o.separate_out="0"
83 o.separate_out2="0"
83 o.separate_out2="0"
84
84
85 # now alias all syscommands
85 # now alias all syscommands
86
86
87 db = ip.db
87 db = ip.db
88
88
89 syscmds = db.get("syscmdlist",[] )
89 syscmds = db.get("syscmdlist",[] )
90 if not syscmds:
90 if not syscmds:
91 print textwrap.dedent("""
91 print textwrap.dedent("""
92 System command list not initialized, probably the first run...
92 System command list not initialized, probably the first run...
93 running %rehashx to refresh the command list. Run %rehashx
93 running %rehashx to refresh the command list. Run %rehashx
94 again to refresh command list (after installing new software etc.)
94 again to refresh command list (after installing new software etc.)
95 """)
95 """)
96 ip.magic('rehashx')
96 ip.magic('rehashx')
97 syscmds = db.get("syscmdlist")
97 syscmds = db.get("syscmdlist")
98
98
99 # lowcase aliases on win32 only
99 # lowcase aliases on win32 only
100 if os.name == 'posix':
100 if os.name == 'posix':
101 mapper = lambda s:s
101 mapper = lambda s:s
102 else:
102 else:
103 def mapper(s): return s.lower()
103 def mapper(s): return s.lower()
104
104
105 for cmd in syscmds:
105 for cmd in syscmds:
106 # print "sys",cmd #dbg
106 # print "sys",cmd #dbg
107 noext, ext = os.path.splitext(cmd)
107 noext, ext = os.path.splitext(cmd)
108 if ext.lower() == '.exe':
108 if ext.lower() == '.exe':
109 cmd = noext
109 cmd = noext
110
110
111 key = mapper(cmd)
111 key = mapper(cmd)
112 if key not in ip.alias_manager.alias_table:
112 if key not in ip.alias_manager.alias_table:
113 # Dots will be removed from alias names, since ipython
113 # Dots will be removed from alias names, since ipython
114 # assumes names with dots to be python code
114 # assumes names with dots to be python code
115
115
116 ip.define_alias(key.replace('.',''), cmd)
116 ip.define_alias(key.replace('.',''), cmd)
117
117
118 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
119 ip.load("IPython.external.mglob")
120
121 # win32 is crippled w/o cygwin, try to help it a little bit
118 # win32 is crippled w/o cygwin, try to help it a little bit
122 if sys.platform == 'win32':
119 if sys.platform == 'win32':
123 if 'cygwin' in os.environ['PATH'].lower():
120 if 'cygwin' in os.environ['PATH'].lower():
124 # use the colors of cygwin ls (recommended)
121 # use the colors of cygwin ls (recommended)
125 ip.define_alias('d', 'ls -F --color=auto')
122 ip.define_alias('d', 'ls -F --color=auto')
126 else:
123 else:
127 # get icp, imv, imkdir, igrep, irm,...
124 # get icp, imv, imkdir, igrep, irm,...
128 ip.load('ipy_fsops')
125 ip.load('ipy_fsops')
129
126
130 # and the next best thing to real 'ls -F'
127 # and the next best thing to real 'ls -F'
131 ip.define_alias('d','dir /w /og /on')
128 ip.define_alias('d','dir /w /og /on')
132
129
133 ip.set_hook('input_prefilter', slash_prefilter_f)
130 ip.set_hook('input_prefilter', slash_prefilter_f)
134 extend_shell_behavior(ip)
131 extend_shell_behavior(ip)
135
132
136 class LastArgFinder:
133 class LastArgFinder:
137 """ Allow $LA to work as "last argument of previous command", like $! in bash
134 """ Allow $LA to work as "last argument of previous command", like $! in bash
138
135
139 To call this in normal IPython code, do LA()
136 To call this in normal IPython code, do LA()
140 """
137 """
141 def __call__(self, hist_idx = None):
138 def __call__(self, hist_idx = None):
142 ip = ipapi.get()
139 ip = ipapi.get()
143 if hist_idx is None:
140 if hist_idx is None:
144 return str(self)
141 return str(self)
145 return ip.input_hist_raw[hist_idx].strip().split()[-1]
142 return ip.input_hist_raw[hist_idx].strip().split()[-1]
146 def __str__(self):
143 def __str__(self):
147 ip = ipapi.get()
144 ip = ipapi.get()
148 for cmd in reversed(ip.input_hist_raw):
145 for cmd in reversed(ip.input_hist_raw):
149 parts = cmd.strip().split()
146 parts = cmd.strip().split()
150 if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']:
147 if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']:
151 continue
148 continue
152 return parts[-1]
149 return parts[-1]
153 return ""
150 return ""
154
151
155 def slash_prefilter_f(self,line):
152 def slash_prefilter_f(self,line):
156 """ ./foo, ~/foo and /bin/foo now run foo as system command
153 """ ./foo, ~/foo and /bin/foo now run foo as system command
157
154
158 Removes the need for doing !./foo, !~/foo or !/bin/foo
155 Removes the need for doing !./foo, !~/foo or !/bin/foo
159 """
156 """
160 from IPython.utils import genutils
157 from IPython.utils import genutils
161 if re.match('(?:[.~]|/[a-zA-Z_0-9]+)/', line):
158 if re.match('(?:[.~]|/[a-zA-Z_0-9]+)/', line):
162 return "get_ipython().system(" + genutils.make_quoted_expr(line)+")"
159 return "get_ipython().system(" + genutils.make_quoted_expr(line)+")"
163 raise TryNext
160 raise TryNext
164
161
165 # XXX You do not need to understand the next function!
162 # XXX You do not need to understand the next function!
166 # This should probably be moved out of profile
163 # This should probably be moved out of profile
167
164
168 def extend_shell_behavior(ip):
165 def extend_shell_behavior(ip):
169
166
170 # Instead of making signature a global variable tie it to IPSHELL.
167 # Instead of making signature a global variable tie it to IPSHELL.
171 # In future if it is required to distinguish between different
168 # In future if it is required to distinguish between different
172 # shells we can assign a signature per shell basis
169 # shells we can assign a signature per shell basis
173 ip.__sig__ = 0xa005
170 ip.__sig__ = 0xa005
174 # mark the IPSHELL with this signature
171 # mark the IPSHELL with this signature
175 ip.user_ns['__builtins__'].__dict__['__sig__'] = ip.__sig__
172 ip.user_ns['__builtins__'].__dict__['__sig__'] = ip.__sig__
176
173
177 from IPython.external.Itpl import ItplNS
174 from IPython.external.Itpl import ItplNS
178 from IPython.utils.genutils import shell
175 from IPython.utils.genutils import shell
179 # utility to expand user variables via Itpl
176 # utility to expand user variables via Itpl
180 # xxx do something sensible with depth?
177 # xxx do something sensible with depth?
181 ip.var_expand = lambda cmd, lvars=None, depth=2: \
178 ip.var_expand = lambda cmd, lvars=None, depth=2: \
182 str(ItplNS(cmd, ip.user_ns, get_locals()))
179 str(ItplNS(cmd, ip.user_ns, get_locals()))
183
180
184 def get_locals():
181 def get_locals():
185 """ Substituting a variable through Itpl deep inside the IPSHELL stack
182 """ Substituting a variable through Itpl deep inside the IPSHELL stack
186 requires the knowledge of all the variables in scope upto the last
183 requires the knowledge of all the variables in scope upto the last
187 IPSHELL frame. This routine simply merges all the local variables
184 IPSHELL frame. This routine simply merges all the local variables
188 on the IPSHELL stack without worrying about their scope rules
185 on the IPSHELL stack without worrying about their scope rules
189 """
186 """
190 import sys
187 import sys
191 # note lambda expression constitues a function call
188 # note lambda expression constitues a function call
192 # hence fno should be incremented by one
189 # hence fno should be incremented by one
193 getsig = lambda fno: sys._getframe(fno+1).f_globals \
190 getsig = lambda fno: sys._getframe(fno+1).f_globals \
194 ['__builtins__'].__dict__['__sig__']
191 ['__builtins__'].__dict__['__sig__']
195 getlvars = lambda fno: sys._getframe(fno+1).f_locals
192 getlvars = lambda fno: sys._getframe(fno+1).f_locals
196 # trackback until we enter the IPSHELL
193 # trackback until we enter the IPSHELL
197 frame_no = 1
194 frame_no = 1
198 sig = ip.__sig__
195 sig = ip.__sig__
199 fsig = ~sig
196 fsig = ~sig
200 while fsig != sig :
197 while fsig != sig :
201 try:
198 try:
202 fsig = getsig(frame_no)
199 fsig = getsig(frame_no)
203 except (AttributeError, KeyError):
200 except (AttributeError, KeyError):
204 frame_no += 1
201 frame_no += 1
205 except ValueError:
202 except ValueError:
206 # stack is depleted
203 # stack is depleted
207 # call did not originate from IPSHELL
204 # call did not originate from IPSHELL
208 return {}
205 return {}
209 first_frame = frame_no
206 first_frame = frame_no
210 # walk further back until we exit from IPSHELL or deplete stack
207 # walk further back until we exit from IPSHELL or deplete stack
211 try:
208 try:
212 while(sig == getsig(frame_no+1)):
209 while(sig == getsig(frame_no+1)):
213 frame_no += 1
210 frame_no += 1
214 except (AttributeError, KeyError, ValueError):
211 except (AttributeError, KeyError, ValueError):
215 pass
212 pass
216 # merge the locals from top down hence overriding
213 # merge the locals from top down hence overriding
217 # any re-definitions of variables, functions etc.
214 # any re-definitions of variables, functions etc.
218 lvars = {}
215 lvars = {}
219 for fno in range(frame_no, first_frame-1, -1):
216 for fno in range(frame_no, first_frame-1, -1):
220 lvars.update(getlvars(fno))
217 lvars.update(getlvars(fno))
221 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
218 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
222 return lvars
219 return lvars
223
220
224 def _runlines(lines):
221 def _runlines(lines):
225 """Run a string of one or more lines of source.
222 """Run a string of one or more lines of source.
226
223
227 This method is capable of running a string containing multiple source
224 This method is capable of running a string containing multiple source
228 lines, as if they had been entered at the IPython prompt. Since it
225 lines, as if they had been entered at the IPython prompt. Since it
229 exposes IPython's processing machinery, the given strings can contain
226 exposes IPython's processing machinery, the given strings can contain
230 magic calls (%magic), special shell access (!cmd), etc."""
227 magic calls (%magic), special shell access (!cmd), etc."""
231
228
232 # We must start with a clean buffer, in case this is run from an
229 # We must start with a clean buffer, in case this is run from an
233 # interactive IPython session (via a magic, for example).
230 # interactive IPython session (via a magic, for example).
234 ip.resetbuffer()
231 ip.resetbuffer()
235 lines = lines.split('\n')
232 lines = lines.split('\n')
236 more = 0
233 more = 0
237 command = ''
234 command = ''
238 for line in lines:
235 for line in lines:
239 # skip blank lines so we don't mess up the prompt counter, but do
236 # skip blank lines so we don't mess up the prompt counter, but do
240 # NOT skip even a blank line if we are in a code block (more is
237 # NOT skip even a blank line if we are in a code block (more is
241 # true)
238 # true)
242 # if command is not empty trim the line
239 # if command is not empty trim the line
243 if command != '' :
240 if command != '' :
244 line = line.strip()
241 line = line.strip()
245 # add the broken line to the command
242 # add the broken line to the command
246 if line and line[-1] == '\\' :
243 if line and line[-1] == '\\' :
247 command += line[0:-1] + ' '
244 command += line[0:-1] + ' '
248 more = True
245 more = True
249 continue
246 continue
250 else :
247 else :
251 # add the last (current) line to the command
248 # add the last (current) line to the command
252 command += line
249 command += line
253 if command or more:
250 if command or more:
254 # push to raw history, so hist line numbers stay in sync
251 # push to raw history, so hist line numbers stay in sync
255 ip.input_hist_raw.append("# " + command + "\n")
252 ip.input_hist_raw.append("# " + command + "\n")
256
253
257 more = ip.push_line(ip.prefilter(command,more))
254 more = ip.push_line(ip.prefilter(command,more))
258 command = ''
255 command = ''
259 # IPython's runsource returns None if there was an error
256 # IPython's runsource returns None if there was an error
260 # compiling the code. This allows us to stop processing right
257 # compiling the code. This allows us to stop processing right
261 # away, so the user gets the error message at the right place.
258 # away, so the user gets the error message at the right place.
262 if more is None:
259 if more is None:
263 break
260 break
264 # final newline in case the input didn't have it, so that the code
261 # final newline in case the input didn't have it, so that the code
265 # actually does get executed
262 # actually does get executed
266 if more:
263 if more:
267 ip.push_line('\n')
264 ip.push_line('\n')
268
265
269 ip.runlines = _runlines
266 ip.runlines = _runlines
270
267
271 main()
268 main()
@@ -1,246 +1,254 b''
1 """ File system operations
1 """ File system operations
2
2
3 Contains: Simple variants of normal unix shell commands (icp, imv, irm,
3 Contains: Simple variants of normal unix shell commands (icp, imv, irm,
4 imkdir, igrep).
4 imkdir, igrep).
5
5
6 Some "otherwise handy" utils ('collect' for gathering files to
6 Some "otherwise handy" utils ('collect' for gathering files to
7 ~/_ipython/collect, 'inote' for collecting single note lines to
7 ~/_ipython/collect, 'inote' for collecting single note lines to
8 ~/_ipython/note.txt)
8 ~/_ipython/note.txt)
9
9
10 Mostly of use for bare windows installations where cygwin/equivalent is not
10 Mostly of use for bare windows installations where cygwin/equivalent is not
11 installed and you would otherwise need to deal with dos versions of the
11 installed and you would otherwise need to deal with dos versions of the
12 commands (that e.g. don't understand / as path separator). These can
12 commands (that e.g. don't understand / as path separator). These can
13 do some useful tricks on their own, though (like use 'mglob' patterns).
13 do some useful tricks on their own, though (like use 'mglob' patterns).
14
14
15 Not to be confused with ipipe commands (ils etc.) that also start with i.
15 Not to be confused with ipipe commands (ils etc.) that also start with i.
16
17 QUARANTINE, NEEDS UPDATING TO THE NEW IPYTHON API TO WORK
18
19 this depends on mglob that used to be in externals,
20 if this code is updated to run again with current IPython, you may need to
21 reintroduce that file back. In doing so, look for the possibility of achieving
22 the same effect only with the standard library (which may have improved by now,
23 since we currently depend on Python 2.6).
16 """
24 """
17
25
18 from IPython.core import ipapi
26 from IPython.core import ipapi
19 from IPython.core.error import TryNext
27 from IPython.core.error import TryNext
20 ip = ipapi.get()
28 ip = ipapi.get()
21
29
22 import shutil,os,shlex
30 import shutil,os,shlex
23 from IPython.external import mglob
31 from IPython.external import mglob
24 from IPython.external.path import path
32 from IPython.external.path import path
25 from IPython.core.error import UsageError
33 from IPython.core.error import UsageError
26 import IPython.utils.generics
34 import IPython.utils.generics
27
35
28 def parse_args(args):
36 def parse_args(args):
29 """ Given arg string 'CMD files... target', return ([files], target) """
37 """ Given arg string 'CMD files... target', return ([files], target) """
30
38
31 tup = args.split(None, 1)
39 tup = args.split(None, 1)
32 if len(tup) == 1:
40 if len(tup) == 1:
33 raise UsageError("Expected arguments for " + tup[0])
41 raise UsageError("Expected arguments for " + tup[0])
34
42
35 tup2 = shlex.split(tup[1])
43 tup2 = shlex.split(tup[1])
36
44
37 flist, trg = mglob.expand(tup2[0:-1]), tup2[-1]
45 flist, trg = mglob.expand(tup2[0:-1]), tup2[-1]
38 if not flist:
46 if not flist:
39 raise UsageError("No files found:" + str(tup2[0:-1]))
47 raise UsageError("No files found:" + str(tup2[0:-1]))
40 return flist, trg
48 return flist, trg
41
49
42 def icp(ip,arg):
50 def icp(ip,arg):
43 """ icp files... targetdir
51 """ icp files... targetdir
44
52
45 Copy all files to target, creating dirs for target if necessary
53 Copy all files to target, creating dirs for target if necessary
46
54
47 icp srcdir dstdir
55 icp srcdir dstdir
48
56
49 Copy srcdir to distdir
57 Copy srcdir to distdir
50
58
51 """
59 """
52 import distutils.dir_util
60 import distutils.dir_util
53
61
54 fs, targetdir = parse_args(arg)
62 fs, targetdir = parse_args(arg)
55 if not os.path.isdir(targetdir) and len(fs) > 1:
63 if not os.path.isdir(targetdir) and len(fs) > 1:
56 distutils.dir_util.mkpath(targetdir,verbose =1)
64 distutils.dir_util.mkpath(targetdir,verbose =1)
57 for f in fs:
65 for f in fs:
58 if os.path.isdir(f):
66 if os.path.isdir(f):
59 shutil.copytree(f, targetdir)
67 shutil.copytree(f, targetdir)
60 else:
68 else:
61 shutil.copy2(f,targetdir)
69 shutil.copy2(f,targetdir)
62 return fs
70 return fs
63 ip.define_alias("icp",icp)
71 ip.define_alias("icp",icp)
64
72
65 def imv(ip,arg):
73 def imv(ip,arg):
66 """ imv src tgt
74 """ imv src tgt
67
75
68 Move source to target.
76 Move source to target.
69 """
77 """
70
78
71 fs, target = parse_args(arg)
79 fs, target = parse_args(arg)
72 if len(fs) > 1:
80 if len(fs) > 1:
73 assert os.path.isdir(target)
81 assert os.path.isdir(target)
74 for f in fs:
82 for f in fs:
75 shutil.move(f, target)
83 shutil.move(f, target)
76 return fs
84 return fs
77 ip.define_alias("imv",imv)
85 ip.define_alias("imv",imv)
78
86
79 def irm(ip,arg):
87 def irm(ip,arg):
80 """ irm path[s]...
88 """ irm path[s]...
81
89
82 Remove file[s] or dir[s] path. Dirs are deleted recursively.
90 Remove file[s] or dir[s] path. Dirs are deleted recursively.
83 """
91 """
84 try:
92 try:
85 paths = mglob.expand(arg.split(None,1)[1])
93 paths = mglob.expand(arg.split(None,1)[1])
86 except IndexError:
94 except IndexError:
87 raise UsageError("%irm paths...")
95 raise UsageError("%irm paths...")
88 import distutils.dir_util
96 import distutils.dir_util
89 for p in paths:
97 for p in paths:
90 print "rm",p
98 print "rm",p
91 if os.path.isdir(p):
99 if os.path.isdir(p):
92 distutils.dir_util.remove_tree(p, verbose = 1)
100 distutils.dir_util.remove_tree(p, verbose = 1)
93 else:
101 else:
94 os.remove(p)
102 os.remove(p)
95
103
96 ip.define_alias("irm",irm)
104 ip.define_alias("irm",irm)
97
105
98 def imkdir(ip,arg):
106 def imkdir(ip,arg):
99 """ imkdir path
107 """ imkdir path
100
108
101 Creates dir path, and all dirs on the road
109 Creates dir path, and all dirs on the road
102 """
110 """
103 import distutils.dir_util
111 import distutils.dir_util
104 targetdir = arg.split(None,1)[1]
112 targetdir = arg.split(None,1)[1]
105 distutils.dir_util.mkpath(targetdir,verbose =1)
113 distutils.dir_util.mkpath(targetdir,verbose =1)
106
114
107 ip.define_alias("imkdir",imkdir)
115 ip.define_alias("imkdir",imkdir)
108
116
109 def igrep(ip,arg):
117 def igrep(ip,arg):
110 """ igrep PAT files...
118 """ igrep PAT files...
111
119
112 Very dumb file scan, case-insensitive.
120 Very dumb file scan, case-insensitive.
113
121
114 e.g.
122 e.g.
115
123
116 igrep "test this" rec:*.py
124 igrep "test this" rec:*.py
117
125
118 """
126 """
119 elems = shlex.split(arg)
127 elems = shlex.split(arg)
120 dummy, pat, fs = elems[0], elems[1], mglob.expand(elems[2:])
128 dummy, pat, fs = elems[0], elems[1], mglob.expand(elems[2:])
121 res = []
129 res = []
122 for f in fs:
130 for f in fs:
123 found = False
131 found = False
124 for l in open(f):
132 for l in open(f):
125 if pat.lower() in l.lower():
133 if pat.lower() in l.lower():
126 if not found:
134 if not found:
127 print "[[",f,"]]"
135 print "[[",f,"]]"
128 found = True
136 found = True
129 res.append(f)
137 res.append(f)
130 print l.rstrip()
138 print l.rstrip()
131 return res
139 return res
132
140
133 ip.define_alias("igrep",igrep)
141 ip.define_alias("igrep",igrep)
134
142
135 def collect(ip,arg):
143 def collect(ip,arg):
136 """ collect foo/a.txt rec:bar=*.py
144 """ collect foo/a.txt rec:bar=*.py
137
145
138 Copies foo/a.txt to ~/_ipython/collect/foo/a.txt and *.py from bar,
146 Copies foo/a.txt to ~/_ipython/collect/foo/a.txt and *.py from bar,
139 likewise
147 likewise
140
148
141 Without args, try to open ~/_ipython/collect dir (in win32 at least).
149 Without args, try to open ~/_ipython/collect dir (in win32 at least).
142 """
150 """
143 from IPython.external.path import path
151 from IPython.external.path import path
144 basedir = path(ip.ipython_dir + '/collect')
152 basedir = path(ip.ipython_dir + '/collect')
145 try:
153 try:
146 fs = mglob.expand(arg.split(None,1)[1])
154 fs = mglob.expand(arg.split(None,1)[1])
147 except IndexError:
155 except IndexError:
148 os.startfile(basedir)
156 os.startfile(basedir)
149 return
157 return
150 for f in fs:
158 for f in fs:
151 f = path(f)
159 f = path(f)
152 trg = basedir / f.splitdrive()[1].lstrip('/\\')
160 trg = basedir / f.splitdrive()[1].lstrip('/\\')
153 if f.isdir():
161 if f.isdir():
154 print "mkdir",trg
162 print "mkdir",trg
155 trg.makedirs()
163 trg.makedirs()
156 continue
164 continue
157 dname = trg.dirname()
165 dname = trg.dirname()
158 if not dname.isdir():
166 if not dname.isdir():
159 dname.makedirs()
167 dname.makedirs()
160 print f,"=>",trg
168 print f,"=>",trg
161 shutil.copy2(f,trg)
169 shutil.copy2(f,trg)
162
170
163 ip.define_alias("collect",collect)
171 ip.define_alias("collect",collect)
164
172
165 def inote(ip,arg):
173 def inote(ip,arg):
166 """ inote Hello world
174 """ inote Hello world
167
175
168 Adds timestamp and Hello world to ~/_ipython/notes.txt
176 Adds timestamp and Hello world to ~/_ipython/notes.txt
169
177
170 Without args, opens notes.txt for editing.
178 Without args, opens notes.txt for editing.
171 """
179 """
172 import time
180 import time
173 fname = ip.ipython_dir + '/notes.txt'
181 fname = ip.ipython_dir + '/notes.txt'
174
182
175 try:
183 try:
176 entry = " === " + time.asctime() + ': ===\n' + arg.split(None,1)[1] + '\n'
184 entry = " === " + time.asctime() + ': ===\n' + arg.split(None,1)[1] + '\n'
177 f= open(fname, 'a').write(entry)
185 f= open(fname, 'a').write(entry)
178 except IndexError:
186 except IndexError:
179 ip.hooks.editor(fname)
187 ip.hooks.editor(fname)
180
188
181 ip.define_alias("inote",inote)
189 ip.define_alias("inote",inote)
182
190
183 def pathobj_mangle(p):
191 def pathobj_mangle(p):
184 return p.replace(' ', '__').replace('.','DOT')
192 return p.replace(' ', '__').replace('.','DOT')
185 def pathobj_unmangle(s):
193 def pathobj_unmangle(s):
186 return s.replace('__',' ').replace('DOT','.')
194 return s.replace('__',' ').replace('DOT','.')
187
195
188
196
189
197
190 class PathObj(path):
198 class PathObj(path):
191 def __init__(self,p):
199 def __init__(self,p):
192 self.path = p
200 self.path = p
193 if p != '.':
201 if p != '.':
194 self.ents = [pathobj_mangle(ent) for ent in os.listdir(p)]
202 self.ents = [pathobj_mangle(ent) for ent in os.listdir(p)]
195 else:
203 else:
196 self.ents = None
204 self.ents = None
197 def __complete__(self):
205 def __complete__(self):
198 if self.path != '.':
206 if self.path != '.':
199 return self.ents
207 return self.ents
200 self.ents = [pathobj_mangle(ent) for ent in os.listdir('.')]
208 self.ents = [pathobj_mangle(ent) for ent in os.listdir('.')]
201 return self.ents
209 return self.ents
202 def __getattr__(self,name):
210 def __getattr__(self,name):
203 if name in self.ents:
211 if name in self.ents:
204 if self.path.endswith('/'):
212 if self.path.endswith('/'):
205 sep = ''
213 sep = ''
206 else:
214 else:
207 sep = '/'
215 sep = '/'
208
216
209 tgt = self.path + sep + pathobj_unmangle(name)
217 tgt = self.path + sep + pathobj_unmangle(name)
210 #print "tgt",tgt
218 #print "tgt",tgt
211 if os.path.isdir(tgt):
219 if os.path.isdir(tgt):
212 return PathObj(tgt)
220 return PathObj(tgt)
213 if os.path.isfile(tgt):
221 if os.path.isfile(tgt):
214 return path(tgt)
222 return path(tgt)
215
223
216 raise AttributeError, name # <<< DON'T FORGET THIS LINE !!
224 raise AttributeError, name # <<< DON'T FORGET THIS LINE !!
217 def __str__(self):
225 def __str__(self):
218 return self.path
226 return self.path
219
227
220 def __repr__(self):
228 def __repr__(self):
221 return "<PathObj to %s>" % self.path
229 return "<PathObj to %s>" % self.path
222
230
223 def __call__(self):
231 def __call__(self):
224 print "cd:",self.path
232 print "cd:",self.path
225 os.chdir(self.path)
233 os.chdir(self.path)
226
234
227 def complete_pathobj(obj, prev_completions):
235 def complete_pathobj(obj, prev_completions):
228 if hasattr(obj,'__complete__'):
236 if hasattr(obj,'__complete__'):
229 res = obj.__complete__()
237 res = obj.__complete__()
230 if res:
238 if res:
231 return res
239 return res
232 # just return normal attributes of 'path' object if the dir is empty
240 # just return normal attributes of 'path' object if the dir is empty
233 raise TryNext
241 raise TryNext
234
242
235 complete_pathobj = IPython.utils.generics.complete_object.when_type(PathObj)(complete_pathobj)
243 complete_pathobj = IPython.utils.generics.complete_object.when_type(PathObj)(complete_pathobj)
236
244
237 def test_pathobj():
245 def test_pathobj():
238 #p = PathObj('c:/prj')
246 #p = PathObj('c:/prj')
239 #p2 = p.cgi
247 #p2 = p.cgi
240 #print p,p2
248 #print p,p2
241 rootdir = PathObj("/")
249 rootdir = PathObj("/")
242 startmenu = PathObj("d:/Documents and Settings/All Users/Start Menu/Programs")
250 startmenu = PathObj("d:/Documents and Settings/All Users/Start Menu/Programs")
243 cwd = PathObj('.')
251 cwd = PathObj('.')
244 ip.push("rootdir startmenu cwd")
252 ip.push("rootdir startmenu cwd")
245
253
246 #test_pathobj() No newline at end of file
254 #test_pathobj()
@@ -1,294 +1,283 b''
1 .. _ipython_as_shell:
1 .. _ipython_as_shell:
2
2
3 =========================
3 =========================
4 IPython as a system shell
4 IPython as a system shell
5 =========================
5 =========================
6
6
7 .. warning::
7 .. warning::
8
8
9 As of the 0.11 version of IPython, most of the APIs used by the shell
9 As of the 0.11 version of IPython, most of the APIs used by the shell
10 profile have been changed, so the profile currently does very little
10 profile have been changed, so the profile currently does very little
11 beyond changing the IPython prompt. To help restore the shell
11 beyond changing the IPython prompt. To help restore the shell
12 profile to past functionality described here, the old code is found in
12 profile to past functionality described here, the old code is found in
13 :file:`IPython/deathrow`, which needs to be updated to use the
13 :file:`IPython/deathrow`, which needs to be updated to use the
14 APIs in 0.11.
14 APIs in 0.11.
15
15
16 Overview
16 Overview
17 ========
17 ========
18
18
19 The 'sh' profile optimizes IPython for system shell usage. Apart from
19 The 'sh' profile optimizes IPython for system shell usage. Apart from
20 certain job control functionality that is present in unix (ctrl+z does
20 certain job control functionality that is present in unix (ctrl+z does
21 "suspend"), the sh profile should provide you with most of the
21 "suspend"), the sh profile should provide you with most of the
22 functionality you use daily in system shell, and more. Invoke IPython
22 functionality you use daily in system shell, and more. Invoke IPython
23 in 'sh' profile by doing 'ipython -p sh', or (in win32) by launching
23 in 'sh' profile by doing 'ipython -p sh', or (in win32) by launching
24 the "pysh" shortcut in start menu.
24 the "pysh" shortcut in start menu.
25
25
26 If you want to use the features of sh profile as your defaults (which
26 If you want to use the features of sh profile as your defaults (which
27 might be a good idea if you use other profiles a lot of the time but
27 might be a good idea if you use other profiles a lot of the time but
28 still want the convenience of sh profile), add ``import ipy_profile_sh``
28 still want the convenience of sh profile), add ``import ipy_profile_sh``
29 to your $IPYTHONDIR/ipy_user_conf.py.
29 to your $IPYTHONDIR/ipy_user_conf.py.
30
30
31 The 'sh' profile is different from the default profile in that:
31 The 'sh' profile is different from the default profile in that:
32
32
33 * Prompt shows the current directory
33 * Prompt shows the current directory
34 * Spacing between prompts and input is more compact (no padding with
34 * Spacing between prompts and input is more compact (no padding with
35 empty lines). The startup banner is more compact as well.
35 empty lines). The startup banner is more compact as well.
36 * System commands are directly available (in alias table) without
36 * System commands are directly available (in alias table) without
37 requesting %rehashx - however, if you install new programs along
37 requesting %rehashx - however, if you install new programs along
38 your PATH, you might want to run %rehashx to update the persistent
38 your PATH, you might want to run %rehashx to update the persistent
39 alias table
39 alias table
40 * Macros are stored in raw format by default. That is, instead of
40 * Macros are stored in raw format by default. That is, instead of
41 '_ip.system("cat foo"), the macro will contain text 'cat foo')
41 '_ip.system("cat foo"), the macro will contain text 'cat foo')
42 * Autocall is in full mode
42 * Autocall is in full mode
43 * Calling "up" does "cd .."
43 * Calling "up" does "cd .."
44
44
45 The 'sh' profile is different from the now-obsolete (and unavailable)
45 The 'sh' profile is different from the now-obsolete (and unavailable)
46 'pysh' profile in that the ``$$var = command`` and ``$var = command`` syntax is
46 'pysh' profile in that the ``$$var = command`` and ``$var = command`` syntax is
47 not supported anymore. Use ``var = !command`` instead (which is available in all
47 not supported anymore. Use ``var = !command`` instead (which is available in all
48 IPython profiles).
48 IPython profiles).
49
49
50 Aliases
50 Aliases
51 =======
51 =======
52
52
53 All of your $PATH has been loaded as IPython aliases, so you should be
53 All of your $PATH has been loaded as IPython aliases, so you should be
54 able to type any normal system command and have it executed. See
54 able to type any normal system command and have it executed. See
55 %alias? and %unalias? for details on the alias facilities. See also
55 %alias? and %unalias? for details on the alias facilities. See also
56 %rehashx? for details on the mechanism used to load $PATH.
56 %rehashx? for details on the mechanism used to load $PATH.
57
57
58
58
59 Directory management
59 Directory management
60 ====================
60 ====================
61
61
62 Since each command passed by ipython to the underlying system is executed
62 Since each command passed by ipython to the underlying system is executed
63 in a subshell which exits immediately, you can NOT use !cd to navigate
63 in a subshell which exits immediately, you can NOT use !cd to navigate
64 the filesystem.
64 the filesystem.
65
65
66 IPython provides its own builtin '%cd' magic command to move in the
66 IPython provides its own builtin '%cd' magic command to move in the
67 filesystem (the % is not required with automagic on). It also maintains
67 filesystem (the % is not required with automagic on). It also maintains
68 a list of visited directories (use %dhist to see it) and allows direct
68 a list of visited directories (use %dhist to see it) and allows direct
69 switching to any of them. Type 'cd?' for more details.
69 switching to any of them. Type 'cd?' for more details.
70
70
71 %pushd, %popd and %dirs are provided for directory stack handling.
71 %pushd, %popd and %dirs are provided for directory stack handling.
72
72
73
73
74 Enabled extensions
74 Enabled extensions
75 ==================
75 ==================
76
76
77 Some extensions, listed below, are enabled as default in this profile.
77 Some extensions, listed below, are enabled as default in this profile.
78
78
79 envpersist
79 envpersist
80 ----------
80 ----------
81
81
82 %env can be used to "remember" environment variable manipulations. Examples::
82 %env can be used to "remember" environment variable manipulations. Examples::
83
83
84 %env - Show all environment variables
84 %env - Show all environment variables
85 %env VISUAL=jed - set VISUAL to jed
85 %env VISUAL=jed - set VISUAL to jed
86 %env PATH+=;/foo - append ;foo to PATH
86 %env PATH+=;/foo - append ;foo to PATH
87 %env PATH+=;/bar - also append ;bar to PATH
87 %env PATH+=;/bar - also append ;bar to PATH
88 %env PATH-=/wbin; - prepend /wbin; to PATH
88 %env PATH-=/wbin; - prepend /wbin; to PATH
89 %env -d VISUAL - forget VISUAL persistent val
89 %env -d VISUAL - forget VISUAL persistent val
90 %env -p - print all persistent env modifications
90 %env -p - print all persistent env modifications
91
91
92 ipy_which
92 ipy_which
93 ---------
93 ---------
94
94
95 %which magic command. Like 'which' in unix, but knows about ipython aliases.
95 %which magic command. Like 'which' in unix, but knows about ipython aliases.
96
96
97 Example::
97 Example::
98
98
99 [C:/ipython]|14> %which st
99 [C:/ipython]|14> %which st
100 st -> start .
100 st -> start .
101 [C:/ipython]|15> %which d
101 [C:/ipython]|15> %which d
102 d -> dir /w /og /on
102 d -> dir /w /og /on
103 [C:/ipython]|16> %which cp
103 [C:/ipython]|16> %which cp
104 cp -> cp
104 cp -> cp
105 == c:\bin\cp.exe
105 == c:\bin\cp.exe
106 c:\bin\cp.exe
106 c:\bin\cp.exe
107
107
108 ipy_app_completers
108 ipy_app_completers
109 ------------------
109 ------------------
110
110
111 Custom tab completers for some apps like svn, hg, bzr, apt-get. Try 'apt-get install <TAB>' in debian/ubuntu.
111 Custom tab completers for some apps like svn, hg, bzr, apt-get. Try 'apt-get install <TAB>' in debian/ubuntu.
112
112
113 ipy_rehashdir
113 ipy_rehashdir
114 -------------
114 -------------
115
115
116 Allows you to add system command aliases for commands that are not along your path. Let's say that you just installed Putty and want to be able to invoke it without adding it to path, you can create the alias for it with rehashdir::
116 Allows you to add system command aliases for commands that are not along your path. Let's say that you just installed Putty and want to be able to invoke it without adding it to path, you can create the alias for it with rehashdir::
117
117
118 [~]|22> cd c:/opt/PuTTY/
118 [~]|22> cd c:/opt/PuTTY/
119 [c:opt/PuTTY]|23> rehashdir .
119 [c:opt/PuTTY]|23> rehashdir .
120 <23> ['pageant', 'plink', 'pscp', 'psftp', 'putty', 'puttygen', 'unins000']
120 <23> ['pageant', 'plink', 'pscp', 'psftp', 'putty', 'puttygen', 'unins000']
121
121
122 Now, you can execute any of those commams directly::
122 Now, you can execute any of those commams directly::
123
123
124 [c:opt/PuTTY]|24> cd
124 [c:opt/PuTTY]|24> cd
125 [~]|25> putty
125 [~]|25> putty
126
126
127 (the putty window opens).
127 (the putty window opens).
128
128
129 If you want to store the alias so that it will always be available, do '%store putty'. If you want to %store all these aliases persistently, just do it in a for loop::
129 If you want to store the alias so that it will always be available, do '%store putty'. If you want to %store all these aliases persistently, just do it in a for loop::
130
130
131 [~]|27> for a in _23:
131 [~]|27> for a in _23:
132 |..> %store $a
132 |..> %store $a
133 |..>
133 |..>
134 |..>
134 |..>
135 Alias stored: pageant (0, 'c:\\opt\\PuTTY\\pageant.exe')
135 Alias stored: pageant (0, 'c:\\opt\\PuTTY\\pageant.exe')
136 Alias stored: plink (0, 'c:\\opt\\PuTTY\\plink.exe')
136 Alias stored: plink (0, 'c:\\opt\\PuTTY\\plink.exe')
137 Alias stored: pscp (0, 'c:\\opt\\PuTTY\\pscp.exe')
137 Alias stored: pscp (0, 'c:\\opt\\PuTTY\\pscp.exe')
138 Alias stored: psftp (0, 'c:\\opt\\PuTTY\\psftp.exe')
138 Alias stored: psftp (0, 'c:\\opt\\PuTTY\\psftp.exe')
139 ...
139 ...
140
140
141 mglob
142 -----
143
144 Provide the magic function %mglob, which makes it easier (than the 'find' command) to collect (possibly recursive) file lists. Examples::
145
146 [c:/ipython]|9> mglob *.py
147 [c:/ipython]|10> mglob *.py rec:*.txt
148 [c:/ipython]|19> workfiles = %mglob !.svn/ !.hg/ !*_Data/ !*.bak rec:.
149
150 Note that the first 2 calls will put the file list in result history (_, _9, _10), and the last one will assign it to 'workfiles'.
151
152
141
153 Prompt customization
142 Prompt customization
154 ====================
143 ====================
155
144
156 The sh profile uses the following prompt configurations::
145 The sh profile uses the following prompt configurations::
157
146
158 c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> '
147 c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> '
159 c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> '
148 c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> '
160 c.PromptManager.out_template = r'<\#> '
149 c.PromptManager.out_template = r'<\#> '
161
150
162 You can change the prompt configuration to your liking by editing
151 You can change the prompt configuration to your liking by editing
163 ipython_config.py.
152 ipython_config.py.
164
153
165 .. _string_lists:
154 .. _string_lists:
166
155
167 String lists
156 String lists
168 ============
157 ============
169
158
170 String lists (IPython.utils.text.SList) are handy way to process output
159 String lists (IPython.utils.text.SList) are handy way to process output
171 from system commands. They are produced by ``var = !cmd`` syntax.
160 from system commands. They are produced by ``var = !cmd`` syntax.
172
161
173 First, we acquire the output of 'ls -l'::
162 First, we acquire the output of 'ls -l'::
174
163
175 [Q:doc/examples]|2> lines = !ls -l
164 [Q:doc/examples]|2> lines = !ls -l
176 ==
165 ==
177 ['total 23',
166 ['total 23',
178 '-rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py',
167 '-rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py',
179 '-rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py',
168 '-rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py',
180 '-rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py',
169 '-rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py',
181 '-rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py',
170 '-rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py',
182 '-rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py',
171 '-rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py',
183 '-rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py',
172 '-rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py',
184 '-rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc']
173 '-rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc']
185
174
186 Now, let's take a look at the contents of 'lines' (the first number is
175 Now, let's take a look at the contents of 'lines' (the first number is
187 the list element number)::
176 the list element number)::
188
177
189 [Q:doc/examples]|3> lines
178 [Q:doc/examples]|3> lines
190 <3> SList (.p, .n, .l, .s, .grep(), .fields() available). Value:
179 <3> SList (.p, .n, .l, .s, .grep(), .fields() available). Value:
191
180
192 0: total 23
181 0: total 23
193 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py
182 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py
194 2: -rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py
183 2: -rw-rw-rw- 1 ville None 1927 Sep 30 2006 example-embed-short.py
195 3: -rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py
184 3: -rwxrwxrwx 1 ville None 4606 Sep 1 17:15 example-embed.py
196 4: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py
185 4: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py
197 5: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py
186 5: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py
198 6: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py
187 6: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py
199 7: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc
188 7: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc
200
189
201 Now, let's filter out the 'embed' lines::
190 Now, let's filter out the 'embed' lines::
202
191
203 [Q:doc/examples]|4> l2 = lines.grep('embed',prune=1)
192 [Q:doc/examples]|4> l2 = lines.grep('embed',prune=1)
204 [Q:doc/examples]|5> l2
193 [Q:doc/examples]|5> l2
205 <5> SList (.p, .n, .l, .s, .grep(), .fields() available). Value:
194 <5> SList (.p, .n, .l, .s, .grep(), .fields() available). Value:
206
195
207 0: total 23
196 0: total 23
208 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py
197 1: -rw-rw-rw- 1 ville None 1163 Sep 30 2006 example-demo.py
209 2: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py
198 2: -rwxrwxrwx 1 ville None 1017 Sep 30 2006 example-gnuplot.py
210 3: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py
199 3: -rwxrwxrwx 1 ville None 339 Jun 11 18:01 extension.py
211 4: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py
200 4: -rwxrwxrwx 1 ville None 113 Dec 20 2006 seteditor.py
212 5: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc
201 5: -rwxrwxrwx 1 ville None 245 Dec 12 2006 seteditor.pyc
213
202
214 Now, we want strings having just file names and permissions::
203 Now, we want strings having just file names and permissions::
215
204
216 [Q:doc/examples]|6> l2.fields(8,0)
205 [Q:doc/examples]|6> l2.fields(8,0)
217 <6> SList (.p, .n, .l, .s, .grep(), .fields() available). Value:
206 <6> SList (.p, .n, .l, .s, .grep(), .fields() available). Value:
218
207
219 0: total
208 0: total
220 1: example-demo.py -rw-rw-rw-
209 1: example-demo.py -rw-rw-rw-
221 2: example-gnuplot.py -rwxrwxrwx
210 2: example-gnuplot.py -rwxrwxrwx
222 3: extension.py -rwxrwxrwx
211 3: extension.py -rwxrwxrwx
223 4: seteditor.py -rwxrwxrwx
212 4: seteditor.py -rwxrwxrwx
224 5: seteditor.pyc -rwxrwxrwx
213 5: seteditor.pyc -rwxrwxrwx
225
214
226 Note how the line with 'total' does not raise IndexError.
215 Note how the line with 'total' does not raise IndexError.
227
216
228 If you want to split these (yielding lists), call fields() without
217 If you want to split these (yielding lists), call fields() without
229 arguments::
218 arguments::
230
219
231 [Q:doc/examples]|7> _.fields()
220 [Q:doc/examples]|7> _.fields()
232 <7>
221 <7>
233 [['total'],
222 [['total'],
234 ['example-demo.py', '-rw-rw-rw-'],
223 ['example-demo.py', '-rw-rw-rw-'],
235 ['example-gnuplot.py', '-rwxrwxrwx'],
224 ['example-gnuplot.py', '-rwxrwxrwx'],
236 ['extension.py', '-rwxrwxrwx'],
225 ['extension.py', '-rwxrwxrwx'],
237 ['seteditor.py', '-rwxrwxrwx'],
226 ['seteditor.py', '-rwxrwxrwx'],
238 ['seteditor.pyc', '-rwxrwxrwx']]
227 ['seteditor.pyc', '-rwxrwxrwx']]
239
228
240 If you want to pass these separated with spaces to a command (typical
229 If you want to pass these separated with spaces to a command (typical
241 for lists if files), use the .s property::
230 for lists if files), use the .s property::
242
231
243
232
244 [Q:doc/examples]|13> files = l2.fields(8).s
233 [Q:doc/examples]|13> files = l2.fields(8).s
245 [Q:doc/examples]|14> files
234 [Q:doc/examples]|14> files
246 <14> 'example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc'
235 <14> 'example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc'
247 [Q:doc/examples]|15> ls $files
236 [Q:doc/examples]|15> ls $files
248 example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc
237 example-demo.py example-gnuplot.py extension.py seteditor.py seteditor.pyc
249
238
250 SLists are inherited from normal python lists, so every list method is
239 SLists are inherited from normal python lists, so every list method is
251 available::
240 available::
252
241
253 [Q:doc/examples]|21> lines.append('hey')
242 [Q:doc/examples]|21> lines.append('hey')
254
243
255
244
256 Real world example: remove all files outside version control
245 Real world example: remove all files outside version control
257 ------------------------------------------------------------
246 ------------------------------------------------------------
258
247
259 First, capture output of "hg status"::
248 First, capture output of "hg status"::
260
249
261 [Q:/ipython]|28> out = !hg status
250 [Q:/ipython]|28> out = !hg status
262 ==
251 ==
263 ['M IPython\\extensions\\ipy_kitcfg.py',
252 ['M IPython\\extensions\\ipy_kitcfg.py',
264 'M IPython\\extensions\\ipy_rehashdir.py',
253 'M IPython\\extensions\\ipy_rehashdir.py',
265 ...
254 ...
266 '? build\\lib\\IPython\\Debugger.py',
255 '? build\\lib\\IPython\\Debugger.py',
267 '? build\\lib\\IPython\\extensions\\InterpreterExec.py',
256 '? build\\lib\\IPython\\extensions\\InterpreterExec.py',
268 '? build\\lib\\IPython\\extensions\\InterpreterPasteInput.py',
257 '? build\\lib\\IPython\\extensions\\InterpreterPasteInput.py',
269 ...
258 ...
270
259
271 (lines starting with ? are not under version control).
260 (lines starting with ? are not under version control).
272
261
273 ::
262 ::
274
263
275 [Q:/ipython]|35> junk = out.grep(r'^\?').fields(1)
264 [Q:/ipython]|35> junk = out.grep(r'^\?').fields(1)
276 [Q:/ipython]|36> junk
265 [Q:/ipython]|36> junk
277 <36> SList (.p, .n, .l, .s, .grep(), .fields() availab
266 <36> SList (.p, .n, .l, .s, .grep(), .fields() availab
278 ...
267 ...
279 10: build\bdist.win32\winexe\temp\_ctypes.py
268 10: build\bdist.win32\winexe\temp\_ctypes.py
280 11: build\bdist.win32\winexe\temp\_hashlib.py
269 11: build\bdist.win32\winexe\temp\_hashlib.py
281 12: build\bdist.win32\winexe\temp\_socket.py
270 12: build\bdist.win32\winexe\temp\_socket.py
282
271
283 Now we can just remove these files by doing 'rm $junk.s'.
272 Now we can just remove these files by doing 'rm $junk.s'.
284
273
285 The .s, .n, .p properties
274 The .s, .n, .p properties
286 -------------------------
275 -------------------------
287
276
288 The ``.s`` property returns one string where lines are separated by
277 The ``.s`` property returns one string where lines are separated by
289 single space (for convenient passing to system commands). The ``.n``
278 single space (for convenient passing to system commands). The ``.n``
290 property return one string where the lines are separated by a newline
279 property return one string where the lines are separated by a newline
291 (i.e. the original output of the function). If the items in string
280 (i.e. the original output of the function). If the items in string
292 list are file names, ``.p`` can be used to get a list of "path" objects
281 list are file names, ``.p`` can be used to get a list of "path" objects
293 for convenient file manipulation.
282 for convenient file manipulation.
294
283
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (3708 lines changed) Show them Hide them
General Comments 0
You need to be logged in to leave comments. Login now