Show More
@@ -1,527 +1,528 b'' | |||||
1 | #!/usr/bin/python |
|
1 | #!/usr/bin/python | |
2 | # -*- coding: iso-8859-15 -*- |
|
2 | # -*- coding: iso-8859-15 -*- | |
3 | ''' |
|
3 | ''' | |
4 | Provides IPython remote instance. |
|
4 | Provides IPython remote instance. | |
5 |
|
5 | |||
6 | @author: Laurent Dufrechou |
|
6 | @author: Laurent Dufrechou | |
7 | laurent.dufrechou _at_ gmail.com |
|
7 | laurent.dufrechou _at_ gmail.com | |
8 | @license: BSD |
|
8 | @license: BSD | |
9 |
|
9 | |||
10 | All rights reserved. This program and the accompanying materials are made |
|
10 | All rights reserved. This program and the accompanying materials are made | |
11 | available under the terms of the BSD which accompanies this distribution, and |
|
11 | available under the terms of the BSD which accompanies this distribution, and | |
12 | is available at U{http://www.opensource.org/licenses/bsd-license.php} |
|
12 | is available at U{http://www.opensource.org/licenses/bsd-license.php} | |
13 | ''' |
|
13 | ''' | |
14 |
|
14 | |||
15 | __version__ = 0.9 |
|
15 | __version__ = 0.9 | |
16 | __author__ = "Laurent Dufrechou" |
|
16 | __author__ = "Laurent Dufrechou" | |
17 | __email__ = "laurent.dufrechou _at_ gmail.com" |
|
17 | __email__ = "laurent.dufrechou _at_ gmail.com" | |
18 | __license__ = "BSD" |
|
18 | __license__ = "BSD" | |
19 |
|
19 | |||
20 | import re |
|
20 | import re | |
21 | import sys |
|
21 | import sys | |
22 | import os |
|
22 | import os | |
23 | import locale |
|
23 | import locale | |
24 | from thread_ex import ThreadEx |
|
24 | from thread_ex import ThreadEx | |
25 |
|
25 | |||
26 | try: |
|
26 | import IPython | |
27 | import IPython |
|
27 | from IPython.core import iplib, ipapp | |
28 |
|
|
28 | from IPython.utils import genutils | |
29 | from IPython.core import iplib |
|
|||
30 | except Exception,e: |
|
|||
31 | print "Error importing IPython (%s)" % str(e) |
|
|||
32 | raise Exception, e |
|
|||
33 |
|
29 | |||
34 | ############################################################################## |
|
30 | ############################################################################## | |
35 | class _Helper(object): |
|
31 | class _Helper(object): | |
36 | """Redefine the built-in 'help'. |
|
32 | """Redefine the built-in 'help'. | |
37 | This is a wrapper around pydoc.help (with a twist). |
|
33 | This is a wrapper around pydoc.help (with a twist). | |
38 | """ |
|
34 | """ | |
39 |
|
35 | |||
40 | def __init__(self, pager): |
|
36 | def __init__(self, pager): | |
41 | self._pager = pager |
|
37 | self._pager = pager | |
42 |
|
38 | |||
43 | def __repr__(self): |
|
39 | def __repr__(self): | |
44 | return "Type help() for interactive help, " \ |
|
40 | return "Type help() for interactive help, " \ | |
45 | "or help(object) for help about object." |
|
41 | "or help(object) for help about object." | |
46 |
|
42 | |||
47 | def __call__(self, *args, **kwds): |
|
43 | def __call__(self, *args, **kwds): | |
48 | class DummyWriter(object): |
|
44 | class DummyWriter(object): | |
49 | '''Dumy class to handle help output''' |
|
45 | '''Dumy class to handle help output''' | |
50 | def __init__(self, pager): |
|
46 | def __init__(self, pager): | |
51 | self._pager = pager |
|
47 | self._pager = pager | |
52 |
|
48 | |||
53 | def write(self, data): |
|
49 | def write(self, data): | |
54 | '''hook to fill self._pager''' |
|
50 | '''hook to fill self._pager''' | |
55 | self._pager(data) |
|
51 | self._pager(data) | |
56 |
|
52 | |||
57 | import pydoc |
|
53 | import pydoc | |
58 | pydoc.help.output = DummyWriter(self._pager) |
|
54 | pydoc.help.output = DummyWriter(self._pager) | |
59 | pydoc.help.interact = lambda :1 |
|
55 | pydoc.help.interact = lambda :1 | |
60 |
|
56 | |||
61 | return pydoc.help(*args, **kwds) |
|
57 | return pydoc.help(*args, **kwds) | |
62 |
|
58 | |||
63 |
|
59 | |||
64 | ############################################################################## |
|
60 | ############################################################################## | |
65 | class _CodeExecutor(ThreadEx): |
|
61 | class _CodeExecutor(ThreadEx): | |
66 | ''' Thread that execute ipython code ''' |
|
62 | ''' Thread that execute ipython code ''' | |
67 | def __init__(self, instance): |
|
63 | def __init__(self, instance): | |
68 | ThreadEx.__init__(self) |
|
64 | ThreadEx.__init__(self) | |
69 | self.instance = instance |
|
65 | self.instance = instance | |
70 |
|
66 | |||
71 | def run(self): |
|
67 | def run(self): | |
72 | '''Thread main loop''' |
|
68 | '''Thread main loop''' | |
73 | try: |
|
69 | try: | |
74 | self.instance._doc_text = None |
|
70 | self.instance._doc_text = None | |
75 | self.instance._help_text = None |
|
71 | self.instance._help_text = None | |
76 | self.instance._execute() |
|
72 | self.instance._execute() | |
77 | # used for uper class to generate event after execution |
|
73 | # used for uper class to generate event after execution | |
78 | self.instance._after_execute() |
|
74 | self.instance._after_execute() | |
79 |
|
75 | |||
80 | except KeyboardInterrupt: |
|
76 | except KeyboardInterrupt: | |
81 | pass |
|
77 | pass | |
82 |
|
78 | |||
83 |
|
79 | |||
84 | ############################################################################## |
|
80 | ############################################################################## | |
85 | class NonBlockingIPShell(object): |
|
81 | class NonBlockingIPShell(object): | |
86 | ''' |
|
82 | ''' | |
87 | Create an IPython instance, running the commands in a separate, |
|
83 | Create an IPython instance, running the commands in a separate, | |
88 | non-blocking thread. |
|
84 | non-blocking thread. | |
89 | This allows embedding in any GUI without blockage. |
|
85 | This allows embedding in any GUI without blockage. | |
90 |
|
86 | |||
91 | Note: The ThreadEx class supports asynchroneous function call |
|
87 | Note: The ThreadEx class supports asynchroneous function call | |
92 | via raise_exc() |
|
88 | via raise_exc() | |
93 | ''' |
|
89 | ''' | |
94 |
|
90 | |||
95 | def __init__(self, argv=[], user_ns={}, user_global_ns=None, |
|
91 | def __init__(self, argv=[], user_ns={}, user_global_ns=None, | |
96 | cin=None, cout=None, cerr=None, |
|
92 | cin=None, cout=None, cerr=None, | |
97 | ask_exit_handler=None): |
|
93 | ask_exit_handler=None): | |
98 | ''' |
|
94 | ''' | |
99 | @param argv: Command line options for IPython |
|
95 | @param argv: Command line options for IPython | |
100 | @type argv: list |
|
96 | @type argv: list | |
101 | @param user_ns: User namespace. |
|
97 | @param user_ns: User namespace. | |
102 | @type user_ns: dictionary |
|
98 | @type user_ns: dictionary | |
103 | @param user_global_ns: User global namespace. |
|
99 | @param user_global_ns: User global namespace. | |
104 | @type user_global_ns: dictionary. |
|
100 | @type user_global_ns: dictionary. | |
105 | @param cin: Console standard input. |
|
101 | @param cin: Console standard input. | |
106 | @type cin: IO stream |
|
102 | @type cin: IO stream | |
107 | @param cout: Console standard output. |
|
103 | @param cout: Console standard output. | |
108 | @type cout: IO stream |
|
104 | @type cout: IO stream | |
109 | @param cerr: Console standard error. |
|
105 | @param cerr: Console standard error. | |
110 | @type cerr: IO stream |
|
106 | @type cerr: IO stream | |
111 | @param exit_handler: Replacement for builtin exit() function |
|
107 | @param exit_handler: Replacement for builtin exit() function | |
112 | @type exit_handler: function |
|
108 | @type exit_handler: function | |
113 | @param time_loop: Define the sleep time between two thread's loop |
|
109 | @param time_loop: Define the sleep time between two thread's loop | |
114 | @type int |
|
110 | @type int | |
115 | ''' |
|
111 | ''' | |
116 | #ipython0 initialisation |
|
112 | #ipython0 initialisation | |
117 | self._IP = None |
|
113 | self._IP = None | |
118 | self.init_ipython0(argv, user_ns, user_global_ns, |
|
114 | self.init_ipython0(argv, user_ns, user_global_ns, | |
119 | cin, cout, cerr, |
|
115 | cin, cout, cerr, | |
120 | ask_exit_handler) |
|
116 | ask_exit_handler) | |
121 |
|
117 | |||
122 | #vars used by _execute |
|
118 | #vars used by _execute | |
123 | self._iter_more = 0 |
|
119 | self._iter_more = 0 | |
124 | self._history_level = 0 |
|
120 | self._history_level = 0 | |
125 | self._complete_sep = re.compile('[\s\{\}\[\]\(\)\=]') |
|
121 | self._complete_sep = re.compile('[\s\{\}\[\]\(\)\=]') | |
126 | self._prompt = str(self._IP.outputcache.prompt1).strip() |
|
122 | self._prompt = str(self._IP.outputcache.prompt1).strip() | |
127 |
|
123 | |||
128 | #thread working vars |
|
124 | #thread working vars | |
129 | self._line_to_execute = '' |
|
125 | self._line_to_execute = '' | |
130 | self._threading = True |
|
126 | self._threading = True | |
131 |
|
127 | |||
132 | #vars that will be checked by GUI loop to handle thread states... |
|
128 | #vars that will be checked by GUI loop to handle thread states... | |
133 | #will be replaced later by PostEvent GUI funtions... |
|
129 | #will be replaced later by PostEvent GUI funtions... | |
134 | self._doc_text = None |
|
130 | self._doc_text = None | |
135 | self._help_text = None |
|
131 | self._help_text = None | |
136 | self._add_button = None |
|
132 | self._add_button = None | |
137 |
|
133 | |||
138 | def init_ipython0(self, argv=[], user_ns={}, user_global_ns=None, |
|
134 | def init_ipython0(self, argv=[], user_ns={}, user_global_ns=None, | |
139 | cin=None, cout=None, cerr=None, |
|
135 | cin=None, cout=None, cerr=None, | |
140 | ask_exit_handler=None): |
|
136 | ask_exit_handler=None): | |
141 | ''' Initialize an ipython0 instance ''' |
|
137 | ''' Initialize an ipython0 instance ''' | |
142 |
|
138 | |||
143 | #first we redefine in/out/error functions of IPython |
|
139 | #first we redefine in/out/error functions of IPython | |
144 | #BUG: we've got a limitation form ipython0 there |
|
140 | #BUG: we've got a limitation form ipython0 there | |
145 | #only one instance can be instanciated else tehre will be |
|
141 | #only one instance can be instanciated else tehre will be | |
146 | #cin/cout/cerr clash... |
|
142 | #cin/cout/cerr clash... | |
147 | if cin: |
|
143 | if cin: | |
148 | genutils.Term.cin = cin |
|
144 | genutils.Term.cin = cin | |
149 | if cout: |
|
145 | if cout: | |
150 | genutils.Term.cout = cout |
|
146 | genutils.Term.cout = cout | |
151 | if cerr: |
|
147 | if cerr: | |
152 | genutils.Term.cerr = cerr |
|
148 | genutils.Term.cerr = cerr | |
153 |
|
149 | |||
154 | excepthook = sys.excepthook |
|
150 | excepthook = sys.excepthook | |
155 |
|
151 | |||
156 | #Hack to save sys.displayhook, because ipython seems to overwrite it... |
|
152 | #Hack to save sys.displayhook, because ipython seems to overwrite it... | |
157 | self.sys_displayhook_ori = sys.displayhook |
|
153 | self.sys_displayhook_ori = sys.displayhook | |
|
154 | ||||
|
155 | ipython0 = ipapp.IPythonApp(argv,user_ns=user_ns, | |||
|
156 | user_global_ns=user_global_ns) | |||
|
157 | ipython0.initialize() | |||
|
158 | self._IP = ipython0.shell | |||
158 |
|
159 | |||
159 | self._IP = IPython.shell.make_IPython( |
|
160 | ## self._IP = IPython.shell.make_IPython( | |
160 | argv,user_ns=user_ns, |
|
161 | ## argv,user_ns=user_ns, | |
161 | user_global_ns=user_global_ns, |
|
162 | ## user_global_ns=user_global_ns, | |
162 | embedded=True, |
|
163 | ## embedded=True, | |
163 | shell_class=IPython.shell.InteractiveShell) |
|
164 | ## shell_class=IPython.shell.InteractiveShell) | |
164 |
|
165 | |||
165 | #we save ipython0 displayhook and we restore sys.displayhook |
|
166 | #we save ipython0 displayhook and we restore sys.displayhook | |
166 | self.displayhook = sys.displayhook |
|
167 | self.displayhook = sys.displayhook | |
167 | sys.displayhook = self.sys_displayhook_ori |
|
168 | sys.displayhook = self.sys_displayhook_ori | |
168 |
|
169 | |||
169 | #we replace IPython default encoding by wx locale encoding |
|
170 | #we replace IPython default encoding by wx locale encoding | |
170 | loc = locale.getpreferredencoding() |
|
171 | loc = locale.getpreferredencoding() | |
171 | if loc: |
|
172 | if loc: | |
172 | self._IP.stdin_encoding = loc |
|
173 | self._IP.stdin_encoding = loc | |
173 | #we replace the ipython default pager by our pager |
|
174 | #we replace the ipython default pager by our pager | |
174 | self._IP.set_hook('show_in_pager', self._pager) |
|
175 | self._IP.set_hook('show_in_pager', self._pager) | |
175 |
|
176 | |||
176 | #we replace the ipython default shell command caller |
|
177 | #we replace the ipython default shell command caller | |
177 | #by our shell handler |
|
178 | #by our shell handler | |
178 | self._IP.set_hook('shell_hook', self._shell) |
|
179 | self._IP.set_hook('shell_hook', self._shell) | |
179 |
|
180 | |||
180 | #we replace the ipython default input command caller by our method |
|
181 | #we replace the ipython default input command caller by our method | |
181 | iplib.raw_input_original = self._raw_input_original |
|
182 | iplib.raw_input_original = self._raw_input_original | |
182 | #we replace the ipython default exit command by our method |
|
183 | #we replace the ipython default exit command by our method | |
183 | self._IP.exit = ask_exit_handler |
|
184 | self._IP.exit = ask_exit_handler | |
184 | #we replace the help command |
|
185 | #we replace the help command | |
185 | self._IP.user_ns['help'] = _Helper(self._pager_help) |
|
186 | self._IP.user_ns['help'] = _Helper(self._pager_help) | |
186 |
|
187 | |||
187 | #we disable cpase magic... until we found a way to use it properly. |
|
188 | #we disable cpase magic... until we found a way to use it properly. | |
188 | from IPython.core import ipapi |
|
189 | from IPython.core import ipapi | |
189 | ip = ipapi.get() |
|
190 | ip = ipapi.get() | |
190 | def bypass_magic(self, arg): |
|
191 | def bypass_magic(self, arg): | |
191 | print '%this magic is currently disabled.' |
|
192 | print '%this magic is currently disabled.' | |
192 | ip.define_magic('cpaste', bypass_magic) |
|
193 | ip.define_magic('cpaste', bypass_magic) | |
193 |
|
194 | |||
194 | import __builtin__ |
|
195 | import __builtin__ | |
195 | __builtin__.raw_input = self._raw_input |
|
196 | __builtin__.raw_input = self._raw_input | |
196 |
|
197 | |||
197 | sys.excepthook = excepthook |
|
198 | sys.excepthook = excepthook | |
198 |
|
199 | |||
199 | #----------------------- Thread management section ---------------------- |
|
200 | #----------------------- Thread management section ---------------------- | |
200 | def do_execute(self, line): |
|
201 | def do_execute(self, line): | |
201 | """ |
|
202 | """ | |
202 | Tell the thread to process the 'line' command |
|
203 | Tell the thread to process the 'line' command | |
203 | """ |
|
204 | """ | |
204 |
|
205 | |||
205 | self._line_to_execute = line |
|
206 | self._line_to_execute = line | |
206 |
|
207 | |||
207 | if self._threading: |
|
208 | if self._threading: | |
208 | #we launch the ipython line execution in a thread to make it |
|
209 | #we launch the ipython line execution in a thread to make it | |
209 | #interruptible with include it in self namespace to be able |
|
210 | #interruptible with include it in self namespace to be able | |
210 | #to call ce.raise_exc(KeyboardInterrupt) |
|
211 | #to call ce.raise_exc(KeyboardInterrupt) | |
211 | self.ce = _CodeExecutor(self) |
|
212 | self.ce = _CodeExecutor(self) | |
212 | self.ce.start() |
|
213 | self.ce.start() | |
213 | else: |
|
214 | else: | |
214 | try: |
|
215 | try: | |
215 | self._doc_text = None |
|
216 | self._doc_text = None | |
216 | self._help_text = None |
|
217 | self._help_text = None | |
217 | self._execute() |
|
218 | self._execute() | |
218 | # used for uper class to generate event after execution |
|
219 | # used for uper class to generate event after execution | |
219 | self._after_execute() |
|
220 | self._after_execute() | |
220 |
|
221 | |||
221 | except KeyboardInterrupt: |
|
222 | except KeyboardInterrupt: | |
222 | pass |
|
223 | pass | |
223 |
|
224 | |||
224 | #----------------------- IPython management section ---------------------- |
|
225 | #----------------------- IPython management section ---------------------- | |
225 | def get_threading(self): |
|
226 | def get_threading(self): | |
226 | """ |
|
227 | """ | |
227 | Returns threading status, is set to True, then each command sent to |
|
228 | Returns threading status, is set to True, then each command sent to | |
228 | the interpreter will be executed in a separated thread allowing, |
|
229 | the interpreter will be executed in a separated thread allowing, | |
229 | for example, breaking a long running commands. |
|
230 | for example, breaking a long running commands. | |
230 | Disallowing it, permits better compatibilty with instance that is embedding |
|
231 | Disallowing it, permits better compatibilty with instance that is embedding | |
231 | IPython instance. |
|
232 | IPython instance. | |
232 |
|
233 | |||
233 | @return: Execution method |
|
234 | @return: Execution method | |
234 | @rtype: bool |
|
235 | @rtype: bool | |
235 | """ |
|
236 | """ | |
236 | return self._threading |
|
237 | return self._threading | |
237 |
|
238 | |||
238 | def set_threading(self, state): |
|
239 | def set_threading(self, state): | |
239 | """ |
|
240 | """ | |
240 | Sets threading state, if set to True, then each command sent to |
|
241 | Sets threading state, if set to True, then each command sent to | |
241 | the interpreter will be executed in a separated thread allowing, |
|
242 | the interpreter will be executed in a separated thread allowing, | |
242 | for example, breaking a long running commands. |
|
243 | for example, breaking a long running commands. | |
243 | Disallowing it, permits better compatibilty with instance that is embedding |
|
244 | Disallowing it, permits better compatibilty with instance that is embedding | |
244 | IPython instance. |
|
245 | IPython instance. | |
245 |
|
246 | |||
246 | @param state: Sets threading state |
|
247 | @param state: Sets threading state | |
247 | @type bool |
|
248 | @type bool | |
248 | """ |
|
249 | """ | |
249 | self._threading = state |
|
250 | self._threading = state | |
250 |
|
251 | |||
251 | def get_doc_text(self): |
|
252 | def get_doc_text(self): | |
252 | """ |
|
253 | """ | |
253 | Returns the output of the processing that need to be paged (if any) |
|
254 | Returns the output of the processing that need to be paged (if any) | |
254 |
|
255 | |||
255 | @return: The std output string. |
|
256 | @return: The std output string. | |
256 | @rtype: string |
|
257 | @rtype: string | |
257 | """ |
|
258 | """ | |
258 | return self._doc_text |
|
259 | return self._doc_text | |
259 |
|
260 | |||
260 | def get_help_text(self): |
|
261 | def get_help_text(self): | |
261 | """ |
|
262 | """ | |
262 | Returns the output of the processing that need to be paged via help pager(if any) |
|
263 | Returns the output of the processing that need to be paged via help pager(if any) | |
263 |
|
264 | |||
264 | @return: The std output string. |
|
265 | @return: The std output string. | |
265 | @rtype: string |
|
266 | @rtype: string | |
266 | """ |
|
267 | """ | |
267 | return self._help_text |
|
268 | return self._help_text | |
268 |
|
269 | |||
269 | def get_banner(self): |
|
270 | def get_banner(self): | |
270 | """ |
|
271 | """ | |
271 | Returns the IPython banner for useful info on IPython instance |
|
272 | Returns the IPython banner for useful info on IPython instance | |
272 |
|
273 | |||
273 | @return: The banner string. |
|
274 | @return: The banner string. | |
274 | @rtype: string |
|
275 | @rtype: string | |
275 | """ |
|
276 | """ | |
276 |
return self._IP. |
|
277 | return self._IP.banner | |
277 |
|
278 | |||
278 | def get_prompt_count(self): |
|
279 | def get_prompt_count(self): | |
279 | """ |
|
280 | """ | |
280 | Returns the prompt number. |
|
281 | Returns the prompt number. | |
281 | Each time a user execute a line in the IPython shell the prompt count is increased |
|
282 | Each time a user execute a line in the IPython shell the prompt count is increased | |
282 |
|
283 | |||
283 | @return: The prompt number |
|
284 | @return: The prompt number | |
284 | @rtype: int |
|
285 | @rtype: int | |
285 | """ |
|
286 | """ | |
286 | return self._IP.outputcache.prompt_count |
|
287 | return self._IP.outputcache.prompt_count | |
287 |
|
288 | |||
288 | def get_prompt(self): |
|
289 | def get_prompt(self): | |
289 | """ |
|
290 | """ | |
290 | Returns current prompt inside IPython instance |
|
291 | Returns current prompt inside IPython instance | |
291 | (Can be In [...]: ot ...:) |
|
292 | (Can be In [...]: ot ...:) | |
292 |
|
293 | |||
293 | @return: The current prompt. |
|
294 | @return: The current prompt. | |
294 | @rtype: string |
|
295 | @rtype: string | |
295 | """ |
|
296 | """ | |
296 | return self._prompt |
|
297 | return self._prompt | |
297 |
|
298 | |||
298 | def get_indentation(self): |
|
299 | def get_indentation(self): | |
299 | """ |
|
300 | """ | |
300 | Returns the current indentation level |
|
301 | Returns the current indentation level | |
301 | Usefull to put the caret at the good start position if we want to do autoindentation. |
|
302 | Usefull to put the caret at the good start position if we want to do autoindentation. | |
302 |
|
303 | |||
303 | @return: The indentation level. |
|
304 | @return: The indentation level. | |
304 | @rtype: int |
|
305 | @rtype: int | |
305 | """ |
|
306 | """ | |
306 | return self._IP.indent_current_nsp |
|
307 | return self._IP.indent_current_nsp | |
307 |
|
308 | |||
308 | def update_namespace(self, ns_dict): |
|
309 | def update_namespace(self, ns_dict): | |
309 | ''' |
|
310 | ''' | |
310 | Add the current dictionary to the shell namespace. |
|
311 | Add the current dictionary to the shell namespace. | |
311 |
|
312 | |||
312 | @param ns_dict: A dictionary of symbol-values. |
|
313 | @param ns_dict: A dictionary of symbol-values. | |
313 | @type ns_dict: dictionary |
|
314 | @type ns_dict: dictionary | |
314 | ''' |
|
315 | ''' | |
315 | self._IP.user_ns.update(ns_dict) |
|
316 | self._IP.user_ns.update(ns_dict) | |
316 |
|
317 | |||
317 | def complete(self, line): |
|
318 | def complete(self, line): | |
318 | ''' |
|
319 | ''' | |
319 | Returns an auto completed line and/or posibilities for completion. |
|
320 | Returns an auto completed line and/or posibilities for completion. | |
320 |
|
321 | |||
321 | @param line: Given line so far. |
|
322 | @param line: Given line so far. | |
322 | @type line: string |
|
323 | @type line: string | |
323 |
|
324 | |||
324 | @return: Line completed as for as possible, |
|
325 | @return: Line completed as for as possible, | |
325 | and possible further completions. |
|
326 | and possible further completions. | |
326 | @rtype: tuple |
|
327 | @rtype: tuple | |
327 | ''' |
|
328 | ''' | |
328 | split_line = self._complete_sep.split(line) |
|
329 | split_line = self._complete_sep.split(line) | |
329 | possibilities = self._IP.complete(split_line[-1]) |
|
330 | possibilities = self._IP.complete(split_line[-1]) | |
330 | if possibilities: |
|
331 | if possibilities: | |
331 |
|
332 | |||
332 | def _common_prefix(str1, str2): |
|
333 | def _common_prefix(str1, str2): | |
333 | ''' |
|
334 | ''' | |
334 | Reduction function. returns common prefix of two given strings. |
|
335 | Reduction function. returns common prefix of two given strings. | |
335 |
|
336 | |||
336 | @param str1: First string. |
|
337 | @param str1: First string. | |
337 | @type str1: string |
|
338 | @type str1: string | |
338 | @param str2: Second string |
|
339 | @param str2: Second string | |
339 | @type str2: string |
|
340 | @type str2: string | |
340 |
|
341 | |||
341 | @return: Common prefix to both strings. |
|
342 | @return: Common prefix to both strings. | |
342 | @rtype: string |
|
343 | @rtype: string | |
343 | ''' |
|
344 | ''' | |
344 | for i in range(len(str1)): |
|
345 | for i in range(len(str1)): | |
345 | if not str2.startswith(str1[:i+1]): |
|
346 | if not str2.startswith(str1[:i+1]): | |
346 | return str1[:i] |
|
347 | return str1[:i] | |
347 | return str1 |
|
348 | return str1 | |
348 | common_prefix = reduce(_common_prefix, possibilities) |
|
349 | common_prefix = reduce(_common_prefix, possibilities) | |
349 | completed = line[:-len(split_line[-1])]+common_prefix |
|
350 | completed = line[:-len(split_line[-1])]+common_prefix | |
350 | else: |
|
351 | else: | |
351 | completed = line |
|
352 | completed = line | |
352 | return completed, possibilities |
|
353 | return completed, possibilities | |
353 |
|
354 | |||
354 | def history_back(self): |
|
355 | def history_back(self): | |
355 | ''' |
|
356 | ''' | |
356 | Provides one history command back. |
|
357 | Provides one history command back. | |
357 |
|
358 | |||
358 | @return: The command string. |
|
359 | @return: The command string. | |
359 | @rtype: string |
|
360 | @rtype: string | |
360 | ''' |
|
361 | ''' | |
361 | history = '' |
|
362 | history = '' | |
362 | #the below while loop is used to suppress empty history lines |
|
363 | #the below while loop is used to suppress empty history lines | |
363 | while((history == '' or history == '\n') and self._history_level >0): |
|
364 | while((history == '' or history == '\n') and self._history_level >0): | |
364 | if self._history_level >= 1: |
|
365 | if self._history_level >= 1: | |
365 | self._history_level -= 1 |
|
366 | self._history_level -= 1 | |
366 | history = self._get_history() |
|
367 | history = self._get_history() | |
367 | return history |
|
368 | return history | |
368 |
|
369 | |||
369 | def history_forward(self): |
|
370 | def history_forward(self): | |
370 | ''' |
|
371 | ''' | |
371 | Provides one history command forward. |
|
372 | Provides one history command forward. | |
372 |
|
373 | |||
373 | @return: The command string. |
|
374 | @return: The command string. | |
374 | @rtype: string |
|
375 | @rtype: string | |
375 | ''' |
|
376 | ''' | |
376 | history = '' |
|
377 | history = '' | |
377 | #the below while loop is used to suppress empty history lines |
|
378 | #the below while loop is used to suppress empty history lines | |
378 | while((history == '' or history == '\n') \ |
|
379 | while((history == '' or history == '\n') \ | |
379 | and self._history_level <= self._get_history_max_index()): |
|
380 | and self._history_level <= self._get_history_max_index()): | |
380 | if self._history_level < self._get_history_max_index(): |
|
381 | if self._history_level < self._get_history_max_index(): | |
381 | self._history_level += 1 |
|
382 | self._history_level += 1 | |
382 | history = self._get_history() |
|
383 | history = self._get_history() | |
383 | else: |
|
384 | else: | |
384 | if self._history_level == self._get_history_max_index(): |
|
385 | if self._history_level == self._get_history_max_index(): | |
385 | history = self._get_history() |
|
386 | history = self._get_history() | |
386 | self._history_level += 1 |
|
387 | self._history_level += 1 | |
387 | else: |
|
388 | else: | |
388 | history = '' |
|
389 | history = '' | |
389 | return history |
|
390 | return history | |
390 |
|
391 | |||
391 | def init_history_index(self): |
|
392 | def init_history_index(self): | |
392 | ''' |
|
393 | ''' | |
393 | set history to last command entered |
|
394 | set history to last command entered | |
394 | ''' |
|
395 | ''' | |
395 | self._history_level = self._get_history_max_index()+1 |
|
396 | self._history_level = self._get_history_max_index()+1 | |
396 |
|
397 | |||
397 | #----------------------- IPython PRIVATE management section -------------- |
|
398 | #----------------------- IPython PRIVATE management section -------------- | |
398 | def _after_execute(self): |
|
399 | def _after_execute(self): | |
399 | ''' |
|
400 | ''' | |
400 | Can be redefined to generate post event after excution is done |
|
401 | Can be redefined to generate post event after excution is done | |
401 | ''' |
|
402 | ''' | |
402 | pass |
|
403 | pass | |
403 |
|
404 | |||
404 | def _ask_exit(self): |
|
405 | def _ask_exit(self): | |
405 | ''' |
|
406 | ''' | |
406 | Can be redefined to generate post event to exit the Ipython shell |
|
407 | Can be redefined to generate post event to exit the Ipython shell | |
407 | ''' |
|
408 | ''' | |
408 | pass |
|
409 | pass | |
409 |
|
410 | |||
410 | def _get_history_max_index(self): |
|
411 | def _get_history_max_index(self): | |
411 | ''' |
|
412 | ''' | |
412 | returns the max length of the history buffer |
|
413 | returns the max length of the history buffer | |
413 |
|
414 | |||
414 | @return: history length |
|
415 | @return: history length | |
415 | @rtype: int |
|
416 | @rtype: int | |
416 | ''' |
|
417 | ''' | |
417 | return len(self._IP.input_hist_raw)-1 |
|
418 | return len(self._IP.input_hist_raw)-1 | |
418 |
|
419 | |||
419 | def _get_history(self): |
|
420 | def _get_history(self): | |
420 | ''' |
|
421 | ''' | |
421 | Get's the command string of the current history level. |
|
422 | Get's the command string of the current history level. | |
422 |
|
423 | |||
423 | @return: Historic command stri |
|
424 | @return: Historic command stri | |
424 | @rtype: string |
|
425 | @rtype: string | |
425 | ''' |
|
426 | ''' | |
426 | rv = self._IP.input_hist_raw[self._history_level].strip('\n') |
|
427 | rv = self._IP.input_hist_raw[self._history_level].strip('\n') | |
427 | return rv |
|
428 | return rv | |
428 |
|
429 | |||
429 | def _pager_help(self, text): |
|
430 | def _pager_help(self, text): | |
430 | ''' |
|
431 | ''' | |
431 | This function is used as a callback replacment to IPython help pager function |
|
432 | This function is used as a callback replacment to IPython help pager function | |
432 |
|
433 | |||
433 | It puts the 'text' value inside the self._help_text string that can be retrived via |
|
434 | It puts the 'text' value inside the self._help_text string that can be retrived via | |
434 | get_help_text function. |
|
435 | get_help_text function. | |
435 | ''' |
|
436 | ''' | |
436 | if self._help_text == None: |
|
437 | if self._help_text == None: | |
437 | self._help_text = text |
|
438 | self._help_text = text | |
438 | else: |
|
439 | else: | |
439 | self._help_text += text |
|
440 | self._help_text += text | |
440 |
|
441 | |||
441 | def _pager(self, IP, text): |
|
442 | def _pager(self, IP, text): | |
442 | ''' |
|
443 | ''' | |
443 | This function is used as a callback replacment to IPython pager function |
|
444 | This function is used as a callback replacment to IPython pager function | |
444 |
|
445 | |||
445 | It puts the 'text' value inside the self._doc_text string that can be retrived via |
|
446 | It puts the 'text' value inside the self._doc_text string that can be retrived via | |
446 | get_doc_text function. |
|
447 | get_doc_text function. | |
447 | ''' |
|
448 | ''' | |
448 | self._doc_text = text |
|
449 | self._doc_text = text | |
449 |
|
450 | |||
450 | def _raw_input_original(self, prompt=''): |
|
451 | def _raw_input_original(self, prompt=''): | |
451 | ''' |
|
452 | ''' | |
452 | Custom raw_input() replacement. Get's current line from console buffer. |
|
453 | Custom raw_input() replacement. Get's current line from console buffer. | |
453 |
|
454 | |||
454 | @param prompt: Prompt to print. Here for compatability as replacement. |
|
455 | @param prompt: Prompt to print. Here for compatability as replacement. | |
455 | @type prompt: string |
|
456 | @type prompt: string | |
456 |
|
457 | |||
457 | @return: The current command line text. |
|
458 | @return: The current command line text. | |
458 | @rtype: string |
|
459 | @rtype: string | |
459 | ''' |
|
460 | ''' | |
460 | return self._line_to_execute |
|
461 | return self._line_to_execute | |
461 |
|
462 | |||
462 | def _raw_input(self, prompt=''): |
|
463 | def _raw_input(self, prompt=''): | |
463 | """ A replacement from python's raw_input. |
|
464 | """ A replacement from python's raw_input. | |
464 | """ |
|
465 | """ | |
465 | raise NotImplementedError |
|
466 | raise NotImplementedError | |
466 |
|
467 | |||
467 | def _execute(self): |
|
468 | def _execute(self): | |
468 | ''' |
|
469 | ''' | |
469 | Executes the current line provided by the shell object. |
|
470 | Executes the current line provided by the shell object. | |
470 | ''' |
|
471 | ''' | |
471 |
|
472 | |||
472 | orig_stdout = sys.stdout |
|
473 | orig_stdout = sys.stdout | |
473 |
sys.stdout = |
|
474 | sys.stdout = genutils.Term.cout | |
474 | #self.sys_displayhook_ori = sys.displayhook |
|
475 | #self.sys_displayhook_ori = sys.displayhook | |
475 | #sys.displayhook = self.displayhook |
|
476 | #sys.displayhook = self.displayhook | |
476 |
|
477 | |||
477 | try: |
|
478 | try: | |
478 | line = self._IP.raw_input(None, self._iter_more) |
|
479 | line = self._IP.raw_input(None, self._iter_more) | |
479 | if self._IP.autoindent: |
|
480 | if self._IP.autoindent: | |
480 | self._IP.readline_startup_hook(None) |
|
481 | self._IP.readline_startup_hook(None) | |
481 |
|
482 | |||
482 | except KeyboardInterrupt: |
|
483 | except KeyboardInterrupt: | |
483 | self._IP.write('\nKeyboardInterrupt\n') |
|
484 | self._IP.write('\nKeyboardInterrupt\n') | |
484 | self._IP.resetbuffer() |
|
485 | self._IP.resetbuffer() | |
485 | # keep cache in sync with the prompt counter: |
|
486 | # keep cache in sync with the prompt counter: | |
486 | self._IP.outputcache.prompt_count -= 1 |
|
487 | self._IP.outputcache.prompt_count -= 1 | |
487 |
|
488 | |||
488 | if self._IP.autoindent: |
|
489 | if self._IP.autoindent: | |
489 | self._IP.indent_current_nsp = 0 |
|
490 | self._IP.indent_current_nsp = 0 | |
490 | self._iter_more = 0 |
|
491 | self._iter_more = 0 | |
491 | except: |
|
492 | except: | |
492 | self._IP.showtraceback() |
|
493 | self._IP.showtraceback() | |
493 | else: |
|
494 | else: | |
494 | self._IP.write(str(self._IP.outputcache.prompt_out).strip()) |
|
495 | self._IP.write(str(self._IP.outputcache.prompt_out).strip()) | |
495 | self._iter_more = self._IP.push_line(line) |
|
496 | self._iter_more = self._IP.push_line(line) | |
496 | if (self._IP.SyntaxTB.last_syntax_error and \ |
|
497 | if (self._IP.SyntaxTB.last_syntax_error and \ | |
497 | self._IP.autoedit_syntax): |
|
498 | self._IP.autoedit_syntax): | |
498 | self._IP.edit_syntax_error() |
|
499 | self._IP.edit_syntax_error() | |
499 | if self._iter_more: |
|
500 | if self._iter_more: | |
500 | self._prompt = str(self._IP.outputcache.prompt2).strip() |
|
501 | self._prompt = str(self._IP.outputcache.prompt2).strip() | |
501 | if self._IP.autoindent: |
|
502 | if self._IP.autoindent: | |
502 | self._IP.readline_startup_hook(self._IP.pre_readline) |
|
503 | self._IP.readline_startup_hook(self._IP.pre_readline) | |
503 | else: |
|
504 | else: | |
504 | self._prompt = str(self._IP.outputcache.prompt1).strip() |
|
505 | self._prompt = str(self._IP.outputcache.prompt1).strip() | |
505 | self._IP.indent_current_nsp = 0 #we set indentation to 0 |
|
506 | self._IP.indent_current_nsp = 0 #we set indentation to 0 | |
506 |
|
507 | |||
507 | sys.stdout = orig_stdout |
|
508 | sys.stdout = orig_stdout | |
508 | #sys.displayhook = self.sys_displayhook_ori |
|
509 | #sys.displayhook = self.sys_displayhook_ori | |
509 |
|
510 | |||
510 | def _shell(self, ip, cmd): |
|
511 | def _shell(self, ip, cmd): | |
511 | ''' |
|
512 | ''' | |
512 | Replacement method to allow shell commands without them blocking. |
|
513 | Replacement method to allow shell commands without them blocking. | |
513 |
|
514 | |||
514 | @param ip: Ipython instance, same as self._IP |
|
515 | @param ip: Ipython instance, same as self._IP | |
515 | @type cmd: Ipython instance |
|
516 | @type cmd: Ipython instance | |
516 | @param cmd: Shell command to execute. |
|
517 | @param cmd: Shell command to execute. | |
517 | @type cmd: string |
|
518 | @type cmd: string | |
518 | ''' |
|
519 | ''' | |
519 | stdin, stdout = os.popen4(cmd) |
|
520 | stdin, stdout = os.popen4(cmd) | |
520 | result = stdout.read().decode('cp437').\ |
|
521 | result = stdout.read().decode('cp437').\ | |
521 | encode(locale.getpreferredencoding()) |
|
522 | encode(locale.getpreferredencoding()) | |
522 | #we use print command because the shell command is called |
|
523 | #we use print command because the shell command is called | |
523 | #inside IPython instance and thus is redirected to thread cout |
|
524 | #inside IPython instance and thus is redirected to thread cout | |
524 | #"\x01\x1b[1;36m\x02" <-- add colour to the text... |
|
525 | #"\x01\x1b[1;36m\x02" <-- add colour to the text... | |
525 | print "\x01\x1b[1;36m\x02"+result |
|
526 | print "\x01\x1b[1;36m\x02"+result | |
526 | stdout.close() |
|
527 | stdout.close() | |
527 | stdin.close() |
|
528 | stdin.close() |
General Comments 0
You need to be logged in to leave comments.
Login now