Show "Select Kernel" in jupyter notebooks without the jupyter extension installed

This commit is contained in:
Rob Lourens 2021-07-22 17:22:51 -07:00
parent ece4337751
commit 33257a46b0
2 changed files with 47 additions and 31 deletions

View file

@ -3,31 +3,33 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable, DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { HoverProviderRegistry } from 'vs/editor/common/modes';
import * as nls from 'vs/nls';
import { Registry } from 'vs/platform/registry/common/platform';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IQuickInputButton, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { NOTEBOOK_ACTIONS_CATEGORY, SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
import { getNotebookEditorFromEditorPane, INotebookEditor, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_KERNEL_COUNT } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IDisposable, Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
import { configureKernelIcon, selectKernelIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { INotebookKernel, INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
import { NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ILabelService } from 'vs/platform/label/common/label';
import { ILogService } from 'vs/platform/log/common/log';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { HoverProviderRegistry } from 'vs/editor/common/modes';
import { Schemas } from 'vs/base/common/network';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IQuickInputButton, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { Registry } from 'vs/platform/registry/common/platform';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { IExtensionsViewPaneContainer, VIEWLET_ID as EXTENSION_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions';
import { NOTEBOOK_ACTIONS_CATEGORY, SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
import { getNotebookEditorFromEditorPane, INotebookEditor, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_KERNEL_COUNT, NOTEBOOK_VIEW_TYPE } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget';
import { configureKernelIcon, selectKernelIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
import { NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookKernel, INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/workbench/services/statusbar/common/statusbar';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
registerAction2(class extends Action2 {
constructor() {
@ -42,7 +44,7 @@ registerAction2(class extends Action2 {
id: MenuId.EditorTitle,
when: ContextKeyExpr.and(
NOTEBOOK_IS_ACTIVE_EDITOR,
NOTEBOOK_KERNEL_COUNT.notEqualsTo(0),
ContextKeyExpr.or(NOTEBOOK_KERNEL_COUNT.notEqualsTo(0), NOTEBOOK_VIEW_TYPE.isEqualTo('jupyter-notebook')),
ContextKeyExpr.notEquals('config.notebook.globalToolbar', true)
),
group: 'navigation',
@ -50,7 +52,7 @@ registerAction2(class extends Action2 {
}, {
id: MenuId.NotebookToolbar,
when: ContextKeyExpr.and(
NOTEBOOK_KERNEL_COUNT.notEqualsTo(0),
ContextKeyExpr.or(NOTEBOOK_KERNEL_COUNT.notEqualsTo(0), NOTEBOOK_VIEW_TYPE.isEqualTo('jupyter-notebook')),
ContextKeyExpr.equals('config.notebook.globalToolbar', true)
),
group: 'status',
@ -91,6 +93,7 @@ registerAction2(class extends Action2 {
const quickInputService = accessor.get(IQuickInputService);
const labelService = accessor.get(ILabelService);
const logService = accessor.get(ILogService);
const viewletService = accessor.get(IViewletService);
const editor = context?.notebookEditor ?? getNotebookEditorFromEditorPane(editorService.activeEditorPane);
if (!editor || !editor.hasModel()) {
@ -131,7 +134,7 @@ registerAction2(class extends Action2 {
iconClass: ThemeIcon.asClassName(configureKernelIcon),
tooltip: nls.localize('notebook.promptKernel.setDefaultTooltip', "Set as default for '{0}' notebooks", editor.textModel.viewType)
};
const picks = all.map(kernel => {
const picks: (KernelPick | IQuickPickItem)[] = all.map(kernel => {
const res = <KernelPick>{
kernel,
picked: kernel.id === selected?.id,
@ -149,17 +152,30 @@ registerAction2(class extends Action2 {
}
{ return res; }
});
if (!picks.length) {
picks.push({
id: 'install',
label: nls.localize('installKernels', "Install kernels from the marketplace"),
});
}
const pick = await quickInputService.pick(picks, {
placeHolder: selected
? nls.localize('prompt.placeholder.change', "Change kernel for '{0}'", labelService.getUriLabel(notebook.uri, { relative: true }))
: nls.localize('prompt.placeholder.select', "Select kernel for '{0}'", labelService.getUriLabel(notebook.uri, { relative: true })),
onDidTriggerItemButton: (context) => {
notebookKernelService.selectKernelForNotebookType(context.item.kernel, notebook.viewType);
if ('kernel' in context.item) {
notebookKernelService.selectKernelForNotebookType(context.item.kernel, notebook.viewType);
}
}
});
if (pick) {
newKernel = pick.kernel;
if (pick.id === 'install') {
await this._showJupyterExtension(viewletService);
} else if ('kernel' in pick) {
newKernel = pick.kernel;
}
}
}
@ -169,6 +185,12 @@ registerAction2(class extends Action2 {
}
return false;
}
private async _showJupyterExtension(viewletService: IViewletService) {
const viewlet = await viewletService.openViewlet(EXTENSION_VIEWLET_ID, true);
const view = viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer | undefined;
view?.search('@id:ms-toolsai.jupyter');
}
});

View file

@ -71,12 +71,6 @@ export class NotebooKernelActionViewItem extends ActionViewItem {
private _updateActionFromKernelInfo(info: INotebookKernelMatchResult): void {
if (info.all.length === 0) {
// should not happen - means "bad" context keys
this._resetAction();
return;
}
this._action.enabled = true;
const selectedOrSuggested = info.selected ?? info.suggested;
if (selectedOrSuggested) {
@ -88,7 +82,7 @@ export class NotebooKernelActionViewItem extends ActionViewItem {
}
} else {
// many kernels
// many kernels or no kernels
this._action.label = localize('select', "Select Kernel");
this._action.tooltip = '';
}