##// END OF EJS Templates
merge remote
Fernando Perez -
r1226:c5dce4c7 merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,183 +1,184 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 %store magic for lightweight persistence.
4 4
5 5 Stores variables, aliases etc. in PickleShare database.
6 6
7 7 $Id: iplib.py 1107 2006-01-30 19:02:20Z vivainio $
8 8 """
9 9
10 10 import IPython.ipapi
11 from IPython.ipapi import UsageError
11 12 ip = IPython.ipapi.get()
12 13
13 14 import pickleshare
14 15
15 16 import inspect,pickle,os,sys,textwrap
16 17 from IPython.FakeModule import FakeModule
17 18
18 19 def restore_aliases(self):
19 20 ip = self.getapi()
20 21 staliases = ip.db.get('stored_aliases', {})
21 22 for k,v in staliases.items():
22 23 #print "restore alias",k,v # dbg
23 24 #self.alias_table[k] = v
24 25 ip.defalias(k,v)
25 26
26 27
27 28 def refresh_variables(ip):
28 29 db = ip.db
29 30 for key in db.keys('autorestore/*'):
30 31 # strip autorestore
31 32 justkey = os.path.basename(key)
32 33 try:
33 34 obj = db[key]
34 35 except KeyError:
35 36 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
36 37 print "The error was:",sys.exc_info()[0]
37 38 else:
38 39 #print "restored",justkey,"=",obj #dbg
39 40 ip.user_ns[justkey] = obj
40 41
41 42
42 43 def restore_dhist(ip):
43 44 db = ip.db
44 45 ip.user_ns['_dh'] = db.get('dhist',[])
45 46
46 47 def restore_data(self):
47 48 ip = self.getapi()
48 49 refresh_variables(ip)
49 50 restore_aliases(self)
50 51 restore_dhist(self)
51 52 raise IPython.ipapi.TryNext
52 53
53 54 ip.set_hook('late_startup_hook', restore_data)
54 55
55 56 def magic_store(self, parameter_s=''):
56 57 """Lightweight persistence for python variables.
57 58
58 59 Example:
59 60
60 61 ville@badger[~]|1> A = ['hello',10,'world']\\
61 62 ville@badger[~]|2> %store A\\
62 63 ville@badger[~]|3> Exit
63 64
64 65 (IPython session is closed and started again...)
65 66
66 67 ville@badger:~$ ipython -p pysh\\
67 68 ville@badger[~]|1> print A
68 69
69 70 ['hello', 10, 'world']
70 71
71 72 Usage:
72 73
73 74 %store - Show list of all variables and their current values\\
74 75 %store <var> - Store the *current* value of the variable to disk\\
75 76 %store -d <var> - Remove the variable and its value from storage\\
76 77 %store -z - Remove all variables from storage\\
77 78 %store -r - Refresh all variables from store (delete current vals)\\
78 79 %store foo >a.txt - Store value of foo to new file a.txt\\
79 80 %store foo >>a.txt - Append value of foo to file a.txt\\
80 81
81 82 It should be noted that if you change the value of a variable, you
82 83 need to %store it again if you want to persist the new value.
83 84
84 85 Note also that the variables will need to be pickleable; most basic
85 86 python types can be safely %stored.
86 87
87 88 Also aliases can be %store'd across sessions.
88 89 """
89 90
90 91 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
91 92 args = argsl.split(None,1)
92 93 ip = self.getapi()
93 94 db = ip.db
94 95 # delete
95 96 if opts.has_key('d'):
96 97 try:
97 98 todel = args[0]
98 99 except IndexError:
99 error('You must provide the variable to forget')
100 raise UsageError('You must provide the variable to forget')
100 101 else:
101 102 try:
102 103 del db['autorestore/' + todel]
103 104 except:
104 error("Can't delete variable '%s'" % todel)
105 raise UsageError("Can't delete variable '%s'" % todel)
105 106 # reset
106 107 elif opts.has_key('z'):
107 108 for k in db.keys('autorestore/*'):
108 109 del db[k]
109 110
110 111 elif opts.has_key('r'):
111 112 refresh_variables(ip)
112 113
113 114
114 115 # run without arguments -> list variables & values
115 116 elif not args:
116 117 vars = self.db.keys('autorestore/*')
117 118 vars.sort()
118 119 if vars:
119 120 size = max(map(len,vars))
120 121 else:
121 122 size = 0
122 123
123 124 print 'Stored variables and their in-db values:'
124 125 fmt = '%-'+str(size)+'s -> %s'
125 126 get = db.get
126 127 for var in vars:
127 128 justkey = os.path.basename(var)
128 129 # print 30 first characters from every var
129 130 print fmt % (justkey,repr(get(var,'<unavailable>'))[:50])
130 131
131 132 # default action - store the variable
132 133 else:
133 134 # %store foo >file.txt or >>file.txt
134 135 if len(args) > 1 and args[1].startswith('>'):
135 136 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
136 137 if args[1].startswith('>>'):
137 138 fil = open(fnam,'a')
138 139 else:
139 140 fil = open(fnam,'w')
140 141 obj = ip.ev(args[0])
141 142 print "Writing '%s' (%s) to file '%s'." % (args[0],
142 143 obj.__class__.__name__, fnam)
143 144
144 145
145 146 if not isinstance (obj,basestring):
146 147 from pprint import pprint
147 148 pprint(obj,fil)
148 149 else:
149 150 fil.write(obj)
150 151 if not obj.endswith('\n'):
151 152 fil.write('\n')
152 153
153 154 fil.close()
154 155 return
155 156
156 157 # %store foo
157 158 try:
158 159 obj = ip.user_ns[args[0]]
159 160 except KeyError:
160 161 # it might be an alias
161 162 if args[0] in self.alias_table:
162 163 staliases = db.get('stored_aliases',{})
163 164 staliases[ args[0] ] = self.alias_table[ args[0] ]
164 165 db['stored_aliases'] = staliases
165 166 print "Alias stored:", args[0], self.alias_table[ args[0] ]
166 167 return
167 168 else:
168 print "Error: unknown variable '%s'" % args[0]
169 raise UsageError("Unknown variable '%s'" % args[0])
169 170
170 171 else:
171 172 if isinstance(inspect.getmodule(obj), FakeModule):
172 173 print textwrap.dedent("""\
173 174 Warning:%s is %s
174 175 Proper storage of interactively declared classes (or instances
175 176 of those classes) is not possible! Only instances
176 177 of classes in real modules on file system can be %%store'd.
177 178 """ % (args[0], obj) )
178 179 return
179 180 #pickled = pickle.dumps(obj)
180 181 self.db[ 'autorestore/' + args[0] ] = obj
181 182 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
182 183
183 184 ip.expose_magic('store',magic_store)
@@ -1,460 +1,465 b''
1 1 #!/usr/bin/python
2 2 # -*- coding: iso-8859-15 -*-
3 3 '''
4 4 Provides IPython remote instance.
5 5
6 6 @author: Laurent Dufrechou
7 7 laurent.dufrechou _at_ gmail.com
8 8 @license: BSD
9 9
10 10 All rights reserved. This program and the accompanying materials are made
11 11 available under the terms of the BSD which accompanies this distribution, and
12 12 is available at U{http://www.opensource.org/licenses/bsd-license.php}
13 13 '''
14 14
15 15 __version__ = 0.9
16 16 __author__ = "Laurent Dufrechou"
17 17 __email__ = "laurent.dufrechou _at_ gmail.com"
18 18 __license__ = "BSD"
19 19
20 20 import re
21 21 import sys
22 22 import os
23 23 import locale
24 import time
25 import pydoc,__builtin__,site
26 24 from thread_ex import ThreadEx
27 from StringIO import StringIO
28 25
29 26 try:
30 import IPython
27 import IPython
31 28 except Exception,e:
32 raise "Error importing IPython (%s)" % str(e)
29 print "Error importing IPython (%s)" % str(e)
30 raise Exception, e
33 31
34 32 ##############################################################################
35 33 class _Helper(object):
36 34 """Redefine the built-in 'help'.
37 35 This is a wrapper around pydoc.help (with a twist).
38 36 """
39 37
40 def __init__(self,pager):
38 def __init__(self, pager):
41 39 self._pager = pager
42 40
43 41 def __repr__(self):
44 42 return "Type help() for interactive help, " \
45 43 "or help(object) for help about object."
46 44
47 45 def __call__(self, *args, **kwds):
48 46 class DummyWriter(object):
49 def __init__(self,pager):
47 '''Dumy class to handle help output'''
48 def __init__(self, pager):
50 49 self._pager = pager
51 50
52 def write(self,data):
51 def write(self, data):
52 '''hook to fill self._pager'''
53 53 self._pager(data)
54 54
55 55 import pydoc
56 56 pydoc.help.output = DummyWriter(self._pager)
57 57 pydoc.help.interact = lambda :1
58 58
59 59 return pydoc.help(*args, **kwds)
60 60
61 61
62 62 ##############################################################################
63 63 class _CodeExecutor(ThreadEx):
64
64 ''' Thread that execute ipython code '''
65 65 def __init__(self, instance, after):
66 66 ThreadEx.__init__(self)
67 67 self.instance = instance
68 self._afterExecute=after
68 self._afterExecute = after
69 69
70 70 def run(self):
71 '''Thread main loop'''
71 72 try:
72 73 self.instance._doc_text = None
73 74 self.instance._help_text = None
74 75 self.instance._execute()
75 76 # used for uper class to generate event after execution
76 77 self._afterExecute()
77 78
78 79 except KeyboardInterrupt:
79 80 pass
80 81
81 82
82 83 ##############################################################################
83 84 class NonBlockingIPShell(object):
84 85 '''
85 86 Create an IPython instance, running the commands in a separate,
86 87 non-blocking thread.
87 88 This allows embedding in any GUI without blockage.
88 89
89 90 Note: The ThreadEx class supports asynchroneous function call
90 91 via raise_exc()
91 92 '''
92 93
93 def __init__(self,argv=[],user_ns={},user_global_ns=None,
94 def __init__(self, argv=[], user_ns={}, user_global_ns=None,
94 95 cin=None, cout=None, cerr=None,
95 96 ask_exit_handler=None):
96 97 '''
97 98 @param argv: Command line options for IPython
98 99 @type argv: list
99 100 @param user_ns: User namespace.
100 101 @type user_ns: dictionary
101 102 @param user_global_ns: User global namespace.
102 103 @type user_global_ns: dictionary.
103 104 @param cin: Console standard input.
104 105 @type cin: IO stream
105 106 @param cout: Console standard output.
106 107 @type cout: IO stream
107 108 @param cerr: Console standard error.
108 109 @type cerr: IO stream
109 110 @param exit_handler: Replacement for builtin exit() function
110 111 @type exit_handler: function
111 112 @param time_loop: Define the sleep time between two thread's loop
112 113 @type int
113 114 '''
114 115 #ipython0 initialisation
116 self._IP = None
117 self._term = None
115 118 self.initIpython0(argv, user_ns, user_global_ns,
116 119 cin, cout, cerr,
117 120 ask_exit_handler)
118 121
119 122 #vars used by _execute
120 123 self._iter_more = 0
121 124 self._history_level = 0
122 125 self._complete_sep = re.compile('[\s\{\}\[\]\(\)\=]')
123 126 self._prompt = str(self._IP.outputcache.prompt1).strip()
124 127
125 128 #thread working vars
126 129 self._line_to_execute = ''
127 130
128 131 #vars that will be checked by GUI loop to handle thread states...
129 132 #will be replaced later by PostEvent GUI funtions...
130 133 self._doc_text = None
131 134 self._help_text = None
132 135 self._add_button = None
133 136
134 137 def initIpython0(self, argv=[], user_ns={}, user_global_ns=None,
135 138 cin=None, cout=None, cerr=None,
136 139 ask_exit_handler=None):
140 ''' Initialize an ithon0 instance '''
141
137 142 #first we redefine in/out/error functions of IPython
138 143 if cin:
139 144 IPython.Shell.Term.cin = cin
140 145 if cout:
141 146 IPython.Shell.Term.cout = cout
142 147 if cerr:
143 148 IPython.Shell.Term.cerr = cerr
144 149
145 150 # This is to get rid of the blockage that accurs during
146 151 # IPython.Shell.InteractiveShell.user_setup()
147 152 IPython.iplib.raw_input = lambda x: None
148 153
149 154 self._term = IPython.genutils.IOTerm(cin=cin, cout=cout, cerr=cerr)
150 155
151 156 excepthook = sys.excepthook
152 157
153 158 self._IP = IPython.Shell.make_IPython(
154 argv,user_ns=user_ns,
155 user_global_ns=user_global_ns,
156 embedded=True,
157 shell_class=IPython.Shell.InteractiveShell)
159 argv,user_ns=user_ns,
160 user_global_ns=user_global_ns,
161 embedded=True,
162 shell_class=IPython.Shell.InteractiveShell)
158 163
159 164 #we replace IPython default encoding by wx locale encoding
160 165 loc = locale.getpreferredencoding()
161 166 if loc:
162 self._IP.stdin_encoding = loc
167 self._IP.stdin_encoding = loc
163 168 #we replace the ipython default pager by our pager
164 self._IP.set_hook('show_in_pager',self._pager)
169 self._IP.set_hook('show_in_pager', self._pager)
165 170
166 171 #we replace the ipython default shell command caller by our shell handler
167 self._IP.set_hook('shell_hook',self._shell)
172 self._IP.set_hook('shell_hook', self._shell)
168 173
169 174 #we replace the ipython default input command caller by our method
170 175 IPython.iplib.raw_input_original = self._raw_input
171 176 #we replace the ipython default exit command by our method
172 177 self._IP.exit = ask_exit_handler
173 178 #we replace the help command
174 179 self._IP.user_ns['help'] = _Helper(self._pager_help)
175 180
176 181 #we disable cpase magic... until we found a way to use it properly.
177 182 #import IPython.ipapi
178 183 ip = IPython.ipapi.get()
179 184 def bypassMagic(self, arg):
180 185 print '%this magic is currently disabled.'
181 186 ip.expose_magic('cpaste', bypassMagic)
182 187
183 188 sys.excepthook = excepthook
184 189
185 190 #----------------------- Thread management section ----------------------
186 def doExecute(self,line):
191 def doExecute(self, line):
187 192 """
188 193 Tell the thread to process the 'line' command
189 194 """
190 195
191 196 self._line_to_execute = line
192 197 #we launch the ipython line execution in a thread to make it interruptible
193 self.ce = _CodeExecutor(self,self._afterExecute)
194 self.ce.start()
198 ce = _CodeExecutor(self, self._afterExecute)
199 ce.start()
195 200
196 201 #----------------------- IPython management section ----------------------
197 202 def getDocText(self):
198 203 """
199 204 Returns the output of the processing that need to be paged (if any)
200 205
201 206 @return: The std output string.
202 207 @rtype: string
203 208 """
204 209 return self._doc_text
205 210
206 211 def getHelpText(self):
207 212 """
208 213 Returns the output of the processing that need to be paged via help pager(if any)
209 214
210 215 @return: The std output string.
211 216 @rtype: string
212 217 """
213 218 return self._help_text
214 219
215 220 def getBanner(self):
216 221 """
217 222 Returns the IPython banner for useful info on IPython instance
218 223
219 224 @return: The banner string.
220 225 @rtype: string
221 226 """
222 227 return self._IP.BANNER
223 228
224 229 def getPromptCount(self):
225 230 """
226 231 Returns the prompt number.
227 232 Each time a user execute a line in the IPython shell the prompt count is increased
228 233
229 234 @return: The prompt number
230 235 @rtype: int
231 236 """
232 237 return self._IP.outputcache.prompt_count
233 238
234 239 def getPrompt(self):
235 240 """
236 241 Returns current prompt inside IPython instance
237 242 (Can be In [...]: ot ...:)
238 243
239 244 @return: The current prompt.
240 245 @rtype: string
241 246 """
242 247 return self._prompt
243 248
244 249 def getIndentation(self):
245 250 """
246 251 Returns the current indentation level
247 252 Usefull to put the caret at the good start position if we want to do autoindentation.
248 253
249 254 @return: The indentation level.
250 255 @rtype: int
251 256 """
252 257 return self._IP.indent_current_nsp
253 258
254 259 def updateNamespace(self, ns_dict):
255 260 '''
256 261 Add the current dictionary to the shell namespace.
257 262
258 263 @param ns_dict: A dictionary of symbol-values.
259 264 @type ns_dict: dictionary
260 265 '''
261 266 self._IP.user_ns.update(ns_dict)
262 267
263 268 def complete(self, line):
264 269 '''
265 270 Returns an auto completed line and/or posibilities for completion.
266 271
267 272 @param line: Given line so far.
268 273 @type line: string
269 274
270 275 @return: Line completed as for as possible,
271 276 and possible further completions.
272 277 @rtype: tuple
273 278 '''
274 279 split_line = self._complete_sep.split(line)
275 280 possibilities = self._IP.complete(split_line[-1])
276 281 if possibilities:
277 282
278 283 def _commonPrefix(str1, str2):
279 284 '''
280 285 Reduction function. returns common prefix of two given strings.
281 286
282 287 @param str1: First string.
283 288 @type str1: string
284 289 @param str2: Second string
285 290 @type str2: string
286 291
287 292 @return: Common prefix to both strings.
288 293 @rtype: string
289 294 '''
290 295 for i in range(len(str1)):
291 296 if not str2.startswith(str1[:i+1]):
292 297 return str1[:i]
293 298 return str1
294 299 common_prefix = reduce(_commonPrefix, possibilities)
295 300 completed = line[:-len(split_line[-1])]+common_prefix
296 301 else:
297 302 completed = line
298 303 return completed, possibilities
299 304
300 305 def historyBack(self):
301 306 '''
302 307 Provides one history command back.
303 308
304 309 @return: The command string.
305 310 @rtype: string
306 311 '''
307 312 history = ''
308 313 #the below while loop is used to suppress empty history lines
309 314 while((history == '' or history == '\n') and self._history_level >0):
310 if self._history_level>=1:
311 self._history_level -= 1
312 history = self._getHistory()
315 if self._history_level >= 1:
316 self._history_level -= 1
317 history = self._getHistory()
313 318 return history
314 319
315 320 def historyForward(self):
316 321 '''
317 322 Provides one history command forward.
318 323
319 324 @return: The command string.
320 325 @rtype: string
321 326 '''
322 327 history = ''
323 328 #the below while loop is used to suppress empty history lines
324 while((history == '' or history == '\n') and self._history_level <= self._getHistoryMaxIndex()):
325 if self._history_level < self._getHistoryMaxIndex():
326 self._history_level += 1
327 history = self._getHistory()
329 while((history == '' or history == '\n') \
330 and self._history_level <= self._getHistoryMaxIndex()):
331 if self._history_level < self._getHistoryMaxIndex():
332 self._history_level += 1
333 history = self._getHistory()
334 else:
335 if self._history_level == self._getHistoryMaxIndex():
336 history = self._getHistory()
337 self._history_level += 1
328 338 else:
329 if self._history_level == self._getHistoryMaxIndex():
330 history = self._getHistory()
331 self._history_level += 1
332 else:
333 history = ''
339 history = ''
334 340 return history
335 341
336 342 def initHistoryIndex(self):
337 343 '''
338 344 set history to last command entered
339 345 '''
340 346 self._history_level = self._getHistoryMaxIndex()+1
341 347
342 348 #----------------------- IPython PRIVATE management section --------------
343 349 def _afterExecute(self):
344 350 '''
345 351 Can be redefined to generate post event after excution is done
346 352 '''
347 353 pass
348 354
349 355 #def _askExit(self):
350 356 # '''
351 357 # Can be redefined to generate post event to exit the Ipython shell
352 358 # '''
353 359 # pass
354 360
355 361 def _getHistoryMaxIndex(self):
356 362 '''
357 363 returns the max length of the history buffer
358 364
359 365 @return: history length
360 366 @rtype: int
361 367 '''
362 368 return len(self._IP.input_hist_raw)-1
363 369
364 370 def _getHistory(self):
365 371 '''
366 372 Get's the command string of the current history level.
367 373
368 374 @return: Historic command stri
369 375 @rtype: string
370 376 '''
371 377 rv = self._IP.input_hist_raw[self._history_level].strip('\n')
372 378 return rv
373 379
374 def _pager_help(self,text):
380 def _pager_help(self, text):
375 381 '''
376 382 This function is used as a callback replacment to IPython help pager function
377 383
378 It puts the 'text' value inside the self._help_text string that can be retrived via getHelpText
379 function.
384 It puts the 'text' value inside the self._help_text string that can be retrived via
385 getHelpText function.
380 386 '''
381 387 if self._help_text == None:
382 388 self._help_text = text
383 389 else:
384 390 self._help_text += text
385 391
386 def _pager(self,IP,text):
392 def _pager(self, IP, text):
387 393 '''
388 394 This function is used as a callback replacment to IPython pager function
389 395
390 It puts the 'text' value inside the self._doc_text string that can be retrived via getDocText
391 function.
396 It puts the 'text' value inside the self._doc_text string that can be retrived via
397 getDocText function.
392 398 '''
393 399 self._doc_text = text
394 400
395 401 def _raw_input(self, prompt=''):
396 402 '''
397 403 Custom raw_input() replacement. Get's current line from console buffer.
398 404
399 405 @param prompt: Prompt to print. Here for compatability as replacement.
400 406 @type prompt: string
401 407
402 408 @return: The current command line text.
403 409 @rtype: string
404 410 '''
405 411 return self._line_to_execute
406 412
407 413 def _execute(self):
408 414 '''
409 415 Executes the current line provided by the shell object.
410 416 '''
411 417 orig_stdout = sys.stdout
412 418 sys.stdout = IPython.Shell.Term.cout
413 419
414 420 try:
415 421 line = self._IP.raw_input(None, self._iter_more)
416 422 if self._IP.autoindent:
417 423 self._IP.readline_startup_hook(None)
418 424
419 425 except KeyboardInterrupt:
420 426 self._IP.write('\nKeyboardInterrupt\n')
421 427 self._IP.resetbuffer()
422 428 # keep cache in sync with the prompt counter:
423 429 self._IP.outputcache.prompt_count -= 1
424 430
425 431 if self._IP.autoindent:
426 432 self._IP.indent_current_nsp = 0
427 433 self._iter_more = 0
428 434 except:
429 435 self._IP.showtraceback()
430 436 else:
431 437 self._iter_more = self._IP.push(line)
432 if (self._IP.SyntaxTB.last_syntax_error and
433 self._IP.rc.autoedit_syntax):
438 if (self._IP.SyntaxTB.last_syntax_error and self._IP.rc.autoedit_syntax):
434 439 self._IP.edit_syntax_error()
435 440 if self._iter_more:
436 441 self._prompt = str(self._IP.outputcache.prompt2).strip()
437 442 if self._IP.autoindent:
438 443 self._IP.readline_startup_hook(self._IP.pre_readline)
439 444 else:
440 445 self._prompt = str(self._IP.outputcache.prompt1).strip()
441 446 self._IP.indent_current_nsp = 0 #we set indentation to 0
442 447 sys.stdout = orig_stdout
443 448
444 449 def _shell(self, ip, cmd):
445 450 '''
446 451 Replacement method to allow shell commands without them blocking.
447 452
448 453 @param ip: Ipython instance, same as self._IP
449 454 @type cmd: Ipython instance
450 455 @param cmd: Shell command to execute.
451 456 @type cmd: string
452 457 '''
453 458 stdin, stdout = os.popen4(cmd)
454 459 result = stdout.read().decode('cp437').encode(locale.getpreferredencoding())
455 #we use print command because the shell command is called inside IPython instance and thus is
456 #redirected to thread cout
460 #we use print command because the shell command is called
461 #inside IPython instance and thus is redirected to thread cout
457 462 #"\x01\x1b[1;36m\x02" <-- add colour to the text...
458 463 print "\x01\x1b[1;36m\x02"+result
459 464 stdout.close()
460 465 stdin.close()
@@ -1,877 +1,870 b''
1 1 #!/usr/bin/python
2 2 # -*- coding: iso-8859-15 -*-
3 3 '''
4 4 Provides IPython WX console widgets.
5 5
6 6 @author: Laurent Dufrechou
7 7 laurent.dufrechou _at_ gmail.com
8 8 This WX widget is based on the original work of Eitan Isaacson
9 9 that provided the console for the GTK toolkit.
10 10
11 11 Original work from:
12 12 @author: Eitan Isaacson
13 13 @organization: IBM Corporation
14 14 @copyright: Copyright (c) 2007 IBM Corporation
15 15 @license: BSD
16 16
17 17 All rights reserved. This program and the accompanying materials are made
18 18 available under the terms of the BSD which accompanies this distribution, and
19 19 is available at U{http://www.opensource.org/licenses/bsd-license.php}
20 20 '''
21 21
22 22 __version__ = 0.8
23 23 __author__ = "Laurent Dufrechou"
24 24 __email__ = "laurent.dufrechou _at_ gmail.com"
25 25 __license__ = "BSD"
26 26
27 27 import wx
28 28 import wx.stc as stc
29 29
30 30 import re
31 import sys
32 import locale
33 31 from StringIO import StringIO
34 try:
35 import IPython
36 except Exception,e:
37 raise "Error importing IPython (%s)" % str(e)
38 32
39 33 from ipshell_nonblocking import NonBlockingIPShell
40 34
41 35 class WxNonBlockingIPShell(NonBlockingIPShell):
42 36 '''
43 37 An NonBlockingIPShell Thread that is WX dependent.
44 38 '''
45 39 def __init__(self, parent,
46 40 argv=[],user_ns={},user_global_ns=None,
47 41 cin=None, cout=None, cerr=None,
48 42 ask_exit_handler=None):
49 43
50 NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns,
44 NonBlockingIPShell.__init__(self, argv, user_ns, user_global_ns,
51 45 cin, cout, cerr,
52 46 ask_exit_handler)
53 47
54 48 self.parent = parent
55 49
56 50 self.ask_exit_callback = ask_exit_handler
57 51 self._IP.exit = self._askExit
58 52
59 def addGUIShortcut(self,text,func):
53 def addGUIShortcut(self, text, func):
60 54 wx.CallAfter(self.parent.add_button_handler,
61 55 button_info={ 'text':text,
62 56 'func':self.parent.doExecuteLine(func)})
63 57
64 58 def _askExit(self):
65 59 wx.CallAfter(self.ask_exit_callback, ())
66 60
67 61 def _afterExecute(self):
68 62 wx.CallAfter(self.parent.evtStateExecuteDone, ())
69 63
70 64
71 65 class WxConsoleView(stc.StyledTextCtrl):
72 66 '''
73 67 Specialized styled text control view for console-like workflow.
74 68 We use here a scintilla frontend thus it can be reused in any GUI that
75 69 supports scintilla with less work.
76 70
77 71 @cvar ANSI_COLORS_BLACK: Mapping of terminal colors to X11 names.
78 72 (with Black background)
79 73 @type ANSI_COLORS_BLACK: dictionary
80 74
81 75 @cvar ANSI_COLORS_WHITE: Mapping of terminal colors to X11 names.
82 76 (with White background)
83 77 @type ANSI_COLORS_WHITE: dictionary
84 78
85 79 @ivar color_pat: Regex of terminal color pattern
86 80 @type color_pat: _sre.SRE_Pattern
87 81 '''
88 ANSI_STYLES_BLACK={'0;30': [0,'WHITE'], '0;31': [1,'RED'],
89 '0;32': [2,'GREEN'], '0;33': [3,'BROWN'],
90 '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'],
91 '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'],
92 '1;30': [8,'DARK GREY'], '1;31': [9,'RED'],
93 '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'],
94 '1;34': [12,'LIGHT BLUE'], '1;35':
95 [13,'MEDIUM VIOLET RED'],
96 '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']}
97
98 ANSI_STYLES_WHITE={'0;30': [0,'BLACK'], '0;31': [1,'RED'],
99 '0;32': [2,'GREEN'], '0;33': [3,'BROWN'],
100 '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'],
101 '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'],
102 '1;30': [8,'DARK GREY'], '1;31': [9,'RED'],
103 '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'],
104 '1;34': [12,'LIGHT BLUE'], '1;35':
105 [13,'MEDIUM VIOLET RED'],
106 '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']}
107
108 def __init__(self,parent,prompt,intro="",background_color="BLACK",
82 ANSI_STYLES_BLACK = {'0;30': [0, 'WHITE'], '0;31': [1, 'RED'],
83 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
84 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
85 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
86 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
87 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
88 '1;34': [12, 'LIGHT BLUE'], '1;35':
89 [13, 'MEDIUM VIOLET RED'],
90 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
91
92 ANSI_STYLES_WHITE = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
93 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
94 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
95 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
96 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
97 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
98 '1;34': [12, 'LIGHT BLUE'], '1;35':
99 [13, 'MEDIUM VIOLET RED'],
100 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
101
102 def __init__(self, parent, prompt, intro="", background_color="BLACK",
109 103 pos=wx.DefaultPosition, ID = -1, size=wx.DefaultSize,
110 104 style=0, autocomplete_mode = 'IPYTHON'):
111 105 '''
112 106 Initialize console view.
113 107
114 108 @param parent: Parent widget
115 109 @param prompt: User specified prompt
116 110 @type intro: string
117 111 @param intro: User specified startup introduction string
118 112 @type intro: string
119 113 @param background_color: Can be BLACK or WHITE
120 114 @type background_color: string
121 115 @param other: init param of styledTextControl (can be used as-is)
122 116 @param autocomplete_mode: Can be 'IPYTHON' or 'STC'
123 117 'IPYTHON' show autocompletion the ipython way
124 118 'STC" show it scintilla text control way
125 119 '''
126 120 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
127 121
128 122 ####### Scintilla configuration ###################################
129 123
130 124 # Ctrl + B or Ctrl + N can be used to zoomin/zoomout the text inside
131 125 # the widget
132 126 self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
133 127 self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
134 128
135 129 #We draw a line at position 80
136 130 self.SetEdgeMode(stc.STC_EDGE_LINE)
137 131 self.SetEdgeColumn(80)
138 132 self.SetEdgeColour(wx.LIGHT_GREY)
139 133
140 134 #self.SetViewWhiteSpace(True)
141 135 #self.SetViewEOL(True)
142 136 self.SetEOLMode(stc.STC_EOL_CRLF)
143 137 #self.SetWrapMode(stc.STC_WRAP_CHAR)
144 138 #self.SetWrapMode(stc.STC_WRAP_WORD)
145 139 self.SetBufferedDraw(True)
146 140 #self.SetUseAntiAliasing(True)
147 141 self.SetLayoutCache(stc.STC_CACHE_PAGE)
148 142 self.SetUndoCollection(False)
149 self.SetUseTabs(True)
150 self.SetIndent(4)
151 self.SetTabWidth(4)
143 self.SetUseTabs(True)
144 self.SetIndent(4)
145 self.SetTabWidth(4)
152 146
153 147 self.EnsureCaretVisible()
154 148
155 self.SetMargins(3,3) #text is moved away from border with 3px
149 self.SetMargins(3, 3) #text is moved away from border with 3px
156 150 # Suppressing Scintilla margins
157 self.SetMarginWidth(0,0)
158 self.SetMarginWidth(1,0)
159 self.SetMarginWidth(2,0)
151 self.SetMarginWidth(0, 0)
152 self.SetMarginWidth(1, 0)
153 self.SetMarginWidth(2, 0)
160 154
161 155 self.background_color = background_color
162 156 self.buildStyles()
163 157
164 158 self.indent = 0
165 159 self.prompt_count = 0
166 160 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
167 161
168 162 self.write(intro)
169 163 self.setPrompt(prompt)
170 164 self.showPrompt()
171 165
172 166 self.autocomplete_mode = autocomplete_mode
173 167
174 168 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress)
175 169
176 170 def buildStyles(self):
177 171 #we define platform specific fonts
178 172 if wx.Platform == '__WXMSW__':
179 faces = { 'times': 'Times New Roman',
180 'mono' : 'Courier New',
181 'helv' : 'Arial',
182 'other': 'Comic Sans MS',
183 'size' : 10,
184 'size2': 8,
185 }
173 faces = { 'times': 'Times New Roman',
174 'mono' : 'Courier New',
175 'helv' : 'Arial',
176 'other': 'Comic Sans MS',
177 'size' : 10,
178 'size2': 8,
179 }
186 180 elif wx.Platform == '__WXMAC__':
187 181 faces = { 'times': 'Times New Roman',
188 182 'mono' : 'Monaco',
189 183 'helv' : 'Arial',
190 184 'other': 'Comic Sans MS',
191 185 'size' : 10,
192 186 'size2': 8,
193 187 }
194 188 else:
195 189 faces = { 'times': 'Times',
196 190 'mono' : 'Courier',
197 191 'helv' : 'Helvetica',
198 192 'other': 'new century schoolbook',
199 193 'size' : 10,
200 194 'size2': 8,
201 195 }
202 196
203 197 # make some styles
204 198 if self.background_color != "BLACK":
205 199 self.background_color = "WHITE"
206 200 self.SetCaretForeground("BLACK")
207 201 self.ANSI_STYLES = self.ANSI_STYLES_WHITE
208 202 else:
209 203 self.SetCaretForeground("WHITE")
210 204 self.ANSI_STYLES = self.ANSI_STYLES_BLACK
211 205
212 206 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
213 207 "fore:%s,back:%s,size:%d,face:%s"
214 208 % (self.ANSI_STYLES['0;30'][1],
215 209 self.background_color,
216 210 faces['size'], faces['mono']))
217 211 self.StyleClearAll()
218 212 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
219 213 "fore:#FF0000,back:#0000FF,bold")
220 214 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
221 215 "fore:#000000,back:#FF0000,bold")
222 216
223 217 for style in self.ANSI_STYLES.values():
224 218 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
225 219
226 220 #######################################################################
227 221
228 def setBackgroundColor(self,color):
222 def setBackgroundColor(self, color):
229 223 self.background_color = color
230 224 self.buildStyles()
231 225
232 def getBackgroundColor(self,color):
226 def getBackgroundColor(self, color):
233 227 return self.background_color
234 228
235 229 def asyncWrite(self, text):
236 230 '''
237 231 Write given text to buffer in an asynchroneous way.
238 232 It is used from another thread to be able to acces the GUI.
239 233 @param text: Text to append
240 234 @type text: string
241 235 '''
242 236 try:
243 #print >>sys.__stdout__,'entering'
244 wx.MutexGuiEnter()
245 #print >>sys.__stdout__,'locking the GUI'
237 #print >>sys.__stdout__,'entering'
238 wx.MutexGuiEnter()
239 #print >>sys.__stdout__,'locking the GUI'
246 240
247 #be sure not to be interrutpted before the MutexGuiLeave!
248 self.write(text)
241 #be sure not to be interrutpted before the MutexGuiLeave!
242 self.write(text)
249 243
250 #print >>sys.__stdout__,'done'
244 #print >>sys.__stdout__,'done'
251 245
252 246 except KeyboardInterrupt:
253 #print >>sys.__stdout__,'got keyboard interrupt'
254 wx.MutexGuiLeave()
255 #print >>sys.__stdout__,'interrupt unlock the GUI'
256 raise KeyboardInterrupt
247 #print >>sys.__stdout__,'got keyboard interrupt'
248 wx.MutexGuiLeave()
249 #print >>sys.__stdout__,'interrupt unlock the GUI'
250 raise KeyboardInterrupt
257 251 wx.MutexGuiLeave()
258 252 #print >>sys.__stdout__,'normal unlock the GUI'
259 253
260 254
261 255 def write(self, text):
262 256 '''
263 257 Write given text to buffer.
264 258
265 259 @param text: Text to append.
266 260 @type text: string
267 261 '''
268 262 segments = self.color_pat.split(text)
269 263 segment = segments.pop(0)
270 self.StartStyling(self.getCurrentLineEnd(),0xFF)
264 self.StartStyling(self.getCurrentLineEnd(), 0xFF)
271 265 self.AppendText(segment)
272 266
273 267 if segments:
274 268 ansi_tags = self.color_pat.findall(text)
275 269
276 270 for tag in ansi_tags:
277 271 i = segments.index(tag)
278 self.StartStyling(self.getCurrentLineEnd(),0xFF)
272 self.StartStyling(self.getCurrentLineEnd(), 0xFF)
279 273 self.AppendText(segments[i+1])
280 274
281 275 if tag != '0':
282 self.SetStyling(len(segments[i+1]),self.ANSI_STYLES[tag][0])
276 self.SetStyling(len(segments[i+1]), self.ANSI_STYLES[tag][0])
283 277
284 278 segments.pop(i)
285 279
286 280 self.moveCursor(self.getCurrentLineEnd())
287 281
288 282 def getPromptLen(self):
289 283 '''
290 284 Return the length of current prompt
291 285 '''
292 286 return len(str(self.prompt_count)) + 7
293 287
294 def setPrompt(self,prompt):
288 def setPrompt(self, prompt):
295 289 self.prompt = prompt
296 290
297 def setIndentation(self,indentation):
291 def setIndentation(self, indentation):
298 292 self.indent = indentation
299 293
300 def setPromptCount(self,count):
294 def setPromptCount(self, count):
301 295 self.prompt_count = count
302 296
303 297 def showPrompt(self):
304 298 '''
305 299 Prints prompt at start of line.
306 300
307 301 @param prompt: Prompt to print.
308 302 @type prompt: string
309 303 '''
310 304 self.write(self.prompt)
311 305 #now we update the position of end of prompt
312 306 self.current_start = self.getCurrentLineEnd()
313 307
314 308 autoindent = self.indent*' '
315 309 autoindent = autoindent.replace(' ','\t')
316 310 self.write(autoindent)
317 311
318 312 def changeLine(self, text):
319 313 '''
320 314 Replace currently entered command line with given text.
321 315
322 316 @param text: Text to use as replacement.
323 317 @type text: string
324 318 '''
325 self.SetSelection(self.getCurrentPromptStart(),self.getCurrentLineEnd())
319 self.SetSelection(self.getCurrentPromptStart(), self.getCurrentLineEnd())
326 320 self.ReplaceSelection(text)
327 321 self.moveCursor(self.getCurrentLineEnd())
328 322
329 323 def getCurrentPromptStart(self):
330 324 return self.current_start
331 325
332 326 def getCurrentLineStart(self):
333 327 return self.GotoLine(self.LineFromPosition(self.GetCurrentPos()))
334 328
335 329 def getCurrentLineEnd(self):
336 330 return self.GetLength()
337 331
338 332 def getCurrentLine(self):
339 333 '''
340 334 Get text in current command line.
341 335
342 336 @return: Text of current command line.
343 337 @rtype: string
344 338 '''
345 339 return self.GetTextRange(self.getCurrentPromptStart(),
346 340 self.getCurrentLineEnd())
347 341
348 342 def moveCursorOnNewValidKey(self):
349 343 #If cursor is at wrong position put it at last line...
350 344 if self.GetCurrentPos() < self.getCurrentPromptStart():
351 345 self.GotoPos(self.getCurrentPromptStart())
352 346
353 def removeFromTo(self,from_pos,to_pos):
347 def removeFromTo(self, from_pos, to_pos):
354 348 if from_pos < to_pos:
355 self.SetSelection(from_pos,to_pos)
349 self.SetSelection(from_pos, to_pos)
356 350 self.DeleteBack()
357 351
358 352 def removeCurrentLine(self):
359 353 self.LineDelete()
360 354
361 def moveCursor(self,position):
355 def moveCursor(self, position):
362 356 self.GotoPos(position)
363 357
364 358 def getCursorPos(self):
365 359 return self.GetCurrentPos()
366 360
367 def selectFromTo(self,from_pos,to_pos):
361 def selectFromTo(self, from_pos, to_pos):
368 362 self.SetSelectionStart(from_pos)
369 363 self.SetSelectionEnd(to_pos)
370 364
371 def writeHistory(self,history):
372 self.removeFromTo(self.getCurrentPromptStart(),self.getCurrentLineEnd())
365 def writeHistory(self, history):
366 self.removeFromTo(self.getCurrentPromptStart(), self.getCurrentLineEnd())
373 367 self.changeLine(history)
374 368
375 369 def setCompletionMethod(self, completion):
376 if completion in ['IPYTHON','STC']:
370 if completion in ['IPYTHON', 'STC']:
377 371 self.autocomplete_mode = completion
378 372 else:
379 373 raise AttributeError
380 374
381 375 def getCompletionMethod(self, completion):
382 376 return self.autocomplete_mode
383 377
384 378 def writeCompletion(self, possibilities):
385 379 if self.autocomplete_mode == 'IPYTHON':
386 max_len = len(max(possibilities,key=len))
387 max_symbol =' '*max_len
380 max_len = len(max(possibilities, key=len))
381 max_symbol = ' '*max_len
388 382
389 383 #now we check how much symbol we can put on a line...
390 cursor_pos = self.getCursorPos()
391 384 test_buffer = max_symbol + ' '*4
392 current_lines = self.GetLineCount()
393 385
394 386 allowed_symbols = 80/len(test_buffer)
395 387 if allowed_symbols == 0:
396 allowed_symbols = 1
388 allowed_symbols = 1
397 389
398 390 pos = 1
399 391 buf = ''
400 392 for symbol in possibilities:
401 393 #buf += symbol+'\n'#*spaces)
402 if pos<allowed_symbols:
394 if pos < allowed_symbols:
403 395 spaces = max_len - len(symbol) + 4
404 396 buf += symbol+' '*spaces
405 397 pos += 1
406 398 else:
407 buf+=symbol+'\n'
399 buf += symbol+'\n'
408 400 pos = 1
409 401 self.write(buf)
410 402 else:
411 403 possibilities.sort() # Python sorts are case sensitive
412 404 self.AutoCompSetIgnoreCase(False)
413 405 self.AutoCompSetAutoHide(False)
414 406 #let compute the length ot last word
415 splitter = [' ','(','[','{']
407 splitter = [' ', '(', '[', '{']
416 408 last_word = self.getCurrentLine()
417 409 for breaker in splitter:
418 410 last_word = last_word.split(breaker)[-1]
419 411 self.AutoCompShow(len(last_word), " ".join(possibilities))
420 412
421 413 def _onKeypress(self, event, skip=True):
422 414 '''
423 415 Key press callback used for correcting behavior for console-like
424 416 interfaces. For example 'home' should go to prompt, not to begining of
425 417 line.
426 418
427 419 @param widget: Widget that key press accored in.
428 420 @type widget: gtk.Widget
429 421 @param event: Event object
430 422 @type event: gtk.gdk.Event
431 423
432 424 @return: Return True if event as been catched.
433 425 @rtype: boolean
434 426 '''
435 427
436 428 if not self.AutoCompActive():
437 429 if event.GetKeyCode() == wx.WXK_HOME:
438 430 if event.Modifiers == wx.MOD_NONE:
439 431 self.moveCursorOnNewValidKey()
440 432 self.moveCursor(self.getCurrentPromptStart())
441 433 return True
442 434 elif event.Modifiers == wx.MOD_SHIFT:
443 435 self.moveCursorOnNewValidKey()
444 self.selectFromTo(self.getCurrentPromptStart(),self.getCursorPos())
436 self.selectFromTo(self.getCurrentPromptStart(), self.getCursorPos())
445 437 return True
446 438 else:
447 439 return False
448 440
449 441 elif event.GetKeyCode() == wx.WXK_LEFT:
450 442 if event.Modifiers == wx.MOD_NONE:
451 443 self.moveCursorOnNewValidKey()
452 444
453 445 self.moveCursor(self.getCursorPos()-1)
454 446 if self.getCursorPos() < self.getCurrentPromptStart():
455 447 self.moveCursor(self.getCurrentPromptStart())
456 448 return True
457 449
458 450 elif event.GetKeyCode() == wx.WXK_BACK:
459 451 self.moveCursorOnNewValidKey()
460 452 if self.getCursorPos() > self.getCurrentPromptStart():
461 453 event.Skip()
462 454 return True
463 455
464 456 if skip:
465 if event.GetKeyCode() not in [wx.WXK_PAGEUP,wx.WXK_PAGEDOWN] and event.Modifiers == wx.MOD_NONE:
457 if event.GetKeyCode() not in [wx.WXK_PAGEUP, wx.WXK_PAGEDOWN]\
458 and event.Modifiers == wx.MOD_NONE:
466 459 self.moveCursorOnNewValidKey()
467 460
468 461 event.Skip()
469 462 return True
470 463 return False
471 464 else:
472 465 event.Skip()
473 466
474 467 def OnUpdateUI(self, evt):
475 468 # check for matching braces
476 469 braceAtCaret = -1
477 470 braceOpposite = -1
478 471 charBefore = None
479 472 caretPos = self.GetCurrentPos()
480 473
481 474 if caretPos > 0:
482 475 charBefore = self.GetCharAt(caretPos - 1)
483 476 styleBefore = self.GetStyleAt(caretPos - 1)
484 477
485 478 # check before
486 479 if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
487 480 braceAtCaret = caretPos - 1
488 481
489 482 # check after
490 483 if braceAtCaret < 0:
491 484 charAfter = self.GetCharAt(caretPos)
492 485 styleAfter = self.GetStyleAt(caretPos)
493 486
494 487 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
495 488 braceAtCaret = caretPos
496 489
497 490 if braceAtCaret >= 0:
498 491 braceOpposite = self.BraceMatch(braceAtCaret)
499 492
500 493 if braceAtCaret != -1 and braceOpposite == -1:
501 494 self.BraceBadLight(braceAtCaret)
502 495 else:
503 496 self.BraceHighlight(braceAtCaret, braceOpposite)
504 497 #pt = self.PointFromPosition(braceOpposite)
505 498 #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
506 499 #print pt
507 500 #self.Refresh(False)
508 501
509 502 class IPShellWidget(wx.Panel):
510 503 '''
511 504 This is wx.Panel that embbed the IPython Thread and the wx.StyledTextControl
512 505 If you want to port this to any other GUI toolkit, just replace the
513 506 WxConsoleView by YOURGUIConsoleView and make YOURGUIIPythonView derivate
514 507 from whatever container you want. I've choosed to derivate from a wx.Panel
515 508 because it seems to be more useful
516 509 Any idea to make it more 'generic' welcomed.
517 510 '''
518 511
519 512 def __init__(self, parent, intro=None,
520 513 background_color="BLACK", add_button_handler=None,
521 514 wx_ip_shell=None, user_ns={},user_global_ns=None,
522 515 ):
523 516 '''
524 517 Initialize.
525 518 Instanciate an IPython thread.
526 519 Instanciate a WxConsoleView.
527 520 Redirect I/O to console.
528 521 '''
529 522 wx.Panel.__init__(self,parent,wx.ID_ANY)
530 523
531 524 self.parent = parent
532 525 ### IPython non blocking shell instanciation ###
533 526 self.cout = StringIO()
534 527 self.add_button_handler = add_button_handler
535 528
536 529 if wx_ip_shell is not None:
537 530 self.IP = wx_ip_shell
538 531 else:
539 532 self.IP = WxNonBlockingIPShell(self,
540 533 cout = self.cout, cerr = self.cout,
541 534 ask_exit_handler = self.askExitCallback)
542 535
543 536 ### IPython wx console view instanciation ###
544 537 #If user didn't defined an intro text, we create one for him
545 538 #If you really wnat an empty intro just call wxIPythonViewPanel
546 539 #with intro=''
547 540 if intro is None:
548 541 welcome_text = "Welcome to WxIPython Shell.\n\n"
549 542 welcome_text+= self.IP.getBanner()
550 543 welcome_text+= "!command -> Execute command in shell\n"
551 544 welcome_text+= "TAB -> Autocompletion\n"
552 545 else:
553 546 welcome_text = intro
554 547
555 548 self.text_ctrl = WxConsoleView(self,
556 549 self.IP.getPrompt(),
557 550 intro=welcome_text,
558 551 background_color=background_color)
559 552
560 553 self.cout.write = self.text_ctrl.asyncWrite
561 554
562 555 option_text = wx.StaticText(self, -1, "Options:")
563 556 self.completion_option = wx.CheckBox(self, -1, "Scintilla Completion")
564 557 #self.completion_option.SetValue(False)
565 558 self.background_option = wx.CheckBox(self, -1, "White Background")
566 559 #self.background_option.SetValue(False)
567 560
568 561 self.options={'completion':{'value':'IPYTHON',
569 562 'checkbox':self.completion_option,'STC':True,'IPYTHON':False,
570 563 'setfunc':self.text_ctrl.setCompletionMethod},
571 564 'background_color':{'value':'BLACK',
572 565 'checkbox':self.background_option,'WHITE':True,'BLACK':False,
573 566 'setfunc':self.text_ctrl.setBackgroundColor},
574 567 }
575 568 self.reloadOptions(self.options)
576 569
577 570 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress)
578 571 self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion)
579 572 self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor)
580 573
581 574 ### making the layout of the panel ###
582 575 sizer = wx.BoxSizer(wx.VERTICAL)
583 576 sizer.Add(self.text_ctrl, 1, wx.EXPAND)
584 577 option_sizer = wx.BoxSizer(wx.HORIZONTAL)
585 578 sizer.Add(option_sizer, 0)
586 579 option_sizer.AddMany([(10, 20),
587 580 (option_text, 0, wx.ALIGN_CENTER_VERTICAL),
588 581 (5, 5),
589 582 (self.completion_option, 0, wx.ALIGN_CENTER_VERTICAL),
590 583 (8, 8),
591 584 (self.background_option, 0, wx.ALIGN_CENTER_VERTICAL)
592 585 ])
593 586 self.SetAutoLayout(True)
594 587 sizer.Fit(self)
595 588 sizer.SetSizeHints(self)
596 589 self.SetSizer(sizer)
597 590 #and we focus on the widget :)
598 591 self.SetFocus()
599 592
600 593 #widget state management (for key handling different cases)
601 594 self.setCurrentState('IDLE')
602 595 self.pager_state = 'DONE'
603 596 self.raw_input_current_line = 0
604 597
605 598 def askExitCallback(self, event):
606 599 self.askExitHandler(event)
607 600
608 601 #---------------------- IPython Thread Management ------------------------
609 602 def stateDoExecuteLine(self):
610 603 lines=self.text_ctrl.getCurrentLine()
611 604 self.text_ctrl.write('\n')
612 605 lines_to_execute = lines.replace('\t',' '*4)
613 606 lines_to_execute = lines_to_execute.replace('\r','')
614 607 self.IP.doExecute(lines_to_execute.encode('cp1252'))
615 608 self.updateHistoryTracker(lines)
616 609 self.setCurrentState('WAIT_END_OF_EXECUTION')
617 610
618 611 def evtStateExecuteDone(self,evt):
619 612 self.doc = self.IP.getDocText()
620 613 self.help = self.IP.getHelpText()
621 614 if self.doc:
622 615 self.pager_lines = self.doc[7:].split('\n')
623 616 self.pager_state = 'INIT'
624 617 self.setCurrentState('SHOW_DOC')
625 618 self.pager(self.doc)
626 619 elif self.help:
627 620 self.pager_lines = self.help.split('\n')
628 621 self.pager_state = 'INIT'
629 622 self.setCurrentState('SHOW_DOC')
630 623 self.pager(self.help)
631 624 else:
632 625 self.stateShowPrompt()
633 626
634 627 def stateShowPrompt(self):
635 628 self.setCurrentState('SHOW_PROMPT')
636 629 self.text_ctrl.setPrompt(self.IP.getPrompt())
637 630 self.text_ctrl.setIndentation(self.IP.getIndentation())
638 631 self.text_ctrl.setPromptCount(self.IP.getPromptCount())
639 632 self.text_ctrl.showPrompt()
640 633 self.IP.initHistoryIndex()
641 634 self.setCurrentState('IDLE')
642 635
643 636 def setCurrentState(self, state):
644 637 self.cur_state = state
645 638 self.updateStatusTracker(self.cur_state)
646 639
647 640 def pager(self,text):
648 641
649 642 if self.pager_state == 'INIT':
650 #print >>sys.__stdout__,"PAGER state:",self.pager_state
651 self.pager_nb_lines = len(self.pager_lines)
652 self.pager_index = 0
653 self.pager_do_remove = False
654 self.text_ctrl.write('\n')
655 self.pager_state = 'PROCESS_LINES'
643 #print >>sys.__stdout__,"PAGER state:",self.pager_state
644 self.pager_nb_lines = len(self.pager_lines)
645 self.pager_index = 0
646 self.pager_do_remove = False
647 self.text_ctrl.write('\n')
648 self.pager_state = 'PROCESS_LINES'
656 649
657 650 if self.pager_state == 'PROCESS_LINES':
658 #print >>sys.__stdout__,"PAGER state:",self.pager_state
659 if self.pager_do_remove == True:
660 self.text_ctrl.removeCurrentLine()
661 self.pager_do_remove = False
662
663 if self.pager_nb_lines > 10:
664 #print >>sys.__stdout__,"PAGER processing 10 lines"
665 if self.pager_index > 0:
666 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
667 else:
668 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
669
670 for line in self.pager_lines[self.pager_index+1:self.pager_index+9]:
671 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
672 self.pager_index += 10
673 self.pager_nb_lines -= 10
674 self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---")
675 self.pager_do_remove = True
676 self.pager_state = 'WAITING'
677 return
651 #print >>sys.__stdout__,"PAGER state:",self.pager_state
652 if self.pager_do_remove == True:
653 self.text_ctrl.removeCurrentLine()
654 self.pager_do_remove = False
655
656 if self.pager_nb_lines > 10:
657 #print >>sys.__stdout__,"PAGER processing 10 lines"
658 if self.pager_index > 0:
659 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
678 660 else:
679 #print >>sys.__stdout__,"PAGER processing last lines"
680 if self.pager_nb_lines > 0:
681 if self.pager_index > 0:
682 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
683 else:
684 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
685
686 self.pager_index += 1
687 self.pager_nb_lines -= 1
688 if self.pager_nb_lines > 0:
689 for line in self.pager_lines[self.pager_index:]:
690 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
691 self.pager_nb_lines = 0
692 self.pager_state = 'DONE'
693 self.stateShowPrompt()
694
661 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
662
663 for line in self.pager_lines[self.pager_index+1:self.pager_index+9]:
664 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
665 self.pager_index += 10
666 self.pager_nb_lines -= 10
667 self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---")
668 self.pager_do_remove = True
669 self.pager_state = 'WAITING'
670 return
671 else:
672 #print >>sys.__stdout__,"PAGER processing last lines"
673 if self.pager_nb_lines > 0:
674 if self.pager_index > 0:
675 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
676 else:
677 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
678
679 self.pager_index += 1
680 self.pager_nb_lines -= 1
681 if self.pager_nb_lines > 0:
682 for line in self.pager_lines[self.pager_index:]:
683 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
684 self.pager_nb_lines = 0
685 self.pager_state = 'DONE'
686 self.stateShowPrompt()
687
695 688 #------------------------ Key Handler ------------------------------------
696 689 def keyPress(self, event):
697 690 '''
698 691 Key press callback with plenty of shell goodness, like history,
699 692 autocompletions, etc.
700 693 '''
701 694 if event.GetKeyCode() == ord('C'):
702 695 if event.Modifiers == wx.MOD_CONTROL or event.Modifiers == wx.MOD_ALT:
703 696 if self.cur_state == 'WAIT_END_OF_EXECUTION':
704 697 #we raise an exception inside the IPython thread container
705 698 self.IP.ce.raise_exc(KeyboardInterrupt)
706 699 return
707 700
708 701 #let this before 'wx.WXK_RETURN' because we have to put 'IDLE'
709 702 #mode if AutoComp has been set as inactive
710 703 if self.cur_state == 'COMPLETING':
711 704 if not self.text_ctrl.AutoCompActive():
712 705 self.cur_state = 'IDLE'
713 706 else:
714 707 event.Skip()
715 708
716 709 if event.KeyCode == wx.WXK_RETURN:
717 710 if self.cur_state == 'IDLE':
718 711 #we change the state ot the state machine
719 712 self.setCurrentState('DO_EXECUTE_LINE')
720 713 self.stateDoExecuteLine()
721 714 return
722 715
723 716 if self.pager_state == 'WAITING':
724 717 self.pager_state = 'PROCESS_LINES'
725 718 self.pager(self.doc)
726 719 return
727 720
728 721 if self.cur_state == 'WAITING_USER_INPUT':
729 722 line=self.text_ctrl.getCurrentLine()
730 723 self.text_ctrl.write('\n')
731 724 self.setCurrentState('WAIT_END_OF_EXECUTION')
732 725 return
733 726
734 727 if event.GetKeyCode() in [ord('q'),ord('Q')]:
735 728 if self.pager_state == 'WAITING':
736 729 self.pager_state = 'DONE'
737 730 self.text_ctrl.write('\n')
738 731 self.stateShowPrompt()
739 732 return
740 733
741 734 if self.cur_state == 'WAITING_USER_INPUT':
742 735 event.Skip()
743 736
744 737 if self.cur_state == 'IDLE':
745 738 if event.KeyCode == wx.WXK_UP:
746 739 history = self.IP.historyBack()
747 740 self.text_ctrl.writeHistory(history)
748 741 return
749 742 if event.KeyCode == wx.WXK_DOWN:
750 743 history = self.IP.historyForward()
751 744 self.text_ctrl.writeHistory(history)
752 745 return
753 746 if event.KeyCode == wx.WXK_TAB:
754 747 #if line empty we disable tab completion
755 748 if not self.text_ctrl.getCurrentLine().strip():
756 749 self.text_ctrl.write('\t')
757 750 return
758 751 completed, possibilities = self.IP.complete(self.text_ctrl.getCurrentLine())
759 752 if len(possibilities) > 1:
760 753 if self.text_ctrl.autocomplete_mode == 'IPYTHON':
761 754 cur_slice = self.text_ctrl.getCurrentLine()
762 755 self.text_ctrl.write('\n')
763 756 self.text_ctrl.writeCompletion(possibilities)
764 757 self.text_ctrl.write('\n')
765 758
766 759 self.text_ctrl.showPrompt()
767 760 self.text_ctrl.write(cur_slice)
768 761 self.text_ctrl.changeLine(completed or cur_slice)
769 762 else:
770 763 self.cur_state = 'COMPLETING'
771 764 self.text_ctrl.writeCompletion(possibilities)
772 765 else:
773 766 self.text_ctrl.changeLine(completed or cur_slice)
774 767 return
775 768 event.Skip()
776 769
777 770 #------------------------ Option Section ---------------------------------
778 771 def evtCheckOptionCompletion(self, event):
779 772 if event.IsChecked():
780 773 self.options['completion']['value']='STC'
781 774 else:
782 775 self.options['completion']['value']='IPYTHON'
783 776 self.text_ctrl.setCompletionMethod(self.options['completion']['value'])
784 777 self.updateOptionTracker('completion',
785 778 self.options['completion']['value'])
786 779 self.text_ctrl.SetFocus()
787 780
788 781 def evtCheckOptionBackgroundColor(self, event):
789 782 if event.IsChecked():
790 783 self.options['background_color']['value']='WHITE'
791 784 else:
792 785 self.options['background_color']['value']='BLACK'
793 786 self.text_ctrl.setBackgroundColor(self.options['background_color']['value'])
794 787 self.updateOptionTracker('background_color',
795 788 self.options['background_color']['value'])
796 789 self.text_ctrl.SetFocus()
797 790
798 791 def getOptions(self):
799 792 return self.options
800 793
801 794 def reloadOptions(self,options):
802 795 self.options = options
803 796 for key in self.options.keys():
804 797 value = self.options[key]['value']
805 798 self.options[key]['checkbox'].SetValue(self.options[key][value])
806 799 self.options[key]['setfunc'](value)
807 800
808 801
809 802 #------------------------ Hook Section -----------------------------------
810 803 def updateOptionTracker(self,name,value):
811 804 '''
812 805 Default history tracker (does nothing)
813 806 '''
814 807 pass
815 808
816 809 def setOptionTrackerHook(self,func):
817 810 '''
818 811 Define a new history tracker
819 812 '''
820 813 self.updateOptionTracker = func
821 814
822 815 def updateHistoryTracker(self,command_line):
823 816 '''
824 817 Default history tracker (does nothing)
825 818 '''
826 819 pass
827 820
828 821 def setHistoryTrackerHook(self,func):
829 822 '''
830 823 Define a new history tracker
831 824 '''
832 825 self.updateHistoryTracker = func
833 826
834 827 def updateStatusTracker(self,status):
835 828 '''
836 829 Default status tracker (does nothing)
837 830 '''
838 831 pass
839 832
840 833 def setStatusTrackerHook(self,func):
841 834 '''
842 835 Define a new status tracker
843 836 '''
844 837 self.updateStatusTracker = func
845 838
846 839 def askExitHandler(self, event):
847 840 '''
848 841 Default exit handler
849 842 '''
850 843 self.text_ctrl.write('\nExit callback has not been set.')
851 844
852 845 def setAskExitHandler(self, func):
853 846 '''
854 847 Define an exit handler
855 848 '''
856 849 self.askExitHandler = func
857 850
858 851 if __name__ == '__main__':
859 852 # Some simple code to test the shell widget.
860 853 class MainWindow(wx.Frame):
861 854 def __init__(self, parent, id, title):
862 855 wx.Frame.__init__(self, parent, id, title, size=(300,250))
863 856 self._sizer = wx.BoxSizer(wx.VERTICAL)
864 857 self.shell = IPShellWidget(self)
865 858 self._sizer.Add(self.shell, 1, wx.EXPAND)
866 859 self.SetSizer(self._sizer)
867 860 self.SetAutoLayout(1)
868 861 self.Show(True)
869 862
870 863 app = wx.PySimpleApp()
871 864 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
872 865 frame.SetSize((780, 460))
873 866 shell = frame.shell
874 867
875 868 app.MainLoop()
876 869
877 870
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,395 +1,395 b''
1 1 .\" Hey, EMACS: -*- nroff -*-
2 2 .\" First parameter, NAME, should be all caps
3 3 .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
4 4 .\" other parameters are allowed: see man(7), man(1)
5 5 .TH IPYTHON 1 "November 30, 2004"
6 6 .\" Please adjust this date whenever revising the manpage.
7 7 .\"
8 8 .\" Some roff macros, for reference:
9 9 .\" .nh disable hyphenation
10 10 .\" .hy enable hyphenation
11 11 .\" .ad l left justify
12 12 .\" .ad b justify to both left and right margins
13 13 .\" .nf disable filling
14 14 .\" .fi enable filling
15 15 .\" .br insert line break
16 16 .\" .sp <n> insert n+1 empty lines
17 17 .\" for manpage-specific macros, see man(7) and groff_man(7)
18 18 .\" .SH section heading
19 19 .\" .SS secondary section heading
20 20 .\"
21 21 .\"
22 22 .\" To preview this page as plain text: nroff -man ipython.1
23 23 .\"
24 24 .SH NAME
25 25 ipython \- An Enhanced Interactive Python
26 26 .SH SYNOPSIS
27 27 .B ipython
28 28 .RI [ options ] " files" ...
29 29 .SH DESCRIPTION
30 30 An interactive Python shell with automatic history (input and output),
31 31 dynamic object introspection, easier configuration, command
32 32 completion, access to the system shell, integration with numerical and
33 33 scientific computing tools, and more.
34 34 .SH SPECIAL THREADING OPTIONS
35 35 The following special options are ONLY valid at the beginning of the command
36 36 line, and not later. This is because they control the initialization of
37 37 ipython itself, before the normal option-handling mechanism is active.
38 38 .TP
39 .B \-gthread, \-qthread, \-q4thread, \-wthread, \-pylab, \-twisted
39 .B \-gthread, \-qthread, \-q4thread, \-wthread, \-pylab
40 40 Only ONE of these can be given, and it can only be given as the first option
41 41 passed to IPython (it will have no effect in any other position). They provide
42 42 threading support for the GTK, QT3, QT4 and WXWidgets toolkits, for the
43 43 matplotlib library and Twisted reactor.
44 44 .br
45 45 .sp 1
46 46 With any of the first four options, IPython starts running a separate thread
47 47 for the graphical toolkit's operation, so that you can open and control
48 48 graphical elements from within an IPython command line, without blocking. All
49 49 four provide essentially the same functionality, respectively for GTK, QT3, QT4
50 50 and WXWidgets (via their Python interfaces).
51 51 .br
52 52 .sp 1
53 53 Note that with \-wthread, you can additionally use the \-wxversion option to
54 54 request a specific version of wx to be used. This requires that you have the
55 55 'wxversion' Python module installed, which is part of recent wxPython
56 56 distributions.
57 57 .br
58 58 .sp 1
59 If \-twisted is given, IPython start a Twisted reactor and runs IPython mainloop
60 in a dedicated thread, passing commands to be run inside the Twisted reactor.
61 .br
62 .sp 1
63 59 If \-pylab is given, IPython loads special support for the matplotlib library
64 60 (http://matplotlib.sourceforge.net), allowing interactive usage of any of its
65 61 backends as defined in the user's .matplotlibrc file. It automatically
66 62 activates GTK, QT or WX threading for IPyhton if the choice of matplotlib
67 63 backend requires it. It also modifies the %run command to correctly execute
68 64 (without blocking) any matplotlib-based script which calls show() at the end.
69 65 .TP
70 66 .B \-tk
71 67 The \-g/q/q4/wthread options, and \-pylab (if matplotlib is configured to use
72 68 GTK, QT or WX), will normally block Tk graphical interfaces. This means that
73 69 when GTK, QT or WX threading is active, any attempt to open a Tk GUI will
74 70 result in a dead window, and possibly cause the Python interpreter to crash.
75 71 An extra option, \-tk, is available to address this issue. It can ONLY be
76 72 given as a SECOND option after any of the above (\-gthread, \-qthread,
77 73 \-wthread or \-pylab).
78 74 .br
79 75 .sp 1
80 76 If \-tk is given, IPython will try to coordinate Tk threading with GTK, QT or
81 77 WX. This is however potentially unreliable, and you will have to test on your
82 78 platform and Python configuration to determine whether it works for you.
83 79 Debian users have reported success, apparently due to the fact that Debian
84 80 builds all of Tcl, Tk, Tkinter and Python with pthreads support. Under other
85 81 Linux environments (such as Fedora Core 2), this option has caused random
86 82 crashes and lockups of the Python interpreter. Under other operating systems
87 83 (Mac OSX and Windows), you'll need to try it to find out, since currently no
88 84 user reports are available.
89 85 .br
90 86 .sp 1
91 87 There is unfortunately no way for IPython to determine at runtime whether \-tk
92 88 will work reliably or not, so you will need to do some experiments before
93 89 relying on it for regular work.
94 90 .
95 91 .SH REGULAR OPTIONS
96 92 After the above threading options have been given, regular options can follow
97 93 in any order. All options can be abbreviated to their shortest non-ambiguous
98 94 form and are case-sensitive. One or two dashes can be used. Some options
99 95 have an alternate short form, indicated after a |.
100 96 .br
101 97 .sp 1
102 98 Most options can also be set from your ipythonrc configuration file.
103 99 See the provided examples for assistance. Options given on the
104 100 commandline override the values set in the ipythonrc file.
105 101 .br
106 102 .sp 1
107 103 All options with a [no] prepended can be specified in negated form
108 104 (\-nooption instead of \-option) to turn the feature off.
109 105 .TP
110 106 .B \-h, \-\-help
111 107 Show summary of options.
112 108 .TP
113 109 .B \-autocall <val>
114 110 Make IPython automatically call any callable object even if you didn't type
115 111 explicit parentheses. For example, 'str 43' becomes
116 112 'str(43)' automatically. The value can be '0' to disable the
117 113 feature, '1' for 'smart' autocall, where it is not applied if
118 114 there are no more arguments on the line, and '2' for 'full'
119 115 autocall, where all callable objects are automatically called
120 116 (even if no arguments are present). The default is '1'.
121 117 .TP
122 118 .B \-[no]autoindent
123 119 Turn automatic indentation on/off.
124 120 .TP
125 121 .B \-[no]automagic
126 122 Make magic commands automatic (without needing their first character
127 123 to be %). Type %magic at the IPython prompt for more information.
128 124 .TP
129 125 .B \-[no]autoedit_syntax
130 126 When a syntax error occurs after editing a file, automatically open the file
131 127 to the trouble causing line for convenient fixing.
132 128 .TP
133 129 .B \-[no]banner
134 130 Print the intial information banner (default on).
135 131 .TP
136 132 .B \-c <command>
137 133 Execute the given command string, and set sys.argv to ['c']. This is similar
138 134 to the \-c option in the normal Python interpreter.
139 135 .TP
140 136 .B \-cache_size|cs <n>
141 137 Size of the output cache (maximum number of entries to hold in
142 138 memory). The default is 1000, you can change it permanently in your
143 139 config file. Setting it to 0 completely disables the caching system,
144 140 and the minimum value accepted is 20 (if you provide a value less than
145 141 20, it is reset to 0 and a warning is issued). This limit is defined
146 142 because otherwise you'll spend more time re-flushing a too small cache
147 143 than working.
148 144 .TP
149 145 .B \-classic|cl
150 146 Gives IPython a similar feel to the classic Python prompt.
151 147 .TP
152 148 .B \-colors <scheme>
153 149 Color scheme for prompts and exception reporting. Currently
154 150 implemented: NoColor, Linux, and LightBG.
155 151 .TP
156 152 .B \-[no]color_info
157 153 IPython can display information about objects via a set of functions,
158 154 and optionally can use colors for this, syntax highlighting source
159 155 code and various other elements. However, because this information is
160 156 passed through a pager (like 'less') and many pagers get confused with
161 157 color codes, this option is off by default. You can test it and turn
162 158 it on permanently in your ipythonrc file if it works for you. As a
163 159 reference, the 'less' pager supplied with Mandrake 8.2 works ok, but
164 160 that in RedHat 7.2 doesn't.
165 161 .br
166 162 .sp 1
167 163 Test it and turn it on permanently if it works with your system. The
168 164 magic function @color_info allows you to toggle this interactively for
169 165 testing.
170 166 .TP
171 167 .B \-[no]confirm_exit
172 168 Set to confirm when you try to exit IPython with an EOF (Control-D in
173 169 Unix, Control-Z/Enter in Windows). Note that using the magic functions
174 170 @Exit or @Quit you can force a direct exit, bypassing any
175 171 confirmation.
176 172 .TP
177 173 .B \-[no]debug
178 174 Show information about the loading process. Very useful to pin down
179 175 problems with your configuration files or to get details about session
180 176 restores.
181 177 .TP
182 178 .B \-[no]deep_reload
183 179 IPython can use the deep_reload module which reloads changes in
184 180 modules recursively (it replaces the reload() function, so you don't
185 181 need to change anything to use it). deep_reload() forces a full reload
186 182 of modules whose code may have changed, which the default reload()
187 183 function does not.
188 184 .br
189 185 .sp 1
190 186 When deep_reload is off, IPython will use the normal reload(), but
191 187 deep_reload will still be available as dreload(). This feature is off
192 188 by default [which means that you have both normal reload() and
193 189 dreload()].
194 190 .TP
195 191 .B \-editor <name>
196 192 Which editor to use with the @edit command. By default, IPython will
197 193 honor your EDITOR environment variable (if not set, vi is the Unix
198 194 default and notepad the Windows one). Since this editor is invoked on
199 195 the fly by IPython and is meant for editing small code snippets, you
200 196 may want to use a small, lightweight editor here (in case your default
201 197 EDITOR is something like Emacs).
202 198 .TP
203 199 .B \-ipythondir <name>
204 200 The name of your IPython configuration directory IPYTHONDIR. This can
205 201 also be specified through the environment variable IPYTHONDIR.
206 202 .TP
207 203 .B \-log|l
208 204 Generate a log file of all input. The file is named ipython_log.py in your
209 205 current directory (which prevents logs from multiple IPython sessions from
210 206 trampling each other). You can use this to later restore a session by loading
211 207 your logfile as a file to be executed with option -logplay (see below).
212 208 .TP
213 209 .B \-logfile|lf
214 210 Specify the name of your logfile.
215 211 .TP
216 212 .B \-logplay|lp
217 213 Replay a previous log. For restoring a session as close as possible to
218 214 the state you left it in, use this option (don't just run the
219 215 logfile). With \-logplay, IPython will try to reconstruct the previous
220 216 working environment in full, not just execute the commands in the
221 217 logfile.
222 218 .br
223 219 .sh 1
224 220 When a session is restored, logging is automatically turned on again
225 221 with the name of the logfile it was invoked with (it is read from the
226 222 log header). So once you've turned logging on for a session, you can
227 223 quit IPython and reload it as many times as you want and it will
228 224 continue to log its history and restore from the beginning every time.
229 225 .br
230 226 .sp 1
231 227 Caveats: there are limitations in this option. The history variables
232 228 _i*,_* and _dh don't get restored properly. In the future we will try
233 229 to implement full session saving by writing and retrieving a
234 230 'snapshot' of the memory state of IPython. But our first attempts
235 231 failed because of inherent limitations of Python's Pickle module, so
236 232 this may have to wait.
237 233 .TP
238 234 .B \-[no]messages
239 235 Print messages which IPython collects about its startup process
240 236 (default on).
241 237 .TP
242 238 .B \-[no]pdb
243 239 Automatically call the pdb debugger after every uncaught exception. If
244 240 you are used to debugging using pdb, this puts you automatically
245 241 inside of it after any call (either in IPython or in code called by
246 242 it) which triggers an exception which goes uncaught.
247 243 .TP
244 .B \-pydb
245 Makes IPython use the third party "pydb" package as debugger,
246 instead of pdb. Requires that pydb is installed.
247 .TP
248 248 .B \-[no]pprint
249 249 IPython can optionally use the pprint (pretty printer) module for
250 250 displaying results. pprint tends to give a nicer display of nested
251 251 data structures. If you like it, you can turn it on permanently in
252 252 your config file (default off).
253 253 .TP
254 254 .B \-profile|p <name>
255 255 Assume that your config file is ipythonrc-<name> (looks in current dir
256 256 first, then in IPYTHONDIR). This is a quick way to keep and load
257 257 multiple config files for different tasks, especially if you use the
258 258 include option of config files. You can keep a basic
259 259 IPYTHONDIR/ipythonrc file and then have other 'profiles' which include
260 260 this one and load extra things for particular tasks. For example:
261 261 .br
262 262 .sp 1
263 263 1) $HOME/.ipython/ipythonrc : load basic things you always want.
264 264 .br
265 265 2) $HOME/.ipython/ipythonrc-math : load (1) and basic math-related
266 266 modules.
267 267 .br
268 268 3) $HOME/.ipython/ipythonrc-numeric : load (1) and Numeric and
269 269 plotting modules.
270 270 .br
271 271 .sp 1
272 272 Since it is possible to create an endless loop by having circular file
273 273 inclusions, IPython will stop if it reaches 15 recursive inclusions.
274 274 .TP
275 275 .B \-prompt_in1|pi1 <string>
276 276 Specify the string used for input prompts. Note that if you are using
277 277 numbered prompts, the number is represented with a '\\#' in the
278 278 string. Don't forget to quote strings with spaces embedded in
279 279 them. Default: 'In [\\#]: '.
280 280 .br
281 281 .sp 1
282 282 Most bash-like escapes can be used to customize IPython's prompts, as well as
283 283 a few additional ones which are IPython-specific. All valid prompt escapes
284 284 are described in detail in the Customization section of the IPython HTML/PDF
285 285 manual.
286 286 .TP
287 287 .B \-prompt_in2|pi2 <string>
288 288 Similar to the previous option, but used for the continuation prompts. The
289 289 special sequence '\\D' is similar to '\\#', but with all digits replaced dots
290 290 (so you can have your continuation prompt aligned with your input
291 291 prompt). Default: ' .\\D.: ' (note three spaces at the start for alignment
292 292 with 'In [\\#]').
293 293 .TP
294 294 .B \-prompt_out|po <string>
295 295 String used for output prompts, also uses numbers like prompt_in1.
296 296 Default: 'Out[\\#]:'.
297 297 .TP
298 298 .B \-quick
299 299 Start in bare bones mode (no config file loaded).
300 300 .TP
301 301 .B \-rcfile <name>
302 302 Name of your IPython resource configuration file. normally IPython
303 303 loads ipythonrc (from current directory) or IPYTHONDIR/ipythonrc. If
304 304 the loading of your config file fails, IPython starts with a bare
305 305 bones configuration (no modules loaded at all).
306 306 .TP
307 307 .B \-[no]readline
308 308 Use the readline library, which is needed to support name completion
309 309 and command history, among other things. It is enabled by default, but
310 310 may cause problems for users of X/Emacs in Python comint or shell
311 311 buffers.
312 312 .br
313 313 .sp 1
314 314 Note that emacs 'eterm' buffers (opened with M-x term) support
315 315 IPython's readline and syntax coloring fine, only 'emacs' (M-x shell
316 316 and C-c !) buffers do not.
317 317 .TP
318 318 .B \-screen_length|sl <n>
319 319 Number of lines of your screen. This is used to control printing of
320 320 very long strings. Strings longer than this number of lines will be
321 321 sent through a pager instead of directly printed.
322 322 .br
323 323 .sp 1
324 324 The default value for this is 0, which means IPython will auto-detect
325 325 your screen size every time it needs to print certain potentially long
326 326 strings (this doesn't change the behavior of the 'print' keyword, it's
327 327 only triggered internally). If for some reason this isn't working well
328 328 (it needs curses support), specify it yourself. Otherwise don't change
329 329 the default.
330 330 .TP
331 331 .B \-separate_in|si <string>
332 332 Separator before input prompts. Default '\n'.
333 333 .TP
334 334 .B \-separate_out|so <string>
335 335 Separator before output prompts. Default: 0 (nothing).
336 336 .TP
337 337 .B \-separate_out2|so2 <string>
338 338 Separator after output prompts. Default: 0 (nothing).
339 339 .TP
340 340 .B \-nosep
341 341 Shorthand for '\-separate_in 0 \-separate_out 0 \-separate_out2 0'.
342 342 Simply removes all input/output separators.
343 343 .TP
344 344 .B \-upgrade
345 345 Allows you to upgrade your IPYTHONDIR configuration when you install a
346 346 new version of IPython. Since new versions may include new command
347 347 lines options or example files, this copies updated ipythonrc-type
348 348 files. However, it backs up (with a .old extension) all files which
349 349 it overwrites so that you can merge back any custimizations you might
350 350 have in your personal files.
351 351 .TP
352 352 .B \-Version
353 353 Print version information and exit.
354 354 .TP
355 355 .B -wxversion <string>
356 356 Select a specific version of wxPython (used in conjunction with
357 357 \-wthread). Requires the wxversion module, part of recent wxPython
358 358 distributions.
359 359 .TP
360 360 .B \-xmode <modename>
361 361 Mode for exception reporting. The valid modes are Plain, Context, and
362 362 Verbose.
363 363 .br
364 364 .sp 1
365 365 \- Plain: similar to python's normal traceback printing.
366 366 .br
367 367 .sp 1
368 368 \- Context: prints 5 lines of context source code around each line in the
369 369 traceback.
370 370 .br
371 371 .sp 1
372 372 \- Verbose: similar to Context, but additionally prints the variables
373 373 currently visible where the exception happened (shortening their strings if
374 374 too long). This can potentially be very slow, if you happen to have a huge
375 375 data structure whose string representation is complex to compute. Your
376 376 computer may appear to freeze for a while with cpu usage at 100%. If this
377 377 occurs, you can cancel the traceback with Ctrl-C (maybe hitting it more than
378 378 once).
379 379 .
380 380 .SH EMBEDDING
381 381 It is possible to start an IPython instance inside your own Python
382 382 programs. In the documentation example files there are some
383 383 illustrations on how to do this.
384 384 .br
385 385 .sp 1
386 386 This feature allows you to evalutate dynamically the state of your
387 387 code, operate with your variables, analyze them, etc. Note however
388 388 that any changes you make to values while in the shell do NOT
389 389 propagate back to the running code, so it is safe to modify your
390 390 values because you won't break your code in bizarre ways by doing so.
391 391 .SH AUTHOR
392 392 IPython was written by Fernando Perez <fperez@colorado.edu>, based on earlier
393 393 code by Janko Hauser <jh@comunit.de> and Nathaniel Gray
394 394 <n8gray@caltech.edu>. This manual page was written by Jack Moffitt
395 395 <jack@xiph.org>, for the Debian project (but may be used by others).
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now