##// END OF EJS Templates
Removing KBN null mode and replacing with enable/disable.
Brian E. Granger -
Show More
@@ -1,146 +1,147 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2013 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Utility for modal dialogs with bootstrap
10 10 //============================================================================
11 11
12 12 IPython.namespace('IPython.dialog');
13 13
14 14 IPython.dialog = (function (IPython) {
15 15 "use strict";
16 16
17 17 var modal = function (options) {
18 18 var dialog = $("<div/>").addClass("modal").attr("role", "dialog");
19 19 dialog.append(
20 20 $("<div/>")
21 21 .addClass("modal-header")
22 22 .append($("<button>")
23 23 .addClass("close")
24 24 .attr("data-dismiss", "modal")
25 25 .html("&times;")
26 26 ).append(
27 27 $("<h3/>").text(options.title || "")
28 28 )
29 29 ).append(
30 30 $("<div/>").addClass("modal-body").append(
31 31 options.body || $("<p/>")
32 32 )
33 33 );
34 34
35 35 var footer = $("<div/>").addClass("modal-footer");
36 36
37 37 for (var label in options.buttons) {
38 38 var btn_opts = options.buttons[label];
39 39 var button = $("<button/>")
40 40 .addClass("btn")
41 41 .attr("data-dismiss", "modal")
42 42 .text(label);
43 43 if (btn_opts.click) {
44 44 button.click($.proxy(btn_opts.click, dialog));
45 45 }
46 46 if (btn_opts.class) {
47 47 button.addClass(btn_opts.class);
48 48 }
49 49 footer.append(button);
50 50 }
51 51 dialog.append(footer);
52 52 // hook up on-open event
53 53 dialog.on("shown", function() {
54 54 setTimeout(function() {
55 55 footer.find("button").last().focus();
56 56 if (options.open) {
57 57 $.proxy(options.open, dialog)();
58 58 }
59 59 }, 0);
60 60 });
61 61
62 62 // destroy dialog on hide, unless explicitly asked not to
63 63 if (options.destroy === undefined || options.destroy) {
64 64 dialog.on("hidden", function () {
65 65 dialog.remove();
66 66 });
67 67 }
68 68 dialog.on("hidden", function () {
69 69 if (IPython.notebook) {
70 70 var cell = IPython.notebook.get_selected_cell();
71 71 if (cell) cell.select();
72 IPython.keyboard_manager.enable();
72 73 IPython.keyboard_manager.command_mode();
73 74 }
74 75 });
75 76
76 77 if (IPython.keyboard_manager) {
77 IPython.keyboard_manager.null_mode();
78 IPython.keyboard_manager.disable();
78 79 }
79 80
80 81 return dialog.modal(options);
81 82 };
82 83
83 84 var edit_metadata = function (md, callback, name) {
84 85 name = name || "Cell";
85 86 var error_div = $('<div/>').css('color', 'red');
86 87 var message =
87 88 "Manually edit the JSON below to manipulate the metadata for this " + name + "." +
88 89 " We recommend putting custom metadata attributes in an appropriately named sub-structure," +
89 90 " so they don't conflict with those of others.";
90 91
91 92 var textarea = $('<textarea/>')
92 93 .attr('rows', '13')
93 94 .attr('cols', '80')
94 95 .attr('name', 'metadata')
95 96 .text(JSON.stringify(md || {}, null, 2));
96 97
97 98 var dialogform = $('<div/>').attr('title', 'Edit the metadata')
98 99 .append(
99 100 $('<form/>').append(
100 101 $('<fieldset/>').append(
101 102 $('<label/>')
102 103 .attr('for','metadata')
103 104 .text(message)
104 105 )
105 106 .append(error_div)
106 107 .append($('<br/>'))
107 108 .append(textarea)
108 109 )
109 110 );
110 111 var editor = CodeMirror.fromTextArea(textarea[0], {
111 112 lineNumbers: true,
112 113 matchBrackets: true,
113 114 indentUnit: 2,
114 115 autoIndent: true,
115 116 mode: 'application/json',
116 117 });
117 118 IPython.dialog.modal({
118 119 title: "Edit " + name + " Metadata",
119 120 body: dialogform,
120 121 buttons: {
121 122 OK: { class : "btn-primary",
122 123 click: function() {
123 124 // validate json and set it
124 125 var new_md;
125 126 try {
126 127 new_md = JSON.parse(editor.getValue());
127 128 } catch(e) {
128 129 console.log(e);
129 130 error_div.text('WARNING: Could not save invalid JSON.');
130 131 return false;
131 132 }
132 133 callback(new_md);
133 134 }
134 135 },
135 136 Cancel: {}
136 137 }
137 138 });
138 139 editor.refresh();
139 140 };
140 141
141 142 return {
142 143 modal : modal,
143 144 edit_metadata : edit_metadata,
144 145 };
145 146
146 147 }(IPython));
@@ -1,357 +1,357 b''
1 1 // function completer.
2 2 //
3 3 // completer should be a class that takes an cell instance
4 4 var IPython = (function (IPython) {
5 5 // that will prevent us from misspelling
6 6 "use strict";
7 7
8 8 // easier key mapping
9 9 var key = IPython.utils.keycodes;
10 10
11 11 function prepend_n_prc(str, n) {
12 12 for( var i =0 ; i< n ; i++){
13 13 str = '%'+str ;
14 14 }
15 15 return str;
16 16 }
17 17
18 18 function _existing_completion(item, completion_array){
19 19 for( var c in completion_array ) {
20 20 if(completion_array[c].trim().substr(-item.length) == item)
21 21 { return true; }
22 22 }
23 23 return false;
24 24 }
25 25
26 26 // what is the common start of all completions
27 27 function shared_start(B, drop_prct) {
28 28 if (B.length == 1) {
29 29 return B[0];
30 30 }
31 31 var A = new Array();
32 32 var common;
33 33 var min_lead_prct = 10;
34 34 for (var i = 0; i < B.length; i++) {
35 35 var str = B[i].str;
36 36 var localmin = 0;
37 37 if(drop_prct === true){
38 38 while ( str.substr(0, 1) == '%') {
39 39 localmin = localmin+1;
40 40 str = str.substring(1);
41 41 }
42 42 }
43 43 min_lead_prct = Math.min(min_lead_prct, localmin);
44 44 A.push(str);
45 45 }
46 46
47 47 if (A.length > 1) {
48 48 var tem1, tem2, s;
49 49 A = A.slice(0).sort();
50 50 tem1 = A[0];
51 51 s = tem1.length;
52 52 tem2 = A.pop();
53 53 while (s && tem2.indexOf(tem1) == -1) {
54 54 tem1 = tem1.substring(0, --s);
55 55 }
56 56 if (tem1 === "" || tem2.indexOf(tem1) !== 0) {
57 57 return {
58 58 str:prepend_n_prc('', min_lead_prct),
59 59 type: "computed",
60 60 from: B[0].from,
61 61 to: B[0].to
62 62 };
63 63 }
64 64 return {
65 65 str: prepend_n_prc(tem1, min_lead_prct),
66 66 type: "computed",
67 67 from: B[0].from,
68 68 to: B[0].to
69 69 };
70 70 }
71 71 return null;
72 72 }
73 73
74 74
75 75 var Completer = function (cell) {
76 76 this.cell = cell;
77 77 this.editor = cell.code_mirror;
78 78 var that = this;
79 79 $([IPython.events]).on('status_busy.Kernel', function () {
80 80 that.skip_kernel_completion = true;
81 81 });
82 82 $([IPython.events]).on('status_idle.Kernel', function () {
83 83 that.skip_kernel_completion = false;
84 84 });
85 85 };
86 86
87 87
88 88 Completer.prototype.startCompletion = function () {
89 89 // call for a 'first' completion, that will set the editor and do some
90 90 // special behaviour like autopicking if only one completion availlable
91 91 //
92 92 if (this.editor.somethingSelected()) return;
93 93 this.done = false;
94 94 // use to get focus back on opera
95 95 this.carry_on_completion(true);
96 96 };
97 97
98 98
99 99 // easy access for julia to monkeypatch
100 100 //
101 101 Completer.reinvoke_re = /[%0-9a-z._/\\:~-]/i;
102 102
103 103 Completer.prototype.reinvoke= function(pre_cursor, block, cursor){
104 104 return Completer.reinvoke_re.test(pre_cursor);
105 105 }
106 106
107 107 /**
108 108 *
109 109 * pass true as parameter if this is the first invocation of the completer
110 110 * this will prevent the completer to dissmiss itself if it is not on a
111 111 * word boundary like pressing tab after a space, and make it autopick the
112 112 * only choice if there is only one which prevent from popping the UI. as
113 113 * well as fast-forwarding the typing if all completion have a common
114 114 * shared start
115 115 **/
116 116 Completer.prototype.carry_on_completion = function (first_invocation) {
117 117 // Pass true as parameter if you want the completer to autopick when
118 118 // only one completion. This function is automatically reinvoked at
119 119 // each keystroke with first_invocation = false
120 120 var cur = this.editor.getCursor();
121 121 var line = this.editor.getLine(cur.line);
122 122 var pre_cursor = this.editor.getRange({
123 123 line: cur.line,
124 124 ch: cur.ch - 1
125 125 }, cur);
126 126
127 127 // we need to check that we are still on a word boundary
128 128 // because while typing the completer is still reinvoking itself
129 129 // so dismiss if we are on a "bad" caracter
130 130 if (!this.reinvoke(pre_cursor) && !first_invocation) {
131 131 this.close();
132 132 return;
133 133 }
134 134
135 135 this.autopick = false;
136 136 if (first_invocation) {
137 137 this.autopick = true;
138 138 }
139 139
140 140 // We want a single cursor position.
141 141 if (this.editor.somethingSelected()) {
142 142 return;
143 143 };
144 144
145 145 // one kernel completion came back, finish_completing will be called with the results
146 146 // we fork here and directly call finish completing if kernel is busy
147 147 if (this.skip_kernel_completion == true) {
148 148 this.finish_completing({
149 149 'matches': [],
150 150 matched_text: ""
151 151 })
152 152 } else {
153 153 this.cell.kernel.complete(line, cur.ch, $.proxy(this.finish_completing, this));
154 154 }
155 155 };
156 156
157 157 Completer.prototype.finish_completing = function (msg) {
158 158 // let's build a function that wrap all that stuff into what is needed
159 159 // for the new completer:
160 160 var content = msg.content;
161 161 var matched_text = content.matched_text;
162 162 var matches = content.matches;
163 163
164 164 var cur = this.editor.getCursor();
165 165 var results = CodeMirror.contextHint(this.editor);
166 166 var filterd_results = Array();
167 167 //remove results from context completion
168 168 //that are already in kernel completion
169 169 for(var elm in results) {
170 170 if(_existing_completion(results[elm]['str'], matches) == false)
171 171 { filterd_results.push(results[elm]); }
172 172 }
173 173
174 174 // append the introspection result, in order, at at the beginning of
175 175 // the table and compute the replacement range from current cursor
176 176 // positon and matched_text length.
177 177 for (var i = matches.length - 1; i >= 0; --i) {
178 178 filterd_results.unshift({
179 179 str: matches[i],
180 180 type: "introspection",
181 181 from: {
182 182 line: cur.line,
183 183 ch: cur.ch - matched_text.length
184 184 },
185 185 to: {
186 186 line: cur.line,
187 187 ch: cur.ch
188 188 }
189 189 });
190 190 }
191 191
192 192 // one the 2 sources results have been merge, deal with it
193 193 this.raw_result = filterd_results;
194 194
195 195 // if empty result return
196 196 if (!this.raw_result || !this.raw_result.length) return;
197 197
198 198 // When there is only one completion, use it directly.
199 199 if (this.autopick == true && this.raw_result.length == 1) {
200 200 this.insert(this.raw_result[0]);
201 201 return;
202 202 }
203 203
204 204 if (this.raw_result.length == 1) {
205 205 // test if first and only completion totally matches
206 206 // what is typed, in this case dismiss
207 207 var str = this.raw_result[0].str;
208 208 var pre_cursor = this.editor.getRange({
209 209 line: cur.line,
210 210 ch: cur.ch - str.length
211 211 }, cur);
212 212 if (pre_cursor == str) {
213 213 this.close();
214 214 return;
215 215 }
216 216 }
217 217
218 218 this.complete = $('<div/>').addClass('completions');
219 219 this.complete.attr('id', 'complete');
220 220
221 221 // Currently webkit doesn't use the size attr correctly. See:
222 222 // https://code.google.com/p/chromium/issues/detail?id=4579
223 223 this.sel = $('<select style="width: auto"/>')
224 224 .attr('multiple', 'true')
225 225 .attr('size', Math.min(10, this.raw_result.length));
226 226 this.complete.append(this.sel);
227 227 $('body').append(this.complete);
228 228
229 229 // After everything is on the page, compute the postion.
230 230 // We put it above the code if it is too close to the bottom of the page.
231 231 var cur = this.editor.getCursor();
232 232 cur.ch = cur.ch-matched_text.length;
233 233 var pos = this.editor.cursorCoords(cur);
234 234 var left = pos.left-3;
235 235 var top;
236 236 var cheight = this.complete.height();
237 237 var wheight = $(window).height();
238 238 if (pos.bottom+cheight+5 > wheight) {
239 239 top = pos.top-cheight-4;
240 240 } else {
241 241 top = pos.bottom+1;
242 242 }
243 243 this.complete.css('left', left + 'px');
244 244 this.complete.css('top', top + 'px');
245 245
246 246
247 247 //build the container
248 248 var that = this;
249 249 this.sel.dblclick(function () {
250 250 that.pick();
251 251 });
252 252 this.sel.blur(this.close);
253 253 this.sel.keydown(function (event) {
254 254 that.keydown(event);
255 255 });
256 256
257 257 this.build_gui_list(this.raw_result);
258 258
259 259 this.sel.focus();
260 IPython.keyboard_manager.null_mode();
260 IPython.keyboard_manager.disable();
261 261 // Opera sometimes ignores focusing a freshly created node
262 262 if (window.opera) setTimeout(function () {
263 263 if (!this.done) this.sel.focus();
264 264 }, 100);
265 265 return true;
266 266 }
267 267
268 268 Completer.prototype.insert = function (completion) {
269 269 this.editor.replaceRange(completion.str, completion.from, completion.to);
270 270 }
271 271
272 272 Completer.prototype.build_gui_list = function (completions) {
273 273 for (var i = 0; i < completions.length; ++i) {
274 274 var opt = $('<option/>').text(completions[i].str).addClass(completions[i].type);
275 275 this.sel.append(opt);
276 276 }
277 277 this.sel.children().first().attr('selected', 'true');
278 278 this.sel.scrollTop(0);
279 279 }
280 280
281 281 Completer.prototype.close = function () {
282 282 if (this.done) return;
283 283 this.done = true;
284 284 $('.completions').remove();
285 IPython.keyboard_manager.edit_mode();
285 IPython.keyboard_manager.enable();
286 286 }
287 287
288 288 Completer.prototype.pick = function () {
289 289 this.insert(this.raw_result[this.sel[0].selectedIndex]);
290 290 this.close();
291 291 var that = this;
292 292 setTimeout(function () {
293 293 that.editor.focus();
294 294 }, 50);
295 295 }
296 296
297 297
298 298 Completer.prototype.keydown = function (event) {
299 299 var code = event.keyCode;
300 300 var that = this;
301 301 var special_key = false;
302 302
303 303 // detect special keys like SHIFT,PGUP,...
304 304 for( var _key in key ) {
305 305 if (code == key[_key] ) {
306 306 special_key = true;
307 307 }
308 308 };
309 309
310 310 // Enter
311 311 if (code == key.ENTER) {
312 312 CodeMirror.e_stop(event);
313 313 this.pick();
314 314 }
315 315 // Escape or backspace
316 316 else if (code == key.ESC) {
317 317 CodeMirror.e_stop(event);
318 318 this.close();
319 319 this.editor.focus();
320 320 } else if (code == key.SPACE || code == key.BACKSPACE) {
321 321 this.close();
322 322 this.editor.focus();
323 323 } else if (code == key.TAB) {
324 324 //all the fastforwarding operation,
325 325 //Check that shared start is not null which can append with prefixed completion
326 326 // like %pylab , pylab have no shred start, and ff will result in py<tab><tab>
327 327 // to erase py
328 328 var sh = shared_start(this.raw_result, true);
329 329 if (sh) {
330 330 this.insert(sh);
331 331 }
332 332 this.close();
333 333 CodeMirror.e_stop(event);
334 334 this.editor.focus();
335 335 //reinvoke self
336 336 setTimeout(function () {
337 337 that.carry_on_completion();
338 338 }, 50);
339 339 } else if (code == key.UPARROW || code == key.DOWNARROW) {
340 340 // need to do that to be able to move the arrow
341 341 // when on the first or last line ofo a code cell
342 342 event.stopPropagation();
343 343 } else if (special_key != true) {
344 344 this.close();
345 345 this.editor.focus();
346 346 //we give focus to the editor immediately and call sell in 50 ms
347 347 setTimeout(function () {
348 348 that.carry_on_completion();
349 349 }, 50);
350 350 }
351 351 }
352 352
353 353
354 354 IPython.Completer = Completer;
355 355
356 356 return IPython;
357 357 }(IPython));
@@ -1,283 +1,265 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Keyboard management
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13 "use strict";
14 14
15 15 var key = IPython.utils.keycodes;
16 16
17 17 var KeyboardManager = function () {
18 18 this.mode = 'command';
19 this.last_mode = 'command';
19 this.enabled = true;
20 20 this.bind_events();
21 21 };
22 22
23 23 KeyboardManager.prototype.bind_events = function () {
24 24 var that = this;
25 25 $(document).keydown(function (event) {
26 26 return that.handle_keydown(event);
27 27 });
28 28 };
29 29
30 30 KeyboardManager.prototype.handle_keydown = function (event) {
31 31 var notebook = IPython.notebook;
32 32
33 33 console.log('keyboard_manager', this.mode, event.keyCode);
34 34
35 35 if (event.which === key.ESC) {
36 36 // Intercept escape at highest level to avoid closing
37 37 // websocket connection with firefox
38 38 event.preventDefault();
39 39 }
40 40
41 if (this.mode === 'null') {
42 return this.handle_null_mode(event);
41 if (!this.enabled) {
42 return true;
43 43 }
44 44
45 45 // Event handlers for both command and edit mode
46 46 if ((event.ctrlKey || event.metaKey) && event.keyCode==83) {
47 47 // Save (CTRL+S) or (Command+S on Mac)
48 48 notebook.save_checkpoint();
49 49 event.preventDefault();
50 50 return false;
51 51 } else if (event.which === key.ESC) {
52 52 // Intercept escape at highest level to avoid closing
53 53 // websocket connection with firefox
54 54 event.preventDefault();
55 55 // Don't return yet to allow edit/command modes to handle
56 56 } else if (event.which === key.SHIFT) {
57 57 // ignore shift keydown
58 58 return true;
59 59 } else if (event.which === key.ENTER && event.shiftKey) {
60 60 notebook.execute_selected_cell('shift');
61 61 return false;
62 62 } else if (event.which === key.ENTER && event.altKey) {
63 63 // Execute code cell, and insert new in place
64 64 notebook.execute_selected_cell('alt');
65 65 return false;
66 66 } else if (event.which === key.ENTER && event.ctrlKey) {
67 67 notebook.execute_selected_cell('ctrl');
68 68 return false;
69 69 }
70 70
71 71 if (this.mode === 'edit') {
72 72 return this.handle_edit_mode(event);
73 73 } else if (this.mode === 'command' && !(event.ctrlKey || event.altKey || event.metaKey)) {
74 74 return this.handle_command_mode(event);
75 75 }
76 76 }
77 77
78 KeyboardManager.prototype.handle_null_mode = function (event) {
79 return true;
80 }
81
82
83 78 KeyboardManager.prototype.handle_edit_mode = function (event) {
84 79 var notebook = IPython.notebook;
85 80
86 81 if (event.which === key.ESC) {
87 82 // ESC
88 83 notebook.command_mode();
89 84 return false;
90 85 } else if (event.which === 77 && event.ctrlKey) {
91 86 // Ctrl-m
92 87 notebook.command_mode();
93 88 return false;
94 89 } else if (event.which === key.UPARROW && !event.shiftKey) {
95 90 var cell = notebook.get_selected_cell();
96 91 if (cell && cell.at_top()) {
97 92 event.preventDefault();
98 93 notebook.command_mode()
99 94 notebook.select_prev();
100 95 notebook.edit_mode();
101 96 return false;
102 97 };
103 98 } else if (event.which === key.DOWNARROW && !event.shiftKey) {
104 99 var cell = notebook.get_selected_cell();
105 100 if (cell && cell.at_bottom()) {
106 101 event.preventDefault();
107 102 notebook.command_mode()
108 103 notebook.select_next();
109 104 notebook.edit_mode();
110 105 return false;
111 106 };
112 107 };
113 108 return true;
114 109 }
115 110
116 111 KeyboardManager.prototype.handle_command_mode = function (event) {
117 112 var notebook = IPython.notebook;
118 113
119 114 if (event.which === key.ENTER && !(event.ctrlKey || event.altKey || event.shiftKey)) {
120 115 // Enter edit mode = ENTER alone
121 116 notebook.edit_mode();
122 117 return false;
123 118 } else if (event.which === key.UPARROW && !event.shiftKey) {
124 119 var index = notebook.get_selected_index();
125 120 if (index !== 0 && index !== null) {
126 121 notebook.select_prev();
127 122 var cell = notebook.get_selected_cell();
128 123 cell.focus_cell();
129 124 };
130 125 return false;
131 126 } else if (event.which === key.DOWNARROW && !event.shiftKey) {
132 127 var index = notebook.get_selected_index();
133 128 if (index !== (notebook.ncells()-1) && index !== null) {
134 129 notebook.select_next();
135 130 var cell = notebook.get_selected_cell();
136 131 cell.focus_cell();
137 132 };
138 133 return false;
139 134 } else if (event.which === 88) {
140 135 // Cut selected cell = x
141 136 notebook.cut_cell();
142 137 return false;
143 138 } else if (event.which === 67) {
144 139 // Copy selected cell = c
145 140 notebook.copy_cell();
146 141 return false;
147 142 } else if (event.which === 86) {
148 143 // Paste below selected cell = v
149 144 notebook.paste_cell_below();
150 145 return false;
151 146 } else if (event.which === 68) {
152 147 // Delete selected cell = d
153 148 notebook.delete_cell();
154 149 return false;
155 150 } else if (event.which === 65) {
156 151 // Insert code cell above selected = a
157 152 notebook.insert_cell_above('code');
158 153 notebook.select_prev();
159 154 return false;
160 155 } else if (event.which === 66) {
161 156 // Insert code cell below selected = b
162 157 notebook.insert_cell_below('code');
163 158 notebook.select_next();
164 159 return false;
165 160 } else if (event.which === 89) {
166 161 // To code = y
167 162 notebook.to_code();
168 163 return false;
169 164 } else if (event.which === 77) {
170 165 // To markdown = m
171 166 notebook.to_markdown();
172 167 return false;
173 168 } else if (event.which === 84) {
174 169 // To Raw = t
175 170 notebook.to_raw();
176 171 return false;
177 172 } else if (event.which === 49) {
178 173 // To Heading 1 = 1
179 174 notebook.to_heading(undefined, 1);
180 175 return false;
181 176 } else if (event.which === 50) {
182 177 // To Heading 2 = 2
183 178 notebook.to_heading(undefined, 2);
184 179 return false;
185 180 } else if (event.which === 51) {
186 181 // To Heading 3 = 3
187 182 notebook.to_heading(undefined, 3);
188 183 return false;
189 184 } else if (event.which === 52) {
190 185 // To Heading 4 = 4
191 186 notebook.to_heading(undefined, 4);
192 187 return false;
193 188 } else if (event.which === 53) {
194 189 // To Heading 5 = 5
195 190 notebook.to_heading(undefined, 5);
196 191 return false;
197 192 } else if (event.which === 54) {
198 193 // To Heading 6 = 6
199 194 notebook.to_heading(undefined, 6);
200 195 return false;
201 196 } else if (event.which === 79) {
202 197 // Toggle output = o
203 198 if (event.shiftKey) {
204 199 notebook.toggle_output_scroll();
205 200 } else {
206 201 notebook.toggle_output();
207 202 };
208 203 return false;
209 204 } else if (event.which === 83) {
210 205 // Save notebook = s
211 206 notebook.save_checkpoint();
212 207 return false;
213 208 } else if (event.which === 74) {
214 209 // Move cell down = j
215 210 notebook.move_cell_down();
216 211 return false;
217 212 } else if (event.which === 75) {
218 213 // Move cell up = k
219 214 notebook.move_cell_up();
220 215 return false;
221 216 } else if (event.which === 80) {
222 217 // Select previous = p
223 218 notebook.select_prev();
224 219 return false;
225 220 } else if (event.which === 78) {
226 221 // Select next = n
227 222 notebook.select_next();
228 223 return false;
229 224 } else if (event.which === 76) {
230 225 // Toggle line numbers = l
231 226 notebook.cell_toggle_line_numbers();
232 227 return false;
233 228 } else if (event.which === 73) {
234 229 // Interrupt kernel = i
235 230 notebook.kernel.interrupt();
236 231 return false;
237 232 } else if (event.which === 190) {
238 233 // Restart kernel = . # matches qt console
239 234 notebook.restart_kernel();
240 235 return false;
241 236 } else if (event.which === 72) {
242 237 // Show keyboard shortcuts = h
243 238 IPython.quick_help.show_keyboard_shortcuts();
244 239 return false;
245 240 } else if (event.which === 90) {
246 241 // Undo last cell delete = z
247 242 notebook.undelete();
248 243 return false;
249 244 };
250 245 // If we havn't handled it, let someone else.
251 246 return true;
252 247 };
253 248
254 249 KeyboardManager.prototype.edit_mode = function () {
255 250 console.log('KeyboardManager', 'changing to edit mode');
256 251 this.last_mode = this.mode;
257 252 this.mode = 'edit';
258 253 }
259 254
260 255 KeyboardManager.prototype.command_mode = function () {
261 256 console.log('KeyboardManager', 'changing to command mode');
262 257 this.last_mode = this.mode;
263 258 this.mode = 'command';
264 259 }
265 260
266 KeyboardManager.prototype.null_mode = function () {
267 console.log('KeyboardManager', 'changing to null mode');
268 this.last_mode = this.mode;
269 this.mode = 'null';
270 }
271
272 KeyboardManager.prototype.last_mode = function () {
273 var lm = this.last_mode;
274 this.last_mode = this.mode;
275 this.mode = lm;
276 }
277
278
279 261 IPython.KeyboardManager = KeyboardManager;
280 262
281 263 return IPython;
282 264
283 265 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now