Show More
@@ -120,8 +120,37 b' var IPython = (function (IPython) {' | |||||
120 | }; |
|
120 | }; | |
121 | }); |
|
121 | }); | |
122 | that.element.focusout(function (event) { |
|
122 | that.element.focusout(function (event) { | |
|
123 | var is_or_has = function (a, b) { | |||
|
124 | // Is b a child of a or a itself? | |||
|
125 | return a.has(b).length !==0 || a.is(b); | |||
|
126 | } | |||
123 | if (that.mode === 'edit') { |
|
127 | if (that.mode === 'edit') { | |
124 | $([IPython.events]).trigger('command_mode.Cell', {'cell':that}); |
|
128 | setTimeout(function () { | |
|
129 | var trigger = true; | |||
|
130 | var target = $(document.activeElement); | |||
|
131 | var completer = that.element.find($('div.completions')); | |||
|
132 | var tooltip = $('div#tooltip') | |||
|
133 | if (target.length > 0) { | |||
|
134 | // If the focused element (target) is inside the cell | |||
|
135 | // (that.element) don't enter command mode. | |||
|
136 | if (is_or_has(that.element, target)) { | |||
|
137 | trigger = false; | |||
|
138 | // The focused element is outside the cell | |||
|
139 | } else { | |||
|
140 | // If the focused element is the tooltip or completer | |||
|
141 | // don't enter command mode, otherwise do. | |||
|
142 | trigger = true; | |||
|
143 | if (tooltip.length > 0 && is_or_has(tooltip, target)) { | |||
|
144 | trigger = false; | |||
|
145 | } else if (completer.length > 0 && is_or_has(completer, target)) { | |||
|
146 | trigger = false; | |||
|
147 | } | |||
|
148 | } | |||
|
149 | } | |||
|
150 | if (trigger) { | |||
|
151 | $([IPython.events]).trigger('command_mode.Cell', {'cell':that}); | |||
|
152 | } | |||
|
153 | }, 1); | |||
125 | }; |
|
154 | }; | |
126 | }); |
|
155 | }); | |
127 | if (this.code_mirror) { |
|
156 | if (this.code_mirror) { |
@@ -74,7 +74,7 b' var IPython = (function (IPython) {' | |||||
74 |
|
74 | |||
75 |
|
75 | |||
76 | var cm_overwrite_options = { |
|
76 | var cm_overwrite_options = { | |
77 |
onKeyEvent: $.proxy(this.handle_ |
|
77 | onKeyEvent: $.proxy(this.handle_keyevent,this) | |
78 | }; |
|
78 | }; | |
79 |
|
79 | |||
80 | options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options}); |
|
80 | options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options}); | |
@@ -149,6 +149,17 b' var IPython = (function (IPython) {' | |||||
149 | ); |
|
149 | ); | |
150 | }; |
|
150 | }; | |
151 |
|
151 | |||
|
152 | CodeCell.prototype.handle_keyevent = function (editor, event) { | |||
|
153 | ||||
|
154 | console.log('CM', this.mode, event.which, event.type) | |||
|
155 | ||||
|
156 | if (this.mode === 'command') { | |||
|
157 | return true; | |||
|
158 | } else if (this.mode === 'edit') { | |||
|
159 | return this.handle_codemirror_keyevent(editor, event); | |||
|
160 | } | |||
|
161 | }; | |||
|
162 | ||||
152 | /** |
|
163 | /** | |
153 | * This method gets called in CodeMirror's onKeyDown/onKeyPress |
|
164 | * This method gets called in CodeMirror's onKeyDown/onKeyPress | |
154 | * handlers and is used to provide custom key handling. Its return |
|
165 | * handlers and is used to provide custom key handling. Its return | |
@@ -157,61 +168,55 b' var IPython = (function (IPython) {' | |||||
157 | * @method handle_codemirror_keyevent |
|
168 | * @method handle_codemirror_keyevent | |
158 | */ |
|
169 | */ | |
159 | CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) { |
|
170 | CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) { | |
|
171 | ||||
160 | var that = this; |
|
172 | var that = this; | |
|
173 | // whatever key is pressed, first, cancel the tooltip request before | |||
|
174 | // they are sent, and remove tooltip if any, except for tab again | |||
|
175 | if (event.type === 'keydown' && event.which != key.TAB ) { | |||
|
176 | IPython.tooltip.remove_and_cancel_tooltip(); | |||
|
177 | } | |||
161 |
|
178 | |||
162 | if (this.mode === 'command') { |
|
179 | var cur = editor.getCursor(); | |
163 | return true; |
|
180 | if (event.keyCode === key.ENTER){ | |
164 | } else if (this.mode === 'edit') { |
|
181 | this.auto_highlight(); | |
165 | // whatever key is pressed, first, cancel the tooltip request before |
|
182 | } | |
166 | // they are sent, and remove tooltip if any, except for tab again |
|
|||
167 | if (event.type === 'keydown' && event.which != key.TAB ) { |
|
|||
168 | IPython.tooltip.remove_and_cancel_tooltip(); |
|
|||
169 | }; |
|
|||
170 |
|
||||
171 | var cur = editor.getCursor(); |
|
|||
172 | if (event.keyCode === key.ENTER){ |
|
|||
173 | this.auto_highlight(); |
|
|||
174 | } |
|
|||
175 |
|
183 | |||
176 |
|
|
184 | if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) { | |
177 |
|
|
185 | // Always ignore shift-enter in CodeMirror as we handle it. | |
|
186 | return true; | |||
|
187 | } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) { | |||
|
188 | // triger on keypress (!) otherwise inconsistent event.which depending on plateform | |||
|
189 | // browser and keyboard layout ! | |||
|
190 | // Pressing '(' , request tooltip, don't forget to reappend it | |||
|
191 | // The second argument says to hide the tooltip if the docstring | |||
|
192 | // is actually empty | |||
|
193 | IPython.tooltip.pending(that, true); | |||
|
194 | } else if (event.which === key.UPARROW && event.type === 'keydown') { | |||
|
195 | // If we are not at the top, let CM handle the up arrow and | |||
|
196 | // prevent the global keydown handler from handling it. | |||
|
197 | if (!that.at_top()) { | |||
|
198 | event.stop(); | |||
|
199 | return false; | |||
|
200 | } else { | |||
178 | return true; |
|
201 | return true; | |
179 |
|
|
202 | } | |
180 | } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) { |
|
203 | } else if (event.which === key.ESC) { | |
181 | // triger on keypress (!) otherwise inconsistent event.which depending on plateform |
|
204 | return IPython.tooltip.remove_and_cancel_tooltip(true); | |
182 | // browser and keyboard layout ! |
|
205 | } else if (event.which === key.DOWNARROW && event.type === 'keydown') { | |
183 | // Pressing '(' , request tooltip, don't forget to reappend it |
|
206 | // If we are not at the bottom, let CM handle the down arrow and | |
184 | // The second argument says to hide the tooltip if the docstring |
|
207 | // prevent the global keydown handler from handling it. | |
185 | // is actually empty |
|
208 | if (!that.at_bottom()) { | |
186 | IPython.tooltip.pending(that, true); |
|
209 | event.stop(); | |
187 | } else if (event.which === key.UPARROW && event.type === 'keydown') { |
|
210 | return false; | |
188 | // If we are not at the top, let CM handle the up arrow and |
|
211 | } else { | |
189 | // prevent the global keydown handler from handling it. |
|
|||
190 | if (!that.at_top()) { |
|
|||
191 | event.stop(); |
|
|||
192 | return false; |
|
|||
193 | } else { |
|
|||
194 | return true; |
|
|||
195 | }; |
|
|||
196 | } else if (event.which === key.ESC) { |
|
|||
197 | IPython.tooltip.remove_and_cancel_tooltip(true); |
|
|||
198 | return true; |
|
212 | return true; | |
199 | } else if (event.which === key.DOWNARROW && event.type === 'keydown') { |
|
213 | } | |
200 | // If we are not at the bottom, let CM handle the down arrow and |
|
214 | } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) { | |
201 | // prevent the global keydown handler from handling it. |
|
215 | if (editor.somethingSelected()){ | |
202 | if (!that.at_bottom()) { |
|
216 | var anchor = editor.getCursor("anchor"); | |
203 |
|
|
217 | var head = editor.getCursor("head"); | |
204 | return false; |
|
218 | if( anchor.line != head.line){ | |
205 |
|
|
219 | return false; | |
206 | return true; |
|
|||
207 | }; |
|
|||
208 | } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) { |
|
|||
209 | if (editor.somethingSelected()){ |
|
|||
210 | var anchor = editor.getCursor("anchor"); |
|
|||
211 | var head = editor.getCursor("head"); |
|
|||
212 | if( anchor.line != head.line){ |
|
|||
213 | return false; |
|
|||
214 | } |
|
|||
215 | } |
|
220 | } | |
216 | } |
|
221 | } | |
217 | IPython.tooltip.request(that); |
|
222 | IPython.tooltip.request(that); | |
@@ -229,16 +234,18 b' var IPython = (function (IPython) {' | |||||
229 | // is empty. In this case, let CodeMirror handle indentation. |
|
234 | // is empty. In this case, let CodeMirror handle indentation. | |
230 | return false; |
|
235 | return false; | |
231 | } else { |
|
236 | } else { | |
232 | // keypress/keyup also trigger on TAB press, and we don't want to |
|
237 | event.stop(); | |
233 |
|
|
238 | this.completer.startCompletion(); | |
234 |
return |
|
239 | return true; | |
235 |
} |
|
240 | } | |
|
241 | } else { | |||
|
242 | // keypress/keyup also trigger on TAB press, and we don't want to | |||
|
243 | // use those to disable tab completion. | |||
236 | return false; |
|
244 | return false; | |
237 | } |
|
245 | } | |
238 | return false; |
|
246 | return false; | |
239 | }; |
|
247 | }; | |
240 |
|
248 | |||
241 |
|
||||
242 | // Kernel related calls. |
|
249 | // Kernel related calls. | |
243 |
|
250 | |||
244 | CodeCell.prototype.set_kernel = function (kernel) { |
|
251 | CodeCell.prototype.set_kernel = function (kernel) { |
@@ -244,28 +244,24 b' var IPython = (function (IPython) {' | |||||
244 |
|
244 | |||
245 | //build the container |
|
245 | //build the container | |
246 | var that = this; |
|
246 | var that = this; | |
247 |
|
|
247 | this.sel.dblclick(function () { | |
248 |
|
|
248 | that.pick(); | |
249 |
|
|
249 | }); | |
250 |
|
|
250 | this.sel.blur(this.close); | |
251 |
|
|
251 | this.sel.keydown(function (event) { | |
252 |
|
|
252 | that.keydown(event); | |
253 |
|
|
253 | }); | |
254 |
|
254 | |||
255 | this.build_gui_list(this.raw_result); |
|
255 | this.build_gui_list(this.raw_result); | |
256 |
|
256 | |||
257 | setTimeout(function () { |
|
257 | this.sel.focus(); | |
258 | console.log('doing it'); |
|
|||
259 | that.sel.focus(); |
|
|||
260 | }, 100); |
|
|||
261 | // this.sel.focus(); |
|
|||
262 | // This needs to be after the focus() call because that puts the notebook into |
|
258 | // This needs to be after the focus() call because that puts the notebook into | |
263 | // command mode. |
|
259 | // command mode. | |
264 |
|
|
260 | IPython.keyboard_manager.null_mode(); | |
265 | // Opera sometimes ignores focusing a freshly created node |
|
261 | // Opera sometimes ignores focusing a freshly created node | |
266 |
|
|
262 | if (window.opera) setTimeout(function () { | |
267 |
|
|
263 | if (!this.done) this.sel.focus(); | |
268 |
|
|
264 | }, 100); | |
269 | return true; |
|
265 | return true; | |
270 | } |
|
266 | } | |
271 |
|
267 | |||
@@ -286,7 +282,6 b' var IPython = (function (IPython) {' | |||||
286 | if (this.done) return; |
|
282 | if (this.done) return; | |
287 | this.done = true; |
|
283 | this.done = true; | |
288 | $('.completions').remove(); |
|
284 | $('.completions').remove(); | |
289 | console.log('closing...') |
|
|||
290 | IPython.keyboard_manager.edit_mode(); |
|
285 | IPython.keyboard_manager.edit_mode(); | |
291 | } |
|
286 | } | |
292 |
|
287 | |||
@@ -301,7 +296,6 b' var IPython = (function (IPython) {' | |||||
301 |
|
296 | |||
302 |
|
297 | |||
303 | Completer.prototype.keydown = function (event) { |
|
298 | Completer.prototype.keydown = function (event) { | |
304 | console.log('keydown', event.keyCode); |
|
|||
305 | var code = event.keyCode; |
|
299 | var code = event.keyCode; | |
306 | var that = this; |
|
300 | var that = this; | |
307 | var special_key = false; |
|
301 | var special_key = false; |
@@ -15,8 +15,8 b' var IPython = (function (IPython) {' | |||||
15 | var key = IPython.utils.keycodes; |
|
15 | var key = IPython.utils.keycodes; | |
16 |
|
16 | |||
17 | var KeyboardManager = function () { |
|
17 | var KeyboardManager = function () { | |
18 |
this.mode = ' |
|
18 | this.mode = 'command'; | |
19 |
this.last_mode = ' |
|
19 | this.last_mode = 'command'; | |
20 | this.bind_events(); |
|
20 | this.bind_events(); | |
21 | }; |
|
21 | }; | |
22 |
|
22 | |||
@@ -30,7 +30,7 b' var IPython = (function (IPython) {' | |||||
30 | KeyboardManager.prototype.handle_keydown = function (event) { |
|
30 | KeyboardManager.prototype.handle_keydown = function (event) { | |
31 | var notebook = IPython.notebook; |
|
31 | var notebook = IPython.notebook; | |
32 |
|
32 | |||
33 | console.log('keyboard_manager', this.mode, event); |
|
33 | console.log('keyboard_manager', this.mode, event.keyCode); | |
34 |
|
34 | |||
35 | if (event.which === key.ESC) { |
|
35 | if (event.which === key.ESC) { | |
36 | // Intercept escape at highest level to avoid closing |
|
36 | // Intercept escape at highest level to avoid closing | |
@@ -39,7 +39,7 b' var IPython = (function (IPython) {' | |||||
39 | } |
|
39 | } | |
40 |
|
40 | |||
41 | if (this.mode === 'null') { |
|
41 | if (this.mode === 'null') { | |
42 |
return this.handle_ |
|
42 | return this.handle_null_mode(event); | |
43 | } |
|
43 | } | |
44 |
|
44 | |||
45 | // Event handlers for both command and edit mode |
|
45 | // Event handlers for both command and edit mode | |
@@ -252,16 +252,19 b' var IPython = (function (IPython) {' | |||||
252 | }; |
|
252 | }; | |
253 |
|
253 | |||
254 | KeyboardManager.prototype.edit_mode = function () { |
|
254 | KeyboardManager.prototype.edit_mode = function () { | |
|
255 | console.log('KeyboardManager', 'changing to edit mode'); | |||
255 | this.last_mode = this.mode; |
|
256 | this.last_mode = this.mode; | |
256 | this.mode = 'edit'; |
|
257 | this.mode = 'edit'; | |
257 | } |
|
258 | } | |
258 |
|
259 | |||
259 | KeyboardManager.prototype.command_mode = function () { |
|
260 | KeyboardManager.prototype.command_mode = function () { | |
|
261 | console.log('KeyboardManager', 'changing to command mode'); | |||
260 | this.last_mode = this.mode; |
|
262 | this.last_mode = this.mode; | |
261 | this.mode = 'command'; |
|
263 | this.mode = 'command'; | |
262 | } |
|
264 | } | |
263 |
|
265 | |||
264 | KeyboardManager.prototype.null_mode = function () { |
|
266 | KeyboardManager.prototype.null_mode = function () { | |
|
267 | console.log('KeyboardManager', 'changing to null mode'); | |||
265 | this.last_mode = this.mode; |
|
268 | this.last_mode = this.mode; | |
266 | this.mode = 'null'; |
|
269 | this.mode = 'null'; | |
267 | } |
|
270 | } |
@@ -38,6 +38,8 b' var IPython = (function (IPython) {' | |||||
38 | this.undelete_index = null; |
|
38 | this.undelete_index = null; | |
39 | this.undelete_below = false; |
|
39 | this.undelete_below = false; | |
40 | this.paste_enabled = false; |
|
40 | this.paste_enabled = false; | |
|
41 | // It is important to start out in command mode to match the intial mode | |||
|
42 | // of the KeyboardManager. | |||
41 | this.mode = 'command'; |
|
43 | this.mode = 'command'; | |
42 | this.set_dirty(false); |
|
44 | this.set_dirty(false); | |
43 | this.metadata = {}; |
|
45 | this.metadata = {}; | |
@@ -521,27 +523,27 b' var IPython = (function (IPython) {' | |||||
521 |
|
523 | |||
522 | Notebook.prototype.command_mode = function () { |
|
524 | Notebook.prototype.command_mode = function () { | |
523 | if (this.mode !== 'command') { |
|
525 | if (this.mode !== 'command') { | |
|
526 | console.log('\nNotebook', 'changing to command mode'); | |||
524 | var index = this.get_edit_index(); |
|
527 | var index = this.get_edit_index(); | |
525 | var cell = this.get_cell(index); |
|
528 | var cell = this.get_cell(index); | |
526 | if (cell) { |
|
529 | if (cell) { | |
527 | cell.command_mode(); |
|
530 | cell.command_mode(); | |
528 | this.mode = 'command'; |
|
|||
529 | }; |
|
531 | }; | |
|
532 | this.mode = 'command'; | |||
|
533 | IPython.keyboard_manager.command_mode(); | |||
530 | }; |
|
534 | }; | |
531 | IPython.keyboard_manager.command_mode(); |
|
|||
532 | }; |
|
535 | }; | |
533 |
|
536 | |||
534 | Notebook.prototype.edit_mode = function () { |
|
537 | Notebook.prototype.edit_mode = function () { | |
535 | if (this.mode !== 'edit') { |
|
538 | if (this.mode !== 'edit') { | |
536 | // We are in command mode so get_edit_index() is null!!! |
|
539 | console.log('\nNotebook', 'changing to edit mode'); | |
537 |
var |
|
540 | var cell = this.get_selected_cell(); | |
538 |
if ( |
|
541 | if (cell === null) {return;} // No cell is selected | |
539 | var cell = this.get_cell(index); |
|
542 | // We need to set the mode to edit to prevent reentering this method | |
540 | if (cell) { |
|
543 | // when cell.edit_mode() is called below. | |
541 | cell.edit_mode(); |
|
544 | this.mode = 'edit'; | |
542 | this.mode = 'edit'; |
|
|||
543 | }; |
|
|||
544 | IPython.keyboard_manager.edit_mode(); |
|
545 | IPython.keyboard_manager.edit_mode(); | |
|
546 | cell.edit_mode(); | |||
545 | }; |
|
547 | }; | |
546 | }; |
|
548 | }; | |
547 |
|
549 |
@@ -41,7 +41,7 b' var IPython = (function (IPython) {' | |||||
41 |
|
41 | |||
42 | // we cannot put this as a class key as it has handle to "this". |
|
42 | // we cannot put this as a class key as it has handle to "this". | |
43 | var cm_overwrite_options = { |
|
43 | var cm_overwrite_options = { | |
44 |
onKeyEvent: $.proxy(this.handle_ |
|
44 | onKeyEvent: $.proxy(this.handle_keyevent,this) | |
45 | }; |
|
45 | }; | |
46 |
|
46 | |||
47 | options = this.mergeopt(TextCell,options,{cm_config:cm_overwrite_options}); |
|
47 | options = this.mergeopt(TextCell,options,{cm_config:cm_overwrite_options}); | |
@@ -109,6 +109,16 b' var IPython = (function (IPython) {' | |||||
109 | }); |
|
109 | }); | |
110 | }; |
|
110 | }; | |
111 |
|
111 | |||
|
112 | TextCell.prototype.handle_keyevent = function (editor, event) { | |||
|
113 | ||||
|
114 | console.log('CM', this.mode, event.which, event.type) | |||
|
115 | ||||
|
116 | if (this.mode === 'command') { | |||
|
117 | return true; | |||
|
118 | } else if (this.mode === 'edit') { | |||
|
119 | return this.handle_codemirror_keyevent(editor, event); | |||
|
120 | } | |||
|
121 | }; | |||
112 |
|
122 | |||
113 | /** |
|
123 | /** | |
114 | * This method gets called in CodeMirror's onKeyDown/onKeyPress |
|
124 | * This method gets called in CodeMirror's onKeyDown/onKeyPress | |
@@ -123,33 +133,29 b' var IPython = (function (IPython) {' | |||||
123 | */ |
|
133 | */ | |
124 | TextCell.prototype.handle_codemirror_keyevent = function (editor, event) { |
|
134 | TextCell.prototype.handle_codemirror_keyevent = function (editor, event) { | |
125 | var that = this; |
|
135 | var that = this; | |
126 | if (this.mode === 'command') { |
|
136 | ||
127 | return false |
|
137 | if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey || event.altKey)) { | |
128 | } else if (this.mode === 'edit') { |
|
138 | // Always ignore shift-enter in CodeMirror as we handle it. | |
129 | if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey || event.altKey)) { |
|
139 | return true; | |
130 | // Always ignore shift-enter in CodeMirror as we handle it. |
|
140 | } else if (event.which === key.UPARROW && event.type === 'keydown') { | |
|
141 | // If we are not at the top, let CM handle the up arrow and | |||
|
142 | // prevent the global keydown handler from handling it. | |||
|
143 | if (!that.at_top()) { | |||
|
144 | event.stop(); | |||
|
145 | return false; | |||
|
146 | } else { | |||
131 | return true; |
|
147 | return true; | |
132 | } else if (event.which === key.UPARROW && event.type === 'keydown') { |
|
148 | }; | |
133 | // If we are not at the top, let CM handle the up arrow and |
|
149 | } else if (event.which === key.DOWNARROW && event.type === 'keydown') { | |
134 | // prevent the global keydown handler from handling it. |
|
150 | // If we are not at the bottom, let CM handle the down arrow and | |
135 | if (!that.at_top()) { |
|
151 | // prevent the global keydown handler from handling it. | |
136 | event.stop(); |
|
152 | if (!that.at_bottom()) { | |
137 |
|
|
153 | event.stop(); | |
138 |
|
|
154 | return false; | |
139 | return true; |
|
155 | } else { | |
140 |
|
|
156 | return true; | |
141 | } else if (event.which === key.DOWNARROW && event.type === 'keydown') { |
|
157 | }; | |
142 | // If we are not at the bottom, let CM handle the down arrow and |
|
158 | } | |
143 | // prevent the global keydown handler from handling it. |
|
|||
144 | if (!that.at_bottom()) { |
|
|||
145 | event.stop(); |
|
|||
146 | return false; |
|
|||
147 | } else { |
|
|||
148 | return true; |
|
|||
149 | }; |
|
|||
150 | } |
|
|||
151 | return false; |
|
|||
152 | }; |
|
|||
153 | return false; |
|
159 | return false; | |
154 | }; |
|
160 | }; | |
155 |
|
161 |
General Comments 0
You need to be logged in to leave comments.
Login now