Show More
@@ -147,10 +147,7 b' var IPython = (function (IPython) {' | |||||
147 | } |
|
147 | } | |
148 | if (this.code_mirror) { |
|
148 | if (this.code_mirror) { | |
149 | this.code_mirror.on('blur', function(cm, change) { |
|
149 | this.code_mirror.on('blur', function(cm, change) { | |
150 | // Check if this unfocus event is legit. |
|
150 | $([IPython.events]).trigger('command_mode.Cell', {cell: that}); | |
151 | if (!that.should_cancel_blur()) { |
|
|||
152 | $([IPython.events]).trigger('command_mode.Cell', {cell: that}); |
|
|||
153 | } |
|
|||
154 | }); |
|
151 | }); | |
155 | } |
|
152 | } | |
156 | }; |
|
153 | }; | |
@@ -331,18 +328,7 b' var IPython = (function (IPython) {' | |||||
331 | return false; |
|
328 | return false; | |
332 | } |
|
329 | } | |
333 | }; |
|
330 | }; | |
334 |
|
331 | |||
335 | /** |
|
|||
336 | * Determine whether or not the unfocus event should be aknowledged. |
|
|||
337 | * |
|
|||
338 | * @method should_cancel_blur |
|
|||
339 | * |
|
|||
340 | * @return results {bool} Whether or not to ignore the cell's blur event. |
|
|||
341 | **/ |
|
|||
342 | Cell.prototype.should_cancel_blur = function () { |
|
|||
343 | return false; |
|
|||
344 | }; |
|
|||
345 |
|
||||
346 | /** |
|
332 | /** | |
347 | * Focus the cell in the DOM sense |
|
333 | * Focus the cell in the DOM sense | |
348 | * @method focus_cell |
|
334 | * @method focus_cell |
@@ -358,21 +358,6 b' var IPython = (function (IPython) {' | |||||
358 | return false; |
|
358 | return false; | |
359 | }; |
|
359 | }; | |
360 |
|
360 | |||
361 | /** |
|
|||
362 | * Determine whether or not the unfocus event should be aknowledged. |
|
|||
363 | * |
|
|||
364 | * @method should_cancel_blur |
|
|||
365 | * |
|
|||
366 | * @return results {bool} Whether or not to ignore the cell's blur event. |
|
|||
367 | **/ |
|
|||
368 | CodeCell.prototype.should_cancel_blur = function () { |
|
|||
369 | // Cancel this unfocus event if the base wants to cancel or the cell |
|
|||
370 | // completer is open or the tooltip is open. |
|
|||
371 | return IPython.Cell.prototype.should_cancel_blur.apply(this) || |
|
|||
372 | (this.completer && this.completer.is_visible()) || |
|
|||
373 | (IPython.tooltip && IPython.tooltip.is_visible()); |
|
|||
374 | }; |
|
|||
375 |
|
||||
376 | CodeCell.prototype.select_all = function () { |
|
361 | CodeCell.prototype.select_all = function () { | |
377 | var start = {line: 0, ch: 0}; |
|
362 | var start = {line: 0, ch: 0}; | |
378 | var nlines = this.code_mirror.lineCount(); |
|
363 | var nlines = this.code_mirror.lineCount(); | |
@@ -508,6 +493,23 b' var IPython = (function (IPython) {' | |||||
508 | return data; |
|
493 | return data; | |
509 | }; |
|
494 | }; | |
510 |
|
495 | |||
|
496 | /** | |||
|
497 | * handle cell level logic when a cell is unselected | |||
|
498 | * @method unselect | |||
|
499 | * @return is the action being taken | |||
|
500 | */ | |||
|
501 | CodeCell.prototype.unselect = function () { | |||
|
502 | var cont = IPython.Cell.prototype.unselect.apply(this); | |||
|
503 | if (cont) { | |||
|
504 | // When a code cell is usnelected, make sure that the corresponding | |||
|
505 | // tooltip and completer to that cell is closed. | |||
|
506 | IPython.tooltip.remove_and_cancel_tooltip(true); | |||
|
507 | if (this.completer !== null) { | |||
|
508 | this.completer.close(); | |||
|
509 | } | |||
|
510 | } | |||
|
511 | return cont; | |||
|
512 | }; | |||
511 |
|
513 | |||
512 | IPython.CodeCell = CodeCell; |
|
514 | IPython.CodeCell = CodeCell; | |
513 |
|
515 |
@@ -73,7 +73,6 b' var IPython = (function (IPython) {' | |||||
73 |
|
73 | |||
74 |
|
74 | |||
75 | var Completer = function (cell) { |
|
75 | var Completer = function (cell) { | |
76 | this._visible = false; |
|
|||
77 | this.cell = cell; |
|
76 | this.cell = cell; | |
78 | this.editor = cell.code_mirror; |
|
77 | this.editor = cell.code_mirror; | |
79 | var that = this; |
|
78 | var that = this; | |
@@ -85,15 +84,9 b' var IPython = (function (IPython) {' | |||||
85 | }); |
|
84 | }); | |
86 | }; |
|
85 | }; | |
87 |
|
86 | |||
88 | Completer.prototype.is_visible = function () { |
|
|||
89 | // Return whether or not the completer is visible. |
|
|||
90 | return this._visible; |
|
|||
91 | }; |
|
|||
92 |
|
||||
93 | Completer.prototype.startCompletion = function () { |
|
87 | Completer.prototype.startCompletion = function () { | |
94 | // call for a 'first' completion, that will set the editor and do some |
|
88 | // call for a 'first' completion, that will set the editor and do some | |
95 |
// special behavio |
|
89 | // special behavior like autopicking if only one completion available. | |
96 | // |
|
|||
97 | if (this.editor.somethingSelected()) return; |
|
90 | if (this.editor.somethingSelected()) return; | |
98 | this.done = false; |
|
91 | this.done = false; | |
99 | // use to get focus back on opera |
|
92 | // use to get focus back on opera | |
@@ -221,17 +214,37 b' var IPython = (function (IPython) {' | |||||
221 | } |
|
214 | } | |
222 | } |
|
215 | } | |
223 |
|
216 | |||
224 | this.complete = $('<div/>').addClass('completions'); |
|
217 | if (!this.visible) { | |
225 |
this.complete.a |
|
218 | this.complete = $('<div/>').addClass('completions'); | |
226 |
|
219 | this.complete.attr('id', 'complete'); | ||
227 | // Currently webkit doesn't use the size attr correctly. See: |
|
220 | ||
228 | // https://code.google.com/p/chromium/issues/detail?id=4579 |
|
221 | // Currently webkit doesn't use the size attr correctly. See: | |
229 | this.sel = $('<select style="width: auto"/>') |
|
222 | // https://code.google.com/p/chromium/issues/detail?id=4579 | |
230 | .attr('multiple', 'true') |
|
223 | this.sel = $('<select/>') | |
231 | .attr('size', Math.min(10, this.raw_result.length)); |
|
224 | .attr('tabindex', -1) | |
232 | this.complete.append(this.sel); |
|
225 | .attr('multiple', 'true'); | |
233 | this._visible = true; |
|
226 | this.complete.append(this.sel); | |
234 | $('body').append(this.complete); |
|
227 | this.visible = true; | |
|
228 | $('body').append(this.complete); | |||
|
229 | ||||
|
230 | //build the container | |||
|
231 | var that = this; | |||
|
232 | this.sel.dblclick(function () { | |||
|
233 | that.pick(); | |||
|
234 | }); | |||
|
235 | this.sel.focus(function () { | |||
|
236 | that.editor.focus(); | |||
|
237 | }); | |||
|
238 | this._handle_keydown = function (cm, event) { | |||
|
239 | that.keydown(event); | |||
|
240 | }; | |||
|
241 | this.editor.on('keydown', this._handle_keydown); | |||
|
242 | this._handle_keypress = function (cm, event) { | |||
|
243 | that.keypress(event); | |||
|
244 | }; | |||
|
245 | this.editor.on('keypress', this._handle_keypress); | |||
|
246 | } | |||
|
247 | this.sel.attr('size', Math.min(10, this.raw_result.length)); | |||
235 |
|
248 | |||
236 | // After everything is on the page, compute the postion. |
|
249 | // After everything is on the page, compute the postion. | |
237 | // We put it above the code if it is too close to the bottom of the page. |
|
250 | // We put it above the code if it is too close to the bottom of the page. | |
@@ -249,28 +262,9 b' var IPython = (function (IPython) {' | |||||
249 | this.complete.css('left', left + 'px'); |
|
262 | this.complete.css('left', left + 'px'); | |
250 | this.complete.css('top', top + 'px'); |
|
263 | this.complete.css('top', top + 'px'); | |
251 |
|
264 | |||
252 |
|
265 | // Clear and fill the list. | ||
253 | //build the container |
|
266 | this.sel.text(''); | |
254 | var that = this; |
|
|||
255 | this.sel.dblclick(function () { |
|
|||
256 | that.pick(); |
|
|||
257 | }); |
|
|||
258 | this.sel.blur(this.close); |
|
|||
259 | this.sel.keydown(function (event) { |
|
|||
260 | that.keydown(event); |
|
|||
261 | }); |
|
|||
262 | this.sel.keypress(function (event) { |
|
|||
263 | that.keypress(event); |
|
|||
264 | }); |
|
|||
265 |
|
||||
266 | this.build_gui_list(this.raw_result); |
|
267 | this.build_gui_list(this.raw_result); | |
267 |
|
||||
268 | this.sel.focus(); |
|
|||
269 | IPython.keyboard_manager.disable(); |
|
|||
270 | // Opera sometimes ignores focusing a freshly created node |
|
|||
271 | if (window.opera) setTimeout(function () { |
|
|||
272 | if (!this.done) this.sel.focus(); |
|
|||
273 | }, 100); |
|
|||
274 | return true; |
|
268 | return true; | |
275 | }; |
|
269 | }; | |
276 |
|
270 | |||
@@ -288,20 +282,16 b' var IPython = (function (IPython) {' | |||||
288 | }; |
|
282 | }; | |
289 |
|
283 | |||
290 | Completer.prototype.close = function () { |
|
284 | Completer.prototype.close = function () { | |
291 | this._visible = false; |
|
|||
292 | if (this.done) return; |
|
|||
293 | this.done = true; |
|
285 | this.done = true; | |
294 |
$(' |
|
286 | $('#complete').remove(); | |
295 | IPython.keyboard_manager.enable(); |
|
287 | this.editor.off('keydown', this._handle_keydown); | |
|
288 | this.editor.off('keypress', this._handle_keypress); | |||
|
289 | this.visible = false; | |||
296 | }; |
|
290 | }; | |
297 |
|
291 | |||
298 | Completer.prototype.pick = function () { |
|
292 | Completer.prototype.pick = function () { | |
299 | this.insert(this.raw_result[this.sel[0].selectedIndex]); |
|
293 | this.insert(this.raw_result[this.sel[0].selectedIndex]); | |
300 | this.close(); |
|
294 | this.close(); | |
301 | var that = this; |
|
|||
302 | setTimeout(function () { |
|
|||
303 | that.editor.focus(); |
|
|||
304 | }, 50); |
|
|||
305 | }; |
|
295 | }; | |
306 |
|
296 | |||
307 | Completer.prototype.keydown = function (event) { |
|
297 | Completer.prototype.keydown = function (event) { | |
@@ -312,16 +302,10 b' var IPython = (function (IPython) {' | |||||
312 | if (code == keycodes.enter) { |
|
302 | if (code == keycodes.enter) { | |
313 | CodeMirror.e_stop(event); |
|
303 | CodeMirror.e_stop(event); | |
314 | this.pick(); |
|
304 | this.pick(); | |
315 | } |
|
|||
316 | // Escape or backspace |
|
305 | // Escape or backspace | |
317 | else if (code == keycodes.esc) { |
|
306 | } else if (code == keycodes.esc || code == keycodes.backspace) { | |
318 | CodeMirror.e_stop(event); |
|
307 | CodeMirror.e_stop(event); | |
319 | this.close(); |
|
308 | this.close(); | |
320 | this.editor.focus(); |
|
|||
321 |
|
||||
322 | } else if (code == keycodes.backspace) { |
|
|||
323 | this.close(); |
|
|||
324 | this.editor.focus(); |
|
|||
325 | } else if (code == keycodes.tab) { |
|
309 | } else if (code == keycodes.tab) { | |
326 | //all the fastforwarding operation, |
|
310 | //all the fastforwarding operation, | |
327 | //Check that shared start is not null which can append with prefixed completion |
|
311 | //Check that shared start is not null which can append with prefixed completion | |
@@ -332,8 +316,6 b' var IPython = (function (IPython) {' | |||||
332 | this.insert(sh); |
|
316 | this.insert(sh); | |
333 | } |
|
317 | } | |
334 | this.close(); |
|
318 | this.close(); | |
335 | CodeMirror.e_stop(event); |
|
|||
336 | this.editor.focus(); |
|
|||
337 | //reinvoke self |
|
319 | //reinvoke self | |
338 | setTimeout(function () { |
|
320 | setTimeout(function () { | |
339 | that.carry_on_completion(); |
|
321 | that.carry_on_completion(); | |
@@ -341,10 +323,23 b' var IPython = (function (IPython) {' | |||||
341 | } else if (code == keycodes.up || code == keycodes.down) { |
|
323 | } else if (code == keycodes.up || code == keycodes.down) { | |
342 | // need to do that to be able to move the arrow |
|
324 | // need to do that to be able to move the arrow | |
343 | // when on the first or last line ofo a code cell |
|
325 | // when on the first or last line ofo a code cell | |
344 | event.stopPropagation(); |
|
326 | CodeMirror.e_stop(event); | |
|
327 | ||||
|
328 | var options = this.sel.find('option'); | |||
|
329 | var index = this.sel[0].selectedIndex; | |||
|
330 | if (code == keycodes.up) { | |||
|
331 | index--; | |||
|
332 | } | |||
|
333 | if (code == keycodes.down) { | |||
|
334 | index++; | |||
|
335 | } | |||
|
336 | index = Math.min(Math.max(index, 0), options.length-1); | |||
|
337 | this.sel[0].selectedIndex = index; | |||
|
338 | } else if (code == keycodes.left || code == keycodes.right) { | |||
|
339 | this.close(); | |||
345 | } |
|
340 | } | |
346 | }; |
|
341 | }; | |
347 |
|
342 | |||
348 | Completer.prototype.keypress = function (event) { |
|
343 | Completer.prototype.keypress = function (event) { | |
349 | // FIXME: This is a band-aid. |
|
344 | // FIXME: This is a band-aid. | |
350 | // on keypress, trigger insertion of a single character. |
|
345 | // on keypress, trigger insertion of a single character. | |
@@ -358,26 +353,16 b' var IPython = (function (IPython) {' | |||||
358 | // don't handle keypress if it's not a character (arrows on FF) |
|
353 | // don't handle keypress if it's not a character (arrows on FF) | |
359 | // or ENTER/TAB |
|
354 | // or ENTER/TAB | |
360 | if (event.charCode === 0 || |
|
355 | if (event.charCode === 0 || | |
361 |
code == keycodes. |
|
356 | code == keycodes.tab || | |
362 |
code == keycodes. |
|
357 | code == keycodes.enter | |
363 | ) return; |
|
358 | ) return; | |
364 |
|
359 | |||
365 | var cur = this.editor.getCursor(); |
|
|||
366 | var completion = { |
|
|||
367 | str: String.fromCharCode(event.which), |
|
|||
368 | type: "introspection", |
|
|||
369 | from: cur, |
|
|||
370 | to: cur, |
|
|||
371 | }; |
|
|||
372 | this.insert(completion); |
|
|||
373 |
|
||||
374 | this.close(); |
|
360 | this.close(); | |
375 | this.editor.focus(); |
|
361 | this.editor.focus(); | |
376 | setTimeout(function () { |
|
362 | setTimeout(function () { | |
377 | that.carry_on_completion(); |
|
363 | that.carry_on_completion(); | |
378 | }, 50); |
|
364 | }, 50); | |
379 | }; |
|
365 | }; | |
380 |
|
||||
381 | IPython.Completer = Completer; |
|
366 | IPython.Completer = Completer; | |
382 |
|
367 | |||
383 | return IPython; |
|
368 | return IPython; |
@@ -17,6 +17,7 b'' | |||||
17 | font-family: @monoFontFamily; |
|
17 | font-family: @monoFontFamily; | |
18 | font-size: 110%; |
|
18 | font-size: 110%; | |
19 | color: @textColor; |
|
19 | color: @textColor; | |
|
20 | width: auto; | |||
20 | } |
|
21 | } | |
21 |
|
22 | |||
22 | .completions select option.context { |
|
23 | .completions select option.context { |
@@ -1,7 +1,3 b'' | |||||
1 | .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0} |
|
|||
2 | .clearfix:after{clear:both} |
|
|||
3 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} |
|
|||
4 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} |
|
|||
5 | article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block} |
|
1 | article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block} | |
6 | audio,canvas,video{display:inline-block;*display:inline;*zoom:1} |
|
2 | audio,canvas,video{display:inline-block;*display:inline;*zoom:1} | |
7 | audio:not([controls]){display:none} |
|
3 | audio:not([controls]){display:none} | |
@@ -856,6 +852,10 b' a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decorati' | |||||
856 | .show{display:block} |
|
852 | .show{display:block} | |
857 | .invisible{visibility:hidden} |
|
853 | .invisible{visibility:hidden} | |
858 | .affix{position:fixed} |
|
854 | .affix{position:fixed} | |
|
855 | .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0} | |||
|
856 | .clearfix:after{clear:both} | |||
|
857 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} | |||
|
858 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} | |||
859 | @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden} |
|
859 | @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden} | |
860 | .visible-phone{display:none !important} |
|
860 | .visible-phone{display:none !important} | |
861 | .visible-tablet{display:none !important} |
|
861 | .visible-tablet{display:none !important} | |
@@ -1497,7 +1497,7 b' p{margin-bottom:0}' | |||||
1497 | .celltoolbar input[type=checkbox]{margin:0;margin-left:4px;margin-right:4px} |
|
1497 | .celltoolbar input[type=checkbox]{margin:0;margin-left:4px;margin-right:4px} | |
1498 | .celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px} |
|
1498 | .celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px} | |
1499 | .completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0 6px 10px -1px #adadad;-moz-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad} |
|
1499 | .completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0 6px 10px -1px #adadad;-moz-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad} | |
1500 | .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000} |
|
1500 | .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000;width:auto} | |
1501 | .completions select option.context{color:#0064cd} |
|
1501 | .completions select option.context{color:#0064cd} | |
1502 | #menubar .navbar-inner{min-height:28px;border-top:1px;border-radius:0 0 4px 4px} |
|
1502 | #menubar .navbar-inner{min-height:28px;border-top:1px;border-radius:0 0 4px 4px} | |
1503 | #menubar .navbar{margin-bottom:8px} |
|
1503 | #menubar .navbar{margin-bottom:8px} |
@@ -83,6 +83,7 b' function(WidgetManager, _, Backbone){' | |||||
83 | break; |
|
83 | break; | |
84 | case 'display': |
|
84 | case 'display': | |
85 | this.widget_manager.display_view(msg, this); |
|
85 | this.widget_manager.display_view(msg, this); | |
|
86 | this.trigger('displayed'); | |||
86 | break; |
|
87 | break; | |
87 | } |
|
88 | } | |
88 | }, |
|
89 | }, |
@@ -29,40 +29,44 b' define(["widgets/js/widget"], function(WidgetManager){' | |||||
29 | this.model.on('change:_children', function(model, value, options) { |
|
29 | this.model.on('change:_children', function(model, value, options) { | |
30 | this.update_children(model.previous('_children'), value); |
|
30 | this.update_children(model.previous('_children'), value); | |
31 | }, this); |
|
31 | }, this); | |
|
32 | this.model.on('change:selected_index', function(model, value, options) { | |||
|
33 | this.update_selected_index(model.previous('selected_index'), value, options); | |||
|
34 | }, this); | |||
|
35 | this.model.on('change:_titles', function(model, value, options) { | |||
|
36 | this.update_titles(value); | |||
|
37 | }, this); | |||
|
38 | this.model.on('displayed', function() { | |||
|
39 | this.update_titles(); | |||
|
40 | }, this); | |||
32 | }, |
|
41 | }, | |
33 |
|
||||
34 | update: function(options) { |
|
|||
35 | // Update the contents of this view |
|
|||
36 | // |
|
|||
37 | // Called when the model is changed. The model may have been |
|
|||
38 | // changed by another view or by a state update from the back-end. |
|
|||
39 | if (options === undefined || options.updated_view != this) { |
|
|||
40 | // Set tab titles |
|
|||
41 | var titles = this.model.get('_titles'); |
|
|||
42 | var that = this; |
|
|||
43 | _.each(titles, function(title, page_index) { |
|
|||
44 | var accordian = that.containers[page_index]; |
|
|||
45 | if (accordian !== undefined) { |
|
|||
46 | accordian |
|
|||
47 | .find('.accordion-heading') |
|
|||
48 | .find('.accordion-toggle') |
|
|||
49 | .text(title); |
|
|||
50 | } |
|
|||
51 | }); |
|
|||
52 |
|
42 | |||
53 | // Set selected page |
|
43 | update_titles: function(titles) { | |
54 | var selected_index = this.model.get("selected_index"); |
|
44 | // Set tab titles | |
55 | if (0 <= selected_index && selected_index < this.containers.length) { |
|
45 | if (!titles) { | |
56 | _.each(this.containers, function(container, index) { |
|
46 | titles = this.model.get('_titles'); | |
57 | if (index==selected_index) { |
|
47 | } | |
58 | container.find('.accordion-body').collapse('show'); |
|
48 | ||
59 | } else { |
|
49 | var that = this; | |
60 | container.find('.accordion-body').collapse('hide'); |
|
50 | _.each(titles, function(title, page_index) { | |
61 | } |
|
51 | var accordian = that.containers[page_index]; | |
62 | }); |
|
52 | if (accordian !== undefined) { | |
|
53 | accordian | |||
|
54 | .find('.accordion-heading') | |||
|
55 | .find('.accordion-toggle') | |||
|
56 | .text(title); | |||
|
57 | } | |||
|
58 | }); | |||
|
59 | }, | |||
|
60 | ||||
|
61 | update_selected_index: function(old_index, new_index, options) { | |||
|
62 | // Only update the selection if the selection wasn't triggered | |||
|
63 | // by the front-end. It must be triggered by the back-end. | |||
|
64 | if (options === undefined || options.updated_view != this) { | |||
|
65 | this.containers[old_index].find('.accordion-body').collapse('hide'); | |||
|
66 | if (0 <= new_index && new_index < this.containers.length) { | |||
|
67 | this.containers[new_index].find('.accordion-body').collapse('show'); | |||
63 | } |
|
68 | } | |
64 | } |
|
69 | } | |
65 | return AccordionView.__super__.update.apply(this); |
|
|||
66 | }, |
|
70 | }, | |
67 |
|
71 | |||
68 | update_children: function(old_list, new_list) { |
|
72 | update_children: function(old_list, new_list) { | |
@@ -103,7 +107,7 b' define(["widgets/js/widget"], function(WidgetManager){' | |||||
103 |
|
107 | |||
104 | // Calling model.set will trigger all of the other views of the |
|
108 | // Calling model.set will trigger all of the other views of the | |
105 | // model to update. |
|
109 | // model to update. | |
106 |
that.model.set("selected_index", index, {updated_view: th |
|
110 | that.model.set("selected_index", index, {updated_view: that}); | |
107 | that.touch(); |
|
111 | that.touch(); | |
108 | }) |
|
112 | }) | |
109 | .text('Page ' + index) |
|
113 | .text('Page ' + index) | |
@@ -120,12 +124,7 b' define(["widgets/js/widget"], function(WidgetManager){' | |||||
120 | accordion_inner.append(view.$el); |
|
124 | accordion_inner.append(view.$el); | |
121 |
|
125 | |||
122 | this.update(); |
|
126 | this.update(); | |
123 |
|
127 | this.update_titles(); | ||
124 | // Stupid workaround to close the bootstrap accordion tabs which |
|
|||
125 | // open by default even though they don't have the `in` class |
|
|||
126 | // attached to them. For some reason a delay is required. |
|
|||
127 | // TODO: Better fix. |
|
|||
128 | setTimeout(function(){ that.update(); }, 500); |
|
|||
129 | }, |
|
128 | }, | |
130 | }); |
|
129 | }); | |
131 | WidgetManager.register_widget_view('AccordionView', AccordionView); |
|
130 | WidgetManager.register_widget_view('AccordionView', AccordionView); |
@@ -104,5 +104,10 b' casper.notebook_test(function () {' | |||||
104 | this.execute_cell_then(index, function(index){ |
|
104 | this.execute_cell_then(index, function(index){ | |
105 | this.test.assertEquals(this.get_output_cell(index).text, '1\n', // 0 based |
|
105 | this.test.assertEquals(this.get_output_cell(index).text, '1\n', // 0 based | |
106 | 'selected_index property updated with tab change.'); |
|
106 | 'selected_index property updated with tab change.'); | |
|
107 | ||||
|
108 | var is_collapsed = this.evaluate(function(s){ | |||
|
109 | return $(s + ' div.accordion-group:nth-child(2) a').hasClass('collapsed'); // 1 based | |||
|
110 | }, {s: multicontainer2_query}); | |||
|
111 | this.test.assertEquals(is_collapsed, false, 'Was tab actually opened?'); | |||
107 | }); |
|
112 | }); | |
108 | }); No newline at end of file |
|
113 | }); |
@@ -304,7 +304,7 b' class Demo(object):' | |||||
304 | self.src_blocks = src_blocks |
|
304 | self.src_blocks = src_blocks | |
305 |
|
305 | |||
306 | # also build syntax-highlighted source |
|
306 | # also build syntax-highlighted source | |
307 | self.src_blocks_colored = map(self.ip_colorize,self.src_blocks) |
|
307 | self.src_blocks_colored = list(map(self.ip_colorize,self.src_blocks)) | |
308 |
|
308 | |||
309 | # ensure clean namespace and seek offset |
|
309 | # ensure clean namespace and seek offset | |
310 | self.reset() |
|
310 | self.reset() |
@@ -593,7 +593,7 b' class SSHLauncher(LocalProcessLauncher):' | |||||
593 |
|
593 | |||
594 | def _send_file(self, local, remote): |
|
594 | def _send_file(self, local, remote): | |
595 | """send a single file""" |
|
595 | """send a single file""" | |
596 | remote = "%s:%s" % (self.location, remote) |
|
596 | full_remote = "%s:%s" % (self.location, remote) | |
597 | for i in range(10): |
|
597 | for i in range(10): | |
598 | if not os.path.exists(local): |
|
598 | if not os.path.exists(local): | |
599 | self.log.debug("waiting for %s" % local) |
|
599 | self.log.debug("waiting for %s" % local) | |
@@ -605,8 +605,8 b' class SSHLauncher(LocalProcessLauncher):' | |||||
605 | check_output(self.ssh_cmd + self.ssh_args + \ |
|
605 | check_output(self.ssh_cmd + self.ssh_args + \ | |
606 | [self.location, 'mkdir', '-p', '--', remote_dir] |
|
606 | [self.location, 'mkdir', '-p', '--', remote_dir] | |
607 | ) |
|
607 | ) | |
608 | self.log.info("sending %s to %s", local, remote) |
|
608 | self.log.info("sending %s to %s", local, full_remote) | |
609 | check_output(self.scp_cmd + [local, remote]) |
|
609 | check_output(self.scp_cmd + [local, full_remote]) | |
610 |
|
610 | |||
611 | def send_files(self): |
|
611 | def send_files(self): | |
612 | """send our files (called before start)""" |
|
612 | """send our files (called before start)""" |
@@ -268,7 +268,7 b" test_sections['qt'].requires('zmq', 'qt', 'pygments')" | |||||
268 |
|
268 | |||
269 | # html: |
|
269 | # html: | |
270 | sec = test_sections['html'] |
|
270 | sec = test_sections['html'] | |
271 | sec.requires('zmq', 'tornado', 'requests') |
|
271 | sec.requires('zmq', 'tornado', 'requests', 'sqlite3') | |
272 | # The notebook 'static' directory contains JS, css and other |
|
272 | # The notebook 'static' directory contains JS, css and other | |
273 | # files for web serving. Occasionally projects may put a .py |
|
273 | # files for web serving. Occasionally projects may put a .py | |
274 | # file in there (MathJax ships a conf.py), so we might as |
|
274 | # file in there (MathJax ships a conf.py), so we might as |
@@ -19,8 +19,8 b' test suite.' | |||||
19 | from __future__ import print_function |
|
19 | from __future__ import print_function | |
20 |
|
20 | |||
21 | import argparse |
|
21 | import argparse | |
|
22 | import json | |||
22 | import multiprocessing.pool |
|
23 | import multiprocessing.pool | |
23 | from multiprocessing import Process, Queue |
|
|||
24 | import os |
|
24 | import os | |
25 | import shutil |
|
25 | import shutil | |
26 | import signal |
|
26 | import signal | |
@@ -28,7 +28,7 b' import sys' | |||||
28 | import subprocess |
|
28 | import subprocess | |
29 | import time |
|
29 | import time | |
30 |
|
30 | |||
31 | from .iptest import have, test_group_names as py_test_group_names, test_sections |
|
31 | from .iptest import have, test_group_names as py_test_group_names, test_sections, StreamCapturer | |
32 | from IPython.utils.path import compress_user |
|
32 | from IPython.utils.path import compress_user | |
33 | from IPython.utils.py3compat import bytes_to_str |
|
33 | from IPython.utils.py3compat import bytes_to_str | |
34 | from IPython.utils.sysinfo import get_sys_info |
|
34 | from IPython.utils.sysinfo import get_sys_info | |
@@ -127,13 +127,14 b' class PyTestController(TestController):' | |||||
127 | #: str, Python command to execute in subprocess |
|
127 | #: str, Python command to execute in subprocess | |
128 | pycmd = None |
|
128 | pycmd = None | |
129 |
|
129 | |||
130 | def __init__(self, section): |
|
130 | def __init__(self, section, options): | |
131 | """Create new test runner.""" |
|
131 | """Create new test runner.""" | |
132 | TestController.__init__(self) |
|
132 | TestController.__init__(self) | |
133 | self.section = section |
|
133 | self.section = section | |
134 | # pycmd is put into cmd[2] in PyTestController.launch() |
|
134 | # pycmd is put into cmd[2] in PyTestController.launch() | |
135 | self.cmd = [sys.executable, '-c', None, section] |
|
135 | self.cmd = [sys.executable, '-c', None, section] | |
136 | self.pycmd = "from IPython.testing.iptest import run_iptest; run_iptest()" |
|
136 | self.pycmd = "from IPython.testing.iptest import run_iptest; run_iptest()" | |
|
137 | self.options = options | |||
137 |
|
138 | |||
138 | def setup(self): |
|
139 | def setup(self): | |
139 | ipydir = TemporaryDirectory() |
|
140 | ipydir = TemporaryDirectory() | |
@@ -145,6 +146,14 b' class PyTestController(TestController):' | |||||
145 | # This means we won't get odd effects from our own matplotlib config |
|
146 | # This means we won't get odd effects from our own matplotlib config | |
146 | self.env['MPLCONFIGDIR'] = workingdir.name |
|
147 | self.env['MPLCONFIGDIR'] = workingdir.name | |
147 |
|
148 | |||
|
149 | # From options: | |||
|
150 | if self.options.xunit: | |||
|
151 | self.add_xunit() | |||
|
152 | if self.options.coverage: | |||
|
153 | self.add_coverage() | |||
|
154 | self.env['IPTEST_SUBPROC_STREAMS'] = self.options.subproc_streams | |||
|
155 | self.cmd.extend(self.options.extra_args) | |||
|
156 | ||||
148 | @property |
|
157 | @property | |
149 | def will_run(self): |
|
158 | def will_run(self): | |
150 | try: |
|
159 | try: | |
@@ -211,48 +220,77 b' class JSController(TestController):' | |||||
211 | os.makedirs(os.path.join(self.nbdir.name, os.path.join(u'sub ∂ir2', u'sub ∂ir 1b'))) |
|
220 | os.makedirs(os.path.join(self.nbdir.name, os.path.join(u'sub ∂ir2', u'sub ∂ir 1b'))) | |
212 |
|
221 | |||
213 | # start the ipython notebook, so we get the port number |
|
222 | # start the ipython notebook, so we get the port number | |
|
223 | self.server_port = 0 | |||
214 | self._init_server() |
|
224 | self._init_server() | |
215 |
|
|
225 | if self.server_port: | |
216 |
|
226 | self.cmd.append("--port=%i" % self.server_port) | ||
|
227 | else: | |||
|
228 | # don't launch tests if the server didn't start | |||
|
229 | self.cmd = [sys.executable, '-c', 'raise SystemExit(1)'] | |||
|
230 | ||||
217 | def print_extra_info(self): |
|
231 | def print_extra_info(self): | |
218 | print("Running tests with notebook directory %r" % self.nbdir.name) |
|
232 | print("Running tests with notebook directory %r" % self.nbdir.name) | |
219 |
|
233 | |||
220 | @property |
|
234 | @property | |
221 | def will_run(self): |
|
235 | def will_run(self): | |
222 | return all(have[a] for a in ['zmq', 'tornado', 'jinja2', 'casperjs']) |
|
236 | return all(have[a] for a in ['zmq', 'tornado', 'jinja2', 'casperjs', 'sqlite3']) | |
223 |
|
237 | |||
224 | def _init_server(self): |
|
238 | def _init_server(self): | |
225 | "Start the notebook server in a separate process" |
|
239 | "Start the notebook server in a separate process" | |
226 | self.queue = q = Queue() |
|
240 | self.server_command = command = [sys.executable, | |
227 | self.server = Process(target=run_webapp, args=(q, self.ipydir.name, self.nbdir.name)) |
|
241 | '-m', 'IPython.html', | |
228 | self.server.start() |
|
242 | '--no-browser', | |
229 | self.server_port = q.get() |
|
243 | '--ipython-dir', self.ipydir.name, | |
|
244 | '--notebook-dir', self.nbdir.name, | |||
|
245 | ] | |||
|
246 | # ipc doesn't work on Windows, and darwin has crazy-long temp paths, | |||
|
247 | # which run afoul of ipc's maximum path length. | |||
|
248 | if sys.platform.startswith('linux'): | |||
|
249 | command.append('--KernelManager.transport=ipc') | |||
|
250 | self.stream_capturer = c = StreamCapturer() | |||
|
251 | c.start() | |||
|
252 | self.server = subprocess.Popen(command, stdout=c.writefd, stderr=subprocess.STDOUT) | |||
|
253 | self.server_info_file = os.path.join(self.ipydir.name, | |||
|
254 | 'profile_default', 'security', 'nbserver-%i.json' % self.server.pid | |||
|
255 | ) | |||
|
256 | self._wait_for_server() | |||
|
257 | ||||
|
258 | def _wait_for_server(self): | |||
|
259 | """Wait 30 seconds for the notebook server to start""" | |||
|
260 | for i in range(300): | |||
|
261 | if self.server.poll() is not None: | |||
|
262 | return self._failed_to_start() | |||
|
263 | if os.path.exists(self.server_info_file): | |||
|
264 | self._load_server_info() | |||
|
265 | return | |||
|
266 | time.sleep(0.1) | |||
|
267 | print("Notebook server-info file never arrived: %s" % self.server_info_file, | |||
|
268 | file=sys.stderr | |||
|
269 | ) | |||
|
270 | ||||
|
271 | def _failed_to_start(self): | |||
|
272 | """Notebook server exited prematurely""" | |||
|
273 | captured = self.stream_capturer.get_buffer().decode('utf-8', 'replace') | |||
|
274 | print("Notebook failed to start: ", file=sys.stderr) | |||
|
275 | print(self.server_command) | |||
|
276 | print(captured, file=sys.stderr) | |||
|
277 | ||||
|
278 | def _load_server_info(self): | |||
|
279 | """Notebook server started, load connection info from JSON""" | |||
|
280 | with open(self.server_info_file) as f: | |||
|
281 | info = json.load(f) | |||
|
282 | self.server_port = info['port'] | |||
230 |
|
283 | |||
231 | def cleanup(self): |
|
284 | def cleanup(self): | |
232 | self.server.terminate() |
|
285 | try: | |
233 |
self.server. |
|
286 | self.server.terminate() | |
|
287 | except OSError: | |||
|
288 | # already dead | |||
|
289 | pass | |||
|
290 | self.server.wait() | |||
|
291 | self.stream_capturer.halt() | |||
234 | TestController.cleanup(self) |
|
292 | TestController.cleanup(self) | |
235 |
|
293 | |||
236 | def run_webapp(q, ipydir, nbdir, loglevel=0): |
|
|||
237 | """start the IPython Notebook, and pass port back to the queue""" |
|
|||
238 | import os |
|
|||
239 | import IPython.html.notebookapp as nbapp |
|
|||
240 | import sys |
|
|||
241 | sys.stderr = open(os.devnull, 'w') |
|
|||
242 | server = nbapp.NotebookApp() |
|
|||
243 | args = ['--no-browser'] |
|
|||
244 | args.extend(['--ipython-dir', ipydir, |
|
|||
245 | '--notebook-dir', nbdir, |
|
|||
246 | '--log-level', str(loglevel), |
|
|||
247 | ]) |
|
|||
248 | # ipc doesn't work on Windows, and darwin has crazy-long temp paths, |
|
|||
249 | # which run afoul of ipc's maximum path length. |
|
|||
250 | if sys.platform.startswith('linux'): |
|
|||
251 | args.append('--KernelManager.transport=ipc') |
|
|||
252 | server.initialize(args) |
|
|||
253 | # communicate the port number to the parent process |
|
|||
254 | q.put(server.port) |
|
|||
255 | server.start() |
|
|||
256 |
|
294 | |||
257 | def prepare_controllers(options): |
|
295 | def prepare_controllers(options): | |
258 | """Returns two lists of TestController instances, those to run, and those |
|
296 | """Returns two lists of TestController instances, those to run, and those | |
@@ -273,28 +311,13 b' def prepare_controllers(options):' | |||||
273 | test_sections['parallel'].enabled = False |
|
311 | test_sections['parallel'].enabled = False | |
274 |
|
312 | |||
275 | c_js = [JSController(name) for name in js_testgroups] |
|
313 | c_js = [JSController(name) for name in js_testgroups] | |
276 | c_py = [PyTestController(name) for name in py_testgroups] |
|
314 | c_py = [PyTestController(name, options) for name in py_testgroups] | |
277 |
|
||||
278 | configure_py_controllers(c_py, xunit=options.xunit, |
|
|||
279 | coverage=options.coverage, subproc_streams=options.subproc_streams, |
|
|||
280 | extra_args=options.extra_args) |
|
|||
281 |
|
315 | |||
282 | controllers = c_py + c_js |
|
316 | controllers = c_py + c_js | |
283 | to_run = [c for c in controllers if c.will_run] |
|
317 | to_run = [c for c in controllers if c.will_run] | |
284 | not_run = [c for c in controllers if not c.will_run] |
|
318 | not_run = [c for c in controllers if not c.will_run] | |
285 | return to_run, not_run |
|
319 | return to_run, not_run | |
286 |
|
320 | |||
287 | def configure_py_controllers(controllers, xunit=False, coverage=False, |
|
|||
288 | subproc_streams='capture', extra_args=()): |
|
|||
289 | """Apply options for a collection of TestController objects.""" |
|
|||
290 | for controller in controllers: |
|
|||
291 | if xunit: |
|
|||
292 | controller.add_xunit() |
|
|||
293 | if coverage: |
|
|||
294 | controller.add_coverage() |
|
|||
295 | controller.env['IPTEST_SUBPROC_STREAMS'] = subproc_streams |
|
|||
296 | controller.cmd.extend(extra_args) |
|
|||
297 |
|
||||
298 | def do_run(controller, buffer_output=True): |
|
321 | def do_run(controller, buffer_output=True): | |
299 | """Setup and run a test controller. |
|
322 | """Setup and run a test controller. | |
300 |
|
323 |
@@ -26,19 +26,6 b' files for each profile, and the files look like :file:`ipython_config.py` or' | |||||
26 | which defaults to :file:`$HOME/.ipython`. For Windows users, :envvar:`HOME` |
|
26 | which defaults to :file:`$HOME/.ipython`. For Windows users, :envvar:`HOME` | |
27 | resolves to :file:`C:\\Users\\{YourUserName}` in most instances. |
|
27 | resolves to :file:`C:\\Users\\{YourUserName}` in most instances. | |
28 |
|
28 | |||
29 |
|
||||
30 | Eventloop integration |
|
|||
31 | --------------------- |
|
|||
32 |
|
||||
33 | Previously IPython had command line options for controlling GUI event loop |
|
|||
34 | integration (-gthread, -qthread, -q4thread, -wthread, -pylab). As of IPython |
|
|||
35 | version 0.11, these have been removed. Please see the new ``%gui`` |
|
|||
36 | magic command or :ref:`this section <gui_support>` for details on the new |
|
|||
37 | interface, or specify the gui at the commandline:: |
|
|||
38 |
|
||||
39 | $ ipython --gui=qt |
|
|||
40 |
|
||||
41 |
|
||||
42 | Command-line Options |
|
29 | Command-line Options | |
43 | -------------------- |
|
30 | -------------------- | |
44 |
|
31 | |||
@@ -131,11 +118,9 b' Note that cell magics *always* require an explicit ``%%`` prefix, automagic' | |||||
131 | calling only works for line magics. |
|
118 | calling only works for line magics. | |
132 |
|
119 | |||
133 | The automagic system has the lowest possible precedence in name searches, so |
|
120 | The automagic system has the lowest possible precedence in name searches, so | |
134 | defining an identifier with the same name as an existing magic function will |
|
121 | you can freely use variables with the same names as magic commands. If a magic | |
135 | shadow it for automagic use. You can still access the shadowed magic function |
|
122 | command is 'shadowed' by a variable, you will need the explicit ``%`` prefix to | |
136 | by explicitly using the ``%`` character at the beginning of the line. |
|
123 | use it: | |
137 |
|
||||
138 | An example (with automagic on) should clarify all this: |
|
|||
139 |
|
124 | |||
140 | .. sourcecode:: ipython |
|
125 | .. sourcecode:: ipython | |
141 |
|
126 | |||
@@ -378,25 +363,16 b' Search command history' | |||||
378 | IPython provides two ways for searching through previous input and thus |
|
363 | IPython provides two ways for searching through previous input and thus | |
379 | reduce the need for repetitive typing: |
|
364 | reduce the need for repetitive typing: | |
380 |
|
365 | |||
381 | 1. Start typing, and then use Ctrl-p (previous,up) and Ctrl-n |
|
366 | 1. Start typing, and then use the up and down arrow keys (or :kbd:`Ctrl-p` | |
382 |
|
|
367 | and :kbd:`Ctrl-n`) to search through only the history items that match | |
383 |
what you've typed so far. |
|
368 | what you've typed so far. | |
384 | prompt, they just behave like normal arrow keys. |
|
369 | 2. Hit :kbd:`Ctrl-r`: to open a search prompt. Begin typing and the system | |
385 | 2. Hit Ctrl-r: opens a search prompt. Begin typing and the system |
|
|||
386 | searches your history for lines that contain what you've typed so |
|
370 | searches your history for lines that contain what you've typed so | |
387 | far, completing as much as it can. |
|
371 | far, completing as much as it can. | |
388 |
|
372 | |||
389 |
|
||||
390 | Persistent command history across sessions |
|
|||
391 | ++++++++++++++++++++++++++++++++++++++++++ |
|
|||
392 |
|
||||
393 | IPython will save your input history when it leaves and reload it next |
|
373 | IPython will save your input history when it leaves and reload it next | |
394 | time you restart it. By default, the history file is named |
|
374 | time you restart it. By default, the history file is named | |
395 | $IPYTHONDIR/profile_<name>/history.sqlite. This allows you to keep |
|
375 | :file:`.ipython/profile_{name}/history.sqlite`. | |
396 | separate histories related to various tasks: commands related to |
|
|||
397 | numerical work will not be clobbered by a system shell history, for |
|
|||
398 | example. |
|
|||
399 |
|
||||
400 |
|
376 | |||
401 | Autoindent |
|
377 | Autoindent | |
402 | ++++++++++ |
|
378 | ++++++++++ | |
@@ -405,7 +381,7 b" IPython can recognize lines ending in ':' and indent the next line," | |||||
405 | while also un-indenting automatically after 'raise' or 'return'. |
|
381 | while also un-indenting automatically after 'raise' or 'return'. | |
406 |
|
382 | |||
407 | This feature uses the readline library, so it will honor your |
|
383 | This feature uses the readline library, so it will honor your | |
408 | :file:`~/.inputrc` configuration (or whatever file your INPUTRC variable points |
|
384 | :file:`~/.inputrc` configuration (or whatever file your :envvar:`INPUTRC` environment variable points | |
409 | to). Adding the following lines to your :file:`.inputrc` file can make |
|
385 | to). Adding the following lines to your :file:`.inputrc` file can make | |
410 | indenting/unindenting more convenient (M-i indents, M-u unindents):: |
|
386 | indenting/unindenting more convenient (M-i indents, M-u unindents):: | |
411 |
|
387 | |||
@@ -441,20 +417,15 b' Customizing readline behavior' | |||||
441 |
|
417 | |||
442 | All these features are based on the GNU readline library, which has an |
|
418 | All these features are based on the GNU readline library, which has an | |
443 | extremely customizable interface. Normally, readline is configured via a |
|
419 | extremely customizable interface. Normally, readline is configured via a | |
444 | file which defines the behavior of the library; the details of the |
|
420 | :file:`.inputrc` file. IPython respects this, and you can also customise readline | |
445 | syntax for this can be found in the readline documentation available |
|
421 | by setting the following :doc:`configuration </config/intro>` options: | |
446 | with your system or on the Internet. IPython doesn't read this file (if |
|
422 | ||
447 | it exists) directly, but it does support passing to readline valid |
|
423 | * ``InteractiveShell.readline_parse_and_bind``: this holds a list of strings to be executed | |
448 | options via a simple interface. In brief, you can customize readline by |
|
|||
449 | setting the following options in your configuration file (note |
|
|||
450 | that these options can not be specified at the command line): |
|
|||
451 |
|
||||
452 | * **readline_parse_and_bind**: this holds a list of strings to be executed |
|
|||
453 | via a readline.parse_and_bind() command. The syntax for valid commands |
|
424 | via a readline.parse_and_bind() command. The syntax for valid commands | |
454 | of this kind can be found by reading the documentation for the GNU |
|
425 | of this kind can be found by reading the documentation for the GNU | |
455 | readline library, as these commands are of the kind which readline |
|
426 | readline library, as these commands are of the kind which readline | |
456 | accepts in its configuration file. |
|
427 | accepts in its configuration file. | |
457 |
* |
|
428 | * ``InteractiveShell.readline_remove_delims``: a string of characters to be removed | |
458 | from the default word-delimiters list used by readline, so that |
|
429 | from the default word-delimiters list used by readline, so that | |
459 | completions may be performed on strings which contain them. Do not |
|
430 | completions may be performed on strings which contain them. Do not | |
460 | change the default value unless you know what you're doing. |
|
431 | change the default value unless you know what you're doing. | |
@@ -595,7 +566,7 b' detailed tracebacks. Furthermore, both normal and verbose tracebacks can' | |||||
595 | be colored (if your terminal supports it) which makes them much easier |
|
566 | be colored (if your terminal supports it) which makes them much easier | |
596 | to parse visually. |
|
567 | to parse visually. | |
597 |
|
568 | |||
598 |
See the magic xmode and colors functions for details |
|
569 | See the magic xmode and colors functions for details. | |
599 |
|
570 | |||
600 | These features are basically a terminal version of Ka-Ping Yee's cgitb |
|
571 | These features are basically a terminal version of Ka-Ping Yee's cgitb | |
601 | module, now part of the standard Python library. |
|
572 | module, now part of the standard Python library. | |
@@ -612,7 +583,7 b' retrieved as variables (besides the usual arrow key recall), in' | |||||
612 | addition to the %rep magic command that brings a history entry |
|
583 | addition to the %rep magic command that brings a history entry | |
613 | up for editing on the next command line. |
|
584 | up for editing on the next command line. | |
614 |
|
585 | |||
615 |
The following |
|
586 | The following variables always exist: | |
616 |
|
587 | |||
617 | * _i, _ii, _iii: store previous, next previous and next-next previous inputs. |
|
588 | * _i, _ii, _iii: store previous, next previous and next-next previous inputs. | |
618 | * In, _ih : a list of all inputs; _ih[n] is the input from line n. If you |
|
589 | * In, _ih : a list of all inputs; _ih[n] is the input from line n. If you | |
@@ -622,14 +593,13 b" The following GLOBAL variables always exist (so don't overwrite them!):" | |||||
622 | Additionally, global variables named _i<n> are dynamically created (<n> |
|
593 | Additionally, global variables named _i<n> are dynamically created (<n> | |
623 | being the prompt counter), so ``_i<n> == _ih[<n>] == In[<n>]``. |
|
594 | being the prompt counter), so ``_i<n> == _ih[<n>] == In[<n>]``. | |
624 |
|
595 | |||
625 | For example, what you typed at prompt 14 is available as _i14, _ih[14] |
|
596 | For example, what you typed at prompt 14 is available as ``_i14``, ``_ih[14]`` | |
626 | and In[14]. |
|
597 | and ``In[14]``. | |
627 |
|
598 | |||
628 | This allows you to easily cut and paste multi line interactive prompts |
|
599 | This allows you to easily cut and paste multi line interactive prompts | |
629 | by printing them out: they print like a clean string, without prompt |
|
600 | by printing them out: they print like a clean string, without prompt | |
630 | characters. You can also manipulate them like regular variables (they |
|
601 | characters. You can also manipulate them like regular variables (they | |
631 |
are strings), modify or exec them |
|
602 | are strings), modify or exec them. | |
632 | contents of input prompt 9. |
|
|||
633 |
|
603 | |||
634 | You can also re-execute multiple lines of input easily by using the |
|
604 | You can also re-execute multiple lines of input easily by using the | |
635 | magic %rerun or %macro functions. The macro system also allows you to re-execute |
|
605 | magic %rerun or %macro functions. The macro system also allows you to re-execute | |
@@ -655,9 +625,9 b' result (NOT assignments, for example) are cached. If you are familiar' | |||||
655 | with Mathematica, IPython's _ variables behave exactly like |
|
625 | with Mathematica, IPython's _ variables behave exactly like | |
656 | Mathematica's % variables. |
|
626 | Mathematica's % variables. | |
657 |
|
627 | |||
658 |
The following |
|
628 | The following variables always exist: | |
659 |
|
629 | |||
660 |
* [_] (a single underscore) |
|
630 | * [_] (a single underscore): stores previous output, like Python's | |
661 | default interpreter. |
|
631 | default interpreter. | |
662 | * [__] (two underscores): next previous. |
|
632 | * [__] (two underscores): next previous. | |
663 | * [___] (three underscores): next-next previous. |
|
633 | * [___] (three underscores): next-next previous. | |
@@ -665,22 +635,21 b" The following GLOBAL variables always exist (so don't overwrite them!):" | |||||
665 | Additionally, global variables named _<n> are dynamically created (<n> |
|
635 | Additionally, global variables named _<n> are dynamically created (<n> | |
666 | being the prompt counter), such that the result of output <n> is always |
|
636 | being the prompt counter), such that the result of output <n> is always | |
667 | available as _<n> (don't use the angle brackets, just the number, e.g. |
|
637 | available as _<n> (don't use the angle brackets, just the number, e.g. | |
668 | _21). |
|
638 | ``_21``). | |
669 |
|
639 | |||
670 | These variables are also stored in a global dictionary (not a |
|
640 | These variables are also stored in a global dictionary (not a | |
671 | list, since it only has entries for lines which returned a result) |
|
641 | list, since it only has entries for lines which returned a result) | |
672 | available under the names _oh and Out (similar to _ih and In). So the |
|
642 | available under the names _oh and Out (similar to _ih and In). So the | |
673 | output from line 12 can be obtained as _12, Out[12] or _oh[12]. If you |
|
643 | output from line 12 can be obtained as ``_12``, ``Out[12]`` or ``_oh[12]``. If you | |
674 | accidentally overwrite the Out variable you can recover it by typing |
|
644 | accidentally overwrite the Out variable you can recover it by typing | |
675 |
|
|
645 | ``Out=_oh`` at the prompt. | |
676 |
|
646 | |||
677 | This system obviously can potentially put heavy memory demands on your |
|
647 | This system obviously can potentially put heavy memory demands on your | |
678 | system, since it prevents Python's garbage collector from removing any |
|
648 | system, since it prevents Python's garbage collector from removing any | |
679 | previously computed results. You can control how many results are kept |
|
649 | previously computed results. You can control how many results are kept | |
680 | in memory with the option (at the command line or in your configuration |
|
650 | in memory with the configuration option ``InteractiveShell.cache_size``. | |
681 | file) cache_size. If you set it to 0, the whole system is completely |
|
651 | If you set it to 0, output caching is disabled. You can also use the ``%reset`` | |
682 | disabled and the prompts revert to the classic '>>>' of normal Python. |
|
652 | and ``%xdel`` magics to clear large items from memory. | |
683 |
|
||||
684 |
|
653 | |||
685 | Directory history |
|
654 | Directory history | |
686 | ----------------- |
|
655 | ----------------- | |
@@ -697,16 +666,17 b' Automatic parentheses and quotes' | |||||
697 | These features were adapted from Nathan Gray's LazyPython. They are |
|
666 | These features were adapted from Nathan Gray's LazyPython. They are | |
698 | meant to allow less typing for common situations. |
|
667 | meant to allow less typing for common situations. | |
699 |
|
668 | |||
700 |
|
||||
701 | Automatic parentheses |
|
|||
702 | +++++++++++++++++++++ |
|
|||
703 |
|
||||
704 | Callable objects (i.e. functions, methods, etc) can be invoked like this |
|
669 | Callable objects (i.e. functions, methods, etc) can be invoked like this | |
705 | (notice the commas between the arguments):: |
|
670 | (notice the commas between the arguments):: | |
706 |
|
671 | |||
707 | In [1]: callable_ob arg1, arg2, arg3 |
|
672 | In [1]: callable_ob arg1, arg2, arg3 | |
708 | ------> callable_ob(arg1, arg2, arg3) |
|
673 | ------> callable_ob(arg1, arg2, arg3) | |
709 |
|
674 | |||
|
675 | .. note:: | |||
|
676 | This feature is disabled by default. To enable it, use the ``%autocall`` | |||
|
677 | magic command. The commands below with special prefixes will always work, | |||
|
678 | however. | |||
|
679 | ||||
710 | You can force automatic parentheses by using '/' as the first character |
|
680 | You can force automatic parentheses by using '/' as the first character | |
711 | of a line. For example:: |
|
681 | of a line. For example:: | |
712 |
|
682 | |||
@@ -730,17 +700,10 b' but this will work::' | |||||
730 | Out[5]: [(1, 4), (2, 5), (3, 6)] |
|
700 | Out[5]: [(1, 4), (2, 5), (3, 6)] | |
731 |
|
701 | |||
732 | IPython tells you that it has altered your command line by displaying |
|
702 | IPython tells you that it has altered your command line by displaying | |
733 |
the new command line preceded by ->. |
|
703 | the new command line preceded by ``--->``. | |
734 |
|
||||
735 | In [6]: callable list |
|
|||
736 | ------> callable(list) |
|
|||
737 |
|
704 | |||
738 |
|
705 | You can force automatic quoting of a function's arguments by using ``,`` | ||
739 | Automatic quoting |
|
706 | or ``;`` as the first character of a line. For example:: | |
740 | +++++++++++++++++ |
|
|||
741 |
|
||||
742 | You can force automatic quoting of a function's arguments by using ',' |
|
|||
743 | or ';' as the first character of a line. For example:: |
|
|||
744 |
|
707 | |||
745 | In [1]: ,my_function /home/me # becomes my_function("/home/me") |
|
708 | In [1]: ,my_function /home/me # becomes my_function("/home/me") | |
746 |
|
709 | |||
@@ -770,7 +733,7 b' environment anytime you start Python::' | |||||
770 | raise SystemExit |
|
733 | raise SystemExit | |
771 |
|
734 | |||
772 | The ``raise SystemExit`` is needed to exit Python when |
|
735 | The ``raise SystemExit`` is needed to exit Python when | |
773 |
it finishes, otherwise you'll be back at the normal Python |
|
736 | it finishes, otherwise you'll be back at the normal Python ``>>>`` | |
774 | prompt. |
|
737 | prompt. | |
775 |
|
738 | |||
776 | This is probably useful to developers who manage multiple Python |
|
739 | This is probably useful to developers who manage multiple Python | |
@@ -788,12 +751,12 b' You can start a regular IPython session with' | |||||
788 | .. sourcecode:: python |
|
751 | .. sourcecode:: python | |
789 |
|
752 | |||
790 | import IPython |
|
753 | import IPython | |
791 | IPython.start_ipython() |
|
754 | IPython.start_ipython(argv=[]) | |
792 |
|
755 | |||
793 | at any point in your program. This will load IPython configuration, |
|
756 | at any point in your program. This will load IPython configuration, | |
794 | startup files, and everything, just as if it were a normal IPython session. |
|
757 | startup files, and everything, just as if it were a normal IPython session. | |
795 | In addition to this, |
|
758 | ||
796 |
|
|
759 | It is also possible to embed an IPython shell in a namespace in your Python code. | |
797 | This allows you to evaluate dynamically the state of your code, |
|
760 | This allows you to evaluate dynamically the state of your code, | |
798 | operate with your variables, analyze them, etc. Note however that |
|
761 | operate with your variables, analyze them, etc. Note however that | |
799 | any changes you make to values while in the shell do not propagate back |
|
762 | any changes you make to values while in the shell do not propagate back | |
@@ -826,13 +789,10 b' your Python programs for this to work (detailed examples follow later)::' | |||||
826 |
|
789 | |||
827 | embed() # this call anywhere in your program will start IPython |
|
790 | embed() # this call anywhere in your program will start IPython | |
828 |
|
791 | |||
829 | .. note:: |
|
792 | You can also embed an IPython *kernel*, for use with qtconsole, etc. via | |
830 |
|
793 | ``IPython.embed_kernel()``. This should function work the same way, but you can | ||
831 | As of 0.13, you can embed an IPython *kernel*, for use with qtconsole, |
|
794 | connect an external frontend (``ipython qtconsole`` or ``ipython console``), | |
832 | etc. via ``IPython.embed_kernel()`` instead of ``IPython.embed()``. |
|
795 | rather than interacting with it in the terminal. | |
833 | It should function just the same as regular embed, but you connect |
|
|||
834 | an external frontend rather than IPython starting up in the local |
|
|||
835 | terminal. |
|
|||
836 |
|
796 | |||
837 | You can run embedded instances even in code which is itself being run at |
|
797 | You can run embedded instances even in code which is itself being run at | |
838 | the IPython interactive prompt with '%run <filename>'. Since it's easy |
|
798 | the IPython interactive prompt with '%run <filename>'. Since it's easy | |
@@ -872,45 +832,31 b' pdb, the Python debugger, is a powerful interactive debugger which' | |||||
872 | allows you to step through code, set breakpoints, watch variables, |
|
832 | allows you to step through code, set breakpoints, watch variables, | |
873 | etc. IPython makes it very easy to start any script under the control |
|
833 | etc. IPython makes it very easy to start any script under the control | |
874 | of pdb, regardless of whether you have wrapped it into a 'main()' |
|
834 | of pdb, regardless of whether you have wrapped it into a 'main()' | |
875 |
function or not. For this, simply type |
|
835 | function or not. For this, simply type ``%run -d myscript`` at an | |
876 |
IPython prompt. See the %run command's documentation |
|
836 | IPython prompt. See the %run command's documentation for more details, including | |
877 | in Sec. magic_ for more details, including how to control where pdb |
|
837 | how to control where pdb will stop execution first. | |
878 | will stop execution first. |
|
|||
879 |
|
||||
880 | For more information on the use of the pdb debugger, read the included |
|
|||
881 | pdb.doc file (part of the standard Python distribution). On a stock |
|
|||
882 | Linux system it is located at /usr/lib/python2.3/pdb.doc, but the |
|
|||
883 | easiest way to read it is by using the help() function of the pdb module |
|
|||
884 | as follows (in an IPython prompt):: |
|
|||
885 |
|
838 | |||
886 | In [1]: import pdb |
|
839 | For more information on the use of the pdb debugger, see :ref:`debugger-commands` | |
887 | In [2]: pdb.help() |
|
840 | in the Python documentation. | |
888 |
|
841 | |||
889 | This will load the pdb.doc document in a file viewer for you automatically. |
|
|||
890 |
|
842 | |||
|
843 | Post-mortem debugging | |||
|
844 | --------------------- | |||
891 |
|
845 | |||
892 | Automatic invocation of pdb on exceptions |
|
846 | Going into a debugger when an exception occurs can be | |
893 | ----------------------------------------- |
|
|||
894 |
|
||||
895 | IPython, if started with the ``--pdb`` option (or if the option is set in |
|
|||
896 | your config file) can call the Python pdb debugger every time your code |
|
|||
897 | triggers an uncaught exception. This feature |
|
|||
898 | can also be toggled at any time with the %pdb magic command. This can be |
|
|||
899 | extremely useful in order to find the origin of subtle bugs, because pdb |
|
847 | extremely useful in order to find the origin of subtle bugs, because pdb | |
900 | opens up at the point in your code which triggered the exception, and |
|
848 | opens up at the point in your code which triggered the exception, and | |
901 | while your program is at this point 'dead', all the data is still |
|
849 | while your program is at this point 'dead', all the data is still | |
902 | available and you can walk up and down the stack frame and understand |
|
850 | available and you can walk up and down the stack frame and understand | |
903 | the origin of the problem. |
|
851 | the origin of the problem. | |
904 |
|
852 | |||
905 | Furthermore, you can use these debugging facilities both with the |
|
853 | You can use the ``%debug`` magic after an exception has occurred to start | |
906 | embedded IPython mode and without IPython at all. For an embedded shell |
|
854 | post-mortem debugging. IPython can also call debugger every time your code | |
907 | (see sec. Embedding_), simply call the constructor with |
|
855 | triggers an uncaught exception. This feature can be toggled with the %pdb magic | |
908 | ``--pdb`` in the argument string and pdb will automatically be called if an |
|
856 | command, or you can start IPython with the ``--pdb`` option. | |
909 | uncaught exception is triggered by your code. |
|
|||
910 |
|
857 | |||
911 | For stand-alone use of the feature in your programs which do not use |
|
858 | For a post-mortem debugger in your programs outside IPython, | |
912 |
|
|
859 | put the following lines toward the top of your 'main' routine:: | |
913 | routine:: |
|
|||
914 |
|
860 | |||
915 | import sys |
|
861 | import sys | |
916 | from IPython.core import ultratb |
|
862 | from IPython.core import ultratb | |
@@ -925,25 +871,10 b' options which can be set in IPython with ``--colors`` and ``--xmode``.' | |||||
925 | This will give any of your programs detailed, colored tracebacks with |
|
871 | This will give any of your programs detailed, colored tracebacks with | |
926 | automatic invocation of pdb. |
|
872 | automatic invocation of pdb. | |
927 |
|
873 | |||
928 |
|
||||
929 | Extensions for syntax processing |
|
|||
930 | ================================ |
|
|||
931 |
|
||||
932 | This isn't for the faint of heart, because the potential for breaking |
|
|||
933 | things is quite high. But it can be a very powerful and useful feature. |
|
|||
934 | In a nutshell, you can redefine the way IPython processes the user input |
|
|||
935 | line to accept new, special extensions to the syntax without needing to |
|
|||
936 | change any of IPython's own code. |
|
|||
937 |
|
||||
938 | In the IPython/extensions directory you will find some examples |
|
|||
939 | supplied, which we will briefly describe now. These can be used 'as is' |
|
|||
940 | (and both provide very useful functionality), or you can use them as a |
|
|||
941 | starting point for writing your own extensions. |
|
|||
942 |
|
||||
943 | .. _pasting_with_prompts: |
|
874 | .. _pasting_with_prompts: | |
944 |
|
875 | |||
945 | Pasting of code starting with Python or IPython prompts |
|
876 | Pasting of code starting with Python or IPython prompts | |
946 | ------------------------------------------------------- |
|
877 | ======================================================= | |
947 |
|
878 | |||
948 | IPython is smart enough to filter out input prompts, be they plain Python ones |
|
879 | IPython is smart enough to filter out input prompts, be they plain Python ones | |
949 | (``>>>`` and ``...``) or IPython ones (``In [N]:`` and ``...:``). You can |
|
880 | (``>>>`` and ``...``) or IPython ones (``In [N]:`` and ``...:``). You can | |
@@ -1012,6 +943,11 b' object, do::' | |||||
1012 |
|
943 | |||
1013 | %gui wx |
|
944 | %gui wx | |
1014 |
|
945 | |||
|
946 | You can also start IPython with an event loop set up using the :option:`--gui` | |||
|
947 | flag:: | |||
|
948 | ||||
|
949 | $ ipython --gui=qt | |||
|
950 | ||||
1015 | For information on IPython's matplotlib_ integration (and the ``matplotlib`` |
|
951 | For information on IPython's matplotlib_ integration (and the ``matplotlib`` | |
1016 | mode) see :ref:`this section <matplotlib_support>`. |
|
952 | mode) see :ref:`this section <matplotlib_support>`. | |
1017 |
|
953 | |||
@@ -1135,29 +1071,23 b' demo::' | |||||
1135 | mydemo = Demo('myscript.py') |
|
1071 | mydemo = Demo('myscript.py') | |
1136 |
|
1072 | |||
1137 | This creates the mydemo object, whose blocks you run one at a time by |
|
1073 | This creates the mydemo object, whose blocks you run one at a time by | |
1138 |
simply calling the object with no arguments. |
|
1074 | simply calling the object with no arguments. Then call it to run each step | |
1139 | in IPython (the default), all you need to do is type:: |
|
1075 | of the demo:: | |
1140 |
|
1076 | |||
1141 |
mydemo |
|
1077 | mydemo() | |
1142 |
|
1078 | |||
1143 | and IPython will call it, executing each block. Demo objects can be |
|
1079 | Demo objects can be | |
1144 | restarted, you can move forward or back skipping blocks, re-execute the |
|
1080 | restarted, you can move forward or back skipping blocks, re-execute the | |
1145 | last block, etc. Simply use the Tab key on a demo object to see its |
|
1081 | last block, etc. See the :mod:`IPython.lib.demo` module and the | |
1146 | methods, and call '?' on them to see their docstrings for more usage |
|
1082 | :class:`~IPython.lib.demo.Demo` class for details. | |
1147 | details. In addition, the demo module itself contains a comprehensive |
|
|||
1148 | docstring, which you can access via:: |
|
|||
1149 |
|
||||
1150 | from IPython.lib import demo |
|
|||
1151 |
|
||||
1152 | demo? |
|
|||
1153 |
|
1083 | |||
1154 |
Limitations: |
|
1084 | Limitations: These demos are limited to | |
1155 | fairly simple uses. In particular, you cannot break up sections within |
|
1085 | fairly simple uses. In particular, you cannot break up sections within | |
1156 | indented code (loops, if statements, function definitions, etc.) |
|
1086 | indented code (loops, if statements, function definitions, etc.) | |
1157 | Supporting something like this would basically require tracking the |
|
1087 | Supporting something like this would basically require tracking the | |
1158 | internal execution state of the Python interpreter, so only top-level |
|
1088 | internal execution state of the Python interpreter, so only top-level | |
1159 | divisions are allowed. If you want to be able to open an IPython |
|
1089 | divisions are allowed. If you want to be able to open an IPython | |
1160 | instance at an arbitrary point in a program, you can use IPython's |
|
1090 | instance at an arbitrary point in a program, you can use IPython's | |
1161 | embedding facilities, see :func:`IPython.embed` for details. |
|
1091 | :ref:`embedding facilities <Embedding>`. | |
1162 |
|
1092 | |||
1163 | .. include:: ../links.txt |
|
1093 | .. include:: ../links.txt |
@@ -1,5 +1,4 b'' | |||||
1 | #!/usr/bin/env python |
|
1 | #!/usr/bin/env python | |
2 |
|
||||
3 | """An example of how to embed an IPython shell into a running program. |
|
2 | """An example of how to embed an IPython shell into a running program. | |
4 |
|
3 | |||
5 | Please see the documentation in the IPython.Shell module for more details. |
|
4 | Please see the documentation in the IPython.Shell module for more details. | |
@@ -13,7 +12,7 b' from __future__ import print_function' | |||||
13 |
|
12 | |||
14 | # The basics to get you going: |
|
13 | # The basics to get you going: | |
15 |
|
14 | |||
16 |
# IPython |
|
15 | # IPython injects get_ipython into builtins, so you can know if you have nested | |
17 | # copies running. |
|
16 | # copies running. | |
18 |
|
17 | |||
19 | # Try running this code both at the command line and from inside IPython (with |
|
18 | # Try running this code both at the command line and from inside IPython (with |
@@ -16,7 +16,6 b" print('unless auto_all has been set to true in the demo object')" | |||||
16 |
|
16 | |||
17 | # The mark below defines a block boundary, which is a point where IPython will |
|
17 | # The mark below defines a block boundary, which is a point where IPython will | |
18 | # stop execution and return to the interactive prompt. |
|
18 | # stop execution and return to the interactive prompt. | |
19 | # Note that in actual interactive execution, |
|
|||
20 | # <demo> --- stop --- |
|
19 | # <demo> --- stop --- | |
21 |
|
20 | |||
22 | x = 1 |
|
21 | x = 1 |
General Comments 0
You need to be logged in to leave comments.
Login now