##// END OF EJS Templates
Finishing merging with ipython-sync-frontend.
Gael Varoquaux -
Show More
@@ -1,207 +1,201 b''
1 1 # encoding: utf-8 -*- test-case-name:
2 2 # FIXME: Need to add tests.
3 3 # ipython1.frontend.cocoa.tests.test_cocoa_frontend -*-
4 4
5 5 """Classes to provide a Wx frontend to the
6 6 ipython1.kernel.engineservice.EngineService.
7 7
8 8 """
9 9
10 10 __docformat__ = "restructuredtext en"
11 11
12 12 #-------------------------------------------------------------------------------
13 13 # Copyright (C) 2008 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-------------------------------------------------------------------------------
18 18
19 19 #-------------------------------------------------------------------------------
20 20 # Imports
21 21 #-------------------------------------------------------------------------------
22 22
23 23
24 24 import wx
25 25 from console_widget import ConsoleWidget
26 26 import re
27 27
28 28 import IPython
29 from IPython.kernel.engineservice import EngineService
29 from IPython.kernel.core.interpreter import Interpreter
30 30 from IPython.frontend.frontendbase import FrontEndBase
31 31
32 32 #-------------------------------------------------------------------------------
33 33 # Classes to implement the Wx frontend
34 34 #-------------------------------------------------------------------------------
35 35
36 36
37 37
38 38
39 39 class IPythonWxController(FrontEndBase, ConsoleWidget):
40 40
41 41 output_prompt = \
42 42 '\n\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02%i\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02'
43 43
44 44 # Are we entering multi line input?
45 45 multi_line_input = False
46 46
47 47 # The added tab stop to the string. It may, for instance, come from
48 48 # copy and pasting something with tabs.
49 49 tab_stop = 0
50 50 # FIXME: We still have to deal with this.
51 51
52 52 #--------------------------------------------------------------------------
53 53 # Public API
54 54 #--------------------------------------------------------------------------
55 55
56 56 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
57 57 size=wx.DefaultSize, style=wx.CLIP_CHILDREN,
58 58 *args, **kwds):
59 59 """ Create Shell instance.
60 60 """
61 61 ConsoleWidget.__init__(self, parent, id, pos, size, style)
62 FrontEndBase.__init__(self, engine=EngineService(),
62 FrontEndBase.__init__(self, shell=Interpreter(),
63 63 )
64 64
65 65 # FIXME: Something is wrong with the history, I instanciate it
66 66 # with an empty cache, but this is not the way to do.
67 67 self.lines = {}
68 68
69 69 # Start the IPython engine
70 self.engine.startService()
70 self.shell
71 71
72 72 # Capture Character keys
73 73 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
74 74
75 75 #FIXME: print banner.
76 76 banner = """IPython1 %s -- An enhanced Interactive Python.""" \
77 77 % IPython.__version__
78 78
79 79
80 def appWillTerminate_(self, notification):
81 """appWillTerminate"""
82
83 self.engine.stopService()
84
85
86 80 def complete(self, token):
87 81 """Complete token in engine's user_ns
88 82
89 83 Parameters
90 84 ----------
91 85 token : string
92 86
93 87 Result
94 88 ------
95 89 Deferred result of
96 90 IPython.kernel.engineservice.IEngineBase.complete
97 91 """
98 92
99 return self.engine.complete(token)
93 return self.shell.complete(token)
100 94
101 95
102 96 def render_result(self, result):
103 97 if 'stdout' in result and result['stdout']:
104 98 self.write('\n' + result['stdout'])
105 99 if 'display' in result and result['display']:
106 100 self.write("%s%s\n" % (
107 101 self.output_prompt % result['number'],
108 102 result['display']['pprint']
109 103 ) )
110 104
111 105
112 106 def render_error(self, failure):
113 107 self.insert_text('\n\n'+str(failure)+'\n\n')
114 108 return failure
115 109
116 110
117 111 #--------------------------------------------------------------------------
118 112 # Private API
119 113 #--------------------------------------------------------------------------
120 114
121 115
122 116 def _on_key_down(self, event, skip=True):
123 117 """ Capture the character events, let the parent
124 118 widget handle them, and put our logic afterward.
125 119 """
126 120 current_line_number = self.GetCurrentLine()
127 121 # Capture enter
128 122 if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \
129 123 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
130 124 self._on_enter()
131 125 # Up history
132 126 elif event.KeyCode == wx.WXK_UP and (
133 127 ( current_line_number == self.current_prompt_line and
134 128 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
135 129 or event.ControlDown() ):
136 130 new_buffer = self.get_history_previous(
137 131 self.get_current_edit_buffer())
138 132 if new_buffer is not None:
139 133 self.replace_current_edit_buffer(new_buffer)
140 134 # Down history
141 135 elif event.KeyCode == wx.WXK_DOWN and (
142 136 ( current_line_number == self.LineCount -1 and
143 137 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
144 138 or event.ControlDown() ):
145 139 new_buffer = self.get_history_next()
146 140 if new_buffer is not None:
147 141 self.replace_current_edit_buffer(new_buffer)
148 142 else:
149 143 ConsoleWidget._on_key_down(self, event, skip=True)
150 144
151 145
152 146 def _on_enter(self):
153 147 """ Called when the return key is pressed in a line editing
154 148 buffer.
155 149 """
156 150 current_buffer = self.get_current_edit_buffer()
157 151 current_buffer = current_buffer.replace('\r\n', '\n')
158 152 current_buffer = current_buffer.replace('\t', 4*' ')
159 153 cleaned_buffer = '\n'.join(l.rstrip()
160 154 for l in current_buffer.split('\n'))
161 155 if ( not self.multi_line_input
162 156 or re.findall(r"\n[\t ]*$", cleaned_buffer)):
163 157 if self.is_complete(cleaned_buffer):
164 158 self._add_history(None, cleaned_buffer.rstrip())
165 result = self.engine.shell.execute(cleaned_buffer)
159 result = self.shell.execute(cleaned_buffer)
166 160 self.render_result(result)
167 161 self.new_prompt(self.prompt % (result['number'] + 1))
168 162 self.multi_line_input = False
169 163 else:
170 164 if self.multi_line_input:
171 165 self.write('\n' + self._get_indent_string(current_buffer))
172 166 else:
173 167 self.multi_line_input = True
174 168 self.write('\n\t')
175 169 else:
176 170 self.write('\n'+self._get_indent_string(current_buffer))
177 171
178 172
179 173 def _get_indent_string(self, string):
180 174 string = string.split('\n')[-1]
181 175 indent_chars = len(string) - len(string.lstrip())
182 176 indent_string = '\t'*(indent_chars // 4) + \
183 177 ' '*(indent_chars % 4)
184 178
185 179 return indent_string
186 180
187 181
188 182
189 183 if __name__ == '__main__':
190 184 class MainWindow(wx.Frame):
191 185 def __init__(self, parent, id, title):
192 186 wx.Frame.__init__(self, parent, id, title, size=(300,250))
193 187 self._sizer = wx.BoxSizer(wx.VERTICAL)
194 188 self.shell = IPythonWxController(self)
195 189 self._sizer.Add(self.shell, 1, wx.EXPAND)
196 190 self.SetSizer(self._sizer)
197 191 self.SetAutoLayout(1)
198 192 self.Show(True)
199 193
200 194 app = wx.PySimpleApp()
201 195 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
202 196 frame.shell.SetFocus()
203 197 frame.SetSize((660, 460))
204 198 self = frame.shell
205 199
206 200 app.MainLoop()
207 201
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now