jupyterlab-emrys
Version:
A computational environment for Jupyter. Powered by Emrys
251 lines (250 loc) • 9.26 kB
JavaScript
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
;
var dialog_1 = require('../dialog');
/**
* Bring up a dialog to select a kernel.
*/
function selectKernel(options) {
var specs = options.specs;
var kernel = options.kernel;
// Create the dialog body.
var body = document.createElement('div');
var text = document.createElement('pre');
text.textContent = "Select kernel for\n\"" + options.name + "\"";
body.appendChild(text);
if (kernel) {
var displayName = specs.kernelspecs[kernel.name].spec.display_name;
text.textContent += "\nCurrent: " + displayName;
text.title = ("Kernel Name: " + displayName + "\n") +
("Kernel Id: " + kernel.id);
}
var selector = document.createElement('select');
body.appendChild(selector);
// Get the current sessions, populate the kernels, and show the dialog.
var lang = options.preferredLanguage;
populateKernels(selector, specs, options.sessions, lang);
return dialog_1.showDialog({
title: 'Select Kernel',
body: body,
okText: 'SELECT'
}).then(function (result) {
// Change the kernel if a kernel was selected.
if (result.text === 'SELECT') {
return JSON.parse(selector.value);
}
return void 0;
});
}
exports.selectKernel = selectKernel;
/**
* Change the kernel on a context.
*/
function selectKernelForContext(context, host) {
return context.listSessions().then(function (sessions) {
var options = {
name: context.path.split('/').pop(),
specs: context.kernelspecs,
sessions: sessions,
preferredLanguage: context.model.defaultKernelLanguage,
kernel: context.kernel.model,
host: host
};
return selectKernel(options);
}).then(function (kernel) {
context.changeKernel(kernel);
});
}
exports.selectKernelForContext = selectKernelForContext;
/**
* Get the appropriate kernel name.
*/
function findKernel(kernelName, language, specs) {
if (kernelName === 'unknown') {
return specs.default;
}
// Look for an exact match.
for (var specName in specs.kernelspecs) {
if (specName === kernelName) {
return kernelName;
}
}
// Next try to match the language name.
if (language === 'unknown') {
return specs.default;
}
for (var specName in specs.kernelspecs) {
var kernelLanguage = specs.kernelspecs[specName].spec.language;
if (language === kernelLanguage) {
console.log('No exact match found for ' + specName +
', using kernel ' + specName + ' that matches ' +
'language=' + language);
return specName;
}
}
// Finally, use the default kernel.
if (kernelName) {
console.log(("No matching kernel found for " + kernelName + ", ") +
("using default kernel " + specs.default));
}
return specs.default;
}
exports.findKernel = findKernel;
/**
* Populate a kernel dropdown list.
*
* @param node - The host html element.
*
* @param specs - The available kernel spec information.
*
* @param running - The list of running session ids.
*
* @param preferredLanguage - The preferred language for the kernel.
*
* #### Notes
* Populates the list with separated sections:
* - Kernels matching the preferred language (display names).
* - "None" signifying no kernel.
* - The remaining kernels.
* - Sessions matching the preferred language (file names).
* - The remaining sessions.
* If no preferred language is given or no kernels are found using
* the preferred language, the default kernel is used in the first
* section. Kernels are sorted by display name. Sessions display the
* base name of the file with an ellipsis overflow and a tooltip with
* the explicit session information.
*/
function populateKernels(node, specs, running, preferredLanguage) {
// Clear any existing options.
while (node.firstChild) {
node.removeChild(node.firstChild);
}
var maxLength = 10;
// Create mappings of display names and languages for kernel name.
var displayNames = Object.create(null);
var languages = Object.create(null);
for (var name_1 in specs.kernelspecs) {
displayNames[name_1] = specs.kernelspecs[name_1].spec.display_name;
maxLength = Math.max(maxLength, displayNames[name_1].length);
languages[name_1] = specs.kernelspecs[name_1].spec.language;
}
// Handle a preferred kernel language in order of display name.
var names = [];
if (preferredLanguage) {
for (var name_2 in specs.kernelspecs) {
if (languages[name_2] === preferredLanguage) {
names.push(name_2);
}
}
names.sort(function (a, b) { return displayNames[a].localeCompare(displayNames[b]); });
for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
var name_3 = names_1[_i];
node.appendChild(optionForName(name_3, displayNames[name_3]));
}
}
// Use the default kernel if no preferred language or none were found.
if (!names.length) {
var name_4 = specs.default;
node.appendChild(optionForName(name_4, displayNames[name_4]));
}
// Add a separator.
node.appendChild(createSeparatorOption(maxLength));
// Add the option to have no kernel.
var option = document.createElement('option');
option.text = 'None';
option.value = 'null';
node.appendChild(option);
node.appendChild(createSeparatorOption(maxLength));
// Add the rest of the kernel names in alphabetical order.
var otherNames = [];
for (var name_5 in specs.kernelspecs) {
if (names.indexOf(name_5) !== -1) {
continue;
}
otherNames.push(name_5);
}
otherNames.sort(function (a, b) { return displayNames[a].localeCompare(displayNames[b]); });
for (var _a = 0, otherNames_1 = otherNames; _a < otherNames_1.length; _a++) {
var name_6 = otherNames_1[_a];
node.appendChild(optionForName(name_6, displayNames[name_6]));
}
// Add a separator option if there were any other names.
if (otherNames.length) {
node.appendChild(createSeparatorOption(maxLength));
}
// Add the sessions using the preferred language first.
var matchingSessions = [];
if (preferredLanguage) {
for (var _b = 0, running_1 = running; _b < running_1.length; _b++) {
var session = running_1[_b];
if (languages[session.kernel.name] === preferredLanguage) {
matchingSessions.push(session);
}
}
if (matchingSessions) {
matchingSessions.sort(function (a, b) {
return a.notebook.path.localeCompare(b.notebook.path);
});
for (var _c = 0, matchingSessions_1 = matchingSessions; _c < matchingSessions_1.length; _c++) {
var session = matchingSessions_1[_c];
var name_7 = displayNames[session.kernel.name];
node.appendChild(optionForSession(session, name_7, maxLength));
}
node.appendChild(createSeparatorOption(maxLength));
}
}
// Add the other remaining sessions.
var otherSessions = [];
for (var _d = 0, running_2 = running; _d < running_2.length; _d++) {
var session = running_2[_d];
if (matchingSessions.indexOf(session) === -1) {
otherSessions.push(session);
}
}
if (otherSessions) {
otherSessions.sort(function (a, b) {
return a.notebook.path.localeCompare(b.notebook.path);
});
for (var _e = 0, otherSessions_1 = otherSessions; _e < otherSessions_1.length; _e++) {
var session = otherSessions_1[_e];
var name_8 = displayNames[session.kernel.name];
node.appendChild(optionForSession(session, name_8, maxLength));
}
}
node.selectedIndex = 0;
}
exports.populateKernels = populateKernels;
/**
* Create a separator option.
*/
function createSeparatorOption(length) {
var option = document.createElement('option');
option.disabled = true;
option.text = Array(length).join('─');
return option;
}
/**
* Create an option element for a kernel name.
*/
function optionForName(name, displayName) {
var option = document.createElement('option');
option.text = displayName;
option.value = JSON.stringify({ name: name });
return option;
}
/**
* Create an option element for a session.
*/
function optionForSession(session, displayName, maxLength) {
var option = document.createElement('option');
var sessionName = session.notebook.path.split('/').pop();
if (sessionName.length > maxLength) {
sessionName = sessionName.slice(0, maxLength - 3) + '...';
}
option.text = sessionName;
option.value = JSON.stringify({ id: session.kernel.id });
option.title = ("Path: " + session.notebook.path + "\n") +
("Kernel Name: " + displayName + "\n") +
("Kernel Id: " + session.kernel.id);
return option;
}