Show More
@@ -21,15 +21,13 b' 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 |
|
|
|
27 | import IPython | |
|
31 | 28 | except Exception,e: |
|
32 |
|
|
|
29 | print "Error importing IPython (%s)" % str(e) | |
|
30 | raise Exception, e | |
|
33 | 31 | |
|
34 | 32 | ############################################################################## |
|
35 | 33 | class _Helper(object): |
@@ -37,7 +35,7 b' class _Helper(object):' | |||
|
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): |
@@ -46,10 +44,12 b' class _Helper(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 |
@@ -61,13 +61,14 b' class _Helper(object):' | |||
|
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 |
@@ -90,7 +91,7 b' class NonBlockingIPShell(object):' | |||
|
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 | ''' |
@@ -112,6 +113,8 b' class NonBlockingIPShell(object):' | |||
|
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) |
@@ -134,6 +137,8 b' class NonBlockingIPShell(object):' | |||
|
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 |
@@ -151,20 +156,20 b' class NonBlockingIPShell(object):' | |||
|
151 | 156 | excepthook = sys.excepthook |
|
152 | 157 | |
|
153 | 158 | self._IP = IPython.Shell.make_IPython( |
|
154 |
|
|
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
|
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 |
|
|
|
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 |
@@ -183,15 +188,15 b' class NonBlockingIPShell(object):' | |||
|
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 |
|
|
|
194 |
|
|
|
198 | ce = _CodeExecutor(self, self._afterExecute) | |
|
199 | ce.start() | |
|
195 | 200 | |
|
196 | 201 | #----------------------- IPython management section ---------------------- |
|
197 | 202 | def getDocText(self): |
@@ -307,9 +312,9 b' class NonBlockingIPShell(object):' | |||
|
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 |
|
|
|
311 |
|
|
|
312 |
|
|
|
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): |
@@ -321,16 +326,17 b' class NonBlockingIPShell(object):' | |||
|
321 | 326 | ''' |
|
322 | 327 | history = '' |
|
323 | 328 | #the below while loop is used to suppress empty history lines |
|
324 |
while((history == '' or history == '\n') |
|
|
325 |
|
|
|
326 |
|
|
|
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): |
@@ -371,24 +377,24 b' class NonBlockingIPShell(object):' | |||
|
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 |
|
|
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 |
|
|
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 | |
@@ -429,8 +435,7 b' class NonBlockingIPShell(object):' | |||
|
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() |
@@ -452,8 +457,8 b' class NonBlockingIPShell(object):' | |||
|
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 |
|
|
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() |
@@ -28,13 +28,7 b' 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 | |
@@ -47,7 +41,7 b' class WxNonBlockingIPShell(NonBlockingIPShell):' | |||
|
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 | |
@@ -56,7 +50,7 b' class WxNonBlockingIPShell(NonBlockingIPShell):' | |||
|
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)}) |
@@ -85,27 +79,27 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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 | ''' |
@@ -146,17 +140,17 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
146 | 140 | #self.SetUseAntiAliasing(True) |
|
147 | 141 | self.SetLayoutCache(stc.STC_CACHE_PAGE) |
|
148 | 142 | self.SetUndoCollection(False) |
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
|
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() |
@@ -176,13 +170,13 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
176 | 170 | def buildStyles(self): |
|
177 | 171 | #we define platform specific fonts |
|
178 | 172 | if wx.Platform == '__WXMSW__': |
|
179 |
|
|
|
180 |
|
|
|
181 |
|
|
|
182 |
|
|
|
183 |
|
|
|
184 |
|
|
|
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', |
@@ -225,11 +219,11 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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): |
@@ -240,20 +234,20 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
240 | 234 | @type text: string |
|
241 | 235 | ''' |
|
242 | 236 | try: |
|
243 |
|
|
|
244 |
|
|
|
245 |
|
|
|
237 | #print >>sys.__stdout__,'entering' | |
|
238 | wx.MutexGuiEnter() | |
|
239 | #print >>sys.__stdout__,'locking the GUI' | |
|
246 | 240 | |
|
247 |
|
|
|
248 |
|
|
|
241 | #be sure not to be interrutpted before the MutexGuiLeave! | |
|
242 | self.write(text) | |
|
249 | 243 | |
|
250 |
|
|
|
244 | #print >>sys.__stdout__,'done' | |
|
251 | 245 | |
|
252 | 246 | except KeyboardInterrupt: |
|
253 |
|
|
|
254 |
|
|
|
255 |
|
|
|
256 |
|
|
|
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 | |
@@ -267,7 +261,7 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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: |
@@ -275,11 +269,11 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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 | |
@@ -291,13 +285,13 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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): |
@@ -322,7 +316,7 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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 | |
@@ -350,30 +344,30 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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 |
@@ -383,28 +377,26 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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 |
|
|
|
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: |
@@ -412,7 +404,7 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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] |
@@ -441,7 +433,7 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
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 |
@@ -462,7 +454,8 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
462 | 454 | return True |
|
463 | 455 | |
|
464 | 456 | if skip: |
|
465 |
if event.GetKeyCode() not in [wx.WXK_PAGEUP,wx.WXK_PAGEDOWN] |
|
|
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() |
@@ -647,51 +640,51 b' class IPShellWidget(wx.Panel):' | |||
|
647 | 640 | def pager(self,text): |
|
648 | 641 | |
|
649 | 642 | if self.pager_state == 'INIT': |
|
650 |
|
|
|
651 |
|
|
|
652 |
|
|
|
653 |
|
|
|
654 |
|
|
|
655 |
|
|
|
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 |
|
|
|
659 |
|
|
|
660 |
|
|
|
661 |
|
|
|
662 | ||
|
663 |
|
|
|
664 |
|
|
|
665 |
|
|
|
666 |
|
|
|
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 |
|
|
|
683 | else: | |
|
684 | self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n') | |
|
685 | ||
|
686 |
|
|
|
687 |
|
|
|
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 |
|
|
|
692 |
|
|
|
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 | ''' |
General Comments 0
You need to be logged in to leave comments.
Login now