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