Common extension points

Spyder offers different way of extending the global application and extending the functionality of plugins tehmeselves.

Application extension points

Creating actions and shortcuts

Main application menus

There are three main ways to extend Spyder’s application menu.

  1. You can add new application menu to the application menu bar.

  2. You can add new actions to the existing application menus.

  3. You can override or extend one of the existing application menu actions.

Creating a new application menu

To add a new menu to the menu bar, you need to create one with the core plugin.

You can then add actions to the menu.

from spyder.api.plugins import Plugins, SpyderPluginV2


class SomePlugin(SpyderPluginV2):

    def register(self):
        core = self.get_plugin(Plugins.Core)
        extras_menu = core.create_application_menu(
            "extras_menu",
            title="Extras",
        )

Adding a new action to an existing menu

from spyder.api.plugins import Plugins, SpyderPluginV2
from spyder.plugins.core.api import HelpMenuSections


class SomePlugin(SpyderPluginV2):

    def register(self):
        core = self.get_plugin(Plugins.Core)
        help_menu = core.get_menu("help_menu")

        # Create a new action
        run_action = self.create_action(
            "hello_world_action"
            text="Print Hello World!",
            triggered=lambda: print("Hello World!"),
        )

        # Add action to menu
        self.add_item_to_menu(
            run_action,
            menu=help_menu,
            section=HelpMenuSections.Documentation,
        )

Extending an existing action

# TODO:

Application toolbars

Status bar

Status bar widgets!

TODO:

Plugin extension points

Appearance

Themes etc..

Layouts

Custom layouts

Projects

A new project type

# ./a_plugin/project_types.py

# Third party imports
from spyder.api.translation import get_translation
from spyder.plugins.projects.api import BaseProjectType


# Localization
_ = get_translation("a_plugin")


class NewProjectType(BaseProjectType):
    ID = None

    def __init__(self, root_path, parent_plugin=None):
        super().__init__(root_path, parent_plugin)

    # --- Configuration
    # -------------------------------------------------------------------------
    def get_option(self, option, section=WORKSPACE, default=None):
        """
        Get project configuration option.
        """
        return self.config.get(section=section, option=option, default=default)

    def set_option(self, option, value, section=WORKSPACE):
        """
        Set project configuration option.
        """
        self.config.set(section=section, option=option, value=value)

    # --- API
    # ------------------------------------------------------------------------
    @staticmethod
    def get_name():
        """
        Provide a human readable version of NAME.
        """
        raise NotImplementedError("Must implement a `get_name` method!")

    @staticmethod
    def validate_name(path, name):
        """
        Validate the project's name.

        Returns
        -------
        tuple
            The first item (bool) indicates if the name was validated
            successfully, and the second item (str) indicates the error
            message, if any.
        """
        return True,  _("Some usefull error message in case of problems.")

    def create_project(self):
        """
        Create a project and do any additional setup for this project type.

        Returns
        -------
        tuple
            The first item (bool) indicates if the project was created
            successfully, and the second item (str) indicates the error
            message, if any.
        """
        return False, _("Some usefull error message in case of problems.")

    def open_project(self):
        """
        Open a project and do any additional setup for this project type.

        Returns
        -------
        tuple
            The first item (bool) indicates if the project was opened
            successfully, and the second item (str) indicates the error
            message, if any.
        """
        return False,  _("Some usefull error message in case of problems.")

    def close_project(self):
        """
        Close a project and do any additional setup for this project type.

        Returns
        -------
        tuple
            The first item (bool) indicates if the project was closed
            successfully, and the second item (str) indicates the error
            message, if any.
        """
        return False,  _("Some usefull error message in case of problems.")

And then register the new project type with the projects plugin.

# ./a_plugin/plugin.py

# Third party imports
from spyder.api.plugins import Plugins, SpyderPluginV2

# Local imports
from a_plugin.project_types import NewProjectType


class SomeAwesomePlugin(SpyderPluginV2):
    # ...
    def register(self):
        projects = self.get_plugin(Plugins.Projects)
        self.register_project_type(self, NewProjectType)
    # ...

A new project type from a cookiecutter

TODO:

Several project types

TODO:

Completion providers

TODO: