##// END OF EJS Templates
Fixing delete_count logic.
Brian E. Granger -
Show More
@@ -1,623 +1,621 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 // Setup global keycodes and inverse keycodes.
15 // Setup global keycodes and inverse keycodes.
16
16
17 // See http://unixpapa.com/js/key.html for a complete description. The short of
17 // See http://unixpapa.com/js/key.html for a complete description. The short of
18 // it is that there are different keycode sets. Firefox uses the "Mozilla keycodes"
18 // it is that there are different keycode sets. Firefox uses the "Mozilla keycodes"
19 // and Webkit/IE use the "IE keycodes". These keycode sets are mostly the same
19 // and Webkit/IE use the "IE keycodes". These keycode sets are mostly the same
20 // but have minor differences.
20 // but have minor differences.
21
21
22 // These apply to Firefox, (Webkit and IE)
22 // These apply to Firefox, (Webkit and IE)
23 var _keycodes = {
23 var _keycodes = {
24 'a': 65, 'b': 66, 'c': 67, 'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73,
24 'a': 65, 'b': 66, 'c': 67, 'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73,
25 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'o': 79, 'p': 80, 'q': 81, 'r': 82,
25 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'o': 79, 'p': 80, 'q': 81, 'r': 82,
26 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, 'z': 90,
26 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, 'z': 90,
27 '1 !': 49, '2 @': 50, '3 #': 51, '4 $': 52, '5 %': 53, '6 ^': 54,
27 '1 !': 49, '2 @': 50, '3 #': 51, '4 $': 52, '5 %': 53, '6 ^': 54,
28 '7 &': 55, '8 *': 56, '9 (': 57, '0 )': 48,
28 '7 &': 55, '8 *': 56, '9 (': 57, '0 )': 48,
29 '[ {': 219, '] }': 221, '` ~': 192, ', <': 188, '. >': 190, '/ ?': 191,
29 '[ {': 219, '] }': 221, '` ~': 192, ', <': 188, '. >': 190, '/ ?': 191,
30 '\\ |': 220, '\' "': 222,
30 '\\ |': 220, '\' "': 222,
31 'numpad0': 96, 'numpad1': 97, 'numpad2': 98, 'numpad3': 99, 'numpad4': 100,
31 'numpad0': 96, 'numpad1': 97, 'numpad2': 98, 'numpad3': 99, 'numpad4': 100,
32 'numpad5': 101, 'numpad6': 102, 'numpad7': 103, 'numpad8': 104, 'numpad9': 105,
32 'numpad5': 101, 'numpad6': 102, 'numpad7': 103, 'numpad8': 104, 'numpad9': 105,
33 'multiply': 106, 'add': 107, 'subtract': 109, 'decimal': 110, 'divide': 111,
33 'multiply': 106, 'add': 107, 'subtract': 109, 'decimal': 110, 'divide': 111,
34 'f1': 112, 'f2': 113, 'f3': 114, 'f4': 115, 'f5': 116, 'f6': 117, 'f7': 118,
34 'f1': 112, 'f2': 113, 'f3': 114, 'f4': 115, 'f5': 116, 'f6': 117, 'f7': 118,
35 'f8': 119, 'f9': 120, 'f11': 122, 'f12': 123, 'f13': 124, 'f14': 125, 'f15': 126,
35 'f8': 119, 'f9': 120, 'f11': 122, 'f12': 123, 'f13': 124, 'f14': 125, 'f15': 126,
36 'backspace': 8, 'tab': 9, 'enter': 13, 'shift': 16, 'ctrl': 17, 'alt': 18,
36 'backspace': 8, 'tab': 9, 'enter': 13, 'shift': 16, 'ctrl': 17, 'alt': 18,
37 'meta': 91, 'capslock': 20, 'esc': 27, 'space': 32, 'pageup': 33, 'pagedown': 34,
37 'meta': 91, 'capslock': 20, 'esc': 27, 'space': 32, 'pageup': 33, 'pagedown': 34,
38 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40,
38 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40,
39 'insert': 45, 'delete': 46, 'numlock': 144,
39 'insert': 45, 'delete': 46, 'numlock': 144,
40 };
40 };
41
41
42 // These apply to Firefox and Opera
42 // These apply to Firefox and Opera
43 var _mozilla_keycodes = {
43 var _mozilla_keycodes = {
44 '; :': 59, '= +': 61, '- _': 173, 'meta': 224
44 '; :': 59, '= +': 61, '- _': 173, 'meta': 224
45 }
45 }
46
46
47 // This apply to Webkit and IE
47 // This apply to Webkit and IE
48 var _ie_keycodes = {
48 var _ie_keycodes = {
49 '; :': 186, '= +': 187, '- _': 189,
49 '; :': 186, '= +': 187, '- _': 189,
50 }
50 }
51
51
52 var browser = IPython.utils.browser[0];
52 var browser = IPython.utils.browser[0];
53
53
54 if (browser === 'Firefox' || browser === 'Opera') {
54 if (browser === 'Firefox' || browser === 'Opera') {
55 $.extend(_keycodes, _mozilla_keycodes);
55 $.extend(_keycodes, _mozilla_keycodes);
56 } else if (browser === 'Safari' || browser === 'Chrome' || browser === 'MSIE') {
56 } else if (browser === 'Safari' || browser === 'Chrome' || browser === 'MSIE') {
57 $.extend(_keycodes, _ie_keycodes);
57 $.extend(_keycodes, _ie_keycodes);
58 }
58 }
59
59
60 var keycodes = {};
60 var keycodes = {};
61 var inv_keycodes = {};
61 var inv_keycodes = {};
62 for (var name in _keycodes) {
62 for (var name in _keycodes) {
63 var names = name.split(' ');
63 var names = name.split(' ');
64 if (names.length === 1) {
64 if (names.length === 1) {
65 var n = names[0]
65 var n = names[0]
66 keycodes[n] = _keycodes[n]
66 keycodes[n] = _keycodes[n]
67 inv_keycodes[_keycodes[n]] = n
67 inv_keycodes[_keycodes[n]] = n
68 } else {
68 } else {
69 var primary = names[0];
69 var primary = names[0];
70 var secondary = names[1];
70 var secondary = names[1];
71 keycodes[primary] = _keycodes[name]
71 keycodes[primary] = _keycodes[name]
72 keycodes[secondary] = _keycodes[name]
72 keycodes[secondary] = _keycodes[name]
73 inv_keycodes[_keycodes[name]] = primary
73 inv_keycodes[_keycodes[name]] = primary
74 }
74 }
75 }
75 }
76
76
77
77
78 // Default keyboard shortcuts
78 // Default keyboard shortcuts
79
79
80 var default_common_shortcuts = {
80 var default_common_shortcuts = {
81 'meta+s' : {
81 'meta+s' : {
82 help : 'save notebook',
82 help : 'save notebook',
83 handler : function (event) {
83 handler : function (event) {
84 IPython.notebook.save_checkpoint();
84 IPython.notebook.save_checkpoint();
85 event.preventDefault();
85 event.preventDefault();
86 return false;
86 return false;
87 }
87 }
88 },
88 },
89 'ctrl+s' : {
89 'ctrl+s' : {
90 help : 'save notebook',
90 help : 'save notebook',
91 handler : function (event) {
91 handler : function (event) {
92 IPython.notebook.save_checkpoint();
92 IPython.notebook.save_checkpoint();
93 event.preventDefault();
93 event.preventDefault();
94 return false;
94 return false;
95 }
95 }
96 },
96 },
97 'shift' : {
97 'shift' : {
98 help : '',
98 help : '',
99 handler : function (event) {
99 handler : function (event) {
100 // ignore shift keydown
100 // ignore shift keydown
101 return true;
101 return true;
102 }
102 }
103 },
103 },
104 'shift+enter' : {
104 'shift+enter' : {
105 help : 'run cell',
105 help : 'run cell',
106 handler : function (event) {
106 handler : function (event) {
107 IPython.notebook.execute_cell();
107 IPython.notebook.execute_cell();
108 return false;
108 return false;
109 }
109 }
110 },
110 },
111 'alt+enter' : {
111 'alt+enter' : {
112 help : 'run cell, insert below',
112 help : 'run cell, insert below',
113 handler : function (event) {
113 handler : function (event) {
114 IPython.notebook.execute_cell_and_insert_below();
114 IPython.notebook.execute_cell_and_insert_below();
115 return false;
115 return false;
116 }
116 }
117 },
117 },
118 'ctrl+enter' : {
118 'ctrl+enter' : {
119 help : 'run cell, select below',
119 help : 'run cell, select below',
120 handler : function (event) {
120 handler : function (event) {
121 IPython.notebook.execute_cell_and_select_below();
121 IPython.notebook.execute_cell_and_select_below();
122 return false;
122 return false;
123 }
123 }
124 }
124 }
125 }
125 }
126
126
127 // Edit mode defaults
127 // Edit mode defaults
128
128
129 var default_edit_shortcuts = {
129 var default_edit_shortcuts = {
130 'esc' : {
130 'esc' : {
131 help : 'command mode',
131 help : 'command mode',
132 handler : function (event) {
132 handler : function (event) {
133 IPython.notebook.command_mode();
133 IPython.notebook.command_mode();
134 IPython.notebook.focus_cell();
134 IPython.notebook.focus_cell();
135 return false;
135 return false;
136 }
136 }
137 },
137 },
138 'ctrl+m' : {
138 'ctrl+m' : {
139 help : 'command mode',
139 help : 'command mode',
140 handler : function (event) {
140 handler : function (event) {
141 IPython.notebook.command_mode();
141 IPython.notebook.command_mode();
142 IPython.notebook.focus_cell();
142 IPython.notebook.focus_cell();
143 return false;
143 return false;
144 }
144 }
145 },
145 },
146 'up' : {
146 'up' : {
147 help : 'select previous cell',
147 help : 'select previous cell',
148 handler : function (event) {
148 handler : function (event) {
149 var cell = IPython.notebook.get_selected_cell();
149 var cell = IPython.notebook.get_selected_cell();
150 if (cell && cell.at_top()) {
150 if (cell && cell.at_top()) {
151 event.preventDefault();
151 event.preventDefault();
152 IPython.notebook.command_mode()
152 IPython.notebook.command_mode()
153 IPython.notebook.select_prev();
153 IPython.notebook.select_prev();
154 IPython.notebook.edit_mode();
154 IPython.notebook.edit_mode();
155 return false;
155 return false;
156 };
156 };
157 }
157 }
158 },
158 },
159 'down' : {
159 'down' : {
160 help : 'select next cell',
160 help : 'select next cell',
161 handler : function (event) {
161 handler : function (event) {
162 var cell = IPython.notebook.get_selected_cell();
162 var cell = IPython.notebook.get_selected_cell();
163 if (cell && cell.at_bottom()) {
163 if (cell && cell.at_bottom()) {
164 event.preventDefault();
164 event.preventDefault();
165 IPython.notebook.command_mode()
165 IPython.notebook.command_mode()
166 IPython.notebook.select_next();
166 IPython.notebook.select_next();
167 IPython.notebook.edit_mode();
167 IPython.notebook.edit_mode();
168 return false;
168 return false;
169 };
169 };
170 }
170 }
171 },
171 },
172 'alt+-' : {
172 'alt+-' : {
173 help : 'split cell',
173 help : 'split cell',
174 handler : function (event) {
174 handler : function (event) {
175 IPython.notebook.split_cell();
175 IPython.notebook.split_cell();
176 return false;
176 return false;
177 }
177 }
178 },
178 },
179 'alt+subtract' : {
179 'alt+subtract' : {
180 help : 'split cell',
180 help : 'split cell',
181 handler : function (event) {
181 handler : function (event) {
182 IPython.notebook.split_cell();
182 IPython.notebook.split_cell();
183 return false;
183 return false;
184 }
184 }
185 },
185 },
186 }
186 }
187
187
188 // Command mode defaults
188 // Command mode defaults
189
189
190 var default_command_shortcuts = {
190 var default_command_shortcuts = {
191 'enter' : {
191 'enter' : {
192 help : 'edit mode',
192 help : 'edit mode',
193 handler : function (event) {
193 handler : function (event) {
194 IPython.notebook.edit_mode();
194 IPython.notebook.edit_mode();
195 return false;
195 return false;
196 }
196 }
197 },
197 },
198 'up' : {
198 'up' : {
199 help : 'select previous cell',
199 help : 'select previous cell',
200 handler : function (event) {
200 handler : function (event) {
201 var index = IPython.notebook.get_selected_index();
201 var index = IPython.notebook.get_selected_index();
202 if (index !== 0 && index !== null) {
202 if (index !== 0 && index !== null) {
203 IPython.notebook.select_prev();
203 IPython.notebook.select_prev();
204 var cell = IPython.notebook.get_selected_cell();
204 var cell = IPython.notebook.get_selected_cell();
205 cell.focus_cell();
205 cell.focus_cell();
206 };
206 };
207 return false;
207 return false;
208 }
208 }
209 },
209 },
210 'down' : {
210 'down' : {
211 help : 'select next cell',
211 help : 'select next cell',
212 handler : function (event) {
212 handler : function (event) {
213 var index = IPython.notebook.get_selected_index();
213 var index = IPython.notebook.get_selected_index();
214 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
214 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
215 IPython.notebook.select_next();
215 IPython.notebook.select_next();
216 var cell = IPython.notebook.get_selected_cell();
216 var cell = IPython.notebook.get_selected_cell();
217 cell.focus_cell();
217 cell.focus_cell();
218 };
218 };
219 return false;
219 return false;
220 }
220 }
221 },
221 },
222 'k' : {
222 'k' : {
223 help : 'select previous cell',
223 help : 'select previous cell',
224 handler : function (event) {
224 handler : function (event) {
225 var index = IPython.notebook.get_selected_index();
225 var index = IPython.notebook.get_selected_index();
226 if (index !== 0 && index !== null) {
226 if (index !== 0 && index !== null) {
227 IPython.notebook.select_prev();
227 IPython.notebook.select_prev();
228 var cell = IPython.notebook.get_selected_cell();
228 var cell = IPython.notebook.get_selected_cell();
229 cell.focus_cell();
229 cell.focus_cell();
230 };
230 };
231 return false;
231 return false;
232 }
232 }
233 },
233 },
234 'j' : {
234 'j' : {
235 help : 'select next cell',
235 help : 'select next cell',
236 handler : function (event) {
236 handler : function (event) {
237 var index = IPython.notebook.get_selected_index();
237 var index = IPython.notebook.get_selected_index();
238 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
238 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
239 IPython.notebook.select_next();
239 IPython.notebook.select_next();
240 var cell = IPython.notebook.get_selected_cell();
240 var cell = IPython.notebook.get_selected_cell();
241 cell.focus_cell();
241 cell.focus_cell();
242 };
242 };
243 return false;
243 return false;
244 }
244 }
245 },
245 },
246 'x' : {
246 'x' : {
247 help : 'cut cell',
247 help : 'cut cell',
248 handler : function (event) {
248 handler : function (event) {
249 IPython.notebook.cut_cell();
249 IPython.notebook.cut_cell();
250 return false;
250 return false;
251 }
251 }
252 },
252 },
253 'c' : {
253 'c' : {
254 help : 'copy cell',
254 help : 'copy cell',
255 handler : function (event) {
255 handler : function (event) {
256 IPython.notebook.copy_cell();
256 IPython.notebook.copy_cell();
257 return false;
257 return false;
258 }
258 }
259 },
259 },
260 'v' : {
260 'v' : {
261 help : 'paste cell below',
261 help : 'paste cell below',
262 handler : function (event) {
262 handler : function (event) {
263 IPython.notebook.paste_cell_below();
263 IPython.notebook.paste_cell_below();
264 return false;
264 return false;
265 }
265 }
266 },
266 },
267 'd' : {
267 'd' : {
268 help : 'delete cell (press twice)',
268 help : 'delete cell (press twice)',
269 handler : function (event) {
269 handler : function (event) {
270 var dc = IPython.delete_count;
270 var dc = IPython.keyboard_manager._delete_count;
271 if (dc === undefined) {
271 if (dc === 0) {
272 IPython.delete_count = 1;
272 IPython.keyboard_manager._delete_count = 1;
273 } else if (dc === 0) {
274 IPython.delete_count = 1;
275 setTimeout(function () {
273 setTimeout(function () {
276 IPython.delete_count = 0;
274 IPython.keyboard_manager._delete_count = 0;
277 }, 800);
275 }, 800);
278 } else if (dc === 1) {
276 } else if (dc === 1) {
279 IPython.notebook.delete_cell();
277 IPython.notebook.delete_cell();
280 IPython.delete_count = 0;
278 IPython.keyboard_manager._delete_count = 0;
281 }
279 }
282 return false;
280 return false;
283 }
281 }
284 },
282 },
285 'a' : {
283 'a' : {
286 help : 'insert cell above',
284 help : 'insert cell above',
287 handler : function (event) {
285 handler : function (event) {
288 IPython.notebook.insert_cell_above('code');
286 IPython.notebook.insert_cell_above('code');
289 IPython.notebook.select_prev();
287 IPython.notebook.select_prev();
290 IPython.notebook.focus_cell();
288 IPython.notebook.focus_cell();
291 return false;
289 return false;
292 }
290 }
293 },
291 },
294 'b' : {
292 'b' : {
295 help : 'insert cell below',
293 help : 'insert cell below',
296 handler : function (event) {
294 handler : function (event) {
297 IPython.notebook.insert_cell_below('code');
295 IPython.notebook.insert_cell_below('code');
298 IPython.notebook.select_next();
296 IPython.notebook.select_next();
299 IPython.notebook.focus_cell();
297 IPython.notebook.focus_cell();
300 return false;
298 return false;
301 }
299 }
302 },
300 },
303 'y' : {
301 'y' : {
304 help : 'to code',
302 help : 'to code',
305 handler : function (event) {
303 handler : function (event) {
306 IPython.notebook.to_code();
304 IPython.notebook.to_code();
307 return false;
305 return false;
308 }
306 }
309 },
307 },
310 'm' : {
308 'm' : {
311 help : 'to markdown',
309 help : 'to markdown',
312 handler : function (event) {
310 handler : function (event) {
313 IPython.notebook.to_markdown();
311 IPython.notebook.to_markdown();
314 return false;
312 return false;
315 }
313 }
316 },
314 },
317 't' : {
315 't' : {
318 help : 'to raw',
316 help : 'to raw',
319 handler : function (event) {
317 handler : function (event) {
320 IPython.notebook.to_raw();
318 IPython.notebook.to_raw();
321 return false;
319 return false;
322 }
320 }
323 },
321 },
324 '1' : {
322 '1' : {
325 help : 'to heading 1',
323 help : 'to heading 1',
326 handler : function (event) {
324 handler : function (event) {
327 IPython.notebook.to_heading(undefined, 1);
325 IPython.notebook.to_heading(undefined, 1);
328 return false;
326 return false;
329 }
327 }
330 },
328 },
331 '2' : {
329 '2' : {
332 help : 'to heading 2',
330 help : 'to heading 2',
333 handler : function (event) {
331 handler : function (event) {
334 IPython.notebook.to_heading(undefined, 2);
332 IPython.notebook.to_heading(undefined, 2);
335 return false;
333 return false;
336 }
334 }
337 },
335 },
338 '3' : {
336 '3' : {
339 help : 'to heading 3',
337 help : 'to heading 3',
340 handler : function (event) {
338 handler : function (event) {
341 IPython.notebook.to_heading(undefined, 3);
339 IPython.notebook.to_heading(undefined, 3);
342 return false;
340 return false;
343 }
341 }
344 },
342 },
345 '4' : {
343 '4' : {
346 help : 'to heading 4',
344 help : 'to heading 4',
347 handler : function (event) {
345 handler : function (event) {
348 IPython.notebook.to_heading(undefined, 4);
346 IPython.notebook.to_heading(undefined, 4);
349 return false;
347 return false;
350 }
348 }
351 },
349 },
352 '5' : {
350 '5' : {
353 help : 'to heading 5',
351 help : 'to heading 5',
354 handler : function (event) {
352 handler : function (event) {
355 IPython.notebook.to_heading(undefined, 5);
353 IPython.notebook.to_heading(undefined, 5);
356 return false;
354 return false;
357 }
355 }
358 },
356 },
359 '6' : {
357 '6' : {
360 help : 'to heading 6',
358 help : 'to heading 6',
361 handler : function (event) {
359 handler : function (event) {
362 IPython.notebook.to_heading(undefined, 6);
360 IPython.notebook.to_heading(undefined, 6);
363 return false;
361 return false;
364 }
362 }
365 },
363 },
366 'o' : {
364 'o' : {
367 help : 'toggle output',
365 help : 'toggle output',
368 handler : function (event) {
366 handler : function (event) {
369 IPython.notebook.toggle_output();
367 IPython.notebook.toggle_output();
370 return false;
368 return false;
371 }
369 }
372 },
370 },
373 'shift+o' : {
371 'shift+o' : {
374 help : 'toggle output',
372 help : 'toggle output',
375 handler : function (event) {
373 handler : function (event) {
376 IPython.notebook.toggle_output_scroll();
374 IPython.notebook.toggle_output_scroll();
377 return false;
375 return false;
378 }
376 }
379 },
377 },
380 's' : {
378 's' : {
381 help : 'save notebook',
379 help : 'save notebook',
382 handler : function (event) {
380 handler : function (event) {
383 IPython.notebook.save_checkpoint();
381 IPython.notebook.save_checkpoint();
384 return false;
382 return false;
385 }
383 }
386 },
384 },
387 'ctrl+j' : {
385 'ctrl+j' : {
388 help : 'move cell down',
386 help : 'move cell down',
389 handler : function (event) {
387 handler : function (event) {
390 IPython.notebook.move_cell_down();
388 IPython.notebook.move_cell_down();
391 return false;
389 return false;
392 }
390 }
393 },
391 },
394 'ctrl+k' : {
392 'ctrl+k' : {
395 help : 'move cell up',
393 help : 'move cell up',
396 handler : function (event) {
394 handler : function (event) {
397 IPython.notebook.move_cell_up();
395 IPython.notebook.move_cell_up();
398 return false;
396 return false;
399 }
397 }
400 },
398 },
401 'l' : {
399 'l' : {
402 help : 'toggle line numbers',
400 help : 'toggle line numbers',
403 handler : function (event) {
401 handler : function (event) {
404 IPython.notebook.cell_toggle_line_numbers();
402 IPython.notebook.cell_toggle_line_numbers();
405 return false;
403 return false;
406 }
404 }
407 },
405 },
408 'i' : {
406 'i' : {
409 help : 'interrupt kernel',
407 help : 'interrupt kernel',
410 handler : function (event) {
408 handler : function (event) {
411 IPython.notebook.kernel.interrupt();
409 IPython.notebook.kernel.interrupt();
412 return false;
410 return false;
413 }
411 }
414 },
412 },
415 '.' : {
413 '.' : {
416 help : 'restart kernel',
414 help : 'restart kernel',
417 handler : function (event) {
415 handler : function (event) {
418 IPython.notebook.restart_kernel();
416 IPython.notebook.restart_kernel();
419 return false;
417 return false;
420 }
418 }
421 },
419 },
422 'h' : {
420 'h' : {
423 help : 'keyboard shortcuts',
421 help : 'keyboard shortcuts',
424 handler : function (event) {
422 handler : function (event) {
425 IPython.quick_help.show_keyboard_shortcuts();
423 IPython.quick_help.show_keyboard_shortcuts();
426 return false;
424 return false;
427 }
425 }
428 },
426 },
429 'z' : {
427 'z' : {
430 help : 'undo last delete',
428 help : 'undo last delete',
431 handler : function (event) {
429 handler : function (event) {
432 IPython.notebook.undelete_cell();
430 IPython.notebook.undelete_cell();
433 return false;
431 return false;
434 }
432 }
435 },
433 },
436 'shift+=' : {
434 'shift+=' : {
437 help : 'merge cell below',
435 help : 'merge cell below',
438 handler : function (event) {
436 handler : function (event) {
439 IPython.notebook.merge_cell_below();
437 IPython.notebook.merge_cell_below();
440 return false;
438 return false;
441 }
439 }
442 },
440 },
443 }
441 }
444
442
445
443
446 // Shortcut manager class
444 // Shortcut manager class
447
445
448 var ShortcutManager = function () {
446 var ShortcutManager = function () {
449 this._shortcuts = {}
447 this._shortcuts = {}
450 }
448 }
451
449
452 ShortcutManager.prototype.help = function () {
450 ShortcutManager.prototype.help = function () {
453 var help = [];
451 var help = [];
454 for (var shortcut in this._shortcuts) {
452 for (var shortcut in this._shortcuts) {
455 help.push({shortcut: shortcut, help: this._shortcuts[shortcut]['help']});
453 help.push({shortcut: shortcut, help: this._shortcuts[shortcut]['help']});
456 }
454 }
457 return help;
455 return help;
458 }
456 }
459
457
460 ShortcutManager.prototype.canonicalize_key = function (key) {
458 ShortcutManager.prototype.canonicalize_key = function (key) {
461 return inv_keycodes[keycodes[key]];
459 return inv_keycodes[keycodes[key]];
462 }
460 }
463
461
464 ShortcutManager.prototype.canonicalize_shortcut = function (shortcut) {
462 ShortcutManager.prototype.canonicalize_shortcut = function (shortcut) {
465 // Sort a sequence of + separated modifiers into the order alt+ctrl+meta+shift
463 // Sort a sequence of + separated modifiers into the order alt+ctrl+meta+shift
466 var values = shortcut.split("+");
464 var values = shortcut.split("+");
467 if (values.length === 1) {
465 if (values.length === 1) {
468 return this.canonicalize_key(values[0])
466 return this.canonicalize_key(values[0])
469 } else {
467 } else {
470 var modifiers = values.slice(0,-1);
468 var modifiers = values.slice(0,-1);
471 var key = this.canonicalize_key(values[values.length-1]);
469 var key = this.canonicalize_key(values[values.length-1]);
472 modifiers.sort();
470 modifiers.sort();
473 return modifiers.join('+') + '+' + key;
471 return modifiers.join('+') + '+' + key;
474 }
472 }
475 }
473 }
476
474
477 ShortcutManager.prototype.event_to_shortcut = function (event) {
475 ShortcutManager.prototype.event_to_shortcut = function (event) {
478 // Convert a jQuery keyboard event to a strong based keyboard shortcut
476 // Convert a jQuery keyboard event to a strong based keyboard shortcut
479 var shortcut = '';
477 var shortcut = '';
480 var key = inv_keycodes[event.which]
478 var key = inv_keycodes[event.which]
481 if (event.altKey && key !== 'alt') {shortcut += 'alt+';}
479 if (event.altKey && key !== 'alt') {shortcut += 'alt+';}
482 if (event.ctrlKey && key !== 'ctrl') {shortcut += 'ctrl+';}
480 if (event.ctrlKey && key !== 'ctrl') {shortcut += 'ctrl+';}
483 if (event.metaKey && key !== 'meta') {shortcut += 'meta+';}
481 if (event.metaKey && key !== 'meta') {shortcut += 'meta+';}
484 if (event.shiftKey && key !== 'shift') {shortcut += 'shift+';}
482 if (event.shiftKey && key !== 'shift') {shortcut += 'shift+';}
485 shortcut += key;
483 shortcut += key;
486 return shortcut
484 return shortcut
487 }
485 }
488
486
489 ShortcutManager.prototype.clear_shortcuts = function () {
487 ShortcutManager.prototype.clear_shortcuts = function () {
490 this._shortcuts = {};
488 this._shortcuts = {};
491 }
489 }
492
490
493 ShortcutManager.prototype.add_shortcut = function (shortcut, data) {
491 ShortcutManager.prototype.add_shortcut = function (shortcut, data) {
494 shortcut = this.canonicalize_shortcut(shortcut);
492 shortcut = this.canonicalize_shortcut(shortcut);
495 this._shortcuts[shortcut] = data;
493 this._shortcuts[shortcut] = data;
496 }
494 }
497
495
498 ShortcutManager.prototype.add_shortcuts = function (data) {
496 ShortcutManager.prototype.add_shortcuts = function (data) {
499 for (var shortcut in data) {
497 for (var shortcut in data) {
500 this.add_shortcut(shortcut, data[shortcut]);
498 this.add_shortcut(shortcut, data[shortcut]);
501 }
499 }
502 }
500 }
503
501
504 ShortcutManager.prototype.remove_shortcut = function (shortcut) {
502 ShortcutManager.prototype.remove_shortcut = function (shortcut) {
505 shortcut = this.canonicalize_shortcut(shortcut);
503 shortcut = this.canonicalize_shortcut(shortcut);
506 delete this._shortcuts[shortcut];
504 delete this._shortcuts[shortcut];
507 }
505 }
508
506
509 ShortcutManager.prototype.call_handler = function (event) {
507 ShortcutManager.prototype.call_handler = function (event) {
510 var shortcut = this.event_to_shortcut(event);
508 var shortcut = this.event_to_shortcut(event);
511 var data = this._shortcuts[shortcut];
509 var data = this._shortcuts[shortcut];
512 if (data !== undefined) {
510 if (data !== undefined) {
513 var handler = data['handler'];
511 var handler = data['handler'];
514 if (handler !== undefined) {
512 if (handler !== undefined) {
515 return handler(event);
513 return handler(event);
516 }
514 }
517 }
515 }
518 return true;
516 return true;
519 }
517 }
520
518
521
519
522
520
523 // Main keyboard manager for the notebook
521 // Main keyboard manager for the notebook
524
522
525 var KeyboardManager = function () {
523 var KeyboardManager = function () {
526 this.mode = 'command';
524 this.mode = 'command';
527 this.enabled = true;
525 this.enabled = true;
528 this.delete_count = 0;
526 this._delete_count = 0;
529 this.bind_events();
527 this.bind_events();
530 this.command_shortcuts = new ShortcutManager();
528 this.command_shortcuts = new ShortcutManager();
531 this.command_shortcuts.add_shortcuts(default_common_shortcuts);
529 this.command_shortcuts.add_shortcuts(default_common_shortcuts);
532 this.command_shortcuts.add_shortcuts(default_command_shortcuts);
530 this.command_shortcuts.add_shortcuts(default_command_shortcuts);
533 this.edit_shortcuts = new ShortcutManager();
531 this.edit_shortcuts = new ShortcutManager();
534 this.edit_shortcuts.add_shortcuts(default_common_shortcuts);
532 this.edit_shortcuts.add_shortcuts(default_common_shortcuts);
535 this.edit_shortcuts.add_shortcuts(default_edit_shortcuts);
533 this.edit_shortcuts.add_shortcuts(default_edit_shortcuts);
536 };
534 };
537
535
538 KeyboardManager.prototype.bind_events = function () {
536 KeyboardManager.prototype.bind_events = function () {
539 var that = this;
537 var that = this;
540 $(document).keydown(function (event) {
538 $(document).keydown(function (event) {
541 return that.handle_keydown(event);
539 return that.handle_keydown(event);
542 });
540 });
543 };
541 };
544
542
545 KeyboardManager.prototype.handle_keydown = function (event) {
543 KeyboardManager.prototype.handle_keydown = function (event) {
546 var notebook = IPython.notebook;
544 var notebook = IPython.notebook;
547
545
548 console.log('keyboard_manager', this.mode, event.keyCode);
546 console.log('keyboard_manager', this.mode, event.keyCode);
549
547
550 if (event.which === keycodes['esc']) {
548 if (event.which === keycodes['esc']) {
551 // Intercept escape at highest level to avoid closing
549 // Intercept escape at highest level to avoid closing
552 // websocket connection with firefox
550 // websocket connection with firefox
553 event.preventDefault();
551 event.preventDefault();
554 }
552 }
555
553
556 if (!this.enabled) {
554 if (!this.enabled) {
557 if (event.which === keycodes['esc']) {
555 if (event.which === keycodes['esc']) {
558 // ESC
556 // ESC
559 notebook.command_mode();
557 notebook.command_mode();
560 return false;
558 return false;
561 }
559 }
562 return true;
560 return true;
563 }
561 }
564
562
565 if (this.mode === 'edit') {
563 if (this.mode === 'edit') {
566 return this.edit_shortcuts.call_handler(event);
564 return this.edit_shortcuts.call_handler(event);
567 } else if (this.mode === 'command') {
565 } else if (this.mode === 'command') {
568 return this.command_shortcuts.call_handler(event);
566 return this.command_shortcuts.call_handler(event);
569 }
567 }
570 return true;
568 return true;
571 }
569 }
572
570
573 KeyboardManager.prototype.edit_mode = function () {
571 KeyboardManager.prototype.edit_mode = function () {
574 console.log('KeyboardManager', 'changing to edit mode');
572 console.log('KeyboardManager', 'changing to edit mode');
575 this.last_mode = this.mode;
573 this.last_mode = this.mode;
576 this.mode = 'edit';
574 this.mode = 'edit';
577 }
575 }
578
576
579 KeyboardManager.prototype.command_mode = function () {
577 KeyboardManager.prototype.command_mode = function () {
580 console.log('KeyboardManager', 'changing to command mode');
578 console.log('KeyboardManager', 'changing to command mode');
581 this.last_mode = this.mode;
579 this.last_mode = this.mode;
582 this.mode = 'command';
580 this.mode = 'command';
583 }
581 }
584
582
585 KeyboardManager.prototype.enable = function () {
583 KeyboardManager.prototype.enable = function () {
586 this.enabled = true;
584 this.enabled = true;
587 }
585 }
588
586
589 KeyboardManager.prototype.disable = function () {
587 KeyboardManager.prototype.disable = function () {
590 this.enabled = false;
588 this.enabled = false;
591 }
589 }
592
590
593 KeyboardManager.prototype.register_events = function (e) {
591 KeyboardManager.prototype.register_events = function (e) {
594 var that = this;
592 var that = this;
595 e.on('focusin', function () {
593 e.on('focusin', function () {
596 that.command_mode();
594 that.command_mode();
597 that.disable();
595 that.disable();
598 });
596 });
599 e.on('focusout', function () {
597 e.on('focusout', function () {
600 that.command_mode();
598 that.command_mode();
601 that.enable();
599 that.enable();
602 });
600 });
603 // There are times (raw_input) where we remove the element from the DOM before
601 // There are times (raw_input) where we remove the element from the DOM before
604 // focusout is called. In this case we bind to the remove event of jQueryUI,
602 // focusout is called. In this case we bind to the remove event of jQueryUI,
605 // which gets triggered upon removal.
603 // which gets triggered upon removal.
606 e.on('remove', function () {
604 e.on('remove', function () {
607 that.command_mode();
605 that.command_mode();
608 that.enable();
606 that.enable();
609 });
607 });
610 }
608 }
611
609
612
610
613 IPython.keycodes = keycodes;
611 IPython.keycodes = keycodes;
614 IPython.inv_keycodes = inv_keycodes;
612 IPython.inv_keycodes = inv_keycodes;
615 IPython.default_common_shortcuts = default_common_shortcuts;
613 IPython.default_common_shortcuts = default_common_shortcuts;
616 IPython.default_edit_shortcuts = default_edit_shortcuts;
614 IPython.default_edit_shortcuts = default_edit_shortcuts;
617 IPython.default_command_shortcuts = default_command_shortcuts;
615 IPython.default_command_shortcuts = default_command_shortcuts;
618 IPython.ShortcutManager = ShortcutManager;
616 IPython.ShortcutManager = ShortcutManager;
619 IPython.KeyboardManager = KeyboardManager;
617 IPython.KeyboardManager = KeyboardManager;
620
618
621 return IPython;
619 return IPython;
622
620
623 }(IPython));
621 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now