##// END OF EJS Templates
go to appropriate line when coming from another cell...
Paul Ivanov -
Show More
@@ -1,606 +1,614 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2011 The IPython Development Team
2 // Copyright (C) 2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Keyboard management
9 // Keyboard management
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13 "use strict";
13 "use strict";
14
14
15 var browser = IPython.utils.browser[0];
15 var browser = IPython.utils.browser[0];
16 var platform = IPython.utils.platform;
16 var platform = IPython.utils.platform;
17
17
18 // Default keyboard shortcuts
18 // Default keyboard shortcuts
19
19
20 var default_common_shortcuts = {
20 var default_common_shortcuts = {
21 'shift' : {
21 'shift' : {
22 help : '',
22 help : '',
23 help_index : '',
23 help_index : '',
24 handler : function (event) {
24 handler : function (event) {
25 // ignore shift keydown
25 // ignore shift keydown
26 return true;
26 return true;
27 }
27 }
28 },
28 },
29 'shift+enter' : {
29 'shift+enter' : {
30 help : 'run cell, select below',
30 help : 'run cell, select below',
31 help_index : 'ba',
31 help_index : 'ba',
32 handler : function (event) {
32 handler : function (event) {
33 IPython.notebook.execute_cell_and_select_below();
33 IPython.notebook.execute_cell_and_select_below();
34 return false;
34 return false;
35 }
35 }
36 },
36 },
37 'ctrl+enter' : {
37 'ctrl+enter' : {
38 help : 'run cell',
38 help : 'run cell',
39 help_index : 'bb',
39 help_index : 'bb',
40 handler : function (event) {
40 handler : function (event) {
41 IPython.notebook.execute_cell();
41 IPython.notebook.execute_cell();
42 return false;
42 return false;
43 }
43 }
44 },
44 },
45 'alt+enter' : {
45 'alt+enter' : {
46 help : 'run cell, insert below',
46 help : 'run cell, insert below',
47 help_index : 'bc',
47 help_index : 'bc',
48 handler : function (event) {
48 handler : function (event) {
49 IPython.notebook.execute_cell_and_insert_below();
49 IPython.notebook.execute_cell_and_insert_below();
50 return false;
50 return false;
51 }
51 }
52 }
52 }
53 };
53 };
54
54
55 if (platform === 'MacOS') {
55 if (platform === 'MacOS') {
56 default_common_shortcuts['cmd+s'] =
56 default_common_shortcuts['cmd+s'] =
57 {
57 {
58 help : 'save notebook',
58 help : 'save notebook',
59 help_index : 'fb',
59 help_index : 'fb',
60 handler : function (event) {
60 handler : function (event) {
61 IPython.notebook.save_checkpoint();
61 IPython.notebook.save_checkpoint();
62 event.preventDefault();
62 event.preventDefault();
63 return false;
63 return false;
64 }
64 }
65 };
65 };
66 } else {
66 } else {
67 default_common_shortcuts['ctrl+s'] =
67 default_common_shortcuts['ctrl+s'] =
68 {
68 {
69 help : 'save notebook',
69 help : 'save notebook',
70 help_index : 'fb',
70 help_index : 'fb',
71 handler : function (event) {
71 handler : function (event) {
72 IPython.notebook.save_checkpoint();
72 IPython.notebook.save_checkpoint();
73 event.preventDefault();
73 event.preventDefault();
74 return false;
74 return false;
75 }
75 }
76 };
76 };
77 }
77 }
78
78
79 // Edit mode defaults
79 // Edit mode defaults
80
80
81 var default_edit_shortcuts = {
81 var default_edit_shortcuts = {
82 'esc' : {
82 'esc' : {
83 help : 'command mode',
83 help : 'command mode',
84 help_index : 'aa',
84 help_index : 'aa',
85 handler : function (event) {
85 handler : function (event) {
86 IPython.notebook.command_mode();
86 IPython.notebook.command_mode();
87 return false;
87 return false;
88 }
88 }
89 },
89 },
90 'ctrl+m' : {
90 'ctrl+m' : {
91 help : 'command mode',
91 help : 'command mode',
92 help_index : 'ab',
92 help_index : 'ab',
93 handler : function (event) {
93 handler : function (event) {
94 IPython.notebook.command_mode();
94 IPython.notebook.command_mode();
95 return false;
95 return false;
96 }
96 }
97 },
97 },
98 'up' : {
98 'up' : {
99 help : '',
99 help : '',
100 help_index : '',
100 help_index : '',
101 handler : function (event) {
101 handler : function (event) {
102 var index = IPython.notebook.get_selected_index();
102 var index = IPython.notebook.get_selected_index();
103 if (index !== null && index !== 0) {
103 if (index !== null && index !== 0) {
104 var cell = IPython.notebook.get_cell(index);
104 var cell = IPython.notebook.get_cell(index);
105 if (cell && cell.at_top()) {
105 if (cell && cell.at_top()) {
106 event.preventDefault();
106 event.preventDefault();
107 IPython.notebook.command_mode();
107 IPython.notebook.command_mode();
108 IPython.notebook.select_prev();
108 IPython.notebook.select_prev();
109 IPython.notebook.edit_mode();
109 IPython.notebook.edit_mode();
110 var cm = IPython.notebook.get_selected_cell().code_mirror;
111 var prev_cursor = cell.code_mirror.getCursor();
112 cm.setCursor(cm.lastLine(), prev_cursor.ch)
110 return false;
113 return false;
111 } else if (cell) {
114 } else if (cell) {
112 var cm = cell.code_mirror;
115 var cm = cell.code_mirror;
113 var cursor = cm.getCursor();
116 var cursor = cm.getCursor();
114 cursor.line -= 1;
117 cursor.line -= 1;
115 cm.setCursor(cursor);
118 cm.setCursor(cursor);
119 return false;
116 }
120 }
117 }
121 }
118 }
122 }
119 },
123 },
120 'down' : {
124 'down' : {
121 help : '',
125 help : '',
122 help_index : '',
126 help_index : '',
123 handler : function (event) {
127 handler : function (event) {
124 var index = IPython.notebook.get_selected_index();
128 var index = IPython.notebook.get_selected_index();
125 if (index !== null && index !== (IPython.notebook.ncells()-1)) {
129 if (index !== null && index !== (IPython.notebook.ncells()-1)) {
126 var cell = IPython.notebook.get_cell(index);
130 var cell = IPython.notebook.get_cell(index);
127 if (cell && cell.at_bottom()) {
131 if (cell && cell.at_bottom()) {
128 event.preventDefault();
132 event.preventDefault();
129 IPython.notebook.command_mode();
133 IPython.notebook.command_mode();
130 IPython.notebook.select_next();
134 IPython.notebook.select_next();
131 IPython.notebook.edit_mode();
135 IPython.notebook.edit_mode();
136 var cm = IPython.notebook.get_selected_cell().code_mirror;
137 var prev_cursor = cell.code_mirror.getCursor();
138 cm.setCursor(0, prev_cursor.ch);
132 return false;
139 return false;
133 } else if (cell) {
140 } else if (cell) {
134 var cm = cell.code_mirror;
141 var cm = cell.code_mirror;
135 var cursor = cm.getCursor();
142 var cursor = cm.getCursor();
136 cursor.line += 1;
143 cursor.line += 1;
137 cm.setCursor(cursor);
144 cm.setCursor(cursor);
145 return false;
138 }
146 }
139 }
147 }
140 }
148 }
141 },
149 },
142 'alt+-' : {
150 'alt+-' : {
143 help : 'split cell',
151 help : 'split cell',
144 help_index : 'ea',
152 help_index : 'ea',
145 handler : function (event) {
153 handler : function (event) {
146 IPython.notebook.split_cell();
154 IPython.notebook.split_cell();
147 return false;
155 return false;
148 }
156 }
149 },
157 },
150 'alt+subtract' : {
158 'alt+subtract' : {
151 help : '',
159 help : '',
152 help_index : 'eb',
160 help_index : 'eb',
153 handler : function (event) {
161 handler : function (event) {
154 IPython.notebook.split_cell();
162 IPython.notebook.split_cell();
155 return false;
163 return false;
156 }
164 }
157 },
165 },
158 'tab' : {
166 'tab' : {
159 help : 'indent or complete',
167 help : 'indent or complete',
160 help_index : 'ec',
168 help_index : 'ec',
161 },
169 },
162 'shift+tab' : {
170 'shift+tab' : {
163 help : 'tooltip',
171 help : 'tooltip',
164 help_index : 'ed',
172 help_index : 'ed',
165 },
173 },
166 };
174 };
167
175
168 if (platform === 'MacOS') {
176 if (platform === 'MacOS') {
169 default_edit_shortcuts['cmd+/'] =
177 default_edit_shortcuts['cmd+/'] =
170 {
178 {
171 help : 'toggle comment',
179 help : 'toggle comment',
172 help_index : 'ee'
180 help_index : 'ee'
173 };
181 };
174 default_edit_shortcuts['cmd+]'] =
182 default_edit_shortcuts['cmd+]'] =
175 {
183 {
176 help : 'indent',
184 help : 'indent',
177 help_index : 'ef'
185 help_index : 'ef'
178 };
186 };
179 default_edit_shortcuts['cmd+['] =
187 default_edit_shortcuts['cmd+['] =
180 {
188 {
181 help : 'dedent',
189 help : 'dedent',
182 help_index : 'eg'
190 help_index : 'eg'
183 };
191 };
184 } else {
192 } else {
185 default_edit_shortcuts['ctrl+/'] =
193 default_edit_shortcuts['ctrl+/'] =
186 {
194 {
187 help : 'toggle comment',
195 help : 'toggle comment',
188 help_index : 'ee'
196 help_index : 'ee'
189 };
197 };
190 default_edit_shortcuts['ctrl+]'] =
198 default_edit_shortcuts['ctrl+]'] =
191 {
199 {
192 help : 'indent',
200 help : 'indent',
193 help_index : 'ef'
201 help_index : 'ef'
194 };
202 };
195 default_edit_shortcuts['ctrl+['] =
203 default_edit_shortcuts['ctrl+['] =
196 {
204 {
197 help : 'dedent',
205 help : 'dedent',
198 help_index : 'eg'
206 help_index : 'eg'
199 };
207 };
200 }
208 }
201
209
202 // Command mode defaults
210 // Command mode defaults
203
211
204 var default_command_shortcuts = {
212 var default_command_shortcuts = {
205 'enter' : {
213 'enter' : {
206 help : 'edit mode',
214 help : 'edit mode',
207 help_index : 'aa',
215 help_index : 'aa',
208 handler : function (event) {
216 handler : function (event) {
209 IPython.notebook.edit_mode();
217 IPython.notebook.edit_mode();
210 return false;
218 return false;
211 }
219 }
212 },
220 },
213 'up' : {
221 'up' : {
214 help : 'select previous cell',
222 help : 'select previous cell',
215 help_index : 'da',
223 help_index : 'da',
216 handler : function (event) {
224 handler : function (event) {
217 var index = IPython.notebook.get_selected_index();
225 var index = IPython.notebook.get_selected_index();
218 if (index !== 0 && index !== null) {
226 if (index !== 0 && index !== null) {
219 IPython.notebook.select_prev();
227 IPython.notebook.select_prev();
220 IPython.notebook.focus_cell();
228 IPython.notebook.focus_cell();
221 }
229 }
222 return false;
230 return false;
223 }
231 }
224 },
232 },
225 'down' : {
233 'down' : {
226 help : 'select next cell',
234 help : 'select next cell',
227 help_index : 'db',
235 help_index : 'db',
228 handler : function (event) {
236 handler : function (event) {
229 var index = IPython.notebook.get_selected_index();
237 var index = IPython.notebook.get_selected_index();
230 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
238 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
231 IPython.notebook.select_next();
239 IPython.notebook.select_next();
232 IPython.notebook.focus_cell();
240 IPython.notebook.focus_cell();
233 }
241 }
234 return false;
242 return false;
235 }
243 }
236 },
244 },
237 'k' : {
245 'k' : {
238 help : 'select previous cell',
246 help : 'select previous cell',
239 help_index : 'dc',
247 help_index : 'dc',
240 handler : function (event) {
248 handler : function (event) {
241 var index = IPython.notebook.get_selected_index();
249 var index = IPython.notebook.get_selected_index();
242 if (index !== 0 && index !== null) {
250 if (index !== 0 && index !== null) {
243 IPython.notebook.select_prev();
251 IPython.notebook.select_prev();
244 IPython.notebook.focus_cell();
252 IPython.notebook.focus_cell();
245 }
253 }
246 return false;
254 return false;
247 }
255 }
248 },
256 },
249 'j' : {
257 'j' : {
250 help : 'select next cell',
258 help : 'select next cell',
251 help_index : 'dd',
259 help_index : 'dd',
252 handler : function (event) {
260 handler : function (event) {
253 var index = IPython.notebook.get_selected_index();
261 var index = IPython.notebook.get_selected_index();
254 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
262 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
255 IPython.notebook.select_next();
263 IPython.notebook.select_next();
256 IPython.notebook.focus_cell();
264 IPython.notebook.focus_cell();
257 }
265 }
258 return false;
266 return false;
259 }
267 }
260 },
268 },
261 'x' : {
269 'x' : {
262 help : 'cut cell',
270 help : 'cut cell',
263 help_index : 'ee',
271 help_index : 'ee',
264 handler : function (event) {
272 handler : function (event) {
265 IPython.notebook.cut_cell();
273 IPython.notebook.cut_cell();
266 return false;
274 return false;
267 }
275 }
268 },
276 },
269 'c' : {
277 'c' : {
270 help : 'copy cell',
278 help : 'copy cell',
271 help_index : 'ef',
279 help_index : 'ef',
272 handler : function (event) {
280 handler : function (event) {
273 IPython.notebook.copy_cell();
281 IPython.notebook.copy_cell();
274 return false;
282 return false;
275 }
283 }
276 },
284 },
277 'shift+v' : {
285 'shift+v' : {
278 help : 'paste cell above',
286 help : 'paste cell above',
279 help_index : 'eg',
287 help_index : 'eg',
280 handler : function (event) {
288 handler : function (event) {
281 IPython.notebook.paste_cell_above();
289 IPython.notebook.paste_cell_above();
282 return false;
290 return false;
283 }
291 }
284 },
292 },
285 'v' : {
293 'v' : {
286 help : 'paste cell below',
294 help : 'paste cell below',
287 help_index : 'eh',
295 help_index : 'eh',
288 handler : function (event) {
296 handler : function (event) {
289 IPython.notebook.paste_cell_below();
297 IPython.notebook.paste_cell_below();
290 return false;
298 return false;
291 }
299 }
292 },
300 },
293 'd' : {
301 'd' : {
294 help : 'delete cell (press twice)',
302 help : 'delete cell (press twice)',
295 help_index : 'ej',
303 help_index : 'ej',
296 count: 2,
304 count: 2,
297 handler : function (event) {
305 handler : function (event) {
298 IPython.notebook.delete_cell();
306 IPython.notebook.delete_cell();
299 return false;
307 return false;
300 }
308 }
301 },
309 },
302 'a' : {
310 'a' : {
303 help : 'insert cell above',
311 help : 'insert cell above',
304 help_index : 'ec',
312 help_index : 'ec',
305 handler : function (event) {
313 handler : function (event) {
306 IPython.notebook.insert_cell_above('code');
314 IPython.notebook.insert_cell_above('code');
307 IPython.notebook.select_prev();
315 IPython.notebook.select_prev();
308 IPython.notebook.focus_cell();
316 IPython.notebook.focus_cell();
309 return false;
317 return false;
310 }
318 }
311 },
319 },
312 'b' : {
320 'b' : {
313 help : 'insert cell below',
321 help : 'insert cell below',
314 help_index : 'ed',
322 help_index : 'ed',
315 handler : function (event) {
323 handler : function (event) {
316 IPython.notebook.insert_cell_below('code');
324 IPython.notebook.insert_cell_below('code');
317 IPython.notebook.select_next();
325 IPython.notebook.select_next();
318 IPython.notebook.focus_cell();
326 IPython.notebook.focus_cell();
319 return false;
327 return false;
320 }
328 }
321 },
329 },
322 'y' : {
330 'y' : {
323 help : 'to code',
331 help : 'to code',
324 help_index : 'ca',
332 help_index : 'ca',
325 handler : function (event) {
333 handler : function (event) {
326 IPython.notebook.to_code();
334 IPython.notebook.to_code();
327 return false;
335 return false;
328 }
336 }
329 },
337 },
330 'm' : {
338 'm' : {
331 help : 'to markdown',
339 help : 'to markdown',
332 help_index : 'cb',
340 help_index : 'cb',
333 handler : function (event) {
341 handler : function (event) {
334 IPython.notebook.to_markdown();
342 IPython.notebook.to_markdown();
335 return false;
343 return false;
336 }
344 }
337 },
345 },
338 'r' : {
346 'r' : {
339 help : 'to raw',
347 help : 'to raw',
340 help_index : 'cc',
348 help_index : 'cc',
341 handler : function (event) {
349 handler : function (event) {
342 IPython.notebook.to_raw();
350 IPython.notebook.to_raw();
343 return false;
351 return false;
344 }
352 }
345 },
353 },
346 '1' : {
354 '1' : {
347 help : 'to heading 1',
355 help : 'to heading 1',
348 help_index : 'cd',
356 help_index : 'cd',
349 handler : function (event) {
357 handler : function (event) {
350 IPython.notebook.to_heading(undefined, 1);
358 IPython.notebook.to_heading(undefined, 1);
351 return false;
359 return false;
352 }
360 }
353 },
361 },
354 '2' : {
362 '2' : {
355 help : 'to heading 2',
363 help : 'to heading 2',
356 help_index : 'ce',
364 help_index : 'ce',
357 handler : function (event) {
365 handler : function (event) {
358 IPython.notebook.to_heading(undefined, 2);
366 IPython.notebook.to_heading(undefined, 2);
359 return false;
367 return false;
360 }
368 }
361 },
369 },
362 '3' : {
370 '3' : {
363 help : 'to heading 3',
371 help : 'to heading 3',
364 help_index : 'cf',
372 help_index : 'cf',
365 handler : function (event) {
373 handler : function (event) {
366 IPython.notebook.to_heading(undefined, 3);
374 IPython.notebook.to_heading(undefined, 3);
367 return false;
375 return false;
368 }
376 }
369 },
377 },
370 '4' : {
378 '4' : {
371 help : 'to heading 4',
379 help : 'to heading 4',
372 help_index : 'cg',
380 help_index : 'cg',
373 handler : function (event) {
381 handler : function (event) {
374 IPython.notebook.to_heading(undefined, 4);
382 IPython.notebook.to_heading(undefined, 4);
375 return false;
383 return false;
376 }
384 }
377 },
385 },
378 '5' : {
386 '5' : {
379 help : 'to heading 5',
387 help : 'to heading 5',
380 help_index : 'ch',
388 help_index : 'ch',
381 handler : function (event) {
389 handler : function (event) {
382 IPython.notebook.to_heading(undefined, 5);
390 IPython.notebook.to_heading(undefined, 5);
383 return false;
391 return false;
384 }
392 }
385 },
393 },
386 '6' : {
394 '6' : {
387 help : 'to heading 6',
395 help : 'to heading 6',
388 help_index : 'ci',
396 help_index : 'ci',
389 handler : function (event) {
397 handler : function (event) {
390 IPython.notebook.to_heading(undefined, 6);
398 IPython.notebook.to_heading(undefined, 6);
391 return false;
399 return false;
392 }
400 }
393 },
401 },
394 'o' : {
402 'o' : {
395 help : 'toggle output',
403 help : 'toggle output',
396 help_index : 'gb',
404 help_index : 'gb',
397 handler : function (event) {
405 handler : function (event) {
398 IPython.notebook.toggle_output();
406 IPython.notebook.toggle_output();
399 return false;
407 return false;
400 }
408 }
401 },
409 },
402 'shift+o' : {
410 'shift+o' : {
403 help : 'toggle output scrolling',
411 help : 'toggle output scrolling',
404 help_index : 'gc',
412 help_index : 'gc',
405 handler : function (event) {
413 handler : function (event) {
406 IPython.notebook.toggle_output_scroll();
414 IPython.notebook.toggle_output_scroll();
407 return false;
415 return false;
408 }
416 }
409 },
417 },
410 's' : {
418 's' : {
411 help : 'save notebook',
419 help : 'save notebook',
412 help_index : 'fa',
420 help_index : 'fa',
413 handler : function (event) {
421 handler : function (event) {
414 IPython.notebook.save_checkpoint();
422 IPython.notebook.save_checkpoint();
415 return false;
423 return false;
416 }
424 }
417 },
425 },
418 'ctrl+j' : {
426 'ctrl+j' : {
419 help : 'move cell down',
427 help : 'move cell down',
420 help_index : 'eb',
428 help_index : 'eb',
421 handler : function (event) {
429 handler : function (event) {
422 IPython.notebook.move_cell_down();
430 IPython.notebook.move_cell_down();
423 return false;
431 return false;
424 }
432 }
425 },
433 },
426 'ctrl+k' : {
434 'ctrl+k' : {
427 help : 'move cell up',
435 help : 'move cell up',
428 help_index : 'ea',
436 help_index : 'ea',
429 handler : function (event) {
437 handler : function (event) {
430 IPython.notebook.move_cell_up();
438 IPython.notebook.move_cell_up();
431 return false;
439 return false;
432 }
440 }
433 },
441 },
434 'l' : {
442 'l' : {
435 help : 'toggle line numbers',
443 help : 'toggle line numbers',
436 help_index : 'ga',
444 help_index : 'ga',
437 handler : function (event) {
445 handler : function (event) {
438 IPython.notebook.cell_toggle_line_numbers();
446 IPython.notebook.cell_toggle_line_numbers();
439 return false;
447 return false;
440 }
448 }
441 },
449 },
442 'i' : {
450 'i' : {
443 help : 'interrupt kernel (press twice)',
451 help : 'interrupt kernel (press twice)',
444 help_index : 'ha',
452 help_index : 'ha',
445 count: 2,
453 count: 2,
446 handler : function (event) {
454 handler : function (event) {
447 IPython.notebook.kernel.interrupt();
455 IPython.notebook.kernel.interrupt();
448 return false;
456 return false;
449 }
457 }
450 },
458 },
451 '0' : {
459 '0' : {
452 help : 'restart kernel (press twice)',
460 help : 'restart kernel (press twice)',
453 help_index : 'hb',
461 help_index : 'hb',
454 count: 2,
462 count: 2,
455 handler : function (event) {
463 handler : function (event) {
456 IPython.notebook.restart_kernel();
464 IPython.notebook.restart_kernel();
457 return false;
465 return false;
458 }
466 }
459 },
467 },
460 'h' : {
468 'h' : {
461 help : 'keyboard shortcuts',
469 help : 'keyboard shortcuts',
462 help_index : 'ge',
470 help_index : 'ge',
463 handler : function (event) {
471 handler : function (event) {
464 IPython.quick_help.show_keyboard_shortcuts();
472 IPython.quick_help.show_keyboard_shortcuts();
465 return false;
473 return false;
466 }
474 }
467 },
475 },
468 'z' : {
476 'z' : {
469 help : 'undo last delete',
477 help : 'undo last delete',
470 help_index : 'ei',
478 help_index : 'ei',
471 handler : function (event) {
479 handler : function (event) {
472 IPython.notebook.undelete_cell();
480 IPython.notebook.undelete_cell();
473 return false;
481 return false;
474 }
482 }
475 },
483 },
476 'shift+m' : {
484 'shift+m' : {
477 help : 'merge cell below',
485 help : 'merge cell below',
478 help_index : 'ek',
486 help_index : 'ek',
479 handler : function (event) {
487 handler : function (event) {
480 IPython.notebook.merge_cell_below();
488 IPython.notebook.merge_cell_below();
481 return false;
489 return false;
482 }
490 }
483 },
491 },
484 'q' : {
492 'q' : {
485 help : 'close pager',
493 help : 'close pager',
486 help_index : 'gd',
494 help_index : 'gd',
487 handler : function (event) {
495 handler : function (event) {
488 IPython.pager.collapse();
496 IPython.pager.collapse();
489 return false;
497 return false;
490 }
498 }
491 },
499 },
492 };
500 };
493
501
494
502
495 // Main keyboard manager for the notebook
503 // Main keyboard manager for the notebook
496
504
497 var ShortcutManager = IPython.keyboard.ShortcutManager;
505 var ShortcutManager = IPython.keyboard.ShortcutManager;
498 var keycodes = IPython.keyboard.keycodes;
506 var keycodes = IPython.keyboard.keycodes;
499
507
500 var KeyboardManager = function () {
508 var KeyboardManager = function () {
501 this.mode = 'command';
509 this.mode = 'command';
502 this.enabled = true;
510 this.enabled = true;
503 this.bind_events();
511 this.bind_events();
504 this.command_shortcuts = new ShortcutManager();
512 this.command_shortcuts = new ShortcutManager();
505 this.command_shortcuts.add_shortcuts(default_common_shortcuts);
513 this.command_shortcuts.add_shortcuts(default_common_shortcuts);
506 this.command_shortcuts.add_shortcuts(default_command_shortcuts);
514 this.command_shortcuts.add_shortcuts(default_command_shortcuts);
507 this.edit_shortcuts = new ShortcutManager();
515 this.edit_shortcuts = new ShortcutManager();
508 this.edit_shortcuts.add_shortcuts(default_common_shortcuts);
516 this.edit_shortcuts.add_shortcuts(default_common_shortcuts);
509 this.edit_shortcuts.add_shortcuts(default_edit_shortcuts);
517 this.edit_shortcuts.add_shortcuts(default_edit_shortcuts);
510 };
518 };
511
519
512 KeyboardManager.prototype.bind_events = function () {
520 KeyboardManager.prototype.bind_events = function () {
513 var that = this;
521 var that = this;
514 $(document).keydown(function (event) {
522 $(document).keydown(function (event) {
515 return that.handle_keydown(event);
523 return that.handle_keydown(event);
516 });
524 });
517 };
525 };
518
526
519 KeyboardManager.prototype.handle_keydown = function (event) {
527 KeyboardManager.prototype.handle_keydown = function (event) {
520 var notebook = IPython.notebook;
528 var notebook = IPython.notebook;
521
529
522 if (event.which === keycodes.esc) {
530 if (event.which === keycodes.esc) {
523 // Intercept escape at highest level to avoid closing
531 // Intercept escape at highest level to avoid closing
524 // websocket connection with firefox
532 // websocket connection with firefox
525 event.preventDefault();
533 event.preventDefault();
526 }
534 }
527
535
528 if (!this.enabled) {
536 if (!this.enabled) {
529 if (event.which === keycodes.esc) {
537 if (event.which === keycodes.esc) {
530 // ESC
538 // ESC
531 notebook.command_mode();
539 notebook.command_mode();
532 return false;
540 return false;
533 }
541 }
534 return true;
542 return true;
535 }
543 }
536
544
537 if (this.mode === 'edit') {
545 if (this.mode === 'edit') {
538 return this.edit_shortcuts.call_handler(event);
546 return this.edit_shortcuts.call_handler(event);
539 } else if (this.mode === 'command') {
547 } else if (this.mode === 'command') {
540 return this.command_shortcuts.call_handler(event);
548 return this.command_shortcuts.call_handler(event);
541 }
549 }
542 return true;
550 return true;
543 };
551 };
544
552
545 KeyboardManager.prototype.edit_mode = function () {
553 KeyboardManager.prototype.edit_mode = function () {
546 this.last_mode = this.mode;
554 this.last_mode = this.mode;
547 this.mode = 'edit';
555 this.mode = 'edit';
548 };
556 };
549
557
550 KeyboardManager.prototype.command_mode = function () {
558 KeyboardManager.prototype.command_mode = function () {
551 this.last_mode = this.mode;
559 this.last_mode = this.mode;
552 this.mode = 'command';
560 this.mode = 'command';
553 };
561 };
554
562
555 KeyboardManager.prototype.enable = function () {
563 KeyboardManager.prototype.enable = function () {
556 this.enabled = true;
564 this.enabled = true;
557 };
565 };
558
566
559 KeyboardManager.prototype.disable = function () {
567 KeyboardManager.prototype.disable = function () {
560 this.enabled = false;
568 this.enabled = false;
561 };
569 };
562
570
563 KeyboardManager.prototype.register_events = function (e) {
571 KeyboardManager.prototype.register_events = function (e) {
564 var that = this;
572 var that = this;
565 var handle_focus = function () {
573 var handle_focus = function () {
566 that.disable();
574 that.disable();
567 };
575 };
568 var handle_blur = function () {
576 var handle_blur = function () {
569 that.enable();
577 that.enable();
570 };
578 };
571 e.on('focusin', handle_focus);
579 e.on('focusin', handle_focus);
572 e.on('focusout', handle_blur);
580 e.on('focusout', handle_blur);
573 // TODO: Very strange. The focusout event does not seem fire for the
581 // TODO: Very strange. The focusout event does not seem fire for the
574 // bootstrap textboxes on FF25&26... This works around that by
582 // bootstrap textboxes on FF25&26... This works around that by
575 // registering focus and blur events recursively on all inputs within
583 // registering focus and blur events recursively on all inputs within
576 // registered element.
584 // registered element.
577 e.find('input').blur(handle_blur);
585 e.find('input').blur(handle_blur);
578 e.on('DOMNodeInserted', function (event) {
586 e.on('DOMNodeInserted', function (event) {
579 var target = $(event.target);
587 var target = $(event.target);
580 if (target.is('input')) {
588 if (target.is('input')) {
581 target.blur(handle_blur);
589 target.blur(handle_blur);
582 } else {
590 } else {
583 target.find('input').blur(handle_blur);
591 target.find('input').blur(handle_blur);
584 }
592 }
585 });
593 });
586 // There are times (raw_input) where we remove the element from the DOM before
594 // There are times (raw_input) where we remove the element from the DOM before
587 // focusout is called. In this case we bind to the remove event of jQueryUI,
595 // focusout is called. In this case we bind to the remove event of jQueryUI,
588 // which gets triggered upon removal, iff it is focused at the time.
596 // which gets triggered upon removal, iff it is focused at the time.
589 // is_focused must be used to check for the case where an element within
597 // is_focused must be used to check for the case where an element within
590 // the element being removed is focused.
598 // the element being removed is focused.
591 e.on('remove', function () {
599 e.on('remove', function () {
592 if (IPython.utils.is_focused(e[0])) {
600 if (IPython.utils.is_focused(e[0])) {
593 that.enable();
601 that.enable();
594 }
602 }
595 });
603 });
596 };
604 };
597
605
598
606
599 IPython.default_common_shortcuts = default_common_shortcuts;
607 IPython.default_common_shortcuts = default_common_shortcuts;
600 IPython.default_edit_shortcuts = default_edit_shortcuts;
608 IPython.default_edit_shortcuts = default_edit_shortcuts;
601 IPython.default_command_shortcuts = default_command_shortcuts;
609 IPython.default_command_shortcuts = default_command_shortcuts;
602 IPython.KeyboardManager = KeyboardManager;
610 IPython.KeyboardManager = KeyboardManager;
603
611
604 return IPython;
612 return IPython;
605
613
606 }(IPython));
614 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now