Show More
@@ -144,3 +144,10 b' span#login_widget > .button,' | |||||
144 | .fa(); |
|
144 | .fa(); | |
145 | content: @ico; |
|
145 | content: @ico; | |
146 | } |
|
146 | } | |
|
147 | ||||
|
148 | @media (min-width: @screen-sm-min) { | |||
|
149 | select.form-control { | |||
|
150 | margin-left: @padding-base-horizontal; | |||
|
151 | margin-right: @padding-base-horizontal; | |||
|
152 | } | |||
|
153 | } |
@@ -25,7 +25,8 b' define([' | |||||
25 | // Make the object globally available for user convenience & inspection |
|
25 | // Make the object globally available for user convenience & inspection | |
26 | IPython.kernelselector = this; |
|
26 | IPython.kernelselector = this; | |
27 | this._finish_load = null; |
|
27 | this._finish_load = null; | |
28 | this.loaded = new Promise(function(resolve, reject) { |
|
28 | this._loaded = false; | |
|
29 | this.loaded = new Promise(function(resolve) { | |||
29 | that._finish_load = resolve; |
|
30 | that._finish_load = resolve; | |
30 | }); |
|
31 | }); | |
31 |
|
32 | |||
@@ -37,16 +38,12 b' define([' | |||||
37 | utils.promising_ajax(url).then($.proxy(this._got_kernelspecs, this)); |
|
38 | utils.promising_ajax(url).then($.proxy(this._got_kernelspecs, this)); | |
38 | }; |
|
39 | }; | |
39 |
|
40 | |||
40 | KernelSelector.prototype._got_kernelspecs = function(data) { |
|
41 | var _sorted_names = function(kernelspecs) { | |
41 | var that = this; |
|
42 | // sort kernel names | |
42 | this.kernelspecs = data.kernelspecs; |
|
43 | return Object.keys(kernelspecs).sort(function (a, b) { | |
43 | var change_kernel_submenu = $("#menu-change-kernel-submenu"); |
|
|||
44 | var new_notebook_submenu = $("#menu-new-notebook-submenu"); |
|
|||
45 |
|
||||
46 | var keys = Object.keys(data.kernelspecs).sort(function (a, b) { |
|
|||
47 | // sort by display_name |
|
44 | // sort by display_name | |
48 |
var da = |
|
45 | var da = kernelspecs[a].spec.display_name; | |
49 |
var db = |
|
46 | var db = kernelspecs[b].spec.display_name; | |
50 | if (da === db) { |
|
47 | if (da === db) { | |
51 | return 0; |
|
48 | return 0; | |
52 | } else if (da > db) { |
|
49 | } else if (da > db) { | |
@@ -55,6 +52,14 b' define([' | |||||
55 | return -1; |
|
52 | return -1; | |
56 | } |
|
53 | } | |
57 | }); |
|
54 | }); | |
|
55 | }; | |||
|
56 | ||||
|
57 | KernelSelector.prototype._got_kernelspecs = function(data) { | |||
|
58 | var that = this; | |||
|
59 | this.kernelspecs = data.kernelspecs; | |||
|
60 | var change_kernel_submenu = $("#menu-change-kernel-submenu"); | |||
|
61 | var new_notebook_submenu = $("#menu-new-notebook-submenu"); | |||
|
62 | var keys = _sorted_names(data.kernelspecs); | |||
58 |
|
63 | |||
59 | keys.map(function (key) { |
|
64 | keys.map(function (key) { | |
60 | // Create the Kernel > Change kernel submenu |
|
65 | // Create the Kernel > Change kernel submenu | |
@@ -83,6 +88,7 b' define([' | |||||
83 |
|
88 | |||
84 | }); |
|
89 | }); | |
85 | // trigger loaded promise |
|
90 | // trigger loaded promise | |
|
91 | this._loaded = true; | |||
86 | this._finish_load(); |
|
92 | this._finish_load(); | |
87 | }; |
|
93 | }; | |
88 |
|
94 | |||
@@ -154,28 +160,115 b' define([' | |||||
154 | } |
|
160 | } | |
155 | }; |
|
161 | }; | |
156 |
|
162 | |||
157 |
KernelSelector.prototype.set_kernel = function ( |
|
163 | KernelSelector.prototype.set_kernel = function (selected) { | |
158 |
/** set the kernel by name, ensuring kernelspecs have been loaded, first |
|
164 | /** set the kernel by name, ensuring kernelspecs have been loaded, first | |
|
165 | ||||
|
166 | kernel can be just a kernel name, or a notebook kernelspec metadata | |||
|
167 | (name, language, display_name). | |||
|
168 | */ | |||
159 | var that = this; |
|
169 | var that = this; | |
160 | return this.loaded.then(function () { |
|
170 | if (typeof selected === 'string') { | |
161 | that._set_kernel(kernel_name); |
|
171 | selected = { | |
162 | }); |
|
172 | name: selected | |
|
173 | }; | |||
|
174 | } | |||
|
175 | if (this._loaded) { | |||
|
176 | this._set_kernel(selected); | |||
|
177 | } else { | |||
|
178 | return this.loaded.then(function () { | |||
|
179 | that._set_kernel(selected); | |||
|
180 | }); | |||
|
181 | } | |||
163 | }; |
|
182 | }; | |
164 |
|
183 | |||
165 |
KernelSelector.prototype._set_kernel = function ( |
|
184 | KernelSelector.prototype._set_kernel = function (selected) { | |
166 | /** Actually set the kernel (kernelspecs have been loaded) */ |
|
185 | /** Actually set the kernel (kernelspecs have been loaded) */ | |
167 |
if ( |
|
186 | if (selected.name === this.current_selection) { | |
168 | // only trigger event if value changed |
|
187 | // only trigger event if value changed | |
169 | return; |
|
188 | return; | |
170 | } |
|
189 | } | |
171 |
var ks = this.kernelspecs |
|
190 | var kernelspecs = this.kernelspecs; | |
|
191 | var ks = kernelspecs[selected.name]; | |||
|
192 | if (ks === undefined) { | |||
|
193 | var available = _sorted_names(kernelspecs); | |||
|
194 | var matches = []; | |||
|
195 | if (selected.language && selected.language.length > 0) { | |||
|
196 | available.map(function (name) { | |||
|
197 | if (kernelspecs[name].spec.language.toLowerCase() === selected.language.toLowerCase()) { | |||
|
198 | matches.push(name); | |||
|
199 | } | |||
|
200 | }); | |||
|
201 | } | |||
|
202 | if (matches.length === 1) { | |||
|
203 | ks = kernelspecs[matches[0]]; | |||
|
204 | console.log("No exact match found for " + selected.name + | |||
|
205 | ", using only kernel that matches language=" + selected.language, ks); | |||
|
206 | this.events.trigger("spec_match_found.Kernel", { | |||
|
207 | selected: selected, | |||
|
208 | found: ks, | |||
|
209 | }); | |||
|
210 | } | |||
|
211 | // if still undefined, trigger failure event | |||
|
212 | if (ks === undefined) { | |||
|
213 | this.events.trigger("spec_not_found.Kernel", { | |||
|
214 | selected: selected, | |||
|
215 | matches: matches, | |||
|
216 | available: available, | |||
|
217 | }); | |||
|
218 | return; | |||
|
219 | } | |||
|
220 | } | |||
172 | if (this.notebook._session_starting) { |
|
221 | if (this.notebook._session_starting) { | |
173 | console.error("Cannot change kernel while waiting for pending session start."); |
|
222 | console.error("Cannot change kernel while waiting for pending session start."); | |
174 | return; |
|
223 | return; | |
175 | } |
|
224 | } | |
176 |
this.current_selection = k |
|
225 | this.current_selection = ks.name; | |
177 | this.events.trigger('spec_changed.Kernel', ks); |
|
226 | this.events.trigger('spec_changed.Kernel', ks); | |
178 | }; |
|
227 | }; | |
|
228 | ||||
|
229 | KernelSelector.prototype._spec_not_found = function (event, data) { | |||
|
230 | var that = this; | |||
|
231 | var select = $("<select>").addClass('form-control'); | |||
|
232 | console.warn("Kernelspec not found:", data); | |||
|
233 | var names; | |||
|
234 | if (data.matches.length > 1) { | |||
|
235 | names = data.matches; | |||
|
236 | } else { | |||
|
237 | names = data.available; | |||
|
238 | } | |||
|
239 | names.map(function (name) { | |||
|
240 | var ks = that.kernelspecs[name]; | |||
|
241 | select.append( | |||
|
242 | $('<option/>').attr('value', ks.name).text(ks.spec.display_name || ks.name) | |||
|
243 | ); | |||
|
244 | }); | |||
|
245 | ||||
|
246 | var body = $("<form>").addClass("form-inline").append( | |||
|
247 | $("<span>").text( | |||
|
248 | "I couldn't find a kernel matching " + (data.selected.display_name || data.name) + "." + | |||
|
249 | " Please select a kernel:" | |||
|
250 | ) | |||
|
251 | ).append(select); | |||
|
252 | ||||
|
253 | dialog.modal({ | |||
|
254 | title : 'Kernel not found', | |||
|
255 | body : body, | |||
|
256 | buttons : { | |||
|
257 | 'Continue without kernel' : { | |||
|
258 | class : 'btn-danger', | |||
|
259 | click : function () { | |||
|
260 | that.events.trigger('no_kernel.Kernel'); | |||
|
261 | } | |||
|
262 | }, | |||
|
263 | OK : { | |||
|
264 | class : 'btn-primary', | |||
|
265 | click : function () { | |||
|
266 | that.set_kernel(select.val()); | |||
|
267 | } | |||
|
268 | } | |||
|
269 | } | |||
|
270 | }); | |||
|
271 | }; | |||
179 |
|
272 | |||
180 | KernelSelector.prototype.new_notebook = function (kernel_name) { |
|
273 | KernelSelector.prototype.new_notebook = function (kernel_name) { | |
181 |
|
274 | |||
@@ -213,7 +306,7 b' define([' | |||||
213 | KernelSelector.prototype.bind_events = function() { |
|
306 | KernelSelector.prototype.bind_events = function() { | |
214 | var that = this; |
|
307 | var that = this; | |
215 | this.events.on('spec_changed.Kernel', $.proxy(this._spec_changed, this)); |
|
308 | this.events.on('spec_changed.Kernel', $.proxy(this._spec_changed, this)); | |
216 |
|
309 | this.events.on('spec_not_found.Kernel', $.proxy(this._spec_not_found, this)); | ||
217 | this.events.on('kernel_created.Session', function (event, data) { |
|
310 | this.events.on('kernel_created.Session', function (event, data) { | |
218 | that.set_kernel(data.kernel.name); |
|
311 | that.set_kernel(data.kernel.name); | |
219 | }); |
|
312 | }); |
@@ -226,8 +226,11 b' define(function (require) {' | |||||
226 | }); |
|
226 | }); | |
227 |
|
227 | |||
228 | this.events.on('spec_changed.Kernel', function(event, data) { |
|
228 | this.events.on('spec_changed.Kernel', function(event, data) { | |
229 | that.metadata.kernelspec = |
|
229 | that.metadata.kernelspec = { | |
230 |
|
|
230 | name: data.name, | |
|
231 | display_name: data.spec.display_name, | |||
|
232 | language: data.spec.language, | |||
|
233 | }; | |||
231 | // start session if the current session isn't already correct |
|
234 | // start session if the current session isn't already correct | |
232 | if (!(this.session && this.session.kernel && this.session.kernel.name === data.name)) { |
|
235 | if (!(this.session && this.session.kernel && this.session.kernel.name === data.name)) { | |
233 | that.start_session(data.name); |
|
236 | that.start_session(data.name); | |
@@ -2208,18 +2211,14 b' define(function (require) {' | |||||
2208 | } |
|
2211 | } | |
2209 |
|
2212 | |||
2210 | if (this.session === null) { |
|
2213 | if (this.session === null) { | |
2211 | var kernel_name; |
|
2214 | var kernel_name = utils.get_url_param('kernel_name'); | |
2212 | if (this.metadata.kernelspec) { |
|
|||
2213 | var kernelspec = this.metadata.kernelspec || {}; |
|
|||
2214 | kernel_name = kernelspec.name; |
|
|||
2215 | } else { |
|
|||
2216 | kernel_name = utils.get_url_param('kernel_name'); |
|
|||
2217 | } |
|
|||
2218 | if (kernel_name) { |
|
2215 | if (kernel_name) { | |
2219 | // setting kernel_name here triggers start_session |
|
|||
2220 | this.kernel_selector.set_kernel(kernel_name); |
|
2216 | this.kernel_selector.set_kernel(kernel_name); | |
|
2217 | } else if (this.metadata.kernelspec) { | |||
|
2218 | this.kernel_selector.set_kernel(this.metadata.kernelspec); | |||
2221 | } else { |
|
2219 | } else { | |
2222 | // start a new session with the server's default kernel |
|
2220 | // setting kernel via set_kernel above triggers start_session, | |
|
2221 | // otherwise start a new session with the server's default kernel | |||
2223 | // spec_changed events will fire after kernel is loaded |
|
2222 | // spec_changed events will fire after kernel is loaded | |
2224 | this.start_session(); |
|
2223 | this.start_session(); | |
2225 | } |
|
2224 | } |
@@ -14,7 +14,7 b' define([' | |||||
14 | this.save_widget = options.save_widget; |
|
14 | this.save_widget = options.save_widget; | |
15 | this.notebook = options.notebook; |
|
15 | this.notebook = options.notebook; | |
16 | this.keyboard_manager = options.keyboard_manager; |
|
16 | this.keyboard_manager = options.keyboard_manager; | |
17 | } |
|
17 | }; | |
18 |
|
18 | |||
19 | NotebookNotificationArea.prototype = Object.create(NotificationArea.prototype); |
|
19 | NotebookNotificationArea.prototype = Object.create(NotificationArea.prototype); | |
20 |
|
20 | |||
@@ -38,7 +38,7 b' define([' | |||||
38 | var knw = this.new_notification_widget('kernel'); |
|
38 | var knw = this.new_notification_widget('kernel'); | |
39 | var $kernel_ind_icon = $("#kernel_indicator_icon"); |
|
39 | var $kernel_ind_icon = $("#kernel_indicator_icon"); | |
40 | var $modal_ind_icon = $("#modal_indicator"); |
|
40 | var $modal_ind_icon = $("#modal_indicator"); | |
41 | var $body = $('body') |
|
41 | var $body = $('body'); | |
42 |
|
42 | |||
43 | // Command/Edit mode |
|
43 | // Command/Edit mode | |
44 | this.events.on('edit_mode.Notebook', function () { |
|
44 | this.events.on('edit_mode.Notebook', function () { | |
@@ -57,9 +57,9 b' define([' | |||||
57 |
|
57 | |||
58 | // Implicitly start off in Command mode, switching to Edit mode will trigger event |
|
58 | // Implicitly start off in Command mode, switching to Edit mode will trigger event | |
59 | $modal_ind_icon.addClass('modal_indicator').attr('title','Command Mode'); |
|
59 | $modal_ind_icon.addClass('modal_indicator').attr('title','Command Mode'); | |
60 | $body.addClass('command_mode') |
|
60 | $body.addClass('command_mode'); | |
61 |
|
61 | |||
62 |
// Kernel events |
|
62 | // Kernel events | |
63 |
|
63 | |||
64 | // this can be either kernel_created.Kernel or kernel_created.Session |
|
64 | // this can be either kernel_created.Kernel or kernel_created.Session | |
65 | this.events.on('kernel_created.Kernel kernel_created.Session', function () { |
|
65 | this.events.on('kernel_created.Kernel kernel_created.Session', function () { | |
@@ -105,7 +105,7 b' define([' | |||||
105 | } |
|
105 | } | |
106 | } |
|
106 | } | |
107 | }); |
|
107 | }); | |
108 |
} |
|
108 | } | |
109 |
|
109 | |||
110 | that.save_widget.update_document_title(); |
|
110 | that.save_widget.update_document_title(); | |
111 | knw.danger("Dead kernel"); |
|
111 | knw.danger("Dead kernel"); | |
@@ -187,6 +187,10 b' define([' | |||||
187 |
|
187 | |||
188 | showMsg(); |
|
188 | showMsg(); | |
189 | }); |
|
189 | }); | |
|
190 | ||||
|
191 | this.events.on("no_kernel.Kernel", function (evt, data) { | |||
|
192 | $("#kernel_indicator").find('.kernel_indicator_name').text("No Kernel"); | |||
|
193 | }); | |||
190 |
|
194 | |||
191 | this.events.on('kernel_dead.Session', function (evt, info) { |
|
195 | this.events.on('kernel_dead.Session', function (evt, info) { | |
192 | var full = info.xhr.responseJSON.message; |
|
196 | var full = info.xhr.responseJSON.message; | |
@@ -251,6 +255,13 b' define([' | |||||
251 | window.document.title='(Busy) '+window.document.title; |
|
255 | window.document.title='(Busy) '+window.document.title; | |
252 | $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy'); |
|
256 | $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy'); | |
253 | }); |
|
257 | }); | |
|
258 | ||||
|
259 | this.events.on('spec_match_found.Kernel', function (evt, data) { | |||
|
260 | that.widget('kernelspec').info("Using kernel: " + data.found.spec.display_name, 3000, undefined, { | |||
|
261 | title: "Only candidate for language: " + data.selected.language + " was " + data.found.spec.display_name | |||
|
262 | }); | |||
|
263 | }); | |||
|
264 | ||||
254 |
|
265 | |||
255 | // Start the kernel indicator in the busy state, and send a kernel_info request. |
|
266 | // Start the kernel indicator in the busy state, and send a kernel_info request. | |
256 | // When the kernel_info reply arrives, the kernel is idle. |
|
267 | // When the kernel_info reply arrives, the kernel is idle. |
@@ -8588,6 +8588,12 b' span#login_widget > .button .badge,' | |||||
8588 | width: 700px; |
|
8588 | width: 700px; | |
8589 | } |
|
8589 | } | |
8590 | } |
|
8590 | } | |
|
8591 | @media (min-width: 768px) { | |||
|
8592 | select.form-control { | |||
|
8593 | margin-left: 12px; | |||
|
8594 | margin-right: 12px; | |||
|
8595 | } | |||
|
8596 | } | |||
8591 | /*! |
|
8597 | /*! | |
8592 | * |
|
8598 | * | |
8593 | * IPython auth |
|
8599 | * IPython auth |
@@ -36,6 +36,7 b' def _pythonfirst(s):' | |||||
36 | class KernelSpec(HasTraits): |
|
36 | class KernelSpec(HasTraits): | |
37 | argv = List() |
|
37 | argv = List() | |
38 | display_name = Unicode() |
|
38 | display_name = Unicode() | |
|
39 | language = Unicode() | |||
39 | env = Dict() |
|
40 | env = Dict() | |
40 | resource_dir = Unicode() |
|
41 | resource_dir = Unicode() | |
41 |
|
42 | |||
@@ -54,6 +55,7 b' class KernelSpec(HasTraits):' | |||||
54 | d = dict(argv=self.argv, |
|
55 | d = dict(argv=self.argv, | |
55 | env=self.env, |
|
56 | env=self.env, | |
56 | display_name=self.display_name, |
|
57 | display_name=self.display_name, | |
|
58 | language=self.language, | |||
57 | ) |
|
59 | ) | |
58 |
|
60 | |||
59 | return d |
|
61 | return d | |
@@ -109,8 +111,10 b' class KernelSpecManager(HasTraits):' | |||||
109 | The native kernel is the kernel using the same Python runtime as this |
|
111 | The native kernel is the kernel using the same Python runtime as this | |
110 | process. This will put its information in the user kernels directory. |
|
112 | process. This will put its information in the user kernels directory. | |
111 | """ |
|
113 | """ | |
112 | return {'argv': make_ipkernel_cmd(), |
|
114 | return { | |
|
115 | 'argv': make_ipkernel_cmd(), | |||
113 | 'display_name': 'Python %i' % (3 if PY3 else 2), |
|
116 | 'display_name': 'Python %i' % (3 if PY3 else 2), | |
|
117 | 'language': 'python', | |||
114 | } |
|
118 | } | |
115 |
|
119 | |||
116 | @property |
|
120 | @property |
@@ -112,6 +112,11 b' JSON serialised dictionary containing the following keys and values:' | |||||
112 | - **display_name**: The kernel's name as it should be displayed in the UI. |
|
112 | - **display_name**: The kernel's name as it should be displayed in the UI. | |
113 | Unlike the kernel name used in the API, this can contain arbitrary unicode |
|
113 | Unlike the kernel name used in the API, this can contain arbitrary unicode | |
114 | characters. |
|
114 | characters. | |
|
115 | - **language**: The name of the language of the kernel. | |||
|
116 | When loading notebooks, if no matching kernelspec key (may differ across machines) | |||
|
117 | is found, a kernel with a matching `language` will be used. | |||
|
118 | This allows a notebook written on any Python or Julia kernel to be properly associated | |||
|
119 | with the user's Python or Julia kernel, even if they aren't listed under the same name as the author's. | |||
115 | - **env** (optional): A dictionary of environment variables to set for the kernel. |
|
120 | - **env** (optional): A dictionary of environment variables to set for the kernel. | |
116 | These will be added to the current environment variables before the kernel is |
|
121 | These will be added to the current environment variables before the kernel is | |
117 | started. |
|
122 | started. | |
@@ -121,7 +126,8 b' For example, the kernel.json file for IPython looks like this::' | |||||
121 | { |
|
126 | { | |
122 | "argv": ["python3", "-c", "from IPython.kernel.zmq.kernelapp import main; main()", |
|
127 | "argv": ["python3", "-c", "from IPython.kernel.zmq.kernelapp import main; main()", | |
123 | "-f", "{connection_file}"], |
|
128 | "-f", "{connection_file}"], | |
124 | "display_name": "IPython (Python 3)" |
|
129 | "display_name": "IPython (Python 3)", | |
|
130 | "language": "python" | |||
125 | } |
|
131 | } | |
126 |
|
132 | |||
127 | To see the available kernel specs, run:: |
|
133 | To see the available kernel specs, run:: |
General Comments 0
You need to be logged in to leave comments.
Login now