Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't call inherent commands through app.commands.execute in extension #10337

Open
Lykeios opened this issue Jun 3, 2021 · 4 comments
Open

Comments

@Lykeios
Copy link

Lykeios commented Jun 3, 2021

I saw that the function of opening up a new terminal is registered into the commands registry by the name of 'terminal:create-new' in the @jupyter/terminal-extension, and I think it's a recommended way to call it rather than write an open-up function myself.

Yet when I write some code like below and build it:

const extension: JupyterFrontEndPlugin = {
id: 'launcher_terminal:plugin',
autoStart: true,
activate: (app: JupyterFrontEnd) => {
console.log('JupyterLab extension launcher_terminal is activated!');
app.commands.execute('terminal:create-new');
}
};

the browser console prints it wasn't registered:

index.es6.js:367 Uncaught (in promise) Error: Command 'terminal:create-new' not registered.
at e.execute (index.es6.js:367)
at activate (index.js:13)
at index.es6.js:162
at async Promise.all (index 101)

Seems I didn't call the commands in a correct way. Is there any way to do the job? I didn't import @jupyter/terminal-extension, since the only member that can be imported is addCommands(). Should I import it anyway? If so, how could I do it in the right way?

@welcome
Copy link

welcome bot commented Jun 3, 2021

Thank you for opening your first issue in this project! Engagement like this is essential for open source projects! 🤗

If you haven't done so already, check out Jupyter's Code of Conduct. Also, please try to follow the issue template as it helps other other community members to contribute more effectively.
welcome
You can meet the other Jovyans by joining our Discourse forum. There is also an intro thread there where you can stop by and say Hi! 👋

Welcome to the Jupyter community! 🎉

@krassowski
Copy link
Member

Your code seems good and indeed this is the recommended way of using existing commands. One thing that might be missing is specifying that your "launcher_terminal:plugin" requires ITerminalTracker to be available (because this is the token provided by the plugin that registers "terminal:create-new" command). I think that this will ensure that your extension is started only after the command you need is available. The code would look like:

import {  JupyterFrontEnd,  JupyterFrontEndPlugin} from '@jupyterlab/application';
import { ITerminalTracker } from '@jupyterlab/terminal';

const extension: JupyterFrontEndPlugin = {
  id: 'launcher_terminal:plugin',
  autoStart: true,
  requires: [ITerminalTracker],
  activate: (app: JupyterFrontEnd) => {
    console.log('JupyterLab extension launcher_terminal is activated!');
    app.commands.execute('terminal:create-new');
  }
};

And you would also want to add the terminal dependencies to your package.json and yarn.lock using:

jlpm add @jupyterlab/terminal @jupyterlab/terminal-extension

Does it help?

@Lykeios
Copy link
Author

Lykeios commented Jun 4, 2021

@krassowski Thanks for your help! It works, to some extent. I have some further questions if I may ask:
The function of the extension I developing is intended to let JupyterLab open up a terminal directly when activated, instead of opening up the launcher first. Thanks to your assist, I modified my code and it now can start a terminal when JupyterLab started. The whole source code is pasted in the following snippet

import {
  ILabShell,
  JupyterFrontEnd,
  JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { ILauncher } from '@jupyterlab/launcher';
import { ITerminalTracker } from '@jupyterlab/terminal';

const extension: JupyterFrontEndPlugin<void> = {
  id: 'launcher_terminal:plugin',
  autoStart: true,
  requires: [ITerminalTracker, ILauncher, ILabShell],
  activate: (app: JupyterFrontEnd) => {
    console.log('JupyterLab extension launcher_terminal is activated!');
    app.commands.execute('terminal:create-new', {
      isPalette: false
    });
  }
};

export default extension;

Yet this terminal runs in the background and seems it cannot be called to the foreground, as the images are shown below. I hoped it will achieve the effect just like opening up a terminal from the original launcher's panel, but it looks different from what expected.
Are there further steps that I need to do, or did I neglect something that essential?

20210604170332

@krassowski
Copy link
Member

There is an example on how to add the terminal to the main widget area after it was opened in the extension points article; for convenience I will copy-paste how to do so here (but it might change in the future, so for any time-traveler - it is best to check the docs):

app.commands
  .execute('terminal:create-new')
  .then((terminal: WidgetModuleType.Terminal) => {
    app.shell.add(terminal, 'right');
  });

I found it by using "search" -> "in this repository" function on GitHub (using terminal:create-new as a search phrase) - it is very handy and together with GitHub code navigation (click on variable/function names in files to see where it is defined and where it is referenced) allows to find relevant examples easily. There is also https://github.com/jupyterlab/extension-examples repository but in this case it does not have a relevant example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants