##// END OF EJS Templates
This feature was discussed in #6123, but it doesn't look like anything was ever incorporated into the IPython Notebook....
Nathan Heijermans -
Show More
@@ -253,6 +253,14 b" define(['require'"
253 env.notebook.delete_cell();
253 env.notebook.delete_cell();
254 }
254 }
255 },
255 },
256 'toggle-unsolicited-message-display':{
257 help: 'toggle display from external clients',
258 icon: 'fa-sitemap',
259 help_index: 'gb',
260 handler: function (env) {
261 env.notebook.toggle_ignore_unsolicited_msgs();
262 }
263 },
256 'interrupt-kernel':{
264 'interrupt-kernel':{
257 icon: 'fa-stop',
265 icon: 'fa-stop',
258 help_index : 'ha',
266 help_index : 'ha',
@@ -95,6 +95,7 b' define(['
95 'space' : 'ipython.scroll-down',
95 'space' : 'ipython.scroll-down',
96 'down' : 'ipython.select-next-cell',
96 'down' : 'ipython.select-next-cell',
97 'i,i' : 'ipython.interrupt-kernel',
97 'i,i' : 'ipython.interrupt-kernel',
98 'e': 'ipython.toggle-unsolicited-message-display',
98 '0,0' : 'ipython.restart-kernel',
99 '0,0' : 'ipython.restart-kernel',
99 'd,d' : 'ipython.delete-cell',
100 'd,d' : 'ipython.delete-cell',
100 'esc': 'ipython.close-pager',
101 'esc': 'ipython.close-pager',
@@ -278,6 +278,9 b' define(['
278 });
278 });
279
279
280 // Kernel
280 // Kernel
281 this.element.find('#toggle_unsolicited').click(function() {
282 IPython.notebook.toggle_ignore_unsolicited_msgs();
283 });
281 this.element.find('#int_kernel').click(function () {
284 this.element.find('#int_kernel').click(function () {
282 that.notebook.kernel.interrupt();
285 that.notebook.kernel.interrupt();
283 });
286 });
@@ -135,6 +135,7 b' define(['
135 this.undelete_below = false;
135 this.undelete_below = false;
136 this.paste_enabled = false;
136 this.paste_enabled = false;
137 this.writable = false;
137 this.writable = false;
138 this.ignore_unsolicited_msgs = false;
138 // It is important to start out in command mode to match the intial mode
139 // It is important to start out in command mode to match the intial mode
139 // of the KeyboardManager.
140 // of the KeyboardManager.
140 this.mode = 'command';
141 this.mode = 'command';
@@ -1562,6 +1563,60 b' define(['
1562 this.get_selected_cell().toggle_line_numbers();
1563 this.get_selected_cell().toggle_line_numbers();
1563 };
1564 };
1564
1565
1566 // Support for displaying input and output messages from other iPy clients.
1567
1568 /**
1569 * Toggles the ability to display input/output message events from
1570 * externally connected clients (i.e. other iPython shells, vim-ipython,
1571 * etc).
1572 *
1573 * @method toggle_ignore_unsolicited_msgs
1574 */
1575 Notebook.prototype.toggle_ignore_unsolicited_msgs = function () {
1576 this.ignore_unsolicited_msgs = !this.ignore_unsolicited_msgs;
1577 this.events.trigger('toggle_unsolicited_msgs.Notebook',
1578 [this.ignore_unsolicited_msgs]);
1579 return this.ignore_unsolicited_msgs;
1580 };
1581
1582 /**
1583 * Handles the display of unsolicited messages, i.e. inputs or outputs that
1584 * were generated by a client other than this notebook. New messages are
1585 * displayed at the bottom of the notebook.
1586 *
1587 * @method handle_unsolicited_msg
1588 */
1589 Notebook.prototype.handle_unsolicited_msg = function(msg) {
1590 if (this.ignore_unsolicited_msgs) {
1591 return;
1592 }
1593 if (msg.msg_type == 'execute_input') {
1594 var cell = this.insert_cell_at_bottom('code');
1595 if (cell) {
1596 var cell_index = this.ncells() - 1;
1597 cell.last_msg_id = msg.parent_header.msg_id;
1598 cell.set_text(msg.content.code);
1599 cell._handle_execute_reply(msg);
1600 this.scroll_to_cell(cell_index);
1601 this.select(cell_index);
1602 }
1603 } else {
1604 /* Find the input cell that corresponds with the output, then add
1605 * the contents to the cell's output area.
1606 */
1607 var count = this.ncells();
1608 while (count--) {
1609 var cell = this.get_cell(count);
1610 if (cell && cell.last_msg_id == msg.parent_header.msg_id) {
1611 cell.output_area.handle_output(msg);
1612 this.scroll_to_cell(count);
1613 this.select(count);
1614 break;
1615 }
1616 }
1617 }
1618 };
1619
1565 /**
1620 /**
1566 * Set the codemirror mode for all code cells, including the default for
1621 * Set the codemirror mode for all code cells, including the default for
1567 * new code cells.
1622 * new code cells.
@@ -1639,6 +1694,7 b' define(['
1639 cell.set_kernel(this.session.kernel);
1694 cell.set_kernel(this.session.kernel);
1640 }
1695 }
1641 }
1696 }
1697 this.kernel.unsolicited_msg_callback = $.proxy(this.handle_unsolicited_msg, this);
1642 };
1698 };
1643 Notebook.prototype._session_start_failed = function (jqxhr, status, error){
1699 Notebook.prototype._session_start_failed = function (jqxhr, status, error){
1644 this._session_starting = false;
1700 this._session_starting = false;
@@ -279,6 +279,11 b' define(['
279 nnw.warning(error.message || "Notebook copy failed");
279 nnw.warning(error.message || "Notebook copy failed");
280 });
280 });
281
281
282 this.events.on('toggle_unsolicited_msgs.Notebook', function(evt, ignored) {
283 var msg = (ignored? "Ignoring": "Showing") + " I/O from external clients";
284 nnw.set_message(msg, 1000);
285 });
286
282 // Checkpoint events
287 // Checkpoint events
283 this.events.on('checkpoint_created.Notebook', function (evt, data) {
288 this.events.on('checkpoint_created.Notebook', function (evt, data) {
284 var msg = "Checkpoint created";
289 var msg = "Checkpoint created";
@@ -47,6 +47,7 b' define(['
47 this.session_id = utils.uuid();
47 this.session_id = utils.uuid();
48 this._msg_callbacks = {};
48 this._msg_callbacks = {};
49 this.info_reply = {}; // kernel_info_reply stored here after starting
49 this.info_reply = {}; // kernel_info_reply stored here after starting
50 this.unsolicited_msg_callback = null;
50
51
51 if (typeof(WebSocket) !== 'undefined') {
52 if (typeof(WebSocket) !== 'undefined') {
52 this.WebSocket = WebSocket;
53 this.WebSocket = WebSocket;
@@ -136,6 +137,7 b' define(['
136 this._iopub_handlers = {};
137 this._iopub_handlers = {};
137 this.register_iopub_handler('status', $.proxy(this._handle_status_message, this));
138 this.register_iopub_handler('status', $.proxy(this._handle_status_message, this));
138 this.register_iopub_handler('clear_output', $.proxy(this._handle_clear_output, this));
139 this.register_iopub_handler('clear_output', $.proxy(this._handle_clear_output, this));
140 this.register_iopub_handler('execute_input', $.proxy(this._handle_input_message, this));
139
141
140 for (var i=0; i < output_msg_types.length; i++) {
142 for (var i=0; i < output_msg_types.length; i++) {
141 this.register_iopub_handler(output_msg_types[i], $.proxy(this._handle_output_message, this));
143 this.register_iopub_handler(output_msg_types[i], $.proxy(this._handle_output_message, this));
@@ -994,6 +996,11 b' define(['
994 Kernel.prototype._handle_output_message = function (msg) {
996 Kernel.prototype._handle_output_message = function (msg) {
995 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
997 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
996 if (!callbacks || !callbacks.iopub) {
998 if (!callbacks || !callbacks.iopub) {
999 if (this.unsolicited_msg_callback) {
1000 // The message came from another client. Let the UI decide what
1001 // to do with it.
1002 this.unsolicited_msg_callback(msg);
1003 }
997 return;
1004 return;
998 }
1005 }
999 var callback = callbacks.iopub.output;
1006 var callback = callbacks.iopub.output;
@@ -1003,6 +1010,20 b' define(['
1003 };
1010 };
1004
1011
1005 /**
1012 /**
1013 * Handle an input message (execute_input).
1014 *
1015 * @function _handle_input message
1016 */
1017 Kernel.prototype._handle_input_message = function (msg) {
1018 var callbacks = this.get_callbacks_for_msg(msg.parent_header.msg_id);
1019 if (!callbacks && this.unsolicited_msg_callback) {
1020 // The message came from another client. Let the UI decide what to
1021 // do with it.
1022 this.unsolicited_msg_callback(msg);
1023 }
1024 };
1025
1026 /**
1006 * Dispatch IOPub messages to respective handlers. Each message
1027 * Dispatch IOPub messages to respective handlers. Each message
1007 * type should have a handler.
1028 * type should have a handler.
1008 *
1029 *
@@ -228,6 +228,9 b' class="notebook_app"'
228 </li>
228 </li>
229 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Kernel</a>
229 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Kernel</a>
230 <ul id="kernel_menu" class="dropdown-menu">
230 <ul id="kernel_menu" class="dropdown-menu">
231 <li id="toggle_unsolicited"
232 title="Toggle display of unsolicited messages.">
233 <a href="#">Show/ignore unsolicited messages.</a></li>
231 <li id="int_kernel"
234 <li id="int_kernel"
232 title="Send KeyboardInterrupt (CTRL-C) to the Kernel">
235 title="Send KeyboardInterrupt (CTRL-C) to the Kernel">
233 <a href="#">Interrupt</a>
236 <a href="#">Interrupt</a>
General Comments 0
You need to be logged in to leave comments. Login now