diff --git a/IPython/html/static/base/less/page.less b/IPython/html/static/base/less/page.less index 2b0dd58..88acff7 100644 --- a/IPython/html/static/base/less/page.less +++ b/IPython/html/static/base/less/page.less @@ -144,3 +144,10 @@ span#login_widget > .button, .fa(); content: @ico; } + +@media (min-width: @screen-sm-min) { + select.form-control { + margin-left: @padding-base-horizontal; + margin-right: @padding-base-horizontal; + } +} diff --git a/IPython/html/static/notebook/js/kernelselector.js b/IPython/html/static/notebook/js/kernelselector.js index 953a232..c9623e7 100644 --- a/IPython/html/static/notebook/js/kernelselector.js +++ b/IPython/html/static/notebook/js/kernelselector.js @@ -25,7 +25,8 @@ define([ // Make the object globally available for user convenience & inspection IPython.kernelselector = this; this._finish_load = null; - this.loaded = new Promise(function(resolve, reject) { + this._loaded = false; + this.loaded = new Promise(function(resolve) { that._finish_load = resolve; }); @@ -37,16 +38,12 @@ define([ utils.promising_ajax(url).then($.proxy(this._got_kernelspecs, this)); }; - KernelSelector.prototype._got_kernelspecs = function(data) { - var that = this; - this.kernelspecs = data.kernelspecs; - var change_kernel_submenu = $("#menu-change-kernel-submenu"); - var new_notebook_submenu = $("#menu-new-notebook-submenu"); - - var keys = Object.keys(data.kernelspecs).sort(function (a, b) { + var _sorted_names = function(kernelspecs) { + // sort kernel names + return Object.keys(kernelspecs).sort(function (a, b) { // sort by display_name - var da = data.kernelspecs[a].spec.display_name; - var db = data.kernelspecs[b].spec.display_name; + var da = kernelspecs[a].spec.display_name; + var db = kernelspecs[b].spec.display_name; if (da === db) { return 0; } else if (da > db) { @@ -55,6 +52,14 @@ define([ return -1; } }); + }; + + KernelSelector.prototype._got_kernelspecs = function(data) { + var that = this; + this.kernelspecs = data.kernelspecs; + var change_kernel_submenu = $("#menu-change-kernel-submenu"); + var new_notebook_submenu = $("#menu-new-notebook-submenu"); + var keys = _sorted_names(data.kernelspecs); keys.map(function (key) { // Create the Kernel > Change kernel submenu @@ -83,6 +88,7 @@ define([ }); // trigger loaded promise + this._loaded = true; this._finish_load(); }; @@ -154,28 +160,115 @@ define([ } }; - KernelSelector.prototype.set_kernel = function (kernel_name) { - /** set the kernel by name, ensuring kernelspecs have been loaded, first */ + KernelSelector.prototype.set_kernel = function (selected) { + /** set the kernel by name, ensuring kernelspecs have been loaded, first + + kernel can be just a kernel name, or a notebook kernelspec metadata + (name, language, display_name). + */ var that = this; - return this.loaded.then(function () { - that._set_kernel(kernel_name); - }); + if (typeof selected === 'string') { + selected = { + name: selected + }; + } + if (this._loaded) { + this._set_kernel(selected); + } else { + return this.loaded.then(function () { + that._set_kernel(selected); + }); + } }; - KernelSelector.prototype._set_kernel = function (kernel_name) { + KernelSelector.prototype._set_kernel = function (selected) { /** Actually set the kernel (kernelspecs have been loaded) */ - if (kernel_name === this.current_selection) { + if (selected.name === this.current_selection) { // only trigger event if value changed return; } - var ks = this.kernelspecs[kernel_name]; + var kernelspecs = this.kernelspecs; + var ks = kernelspecs[selected.name]; + if (ks === undefined) { + var available = _sorted_names(kernelspecs); + var matches = []; + if (selected.language && selected.language.length > 0) { + available.map(function (name) { + if (kernelspecs[name].spec.language.toLowerCase() === selected.language.toLowerCase()) { + matches.push(name); + } + }); + } + if (matches.length === 1) { + ks = kernelspecs[matches[0]]; + console.log("No exact match found for " + selected.name + + ", using only kernel that matches language=" + selected.language, ks); + this.events.trigger("spec_match_found.Kernel", { + selected: selected, + found: ks, + }); + } + // if still undefined, trigger failure event + if (ks === undefined) { + this.events.trigger("spec_not_found.Kernel", { + selected: selected, + matches: matches, + available: available, + }); + return; + } + } if (this.notebook._session_starting) { console.error("Cannot change kernel while waiting for pending session start."); return; } - this.current_selection = kernel_name; + this.current_selection = ks.name; this.events.trigger('spec_changed.Kernel', ks); }; + + KernelSelector.prototype._spec_not_found = function (event, data) { + var that = this; + var select = $("