jupyterlab / jupyterlab-plugin-playground

A dynamic extension loader for JupyterLab
BSD 3-Clause "New" or "Revised" License
48 stars 15 forks source link

Add support for lumino plugin deactivation #54

Open fcollonval opened 1 year ago

fcollonval commented 1 year ago

This add the support for the plugin deactivate method that will be support in JupyterLab 3.6.

welcome[bot] commented 1 year ago

Thanks for submitting your first pull request! You are awesome! :hugs:
If you haven't done so already, check out Jupyter's Code of Conduct. Also, please make sure you followed the pull request template, as this will help us review your contribution more quickly. welcome You can meet the other Jovyans by joining our Discourse forum. There is also a intro thread there where you can stop by and say Hi! :wave:
Welcome to the Jupyter community! :tada:

bollwyvl commented 1 year ago

y'all got any other breaking changes hidden up yer sleeve?

bollwyvl commented 1 year ago

(to be fair, many of these are very cool, but i'm really wondering about why these are being backported: every one of them reduces the chance that existing third-party extensions will work properly, which is going to lead to a lot of unhappy users on launch day)

fcollonval commented 1 year ago

@bollwyvl we don't use the deactivate in lumino application nor in JupyterLab. And if we start to do so (for instance for the extension manager), we should really first have a discussion about which core plugin will support it.

But for this project to work with a code like the one below, we need a proper way to deactivate the previous version. Otherwise reloading the plugin will fail due to the command ID being already registered.

import {
  JupyterFrontEnd,
  JupyterFrontEndPlugin,
} from '@jupyterlab/application';
import {
  DisposableSet
} from '@lumino/disposable';

const resources = new DisposableSet();

const plugin: JupyterFrontEndPlugin<void> = {
  id: 'mydynamicplugin',
  autoStart: true,
  requires: ['@jupyterlab/apputils:ICommandPalette'],
  activate: (app, palette) => {
    console.log('Hello from a dynamically loaded plugin!');

    // We can use `.app` here to do something with the JupyterLab
    // app instance, such as adding a new command
    let commandID = 'MySuperCoolDynamicCommand';
    let toggle = true;
    const cmd = app.commands.addCommand(commandID, {
      label: 'My Super Cool  Command',
      isToggled: function () {
        return toggle;
      },
      execute: function () {
        console.log('Executed ' + commandID + 'uu');
        toggle = !toggle;
      }
    });
    resources.add(cmd);

    const item = palette.addItem({
      command: commandID,
      // make it appear right at the top!
      category: 'AAA',
      args: {}
    });
    resources.add(item);
  },
  deactivate: () => {
    resources.dispose();
    resources.clear();
  }
};

export default plugin;

And incidentally this raises a good question, is it really easier to create a plugin for JupyterLab as it requires a deactivate function that is otherwise not needed. And that function will require good knowledge to be written properly.

bollwyvl commented 1 year ago

Again, it's important that these things get improved... but on X, rather than X.y. In a playground setting, exposing these things with docs is great and helpful.